summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorStephen Rothwell <sfr@canb.auug.org.au>2010-12-09 12:08:47 +1100
committerStephen Rothwell <sfr@canb.auug.org.au>2010-12-09 12:08:47 +1100
commit3597f3e7ca7b21f43d7c79ffeb32c7e653c79743 (patch)
tree9a3734fca0b9bd5a2021b53bf464ddd69e9fe4ec /drivers
parent8f1429664fbda34435e225c6b176f5678722b5c5 (diff)
parent393934c6b5c8d00f9d1ae20670d4a770f07a418a (diff)
Merge remote branch 'wireless/master'
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/ath/ar9170/cmd.c2
-rw-r--r--drivers/net/wireless/ath/ar9170/usb.c6
-rw-r--r--drivers/net/wireless/ath/ath.h108
-rw-r--r--drivers/net/wireless/ath/ath5k/Kconfig18
-rw-r--r--drivers/net/wireless/ath/ath5k/Makefile2
-rw-r--r--drivers/net/wireless/ath/ath5k/ahb.c219
-rw-r--r--drivers/net/wireless/ath/ath5k/ani.c40
-rw-r--r--drivers/net/wireless/ath/ath5k/ath5k.h286
-rw-r--r--drivers/net/wireless/ath/ath5k/attach.c28
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c909
-rw-r--r--drivers/net/wireless/ath/ath5k/base.h5
-rw-r--r--drivers/net/wireless/ath/ath5k/caps.c6
-rw-r--r--drivers/net/wireless/ath/ath5k/debug.c34
-rw-r--r--drivers/net/wireless/ath/ath5k/debug.h2
-rw-r--r--drivers/net/wireless/ath/ath5k/desc.c24
-rw-r--r--drivers/net/wireless/ath/ath5k/desc.h18
-rw-r--r--drivers/net/wireless/ath/ath5k/dma.c180
-rw-r--r--drivers/net/wireless/ath/ath5k/eeprom.c127
-rw-r--r--drivers/net/wireless/ath/ath5k/eeprom.h2
-rw-r--r--drivers/net/wireless/ath/ath5k/initvals.c409
-rw-r--r--drivers/net/wireless/ath/ath5k/led.c11
-rw-r--r--drivers/net/wireless/ath/ath5k/pci.c326
-rw-r--r--drivers/net/wireless/ath/ath5k/pcu.c571
-rw-r--r--drivers/net/wireless/ath/ath5k/phy.c676
-rw-r--r--drivers/net/wireless/ath/ath5k/qcu.c696
-rw-r--r--drivers/net/wireless/ath/ath5k/reg.h31
-rw-r--r--drivers/net/wireless/ath/ath5k/reset.c1221
-rw-r--r--drivers/net/wireless/ath/ath5k/rfbuffer.h1169
-rw-r--r--drivers/net/wireless/ath/ath5k/sysfs.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/ahb.c7
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.c107
-rw-r--r--drivers/net/wireless/ath/ath9k/ar5008_phy.c292
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_calib.c220
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_hw.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_mac.c143
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_phy.c20
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_calib.c494
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.c2997
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.h29
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_hw.c278
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.c111
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.h6
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_paprd.c41
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c316
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.h70
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9485_initvals.h943
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h59
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c107
-rw-r--r--drivers/net/wireless/ath/ath9k/btcoex.c23
-rw-r--r--drivers/net/wireless/ath/ath9k/btcoex.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.c59
-rw-r--r--drivers/net/wireless/ath/ath9k/common.c19
-rw-r--r--drivers/net/wireless/ath/ath9k/common.h15
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c83
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.h21
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.h4
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_4k.c93
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_9287.c82
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_def.c142
-rw-r--r--drivers/net/wireless/ath/ath9k/gpio.c30
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.c182
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/htc.h4
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_beacon.c24
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_gpio.c15
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_init.c104
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c204
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_txrx.c42
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_hst.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_hst.h22
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c239
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h65
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c157
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.c201
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.h14
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c390
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c94
-rw-r--r--drivers/net/wireless/ath/ath9k/phy.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.c78
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.h6
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c110
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h30
-rw-r--r--drivers/net/wireless/ath/ath9k/virtual.c15
-rw-r--r--drivers/net/wireless/ath/ath9k/wmi.c12
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c814
-rw-r--r--drivers/net/wireless/ath/carl9170/carl9170.h5
-rw-r--r--drivers/net/wireless/ath/carl9170/cmd.c2
-rw-r--r--drivers/net/wireless/ath/carl9170/fwcmd.h13
-rw-r--r--drivers/net/wireless/ath/carl9170/hw.h7
-rw-r--r--drivers/net/wireless/ath/carl9170/mac.c56
-rw-r--r--drivers/net/wireless/ath/carl9170/main.c19
-rw-r--r--drivers/net/wireless/ath/carl9170/phy.c17
-rw-r--r--drivers/net/wireless/ath/carl9170/phy.h24
-rw-r--r--drivers/net/wireless/ath/carl9170/tx.c80
-rw-r--r--drivers/net/wireless/ath/carl9170/usb.c5
-rw-r--r--drivers/net/wireless/ath/carl9170/version.h6
-rw-r--r--drivers/net/wireless/ath/debug.c15
-rw-r--r--drivers/net/wireless/ath/debug.h90
-rw-r--r--drivers/net/wireless/ath/key.c37
-rw-r--r--drivers/net/wireless/ath/main.c20
-rw-r--r--drivers/net/wireless/atmel.c6
-rw-r--r--drivers/net/wireless/b43/Kconfig13
-rw-r--r--drivers/net/wireless/b43/Makefile8
-rw-r--r--drivers/net/wireless/b43/b43.h13
-rw-r--r--drivers/net/wireless/b43/dma.c5
-rw-r--r--drivers/net/wireless/b43/main.c60
-rw-r--r--drivers/net/wireless/b43/phy_common.c22
-rw-r--r--drivers/net/wireless/b43/phy_common.h8
-rw-r--r--drivers/net/wireless/b43/phy_n.c429
-rw-r--r--drivers/net/wireless/b43/phy_n.h2
-rw-r--r--drivers/net/wireless/b43/radio_2055.c502
-rw-r--r--drivers/net/wireless/b43/radio_2056.c6019
-rw-r--r--drivers/net/wireless/b43/radio_2056.h1081
-rw-r--r--drivers/net/wireless/b43/rfkill.c19
-rw-r--r--drivers/net/wireless/b43/tables_nphy.c224
-rw-r--r--drivers/net/wireless/b43legacy/main.c47
-rw-r--r--drivers/net/wireless/b43legacy/rfkill.c2
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig3
-rw-r--r--drivers/net/wireless/iwlwifi/Makefile11
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c36
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c35
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c369
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c64
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c186
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-calib.c230
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c41
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c115
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c32
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rxon.c635
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-sta.c32
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c155
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-ucode.c69
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c594
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.h61
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h26
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c954
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h91
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-csr.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c33
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h22
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.h13
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-helpers.h45
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.c12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.h6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-legacy.c662
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-legacy.h79
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.c190
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c45
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c64
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c64
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c88
-rw-r--r--drivers/net/wireless/iwmc3200wifi/commands.c2
-rw-r--r--drivers/net/wireless/libertas/cfg.c4
-rw-r--r--drivers/net/wireless/libertas/cmd.c8
-rw-r--r--drivers/net/wireless/libertas/dev.h1
-rw-r--r--drivers/net/wireless/libertas/if_usb.c13
-rw-r--r--drivers/net/wireless/libertas/main.c3
-rw-r--r--drivers/net/wireless/libertas/rx.c4
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c5
-rw-r--r--drivers/net/wireless/mwl8k.c670
-rw-r--r--drivers/net/wireless/orinoco/wext.c8
-rw-r--r--drivers/net/wireless/p54/p54usb.c2
-rw-r--r--drivers/net/wireless/ray_cs.c18
-rw-r--r--drivers/net/wireless/rndis_wlan.c206
-rw-r--r--drivers/net/wireless/rt2x00/Kconfig72
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c14
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.h6
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c20
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.h4
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c22
-rw-r--r--drivers/net/wireless/rt2x00/rt2800.h62
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c54
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.c66
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.h12
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c278
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.h4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00config.c8
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00debug.c10
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c54
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00lib.h3
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00link.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c52
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c45
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.h33
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00reg.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00soc.c6
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c25
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c28
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c22
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.h2
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_dev.c140
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_rtl8225.c22
-rw-r--r--drivers/net/wireless/wl1251/main.c15
-rw-r--r--drivers/net/wireless/wl1251/sdio.c101
-rw-r--r--drivers/net/wireless/wl1251/spi.c9
-rw-r--r--drivers/net/wireless/wl1251/wl1251.h1
-rw-r--r--drivers/net/wireless/wl12xx/Kconfig54
-rw-r--r--drivers/net/wireless/wl12xx/Makefile17
-rw-r--r--drivers/net/wireless/wl12xx/acx.c (renamed from drivers/net/wireless/wl12xx/wl1271_acx.c)95
-rw-r--r--drivers/net/wireless/wl12xx/acx.h (renamed from drivers/net/wireless/wl12xx/wl1271_acx.h)99
-rw-r--r--drivers/net/wireless/wl12xx/boot.c (renamed from drivers/net/wireless/wl12xx/wl1271_boot.c)20
-rw-r--r--drivers/net/wireless/wl12xx/boot.h (renamed from drivers/net/wireless/wl12xx/wl1271_boot.h)2
-rw-r--r--drivers/net/wireless/wl12xx/cmd.c (renamed from drivers/net/wireless/wl12xx/wl1271_cmd.c)12
-rw-r--r--drivers/net/wireless/wl12xx/cmd.h (renamed from drivers/net/wireless/wl12xx/wl1271_cmd.h)54
-rw-r--r--drivers/net/wireless/wl12xx/conf.h (renamed from drivers/net/wireless/wl12xx/wl1271_conf.h)4
-rw-r--r--drivers/net/wireless/wl12xx/debugfs.c (renamed from drivers/net/wireless/wl12xx/wl1271_debugfs.c)225
-rw-r--r--drivers/net/wireless/wl12xx/debugfs.h (renamed from drivers/net/wireless/wl12xx/wl1271_debugfs.h)6
-rw-r--r--drivers/net/wireless/wl12xx/event.c (renamed from drivers/net/wireless/wl12xx/wl1271_event.c)14
-rw-r--r--drivers/net/wireless/wl12xx/event.h (renamed from drivers/net/wireless/wl12xx/wl1271_event.h)4
-rw-r--r--drivers/net/wireless/wl12xx/ini.h (renamed from drivers/net/wireless/wl12xx/wl1271_ini.h)4
-rw-r--r--drivers/net/wireless/wl12xx/init.c (renamed from drivers/net/wireless/wl12xx/wl1271_init.c)10
-rw-r--r--drivers/net/wireless/wl12xx/init.h (renamed from drivers/net/wireless/wl12xx/wl1271_init.h)6
-rw-r--r--drivers/net/wireless/wl12xx/io.c (renamed from drivers/net/wireless/wl12xx/wl1271_io.c)4
-rw-r--r--drivers/net/wireless/wl12xx/io.h (renamed from drivers/net/wireless/wl12xx/wl1271_io.h)6
-rw-r--r--drivers/net/wireless/wl12xx/main.c (renamed from drivers/net/wireless/wl12xx/wl1271_main.c)391
-rw-r--r--drivers/net/wireless/wl12xx/ps.c (renamed from drivers/net/wireless/wl12xx/wl1271_ps.c)6
-rw-r--r--drivers/net/wireless/wl12xx/ps.h (renamed from drivers/net/wireless/wl12xx/wl1271_ps.h)8
-rw-r--r--drivers/net/wireless/wl12xx/reg.h (renamed from drivers/net/wireless/wl12xx/wl1271_reg.h)0
-rw-r--r--drivers/net/wireless/wl12xx/rx.c (renamed from drivers/net/wireless/wl12xx/wl1271_rx.c)38
-rw-r--r--drivers/net/wireless/wl12xx/rx.h (renamed from drivers/net/wireless/wl12xx/wl1271_rx.h)6
-rw-r--r--drivers/net/wireless/wl12xx/scan.c (renamed from drivers/net/wireless/wl12xx/wl1271_scan.c)13
-rw-r--r--drivers/net/wireless/wl12xx/scan.h (renamed from drivers/net/wireless/wl12xx/wl1271_scan.h)6
-rw-r--r--drivers/net/wireless/wl12xx/sdio.c (renamed from drivers/net/wireless/wl12xx/wl1271_sdio.c)4
-rw-r--r--drivers/net/wireless/wl12xx/spi.c (renamed from drivers/net/wireless/wl12xx/wl1271_spi.c)6
-rw-r--r--drivers/net/wireless/wl12xx/testmode.c (renamed from drivers/net/wireless/wl12xx/wl1271_testmode.c)18
-rw-r--r--drivers/net/wireless/wl12xx/testmode.h (renamed from drivers/net/wireless/wl12xx/wl1271_testmode.h)4
-rw-r--r--drivers/net/wireless/wl12xx/tx.c (renamed from drivers/net/wireless/wl12xx/wl1271_tx.c)142
-rw-r--r--drivers/net/wireless/wl12xx/tx.h (renamed from drivers/net/wireless/wl12xx/wl1271_tx.h)7
-rw-r--r--drivers/net/wireless/wl12xx/wl12xx.h (renamed from drivers/net/wireless/wl12xx/wl1271.h)21
-rw-r--r--drivers/net/wireless/zd1201.c3
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.c4
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.c2
-rw-r--r--drivers/ssb/main.c30
-rw-r--r--drivers/ssb/pci.c96
-rw-r--r--drivers/ssb/pcihost_wrapper.c7
244 files changed, 24490 insertions, 9837 deletions
diff --git a/drivers/net/wireless/ath/ar9170/cmd.c b/drivers/net/wireless/ath/ar9170/cmd.c
index 4604de09a8b2..6452c5055a63 100644
--- a/drivers/net/wireless/ath/ar9170/cmd.c
+++ b/drivers/net/wireless/ath/ar9170/cmd.c
@@ -54,7 +54,7 @@ int ar9170_write_mem(struct ar9170 *ar, const __le32 *data, size_t len)
int ar9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val)
{
- __le32 buf[2] = {
+ const __le32 buf[2] = {
cpu_to_le32(reg),
cpu_to_le32(val),
};
diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c
index 5dbb5361fd51..d3be6f9816b5 100644
--- a/drivers/net/wireless/ath/ar9170/usb.c
+++ b/drivers/net/wireless/ath/ar9170/usb.c
@@ -161,8 +161,7 @@ static void ar9170_usb_submit_urb(struct ar9170_usb *aru)
static void ar9170_usb_tx_urb_complete_frame(struct urb *urb)
{
struct sk_buff *skb = urb->context;
- struct ar9170_usb *aru = (struct ar9170_usb *)
- usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
+ struct ar9170_usb *aru = usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
if (unlikely(!aru)) {
dev_kfree_skb_irq(skb);
@@ -219,8 +218,7 @@ free:
static void ar9170_usb_rx_completed(struct urb *urb)
{
struct sk_buff *skb = urb->context;
- struct ar9170_usb *aru = (struct ar9170_usb *)
- usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
+ struct ar9170_usb *aru = usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
int err;
if (!aru)
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index 501050c0296f..3eb95e268f03 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -126,6 +126,7 @@ struct ath_bus_ops {
void (*read_cachesize)(struct ath_common *common, int *csz);
bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data);
void (*bt_coex_prep)(struct ath_common *common);
+ void (*extn_synch_en)(struct ath_common *common);
};
struct ath_common {
@@ -162,6 +163,8 @@ struct ath_common {
struct ath_regulatory regulatory;
const struct ath_ops *ops;
const struct ath_bus_ops *bus_ops;
+
+ bool btcoex_enabled;
};
struct sk_buff *ath_rxbuf_alloc(struct ath_common *common,
@@ -178,4 +181,109 @@ bool ath_hw_keyreset(struct ath_common *common, u16 entry);
void ath_hw_cycle_counters_update(struct ath_common *common);
int32_t ath_hw_get_listen_time(struct ath_common *common);
+extern __attribute__ ((format (printf, 3, 4))) int
+ath_printk(const char *level, struct ath_common *common, const char *fmt, ...);
+
+#define ath_emerg(common, fmt, ...) \
+ ath_printk(KERN_EMERG, common, fmt, ##__VA_ARGS__)
+#define ath_alert(common, fmt, ...) \
+ ath_printk(KERN_ALERT, common, fmt, ##__VA_ARGS__)
+#define ath_crit(common, fmt, ...) \
+ ath_printk(KERN_CRIT, common, fmt, ##__VA_ARGS__)
+#define ath_err(common, fmt, ...) \
+ ath_printk(KERN_ERR, common, fmt, ##__VA_ARGS__)
+#define ath_warn(common, fmt, ...) \
+ ath_printk(KERN_WARNING, common, fmt, ##__VA_ARGS__)
+#define ath_notice(common, fmt, ...) \
+ ath_printk(KERN_NOTICE, common, fmt, ##__VA_ARGS__)
+#define ath_info(common, fmt, ...) \
+ ath_printk(KERN_INFO, common, fmt, ##__VA_ARGS__)
+
+/**
+ * enum ath_debug_level - atheros wireless debug level
+ *
+ * @ATH_DBG_RESET: reset processing
+ * @ATH_DBG_QUEUE: hardware queue management
+ * @ATH_DBG_EEPROM: eeprom processing
+ * @ATH_DBG_CALIBRATE: periodic calibration
+ * @ATH_DBG_INTERRUPT: interrupt processing
+ * @ATH_DBG_REGULATORY: regulatory processing
+ * @ATH_DBG_ANI: adaptive noise immunitive processing
+ * @ATH_DBG_XMIT: basic xmit operation
+ * @ATH_DBG_BEACON: beacon handling
+ * @ATH_DBG_CONFIG: configuration of the hardware
+ * @ATH_DBG_FATAL: fatal errors, this is the default, DBG_DEFAULT
+ * @ATH_DBG_PS: power save processing
+ * @ATH_DBG_HWTIMER: hardware timer handling
+ * @ATH_DBG_BTCOEX: bluetooth coexistance
+ * @ATH_DBG_BSTUCK: stuck beacons
+ * @ATH_DBG_ANY: enable all debugging
+ *
+ * The debug level is used to control the amount and type of debugging output
+ * we want to see. Each driver has its own method for enabling debugging and
+ * modifying debug level states -- but this is typically done through a
+ * module parameter 'debug' along with a respective 'debug' debugfs file
+ * entry.
+ */
+enum ATH_DEBUG {
+ ATH_DBG_RESET = 0x00000001,
+ ATH_DBG_QUEUE = 0x00000002,
+ ATH_DBG_EEPROM = 0x00000004,
+ ATH_DBG_CALIBRATE = 0x00000008,
+ ATH_DBG_INTERRUPT = 0x00000010,
+ ATH_DBG_REGULATORY = 0x00000020,
+ ATH_DBG_ANI = 0x00000040,
+ ATH_DBG_XMIT = 0x00000080,
+ ATH_DBG_BEACON = 0x00000100,
+ ATH_DBG_CONFIG = 0x00000200,
+ ATH_DBG_FATAL = 0x00000400,
+ ATH_DBG_PS = 0x00000800,
+ ATH_DBG_HWTIMER = 0x00001000,
+ ATH_DBG_BTCOEX = 0x00002000,
+ ATH_DBG_WMI = 0x00004000,
+ ATH_DBG_BSTUCK = 0x00008000,
+ ATH_DBG_ANY = 0xffffffff
+};
+
+#define ATH_DBG_DEFAULT (ATH_DBG_FATAL)
+
+#ifdef CONFIG_ATH_DEBUG
+
+#define ath_dbg(common, dbg_mask, fmt, ...) \
+({ \
+ int rtn; \
+ if ((common)->debug_mask & dbg_mask) \
+ rtn = ath_printk(KERN_DEBUG, common, fmt, \
+ ##__VA_ARGS__); \
+ else \
+ rtn = 0; \
+ \
+ rtn; \
+})
+#define ATH_DBG_WARN(foo, arg...) WARN(foo, arg)
+#define ATH_DBG_WARN_ON_ONCE(foo) WARN_ON_ONCE(foo)
+
+#else
+
+static inline __attribute__ ((format (printf, 3, 4))) int
+ath_dbg(struct ath_common *common, enum ATH_DEBUG dbg_mask,
+ const char *fmt, ...)
+{
+ return 0;
+}
+#define ATH_DBG_WARN(foo, arg...) do {} while (0)
+#define ATH_DBG_WARN_ON_ONCE(foo) do {} while (0)
+
+#endif /* CONFIG_ATH_DEBUG */
+
+/** Returns string describing opmode, or NULL if unknown mode. */
+#ifdef CONFIG_ATH_DEBUG
+const char *ath_opmode_to_string(enum nl80211_iftype opmode);
+#else
+static inline const char *ath_opmode_to_string(enum nl80211_iftype opmode)
+{
+ return "UNKNOWN";
+}
+#endif
+
#endif /* ATH_H */
diff --git a/drivers/net/wireless/ath/ath5k/Kconfig b/drivers/net/wireless/ath/ath5k/Kconfig
index eb83b7b4d0e3..e0793319389d 100644
--- a/drivers/net/wireless/ath/ath5k/Kconfig
+++ b/drivers/net/wireless/ath/ath5k/Kconfig
@@ -1,9 +1,12 @@
config ATH5K
tristate "Atheros 5xxx wireless cards support"
- depends on PCI && MAC80211
+ depends on (PCI || ATHEROS_AR231X) && MAC80211
select MAC80211_LEDS
select LEDS_CLASS
select NEW_LEDS
+ select AVERAGE
+ select ATH5K_AHB if (ATHEROS_AR231X && !PCI)
+ select ATH5K_PCI if (!ATHEROS_AR231X && PCI)
---help---
This module adds support for wireless adapters based on
Atheros 5xxx chipset.
@@ -37,3 +40,16 @@ config ATH5K_DEBUG
modprobe ath5k debug=0x00000400
+config ATH5K_AHB
+ bool "Atheros 5xxx AHB bus support"
+ depends on (ATHEROS_AR231X && !PCI)
+ ---help---
+ This adds support for WiSoC type chipsets of the 5xxx Atheros
+ family.
+
+config ATH5K_PCI
+ bool "Atheros 5xxx PCI bus support"
+ depends on (!ATHEROS_AR231X && PCI)
+ ---help---
+ This adds support for PCI type chipsets of the 5xxx Atheros
+ family.
diff --git a/drivers/net/wireless/ath/ath5k/Makefile b/drivers/net/wireless/ath/ath5k/Makefile
index 2242a140e4fe..67dd9fd0650e 100644
--- a/drivers/net/wireless/ath/ath5k/Makefile
+++ b/drivers/net/wireless/ath/ath5k/Makefile
@@ -15,4 +15,6 @@ ath5k-y += rfkill.o
ath5k-y += ani.o
ath5k-y += sysfs.o
ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o
+ath5k-$(CONFIG_ATH5K_AHB) += ahb.o
+ath5k-$(CONFIG_ATH5K_PCI) += pci.o
obj-$(CONFIG_ATH5K) += ath5k.o
diff --git a/drivers/net/wireless/ath/ath5k/ahb.c b/drivers/net/wireless/ath/ath5k/ahb.c
new file mode 100644
index 000000000000..707cde149248
--- /dev/null
+++ b/drivers/net/wireless/ath/ath5k/ahb.c
@@ -0,0 +1,219 @@
+/*
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
+ * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/nl80211.h>
+#include <linux/platform_device.h>
+#include <ar231x_platform.h>
+#include "ath5k.h"
+#include "debug.h"
+#include "base.h"
+#include "reg.h"
+#include "debug.h"
+
+/* return bus cachesize in 4B word units */
+static void ath5k_ahb_read_cachesize(struct ath_common *common, int *csz)
+{
+ *csz = L1_CACHE_BYTES >> 2;
+}
+
+bool ath5k_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data)
+{
+ struct ath5k_softc *sc = common->priv;
+ struct platform_device *pdev = to_platform_device(sc->dev);
+ struct ar231x_board_config *bcfg = pdev->dev.platform_data;
+ u16 *eeprom, *eeprom_end;
+
+
+
+ bcfg = pdev->dev.platform_data;
+ eeprom = (u16 *) bcfg->radio;
+ eeprom_end = ((void *) bcfg->config) + BOARD_CONFIG_BUFSZ;
+
+ eeprom += off;
+ if (eeprom > eeprom_end)
+ return -EINVAL;
+
+ *data = *eeprom;
+ return 0;
+}
+
+int ath5k_hw_read_srev(struct ath5k_hw *ah)
+{
+ struct ath5k_softc *sc = ah->ah_sc;
+ struct platform_device *pdev = to_platform_device(sc->dev);
+ struct ar231x_board_config *bcfg = pdev->dev.platform_data;
+ ah->ah_mac_srev = bcfg->devid;
+ return 0;
+}
+
+static const struct ath_bus_ops ath_ahb_bus_ops = {
+ .ath_bus_type = ATH_AHB,
+ .read_cachesize = ath5k_ahb_read_cachesize,
+ .eeprom_read = ath5k_ahb_eeprom_read,
+};
+
+/*Initialization*/
+static int ath_ahb_probe(struct platform_device *pdev)
+{
+ struct ar231x_board_config *bcfg = pdev->dev.platform_data;
+ struct ath5k_softc *sc;
+ struct ieee80211_hw *hw;
+ struct resource *res;
+ void __iomem *mem;
+ int irq;
+ int ret = 0;
+ u32 reg;
+
+ if (!pdev->dev.platform_data) {
+ dev_err(&pdev->dev, "no platform data specified\n");
+ ret = -EINVAL;
+ goto err_out;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res == NULL) {
+ dev_err(&pdev->dev, "no memory resource found\n");
+ ret = -ENXIO;
+ goto err_out;
+ }
+
+ mem = ioremap_nocache(res->start, res->end - res->start + 1);
+ if (mem == NULL) {
+ dev_err(&pdev->dev, "ioremap failed\n");
+ ret = -ENOMEM;
+ goto err_out;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (res == NULL) {
+ dev_err(&pdev->dev, "no IRQ resource found\n");
+ ret = -ENXIO;
+ goto err_out;
+ }
+
+ irq = res->start;
+
+ hw = ieee80211_alloc_hw(sizeof(struct ath5k_softc), &ath5k_hw_ops);
+ if (hw == NULL) {
+ dev_err(&pdev->dev, "no memory for ieee80211_hw\n");
+ ret = -ENOMEM;
+ goto err_out;
+ }
+
+ sc = hw->priv;
+ sc->hw = hw;
+ sc->dev = &pdev->dev;
+ sc->iobase = mem;
+ sc->irq = irq;
+ sc->devid = bcfg->devid;
+
+ if (bcfg->devid >= AR5K_SREV_AR2315_R6) {
+ /* Enable WMAC AHB arbitration */
+ reg = __raw_readl((void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
+ reg |= AR5K_AR2315_AHB_ARB_CTL_WLAN;
+ __raw_writel(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
+
+ /* Enable global WMAC swapping */
+ reg = __raw_readl((void __iomem *) AR5K_AR2315_BYTESWAP);
+ reg |= AR5K_AR2315_BYTESWAP_WMAC;
+ __raw_writel(reg, (void __iomem *) AR5K_AR2315_BYTESWAP);
+ } else {
+ /* Enable WMAC DMA access (assuming 5312 or 231x*/
+ /* TODO: check other platforms */
+ reg = __raw_readl((void __iomem *) AR5K_AR5312_ENABLE);
+ if (to_platform_device(sc->dev)->id == 0)
+ reg |= AR5K_AR5312_ENABLE_WLAN0;
+ else
+ reg |= AR5K_AR5312_ENABLE_WLAN1;
+ __raw_writel(reg, (void __iomem *) AR5K_AR5312_ENABLE);
+ }
+
+ ret = ath5k_init_softc(sc, &ath_ahb_bus_ops);
+ if (ret != 0) {
+ dev_err(&pdev->dev, "failed to attach device, err=%d\n", ret);
+ ret = -ENODEV;
+ goto err_free_hw;
+ }
+
+ platform_set_drvdata(pdev, hw);
+
+ return 0;
+
+ err_free_hw:
+ ieee80211_free_hw(hw);
+ platform_set_drvdata(pdev, NULL);
+ err_out:
+ return ret;
+}
+
+static int ath_ahb_remove(struct platform_device *pdev)
+{
+ struct ar231x_board_config *bcfg = pdev->dev.platform_data;
+ struct ieee80211_hw *hw = platform_get_drvdata(pdev);
+ struct ath5k_softc *sc;
+ u32 reg;
+
+ if (!hw)
+ return 0;
+
+ sc = hw->priv;
+
+ if (bcfg->devid >= AR5K_SREV_AR2315_R6) {
+ /* Disable WMAC AHB arbitration */
+ reg = __raw_readl((void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
+ reg &= ~AR5K_AR2315_AHB_ARB_CTL_WLAN;
+ __raw_writel(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
+ } else {
+ /*Stop DMA access */
+ reg = __raw_readl((void __iomem *) AR5K_AR5312_ENABLE);
+ if (to_platform_device(sc->dev)->id == 0)
+ reg &= ~AR5K_AR5312_ENABLE_WLAN0;
+ else
+ reg &= ~AR5K_AR5312_ENABLE_WLAN1;
+ __raw_writel(reg, (void __iomem *) AR5K_AR5312_ENABLE);
+ }
+
+ ath5k_deinit_softc(sc);
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+static struct platform_driver ath_ahb_driver = {
+ .probe = ath_ahb_probe,
+ .remove = ath_ahb_remove,
+ .driver = {
+ .name = "ar231x-wmac",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init
+ath5k_ahb_init(void)
+{
+ return platform_driver_register(&ath_ahb_driver);
+}
+
+static void __exit
+ath5k_ahb_exit(void)
+{
+ platform_driver_unregister(&ath_ahb_driver);
+}
+
+module_init(ath5k_ahb_init);
+module_exit(ath5k_ahb_exit);
diff --git a/drivers/net/wireless/ath/ath5k/ani.c b/drivers/net/wireless/ath/ath5k/ani.c
index f1419198a479..f915f404302d 100644
--- a/drivers/net/wireless/ath/ath5k/ani.c
+++ b/drivers/net/wireless/ath/ath5k/ani.c
@@ -58,20 +58,20 @@ ath5k_ani_set_noise_immunity_level(struct ath5k_hw *ah, int level)
{
/* TODO:
* ANI documents suggest the following five levels to use, but the HAL
- * and ath9k use only use the last two levels, making this
+ * and ath9k use only the last two levels, making this
* essentially an on/off option. There *may* be a reason for this (???),
* so i stick with the HAL version for now...
*/
#if 0
- const s8 hi[] = { -18, -18, -16, -14, -12 };
- const s8 lo[] = { -52, -56, -60, -64, -70 };
- const s8 sz[] = { -34, -41, -48, -55, -62 };
- const s8 fr[] = { -70, -72, -75, -78, -80 };
+ static const s8 lo[] = { -52, -56, -60, -64, -70 };
+ static const s8 hi[] = { -18, -18, -16, -14, -12 };
+ static const s8 sz[] = { -34, -41, -48, -55, -62 };
+ static const s8 fr[] = { -70, -72, -75, -78, -80 };
#else
- const s8 sz[] = { -55, -62 };
- const s8 lo[] = { -64, -70 };
- const s8 hi[] = { -14, -12 };
- const s8 fr[] = { -78, -80 };
+ static const s8 lo[] = { -64, -70 };
+ static const s8 hi[] = { -14, -12 };
+ static const s8 sz[] = { -55, -62 };
+ static const s8 fr[] = { -78, -80 };
#endif
if (level < 0 || level >= ARRAY_SIZE(sz)) {
ATH5K_ERR(ah->ah_sc, "noise immuniy level %d out of range",
@@ -102,7 +102,7 @@ ath5k_ani_set_noise_immunity_level(struct ath5k_hw *ah, int level)
void
ath5k_ani_set_spur_immunity_level(struct ath5k_hw *ah, int level)
{
- const int val[] = { 2, 4, 6, 8, 10, 12, 14, 16 };
+ static const int val[] = { 2, 4, 6, 8, 10, 12, 14, 16 };
if (level < 0 || level >= ARRAY_SIZE(val) ||
level > ah->ah_sc->ani_state.max_spur_level) {
@@ -127,7 +127,7 @@ ath5k_ani_set_spur_immunity_level(struct ath5k_hw *ah, int level)
void
ath5k_ani_set_firstep_level(struct ath5k_hw *ah, int level)
{
- const int val[] = { 0, 4, 8 };
+ static const int val[] = { 0, 4, 8 };
if (level < 0 || level >= ARRAY_SIZE(val)) {
ATH5K_ERR(ah->ah_sc, "firstep level %d out of range", level);
@@ -151,12 +151,12 @@ ath5k_ani_set_firstep_level(struct ath5k_hw *ah, int level)
void
ath5k_ani_set_ofdm_weak_signal_detection(struct ath5k_hw *ah, bool on)
{
- const int m1l[] = { 127, 50 };
- const int m2l[] = { 127, 40 };
- const int m1[] = { 127, 0x4d };
- const int m2[] = { 127, 0x40 };
- const int m2cnt[] = { 31, 16 };
- const int m2lcnt[] = { 63, 48 };
+ static const int m1l[] = { 127, 50 };
+ static const int m2l[] = { 127, 40 };
+ static const int m1[] = { 127, 0x4d };
+ static const int m2[] = { 127, 0x40 };
+ static const int m2cnt[] = { 31, 16 };
+ static const int m2lcnt[] = { 63, 48 };
AR5K_REG_WRITE_BITS(ah, AR5K_PHY_WEAK_OFDM_LOW_THR,
AR5K_PHY_WEAK_OFDM_LOW_THR_M1, m1l[on]);
@@ -192,7 +192,7 @@ ath5k_ani_set_ofdm_weak_signal_detection(struct ath5k_hw *ah, bool on)
void
ath5k_ani_set_cck_weak_signal_detection(struct ath5k_hw *ah, bool on)
{
- const int val[] = { 8, 6 };
+ static const int val[] = { 8, 6 };
AR5K_REG_WRITE_BITS(ah, AR5K_PHY_CCK_CROSSCORR,
AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR, val[on]);
ah->ah_sc->ani_state.cck_weak_sig = on;
@@ -216,7 +216,7 @@ static void
ath5k_ani_raise_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as,
bool ofdm_trigger)
{
- int rssi = ah->ah_beacon_rssi_avg.avg;
+ int rssi = ewma_read(&ah->ah_beacon_rssi_avg);
ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "raise immunity (%s)",
ofdm_trigger ? "ODFM" : "CCK");
@@ -301,7 +301,7 @@ ath5k_ani_raise_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as,
static void
ath5k_ani_lower_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as)
{
- int rssi = ah->ah_beacon_rssi_avg.avg;
+ int rssi = ewma_read(&ah->ah_beacon_rssi_avg);
ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "lower immunity");
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 308b79e1ff08..d6e744088bc6 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -25,6 +25,7 @@
#include <linux/io.h>
#include <linux/types.h>
+#include <linux/average.h>
#include <net/mac80211.h>
/* RX/TX descriptor hw structs
@@ -157,15 +158,6 @@
#define AR5K_INI_RFGAIN_5GHZ 0
#define AR5K_INI_RFGAIN_2GHZ 1
-/* TODO: Clean this up */
-#define AR5K_INI_VAL_11A 0
-#define AR5K_INI_VAL_11A_TURBO 1
-#define AR5K_INI_VAL_11B 2
-#define AR5K_INI_VAL_11G 3
-#define AR5K_INI_VAL_11G_TURBO 4
-#define AR5K_INI_VAL_XR 0
-#define AR5K_INI_VAL_MAX 5
-
/*
* Some tuneable values (these should be changeable by the user)
* TODO: Make use of them and add more options OR use debug/configfs
@@ -221,42 +213,66 @@
/* Initial values */
#define AR5K_INIT_CYCRSSI_THR1 2
-#define AR5K_INIT_TX_LATENCY 502
-#define AR5K_INIT_USEC 39
-#define AR5K_INIT_USEC_TURBO 79
-#define AR5K_INIT_USEC_32 31
-#define AR5K_INIT_SLOT_TIME 396
-#define AR5K_INIT_SLOT_TIME_TURBO 480
-#define AR5K_INIT_ACK_CTS_TIMEOUT 1024
-#define AR5K_INIT_ACK_CTS_TIMEOUT_TURBO 0x08000800
-#define AR5K_INIT_PROG_IFS 920
-#define AR5K_INIT_PROG_IFS_TURBO 960
-#define AR5K_INIT_EIFS 3440
-#define AR5K_INIT_EIFS_TURBO 6880
-#define AR5K_INIT_SIFS 560
-#define AR5K_INIT_SIFS_TURBO 480
+
+/* Tx retry limits */
#define AR5K_INIT_SH_RETRY 10
#define AR5K_INIT_LG_RETRY AR5K_INIT_SH_RETRY
+/* For station mode */
#define AR5K_INIT_SSH_RETRY 32
#define AR5K_INIT_SLG_RETRY AR5K_INIT_SSH_RETRY
#define AR5K_INIT_TX_RETRY 10
-#define AR5K_INIT_TRANSMIT_LATENCY ( \
- (AR5K_INIT_TX_LATENCY << 14) | (AR5K_INIT_USEC_32 << 7) | \
- (AR5K_INIT_USEC) \
-)
-#define AR5K_INIT_TRANSMIT_LATENCY_TURBO ( \
- (AR5K_INIT_TX_LATENCY << 14) | (AR5K_INIT_USEC_32 << 7) | \
- (AR5K_INIT_USEC_TURBO) \
-)
-#define AR5K_INIT_PROTO_TIME_CNTRL ( \
- (AR5K_INIT_CARR_SENSE_EN << 26) | (AR5K_INIT_EIFS << 12) | \
- (AR5K_INIT_PROG_IFS) \
-)
-#define AR5K_INIT_PROTO_TIME_CNTRL_TURBO ( \
- (AR5K_INIT_CARR_SENSE_EN << 26) | (AR5K_INIT_EIFS_TURBO << 12) | \
- (AR5K_INIT_PROG_IFS_TURBO) \
-)
+
+/* Slot time */
+#define AR5K_INIT_SLOT_TIME_TURBO 6
+#define AR5K_INIT_SLOT_TIME_DEFAULT 9
+#define AR5K_INIT_SLOT_TIME_HALF_RATE 13
+#define AR5K_INIT_SLOT_TIME_QUARTER_RATE 21
+#define AR5K_INIT_SLOT_TIME_B 20
+#define AR5K_SLOT_TIME_MAX 0xffff
+
+/* SIFS */
+#define AR5K_INIT_SIFS_TURBO 6
+/* XXX: 8 from initvals 10 from standard */
+#define AR5K_INIT_SIFS_DEFAULT_BG 8
+#define AR5K_INIT_SIFS_DEFAULT_A 16
+#define AR5K_INIT_SIFS_HALF_RATE 32
+#define AR5K_INIT_SIFS_QUARTER_RATE 64
+
+/* Used to calculate tx time for non 5/10/40MHz
+ * operation */
+/* It's preamble time + signal time (16 + 4) */
+#define AR5K_INIT_OFDM_PREAMPLE_TIME 20
+/* Preamble time for 40MHz (turbo) operation (min ?) */
+#define AR5K_INIT_OFDM_PREAMBLE_TIME_MIN 14
+#define AR5K_INIT_OFDM_SYMBOL_TIME 4
+#define AR5K_INIT_OFDM_PLCP_BITS 22
+
+/* Rx latency for 5 and 10MHz operation (max ?) */
+#define AR5K_INIT_RX_LAT_MAX 63
+/* Tx latencies from initvals (5212 only but no problem
+ * because we only tweak them on 5212) */
+#define AR5K_INIT_TX_LAT_A 54
+#define AR5K_INIT_TX_LAT_BG 384
+/* Tx latency for 40MHz (turbo) operation (min ?) */
+#define AR5K_INIT_TX_LAT_MIN 32
+/* Default Tx/Rx latencies (same for 5211)*/
+#define AR5K_INIT_TX_LATENCY_5210 54
+#define AR5K_INIT_RX_LATENCY_5210 29
+
+/* Tx frame to Tx data start delay */
+#define AR5K_INIT_TXF2TXD_START_DEFAULT 14
+#define AR5K_INIT_TXF2TXD_START_DELAY_10MHZ 12
+#define AR5K_INIT_TXF2TXD_START_DELAY_5MHZ 13
+
+/* We need to increase PHY switch and agc settling time
+ * on turbo mode */
+#define AR5K_SWITCH_SETTLING 5760
+#define AR5K_SWITCH_SETTLING_TURBO 7168
+
+#define AR5K_AGC_SETTLING 28
+/* 38 on 5210 but shouldn't matter */
+#define AR5K_AGC_SETTLING_TURBO 37
/* GENERIC CHIPSET DEFINITIONS */
@@ -303,12 +319,19 @@ struct ath5k_srev_name {
#define AR5K_SREV_AR5311B 0x30 /* Spirit */
#define AR5K_SREV_AR5211 0x40 /* Oahu */
#define AR5K_SREV_AR5212 0x50 /* Venice */
+#define AR5K_SREV_AR5312_R2 0x52 /* AP31 */
#define AR5K_SREV_AR5212_V4 0x54 /* ??? */
#define AR5K_SREV_AR5213 0x55 /* ??? */
+#define AR5K_SREV_AR5312_R7 0x57 /* AP30 */
+#define AR5K_SREV_AR2313_R8 0x58 /* AP43 */
#define AR5K_SREV_AR5213A 0x59 /* Hainan */
#define AR5K_SREV_AR2413 0x78 /* Griffin lite */
#define AR5K_SREV_AR2414 0x70 /* Griffin */
+#define AR5K_SREV_AR2315_R6 0x86 /* AP51-Light */
+#define AR5K_SREV_AR2315_R7 0x87 /* AP51-Full */
#define AR5K_SREV_AR5424 0x90 /* Condor */
+#define AR5K_SREV_AR2317_R1 0x90 /* AP61-Light */
+#define AR5K_SREV_AR2317_R2 0x91 /* AP61-Full */
#define AR5K_SREV_AR5413 0xa4 /* Eagle lite */
#define AR5K_SREV_AR5414 0xa0 /* Eagle */
#define AR5K_SREV_AR2415 0xb0 /* Talon */
@@ -404,12 +427,10 @@ struct ath5k_srev_name {
enum ath5k_driver_mode {
AR5K_MODE_11A = 0,
- AR5K_MODE_11A_TURBO = 1,
- AR5K_MODE_11B = 2,
- AR5K_MODE_11G = 3,
- AR5K_MODE_11G_TURBO = 4,
+ AR5K_MODE_11B = 1,
+ AR5K_MODE_11G = 2,
AR5K_MODE_XR = 0,
- AR5K_MODE_MAX = 5
+ AR5K_MODE_MAX = 3
};
enum ath5k_ant_mode {
@@ -423,6 +444,12 @@ enum ath5k_ant_mode {
AR5K_ANTMODE_MAX,
};
+enum ath5k_bw_mode {
+ AR5K_BWMODE_DEFAULT = 0, /* 20MHz, default operation */
+ AR5K_BWMODE_5MHZ = 1, /* Quarter rate */
+ AR5K_BWMODE_10MHZ = 2, /* Half rate */
+ AR5K_BWMODE_40MHZ = 3 /* Turbo */
+};
/****************\
TX DEFINITIONS
@@ -655,7 +682,6 @@ struct ath5k_gain {
/* channel_flags */
#define CHANNEL_CW_INT 0x0008 /* Contention Window interference detected */
-#define CHANNEL_TURBO 0x0010 /* Turbo Channel */
#define CHANNEL_CCK 0x0020 /* CCK channel */
#define CHANNEL_OFDM 0x0040 /* OFDM channel */
#define CHANNEL_2GHZ 0x0080 /* 2GHz channel. */
@@ -667,16 +693,10 @@ struct ath5k_gain {
#define CHANNEL_A (CHANNEL_5GHZ|CHANNEL_OFDM)
#define CHANNEL_B (CHANNEL_2GHZ|CHANNEL_CCK)
#define CHANNEL_G (CHANNEL_2GHZ|CHANNEL_OFDM)
-#define CHANNEL_T (CHANNEL_5GHZ|CHANNEL_OFDM|CHANNEL_TURBO)
-#define CHANNEL_TG (CHANNEL_2GHZ|CHANNEL_OFDM|CHANNEL_TURBO)
-#define CHANNEL_108A CHANNEL_T
-#define CHANNEL_108G CHANNEL_TG
#define CHANNEL_X (CHANNEL_5GHZ|CHANNEL_OFDM|CHANNEL_XR)
-#define CHANNEL_ALL (CHANNEL_OFDM|CHANNEL_CCK|CHANNEL_2GHZ|CHANNEL_5GHZ| \
- CHANNEL_TURBO)
+#define CHANNEL_ALL (CHANNEL_OFDM|CHANNEL_CCK|CHANNEL_2GHZ|CHANNEL_5GHZ)
-#define CHANNEL_ALL_NOTURBO (CHANNEL_ALL & ~CHANNEL_TURBO)
#define CHANNEL_MODES CHANNEL_ALL
/*
@@ -1025,7 +1045,6 @@ struct ath5k_hw {
enum ath5k_int ah_imr;
struct ieee80211_channel *ah_current_channel;
- bool ah_turbo;
bool ah_calibration;
bool ah_single_chip;
@@ -1034,6 +1053,7 @@ struct ath5k_hw {
u32 ah_phy;
u32 ah_mac_srev;
u16 ah_mac_version;
+ u16 ah_mac_revision;
u16 ah_phy_revision;
u16 ah_radio_5ghz_revision;
u16 ah_radio_2ghz_revision;
@@ -1043,6 +1063,8 @@ struct ath5k_hw {
u32 ah_limit_tx_retries;
u8 ah_coverage_class;
+ bool ah_ack_bitrate_high;
+ u8 ah_bwmode;
/* Antenna Control */
u32 ah_ant_ctl[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
@@ -1102,7 +1124,7 @@ struct ath5k_hw {
struct ath5k_nfcal_hist ah_nfcal_hist;
/* average beacon RSSI in our BSS (used by ANI) */
- struct ath5k_avg_val ah_beacon_rssi_avg;
+ struct ewma ah_beacon_rssi_avg;
/* noise floor from last periodic calibration */
s32 ah_noise_floor;
@@ -1131,36 +1153,50 @@ struct ath5k_hw {
/*
* Prototypes
*/
+extern const struct ieee80211_ops ath5k_hw_ops;
-/* Attach/Detach Functions */
-int ath5k_hw_attach(struct ath5k_softc *sc);
-void ath5k_hw_detach(struct ath5k_hw *ah);
+/* Initialization and detach functions */
+int ath5k_init_softc(struct ath5k_softc *sc, const struct ath_bus_ops *bus_ops);
+void ath5k_deinit_softc(struct ath5k_softc *sc);
+int ath5k_hw_init(struct ath5k_softc *sc);
+void ath5k_hw_deinit(struct ath5k_hw *ah);
int ath5k_sysfs_register(struct ath5k_softc *sc);
void ath5k_sysfs_unregister(struct ath5k_softc *sc);
+/*Chip id helper functions */
+const char *ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val);
+int ath5k_hw_read_srev(struct ath5k_hw *ah);
+
/* LED functions */
int ath5k_init_leds(struct ath5k_softc *sc);
void ath5k_led_enable(struct ath5k_softc *sc);
void ath5k_led_off(struct ath5k_softc *sc);
void ath5k_unregister_leds(struct ath5k_softc *sc);
+
/* Reset Functions */
int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial);
int ath5k_hw_on_hold(struct ath5k_hw *ah);
int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
- struct ieee80211_channel *channel, bool change_channel);
+ struct ieee80211_channel *channel, bool fast, bool skip_pcu);
int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val,
bool is_set);
/* Power management functions */
+
+/* Clock rate related functions */
+unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec);
+unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock);
+void ath5k_hw_set_clockrate(struct ath5k_hw *ah);
+
+
/* DMA Related Functions */
void ath5k_hw_start_rx_dma(struct ath5k_hw *ah);
-int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah);
u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah);
-void ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr);
+int ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr);
int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue);
-int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue);
+int ath5k_hw_stop_beacon_queue(struct ath5k_hw *ah, unsigned int queue);
u32 ath5k_hw_get_txdp(struct ath5k_hw *ah, unsigned int queue);
int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue,
u32 phys_addr);
@@ -1170,38 +1206,43 @@ bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah);
int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask);
enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum ath5k_int new_mask);
void ath5k_hw_update_mib_counters(struct ath5k_hw *ah);
+/* Init/Stop functions */
+void ath5k_hw_dma_init(struct ath5k_hw *ah);
+int ath5k_hw_dma_stop(struct ath5k_hw *ah);
/* EEPROM access functions */
int ath5k_eeprom_init(struct ath5k_hw *ah);
void ath5k_eeprom_detach(struct ath5k_hw *ah);
int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac);
+
/* Protocol Control Unit Functions */
+/* Helpers */
+int ath5k_hw_get_frame_duration(struct ath5k_hw *ah,
+ int len, struct ieee80211_rate *rate);
+unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah);
+unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah);
extern int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype opmode);
void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class);
-/* BSSID Functions */
+/* RX filter control*/
int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac);
void ath5k_hw_set_bssid(struct ath5k_hw *ah);
void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask);
-/* Receive start/stop functions */
-void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah);
-void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah);
-/* RX Filter functions */
void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1);
u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah);
void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter);
+/* Receive (DRU) start/stop functions */
+void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah);
+void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah);
/* Beacon control functions */
u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah);
void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64);
void ath5k_hw_reset_tsf(struct ath5k_hw *ah);
void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval);
bool ath5k_hw_check_beacon_timers(struct ath5k_hw *ah, int intval);
-/* ACK bit rate */
-void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high);
-/* Clock rate related functions */
-unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec);
-unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock);
-void ath5k_hw_set_clockrate(struct ath5k_hw *ah);
+/* Init function */
+void ath5k_hw_pcu_init(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
+ u8 mode);
/* Queue Control Unit, DFS Control Unit Functions */
int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue,
@@ -1214,7 +1255,9 @@ int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah,
u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue);
void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue);
int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue);
-int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time);
+int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time);
+/* Init function */
+int ath5k_hw_init_queues(struct ath5k_hw *ah);
/* Hardware Descriptor Functions */
int ath5k_hw_init_desc_functions(struct ath5k_hw *ah);
@@ -1224,6 +1267,7 @@ int ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2,
u_int tx_tries2, unsigned int tx_rate3, u_int tx_tries3);
+
/* GPIO Functions */
void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state);
int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio);
@@ -1233,11 +1277,13 @@ int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val);
void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio,
u32 interrupt_level);
-/* rfkill Functions */
+
+/* RFkill Functions */
void ath5k_rfkill_hw_start(struct ath5k_hw *ah);
void ath5k_rfkill_hw_stop(struct ath5k_hw *ah);
-/* Misc functions */
+
+/* Misc functions TODO: Cleanup */
int ath5k_hw_set_capabilities(struct ath5k_hw *ah);
int ath5k_hw_get_capability(struct ath5k_hw *ah,
enum ath5k_capability_type cap_type, u32 capability,
@@ -1245,19 +1291,20 @@ int ath5k_hw_get_capability(struct ath5k_hw *ah,
int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid, u16 assoc_id);
int ath5k_hw_disable_pspoll(struct ath5k_hw *ah);
+
/* Initial register settings functions */
int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel);
-/* Initialize RF */
-int ath5k_hw_rfregs_init(struct ath5k_hw *ah,
- struct ieee80211_channel *channel,
- unsigned int mode);
-int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq);
+
+/* PHY functions */
+/* Misc PHY functions */
+u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan);
+int ath5k_hw_phy_disable(struct ath5k_hw *ah);
+/* Gain_F optimization */
enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah);
int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah);
/* PHY/RF channel functions */
bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags);
-int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel);
/* PHY calibration */
void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah);
int ath5k_hw_phy_calibrate(struct ath5k_hw *ah,
@@ -1266,18 +1313,14 @@ void ath5k_hw_update_noise_floor(struct ath5k_hw *ah);
/* Spur mitigation */
bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
struct ieee80211_channel *channel);
-void ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
- struct ieee80211_channel *channel);
-/* Misc PHY functions */
-u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan);
-int ath5k_hw_phy_disable(struct ath5k_hw *ah);
/* Antenna control */
void ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode);
void ath5k_hw_set_antenna_switch(struct ath5k_hw *ah, u8 ee_mode);
/* TX power setup */
-int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
- u8 ee_mode, u8 txpower);
int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower);
+/* Init function */
+int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
+ u8 mode, u8 ee_mode, u8 freq, bool fast);
/*
* Functions used internaly
@@ -1293,6 +1336,32 @@ static inline struct ath_regulatory *ath5k_hw_regulatory(struct ath5k_hw *ah)
return &(ath5k_hw_common(ah)->regulatory);
}
+#ifdef CONFIG_ATHEROS_AR231X
+#define AR5K_AR2315_PCI_BASE ((void __iomem *)0xb0100000)
+
+static inline void __iomem *ath5k_ahb_reg(struct ath5k_hw *ah, u16 reg)
+{
+ /* On AR2315 and AR2317 the PCI clock domain registers
+ * are outside of the WMAC register space */
+ if (unlikely((reg >= 0x4000) && (reg < 0x5000) &&
+ (ah->ah_mac_srev >= AR5K_SREV_AR2315_R6)))
+ return AR5K_AR2315_PCI_BASE + reg;
+
+ return ah->ah_iobase + reg;
+}
+
+static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
+{
+ return __raw_readl(ath5k_ahb_reg(ah, reg));
+}
+
+static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
+{
+ __raw_writel(val, ath5k_ahb_reg(ah, reg));
+}
+
+#else
+
static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
{
return ioread32(ah->ah_iobase + reg);
@@ -1303,6 +1372,24 @@ static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
iowrite32(val, ah->ah_iobase + reg);
}
+#endif
+
+static inline enum ath_bus_type ath5k_get_bus_type(struct ath5k_hw *ah)
+{
+ return ath5k_hw_common(ah)->bus_ops->ath_bus_type;
+}
+
+static inline void ath5k_read_cachesize(struct ath_common *common, int *csz)
+{
+ common->bus_ops->read_cachesize(common, csz);
+}
+
+static inline bool ath5k_hw_nvram_read(struct ath5k_hw *ah, u32 off, u16 *data)
+{
+ struct ath_common *common = ath5k_hw_common(ah);
+ return common->bus_ops->eeprom_read(common, off, data);
+}
+
static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits)
{
u32 retval = 0, bit, i;
@@ -1315,27 +1402,4 @@ static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits)
return retval;
}
-#define AVG_SAMPLES 8
-#define AVG_FACTOR 1000
-
-/**
- * ath5k_moving_average - Exponentially weighted moving average
- * @avg: average structure
- * @val: current value
- *
- * This implementation make use of a struct ath5k_avg_val to prevent rounding
- * errors.
- */
-static inline struct ath5k_avg_val
-ath5k_moving_average(const struct ath5k_avg_val avg, const int val)
-{
- struct ath5k_avg_val new;
- new.avg_weight = avg.avg_weight ?
- (((avg.avg_weight * ((AVG_SAMPLES) - 1)) +
- (val * (AVG_FACTOR))) / (AVG_SAMPLES)) :
- (val * (AVG_FACTOR));
- new.avg = new.avg_weight / (AVG_FACTOR);
- return new;
-}
-
#endif
diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c
index fbe8aca975d8..9dbc1fa81795 100644
--- a/drivers/net/wireless/ath/ath5k/attach.c
+++ b/drivers/net/wireless/ath/ath5k/attach.c
@@ -93,16 +93,16 @@ static int ath5k_hw_post(struct ath5k_hw *ah)
}
/**
- * ath5k_hw_attach - Check if hw is supported and init the needed structs
+ * ath5k_hw_init - Check if hw is supported and init the needed structs
*
- * @sc: The &struct ath5k_softc we got from the driver's attach function
+ * @sc: The &struct ath5k_softc we got from the driver's init_softc function
*
* Check if the device is supported, perform a POST and initialize the needed
* structs. Returns -ENOMEM if we don't have memory for the needed structs,
* -ENODEV if the device is not supported or prints an error msg if something
* else went wrong.
*/
-int ath5k_hw_attach(struct ath5k_softc *sc)
+int ath5k_hw_init(struct ath5k_softc *sc)
{
struct ath5k_hw *ah = sc->ah;
struct ath_common *common = ath5k_hw_common(ah);
@@ -115,7 +115,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
* HW information
*/
ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT;
- ah->ah_turbo = false;
+ ah->ah_bwmode = AR5K_BWMODE_DEFAULT;
ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
ah->ah_imr = 0;
ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY;
@@ -128,7 +128,8 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
/*
* Find the mac version
*/
- srev = ath5k_hw_reg_read(ah, AR5K_SREV);
+ ath5k_hw_read_srev(ah);
+ srev = ah->ah_mac_srev;
if (srev < AR5K_SREV_AR5311)
ah->ah_version = AR5K_AR5210;
else if (srev < AR5K_SREV_AR5212)
@@ -136,6 +137,10 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
else
ah->ah_version = AR5K_AR5212;
+ /* Get the MAC revision */
+ ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER);
+ ah->ah_mac_revision = AR5K_REG_MS(srev, AR5K_SREV_REV);
+
/* Fill the ath5k_hw struct with the needed functions */
ret = ath5k_hw_init_desc_functions(ah);
if (ret)
@@ -146,9 +151,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
if (ret)
goto err;
- /* Get MAC, PHY and RADIO revisions */
- ah->ah_mac_srev = srev;
- ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER);
+ /* Get PHY and RADIO revisions */
ah->ah_phy_revision = ath5k_hw_reg_read(ah, AR5K_PHY_CHIP_ID) &
0xffffffff;
ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah,
@@ -273,7 +276,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
/*
* Write PCI-E power save settings
*/
- if ((ah->ah_version == AR5K_AR5212) && (pdev->is_pcie)) {
+ if ((ah->ah_version == AR5K_AR5212) && pdev && (pdev->is_pcie)) {
ath5k_hw_reg_write(ah, 0x9248fc00, AR5K_PCIE_SERDES);
ath5k_hw_reg_write(ah, 0x24924924, AR5K_PCIE_SERDES);
@@ -305,8 +308,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
/* Get misc capabilities */
ret = ath5k_hw_set_capabilities(ah);
if (ret) {
- ATH5K_ERR(sc, "unable to get device capabilities: 0x%04x\n",
- sc->pdev->device);
+ ATH5K_ERR(sc, "unable to get device capabilities\n");
goto err;
}
@@ -346,11 +348,11 @@ err:
}
/**
- * ath5k_hw_detach - Free the ath5k_hw struct
+ * ath5k_hw_deinit - Free the ath5k_hw struct
*
* @ah: The &struct ath5k_hw
*/
-void ath5k_hw_detach(struct ath5k_hw *ah)
+void ath5k_hw_deinit(struct ath5k_hw *ah)
{
__set_bit(ATH_STAT_INVALID, ah->ah_sc->status);
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 42ed923cdb1a..4e3b97c3d7c2 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -47,8 +47,6 @@
#include <linux/io.h>
#include <linux/netdevice.h>
#include <linux/cache.h>
-#include <linux/pci.h>
-#include <linux/pci-aspm.h>
#include <linux/ethtool.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
@@ -62,7 +60,6 @@
#include "reg.h"
#include "debug.h"
#include "ani.h"
-#include "../debug.h"
static int modparam_nohwcrypt;
module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
@@ -78,39 +75,25 @@ MODULE_AUTHOR("Nick Kossifidis");
MODULE_DESCRIPTION("Support for 5xxx series of Atheros 802.11 wireless LAN cards.");
MODULE_SUPPORTED_DEVICE("Atheros 5xxx WLAN cards");
MODULE_LICENSE("Dual BSD/GPL");
-MODULE_VERSION("0.6.0 (EXPERIMENTAL)");
-static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan);
+static int ath5k_init(struct ieee80211_hw *hw);
+static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan,
+ bool skip_pcu);
static int ath5k_beacon_update(struct ieee80211_hw *hw,
struct ieee80211_vif *vif);
static void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf);
-/* Known PCI ids */
-static DEFINE_PCI_DEVICE_TABLE(ath5k_pci_id_table) = {
- { PCI_VDEVICE(ATHEROS, 0x0207) }, /* 5210 early */
- { PCI_VDEVICE(ATHEROS, 0x0007) }, /* 5210 */
- { PCI_VDEVICE(ATHEROS, 0x0011) }, /* 5311 - this is on AHB bus !*/
- { PCI_VDEVICE(ATHEROS, 0x0012) }, /* 5211 */
- { PCI_VDEVICE(ATHEROS, 0x0013) }, /* 5212 */
- { PCI_VDEVICE(3COM_2, 0x0013) }, /* 3com 5212 */
- { PCI_VDEVICE(3COM, 0x0013) }, /* 3com 3CRDAG675 5212 */
- { PCI_VDEVICE(ATHEROS, 0x1014) }, /* IBM minipci 5212 */
- { PCI_VDEVICE(ATHEROS, 0x0014) }, /* 5212 combatible */
- { PCI_VDEVICE(ATHEROS, 0x0015) }, /* 5212 combatible */
- { PCI_VDEVICE(ATHEROS, 0x0016) }, /* 5212 combatible */
- { PCI_VDEVICE(ATHEROS, 0x0017) }, /* 5212 combatible */
- { PCI_VDEVICE(ATHEROS, 0x0018) }, /* 5212 combatible */
- { PCI_VDEVICE(ATHEROS, 0x0019) }, /* 5212 combatible */
- { PCI_VDEVICE(ATHEROS, 0x001a) }, /* 2413 Griffin-lite */
- { PCI_VDEVICE(ATHEROS, 0x001b) }, /* 5413 Eagle */
- { PCI_VDEVICE(ATHEROS, 0x001c) }, /* PCI-E cards */
- { PCI_VDEVICE(ATHEROS, 0x001d) }, /* 2417 Nala */
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, ath5k_pci_id_table);
-
/* Known SREVs */
static const struct ath5k_srev_name srev_names[] = {
+#ifdef CONFIG_ATHEROS_AR231X
+ { "5312", AR5K_VERSION_MAC, AR5K_SREV_AR5312_R2 },
+ { "5312", AR5K_VERSION_MAC, AR5K_SREV_AR5312_R7 },
+ { "2313", AR5K_VERSION_MAC, AR5K_SREV_AR2313_R8 },
+ { "2315", AR5K_VERSION_MAC, AR5K_SREV_AR2315_R6 },
+ { "2315", AR5K_VERSION_MAC, AR5K_SREV_AR2315_R7 },
+ { "2317", AR5K_VERSION_MAC, AR5K_SREV_AR2317_R1 },
+ { "2317", AR5K_VERSION_MAC, AR5K_SREV_AR2317_R2 },
+#else
{ "5210", AR5K_VERSION_MAC, AR5K_SREV_AR5210 },
{ "5311", AR5K_VERSION_MAC, AR5K_SREV_AR5311 },
{ "5311A", AR5K_VERSION_MAC, AR5K_SREV_AR5311A },
@@ -129,6 +112,7 @@ static const struct ath5k_srev_name srev_names[] = {
{ "5418", AR5K_VERSION_MAC, AR5K_SREV_AR5418 },
{ "2425", AR5K_VERSION_MAC, AR5K_SREV_AR2425 },
{ "2417", AR5K_VERSION_MAC, AR5K_SREV_AR2417 },
+#endif
{ "xxxxx", AR5K_VERSION_MAC, AR5K_SREV_UNKNOWN },
{ "5110", AR5K_VERSION_RAD, AR5K_SREV_RAD_5110 },
{ "5111", AR5K_VERSION_RAD, AR5K_SREV_RAD_5111 },
@@ -142,10 +126,12 @@ static const struct ath5k_srev_name srev_names[] = {
{ "2112B", AR5K_VERSION_RAD, AR5K_SREV_RAD_2112B },
{ "2413", AR5K_VERSION_RAD, AR5K_SREV_RAD_2413 },
{ "5413", AR5K_VERSION_RAD, AR5K_SREV_RAD_5413 },
- { "2316", AR5K_VERSION_RAD, AR5K_SREV_RAD_2316 },
- { "2317", AR5K_VERSION_RAD, AR5K_SREV_RAD_2317 },
{ "5424", AR5K_VERSION_RAD, AR5K_SREV_RAD_5424 },
{ "5133", AR5K_VERSION_RAD, AR5K_SREV_RAD_5133 },
+#ifdef CONFIG_ATHEROS_AR231X
+ { "2316", AR5K_VERSION_RAD, AR5K_SREV_RAD_2316 },
+ { "2317", AR5K_VERSION_RAD, AR5K_SREV_RAD_2317 },
+#endif
{ "xxxxx", AR5K_VERSION_RAD, AR5K_SREV_UNKNOWN },
};
@@ -197,8 +183,8 @@ static inline void ath5k_txbuf_free_skb(struct ath5k_softc *sc,
BUG_ON(!bf);
if (!bf->skb)
return;
- pci_unmap_single(sc->pdev, bf->skbaddr, bf->skb->len,
- PCI_DMA_TODEVICE);
+ dma_unmap_single(sc->dev, bf->skbaddr, bf->skb->len,
+ DMA_TO_DEVICE);
dev_kfree_skb_any(bf->skb);
bf->skb = NULL;
bf->skbaddr = 0;
@@ -214,8 +200,8 @@ static inline void ath5k_rxbuf_free_skb(struct ath5k_softc *sc,
BUG_ON(!bf);
if (!bf->skb)
return;
- pci_unmap_single(sc->pdev, bf->skbaddr, common->rx_bufsize,
- PCI_DMA_FROMDEVICE);
+ dma_unmap_single(sc->dev, bf->skbaddr, common->rx_bufsize,
+ DMA_FROM_DEVICE);
dev_kfree_skb_any(bf->skb);
bf->skb = NULL;
bf->skbaddr = 0;
@@ -233,7 +219,7 @@ static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp)
return (tsf & ~0x7fff) | rstamp;
}
-static const char *
+const char *
ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val)
{
const char *name = "xxxxx";
@@ -327,14 +313,12 @@ ath5k_copy_channels(struct ath5k_hw *ah,
switch (mode) {
case AR5K_MODE_11A:
- case AR5K_MODE_11A_TURBO:
/* 1..220, but 2GHz frequencies are filtered by check_channel */
size = 220 ;
chfreq = CHANNEL_5GHZ;
break;
case AR5K_MODE_11B:
case AR5K_MODE_11G:
- case AR5K_MODE_11G_TURBO:
size = 26;
chfreq = CHANNEL_2GHZ;
break;
@@ -363,11 +347,6 @@ ath5k_copy_channels(struct ath5k_hw *ah,
case AR5K_MODE_11G:
channels[count].hw_value = chfreq | CHANNEL_OFDM;
break;
- case AR5K_MODE_11A_TURBO:
- case AR5K_MODE_11G_TURBO:
- channels[count].hw_value = chfreq |
- CHANNEL_OFDM | CHANNEL_TURBO;
- break;
case AR5K_MODE_11B:
channels[count].hw_value = CHANNEL_B;
}
@@ -496,7 +475,7 @@ ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan)
* hardware at the new frequency, and then re-enable
* the relevant bits of the h/w.
*/
- return ath5k_reset(sc, chan);
+ return ath5k_reset(sc, chan, true);
}
static void
@@ -549,7 +528,7 @@ static void ath_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
/* Calculate combined mode - when APs are active, operate in AP mode.
* Otherwise use the mode of the new interface. This can currently
* only deal with combinations of APs and STAs. Only one ad-hoc
- * interfaces is allowed above.
+ * interfaces is allowed.
*/
if (avf->opmode == NL80211_IFTYPE_AP)
iter_data->opmode = NL80211_IFTYPE_AP;
@@ -558,16 +537,8 @@ static void ath_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
iter_data->opmode = avf->opmode;
}
-static void ath_do_set_opmode(struct ath5k_softc *sc)
-{
- struct ath5k_hw *ah = sc->ah;
- ath5k_hw_set_opmode(ah, sc->opmode);
- ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "mode setup opmode %d (%s)\n",
- sc->opmode, ath_opmode_to_string(sc->opmode));
-}
-
-void ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc,
- struct ieee80211_vif *vif)
+static void ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc,
+ struct ieee80211_vif *vif)
{
struct ath_common *common = ath5k_hw_common(sc->ah);
struct ath_vif_iter_data iter_data;
@@ -595,7 +566,9 @@ void ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc,
/* Nothing active, default to station mode */
sc->opmode = NL80211_IFTYPE_STATION;
- ath_do_set_opmode(sc);
+ ath5k_hw_set_opmode(sc->ah, sc->opmode);
+ ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "mode setup opmode %d (%s)\n",
+ sc->opmode, ath_opmode_to_string(sc->opmode));
if (iter_data.need_set_hw_addr && iter_data.found_active)
ath5k_hw_set_lladdr(sc->ah, iter_data.active_mac);
@@ -659,10 +632,11 @@ struct sk_buff *ath5k_rx_skb_alloc(struct ath5k_softc *sc, dma_addr_t *skb_addr)
return NULL;
}
- *skb_addr = pci_map_single(sc->pdev,
+ *skb_addr = dma_map_single(sc->dev,
skb->data, common->rx_bufsize,
- PCI_DMA_FROMDEVICE);
- if (unlikely(pci_dma_mapping_error(sc->pdev, *skb_addr))) {
+ DMA_FROM_DEVICE);
+
+ if (unlikely(dma_mapping_error(sc->dev, *skb_addr))) {
ATH5K_ERR(sc, "%s: DMA mapping failed\n", __func__);
dev_kfree_skb(skb);
return NULL;
@@ -758,8 +732,8 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK;
/* XXX endianness */
- bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len,
- PCI_DMA_TODEVICE);
+ bf->skbaddr = dma_map_single(sc->dev, skb->data, skb->len,
+ DMA_TO_DEVICE);
rate = ieee80211_get_tx_rate(sc->hw, info);
if (!rate) {
@@ -839,7 +813,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
return 0;
err_unmap:
- pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, PCI_DMA_TODEVICE);
+ dma_unmap_single(sc->dev, bf->skbaddr, skb->len, DMA_TO_DEVICE);
return ret;
}
@@ -848,7 +822,7 @@ err_unmap:
\*******************/
static int
-ath5k_desc_alloc(struct ath5k_softc *sc, struct pci_dev *pdev)
+ath5k_desc_alloc(struct ath5k_softc *sc)
{
struct ath5k_desc *ds;
struct ath5k_buf *bf;
@@ -859,7 +833,9 @@ ath5k_desc_alloc(struct ath5k_softc *sc, struct pci_dev *pdev)
/* allocate descriptors */
sc->desc_len = sizeof(struct ath5k_desc) *
(ATH_TXBUF + ATH_RXBUF + ATH_BCBUF + 1);
- sc->desc = pci_alloc_consistent(pdev, sc->desc_len, &sc->desc_daddr);
+
+ sc->desc = dma_alloc_coherent(sc->dev, sc->desc_len,
+ &sc->desc_daddr, GFP_KERNEL);
if (sc->desc == NULL) {
ATH5K_ERR(sc, "can't allocate descriptors\n");
ret = -ENOMEM;
@@ -905,14 +881,14 @@ ath5k_desc_alloc(struct ath5k_softc *sc, struct pci_dev *pdev)
return 0;
err_free:
- pci_free_consistent(pdev, sc->desc_len, sc->desc, sc->desc_daddr);
+ dma_free_coherent(sc->dev, sc->desc_len, sc->desc, sc->desc_daddr);
err:
sc->desc = NULL;
return ret;
}
static void
-ath5k_desc_free(struct ath5k_softc *sc, struct pci_dev *pdev)
+ath5k_desc_free(struct ath5k_softc *sc)
{
struct ath5k_buf *bf;
@@ -924,7 +900,7 @@ ath5k_desc_free(struct ath5k_softc *sc, struct pci_dev *pdev)
ath5k_txbuf_free_skb(sc, bf);
/* Free memory associated with all descriptors */
- pci_free_consistent(pdev, sc->desc_len, sc->desc, sc->desc_daddr);
+ dma_free_coherent(sc->dev, sc->desc_len, sc->desc, sc->desc_daddr);
sc->desc = NULL;
sc->desc_daddr = 0;
@@ -1069,62 +1045,44 @@ err:
return ret;
}
+/**
+ * ath5k_drain_tx_buffs - Empty tx buffers
+ *
+ * @sc The &struct ath5k_softc
+ *
+ * Empty tx buffers from all queues in preparation
+ * of a reset or during shutdown.
+ *
+ * NB: this assumes output has been stopped and
+ * we do not need to block ath5k_tx_tasklet
+ */
static void
-ath5k_txq_drainq(struct ath5k_softc *sc, struct ath5k_txq *txq)
+ath5k_drain_tx_buffs(struct ath5k_softc *sc)
{
+ struct ath5k_txq *txq;
struct ath5k_buf *bf, *bf0;
+ int i;
- /*
- * NB: this assumes output has been stopped and
- * we do not need to block ath5k_tx_tasklet
- */
- spin_lock_bh(&txq->lock);
- list_for_each_entry_safe(bf, bf0, &txq->q, list) {
- ath5k_debug_printtxbuf(sc, bf);
-
- ath5k_txbuf_free_skb(sc, bf);
-
- spin_lock_bh(&sc->txbuflock);
- list_move_tail(&bf->list, &sc->txbuf);
- sc->txbuf_len++;
- txq->txq_len--;
- spin_unlock_bh(&sc->txbuflock);
- }
- txq->link = NULL;
- txq->txq_poll_mark = false;
- spin_unlock_bh(&txq->lock);
-}
+ for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) {
+ if (sc->txqs[i].setup) {
+ txq = &sc->txqs[i];
+ spin_lock_bh(&txq->lock);
+ list_for_each_entry_safe(bf, bf0, &txq->q, list) {
+ ath5k_debug_printtxbuf(sc, bf);
-/*
- * Drain the transmit queues and reclaim resources.
- */
-static void
-ath5k_txq_cleanup(struct ath5k_softc *sc)
-{
- struct ath5k_hw *ah = sc->ah;
- unsigned int i;
+ ath5k_txbuf_free_skb(sc, bf);
- /* XXX return value */
- if (likely(!test_bit(ATH_STAT_INVALID, sc->status))) {
- /* don't touch the hardware if marked invalid */
- ath5k_hw_stop_tx_dma(ah, sc->bhalq);
- ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "beacon queue %x\n",
- ath5k_hw_get_txdp(ah, sc->bhalq));
- for (i = 0; i < ARRAY_SIZE(sc->txqs); i++)
- if (sc->txqs[i].setup) {
- ath5k_hw_stop_tx_dma(ah, sc->txqs[i].qnum);
- ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "txq [%u] %x, "
- "link %p\n",
- sc->txqs[i].qnum,
- ath5k_hw_get_txdp(ah,
- sc->txqs[i].qnum),
- sc->txqs[i].link);
+ spin_lock_bh(&sc->txbuflock);
+ list_move_tail(&bf->list, &sc->txbuf);
+ sc->txbuf_len++;
+ txq->txq_len--;
+ spin_unlock_bh(&sc->txbuflock);
}
+ txq->link = NULL;
+ txq->txq_poll_mark = false;
+ spin_unlock_bh(&txq->lock);
+ }
}
-
- for (i = 0; i < ARRAY_SIZE(sc->txqs); i++)
- if (sc->txqs[i].setup)
- ath5k_txq_drainq(sc, &sc->txqs[i]);
}
static void
@@ -1184,16 +1142,19 @@ err:
}
/*
- * Disable the receive h/w in preparation for a reset.
+ * Disable the receive logic on PCU (DRU)
+ * In preparation for a shutdown.
+ *
+ * Note: Doesn't stop rx DMA, ath5k_hw_dma_stop
+ * does.
*/
static void
ath5k_rx_stop(struct ath5k_softc *sc)
{
struct ath5k_hw *ah = sc->ah;
- ath5k_hw_stop_rx_pcu(ah); /* disable PCU */
ath5k_hw_set_rx_filter(ah, 0); /* clear recv filter */
- ath5k_hw_stop_rx_dma(ah); /* disable DMA engine */
+ ath5k_hw_stop_rx_pcu(ah); /* disable PCU */
ath5k_debug_printrxbuffs(sc, ah);
}
@@ -1307,8 +1268,7 @@ ath5k_update_beacon_rssi(struct ath5k_softc *sc, struct sk_buff *skb, int rssi)
memcmp(mgmt->bssid, common->curbssid, ETH_ALEN) != 0)
return;
- ah->ah_beacon_rssi_avg = ath5k_moving_average(ah->ah_beacon_rssi_avg,
- rssi);
+ ewma_add(&ah->ah_beacon_rssi_avg, rssi);
/* in IBSS mode we should keep RSSI statistics per neighbour */
/* le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS */
@@ -1551,9 +1511,9 @@ ath5k_tasklet_rx(unsigned long data)
if (!next_skb)
goto next;
- pci_unmap_single(sc->pdev, bf->skbaddr,
+ dma_unmap_single(sc->dev, bf->skbaddr,
common->rx_bufsize,
- PCI_DMA_FROMDEVICE);
+ DMA_FROM_DEVICE);
skb_put(skb, rs.rs_datalen);
@@ -1716,8 +1676,9 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
skb = bf->skb;
bf->skb = NULL;
- pci_unmap_single(sc->pdev, bf->skbaddr, skb->len,
- PCI_DMA_TODEVICE);
+
+ dma_unmap_single(sc->dev, bf->skbaddr, skb->len,
+ DMA_TO_DEVICE);
ath5k_tx_frame_completed(sc, skb, &ts);
}
@@ -1771,12 +1732,13 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
u32 flags;
const int padsize = 0;
- bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len,
- PCI_DMA_TODEVICE);
+ bf->skbaddr = dma_map_single(sc->dev, skb->data, skb->len,
+ DMA_TO_DEVICE);
ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "skb %p [data %p len %u] "
"skbaddr %llx\n", skb, skb->data, skb->len,
(unsigned long long)bf->skbaddr);
- if (pci_dma_mapping_error(sc->pdev, bf->skbaddr)) {
+
+ if (dma_mapping_error(sc->dev, bf->skbaddr)) {
ATH5K_ERR(sc, "beacon DMA mapping failed\n");
return -EIO;
}
@@ -1828,7 +1790,7 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
return 0;
err_unmap:
- pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, PCI_DMA_TODEVICE);
+ dma_unmap_single(sc->dev, bf->skbaddr, skb->len, DMA_TO_DEVICE);
return ret;
}
@@ -1945,7 +1907,7 @@ ath5k_beacon_send(struct ath5k_softc *sc)
* This should never fail since we check above that no frames
* are still pending on the queue.
*/
- if (unlikely(ath5k_hw_stop_tx_dma(ah, sc->bhalq))) {
+ if (unlikely(ath5k_hw_stop_beacon_queue(ah, sc->bhalq))) {
ATH5K_WARN(sc, "beacon queue %u didn't start/stop ?\n", sc->bhalq);
/* NB: hw still stops DMA, so proceed */
}
@@ -2115,7 +2077,7 @@ ath5k_beacon_config(struct ath5k_softc *sc)
} else
ath5k_beacon_update_timers(sc, -1);
} else {
- ath5k_hw_stop_tx_dma(sc->ah, sc->bhalq);
+ ath5k_hw_stop_beacon_queue(sc->ah, sc->bhalq);
}
ath5k_hw_set_imr(ah, sc->imask);
@@ -2177,7 +2139,7 @@ ath5k_intr_calibration_poll(struct ath5k_hw *ah)
* AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI); */
}
-static irqreturn_t
+irqreturn_t
ath5k_intr(int irq, void *dev_id)
{
struct ath5k_softc *sc = dev_id;
@@ -2186,7 +2148,8 @@ ath5k_intr(int irq, void *dev_id)
unsigned int counter = 1000;
if (unlikely(test_bit(ATH_STAT_INVALID, sc->status) ||
- !ath5k_hw_is_intr_pending(ah)))
+ ((ath5k_get_bus_type(ah) != ATH_AHB) &&
+ !ath5k_hw_is_intr_pending(ah))))
return IRQ_NONE;
do {
@@ -2252,6 +2215,10 @@ ath5k_intr(int irq, void *dev_id)
tasklet_schedule(&sc->rf_kill.toggleq);
}
+
+ if (ath5k_get_bus_type(ah) == ATH_AHB)
+ break;
+
} while (ath5k_hw_is_intr_pending(ah) && --counter > 0);
if (unlikely(!counter))
@@ -2351,7 +2318,7 @@ ath5k_tx_complete_poll_work(struct work_struct *work)
if (needreset) {
ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
"TX queues stuck, resetting\n");
- ath5k_reset(sc, sc->curchan);
+ ath5k_reset(sc, NULL, true);
}
ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work,
@@ -2363,6 +2330,159 @@ ath5k_tx_complete_poll_work(struct work_struct *work)
* Initialization routines *
\*************************/
+int
+ath5k_init_softc(struct ath5k_softc *sc, const struct ath_bus_ops *bus_ops)
+{
+ struct ieee80211_hw *hw = sc->hw;
+ struct ath_common *common;
+ int ret;
+ int csz;
+
+ /* Initialize driver private data */
+ SET_IEEE80211_DEV(hw, sc->dev);
+ hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
+ IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
+ IEEE80211_HW_SIGNAL_DBM |
+ IEEE80211_HW_REPORTS_TX_ACK_STATUS;
+
+ hw->wiphy->interface_modes =
+ BIT(NL80211_IFTYPE_AP) |
+ BIT(NL80211_IFTYPE_STATION) |
+ BIT(NL80211_IFTYPE_ADHOC) |
+ BIT(NL80211_IFTYPE_MESH_POINT);
+
+ hw->extra_tx_headroom = 2;
+ hw->channel_change_time = 5000;
+
+ /*
+ * Mark the device as detached to avoid processing
+ * interrupts until setup is complete.
+ */
+ __set_bit(ATH_STAT_INVALID, sc->status);
+
+ sc->opmode = NL80211_IFTYPE_STATION;
+ sc->bintval = 1000;
+ mutex_init(&sc->lock);
+ spin_lock_init(&sc->rxbuflock);
+ spin_lock_init(&sc->txbuflock);
+ spin_lock_init(&sc->block);
+
+
+ /* Setup interrupt handler */
+ ret = request_irq(sc->irq, ath5k_intr, IRQF_SHARED, "ath", sc);
+ if (ret) {
+ ATH5K_ERR(sc, "request_irq failed\n");
+ goto err;
+ }
+
+ /* If we passed the test, malloc an ath5k_hw struct */
+ sc->ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL);
+ if (!sc->ah) {
+ ret = -ENOMEM;
+ ATH5K_ERR(sc, "out of memory\n");
+ goto err_irq;
+ }
+
+ sc->ah->ah_sc = sc;
+ sc->ah->ah_iobase = sc->iobase;
+ common = ath5k_hw_common(sc->ah);
+ common->ops = &ath5k_common_ops;
+ common->bus_ops = bus_ops;
+ common->ah = sc->ah;
+ common->hw = hw;
+ common->priv = sc;
+
+ /*
+ * Cache line size is used to size and align various
+ * structures used to communicate with the hardware.
+ */
+ ath5k_read_cachesize(common, &csz);
+ common->cachelsz = csz << 2; /* convert to bytes */
+
+ spin_lock_init(&common->cc_lock);
+
+ /* Initialize device */
+ ret = ath5k_hw_init(sc);
+ if (ret)
+ goto err_free_ah;
+
+ /* set up multi-rate retry capabilities */
+ if (sc->ah->ah_version == AR5K_AR5212) {
+ hw->max_rates = 4;
+ hw->max_rate_tries = 11;
+ }
+
+ hw->vif_data_size = sizeof(struct ath5k_vif);
+
+ /* Finish private driver data initialization */
+ ret = ath5k_init(hw);
+ if (ret)
+ goto err_ah;
+
+ ATH5K_INFO(sc, "Atheros AR%s chip found (MAC: 0x%x, PHY: 0x%x)\n",
+ ath5k_chip_name(AR5K_VERSION_MAC, sc->ah->ah_mac_srev),
+ sc->ah->ah_mac_srev,
+ sc->ah->ah_phy_revision);
+
+ if (!sc->ah->ah_single_chip) {
+ /* Single chip radio (!RF5111) */
+ if (sc->ah->ah_radio_5ghz_revision &&
+ !sc->ah->ah_radio_2ghz_revision) {
+ /* No 5GHz support -> report 2GHz radio */
+ if (!test_bit(AR5K_MODE_11A,
+ sc->ah->ah_capabilities.cap_mode)) {
+ ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n",
+ ath5k_chip_name(AR5K_VERSION_RAD,
+ sc->ah->ah_radio_5ghz_revision),
+ sc->ah->ah_radio_5ghz_revision);
+ /* No 2GHz support (5110 and some
+ * 5Ghz only cards) -> report 5Ghz radio */
+ } else if (!test_bit(AR5K_MODE_11B,
+ sc->ah->ah_capabilities.cap_mode)) {
+ ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n",
+ ath5k_chip_name(AR5K_VERSION_RAD,
+ sc->ah->ah_radio_5ghz_revision),
+ sc->ah->ah_radio_5ghz_revision);
+ /* Multiband radio */
+ } else {
+ ATH5K_INFO(sc, "RF%s multiband radio found"
+ " (0x%x)\n",
+ ath5k_chip_name(AR5K_VERSION_RAD,
+ sc->ah->ah_radio_5ghz_revision),
+ sc->ah->ah_radio_5ghz_revision);
+ }
+ }
+ /* Multi chip radio (RF5111 - RF2111) ->
+ * report both 2GHz/5GHz radios */
+ else if (sc->ah->ah_radio_5ghz_revision &&
+ sc->ah->ah_radio_2ghz_revision){
+ ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n",
+ ath5k_chip_name(AR5K_VERSION_RAD,
+ sc->ah->ah_radio_5ghz_revision),
+ sc->ah->ah_radio_5ghz_revision);
+ ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n",
+ ath5k_chip_name(AR5K_VERSION_RAD,
+ sc->ah->ah_radio_2ghz_revision),
+ sc->ah->ah_radio_2ghz_revision);
+ }
+ }
+
+ ath5k_debug_init_device(sc);
+
+ /* ready to process interrupts */
+ __clear_bit(ATH_STAT_INVALID, sc->status);
+
+ return 0;
+err_ah:
+ ath5k_hw_deinit(sc->ah);
+err_free_ah:
+ kfree(sc->ah);
+err_irq:
+ free_irq(sc->irq, sc);
+err:
+ return ret;
+}
+
static int
ath5k_stop_locked(struct ath5k_softc *sc)
{
@@ -2391,11 +2511,10 @@ ath5k_stop_locked(struct ath5k_softc *sc)
if (!test_bit(ATH_STAT_INVALID, sc->status)) {
ath5k_led_off(sc);
ath5k_hw_set_imr(ah, 0);
- synchronize_irq(sc->pdev->irq);
- }
- ath5k_txq_cleanup(sc);
- if (!test_bit(ATH_STAT_INVALID, sc->status)) {
+ synchronize_irq(sc->irq);
ath5k_rx_stop(sc);
+ ath5k_hw_dma_stop(ah);
+ ath5k_drain_tx_buffs(sc);
ath5k_hw_phy_disable(ah);
}
@@ -2403,7 +2522,7 @@ ath5k_stop_locked(struct ath5k_softc *sc)
}
static int
-ath5k_init(struct ath5k_softc *sc)
+ath5k_init_hw(struct ath5k_softc *sc)
{
struct ath5k_hw *ah = sc->ah;
struct ath_common *common = ath5k_hw_common(ah);
@@ -2432,7 +2551,7 @@ ath5k_init(struct ath5k_softc *sc)
AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL |
AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_MIB;
- ret = ath5k_reset(sc, NULL);
+ ret = ath5k_reset(sc, NULL, false);
if (ret)
goto done;
@@ -2445,7 +2564,9 @@ ath5k_init(struct ath5k_softc *sc)
for (i = 0; i < common->keymax; i++)
ath_hw_keyreset(common, (u16) i);
- ath5k_hw_set_ack_bitrate_high(ah, true);
+ /* Use higher rates for acks instead of base
+ * rate */
+ ah->ah_ack_bitrate_high = true;
for (i = 0; i < ARRAY_SIZE(sc->bslot); i++)
sc->bslot[i] = NULL;
@@ -2529,25 +2650,34 @@ ath5k_stop_hw(struct ath5k_softc *sc)
* This should be called with sc->lock.
*/
static int
-ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan)
+ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan,
+ bool skip_pcu)
{
struct ath5k_hw *ah = sc->ah;
- int ret;
+ int ret, ani_mode;
ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n");
ath5k_hw_set_imr(ah, 0);
- synchronize_irq(sc->pdev->irq);
+ synchronize_irq(sc->irq);
stop_tasklets(sc);
- if (chan) {
- ath5k_txq_cleanup(sc);
- ath5k_rx_stop(sc);
+ /* Save ani mode and disable ANI durring
+ * reset. If we don't we might get false
+ * PHY error interrupts. */
+ ani_mode = ah->ah_sc->ani_state.ani_mode;
+ ath5k_ani_init(ah, ATH5K_ANI_MODE_OFF);
+ /* We are going to empty hw queues
+ * so we should also free any remaining
+ * tx buffers */
+ ath5k_drain_tx_buffs(sc);
+ if (chan) {
sc->curchan = chan;
sc->curband = &sc->sbands[chan->band];
}
- ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, chan != NULL);
+ ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, chan != NULL,
+ skip_pcu);
if (ret) {
ATH5K_ERR(sc, "can't reset hardware (%d)\n", ret);
goto err;
@@ -2559,11 +2689,12 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan)
goto err;
}
- ath5k_ani_init(ah, ah->ah_sc->ani_state.ani_mode);
+ ath5k_ani_init(ah, ani_mode);
ah->ah_cal_next_full = jiffies;
ah->ah_cal_next_ani = jiffies;
ah->ah_cal_next_nf = jiffies;
+ ewma_init(&ah->ah_beacon_rssi_avg, 1024, 8);
/*
* Change channels and update the h/w rate map if we're switching;
@@ -2592,13 +2723,14 @@ static void ath5k_reset_work(struct work_struct *work)
reset_work);
mutex_lock(&sc->lock);
- ath5k_reset(sc, sc->curchan);
+ ath5k_reset(sc, NULL, true);
mutex_unlock(&sc->lock);
}
static int
-ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
+ath5k_init(struct ieee80211_hw *hw)
{
+
struct ath5k_softc *sc = hw->priv;
struct ath5k_hw *ah = sc->ah;
struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah);
@@ -2606,7 +2738,6 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
u8 mac[ETH_ALEN] = {};
int ret;
- ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "devid 0x%x\n", pdev->device);
/*
* Check if the MAC has multi-rate retry support.
@@ -2643,7 +2774,7 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
/*
* Allocate tx+rx descriptors and populate the lists.
*/
- ret = ath5k_desc_alloc(sc, pdev);
+ ret = ath5k_desc_alloc(sc);
if (ret) {
ATH5K_ERR(sc, "can't allocate descriptors\n");
goto err;
@@ -2668,33 +2799,46 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
goto err_bhal;
}
- /* This order matches mac80211's queue priority, so we can
- * directly use the mac80211 queue number without any mapping */
- txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_VO);
- if (IS_ERR(txq)) {
- ATH5K_ERR(sc, "can't setup xmit queue\n");
- ret = PTR_ERR(txq);
- goto err_queues;
- }
- txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_VI);
- if (IS_ERR(txq)) {
- ATH5K_ERR(sc, "can't setup xmit queue\n");
- ret = PTR_ERR(txq);
- goto err_queues;
- }
- txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BE);
- if (IS_ERR(txq)) {
- ATH5K_ERR(sc, "can't setup xmit queue\n");
- ret = PTR_ERR(txq);
- goto err_queues;
- }
- txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BK);
- if (IS_ERR(txq)) {
- ATH5K_ERR(sc, "can't setup xmit queue\n");
- ret = PTR_ERR(txq);
- goto err_queues;
+ /* 5211 and 5212 usually support 10 queues but we better rely on the
+ * capability information */
+ if (ah->ah_capabilities.cap_queues.q_tx_num >= 6) {
+ /* This order matches mac80211's queue priority, so we can
+ * directly use the mac80211 queue number without any mapping */
+ txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_VO);
+ if (IS_ERR(txq)) {
+ ATH5K_ERR(sc, "can't setup xmit queue\n");
+ ret = PTR_ERR(txq);
+ goto err_queues;
+ }
+ txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_VI);
+ if (IS_ERR(txq)) {
+ ATH5K_ERR(sc, "can't setup xmit queue\n");
+ ret = PTR_ERR(txq);
+ goto err_queues;
+ }
+ txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BE);
+ if (IS_ERR(txq)) {
+ ATH5K_ERR(sc, "can't setup xmit queue\n");
+ ret = PTR_ERR(txq);
+ goto err_queues;
+ }
+ txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BK);
+ if (IS_ERR(txq)) {
+ ATH5K_ERR(sc, "can't setup xmit queue\n");
+ ret = PTR_ERR(txq);
+ goto err_queues;
+ }
+ hw->queues = 4;
+ } else {
+ /* older hardware (5210) can only support one data queue */
+ txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BE);
+ if (IS_ERR(txq)) {
+ ATH5K_ERR(sc, "can't setup xmit queue\n");
+ ret = PTR_ERR(txq);
+ goto err_queues;
+ }
+ hw->queues = 1;
}
- hw->queues = 4;
tasklet_init(&sc->rxtq, ath5k_tasklet_rx, (unsigned long)sc);
tasklet_init(&sc->txtq, ath5k_tasklet_tx, (unsigned long)sc);
@@ -2707,8 +2851,7 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
ret = ath5k_eeprom_read_mac(ah, mac);
if (ret) {
- ATH5K_ERR(sc, "unable to read address from EEPROM: 0x%04x\n",
- sc->pdev->device);
+ ATH5K_ERR(sc, "unable to read address from EEPROM\n");
goto err_queues;
}
@@ -2743,15 +2886,15 @@ err_queues:
err_bhal:
ath5k_hw_release_tx_queue(ah, sc->bhalq);
err_desc:
- ath5k_desc_free(sc, pdev);
+ ath5k_desc_free(sc);
err:
return ret;
}
-static void
-ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw)
+void
+ath5k_deinit_softc(struct ath5k_softc *sc)
{
- struct ath5k_softc *sc = hw->priv;
+ struct ieee80211_hw *hw = sc->hw;
/*
* NB: the order of these is important:
@@ -2766,8 +2909,9 @@ ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw)
* XXX: ??? detach ath5k_hw ???
* Other than that, it's straightforward...
*/
+ ath5k_debug_finish_device(sc);
ieee80211_unregister_hw(hw);
- ath5k_desc_free(sc, pdev);
+ ath5k_desc_free(sc);
ath5k_txq_release(sc);
ath5k_hw_release_tx_queue(sc->ah, sc->bhalq);
ath5k_unregister_leds(sc);
@@ -2778,6 +2922,8 @@ ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw)
* returns because we'll get called back to reclaim node
* state and potentially want to use them.
*/
+ ath5k_hw_deinit(sc->ah);
+ free_irq(sc->irq, sc);
}
/********************\
@@ -2800,7 +2946,7 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
static int ath5k_start(struct ieee80211_hw *hw)
{
- return ath5k_init(hw->priv);
+ return ath5k_init_hw(hw->priv);
}
static void ath5k_stop(struct ieee80211_hw *hw)
@@ -3209,14 +3355,32 @@ static int ath5k_get_survey(struct ieee80211_hw *hw, int idx,
{
struct ath5k_softc *sc = hw->priv;
struct ieee80211_conf *conf = &hw->conf;
+ struct ath_common *common = ath5k_hw_common(sc->ah);
+ struct ath_cycle_counters *cc = &common->cc_survey;
+ unsigned int div = common->clockrate * 1000;
- if (idx != 0)
+ if (idx != 0)
return -ENOENT;
survey->channel = conf->channel;
survey->filled = SURVEY_INFO_NOISE_DBM;
survey->noise = sc->ah->ah_noise_floor;
+ spin_lock_bh(&common->cc_lock);
+ ath_hw_cycle_counters_update(common);
+ if (cc->cycles > 0) {
+ survey->filled |= SURVEY_INFO_CHANNEL_TIME |
+ SURVEY_INFO_CHANNEL_TIME_BUSY |
+ SURVEY_INFO_CHANNEL_TIME_RX |
+ SURVEY_INFO_CHANNEL_TIME_TX;
+ survey->channel_time += cc->cycles / div;
+ survey->channel_time_busy += cc->rx_busy / div;
+ survey->channel_time_rx += cc->rx_frame / div;
+ survey->channel_time_tx += cc->tx_frame / div;
+ }
+ memset(cc, 0, sizeof(*cc));
+ spin_unlock_bh(&common->cc_lock);
+
return 0;
}
@@ -3398,7 +3562,37 @@ static int ath5k_conf_tx(struct ieee80211_hw *hw, u16 queue,
return ret;
}
-static const struct ieee80211_ops ath5k_hw_ops = {
+static int ath5k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
+{
+ struct ath5k_softc *sc = hw->priv;
+
+ if (tx_ant == 1 && rx_ant == 1)
+ ath5k_hw_set_antenna_mode(sc->ah, AR5K_ANTMODE_FIXED_A);
+ else if (tx_ant == 2 && rx_ant == 2)
+ ath5k_hw_set_antenna_mode(sc->ah, AR5K_ANTMODE_FIXED_B);
+ else if ((tx_ant & 3) == 3 && (rx_ant & 3) == 3)
+ ath5k_hw_set_antenna_mode(sc->ah, AR5K_ANTMODE_DEFAULT);
+ else
+ return -EINVAL;
+ return 0;
+}
+
+static int ath5k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
+{
+ struct ath5k_softc *sc = hw->priv;
+
+ switch (sc->ah->ah_ant_mode) {
+ case AR5K_ANTMODE_FIXED_A:
+ *tx_ant = 1; *rx_ant = 1; break;
+ case AR5K_ANTMODE_FIXED_B:
+ *tx_ant = 2; *rx_ant = 2; break;
+ case AR5K_ANTMODE_DEFAULT:
+ *tx_ant = 3; *rx_ant = 3; break;
+ }
+ return 0;
+}
+
+const struct ieee80211_ops ath5k_hw_ops = {
.tx = ath5k_tx,
.start = ath5k_start,
.stop = ath5k_stop,
@@ -3418,341 +3612,6 @@ static const struct ieee80211_ops ath5k_hw_ops = {
.sw_scan_start = ath5k_sw_scan_start,
.sw_scan_complete = ath5k_sw_scan_complete,
.set_coverage_class = ath5k_set_coverage_class,
+ .set_antenna = ath5k_set_antenna,
+ .get_antenna = ath5k_get_antenna,
};
-
-/********************\
-* PCI Initialization *
-\********************/
-
-static int __devinit
-ath5k_pci_probe(struct pci_dev *pdev,
- const struct pci_device_id *id)
-{
- void __iomem *mem;
- struct ath5k_softc *sc;
- struct ath_common *common;
- struct ieee80211_hw *hw;
- int ret;
- u8 csz;
-
- /*
- * L0s needs to be disabled on all ath5k cards.
- *
- * For distributions shipping with CONFIG_PCIEASPM (this will be enabled
- * by default in the future in 2.6.36) this will also mean both L1 and
- * L0s will be disabled when a pre 1.1 PCIe device is detected. We do
- * know L1 works correctly even for all ath5k pre 1.1 PCIe devices
- * though but cannot currently undue the effect of a blacklist, for
- * details you can read pcie_aspm_sanity_check() and see how it adjusts
- * the device link capability.
- *
- * It may be possible in the future to implement some PCI API to allow
- * drivers to override blacklists for pre 1.1 PCIe but for now it is
- * best to accept that both L0s and L1 will be disabled completely for
- * distributions shipping with CONFIG_PCIEASPM rather than having this
- * issue present. Motivation for adding this new API will be to help
- * with power consumption for some of these devices.
- */
- pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S);
-
- ret = pci_enable_device(pdev);
- if (ret) {
- dev_err(&pdev->dev, "can't enable device\n");
- goto err;
- }
-
- /* XXX 32-bit addressing only */
- ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
- if (ret) {
- dev_err(&pdev->dev, "32-bit DMA not available\n");
- goto err_dis;
- }
-
- /*
- * Cache line size is used to size and align various
- * structures used to communicate with the hardware.
- */
- pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);
- if (csz == 0) {
- /*
- * Linux 2.4.18 (at least) writes the cache line size
- * register as a 16-bit wide register which is wrong.
- * We must have this setup properly for rx buffer
- * DMA to work so force a reasonable value here if it
- * comes up zero.
- */
- csz = L1_CACHE_BYTES >> 2;
- pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
- }
- /*
- * The default setting of latency timer yields poor results,
- * set it to the value used by other systems. It may be worth
- * tweaking this setting more.
- */
- pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);
-
- /* Enable bus mastering */
- pci_set_master(pdev);
-
- /*
- * Disable the RETRY_TIMEOUT register (0x41) to keep
- * PCI Tx retries from interfering with C3 CPU state.
- */
- pci_write_config_byte(pdev, 0x41, 0);
-
- ret = pci_request_region(pdev, 0, "ath5k");
- if (ret) {
- dev_err(&pdev->dev, "cannot reserve PCI memory region\n");
- goto err_dis;
- }
-
- mem = pci_iomap(pdev, 0, 0);
- if (!mem) {
- dev_err(&pdev->dev, "cannot remap PCI memory region\n") ;
- ret = -EIO;
- goto err_reg;
- }
-
- /*
- * Allocate hw (mac80211 main struct)
- * and hw->priv (driver private data)
- */
- hw = ieee80211_alloc_hw(sizeof(*sc), &ath5k_hw_ops);
- if (hw == NULL) {
- dev_err(&pdev->dev, "cannot allocate ieee80211_hw\n");
- ret = -ENOMEM;
- goto err_map;
- }
-
- dev_info(&pdev->dev, "registered as '%s'\n", wiphy_name(hw->wiphy));
-
- /* Initialize driver private data */
- SET_IEEE80211_DEV(hw, &pdev->dev);
- hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
- IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
- IEEE80211_HW_SIGNAL_DBM;
-
- hw->wiphy->interface_modes =
- BIT(NL80211_IFTYPE_AP) |
- BIT(NL80211_IFTYPE_STATION) |
- BIT(NL80211_IFTYPE_ADHOC) |
- BIT(NL80211_IFTYPE_MESH_POINT);
-
- hw->extra_tx_headroom = 2;
- hw->channel_change_time = 5000;
- sc = hw->priv;
- sc->hw = hw;
- sc->pdev = pdev;
-
- /*
- * Mark the device as detached to avoid processing
- * interrupts until setup is complete.
- */
- __set_bit(ATH_STAT_INVALID, sc->status);
-
- sc->iobase = mem; /* So we can unmap it on detach */
- sc->opmode = NL80211_IFTYPE_STATION;
- sc->bintval = 1000;
- mutex_init(&sc->lock);
- spin_lock_init(&sc->rxbuflock);
- spin_lock_init(&sc->txbuflock);
- spin_lock_init(&sc->block);
-
- /* Set private data */
- pci_set_drvdata(pdev, sc);
-
- /* Setup interrupt handler */
- ret = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc);
- if (ret) {
- ATH5K_ERR(sc, "request_irq failed\n");
- goto err_free;
- }
-
- /* If we passed the test, malloc an ath5k_hw struct */
- sc->ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL);
- if (!sc->ah) {
- ret = -ENOMEM;
- ATH5K_ERR(sc, "out of memory\n");
- goto err_irq;
- }
-
- sc->ah->ah_sc = sc;
- sc->ah->ah_iobase = sc->iobase;
- common = ath5k_hw_common(sc->ah);
- common->ops = &ath5k_common_ops;
- common->ah = sc->ah;
- common->hw = hw;
- common->cachelsz = csz << 2; /* convert to bytes */
- spin_lock_init(&common->cc_lock);
-
- /* Initialize device */
- ret = ath5k_hw_attach(sc);
- if (ret) {
- goto err_free_ah;
- }
-
- /* set up multi-rate retry capabilities */
- if (sc->ah->ah_version == AR5K_AR5212) {
- hw->max_rates = 4;
- hw->max_rate_tries = 11;
- }
-
- hw->vif_data_size = sizeof(struct ath5k_vif);
-
- /* Finish private driver data initialization */
- ret = ath5k_attach(pdev, hw);
- if (ret)
- goto err_ah;
-
- ATH5K_INFO(sc, "Atheros AR%s chip found (MAC: 0x%x, PHY: 0x%x)\n",
- ath5k_chip_name(AR5K_VERSION_MAC, sc->ah->ah_mac_srev),
- sc->ah->ah_mac_srev,
- sc->ah->ah_phy_revision);
-
- if (!sc->ah->ah_single_chip) {
- /* Single chip radio (!RF5111) */
- if (sc->ah->ah_radio_5ghz_revision &&
- !sc->ah->ah_radio_2ghz_revision) {
- /* No 5GHz support -> report 2GHz radio */
- if (!test_bit(AR5K_MODE_11A,
- sc->ah->ah_capabilities.cap_mode)) {
- ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n",
- ath5k_chip_name(AR5K_VERSION_RAD,
- sc->ah->ah_radio_5ghz_revision),
- sc->ah->ah_radio_5ghz_revision);
- /* No 2GHz support (5110 and some
- * 5Ghz only cards) -> report 5Ghz radio */
- } else if (!test_bit(AR5K_MODE_11B,
- sc->ah->ah_capabilities.cap_mode)) {
- ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n",
- ath5k_chip_name(AR5K_VERSION_RAD,
- sc->ah->ah_radio_5ghz_revision),
- sc->ah->ah_radio_5ghz_revision);
- /* Multiband radio */
- } else {
- ATH5K_INFO(sc, "RF%s multiband radio found"
- " (0x%x)\n",
- ath5k_chip_name(AR5K_VERSION_RAD,
- sc->ah->ah_radio_5ghz_revision),
- sc->ah->ah_radio_5ghz_revision);
- }
- }
- /* Multi chip radio (RF5111 - RF2111) ->
- * report both 2GHz/5GHz radios */
- else if (sc->ah->ah_radio_5ghz_revision &&
- sc->ah->ah_radio_2ghz_revision){
- ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n",
- ath5k_chip_name(AR5K_VERSION_RAD,
- sc->ah->ah_radio_5ghz_revision),
- sc->ah->ah_radio_5ghz_revision);
- ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n",
- ath5k_chip_name(AR5K_VERSION_RAD,
- sc->ah->ah_radio_2ghz_revision),
- sc->ah->ah_radio_2ghz_revision);
- }
- }
-
- ath5k_debug_init_device(sc);
-
- /* ready to process interrupts */
- __clear_bit(ATH_STAT_INVALID, sc->status);
-
- return 0;
-err_ah:
- ath5k_hw_detach(sc->ah);
-err_free_ah:
- kfree(sc->ah);
-err_irq:
- free_irq(pdev->irq, sc);
-err_free:
- ieee80211_free_hw(hw);
-err_map:
- pci_iounmap(pdev, mem);
-err_reg:
- pci_release_region(pdev, 0);
-err_dis:
- pci_disable_device(pdev);
-err:
- return ret;
-}
-
-static void __devexit
-ath5k_pci_remove(struct pci_dev *pdev)
-{
- struct ath5k_softc *sc = pci_get_drvdata(pdev);
-
- ath5k_debug_finish_device(sc);
- ath5k_detach(pdev, sc->hw);
- ath5k_hw_detach(sc->ah);
- kfree(sc->ah);
- free_irq(pdev->irq, sc);
- pci_iounmap(pdev, sc->iobase);
- pci_release_region(pdev, 0);
- pci_disable_device(pdev);
- ieee80211_free_hw(sc->hw);
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int ath5k_pci_suspend(struct device *dev)
-{
- struct ath5k_softc *sc = pci_get_drvdata(to_pci_dev(dev));
-
- ath5k_led_off(sc);
- return 0;
-}
-
-static int ath5k_pci_resume(struct device *dev)
-{
- struct pci_dev *pdev = to_pci_dev(dev);
- struct ath5k_softc *sc = pci_get_drvdata(pdev);
-
- /*
- * Suspend/Resume resets the PCI configuration space, so we have to
- * re-disable the RETRY_TIMEOUT register (0x41) to keep
- * PCI Tx retries from interfering with C3 CPU state
- */
- pci_write_config_byte(pdev, 0x41, 0);
-
- ath5k_led_enable(sc);
- return 0;
-}
-
-static SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume);
-#define ATH5K_PM_OPS (&ath5k_pm_ops)
-#else
-#define ATH5K_PM_OPS NULL
-#endif /* CONFIG_PM_SLEEP */
-
-static struct pci_driver ath5k_pci_driver = {
- .name = KBUILD_MODNAME,
- .id_table = ath5k_pci_id_table,
- .probe = ath5k_pci_probe,
- .remove = __devexit_p(ath5k_pci_remove),
- .driver.pm = ATH5K_PM_OPS,
-};
-
-/*
- * Module init/exit functions
- */
-static int __init
-init_ath5k_pci(void)
-{
- int ret;
-
- ret = pci_register_driver(&ath5k_pci_driver);
- if (ret) {
- printk(KERN_ERR "ath5k_pci: can't register pci driver\n");
- return ret;
- }
-
- return 0;
-}
-
-static void __exit
-exit_ath5k_pci(void)
-{
- pci_unregister_driver(&ath5k_pci_driver);
-}
-
-module_init(init_ath5k_pci);
-module_exit(exit_ath5k_pci);
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h
index 9a79773cdc2a..aa6c32aafb59 100644
--- a/drivers/net/wireless/ath/ath5k/base.h
+++ b/drivers/net/wireless/ath/ath5k/base.h
@@ -169,7 +169,10 @@ struct ath5k_vif {
/* Software Carrier, keeps track of the driver state
* associated with an instance of a device */
struct ath5k_softc {
- struct pci_dev *pdev; /* for dma mapping */
+ struct pci_dev *pdev;
+ struct device *dev; /* for dma mapping */
+ int irq;
+ u16 devid;
void __iomem *iobase; /* address of the device */
struct mutex lock; /* dev-level lock */
struct ieee80211_hw *hw; /* IEEE 802.11 common */
diff --git a/drivers/net/wireless/ath/ath5k/caps.c b/drivers/net/wireless/ath/ath5k/caps.c
index beae519aa735..31cad80e9b01 100644
--- a/drivers/net/wireless/ath/ath5k/caps.c
+++ b/drivers/net/wireless/ath/ath5k/caps.c
@@ -49,7 +49,6 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah)
/* Set supported modes */
__set_bit(AR5K_MODE_11A, ah->ah_capabilities.cap_mode);
- __set_bit(AR5K_MODE_11A_TURBO, ah->ah_capabilities.cap_mode);
} else {
/*
* XXX The tranceiver supports frequencies from 4920 to 6100GHz
@@ -74,11 +73,6 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah)
/* Set supported modes */
__set_bit(AR5K_MODE_11A,
ah->ah_capabilities.cap_mode);
- __set_bit(AR5K_MODE_11A_TURBO,
- ah->ah_capabilities.cap_mode);
- if (ah->ah_version == AR5K_AR5212)
- __set_bit(AR5K_MODE_11G_TURBO,
- ah->ah_capabilities.cap_mode);
}
/* Enable 802.11b if a 2GHz capable radio (2111/5112) is
diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c
index acda56ee521b..d2f84d76bb07 100644
--- a/drivers/net/wireless/ath/ath5k/debug.c
+++ b/drivers/net/wireless/ath/ath5k/debug.c
@@ -60,7 +60,6 @@
#include "base.h"
#include "debug.h"
-#include "../debug.h"
static unsigned int ath5k_debug;
module_param_named(debug, ath5k_debug, uint, 0);
@@ -312,6 +311,7 @@ static const struct {
{ ATH5K_DEBUG_DUMP_RX, "dumprx", "print received skb content" },
{ ATH5K_DEBUG_DUMP_TX, "dumptx", "print transmit skb content" },
{ ATH5K_DEBUG_DUMPBANDS, "dumpbands", "dump bands" },
+ { ATH5K_DEBUG_DMA, "dma", "dma start/stop" },
{ ATH5K_DEBUG_ANI, "ani", "adaptive noise immunity" },
{ ATH5K_DEBUG_DESC, "desc", "descriptor chains" },
{ ATH5K_DEBUG_ANY, "all", "show all debug levels" },
@@ -554,63 +554,63 @@ static ssize_t read_file_frameerrors(struct file *file, char __user *user_buf,
len += snprintf(buf+len, sizeof(buf)-len,
"RX\n---------------------\n");
- len += snprintf(buf+len, sizeof(buf)-len, "CRC\t%d\t(%d%%)\n",
+ len += snprintf(buf+len, sizeof(buf)-len, "CRC\t%u\t(%u%%)\n",
st->rxerr_crc,
st->rx_all_count > 0 ?
st->rxerr_crc*100/st->rx_all_count : 0);
- len += snprintf(buf+len, sizeof(buf)-len, "PHY\t%d\t(%d%%)\n",
+ len += snprintf(buf+len, sizeof(buf)-len, "PHY\t%u\t(%u%%)\n",
st->rxerr_phy,
st->rx_all_count > 0 ?
st->rxerr_phy*100/st->rx_all_count : 0);
for (i = 0; i < 32; i++) {
if (st->rxerr_phy_code[i])
len += snprintf(buf+len, sizeof(buf)-len,
- " phy_err[%d]\t%d\n",
+ " phy_err[%u]\t%u\n",
i, st->rxerr_phy_code[i]);
}
- len += snprintf(buf+len, sizeof(buf)-len, "FIFO\t%d\t(%d%%)\n",
+ len += snprintf(buf+len, sizeof(buf)-len, "FIFO\t%u\t(%u%%)\n",
st->rxerr_fifo,
st->rx_all_count > 0 ?
st->rxerr_fifo*100/st->rx_all_count : 0);
- len += snprintf(buf+len, sizeof(buf)-len, "decrypt\t%d\t(%d%%)\n",
+ len += snprintf(buf+len, sizeof(buf)-len, "decrypt\t%u\t(%u%%)\n",
st->rxerr_decrypt,
st->rx_all_count > 0 ?
st->rxerr_decrypt*100/st->rx_all_count : 0);
- len += snprintf(buf+len, sizeof(buf)-len, "MIC\t%d\t(%d%%)\n",
+ len += snprintf(buf+len, sizeof(buf)-len, "MIC\t%u\t(%u%%)\n",
st->rxerr_mic,
st->rx_all_count > 0 ?
st->rxerr_mic*100/st->rx_all_count : 0);
- len += snprintf(buf+len, sizeof(buf)-len, "process\t%d\t(%d%%)\n",
+ len += snprintf(buf+len, sizeof(buf)-len, "process\t%u\t(%u%%)\n",
st->rxerr_proc,
st->rx_all_count > 0 ?
st->rxerr_proc*100/st->rx_all_count : 0);
- len += snprintf(buf+len, sizeof(buf)-len, "jumbo\t%d\t(%d%%)\n",
+ len += snprintf(buf+len, sizeof(buf)-len, "jumbo\t%u\t(%u%%)\n",
st->rxerr_jumbo,
st->rx_all_count > 0 ?
st->rxerr_jumbo*100/st->rx_all_count : 0);
- len += snprintf(buf+len, sizeof(buf)-len, "[RX all\t%d]\n",
+ len += snprintf(buf+len, sizeof(buf)-len, "[RX all\t%u]\n",
st->rx_all_count);
- len += snprintf(buf+len, sizeof(buf)-len, "RX-all-bytes\t%d\n",
+ len += snprintf(buf+len, sizeof(buf)-len, "RX-all-bytes\t%u\n",
st->rx_bytes_count);
len += snprintf(buf+len, sizeof(buf)-len,
"\nTX\n---------------------\n");
- len += snprintf(buf+len, sizeof(buf)-len, "retry\t%d\t(%d%%)\n",
+ len += snprintf(buf+len, sizeof(buf)-len, "retry\t%u\t(%u%%)\n",
st->txerr_retry,
st->tx_all_count > 0 ?
st->txerr_retry*100/st->tx_all_count : 0);
- len += snprintf(buf+len, sizeof(buf)-len, "FIFO\t%d\t(%d%%)\n",
+ len += snprintf(buf+len, sizeof(buf)-len, "FIFO\t%u\t(%u%%)\n",
st->txerr_fifo,
st->tx_all_count > 0 ?
st->txerr_fifo*100/st->tx_all_count : 0);
- len += snprintf(buf+len, sizeof(buf)-len, "filter\t%d\t(%d%%)\n",
+ len += snprintf(buf+len, sizeof(buf)-len, "filter\t%u\t(%u%%)\n",
st->txerr_filt,
st->tx_all_count > 0 ?
st->txerr_filt*100/st->tx_all_count : 0);
- len += snprintf(buf+len, sizeof(buf)-len, "[TX all\t%d]\n",
+ len += snprintf(buf+len, sizeof(buf)-len, "[TX all\t%u]\n",
st->tx_all_count);
- len += snprintf(buf+len, sizeof(buf)-len, "TX-all-bytes\t%d\n",
+ len += snprintf(buf+len, sizeof(buf)-len, "TX-all-bytes\t%u\n",
st->tx_bytes_count);
if (len > sizeof(buf))
@@ -719,7 +719,7 @@ static ssize_t read_file_ani(struct file *file, char __user *user_buf,
st->mib_intr);
len += snprintf(buf+len, sizeof(buf)-len,
"beacon RSSI average:\t%d\n",
- sc->ah->ah_beacon_rssi_avg.avg);
+ (int)ewma_read(&sc->ah->ah_beacon_rssi_avg));
#define CC_PRINT(_struct, _field) \
_struct._field, \
diff --git a/drivers/net/wireless/ath/ath5k/debug.h b/drivers/net/wireless/ath/ath5k/debug.h
index 236edbd2507d..3e34428d5126 100644
--- a/drivers/net/wireless/ath/ath5k/debug.h
+++ b/drivers/net/wireless/ath/ath5k/debug.h
@@ -95,6 +95,7 @@ struct ath5k_dbg_info {
* @ATH5K_DEBUG_DUMP_RX: print received skb content
* @ATH5K_DEBUG_DUMP_TX: print transmit skb content
* @ATH5K_DEBUG_DUMPBANDS: dump bands
+ * @ATH5K_DEBUG_DMA: debug dma start/stop
* @ATH5K_DEBUG_TRACE: trace function calls
* @ATH5K_DEBUG_DESC: descriptor setup
* @ATH5K_DEBUG_ANY: show at any debug level
@@ -118,6 +119,7 @@ enum ath5k_debug_level {
ATH5K_DEBUG_DUMP_RX = 0x00000100,
ATH5K_DEBUG_DUMP_TX = 0x00000200,
ATH5K_DEBUG_DUMPBANDS = 0x00000400,
+ ATH5K_DEBUG_DMA = 0x00000800,
ATH5K_DEBUG_ANI = 0x00002000,
ATH5K_DEBUG_DESC = 0x00004000,
ATH5K_DEBUG_ANY = 0xffffffff
diff --git a/drivers/net/wireless/ath/ath5k/desc.c b/drivers/net/wireless/ath/ath5k/desc.c
index 43244382f213..16b44ff7dd3e 100644
--- a/drivers/net/wireless/ath/ath5k/desc.c
+++ b/drivers/net/wireless/ath/ath5k/desc.c
@@ -26,9 +26,10 @@
#include "debug.h"
#include "base.h"
-/*
- * TX Descriptors
- */
+
+/************************\
+* TX Control descriptors *
+\************************/
/*
* Initialize the 2-word tx control descriptor on 5210/5211
@@ -335,6 +336,11 @@ ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
return 0;
}
+
+/***********************\
+* TX Status descriptors *
+\***********************/
+
/*
* Proccess the tx status descriptor on 5210/5211
*/
@@ -476,9 +482,10 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah,
return 0;
}
-/*
- * RX Descriptors
- */
+
+/****************\
+* RX Descriptors *
+\****************/
/*
* Initialize an rx control descriptor
@@ -666,6 +673,11 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,
return 0;
}
+
+/********\
+* Attach *
+\********/
+
/*
* Init function pointers inside ath5k_hw struct
*/
diff --git a/drivers/net/wireless/ath/ath5k/desc.h b/drivers/net/wireless/ath/ath5k/desc.h
index b2adb2a281c2..2509d0bf037d 100644
--- a/drivers/net/wireless/ath/ath5k/desc.h
+++ b/drivers/net/wireless/ath/ath5k/desc.h
@@ -26,7 +26,7 @@
struct ath5k_hw_rx_ctl {
u32 rx_control_0; /* RX control word 0 */
u32 rx_control_1; /* RX control word 1 */
-} __packed;
+} __packed __aligned(4);
/* RX control word 1 fields/flags */
#define AR5K_DESC_RX_CTL1_BUF_LEN 0x00000fff /* data buffer length */
@@ -39,7 +39,7 @@ struct ath5k_hw_rx_ctl {
struct ath5k_hw_rx_status {
u32 rx_status_0; /* RX status word 0 */
u32 rx_status_1; /* RX status word 1 */
-} __packed;
+} __packed __aligned(4);
/* 5210/5211 */
/* RX status word 0 fields/flags */
@@ -129,7 +129,7 @@ enum ath5k_phy_error_code {
struct ath5k_hw_2w_tx_ctl {
u32 tx_control_0; /* TX control word 0 */
u32 tx_control_1; /* TX control word 1 */
-} __packed;
+} __packed __aligned(4);
/* TX control word 0 fields/flags */
#define AR5K_2W_TX_DESC_CTL0_FRAME_LEN 0x00000fff /* frame length */
@@ -185,7 +185,7 @@ struct ath5k_hw_4w_tx_ctl {
u32 tx_control_1; /* TX control word 1 */
u32 tx_control_2; /* TX control word 2 */
u32 tx_control_3; /* TX control word 3 */
-} __packed;
+} __packed __aligned(4);
/* TX control word 0 fields/flags */
#define AR5K_4W_TX_DESC_CTL0_FRAME_LEN 0x00000fff /* frame length */
@@ -244,7 +244,7 @@ struct ath5k_hw_4w_tx_ctl {
struct ath5k_hw_tx_status {
u32 tx_status_0; /* TX status word 0 */
u32 tx_status_1; /* TX status word 1 */
-} __packed;
+} __packed __aligned(4);
/* TX status word 0 fields/flags */
#define AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK 0x00000001 /* TX success */
@@ -282,7 +282,7 @@ struct ath5k_hw_tx_status {
struct ath5k_hw_5210_tx_desc {
struct ath5k_hw_2w_tx_ctl tx_ctl;
struct ath5k_hw_tx_status tx_stat;
-} __packed;
+} __packed __aligned(4);
/*
* 5212 hardware TX descriptor
@@ -290,7 +290,7 @@ struct ath5k_hw_5210_tx_desc {
struct ath5k_hw_5212_tx_desc {
struct ath5k_hw_4w_tx_ctl tx_ctl;
struct ath5k_hw_tx_status tx_stat;
-} __packed;
+} __packed __aligned(4);
/*
* Common hardware RX descriptor
@@ -298,7 +298,7 @@ struct ath5k_hw_5212_tx_desc {
struct ath5k_hw_all_rx_desc {
struct ath5k_hw_rx_ctl rx_ctl;
struct ath5k_hw_rx_status rx_stat;
-} __packed;
+} __packed __aligned(4);
/*
* Atheros hardware DMA descriptor
@@ -313,7 +313,7 @@ struct ath5k_desc {
struct ath5k_hw_5212_tx_desc ds_tx5212;
struct ath5k_hw_all_rx_desc ds_rx;
} ud;
-} __packed;
+} __packed __aligned(4);
#define AR5K_RXDESC_INTREQ 0x0020
diff --git a/drivers/net/wireless/ath/ath5k/dma.c b/drivers/net/wireless/ath/ath5k/dma.c
index 923c9ca5c4f0..0064be7ce5c9 100644
--- a/drivers/net/wireless/ath/ath5k/dma.c
+++ b/drivers/net/wireless/ath/ath5k/dma.c
@@ -37,6 +37,7 @@
#include "debug.h"
#include "base.h"
+
/*********\
* Receive *
\*********/
@@ -57,7 +58,7 @@ void ath5k_hw_start_rx_dma(struct ath5k_hw *ah)
*
* @ah: The &struct ath5k_hw
*/
-int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah)
+static int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah)
{
unsigned int i;
@@ -69,7 +70,11 @@ int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah)
for (i = 1000; i > 0 &&
(ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_CR_RXE) != 0;
i--)
- udelay(10);
+ udelay(100);
+
+ if (!i)
+ ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA,
+ "failed to stop RX DMA !\n");
return i ? 0 : -EBUSY;
}
@@ -90,11 +95,18 @@ u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah)
* @ah: The &struct ath5k_hw
* @phys_addr: RX descriptor address
*
- * XXX: Should we check if rx is enabled before setting rxdp ?
+ * Returns -EIO if rx is active
*/
-void ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr)
+int ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr)
{
+ if (ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_CR_RXE) {
+ ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA,
+ "tried to set RXDP while rx was active !\n");
+ return -EIO;
+ }
+
ath5k_hw_reg_write(ah, phys_addr, AR5K_RXDP);
+ return 0;
}
@@ -125,7 +137,7 @@ int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue)
/* Return if queue is declared inactive */
if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
- return -EIO;
+ return -EINVAL;
if (ah->ah_version == AR5K_AR5210) {
tx_queue = ath5k_hw_reg_read(ah, AR5K_CR);
@@ -173,10 +185,10 @@ int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue)
*
* Stop DMA transmit on a specific hw queue and drain queue so we don't
* have any pending frames. Returns -EBUSY if we still have pending frames,
- * -EINVAL if queue number is out of range.
+ * -EINVAL if queue number is out of range or inactive.
*
*/
-int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
+static int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
{
unsigned int i = 40;
u32 tx_queue, pending;
@@ -185,7 +197,7 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
/* Return if queue is declared inactive */
if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
- return -EIO;
+ return -EINVAL;
if (ah->ah_version == AR5K_AR5210) {
tx_queue = ath5k_hw_reg_read(ah, AR5K_CR);
@@ -211,12 +223,31 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
ath5k_hw_reg_write(ah, tx_queue, AR5K_CR);
ath5k_hw_reg_read(ah, AR5K_CR);
} else {
+
+ /*
+ * Enable DCU early termination to quickly
+ * flush any pending frames from QCU
+ */
+ AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
+ AR5K_QCU_MISC_DCU_EARLY);
+
/*
* Schedule TX disable and wait until queue is empty
*/
AR5K_REG_WRITE_Q(ah, AR5K_QCU_TXD, queue);
- /*Check for pending frames*/
+ /* Wait for queue to stop */
+ for (i = 1000; i > 0 &&
+ (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue) != 0);
+ i--)
+ udelay(100);
+
+ if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue))
+ ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA,
+ "queue %i didn't stop !\n", queue);
+
+ /* Check for pending frames */
+ i = 1000;
do {
pending = ath5k_hw_reg_read(ah,
AR5K_QUEUE_STATUS(queue)) &
@@ -247,12 +278,12 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
AR5K_DIAG_SW_CHANNEL_IDLE_HIGH);
/* Wait a while and disable mechanism */
- udelay(200);
+ udelay(400);
AR5K_REG_DISABLE_BITS(ah, AR5K_QUIET_CTL1,
AR5K_QUIET_CTL1_QT_EN);
/* Re-check for pending frames */
- i = 40;
+ i = 100;
do {
pending = ath5k_hw_reg_read(ah,
AR5K_QUEUE_STATUS(queue)) &
@@ -262,12 +293,27 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5211,
AR5K_DIAG_SW_CHANNEL_IDLE_HIGH);
+
+ if (pending)
+ ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA,
+ "quiet mechanism didn't work q:%i !\n",
+ queue);
}
+ /*
+ * Disable DCU early termination
+ */
+ AR5K_REG_DISABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
+ AR5K_QCU_MISC_DCU_EARLY);
+
/* Clear register */
ath5k_hw_reg_write(ah, 0, AR5K_QCU_TXD);
- if (pending)
+ if (pending) {
+ ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA,
+ "tx dma didn't stop (q:%i, frm:%i) !\n",
+ queue, pending);
return -EBUSY;
+ }
}
/* TODO: Check for success on 5210 else return error */
@@ -275,6 +321,26 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
}
/**
+ * ath5k_hw_stop_beacon_queue - Stop beacon queue
+ *
+ * @ah The &struct ath5k_hw
+ * @queue The queue number
+ *
+ * Returns -EIO if queue didn't stop
+ */
+int ath5k_hw_stop_beacon_queue(struct ath5k_hw *ah, unsigned int queue)
+{
+ int ret;
+ ret = ath5k_hw_stop_tx_dma(ah, queue);
+ if (ret) {
+ ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA,
+ "beacon queue didn't stop !\n");
+ return -EIO;
+ }
+ return 0;
+}
+
+/**
* ath5k_hw_get_txdp - Get TX Descriptor's address for a specific queue
*
* @ah: The &struct ath5k_hw
@@ -427,6 +493,7 @@ done:
return ret;
}
+
/*******************\
* Interrupt masking *
\*******************/
@@ -688,3 +755,92 @@ enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum ath5k_int new_mask)
return old_mask;
}
+
+/********************\
+ Init/Stop functions
+\********************/
+
+/**
+ * ath5k_hw_dma_init - Initialize DMA unit
+ *
+ * @ah: The &struct ath5k_hw
+ *
+ * Set DMA size and pre-enable interrupts
+ * (driver handles tx/rx buffer setup and
+ * dma start/stop)
+ *
+ * XXX: Save/restore RXDP/TXDP registers ?
+ */
+void ath5k_hw_dma_init(struct ath5k_hw *ah)
+{
+ /*
+ * Set Rx/Tx DMA Configuration
+ *
+ * Set standard DMA size (128). Note that
+ * a DMA size of 512 causes rx overruns and tx errors
+ * on pci-e cards (tested on 5424 but since rx overruns
+ * also occur on 5416/5418 with madwifi we set 128
+ * for all PCI-E cards to be safe).
+ *
+ * XXX: need to check 5210 for this
+ * TODO: Check out tx triger level, it's always 64 on dumps but I
+ * guess we can tweak it and see how it goes ;-)
+ */
+ if (ah->ah_version != AR5K_AR5210) {
+ AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
+ AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B);
+ AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG,
+ AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_128B);
+ }
+
+ /* Pre-enable interrupts on 5211/5212*/
+ if (ah->ah_version != AR5K_AR5210)
+ ath5k_hw_set_imr(ah, ah->ah_imr);
+
+}
+
+/**
+ * ath5k_hw_dma_stop - stop DMA unit
+ *
+ * @ah: The &struct ath5k_hw
+ *
+ * Stop tx/rx DMA and interrupts. Returns
+ * -EBUSY if tx or rx dma failed to stop.
+ *
+ * XXX: Sometimes DMA unit hangs and we have
+ * stuck frames on tx queues, only a reset
+ * can fix that.
+ */
+int ath5k_hw_dma_stop(struct ath5k_hw *ah)
+{
+ int i, qmax, err;
+ err = 0;
+
+ /* Disable interrupts */
+ ath5k_hw_set_imr(ah, 0);
+
+ /* Stop rx dma */
+ err = ath5k_hw_stop_rx_dma(ah);
+ if (err)
+ return err;
+
+ /* Clear any pending interrupts
+ * and disable tx dma */
+ if (ah->ah_version != AR5K_AR5210) {
+ ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR);
+ qmax = AR5K_NUM_TX_QUEUES;
+ } else {
+ /* PISR/SISR Not available on 5210 */
+ ath5k_hw_reg_read(ah, AR5K_ISR);
+ qmax = AR5K_NUM_TX_QUEUES_NOQCU;
+ }
+
+ for (i = 0; i < qmax; i++) {
+ err = ath5k_hw_stop_tx_dma(ah, i);
+ /* -EINVAL -> queue inactive */
+ if (err != -EINVAL)
+ return err;
+ }
+
+ return err;
+}
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c
index 39722dd73e43..97eaa9a4415e 100644
--- a/drivers/net/wireless/ath/ath5k/eeprom.c
+++ b/drivers/net/wireless/ath/ath5k/eeprom.c
@@ -28,45 +28,16 @@
#include "debug.h"
#include "base.h"
-/*
- * Read from eeprom
- */
-static int ath5k_hw_eeprom_read(struct ath5k_hw *ah, u32 offset, u16 *data)
-{
- u32 status, timeout;
-
- /*
- * Initialize EEPROM access
- */
- if (ah->ah_version == AR5K_AR5210) {
- AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_EEAE);
- (void)ath5k_hw_reg_read(ah, AR5K_EEPROM_BASE + (4 * offset));
- } else {
- ath5k_hw_reg_write(ah, offset, AR5K_EEPROM_BASE);
- AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD,
- AR5K_EEPROM_CMD_READ);
- }
- for (timeout = AR5K_TUNE_REGISTER_TIMEOUT; timeout > 0; timeout--) {
- status = ath5k_hw_reg_read(ah, AR5K_EEPROM_STATUS);
- if (status & AR5K_EEPROM_STAT_RDDONE) {
- if (status & AR5K_EEPROM_STAT_RDERR)
- return -EIO;
- *data = (u16)(ath5k_hw_reg_read(ah, AR5K_EEPROM_DATA) &
- 0xffff);
- return 0;
- }
- udelay(15);
- }
-
- return -ETIMEDOUT;
-}
+/******************\
+* Helper functions *
+\******************/
/*
* Translate binary channel representation in EEPROM to frequency
*/
static u16 ath5k_eeprom_bin2freq(struct ath5k_eeprom_info *ee, u16 bin,
- unsigned int mode)
+ unsigned int mode)
{
u16 val;
@@ -89,6 +60,11 @@ static u16 ath5k_eeprom_bin2freq(struct ath5k_eeprom_info *ee, u16 bin,
return val;
}
+
+/*********\
+* Parsers *
+\*********/
+
/*
* Initialize eeprom & capabilities structs
*/
@@ -198,7 +174,7 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah)
*
* XXX: Serdes values seem to be fixed so
* no need to read them here, we write them
- * during ath5k_hw_attach */
+ * during ath5k_hw_init */
AR5K_EEPROM_READ(AR5K_EEPROM_PCIE_OFFSET, val);
ee->ee_serdes = (val == AR5K_EEPROM_PCIE_SERDES_SECTION) ?
true : false;
@@ -647,6 +623,7 @@ ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset)
return 0;
}
+
/*
* Read power calibration for RF5111 chips
*
@@ -1514,6 +1491,7 @@ ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned int mode)
return 0;
}
+
/*
* Read per channel calibration info from EEPROM
*
@@ -1607,15 +1585,6 @@ ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode)
return 0;
}
-void
-ath5k_eeprom_detach(struct ath5k_hw *ah)
-{
- u8 mode;
-
- for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++)
- ath5k_eeprom_free_pcal_info(ah, mode);
-}
-
/* Read conformance test limits used for regulatory control */
static int
ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah)
@@ -1757,6 +1726,44 @@ ath5k_eeprom_read_spur_chans(struct ath5k_hw *ah)
}
/*
+ * Read the MAC address from eeprom
+ */
+int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
+{
+ u8 mac_d[ETH_ALEN] = {};
+ u32 total, offset;
+ u16 data;
+ int octet, ret;
+
+ ret = ath5k_hw_nvram_read(ah, 0x20, &data);
+ if (ret)
+ return ret;
+
+ for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) {
+ ret = ath5k_hw_nvram_read(ah, offset, &data);
+ if (ret)
+ return ret;
+
+ total += data;
+ mac_d[octet + 1] = data & 0xff;
+ mac_d[octet] = data >> 8;
+ octet += 2;
+ }
+
+ if (!total || total == 3 * 0xffff)
+ return -EINVAL;
+
+ memcpy(mac, mac_d, ETH_ALEN);
+
+ return 0;
+}
+
+
+/***********************\
+* Init/Detach functions *
+\***********************/
+
+/*
* Initialize eeprom data structure
*/
int
@@ -1787,35 +1794,11 @@ ath5k_eeprom_init(struct ath5k_hw *ah)
return 0;
}
-/*
- * Read the MAC address from eeprom
- */
-int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
+void
+ath5k_eeprom_detach(struct ath5k_hw *ah)
{
- u8 mac_d[ETH_ALEN] = {};
- u32 total, offset;
- u16 data;
- int octet, ret;
-
- ret = ath5k_hw_eeprom_read(ah, 0x20, &data);
- if (ret)
- return ret;
-
- for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) {
- ret = ath5k_hw_eeprom_read(ah, offset, &data);
- if (ret)
- return ret;
-
- total += data;
- mac_d[octet + 1] = data & 0xff;
- mac_d[octet] = data >> 8;
- octet += 2;
- }
-
- if (!total || total == 3 * 0xffff)
- return -EINVAL;
-
- memcpy(mac, mac_d, ETH_ALEN);
+ u8 mode;
- return 0;
+ for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++)
+ ath5k_eeprom_free_pcal_info(ah, mode);
}
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.h b/drivers/net/wireless/ath/ath5k/eeprom.h
index c4a6d5f26af4..0017006be841 100644
--- a/drivers/net/wireless/ath/ath5k/eeprom.h
+++ b/drivers/net/wireless/ath/ath5k/eeprom.h
@@ -241,7 +241,7 @@ enum ath5k_eeprom_freq_bands{
#define AR5K_SPUR_SYMBOL_WIDTH_TURBO_100Hz 6250
#define AR5K_EEPROM_READ(_o, _v) do { \
- ret = ath5k_hw_eeprom_read(ah, (_o), &(_v)); \
+ ret = ath5k_hw_nvram_read(ah, (_o), &(_v)); \
if (ret) \
return ret; \
} while (0)
diff --git a/drivers/net/wireless/ath/ath5k/initvals.c b/drivers/net/wireless/ath/ath5k/initvals.c
index 8fa439308828..e49340d18df4 100644
--- a/drivers/net/wireless/ath/ath5k/initvals.c
+++ b/drivers/net/wireless/ath/ath5k/initvals.c
@@ -44,7 +44,7 @@ struct ath5k_ini {
struct ath5k_ini_mode {
u16 mode_register;
- u32 mode_value[5];
+ u32 mode_value[3];
};
/* Initial register settings for AR5210 */
@@ -391,76 +391,74 @@ static const struct ath5k_ini ar5211_ini[] = {
*/
static const struct ath5k_ini_mode ar5211_ini_mode[] = {
{ AR5K_TXCFG,
- /* a aTurbo b g (OFDM) */
- { 0x00000015, 0x00000015, 0x0000001d, 0x00000015 } },
+ /* A/XR B G */
+ { 0x00000015, 0x0000001d, 0x00000015 } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(0),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(1),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(2),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(3),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(4),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(5),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(6),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(7),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(8),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(9),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_DCU_GBL_IFS_SLOT,
- { 0x00000168, 0x000001e0, 0x000001b8, 0x00000168 } },
+ { 0x00000168, 0x000001b8, 0x00000168 } },
{ AR5K_DCU_GBL_IFS_SIFS,
- { 0x00000230, 0x000001e0, 0x000000b0, 0x00000230 } },
+ { 0x00000230, 0x000000b0, 0x00000230 } },
{ AR5K_DCU_GBL_IFS_EIFS,
- { 0x00000d98, 0x00001180, 0x00001f48, 0x00000d98 } },
+ { 0x00000d98, 0x00001f48, 0x00000d98 } },
{ AR5K_DCU_GBL_IFS_MISC,
- { 0x0000a0e0, 0x00014068, 0x00005880, 0x0000a0e0 } },
+ { 0x0000a0e0, 0x00005880, 0x0000a0e0 } },
{ AR5K_TIME_OUT,
- { 0x04000400, 0x08000800, 0x20003000, 0x04000400 } },
+ { 0x04000400, 0x20003000, 0x04000400 } },
{ AR5K_USEC_5211,
- { 0x0e8d8fa7, 0x0e8d8fcf, 0x01608f95, 0x0e8d8fa7 } },
- { AR5K_PHY_TURBO,
- { 0x00000000, 0x00000003, 0x00000000, 0x00000000 } },
+ { 0x0e8d8fa7, 0x01608f95, 0x0e8d8fa7 } },
{ AR5K_PHY(8),
- { 0x02020200, 0x02020200, 0x02010200, 0x02020200 } },
- { AR5K_PHY(9),
- { 0x00000e0e, 0x00000e0e, 0x00000707, 0x00000e0e } },
- { AR5K_PHY(10),
- { 0x0a020001, 0x0a020001, 0x05010000, 0x0a020001 } },
- { AR5K_PHY(13),
- { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
- { AR5K_PHY(14),
- { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b } },
- { AR5K_PHY(17),
- { 0x1372169c, 0x137216a5, 0x137216a8, 0x1372169c } },
- { AR5K_PHY(18),
- { 0x0018ba67, 0x0018ba67, 0x0018ba69, 0x0018ba69 } },
- { AR5K_PHY(20),
- { 0x0c28b4e0, 0x0c28b4e0, 0x0c28b4e0, 0x0c28b4e0 } },
+ { 0x02020200, 0x02010200, 0x02020200 } },
+ { AR5K_PHY_RF_CTL2,
+ { 0x00000e0e, 0x00000707, 0x00000e0e } },
+ { AR5K_PHY_RF_CTL3,
+ { 0x0a020001, 0x05010000, 0x0a020001 } },
+ { AR5K_PHY_RF_CTL4,
+ { 0x00000e0e, 0x00000e0e, 0x00000e0e } },
+ { AR5K_PHY_PA_CTL,
+ { 0x00000007, 0x0000000b, 0x0000000b } },
+ { AR5K_PHY_SETTLING,
+ { 0x1372169c, 0x137216a8, 0x1372169c } },
+ { AR5K_PHY_GAIN,
+ { 0x0018ba67, 0x0018ba69, 0x0018ba69 } },
+ { AR5K_PHY_DESIRED_SIZE,
+ { 0x0c28b4e0, 0x0c28b4e0, 0x0c28b4e0 } },
{ AR5K_PHY_SIG,
- { 0x7e800d2e, 0x7e800d2e, 0x7ec00d2e, 0x7e800d2e } },
+ { 0x7e800d2e, 0x7ec00d2e, 0x7e800d2e } },
{ AR5K_PHY_AGCCOARSE,
- { 0x31375d5e, 0x31375d5e, 0x313a5d5e, 0x31375d5e } },
+ { 0x31375d5e, 0x313a5d5e, 0x31375d5e } },
{ AR5K_PHY_AGCCTL,
- { 0x0000bd10, 0x0000bd10, 0x0000bd38, 0x0000bd10 } },
+ { 0x0000bd10, 0x0000bd38, 0x0000bd10 } },
{ AR5K_PHY_NF,
- { 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 } },
+ { 0x0001ce00, 0x0001ce00, 0x0001ce00 } },
{ AR5K_PHY_RX_DELAY,
- { 0x00002710, 0x00002710, 0x0000157c, 0x00002710 } },
+ { 0x00002710, 0x0000157c, 0x00002710 } },
{ AR5K_PHY(70),
- { 0x00000190, 0x00000190, 0x00000084, 0x00000190 } },
+ { 0x00000190, 0x00000084, 0x00000190 } },
{ AR5K_PHY_FRAME_CTL_5211,
- { 0x6fe01020, 0x6fe01020, 0x6fe00920, 0x6fe01020 } },
+ { 0x6fe01020, 0x6fe00920, 0x6fe01020 } },
{ AR5K_PHY_PCDAC_TXPOWER_BASE,
- { 0x05ff14ff, 0x05ff14ff, 0x05ff14ff, 0x05ff19ff } },
+ { 0x05ff14ff, 0x05ff14ff, 0x05ff19ff } },
{ AR5K_RF_BUFFER_CONTROL_4,
- { 0x00000010, 0x00000014, 0x00000010, 0x00000010 } },
+ { 0x00000010, 0x00000010, 0x00000010 } },
};
/* Initial register settings for AR5212 */
@@ -677,89 +675,87 @@ static const struct ath5k_ini ar5212_ini_common_start[] = {
/* Initial mode-specific settings for AR5212 (Written before ar5212_ini) */
static const struct ath5k_ini_mode ar5212_ini_mode_start[] = {
{ AR5K_QUEUE_DFS_LOCAL_IFS(0),
- /* a/XR aTurbo b g (DYN) gTurbo */
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+ /* A/XR B G */
+ { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(1),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(2),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(3),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(4),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(5),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(6),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(7),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(8),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(9),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_DCU_GBL_IFS_SIFS,
- { 0x00000230, 0x000001e0, 0x000000b0, 0x00000160, 0x000001e0 } },
+ { 0x00000230, 0x000000b0, 0x00000160 } },
{ AR5K_DCU_GBL_IFS_SLOT,
- { 0x00000168, 0x000001e0, 0x000001b8, 0x0000018c, 0x000001e0 } },
+ { 0x00000168, 0x000001b8, 0x0000018c } },
{ AR5K_DCU_GBL_IFS_EIFS,
- { 0x00000e60, 0x00001180, 0x00001f1c, 0x00003e38, 0x00001180 } },
+ { 0x00000e60, 0x00001f1c, 0x00003e38 } },
{ AR5K_DCU_GBL_IFS_MISC,
- { 0x0000a0e0, 0x00014068, 0x00005880, 0x0000b0e0, 0x00014068 } },
+ { 0x0000a0e0, 0x00005880, 0x0000b0e0 } },
{ AR5K_TIME_OUT,
- { 0x03e803e8, 0x06e006e0, 0x04200420, 0x08400840, 0x06e006e0 } },
- { AR5K_PHY_TURBO,
- { 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000003 } },
+ { 0x03e803e8, 0x04200420, 0x08400840 } },
{ AR5K_PHY(8),
- { 0x02020200, 0x02020200, 0x02010200, 0x02020200, 0x02020200 } },
+ { 0x02020200, 0x02010200, 0x02020200 } },
{ AR5K_PHY_RF_CTL2,
- { 0x00000e0e, 0x00000e0e, 0x00000707, 0x00000e0e, 0x00000e0e } },
+ { 0x00000e0e, 0x00000707, 0x00000e0e } },
{ AR5K_PHY_SETTLING,
- { 0x1372161c, 0x13721c25, 0x13721722, 0x137216a2, 0x13721c25 } },
+ { 0x1372161c, 0x13721722, 0x137216a2 } },
{ AR5K_PHY_AGCCTL,
- { 0x00009d10, 0x00009d10, 0x00009d18, 0x00009d18, 0x00009d10 } },
+ { 0x00009d10, 0x00009d18, 0x00009d18 } },
{ AR5K_PHY_NF,
- { 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 } },
+ { 0x0001ce00, 0x0001ce00, 0x0001ce00 } },
{ AR5K_PHY_WEAK_OFDM_HIGH_THR,
- { 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190 } },
+ { 0x409a4190, 0x409a4190, 0x409a4190 } },
{ AR5K_PHY(70),
- { 0x000001b8, 0x000001b8, 0x00000084, 0x00000108, 0x000001b8 } },
+ { 0x000001b8, 0x00000084, 0x00000108 } },
{ AR5K_PHY_OFDM_SELFCORR,
- { 0x10058a05, 0x10058a05, 0x10058a05, 0x10058a05, 0x10058a05 } },
+ { 0x10058a05, 0x10058a05, 0x10058a05 } },
{ 0xa230,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000108, 0x00000000 } },
+ { 0x00000000, 0x00000000, 0x00000108 } },
};
/* Initial mode-specific settings for AR5212 + RF5111 (Written after ar5212_ini) */
static const struct ath5k_ini_mode rf5111_ini_mode_end[] = {
{ AR5K_TXCFG,
- /* a/XR aTurbo b g (DYN) gTurbo */
- { 0x00008015, 0x00008015, 0x00008015, 0x00008015, 0x00008015 } },
+ /* A/XR B G */
+ { 0x00008015, 0x00008015, 0x00008015 } },
{ AR5K_USEC_5211,
- { 0x128d8fa7, 0x09880fcf, 0x04e00f95, 0x12e00fab, 0x09880fcf } },
+ { 0x128d8fa7, 0x04e00f95, 0x12e00fab } },
{ AR5K_PHY_RF_CTL3,
- { 0x0a020001, 0x0a020001, 0x05010100, 0x0a020001, 0x0a020001 } },
+ { 0x0a020001, 0x05010100, 0x0a020001 } },
{ AR5K_PHY_RF_CTL4,
- { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
+ { 0x00000e0e, 0x00000e0e, 0x00000e0e } },
{ AR5K_PHY_PA_CTL,
- { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
+ { 0x00000007, 0x0000000b, 0x0000000b } },
{ AR5K_PHY_GAIN,
- { 0x0018da5a, 0x0018da5a, 0x0018ca69, 0x0018ca69, 0x0018ca69 } },
+ { 0x0018da5a, 0x0018ca69, 0x0018ca69 } },
{ AR5K_PHY_DESIRED_SIZE,
- { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } },
+ { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } },
{ AR5K_PHY_SIG,
- { 0x7e800d2e, 0x7e800d2e, 0x7ee84d2e, 0x7ee84d2e, 0x7e800d2e } },
+ { 0x7e800d2e, 0x7ee84d2e, 0x7ee84d2e } },
{ AR5K_PHY_AGCCOARSE,
- { 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e, 0x3137615e } },
+ { 0x3137665e, 0x3137665e, 0x3137665e } },
{ AR5K_PHY_WEAK_OFDM_LOW_THR,
- { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb080, 0x050cb080 } },
+ { 0x050cb081, 0x050cb081, 0x050cb080 } },
{ AR5K_PHY_RX_DELAY,
- { 0x00002710, 0x00002710, 0x0000157c, 0x00002af8, 0x00002710 } },
+ { 0x00002710, 0x0000157c, 0x00002af8 } },
{ AR5K_PHY_FRAME_CTL_5211,
- { 0xf7b81020, 0xf7b81020, 0xf7b80d20, 0xf7b81020, 0xf7b81020 } },
+ { 0xf7b81020, 0xf7b80d20, 0xf7b81020 } },
{ AR5K_PHY_GAIN_2GHZ,
- { 0x642c416a, 0x642c416a, 0x6440416a, 0x6440416a, 0x6440416a } },
+ { 0x642c416a, 0x6440416a, 0x6440416a } },
{ AR5K_PHY_CCK_RX_CTL_4,
- { 0x1883800a, 0x1883800a, 0x1873800a, 0x1883800a, 0x1883800a } },
+ { 0x1883800a, 0x1873800a, 0x1883800a } },
};
static const struct ath5k_ini rf5111_ini_common_end[] = {
@@ -782,38 +778,38 @@ static const struct ath5k_ini rf5111_ini_common_end[] = {
/* Initial mode-specific settings for AR5212 + RF5112 (Written after ar5212_ini) */
static const struct ath5k_ini_mode rf5112_ini_mode_end[] = {
{ AR5K_TXCFG,
- /* a/XR aTurbo b g (DYN) gTurbo */
- { 0x00008015, 0x00008015, 0x00008015, 0x00008015, 0x00008015 } },
+ /* A/XR B G */
+ { 0x00008015, 0x00008015, 0x00008015 } },
{ AR5K_USEC_5211,
- { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
+ { 0x128d93a7, 0x04e01395, 0x12e013ab } },
{ AR5K_PHY_RF_CTL3,
- { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } },
+ { 0x0a020001, 0x05020100, 0x0a020001 } },
{ AR5K_PHY_RF_CTL4,
- { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
+ { 0x00000e0e, 0x00000e0e, 0x00000e0e } },
{ AR5K_PHY_PA_CTL,
- { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
+ { 0x00000007, 0x0000000b, 0x0000000b } },
{ AR5K_PHY_GAIN,
- { 0x0018da6d, 0x0018da6d, 0x0018ca75, 0x0018ca75, 0x0018ca75 } },
+ { 0x0018da6d, 0x0018ca75, 0x0018ca75 } },
{ AR5K_PHY_DESIRED_SIZE,
- { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } },
+ { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } },
{ AR5K_PHY_SIG,
- { 0x7e800d2e, 0x7e800d2e, 0x7ee80d2e, 0x7ee80d2e, 0x7e800d2e } },
+ { 0x7e800d2e, 0x7ee80d2e, 0x7ee80d2e } },
{ AR5K_PHY_AGCCOARSE,
- { 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e } },
+ { 0x3137665e, 0x3137665e, 0x3137665e } },
{ AR5K_PHY_WEAK_OFDM_LOW_THR,
- { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
+ { 0x050cb081, 0x050cb081, 0x050cb081 } },
{ AR5K_PHY_RX_DELAY,
- { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
+ { 0x000007d0, 0x0000044c, 0x00000898 } },
{ AR5K_PHY_FRAME_CTL_5211,
- { 0xf7b81020, 0xf7b81020, 0xf7b80d10, 0xf7b81010, 0xf7b81010 } },
+ { 0xf7b81020, 0xf7b80d10, 0xf7b81010 } },
{ AR5K_PHY_CCKTXCTL,
- { 0x00000000, 0x00000000, 0x00000008, 0x00000008, 0x00000008 } },
+ { 0x00000000, 0x00000008, 0x00000008 } },
{ AR5K_PHY_CCK_CROSSCORR,
- { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
+ { 0xd6be6788, 0xd03e6788, 0xd03e6788 } },
{ AR5K_PHY_GAIN_2GHZ,
- { 0x642c0140, 0x642c0140, 0x6442c160, 0x6442c160, 0x6442c160 } },
+ { 0x642c0140, 0x6442c160, 0x6442c160 } },
{ AR5K_PHY_CCK_RX_CTL_4,
- { 0x1883800a, 0x1883800a, 0x1873800a, 0x1883800a, 0x1883800a } },
+ { 0x1883800a, 0x1873800a, 0x1883800a } },
};
static const struct ath5k_ini rf5112_ini_common_end[] = {
@@ -833,66 +829,66 @@ static const struct ath5k_ini rf5112_ini_common_end[] = {
/* Initial mode-specific settings for RF5413/5414 (Written after ar5212_ini) */
static const struct ath5k_ini_mode rf5413_ini_mode_end[] = {
{ AR5K_TXCFG,
- /* a/XR aTurbo b g (DYN) gTurbo */
- { 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } },
+ /* A/XR B G */
+ { 0x00000015, 0x00000015, 0x00000015 } },
{ AR5K_USEC_5211,
- { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
+ { 0x128d93a7, 0x04e01395, 0x12e013ab } },
{ AR5K_PHY_RF_CTL3,
- { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } },
+ { 0x0a020001, 0x05020100, 0x0a020001 } },
{ AR5K_PHY_RF_CTL4,
- { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
+ { 0x00000e0e, 0x00000e0e, 0x00000e0e } },
{ AR5K_PHY_PA_CTL,
- { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
+ { 0x00000007, 0x0000000b, 0x0000000b } },
{ AR5K_PHY_GAIN,
- { 0x0018fa61, 0x0018fa61, 0x001a1a63, 0x001a1a63, 0x001a1a63 } },
+ { 0x0018fa61, 0x001a1a63, 0x001a1a63 } },
{ AR5K_PHY_DESIRED_SIZE,
- { 0x0c98b4e0, 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da, 0x0c98b0da } },
+ { 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da } },
{ AR5K_PHY_SIG,
- { 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } },
+ { 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } },
{ AR5K_PHY_AGCCOARSE,
- { 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e } },
+ { 0x3139605e, 0x3139605e, 0x3139605e } },
{ AR5K_PHY_WEAK_OFDM_LOW_THR,
- { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
+ { 0x050cb081, 0x050cb081, 0x050cb081 } },
{ AR5K_PHY_RX_DELAY,
- { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
+ { 0x000007d0, 0x0000044c, 0x00000898 } },
{ AR5K_PHY_FRAME_CTL_5211,
- { 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } },
+ { 0xf7b81000, 0xf7b80d00, 0xf7b81000 } },
{ AR5K_PHY_CCKTXCTL,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 0x00000000, 0x00000000, 0x00000000 } },
{ AR5K_PHY_CCK_CROSSCORR,
- { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
+ { 0xd6be6788, 0xd03e6788, 0xd03e6788 } },
{ AR5K_PHY_GAIN_2GHZ,
- { 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 } },
+ { 0x002ec1e0, 0x002ac120, 0x002ac120 } },
{ AR5K_PHY_CCK_RX_CTL_4,
- { 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } },
+ { 0x1883800a, 0x1863800a, 0x1883800a } },
{ 0xa300,
- { 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 } },
+ { 0x18010000, 0x18010000, 0x18010000 } },
{ 0xa304,
- { 0x30032602, 0x30032602, 0x30032602, 0x30032602, 0x30032602 } },
+ { 0x30032602, 0x30032602, 0x30032602 } },
{ 0xa308,
- { 0x48073e06, 0x48073e06, 0x48073e06, 0x48073e06, 0x48073e06 } },
+ { 0x48073e06, 0x48073e06, 0x48073e06 } },
{ 0xa30c,
- { 0x560b4c0a, 0x560b4c0a, 0x560b4c0a, 0x560b4c0a, 0x560b4c0a } },
+ { 0x560b4c0a, 0x560b4c0a, 0x560b4c0a } },
{ 0xa310,
- { 0x641a600f, 0x641a600f, 0x641a600f, 0x641a600f, 0x641a600f } },
+ { 0x641a600f, 0x641a600f, 0x641a600f } },
{ 0xa314,
- { 0x784f6e1b, 0x784f6e1b, 0x784f6e1b, 0x784f6e1b, 0x784f6e1b } },
+ { 0x784f6e1b, 0x784f6e1b, 0x784f6e1b } },
{ 0xa318,
- { 0x868f7c5a, 0x868f7c5a, 0x868f7c5a, 0x868f7c5a, 0x868f7c5a } },
+ { 0x868f7c5a, 0x868f7c5a, 0x868f7c5a } },
{ 0xa31c,
- { 0x90cf865b, 0x90cf865b, 0x8ecf865b, 0x8ecf865b, 0x8ecf865b } },
+ { 0x90cf865b, 0x8ecf865b, 0x8ecf865b } },
{ 0xa320,
- { 0x9d4f970f, 0x9d4f970f, 0x9b4f970f, 0x9b4f970f, 0x9b4f970f } },
+ { 0x9d4f970f, 0x9b4f970f, 0x9b4f970f } },
{ 0xa324,
- { 0xa7cfa38f, 0xa7cfa38f, 0xa3cf9f8f, 0xa3cf9f8f, 0xa3cf9f8f } },
+ { 0xa7cfa38f, 0xa3cf9f8f, 0xa3cf9f8f } },
{ 0xa328,
- { 0xb55faf1f, 0xb55faf1f, 0xb35faf1f, 0xb35faf1f, 0xb35faf1f } },
+ { 0xb55faf1f, 0xb35faf1f, 0xb35faf1f } },
{ 0xa32c,
- { 0xbddfb99f, 0xbddfb99f, 0xbbdfb99f, 0xbbdfb99f, 0xbbdfb99f } },
+ { 0xbddfb99f, 0xbbdfb99f, 0xbbdfb99f } },
{ 0xa330,
- { 0xcb7fc53f, 0xcb7fc53f, 0xcb7fc73f, 0xcb7fc73f, 0xcb7fc73f } },
+ { 0xcb7fc53f, 0xcb7fc73f, 0xcb7fc73f } },
{ 0xa334,
- { 0xd5ffd1bf, 0xd5ffd1bf, 0xd3ffd1bf, 0xd3ffd1bf, 0xd3ffd1bf } },
+ { 0xd5ffd1bf, 0xd3ffd1bf, 0xd3ffd1bf } },
};
static const struct ath5k_ini rf5413_ini_common_end[] = {
@@ -972,38 +968,38 @@ static const struct ath5k_ini rf5413_ini_common_end[] = {
/* XXX: a mode ? */
static const struct ath5k_ini_mode rf2413_ini_mode_end[] = {
{ AR5K_TXCFG,
- /* a/XR aTurbo b g (DYN) gTurbo */
- { 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } },
+ /* A/XR B G */
+ { 0x00000015, 0x00000015, 0x00000015 } },
{ AR5K_USEC_5211,
- { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
+ { 0x128d93a7, 0x04e01395, 0x12e013ab } },
{ AR5K_PHY_RF_CTL3,
- { 0x0a020001, 0x0a020001, 0x05020000, 0x0a020001, 0x0a020001 } },
+ { 0x0a020001, 0x05020000, 0x0a020001 } },
{ AR5K_PHY_RF_CTL4,
- { 0x00000e00, 0x00000e00, 0x00000e00, 0x00000e00, 0x00000e00 } },
+ { 0x00000e00, 0x00000e00, 0x00000e00 } },
{ AR5K_PHY_PA_CTL,
- { 0x00000002, 0x00000002, 0x0000000a, 0x0000000a, 0x0000000a } },
+ { 0x00000002, 0x0000000a, 0x0000000a } },
{ AR5K_PHY_GAIN,
- { 0x0018da6d, 0x0018da6d, 0x001a6a64, 0x001a6a64, 0x001a6a64 } },
+ { 0x0018da6d, 0x001a6a64, 0x001a6a64 } },
{ AR5K_PHY_DESIRED_SIZE,
- { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b0da, 0x0c98b0da, 0x0de8b0da } },
+ { 0x0de8b4e0, 0x0de8b0da, 0x0c98b0da } },
{ AR5K_PHY_SIG,
- { 0x7e800d2e, 0x7e800d2e, 0x7ee80d2e, 0x7ec80d2e, 0x7e800d2e } },
+ { 0x7e800d2e, 0x7ee80d2e, 0x7ec80d2e } },
{ AR5K_PHY_AGCCOARSE,
- { 0x3137665e, 0x3137665e, 0x3137665e, 0x3139605e, 0x3137665e } },
+ { 0x3137665e, 0x3137665e, 0x3139605e } },
{ AR5K_PHY_WEAK_OFDM_LOW_THR,
- { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
+ { 0x050cb081, 0x050cb081, 0x050cb081 } },
{ AR5K_PHY_RX_DELAY,
- { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
+ { 0x000007d0, 0x0000044c, 0x00000898 } },
{ AR5K_PHY_FRAME_CTL_5211,
- { 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } },
+ { 0xf7b81000, 0xf7b80d00, 0xf7b81000 } },
{ AR5K_PHY_CCKTXCTL,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 0x00000000, 0x00000000, 0x00000000 } },
{ AR5K_PHY_CCK_CROSSCORR,
- { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
+ { 0xd6be6788, 0xd03e6788, 0xd03e6788 } },
{ AR5K_PHY_GAIN_2GHZ,
- { 0x002c0140, 0x002c0140, 0x0042c140, 0x0042c140, 0x0042c140 } },
+ { 0x002c0140, 0x0042c140, 0x0042c140 } },
{ AR5K_PHY_CCK_RX_CTL_4,
- { 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } },
+ { 0x1883800a, 0x1863800a, 0x1883800a } },
};
static const struct ath5k_ini rf2413_ini_common_end[] = {
@@ -1094,52 +1090,50 @@ static const struct ath5k_ini rf2413_ini_common_end[] = {
/* XXX: a mode ? */
static const struct ath5k_ini_mode rf2425_ini_mode_end[] = {
{ AR5K_TXCFG,
- /* a/XR aTurbo b g (DYN) gTurbo */
- { 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } },
+ /* A/XR B G */
+ { 0x00000015, 0x00000015, 0x00000015 } },
{ AR5K_USEC_5211,
- { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
- { AR5K_PHY_TURBO,
- { 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000001 } },
+ { 0x128d93a7, 0x04e01395, 0x12e013ab } },
{ AR5K_PHY_RF_CTL3,
- { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } },
+ { 0x0a020001, 0x05020100, 0x0a020001 } },
{ AR5K_PHY_RF_CTL4,
- { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
+ { 0x00000e0e, 0x00000e0e, 0x00000e0e } },
{ AR5K_PHY_PA_CTL,
- { 0x00000003, 0x00000003, 0x0000000b, 0x0000000b, 0x0000000b } },
+ { 0x00000003, 0x0000000b, 0x0000000b } },
{ AR5K_PHY_SETTLING,
- { 0x1372161c, 0x13721c25, 0x13721722, 0x13721422, 0x13721c25 } },
+ { 0x1372161c, 0x13721722, 0x13721422 } },
{ AR5K_PHY_GAIN,
- { 0x0018fa61, 0x0018fa61, 0x00199a65, 0x00199a65, 0x00199a65 } },
+ { 0x0018fa61, 0x00199a65, 0x00199a65 } },
{ AR5K_PHY_DESIRED_SIZE,
- { 0x0c98b4e0, 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da, 0x0c98b0da } },
+ { 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da } },
{ AR5K_PHY_SIG,
- { 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } },
+ { 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } },
{ AR5K_PHY_AGCCOARSE,
- { 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e } },
+ { 0x3139605e, 0x3139605e, 0x3139605e } },
{ AR5K_PHY_WEAK_OFDM_LOW_THR,
- { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
+ { 0x050cb081, 0x050cb081, 0x050cb081 } },
{ AR5K_PHY_RX_DELAY,
- { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
+ { 0x000007d0, 0x0000044c, 0x00000898 } },
{ AR5K_PHY_FRAME_CTL_5211,
- { 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } },
+ { 0xf7b81000, 0xf7b80d00, 0xf7b81000 } },
{ AR5K_PHY_CCKTXCTL,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 0x00000000, 0x00000000, 0x00000000 } },
{ AR5K_PHY_CCK_CROSSCORR,
- { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
+ { 0xd6be6788, 0xd03e6788, 0xd03e6788 } },
{ AR5K_PHY_GAIN_2GHZ,
- { 0x00000140, 0x00000140, 0x0052c140, 0x0052c140, 0x0052c140 } },
+ { 0x00000140, 0x0052c140, 0x0052c140 } },
{ AR5K_PHY_CCK_RX_CTL_4,
- { 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } },
+ { 0x1883800a, 0x1863800a, 0x1883800a } },
{ 0xa324,
- { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
+ { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
{ 0xa328,
- { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
+ { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
{ 0xa32c,
- { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
+ { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
{ 0xa330,
- { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
+ { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
{ 0xa334,
- { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
+ { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
};
static const struct ath5k_ini rf2425_ini_common_end[] = {
@@ -1368,15 +1362,15 @@ static const struct ath5k_ini rf5112_ini_bbgain[] = {
* Write initial register dump
*/
static void ath5k_hw_ini_registers(struct ath5k_hw *ah, unsigned int size,
- const struct ath5k_ini *ini_regs, bool change_channel)
+ const struct ath5k_ini *ini_regs, bool skip_pcu)
{
unsigned int i;
/* Write initial registers */
for (i = 0; i < size; i++) {
- /* On channel change there is
- * no need to mess with PCU */
- if (change_channel &&
+ /* Skip PCU registers if
+ * requested */
+ if (skip_pcu &&
ini_regs[i].ini_register >= AR5K_PCU_MIN &&
ini_regs[i].ini_register <= AR5K_PCU_MAX)
continue;
@@ -1409,7 +1403,7 @@ static void ath5k_hw_ini_mode_registers(struct ath5k_hw *ah,
}
-int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
+int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool skip_pcu)
{
/*
* Write initial register settings
@@ -1427,7 +1421,7 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
* Write initial settings common for all modes
*/
ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5212_ini_common_start),
- ar5212_ini_common_start, change_channel);
+ ar5212_ini_common_start, skip_pcu);
/* Second set of mode-specific settings */
switch (ah->ah_radio) {
@@ -1439,12 +1433,12 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
ath5k_hw_ini_registers(ah,
ARRAY_SIZE(rf5111_ini_common_end),
- rf5111_ini_common_end, change_channel);
+ rf5111_ini_common_end, skip_pcu);
/* Baseband gain table */
ath5k_hw_ini_registers(ah,
ARRAY_SIZE(rf5111_ini_bbgain),
- rf5111_ini_bbgain, change_channel);
+ rf5111_ini_bbgain, skip_pcu);
break;
case AR5K_RF5112:
@@ -1455,11 +1449,11 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
ath5k_hw_ini_registers(ah,
ARRAY_SIZE(rf5112_ini_common_end),
- rf5112_ini_common_end, change_channel);
+ rf5112_ini_common_end, skip_pcu);
ath5k_hw_ini_registers(ah,
ARRAY_SIZE(rf5112_ini_bbgain),
- rf5112_ini_bbgain, change_channel);
+ rf5112_ini_bbgain, skip_pcu);
break;
case AR5K_RF5413:
@@ -1470,11 +1464,11 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
ath5k_hw_ini_registers(ah,
ARRAY_SIZE(rf5413_ini_common_end),
- rf5413_ini_common_end, change_channel);
+ rf5413_ini_common_end, skip_pcu);
ath5k_hw_ini_registers(ah,
ARRAY_SIZE(rf5112_ini_bbgain),
- rf5112_ini_bbgain, change_channel);
+ rf5112_ini_bbgain, skip_pcu);
break;
case AR5K_RF2316:
@@ -1486,7 +1480,7 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
ath5k_hw_ini_registers(ah,
ARRAY_SIZE(rf2413_ini_common_end),
- rf2413_ini_common_end, change_channel);
+ rf2413_ini_common_end, skip_pcu);
/* Override settings from rf2413_ini_common_end */
if (ah->ah_radio == AR5K_RF2316) {
@@ -1498,9 +1492,32 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
ath5k_hw_ini_registers(ah,
ARRAY_SIZE(rf5112_ini_bbgain),
- rf5112_ini_bbgain, change_channel);
+ rf5112_ini_bbgain, skip_pcu);
break;
case AR5K_RF2317:
+
+ ath5k_hw_ini_mode_registers(ah,
+ ARRAY_SIZE(rf2413_ini_mode_end),
+ rf2413_ini_mode_end, mode);
+
+ ath5k_hw_ini_registers(ah,
+ ARRAY_SIZE(rf2425_ini_common_end),
+ rf2425_ini_common_end, skip_pcu);
+
+ /* Override settings from rf2413_ini_mode_end */
+ ath5k_hw_reg_write(ah, 0x00180a65, AR5K_PHY_GAIN);
+
+ /* Override settings from rf2413_ini_common_end */
+ ath5k_hw_reg_write(ah, 0x00004000, AR5K_PHY_AGC);
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TPC_RG5,
+ AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP, 0xa);
+ ath5k_hw_reg_write(ah, 0x800000a8, 0x8140);
+ ath5k_hw_reg_write(ah, 0x000000ff, 0x9958);
+
+ ath5k_hw_ini_registers(ah,
+ ARRAY_SIZE(rf5112_ini_bbgain),
+ rf5112_ini_bbgain, skip_pcu);
+ break;
case AR5K_RF2425:
ath5k_hw_ini_mode_registers(ah,
@@ -1509,11 +1526,11 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
ath5k_hw_ini_registers(ah,
ARRAY_SIZE(rf2425_ini_common_end),
- rf2425_ini_common_end, change_channel);
+ rf2425_ini_common_end, skip_pcu);
ath5k_hw_ini_registers(ah,
ARRAY_SIZE(rf5112_ini_bbgain),
- rf5112_ini_bbgain, change_channel);
+ rf5112_ini_bbgain, skip_pcu);
break;
default:
return -EINVAL;
@@ -1538,17 +1555,17 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
* Write initial settings common for all modes
*/
ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5211_ini),
- ar5211_ini, change_channel);
+ ar5211_ini, skip_pcu);
/* AR5211 only comes with 5111 */
/* Baseband gain table */
ath5k_hw_ini_registers(ah, ARRAY_SIZE(rf5111_ini_bbgain),
- rf5111_ini_bbgain, change_channel);
+ rf5111_ini_bbgain, skip_pcu);
/* For AR5210 (for mode settings check out ath5k_hw_reset_tx_queue) */
} else if (ah->ah_version == AR5K_AR5210) {
ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5210_ini),
- ar5210_ini, change_channel);
+ ar5210_ini, skip_pcu);
}
return 0;
diff --git a/drivers/net/wireless/ath/ath5k/led.c b/drivers/net/wireless/ath/ath5k/led.c
index 67aa52e9bf94..576edf2965dc 100644
--- a/drivers/net/wireless/ath/ath5k/led.c
+++ b/drivers/net/wireless/ath/ath5k/led.c
@@ -133,7 +133,7 @@ ath5k_register_led(struct ath5k_softc *sc, struct ath5k_led *led,
led->led_dev.default_trigger = trigger;
led->led_dev.brightness_set = ath5k_led_brightness_set;
- err = led_classdev_register(&sc->pdev->dev, &led->led_dev);
+ err = led_classdev_register(sc->dev, &led->led_dev);
if (err) {
ATH5K_WARN(sc, "could not register LED %s\n", name);
led->sc = NULL;
@@ -161,11 +161,20 @@ int ath5k_init_leds(struct ath5k_softc *sc)
{
int ret = 0;
struct ieee80211_hw *hw = sc->hw;
+#ifndef CONFIG_ATHEROS_AR231X
struct pci_dev *pdev = sc->pdev;
+#endif
char name[ATH5K_LED_MAX_NAME_LEN + 1];
const struct pci_device_id *match;
+ if (!sc->pdev)
+ return 0;
+
+#ifdef CONFIG_ATHEROS_AR231X
+ match = NULL;
+#else
match = pci_match_id(&ath5k_led_devices[0], pdev);
+#endif
if (match) {
__set_bit(ATH_STAT_LEDSOFT, sc->status);
sc->led_pin = ATH_PIN(match->driver_data);
diff --git a/drivers/net/wireless/ath/ath5k/pci.c b/drivers/net/wireless/ath/ath5k/pci.c
new file mode 100644
index 000000000000..39f033128c5a
--- /dev/null
+++ b/drivers/net/wireless/ath/ath5k/pci.c
@@ -0,0 +1,326 @@
+/*
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/nl80211.h>
+#include <linux/pci.h>
+#include <linux/pci-aspm.h>
+#include "../ath.h"
+#include "ath5k.h"
+#include "debug.h"
+#include "base.h"
+#include "reg.h"
+
+/* Known PCI ids */
+static DEFINE_PCI_DEVICE_TABLE(ath5k_pci_id_table) = {
+ { PCI_VDEVICE(ATHEROS, 0x0207) }, /* 5210 early */
+ { PCI_VDEVICE(ATHEROS, 0x0007) }, /* 5210 */
+ { PCI_VDEVICE(ATHEROS, 0x0011) }, /* 5311 - this is on AHB bus !*/
+ { PCI_VDEVICE(ATHEROS, 0x0012) }, /* 5211 */
+ { PCI_VDEVICE(ATHEROS, 0x0013) }, /* 5212 */
+ { PCI_VDEVICE(3COM_2, 0x0013) }, /* 3com 5212 */
+ { PCI_VDEVICE(3COM, 0x0013) }, /* 3com 3CRDAG675 5212 */
+ { PCI_VDEVICE(ATHEROS, 0x1014) }, /* IBM minipci 5212 */
+ { PCI_VDEVICE(ATHEROS, 0x0014) }, /* 5212 combatible */
+ { PCI_VDEVICE(ATHEROS, 0x0015) }, /* 5212 combatible */
+ { PCI_VDEVICE(ATHEROS, 0x0016) }, /* 5212 combatible */
+ { PCI_VDEVICE(ATHEROS, 0x0017) }, /* 5212 combatible */
+ { PCI_VDEVICE(ATHEROS, 0x0018) }, /* 5212 combatible */
+ { PCI_VDEVICE(ATHEROS, 0x0019) }, /* 5212 combatible */
+ { PCI_VDEVICE(ATHEROS, 0x001a) }, /* 2413 Griffin-lite */
+ { PCI_VDEVICE(ATHEROS, 0x001b) }, /* 5413 Eagle */
+ { PCI_VDEVICE(ATHEROS, 0x001c) }, /* PCI-E cards */
+ { PCI_VDEVICE(ATHEROS, 0x001d) }, /* 2417 Nala */
+ { 0 }
+};
+
+/* return bus cachesize in 4B word units */
+static void ath5k_pci_read_cachesize(struct ath_common *common, int *csz)
+{
+ struct ath5k_softc *sc = (struct ath5k_softc *) common->priv;
+ u8 u8tmp;
+
+ pci_read_config_byte(sc->pdev, PCI_CACHE_LINE_SIZE, &u8tmp);
+ *csz = (int)u8tmp;
+
+ /*
+ * This check was put in to avoid "unplesant" consequences if
+ * the bootrom has not fully initialized all PCI devices.
+ * Sometimes the cache line size register is not set
+ */
+
+ if (*csz == 0)
+ *csz = L1_CACHE_BYTES >> 2; /* Use the default size */
+}
+
+/*
+ * Read from eeprom
+ */
+bool ath5k_pci_eeprom_read(struct ath_common *common, u32 offset, u16 *data)
+{
+ struct ath5k_hw *ah = (struct ath5k_hw *) common->ah;
+ u32 status, timeout;
+
+ /*
+ * Initialize EEPROM access
+ */
+ if (ah->ah_version == AR5K_AR5210) {
+ AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_EEAE);
+ (void)ath5k_hw_reg_read(ah, AR5K_EEPROM_BASE + (4 * offset));
+ } else {
+ ath5k_hw_reg_write(ah, offset, AR5K_EEPROM_BASE);
+ AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD,
+ AR5K_EEPROM_CMD_READ);
+ }
+
+ for (timeout = AR5K_TUNE_REGISTER_TIMEOUT; timeout > 0; timeout--) {
+ status = ath5k_hw_reg_read(ah, AR5K_EEPROM_STATUS);
+ if (status & AR5K_EEPROM_STAT_RDDONE) {
+ if (status & AR5K_EEPROM_STAT_RDERR)
+ return -EIO;
+ *data = (u16)(ath5k_hw_reg_read(ah, AR5K_EEPROM_DATA) &
+ 0xffff);
+ return 0;
+ }
+ udelay(15);
+ }
+
+ return -ETIMEDOUT;
+}
+
+int ath5k_hw_read_srev(struct ath5k_hw *ah)
+{
+ ah->ah_mac_srev = ath5k_hw_reg_read(ah, AR5K_SREV);
+ return 0;
+}
+
+/* Common ath_bus_opts structure */
+static const struct ath_bus_ops ath_pci_bus_ops = {
+ .ath_bus_type = ATH_PCI,
+ .read_cachesize = ath5k_pci_read_cachesize,
+ .eeprom_read = ath5k_pci_eeprom_read,
+};
+
+/********************\
+* PCI Initialization *
+\********************/
+
+static int __devinit
+ath5k_pci_probe(struct pci_dev *pdev,
+ const struct pci_device_id *id)
+{
+ void __iomem *mem;
+ struct ath5k_softc *sc;
+ struct ieee80211_hw *hw;
+ int ret;
+ u8 csz;
+
+ /*
+ * L0s needs to be disabled on all ath5k cards.
+ *
+ * For distributions shipping with CONFIG_PCIEASPM (this will be enabled
+ * by default in the future in 2.6.36) this will also mean both L1 and
+ * L0s will be disabled when a pre 1.1 PCIe device is detected. We do
+ * know L1 works correctly even for all ath5k pre 1.1 PCIe devices
+ * though but cannot currently undue the effect of a blacklist, for
+ * details you can read pcie_aspm_sanity_check() and see how it adjusts
+ * the device link capability.
+ *
+ * It may be possible in the future to implement some PCI API to allow
+ * drivers to override blacklists for pre 1.1 PCIe but for now it is
+ * best to accept that both L0s and L1 will be disabled completely for
+ * distributions shipping with CONFIG_PCIEASPM rather than having this
+ * issue present. Motivation for adding this new API will be to help
+ * with power consumption for some of these devices.
+ */
+ pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S);
+
+ ret = pci_enable_device(pdev);
+ if (ret) {
+ dev_err(&pdev->dev, "can't enable device\n");
+ goto err;
+ }
+
+ /* XXX 32-bit addressing only */
+ ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+ if (ret) {
+ dev_err(&pdev->dev, "32-bit DMA not available\n");
+ goto err_dis;
+ }
+
+ /*
+ * Cache line size is used to size and align various
+ * structures used to communicate with the hardware.
+ */
+ pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);
+ if (csz == 0) {
+ /*
+ * Linux 2.4.18 (at least) writes the cache line size
+ * register as a 16-bit wide register which is wrong.
+ * We must have this setup properly for rx buffer
+ * DMA to work so force a reasonable value here if it
+ * comes up zero.
+ */
+ csz = L1_CACHE_BYTES >> 2;
+ pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
+ }
+ /*
+ * The default setting of latency timer yields poor results,
+ * set it to the value used by other systems. It may be worth
+ * tweaking this setting more.
+ */
+ pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);
+
+ /* Enable bus mastering */
+ pci_set_master(pdev);
+
+ /*
+ * Disable the RETRY_TIMEOUT register (0x41) to keep
+ * PCI Tx retries from interfering with C3 CPU state.
+ */
+ pci_write_config_byte(pdev, 0x41, 0);
+
+ ret = pci_request_region(pdev, 0, "ath5k");
+ if (ret) {
+ dev_err(&pdev->dev, "cannot reserve PCI memory region\n");
+ goto err_dis;
+ }
+
+ mem = pci_iomap(pdev, 0, 0);
+ if (!mem) {
+ dev_err(&pdev->dev, "cannot remap PCI memory region\n") ;
+ ret = -EIO;
+ goto err_reg;
+ }
+
+ /*
+ * Allocate hw (mac80211 main struct)
+ * and hw->priv (driver private data)
+ */
+ hw = ieee80211_alloc_hw(sizeof(*sc), &ath5k_hw_ops);
+ if (hw == NULL) {
+ dev_err(&pdev->dev, "cannot allocate ieee80211_hw\n");
+ ret = -ENOMEM;
+ goto err_map;
+ }
+
+ dev_info(&pdev->dev, "registered as '%s'\n", wiphy_name(hw->wiphy));
+
+ sc = hw->priv;
+ sc->hw = hw;
+ sc->pdev = pdev;
+ sc->dev = &pdev->dev;
+ sc->irq = pdev->irq;
+ sc->devid = id->device;
+ sc->iobase = mem; /* So we can unmap it on detach */
+
+ /* Initialize */
+ ret = ath5k_init_softc(sc, &ath_pci_bus_ops);
+ if (ret)
+ goto err_free;
+
+ /* Set private data */
+ pci_set_drvdata(pdev, hw);
+
+ return 0;
+err_free:
+ ieee80211_free_hw(hw);
+err_map:
+ pci_iounmap(pdev, mem);
+err_reg:
+ pci_release_region(pdev, 0);
+err_dis:
+ pci_disable_device(pdev);
+err:
+ return ret;
+}
+
+static void __devexit
+ath5k_pci_remove(struct pci_dev *pdev)
+{
+ struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+ struct ath5k_softc *sc = hw->priv;
+
+ ath5k_deinit_softc(sc);
+ pci_iounmap(pdev, sc->iobase);
+ pci_release_region(pdev, 0);
+ pci_disable_device(pdev);
+ ieee80211_free_hw(hw);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int ath5k_pci_suspend(struct device *dev)
+{
+ struct ath5k_softc *sc = pci_get_drvdata(to_pci_dev(dev));
+
+ ath5k_led_off(sc);
+ return 0;
+}
+
+static int ath5k_pci_resume(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct ath5k_softc *sc = pci_get_drvdata(pdev);
+
+ /*
+ * Suspend/Resume resets the PCI configuration space, so we have to
+ * re-disable the RETRY_TIMEOUT register (0x41) to keep
+ * PCI Tx retries from interfering with C3 CPU state
+ */
+ pci_write_config_byte(pdev, 0x41, 0);
+
+ ath5k_led_enable(sc);
+ return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume);
+#define ATH5K_PM_OPS (&ath5k_pm_ops)
+#else
+#define ATH5K_PM_OPS NULL
+#endif /* CONFIG_PM_SLEEP */
+
+static struct pci_driver ath5k_pci_driver = {
+ .name = KBUILD_MODNAME,
+ .id_table = ath5k_pci_id_table,
+ .probe = ath5k_pci_probe,
+ .remove = __devexit_p(ath5k_pci_remove),
+ .driver.pm = ATH5K_PM_OPS,
+};
+
+/*
+ * Module init/exit functions
+ */
+static int __init
+init_ath5k_pci(void)
+{
+ int ret;
+
+ ret = pci_register_driver(&ath5k_pci_driver);
+ if (ret) {
+ printk(KERN_ERR "ath5k_pci: can't register pci driver\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static void __exit
+exit_ath5k_pci(void)
+{
+ pci_unregister_driver(&ath5k_pci_driver);
+}
+
+module_init(init_ath5k_pci);
+module_exit(exit_ath5k_pci);
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c
index 074b4c644399..e5f2b96a4c63 100644
--- a/drivers/net/wireless/ath/ath5k/pcu.c
+++ b/drivers/net/wireless/ath/ath5k/pcu.c
@@ -31,87 +31,163 @@
#include "debug.h"
#include "base.h"
+/*
+ * AR5212+ can use higher rates for ack transmition
+ * based on current tx rate instead of the base rate.
+ * It does this to better utilize channel usage.
+ * This is a mapping between G rates (that cover both
+ * CCK and OFDM) and ack rates that we use when setting
+ * rate -> duration table. This mapping is hw-based so
+ * don't change anything.
+ *
+ * To enable this functionality we must set
+ * ah->ah_ack_bitrate_high to true else base rate is
+ * used (1Mb for CCK, 6Mb for OFDM).
+ */
+static const unsigned int ack_rates_high[] =
+/* Tx -> ACK */
+/* 1Mb -> 1Mb */ { 0,
+/* 2MB -> 2Mb */ 1,
+/* 5.5Mb -> 2Mb */ 1,
+/* 11Mb -> 2Mb */ 1,
+/* 6Mb -> 6Mb */ 4,
+/* 9Mb -> 6Mb */ 4,
+/* 12Mb -> 12Mb */ 6,
+/* 18Mb -> 12Mb */ 6,
+/* 24Mb -> 24Mb */ 8,
+/* 36Mb -> 24Mb */ 8,
+/* 48Mb -> 24Mb */ 8,
+/* 54Mb -> 24Mb */ 8 };
+
/*******************\
-* Generic functions *
+* Helper functions *
\*******************/
/**
- * ath5k_hw_set_opmode - Set PCU operating mode
+ * ath5k_hw_get_frame_duration - Get tx time of a frame
*
* @ah: The &struct ath5k_hw
- * @op_mode: &enum nl80211_iftype operating mode
+ * @len: Frame's length in bytes
+ * @rate: The @struct ieee80211_rate
*
- * Initialize PCU for the various operating modes (AP/STA etc)
+ * Calculate tx duration of a frame given it's rate and length
+ * It extends ieee80211_generic_frame_duration for non standard
+ * bwmodes.
*/
-int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype op_mode)
+int ath5k_hw_get_frame_duration(struct ath5k_hw *ah,
+ int len, struct ieee80211_rate *rate)
{
- struct ath_common *common = ath5k_hw_common(ah);
- u32 pcu_reg, beacon_reg, low_id, high_id;
+ struct ath5k_softc *sc = ah->ah_sc;
+ int sifs, preamble, plcp_bits, sym_time;
+ int bitrate, bits, symbols, symbol_bits;
+ int dur;
+
+ /* Fallback */
+ if (!ah->ah_bwmode) {
+ dur = ieee80211_generic_frame_duration(sc->hw,
+ NULL, len, rate);
+ return dur;
+ }
- ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_MODE, "mode %d\n", op_mode);
+ bitrate = rate->bitrate;
+ preamble = AR5K_INIT_OFDM_PREAMPLE_TIME;
+ plcp_bits = AR5K_INIT_OFDM_PLCP_BITS;
+ sym_time = AR5K_INIT_OFDM_SYMBOL_TIME;
- /* Preserve rest settings */
- pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000;
- pcu_reg &= ~(AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_AP
- | AR5K_STA_ID1_KEYSRCH_MODE
- | (ah->ah_version == AR5K_AR5210 ?
- (AR5K_STA_ID1_PWR_SV | AR5K_STA_ID1_NO_PSPOLL) : 0));
+ switch (ah->ah_bwmode) {
+ case AR5K_BWMODE_40MHZ:
+ sifs = AR5K_INIT_SIFS_TURBO;
+ preamble = AR5K_INIT_OFDM_PREAMBLE_TIME_MIN;
+ break;
+ case AR5K_BWMODE_10MHZ:
+ sifs = AR5K_INIT_SIFS_HALF_RATE;
+ preamble *= 2;
+ sym_time *= 2;
+ break;
+ case AR5K_BWMODE_5MHZ:
+ sifs = AR5K_INIT_SIFS_QUARTER_RATE;
+ preamble *= 4;
+ sym_time *= 4;
+ break;
+ default:
+ sifs = AR5K_INIT_SIFS_DEFAULT_BG;
+ break;
+ }
- beacon_reg = 0;
+ bits = plcp_bits + (len << 3);
+ /* Bit rate is in 100Kbits */
+ symbol_bits = bitrate * sym_time;
+ symbols = DIV_ROUND_UP(bits * 10, symbol_bits);
- switch (op_mode) {
- case NL80211_IFTYPE_ADHOC:
- pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_KEYSRCH_MODE;
- beacon_reg |= AR5K_BCR_ADHOC;
- if (ah->ah_version == AR5K_AR5210)
- pcu_reg |= AR5K_STA_ID1_NO_PSPOLL;
- else
- AR5K_REG_ENABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS);
- break;
+ dur = sifs + preamble + (sym_time * symbols);
- case NL80211_IFTYPE_AP:
- case NL80211_IFTYPE_MESH_POINT:
- pcu_reg |= AR5K_STA_ID1_AP | AR5K_STA_ID1_KEYSRCH_MODE;
- beacon_reg |= AR5K_BCR_AP;
- if (ah->ah_version == AR5K_AR5210)
- pcu_reg |= AR5K_STA_ID1_NO_PSPOLL;
- else
- AR5K_REG_DISABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS);
- break;
+ return dur;
+}
- case NL80211_IFTYPE_STATION:
- pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE
- | (ah->ah_version == AR5K_AR5210 ?
- AR5K_STA_ID1_PWR_SV : 0);
- case NL80211_IFTYPE_MONITOR:
- pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE
- | (ah->ah_version == AR5K_AR5210 ?
- AR5K_STA_ID1_NO_PSPOLL : 0);
- break;
+/**
+ * ath5k_hw_get_default_slottime - Get the default slot time for current mode
+ *
+ * @ah: The &struct ath5k_hw
+ */
+unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah)
+{
+ struct ieee80211_channel *channel = ah->ah_current_channel;
+ unsigned int slot_time;
+ switch (ah->ah_bwmode) {
+ case AR5K_BWMODE_40MHZ:
+ slot_time = AR5K_INIT_SLOT_TIME_TURBO;
+ break;
+ case AR5K_BWMODE_10MHZ:
+ slot_time = AR5K_INIT_SLOT_TIME_HALF_RATE;
+ break;
+ case AR5K_BWMODE_5MHZ:
+ slot_time = AR5K_INIT_SLOT_TIME_QUARTER_RATE;
+ break;
+ case AR5K_BWMODE_DEFAULT:
+ slot_time = AR5K_INIT_SLOT_TIME_DEFAULT;
default:
- return -EINVAL;
+ if (channel->hw_value & CHANNEL_CCK)
+ slot_time = AR5K_INIT_SLOT_TIME_B;
+ break;
}
- /*
- * Set PCU registers
- */
- low_id = get_unaligned_le32(common->macaddr);
- high_id = get_unaligned_le16(common->macaddr + 4);
- ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
- ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1);
+ return slot_time;
+}
- /*
- * Set Beacon Control Register on 5210
- */
- if (ah->ah_version == AR5K_AR5210)
- ath5k_hw_reg_write(ah, beacon_reg, AR5K_BCR);
+/**
+ * ath5k_hw_get_default_sifs - Get the default SIFS for current mode
+ *
+ * @ah: The &struct ath5k_hw
+ */
+unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah)
+{
+ struct ieee80211_channel *channel = ah->ah_current_channel;
+ unsigned int sifs;
- return 0;
+ switch (ah->ah_bwmode) {
+ case AR5K_BWMODE_40MHZ:
+ sifs = AR5K_INIT_SIFS_TURBO;
+ break;
+ case AR5K_BWMODE_10MHZ:
+ sifs = AR5K_INIT_SIFS_HALF_RATE;
+ break;
+ case AR5K_BWMODE_5MHZ:
+ sifs = AR5K_INIT_SIFS_QUARTER_RATE;
+ break;
+ case AR5K_BWMODE_DEFAULT:
+ sifs = AR5K_INIT_SIFS_DEFAULT_BG;
+ default:
+ if (channel->hw_value & CHANNEL_5GHZ)
+ sifs = AR5K_INIT_SIFS_DEFAULT_A;
+ break;
+ }
+
+ return sifs;
}
/**
- * ath5k_hw_update - Update MIB counters (mac layer statistics)
+ * ath5k_hw_update_mib_counters - Update MIB counters (mac layer statistics)
*
* @ah: The &struct ath5k_hw
*
@@ -133,36 +209,88 @@ void ath5k_hw_update_mib_counters(struct ath5k_hw *ah)
stats->beacons += ath5k_hw_reg_read(ah, AR5K_BEACON_CNT);
}
+
+/******************\
+* ACK/CTS Timeouts *
+\******************/
+
/**
- * ath5k_hw_set_ack_bitrate - set bitrate for ACKs
+ * ath5k_hw_write_rate_duration - fill rate code to duration table
*
- * @ah: The &struct ath5k_hw
- * @high: Flag to determine if we want to use high transmission rate
- * for ACKs or not
+ * @ah: the &struct ath5k_hw
+ * @mode: one of enum ath5k_driver_mode
+ *
+ * Write the rate code to duration table upon hw reset. This is a helper for
+ * ath5k_hw_pcu_init(). It seems all this is doing is setting an ACK timeout on
+ * the hardware, based on current mode, for each rate. The rates which are
+ * capable of short preamble (802.11b rates 2Mbps, 5.5Mbps, and 11Mbps) have
+ * different rate code so we write their value twice (one for long preamble
+ * and one for short).
+ *
+ * Note: Band doesn't matter here, if we set the values for OFDM it works
+ * on both a and g modes. So all we have to do is set values for all g rates
+ * that include all OFDM and CCK rates.
*
- * If high flag is set, we tell hw to use a set of control rates based on
- * the current transmission rate (check out control_rates array inside reset.c).
- * If not hw just uses the lowest rate available for the current modulation
- * scheme being used (1Mbit for CCK and 6Mbits for OFDM).
*/
-void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high)
+static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah)
{
- if (ah->ah_version != AR5K_AR5212)
- return;
- else {
- u32 val = AR5K_STA_ID1_BASE_RATE_11B | AR5K_STA_ID1_ACKCTS_6MB;
- if (high)
- AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, val);
+ struct ath5k_softc *sc = ah->ah_sc;
+ struct ieee80211_rate *rate;
+ unsigned int i;
+ /* 802.11g covers both OFDM and CCK */
+ u8 band = IEEE80211_BAND_2GHZ;
+
+ /* Write rate duration table */
+ for (i = 0; i < sc->sbands[band].n_bitrates; i++) {
+ u32 reg;
+ u16 tx_time;
+
+ if (ah->ah_ack_bitrate_high)
+ rate = &sc->sbands[band].bitrates[ack_rates_high[i]];
+ /* CCK -> 1Mb */
+ else if (i < 4)
+ rate = &sc->sbands[band].bitrates[0];
+ /* OFDM -> 6Mb */
else
- AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, val);
+ rate = &sc->sbands[band].bitrates[4];
+
+ /* Set ACK timeout */
+ reg = AR5K_RATE_DUR(rate->hw_value);
+
+ /* An ACK frame consists of 10 bytes. If you add the FCS,
+ * which ieee80211_generic_frame_duration() adds,
+ * its 14 bytes. Note we use the control rate and not the
+ * actual rate for this rate. See mac80211 tx.c
+ * ieee80211_duration() for a brief description of
+ * what rate we should choose to TX ACKs. */
+ tx_time = ath5k_hw_get_frame_duration(ah, 10, rate);
+
+ tx_time = le16_to_cpu(tx_time);
+
+ ath5k_hw_reg_write(ah, tx_time, reg);
+
+ if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE))
+ continue;
+
+ /*
+ * We're not distinguishing short preamble here,
+ * This is true, all we'll get is a longer value here
+ * which is not necessarilly bad. We could use
+ * export ieee80211_frame_duration() but that needs to be
+ * fixed first to be properly used by mac802111 drivers:
+ *
+ * - remove erp stuff and let the routine figure ofdm
+ * erp rates
+ * - remove passing argument ieee80211_local as
+ * drivers don't have access to it
+ * - move drivers using ieee80211_generic_frame_duration()
+ * to this
+ */
+ ath5k_hw_reg_write(ah, tx_time,
+ reg + (AR5K_SET_SHORT_PREAMBLE << 2));
}
}
-
-/******************\
-* ACK/CTS Timeouts *
-\******************/
-
/**
* ath5k_hw_set_ack_timeout - Set ACK timeout on PCU
*
@@ -199,88 +327,10 @@ static int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout)
return 0;
}
-/**
- * ath5k_hw_htoclock - Translate usec to hw clock units
- *
- * @ah: The &struct ath5k_hw
- * @usec: value in microseconds
- */
-unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec)
-{
- struct ath_common *common = ath5k_hw_common(ah);
- return usec * common->clockrate;
-}
-
-/**
- * ath5k_hw_clocktoh - Translate hw clock units to usec
- * @clock: value in hw clock units
- */
-unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock)
-{
- struct ath_common *common = ath5k_hw_common(ah);
- return clock / common->clockrate;
-}
-
-/**
- * ath5k_hw_set_clockrate - Set common->clockrate for the current channel
- *
- * @ah: The &struct ath5k_hw
- */
-void ath5k_hw_set_clockrate(struct ath5k_hw *ah)
-{
- struct ieee80211_channel *channel = ah->ah_current_channel;
- struct ath_common *common = ath5k_hw_common(ah);
- int clock;
-
- if (channel->hw_value & CHANNEL_5GHZ)
- clock = 40; /* 802.11a */
- else if (channel->hw_value & CHANNEL_CCK)
- clock = 22; /* 802.11b */
- else
- clock = 44; /* 802.11g */
-
- /* Clock rate in turbo modes is twice the normal rate */
- if (channel->hw_value & CHANNEL_TURBO)
- clock *= 2;
-
- common->clockrate = clock;
-}
-
-/**
- * ath5k_hw_get_default_slottime - Get the default slot time for current mode
- *
- * @ah: The &struct ath5k_hw
- */
-static unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah)
-{
- struct ieee80211_channel *channel = ah->ah_current_channel;
-
- if (channel->hw_value & CHANNEL_TURBO)
- return 6; /* both turbo modes */
-
- if (channel->hw_value & CHANNEL_CCK)
- return 20; /* 802.11b */
-
- return 9; /* 802.11 a/g */
-}
-
-/**
- * ath5k_hw_get_default_sifs - Get the default SIFS for current mode
- *
- * @ah: The &struct ath5k_hw
- */
-static unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah)
-{
- struct ieee80211_channel *channel = ah->ah_current_channel;
-
- if (channel->hw_value & CHANNEL_TURBO)
- return 8; /* both turbo modes */
- if (channel->hw_value & CHANNEL_5GHZ)
- return 16; /* 802.11a */
-
- return 10; /* 802.11 b/g */
-}
+/*******************\
+* RX filter Control *
+\*******************/
/**
* ath5k_hw_set_lladdr - Set station id
@@ -362,39 +412,6 @@ void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask)
ath_hw_setbssidmask(common);
}
-/************\
-* RX Control *
-\************/
-
-/**
- * ath5k_hw_start_rx_pcu - Start RX engine
- *
- * @ah: The &struct ath5k_hw
- *
- * Starts RX engine on PCU so that hw can process RXed frames
- * (ACK etc).
- *
- * NOTE: RX DMA should be already enabled using ath5k_hw_start_rx_dma
- */
-void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah)
-{
- AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
-}
-
-/**
- * at5k_hw_stop_rx_pcu - Stop RX engine
- *
- * @ah: The &struct ath5k_hw
- *
- * Stops RX engine on PCU
- *
- * TODO: Detach ANI here
- */
-void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah)
-{
- AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
-}
-
/*
* Set multicast filter
*/
@@ -746,7 +763,7 @@ ath5k_hw_check_beacon_timers(struct ath5k_hw *ah, int intval)
* @ah: The &struct ath5k_hw
* @coverage_class: IEEE 802.11 coverage class number
*
- * Sets slot time, ACK timeout and CTS timeout for given coverage class.
+ * Sets IFS intervals and ACK/CTS timeouts for given coverage class.
*/
void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class)
{
@@ -755,9 +772,175 @@ void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class)
int ack_timeout = ath5k_hw_get_default_sifs(ah) + slot_time;
int cts_timeout = ack_timeout;
- ath5k_hw_set_slot_time(ah, slot_time);
+ ath5k_hw_set_ifs_intervals(ah, slot_time);
ath5k_hw_set_ack_timeout(ah, ack_timeout);
ath5k_hw_set_cts_timeout(ah, cts_timeout);
ah->ah_coverage_class = coverage_class;
}
+
+/***************************\
+* Init/Start/Stop functions *
+\***************************/
+
+/**
+ * ath5k_hw_start_rx_pcu - Start RX engine
+ *
+ * @ah: The &struct ath5k_hw
+ *
+ * Starts RX engine on PCU so that hw can process RXed frames
+ * (ACK etc).
+ *
+ * NOTE: RX DMA should be already enabled using ath5k_hw_start_rx_dma
+ */
+void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah)
+{
+ AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
+}
+
+/**
+ * at5k_hw_stop_rx_pcu - Stop RX engine
+ *
+ * @ah: The &struct ath5k_hw
+ *
+ * Stops RX engine on PCU
+ */
+void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah)
+{
+ AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
+}
+
+/**
+ * ath5k_hw_set_opmode - Set PCU operating mode
+ *
+ * @ah: The &struct ath5k_hw
+ * @op_mode: &enum nl80211_iftype operating mode
+ *
+ * Configure PCU for the various operating modes (AP/STA etc)
+ */
+int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype op_mode)
+{
+ struct ath_common *common = ath5k_hw_common(ah);
+ u32 pcu_reg, beacon_reg, low_id, high_id;
+
+ ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_MODE, "mode %d\n", op_mode);
+
+ /* Preserve rest settings */
+ pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000;
+ pcu_reg &= ~(AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_AP
+ | AR5K_STA_ID1_KEYSRCH_MODE
+ | (ah->ah_version == AR5K_AR5210 ?
+ (AR5K_STA_ID1_PWR_SV | AR5K_STA_ID1_NO_PSPOLL) : 0));
+
+ beacon_reg = 0;
+
+ switch (op_mode) {
+ case NL80211_IFTYPE_ADHOC:
+ pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_KEYSRCH_MODE;
+ beacon_reg |= AR5K_BCR_ADHOC;
+ if (ah->ah_version == AR5K_AR5210)
+ pcu_reg |= AR5K_STA_ID1_NO_PSPOLL;
+ else
+ AR5K_REG_ENABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS);
+ break;
+
+ case NL80211_IFTYPE_AP:
+ case NL80211_IFTYPE_MESH_POINT:
+ pcu_reg |= AR5K_STA_ID1_AP | AR5K_STA_ID1_KEYSRCH_MODE;
+ beacon_reg |= AR5K_BCR_AP;
+ if (ah->ah_version == AR5K_AR5210)
+ pcu_reg |= AR5K_STA_ID1_NO_PSPOLL;
+ else
+ AR5K_REG_DISABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS);
+ break;
+
+ case NL80211_IFTYPE_STATION:
+ pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE
+ | (ah->ah_version == AR5K_AR5210 ?
+ AR5K_STA_ID1_PWR_SV : 0);
+ case NL80211_IFTYPE_MONITOR:
+ pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE
+ | (ah->ah_version == AR5K_AR5210 ?
+ AR5K_STA_ID1_NO_PSPOLL : 0);
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ /*
+ * Set PCU registers
+ */
+ low_id = get_unaligned_le32(common->macaddr);
+ high_id = get_unaligned_le16(common->macaddr + 4);
+ ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
+ ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1);
+
+ /*
+ * Set Beacon Control Register on 5210
+ */
+ if (ah->ah_version == AR5K_AR5210)
+ ath5k_hw_reg_write(ah, beacon_reg, AR5K_BCR);
+
+ return 0;
+}
+
+void ath5k_hw_pcu_init(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
+ u8 mode)
+{
+ /* Set bssid and bssid mask */
+ ath5k_hw_set_bssid(ah);
+
+ /* Set PCU config */
+ ath5k_hw_set_opmode(ah, op_mode);
+
+ /* Write rate duration table only on AR5212 and if
+ * virtual interface has already been brought up
+ * XXX: rethink this after new mode changes to
+ * mac80211 are integrated */
+ if (ah->ah_version == AR5K_AR5212 &&
+ ah->ah_sc->nvifs)
+ ath5k_hw_write_rate_duration(ah);
+
+ /* Set RSSI/BRSSI thresholds
+ *
+ * Note: If we decide to set this value
+ * dynamicaly, have in mind that when AR5K_RSSI_THR
+ * register is read it might return 0x40 if we haven't
+ * wrote anything to it plus BMISS RSSI threshold is zeroed.
+ * So doing a save/restore procedure here isn't the right
+ * choice. Instead store it on ath5k_hw */
+ ath5k_hw_reg_write(ah, (AR5K_TUNE_RSSI_THRES |
+ AR5K_TUNE_BMISS_THRES <<
+ AR5K_RSSI_THR_BMISS_S),
+ AR5K_RSSI_THR);
+
+ /* MIC QoS support */
+ if (ah->ah_mac_srev >= AR5K_SREV_AR2413) {
+ ath5k_hw_reg_write(ah, 0x000100aa, AR5K_MIC_QOS_CTL);
+ ath5k_hw_reg_write(ah, 0x00003210, AR5K_MIC_QOS_SEL);
+ }
+
+ /* QoS NOACK Policy */
+ if (ah->ah_version == AR5K_AR5212) {
+ ath5k_hw_reg_write(ah,
+ AR5K_REG_SM(2, AR5K_QOS_NOACK_2BIT_VALUES) |
+ AR5K_REG_SM(5, AR5K_QOS_NOACK_BIT_OFFSET) |
+ AR5K_REG_SM(0, AR5K_QOS_NOACK_BYTE_OFFSET),
+ AR5K_QOS_NOACK);
+ }
+
+ /* Restore slot time and ACK timeouts */
+ if (ah->ah_coverage_class > 0)
+ ath5k_hw_set_coverage_class(ah, ah->ah_coverage_class);
+
+ /* Set ACK bitrate mode (see ack_rates_high) */
+ if (ah->ah_version == AR5K_AR5212) {
+ u32 val = AR5K_STA_ID1_BASE_RATE_11B | AR5K_STA_ID1_ACKCTS_6MB;
+ if (ah->ah_ack_bitrate_high)
+ AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, val);
+ else
+ AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, val);
+ }
+ return;
+}
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
index 219367884e64..f84afb420bd8 100644
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -29,6 +29,95 @@
#include "rfbuffer.h"
#include "rfgain.h"
+
+/******************\
+* Helper functions *
+\******************/
+
+/*
+ * Get the PHY Chip revision
+ */
+u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan)
+{
+ unsigned int i;
+ u32 srev;
+ u16 ret;
+
+ /*
+ * Set the radio chip access register
+ */
+ switch (chan) {
+ case CHANNEL_2GHZ:
+ ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_2GHZ, AR5K_PHY(0));
+ break;
+ case CHANNEL_5GHZ:
+ ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
+ break;
+ default:
+ return 0;
+ }
+
+ mdelay(2);
+
+ /* ...wait until PHY is ready and read the selected radio revision */
+ ath5k_hw_reg_write(ah, 0x00001c16, AR5K_PHY(0x34));
+
+ for (i = 0; i < 8; i++)
+ ath5k_hw_reg_write(ah, 0x00010000, AR5K_PHY(0x20));
+
+ if (ah->ah_version == AR5K_AR5210) {
+ srev = ath5k_hw_reg_read(ah, AR5K_PHY(256) >> 28) & 0xf;
+ ret = (u16)ath5k_hw_bitswap(srev, 4) + 1;
+ } else {
+ srev = (ath5k_hw_reg_read(ah, AR5K_PHY(0x100)) >> 24) & 0xff;
+ ret = (u16)ath5k_hw_bitswap(((srev & 0xf0) >> 4) |
+ ((srev & 0x0f) << 4), 8);
+ }
+
+ /* Reset to the 5GHz mode */
+ ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
+
+ return ret;
+}
+
+/*
+ * Check if a channel is supported
+ */
+bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags)
+{
+ /* Check if the channel is in our supported range */
+ if (flags & CHANNEL_2GHZ) {
+ if ((freq >= ah->ah_capabilities.cap_range.range_2ghz_min) &&
+ (freq <= ah->ah_capabilities.cap_range.range_2ghz_max))
+ return true;
+ } else if (flags & CHANNEL_5GHZ)
+ if ((freq >= ah->ah_capabilities.cap_range.range_5ghz_min) &&
+ (freq <= ah->ah_capabilities.cap_range.range_5ghz_max))
+ return true;
+
+ return false;
+}
+
+bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
+ struct ieee80211_channel *channel)
+{
+ u8 refclk_freq;
+
+ if ((ah->ah_radio == AR5K_RF5112) ||
+ (ah->ah_radio == AR5K_RF5413) ||
+ (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
+ refclk_freq = 40;
+ else
+ refclk_freq = 32;
+
+ if ((channel->center_freq % refclk_freq != 0) &&
+ ((channel->center_freq % refclk_freq < 10) ||
+ (channel->center_freq % refclk_freq > 22)))
+ return true;
+ else
+ return false;
+}
+
/*
* Used to modify RF Banks before writing them to AR5K_RF_BUFFER
*/
@@ -110,6 +199,90 @@ static unsigned int ath5k_hw_rfb_op(struct ath5k_hw *ah,
return data;
}
+/**
+ * ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212
+ *
+ * @ah: the &struct ath5k_hw
+ * @channel: the currently set channel upon reset
+ *
+ * Write the delta slope coefficient (used on pilot tracking ?) for OFDM
+ * operation on the AR5212 upon reset. This is a helper for ath5k_hw_phy_init.
+ *
+ * Since delta slope is floating point we split it on its exponent and
+ * mantissa and provide these values on hw.
+ *
+ * For more infos i think this patent is related
+ * http://www.freepatentsonline.com/7184495.html
+ */
+static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
+ struct ieee80211_channel *channel)
+{
+ /* Get exponent and mantissa and set it */
+ u32 coef_scaled, coef_exp, coef_man,
+ ds_coef_exp, ds_coef_man, clock;
+
+ BUG_ON(!(ah->ah_version == AR5K_AR5212) ||
+ !(channel->hw_value & CHANNEL_OFDM));
+
+ /* Get coefficient
+ * ALGO: coef = (5 * clock / carrier_freq) / 2
+ * we scale coef by shifting clock value by 24 for
+ * better precision since we use integers */
+ switch (ah->ah_bwmode) {
+ case AR5K_BWMODE_40MHZ:
+ clock = 40 * 2;
+ break;
+ case AR5K_BWMODE_10MHZ:
+ clock = 40 / 2;
+ break;
+ case AR5K_BWMODE_5MHZ:
+ clock = 40 / 4;
+ break;
+ default:
+ clock = 40;
+ break;
+ }
+ coef_scaled = ((5 * (clock << 24)) / 2) / channel->center_freq;
+
+ /* Get exponent
+ * ALGO: coef_exp = 14 - highest set bit position */
+ coef_exp = ilog2(coef_scaled);
+
+ /* Doesn't make sense if it's zero*/
+ if (!coef_scaled || !coef_exp)
+ return -EINVAL;
+
+ /* Note: we've shifted coef_scaled by 24 */
+ coef_exp = 14 - (coef_exp - 24);
+
+
+ /* Get mantissa (significant digits)
+ * ALGO: coef_mant = floor(coef_scaled* 2^coef_exp+0.5) */
+ coef_man = coef_scaled +
+ (1 << (24 - coef_exp - 1));
+
+ /* Calculate delta slope coefficient exponent
+ * and mantissa (remove scaling) and set them on hw */
+ ds_coef_man = coef_man >> (24 - coef_exp);
+ ds_coef_exp = coef_exp - 16;
+
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
+ AR5K_PHY_TIMING_3_DSC_MAN, ds_coef_man);
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
+ AR5K_PHY_TIMING_3_DSC_EXP, ds_coef_exp);
+
+ return 0;
+}
+
+int ath5k_hw_phy_disable(struct ath5k_hw *ah)
+{
+ /*Just a try M.F.*/
+ ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
+
+ return 0;
+}
+
+
/**********************\
* RF Gain optimization *
\**********************/
@@ -436,7 +609,7 @@ done:
/* Write initial RF gain table to set the RF sensitivity
* this one works on all RF chips and has nothing to do
* with gain_F calibration */
-int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq)
+static int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq)
{
const struct ath5k_ini_rfgain *ath5k_rfg;
unsigned int i, size;
@@ -494,12 +667,11 @@ int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq)
* RF Registers setup *
\********************/
-
/*
* Setup RF registers by writing RF buffer on hw
*/
-int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
- unsigned int mode)
+static int ath5k_hw_rfregs_init(struct ath5k_hw *ah,
+ struct ieee80211_channel *channel, unsigned int mode)
{
const struct ath5k_rf_reg *rf_regs;
const struct ath5k_ini_rfbuffer *ini_rfb;
@@ -652,6 +824,11 @@ int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
g_step = &go->go_step[ah->ah_gain.g_step_idx];
+ /* Set turbo mode (N/A on RF5413) */
+ if ((ah->ah_bwmode == AR5K_BWMODE_40MHZ) &&
+ (ah->ah_radio != AR5K_RF5413))
+ ath5k_hw_rfb_op(ah, rf_regs, 1, AR5K_RF_TURBO, false);
+
/* Bank Modifications (chip-specific) */
if (ah->ah_radio == AR5K_RF5111) {
@@ -691,7 +868,23 @@ int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
ath5k_hw_rfb_op(ah, rf_regs, ee->ee_xpd[ee_mode],
AR5K_RF_PLO_SEL, true);
- /* TODO: Half/quarter channel support */
+ /* Tweak power detectors for half/quarter rate support */
+ if (ah->ah_bwmode == AR5K_BWMODE_5MHZ ||
+ ah->ah_bwmode == AR5K_BWMODE_10MHZ) {
+ u8 wait_i;
+
+ ath5k_hw_rfb_op(ah, rf_regs, 0x1f,
+ AR5K_RF_WAIT_S, true);
+
+ wait_i = (ah->ah_bwmode == AR5K_BWMODE_5MHZ) ?
+ 0x1f : 0x10;
+
+ ath5k_hw_rfb_op(ah, rf_regs, wait_i,
+ AR5K_RF_WAIT_I, true);
+ ath5k_hw_rfb_op(ah, rf_regs, 3,
+ AR5K_RF_MAX_TIME, true);
+
+ }
}
if (ah->ah_radio == AR5K_RF5112) {
@@ -789,8 +982,20 @@ int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
ath5k_hw_rfb_op(ah, rf_regs, ee->ee_i_gain[ee_mode],
AR5K_RF_GAIN_I, true);
- /* TODO: Half/quarter channel support */
+ /* Tweak power detector for half/quarter rates */
+ if (ah->ah_bwmode == AR5K_BWMODE_5MHZ ||
+ ah->ah_bwmode == AR5K_BWMODE_10MHZ) {
+ u8 pd_delay;
+
+ pd_delay = (ah->ah_bwmode == AR5K_BWMODE_5MHZ) ?
+ 0xf : 0x8;
+
+ ath5k_hw_rfb_op(ah, rf_regs, pd_delay,
+ AR5K_RF_PD_PERIOD_A, true);
+ ath5k_hw_rfb_op(ah, rf_regs, 0xf,
+ AR5K_RF_PD_DELAY_A, true);
+ }
}
if (ah->ah_radio == AR5K_RF5413 &&
@@ -822,24 +1027,6 @@ int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
\**************************/
/*
- * Check if a channel is supported
- */
-bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags)
-{
- /* Check if the channel is in our supported range */
- if (flags & CHANNEL_2GHZ) {
- if ((freq >= ah->ah_capabilities.cap_range.range_2ghz_min) &&
- (freq <= ah->ah_capabilities.cap_range.range_2ghz_max))
- return true;
- } else if (flags & CHANNEL_5GHZ)
- if ((freq >= ah->ah_capabilities.cap_range.range_5ghz_min) &&
- (freq <= ah->ah_capabilities.cap_range.range_5ghz_max))
- return true;
-
- return false;
-}
-
-/*
* Convertion needed for RF5110
*/
static u32 ath5k_hw_rf5110_chan2athchan(struct ieee80211_channel *channel)
@@ -1045,7 +1232,8 @@ static int ath5k_hw_rf2425_channel(struct ath5k_hw *ah,
/*
* Set a channel on the radio chip
*/
-int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel)
+static int ath5k_hw_channel(struct ath5k_hw *ah,
+ struct ieee80211_channel *channel)
{
int ret;
/*
@@ -1092,8 +1280,6 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel)
}
ah->ah_current_channel = channel;
- ah->ah_turbo = channel->hw_value == CHANNEL_T ? true : false;
- ath5k_hw_set_clockrate(ah);
return 0;
}
@@ -1102,18 +1288,12 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel)
PHY calibration
\*****************/
-static int sign_extend(int val, const int nbits)
-{
- int order = BIT(nbits-1);
- return (val ^ order) - order;
-}
-
static s32 ath5k_hw_read_measured_noise_floor(struct ath5k_hw *ah)
{
s32 val;
val = ath5k_hw_reg_read(ah, AR5K_PHY_NF);
- return sign_extend(AR5K_REG_MS(val, AR5K_PHY_NF_MINCCA_PWR), 9);
+ return sign_extend32(AR5K_REG_MS(val, AR5K_PHY_NF_MINCCA_PWR), 8);
}
void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah)
@@ -1183,12 +1363,10 @@ void ath5k_hw_update_noise_floor(struct ath5k_hw *ah)
switch (ah->ah_current_channel->hw_value & CHANNEL_MODES) {
case CHANNEL_A:
- case CHANNEL_T:
case CHANNEL_XR:
ee_mode = AR5K_EEPROM_MODE_11A;
break;
case CHANNEL_G:
- case CHANNEL_TG:
ee_mode = AR5K_EEPROM_MODE_11G;
break;
default:
@@ -1425,31 +1603,12 @@ int ath5k_hw_phy_calibrate(struct ath5k_hw *ah,
return ret;
}
+
/***************************\
* Spur mitigation functions *
\***************************/
-bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
- struct ieee80211_channel *channel)
-{
- u8 refclk_freq;
-
- if ((ah->ah_radio == AR5K_RF5112) ||
- (ah->ah_radio == AR5K_RF5413) ||
- (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
- refclk_freq = 40;
- else
- refclk_freq = 32;
-
- if ((channel->center_freq % refclk_freq != 0) &&
- ((channel->center_freq % refclk_freq < 10) ||
- (channel->center_freq % refclk_freq > 22)))
- return true;
- else
- return false;
-}
-
-void
+static void
ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
struct ieee80211_channel *channel)
{
@@ -1478,7 +1637,7 @@ ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
spur_chan_fbin = AR5K_EEPROM_NO_SPUR;
spur_detection_window = AR5K_SPUR_CHAN_WIDTH;
/* XXX: Half/Quarter channels ?*/
- if (channel->hw_value & CHANNEL_TURBO)
+ if (ah->ah_bwmode == AR5K_BWMODE_40MHZ)
spur_detection_window *= 2;
for (i = 0; i < AR5K_EEPROM_N_SPUR_CHANS; i++) {
@@ -1507,32 +1666,43 @@ ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
* Calculate deltas:
* spur_freq_sigma_delta -> spur_offset / sample_freq << 21
* spur_delta_phase -> spur_offset / chip_freq << 11
- * Note: Both values have 100KHz resolution
+ * Note: Both values have 100Hz resolution
*/
- /* XXX: Half/Quarter rate channels ? */
- switch (channel->hw_value) {
- case CHANNEL_A:
- /* Both sample_freq and chip_freq are 40MHz */
- spur_delta_phase = (spur_offset << 17) / 25;
- spur_freq_sigma_delta = (spur_delta_phase >> 10);
- symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz;
- break;
- case CHANNEL_G:
- /* sample_freq -> 40MHz chip_freq -> 44MHz
- * (for b compatibility) */
- spur_freq_sigma_delta = (spur_offset << 8) / 55;
- spur_delta_phase = (spur_offset << 17) / 25;
- symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz;
- break;
- case CHANNEL_T:
- case CHANNEL_TG:
+ switch (ah->ah_bwmode) {
+ case AR5K_BWMODE_40MHZ:
/* Both sample_freq and chip_freq are 80MHz */
spur_delta_phase = (spur_offset << 16) / 25;
spur_freq_sigma_delta = (spur_delta_phase >> 10);
- symbol_width = AR5K_SPUR_SYMBOL_WIDTH_TURBO_100Hz;
+ symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz * 2;
break;
+ case AR5K_BWMODE_10MHZ:
+ /* Both sample_freq and chip_freq are 20MHz (?) */
+ spur_delta_phase = (spur_offset << 18) / 25;
+ spur_freq_sigma_delta = (spur_delta_phase >> 10);
+ symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz / 2;
+ case AR5K_BWMODE_5MHZ:
+ /* Both sample_freq and chip_freq are 10MHz (?) */
+ spur_delta_phase = (spur_offset << 19) / 25;
+ spur_freq_sigma_delta = (spur_delta_phase >> 10);
+ symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz / 4;
default:
- return;
+ if (channel->hw_value == CHANNEL_A) {
+ /* Both sample_freq and chip_freq are 40MHz */
+ spur_delta_phase = (spur_offset << 17) / 25;
+ spur_freq_sigma_delta =
+ (spur_delta_phase >> 10);
+ symbol_width =
+ AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz;
+ } else {
+ /* sample_freq -> 40MHz chip_freq -> 44MHz
+ * (for b compatibility) */
+ spur_delta_phase = (spur_offset << 17) / 25;
+ spur_freq_sigma_delta =
+ (spur_offset << 8) / 55;
+ symbol_width =
+ AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz;
+ }
+ break;
}
/* Calculate pilot and magnitude masks */
@@ -1672,63 +1842,6 @@ ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
}
}
-/********************\
- Misc PHY functions
-\********************/
-
-int ath5k_hw_phy_disable(struct ath5k_hw *ah)
-{
- /*Just a try M.F.*/
- ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
-
- return 0;
-}
-
-/*
- * Get the PHY Chip revision
- */
-u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan)
-{
- unsigned int i;
- u32 srev;
- u16 ret;
-
- /*
- * Set the radio chip access register
- */
- switch (chan) {
- case CHANNEL_2GHZ:
- ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_2GHZ, AR5K_PHY(0));
- break;
- case CHANNEL_5GHZ:
- ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
- break;
- default:
- return 0;
- }
-
- mdelay(2);
-
- /* ...wait until PHY is ready and read the selected radio revision */
- ath5k_hw_reg_write(ah, 0x00001c16, AR5K_PHY(0x34));
-
- for (i = 0; i < 8; i++)
- ath5k_hw_reg_write(ah, 0x00010000, AR5K_PHY(0x20));
-
- if (ah->ah_version == AR5K_AR5210) {
- srev = ath5k_hw_reg_read(ah, AR5K_PHY(256) >> 28) & 0xf;
- ret = (u16)ath5k_hw_bitswap(srev, 4) + 1;
- } else {
- srev = (ath5k_hw_reg_read(ah, AR5K_PHY(0x100)) >> 24) & 0xff;
- ret = (u16)ath5k_hw_bitswap(((srev & 0xf0) >> 4) |
- ((srev & 0x0f) << 4), 8);
- }
-
- /* Reset to the 5GHz mode */
- ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
-
- return ret;
-}
/*****************\
* Antenna control *
@@ -1836,12 +1949,10 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode)
switch (channel->hw_value & CHANNEL_MODES) {
case CHANNEL_A:
- case CHANNEL_T:
case CHANNEL_XR:
ee_mode = AR5K_EEPROM_MODE_11A;
break;
case CHANNEL_G:
- case CHANNEL_TG:
ee_mode = AR5K_EEPROM_MODE_11G;
break;
case CHANNEL_B:
@@ -2275,20 +2386,20 @@ ath5k_get_max_ctl_power(struct ath5k_hw *ah,
switch (channel->hw_value & CHANNEL_MODES) {
case CHANNEL_A:
- ctl_mode |= AR5K_CTL_11A;
+ if (ah->ah_bwmode == AR5K_BWMODE_40MHZ)
+ ctl_mode |= AR5K_CTL_TURBO;
+ else
+ ctl_mode |= AR5K_CTL_11A;
break;
case CHANNEL_G:
- ctl_mode |= AR5K_CTL_11G;
+ if (ah->ah_bwmode == AR5K_BWMODE_40MHZ)
+ ctl_mode |= AR5K_CTL_TURBOG;
+ else
+ ctl_mode |= AR5K_CTL_11G;
break;
case CHANNEL_B:
ctl_mode |= AR5K_CTL_11B;
break;
- case CHANNEL_T:
- ctl_mode |= AR5K_CTL_TURBO;
- break;
- case CHANNEL_TG:
- ctl_mode |= AR5K_CTL_TURBOG;
- break;
case CHANNEL_XR:
/* Fall through */
default:
@@ -2631,10 +2742,12 @@ ath5k_combine_pwr_to_pdadc_curves(struct ath5k_hw *ah,
/* Write PDADC values on hw */
static void
-ath5k_setup_pwr_to_pdadc_table(struct ath5k_hw *ah,
- u8 pdcurves, u8 *pdg_to_idx)
+ath5k_setup_pwr_to_pdadc_table(struct ath5k_hw *ah, u8 ee_mode)
{
+ struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
u8 *pdadc_out = ah->ah_txpower.txp_pd_table;
+ u8 *pdg_to_idx = ee->ee_pdc_to_idx[ee_mode];
+ u8 pdcurves = ee->ee_pd_gains[ee_mode];
u32 reg;
u8 i;
@@ -2881,7 +2994,7 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah,
ee->ee_pd_gains[ee_mode]);
/* Write settings on hw */
- ath5k_setup_pwr_to_pdadc_table(ah, pdg, pdg_curve_to_idx);
+ ath5k_setup_pwr_to_pdadc_table(ah, ee_mode);
/* Set txp.offset, note that table_min
* can be negative */
@@ -2990,9 +3103,9 @@ ath5k_setup_rate_powertable(struct ath5k_hw *ah, u16 max_pwr,
/*
* Set transmission power
*/
-int
+static int
ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
- u8 ee_mode, u8 txpower)
+ u8 ee_mode, u8 txpower, bool fast)
{
struct ath5k_rate_pcal_info rate_info;
u8 type;
@@ -3003,14 +3116,11 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
return -EINVAL;
}
- /* Reset TX power values */
- memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower));
- ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
- ah->ah_txpower.txp_min_pwr = 0;
- ah->ah_txpower.txp_max_pwr = AR5K_TUNE_MAX_TXPOWER;
-
/* Initialize TX power table */
switch (ah->ah_radio) {
+ case AR5K_RF5110:
+ /* TODO */
+ return 0;
case AR5K_RF5111:
type = AR5K_PWRTABLE_PWR_TO_PCDAC;
break;
@@ -3028,10 +3138,28 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
return -EINVAL;
}
- /* FIXME: Only on channel/mode change */
- ret = ath5k_setup_channel_powertable(ah, channel, ee_mode, type);
- if (ret)
- return ret;
+ /* If fast is set it means we are on the same channel/mode
+ * so there is no need to recalculate the powertable, we 'll
+ * just use the cached one */
+ if (!fast) {
+ /* Reset TX power values */
+ memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower));
+ ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
+ ah->ah_txpower.txp_min_pwr = 0;
+ ah->ah_txpower.txp_max_pwr = AR5K_TUNE_MAX_TXPOWER;
+
+ /* Calculate the powertable */
+ ret = ath5k_setup_channel_powertable(ah, channel,
+ ee_mode, type);
+ if (ret)
+ return ret;
+ /* Write cached table on hw */
+ } else if (type == AR5K_PWRTABLE_PWR_TO_PDADC)
+ ath5k_setup_pwr_to_pdadc_table(ah, ee_mode);
+ else
+ ath5k_setup_pcdac_table(ah);
+
+
/* Limit max power if we have a CTL available */
ath5k_get_max_ctl_power(ah, channel);
@@ -3092,12 +3220,10 @@ int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower)
switch (channel->hw_value & CHANNEL_MODES) {
case CHANNEL_A:
- case CHANNEL_T:
case CHANNEL_XR:
ee_mode = AR5K_EEPROM_MODE_11A;
break;
case CHANNEL_G:
- case CHANNEL_TG:
ee_mode = AR5K_EEPROM_MODE_11G;
break;
case CHANNEL_B:
@@ -3112,5 +3238,229 @@ int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower)
ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_TXPOWER,
"changing txpower to %d\n", txpower);
- return ath5k_hw_txpower(ah, channel, ee_mode, txpower);
+ return ath5k_hw_txpower(ah, channel, ee_mode, txpower, true);
+}
+
+/*************\
+ Init function
+\*************/
+
+int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
+ u8 mode, u8 ee_mode, u8 freq, bool fast)
+{
+ struct ieee80211_channel *curr_channel;
+ int ret, i;
+ u32 phy_tst1;
+ bool fast_txp;
+ ret = 0;
+
+ /*
+ * Sanity check for fast flag
+ * Don't try fast channel change when changing modulation
+ * mode/band. We check for chip compatibility on
+ * ath5k_hw_reset.
+ */
+ curr_channel = ah->ah_current_channel;
+ if (fast && (channel->hw_value != curr_channel->hw_value))
+ return -EINVAL;
+
+ /*
+ * On fast channel change we only set the synth parameters
+ * while PHY is running, enable calibration and skip the rest.
+ */
+ if (fast) {
+ AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_RFBUS_REQ,
+ AR5K_PHY_RFBUS_REQ_REQUEST);
+ for (i = 0; i < 100; i++) {
+ if (ath5k_hw_reg_read(ah, AR5K_PHY_RFBUS_GRANT))
+ break;
+ udelay(5);
+ }
+ /* Failed */
+ if (i >= 100)
+ return -EIO;
+ }
+
+ /*
+ * If we don't change channel/mode skip
+ * tx powertable calculation and use the
+ * cached one.
+ */
+ if ((channel->hw_value == curr_channel->hw_value) &&
+ (channel->center_freq == curr_channel->center_freq))
+ fast_txp = true;
+ else
+ fast_txp = false;
+
+ /*
+ * Set TX power
+ *
+ * Note: We need to do that before we set
+ * RF buffer settings on 5211/5212+ so that we
+ * properly set curve indices.
+ */
+ ret = ath5k_hw_txpower(ah, channel, ee_mode,
+ ah->ah_txpower.txp_max_pwr / 2,
+ fast_txp);
+ if (ret)
+ return ret;
+
+ /*
+ * For 5210 we do all initialization using
+ * initvals, so we don't have to modify
+ * any settings (5210 also only supports
+ * a/aturbo modes)
+ */
+ if ((ah->ah_version != AR5K_AR5210) && !fast) {
+
+ /*
+ * Write initial RF gain settings
+ * This should work for both 5111/5112
+ */
+ ret = ath5k_hw_rfgain_init(ah, freq);
+ if (ret)
+ return ret;
+
+ mdelay(1);
+
+ /*
+ * Write RF buffer
+ */
+ ret = ath5k_hw_rfregs_init(ah, channel, mode);
+ if (ret)
+ return ret;
+
+ /* Write OFDM timings on 5212*/
+ if (ah->ah_version == AR5K_AR5212 &&
+ channel->hw_value & CHANNEL_OFDM) {
+
+ ret = ath5k_hw_write_ofdm_timings(ah, channel);
+ if (ret)
+ return ret;
+
+ /* Spur info is available only from EEPROM versions
+ * greater than 5.3, but the EEPROM routines will use
+ * static values for older versions */
+ if (ah->ah_mac_srev >= AR5K_SREV_AR5424)
+ ath5k_hw_set_spur_mitigation_filter(ah,
+ channel);
+ }
+
+ /*Enable/disable 802.11b mode on 5111
+ (enable 2111 frequency converter + CCK)*/
+ if (ah->ah_radio == AR5K_RF5111) {
+ if (mode == AR5K_MODE_11B)
+ AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG,
+ AR5K_TXCFG_B_MODE);
+ else
+ AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG,
+ AR5K_TXCFG_B_MODE);
+ }
+
+ } else if (ah->ah_version == AR5K_AR5210) {
+ mdelay(1);
+ /* Disable phy and wait */
+ ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
+ mdelay(1);
+ }
+
+ /* Set channel on PHY */
+ ret = ath5k_hw_channel(ah, channel);
+ if (ret)
+ return ret;
+
+ /*
+ * Enable the PHY and wait until completion
+ * This includes BaseBand and Synthesizer
+ * activation.
+ */
+ ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT);
+
+ /*
+ * On 5211+ read activation -> rx delay
+ * and use it.
+ */
+ if (ah->ah_version != AR5K_AR5210) {
+ u32 delay;
+ delay = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) &
+ AR5K_PHY_RX_DELAY_M;
+ delay = (channel->hw_value & CHANNEL_CCK) ?
+ ((delay << 2) / 22) : (delay / 10);
+ if (ah->ah_bwmode == AR5K_BWMODE_10MHZ)
+ delay = delay << 1;
+ if (ah->ah_bwmode == AR5K_BWMODE_5MHZ)
+ delay = delay << 2;
+ /* XXX: /2 on turbo ? Let's be safe
+ * for now */
+ udelay(100 + delay);
+ } else {
+ mdelay(1);
+ }
+
+ if (fast)
+ /*
+ * Release RF Bus grant
+ */
+ AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_RFBUS_REQ,
+ AR5K_PHY_RFBUS_REQ_REQUEST);
+ else {
+ /*
+ * Perform ADC test to see if baseband is ready
+ * Set tx hold and check adc test register
+ */
+ phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1);
+ ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1);
+ for (i = 0; i <= 20; i++) {
+ if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10))
+ break;
+ udelay(200);
+ }
+ ath5k_hw_reg_write(ah, phy_tst1, AR5K_PHY_TST1);
+ }
+
+ /*
+ * Start automatic gain control calibration
+ *
+ * During AGC calibration RX path is re-routed to
+ * a power detector so we don't receive anything.
+ *
+ * This method is used to calibrate some static offsets
+ * used together with on-the fly I/Q calibration (the
+ * one performed via ath5k_hw_phy_calibrate), which doesn't
+ * interrupt rx path.
+ *
+ * While rx path is re-routed to the power detector we also
+ * start a noise floor calibration to measure the
+ * card's noise floor (the noise we measure when we are not
+ * transmitting or receiving anything).
+ *
+ * If we are in a noisy environment, AGC calibration may time
+ * out and/or noise floor calibration might timeout.
+ */
+ AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
+ AR5K_PHY_AGCCTL_CAL | AR5K_PHY_AGCCTL_NF);
+
+ /* At the same time start I/Q calibration for QAM constellation
+ * -no need for CCK- */
+ ah->ah_calibration = false;
+ if (!(mode == AR5K_MODE_11B)) {
+ ah->ah_calibration = true;
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ,
+ AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15);
+ AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
+ AR5K_PHY_IQ_RUN);
+ }
+
+ /* Wait for gain calibration to finish (we check for I/Q calibration
+ * during ath5k_phy_calibrate) */
+ if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
+ AR5K_PHY_AGCCTL_CAL, 0, false)) {
+ ATH5K_ERR(ah->ah_sc, "gain calibration timeout (%uMHz)\n",
+ channel->center_freq);
+ }
+
+ /* Restore antenna mode */
+ ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode);
+
+ return ret;
}
diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c
index 84c717ded1c5..2c9c9e793d4e 100644
--- a/drivers/net/wireless/ath/ath5k/qcu.c
+++ b/drivers/net/wireless/ath/ath5k/qcu.c
@@ -25,14 +25,52 @@ Queue Control Unit, DFS Control Unit Functions
#include "debug.h"
#include "base.h"
+
+/******************\
+* Helper functions *
+\******************/
+
/*
- * Get properties for a transmit queue
+ * Get number of pending frames
+ * for a specific queue [5211+]
*/
-int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue,
- struct ath5k_txq_info *queue_info)
+u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue)
{
- memcpy(queue_info, &ah->ah_txq[queue], sizeof(struct ath5k_txq_info));
- return 0;
+ u32 pending;
+ AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
+
+ /* Return if queue is declared inactive */
+ if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
+ return false;
+
+ /* XXX: How about AR5K_CFG_TXCNT ? */
+ if (ah->ah_version == AR5K_AR5210)
+ return false;
+
+ pending = ath5k_hw_reg_read(ah, AR5K_QUEUE_STATUS(queue));
+ pending &= AR5K_QCU_STS_FRMPENDCNT;
+
+ /* It's possible to have no frames pending even if TXE
+ * is set. To indicate that q has not stopped return
+ * true */
+ if (!pending && AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue))
+ return true;
+
+ return pending;
+}
+
+/*
+ * Set a transmit queue inactive
+ */
+void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue)
+{
+ if (WARN_ON(queue >= ah->ah_capabilities.cap_queues.q_tx_num))
+ return;
+
+ /* This queue will be skipped in further operations */
+ ah->ah_txq[queue].tqi_type = AR5K_TX_QUEUE_INACTIVE;
+ /*For SIMR setup*/
+ AR5K_Q_DISABLE_BITS(ah->ah_txq_status, queue);
}
/*
@@ -50,6 +88,16 @@ static u16 ath5k_cw_validate(u16 cw_req)
}
/*
+ * Get properties for a transmit queue
+ */
+int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue,
+ struct ath5k_txq_info *queue_info)
+{
+ memcpy(queue_info, &ah->ah_txq[queue], sizeof(struct ath5k_txq_info));
+ return 0;
+}
+
+/*
* Set properties for a transmit queue
*/
int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue,
@@ -104,8 +152,8 @@ int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type,
/*
* Get queue by type
*/
- /*5210 only has 2 queues*/
- if (ah->ah_version == AR5K_AR5210) {
+ /* 5210 only has 2 queues */
+ if (ah->ah_capabilities.cap_queues.q_tx_num == 2) {
switch (queue_type) {
case AR5K_TX_QUEUE_DATA:
queue = AR5K_TX_QUEUE_ID_NOQCU_DATA;
@@ -172,113 +220,18 @@ int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type,
return queue;
}
-/*
- * Get number of pending frames
- * for a specific queue [5211+]
- */
-u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue)
-{
- u32 pending;
- AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
-
- /* Return if queue is declared inactive */
- if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
- return false;
-
- /* XXX: How about AR5K_CFG_TXCNT ? */
- if (ah->ah_version == AR5K_AR5210)
- return false;
-
- pending = ath5k_hw_reg_read(ah, AR5K_QUEUE_STATUS(queue));
- pending &= AR5K_QCU_STS_FRMPENDCNT;
-
- /* It's possible to have no frames pending even if TXE
- * is set. To indicate that q has not stopped return
- * true */
- if (!pending && AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue))
- return true;
-
- return pending;
-}
-
-/*
- * Set a transmit queue inactive
- */
-void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue)
-{
- if (WARN_ON(queue >= ah->ah_capabilities.cap_queues.q_tx_num))
- return;
- /* This queue will be skipped in further operations */
- ah->ah_txq[queue].tqi_type = AR5K_TX_QUEUE_INACTIVE;
- /*For SIMR setup*/
- AR5K_Q_DISABLE_BITS(ah->ah_txq_status, queue);
-}
+/*******************************\
+* Single QCU/DCU initialization *
+\*******************************/
/*
- * Set DFS properties for a transmit queue on DCU
+ * Set tx retry limits on DCU
*/
-int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
+static void ath5k_hw_set_tx_retry_limits(struct ath5k_hw *ah,
+ unsigned int queue)
{
u32 retry_lg, retry_sh;
- struct ath5k_txq_info *tq = &ah->ah_txq[queue];
-
- AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
-
- tq = &ah->ah_txq[queue];
-
- if (tq->tqi_type == AR5K_TX_QUEUE_INACTIVE)
- return 0;
-
- if (ah->ah_version == AR5K_AR5210) {
- /* Only handle data queues, others will be ignored */
- if (tq->tqi_type != AR5K_TX_QUEUE_DATA)
- return 0;
-
- /* Set Slot time */
- ath5k_hw_reg_write(ah, ah->ah_turbo ?
- AR5K_INIT_SLOT_TIME_TURBO : AR5K_INIT_SLOT_TIME,
- AR5K_SLOT_TIME);
- /* Set ACK_CTS timeout */
- ath5k_hw_reg_write(ah, ah->ah_turbo ?
- AR5K_INIT_ACK_CTS_TIMEOUT_TURBO :
- AR5K_INIT_ACK_CTS_TIMEOUT, AR5K_SLOT_TIME);
- /* Set Transmit Latency */
- ath5k_hw_reg_write(ah, ah->ah_turbo ?
- AR5K_INIT_TRANSMIT_LATENCY_TURBO :
- AR5K_INIT_TRANSMIT_LATENCY, AR5K_USEC_5210);
-
- /* Set IFS0 */
- if (ah->ah_turbo) {
- ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS_TURBO +
- tq->tqi_aifs * AR5K_INIT_SLOT_TIME_TURBO) <<
- AR5K_IFS0_DIFS_S) | AR5K_INIT_SIFS_TURBO,
- AR5K_IFS0);
- } else {
- ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS +
- tq->tqi_aifs * AR5K_INIT_SLOT_TIME) <<
- AR5K_IFS0_DIFS_S) |
- AR5K_INIT_SIFS, AR5K_IFS0);
- }
-
- /* Set IFS1 */
- ath5k_hw_reg_write(ah, ah->ah_turbo ?
- AR5K_INIT_PROTO_TIME_CNTRL_TURBO :
- AR5K_INIT_PROTO_TIME_CNTRL, AR5K_IFS1);
- /* Set AR5K_PHY_SETTLING */
- ath5k_hw_reg_write(ah, ah->ah_turbo ?
- (ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F)
- | 0x38 :
- (ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F)
- | 0x1C,
- AR5K_PHY_SETTLING);
- /* Set Frame Control Register */
- ath5k_hw_reg_write(ah, ah->ah_turbo ?
- (AR5K_PHY_FRAME_CTL_INI | AR5K_PHY_TURBO_MODE |
- AR5K_PHY_TURBO_SHORT | 0x2020) :
- (AR5K_PHY_FRAME_CTL_INI | 0x1020),
- AR5K_PHY_FRAME_CTL_5210);
- }
/*
* Calculate and set retry limits
@@ -293,8 +246,13 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
retry_sh = AR5K_INIT_SH_RETRY;
}
- /*No QCU/DCU [5210]*/
+ /* Single data queue on AR5210 */
if (ah->ah_version == AR5K_AR5210) {
+ struct ath5k_txq_info *tq = &ah->ah_txq[queue];
+
+ if (queue > 0)
+ return;
+
ath5k_hw_reg_write(ah,
(tq->tqi_cw_min << AR5K_NODCU_RETRY_LMT_CW_MIN_S)
| AR5K_REG_SM(AR5K_INIT_SLG_RETRY,
@@ -304,8 +262,8 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
| AR5K_REG_SM(retry_lg, AR5K_NODCU_RETRY_LMT_LG_RETRY)
| AR5K_REG_SM(retry_sh, AR5K_NODCU_RETRY_LMT_SH_RETRY),
AR5K_NODCU_RETRY_LMT);
+ /* DCU on AR5211+ */
} else {
- /*QCU/DCU [5211+]*/
ath5k_hw_reg_write(ah,
AR5K_REG_SM(AR5K_INIT_SLG_RETRY,
AR5K_DCU_RETRY_LMT_SLG_RETRY) |
@@ -314,219 +272,393 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
AR5K_REG_SM(retry_lg, AR5K_DCU_RETRY_LMT_LG_RETRY) |
AR5K_REG_SM(retry_sh, AR5K_DCU_RETRY_LMT_SH_RETRY),
AR5K_QUEUE_DFS_RETRY_LIMIT(queue));
+ }
+ return;
+}
- /*===Rest is also for QCU/DCU only [5211+]===*/
+/**
+ * ath5k_hw_reset_tx_queue - Initialize a single hw queue
+ *
+ * @ah The &struct ath5k_hw
+ * @queue The hw queue number
+ *
+ * Set DFS properties for the given transmit queue on DCU
+ * and configures all queue-specific parameters.
+ */
+int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
+{
+ struct ath5k_txq_info *tq = &ah->ah_txq[queue];
- /*
- * Set contention window (cw_min/cw_max)
- * and arbitrated interframe space (aifs)...
- */
- ath5k_hw_reg_write(ah,
- AR5K_REG_SM(tq->tqi_cw_min, AR5K_DCU_LCL_IFS_CW_MIN) |
- AR5K_REG_SM(tq->tqi_cw_max, AR5K_DCU_LCL_IFS_CW_MAX) |
- AR5K_REG_SM(tq->tqi_aifs, AR5K_DCU_LCL_IFS_AIFS),
- AR5K_QUEUE_DFS_LOCAL_IFS(queue));
-
- /*
- * Set misc registers
- */
- /* Enable DCU early termination for this queue */
- AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
- AR5K_QCU_MISC_DCU_EARLY);
+ AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
+
+ tq = &ah->ah_txq[queue];
+
+ /* Skip if queue inactive or if we are on AR5210
+ * that doesn't have QCU/DCU */
+ if ((ah->ah_version == AR5K_AR5210) ||
+ (tq->tqi_type == AR5K_TX_QUEUE_INACTIVE))
+ return 0;
+
+ /*
+ * Set contention window (cw_min/cw_max)
+ * and arbitrated interframe space (aifs)...
+ */
+ ath5k_hw_reg_write(ah,
+ AR5K_REG_SM(tq->tqi_cw_min, AR5K_DCU_LCL_IFS_CW_MIN) |
+ AR5K_REG_SM(tq->tqi_cw_max, AR5K_DCU_LCL_IFS_CW_MAX) |
+ AR5K_REG_SM(tq->tqi_aifs, AR5K_DCU_LCL_IFS_AIFS),
+ AR5K_QUEUE_DFS_LOCAL_IFS(queue));
+
+ /*
+ * Set tx retry limits for this queue
+ */
+ ath5k_hw_set_tx_retry_limits(ah, queue);
+
+
+ /*
+ * Set misc registers
+ */
+
+ /* Enable DCU to wait for next fragment from QCU */
+ AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
+ AR5K_DCU_MISC_FRAG_WAIT);
- /* Enable DCU to wait for next fragment from QCU */
+ /* On Maui and Spirit use the global seqnum on DCU */
+ if (ah->ah_mac_version < AR5K_SREV_AR5211)
AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
- AR5K_DCU_MISC_FRAG_WAIT);
-
- /* On Maui and Spirit use the global seqnum on DCU */
- if (ah->ah_mac_version < AR5K_SREV_AR5211)
- AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
- AR5K_DCU_MISC_SEQNUM_CTL);
-
- if (tq->tqi_cbr_period) {
- ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_cbr_period,
- AR5K_QCU_CBRCFG_INTVAL) |
- AR5K_REG_SM(tq->tqi_cbr_overflow_limit,
- AR5K_QCU_CBRCFG_ORN_THRES),
- AR5K_QUEUE_CBRCFG(queue));
+ AR5K_DCU_MISC_SEQNUM_CTL);
+
+ /* Constant bit rate period */
+ if (tq->tqi_cbr_period) {
+ ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_cbr_period,
+ AR5K_QCU_CBRCFG_INTVAL) |
+ AR5K_REG_SM(tq->tqi_cbr_overflow_limit,
+ AR5K_QCU_CBRCFG_ORN_THRES),
+ AR5K_QUEUE_CBRCFG(queue));
+
+ AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
+ AR5K_QCU_MISC_FRSHED_CBR);
+
+ if (tq->tqi_cbr_overflow_limit)
AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
- AR5K_QCU_MISC_FRSHED_CBR);
- if (tq->tqi_cbr_overflow_limit)
- AR5K_REG_ENABLE_BITS(ah,
- AR5K_QUEUE_MISC(queue),
AR5K_QCU_MISC_CBR_THRES_ENABLE);
- }
+ }
- if (tq->tqi_ready_time &&
- (tq->tqi_type != AR5K_TX_QUEUE_CAB))
- ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_ready_time,
- AR5K_QCU_RDYTIMECFG_INTVAL) |
- AR5K_QCU_RDYTIMECFG_ENABLE,
- AR5K_QUEUE_RDYTIMECFG(queue));
-
- if (tq->tqi_burst_time) {
- ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_burst_time,
- AR5K_DCU_CHAN_TIME_DUR) |
- AR5K_DCU_CHAN_TIME_ENABLE,
- AR5K_QUEUE_DFS_CHANNEL_TIME(queue));
-
- if (tq->tqi_flags
- & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)
- AR5K_REG_ENABLE_BITS(ah,
- AR5K_QUEUE_MISC(queue),
+ /* Ready time interval */
+ if (tq->tqi_ready_time && (tq->tqi_type != AR5K_TX_QUEUE_CAB))
+ ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_ready_time,
+ AR5K_QCU_RDYTIMECFG_INTVAL) |
+ AR5K_QCU_RDYTIMECFG_ENABLE,
+ AR5K_QUEUE_RDYTIMECFG(queue));
+
+ if (tq->tqi_burst_time) {
+ ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_burst_time,
+ AR5K_DCU_CHAN_TIME_DUR) |
+ AR5K_DCU_CHAN_TIME_ENABLE,
+ AR5K_QUEUE_DFS_CHANNEL_TIME(queue));
+
+ if (tq->tqi_flags & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)
+ AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
AR5K_QCU_MISC_RDY_VEOL_POLICY);
- }
+ }
- if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE)
- ath5k_hw_reg_write(ah, AR5K_DCU_MISC_POST_FR_BKOFF_DIS,
- AR5K_QUEUE_DFS_MISC(queue));
+ /* Enable/disable Post frame backoff */
+ if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE)
+ ath5k_hw_reg_write(ah, AR5K_DCU_MISC_POST_FR_BKOFF_DIS,
+ AR5K_QUEUE_DFS_MISC(queue));
- if (tq->tqi_flags & AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE)
- ath5k_hw_reg_write(ah, AR5K_DCU_MISC_BACKOFF_FRAG,
- AR5K_QUEUE_DFS_MISC(queue));
+ /* Enable/disable fragmentation burst backoff */
+ if (tq->tqi_flags & AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE)
+ ath5k_hw_reg_write(ah, AR5K_DCU_MISC_BACKOFF_FRAG,
+ AR5K_QUEUE_DFS_MISC(queue));
- /*
- * Set registers by queue type
- */
- switch (tq->tqi_type) {
- case AR5K_TX_QUEUE_BEACON:
- AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
+ /*
+ * Set registers by queue type
+ */
+ switch (tq->tqi_type) {
+ case AR5K_TX_QUEUE_BEACON:
+ AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
AR5K_QCU_MISC_FRSHED_DBA_GT |
AR5K_QCU_MISC_CBREXP_BCN_DIS |
AR5K_QCU_MISC_BCN_ENABLE);
- AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
+ AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
(AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
AR5K_DCU_MISC_ARBLOCK_CTL_S) |
AR5K_DCU_MISC_ARBLOCK_IGNORE |
AR5K_DCU_MISC_POST_FR_BKOFF_DIS |
AR5K_DCU_MISC_BCN_ENABLE);
- break;
+ break;
- case AR5K_TX_QUEUE_CAB:
- /* XXX: use BCN_SENT_GT, if we can figure out how */
- AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
- AR5K_QCU_MISC_FRSHED_DBA_GT |
- AR5K_QCU_MISC_CBREXP_DIS |
- AR5K_QCU_MISC_CBREXP_BCN_DIS);
+ case AR5K_TX_QUEUE_CAB:
+ /* XXX: use BCN_SENT_GT, if we can figure out how */
+ AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
+ AR5K_QCU_MISC_FRSHED_DBA_GT |
+ AR5K_QCU_MISC_CBREXP_DIS |
+ AR5K_QCU_MISC_CBREXP_BCN_DIS);
- ath5k_hw_reg_write(ah, ((tq->tqi_ready_time -
- (AR5K_TUNE_SW_BEACON_RESP -
- AR5K_TUNE_DMA_BEACON_RESP) -
+ ath5k_hw_reg_write(ah, ((tq->tqi_ready_time -
+ (AR5K_TUNE_SW_BEACON_RESP -
+ AR5K_TUNE_DMA_BEACON_RESP) -
AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) |
- AR5K_QCU_RDYTIMECFG_ENABLE,
- AR5K_QUEUE_RDYTIMECFG(queue));
+ AR5K_QCU_RDYTIMECFG_ENABLE,
+ AR5K_QUEUE_RDYTIMECFG(queue));
- AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
- (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
- AR5K_DCU_MISC_ARBLOCK_CTL_S));
- break;
+ AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
+ (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
+ AR5K_DCU_MISC_ARBLOCK_CTL_S));
+ break;
- case AR5K_TX_QUEUE_UAPSD:
- AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
- AR5K_QCU_MISC_CBREXP_DIS);
- break;
+ case AR5K_TX_QUEUE_UAPSD:
+ AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
+ AR5K_QCU_MISC_CBREXP_DIS);
+ break;
- case AR5K_TX_QUEUE_DATA:
- default:
+ case AR5K_TX_QUEUE_DATA:
+ default:
break;
- }
-
- /* TODO: Handle frame compression */
-
- /*
- * Enable interrupts for this tx queue
- * in the secondary interrupt mask registers
- */
- if (tq->tqi_flags & AR5K_TXQ_FLAG_TXOKINT_ENABLE)
- AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txok, queue);
-
- if (tq->tqi_flags & AR5K_TXQ_FLAG_TXERRINT_ENABLE)
- AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txerr, queue);
-
- if (tq->tqi_flags & AR5K_TXQ_FLAG_TXURNINT_ENABLE)
- AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txurn, queue);
-
- if (tq->tqi_flags & AR5K_TXQ_FLAG_TXDESCINT_ENABLE)
- AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txdesc, queue);
-
- if (tq->tqi_flags & AR5K_TXQ_FLAG_TXEOLINT_ENABLE)
- AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txeol, queue);
-
- if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRORNINT_ENABLE)
- AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrorn, queue);
-
- if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRURNINT_ENABLE)
- AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrurn, queue);
-
- if (tq->tqi_flags & AR5K_TXQ_FLAG_QTRIGINT_ENABLE)
- AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_qtrig, queue);
-
- if (tq->tqi_flags & AR5K_TXQ_FLAG_TXNOFRMINT_ENABLE)
- AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_nofrm, queue);
-
- /* Update secondary interrupt mask registers */
-
- /* Filter out inactive queues */
- ah->ah_txq_imr_txok &= ah->ah_txq_status;
- ah->ah_txq_imr_txerr &= ah->ah_txq_status;
- ah->ah_txq_imr_txurn &= ah->ah_txq_status;
- ah->ah_txq_imr_txdesc &= ah->ah_txq_status;
- ah->ah_txq_imr_txeol &= ah->ah_txq_status;
- ah->ah_txq_imr_cbrorn &= ah->ah_txq_status;
- ah->ah_txq_imr_cbrurn &= ah->ah_txq_status;
- ah->ah_txq_imr_qtrig &= ah->ah_txq_status;
- ah->ah_txq_imr_nofrm &= ah->ah_txq_status;
-
- ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txok,
- AR5K_SIMR0_QCU_TXOK) |
- AR5K_REG_SM(ah->ah_txq_imr_txdesc,
- AR5K_SIMR0_QCU_TXDESC), AR5K_SIMR0);
- ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txerr,
- AR5K_SIMR1_QCU_TXERR) |
- AR5K_REG_SM(ah->ah_txq_imr_txeol,
- AR5K_SIMR1_QCU_TXEOL), AR5K_SIMR1);
- /* Update simr2 but don't overwrite rest simr2 settings */
- AR5K_REG_DISABLE_BITS(ah, AR5K_SIMR2, AR5K_SIMR2_QCU_TXURN);
- AR5K_REG_ENABLE_BITS(ah, AR5K_SIMR2,
- AR5K_REG_SM(ah->ah_txq_imr_txurn,
- AR5K_SIMR2_QCU_TXURN));
- ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_cbrorn,
- AR5K_SIMR3_QCBRORN) |
- AR5K_REG_SM(ah->ah_txq_imr_cbrurn,
- AR5K_SIMR3_QCBRURN), AR5K_SIMR3);
- ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_qtrig,
- AR5K_SIMR4_QTRIG), AR5K_SIMR4);
- /* Set TXNOFRM_QCU for the queues with TXNOFRM enabled */
- ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_nofrm,
- AR5K_TXNOFRM_QCU), AR5K_TXNOFRM);
- /* No queue has TXNOFRM enabled, disable the interrupt
- * by setting AR5K_TXNOFRM to zero */
- if (ah->ah_txq_imr_nofrm == 0)
- ath5k_hw_reg_write(ah, 0, AR5K_TXNOFRM);
-
- /* Set QCU mask for this DCU to save power */
- AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(queue), queue);
}
+ /* TODO: Handle frame compression */
+
+ /*
+ * Enable interrupts for this tx queue
+ * in the secondary interrupt mask registers
+ */
+ if (tq->tqi_flags & AR5K_TXQ_FLAG_TXOKINT_ENABLE)
+ AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txok, queue);
+
+ if (tq->tqi_flags & AR5K_TXQ_FLAG_TXERRINT_ENABLE)
+ AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txerr, queue);
+
+ if (tq->tqi_flags & AR5K_TXQ_FLAG_TXURNINT_ENABLE)
+ AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txurn, queue);
+
+ if (tq->tqi_flags & AR5K_TXQ_FLAG_TXDESCINT_ENABLE)
+ AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txdesc, queue);
+
+ if (tq->tqi_flags & AR5K_TXQ_FLAG_TXEOLINT_ENABLE)
+ AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txeol, queue);
+
+ if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRORNINT_ENABLE)
+ AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrorn, queue);
+
+ if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRURNINT_ENABLE)
+ AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrurn, queue);
+
+ if (tq->tqi_flags & AR5K_TXQ_FLAG_QTRIGINT_ENABLE)
+ AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_qtrig, queue);
+
+ if (tq->tqi_flags & AR5K_TXQ_FLAG_TXNOFRMINT_ENABLE)
+ AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_nofrm, queue);
+
+ /* Update secondary interrupt mask registers */
+
+ /* Filter out inactive queues */
+ ah->ah_txq_imr_txok &= ah->ah_txq_status;
+ ah->ah_txq_imr_txerr &= ah->ah_txq_status;
+ ah->ah_txq_imr_txurn &= ah->ah_txq_status;
+ ah->ah_txq_imr_txdesc &= ah->ah_txq_status;
+ ah->ah_txq_imr_txeol &= ah->ah_txq_status;
+ ah->ah_txq_imr_cbrorn &= ah->ah_txq_status;
+ ah->ah_txq_imr_cbrurn &= ah->ah_txq_status;
+ ah->ah_txq_imr_qtrig &= ah->ah_txq_status;
+ ah->ah_txq_imr_nofrm &= ah->ah_txq_status;
+
+ ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txok,
+ AR5K_SIMR0_QCU_TXOK) |
+ AR5K_REG_SM(ah->ah_txq_imr_txdesc,
+ AR5K_SIMR0_QCU_TXDESC),
+ AR5K_SIMR0);
+
+ ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txerr,
+ AR5K_SIMR1_QCU_TXERR) |
+ AR5K_REG_SM(ah->ah_txq_imr_txeol,
+ AR5K_SIMR1_QCU_TXEOL),
+ AR5K_SIMR1);
+
+ /* Update SIMR2 but don't overwrite rest simr2 settings */
+ AR5K_REG_DISABLE_BITS(ah, AR5K_SIMR2, AR5K_SIMR2_QCU_TXURN);
+ AR5K_REG_ENABLE_BITS(ah, AR5K_SIMR2,
+ AR5K_REG_SM(ah->ah_txq_imr_txurn,
+ AR5K_SIMR2_QCU_TXURN));
+
+ ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_cbrorn,
+ AR5K_SIMR3_QCBRORN) |
+ AR5K_REG_SM(ah->ah_txq_imr_cbrurn,
+ AR5K_SIMR3_QCBRURN),
+ AR5K_SIMR3);
+
+ ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_qtrig,
+ AR5K_SIMR4_QTRIG), AR5K_SIMR4);
+
+ /* Set TXNOFRM_QCU for the queues with TXNOFRM enabled */
+ ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_nofrm,
+ AR5K_TXNOFRM_QCU), AR5K_TXNOFRM);
+
+ /* No queue has TXNOFRM enabled, disable the interrupt
+ * by setting AR5K_TXNOFRM to zero */
+ if (ah->ah_txq_imr_nofrm == 0)
+ ath5k_hw_reg_write(ah, 0, AR5K_TXNOFRM);
+
+ /* Set QCU mask for this DCU to save power */
+ AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(queue), queue);
+
return 0;
}
-/*
- * Set slot time on DCU
+
+/**************************\
+* Global QCU/DCU functions *
+\**************************/
+
+/**
+ * ath5k_hw_set_ifs_intervals - Set global inter-frame spaces on DCU
+ *
+ * @ah The &struct ath5k_hw
+ * @slot_time Slot time in us
+ *
+ * Sets the global IFS intervals on DCU (also works on AR5210) for
+ * the given slot time and the current bwmode.
*/
-int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time)
+int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time)
{
+ struct ieee80211_channel *channel = ah->ah_current_channel;
+ struct ath5k_softc *sc = ah->ah_sc;
+ struct ieee80211_rate *rate;
+ u32 ack_tx_time, eifs, eifs_clock, sifs, sifs_clock;
u32 slot_time_clock = ath5k_hw_htoclock(ah, slot_time);
if (slot_time < 6 || slot_time_clock > AR5K_SLOT_TIME_MAX)
return -EINVAL;
- if (ah->ah_version == AR5K_AR5210)
- ath5k_hw_reg_write(ah, slot_time_clock, AR5K_SLOT_TIME);
+ sifs = ath5k_hw_get_default_sifs(ah);
+ sifs_clock = ath5k_hw_htoclock(ah, sifs);
+
+ /* EIFS
+ * Txtime of ack at lowest rate + SIFS + DIFS
+ * (DIFS = SIFS + 2 * Slot time)
+ *
+ * Note: HAL has some predefined values for EIFS
+ * Turbo: (37 + 2 * 6)
+ * Default: (74 + 2 * 9)
+ * Half: (149 + 2 * 13)
+ * Quarter: (298 + 2 * 21)
+ *
+ * (74 + 2 * 6) for AR5210 default and turbo !
+ *
+ * According to the formula we have
+ * ack_tx_time = 25 for turbo and
+ * ack_tx_time = 42.5 * clock multiplier
+ * for default/half/quarter.
+ *
+ * This can't be right, 42 is what we would get
+ * from ath5k_hw_get_frame_dur_for_bwmode or
+ * ieee80211_generic_frame_duration for zero frame
+ * length and without SIFS !
+ *
+ * Also we have different lowest rate for 802.11a
+ */
+ if (channel->hw_value & CHANNEL_5GHZ)
+ rate = &sc->sbands[IEEE80211_BAND_5GHZ].bitrates[0];
else
- ath5k_hw_reg_write(ah, slot_time_clock, AR5K_DCU_GBL_IFS_SLOT);
+ rate = &sc->sbands[IEEE80211_BAND_2GHZ].bitrates[0];
+
+ ack_tx_time = ath5k_hw_get_frame_duration(ah, 10, rate);
+
+ /* ack_tx_time includes an SIFS already */
+ eifs = ack_tx_time + sifs + 2 * slot_time;
+ eifs_clock = ath5k_hw_htoclock(ah, eifs);
+
+ /* Set IFS settings on AR5210 */
+ if (ah->ah_version == AR5K_AR5210) {
+ u32 pifs, pifs_clock, difs, difs_clock;
+
+ /* Set slot time */
+ ath5k_hw_reg_write(ah, slot_time_clock, AR5K_SLOT_TIME);
+
+ /* Set EIFS */
+ eifs_clock = AR5K_REG_SM(eifs_clock, AR5K_IFS1_EIFS);
+
+ /* PIFS = Slot time + SIFS */
+ pifs = slot_time + sifs;
+ pifs_clock = ath5k_hw_htoclock(ah, pifs);
+ pifs_clock = AR5K_REG_SM(pifs_clock, AR5K_IFS1_PIFS);
+
+ /* DIFS = SIFS + 2 * Slot time */
+ difs = sifs + 2 * slot_time;
+ difs_clock = ath5k_hw_htoclock(ah, difs);
+
+ /* Set SIFS/DIFS */
+ ath5k_hw_reg_write(ah, (difs_clock <<
+ AR5K_IFS0_DIFS_S) | sifs_clock,
+ AR5K_IFS0);
+
+ /* Set PIFS/EIFS and preserve AR5K_INIT_CARR_SENSE_EN */
+ ath5k_hw_reg_write(ah, pifs_clock | eifs_clock |
+ (AR5K_INIT_CARR_SENSE_EN << AR5K_IFS1_CS_EN_S),
+ AR5K_IFS1);
+
+ return 0;
+ }
+
+ /* Set IFS slot time */
+ ath5k_hw_reg_write(ah, slot_time_clock, AR5K_DCU_GBL_IFS_SLOT);
+
+ /* Set EIFS interval */
+ ath5k_hw_reg_write(ah, eifs_clock, AR5K_DCU_GBL_IFS_EIFS);
+
+ /* Set SIFS interval in usecs */
+ AR5K_REG_WRITE_BITS(ah, AR5K_DCU_GBL_IFS_MISC,
+ AR5K_DCU_GBL_IFS_MISC_SIFS_DUR_USEC,
+ sifs);
+
+ /* Set SIFS interval in clock cycles */
+ ath5k_hw_reg_write(ah, sifs_clock, AR5K_DCU_GBL_IFS_SIFS);
return 0;
}
+
+int ath5k_hw_init_queues(struct ath5k_hw *ah)
+{
+ int i, ret;
+
+ /* TODO: HW Compression support for data queues */
+ /* TODO: Burst prefetch for data queues */
+
+ /*
+ * Reset queues and start beacon timers at the end of the reset routine
+ * This also sets QCU mask on each DCU for 1:1 qcu to dcu mapping
+ * Note: If we want we can assign multiple qcus on one dcu.
+ */
+ if (ah->ah_version != AR5K_AR5210)
+ for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) {
+ ret = ath5k_hw_reset_tx_queue(ah, i);
+ if (ret) {
+ ATH5K_ERR(ah->ah_sc,
+ "failed to reset TX queue #%d\n", i);
+ return ret;
+ }
+ }
+ else
+ /* No QCU/DCU on AR5210, just set tx
+ * retry limits. We set IFS parameters
+ * on ath5k_hw_set_ifs_intervals */
+ ath5k_hw_set_tx_retry_limits(ah, 0);
+
+ /* Set the turbo flag when operating on 40MHz */
+ if (ah->ah_bwmode == AR5K_BWMODE_40MHZ)
+ AR5K_REG_ENABLE_BITS(ah, AR5K_DCU_GBL_IFS_MISC,
+ AR5K_DCU_GBL_IFS_MISC_TURBO_MODE);
+
+ /* If we didn't set IFS timings through
+ * ath5k_hw_set_coverage_class make sure
+ * we set them here */
+ if (!ah->ah_coverage_class) {
+ unsigned int slot_time = ath5k_hw_get_default_slottime(ah);
+ ath5k_hw_set_ifs_intervals(ah, slot_time);
+ }
+
+ return 0;
+}
diff --git a/drivers/net/wireless/ath/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h
index ca79ecd832fd..7ad05d401ab5 100644
--- a/drivers/net/wireless/ath/ath5k/reg.h
+++ b/drivers/net/wireless/ath/ath5k/reg.h
@@ -787,6 +787,7 @@
#define AR5K_DCU_GBL_IFS_MISC_LFSR_SLICE 0x00000007 /* LFSR Slice Select */
#define AR5K_DCU_GBL_IFS_MISC_TURBO_MODE 0x00000008 /* Turbo mode */
#define AR5K_DCU_GBL_IFS_MISC_SIFS_DUR_USEC 0x000003f0 /* SIFS Duration mask */
+#define AR5K_DCU_GBL_IFS_MISC_SIFS_DUR_USEC_S 4
#define AR5K_DCU_GBL_IFS_MISC_USEC_DUR 0x000ffc00 /* USEC Duration mask */
#define AR5K_DCU_GBL_IFS_MISC_USEC_DUR_S 10
#define AR5K_DCU_GBL_IFS_MISC_DCU_ARB_DELAY 0x00300000 /* DCU Arbiter delay mask */
@@ -1311,7 +1312,7 @@
#define AR5K_IFS1_EIFS 0x03fff000
#define AR5K_IFS1_EIFS_S 12
#define AR5K_IFS1_CS_EN 0x04000000
-
+#define AR5K_IFS1_CS_EN_S 26
/*
* CFP duration register
@@ -2058,6 +2059,7 @@
#define AR5K_PHY_SCAL 0x9878
#define AR5K_PHY_SCAL_32MHZ 0x0000000e
+#define AR5K_PHY_SCAL_32MHZ_5311 0x00000008
#define AR5K_PHY_SCAL_32MHZ_2417 0x0000000a
#define AR5K_PHY_SCAL_32MHZ_HB63 0x00000032
@@ -2244,6 +2246,8 @@
#define AR5K_PHY_FRAME_CTL (ah->ah_version == AR5K_AR5210 ? \
AR5K_PHY_FRAME_CTL_5210 : AR5K_PHY_FRAME_CTL_5211)
/*---[5111+]---*/
+#define AR5K_PHY_FRAME_CTL_WIN_LEN 0x00000003 /* Force window length (?) */
+#define AR5K_PHY_FRAME_CTL_WIN_LEN_S 0
#define AR5K_PHY_FRAME_CTL_TX_CLIP 0x00000038 /* Mask for tx clip (?) */
#define AR5K_PHY_FRAME_CTL_TX_CLIP_S 3
#define AR5K_PHY_FRAME_CTL_PREP_CHINFO 0x00010000 /* Prepend chan info */
@@ -2558,3 +2562,28 @@
*/
#define AR5K_PHY_PDADC_TXPOWER_BASE 0xa280
#define AR5K_PHY_PDADC_TXPOWER(_n) (AR5K_PHY_PDADC_TXPOWER_BASE + ((_n) << 2))
+
+/*
+ * Platform registers for WiSoC
+ */
+#define AR5K_AR5312_RESET 0xbc003020
+#define AR5K_AR5312_RESET_BB0_COLD 0x00000004
+#define AR5K_AR5312_RESET_BB1_COLD 0x00000200
+#define AR5K_AR5312_RESET_WMAC0 0x00002000
+#define AR5K_AR5312_RESET_BB0_WARM 0x00004000
+#define AR5K_AR5312_RESET_WMAC1 0x00020000
+#define AR5K_AR5312_RESET_BB1_WARM 0x00040000
+
+#define AR5K_AR5312_ENABLE 0xbc003080
+#define AR5K_AR5312_ENABLE_WLAN0 0x00000001
+#define AR5K_AR5312_ENABLE_WLAN1 0x00000008
+
+#define AR5K_AR2315_RESET 0xb1000004
+#define AR5K_AR2315_RESET_WMAC 0x00000001
+#define AR5K_AR2315_RESET_BB_WARM 0x00000002
+
+#define AR5K_AR2315_AHB_ARB_CTL 0xb1000008
+#define AR5K_AR2315_AHB_ARB_CTL_WLAN 0x00000002
+
+#define AR5K_AR2315_BYTESWAP 0xb100000c
+#define AR5K_AR2315_BYTESWAP_WMAC 0x00000002
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index 5b179d01f97d..bc84aaa31446 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -27,11 +27,17 @@
#include <linux/pci.h> /* To determine if a card is pci-e */
#include <linux/log2.h>
+#include <linux/platform_device.h>
#include "ath5k.h"
#include "reg.h"
#include "base.h"
#include "debug.h"
+
+/******************\
+* Helper functions *
+\******************/
+
/*
* Check if a register write has been completed
*/
@@ -53,146 +59,267 @@ int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val,
return (i <= 0) ? -EAGAIN : 0;
}
+
+/*************************\
+* Clock related functions *
+\*************************/
+
/**
- * ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212
+ * ath5k_hw_htoclock - Translate usec to hw clock units
*
- * @ah: the &struct ath5k_hw
- * @channel: the currently set channel upon reset
- *
- * Write the delta slope coefficient (used on pilot tracking ?) for OFDM
- * operation on the AR5212 upon reset. This is a helper for ath5k_hw_reset().
+ * @ah: The &struct ath5k_hw
+ * @usec: value in microseconds
+ */
+unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec)
+{
+ struct ath_common *common = ath5k_hw_common(ah);
+ return usec * common->clockrate;
+}
+
+/**
+ * ath5k_hw_clocktoh - Translate hw clock units to usec
+ * @clock: value in hw clock units
+ */
+unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock)
+{
+ struct ath_common *common = ath5k_hw_common(ah);
+ return clock / common->clockrate;
+}
+
+/**
+ * ath5k_hw_init_core_clock - Initialize core clock
*
- * Since delta slope is floating point we split it on its exponent and
- * mantissa and provide these values on hw.
+ * @ah The &struct ath5k_hw
*
- * For more infos i think this patent is related
- * http://www.freepatentsonline.com/7184495.html
+ * Initialize core clock parameters (usec, usec32, latencies etc).
*/
-static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
- struct ieee80211_channel *channel)
+static void ath5k_hw_init_core_clock(struct ath5k_hw *ah)
{
- /* Get exponent and mantissa and set it */
- u32 coef_scaled, coef_exp, coef_man,
- ds_coef_exp, ds_coef_man, clock;
-
- BUG_ON(!(ah->ah_version == AR5K_AR5212) ||
- !(channel->hw_value & CHANNEL_OFDM));
-
- /* Get coefficient
- * ALGO: coef = (5 * clock / carrier_freq) / 2
- * we scale coef by shifting clock value by 24 for
- * better precision since we use integers */
- /* TODO: Half/quarter rate */
- clock = (channel->hw_value & CHANNEL_TURBO) ? 80 : 40;
- coef_scaled = ((5 * (clock << 24)) / 2) / channel->center_freq;
-
- /* Get exponent
- * ALGO: coef_exp = 14 - highest set bit position */
- coef_exp = ilog2(coef_scaled);
-
- /* Doesn't make sense if it's zero*/
- if (!coef_scaled || !coef_exp)
- return -EINVAL;
+ struct ieee80211_channel *channel = ah->ah_current_channel;
+ struct ath_common *common = ath5k_hw_common(ah);
+ u32 usec_reg, txlat, rxlat, usec, clock, sclock, txf2txs;
+
+ /*
+ * Set core clock frequency
+ */
+ if (channel->hw_value & CHANNEL_5GHZ)
+ clock = 40; /* 802.11a */
+ else if (channel->hw_value & CHANNEL_CCK)
+ clock = 22; /* 802.11b */
+ else
+ clock = 44; /* 802.11g */
+
+ /* Use clock multiplier for non-default
+ * bwmode */
+ switch (ah->ah_bwmode) {
+ case AR5K_BWMODE_40MHZ:
+ clock *= 2;
+ break;
+ case AR5K_BWMODE_10MHZ:
+ clock /= 2;
+ break;
+ case AR5K_BWMODE_5MHZ:
+ clock /= 4;
+ break;
+ default:
+ break;
+ }
- /* Note: we've shifted coef_scaled by 24 */
- coef_exp = 14 - (coef_exp - 24);
+ common->clockrate = clock;
+ /*
+ * Set USEC parameters
+ */
+ /* Set USEC counter on PCU*/
+ usec = clock - 1;
+ usec = AR5K_REG_SM(usec, AR5K_USEC_1);
- /* Get mantissa (significant digits)
- * ALGO: coef_mant = floor(coef_scaled* 2^coef_exp+0.5) */
- coef_man = coef_scaled +
- (1 << (24 - coef_exp - 1));
+ /* Set usec duration on DCU */
+ if (ah->ah_version != AR5K_AR5210)
+ AR5K_REG_WRITE_BITS(ah, AR5K_DCU_GBL_IFS_MISC,
+ AR5K_DCU_GBL_IFS_MISC_USEC_DUR,
+ clock);
- /* Calculate delta slope coefficient exponent
- * and mantissa (remove scaling) and set them on hw */
- ds_coef_man = coef_man >> (24 - coef_exp);
- ds_coef_exp = coef_exp - 16;
+ /* Set 32MHz USEC counter */
+ if ((ah->ah_radio == AR5K_RF5112) ||
+ (ah->ah_radio == AR5K_RF5413) ||
+ (ah->ah_radio == AR5K_RF2316) ||
+ (ah->ah_radio == AR5K_RF2317))
+ /* Remain on 40MHz clock ? */
+ sclock = 40 - 1;
+ else
+ sclock = 32 - 1;
+ sclock = AR5K_REG_SM(sclock, AR5K_USEC_32);
- AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
- AR5K_PHY_TIMING_3_DSC_MAN, ds_coef_man);
- AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
- AR5K_PHY_TIMING_3_DSC_EXP, ds_coef_exp);
+ /*
+ * Set tx/rx latencies
+ */
+ usec_reg = ath5k_hw_reg_read(ah, AR5K_USEC_5211);
+ txlat = AR5K_REG_MS(usec_reg, AR5K_USEC_TX_LATENCY_5211);
+ rxlat = AR5K_REG_MS(usec_reg, AR5K_USEC_RX_LATENCY_5211);
- return 0;
-}
+ /*
+ * 5210 initvals don't include usec settings
+ * so we need to use magic values here for
+ * tx/rx latencies
+ */
+ if (ah->ah_version == AR5K_AR5210) {
+ /* same for turbo */
+ txlat = AR5K_INIT_TX_LATENCY_5210;
+ rxlat = AR5K_INIT_RX_LATENCY_5210;
+ }
+ if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
+ /* 5311 has different tx/rx latency masks
+ * from 5211, since we deal 5311 the same
+ * as 5211 when setting initvals, shift
+ * values here to their proper locations
+ *
+ * Note: Initvals indicate tx/rx/ latencies
+ * are the same for turbo mode */
+ txlat = AR5K_REG_SM(txlat, AR5K_USEC_TX_LATENCY_5210);
+ rxlat = AR5K_REG_SM(rxlat, AR5K_USEC_RX_LATENCY_5210);
+ } else
+ switch (ah->ah_bwmode) {
+ case AR5K_BWMODE_10MHZ:
+ txlat = AR5K_REG_SM(txlat * 2,
+ AR5K_USEC_TX_LATENCY_5211);
+ rxlat = AR5K_REG_SM(AR5K_INIT_RX_LAT_MAX,
+ AR5K_USEC_RX_LATENCY_5211);
+ txf2txs = AR5K_INIT_TXF2TXD_START_DELAY_10MHZ;
+ break;
+ case AR5K_BWMODE_5MHZ:
+ txlat = AR5K_REG_SM(txlat * 4,
+ AR5K_USEC_TX_LATENCY_5211);
+ rxlat = AR5K_REG_SM(AR5K_INIT_RX_LAT_MAX,
+ AR5K_USEC_RX_LATENCY_5211);
+ txf2txs = AR5K_INIT_TXF2TXD_START_DELAY_5MHZ;
+ break;
+ case AR5K_BWMODE_40MHZ:
+ txlat = AR5K_INIT_TX_LAT_MIN;
+ rxlat = AR5K_REG_SM(rxlat / 2,
+ AR5K_USEC_RX_LATENCY_5211);
+ txf2txs = AR5K_INIT_TXF2TXD_START_DEFAULT;
+ break;
+ default:
+ break;
+ }
-/*
- * index into rates for control rates, we can set it up like this because
- * this is only used for AR5212 and we know it supports G mode
- */
-static const unsigned int control_rates[] =
- { 0, 1, 1, 1, 4, 4, 6, 6, 8, 8, 8, 8 };
+ usec_reg = (usec | sclock | txlat | rxlat);
+ ath5k_hw_reg_write(ah, usec_reg, AR5K_USEC);
-/**
- * ath5k_hw_write_rate_duration - fill rate code to duration table
- *
- * @ah: the &struct ath5k_hw
- * @mode: one of enum ath5k_driver_mode
- *
- * Write the rate code to duration table upon hw reset. This is a helper for
- * ath5k_hw_reset(). It seems all this is doing is setting an ACK timeout on
- * the hardware, based on current mode, for each rate. The rates which are
- * capable of short preamble (802.11b rates 2Mbps, 5.5Mbps, and 11Mbps) have
- * different rate code so we write their value twice (one for long preample
- * and one for short).
+ /* On 5112 set tx frane to tx data start delay */
+ if (ah->ah_radio == AR5K_RF5112) {
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RF_CTL2,
+ AR5K_PHY_RF_CTL2_TXF2TXD_START,
+ txf2txs);
+ }
+}
+
+/*
+ * If there is an external 32KHz crystal available, use it
+ * as ref. clock instead of 32/40MHz clock and baseband clocks
+ * to save power during sleep or restore normal 32/40MHz
+ * operation.
*
- * Note: Band doesn't matter here, if we set the values for OFDM it works
- * on both a and g modes. So all we have to do is set values for all g rates
- * that include all OFDM and CCK rates. If we operate in turbo or xr/half/
- * quarter rate mode, we need to use another set of bitrates (that's why we
- * need the mode parameter) but we don't handle these proprietary modes yet.
+ * XXX: When operating on 32KHz certain PHY registers (27 - 31,
+ * 123 - 127) require delay on access.
*/
-static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah,
- unsigned int mode)
+static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable)
{
- struct ath5k_softc *sc = ah->ah_sc;
- struct ieee80211_rate *rate;
- unsigned int i;
+ struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+ u32 scal, spending;
- /* Write rate duration table */
- for (i = 0; i < sc->sbands[IEEE80211_BAND_2GHZ].n_bitrates; i++) {
- u32 reg;
- u16 tx_time;
+ /* Only set 32KHz settings if we have an external
+ * 32KHz crystal present */
+ if ((AR5K_EEPROM_HAS32KHZCRYSTAL(ee->ee_misc1) ||
+ AR5K_EEPROM_HAS32KHZCRYSTAL_OLD(ee->ee_misc1)) &&
+ enable) {
- rate = &sc->sbands[IEEE80211_BAND_2GHZ].bitrates[control_rates[i]];
+ /* 1 usec/cycle */
+ AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, 1);
+ /* Set up tsf increment on each cycle */
+ AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 61);
- /* Set ACK timeout */
- reg = AR5K_RATE_DUR(rate->hw_value);
+ /* Set baseband sleep control registers
+ * and sleep control rate */
+ ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR);
- /* An ACK frame consists of 10 bytes. If you add the FCS,
- * which ieee80211_generic_frame_duration() adds,
- * its 14 bytes. Note we use the control rate and not the
- * actual rate for this rate. See mac80211 tx.c
- * ieee80211_duration() for a brief description of
- * what rate we should choose to TX ACKs. */
- tx_time = le16_to_cpu(ieee80211_generic_frame_duration(sc->hw,
- NULL, 10, rate));
+ if ((ah->ah_radio == AR5K_RF5112) ||
+ (ah->ah_radio == AR5K_RF5413) ||
+ (ah->ah_radio == AR5K_RF2316) ||
+ (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
+ spending = 0x14;
+ else
+ spending = 0x18;
+ ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING);
- ath5k_hw_reg_write(ah, tx_time, reg);
+ if ((ah->ah_radio == AR5K_RF5112) ||
+ (ah->ah_radio == AR5K_RF5413) ||
+ (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) {
+ ath5k_hw_reg_write(ah, 0x26, AR5K_PHY_SLMT);
+ ath5k_hw_reg_write(ah, 0x0d, AR5K_PHY_SCAL);
+ ath5k_hw_reg_write(ah, 0x07, AR5K_PHY_SCLOCK);
+ ath5k_hw_reg_write(ah, 0x3f, AR5K_PHY_SDELAY);
+ AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
+ AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x02);
+ } else {
+ ath5k_hw_reg_write(ah, 0x0a, AR5K_PHY_SLMT);
+ ath5k_hw_reg_write(ah, 0x0c, AR5K_PHY_SCAL);
+ ath5k_hw_reg_write(ah, 0x03, AR5K_PHY_SCLOCK);
+ ath5k_hw_reg_write(ah, 0x20, AR5K_PHY_SDELAY);
+ AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
+ AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x03);
+ }
- if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE))
- continue;
+ /* Enable sleep clock operation */
+ AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG,
+ AR5K_PCICFG_SLEEP_CLOCK_EN);
- /*
- * We're not distinguishing short preamble here,
- * This is true, all we'll get is a longer value here
- * which is not necessarilly bad. We could use
- * export ieee80211_frame_duration() but that needs to be
- * fixed first to be properly used by mac802111 drivers:
- *
- * - remove erp stuff and let the routine figure ofdm
- * erp rates
- * - remove passing argument ieee80211_local as
- * drivers don't have access to it
- * - move drivers using ieee80211_generic_frame_duration()
- * to this
- */
- ath5k_hw_reg_write(ah, tx_time,
- reg + (AR5K_SET_SHORT_PREAMBLE << 2));
+ } else {
+
+ /* Disable sleep clock operation and
+ * restore default parameters */
+ AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG,
+ AR5K_PCICFG_SLEEP_CLOCK_EN);
+
+ AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
+ AR5K_PCICFG_SLEEP_CLOCK_RATE, 0);
+
+ /* Set DAC/ADC delays */
+ ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR);
+ ath5k_hw_reg_write(ah, AR5K_PHY_SLMT_32MHZ, AR5K_PHY_SLMT);
+
+ if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))
+ scal = AR5K_PHY_SCAL_32MHZ_2417;
+ else if (ee->ee_is_hb63)
+ scal = AR5K_PHY_SCAL_32MHZ_HB63;
+ else
+ scal = AR5K_PHY_SCAL_32MHZ;
+ ath5k_hw_reg_write(ah, scal, AR5K_PHY_SCAL);
+
+ ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK);
+ ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY);
+
+ if ((ah->ah_radio == AR5K_RF5112) ||
+ (ah->ah_radio == AR5K_RF5413) ||
+ (ah->ah_radio == AR5K_RF2316) ||
+ (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
+ spending = 0x14;
+ else
+ spending = 0x18;
+ ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING);
+
+ /* Set up tsf increment on each cycle */
+ AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 1);
}
}
+
+/*********************\
+* Reset/Sleep control *
+\*********************/
+
/*
* Reset chipset
*/
@@ -236,6 +363,64 @@ static int ath5k_hw_nic_reset(struct ath5k_hw *ah, u32 val)
}
/*
+ * Reset AHB chipset
+ * AR5K_RESET_CTL_PCU flag resets WMAC
+ * AR5K_RESET_CTL_BASEBAND flag resets WBB
+ */
+static int ath5k_hw_wisoc_reset(struct ath5k_hw *ah, u32 flags)
+{
+ u32 mask = flags ? flags : ~0U;
+ volatile u32 *reg;
+ u32 regval;
+ u32 val = 0;
+
+ /* ah->ah_mac_srev is not available at this point yet */
+ if (ah->ah_sc->devid >= AR5K_SREV_AR2315_R6) {
+ reg = (u32 *) AR5K_AR2315_RESET;
+ if (mask & AR5K_RESET_CTL_PCU)
+ val |= AR5K_AR2315_RESET_WMAC;
+ if (mask & AR5K_RESET_CTL_BASEBAND)
+ val |= AR5K_AR2315_RESET_BB_WARM;
+ } else {
+ reg = (u32 *) AR5K_AR5312_RESET;
+ if (to_platform_device(ah->ah_sc->dev)->id == 0) {
+ if (mask & AR5K_RESET_CTL_PCU)
+ val |= AR5K_AR5312_RESET_WMAC0;
+ if (mask & AR5K_RESET_CTL_BASEBAND)
+ val |= AR5K_AR5312_RESET_BB0_COLD |
+ AR5K_AR5312_RESET_BB0_WARM;
+ } else {
+ if (mask & AR5K_RESET_CTL_PCU)
+ val |= AR5K_AR5312_RESET_WMAC1;
+ if (mask & AR5K_RESET_CTL_BASEBAND)
+ val |= AR5K_AR5312_RESET_BB1_COLD |
+ AR5K_AR5312_RESET_BB1_WARM;
+ }
+ }
+
+ /* Put BB/MAC into reset */
+ regval = __raw_readl(reg);
+ __raw_writel(regval | val, reg);
+ regval = __raw_readl(reg);
+ udelay(100);
+
+ /* Bring BB/MAC out of reset */
+ __raw_writel(regval & ~val, reg);
+ regval = __raw_readl(reg);
+
+ /*
+ * Reset configuration register (for hw byte-swap). Note that this
+ * is only set for big endian. We do the necessary magic in
+ * AR5K_INIT_CFG.
+ */
+ if ((flags & AR5K_RESET_CTL_PCU) == 0)
+ ath5k_hw_reg_write(ah, AR5K_INIT_CFG, AR5K_CFG);
+
+ return 0;
+}
+
+
+/*
* Sleep control
*/
static int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode,
@@ -334,6 +519,9 @@ int ath5k_hw_on_hold(struct ath5k_hw *ah)
u32 bus_flags;
int ret;
+ if (ath5k_get_bus_type(ah) == ATH_AHB)
+ return 0;
+
/* Make sure device is awake */
ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
if (ret) {
@@ -349,7 +537,7 @@ int ath5k_hw_on_hold(struct ath5k_hw *ah)
* we ingore that flag for PCI-E cards. On PCI cards
* this flag gets cleared after 64 PCI clocks.
*/
- bus_flags = (pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI;
+ bus_flags = (pdev && pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI;
if (ah->ah_version == AR5K_AR5210) {
ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
@@ -378,7 +566,6 @@ int ath5k_hw_on_hold(struct ath5k_hw *ah)
/*
* Bring up MAC + PHY Chips and program PLL
- * TODO: Half/Quarter rate support
*/
int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
{
@@ -390,11 +577,13 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
mode = 0;
clock = 0;
- /* Wakeup the device */
- ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
- if (ret) {
- ATH5K_ERR(ah->ah_sc, "failed to wakeup the MAC Chip\n");
- return ret;
+ if ((ath5k_get_bus_type(ah) != ATH_AHB) || !initial) {
+ /* Wakeup the device */
+ ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
+ if (ret) {
+ ATH5K_ERR(ah->ah_sc, "failed to wakeup the MAC Chip\n");
+ return ret;
+ }
}
/*
@@ -405,7 +594,7 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
* we ingore that flag for PCI-E cards. On PCI cards
* this flag gets cleared after 64 PCI clocks.
*/
- bus_flags = (pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI;
+ bus_flags = (pdev && pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI;
if (ah->ah_version == AR5K_AR5210) {
ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
@@ -413,8 +602,12 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
AR5K_RESET_CTL_PHY | AR5K_RESET_CTL_PCI);
mdelay(2);
} else {
- ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
- AR5K_RESET_CTL_BASEBAND | bus_flags);
+ if (ath5k_get_bus_type(ah) == ATH_AHB)
+ ret = ath5k_hw_wisoc_reset(ah, AR5K_RESET_CTL_PCU |
+ AR5K_RESET_CTL_BASEBAND);
+ else
+ ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
+ AR5K_RESET_CTL_BASEBAND | bus_flags);
}
if (ret) {
@@ -429,9 +622,15 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
return ret;
}
- /* ...clear reset control register and pull device out of
- * warm reset */
- if (ath5k_hw_nic_reset(ah, 0)) {
+ /* ...reset configuration regiter on Wisoc ...
+ * ...clear reset control register and pull device out of
+ * warm reset on others */
+ if (ath5k_get_bus_type(ah) == ATH_AHB)
+ ret = ath5k_hw_wisoc_reset(ah, 0);
+ else
+ ret = ath5k_hw_nic_reset(ah, 0);
+
+ if (ret) {
ATH5K_ERR(ah->ah_sc, "failed to warm reset the MAC Chip\n");
return -EIO;
}
@@ -466,7 +665,8 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
* CCK headers) operation. We need to test
* this, 5211 might support ofdm-only g after
* all, there are also initial register values
- * in the code for g mode (see initvals.c). */
+ * in the code for g mode (see initvals.c).
+ */
if (ah->ah_version == AR5K_AR5211)
mode |= AR5K_PHY_MODE_MOD_OFDM;
else
@@ -479,6 +679,7 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
} else if (flags & CHANNEL_5GHZ) {
mode |= AR5K_PHY_MODE_FREQ_5GHZ;
+ /* Different PLL setting for 5413 */
if (ah->ah_radio == AR5K_RF5413)
clock = AR5K_PHY_PLL_40MHZ_5413;
else
@@ -496,12 +697,29 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
return -EINVAL;
}
- if (flags & CHANNEL_TURBO)
- turbo = AR5K_PHY_TURBO_MODE | AR5K_PHY_TURBO_SHORT;
+ /*XXX: Can bwmode be used with dynamic mode ?
+ * (I don't think it supports 44MHz) */
+ /* On 2425 initvals TURBO_SHORT is not pressent */
+ if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) {
+ turbo = AR5K_PHY_TURBO_MODE |
+ (ah->ah_radio == AR5K_RF2425) ? 0 :
+ AR5K_PHY_TURBO_SHORT;
+ } else if (ah->ah_bwmode != AR5K_BWMODE_DEFAULT) {
+ if (ah->ah_radio == AR5K_RF5413) {
+ mode |= (ah->ah_bwmode == AR5K_BWMODE_10MHZ) ?
+ AR5K_PHY_MODE_HALF_RATE :
+ AR5K_PHY_MODE_QUARTER_RATE;
+ } else if (ah->ah_version == AR5K_AR5212) {
+ clock |= (ah->ah_bwmode == AR5K_BWMODE_10MHZ) ?
+ AR5K_PHY_PLL_HALF_RATE :
+ AR5K_PHY_PLL_QUARTER_RATE;
+ }
+ }
+
} else { /* Reset the device */
/* ...enable Atheros turbo mode if requested */
- if (flags & CHANNEL_TURBO)
+ if (ah->ah_bwmode == AR5K_BWMODE_40MHZ)
ath5k_hw_reg_write(ah, AR5K_PHY_TURBO_MODE,
AR5K_PHY_TURBO);
}
@@ -522,107 +740,10 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
return 0;
}
-/*
- * If there is an external 32KHz crystal available, use it
- * as ref. clock instead of 32/40MHz clock and baseband clocks
- * to save power during sleep or restore normal 32/40MHz
- * operation.
- *
- * XXX: When operating on 32KHz certain PHY registers (27 - 31,
- * 123 - 127) require delay on access.
- */
-static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable)
-{
- struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
- u32 scal, spending, usec32;
-
- /* Only set 32KHz settings if we have an external
- * 32KHz crystal present */
- if ((AR5K_EEPROM_HAS32KHZCRYSTAL(ee->ee_misc1) ||
- AR5K_EEPROM_HAS32KHZCRYSTAL_OLD(ee->ee_misc1)) &&
- enable) {
-
- /* 1 usec/cycle */
- AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, 1);
- /* Set up tsf increment on each cycle */
- AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 61);
-
- /* Set baseband sleep control registers
- * and sleep control rate */
- ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR);
-
- if ((ah->ah_radio == AR5K_RF5112) ||
- (ah->ah_radio == AR5K_RF5413) ||
- (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
- spending = 0x14;
- else
- spending = 0x18;
- ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING);
-
- if ((ah->ah_radio == AR5K_RF5112) ||
- (ah->ah_radio == AR5K_RF5413) ||
- (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) {
- ath5k_hw_reg_write(ah, 0x26, AR5K_PHY_SLMT);
- ath5k_hw_reg_write(ah, 0x0d, AR5K_PHY_SCAL);
- ath5k_hw_reg_write(ah, 0x07, AR5K_PHY_SCLOCK);
- ath5k_hw_reg_write(ah, 0x3f, AR5K_PHY_SDELAY);
- AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
- AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x02);
- } else {
- ath5k_hw_reg_write(ah, 0x0a, AR5K_PHY_SLMT);
- ath5k_hw_reg_write(ah, 0x0c, AR5K_PHY_SCAL);
- ath5k_hw_reg_write(ah, 0x03, AR5K_PHY_SCLOCK);
- ath5k_hw_reg_write(ah, 0x20, AR5K_PHY_SDELAY);
- AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
- AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x03);
- }
-
- /* Enable sleep clock operation */
- AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG,
- AR5K_PCICFG_SLEEP_CLOCK_EN);
-
- } else {
-
- /* Disable sleep clock operation and
- * restore default parameters */
- AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG,
- AR5K_PCICFG_SLEEP_CLOCK_EN);
-
- AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
- AR5K_PCICFG_SLEEP_CLOCK_RATE, 0);
-
- ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR);
- ath5k_hw_reg_write(ah, AR5K_PHY_SLMT_32MHZ, AR5K_PHY_SLMT);
-
- if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))
- scal = AR5K_PHY_SCAL_32MHZ_2417;
- else if (ee->ee_is_hb63)
- scal = AR5K_PHY_SCAL_32MHZ_HB63;
- else
- scal = AR5K_PHY_SCAL_32MHZ;
- ath5k_hw_reg_write(ah, scal, AR5K_PHY_SCAL);
-
- ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK);
- ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY);
- if ((ah->ah_radio == AR5K_RF5112) ||
- (ah->ah_radio == AR5K_RF5413) ||
- (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
- spending = 0x14;
- else
- spending = 0x18;
- ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING);
-
- if ((ah->ah_radio == AR5K_RF5112) ||
- (ah->ah_radio == AR5K_RF5413))
- usec32 = 39;
- else
- usec32 = 31;
- AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, usec32);
-
- AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 1);
- }
-}
+/**************************************\
+* Post-initvals register modifications *
+\**************************************/
/* TODO: Half/Quarter rate */
static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah,
@@ -663,22 +784,10 @@ static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah,
AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG,
AR5K_TXCFG_DCU_DBL_BUF_DIS);
- /* Set DAC/ADC delays */
- if (ah->ah_version == AR5K_AR5212) {
- u32 scal;
- struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
- if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))
- scal = AR5K_PHY_SCAL_32MHZ_2417;
- else if (ee->ee_is_hb63)
- scal = AR5K_PHY_SCAL_32MHZ_HB63;
- else
- scal = AR5K_PHY_SCAL_32MHZ;
- ath5k_hw_reg_write(ah, scal, AR5K_PHY_SCAL);
- }
-
/* Set fast ADC */
if ((ah->ah_radio == AR5K_RF5413) ||
- (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) {
+ (ah->ah_radio == AR5K_RF2317) ||
+ (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) {
u32 fast_adc = true;
if (channel->center_freq == 2462 ||
@@ -706,26 +815,54 @@ static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah,
}
if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
- u32 usec_reg;
- /* 5311 has different tx/rx latency masks
- * from 5211, since we deal 5311 the same
- * as 5211 when setting initvals, shift
- * values here to their proper locations */
- usec_reg = ath5k_hw_reg_read(ah, AR5K_USEC_5211);
- ath5k_hw_reg_write(ah, usec_reg & (AR5K_USEC_1 |
- AR5K_USEC_32 |
- AR5K_USEC_TX_LATENCY_5211 |
- AR5K_REG_SM(29,
- AR5K_USEC_RX_LATENCY_5210)),
- AR5K_USEC_5211);
/* Clear QCU/DCU clock gating register */
ath5k_hw_reg_write(ah, 0, AR5K_QCUDCU_CLKGT);
/* Set DAC/ADC delays */
- ath5k_hw_reg_write(ah, 0x08, AR5K_PHY_SCAL);
+ ath5k_hw_reg_write(ah, AR5K_PHY_SCAL_32MHZ_5311,
+ AR5K_PHY_SCAL);
/* Enable PCU FIFO corruption ECO */
AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5211,
AR5K_DIAG_SW_ECO_ENABLE);
}
+
+ if (ah->ah_bwmode) {
+ /* Increase PHY switch and AGC settling time
+ * on turbo mode (ath5k_hw_commit_eeprom_settings
+ * will override settling time if available) */
+ if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) {
+
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING,
+ AR5K_PHY_SETTLING_AGC,
+ AR5K_AGC_SETTLING_TURBO);
+
+ /* XXX: Initvals indicate we only increase
+ * switch time on AR5212, 5211 and 5210
+ * only change agc time (bug?) */
+ if (ah->ah_version == AR5K_AR5212)
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING,
+ AR5K_PHY_SETTLING_SWITCH,
+ AR5K_SWITCH_SETTLING_TURBO);
+
+ if (ah->ah_version == AR5K_AR5210) {
+ /* Set Frame Control Register */
+ ath5k_hw_reg_write(ah,
+ (AR5K_PHY_FRAME_CTL_INI |
+ AR5K_PHY_TURBO_MODE |
+ AR5K_PHY_TURBO_SHORT | 0x2020),
+ AR5K_PHY_FRAME_CTL_5210);
+ }
+ /* On 5413 PHY force window length for half/quarter rate*/
+ } else if ((ah->ah_mac_srev >= AR5K_SREV_AR5424) &&
+ (ah->ah_mac_srev <= AR5K_SREV_AR5414)) {
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_FRAME_CTL_5211,
+ AR5K_PHY_FRAME_CTL_WIN_LEN,
+ 3);
+ }
+ } else if (ah->ah_version == AR5K_AR5210) {
+ /* Set Frame Control Register for normal operation */
+ ath5k_hw_reg_write(ah, (AR5K_PHY_FRAME_CTL_INI | 0x1020),
+ AR5K_PHY_FRAME_CTL_5210);
+ }
}
static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
@@ -734,6 +871,10 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
s16 cck_ofdm_pwr_delta;
+ /* TODO: Add support for AR5210 EEPROM */
+ if (ah->ah_version == AR5K_AR5210)
+ return;
+
/* Adjust power delta for channel 14 */
if (channel->center_freq == 2484)
cck_ofdm_pwr_delta =
@@ -772,7 +913,7 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
AR5K_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]),
AR5K_PHY_NFTHRES);
- if ((channel->hw_value & CHANNEL_TURBO) &&
+ if ((ah->ah_bwmode == AR5K_BWMODE_40MHZ) &&
(ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_0)) {
/* Switch settling time (Turbo) */
AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING,
@@ -870,143 +1011,183 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
ath5k_hw_reg_write(ah, 0, AR5K_PHY_HEAVY_CLIP_ENABLE);
}
-/*
- * Main reset function
- */
+
+/*********************\
+* Main reset function *
+\*********************/
+
int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
- struct ieee80211_channel *channel, bool change_channel)
+ struct ieee80211_channel *channel, bool fast, bool skip_pcu)
{
- struct ath_common *common = ath5k_hw_common(ah);
- u32 s_seq[10], s_led[3], staid1_flags, tsf_up, tsf_lo;
- u32 phy_tst1;
+ u32 s_seq[10], s_led[3], tsf_up, tsf_lo;
u8 mode, freq, ee_mode;
int i, ret;
ee_mode = 0;
- staid1_flags = 0;
tsf_up = 0;
tsf_lo = 0;
freq = 0;
mode = 0;
/*
- * Save some registers before a reset
+ * Sanity check for fast flag
+ * Fast channel change only available
+ * on AR2413/AR5413.
*/
- /*DCU/Antenna selection not available on 5210*/
- if (ah->ah_version != AR5K_AR5210) {
+ if (fast && (ah->ah_radio != AR5K_RF2413) &&
+ (ah->ah_radio != AR5K_RF5413))
+ fast = 0;
- switch (channel->hw_value & CHANNEL_MODES) {
- case CHANNEL_A:
- mode = AR5K_MODE_11A;
- freq = AR5K_INI_RFGAIN_5GHZ;
- ee_mode = AR5K_EEPROM_MODE_11A;
- break;
- case CHANNEL_G:
- mode = AR5K_MODE_11G;
- freq = AR5K_INI_RFGAIN_2GHZ;
- ee_mode = AR5K_EEPROM_MODE_11G;
- break;
- case CHANNEL_B:
- mode = AR5K_MODE_11B;
- freq = AR5K_INI_RFGAIN_2GHZ;
- ee_mode = AR5K_EEPROM_MODE_11B;
- break;
- case CHANNEL_T:
- mode = AR5K_MODE_11A_TURBO;
- freq = AR5K_INI_RFGAIN_5GHZ;
- ee_mode = AR5K_EEPROM_MODE_11A;
- break;
- case CHANNEL_TG:
- if (ah->ah_version == AR5K_AR5211) {
- ATH5K_ERR(ah->ah_sc,
- "TurboG mode not available on 5211");
- return -EINVAL;
- }
- mode = AR5K_MODE_11G_TURBO;
- freq = AR5K_INI_RFGAIN_2GHZ;
- ee_mode = AR5K_EEPROM_MODE_11G;
- break;
- case CHANNEL_XR:
- if (ah->ah_version == AR5K_AR5211) {
- ATH5K_ERR(ah->ah_sc,
- "XR mode not available on 5211");
- return -EINVAL;
- }
- mode = AR5K_MODE_XR;
- freq = AR5K_INI_RFGAIN_5GHZ;
- ee_mode = AR5K_EEPROM_MODE_11A;
- break;
- default:
+ /* Disable sleep clock operation
+ * to avoid register access delay on certain
+ * PHY registers */
+ if (ah->ah_version == AR5K_AR5212)
+ ath5k_hw_set_sleep_clock(ah, false);
+
+ /*
+ * Stop PCU
+ */
+ ath5k_hw_stop_rx_pcu(ah);
+
+ /*
+ * Stop DMA
+ *
+ * Note: If DMA didn't stop continue
+ * since only a reset will fix it.
+ */
+ ret = ath5k_hw_dma_stop(ah);
+
+ /* RF Bus grant won't work if we have pending
+ * frames */
+ if (ret && fast) {
+ ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_RESET,
+ "DMA didn't stop, falling back to normal reset\n");
+ fast = 0;
+ /* Non fatal, just continue with
+ * normal reset */
+ ret = 0;
+ }
+
+ switch (channel->hw_value & CHANNEL_MODES) {
+ case CHANNEL_A:
+ mode = AR5K_MODE_11A;
+ freq = AR5K_INI_RFGAIN_5GHZ;
+ ee_mode = AR5K_EEPROM_MODE_11A;
+ break;
+ case CHANNEL_G:
+
+ if (ah->ah_version <= AR5K_AR5211) {
ATH5K_ERR(ah->ah_sc,
- "invalid channel: %d\n", channel->center_freq);
+ "G mode not available on 5210/5211");
return -EINVAL;
}
- if (change_channel) {
- /*
- * Save frame sequence count
- * For revs. after Oahu, only save
- * seq num for DCU 0 (Global seq num)
- */
- if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
-
- for (i = 0; i < 10; i++)
- s_seq[i] = ath5k_hw_reg_read(ah,
- AR5K_QUEUE_DCU_SEQNUM(i));
+ mode = AR5K_MODE_11G;
+ freq = AR5K_INI_RFGAIN_2GHZ;
+ ee_mode = AR5K_EEPROM_MODE_11G;
+ break;
+ case CHANNEL_B:
- } else {
- s_seq[0] = ath5k_hw_reg_read(ah,
- AR5K_QUEUE_DCU_SEQNUM(0));
- }
+ if (ah->ah_version < AR5K_AR5211) {
+ ATH5K_ERR(ah->ah_sc,
+ "B mode not available on 5210");
+ return -EINVAL;
+ }
- /* TSF accelerates on AR5211 during reset
- * As a workaround save it here and restore
- * it later so that it's back in time after
- * reset. This way it'll get re-synced on the
- * next beacon without breaking ad-hoc.
- *
- * On AR5212 TSF is almost preserved across a
- * reset so it stays back in time anyway and
- * we don't have to save/restore it.
- *
- * XXX: Since this breaks power saving we have
- * to disable power saving until we receive the
- * next beacon, so we can resync beacon timers */
- if (ah->ah_version == AR5K_AR5211) {
- tsf_up = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
- tsf_lo = ath5k_hw_reg_read(ah, AR5K_TSF_L32);
- }
+ mode = AR5K_MODE_11B;
+ freq = AR5K_INI_RFGAIN_2GHZ;
+ ee_mode = AR5K_EEPROM_MODE_11B;
+ break;
+ case CHANNEL_XR:
+ if (ah->ah_version == AR5K_AR5211) {
+ ATH5K_ERR(ah->ah_sc,
+ "XR mode not available on 5211");
+ return -EINVAL;
}
+ mode = AR5K_MODE_XR;
+ freq = AR5K_INI_RFGAIN_5GHZ;
+ ee_mode = AR5K_EEPROM_MODE_11A;
+ break;
+ default:
+ ATH5K_ERR(ah->ah_sc,
+ "invalid channel: %d\n", channel->center_freq);
+ return -EINVAL;
+ }
- if (ah->ah_version == AR5K_AR5212) {
- /* Restore normal 32/40MHz clock operation
- * to avoid register access delay on certain
- * PHY registers */
- ath5k_hw_set_sleep_clock(ah, false);
+ /*
+ * If driver requested fast channel change and DMA has stopped
+ * go on. If it fails continue with a normal reset.
+ */
+ if (fast) {
+ ret = ath5k_hw_phy_init(ah, channel, mode,
+ ee_mode, freq, true);
+ if (ret) {
+ ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_RESET,
+ "fast chan change failed, falling back to normal reset\n");
+ /* Non fatal, can happen eg.
+ * on mode change */
+ ret = 0;
+ } else
+ return 0;
+ }
- /* Since we are going to write rf buffer
- * check if we have any pending gain_F
- * optimization settings */
- if (change_channel && ah->ah_rf_banks != NULL)
- ath5k_hw_gainf_calibrate(ah);
+ /*
+ * Save some registers before a reset
+ */
+ if (ah->ah_version != AR5K_AR5210) {
+ /*
+ * Save frame sequence count
+ * For revs. after Oahu, only save
+ * seq num for DCU 0 (Global seq num)
+ */
+ if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
+
+ for (i = 0; i < 10; i++)
+ s_seq[i] = ath5k_hw_reg_read(ah,
+ AR5K_QUEUE_DCU_SEQNUM(i));
+
+ } else {
+ s_seq[0] = ath5k_hw_reg_read(ah,
+ AR5K_QUEUE_DCU_SEQNUM(0));
+ }
+
+ /* TSF accelerates on AR5211 during reset
+ * As a workaround save it here and restore
+ * it later so that it's back in time after
+ * reset. This way it'll get re-synced on the
+ * next beacon without breaking ad-hoc.
+ *
+ * On AR5212 TSF is almost preserved across a
+ * reset so it stays back in time anyway and
+ * we don't have to save/restore it.
+ *
+ * XXX: Since this breaks power saving we have
+ * to disable power saving until we receive the
+ * next beacon, so we can resync beacon timers */
+ if (ah->ah_version == AR5K_AR5211) {
+ tsf_up = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
+ tsf_lo = ath5k_hw_reg_read(ah, AR5K_TSF_L32);
}
}
+
/*GPIOs*/
s_led[0] = ath5k_hw_reg_read(ah, AR5K_PCICFG) &
AR5K_PCICFG_LEDSTATE;
s_led[1] = ath5k_hw_reg_read(ah, AR5K_GPIOCR);
s_led[2] = ath5k_hw_reg_read(ah, AR5K_GPIODO);
- /* AR5K_STA_ID1 flags, only preserve antenna
- * settings and ack/cts rate mode */
- staid1_flags = ath5k_hw_reg_read(ah, AR5K_STA_ID1) &
- (AR5K_STA_ID1_DEFAULT_ANTENNA |
- AR5K_STA_ID1_DESC_ANTENNA |
- AR5K_STA_ID1_RTS_DEF_ANTENNA |
- AR5K_STA_ID1_ACKCTS_6MB |
- AR5K_STA_ID1_BASE_RATE_11B |
- AR5K_STA_ID1_SELFGEN_DEF_ANT);
+
+ /*
+ * Since we are going to write rf buffer
+ * check if we have any pending gain_F
+ * optimization settings
+ */
+ if (ah->ah_version == AR5K_AR5212 &&
+ (ah->ah_radio <= AR5K_RF5112)) {
+ if (!fast && ah->ah_rf_banks != NULL)
+ ath5k_hw_gainf_calibrate(ah);
+ }
/* Wakeup the device */
ret = ath5k_hw_nic_wakeup(ah, channel->hw_value, false);
@@ -1021,121 +1202,42 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
AR5K_PHY(0));
/* Write initial settings */
- ret = ath5k_hw_write_initvals(ah, mode, change_channel);
+ ret = ath5k_hw_write_initvals(ah, mode, skip_pcu);
if (ret)
return ret;
+ /* Initialize core clock settings */
+ ath5k_hw_init_core_clock(ah);
+
/*
- * 5211/5212 Specific
+ * Tweak initval settings for revised
+ * chipsets and add some more config
+ * bits
*/
- if (ah->ah_version != AR5K_AR5210) {
-
- /*
- * Write initial RF gain settings
- * This should work for both 5111/5112
- */
- ret = ath5k_hw_rfgain_init(ah, freq);
- if (ret)
- return ret;
-
- mdelay(1);
-
- /*
- * Tweak initval settings for revised
- * chipsets and add some more config
- * bits
- */
- ath5k_hw_tweak_initval_settings(ah, channel);
-
- /*
- * Set TX power
- */
- ret = ath5k_hw_txpower(ah, channel, ee_mode,
- ah->ah_txpower.txp_max_pwr / 2);
- if (ret)
- return ret;
+ ath5k_hw_tweak_initval_settings(ah, channel);
- /* Write rate duration table only on AR5212 and if
- * virtual interface has already been brought up
- * XXX: rethink this after new mode changes to
- * mac80211 are integrated */
- if (ah->ah_version == AR5K_AR5212 &&
- ah->ah_sc->nvifs)
- ath5k_hw_write_rate_duration(ah, mode);
+ /* Commit values from EEPROM */
+ ath5k_hw_commit_eeprom_settings(ah, channel, ee_mode);
- /*
- * Write RF buffer
- */
- ret = ath5k_hw_rfregs_init(ah, channel, mode);
- if (ret)
- return ret;
-
-
- /* Write OFDM timings on 5212*/
- if (ah->ah_version == AR5K_AR5212 &&
- channel->hw_value & CHANNEL_OFDM) {
-
- ret = ath5k_hw_write_ofdm_timings(ah, channel);
- if (ret)
- return ret;
-
- /* Spur info is available only from EEPROM versions
- * greater than 5.3, but the EEPROM routines will use
- * static values for older versions */
- if (ah->ah_mac_srev >= AR5K_SREV_AR5424)
- ath5k_hw_set_spur_mitigation_filter(ah,
- channel);
- }
-
- /*Enable/disable 802.11b mode on 5111
- (enable 2111 frequency converter + CCK)*/
- if (ah->ah_radio == AR5K_RF5111) {
- if (mode == AR5K_MODE_11B)
- AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG,
- AR5K_TXCFG_B_MODE);
- else
- AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG,
- AR5K_TXCFG_B_MODE);
- }
-
- /* Commit values from EEPROM */
- ath5k_hw_commit_eeprom_settings(ah, channel, ee_mode);
-
- } else {
- /*
- * For 5210 we do all initialization using
- * initvals, so we don't have to modify
- * any settings (5210 also only supports
- * a/aturbo modes)
- */
- mdelay(1);
- /* Disable phy and wait */
- ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
- mdelay(1);
- }
/*
* Restore saved values
*/
- /*DCU/Antenna selection not available on 5210*/
+ /* Seqnum, TSF */
if (ah->ah_version != AR5K_AR5210) {
+ if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
+ for (i = 0; i < 10; i++)
+ ath5k_hw_reg_write(ah, s_seq[i],
+ AR5K_QUEUE_DCU_SEQNUM(i));
+ } else {
+ ath5k_hw_reg_write(ah, s_seq[0],
+ AR5K_QUEUE_DCU_SEQNUM(0));
+ }
- if (change_channel) {
- if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
- for (i = 0; i < 10; i++)
- ath5k_hw_reg_write(ah, s_seq[i],
- AR5K_QUEUE_DCU_SEQNUM(i));
- } else {
- ath5k_hw_reg_write(ah, s_seq[0],
- AR5K_QUEUE_DCU_SEQNUM(0));
- }
-
-
- if (ah->ah_version == AR5K_AR5211) {
- ath5k_hw_reg_write(ah, tsf_up, AR5K_TSF_U32);
- ath5k_hw_reg_write(ah, tsf_lo, AR5K_TSF_L32);
- }
+ if (ah->ah_version == AR5K_AR5211) {
+ ath5k_hw_reg_write(ah, tsf_up, AR5K_TSF_U32);
+ ath5k_hw_reg_write(ah, tsf_lo, AR5K_TSF_L32);
}
}
@@ -1146,203 +1248,34 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
ath5k_hw_reg_write(ah, s_led[1], AR5K_GPIOCR);
ath5k_hw_reg_write(ah, s_led[2], AR5K_GPIODO);
- /* Restore sta_id flags and preserve our mac address*/
- ath5k_hw_reg_write(ah,
- get_unaligned_le32(common->macaddr),
- AR5K_STA_ID0);
- ath5k_hw_reg_write(ah,
- staid1_flags | get_unaligned_le16(common->macaddr + 4),
- AR5K_STA_ID1);
-
-
/*
- * Configure PCU
+ * Initialize PCU
*/
-
- /* Restore bssid and bssid mask */
- ath5k_hw_set_bssid(ah);
-
- /* Set PCU config */
- ath5k_hw_set_opmode(ah, op_mode);
-
- /* Clear any pending interrupts
- * PISR/SISR Not available on 5210 */
- if (ah->ah_version != AR5K_AR5210)
- ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR);
-
- /* Set RSSI/BRSSI thresholds
- *
- * Note: If we decide to set this value
- * dynamically, keep in mind that when AR5K_RSSI_THR
- * register is read, it might return 0x40 if we haven't
- * written anything to it. Also, BMISS RSSI threshold is zeroed.
- * So doing a save/restore procedure here isn't the right
- * choice. Instead, store it in ath5k_hw */
- ath5k_hw_reg_write(ah, (AR5K_TUNE_RSSI_THRES |
- AR5K_TUNE_BMISS_THRES <<
- AR5K_RSSI_THR_BMISS_S),
- AR5K_RSSI_THR);
-
- /* MIC QoS support */
- if (ah->ah_mac_srev >= AR5K_SREV_AR2413) {
- ath5k_hw_reg_write(ah, 0x000100aa, AR5K_MIC_QOS_CTL);
- ath5k_hw_reg_write(ah, 0x00003210, AR5K_MIC_QOS_SEL);
- }
-
- /* QoS NOACK Policy */
- if (ah->ah_version == AR5K_AR5212) {
- ath5k_hw_reg_write(ah,
- AR5K_REG_SM(2, AR5K_QOS_NOACK_2BIT_VALUES) |
- AR5K_REG_SM(5, AR5K_QOS_NOACK_BIT_OFFSET) |
- AR5K_REG_SM(0, AR5K_QOS_NOACK_BYTE_OFFSET),
- AR5K_QOS_NOACK);
- }
-
+ ath5k_hw_pcu_init(ah, op_mode, mode);
/*
- * Configure PHY
+ * Initialize PHY
*/
-
- /* Set channel on PHY */
- ret = ath5k_hw_channel(ah, channel);
- if (ret)
+ ret = ath5k_hw_phy_init(ah, channel, mode, ee_mode, freq, false);
+ if (ret) {
+ ATH5K_ERR(ah->ah_sc,
+ "failed to initialize PHY (%i) !\n", ret);
return ret;
-
- /*
- * Enable the PHY and wait until completion
- * This includes BaseBand and Synthesizer
- * activation.
- */
- ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT);
-
- /*
- * On 5211+ read activation -> rx delay
- * and use it.
- *
- * TODO: Half/quarter rate support
- */
- if (ah->ah_version != AR5K_AR5210) {
- u32 delay;
- delay = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) &
- AR5K_PHY_RX_DELAY_M;
- delay = (channel->hw_value & CHANNEL_CCK) ?
- ((delay << 2) / 22) : (delay / 10);
-
- udelay(100 + (2 * delay));
- } else {
- mdelay(1);
}
/*
- * Perform ADC test to see if baseband is ready
- * Set TX hold and check ADC test register
- */
- phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1);
- ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1);
- for (i = 0; i <= 20; i++) {
- if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10))
- break;
- udelay(200);
- }
- ath5k_hw_reg_write(ah, phy_tst1, AR5K_PHY_TST1);
-
- /*
- * Start automatic gain control calibration
- *
- * During AGC calibration RX path is re-routed to
- * a power detector so we don't receive anything.
- *
- * This method is used to calibrate some static offsets
- * used together with on-the fly I/Q calibration (the
- * one performed via ath5k_hw_phy_calibrate), which doesn't
- * interrupt rx path.
- *
- * While rx path is re-routed to the power detector we also
- * start a noise floor calibration to measure the
- * card's noise floor (the noise we measure when we are not
- * transmitting or receiving anything).
- *
- * If we are in a noisy environment, AGC calibration may time
- * out and/or noise floor calibration might timeout.
- */
- AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
- AR5K_PHY_AGCCTL_CAL | AR5K_PHY_AGCCTL_NF);
-
- /* At the same time start I/Q calibration for QAM constellation
- * -no need for CCK- */
- ah->ah_calibration = false;
- if (!(mode == AR5K_MODE_11B)) {
- ah->ah_calibration = true;
- AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ,
- AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15);
- AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
- AR5K_PHY_IQ_RUN);
- }
-
- /* Wait for gain calibration to finish (we check for I/Q calibration
- * during ath5k_phy_calibrate) */
- if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
- AR5K_PHY_AGCCTL_CAL, 0, false)) {
- ATH5K_ERR(ah->ah_sc, "gain calibration timeout (%uMHz)\n",
- channel->center_freq);
- }
-
- /* Restore antenna mode */
- ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode);
-
- /* Restore slot time and ACK timeouts */
- if (ah->ah_coverage_class > 0)
- ath5k_hw_set_coverage_class(ah, ah->ah_coverage_class);
-
- /*
* Configure QCUs/DCUs
*/
+ ret = ath5k_hw_init_queues(ah);
+ if (ret)
+ return ret;
- /* TODO: HW Compression support for data queues */
- /* TODO: Burst prefetch for data queues */
-
- /*
- * Reset queues and start beacon timers at the end of the reset routine
- * This also sets QCU mask on each DCU for 1:1 qcu to dcu mapping
- * Note: If we want we can assign multiple qcus on one dcu.
- */
- for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) {
- ret = ath5k_hw_reset_tx_queue(ah, i);
- if (ret) {
- ATH5K_ERR(ah->ah_sc,
- "failed to reset TX queue #%d\n", i);
- return ret;
- }
- }
-
-
- /*
- * Configure DMA/Interrupts
- */
/*
- * Set Rx/Tx DMA Configuration
- *
- * Set standard DMA size (128). Note that
- * a DMA size of 512 causes rx overruns and tx errors
- * on pci-e cards (tested on 5424 but since rx overruns
- * also occur on 5416/5418 with madwifi we set 128
- * for all PCI-E cards to be safe).
- *
- * XXX: need to check 5210 for this
- * TODO: Check out tx triger level, it's always 64 on dumps but I
- * guess we can tweak it and see how it goes ;-)
+ * Initialize DMA/Interrupts
*/
- if (ah->ah_version != AR5K_AR5210) {
- AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
- AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B);
- AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG,
- AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_128B);
- }
+ ath5k_hw_dma_init(ah);
- /* Pre-enable interrupts on 5211/5212*/
- if (ah->ah_version != AR5K_AR5210)
- ath5k_hw_set_imr(ah, ah->ah_imr);
/* Enable 32KHz clock function for AR5212+ chips
* Set clocks to 32KHz operation and use an
diff --git a/drivers/net/wireless/ath/ath5k/rfbuffer.h b/drivers/net/wireless/ath/ath5k/rfbuffer.h
index 3ac4cff4239d..16b67e84906d 100644
--- a/drivers/net/wireless/ath/ath5k/rfbuffer.h
+++ b/drivers/net/wireless/ath/ath5k/rfbuffer.h
@@ -51,7 +51,7 @@
struct ath5k_ini_rfbuffer {
u8 rfb_bank; /* RF Bank number */
u16 rfb_ctrl_register; /* RF Buffer control register */
- u32 rfb_mode_data[5]; /* RF Buffer data for each mode */
+ u32 rfb_mode_data[3]; /* RF Buffer data for each mode */
};
/*
@@ -79,8 +79,10 @@ struct ath5k_rf_reg {
* life easier by using an index for each register
* instead of a full rfb_field */
enum ath5k_rf_regs_idx {
+ /* BANK 2 */
+ AR5K_RF_TURBO = 0,
/* BANK 6 */
- AR5K_RF_OB_2GHZ = 0,
+ AR5K_RF_OB_2GHZ,
AR5K_RF_OB_5GHZ,
AR5K_RF_DB_2GHZ,
AR5K_RF_DB_5GHZ,
@@ -134,6 +136,9 @@ enum ath5k_rf_regs_idx {
* RF5111 (Sombrero) *
\*******************/
+/* BANK 2 len pos col */
+#define AR5K_RF5111_RF_TURBO { 1, 3, 0 }
+
/* BANK 6 len pos col */
#define AR5K_RF5111_OB_2GHZ { 3, 119, 0 }
#define AR5K_RF5111_DB_2GHZ { 3, 122, 0 }
@@ -158,6 +163,7 @@ enum ath5k_rf_regs_idx {
#define AR5K_RF5111_MAX_TIME { 2, 49, 0 }
static const struct ath5k_rf_reg rf_regs_5111[] = {
+ {2, AR5K_RF_TURBO, AR5K_RF5111_RF_TURBO},
{6, AR5K_RF_OB_2GHZ, AR5K_RF5111_OB_2GHZ},
{6, AR5K_RF_DB_2GHZ, AR5K_RF5111_DB_2GHZ},
{6, AR5K_RF_OB_5GHZ, AR5K_RF5111_OB_5GHZ},
@@ -177,97 +183,52 @@ static const struct ath5k_rf_reg rf_regs_5111[] = {
/* Default mode specific settings */
static const struct ath5k_ini_rfbuffer rfb_5111[] = {
- { 0, 0x989c,
- /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00380000, 0x00380000, 0x00380000, 0x00380000, 0x00380000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x000000c0, 0x00000080, 0x00000080 } },
- { 0, 0x989c,
- { 0x000400f9, 0x000400f9, 0x000400ff, 0x000400fd, 0x000400fd } },
- { 0, 0x98d4,
- { 0x00000000, 0x00000000, 0x00000004, 0x00000004, 0x00000004 } },
- { 1, 0x98d4,
- { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
- { 2, 0x98d4,
- { 0x00000010, 0x00000014, 0x00000010, 0x00000010, 0x00000014 } },
- { 3, 0x98d8,
- { 0x00601068, 0x00601068, 0x00601068, 0x00601068, 0x00601068 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
- { 6, 0x989c,
- { 0x04000000, 0x04000000, 0x04000000, 0x04000000, 0x04000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x0a000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x003800c0, 0x00380080, 0x023800c0, 0x003800c0, 0x003800c0 } },
- { 6, 0x989c,
- { 0x00020006, 0x00020006, 0x00000006, 0x00020006, 0x00020006 } },
- { 6, 0x989c,
- { 0x00000089, 0x00000089, 0x00000089, 0x00000089, 0x00000089 } },
- { 6, 0x989c,
- { 0x000000a0, 0x000000a0, 0x000000a0, 0x000000a0, 0x000000a0 } },
- { 6, 0x989c,
- { 0x00040007, 0x00040007, 0x00040007, 0x00040007, 0x00040007 } },
- { 6, 0x98d4,
- { 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a } },
- { 7, 0x989c,
- { 0x00000040, 0x00000048, 0x00000040, 0x00000040, 0x00000040 } },
- { 7, 0x989c,
- { 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 } },
- { 7, 0x989c,
- { 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008 } },
- { 7, 0x989c,
- { 0x0000004f, 0x0000004f, 0x0000004f, 0x0000004f, 0x0000004f } },
- { 7, 0x989c,
- { 0x000000f1, 0x000000f1, 0x00000061, 0x000000f1, 0x000000f1 } },
- { 7, 0x989c,
- { 0x0000904f, 0x0000904f, 0x0000904c, 0x0000904f, 0x0000904f } },
- { 7, 0x989c,
- { 0x0000125a, 0x0000125a, 0x0000129a, 0x0000125a, 0x0000125a } },
- { 7, 0x98cc,
- { 0x0000000e, 0x0000000e, 0x0000000f, 0x0000000e, 0x0000000e } },
+ /* BANK / C.R. A/XR B G */
+ { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c, { 0x00380000, 0x00380000, 0x00380000 } },
+ { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c, { 0x00000000, 0x000000c0, 0x00000080 } },
+ { 0, 0x989c, { 0x000400f9, 0x000400ff, 0x000400fd } },
+ { 0, 0x98d4, { 0x00000000, 0x00000004, 0x00000004 } },
+ { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } },
+ { 2, 0x98d4, { 0x00000010, 0x00000010, 0x00000010 } },
+ { 3, 0x98d8, { 0x00601068, 0x00601068, 0x00601068 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x10000000, 0x10000000, 0x10000000 } },
+ { 6, 0x989c, { 0x04000000, 0x04000000, 0x04000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x0a000000, 0x00000000 } },
+ { 6, 0x989c, { 0x003800c0, 0x023800c0, 0x003800c0 } },
+ { 6, 0x989c, { 0x00020006, 0x00000006, 0x00020006 } },
+ { 6, 0x989c, { 0x00000089, 0x00000089, 0x00000089 } },
+ { 6, 0x989c, { 0x000000a0, 0x000000a0, 0x000000a0 } },
+ { 6, 0x989c, { 0x00040007, 0x00040007, 0x00040007 } },
+ { 6, 0x98d4, { 0x0000001a, 0x0000001a, 0x0000001a } },
+ { 7, 0x989c, { 0x00000040, 0x00000040, 0x00000040 } },
+ { 7, 0x989c, { 0x00000010, 0x00000010, 0x00000010 } },
+ { 7, 0x989c, { 0x00000008, 0x00000008, 0x00000008 } },
+ { 7, 0x989c, { 0x0000004f, 0x0000004f, 0x0000004f } },
+ { 7, 0x989c, { 0x000000f1, 0x00000061, 0x000000f1 } },
+ { 7, 0x989c, { 0x0000904f, 0x0000904c, 0x0000904f } },
+ { 7, 0x989c, { 0x0000125a, 0x0000129a, 0x0000125a } },
+ { 7, 0x98cc, { 0x0000000e, 0x0000000f, 0x0000000e } },
};
@@ -276,6 +237,9 @@ static const struct ath5k_ini_rfbuffer rfb_5111[] = {
* RF5112/RF2112 (Derby) *
\***********************/
+/* BANK 2 (Common) len pos col */
+#define AR5K_RF5112X_RF_TURBO { 1, 1, 2 }
+
/* BANK 7 (Common) len pos col */
#define AR5K_RF5112X_GAIN_I { 6, 14, 0 }
#define AR5K_RF5112X_MIXVGA_OVR { 1, 36, 0 }
@@ -307,6 +271,7 @@ static const struct ath5k_ini_rfbuffer rfb_5111[] = {
#define AR5K_RF5112_PWD(_n) { 1, (302 - _n), 3 }
static const struct ath5k_rf_reg rf_regs_5112[] = {
+ {2, AR5K_RF_TURBO, AR5K_RF5112X_RF_TURBO},
{6, AR5K_RF_OB_2GHZ, AR5K_RF5112_OB_2GHZ},
{6, AR5K_RF_DB_2GHZ, AR5K_RF5112_DB_2GHZ},
{6, AR5K_RF_OB_5GHZ, AR5K_RF5112_OB_5GHZ},
@@ -335,115 +300,61 @@ static const struct ath5k_rf_reg rf_regs_5112[] = {
/* Default mode specific settings */
static const struct ath5k_ini_rfbuffer rfb_5112[] = {
- { 1, 0x98d4,
- /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
- { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
- { 2, 0x98d0,
- { 0x03060408, 0x03070408, 0x03060408, 0x03060408, 0x03070408 } },
- { 3, 0x98dc,
- { 0x00a0c0c0, 0x00a0c0c0, 0x00e0c0c0, 0x00e0c0c0, 0x00e0c0c0 } },
- { 6, 0x989c,
- { 0x00a00000, 0x00a00000, 0x00a00000, 0x00a00000, 0x00a00000 } },
- { 6, 0x989c,
- { 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00660000, 0x00660000, 0x00660000, 0x00660000, 0x00660000 } },
- { 6, 0x989c,
- { 0x00db0000, 0x00db0000, 0x00db0000, 0x00db0000, 0x00db0000 } },
- { 6, 0x989c,
- { 0x00f10000, 0x00f10000, 0x00f10000, 0x00f10000, 0x00f10000 } },
- { 6, 0x989c,
- { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
- { 6, 0x989c,
- { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
- { 6, 0x989c,
- { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
- { 6, 0x989c,
- { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
- { 6, 0x989c,
- { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
- { 6, 0x989c,
- { 0x008b0000, 0x008b0000, 0x008b0000, 0x008b0000, 0x008b0000 } },
- { 6, 0x989c,
- { 0x00600000, 0x00600000, 0x00600000, 0x00600000, 0x00600000 } },
- { 6, 0x989c,
- { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
- { 6, 0x989c,
- { 0x00840000, 0x00840000, 0x00840000, 0x00840000, 0x00840000 } },
- { 6, 0x989c,
- { 0x00640000, 0x00640000, 0x00640000, 0x00640000, 0x00640000 } },
- { 6, 0x989c,
- { 0x00200000, 0x00200000, 0x00200000, 0x00200000, 0x00200000 } },
- { 6, 0x989c,
- { 0x00240000, 0x00240000, 0x00240000, 0x00240000, 0x00240000 } },
- { 6, 0x989c,
- { 0x00250000, 0x00250000, 0x00250000, 0x00250000, 0x00250000 } },
- { 6, 0x989c,
- { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
- { 6, 0x989c,
- { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
- { 6, 0x989c,
- { 0x00510000, 0x00510000, 0x00510000, 0x00510000, 0x00510000 } },
- { 6, 0x989c,
- { 0x1c040000, 0x1c040000, 0x1c040000, 0x1c040000, 0x1c040000 } },
- { 6, 0x989c,
- { 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000 } },
- { 6, 0x989c,
- { 0x00a10000, 0x00a10000, 0x00a10000, 0x00a10000, 0x00a10000 } },
- { 6, 0x989c,
- { 0x00400000, 0x00400000, 0x00400000, 0x00400000, 0x00400000 } },
- { 6, 0x989c,
- { 0x03090000, 0x03090000, 0x03090000, 0x03090000, 0x03090000 } },
- { 6, 0x989c,
- { 0x06000000, 0x06000000, 0x06000000, 0x06000000, 0x06000000 } },
- { 6, 0x989c,
- { 0x000000b0, 0x000000b0, 0x000000a8, 0x000000a8, 0x000000a8 } },
- { 6, 0x989c,
- { 0x0000002e, 0x0000002e, 0x0000002e, 0x0000002e, 0x0000002e } },
- { 6, 0x989c,
- { 0x006c4a41, 0x006c4a41, 0x006c4af1, 0x006c4a61, 0x006c4a61 } },
- { 6, 0x989c,
- { 0x0050892a, 0x0050892a, 0x0050892b, 0x0050892b, 0x0050892b } },
- { 6, 0x989c,
- { 0x00842400, 0x00842400, 0x00842400, 0x00842400, 0x00842400 } },
- { 6, 0x989c,
- { 0x00c69200, 0x00c69200, 0x00c69200, 0x00c69200, 0x00c69200 } },
- { 6, 0x98d0,
- { 0x0002000c, 0x0002000c, 0x0002000c, 0x0002000c, 0x0002000c } },
- { 7, 0x989c,
- { 0x00000094, 0x00000094, 0x00000094, 0x00000094, 0x00000094 } },
- { 7, 0x989c,
- { 0x00000091, 0x00000091, 0x00000091, 0x00000091, 0x00000091 } },
- { 7, 0x989c,
- { 0x0000000a, 0x0000000a, 0x00000012, 0x00000012, 0x00000012 } },
- { 7, 0x989c,
- { 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080 } },
- { 7, 0x989c,
- { 0x000000c1, 0x000000c1, 0x000000c1, 0x000000c1, 0x000000c1 } },
- { 7, 0x989c,
- { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } },
- { 7, 0x989c,
- { 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0 } },
- { 7, 0x989c,
- { 0x00000022, 0x00000022, 0x00000022, 0x00000022, 0x00000022 } },
- { 7, 0x989c,
- { 0x00000092, 0x00000092, 0x00000092, 0x00000092, 0x00000092 } },
- { 7, 0x989c,
- { 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4 } },
- { 7, 0x989c,
- { 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc } },
- { 7, 0x989c,
- { 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c } },
- { 7, 0x98c4,
- { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
+ /* BANK / C.R. A/XR B G */
+ { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } },
+ { 2, 0x98d0, { 0x03060408, 0x03060408, 0x03060408 } },
+ { 3, 0x98dc, { 0x00a0c0c0, 0x00e0c0c0, 0x00e0c0c0 } },
+ { 6, 0x989c, { 0x00a00000, 0x00a00000, 0x00a00000 } },
+ { 6, 0x989c, { 0x000a0000, 0x000a0000, 0x000a0000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00660000, 0x00660000, 0x00660000 } },
+ { 6, 0x989c, { 0x00db0000, 0x00db0000, 0x00db0000 } },
+ { 6, 0x989c, { 0x00f10000, 0x00f10000, 0x00f10000 } },
+ { 6, 0x989c, { 0x00120000, 0x00120000, 0x00120000 } },
+ { 6, 0x989c, { 0x00120000, 0x00120000, 0x00120000 } },
+ { 6, 0x989c, { 0x00730000, 0x00730000, 0x00730000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x000c0000, 0x000c0000, 0x000c0000 } },
+ { 6, 0x989c, { 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+ { 6, 0x989c, { 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+ { 6, 0x989c, { 0x008b0000, 0x008b0000, 0x008b0000 } },
+ { 6, 0x989c, { 0x00600000, 0x00600000, 0x00600000 } },
+ { 6, 0x989c, { 0x000c0000, 0x000c0000, 0x000c0000 } },
+ { 6, 0x989c, { 0x00840000, 0x00840000, 0x00840000 } },
+ { 6, 0x989c, { 0x00640000, 0x00640000, 0x00640000 } },
+ { 6, 0x989c, { 0x00200000, 0x00200000, 0x00200000 } },
+ { 6, 0x989c, { 0x00240000, 0x00240000, 0x00240000 } },
+ { 6, 0x989c, { 0x00250000, 0x00250000, 0x00250000 } },
+ { 6, 0x989c, { 0x00110000, 0x00110000, 0x00110000 } },
+ { 6, 0x989c, { 0x00110000, 0x00110000, 0x00110000 } },
+ { 6, 0x989c, { 0x00510000, 0x00510000, 0x00510000 } },
+ { 6, 0x989c, { 0x1c040000, 0x1c040000, 0x1c040000 } },
+ { 6, 0x989c, { 0x000a0000, 0x000a0000, 0x000a0000 } },
+ { 6, 0x989c, { 0x00a10000, 0x00a10000, 0x00a10000 } },
+ { 6, 0x989c, { 0x00400000, 0x00400000, 0x00400000 } },
+ { 6, 0x989c, { 0x03090000, 0x03090000, 0x03090000 } },
+ { 6, 0x989c, { 0x06000000, 0x06000000, 0x06000000 } },
+ { 6, 0x989c, { 0x000000b0, 0x000000a8, 0x000000a8 } },
+ { 6, 0x989c, { 0x0000002e, 0x0000002e, 0x0000002e } },
+ { 6, 0x989c, { 0x006c4a41, 0x006c4af1, 0x006c4a61 } },
+ { 6, 0x989c, { 0x0050892a, 0x0050892b, 0x0050892b } },
+ { 6, 0x989c, { 0x00842400, 0x00842400, 0x00842400 } },
+ { 6, 0x989c, { 0x00c69200, 0x00c69200, 0x00c69200 } },
+ { 6, 0x98d0, { 0x0002000c, 0x0002000c, 0x0002000c } },
+ { 7, 0x989c, { 0x00000094, 0x00000094, 0x00000094 } },
+ { 7, 0x989c, { 0x00000091, 0x00000091, 0x00000091 } },
+ { 7, 0x989c, { 0x0000000a, 0x00000012, 0x00000012 } },
+ { 7, 0x989c, { 0x00000080, 0x00000080, 0x00000080 } },
+ { 7, 0x989c, { 0x000000c1, 0x000000c1, 0x000000c1 } },
+ { 7, 0x989c, { 0x00000060, 0x00000060, 0x00000060 } },
+ { 7, 0x989c, { 0x000000f0, 0x000000f0, 0x000000f0 } },
+ { 7, 0x989c, { 0x00000022, 0x00000022, 0x00000022 } },
+ { 7, 0x989c, { 0x00000092, 0x00000092, 0x00000092 } },
+ { 7, 0x989c, { 0x000000d4, 0x000000d4, 0x000000d4 } },
+ { 7, 0x989c, { 0x000014cc, 0x000014cc, 0x000014cc } },
+ { 7, 0x989c, { 0x0000048c, 0x0000048c, 0x0000048c } },
+ { 7, 0x98c4, { 0x00000003, 0x00000003, 0x00000003 } },
};
/* RFX112A (Derby 2) */
@@ -477,6 +388,7 @@ static const struct ath5k_ini_rfbuffer rfb_5112[] = {
#define AR5K_RF5112A_XB5_LVL { 2, 3, 3 }
static const struct ath5k_rf_reg rf_regs_5112a[] = {
+ {2, AR5K_RF_TURBO, AR5K_RF5112X_RF_TURBO},
{6, AR5K_RF_OB_2GHZ, AR5K_RF5112A_OB_2GHZ},
{6, AR5K_RF_DB_2GHZ, AR5K_RF5112A_DB_2GHZ},
{6, AR5K_RF_OB_5GHZ, AR5K_RF5112A_OB_5GHZ},
@@ -515,119 +427,63 @@ static const struct ath5k_rf_reg rf_regs_5112a[] = {
/* Default mode specific settings */
static const struct ath5k_ini_rfbuffer rfb_5112a[] = {
- { 1, 0x98d4,
- /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
- { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
- { 2, 0x98d0,
- { 0x03060408, 0x03070408, 0x03060408, 0x03060408, 0x03070408 } },
- { 3, 0x98dc,
- { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
- { 6, 0x989c,
- { 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000 } },
- { 6, 0x989c,
- { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
- { 6, 0x989c,
- { 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00180000, 0x00180000, 0x00180000, 0x00180000, 0x00180000 } },
- { 6, 0x989c,
- { 0x00600000, 0x00600000, 0x006e0000, 0x006e0000, 0x006e0000 } },
- { 6, 0x989c,
- { 0x00c70000, 0x00c70000, 0x00c70000, 0x00c70000, 0x00c70000 } },
- { 6, 0x989c,
- { 0x004b0000, 0x004b0000, 0x004b0000, 0x004b0000, 0x004b0000 } },
- { 6, 0x989c,
- { 0x04480000, 0x04480000, 0x04480000, 0x04480000, 0x04480000 } },
- { 6, 0x989c,
- { 0x004c0000, 0x004c0000, 0x004c0000, 0x004c0000, 0x004c0000 } },
- { 6, 0x989c,
- { 0x00e40000, 0x00e40000, 0x00e40000, 0x00e40000, 0x00e40000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00fc0000, 0x00fc0000, 0x00fc0000, 0x00fc0000, 0x00fc0000 } },
- { 6, 0x989c,
- { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
- { 6, 0x989c,
- { 0x043f0000, 0x043f0000, 0x043f0000, 0x043f0000, 0x043f0000 } },
- { 6, 0x989c,
- { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
- { 6, 0x989c,
- { 0x02190000, 0x02190000, 0x02190000, 0x02190000, 0x02190000 } },
- { 6, 0x989c,
- { 0x00240000, 0x00240000, 0x00240000, 0x00240000, 0x00240000 } },
- { 6, 0x989c,
- { 0x00b40000, 0x00b40000, 0x00b40000, 0x00b40000, 0x00b40000 } },
- { 6, 0x989c,
- { 0x00990000, 0x00990000, 0x00990000, 0x00990000, 0x00990000 } },
- { 6, 0x989c,
- { 0x00500000, 0x00500000, 0x00500000, 0x00500000, 0x00500000 } },
- { 6, 0x989c,
- { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
- { 6, 0x989c,
- { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
- { 6, 0x989c,
- { 0xc0320000, 0xc0320000, 0xc0320000, 0xc0320000, 0xc0320000 } },
- { 6, 0x989c,
- { 0x01740000, 0x01740000, 0x01740000, 0x01740000, 0x01740000 } },
- { 6, 0x989c,
- { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
- { 6, 0x989c,
- { 0x86280000, 0x86280000, 0x86280000, 0x86280000, 0x86280000 } },
- { 6, 0x989c,
- { 0x31840000, 0x31840000, 0x31840000, 0x31840000, 0x31840000 } },
- { 6, 0x989c,
- { 0x00f20080, 0x00f20080, 0x00f20080, 0x00f20080, 0x00f20080 } },
- { 6, 0x989c,
- { 0x00270019, 0x00270019, 0x00270019, 0x00270019, 0x00270019 } },
- { 6, 0x989c,
- { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x000000b2, 0x000000b2, 0x000000b2, 0x000000b2, 0x000000b2 } },
- { 6, 0x989c,
- { 0x00b02084, 0x00b02084, 0x00b02084, 0x00b02084, 0x00b02084 } },
- { 6, 0x989c,
- { 0x004125a4, 0x004125a4, 0x004125a4, 0x004125a4, 0x004125a4 } },
- { 6, 0x989c,
- { 0x00119220, 0x00119220, 0x00119220, 0x00119220, 0x00119220 } },
- { 6, 0x989c,
- { 0x001a4800, 0x001a4800, 0x001a4800, 0x001a4800, 0x001a4800 } },
- { 6, 0x98d8,
- { 0x000b0230, 0x000b0230, 0x000b0230, 0x000b0230, 0x000b0230 } },
- { 7, 0x989c,
- { 0x00000094, 0x00000094, 0x00000094, 0x00000094, 0x00000094 } },
- { 7, 0x989c,
- { 0x00000091, 0x00000091, 0x00000091, 0x00000091, 0x00000091 } },
- { 7, 0x989c,
- { 0x00000012, 0x00000012, 0x00000012, 0x00000012, 0x00000012 } },
- { 7, 0x989c,
- { 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080 } },
- { 7, 0x989c,
- { 0x000000d9, 0x000000d9, 0x000000d9, 0x000000d9, 0x000000d9 } },
- { 7, 0x989c,
- { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } },
- { 7, 0x989c,
- { 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0 } },
- { 7, 0x989c,
- { 0x000000a2, 0x000000a2, 0x000000a2, 0x000000a2, 0x000000a2 } },
- { 7, 0x989c,
- { 0x00000052, 0x00000052, 0x00000052, 0x00000052, 0x00000052 } },
- { 7, 0x989c,
- { 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4 } },
- { 7, 0x989c,
- { 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc } },
- { 7, 0x989c,
- { 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c } },
- { 7, 0x98c4,
- { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
+ /* BANK / C.R. A/XR B G */
+ { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } },
+ { 2, 0x98d0, { 0x03060408, 0x03060408, 0x03060408 } },
+ { 3, 0x98dc, { 0x00a020c0, 0x00e020c0, 0x00e020c0 } },
+ { 6, 0x989c, { 0x0f000000, 0x0f000000, 0x0f000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00800000, 0x00800000, 0x00800000 } },
+ { 6, 0x989c, { 0x002a0000, 0x002a0000, 0x002a0000 } },
+ { 6, 0x989c, { 0x00010000, 0x00010000, 0x00010000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00180000, 0x00180000, 0x00180000 } },
+ { 6, 0x989c, { 0x00600000, 0x006e0000, 0x006e0000 } },
+ { 6, 0x989c, { 0x00c70000, 0x00c70000, 0x00c70000 } },
+ { 6, 0x989c, { 0x004b0000, 0x004b0000, 0x004b0000 } },
+ { 6, 0x989c, { 0x04480000, 0x04480000, 0x04480000 } },
+ { 6, 0x989c, { 0x004c0000, 0x004c0000, 0x004c0000 } },
+ { 6, 0x989c, { 0x00e40000, 0x00e40000, 0x00e40000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00fc0000, 0x00fc0000, 0x00fc0000 } },
+ { 6, 0x989c, { 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+ { 6, 0x989c, { 0x043f0000, 0x043f0000, 0x043f0000 } },
+ { 6, 0x989c, { 0x000c0000, 0x000c0000, 0x000c0000 } },
+ { 6, 0x989c, { 0x02190000, 0x02190000, 0x02190000 } },
+ { 6, 0x989c, { 0x00240000, 0x00240000, 0x00240000 } },
+ { 6, 0x989c, { 0x00b40000, 0x00b40000, 0x00b40000 } },
+ { 6, 0x989c, { 0x00990000, 0x00990000, 0x00990000 } },
+ { 6, 0x989c, { 0x00500000, 0x00500000, 0x00500000 } },
+ { 6, 0x989c, { 0x002a0000, 0x002a0000, 0x002a0000 } },
+ { 6, 0x989c, { 0x00120000, 0x00120000, 0x00120000 } },
+ { 6, 0x989c, { 0xc0320000, 0xc0320000, 0xc0320000 } },
+ { 6, 0x989c, { 0x01740000, 0x01740000, 0x01740000 } },
+ { 6, 0x989c, { 0x00110000, 0x00110000, 0x00110000 } },
+ { 6, 0x989c, { 0x86280000, 0x86280000, 0x86280000 } },
+ { 6, 0x989c, { 0x31840000, 0x31840000, 0x31840000 } },
+ { 6, 0x989c, { 0x00f20080, 0x00f20080, 0x00f20080 } },
+ { 6, 0x989c, { 0x00270019, 0x00270019, 0x00270019 } },
+ { 6, 0x989c, { 0x00000003, 0x00000003, 0x00000003 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x000000b2, 0x000000b2, 0x000000b2 } },
+ { 6, 0x989c, { 0x00b02084, 0x00b02084, 0x00b02084 } },
+ { 6, 0x989c, { 0x004125a4, 0x004125a4, 0x004125a4 } },
+ { 6, 0x989c, { 0x00119220, 0x00119220, 0x00119220 } },
+ { 6, 0x989c, { 0x001a4800, 0x001a4800, 0x001a4800 } },
+ { 6, 0x98d8, { 0x000b0230, 0x000b0230, 0x000b0230 } },
+ { 7, 0x989c, { 0x00000094, 0x00000094, 0x00000094 } },
+ { 7, 0x989c, { 0x00000091, 0x00000091, 0x00000091 } },
+ { 7, 0x989c, { 0x00000012, 0x00000012, 0x00000012 } },
+ { 7, 0x989c, { 0x00000080, 0x00000080, 0x00000080 } },
+ { 7, 0x989c, { 0x000000d9, 0x000000d9, 0x000000d9 } },
+ { 7, 0x989c, { 0x00000060, 0x00000060, 0x00000060 } },
+ { 7, 0x989c, { 0x000000f0, 0x000000f0, 0x000000f0 } },
+ { 7, 0x989c, { 0x000000a2, 0x000000a2, 0x000000a2 } },
+ { 7, 0x989c, { 0x00000052, 0x00000052, 0x00000052 } },
+ { 7, 0x989c, { 0x000000d4, 0x000000d4, 0x000000d4 } },
+ { 7, 0x989c, { 0x000014cc, 0x000014cc, 0x000014cc } },
+ { 7, 0x989c, { 0x0000048c, 0x0000048c, 0x0000048c } },
+ { 7, 0x98c4, { 0x00000003, 0x00000003, 0x00000003 } },
};
@@ -636,11 +492,15 @@ static const struct ath5k_ini_rfbuffer rfb_5112a[] = {
* RF2413 (Griffin) *
\******************/
+/* BANK 2 len pos col */
+#define AR5K_RF2413_RF_TURBO { 1, 1, 2 }
+
/* BANK 6 len pos col */
#define AR5K_RF2413_OB_2GHZ { 3, 168, 0 }
#define AR5K_RF2413_DB_2GHZ { 3, 165, 0 }
static const struct ath5k_rf_reg rf_regs_2413[] = {
+ {2, AR5K_RF_TURBO, AR5K_RF2413_RF_TURBO},
{6, AR5K_RF_OB_2GHZ, AR5K_RF2413_OB_2GHZ},
{6, AR5K_RF_DB_2GHZ, AR5K_RF2413_DB_2GHZ},
};
@@ -649,73 +509,40 @@ static const struct ath5k_rf_reg rf_regs_2413[] = {
* XXX: a/aTurbo ???
*/
static const struct ath5k_ini_rfbuffer rfb_2413[] = {
- { 1, 0x98d4,
- /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
- { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
- { 2, 0x98d0,
- { 0x02001408, 0x02011408, 0x02001408, 0x02001408, 0x02011408 } },
- { 3, 0x98dc,
- { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
- { 6, 0x989c,
- { 0xf0000000, 0xf0000000, 0xf0000000, 0xf0000000, 0xf0000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x03000000, 0x03000000, 0x03000000, 0x03000000, 0x03000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x40400000, 0x40400000, 0x40400000, 0x40400000, 0x40400000 } },
- { 6, 0x989c,
- { 0x65050000, 0x65050000, 0x65050000, 0x65050000, 0x65050000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00420000, 0x00420000, 0x00420000, 0x00420000, 0x00420000 } },
- { 6, 0x989c,
- { 0x00b50000, 0x00b50000, 0x00b50000, 0x00b50000, 0x00b50000 } },
- { 6, 0x989c,
- { 0x00030000, 0x00030000, 0x00030000, 0x00030000, 0x00030000 } },
- { 6, 0x989c,
- { 0x00f70000, 0x00f70000, 0x00f70000, 0x00f70000, 0x00f70000 } },
- { 6, 0x989c,
- { 0x009d0000, 0x009d0000, 0x009d0000, 0x009d0000, 0x009d0000 } },
- { 6, 0x989c,
- { 0x00220000, 0x00220000, 0x00220000, 0x00220000, 0x00220000 } },
- { 6, 0x989c,
- { 0x04220000, 0x04220000, 0x04220000, 0x04220000, 0x04220000 } },
- { 6, 0x989c,
- { 0x00230018, 0x00230018, 0x00230018, 0x00230018, 0x00230018 } },
- { 6, 0x989c,
- { 0x00280000, 0x00280000, 0x00280060, 0x00280060, 0x00280060 } },
- { 6, 0x989c,
- { 0x005000c0, 0x005000c0, 0x005000c3, 0x005000c3, 0x005000c3 } },
- { 6, 0x989c,
- { 0x0004007f, 0x0004007f, 0x0004007f, 0x0004007f, 0x0004007f } },
- { 6, 0x989c,
- { 0x00000458, 0x00000458, 0x00000458, 0x00000458, 0x00000458 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x0000c000, 0x0000c000, 0x0000c000, 0x0000c000, 0x0000c000 } },
- { 6, 0x98d8,
- { 0x00400230, 0x00400230, 0x00400230, 0x00400230, 0x00400230 } },
- { 7, 0x989c,
- { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
- { 7, 0x989c,
- { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
- { 7, 0x98cc,
- { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
+ /* BANK / C.R. A/XR B G */
+ { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } },
+ { 2, 0x98d0, { 0x02001408, 0x02001408, 0x02001408 } },
+ { 3, 0x98dc, { 0x00a020c0, 0x00e020c0, 0x00e020c0 } },
+ { 6, 0x989c, { 0xf0000000, 0xf0000000, 0xf0000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x03000000, 0x03000000, 0x03000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x40400000, 0x40400000, 0x40400000 } },
+ { 6, 0x989c, { 0x65050000, 0x65050000, 0x65050000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00420000, 0x00420000, 0x00420000 } },
+ { 6, 0x989c, { 0x00b50000, 0x00b50000, 0x00b50000 } },
+ { 6, 0x989c, { 0x00030000, 0x00030000, 0x00030000 } },
+ { 6, 0x989c, { 0x00f70000, 0x00f70000, 0x00f70000 } },
+ { 6, 0x989c, { 0x009d0000, 0x009d0000, 0x009d0000 } },
+ { 6, 0x989c, { 0x00220000, 0x00220000, 0x00220000 } },
+ { 6, 0x989c, { 0x04220000, 0x04220000, 0x04220000 } },
+ { 6, 0x989c, { 0x00230018, 0x00230018, 0x00230018 } },
+ { 6, 0x989c, { 0x00280000, 0x00280060, 0x00280060 } },
+ { 6, 0x989c, { 0x005000c0, 0x005000c3, 0x005000c3 } },
+ { 6, 0x989c, { 0x0004007f, 0x0004007f, 0x0004007f } },
+ { 6, 0x989c, { 0x00000458, 0x00000458, 0x00000458 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x0000c000, 0x0000c000, 0x0000c000 } },
+ { 6, 0x98d8, { 0x00400230, 0x00400230, 0x00400230 } },
+ { 7, 0x989c, { 0x00006400, 0x00006400, 0x00006400 } },
+ { 7, 0x989c, { 0x00000800, 0x00000800, 0x00000800 } },
+ { 7, 0x98cc, { 0x0000000e, 0x0000000e, 0x0000000e } },
};
@@ -724,88 +551,57 @@ static const struct ath5k_ini_rfbuffer rfb_2413[] = {
* RF2315/RF2316 (Cobra SoC) *
\***************************/
+/* BANK 2 len pos col */
+#define AR5K_RF2316_RF_TURBO { 1, 1, 2 }
+
/* BANK 6 len pos col */
#define AR5K_RF2316_OB_2GHZ { 3, 178, 0 }
#define AR5K_RF2316_DB_2GHZ { 3, 175, 0 }
static const struct ath5k_rf_reg rf_regs_2316[] = {
+ {2, AR5K_RF_TURBO, AR5K_RF2316_RF_TURBO},
{6, AR5K_RF_OB_2GHZ, AR5K_RF2316_OB_2GHZ},
{6, AR5K_RF_DB_2GHZ, AR5K_RF2316_DB_2GHZ},
};
/* Default mode specific settings */
static const struct ath5k_ini_rfbuffer rfb_2316[] = {
- { 1, 0x98d4,
- /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
- { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
- { 2, 0x98d0,
- { 0x02001408, 0x02011408, 0x02001408, 0x02001408, 0x02011408 } },
- { 3, 0x98dc,
- { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0xc0000000, 0xc0000000, 0xc0000000, 0xc0000000, 0xc0000000 } },
- { 6, 0x989c,
- { 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000 } },
- { 6, 0x989c,
- { 0x02000000, 0x02000000, 0x02000000, 0x02000000, 0x02000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0xf8000000, 0xf8000000, 0xf8000000, 0xf8000000, 0xf8000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x95150000, 0x95150000, 0x95150000, 0x95150000, 0x95150000 } },
- { 6, 0x989c,
- { 0xc1000000, 0xc1000000, 0xc1000000, 0xc1000000, 0xc1000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00080000, 0x00080000, 0x00080000, 0x00080000, 0x00080000 } },
- { 6, 0x989c,
- { 0x00d50000, 0x00d50000, 0x00d50000, 0x00d50000, 0x00d50000 } },
- { 6, 0x989c,
- { 0x000e0000, 0x000e0000, 0x000e0000, 0x000e0000, 0x000e0000 } },
- { 6, 0x989c,
- { 0x00dc0000, 0x00dc0000, 0x00dc0000, 0x00dc0000, 0x00dc0000 } },
- { 6, 0x989c,
- { 0x00770000, 0x00770000, 0x00770000, 0x00770000, 0x00770000 } },
- { 6, 0x989c,
- { 0x008a0000, 0x008a0000, 0x008a0000, 0x008a0000, 0x008a0000 } },
- { 6, 0x989c,
- { 0x10880000, 0x10880000, 0x10880000, 0x10880000, 0x10880000 } },
- { 6, 0x989c,
- { 0x008c0060, 0x008c0060, 0x008c0060, 0x008c0060, 0x008c0060 } },
- { 6, 0x989c,
- { 0x00a00000, 0x00a00000, 0x00a00080, 0x00a00080, 0x00a00080 } },
- { 6, 0x989c,
- { 0x00400000, 0x00400000, 0x0040000d, 0x0040000d, 0x0040000d } },
- { 6, 0x989c,
- { 0x00110400, 0x00110400, 0x00110400, 0x00110400, 0x00110400 } },
- { 6, 0x989c,
- { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } },
- { 6, 0x989c,
- { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
- { 6, 0x989c,
- { 0x00000b00, 0x00000b00, 0x00000b00, 0x00000b00, 0x00000b00 } },
- { 6, 0x989c,
- { 0x00000be8, 0x00000be8, 0x00000be8, 0x00000be8, 0x00000be8 } },
- { 6, 0x98c0,
- { 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000 } },
- { 7, 0x989c,
- { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
- { 7, 0x989c,
- { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
- { 7, 0x98cc,
- { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
+ /* BANK / C.R. A/XR B G */
+ { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } },
+ { 2, 0x98d0, { 0x02001408, 0x02001408, 0x02001408 } },
+ { 3, 0x98dc, { 0x00a020c0, 0x00e020c0, 0x00e020c0 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0xc0000000, 0xc0000000, 0xc0000000 } },
+ { 6, 0x989c, { 0x0f000000, 0x0f000000, 0x0f000000 } },
+ { 6, 0x989c, { 0x02000000, 0x02000000, 0x02000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0xf8000000, 0xf8000000, 0xf8000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x95150000, 0x95150000, 0x95150000 } },
+ { 6, 0x989c, { 0xc1000000, 0xc1000000, 0xc1000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00080000, 0x00080000, 0x00080000 } },
+ { 6, 0x989c, { 0x00d50000, 0x00d50000, 0x00d50000 } },
+ { 6, 0x989c, { 0x000e0000, 0x000e0000, 0x000e0000 } },
+ { 6, 0x989c, { 0x00dc0000, 0x00dc0000, 0x00dc0000 } },
+ { 6, 0x989c, { 0x00770000, 0x00770000, 0x00770000 } },
+ { 6, 0x989c, { 0x008a0000, 0x008a0000, 0x008a0000 } },
+ { 6, 0x989c, { 0x10880000, 0x10880000, 0x10880000 } },
+ { 6, 0x989c, { 0x008c0060, 0x008c0060, 0x008c0060 } },
+ { 6, 0x989c, { 0x00a00000, 0x00a00080, 0x00a00080 } },
+ { 6, 0x989c, { 0x00400000, 0x0040000d, 0x0040000d } },
+ { 6, 0x989c, { 0x00110400, 0x00110400, 0x00110400 } },
+ { 6, 0x989c, { 0x00000060, 0x00000060, 0x00000060 } },
+ { 6, 0x989c, { 0x00000001, 0x00000001, 0x00000001 } },
+ { 6, 0x989c, { 0x00000b00, 0x00000b00, 0x00000b00 } },
+ { 6, 0x989c, { 0x00000be8, 0x00000be8, 0x00000be8 } },
+ { 6, 0x98c0, { 0x00010000, 0x00010000, 0x00010000 } },
+ { 7, 0x989c, { 0x00006400, 0x00006400, 0x00006400 } },
+ { 7, 0x989c, { 0x00000800, 0x00000800, 0x00000800 } },
+ { 7, 0x98cc, { 0x0000000e, 0x0000000e, 0x0000000e } },
};
@@ -835,93 +631,50 @@ static const struct ath5k_rf_reg rf_regs_5413[] = {
/* Default mode specific settings */
static const struct ath5k_ini_rfbuffer rfb_5413[] = {
- { 1, 0x98d4,
- /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
- { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
- { 2, 0x98d0,
- { 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008 } },
- { 3, 0x98dc,
- { 0x00a000c0, 0x00a000c0, 0x00e000c0, 0x00e000c0, 0x00e000c0 } },
- { 6, 0x989c,
- { 0x33000000, 0x33000000, 0x33000000, 0x33000000, 0x33000000 } },
- { 6, 0x989c,
- { 0x01000000, 0x01000000, 0x01000000, 0x01000000, 0x01000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x1f000000, 0x1f000000, 0x1f000000, 0x1f000000, 0x1f000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00b80000, 0x00b80000, 0x00b80000, 0x00b80000, 0x00b80000 } },
- { 6, 0x989c,
- { 0x00b70000, 0x00b70000, 0x00b70000, 0x00b70000, 0x00b70000 } },
- { 6, 0x989c,
- { 0x00840000, 0x00840000, 0x00840000, 0x00840000, 0x00840000 } },
- { 6, 0x989c,
- { 0x00980000, 0x00980000, 0x00980000, 0x00980000, 0x00980000 } },
- { 6, 0x989c,
- { 0x00c00000, 0x00c00000, 0x00c00000, 0x00c00000, 0x00c00000 } },
- { 6, 0x989c,
- { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
- { 6, 0x989c,
- { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
- { 6, 0x989c,
- { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
- { 6, 0x989c,
- { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
- { 6, 0x989c,
- { 0x00d70000, 0x00d70000, 0x00d70000, 0x00d70000, 0x00d70000 } },
- { 6, 0x989c,
- { 0x00610000, 0x00610000, 0x00610000, 0x00610000, 0x00610000 } },
- { 6, 0x989c,
- { 0x00fe0000, 0x00fe0000, 0x00fe0000, 0x00fe0000, 0x00fe0000 } },
- { 6, 0x989c,
- { 0x00de0000, 0x00de0000, 0x00de0000, 0x00de0000, 0x00de0000 } },
- { 6, 0x989c,
- { 0x007f0000, 0x007f0000, 0x007f0000, 0x007f0000, 0x007f0000 } },
- { 6, 0x989c,
- { 0x043d0000, 0x043d0000, 0x043d0000, 0x043d0000, 0x043d0000 } },
- { 6, 0x989c,
- { 0x00770000, 0x00770000, 0x00770000, 0x00770000, 0x00770000 } },
- { 6, 0x989c,
- { 0x00440000, 0x00440000, 0x00440000, 0x00440000, 0x00440000 } },
- { 6, 0x989c,
- { 0x00980000, 0x00980000, 0x00980000, 0x00980000, 0x00980000 } },
- { 6, 0x989c,
- { 0x00100080, 0x00100080, 0x00100080, 0x00100080, 0x00100080 } },
- { 6, 0x989c,
- { 0x0005c034, 0x0005c034, 0x0005c034, 0x0005c034, 0x0005c034 } },
- { 6, 0x989c,
- { 0x003100f0, 0x003100f0, 0x003100f0, 0x003100f0, 0x003100f0 } },
- { 6, 0x989c,
- { 0x000c011f, 0x000c011f, 0x000c011f, 0x000c011f, 0x000c011f } },
- { 6, 0x989c,
- { 0x00510040, 0x00510040, 0x00510040, 0x00510040, 0x00510040 } },
- { 6, 0x989c,
- { 0x005000da, 0x005000da, 0x005000da, 0x005000da, 0x005000da } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00004044, 0x00004044, 0x00004044, 0x00004044, 0x00004044 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x000060c0, 0x000060c0, 0x000060c0, 0x000060c0, 0x000060c0 } },
- { 6, 0x989c,
- { 0x00002c00, 0x00002c00, 0x00003600, 0x00003600, 0x00002c00 } },
- { 6, 0x98c8,
- { 0x00000403, 0x00000403, 0x00040403, 0x00040403, 0x00040403 } },
- { 7, 0x989c,
- { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
- { 7, 0x989c,
- { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
- { 7, 0x98cc,
- { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
+ /* BANK / C.R. A/XR B G */
+ { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } },
+ { 2, 0x98d0, { 0x00000008, 0x00000008, 0x00000008 } },
+ { 3, 0x98dc, { 0x00a000c0, 0x00e000c0, 0x00e000c0 } },
+ { 6, 0x989c, { 0x33000000, 0x33000000, 0x33000000 } },
+ { 6, 0x989c, { 0x01000000, 0x01000000, 0x01000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x1f000000, 0x1f000000, 0x1f000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00b80000, 0x00b80000, 0x00b80000 } },
+ { 6, 0x989c, { 0x00b70000, 0x00b70000, 0x00b70000 } },
+ { 6, 0x989c, { 0x00840000, 0x00840000, 0x00840000 } },
+ { 6, 0x989c, { 0x00980000, 0x00980000, 0x00980000 } },
+ { 6, 0x989c, { 0x00c00000, 0x00c00000, 0x00c00000 } },
+ { 6, 0x989c, { 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+ { 6, 0x989c, { 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+ { 6, 0x989c, { 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+ { 6, 0x989c, { 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+ { 6, 0x989c, { 0x00d70000, 0x00d70000, 0x00d70000 } },
+ { 6, 0x989c, { 0x00610000, 0x00610000, 0x00610000 } },
+ { 6, 0x989c, { 0x00fe0000, 0x00fe0000, 0x00fe0000 } },
+ { 6, 0x989c, { 0x00de0000, 0x00de0000, 0x00de0000 } },
+ { 6, 0x989c, { 0x007f0000, 0x007f0000, 0x007f0000 } },
+ { 6, 0x989c, { 0x043d0000, 0x043d0000, 0x043d0000 } },
+ { 6, 0x989c, { 0x00770000, 0x00770000, 0x00770000 } },
+ { 6, 0x989c, { 0x00440000, 0x00440000, 0x00440000 } },
+ { 6, 0x989c, { 0x00980000, 0x00980000, 0x00980000 } },
+ { 6, 0x989c, { 0x00100080, 0x00100080, 0x00100080 } },
+ { 6, 0x989c, { 0x0005c034, 0x0005c034, 0x0005c034 } },
+ { 6, 0x989c, { 0x003100f0, 0x003100f0, 0x003100f0 } },
+ { 6, 0x989c, { 0x000c011f, 0x000c011f, 0x000c011f } },
+ { 6, 0x989c, { 0x00510040, 0x00510040, 0x00510040 } },
+ { 6, 0x989c, { 0x005000da, 0x005000da, 0x005000da } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00004044, 0x00004044, 0x00004044 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x000060c0, 0x000060c0, 0x000060c0 } },
+ { 6, 0x989c, { 0x00002c00, 0x00003600, 0x00003600 } },
+ { 6, 0x98c8, { 0x00000403, 0x00040403, 0x00040403 } },
+ { 7, 0x989c, { 0x00006400, 0x00006400, 0x00006400 } },
+ { 7, 0x989c, { 0x00000800, 0x00000800, 0x00000800 } },
+ { 7, 0x98cc, { 0x0000000e, 0x0000000e, 0x0000000e } },
};
@@ -931,92 +684,59 @@ static const struct ath5k_ini_rfbuffer rfb_5413[] = {
* AR2317 (Spider SoC) *
\***************************/
+/* BANK 2 len pos col */
+#define AR5K_RF2425_RF_TURBO { 1, 1, 2 }
+
/* BANK 6 len pos col */
#define AR5K_RF2425_OB_2GHZ { 3, 193, 0 }
#define AR5K_RF2425_DB_2GHZ { 3, 190, 0 }
static const struct ath5k_rf_reg rf_regs_2425[] = {
+ {2, AR5K_RF_TURBO, AR5K_RF2425_RF_TURBO},
{6, AR5K_RF_OB_2GHZ, AR5K_RF2425_OB_2GHZ},
{6, AR5K_RF_DB_2GHZ, AR5K_RF2425_DB_2GHZ},
};
/* Default mode specific settings
- * XXX: a/aTurbo ?
*/
static const struct ath5k_ini_rfbuffer rfb_2425[] = {
- { 1, 0x98d4,
- /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
- { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
- { 2, 0x98d0,
- { 0x02001408, 0x02001408, 0x02001408, 0x02001408, 0x02001408 } },
- { 3, 0x98dc,
- { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
- { 6, 0x989c,
- { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000 } },
- { 6, 0x989c,
- { 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000 } },
- { 6, 0x989c,
- { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
- { 6, 0x989c,
- { 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000 } },
- { 6, 0x989c,
- { 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000 } },
- { 6, 0x989c,
- { 0x00140000, 0x00140000, 0x00140000, 0x00140000, 0x00140000 } },
- { 6, 0x989c,
- { 0x00910040, 0x00910040, 0x00910040, 0x00910040, 0x00910040 } },
- { 6, 0x989c,
- { 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a } },
- { 6, 0x989c,
- { 0x00410000, 0x00410000, 0x00410000, 0x00410000, 0x00410000 } },
- { 6, 0x989c,
- { 0x00810000, 0x00810000, 0x00810060, 0x00810060, 0x00810060 } },
- { 6, 0x989c,
- { 0x00020800, 0x00020800, 0x00020803, 0x00020803, 0x00020803 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00001660, 0x00001660, 0x00001660, 0x00001660, 0x00001660 } },
- { 6, 0x989c,
- { 0x00001688, 0x00001688, 0x00001688, 0x00001688, 0x00001688 } },
- { 6, 0x98c4,
- { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
- { 7, 0x989c,
- { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
- { 7, 0x989c,
- { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
- { 7, 0x98cc,
- { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
+ /* BANK / C.R. A/XR B G */
+ { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } },
+ { 2, 0x98d0, { 0x02001408, 0x02001408, 0x02001408 } },
+ { 3, 0x98dc, { 0x00a020c0, 0x00e020c0, 0x00e020c0 } },
+ { 6, 0x989c, { 0x10000000, 0x10000000, 0x10000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x002a0000, 0x002a0000, 0x002a0000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00100000, 0x00100000, 0x00100000 } },
+ { 6, 0x989c, { 0x00020000, 0x00020000, 0x00020000 } },
+ { 6, 0x989c, { 0x00730000, 0x00730000, 0x00730000 } },
+ { 6, 0x989c, { 0x00f80000, 0x00f80000, 0x00f80000 } },
+ { 6, 0x989c, { 0x00e70000, 0x00e70000, 0x00e70000 } },
+ { 6, 0x989c, { 0x00140000, 0x00140000, 0x00140000 } },
+ { 6, 0x989c, { 0x00910040, 0x00910040, 0x00910040 } },
+ { 6, 0x989c, { 0x0007001a, 0x0007001a, 0x0007001a } },
+ { 6, 0x989c, { 0x00410000, 0x00410000, 0x00410000 } },
+ { 6, 0x989c, { 0x00810000, 0x00810060, 0x00810060 } },
+ { 6, 0x989c, { 0x00020800, 0x00020803, 0x00020803 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00001660, 0x00001660, 0x00001660 } },
+ { 6, 0x989c, { 0x00001688, 0x00001688, 0x00001688 } },
+ { 6, 0x98c4, { 0x00000001, 0x00000001, 0x00000001 } },
+ { 7, 0x989c, { 0x00006400, 0x00006400, 0x00006400 } },
+ { 7, 0x989c, { 0x00000800, 0x00000800, 0x00000800 } },
+ { 7, 0x98cc, { 0x0000000e, 0x0000000e, 0x0000000e } },
};
/*
@@ -1024,158 +744,85 @@ static const struct ath5k_ini_rfbuffer rfb_2425[] = {
* bank modification and get rid of this
*/
static const struct ath5k_ini_rfbuffer rfb_2317[] = {
- { 1, 0x98d4,
- /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
- { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
- { 2, 0x98d0,
- { 0x02001408, 0x02011408, 0x02001408, 0x02001408, 0x02011408 } },
- { 3, 0x98dc,
- { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
- { 6, 0x989c,
- { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000 } },
- { 6, 0x989c,
- { 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000 } },
- { 6, 0x989c,
- { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
- { 6, 0x989c,
- { 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000 } },
- { 6, 0x989c,
- { 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000 } },
- { 6, 0x989c,
- { 0x00140100, 0x00140100, 0x00140100, 0x00140100, 0x00140100 } },
- { 6, 0x989c,
- { 0x00910040, 0x00910040, 0x00910040, 0x00910040, 0x00910040 } },
- { 6, 0x989c,
- { 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a } },
- { 6, 0x989c,
- { 0x00410000, 0x00410000, 0x00410000, 0x00410000, 0x00410000 } },
- { 6, 0x989c,
- { 0x00810000, 0x00810000, 0x00810060, 0x00810060, 0x00810060 } },
- { 6, 0x989c,
- { 0x00020800, 0x00020800, 0x00020803, 0x00020803, 0x00020803 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00001660, 0x00001660, 0x00001660, 0x00001660, 0x00001660 } },
- { 6, 0x989c,
- { 0x00009688, 0x00009688, 0x00009688, 0x00009688, 0x00009688 } },
- { 6, 0x98c4,
- { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
- { 7, 0x989c,
- { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
- { 7, 0x989c,
- { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
- { 7, 0x98cc,
- { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
+ /* BANK / C.R. A/XR B G */
+ { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } },
+ { 2, 0x98d0, { 0x02001408, 0x02001408, 0x02001408 } },
+ { 3, 0x98dc, { 0x00a020c0, 0x00e020c0, 0x00e020c0 } },
+ { 6, 0x989c, { 0x10000000, 0x10000000, 0x10000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x002a0000, 0x002a0000, 0x002a0000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00100000, 0x00100000, 0x00100000 } },
+ { 6, 0x989c, { 0x00020000, 0x00020000, 0x00020000 } },
+ { 6, 0x989c, { 0x00730000, 0x00730000, 0x00730000 } },
+ { 6, 0x989c, { 0x00f80000, 0x00f80000, 0x00f80000 } },
+ { 6, 0x989c, { 0x00e70000, 0x00e70000, 0x00e70000 } },
+ { 6, 0x989c, { 0x00140100, 0x00140100, 0x00140100 } },
+ { 6, 0x989c, { 0x00910040, 0x00910040, 0x00910040 } },
+ { 6, 0x989c, { 0x0007001a, 0x0007001a, 0x0007001a } },
+ { 6, 0x989c, { 0x00410000, 0x00410000, 0x00410000 } },
+ { 6, 0x989c, { 0x00810000, 0x00810060, 0x00810060 } },
+ { 6, 0x989c, { 0x00020800, 0x00020803, 0x00020803 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00001660, 0x00001660, 0x00001660 } },
+ { 6, 0x989c, { 0x00009688, 0x00009688, 0x00009688 } },
+ { 6, 0x98c4, { 0x00000001, 0x00000001, 0x00000001 } },
+ { 7, 0x989c, { 0x00006400, 0x00006400, 0x00006400 } },
+ { 7, 0x989c, { 0x00000800, 0x00000800, 0x00000800 } },
+ { 7, 0x98cc, { 0x0000000e, 0x0000000e, 0x0000000e } },
};
/*
* TODO: Handle the few differences with swan during
* bank modification and get rid of this
- * XXX: a/aTurbo ?
*/
static const struct ath5k_ini_rfbuffer rfb_2417[] = {
- { 1, 0x98d4,
- /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
- { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
- { 2, 0x98d0,
- { 0x02001408, 0x02001408, 0x02001408, 0x02001408, 0x02001408 } },
- { 3, 0x98dc,
- { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
- { 6, 0x989c,
- { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000 } },
- { 6, 0x989c,
- { 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000 } },
- { 6, 0x989c,
- { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
- { 6, 0x989c,
- { 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000 } },
- { 6, 0x989c,
- { 0x00e70000, 0x00e70000, 0x80e70000, 0x80e70000, 0x00e70000 } },
- { 6, 0x989c,
- { 0x00140000, 0x00140000, 0x00140000, 0x00140000, 0x00140000 } },
- { 6, 0x989c,
- { 0x00910040, 0x00910040, 0x00910040, 0x00910040, 0x00910040 } },
- { 6, 0x989c,
- { 0x0007001a, 0x0007001a, 0x0207001a, 0x0207001a, 0x0007001a } },
- { 6, 0x989c,
- { 0x00410000, 0x00410000, 0x00410000, 0x00410000, 0x00410000 } },
- { 6, 0x989c,
- { 0x00810000, 0x00810000, 0x00810060, 0x00810060, 0x00810060 } },
- { 6, 0x989c,
- { 0x00020800, 0x00020800, 0x00020803, 0x00020803, 0x00020803 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00001660, 0x00001660, 0x00001660, 0x00001660, 0x00001660 } },
- { 6, 0x989c,
- { 0x00001688, 0x00001688, 0x00001688, 0x00001688, 0x00001688 } },
- { 6, 0x98c4,
- { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
- { 7, 0x989c,
- { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
- { 7, 0x989c,
- { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
- { 7, 0x98cc,
- { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
+ /* BANK / C.R. A/XR B G */
+ { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } },
+ { 2, 0x98d0, { 0x02001408, 0x02001408, 0x02001408 } },
+ { 3, 0x98dc, { 0x00a020c0, 0x00e020c0, 0x00e020c0 } },
+ { 6, 0x989c, { 0x10000000, 0x10000000, 0x10000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x002a0000, 0x002a0000, 0x002a0000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00100000, 0x00100000, 0x00100000 } },
+ { 6, 0x989c, { 0x00020000, 0x00020000, 0x00020000 } },
+ { 6, 0x989c, { 0x00730000, 0x00730000, 0x00730000 } },
+ { 6, 0x989c, { 0x00f80000, 0x00f80000, 0x00f80000 } },
+ { 6, 0x989c, { 0x00e70000, 0x80e70000, 0x80e70000 } },
+ { 6, 0x989c, { 0x00140000, 0x00140000, 0x00140000 } },
+ { 6, 0x989c, { 0x00910040, 0x00910040, 0x00910040 } },
+ { 6, 0x989c, { 0x0007001a, 0x0207001a, 0x0207001a } },
+ { 6, 0x989c, { 0x00410000, 0x00410000, 0x00410000 } },
+ { 6, 0x989c, { 0x00810000, 0x00810060, 0x00810060 } },
+ { 6, 0x989c, { 0x00020800, 0x00020803, 0x00020803 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c, { 0x00001660, 0x00001660, 0x00001660 } },
+ { 6, 0x989c, { 0x00001688, 0x00001688, 0x00001688 } },
+ { 6, 0x98c4, { 0x00000001, 0x00000001, 0x00000001 } },
+ { 7, 0x989c, { 0x00006400, 0x00006400, 0x00006400 } },
+ { 7, 0x989c, { 0x00000800, 0x00000800, 0x00000800 } },
+ { 7, 0x98cc, { 0x0000000e, 0x0000000e, 0x0000000e } },
};
diff --git a/drivers/net/wireless/ath/ath5k/sysfs.c b/drivers/net/wireless/ath/ath5k/sysfs.c
index 90757de7bf59..929c68cdf8ab 100644
--- a/drivers/net/wireless/ath/ath5k/sysfs.c
+++ b/drivers/net/wireless/ath/ath5k/sysfs.c
@@ -95,7 +95,7 @@ static struct attribute_group ath5k_attribute_group_ani = {
int
ath5k_sysfs_register(struct ath5k_softc *sc)
{
- struct device *dev = &sc->pdev->dev;
+ struct device *dev = sc->dev;
int err;
err = sysfs_create_group(&dev->kobj, &ath5k_attribute_group_ani);
@@ -110,7 +110,7 @@ ath5k_sysfs_register(struct ath5k_softc *sc)
void
ath5k_sysfs_unregister(struct ath5k_softc *sc)
{
- struct device *dev = &sc->pdev->dev;
+ struct device *dev = sc->dev;
sysfs_remove_group(&dev->kobj, &ath5k_attribute_group_ani);
}
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c
index 1a984b02e9e5..25a6e4417cdb 100644
--- a/drivers/net/wireless/ath/ath9k/ahb.c
+++ b/drivers/net/wireless/ath/ath9k/ahb.c
@@ -35,10 +35,9 @@ static bool ath_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data)
pdata = (struct ath9k_platform_data *) pdev->dev.platform_data;
if (off >= (ARRAY_SIZE(pdata->eeprom_data))) {
- ath_print(common, ATH_DBG_FATAL,
- "%s: flash read failed, offset %08x "
- "is out of range\n",
- __func__, off);
+ ath_err(common,
+ "%s: flash read failed, offset %08x is out of range\n",
+ __func__, off);
return false;
}
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index 63ccb39cdcd4..2e31c775351f 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -135,8 +135,8 @@ static void ath9k_ani_restart(struct ath_hw *ah)
cck_base = AR_PHY_COUNTMAX - ah->config.cck_trig_high;
}
- ath_print(common, ATH_DBG_ANI,
- "Writing ofdmbase=%u cckbase=%u\n", ofdm_base, cck_base);
+ ath_dbg(common, ATH_DBG_ANI,
+ "Writing ofdmbase=%u cckbase=%u\n", ofdm_base, cck_base);
ENABLE_REGWRITE_BUFFER(ah);
@@ -267,11 +267,11 @@ static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel)
aniState->noiseFloor = BEACON_RSSI(ah);
- ath_print(common, ATH_DBG_ANI,
- "**** ofdmlevel %d=>%d, rssi=%d[lo=%d hi=%d]\n",
- aniState->ofdmNoiseImmunityLevel,
- immunityLevel, aniState->noiseFloor,
- aniState->rssiThrLow, aniState->rssiThrHigh);
+ ath_dbg(common, ATH_DBG_ANI,
+ "**** ofdmlevel %d=>%d, rssi=%d[lo=%d hi=%d]\n",
+ aniState->ofdmNoiseImmunityLevel,
+ immunityLevel, aniState->noiseFloor,
+ aniState->rssiThrLow, aniState->rssiThrHigh);
aniState->ofdmNoiseImmunityLevel = immunityLevel;
@@ -334,11 +334,11 @@ static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel)
const struct ani_cck_level_entry *entry_cck;
aniState->noiseFloor = BEACON_RSSI(ah);
- ath_print(common, ATH_DBG_ANI,
- "**** ccklevel %d=>%d, rssi=%d[lo=%d hi=%d]\n",
- aniState->cckNoiseImmunityLevel, immunityLevel,
- aniState->noiseFloor, aniState->rssiThrLow,
- aniState->rssiThrHigh);
+ ath_dbg(common, ATH_DBG_ANI,
+ "**** ccklevel %d=>%d, rssi=%d[lo=%d hi=%d]\n",
+ aniState->cckNoiseImmunityLevel, immunityLevel,
+ aniState->noiseFloor, aniState->rssiThrLow,
+ aniState->rssiThrHigh);
if ((ah->opmode == NL80211_IFTYPE_STATION ||
ah->opmode == NL80211_IFTYPE_ADHOC) &&
@@ -358,7 +358,7 @@ static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel)
entry_cck->fir_step_level);
/* Skip MRC CCK for pre AR9003 families */
- if (!AR_SREV_9300_20_OR_LATER(ah))
+ if (!AR_SREV_9300_20_OR_LATER(ah) || AR_SREV_9485(ah))
return;
if (aniState->mrcCCKOff == entry_cck->mrc_cck_on)
@@ -478,8 +478,8 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
if (ah->opmode != NL80211_IFTYPE_STATION
&& ah->opmode != NL80211_IFTYPE_ADHOC) {
- ath_print(common, ATH_DBG_ANI,
- "Reset ANI state opmode %u\n", ah->opmode);
+ ath_dbg(common, ATH_DBG_ANI,
+ "Reset ANI state opmode %u\n", ah->opmode);
ah->stats.ast_ani_reset++;
if (ah->opmode == NL80211_IFTYPE_AP) {
@@ -584,16 +584,14 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning)
ATH9K_ANI_OFDM_DEF_LEVEL ||
aniState->cckNoiseImmunityLevel !=
ATH9K_ANI_CCK_DEF_LEVEL) {
- ath_print(common, ATH_DBG_ANI,
- "Restore defaults: opmode %u "
- "chan %d Mhz/0x%x is_scanning=%d "
- "ofdm:%d cck:%d\n",
- ah->opmode,
- chan->channel,
- chan->channelFlags,
- is_scanning,
- aniState->ofdmNoiseImmunityLevel,
- aniState->cckNoiseImmunityLevel);
+ ath_dbg(common, ATH_DBG_ANI,
+ "Restore defaults: opmode %u chan %d Mhz/0x%x is_scanning=%d ofdm:%d cck:%d\n",
+ ah->opmode,
+ chan->channel,
+ chan->channelFlags,
+ is_scanning,
+ aniState->ofdmNoiseImmunityLevel,
+ aniState->cckNoiseImmunityLevel);
ath9k_hw_set_ofdm_nil(ah, ATH9K_ANI_OFDM_DEF_LEVEL);
ath9k_hw_set_cck_nil(ah, ATH9K_ANI_CCK_DEF_LEVEL);
@@ -602,16 +600,14 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning)
/*
* restore historical levels for this channel
*/
- ath_print(common, ATH_DBG_ANI,
- "Restore history: opmode %u "
- "chan %d Mhz/0x%x is_scanning=%d "
- "ofdm:%d cck:%d\n",
- ah->opmode,
- chan->channel,
- chan->channelFlags,
- is_scanning,
- aniState->ofdmNoiseImmunityLevel,
- aniState->cckNoiseImmunityLevel);
+ ath_dbg(common, ATH_DBG_ANI,
+ "Restore history: opmode %u chan %d Mhz/0x%x is_scanning=%d ofdm:%d cck:%d\n",
+ ah->opmode,
+ chan->channel,
+ chan->channelFlags,
+ is_scanning,
+ aniState->ofdmNoiseImmunityLevel,
+ aniState->cckNoiseImmunityLevel);
ath9k_hw_set_ofdm_nil(ah,
aniState->ofdmNoiseImmunityLevel);
@@ -666,19 +662,17 @@ static bool ath9k_hw_ani_read_counters(struct ath_hw *ah)
if (!use_new_ani(ah) && (phyCnt1 < ofdm_base || phyCnt2 < cck_base)) {
if (phyCnt1 < ofdm_base) {
- ath_print(common, ATH_DBG_ANI,
- "phyCnt1 0x%x, resetting "
- "counter value to 0x%x\n",
- phyCnt1, ofdm_base);
+ ath_dbg(common, ATH_DBG_ANI,
+ "phyCnt1 0x%x, resetting counter value to 0x%x\n",
+ phyCnt1, ofdm_base);
REG_WRITE(ah, AR_PHY_ERR_1, ofdm_base);
REG_WRITE(ah, AR_PHY_ERR_MASK_1,
AR_PHY_ERR_OFDM_TIMING);
}
if (phyCnt2 < cck_base) {
- ath_print(common, ATH_DBG_ANI,
- "phyCnt2 0x%x, resetting "
- "counter value to 0x%x\n",
- phyCnt2, cck_base);
+ ath_dbg(common, ATH_DBG_ANI,
+ "phyCnt2 0x%x, resetting counter value to 0x%x\n",
+ phyCnt2, cck_base);
REG_WRITE(ah, AR_PHY_ERR_2, cck_base);
REG_WRITE(ah, AR_PHY_ERR_MASK_2,
AR_PHY_ERR_CCK_TIMING);
@@ -719,13 +713,12 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan)
cckPhyErrRate = aniState->cckPhyErrCount * 1000 /
aniState->listenTime;
- ath_print(common, ATH_DBG_ANI,
- "listenTime=%d OFDM:%d errs=%d/s CCK:%d "
- "errs=%d/s ofdm_turn=%d\n",
- aniState->listenTime,
- aniState->ofdmNoiseImmunityLevel,
- ofdmPhyErrRate, aniState->cckNoiseImmunityLevel,
- cckPhyErrRate, aniState->ofdmsTurn);
+ ath_dbg(common, ATH_DBG_ANI,
+ "listenTime=%d OFDM:%d errs=%d/s CCK:%d errs=%d/s ofdm_turn=%d\n",
+ aniState->listenTime,
+ aniState->ofdmNoiseImmunityLevel,
+ ofdmPhyErrRate, aniState->cckNoiseImmunityLevel,
+ cckPhyErrRate, aniState->ofdmsTurn);
if (aniState->listenTime > 5 * ah->aniperiod) {
if (ofdmPhyErrRate <= ah->config.ofdm_trig_low &&
@@ -755,7 +748,7 @@ void ath9k_enable_mib_counters(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
- ath_print(common, ATH_DBG_ANI, "Enable MIB counters\n");
+ ath_dbg(common, ATH_DBG_ANI, "Enable MIB counters\n");
ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
@@ -777,7 +770,7 @@ void ath9k_hw_disable_mib_counters(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
- ath_print(common, ATH_DBG_ANI, "Disable MIB counters\n");
+ ath_dbg(common, ATH_DBG_ANI, "Disable MIB counters\n");
REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC);
ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
@@ -834,10 +827,10 @@ void ath9k_hw_ani_setup(struct ath_hw *ah)
{
int i;
- const int totalSizeDesired[] = { -55, -55, -55, -55, -62 };
- const int coarseHigh[] = { -14, -14, -14, -14, -12 };
- const int coarseLow[] = { -64, -64, -64, -64, -70 };
- const int firpwr[] = { -78, -78, -78, -78, -80 };
+ static const int totalSizeDesired[] = { -55, -55, -55, -55, -62 };
+ static const int coarseHigh[] = { -14, -14, -14, -14, -12 };
+ static const int coarseLow[] = { -64, -64, -64, -64, -70 };
+ static const int firpwr[] = { -78, -78, -78, -78, -80 };
for (i = 0; i < 5; i++) {
ah->totalSizeDesired[i] = totalSizeDesired[i];
@@ -852,7 +845,7 @@ void ath9k_hw_ani_init(struct ath_hw *ah)
struct ath_common *common = ath9k_hw_common(ah);
int i;
- ath_print(common, ATH_DBG_ANI, "Initialize ANI\n");
+ ath_dbg(common, ATH_DBG_ANI, "Initialize ANI\n");
if (use_new_ani(ah)) {
ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_NEW;
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index ea9f4497f58c..059330aac645 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -130,9 +130,8 @@ static void ar5008_hw_force_bias(struct ath_hw *ah, u16 synth_freq)
/* pre-reverse this field */
tmp_reg = ath9k_hw_reverse_bits(new_bias, 3);
- ath_print(common, ATH_DBG_CONFIG,
- "Force rf_pwd_icsyndiv to %1d on %4d\n",
- new_bias, synth_freq);
+ ath_dbg(common, ATH_DBG_CONFIG, "Force rf_pwd_icsyndiv to %1d on %4d\n",
+ new_bias, synth_freq);
/* swizzle rf_pwd_icsyndiv */
ar5008_hw_phy_modify_rx_buffer(ah->analogBank6Data, tmp_reg, 3, 181, 3);
@@ -173,8 +172,7 @@ static int ar5008_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
channelSel = ((freq - 704) * 2 - 3040) / 10;
bModeSynth = 1;
} else {
- ath_print(common, ATH_DBG_FATAL,
- "Invalid channel %u MHz\n", freq);
+ ath_err(common, "Invalid channel %u MHz\n", freq);
return -EINVAL;
}
@@ -206,8 +204,7 @@ static int ar5008_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
channelSel = ath9k_hw_reverse_bits((freq - 4800) / 5, 8);
aModeRefSel = ath9k_hw_reverse_bits(1, 2);
} else {
- ath_print(common, ATH_DBG_FATAL,
- "Invalid channel %u MHz\n", freq);
+ ath_err(common, "Invalid channel %u MHz\n", freq);
return -EINVAL;
}
@@ -244,13 +241,15 @@ static void ar5008_hw_spur_mitigate(struct ath_hw *ah,
int upper, lower, cur_vit_mask;
int tmp, new;
int i;
- int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
- AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
+ static int pilot_mask_reg[4] = {
+ AR_PHY_TIMING7, AR_PHY_TIMING8,
+ AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
};
- int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
- AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
+ static int chan_mask_reg[4] = {
+ AR_PHY_TIMING9, AR_PHY_TIMING10,
+ AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
};
- int inc[4] = { 0, 100, 0, 0 };
+ static int inc[4] = { 0, 100, 0, 0 };
int8_t mask_m[123];
int8_t mask_p[123];
@@ -446,8 +445,7 @@ static int ar5008_hw_rf_alloc_ext_banks(struct ath_hw *ah)
#define ATH_ALLOC_BANK(bank, size) do { \
bank = kzalloc((sizeof(u32) * size), GFP_KERNEL); \
if (!bank) { \
- ath_print(common, ATH_DBG_FATAL, \
- "Cannot allocate RF banks\n"); \
+ ath_err(common, "Cannot allocate RF banks\n"); \
return -ENOMEM; \
} \
} while (0);
@@ -873,12 +871,11 @@ static int ar5008_hw_process_ini(struct ath_hw *ah,
channel->max_antenna_gain * 2,
channel->max_power * 2,
min((u32) MAX_RATE_POWER,
- (u32) regulatory->power_limit));
+ (u32) regulatory->power_limit), false);
/* Write analog registers */
if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
- ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
- "ar5416SetRfRegs failed\n");
+ ath_err(ath9k_hw_common(ah), "ar5416SetRfRegs failed\n");
return -EIO;
}
@@ -1056,10 +1053,9 @@ static bool ar5008_hw_ani_control_old(struct ath_hw *ah,
u32 level = param;
if (level >= ARRAY_SIZE(ah->totalSizeDesired)) {
- ath_print(common, ATH_DBG_ANI,
- "level out of range (%u > %u)\n",
- level,
- (unsigned)ARRAY_SIZE(ah->totalSizeDesired));
+ ath_dbg(common, ATH_DBG_ANI,
+ "level out of range (%u > %zu)\n",
+ level, ARRAY_SIZE(ah->totalSizeDesired));
return false;
}
@@ -1084,12 +1080,12 @@ static bool ar5008_hw_ani_control_old(struct ath_hw *ah,
break;
}
case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{
- const int m1ThreshLow[] = { 127, 50 };
- const int m2ThreshLow[] = { 127, 40 };
- const int m1Thresh[] = { 127, 0x4d };
- const int m2Thresh[] = { 127, 0x40 };
- const int m2CountThr[] = { 31, 16 };
- const int m2CountThrLow[] = { 63, 48 };
+ static const int m1ThreshLow[] = { 127, 50 };
+ static const int m2ThreshLow[] = { 127, 40 };
+ static const int m1Thresh[] = { 127, 0x4d };
+ static const int m2Thresh[] = { 127, 0x40 };
+ static const int m2CountThr[] = { 31, 16 };
+ static const int m2CountThrLow[] = { 63, 48 };
u32 on = param ? 1 : 0;
REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
@@ -1141,7 +1137,7 @@ static bool ar5008_hw_ani_control_old(struct ath_hw *ah,
break;
}
case ATH9K_ANI_CCK_WEAK_SIGNAL_THR:{
- const int weakSigThrCck[] = { 8, 6 };
+ static const int weakSigThrCck[] = { 8, 6 };
u32 high = param ? 1 : 0;
REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT,
@@ -1157,14 +1153,13 @@ static bool ar5008_hw_ani_control_old(struct ath_hw *ah,
break;
}
case ATH9K_ANI_FIRSTEP_LEVEL:{
- const int firstep[] = { 0, 4, 8 };
+ static const int firstep[] = { 0, 4, 8 };
u32 level = param;
if (level >= ARRAY_SIZE(firstep)) {
- ath_print(common, ATH_DBG_ANI,
- "level out of range (%u > %u)\n",
- level,
- (unsigned) ARRAY_SIZE(firstep));
+ ath_dbg(common, ATH_DBG_ANI,
+ "level out of range (%u > %zu)\n",
+ level, ARRAY_SIZE(firstep));
return false;
}
REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
@@ -1178,14 +1173,13 @@ static bool ar5008_hw_ani_control_old(struct ath_hw *ah,
break;
}
case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{
- const int cycpwrThr1[] = { 2, 4, 6, 8, 10, 12, 14, 16 };
+ static const int cycpwrThr1[] = { 2, 4, 6, 8, 10, 12, 14, 16 };
u32 level = param;
if (level >= ARRAY_SIZE(cycpwrThr1)) {
- ath_print(common, ATH_DBG_ANI,
- "level out of range (%u > %u)\n",
- level,
- (unsigned) ARRAY_SIZE(cycpwrThr1));
+ ath_dbg(common, ATH_DBG_ANI,
+ "level out of range (%u > %zu)\n",
+ level, ARRAY_SIZE(cycpwrThr1));
return false;
}
REG_RMW_FIELD(ah, AR_PHY_TIMING5,
@@ -1201,25 +1195,22 @@ static bool ar5008_hw_ani_control_old(struct ath_hw *ah,
case ATH9K_ANI_PRESENT:
break;
default:
- ath_print(common, ATH_DBG_ANI,
- "invalid cmd %u\n", cmd);
+ ath_dbg(common, ATH_DBG_ANI, "invalid cmd %u\n", cmd);
return false;
}
- ath_print(common, ATH_DBG_ANI, "ANI parameters:\n");
- ath_print(common, ATH_DBG_ANI,
- "noiseImmunityLevel=%d, spurImmunityLevel=%d, "
- "ofdmWeakSigDetectOff=%d\n",
- aniState->noiseImmunityLevel,
- aniState->spurImmunityLevel,
- !aniState->ofdmWeakSigDetectOff);
- ath_print(common, ATH_DBG_ANI,
- "cckWeakSigThreshold=%d, "
- "firstepLevel=%d, listenTime=%d\n",
- aniState->cckWeakSigThreshold,
- aniState->firstepLevel,
- aniState->listenTime);
- ath_print(common, ATH_DBG_ANI,
+ ath_dbg(common, ATH_DBG_ANI, "ANI parameters:\n");
+ ath_dbg(common, ATH_DBG_ANI,
+ "noiseImmunityLevel=%d, spurImmunityLevel=%d, ofdmWeakSigDetectOff=%d\n",
+ aniState->noiseImmunityLevel,
+ aniState->spurImmunityLevel,
+ !aniState->ofdmWeakSigDetectOff);
+ ath_dbg(common, ATH_DBG_ANI,
+ "cckWeakSigThreshold=%d, firstepLevel=%d, listenTime=%d\n",
+ aniState->cckWeakSigThreshold,
+ aniState->firstepLevel,
+ aniState->listenTime);
+ ath_dbg(common, ATH_DBG_ANI,
"ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n",
aniState->ofdmPhyErrCount,
aniState->cckPhyErrCount);
@@ -1304,12 +1295,12 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah,
AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
if (!on != aniState->ofdmWeakSigDetectOff) {
- ath_print(common, ATH_DBG_ANI,
- "** ch %d: ofdm weak signal: %s=>%s\n",
- chan->channel,
- !aniState->ofdmWeakSigDetectOff ?
- "on" : "off",
- on ? "on" : "off");
+ ath_dbg(common, ATH_DBG_ANI,
+ "** ch %d: ofdm weak signal: %s=>%s\n",
+ chan->channel,
+ !aniState->ofdmWeakSigDetectOff ?
+ "on" : "off",
+ on ? "on" : "off");
if (on)
ah->stats.ast_ani_ofdmon++;
else
@@ -1322,11 +1313,9 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah,
u32 level = param;
if (level >= ARRAY_SIZE(firstep_table)) {
- ath_print(common, ATH_DBG_ANI,
- "ATH9K_ANI_FIRSTEP_LEVEL: level "
- "out of range (%u > %u)\n",
- level,
- (unsigned) ARRAY_SIZE(firstep_table));
+ ath_dbg(common, ATH_DBG_ANI,
+ "ATH9K_ANI_FIRSTEP_LEVEL: level out of range (%u > %zu)\n",
+ level, ARRAY_SIZE(firstep_table));
return false;
}
@@ -1361,24 +1350,22 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah,
AR_PHY_FIND_SIG_FIRSTEP_LOW, value2);
if (level != aniState->firstepLevel) {
- ath_print(common, ATH_DBG_ANI,
- "** ch %d: level %d=>%d[def:%d] "
- "firstep[level]=%d ini=%d\n",
- chan->channel,
- aniState->firstepLevel,
- level,
- ATH9K_ANI_FIRSTEP_LVL_NEW,
- value,
- aniState->iniDef.firstep);
- ath_print(common, ATH_DBG_ANI,
- "** ch %d: level %d=>%d[def:%d] "
- "firstep_low[level]=%d ini=%d\n",
- chan->channel,
- aniState->firstepLevel,
- level,
- ATH9K_ANI_FIRSTEP_LVL_NEW,
- value2,
- aniState->iniDef.firstepLow);
+ ath_dbg(common, ATH_DBG_ANI,
+ "** ch %d: level %d=>%d[def:%d] firstep[level]=%d ini=%d\n",
+ chan->channel,
+ aniState->firstepLevel,
+ level,
+ ATH9K_ANI_FIRSTEP_LVL_NEW,
+ value,
+ aniState->iniDef.firstep);
+ ath_dbg(common, ATH_DBG_ANI,
+ "** ch %d: level %d=>%d[def:%d] firstep_low[level]=%d ini=%d\n",
+ chan->channel,
+ aniState->firstepLevel,
+ level,
+ ATH9K_ANI_FIRSTEP_LVL_NEW,
+ value2,
+ aniState->iniDef.firstepLow);
if (level > aniState->firstepLevel)
ah->stats.ast_ani_stepup++;
else if (level < aniState->firstepLevel)
@@ -1391,11 +1378,9 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah,
u32 level = param;
if (level >= ARRAY_SIZE(cycpwrThr1_table)) {
- ath_print(common, ATH_DBG_ANI,
- "ATH9K_ANI_SPUR_IMMUNITY_LEVEL: level "
- "out of range (%u > %u)\n",
- level,
- (unsigned) ARRAY_SIZE(cycpwrThr1_table));
+ ath_dbg(common, ATH_DBG_ANI,
+ "ATH9K_ANI_SPUR_IMMUNITY_LEVEL: level out of range (%u > %zu)\n",
+ level, ARRAY_SIZE(cycpwrThr1_table));
return false;
}
/*
@@ -1429,24 +1414,22 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah,
AR_PHY_EXT_TIMING5_CYCPWR_THR1, value2);
if (level != aniState->spurImmunityLevel) {
- ath_print(common, ATH_DBG_ANI,
- "** ch %d: level %d=>%d[def:%d] "
- "cycpwrThr1[level]=%d ini=%d\n",
- chan->channel,
- aniState->spurImmunityLevel,
- level,
- ATH9K_ANI_SPUR_IMMUNE_LVL_NEW,
- value,
- aniState->iniDef.cycpwrThr1);
- ath_print(common, ATH_DBG_ANI,
- "** ch %d: level %d=>%d[def:%d] "
- "cycpwrThr1Ext[level]=%d ini=%d\n",
- chan->channel,
- aniState->spurImmunityLevel,
- level,
- ATH9K_ANI_SPUR_IMMUNE_LVL_NEW,
- value2,
- aniState->iniDef.cycpwrThr1Ext);
+ ath_dbg(common, ATH_DBG_ANI,
+ "** ch %d: level %d=>%d[def:%d] cycpwrThr1[level]=%d ini=%d\n",
+ chan->channel,
+ aniState->spurImmunityLevel,
+ level,
+ ATH9K_ANI_SPUR_IMMUNE_LVL_NEW,
+ value,
+ aniState->iniDef.cycpwrThr1);
+ ath_dbg(common, ATH_DBG_ANI,
+ "** ch %d: level %d=>%d[def:%d] cycpwrThr1Ext[level]=%d ini=%d\n",
+ chan->channel,
+ aniState->spurImmunityLevel,
+ level,
+ ATH9K_ANI_SPUR_IMMUNE_LVL_NEW,
+ value2,
+ aniState->iniDef.cycpwrThr1Ext);
if (level > aniState->spurImmunityLevel)
ah->stats.ast_ani_spurup++;
else if (level < aniState->spurImmunityLevel)
@@ -1465,22 +1448,19 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah,
case ATH9K_ANI_PRESENT:
break;
default:
- ath_print(common, ATH_DBG_ANI,
- "invalid cmd %u\n", cmd);
+ ath_dbg(common, ATH_DBG_ANI, "invalid cmd %u\n", cmd);
return false;
}
- ath_print(common, ATH_DBG_ANI,
- "ANI parameters: SI=%d, ofdmWS=%s FS=%d "
- "MRCcck=%s listenTime=%d "
- "ofdmErrs=%d cckErrs=%d\n",
- aniState->spurImmunityLevel,
- !aniState->ofdmWeakSigDetectOff ? "on" : "off",
- aniState->firstepLevel,
- !aniState->mrcCCKOff ? "on" : "off",
- aniState->listenTime,
- aniState->ofdmPhyErrCount,
- aniState->cckPhyErrCount);
+ ath_dbg(common, ATH_DBG_ANI,
+ "ANI parameters: SI=%d, ofdmWS=%s FS=%d MRCcck=%s listenTime=%d ofdmErrs=%d cckErrs=%d\n",
+ aniState->spurImmunityLevel,
+ !aniState->ofdmWeakSigDetectOff ? "on" : "off",
+ aniState->firstepLevel,
+ !aniState->mrcCCKOff ? "on" : "off",
+ aniState->listenTime,
+ aniState->ofdmPhyErrCount,
+ aniState->cckPhyErrCount);
return true;
}
@@ -1490,25 +1470,25 @@ static void ar5008_hw_do_getnf(struct ath_hw *ah,
int16_t nf;
nf = MS(REG_READ(ah, AR_PHY_CCA), AR_PHY_MINCCA_PWR);
- nfarray[0] = sign_extend(nf, 9);
+ nfarray[0] = sign_extend32(nf, 8);
nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), AR_PHY_CH1_MINCCA_PWR);
- nfarray[1] = sign_extend(nf, 9);
+ nfarray[1] = sign_extend32(nf, 8);
nf = MS(REG_READ(ah, AR_PHY_CH2_CCA), AR_PHY_CH2_MINCCA_PWR);
- nfarray[2] = sign_extend(nf, 9);
+ nfarray[2] = sign_extend32(nf, 8);
if (!IS_CHAN_HT40(ah->curchan))
return;
nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR);
- nfarray[3] = sign_extend(nf, 9);
+ nfarray[3] = sign_extend32(nf, 8);
nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), AR_PHY_CH1_EXT_MINCCA_PWR);
- nfarray[4] = sign_extend(nf, 9);
+ nfarray[4] = sign_extend32(nf, 8);
nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA), AR_PHY_CH2_EXT_MINCCA_PWR);
- nfarray[5] = sign_extend(nf, 9);
+ nfarray[5] = sign_extend32(nf, 8);
}
/*
@@ -1526,13 +1506,12 @@ static void ar5008_hw_ani_cache_ini_regs(struct ath_hw *ah)
iniDef = &aniState->iniDef;
- ath_print(common, ATH_DBG_ANI,
- "ver %d.%d opmode %u chan %d Mhz/0x%x\n",
- ah->hw_version.macVersion,
- ah->hw_version.macRev,
- ah->opmode,
- chan->channel,
- chan->channelFlags);
+ ath_dbg(common, ATH_DBG_ANI, "ver %d.%d opmode %u chan %d Mhz/0x%x\n",
+ ah->hw_version.macVersion,
+ ah->hw_version.macRev,
+ ah->opmode,
+ chan->channel,
+ chan->channelFlags);
val = REG_READ(ah, AR_PHY_SFCORR);
iniDef->m1Thresh = MS(val, AR_PHY_SFCORR_M1_THRESH);
@@ -1579,10 +1558,55 @@ static void ar5008_hw_set_nf_limits(struct ath_hw *ah)
ah->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_5416_5GHZ;
}
+static void ar5008_hw_set_radar_params(struct ath_hw *ah,
+ struct ath_hw_radar_conf *conf)
+{
+ u32 radar_0 = 0, radar_1 = 0;
+
+ if (!conf) {
+ REG_CLR_BIT(ah, AR_PHY_RADAR_0, AR_PHY_RADAR_0_ENA);
+ return;
+ }
+
+ radar_0 |= AR_PHY_RADAR_0_ENA | AR_PHY_RADAR_0_FFT_ENA;
+ radar_0 |= SM(conf->fir_power, AR_PHY_RADAR_0_FIRPWR);
+ radar_0 |= SM(conf->radar_rssi, AR_PHY_RADAR_0_RRSSI);
+ radar_0 |= SM(conf->pulse_height, AR_PHY_RADAR_0_HEIGHT);
+ radar_0 |= SM(conf->pulse_rssi, AR_PHY_RADAR_0_PRSSI);
+ radar_0 |= SM(conf->pulse_inband, AR_PHY_RADAR_0_INBAND);
+
+ radar_1 |= AR_PHY_RADAR_1_MAX_RRSSI;
+ radar_1 |= AR_PHY_RADAR_1_BLOCK_CHECK;
+ radar_1 |= SM(conf->pulse_maxlen, AR_PHY_RADAR_1_MAXLEN);
+ radar_1 |= SM(conf->pulse_inband_step, AR_PHY_RADAR_1_RELSTEP_THRESH);
+ radar_1 |= SM(conf->radar_inband, AR_PHY_RADAR_1_RELPWR_THRESH);
+
+ REG_WRITE(ah, AR_PHY_RADAR_0, radar_0);
+ REG_WRITE(ah, AR_PHY_RADAR_1, radar_1);
+ if (conf->ext_channel)
+ REG_SET_BIT(ah, AR_PHY_RADAR_EXT, AR_PHY_RADAR_EXT_ENA);
+ else
+ REG_CLR_BIT(ah, AR_PHY_RADAR_EXT, AR_PHY_RADAR_EXT_ENA);
+}
+
+static void ar5008_hw_set_radar_conf(struct ath_hw *ah)
+{
+ struct ath_hw_radar_conf *conf = &ah->radar_conf;
+
+ conf->fir_power = -33;
+ conf->radar_rssi = 20;
+ conf->pulse_height = 10;
+ conf->pulse_rssi = 24;
+ conf->pulse_inband = 15;
+ conf->pulse_maxlen = 255;
+ conf->pulse_inband_step = 12;
+ conf->radar_inband = 8;
+}
+
void ar5008_hw_attach_phy_ops(struct ath_hw *ah)
{
struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
- const u32 ar5416_cca_regs[6] = {
+ static const u32 ar5416_cca_regs[6] = {
AR_PHY_CCA,
AR_PHY_CH1_CCA,
AR_PHY_CH2_CCA,
@@ -1609,6 +1633,7 @@ void ar5008_hw_attach_phy_ops(struct ath_hw *ah)
priv_ops->restore_chainmask = ar5008_restore_chainmask;
priv_ops->set_diversity = ar5008_set_diversity;
priv_ops->do_getnf = ar5008_hw_do_getnf;
+ priv_ops->set_radar_params = ar5008_hw_set_radar_params;
if (modparam_force_new_ani) {
priv_ops->ani_control = ar5008_hw_ani_control_new;
@@ -1624,5 +1649,6 @@ void ar5008_hw_attach_phy_ops(struct ath_hw *ah)
priv_ops->compute_pll_control = ar5008_hw_compute_pll_control;
ar5008_hw_set_nf_limits(ah);
+ ar5008_hw_set_radar_conf(ah);
memcpy(ah->nf_regs, ar5416_cca_regs, sizeof(ah->nf_regs));
}
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
index 15f62cd0cc38..01880aa13e36 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
@@ -39,18 +39,18 @@ static void ar9002_hw_setup_calibration(struct ath_hw *ah,
switch (currCal->calData->calType) {
case IQ_MISMATCH_CAL:
REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
- ath_print(common, ATH_DBG_CALIBRATE,
- "starting IQ Mismatch Calibration\n");
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "starting IQ Mismatch Calibration\n");
break;
case ADC_GAIN_CAL:
REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN);
- ath_print(common, ATH_DBG_CALIBRATE,
- "starting ADC Gain Calibration\n");
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "starting ADC Gain Calibration\n");
break;
case ADC_DC_CAL:
REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER);
- ath_print(common, ATH_DBG_CALIBRATE,
- "starting ADC DC Calibration\n");
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "starting ADC DC Calibration\n");
break;
}
@@ -107,11 +107,11 @@ static void ar9002_hw_iqcal_collect(struct ath_hw *ah)
REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
ah->totalIqCorrMeas[i] +=
(int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
- ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
- "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
- ah->cal_samples, i, ah->totalPowerMeasI[i],
- ah->totalPowerMeasQ[i],
- ah->totalIqCorrMeas[i]);
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
+ "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
+ ah->cal_samples, i, ah->totalPowerMeasI[i],
+ ah->totalPowerMeasQ[i],
+ ah->totalIqCorrMeas[i]);
}
}
@@ -129,14 +129,13 @@ static void ar9002_hw_adc_gaincal_collect(struct ath_hw *ah)
ah->totalAdcQEvenPhase[i] +=
REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
- ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
- "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
- "oddq=0x%08x; evenq=0x%08x;\n",
- ah->cal_samples, i,
- ah->totalAdcIOddPhase[i],
- ah->totalAdcIEvenPhase[i],
- ah->totalAdcQOddPhase[i],
- ah->totalAdcQEvenPhase[i]);
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
+ "%d: Chn %d oddi=0x%08x; eveni=0x%08x; oddq=0x%08x; evenq=0x%08x;\n",
+ ah->cal_samples, i,
+ ah->totalAdcIOddPhase[i],
+ ah->totalAdcIEvenPhase[i],
+ ah->totalAdcQOddPhase[i],
+ ah->totalAdcQEvenPhase[i]);
}
}
@@ -154,14 +153,13 @@ static void ar9002_hw_adc_dccal_collect(struct ath_hw *ah)
ah->totalAdcDcOffsetQEvenPhase[i] +=
(int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
- ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
- "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
- "oddq=0x%08x; evenq=0x%08x;\n",
- ah->cal_samples, i,
- ah->totalAdcDcOffsetIOddPhase[i],
- ah->totalAdcDcOffsetIEvenPhase[i],
- ah->totalAdcDcOffsetQOddPhase[i],
- ah->totalAdcDcOffsetQEvenPhase[i]);
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
+ "%d: Chn %d oddi=0x%08x; eveni=0x%08x; oddq=0x%08x; evenq=0x%08x;\n",
+ ah->cal_samples, i,
+ ah->totalAdcDcOffsetIOddPhase[i],
+ ah->totalAdcDcOffsetIEvenPhase[i],
+ ah->totalAdcDcOffsetQOddPhase[i],
+ ah->totalAdcDcOffsetQEvenPhase[i]);
}
}
@@ -178,13 +176,13 @@ static void ar9002_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
powerMeasQ = ah->totalPowerMeasQ[i];
iqCorrMeas = ah->totalIqCorrMeas[i];
- ath_print(common, ATH_DBG_CALIBRATE,
- "Starting IQ Cal and Correction for Chain %d\n",
- i);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Starting IQ Cal and Correction for Chain %d\n",
+ i);
- ath_print(common, ATH_DBG_CALIBRATE,
- "Orignal: Chn %diq_corr_meas = 0x%08x\n",
- i, ah->totalIqCorrMeas[i]);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Orignal: Chn %diq_corr_meas = 0x%08x\n",
+ i, ah->totalIqCorrMeas[i]);
iqCorrNeg = 0;
@@ -193,12 +191,12 @@ static void ar9002_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
iqCorrNeg = 1;
}
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI);
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ);
- ath_print(common, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n",
- iqCorrNeg);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ);
+ ath_dbg(common, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n",
+ iqCorrNeg);
iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128;
qCoffDenom = powerMeasQ / 64;
@@ -207,14 +205,14 @@ static void ar9002_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
(qCoffDenom != 0)) {
iCoff = iqCorrMeas / iCoffDenom;
qCoff = powerMeasI / qCoffDenom - 64;
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d iCoff = 0x%08x\n", i, iCoff);
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d qCoff = 0x%08x\n", i, qCoff);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Chn %d iCoff = 0x%08x\n", i, iCoff);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Chn %d qCoff = 0x%08x\n", i, qCoff);
iCoff = iCoff & 0x3f;
- ath_print(common, ATH_DBG_CALIBRATE,
- "New: Chn %d iCoff = 0x%08x\n", i, iCoff);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "New: Chn %d iCoff = 0x%08x\n", i, iCoff);
if (iqCorrNeg == 0x0)
iCoff = 0x40 - iCoff;
@@ -223,9 +221,9 @@ static void ar9002_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
else if (qCoff <= -16)
qCoff = -16;
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d : iCoff = 0x%x qCoff = 0x%x\n",
- i, iCoff, qCoff);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Chn %d : iCoff = 0x%x qCoff = 0x%x\n",
+ i, iCoff, qCoff);
REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF,
@@ -233,9 +231,9 @@ static void ar9002_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF,
qCoff);
- ath_print(common, ATH_DBG_CALIBRATE,
- "IQ Cal and Correction done for Chain %d\n",
- i);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "IQ Cal and Correction done for Chain %d\n",
+ i);
}
}
@@ -255,21 +253,21 @@ static void ar9002_hw_adc_gaincal_calibrate(struct ath_hw *ah, u8 numChains)
qOddMeasOffset = ah->totalAdcQOddPhase[i];
qEvenMeasOffset = ah->totalAdcQEvenPhase[i];
- ath_print(common, ATH_DBG_CALIBRATE,
- "Starting ADC Gain Cal for Chain %d\n", i);
-
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d pwr_meas_odd_i = 0x%08x\n", i,
- iOddMeasOffset);
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d pwr_meas_even_i = 0x%08x\n", i,
- iEvenMeasOffset);
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d pwr_meas_odd_q = 0x%08x\n", i,
- qOddMeasOffset);
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d pwr_meas_even_q = 0x%08x\n", i,
- qEvenMeasOffset);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Starting ADC Gain Cal for Chain %d\n", i);
+
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Chn %d pwr_meas_odd_i = 0x%08x\n", i,
+ iOddMeasOffset);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Chn %d pwr_meas_even_i = 0x%08x\n", i,
+ iEvenMeasOffset);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Chn %d pwr_meas_odd_q = 0x%08x\n", i,
+ qOddMeasOffset);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Chn %d pwr_meas_even_q = 0x%08x\n", i,
+ qEvenMeasOffset);
if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) {
iGainMismatch =
@@ -279,20 +277,20 @@ static void ar9002_hw_adc_gaincal_calibrate(struct ath_hw *ah, u8 numChains)
((qOddMeasOffset * 32) /
qEvenMeasOffset) & 0x3f;
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d gain_mismatch_i = 0x%08x\n", i,
- iGainMismatch);
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d gain_mismatch_q = 0x%08x\n", i,
- qGainMismatch);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Chn %d gain_mismatch_i = 0x%08x\n", i,
+ iGainMismatch);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Chn %d gain_mismatch_q = 0x%08x\n", i,
+ qGainMismatch);
val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
val &= 0xfffff000;
val |= (qGainMismatch) | (iGainMismatch << 6);
REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
- ath_print(common, ATH_DBG_CALIBRATE,
- "ADC Gain Cal done for Chain %d\n", i);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "ADC Gain Cal done for Chain %d\n", i);
}
}
@@ -317,41 +315,41 @@ static void ar9002_hw_adc_dccal_calibrate(struct ath_hw *ah, u8 numChains)
qOddMeasOffset = ah->totalAdcDcOffsetQOddPhase[i];
qEvenMeasOffset = ah->totalAdcDcOffsetQEvenPhase[i];
- ath_print(common, ATH_DBG_CALIBRATE,
- "Starting ADC DC Offset Cal for Chain %d\n", i);
-
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d pwr_meas_odd_i = %d\n", i,
- iOddMeasOffset);
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d pwr_meas_even_i = %d\n", i,
- iEvenMeasOffset);
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d pwr_meas_odd_q = %d\n", i,
- qOddMeasOffset);
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d pwr_meas_even_q = %d\n", i,
- qEvenMeasOffset);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Starting ADC DC Offset Cal for Chain %d\n", i);
+
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Chn %d pwr_meas_odd_i = %d\n", i,
+ iOddMeasOffset);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Chn %d pwr_meas_even_i = %d\n", i,
+ iEvenMeasOffset);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Chn %d pwr_meas_odd_q = %d\n", i,
+ qOddMeasOffset);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Chn %d pwr_meas_even_q = %d\n", i,
+ qEvenMeasOffset);
iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) /
numSamples) & 0x1ff;
qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) /
numSamples) & 0x1ff;
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d dc_offset_mismatch_i = 0x%08x\n", i,
- iDcMismatch);
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d dc_offset_mismatch_q = 0x%08x\n", i,
- qDcMismatch);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Chn %d dc_offset_mismatch_i = 0x%08x\n", i,
+ iDcMismatch);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Chn %d dc_offset_mismatch_q = 0x%08x\n", i,
+ qDcMismatch);
val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
val &= 0xc0000fff;
val |= (qDcMismatch << 12) | (iDcMismatch << 21);
REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
- ath_print(common, ATH_DBG_CALIBRATE,
- "ADC DC Offset Cal done for Chain %d\n", i);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "ADC DC Offset Cal done for Chain %d\n", i);
}
REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
@@ -540,7 +538,7 @@ static inline void ar9285_hw_pa_cal(struct ath_hw *ah, bool is_reset)
{ 0x7838, 0 },
};
- ath_print(common, ATH_DBG_CALIBRATE, "Running PA Calibration\n");
+ ath_dbg(common, ATH_DBG_CALIBRATE, "Running PA Calibration\n");
/* PA CAL is not needed for high power solution */
if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) ==
@@ -721,9 +719,8 @@ static bool ar9285_hw_cl_cal(struct ath_hw *ah, struct ath9k_channel *chan)
REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
AR_PHY_AGC_CONTROL_CAL, 0, AH_WAIT_TIMEOUT)) {
- ath_print(common, ATH_DBG_CALIBRATE, "offset "
- "calibration failed to complete in "
- "1ms; noisy ??\n");
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "offset calibration failed to complete in 1ms; noisy environment?\n");
return false;
}
REG_CLR_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
@@ -736,8 +733,8 @@ static bool ar9285_hw_cl_cal(struct ath_hw *ah, struct ath9k_channel *chan)
REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
0, AH_WAIT_TIMEOUT)) {
- ath_print(common, ATH_DBG_CALIBRATE, "offset calibration "
- "failed to complete in 1ms; noisy ??\n");
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "offset calibration failed to complete in 1ms; noisy environment?\n");
return false;
}
@@ -829,9 +826,8 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
AR_PHY_AGC_CONTROL_CAL,
0, AH_WAIT_TIMEOUT)) {
- ath_print(common, ATH_DBG_CALIBRATE,
- "offset calibration failed to "
- "complete in 1ms; noisy environment?\n");
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "offset calibration failed to complete in 1ms; noisy environment?\n");
return false;
}
@@ -866,19 +862,19 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
INIT_CAL(&ah->adcgain_caldata);
INSERT_CAL(ah, &ah->adcgain_caldata);
- ath_print(common, ATH_DBG_CALIBRATE,
- "enabling ADC Gain Calibration.\n");
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "enabling ADC Gain Calibration.\n");
INIT_CAL(&ah->adcdc_caldata);
INSERT_CAL(ah, &ah->adcdc_caldata);
- ath_print(common, ATH_DBG_CALIBRATE,
- "enabling ADC DC Calibration.\n");
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "enabling ADC DC Calibration.\n");
}
INIT_CAL(&ah->iq_caldata);
INSERT_CAL(ah, &ah->iq_caldata);
- ath_print(common, ATH_DBG_CALIBRATE,
- "enabling IQ Calibration.\n");
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "enabling IQ Calibration.\n");
ah->cal_list_curr = ah->cal_list;
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
index 48261b7252d0..7d5cb204f938 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
@@ -494,9 +494,9 @@ int ar9002_hw_rf_claim(struct ath_hw *ah)
case AR_RAD2122_SREV_MAJOR:
break;
default:
- ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
- "Radio Chip Rev 0x%02X not supported\n",
- val & AR_RADIO_SREV_MAJOR);
+ ath_err(ath9k_hw_common(ah),
+ "Radio Chip Rev 0x%02X not supported\n",
+ val & AR_RADIO_SREV_MAJOR);
return -EOPNOTSUPP;
}
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
index 50dda394f8be..f3f9c589158e 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
@@ -90,13 +90,10 @@ static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
*masked = isr & ATH9K_INT_COMMON;
- if (ah->config.rx_intr_mitigation) {
- if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
- *masked |= ATH9K_INT_RX;
- }
-
- if (isr & (AR_ISR_RXOK | AR_ISR_RXERR))
+ if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM |
+ AR_ISR_RXOK | AR_ISR_RXERR))
*masked |= ATH9K_INT_RX;
+
if (isr &
(AR_ISR_TXOK | AR_ISR_TXDESC | AR_ISR_TXERR |
AR_ISR_TXEOL)) {
@@ -114,16 +111,8 @@ static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
}
if (isr & AR_ISR_RXORN) {
- ath_print(common, ATH_DBG_INTERRUPT,
- "receive FIFO overrun interrupt\n");
- }
-
- if (!AR_SREV_9100(ah)) {
- if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
- u32 isr5 = REG_READ(ah, AR_ISR_S5_S);
- if (isr5 & AR_ISR_S5_TIM_TIMER)
- *masked |= ATH9K_INT_TIM_TIMER;
- }
+ ath_dbg(common, ATH_DBG_INTERRUPT,
+ "receive FIFO overrun interrupt\n");
}
*masked |= mask2;
@@ -136,17 +125,18 @@ static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
u32 s5_s;
s5_s = REG_READ(ah, AR_ISR_S5_S);
- if (isr & AR_ISR_GENTMR) {
- ah->intr_gen_timer_trigger =
+ ah->intr_gen_timer_trigger =
MS(s5_s, AR_ISR_S5_GENTIMER_TRIG);
- ah->intr_gen_timer_thresh =
- MS(s5_s, AR_ISR_S5_GENTIMER_THRESH);
+ ah->intr_gen_timer_thresh =
+ MS(s5_s, AR_ISR_S5_GENTIMER_THRESH);
- if (ah->intr_gen_timer_trigger)
- *masked |= ATH9K_INT_GENTIMER;
+ if (ah->intr_gen_timer_trigger)
+ *masked |= ATH9K_INT_GENTIMER;
- }
+ if ((s5_s & AR_ISR_S5_TIM_TIMER) &&
+ !(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
+ *masked |= ATH9K_INT_TIM_TIMER;
}
if (sync_cause) {
@@ -157,25 +147,25 @@ static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
if (fatal_int) {
if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) {
- ath_print(common, ATH_DBG_ANY,
- "received PCI FATAL interrupt\n");
+ ath_dbg(common, ATH_DBG_ANY,
+ "received PCI FATAL interrupt\n");
}
if (sync_cause & AR_INTR_SYNC_HOST1_PERR) {
- ath_print(common, ATH_DBG_ANY,
- "received PCI PERR interrupt\n");
+ ath_dbg(common, ATH_DBG_ANY,
+ "received PCI PERR interrupt\n");
}
*masked |= ATH9K_INT_FATAL;
}
if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
- ath_print(common, ATH_DBG_INTERRUPT,
- "AR_INTR_SYNC_RADM_CPL_TIMEOUT\n");
+ ath_dbg(common, ATH_DBG_INTERRUPT,
+ "AR_INTR_SYNC_RADM_CPL_TIMEOUT\n");
REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
REG_WRITE(ah, AR_RC, 0);
*masked |= ATH9K_INT_FATAL;
}
if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) {
- ath_print(common, ATH_DBG_INTERRUPT,
- "AR_INTR_SYNC_LOCAL_TIMEOUT\n");
+ ath_dbg(common, ATH_DBG_INTERRUPT,
+ "AR_INTR_SYNC_LOCAL_TIMEOUT\n");
}
REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
@@ -218,77 +208,70 @@ static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds,
struct ath_tx_status *ts)
{
struct ar5416_desc *ads = AR5416DESC(ds);
+ u32 status;
- if ((ads->ds_txstatus9 & AR_TxDone) == 0)
+ status = ACCESS_ONCE(ads->ds_txstatus9);
+ if ((status & AR_TxDone) == 0)
return -EINPROGRESS;
- ts->ts_seqnum = MS(ads->ds_txstatus9, AR_SeqNum);
ts->ts_tstamp = ads->AR_SendTimestamp;
ts->ts_status = 0;
ts->ts_flags = 0;
- if (ads->ds_txstatus1 & AR_FrmXmitOK)
+ if (status & AR_TxOpExceeded)
+ ts->ts_status |= ATH9K_TXERR_XTXOP;
+ ts->tid = MS(status, AR_TxTid);
+ ts->ts_rateindex = MS(status, AR_FinalTxIdx);
+ ts->ts_seqnum = MS(status, AR_SeqNum);
+
+ status = ACCESS_ONCE(ads->ds_txstatus0);
+ ts->ts_rssi_ctl0 = MS(status, AR_TxRSSIAnt00);
+ ts->ts_rssi_ctl1 = MS(status, AR_TxRSSIAnt01);
+ ts->ts_rssi_ctl2 = MS(status, AR_TxRSSIAnt02);
+ if (status & AR_TxBaStatus) {
+ ts->ts_flags |= ATH9K_TX_BA;
+ ts->ba_low = ads->AR_BaBitmapLow;
+ ts->ba_high = ads->AR_BaBitmapHigh;
+ }
+
+ status = ACCESS_ONCE(ads->ds_txstatus1);
+ if (status & AR_FrmXmitOK)
ts->ts_status |= ATH9K_TX_ACKED;
- if (ads->ds_txstatus1 & AR_ExcessiveRetries)
- ts->ts_status |= ATH9K_TXERR_XRETRY;
- if (ads->ds_txstatus1 & AR_Filtered)
- ts->ts_status |= ATH9K_TXERR_FILT;
- if (ads->ds_txstatus1 & AR_FIFOUnderrun) {
- ts->ts_status |= ATH9K_TXERR_FIFO;
- ath9k_hw_updatetxtriglevel(ah, true);
+ else {
+ if (status & AR_ExcessiveRetries)
+ ts->ts_status |= ATH9K_TXERR_XRETRY;
+ if (status & AR_Filtered)
+ ts->ts_status |= ATH9K_TXERR_FILT;
+ if (status & AR_FIFOUnderrun) {
+ ts->ts_status |= ATH9K_TXERR_FIFO;
+ ath9k_hw_updatetxtriglevel(ah, true);
+ }
}
- if (ads->ds_txstatus9 & AR_TxOpExceeded)
- ts->ts_status |= ATH9K_TXERR_XTXOP;
- if (ads->ds_txstatus1 & AR_TxTimerExpired)
+ if (status & AR_TxTimerExpired)
ts->ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
-
- if (ads->ds_txstatus1 & AR_DescCfgErr)
+ if (status & AR_DescCfgErr)
ts->ts_flags |= ATH9K_TX_DESC_CFG_ERR;
- if (ads->ds_txstatus1 & AR_TxDataUnderrun) {
+ if (status & AR_TxDataUnderrun) {
ts->ts_flags |= ATH9K_TX_DATA_UNDERRUN;
ath9k_hw_updatetxtriglevel(ah, true);
}
- if (ads->ds_txstatus1 & AR_TxDelimUnderrun) {
+ if (status & AR_TxDelimUnderrun) {
ts->ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
ath9k_hw_updatetxtriglevel(ah, true);
}
- if (ads->ds_txstatus0 & AR_TxBaStatus) {
- ts->ts_flags |= ATH9K_TX_BA;
- ts->ba_low = ads->AR_BaBitmapLow;
- ts->ba_high = ads->AR_BaBitmapHigh;
- }
+ ts->ts_shortretry = MS(status, AR_RTSFailCnt);
+ ts->ts_longretry = MS(status, AR_DataFailCnt);
+ ts->ts_virtcol = MS(status, AR_VirtRetryCnt);
- ts->ts_rateindex = MS(ads->ds_txstatus9, AR_FinalTxIdx);
- switch (ts->ts_rateindex) {
- case 0:
- ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate0);
- break;
- case 1:
- ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate1);
- break;
- case 2:
- ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate2);
- break;
- case 3:
- ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate3);
- break;
- }
+ status = ACCESS_ONCE(ads->ds_txstatus5);
+ ts->ts_rssi = MS(status, AR_TxRSSICombined);
+ ts->ts_rssi_ext0 = MS(status, AR_TxRSSIAnt10);
+ ts->ts_rssi_ext1 = MS(status, AR_TxRSSIAnt11);
+ ts->ts_rssi_ext2 = MS(status, AR_TxRSSIAnt12);
- ts->ts_rssi = MS(ads->ds_txstatus5, AR_TxRSSICombined);
- ts->ts_rssi_ctl0 = MS(ads->ds_txstatus0, AR_TxRSSIAnt00);
- ts->ts_rssi_ctl1 = MS(ads->ds_txstatus0, AR_TxRSSIAnt01);
- ts->ts_rssi_ctl2 = MS(ads->ds_txstatus0, AR_TxRSSIAnt02);
- ts->ts_rssi_ext0 = MS(ads->ds_txstatus5, AR_TxRSSIAnt10);
- ts->ts_rssi_ext1 = MS(ads->ds_txstatus5, AR_TxRSSIAnt11);
- ts->ts_rssi_ext2 = MS(ads->ds_txstatus5, AR_TxRSSIAnt12);
ts->evm0 = ads->AR_TxEVM0;
ts->evm1 = ads->AR_TxEVM1;
ts->evm2 = ads->AR_TxEVM2;
- ts->ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt);
- ts->ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt);
- ts->ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt);
- ts->tid = MS(ads->ds_txstatus9, AR_TxTid);
- ts->ts_antenna = 0;
return 0;
}
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
index c00cdc67b55b..7ae66a889f5a 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
@@ -175,13 +175,15 @@ static void ar9002_hw_spur_mitigate(struct ath_hw *ah,
int upper, lower, cur_vit_mask;
int tmp, newVal;
int i;
- int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
- AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
+ static const int pilot_mask_reg[4] = {
+ AR_PHY_TIMING7, AR_PHY_TIMING8,
+ AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
};
- int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
- AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
+ static const int chan_mask_reg[4] = {
+ AR_PHY_TIMING9, AR_PHY_TIMING10,
+ AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
};
- int inc[4] = { 0, 100, 0, 0 };
+ static const int inc[4] = { 0, 100, 0, 0 };
struct chan_centers centers;
int8_t mask_m[123];
@@ -473,21 +475,21 @@ static void ar9002_hw_do_getnf(struct ath_hw *ah,
int16_t nf;
nf = MS(REG_READ(ah, AR_PHY_CCA), AR9280_PHY_MINCCA_PWR);
- nfarray[0] = sign_extend(nf, 9);
+ nfarray[0] = sign_extend32(nf, 8);
nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR9280_PHY_EXT_MINCCA_PWR);
if (IS_CHAN_HT40(ah->curchan))
- nfarray[3] = sign_extend(nf, 9);
+ nfarray[3] = sign_extend32(nf, 8);
if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
return;
nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), AR9280_PHY_CH1_MINCCA_PWR);
- nfarray[1] = sign_extend(nf, 9);
+ nfarray[1] = sign_extend32(nf, 8);
nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), AR9280_PHY_CH1_EXT_MINCCA_PWR);
if (IS_CHAN_HT40(ah->curchan))
- nfarray[4] = sign_extend(nf, 9);
+ nfarray[4] = sign_extend32(nf, 8);
}
static void ar9002_hw_set_nf_limits(struct ath_hw *ah)
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
index 9e6edffe0bd1..7c3334bd396e 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
@@ -18,6 +18,16 @@
#include "hw-ops.h"
#include "ar9003_phy.h"
+#define MPASS 3
+#define MAX_MEASUREMENT 8
+#define MAX_DIFFERENCE 10
+
+struct coeff {
+ int mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MPASS];
+ int phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MPASS];
+ int iqc_coeff[2];
+};
+
enum ar9003_cal_types {
IQ_MISMATCH_CAL = BIT(0),
TEMP_COMP_CAL = BIT(1),
@@ -40,8 +50,8 @@ static void ar9003_hw_setup_calibration(struct ath_hw *ah,
currCal->calData->calCountMax);
REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
- ath_print(common, ATH_DBG_CALIBRATE,
- "starting IQ Mismatch Calibration\n");
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "starting IQ Mismatch Calibration\n");
/* Kick-off cal */
REG_SET_BIT(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_DO_CAL);
@@ -52,8 +62,8 @@ static void ar9003_hw_setup_calibration(struct ath_hw *ah,
REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_THERM,
AR_PHY_65NM_CH0_THERM_START, 1);
- ath_print(common, ATH_DBG_CALIBRATE,
- "starting Temperature Compensation Calibration\n");
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "starting Temperature Compensation Calibration\n");
break;
}
}
@@ -181,11 +191,11 @@ static void ar9003_hw_iqcal_collect(struct ath_hw *ah)
REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
ah->totalIqCorrMeas[i] +=
(int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
- ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
- "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
- ah->cal_samples, i, ah->totalPowerMeasI[i],
- ah->totalPowerMeasQ[i],
- ah->totalIqCorrMeas[i]);
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
+ "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
+ ah->cal_samples, i, ah->totalPowerMeasI[i],
+ ah->totalPowerMeasQ[i],
+ ah->totalIqCorrMeas[i]);
}
}
@@ -196,7 +206,7 @@ static void ar9003_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
u32 qCoffDenom, iCoffDenom;
int32_t qCoff, iCoff;
int iqCorrNeg, i;
- const u_int32_t offset_array[3] = {
+ static const u_int32_t offset_array[3] = {
AR_PHY_RX_IQCAL_CORR_B0,
AR_PHY_RX_IQCAL_CORR_B1,
AR_PHY_RX_IQCAL_CORR_B2,
@@ -207,13 +217,13 @@ static void ar9003_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
powerMeasQ = ah->totalPowerMeasQ[i];
iqCorrMeas = ah->totalIqCorrMeas[i];
- ath_print(common, ATH_DBG_CALIBRATE,
- "Starting IQ Cal and Correction for Chain %d\n",
- i);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Starting IQ Cal and Correction for Chain %d\n",
+ i);
- ath_print(common, ATH_DBG_CALIBRATE,
- "Orignal: Chn %diq_corr_meas = 0x%08x\n",
- i, ah->totalIqCorrMeas[i]);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Orignal: Chn %diq_corr_meas = 0x%08x\n",
+ i, ah->totalIqCorrMeas[i]);
iqCorrNeg = 0;
@@ -222,12 +232,12 @@ static void ar9003_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
iqCorrNeg = 1;
}
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI);
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ);
- ath_print(common, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n",
- iqCorrNeg);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ);
+ ath_dbg(common, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n",
+ iqCorrNeg);
iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 256;
qCoffDenom = powerMeasQ / 64;
@@ -235,10 +245,10 @@ static void ar9003_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
if ((iCoffDenom != 0) && (qCoffDenom != 0)) {
iCoff = iqCorrMeas / iCoffDenom;
qCoff = powerMeasI / qCoffDenom - 64;
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d iCoff = 0x%08x\n", i, iCoff);
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d qCoff = 0x%08x\n", i, qCoff);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Chn %d iCoff = 0x%08x\n", i, iCoff);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Chn %d qCoff = 0x%08x\n", i, qCoff);
/* Force bounds on iCoff */
if (iCoff >= 63)
@@ -259,14 +269,13 @@ static void ar9003_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
iCoff = iCoff & 0x7f;
qCoff = qCoff & 0x7f;
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d : iCoff = 0x%x qCoff = 0x%x\n",
- i, iCoff, qCoff);
- ath_print(common, ATH_DBG_CALIBRATE,
- "Register offset (0x%04x) "
- "before update = 0x%x\n",
- offset_array[i],
- REG_READ(ah, offset_array[i]));
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Chn %d : iCoff = 0x%x qCoff = 0x%x\n",
+ i, iCoff, qCoff);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Register offset (0x%04x) before update = 0x%x\n",
+ offset_array[i],
+ REG_READ(ah, offset_array[i]));
REG_RMW_FIELD(ah, offset_array[i],
AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF,
@@ -274,33 +283,29 @@ static void ar9003_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
REG_RMW_FIELD(ah, offset_array[i],
AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF,
qCoff);
- ath_print(common, ATH_DBG_CALIBRATE,
- "Register offset (0x%04x) QI COFF "
- "(bitfields 0x%08x) after update = 0x%x\n",
- offset_array[i],
- AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF,
- REG_READ(ah, offset_array[i]));
- ath_print(common, ATH_DBG_CALIBRATE,
- "Register offset (0x%04x) QQ COFF "
- "(bitfields 0x%08x) after update = 0x%x\n",
- offset_array[i],
- AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF,
- REG_READ(ah, offset_array[i]));
-
- ath_print(common, ATH_DBG_CALIBRATE,
- "IQ Cal and Correction done for Chain %d\n",
- i);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Register offset (0x%04x) QI COFF (bitfields 0x%08x) after update = 0x%x\n",
+ offset_array[i],
+ AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF,
+ REG_READ(ah, offset_array[i]));
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Register offset (0x%04x) QQ COFF (bitfields 0x%08x) after update = 0x%x\n",
+ offset_array[i],
+ AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF,
+ REG_READ(ah, offset_array[i]));
+
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "IQ Cal and Correction done for Chain %d\n", i);
}
}
REG_SET_BIT(ah, AR_PHY_RX_IQCAL_CORR_B0,
AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE);
- ath_print(common, ATH_DBG_CALIBRATE,
- "IQ Cal and Correction (offset 0x%04x) enabled "
- "(bit position 0x%08x). New Value 0x%08x\n",
- (unsigned) (AR_PHY_RX_IQCAL_CORR_B0),
- AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE,
- REG_READ(ah, AR_PHY_RX_IQCAL_CORR_B0));
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "IQ Cal and Correction (offset 0x%04x) enabled (bit position 0x%08x). New Value 0x%08x\n",
+ (unsigned) (AR_PHY_RX_IQCAL_CORR_B0),
+ AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE,
+ REG_READ(ah, AR_PHY_RX_IQCAL_CORR_B0));
}
static const struct ath9k_percal_data iq_cal_single_sample = {
@@ -340,7 +345,7 @@ static bool ar9003_hw_solve_iq_cal(struct ath_hw *ah,
f2 = (f1 * f1 + f3 * f3) / result_shift;
if (!f2) {
- ath_print(common, ATH_DBG_CALIBRATE, "Divide by 0\n");
+ ath_dbg(common, ATH_DBG_CALIBRATE, "Divide by 0\n");
return false;
}
@@ -461,11 +466,14 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah,
if ((i2_p_q2_a0_d0 == 0) || (i2_p_q2_a0_d1 == 0) ||
(i2_p_q2_a1_d0 == 0) || (i2_p_q2_a1_d1 == 0)) {
- ath_print(common, ATH_DBG_CALIBRATE,
- "Divide by 0:\na0_d0=%d\n"
- "a0_d1=%d\na2_d0=%d\na1_d1=%d\n",
- i2_p_q2_a0_d0, i2_p_q2_a0_d1,
- i2_p_q2_a1_d0, i2_p_q2_a1_d1);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Divide by 0:\n"
+ "a0_d0=%d\n"
+ "a0_d1=%d\n"
+ "a2_d0=%d\n"
+ "a1_d1=%d\n",
+ i2_p_q2_a0_d0, i2_p_q2_a0_d1,
+ i2_p_q2_a1_d0, i2_p_q2_a1_d1);
return false;
}
@@ -498,9 +506,9 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah,
mag2 = ar9003_hw_find_mag_approx(ah, cos_2phi_2, sin_2phi_2);
if ((mag1 == 0) || (mag2 == 0)) {
- ath_print(common, ATH_DBG_CALIBRATE,
- "Divide by 0: mag1=%d, mag2=%d\n",
- mag1, mag2);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Divide by 0: mag1=%d, mag2=%d\n",
+ mag1, mag2);
return false;
}
@@ -517,8 +525,8 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah,
mag_a0_d0, phs_a0_d0,
mag_a1_d0,
phs_a1_d0, solved_eq)) {
- ath_print(common, ATH_DBG_CALIBRATE,
- "Call to ar9003_hw_solve_iq_cal() failed.\n");
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Call to ar9003_hw_solve_iq_cal() failed.\n");
return false;
}
@@ -527,14 +535,14 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah,
mag_rx = solved_eq[2];
phs_rx = solved_eq[3];
- ath_print(common, ATH_DBG_CALIBRATE,
- "chain %d: mag mismatch=%d phase mismatch=%d\n",
- chain_idx, mag_tx/res_scale, phs_tx/res_scale);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "chain %d: mag mismatch=%d phase mismatch=%d\n",
+ chain_idx, mag_tx/res_scale, phs_tx/res_scale);
if (res_scale == mag_tx) {
- ath_print(common, ATH_DBG_CALIBRATE,
- "Divide by 0: mag_tx=%d, res_scale=%d\n",
- mag_tx, res_scale);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Divide by 0: mag_tx=%d, res_scale=%d\n",
+ mag_tx, res_scale);
return false;
}
@@ -545,9 +553,9 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah,
q_q_coff = (mag_corr_tx * 128 / res_scale);
q_i_coff = (phs_corr_tx * 256 / res_scale);
- ath_print(common, ATH_DBG_CALIBRATE,
- "tx chain %d: mag corr=%d phase corr=%d\n",
- chain_idx, q_q_coff, q_i_coff);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "tx chain %d: mag corr=%d phase corr=%d\n",
+ chain_idx, q_q_coff, q_i_coff);
if (q_i_coff < -63)
q_i_coff = -63;
@@ -560,14 +568,14 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah,
iqc_coeff[0] = (q_q_coff * 128) + q_i_coff;
- ath_print(common, ATH_DBG_CALIBRATE,
- "tx chain %d: iq corr coeff=%x\n",
- chain_idx, iqc_coeff[0]);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "tx chain %d: iq corr coeff=%x\n",
+ chain_idx, iqc_coeff[0]);
if (-mag_rx == res_scale) {
- ath_print(common, ATH_DBG_CALIBRATE,
- "Divide by 0: mag_rx=%d, res_scale=%d\n",
- mag_rx, res_scale);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Divide by 0: mag_rx=%d, res_scale=%d\n",
+ mag_rx, res_scale);
return false;
}
@@ -578,9 +586,9 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah,
q_q_coff = (mag_corr_rx * 128 / res_scale);
q_i_coff = (phs_corr_rx * 256 / res_scale);
- ath_print(common, ATH_DBG_CALIBRATE,
- "rx chain %d: mag corr=%d phase corr=%d\n",
- chain_idx, q_q_coff, q_i_coff);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "rx chain %d: mag corr=%d phase corr=%d\n",
+ chain_idx, q_q_coff, q_i_coff);
if (q_i_coff < -63)
q_i_coff = -63;
@@ -593,9 +601,9 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah,
iqc_coeff[1] = (q_q_coff * 128) + q_i_coff;
- ath_print(common, ATH_DBG_CALIBRATE,
- "rx chain %d: iq corr coeff=%x\n",
- chain_idx, iqc_coeff[1]);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "rx chain %d: iq corr coeff=%x\n",
+ chain_idx, iqc_coeff[1]);
return true;
}
@@ -603,31 +611,31 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah,
static void ar9003_hw_tx_iq_cal(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
- const u32 txiqcal_status[AR9300_MAX_CHAINS] = {
+ static const u32 txiqcal_status[AR9300_MAX_CHAINS] = {
AR_PHY_TX_IQCAL_STATUS_B0,
AR_PHY_TX_IQCAL_STATUS_B1,
AR_PHY_TX_IQCAL_STATUS_B2,
};
- const u32 tx_corr_coeff[AR9300_MAX_CHAINS] = {
- AR_PHY_TX_IQCAL_CORR_COEFF_01_B0,
- AR_PHY_TX_IQCAL_CORR_COEFF_01_B1,
- AR_PHY_TX_IQCAL_CORR_COEFF_01_B2,
- };
- const u32 rx_corr[AR9300_MAX_CHAINS] = {
+ static const u32 rx_corr[AR9300_MAX_CHAINS] = {
AR_PHY_RX_IQCAL_CORR_B0,
AR_PHY_RX_IQCAL_CORR_B1,
AR_PHY_RX_IQCAL_CORR_B2,
};
- const u_int32_t chan_info_tab[] = {
+ static const u_int32_t chan_info_tab[] = {
AR_PHY_CHAN_INFO_TAB_0,
AR_PHY_CHAN_INFO_TAB_1,
AR_PHY_CHAN_INFO_TAB_2,
};
+ u32 tx_corr_coeff[AR9300_MAX_CHAINS];
s32 iq_res[6];
s32 iqc_coeff[2];
s32 i, j;
u32 num_chains = 0;
+ tx_corr_coeff[0] = AR_PHY_TX_IQCAL_CORR_COEFF_B0(0);
+ tx_corr_coeff[1] = AR_PHY_TX_IQCAL_CORR_COEFF_B1(0);
+ tx_corr_coeff[2] = AR_PHY_TX_IQCAL_CORR_COEFF_B2(0);
+
for (i = 0; i < AR9300_MAX_CHAINS; i++) {
if (ah->txchainmask & (1 << i))
num_chains++;
@@ -643,19 +651,19 @@ static void ar9003_hw_tx_iq_cal(struct ath_hw *ah)
if (!ath9k_hw_wait(ah, AR_PHY_TX_IQCAL_START,
AR_PHY_TX_IQCAL_START_DO_CAL,
0, AH_WAIT_TIMEOUT)) {
- ath_print(common, ATH_DBG_CALIBRATE,
- "Tx IQ Cal not complete.\n");
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Tx IQ Cal not complete.\n");
goto TX_IQ_CAL_FAILED;
}
for (i = 0; i < num_chains; i++) {
- ath_print(common, ATH_DBG_CALIBRATE,
- "Doing Tx IQ Cal for chain %d.\n", i);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Doing Tx IQ Cal for chain %d.\n", i);
if (REG_READ(ah, txiqcal_status[i]) &
AR_PHY_TX_IQCAL_STATUS_FAILED) {
- ath_print(common, ATH_DBG_CALIBRATE,
- "Tx IQ Cal failed for chain %d.\n", i);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Tx IQ Cal failed for chain %d.\n", i);
goto TX_IQ_CAL_FAILED;
}
@@ -677,20 +685,20 @@ static void ar9003_hw_tx_iq_cal(struct ath_hw *ah)
chan_info_tab[i] +
offset);
- ath_print(common, ATH_DBG_CALIBRATE,
- "IQ RES[%d]=0x%x IQ_RES[%d]=0x%x\n",
- idx, iq_res[idx], idx+1, iq_res[idx+1]);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "IQ RES[%d]=0x%x IQ_RES[%d]=0x%x\n",
+ idx, iq_res[idx], idx+1, iq_res[idx+1]);
}
if (!ar9003_hw_calc_iq_corr(ah, i, iq_res, iqc_coeff)) {
- ath_print(common, ATH_DBG_CALIBRATE,
- "Failed in calculation of IQ correction.\n");
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Failed in calculation of IQ correction.\n");
goto TX_IQ_CAL_FAILED;
}
- ath_print(common, ATH_DBG_CALIBRATE,
- "IQ_COEFF[0] = 0x%x IQ_COEFF[1] = 0x%x\n",
- iqc_coeff[0], iqc_coeff[1]);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "IQ_COEFF[0] = 0x%x IQ_COEFF[1] = 0x%x\n",
+ iqc_coeff[0], iqc_coeff[1]);
REG_RMW_FIELD(ah, tx_corr_coeff[i],
AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
@@ -711,22 +719,258 @@ static void ar9003_hw_tx_iq_cal(struct ath_hw *ah)
return;
TX_IQ_CAL_FAILED:
- ath_print(common, ATH_DBG_CALIBRATE, "Tx IQ Cal failed\n");
+ ath_dbg(common, ATH_DBG_CALIBRATE, "Tx IQ Cal failed\n");
+}
+
+static bool ar9003_hw_compute_closest_pass_and_avg(int *mp_coeff, int *mp_avg)
+{
+ int diff[MPASS];
+
+ diff[0] = abs(mp_coeff[0] - mp_coeff[1]);
+ diff[1] = abs(mp_coeff[1] - mp_coeff[2]);
+ diff[2] = abs(mp_coeff[2] - mp_coeff[0]);
+
+ if (diff[0] > MAX_MEASUREMENT &&
+ diff[1] > MAX_MEASUREMENT &&
+ diff[2] > MAX_MEASUREMENT)
+ return false;
+
+ if (diff[0] <= diff[1] && diff[0] <= diff[2])
+ *mp_avg = (mp_coeff[0] + mp_coeff[1]) / 2;
+ else if (diff[1] <= diff[2])
+ *mp_avg = (mp_coeff[1] + mp_coeff[2]) / 2;
+ else
+ *mp_avg = (mp_coeff[2] + mp_coeff[0]) / 2;
+
+ return true;
+}
+
+static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah,
+ u8 num_chains,
+ struct coeff *coeff)
+{
+ struct ath_common *common = ath9k_hw_common(ah);
+ int i, im, nmeasurement;
+ int magnitude, phase;
+ u32 tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS];
+
+ memset(tx_corr_coeff, 0, sizeof(tx_corr_coeff));
+ for (i = 0; i < MAX_MEASUREMENT / 2; i++) {
+ tx_corr_coeff[i * 2][0] = tx_corr_coeff[(i * 2) + 1][0] =
+ AR_PHY_TX_IQCAL_CORR_COEFF_B0(i);
+ if (!AR_SREV_9485(ah)) {
+ tx_corr_coeff[i * 2][1] =
+ tx_corr_coeff[(i * 2) + 1][1] =
+ AR_PHY_TX_IQCAL_CORR_COEFF_B1(i);
+
+ tx_corr_coeff[i * 2][2] =
+ tx_corr_coeff[(i * 2) + 1][2] =
+ AR_PHY_TX_IQCAL_CORR_COEFF_B2(i);
+ }
+ }
+
+ /* Load the average of 2 passes */
+ for (i = 0; i < num_chains; i++) {
+ if (AR_SREV_9485(ah))
+ nmeasurement = REG_READ_FIELD(ah,
+ AR_PHY_TX_IQCAL_STATUS_B0_9485,
+ AR_PHY_CALIBRATED_GAINS_0);
+ else
+ nmeasurement = REG_READ_FIELD(ah,
+ AR_PHY_TX_IQCAL_STATUS_B0,
+ AR_PHY_CALIBRATED_GAINS_0);
+
+ if (nmeasurement > MAX_MEASUREMENT)
+ nmeasurement = MAX_MEASUREMENT;
+
+ for (im = 0; im < nmeasurement; im++) {
+ /*
+ * Determine which 2 passes are closest and compute avg
+ * magnitude
+ */
+ if (!ar9003_hw_compute_closest_pass_and_avg(coeff->mag_coeff[i][im],
+ &magnitude))
+ goto disable_txiqcal;
+
+ /*
+ * Determine which 2 passes are closest and compute avg
+ * phase
+ */
+ if (!ar9003_hw_compute_closest_pass_and_avg(coeff->phs_coeff[i][im],
+ &phase))
+ goto disable_txiqcal;
+
+ coeff->iqc_coeff[0] = (magnitude & 0x7f) |
+ ((phase & 0x7f) << 7);
+
+ if ((im % 2) == 0)
+ REG_RMW_FIELD(ah, tx_corr_coeff[im][i],
+ AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE,
+ coeff->iqc_coeff[0]);
+ else
+ REG_RMW_FIELD(ah, tx_corr_coeff[im][i],
+ AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
+ coeff->iqc_coeff[0]);
+ }
+ }
+
+ REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
+ AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1);
+ REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0,
+ AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1);
+
+ return;
+
+disable_txiqcal:
+ REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
+ AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x0);
+ REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0,
+ AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x0);
+
+ ath_dbg(common, ATH_DBG_CALIBRATE, "TX IQ Cal disabled\n");
+}
+
+static void ar9003_hw_tx_iq_cal_run(struct ath_hw *ah)
+{
+ u8 tx_gain_forced;
+
+ REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1_9485,
+ AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT, DELPT);
+ tx_gain_forced = REG_READ_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
+ AR_PHY_TXGAIN_FORCE);
+ if (tx_gain_forced)
+ REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
+ AR_PHY_TXGAIN_FORCE, 0);
+
+ REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START_9485,
+ AR_PHY_TX_IQCAL_START_DO_CAL_9485, 1);
}
+static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah)
+{
+ struct ath_common *common = ath9k_hw_common(ah);
+ const u32 txiqcal_status[AR9300_MAX_CHAINS] = {
+ AR_PHY_TX_IQCAL_STATUS_B0_9485,
+ AR_PHY_TX_IQCAL_STATUS_B1,
+ AR_PHY_TX_IQCAL_STATUS_B2,
+ };
+ const u_int32_t chan_info_tab[] = {
+ AR_PHY_CHAN_INFO_TAB_0,
+ AR_PHY_CHAN_INFO_TAB_1,
+ AR_PHY_CHAN_INFO_TAB_2,
+ };
+ struct coeff coeff;
+ s32 iq_res[6];
+ u8 num_chains = 0;
+ int i, ip, im, j;
+ int nmeasurement;
+
+ for (i = 0; i < AR9300_MAX_CHAINS; i++) {
+ if (ah->txchainmask & (1 << i))
+ num_chains++;
+ }
+
+ for (ip = 0; ip < MPASS; ip++) {
+ for (i = 0; i < num_chains; i++) {
+ nmeasurement = REG_READ_FIELD(ah,
+ AR_PHY_TX_IQCAL_STATUS_B0_9485,
+ AR_PHY_CALIBRATED_GAINS_0);
+ if (nmeasurement > MAX_MEASUREMENT)
+ nmeasurement = MAX_MEASUREMENT;
+
+ for (im = 0; im < nmeasurement; im++) {
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Doing Tx IQ Cal for chain %d.\n", i);
+
+ if (REG_READ(ah, txiqcal_status[i]) &
+ AR_PHY_TX_IQCAL_STATUS_FAILED) {
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Tx IQ Cal failed for chain %d.\n", i);
+ goto tx_iqcal_fail;
+ }
+
+ for (j = 0; j < 3; j++) {
+ u32 idx = 2 * j, offset = 4 * (3 * im + j);
+
+ REG_RMW_FIELD(ah,
+ AR_PHY_CHAN_INFO_MEMORY,
+ AR_PHY_CHAN_INFO_TAB_S2_READ,
+ 0);
+
+ /* 32 bits */
+ iq_res[idx] = REG_READ(ah,
+ chan_info_tab[i] +
+ offset);
+
+ REG_RMW_FIELD(ah,
+ AR_PHY_CHAN_INFO_MEMORY,
+ AR_PHY_CHAN_INFO_TAB_S2_READ,
+ 1);
+
+ /* 16 bits */
+ iq_res[idx + 1] = 0xffff & REG_READ(ah,
+ chan_info_tab[i] + offset);
+
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "IQ RES[%d]=0x%x"
+ "IQ_RES[%d]=0x%x\n",
+ idx, iq_res[idx], idx + 1,
+ iq_res[idx + 1]);
+ }
+
+ if (!ar9003_hw_calc_iq_corr(ah, i, iq_res,
+ coeff.iqc_coeff)) {
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Failed in calculation of IQ correction.\n");
+ goto tx_iqcal_fail;
+ }
+
+ coeff.mag_coeff[i][im][ip] =
+ coeff.iqc_coeff[0] & 0x7f;
+ coeff.phs_coeff[i][im][ip] =
+ (coeff.iqc_coeff[0] >> 7) & 0x7f;
+
+ if (coeff.mag_coeff[i][im][ip] > 63)
+ coeff.mag_coeff[i][im][ip] -= 128;
+ if (coeff.phs_coeff[i][im][ip] > 63)
+ coeff.phs_coeff[i][im][ip] -= 128;
+ }
+ }
+ }
+ ar9003_hw_tx_iqcal_load_avg_2_passes(ah, num_chains, &coeff);
+
+ return;
+
+tx_iqcal_fail:
+ ath_dbg(common, ATH_DBG_CALIBRATE, "Tx IQ Cal failed\n");
+ return;
+}
static bool ar9003_hw_init_cal(struct ath_hw *ah,
struct ath9k_channel *chan)
{
struct ath_common *common = ath9k_hw_common(ah);
+ int val;
- /*
- * 0x7 = 0b111 , AR9003 needs to be configured for 3-chain mode before
- * running AGC/TxIQ cals
- */
- ar9003_hw_set_chain_masks(ah, 0x7, 0x7);
+ val = REG_READ(ah, AR_ENT_OTP);
+ ath_dbg(common, ATH_DBG_CALIBRATE, "ath9k: AR_ENT_OTP 0x%x\n", val);
+
+ if (AR_SREV_9485(ah))
+ ar9003_hw_set_chain_masks(ah, 0x1, 0x1);
+ else if (val & AR_ENT_OTP_CHAIN2_DISABLE)
+ ar9003_hw_set_chain_masks(ah, 0x3, 0x3);
+ else
+ /*
+ * 0x7 = 0b111 , AR9003 needs to be configured for 3-chain
+ * mode before running AGC/TxIQ cals
+ */
+ ar9003_hw_set_chain_masks(ah, 0x7, 0x7);
/* Do Tx IQ Calibration */
- ar9003_hw_tx_iq_cal(ah);
+ if (AR_SREV_9485(ah))
+ ar9003_hw_tx_iq_cal_run(ah);
+ else
+ ar9003_hw_tx_iq_cal(ah);
+
REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
udelay(5);
REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
@@ -739,12 +983,14 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
/* Poll for offset calibration complete */
if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
0, AH_WAIT_TIMEOUT)) {
- ath_print(common, ATH_DBG_CALIBRATE,
- "offset calibration failed to "
- "complete in 1ms; noisy environment?\n");
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "offset calibration failed to complete in 1ms; noisy environment?\n");
return false;
}
+ if (AR_SREV_9485(ah))
+ ar9003_hw_tx_iq_cal_post_proc(ah);
+
/* Revert chainmasks to their original values before NF cal */
ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
@@ -757,15 +1003,15 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
if (ah->supp_cals & IQ_MISMATCH_CAL) {
INIT_CAL(&ah->iq_caldata);
INSERT_CAL(ah, &ah->iq_caldata);
- ath_print(common, ATH_DBG_CALIBRATE,
- "enabling IQ Calibration.\n");
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "enabling IQ Calibration.\n");
}
if (ah->supp_cals & TEMP_COMP_CAL) {
INIT_CAL(&ah->tempCompCalData);
INSERT_CAL(ah, &ah->tempCompCalData);
- ath_print(common, ATH_DBG_CALIBRATE,
- "enabling Temperature Compensation Calibration.\n");
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "enabling Temperature Compensation Calibration.\n");
}
/* Initialize current pointer to first element in list */
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index a7b82f0085d2..1f5aa51b9cef 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -22,12 +22,14 @@
#define COMP_CKSUM_LEN 2
#define AR_CH0_TOP (0x00016288)
-#define AR_CH0_TOP_XPABIASLVL (0x3)
+#define AR_CH0_TOP_XPABIASLVL (0x300)
#define AR_CH0_TOP_XPABIASLVL_S (8)
#define AR_CH0_THERM (0x00016290)
-#define AR_CH0_THERM_SPARE (0x3f)
-#define AR_CH0_THERM_SPARE_S (0)
+#define AR_CH0_THERM_XPABIASLVL_MSB 0x3
+#define AR_CH0_THERM_XPABIASLVL_MSB_S 0
+#define AR_CH0_THERM_XPASHORT2GND 0x4
+#define AR_CH0_THERM_XPASHORT2GND_S 2
#define AR_SWITCH_TABLE_COM_ALL (0xffff)
#define AR_SWITCH_TABLE_COM_ALL_S (0)
@@ -57,6 +59,9 @@
#define CTL(_tpower, _flag) ((_tpower) | ((_flag) << 6))
+static int ar9003_hw_power_interpolate(int32_t x,
+ int32_t *px, int32_t *py, u_int16_t np);
+
static const struct ar9300_eeprom ar9300_default = {
.eepromVersion = 2,
.templateVersion = 2,
@@ -146,13 +151,16 @@ static const struct ar9300_eeprom ar9300_default = {
.txEndToRxOn = 0x2,
.txFrameToXpaOn = 0xe,
.thresh62 = 28,
- .papdRateMaskHt20 = LE32(0x80c080),
- .papdRateMaskHt40 = LE32(0x80c080),
+ .papdRateMaskHt20 = LE32(0x0cf0e0e0),
+ .papdRateMaskHt40 = LE32(0x6cf0e0e0),
.futureModal = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
},
},
+ .base_ext1 = {
+ .ant_div_control = 0,
+ .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ },
.calFreqPier2G = {
FREQ2FBIN(2412, 1),
FREQ2FBIN(2437, 1),
@@ -287,8 +295,7 @@ static const struct ar9300_eeprom ar9300_default = {
/* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
/* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
/* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
- /* Data[11].ctlEdges[3].bChannel */
- FREQ2FBIN(2462, 1),
+ /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
}
},
.ctlPowerData_2G = {
@@ -346,13 +353,20 @@ static const struct ar9300_eeprom ar9300_default = {
.txEndToRxOn = 0x2,
.txFrameToXpaOn = 0xe,
.thresh62 = 28,
- .papdRateMaskHt20 = LE32(0xf0e0e0),
- .papdRateMaskHt40 = LE32(0xf0e0e0),
+ .papdRateMaskHt20 = LE32(0x0c80c080),
+ .papdRateMaskHt40 = LE32(0x0080c080),
.futureModal = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
},
},
+ .base_ext2 = {
+ .tempSlopeLow = 0,
+ .tempSlopeHigh = 0,
+ .xatten1DBLow = {0, 0, 0},
+ .xatten1MarginLow = {0, 0, 0},
+ .xatten1DBHigh = {0, 0, 0},
+ .xatten1MarginHigh = {0, 0, 0}
+ },
.calFreqPier5G = {
FREQ2FBIN(5180, 0),
FREQ2FBIN(5220, 0),
@@ -626,6 +640,2338 @@ static const struct ar9300_eeprom ar9300_default = {
}
};
+static const struct ar9300_eeprom ar9300_x113 = {
+ .eepromVersion = 2,
+ .templateVersion = 6,
+ .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
+ .custData = {"x113-023-f0000"},
+ .baseEepHeader = {
+ .regDmn = { LE16(0), LE16(0x1f) },
+ .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
+ .opCapFlags = {
+ .opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A,
+ .eepMisc = 0,
+ },
+ .rfSilent = 0,
+ .blueToothOptions = 0,
+ .deviceCap = 0,
+ .deviceType = 5, /* takes lower byte in eeprom location */
+ .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
+ .params_for_tuning_caps = {0, 0},
+ .featureEnable = 0x0d,
+ /*
+ * bit0 - enable tx temp comp - disabled
+ * bit1 - enable tx volt comp - disabled
+ * bit2 - enable fastClock - enabled
+ * bit3 - enable doubling - enabled
+ * bit4 - enable internal regulator - disabled
+ * bit5 - enable pa predistortion - disabled
+ */
+ .miscConfiguration = 0, /* bit0 - turn down drivestrength */
+ .eepromWriteEnableGpio = 6,
+ .wlanDisableGpio = 0,
+ .wlanLedGpio = 8,
+ .rxBandSelectGpio = 0xff,
+ .txrxgain = 0x21,
+ .swreg = 0,
+ },
+ .modalHeader2G = {
+ /* ar9300_modal_eep_header 2g */
+ /* 4 idle,t1,t2,b(4 bits per setting) */
+ .antCtrlCommon = LE32(0x110),
+ /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
+ .antCtrlCommon2 = LE32(0x44444),
+
+ /*
+ * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
+ * rx1, rx12, b (2 bits each)
+ */
+ .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) },
+
+ /*
+ * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
+ * for ar9280 (0xa20c/b20c 5:0)
+ */
+ .xatten1DB = {0, 0, 0},
+
+ /*
+ * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
+ * for ar9280 (0xa20c/b20c 16:12
+ */
+ .xatten1Margin = {0, 0, 0},
+ .tempSlope = 25,
+ .voltSlope = 0,
+
+ /*
+ * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
+ * channels in usual fbin coding format
+ */
+ .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
+
+ /*
+ * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
+ * if the register is per chain
+ */
+ .noiseFloorThreshCh = {-1, 0, 0},
+ .ob = {1, 1, 1},/* 3 chain */
+ .db_stage2 = {1, 1, 1}, /* 3 chain */
+ .db_stage3 = {0, 0, 0},
+ .db_stage4 = {0, 0, 0},
+ .xpaBiasLvl = 0,
+ .txFrameToDataStart = 0x0e,
+ .txFrameToPaOn = 0x0e,
+ .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
+ .antennaGain = 0,
+ .switchSettling = 0x2c,
+ .adcDesiredSize = -30,
+ .txEndToXpaOff = 0,
+ .txEndToRxOn = 0x2,
+ .txFrameToXpaOn = 0xe,
+ .thresh62 = 28,
+ .papdRateMaskHt20 = LE32(0x0c80c080),
+ .papdRateMaskHt40 = LE32(0x0080c080),
+ .futureModal = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ },
+ },
+ .base_ext1 = {
+ .ant_div_control = 0,
+ .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ },
+ .calFreqPier2G = {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2437, 1),
+ FREQ2FBIN(2472, 1),
+ },
+ /* ar9300_cal_data_per_freq_op_loop 2g */
+ .calPierData2G = {
+ { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
+ { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
+ { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
+ },
+ .calTarget_freqbin_Cck = {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2472, 1),
+ },
+ .calTarget_freqbin_2G = {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2437, 1),
+ FREQ2FBIN(2472, 1)
+ },
+ .calTarget_freqbin_2GHT20 = {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2437, 1),
+ FREQ2FBIN(2472, 1)
+ },
+ .calTarget_freqbin_2GHT40 = {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2437, 1),
+ FREQ2FBIN(2472, 1)
+ },
+ .calTargetPowerCck = {
+ /* 1L-5L,5S,11L,11S */
+ { {34, 34, 34, 34} },
+ { {34, 34, 34, 34} },
+ },
+ .calTargetPower2G = {
+ /* 6-24,36,48,54 */
+ { {34, 34, 32, 32} },
+ { {34, 34, 32, 32} },
+ { {34, 34, 32, 32} },
+ },
+ .calTargetPower2GHT20 = {
+ { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
+ { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
+ { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
+ },
+ .calTargetPower2GHT40 = {
+ { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
+ { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
+ { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
+ },
+ .ctlIndex_2G = {
+ 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
+ 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
+ },
+ .ctl_freqbin_2G = {
+ {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2417, 1),
+ FREQ2FBIN(2457, 1),
+ FREQ2FBIN(2462, 1)
+ },
+ {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2417, 1),
+ FREQ2FBIN(2462, 1),
+ 0xFF,
+ },
+
+ {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2417, 1),
+ FREQ2FBIN(2462, 1),
+ 0xFF,
+ },
+ {
+ FREQ2FBIN(2422, 1),
+ FREQ2FBIN(2427, 1),
+ FREQ2FBIN(2447, 1),
+ FREQ2FBIN(2452, 1)
+ },
+
+ {
+ /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+ /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+ /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
+ /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
+ },
+
+ {
+ /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+ /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+ /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
+ 0,
+ },
+
+ {
+ /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+ /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+ FREQ2FBIN(2472, 1),
+ 0,
+ },
+
+ {
+ /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
+ /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
+ /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
+ /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
+ },
+
+ {
+ /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+ /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+ /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
+ },
+
+ {
+ /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+ /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+ /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
+ 0
+ },
+
+ {
+ /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+ /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+ /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
+ 0
+ },
+
+ {
+ /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
+ /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
+ /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
+ /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
+ }
+ },
+ .ctlPowerData_2G = {
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
+
+ { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
+ },
+ .modalHeader5G = {
+ /* 4 idle,t1,t2,b (4 bits per setting) */
+ .antCtrlCommon = LE32(0x220),
+ /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
+ .antCtrlCommon2 = LE32(0x11111),
+ /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
+ .antCtrlChain = {
+ LE16(0x150), LE16(0x150), LE16(0x150),
+ },
+ /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
+ .xatten1DB = {0, 0, 0},
+
+ /*
+ * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
+ * for merlin (0xa20c/b20c 16:12
+ */
+ .xatten1Margin = {0, 0, 0},
+ .tempSlope = 68,
+ .voltSlope = 0,
+ /* spurChans spur channels in usual fbin coding format */
+ .spurChans = {FREQ2FBIN(5500, 0), 0, 0, 0, 0},
+ /* noiseFloorThreshCh Check if the register is per chain */
+ .noiseFloorThreshCh = {-1, 0, 0},
+ .ob = {3, 3, 3}, /* 3 chain */
+ .db_stage2 = {3, 3, 3}, /* 3 chain */
+ .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */
+ .db_stage4 = {3, 3, 3}, /* don't exist for 2G */
+ .xpaBiasLvl = 0,
+ .txFrameToDataStart = 0x0e,
+ .txFrameToPaOn = 0x0e,
+ .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
+ .antennaGain = 0,
+ .switchSettling = 0x2d,
+ .adcDesiredSize = -30,
+ .txEndToXpaOff = 0,
+ .txEndToRxOn = 0x2,
+ .txFrameToXpaOn = 0xe,
+ .thresh62 = 28,
+ .papdRateMaskHt20 = LE32(0x0cf0e0e0),
+ .papdRateMaskHt40 = LE32(0x6cf0e0e0),
+ .futureModal = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ },
+ },
+ .base_ext2 = {
+ .tempSlopeLow = 72,
+ .tempSlopeHigh = 105,
+ .xatten1DBLow = {0, 0, 0},
+ .xatten1MarginLow = {0, 0, 0},
+ .xatten1DBHigh = {0, 0, 0},
+ .xatten1MarginHigh = {0, 0, 0}
+ },
+ .calFreqPier5G = {
+ FREQ2FBIN(5180, 0),
+ FREQ2FBIN(5240, 0),
+ FREQ2FBIN(5320, 0),
+ FREQ2FBIN(5400, 0),
+ FREQ2FBIN(5500, 0),
+ FREQ2FBIN(5600, 0),
+ FREQ2FBIN(5745, 0),
+ FREQ2FBIN(5785, 0)
+ },
+ .calPierData5G = {
+ {
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ },
+ {
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ },
+ {
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ },
+
+ },
+ .calTarget_freqbin_5G = {
+ FREQ2FBIN(5180, 0),
+ FREQ2FBIN(5220, 0),
+ FREQ2FBIN(5320, 0),
+ FREQ2FBIN(5400, 0),
+ FREQ2FBIN(5500, 0),
+ FREQ2FBIN(5600, 0),
+ FREQ2FBIN(5745, 0),
+ FREQ2FBIN(5785, 0)
+ },
+ .calTarget_freqbin_5GHT20 = {
+ FREQ2FBIN(5180, 0),
+ FREQ2FBIN(5240, 0),
+ FREQ2FBIN(5320, 0),
+ FREQ2FBIN(5400, 0),
+ FREQ2FBIN(5500, 0),
+ FREQ2FBIN(5700, 0),
+ FREQ2FBIN(5745, 0),
+ FREQ2FBIN(5825, 0)
+ },
+ .calTarget_freqbin_5GHT40 = {
+ FREQ2FBIN(5190, 0),
+ FREQ2FBIN(5230, 0),
+ FREQ2FBIN(5320, 0),
+ FREQ2FBIN(5410, 0),
+ FREQ2FBIN(5510, 0),
+ FREQ2FBIN(5670, 0),
+ FREQ2FBIN(5755, 0),
+ FREQ2FBIN(5825, 0)
+ },
+ .calTargetPower5G = {
+ /* 6-24,36,48,54 */
+ { {42, 40, 40, 34} },
+ { {42, 40, 40, 34} },
+ { {42, 40, 40, 34} },
+ { {42, 40, 40, 34} },
+ { {42, 40, 40, 34} },
+ { {42, 40, 40, 34} },
+ { {42, 40, 40, 34} },
+ { {42, 40, 40, 34} },
+ },
+ .calTargetPower5GHT20 = {
+ /*
+ * 0_8_16,1-3_9-11_17-19,
+ * 4,5,6,7,12,13,14,15,20,21,22,23
+ */
+ { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
+ { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
+ { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
+ { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
+ { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
+ { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
+ { {38, 38, 38, 38, 32, 28, 38, 38, 32, 28, 38, 38, 32, 26} },
+ { {36, 36, 36, 36, 32, 28, 36, 36, 32, 28, 36, 36, 32, 26} },
+ },
+ .calTargetPower5GHT40 = {
+ /*
+ * 0_8_16,1-3_9-11_17-19,
+ * 4,5,6,7,12,13,14,15,20,21,22,23
+ */
+ { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
+ { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
+ { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
+ { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
+ { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
+ { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
+ { {36, 36, 36, 36, 30, 26, 36, 36, 30, 26, 36, 36, 30, 24} },
+ { {34, 34, 34, 34, 30, 26, 34, 34, 30, 26, 34, 34, 30, 24} },
+ },
+ .ctlIndex_5G = {
+ 0x10, 0x16, 0x18, 0x40, 0x46,
+ 0x48, 0x30, 0x36, 0x38
+ },
+ .ctl_freqbin_5G = {
+ {
+ /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+ /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
+ /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
+ /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
+ /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
+ /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
+ /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
+ /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
+ },
+ {
+ /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+ /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
+ /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
+ /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
+ /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
+ /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
+ /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
+ /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
+ },
+
+ {
+ /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
+ /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
+ /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
+ /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
+ /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
+ /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
+ /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
+ /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
+ },
+
+ {
+ /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+ /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
+ /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
+ /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
+ /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
+ /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
+ /* Data[3].ctlEdges[6].bChannel */ 0xFF,
+ /* Data[3].ctlEdges[7].bChannel */ 0xFF,
+ },
+
+ {
+ /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+ /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
+ /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
+ /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
+ /* Data[4].ctlEdges[4].bChannel */ 0xFF,
+ /* Data[4].ctlEdges[5].bChannel */ 0xFF,
+ /* Data[4].ctlEdges[6].bChannel */ 0xFF,
+ /* Data[4].ctlEdges[7].bChannel */ 0xFF,
+ },
+
+ {
+ /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
+ /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
+ /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
+ /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
+ /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
+ /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
+ /* Data[5].ctlEdges[6].bChannel */ 0xFF,
+ /* Data[5].ctlEdges[7].bChannel */ 0xFF
+ },
+
+ {
+ /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+ /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
+ /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
+ /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
+ /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
+ /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
+ /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
+ /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
+ },
+
+ {
+ /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+ /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
+ /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
+ /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
+ /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
+ /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
+ /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
+ /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
+ },
+
+ {
+ /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
+ /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
+ /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
+ /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
+ /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
+ /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
+ /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
+ /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
+ }
+ },
+ .ctlPowerData_5G = {
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ }
+ },
+ {
+ {
+ CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+ CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+ CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+ }
+ },
+ }
+};
+
+
+static const struct ar9300_eeprom ar9300_h112 = {
+ .eepromVersion = 2,
+ .templateVersion = 3,
+ .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
+ .custData = {"h112-241-f0000"},
+ .baseEepHeader = {
+ .regDmn = { LE16(0), LE16(0x1f) },
+ .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
+ .opCapFlags = {
+ .opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A,
+ .eepMisc = 0,
+ },
+ .rfSilent = 0,
+ .blueToothOptions = 0,
+ .deviceCap = 0,
+ .deviceType = 5, /* takes lower byte in eeprom location */
+ .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
+ .params_for_tuning_caps = {0, 0},
+ .featureEnable = 0x0d,
+ /*
+ * bit0 - enable tx temp comp - disabled
+ * bit1 - enable tx volt comp - disabled
+ * bit2 - enable fastClock - enabled
+ * bit3 - enable doubling - enabled
+ * bit4 - enable internal regulator - disabled
+ * bit5 - enable pa predistortion - disabled
+ */
+ .miscConfiguration = 0, /* bit0 - turn down drivestrength */
+ .eepromWriteEnableGpio = 6,
+ .wlanDisableGpio = 0,
+ .wlanLedGpio = 8,
+ .rxBandSelectGpio = 0xff,
+ .txrxgain = 0x10,
+ .swreg = 0,
+ },
+ .modalHeader2G = {
+ /* ar9300_modal_eep_header 2g */
+ /* 4 idle,t1,t2,b(4 bits per setting) */
+ .antCtrlCommon = LE32(0x110),
+ /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
+ .antCtrlCommon2 = LE32(0x44444),
+
+ /*
+ * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
+ * rx1, rx12, b (2 bits each)
+ */
+ .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) },
+
+ /*
+ * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
+ * for ar9280 (0xa20c/b20c 5:0)
+ */
+ .xatten1DB = {0, 0, 0},
+
+ /*
+ * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
+ * for ar9280 (0xa20c/b20c 16:12
+ */
+ .xatten1Margin = {0, 0, 0},
+ .tempSlope = 25,
+ .voltSlope = 0,
+
+ /*
+ * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
+ * channels in usual fbin coding format
+ */
+ .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
+
+ /*
+ * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
+ * if the register is per chain
+ */
+ .noiseFloorThreshCh = {-1, 0, 0},
+ .ob = {1, 1, 1},/* 3 chain */
+ .db_stage2 = {1, 1, 1}, /* 3 chain */
+ .db_stage3 = {0, 0, 0},
+ .db_stage4 = {0, 0, 0},
+ .xpaBiasLvl = 0,
+ .txFrameToDataStart = 0x0e,
+ .txFrameToPaOn = 0x0e,
+ .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
+ .antennaGain = 0,
+ .switchSettling = 0x2c,
+ .adcDesiredSize = -30,
+ .txEndToXpaOff = 0,
+ .txEndToRxOn = 0x2,
+ .txFrameToXpaOn = 0xe,
+ .thresh62 = 28,
+ .papdRateMaskHt20 = LE32(0x80c080),
+ .papdRateMaskHt40 = LE32(0x80c080),
+ .futureModal = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ },
+ },
+ .base_ext1 = {
+ .ant_div_control = 0,
+ .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ },
+ .calFreqPier2G = {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2437, 1),
+ FREQ2FBIN(2472, 1),
+ },
+ /* ar9300_cal_data_per_freq_op_loop 2g */
+ .calPierData2G = {
+ { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
+ { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
+ { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
+ },
+ .calTarget_freqbin_Cck = {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2484, 1),
+ },
+ .calTarget_freqbin_2G = {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2437, 1),
+ FREQ2FBIN(2472, 1)
+ },
+ .calTarget_freqbin_2GHT20 = {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2437, 1),
+ FREQ2FBIN(2472, 1)
+ },
+ .calTarget_freqbin_2GHT40 = {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2437, 1),
+ FREQ2FBIN(2472, 1)
+ },
+ .calTargetPowerCck = {
+ /* 1L-5L,5S,11L,11S */
+ { {34, 34, 34, 34} },
+ { {34, 34, 34, 34} },
+ },
+ .calTargetPower2G = {
+ /* 6-24,36,48,54 */
+ { {34, 34, 32, 32} },
+ { {34, 34, 32, 32} },
+ { {34, 34, 32, 32} },
+ },
+ .calTargetPower2GHT20 = {
+ { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} },
+ { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} },
+ { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} },
+ },
+ .calTargetPower2GHT40 = {
+ { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} },
+ { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} },
+ { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} },
+ },
+ .ctlIndex_2G = {
+ 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
+ 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
+ },
+ .ctl_freqbin_2G = {
+ {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2417, 1),
+ FREQ2FBIN(2457, 1),
+ FREQ2FBIN(2462, 1)
+ },
+ {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2417, 1),
+ FREQ2FBIN(2462, 1),
+ 0xFF,
+ },
+
+ {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2417, 1),
+ FREQ2FBIN(2462, 1),
+ 0xFF,
+ },
+ {
+ FREQ2FBIN(2422, 1),
+ FREQ2FBIN(2427, 1),
+ FREQ2FBIN(2447, 1),
+ FREQ2FBIN(2452, 1)
+ },
+
+ {
+ /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+ /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+ /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
+ /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
+ },
+
+ {
+ /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+ /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+ /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
+ 0,
+ },
+
+ {
+ /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+ /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+ FREQ2FBIN(2472, 1),
+ 0,
+ },
+
+ {
+ /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
+ /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
+ /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
+ /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
+ },
+
+ {
+ /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+ /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+ /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
+ },
+
+ {
+ /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+ /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+ /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
+ 0
+ },
+
+ {
+ /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+ /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+ /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
+ 0
+ },
+
+ {
+ /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
+ /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
+ /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
+ /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
+ }
+ },
+ .ctlPowerData_2G = {
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
+
+ { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
+ },
+ .modalHeader5G = {
+ /* 4 idle,t1,t2,b (4 bits per setting) */
+ .antCtrlCommon = LE32(0x220),
+ /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
+ .antCtrlCommon2 = LE32(0x44444),
+ /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
+ .antCtrlChain = {
+ LE16(0x150), LE16(0x150), LE16(0x150),
+ },
+ /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
+ .xatten1DB = {0, 0, 0},
+
+ /*
+ * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
+ * for merlin (0xa20c/b20c 16:12
+ */
+ .xatten1Margin = {0, 0, 0},
+ .tempSlope = 45,
+ .voltSlope = 0,
+ /* spurChans spur channels in usual fbin coding format */
+ .spurChans = {0, 0, 0, 0, 0},
+ /* noiseFloorThreshCh Check if the register is per chain */
+ .noiseFloorThreshCh = {-1, 0, 0},
+ .ob = {3, 3, 3}, /* 3 chain */
+ .db_stage2 = {3, 3, 3}, /* 3 chain */
+ .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */
+ .db_stage4 = {3, 3, 3}, /* don't exist for 2G */
+ .xpaBiasLvl = 0,
+ .txFrameToDataStart = 0x0e,
+ .txFrameToPaOn = 0x0e,
+ .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
+ .antennaGain = 0,
+ .switchSettling = 0x2d,
+ .adcDesiredSize = -30,
+ .txEndToXpaOff = 0,
+ .txEndToRxOn = 0x2,
+ .txFrameToXpaOn = 0xe,
+ .thresh62 = 28,
+ .papdRateMaskHt20 = LE32(0x0cf0e0e0),
+ .papdRateMaskHt40 = LE32(0x6cf0e0e0),
+ .futureModal = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ },
+ },
+ .base_ext2 = {
+ .tempSlopeLow = 40,
+ .tempSlopeHigh = 50,
+ .xatten1DBLow = {0, 0, 0},
+ .xatten1MarginLow = {0, 0, 0},
+ .xatten1DBHigh = {0, 0, 0},
+ .xatten1MarginHigh = {0, 0, 0}
+ },
+ .calFreqPier5G = {
+ FREQ2FBIN(5180, 0),
+ FREQ2FBIN(5220, 0),
+ FREQ2FBIN(5320, 0),
+ FREQ2FBIN(5400, 0),
+ FREQ2FBIN(5500, 0),
+ FREQ2FBIN(5600, 0),
+ FREQ2FBIN(5700, 0),
+ FREQ2FBIN(5825, 0)
+ },
+ .calPierData5G = {
+ {
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ },
+ {
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ },
+ {
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ },
+
+ },
+ .calTarget_freqbin_5G = {
+ FREQ2FBIN(5180, 0),
+ FREQ2FBIN(5240, 0),
+ FREQ2FBIN(5320, 0),
+ FREQ2FBIN(5400, 0),
+ FREQ2FBIN(5500, 0),
+ FREQ2FBIN(5600, 0),
+ FREQ2FBIN(5700, 0),
+ FREQ2FBIN(5825, 0)
+ },
+ .calTarget_freqbin_5GHT20 = {
+ FREQ2FBIN(5180, 0),
+ FREQ2FBIN(5240, 0),
+ FREQ2FBIN(5320, 0),
+ FREQ2FBIN(5400, 0),
+ FREQ2FBIN(5500, 0),
+ FREQ2FBIN(5700, 0),
+ FREQ2FBIN(5745, 0),
+ FREQ2FBIN(5825, 0)
+ },
+ .calTarget_freqbin_5GHT40 = {
+ FREQ2FBIN(5180, 0),
+ FREQ2FBIN(5240, 0),
+ FREQ2FBIN(5320, 0),
+ FREQ2FBIN(5400, 0),
+ FREQ2FBIN(5500, 0),
+ FREQ2FBIN(5700, 0),
+ FREQ2FBIN(5745, 0),
+ FREQ2FBIN(5825, 0)
+ },
+ .calTargetPower5G = {
+ /* 6-24,36,48,54 */
+ { {30, 30, 28, 24} },
+ { {30, 30, 28, 24} },
+ { {30, 30, 28, 24} },
+ { {30, 30, 28, 24} },
+ { {30, 30, 28, 24} },
+ { {30, 30, 28, 24} },
+ { {30, 30, 28, 24} },
+ { {30, 30, 28, 24} },
+ },
+ .calTargetPower5GHT20 = {
+ /*
+ * 0_8_16,1-3_9-11_17-19,
+ * 4,5,6,7,12,13,14,15,20,21,22,23
+ */
+ { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 20, 20, 20, 16} },
+ { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 20, 20, 20, 16} },
+ { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 18, 18, 18, 16} },
+ { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 18, 18, 18, 16} },
+ { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 16, 16, 16, 14} },
+ { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 16, 16, 16, 14} },
+ { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 14, 14, 14, 12} },
+ { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 14, 14, 14, 12} },
+ },
+ .calTargetPower5GHT40 = {
+ /*
+ * 0_8_16,1-3_9-11_17-19,
+ * 4,5,6,7,12,13,14,15,20,21,22,23
+ */
+ { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 18, 18, 18, 14} },
+ { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 18, 18, 18, 14} },
+ { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 16, 16, 16, 12} },
+ { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 16, 16, 16, 12} },
+ { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 14, 14, 14, 10} },
+ { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 14, 14, 14, 10} },
+ { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 12, 12, 12, 8} },
+ { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 12, 12, 12, 8} },
+ },
+ .ctlIndex_5G = {
+ 0x10, 0x16, 0x18, 0x40, 0x46,
+ 0x48, 0x30, 0x36, 0x38
+ },
+ .ctl_freqbin_5G = {
+ {
+ /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+ /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
+ /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
+ /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
+ /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
+ /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
+ /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
+ /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
+ },
+ {
+ /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+ /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
+ /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
+ /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
+ /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
+ /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
+ /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
+ /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
+ },
+
+ {
+ /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
+ /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
+ /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
+ /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
+ /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
+ /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
+ /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
+ /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
+ },
+
+ {
+ /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+ /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
+ /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
+ /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
+ /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
+ /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
+ /* Data[3].ctlEdges[6].bChannel */ 0xFF,
+ /* Data[3].ctlEdges[7].bChannel */ 0xFF,
+ },
+
+ {
+ /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+ /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
+ /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
+ /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
+ /* Data[4].ctlEdges[4].bChannel */ 0xFF,
+ /* Data[4].ctlEdges[5].bChannel */ 0xFF,
+ /* Data[4].ctlEdges[6].bChannel */ 0xFF,
+ /* Data[4].ctlEdges[7].bChannel */ 0xFF,
+ },
+
+ {
+ /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
+ /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
+ /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
+ /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
+ /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
+ /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
+ /* Data[5].ctlEdges[6].bChannel */ 0xFF,
+ /* Data[5].ctlEdges[7].bChannel */ 0xFF
+ },
+
+ {
+ /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+ /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
+ /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
+ /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
+ /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
+ /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
+ /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
+ /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
+ },
+
+ {
+ /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+ /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
+ /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
+ /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
+ /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
+ /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
+ /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
+ /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
+ },
+
+ {
+ /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
+ /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
+ /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
+ /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
+ /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
+ /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
+ /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
+ /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
+ }
+ },
+ .ctlPowerData_5G = {
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ }
+ },
+ {
+ {
+ CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+ CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+ CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+ }
+ },
+ }
+};
+
+
+static const struct ar9300_eeprom ar9300_x112 = {
+ .eepromVersion = 2,
+ .templateVersion = 5,
+ .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
+ .custData = {"x112-041-f0000"},
+ .baseEepHeader = {
+ .regDmn = { LE16(0), LE16(0x1f) },
+ .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
+ .opCapFlags = {
+ .opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A,
+ .eepMisc = 0,
+ },
+ .rfSilent = 0,
+ .blueToothOptions = 0,
+ .deviceCap = 0,
+ .deviceType = 5, /* takes lower byte in eeprom location */
+ .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
+ .params_for_tuning_caps = {0, 0},
+ .featureEnable = 0x0d,
+ /*
+ * bit0 - enable tx temp comp - disabled
+ * bit1 - enable tx volt comp - disabled
+ * bit2 - enable fastclock - enabled
+ * bit3 - enable doubling - enabled
+ * bit4 - enable internal regulator - disabled
+ * bit5 - enable pa predistortion - disabled
+ */
+ .miscConfiguration = 0, /* bit0 - turn down drivestrength */
+ .eepromWriteEnableGpio = 6,
+ .wlanDisableGpio = 0,
+ .wlanLedGpio = 8,
+ .rxBandSelectGpio = 0xff,
+ .txrxgain = 0x0,
+ .swreg = 0,
+ },
+ .modalHeader2G = {
+ /* ar9300_modal_eep_header 2g */
+ /* 4 idle,t1,t2,b(4 bits per setting) */
+ .antCtrlCommon = LE32(0x110),
+ /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
+ .antCtrlCommon2 = LE32(0x22222),
+
+ /*
+ * antCtrlChain[ar9300_max_chains]; 6 idle, t, r,
+ * rx1, rx12, b (2 bits each)
+ */
+ .antCtrlChain = { LE16(0x10), LE16(0x10), LE16(0x10) },
+
+ /*
+ * xatten1DB[AR9300_max_chains]; 3 xatten1_db
+ * for ar9280 (0xa20c/b20c 5:0)
+ */
+ .xatten1DB = {0x1b, 0x1b, 0x1b},
+
+ /*
+ * xatten1Margin[ar9300_max_chains]; 3 xatten1_margin
+ * for ar9280 (0xa20c/b20c 16:12
+ */
+ .xatten1Margin = {0x15, 0x15, 0x15},
+ .tempSlope = 50,
+ .voltSlope = 0,
+
+ /*
+ * spurChans[OSPrey_eeprom_modal_sPURS]; spur
+ * channels in usual fbin coding format
+ */
+ .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
+
+ /*
+ * noiseFloorThreshch[ar9300_max_cHAINS]; 3 Check
+ * if the register is per chain
+ */
+ .noiseFloorThreshCh = {-1, 0, 0},
+ .ob = {1, 1, 1},/* 3 chain */
+ .db_stage2 = {1, 1, 1}, /* 3 chain */
+ .db_stage3 = {0, 0, 0},
+ .db_stage4 = {0, 0, 0},
+ .xpaBiasLvl = 0,
+ .txFrameToDataStart = 0x0e,
+ .txFrameToPaOn = 0x0e,
+ .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
+ .antennaGain = 0,
+ .switchSettling = 0x2c,
+ .adcDesiredSize = -30,
+ .txEndToXpaOff = 0,
+ .txEndToRxOn = 0x2,
+ .txFrameToXpaOn = 0xe,
+ .thresh62 = 28,
+ .papdRateMaskHt20 = LE32(0x0c80c080),
+ .papdRateMaskHt40 = LE32(0x0080c080),
+ .futureModal = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ },
+ },
+ .base_ext1 = {
+ .ant_div_control = 0,
+ .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ },
+ .calFreqPier2G = {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2437, 1),
+ FREQ2FBIN(2472, 1),
+ },
+ /* ar9300_cal_data_per_freq_op_loop 2g */
+ .calPierData2G = {
+ { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
+ { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
+ { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
+ },
+ .calTarget_freqbin_Cck = {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2472, 1),
+ },
+ .calTarget_freqbin_2G = {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2437, 1),
+ FREQ2FBIN(2472, 1)
+ },
+ .calTarget_freqbin_2GHT20 = {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2437, 1),
+ FREQ2FBIN(2472, 1)
+ },
+ .calTarget_freqbin_2GHT40 = {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2437, 1),
+ FREQ2FBIN(2472, 1)
+ },
+ .calTargetPowerCck = {
+ /* 1L-5L,5S,11L,11s */
+ { {38, 38, 38, 38} },
+ { {38, 38, 38, 38} },
+ },
+ .calTargetPower2G = {
+ /* 6-24,36,48,54 */
+ { {38, 38, 36, 34} },
+ { {38, 38, 36, 34} },
+ { {38, 38, 34, 32} },
+ },
+ .calTargetPower2GHT20 = {
+ { {36, 36, 36, 36, 36, 34, 34, 32, 30, 28, 28, 28, 28, 26} },
+ { {36, 36, 36, 36, 36, 34, 36, 34, 32, 30, 30, 30, 28, 26} },
+ { {36, 36, 36, 36, 36, 34, 34, 32, 30, 28, 28, 28, 28, 26} },
+ },
+ .calTargetPower2GHT40 = {
+ { {36, 36, 36, 36, 34, 32, 32, 30, 28, 26, 26, 26, 26, 24} },
+ { {36, 36, 36, 36, 34, 32, 34, 32, 30, 28, 28, 28, 28, 24} },
+ { {36, 36, 36, 36, 34, 32, 32, 30, 28, 26, 26, 26, 26, 24} },
+ },
+ .ctlIndex_2G = {
+ 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
+ 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
+ },
+ .ctl_freqbin_2G = {
+ {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2417, 1),
+ FREQ2FBIN(2457, 1),
+ FREQ2FBIN(2462, 1)
+ },
+ {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2417, 1),
+ FREQ2FBIN(2462, 1),
+ 0xFF,
+ },
+
+ {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2417, 1),
+ FREQ2FBIN(2462, 1),
+ 0xFF,
+ },
+ {
+ FREQ2FBIN(2422, 1),
+ FREQ2FBIN(2427, 1),
+ FREQ2FBIN(2447, 1),
+ FREQ2FBIN(2452, 1)
+ },
+
+ {
+ /* Data[4].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
+ /* Data[4].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
+ /* Data[4].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
+ /* Data[4].ctledges[3].bchannel */ FREQ2FBIN(2484, 1),
+ },
+
+ {
+ /* Data[5].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
+ /* Data[5].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
+ /* Data[5].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
+ 0,
+ },
+
+ {
+ /* Data[6].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
+ /* Data[6].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
+ FREQ2FBIN(2472, 1),
+ 0,
+ },
+
+ {
+ /* Data[7].ctledges[0].bchannel */ FREQ2FBIN(2422, 1),
+ /* Data[7].ctledges[1].bchannel */ FREQ2FBIN(2427, 1),
+ /* Data[7].ctledges[2].bchannel */ FREQ2FBIN(2447, 1),
+ /* Data[7].ctledges[3].bchannel */ FREQ2FBIN(2462, 1),
+ },
+
+ {
+ /* Data[8].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
+ /* Data[8].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
+ /* Data[8].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
+ },
+
+ {
+ /* Data[9].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
+ /* Data[9].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
+ /* Data[9].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
+ 0
+ },
+
+ {
+ /* Data[10].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
+ /* Data[10].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
+ /* Data[10].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
+ 0
+ },
+
+ {
+ /* Data[11].ctledges[0].bchannel */ FREQ2FBIN(2422, 1),
+ /* Data[11].ctledges[1].bchannel */ FREQ2FBIN(2427, 1),
+ /* Data[11].ctledges[2].bchannel */ FREQ2FBIN(2447, 1),
+ /* Data[11].ctledges[3].bchannel */ FREQ2FBIN(2462, 1),
+ }
+ },
+ .ctlPowerData_2G = {
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
+
+ { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
+ },
+ .modalHeader5G = {
+ /* 4 idle,t1,t2,b (4 bits per setting) */
+ .antCtrlCommon = LE32(0x110),
+ /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
+ .antCtrlCommon2 = LE32(0x22222),
+ /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
+ .antCtrlChain = {
+ LE16(0x0), LE16(0x0), LE16(0x0),
+ },
+ /* xatten1DB 3 xatten1_db for ar9280 (0xa20c/b20c 5:0) */
+ .xatten1DB = {0x13, 0x19, 0x17},
+
+ /*
+ * xatten1Margin[ar9300_max_chains]; 3 xatten1_margin
+ * for merlin (0xa20c/b20c 16:12
+ */
+ .xatten1Margin = {0x19, 0x19, 0x19},
+ .tempSlope = 70,
+ .voltSlope = 15,
+ /* spurChans spur channels in usual fbin coding format */
+ .spurChans = {0, 0, 0, 0, 0},
+ /* noiseFloorThreshch check if the register is per chain */
+ .noiseFloorThreshCh = {-1, 0, 0},
+ .ob = {3, 3, 3}, /* 3 chain */
+ .db_stage2 = {3, 3, 3}, /* 3 chain */
+ .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */
+ .db_stage4 = {3, 3, 3}, /* don't exist for 2G */
+ .xpaBiasLvl = 0,
+ .txFrameToDataStart = 0x0e,
+ .txFrameToPaOn = 0x0e,
+ .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
+ .antennaGain = 0,
+ .switchSettling = 0x2d,
+ .adcDesiredSize = -30,
+ .txEndToXpaOff = 0,
+ .txEndToRxOn = 0x2,
+ .txFrameToXpaOn = 0xe,
+ .thresh62 = 28,
+ .papdRateMaskHt20 = LE32(0x0cf0e0e0),
+ .papdRateMaskHt40 = LE32(0x6cf0e0e0),
+ .futureModal = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ },
+ },
+ .base_ext2 = {
+ .tempSlopeLow = 72,
+ .tempSlopeHigh = 105,
+ .xatten1DBLow = {0x10, 0x14, 0x10},
+ .xatten1MarginLow = {0x19, 0x19 , 0x19},
+ .xatten1DBHigh = {0x1d, 0x20, 0x24},
+ .xatten1MarginHigh = {0x10, 0x10, 0x10}
+ },
+ .calFreqPier5G = {
+ FREQ2FBIN(5180, 0),
+ FREQ2FBIN(5220, 0),
+ FREQ2FBIN(5320, 0),
+ FREQ2FBIN(5400, 0),
+ FREQ2FBIN(5500, 0),
+ FREQ2FBIN(5600, 0),
+ FREQ2FBIN(5700, 0),
+ FREQ2FBIN(5785, 0)
+ },
+ .calPierData5G = {
+ {
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ },
+ {
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ },
+ {
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ },
+
+ },
+ .calTarget_freqbin_5G = {
+ FREQ2FBIN(5180, 0),
+ FREQ2FBIN(5220, 0),
+ FREQ2FBIN(5320, 0),
+ FREQ2FBIN(5400, 0),
+ FREQ2FBIN(5500, 0),
+ FREQ2FBIN(5600, 0),
+ FREQ2FBIN(5725, 0),
+ FREQ2FBIN(5825, 0)
+ },
+ .calTarget_freqbin_5GHT20 = {
+ FREQ2FBIN(5180, 0),
+ FREQ2FBIN(5220, 0),
+ FREQ2FBIN(5320, 0),
+ FREQ2FBIN(5400, 0),
+ FREQ2FBIN(5500, 0),
+ FREQ2FBIN(5600, 0),
+ FREQ2FBIN(5725, 0),
+ FREQ2FBIN(5825, 0)
+ },
+ .calTarget_freqbin_5GHT40 = {
+ FREQ2FBIN(5180, 0),
+ FREQ2FBIN(5220, 0),
+ FREQ2FBIN(5320, 0),
+ FREQ2FBIN(5400, 0),
+ FREQ2FBIN(5500, 0),
+ FREQ2FBIN(5600, 0),
+ FREQ2FBIN(5725, 0),
+ FREQ2FBIN(5825, 0)
+ },
+ .calTargetPower5G = {
+ /* 6-24,36,48,54 */
+ { {32, 32, 28, 26} },
+ { {32, 32, 28, 26} },
+ { {32, 32, 28, 26} },
+ { {32, 32, 26, 24} },
+ { {32, 32, 26, 24} },
+ { {32, 32, 24, 22} },
+ { {30, 30, 24, 22} },
+ { {30, 30, 24, 22} },
+ },
+ .calTargetPower5GHT20 = {
+ /*
+ * 0_8_16,1-3_9-11_17-19,
+ * 4,5,6,7,12,13,14,15,20,21,22,23
+ */
+ { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} },
+ { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} },
+ { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} },
+ { {32, 32, 32, 32, 28, 26, 32, 26, 24, 22, 22, 22, 20, 20} },
+ { {32, 32, 32, 32, 28, 26, 32, 26, 24, 22, 20, 18, 16, 16} },
+ { {32, 32, 32, 32, 28, 26, 32, 24, 20, 16, 18, 16, 14, 14} },
+ { {30, 30, 30, 30, 28, 26, 30, 24, 20, 16, 18, 16, 14, 14} },
+ { {30, 30, 30, 30, 28, 26, 30, 24, 20, 16, 18, 16, 14, 14} },
+ },
+ .calTargetPower5GHT40 = {
+ /*
+ * 0_8_16,1-3_9-11_17-19,
+ * 4,5,6,7,12,13,14,15,20,21,22,23
+ */
+ { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} },
+ { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} },
+ { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} },
+ { {32, 32, 32, 30, 28, 26, 30, 26, 24, 22, 22, 22, 20, 20} },
+ { {32, 32, 32, 30, 28, 26, 30, 26, 24, 22, 20, 18, 16, 16} },
+ { {32, 32, 32, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} },
+ { {30, 30, 30, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} },
+ { {30, 30, 30, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} },
+ },
+ .ctlIndex_5G = {
+ 0x10, 0x16, 0x18, 0x40, 0x46,
+ 0x48, 0x30, 0x36, 0x38
+ },
+ .ctl_freqbin_5G = {
+ {
+ /* Data[0].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
+ /* Data[0].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
+ /* Data[0].ctledges[2].bchannel */ FREQ2FBIN(5280, 0),
+ /* Data[0].ctledges[3].bchannel */ FREQ2FBIN(5500, 0),
+ /* Data[0].ctledges[4].bchannel */ FREQ2FBIN(5600, 0),
+ /* Data[0].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
+ /* Data[0].ctledges[6].bchannel */ FREQ2FBIN(5745, 0),
+ /* Data[0].ctledges[7].bchannel */ FREQ2FBIN(5825, 0)
+ },
+ {
+ /* Data[1].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
+ /* Data[1].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
+ /* Data[1].ctledges[2].bchannel */ FREQ2FBIN(5280, 0),
+ /* Data[1].ctledges[3].bchannel */ FREQ2FBIN(5500, 0),
+ /* Data[1].ctledges[4].bchannel */ FREQ2FBIN(5520, 0),
+ /* Data[1].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
+ /* Data[1].ctledges[6].bchannel */ FREQ2FBIN(5745, 0),
+ /* Data[1].ctledges[7].bchannel */ FREQ2FBIN(5825, 0)
+ },
+
+ {
+ /* Data[2].ctledges[0].bchannel */ FREQ2FBIN(5190, 0),
+ /* Data[2].ctledges[1].bchannel */ FREQ2FBIN(5230, 0),
+ /* Data[2].ctledges[2].bchannel */ FREQ2FBIN(5270, 0),
+ /* Data[2].ctledges[3].bchannel */ FREQ2FBIN(5310, 0),
+ /* Data[2].ctledges[4].bchannel */ FREQ2FBIN(5510, 0),
+ /* Data[2].ctledges[5].bchannel */ FREQ2FBIN(5550, 0),
+ /* Data[2].ctledges[6].bchannel */ FREQ2FBIN(5670, 0),
+ /* Data[2].ctledges[7].bchannel */ FREQ2FBIN(5755, 0)
+ },
+
+ {
+ /* Data[3].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
+ /* Data[3].ctledges[1].bchannel */ FREQ2FBIN(5200, 0),
+ /* Data[3].ctledges[2].bchannel */ FREQ2FBIN(5260, 0),
+ /* Data[3].ctledges[3].bchannel */ FREQ2FBIN(5320, 0),
+ /* Data[3].ctledges[4].bchannel */ FREQ2FBIN(5500, 0),
+ /* Data[3].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
+ /* Data[3].ctledges[6].bchannel */ 0xFF,
+ /* Data[3].ctledges[7].bchannel */ 0xFF,
+ },
+
+ {
+ /* Data[4].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
+ /* Data[4].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
+ /* Data[4].ctledges[2].bchannel */ FREQ2FBIN(5500, 0),
+ /* Data[4].ctledges[3].bchannel */ FREQ2FBIN(5700, 0),
+ /* Data[4].ctledges[4].bchannel */ 0xFF,
+ /* Data[4].ctledges[5].bchannel */ 0xFF,
+ /* Data[4].ctledges[6].bchannel */ 0xFF,
+ /* Data[4].ctledges[7].bchannel */ 0xFF,
+ },
+
+ {
+ /* Data[5].ctledges[0].bchannel */ FREQ2FBIN(5190, 0),
+ /* Data[5].ctledges[1].bchannel */ FREQ2FBIN(5270, 0),
+ /* Data[5].ctledges[2].bchannel */ FREQ2FBIN(5310, 0),
+ /* Data[5].ctledges[3].bchannel */ FREQ2FBIN(5510, 0),
+ /* Data[5].ctledges[4].bchannel */ FREQ2FBIN(5590, 0),
+ /* Data[5].ctledges[5].bchannel */ FREQ2FBIN(5670, 0),
+ /* Data[5].ctledges[6].bchannel */ 0xFF,
+ /* Data[5].ctledges[7].bchannel */ 0xFF
+ },
+
+ {
+ /* Data[6].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
+ /* Data[6].ctledges[1].bchannel */ FREQ2FBIN(5200, 0),
+ /* Data[6].ctledges[2].bchannel */ FREQ2FBIN(5220, 0),
+ /* Data[6].ctledges[3].bchannel */ FREQ2FBIN(5260, 0),
+ /* Data[6].ctledges[4].bchannel */ FREQ2FBIN(5500, 0),
+ /* Data[6].ctledges[5].bchannel */ FREQ2FBIN(5600, 0),
+ /* Data[6].ctledges[6].bchannel */ FREQ2FBIN(5700, 0),
+ /* Data[6].ctledges[7].bchannel */ FREQ2FBIN(5745, 0)
+ },
+
+ {
+ /* Data[7].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
+ /* Data[7].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
+ /* Data[7].ctledges[2].bchannel */ FREQ2FBIN(5320, 0),
+ /* Data[7].ctledges[3].bchannel */ FREQ2FBIN(5500, 0),
+ /* Data[7].ctledges[4].bchannel */ FREQ2FBIN(5560, 0),
+ /* Data[7].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
+ /* Data[7].ctledges[6].bchannel */ FREQ2FBIN(5745, 0),
+ /* Data[7].ctledges[7].bchannel */ FREQ2FBIN(5825, 0)
+ },
+
+ {
+ /* Data[8].ctledges[0].bchannel */ FREQ2FBIN(5190, 0),
+ /* Data[8].ctledges[1].bchannel */ FREQ2FBIN(5230, 0),
+ /* Data[8].ctledges[2].bchannel */ FREQ2FBIN(5270, 0),
+ /* Data[8].ctledges[3].bchannel */ FREQ2FBIN(5510, 0),
+ /* Data[8].ctledges[4].bchannel */ FREQ2FBIN(5550, 0),
+ /* Data[8].ctledges[5].bchannel */ FREQ2FBIN(5670, 0),
+ /* Data[8].ctledges[6].bchannel */ FREQ2FBIN(5755, 0),
+ /* Data[8].ctledges[7].bchannel */ FREQ2FBIN(5795, 0)
+ }
+ },
+ .ctlPowerData_5G = {
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ }
+ },
+ {
+ {
+ CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+ CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+ CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+ }
+ },
+ }
+};
+
+static const struct ar9300_eeprom ar9300_h116 = {
+ .eepromVersion = 2,
+ .templateVersion = 4,
+ .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
+ .custData = {"h116-041-f0000"},
+ .baseEepHeader = {
+ .regDmn = { LE16(0), LE16(0x1f) },
+ .txrxMask = 0x33, /* 4 bits tx and 4 bits rx */
+ .opCapFlags = {
+ .opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A,
+ .eepMisc = 0,
+ },
+ .rfSilent = 0,
+ .blueToothOptions = 0,
+ .deviceCap = 0,
+ .deviceType = 5, /* takes lower byte in eeprom location */
+ .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
+ .params_for_tuning_caps = {0, 0},
+ .featureEnable = 0x0d,
+ /*
+ * bit0 - enable tx temp comp - disabled
+ * bit1 - enable tx volt comp - disabled
+ * bit2 - enable fastClock - enabled
+ * bit3 - enable doubling - enabled
+ * bit4 - enable internal regulator - disabled
+ * bit5 - enable pa predistortion - disabled
+ */
+ .miscConfiguration = 0, /* bit0 - turn down drivestrength */
+ .eepromWriteEnableGpio = 6,
+ .wlanDisableGpio = 0,
+ .wlanLedGpio = 8,
+ .rxBandSelectGpio = 0xff,
+ .txrxgain = 0x10,
+ .swreg = 0,
+ },
+ .modalHeader2G = {
+ /* ar9300_modal_eep_header 2g */
+ /* 4 idle,t1,t2,b(4 bits per setting) */
+ .antCtrlCommon = LE32(0x110),
+ /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
+ .antCtrlCommon2 = LE32(0x44444),
+
+ /*
+ * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
+ * rx1, rx12, b (2 bits each)
+ */
+ .antCtrlChain = { LE16(0x10), LE16(0x10), LE16(0x10) },
+
+ /*
+ * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
+ * for ar9280 (0xa20c/b20c 5:0)
+ */
+ .xatten1DB = {0x1f, 0x1f, 0x1f},
+
+ /*
+ * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
+ * for ar9280 (0xa20c/b20c 16:12
+ */
+ .xatten1Margin = {0x12, 0x12, 0x12},
+ .tempSlope = 25,
+ .voltSlope = 0,
+
+ /*
+ * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
+ * channels in usual fbin coding format
+ */
+ .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
+
+ /*
+ * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
+ * if the register is per chain
+ */
+ .noiseFloorThreshCh = {-1, 0, 0},
+ .ob = {1, 1, 1},/* 3 chain */
+ .db_stage2 = {1, 1, 1}, /* 3 chain */
+ .db_stage3 = {0, 0, 0},
+ .db_stage4 = {0, 0, 0},
+ .xpaBiasLvl = 0,
+ .txFrameToDataStart = 0x0e,
+ .txFrameToPaOn = 0x0e,
+ .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
+ .antennaGain = 0,
+ .switchSettling = 0x2c,
+ .adcDesiredSize = -30,
+ .txEndToXpaOff = 0,
+ .txEndToRxOn = 0x2,
+ .txFrameToXpaOn = 0xe,
+ .thresh62 = 28,
+ .papdRateMaskHt20 = LE32(0x0c80C080),
+ .papdRateMaskHt40 = LE32(0x0080C080),
+ .futureModal = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ },
+ },
+ .base_ext1 = {
+ .ant_div_control = 0,
+ .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ },
+ .calFreqPier2G = {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2437, 1),
+ FREQ2FBIN(2472, 1),
+ },
+ /* ar9300_cal_data_per_freq_op_loop 2g */
+ .calPierData2G = {
+ { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
+ { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
+ { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
+ },
+ .calTarget_freqbin_Cck = {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2472, 1),
+ },
+ .calTarget_freqbin_2G = {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2437, 1),
+ FREQ2FBIN(2472, 1)
+ },
+ .calTarget_freqbin_2GHT20 = {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2437, 1),
+ FREQ2FBIN(2472, 1)
+ },
+ .calTarget_freqbin_2GHT40 = {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2437, 1),
+ FREQ2FBIN(2472, 1)
+ },
+ .calTargetPowerCck = {
+ /* 1L-5L,5S,11L,11S */
+ { {34, 34, 34, 34} },
+ { {34, 34, 34, 34} },
+ },
+ .calTargetPower2G = {
+ /* 6-24,36,48,54 */
+ { {34, 34, 32, 32} },
+ { {34, 34, 32, 32} },
+ { {34, 34, 32, 32} },
+ },
+ .calTargetPower2GHT20 = {
+ { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
+ { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
+ { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
+ },
+ .calTargetPower2GHT40 = {
+ { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
+ { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
+ { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
+ },
+ .ctlIndex_2G = {
+ 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
+ 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
+ },
+ .ctl_freqbin_2G = {
+ {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2417, 1),
+ FREQ2FBIN(2457, 1),
+ FREQ2FBIN(2462, 1)
+ },
+ {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2417, 1),
+ FREQ2FBIN(2462, 1),
+ 0xFF,
+ },
+
+ {
+ FREQ2FBIN(2412, 1),
+ FREQ2FBIN(2417, 1),
+ FREQ2FBIN(2462, 1),
+ 0xFF,
+ },
+ {
+ FREQ2FBIN(2422, 1),
+ FREQ2FBIN(2427, 1),
+ FREQ2FBIN(2447, 1),
+ FREQ2FBIN(2452, 1)
+ },
+
+ {
+ /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+ /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+ /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
+ /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
+ },
+
+ {
+ /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+ /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+ /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
+ 0,
+ },
+
+ {
+ /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+ /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+ FREQ2FBIN(2472, 1),
+ 0,
+ },
+
+ {
+ /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
+ /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
+ /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
+ /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
+ },
+
+ {
+ /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+ /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+ /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
+ },
+
+ {
+ /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+ /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+ /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
+ 0
+ },
+
+ {
+ /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
+ /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
+ /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
+ 0
+ },
+
+ {
+ /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
+ /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
+ /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
+ /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
+ }
+ },
+ .ctlPowerData_2G = {
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
+
+ { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
+ },
+ .modalHeader5G = {
+ /* 4 idle,t1,t2,b (4 bits per setting) */
+ .antCtrlCommon = LE32(0x220),
+ /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
+ .antCtrlCommon2 = LE32(0x44444),
+ /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
+ .antCtrlChain = {
+ LE16(0x150), LE16(0x150), LE16(0x150),
+ },
+ /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
+ .xatten1DB = {0x19, 0x19, 0x19},
+
+ /*
+ * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
+ * for merlin (0xa20c/b20c 16:12
+ */
+ .xatten1Margin = {0x14, 0x14, 0x14},
+ .tempSlope = 70,
+ .voltSlope = 0,
+ /* spurChans spur channels in usual fbin coding format */
+ .spurChans = {0, 0, 0, 0, 0},
+ /* noiseFloorThreshCh Check if the register is per chain */
+ .noiseFloorThreshCh = {-1, 0, 0},
+ .ob = {3, 3, 3}, /* 3 chain */
+ .db_stage2 = {3, 3, 3}, /* 3 chain */
+ .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */
+ .db_stage4 = {3, 3, 3}, /* don't exist for 2G */
+ .xpaBiasLvl = 0,
+ .txFrameToDataStart = 0x0e,
+ .txFrameToPaOn = 0x0e,
+ .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
+ .antennaGain = 0,
+ .switchSettling = 0x2d,
+ .adcDesiredSize = -30,
+ .txEndToXpaOff = 0,
+ .txEndToRxOn = 0x2,
+ .txFrameToXpaOn = 0xe,
+ .thresh62 = 28,
+ .papdRateMaskHt20 = LE32(0x0cf0e0e0),
+ .papdRateMaskHt40 = LE32(0x6cf0e0e0),
+ .futureModal = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ },
+ },
+ .base_ext2 = {
+ .tempSlopeLow = 35,
+ .tempSlopeHigh = 50,
+ .xatten1DBLow = {0, 0, 0},
+ .xatten1MarginLow = {0, 0, 0},
+ .xatten1DBHigh = {0, 0, 0},
+ .xatten1MarginHigh = {0, 0, 0}
+ },
+ .calFreqPier5G = {
+ FREQ2FBIN(5180, 0),
+ FREQ2FBIN(5220, 0),
+ FREQ2FBIN(5320, 0),
+ FREQ2FBIN(5400, 0),
+ FREQ2FBIN(5500, 0),
+ FREQ2FBIN(5600, 0),
+ FREQ2FBIN(5700, 0),
+ FREQ2FBIN(5785, 0)
+ },
+ .calPierData5G = {
+ {
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ },
+ {
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ },
+ {
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0},
+ },
+
+ },
+ .calTarget_freqbin_5G = {
+ FREQ2FBIN(5180, 0),
+ FREQ2FBIN(5240, 0),
+ FREQ2FBIN(5320, 0),
+ FREQ2FBIN(5400, 0),
+ FREQ2FBIN(5500, 0),
+ FREQ2FBIN(5600, 0),
+ FREQ2FBIN(5700, 0),
+ FREQ2FBIN(5825, 0)
+ },
+ .calTarget_freqbin_5GHT20 = {
+ FREQ2FBIN(5180, 0),
+ FREQ2FBIN(5240, 0),
+ FREQ2FBIN(5320, 0),
+ FREQ2FBIN(5400, 0),
+ FREQ2FBIN(5500, 0),
+ FREQ2FBIN(5700, 0),
+ FREQ2FBIN(5745, 0),
+ FREQ2FBIN(5825, 0)
+ },
+ .calTarget_freqbin_5GHT40 = {
+ FREQ2FBIN(5180, 0),
+ FREQ2FBIN(5240, 0),
+ FREQ2FBIN(5320, 0),
+ FREQ2FBIN(5400, 0),
+ FREQ2FBIN(5500, 0),
+ FREQ2FBIN(5700, 0),
+ FREQ2FBIN(5745, 0),
+ FREQ2FBIN(5825, 0)
+ },
+ .calTargetPower5G = {
+ /* 6-24,36,48,54 */
+ { {30, 30, 28, 24} },
+ { {30, 30, 28, 24} },
+ { {30, 30, 28, 24} },
+ { {30, 30, 28, 24} },
+ { {30, 30, 28, 24} },
+ { {30, 30, 28, 24} },
+ { {30, 30, 28, 24} },
+ { {30, 30, 28, 24} },
+ },
+ .calTargetPower5GHT20 = {
+ /*
+ * 0_8_16,1-3_9-11_17-19,
+ * 4,5,6,7,12,13,14,15,20,21,22,23
+ */
+ { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 0, 0, 0, 0} },
+ { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 0, 0, 0, 0} },
+ { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 0, 0, 0, 0} },
+ { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 0, 0, 0, 0} },
+ { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 0, 0, 0, 0} },
+ { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 0, 0, 0, 0} },
+ { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 0, 0, 0, 0} },
+ { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 0, 0, 0, 0} },
+ },
+ .calTargetPower5GHT40 = {
+ /*
+ * 0_8_16,1-3_9-11_17-19,
+ * 4,5,6,7,12,13,14,15,20,21,22,23
+ */
+ { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 0, 0, 0, 0} },
+ { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 0, 0, 0, 0} },
+ { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 0, 0, 0, 0} },
+ { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 0, 0, 0, 0} },
+ { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 0, 0, 0, 0} },
+ { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 0, 0, 0, 0} },
+ { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 0, 0, 0, 0} },
+ { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 0, 0, 0, 0} },
+ },
+ .ctlIndex_5G = {
+ 0x10, 0x16, 0x18, 0x40, 0x46,
+ 0x48, 0x30, 0x36, 0x38
+ },
+ .ctl_freqbin_5G = {
+ {
+ /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+ /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
+ /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
+ /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
+ /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
+ /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
+ /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
+ /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
+ },
+ {
+ /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+ /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
+ /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
+ /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
+ /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
+ /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
+ /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
+ /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
+ },
+
+ {
+ /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
+ /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
+ /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
+ /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
+ /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
+ /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
+ /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
+ /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
+ },
+
+ {
+ /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+ /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
+ /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
+ /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
+ /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
+ /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
+ /* Data[3].ctlEdges[6].bChannel */ 0xFF,
+ /* Data[3].ctlEdges[7].bChannel */ 0xFF,
+ },
+
+ {
+ /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+ /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
+ /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
+ /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
+ /* Data[4].ctlEdges[4].bChannel */ 0xFF,
+ /* Data[4].ctlEdges[5].bChannel */ 0xFF,
+ /* Data[4].ctlEdges[6].bChannel */ 0xFF,
+ /* Data[4].ctlEdges[7].bChannel */ 0xFF,
+ },
+
+ {
+ /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
+ /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
+ /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
+ /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
+ /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
+ /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
+ /* Data[5].ctlEdges[6].bChannel */ 0xFF,
+ /* Data[5].ctlEdges[7].bChannel */ 0xFF
+ },
+
+ {
+ /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+ /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
+ /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
+ /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
+ /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
+ /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
+ /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
+ /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
+ },
+
+ {
+ /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
+ /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
+ /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
+ /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
+ /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
+ /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
+ /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
+ /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
+ },
+
+ {
+ /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
+ /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
+ /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
+ /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
+ /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
+ /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
+ /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
+ /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
+ }
+ },
+ .ctlPowerData_5G = {
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ }
+ },
+ {
+ {
+ CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+ CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+ CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+ }
+ },
+ {
+ {
+ CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+ }
+ },
+ }
+};
+
+
+static const struct ar9300_eeprom *ar9300_eep_templates[] = {
+ &ar9300_default,
+ &ar9300_x112,
+ &ar9300_h116,
+ &ar9300_h112,
+ &ar9300_x113,
+};
+
+static const struct ar9300_eeprom *ar9003_eeprom_struct_find_by_id(int id)
+{
+#define N_LOOP (sizeof(ar9300_eep_templates) / sizeof(ar9300_eep_templates[0]))
+ int it;
+
+ for (it = 0; it < N_LOOP; it++)
+ if (ar9300_eep_templates[it]->templateVersion == id)
+ return ar9300_eep_templates[it];
+ return NULL;
+#undef N_LOOP
+}
+
+
static u16 ath9k_hw_fbin2freq(u8 fbin, bool is2GHz)
{
if (fbin == AR9300_BCHAN_UNUSED)
@@ -639,6 +2985,16 @@ static int ath9k_hw_ar9300_check_eeprom(struct ath_hw *ah)
return 0;
}
+static int interpolate(int x, int xa, int xb, int ya, int yb)
+{
+ int bf, factor, plus;
+
+ bf = 2 * (yb - ya) * (x - xa) / (xb - xa);
+ factor = bf / 2;
+ plus = bf % 2;
+ return ya + factor + plus;
+}
+
static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
enum eeprom_param param)
{
@@ -676,6 +3032,10 @@ static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
return le32_to_cpu(pBase->swreg);
case EEP_PAPRD:
return !!(pBase->featureEnable & BIT(5));
+ case EEP_CHAIN_MASK_REDUCE:
+ return (pBase->miscConfiguration >> 0x3) & 0x1;
+ case EEP_ANT_DIV_CTL1:
+ return le32_to_cpu(eep->base_ext1.ant_div_control);
default:
return 0;
}
@@ -714,8 +3074,8 @@ static bool ar9300_read_eeprom(struct ath_hw *ah, int address, u8 *buffer,
int i;
if ((address < 0) || ((address + count) / 2 > AR9300_EEPROM_SIZE - 1)) {
- ath_print(common, ATH_DBG_EEPROM,
- "eeprom address not in range\n");
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "eeprom address not in range\n");
return false;
}
@@ -746,11 +3106,41 @@ static bool ar9300_read_eeprom(struct ath_hw *ah, int address, u8 *buffer,
return true;
error:
- ath_print(common, ATH_DBG_EEPROM,
- "unable to read eeprom region at offset %d\n", address);
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "unable to read eeprom region at offset %d\n", address);
return false;
}
+static bool ar9300_otp_read_word(struct ath_hw *ah, int addr, u32 *data)
+{
+ REG_READ(ah, AR9300_OTP_BASE + (4 * addr));
+
+ if (!ath9k_hw_wait(ah, AR9300_OTP_STATUS, AR9300_OTP_STATUS_TYPE,
+ AR9300_OTP_STATUS_VALID, 1000))
+ return false;
+
+ *data = REG_READ(ah, AR9300_OTP_READ_DATA);
+ return true;
+}
+
+static bool ar9300_read_otp(struct ath_hw *ah, int address, u8 *buffer,
+ int count)
+{
+ u32 data;
+ int i;
+
+ for (i = 0; i < count; i++) {
+ int offset = 8 * ((address - i) % 4);
+ if (!ar9300_otp_read_word(ah, (address - i) / 4, &data))
+ return false;
+
+ buffer[i] = (data >> offset) & 0xff;
+ }
+
+ return true;
+}
+
+
static void ar9300_comp_hdr_unpack(u8 *best, int *code, int *reference,
int *length, int *major, int *minor)
{
@@ -801,17 +3191,15 @@ static bool ar9300_uncompress_block(struct ath_hw *ah,
length &= 0xff;
if (length > 0 && spot >= 0 && spot+length <= mdataSize) {
- ath_print(common, ATH_DBG_EEPROM,
- "Restore at %d: spot=%d "
- "offset=%d length=%d\n",
- it, spot, offset, length);
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "Restore at %d: spot=%d offset=%d length=%d\n",
+ it, spot, offset, length);
memcpy(&mptr[spot], &block[it+2], length);
spot += length;
} else if (length > 0) {
- ath_print(common, ATH_DBG_EEPROM,
- "Bad restore at %d: spot=%d "
- "offset=%d length=%d\n",
- it, spot, offset, length);
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "Bad restore at %d: spot=%d offset=%d length=%d\n",
+ it, spot, offset, length);
return false;
}
}
@@ -827,45 +3215,80 @@ static int ar9300_compress_decision(struct ath_hw *ah,
{
struct ath_common *common = ath9k_hw_common(ah);
u8 *dptr;
+ const struct ar9300_eeprom *eep = NULL;
switch (code) {
case _CompressNone:
if (length != mdata_size) {
- ath_print(common, ATH_DBG_EEPROM,
- "EEPROM structure size mismatch"
- "memory=%d eeprom=%d\n", mdata_size, length);
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "EEPROM structure size mismatch memory=%d eeprom=%d\n",
+ mdata_size, length);
return -1;
}
memcpy(mptr, (u8 *) (word + COMP_HDR_LEN), length);
- ath_print(common, ATH_DBG_EEPROM, "restored eeprom %d:"
- " uncompressed, length %d\n", it, length);
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "restored eeprom %d: uncompressed, length %d\n",
+ it, length);
break;
case _CompressBlock:
if (reference == 0) {
dptr = mptr;
} else {
- if (reference != 2) {
- ath_print(common, ATH_DBG_EEPROM,
- "cant find reference eeprom"
- "struct %d\n", reference);
+ eep = ar9003_eeprom_struct_find_by_id(reference);
+ if (eep == NULL) {
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "cant find reference eeprom struct %d\n",
+ reference);
return -1;
}
- memcpy(mptr, &ar9300_default, mdata_size);
+ memcpy(mptr, eep, mdata_size);
}
- ath_print(common, ATH_DBG_EEPROM,
- "restore eeprom %d: block, reference %d,"
- " length %d\n", it, reference, length);
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "restore eeprom %d: block, reference %d, length %d\n",
+ it, reference, length);
ar9300_uncompress_block(ah, mptr, mdata_size,
(u8 *) (word + COMP_HDR_LEN), length);
break;
default:
- ath_print(common, ATH_DBG_EEPROM, "unknown compression"
- " code %d\n", code);
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "unknown compression code %d\n", code);
return -1;
}
return 0;
}
+typedef bool (*eeprom_read_op)(struct ath_hw *ah, int address, u8 *buffer,
+ int count);
+
+static bool ar9300_check_header(void *data)
+{
+ u32 *word = data;
+ return !(*word == 0 || *word == ~0);
+}
+
+static bool ar9300_check_eeprom_header(struct ath_hw *ah, eeprom_read_op read,
+ int base_addr)
+{
+ u8 header[4];
+
+ if (!read(ah, base_addr, header, 4))
+ return false;
+
+ return ar9300_check_header(header);
+}
+
+static int ar9300_eeprom_restore_flash(struct ath_hw *ah, u8 *mptr,
+ int mdata_size)
+{
+ struct ath_common *common = ath9k_hw_common(ah);
+ u16 *data = (u16 *) mptr;
+ int i;
+
+ for (i = 0; i < mdata_size / 2; i++, data++)
+ ath9k_hw_nvram_read(common, i, data);
+
+ return 0;
+}
/*
* Read the configuration data from the eeprom.
* The data can be put in any specified memory buffer.
@@ -886,6 +3309,10 @@ static int ar9300_eeprom_restore_internal(struct ath_hw *ah,
int it;
u16 checksum, mchecksum;
struct ath_common *common = ath9k_hw_common(ah);
+ eeprom_read_op read;
+
+ if (ath9k_hw_use_flash(ah))
+ return ar9300_eeprom_restore_flash(ah, mptr, mdata_size);
word = kzalloc(2048, GFP_KERNEL);
if (!word)
@@ -893,43 +3320,73 @@ static int ar9300_eeprom_restore_internal(struct ath_hw *ah,
memcpy(mptr, &ar9300_default, mdata_size);
+ read = ar9300_read_eeprom;
+ if (AR_SREV_9485(ah))
+ cptr = AR9300_BASE_ADDR_4K;
+ else
+ cptr = AR9300_BASE_ADDR;
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "Trying EEPROM accesss at Address 0x%04x\n", cptr);
+ if (ar9300_check_eeprom_header(ah, read, cptr))
+ goto found;
+
+ cptr = AR9300_BASE_ADDR_512;
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "Trying EEPROM accesss at Address 0x%04x\n", cptr);
+ if (ar9300_check_eeprom_header(ah, read, cptr))
+ goto found;
+
+ read = ar9300_read_otp;
cptr = AR9300_BASE_ADDR;
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "Trying OTP accesss at Address 0x%04x\n", cptr);
+ if (ar9300_check_eeprom_header(ah, read, cptr))
+ goto found;
+
+ cptr = AR9300_BASE_ADDR_512;
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "Trying OTP accesss at Address 0x%04x\n", cptr);
+ if (ar9300_check_eeprom_header(ah, read, cptr))
+ goto found;
+
+ goto fail;
+
+found:
+ ath_dbg(common, ATH_DBG_EEPROM, "Found valid EEPROM data\n");
+
for (it = 0; it < MSTATE; it++) {
- if (!ar9300_read_eeprom(ah, cptr, word, COMP_HDR_LEN))
+ if (!read(ah, cptr, word, COMP_HDR_LEN))
goto fail;
- if ((word[0] == 0 && word[1] == 0 && word[2] == 0 &&
- word[3] == 0) || (word[0] == 0xff && word[1] == 0xff
- && word[2] == 0xff && word[3] == 0xff))
+ if (!ar9300_check_header(word))
break;
ar9300_comp_hdr_unpack(word, &code, &reference,
&length, &major, &minor);
- ath_print(common, ATH_DBG_EEPROM,
- "Found block at %x: code=%d ref=%d"
- "length=%d major=%d minor=%d\n", cptr, code,
- reference, length, major, minor);
- if (length >= 1024) {
- ath_print(common, ATH_DBG_EEPROM,
- "Skipping bad header\n");
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "Found block at %x: code=%d ref=%d length=%d major=%d minor=%d\n",
+ cptr, code, reference, length, major, minor);
+ if ((!AR_SREV_9485(ah) && length >= 1024) ||
+ (AR_SREV_9485(ah) && length >= (4 * 1024))) {
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "Skipping bad header\n");
cptr -= COMP_HDR_LEN;
continue;
}
osize = length;
- ar9300_read_eeprom(ah, cptr, word,
- COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
+ read(ah, cptr, word, COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
checksum = ar9300_comp_cksum(&word[COMP_HDR_LEN], length);
mchecksum = word[COMP_HDR_LEN + osize] |
(word[COMP_HDR_LEN + osize + 1] << 8);
- ath_print(common, ATH_DBG_EEPROM,
- "checksum %x %x\n", checksum, mchecksum);
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "checksum %x %x\n", checksum, mchecksum);
if (checksum == mchecksum) {
ar9300_compress_decision(ah, it, code, reference, mptr,
word, length, mdata_size);
} else {
- ath_print(common, ATH_DBG_EEPROM,
- "skipping block with bad checksum\n");
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "skipping block with bad checksum\n");
}
cptr -= (COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
}
@@ -995,9 +3452,15 @@ static s32 ar9003_hw_xpa_bias_level_get(struct ath_hw *ah, bool is2ghz)
static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
{
int bias = ar9003_hw_xpa_bias_level_get(ah, is2ghz);
- REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, (bias & 0x3));
- REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_SPARE,
- ((bias >> 2) & 0x3));
+
+ if (AR_SREV_9485(ah))
+ REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias);
+ else {
+ REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
+ REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_XPABIASLVL_MSB,
+ bias >> 2);
+ REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_XPASHORT2GND, 1);
+ }
}
static u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, bool is2ghz)
@@ -1052,11 +3515,25 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
value = ar9003_hw_ant_ctrl_chain_get(ah, 0, is2ghz);
REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_0, AR_SWITCH_TABLE_ALL, value);
- value = ar9003_hw_ant_ctrl_chain_get(ah, 1, is2ghz);
- REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_1, AR_SWITCH_TABLE_ALL, value);
+ if (!AR_SREV_9485(ah)) {
+ value = ar9003_hw_ant_ctrl_chain_get(ah, 1, is2ghz);
+ REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_1, AR_SWITCH_TABLE_ALL,
+ value);
- value = ar9003_hw_ant_ctrl_chain_get(ah, 2, is2ghz);
- REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_2, AR_SWITCH_TABLE_ALL, value);
+ value = ar9003_hw_ant_ctrl_chain_get(ah, 2, is2ghz);
+ REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_2, AR_SWITCH_TABLE_ALL,
+ value);
+ }
+
+ if (AR_SREV_9485(ah)) {
+ value = ath9k_hw_ar9300_get_eeprom(ah, EEP_ANT_DIV_CTL1);
+ REG_RMW_FIELD(ah, AR_PHY_MC_GAIN_CTRL, AR_ANT_DIV_CTRL_ALL,
+ value);
+ REG_RMW_FIELD(ah, AR_PHY_MC_GAIN_CTRL, AR_ANT_DIV_ENABLE,
+ value >> 6);
+ REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT, AR_FAST_DIV_ENABLE,
+ value >> 7);
+ }
}
static void ar9003_hw_drive_strength_apply(struct ath_hw *ah)
@@ -1100,28 +3577,177 @@ static void ar9003_hw_drive_strength_apply(struct ath_hw *ah)
REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS4, reg);
}
+static u16 ar9003_hw_atten_chain_get(struct ath_hw *ah, int chain,
+ struct ath9k_channel *chan)
+{
+ int f[3], t[3];
+ u16 value;
+ struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+
+ if (chain >= 0 && chain < 3) {
+ if (IS_CHAN_2GHZ(chan))
+ return eep->modalHeader2G.xatten1DB[chain];
+ else if (eep->base_ext2.xatten1DBLow[chain] != 0) {
+ t[0] = eep->base_ext2.xatten1DBLow[chain];
+ f[0] = 5180;
+ t[1] = eep->modalHeader5G.xatten1DB[chain];
+ f[1] = 5500;
+ t[2] = eep->base_ext2.xatten1DBHigh[chain];
+ f[2] = 5785;
+ value = ar9003_hw_power_interpolate((s32) chan->channel,
+ f, t, 3);
+ return value;
+ } else
+ return eep->modalHeader5G.xatten1DB[chain];
+ }
+
+ return 0;
+}
+
+
+static u16 ar9003_hw_atten_chain_get_margin(struct ath_hw *ah, int chain,
+ struct ath9k_channel *chan)
+{
+ int f[3], t[3];
+ u16 value;
+ struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+
+ if (chain >= 0 && chain < 3) {
+ if (IS_CHAN_2GHZ(chan))
+ return eep->modalHeader2G.xatten1Margin[chain];
+ else if (eep->base_ext2.xatten1MarginLow[chain] != 0) {
+ t[0] = eep->base_ext2.xatten1MarginLow[chain];
+ f[0] = 5180;
+ t[1] = eep->modalHeader5G.xatten1Margin[chain];
+ f[1] = 5500;
+ t[2] = eep->base_ext2.xatten1MarginHigh[chain];
+ f[2] = 5785;
+ value = ar9003_hw_power_interpolate((s32) chan->channel,
+ f, t, 3);
+ return value;
+ } else
+ return eep->modalHeader5G.xatten1Margin[chain];
+ }
+
+ return 0;
+}
+
+static void ar9003_hw_atten_apply(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+ int i;
+ u16 value;
+ unsigned long ext_atten_reg[3] = {AR_PHY_EXT_ATTEN_CTL_0,
+ AR_PHY_EXT_ATTEN_CTL_1,
+ AR_PHY_EXT_ATTEN_CTL_2,
+ };
+
+ /* Test value. if 0 then attenuation is unused. Don't load anything. */
+ for (i = 0; i < 3; i++) {
+ value = ar9003_hw_atten_chain_get(ah, i, chan);
+ REG_RMW_FIELD(ah, ext_atten_reg[i],
+ AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
+
+ value = ar9003_hw_atten_chain_get_margin(ah, i, chan);
+ REG_RMW_FIELD(ah, ext_atten_reg[i],
+ AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN, value);
+ }
+}
+
+static bool is_pmu_set(struct ath_hw *ah, u32 pmu_reg, int pmu_set)
+{
+ int timeout = 100;
+
+ while (pmu_set != REG_READ(ah, pmu_reg)) {
+ if (timeout-- == 0)
+ return false;
+ REG_WRITE(ah, pmu_reg, pmu_set);
+ udelay(10);
+ }
+
+ return true;
+}
+
static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
{
int internal_regulator =
ath9k_hw_ar9300_get_eeprom(ah, EEP_INTERNAL_REGULATOR);
if (internal_regulator) {
- /* Internal regulator is ON. Write swreg register. */
- int swreg = ath9k_hw_ar9300_get_eeprom(ah, EEP_SWREG);
- REG_WRITE(ah, AR_RTC_REG_CONTROL1,
- REG_READ(ah, AR_RTC_REG_CONTROL1) &
- (~AR_RTC_REG_CONTROL1_SWREG_PROGRAM));
- REG_WRITE(ah, AR_RTC_REG_CONTROL0, swreg);
- /* Set REG_CONTROL1.SWREG_PROGRAM */
- REG_WRITE(ah, AR_RTC_REG_CONTROL1,
- REG_READ(ah,
- AR_RTC_REG_CONTROL1) |
- AR_RTC_REG_CONTROL1_SWREG_PROGRAM);
+ if (AR_SREV_9485(ah)) {
+ int reg_pmu_set;
+
+ reg_pmu_set = REG_READ(ah, AR_PHY_PMU2) & ~AR_PHY_PMU2_PGM;
+ REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
+ if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
+ return;
+
+ reg_pmu_set = (5 << 1) | (7 << 4) | (1 << 8) |
+ (7 << 14) | (6 << 17) | (1 << 20) |
+ (3 << 24) | (1 << 28);
+
+ REG_WRITE(ah, AR_PHY_PMU1, reg_pmu_set);
+ if (!is_pmu_set(ah, AR_PHY_PMU1, reg_pmu_set))
+ return;
+
+ reg_pmu_set = (REG_READ(ah, AR_PHY_PMU2) & ~0xFFC00000)
+ | (4 << 26);
+ REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
+ if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
+ return;
+
+ reg_pmu_set = (REG_READ(ah, AR_PHY_PMU2) & ~0x00200000)
+ | (1 << 21);
+ REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
+ if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
+ return;
+ } else {
+ /* Internal regulator is ON. Write swreg register. */
+ int swreg = ath9k_hw_ar9300_get_eeprom(ah, EEP_SWREG);
+ REG_WRITE(ah, AR_RTC_REG_CONTROL1,
+ REG_READ(ah, AR_RTC_REG_CONTROL1) &
+ (~AR_RTC_REG_CONTROL1_SWREG_PROGRAM));
+ REG_WRITE(ah, AR_RTC_REG_CONTROL0, swreg);
+ /* Set REG_CONTROL1.SWREG_PROGRAM */
+ REG_WRITE(ah, AR_RTC_REG_CONTROL1,
+ REG_READ(ah,
+ AR_RTC_REG_CONTROL1) |
+ AR_RTC_REG_CONTROL1_SWREG_PROGRAM);
+ }
} else {
- REG_WRITE(ah, AR_RTC_SLEEP_CLK,
- (REG_READ(ah,
- AR_RTC_SLEEP_CLK) |
- AR_RTC_FORCE_SWREG_PRD));
+ if (AR_SREV_9485(ah)) {
+ REG_RMW_FIELD(ah, AR_PHY_PMU2, AR_PHY_PMU2_PGM, 0);
+ while (REG_READ_FIELD(ah, AR_PHY_PMU2,
+ AR_PHY_PMU2_PGM))
+ udelay(10);
+
+ REG_RMW_FIELD(ah, AR_PHY_PMU1, AR_PHY_PMU1_PWD, 0x1);
+ while (!REG_READ_FIELD(ah, AR_PHY_PMU1,
+ AR_PHY_PMU1_PWD))
+ udelay(10);
+ REG_RMW_FIELD(ah, AR_PHY_PMU2, AR_PHY_PMU2_PGM, 0x1);
+ while (!REG_READ_FIELD(ah, AR_PHY_PMU2,
+ AR_PHY_PMU2_PGM))
+ udelay(10);
+ } else
+ REG_WRITE(ah, AR_RTC_SLEEP_CLK,
+ (REG_READ(ah,
+ AR_RTC_SLEEP_CLK) |
+ AR_RTC_FORCE_SWREG_PRD));
+ }
+
+}
+
+static void ar9003_hw_apply_tuning_caps(struct ath_hw *ah)
+{
+ struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+ u8 tuning_caps_param = eep->baseEepHeader.params_for_tuning_caps[0];
+
+ if (eep->baseEepHeader.featureEnable & 0x40) {
+ tuning_caps_param &= 0x7f;
+ REG_RMW_FIELD(ah, AR_CH0_XTAL, AR_CH0_XTAL_CAPINDAC,
+ tuning_caps_param);
+ REG_RMW_FIELD(ah, AR_CH0_XTAL, AR_CH0_XTAL_CAPOUTDAC,
+ tuning_caps_param);
}
}
@@ -1131,7 +3757,10 @@ static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
ar9003_hw_xpa_bias_level_apply(ah, IS_CHAN_2GHZ(chan));
ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan));
ar9003_hw_drive_strength_apply(ah);
+ ar9003_hw_atten_apply(ah, chan);
ar9003_hw_internal_regulator_apply(ah);
+ if (AR_SREV_9485(ah))
+ ar9003_hw_apply_tuning_caps(ah);
}
static void ath9k_hw_ar9300_set_addac(struct ath_hw *ah,
@@ -1192,7 +3821,7 @@ static int ar9003_hw_power_interpolate(int32_t x,
if (hx == lx)
y = ly;
else /* interpolate */
- y = ly + (((x - lx) * (hy - ly)) / (hx - lx));
+ y = interpolate(x, lx, hx, ly, hy);
} else /* only low is good, use it */
y = ly;
} else if (hhave) /* only high is good, use it */
@@ -1561,22 +4190,9 @@ static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq,
ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
is2GHz) + ht40PowerIncForPdadc;
- while (i < ar9300RateSize) {
- ath_print(common, ATH_DBG_EEPROM,
- "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
- i++;
-
- ath_print(common, ATH_DBG_EEPROM,
- "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
- i++;
-
- ath_print(common, ATH_DBG_EEPROM,
- "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
- i++;
-
- ath_print(common, ATH_DBG_EEPROM,
- "TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]);
- i++;
+ for (i = 0; i < ar9300RateSize; i++) {
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]);
}
}
@@ -1595,18 +4211,17 @@ static int ar9003_hw_cal_pier_get(struct ath_hw *ah,
struct ath_common *common = ath9k_hw_common(ah);
if (ichain >= AR9300_MAX_CHAINS) {
- ath_print(common, ATH_DBG_EEPROM,
- "Invalid chain index, must be less than %d\n",
- AR9300_MAX_CHAINS);
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "Invalid chain index, must be less than %d\n",
+ AR9300_MAX_CHAINS);
return -1;
}
if (mode) { /* 5GHz */
if (ipier >= AR9300_NUM_5G_CAL_PIERS) {
- ath_print(common, ATH_DBG_EEPROM,
- "Invalid 5GHz cal pier index, must "
- "be less than %d\n",
- AR9300_NUM_5G_CAL_PIERS);
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "Invalid 5GHz cal pier index, must be less than %d\n",
+ AR9300_NUM_5G_CAL_PIERS);
return -1;
}
pCalPier = &(eep->calFreqPier5G[ipier]);
@@ -1614,9 +4229,9 @@ static int ar9003_hw_cal_pier_get(struct ath_hw *ah,
is2GHz = 0;
} else {
if (ipier >= AR9300_NUM_2G_CAL_PIERS) {
- ath_print(common, ATH_DBG_EEPROM,
- "Invalid 2GHz cal pier index, must "
- "be less than %d\n", AR9300_NUM_2G_CAL_PIERS);
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "Invalid 2GHz cal pier index, must be less than %d\n",
+ AR9300_NUM_2G_CAL_PIERS);
return -1;
}
@@ -1640,27 +4255,32 @@ static int ar9003_hw_power_control_override(struct ath_hw *ah,
{
int tempSlope = 0;
struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+ int f[3], t[3];
REG_RMW(ah, AR_PHY_TPC_11_B0,
(correction[0] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
AR_PHY_TPC_OLPC_GAIN_DELTA);
- REG_RMW(ah, AR_PHY_TPC_11_B1,
- (correction[1] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
- AR_PHY_TPC_OLPC_GAIN_DELTA);
- REG_RMW(ah, AR_PHY_TPC_11_B2,
- (correction[2] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
- AR_PHY_TPC_OLPC_GAIN_DELTA);
+ if (ah->caps.tx_chainmask & BIT(1))
+ REG_RMW(ah, AR_PHY_TPC_11_B1,
+ (correction[1] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
+ AR_PHY_TPC_OLPC_GAIN_DELTA);
+ if (ah->caps.tx_chainmask & BIT(2))
+ REG_RMW(ah, AR_PHY_TPC_11_B2,
+ (correction[2] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
+ AR_PHY_TPC_OLPC_GAIN_DELTA);
/* enable open loop power control on chip */
REG_RMW(ah, AR_PHY_TPC_6_B0,
(3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
AR_PHY_TPC_6_ERROR_EST_MODE);
- REG_RMW(ah, AR_PHY_TPC_6_B1,
- (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
- AR_PHY_TPC_6_ERROR_EST_MODE);
- REG_RMW(ah, AR_PHY_TPC_6_B2,
- (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
- AR_PHY_TPC_6_ERROR_EST_MODE);
+ if (ah->caps.tx_chainmask & BIT(1))
+ REG_RMW(ah, AR_PHY_TPC_6_B1,
+ (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
+ AR_PHY_TPC_6_ERROR_EST_MODE);
+ if (ah->caps.tx_chainmask & BIT(2))
+ REG_RMW(ah, AR_PHY_TPC_6_B2,
+ (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
+ AR_PHY_TPC_6_ERROR_EST_MODE);
/*
* enable temperature compensation
@@ -1668,7 +4288,16 @@ static int ar9003_hw_power_control_override(struct ath_hw *ah,
*/
if (frequency < 4000)
tempSlope = eep->modalHeader2G.tempSlope;
- else
+ else if (eep->base_ext2.tempSlopeLow != 0) {
+ t[0] = eep->base_ext2.tempSlopeLow;
+ f[0] = 5180;
+ t[1] = eep->modalHeader5G.tempSlope;
+ f[1] = 5500;
+ t[2] = eep->base_ext2.tempSlopeHigh;
+ f[2] = 5785;
+ tempSlope = ar9003_hw_power_interpolate((s32) frequency,
+ f, t, 3);
+ } else
tempSlope = eep->modalHeader5G.tempSlope;
REG_RMW_FIELD(ah, AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, tempSlope);
@@ -1756,11 +4385,11 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency)
/* interpolate */
for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
- ath_print(common, ATH_DBG_EEPROM,
- "ch=%d f=%d low=%d %d h=%d %d\n",
- ichain, frequency, lfrequency[ichain],
- lcorrection[ichain], hfrequency[ichain],
- hcorrection[ichain]);
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "ch=%d f=%d low=%d %d h=%d %d\n",
+ ichain, frequency, lfrequency[ichain],
+ lcorrection[ichain], hfrequency[ichain],
+ hcorrection[ichain]);
/* they're the same, so just pick one */
if (hfrequency[ichain] == lfrequency[ichain]) {
correction[ichain] = lcorrection[ichain];
@@ -1772,25 +4401,23 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency)
/* so is the high frequency, interpolate */
if (hfrequency[ichain] - frequency < 1000) {
- correction[ichain] = lcorrection[ichain] +
- (((frequency - lfrequency[ichain]) *
- (hcorrection[ichain] -
- lcorrection[ichain])) /
- (hfrequency[ichain] - lfrequency[ichain]));
-
- temperature[ichain] = ltemperature[ichain] +
- (((frequency - lfrequency[ichain]) *
- (htemperature[ichain] -
- ltemperature[ichain])) /
- (hfrequency[ichain] - lfrequency[ichain]));
-
- voltage[ichain] =
- lvoltage[ichain] +
- (((frequency -
- lfrequency[ichain]) * (hvoltage[ichain] -
- lvoltage[ichain]))
- / (hfrequency[ichain] -
- lfrequency[ichain]));
+ correction[ichain] = interpolate(frequency,
+ lfrequency[ichain],
+ hfrequency[ichain],
+ lcorrection[ichain],
+ hcorrection[ichain]);
+
+ temperature[ichain] = interpolate(frequency,
+ lfrequency[ichain],
+ hfrequency[ichain],
+ ltemperature[ichain],
+ htemperature[ichain]);
+
+ voltage[ichain] = interpolate(frequency,
+ lfrequency[ichain],
+ hfrequency[ichain],
+ lvoltage[ichain],
+ hvoltage[ichain]);
}
/* only low is good, use it */
else {
@@ -1814,9 +4441,9 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency)
ar9003_hw_power_control_override(ah, frequency, correction, voltage,
temperature);
- ath_print(common, ATH_DBG_EEPROM,
- "for frequency=%d, calibration correction = %d %d %d\n",
- frequency, correction[0], correction[1], correction[2]);
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "for frequency=%d, calibration correction = %d %d %d\n",
+ frequency, correction[0], correction[1], correction[2]);
return 0;
}
@@ -1922,14 +4549,16 @@ static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
int i;
int16_t twiceLargestAntenna;
u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
- u16 ctlModesFor11a[] = {
+ static const u16 ctlModesFor11a[] = {
CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40
};
- u16 ctlModesFor11g[] = {
+ static const u16 ctlModesFor11g[] = {
CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT,
CTL_11G_EXT, CTL_2GHT40
};
- u16 numCtlModes, *pCtlMode, ctlMode, freq;
+ u16 numCtlModes;
+ const u16 *pCtlMode;
+ u16 ctlMode, freq;
struct chan_centers centers;
u8 *ctlIndex;
u8 ctlNum;
@@ -2019,11 +4648,10 @@ static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
else
freq = centers.ctl_center;
- ath_print(common, ATH_DBG_REGULATORY,
- "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
- "EXT_ADDITIVE %d\n",
- ctlMode, numCtlModes, isHt40CtlMode,
- (pCtlMode[ctlMode] & EXT_ADDITIVE));
+ ath_dbg(common, ATH_DBG_REGULATORY,
+ "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, EXT_ADDITIVE %d\n",
+ ctlMode, numCtlModes, isHt40CtlMode,
+ (pCtlMode[ctlMode] & EXT_ADDITIVE));
/* walk through each CTL index stored in EEPROM */
if (is2ghz) {
@@ -2035,12 +4663,10 @@ static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
}
for (i = 0; (i < ctlNum) && ctlIndex[i]; i++) {
- ath_print(common, ATH_DBG_REGULATORY,
- "LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
- "pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
- "chan %dn",
- i, cfgCtl, pCtlMode[ctlMode], ctlIndex[i],
- chan->channel);
+ ath_dbg(common, ATH_DBG_REGULATORY,
+ "LOOP-Ctlidx %d: cfgCtl 0x%2.2x pCtlMode 0x%2.2x ctlIndex 0x%2.2x chan %d\n",
+ i, cfgCtl, pCtlMode[ctlMode], ctlIndex[i],
+ chan->channel);
/*
* compare test group from regulatory
@@ -2079,11 +4705,10 @@ static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower);
- ath_print(common, ATH_DBG_REGULATORY,
- "SEL-Min ctlMode %d pCtlMode %d 2xMaxEdge %d "
- "sP %d minCtlPwr %d\n",
- ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
- scaledPower, minCtlPower);
+ ath_dbg(common, ATH_DBG_REGULATORY,
+ "SEL-Min ctlMode %d pCtlMode %d 2xMaxEdge %d sP %d minCtlPwr %d\n",
+ ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
+ scaledPower, minCtlPower);
/* Apply ctl mode to correct target power set */
switch (pCtlMode[ctlMode]) {
@@ -2134,8 +4759,9 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
struct ath9k_channel *chan, u16 cfgCtl,
u8 twiceAntennaReduction,
u8 twiceMaxRegulatoryPower,
- u8 powerLimit)
+ u8 powerLimit, bool test)
{
+ struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
struct ath_common *common = ath9k_hw_common(ah);
u8 targetPowerValT2[ar9300RateSize];
unsigned int i = 0;
@@ -2147,23 +4773,19 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
twiceMaxRegulatoryPower,
powerLimit);
- while (i < ar9300RateSize) {
- ath_print(common, ATH_DBG_EEPROM,
- "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
- i++;
- ath_print(common, ATH_DBG_EEPROM,
- "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
- i++;
- ath_print(common, ATH_DBG_EEPROM,
- "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
- i++;
- ath_print(common, ATH_DBG_EEPROM,
- "TPC[%02d] 0x%08x\n\n", i, targetPowerValT2[i]);
- i++;
+ regulatory->max_power_level = 0;
+ for (i = 0; i < ar9300RateSize; i++) {
+ if (targetPowerValT2[i] > regulatory->max_power_level)
+ regulatory->max_power_level = targetPowerValT2[i];
}
- /* Write target power array to registers */
- ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
+ if (test)
+ return;
+
+ for (i = 0; i < ar9300RateSize; i++) {
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]);
+ }
/*
* This is the TX power we send back to driver core,
@@ -2183,7 +4805,10 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
i = ALL_TARGET_HT20_0_8_16; /* ht20 */
ah->txpower_limit = targetPowerValT2[i];
+ regulatory->max_power_level = targetPowerValT2[i];
+ /* Write target power array to registers */
+ ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
ar9003_hw_calibration_apply(ah, chan->channel);
}
@@ -2207,6 +4832,16 @@ s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah)
return (eep->baseEepHeader.txrxgain) & 0xf; /* bits 3:0 */
}
+u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is_2ghz)
+{
+ struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+
+ if (is_2ghz)
+ return eep->modalHeader2G.spurChans;
+ else
+ return eep->modalHeader5G.spurChans;
+}
+
const struct eeprom_ops eep_ar9300_ops = {
.check_eeprom = ath9k_hw_ar9300_check_eeprom,
.get_eeprom = ath9k_hw_ar9300_get_eeprom,
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
index 655b3033396c..33503217dab3 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
@@ -78,7 +78,17 @@
#define AR9300_EEPROM_SIZE (16*1024)
#define FIXED_CCA_THRESHOLD 15
+#define AR9300_BASE_ADDR_4K 0xfff
#define AR9300_BASE_ADDR 0x3ff
+#define AR9300_BASE_ADDR_512 0x1ff
+
+#define AR9300_OTP_BASE 0x14000
+#define AR9300_OTP_STATUS 0x15f18
+#define AR9300_OTP_STATUS_TYPE 0x7
+#define AR9300_OTP_STATUS_VALID 0x4
+#define AR9300_OTP_STATUS_ACCESS_BUSY 0x2
+#define AR9300_OTP_STATUS_SM_BUSY 0x1
+#define AR9300_OTP_READ_DATA 0x15f1c
enum targetPowerHTRates {
HT_TARGET_RATE_0_8_16,
@@ -236,7 +246,7 @@ struct ar9300_modal_eep_header {
u8 thresh62;
__le32 papdRateMaskHt20;
__le32 papdRateMaskHt40;
- u8 futureModal[24];
+ u8 futureModal[10];
} __packed;
struct ar9300_cal_data_per_freq_op_loop {
@@ -269,6 +279,20 @@ struct cal_ctl_data_5g {
u8 ctlEdges[AR9300_NUM_BAND_EDGES_5G];
} __packed;
+struct ar9300_BaseExtension_1 {
+ u8 ant_div_control;
+ u8 future[13];
+} __packed;
+
+struct ar9300_BaseExtension_2 {
+ int8_t tempSlopeLow;
+ int8_t tempSlopeHigh;
+ u8 xatten1DBLow[AR9300_MAX_CHAINS];
+ u8 xatten1MarginLow[AR9300_MAX_CHAINS];
+ u8 xatten1DBHigh[AR9300_MAX_CHAINS];
+ u8 xatten1MarginHigh[AR9300_MAX_CHAINS];
+} __packed;
+
struct ar9300_eeprom {
u8 eepromVersion;
u8 templateVersion;
@@ -278,6 +302,7 @@ struct ar9300_eeprom {
struct ar9300_base_eep_hdr baseEepHeader;
struct ar9300_modal_eep_header modalHeader2G;
+ struct ar9300_BaseExtension_1 base_ext1;
u8 calFreqPier2G[AR9300_NUM_2G_CAL_PIERS];
struct ar9300_cal_data_per_freq_op_loop
calPierData2G[AR9300_MAX_CHAINS][AR9300_NUM_2G_CAL_PIERS];
@@ -297,6 +322,7 @@ struct ar9300_eeprom {
u8 ctl_freqbin_2G[AR9300_NUM_CTLS_2G][AR9300_NUM_BAND_EDGES_2G];
struct cal_ctl_data_2g ctlPowerData_2G[AR9300_NUM_CTLS_2G];
struct ar9300_modal_eep_header modalHeader5G;
+ struct ar9300_BaseExtension_2 base_ext2;
u8 calFreqPier5G[AR9300_NUM_5G_CAL_PIERS];
struct ar9300_cal_data_per_freq_op_loop
calPierData5G[AR9300_MAX_CHAINS][AR9300_NUM_5G_CAL_PIERS];
@@ -317,4 +343,5 @@ struct ar9300_eeprom {
s32 ar9003_hw_get_tx_gain_idx(struct ath_hw *ah);
s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah);
+u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is_2ghz);
#endif
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
index c2a057156bfa..21a5bfe354a0 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -17,6 +17,7 @@
#include "hw.h"
#include "ar9003_mac.h"
#include "ar9003_2p2_initvals.h"
+#include "ar9485_initvals.h"
/* General hardware code for the AR9003 hadware family */
@@ -24,6 +25,7 @@ static bool ar9003_hw_macversion_supported(u32 macversion)
{
switch (macversion) {
case AR_SREV_VERSION_9300:
+ case AR_SREV_VERSION_9485:
return true;
default:
break;
@@ -38,72 +40,134 @@ static bool ar9003_hw_macversion_supported(u32 macversion)
*/
static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
{
- /* mac */
- INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
- INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
- ar9300_2p2_mac_core,
- ARRAY_SIZE(ar9300_2p2_mac_core), 2);
- INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
- ar9300_2p2_mac_postamble,
- ARRAY_SIZE(ar9300_2p2_mac_postamble), 5);
-
- /* bb */
- INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
- INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
- ar9300_2p2_baseband_core,
- ARRAY_SIZE(ar9300_2p2_baseband_core), 2);
- INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
- ar9300_2p2_baseband_postamble,
- ARRAY_SIZE(ar9300_2p2_baseband_postamble), 5);
-
- /* radio */
- INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
- INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
- ar9300_2p2_radio_core,
- ARRAY_SIZE(ar9300_2p2_radio_core), 2);
- INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
- ar9300_2p2_radio_postamble,
- ARRAY_SIZE(ar9300_2p2_radio_postamble), 5);
-
- /* soc */
- INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
- ar9300_2p2_soc_preamble,
- ARRAY_SIZE(ar9300_2p2_soc_preamble), 2);
- INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
- INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
- ar9300_2p2_soc_postamble,
- ARRAY_SIZE(ar9300_2p2_soc_postamble), 5);
-
- /* rx/tx gain */
- INIT_INI_ARRAY(&ah->iniModesRxGain,
- ar9300Common_rx_gain_table_2p2,
- ARRAY_SIZE(ar9300Common_rx_gain_table_2p2), 2);
- INIT_INI_ARRAY(&ah->iniModesTxGain,
- ar9300Modes_lowest_ob_db_tx_gain_table_2p2,
- ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2),
- 5);
-
- /* Load PCIE SERDES settings from INI */
-
- /* Awake Setting */
-
- INIT_INI_ARRAY(&ah->iniPcieSerdes,
- ar9300PciePhy_pll_on_clkreq_disable_L1_2p2,
- ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p2),
- 2);
-
- /* Sleep Setting */
-
- INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
- ar9300PciePhy_clkreq_enable_L1_2p2,
- ARRAY_SIZE(ar9300PciePhy_clkreq_enable_L1_2p2),
- 2);
-
- /* Fast clock modal settings */
- INIT_INI_ARRAY(&ah->iniModesAdditional,
- ar9300Modes_fast_clock_2p2,
- ARRAY_SIZE(ar9300Modes_fast_clock_2p2),
- 3);
+ if (AR_SREV_9485(ah)) {
+ /* mac */
+ INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
+ INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
+ ar9485_1_0_mac_core,
+ ARRAY_SIZE(ar9485_1_0_mac_core), 2);
+ INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
+ ar9485_1_0_mac_postamble,
+ ARRAY_SIZE(ar9485_1_0_mac_postamble), 5);
+
+ /* bb */
+ INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], ar9485_1_0,
+ ARRAY_SIZE(ar9485_1_0), 2);
+ INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
+ ar9485_1_0_baseband_core,
+ ARRAY_SIZE(ar9485_1_0_baseband_core), 2);
+ INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
+ ar9485_1_0_baseband_postamble,
+ ARRAY_SIZE(ar9485_1_0_baseband_postamble), 5);
+
+ /* radio */
+ INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
+ INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
+ ar9485_1_0_radio_core,
+ ARRAY_SIZE(ar9485_1_0_radio_core), 2);
+ INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
+ ar9485_1_0_radio_postamble,
+ ARRAY_SIZE(ar9485_1_0_radio_postamble), 2);
+
+ /* soc */
+ INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
+ ar9485_1_0_soc_preamble,
+ ARRAY_SIZE(ar9485_1_0_soc_preamble), 2);
+ INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
+ INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], NULL, 0, 0);
+
+ /* rx/tx gain */
+ INIT_INI_ARRAY(&ah->iniModesRxGain,
+ ar9485Common_rx_gain_1_0,
+ ARRAY_SIZE(ar9485Common_rx_gain_1_0), 2);
+ INIT_INI_ARRAY(&ah->iniModesTxGain,
+ ar9485Modes_lowest_ob_db_tx_gain_1_0,
+ ARRAY_SIZE(ar9485Modes_lowest_ob_db_tx_gain_1_0),
+ 5);
+
+ /* Load PCIE SERDES settings from INI */
+
+ /* Awake Setting */
+
+ INIT_INI_ARRAY(&ah->iniPcieSerdes,
+ ar9485_1_0_pcie_phy_pll_on_clkreq_disable_L1,
+ ARRAY_SIZE(ar9485_1_0_pcie_phy_pll_on_clkreq_disable_L1),
+ 2);
+
+ /* Sleep Setting */
+
+ INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
+ ar9485_1_0_pcie_phy_pll_on_clkreq_enable_L1,
+ ARRAY_SIZE(ar9485_1_0_pcie_phy_pll_on_clkreq_enable_L1),
+ 2);
+ } else {
+ /* mac */
+ INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
+ INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
+ ar9300_2p2_mac_core,
+ ARRAY_SIZE(ar9300_2p2_mac_core), 2);
+ INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
+ ar9300_2p2_mac_postamble,
+ ARRAY_SIZE(ar9300_2p2_mac_postamble), 5);
+
+ /* bb */
+ INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
+ INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
+ ar9300_2p2_baseband_core,
+ ARRAY_SIZE(ar9300_2p2_baseband_core), 2);
+ INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
+ ar9300_2p2_baseband_postamble,
+ ARRAY_SIZE(ar9300_2p2_baseband_postamble), 5);
+
+ /* radio */
+ INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
+ INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
+ ar9300_2p2_radio_core,
+ ARRAY_SIZE(ar9300_2p2_radio_core), 2);
+ INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
+ ar9300_2p2_radio_postamble,
+ ARRAY_SIZE(ar9300_2p2_radio_postamble), 5);
+
+ /* soc */
+ INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
+ ar9300_2p2_soc_preamble,
+ ARRAY_SIZE(ar9300_2p2_soc_preamble), 2);
+ INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
+ INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
+ ar9300_2p2_soc_postamble,
+ ARRAY_SIZE(ar9300_2p2_soc_postamble), 5);
+
+ /* rx/tx gain */
+ INIT_INI_ARRAY(&ah->iniModesRxGain,
+ ar9300Common_rx_gain_table_2p2,
+ ARRAY_SIZE(ar9300Common_rx_gain_table_2p2), 2);
+ INIT_INI_ARRAY(&ah->iniModesTxGain,
+ ar9300Modes_lowest_ob_db_tx_gain_table_2p2,
+ ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2),
+ 5);
+
+ /* Load PCIE SERDES settings from INI */
+
+ /* Awake Setting */
+
+ INIT_INI_ARRAY(&ah->iniPcieSerdes,
+ ar9300PciePhy_pll_on_clkreq_disable_L1_2p2,
+ ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p2),
+ 2);
+
+ /* Sleep Setting */
+
+ INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
+ ar9300PciePhy_clkreq_enable_L1_2p2,
+ ARRAY_SIZE(ar9300PciePhy_clkreq_enable_L1_2p2),
+ 2);
+
+ /* Fast clock modal settings */
+ INIT_INI_ARRAY(&ah->iniModesAdditional,
+ ar9300Modes_fast_clock_2p2,
+ ARRAY_SIZE(ar9300Modes_fast_clock_2p2),
+ 3);
+ }
}
static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
@@ -111,22 +175,52 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
switch (ar9003_hw_get_tx_gain_idx(ah)) {
case 0:
default:
- INIT_INI_ARRAY(&ah->iniModesTxGain,
- ar9300Modes_lowest_ob_db_tx_gain_table_2p2,
- ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2),
- 5);
+ if (AR_SREV_9485(ah))
+ INIT_INI_ARRAY(&ah->iniModesTxGain,
+ ar9485Modes_lowest_ob_db_tx_gain_1_0,
+ ARRAY_SIZE(ar9485Modes_lowest_ob_db_tx_gain_1_0),
+ 5);
+ else
+ INIT_INI_ARRAY(&ah->iniModesTxGain,
+ ar9300Modes_lowest_ob_db_tx_gain_table_2p2,
+ ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2),
+ 5);
break;
case 1:
- INIT_INI_ARRAY(&ah->iniModesTxGain,
- ar9300Modes_high_ob_db_tx_gain_table_2p2,
- ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p2),
- 5);
+ if (AR_SREV_9485(ah))
+ INIT_INI_ARRAY(&ah->iniModesTxGain,
+ ar9485Modes_high_ob_db_tx_gain_1_0,
+ ARRAY_SIZE(ar9485Modes_lowest_ob_db_tx_gain_1_0),
+ 5);
+ else
+ INIT_INI_ARRAY(&ah->iniModesTxGain,
+ ar9300Modes_high_ob_db_tx_gain_table_2p2,
+ ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p2),
+ 5);
break;
case 2:
- INIT_INI_ARRAY(&ah->iniModesTxGain,
- ar9300Modes_low_ob_db_tx_gain_table_2p2,
- ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p2),
- 5);
+ if (AR_SREV_9485(ah))
+ INIT_INI_ARRAY(&ah->iniModesTxGain,
+ ar9485Modes_low_ob_db_tx_gain_1_0,
+ ARRAY_SIZE(ar9485Modes_lowest_ob_db_tx_gain_1_0),
+ 5);
+ else
+ INIT_INI_ARRAY(&ah->iniModesTxGain,
+ ar9300Modes_low_ob_db_tx_gain_table_2p2,
+ ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p2),
+ 5);
+ break;
+ case 3:
+ if (AR_SREV_9485(ah))
+ INIT_INI_ARRAY(&ah->iniModesTxGain,
+ ar9485Modes_high_power_tx_gain_1_0,
+ ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_0),
+ 5);
+ else
+ INIT_INI_ARRAY(&ah->iniModesTxGain,
+ ar9300Modes_high_power_tx_gain_table_2p2,
+ ARRAY_SIZE(ar9300Modes_high_power_tx_gain_table_2p2),
+ 5);
break;
}
}
@@ -136,16 +230,28 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
switch (ar9003_hw_get_rx_gain_idx(ah)) {
case 0:
default:
- INIT_INI_ARRAY(&ah->iniModesRxGain,
- ar9300Common_rx_gain_table_2p2,
- ARRAY_SIZE(ar9300Common_rx_gain_table_2p2),
- 2);
+ if (AR_SREV_9485(ah))
+ INIT_INI_ARRAY(&ah->iniModesRxGain,
+ ar9485Common_rx_gain_1_0,
+ ARRAY_SIZE(ar9485Common_rx_gain_1_0),
+ 2);
+ else
+ INIT_INI_ARRAY(&ah->iniModesRxGain,
+ ar9300Common_rx_gain_table_2p2,
+ ARRAY_SIZE(ar9300Common_rx_gain_table_2p2),
+ 2);
break;
case 1:
- INIT_INI_ARRAY(&ah->iniModesRxGain,
- ar9300Common_wo_xlna_rx_gain_table_2p2,
- ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p2),
- 2);
+ if (AR_SREV_9485(ah))
+ INIT_INI_ARRAY(&ah->iniModesRxGain,
+ ar9485Common_wo_xlna_rx_gain_1_0,
+ ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_0),
+ 2);
+ else
+ INIT_INI_ARRAY(&ah->iniModesRxGain,
+ ar9300Common_wo_xlna_rx_gain_table_2p2,
+ ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p2),
+ 2);
break;
}
}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index 3b424ca1ba84..bfba6a2b741d 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -182,8 +182,8 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
}
if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT)
- ath_print(common, ATH_DBG_INTERRUPT,
- "AR_INTR_SYNC_LOCAL_TIMEOUT\n");
+ ath_dbg(common, ATH_DBG_INTERRUPT,
+ "AR_INTR_SYNC_LOCAL_TIMEOUT\n");
REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
(void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR);
@@ -237,73 +237,76 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds,
struct ath_tx_status *ts)
{
struct ar9003_txs *ads;
+ u32 status;
ads = &ah->ts_ring[ah->ts_tail];
- if ((ads->status8 & AR_TxDone) == 0)
+ status = ACCESS_ONCE(ads->status8);
+ if ((status & AR_TxDone) == 0)
return -EINPROGRESS;
ah->ts_tail = (ah->ts_tail + 1) % ah->ts_size;
if ((MS(ads->ds_info, AR_DescId) != ATHEROS_VENDOR_ID) ||
(MS(ads->ds_info, AR_TxRxDesc) != 1)) {
- ath_print(ath9k_hw_common(ah), ATH_DBG_XMIT,
- "Tx Descriptor error %x\n", ads->ds_info);
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_XMIT,
+ "Tx Descriptor error %x\n", ads->ds_info);
memset(ads, 0, sizeof(*ads));
return -EIO;
}
+ if (status & AR_TxOpExceeded)
+ ts->ts_status |= ATH9K_TXERR_XTXOP;
+ ts->ts_rateindex = MS(status, AR_FinalTxIdx);
+ ts->ts_seqnum = MS(status, AR_SeqNum);
+ ts->tid = MS(status, AR_TxTid);
+
ts->qid = MS(ads->ds_info, AR_TxQcuNum);
ts->desc_id = MS(ads->status1, AR_TxDescId);
- ts->ts_seqnum = MS(ads->status8, AR_SeqNum);
ts->ts_tstamp = ads->status4;
ts->ts_status = 0;
ts->ts_flags = 0;
- if (ads->status3 & AR_ExcessiveRetries)
+ status = ACCESS_ONCE(ads->status2);
+ ts->ts_rssi_ctl0 = MS(status, AR_TxRSSIAnt00);
+ ts->ts_rssi_ctl1 = MS(status, AR_TxRSSIAnt01);
+ ts->ts_rssi_ctl2 = MS(status, AR_TxRSSIAnt02);
+ if (status & AR_TxBaStatus) {
+ ts->ts_flags |= ATH9K_TX_BA;
+ ts->ba_low = ads->status5;
+ ts->ba_high = ads->status6;
+ }
+
+ status = ACCESS_ONCE(ads->status3);
+ if (status & AR_ExcessiveRetries)
ts->ts_status |= ATH9K_TXERR_XRETRY;
- if (ads->status3 & AR_Filtered)
+ if (status & AR_Filtered)
ts->ts_status |= ATH9K_TXERR_FILT;
- if (ads->status3 & AR_FIFOUnderrun) {
+ if (status & AR_FIFOUnderrun) {
ts->ts_status |= ATH9K_TXERR_FIFO;
ath9k_hw_updatetxtriglevel(ah, true);
}
- if (ads->status8 & AR_TxOpExceeded)
- ts->ts_status |= ATH9K_TXERR_XTXOP;
- if (ads->status3 & AR_TxTimerExpired)
+ if (status & AR_TxTimerExpired)
ts->ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
-
- if (ads->status3 & AR_DescCfgErr)
+ if (status & AR_DescCfgErr)
ts->ts_flags |= ATH9K_TX_DESC_CFG_ERR;
- if (ads->status3 & AR_TxDataUnderrun) {
+ if (status & AR_TxDataUnderrun) {
ts->ts_flags |= ATH9K_TX_DATA_UNDERRUN;
ath9k_hw_updatetxtriglevel(ah, true);
}
- if (ads->status3 & AR_TxDelimUnderrun) {
+ if (status & AR_TxDelimUnderrun) {
ts->ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
ath9k_hw_updatetxtriglevel(ah, true);
}
- if (ads->status2 & AR_TxBaStatus) {
- ts->ts_flags |= ATH9K_TX_BA;
- ts->ba_low = ads->status5;
- ts->ba_high = ads->status6;
- }
-
- ts->ts_rateindex = MS(ads->status8, AR_FinalTxIdx);
-
- ts->ts_rssi = MS(ads->status7, AR_TxRSSICombined);
- ts->ts_rssi_ctl0 = MS(ads->status2, AR_TxRSSIAnt00);
- ts->ts_rssi_ctl1 = MS(ads->status2, AR_TxRSSIAnt01);
- ts->ts_rssi_ctl2 = MS(ads->status2, AR_TxRSSIAnt02);
- ts->ts_rssi_ext0 = MS(ads->status7, AR_TxRSSIAnt10);
- ts->ts_rssi_ext1 = MS(ads->status7, AR_TxRSSIAnt11);
- ts->ts_rssi_ext2 = MS(ads->status7, AR_TxRSSIAnt12);
- ts->ts_shortretry = MS(ads->status3, AR_RTSFailCnt);
- ts->ts_longretry = MS(ads->status3, AR_DataFailCnt);
- ts->ts_virtcol = MS(ads->status3, AR_VirtRetryCnt);
- ts->ts_antenna = 0;
+ ts->ts_shortretry = MS(status, AR_RTSFailCnt);
+ ts->ts_longretry = MS(status, AR_DataFailCnt);
+ ts->ts_virtcol = MS(status, AR_VirtRetryCnt);
- ts->tid = MS(ads->status8, AR_TxTid);
+ status = ACCESS_ONCE(ads->status7);
+ ts->ts_rssi = MS(status, AR_TxRSSICombined);
+ ts->ts_rssi_ext0 = MS(status, AR_TxRSSIAnt10);
+ ts->ts_rssi_ext1 = MS(status, AR_TxRSSIAnt11);
+ ts->ts_rssi_ext2 = MS(status, AR_TxRSSIAnt12);
memset(ads, 0, sizeof(*ads));
@@ -407,12 +410,36 @@ static void ar9003_hw_set11n_ratescenario(struct ath_hw *ah, void *ds,
static void ar9003_hw_set11n_aggr_first(struct ath_hw *ah, void *ds,
u32 aggrLen)
{
+#define FIRST_DESC_NDELIMS 60
struct ar9003_txc *ads = (struct ar9003_txc *) ds;
ads->ctl12 |= (AR_IsAggr | AR_MoreAggr);
- ads->ctl17 &= ~AR_AggrLen;
- ads->ctl17 |= SM(aggrLen, AR_AggrLen);
+ if (ah->ent_mode & AR_ENT_OTP_MPSD) {
+ u32 ctl17, ndelim;
+ /*
+ * Add delimiter when using RTS/CTS with aggregation
+ * and non enterprise AR9003 card
+ */
+ ctl17 = ads->ctl17;
+ ndelim = MS(ctl17, AR_PadDelim);
+
+ if (ndelim < FIRST_DESC_NDELIMS) {
+ aggrLen += (FIRST_DESC_NDELIMS - ndelim) * 4;
+ ndelim = FIRST_DESC_NDELIMS;
+ }
+
+ ctl17 &= ~AR_AggrLen;
+ ctl17 |= SM(aggrLen, AR_AggrLen);
+
+ ctl17 &= ~AR_PadDelim;
+ ctl17 |= SM(ndelim, AR_PadDelim);
+
+ ads->ctl17 = ctl17;
+ } else {
+ ads->ctl17 &= ~AR_AggrLen;
+ ads->ctl17 |= SM(aggrLen, AR_AggrLen);
+ }
}
static void ar9003_hw_set11n_aggr_middle(struct ath_hw *ah, void *ds,
@@ -631,10 +658,10 @@ void ath9k_hw_reset_txstatus_ring(struct ath_hw *ah)
memset((void *) ah->ts_ring, 0,
ah->ts_size * sizeof(struct ar9003_txs));
- ath_print(ath9k_hw_common(ah), ATH_DBG_XMIT,
- "TS Start 0x%x End 0x%x Virt %p, Size %d\n",
- ah->ts_paddr_start, ah->ts_paddr_end,
- ah->ts_ring, ah->ts_size);
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_XMIT,
+ "TS Start 0x%x End 0x%x Virt %p, Size %d\n",
+ ah->ts_paddr_start, ah->ts_paddr_end,
+ ah->ts_ring, ah->ts_size);
REG_WRITE(ah, AR_Q_STATUS_RING_START, ah->ts_paddr_start);
REG_WRITE(ah, AR_Q_STATUS_RING_END, ah->ts_paddr_end);
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.h b/drivers/net/wireless/ath/ath9k/ar9003_mac.h
index 9f2cea70a840..45cc7e80436c 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.h
@@ -65,7 +65,7 @@ struct ar9003_rxs {
u32 status9;
u32 status10;
u32 status11;
-} __packed;
+} __packed __aligned(4);
/* Transmit Control Descriptor */
struct ar9003_txc {
@@ -93,7 +93,7 @@ struct ar9003_txc {
u32 ctl21; /* DMA control 21 */
u32 ctl22; /* DMA control 22 */
u32 pad[9]; /* pad to cache line (128 bytes/32 dwords) */
-} __packed;
+} __packed __aligned(4);
struct ar9003_txs {
u32 ds_info;
@@ -105,7 +105,7 @@ struct ar9003_txs {
u32 status6;
u32 status7;
u32 status8;
-} __packed;
+} __packed __aligned(4);
void ar9003_hw_attach_mac_ops(struct ath_hw *hw);
void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size);
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
index 716db414c258..74cff4365c43 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
@@ -21,10 +21,12 @@ void ar9003_paprd_enable(struct ath_hw *ah, bool val)
{
REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B0,
AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val);
- REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B1,
- AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val);
- REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B2,
- AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val);
+ if (ah->caps.tx_chainmask & BIT(1))
+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B1,
+ AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val);
+ if (ah->caps.tx_chainmask & BIT(2))
+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B2,
+ AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val);
}
EXPORT_SYMBOL(ar9003_paprd_enable);
@@ -32,12 +34,12 @@ static void ar9003_paprd_setup_single_table(struct ath_hw *ah)
{
struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
struct ar9300_modal_eep_header *hdr;
- const u32 ctrl0[3] = {
+ static const u32 ctrl0[3] = {
AR_PHY_PAPRD_CTRL0_B0,
AR_PHY_PAPRD_CTRL0_B1,
AR_PHY_PAPRD_CTRL0_B2
};
- const u32 ctrl1[3] = {
+ static const u32 ctrl1[3] = {
AR_PHY_PAPRD_CTRL1_B0,
AR_PHY_PAPRD_CTRL1_B1,
AR_PHY_PAPRD_CTRL1_B2
@@ -57,7 +59,8 @@ static void ar9003_paprd_setup_single_table(struct ath_hw *ah)
REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK, am_mask);
REG_RMW_FIELD(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK, ht40_mask);
- for (i = 0; i < 3; i++) {
+
+ for (i = 0; i < ah->caps.max_txchains; i++) {
REG_RMW_FIELD(ah, ctrl0[i],
AR_PHY_PAPRD_CTRL0_USE_SINGLE_TABLE_MASK, 1);
REG_RMW_FIELD(ah, ctrl1[i],
@@ -102,8 +105,14 @@ static void ar9003_paprd_setup_single_table(struct ath_hw *ah)
AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES, 7);
REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL, 1);
- REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
- AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP, -6);
+ if (AR_SREV_9485(ah))
+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
+ AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP,
+ -3);
+ else
+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
+ AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP,
+ -6);
REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE,
-15);
@@ -620,13 +629,15 @@ void ar9003_paprd_populate_single_table(struct ath_hw *ah,
AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL,
training_power);
- REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL1_B1,
- AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL,
- training_power);
+ if (ah->caps.tx_chainmask & BIT(1))
+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL1_B1,
+ AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL,
+ training_power);
- REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL1_B2,
- AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL,
- training_power);
+ if (ah->caps.tx_chainmask & BIT(2))
+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL1_B2,
+ AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL,
+ training_power);
}
EXPORT_SYMBOL(ar9003_paprd_populate_single_table);
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index 669b777729b3..da4a571304da 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -75,7 +75,10 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
freq = centers.synth_center;
if (freq < 4800) { /* 2 GHz, fractional mode */
- channelSel = CHANSEL_2G(freq);
+ if (AR_SREV_9485(ah))
+ channelSel = CHANSEL_2G_9485(freq);
+ else
+ channelSel = CHANSEL_2G(freq);
/* Set to 2G mode */
bMode = 1;
} else {
@@ -128,24 +131,53 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah,
struct ath9k_channel *chan)
{
- u32 spur_freq[4] = { 2420, 2440, 2464, 2480 };
+ static const u32 spur_freq[4] = { 2420, 2440, 2464, 2480 };
int cur_bb_spur, negative = 0, cck_spur_freq;
int i;
+ int range, max_spur_cnts, synth_freq;
+ u8 *spur_fbin_ptr = NULL;
/*
* Need to verify range +/- 10 MHz in control channel, otherwise spur
* is out-of-band and can be ignored.
*/
- for (i = 0; i < 4; i++) {
+ if (AR_SREV_9485(ah)) {
+ spur_fbin_ptr = ar9003_get_spur_chan_ptr(ah,
+ IS_CHAN_2GHZ(chan));
+ if (spur_fbin_ptr[0] == 0) /* No spur */
+ return;
+ max_spur_cnts = 5;
+ if (IS_CHAN_HT40(chan)) {
+ range = 19;
+ if (REG_READ_FIELD(ah, AR_PHY_GEN_CTRL,
+ AR_PHY_GC_DYN2040_PRI_CH) == 0)
+ synth_freq = chan->channel + 10;
+ else
+ synth_freq = chan->channel - 10;
+ } else {
+ range = 10;
+ synth_freq = chan->channel;
+ }
+ } else {
+ range = 10;
+ max_spur_cnts = 4;
+ synth_freq = chan->channel;
+ }
+
+ for (i = 0; i < max_spur_cnts; i++) {
negative = 0;
- cur_bb_spur = spur_freq[i] - chan->channel;
+ if (AR_SREV_9485(ah))
+ cur_bb_spur = FBIN2FREQ(spur_fbin_ptr[i],
+ IS_CHAN_2GHZ(chan)) - synth_freq;
+ else
+ cur_bb_spur = spur_freq[i] - synth_freq;
if (cur_bb_spur < 0) {
negative = 1;
cur_bb_spur = -cur_bb_spur;
}
- if (cur_bb_spur < 10) {
+ if (cur_bb_spur < range) {
cck_spur_freq = (int)((cur_bb_spur << 19) / 11);
if (negative == 1)
@@ -487,7 +519,11 @@ void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx)
break;
}
- REG_WRITE(ah, AR_SELFGEN_MASK, tx);
+ if ((ah->caps.hw_caps & ATH9K_HW_CAP_APM) && (tx == 0x7))
+ REG_WRITE(ah, AR_SELFGEN_MASK, 0x3);
+ else
+ REG_WRITE(ah, AR_SELFGEN_MASK, tx);
+
if (tx == 0x5) {
REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
AR_PHY_SWAP_ALT_CHAIN);
@@ -614,7 +650,7 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
channel->max_antenna_gain * 2,
channel->max_power * 2,
min((u32) MAX_RATE_POWER,
- (u32) regulatory->power_limit));
+ (u32) regulatory->power_limit), false);
return 0;
}
@@ -820,12 +856,12 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
if (!on != aniState->ofdmWeakSigDetectOff) {
- ath_print(common, ATH_DBG_ANI,
- "** ch %d: ofdm weak signal: %s=>%s\n",
- chan->channel,
- !aniState->ofdmWeakSigDetectOff ?
- "on" : "off",
- on ? "on" : "off");
+ ath_dbg(common, ATH_DBG_ANI,
+ "** ch %d: ofdm weak signal: %s=>%s\n",
+ chan->channel,
+ !aniState->ofdmWeakSigDetectOff ?
+ "on" : "off",
+ on ? "on" : "off");
if (on)
ah->stats.ast_ani_ofdmon++;
else
@@ -838,11 +874,9 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
u32 level = param;
if (level >= ARRAY_SIZE(firstep_table)) {
- ath_print(common, ATH_DBG_ANI,
- "ATH9K_ANI_FIRSTEP_LEVEL: level "
- "out of range (%u > %u)\n",
- level,
- (unsigned) ARRAY_SIZE(firstep_table));
+ ath_dbg(common, ATH_DBG_ANI,
+ "ATH9K_ANI_FIRSTEP_LEVEL: level out of range (%u > %zu)\n",
+ level, ARRAY_SIZE(firstep_table));
return false;
}
@@ -877,24 +911,22 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
AR_PHY_FIND_SIG_LOW_FIRSTEP_LOW, value2);
if (level != aniState->firstepLevel) {
- ath_print(common, ATH_DBG_ANI,
- "** ch %d: level %d=>%d[def:%d] "
- "firstep[level]=%d ini=%d\n",
- chan->channel,
- aniState->firstepLevel,
- level,
- ATH9K_ANI_FIRSTEP_LVL_NEW,
- value,
- aniState->iniDef.firstep);
- ath_print(common, ATH_DBG_ANI,
- "** ch %d: level %d=>%d[def:%d] "
- "firstep_low[level]=%d ini=%d\n",
- chan->channel,
- aniState->firstepLevel,
- level,
- ATH9K_ANI_FIRSTEP_LVL_NEW,
- value2,
- aniState->iniDef.firstepLow);
+ ath_dbg(common, ATH_DBG_ANI,
+ "** ch %d: level %d=>%d[def:%d] firstep[level]=%d ini=%d\n",
+ chan->channel,
+ aniState->firstepLevel,
+ level,
+ ATH9K_ANI_FIRSTEP_LVL_NEW,
+ value,
+ aniState->iniDef.firstep);
+ ath_dbg(common, ATH_DBG_ANI,
+ "** ch %d: level %d=>%d[def:%d] firstep_low[level]=%d ini=%d\n",
+ chan->channel,
+ aniState->firstepLevel,
+ level,
+ ATH9K_ANI_FIRSTEP_LVL_NEW,
+ value2,
+ aniState->iniDef.firstepLow);
if (level > aniState->firstepLevel)
ah->stats.ast_ani_stepup++;
else if (level < aniState->firstepLevel)
@@ -907,11 +939,9 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
u32 level = param;
if (level >= ARRAY_SIZE(cycpwrThr1_table)) {
- ath_print(common, ATH_DBG_ANI,
- "ATH9K_ANI_SPUR_IMMUNITY_LEVEL: level "
- "out of range (%u > %u)\n",
- level,
- (unsigned) ARRAY_SIZE(cycpwrThr1_table));
+ ath_dbg(common, ATH_DBG_ANI,
+ "ATH9K_ANI_SPUR_IMMUNITY_LEVEL: level out of range (%u > %zu)\n",
+ level, ARRAY_SIZE(cycpwrThr1_table));
return false;
}
/*
@@ -945,24 +975,22 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
AR_PHY_EXT_CYCPWR_THR1, value2);
if (level != aniState->spurImmunityLevel) {
- ath_print(common, ATH_DBG_ANI,
- "** ch %d: level %d=>%d[def:%d] "
- "cycpwrThr1[level]=%d ini=%d\n",
- chan->channel,
- aniState->spurImmunityLevel,
- level,
- ATH9K_ANI_SPUR_IMMUNE_LVL_NEW,
- value,
- aniState->iniDef.cycpwrThr1);
- ath_print(common, ATH_DBG_ANI,
- "** ch %d: level %d=>%d[def:%d] "
- "cycpwrThr1Ext[level]=%d ini=%d\n",
- chan->channel,
- aniState->spurImmunityLevel,
- level,
- ATH9K_ANI_SPUR_IMMUNE_LVL_NEW,
- value2,
- aniState->iniDef.cycpwrThr1Ext);
+ ath_dbg(common, ATH_DBG_ANI,
+ "** ch %d: level %d=>%d[def:%d] cycpwrThr1[level]=%d ini=%d\n",
+ chan->channel,
+ aniState->spurImmunityLevel,
+ level,
+ ATH9K_ANI_SPUR_IMMUNE_LVL_NEW,
+ value,
+ aniState->iniDef.cycpwrThr1);
+ ath_dbg(common, ATH_DBG_ANI,
+ "** ch %d: level %d=>%d[def:%d] cycpwrThr1Ext[level]=%d ini=%d\n",
+ chan->channel,
+ aniState->spurImmunityLevel,
+ level,
+ ATH9K_ANI_SPUR_IMMUNE_LVL_NEW,
+ value2,
+ aniState->iniDef.cycpwrThr1Ext);
if (level > aniState->spurImmunityLevel)
ah->stats.ast_ani_spurup++;
else if (level < aniState->spurImmunityLevel)
@@ -982,11 +1010,11 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL,
AR_PHY_MRC_CCK_MUX_REG, is_on);
if (!is_on != aniState->mrcCCKOff) {
- ath_print(common, ATH_DBG_ANI,
- "** ch %d: MRC CCK: %s=>%s\n",
- chan->channel,
- !aniState->mrcCCKOff ? "on" : "off",
- is_on ? "on" : "off");
+ ath_dbg(common, ATH_DBG_ANI,
+ "** ch %d: MRC CCK: %s=>%s\n",
+ chan->channel,
+ !aniState->mrcCCKOff ? "on" : "off",
+ is_on ? "on" : "off");
if (is_on)
ah->stats.ast_ani_ccklow++;
else
@@ -998,22 +1026,19 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
case ATH9K_ANI_PRESENT:
break;
default:
- ath_print(common, ATH_DBG_ANI,
- "invalid cmd %u\n", cmd);
+ ath_dbg(common, ATH_DBG_ANI, "invalid cmd %u\n", cmd);
return false;
}
- ath_print(common, ATH_DBG_ANI,
- "ANI parameters: SI=%d, ofdmWS=%s FS=%d "
- "MRCcck=%s listenTime=%d "
- "ofdmErrs=%d cckErrs=%d\n",
- aniState->spurImmunityLevel,
- !aniState->ofdmWeakSigDetectOff ? "on" : "off",
- aniState->firstepLevel,
- !aniState->mrcCCKOff ? "on" : "off",
- aniState->listenTime,
- aniState->ofdmPhyErrCount,
- aniState->cckPhyErrCount);
+ ath_dbg(common, ATH_DBG_ANI,
+ "ANI parameters: SI=%d, ofdmWS=%s FS=%d MRCcck=%s listenTime=%d ofdmErrs=%d cckErrs=%d\n",
+ aniState->spurImmunityLevel,
+ !aniState->ofdmWeakSigDetectOff ? "on" : "off",
+ aniState->firstepLevel,
+ !aniState->mrcCCKOff ? "on" : "off",
+ aniState->listenTime,
+ aniState->ofdmPhyErrCount,
+ aniState->cckPhyErrCount);
return true;
}
@@ -1023,25 +1048,25 @@ static void ar9003_hw_do_getnf(struct ath_hw *ah,
int16_t nf;
nf = MS(REG_READ(ah, AR_PHY_CCA_0), AR_PHY_MINCCA_PWR);
- nfarray[0] = sign_extend(nf, 9);
+ nfarray[0] = sign_extend32(nf, 8);
nf = MS(REG_READ(ah, AR_PHY_CCA_1), AR_PHY_CH1_MINCCA_PWR);
- nfarray[1] = sign_extend(nf, 9);
+ nfarray[1] = sign_extend32(nf, 8);
nf = MS(REG_READ(ah, AR_PHY_CCA_2), AR_PHY_CH2_MINCCA_PWR);
- nfarray[2] = sign_extend(nf, 9);
+ nfarray[2] = sign_extend32(nf, 8);
if (!IS_CHAN_HT40(ah->curchan))
return;
nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR);
- nfarray[3] = sign_extend(nf, 9);
+ nfarray[3] = sign_extend32(nf, 8);
nf = MS(REG_READ(ah, AR_PHY_EXT_CCA_1), AR_PHY_CH1_EXT_MINCCA_PWR);
- nfarray[4] = sign_extend(nf, 9);
+ nfarray[4] = sign_extend32(nf, 8);
nf = MS(REG_READ(ah, AR_PHY_EXT_CCA_2), AR_PHY_CH2_EXT_MINCCA_PWR);
- nfarray[5] = sign_extend(nf, 9);
+ nfarray[5] = sign_extend32(nf, 8);
}
static void ar9003_hw_set_nf_limits(struct ath_hw *ah)
@@ -1070,13 +1095,13 @@ static void ar9003_hw_ani_cache_ini_regs(struct ath_hw *ah)
aniState = &ah->curchan->ani;
iniDef = &aniState->iniDef;
- ath_print(common, ATH_DBG_ANI,
- "ver %d.%d opmode %u chan %d Mhz/0x%x\n",
- ah->hw_version.macVersion,
- ah->hw_version.macRev,
- ah->opmode,
- chan->channel,
- chan->channelFlags);
+ ath_dbg(common, ATH_DBG_ANI,
+ "ver %d.%d opmode %u chan %d Mhz/0x%x\n",
+ ah->hw_version.macVersion,
+ ah->hw_version.macRev,
+ ah->opmode,
+ chan->channel,
+ chan->channelFlags);
val = REG_READ(ah, AR_PHY_SFCORR);
iniDef->m1Thresh = MS(val, AR_PHY_SFCORR_M1_THRESH);
@@ -1113,10 +1138,55 @@ static void ar9003_hw_ani_cache_ini_regs(struct ath_hw *ah)
aniState->mrcCCKOff = !ATH9K_ANI_ENABLE_MRC_CCK;
}
+static void ar9003_hw_set_radar_params(struct ath_hw *ah,
+ struct ath_hw_radar_conf *conf)
+{
+ u32 radar_0 = 0, radar_1 = 0;
+
+ if (!conf) {
+ REG_CLR_BIT(ah, AR_PHY_RADAR_0, AR_PHY_RADAR_0_ENA);
+ return;
+ }
+
+ radar_0 |= AR_PHY_RADAR_0_ENA | AR_PHY_RADAR_0_FFT_ENA;
+ radar_0 |= SM(conf->fir_power, AR_PHY_RADAR_0_FIRPWR);
+ radar_0 |= SM(conf->radar_rssi, AR_PHY_RADAR_0_RRSSI);
+ radar_0 |= SM(conf->pulse_height, AR_PHY_RADAR_0_HEIGHT);
+ radar_0 |= SM(conf->pulse_rssi, AR_PHY_RADAR_0_PRSSI);
+ radar_0 |= SM(conf->pulse_inband, AR_PHY_RADAR_0_INBAND);
+
+ radar_1 |= AR_PHY_RADAR_1_MAX_RRSSI;
+ radar_1 |= AR_PHY_RADAR_1_BLOCK_CHECK;
+ radar_1 |= SM(conf->pulse_maxlen, AR_PHY_RADAR_1_MAXLEN);
+ radar_1 |= SM(conf->pulse_inband_step, AR_PHY_RADAR_1_RELSTEP_THRESH);
+ radar_1 |= SM(conf->radar_inband, AR_PHY_RADAR_1_RELPWR_THRESH);
+
+ REG_WRITE(ah, AR_PHY_RADAR_0, radar_0);
+ REG_WRITE(ah, AR_PHY_RADAR_1, radar_1);
+ if (conf->ext_channel)
+ REG_SET_BIT(ah, AR_PHY_RADAR_EXT, AR_PHY_RADAR_EXT_ENA);
+ else
+ REG_CLR_BIT(ah, AR_PHY_RADAR_EXT, AR_PHY_RADAR_EXT_ENA);
+}
+
+static void ar9003_hw_set_radar_conf(struct ath_hw *ah)
+{
+ struct ath_hw_radar_conf *conf = &ah->radar_conf;
+
+ conf->fir_power = -28;
+ conf->radar_rssi = 0;
+ conf->pulse_height = 10;
+ conf->pulse_rssi = 24;
+ conf->pulse_inband = 8;
+ conf->pulse_maxlen = 255;
+ conf->pulse_inband_step = 12;
+ conf->radar_inband = 8;
+}
+
void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
{
struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
- const u32 ar9300_cca_regs[6] = {
+ static const u32 ar9300_cca_regs[6] = {
AR_PHY_CCA_0,
AR_PHY_CCA_1,
AR_PHY_CCA_2,
@@ -1141,8 +1211,10 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
priv_ops->ani_control = ar9003_hw_ani_control;
priv_ops->do_getnf = ar9003_hw_do_getnf;
priv_ops->ani_cache_ini_regs = ar9003_hw_ani_cache_ini_regs;
+ priv_ops->set_radar_params = ar9003_hw_set_radar_params;
ar9003_hw_set_nf_limits(ah);
+ ar9003_hw_set_radar_conf(ah);
memcpy(ah->nf_regs, ar9300_cca_regs, sizeof(ah->nf_regs));
}
@@ -1165,7 +1237,7 @@ void ar9003_hw_bb_watchdog_config(struct ath_hw *ah)
~(AR_PHY_WATCHDOG_NON_IDLE_ENABLE |
AR_PHY_WATCHDOG_IDLE_ENABLE));
- ath_print(common, ATH_DBG_RESET, "Disabled BB Watchdog\n");
+ ath_dbg(common, ATH_DBG_RESET, "Disabled BB Watchdog\n");
return;
}
@@ -1201,9 +1273,9 @@ void ar9003_hw_bb_watchdog_config(struct ath_hw *ah)
AR_PHY_WATCHDOG_IDLE_MASK |
(AR_PHY_WATCHDOG_NON_IDLE_MASK & (idle_count << 2)));
- ath_print(common, ATH_DBG_RESET,
- "Enabled BB Watchdog timeout (%u ms)\n",
- idle_tmo_ms);
+ ath_dbg(common, ATH_DBG_RESET,
+ "Enabled BB Watchdog timeout (%u ms)\n",
+ idle_tmo_ms);
}
void ar9003_hw_bb_watchdog_read(struct ath_hw *ah)
@@ -1231,37 +1303,35 @@ void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah)
return;
status = ah->bb_watchdog_last_status;
- ath_print(common, ATH_DBG_RESET,
- "\n==== BB update: BB status=0x%08x ====\n", status);
- ath_print(common, ATH_DBG_RESET,
- "** BB state: wd=%u det=%u rdar=%u rOFDM=%d "
- "rCCK=%u tOFDM=%u tCCK=%u agc=%u src=%u **\n",
- MS(status, AR_PHY_WATCHDOG_INFO),
- MS(status, AR_PHY_WATCHDOG_DET_HANG),
- MS(status, AR_PHY_WATCHDOG_RADAR_SM),
- MS(status, AR_PHY_WATCHDOG_RX_OFDM_SM),
- MS(status, AR_PHY_WATCHDOG_RX_CCK_SM),
- MS(status, AR_PHY_WATCHDOG_TX_OFDM_SM),
- MS(status, AR_PHY_WATCHDOG_TX_CCK_SM),
- MS(status, AR_PHY_WATCHDOG_AGC_SM),
- MS(status,AR_PHY_WATCHDOG_SRCH_SM));
-
- ath_print(common, ATH_DBG_RESET,
- "** BB WD cntl: cntl1=0x%08x cntl2=0x%08x **\n",
- REG_READ(ah, AR_PHY_WATCHDOG_CTL_1),
- REG_READ(ah, AR_PHY_WATCHDOG_CTL_2));
- ath_print(common, ATH_DBG_RESET,
- "** BB mode: BB_gen_controls=0x%08x **\n",
- REG_READ(ah, AR_PHY_GEN_CTRL));
+ ath_dbg(common, ATH_DBG_RESET,
+ "\n==== BB update: BB status=0x%08x ====\n", status);
+ ath_dbg(common, ATH_DBG_RESET,
+ "** BB state: wd=%u det=%u rdar=%u rOFDM=%d rCCK=%u tOFDM=%u tCCK=%u agc=%u src=%u **\n",
+ MS(status, AR_PHY_WATCHDOG_INFO),
+ MS(status, AR_PHY_WATCHDOG_DET_HANG),
+ MS(status, AR_PHY_WATCHDOG_RADAR_SM),
+ MS(status, AR_PHY_WATCHDOG_RX_OFDM_SM),
+ MS(status, AR_PHY_WATCHDOG_RX_CCK_SM),
+ MS(status, AR_PHY_WATCHDOG_TX_OFDM_SM),
+ MS(status, AR_PHY_WATCHDOG_TX_CCK_SM),
+ MS(status, AR_PHY_WATCHDOG_AGC_SM),
+ MS(status, AR_PHY_WATCHDOG_SRCH_SM));
+
+ ath_dbg(common, ATH_DBG_RESET,
+ "** BB WD cntl: cntl1=0x%08x cntl2=0x%08x **\n",
+ REG_READ(ah, AR_PHY_WATCHDOG_CTL_1),
+ REG_READ(ah, AR_PHY_WATCHDOG_CTL_2));
+ ath_dbg(common, ATH_DBG_RESET,
+ "** BB mode: BB_gen_controls=0x%08x **\n",
+ REG_READ(ah, AR_PHY_GEN_CTRL));
#define PCT(_field) (common->cc_survey._field * 100 / common->cc_survey.cycles)
if (common->cc_survey.cycles)
- ath_print(common, ATH_DBG_RESET,
- "** BB busy times: rx_clear=%d%%, "
- "rx_frame=%d%%, tx_frame=%d%% **\n",
- PCT(rx_busy), PCT(rx_frame), PCT(tx_frame));
+ ath_dbg(common, ATH_DBG_RESET,
+ "** BB busy times: rx_clear=%d%%, rx_frame=%d%%, tx_frame=%d%% **\n",
+ PCT(rx_busy), PCT(rx_frame), PCT(tx_frame));
- ath_print(common, ATH_DBG_RESET,
- "==== BB update: done ====\n\n");
+ ath_dbg(common, ATH_DBG_RESET,
+ "==== BB update: done ====\n\n");
}
EXPORT_SYMBOL(ar9003_hw_bb_watchdog_dbg_info);
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
index 3394dfe52b42..6f811c7ada05 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
@@ -260,7 +260,13 @@
#define AR_PHY_CCA_0 (AR_AGC_BASE + 0x1c)
#define AR_PHY_EXT_CCA0 (AR_AGC_BASE + 0x20)
#define AR_PHY_RESTART (AR_AGC_BASE + 0x24)
+
#define AR_PHY_MC_GAIN_CTRL (AR_AGC_BASE + 0x28)
+#define AR_ANT_DIV_CTRL_ALL 0x7e000000
+#define AR_ANT_DIV_CTRL_ALL_S 25
+#define AR_ANT_DIV_ENABLE 0x1000000
+#define AR_ANT_DIV_ENABLE_S 24
+
#define AR_PHY_EXTCHN_PWRTHR1 (AR_AGC_BASE + 0x2c)
#define AR_PHY_EXT_CHN_WIN (AR_AGC_BASE + 0x30)
#define AR_PHY_20_40_DET_THR (AR_AGC_BASE + 0x34)
@@ -271,7 +277,11 @@
#define AR_PHY_RX_GAIN_BOUNDS_2 (AR_AGC_BASE + 0x48)
#define AR_PHY_RSSI_0 (AR_AGC_BASE + 0x180)
#define AR_PHY_SPUR_CCK_REP0 (AR_AGC_BASE + 0x184)
+
#define AR_PHY_CCK_DETECT (AR_AGC_BASE + 0x1c0)
+#define AR_FAST_DIV_ENABLE 0x2000
+#define AR_FAST_DIV_ENABLE_S 13
+
#define AR_PHY_DAG_CTRLCCK (AR_AGC_BASE + 0x1c4)
#define AR_PHY_IQCORR_CTRL_CCK (AR_AGC_BASE + 0x1c8)
@@ -536,10 +546,18 @@
#define AR_PHY_TXGAIN_TABLE (AR_SM_BASE + 0x300)
+#define AR_PHY_TX_IQCAL_START_9485 (AR_SM_BASE + 0x3c4)
+#define AR_PHY_TX_IQCAL_START_DO_CAL_9485 0x80000000
+#define AR_PHY_TX_IQCAL_START_DO_CAL_9485_S 31
+#define AR_PHY_TX_IQCAL_CONTROL_1_9485 (AR_SM_BASE + 0x3c8)
+#define AR_PHY_TX_IQCAL_STATUS_B0_9485 (AR_SM_BASE + 0x3f0)
+
#define AR_PHY_TX_IQCAL_CONTROL_1 (AR_SM_BASE + 0x448)
#define AR_PHY_TX_IQCAL_START (AR_SM_BASE + 0x440)
#define AR_PHY_TX_IQCAL_STATUS_B0 (AR_SM_BASE + 0x48c)
-#define AR_PHY_TX_IQCAL_CORR_COEFF_01_B0 (AR_SM_BASE + 0x450)
+#define AR_PHY_TX_IQCAL_CORR_COEFF_B0(_i) (AR_SM_BASE + \
+ (AR_SREV_9485(ah) ? \
+ 0x3d0 : 0x450) + ((_i) << 2))
#define AR_PHY_WATCHDOG_STATUS (AR_SM_BASE + 0x5c0)
#define AR_PHY_WATCHDOG_CTL_1 (AR_SM_BASE + 0x5c4)
@@ -568,7 +586,7 @@
#define AR_PHY_65NM_CH0_BIAS2 0x160c4
#define AR_PHY_65NM_CH0_BIAS4 0x160cc
#define AR_PHY_65NM_CH0_RXTX4 0x1610c
-#define AR_PHY_65NM_CH0_THERM 0x16290
+#define AR_PHY_65NM_CH0_THERM (AR_SREV_9485(ah) ? 0x1628c : 0x16290)
#define AR_PHY_65NM_CH0_THERM_LOCAL 0x80000000
#define AR_PHY_65NM_CH0_THERM_LOCAL_S 31
@@ -584,6 +602,24 @@
#define AR_PHY_65NM_CH2_RXTX1 0x16900
#define AR_PHY_65NM_CH2_RXTX2 0x16904
+#define AR_CH0_TOP2 (AR_SREV_9485(ah) ? 0x00016284 : 0x0001628c)
+#define AR_CH0_TOP2_XPABIASLVL 0xf000
+#define AR_CH0_TOP2_XPABIASLVL_S 12
+
+#define AR_CH0_XTAL (AR_SREV_9485(ah) ? 0x16290 : 0x16294)
+#define AR_CH0_XTAL_CAPINDAC 0x7f000000
+#define AR_CH0_XTAL_CAPINDAC_S 24
+#define AR_CH0_XTAL_CAPOUTDAC 0x00fe0000
+#define AR_CH0_XTAL_CAPOUTDAC_S 17
+
+#define AR_PHY_PMU1 0x16c40
+#define AR_PHY_PMU1_PWD 0x1
+#define AR_PHY_PMU1_PWD_S 0
+
+#define AR_PHY_PMU2 0x16c44
+#define AR_PHY_PMU2_PGM 0x00200000
+#define AR_PHY_PMU2_PGM_S 21
+
#define AR_PHY_RX1DB_BIQUAD_LONG_SHIFT 0x00380000
#define AR_PHY_RX1DB_BIQUAD_LONG_SHIFT_S 19
#define AR_PHY_RX6DB_BIQUAD_LONG_SHIFT 0x00c00000
@@ -683,6 +719,7 @@
#define AR_PHY_TPCGR1_FORCED_DAC_GAIN_S 1
#define AR_PHY_TPCGR1_FORCE_DAC_GAIN 0x00000001
#define AR_PHY_TXGAIN_FORCE 0x00000001
+#define AR_PHY_TXGAIN_FORCE_S 0
#define AR_PHY_TXGAIN_FORCED_PADVGNRA 0x00003c00
#define AR_PHY_TXGAIN_FORCED_PADVGNRA_S 10
#define AR_PHY_TXGAIN_FORCED_PADVGNRB 0x0003c000
@@ -725,8 +762,13 @@
#define AR_PHY_TX_IQCAL_START_DO_CAL_S 0
#define AR_PHY_TX_IQCAL_STATUS_FAILED 0x00000001
-#define AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE 0x00003fff
-#define AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE_S 0
+#define AR_PHY_CALIBRATED_GAINS_0 0x3e
+#define AR_PHY_CALIBRATED_GAINS_0_S 1
+
+#define AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE 0x00003fff
+#define AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE_S 0
+#define AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE 0x0fffc000
+#define AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE_S 14
#define AR_PHY_65NM_CH0_RXTX4_THERM_ON 0x10000000
#define AR_PHY_65NM_CH0_RXTX4_THERM_ON_S 28
@@ -785,7 +827,7 @@
#define AR_PHY_TPC_11_B1 (AR_SM1_BASE + 0x220)
#define AR_PHY_PDADC_TAB_1 (AR_SM1_BASE + 0x240)
#define AR_PHY_TX_IQCAL_STATUS_B1 (AR_SM1_BASE + 0x48c)
-#define AR_PHY_TX_IQCAL_CORR_COEFF_01_B1 (AR_SM1_BASE + 0x450)
+#define AR_PHY_TX_IQCAL_CORR_COEFF_B1(_i) (AR_SM_BASE + 0x450 + ((_i) << 2))
/*
* Channel 2 Register Map
@@ -838,7 +880,7 @@
#define AR_PHY_TPC_11_B2 (AR_SM2_BASE + 0x220)
#define AR_PHY_PDADC_TAB_2 (AR_SM2_BASE + 0x240)
#define AR_PHY_TX_IQCAL_STATUS_B2 (AR_SM2_BASE + 0x48c)
-#define AR_PHY_TX_IQCAL_CORR_COEFF_01_B2 (AR_SM2_BASE + 0x450)
+#define AR_PHY_TX_IQCAL_CORR_COEFF_B2(_i) (AR_SM2_BASE + 0x450 + ((_i) << 2))
#define AR_PHY_TX_IQCAL_STATUS_B2_FAILED 0x00000001
@@ -945,7 +987,9 @@
#define AR_PHY_PAPRD_CTRL1_PAPRD_MAG_SCALE_FACT 0x0ffe0000
#define AR_PHY_PAPRD_CTRL1_PAPRD_MAG_SCALE_FACT_S 17
-#define AR_PHY_PAPRD_TRAINER_CNTL1 (AR_SM_BASE + 0x490)
+#define AR_PHY_PAPRD_TRAINER_CNTL1 (AR_SM_BASE + \
+ (AR_SREV_9485(ah) ? \
+ 0x580 : 0x490))
#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE 0x00000001
#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE_S 0
#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING 0x0000007e
@@ -961,11 +1005,15 @@
#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP 0x0003f000
#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP_S 12
-#define AR_PHY_PAPRD_TRAINER_CNTL2 (AR_SM_BASE + 0x494)
+#define AR_PHY_PAPRD_TRAINER_CNTL2 (AR_SM_BASE + \
+ (AR_SREV_9485(ah) ? \
+ 0x584 : 0x494))
#define AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN 0xFFFFFFFF
#define AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN_S 0
-#define AR_PHY_PAPRD_TRAINER_CNTL3 (AR_SM_BASE + 0x498)
+#define AR_PHY_PAPRD_TRAINER_CNTL3 (AR_SM_BASE + \
+ (AR_SREV_9485(ah) ? \
+ 0x588 : 0x498))
#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE 0x0000003f
#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE_S 0
#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP 0x00000fc0
@@ -981,7 +1029,9 @@
#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE 0x20000000
#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE_S 29
-#define AR_PHY_PAPRD_TRAINER_CNTL4 (AR_SM_BASE + 0x49c)
+#define AR_PHY_PAPRD_TRAINER_CNTL4 (AR_SM_BASE + \
+ (AR_SREV_9485(ah) ? \
+ 0x58c : 0x49c))
#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_NUM_TRAIN_SAMPLES 0x03ff0000
#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_NUM_TRAIN_SAMPLES_S 16
#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_SAFETY_DELTA 0x0000f000
diff --git a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h
new file mode 100644
index 000000000000..70de3d89a7b5
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h
@@ -0,0 +1,943 @@
+/*
+ * Copyright (c) 2010 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef INITVALS_9485_H
+#define INITVALS_9485_H
+
+static const u32 ar9485Common_1_0[][2] = {
+ /* Addr allmodes */
+ {0x00007010, 0x00000022},
+ {0x00007020, 0x00000000},
+ {0x00007034, 0x00000002},
+ {0x00007038, 0x000004c2},
+};
+
+static const u32 ar9485_1_0_mac_postamble[][5] = {
+ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
+ {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
+ {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c},
+ {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38},
+ {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00},
+ {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b},
+ {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810},
+ {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a},
+ {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440},
+};
+
+static const u32 ar9485_1_0_pcie_phy_pll_on_clkreq_disable_L1[][2] = {
+ /* Addr allmodes */
+ {0x00018c00, 0x10212e5e},
+ {0x00018c04, 0x000801d8},
+ {0x00018c08, 0x0000580c},
+};
+
+static const u32 ar9485Common_wo_xlna_rx_gain_1_0[][2] = {
+ /* Addr allmodes */
+ {0x0000a000, 0x00010000},
+ {0x0000a004, 0x00030002},
+ {0x0000a008, 0x00050004},
+ {0x0000a00c, 0x00810080},
+ {0x0000a010, 0x01800082},
+ {0x0000a014, 0x01820181},
+ {0x0000a018, 0x01840183},
+ {0x0000a01c, 0x01880185},
+ {0x0000a020, 0x018a0189},
+ {0x0000a024, 0x02850284},
+ {0x0000a028, 0x02890288},
+ {0x0000a02c, 0x03850384},
+ {0x0000a030, 0x03890388},
+ {0x0000a034, 0x038b038a},
+ {0x0000a038, 0x038d038c},
+ {0x0000a03c, 0x03910390},
+ {0x0000a040, 0x03930392},
+ {0x0000a044, 0x03950394},
+ {0x0000a048, 0x00000396},
+ {0x0000a04c, 0x00000000},
+ {0x0000a050, 0x00000000},
+ {0x0000a054, 0x00000000},
+ {0x0000a058, 0x00000000},
+ {0x0000a05c, 0x00000000},
+ {0x0000a060, 0x00000000},
+ {0x0000a064, 0x00000000},
+ {0x0000a068, 0x00000000},
+ {0x0000a06c, 0x00000000},
+ {0x0000a070, 0x00000000},
+ {0x0000a074, 0x00000000},
+ {0x0000a078, 0x00000000},
+ {0x0000a07c, 0x00000000},
+ {0x0000a080, 0x28282828},
+ {0x0000a084, 0x28282828},
+ {0x0000a088, 0x28282828},
+ {0x0000a08c, 0x28282828},
+ {0x0000a090, 0x28282828},
+ {0x0000a094, 0x21212128},
+ {0x0000a098, 0x171c1c1c},
+ {0x0000a09c, 0x02020212},
+ {0x0000a0a0, 0x00000202},
+ {0x0000a0a4, 0x00000000},
+ {0x0000a0a8, 0x00000000},
+ {0x0000a0ac, 0x00000000},
+ {0x0000a0b0, 0x00000000},
+ {0x0000a0b4, 0x00000000},
+ {0x0000a0b8, 0x00000000},
+ {0x0000a0bc, 0x00000000},
+ {0x0000a0c0, 0x001f0000},
+ {0x0000a0c4, 0x111f1100},
+ {0x0000a0c8, 0x111d111e},
+ {0x0000a0cc, 0x111b111c},
+ {0x0000a0d0, 0x22032204},
+ {0x0000a0d4, 0x22012202},
+ {0x0000a0d8, 0x221f2200},
+ {0x0000a0dc, 0x221d221e},
+ {0x0000a0e0, 0x33013302},
+ {0x0000a0e4, 0x331f3300},
+ {0x0000a0e8, 0x4402331e},
+ {0x0000a0ec, 0x44004401},
+ {0x0000a0f0, 0x441e441f},
+ {0x0000a0f4, 0x55015502},
+ {0x0000a0f8, 0x551f5500},
+ {0x0000a0fc, 0x6602551e},
+ {0x0000a100, 0x66006601},
+ {0x0000a104, 0x661e661f},
+ {0x0000a108, 0x7703661d},
+ {0x0000a10c, 0x77017702},
+ {0x0000a110, 0x00007700},
+ {0x0000a114, 0x00000000},
+ {0x0000a118, 0x00000000},
+ {0x0000a11c, 0x00000000},
+ {0x0000a120, 0x00000000},
+ {0x0000a124, 0x00000000},
+ {0x0000a128, 0x00000000},
+ {0x0000a12c, 0x00000000},
+ {0x0000a130, 0x00000000},
+ {0x0000a134, 0x00000000},
+ {0x0000a138, 0x00000000},
+ {0x0000a13c, 0x00000000},
+ {0x0000a140, 0x001f0000},
+ {0x0000a144, 0x111f1100},
+ {0x0000a148, 0x111d111e},
+ {0x0000a14c, 0x111b111c},
+ {0x0000a150, 0x22032204},
+ {0x0000a154, 0x22012202},
+ {0x0000a158, 0x221f2200},
+ {0x0000a15c, 0x221d221e},
+ {0x0000a160, 0x33013302},
+ {0x0000a164, 0x331f3300},
+ {0x0000a168, 0x4402331e},
+ {0x0000a16c, 0x44004401},
+ {0x0000a170, 0x441e441f},
+ {0x0000a174, 0x55015502},
+ {0x0000a178, 0x551f5500},
+ {0x0000a17c, 0x6602551e},
+ {0x0000a180, 0x66006601},
+ {0x0000a184, 0x661e661f},
+ {0x0000a188, 0x7703661d},
+ {0x0000a18c, 0x77017702},
+ {0x0000a190, 0x00007700},
+ {0x0000a194, 0x00000000},
+ {0x0000a198, 0x00000000},
+ {0x0000a19c, 0x00000000},
+ {0x0000a1a0, 0x00000000},
+ {0x0000a1a4, 0x00000000},
+ {0x0000a1a8, 0x00000000},
+ {0x0000a1ac, 0x00000000},
+ {0x0000a1b0, 0x00000000},
+ {0x0000a1b4, 0x00000000},
+ {0x0000a1b8, 0x00000000},
+ {0x0000a1bc, 0x00000000},
+ {0x0000a1c0, 0x00000000},
+ {0x0000a1c4, 0x00000000},
+ {0x0000a1c8, 0x00000000},
+ {0x0000a1cc, 0x00000000},
+ {0x0000a1d0, 0x00000000},
+ {0x0000a1d4, 0x00000000},
+ {0x0000a1d8, 0x00000000},
+ {0x0000a1dc, 0x00000000},
+ {0x0000a1e0, 0x00000000},
+ {0x0000a1e4, 0x00000000},
+ {0x0000a1e8, 0x00000000},
+ {0x0000a1ec, 0x00000000},
+ {0x0000a1f0, 0x00000396},
+ {0x0000a1f4, 0x00000396},
+ {0x0000a1f8, 0x00000396},
+ {0x0000a1fc, 0x00000296},
+};
+
+static const u32 ar9485Modes_high_power_tx_gain_1_0[][5] = {
+ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
+ {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
+ {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000},
+ {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002},
+ {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004},
+ {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200},
+ {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202},
+ {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400},
+ {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402},
+ {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404},
+ {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603},
+ {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605},
+ {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03},
+ {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04},
+ {0x0000a530, 0x48023ec6, 0x48023ec6, 0x2e000a20, 0x2e000a20},
+ {0x0000a534, 0x4d023f01, 0x4d023f01, 0x34000e20, 0x34000e20},
+ {0x0000a538, 0x53023f4b, 0x53023f4b, 0x38000e22, 0x38000e22},
+ {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x3c000e24, 0x3c000e24},
+ {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x40000e26, 0x40000e26},
+ {0x0000a544, 0x6502feca, 0x6502feca, 0x43001640, 0x43001640},
+ {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x46001660, 0x46001660},
+ {0x0000a54c, 0x7203feca, 0x7203feca, 0x49001861, 0x49001861},
+ {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x4c001a81, 0x4c001a81},
+ {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x4f001a83, 0x4f001a83},
+ {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x54001c85, 0x54001c85},
+ {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x58001ce5, 0x58001ce5},
+ {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5b001ce9, 0x5b001ce9},
+ {0x0000a564, 0x960fffcb, 0x960fffcb, 0x60001eeb, 0x60001eeb},
+ {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x00016044, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db},
+};
+
+static const u32 ar9485_1_0[][2] = {
+ /* Addr allmodes */
+ {0x0000a580, 0x00000000},
+ {0x0000a584, 0x00000000},
+ {0x0000a588, 0x00000000},
+ {0x0000a58c, 0x00000000},
+ {0x0000a590, 0x00000000},
+ {0x0000a594, 0x00000000},
+ {0x0000a598, 0x00000000},
+ {0x0000a59c, 0x00000000},
+ {0x0000a5a0, 0x00000000},
+ {0x0000a5a4, 0x00000000},
+ {0x0000a5a8, 0x00000000},
+ {0x0000a5ac, 0x00000000},
+ {0x0000a5b0, 0x00000000},
+ {0x0000a5b4, 0x00000000},
+ {0x0000a5b8, 0x00000000},
+ {0x0000a5bc, 0x00000000},
+};
+
+static const u32 ar9485_1_0_radio_core[][2] = {
+ /* Addr allmodes */
+ {0x00016000, 0x36db6db6},
+ {0x00016004, 0x6db6db40},
+ {0x00016008, 0x73800000},
+ {0x0001600c, 0x00000000},
+ {0x00016040, 0x7f80fff8},
+ {0x00016048, 0x6c92426e},
+ {0x0001604c, 0x000f0278},
+ {0x00016050, 0x6db6db6c},
+ {0x00016054, 0x6db60000},
+ {0x00016080, 0x00080000},
+ {0x00016084, 0x0e48048c},
+ {0x00016088, 0x14214514},
+ {0x0001608c, 0x119f081e},
+ {0x00016090, 0x24926490},
+ {0x00016098, 0xd28b3330},
+ {0x000160a0, 0xc2108ffe},
+ {0x000160a4, 0x812fc370},
+ {0x000160a8, 0x423c8000},
+ {0x000160b4, 0x92480040},
+ {0x000160c0, 0x006db6db},
+ {0x000160c4, 0x0186db60},
+ {0x000160c8, 0x6db6db6c},
+ {0x000160cc, 0x6de6fbe0},
+ {0x000160d0, 0xf7dfcf3c},
+ {0x00016100, 0x04cb0001},
+ {0x00016104, 0xfff80015},
+ {0x00016108, 0x00080010},
+ {0x00016144, 0x01884080},
+ {0x00016148, 0x00008040},
+ {0x00016180, 0x08453333},
+ {0x00016184, 0x18e82f01},
+ {0x00016188, 0x00000000},
+ {0x0001618c, 0x00000000},
+ {0x00016240, 0x08400000},
+ {0x00016244, 0x1bf90f00},
+ {0x00016248, 0x00000000},
+ {0x0001624c, 0x00000000},
+ {0x00016280, 0x01000015},
+ {0x00016284, 0x00d30000},
+ {0x00016288, 0x00318000},
+ {0x0001628c, 0x50000000},
+ {0x00016290, 0x4b96210f},
+ {0x00016380, 0x00000000},
+ {0x00016384, 0x00000000},
+ {0x00016388, 0x00800700},
+ {0x0001638c, 0x00800700},
+ {0x00016390, 0x00800700},
+ {0x00016394, 0x00000000},
+ {0x00016398, 0x00000000},
+ {0x0001639c, 0x00000000},
+ {0x000163a0, 0x00000001},
+ {0x000163a4, 0x00000001},
+ {0x000163a8, 0x00000000},
+ {0x000163ac, 0x00000000},
+ {0x000163b0, 0x00000000},
+ {0x000163b4, 0x00000000},
+ {0x000163b8, 0x00000000},
+ {0x000163bc, 0x00000000},
+ {0x000163c0, 0x000000a0},
+ {0x000163c4, 0x000c0000},
+ {0x000163c8, 0x14021402},
+ {0x000163cc, 0x00001402},
+ {0x000163d0, 0x00000000},
+ {0x000163d4, 0x00000000},
+ {0x00016c40, 0x1319c178},
+ {0x00016c44, 0x10000000},
+};
+
+static const u32 ar9485Modes_lowest_ob_db_tx_gain_1_0[][5] = {
+ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
+ {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
+ {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000},
+ {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002},
+ {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004},
+ {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200},
+ {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202},
+ {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400},
+ {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402},
+ {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404},
+ {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603},
+ {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605},
+ {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03},
+ {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04},
+ {0x0000a530, 0x48023ec6, 0x48023ec6, 0x2e000a20, 0x2e000a20},
+ {0x0000a534, 0x4d023f01, 0x4d023f01, 0x34000e20, 0x34000e20},
+ {0x0000a538, 0x53023f4b, 0x53023f4b, 0x38000e22, 0x38000e22},
+ {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x3c000e24, 0x3c000e24},
+ {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x40000e26, 0x40000e26},
+ {0x0000a544, 0x6502feca, 0x6502feca, 0x43001640, 0x43001640},
+ {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x46001660, 0x46001660},
+ {0x0000a54c, 0x7203feca, 0x7203feca, 0x49001861, 0x49001861},
+ {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x4c001a81, 0x4c001a81},
+ {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x4f001a83, 0x4f001a83},
+ {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x54001c85, 0x54001c85},
+ {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x58001ce5, 0x58001ce5},
+ {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5b001ce9, 0x5b001ce9},
+ {0x0000a564, 0x960fffcb, 0x960fffcb, 0x60001eeb, 0x60001eeb},
+ {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x00016044, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db},
+};
+
+static const u32 ar9485_1_0_baseband_core[][2] = {
+ /* Addr allmodes */
+ {0x00009800, 0xafe68e30},
+ {0x00009804, 0xfd14e000},
+ {0x00009808, 0x9c0a8f6b},
+ {0x0000980c, 0x04800000},
+ {0x00009814, 0x9280c00a},
+ {0x00009818, 0x00000000},
+ {0x0000981c, 0x00020028},
+ {0x00009834, 0x5f3ca3de},
+ {0x00009838, 0x0108ecff},
+ {0x0000983c, 0x14750600},
+ {0x00009880, 0x201fff00},
+ {0x00009884, 0x00001042},
+ {0x000098a4, 0x00200400},
+ {0x000098b0, 0x52440bbe},
+ {0x000098bc, 0x00000002},
+ {0x000098d0, 0x004b6a8e},
+ {0x000098d4, 0x00000820},
+ {0x000098dc, 0x00000000},
+ {0x000098f0, 0x00000000},
+ {0x000098f4, 0x00000000},
+ {0x00009c04, 0x00000000},
+ {0x00009c08, 0x03200000},
+ {0x00009c0c, 0x00000000},
+ {0x00009c10, 0x00000000},
+ {0x00009c14, 0x00046384},
+ {0x00009c18, 0x05b6b440},
+ {0x00009c1c, 0x00b6b440},
+ {0x00009d00, 0xc080a333},
+ {0x00009d04, 0x40206c10},
+ {0x00009d08, 0x009c4060},
+ {0x00009d0c, 0x1883800a},
+ {0x00009d10, 0x01834061},
+ {0x00009d14, 0x00c00400},
+ {0x00009d18, 0x00000000},
+ {0x00009d1c, 0x00000000},
+ {0x00009e08, 0x0038233c},
+ {0x00009e24, 0x990bb515},
+ {0x00009e28, 0x0a6f0000},
+ {0x00009e30, 0x06336f77},
+ {0x00009e34, 0x6af6532f},
+ {0x00009e38, 0x0cc80c00},
+ {0x00009e40, 0x0d261820},
+ {0x00009e4c, 0x00001004},
+ {0x00009e50, 0x00ff03f1},
+ {0x00009fc0, 0x80be4788},
+ {0x00009fc4, 0x0001efb5},
+ {0x00009fcc, 0x40000014},
+ {0x0000a20c, 0x00000000},
+ {0x0000a210, 0x00000000},
+ {0x0000a220, 0x00000000},
+ {0x0000a224, 0x00000000},
+ {0x0000a228, 0x10002310},
+ {0x0000a23c, 0x00000000},
+ {0x0000a244, 0x0c000000},
+ {0x0000a2a0, 0x00000001},
+ {0x0000a2c0, 0x00000001},
+ {0x0000a2c8, 0x00000000},
+ {0x0000a2cc, 0x18c43433},
+ {0x0000a2d4, 0x00000000},
+ {0x0000a2dc, 0x00000000},
+ {0x0000a2e0, 0x00000000},
+ {0x0000a2e4, 0x00000000},
+ {0x0000a2e8, 0x00000000},
+ {0x0000a2ec, 0x00000000},
+ {0x0000a2f0, 0x00000000},
+ {0x0000a2f4, 0x00000000},
+ {0x0000a2f8, 0x00000000},
+ {0x0000a344, 0x00000000},
+ {0x0000a34c, 0x00000000},
+ {0x0000a350, 0x0000a000},
+ {0x0000a364, 0x00000000},
+ {0x0000a370, 0x00000000},
+ {0x0000a390, 0x00000001},
+ {0x0000a394, 0x00000444},
+ {0x0000a398, 0x001f0e0f},
+ {0x0000a39c, 0x0075393f},
+ {0x0000a3a0, 0xb79f6427},
+ {0x0000a3a4, 0x00000000},
+ {0x0000a3a8, 0xaaaaaaaa},
+ {0x0000a3ac, 0x3c466478},
+ {0x0000a3c0, 0x20202020},
+ {0x0000a3c4, 0x22222220},
+ {0x0000a3c8, 0x20200020},
+ {0x0000a3cc, 0x20202020},
+ {0x0000a3d0, 0x20202020},
+ {0x0000a3d4, 0x20202020},
+ {0x0000a3d8, 0x20202020},
+ {0x0000a3dc, 0x20202020},
+ {0x0000a3e0, 0x20202020},
+ {0x0000a3e4, 0x20202020},
+ {0x0000a3e8, 0x20202020},
+ {0x0000a3ec, 0x20202020},
+ {0x0000a3f0, 0x00000000},
+ {0x0000a3f4, 0x00000006},
+ {0x0000a3f8, 0x0cdbd380},
+ {0x0000a3fc, 0x000f0f01},
+ {0x0000a400, 0x8fa91f01},
+ {0x0000a404, 0x00000000},
+ {0x0000a408, 0x0e79e5c6},
+ {0x0000a40c, 0x00820820},
+ {0x0000a414, 0x1ce739ce},
+ {0x0000a418, 0x2d0011ce},
+ {0x0000a41c, 0x1ce739ce},
+ {0x0000a420, 0x000001ce},
+ {0x0000a424, 0x1ce739ce},
+ {0x0000a428, 0x000001ce},
+ {0x0000a42c, 0x1ce739ce},
+ {0x0000a430, 0x1ce739ce},
+ {0x0000a434, 0x00000000},
+ {0x0000a438, 0x00001801},
+ {0x0000a43c, 0x00000000},
+ {0x0000a440, 0x00000000},
+ {0x0000a444, 0x00000000},
+ {0x0000a448, 0x04000000},
+ {0x0000a44c, 0x00000001},
+ {0x0000a450, 0x00010000},
+ {0x0000a458, 0x00000000},
+ {0x0000a5c4, 0x3fad9d74},
+ {0x0000a5c8, 0x0048060a},
+ {0x0000a5cc, 0x00000637},
+ {0x0000a760, 0x03020100},
+ {0x0000a764, 0x09080504},
+ {0x0000a768, 0x0d0c0b0a},
+ {0x0000a76c, 0x13121110},
+ {0x0000a770, 0x31301514},
+ {0x0000a774, 0x35343332},
+ {0x0000a778, 0x00000036},
+ {0x0000a780, 0x00000838},
+ {0x0000a7c0, 0x00000000},
+ {0x0000a7c4, 0xfffffffc},
+ {0x0000a7c8, 0x00000000},
+ {0x0000a7cc, 0x00000000},
+ {0x0000a7d0, 0x00000000},
+ {0x0000a7d4, 0x00000004},
+ {0x0000a7dc, 0x00000001},
+};
+
+static const u32 ar9485Modes_high_ob_db_tx_gain_1_0[][5] = {
+ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
+ {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
+ {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000},
+ {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002},
+ {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004},
+ {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200},
+ {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202},
+ {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400},
+ {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402},
+ {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404},
+ {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603},
+ {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605},
+ {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03},
+ {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04},
+ {0x0000a530, 0x48023ec6, 0x48023ec6, 0x2e000a20, 0x2e000a20},
+ {0x0000a534, 0x4d023f01, 0x4d023f01, 0x34000e20, 0x34000e20},
+ {0x0000a538, 0x53023f4b, 0x53023f4b, 0x38000e22, 0x38000e22},
+ {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x3c000e24, 0x3c000e24},
+ {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x40000e26, 0x40000e26},
+ {0x0000a544, 0x6502feca, 0x6502feca, 0x43001640, 0x43001640},
+ {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x46001660, 0x46001660},
+ {0x0000a54c, 0x7203feca, 0x7203feca, 0x49001861, 0x49001861},
+ {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x4c001a81, 0x4c001a81},
+ {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x4f001a83, 0x4f001a83},
+ {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x54001c85, 0x54001c85},
+ {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x58001ce5, 0x58001ce5},
+ {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5b001ce9, 0x5b001ce9},
+ {0x0000a564, 0x960fffcb, 0x960fffcb, 0x60001eeb, 0x60001eeb},
+ {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x00016044, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db},
+};
+
+static const u32 ar9485Common_rx_gain_1_0[][2] = {
+ /* Addr allmodes */
+ {0x0000a000, 0x00010000},
+ {0x0000a004, 0x00030002},
+ {0x0000a008, 0x00050004},
+ {0x0000a00c, 0x00810080},
+ {0x0000a010, 0x01800082},
+ {0x0000a014, 0x01820181},
+ {0x0000a018, 0x01840183},
+ {0x0000a01c, 0x01880185},
+ {0x0000a020, 0x018a0189},
+ {0x0000a024, 0x02850284},
+ {0x0000a028, 0x02890288},
+ {0x0000a02c, 0x03850384},
+ {0x0000a030, 0x03890388},
+ {0x0000a034, 0x038b038a},
+ {0x0000a038, 0x038d038c},
+ {0x0000a03c, 0x03910390},
+ {0x0000a040, 0x03930392},
+ {0x0000a044, 0x03950394},
+ {0x0000a048, 0x00000396},
+ {0x0000a04c, 0x00000000},
+ {0x0000a050, 0x00000000},
+ {0x0000a054, 0x00000000},
+ {0x0000a058, 0x00000000},
+ {0x0000a05c, 0x00000000},
+ {0x0000a060, 0x00000000},
+ {0x0000a064, 0x00000000},
+ {0x0000a068, 0x00000000},
+ {0x0000a06c, 0x00000000},
+ {0x0000a070, 0x00000000},
+ {0x0000a074, 0x00000000},
+ {0x0000a078, 0x00000000},
+ {0x0000a07c, 0x00000000},
+ {0x0000a080, 0x28282828},
+ {0x0000a084, 0x28282828},
+ {0x0000a088, 0x28282828},
+ {0x0000a08c, 0x28282828},
+ {0x0000a090, 0x28282828},
+ {0x0000a094, 0x21212128},
+ {0x0000a098, 0x171c1c1c},
+ {0x0000a09c, 0x02020212},
+ {0x0000a0a0, 0x00000202},
+ {0x0000a0a4, 0x00000000},
+ {0x0000a0a8, 0x00000000},
+ {0x0000a0ac, 0x00000000},
+ {0x0000a0b0, 0x00000000},
+ {0x0000a0b4, 0x00000000},
+ {0x0000a0b8, 0x00000000},
+ {0x0000a0bc, 0x00000000},
+ {0x0000a0c0, 0x001f0000},
+ {0x0000a0c4, 0x111f1100},
+ {0x0000a0c8, 0x111d111e},
+ {0x0000a0cc, 0x111b111c},
+ {0x0000a0d0, 0x22032204},
+ {0x0000a0d4, 0x22012202},
+ {0x0000a0d8, 0x221f2200},
+ {0x0000a0dc, 0x221d221e},
+ {0x0000a0e0, 0x33013302},
+ {0x0000a0e4, 0x331f3300},
+ {0x0000a0e8, 0x4402331e},
+ {0x0000a0ec, 0x44004401},
+ {0x0000a0f0, 0x441e441f},
+ {0x0000a0f4, 0x55015502},
+ {0x0000a0f8, 0x551f5500},
+ {0x0000a0fc, 0x6602551e},
+ {0x0000a100, 0x66006601},
+ {0x0000a104, 0x661e661f},
+ {0x0000a108, 0x7703661d},
+ {0x0000a10c, 0x77017702},
+ {0x0000a110, 0x00007700},
+ {0x0000a114, 0x00000000},
+ {0x0000a118, 0x00000000},
+ {0x0000a11c, 0x00000000},
+ {0x0000a120, 0x00000000},
+ {0x0000a124, 0x00000000},
+ {0x0000a128, 0x00000000},
+ {0x0000a12c, 0x00000000},
+ {0x0000a130, 0x00000000},
+ {0x0000a134, 0x00000000},
+ {0x0000a138, 0x00000000},
+ {0x0000a13c, 0x00000000},
+ {0x0000a140, 0x001f0000},
+ {0x0000a144, 0x111f1100},
+ {0x0000a148, 0x111d111e},
+ {0x0000a14c, 0x111b111c},
+ {0x0000a150, 0x22032204},
+ {0x0000a154, 0x22012202},
+ {0x0000a158, 0x221f2200},
+ {0x0000a15c, 0x221d221e},
+ {0x0000a160, 0x33013302},
+ {0x0000a164, 0x331f3300},
+ {0x0000a168, 0x4402331e},
+ {0x0000a16c, 0x44004401},
+ {0x0000a170, 0x441e441f},
+ {0x0000a174, 0x55015502},
+ {0x0000a178, 0x551f5500},
+ {0x0000a17c, 0x6602551e},
+ {0x0000a180, 0x66006601},
+ {0x0000a184, 0x661e661f},
+ {0x0000a188, 0x7703661d},
+ {0x0000a18c, 0x77017702},
+ {0x0000a190, 0x00007700},
+ {0x0000a194, 0x00000000},
+ {0x0000a198, 0x00000000},
+ {0x0000a19c, 0x00000000},
+ {0x0000a1a0, 0x00000000},
+ {0x0000a1a4, 0x00000000},
+ {0x0000a1a8, 0x00000000},
+ {0x0000a1ac, 0x00000000},
+ {0x0000a1b0, 0x00000000},
+ {0x0000a1b4, 0x00000000},
+ {0x0000a1b8, 0x00000000},
+ {0x0000a1bc, 0x00000000},
+ {0x0000a1c0, 0x00000000},
+ {0x0000a1c4, 0x00000000},
+ {0x0000a1c8, 0x00000000},
+ {0x0000a1cc, 0x00000000},
+ {0x0000a1d0, 0x00000000},
+ {0x0000a1d4, 0x00000000},
+ {0x0000a1d8, 0x00000000},
+ {0x0000a1dc, 0x00000000},
+ {0x0000a1e0, 0x00000000},
+ {0x0000a1e4, 0x00000000},
+ {0x0000a1e8, 0x00000000},
+ {0x0000a1ec, 0x00000000},
+ {0x0000a1f0, 0x00000396},
+ {0x0000a1f4, 0x00000396},
+ {0x0000a1f8, 0x00000396},
+ {0x0000a1fc, 0x00000296},
+};
+
+static const u32 ar9485_1_0_pcie_phy_pll_on_clkreq_enable_L1[][2] = {
+ /* Addr allmodes */
+ {0x00018c00, 0x10252e5e},
+ {0x00018c04, 0x000801d8},
+ {0x00018c08, 0x0000580c},
+};
+
+static const u32 ar9485_1_0_pcie_phy_clkreq_enable_L1[][2] = {
+ /* Addr allmodes */
+ {0x00018c00, 0x10253e5e},
+ {0x00018c04, 0x000801d8},
+ {0x00018c08, 0x0000580c},
+};
+
+static const u32 ar9485_1_0_soc_preamble[][2] = {
+ /* Addr allmodes */
+ {0x000040a4, 0x00a0c9c9},
+ {0x00007048, 0x00000004},
+};
+
+static const u32 ar9485_fast_clock_1_0_baseband_postamble[][3] = {
+ /* Addr 5G_HT20 5G_HT40 */
+ {0x00009e00, 0x03721821, 0x03721821},
+ {0x0000a230, 0x0000400b, 0x00004016},
+ {0x0000a254, 0x00000898, 0x00001130},
+};
+
+static const u32 ar9485_1_0_baseband_postamble[][5] = {
+ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
+ {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a8005},
+ {0x00009820, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e},
+ {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0},
+ {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881},
+ {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
+ {0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x0000059c},
+ {0x00009c00, 0x00000044, 0x00000044, 0x00000044, 0x00000044},
+ {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0},
+ {0x00009e04, 0x00182020, 0x00182020, 0x00182020, 0x00182020},
+ {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2},
+ {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec80d2e, 0x7ec80d2e},
+ {0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e},
+ {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c},
+ {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce},
+ {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021},
+ {0x00009e3c, 0xcf946220, 0xcf946220, 0xcf946222, 0xcf946222},
+ {0x00009e44, 0x02321e27, 0x02321e27, 0x02282324, 0x02282324},
+ {0x00009e48, 0x5030201a, 0x5030201a, 0x50302010, 0x50302010},
+ {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000},
+ {0x0000a204, 0x01303fc0, 0x01303fc4, 0x01303fc4, 0x01303fc0},
+ {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004},
+ {0x0000a230, 0x0000400a, 0x00004014, 0x00004016, 0x0000400b},
+ {0x0000a234, 0x10000fff, 0x10000fff, 0x10000fff, 0x10000fff},
+ {0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018},
+ {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108},
+ {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898},
+ {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002},
+ {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e},
+ {0x0000a260, 0x3a021501, 0x3a021501, 0x3a021501, 0x3a021501},
+ {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e},
+ {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b},
+ {0x0000a284, 0x00000000, 0x00000000, 0x000002a0, 0x000002a0},
+ {0x0000a288, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x0000a28c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18},
+ {0x0000a2d0, 0x00071981, 0x00071981, 0x00071981, 0x00071982},
+ {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a},
+ {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x0000be04, 0x00802020, 0x00802020, 0x00802020, 0x00802020},
+ {0x0000be18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+};
+
+static const u32 ar9485Modes_low_ob_db_tx_gain_1_0[][5] = {
+ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
+ {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
+ {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000},
+ {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002},
+ {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004},
+ {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200},
+ {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202},
+ {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400},
+ {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402},
+ {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404},
+ {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603},
+ {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605},
+ {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03},
+ {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04},
+ {0x0000a530, 0x48023ec6, 0x48023ec6, 0x2e000a20, 0x2e000a20},
+ {0x0000a534, 0x4d023f01, 0x4d023f01, 0x34000e20, 0x34000e20},
+ {0x0000a538, 0x53023f4b, 0x53023f4b, 0x38000e22, 0x38000e22},
+ {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x3c000e24, 0x3c000e24},
+ {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x40000e26, 0x40000e26},
+ {0x0000a544, 0x6502feca, 0x6502feca, 0x43001640, 0x43001640},
+ {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x46001660, 0x46001660},
+ {0x0000a54c, 0x7203feca, 0x7203feca, 0x49001861, 0x49001861},
+ {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x4c001a81, 0x4c001a81},
+ {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x4f001a83, 0x4f001a83},
+ {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x54001c85, 0x54001c85},
+ {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x58001ce5, 0x58001ce5},
+ {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5b001ce9, 0x5b001ce9},
+ {0x0000a564, 0x960fffcb, 0x960fffcb, 0x60001eeb, 0x60001eeb},
+ {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
+ {0x00016044, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db},
+};
+
+static const u32 ar9485_1_0_pcie_phy_clkreq_disable_L1[][2] = {
+ /* Addr allmodes */
+ {0x00018c00, 0x10213e5e},
+ {0x00018c04, 0x000801d8},
+ {0x00018c08, 0x0000580c},
+};
+
+static const u32 ar9485_1_0_radio_postamble[][2] = {
+ /* Addr allmodes */
+ {0x0001609c, 0x0b283f31},
+ {0x000160ac, 0x24611800},
+ {0x000160b0, 0x03284f3e},
+ {0x0001610c, 0x00170000},
+ {0x00016140, 0x10804008},
+};
+
+static const u32 ar9485_1_0_mac_core[][2] = {
+ /* Addr allmodes */
+ {0x00000008, 0x00000000},
+ {0x00000030, 0x00020085},
+ {0x00000034, 0x00000005},
+ {0x00000040, 0x00000000},
+ {0x00000044, 0x00000000},
+ {0x00000048, 0x00000008},
+ {0x0000004c, 0x00000010},
+ {0x00000050, 0x00000000},
+ {0x00001040, 0x002ffc0f},
+ {0x00001044, 0x002ffc0f},
+ {0x00001048, 0x002ffc0f},
+ {0x0000104c, 0x002ffc0f},
+ {0x00001050, 0x002ffc0f},
+ {0x00001054, 0x002ffc0f},
+ {0x00001058, 0x002ffc0f},
+ {0x0000105c, 0x002ffc0f},
+ {0x00001060, 0x002ffc0f},
+ {0x00001064, 0x002ffc0f},
+ {0x000010f0, 0x00000100},
+ {0x00001270, 0x00000000},
+ {0x000012b0, 0x00000000},
+ {0x000012f0, 0x00000000},
+ {0x0000143c, 0x00000000},
+ {0x0000147c, 0x00000000},
+ {0x00008000, 0x00000000},
+ {0x00008004, 0x00000000},
+ {0x00008008, 0x00000000},
+ {0x0000800c, 0x00000000},
+ {0x00008018, 0x00000000},
+ {0x00008020, 0x00000000},
+ {0x00008038, 0x00000000},
+ {0x0000803c, 0x00000000},
+ {0x00008040, 0x00000000},
+ {0x00008044, 0x00000000},
+ {0x00008048, 0x00000000},
+ {0x0000804c, 0xffffffff},
+ {0x00008054, 0x00000000},
+ {0x00008058, 0x00000000},
+ {0x0000805c, 0x000fc78f},
+ {0x00008060, 0x0000000f},
+ {0x00008064, 0x00000000},
+ {0x00008070, 0x00000310},
+ {0x00008074, 0x00000020},
+ {0x00008078, 0x00000000},
+ {0x0000809c, 0x0000000f},
+ {0x000080a0, 0x00000000},
+ {0x000080a4, 0x02ff0000},
+ {0x000080a8, 0x0e070605},
+ {0x000080ac, 0x0000000d},
+ {0x000080b0, 0x00000000},
+ {0x000080b4, 0x00000000},
+ {0x000080b8, 0x00000000},
+ {0x000080bc, 0x00000000},
+ {0x000080c0, 0x2a800000},
+ {0x000080c4, 0x06900168},
+ {0x000080c8, 0x13881c20},
+ {0x000080cc, 0x01f40000},
+ {0x000080d0, 0x00252500},
+ {0x000080d4, 0x00a00000},
+ {0x000080d8, 0x00400000},
+ {0x000080dc, 0x00000000},
+ {0x000080e0, 0xffffffff},
+ {0x000080e4, 0x0000ffff},
+ {0x000080e8, 0x3f3f3f3f},
+ {0x000080ec, 0x00000000},
+ {0x000080f0, 0x00000000},
+ {0x000080f4, 0x00000000},
+ {0x000080fc, 0x00020000},
+ {0x00008100, 0x00000000},
+ {0x00008108, 0x00000052},
+ {0x0000810c, 0x00000000},
+ {0x00008110, 0x00000000},
+ {0x00008114, 0x000007ff},
+ {0x00008118, 0x000000aa},
+ {0x0000811c, 0x00003210},
+ {0x00008124, 0x00000000},
+ {0x00008128, 0x00000000},
+ {0x0000812c, 0x00000000},
+ {0x00008130, 0x00000000},
+ {0x00008134, 0x00000000},
+ {0x00008138, 0x00000000},
+ {0x0000813c, 0x0000ffff},
+ {0x00008144, 0xffffffff},
+ {0x00008168, 0x00000000},
+ {0x0000816c, 0x00000000},
+ {0x00008170, 0x18486200},
+ {0x00008174, 0x33332210},
+ {0x00008178, 0x00000000},
+ {0x0000817c, 0x00020000},
+ {0x000081c0, 0x00000000},
+ {0x000081c4, 0x33332210},
+ {0x000081c8, 0x00000000},
+ {0x000081cc, 0x00000000},
+ {0x000081d4, 0x00000000},
+ {0x000081ec, 0x00000000},
+ {0x000081f0, 0x00000000},
+ {0x000081f4, 0x00000000},
+ {0x000081f8, 0x00000000},
+ {0x000081fc, 0x00000000},
+ {0x00008240, 0x00100000},
+ {0x00008244, 0x0010f400},
+ {0x00008248, 0x00000800},
+ {0x0000824c, 0x0001e800},
+ {0x00008250, 0x00000000},
+ {0x00008254, 0x00000000},
+ {0x00008258, 0x00000000},
+ {0x0000825c, 0x40000000},
+ {0x00008260, 0x00080922},
+ {0x00008264, 0x9ca00010},
+ {0x00008268, 0xffffffff},
+ {0x0000826c, 0x0000ffff},
+ {0x00008270, 0x00000000},
+ {0x00008274, 0x40000000},
+ {0x00008278, 0x003e4180},
+ {0x0000827c, 0x00000004},
+ {0x00008284, 0x0000002c},
+ {0x00008288, 0x0000002c},
+ {0x0000828c, 0x000000ff},
+ {0x00008294, 0x00000000},
+ {0x00008298, 0x00000000},
+ {0x0000829c, 0x00000000},
+ {0x00008300, 0x00000140},
+ {0x00008314, 0x00000000},
+ {0x0000831c, 0x0000010d},
+ {0x00008328, 0x00000000},
+ {0x0000832c, 0x00000007},
+ {0x00008330, 0x00000302},
+ {0x00008334, 0x00000700},
+ {0x00008338, 0x00ff0000},
+ {0x0000833c, 0x02400000},
+ {0x00008340, 0x000107ff},
+ {0x00008344, 0xa248105b},
+ {0x00008348, 0x008f0000},
+ {0x0000835c, 0x00000000},
+ {0x00008360, 0xffffffff},
+ {0x00008364, 0xffffffff},
+ {0x00008368, 0x00000000},
+ {0x00008370, 0x00000000},
+ {0x00008374, 0x000000ff},
+ {0x00008378, 0x00000000},
+ {0x0000837c, 0x00000000},
+ {0x00008380, 0xffffffff},
+ {0x00008384, 0xffffffff},
+ {0x00008390, 0xffffffff},
+ {0x00008394, 0xffffffff},
+ {0x00008398, 0x00000000},
+ {0x0000839c, 0x00000000},
+ {0x000083a0, 0x00000000},
+ {0x000083a4, 0x0000fa14},
+ {0x000083a8, 0x000f0c00},
+ {0x000083ac, 0x33332210},
+ {0x000083b0, 0x33332210},
+ {0x000083b4, 0x33332210},
+ {0x000083b8, 0x33332210},
+ {0x000083bc, 0x00000000},
+ {0x000083c0, 0x00000000},
+ {0x000083c4, 0x00000000},
+ {0x000083c8, 0x00000000},
+ {0x000083cc, 0x00000200},
+ {0x000083d0, 0x000301ff},
+};
+#endif
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 0963071e8f90..9b5501f90010 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -87,33 +87,19 @@ struct ath_config {
/**
* enum buffer_type - Buffer type flags
*
- * @BUF_HT: Send this buffer using HT capabilities
* @BUF_AMPDU: This buffer is an ampdu, as part of an aggregate (during TX)
* @BUF_AGGR: Indicates whether the buffer can be aggregated
* (used in aggregation scheduling)
- * @BUF_RETRY: Indicates whether the buffer is retried
* @BUF_XRETRY: To denote excessive retries of the buffer
*/
enum buffer_type {
- BUF_HT = BIT(1),
BUF_AMPDU = BIT(2),
BUF_AGGR = BIT(3),
- BUF_RETRY = BIT(4),
BUF_XRETRY = BIT(5),
};
-#define bf_nframes bf_state.bfs_nframes
-#define bf_al bf_state.bfs_al
-#define bf_frmlen bf_state.bfs_frmlen
-#define bf_retries bf_state.bfs_retries
-#define bf_seqno bf_state.bfs_seqno
-#define bf_tidno bf_state.bfs_tidno
-#define bf_keyix bf_state.bfs_keyix
-#define bf_keytype bf_state.bfs_keytype
-#define bf_isht(bf) (bf->bf_state.bf_type & BUF_HT)
#define bf_isampdu(bf) (bf->bf_state.bf_type & BUF_AMPDU)
#define bf_isaggr(bf) (bf->bf_state.bf_type & BUF_AGGR)
-#define bf_isretried(bf) (bf->bf_state.bf_type & BUF_RETRY)
#define bf_isxretried(bf) (bf->bf_state.bf_type & BUF_XRETRY)
#define ATH_TXSTATUS_RING_SIZE 64
@@ -178,8 +164,8 @@ void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
/* returns delimiter padding required given the packet length */
#define ATH_AGGR_GET_NDELIM(_len) \
- (((((_len) + ATH_AGGR_DELIM_SZ) < ATH_AGGR_MINPLEN) ? \
- (ATH_AGGR_MINPLEN - (_len) - ATH_AGGR_DELIM_SZ) : 0) >> 2)
+ (((_len) >= ATH_AGGR_MINPLEN) ? 0 : \
+ DIV_ROUND_UP(ATH_AGGR_MINPLEN - (_len), ATH_AGGR_DELIM_SZ))
#define BAW_WITHIN(_start, _bawsz, _seqno) \
((((_seqno) - (_start)) & 4095) < (_bawsz))
@@ -196,7 +182,6 @@ enum ATH_AGGR_STATUS {
#define ATH_TXFIFO_DEPTH 8
struct ath_txq {
- int axq_class;
u32 axq_qnum;
u32 *axq_link;
struct list_head axq_q;
@@ -209,27 +194,28 @@ struct ath_txq {
struct list_head txq_fifo_pending;
u8 txq_headidx;
u8 txq_tailidx;
+ int pending_frames;
};
struct ath_atx_ac {
+ struct ath_txq *txq;
int sched;
- int qnum;
struct list_head list;
struct list_head tid_q;
};
+struct ath_frame_info {
+ int framelen;
+ u32 keyix;
+ enum ath9k_key_type keytype;
+ u8 retries;
+ u16 seqno;
+};
+
struct ath_buf_state {
- int bfs_nframes;
- u16 bfs_al;
- u16 bfs_frmlen;
- int bfs_seqno;
- int bfs_tidno;
- int bfs_retries;
u8 bf_type;
u8 bfs_paprd;
- unsigned long bfs_paprd_timestamp;
- u32 bfs_keyix;
- enum ath9k_key_type bfs_keytype;
+ enum ath9k_internal_frame_type bfs_ftype;
};
struct ath_buf {
@@ -242,7 +228,6 @@ struct ath_buf {
dma_addr_t bf_daddr; /* physical addr of desc */
dma_addr_t bf_buf_addr; /* physical addr of data buffer, for DMA */
bool bf_stale;
- bool bf_tx_aborted;
u16 bf_flags;
struct ath_buf_state bf_state;
struct ath_wiphy *aphy;
@@ -271,7 +256,6 @@ struct ath_node {
struct ath_atx_ac ac[WME_NUM_AC];
u16 maxampdu;
u8 mpdudensity;
- int last_rssi;
};
#define AGGR_CLEANUP BIT(1)
@@ -280,6 +264,7 @@ struct ath_node {
struct ath_tx_control {
struct ath_txq *txq;
+ struct ath_node *an;
int if_id;
enum ath9k_internal_frame_type frame_type;
u8 paprd;
@@ -292,12 +277,11 @@ struct ath_tx_control {
struct ath_tx {
u16 seq_no;
u32 txqsetup;
- int hwq_map[WME_NUM_AC];
spinlock_t txbuflock;
struct list_head txbuf;
struct ath_txq txq[ATH9K_NUM_TX_QUEUES];
struct ath_descdma txdma;
- int pending_frames[WME_NUM_AC];
+ struct ath_txq *txq_map[WME_NUM_AC];
};
struct ath_rx_edma {
@@ -311,7 +295,6 @@ struct ath_rx {
u8 rxotherant;
u32 *rxlink;
unsigned int rxfilter;
- spinlock_t pcu_lock;
spinlock_t rxbuflock;
struct list_head rxbuf;
struct ath_descdma rxdma;
@@ -328,7 +311,6 @@ void ath_rx_cleanup(struct ath_softc *sc);
int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp);
struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype);
void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq);
-int ath_tx_setup(struct ath_softc *sc, int haltype);
bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx);
void ath_draintxq(struct ath_softc *sc,
struct ath_txq *txq, bool retry_tx);
@@ -343,7 +325,6 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
struct ath_tx_control *txctl);
void ath_tx_tasklet(struct ath_softc *sc);
void ath_tx_edma_tasklet(struct ath_softc *sc);
-void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb);
int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
u16 tid, u16 *ssn);
void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
@@ -564,6 +545,7 @@ struct ath_ant_comb {
#define SC_OP_BT_PRIORITY_DETECTED BIT(12)
#define SC_OP_BT_SCAN BIT(13)
#define SC_OP_ANI_RUN BIT(14)
+#define SC_OP_ENABLE_APM BIT(15)
/* Powersave flags */
#define PS_WAIT_FOR_BEACON BIT(0)
@@ -601,13 +583,14 @@ struct ath_softc {
struct ath_hw *sc_ah;
void __iomem *mem;
int irq;
- spinlock_t sc_resetlock;
spinlock_t sc_serial_rw;
spinlock_t sc_pm_lock;
+ spinlock_t sc_pcu_lock;
struct mutex mutex;
struct work_struct paprd_work;
struct work_struct hw_check_work;
struct completion paprd_complete;
+ bool paprd_pending;
u32 intrstatus;
u32 sc_flags; /* SC_OP_* */
@@ -665,11 +648,11 @@ struct ath_wiphy {
bool idle;
int chan_idx;
int chan_is_ht;
+ int last_rssi;
};
void ath9k_tasklet(unsigned long data);
int ath_reset(struct ath_softc *sc, bool retry_tx);
-int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc);
int ath_cabq_update(struct ath_softc *);
static inline void ath_read_cachesize(struct ath_common *common, int *csz)
@@ -715,10 +698,12 @@ static inline void ath_ahb_exit(void) {};
void ath9k_ps_wakeup(struct ath_softc *sc);
void ath9k_ps_restore(struct ath_softc *sc);
+u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate);
+
void ath9k_set_bssid_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
int ath9k_wiphy_add(struct ath_softc *sc);
int ath9k_wiphy_del(struct ath_wiphy *aphy);
-void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb);
+void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, int ftype);
int ath9k_wiphy_pause(struct ath_wiphy *aphy);
int ath9k_wiphy_unpause(struct ath_wiphy *aphy);
int ath9k_wiphy_select(struct ath_wiphy *aphy);
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index 19891e7d49ae..5e108c086904 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -28,7 +28,7 @@ int ath_beaconq_config(struct ath_softc *sc)
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
struct ath9k_tx_queue_info qi, qi_be;
- int qnum;
+ struct ath_txq *txq;
ath9k_hw_get_txq_props(ah, sc->beacon.beaconq, &qi);
if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) {
@@ -38,16 +38,16 @@ int ath_beaconq_config(struct ath_softc *sc)
qi.tqi_cwmax = 0;
} else {
/* Adhoc mode; important thing is to use 2x cwmin. */
- qnum = sc->tx.hwq_map[WME_AC_BE];
- ath9k_hw_get_txq_props(ah, qnum, &qi_be);
+ txq = sc->tx.txq_map[WME_AC_BE];
+ ath9k_hw_get_txq_props(ah, txq->axq_qnum, &qi_be);
qi.tqi_aifs = qi_be.tqi_aifs;
qi.tqi_cwmin = 4*qi_be.tqi_cwmin;
qi.tqi_cwmax = qi_be.tqi_cwmax;
}
if (!ath9k_hw_set_txq_props(ah, sc->beacon.beaconq, &qi)) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to update h/w beacon queue parameters\n");
+ ath_err(common,
+ "Unable to update h/w beacon queue parameters\n");
return 0;
} else {
ath9k_hw_resettxqueue(ah, sc->beacon.beaconq);
@@ -103,12 +103,32 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
series[0].Tries = 1;
series[0].Rate = rate;
- series[0].ChSel = common->tx_chainmask;
+ series[0].ChSel = ath_txchainmask_reduction(sc,
+ common->tx_chainmask, series[0].Rate);
series[0].RateFlags = (ctsrate) ? ATH9K_RATESERIES_RTS_CTS : 0;
ath9k_hw_set11n_ratescenario(ah, ds, ds, 0, ctsrate, ctsduration,
series, 4, 0);
}
+static void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+ struct ath_tx_control txctl;
+
+ memset(&txctl, 0, sizeof(struct ath_tx_control));
+ txctl.txq = sc->beacon.cabq;
+
+ ath_dbg(common, ATH_DBG_XMIT,
+ "transmitting CABQ packet, skb: %p\n", skb);
+
+ if (ath_tx_start(hw, skb, &txctl) != 0) {
+ ath_dbg(common, ATH_DBG_XMIT, "CABQ TX failed\n");
+ dev_kfree_skb_any(skb);
+ }
+}
+
static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
@@ -169,8 +189,7 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL;
bf->bf_buf_addr = 0;
- ath_print(common, ATH_DBG_FATAL,
- "dma_mapping_error on beaconing\n");
+ ath_err(common, "dma_mapping_error on beaconing\n");
return NULL;
}
@@ -190,8 +209,8 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
if (skb && cabq_depth) {
if (sc->nvifs > 1) {
- ath_print(common, ATH_DBG_BEACON,
- "Flushing previous cabq traffic\n");
+ ath_dbg(common, ATH_DBG_BEACON,
+ "Flushing previous cabq traffic\n");
ath_draintxq(sc, cabq, false);
}
}
@@ -263,7 +282,7 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
/* NB: the beacon data buffer must be 32-bit aligned. */
skb = ieee80211_beacon_get(sc->hw, vif);
if (skb == NULL) {
- ath_print(common, ATH_DBG_BEACON, "cannot get skb\n");
+ ath_dbg(common, ATH_DBG_BEACON, "cannot get skb\n");
return -ENOMEM;
}
@@ -287,10 +306,9 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
tsfadjust = intval * avp->av_bslot / ATH_BCBUF;
avp->tsf_adjust = cpu_to_le64(TU_TO_USEC(tsfadjust));
- ath_print(common, ATH_DBG_BEACON,
- "stagger beacons, bslot %d intval "
- "%u tsfadjust %llu\n",
- avp->av_bslot, intval, (unsigned long long)tsfadjust);
+ ath_dbg(common, ATH_DBG_BEACON,
+ "stagger beacons, bslot %d intval %u tsfadjust %llu\n",
+ avp->av_bslot, intval, (unsigned long long)tsfadjust);
((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp =
avp->tsf_adjust;
@@ -304,8 +322,7 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL;
bf->bf_buf_addr = 0;
- ath_print(common, ATH_DBG_FATAL,
- "dma_mapping_error on beacon alloc\n");
+ ath_err(common, "dma_mapping_error on beacon alloc\n");
return -ENOMEM;
}
@@ -362,13 +379,13 @@ void ath_beacon_tasklet(unsigned long data)
sc->beacon.bmisscnt++;
if (sc->beacon.bmisscnt < BSTUCK_THRESH) {
- ath_print(common, ATH_DBG_BSTUCK,
- "missed %u consecutive beacons\n",
- sc->beacon.bmisscnt);
+ ath_dbg(common, ATH_DBG_BSTUCK,
+ "missed %u consecutive beacons\n",
+ sc->beacon.bmisscnt);
ath9k_hw_bstuck_nfcal(ah);
} else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) {
- ath_print(common, ATH_DBG_BSTUCK,
- "beacon is officially stuck\n");
+ ath_dbg(common, ATH_DBG_BSTUCK,
+ "beacon is officially stuck\n");
sc->sc_flags |= SC_OP_TSF_RESET;
ath_reset(sc, true);
}
@@ -377,9 +394,9 @@ void ath_beacon_tasklet(unsigned long data)
}
if (sc->beacon.bmisscnt != 0) {
- ath_print(common, ATH_DBG_BSTUCK,
- "resume beacon xmit after %u misses\n",
- sc->beacon.bmisscnt);
+ ath_dbg(common, ATH_DBG_BSTUCK,
+ "resume beacon xmit after %u misses\n",
+ sc->beacon.bmisscnt);
sc->beacon.bmisscnt = 0;
}
@@ -405,9 +422,9 @@ void ath_beacon_tasklet(unsigned long data)
vif = sc->beacon.bslot[slot];
aphy = sc->beacon.bslot_aphy[slot];
- ath_print(common, ATH_DBG_BEACON,
- "slot %d [tsf %llu tsftu %u intval %u] vif %p\n",
- slot, tsf, tsftu, intval, vif);
+ ath_dbg(common, ATH_DBG_BEACON,
+ "slot %d [tsf %llu tsftu %u intval %u] vif %p\n",
+ slot, tsf, tsftu, intval, vif);
bfaddr = 0;
if (vif) {
@@ -449,8 +466,8 @@ void ath_beacon_tasklet(unsigned long data)
* are still pending on the queue.
*/
if (!ath9k_hw_stoptxdma(ah, sc->beacon.beaconq)) {
- ath_print(common, ATH_DBG_FATAL,
- "beacon queue %u did not stop?\n", sc->beacon.beaconq);
+ ath_err(common, "beacon queue %u did not stop?\n",
+ sc->beacon.beaconq);
}
/* NB: cabq traffic should already be queued and primed */
@@ -503,7 +520,7 @@ static void ath_beacon_config_ap(struct ath_softc *sc,
/* Set the computed AP beacon timers */
- ath9k_hw_set_interrupts(ah, 0);
+ ath9k_hw_disable_interrupts(ah);
ath9k_beacon_init(sc, nexttbtt, intval);
sc->beacon.bmisscnt = 0;
ath9k_hw_set_interrupts(ah, ah->imask);
@@ -536,8 +553,8 @@ static void ath_beacon_config_sta(struct ath_softc *sc,
/* No need to configure beacon if we are not associated */
if (!common->curaid) {
- ath_print(common, ATH_DBG_BEACON,
- "STA is not yet associated..skipping beacon config\n");
+ ath_dbg(common, ATH_DBG_BEACON,
+ "STA is not yet associated..skipping beacon config\n");
return;
}
@@ -630,15 +647,15 @@ static void ath_beacon_config_sta(struct ath_softc *sc,
/* TSF out of range threshold fixed at 1 second */
bs.bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD;
- ath_print(common, ATH_DBG_BEACON, "tsf: %llu tsftu: %u\n", tsf, tsftu);
- ath_print(common, ATH_DBG_BEACON,
- "bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n",
- bs.bs_bmissthreshold, bs.bs_sleepduration,
- bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext);
+ ath_dbg(common, ATH_DBG_BEACON, "tsf: %llu tsftu: %u\n", tsf, tsftu);
+ ath_dbg(common, ATH_DBG_BEACON,
+ "bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n",
+ bs.bs_bmissthreshold, bs.bs_sleepduration,
+ bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext);
/* Set the computed STA beacon timers */
- ath9k_hw_set_interrupts(ah, 0);
+ ath9k_hw_disable_interrupts(ah);
ath9k_hw_set_sta_beacon_timers(ah, &bs);
ah->imask |= ATH9K_INT_BMISS;
ath9k_hw_set_interrupts(ah, ah->imask);
@@ -670,9 +687,9 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
nexttbtt += intval;
} while (nexttbtt < tsftu);
- ath_print(common, ATH_DBG_BEACON,
- "IBSS nexttbtt %u intval %u (%u)\n",
- nexttbtt, intval, conf->beacon_interval);
+ ath_dbg(common, ATH_DBG_BEACON,
+ "IBSS nexttbtt %u intval %u (%u)\n",
+ nexttbtt, intval, conf->beacon_interval);
/*
* In IBSS mode enable the beacon timers but only enable SWBA interrupts
@@ -686,7 +703,7 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
/* Set the computed ADHOC beacon timers */
- ath9k_hw_set_interrupts(ah, 0);
+ ath9k_hw_disable_interrupts(ah);
ath9k_beacon_init(sc, nexttbtt, intval);
sc->beacon.bmisscnt = 0;
ath9k_hw_set_interrupts(ah, ah->imask);
@@ -735,8 +752,8 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
ath_beacon_config_sta(sc, cur_conf);
break;
default:
- ath_print(common, ATH_DBG_CONFIG,
- "Unsupported beaconing mode\n");
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "Unsupported beaconing mode\n");
return;
}
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c
index 6a92e57fddf0..d33bf204c995 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.c
+++ b/drivers/net/wireless/ath/ath9k/btcoex.c
@@ -35,29 +35,6 @@ struct ath_btcoex_config {
bool bt_hold_rx_clear;
};
-static const u16 ath_subsysid_tbl[] = {
- AR9280_COEX2WIRE_SUBSYSID,
- AT9285_COEX3WIRE_SA_SUBSYSID,
- AT9285_COEX3WIRE_DA_SUBSYSID
-};
-
-/*
- * Checks the subsystem id of the device to see if it
- * supports btcoex
- */
-bool ath9k_hw_btcoex_supported(struct ath_hw *ah)
-{
- int i;
-
- if (!ah->hw_version.subsysid)
- return false;
-
- for (i = 0; i < ARRAY_SIZE(ath_subsysid_tbl); i++)
- if (ah->hw_version.subsysid == ath_subsysid_tbl[i])
- return true;
-
- return false;
-}
void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum)
{
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.h b/drivers/net/wireless/ath/ath9k/btcoex.h
index 1ee5a15ccbb1..588dfd464dd1 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.h
+++ b/drivers/net/wireless/ath/ath9k/btcoex.h
@@ -49,7 +49,6 @@ struct ath_btcoex_hw {
u32 bt_coex_mode2; /* Register setting for AR_BT_COEX_MODE2 */
};
-bool ath9k_hw_btcoex_supported(struct ath_hw *ah);
void ath9k_hw_btcoex_init_2wire(struct ath_hw *ah);
void ath9k_hw_btcoex_init_3wire(struct ath_hw *ah);
void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum);
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index 6d509484b5f6..b68a1acbddd0 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -97,12 +97,12 @@ static void ath9k_hw_update_nfcal_hist_buffer(struct ath_hw *ah,
if (h[i].privNF > limit->max) {
high_nf_mid = true;
- ath_print(common, ATH_DBG_CALIBRATE,
- "NFmid[%d] (%d) > MAX (%d), %s\n",
- i, h[i].privNF, limit->max,
- (cal->nfcal_interference ?
- "not corrected (due to interference)" :
- "correcting to MAX"));
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "NFmid[%d] (%d) > MAX (%d), %s\n",
+ i, h[i].privNF, limit->max,
+ (cal->nfcal_interference ?
+ "not corrected (due to interference)" :
+ "correcting to MAX"));
/*
* Normally we limit the average noise floor by the
@@ -180,18 +180,18 @@ bool ath9k_hw_reset_calvalid(struct ath_hw *ah)
return true;
if (currCal->calState != CAL_DONE) {
- ath_print(common, ATH_DBG_CALIBRATE,
- "Calibration state incorrect, %d\n",
- currCal->calState);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Calibration state incorrect, %d\n",
+ currCal->calState);
return true;
}
if (!(ah->supp_cals & currCal->calData->calType))
return true;
- ath_print(common, ATH_DBG_CALIBRATE,
- "Resetting Cal %d state for channel %u\n",
- currCal->calData->calType, conf->channel->center_freq);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Resetting Cal %d state for channel %u\n",
+ currCal->calData->calType, conf->channel->center_freq);
ah->caldata->CalValid &= ~currCal->calData->calType;
currCal->calState = CAL_WAITING;
@@ -279,9 +279,9 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
* noisefloor until the next calibration timer.
*/
if (j == 1000) {
- ath_print(common, ATH_DBG_ANY, "Timeout while waiting for nf "
- "to load: AR_PHY_AGC_CONTROL=0x%x\n",
- REG_READ(ah, AR_PHY_AGC_CONTROL));
+ ath_dbg(common, ATH_DBG_ANY,
+ "Timeout while waiting for nf to load: AR_PHY_AGC_CONTROL=0x%x\n",
+ REG_READ(ah, AR_PHY_AGC_CONTROL));
return;
}
@@ -318,19 +318,19 @@ static void ath9k_hw_nf_sanitize(struct ath_hw *ah, s16 *nf)
if (!nf[i])
continue;
- ath_print(common, ATH_DBG_CALIBRATE,
- "NF calibrated [%s] [chain %d] is %d\n",
- (i >= 3 ? "ext" : "ctl"), i % 3, nf[i]);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "NF calibrated [%s] [chain %d] is %d\n",
+ (i >= 3 ? "ext" : "ctl"), i % 3, nf[i]);
if (nf[i] > ATH9K_NF_TOO_HIGH) {
- ath_print(common, ATH_DBG_CALIBRATE,
- "NF[%d] (%d) > MAX (%d), correcting to MAX",
- i, nf[i], ATH9K_NF_TOO_HIGH);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "NF[%d] (%d) > MAX (%d), correcting to MAX\n",
+ i, nf[i], ATH9K_NF_TOO_HIGH);
nf[i] = limit->max;
} else if (nf[i] < limit->min) {
- ath_print(common, ATH_DBG_CALIBRATE,
- "NF[%d] (%d) < MIN (%d), correcting to NOM",
- i, nf[i], limit->min);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "NF[%d] (%d) < MIN (%d), correcting to NOM\n",
+ i, nf[i], limit->min);
nf[i] = limit->nominal;
}
}
@@ -347,8 +347,8 @@ bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan)
chan->channelFlags &= (~CHANNEL_CW_INT);
if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
- ath_print(common, ATH_DBG_CALIBRATE,
- "NF did not complete in calibration window\n");
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "NF did not complete in calibration window\n");
return false;
}
@@ -357,10 +357,9 @@ bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan)
nf = nfarray[0];
if (ath9k_hw_get_nf_thresh(ah, c->band, &nfThresh)
&& nf > nfThresh) {
- ath_print(common, ATH_DBG_CALIBRATE,
- "noise floor failed detected; "
- "detected %d, threshold %d\n",
- nf, nfThresh);
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "noise floor failed detected; detected %d, threshold %d\n",
+ nf, nfThresh);
chan->channelFlags |= CHANNEL_CW_INT;
}
diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c
index f43a2d98421c..df1998d48253 100644
--- a/drivers/net/wireless/ath/ath9k/common.c
+++ b/drivers/net/wireless/ath/ath9k/common.c
@@ -107,12 +107,10 @@ static u32 ath9k_get_extchanmode(struct ieee80211_channel *chan,
/*
* Update internal channel flags.
*/
-void ath9k_cmn_update_ichannel(struct ieee80211_hw *hw,
- struct ath9k_channel *ichan)
+void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan,
+ struct ieee80211_channel *chan,
+ enum nl80211_channel_type channel_type)
{
- struct ieee80211_channel *chan = hw->conf.channel;
- struct ieee80211_conf *conf = &hw->conf;
-
ichan->channel = chan->center_freq;
ichan->chan = chan;
@@ -124,9 +122,8 @@ void ath9k_cmn_update_ichannel(struct ieee80211_hw *hw,
ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM;
}
- if (conf_is_ht(conf))
- ichan->chanmode = ath9k_get_extchanmode(chan,
- conf->channel_type);
+ if (channel_type != NL80211_CHAN_NO_HT)
+ ichan->chanmode = ath9k_get_extchanmode(chan, channel_type);
}
EXPORT_SYMBOL(ath9k_cmn_update_ichannel);
@@ -142,7 +139,7 @@ struct ath9k_channel *ath9k_cmn_get_curchannel(struct ieee80211_hw *hw,
chan_idx = curchan->hw_value;
channel = &ah->channels[chan_idx];
- ath9k_cmn_update_ichannel(hw, channel);
+ ath9k_cmn_update_ichannel(channel, curchan, hw->conf.channel_type);
return channel;
}
@@ -183,8 +180,8 @@ void ath9k_cmn_btcoex_bt_stomp(struct ath_common *common,
AR_STOMP_NONE_WLAN_WGHT);
break;
default:
- ath_print(common, ATH_DBG_BTCOEX,
- "Invalid Stomptype\n");
+ ath_dbg(common, ATH_DBG_BTCOEX,
+ "Invalid Stomptype\n");
break;
}
diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h
index fea3b3315391..a126bddebb0a 100644
--- a/drivers/net/wireless/ath/ath9k/common.h
+++ b/drivers/net/wireless/ath/ath9k/common.h
@@ -17,7 +17,6 @@
#include <net/mac80211.h>
#include "../ath.h"
-#include "../debug.h"
#include "hw.h"
#include "hw-ops.h"
@@ -31,10 +30,11 @@
#define WME_MAX_BA WME_BA_BMP_SIZE
#define ATH_TID_MAX_BUFS (2 * WME_MAX_BA)
-#define WME_AC_BE 0
-#define WME_AC_BK 1
-#define WME_AC_VI 2
-#define WME_AC_VO 3
+/* These must match mac80211 skb queue mapping numbers */
+#define WME_AC_VO 0
+#define WME_AC_VI 1
+#define WME_AC_BE 2
+#define WME_AC_BK 3
#define WME_NUM_AC 4
#define ATH_RSSI_DUMMY_MARKER 0x127
@@ -62,8 +62,9 @@ enum ath_stomp_type {
int ath9k_cmn_padpos(__le16 frame_control);
int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb);
-void ath9k_cmn_update_ichannel(struct ieee80211_hw *hw,
- struct ath9k_channel *ichan);
+void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan,
+ struct ieee80211_channel *chan,
+ enum nl80211_channel_type channel_type);
struct ath9k_channel *ath9k_cmn_get_curchannel(struct ieee80211_hw *hw,
struct ath_hw *ah);
int ath9k_cmn_count_streams(unsigned int chainmask, int max);
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 43e71a944cb1..3586c43077a7 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -24,8 +24,6 @@
#define REG_READ_D(_ah, _reg) \
ath9k_hw_common(_ah)->ops->read((_ah), (_reg))
-static struct dentry *ath9k_debugfs_root;
-
static int ath9k_debugfs_open(struct inode *inode, struct file *file)
{
file->private_data = inode->i_private;
@@ -461,16 +459,16 @@ static ssize_t read_file_wiphy(struct file *file, char __user *user_buf,
/* Put variable-length stuff down here, and check for overflows. */
for (i = 0; i < sc->num_sec_wiphy; i++) {
- struct ath_wiphy *aphy = sc->sec_wiphy[i];
- if (aphy == NULL)
+ struct ath_wiphy *aphy_tmp = sc->sec_wiphy[i];
+ if (aphy_tmp == NULL)
continue;
- chan = aphy->hw->conf.channel;
+ chan = aphy_tmp->hw->conf.channel;
len += snprintf(buf + len, sizeof(buf) - len,
"secondary: %s (%s chan=%d ht=%d)\n",
- wiphy_name(aphy->hw->wiphy),
- ath_wiphy_state_str(aphy->state),
+ wiphy_name(aphy_tmp->hw->wiphy),
+ ath_wiphy_state_str(aphy_tmp->state),
ieee80211_frequency_to_channel(chan->center_freq),
- aphy->chan_is_ht);
+ aphy_tmp->chan_is_ht);
}
if (len > sizeof(buf))
len = sizeof(buf);
@@ -585,10 +583,10 @@ static const struct file_operations fops_wiphy = {
do { \
len += snprintf(buf + len, size - len, \
"%s%13u%11u%10u%10u\n", str, \
- sc->debug.stats.txstats[sc->tx.hwq_map[WME_AC_BE]].elem, \
- sc->debug.stats.txstats[sc->tx.hwq_map[WME_AC_BK]].elem, \
- sc->debug.stats.txstats[sc->tx.hwq_map[WME_AC_VI]].elem, \
- sc->debug.stats.txstats[sc->tx.hwq_map[WME_AC_VO]].elem); \
+ sc->debug.stats.txstats[WME_AC_BE].elem, \
+ sc->debug.stats.txstats[WME_AC_BK].elem, \
+ sc->debug.stats.txstats[WME_AC_VI].elem, \
+ sc->debug.stats.txstats[WME_AC_VO].elem); \
} while(0)
static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
@@ -630,33 +628,35 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
return retval;
}
-void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq,
- struct ath_buf *bf, struct ath_tx_status *ts)
+void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf,
+ struct ath_tx_status *ts)
{
- TX_STAT_INC(txq->axq_qnum, tx_pkts_all);
- sc->debug.stats.txstats[txq->axq_qnum].tx_bytes_all += bf->bf_mpdu->len;
+ int qnum = skb_get_queue_mapping(bf->bf_mpdu);
+
+ TX_STAT_INC(qnum, tx_pkts_all);
+ sc->debug.stats.txstats[qnum].tx_bytes_all += bf->bf_mpdu->len;
if (bf_isampdu(bf)) {
if (bf_isxretried(bf))
- TX_STAT_INC(txq->axq_qnum, a_xretries);
+ TX_STAT_INC(qnum, a_xretries);
else
- TX_STAT_INC(txq->axq_qnum, a_completed);
+ TX_STAT_INC(qnum, a_completed);
} else {
- TX_STAT_INC(txq->axq_qnum, completed);
+ TX_STAT_INC(qnum, completed);
}
if (ts->ts_status & ATH9K_TXERR_FIFO)
- TX_STAT_INC(txq->axq_qnum, fifo_underrun);
+ TX_STAT_INC(qnum, fifo_underrun);
if (ts->ts_status & ATH9K_TXERR_XTXOP)
- TX_STAT_INC(txq->axq_qnum, xtxop);
+ TX_STAT_INC(qnum, xtxop);
if (ts->ts_status & ATH9K_TXERR_TIMER_EXPIRED)
- TX_STAT_INC(txq->axq_qnum, timer_exp);
+ TX_STAT_INC(qnum, timer_exp);
if (ts->ts_flags & ATH9K_TX_DESC_CFG_ERR)
- TX_STAT_INC(txq->axq_qnum, desc_cfg_err);
+ TX_STAT_INC(qnum, desc_cfg_err);
if (ts->ts_flags & ATH9K_TX_DATA_UNDERRUN)
- TX_STAT_INC(txq->axq_qnum, data_underrun);
+ TX_STAT_INC(qnum, data_underrun);
if (ts->ts_flags & ATH9K_TX_DELIM_UNDERRUN)
- TX_STAT_INC(txq->axq_qnum, delim_underrun);
+ TX_STAT_INC(qnum, delim_underrun);
}
static const struct file_operations fops_xmit = {
@@ -876,11 +876,8 @@ int ath9k_init_debug(struct ath_hw *ah)
struct ath_common *common = ath9k_hw_common(ah);
struct ath_softc *sc = (struct ath_softc *) common->priv;
- if (!ath9k_debugfs_root)
- return -ENOENT;
-
- sc->debug.debugfs_phy = debugfs_create_dir(wiphy_name(sc->hw->wiphy),
- ath9k_debugfs_root);
+ sc->debug.debugfs_phy = debugfs_create_dir("ath9k",
+ sc->hw->wiphy->debugfsdir);
if (!sc->debug.debugfs_phy)
return -ENOMEM;
@@ -933,29 +930,7 @@ int ath9k_init_debug(struct ath_hw *ah)
sc->debug.regidx = 0;
return 0;
err:
- ath9k_exit_debug(ah);
- return -ENOMEM;
-}
-
-void ath9k_exit_debug(struct ath_hw *ah)
-{
- struct ath_common *common = ath9k_hw_common(ah);
- struct ath_softc *sc = (struct ath_softc *) common->priv;
-
debugfs_remove_recursive(sc->debug.debugfs_phy);
-}
-
-int ath9k_debug_create_root(void)
-{
- ath9k_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
- if (!ath9k_debugfs_root)
- return -ENOENT;
-
- return 0;
-}
-
-void ath9k_debug_remove_root(void)
-{
- debugfs_remove(ath9k_debugfs_root);
- ath9k_debugfs_root = NULL;
+ sc->debug.debugfs_phy = NULL;
+ return -ENOMEM;
}
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index bb0823242ba0..1e5078bd0344 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -164,13 +164,10 @@ struct ath9k_debug {
};
int ath9k_init_debug(struct ath_hw *ah);
-void ath9k_exit_debug(struct ath_hw *ah);
-int ath9k_debug_create_root(void);
-void ath9k_debug_remove_root(void);
void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
-void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq,
- struct ath_buf *bf, struct ath_tx_status *ts);
+void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf,
+ struct ath_tx_status *ts);
void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs);
#else
@@ -180,26 +177,12 @@ static inline int ath9k_init_debug(struct ath_hw *ah)
return 0;
}
-static inline void ath9k_exit_debug(struct ath_hw *ah)
-{
-}
-
-static inline int ath9k_debug_create_root(void)
-{
- return 0;
-}
-
-static inline void ath9k_debug_remove_root(void)
-{
-}
-
static inline void ath_debug_stat_interrupt(struct ath_softc *sc,
enum ath9k_int status)
{
}
static inline void ath_debug_stat_tx(struct ath_softc *sc,
- struct ath_txq *txq,
struct ath_buf *bf,
struct ath_tx_status *ts)
{
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c
index 2bbf94d0191e..fda533cfd881 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom.c
@@ -273,8 +273,8 @@ void ath9k_hw_update_regulatory_maxpower(struct ath_hw *ah)
regulatory->max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN;
break;
default:
- ath_print(common, ATH_DBG_EEPROM,
- "Invalid chainmask configuration\n");
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "Invalid chainmask configuration\n");
break;
}
}
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h
index dd59f09441a3..8b9885b5243f 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/eeprom.h
@@ -280,6 +280,7 @@ enum eeprom_param {
EEP_PAPRD,
EEP_MODAL_VER,
EEP_ANT_DIV_CTL1,
+ EEP_CHAIN_MASK_REDUCE
};
enum ar5416_rates {
@@ -681,7 +682,8 @@ struct eeprom_ops {
void (*set_addac)(struct ath_hw *hw, struct ath9k_channel *chan);
void (*set_txpower)(struct ath_hw *hw, struct ath9k_channel *chan,
u16 cfgCtl, u8 twiceAntennaReduction,
- u8 twiceMaxRegulatoryPower, u8 powerLimit);
+ u8 twiceMaxRegulatoryPower, u8 powerLimit,
+ bool test);
u16 (*get_spur_channel)(struct ath_hw *ah, u16 i, bool is2GHz);
};
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
index 4fa4d8e28c64..939fc7af86f8 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
@@ -37,14 +37,14 @@ static bool ath9k_hw_4k_fill_eeprom(struct ath_hw *ah)
eep_start_loc = 64;
if (!ath9k_hw_use_flash(ah)) {
- ath_print(common, ATH_DBG_EEPROM,
- "Reading from EEPROM, not flash\n");
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "Reading from EEPROM, not flash\n");
}
for (addr = 0; addr < SIZE_EEPROM_4K; addr++) {
if (!ath9k_hw_nvram_read(common, addr + eep_start_loc, eep_data)) {
- ath_print(common, ATH_DBG_EEPROM,
- "Unable to read eeprom region\n");
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "Unable to read eeprom region\n");
return false;
}
eep_data++;
@@ -69,13 +69,12 @@ static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah)
if (!ath9k_hw_use_flash(ah)) {
if (!ath9k_hw_nvram_read(common, AR5416_EEPROM_MAGIC_OFFSET,
&magic)) {
- ath_print(common, ATH_DBG_FATAL,
- "Reading Magic # failed\n");
+ ath_err(common, "Reading Magic # failed\n");
return false;
}
- ath_print(common, ATH_DBG_EEPROM,
- "Read Magic = 0x%04X\n", magic);
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "Read Magic = 0x%04X\n", magic);
if (magic != AR5416_EEPROM_MAGIC) {
magic2 = swab16(magic);
@@ -90,16 +89,15 @@ static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah)
eepdata++;
}
} else {
- ath_print(common, ATH_DBG_FATAL,
- "Invalid EEPROM Magic. "
- "endianness mismatch.\n");
+ ath_err(common,
+ "Invalid EEPROM Magic. Endianness mismatch.\n");
return -EINVAL;
}
}
}
- ath_print(common, ATH_DBG_EEPROM, "need_swap = %s.\n",
- need_swap ? "True" : "False");
+ ath_dbg(common, ATH_DBG_EEPROM, "need_swap = %s.\n",
+ need_swap ? "True" : "False");
if (need_swap)
el = swab16(ah->eeprom.map4k.baseEepHeader.length);
@@ -120,8 +118,8 @@ static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah)
u32 integer;
u16 word;
- ath_print(common, ATH_DBG_EEPROM,
- "EEPROM Endianness is not native.. Changing\n");
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "EEPROM Endianness is not native.. Changing\n");
word = swab16(eep->baseEepHeader.length);
eep->baseEepHeader.length = word;
@@ -163,9 +161,8 @@ static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah)
if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER ||
ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
- ath_print(common, ATH_DBG_FATAL,
- "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
- sum, ah->eep_ops->get_eeprom_ver(ah));
+ ath_err(common, "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
+ sum, ah->eep_ops->get_eeprom_ver(ah));
return -EINVAL;
}
@@ -488,21 +485,20 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
((pdadcValues[4 * j + 3] & 0xFF) << 24);
REG_WRITE(ah, regOffset, reg32);
- ath_print(common, ATH_DBG_EEPROM,
- "PDADC (%d,%4x): %4.4x %8.8x\n",
- i, regChainOffset, regOffset,
- reg32);
- ath_print(common, ATH_DBG_EEPROM,
- "PDADC: Chain %d | "
- "PDADC %3d Value %3d | "
- "PDADC %3d Value %3d | "
- "PDADC %3d Value %3d | "
- "PDADC %3d Value %3d |\n",
- i, 4 * j, pdadcValues[4 * j],
- 4 * j + 1, pdadcValues[4 * j + 1],
- 4 * j + 2, pdadcValues[4 * j + 2],
- 4 * j + 3,
- pdadcValues[4 * j + 3]);
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "PDADC (%d,%4x): %4.4x %8.8x\n",
+ i, regChainOffset, regOffset,
+ reg32);
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "PDADC: Chain %d | "
+ "PDADC %3d Value %3d | "
+ "PDADC %3d Value %3d | "
+ "PDADC %3d Value %3d | "
+ "PDADC %3d Value %3d |\n",
+ i, 4 * j, pdadcValues[4 * j],
+ 4 * j + 1, pdadcValues[4 * j + 1],
+ 4 * j + 2, pdadcValues[4 * j + 2],
+ 4 * j + 3, pdadcValues[4 * j + 3]);
regOffset += 4;
}
@@ -534,7 +530,9 @@ static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
u16 twiceMinEdgePower;
u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
- u16 numCtlModes, *pCtlMode, ctlMode, freq;
+ u16 numCtlModes;
+ const u16 *pCtlMode;
+ u16 ctlMode, freq;
struct chan_centers centers;
struct cal_ctl_data_4k *rep;
struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
@@ -550,10 +548,10 @@ static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
0, {0, 0, 0, 0}
};
- u16 ctlModesFor11g[] =
- { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
- CTL_2GHT40
- };
+ static const u16 ctlModesFor11g[] = {
+ CTL_11B, CTL_11G, CTL_2GHT20,
+ CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40
+ };
ath9k_hw_get_channel_centers(ah, chan, &centers);
@@ -726,7 +724,7 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
u16 cfgCtl,
u8 twiceAntennaReduction,
u8 twiceMaxRegulatoryPower,
- u8 powerLimit)
+ u8 powerLimit, bool test)
{
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
@@ -751,15 +749,20 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
ath9k_hw_set_4k_power_cal_table(ah, chan, &txPowerIndexOffset);
+ regulatory->max_power_level = 0;
for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
if (ratesArray[i] > AR5416_MAX_RATE_POWER)
ratesArray[i] = AR5416_MAX_RATE_POWER;
+
+ if (ratesArray[i] > regulatory->max_power_level)
+ regulatory->max_power_level = ratesArray[i];
}
+ if (test)
+ return;
/* Update regulatory */
-
i = rate6mb;
if (IS_CHAN_HT40(chan))
i = rateHt40_0;
@@ -1174,17 +1177,17 @@ static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
u16 spur_val = AR_NO_SPUR;
- ath_print(common, ATH_DBG_ANI,
- "Getting spur idx %d is2Ghz. %d val %x\n",
- i, is2GHz, ah->config.spurchans[i][is2GHz]);
+ ath_dbg(common, ATH_DBG_ANI,
+ "Getting spur idx:%d is2Ghz:%d val:%x\n",
+ i, is2GHz, ah->config.spurchans[i][is2GHz]);
switch (ah->config.spurmode) {
case SPUR_DISABLE:
break;
case SPUR_ENABLE_IOCTL:
spur_val = ah->config.spurchans[i][is2GHz];
- ath_print(common, ATH_DBG_ANI,
- "Getting spur val from new loc. %d\n", spur_val);
+ ath_dbg(common, ATH_DBG_ANI,
+ "Getting spur val from new loc. %d\n", spur_val);
break;
case SPUR_ENABLE_EEPROM:
spur_val = EEP_MAP4K_SPURCHAN;
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
index 195406db3bd8..065402f2e402 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
@@ -37,21 +37,21 @@ static bool ath9k_hw_ar9287_fill_eeprom(struct ath_hw *ah)
int addr, eep_start_loc;
eep_data = (u16 *)eep;
- if (AR9287_HTC_DEVID(ah))
+ if (common->bus_ops->ath_bus_type == ATH_USB)
eep_start_loc = AR9287_HTC_EEP_START_LOC;
else
eep_start_loc = AR9287_EEP_START_LOC;
if (!ath9k_hw_use_flash(ah)) {
- ath_print(common, ATH_DBG_EEPROM,
- "Reading from EEPROM, not flash\n");
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "Reading from EEPROM, not flash\n");
}
for (addr = 0; addr < NUM_EEP_WORDS; addr++) {
if (!ath9k_hw_nvram_read(common, addr + eep_start_loc,
eep_data)) {
- ath_print(common, ATH_DBG_EEPROM,
- "Unable to read eeprom region\n");
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "Unable to read eeprom region\n");
return false;
}
eep_data++;
@@ -72,13 +72,12 @@ static int ath9k_hw_ar9287_check_eeprom(struct ath_hw *ah)
if (!ath9k_hw_use_flash(ah)) {
if (!ath9k_hw_nvram_read(common, AR5416_EEPROM_MAGIC_OFFSET,
&magic)) {
- ath_print(common, ATH_DBG_FATAL,
- "Reading Magic # failed\n");
+ ath_err(common, "Reading Magic # failed\n");
return false;
}
- ath_print(common, ATH_DBG_EEPROM,
- "Read Magic = 0x%04X\n", magic);
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "Read Magic = 0x%04X\n", magic);
if (magic != AR5416_EEPROM_MAGIC) {
magic2 = swab16(magic);
@@ -93,16 +92,15 @@ static int ath9k_hw_ar9287_check_eeprom(struct ath_hw *ah)
eepdata++;
}
} else {
- ath_print(common, ATH_DBG_FATAL,
- "Invalid EEPROM Magic. "
- "Endianness mismatch.\n");
+ ath_err(common,
+ "Invalid EEPROM Magic. Endianness mismatch.\n");
return -EINVAL;
}
}
}
- ath_print(common, ATH_DBG_EEPROM, "need_swap = %s.\n",
- need_swap ? "True" : "False");
+ ath_dbg(common, ATH_DBG_EEPROM, "need_swap = %s.\n",
+ need_swap ? "True" : "False");
if (need_swap)
el = swab16(ah->eeprom.map9287.baseEepHeader.length);
@@ -160,9 +158,8 @@ static int ath9k_hw_ar9287_check_eeprom(struct ath_hw *ah)
if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR9287_EEP_VER
|| ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
- ath_print(common, ATH_DBG_FATAL,
- "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
- sum, ah->eep_ops->get_eeprom_ver(ah));
+ ath_err(common, "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
+ sum, ah->eep_ops->get_eeprom_ver(ah));
return -EINVAL;
}
@@ -626,13 +623,13 @@ static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah,
struct cal_target_power_ht targetPowerHt20,
targetPowerHt40 = {0, {0, 0, 0, 0} };
u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
- u16 ctlModesFor11g[] = {CTL_11B,
- CTL_11G,
- CTL_2GHT20,
- CTL_11B_EXT,
- CTL_11G_EXT,
- CTL_2GHT40};
- u16 numCtlModes = 0, *pCtlMode = NULL, ctlMode, freq;
+ static const u16 ctlModesFor11g[] = {
+ CTL_11B, CTL_11G, CTL_2GHT20,
+ CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40
+ };
+ u16 numCtlModes = 0;
+ const u16 *pCtlMode = NULL;
+ u16 ctlMode, freq;
struct chan_centers centers;
int tx_chainmask;
u16 twiceMinEdgePower;
@@ -853,7 +850,7 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah,
struct ath9k_channel *chan, u16 cfgCtl,
u8 twiceAntennaReduction,
u8 twiceMaxRegulatoryPower,
- u8 powerLimit)
+ u8 powerLimit, bool test)
{
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
struct ar9287_eeprom *pEepData = &ah->eeprom.map9287;
@@ -877,12 +874,26 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah,
ath9k_hw_set_ar9287_power_cal_table(ah, chan, &txPowerIndexOffset);
+ regulatory->max_power_level = 0;
for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
if (ratesArray[i] > AR9287_MAX_RATE_POWER)
ratesArray[i] = AR9287_MAX_RATE_POWER;
+
+ if (ratesArray[i] > regulatory->max_power_level)
+ regulatory->max_power_level = ratesArray[i];
}
+ if (test)
+ return;
+
+ if (IS_CHAN_2GHZ(chan))
+ i = rate1l;
+ else
+ i = rate6mb;
+
+ regulatory->max_power_level = ratesArray[i];
+
if (AR_SREV_9280_20_OR_LATER(ah)) {
for (i = 0; i < Ar5416RateSize; i++)
ratesArray[i] -= AR9287_PWR_TABLE_OFFSET_DB * 2;
@@ -971,17 +982,6 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah,
| ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
| ATH9K_POW_SM(ratesArray[rateDupCck], 0));
}
-
- if (IS_CHAN_2GHZ(chan))
- i = rate1l;
- else
- i = rate6mb;
-
- if (AR_SREV_9280_20_OR_LATER(ah))
- regulatory->max_power_level =
- ratesArray[i] + AR9287_PWR_TABLE_OFFSET_DB * 2;
- else
- regulatory->max_power_level = ratesArray[i];
}
static void ath9k_hw_ar9287_set_addac(struct ath_hw *ah,
@@ -1149,17 +1149,17 @@ static u16 ath9k_hw_ar9287_get_spur_channel(struct ath_hw *ah,
struct ath_common *common = ath9k_hw_common(ah);
u16 spur_val = AR_NO_SPUR;
- ath_print(common, ATH_DBG_ANI,
- "Getting spur idx %d is2Ghz. %d val %x\n",
- i, is2GHz, ah->config.spurchans[i][is2GHz]);
+ ath_dbg(common, ATH_DBG_ANI,
+ "Getting spur idx:%d is2Ghz:%d val:%x\n",
+ i, is2GHz, ah->config.spurchans[i][is2GHz]);
switch (ah->config.spurmode) {
case SPUR_DISABLE:
break;
case SPUR_ENABLE_IOCTL:
spur_val = ah->config.spurchans[i][is2GHz];
- ath_print(common, ATH_DBG_ANI,
- "Getting spur val from new loc. %d\n", spur_val);
+ ath_dbg(common, ATH_DBG_ANI,
+ "Getting spur val from new loc. %d\n", spur_val);
break;
case SPUR_ENABLE_EEPROM:
spur_val = EEP_MAP9287_SPURCHAN;
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c
index a3ccb1b9638d..5bfa031545f4 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
@@ -96,8 +96,8 @@ static bool ath9k_hw_def_fill_eeprom(struct ath_hw *ah)
for (addr = 0; addr < SIZE_EEPROM_DEF; addr++) {
if (!ath9k_hw_nvram_read(common, addr + ar5416_eep_start_loc,
eep_data)) {
- ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
- "Unable to read eeprom region\n");
+ ath_err(ath9k_hw_common(ah),
+ "Unable to read eeprom region\n");
return false;
}
eep_data++;
@@ -117,13 +117,13 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
int i, addr, size;
if (!ath9k_hw_nvram_read(common, AR5416_EEPROM_MAGIC_OFFSET, &magic)) {
- ath_print(common, ATH_DBG_FATAL, "Reading Magic # failed\n");
+ ath_err(common, "Reading Magic # failed\n");
return false;
}
if (!ath9k_hw_use_flash(ah)) {
- ath_print(common, ATH_DBG_EEPROM,
- "Read Magic = 0x%04X\n", magic);
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "Read Magic = 0x%04X\n", magic);
if (magic != AR5416_EEPROM_MAGIC) {
magic2 = swab16(magic);
@@ -139,16 +139,15 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
eepdata++;
}
} else {
- ath_print(common, ATH_DBG_FATAL,
- "Invalid EEPROM Magic. "
- "Endianness mismatch.\n");
+ ath_err(common,
+ "Invalid EEPROM Magic. Endianness mismatch.\n");
return -EINVAL;
}
}
}
- ath_print(common, ATH_DBG_EEPROM, "need_swap = %s.\n",
- need_swap ? "True" : "False");
+ ath_dbg(common, ATH_DBG_EEPROM, "need_swap = %s.\n",
+ need_swap ? "True" : "False");
if (need_swap)
el = swab16(ah->eeprom.def.baseEepHeader.length);
@@ -169,8 +168,8 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
u32 integer, j;
u16 word;
- ath_print(common, ATH_DBG_EEPROM,
- "EEPROM Endianness is not native.. Changing.\n");
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "EEPROM Endianness is not native.. Changing.\n");
word = swab16(eep->baseEepHeader.length);
eep->baseEepHeader.length = word;
@@ -216,8 +215,7 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER ||
ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
- ath_print(common, ATH_DBG_FATAL,
- "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
+ ath_err(common, "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
sum, ah->eep_ops->get_eeprom_ver(ah));
return -EINVAL;
}
@@ -966,20 +964,19 @@ static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
((pdadcValues[4 * j + 3] & 0xFF) << 24);
REG_WRITE(ah, regOffset, reg32);
- ath_print(common, ATH_DBG_EEPROM,
- "PDADC (%d,%4x): %4.4x %8.8x\n",
- i, regChainOffset, regOffset,
- reg32);
- ath_print(common, ATH_DBG_EEPROM,
- "PDADC: Chain %d | PDADC %3d "
- "Value %3d | PDADC %3d Value %3d | "
- "PDADC %3d Value %3d | PDADC %3d "
- "Value %3d |\n",
- i, 4 * j, pdadcValues[4 * j],
- 4 * j + 1, pdadcValues[4 * j + 1],
- 4 * j + 2, pdadcValues[4 * j + 2],
- 4 * j + 3,
- pdadcValues[4 * j + 3]);
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "PDADC (%d,%4x): %4.4x %8.8x\n",
+ i, regChainOffset, regOffset,
+ reg32);
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "PDADC: Chain %d | PDADC %3d "
+ "Value %3d | PDADC %3d Value %3d | "
+ "PDADC %3d Value %3d | PDADC %3d "
+ "Value %3d |\n",
+ i, 4 * j, pdadcValues[4 * j],
+ 4 * j + 1, pdadcValues[4 * j + 1],
+ 4 * j + 2, pdadcValues[4 * j + 2],
+ 4 * j + 3, pdadcValues[4 * j + 3]);
regOffset += 4;
}
@@ -1022,13 +1019,16 @@ static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
0, {0, 0, 0, 0}
};
u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
- u16 ctlModesFor11a[] =
- { CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 };
- u16 ctlModesFor11g[] =
- { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
- CTL_2GHT40
- };
- u16 numCtlModes, *pCtlMode, ctlMode, freq;
+ static const u16 ctlModesFor11a[] = {
+ CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40
+ };
+ static const u16 ctlModesFor11g[] = {
+ CTL_11B, CTL_11G, CTL_2GHT20,
+ CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40
+ };
+ u16 numCtlModes;
+ const u16 *pCtlMode;
+ u16 ctlMode, freq;
struct chan_centers centers;
int tx_chainmask;
u16 twiceMinEdgePower;
@@ -1263,7 +1263,7 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
u16 cfgCtl,
u8 twiceAntennaReduction,
u8 twiceMaxRegulatoryPower,
- u8 powerLimit)
+ u8 powerLimit, bool test)
{
#define RT_AR_DELTA(x) (ratesArray[x] - cck_ofdm_delta)
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
@@ -1290,12 +1290,44 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
ath9k_hw_set_def_power_cal_table(ah, chan, &txPowerIndexOffset);
+ regulatory->max_power_level = 0;
for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
if (ratesArray[i] > AR5416_MAX_RATE_POWER)
ratesArray[i] = AR5416_MAX_RATE_POWER;
+ if (ratesArray[i] > regulatory->max_power_level)
+ regulatory->max_power_level = ratesArray[i];
+ }
+
+ if (!test) {
+ i = rate6mb;
+
+ if (IS_CHAN_HT40(chan))
+ i = rateHt40_0;
+ else if (IS_CHAN_HT20(chan))
+ i = rateHt20_0;
+
+ regulatory->max_power_level = ratesArray[i];
+ }
+
+ switch(ar5416_get_ntxchains(ah->txchainmask)) {
+ case 1:
+ break;
+ case 2:
+ regulatory->max_power_level += INCREASE_MAXPOW_BY_TWO_CHAIN;
+ break;
+ case 3:
+ regulatory->max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN;
+ break;
+ default:
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_EEPROM,
+ "Invalid chainmask configuration\n");
+ break;
}
+ if (test)
+ return;
+
if (AR_SREV_9280_20_OR_LATER(ah)) {
for (i = 0; i < Ar5416RateSize; i++) {
int8_t pwr_table_offset;
@@ -1392,34 +1424,6 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
| ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0));
-
- i = rate6mb;
-
- if (IS_CHAN_HT40(chan))
- i = rateHt40_0;
- else if (IS_CHAN_HT20(chan))
- i = rateHt20_0;
-
- if (AR_SREV_9280_20_OR_LATER(ah))
- regulatory->max_power_level =
- ratesArray[i] + AR5416_PWR_TABLE_OFFSET_DB * 2;
- else
- regulatory->max_power_level = ratesArray[i];
-
- switch(ar5416_get_ntxchains(ah->txchainmask)) {
- case 1:
- break;
- case 2:
- regulatory->max_power_level += INCREASE_MAXPOW_BY_TWO_CHAIN;
- break;
- case 3:
- regulatory->max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN;
- break;
- default:
- ath_print(ath9k_hw_common(ah), ATH_DBG_EEPROM,
- "Invalid chainmask configuration\n");
- break;
- }
}
static u8 ath9k_hw_def_get_num_ant_config(struct ath_hw *ah,
@@ -1458,17 +1462,17 @@ static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
u16 spur_val = AR_NO_SPUR;
- ath_print(common, ATH_DBG_ANI,
- "Getting spur idx %d is2Ghz. %d val %x\n",
- i, is2GHz, ah->config.spurchans[i][is2GHz]);
+ ath_dbg(common, ATH_DBG_ANI,
+ "Getting spur idx:%d is2Ghz:%d val:%x\n",
+ i, is2GHz, ah->config.spurchans[i][is2GHz]);
switch (ah->config.spurmode) {
case SPUR_DISABLE:
break;
case SPUR_ENABLE_IOCTL:
spur_val = ah->config.spurchans[i][is2GHz];
- ath_print(common, ATH_DBG_ANI,
- "Getting spur val from new loc. %d\n", spur_val);
+ ath_dbg(common, ATH_DBG_ANI,
+ "Getting spur val from new loc. %d\n", spur_val);
break;
case SPUR_ENABLE_EEPROM:
spur_val = EEP_DEF_SPURCHAN;
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c
index 4a9a68bba324..133764069246 100644
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -103,8 +103,8 @@ static int ath_register_led(struct ath_softc *sc, struct ath_led *led,
ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &led->led_cdev);
if (ret)
- ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
- "Failed to register led:%s", led->name);
+ ath_err(ath9k_hw_common(sc->sc_ah),
+ "Failed to register led:%s", led->name);
else
led->registered = 1;
return ret;
@@ -236,13 +236,13 @@ static void ath_detect_bt_priority(struct ath_softc *sc)
sc->sc_flags &= ~(SC_OP_BT_PRIORITY_DETECTED | SC_OP_BT_SCAN);
/* Detect if colocated bt started scanning */
if (btcoex->bt_priority_cnt >= ATH_BT_CNT_SCAN_THRESHOLD) {
- ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_BTCOEX,
- "BT scan detected");
+ ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_BTCOEX,
+ "BT scan detected\n");
sc->sc_flags |= (SC_OP_BT_SCAN |
SC_OP_BT_PRIORITY_DETECTED);
} else if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) {
- ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_BTCOEX,
- "BT priority traffic detected");
+ ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_BTCOEX,
+ "BT priority traffic detected\n");
sc->sc_flags |= SC_OP_BT_PRIORITY_DETECTED;
}
@@ -259,7 +259,7 @@ static void ath9k_gen_timer_start(struct ath_hw *ah,
ath9k_hw_gen_timer_start(ah, timer, timer_next, timer_period);
if ((ah->imask & ATH9K_INT_GENTIMER) == 0) {
- ath9k_hw_set_interrupts(ah, 0);
+ ath9k_hw_disable_interrupts(ah);
ah->imask |= ATH9K_INT_GENTIMER;
ath9k_hw_set_interrupts(ah, ah->imask);
}
@@ -273,7 +273,7 @@ static void ath9k_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer)
/* if no timer is enabled, turn off interrupt mask */
if (timer_table->timer_mask.val == 0) {
- ath9k_hw_set_interrupts(ah, 0);
+ ath9k_hw_disable_interrupts(ah);
ah->imask &= ~ATH9K_INT_GENTIMER;
ath9k_hw_set_interrupts(ah, ah->imask);
}
@@ -310,10 +310,8 @@ static void ath_btcoex_period_timer(unsigned long data)
timer_period = is_btscan ? btcoex->btscan_no_stomp :
btcoex->btcoex_no_stomp;
- ath9k_gen_timer_start(ah,
- btcoex->no_stomp_timer,
- (ath9k_hw_gettsf32(ah) +
- timer_period), timer_period * 10);
+ ath9k_gen_timer_start(ah, btcoex->no_stomp_timer, 0,
+ timer_period * 10);
btcoex->hw_timer_enabled = true;
}
@@ -333,8 +331,8 @@ static void ath_btcoex_no_stomp_timer(void *arg)
struct ath_common *common = ath9k_hw_common(ah);
bool is_btscan = sc->sc_flags & SC_OP_BT_SCAN;
- ath_print(common, ATH_DBG_BTCOEX,
- "no stomp timer running\n");
+ ath_dbg(common, ATH_DBG_BTCOEX,
+ "no stomp timer running\n");
spin_lock_bh(&btcoex->btcoex_lock);
@@ -380,8 +378,8 @@ void ath9k_btcoex_timer_resume(struct ath_softc *sc)
struct ath_btcoex *btcoex = &sc->btcoex;
struct ath_hw *ah = sc->sc_ah;
- ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
- "Starting btcoex timers");
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
+ "Starting btcoex timers\n");
/* make sure duty cycle timer is also stopped when resuming */
if (btcoex->hw_timer_enabled)
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index 0de3c3d3c245..d0918bd23b8e 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -28,10 +28,7 @@ MODULE_FIRMWARE(FIRMWARE_AR9271);
static struct usb_device_id ath9k_hif_usb_ids[] = {
{ USB_DEVICE(0x0cf3, 0x9271) }, /* Atheros */
{ USB_DEVICE(0x0cf3, 0x1006) }, /* Atheros */
- { USB_DEVICE(0x0cf3, 0x7010) }, /* Atheros */
- { USB_DEVICE(0x0cf3, 0x7015) }, /* Atheros */
{ USB_DEVICE(0x0846, 0x9030) }, /* Netgear N150 */
- { USB_DEVICE(0x0846, 0x9018) }, /* Netgear WNDA3200 */
{ USB_DEVICE(0x07D1, 0x3A10) }, /* Dlink Wireless 150 */
{ USB_DEVICE(0x13D3, 0x3327) }, /* Azurewave */
{ USB_DEVICE(0x13D3, 0x3328) }, /* Azurewave */
@@ -40,9 +37,20 @@ static struct usb_device_id ath9k_hif_usb_ids[] = {
{ USB_DEVICE(0x13D3, 0x3349) }, /* Azurewave */
{ USB_DEVICE(0x13D3, 0x3350) }, /* Azurewave */
{ USB_DEVICE(0x04CA, 0x4605) }, /* Liteon */
- { USB_DEVICE(0x083A, 0xA704) }, /* SMC Networks */
{ USB_DEVICE(0x040D, 0x3801) }, /* VIA */
- { USB_DEVICE(0x1668, 0x1200) }, /* Verizon */
+
+ { USB_DEVICE(0x0cf3, 0x7015),
+ .driver_info = AR9287_USB }, /* Atheros */
+ { USB_DEVICE(0x1668, 0x1200),
+ .driver_info = AR9287_USB }, /* Verizon */
+
+ { USB_DEVICE(0x0cf3, 0x7010),
+ .driver_info = AR9280_USB }, /* Atheros */
+ { USB_DEVICE(0x0846, 0x9018),
+ .driver_info = AR9280_USB }, /* Netgear WNDA3200 */
+ { USB_DEVICE(0x083A, 0xA704),
+ .driver_info = AR9280_USB }, /* SMC Networks */
+
{ },
};
@@ -353,9 +361,9 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
struct sk_buff *skb)
{
struct sk_buff *nskb, *skb_pool[MAX_PKT_NUM_IN_TRANSFER];
- int index = 0, i = 0, chk_idx, len = skb->len;
- int rx_remain_len = 0, rx_pkt_len = 0;
- u16 pkt_len, pkt_tag, pool_index = 0;
+ int index = 0, i = 0, len = skb->len;
+ int rx_remain_len, rx_pkt_len;
+ u16 pool_index = 0;
u8 *ptr;
spin_lock(&hif_dev->rx_lock);
@@ -389,64 +397,64 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
spin_unlock(&hif_dev->rx_lock);
while (index < len) {
+ u16 pkt_len;
+ u16 pkt_tag;
+ u16 pad_len;
+ int chk_idx;
+
ptr = (u8 *) skb->data;
pkt_len = ptr[index] + (ptr[index+1] << 8);
pkt_tag = ptr[index+2] + (ptr[index+3] << 8);
- if (pkt_tag == ATH_USB_RX_STREAM_MODE_TAG) {
- u16 pad_len;
-
- pad_len = 4 - (pkt_len & 0x3);
- if (pad_len == 4)
- pad_len = 0;
-
- chk_idx = index;
- index = index + 4 + pkt_len + pad_len;
-
- if (index > MAX_RX_BUF_SIZE) {
- spin_lock(&hif_dev->rx_lock);
- hif_dev->rx_remain_len = index - MAX_RX_BUF_SIZE;
- hif_dev->rx_transfer_len =
- MAX_RX_BUF_SIZE - chk_idx - 4;
- hif_dev->rx_pad_len = pad_len;
-
- nskb = __dev_alloc_skb(pkt_len + 32,
- GFP_ATOMIC);
- if (!nskb) {
- dev_err(&hif_dev->udev->dev,
- "ath9k_htc: RX memory allocation"
- " error\n");
- spin_unlock(&hif_dev->rx_lock);
- goto err;
- }
- skb_reserve(nskb, 32);
- RX_STAT_INC(skb_allocated);
-
- memcpy(nskb->data, &(skb->data[chk_idx+4]),
- hif_dev->rx_transfer_len);
-
- /* Record the buffer pointer */
- hif_dev->remain_skb = nskb;
+ if (pkt_tag != ATH_USB_RX_STREAM_MODE_TAG) {
+ RX_STAT_INC(skb_dropped);
+ return;
+ }
+
+ pad_len = 4 - (pkt_len & 0x3);
+ if (pad_len == 4)
+ pad_len = 0;
+
+ chk_idx = index;
+ index = index + 4 + pkt_len + pad_len;
+
+ if (index > MAX_RX_BUF_SIZE) {
+ spin_lock(&hif_dev->rx_lock);
+ hif_dev->rx_remain_len = index - MAX_RX_BUF_SIZE;
+ hif_dev->rx_transfer_len =
+ MAX_RX_BUF_SIZE - chk_idx - 4;
+ hif_dev->rx_pad_len = pad_len;
+
+ nskb = __dev_alloc_skb(pkt_len + 32, GFP_ATOMIC);
+ if (!nskb) {
+ dev_err(&hif_dev->udev->dev,
+ "ath9k_htc: RX memory allocation error\n");
spin_unlock(&hif_dev->rx_lock);
- } else {
- nskb = __dev_alloc_skb(pkt_len + 32, GFP_ATOMIC);
- if (!nskb) {
- dev_err(&hif_dev->udev->dev,
- "ath9k_htc: RX memory allocation"
- " error\n");
- goto err;
- }
- skb_reserve(nskb, 32);
- RX_STAT_INC(skb_allocated);
-
- memcpy(nskb->data, &(skb->data[chk_idx+4]), pkt_len);
- skb_put(nskb, pkt_len);
- skb_pool[pool_index++] = nskb;
+ goto err;
}
+ skb_reserve(nskb, 32);
+ RX_STAT_INC(skb_allocated);
+
+ memcpy(nskb->data, &(skb->data[chk_idx+4]),
+ hif_dev->rx_transfer_len);
+
+ /* Record the buffer pointer */
+ hif_dev->remain_skb = nskb;
+ spin_unlock(&hif_dev->rx_lock);
} else {
- RX_STAT_INC(skb_dropped);
- return;
+ nskb = __dev_alloc_skb(pkt_len + 32, GFP_ATOMIC);
+ if (!nskb) {
+ dev_err(&hif_dev->udev->dev,
+ "ath9k_htc: RX memory allocation error\n");
+ goto err;
+ }
+ skb_reserve(nskb, 32);
+ RX_STAT_INC(skb_allocated);
+
+ memcpy(nskb->data, &(skb->data[chk_idx+4]), pkt_len);
+ skb_put(nskb, pkt_len);
+ skb_pool[pool_index++] = nskb;
}
}
@@ -461,7 +469,7 @@ err:
static void ath9k_hif_usb_rx_cb(struct urb *urb)
{
struct sk_buff *skb = (struct sk_buff *) urb->context;
- struct hif_device_usb *hif_dev = (struct hif_device_usb *)
+ struct hif_device_usb *hif_dev =
usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
int ret;
@@ -508,7 +516,7 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb)
{
struct sk_buff *skb = (struct sk_buff *) urb->context;
struct sk_buff *nskb;
- struct hif_device_usb *hif_dev = (struct hif_device_usb *)
+ struct hif_device_usb *hif_dev =
usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
int ret;
@@ -776,7 +784,8 @@ static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev)
ath9k_hif_usb_dealloc_rx_urbs(hif_dev);
}
-static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev)
+static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev,
+ u32 drv_info)
{
int transfer, err;
const void *data = hif_dev->firmware->data;
@@ -807,18 +816,10 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev)
}
kfree(buf);
- switch (hif_dev->device_id) {
- case 0x7010:
- case 0x7015:
- case 0x9018:
- case 0xA704:
- case 0x1200:
+ if (IS_AR7010_DEVICE(drv_info))
firm_offset = AR7010_FIRMWARE_TEXT;
- break;
- default:
+ else
firm_offset = AR9271_FIRMWARE_TEXT;
- break;
- }
/*
* Issue FW download complete command to firmware.
@@ -836,7 +837,7 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev)
return 0;
}
-static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev)
+static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev, u32 drv_info)
{
int ret, idx;
struct usb_host_interface *alt = &hif_dev->interface->altsetting[0];
@@ -852,7 +853,7 @@ static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev)
}
/* Download firmware */
- ret = ath9k_hif_usb_download_fw(hif_dev);
+ ret = ath9k_hif_usb_download_fw(hif_dev, drv_info);
if (ret) {
dev_err(&hif_dev->udev->dev,
"ath9k_htc: Firmware - %s download failed\n",
@@ -884,9 +885,9 @@ static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev)
return 0;
-err_fw_download:
- ath9k_hif_usb_dealloc_urbs(hif_dev);
err_urb:
+ ath9k_hif_usb_dealloc_urbs(hif_dev);
+err_fw_download:
release_firmware(hif_dev->firmware);
err_fw_req:
hif_dev->firmware = NULL;
@@ -931,23 +932,15 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface,
/* Find out which firmware to load */
- switch(hif_dev->device_id) {
- case 0x7010:
- case 0x7015:
- case 0x9018:
- case 0xA704:
- case 0x1200:
+ if (IS_AR7010_DEVICE(id->driver_info))
if (le16_to_cpu(udev->descriptor.bcdDevice) == 0x0202)
hif_dev->fw_name = FIRMWARE_AR7010_1_1;
else
hif_dev->fw_name = FIRMWARE_AR7010;
- break;
- default:
+ else
hif_dev->fw_name = FIRMWARE_AR9271;
- break;
- }
- ret = ath9k_hif_usb_dev_init(hif_dev);
+ ret = ath9k_hif_usb_dev_init(hif_dev, id->driver_info);
if (ret) {
ret = -EINVAL;
goto err_hif_init_usb;
@@ -955,7 +948,7 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface,
ret = ath9k_htc_hw_init(hif_dev->htc_handle,
&hif_dev->udev->dev, hif_dev->device_id,
- hif_dev->udev->product);
+ hif_dev->udev->product, id->driver_info);
if (ret) {
ret = -EINVAL;
goto err_htc_hw_init;
@@ -998,8 +991,7 @@ static void ath9k_hif_usb_reboot(struct usb_device *udev)
static void ath9k_hif_usb_disconnect(struct usb_interface *interface)
{
struct usb_device *udev = interface_to_usbdev(interface);
- struct hif_device_usb *hif_dev =
- (struct hif_device_usb *) usb_get_intfdata(interface);
+ struct hif_device_usb *hif_dev = usb_get_intfdata(interface);
if (hif_dev) {
ath9k_htc_hw_deinit(hif_dev->htc_handle,
@@ -1021,8 +1013,7 @@ static void ath9k_hif_usb_disconnect(struct usb_interface *interface)
static int ath9k_hif_usb_suspend(struct usb_interface *interface,
pm_message_t message)
{
- struct hif_device_usb *hif_dev =
- (struct hif_device_usb *) usb_get_intfdata(interface);
+ struct hif_device_usb *hif_dev = usb_get_intfdata(interface);
/*
* The device has to be set to FULLSLEEP mode in case no
@@ -1038,8 +1029,8 @@ static int ath9k_hif_usb_suspend(struct usb_interface *interface,
static int ath9k_hif_usb_resume(struct usb_interface *interface)
{
- struct hif_device_usb *hif_dev =
- (struct hif_device_usb *) usb_get_intfdata(interface);
+ struct hif_device_usb *hif_dev = usb_get_intfdata(interface);
+ struct htc_target *htc_handle = hif_dev->htc_handle;
int ret;
ret = ath9k_hif_usb_alloc_urbs(hif_dev);
@@ -1047,7 +1038,8 @@ static int ath9k_hif_usb_resume(struct usb_interface *interface)
return ret;
if (hif_dev->firmware) {
- ret = ath9k_hif_usb_download_fw(hif_dev);
+ ret = ath9k_hif_usb_download_fw(hif_dev,
+ htc_handle->drv_priv->ah->hw_version.usbdev);
if (ret)
goto fail_resume;
} else {
@@ -1057,7 +1049,7 @@ static int ath9k_hif_usb_resume(struct usb_interface *interface)
mdelay(100);
- ret = ath9k_htc_resume(hif_dev->htc_handle);
+ ret = ath9k_htc_resume(htc_handle);
if (ret)
goto fail_resume;
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h
index 2daf97b11c08..e4a5e2e79541 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.h
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.h
@@ -17,6 +17,8 @@
#ifndef HTC_USB_H
#define HTC_USB_H
+#define IS_AR7010_DEVICE(_v) (((_v) == AR9280_USB) || ((_v) == AR9287_USB))
+
#define AR9271_FIRMWARE 0x501000
#define AR9271_FIRMWARE_TEXT 0x903000
#define AR7010_FIRMWARE_TEXT 0x906000
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index c3b561daa6c1..fdf9d5fe8cc0 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -368,7 +368,7 @@ struct ath9k_htc_priv {
u16 seq_no;
u32 bmiss_cnt;
- struct ath9k_hw_cal_data caldata[38];
+ struct ath9k_hw_cal_data caldata[ATH9K_NUM_CHANNELS];
spinlock_t beacon_lock;
@@ -463,7 +463,7 @@ void ath9k_init_leds(struct ath9k_htc_priv *priv);
void ath9k_deinit_leds(struct ath9k_htc_priv *priv);
int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
- u16 devid, char *product);
+ u16 devid, char *product, u32 drv_info);
void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug);
#ifdef CONFIG_PM
void ath9k_htc_suspend(struct htc_target *htc_handle);
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
index 1b72aa482ac7..87cc65a78a3f 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
@@ -123,11 +123,11 @@ static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv,
/* TSF out of range threshold fixed at 1 second */
bs.bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD;
- ath_print(common, ATH_DBG_BEACON, "tsf: %llu tsftu: %u\n", tsf, tsftu);
- ath_print(common, ATH_DBG_BEACON,
- "bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n",
- bs.bs_bmissthreshold, bs.bs_sleepduration,
- bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext);
+ ath_dbg(common, ATH_DBG_BEACON, "tsf: %llu tsftu: %u\n", tsf, tsftu);
+ ath_dbg(common, ATH_DBG_BEACON,
+ "bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n",
+ bs.bs_bmissthreshold, bs.bs_sleepduration,
+ bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext);
/* Set the computed STA beacon timers */
@@ -154,9 +154,9 @@ static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv,
if (priv->op_flags & OP_ENABLE_BEACON)
imask |= ATH9K_INT_SWBA;
- ath_print(common, ATH_DBG_BEACON,
- "IBSS Beacon config, intval: %d, imask: 0x%x\n",
- bss_conf->beacon_interval, imask);
+ ath_dbg(common, ATH_DBG_BEACON,
+ "IBSS Beacon config, intval: %d, imask: 0x%x\n",
+ bss_conf->beacon_interval, imask);
WMI_CMD(WMI_DISABLE_INTR_CMDID);
ath9k_hw_beaconinit(priv->ah, nexttbtt, intval);
@@ -246,8 +246,8 @@ void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv)
qi.tqi_cwmax = qi_be.tqi_cwmax;
if (!ath9k_hw_set_txq_props(ah, priv->beaconq, &qi)) {
- ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
- "Unable to update beacon queue %u!\n", qnum);
+ ath_err(ath9k_hw_common(ah),
+ "Unable to update beacon queue %u!\n", qnum);
} else {
ath9k_hw_resettxqueue(ah, priv->beaconq);
}
@@ -278,8 +278,8 @@ void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv,
ath9k_htc_beacon_config_adhoc(priv, cur_conf);
break;
default:
- ath_print(common, ATH_DBG_CONFIG,
- "Unsupported beaconing mode\n");
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "Unsupported beaconing mode\n");
return;
}
}
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
index 50eec9a3b88c..283ff97ed446 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
@@ -20,13 +20,13 @@ static void ath_detect_bt_priority(struct ath9k_htc_priv *priv)
priv->op_flags &= ~(OP_BT_PRIORITY_DETECTED | OP_BT_SCAN);
/* Detect if colocated bt started scanning */
if (btcoex->bt_priority_cnt >= ATH_BT_CNT_SCAN_THRESHOLD) {
- ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
- "BT scan detected");
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
+ "BT scan detected\n");
priv->op_flags |= (OP_BT_SCAN |
OP_BT_PRIORITY_DETECTED);
} else if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) {
- ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
- "BT priority traffic detected");
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
+ "BT priority traffic detected\n");
priv->op_flags |= OP_BT_PRIORITY_DETECTED;
}
@@ -83,8 +83,8 @@ static void ath_btcoex_duty_cycle_work(struct work_struct *work)
struct ath_common *common = ath9k_hw_common(ah);
bool is_btscan = priv->op_flags & OP_BT_SCAN;
- ath_print(common, ATH_DBG_BTCOEX,
- "time slice work for bt and wlan\n");
+ ath_dbg(common, ATH_DBG_BTCOEX,
+ "time slice work for bt and wlan\n");
if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan)
ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_NONE);
@@ -114,8 +114,7 @@ void ath_htc_resume_btcoex_work(struct ath9k_htc_priv *priv)
struct ath_btcoex *btcoex = &priv->btcoex;
struct ath_hw *ah = priv->ah;
- ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
- "Starting btcoex work");
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_BTCOEX, "Starting btcoex work\n");
btcoex->bt_priority_cnt = 0;
btcoex->bt_priority_time = jiffies;
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index 8776f49ffd41..0f6be350fd3c 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -181,7 +181,8 @@ static inline int ath9k_htc_connect_svc(struct ath9k_htc_priv *priv,
return htc_connect_service(priv->htc, &req, ep_id);
}
-static int ath9k_init_htc_services(struct ath9k_htc_priv *priv, u16 devid)
+static int ath9k_init_htc_services(struct ath9k_htc_priv *priv, u16 devid,
+ u32 drv_info)
{
int ret;
@@ -245,17 +246,10 @@ static int ath9k_init_htc_services(struct ath9k_htc_priv *priv, u16 devid)
* the HIF layer, shouldn't matter much.
*/
- switch(devid) {
- case 0x7010:
- case 0x7015:
- case 0x9018:
- case 0xA704:
- case 0x1200:
+ if (IS_AR7010_DEVICE(drv_info))
priv->htc->credits = 45;
- break;
- default:
+ else
priv->htc->credits = 33;
- }
ret = htc_init(priv->htc);
if (ret)
@@ -294,9 +288,9 @@ static unsigned int ath9k_regread(void *hw_priv, u32 reg_offset)
(u8 *) &val, sizeof(val),
100);
if (unlikely(r)) {
- ath_print(common, ATH_DBG_WMI,
- "REGISTER READ FAILED: (0x%04x, %d)\n",
- reg_offset, r);
+ ath_dbg(common, ATH_DBG_WMI,
+ "REGISTER READ FAILED: (0x%04x, %d)\n",
+ reg_offset, r);
return -EIO;
}
@@ -308,7 +302,7 @@ static void ath9k_regwrite_single(void *hw_priv, u32 val, u32 reg_offset)
struct ath_hw *ah = (struct ath_hw *) hw_priv;
struct ath_common *common = ath9k_hw_common(ah);
struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
- __be32 buf[2] = {
+ const __be32 buf[2] = {
cpu_to_be32(reg_offset),
cpu_to_be32(val),
};
@@ -319,9 +313,9 @@ static void ath9k_regwrite_single(void *hw_priv, u32 val, u32 reg_offset)
(u8 *) &val, sizeof(val),
100);
if (unlikely(r)) {
- ath_print(common, ATH_DBG_WMI,
- "REGISTER WRITE FAILED:(0x%04x, %d)\n",
- reg_offset, r);
+ ath_dbg(common, ATH_DBG_WMI,
+ "REGISTER WRITE FAILED:(0x%04x, %d)\n",
+ reg_offset, r);
}
}
@@ -351,9 +345,9 @@ static void ath9k_regwrite_buffer(void *hw_priv, u32 val, u32 reg_offset)
(u8 *) &rsp_status, sizeof(rsp_status),
100);
if (unlikely(r)) {
- ath_print(common, ATH_DBG_WMI,
- "REGISTER WRITE FAILED, multi len: %d\n",
- priv->wmi->multi_write_idx);
+ ath_dbg(common, ATH_DBG_WMI,
+ "REGISTER WRITE FAILED, multi len: %d\n",
+ priv->wmi->multi_write_idx);
}
priv->wmi->multi_write_idx = 0;
}
@@ -401,9 +395,9 @@ static void ath9k_regwrite_flush(void *hw_priv)
(u8 *) &rsp_status, sizeof(rsp_status),
100);
if (unlikely(r)) {
- ath_print(common, ATH_DBG_WMI,
- "REGISTER WRITE FAILED, multi len: %d\n",
- priv->wmi->multi_write_idx);
+ ath_dbg(common, ATH_DBG_WMI,
+ "REGISTER WRITE FAILED, multi len: %d\n",
+ priv->wmi->multi_write_idx);
}
priv->wmi->multi_write_idx = 0;
}
@@ -475,9 +469,9 @@ static void setup_ht_cap(struct ath9k_htc_priv *priv,
tx_streams = ath9k_cmn_count_streams(common->tx_chainmask, 2);
rx_streams = ath9k_cmn_count_streams(common->rx_chainmask, 2);
- ath_print(common, ATH_DBG_CONFIG,
- "TX streams %d, RX streams: %d\n",
- tx_streams, rx_streams);
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "TX streams %d, RX streams: %d\n",
+ tx_streams, rx_streams);
if (tx_streams != rx_streams) {
ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF;
@@ -501,37 +495,31 @@ static int ath9k_init_queues(struct ath9k_htc_priv *priv)
priv->beaconq = ath9k_hw_beaconq_setup(priv->ah);
if (priv->beaconq == -1) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to setup BEACON xmit queue\n");
+ ath_err(common, "Unable to setup BEACON xmit queue\n");
goto err;
}
priv->cabq = ath9k_htc_cabq_setup(priv);
if (priv->cabq == -1) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to setup CAB xmit queue\n");
+ ath_err(common, "Unable to setup CAB xmit queue\n");
goto err;
}
if (!ath9k_htc_txq_setup(priv, WME_AC_BE)) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to setup xmit queue for BE traffic\n");
+ ath_err(common, "Unable to setup xmit queue for BE traffic\n");
goto err;
}
if (!ath9k_htc_txq_setup(priv, WME_AC_BK)) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to setup xmit queue for BK traffic\n");
+ ath_err(common, "Unable to setup xmit queue for BK traffic\n");
goto err;
}
if (!ath9k_htc_txq_setup(priv, WME_AC_VI)) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to setup xmit queue for VI traffic\n");
+ ath_err(common, "Unable to setup xmit queue for VI traffic\n");
goto err;
}
if (!ath9k_htc_txq_setup(priv, WME_AC_VO)) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to setup xmit queue for VO traffic\n");
+ ath_err(common, "Unable to setup xmit queue for VO traffic\n");
goto err;
}
@@ -549,9 +537,9 @@ static void ath9k_init_crypto(struct ath9k_htc_priv *priv)
/* Get the hardware key cache size. */
common->keymax = priv->ah->caps.keycache_size;
if (common->keymax > ATH_KEYMAX) {
- ath_print(common, ATH_DBG_ANY,
- "Warning, using only %u entries in %u key cache\n",
- ATH_KEYMAX, common->keymax);
+ ath_dbg(common, ATH_DBG_ANY,
+ "Warning, using only %u entries in %u key cache\n",
+ ATH_KEYMAX, common->keymax);
common->keymax = ATH_KEYMAX;
}
@@ -627,7 +615,8 @@ static void ath9k_init_btcoex(struct ath9k_htc_priv *priv)
}
static int ath9k_init_priv(struct ath9k_htc_priv *priv,
- u16 devid, char *product)
+ u16 devid, char *product,
+ u32 drv_info)
{
struct ath_hw *ah = NULL;
struct ath_common *common;
@@ -641,6 +630,8 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv,
ah->hw_version.devid = devid;
ah->hw_version.subsysid = 0; /* FIXME */
+ ah->hw_version.usbdev = drv_info;
+ ah->ah_flags |= AH_USE_EEPROM;
priv->ah = ah;
common = ath9k_hw_common(ah);
@@ -673,16 +664,15 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv,
ret = ath9k_hw_init(ah);
if (ret) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to initialize hardware; "
- "initialization status: %d\n", ret);
+ ath_err(common,
+ "Unable to initialize hardware; initialization status: %d\n",
+ ret);
goto err_hw;
}
ret = ath9k_htc_init_debug(ah);
if (ret) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to create debugfs files\n");
+ ath_err(common, "Unable to create debugfs files\n");
goto err_debug;
}
@@ -724,7 +714,8 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
IEEE80211_HW_HAS_RATE_CONTROL |
IEEE80211_HW_RX_INCLUDES_FCS |
IEEE80211_HW_SUPPORTS_PS |
- IEEE80211_HW_PS_NULLFUNC_STACK;
+ IEEE80211_HW_PS_NULLFUNC_STACK |
+ IEEE80211_HW_NEED_DTIM_PERIOD;
hw->wiphy->interface_modes =
BIT(NL80211_IFTYPE_STATION) |
@@ -762,7 +753,7 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
}
static int ath9k_init_device(struct ath9k_htc_priv *priv,
- u16 devid, char *product)
+ u16 devid, char *product, u32 drv_info)
{
struct ieee80211_hw *hw = priv->hw;
struct ath_common *common;
@@ -771,7 +762,7 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv,
struct ath_regulatory *reg;
/* Bring up device */
- error = ath9k_init_priv(priv, devid, product);
+ error = ath9k_init_priv(priv, devid, product, drv_info);
if (error != 0)
goto err_init;
@@ -829,7 +820,7 @@ err_init:
}
int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
- u16 devid, char *product)
+ u16 devid, char *product, u32 drv_info)
{
struct ieee80211_hw *hw;
struct ath9k_htc_priv *priv;
@@ -856,14 +847,14 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
goto err_free;
}
- ret = ath9k_init_htc_services(priv, devid);
+ ret = ath9k_init_htc_services(priv, devid, drv_info);
if (ret)
goto err_init;
/* The device may have been unplugged earlier. */
priv->op_flags &= ~OP_UNPLUGGED;
- ret = ath9k_init_device(priv, devid, product);
+ ret = ath9k_init_device(priv, devid, product, drv_info);
if (ret)
goto err_init;
@@ -899,14 +890,15 @@ void ath9k_htc_suspend(struct htc_target *htc_handle)
int ath9k_htc_resume(struct htc_target *htc_handle)
{
+ struct ath9k_htc_priv *priv = htc_handle->drv_priv;
int ret;
- ret = ath9k_htc_wait_for_target(htc_handle->drv_priv);
+ ret = ath9k_htc_wait_for_target(priv);
if (ret)
return ret;
- ret = ath9k_init_htc_services(htc_handle->drv_priv,
- htc_handle->drv_priv->ah->hw_version.devid);
+ ret = ath9k_init_htc_services(priv, priv->ah->hw_version.devid,
+ priv->ah->hw_version.usbdev);
return ret;
}
#endif
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index 51977caca47f..20ea75a44e52 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -29,7 +29,7 @@ static void ath_update_txpow(struct ath9k_htc_priv *priv)
struct ath_hw *ah = priv->ah;
if (priv->curtxpow != priv->txpowlimit) {
- ath9k_hw_set_txpowerlimit(ah, priv->txpowlimit);
+ ath9k_hw_set_txpowerlimit(ah, priv->txpowlimit, false);
/* read back in case value is clamped */
priv->curtxpow = ath9k_hw_regulatory(ah)->power_limit;
}
@@ -143,18 +143,18 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
WMI_CMD(WMI_STOP_RECV_CMDID);
- ath_print(common, ATH_DBG_CONFIG,
- "(%u MHz) -> (%u MHz), HT: %d, HT40: %d fastcc: %d\n",
- priv->ah->curchan->channel,
- channel->center_freq, conf_is_ht(conf), conf_is_ht40(conf),
- fastcc);
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "(%u MHz) -> (%u MHz), HT: %d, HT40: %d fastcc: %d\n",
+ priv->ah->curchan->channel,
+ channel->center_freq, conf_is_ht(conf), conf_is_ht40(conf),
+ fastcc);
caldata = &priv->caldata[channel->hw_value];
ret = ath9k_hw_reset(ah, hchan, caldata, fastcc);
if (ret) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to reset channel (%u Mhz) "
- "reset status %d\n", channel->center_freq, ret);
+ ath_err(common,
+ "Unable to reset channel (%u Mhz) reset status %d\n",
+ channel->center_freq, ret);
goto err;
}
@@ -263,15 +263,16 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,
WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta);
if (ret) {
if (sta)
- ath_print(common, ATH_DBG_FATAL,
- "Unable to add station entry for: %pM\n", sta->addr);
+ ath_err(common,
+ "Unable to add station entry for: %pM\n",
+ sta->addr);
return ret;
}
if (sta)
- ath_print(common, ATH_DBG_CONFIG,
- "Added a station entry for: %pM (idx: %d)\n",
- sta->addr, tsta.sta_index);
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "Added a station entry for: %pM (idx: %d)\n",
+ sta->addr, tsta.sta_index);
priv->nstations++;
return 0;
@@ -296,16 +297,16 @@ static int ath9k_htc_remove_station(struct ath9k_htc_priv *priv,
WMI_CMD_BUF(WMI_NODE_REMOVE_CMDID, &sta_idx);
if (ret) {
if (sta)
- ath_print(common, ATH_DBG_FATAL,
- "Unable to remove station entry for: %pM\n",
- sta->addr);
+ ath_err(common,
+ "Unable to remove station entry for: %pM\n",
+ sta->addr);
return ret;
}
if (sta)
- ath_print(common, ATH_DBG_CONFIG,
- "Removed a station entry for: %pM (idx: %d)\n",
- sta->addr, sta_idx);
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "Removed a station entry for: %pM (idx: %d)\n",
+ sta->addr, sta_idx);
priv->nstations--;
return 0;
@@ -390,8 +391,8 @@ static int ath9k_htc_send_rate_cmd(struct ath9k_htc_priv *priv,
WMI_CMD_BUF(WMI_RC_RATE_UPDATE_CMDID, trate);
if (ret) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to initialize Rate information on target\n");
+ ath_err(common,
+ "Unable to initialize Rate information on target\n");
}
return ret;
@@ -408,9 +409,9 @@ static void ath9k_htc_init_rate(struct ath9k_htc_priv *priv,
ath9k_htc_setup_rate(priv, sta, &trate);
ret = ath9k_htc_send_rate_cmd(priv, &trate);
if (!ret)
- ath_print(common, ATH_DBG_CONFIG,
- "Updated target sta: %pM, rate caps: 0x%X\n",
- sta->addr, be32_to_cpu(trate.capflags));
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "Updated target sta: %pM, rate caps: 0x%X\n",
+ sta->addr, be32_to_cpu(trate.capflags));
}
static void ath9k_htc_update_rate(struct ath9k_htc_priv *priv,
@@ -435,9 +436,9 @@ static void ath9k_htc_update_rate(struct ath9k_htc_priv *priv,
ret = ath9k_htc_send_rate_cmd(priv, &trate);
if (!ret)
- ath_print(common, ATH_DBG_CONFIG,
- "Updated target sta: %pM, rate caps: 0x%X\n",
- bss_conf->bssid, be32_to_cpu(trate.capflags));
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "Updated target sta: %pM, rate caps: 0x%X\n",
+ bss_conf->bssid, be32_to_cpu(trate.capflags));
}
static int ath9k_htc_tx_aggr_oper(struct ath9k_htc_priv *priv,
@@ -464,14 +465,14 @@ static int ath9k_htc_tx_aggr_oper(struct ath9k_htc_priv *priv,
WMI_CMD_BUF(WMI_TX_AGGR_ENABLE_CMDID, &aggr);
if (ret)
- ath_print(common, ATH_DBG_CONFIG,
- "Unable to %s TX aggregation for (%pM, %d)\n",
- (aggr.aggr_enable) ? "start" : "stop", sta->addr, tid);
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "Unable to %s TX aggregation for (%pM, %d)\n",
+ (aggr.aggr_enable) ? "start" : "stop", sta->addr, tid);
else
- ath_print(common, ATH_DBG_CONFIG,
- "%s TX aggregation for (%pM, %d)\n",
- (aggr.aggr_enable) ? "Starting" : "Stopping",
- sta->addr, tid);
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "%s TX aggregation for (%pM, %d)\n",
+ (aggr.aggr_enable) ? "Starting" : "Stopping",
+ sta->addr, tid);
spin_lock_bh(&priv->tx_lock);
ista->tid_state[tid] = (aggr.aggr_enable && !ret) ? AGGR_START : AGGR_STOP;
@@ -724,7 +725,7 @@ void ath9k_ani_work(struct work_struct *work)
/* Long calibration runs independently of short calibration. */
if ((timestamp - common->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) {
longcal = true;
- ath_print(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies);
+ ath_dbg(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies);
common->ani.longcal_timer = timestamp;
}
@@ -733,8 +734,8 @@ void ath9k_ani_work(struct work_struct *work)
if ((timestamp - common->ani.shortcal_timer) >=
short_cal_interval) {
shortcal = true;
- ath_print(common, ATH_DBG_ANI,
- "shortcal @%lu\n", jiffies);
+ ath_dbg(common, ATH_DBG_ANI,
+ "shortcal @%lu\n", jiffies);
common->ani.shortcal_timer = timestamp;
common->ani.resetcal_timer = timestamp;
}
@@ -895,8 +896,8 @@ static int ath9k_register_led(struct ath9k_htc_priv *priv, struct ath_led *led,
ret = led_classdev_register(wiphy_dev(priv->hw->wiphy), &led->led_cdev);
if (ret)
- ath_print(ath9k_hw_common(priv->ah), ATH_DBG_FATAL,
- "Failed to register led:%s", led->name);
+ ath_err(ath9k_hw_common(priv->ah),
+ "Failed to register led:%s", led->name);
else
led->registered = 1;
@@ -1024,9 +1025,9 @@ static void ath9k_htc_radio_enable(struct ieee80211_hw *hw)
/* Reset the HW */
ret = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
if (ret) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to reset hardware; reset status %d "
- "(freq %u MHz)\n", ret, ah->curchan->channel);
+ ath_err(common,
+ "Unable to reset hardware; reset status %d (freq %u MHz)\n",
+ ret, ah->curchan->channel);
}
ath_update_txpow(priv);
@@ -1087,9 +1088,9 @@ static void ath9k_htc_radio_disable(struct ieee80211_hw *hw)
/* Reset the HW */
ret = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
if (ret) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to reset hardware; reset status %d "
- "(freq %u MHz)\n", ret, ah->curchan->channel);
+ ath_err(common,
+ "Unable to reset hardware; reset status %d (freq %u MHz)\n",
+ ret, ah->curchan->channel);
}
/* Disable the PHY */
@@ -1124,15 +1125,15 @@ static int ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
ret = ath9k_htc_tx_start(priv, skb);
if (ret != 0) {
if (ret == -ENOMEM) {
- ath_print(ath9k_hw_common(priv->ah), ATH_DBG_XMIT,
- "Stopping TX queues\n");
+ ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT,
+ "Stopping TX queues\n");
ieee80211_stop_queues(hw);
spin_lock_bh(&priv->tx_lock);
priv->tx_queues_stop = true;
spin_unlock_bh(&priv->tx_lock);
} else {
- ath_print(ath9k_hw_common(priv->ah), ATH_DBG_XMIT,
- "Tx failed");
+ ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT,
+ "Tx failed\n");
}
goto fail_tx;
}
@@ -1158,9 +1159,9 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
mutex_lock(&priv->mutex);
- ath_print(common, ATH_DBG_CONFIG,
- "Starting driver with initial channel: %d MHz\n",
- curchan->center_freq);
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "Starting driver with initial channel: %d MHz\n",
+ curchan->center_freq);
/* Ensure that HW is awake before flushing RX */
ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
@@ -1175,9 +1176,9 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
ath9k_hw_htc_resetinit(ah);
ret = ath9k_hw_reset(ah, init_channel, ah->caldata, false);
if (ret) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to reset hardware; reset status %d "
- "(freq %u MHz)\n", ret, curchan->center_freq);
+ ath_err(common,
+ "Unable to reset hardware; reset status %d (freq %u MHz)\n",
+ ret, curchan->center_freq);
mutex_unlock(&priv->mutex);
return ret;
}
@@ -1223,7 +1224,7 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
mutex_lock(&priv->mutex);
if (priv->op_flags & OP_INVALID) {
- ath_print(common, ATH_DBG_ANY, "Device not present\n");
+ ath_dbg(common, ATH_DBG_ANY, "Device not present\n");
mutex_unlock(&priv->mutex);
return;
}
@@ -1243,11 +1244,10 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
/* Remove monitor interface here */
if (ah->opmode == NL80211_IFTYPE_MONITOR) {
if (ath9k_htc_remove_monitor_interface(priv))
- ath_print(common, ATH_DBG_FATAL,
- "Unable to remove monitor interface\n");
+ ath_err(common, "Unable to remove monitor interface\n");
else
- ath_print(common, ATH_DBG_CONFIG,
- "Monitor interface removed\n");
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "Monitor interface removed\n");
}
if (ah->btcoex_hw.enabled) {
@@ -1264,7 +1264,7 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
priv->op_flags |= OP_INVALID;
- ath_print(common, ATH_DBG_CONFIG, "Driver halt\n");
+ ath_dbg(common, ATH_DBG_CONFIG, "Driver halt\n");
mutex_unlock(&priv->mutex);
}
@@ -1298,14 +1298,14 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw,
hvif.opmode = cpu_to_be32(HTC_M_IBSS);
break;
default:
- ath_print(common, ATH_DBG_FATAL,
+ ath_err(common,
"Interface type %d not yet supported\n", vif->type);
ret = -EOPNOTSUPP;
goto out;
}
- ath_print(common, ATH_DBG_CONFIG,
- "Attach a VIF of type: %d\n", vif->type);
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "Attach a VIF of type: %d\n", vif->type);
priv->ah->opmode = vif->type;
@@ -1328,8 +1328,8 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw,
ret = ath9k_htc_update_cap_target(priv);
if (ret)
- ath_print(common, ATH_DBG_CONFIG, "Failed to update"
- " capability in target \n");
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "Failed to update capability in target\n");
priv->vif = vif;
out:
@@ -1349,7 +1349,7 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,
int ret = 0;
u8 cmd_rsp;
- ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n");
+ ath_dbg(common, ATH_DBG_CONFIG, "Detach Interface\n");
mutex_lock(&priv->mutex);
ath9k_htc_ps_wakeup(priv);
@@ -1386,8 +1386,8 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
mutex_unlock(&priv->htc_pm_lock);
if (enable_radio) {
- ath_print(common, ATH_DBG_CONFIG,
- "not-idle: enabling radio\n");
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "not-idle: enabling radio\n");
ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
ath9k_htc_radio_enable(hw);
}
@@ -1397,19 +1397,21 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
struct ieee80211_channel *curchan = hw->conf.channel;
int pos = curchan->hw_value;
- ath_print(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n",
- curchan->center_freq);
+ ath_dbg(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n",
+ curchan->center_freq);
- ath9k_cmn_update_ichannel(hw, &priv->ah->channels[pos]);
+ ath9k_cmn_update_ichannel(&priv->ah->channels[pos],
+ hw->conf.channel,
+ hw->conf.channel_type);
if (ath9k_htc_set_channel(priv, hw, &priv->ah->channels[pos]) < 0) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to set channel\n");
+ ath_err(common, "Unable to set channel\n");
mutex_unlock(&priv->mutex);
return -EINVAL;
}
}
+
if (changed & IEEE80211_CONF_CHANGE_PS) {
if (conf->flags & IEEE80211_CONF_PS) {
ath9k_htc_setpower(priv, ATH9K_PM_NETWORK_SLEEP);
@@ -1421,14 +1423,18 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
}
}
+ if (changed & IEEE80211_CONF_CHANGE_POWER) {
+ priv->txpowlimit = 2 * conf->power_level;
+ ath_update_txpow(priv);
+ }
+
if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
if (conf->flags & IEEE80211_CONF_MONITOR) {
if (ath9k_htc_add_monitor_interface(priv))
- ath_print(common, ATH_DBG_FATAL,
- "Failed to set monitor mode\n");
+ ath_err(common, "Failed to set monitor mode\n");
else
- ath_print(common, ATH_DBG_CONFIG,
- "HW opmode set to Monitor mode\n");
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "HW opmode set to Monitor mode\n");
}
}
@@ -1440,8 +1446,8 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
}
mutex_unlock(&priv->htc_pm_lock);
- ath_print(common, ATH_DBG_CONFIG,
- "idle: disabling radio\n");
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "idle: disabling radio\n");
ath9k_htc_radio_disable(hw);
}
@@ -1478,8 +1484,8 @@ static void ath9k_htc_configure_filter(struct ieee80211_hw *hw,
rfilt = ath9k_htc_calcrxfilter(priv);
ath9k_hw_setrxfilter(priv->ah, rfilt);
- ath_print(ath9k_hw_common(priv->ah), ATH_DBG_CONFIG,
- "Set HW RX filter: 0x%x\n", rfilt);
+ ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_CONFIG,
+ "Set HW RX filter: 0x%x\n", rfilt);
ath9k_htc_ps_restore(priv);
mutex_unlock(&priv->mutex);
@@ -1542,15 +1548,14 @@ static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, u16 queue,
qnum = get_hw_qnum(queue, priv->hwq_map);
- ath_print(common, ATH_DBG_CONFIG,
- "Configure tx [queue/hwq] [%d/%d], "
- "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
- queue, qnum, params->aifs, params->cw_min,
- params->cw_max, params->txop);
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "Configure tx [queue/hwq] [%d/%d], aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
+ queue, qnum, params->aifs, params->cw_min,
+ params->cw_max, params->txop);
ret = ath_htc_txq_update(priv, qnum, &qi);
if (ret) {
- ath_print(common, ATH_DBG_FATAL, "TXQ Update failed\n");
+ ath_err(common, "TXQ Update failed\n");
goto out;
}
@@ -1578,7 +1583,7 @@ static int ath9k_htc_set_key(struct ieee80211_hw *hw,
return -ENOSPC;
mutex_lock(&priv->mutex);
- ath_print(common, ATH_DBG_CONFIG, "Set HW Key\n");
+ ath_dbg(common, ATH_DBG_CONFIG, "Set HW Key\n");
ath9k_htc_ps_wakeup(priv);
switch (cmd) {
@@ -1624,7 +1629,7 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
if (changed & BSS_CHANGED_ASSOC) {
common->curaid = bss_conf->assoc ?
bss_conf->aid : 0;
- ath_print(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
+ ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
bss_conf->assoc);
if (bss_conf->assoc) {
@@ -1641,9 +1646,9 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
ath9k_hw_write_associd(ah);
- ath_print(common, ATH_DBG_CONFIG,
- "BSSID: %pM aid: 0x%x\n",
- common->curbssid, common->curaid);
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "BSSID: %pM aid: 0x%x\n",
+ common->curbssid, common->curaid);
}
if ((changed & BSS_CHANGED_BEACON_INT) ||
@@ -1661,8 +1666,8 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
}
if (changed & BSS_CHANGED_ERP_PREAMBLE) {
- ath_print(common, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n",
- bss_conf->use_short_preamble);
+ ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n",
+ bss_conf->use_short_preamble);
if (bss_conf->use_short_preamble)
priv->op_flags |= OP_PREAMBLE_SHORT;
else
@@ -1670,8 +1675,8 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
}
if (changed & BSS_CHANGED_ERP_CTS_PROT) {
- ath_print(common, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n",
- bss_conf->use_cts_prot);
+ ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n",
+ bss_conf->use_cts_prot);
if (bss_conf->use_cts_prot &&
hw->conf.channel->band != IEEE80211_BAND_5GHZ)
priv->op_flags |= OP_PROTECT_ENABLE;
@@ -1762,8 +1767,7 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,
spin_unlock_bh(&priv->tx_lock);
break;
default:
- ath_print(ath9k_hw_common(priv->ah), ATH_DBG_FATAL,
- "Unknown AMPDU action\n");
+ ath_err(ath9k_hw_common(priv->ah), "Unknown AMPDU action\n");
}
return ret;
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
index 29d80ca78393..31fad82239b3 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
@@ -20,8 +20,15 @@
/* TX */
/******/
+static const int subtype_txq_to_hwq[] = {
+ [WME_AC_BE] = ATH_TXQ_AC_BE,
+ [WME_AC_BK] = ATH_TXQ_AC_BK,
+ [WME_AC_VI] = ATH_TXQ_AC_VI,
+ [WME_AC_VO] = ATH_TXQ_AC_VO,
+};
+
#define ATH9K_HTC_INIT_TXQ(subtype) do { \
- qi.tqi_subtype = subtype; \
+ qi.tqi_subtype = subtype_txq_to_hwq[subtype]; \
qi.tqi_aifs = ATH9K_TXQ_USEDEFAULT; \
qi.tqi_cwmin = ATH9K_TXQ_USEDEFAULT; \
qi.tqi_cwmax = ATH9K_TXQ_USEDEFAULT; \
@@ -62,8 +69,8 @@ int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum,
qi.tqi_readyTime = qinfo->tqi_readyTime;
if (!ath9k_hw_set_txq_props(ah, qnum, &qi)) {
- ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
- "Unable to update hardware queue %u!\n", qnum);
+ ath_err(ath9k_hw_common(ah),
+ "Unable to update hardware queue %u!\n", qnum);
error = -EIO;
} else {
ath9k_hw_resettxqueue(ah, qnum);
@@ -263,8 +270,8 @@ void ath9k_tx_tasklet(unsigned long data)
if (priv->tx_queues_stop) {
priv->tx_queues_stop = false;
spin_unlock_bh(&priv->tx_lock);
- ath_print(ath9k_hw_common(priv->ah), ATH_DBG_XMIT,
- "Waking up TX queues\n");
+ ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT,
+ "Waking up TX queues\n");
ieee80211_wake_queues(priv->hw);
return;
}
@@ -289,8 +296,7 @@ void ath9k_htc_txep(void *drv_priv, struct sk_buff *skb,
(ep_id == priv->data_vo_ep)) {
skb_pull(skb, sizeof(struct tx_frame_hdr));
} else {
- ath_print(common, ATH_DBG_FATAL,
- "Unsupported TX EPID: %d\n", ep_id);
+ ath_err(common, "Unsupported TX EPID: %d\n", ep_id);
dev_kfree_skb_any(skb);
return;
}
@@ -330,9 +336,8 @@ bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv, int subtype)
return false;
if (qnum >= ARRAY_SIZE(priv->hwq_map)) {
- ath_print(common, ATH_DBG_FATAL,
- "qnum %u out of range, max %u!\n",
- qnum, (unsigned int)ARRAY_SIZE(priv->hwq_map));
+ ath_err(common, "qnum %u out of range, max %zu!\n",
+ qnum, ARRAY_SIZE(priv->hwq_map));
ath9k_hw_releasetxqueue(ah, qnum);
return false;
}
@@ -483,8 +488,7 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv,
__le16 fc;
if (skb->len <= HTC_RX_FRAME_HEADER_SIZE) {
- ath_print(common, ATH_DBG_FATAL,
- "Corrupted RX frame, dropping\n");
+ ath_err(common, "Corrupted RX frame, dropping\n");
goto rx_next;
}
@@ -492,10 +496,9 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv,
if (be16_to_cpu(rxstatus->rs_datalen) -
(skb->len - HTC_RX_FRAME_HEADER_SIZE) != 0) {
- ath_print(common, ATH_DBG_FATAL,
- "Corrupted RX data len, dropping "
- "(dlen: %d, skblen: %d)\n",
- rxstatus->rs_datalen, skb->len);
+ ath_err(common,
+ "Corrupted RX data len, dropping (dlen: %d, skblen: %d)\n",
+ rxstatus->rs_datalen, skb->len);
goto rx_next;
}
@@ -678,8 +681,8 @@ void ath9k_htc_rxep(void *drv_priv, struct sk_buff *skb,
spin_unlock(&priv->rx.rxbuflock);
if (rxbuf == NULL) {
- ath_print(common, ATH_DBG_ANY,
- "No free RX buffer\n");
+ ath_dbg(common, ATH_DBG_ANY,
+ "No free RX buffer\n");
goto err;
}
@@ -721,8 +724,7 @@ int ath9k_rx_init(struct ath9k_htc_priv *priv)
for (i = 0; i < ATH9K_HTC_RXBUF; i++) {
rxbuf = kzalloc(sizeof(struct ath9k_htc_rxbuf), GFP_KERNEL);
if (rxbuf == NULL) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to allocate RX buffers\n");
+ ath_err(common, "Unable to allocate RX buffers\n");
goto err;
}
list_add_tail(&rxbuf->list, &priv->rx.rxbuf);
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c
index 861ec9269309..c41ab8c30161 100644
--- a/drivers/net/wireless/ath/ath9k/htc_hst.c
+++ b/drivers/net/wireless/ath/ath9k/htc_hst.c
@@ -462,9 +462,10 @@ void ath9k_htc_hw_free(struct htc_target *htc)
}
int ath9k_htc_hw_init(struct htc_target *target,
- struct device *dev, u16 devid, char *product)
+ struct device *dev, u16 devid,
+ char *product, u32 drv_info)
{
- if (ath9k_htc_probe_device(target, dev, devid, product)) {
+ if (ath9k_htc_probe_device(target, dev, devid, product, drv_info)) {
printk(KERN_ERR "Failed to initialize the device\n");
return -ENODEV;
}
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.h b/drivers/net/wireless/ath/ath9k/htc_hst.h
index 07b6509d5896..ecd018798c47 100644
--- a/drivers/net/wireless/ath/ath9k/htc_hst.h
+++ b/drivers/net/wireless/ath/ath9k/htc_hst.h
@@ -77,20 +77,6 @@ struct htc_config_pipe_msg {
u8 credits;
} __packed;
-struct htc_packet {
- void *pktcontext;
- u8 *buf;
- u8 *buf_payload;
- u32 buflen;
- u32 payload_len;
-
- int endpoint;
- int status;
-
- void *context;
- u32 reserved;
-};
-
struct htc_ep_callbacks {
void *priv;
void (*tx) (void *, struct sk_buff *, enum htc_endpoint_id, bool txok);
@@ -123,11 +109,6 @@ struct htc_endpoint {
#define HTC_CONTROL_BUFFER_SIZE \
(HTC_MAX_CONTROL_MESSAGE_LENGTH + sizeof(struct htc_frame_hdr))
-struct htc_control_buf {
- struct htc_packet htc_pkt;
- u8 buf[HTC_CONTROL_BUFFER_SIZE];
-};
-
#define HTC_OP_START_WAIT BIT(0)
#define HTC_OP_CONFIG_PIPE_CREDITS BIT(1)
@@ -239,7 +220,8 @@ struct htc_target *ath9k_htc_hw_alloc(void *hif_handle,
struct device *dev);
void ath9k_htc_hw_free(struct htc_target *htc);
int ath9k_htc_hw_init(struct htc_target *target,
- struct device *dev, u16 devid, char *product);
+ struct device *dev, u16 devid, char *product,
+ u32 drv_info);
void ath9k_htc_hw_deinit(struct htc_target *target, bool hot_unplug);
#endif /* HTC_HST_H */
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index c7fbe25cc128..516227fa668e 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -129,9 +129,9 @@ bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout)
udelay(AH_TIME_QUANTUM);
}
- ath_print(ath9k_hw_common(ah), ATH_DBG_ANY,
- "timeout (%d us) on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n",
- timeout, reg, REG_READ(ah, reg), mask, val);
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_ANY,
+ "timeout (%d us) on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n",
+ timeout, reg, REG_READ(ah, reg), mask, val);
return false;
}
@@ -211,8 +211,8 @@ u16 ath9k_hw_computetxtime(struct ath_hw *ah,
}
break;
default:
- ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
- "Unknown phy %u (rate ix %u)\n", phy, rateix);
+ ath_err(ath9k_hw_common(ah),
+ "Unknown phy %u (rate ix %u)\n", phy, rateix);
txTime = 0;
break;
}
@@ -310,10 +310,9 @@ static bool ath9k_hw_chip_test(struct ath_hw *ah)
struct ath_common *common = ath9k_hw_common(ah);
u32 regAddr[2] = { AR_STA_ID0 };
u32 regHold[2];
- u32 patternData[4] = { 0x55555555,
- 0xaaaaaaaa,
- 0x66666666,
- 0x99999999 };
+ static const u32 patternData[4] = {
+ 0x55555555, 0xaaaaaaaa, 0x66666666, 0x99999999
+ };
int i, j, loop_max;
if (!AR_SREV_9300_20_OR_LATER(ah)) {
@@ -332,11 +331,9 @@ static bool ath9k_hw_chip_test(struct ath_hw *ah)
REG_WRITE(ah, addr, wrData);
rdData = REG_READ(ah, addr);
if (rdData != wrData) {
- ath_print(common, ATH_DBG_FATAL,
- "address test failed "
- "addr: 0x%08x - wr:0x%08x != "
- "rd:0x%08x\n",
- addr, wrData, rdData);
+ ath_err(common,
+ "address test failed addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
+ addr, wrData, rdData);
return false;
}
}
@@ -345,11 +342,9 @@ static bool ath9k_hw_chip_test(struct ath_hw *ah)
REG_WRITE(ah, addr, wrData);
rdData = REG_READ(ah, addr);
if (wrData != rdData) {
- ath_print(common, ATH_DBG_FATAL,
- "address test failed "
- "addr: 0x%08x - wr:0x%08x != "
- "rd:0x%08x\n",
- addr, wrData, rdData);
+ ath_err(common,
+ "address test failed addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
+ addr, wrData, rdData);
return false;
}
}
@@ -419,10 +414,6 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah)
ah->hw_version.magic = AR5416_MAGIC;
ah->hw_version.subvendorid = 0;
- ah->ah_flags = 0;
- if (!AR_SREV_9100(ah))
- ah->ah_flags = AH_USE_EEPROM;
-
ah->atim_window = 0;
ah->sta_id1_defaults =
AR_STA_ID1_CRPT_MIC_ENABLE |
@@ -440,7 +431,7 @@ static int ath9k_hw_init_macaddr(struct ath_hw *ah)
u32 sum;
int i;
u16 eeval;
- u32 EEP_MAC[] = { EEP_MAC_LSW, EEP_MAC_MID, EEP_MAC_MSW };
+ static const u32 EEP_MAC[] = { EEP_MAC_LSW, EEP_MAC_MID, EEP_MAC_MSW };
sum = 0;
for (i = 0; i < 3; i++) {
@@ -474,16 +465,15 @@ static int ath9k_hw_post_init(struct ath_hw *ah)
if (ecode != 0)
return ecode;
- ath_print(ath9k_hw_common(ah), ATH_DBG_CONFIG,
- "Eeprom VER: %d, REV: %d\n",
- ah->eep_ops->get_eeprom_ver(ah),
- ah->eep_ops->get_eeprom_rev(ah));
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_CONFIG,
+ "Eeprom VER: %d, REV: %d\n",
+ ah->eep_ops->get_eeprom_ver(ah),
+ ah->eep_ops->get_eeprom_rev(ah));
ecode = ath9k_hw_rf_alloc_ext_banks(ah);
if (ecode) {
- ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
- "Failed allocating banks for "
- "external radio\n");
+ ath_err(ath9k_hw_common(ah),
+ "Failed allocating banks for external radio\n");
ath9k_hw_rf_free_ext_banks(ah);
return ecode;
}
@@ -514,8 +504,7 @@ static int __ath9k_hw_init(struct ath_hw *ah)
ah->hw_version.macVersion = AR_SREV_VERSION_9100;
if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) {
- ath_print(common, ATH_DBG_FATAL,
- "Couldn't reset chip\n");
+ ath_err(common, "Couldn't reset chip\n");
return -EIO;
}
@@ -525,7 +514,7 @@ static int __ath9k_hw_init(struct ath_hw *ah)
ath9k_hw_attach_ops(ah);
if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
- ath_print(common, ATH_DBG_FATAL, "Couldn't wakeup chip\n");
+ ath_err(common, "Couldn't wakeup chip\n");
return -EIO;
}
@@ -541,7 +530,7 @@ static int __ath9k_hw_init(struct ath_hw *ah)
}
}
- ath_print(common, ATH_DBG_RESET, "serialize_regmode is %d\n",
+ ath_dbg(common, ATH_DBG_RESET, "serialize_regmode is %d\n",
ah->config.serialize_regmode);
if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
@@ -550,10 +539,9 @@ static int __ath9k_hw_init(struct ath_hw *ah)
ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD;
if (!ath9k_hw_macversion_supported(ah)) {
- ath_print(common, ATH_DBG_FATAL,
- "Mac Chip Rev 0x%02x.%x is not supported by "
- "this driver\n", ah->hw_version.macVersion,
- ah->hw_version.macRev);
+ ath_err(common,
+ "Mac Chip Rev 0x%02x.%x is not supported by this driver\n",
+ ah->hw_version.macVersion, ah->hw_version.macRev);
return -EOPNOTSUPP;
}
@@ -599,8 +587,7 @@ static int __ath9k_hw_init(struct ath_hw *ah)
r = ath9k_hw_init_macaddr(ah);
if (r) {
- ath_print(common, ATH_DBG_FATAL,
- "Failed to initialize MAC address\n");
+ ath_err(common, "Failed to initialize MAC address\n");
return r;
}
@@ -634,21 +621,21 @@ int ath9k_hw_init(struct ath_hw *ah)
case AR9287_DEVID_PCIE:
case AR2427_DEVID_PCIE:
case AR9300_DEVID_PCIE:
+ case AR9300_DEVID_AR9485_PCIE:
break;
default:
if (common->bus_ops->ath_bus_type == ATH_USB)
break;
- ath_print(common, ATH_DBG_FATAL,
- "Hardware device ID 0x%04x not supported\n",
- ah->hw_version.devid);
+ ath_err(common, "Hardware device ID 0x%04x not supported\n",
+ ah->hw_version.devid);
return -EOPNOTSUPP;
}
ret = __ath9k_hw_init(ah);
if (ret) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to initialize hardware; "
- "initialization status: %d\n", ret);
+ ath_err(common,
+ "Unable to initialize hardware; initialization status: %d\n",
+ ret);
return ret;
}
@@ -680,7 +667,12 @@ static void ath9k_hw_init_qos(struct ath_hw *ah)
static void ath9k_hw_init_pll(struct ath_hw *ah,
struct ath9k_channel *chan)
{
- u32 pll = ath9k_hw_compute_pll_control(ah, chan);
+ u32 pll;
+
+ if (AR_SREV_9485(ah))
+ REG_WRITE(ah, AR_RTC_PLL_CONTROL2, 0x886666);
+
+ pll = ath9k_hw_compute_pll_control(ah, chan);
REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll);
@@ -772,8 +764,8 @@ static void ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us)
static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu)
{
if (tu > 0xFFFF) {
- ath_print(ath9k_hw_common(ah), ATH_DBG_XMIT,
- "bad global tx timeout %u\n", tu);
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_XMIT,
+ "bad global tx timeout %u\n", tu);
ah->globaltxtimeout = (u32) -1;
return false;
} else {
@@ -790,8 +782,8 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah)
int slottime;
int sifstime;
- ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, "ah->misc_mode 0x%x\n",
- ah->misc_mode);
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_RESET, "ah->misc_mode 0x%x\n",
+ ah->misc_mode);
if (ah->misc_mode != 0)
REG_WRITE(ah, AR_PCU_MISC,
@@ -1034,8 +1026,8 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
REG_WRITE(ah, AR_RTC_RC, 0);
if (!ath9k_hw_wait(ah, AR_RTC_RC, AR_RTC_RC_M, 0, AH_WAIT_TIMEOUT)) {
- ath_print(ath9k_hw_common(ah), ATH_DBG_RESET,
- "RTC stuck in MAC reset\n");
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_RESET,
+ "RTC stuck in MAC reset\n");
return false;
}
@@ -1081,8 +1073,8 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah)
AR_RTC_STATUS_M,
AR_RTC_STATUS_ON,
AH_WAIT_TIMEOUT)) {
- ath_print(ath9k_hw_common(ah), ATH_DBG_RESET,
- "RTC not waking up\n");
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_RESET,
+ "RTC not waking up\n");
return false;
}
@@ -1142,16 +1134,14 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
if (ath9k_hw_numtxpending(ah, qnum)) {
- ath_print(common, ATH_DBG_QUEUE,
- "Transmit frames pending on "
- "queue %d\n", qnum);
+ ath_dbg(common, ATH_DBG_QUEUE,
+ "Transmit frames pending on queue %d\n", qnum);
return false;
}
}
if (!ath9k_hw_rfbus_req(ah)) {
- ath_print(common, ATH_DBG_FATAL,
- "Could not kill baseband RX\n");
+ ath_err(common, "Could not kill baseband RX\n");
return false;
}
@@ -1159,8 +1149,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
r = ath9k_hw_rf_set_freq(ah, chan);
if (r) {
- ath_print(common, ATH_DBG_FATAL,
- "Failed to set channel\n");
+ ath_err(common, "Failed to set channel\n");
return false;
}
ath9k_hw_set_clockrate(ah);
@@ -1170,7 +1159,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
channel->max_antenna_gain * 2,
channel->max_power * 2,
min((u32) MAX_RATE_POWER,
- (u32) regulatory->power_limit));
+ (u32) regulatory->power_limit), false);
ath9k_hw_rfbus_done(ah);
@@ -1227,7 +1216,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
if (!ah->chip_fullsleep) {
ath9k_hw_abortpcurecv(ah);
if (!ath9k_hw_stopdmarecv(ah)) {
- ath_print(common, ATH_DBG_XMIT,
+ ath_dbg(common, ATH_DBG_XMIT,
"Failed to stop receive dma\n");
bChannelChange = false;
}
@@ -1292,7 +1281,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
}
if (!ath9k_hw_chip_reset(ah, chan)) {
- ath_print(common, ATH_DBG_FATAL, "Chip reset failed\n");
+ ath_err(common, "Chip reset failed\n");
return -EINVAL;
}
@@ -1439,13 +1428,13 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
u32 mask;
mask = REG_READ(ah, AR_CFG);
if (mask & (AR_CFG_SWRB | AR_CFG_SWTB | AR_CFG_SWRG)) {
- ath_print(common, ATH_DBG_RESET,
+ ath_dbg(common, ATH_DBG_RESET,
"CFG Byte Swap Set 0x%x\n", mask);
} else {
mask =
INIT_CONFIG_STATUS | AR_CFG_SWRB | AR_CFG_SWTB;
REG_WRITE(ah, AR_CFG, mask);
- ath_print(common, ATH_DBG_RESET,
+ ath_dbg(common, ATH_DBG_RESET,
"Setting CFG 0x%x\n", REG_READ(ah, AR_CFG));
}
} else {
@@ -1573,9 +1562,9 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip)
AR_RTC_FORCE_WAKE_EN);
}
if (i == 0) {
- ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
- "Failed to wakeup in %uus\n",
- POWER_UP_TIME / 20);
+ ath_err(ath9k_hw_common(ah),
+ "Failed to wakeup in %uus\n",
+ POWER_UP_TIME / 20);
return false;
}
}
@@ -1599,8 +1588,8 @@ bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
if (ah->power_mode == mode)
return status;
- ath_print(common, ATH_DBG_RESET, "%s -> %s\n",
- modes[ah->power_mode], modes[mode]);
+ ath_dbg(common, ATH_DBG_RESET, "%s -> %s\n",
+ modes[ah->power_mode], modes[mode]);
switch (mode) {
case ATH9K_PM_AWAKE:
@@ -1614,12 +1603,18 @@ bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
ath9k_set_power_network_sleep(ah, setChip);
break;
default:
- ath_print(common, ATH_DBG_FATAL,
- "Unknown power mode %u\n", mode);
+ ath_err(common, "Unknown power mode %u\n", mode);
return false;
}
ah->power_mode = mode;
+ /*
+ * XXX: If this warning never comes up after a while then
+ * simply keep the ATH_DBG_WARN_ON_ONCE() but make
+ * ath9k_hw_setpower() return type void.
+ */
+ ATH_DBG_WARN_ON_ONCE(!status);
+
return status;
}
EXPORT_SYMBOL(ath9k_hw_setpower);
@@ -1674,9 +1669,9 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
flags |= AR_TBTT_TIMER_EN;
break;
}
- ath_print(ath9k_hw_common(ah), ATH_DBG_BEACON,
- "%s: unsupported opmode: %d\n",
- __func__, ah->opmode);
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_BEACON,
+ "%s: unsupported opmode: %d\n",
+ __func__, ah->opmode);
return;
break;
}
@@ -1732,10 +1727,10 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
else
nextTbtt = bs->bs_nexttbtt;
- ath_print(common, ATH_DBG_BEACON, "next DTIM %d\n", bs->bs_nextdtim);
- ath_print(common, ATH_DBG_BEACON, "next beacon %d\n", nextTbtt);
- ath_print(common, ATH_DBG_BEACON, "beacon period %d\n", beaconintval);
- ath_print(common, ATH_DBG_BEACON, "DTIM period %d\n", dtimperiod);
+ ath_dbg(common, ATH_DBG_BEACON, "next DTIM %d\n", bs->bs_nextdtim);
+ ath_dbg(common, ATH_DBG_BEACON, "next beacon %d\n", nextTbtt);
+ ath_dbg(common, ATH_DBG_BEACON, "beacon period %d\n", beaconintval);
+ ath_dbg(common, ATH_DBG_BEACON, "DTIM period %d\n", dtimperiod);
ENABLE_REGWRITE_BUFFER(ah);
@@ -1781,7 +1776,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
u16 capField = 0, eeval;
- u8 ant_div_ctl1;
+ u8 ant_div_ctl1, tx_chainmask, rx_chainmask;
eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_0);
regulatory->current_rd = eeval;
@@ -1800,14 +1795,14 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
regulatory->current_rd += 5;
else if (regulatory->current_rd == 0x41)
regulatory->current_rd = 0x43;
- ath_print(common, ATH_DBG_REGULATORY,
- "regdomain mapped to 0x%x\n", regulatory->current_rd);
+ ath_dbg(common, ATH_DBG_REGULATORY,
+ "regdomain mapped to 0x%x\n", regulatory->current_rd);
}
eeval = ah->eep_ops->get_eeprom(ah, EEP_OP_MODE);
if ((eeval & (AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A)) == 0) {
- ath_print(common, ATH_DBG_FATAL,
- "no band has been marked as supported in EEPROM.\n");
+ ath_err(common,
+ "no band has been marked as supported in EEPROM\n");
return -EINVAL;
}
@@ -1833,6 +1828,10 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
ah->misc_mode |= AR_PCU_MIC_NEW_LOC_ENA;
+ /* enable key search for every frame in an aggregate */
+ if (AR_SREV_9300_20_OR_LATER(ah))
+ ah->misc_mode |= AR_PCU_ALWAYS_PERFORM_KEYSEARCH;
+
pCap->low_2ghz_chan = 2312;
pCap->high_2ghz_chan = 2732;
@@ -1926,8 +1925,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
pCap->num_antcfg_2ghz =
ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_2GHZ);
- if (AR_SREV_9280_20_OR_LATER(ah) &&
- ath9k_hw_btcoex_supported(ah)) {
+ if (AR_SREV_9280_20_OR_LATER(ah) && common->btcoex_enabled) {
btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO;
btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO;
@@ -1942,8 +1940,10 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
}
if (AR_SREV_9300_20_OR_LATER(ah)) {
- pCap->hw_caps |= ATH9K_HW_CAP_EDMA | ATH9K_HW_CAP_LDPC |
- ATH9K_HW_CAP_FASTCLOCK;
+ pCap->hw_caps |= ATH9K_HW_CAP_EDMA | ATH9K_HW_CAP_FASTCLOCK;
+ if (!AR_SREV_9485(ah))
+ pCap->hw_caps |= ATH9K_HW_CAP_LDPC;
+
pCap->rx_hp_qdepth = ATH9K_HW_RX_HP_QDEPTH;
pCap->rx_lp_qdepth = ATH9K_HW_RX_LP_QDEPTH;
pCap->rx_status_len = sizeof(struct ar9003_rxs);
@@ -1963,6 +1963,9 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
if (AR_SREV_9300_20_OR_LATER(ah))
pCap->hw_caps |= ATH9K_HW_CAP_RAC_SUPPORTED;
+ if (AR_SREV_9300_20_OR_LATER(ah))
+ ah->ent_mode = REG_READ(ah, AR_ENT_OTP);
+
if (AR_SREV_9287_11_OR_LATER(ah) || AR_SREV_9271(ah))
pCap->hw_caps |= ATH9K_HW_CAP_SGI_20;
@@ -1973,6 +1976,29 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
if ((ant_div_ctl1 & 0x1) && ((ant_div_ctl1 >> 3) & 0x1))
pCap->hw_caps |= ATH9K_HW_CAP_ANT_DIV_COMB;
}
+ if (AR_SREV_9300_20_OR_LATER(ah)) {
+ if (ah->eep_ops->get_eeprom(ah, EEP_CHAIN_MASK_REDUCE))
+ pCap->hw_caps |= ATH9K_HW_CAP_APM;
+ }
+
+
+
+ if (AR_SREV_9485_10(ah)) {
+ pCap->pcie_lcr_extsync_en = true;
+ pCap->pcie_lcr_offset = 0x80;
+ }
+
+ tx_chainmask = pCap->tx_chainmask;
+ rx_chainmask = pCap->rx_chainmask;
+ while (tx_chainmask || rx_chainmask) {
+ if (tx_chainmask & BIT(0))
+ pCap->max_txchains++;
+ if (rx_chainmask & BIT(0))
+ pCap->max_rxchains++;
+
+ tx_chainmask >>= 1;
+ rx_chainmask >>= 1;
+ }
return 0;
}
@@ -2177,7 +2203,7 @@ bool ath9k_hw_disable(struct ath_hw *ah)
}
EXPORT_SYMBOL(ath9k_hw_disable);
-void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit)
+void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test)
{
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
struct ath9k_channel *chan = ah->curchan;
@@ -2190,7 +2216,7 @@ void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit)
channel->max_antenna_gain * 2,
channel->max_power * 2,
min((u32) MAX_RATE_POWER,
- (u32) regulatory->power_limit));
+ (u32) regulatory->power_limit), test);
}
EXPORT_SYMBOL(ath9k_hw_set_txpowerlimit);
@@ -2250,8 +2276,8 @@ void ath9k_hw_reset_tsf(struct ath_hw *ah)
{
if (!ath9k_hw_wait(ah, AR_SLP32_MODE, AR_SLP32_TSF_WRITE_STATUS, 0,
AH_TSF_WRITE_TIMEOUT))
- ath_print(ath9k_hw_common(ah), ATH_DBG_RESET,
- "AR_SLP32_TSF_WRITE_STATUS limit exceeded\n");
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_RESET,
+ "AR_SLP32_TSF_WRITE_STATUS limit exceeded\n");
REG_WRITE(ah, AR_RESET_TSF, AR_RESET_TSF_ONCE);
}
@@ -2324,11 +2350,10 @@ static u32 rightmost_index(struct ath_gen_timer_table *timer_table, u32 *mask)
return timer_table->gen_timer_index[b];
}
-u32 ath9k_hw_gettsf32(struct ath_hw *ah)
+static u32 ath9k_hw_gettsf32(struct ath_hw *ah)
{
return REG_READ(ah, AR_TSF_L32);
}
-EXPORT_SYMBOL(ath9k_hw_gettsf32);
struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah,
void (*trigger)(void *),
@@ -2342,9 +2367,9 @@ struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah,
timer = kzalloc(sizeof(struct ath_gen_timer), GFP_KERNEL);
if (timer == NULL) {
- ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
- "Failed to allocate memory"
- "for hw timer[%d]\n", timer_index);
+ ath_err(ath9k_hw_common(ah),
+ "Failed to allocate memory for hw timer[%d]\n",
+ timer_index);
return NULL;
}
@@ -2373,9 +2398,9 @@ void ath9k_hw_gen_timer_start(struct ath_hw *ah,
tsf = ath9k_hw_gettsf32(ah);
- ath_print(ath9k_hw_common(ah), ATH_DBG_HWTIMER,
- "curent tsf %x period %x"
- "timer_next %x\n", tsf, timer_period, timer_next);
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_HWTIMER,
+ "current tsf %x period %x timer_next %x\n",
+ tsf, timer_period, timer_next);
/*
* Pull timer_next forward if the current TSF already passed it
@@ -2455,8 +2480,8 @@ void ath_gen_timer_isr(struct ath_hw *ah)
index = rightmost_index(timer_table, &thresh_mask);
timer = timer_table->timers[index];
BUG_ON(!timer);
- ath_print(common, ATH_DBG_HWTIMER,
- "TSF overflow for Gen timer %d\n", index);
+ ath_dbg(common, ATH_DBG_HWTIMER,
+ "TSF overflow for Gen timer %d\n", index);
timer->overflow(timer->arg);
}
@@ -2464,8 +2489,8 @@ void ath_gen_timer_isr(struct ath_hw *ah)
index = rightmost_index(timer_table, &trigger_mask);
timer = timer_table->timers[index];
BUG_ON(!timer);
- ath_print(common, ATH_DBG_HWTIMER,
- "Gen timer[%d] trigger\n", index);
+ ath_dbg(common, ATH_DBG_HWTIMER,
+ "Gen timer[%d] trigger\n", index);
timer->trigger(timer->arg);
}
}
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index d47d1b4b6002..d83cc3b4685b 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -30,7 +30,6 @@
#include "btcoex.h"
#include "../regd.h"
-#include "../debug.h"
#define ATHEROS_VENDOR_ID 0x168c
@@ -44,6 +43,7 @@
#define AR9287_DEVID_PCI 0x002d
#define AR9287_DEVID_PCIE 0x002e
#define AR9300_DEVID_PCIE 0x0030
+#define AR9300_DEVID_AR9485_PCIE 0x0032
#define AR5416_AR9100_DEVID 0x000b
@@ -157,6 +157,13 @@
#define PAPRD_GAIN_TABLE_ENTRIES 32
#define PAPRD_TABLE_SZ 24
+enum ath_hw_txq_subtype {
+ ATH_TXQ_AC_BE = 0,
+ ATH_TXQ_AC_BK = 1,
+ ATH_TXQ_AC_VI = 2,
+ ATH_TXQ_AC_VO = 3,
+};
+
enum ath_ini_subsys {
ATH_INI_PRE = 0,
ATH_INI_CORE,
@@ -180,6 +187,7 @@ enum ath9k_hw_caps {
ATH9K_HW_CAP_ANT_DIV_COMB = BIT(12),
ATH9K_HW_CAP_2GHZ = BIT(13),
ATH9K_HW_CAP_5GHZ = BIT(14),
+ ATH9K_HW_CAP_APM = BIT(15),
};
struct ath9k_hw_capabilities {
@@ -191,6 +199,8 @@ struct ath9k_hw_capabilities {
u16 rts_aggr_limit;
u8 tx_chainmask;
u8 rx_chainmask;
+ u8 max_txchains;
+ u8 max_rxchains;
u16 tx_triglevel_max;
u16 reg_cap;
u8 num_gpio_pins;
@@ -201,6 +211,8 @@ struct ath9k_hw_capabilities {
u8 rx_status_len;
u8 tx_desc_len;
u8 txs_len;
+ u16 pcie_lcr_offset;
+ bool pcie_lcr_extsync_en;
};
struct ath9k_ops_config {
@@ -434,6 +446,7 @@ struct ath9k_hw_version {
u16 analog5GhzRev;
u16 analog2GhzRev;
u16 subsysid;
+ enum ath_usb_dev usbdev;
};
/* Generic TSF timer definitions */
@@ -478,6 +491,40 @@ struct ath_hw_antcomb_conf {
};
/**
+ * struct ath_hw_radar_conf - radar detection initialization parameters
+ *
+ * @pulse_inband: threshold for checking the ratio of in-band power
+ * to total power for short radar pulses (half dB steps)
+ * @pulse_inband_step: threshold for checking an in-band power to total
+ * power ratio increase for short radar pulses (half dB steps)
+ * @pulse_height: threshold for detecting the beginning of a short
+ * radar pulse (dB step)
+ * @pulse_rssi: threshold for detecting if a short radar pulse is
+ * gone (dB step)
+ * @pulse_maxlen: maximum pulse length (0.8 us steps)
+ *
+ * @radar_rssi: RSSI threshold for starting long radar detection (dB steps)
+ * @radar_inband: threshold for checking the ratio of in-band power
+ * to total power for long radar pulses (half dB steps)
+ * @fir_power: threshold for detecting the end of a long radar pulse (dB)
+ *
+ * @ext_channel: enable extension channel radar detection
+ */
+struct ath_hw_radar_conf {
+ unsigned int pulse_inband;
+ unsigned int pulse_inband_step;
+ unsigned int pulse_height;
+ unsigned int pulse_rssi;
+ unsigned int pulse_maxlen;
+
+ unsigned int radar_rssi;
+ unsigned int radar_inband;
+ int fir_power;
+
+ bool ext_channel;
+};
+
+/**
* struct ath_hw_private_ops - callbacks used internally by hardware code
*
* This structure contains private callbacks designed to only be used internally
@@ -542,6 +589,8 @@ struct ath_hw_private_ops {
bool (*ani_control)(struct ath_hw *ah, enum ath9k_ani_cmd cmd,
int param);
void (*do_getnf)(struct ath_hw *ah, int16_t nfarray[NUM_NF_READINGS]);
+ void (*set_radar_params)(struct ath_hw *ah,
+ struct ath_hw_radar_conf *conf);
/* ANI */
void (*ani_cache_ini_regs)(struct ath_hw *ah);
@@ -740,6 +789,8 @@ struct ath_hw {
u8 txchainmask;
u8 rxchainmask;
+ struct ath_hw_radar_conf radar_conf;
+
u32 originalGain[22];
int initPDADC;
int PDADCdelta;
@@ -797,6 +848,9 @@ struct ath_hw {
* this register when in sleep states.
*/
u32 WARegVal;
+
+ /* Enterprise mode cap */
+ u32 ent_mode;
};
static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah)
@@ -819,12 +873,6 @@ static inline struct ath_hw_ops *ath9k_hw_ops(struct ath_hw *ah)
return &ah->ops;
}
-static inline int sign_extend(int val, const int nbits)
-{
- int order = BIT(nbits-1);
- return (val ^ order) - order;
-}
-
/* Initialization, Detach, Reset */
const char *ath9k_hw_probe(u16 vendorid, u16 devid);
void ath9k_hw_deinit(struct ath_hw *ah);
@@ -861,7 +909,7 @@ u32 ath9k_hw_getrxfilter(struct ath_hw *ah);
void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits);
bool ath9k_hw_phy_disable(struct ath_hw *ah);
bool ath9k_hw_disable(struct ath_hw *ah);
-void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit);
+void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test);
void ath9k_hw_setopmode(struct ath_hw *ah);
void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1);
void ath9k_hw_setbssidmask(struct ath_hw *ah);
@@ -893,7 +941,6 @@ void ath9k_hw_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer);
void ath_gen_timer_free(struct ath_hw *ah, struct ath_gen_timer *timer);
void ath_gen_timer_isr(struct ath_hw *hw);
-u32 ath9k_hw_gettsf32(struct ath_hw *ah);
void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len);
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 14b8ab386daf..b2983ce19dfb 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -37,6 +37,10 @@ int led_blink;
module_param_named(blink, led_blink, int, 0444);
MODULE_PARM_DESC(blink, "Enable LED blink on activity");
+static int ath9k_btcoex_enable;
+module_param_named(btcoex_enable, ath9k_btcoex_enable, int, 0444);
+MODULE_PARM_DESC(btcoex_enable, "Enable wifi-BT coexistence");
+
/* We use the hw_value as an index into our private channel structure */
#define CHAN2G(_freq, _idx) { \
@@ -206,7 +210,9 @@ static void setup_ht_cap(struct ath_softc *sc,
ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
- if (AR_SREV_9300_20_OR_LATER(ah))
+ if (AR_SREV_9485(ah))
+ max_streams = 1;
+ else if (AR_SREV_9300_20_OR_LATER(ah))
max_streams = 3;
else
max_streams = 2;
@@ -222,9 +228,9 @@ static void setup_ht_cap(struct ath_softc *sc,
tx_streams = ath9k_cmn_count_streams(common->tx_chainmask, max_streams);
rx_streams = ath9k_cmn_count_streams(common->rx_chainmask, max_streams);
- ath_print(common, ATH_DBG_CONFIG,
- "TX streams %d, RX streams: %d\n",
- tx_streams, rx_streams);
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "TX streams %d, RX streams: %d\n",
+ tx_streams, rx_streams);
if (tx_streams != rx_streams) {
ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF;
@@ -267,8 +273,8 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
struct ath_buf *bf;
int i, bsize, error, desc_len;
- ath_print(common, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n",
- name, nbuf, ndesc);
+ ath_dbg(common, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n",
+ name, nbuf, ndesc);
INIT_LIST_HEAD(head);
@@ -279,8 +285,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
/* ath_desc must be a multiple of DWORDs */
if ((desc_len % 4) != 0) {
- ath_print(common, ATH_DBG_FATAL,
- "ath_desc not DWORD aligned\n");
+ ath_err(common, "ath_desc not DWORD aligned\n");
BUG_ON((desc_len % 4) != 0);
error = -ENOMEM;
goto fail;
@@ -314,9 +319,9 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
goto fail;
}
ds = (u8 *) dd->dd_desc;
- ath_print(common, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n",
- name, ds, (u32) dd->dd_desc_len,
- ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len);
+ ath_dbg(common, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n",
+ name, ds, (u32) dd->dd_desc_len,
+ ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len);
/* allocate buffers */
bsize = sizeof(struct ath_buf) * nbuf;
@@ -370,9 +375,9 @@ static void ath9k_init_crypto(struct ath_softc *sc)
/* Get the hardware key cache size. */
common->keymax = sc->sc_ah->caps.keycache_size;
if (common->keymax > ATH_KEYMAX) {
- ath_print(common, ATH_DBG_ANY,
- "Warning, using only %u entries in %u key cache\n",
- ATH_KEYMAX, common->keymax);
+ ath_dbg(common, ATH_DBG_ANY,
+ "Warning, using only %u entries in %u key cache\n",
+ ATH_KEYMAX, common->keymax);
common->keymax = ATH_KEYMAX;
}
@@ -395,7 +400,8 @@ static void ath9k_init_crypto(struct ath_softc *sc)
static int ath9k_init_btcoex(struct ath_softc *sc)
{
- int r, qnum;
+ struct ath_txq *txq;
+ int r;
switch (sc->sc_ah->btcoex_hw.scheme) {
case ATH_BTCOEX_CFG_NONE:
@@ -408,8 +414,8 @@ static int ath9k_init_btcoex(struct ath_softc *sc)
r = ath_init_btcoex_timer(sc);
if (r)
return -1;
- qnum = sc->tx.hwq_map[WME_AC_BE];
- ath9k_hw_init_btcoex_hw(sc->sc_ah, qnum);
+ txq = sc->tx.txq_map[WME_AC_BE];
+ ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum);
sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
break;
default:
@@ -422,59 +428,18 @@ static int ath9k_init_btcoex(struct ath_softc *sc)
static int ath9k_init_queues(struct ath_softc *sc)
{
- struct ath_common *common = ath9k_hw_common(sc->sc_ah);
int i = 0;
- for (i = 0; i < ARRAY_SIZE(sc->tx.hwq_map); i++)
- sc->tx.hwq_map[i] = -1;
-
sc->beacon.beaconq = ath9k_hw_beaconq_setup(sc->sc_ah);
- if (sc->beacon.beaconq == -1) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to setup a beacon xmit queue\n");
- goto err;
- }
-
sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0);
- if (sc->beacon.cabq == NULL) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to setup CAB xmit queue\n");
- goto err;
- }
sc->config.cabqReadytime = ATH_CABQ_READY_TIME;
ath_cabq_update(sc);
- if (!ath_tx_setup(sc, WME_AC_BK)) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to setup xmit queue for BK traffic\n");
- goto err;
- }
-
- if (!ath_tx_setup(sc, WME_AC_BE)) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to setup xmit queue for BE traffic\n");
- goto err;
- }
- if (!ath_tx_setup(sc, WME_AC_VI)) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to setup xmit queue for VI traffic\n");
- goto err;
- }
- if (!ath_tx_setup(sc, WME_AC_VO)) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to setup xmit queue for VO traffic\n");
- goto err;
- }
+ for (i = 0; i < WME_NUM_AC; i++)
+ sc->tx.txq_map[i] = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, i);
return 0;
-
-err:
- for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
- if (ATH_TXQ_SETUP(sc, i))
- ath_tx_cleanupq(sc, &sc->tx.txq[i]);
-
- return -EIO;
}
static int ath9k_init_channels_rates(struct ath_softc *sc)
@@ -570,6 +535,9 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
ah->hw_version.subsysid = subsysid;
sc->sc_ah = ah;
+ if (!sc->dev->platform_data)
+ ah->ah_flags |= AH_USE_EEPROM;
+
common = ath9k_hw_common(ah);
common->ops = &ath9k_common_ops;
common->bus_ops = bus_ops;
@@ -577,10 +545,10 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
common->hw = sc->hw;
common->priv = sc;
common->debug_mask = ath9k_debug;
+ common->btcoex_enabled = ath9k_btcoex_enable == 1;
spin_lock_init(&common->cc_lock);
spin_lock_init(&sc->wiphy_lock);
- spin_lock_init(&sc->sc_resetlock);
spin_lock_init(&sc->sc_serial_rw);
spin_lock_init(&sc->sc_pm_lock);
mutex_init(&sc->mutex);
@@ -600,13 +568,6 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
if (ret)
goto err_hw;
- ret = ath9k_init_debug(ah);
- if (ret) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to create debugfs files\n");
- goto err_debug;
- }
-
ret = ath9k_init_queues(sc);
if (ret)
goto err_queues;
@@ -629,8 +590,6 @@ err_btcoex:
if (ATH_TXQ_SETUP(sc, i))
ath_tx_cleanupq(sc, &sc->tx.txq[i]);
err_queues:
- ath9k_exit_debug(ah);
-err_debug:
ath9k_hw_deinit(ah);
err_hw:
tasklet_kill(&sc->intr_tq);
@@ -642,6 +601,37 @@ err_hw:
return ret;
}
+static void ath9k_init_band_txpower(struct ath_softc *sc, int band)
+{
+ struct ieee80211_supported_band *sband;
+ struct ieee80211_channel *chan;
+ struct ath_hw *ah = sc->sc_ah;
+ struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
+ int i;
+
+ sband = &sc->sbands[band];
+ for (i = 0; i < sband->n_channels; i++) {
+ chan = &sband->channels[i];
+ ah->curchan = &ah->channels[chan->hw_value];
+ ath9k_cmn_update_ichannel(ah->curchan, chan, NL80211_CHAN_HT20);
+ ath9k_hw_set_txpowerlimit(ah, MAX_RATE_POWER, true);
+ chan->max_power = reg->max_power_level / 2;
+ }
+}
+
+static void ath9k_init_txpower_limits(struct ath_softc *sc)
+{
+ struct ath_hw *ah = sc->sc_ah;
+ struct ath9k_channel *curchan = ah->curchan;
+
+ if (ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
+ ath9k_init_band_txpower(sc, IEEE80211_BAND_2GHZ);
+ if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
+ ath9k_init_band_txpower(sc, IEEE80211_BAND_5GHZ);
+
+ ah->curchan = curchan;
+}
+
void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
{
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
@@ -652,7 +642,8 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
IEEE80211_HW_SUPPORTS_PS |
IEEE80211_HW_PS_NULLFUNC_STACK |
IEEE80211_HW_SPECTRUM_MGMT |
- IEEE80211_HW_REPORTS_TX_ACK_STATUS;
+ IEEE80211_HW_REPORTS_TX_ACK_STATUS |
+ IEEE80211_HW_NEED_DTIM_PERIOD;
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
@@ -705,6 +696,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
const struct ath_bus_ops *bus_ops)
{
struct ieee80211_hw *hw = sc->hw;
+ struct ath_wiphy *aphy = hw->priv;
struct ath_common *common;
struct ath_hw *ah;
int error = 0;
@@ -737,11 +729,19 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
if (error != 0)
goto error_rx;
+ ath9k_init_txpower_limits(sc);
+
/* Register with mac80211 */
error = ieee80211_register_hw(hw);
if (error)
goto error_register;
+ error = ath9k_init_debug(ah);
+ if (error) {
+ ath_err(common, "Unable to create debugfs files\n");
+ goto error_world;
+ }
+
/* Handle world regulatory */
if (!ath_is_world_regd(reg)) {
error = regulatory_hint(hw->wiphy, reg->alpha2);
@@ -754,6 +754,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work);
INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work);
sc->wiphy_scheduler_int = msecs_to_jiffies(500);
+ aphy->last_rssi = ATH_RSSI_DUMMY_MARKER;
ath_init_leds(sc);
ath_start_rfkill_poll(sc);
@@ -799,7 +800,6 @@ static void ath9k_deinit_softc(struct ath_softc *sc)
if (ATH_TXQ_SETUP(sc, i))
ath_tx_cleanupq(sc, &sc->tx.txq[i]);
- ath9k_exit_debug(sc->sc_ah);
ath9k_hw_deinit(sc->sc_ah);
tasklet_kill(&sc->intr_tq);
@@ -866,20 +866,12 @@ static int __init ath9k_init(void)
goto err_out;
}
- error = ath9k_debug_create_root();
- if (error) {
- printk(KERN_ERR
- "ath9k: Unable to create debugfs root: %d\n",
- error);
- goto err_rate_unregister;
- }
-
error = ath_pci_init();
if (error < 0) {
printk(KERN_ERR
"ath9k: No PCI devices found, driver not installed.\n");
error = -ENODEV;
- goto err_remove_root;
+ goto err_rate_unregister;
}
error = ath_ahb_init();
@@ -893,8 +885,6 @@ static int __init ath9k_init(void)
err_pci_exit:
ath_pci_exit();
- err_remove_root:
- ath9k_debug_remove_root();
err_rate_unregister:
ath_rate_control_unregister();
err_out:
@@ -906,7 +896,6 @@ static void __exit ath9k_exit(void)
{
ath_ahb_exit();
ath_pci_exit();
- ath9k_debug_remove_root();
ath_rate_control_unregister();
printk(KERN_INFO "%s: Driver unloaded\n", dev_info);
}
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index c996963ab339..e3d2ebf00e2e 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -20,11 +20,11 @@
static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah,
struct ath9k_tx_queue_info *qi)
{
- ath_print(ath9k_hw_common(ah), ATH_DBG_INTERRUPT,
- "tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n",
- ah->txok_interrupt_mask, ah->txerr_interrupt_mask,
- ah->txdesc_interrupt_mask, ah->txeol_interrupt_mask,
- ah->txurn_interrupt_mask);
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_INTERRUPT,
+ "tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n",
+ ah->txok_interrupt_mask, ah->txerr_interrupt_mask,
+ ah->txdesc_interrupt_mask, ah->txeol_interrupt_mask,
+ ah->txurn_interrupt_mask);
ENABLE_REGWRITE_BUFFER(ah);
@@ -56,8 +56,8 @@ EXPORT_SYMBOL(ath9k_hw_puttxbuf);
void ath9k_hw_txstart(struct ath_hw *ah, u32 q)
{
- ath_print(ath9k_hw_common(ah), ATH_DBG_QUEUE,
- "Enable TXE on queue: %u\n", q);
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_QUEUE,
+ "Enable TXE on queue: %u\n", q);
REG_WRITE(ah, AR_Q_TXE, 1 << q);
}
EXPORT_SYMBOL(ath9k_hw_txstart);
@@ -117,12 +117,11 @@ EXPORT_SYMBOL(ath9k_hw_numtxpending);
bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel)
{
u32 txcfg, curLevel, newLevel;
- enum ath9k_int omask;
if (ah->tx_trig_level >= ah->config.max_txtrig_level)
return false;
- omask = ath9k_hw_set_interrupts(ah, ah->imask & ~ATH9K_INT_GLOBAL);
+ ath9k_hw_disable_interrupts(ah);
txcfg = REG_READ(ah, AR_TXCFG);
curLevel = MS(txcfg, AR_FTRIG);
@@ -136,7 +135,7 @@ bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel)
REG_WRITE(ah, AR_TXCFG,
(txcfg & ~AR_FTRIG) | SM(newLevel, AR_FTRIG));
- ath9k_hw_set_interrupts(ah, omask);
+ ath9k_hw_enable_interrupts(ah);
ah->tx_trig_level = newLevel;
@@ -155,15 +154,15 @@ bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q)
u32 wait_time = ATH9K_TX_STOP_DMA_TIMEOUT / ATH9K_TIME_QUANTUM;
if (q >= pCap->total_queues) {
- ath_print(common, ATH_DBG_QUEUE, "Stopping TX DMA, "
- "invalid queue: %u\n", q);
+ ath_dbg(common, ATH_DBG_QUEUE,
+ "Stopping TX DMA, invalid queue: %u\n", q);
return false;
}
qi = &ah->txq[q];
if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
- ath_print(common, ATH_DBG_QUEUE, "Stopping TX DMA, "
- "inactive queue: %u\n", q);
+ ath_dbg(common, ATH_DBG_QUEUE,
+ "Stopping TX DMA, inactive queue: %u\n", q);
return false;
}
@@ -176,9 +175,9 @@ bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q)
}
if (ath9k_hw_numtxpending(ah, q)) {
- ath_print(common, ATH_DBG_QUEUE,
- "%s: Num of pending TX Frames %d on Q %d\n",
- __func__, ath9k_hw_numtxpending(ah, q), q);
+ ath_dbg(common, ATH_DBG_QUEUE,
+ "%s: Num of pending TX Frames %d on Q %d\n",
+ __func__, ath9k_hw_numtxpending(ah, q), q);
for (j = 0; j < 2; j++) {
tsfLow = REG_READ(ah, AR_TSF_L32);
@@ -192,9 +191,9 @@ bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q)
if ((REG_READ(ah, AR_TSF_L32) >> 10) == (tsfLow >> 10))
break;
- ath_print(common, ATH_DBG_QUEUE,
- "TSF has moved while trying to set "
- "quiet time TSF: 0x%08x\n", tsfLow);
+ ath_dbg(common, ATH_DBG_QUEUE,
+ "TSF has moved while trying to set quiet time TSF: 0x%08x\n",
+ tsfLow);
}
REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
@@ -205,9 +204,8 @@ bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q)
wait = wait_time;
while (ath9k_hw_numtxpending(ah, q)) {
if ((--wait) == 0) {
- ath_print(common, ATH_DBG_FATAL,
- "Failed to stop TX DMA in 100 "
- "msec after killing last frame\n");
+ ath_err(common,
+ "Failed to stop TX DMA in 100 msec after killing last frame\n");
break;
}
udelay(ATH9K_TIME_QUANTUM);
@@ -240,19 +238,19 @@ bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q,
struct ath9k_tx_queue_info *qi;
if (q >= pCap->total_queues) {
- ath_print(common, ATH_DBG_QUEUE, "Set TXQ properties, "
- "invalid queue: %u\n", q);
+ ath_dbg(common, ATH_DBG_QUEUE,
+ "Set TXQ properties, invalid queue: %u\n", q);
return false;
}
qi = &ah->txq[q];
if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
- ath_print(common, ATH_DBG_QUEUE, "Set TXQ properties, "
- "inactive queue: %u\n", q);
+ ath_dbg(common, ATH_DBG_QUEUE,
+ "Set TXQ properties, inactive queue: %u\n", q);
return false;
}
- ath_print(common, ATH_DBG_QUEUE, "Set queue properties for: %u\n", q);
+ ath_dbg(common, ATH_DBG_QUEUE, "Set queue properties for: %u\n", q);
qi->tqi_ver = qinfo->tqi_ver;
qi->tqi_subtype = qinfo->tqi_subtype;
@@ -311,15 +309,15 @@ bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q,
struct ath9k_tx_queue_info *qi;
if (q >= pCap->total_queues) {
- ath_print(common, ATH_DBG_QUEUE, "Get TXQ properties, "
- "invalid queue: %u\n", q);
+ ath_dbg(common, ATH_DBG_QUEUE,
+ "Get TXQ properties, invalid queue: %u\n", q);
return false;
}
qi = &ah->txq[q];
if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
- ath_print(common, ATH_DBG_QUEUE, "Get TXQ properties, "
- "inactive queue: %u\n", q);
+ ath_dbg(common, ATH_DBG_QUEUE,
+ "Get TXQ properties, inactive queue: %u\n", q);
return false;
}
@@ -369,23 +367,20 @@ int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type,
ATH9K_TX_QUEUE_INACTIVE)
break;
if (q == pCap->total_queues) {
- ath_print(common, ATH_DBG_FATAL,
- "No available TX queue\n");
+ ath_err(common, "No available TX queue\n");
return -1;
}
break;
default:
- ath_print(common, ATH_DBG_FATAL,
- "Invalid TX queue type: %u\n", type);
+ ath_err(common, "Invalid TX queue type: %u\n", type);
return -1;
}
- ath_print(common, ATH_DBG_QUEUE, "Setup TX queue: %u\n", q);
+ ath_dbg(common, ATH_DBG_QUEUE, "Setup TX queue: %u\n", q);
qi = &ah->txq[q];
if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) {
- ath_print(common, ATH_DBG_FATAL,
- "TX queue: %u already active\n", q);
+ ath_err(common, "TX queue: %u already active\n", q);
return -1;
}
memset(qi, 0, sizeof(struct ath9k_tx_queue_info));
@@ -417,18 +412,18 @@ bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q)
struct ath9k_tx_queue_info *qi;
if (q >= pCap->total_queues) {
- ath_print(common, ATH_DBG_QUEUE, "Release TXQ, "
- "invalid queue: %u\n", q);
+ ath_dbg(common, ATH_DBG_QUEUE,
+ "Release TXQ, invalid queue: %u\n", q);
return false;
}
qi = &ah->txq[q];
if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
- ath_print(common, ATH_DBG_QUEUE, "Release TXQ, "
- "inactive queue: %u\n", q);
+ ath_dbg(common, ATH_DBG_QUEUE,
+ "Release TXQ, inactive queue: %u\n", q);
return false;
}
- ath_print(common, ATH_DBG_QUEUE, "Release TX queue: %u\n", q);
+ ath_dbg(common, ATH_DBG_QUEUE, "Release TX queue: %u\n", q);
qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE;
ah->txok_interrupt_mask &= ~(1 << q);
@@ -451,19 +446,19 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
u32 cwMin, chanCwMin, value;
if (q >= pCap->total_queues) {
- ath_print(common, ATH_DBG_QUEUE, "Reset TXQ, "
- "invalid queue: %u\n", q);
+ ath_dbg(common, ATH_DBG_QUEUE,
+ "Reset TXQ, invalid queue: %u\n", q);
return false;
}
qi = &ah->txq[q];
if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
- ath_print(common, ATH_DBG_QUEUE, "Reset TXQ, "
- "inactive queue: %u\n", q);
+ ath_dbg(common, ATH_DBG_QUEUE,
+ "Reset TXQ, inactive queue: %u\n", q);
return true;
}
- ath_print(common, ATH_DBG_QUEUE, "Reset TX queue: %u\n", q);
+ ath_dbg(common, ATH_DBG_QUEUE, "Reset TX queue: %u\n", q);
if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) {
if (chan && IS_CHAN_B(chan))
@@ -735,9 +730,9 @@ bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set)
AR_DIAG_RX_ABORT));
reg = REG_READ(ah, AR_OBS_BUS_1);
- ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
- "RX failed to go idle in 10 ms RXSM=0x%x\n",
- reg);
+ ath_err(ath9k_hw_common(ah),
+ "RX failed to go idle in 10 ms RXSM=0x%x\n",
+ reg);
return false;
}
@@ -766,14 +761,6 @@ void ath9k_hw_startpcureceive(struct ath_hw *ah, bool is_scanning)
}
EXPORT_SYMBOL(ath9k_hw_startpcureceive);
-void ath9k_hw_stoppcurecv(struct ath_hw *ah)
-{
- REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
-
- ath9k_hw_disable_mib_counters(ah);
-}
-EXPORT_SYMBOL(ath9k_hw_stoppcurecv);
-
void ath9k_hw_abortpcurecv(struct ath_hw *ah)
{
REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_ABORT | AR_DIAG_RX_DIS);
@@ -799,12 +786,11 @@ bool ath9k_hw_stopdmarecv(struct ath_hw *ah)
}
if (i == 0) {
- ath_print(common, ATH_DBG_FATAL,
- "DMA failed to stop in %d ms "
- "AR_CR=0x%08x AR_DIAG_SW=0x%08x\n",
- AH_RX_STOP_DMA_TIMEOUT / 1000,
- REG_READ(ah, AR_CR),
- REG_READ(ah, AR_DIAG_SW));
+ ath_err(common,
+ "DMA failed to stop in %d ms AR_CR=0x%08x AR_DIAG_SW=0x%08x\n",
+ AH_RX_STOP_DMA_TIMEOUT / 1000,
+ REG_READ(ah, AR_CR),
+ REG_READ(ah, AR_DIAG_SW));
return false;
} else {
return true;
@@ -848,28 +834,59 @@ bool ath9k_hw_intrpend(struct ath_hw *ah)
}
EXPORT_SYMBOL(ath9k_hw_intrpend);
-enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah,
- enum ath9k_int ints)
+void ath9k_hw_disable_interrupts(struct ath_hw *ah)
+{
+ struct ath_common *common = ath9k_hw_common(ah);
+
+ ath_dbg(common, ATH_DBG_INTERRUPT, "disable IER\n");
+ REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
+ (void) REG_READ(ah, AR_IER);
+ if (!AR_SREV_9100(ah)) {
+ REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0);
+ (void) REG_READ(ah, AR_INTR_ASYNC_ENABLE);
+
+ REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
+ (void) REG_READ(ah, AR_INTR_SYNC_ENABLE);
+ }
+}
+EXPORT_SYMBOL(ath9k_hw_disable_interrupts);
+
+void ath9k_hw_enable_interrupts(struct ath_hw *ah)
+{
+ struct ath_common *common = ath9k_hw_common(ah);
+
+ if (!(ah->imask & ATH9K_INT_GLOBAL))
+ return;
+
+ ath_dbg(common, ATH_DBG_INTERRUPT, "enable IER\n");
+ REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
+ if (!AR_SREV_9100(ah)) {
+ REG_WRITE(ah, AR_INTR_ASYNC_ENABLE,
+ AR_INTR_MAC_IRQ);
+ REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);
+
+
+ REG_WRITE(ah, AR_INTR_SYNC_ENABLE,
+ AR_INTR_SYNC_DEFAULT);
+ REG_WRITE(ah, AR_INTR_SYNC_MASK,
+ AR_INTR_SYNC_DEFAULT);
+ }
+ ath_dbg(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
+ REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
+}
+EXPORT_SYMBOL(ath9k_hw_enable_interrupts);
+
+void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
{
enum ath9k_int omask = ah->imask;
u32 mask, mask2;
struct ath9k_hw_capabilities *pCap = &ah->caps;
struct ath_common *common = ath9k_hw_common(ah);
- ath_print(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints);
+ if (!(ints & ATH9K_INT_GLOBAL))
+ ath9k_hw_enable_interrupts(ah);
- if (omask & ATH9K_INT_GLOBAL) {
- ath_print(common, ATH_DBG_INTERRUPT, "disable IER\n");
- REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
- (void) REG_READ(ah, AR_IER);
- if (!AR_SREV_9100(ah)) {
- REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0);
- (void) REG_READ(ah, AR_INTR_ASYNC_ENABLE);
-
- REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
- (void) REG_READ(ah, AR_INTR_SYNC_ENABLE);
- }
- }
+ ath_dbg(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints);
/* TODO: global int Ref count */
mask = ints & ATH9K_INT_COMMON;
@@ -930,7 +947,7 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah,
mask2 |= AR_IMR_S2_CST;
}
- ath_print(common, ATH_DBG_INTERRUPT, "new IMR 0x%x\n", mask);
+ ath_dbg(common, ATH_DBG_INTERRUPT, "new IMR 0x%x\n", mask);
REG_WRITE(ah, AR_IMR, mask);
ah->imrs2_reg &= ~(AR_IMR_S2_TIM | AR_IMR_S2_DTIM | AR_IMR_S2_DTIMSYNC |
AR_IMR_S2_CABEND | AR_IMR_S2_CABTO |
@@ -945,24 +962,8 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah,
REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
}
- if (ints & ATH9K_INT_GLOBAL) {
- ath_print(common, ATH_DBG_INTERRUPT, "enable IER\n");
- REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
- if (!AR_SREV_9100(ah)) {
- REG_WRITE(ah, AR_INTR_ASYNC_ENABLE,
- AR_INTR_MAC_IRQ);
- REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);
-
-
- REG_WRITE(ah, AR_INTR_SYNC_ENABLE,
- AR_INTR_SYNC_DEFAULT);
- REG_WRITE(ah, AR_INTR_SYNC_MASK,
- AR_INTR_SYNC_DEFAULT);
- }
- ath_print(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
- REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
- }
+ ath9k_hw_enable_interrupts(ah);
- return omask;
+ return;
}
EXPORT_SYMBOL(ath9k_hw_set_interrupts);
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index 7c1a34d64f6d..7512f97e8f49 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -104,13 +104,11 @@ struct ath_tx_status {
u32 ts_tstamp;
u16 ts_seqnum;
u8 ts_status;
- u8 ts_ratecode;
u8 ts_rateindex;
int8_t ts_rssi;
u8 ts_shortretry;
u8 ts_longretry;
u8 ts_virtcol;
- u8 ts_antenna;
u8 ts_flags;
int8_t ts_rssi_ctl0;
int8_t ts_rssi_ctl1;
@@ -121,7 +119,6 @@ struct ath_tx_status {
u8 qid;
u16 desc_id;
u8 tid;
- u8 pad[2];
u32 ba_low;
u32 ba_high;
u32 evm0;
@@ -240,7 +237,7 @@ struct ath_desc {
u32 ds_ctl1;
u32 ds_hw[20];
void *ds_vdata;
-} __packed;
+} __packed __aligned(4);
#define ATH9K_TXDESC_CLRDMASK 0x0001
#define ATH9K_TXDESC_NOACK 0x0002
@@ -310,7 +307,7 @@ struct ar5416_desc {
u32 status8;
} rx;
} u;
-} __packed;
+} __packed __aligned(4);
#define AR5416DESC(_ds) ((struct ar5416_desc *)(_ds))
#define AR5416DESC_CONST(_ds) ((const struct ar5416_desc *)(_ds))
@@ -669,6 +666,7 @@ enum ath9k_key_type {
struct ath_hw;
struct ath9k_channel;
+enum ath9k_int;
u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q);
void ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp);
@@ -693,15 +691,15 @@ void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set);
void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp);
void ath9k_hw_startpcureceive(struct ath_hw *ah, bool is_scanning);
-void ath9k_hw_stoppcurecv(struct ath_hw *ah);
void ath9k_hw_abortpcurecv(struct ath_hw *ah);
bool ath9k_hw_stopdmarecv(struct ath_hw *ah);
int ath9k_hw_beaconq_setup(struct ath_hw *ah);
/* Interrupt Handling */
bool ath9k_hw_intrpend(struct ath_hw *ah);
-enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah,
- enum ath9k_int ints);
+void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints);
+void ath9k_hw_enable_interrupts(struct ath_hw *ah);
+void ath9k_hw_disable_interrupts(struct ath_hw *ah);
void ar9002_hw_attach_mac_ops(struct ath_hw *ah);
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index c0c3464d3a86..daa3c9feca66 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -23,7 +23,7 @@ static void ath_update_txpow(struct ath_softc *sc)
struct ath_hw *ah = sc->sc_ah;
if (sc->curtxpow != sc->config.txpowlimit) {
- ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit);
+ ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit, false);
/* read back in case value is clamped */
sc->curtxpow = ath9k_hw_regulatory(ah)->power_limit;
}
@@ -234,6 +234,8 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
ath9k_ps_wakeup(sc);
+ spin_lock_bh(&sc->sc_pcu_lock);
+
/*
* This is only performed if the channel settings have
* actually changed.
@@ -243,11 +245,9 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
* hardware at the new frequency, and then re-enable
* the relevant bits of the h/w.
*/
- ath9k_hw_set_interrupts(ah, 0);
+ ath9k_hw_disable_interrupts(ah);
stopped = ath_drain_all_txq(sc, false);
- spin_lock_bh(&sc->rx.pcu_lock);
-
if (!ath_stoprecv(sc))
stopped = false;
@@ -261,36 +261,26 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
if (!(sc->sc_flags & SC_OP_OFFCHANNEL))
caldata = &aphy->caldata;
- ath_print(common, ATH_DBG_CONFIG,
- "(%u MHz) -> (%u MHz), conf_is_ht40: %d fastcc: %d\n",
- sc->sc_ah->curchan->channel,
- channel->center_freq, conf_is_ht40(conf),
- fastcc);
-
- spin_lock_bh(&sc->sc_resetlock);
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "(%u MHz) -> (%u MHz), conf_is_ht40: %d fastcc: %d\n",
+ sc->sc_ah->curchan->channel,
+ channel->center_freq, conf_is_ht40(conf),
+ fastcc);
r = ath9k_hw_reset(ah, hchan, caldata, fastcc);
if (r) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to reset channel (%u MHz), "
- "reset status %d\n",
- channel->center_freq, r);
- spin_unlock_bh(&sc->sc_resetlock);
- spin_unlock_bh(&sc->rx.pcu_lock);
+ ath_err(common,
+ "Unable to reset channel (%u MHz), reset status %d\n",
+ channel->center_freq, r);
goto ps_restore;
}
- spin_unlock_bh(&sc->sc_resetlock);
if (ath_startrecv(sc) != 0) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to restart recv logic\n");
+ ath_err(common, "Unable to restart recv logic\n");
r = -EIO;
- spin_unlock_bh(&sc->rx.pcu_lock);
goto ps_restore;
}
- spin_unlock_bh(&sc->rx.pcu_lock);
-
ath_update_txpow(sc);
ath9k_hw_set_interrupts(ah, ah->imask);
@@ -301,6 +291,8 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
}
ps_restore:
+ spin_unlock_bh(&sc->sc_pcu_lock);
+
ath9k_ps_restore(sc);
return r;
}
@@ -341,7 +333,7 @@ void ath_paprd_calibrate(struct work_struct *work)
struct ath_tx_control txctl;
struct ath9k_hw_cal_data *caldata = ah->caldata;
struct ath_common *common = ath9k_hw_common(ah);
- int qnum, ftype;
+ int ftype;
int chain_ok = 0;
int chain;
int len = 1800;
@@ -368,8 +360,7 @@ void ath_paprd_calibrate(struct work_struct *work)
memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN);
memset(&txctl, 0, sizeof(txctl));
- qnum = sc->tx.hwq_map[WME_AC_BE];
- txctl.txq = &sc->tx.txq[qnum];
+ txctl.txq = sc->tx.txq_map[WME_AC_BE];
ath9k_ps_wakeup(sc);
ar9003_paprd_init_table(ah);
@@ -387,6 +378,7 @@ void ath_paprd_calibrate(struct work_struct *work)
}
init_completion(&sc->paprd_complete);
+ sc->paprd_pending = true;
ar9003_paprd_setup_gain_table(ah, chain);
txctl.paprd = BIT(chain);
if (ath_tx_start(hw, skb, &txctl) != 0)
@@ -394,11 +386,11 @@ void ath_paprd_calibrate(struct work_struct *work)
time_left = wait_for_completion_timeout(&sc->paprd_complete,
msecs_to_jiffies(ATH_PAPRD_TIMEOUT));
+ sc->paprd_pending = false;
if (!time_left) {
- ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
- "Timeout waiting for paprd training on "
- "TX chain %d\n",
- chain);
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
+ "Timeout waiting for paprd training on TX chain %d\n",
+ chain);
goto fail_paprd;
}
@@ -457,7 +449,7 @@ void ath_ani_calibrate(unsigned long data)
/* Long calibration runs independently of short calibration. */
if ((timestamp - common->ani.longcal_timer) >= long_cal_interval) {
longcal = true;
- ath_print(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies);
+ ath_dbg(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies);
common->ani.longcal_timer = timestamp;
}
@@ -465,8 +457,8 @@ void ath_ani_calibrate(unsigned long data)
if (!common->ani.caldone) {
if ((timestamp - common->ani.shortcal_timer) >= short_cal_interval) {
shortcal = true;
- ath_print(common, ATH_DBG_ANI,
- "shortcal @%lu\n", jiffies);
+ ath_dbg(common, ATH_DBG_ANI,
+ "shortcal @%lu\n", jiffies);
common->ani.shortcal_timer = timestamp;
common->ani.resetcal_timer = timestamp;
}
@@ -550,24 +542,26 @@ void ath_update_chainmask(struct ath_softc *sc, int is_ht)
common->rx_chainmask = 1;
}
- ath_print(common, ATH_DBG_CONFIG,
- "tx chmask: %d, rx chmask: %d\n",
- common->tx_chainmask,
- common->rx_chainmask);
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "tx chmask: %d, rx chmask: %d\n",
+ common->tx_chainmask,
+ common->rx_chainmask);
}
static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta)
{
struct ath_node *an;
-
+ struct ath_hw *ah = sc->sc_ah;
an = (struct ath_node *)sta->drv_priv;
+ if ((ah->caps.hw_caps) & ATH9K_HW_CAP_APM)
+ sc->sc_flags |= SC_OP_ENABLE_APM;
+
if (sc->sc_flags & SC_OP_TXAGGR) {
ath_tx_node_init(sc, an);
an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
sta->ht_cap.ampdu_factor);
an->mpdudensity = parse_mpdudensity(sta->ht_cap.ampdu_density);
- an->last_rssi = ATH_RSSI_DUMMY_MARKER;
}
}
@@ -615,6 +609,8 @@ void ath9k_tasklet(unsigned long data)
return;
}
+ spin_lock_bh(&sc->sc_pcu_lock);
+
if (!ath9k_hw_check_alive(ah))
ieee80211_queue_work(sc->hw, &sc->hw_check_work);
@@ -625,15 +621,12 @@ void ath9k_tasklet(unsigned long data)
rxmask = (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN);
if (status & rxmask) {
- spin_lock_bh(&sc->rx.pcu_lock);
-
/* Check for high priority Rx first */
if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) &&
(status & ATH9K_INT_RXHP))
ath_rx_tasklet(sc, 0, true);
ath_rx_tasklet(sc, 0, false);
- spin_unlock_bh(&sc->rx.pcu_lock);
}
if (status & ATH9K_INT_TX) {
@@ -648,8 +641,8 @@ void ath9k_tasklet(unsigned long data)
* TSF sync does not look correct; remain awake to sync with
* the next Beacon.
*/
- ath_print(common, ATH_DBG_PS,
- "TSFOOR - Sync with next Beacon\n");
+ ath_dbg(common, ATH_DBG_PS,
+ "TSFOOR - Sync with next Beacon\n");
sc->ps_flags |= PS_WAIT_FOR_BEACON | PS_BEACON_SYNC;
}
@@ -658,7 +651,9 @@ void ath9k_tasklet(unsigned long data)
ath_gen_timer_isr(sc->sc_ah);
/* re-enable hardware interrupt */
- ath9k_hw_set_interrupts(ah, ah->imask);
+ ath9k_hw_enable_interrupts(ah);
+
+ spin_unlock_bh(&sc->sc_pcu_lock);
ath9k_ps_restore(sc);
}
@@ -757,7 +752,7 @@ irqreturn_t ath_isr(int irq, void *dev)
* interrupt; otherwise it will continue to
* fire.
*/
- ath9k_hw_set_interrupts(ah, 0);
+ ath9k_hw_disable_interrupts(ah);
/*
* Let the hal handle the event. We assume
* it will clear whatever condition caused
@@ -766,11 +761,13 @@ irqreturn_t ath_isr(int irq, void *dev)
spin_lock(&common->cc_lock);
ath9k_hw_proc_mib_event(ah);
spin_unlock(&common->cc_lock);
- ath9k_hw_set_interrupts(ah, ah->imask);
+ ath9k_hw_enable_interrupts(ah);
}
if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
if (status & ATH9K_INT_TIM_TIMER) {
+ if (ATH_DBG_WARN_ON_ONCE(sc->ps_idle))
+ goto chip_reset;
/* Clear RxAbort bit so that we can
* receive frames */
ath9k_setpower(sc, ATH9K_PM_AWAKE);
@@ -783,8 +780,8 @@ chip_reset:
ath_debug_stat_interrupt(sc, status);
if (sched) {
- /* turn off every interrupt except SWBA */
- ath9k_hw_set_interrupts(ah, (ah->imask & ATH9K_INT_SWBA));
+ /* turn off every interrupt */
+ ath9k_hw_disable_interrupts(ah);
tasklet_schedule(&sc->intr_tq);
}
@@ -836,16 +833,18 @@ static u32 ath_get_extchanmode(struct ath_softc *sc,
}
static void ath9k_bss_assoc_info(struct ath_softc *sc,
+ struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *bss_conf)
{
+ struct ath_wiphy *aphy = hw->priv;
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
if (bss_conf->assoc) {
- ath_print(common, ATH_DBG_CONFIG,
- "Bss Info ASSOC %d, bssid: %pM\n",
- bss_conf->aid, common->curbssid);
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "Bss Info ASSOC %d, bssid: %pM\n",
+ bss_conf->aid, common->curbssid);
/* New association, store aid */
common->curaid = bss_conf->aid;
@@ -862,12 +861,13 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc,
ath_beacon_config(sc, vif);
/* Reset rssi stats */
+ aphy->last_rssi = ATH_RSSI_DUMMY_MARKER;
sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
sc->sc_flags |= SC_OP_ANI_RUN;
ath_start_ani(common);
} else {
- ath_print(common, ATH_DBG_CONFIG, "Bss Info DISASSOC\n");
+ ath_dbg(common, ATH_DBG_CONFIG, "Bss Info DISASSOC\n");
common->curaid = 0;
/* Stop ANI */
sc->sc_flags &= ~SC_OP_ANI_RUN;
@@ -883,31 +883,26 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
int r;
ath9k_ps_wakeup(sc);
+ spin_lock_bh(&sc->sc_pcu_lock);
+
ath9k_hw_configpcipowersave(ah, 0, 0);
if (!ah->curchan)
ah->curchan = ath_get_curchannel(sc, sc->hw);
- spin_lock_bh(&sc->rx.pcu_lock);
- spin_lock_bh(&sc->sc_resetlock);
r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
if (r) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to reset channel (%u MHz), "
- "reset status %d\n",
- channel->center_freq, r);
+ ath_err(common,
+ "Unable to reset channel (%u MHz), reset status %d\n",
+ channel->center_freq, r);
}
- spin_unlock_bh(&sc->sc_resetlock);
ath_update_txpow(sc);
if (ath_startrecv(sc) != 0) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to restart recv logic\n");
- spin_unlock_bh(&sc->rx.pcu_lock);
+ ath_err(common, "Unable to restart recv logic\n");
+ spin_unlock_bh(&sc->sc_pcu_lock);
return;
}
- spin_unlock_bh(&sc->rx.pcu_lock);
-
if (sc->sc_flags & SC_OP_BEACONS)
ath_beacon_config(sc, NULL); /* restart beacons */
@@ -920,6 +915,8 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
ath9k_hw_set_gpio(ah, ah->led_pin, 0);
ieee80211_wake_queues(hw);
+ spin_unlock_bh(&sc->sc_pcu_lock);
+
ath9k_ps_restore(sc);
}
@@ -930,6 +927,8 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw)
int r;
ath9k_ps_wakeup(sc);
+ spin_lock_bh(&sc->sc_pcu_lock);
+
ieee80211_stop_queues(hw);
/*
@@ -942,34 +941,30 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw)
}
/* Disable interrupts */
- ath9k_hw_set_interrupts(ah, 0);
+ ath9k_hw_disable_interrupts(ah);
ath_drain_all_txq(sc, false); /* clear pending tx frames */
- spin_lock_bh(&sc->rx.pcu_lock);
-
ath_stoprecv(sc); /* turn off frame recv */
ath_flushrecv(sc); /* flush recv queue */
if (!ah->curchan)
ah->curchan = ath_get_curchannel(sc, hw);
- spin_lock_bh(&sc->sc_resetlock);
r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
if (r) {
- ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
- "Unable to reset channel (%u MHz), "
- "reset status %d\n",
- channel->center_freq, r);
+ ath_err(ath9k_hw_common(sc->sc_ah),
+ "Unable to reset channel (%u MHz), reset status %d\n",
+ channel->center_freq, r);
}
- spin_unlock_bh(&sc->sc_resetlock);
ath9k_hw_phy_disable(ah);
- spin_unlock_bh(&sc->rx.pcu_lock);
-
ath9k_hw_configpcipowersave(ah, 1, 1);
+
+ spin_unlock_bh(&sc->sc_pcu_lock);
ath9k_ps_restore(sc);
+
ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP);
}
@@ -983,28 +978,23 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
/* Stop ANI */
del_timer_sync(&common->ani.timer);
+ spin_lock_bh(&sc->sc_pcu_lock);
+
ieee80211_stop_queues(hw);
- ath9k_hw_set_interrupts(ah, 0);
+ ath9k_hw_disable_interrupts(ah);
ath_drain_all_txq(sc, retry_tx);
- spin_lock_bh(&sc->rx.pcu_lock);
-
ath_stoprecv(sc);
ath_flushrecv(sc);
- spin_lock_bh(&sc->sc_resetlock);
r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false);
if (r)
- ath_print(common, ATH_DBG_FATAL,
- "Unable to reset hardware; reset status %d\n", r);
- spin_unlock_bh(&sc->sc_resetlock);
+ ath_err(common,
+ "Unable to reset hardware; reset status %d\n", r);
if (ath_startrecv(sc) != 0)
- ath_print(common, ATH_DBG_FATAL,
- "Unable to start recv logic\n");
-
- spin_unlock_bh(&sc->rx.pcu_lock);
+ ath_err(common, "Unable to start recv logic\n");
/*
* We may be doing a reset in response to a request
@@ -1030,6 +1020,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
}
ieee80211_wake_queues(hw);
+ spin_unlock_bh(&sc->sc_pcu_lock);
/* Start ANI */
ath_start_ani(common);
@@ -1037,56 +1028,6 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
return r;
}
-static int ath_get_hal_qnum(u16 queue, struct ath_softc *sc)
-{
- int qnum;
-
- switch (queue) {
- case 0:
- qnum = sc->tx.hwq_map[WME_AC_VO];
- break;
- case 1:
- qnum = sc->tx.hwq_map[WME_AC_VI];
- break;
- case 2:
- qnum = sc->tx.hwq_map[WME_AC_BE];
- break;
- case 3:
- qnum = sc->tx.hwq_map[WME_AC_BK];
- break;
- default:
- qnum = sc->tx.hwq_map[WME_AC_BE];
- break;
- }
-
- return qnum;
-}
-
-int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc)
-{
- int qnum;
-
- switch (queue) {
- case WME_AC_VO:
- qnum = 0;
- break;
- case WME_AC_VI:
- qnum = 1;
- break;
- case WME_AC_BE:
- qnum = 2;
- break;
- case WME_AC_BK:
- qnum = 3;
- break;
- default:
- qnum = -1;
- break;
- }
-
- return qnum;
-}
-
/* XXX: Remove me once we don't depend on ath9k_channel for all
* this redundant data */
void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw,
@@ -1125,9 +1066,9 @@ static int ath9k_start(struct ieee80211_hw *hw)
struct ath9k_channel *init_channel;
int r;
- ath_print(common, ATH_DBG_CONFIG,
- "Starting driver with initial channel: %d MHz\n",
- curchan->center_freq);
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "Starting driver with initial channel: %d MHz\n",
+ curchan->center_freq);
mutex_lock(&sc->mutex);
@@ -1168,19 +1109,15 @@ static int ath9k_start(struct ieee80211_hw *hw)
* be followed by initialization of the appropriate bits
* and then setup of the interrupt mask.
*/
- spin_lock_bh(&sc->rx.pcu_lock);
- spin_lock_bh(&sc->sc_resetlock);
+ spin_lock_bh(&sc->sc_pcu_lock);
r = ath9k_hw_reset(ah, init_channel, ah->caldata, false);
if (r) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to reset hardware; reset status %d "
- "(freq %u MHz)\n", r,
- curchan->center_freq);
- spin_unlock_bh(&sc->sc_resetlock);
- spin_unlock_bh(&sc->rx.pcu_lock);
+ ath_err(common,
+ "Unable to reset hardware; reset status %d (freq %u MHz)\n",
+ r, curchan->center_freq);
+ spin_unlock_bh(&sc->sc_pcu_lock);
goto mutex_unlock;
}
- spin_unlock_bh(&sc->sc_resetlock);
/*
* This is needed only to setup initial state
@@ -1196,13 +1133,12 @@ static int ath9k_start(struct ieee80211_hw *hw)
* here except setup the interrupt mask.
*/
if (ath_startrecv(sc) != 0) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to start recv logic\n");
+ ath_err(common, "Unable to start recv logic\n");
r = -EIO;
- spin_unlock_bh(&sc->rx.pcu_lock);
+ spin_unlock_bh(&sc->sc_pcu_lock);
goto mutex_unlock;
}
- spin_unlock_bh(&sc->rx.pcu_lock);
+ spin_unlock_bh(&sc->sc_pcu_lock);
/* Setup our intr mask. */
ah->imask = ATH9K_INT_TX | ATH9K_INT_RXEOL |
@@ -1246,6 +1182,9 @@ static int ath9k_start(struct ieee80211_hw *hw)
pm_qos_update_request(&sc->pm_qos_req, 55);
+ if (ah->caps.pcie_lcr_extsync_en && common->bus_ops->extn_synch_en)
+ common->bus_ops->extn_synch_en(common);
+
mutex_unlock:
mutex_unlock(&sc->mutex);
@@ -1255,19 +1194,16 @@ mutex_unlock:
static int ath9k_tx(struct ieee80211_hw *hw,
struct sk_buff *skb)
{
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ath_wiphy *aphy = hw->priv;
struct ath_softc *sc = aphy->sc;
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
struct ath_tx_control txctl;
- int padpos, padsize;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
- int qnum;
if (aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN) {
- ath_print(common, ATH_DBG_XMIT,
- "ath9k: %s: TX in unexpected wiphy state "
- "%d\n", wiphy_name(hw->wiphy), aphy->state);
+ ath_dbg(common, ATH_DBG_XMIT,
+ "ath9k: %s: TX in unexpected wiphy state %d\n",
+ wiphy_name(hw->wiphy), aphy->state);
goto exit;
}
@@ -1279,8 +1215,8 @@ static int ath9k_tx(struct ieee80211_hw *hw,
if (ieee80211_is_data(hdr->frame_control) &&
!ieee80211_is_nullfunc(hdr->frame_control) &&
!ieee80211_has_pm(hdr->frame_control)) {
- ath_print(common, ATH_DBG_PS, "Add PM=1 for a TX frame "
- "while in PS mode\n");
+ ath_dbg(common, ATH_DBG_PS,
+ "Add PM=1 for a TX frame while in PS mode\n");
hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
}
}
@@ -1295,12 +1231,12 @@ static int ath9k_tx(struct ieee80211_hw *hw,
if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
ath9k_hw_setrxabort(sc->sc_ah, 0);
if (ieee80211_is_pspoll(hdr->frame_control)) {
- ath_print(common, ATH_DBG_PS,
- "Sending PS-Poll to pick a buffered frame\n");
+ ath_dbg(common, ATH_DBG_PS,
+ "Sending PS-Poll to pick a buffered frame\n");
sc->ps_flags |= PS_WAIT_FOR_PSPOLL_DATA;
} else {
- ath_print(common, ATH_DBG_PS,
- "Wake up to complete TX\n");
+ ath_dbg(common, ATH_DBG_PS,
+ "Wake up to complete TX\n");
sc->ps_flags |= PS_WAIT_FOR_TX_ACK;
}
/*
@@ -1312,36 +1248,12 @@ static int ath9k_tx(struct ieee80211_hw *hw,
}
memset(&txctl, 0, sizeof(struct ath_tx_control));
+ txctl.txq = sc->tx.txq_map[skb_get_queue_mapping(skb)];
- /*
- * As a temporary workaround, assign seq# here; this will likely need
- * to be cleaned up to work better with Beacon transmission and virtual
- * BSSes.
- */
- if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
- if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
- sc->tx.seq_no += 0x10;
- hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
- hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
- }
-
- /* Add the padding after the header if this is not already done */
- padpos = ath9k_cmn_padpos(hdr->frame_control);
- padsize = padpos & 3;
- if (padsize && skb->len>padpos) {
- if (skb_headroom(skb) < padsize)
- return -1;
- skb_push(skb, padsize);
- memmove(skb->data, skb->data + padsize, padpos);
- }
-
- qnum = ath_get_hal_qnum(skb_get_queue_mapping(skb), sc);
- txctl.txq = &sc->tx.txq[qnum];
-
- ath_print(common, ATH_DBG_XMIT, "transmitting packet, skb: %p\n", skb);
+ ath_dbg(common, ATH_DBG_XMIT, "transmitting packet, skb: %p\n", skb);
if (ath_tx_start(hw, skb, &txctl) != 0) {
- ath_print(common, ATH_DBG_XMIT, "TX failed\n");
+ ath_dbg(common, ATH_DBG_XMIT, "TX failed\n");
goto exit;
}
@@ -1381,7 +1293,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
}
if (sc->sc_flags & SC_OP_INVALID) {
- ath_print(common, ATH_DBG_ANY, "Device not present\n");
+ ath_dbg(common, ATH_DBG_ANY, "Device not present\n");
mutex_unlock(&sc->mutex);
return;
}
@@ -1400,22 +1312,25 @@ static void ath9k_stop(struct ieee80211_hw *hw)
ath9k_btcoex_timer_pause(sc);
}
+ spin_lock_bh(&sc->sc_pcu_lock);
+
/* make sure h/w will not generate any interrupt
* before setting the invalid flag. */
- ath9k_hw_set_interrupts(ah, 0);
+ ath9k_hw_disable_interrupts(ah);
- spin_lock_bh(&sc->rx.pcu_lock);
if (!(sc->sc_flags & SC_OP_INVALID)) {
ath_drain_all_txq(sc, false);
ath_stoprecv(sc);
ath9k_hw_phy_disable(ah);
} else
sc->rx.rxlink = NULL;
- spin_unlock_bh(&sc->rx.pcu_lock);
/* disable HAL and put h/w to sleep */
ath9k_hw_disable(ah);
ath9k_hw_configpcipowersave(ah, 1, 1);
+
+ spin_unlock_bh(&sc->sc_pcu_lock);
+
ath9k_ps_restore(sc);
/* Finally, put the chip in FULL SLEEP mode */
@@ -1427,7 +1342,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
mutex_unlock(&sc->mutex);
- ath_print(common, ATH_DBG_CONFIG, "Driver halt\n");
+ ath_dbg(common, ATH_DBG_CONFIG, "Driver halt\n");
}
static int ath9k_add_interface(struct ieee80211_hw *hw,
@@ -1460,14 +1375,14 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
ic_opmode = vif->type;
break;
default:
- ath_print(common, ATH_DBG_FATAL,
- "Interface type %d not yet supported\n", vif->type);
+ ath_err(common, "Interface type %d not yet supported\n",
+ vif->type);
ret = -EOPNOTSUPP;
goto out;
}
- ath_print(common, ATH_DBG_CONFIG,
- "Attach a VIF of type: %d\n", ic_opmode);
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "Attach a VIF of type: %d\n", ic_opmode);
/* Set the VIF opmode */
avp->av_opmode = ic_opmode;
@@ -1521,7 +1436,7 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
struct ath_vif *avp = (void *)vif->drv_priv;
- ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n");
+ ath_dbg(common, ATH_DBG_CONFIG, "Detach Interface\n");
mutex_lock(&sc->mutex);
@@ -1631,8 +1546,8 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
if (enable_radio) {
sc->ps_idle = false;
ath_radio_enable(sc, hw);
- ath_print(common, ATH_DBG_CONFIG,
- "not-idle: enabling radio\n");
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "not-idle: enabling radio\n");
}
}
@@ -1654,12 +1569,12 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
if (conf->flags & IEEE80211_CONF_MONITOR) {
- ath_print(common, ATH_DBG_CONFIG,
- "Monitor mode is enabled\n");
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "Monitor mode is enabled\n");
sc->sc_ah->is_monitoring = true;
} else {
- ath_print(common, ATH_DBG_CONFIG,
- "Monitor mode is disabled\n");
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "Monitor mode is disabled\n");
sc->sc_ah->is_monitoring = false;
}
}
@@ -1691,8 +1606,8 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
goto skip_chan_change;
}
- ath_print(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n",
- curchan->center_freq);
+ ath_dbg(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n",
+ curchan->center_freq);
/* XXX: remove me eventualy */
ath9k_update_ichannel(sc, hw, &sc->sc_ah->channels[pos]);
@@ -1725,8 +1640,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
}
if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) {
- ath_print(common, ATH_DBG_FATAL,
- "Unable to set channel\n");
+ ath_err(common, "Unable to set channel\n");
mutex_unlock(&sc->mutex);
return -EINVAL;
}
@@ -1751,7 +1665,7 @@ skip_chan_change:
spin_unlock_bh(&sc->wiphy_lock);
if (disable_radio) {
- ath_print(common, ATH_DBG_CONFIG, "idle: disabling radio\n");
+ ath_dbg(common, ATH_DBG_CONFIG, "idle: disabling radio\n");
sc->ps_idle = true;
ath_radio_disable(sc, hw);
}
@@ -1790,8 +1704,8 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw,
ath9k_hw_setrxfilter(sc->sc_ah, rfilt);
ath9k_ps_restore(sc);
- ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG,
- "Set HW RX filter: 0x%x\n", rfilt);
+ ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG,
+ "Set HW RX filter: 0x%x\n", rfilt);
}
static int ath9k_sta_add(struct ieee80211_hw *hw,
@@ -1824,12 +1738,15 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue,
struct ath_wiphy *aphy = hw->priv;
struct ath_softc *sc = aphy->sc;
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+ struct ath_txq *txq;
struct ath9k_tx_queue_info qi;
- int ret = 0, qnum;
+ int ret = 0;
if (queue >= WME_NUM_AC)
return 0;
+ txq = sc->tx.txq_map[queue];
+
mutex_lock(&sc->mutex);
memset(&qi, 0, sizeof(struct ath9k_tx_queue_info));
@@ -1838,20 +1755,18 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue,
qi.tqi_cwmin = params->cw_min;
qi.tqi_cwmax = params->cw_max;
qi.tqi_burstTime = params->txop;
- qnum = ath_get_hal_qnum(queue, sc);
- ath_print(common, ATH_DBG_CONFIG,
- "Configure tx [queue/halq] [%d/%d], "
- "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
- queue, qnum, params->aifs, params->cw_min,
- params->cw_max, params->txop);
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "Configure tx [queue/halq] [%d/%d], aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
+ queue, txq->axq_qnum, params->aifs, params->cw_min,
+ params->cw_max, params->txop);
- ret = ath_txq_update(sc, qnum, &qi);
+ ret = ath_txq_update(sc, txq->axq_qnum, &qi);
if (ret)
- ath_print(common, ATH_DBG_FATAL, "TXQ Update failed\n");
+ ath_err(common, "TXQ Update failed\n");
if (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)
- if ((qnum == sc->tx.hwq_map[WME_AC_BE]) && !ret)
+ if (queue == WME_AC_BE && !ret)
ath_beaconq_config(sc);
mutex_unlock(&sc->mutex);
@@ -1875,7 +1790,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw,
mutex_lock(&sc->mutex);
ath9k_ps_wakeup(sc);
- ath_print(common, ATH_DBG_CONFIG, "Set HW Key\n");
+ ath_dbg(common, ATH_DBG_CONFIG, "Set HW Key\n");
switch (cmd) {
case SET_KEY:
@@ -1934,9 +1849,8 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
if (vif->type == NL80211_IFTYPE_ADHOC)
ath_update_chainmask(sc, 0);
- ath_print(common, ATH_DBG_CONFIG,
- "BSSID: %pM aid: 0x%x\n",
- common->curbssid, common->curaid);
+ ath_dbg(common, ATH_DBG_CONFIG, "BSSID: %pM aid: 0x%x\n",
+ common->curbssid, common->curaid);
/* need to reconfigure the beacon */
sc->sc_flags &= ~SC_OP_BEACONS ;
@@ -1992,8 +1906,8 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
}
if (changed & BSS_CHANGED_ERP_PREAMBLE) {
- ath_print(common, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n",
- bss_conf->use_short_preamble);
+ ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n",
+ bss_conf->use_short_preamble);
if (bss_conf->use_short_preamble)
sc->sc_flags |= SC_OP_PREAMBLE_SHORT;
else
@@ -2001,8 +1915,8 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
}
if (changed & BSS_CHANGED_ERP_CTS_PROT) {
- ath_print(common, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n",
- bss_conf->use_cts_prot);
+ ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n",
+ bss_conf->use_cts_prot);
if (bss_conf->use_cts_prot &&
hw->conf.channel->band != IEEE80211_BAND_5GHZ)
sc->sc_flags |= SC_OP_PROTECT_ENABLE;
@@ -2011,9 +1925,9 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
}
if (changed & BSS_CHANGED_ASSOC) {
- ath_print(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
+ ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
bss_conf->assoc);
- ath9k_bss_assoc_info(sc, vif, bss_conf);
+ ath9k_bss_assoc_info(sc, hw, vif, bss_conf);
}
mutex_unlock(&sc->mutex);
@@ -2076,6 +1990,9 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
case IEEE80211_AMPDU_RX_STOP:
break;
case IEEE80211_AMPDU_TX_START:
+ if (!(sc->sc_flags & SC_OP_TXAGGR))
+ return -EOPNOTSUPP;
+
ath9k_ps_wakeup(sc);
ret = ath_tx_aggr_start(sc, sta, tid, ssn);
if (!ret)
@@ -2094,8 +2011,7 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
ath9k_ps_restore(sc);
break;
default:
- ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
- "Unknown AMPDU action\n");
+ ath_err(ath9k_hw_common(sc->sc_ah), "Unknown AMPDU action\n");
}
local_bh_enable();
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index b5b651413e77..747b2871e48f 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -16,6 +16,7 @@
#include <linux/nl80211.h>
#include <linux/pci.h>
+#include <linux/ath9k_platform.h>
#include "ath9k.h"
static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
@@ -29,6 +30,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
{ PCI_VDEVICE(ATHEROS, 0x002D) }, /* PCI */
{ PCI_VDEVICE(ATHEROS, 0x002E) }, /* PCI-E */
{ PCI_VDEVICE(ATHEROS, 0x0030) }, /* PCI-E AR9300 */
+ { PCI_VDEVICE(ATHEROS, 0x0032) }, /* PCI-E AR9485 */
{ 0 }
};
@@ -53,21 +55,35 @@ static void ath_pci_read_cachesize(struct ath_common *common, int *csz)
static bool ath_pci_eeprom_read(struct ath_common *common, u32 off, u16 *data)
{
- struct ath_hw *ah = (struct ath_hw *) common->ah;
-
- common->ops->read(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S));
-
- if (!ath9k_hw_wait(ah,
- AR_EEPROM_STATUS_DATA,
- AR_EEPROM_STATUS_DATA_BUSY |
- AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0,
- AH_WAIT_TIMEOUT)) {
- return false;
+ struct ath_softc *sc = (struct ath_softc *) common->priv;
+ struct ath9k_platform_data *pdata = sc->dev->platform_data;
+
+ if (pdata) {
+ if (off >= (ARRAY_SIZE(pdata->eeprom_data))) {
+ ath_err(common,
+ "%s: eeprom read failed, offset %08x is out of range\n",
+ __func__, off);
+ }
+
+ *data = pdata->eeprom_data[off];
+ } else {
+ struct ath_hw *ah = (struct ath_hw *) common->ah;
+
+ common->ops->read(ah, AR5416_EEPROM_OFFSET +
+ (off << AR5416_EEPROM_S));
+
+ if (!ath9k_hw_wait(ah,
+ AR_EEPROM_STATUS_DATA,
+ AR_EEPROM_STATUS_DATA_BUSY |
+ AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0,
+ AH_WAIT_TIMEOUT)) {
+ return false;
+ }
+
+ *data = MS(common->ops->read(ah, AR_EEPROM_STATUS_DATA),
+ AR_EEPROM_STATUS_DATA_VAL);
}
- *data = MS(common->ops->read(ah, AR_EEPROM_STATUS_DATA),
- AR_EEPROM_STATUS_DATA_VAL);
-
return true;
}
@@ -88,11 +104,23 @@ static void ath_pci_bt_coex_prep(struct ath_common *common)
pci_write_config_byte(pdev, ATH_PCIE_CAP_LINK_CTRL, aspm);
}
+static void ath_pci_extn_synch_enable(struct ath_common *common)
+{
+ struct ath_softc *sc = (struct ath_softc *) common->priv;
+ struct pci_dev *pdev = to_pci_dev(sc->dev);
+ u8 lnkctl;
+
+ pci_read_config_byte(pdev, sc->sc_ah->caps.pcie_lcr_offset, &lnkctl);
+ lnkctl |= PCI_EXP_LNKCTL_ES;
+ pci_write_config_byte(pdev, sc->sc_ah->caps.pcie_lcr_offset, lnkctl);
+}
+
static const struct ath_bus_ops ath_pci_bus_ops = {
.ath_bus_type = ATH_PCI,
.read_cachesize = ath_pci_read_cachesize,
.eeprom_read = ath_pci_eeprom_read,
.bt_coex_prep = ath_pci_bt_coex_prep,
+ .extn_synch_en = ath_pci_extn_synch_enable,
};
static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
@@ -247,34 +275,25 @@ static void ath_pci_remove(struct pci_dev *pdev)
#ifdef CONFIG_PM
-static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+static int ath_pci_suspend(struct device *device)
{
+ struct pci_dev *pdev = to_pci_dev(device);
struct ieee80211_hw *hw = pci_get_drvdata(pdev);
struct ath_wiphy *aphy = hw->priv;
struct ath_softc *sc = aphy->sc;
ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
- pci_save_state(pdev);
- pci_disable_device(pdev);
- pci_set_power_state(pdev, PCI_D3hot);
-
return 0;
}
-static int ath_pci_resume(struct pci_dev *pdev)
+static int ath_pci_resume(struct device *device)
{
+ struct pci_dev *pdev = to_pci_dev(device);
struct ieee80211_hw *hw = pci_get_drvdata(pdev);
struct ath_wiphy *aphy = hw->priv;
struct ath_softc *sc = aphy->sc;
u32 val;
- int err;
-
- pci_restore_state(pdev);
-
- err = pci_enable_device(pdev);
- if (err)
- return err;
/*
* Suspend/Resume resets the PCI configuration space, so we have to
@@ -293,7 +312,23 @@ static int ath_pci_resume(struct pci_dev *pdev)
return 0;
}
-#endif /* CONFIG_PM */
+static const struct dev_pm_ops ath9k_pm_ops = {
+ .suspend = ath_pci_suspend,
+ .resume = ath_pci_resume,
+ .freeze = ath_pci_suspend,
+ .thaw = ath_pci_resume,
+ .poweroff = ath_pci_suspend,
+ .restore = ath_pci_resume,
+};
+
+#define ATH9K_PM_OPS (&ath9k_pm_ops)
+
+#else /* !CONFIG_PM */
+
+#define ATH9K_PM_OPS NULL
+
+#endif /* !CONFIG_PM */
+
MODULE_DEVICE_TABLE(pci, ath_pci_id_table);
@@ -302,10 +337,7 @@ static struct pci_driver ath_pci_driver = {
.id_table = ath_pci_id_table,
.probe = ath_pci_probe,
.remove = ath_pci_remove,
-#ifdef CONFIG_PM
- .suspend = ath_pci_suspend,
- .resume = ath_pci_resume,
-#endif /* CONFIG_PM */
+ .driver.pm = ATH9K_PM_OPS,
};
int ath_pci_init(void)
diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h
index 17969af842f6..5e3d7496986e 100644
--- a/drivers/net/wireless/ath/ath9k/phy.h
+++ b/drivers/net/wireless/ath/ath9k/phy.h
@@ -19,6 +19,7 @@
#define CHANSEL_DIV 15
#define CHANSEL_2G(_freq) (((_freq) * 0x10000) / CHANSEL_DIV)
+#define CHANSEL_2G_9485(_freq) ((((_freq) * 0x10000) - 215) / CHANSEL_DIV)
#define CHANSEL_5G(_freq) (((_freq) * 0x8000) / CHANSEL_DIV)
#define AR_PHY_BASE 0x9800
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index 89978d71617f..2061a755a026 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -381,25 +381,6 @@ static const struct ath_rate_table ar5416_11g_ratetable = {
static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table,
struct ieee80211_tx_rate *rate);
-static inline int8_t median(int8_t a, int8_t b, int8_t c)
-{
- if (a >= b) {
- if (b >= c)
- return b;
- else if (a > c)
- return c;
- else
- return a;
- } else {
- if (a >= c)
- return a;
- else if (b >= c)
- return c;
- else
- return b;
- }
-}
-
static void ath_rc_sort_validrates(const struct ath_rate_table *rate_table,
struct ath_rate_priv *ath_rc_priv)
{
@@ -883,7 +864,7 @@ static bool ath_rc_update_per(struct ath_softc *sc,
bool state_change = false;
int count, n_bad_frames;
u8 last_per;
- static u32 nretry_to_per_lookup[10] = {
+ static const u32 nretry_to_per_lookup[10] = {
100 * 0 / 1,
100 * 1 / 4,
100 * 1 / 2,
@@ -1106,13 +1087,13 @@ static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table,
struct ieee80211_tx_rate *rate)
{
int rix = 0, i = 0;
- int mcs_rix_off[] = { 7, 15, 20, 21, 22, 23 };
+ static const int mcs_rix_off[] = { 7, 15, 20, 21, 22, 23 };
if (!(rate->flags & IEEE80211_TX_RC_MCS))
return rate->idx;
while (rate->idx > mcs_rix_off[i] &&
- i < sizeof(mcs_rix_off)/sizeof(int)) {
+ i < ARRAY_SIZE(mcs_rix_off)) {
rix++; i++;
}
@@ -1203,7 +1184,7 @@ struct ath_rate_table *ath_choose_rate_table(struct ath_softc *sc,
return &ar5416_11na_ratetable;
return &ar5416_11a_ratetable;
default:
- ath_print(common, ATH_DBG_CONFIG, "Invalid band\n");
+ ath_dbg(common, ATH_DBG_CONFIG, "Invalid band\n");
return NULL;
}
}
@@ -1278,9 +1259,9 @@ static void ath_rc_init(struct ath_softc *sc,
ath_rc_priv->rate_max_phy = ath_rc_priv->valid_rate_index[k-4];
ath_rc_priv->rate_table = rate_table;
- ath_print(common, ATH_DBG_CONFIG,
- "RC Initialized with capabilities: 0x%x\n",
- ath_rc_priv->ht_cap);
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "RC Initialized with capabilities: 0x%x\n",
+ ath_rc_priv->ht_cap);
}
static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta,
@@ -1373,23 +1354,7 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
tx_info->status.ampdu_len = 1;
}
- /*
- * If an underrun error is seen assume it as an excessive retry only
- * if max frame trigger level has been reached (2 KB for singel stream,
- * and 4 KB for dual stream). Adjust the long retry as if the frame was
- * tried hw->max_rate_tries times to affect how ratectrl updates PER for
- * the failed rate. In case of congestion on the bus penalizing these
- * type of underruns should help hardware actually transmit new frames
- * successfully by eventually preferring slower rates. This itself
- * should also alleviate congestion on the bus.
- */
- if ((tx_info->pad[0] & ATH_TX_INFO_UNDERRUN) &&
- (sc->sc_ah->tx_trig_level >= ath_rc_priv->tx_triglevel_max)) {
- tx_status = 1;
- is_underrun = 1;
- }
-
- if (tx_info->pad[0] & ATH_TX_INFO_XRETRY)
+ if (!(tx_info->flags & IEEE80211_TX_STAT_ACK))
tx_status = 1;
ath_rc_tx_status(sc, ath_rc_priv, tx_info, final_ts_idx, tx_status,
@@ -1398,7 +1363,8 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
/* Check if aggregation has to be enabled for this tid */
if (conf_is_ht(&sc->hw->conf) &&
!(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
- if (ieee80211_is_data_qos(fc)) {
+ if (ieee80211_is_data_qos(fc) &&
+ skb_get_queue_mapping(skb) != IEEE80211_AC_VO) {
u8 *qc, tid;
struct ath_node *an;
@@ -1444,12 +1410,12 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
ath_rc_priv->neg_ht_rates.rs_nrates = j;
}
- is_cw40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+ is_cw40 = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40);
if (is_cw40)
- is_sgi = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40;
+ is_sgi = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40);
else if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_SGI_20)
- is_sgi = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20;
+ is_sgi = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20);
/* Choose rate table first */
@@ -1468,10 +1434,8 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
struct ath_rate_priv *ath_rc_priv = priv_sta;
const struct ath_rate_table *rate_table = NULL;
bool oper_cw40 = false, oper_sgi;
- bool local_cw40 = (ath_rc_priv->ht_cap & WLAN_RC_40_FLAG) ?
- true : false;
- bool local_sgi = (ath_rc_priv->ht_cap & WLAN_RC_SGI_FLAG) ?
- true : false;
+ bool local_cw40 = !!(ath_rc_priv->ht_cap & WLAN_RC_40_FLAG);
+ bool local_sgi = !!(ath_rc_priv->ht_cap & WLAN_RC_SGI_FLAG);
/* FIXME: Handle AP mode later when we support CWM */
@@ -1499,9 +1463,9 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
oper_cw40, oper_sgi);
ath_rc_init(sc, priv_sta, sband, sta, rate_table);
- ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG,
- "Operating HT Bandwidth changed to: %d\n",
- sc->hw->conf.channel_type);
+ ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG,
+ "Operating HT Bandwidth changed to: %d\n",
+ sc->hw->conf.channel_type);
}
}
}
@@ -1612,13 +1576,11 @@ static void *ath_rate_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp
rate_priv = kzalloc(sizeof(struct ath_rate_priv), gfp);
if (!rate_priv) {
- ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
- "Unable to allocate private rc structure\n");
+ ath_err(ath9k_hw_common(sc->sc_ah),
+ "Unable to allocate private rc structure\n");
return NULL;
}
- rate_priv->tx_triglevel_max = sc->sc_ah->caps.tx_triglevel_max;
-
return rate_priv;
}
diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h
index 2f46a2266ba1..31a004cb60ac 100644
--- a/drivers/net/wireless/ath/ath9k/rc.h
+++ b/drivers/net/wireless/ath/ath9k/rc.h
@@ -215,7 +215,6 @@ struct ath_rate_priv {
u32 per_down_time;
u32 probe_interval;
u32 prev_data_rix;
- u32 tx_triglevel_max;
struct ath_rateset neg_rates;
struct ath_rateset neg_ht_rates;
struct ath_rate_softc *asc;
@@ -225,11 +224,6 @@ struct ath_rate_priv {
struct ath_rc_stats rcstats[RATE_TABLE_SIZE];
};
-#define ATH_TX_INFO_FRAME_TYPE_INTERNAL (1 << 0)
-#define ATH_TX_INFO_FRAME_TYPE_PAUSE (1 << 1)
-#define ATH_TX_INFO_XRETRY (1 << 3)
-#define ATH_TX_INFO_UNDERRUN (1 << 4)
-
enum ath9k_internal_frame_type {
ATH9K_IFT_NOT_INTERNAL,
ATH9K_IFT_PAUSE,
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index fdc2ec52b42f..00ebed3f9158 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -165,7 +165,7 @@ static void ath_rx_addbuffer_edma(struct ath_softc *sc,
u32 nbuf = 0;
if (list_empty(&sc->rx.rxbuf)) {
- ath_print(common, ATH_DBG_QUEUE, "No free rx buf available\n");
+ ath_dbg(common, ATH_DBG_QUEUE, "No free rx buf available\n");
return;
}
@@ -269,7 +269,7 @@ static int ath_rx_edma_init(struct ath_softc *sc, int nbufs)
dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL;
bf->bf_buf_addr = 0;
- ath_print(common, ATH_DBG_FATAL,
+ ath_err(common,
"dma_mapping_error() on RX init\n");
error = -ENOMEM;
goto rx_init_fail;
@@ -317,7 +317,7 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
struct ath_buf *bf;
int error = 0;
- spin_lock_init(&sc->rx.pcu_lock);
+ spin_lock_init(&sc->sc_pcu_lock);
sc->sc_flags &= ~SC_OP_RXFLUSH;
spin_lock_init(&sc->rx.rxbuflock);
@@ -327,17 +327,17 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
common->rx_bufsize = roundup(IEEE80211_MAX_MPDU_LEN,
min(common->cachelsz, (u16)64));
- ath_print(common, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n",
- common->cachelsz, common->rx_bufsize);
+ ath_dbg(common, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n",
+ common->cachelsz, common->rx_bufsize);
/* Initialize rx descriptors */
error = ath_descdma_setup(sc, &sc->rx.rxdma, &sc->rx.rxbuf,
"rx", nbufs, 1, 0);
if (error != 0) {
- ath_print(common, ATH_DBG_FATAL,
- "failed to allocate rx descriptors: %d\n",
- error);
+ ath_err(common,
+ "failed to allocate rx descriptors: %d\n",
+ error);
goto err;
}
@@ -358,8 +358,8 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL;
bf->bf_buf_addr = 0;
- ath_print(common, ATH_DBG_FATAL,
- "dma_mapping_error() on RX init\n");
+ ath_err(common,
+ "dma_mapping_error() on RX init\n");
error = -ENOMEM;
goto err;
}
@@ -528,6 +528,12 @@ bool ath_stoprecv(struct ath_softc *sc)
sc->rx.rxlink = NULL;
spin_unlock_bh(&sc->rx.rxbuflock);
+ if (unlikely(!stopped)) {
+ ath_err(ath9k_hw_common(sc->sc_ah),
+ "Could not stop RX, we could be "
+ "confusing the DMA engine when we start RX up\n");
+ ATH_DBG_WARN_ON_ONCE(!stopped);
+ }
return stopped;
}
@@ -588,9 +594,8 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
if (sc->ps_flags & PS_BEACON_SYNC) {
sc->ps_flags &= ~PS_BEACON_SYNC;
- ath_print(common, ATH_DBG_PS,
- "Reconfigure Beacon timers based on "
- "timestamp from the AP\n");
+ ath_dbg(common, ATH_DBG_PS,
+ "Reconfigure Beacon timers based on timestamp from the AP\n");
ath_beacon_config(sc, NULL);
}
@@ -602,8 +607,8 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
* a backup trigger for returning into NETWORK SLEEP state,
* so we are waiting for it as well.
*/
- ath_print(common, ATH_DBG_PS, "Received DTIM beacon indicating "
- "buffered broadcast/multicast frame(s)\n");
+ ath_dbg(common, ATH_DBG_PS,
+ "Received DTIM beacon indicating buffered broadcast/multicast frame(s)\n");
sc->ps_flags |= PS_WAIT_FOR_CAB | PS_WAIT_FOR_BEACON;
return;
}
@@ -615,8 +620,8 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
* been delivered.
*/
sc->ps_flags &= ~PS_WAIT_FOR_CAB;
- ath_print(common, ATH_DBG_PS,
- "PS wait for CAB frames timed out\n");
+ ath_dbg(common, ATH_DBG_PS,
+ "PS wait for CAB frames timed out\n");
}
}
@@ -641,15 +646,14 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb)
* point.
*/
sc->ps_flags &= ~(PS_WAIT_FOR_CAB | PS_WAIT_FOR_BEACON);
- ath_print(common, ATH_DBG_PS,
- "All PS CAB frames received, back to sleep\n");
+ ath_dbg(common, ATH_DBG_PS,
+ "All PS CAB frames received, back to sleep\n");
} else if ((sc->ps_flags & PS_WAIT_FOR_PSPOLL_DATA) &&
!is_multicast_ether_addr(hdr->addr1) &&
!ieee80211_has_morefrags(hdr->frame_control)) {
sc->ps_flags &= ~PS_WAIT_FOR_PSPOLL_DATA;
- ath_print(common, ATH_DBG_PS,
- "Going back to sleep after having received "
- "PS-Poll data (0x%lx)\n",
+ ath_dbg(common, ATH_DBG_PS,
+ "Going back to sleep after having received PS-Poll data (0x%lx)\n",
sc->ps_flags & (PS_WAIT_FOR_BEACON |
PS_WAIT_FOR_CAB |
PS_WAIT_FOR_PSPOLL_DATA |
@@ -658,8 +662,7 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb)
}
static void ath_rx_send_to_mac80211(struct ieee80211_hw *hw,
- struct ath_softc *sc, struct sk_buff *skb,
- struct ieee80211_rx_status *rxs)
+ struct ath_softc *sc, struct sk_buff *skb)
{
struct ieee80211_hdr *hdr;
@@ -958,8 +961,9 @@ static int ath9k_process_rate(struct ath_common *common,
* No valid hardware bitrate found -- we should not get here
* because hardware has already validated this frame as OK.
*/
- ath_print(common, ATH_DBG_XMIT, "unsupported hw bitrate detected "
- "0x%02x using 1 Mbit\n", rx_stats->rs_rate);
+ ath_dbg(common, ATH_DBG_XMIT,
+ "unsupported hw bitrate detected 0x%02x using 1 Mbit\n",
+ rx_stats->rs_rate);
return -EINVAL;
}
@@ -969,36 +973,23 @@ static void ath9k_process_rssi(struct ath_common *common,
struct ieee80211_hdr *hdr,
struct ath_rx_status *rx_stats)
{
+ struct ath_wiphy *aphy = hw->priv;
struct ath_hw *ah = common->ah;
- struct ieee80211_sta *sta;
- struct ath_node *an;
- int last_rssi = ATH_RSSI_DUMMY_MARKER;
+ int last_rssi;
__le16 fc;
+ if (ah->opmode != NL80211_IFTYPE_STATION)
+ return;
+
fc = hdr->frame_control;
+ if (!ieee80211_is_beacon(fc) ||
+ compare_ether_addr(hdr->addr3, common->curbssid))
+ return;
- rcu_read_lock();
- /*
- * XXX: use ieee80211_find_sta! This requires quite a bit of work
- * under the current ath9k virtual wiphy implementation as we have
- * no way of tying a vif to wiphy. Typically vifs are attached to
- * at least one sdata of a wiphy on mac80211 but with ath9k virtual
- * wiphy you'd have to iterate over every wiphy and each sdata.
- */
- if (is_multicast_ether_addr(hdr->addr1))
- sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr2, NULL);
- else
- sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr2, hdr->addr1);
-
- if (sta) {
- an = (struct ath_node *) sta->drv_priv;
- if (rx_stats->rs_rssi != ATH9K_RSSI_BAD &&
- !rx_stats->rs_moreaggr)
- ATH_RSSI_LPF(an->last_rssi, rx_stats->rs_rssi);
- last_rssi = an->last_rssi;
- }
- rcu_read_unlock();
+ if (rx_stats->rs_rssi != ATH9K_RSSI_BAD && !rx_stats->rs_moreaggr)
+ ATH_RSSI_LPF(aphy->last_rssi, rx_stats->rs_rssi);
+ last_rssi = aphy->last_rssi;
if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
rx_stats->rs_rssi = ATH_EP_RND(last_rssi,
ATH_RSSI_EP_MULTIPLIER);
@@ -1006,8 +997,7 @@ static void ath9k_process_rssi(struct ath_common *common,
rx_stats->rs_rssi = 0;
/* Update Beacon RSSI, this is used by ANI. */
- if (ieee80211_is_beacon(fc))
- ah->stats.avgbrssi = rx_stats->rs_rssi;
+ ah->stats.avgbrssi = rx_stats->rs_rssi;
}
/*
@@ -1637,7 +1627,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
/*
- * The hw can techncically differ from common->hw when using ath9k
+ * The hw can technically differ from common->hw when using ath9k
* virtual wiphy so to account for that we iterate over the active
* wiphys and find the appropriate wiphy and therefore hw.
*/
@@ -1744,9 +1734,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
dev_kfree_skb_any(requeue_skb);
bf->bf_mpdu = NULL;
bf->bf_buf_addr = 0;
- ath_print(common, ATH_DBG_FATAL,
- "dma_mapping_error() on RX\n");
- ath_rx_send_to_mac80211(hw, sc, skb, rxs);
+ ath_err(common, "dma_mapping_error() on RX\n");
+ ath_rx_send_to_mac80211(hw, sc, skb);
break;
}
@@ -1762,17 +1751,18 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
}
spin_lock_irqsave(&sc->sc_pm_lock, flags);
- if (unlikely(ath9k_check_auto_sleep(sc) ||
- (sc->ps_flags & (PS_WAIT_FOR_BEACON |
+
+ if ((sc->ps_flags & (PS_WAIT_FOR_BEACON |
PS_WAIT_FOR_CAB |
- PS_WAIT_FOR_PSPOLL_DATA))))
+ PS_WAIT_FOR_PSPOLL_DATA)) ||
+ unlikely(ath9k_check_auto_sleep(sc)))
ath_rx_ps(sc, skb);
spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
if (ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB)
ath_ant_comb_scan(sc, &rs);
- ath_rx_send_to_mac80211(hw, sc, skb, rxs);
+ ath_rx_send_to_mac80211(hw, sc, skb);
requeue:
if (edma) {
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index 2c6a22fbb0f0..4df5659c6c16 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -787,6 +787,8 @@
#define AR_SREV_REVISION_9271_11 1
#define AR_SREV_VERSION_9300 0x1c0
#define AR_SREV_REVISION_9300_20 2 /* 2.0 and 2.1 */
+#define AR_SREV_VERSION_9485 0x240
+#define AR_SREV_REVISION_9485_10 0
#define AR_SREV_5416(_ah) \
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \
@@ -859,20 +861,24 @@
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300) && \
((_ah)->hw_version.macRev >= AR_SREV_REVISION_9300_20)))
+#define AR_SREV_9485(_ah) \
+ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9485))
+#define AR_SREV_9485_10(_ah) \
+ (AR_SREV_9485(_ah) && \
+ ((_ah)->hw_version.macRev == AR_SREV_REVISION_9485_10))
+
#define AR_SREV_9285E_20(_ah) \
(AR_SREV_9285_12_OR_LATER(_ah) && \
((REG_READ(_ah, AR_AN_SYNTH9) & 0x7) == 0x1))
-#define AR_DEVID_7010(_ah) \
- (((_ah)->hw_version.devid == 0x7010) || \
- ((_ah)->hw_version.devid == 0x7015) || \
- ((_ah)->hw_version.devid == 0x9018) || \
- ((_ah)->hw_version.devid == 0xA704) || \
- ((_ah)->hw_version.devid == 0x1200))
+enum ath_usb_dev {
+ AR9280_USB = 1, /* AR7010 + AR9280, UB94 */
+ AR9287_USB = 2, /* AR7010 + AR9287, UB95 */
+};
-#define AR9287_HTC_DEVID(_ah) \
- (((_ah)->hw_version.devid == 0x7015) || \
- ((_ah)->hw_version.devid == 0x1200))
+#define AR_DEVID_7010(_ah) \
+ (((_ah)->hw_version.usbdev == AR9280_USB) || \
+ ((_ah)->hw_version.usbdev == AR9287_USB))
#define AR_RADIO_SREV_MAJOR 0xf0
#define AR_RAD5133_SREV_MAJOR 0xc0
@@ -1074,6 +1080,9 @@ enum {
#define AR_INTR_PRIO_ASYNC_MASK 0x40c8
#define AR_INTR_PRIO_SYNC_MASK 0x40cc
#define AR_INTR_PRIO_ASYNC_ENABLE 0x40d4
+#define AR_ENT_OTP 0x40d8
+#define AR_ENT_OTP_CHAIN2_DISABLE 0x00020000
+#define AR_ENT_OTP_MPSD 0x00800000
#define AR_RTC_9300_PLL_DIV 0x000003ff
#define AR_RTC_9300_PLL_DIV_S 0
@@ -1111,6 +1120,8 @@ enum {
#define AR_RTC_PLL_CONTROL \
((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0014) : 0x7014)
+#define AR_RTC_PLL_CONTROL2 0x703c
+
#define AR_RTC_PLL_DIV 0x0000001f
#define AR_RTC_PLL_DIV_S 0
#define AR_RTC_PLL_DIV2 0x00000020
@@ -1574,6 +1585,7 @@ enum {
#define AR_PCU_TBTT_PROTECT 0x00200000
#define AR_PCU_CLEAR_VMF 0x01000000
#define AR_PCU_CLEAR_BA_VALID 0x04000000
+#define AR_PCU_ALWAYS_PERFORM_KEYSEARCH 0x10000000
#define AR_PCU_BT_ANT_PREVENT_RX 0x00100000
#define AR_PCU_BT_ANT_PREVENT_RX_S 20
diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c
index ec7cf5ee56bc..fbfbc8239971 100644
--- a/drivers/net/wireless/ath/ath9k/virtual.c
+++ b/drivers/net/wireless/ath/ath9k/virtual.c
@@ -107,6 +107,7 @@ int ath9k_wiphy_add(struct ath_softc *sc)
aphy->sc = sc;
aphy->hw = hw;
sc->sec_wiphy[i] = aphy;
+ aphy->last_rssi = ATH_RSSI_DUMMY_MARKER;
spin_unlock_bh(&sc->wiphy_lock);
memcpy(addr, common->macaddr, ETH_ALEN);
@@ -186,7 +187,7 @@ static int ath9k_send_nullfunc(struct ath_wiphy *aphy,
info->control.rates[1].idx = -1;
memset(&txctl, 0, sizeof(struct ath_tx_control));
- txctl.txq = &sc->tx.txq[sc->tx.hwq_map[WME_AC_VO]];
+ txctl.txq = sc->tx.txq_map[WME_AC_VO];
txctl.frame_type = ps ? ATH9K_IFT_PAUSE : ATH9K_IFT_UNPAUSE;
if (ath_tx_start(aphy->hw, skb, &txctl) != 0)
@@ -304,13 +305,12 @@ void ath9k_wiphy_chan_work(struct work_struct *work)
* ath9k version of ieee80211_tx_status() for TX frames that are generated
* internally in the driver.
*/
-void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
+void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, int ftype)
{
struct ath_wiphy *aphy = hw->priv;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
- if ((tx_info->pad[0] & ATH_TX_INFO_FRAME_TYPE_PAUSE) &&
- aphy->state == ATH_WIPHY_PAUSING) {
+ if (ftype == ATH9K_IFT_PAUSE && aphy->state == ATH_WIPHY_PAUSING) {
if (!(tx_info->flags & IEEE80211_TX_STAT_ACK)) {
printk(KERN_DEBUG "ath9k: %s: no ACK for pause "
"frame\n", wiphy_name(hw->wiphy));
@@ -656,10 +656,9 @@ void ath9k_set_wiphy_idle(struct ath_wiphy *aphy, bool idle)
struct ath_softc *sc = aphy->sc;
aphy->idle = idle;
- ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG,
- "Marking %s as %s\n",
- wiphy_name(aphy->hw->wiphy),
- idle ? "idle" : "not-idle");
+ ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG,
+ "Marking %s as %sidle\n",
+ wiphy_name(aphy->hw->wiphy), idle ? "" : "not-");
}
/* Only bother starting a queue on an active virtual wiphy */
bool ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue)
diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c
index 93a8bda09c25..8f42ea78198c 100644
--- a/drivers/net/wireless/ath/ath9k/wmi.c
+++ b/drivers/net/wireless/ath/ath9k/wmi.c
@@ -125,7 +125,7 @@ void ath9k_wmi_tasklet(unsigned long data)
struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
struct ath_common *common = ath9k_hw_common(priv->ah);
- ath_print(common, ATH_DBG_WMI, "SWBA Event received\n");
+ ath_dbg(common, ATH_DBG_WMI, "SWBA Event received\n");
ath9k_htc_swba(priv, priv->wmi->beacon_pending);
@@ -286,9 +286,9 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
time_left = wait_for_completion_timeout(&wmi->cmd_wait, timeout);
if (!time_left) {
- ath_print(common, ATH_DBG_WMI,
- "Timeout waiting for WMI command: %s\n",
- wmi_cmd_to_name(cmd_id));
+ ath_dbg(common, ATH_DBG_WMI,
+ "Timeout waiting for WMI command: %s\n",
+ wmi_cmd_to_name(cmd_id));
mutex_unlock(&wmi->op_mutex);
return -ETIMEDOUT;
}
@@ -298,8 +298,8 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
return 0;
out:
- ath_print(common, ATH_DBG_WMI,
- "WMI failure for: %s\n", wmi_cmd_to_name(cmd_id));
+ ath_dbg(common, ATH_DBG_WMI,
+ "WMI failure for: %s\n", wmi_cmd_to_name(cmd_id));
mutex_unlock(&wmi->op_mutex);
kfree_skb(skb);
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index aff04789f794..43c0109f202c 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -48,19 +48,17 @@ static u16 bits_per_symbol[][2] = {
#define IS_HT_RATE(_rate) ((_rate) & 0x80)
-static void ath_tx_send_ht_normal(struct ath_softc *sc, struct ath_txq *txq,
- struct ath_atx_tid *tid,
- struct list_head *bf_head);
+static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
+ struct ath_atx_tid *tid,
+ struct list_head *bf_head);
static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
struct ath_txq *txq, struct list_head *bf_q,
struct ath_tx_status *ts, int txok, int sendbar);
static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
struct list_head *head);
-static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf);
-static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
- struct ath_tx_status *ts, int txok);
+static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len);
static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts,
- int nbad, int txok, bool update_rc);
+ int nframes, int nbad, int txok, bool update_rc);
static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
int seqno);
@@ -124,7 +122,7 @@ static void ath_tx_queue_tid(struct ath_txq *txq, struct ath_atx_tid *tid)
static void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
{
- struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum];
+ struct ath_txq *txq = tid->ac->txq;
WARN_ON(!tid->paused);
@@ -140,12 +138,21 @@ unlock:
spin_unlock_bh(&txq->axq_lock);
}
+static struct ath_frame_info *get_frame_info(struct sk_buff *skb)
+{
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+ BUILD_BUG_ON(sizeof(struct ath_frame_info) >
+ sizeof(tx_info->rate_driver_data));
+ return (struct ath_frame_info *) &tx_info->rate_driver_data[0];
+}
+
static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
{
- struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum];
+ struct ath_txq *txq = tid->ac->txq;
struct ath_buf *bf;
struct list_head bf_head;
struct ath_tx_status ts;
+ struct ath_frame_info *fi;
INIT_LIST_HEAD(&bf_head);
@@ -156,12 +163,15 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
list_move_tail(&bf->list, &bf_head);
- if (bf_isretried(bf)) {
- ath_tx_update_baw(sc, tid, bf->bf_seqno);
+ spin_unlock_bh(&txq->axq_lock);
+ fi = get_frame_info(bf->bf_mpdu);
+ if (fi->retries) {
+ ath_tx_update_baw(sc, tid, fi->seqno);
ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0);
} else {
- ath_tx_send_ht_normal(sc, txq, tid, &bf_head);
+ ath_tx_send_normal(sc, txq, tid, &bf_head);
}
+ spin_lock_bh(&txq->axq_lock);
}
spin_unlock_bh(&txq->axq_lock);
@@ -184,14 +194,11 @@ static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
}
static void ath_tx_addto_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
- struct ath_buf *bf)
+ u16 seqno)
{
int index, cindex;
- if (bf_isretried(bf))
- return;
-
- index = ATH_BA_INDEX(tid->seq_start, bf->bf_seqno);
+ index = ATH_BA_INDEX(tid->seq_start, seqno);
cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1);
__set_bit(cindex, tid->tx_buf);
@@ -215,6 +222,7 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq,
struct ath_buf *bf;
struct list_head bf_head;
struct ath_tx_status ts;
+ struct ath_frame_info *fi;
memset(&ts, 0, sizeof(ts));
INIT_LIST_HEAD(&bf_head);
@@ -226,8 +234,9 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq,
bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
list_move_tail(&bf->list, &bf_head);
- if (bf_isretried(bf))
- ath_tx_update_baw(sc, tid, bf->bf_seqno);
+ fi = get_frame_info(bf->bf_mpdu);
+ if (fi->retries)
+ ath_tx_update_baw(sc, tid, fi->seqno);
spin_unlock(&txq->axq_lock);
ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0);
@@ -239,16 +248,15 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq,
}
static void ath_tx_set_retry(struct ath_softc *sc, struct ath_txq *txq,
- struct ath_buf *bf)
+ struct sk_buff *skb)
{
- struct sk_buff *skb;
+ struct ath_frame_info *fi = get_frame_info(skb);
struct ieee80211_hdr *hdr;
- bf->bf_state.bf_type |= BUF_RETRY;
- bf->bf_retries++;
TX_STAT_INC(txq->axq_qnum, a_retries);
+ if (fi->retries++ > 0)
+ return;
- skb = bf->bf_mpdu;
hdr = (struct ieee80211_hdr *)skb->data;
hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_RETRY);
}
@@ -298,9 +306,41 @@ static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf)
return tbf;
}
+static void ath_tx_count_frames(struct ath_softc *sc, struct ath_buf *bf,
+ struct ath_tx_status *ts, int txok,
+ int *nframes, int *nbad)
+{
+ struct ath_frame_info *fi;
+ u16 seq_st = 0;
+ u32 ba[WME_BA_BMP_SIZE >> 5];
+ int ba_index;
+ int isaggr = 0;
+
+ *nbad = 0;
+ *nframes = 0;
+
+ isaggr = bf_isaggr(bf);
+ if (isaggr) {
+ seq_st = ts->ts_seqnum;
+ memcpy(ba, &ts->ba_low, WME_BA_BMP_SIZE >> 3);
+ }
+
+ while (bf) {
+ fi = get_frame_info(bf->bf_mpdu);
+ ba_index = ATH_BA_INDEX(seq_st, fi->seqno);
+
+ (*nframes)++;
+ if (!txok || (isaggr && !ATH_BA_ISSET(ba, ba_index)))
+ (*nbad)++;
+
+ bf = bf->bf_next;
+ }
+}
+
+
static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
struct ath_buf *bf, struct list_head *bf_q,
- struct ath_tx_status *ts, int txok)
+ struct ath_tx_status *ts, int txok, bool retry)
{
struct ath_node *an = NULL;
struct sk_buff *skb;
@@ -316,7 +356,9 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0;
bool rc_update = true;
struct ieee80211_tx_rate rates[4];
+ struct ath_frame_info *fi;
int nframes;
+ u8 tidno;
skb = bf->bf_mpdu;
hdr = (struct ieee80211_hdr *)skb->data;
@@ -325,7 +367,6 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
hw = bf->aphy->hw;
memcpy(rates, tx_info->control.rates, sizeof(rates));
- nframes = bf->bf_nframes;
rcu_read_lock();
@@ -342,7 +383,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
!bf->bf_stale || bf_next != NULL)
list_move_tail(&bf->list, &bf_head);
- ath_tx_rc_status(bf, ts, 1, 0, false);
+ ath_tx_rc_status(bf, ts, 1, 1, 0, false);
ath_tx_complete_buf(sc, bf, txq, &bf_head, ts,
0, 0);
@@ -352,14 +393,15 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
}
an = (struct ath_node *)sta->drv_priv;
- tid = ATH_AN_2_TID(an, bf->bf_tidno);
+ tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK;
+ tid = ATH_AN_2_TID(an, tidno);
/*
* The hardware occasionally sends a tx status for the wrong TID.
* In this case, the BA status cannot be considered valid and all
* subframes need to be retransmitted
*/
- if (bf->bf_tidno != ts->tid)
+ if (tidno != ts->tid)
txok = false;
isaggr = bf_isaggr(bf);
@@ -385,15 +427,16 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
INIT_LIST_HEAD(&bf_pending);
INIT_LIST_HEAD(&bf_head);
- nbad = ath_tx_num_badfrms(sc, bf, ts, txok);
+ ath_tx_count_frames(sc, bf, ts, txok, &nframes, &nbad);
while (bf) {
txfail = txpending = 0;
bf_next = bf->bf_next;
skb = bf->bf_mpdu;
tx_info = IEEE80211_SKB_CB(skb);
+ fi = get_frame_info(skb);
- if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, bf->bf_seqno))) {
+ if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, fi->seqno))) {
/* transmit completion, subframe is
* acked by block ack */
acked_cnt++;
@@ -401,10 +444,9 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
/* transmit completion */
acked_cnt++;
} else {
- if (!(tid->state & AGGR_CLEANUP) &&
- !bf_last->bf_tx_aborted) {
- if (bf->bf_retries < ATH_MAX_SW_RETRIES) {
- ath_tx_set_retry(sc, txq, bf);
+ if (!(tid->state & AGGR_CLEANUP) && retry) {
+ if (fi->retries < ATH_MAX_SW_RETRIES) {
+ ath_tx_set_retry(sc, txq, bf->bf_mpdu);
txpending = 1;
} else {
bf->bf_state.bf_type |= BUF_XRETRY;
@@ -442,16 +484,15 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
* block-ack window
*/
spin_lock_bh(&txq->axq_lock);
- ath_tx_update_baw(sc, tid, bf->bf_seqno);
+ ath_tx_update_baw(sc, tid, fi->seqno);
spin_unlock_bh(&txq->axq_lock);
if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) {
memcpy(tx_info->control.rates, rates, sizeof(rates));
- bf->bf_nframes = nframes;
- ath_tx_rc_status(bf, ts, nbad, txok, true);
+ ath_tx_rc_status(bf, ts, nframes, nbad, txok, true);
rc_update = false;
} else {
- ath_tx_rc_status(bf, ts, nbad, txok, false);
+ ath_tx_rc_status(bf, ts, nframes, nbad, txok, false);
}
ath_tx_complete_buf(sc, bf, txq, &bf_head, ts,
@@ -470,14 +511,13 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
*/
if (!tbf) {
spin_lock_bh(&txq->axq_lock);
- ath_tx_update_baw(sc, tid,
- bf->bf_seqno);
+ ath_tx_update_baw(sc, tid, fi->seqno);
spin_unlock_bh(&txq->axq_lock);
bf->bf_state.bf_type |=
BUF_XRETRY;
- ath_tx_rc_status(bf, ts, nbad,
- 0, false);
+ ath_tx_rc_status(bf, ts, nframes,
+ nbad, 0, false);
ath_tx_complete_buf(sc, bf, txq,
&bf_head,
ts, 0, 0);
@@ -611,6 +651,7 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
u16 minlen;
u8 flags, rix;
int width, streams, half_gi, ndelim, mindelim;
+ struct ath_frame_info *fi = get_frame_info(bf->bf_mpdu);
/* Select standard number of delimiters based on frame length alone */
ndelim = ATH_AGGR_GET_NDELIM(frmlen);
@@ -621,7 +662,7 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
* TODO - this could be improved to be dependent on the rate.
* The hardware can keep up at lower rates, but not higher rates
*/
- if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR)
+ if (fi->keyix != ATH9K_TXKEYIX_INVALID)
ndelim += ATH_AGGR_ENCRYPTDELIM;
/*
@@ -665,7 +706,8 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
struct ath_txq *txq,
struct ath_atx_tid *tid,
- struct list_head *bf_q)
+ struct list_head *bf_q,
+ int *aggr_len)
{
#define PADBYTES(_len) ((4 - ((_len) % 4)) % 4)
struct ath_buf *bf, *bf_first, *bf_prev = NULL;
@@ -674,14 +716,16 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
al_delta, h_baw = tid->baw_size / 2;
enum ATH_AGGR_STATUS status = ATH_AGGR_DONE;
struct ieee80211_tx_info *tx_info;
+ struct ath_frame_info *fi;
bf_first = list_first_entry(&tid->buf_q, struct ath_buf, list);
do {
bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
+ fi = get_frame_info(bf->bf_mpdu);
/* do not step over block-ack window */
- if (!BAW_WITHIN(tid->seq_start, tid->baw_size, bf->bf_seqno)) {
+ if (!BAW_WITHIN(tid->seq_start, tid->baw_size, fi->seqno)) {
status = ATH_AGGR_BAW_CLOSED;
break;
}
@@ -692,7 +736,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
}
/* do not exceed aggregation limit */
- al_delta = ATH_AGGR_DELIM_SZ + bf->bf_frmlen;
+ al_delta = ATH_AGGR_DELIM_SZ + fi->framelen;
if (nframes &&
(aggr_limit < (al + bpad + al_delta + prev_al))) {
@@ -719,14 +763,15 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
* Get the delimiters needed to meet the MPDU
* density for this node.
*/
- ndelim = ath_compute_num_delims(sc, tid, bf_first, bf->bf_frmlen);
+ ndelim = ath_compute_num_delims(sc, tid, bf_first, fi->framelen);
bpad = PADBYTES(al_delta) + (ndelim << 2);
bf->bf_next = NULL;
ath9k_hw_set_desc_link(sc->sc_ah, bf->bf_desc, 0);
/* link buffers of this frame to the aggregate */
- ath_tx_addto_baw(sc, tid, bf);
+ if (!fi->retries)
+ ath_tx_addto_baw(sc, tid, fi->seqno);
ath9k_hw_set11n_aggr_middle(sc->sc_ah, bf->bf_desc, ndelim);
list_move_tail(&bf->list, bf_q);
if (bf_prev) {
@@ -738,8 +783,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
} while (!list_empty(&tid->buf_q));
- bf_first->bf_al = al;
- bf_first->bf_nframes = nframes;
+ *aggr_len = al;
return status;
#undef PADBYTES
@@ -750,7 +794,9 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
{
struct ath_buf *bf;
enum ATH_AGGR_STATUS status;
+ struct ath_frame_info *fi;
struct list_head bf_q;
+ int aggr_len;
do {
if (list_empty(&tid->buf_q))
@@ -758,7 +804,7 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
INIT_LIST_HEAD(&bf_q);
- status = ath_tx_form_aggr(sc, txq, tid, &bf_q);
+ status = ath_tx_form_aggr(sc, txq, tid, &bf_q, &aggr_len);
/*
* no frames picked up to be aggregated;
@@ -771,18 +817,20 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
bf->bf_lastbf = list_entry(bf_q.prev, struct ath_buf, list);
/* if only one frame, send as non-aggregate */
- if (bf->bf_nframes == 1) {
+ if (bf == bf->bf_lastbf) {
+ fi = get_frame_info(bf->bf_mpdu);
+
bf->bf_state.bf_type &= ~BUF_AGGR;
ath9k_hw_clr11n_aggr(sc->sc_ah, bf->bf_desc);
- ath_buf_set_rate(sc, bf);
+ ath_buf_set_rate(sc, bf, fi->framelen);
ath_tx_txqaddbuf(sc, txq, &bf_q);
continue;
}
/* setup first desc of aggregate */
bf->bf_state.bf_type |= BUF_AGGR;
- ath_buf_set_rate(sc, bf);
- ath9k_hw_set11n_aggr_first(sc->sc_ah, bf->bf_desc, bf->bf_al);
+ ath_buf_set_rate(sc, bf, aggr_len);
+ ath9k_hw_set11n_aggr_first(sc->sc_ah, bf->bf_desc, aggr_len);
/* anchor last desc of aggregate */
ath9k_hw_set11n_aggr_last(sc->sc_ah, bf->bf_lastbf->bf_desc);
@@ -817,7 +865,7 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
{
struct ath_node *an = (struct ath_node *)sta->drv_priv;
struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid);
- struct ath_txq *txq = &sc->tx.txq[txtid->ac->qnum];
+ struct ath_txq *txq = txtid->ac->txq;
if (txtid->state & AGGR_CLEANUP)
return;
@@ -888,10 +936,16 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
struct ath9k_tx_queue_info qi;
+ static const int subtype_txq_to_hwq[] = {
+ [WME_AC_BE] = ATH_TXQ_AC_BE,
+ [WME_AC_BK] = ATH_TXQ_AC_BK,
+ [WME_AC_VI] = ATH_TXQ_AC_VI,
+ [WME_AC_VO] = ATH_TXQ_AC_VO,
+ };
int qnum, i;
memset(&qi, 0, sizeof(qi));
- qi.tqi_subtype = subtype;
+ qi.tqi_subtype = subtype_txq_to_hwq[subtype];
qi.tqi_aifs = ATH9K_TXQ_USEDEFAULT;
qi.tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
qi.tqi_cwmax = ATH9K_TXQ_USEDEFAULT;
@@ -931,16 +985,14 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
return NULL;
}
if (qnum >= ARRAY_SIZE(sc->tx.txq)) {
- ath_print(common, ATH_DBG_FATAL,
- "qnum %u out of range, max %u!\n",
- qnum, (unsigned int)ARRAY_SIZE(sc->tx.txq));
+ ath_err(common, "qnum %u out of range, max %zu!\n",
+ qnum, ARRAY_SIZE(sc->tx.txq));
ath9k_hw_releasetxqueue(ah, qnum);
return NULL;
}
if (!ATH_TXQ_SETUP(sc, qnum)) {
struct ath_txq *txq = &sc->tx.txq[qnum];
- txq->axq_class = subtype;
txq->axq_qnum = qnum;
txq->axq_link = NULL;
INIT_LIST_HEAD(&txq->axq_q);
@@ -985,8 +1037,8 @@ int ath_txq_update(struct ath_softc *sc, int qnum,
qi.tqi_readyTime = qinfo->tqi_readyTime;
if (!ath9k_hw_set_txq_props(ah, qnum, &qi)) {
- ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
- "Unable to update hardware queue %u!\n", qnum);
+ ath_err(ath9k_hw_common(sc->sc_ah),
+ "Unable to update hardware queue %u!\n", qnum);
error = -EIO;
} else {
ath9k_hw_resettxqueue(ah, qnum);
@@ -1062,8 +1114,6 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
}
lastbf = bf->bf_lastbf;
- if (!retry_tx)
- lastbf->bf_tx_aborted = true;
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
list_cut_position(&bf_head,
@@ -1080,7 +1130,8 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
spin_unlock_bh(&txq->axq_lock);
if (bf_isampdu(bf))
- ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, 0);
+ ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, 0,
+ retry_tx);
else
ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0);
}
@@ -1101,7 +1152,7 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
if (bf_isampdu(bf))
ath_tx_complete_aggr(sc, txq, bf, &bf_head,
- &ts, 0);
+ &ts, 0, retry_tx);
else
ath_tx_complete_buf(sc, bf, txq, &bf_head,
&ts, 0, 0);
@@ -1143,7 +1194,7 @@ bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
}
if (npend)
- ath_print(common, ATH_DBG_FATAL, "Failed to stop TX DMA!\n");
+ ath_err(common, "Failed to stop TX DMA!\n");
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
if (ATH_TXQ_SETUP(sc, i))
@@ -1202,24 +1253,6 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
}
}
-int ath_tx_setup(struct ath_softc *sc, int haltype)
-{
- struct ath_txq *txq;
-
- if (haltype >= ARRAY_SIZE(sc->tx.hwq_map)) {
- ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
- "HAL AC %u out of range, max %zu!\n",
- haltype, ARRAY_SIZE(sc->tx.hwq_map));
- return 0;
- }
- txq = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, haltype);
- if (txq != NULL) {
- sc->tx.hwq_map[haltype] = txq->axq_qnum;
- return 1;
- } else
- return 0;
-}
-
/***********/
/* TX, DMA */
/***********/
@@ -1245,8 +1278,8 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
bf = list_first_entry(head, struct ath_buf, list);
- ath_print(common, ATH_DBG_QUEUE,
- "qnum: %d, txq depth: %d\n", txq->axq_qnum, txq->axq_depth);
+ ath_dbg(common, ATH_DBG_QUEUE,
+ "qnum: %d, txq depth: %d\n", txq->axq_qnum, txq->axq_depth);
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
if (txq->axq_depth >= ATH_TXFIFO_DEPTH) {
@@ -1254,32 +1287,29 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
return;
}
if (!list_empty(&txq->txq_fifo[txq->txq_headidx]))
- ath_print(common, ATH_DBG_XMIT,
- "Initializing tx fifo %d which "
- "is non-empty\n",
- txq->txq_headidx);
+ ath_dbg(common, ATH_DBG_XMIT,
+ "Initializing tx fifo %d which is non-empty\n",
+ txq->txq_headidx);
INIT_LIST_HEAD(&txq->txq_fifo[txq->txq_headidx]);
list_splice_init(head, &txq->txq_fifo[txq->txq_headidx]);
INCR(txq->txq_headidx, ATH_TXFIFO_DEPTH);
ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
- ath_print(common, ATH_DBG_XMIT,
- "TXDP[%u] = %llx (%p)\n",
- txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc);
+ ath_dbg(common, ATH_DBG_XMIT, "TXDP[%u] = %llx (%p)\n",
+ txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc);
} else {
list_splice_tail_init(head, &txq->axq_q);
if (txq->axq_link == NULL) {
ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
- ath_print(common, ATH_DBG_XMIT,
- "TXDP[%u] = %llx (%p)\n",
- txq->axq_qnum, ito64(bf->bf_daddr),
- bf->bf_desc);
+ ath_dbg(common, ATH_DBG_XMIT, "TXDP[%u] = %llx (%p)\n",
+ txq->axq_qnum, ito64(bf->bf_daddr),
+ bf->bf_desc);
} else {
*txq->axq_link = bf->bf_daddr;
- ath_print(common, ATH_DBG_XMIT,
- "link[%u] (%p)=%llx (%p)\n",
- txq->axq_qnum, txq->axq_link,
- ito64(bf->bf_daddr), bf->bf_desc);
+ ath_dbg(common, ATH_DBG_XMIT,
+ "link[%u] (%p)=%llx (%p)\n",
+ txq->axq_qnum, txq->axq_link,
+ ito64(bf->bf_daddr), bf->bf_desc);
}
ath9k_hw_get_desc_link(ah, bf->bf_lastbf->bf_desc,
&txq->axq_link);
@@ -1289,12 +1319,11 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
}
static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
- struct list_head *bf_head,
- struct ath_tx_control *txctl)
+ struct ath_buf *bf, struct ath_tx_control *txctl)
{
- struct ath_buf *bf;
+ struct ath_frame_info *fi = get_frame_info(bf->bf_mpdu);
+ struct list_head bf_head;
- bf = list_first_entry(bf_head, struct ath_buf, list);
bf->bf_state.bf_type |= BUF_AMPDU;
TX_STAT_INC(txctl->txq->axq_qnum, a_queued);
@@ -1306,56 +1335,47 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
* - h/w queue depth exceeds low water mark
*/
if (!list_empty(&tid->buf_q) || tid->paused ||
- !BAW_WITHIN(tid->seq_start, tid->baw_size, bf->bf_seqno) ||
+ !BAW_WITHIN(tid->seq_start, tid->baw_size, fi->seqno) ||
txctl->txq->axq_depth >= ATH_AGGR_MIN_QDEPTH) {
/*
* Add this frame to software queue for scheduling later
* for aggregation.
*/
- list_move_tail(&bf->list, &tid->buf_q);
+ list_add_tail(&bf->list, &tid->buf_q);
ath_tx_queue_tid(txctl->txq, tid);
return;
}
+ INIT_LIST_HEAD(&bf_head);
+ list_add(&bf->list, &bf_head);
+
/* Add sub-frame to BAW */
- ath_tx_addto_baw(sc, tid, bf);
+ if (!fi->retries)
+ ath_tx_addto_baw(sc, tid, fi->seqno);
/* Queue to h/w without aggregation */
- bf->bf_nframes = 1;
bf->bf_lastbf = bf;
- ath_buf_set_rate(sc, bf);
- ath_tx_txqaddbuf(sc, txctl->txq, bf_head);
+ ath_buf_set_rate(sc, bf, fi->framelen);
+ ath_tx_txqaddbuf(sc, txctl->txq, &bf_head);
}
-static void ath_tx_send_ht_normal(struct ath_softc *sc, struct ath_txq *txq,
- struct ath_atx_tid *tid,
- struct list_head *bf_head)
+static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
+ struct ath_atx_tid *tid,
+ struct list_head *bf_head)
{
+ struct ath_frame_info *fi;
struct ath_buf *bf;
bf = list_first_entry(bf_head, struct ath_buf, list);
bf->bf_state.bf_type &= ~BUF_AMPDU;
/* update starting sequence number for subsequent ADDBA request */
- INCR(tid->seq_start, IEEE80211_SEQ_MAX);
-
- bf->bf_nframes = 1;
- bf->bf_lastbf = bf;
- ath_buf_set_rate(sc, bf);
- ath_tx_txqaddbuf(sc, txq, bf_head);
- TX_STAT_INC(txq->axq_qnum, queued);
-}
-
-static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
- struct list_head *bf_head)
-{
- struct ath_buf *bf;
-
- bf = list_first_entry(bf_head, struct ath_buf, list);
+ if (tid)
+ INCR(tid->seq_start, IEEE80211_SEQ_MAX);
bf->bf_lastbf = bf;
- bf->bf_nframes = 1;
- ath_buf_set_rate(sc, bf);
+ fi = get_frame_info(bf->bf_mpdu);
+ ath_buf_set_rate(sc, bf, fi->framelen);
ath_tx_txqaddbuf(sc, txq, bf_head);
TX_STAT_INC(txq->axq_qnum, queued);
}
@@ -1383,40 +1403,52 @@ static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb)
return htype;
}
-static void assign_aggr_tid_seqno(struct sk_buff *skb,
- struct ath_buf *bf)
+static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb,
+ int framelen)
{
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_sta *sta = tx_info->control.sta;
+ struct ieee80211_key_conf *hw_key = tx_info->control.hw_key;
struct ieee80211_hdr *hdr;
+ struct ath_frame_info *fi = get_frame_info(skb);
struct ath_node *an;
struct ath_atx_tid *tid;
- __le16 fc;
- u8 *qc;
+ enum ath9k_key_type keytype;
+ u16 seqno = 0;
+ u8 tidno;
- if (!tx_info->control.sta)
- return;
+ keytype = ath9k_cmn_get_hw_crypto_keytype(skb);
- an = (struct ath_node *)tx_info->control.sta->drv_priv;
hdr = (struct ieee80211_hdr *)skb->data;
- fc = hdr->frame_control;
+ if (sta && ieee80211_is_data_qos(hdr->frame_control) &&
+ conf_is_ht(&hw->conf) && (sc->sc_flags & SC_OP_TXAGGR)) {
- if (ieee80211_is_data_qos(fc)) {
- qc = ieee80211_get_qos_ctl(hdr);
- bf->bf_tidno = qc[0] & 0xf;
+ an = (struct ath_node *) sta->drv_priv;
+ tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK;
+
+ /*
+ * Override seqno set by upper layer with the one
+ * in tx aggregation state.
+ */
+ tid = ATH_AN_2_TID(an, tidno);
+ seqno = tid->seq_next;
+ hdr->seq_ctrl = cpu_to_le16(seqno << IEEE80211_SEQ_SEQ_SHIFT);
+ INCR(tid->seq_next, IEEE80211_SEQ_MAX);
}
- /*
- * For HT capable stations, we save tidno for later use.
- * We also override seqno set by upper layer with the one
- * in tx aggregation state.
- */
- tid = ATH_AN_2_TID(an, bf->bf_tidno);
- hdr->seq_ctrl = cpu_to_le16(tid->seq_next << IEEE80211_SEQ_SEQ_SHIFT);
- bf->bf_seqno = tid->seq_next;
- INCR(tid->seq_next, IEEE80211_SEQ_MAX);
+ memset(fi, 0, sizeof(*fi));
+ if (hw_key)
+ fi->keyix = hw_key->hw_key_idx;
+ else
+ fi->keyix = ATH9K_TXKEYIX_INVALID;
+ fi->keytype = keytype;
+ fi->framelen = framelen;
+ fi->seqno = seqno;
}
-static int setup_tx_flags(struct sk_buff *skb, bool use_ldpc)
+static int setup_tx_flags(struct sk_buff *skb)
{
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
int flags = 0;
@@ -1427,7 +1459,7 @@ static int setup_tx_flags(struct sk_buff *skb, bool use_ldpc)
if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK)
flags |= ATH9K_TXDESC_NOACK;
- if (use_ldpc)
+ if (tx_info->flags & IEEE80211_TX_CTL_LDPC)
flags |= ATH9K_TXDESC_LDPC;
return flags;
@@ -1439,13 +1471,11 @@ static int setup_tx_flags(struct sk_buff *skb, bool use_ldpc)
* width - 0 for 20 MHz, 1 for 40 MHz
* half_gi - to use 4us v/s 3.6 us for symbol time
*/
-static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf,
+static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, int pktlen,
int width, int half_gi, bool shortPreamble)
{
u32 nbits, nsymbits, duration, nsymbols;
- int streams, pktlen;
-
- pktlen = bf_isaggr(bf) ? bf->bf_al : bf->bf_frmlen;
+ int streams;
/* find number of symbols: PLCP + data */
streams = HT_RC_2_STREAMS(rix);
@@ -1464,7 +1494,19 @@ static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf,
return duration;
}
-static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
+u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate)
+{
+ struct ath_hw *ah = sc->sc_ah;
+ struct ath9k_channel *curchan = ah->curchan;
+ if ((sc->sc_flags & SC_OP_ENABLE_APM) &&
+ (curchan->channelFlags & CHANNEL_5GHZ) &&
+ (chainmask == 0x7) && (rate < 0x90))
+ return 0x3;
+ else
+ return chainmask;
+}
+
+static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len)
{
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
struct ath9k_11n_rate_series series[4];
@@ -1504,7 +1546,6 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
rix = rates[i].idx;
series[i].Tries = rates[i].count;
- series[i].ChSel = common->tx_chainmask;
if ((sc->config.ath_aggr_prot && bf_isaggr(bf)) ||
(rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS)) {
@@ -1527,14 +1568,16 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
if (rates[i].flags & IEEE80211_TX_RC_MCS) {
/* MCS rates */
series[i].Rate = rix | 0x80;
- series[i].PktDuration = ath_pkt_duration(sc, rix, bf,
+ series[i].ChSel = ath_txchainmask_reduction(sc,
+ common->tx_chainmask, series[i].Rate);
+ series[i].PktDuration = ath_pkt_duration(sc, rix, len,
is_40, is_sgi, is_sp);
if (rix < 8 && (tx_info->flags & IEEE80211_TX_CTL_STBC))
series[i].RateFlags |= ATH9K_RATESERIES_STBC;
continue;
}
- /* legcay rates */
+ /* legacy rates */
if ((tx_info->band == IEEE80211_BAND_2GHZ) &&
!(rate->flags & IEEE80211_RATE_ERP_G))
phy = WLAN_RC_PHY_CCK;
@@ -1550,12 +1593,18 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
is_sp = false;
}
+ if (bf->bf_state.bfs_paprd)
+ series[i].ChSel = common->tx_chainmask;
+ else
+ series[i].ChSel = ath_txchainmask_reduction(sc,
+ common->tx_chainmask, series[i].Rate);
+
series[i].PktDuration = ath9k_hw_computetxtime(sc->sc_ah,
- phy, rate->bitrate * 100, bf->bf_frmlen, rix, is_sp);
+ phy, rate->bitrate * 100, len, rix, is_sp);
}
/* For AR5416 - RTS cannot be followed by a frame larger than 8K */
- if (bf_isaggr(bf) && (bf->bf_al > sc->sc_ah->caps.rts_aggr_limit))
+ if (bf_isaggr(bf) && (len > sc->sc_ah->caps.rts_aggr_limit))
flags &= ~ATH9K_TXDESC_RTSENA;
/* ATH9K_TXDESC_RTSENA and ATH9K_TXDESC_CTSENA are mutually exclusive. */
@@ -1572,67 +1621,29 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
ath9k_hw_set11n_burstduration(sc->sc_ah, bf->bf_desc, 8192);
}
-static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
- struct sk_buff *skb,
- struct ath_tx_control *txctl)
+static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw,
+ struct ath_txq *txq,
+ struct sk_buff *skb)
{
struct ath_wiphy *aphy = hw->priv;
struct ath_softc *sc = aphy->sc;
- struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- int hdrlen;
- __le16 fc;
- int padpos, padsize;
- bool use_ldpc = false;
+ struct ath_hw *ah = sc->sc_ah;
+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+ struct ath_frame_info *fi = get_frame_info(skb);
+ struct ath_buf *bf;
+ struct ath_desc *ds;
+ int frm_type;
- tx_info->pad[0] = 0;
- switch (txctl->frame_type) {
- case ATH9K_IFT_NOT_INTERNAL:
- break;
- case ATH9K_IFT_PAUSE:
- tx_info->pad[0] |= ATH_TX_INFO_FRAME_TYPE_PAUSE;
- /* fall through */
- case ATH9K_IFT_UNPAUSE:
- tx_info->pad[0] |= ATH_TX_INFO_FRAME_TYPE_INTERNAL;
- break;
+ bf = ath_tx_get_buffer(sc);
+ if (!bf) {
+ ath_dbg(common, ATH_DBG_XMIT, "TX buffers are full\n");
+ return NULL;
}
- hdrlen = ieee80211_get_hdrlen_from_skb(skb);
- fc = hdr->frame_control;
ATH_TXBUF_RESET(bf);
bf->aphy = aphy;
- bf->bf_frmlen = skb->len + FCS_LEN;
- /* Remove the padding size from bf_frmlen, if any */
- padpos = ath9k_cmn_padpos(hdr->frame_control);
- padsize = padpos & 3;
- if (padsize && skb->len>padpos+padsize) {
- bf->bf_frmlen -= padsize;
- }
-
- if (!txctl->paprd && conf_is_ht(&hw->conf)) {
- bf->bf_state.bf_type |= BUF_HT;
- if (tx_info->flags & IEEE80211_TX_CTL_LDPC)
- use_ldpc = true;
- }
-
- bf->bf_state.bfs_paprd = txctl->paprd;
- if (txctl->paprd)
- bf->bf_state.bfs_paprd_timestamp = jiffies;
- bf->bf_flags = setup_tx_flags(skb, use_ldpc);
-
- bf->bf_keytype = ath9k_cmn_get_hw_crypto_keytype(skb);
- if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR) {
- bf->bf_frmlen += tx_info->control.hw_key->icv_len;
- bf->bf_keyix = tx_info->control.hw_key->hw_key_idx;
- } else {
- bf->bf_keyix = ATH9K_TXKEYIX_INVALID;
- }
-
- if (ieee80211_is_data_qos(fc) && bf_isht(bf) &&
- (sc->sc_flags & SC_OP_TXAGGR))
- assign_aggr_tid_seqno(skb, bf);
-
+ bf->bf_flags = setup_tx_flags(skb);
bf->bf_mpdu = skb;
bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
@@ -1640,42 +1651,19 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) {
bf->bf_mpdu = NULL;
bf->bf_buf_addr = 0;
- ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
- "dma_mapping_error() on TX\n");
- return -ENOMEM;
+ ath_err(ath9k_hw_common(sc->sc_ah),
+ "dma_mapping_error() on TX\n");
+ ath_tx_return_buffer(sc, bf);
+ return NULL;
}
- bf->bf_tx_aborted = false;
-
- return 0;
-}
-
-/* FIXME: tx power */
-static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
- struct ath_tx_control *txctl)
-{
- struct sk_buff *skb = bf->bf_mpdu;
- struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- struct ath_node *an = NULL;
- struct list_head bf_head;
- struct ath_desc *ds;
- struct ath_atx_tid *tid;
- struct ath_hw *ah = sc->sc_ah;
- int frm_type;
- __le16 fc;
-
frm_type = get_hw_packet_type(skb);
- fc = hdr->frame_control;
-
- INIT_LIST_HEAD(&bf_head);
- list_add_tail(&bf->list, &bf_head);
ds = bf->bf_desc;
ath9k_hw_set_desc_link(ah, ds, 0);
- ath9k_hw_set11n_txdesc(ah, ds, bf->bf_frmlen, frm_type, MAX_RATE_POWER,
- bf->bf_keyix, bf->bf_keytype, bf->bf_flags);
+ ath9k_hw_set11n_txdesc(ah, ds, fi->framelen, frm_type, MAX_RATE_POWER,
+ fi->keyix, fi->keytype, bf->bf_flags);
ath9k_hw_filltxdesc(ah, ds,
skb->len, /* segment length */
@@ -1683,42 +1671,50 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
true, /* last segment */
ds, /* first descriptor */
bf->bf_buf_addr,
- txctl->txq->axq_qnum);
+ txq->axq_qnum);
- if (bf->bf_state.bfs_paprd)
- ar9003_hw_set_paprd_txdesc(ah, ds, bf->bf_state.bfs_paprd);
- spin_lock_bh(&txctl->txq->axq_lock);
+ return bf;
+}
+
+/* FIXME: tx power */
+static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
+ struct ath_tx_control *txctl)
+{
+ struct sk_buff *skb = bf->bf_mpdu;
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ struct list_head bf_head;
+ struct ath_atx_tid *tid;
+ u8 tidno;
- if (bf_isht(bf) && (sc->sc_flags & SC_OP_TXAGGR) &&
- tx_info->control.sta) {
- an = (struct ath_node *)tx_info->control.sta->drv_priv;
- tid = ATH_AN_2_TID(an, bf->bf_tidno);
+ spin_lock_bh(&txctl->txq->axq_lock);
- if (!ieee80211_is_data_qos(fc)) {
- ath_tx_send_normal(sc, txctl->txq, &bf_head);
- goto tx_done;
- }
+ if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && txctl->an) {
+ tidno = ieee80211_get_qos_ctl(hdr)[0] &
+ IEEE80211_QOS_CTL_TID_MASK;
+ tid = ATH_AN_2_TID(txctl->an, tidno);
- if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
- /*
- * Try aggregation if it's a unicast data frame
- * and the destination is HT capable.
- */
- ath_tx_send_ampdu(sc, tid, &bf_head, txctl);
- } else {
- /*
- * Send this frame as regular when ADDBA
- * exchange is neither complete nor pending.
- */
- ath_tx_send_ht_normal(sc, txctl->txq,
- tid, &bf_head);
- }
+ WARN_ON(tid->ac->txq != txctl->txq);
+ /*
+ * Try aggregation if it's a unicast data frame
+ * and the destination is HT capable.
+ */
+ ath_tx_send_ampdu(sc, tid, bf, txctl);
} else {
- ath_tx_send_normal(sc, txctl->txq, &bf_head);
+ INIT_LIST_HEAD(&bf_head);
+ list_add_tail(&bf->list, &bf_head);
+
+ bf->bf_state.bfs_ftype = txctl->frame_type;
+ bf->bf_state.bfs_paprd = txctl->paprd;
+
+ if (bf->bf_state.bfs_paprd)
+ ar9003_hw_set_paprd_txdesc(sc->sc_ah, bf->bf_desc,
+ bf->bf_state.bfs_paprd);
+
+ ath_tx_send_normal(sc, txctl->txq, NULL, &bf_head);
}
-tx_done:
spin_unlock_bh(&txctl->txq->axq_lock);
}
@@ -1726,66 +1722,23 @@ tx_done:
int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
struct ath_tx_control *txctl)
{
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_sta *sta = info->control.sta;
struct ath_wiphy *aphy = hw->priv;
struct ath_softc *sc = aphy->sc;
- struct ath_common *common = ath9k_hw_common(sc->sc_ah);
struct ath_txq *txq = txctl->txq;
struct ath_buf *bf;
- int q, r;
-
- bf = ath_tx_get_buffer(sc);
- if (!bf) {
- ath_print(common, ATH_DBG_XMIT, "TX buffers are full\n");
- return -1;
- }
-
- r = ath_tx_setup_buffer(hw, bf, skb, txctl);
- if (unlikely(r)) {
- ath_print(common, ATH_DBG_FATAL, "TX mem alloc failure\n");
-
- /* upon ath_tx_processq() this TX queue will be resumed, we
- * guarantee this will happen by knowing beforehand that
- * we will at least have to run TX completionon one buffer
- * on the queue */
- spin_lock_bh(&txq->axq_lock);
- if (!txq->stopped && txq->axq_depth > 1) {
- ath_mac80211_stop_queue(sc, skb_get_queue_mapping(skb));
- txq->stopped = 1;
- }
- spin_unlock_bh(&txq->axq_lock);
-
- ath_tx_return_buffer(sc, bf);
-
- return r;
- }
-
- q = skb_get_queue_mapping(skb);
- if (q >= 4)
- q = 0;
-
- spin_lock_bh(&txq->axq_lock);
- if (++sc->tx.pending_frames[q] > ATH_MAX_QDEPTH && !txq->stopped) {
- ath_mac80211_stop_queue(sc, skb_get_queue_mapping(skb));
- txq->stopped = 1;
- }
- spin_unlock_bh(&txq->axq_lock);
-
- ath_tx_start_dma(sc, bf, txctl);
-
- return 0;
-}
-
-void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb)
-{
- struct ath_wiphy *aphy = hw->priv;
- struct ath_softc *sc = aphy->sc;
- struct ath_common *common = ath9k_hw_common(sc->sc_ah);
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
int padpos, padsize;
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- struct ath_tx_control txctl;
+ int frmlen = skb->len + FCS_LEN;
+ int q;
+
+ /* NOTE: sta can be NULL according to net/mac80211.h */
+ if (sta)
+ txctl->an = (struct ath_node *)sta->drv_priv;
- memset(&txctl, 0, sizeof(struct ath_tx_control));
+ if (info->control.hw_key)
+ frmlen += info->control.hw_key->icv_len;
/*
* As a temporary workaround, assign seq# here; this will likely need
@@ -1802,30 +1755,37 @@ void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb)
/* Add the padding after the header if this is not already done */
padpos = ath9k_cmn_padpos(hdr->frame_control);
padsize = padpos & 3;
- if (padsize && skb->len>padpos) {
- if (skb_headroom(skb) < padsize) {
- ath_print(common, ATH_DBG_XMIT,
- "TX CABQ padding failed\n");
- dev_kfree_skb_any(skb);
- return;
- }
+ if (padsize && skb->len > padpos) {
+ if (skb_headroom(skb) < padsize)
+ return -ENOMEM;
+
skb_push(skb, padsize);
memmove(skb->data, skb->data + padsize, padpos);
}
- txctl.txq = sc->beacon.cabq;
+ setup_frame_info(hw, skb, frmlen);
- ath_print(common, ATH_DBG_XMIT,
- "transmitting CABQ packet, skb: %p\n", skb);
+ /*
+ * At this point, the vif, hw_key and sta pointers in the tx control
+ * info are no longer valid (overwritten by the ath_frame_info data.
+ */
+
+ bf = ath_tx_setup_buffer(hw, txctl->txq, skb);
+ if (unlikely(!bf))
+ return -ENOMEM;
- if (ath_tx_start(hw, skb, &txctl) != 0) {
- ath_print(common, ATH_DBG_XMIT, "CABQ TX failed\n");
- goto exit;
+ q = skb_get_queue_mapping(skb);
+ spin_lock_bh(&txq->axq_lock);
+ if (txq == sc->tx.txq_map[q] &&
+ ++txq->pending_frames > ATH_MAX_QDEPTH && !txq->stopped) {
+ ath_mac80211_stop_queue(sc, q);
+ txq->stopped = 1;
}
+ spin_unlock_bh(&txq->axq_lock);
- return;
-exit:
- dev_kfree_skb_any(skb);
+ ath_tx_start_dma(sc, bf, txctl);
+
+ return 0;
}
/*****************/
@@ -1833,7 +1793,8 @@ exit:
/*****************/
static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
- struct ath_wiphy *aphy, int tx_flags)
+ struct ath_wiphy *aphy, int tx_flags, int ftype,
+ struct ath_txq *txq)
{
struct ieee80211_hw *hw = sc->hw;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
@@ -1841,7 +1802,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data;
int q, padpos, padsize;
- ath_print(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb);
+ ath_dbg(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb);
if (aphy)
hw = aphy->hw;
@@ -1867,24 +1828,24 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
if (sc->ps_flags & PS_WAIT_FOR_TX_ACK) {
sc->ps_flags &= ~PS_WAIT_FOR_TX_ACK;
- ath_print(common, ATH_DBG_PS,
- "Going back to sleep after having "
- "received TX status (0x%lx)\n",
+ ath_dbg(common, ATH_DBG_PS,
+ "Going back to sleep after having received TX status (0x%lx)\n",
sc->ps_flags & (PS_WAIT_FOR_BEACON |
PS_WAIT_FOR_CAB |
PS_WAIT_FOR_PSPOLL_DATA |
PS_WAIT_FOR_TX_ACK));
}
- if (unlikely(tx_info->pad[0] & ATH_TX_INFO_FRAME_TYPE_INTERNAL))
- ath9k_tx_status(hw, skb);
+ if (unlikely(ftype))
+ ath9k_tx_status(hw, skb, ftype);
else {
q = skb_get_queue_mapping(skb);
- if (q >= 4)
- q = 0;
-
- if (--sc->tx.pending_frames[q] < 0)
- sc->tx.pending_frames[q] = 0;
+ if (txq == sc->tx.txq_map[q]) {
+ spin_lock_bh(&txq->axq_lock);
+ if (WARN_ON(--txq->pending_frames < 0))
+ txq->pending_frames = 0;
+ spin_unlock_bh(&txq->axq_lock);
+ }
ieee80211_tx_status(hw, skb);
}
@@ -1912,15 +1873,14 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
bf->bf_buf_addr = 0;
if (bf->bf_state.bfs_paprd) {
- if (time_after(jiffies,
- bf->bf_state.bfs_paprd_timestamp +
- msecs_to_jiffies(ATH_PAPRD_TIMEOUT)))
+ if (!sc->paprd_pending)
dev_kfree_skb_any(skb);
else
complete(&sc->paprd_complete);
} else {
- ath_debug_stat_tx(sc, txq, bf, ts);
- ath_tx_complete(sc, skb, bf->aphy, tx_flags);
+ ath_debug_stat_tx(sc, bf, ts);
+ ath_tx_complete(sc, skb, bf->aphy, tx_flags,
+ bf->bf_state.bfs_ftype, txq);
}
/* At this point, skb (bf->bf_mpdu) is consumed...make sure we don't
* accidentally reference it later.
@@ -1935,42 +1895,15 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
spin_unlock_irqrestore(&sc->tx.txbuflock, flags);
}
-static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
- struct ath_tx_status *ts, int txok)
-{
- u16 seq_st = 0;
- u32 ba[WME_BA_BMP_SIZE >> 5];
- int ba_index;
- int nbad = 0;
- int isaggr = 0;
-
- if (bf->bf_lastbf->bf_tx_aborted)
- return 0;
-
- isaggr = bf_isaggr(bf);
- if (isaggr) {
- seq_st = ts->ts_seqnum;
- memcpy(ba, &ts->ba_low, WME_BA_BMP_SIZE >> 3);
- }
-
- while (bf) {
- ba_index = ATH_BA_INDEX(seq_st, bf->bf_seqno);
- if (!txok || (isaggr && !ATH_BA_ISSET(ba, ba_index)))
- nbad++;
-
- bf = bf->bf_next;
- }
-
- return nbad;
-}
-
static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts,
- int nbad, int txok, bool update_rc)
+ int nframes, int nbad, int txok, bool update_rc)
{
struct sk_buff *skb = bf->bf_mpdu;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
struct ieee80211_hw *hw = bf->aphy->hw;
+ struct ath_softc *sc = bf->aphy->sc;
+ struct ath_hw *ah = sc->sc_ah;
u8 i, tx_rateindex;
if (txok)
@@ -1984,22 +1917,32 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts,
if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && update_rc) {
tx_info->flags |= IEEE80211_TX_STAT_AMPDU;
- BUG_ON(nbad > bf->bf_nframes);
+ BUG_ON(nbad > nframes);
- tx_info->status.ampdu_len = bf->bf_nframes;
- tx_info->status.ampdu_ack_len = bf->bf_nframes - nbad;
+ tx_info->status.ampdu_len = nframes;
+ tx_info->status.ampdu_ack_len = nframes - nbad;
}
if ((ts->ts_status & ATH9K_TXERR_FILT) == 0 &&
(bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) {
- if (ieee80211_is_data(hdr->frame_control)) {
- if (ts->ts_flags &
- (ATH9K_TX_DATA_UNDERRUN | ATH9K_TX_DELIM_UNDERRUN))
- tx_info->pad[0] |= ATH_TX_INFO_UNDERRUN;
- if ((ts->ts_status & ATH9K_TXERR_XRETRY) ||
- (ts->ts_status & ATH9K_TXERR_FIFO))
- tx_info->pad[0] |= ATH_TX_INFO_XRETRY;
- }
+ /*
+ * If an underrun error is seen assume it as an excessive
+ * retry only if max frame trigger level has been reached
+ * (2 KB for single stream, and 4 KB for dual stream).
+ * Adjust the long retry as if the frame was tried
+ * hw->max_rate_tries times to affect how rate control updates
+ * PER for the failed rate.
+ * In case of congestion on the bus penalizing this type of
+ * underruns should help hardware actually transmit new frames
+ * successfully by eventually preferring slower rates.
+ * This itself should also alleviate congestion on the bus.
+ */
+ if (ieee80211_is_data(hdr->frame_control) &&
+ (ts->ts_flags & (ATH9K_TX_DATA_UNDERRUN |
+ ATH9K_TX_DELIM_UNDERRUN)) &&
+ ah->tx_trig_level >= sc->sc_ah->caps.tx_triglevel_max)
+ tx_info->status.rates[tx_rateindex].count =
+ hw->max_rate_tries;
}
for (i = tx_rateindex + 1; i < hw->max_rates; i++) {
@@ -2010,16 +1953,13 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts,
tx_info->status.rates[tx_rateindex].count = ts->ts_longretry + 1;
}
-static void ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq)
+static void ath_wake_mac80211_queue(struct ath_softc *sc, int qnum)
{
- int qnum;
-
- qnum = ath_get_mac80211_qnum(txq->axq_class, sc);
- if (qnum == -1)
- return;
+ struct ath_txq *txq;
+ txq = sc->tx.txq_map[qnum];
spin_lock_bh(&txq->axq_lock);
- if (txq->stopped && sc->tx.pending_frames[qnum] < ATH_MAX_QDEPTH) {
+ if (txq->stopped && txq->pending_frames < ATH_MAX_QDEPTH) {
if (ath_mac80211_start_queue(sc, qnum))
txq->stopped = 0;
}
@@ -2036,10 +1976,11 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
struct ath_tx_status ts;
int txok;
int status;
+ int qnum;
- ath_print(common, ATH_DBG_QUEUE, "tx queue %d (%x), link %p\n",
- txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum),
- txq->axq_link);
+ ath_dbg(common, ATH_DBG_QUEUE, "tx queue %d (%x), link %p\n",
+ txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum),
+ txq->axq_link);
for (;;) {
spin_lock_bh(&txq->axq_lock);
@@ -2108,15 +2049,19 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
*/
if (ts.ts_status & ATH9K_TXERR_XRETRY)
bf->bf_state.bf_type |= BUF_XRETRY;
- ath_tx_rc_status(bf, &ts, txok ? 0 : 1, txok, true);
+ ath_tx_rc_status(bf, &ts, 1, txok ? 0 : 1, txok, true);
}
+ qnum = skb_get_queue_mapping(bf->bf_mpdu);
+
if (bf_isampdu(bf))
- ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, txok);
+ ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, txok,
+ true);
else
ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, txok, 0);
- ath_wake_mac80211_queue(sc, txq);
+ if (txq == sc->tx.txq_map[qnum])
+ ath_wake_mac80211_queue(sc, qnum);
spin_lock_bh(&txq->axq_lock);
if (sc->sc_flags & SC_OP_TXAGGR)
@@ -2150,8 +2095,8 @@ static void ath_tx_complete_poll_work(struct work_struct *work)
}
if (needreset) {
- ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_RESET,
- "tx hung, resetting the chip\n");
+ ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_RESET,
+ "tx hung, resetting the chip\n");
ath9k_ps_wakeup(sc);
ath_reset(sc, true);
ath9k_ps_restore(sc);
@@ -2186,14 +2131,15 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
struct list_head bf_head;
int status;
int txok;
+ int qnum;
for (;;) {
status = ath9k_hw_txprocdesc(ah, NULL, (void *)&txs);
if (status == -EINPROGRESS)
break;
if (status == -EIO) {
- ath_print(common, ATH_DBG_XMIT,
- "Error processing tx status\n");
+ ath_dbg(common, ATH_DBG_XMIT,
+ "Error processing tx status\n");
break;
}
@@ -2226,16 +2172,20 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
if (!bf_isampdu(bf)) {
if (txs.ts_status & ATH9K_TXERR_XRETRY)
bf->bf_state.bf_type |= BUF_XRETRY;
- ath_tx_rc_status(bf, &txs, txok ? 0 : 1, txok, true);
+ ath_tx_rc_status(bf, &txs, 1, txok ? 0 : 1, txok, true);
}
+ qnum = skb_get_queue_mapping(bf->bf_mpdu);
+
if (bf_isampdu(bf))
- ath_tx_complete_aggr(sc, txq, bf, &bf_head, &txs, txok);
+ ath_tx_complete_aggr(sc, txq, bf, &bf_head, &txs,
+ txok, true);
else
ath_tx_complete_buf(sc, bf, txq, &bf_head,
&txs, txok, 0);
- ath_wake_mac80211_queue(sc, txq);
+ if (txq == sc->tx.txq_map[qnum])
+ ath_wake_mac80211_queue(sc, qnum);
spin_lock_bh(&txq->axq_lock);
if (!list_empty(&txq->txq_fifo_pending)) {
@@ -2300,16 +2250,16 @@ int ath_tx_init(struct ath_softc *sc, int nbufs)
error = ath_descdma_setup(sc, &sc->tx.txdma, &sc->tx.txbuf,
"tx", nbufs, 1, 1);
if (error != 0) {
- ath_print(common, ATH_DBG_FATAL,
- "Failed to allocate tx descriptors: %d\n", error);
+ ath_err(common,
+ "Failed to allocate tx descriptors: %d\n", error);
goto err;
}
error = ath_descdma_setup(sc, &sc->beacon.bdma, &sc->beacon.bbuf,
"beacon", ATH_BCBUF, 1, 1);
if (error != 0) {
- ath_print(common, ATH_DBG_FATAL,
- "Failed to allocate beacon descriptors: %d\n", error);
+ ath_err(common,
+ "Failed to allocate beacon descriptors: %d\n", error);
goto err;
}
@@ -2367,7 +2317,7 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
for (acno = 0, ac = &an->ac[acno];
acno < WME_NUM_AC; acno++, ac++) {
ac->sched = false;
- ac->qnum = sc->tx.hwq_map[acno];
+ ac->txq = sc->tx.txq_map[acno];
INIT_LIST_HEAD(&ac->tid_q);
}
}
@@ -2377,17 +2327,13 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
struct ath_atx_ac *ac;
struct ath_atx_tid *tid;
struct ath_txq *txq;
- int i, tidno;
+ int tidno;
for (tidno = 0, tid = &an->tid[tidno];
tidno < WME_NUM_TID; tidno++, tid++) {
- i = tid->ac->qnum;
-
- if (!ATH_TXQ_SETUP(sc, i))
- continue;
- txq = &sc->tx.txq[i];
ac = tid->ac;
+ txq = ac->txq;
spin_lock_bh(&txq->axq_lock);
diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h
index 6cf0c9ef47aa..d07ff7f2fd92 100644
--- a/drivers/net/wireless/ath/carl9170/carl9170.h
+++ b/drivers/net/wireless/ath/carl9170/carl9170.h
@@ -48,7 +48,7 @@
#include <linux/usb.h>
#ifdef CONFIG_CARL9170_LEDS
#include <linux/leds.h>
-#endif /* CONFIG_CARL170_LEDS */
+#endif /* CONFIG_CARL9170_LEDS */
#ifdef CONFIG_CARL9170_WPC
#include <linux/input.h>
#endif /* CONFIG_CARL9170_WPC */
@@ -215,7 +215,7 @@ enum carl9170_restart_reasons {
CARL9170_RR_TOO_MANY_FIRMWARE_ERRORS,
CARL9170_RR_WATCHDOG,
CARL9170_RR_STUCK_TX,
- CARL9170_RR_SLOW_SYSTEM,
+ CARL9170_RR_UNRESPONSIVE_DEVICE,
CARL9170_RR_COMMAND_TIMEOUT,
CARL9170_RR_TOO_MANY_PHY_ERRORS,
CARL9170_RR_LOST_RSP,
@@ -287,6 +287,7 @@ struct ar9170 {
/* reset / stuck frames/queue detection */
struct work_struct restart_work;
+ struct work_struct ping_work;
unsigned int restart_counter;
unsigned long queue_stop_timeout[__AR9170_NUM_TXQ];
unsigned long max_queue_stop_timeout[__AR9170_NUM_TXQ];
diff --git a/drivers/net/wireless/ath/carl9170/cmd.c b/drivers/net/wireless/ath/carl9170/cmd.c
index c21f3364bfec..cdfc94c371b4 100644
--- a/drivers/net/wireless/ath/carl9170/cmd.c
+++ b/drivers/net/wireless/ath/carl9170/cmd.c
@@ -41,7 +41,7 @@
int carl9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val)
{
- __le32 buf[2] = {
+ const __le32 buf[2] = {
cpu_to_le32(reg),
cpu_to_le32(val),
};
diff --git a/drivers/net/wireless/ath/carl9170/fwcmd.h b/drivers/net/wireless/ath/carl9170/fwcmd.h
index d552166db505..3680dfc70f46 100644
--- a/drivers/net/wireless/ath/carl9170/fwcmd.h
+++ b/drivers/net/wireless/ath/carl9170/fwcmd.h
@@ -97,13 +97,13 @@ struct carl9170_set_key_cmd {
__le16 type;
u8 macAddr[6];
u32 key[4];
-} __packed;
+} __packed __aligned(4);
#define CARL9170_SET_KEY_CMD_SIZE 28
struct carl9170_disable_key_cmd {
__le16 user;
__le16 padding;
-} __packed;
+} __packed __aligned(4);
#define CARL9170_DISABLE_KEY_CMD_SIZE 4
struct carl9170_u32_list {
@@ -206,7 +206,7 @@ struct carl9170_cmd {
struct carl9170_rx_filter_cmd rx_filter;
u8 data[CARL9170_MAX_CMD_PAYLOAD_LEN];
} __packed;
-} __packed;
+} __packed __aligned(4);
#define CARL9170_TX_STATUS_QUEUE 3
#define CARL9170_TX_STATUS_QUEUE_S 0
@@ -216,6 +216,7 @@ struct carl9170_cmd {
#define CARL9170_TX_STATUS_TRIES (7 << CARL9170_TX_STATUS_TRIES_S)
#define CARL9170_TX_STATUS_SUCCESS 0x80
+#ifdef __CARL9170FW__
/*
* NOTE:
* Both structs [carl9170_tx_status and _carl9170_tx_status]
@@ -232,6 +233,8 @@ struct carl9170_tx_status {
u8 tries:3;
u8 success:1;
} __packed;
+#endif /* __CARL9170FW__ */
+
struct _carl9170_tx_status {
/*
* This version should be immune to all alignment bugs.
@@ -272,13 +275,15 @@ struct carl9170_rsp {
struct carl9170_rf_init_result rf_init_res;
struct carl9170_u32_list rreg_res;
struct carl9170_u32_list echo;
+#ifdef __CARL9170FW__
struct carl9170_tx_status tx_status[0];
+#endif /* __CARL9170FW__ */
struct _carl9170_tx_status _tx_status[0];
struct carl9170_gpio gpio;
struct carl9170_tsf_rsp tsf;
struct carl9170_psm psm;
u8 data[CARL9170_MAX_CMD_PAYLOAD_LEN];
} __packed;
-} __packed;
+} __packed __aligned(4);
#endif /* __CARL9170_SHARED_FWCMD_H */
diff --git a/drivers/net/wireless/ath/carl9170/hw.h b/drivers/net/wireless/ath/carl9170/hw.h
index 2f471b3f05af..e85df6edfed3 100644
--- a/drivers/net/wireless/ath/carl9170/hw.h
+++ b/drivers/net/wireless/ath/carl9170/hw.h
@@ -712,7 +712,8 @@ struct ar9170_stream {
__le16 tag;
u8 payload[0];
-};
+} __packed __aligned(4);
+#define AR9170_STREAM_LEN 4
#define AR9170_MAX_ACKTABLE_ENTRIES 8
#define AR9170_MAX_VIRTUAL_MAC 7
@@ -736,4 +737,8 @@ struct ar9170_stream {
#define MOD_VAL(reg, value, newvalue) \
(((value) & ~reg) | (((newvalue) << reg##_S) & reg))
+
+#define GET_VAL(reg, value) \
+ (((value) & reg) >> reg##_S)
+
#endif /* __CARL9170_SHARED_HW_H */
diff --git a/drivers/net/wireless/ath/carl9170/mac.c b/drivers/net/wireless/ath/carl9170/mac.c
index 2305bc27151c..385cf508479b 100644
--- a/drivers/net/wireless/ath/carl9170/mac.c
+++ b/drivers/net/wireless/ath/carl9170/mac.c
@@ -205,8 +205,8 @@ int carl9170_init_mac(struct ar9170 *ar)
carl9170_regwrite(AR9170_MAC_REG_BACKOFF_PROTECT, 0x105);
/* Aggregation MAX number and timeout */
- carl9170_regwrite(AR9170_MAC_REG_AMPDU_FACTOR, 0xa);
- carl9170_regwrite(AR9170_MAC_REG_AMPDU_DENSITY, 0x140a00);
+ carl9170_regwrite(AR9170_MAC_REG_AMPDU_FACTOR, 0x8000a);
+ carl9170_regwrite(AR9170_MAC_REG_AMPDU_DENSITY, 0x140a07);
carl9170_regwrite(AR9170_MAC_REG_FRAMETYPE_FILTER,
AR9170_MAC_FTF_DEFAULTS);
@@ -457,8 +457,9 @@ int carl9170_set_beacon_timers(struct ar9170 *ar)
int carl9170_update_beacon(struct ar9170 *ar, const bool submit)
{
- struct sk_buff *skb;
+ struct sk_buff *skb = NULL;
struct carl9170_vif_info *cvif;
+ struct ieee80211_tx_info *txinfo;
__le32 *data, *old = NULL;
u32 word, off, addr, len;
int i = 0, err = 0;
@@ -487,7 +488,13 @@ found:
if (!skb) {
err = -ENOMEM;
- goto out_unlock;
+ goto err_free;
+ }
+
+ txinfo = IEEE80211_SKB_CB(skb);
+ if (txinfo->control.rates[0].flags & IEEE80211_TX_RC_MCS) {
+ err = -EINVAL;
+ goto err_free;
}
spin_lock_bh(&ar->beacon_lock);
@@ -504,11 +511,8 @@ found:
wiphy_err(ar->hw->wiphy, "beacon does not "
"fit into device memory!\n");
}
-
- spin_unlock_bh(&ar->beacon_lock);
- dev_kfree_skb_any(skb);
err = -EINVAL;
- goto out_unlock;
+ goto err_unlock;
}
if (len > AR9170_MAC_BCN_LENGTH_MAX) {
@@ -518,22 +522,22 @@ found:
AR9170_MAC_BCN_LENGTH_MAX, len);
}
- spin_unlock_bh(&ar->beacon_lock);
- dev_kfree_skb_any(skb);
err = -EMSGSIZE;
- goto out_unlock;
+ goto err_unlock;
}
- carl9170_async_regwrite_begin(ar);
+ i = txinfo->control.rates[0].idx;
+ if (txinfo->band != IEEE80211_BAND_2GHZ)
+ i += 4;
- /* XXX: use skb->cb info */
- if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) {
- carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP,
- ((skb->len + FCS_LEN) << (3 + 16)) + 0x0400);
- } else {
- carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP,
- ((skb->len + FCS_LEN) << 16) + 0x001b);
- }
+ word = __carl9170_ratetable[i].hw_value & 0xf;
+ if (i < 4)
+ word |= ((skb->len + FCS_LEN) << (3 + 16)) + 0x0400;
+ else
+ word |= ((skb->len + FCS_LEN) << 16) + 0x0010;
+
+ carl9170_async_regwrite_begin(ar);
+ carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP, word);
for (i = 0; i < DIV_ROUND_UP(skb->len, 4); i++) {
/*
@@ -557,7 +561,7 @@ found:
cvif->beacon = skb;
spin_unlock_bh(&ar->beacon_lock);
if (err)
- goto out_unlock;
+ goto err_free;
if (submit) {
err = carl9170_bcn_ctrl(ar, cvif->id,
@@ -565,10 +569,18 @@ found:
addr, skb->len + FCS_LEN);
if (err)
- goto out_unlock;
+ goto err_free;
}
out_unlock:
rcu_read_unlock();
+ return 0;
+
+err_unlock:
+ spin_unlock_bh(&ar->beacon_lock);
+
+err_free:
+ rcu_read_unlock();
+ dev_kfree_skb_any(skb);
return err;
}
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c
index dc7b30b170d0..870df8c42622 100644
--- a/drivers/net/wireless/ath/carl9170/main.c
+++ b/drivers/net/wireless/ath/carl9170/main.c
@@ -428,6 +428,7 @@ static void carl9170_cancel_worker(struct ar9170 *ar)
cancel_delayed_work_sync(&ar->led_work);
#endif /* CONFIG_CARL9170_LEDS */
cancel_work_sync(&ar->ps_work);
+ cancel_work_sync(&ar->ping_work);
cancel_work_sync(&ar->ampdu_work);
}
@@ -533,6 +534,21 @@ void carl9170_restart(struct ar9170 *ar, const enum carl9170_restart_reasons r)
*/
}
+static void carl9170_ping_work(struct work_struct *work)
+{
+ struct ar9170 *ar = container_of(work, struct ar9170, ping_work);
+ int err;
+
+ if (!IS_STARTED(ar))
+ return;
+
+ mutex_lock(&ar->mutex);
+ err = carl9170_echo_test(ar, 0xdeadbeef);
+ if (err)
+ carl9170_restart(ar, CARL9170_RR_UNRESPONSIVE_DEVICE);
+ mutex_unlock(&ar->mutex);
+}
+
static int carl9170_init_interface(struct ar9170 *ar,
struct ieee80211_vif *vif)
{
@@ -1614,6 +1630,7 @@ void *carl9170_alloc(size_t priv_size)
skb_queue_head_init(&ar->tx_pending[i]);
}
INIT_WORK(&ar->ps_work, carl9170_ps_work);
+ INIT_WORK(&ar->ping_work, carl9170_ping_work);
INIT_WORK(&ar->restart_work, carl9170_restart_work);
INIT_WORK(&ar->ampdu_work, carl9170_ampdu_work);
INIT_DELAYED_WORK(&ar->tx_janitor, carl9170_tx_janitor);
@@ -1829,7 +1846,7 @@ int carl9170_register(struct ar9170 *ar)
err = carl9170_led_register(ar);
if (err)
goto err_unreg;
-#endif /* CONFIG_CAR9L170_LEDS */
+#endif /* CONFIG_CARL9170_LEDS */
#ifdef CONFIG_CARL9170_WPC
err = carl9170_register_wps_button(ar);
diff --git a/drivers/net/wireless/ath/carl9170/phy.c b/drivers/net/wireless/ath/carl9170/phy.c
index 89deca37a988..82bc81c4c930 100644
--- a/drivers/net/wireless/ath/carl9170/phy.c
+++ b/drivers/net/wireless/ath/carl9170/phy.c
@@ -1554,15 +1554,6 @@ static int carl9170_set_power_cal(struct ar9170 *ar, u32 freq,
return carl9170_regwrite_result();
}
-/* TODO: replace this with sign_extend32(noise, 8) */
-static int carl9170_calc_noise_dbm(u32 raw_noise)
-{
- if (raw_noise & 0x100)
- return ~0x1ff | raw_noise;
- else
- return raw_noise;
-}
-
int carl9170_get_noisefloor(struct ar9170 *ar)
{
static const u32 phy_regs[] = {
@@ -1578,11 +1569,11 @@ int carl9170_get_noisefloor(struct ar9170 *ar)
return err;
for (i = 0; i < 2; i++) {
- ar->noise[i] = carl9170_calc_noise_dbm(
- (phy_res[i] >> 19) & 0x1ff);
+ ar->noise[i] = sign_extend32(GET_VAL(
+ AR9170_PHY_CCA_MIN_PWR, phy_res[i]), 8);
- ar->noise[i + 2] = carl9170_calc_noise_dbm(
- (phy_res[i + 2] >> 23) & 0x1ff);
+ ar->noise[i + 2] = sign_extend32(GET_VAL(
+ AR9170_PHY_EXT_CCA_MIN_PWR, phy_res[i + 2]), 8);
}
return 0;
diff --git a/drivers/net/wireless/ath/carl9170/phy.h b/drivers/net/wireless/ath/carl9170/phy.h
index 02c34eb4ebde..024fb42bc787 100644
--- a/drivers/net/wireless/ath/carl9170/phy.h
+++ b/drivers/net/wireless/ath/carl9170/phy.h
@@ -139,8 +139,8 @@
#define AR9170_PHY_AGC_CONTROL_NO_UPDATE_NF 0x00020000
#define AR9170_PHY_REG_CCA (AR9170_PHY_REG_BASE + 0x0064)
-#define AR9170_PHY_CCA_MINCCA_PWR 0x0ff80000
-#define AR9170_PHY_CCA_MINCCA_PWR_S 19
+#define AR9170_PHY_CCA_MIN_PWR 0x0ff80000
+#define AR9170_PHY_CCA_MIN_PWR_S 19
#define AR9170_PHY_CCA_THRESH62 0x0007f000
#define AR9170_PHY_CCA_THRESH62_S 12
@@ -338,8 +338,8 @@
#define AR9170_PHY_EXT_CCA_CYCPWR_THR1_S 9
#define AR9170_PHY_EXT_CCA_THRESH62 0x007f0000
#define AR9170_PHY_EXT_CCA_THRESH62_S 16
-#define AR9170_PHY_EXT_MINCCA_PWR 0xff800000
-#define AR9170_PHY_EXT_MINCCA_PWR_S 23
+#define AR9170_PHY_EXT_CCA_MIN_PWR 0xff800000
+#define AR9170_PHY_EXT_CCA_MIN_PWR_S 23
#define AR9170_PHY_REG_SFCORR_EXT (AR9170_PHY_REG_BASE + 0x01c0)
#define AR9170_PHY_SFCORR_EXT_M1_THRESH 0x0000007f
@@ -546,19 +546,19 @@
#define AR9170_PHY_FORCE_XPA_CFG_S 0
#define AR9170_PHY_REG_CH1_CCA (AR9170_PHY_REG_BASE + 0x1064)
-#define AR9170_PHY_CH1_MINCCA_PWR 0x0ff80000
-#define AR9170_PHY_CH1_MINCCA_PWR_S 19
+#define AR9170_PHY_CH1_CCA_MIN_PWR 0x0ff80000
+#define AR9170_PHY_CH1_CCA_MIN_PWR_S 19
#define AR9170_PHY_REG_CH2_CCA (AR9170_PHY_REG_BASE + 0x2064)
-#define AR9170_PHY_CH2_MINCCA_PWR 0x0ff80000
-#define AR9170_PHY_CH2_MINCCA_PWR_S 19
+#define AR9170_PHY_CH2_CCA_MIN_PWR 0x0ff80000
+#define AR9170_PHY_CH2_CCA_MIN_PWR_S 19
#define AR9170_PHY_REG_CH1_EXT_CCA (AR9170_PHY_REG_BASE + 0x11bc)
-#define AR9170_PHY_CH1_EXT_MINCCA_PWR 0xff800000
-#define AR9170_PHY_CH1_EXT_MINCCA_PWR_S 23
+#define AR9170_PHY_CH1_EXT_CCA_MIN_PWR 0xff800000
+#define AR9170_PHY_CH1_EXT_CCA_MIN_PWR_S 23
#define AR9170_PHY_REG_CH2_EXT_CCA (AR9170_PHY_REG_BASE + 0x21bc)
-#define AR9170_PHY_CH2_EXT_MINCCA_PWR 0xff800000
-#define AR9170_PHY_CH2_EXT_MINCCA_PWR_S 23
+#define AR9170_PHY_CH2_EXT_CCA_MIN_PWR 0xff800000
+#define AR9170_PHY_CH2_EXT_CCA_MIN_PWR_S 23
#endif /* __CARL9170_SHARED_PHY_H */
diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c
index 7e6506a77bbb..6cc58e052d10 100644
--- a/drivers/net/wireless/ath/carl9170/tx.c
+++ b/drivers/net/wireless/ath/carl9170/tx.c
@@ -242,9 +242,11 @@ static void carl9170_tx_release(struct kref *ref)
ar->tx_ampdu_schedule = true;
if (txinfo->flags & IEEE80211_TX_STAT_AMPDU) {
- txinfo->status.ampdu_len = txinfo->pad[0];
- txinfo->status.ampdu_ack_len = txinfo->pad[1];
- txinfo->pad[0] = txinfo->pad[1] = 0;
+ struct _carl9170_tx_superframe *super;
+
+ super = (void *)skb->data;
+ txinfo->status.ampdu_len = super->s.rix;
+ txinfo->status.ampdu_ack_len = super->s.cnt;
} else if (txinfo->flags & IEEE80211_TX_STAT_ACK) {
/*
* drop redundant tx_status reports:
@@ -337,7 +339,8 @@ static void carl9170_tx_status_process_ampdu(struct ar9170 *ar,
u8 tid;
if (!(txinfo->flags & IEEE80211_TX_CTL_AMPDU) ||
- txinfo->flags & IEEE80211_TX_CTL_INJECTED)
+ txinfo->flags & IEEE80211_TX_CTL_INJECTED ||
+ (!(super->f.mac_control & cpu_to_le16(AR9170_TX_MAC_AGGR))))
return;
tx_info = IEEE80211_SKB_CB(skb);
@@ -389,8 +392,8 @@ static void carl9170_tx_status_process_ampdu(struct ar9170 *ar,
sta_info->stats[tid].ampdu_ack_len++;
if (super->f.mac_control & cpu_to_le16(AR9170_TX_MAC_IMM_BA)) {
- txinfo->pad[0] = sta_info->stats[tid].ampdu_len;
- txinfo->pad[1] = sta_info->stats[tid].ampdu_ack_len;
+ super->s.rix = sta_info->stats[tid].ampdu_len;
+ super->s.cnt = sta_info->stats[tid].ampdu_ack_len;
txinfo->flags |= IEEE80211_TX_STAT_AMPDU;
sta_info->stats[tid].clear = true;
}
@@ -524,6 +527,59 @@ next:
}
}
+static void carl9170_tx_ampdu_timeout(struct ar9170 *ar)
+{
+ struct carl9170_sta_tid *iter;
+ struct sk_buff *skb;
+ struct ieee80211_tx_info *txinfo;
+ struct carl9170_tx_info *arinfo;
+ struct _carl9170_tx_superframe *super;
+ struct ieee80211_sta *sta;
+ struct ieee80211_vif *vif;
+ struct ieee80211_hdr *hdr;
+ unsigned int vif_id;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(iter, &ar->tx_ampdu_list, list) {
+ if (iter->state < CARL9170_TID_STATE_IDLE)
+ continue;
+
+ spin_lock_bh(&iter->lock);
+ skb = skb_peek(&iter->queue);
+ if (!skb)
+ goto unlock;
+
+ txinfo = IEEE80211_SKB_CB(skb);
+ arinfo = (void *)txinfo->rate_driver_data;
+ if (time_is_after_jiffies(arinfo->timeout +
+ msecs_to_jiffies(CARL9170_QUEUE_TIMEOUT)))
+ goto unlock;
+
+ super = (void *) skb->data;
+ hdr = (void *) super->frame_data;
+
+ vif_id = (super->s.misc & CARL9170_TX_SUPER_MISC_VIF_ID) >>
+ CARL9170_TX_SUPER_MISC_VIF_ID_S;
+
+ if (WARN_ON(vif_id >= AR9170_MAX_VIRTUAL_MAC))
+ goto unlock;
+
+ vif = rcu_dereference(ar->vif_priv[vif_id].vif);
+ if (WARN_ON(!vif))
+ goto unlock;
+
+ sta = ieee80211_find_sta(vif, hdr->addr1);
+ if (WARN_ON(!sta))
+ goto unlock;
+
+ ieee80211_stop_tx_ba_session(sta, iter->tid);
+unlock:
+ spin_unlock_bh(&iter->lock);
+
+ }
+ rcu_read_unlock();
+}
+
void carl9170_tx_janitor(struct work_struct *work)
{
struct ar9170 *ar = container_of(work, struct ar9170,
@@ -534,6 +590,7 @@ void carl9170_tx_janitor(struct work_struct *work)
ar->tx_janitor_last_run = jiffies;
carl9170_check_queue_stop_timeout(ar);
+ carl9170_tx_ampdu_timeout(ar);
if (!atomic_read(&ar->tx_total_queued))
return;
@@ -842,10 +899,8 @@ static int carl9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb)
if (unlikely(!sta || !cvif))
goto err_out;
- factor = min_t(unsigned int, 1u,
- info->control.sta->ht_cap.ampdu_factor);
-
- density = info->control.sta->ht_cap.ampdu_density;
+ factor = min_t(unsigned int, 1u, sta->ht_cap.ampdu_factor);
+ density = sta->ht_cap.ampdu_density;
if (density) {
/*
@@ -1206,6 +1261,7 @@ static void carl9170_tx(struct ar9170 *ar)
static bool carl9170_tx_ampdu_queue(struct ar9170 *ar,
struct ieee80211_sta *sta, struct sk_buff *skb)
{
+ struct _carl9170_tx_superframe *super = (void *) skb->data;
struct carl9170_sta_info *sta_info;
struct carl9170_sta_tid *agg;
struct sk_buff *iter;
@@ -1274,6 +1330,7 @@ err_unlock:
err_unlock_rcu:
rcu_read_unlock();
+ super->f.mac_control &= ~cpu_to_le16(AR9170_TX_MAC_AGGR);
carl9170_tx_status(ar, skb, false);
ar->tx_dropped++;
return false;
@@ -1302,9 +1359,6 @@ int carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
*/
if (info->flags & IEEE80211_TX_CTL_AMPDU) {
- if (WARN_ON_ONCE(!sta))
- goto err_free;
-
run = carl9170_tx_ampdu_queue(ar, sta, skb);
if (run)
carl9170_tx_ampdu(ar);
diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c
index 7504ed14c725..2d947a30d29e 100644
--- a/drivers/net/wireless/ath/carl9170/usb.c
+++ b/drivers/net/wireless/ath/carl9170/usb.c
@@ -160,8 +160,7 @@ err_acc:
static void carl9170_usb_tx_data_complete(struct urb *urb)
{
- struct ar9170 *ar = (struct ar9170 *)
- usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
+ struct ar9170 *ar = usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
if (WARN_ON_ONCE(!ar)) {
dev_kfree_skb_irq(urb->context);
@@ -433,7 +432,7 @@ static void carl9170_usb_rx_complete(struct urb *urb)
* device.
*/
- carl9170_restart(ar, CARL9170_RR_SLOW_SYSTEM);
+ ieee80211_queue_work(ar->hw, &ar->ping_work);
}
} else {
/*
diff --git a/drivers/net/wireless/ath/carl9170/version.h b/drivers/net/wireless/ath/carl9170/version.h
index ff53f078a0b5..ee0f84f2a2f6 100644
--- a/drivers/net/wireless/ath/carl9170/version.h
+++ b/drivers/net/wireless/ath/carl9170/version.h
@@ -1,7 +1,7 @@
#ifndef __CARL9170_SHARED_VERSION_H
#define __CARL9170_SHARED_VERSION_H
#define CARL9170FW_VERSION_YEAR 10
-#define CARL9170FW_VERSION_MONTH 9
-#define CARL9170FW_VERSION_DAY 28
-#define CARL9170FW_VERSION_GIT "1.8.8.3"
+#define CARL9170FW_VERSION_MONTH 10
+#define CARL9170FW_VERSION_DAY 29
+#define CARL9170FW_VERSION_GIT "1.9.0"
#endif /* __CARL9170_SHARED_VERSION_H */
diff --git a/drivers/net/wireless/ath/debug.c b/drivers/net/wireless/ath/debug.c
index dacfb234f491..5367b1086e09 100644
--- a/drivers/net/wireless/ath/debug.c
+++ b/drivers/net/wireless/ath/debug.c
@@ -15,21 +15,6 @@
*/
#include "ath.h"
-#include "debug.h"
-
-void ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...)
-{
- va_list args;
-
- if (likely(!(common->debug_mask & dbg_mask)))
- return;
-
- va_start(args, fmt);
- printk(KERN_DEBUG "ath: ");
- vprintk(fmt, args);
- va_end(args);
-}
-EXPORT_SYMBOL(ath_print);
const char *ath_opmode_to_string(enum nl80211_iftype opmode)
{
diff --git a/drivers/net/wireless/ath/debug.h b/drivers/net/wireless/ath/debug.h
deleted file mode 100644
index 64e4af2c2887..000000000000
--- a/drivers/net/wireless/ath/debug.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2008-2009 Atheros Communications Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef ATH_DEBUG_H
-#define ATH_DEBUG_H
-
-#include "ath.h"
-
-/**
- * enum ath_debug_level - atheros wireless debug level
- *
- * @ATH_DBG_RESET: reset processing
- * @ATH_DBG_QUEUE: hardware queue management
- * @ATH_DBG_EEPROM: eeprom processing
- * @ATH_DBG_CALIBRATE: periodic calibration
- * @ATH_DBG_INTERRUPT: interrupt processing
- * @ATH_DBG_REGULATORY: regulatory processing
- * @ATH_DBG_ANI: adaptive noise immunitive processing
- * @ATH_DBG_XMIT: basic xmit operation
- * @ATH_DBG_BEACON: beacon handling
- * @ATH_DBG_CONFIG: configuration of the hardware
- * @ATH_DBG_FATAL: fatal errors, this is the default, DBG_DEFAULT
- * @ATH_DBG_PS: power save processing
- * @ATH_DBG_HWTIMER: hardware timer handling
- * @ATH_DBG_BTCOEX: bluetooth coexistance
- * @ATH_DBG_BSTUCK: stuck beacons
- * @ATH_DBG_ANY: enable all debugging
- *
- * The debug level is used to control the amount and type of debugging output
- * we want to see. Each driver has its own method for enabling debugging and
- * modifying debug level states -- but this is typically done through a
- * module parameter 'debug' along with a respective 'debug' debugfs file
- * entry.
- */
-enum ATH_DEBUG {
- ATH_DBG_RESET = 0x00000001,
- ATH_DBG_QUEUE = 0x00000002,
- ATH_DBG_EEPROM = 0x00000004,
- ATH_DBG_CALIBRATE = 0x00000008,
- ATH_DBG_INTERRUPT = 0x00000010,
- ATH_DBG_REGULATORY = 0x00000020,
- ATH_DBG_ANI = 0x00000040,
- ATH_DBG_XMIT = 0x00000080,
- ATH_DBG_BEACON = 0x00000100,
- ATH_DBG_CONFIG = 0x00000200,
- ATH_DBG_FATAL = 0x00000400,
- ATH_DBG_PS = 0x00000800,
- ATH_DBG_HWTIMER = 0x00001000,
- ATH_DBG_BTCOEX = 0x00002000,
- ATH_DBG_WMI = 0x00004000,
- ATH_DBG_BSTUCK = 0x00008000,
- ATH_DBG_ANY = 0xffffffff
-};
-
-#define ATH_DBG_DEFAULT (ATH_DBG_FATAL)
-
-#ifdef CONFIG_ATH_DEBUG
-void ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...)
- __attribute__ ((format (printf, 3, 4)));
-#else
-static inline void __attribute__ ((format (printf, 3, 4)))
-ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...)
-{
-}
-#endif /* CONFIG_ATH_DEBUG */
-
-/** Returns string describing opmode, or NULL if unknown mode. */
-#ifdef CONFIG_ATH_DEBUG
-const char *ath_opmode_to_string(enum nl80211_iftype opmode);
-#else
-static inline const char *ath_opmode_to_string(enum nl80211_iftype opmode)
-{
- return "UNKNOWN";
-}
-#endif
-
-#endif /* ATH_DEBUG_H */
diff --git a/drivers/net/wireless/ath/key.c b/drivers/net/wireless/ath/key.c
index bd21a4d82085..29a2961af5fc 100644
--- a/drivers/net/wireless/ath/key.c
+++ b/drivers/net/wireless/ath/key.c
@@ -20,7 +20,6 @@
#include "ath.h"
#include "reg.h"
-#include "debug.h"
#define REG_READ (common->ops->read)
#define REG_WRITE(_ah, _reg, _val) (common->ops->write)(_ah, _val, _reg)
@@ -37,8 +36,7 @@ bool ath_hw_keyreset(struct ath_common *common, u16 entry)
void *ah = common->ah;
if (entry >= common->keymax) {
- ath_print(common, ATH_DBG_FATAL,
- "keychache entry %u out of range\n", entry);
+ ath_err(common, "keycache entry %u out of range\n", entry);
return false;
}
@@ -67,15 +65,15 @@ bool ath_hw_keyreset(struct ath_common *common, u16 entry)
}
EXPORT_SYMBOL(ath_hw_keyreset);
-bool ath_hw_keysetmac(struct ath_common *common, u16 entry, const u8 *mac)
+static bool ath_hw_keysetmac(struct ath_common *common,
+ u16 entry, const u8 *mac)
{
u32 macHi, macLo;
u32 unicast_flag = AR_KEYTABLE_VALID;
void *ah = common->ah;
if (entry >= common->keymax) {
- ath_print(common, ATH_DBG_FATAL,
- "keychache entry %u out of range\n", entry);
+ ath_err(common, "keycache entry %u out of range\n", entry);
return false;
}
@@ -107,17 +105,16 @@ bool ath_hw_keysetmac(struct ath_common *common, u16 entry, const u8 *mac)
return true;
}
-bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry,
- const struct ath_keyval *k,
- const u8 *mac)
+static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry,
+ const struct ath_keyval *k,
+ const u8 *mac)
{
void *ah = common->ah;
u32 key0, key1, key2, key3, key4;
u32 keyType;
if (entry >= common->keymax) {
- ath_print(common, ATH_DBG_FATAL,
- "keycache entry %u out of range\n", entry);
+ ath_err(common, "keycache entry %u out of range\n", entry);
return false;
}
@@ -127,8 +124,8 @@ bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry,
break;
case ATH_CIPHER_AES_CCM:
if (!(common->crypt_caps & ATH_CRYPT_CAP_CIPHER_AESCCM)) {
- ath_print(common, ATH_DBG_ANY,
- "AES-CCM not supported by this mac rev\n");
+ ath_dbg(common, ATH_DBG_ANY,
+ "AES-CCM not supported by this mac rev\n");
return false;
}
keyType = AR_KEYTABLE_TYPE_CCM;
@@ -136,15 +133,15 @@ bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry,
case ATH_CIPHER_TKIP:
keyType = AR_KEYTABLE_TYPE_TKIP;
if (entry + 64 >= common->keymax) {
- ath_print(common, ATH_DBG_ANY,
- "entry %u inappropriate for TKIP\n", entry);
+ ath_dbg(common, ATH_DBG_ANY,
+ "entry %u inappropriate for TKIP\n", entry);
return false;
}
break;
case ATH_CIPHER_WEP:
if (k->kv_len < WLAN_KEY_LEN_WEP40) {
- ath_print(common, ATH_DBG_ANY,
- "WEP key length %u too small\n", k->kv_len);
+ ath_dbg(common, ATH_DBG_ANY,
+ "WEP key length %u too small\n", k->kv_len);
return false;
}
if (k->kv_len <= WLAN_KEY_LEN_WEP40)
@@ -158,8 +155,7 @@ bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry,
keyType = AR_KEYTABLE_TYPE_CLR;
break;
default:
- ath_print(common, ATH_DBG_FATAL,
- "cipher %u not supported\n", k->kv_type);
+ ath_err(common, "cipher %u not supported\n", k->kv_type);
return false;
}
@@ -340,8 +336,7 @@ static int ath_setkey_tkip(struct ath_common *common, u16 keyix, const u8 *key,
memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
if (!ath_hw_set_keycache_entry(common, keyix, hk, NULL)) {
/* TX MIC entry failed. No need to proceed further */
- ath_print(common, ATH_DBG_FATAL,
- "Setting TX MIC Key Failed\n");
+ ath_err(common, "Setting TX MIC Key Failed\n");
return 0;
}
diff --git a/drivers/net/wireless/ath/main.c b/drivers/net/wireless/ath/main.c
index 487193f1de1a..c325202fdc5f 100644
--- a/drivers/net/wireless/ath/main.c
+++ b/drivers/net/wireless/ath/main.c
@@ -56,3 +56,23 @@ struct sk_buff *ath_rxbuf_alloc(struct ath_common *common,
return skb;
}
EXPORT_SYMBOL(ath_rxbuf_alloc);
+
+int ath_printk(const char *level, struct ath_common *common,
+ const char *fmt, ...)
+{
+ struct va_format vaf;
+ va_list args;
+ int rtn;
+
+ va_start(args, fmt);
+
+ vaf.fmt = fmt;
+ vaf.va = &args;
+
+ rtn = printk("%sath: %pV", level, &vaf);
+
+ va_end(args);
+
+ return rtn;
+}
+EXPORT_SYMBOL(ath_printk);
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index c8f7090b27d3..46e382ed46aa 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -1161,7 +1161,7 @@ static irqreturn_t service_interrupt(int irq, void *dev_id)
struct atmel_private *priv = netdev_priv(dev);
u8 isr;
int i = -1;
- static u8 irq_order[] = {
+ static const u8 irq_order[] = {
ISR_OUT_OF_RANGE,
ISR_RxCOMPLETE,
ISR_TxCOMPLETE,
@@ -3771,7 +3771,9 @@ static int probe_atmel_card(struct net_device *dev)
if (rc) {
if (dev->dev_addr[0] == 0xFF) {
- u8 default_mac[] = {0x00, 0x04, 0x25, 0x00, 0x00, 0x00};
+ static const u8 default_mac[] = {
+ 0x00, 0x04, 0x25, 0x00, 0x00, 0x00
+ };
printk(KERN_ALERT "%s: *** Invalid MAC address. UPGRADE Firmware ****\n", dev->name);
memcpy(dev->dev_addr, default_mac, 6);
}
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig
index 0a00d42642cd..47033f6a1c2b 100644
--- a/drivers/net/wireless/b43/Kconfig
+++ b/drivers/net/wireless/b43/Kconfig
@@ -86,15 +86,16 @@ config B43_PIO
select SSB_BLOCKIO
default y
-config B43_NPHY
- bool "Pre IEEE 802.11n support (BROKEN)"
- depends on B43 && EXPERIMENTAL && BROKEN
+config B43_PHY_N
+ bool "Support for 802.11n (N-PHY) devices (EXPERIMENTAL)"
+ depends on B43 && EXPERIMENTAL
---help---
- Support for the IEEE 802.11n draft.
+ Support for the N-PHY.
- THIS IS BROKEN AND DOES NOT WORK YET.
+ This enables support for devices with N-PHY revision up to 2.
- SAY N.
+ Say N if you expect high stability and performance. Saying Y will not
+ affect other devices support and may provide support for basic needs.
config B43_PHY_LP
bool "Support for low-power (LP-PHY) devices (EXPERIMENTAL)"
diff --git a/drivers/net/wireless/b43/Makefile b/drivers/net/wireless/b43/Makefile
index 69d4af09a6cb..cef334a8c669 100644
--- a/drivers/net/wireless/b43/Makefile
+++ b/drivers/net/wireless/b43/Makefile
@@ -1,12 +1,12 @@
b43-y += main.o
b43-y += tables.o
-b43-$(CONFIG_B43_NPHY) += tables_nphy.o
-b43-$(CONFIG_B43_NPHY) += radio_2055.o
-b43-$(CONFIG_B43_NPHY) += radio_2056.o
+b43-$(CONFIG_B43_PHY_N) += tables_nphy.o
+b43-$(CONFIG_B43_PHY_N) += radio_2055.o
+b43-$(CONFIG_B43_PHY_N) += radio_2056.o
b43-y += phy_common.o
b43-y += phy_g.o
b43-y += phy_a.o
-b43-$(CONFIG_B43_NPHY) += phy_n.o
+b43-$(CONFIG_B43_PHY_N) += phy_n.o
b43-$(CONFIG_B43_PHY_LP) += phy_lp.o
b43-$(CONFIG_B43_PHY_LP) += tables_lpphy.o
b43-y += sysfs.o
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index 72821c456b02..9aad2ca3c112 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -153,6 +153,19 @@
#define B43_BFH_FEM_BT 0x0040 /* has FEM and switch to share antenna
* with bluetooth */
+/* SPROM boardflags2_lo values */
+#define B43_BFL2_RXBB_INT_REG_DIS 0x0001 /* external RX BB regulator present */
+#define B43_BFL2_APLL_WAR 0x0002 /* alternative A-band PLL settings implemented */
+#define B43_BFL2_TXPWRCTRL_EN 0x0004 /* permits enabling TX Power Control */
+#define B43_BFL2_2X4_DIV 0x0008 /* 2x4 diversity switch */
+#define B43_BFL2_5G_PWRGAIN 0x0010 /* supports 5G band power gain */
+#define B43_BFL2_PCIEWAR_OVR 0x0020 /* overrides ASPM and Clkreq settings */
+#define B43_BFL2_CAESERS_BRD 0x0040 /* is Caesers board (unused) */
+#define B43_BFL2_BTC3WIRE 0x0080 /* used 3-wire bluetooth coexist */
+#define B43_BFL2_SKWRKFEM_BRD 0x0100 /* 4321mcm93 uses Skyworks FEM */
+#define B43_BFL2_SPUR_WAR 0x0200 /* has a workaround for clock-harmonic spurs */
+#define B43_BFL2_GPLL_WAR 0x0400 /* altenative G-band PLL settings implemented */
+
/* GPIO register offset, in both ChipCommon and PCI core. */
#define B43_GPIO_CONTROL 0x6c
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index 10d0aaf754c5..3d5566e7af0a 100644
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -415,11 +415,6 @@ static int alloc_ringmemory(struct b43_dmaring *ring)
static void free_ringmemory(struct b43_dmaring *ring)
{
- gfp_t flags = GFP_KERNEL;
-
- if (ring->type == B43_DMA_64BIT)
- flags |= GFP_DMA;
-
dma_free_coherent(ring->dev->dev->dma_dev, B43_DMA_RINGMEMSIZE,
ring->descbase, ring->dmabase);
}
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index a1186525c70d..9ae3f619e98d 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -322,59 +322,83 @@ static int b43_ratelimit(struct b43_wl *wl)
void b43info(struct b43_wl *wl, const char *fmt, ...)
{
+ struct va_format vaf;
va_list args;
if (b43_modparam_verbose < B43_VERBOSITY_INFO)
return;
if (!b43_ratelimit(wl))
return;
+
va_start(args, fmt);
- printk(KERN_INFO "b43-%s: ",
- (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan");
- vprintk(fmt, args);
+
+ vaf.fmt = fmt;
+ vaf.va = &args;
+
+ printk(KERN_INFO "b43-%s: %pV",
+ (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan", &vaf);
+
va_end(args);
}
void b43err(struct b43_wl *wl, const char *fmt, ...)
{
+ struct va_format vaf;
va_list args;
if (b43_modparam_verbose < B43_VERBOSITY_ERROR)
return;
if (!b43_ratelimit(wl))
return;
+
va_start(args, fmt);
- printk(KERN_ERR "b43-%s ERROR: ",
- (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan");
- vprintk(fmt, args);
+
+ vaf.fmt = fmt;
+ vaf.va = &args;
+
+ printk(KERN_ERR "b43-%s ERROR: %pV",
+ (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan", &vaf);
+
va_end(args);
}
void b43warn(struct b43_wl *wl, const char *fmt, ...)
{
+ struct va_format vaf;
va_list args;
if (b43_modparam_verbose < B43_VERBOSITY_WARN)
return;
if (!b43_ratelimit(wl))
return;
+
va_start(args, fmt);
- printk(KERN_WARNING "b43-%s warning: ",
- (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan");
- vprintk(fmt, args);
+
+ vaf.fmt = fmt;
+ vaf.va = &args;
+
+ printk(KERN_WARNING "b43-%s warning: %pV",
+ (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan", &vaf);
+
va_end(args);
}
void b43dbg(struct b43_wl *wl, const char *fmt, ...)
{
+ struct va_format vaf;
va_list args;
if (b43_modparam_verbose < B43_VERBOSITY_DEBUG)
return;
+
va_start(args, fmt);
- printk(KERN_DEBUG "b43-%s debug: ",
- (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan");
- vprintk(fmt, args);
+
+ vaf.fmt = fmt;
+ vaf.va = &args;
+
+ printk(KERN_DEBUG "b43-%s debug: %pV",
+ (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan", &vaf);
+
va_end(args);
}
@@ -1126,6 +1150,12 @@ void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags)
flags |= B43_TMSLOW_PHYCLKEN;
flags |= B43_TMSLOW_PHYRESET;
+ if (dev->phy.type == B43_PHYTYPE_N) {
+ if (b43_channel_type_is_40mhz(dev->phy.channel_type))
+ flags |= B43_TMSLOW_PHYCLKSPEED_160MHZ;
+ else
+ flags |= B43_TMSLOW_PHYCLKSPEED_80MHZ;
+ }
ssb_device_enable(dev->dev, flags);
msleep(2); /* Wait for the PLL to turn on. */
@@ -4022,9 +4052,9 @@ static int b43_phy_versioning(struct b43_wldev *dev)
if (phy_rev > 9)
unsupported = 1;
break;
-#ifdef CONFIG_B43_NPHY
+#ifdef CONFIG_B43_PHY_N
case B43_PHYTYPE_N:
- if (phy_rev > 4)
+ if (phy_rev > 2)
unsupported = 1;
break;
#endif
@@ -5067,7 +5097,7 @@ static void b43_print_driverinfo(void)
#ifdef CONFIG_B43_PCMCIA
feat_pcmcia = "M";
#endif
-#ifdef CONFIG_B43_NPHY
+#ifdef CONFIG_B43_PHY_N
feat_nphy = "N";
#endif
#ifdef CONFIG_B43_LEDS
diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c
index 7b2ea6781457..b5c5ce94d3fd 100644
--- a/drivers/net/wireless/b43/phy_common.c
+++ b/drivers/net/wireless/b43/phy_common.c
@@ -50,7 +50,7 @@ int b43_phy_allocate(struct b43_wldev *dev)
phy->ops = &b43_phyops_g;
break;
case B43_PHYTYPE_N:
-#ifdef CONFIG_B43_NPHY
+#ifdef CONFIG_B43_PHY_N
phy->ops = &b43_phyops_n;
#endif
break;
@@ -231,6 +231,7 @@ void b43_radio_maskset(struct b43_wldev *dev, u16 offset, u16 mask, u16 set)
u16 b43_phy_read(struct b43_wldev *dev, u16 reg)
{
assert_mac_suspended(dev);
+ dev->phy.writes_counter = 0;
return dev->phy.ops->phy_read(dev, reg);
}
@@ -238,6 +239,10 @@ void b43_phy_write(struct b43_wldev *dev, u16 reg, u16 value)
{
assert_mac_suspended(dev);
dev->phy.ops->phy_write(dev, reg, value);
+ if (++dev->phy.writes_counter == B43_MAX_WRITES_IN_ROW) {
+ b43_read16(dev, B43_MMIO_PHY_VER);
+ dev->phy.writes_counter = 0;
+ }
}
void b43_phy_copy(struct b43_wldev *dev, u16 destreg, u16 srcreg)
@@ -424,12 +429,21 @@ void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on)
b43_write16(dev, B43_MMIO_PHY0, on ? 0 : 0xF4);
}
+
+bool b43_channel_type_is_40mhz(enum nl80211_channel_type channel_type)
+{
+ return (channel_type == NL80211_CHAN_HT40MINUS ||
+ channel_type == NL80211_CHAN_HT40PLUS);
+}
+
/* http://bcm-v4.sipsolutions.net/802.11/PHY/Cordic */
struct b43_c32 b43_cordic(int theta)
{
- u32 arctg[] = { 2949120, 1740967, 919879, 466945, 234379, 117304,
- 58666, 29335, 14668, 7334, 3667, 1833, 917, 458,
- 229, 115, 57, 29, };
+ static const u32 arctg[] = {
+ 2949120, 1740967, 919879, 466945, 234379, 117304,
+ 58666, 29335, 14668, 7334, 3667, 1833,
+ 917, 458, 229, 115, 57, 29,
+ };
u8 i;
s32 tmp;
s8 signx = 1;
diff --git a/drivers/net/wireless/b43/phy_common.h b/drivers/net/wireless/b43/phy_common.h
index 0e6194228845..2401bee8b081 100644
--- a/drivers/net/wireless/b43/phy_common.h
+++ b/drivers/net/wireless/b43/phy_common.h
@@ -39,6 +39,9 @@ struct b43_c32 { s32 i, q; };
#define B43_PHYVER_TYPE_SHIFT 8
#define B43_PHYVER_VERSION 0x00FF
+/* PHY writes need to be flushed if we reach limit */
+#define B43_MAX_WRITES_IN_ROW 24
+
/**
* enum b43_interference_mitigation - Interference Mitigation mode
*
@@ -232,6 +235,9 @@ struct b43_phy {
/* PHY revision number. */
u8 rev;
+ /* Count writes since last read */
+ u8 writes_counter;
+
/* Radio versioning */
u16 radio_manuf; /* Radio manufacturer */
u16 radio_ver; /* Radio version */
@@ -430,6 +436,8 @@ int b43_phy_shm_tssi_read(struct b43_wldev *dev, u16 shm_offset);
*/
void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on);
+bool b43_channel_type_is_40mhz(enum nl80211_channel_type channel_type);
+
struct b43_c32 b43_cordic(int theta);
#endif /* LINUX_B43_PHY_COMMON_H_ */
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index e0f2d122e124..61875c888278 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -67,6 +67,18 @@ enum b43_nphy_rf_sequence {
B43_RFSEQ_UPDATE_GAINU,
};
+enum b43_nphy_rssi_type {
+ B43_NPHY_RSSI_X = 0,
+ B43_NPHY_RSSI_Y,
+ B43_NPHY_RSSI_Z,
+ B43_NPHY_RSSI_PWRDET,
+ B43_NPHY_RSSI_TSSI_I,
+ B43_NPHY_RSSI_TSSI_Q,
+ B43_NPHY_RSSI_TBD,
+};
+
+static void b43_nphy_stay_in_carrier_search(struct b43_wldev *dev,
+ bool enable);
static void b43_nphy_set_rf_sequence(struct b43_wldev *dev, u8 cmd,
u8 *events, u8 *delays, u8 length);
static void b43_nphy_force_rf_sequence(struct b43_wldev *dev,
@@ -76,13 +88,6 @@ static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field,
static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field,
u16 value, u8 core);
-static inline bool b43_channel_type_is_40mhz(
- enum nl80211_channel_type channel_type)
-{
- return (channel_type == NL80211_CHAN_HT40MINUS ||
- channel_type == NL80211_CHAN_HT40PLUS);
-}
-
void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna)
{//TODO
}
@@ -145,9 +150,154 @@ static void b43_chantab_phy_upload(struct b43_wldev *dev,
b43_phy_write(dev, B43_NPHY_BW6, e->phy_bw6);
}
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlEnable */
+static void b43_nphy_tx_power_ctrl(struct b43_wldev *dev, bool enable)
+{
+ struct b43_phy_n *nphy = dev->phy.n;
+ u8 i;
+ u16 tmp;
+
+ if (nphy->hang_avoid)
+ b43_nphy_stay_in_carrier_search(dev, 1);
+
+ nphy->txpwrctrl = enable;
+ if (!enable) {
+ if (dev->phy.rev >= 3)
+ ; /* TODO */
+
+ b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x6840);
+ for (i = 0; i < 84; i++)
+ b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0);
+
+ b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x6C40);
+ for (i = 0; i < 84; i++)
+ b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0);
+
+ tmp = B43_NPHY_TXPCTL_CMD_COEFF | B43_NPHY_TXPCTL_CMD_HWPCTLEN;
+ if (dev->phy.rev >= 3)
+ tmp |= B43_NPHY_TXPCTL_CMD_PCTLEN;
+ b43_phy_mask(dev, B43_NPHY_TXPCTL_CMD, ~tmp);
+
+ if (dev->phy.rev >= 3) {
+ b43_phy_set(dev, B43_NPHY_AFECTL_OVER1, 0x0100);
+ b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x0100);
+ } else {
+ b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x4000);
+ }
+
+ if (dev->phy.rev == 2)
+ b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3,
+ ~B43_NPHY_BPHY_CTL3_SCALE, 0x53);
+ else if (dev->phy.rev < 2)
+ b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3,
+ ~B43_NPHY_BPHY_CTL3_SCALE, 0x5A);
+
+ if (dev->phy.rev < 2 && 0)
+ ; /* TODO */
+ } else {
+ b43err(dev->wl, "enabling tx pwr ctrl not implemented yet\n");
+ }
+
+ if (nphy->hang_avoid)
+ b43_nphy_stay_in_carrier_search(dev, 0);
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrFix */
static void b43_nphy_tx_power_fix(struct b43_wldev *dev)
{
- //TODO
+ struct b43_phy_n *nphy = dev->phy.n;
+ struct ssb_sprom *sprom = &(dev->dev->bus->sprom);
+
+ u8 txpi[2], bbmult, i;
+ u16 tmp, radio_gain, dac_gain;
+ u16 freq = dev->phy.channel_freq;
+ u32 txgain;
+ /* u32 gaintbl; rev3+ */
+
+ if (nphy->hang_avoid)
+ b43_nphy_stay_in_carrier_search(dev, 1);
+
+ if (dev->phy.rev >= 3) {
+ txpi[0] = 40;
+ txpi[1] = 40;
+ } else if (sprom->revision < 4) {
+ txpi[0] = 72;
+ txpi[1] = 72;
+ } else {
+ if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
+ txpi[0] = sprom->txpid2g[0];
+ txpi[1] = sprom->txpid2g[1];
+ } else if (freq >= 4900 && freq < 5100) {
+ txpi[0] = sprom->txpid5gl[0];
+ txpi[1] = sprom->txpid5gl[1];
+ } else if (freq >= 5100 && freq < 5500) {
+ txpi[0] = sprom->txpid5g[0];
+ txpi[1] = sprom->txpid5g[1];
+ } else if (freq >= 5500) {
+ txpi[0] = sprom->txpid5gh[0];
+ txpi[1] = sprom->txpid5gh[1];
+ } else {
+ txpi[0] = 91;
+ txpi[1] = 91;
+ }
+ }
+
+ /*
+ for (i = 0; i < 2; i++) {
+ nphy->txpwrindex[i].index_internal = txpi[i];
+ nphy->txpwrindex[i].index_internal_save = txpi[i];
+ }
+ */
+
+ for (i = 0; i < 2; i++) {
+ if (dev->phy.rev >= 3) {
+ /* FIXME: support 5GHz */
+ txgain = b43_ntab_tx_gain_rev3plus_2ghz[txpi[i]];
+ radio_gain = (txgain >> 16) & 0x1FFFF;
+ } else {
+ txgain = b43_ntab_tx_gain_rev0_1_2[txpi[i]];
+ radio_gain = (txgain >> 16) & 0x1FFF;
+ }
+
+ dac_gain = (txgain >> 8) & 0x3F;
+ bbmult = txgain & 0xFF;
+
+ if (dev->phy.rev >= 3) {
+ if (i == 0)
+ b43_phy_set(dev, B43_NPHY_AFECTL_OVER1, 0x0100);
+ else
+ b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x0100);
+ } else {
+ b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x4000);
+ }
+
+ if (i == 0)
+ b43_phy_write(dev, B43_NPHY_AFECTL_DACGAIN1, dac_gain);
+ else
+ b43_phy_write(dev, B43_NPHY_AFECTL_DACGAIN2, dac_gain);
+
+ b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x1D10 + i);
+ b43_phy_write(dev, B43_NPHY_TABLE_DATALO, radio_gain);
+
+ b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x3C57);
+ tmp = b43_phy_read(dev, B43_NPHY_TABLE_DATALO);
+
+ if (i == 0)
+ tmp = (tmp & 0x00FF) | (bbmult << 8);
+ else
+ tmp = (tmp & 0xFF00) | bbmult;
+
+ b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x3C57);
+ b43_phy_write(dev, B43_NPHY_TABLE_DATALO, tmp);
+
+ if (0)
+ ; /* TODO */
+ }
+
+ b43_phy_mask(dev, B43_NPHY_BPHY_CTL2, ~B43_NPHY_BPHY_CTL2_LUT);
+
+ if (nphy->hang_avoid)
+ b43_nphy_stay_in_carrier_search(dev, 0);
}
@@ -191,7 +341,8 @@ static void b43_radio_init2055_post(struct b43_wldev *dev)
binfo->type != 0x46D ||
binfo->rev < 0x41);
else
- workaround = ((sprom->boardflags_hi & B43_BFH_NOPA) == 0);
+ workaround =
+ !(sprom->boardflags2_lo & B43_BFL2_RXBB_INT_REG_DIS);
b43_radio_mask(dev, B2055_MASTER1, 0xFFF3);
if (workaround) {
@@ -240,10 +391,13 @@ static void b43_radio_init2055_post(struct b43_wldev *dev)
static void b43_radio_init2055(struct b43_wldev *dev)
{
b43_radio_init2055_pre(dev);
- if (b43_status(dev) < B43_STAT_INITIALIZED)
- b2055_upload_inittab(dev, 0, 1);
- else
- b2055_upload_inittab(dev, 0/*FIXME on 5ghz band*/, 0);
+ if (b43_status(dev) < B43_STAT_INITIALIZED) {
+ /* Follow wl, not specs. Do not force uploading all regs */
+ b2055_upload_inittab(dev, 0, 0);
+ } else {
+ bool ghz5 = b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ;
+ b2055_upload_inittab(dev, ghz5, 0);
+ }
b43_radio_init2055_post(dev);
}
@@ -453,6 +607,8 @@ static void b43_nphy_rx_iq_coeffs(struct b43_wldev *dev, bool write,
}
}
+#if 0
+/* Ready but not used anywhere */
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCalPhyCleanup */
static void b43_nphy_rx_cal_phy_cleanup(struct b43_wldev *dev, u8 core)
{
@@ -534,6 +690,7 @@ static void b43_nphy_rx_cal_phy_setup(struct b43_wldev *dev, u8 core)
b43_nphy_rf_control_intc_override(dev, 1, rxval, (core + 1));
b43_nphy_rf_control_intc_override(dev, 1, txval, (2 - core));
}
+#endif
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalcRxIqComp */
static void b43_nphy_calc_rx_iq_comp(struct b43_wldev *dev, u8 mask)
@@ -569,7 +726,6 @@ static void b43_nphy_calc_rx_iq_comp(struct b43_wldev *dev, u8 mask)
ii = est.i1_pwr;
qq = est.q1_pwr;
} else {
- B43_WARN_ON(1);
continue;
}
@@ -651,7 +807,8 @@ static void b43_nphy_tx_iq_workaround(struct b43_wldev *dev)
}
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/clip-detection */
-static void b43_nphy_write_clip_detection(struct b43_wldev *dev, u16 *clip_st)
+static void b43_nphy_write_clip_detection(struct b43_wldev *dev,
+ const u16 *clip_st)
{
b43_phy_write(dev, B43_NPHY_C1_CLIP1THRES, clip_st[0]);
b43_phy_write(dev, B43_NPHY_C2_CLIP1THRES, clip_st[1]);
@@ -727,7 +884,7 @@ static void b43_nphy_stay_in_carrier_search(struct b43_wldev *dev, bool enable)
struct b43_phy_n *nphy = phy->n;
if (enable) {
- u16 clip[] = { 0xFFFF, 0xFFFF };
+ static const u16 clip[] = { 0xFFFF, 0xFFFF };
if (nphy->deaf_count++ == 0) {
nphy->classifier_state = b43_nphy_classifier(dev, 0, 0);
b43_nphy_classifier(dev, 0x7, 0);
@@ -839,7 +996,7 @@ static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev)
u16 data[4];
s16 gain[2];
u16 minmax[2];
- u16 lna_gain[4] = { -2, 10, 19, 25 };
+ static const u16 lna_gain[4] = { -2, 10, 19, 25 };
if (nphy->hang_avoid)
b43_nphy_stay_in_carrier_search(dev, 1);
@@ -871,7 +1028,7 @@ static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev)
data[2] = lna_gain[2] + gain[i];
data[3] = lna_gain[3] + gain[i];
}
- b43_ntab_write_bulk(dev, B43_NTAB16(10, 8), 4, data);
+ b43_ntab_write_bulk(dev, B43_NTAB16(i, 8), 4, data);
minmax[i] = 23 + gain[i];
}
@@ -891,6 +1048,7 @@ static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev)
struct b43_phy_n *nphy = dev->phy.n;
u8 i, j;
u8 code;
+ u16 tmp;
/* TODO: for PHY >= 3
s8 *lna1_gain, *lna2_gain;
@@ -913,15 +1071,15 @@ static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev)
B43_NPHY_C2_CGAINI_CL2DETECT);
/* Set narrowband clip threshold */
- b43_phy_set(dev, B43_NPHY_C1_NBCLIPTHRES, 0x84);
- b43_phy_set(dev, B43_NPHY_C2_NBCLIPTHRES, 0x84);
+ b43_phy_write(dev, B43_NPHY_C1_NBCLIPTHRES, 0x84);
+ b43_phy_write(dev, B43_NPHY_C2_NBCLIPTHRES, 0x84);
if (!dev->phy.is_40mhz) {
/* Set dwell lengths */
- b43_phy_set(dev, B43_NPHY_CLIP1_NBDWELL_LEN, 0x002B);
- b43_phy_set(dev, B43_NPHY_CLIP2_NBDWELL_LEN, 0x002B);
- b43_phy_set(dev, B43_NPHY_W1CLIP1_DWELL_LEN, 0x0009);
- b43_phy_set(dev, B43_NPHY_W1CLIP2_DWELL_LEN, 0x0009);
+ b43_phy_write(dev, B43_NPHY_CLIP1_NBDWELL_LEN, 0x002B);
+ b43_phy_write(dev, B43_NPHY_CLIP2_NBDWELL_LEN, 0x002B);
+ b43_phy_write(dev, B43_NPHY_W1CLIP1_DWELL_LEN, 0x0009);
+ b43_phy_write(dev, B43_NPHY_W1CLIP2_DWELL_LEN, 0x0009);
}
/* Set wideband clip 2 threshold */
@@ -943,7 +1101,7 @@ static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev)
~B43_NPHY_C2_CCK_CGAINI_GAINBKOFF, 0x1);
}
- b43_phy_set(dev, B43_NPHY_CCK_SHIFTB_REF, 0x809C);
+ b43_phy_write(dev, B43_NPHY_CCK_SHIFTB_REF, 0x809C);
if (nphy->gain_boost) {
if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ &&
@@ -964,10 +1122,10 @@ static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev)
code << B43_NPHY_C2_INITGAIN_HPVGA2_SHIFT);
b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x1D06);
- b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
- (code << 8 | 0x7C));
- b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
- (code << 8 | 0x7C));
+ /* specs say about 2 loops, but wl does 4 */
+ for (i = 0; i < 4; i++)
+ b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
+ (code << 8 | 0x7C));
b43_nphy_adjust_lna_gain_table(dev);
@@ -985,19 +1143,21 @@ static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev)
b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1);
b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x1D06);
- b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
- (code << 8 | 0x74));
- b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
- (code << 8 | 0x74));
+ /* specs say about 2 loops, but wl does 4 */
+ for (i = 0; i < 4; i++)
+ b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
+ (code << 8 | 0x74));
}
if (dev->phy.rev == 2) {
for (i = 0; i < 4; i++) {
b43_phy_write(dev, B43_NPHY_TABLE_ADDR,
(0x0400 * i) + 0x0020);
- for (j = 0; j < 21; j++)
+ for (j = 0; j < 21; j++) {
+ tmp = j * (i < 2 ? 3 : 1);
b43_phy_write(dev,
- B43_NPHY_TABLE_DATALO, 3 * j);
+ B43_NPHY_TABLE_DATALO, tmp);
+ }
}
b43_nphy_set_rf_sequence(dev, 5,
@@ -1026,7 +1186,7 @@ static void b43_nphy_workarounds(struct b43_wldev *dev)
u8 events2[7] = { 0x0, 0x3, 0x5, 0x4, 0x2, 0x1, 0x8 };
u8 delays2[7] = { 0x8, 0x6, 0x2, 0x4, 0x4, 0x6, 0x1 };
- if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
+ if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
b43_nphy_classifier(dev, 1, 0);
else
b43_nphy_classifier(dev, 1, 1);
@@ -1565,19 +1725,20 @@ static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field,
}
}
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/BPHYInit */
static void b43_nphy_bphy_init(struct b43_wldev *dev)
{
unsigned int i;
u16 val;
val = 0x1E1F;
- for (i = 0; i < 14; i++) {
+ for (i = 0; i < 16; i++) {
b43_phy_write(dev, B43_PHY_N_BMODE(0x88 + i), val);
val -= 0x202;
}
val = 0x3E3F;
for (i = 0; i < 16; i++) {
- b43_phy_write(dev, B43_PHY_N_BMODE(0x97 + i), val);
+ b43_phy_write(dev, B43_PHY_N_BMODE(0x98 + i), val);
val -= 0x202;
}
b43_phy_write(dev, B43_PHY_N_BMODE(0x38), 0x668);
@@ -1585,7 +1746,8 @@ static void b43_nphy_bphy_init(struct b43_wldev *dev)
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ScaleOffsetRssi */
static void b43_nphy_scale_offset_rssi(struct b43_wldev *dev, u16 scale,
- s8 offset, u8 core, u8 rail, u8 type)
+ s8 offset, u8 core, u8 rail,
+ enum b43_nphy_rssi_type type)
{
u16 tmp;
bool core1or5 = (core == 1) || (core == 5);
@@ -1594,53 +1756,59 @@ static void b43_nphy_scale_offset_rssi(struct b43_wldev *dev, u16 scale,
offset = clamp_val(offset, -32, 31);
tmp = ((scale & 0x3F) << 8) | (offset & 0x3F);
- if (core1or5 && (rail == 0) && (type == 2))
+ if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_Z))
b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Z, tmp);
- if (core1or5 && (rail == 1) && (type == 2))
+ if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_Z))
b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Z, tmp);
- if (core2or5 && (rail == 0) && (type == 2))
+ if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_Z))
b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_Z, tmp);
- if (core2or5 && (rail == 1) && (type == 2))
+ if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_Z))
b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Z, tmp);
- if (core1or5 && (rail == 0) && (type == 0))
+
+ if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_X))
b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_X, tmp);
- if (core1or5 && (rail == 1) && (type == 0))
+ if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_X))
b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_X, tmp);
- if (core2or5 && (rail == 0) && (type == 0))
+ if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_X))
b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_X, tmp);
- if (core2or5 && (rail == 1) && (type == 0))
+ if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_X))
b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_X, tmp);
- if (core1or5 && (rail == 0) && (type == 1))
+
+ if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_Y))
b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Y, tmp);
- if (core1or5 && (rail == 1) && (type == 1))
+ if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_Y))
b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Y, tmp);
- if (core2or5 && (rail == 0) && (type == 1))
+ if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_Y))
b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_Y, tmp);
- if (core2or5 && (rail == 1) && (type == 1))
+ if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_Y))
b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Y, tmp);
- if (core1or5 && (rail == 0) && (type == 6))
+
+ if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_TBD))
b43_phy_write(dev, B43_NPHY_RSSIMC_0I_TBD, tmp);
- if (core1or5 && (rail == 1) && (type == 6))
+ if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_TBD))
b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_TBD, tmp);
- if (core2or5 && (rail == 0) && (type == 6))
+ if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_TBD))
b43_phy_write(dev, B43_NPHY_RSSIMC_1I_TBD, tmp);
- if (core2or5 && (rail == 1) && (type == 6))
+ if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_TBD))
b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_TBD, tmp);
- if (core1or5 && (rail == 0) && (type == 3))
+
+ if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_PWRDET))
b43_phy_write(dev, B43_NPHY_RSSIMC_0I_PWRDET, tmp);
- if (core1or5 && (rail == 1) && (type == 3))
+ if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_PWRDET))
b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_PWRDET, tmp);
- if (core2or5 && (rail == 0) && (type == 3))
+ if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_PWRDET))
b43_phy_write(dev, B43_NPHY_RSSIMC_1I_PWRDET, tmp);
- if (core2or5 && (rail == 1) && (type == 3))
+ if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_PWRDET))
b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_PWRDET, tmp);
- if (core1or5 && (type == 4))
+
+ if (core1or5 && (type == B43_NPHY_RSSI_TSSI_I))
b43_phy_write(dev, B43_NPHY_RSSIMC_0I_TSSI, tmp);
- if (core2or5 && (type == 4))
+ if (core2or5 && (type == B43_NPHY_RSSI_TSSI_I))
b43_phy_write(dev, B43_NPHY_RSSIMC_1I_TSSI, tmp);
- if (core1or5 && (type == 5))
+
+ if (core1or5 && (type == B43_NPHY_RSSI_TSSI_Q))
b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_TSSI, tmp);
- if (core2or5 && (type == 5))
+ if (core2or5 && (type == B43_NPHY_RSSI_TSSI_Q))
b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_TSSI, tmp);
}
@@ -1668,27 +1836,39 @@ static void b43_nphy_rev2_rssi_select(struct b43_wldev *dev, u8 code, u8 type)
(type + 1) << 4);
}
- /* TODO use some definitions */
if (code == 0) {
- b43_phy_maskset(dev, B43_NPHY_AFECTL_OVER, 0xCFFF, 0);
+ b43_phy_mask(dev, B43_NPHY_AFECTL_OVER, ~0x3000);
if (type < 3) {
- b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, 0xFEC7, 0);
- b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, 0xEFDC, 0);
- b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, 0xFFFE, 0);
+ b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
+ ~(B43_NPHY_RFCTL_CMD_RXEN |
+ B43_NPHY_RFCTL_CMD_CORESEL));
+ b43_phy_mask(dev, B43_NPHY_RFCTL_OVER,
+ ~(0x1 << 12 |
+ 0x1 << 5 |
+ 0x1 << 1 |
+ 0x1));
+ b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
+ ~B43_NPHY_RFCTL_CMD_START);
udelay(20);
- b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, 0xFFFE, 0);
+ b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, ~0x1);
}
} else {
- b43_phy_maskset(dev, B43_NPHY_AFECTL_OVER, 0xCFFF,
- 0x3000);
+ b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x3000);
if (type < 3) {
b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD,
- 0xFEC7, 0x0180);
- b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER,
- 0xEFDC, (code << 1 | 0x1021));
- b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, 0xFFFE, 0x1);
+ ~(B43_NPHY_RFCTL_CMD_RXEN |
+ B43_NPHY_RFCTL_CMD_CORESEL),
+ (B43_NPHY_RFCTL_CMD_RXEN |
+ code << B43_NPHY_RFCTL_CMD_CORESEL_SHIFT));
+ b43_phy_set(dev, B43_NPHY_RFCTL_OVER,
+ (0x1 << 12 |
+ 0x1 << 5 |
+ 0x1 << 1 |
+ 0x1));
+ b43_phy_set(dev, B43_NPHY_RFCTL_CMD,
+ B43_NPHY_RFCTL_CMD_START);
udelay(20);
- b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, 0xFFFE, 0);
+ b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, ~0x1);
}
}
}
@@ -1837,6 +2017,14 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf,
save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B1S0);
save_regs_phy[7] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B32S1);
+ } else if (dev->phy.rev == 2) {
+ save_regs_phy[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1);
+ save_regs_phy[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2);
+ save_regs_phy[2] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
+ save_regs_phy[3] = b43_phy_read(dev, B43_NPHY_RFCTL_CMD);
+ save_regs_phy[4] = b43_phy_read(dev, B43_NPHY_RFCTL_OVER);
+ save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO1);
+ save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO2);
}
b43_nphy_rssi_select(dev, 5, type);
@@ -1880,6 +2068,14 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf,
b43_phy_write(dev, B43_NPHY_AFECTL_OVER, save_regs_phy[5]);
b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S0, save_regs_phy[6]);
b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S1, save_regs_phy[7]);
+ } else if (dev->phy.rev == 2) {
+ b43_phy_write(dev, B43_NPHY_AFECTL_C1, save_regs_phy[0]);
+ b43_phy_write(dev, B43_NPHY_AFECTL_C2, save_regs_phy[1]);
+ b43_phy_write(dev, B43_NPHY_AFECTL_OVER, save_regs_phy[2]);
+ b43_phy_write(dev, B43_NPHY_RFCTL_CMD, save_regs_phy[3]);
+ b43_phy_write(dev, B43_NPHY_RFCTL_OVER, save_regs_phy[4]);
+ b43_phy_write(dev, B43_NPHY_RFCTL_RSSIO1, save_regs_phy[5]);
+ b43_phy_write(dev, B43_NPHY_RFCTL_RSSIO2, save_regs_phy[6]);
}
return out;
@@ -1894,7 +2090,10 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type)
u16 class, override;
u8 regs_save_radio[2];
u16 regs_save_phy[2];
+
s8 offset[4];
+ u8 core;
+ u8 rail;
u16 clip_state[2];
u16 clip_off[2] = { 0xFFFF, 0xFFFF };
@@ -1995,16 +2194,15 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type)
if (results_min[i] == 248)
offset[i] = code - 32;
- if (i % 2 == 0)
- b43_nphy_scale_offset_rssi(dev, 0, offset[i], 1, 0,
- type);
- else
- b43_nphy_scale_offset_rssi(dev, 0, offset[i], 2, 1,
- type);
+ core = (i / 2) ? 2 : 1;
+ rail = (i % 2) ? 1 : 0;
+
+ b43_nphy_scale_offset_rssi(dev, 0, offset[i], core, rail,
+ type);
}
b43_radio_maskset(dev, B2055_C1_PD_RSSIMISC, 0xF8, state[0]);
- b43_radio_maskset(dev, B2055_C1_PD_RSSIMISC, 0xF8, state[1]);
+ b43_radio_maskset(dev, B2055_C2_PD_RSSIMISC, 0xF8, state[1]);
switch (state[2]) {
case 1:
@@ -2042,6 +2240,9 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type)
b43_nphy_classifier(dev, 7, class);
b43_nphy_write_clip_detection(dev, clip_state);
+ /* Specs don't say about reset here, but it makes wl and b43 dumps
+ identical, it really seems wl performs this */
+ b43_nphy_reset_cca(dev);
}
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICalRev3 */
@@ -2059,9 +2260,9 @@ static void b43_nphy_rssi_cal(struct b43_wldev *dev)
if (dev->phy.rev >= 3) {
b43_nphy_rev3_rssi_cal(dev);
} else {
- b43_nphy_rev2_rssi_cal(dev, 2);
- b43_nphy_rev2_rssi_cal(dev, 0);
- b43_nphy_rev2_rssi_cal(dev, 1);
+ b43_nphy_rev2_rssi_cal(dev, B43_NPHY_RSSI_Z);
+ b43_nphy_rev2_rssi_cal(dev, B43_NPHY_RSSI_X);
+ b43_nphy_rev2_rssi_cal(dev, B43_NPHY_RSSI_Y);
}
}
@@ -2295,7 +2496,7 @@ static void b43_nphy_int_pa_set_tx_dig_filters(struct b43_wldev *dev)
{
int i, j;
/* B43_NPHY_TXF_20CO_S0A1, B43_NPHY_TXF_40CO_S0A1, unknown */
- u16 offset[] = { 0x186, 0x195, 0x2C5 };
+ static const u16 offset[] = { 0x186, 0x195, 0x2C5 };
for (i = 0; i < 3; i++)
for (j = 0; j < 15; j++)
@@ -2327,7 +2528,7 @@ static struct nphy_txgains b43_nphy_get_tx_gains(struct b43_wldev *dev)
struct nphy_txgains target;
const u32 *table = NULL;
- if (nphy->txpwrctrl == 0) {
+ if (!nphy->txpwrctrl) {
int i;
if (nphy->hang_avoid)
@@ -2884,7 +3085,7 @@ static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev,
u8 rfctl[2];
u8 afectl_core;
u16 tmp[6];
- u16 cur_hpf1, cur_hpf2, cur_lna;
+ u16 uninitialized_var(cur_hpf1), uninitialized_var(cur_hpf2), cur_lna;
u32 real, imag;
enum ieee80211_band band;
@@ -3088,7 +3289,7 @@ static void b43_nphy_set_rx_core_state(struct b43_wldev *dev, u8 mask)
{
struct b43_phy *phy = &dev->phy;
struct b43_phy_n *nphy = phy->n;
- u16 buf[16];
+ /* u16 buf[16]; it's rev3+ */
nphy->phyrxchain = mask;
@@ -3232,10 +3433,12 @@ int b43_phy_initn(struct b43_wldev *dev)
b43_nphy_classifier(dev, 0, 0);
b43_nphy_read_clip_detection(dev, clip);
+ if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
+ b43_nphy_bphy_init(dev);
+
tx_pwr_state = nphy->txpwrctrl;
- /* TODO N PHY TX power control with argument 0
- (turning off power control) */
- /* TODO Fix the TX Power Settings */
+ b43_nphy_tx_power_ctrl(dev, false);
+ b43_nphy_tx_power_fix(dev);
/* TODO N PHY TX Power Control Idle TSSI */
/* TODO N PHY TX Power Control Setup */
@@ -3292,21 +3495,18 @@ int b43_phy_initn(struct b43_wldev *dev)
/* TODO N PHY Pre Calibrate TX Gain */
target = b43_nphy_get_tx_gains(dev);
}
- }
+ if (!b43_nphy_cal_tx_iq_lo(dev, target, true, false))
+ if (b43_nphy_cal_rx_iq(dev, target, 2, 0) == 0)
+ b43_nphy_save_cal(dev);
+ } else if (nphy->mphase_cal_phase_id == 0)
+ ;/* N PHY Periodic Calibration with arg 3 */
+ } else {
+ b43_nphy_restore_cal(dev);
}
}
- if (!b43_nphy_cal_tx_iq_lo(dev, target, true, false)) {
- if (b43_nphy_cal_rx_iq(dev, target, 2, 0) == 0)
- b43_nphy_save_cal(dev);
- else if (nphy->mphase_cal_phase_id == 0)
- ;/* N PHY Periodic Calibration with argument 3 */
- } else {
- b43_nphy_restore_cal(dev);
- }
-
b43_nphy_tx_pwr_ctrl_coef_setup(dev);
- /* TODO N PHY TX Power Control Enable with argument tx_pwr_state */
+ b43_nphy_tx_power_ctrl(dev, tx_pwr_state);
b43_phy_write(dev, B43_NPHY_TXMACIF_HOLDOFF, 0x0015);
b43_phy_write(dev, B43_NPHY_TXMACDELAY, 0x0320);
if (phy->rev >= 3 && phy->rev <= 6)
@@ -3315,7 +3515,6 @@ int b43_phy_initn(struct b43_wldev *dev)
if (phy->rev >= 3)
b43_nphy_spur_workaround(dev);
- b43err(dev->wl, "IEEE 802.11n devices are not supported, yet.\n");
return 0;
}
@@ -3357,7 +3556,7 @@ static void b43_nphy_channel_setup(struct b43_wldev *dev,
b43_phy_mask(dev, B43_PHY_B_TEST, ~0x840);
}
- if (nphy->txpwrctrl)
+ if (!nphy->txpwrctrl)
b43_nphy_tx_power_fix(dev);
if (dev->phy.rev < 3)
@@ -3381,7 +3580,6 @@ static int b43_nphy_set_channel(struct b43_wldev *dev,
enum nl80211_channel_type channel_type)
{
struct b43_phy *phy = &dev->phy;
- struct b43_phy_n *nphy = dev->phy.n;
const struct b43_nphy_channeltab_entry_rev2 *tabent_r2;
const struct b43_nphy_channeltab_entry_rev3 *tabent_r3;
@@ -3451,7 +3649,10 @@ static void b43_nphy_op_prepare_structs(struct b43_wldev *dev)
memset(nphy, 0, sizeof(*nphy));
- //TODO init struct b43_phy_n
+ nphy->gain_boost = true; /* this way we follow wl, assume it is true */
+ nphy->txrx_chain = 2; /* sth different than 0 and 1 for now */
+ nphy->phyrxchain = 3; /* to avoid b43_nphy_set_rx_core_state like wl */
+ nphy->perical = 2; /* avoid additional rssi cal on init (like wl) */
}
static void b43_nphy_op_free(struct b43_wldev *dev)
@@ -3500,6 +3701,15 @@ static void b43_nphy_op_write(struct b43_wldev *dev, u16 reg, u16 value)
b43_write16(dev, B43_MMIO_PHY_DATA, value);
}
+static void b43_nphy_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
+ u16 set)
+{
+ check_phyreg(dev, reg);
+ b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+ b43_write16(dev, B43_MMIO_PHY_DATA,
+ (b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set);
+}
+
static u16 b43_nphy_op_radio_read(struct b43_wldev *dev, u16 reg)
{
/* Register 1 is a 32-bit register. */
@@ -3524,8 +3734,6 @@ static void b43_nphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
static void b43_nphy_op_software_rfkill(struct b43_wldev *dev,
bool blocked)
{
- struct b43_phy_n *nphy = dev->phy.n;
-
if (b43_read32(dev, B43_MMIO_MACCTL) & B43_MACCTL_ENABLED)
b43err(dev->wl, "MAC not suspended\n");
@@ -3596,6 +3804,7 @@ const struct b43_phy_operations b43_phyops_n = {
.init = b43_nphy_op_init,
.phy_read = b43_nphy_op_read,
.phy_write = b43_nphy_op_write,
+ .phy_maskset = b43_nphy_op_maskset,
.radio_read = b43_nphy_op_radio_read,
.radio_write = b43_nphy_op_radio_write,
.software_rfkill = b43_nphy_op_software_rfkill,
diff --git a/drivers/net/wireless/b43/phy_n.h b/drivers/net/wireless/b43/phy_n.h
index c144e59a708b..001e841f118c 100644
--- a/drivers/net/wireless/b43/phy_n.h
+++ b/drivers/net/wireless/b43/phy_n.h
@@ -782,7 +782,7 @@ struct b43_phy_n {
u16 mphase_txcal_numcmds;
u16 mphase_txcal_bestcoeffs[11];
- u8 txpwrctrl;
+ bool txpwrctrl;
u16 txcal_bbmult;
u16 txiqlocal_bestc[11];
bool txiqlocal_coeffsvalid;
diff --git a/drivers/net/wireless/b43/radio_2055.c b/drivers/net/wireless/b43/radio_2055.c
index 1b5316586cbf..44c6dea66882 100644
--- a/drivers/net/wireless/b43/radio_2055.c
+++ b/drivers/net/wireless/b43/radio_2055.c
@@ -244,7 +244,7 @@ static const struct b2055_inittab_entry b2055_inittab [] = {
[0xCB] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[0xCC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2055_C1_LNA_GAINBST] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [0xCE] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [0xCE] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
[0xCF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[0xD0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[0xD1] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
@@ -256,7 +256,7 @@ static const struct b2055_inittab_entry b2055_inittab [] = {
[0xD7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[0xD8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2055_C2_LNA_GAINBST] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
- [0xDA] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+ [0xDA] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
[0xDB] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[0xDC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[0xDD] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
@@ -304,178 +304,178 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
{ .channel = 184,
.freq = 4920, /* MHz */
.unk2 = 3280,
- RADIOREGS(0x71, 0x01, 0xEC, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0xEC, 0x01, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F,
0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
- PHYREGS(0xB407, 0xB007, 0xAC07, 0x1402, 0x1502, 0x1602),
+ PHYREGS(0x07B4, 0x07B0, 0x07AC, 0x0214, 0x0215, 0x0216),
},
{ .channel = 186,
.freq = 4930, /* MHz */
.unk2 = 3287,
- RADIOREGS(0x71, 0x01, 0xED, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0xED, 0x01, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F,
0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
- PHYREGS(0xB807, 0xB407, 0xB007, 0x1302, 0x1402, 0x1502),
+ PHYREGS(0x07B8, 0x07B4, 0x07B0, 0x0213, 0x0214, 0x0215),
},
{ .channel = 188,
.freq = 4940, /* MHz */
.unk2 = 3293,
- RADIOREGS(0x71, 0x01, 0xEE, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0xEE, 0x01, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
- PHYREGS(0xBC07, 0xB807, 0xB407, 0x1202, 0x1302, 0x1402),
+ PHYREGS(0x07BC, 0x07B8, 0x07B4, 0x0212, 0x0213, 0x0214),
},
{ .channel = 190,
.freq = 4950, /* MHz */
.unk2 = 3300,
- RADIOREGS(0x71, 0x01, 0xEF, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0xEF, 0x01, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
- PHYREGS(0xC007, 0xBC07, 0xB807, 0x1102, 0x1202, 0x1302),
+ PHYREGS(0x07C0, 0x07BC, 0x07B8, 0x0211, 0x0212, 0x0213),
},
{ .channel = 192,
.freq = 4960, /* MHz */
.unk2 = 3307,
- RADIOREGS(0x71, 0x01, 0xF0, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0xF0, 0x01, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
- PHYREGS(0xC407, 0xC007, 0xBC07, 0x0F02, 0x1102, 0x1202),
+ PHYREGS(0x07C4, 0x07C0, 0x07BC, 0x020F, 0x0211, 0x0212),
},
{ .channel = 194,
.freq = 4970, /* MHz */
.unk2 = 3313,
- RADIOREGS(0x71, 0x01, 0xF1, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0xF1, 0x01, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
- PHYREGS(0xC807, 0xC407, 0xC007, 0x0E02, 0x0F02, 0x1102),
+ PHYREGS(0x07C8, 0x07C4, 0x07C0, 0x020E, 0x020F, 0x0211),
},
{ .channel = 196,
.freq = 4980, /* MHz */
.unk2 = 3320,
- RADIOREGS(0x71, 0x01, 0xF2, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0xF2, 0x01, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
- PHYREGS(0xCC07, 0xC807, 0xC407, 0x0D02, 0x0E02, 0x0F02),
+ PHYREGS(0x07CC, 0x07C8, 0x07C4, 0x020D, 0x020E, 0x020F),
},
{ .channel = 198,
.freq = 4990, /* MHz */
.unk2 = 3327,
- RADIOREGS(0x71, 0x01, 0xF3, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0xF3, 0x01, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
- PHYREGS(0xD007, 0xCC07, 0xC807, 0x0C02, 0x0D02, 0x0E02),
+ PHYREGS(0x07D0, 0x07CC, 0x07C8, 0x020C, 0x020D, 0x020E),
},
{ .channel = 200,
.freq = 5000, /* MHz */
.unk2 = 3333,
- RADIOREGS(0x71, 0x01, 0xF4, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0xF4, 0x01, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
- PHYREGS(0xD407, 0xD007, 0xCC07, 0x0B02, 0x0C02, 0x0D02),
+ PHYREGS(0x07D4, 0x07D0, 0x07CC, 0x020B, 0x020C, 0x020D),
},
{ .channel = 202,
.freq = 5010, /* MHz */
.unk2 = 3340,
- RADIOREGS(0x71, 0x01, 0xF5, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0xF5, 0x01, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
- PHYREGS(0xD807, 0xD407, 0xD007, 0x0A02, 0x0B02, 0x0C02),
+ PHYREGS(0x07D8, 0x07D4, 0x07D0, 0x020A, 0x020B, 0x020C),
},
{ .channel = 204,
.freq = 5020, /* MHz */
.unk2 = 3347,
- RADIOREGS(0x71, 0x01, 0xF6, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0xF6, 0x01, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
- PHYREGS(0xDC07, 0xD807, 0xD407, 0x0902, 0x0A02, 0x0B02),
+ PHYREGS(0x07DC, 0x07D8, 0x07D4, 0x0209, 0x020A, 0x020B),
},
{ .channel = 206,
.freq = 5030, /* MHz */
.unk2 = 3353,
- RADIOREGS(0x71, 0x01, 0xF7, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0xF7, 0x01, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
- PHYREGS(0xE007, 0xDC07, 0xD807, 0x0802, 0x0902, 0x0A02),
+ PHYREGS(0x07E0, 0x07DC, 0x07D8, 0x0208, 0x0209, 0x020A),
},
{ .channel = 208,
.freq = 5040, /* MHz */
.unk2 = 3360,
- RADIOREGS(0x71, 0x01, 0xF8, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0xF8, 0x01, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
- PHYREGS(0xE407, 0xE007, 0xDC07, 0x0702, 0x0802, 0x0902),
+ PHYREGS(0x07E4, 0x07E0, 0x07DC, 0x0207, 0x0208, 0x0209),
},
{ .channel = 210,
.freq = 5050, /* MHz */
.unk2 = 3367,
- RADIOREGS(0x71, 0x01, 0xF9, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0xF9, 0x01, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
- PHYREGS(0xE807, 0xE407, 0xE007, 0x0602, 0x0702, 0x0802),
+ PHYREGS(0x07E8, 0x07E4, 0x07E0, 0x0206, 0x0207, 0x0208),
},
{ .channel = 212,
.freq = 5060, /* MHz */
.unk2 = 3373,
- RADIOREGS(0x71, 0x01, 0xFA, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0xFA, 0x01, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F,
0x8E, 0xFF, 0x00, 0x0E, 0x0F, 0x8E),
- PHYREGS(0xEC07, 0xE807, 0xE407, 0x0502, 0x0602, 0x0702),
+ PHYREGS(0x07EC, 0x07E8, 0x07E4, 0x0205, 0x0206, 0x0207),
},
{ .channel = 214,
.freq = 5070, /* MHz */
.unk2 = 3380,
- RADIOREGS(0x71, 0x01, 0xFB, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0xFB, 0x01, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F,
0x8E, 0xFF, 0x00, 0x0E, 0x0F, 0x8E),
- PHYREGS(0xF007, 0xEC07, 0xE807, 0x0402, 0x0502, 0x0602),
+ PHYREGS(0x07F0, 0x07EC, 0x07E8, 0x0204, 0x0205, 0x0206),
},
{ .channel = 216,
.freq = 5080, /* MHz */
.unk2 = 3387,
- RADIOREGS(0x71, 0x01, 0xFC, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0xFC, 0x01, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F,
0x8D, 0xEE, 0x00, 0x0E, 0x0F, 0x8D),
- PHYREGS(0xF407, 0xF007, 0xEC07, 0x0302, 0x0402, 0x0502),
+ PHYREGS(0x07F4, 0x07F0, 0x07EC, 0x0203, 0x0204, 0x0205),
},
{ .channel = 218,
.freq = 5090, /* MHz */
.unk2 = 3393,
- RADIOREGS(0x71, 0x01, 0xFD, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0xFD, 0x01, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F,
0x8D, 0xEE, 0x00, 0x0E, 0x0F, 0x8D),
- PHYREGS(0xF807, 0xF407, 0xF007, 0x0202, 0x0302, 0x0402),
+ PHYREGS(0x07F8, 0x07F4, 0x07F0, 0x0202, 0x0203, 0x0204),
},
{ .channel = 220,
.freq = 5100, /* MHz */
.unk2 = 3400,
- RADIOREGS(0x71, 0x01, 0xFE, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0xFE, 0x01, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F,
0x8D, 0xEE, 0x00, 0x0D, 0x0F, 0x8D),
- PHYREGS(0xFC07, 0xF807, 0xF407, 0x0102, 0x0202, 0x0302),
+ PHYREGS(0x07FC, 0x07F8, 0x07F4, 0x0201, 0x0202, 0x0203),
},
{ .channel = 222,
.freq = 5110, /* MHz */
.unk2 = 3407,
- RADIOREGS(0x71, 0x01, 0xFF, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0xFF, 0x01, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F,
0x8D, 0xEE, 0x00, 0x0D, 0x0F, 0x8D),
- PHYREGS(0x0008, 0xFC07, 0xF807, 0x0002, 0x0102, 0x0202),
+ PHYREGS(0x0800, 0x07FC, 0x07F8, 0x0200, 0x0201, 0x0202),
},
{ .channel = 224,
.freq = 5120, /* MHz */
.unk2 = 3413,
- RADIOREGS(0x71, 0x02, 0x00, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x00, 0x02, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F,
0x8C, 0xDD, 0x00, 0x0D, 0x0F, 0x8C),
- PHYREGS(0x0408, 0x0008, 0xFC07, 0xFF01, 0x0002, 0x0102),
+ PHYREGS(0x0804, 0x0800, 0x07FC, 0x01FF, 0x0200, 0x0201),
},
{ .channel = 226,
.freq = 5130, /* MHz */
.unk2 = 3420,
- RADIOREGS(0x71, 0x02, 0x01, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x01, 0x02, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F,
0x8C, 0xDD, 0x00, 0x0D, 0x0F, 0x8C),
- PHYREGS(0x0808, 0x0408, 0x0008, 0xFE01, 0xFF01, 0x0002),
+ PHYREGS(0x0808, 0x0804, 0x0800, 0x01FE, 0x01FF, 0x0200),
},
{ .channel = 228,
.freq = 5140, /* MHz */
@@ -483,815 +483,815 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
RADIOREGS(0x71, 0x02, 0x02, 0x0C, 0xC6, 0x01, 0x04, 0x0A,
0x00, 0x8D, 0x99, 0x99, 0xDD, 0x00, 0x0C, 0x0E,
0x8B, 0xDD, 0x00, 0x0C, 0x0E, 0x8B),
- PHYREGS(0x0C08, 0x0808, 0x0408, 0xFD01, 0xFE01, 0xFF01),
+ PHYREGS(0x080C, 0x0808, 0x0804, 0x01FD, 0x01FE, 0x01FF),
},
{ .channel = 32,
.freq = 5160, /* MHz */
.unk2 = 3440,
- RADIOREGS(0x71, 0x02, 0x04, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x04, 0x02, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D,
0x8A, 0xCC, 0x00, 0x0B, 0x0D, 0x8A),
- PHYREGS(0x1408, 0x1008, 0x0C08, 0xFB01, 0xFC01, 0xFD01),
+ PHYREGS(0x0814, 0x0810, 0x080C, 0x01FB, 0x01FC, 0x01FD),
},
{ .channel = 34,
.freq = 5170, /* MHz */
.unk2 = 3447,
- RADIOREGS(0x71, 0x02, 0x05, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x05, 0x02, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D,
0x8A, 0xCC, 0x00, 0x0B, 0x0D, 0x8A),
- PHYREGS(0x1808, 0x1408, 0x1008, 0xFA01, 0xFB01, 0xFC01),
+ PHYREGS(0x0818, 0x0814, 0x0810, 0x01FA, 0x01FB, 0x01FC),
},
{ .channel = 36,
.freq = 5180, /* MHz */
.unk2 = 3453,
- RADIOREGS(0x71, 0x02, 0x06, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x06, 0x02, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C,
0x89, 0xCC, 0x00, 0x0B, 0x0C, 0x89),
- PHYREGS(0x1C08, 0x1808, 0x1408, 0xF901, 0xFA01, 0xFB01),
+ PHYREGS(0x081C, 0x0818, 0x0814, 0x01F9, 0x01FA, 0x01FB),
},
{ .channel = 38,
.freq = 5190, /* MHz */
.unk2 = 3460,
- RADIOREGS(0x71, 0x02, 0x07, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x07, 0x02, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C,
0x89, 0xCC, 0x00, 0x0B, 0x0C, 0x89),
- PHYREGS(0x2008, 0x1C08, 0x1808, 0xF801, 0xF901, 0xFA01),
+ PHYREGS(0x0820, 0x081C, 0x0818, 0x01F8, 0x01F9, 0x01FA),
},
{ .channel = 40,
.freq = 5200, /* MHz */
.unk2 = 3467,
- RADIOREGS(0x71, 0x02, 0x08, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x08, 0x02, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B,
0x89, 0xBB, 0x00, 0x0A, 0x0B, 0x89),
- PHYREGS(0x2408, 0x2008, 0x1C08, 0xF701, 0xF801, 0xF901),
+ PHYREGS(0x0824, 0x0820, 0x081C, 0x01F7, 0x01F8, 0x01F9),
},
{ .channel = 42,
.freq = 5210, /* MHz */
.unk2 = 3473,
- RADIOREGS(0x71, 0x02, 0x09, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x09, 0x02, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B,
0x89, 0xBB, 0x00, 0x0A, 0x0B, 0x89),
- PHYREGS(0x2808, 0x2408, 0x2008, 0xF601, 0xF701, 0xF801),
+ PHYREGS(0x0828, 0x0824, 0x0820, 0x01F6, 0x01F7, 0x01F8),
},
{ .channel = 44,
.freq = 5220, /* MHz */
.unk2 = 3480,
- RADIOREGS(0x71, 0x02, 0x0A, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x0A, 0x02, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A,
0x88, 0xBB, 0x00, 0x09, 0x0A, 0x88),
- PHYREGS(0x2C08, 0x2808, 0x2408, 0xF501, 0xF601, 0xF701),
+ PHYREGS(0x082C, 0x0828, 0x0824, 0x01F5, 0x01F6, 0x01F7),
},
{ .channel = 46,
.freq = 5230, /* MHz */
.unk2 = 3487,
- RADIOREGS(0x71, 0x02, 0x0B, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x0B, 0x02, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A,
0x88, 0xBB, 0x00, 0x09, 0x0A, 0x88),
- PHYREGS(0x3008, 0x2C08, 0x2808, 0xF401, 0xF501, 0xF601),
+ PHYREGS(0x0830, 0x082C, 0x0828, 0x01F4, 0x01F5, 0x01F6),
},
{ .channel = 48,
.freq = 5240, /* MHz */
.unk2 = 3493,
- RADIOREGS(0x71, 0x02, 0x0C, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x0C, 0x02, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A,
0x87, 0xAA, 0x00, 0x09, 0x0A, 0x87),
- PHYREGS(0x3408, 0x3008, 0x2C08, 0xF301, 0xF401, 0xF501),
+ PHYREGS(0x0834, 0x0830, 0x082C, 0x01F3, 0x01F4, 0x01F5),
},
{ .channel = 50,
.freq = 5250, /* MHz */
.unk2 = 3500,
- RADIOREGS(0x71, 0x02, 0x0D, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x0D, 0x02, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A,
0x87, 0xAA, 0x00, 0x09, 0x0A, 0x87),
- PHYREGS(0x3808, 0x3408, 0x3008, 0xF201, 0xF301, 0xF401),
+ PHYREGS(0x0838, 0x0834, 0x0830, 0x01F2, 0x01F3, 0x01F4),
},
{ .channel = 52,
.freq = 5260, /* MHz */
.unk2 = 3507,
- RADIOREGS(0x71, 0x02, 0x0E, 0x0A, 0x98, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x0E, 0x02, 0x0A, 0x98, 0x01, 0x04, 0x0A,
0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09,
0x87, 0xAA, 0x00, 0x08, 0x09, 0x87),
- PHYREGS(0x3C08, 0x3808, 0x3408, 0xF101, 0xF201, 0xF301),
+ PHYREGS(0x083C, 0x0838, 0x0834, 0x01F1, 0x01F2, 0x01F3),
},
{ .channel = 54,
.freq = 5270, /* MHz */
.unk2 = 3513,
- RADIOREGS(0x71, 0x02, 0x0F, 0x0A, 0x98, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x0F, 0x02, 0x0A, 0x98, 0x01, 0x04, 0x0A,
0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09,
0x87, 0xAA, 0x00, 0x08, 0x09, 0x87),
- PHYREGS(0x4008, 0x3C08, 0x3808, 0xF001, 0xF101, 0xF201),
+ PHYREGS(0x0840, 0x083C, 0x0838, 0x01F0, 0x01F1, 0x01F2),
},
{ .channel = 56,
.freq = 5280, /* MHz */
.unk2 = 3520,
- RADIOREGS(0x71, 0x02, 0x10, 0x09, 0x91, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x10, 0x02, 0x09, 0x91, 0x01, 0x04, 0x0A,
0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08,
0x86, 0x99, 0x00, 0x08, 0x08, 0x86),
- PHYREGS(0x4408, 0x4008, 0x3C08, 0xF001, 0xF001, 0xF101),
+ PHYREGS(0x0844, 0x0840, 0x083C, 0x01F0, 0x01F0, 0x01F1),
},
{ .channel = 58,
.freq = 5290, /* MHz */
.unk2 = 3527,
- RADIOREGS(0x71, 0x02, 0x11, 0x09, 0x91, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x11, 0x02, 0x09, 0x91, 0x01, 0x04, 0x0A,
0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08,
0x86, 0x99, 0x00, 0x08, 0x08, 0x86),
- PHYREGS(0x4808, 0x4408, 0x4008, 0xEF01, 0xF001, 0xF001),
+ PHYREGS(0x0848, 0x0844, 0x0840, 0x01EF, 0x01F0, 0x01F0),
},
{ .channel = 60,
.freq = 5300, /* MHz */
.unk2 = 3533,
- RADIOREGS(0x71, 0x02, 0x12, 0x09, 0x8A, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x12, 0x02, 0x09, 0x8A, 0x01, 0x04, 0x0A,
0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07,
0x85, 0x99, 0x00, 0x08, 0x07, 0x85),
- PHYREGS(0x4C08, 0x4808, 0x4408, 0xEE01, 0xEF01, 0xF001),
+ PHYREGS(0x084C, 0x0848, 0x0844, 0x01EE, 0x01EF, 0x01F0),
},
{ .channel = 62,
.freq = 5310, /* MHz */
.unk2 = 3540,
- RADIOREGS(0x71, 0x02, 0x13, 0x09, 0x8A, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x13, 0x02, 0x09, 0x8A, 0x01, 0x04, 0x0A,
0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07,
0x85, 0x99, 0x00, 0x08, 0x07, 0x85),
- PHYREGS(0x5008, 0x4C08, 0x4808, 0xED01, 0xEE01, 0xEF01),
+ PHYREGS(0x0850, 0x084C, 0x0848, 0x01ED, 0x01EE, 0x01EF),
},
{ .channel = 64,
.freq = 5320, /* MHz */
.unk2 = 3547,
- RADIOREGS(0x71, 0x02, 0x14, 0x09, 0x83, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x14, 0x02, 0x09, 0x83, 0x01, 0x04, 0x0A,
0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07,
0x84, 0x88, 0x00, 0x07, 0x07, 0x84),
- PHYREGS(0x5408, 0x5008, 0x4C08, 0xEC01, 0xED01, 0xEE01),
+ PHYREGS(0x0854, 0x0850, 0x084C, 0x01EC, 0x01ED, 0x01EE),
},
{ .channel = 66,
.freq = 5330, /* MHz */
.unk2 = 3553,
- RADIOREGS(0x71, 0x02, 0x15, 0x09, 0x83, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x15, 0x02, 0x09, 0x83, 0x01, 0x04, 0x0A,
0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07,
0x84, 0x88, 0x00, 0x07, 0x07, 0x84),
- PHYREGS(0x5808, 0x5408, 0x5008, 0xEB01, 0xEC01, 0xED01),
+ PHYREGS(0x0858, 0x0854, 0x0850, 0x01EB, 0x01EC, 0x01ED),
},
{ .channel = 68,
.freq = 5340, /* MHz */
.unk2 = 3560,
- RADIOREGS(0x71, 0x02, 0x16, 0x08, 0x7C, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x16, 0x02, 0x08, 0x7C, 0x01, 0x04, 0x0A,
0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06,
0x84, 0x88, 0x00, 0x07, 0x06, 0x84),
- PHYREGS(0x5C08, 0x5808, 0x5408, 0xEA01, 0xEB01, 0xEC01),
+ PHYREGS(0x085C, 0x0858, 0x0854, 0x01EA, 0x01EB, 0x01EC),
},
{ .channel = 70,
.freq = 5350, /* MHz */
.unk2 = 3567,
- RADIOREGS(0x71, 0x02, 0x17, 0x08, 0x7C, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x17, 0x02, 0x08, 0x7C, 0x01, 0x04, 0x0A,
0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06,
0x84, 0x88, 0x00, 0x07, 0x06, 0x84),
- PHYREGS(0x6008, 0x5C08, 0x5808, 0xE901, 0xEA01, 0xEB01),
+ PHYREGS(0x0860, 0x085C, 0x0858, 0x01E9, 0x01EA, 0x01EB),
},
{ .channel = 72,
.freq = 5360, /* MHz */
.unk2 = 3573,
- RADIOREGS(0x71, 0x02, 0x18, 0x08, 0x75, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x18, 0x02, 0x08, 0x75, 0x01, 0x04, 0x0A,
0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05,
0x83, 0x77, 0x00, 0x06, 0x05, 0x83),
- PHYREGS(0x6408, 0x6008, 0x5C08, 0xE801, 0xE901, 0xEA01),
+ PHYREGS(0x0864, 0x0860, 0x085C, 0x01E8, 0x01E9, 0x01EA),
},
{ .channel = 74,
.freq = 5370, /* MHz */
.unk2 = 3580,
- RADIOREGS(0x71, 0x02, 0x19, 0x08, 0x75, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x19, 0x02, 0x08, 0x75, 0x01, 0x04, 0x0A,
0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05,
0x83, 0x77, 0x00, 0x06, 0x05, 0x83),
- PHYREGS(0x6808, 0x6408, 0x6008, 0xE701, 0xE801, 0xE901),
+ PHYREGS(0x0868, 0x0864, 0x0860, 0x01E7, 0x01E8, 0x01E9),
},
{ .channel = 76,
.freq = 5380, /* MHz */
.unk2 = 3587,
- RADIOREGS(0x71, 0x02, 0x1A, 0x08, 0x6E, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x1A, 0x02, 0x08, 0x6E, 0x01, 0x04, 0x0A,
0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04,
0x82, 0x77, 0x00, 0x06, 0x04, 0x82),
- PHYREGS(0x6C08, 0x6808, 0x6408, 0xE601, 0xE701, 0xE801),
+ PHYREGS(0x086C, 0x0868, 0x0864, 0x01E6, 0x01E7, 0x01E8),
},
{ .channel = 78,
.freq = 5390, /* MHz */
.unk2 = 3593,
- RADIOREGS(0x71, 0x02, 0x1B, 0x08, 0x6E, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x1B, 0x02, 0x08, 0x6E, 0x01, 0x04, 0x0A,
0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04,
0x82, 0x77, 0x00, 0x06, 0x04, 0x82),
- PHYREGS(0x7008, 0x6C08, 0x6808, 0xE501, 0xE601, 0xE701),
+ PHYREGS(0x0870, 0x086C, 0x0868, 0x01E5, 0x01E6, 0x01E7),
},
{ .channel = 80,
.freq = 5400, /* MHz */
.unk2 = 3600,
- RADIOREGS(0x71, 0x02, 0x1C, 0x07, 0x67, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x1C, 0x02, 0x07, 0x67, 0x01, 0x04, 0x0A,
0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04,
0x81, 0x66, 0x00, 0x05, 0x04, 0x81),
- PHYREGS(0x7408, 0x7008, 0x6C08, 0xE501, 0xE501, 0xE601),
+ PHYREGS(0x0874, 0x0870, 0x086C, 0x01E5, 0x01E5, 0x01E6),
},
{ .channel = 82,
.freq = 5410, /* MHz */
.unk2 = 3607,
- RADIOREGS(0x71, 0x02, 0x1D, 0x07, 0x67, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x1D, 0x02, 0x07, 0x67, 0x01, 0x04, 0x0A,
0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04,
0x81, 0x66, 0x00, 0x05, 0x04, 0x81),
- PHYREGS(0x7808, 0x7408, 0x7008, 0xE401, 0xE501, 0xE501),
+ PHYREGS(0x0878, 0x0874, 0x0870, 0x01E4, 0x01E5, 0x01E5),
},
{ .channel = 84,
.freq = 5420, /* MHz */
.unk2 = 3613,
- RADIOREGS(0x71, 0x02, 0x1E, 0x07, 0x61, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x1E, 0x02, 0x07, 0x61, 0x01, 0x04, 0x0A,
0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03,
0x80, 0x66, 0x00, 0x05, 0x03, 0x80),
- PHYREGS(0x7C08, 0x7808, 0x7408, 0xE301, 0xE401, 0xE501),
+ PHYREGS(0x087C, 0x0878, 0x0874, 0x01E3, 0x01E4, 0x01E5),
},
{ .channel = 86,
.freq = 5430, /* MHz */
.unk2 = 3620,
- RADIOREGS(0x71, 0x02, 0x1F, 0x07, 0x61, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x1F, 0x02, 0x07, 0x61, 0x01, 0x04, 0x0A,
0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03,
0x80, 0x66, 0x00, 0x05, 0x03, 0x80),
- PHYREGS(0x8008, 0x7C08, 0x7808, 0xE201, 0xE301, 0xE401),
+ PHYREGS(0x0880, 0x087C, 0x0878, 0x01E2, 0x01E3, 0x01E4),
},
{ .channel = 88,
.freq = 5440, /* MHz */
.unk2 = 3627,
- RADIOREGS(0x71, 0x02, 0x20, 0x07, 0x5A, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x20, 0x02, 0x07, 0x5A, 0x01, 0x04, 0x0A,
0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02,
0x80, 0x55, 0x00, 0x04, 0x02, 0x80),
- PHYREGS(0x8408, 0x8008, 0x7C08, 0xE101, 0xE201, 0xE301),
+ PHYREGS(0x0884, 0x0880, 0x087C, 0x01E1, 0x01E2, 0x01E3),
},
{ .channel = 90,
.freq = 5450, /* MHz */
.unk2 = 3633,
- RADIOREGS(0x71, 0x02, 0x21, 0x07, 0x5A, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x21, 0x02, 0x07, 0x5A, 0x01, 0x04, 0x0A,
0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02,
0x80, 0x55, 0x00, 0x04, 0x02, 0x80),
- PHYREGS(0x8808, 0x8408, 0x8008, 0xE001, 0xE101, 0xE201),
+ PHYREGS(0x0888, 0x0884, 0x0880, 0x01E0, 0x01E1, 0x01E2),
},
{ .channel = 92,
.freq = 5460, /* MHz */
.unk2 = 3640,
- RADIOREGS(0x71, 0x02, 0x22, 0x06, 0x53, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x22, 0x02, 0x06, 0x53, 0x01, 0x04, 0x0A,
0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01,
0x80, 0x55, 0x00, 0x04, 0x01, 0x80),
- PHYREGS(0x8C08, 0x8808, 0x8408, 0xDF01, 0xE001, 0xE101),
+ PHYREGS(0x088C, 0x0888, 0x0884, 0x01DF, 0x01E0, 0x01E1),
},
{ .channel = 94,
.freq = 5470, /* MHz */
.unk2 = 3647,
- RADIOREGS(0x71, 0x02, 0x23, 0x06, 0x53, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x23, 0x02, 0x06, 0x53, 0x01, 0x04, 0x0A,
0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01,
0x80, 0x55, 0x00, 0x04, 0x01, 0x80),
- PHYREGS(0x9008, 0x8C08, 0x8808, 0xDE01, 0xDF01, 0xE001),
+ PHYREGS(0x0890, 0x088C, 0x0888, 0x01DE, 0x01DF, 0x01E0),
},
{ .channel = 96,
.freq = 5480, /* MHz */
.unk2 = 3653,
- RADIOREGS(0x71, 0x02, 0x24, 0x06, 0x4D, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x24, 0x02, 0x06, 0x4D, 0x01, 0x04, 0x0A,
0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00,
0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
- PHYREGS(0x9408, 0x9008, 0x8C08, 0xDD01, 0xDE01, 0xDF01),
+ PHYREGS(0x0894, 0x0890, 0x088C, 0x01DD, 0x01DE, 0x01DF),
},
{ .channel = 98,
.freq = 5490, /* MHz */
.unk2 = 3660,
- RADIOREGS(0x71, 0x02, 0x25, 0x06, 0x4D, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x25, 0x02, 0x06, 0x4D, 0x01, 0x04, 0x0A,
0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00,
0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
- PHYREGS(0x9808, 0x9408, 0x9008, 0xDD01, 0xDD01, 0xDE01),
+ PHYREGS(0x0898, 0x0894, 0x0890, 0x01DD, 0x01DD, 0x01DE),
},
{ .channel = 100,
.freq = 5500, /* MHz */
.unk2 = 3667,
- RADIOREGS(0x71, 0x02, 0x26, 0x06, 0x47, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x26, 0x02, 0x06, 0x47, 0x01, 0x04, 0x0A,
0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00,
0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
- PHYREGS(0x9C08, 0x9808, 0x9408, 0xDC01, 0xDD01, 0xDD01),
+ PHYREGS(0x089C, 0x0898, 0x0894, 0x01DC, 0x01DD, 0x01DD),
},
{ .channel = 102,
.freq = 5510, /* MHz */
.unk2 = 3673,
- RADIOREGS(0x71, 0x02, 0x27, 0x06, 0x47, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x27, 0x02, 0x06, 0x47, 0x01, 0x04, 0x0A,
0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00,
0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
- PHYREGS(0xA008, 0x9C08, 0x9808, 0xDB01, 0xDC01, 0xDD01),
+ PHYREGS(0x08A0, 0x089C, 0x0898, 0x01DB, 0x01DC, 0x01DD),
},
{ .channel = 104,
.freq = 5520, /* MHz */
.unk2 = 3680,
- RADIOREGS(0x71, 0x02, 0x28, 0x05, 0x40, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x28, 0x02, 0x05, 0x40, 0x01, 0x04, 0x0A,
0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
- PHYREGS(0xA408, 0xA008, 0x9C08, 0xDA01, 0xDB01, 0xDC01),
+ PHYREGS(0x08A4, 0x08A0, 0x089C, 0x01DA, 0x01DB, 0x01DC),
},
{ .channel = 106,
.freq = 5530, /* MHz */
.unk2 = 3687,
- RADIOREGS(0x71, 0x02, 0x29, 0x05, 0x40, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x29, 0x02, 0x05, 0x40, 0x01, 0x04, 0x0A,
0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
- PHYREGS(0xA808, 0xA408, 0xA008, 0xD901, 0xDA01, 0xDB01),
+ PHYREGS(0x08A8, 0x08A4, 0x08A0, 0x01D9, 0x01DA, 0x01DB),
},
{ .channel = 108,
.freq = 5540, /* MHz */
.unk2 = 3693,
- RADIOREGS(0x71, 0x02, 0x2A, 0x05, 0x3A, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x2A, 0x02, 0x05, 0x3A, 0x01, 0x04, 0x0A,
0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
- PHYREGS(0xAC08, 0xA808, 0xA408, 0xD801, 0xD901, 0xDA01),
+ PHYREGS(0x08AC, 0x08A8, 0x08A4, 0x01D8, 0x01D9, 0x01DA),
},
{ .channel = 110,
.freq = 5550, /* MHz */
.unk2 = 3700,
- RADIOREGS(0x71, 0x02, 0x2B, 0x05, 0x3A, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x2B, 0x02, 0x05, 0x3A, 0x01, 0x04, 0x0A,
0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
- PHYREGS(0xB008, 0xAC08, 0xA808, 0xD701, 0xD801, 0xD901),
+ PHYREGS(0x08B0, 0x08AC, 0x08A8, 0x01D7, 0x01D8, 0x01D9),
},
{ .channel = 112,
.freq = 5560, /* MHz */
.unk2 = 3707,
- RADIOREGS(0x71, 0x02, 0x2C, 0x05, 0x34, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x2C, 0x02, 0x05, 0x34, 0x01, 0x04, 0x0A,
0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
- PHYREGS(0xB408, 0xB008, 0xAC08, 0xD701, 0xD701, 0xD801),
+ PHYREGS(0x08B4, 0x08B0, 0x08AC, 0x01D7, 0x01D7, 0x01D8),
},
{ .channel = 114,
.freq = 5570, /* MHz */
.unk2 = 3713,
- RADIOREGS(0x71, 0x02, 0x2D, 0x05, 0x34, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x2D, 0x02, 0x05, 0x34, 0x01, 0x04, 0x0A,
0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
- PHYREGS(0xB808, 0xB408, 0xB008, 0xD601, 0xD701, 0xD701),
+ PHYREGS(0x08B8, 0x08B4, 0x08B0, 0x01D6, 0x01D7, 0x01D7),
},
{ .channel = 116,
.freq = 5580, /* MHz */
.unk2 = 3720,
- RADIOREGS(0x71, 0x02, 0x2E, 0x04, 0x2E, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x2E, 0x02, 0x04, 0x2E, 0x01, 0x04, 0x0A,
0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
- PHYREGS(0xBC08, 0xB808, 0xB408, 0xD501, 0xD601, 0xD701),
+ PHYREGS(0x08BC, 0x08B8, 0x08B4, 0x01D5, 0x01D6, 0x01D7),
},
{ .channel = 118,
.freq = 5590, /* MHz */
.unk2 = 3727,
- RADIOREGS(0x71, 0x02, 0x2F, 0x04, 0x2E, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x2F, 0x02, 0x04, 0x2E, 0x01, 0x04, 0x0A,
0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
- PHYREGS(0xC008, 0xBC08, 0xB808, 0xD401, 0xD501, 0xD601),
+ PHYREGS(0x08C0, 0x08BC, 0x08B8, 0x01D4, 0x01D5, 0x01D6),
},
{ .channel = 120,
.freq = 5600, /* MHz */
.unk2 = 3733,
- RADIOREGS(0x71, 0x02, 0x30, 0x04, 0x28, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x30, 0x02, 0x04, 0x28, 0x01, 0x04, 0x0A,
0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00,
0x80, 0x11, 0x00, 0x01, 0x00, 0x80),
- PHYREGS(0xC408, 0xC008, 0xBC08, 0xD301, 0xD401, 0xD501),
+ PHYREGS(0x08C4, 0x08C0, 0x08BC, 0x01D3, 0x01D4, 0x01D5),
},
{ .channel = 122,
.freq = 5610, /* MHz */
.unk2 = 3740,
- RADIOREGS(0x71, 0x02, 0x31, 0x04, 0x28, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x31, 0x02, 0x04, 0x28, 0x01, 0x04, 0x0A,
0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00,
0x80, 0x11, 0x00, 0x01, 0x00, 0x80),
- PHYREGS(0xC808, 0xC408, 0xC008, 0xD201, 0xD301, 0xD401),
+ PHYREGS(0x08C8, 0x08C4, 0x08C0, 0x01D2, 0x01D3, 0x01D4),
},
{ .channel = 124,
.freq = 5620, /* MHz */
.unk2 = 3747,
- RADIOREGS(0x71, 0x02, 0x32, 0x04, 0x21, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x32, 0x02, 0x04, 0x21, 0x01, 0x04, 0x0A,
0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
0x80, 0x11, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xCC08, 0xC808, 0xC408, 0xD201, 0xD201, 0xD301),
+ PHYREGS(0x08CC, 0x08C8, 0x08C4, 0x01D2, 0x01D2, 0x01D3),
},
{ .channel = 126,
.freq = 5630, /* MHz */
.unk2 = 3753,
- RADIOREGS(0x71, 0x02, 0x33, 0x04, 0x21, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x33, 0x02, 0x04, 0x21, 0x01, 0x04, 0x0A,
0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
0x80, 0x11, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xD008, 0xCC08, 0xC808, 0xD101, 0xD201, 0xD201),
+ PHYREGS(0x08D0, 0x08CC, 0x08C8, 0x01D1, 0x01D2, 0x01D2),
},
{ .channel = 128,
.freq = 5640, /* MHz */
.unk2 = 3760,
- RADIOREGS(0x71, 0x02, 0x34, 0x03, 0x1C, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x34, 0x02, 0x03, 0x1C, 0x01, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xD408, 0xD008, 0xCC08, 0xD001, 0xD101, 0xD201),
+ PHYREGS(0x08D4, 0x08D0, 0x08CC, 0x01D0, 0x01D1, 0x01D2),
},
{ .channel = 130,
.freq = 5650, /* MHz */
.unk2 = 3767,
- RADIOREGS(0x71, 0x02, 0x35, 0x03, 0x1C, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x35, 0x02, 0x03, 0x1C, 0x01, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xD808, 0xD408, 0xD008, 0xCF01, 0xD001, 0xD101),
+ PHYREGS(0x08D8, 0x08D4, 0x08D0, 0x01CF, 0x01D0, 0x01D1),
},
{ .channel = 132,
.freq = 5660, /* MHz */
.unk2 = 3773,
- RADIOREGS(0x71, 0x02, 0x36, 0x03, 0x16, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x36, 0x02, 0x03, 0x16, 0x01, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xDC08, 0xD808, 0xD408, 0xCE01, 0xCF01, 0xD001),
+ PHYREGS(0x08DC, 0x08D8, 0x08D4, 0x01CE, 0x01CF, 0x01D0),
},
{ .channel = 134,
.freq = 5670, /* MHz */
.unk2 = 3780,
- RADIOREGS(0x71, 0x02, 0x37, 0x03, 0x16, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x37, 0x02, 0x03, 0x16, 0x01, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xE008, 0xDC08, 0xD808, 0xCE01, 0xCE01, 0xCF01),
+ PHYREGS(0x08E0, 0x08DC, 0x08D8, 0x01CE, 0x01CE, 0x01CF),
},
{ .channel = 136,
.freq = 5680, /* MHz */
.unk2 = 3787,
- RADIOREGS(0x71, 0x02, 0x38, 0x03, 0x10, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x38, 0x02, 0x03, 0x10, 0x01, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xE408, 0xE008, 0xDC08, 0xCD01, 0xCE01, 0xCE01),
+ PHYREGS(0x08E4, 0x08E0, 0x08DC, 0x01CD, 0x01CE, 0x01CE),
},
{ .channel = 138,
.freq = 5690, /* MHz */
.unk2 = 3793,
- RADIOREGS(0x71, 0x02, 0x39, 0x03, 0x10, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x39, 0x02, 0x03, 0x10, 0x01, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xE808, 0xE408, 0xE008, 0xCC01, 0xCD01, 0xCE01),
+ PHYREGS(0x08E8, 0x08E4, 0x08E0, 0x01CC, 0x01CD, 0x01CE),
},
{ .channel = 140,
.freq = 5700, /* MHz */
.unk2 = 3800,
- RADIOREGS(0x71, 0x02, 0x3A, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x3A, 0x02, 0x02, 0x0A, 0x01, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xEC08, 0xE808, 0xE408, 0xCB01, 0xCC01, 0xCD01),
+ PHYREGS(0x08EC, 0x08E8, 0x08E4, 0x01CB, 0x01CC, 0x01CD),
},
{ .channel = 142,
.freq = 5710, /* MHz */
.unk2 = 3807,
- RADIOREGS(0x71, 0x02, 0x3B, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x3B, 0x02, 0x02, 0x0A, 0x01, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xF008, 0xEC08, 0xE808, 0xCA01, 0xCB01, 0xCC01),
+ PHYREGS(0x08F0, 0x08EC, 0x08E8, 0x01CA, 0x01CB, 0x01CC),
},
{ .channel = 144,
.freq = 5720, /* MHz */
.unk2 = 3813,
- RADIOREGS(0x71, 0x02, 0x3C, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x3C, 0x02, 0x02, 0x0A, 0x01, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xF408, 0xF008, 0xEC08, 0xC901, 0xCA01, 0xCB01),
+ PHYREGS(0x08F4, 0x08F0, 0x08EC, 0x01C9, 0x01CA, 0x01CB),
},
{ .channel = 145,
.freq = 5725, /* MHz */
.unk2 = 3817,
- RADIOREGS(0x72, 0x04, 0x79, 0x02, 0x03, 0x01, 0x03, 0x14,
+ RADIOREGS(0x72, 0x79, 0x04, 0x02, 0x03, 0x01, 0x03, 0x14,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xF608, 0xF208, 0xEE08, 0xC901, 0xCA01, 0xCB01),
+ PHYREGS(0x08F6, 0x08F2, 0x08EE, 0x01C9, 0x01CA, 0x01CB),
},
{ .channel = 146,
.freq = 5730, /* MHz */
.unk2 = 3820,
- RADIOREGS(0x71, 0x02, 0x3D, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x3D, 0x02, 0x02, 0x0A, 0x01, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xF808, 0xF408, 0xF008, 0xC901, 0xC901, 0xCA01),
+ PHYREGS(0x08F8, 0x08F4, 0x08F0, 0x01C9, 0x01C9, 0x01CA),
},
{ .channel = 147,
.freq = 5735, /* MHz */
.unk2 = 3823,
- RADIOREGS(0x72, 0x04, 0x7B, 0x02, 0x03, 0x01, 0x03, 0x14,
+ RADIOREGS(0x72, 0x7B, 0x04, 0x02, 0x03, 0x01, 0x03, 0x14,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xFA08, 0xF608, 0xF208, 0xC801, 0xC901, 0xCA01),
+ PHYREGS(0x08FA, 0x08F6, 0x08F2, 0x01C8, 0x01C9, 0x01CA),
},
{ .channel = 148,
.freq = 5740, /* MHz */
.unk2 = 3827,
- RADIOREGS(0x71, 0x02, 0x3E, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x3E, 0x02, 0x02, 0x0A, 0x01, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xFC08, 0xF808, 0xF408, 0xC801, 0xC901, 0xC901),
+ PHYREGS(0x08FC, 0x08F8, 0x08F4, 0x01C8, 0x01C9, 0x01C9),
},
{ .channel = 149,
.freq = 5745, /* MHz */
.unk2 = 3830,
- RADIOREGS(0x72, 0x04, 0x7D, 0x02, 0xFE, 0x00, 0x03, 0x14,
+ RADIOREGS(0x72, 0x7D, 0x04, 0x02, 0xFE, 0x00, 0x03, 0x14,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0xFE08, 0xFA08, 0xF608, 0xC801, 0xC801, 0xC901),
+ PHYREGS(0x08FE, 0x08FA, 0x08F6, 0x01C8, 0x01C8, 0x01C9),
},
{ .channel = 150,
.freq = 5750, /* MHz */
.unk2 = 3833,
- RADIOREGS(0x71, 0x02, 0x3F, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x3F, 0x02, 0x02, 0x0A, 0x01, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x0009, 0xFC08, 0xF808, 0xC701, 0xC801, 0xC901),
+ PHYREGS(0x0900, 0x08FC, 0x08F8, 0x01C7, 0x01C8, 0x01C9),
},
{ .channel = 151,
.freq = 5755, /* MHz */
.unk2 = 3837,
- RADIOREGS(0x72, 0x04, 0x7F, 0x02, 0xFE, 0x00, 0x03, 0x14,
+ RADIOREGS(0x72, 0x7F, 0x04, 0x02, 0xFE, 0x00, 0x03, 0x14,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x0209, 0xFE08, 0xFA08, 0xC701, 0xC801, 0xC801),
+ PHYREGS(0x0902, 0x08FE, 0x08FA, 0x01C7, 0x01C8, 0x01C8),
},
{ .channel = 152,
.freq = 5760, /* MHz */
.unk2 = 3840,
- RADIOREGS(0x71, 0x02, 0x40, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x40, 0x02, 0x02, 0x0A, 0x01, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x0409, 0x0009, 0xFC08, 0xC601, 0xC701, 0xC801),
+ PHYREGS(0x0904, 0x0900, 0x08FC, 0x01C6, 0x01C7, 0x01C8),
},
{ .channel = 153,
.freq = 5765, /* MHz */
.unk2 = 3843,
- RADIOREGS(0x72, 0x04, 0x81, 0x02, 0xF8, 0x00, 0x03, 0x14,
+ RADIOREGS(0x72, 0x81, 0x04, 0x02, 0xF8, 0x00, 0x03, 0x14,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x0609, 0x0209, 0xFE08, 0xC601, 0xC701, 0xC801),
+ PHYREGS(0x0906, 0x0902, 0x08FE, 0x01C6, 0x01C7, 0x01C8),
},
{ .channel = 154,
.freq = 5770, /* MHz */
.unk2 = 3847,
- RADIOREGS(0x71, 0x02, 0x41, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x41, 0x02, 0x02, 0x0A, 0x01, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x0809, 0x0409, 0x0009, 0xC601, 0xC601, 0xC701),
+ PHYREGS(0x0908, 0x0904, 0x0900, 0x01C6, 0x01C6, 0x01C7),
},
{ .channel = 155,
.freq = 5775, /* MHz */
.unk2 = 3850,
- RADIOREGS(0x72, 0x04, 0x83, 0x02, 0xF8, 0x00, 0x03, 0x14,
+ RADIOREGS(0x72, 0x83, 0x04, 0x02, 0xF8, 0x00, 0x03, 0x14,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x0A09, 0x0609, 0x0209, 0xC501, 0xC601, 0xC701),
+ PHYREGS(0x090A, 0x0906, 0x0902, 0x01C5, 0x01C6, 0x01C7),
},
{ .channel = 156,
.freq = 5780, /* MHz */
.unk2 = 3853,
- RADIOREGS(0x71, 0x02, 0x42, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x42, 0x02, 0x02, 0x0A, 0x01, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x0C09, 0x0809, 0x0409, 0xC501, 0xC601, 0xC601),
+ PHYREGS(0x090C, 0x0908, 0x0904, 0x01C5, 0x01C6, 0x01C6),
},
{ .channel = 157,
.freq = 5785, /* MHz */
.unk2 = 3857,
- RADIOREGS(0x72, 0x04, 0x85, 0x02, 0xF2, 0x00, 0x03, 0x14,
+ RADIOREGS(0x72, 0x85, 0x04, 0x02, 0xF2, 0x00, 0x03, 0x14,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x0E09, 0x0A09, 0x0609, 0xC401, 0xC501, 0xC601),
+ PHYREGS(0x090E, 0x090A, 0x0906, 0x01C4, 0x01C5, 0x01C6),
},
{ .channel = 158,
.freq = 5790, /* MHz */
.unk2 = 3860,
- RADIOREGS(0x71, 0x02, 0x43, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x43, 0x02, 0x02, 0x0A, 0x01, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x1009, 0x0C09, 0x0809, 0xC401, 0xC501, 0xC601),
+ PHYREGS(0x0910, 0x090C, 0x0908, 0x01C4, 0x01C5, 0x01C6),
},
{ .channel = 159,
.freq = 5795, /* MHz */
.unk2 = 3863,
- RADIOREGS(0x72, 0x04, 0x87, 0x02, 0xF2, 0x00, 0x03, 0x14,
+ RADIOREGS(0x72, 0x87, 0x04, 0x02, 0xF2, 0x00, 0x03, 0x14,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x1209, 0x0E09, 0x0A09, 0xC401, 0xC401, 0xC501),
+ PHYREGS(0x0912, 0x090E, 0x090A, 0x01C4, 0x01C4, 0x01C5),
},
{ .channel = 160,
.freq = 5800, /* MHz */
.unk2 = 3867,
- RADIOREGS(0x71, 0x02, 0x44, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x44, 0x02, 0x01, 0x0A, 0x01, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x1409, 0x1009, 0x0C09, 0xC301, 0xC401, 0xC501),
+ PHYREGS(0x0914, 0x0910, 0x090C, 0x01C3, 0x01C4, 0x01C5),
},
{ .channel = 161,
.freq = 5805, /* MHz */
.unk2 = 3870,
- RADIOREGS(0x72, 0x04, 0x89, 0x01, 0xED, 0x00, 0x03, 0x14,
+ RADIOREGS(0x72, 0x89, 0x04, 0x01, 0xED, 0x00, 0x03, 0x14,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x1609, 0x1209, 0x0E09, 0xC301, 0xC401, 0xC401),
+ PHYREGS(0x0916, 0x0912, 0x090E, 0x01C3, 0x01C4, 0x01C4),
},
{ .channel = 162,
.freq = 5810, /* MHz */
.unk2 = 3873,
- RADIOREGS(0x71, 0x02, 0x45, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x45, 0x02, 0x01, 0x0A, 0x01, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x1809, 0x1409, 0x1009, 0xC201, 0xC301, 0xC401),
+ PHYREGS(0x0918, 0x0914, 0x0910, 0x01C2, 0x01C3, 0x01C4),
},
{ .channel = 163,
.freq = 5815, /* MHz */
.unk2 = 3877,
- RADIOREGS(0x72, 0x04, 0x8B, 0x01, 0xED, 0x00, 0x03, 0x14,
+ RADIOREGS(0x72, 0x8B, 0x04, 0x01, 0xED, 0x00, 0x03, 0x14,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x1A09, 0x1609, 0x1209, 0xC201, 0xC301, 0xC401),
+ PHYREGS(0x091A, 0x0916, 0x0912, 0x01C2, 0x01C3, 0x01C4),
},
{ .channel = 164,
.freq = 5820, /* MHz */
.unk2 = 3880,
- RADIOREGS(0x71, 0x02, 0x46, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x46, 0x02, 0x01, 0x0A, 0x01, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x1C09, 0x1809, 0x1409, 0xC201, 0xC201, 0xC301),
+ PHYREGS(0x091C, 0x0918, 0x0914, 0x01C2, 0x01C2, 0x01C3),
},
{ .channel = 165,
.freq = 5825, /* MHz */
.unk2 = 3883,
- RADIOREGS(0x72, 0x04, 0x8D, 0x01, 0xED, 0x00, 0x03, 0x14,
+ RADIOREGS(0x72, 0x8D, 0x04, 0x01, 0xED, 0x00, 0x03, 0x14,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x1E09, 0x1A09, 0x1609, 0xC101, 0xC201, 0xC301),
+ PHYREGS(0x091E, 0x091A, 0x0916, 0x01C1, 0x01C2, 0x01C3),
},
{ .channel = 166,
.freq = 5830, /* MHz */
.unk2 = 3887,
- RADIOREGS(0x71, 0x02, 0x47, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x47, 0x02, 0x01, 0x0A, 0x01, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x2009, 0x1C09, 0x1809, 0xC101, 0xC201, 0xC201),
+ PHYREGS(0x0920, 0x091C, 0x0918, 0x01C1, 0x01C2, 0x01C2),
},
{ .channel = 168,
.freq = 5840, /* MHz */
.unk2 = 3893,
- RADIOREGS(0x71, 0x02, 0x48, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x48, 0x02, 0x01, 0x0A, 0x01, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x2409, 0x2009, 0x1C09, 0xC001, 0xC101, 0xC201),
+ PHYREGS(0x0924, 0x0920, 0x091C, 0x01C0, 0x01C1, 0x01C2),
},
{ .channel = 170,
.freq = 5850, /* MHz */
.unk2 = 3900,
- RADIOREGS(0x71, 0x02, 0x49, 0x01, 0xE0, 0x00, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x49, 0x02, 0x01, 0xE0, 0x00, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x2809, 0x2409, 0x2009, 0xBF01, 0xC001, 0xC101),
+ PHYREGS(0x0928, 0x0924, 0x0920, 0x01BF, 0x01C0, 0x01C1),
},
{ .channel = 172,
.freq = 5860, /* MHz */
.unk2 = 3907,
- RADIOREGS(0x71, 0x02, 0x4A, 0x01, 0xDE, 0x00, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x4A, 0x02, 0x01, 0xDE, 0x00, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x2C09, 0x2809, 0x2409, 0xBF01, 0xBF01, 0xC001),
+ PHYREGS(0x092C, 0x0928, 0x0924, 0x01BF, 0x01BF, 0x01C0),
},
{ .channel = 174,
.freq = 5870, /* MHz */
.unk2 = 3913,
- RADIOREGS(0x71, 0x02, 0x4B, 0x00, 0xDB, 0x00, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x4B, 0x02, 0x00, 0xDB, 0x00, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x3009, 0x2C09, 0x2809, 0xBE01, 0xBF01, 0xBF01),
+ PHYREGS(0x0930, 0x092C, 0x0928, 0x01BE, 0x01BF, 0x01BF),
},
{ .channel = 176,
.freq = 5880, /* MHz */
.unk2 = 3920,
- RADIOREGS(0x71, 0x02, 0x4C, 0x00, 0xD8, 0x00, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x4C, 0x02, 0x00, 0xD8, 0x00, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x3409, 0x3009, 0x2C09, 0xBD01, 0xBE01, 0xBF01),
+ PHYREGS(0x0934, 0x0930, 0x092C, 0x01BD, 0x01BE, 0x01BF),
},
{ .channel = 178,
.freq = 5890, /* MHz */
.unk2 = 3927,
- RADIOREGS(0x71, 0x02, 0x4D, 0x00, 0xD6, 0x00, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x4D, 0x02, 0x00, 0xD6, 0x00, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x3809, 0x3409, 0x3009, 0xBC01, 0xBD01, 0xBE01),
+ PHYREGS(0x0938, 0x0934, 0x0930, 0x01BC, 0x01BD, 0x01BE),
},
{ .channel = 180,
.freq = 5900, /* MHz */
.unk2 = 3933,
- RADIOREGS(0x71, 0x02, 0x4E, 0x00, 0xD3, 0x00, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x4E, 0x02, 0x00, 0xD3, 0x00, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x3C09, 0x3809, 0x3409, 0xBC01, 0xBC01, 0xBD01),
+ PHYREGS(0x093C, 0x0938, 0x0934, 0x01BC, 0x01BC, 0x01BD),
},
{ .channel = 182,
.freq = 5910, /* MHz */
.unk2 = 3940,
- RADIOREGS(0x71, 0x02, 0x4F, 0x00, 0xD6, 0x00, 0x04, 0x0A,
+ RADIOREGS(0x71, 0x4F, 0x02, 0x00, 0xD6, 0x00, 0x04, 0x0A,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
- PHYREGS(0x4009, 0x3C09, 0x3809, 0xBB01, 0xBC01, 0xBC01),
+ PHYREGS(0x0940, 0x093C, 0x0938, 0x01BB, 0x01BC, 0x01BC),
},
{ .channel = 1,
.freq = 2412, /* MHz */
.unk2 = 3216,
- RADIOREGS(0x73, 0x09, 0x6C, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ RADIOREGS(0x73, 0x6C, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15,
0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0D, 0x0C,
0x80, 0xFF, 0x88, 0x0D, 0x0C, 0x80),
- PHYREGS(0xC903, 0xC503, 0xC103, 0x3A04, 0x3F04, 0x4304),
+ PHYREGS(0x03C9, 0x03C5, 0x03C1, 0x043A, 0x043F, 0x0443),
},
{ .channel = 2,
.freq = 2417, /* MHz */
.unk2 = 3223,
- RADIOREGS(0x73, 0x09, 0x71, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ RADIOREGS(0x73, 0x71, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15,
0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0B,
0x80, 0xFF, 0x88, 0x0C, 0x0B, 0x80),
- PHYREGS(0xCB03, 0xC703, 0xC303, 0x3804, 0x3D04, 0x4104),
+ PHYREGS(0x03CB, 0x03C7, 0x03C3, 0x0438, 0x043D, 0x0441),
},
{ .channel = 3,
.freq = 2422, /* MHz */
.unk2 = 3229,
- RADIOREGS(0x73, 0x09, 0x76, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ RADIOREGS(0x73, 0x76, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15,
0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A,
0x80, 0xFF, 0x88, 0x0C, 0x0A, 0x80),
- PHYREGS(0xCD03, 0xC903, 0xC503, 0x3604, 0x3A04, 0x3F04),
+ PHYREGS(0x03CD, 0x03C9, 0x03C5, 0x0436, 0x043A, 0x043F),
},
{ .channel = 4,
.freq = 2427, /* MHz */
.unk2 = 3236,
- RADIOREGS(0x73, 0x09, 0x7B, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ RADIOREGS(0x73, 0x7B, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15,
0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A,
0x80, 0xFF, 0x88, 0x0C, 0x0A, 0x80),
- PHYREGS(0xCF03, 0xCB03, 0xC703, 0x3404, 0x3804, 0x3D04),
+ PHYREGS(0x03CF, 0x03CB, 0x03C7, 0x0434, 0x0438, 0x043D),
},
{ .channel = 5,
.freq = 2432, /* MHz */
.unk2 = 3243,
- RADIOREGS(0x73, 0x09, 0x80, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ RADIOREGS(0x73, 0x80, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15,
0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x09,
0x80, 0xFF, 0x88, 0x0C, 0x09, 0x80),
- PHYREGS(0xD103, 0xCD03, 0xC903, 0x3104, 0x3604, 0x3A04),
+ PHYREGS(0x03D1, 0x03CD, 0x03C9, 0x0431, 0x0436, 0x043A),
},
{ .channel = 6,
.freq = 2437, /* MHz */
.unk2 = 3249,
- RADIOREGS(0x73, 0x09, 0x85, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ RADIOREGS(0x73, 0x85, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15,
0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0B, 0x08,
0x80, 0xFF, 0x88, 0x0B, 0x08, 0x80),
- PHYREGS(0xD303, 0xCF03, 0xCB03, 0x2F04, 0x3404, 0x3804),
+ PHYREGS(0x03D3, 0x03CF, 0x03CB, 0x042F, 0x0434, 0x0438),
},
{ .channel = 7,
.freq = 2442, /* MHz */
.unk2 = 3256,
- RADIOREGS(0x73, 0x09, 0x8A, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ RADIOREGS(0x73, 0x8A, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15,
0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x07,
0x80, 0xFF, 0x88, 0x0A, 0x07, 0x80),
- PHYREGS(0xD503, 0xD103, 0xCD03, 0x2D04, 0x3104, 0x3604),
+ PHYREGS(0x03D5, 0x03D1, 0x03CD, 0x042D, 0x0431, 0x0436),
},
{ .channel = 8,
.freq = 2447, /* MHz */
.unk2 = 3263,
- RADIOREGS(0x73, 0x09, 0x8F, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ RADIOREGS(0x73, 0x8F, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15,
0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x06,
0x80, 0xFF, 0x88, 0x0A, 0x06, 0x80),
- PHYREGS(0xD703, 0xD303, 0xCF03, 0x2B04, 0x2F04, 0x3404),
+ PHYREGS(0x03D7, 0x03D3, 0x03CF, 0x042B, 0x042F, 0x0434),
},
{ .channel = 9,
.freq = 2452, /* MHz */
.unk2 = 3269,
- RADIOREGS(0x73, 0x09, 0x94, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ RADIOREGS(0x73, 0x94, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15,
0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x09, 0x06,
0x80, 0xFF, 0x88, 0x09, 0x06, 0x80),
- PHYREGS(0xD903, 0xD503, 0xD103, 0x2904, 0x2D04, 0x3104),
+ PHYREGS(0x03D9, 0x03D5, 0x03D1, 0x0429, 0x042D, 0x0431),
},
{ .channel = 10,
.freq = 2457, /* MHz */
.unk2 = 3276,
- RADIOREGS(0x73, 0x09, 0x99, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ RADIOREGS(0x73, 0x99, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15,
0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x05,
0x80, 0xFF, 0x88, 0x08, 0x05, 0x80),
- PHYREGS(0xDB03, 0xD703, 0xD303, 0x2704, 0x2B04, 0x2F04),
+ PHYREGS(0x03DB, 0x03D7, 0x03D3, 0x0427, 0x042B, 0x042F),
},
{ .channel = 11,
.freq = 2462, /* MHz */
.unk2 = 3283,
- RADIOREGS(0x73, 0x09, 0x9E, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ RADIOREGS(0x73, 0x9E, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15,
0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x04,
0x80, 0xFF, 0x88, 0x08, 0x04, 0x80),
- PHYREGS(0xDD03, 0xD903, 0xD503, 0x2404, 0x2904, 0x2D04),
+ PHYREGS(0x03DD, 0x03D9, 0x03D5, 0x0424, 0x0429, 0x042D),
},
{ .channel = 12,
.freq = 2467, /* MHz */
.unk2 = 3289,
- RADIOREGS(0x73, 0x09, 0xA3, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ RADIOREGS(0x73, 0xA3, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15,
0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x03,
0x80, 0xFF, 0x88, 0x08, 0x03, 0x80),
- PHYREGS(0xDF03, 0xDB03, 0xD703, 0x2204, 0x2704, 0x2B04),
+ PHYREGS(0x03DF, 0x03DB, 0x03D7, 0x0422, 0x0427, 0x042B),
},
{ .channel = 13,
.freq = 2472, /* MHz */
.unk2 = 3296,
- RADIOREGS(0x73, 0x09, 0xA8, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ RADIOREGS(0x73, 0xA8, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15,
0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x03,
0x80, 0xFF, 0x88, 0x07, 0x03, 0x80),
- PHYREGS(0xE103, 0xDD03, 0xD903, 0x2004, 0x2404, 0x2904),
+ PHYREGS(0x03E1, 0x03DD, 0x03D9, 0x0420, 0x0424, 0x0429),
},
{ .channel = 14,
.freq = 2484, /* MHz */
.unk2 = 3312,
- RADIOREGS(0x73, 0x09, 0xB4, 0x0F, 0xFF, 0x01, 0x07, 0x15,
+ RADIOREGS(0x73, 0xB4, 0x09, 0x0F, 0xFF, 0x01, 0x07, 0x15,
0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x01,
0x80, 0xFF, 0x88, 0x07, 0x01, 0x80),
- PHYREGS(0xE603, 0xE203, 0xDE03, 0x1B04, 0x1F04, 0x2404),
+ PHYREGS(0x03E6, 0x03E2, 0x03DE, 0x041B, 0x041F, 0x0424),
},
};
@@ -1299,7 +1299,7 @@ void b2055_upload_inittab(struct b43_wldev *dev,
bool ghz5, bool ignore_uploadflag)
{
const struct b2055_inittab_entry *e;
- unsigned int i;
+ unsigned int i, writes = 0;
u16 value;
for (i = 0; i < ARRAY_SIZE(b2055_inittab); i++) {
@@ -1312,6 +1312,8 @@ void b2055_upload_inittab(struct b43_wldev *dev,
else
value = e->ghz2;
b43_radio_write16(dev, i, value);
+ if (++writes % 4 == 0)
+ b43_read32(dev, B43_MMIO_MACCTL); /* flush */
}
}
}
diff --git a/drivers/net/wireless/b43/radio_2056.c b/drivers/net/wireless/b43/radio_2056.c
index d8563192ce56..0cdf6a46ba4b 100644
--- a/drivers/net/wireless/b43/radio_2056.c
+++ b/drivers/net/wireless/b43/radio_2056.c
@@ -24,9 +24,6028 @@
#include "radio_2056.h"
#include "phy_common.h"
+#define RADIOREGS3(r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, \
+ r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, \
+ r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, \
+ r30, r31, r32, r33, r34, r35, r36) \
+ .radio_syn_pll_vcocal1 = r00, \
+ .radio_syn_pll_vcocal2 = r01, \
+ .radio_syn_pll_refdiv = r02, \
+ .radio_syn_pll_mmd2 = r03, \
+ .radio_syn_pll_mmd1 = r04, \
+ .radio_syn_pll_loopfilter1 = r05, \
+ .radio_syn_pll_loopfilter2 = r06, \
+ .radio_syn_pll_loopfilter3 = r07, \
+ .radio_syn_pll_loopfilter4 = r08, \
+ .radio_syn_pll_loopfilter5 = r09, \
+ .radio_syn_reserved_addr27 = r10, \
+ .radio_syn_reserved_addr28 = r11, \
+ .radio_syn_reserved_addr29 = r12, \
+ .radio_syn_logen_vcobuf1 = r13, \
+ .radio_syn_logen_mixer2 = r14, \
+ .radio_syn_logen_buf3 = r15, \
+ .radio_syn_logen_buf4 = r16, \
+ .radio_rx0_lnaa_tune = r17, \
+ .radio_rx0_lnag_tune = r18, \
+ .radio_tx0_intpaa_boost_tune = r19, \
+ .radio_tx0_intpag_boost_tune = r20, \
+ .radio_tx0_pada_boost_tune = r21, \
+ .radio_tx0_padg_boost_tune = r22, \
+ .radio_tx0_pgaa_boost_tune = r23, \
+ .radio_tx0_pgag_boost_tune = r24, \
+ .radio_tx0_mixa_boost_tune = r25, \
+ .radio_tx0_mixg_boost_tune = r26, \
+ .radio_rx1_lnaa_tune = r27, \
+ .radio_rx1_lnag_tune = r28, \
+ .radio_tx1_intpaa_boost_tune = r29, \
+ .radio_tx1_intpag_boost_tune = r30, \
+ .radio_tx1_pada_boost_tune = r31, \
+ .radio_tx1_padg_boost_tune = r32, \
+ .radio_tx1_pgaa_boost_tune = r33, \
+ .radio_tx1_pgag_boost_tune = r34, \
+ .radio_tx1_mixa_boost_tune = r35, \
+ .radio_tx1_mixg_boost_tune = r36
+
+#define PHYREGS(r0, r1, r2, r3, r4, r5) \
+ .phy_regs.phy_bw1a = r0, \
+ .phy_regs.phy_bw2 = r1, \
+ .phy_regs.phy_bw3 = r2, \
+ .phy_regs.phy_bw4 = r3, \
+ .phy_regs.phy_bw5 = r4, \
+ .phy_regs.phy_bw6 = r5
+
+/* http://bcm-v4.sipsolutions.net/802.11/Radio/2056/ChannelTable */
static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev3[] = {
+ { .freq = 4920,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00),
+ PHYREGS(0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216),
+ },
+ { .freq = 4930,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00),
+ PHYREGS(0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215),
+ },
+ { .freq = 4940,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00),
+ PHYREGS(0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214),
+ },
+ { .freq = 4950,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00),
+ PHYREGS(0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213),
+ },
+ { .freq = 4960,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00),
+ PHYREGS(0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212),
+ },
+ { .freq = 4970,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00),
+ PHYREGS(0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211),
+ },
+ { .freq = 4980,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00),
+ PHYREGS(0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f),
+ },
+ { .freq = 4990,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00),
+ PHYREGS(0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e),
+ },
+ { .freq = 5000,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00),
+ PHYREGS(0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d),
+ },
+ { .freq = 5010,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00),
+ PHYREGS(0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c),
+ },
+ { .freq = 5020,
+ RADIOREGS3(0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00),
+ PHYREGS(0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b),
+ },
+ { .freq = 5030,
+ RADIOREGS3(0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00),
+ PHYREGS(0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a),
+ },
+ { .freq = 5040,
+ RADIOREGS3(0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00),
+ PHYREGS(0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209),
+ },
+ { .freq = 5050,
+ RADIOREGS3(0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00),
+ PHYREGS(0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208),
+ },
+ { .freq = 5060,
+ RADIOREGS3(0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00),
+ PHYREGS(0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207),
+ },
+ { .freq = 5070,
+ RADIOREGS3(0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00),
+ PHYREGS(0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206),
+ },
+ { .freq = 5080,
+ RADIOREGS3(0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00),
+ PHYREGS(0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205),
+ },
+ { .freq = 5090,
+ RADIOREGS3(0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00),
+ PHYREGS(0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204),
+ },
+ { .freq = 5100,
+ RADIOREGS3(0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00),
+ PHYREGS(0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203),
+ },
+ { .freq = 5110,
+ RADIOREGS3(0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xfc, 0x00),
+ PHYREGS(0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202),
+ },
+ { .freq = 5120,
+ RADIOREGS3(0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xfc, 0x00),
+ PHYREGS(0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201),
+ },
+ { .freq = 5130,
+ RADIOREGS3(0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xfc, 0x00),
+ PHYREGS(0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200),
+ },
+ { .freq = 5140,
+ RADIOREGS3(0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xfc, 0x00),
+ PHYREGS(0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff),
+ },
+ { .freq = 5160,
+ RADIOREGS3(0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xfc, 0x00),
+ PHYREGS(0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd),
+ },
+ { .freq = 5170,
+ RADIOREGS3(0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xfc, 0x00),
+ PHYREGS(0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc),
+ },
+ { .freq = 5180,
+ RADIOREGS3(0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xef, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xfc, 0x00, 0xef, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xfc, 0x00),
+ PHYREGS(0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb),
+ },
+ { .freq = 5190,
+ RADIOREGS3(0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xef, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xfc, 0x00, 0xef, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xfc, 0x00),
+ PHYREGS(0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa),
+ },
+ { .freq = 5200,
+ RADIOREGS3(0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xef, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xfc, 0x00, 0xef, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xfc, 0x00),
+ PHYREGS(0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9),
+ },
+ { .freq = 5210,
+ RADIOREGS3(0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xdf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xfc, 0x00),
+ PHYREGS(0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8),
+ },
+ { .freq = 5220,
+ RADIOREGS3(0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xdf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xfc, 0x00),
+ PHYREGS(0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7),
+ },
+ { .freq = 5230,
+ RADIOREGS3(0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xdf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xfc, 0x00),
+ PHYREGS(0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6),
+ },
+ { .freq = 5240,
+ RADIOREGS3(0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xfc, 0x00),
+ PHYREGS(0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5),
+ },
+ { .freq = 5250,
+ RADIOREGS3(0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xfc, 0x00),
+ PHYREGS(0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4),
+ },
+ { .freq = 5260,
+ RADIOREGS3(0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xfc, 0x00),
+ PHYREGS(0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3),
+ },
+ { .freq = 5270,
+ RADIOREGS3(0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00,
+ 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xfc, 0x00),
+ PHYREGS(0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2),
+ },
+ { .freq = 5280,
+ RADIOREGS3(0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00,
+ 0xff, 0xbf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xfc, 0x00),
+ PHYREGS(0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1),
+ },
+ { .freq = 5290,
+ RADIOREGS3(0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00,
+ 0xff, 0xbf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xfc, 0x00),
+ PHYREGS(0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0),
+ },
+ { .freq = 5300,
+ RADIOREGS3(0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0xbf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x05, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xfc, 0x00),
+ PHYREGS(0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0),
+ },
+ { .freq = 5310,
+ RADIOREGS3(0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0xbf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x05, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xfa, 0x00),
+ PHYREGS(0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef),
+ },
+ { .freq = 5320,
+ RADIOREGS3(0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0xbf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x05, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xfa, 0x00),
+ PHYREGS(0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee),
+ },
+ { .freq = 5330,
+ RADIOREGS3(0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0xaf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x05, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xfa, 0x00),
+ PHYREGS(0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed),
+ },
+ { .freq = 5340,
+ RADIOREGS3(0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0xaf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x05, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xfa, 0x00),
+ PHYREGS(0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec),
+ },
+ { .freq = 5350,
+ RADIOREGS3(0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xfa, 0x00),
+ PHYREGS(0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb),
+ },
+ { .freq = 5360,
+ RADIOREGS3(0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xfa, 0x00),
+ PHYREGS(0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea),
+ },
+ { .freq = 5370,
+ RADIOREGS3(0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xfa, 0x00),
+ PHYREGS(0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9),
+ },
+ { .freq = 5380,
+ RADIOREGS3(0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xfa, 0x00),
+ PHYREGS(0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8),
+ },
+ { .freq = 5390,
+ RADIOREGS3(0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0x8f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x05, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xfa, 0x00),
+ PHYREGS(0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7),
+ },
+ { .freq = 5400,
+ RADIOREGS3(0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x8f, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+ 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x08, 0x00, 0xfa, 0x00),
+ PHYREGS(0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6),
+ },
+ { .freq = 5410,
+ RADIOREGS3(0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x8f, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+ 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x08, 0x00, 0xfa, 0x00),
+ PHYREGS(0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5),
+ },
+ { .freq = 5420,
+ RADIOREGS3(0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x8e, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+ 0x00, 0xfa, 0x00, 0x8e, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x08, 0x00, 0xfa, 0x00),
+ PHYREGS(0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5),
+ },
+ { .freq = 5430,
+ RADIOREGS3(0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x8e, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+ 0x00, 0xfa, 0x00, 0x8e, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x08, 0x00, 0xfa, 0x00),
+ PHYREGS(0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4),
+ },
+ { .freq = 5440,
+ RADIOREGS3(0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x7e, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+ 0x00, 0xfa, 0x00, 0x7e, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x08, 0x00, 0xfa, 0x00),
+ PHYREGS(0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3),
+ },
+ { .freq = 5450,
+ RADIOREGS3(0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x7d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+ 0x00, 0xfa, 0x00, 0x7d, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x08, 0x00, 0xfa, 0x00),
+ PHYREGS(0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2),
+ },
+ { .freq = 5460,
+ RADIOREGS3(0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x6d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+ 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x08, 0x00, 0xf8, 0x00),
+ PHYREGS(0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1),
+ },
+ { .freq = 5470,
+ RADIOREGS3(0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x6d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+ 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x08, 0x00, 0xf8, 0x00),
+ PHYREGS(0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0),
+ },
+ { .freq = 5480,
+ RADIOREGS3(0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x5d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+ 0x00, 0xf8, 0x00, 0x5d, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x08, 0x00, 0xf8, 0x00),
+ PHYREGS(0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df),
+ },
+ { .freq = 5490,
+ RADIOREGS3(0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x5c, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+ 0x00, 0xf8, 0x00, 0x5c, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x08, 0x00, 0xf8, 0x00),
+ PHYREGS(0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de),
+ },
+ { .freq = 5500,
+ RADIOREGS3(0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x5c, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x5c, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00),
+ PHYREGS(0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd),
+ },
+ { .freq = 5510,
+ RADIOREGS3(0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x4c, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x4c, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00),
+ PHYREGS(0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd),
+ },
+ { .freq = 5520,
+ RADIOREGS3(0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x4c, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x4c, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00),
+ PHYREGS(0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc),
+ },
+ { .freq = 5530,
+ RADIOREGS3(0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x3b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x3b, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00),
+ PHYREGS(0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db),
+ },
+ { .freq = 5540,
+ RADIOREGS3(0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x3b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x3b, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00),
+ PHYREGS(0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da),
+ },
+ { .freq = 5550,
+ RADIOREGS3(0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x3b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x3b, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00),
+ PHYREGS(0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9),
+ },
+ { .freq = 5560,
+ RADIOREGS3(0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x2b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x2b, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00),
+ PHYREGS(0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8),
+ },
+ { .freq = 5570,
+ RADIOREGS3(0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x2a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x2a, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00),
+ PHYREGS(0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7),
+ },
+ { .freq = 5580,
+ RADIOREGS3(0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x1a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x1a, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00),
+ PHYREGS(0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7),
+ },
+ { .freq = 5590,
+ RADIOREGS3(0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x1a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x1a, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00),
+ PHYREGS(0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6),
+ },
+ { .freq = 5600,
+ RADIOREGS3(0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x1a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x1a, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00),
+ PHYREGS(0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5),
+ },
+ { .freq = 5610,
+ RADIOREGS3(0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x19, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x19, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00),
+ PHYREGS(0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4),
+ },
+ { .freq = 5620,
+ RADIOREGS3(0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x19, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x19, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00),
+ PHYREGS(0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3),
+ },
+ { .freq = 5630,
+ RADIOREGS3(0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x09, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x09, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00),
+ PHYREGS(0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2),
+ },
+ { .freq = 5640,
+ RADIOREGS3(0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x09, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x09, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00),
+ PHYREGS(0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2),
+ },
+ { .freq = 5650,
+ RADIOREGS3(0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00),
+ PHYREGS(0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1),
+ },
+ { .freq = 5660,
+ RADIOREGS3(0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf6, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf6, 0x00),
+ PHYREGS(0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0),
+ },
+ { .freq = 5670,
+ RADIOREGS3(0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf6, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf6, 0x00),
+ PHYREGS(0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf),
+ },
+ { .freq = 5680,
+ RADIOREGS3(0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf6, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf6, 0x00),
+ PHYREGS(0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce),
+ },
+ { .freq = 5690,
+ RADIOREGS3(0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf6, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf6, 0x00),
+ PHYREGS(0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce),
+ },
+ { .freq = 5700,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x07, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf6, 0x00, 0x07, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf6, 0x00),
+ PHYREGS(0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd),
+ },
+ { .freq = 5710,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x07, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x07, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc),
+ },
+ { .freq = 5720,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x07, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x07, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb),
+ },
+ { .freq = 5725,
+ RADIOREGS3(0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb),
+ },
+ { .freq = 5730,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca),
+ },
+ { .freq = 5735,
+ RADIOREGS3(0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca),
+ },
+ { .freq = 5740,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9),
+ },
+ { .freq = 5745,
+ RADIOREGS3(0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9),
+ },
+ { .freq = 5750,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9),
+ },
+ { .freq = 5755,
+ RADIOREGS3(0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8),
+ },
+ { .freq = 5760,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8),
+ },
+ { .freq = 5765,
+ RADIOREGS3(0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8),
+ },
+ { .freq = 5770,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7),
+ },
+ { .freq = 5775,
+ RADIOREGS3(0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7),
+ },
+ { .freq = 5780,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6),
+ },
+ { .freq = 5785,
+ RADIOREGS3(0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00,
+ 0x40, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6),
+ },
+ { .freq = 5790,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00,
+ 0x40, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6),
+ },
+ { .freq = 5795,
+ RADIOREGS3(0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00,
+ 0x40, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5),
+ },
+ { .freq = 5800,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5),
+ },
+ { .freq = 5805,
+ RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4),
+ },
+ { .freq = 5810,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4),
+ },
+ { .freq = 5815,
+ RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4),
+ },
+ { .freq = 5820,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3),
+ },
+ { .freq = 5825,
+ RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3),
+ },
+ { .freq = 5830,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2),
+ },
+ { .freq = 5840,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2),
+ },
+ { .freq = 5850,
+ RADIOREGS3(0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00),
+ PHYREGS(0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1),
+ },
+ { .freq = 5860,
+ RADIOREGS3(0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf2, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf2, 0x00),
+ PHYREGS(0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0),
+ },
+ { .freq = 5870,
+ RADIOREGS3(0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf2, 0x00),
+ PHYREGS(0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf),
+ },
+ { .freq = 5880,
+ RADIOREGS3(0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf2, 0x00),
+ PHYREGS(0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf),
+ },
+ { .freq = 5890,
+ RADIOREGS3(0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf2, 0x00),
+ PHYREGS(0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be),
+ },
+ { .freq = 5900,
+ RADIOREGS3(0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x87, 0x03, 0x00,
+ 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x05,
+ 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x05, 0x00, 0xf2, 0x00),
+ PHYREGS(0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd),
+ },
+ { .freq = 5910,
+ RADIOREGS3(0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x87, 0x03, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x05,
+ 0x00, 0xf2, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x05, 0x00, 0xf2, 0x00),
+ PHYREGS(0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc),
+ },
+ { .freq = 2412,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xff, 0x00, 0x05, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x05, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0f),
+ PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443),
+ },
+ { .freq = 2417,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xff, 0x00, 0x05, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x05, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0f),
+ PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441),
+ },
+ { .freq = 2422,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xff, 0x00, 0x05, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x05, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0f),
+ PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f),
+ },
+ { .freq = 2427,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xfd, 0x00, 0x05, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0f, 0x00, 0xfd, 0x00, 0x05, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0f),
+ PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d),
+ },
+ { .freq = 2432,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xfb, 0x00, 0x05, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0f, 0x00, 0xfb, 0x00, 0x05, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0f),
+ PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a),
+ },
+ { .freq = 2437,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xfa, 0x00, 0x05, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x05, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0f),
+ PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438),
+ },
+ { .freq = 2442,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xf8, 0x00, 0x05, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x05, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0f),
+ PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436),
+ },
+ { .freq = 2447,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xf7, 0x00, 0x05, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0f, 0x00, 0xf7, 0x00, 0x05, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0f),
+ PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434),
+ },
+ { .freq = 2452,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xf6, 0x00, 0x05, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0f, 0x00, 0xf6, 0x00, 0x05, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0f),
+ PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431),
+ },
+ { .freq = 2457,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xf5, 0x00, 0x05, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0d, 0x00, 0xf5, 0x00, 0x05, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0d),
+ PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f),
+ },
+ { .freq = 2462,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0d, 0x00, 0xf4, 0x00, 0x05, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0d),
+ PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d),
+ },
+ { .freq = 2467,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xf3, 0x00, 0x05, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0d, 0x00, 0xf3, 0x00, 0x05, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0d),
+ PHYREGS(0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b),
+ },
+ { .freq = 2472,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0d, 0x00, 0xf2, 0x00, 0x05, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0d),
+ PHYREGS(0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429),
+ },
+ { .freq = 2484,
+ RADIOREGS3(0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xf0, 0x00, 0x05, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0d, 0x00, 0xf0, 0x00, 0x05, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0d),
+ PHYREGS(0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424),
+ },
+};
+
+static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev4[] = {
+ { .freq = 4920,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00),
+ PHYREGS(0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216),
+ },
+ { .freq = 4930,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00),
+ PHYREGS(0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215),
+ },
+ { .freq = 4940,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00),
+ PHYREGS(0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214),
+ },
+ { .freq = 4950,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00),
+ PHYREGS(0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213),
+ },
+ { .freq = 4960,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00),
+ PHYREGS(0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212),
+ },
+ { .freq = 4970,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00),
+ PHYREGS(0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211),
+ },
+ { .freq = 4980,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00),
+ PHYREGS(0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f),
+ },
+ { .freq = 4990,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00),
+ PHYREGS(0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e),
+ },
+ { .freq = 5000,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00),
+ PHYREGS(0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d),
+ },
+ { .freq = 5010,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00),
+ PHYREGS(0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c),
+ },
+ { .freq = 5020,
+ RADIOREGS3(0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00),
+ PHYREGS(0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b),
+ },
+ { .freq = 5030,
+ RADIOREGS3(0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00),
+ PHYREGS(0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a),
+ },
+ { .freq = 5040,
+ RADIOREGS3(0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00),
+ PHYREGS(0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209),
+ },
+ { .freq = 5050,
+ RADIOREGS3(0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00),
+ PHYREGS(0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208),
+ },
+ { .freq = 5060,
+ RADIOREGS3(0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00),
+ PHYREGS(0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207),
+ },
+ { .freq = 5070,
+ RADIOREGS3(0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00),
+ PHYREGS(0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206),
+ },
+ { .freq = 5080,
+ RADIOREGS3(0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00),
+ PHYREGS(0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205),
+ },
+ { .freq = 5090,
+ RADIOREGS3(0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00),
+ PHYREGS(0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204),
+ },
+ { .freq = 5100,
+ RADIOREGS3(0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfe, 0x00),
+ PHYREGS(0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203),
+ },
+ { .freq = 5110,
+ RADIOREGS3(0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfe, 0x00),
+ PHYREGS(0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202),
+ },
+ { .freq = 5120,
+ RADIOREGS3(0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfe, 0x00),
+ PHYREGS(0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201),
+ },
+ { .freq = 5130,
+ RADIOREGS3(0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfe, 0x00),
+ PHYREGS(0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200),
+ },
+ { .freq = 5140,
+ RADIOREGS3(0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfe, 0x00),
+ PHYREGS(0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff),
+ },
+ { .freq = 5160,
+ RADIOREGS3(0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfe, 0x00),
+ PHYREGS(0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd),
+ },
+ { .freq = 5170,
+ RADIOREGS3(0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfe, 0x00),
+ PHYREGS(0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc),
+ },
+ { .freq = 5180,
+ RADIOREGS3(0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xef, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfe, 0x00, 0xef, 0x00, 0x0c, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfe, 0x00),
+ PHYREGS(0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb),
+ },
+ { .freq = 5190,
+ RADIOREGS3(0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xef, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfe, 0x00, 0xef, 0x00, 0x0c, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfe, 0x00),
+ PHYREGS(0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa),
+ },
+ { .freq = 5200,
+ RADIOREGS3(0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xef, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfc, 0x00, 0xef, 0x00, 0x0a, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfc, 0x00),
+ PHYREGS(0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9),
+ },
+ { .freq = 5210,
+ RADIOREGS3(0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xdf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x0a, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfc, 0x00),
+ PHYREGS(0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8),
+ },
+ { .freq = 5220,
+ RADIOREGS3(0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xdf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x0a, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfc, 0x00),
+ PHYREGS(0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7),
+ },
+ { .freq = 5230,
+ RADIOREGS3(0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xdf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x0a, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfc, 0x00),
+ PHYREGS(0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6),
+ },
+ { .freq = 5240,
+ RADIOREGS3(0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfc, 0x00),
+ PHYREGS(0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5),
+ },
+ { .freq = 5250,
+ RADIOREGS3(0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfc, 0x00),
+ PHYREGS(0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4),
+ },
+ { .freq = 5260,
+ RADIOREGS3(0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfc, 0x00),
+ PHYREGS(0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3),
+ },
+ { .freq = 5270,
+ RADIOREGS3(0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00,
+ 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfc, 0x00),
+ PHYREGS(0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2),
+ },
+ { .freq = 5280,
+ RADIOREGS3(0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00,
+ 0xff, 0xbf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x0a, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfc, 0x00),
+ PHYREGS(0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1),
+ },
+ { .freq = 5290,
+ RADIOREGS3(0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00,
+ 0xff, 0xbf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x0a, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfc, 0x00),
+ PHYREGS(0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0),
+ },
+ { .freq = 5300,
+ RADIOREGS3(0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0xbf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfa, 0x00),
+ PHYREGS(0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0),
+ },
+ { .freq = 5310,
+ RADIOREGS3(0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0xbf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfa, 0x00),
+ PHYREGS(0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef),
+ },
+ { .freq = 5320,
+ RADIOREGS3(0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0xbf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfa, 0x00),
+ PHYREGS(0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee),
+ },
+ { .freq = 5330,
+ RADIOREGS3(0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0xaf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfa, 0x00),
+ PHYREGS(0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed),
+ },
+ { .freq = 5340,
+ RADIOREGS3(0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0xaf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfa, 0x00),
+ PHYREGS(0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec),
+ },
+ { .freq = 5350,
+ RADIOREGS3(0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfa, 0x00),
+ PHYREGS(0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb),
+ },
+ { .freq = 5360,
+ RADIOREGS3(0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfa, 0x00),
+ PHYREGS(0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea),
+ },
+ { .freq = 5370,
+ RADIOREGS3(0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfa, 0x00),
+ PHYREGS(0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9),
+ },
+ { .freq = 5380,
+ RADIOREGS3(0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfa, 0x00),
+ PHYREGS(0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8),
+ },
+ { .freq = 5390,
+ RADIOREGS3(0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0x8f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfa, 0x00),
+ PHYREGS(0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7),
+ },
+ { .freq = 5400,
+ RADIOREGS3(0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x8f, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xf8, 0x00, 0x8f, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xf8, 0x00),
+ PHYREGS(0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6),
+ },
+ { .freq = 5410,
+ RADIOREGS3(0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x8f, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xf8, 0x00, 0x8f, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xf8, 0x00),
+ PHYREGS(0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5),
+ },
+ { .freq = 5420,
+ RADIOREGS3(0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x8e, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xf8, 0x00, 0x8e, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xf8, 0x00),
+ PHYREGS(0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5),
+ },
+ { .freq = 5430,
+ RADIOREGS3(0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x8e, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xf8, 0x00, 0x8e, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xf8, 0x00),
+ PHYREGS(0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4),
+ },
+ { .freq = 5440,
+ RADIOREGS3(0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x7e, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xf8, 0x00, 0x7e, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xf8, 0x00),
+ PHYREGS(0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3),
+ },
+ { .freq = 5450,
+ RADIOREGS3(0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x7d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xf8, 0x00, 0x7d, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xf8, 0x00),
+ PHYREGS(0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2),
+ },
+ { .freq = 5460,
+ RADIOREGS3(0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x6d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xf8, 0x00),
+ PHYREGS(0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1),
+ },
+ { .freq = 5470,
+ RADIOREGS3(0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x6d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xf8, 0x00),
+ PHYREGS(0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0),
+ },
+ { .freq = 5480,
+ RADIOREGS3(0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x5d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xf8, 0x00, 0x5d, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xf8, 0x00),
+ PHYREGS(0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df),
+ },
+ { .freq = 5490,
+ RADIOREGS3(0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x5c, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xf8, 0x00, 0x5c, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xf8, 0x00),
+ PHYREGS(0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de),
+ },
+ { .freq = 5500,
+ RADIOREGS3(0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x5c, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+ 0x00, 0xf6, 0x00, 0x5c, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0d, 0x00, 0xf6, 0x00),
+ PHYREGS(0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd),
+ },
+ { .freq = 5510,
+ RADIOREGS3(0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x4c, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+ 0x00, 0xf6, 0x00, 0x4c, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0d, 0x00, 0xf6, 0x00),
+ PHYREGS(0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd),
+ },
+ { .freq = 5520,
+ RADIOREGS3(0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x4c, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+ 0x00, 0xf6, 0x00, 0x4c, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0d, 0x00, 0xf6, 0x00),
+ PHYREGS(0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc),
+ },
+ { .freq = 5530,
+ RADIOREGS3(0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x3b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+ 0x00, 0xf6, 0x00, 0x3b, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0d, 0x00, 0xf6, 0x00),
+ PHYREGS(0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db),
+ },
+ { .freq = 5540,
+ RADIOREGS3(0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x3b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+ 0x00, 0xf6, 0x00, 0x3b, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0d, 0x00, 0xf6, 0x00),
+ PHYREGS(0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da),
+ },
+ { .freq = 5550,
+ RADIOREGS3(0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x3b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+ 0x00, 0xf6, 0x00, 0x3b, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0d, 0x00, 0xf6, 0x00),
+ PHYREGS(0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9),
+ },
+ { .freq = 5560,
+ RADIOREGS3(0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x2b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+ 0x00, 0xf6, 0x00, 0x2b, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0d, 0x00, 0xf6, 0x00),
+ PHYREGS(0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8),
+ },
+ { .freq = 5570,
+ RADIOREGS3(0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x2a, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+ 0x00, 0xf6, 0x00, 0x2a, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0d, 0x00, 0xf6, 0x00),
+ PHYREGS(0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7),
+ },
+ { .freq = 5580,
+ RADIOREGS3(0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x1a, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+ 0x00, 0xf6, 0x00, 0x1a, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0d, 0x00, 0xf6, 0x00),
+ PHYREGS(0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7),
+ },
+ { .freq = 5590,
+ RADIOREGS3(0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x1a, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+ 0x00, 0xf6, 0x00, 0x1a, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0d, 0x00, 0xf6, 0x00),
+ PHYREGS(0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6),
+ },
+ { .freq = 5600,
+ RADIOREGS3(0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x1a, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xf4, 0x00, 0x1a, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xf4, 0x00),
+ PHYREGS(0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5),
+ },
+ { .freq = 5610,
+ RADIOREGS3(0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x19, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xf4, 0x00, 0x19, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xf4, 0x00),
+ PHYREGS(0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4),
+ },
+ { .freq = 5620,
+ RADIOREGS3(0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x19, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xf4, 0x00, 0x19, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xf4, 0x00),
+ PHYREGS(0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3),
+ },
+ { .freq = 5630,
+ RADIOREGS3(0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x09, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xf4, 0x00, 0x09, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xf4, 0x00),
+ PHYREGS(0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2),
+ },
+ { .freq = 5640,
+ RADIOREGS3(0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x09, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xf4, 0x00, 0x09, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xf4, 0x00),
+ PHYREGS(0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2),
+ },
+ { .freq = 5650,
+ RADIOREGS3(0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xf4, 0x00),
+ PHYREGS(0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1),
+ },
+ { .freq = 5660,
+ RADIOREGS3(0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xf4, 0x00),
+ PHYREGS(0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0),
+ },
+ { .freq = 5670,
+ RADIOREGS3(0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xf4, 0x00),
+ PHYREGS(0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf),
+ },
+ { .freq = 5680,
+ RADIOREGS3(0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xf4, 0x00),
+ PHYREGS(0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce),
+ },
+ { .freq = 5690,
+ RADIOREGS3(0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x07, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xf4, 0x00, 0x07, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xf4, 0x00),
+ PHYREGS(0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce),
+ },
+ { .freq = 5700,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00),
+ PHYREGS(0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd),
+ },
+ { .freq = 5710,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00),
+ PHYREGS(0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc),
+ },
+ { .freq = 5720,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00),
+ PHYREGS(0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb),
+ },
+ { .freq = 5725,
+ RADIOREGS3(0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00),
+ PHYREGS(0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb),
+ },
+ { .freq = 5730,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00),
+ PHYREGS(0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca),
+ },
+ { .freq = 5735,
+ RADIOREGS3(0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00),
+ PHYREGS(0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca),
+ },
+ { .freq = 5740,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00),
+ PHYREGS(0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9),
+ },
+ { .freq = 5745,
+ RADIOREGS3(0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00),
+ PHYREGS(0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9),
+ },
+ { .freq = 5750,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00),
+ PHYREGS(0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9),
+ },
+ { .freq = 5755,
+ RADIOREGS3(0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00),
+ PHYREGS(0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8),
+ },
+ { .freq = 5760,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00),
+ PHYREGS(0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8),
+ },
+ { .freq = 5765,
+ RADIOREGS3(0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00),
+ PHYREGS(0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8),
+ },
+ { .freq = 5770,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00),
+ PHYREGS(0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7),
+ },
+ { .freq = 5775,
+ RADIOREGS3(0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00),
+ PHYREGS(0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7),
+ },
+ { .freq = 5780,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00),
+ PHYREGS(0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6),
+ },
+ { .freq = 5785,
+ RADIOREGS3(0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00,
+ 0x40, 0x04, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x04, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00),
+ PHYREGS(0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6),
+ },
+ { .freq = 5790,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00,
+ 0x40, 0x04, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x04, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00),
+ PHYREGS(0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6),
+ },
+ { .freq = 5795,
+ RADIOREGS3(0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00,
+ 0x40, 0x04, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x04, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00),
+ PHYREGS(0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5),
+ },
+ { .freq = 5800,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xf0, 0x00),
+ PHYREGS(0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5),
+ },
+ { .freq = 5805,
+ RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xf0, 0x00),
+ PHYREGS(0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4),
+ },
+ { .freq = 5810,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xf0, 0x00),
+ PHYREGS(0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4),
+ },
+ { .freq = 5815,
+ RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xf0, 0x00),
+ PHYREGS(0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4),
+ },
+ { .freq = 5820,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xf0, 0x00),
+ PHYREGS(0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3),
+ },
+ { .freq = 5825,
+ RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xf0, 0x00),
+ PHYREGS(0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3),
+ },
+ { .freq = 5830,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xf0, 0x00),
+ PHYREGS(0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2),
+ },
+ { .freq = 5840,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xf0, 0x00),
+ PHYREGS(0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2),
+ },
+ { .freq = 5850,
+ RADIOREGS3(0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xf0, 0x00),
+ PHYREGS(0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1),
+ },
+ { .freq = 5860,
+ RADIOREGS3(0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xf0, 0x00),
+ PHYREGS(0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0),
+ },
+ { .freq = 5870,
+ RADIOREGS3(0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x02, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xf0, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xf0, 0x00),
+ PHYREGS(0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf),
+ },
+ { .freq = 5880,
+ RADIOREGS3(0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x02, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xf0, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xf0, 0x00),
+ PHYREGS(0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf),
+ },
+ { .freq = 5890,
+ RADIOREGS3(0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x02, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xf0, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xf0, 0x00),
+ PHYREGS(0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be),
+ },
+ { .freq = 5900,
+ RADIOREGS3(0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x87, 0x03, 0x00,
+ 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf0, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf0, 0x00),
+ PHYREGS(0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd),
+ },
+ { .freq = 5910,
+ RADIOREGS3(0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x87, 0x03, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf0, 0x00),
+ PHYREGS(0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc),
+ },
+ { .freq = 2412,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xff, 0x00, 0x04, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0e, 0x00, 0xff, 0x00, 0x04, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0e),
+ PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443),
+ },
+ { .freq = 2417,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xff, 0x00, 0x04, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0e, 0x00, 0xff, 0x00, 0x04, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0e),
+ PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441),
+ },
+ { .freq = 2422,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xff, 0x00, 0x04, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0e, 0x00, 0xff, 0x00, 0x04, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0e),
+ PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f),
+ },
+ { .freq = 2427,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xfd, 0x00, 0x04, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0e, 0x00, 0xfd, 0x00, 0x04, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0e),
+ PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d),
+ },
+ { .freq = 2432,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xfb, 0x00, 0x04, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0e, 0x00, 0xfb, 0x00, 0x04, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0e),
+ PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a),
+ },
+ { .freq = 2437,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0e, 0x00, 0xfa, 0x00, 0x04, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0e),
+ PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438),
+ },
+ { .freq = 2442,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xf8, 0x00, 0x04, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0e, 0x00, 0xf8, 0x00, 0x04, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0e),
+ PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436),
+ },
+ { .freq = 2447,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xf7, 0x00, 0x04, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0e, 0x00, 0xf7, 0x00, 0x04, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0e),
+ PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434),
+ },
+ { .freq = 2452,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xf6, 0x00, 0x04, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0e, 0x00, 0xf6, 0x00, 0x04, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0e),
+ PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431),
+ },
+ { .freq = 2457,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xf5, 0x00, 0x04, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0e, 0x00, 0xf5, 0x00, 0x04, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0e),
+ PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f),
+ },
+ { .freq = 2462,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0e, 0x00, 0xf4, 0x00, 0x04, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0e),
+ PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d),
+ },
+ { .freq = 2467,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xf3, 0x00, 0x04, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0e, 0x00, 0xf3, 0x00, 0x04, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0e),
+ PHYREGS(0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b),
+ },
+ { .freq = 2472,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xf2, 0x00, 0x04, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0e, 0x00, 0xf2, 0x00, 0x04, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0e),
+ PHYREGS(0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429),
+ },
+ { .freq = 2484,
+ RADIOREGS3(0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0e, 0x00, 0xf0, 0x00, 0x04, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0e),
+ PHYREGS(0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424),
+ },
+};
+
+static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev5[] = {
+ { .freq = 4920,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0f,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216),
+ },
+ { .freq = 4930,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70,
+ 0x00, 0x0e, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215),
+ },
+ { .freq = 4940,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70,
+ 0x00, 0x0e, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214),
+ },
+ { .freq = 4950,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70,
+ 0x00, 0x0e, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213),
+ },
+ { .freq = 4960,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0e,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70,
+ 0x00, 0x0e, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212),
+ },
+ { .freq = 4970,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211),
+ },
+ { .freq = 4980,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f),
+ },
+ { .freq = 4990,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e),
+ },
+ { .freq = 5000,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d),
+ },
+ { .freq = 5010,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c),
+ },
+ { .freq = 5020,
+ RADIOREGS3(0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0d,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b),
+ },
+ { .freq = 5030,
+ RADIOREGS3(0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a),
+ },
+ { .freq = 5040,
+ RADIOREGS3(0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
+ 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209),
+ },
+ { .freq = 5050,
+ RADIOREGS3(0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
+ 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208),
+ },
+ { .freq = 5060,
+ RADIOREGS3(0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfd, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
+ 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x70,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207),
+ },
+ { .freq = 5070,
+ RADIOREGS3(0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfd, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+ 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x70,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206),
+ },
+ { .freq = 5080,
+ RADIOREGS3(0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+ 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205),
+ },
+ { .freq = 5090,
+ RADIOREGS3(0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+ 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204),
+ },
+ { .freq = 5100,
+ RADIOREGS3(0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+ 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203),
+ },
+ { .freq = 5110,
+ RADIOREGS3(0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+ 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202),
+ },
+ { .freq = 5120,
+ RADIOREGS3(0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+ 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201),
+ },
+ { .freq = 5130,
+ RADIOREGS3(0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfb, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0a,
+ 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x70,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200),
+ },
+ { .freq = 5140,
+ RADIOREGS3(0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x0a,
+ 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00),
+ PHYREGS(0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff),
+ },
+ { .freq = 5160,
+ RADIOREGS3(0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x09,
+ 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70,
+ 0x00, 0x09, 0x00, 0x6e, 0x00),
+ PHYREGS(0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd),
+ },
+ { .freq = 5170,
+ RADIOREGS3(0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfb, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+ 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x06, 0x00, 0x70,
+ 0x00, 0x09, 0x00, 0x6e, 0x00),
+ PHYREGS(0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc),
+ },
+ { .freq = 5180,
+ RADIOREGS3(0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+ 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70,
+ 0x00, 0x09, 0x00, 0x6e, 0x00),
+ PHYREGS(0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb),
+ },
+ { .freq = 5190,
+ RADIOREGS3(0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+ 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70,
+ 0x00, 0x09, 0x00, 0x6e, 0x00),
+ PHYREGS(0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa),
+ },
+ { .freq = 5200,
+ RADIOREGS3(0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+ 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70,
+ 0x00, 0x09, 0x00, 0x6e, 0x00),
+ PHYREGS(0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9),
+ },
+ { .freq = 5210,
+ RADIOREGS3(0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+ 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70,
+ 0x00, 0x09, 0x00, 0x6e, 0x00),
+ PHYREGS(0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8),
+ },
+ { .freq = 5220,
+ RADIOREGS3(0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+ 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70,
+ 0x00, 0x09, 0x00, 0x6e, 0x00),
+ PHYREGS(0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7),
+ },
+ { .freq = 5230,
+ RADIOREGS3(0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xea, 0x00, 0x06, 0x00, 0x70, 0x00, 0x08,
+ 0x00, 0x9e, 0x00, 0xea, 0x00, 0x06, 0x00, 0x70,
+ 0x00, 0x08, 0x00, 0x6e, 0x00),
+ PHYREGS(0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6),
+ },
+ { .freq = 5240,
+ RADIOREGS3(0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
+ 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70,
+ 0x00, 0x08, 0x00, 0x6d, 0x00),
+ PHYREGS(0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5),
+ },
+ { .freq = 5250,
+ RADIOREGS3(0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
+ 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70,
+ 0x00, 0x08, 0x00, 0x6d, 0x00),
+ PHYREGS(0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4),
+ },
+ { .freq = 5260,
+ RADIOREGS3(0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xd9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
+ 0x00, 0x9d, 0x00, 0xd9, 0x00, 0x05, 0x00, 0x70,
+ 0x00, 0x08, 0x00, 0x6d, 0x00),
+ PHYREGS(0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3),
+ },
+ { .freq = 5270,
+ RADIOREGS3(0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00,
+ 0xff, 0xd8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x9c, 0x00, 0xd8, 0x00, 0x04, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x6c, 0x00),
+ PHYREGS(0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2),
+ },
+ { .freq = 5280,
+ RADIOREGS3(0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00,
+ 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x6c, 0x00),
+ PHYREGS(0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1),
+ },
+ { .freq = 5290,
+ RADIOREGS3(0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00,
+ 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x6c, 0x00),
+ PHYREGS(0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0),
+ },
+ { .freq = 5300,
+ RADIOREGS3(0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x6c, 0x00),
+ PHYREGS(0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0),
+ },
+ { .freq = 5310,
+ RADIOREGS3(0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x6c, 0x00),
+ PHYREGS(0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef),
+ },
+ { .freq = 5320,
+ RADIOREGS3(0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0xb8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x9c, 0x00, 0xb8, 0x00, 0x04, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x6c, 0x00),
+ PHYREGS(0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee),
+ },
+ { .freq = 5330,
+ RADIOREGS3(0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0xb7, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x04, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x6b, 0x00),
+ PHYREGS(0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed),
+ },
+ { .freq = 5340,
+ RADIOREGS3(0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0xb7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x6b, 0x00),
+ PHYREGS(0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec),
+ },
+ { .freq = 5350,
+ RADIOREGS3(0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0xa7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+ 0x00, 0x9b, 0x00, 0xa7, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x06, 0x00, 0x6b, 0x00),
+ PHYREGS(0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb),
+ },
+ { .freq = 5360,
+ RADIOREGS3(0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+ 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x06, 0x00, 0x6b, 0x00),
+ PHYREGS(0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea),
+ },
+ { .freq = 5370,
+ RADIOREGS3(0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+ 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x06, 0x00, 0x5b, 0x00),
+ PHYREGS(0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9),
+ },
+ { .freq = 5380,
+ RADIOREGS3(0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0x96, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+ 0x00, 0x9a, 0x00, 0x96, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x06, 0x00, 0x5a, 0x00),
+ PHYREGS(0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8),
+ },
+ { .freq = 5390,
+ RADIOREGS3(0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00,
+ 0xff, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+ 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x06, 0x00, 0x5a, 0x00),
+ PHYREGS(0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7),
+ },
+ { .freq = 5400,
+ RADIOREGS3(0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+ 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x06, 0x00, 0x5a, 0x00),
+ PHYREGS(0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6),
+ },
+ { .freq = 5410,
+ RADIOREGS3(0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05,
+ 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x05, 0x00, 0x5a, 0x00),
+ PHYREGS(0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5),
+ },
+ { .freq = 5420,
+ RADIOREGS3(0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05,
+ 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x05, 0x00, 0x5a, 0x00),
+ PHYREGS(0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5),
+ },
+ { .freq = 5430,
+ RADIOREGS3(0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x85, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
+ 0x00, 0x99, 0x00, 0x85, 0x00, 0x02, 0x00, 0x70,
+ 0x00, 0x05, 0x00, 0x59, 0x00),
+ PHYREGS(0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4),
+ },
+ { .freq = 5440,
+ RADIOREGS3(0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
+ 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70,
+ 0x00, 0x05, 0x00, 0x59, 0x00),
+ PHYREGS(0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3),
+ },
+ { .freq = 5450,
+ RADIOREGS3(0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
+ 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70,
+ 0x00, 0x05, 0x00, 0x59, 0x00),
+ PHYREGS(0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2),
+ },
+ { .freq = 5460,
+ RADIOREGS3(0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x04,
+ 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70,
+ 0x00, 0x04, 0x00, 0x69, 0x00),
+ PHYREGS(0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1),
+ },
+ { .freq = 5470,
+ RADIOREGS3(0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x74, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+ 0x00, 0x99, 0x00, 0x74, 0x00, 0x01, 0x00, 0x70,
+ 0x00, 0x04, 0x00, 0x69, 0x00),
+ PHYREGS(0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0),
+ },
+ { .freq = 5480,
+ RADIOREGS3(0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+ 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70,
+ 0x00, 0x04, 0x00, 0x68, 0x00),
+ PHYREGS(0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df),
+ },
+ { .freq = 5490,
+ RADIOREGS3(0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00,
+ 0xc8, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+ 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70,
+ 0x00, 0x04, 0x00, 0x68, 0x00),
+ PHYREGS(0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de),
+ },
+ { .freq = 5500,
+ RADIOREGS3(0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+ 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70,
+ 0x00, 0x04, 0x00, 0x78, 0x00),
+ PHYREGS(0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd),
+ },
+ { .freq = 5510,
+ RADIOREGS3(0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+ 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70,
+ 0x00, 0x04, 0x00, 0x78, 0x00),
+ PHYREGS(0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd),
+ },
+ { .freq = 5520,
+ RADIOREGS3(0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+ 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70,
+ 0x00, 0x04, 0x00, 0x78, 0x00),
+ PHYREGS(0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc),
+ },
+ { .freq = 5530,
+ RADIOREGS3(0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x63, 0x00, 0x01, 0x00, 0x70, 0x00, 0x03,
+ 0x00, 0x98, 0x00, 0x63, 0x00, 0x01, 0x00, 0x70,
+ 0x00, 0x03, 0x00, 0x78, 0x00),
+ PHYREGS(0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db),
+ },
+ { .freq = 5540,
+ RADIOREGS3(0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
+ 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x03, 0x00, 0x77, 0x00),
+ PHYREGS(0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da),
+ },
+ { .freq = 5550,
+ RADIOREGS3(0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
+ 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x03, 0x00, 0x77, 0x00),
+ PHYREGS(0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9),
+ },
+ { .freq = 5560,
+ RADIOREGS3(0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
+ 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x03, 0x00, 0x77, 0x00),
+ PHYREGS(0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8),
+ },
+ { .freq = 5570,
+ RADIOREGS3(0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x76, 0x00),
+ PHYREGS(0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7),
+ },
+ { .freq = 5580,
+ RADIOREGS3(0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x76, 0x00),
+ PHYREGS(0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7),
+ },
+ { .freq = 5590,
+ RADIOREGS3(0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00,
+ 0x84, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x76, 0x00),
+ PHYREGS(0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6),
+ },
+ { .freq = 5600,
+ RADIOREGS3(0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x76, 0x00),
+ PHYREGS(0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5),
+ },
+ { .freq = 5610,
+ RADIOREGS3(0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x76, 0x00),
+ PHYREGS(0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4),
+ },
+ { .freq = 5620,
+ RADIOREGS3(0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x76, 0x00),
+ PHYREGS(0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3),
+ },
+ { .freq = 5630,
+ RADIOREGS3(0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x76, 0x00),
+ PHYREGS(0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2),
+ },
+ { .freq = 5640,
+ RADIOREGS3(0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x95, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x75, 0x00),
+ PHYREGS(0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2),
+ },
+ { .freq = 5650,
+ RADIOREGS3(0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x75, 0x00),
+ PHYREGS(0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1),
+ },
+ { .freq = 5660,
+ RADIOREGS3(0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x75, 0x00),
+ PHYREGS(0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0),
+ },
+ { .freq = 5670,
+ RADIOREGS3(0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x74, 0x00),
+ PHYREGS(0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf),
+ },
+ { .freq = 5680,
+ RADIOREGS3(0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x74, 0x00),
+ PHYREGS(0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce),
+ },
+ { .freq = 5690,
+ RADIOREGS3(0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00,
+ 0x70, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x74, 0x00),
+ PHYREGS(0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce),
+ },
+ { .freq = 5700,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x74, 0x00),
+ PHYREGS(0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd),
+ },
+ { .freq = 5710,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x74, 0x00),
+ PHYREGS(0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc),
+ },
+ { .freq = 5720,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x74, 0x00),
+ PHYREGS(0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb),
+ },
+ { .freq = 5725,
+ RADIOREGS3(0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x74, 0x00),
+ PHYREGS(0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb),
+ },
+ { .freq = 5730,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x94, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x84, 0x00),
+ PHYREGS(0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca),
+ },
+ { .freq = 5735,
+ RADIOREGS3(0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x83, 0x00),
+ PHYREGS(0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca),
+ },
+ { .freq = 5740,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x83, 0x00),
+ PHYREGS(0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9),
+ },
+ { .freq = 5745,
+ RADIOREGS3(0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x83, 0x00),
+ PHYREGS(0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9),
+ },
+ { .freq = 5750,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x83, 0x00),
+ PHYREGS(0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9),
+ },
+ { .freq = 5755,
+ RADIOREGS3(0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x83, 0x00),
+ PHYREGS(0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8),
+ },
+ { .freq = 5760,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x93, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x83, 0x00),
+ PHYREGS(0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8),
+ },
+ { .freq = 5765,
+ RADIOREGS3(0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x82, 0x00),
+ PHYREGS(0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8),
+ },
+ { .freq = 5770,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x82, 0x00),
+ PHYREGS(0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7),
+ },
+ { .freq = 5775,
+ RADIOREGS3(0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x82, 0x00),
+ PHYREGS(0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7),
+ },
+ { .freq = 5780,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00,
+ 0x40, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x82, 0x00),
+ PHYREGS(0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6),
+ },
+ { .freq = 5785,
+ RADIOREGS3(0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00,
+ 0x40, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x82, 0x00),
+ PHYREGS(0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6),
+ },
+ { .freq = 5790,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00,
+ 0x40, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x82, 0x00),
+ PHYREGS(0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6),
+ },
+ { .freq = 5795,
+ RADIOREGS3(0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00,
+ 0x40, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x82, 0x00),
+ PHYREGS(0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5),
+ },
+ { .freq = 5800,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x82, 0x00),
+ PHYREGS(0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5),
+ },
+ { .freq = 5805,
+ RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x82, 0x00),
+ PHYREGS(0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4),
+ },
+ { .freq = 5810,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x82, 0x00),
+ PHYREGS(0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4),
+ },
+ { .freq = 5815,
+ RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x82, 0x00),
+ PHYREGS(0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4),
+ },
+ { .freq = 5820,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x82, 0x00),
+ PHYREGS(0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3),
+ },
+ { .freq = 5825,
+ RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x82, 0x00),
+ PHYREGS(0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3),
+ },
+ { .freq = 5830,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x72, 0x00),
+ PHYREGS(0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2),
+ },
+ { .freq = 5840,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x72, 0x00),
+ PHYREGS(0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2),
+ },
+ { .freq = 5850,
+ RADIOREGS3(0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x72, 0x00),
+ PHYREGS(0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1),
+ },
+ { .freq = 5860,
+ RADIOREGS3(0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x72, 0x00),
+ PHYREGS(0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0),
+ },
+ { .freq = 5870,
+ RADIOREGS3(0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x71, 0x00),
+ PHYREGS(0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf),
+ },
+ { .freq = 5880,
+ RADIOREGS3(0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x71, 0x00),
+ PHYREGS(0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf),
+ },
+ { .freq = 5890,
+ RADIOREGS3(0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x88, 0x04, 0x00,
+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x71, 0x00),
+ PHYREGS(0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be),
+ },
+ { .freq = 5900,
+ RADIOREGS3(0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x87, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x71, 0x00),
+ PHYREGS(0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd),
+ },
+ { .freq = 5910,
+ RADIOREGS3(0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x87, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x71, 0x00),
+ PHYREGS(0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc),
+ },
+ { .freq = 2412,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x1f, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0b, 0x00, 0x1f, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0b),
+ PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443),
+ },
+ { .freq = 2417,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x1f, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0a, 0x00, 0x1f, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0a),
+ PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441),
+ },
+ { .freq = 2422,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0a, 0x00, 0x0e, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0a),
+ PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f),
+ },
+ { .freq = 2427,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x0d, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0e, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0e, 0x00, 0x0a),
+ PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d),
+ },
+ { .freq = 2432,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0e, 0x00, 0x0a, 0x00, 0x0c, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0e, 0x00, 0x0a),
+ PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a),
+ },
+ { .freq = 2437,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x0b, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0e, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0e, 0x00, 0x0a),
+ PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438),
+ },
+ { .freq = 2442,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x09, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0e, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0e, 0x00, 0x0a),
+ PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436),
+ },
+ { .freq = 2447,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0e, 0x00, 0x09, 0x00, 0x08, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0e, 0x00, 0x09),
+ PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434),
+ },
+ { .freq = 2452,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x07, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0e, 0x00, 0x09, 0x00, 0x07, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0e, 0x00, 0x09),
+ PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431),
+ },
+ { .freq = 2457,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x06, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0d, 0x00, 0x09, 0x00, 0x06, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0d, 0x00, 0x09),
+ PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f),
+ },
+ { .freq = 2462,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x05, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0d, 0x00, 0x09, 0x00, 0x05, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0d, 0x00, 0x09),
+ PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d),
+ },
+ { .freq = 2467,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0d, 0x00, 0x08, 0x00, 0x04, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0d, 0x00, 0x08),
+ PHYREGS(0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b),
+ },
+ { .freq = 2472,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x03, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0d, 0x00, 0x08, 0x00, 0x03, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0d, 0x00, 0x08),
+ PHYREGS(0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429),
+ },
+ { .freq = 2484,
+ RADIOREGS3(0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0d, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0d, 0x00, 0x08),
+ PHYREGS(0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424),
+ },
+};
+
+static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev6[] = {
+ { .freq = 4920,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216),
+ },
+ { .freq = 4930,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215),
+ },
+ { .freq = 4940,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214),
+ },
+ { .freq = 4950,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213),
+ },
+ { .freq = 4960,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212),
+ },
+ { .freq = 4970,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211),
+ },
+ { .freq = 4980,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f),
+ },
+ { .freq = 4990,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e),
+ },
+ { .freq = 5000,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d),
+ },
+ { .freq = 5010,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c),
+ },
+ { .freq = 5020,
+ RADIOREGS3(0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b),
+ },
+ { .freq = 5030,
+ RADIOREGS3(0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a),
+ },
+ { .freq = 5040,
+ RADIOREGS3(0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209),
+ },
+ { .freq = 5050,
+ RADIOREGS3(0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208),
+ },
+ { .freq = 5060,
+ RADIOREGS3(0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207),
+ },
+ { .freq = 5070,
+ RADIOREGS3(0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206),
+ },
+ { .freq = 5080,
+ RADIOREGS3(0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205),
+ },
+ { .freq = 5090,
+ RADIOREGS3(0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204),
+ },
+ { .freq = 5100,
+ RADIOREGS3(0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfd, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203),
+ },
+ { .freq = 5110,
+ RADIOREGS3(0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202),
+ },
+ { .freq = 5120,
+ RADIOREGS3(0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201),
+ },
+ { .freq = 5130,
+ RADIOREGS3(0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200),
+ },
+ { .freq = 5140,
+ RADIOREGS3(0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfb, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff),
+ },
+ { .freq = 5160,
+ RADIOREGS3(0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
+ 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77,
+ 0x00, 0x0e, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd),
+ },
+ { .freq = 5170,
+ RADIOREGS3(0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
+ 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77,
+ 0x00, 0x0e, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc),
+ },
+ { .freq = 5180,
+ RADIOREGS3(0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0e,
+ 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77,
+ 0x00, 0x0e, 0x00, 0x6f, 0x00),
+ PHYREGS(0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb),
+ },
+ { .freq = 5190,
+ RADIOREGS3(0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa),
+ },
+ { .freq = 5200,
+ RADIOREGS3(0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9),
+ },
+ { .freq = 5210,
+ RADIOREGS3(0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8),
+ },
+ { .freq = 5220,
+ RADIOREGS3(0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00,
+ 0xfe, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7),
+ },
+ { .freq = 5230,
+ RADIOREGS3(0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00,
+ 0xee, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6),
+ },
+ { .freq = 5240,
+ RADIOREGS3(0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00,
+ 0xee, 0xc8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0xc8, 0x00, 0x05, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5),
+ },
+ { .freq = 5250,
+ RADIOREGS3(0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00,
+ 0xed, 0xc7, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x05, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4),
+ },
+ { .freq = 5260,
+ RADIOREGS3(0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00,
+ 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3),
+ },
+ { .freq = 5270,
+ RADIOREGS3(0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00,
+ 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2),
+ },
+ { .freq = 5280,
+ RADIOREGS3(0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00,
+ 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1),
+ },
+ { .freq = 5290,
+ RADIOREGS3(0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00,
+ 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0),
+ },
+ { .freq = 5300,
+ RADIOREGS3(0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00,
+ 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00),
+ PHYREGS(0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0),
+ },
+ { .freq = 5310,
+ RADIOREGS3(0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00,
+ 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef),
+ },
+ { .freq = 5320,
+ RADIOREGS3(0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00,
+ 0xdb, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee),
+ },
+ { .freq = 5330,
+ RADIOREGS3(0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00,
+ 0xcb, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
+ 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed),
+ },
+ { .freq = 5340,
+ RADIOREGS3(0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00,
+ 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
+ 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00),
+ PHYREGS(0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec),
+ },
+ { .freq = 5350,
+ RADIOREGS3(0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00,
+ 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
+ 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb),
+ },
+ { .freq = 5360,
+ RADIOREGS3(0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00,
+ 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea),
+ },
+ { .freq = 5370,
+ RADIOREGS3(0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00,
+ 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9),
+ },
+ { .freq = 5380,
+ RADIOREGS3(0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00,
+ 0xb8, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00),
+ PHYREGS(0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8),
+ },
+ { .freq = 5390,
+ RADIOREGS3(0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00,
+ 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7),
+ },
+ { .freq = 5400,
+ RADIOREGS3(0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00,
+ 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6),
+ },
+ { .freq = 5410,
+ RADIOREGS3(0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00,
+ 0xb7, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5),
+ },
+ { .freq = 5420,
+ RADIOREGS3(0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00,
+ 0xa7, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00),
+ PHYREGS(0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5),
+ },
+ { .freq = 5430,
+ RADIOREGS3(0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00,
+ 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4),
+ },
+ { .freq = 5440,
+ RADIOREGS3(0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00,
+ 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3),
+ },
+ { .freq = 5450,
+ RADIOREGS3(0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00,
+ 0x95, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2),
+ },
+ { .freq = 5460,
+ RADIOREGS3(0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00,
+ 0x95, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1),
+ },
+ { .freq = 5470,
+ RADIOREGS3(0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00,
+ 0x94, 0x73, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x73, 0x00, 0x01, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0),
+ },
+ { .freq = 5480,
+ RADIOREGS3(0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00,
+ 0x84, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df),
+ },
+ { .freq = 5490,
+ RADIOREGS3(0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00,
+ 0x83, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de),
+ },
+ { .freq = 5500,
+ RADIOREGS3(0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00,
+ 0x82, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd),
+ },
+ { .freq = 5510,
+ RADIOREGS3(0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00,
+ 0x82, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd),
+ },
+ { .freq = 5520,
+ RADIOREGS3(0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00,
+ 0x72, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc),
+ },
+ { .freq = 5530,
+ RADIOREGS3(0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00,
+ 0x72, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db),
+ },
+ { .freq = 5540,
+ RADIOREGS3(0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00,
+ 0x71, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da),
+ },
+ { .freq = 5550,
+ RADIOREGS3(0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x09, 0x00,
+ 0x61, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9),
+ },
+ { .freq = 5560,
+ RADIOREGS3(0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x09, 0x00,
+ 0x61, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8),
+ },
+ { .freq = 5570,
+ RADIOREGS3(0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x09, 0x00,
+ 0x61, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7),
+ },
+ { .freq = 5580,
+ RADIOREGS3(0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x08, 0x00,
+ 0x60, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+ 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x08, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7),
+ },
+ { .freq = 5590,
+ RADIOREGS3(0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x08, 0x00,
+ 0x50, 0x61, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+ 0x00, 0x6f, 0x00, 0x61, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x08, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6),
+ },
+ { .freq = 5600,
+ RADIOREGS3(0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x89, 0x08, 0x00,
+ 0x50, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+ 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x08, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5),
+ },
+ { .freq = 5610,
+ RADIOREGS3(0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x89, 0x08, 0x00,
+ 0x50, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+ 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x08, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4),
+ },
+ { .freq = 5620,
+ RADIOREGS3(0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x89, 0x08, 0x00,
+ 0x50, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+ 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x07, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3),
+ },
+ { .freq = 5630,
+ RADIOREGS3(0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00,
+ 0x50, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+ 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x07, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2),
+ },
+ { .freq = 5640,
+ RADIOREGS3(0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00,
+ 0x40, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+ 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x07, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2),
+ },
+ { .freq = 5650,
+ RADIOREGS3(0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00,
+ 0x40, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+ 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x07, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1),
+ },
+ { .freq = 5660,
+ RADIOREGS3(0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00,
+ 0x40, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0),
+ },
+ { .freq = 5670,
+ RADIOREGS3(0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00,
+ 0x40, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf),
+ },
+ { .freq = 5680,
+ RADIOREGS3(0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00,
+ 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce),
+ },
+ { .freq = 5690,
+ RADIOREGS3(0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00,
+ 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce),
+ },
+ { .freq = 5700,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00,
+ 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6e, 0x00),
+ PHYREGS(0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd),
+ },
+ { .freq = 5710,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00,
+ 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6e, 0x00),
+ PHYREGS(0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc),
+ },
+ { .freq = 5720,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00,
+ 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6e, 0x00),
+ PHYREGS(0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb),
+ },
+ { .freq = 5725,
+ RADIOREGS3(0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00,
+ 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6e, 0x00),
+ PHYREGS(0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb),
+ },
+ { .freq = 5730,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00,
+ 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6e, 0x00),
+ PHYREGS(0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca),
+ },
+ { .freq = 5735,
+ RADIOREGS3(0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00,
+ 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6d, 0x00),
+ PHYREGS(0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca),
+ },
+ { .freq = 5740,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00,
+ 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6d, 0x00),
+ PHYREGS(0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9),
+ },
+ { .freq = 5745,
+ RADIOREGS3(0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00,
+ 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6d, 0x00),
+ PHYREGS(0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9),
+ },
+ { .freq = 5750,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00,
+ 0x20, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6d, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6d, 0x00),
+ PHYREGS(0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9),
+ },
+ { .freq = 5755,
+ RADIOREGS3(0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00,
+ 0x10, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6c, 0x00),
+ PHYREGS(0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8),
+ },
+ { .freq = 5760,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x86, 0x05, 0x00,
+ 0x10, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6c, 0x00),
+ PHYREGS(0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8),
+ },
+ { .freq = 5765,
+ RADIOREGS3(0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x86, 0x05, 0x00,
+ 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6c, 0x00),
+ PHYREGS(0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8),
+ },
+ { .freq = 5770,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x86, 0x04, 0x00,
+ 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00),
+ PHYREGS(0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7),
+ },
+ { .freq = 5775,
+ RADIOREGS3(0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x86, 0x04, 0x00,
+ 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00),
+ PHYREGS(0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7),
+ },
+ { .freq = 5780,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x86, 0x04, 0x00,
+ 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00),
+ PHYREGS(0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6),
+ },
+ { .freq = 5785,
+ RADIOREGS3(0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00),
+ PHYREGS(0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6),
+ },
+ { .freq = 5790,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00),
+ PHYREGS(0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6),
+ },
+ { .freq = 5795,
+ RADIOREGS3(0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00),
+ PHYREGS(0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5),
+ },
+ { .freq = 5800,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00),
+ PHYREGS(0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5),
+ },
+ { .freq = 5805,
+ RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6a, 0x00),
+ PHYREGS(0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4),
+ },
+ { .freq = 5810,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6a, 0x00),
+ PHYREGS(0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4),
+ },
+ { .freq = 5815,
+ RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6a, 0x00),
+ PHYREGS(0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4),
+ },
+ { .freq = 5820,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6a, 0x00),
+ PHYREGS(0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3),
+ },
+ { .freq = 5825,
+ RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x69, 0x00),
+ PHYREGS(0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3),
+ },
+ { .freq = 5830,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x69, 0x00),
+ PHYREGS(0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2),
+ },
+ { .freq = 5840,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x69, 0x00),
+ PHYREGS(0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2),
+ },
+ { .freq = 5850,
+ RADIOREGS3(0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x69, 0x00),
+ PHYREGS(0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1),
+ },
+ { .freq = 5860,
+ RADIOREGS3(0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x69, 0x00),
+ PHYREGS(0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0),
+ },
+ { .freq = 5870,
+ RADIOREGS3(0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x68, 0x00),
+ PHYREGS(0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf),
+ },
+ { .freq = 5880,
+ RADIOREGS3(0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x68, 0x00),
+ PHYREGS(0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf),
+ },
+ { .freq = 5890,
+ RADIOREGS3(0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x68, 0x00),
+ PHYREGS(0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be),
+ },
+ { .freq = 5900,
+ RADIOREGS3(0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x68, 0x00),
+ PHYREGS(0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd),
+ },
+ { .freq = 5910,
+ RADIOREGS3(0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x68, 0x00),
+ PHYREGS(0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc),
+ },
+ { .freq = 2412,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0b, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0b, 0x00, 0x0a),
+ PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443),
+ },
+ { .freq = 2417,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0b, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0b, 0x00, 0x0a),
+ PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441),
+ },
+ { .freq = 2422,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x67, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0b, 0x00, 0x0a, 0x00, 0x67, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0b, 0x00, 0x0a),
+ PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f),
+ },
+ { .freq = 2427,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x57, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x0a, 0x00, 0x57, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x0a),
+ PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d),
+ },
+ { .freq = 2432,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x56, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x0a, 0x00, 0x56, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x0a),
+ PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a),
+ },
+ { .freq = 2437,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x46, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x0a, 0x00, 0x46, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x0a),
+ PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438),
+ },
+ { .freq = 2442,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x0a, 0x00, 0x45, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x0a),
+ PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436),
+ },
+ { .freq = 2447,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x09),
+ PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434),
+ },
+ { .freq = 2452,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x23, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x09, 0x00, 0x23, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x09),
+ PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431),
+ },
+ { .freq = 2457,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x12, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x09, 0x00, 0x12, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x09),
+ PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f),
+ },
+ { .freq = 2462,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x09, 0x00, 0x09, 0x00, 0x02, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x09, 0x00, 0x09),
+ PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d),
+ },
+ { .freq = 2467,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x09, 0x00, 0x09, 0x00, 0x01, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x09, 0x00, 0x09),
+ PHYREGS(0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b),
+ },
+ { .freq = 2472,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x09, 0x00, 0x09, 0x00, 0x01, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x09, 0x00, 0x09),
+ PHYREGS(0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429),
+ },
+ { .freq = 2484,
+ RADIOREGS3(0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x09, 0x00, 0x09),
+ PHYREGS(0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424),
+ },
+};
+
+static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev7_9[] = {
+ { .freq = 4920,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0f,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216),
+ },
+ { .freq = 4930,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70,
+ 0x00, 0x0e, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215),
+ },
+ { .freq = 4940,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70,
+ 0x00, 0x0e, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214),
+ },
+ { .freq = 4950,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70,
+ 0x00, 0x0e, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213),
+ },
+ { .freq = 4960,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0e,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70,
+ 0x00, 0x0e, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212),
+ },
+ { .freq = 4970,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211),
+ },
+ { .freq = 4980,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f),
+ },
+ { .freq = 4990,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e),
+ },
+ { .freq = 5000,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d),
+ },
+ { .freq = 5010,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c),
+ },
+ { .freq = 5020,
+ RADIOREGS3(0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0d,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b),
+ },
+ { .freq = 5030,
+ RADIOREGS3(0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
+ 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a),
+ },
+ { .freq = 5040,
+ RADIOREGS3(0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
+ 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209),
+ },
+ { .freq = 5050,
+ RADIOREGS3(0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
+ 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208),
+ },
+ { .freq = 5060,
+ RADIOREGS3(0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfd, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
+ 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x70,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207),
+ },
+ { .freq = 5070,
+ RADIOREGS3(0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfd, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+ 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x70,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206),
+ },
+ { .freq = 5080,
+ RADIOREGS3(0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+ 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205),
+ },
+ { .freq = 5090,
+ RADIOREGS3(0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+ 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204),
+ },
+ { .freq = 5100,
+ RADIOREGS3(0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+ 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203),
+ },
+ { .freq = 5110,
+ RADIOREGS3(0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+ 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202),
+ },
+ { .freq = 5120,
+ RADIOREGS3(0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+ 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201),
+ },
+ { .freq = 5130,
+ RADIOREGS3(0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfb, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0a,
+ 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x70,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200),
+ },
+ { .freq = 5140,
+ RADIOREGS3(0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x0a,
+ 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00),
+ PHYREGS(0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff),
+ },
+ { .freq = 5160,
+ RADIOREGS3(0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x09,
+ 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70,
+ 0x00, 0x09, 0x00, 0x6e, 0x00),
+ PHYREGS(0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd),
+ },
+ { .freq = 5170,
+ RADIOREGS3(0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfb, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+ 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x06, 0x00, 0x70,
+ 0x00, 0x09, 0x00, 0x6e, 0x00),
+ PHYREGS(0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc),
+ },
+ { .freq = 5180,
+ RADIOREGS3(0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+ 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70,
+ 0x00, 0x09, 0x00, 0x6e, 0x00),
+ PHYREGS(0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb),
+ },
+ { .freq = 5190,
+ RADIOREGS3(0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+ 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70,
+ 0x00, 0x09, 0x00, 0x6e, 0x00),
+ PHYREGS(0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa),
+ },
+ { .freq = 5200,
+ RADIOREGS3(0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+ 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70,
+ 0x00, 0x09, 0x00, 0x6e, 0x00),
+ PHYREGS(0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9),
+ },
+ { .freq = 5210,
+ RADIOREGS3(0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+ 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70,
+ 0x00, 0x09, 0x00, 0x6e, 0x00),
+ PHYREGS(0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8),
+ },
+ { .freq = 5220,
+ RADIOREGS3(0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00,
+ 0xfe, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+ 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70,
+ 0x00, 0x09, 0x00, 0x6e, 0x00),
+ PHYREGS(0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7),
+ },
+ { .freq = 5230,
+ RADIOREGS3(0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00,
+ 0xee, 0xea, 0x00, 0x06, 0x00, 0x70, 0x00, 0x08,
+ 0x00, 0x9e, 0x00, 0xea, 0x00, 0x06, 0x00, 0x70,
+ 0x00, 0x08, 0x00, 0x6e, 0x00),
+ PHYREGS(0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6),
+ },
+ { .freq = 5240,
+ RADIOREGS3(0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00,
+ 0xee, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
+ 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70,
+ 0x00, 0x08, 0x00, 0x6d, 0x00),
+ PHYREGS(0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5),
+ },
+ { .freq = 5250,
+ RADIOREGS3(0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00,
+ 0xed, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
+ 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70,
+ 0x00, 0x08, 0x00, 0x6d, 0x00),
+ PHYREGS(0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4),
+ },
+ { .freq = 5260,
+ RADIOREGS3(0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00,
+ 0xed, 0xd9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
+ 0x00, 0x9d, 0x00, 0xd9, 0x00, 0x05, 0x00, 0x70,
+ 0x00, 0x08, 0x00, 0x6d, 0x00),
+ PHYREGS(0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3),
+ },
+ { .freq = 5270,
+ RADIOREGS3(0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00,
+ 0xed, 0xd8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x9c, 0x00, 0xd8, 0x00, 0x04, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x6c, 0x00),
+ PHYREGS(0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2),
+ },
+ { .freq = 5280,
+ RADIOREGS3(0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00,
+ 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x6c, 0x00),
+ PHYREGS(0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1),
+ },
+ { .freq = 5290,
+ RADIOREGS3(0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00,
+ 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x6c, 0x00),
+ PHYREGS(0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0),
+ },
+ { .freq = 5300,
+ RADIOREGS3(0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00,
+ 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x6c, 0x00),
+ PHYREGS(0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0),
+ },
+ { .freq = 5310,
+ RADIOREGS3(0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00,
+ 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x6c, 0x00),
+ PHYREGS(0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef),
+ },
+ { .freq = 5320,
+ RADIOREGS3(0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00,
+ 0xdb, 0xb8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x9c, 0x00, 0xb8, 0x00, 0x04, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x6c, 0x00),
+ PHYREGS(0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee),
+ },
+ { .freq = 5330,
+ RADIOREGS3(0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00,
+ 0xcb, 0xb7, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x04, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x6b, 0x00),
+ PHYREGS(0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed),
+ },
+ { .freq = 5340,
+ RADIOREGS3(0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00,
+ 0xca, 0xb7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x6b, 0x00),
+ PHYREGS(0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec),
+ },
+ { .freq = 5350,
+ RADIOREGS3(0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00,
+ 0xca, 0xa7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+ 0x00, 0x9b, 0x00, 0xa7, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x06, 0x00, 0x6b, 0x00),
+ PHYREGS(0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb),
+ },
+ { .freq = 5360,
+ RADIOREGS3(0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00,
+ 0xc9, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+ 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x06, 0x00, 0x6b, 0x00),
+ PHYREGS(0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea),
+ },
+ { .freq = 5370,
+ RADIOREGS3(0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00,
+ 0xc9, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+ 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x06, 0x00, 0x7b, 0x00),
+ PHYREGS(0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9),
+ },
+ { .freq = 5380,
+ RADIOREGS3(0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00,
+ 0xb8, 0x96, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+ 0x00, 0x9a, 0x00, 0x96, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x06, 0x00, 0x7a, 0x00),
+ PHYREGS(0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8),
+ },
+ { .freq = 5390,
+ RADIOREGS3(0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00,
+ 0xb8, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+ 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x06, 0x00, 0x7a, 0x00),
+ PHYREGS(0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7),
+ },
+ { .freq = 5400,
+ RADIOREGS3(0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00,
+ 0xb8, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+ 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x06, 0x00, 0x7a, 0x00),
+ PHYREGS(0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6),
+ },
+ { .freq = 5410,
+ RADIOREGS3(0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00,
+ 0xb7, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05,
+ 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x05, 0x00, 0x7a, 0x00),
+ PHYREGS(0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5),
+ },
+ { .freq = 5420,
+ RADIOREGS3(0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00,
+ 0xa7, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05,
+ 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x05, 0x00, 0x7a, 0x00),
+ PHYREGS(0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5),
+ },
+ { .freq = 5430,
+ RADIOREGS3(0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00,
+ 0xa6, 0x85, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
+ 0x00, 0x99, 0x00, 0x85, 0x00, 0x02, 0x00, 0x70,
+ 0x00, 0x05, 0x00, 0x79, 0x00),
+ PHYREGS(0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4),
+ },
+ { .freq = 5440,
+ RADIOREGS3(0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00,
+ 0xa6, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
+ 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70,
+ 0x00, 0x05, 0x00, 0x79, 0x00),
+ PHYREGS(0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3),
+ },
+ { .freq = 5450,
+ RADIOREGS3(0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00,
+ 0x95, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
+ 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70,
+ 0x00, 0x05, 0x00, 0x79, 0x00),
+ PHYREGS(0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2),
+ },
+ { .freq = 5460,
+ RADIOREGS3(0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00,
+ 0x95, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x04,
+ 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70,
+ 0x00, 0x04, 0x00, 0x79, 0x00),
+ PHYREGS(0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1),
+ },
+ { .freq = 5470,
+ RADIOREGS3(0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00,
+ 0x94, 0x74, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+ 0x00, 0x99, 0x00, 0x74, 0x00, 0x01, 0x00, 0x70,
+ 0x00, 0x04, 0x00, 0x79, 0x00),
+ PHYREGS(0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0),
+ },
+ { .freq = 5480,
+ RADIOREGS3(0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00,
+ 0x84, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+ 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70,
+ 0x00, 0x04, 0x00, 0x78, 0x00),
+ PHYREGS(0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df),
+ },
+ { .freq = 5490,
+ RADIOREGS3(0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00,
+ 0x83, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+ 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70,
+ 0x00, 0x04, 0x00, 0x78, 0x00),
+ PHYREGS(0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de),
+ },
+ { .freq = 5500,
+ RADIOREGS3(0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00,
+ 0x82, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+ 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70,
+ 0x00, 0x04, 0x00, 0x78, 0x00),
+ PHYREGS(0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd),
+ },
+ { .freq = 5510,
+ RADIOREGS3(0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00,
+ 0x82, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+ 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70,
+ 0x00, 0x04, 0x00, 0x78, 0x00),
+ PHYREGS(0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd),
+ },
+ { .freq = 5520,
+ RADIOREGS3(0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00,
+ 0x72, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+ 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70,
+ 0x00, 0x04, 0x00, 0x78, 0x00),
+ PHYREGS(0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc),
+ },
+ { .freq = 5530,
+ RADIOREGS3(0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00,
+ 0x72, 0x63, 0x00, 0x01, 0x00, 0x70, 0x00, 0x03,
+ 0x00, 0x98, 0x00, 0x63, 0x00, 0x01, 0x00, 0x70,
+ 0x00, 0x03, 0x00, 0x78, 0x00),
+ PHYREGS(0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db),
+ },
+ { .freq = 5540,
+ RADIOREGS3(0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00,
+ 0x71, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
+ 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x03, 0x00, 0x77, 0x00),
+ PHYREGS(0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da),
+ },
+ { .freq = 5550,
+ RADIOREGS3(0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x09, 0x00,
+ 0x61, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
+ 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x03, 0x00, 0x77, 0x00),
+ PHYREGS(0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9),
+ },
+ { .freq = 5560,
+ RADIOREGS3(0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x09, 0x00,
+ 0x61, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
+ 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x03, 0x00, 0x77, 0x00),
+ PHYREGS(0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8),
+ },
+ { .freq = 5570,
+ RADIOREGS3(0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x09, 0x00,
+ 0x61, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x76, 0x00),
+ PHYREGS(0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7),
+ },
+ { .freq = 5580,
+ RADIOREGS3(0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x08, 0x00,
+ 0x60, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x86, 0x00),
+ PHYREGS(0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7),
+ },
+ { .freq = 5590,
+ RADIOREGS3(0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x08, 0x00,
+ 0x50, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x86, 0x00),
+ PHYREGS(0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6),
+ },
+ { .freq = 5600,
+ RADIOREGS3(0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x89, 0x08, 0x00,
+ 0x50, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x86, 0x00),
+ PHYREGS(0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5),
+ },
+ { .freq = 5610,
+ RADIOREGS3(0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x89, 0x08, 0x00,
+ 0x50, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x86, 0x00),
+ PHYREGS(0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4),
+ },
+ { .freq = 5620,
+ RADIOREGS3(0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x89, 0x08, 0x00,
+ 0x50, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x86, 0x00),
+ PHYREGS(0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3),
+ },
+ { .freq = 5630,
+ RADIOREGS3(0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00,
+ 0x50, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x86, 0x00),
+ PHYREGS(0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2),
+ },
+ { .freq = 5640,
+ RADIOREGS3(0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00,
+ 0x40, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x95, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x85, 0x00),
+ PHYREGS(0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2),
+ },
+ { .freq = 5650,
+ RADIOREGS3(0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00,
+ 0x40, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x85, 0x00),
+ PHYREGS(0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1),
+ },
+ { .freq = 5660,
+ RADIOREGS3(0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00,
+ 0x40, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x85, 0x00),
+ PHYREGS(0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0),
+ },
+ { .freq = 5670,
+ RADIOREGS3(0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00,
+ 0x40, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x84, 0x00),
+ PHYREGS(0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf),
+ },
+ { .freq = 5680,
+ RADIOREGS3(0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00,
+ 0x30, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x84, 0x00),
+ PHYREGS(0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce),
+ },
+ { .freq = 5690,
+ RADIOREGS3(0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00,
+ 0x30, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x94, 0x00),
+ PHYREGS(0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce),
+ },
+ { .freq = 5700,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00,
+ 0x30, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x94, 0x00),
+ PHYREGS(0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd),
+ },
+ { .freq = 5710,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00,
+ 0x30, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x94, 0x00),
+ PHYREGS(0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc),
+ },
+ { .freq = 5720,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00,
+ 0x30, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x94, 0x00),
+ PHYREGS(0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb),
+ },
+ { .freq = 5725,
+ RADIOREGS3(0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00,
+ 0x30, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x94, 0x00),
+ PHYREGS(0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb),
+ },
+ { .freq = 5730,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00,
+ 0x20, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x94, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x94, 0x00),
+ PHYREGS(0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca),
+ },
+ { .freq = 5735,
+ RADIOREGS3(0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00,
+ 0x20, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x93, 0x00),
+ PHYREGS(0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca),
+ },
+ { .freq = 5740,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00,
+ 0x20, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x93, 0x00),
+ PHYREGS(0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9),
+ },
+ { .freq = 5745,
+ RADIOREGS3(0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00,
+ 0x20, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x93, 0x00),
+ PHYREGS(0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9),
+ },
+ { .freq = 5750,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00,
+ 0x20, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x93, 0x00),
+ PHYREGS(0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9),
+ },
+ { .freq = 5755,
+ RADIOREGS3(0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00,
+ 0x10, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x93, 0x00),
+ PHYREGS(0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8),
+ },
+ { .freq = 5760,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x86, 0x05, 0x00,
+ 0x10, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x93, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x93, 0x00),
+ PHYREGS(0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8),
+ },
+ { .freq = 5765,
+ RADIOREGS3(0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x86, 0x05, 0x00,
+ 0x10, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00),
+ PHYREGS(0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8),
+ },
+ { .freq = 5770,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x86, 0x04, 0x00,
+ 0x10, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00),
+ PHYREGS(0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7),
+ },
+ { .freq = 5775,
+ RADIOREGS3(0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x86, 0x04, 0x00,
+ 0x10, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00),
+ PHYREGS(0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7),
+ },
+ { .freq = 5780,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x86, 0x04, 0x00,
+ 0x10, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00),
+ PHYREGS(0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6),
+ },
+ { .freq = 5785,
+ RADIOREGS3(0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00),
+ PHYREGS(0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6),
+ },
+ { .freq = 5790,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00),
+ PHYREGS(0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6),
+ },
+ { .freq = 5795,
+ RADIOREGS3(0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00),
+ PHYREGS(0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5),
+ },
+ { .freq = 5800,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00),
+ PHYREGS(0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5),
+ },
+ { .freq = 5805,
+ RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00),
+ PHYREGS(0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4),
+ },
+ { .freq = 5810,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00),
+ PHYREGS(0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4),
+ },
+ { .freq = 5815,
+ RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00),
+ PHYREGS(0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4),
+ },
+ { .freq = 5820,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00),
+ PHYREGS(0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3),
+ },
+ { .freq = 5825,
+ RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00),
+ PHYREGS(0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3),
+ },
+ { .freq = 5830,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00),
+ PHYREGS(0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2),
+ },
+ { .freq = 5840,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00),
+ PHYREGS(0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2),
+ },
+ { .freq = 5850,
+ RADIOREGS3(0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00),
+ PHYREGS(0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1),
+ },
+ { .freq = 5860,
+ RADIOREGS3(0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00),
+ PHYREGS(0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0),
+ },
+ { .freq = 5870,
+ RADIOREGS3(0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x91, 0x00),
+ PHYREGS(0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf),
+ },
+ { .freq = 5880,
+ RADIOREGS3(0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x91, 0x00),
+ PHYREGS(0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf),
+ },
+ { .freq = 5890,
+ RADIOREGS3(0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x91, 0x00),
+ PHYREGS(0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be),
+ },
+ { .freq = 5900,
+ RADIOREGS3(0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x91, 0x00),
+ PHYREGS(0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd),
+ },
+ { .freq = 5910,
+ RADIOREGS3(0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x91, 0x00),
+ PHYREGS(0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc),
+ },
+ { .freq = 2412,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0b, 0x00, 0x89, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0b),
+ PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443),
+ },
+ { .freq = 2417,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0a),
+ PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441),
+ },
+ { .freq = 2422,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0a),
+ PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f),
+ },
+ { .freq = 2427,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0e, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0e, 0x00, 0x0a),
+ PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d),
+ },
+ { .freq = 2432,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x77, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0e, 0x00, 0x0a, 0x00, 0x77, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0e, 0x00, 0x0a),
+ PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a),
+ },
+ { .freq = 2437,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x76, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0e, 0x00, 0x0a, 0x00, 0x76, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0e, 0x00, 0x0a),
+ PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438),
+ },
+ { .freq = 2442,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x66, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0e, 0x00, 0x0a, 0x00, 0x66, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0e, 0x00, 0x0a),
+ PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436),
+ },
+ { .freq = 2447,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x55, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0e, 0x00, 0x09, 0x00, 0x55, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0e, 0x00, 0x09),
+ PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434),
+ },
+ { .freq = 2452,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0e, 0x00, 0x09, 0x00, 0x45, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0e, 0x00, 0x09),
+ PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431),
+ },
+ { .freq = 2457,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0d, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0d, 0x00, 0x09),
+ PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f),
+ },
+ { .freq = 2462,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0d, 0x00, 0x09, 0x00, 0x33, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0d, 0x00, 0x09),
+ PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d),
+ },
+ { .freq = 2467,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x22, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0d, 0x00, 0x08, 0x00, 0x22, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0d, 0x00, 0x08),
+ PHYREGS(0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b),
+ },
+ { .freq = 2472,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0d, 0x00, 0x08, 0x00, 0x11, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0d, 0x00, 0x08),
+ PHYREGS(0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429),
+ },
+ { .freq = 2484,
+ RADIOREGS3(0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0d, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0d, 0x00, 0x08),
+ PHYREGS(0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424),
+ },
+};
+
+static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev8[] = {
+ { .freq = 4920,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216),
+ },
+ { .freq = 4930,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215),
+ },
+ { .freq = 4940,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214),
+ },
+ { .freq = 4950,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213),
+ },
+ { .freq = 4960,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212),
+ },
+ { .freq = 4970,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211),
+ },
+ { .freq = 4980,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f),
+ },
+ { .freq = 4990,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e),
+ },
+ { .freq = 5000,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d),
+ },
+ { .freq = 5010,
+ RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c),
+ },
+ { .freq = 5020,
+ RADIOREGS3(0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b),
+ },
+ { .freq = 5030,
+ RADIOREGS3(0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a),
+ },
+ { .freq = 5040,
+ RADIOREGS3(0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209),
+ },
+ { .freq = 5050,
+ RADIOREGS3(0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208),
+ },
+ { .freq = 5060,
+ RADIOREGS3(0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207),
+ },
+ { .freq = 5070,
+ RADIOREGS3(0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206),
+ },
+ { .freq = 5080,
+ RADIOREGS3(0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205),
+ },
+ { .freq = 5090,
+ RADIOREGS3(0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204),
+ },
+ { .freq = 5100,
+ RADIOREGS3(0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfd, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203),
+ },
+ { .freq = 5110,
+ RADIOREGS3(0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202),
+ },
+ { .freq = 5120,
+ RADIOREGS3(0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201),
+ },
+ { .freq = 5130,
+ RADIOREGS3(0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200),
+ },
+ { .freq = 5140,
+ RADIOREGS3(0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfb, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00),
+ PHYREGS(0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff),
+ },
+ { .freq = 5160,
+ RADIOREGS3(0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
+ 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77,
+ 0x00, 0x0e, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd),
+ },
+ { .freq = 5170,
+ RADIOREGS3(0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
+ 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77,
+ 0x00, 0x0e, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc),
+ },
+ { .freq = 5180,
+ RADIOREGS3(0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0e,
+ 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77,
+ 0x00, 0x0e, 0x00, 0x6f, 0x00),
+ PHYREGS(0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb),
+ },
+ { .freq = 5190,
+ RADIOREGS3(0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa),
+ },
+ { .freq = 5200,
+ RADIOREGS3(0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9),
+ },
+ { .freq = 5210,
+ RADIOREGS3(0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
+ 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8),
+ },
+ { .freq = 5220,
+ RADIOREGS3(0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00,
+ 0xfe, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7),
+ },
+ { .freq = 5230,
+ RADIOREGS3(0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00,
+ 0xee, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6),
+ },
+ { .freq = 5240,
+ RADIOREGS3(0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00,
+ 0xee, 0xc8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0xc8, 0x00, 0x05, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5),
+ },
+ { .freq = 5250,
+ RADIOREGS3(0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00,
+ 0xed, 0xc7, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x05, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4),
+ },
+ { .freq = 5260,
+ RADIOREGS3(0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00,
+ 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00),
+ PHYREGS(0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3),
+ },
+ { .freq = 5270,
+ RADIOREGS3(0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00,
+ 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2),
+ },
+ { .freq = 5280,
+ RADIOREGS3(0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00,
+ 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1),
+ },
+ { .freq = 5290,
+ RADIOREGS3(0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00,
+ 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0),
+ },
+ { .freq = 5300,
+ RADIOREGS3(0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00,
+ 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00),
+ PHYREGS(0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0),
+ },
+ { .freq = 5310,
+ RADIOREGS3(0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00,
+ 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef),
+ },
+ { .freq = 5320,
+ RADIOREGS3(0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00,
+ 0xdb, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee),
+ },
+ { .freq = 5330,
+ RADIOREGS3(0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00,
+ 0xcb, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
+ 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed),
+ },
+ { .freq = 5340,
+ RADIOREGS3(0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00,
+ 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
+ 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00),
+ PHYREGS(0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec),
+ },
+ { .freq = 5350,
+ RADIOREGS3(0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00,
+ 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
+ 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb),
+ },
+ { .freq = 5360,
+ RADIOREGS3(0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00,
+ 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea),
+ },
+ { .freq = 5370,
+ RADIOREGS3(0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00,
+ 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9),
+ },
+ { .freq = 5380,
+ RADIOREGS3(0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00,
+ 0xb8, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00),
+ PHYREGS(0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8),
+ },
+ { .freq = 5390,
+ RADIOREGS3(0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00,
+ 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7),
+ },
+ { .freq = 5400,
+ RADIOREGS3(0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00,
+ 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6),
+ },
+ { .freq = 5410,
+ RADIOREGS3(0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00,
+ 0xb7, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5),
+ },
+ { .freq = 5420,
+ RADIOREGS3(0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00,
+ 0xa7, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00),
+ PHYREGS(0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5),
+ },
+ { .freq = 5430,
+ RADIOREGS3(0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00,
+ 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4),
+ },
+ { .freq = 5440,
+ RADIOREGS3(0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00,
+ 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3),
+ },
+ { .freq = 5450,
+ RADIOREGS3(0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00,
+ 0x95, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2),
+ },
+ { .freq = 5460,
+ RADIOREGS3(0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00,
+ 0x95, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1),
+ },
+ { .freq = 5470,
+ RADIOREGS3(0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00,
+ 0x94, 0x73, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x73, 0x00, 0x01, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0),
+ },
+ { .freq = 5480,
+ RADIOREGS3(0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00,
+ 0x84, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df),
+ },
+ { .freq = 5490,
+ RADIOREGS3(0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00,
+ 0x83, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de),
+ },
+ { .freq = 5500,
+ RADIOREGS3(0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00,
+ 0x82, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd),
+ },
+ { .freq = 5510,
+ RADIOREGS3(0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00,
+ 0x82, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd),
+ },
+ { .freq = 5520,
+ RADIOREGS3(0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00,
+ 0x72, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc),
+ },
+ { .freq = 5530,
+ RADIOREGS3(0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00,
+ 0x72, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db),
+ },
+ { .freq = 5540,
+ RADIOREGS3(0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00,
+ 0x71, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da),
+ },
+ { .freq = 5550,
+ RADIOREGS3(0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x09, 0x00,
+ 0x61, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9),
+ },
+ { .freq = 5560,
+ RADIOREGS3(0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x09, 0x00,
+ 0x61, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8),
+ },
+ { .freq = 5570,
+ RADIOREGS3(0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x09, 0x00,
+ 0x61, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7),
+ },
+ { .freq = 5580,
+ RADIOREGS3(0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x08, 0x00,
+ 0x60, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+ 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x08, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7),
+ },
+ { .freq = 5590,
+ RADIOREGS3(0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x04, 0x04, 0x04, 0x89, 0x08, 0x00,
+ 0x50, 0x61, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+ 0x00, 0x6f, 0x00, 0x61, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x08, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6),
+ },
+ { .freq = 5600,
+ RADIOREGS3(0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x89, 0x08, 0x00,
+ 0x50, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+ 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x08, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5),
+ },
+ { .freq = 5610,
+ RADIOREGS3(0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x89, 0x08, 0x00,
+ 0x50, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+ 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x08, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4),
+ },
+ { .freq = 5620,
+ RADIOREGS3(0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x89, 0x08, 0x00,
+ 0x50, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+ 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x07, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3),
+ },
+ { .freq = 5630,
+ RADIOREGS3(0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00,
+ 0x50, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+ 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x07, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2),
+ },
+ { .freq = 5640,
+ RADIOREGS3(0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00,
+ 0x40, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+ 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x07, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2),
+ },
+ { .freq = 5650,
+ RADIOREGS3(0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00,
+ 0x40, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+ 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x07, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1),
+ },
+ { .freq = 5660,
+ RADIOREGS3(0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00,
+ 0x40, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0),
+ },
+ { .freq = 5670,
+ RADIOREGS3(0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x88, 0x07, 0x00,
+ 0x40, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf),
+ },
+ { .freq = 5680,
+ RADIOREGS3(0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00,
+ 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce),
+ },
+ { .freq = 5690,
+ RADIOREGS3(0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00,
+ 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6f, 0x00),
+ PHYREGS(0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce),
+ },
+ { .freq = 5700,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00,
+ 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6e, 0x00),
+ PHYREGS(0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd),
+ },
+ { .freq = 5710,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00,
+ 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6e, 0x00),
+ PHYREGS(0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc),
+ },
+ { .freq = 5720,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00,
+ 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6e, 0x00),
+ PHYREGS(0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb),
+ },
+ { .freq = 5725,
+ RADIOREGS3(0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x87, 0x06, 0x00,
+ 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6e, 0x00),
+ PHYREGS(0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb),
+ },
+ { .freq = 5730,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00,
+ 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6e, 0x00),
+ PHYREGS(0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca),
+ },
+ { .freq = 5735,
+ RADIOREGS3(0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00,
+ 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6d, 0x00),
+ PHYREGS(0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca),
+ },
+ { .freq = 5740,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00,
+ 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6d, 0x00),
+ PHYREGS(0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9),
+ },
+ { .freq = 5745,
+ RADIOREGS3(0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00,
+ 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6d, 0x00),
+ PHYREGS(0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9),
+ },
+ { .freq = 5750,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00,
+ 0x20, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6d, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6d, 0x00),
+ PHYREGS(0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9),
+ },
+ { .freq = 5755,
+ RADIOREGS3(0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00,
+ 0x10, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6c, 0x00),
+ PHYREGS(0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8),
+ },
+ { .freq = 5760,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x86, 0x05, 0x00,
+ 0x10, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6c, 0x00),
+ PHYREGS(0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8),
+ },
+ { .freq = 5765,
+ RADIOREGS3(0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x86, 0x05, 0x00,
+ 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6c, 0x00),
+ PHYREGS(0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8),
+ },
+ { .freq = 5770,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x86, 0x04, 0x00,
+ 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00),
+ PHYREGS(0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7),
+ },
+ { .freq = 5775,
+ RADIOREGS3(0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x05, 0x05, 0x05, 0x86, 0x04, 0x00,
+ 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00),
+ PHYREGS(0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7),
+ },
+ { .freq = 5780,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x05, 0x05, 0x05, 0x86, 0x04, 0x00,
+ 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00),
+ PHYREGS(0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6),
+ },
+ { .freq = 5785,
+ RADIOREGS3(0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00),
+ PHYREGS(0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6),
+ },
+ { .freq = 5790,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00),
+ PHYREGS(0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6),
+ },
+ { .freq = 5795,
+ RADIOREGS3(0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00),
+ PHYREGS(0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5),
+ },
+ { .freq = 5800,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00),
+ PHYREGS(0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5),
+ },
+ { .freq = 5805,
+ RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6a, 0x00),
+ PHYREGS(0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4),
+ },
+ { .freq = 5810,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6a, 0x00),
+ PHYREGS(0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4),
+ },
+ { .freq = 5815,
+ RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6a, 0x00),
+ PHYREGS(0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4),
+ },
+ { .freq = 5820,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6a, 0x00),
+ PHYREGS(0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3),
+ },
+ { .freq = 5825,
+ RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04,
+ 0x10, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x69, 0x00),
+ PHYREGS(0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3),
+ },
+ { .freq = 5830,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x69, 0x00),
+ PHYREGS(0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2),
+ },
+ { .freq = 5840,
+ RADIOREGS3(0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x69, 0x00),
+ PHYREGS(0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2),
+ },
+ { .freq = 5850,
+ RADIOREGS3(0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x69, 0x00),
+ PHYREGS(0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1),
+ },
+ { .freq = 5860,
+ RADIOREGS3(0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x69, 0x00),
+ PHYREGS(0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0),
+ },
+ { .freq = 5870,
+ RADIOREGS3(0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x68, 0x00),
+ PHYREGS(0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf),
+ },
+ { .freq = 5880,
+ RADIOREGS3(0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x68, 0x00),
+ PHYREGS(0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf),
+ },
+ { .freq = 5890,
+ RADIOREGS3(0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x68, 0x00),
+ PHYREGS(0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be),
+ },
+ { .freq = 5900,
+ RADIOREGS3(0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x68, 0x00),
+ PHYREGS(0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd),
+ },
+ { .freq = 5910,
+ RADIOREGS3(0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04,
+ 0x0c, 0x01, 0x06, 0x06, 0x06, 0x85, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x68, 0x00),
+ PHYREGS(0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc),
+ },
+ { .freq = 2412,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0b, 0x00, 0x0a),
+ PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443),
+ },
+ { .freq = 2417,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0b, 0x00, 0x0a),
+ PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441),
+ },
+ { .freq = 2422,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x67, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0b, 0x00, 0x0a),
+ PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f),
+ },
+ { .freq = 2427,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x57, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x0a),
+ PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d),
+ },
+ { .freq = 2432,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x56, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x0a, 0x00, 0x77, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x0a),
+ PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a),
+ },
+ { .freq = 2437,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x46, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x0a, 0x00, 0x76, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x0a),
+ PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438),
+ },
+ { .freq = 2442,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x0a, 0x00, 0x66, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x0a),
+ PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436),
+ },
+ { .freq = 2447,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x09, 0x00, 0x55, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x09),
+ PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434),
+ },
+ { .freq = 2452,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x23, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x09, 0x00, 0x45, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x09),
+ PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431),
+ },
+ { .freq = 2457,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x12, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x09),
+ PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f),
+ },
+ { .freq = 2462,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x09, 0x00, 0x09, 0x00, 0x33, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x09, 0x00, 0x09),
+ PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d),
+ },
+ { .freq = 2467,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x09, 0x00, 0x09, 0x00, 0x22, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x09, 0x00, 0x09),
+ PHYREGS(0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b),
+ },
+ { .freq = 2472,
+ RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00,
+ 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x09, 0x00, 0x09, 0x00, 0x11, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x09, 0x00, 0x09),
+ PHYREGS(0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429),
+ },
+ { .freq = 2484,
+ RADIOREGS3(0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04,
+ 0x16, 0x01, 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x09, 0x00, 0x09),
+ PHYREGS(0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424),
+ },
};
+/* TODO: add support for rev4+ devices by searching in rev4+ tables */
const struct b43_nphy_channeltab_entry_rev3 *
b43_nphy_get_chantabent_rev3(struct b43_wldev *dev, u16 freq)
{
diff --git a/drivers/net/wireless/b43/radio_2056.h b/drivers/net/wireless/b43/radio_2056.h
index fda6dafecb8c..302600c0afa4 100644
--- a/drivers/net/wireless/b43/radio_2056.h
+++ b/drivers/net/wireless/b43/radio_2056.h
@@ -4,6 +4,9 @@
Copyright (c) 2010 Rafał Miłecki <zajec5@gmail.com>
+ Some parts of the code in this file are derived from the brcm80211
+ driver Copyright (c) 2010 Broadcom Corporation
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
@@ -28,13 +31,1085 @@
#include "tables_nphy.h"
+#define B2056_SYN (0x0 << 12)
+#define B2056_TX0 (0x2 << 12)
+#define B2056_TX1 (0x3 << 12)
+#define B2056_RX0 (0x6 << 12)
+#define B2056_RX1 (0x7 << 12)
+#define B2056_ALLTX (0xE << 12)
+#define B2056_ALLRX (0xF << 12)
+
+#define B2056_SYN_RESERVED_ADDR0 0x00
+#define B2056_SYN_IDCODE 0x01
+#define B2056_SYN_RESERVED_ADDR2 0x02
+#define B2056_SYN_RESERVED_ADDR3 0x03
+#define B2056_SYN_RESERVED_ADDR4 0x04
+#define B2056_SYN_RESERVED_ADDR5 0x05
+#define B2056_SYN_RESERVED_ADDR6 0x06
+#define B2056_SYN_RESERVED_ADDR7 0x07
+#define B2056_SYN_COM_CTRL 0x08
+#define B2056_SYN_COM_PU 0x09
+#define B2056_SYN_COM_OVR 0x0A
+#define B2056_SYN_COM_RESET 0x0B
+#define B2056_SYN_COM_RCAL 0x0C
+#define B2056_SYN_COM_RC_RXLPF 0x0D
+#define B2056_SYN_COM_RC_TXLPF 0x0E
+#define B2056_SYN_COM_RC_RXHPF 0x0F
+#define B2056_SYN_RESERVED_ADDR16 0x10
+#define B2056_SYN_RESERVED_ADDR17 0x11
+#define B2056_SYN_RESERVED_ADDR18 0x12
+#define B2056_SYN_RESERVED_ADDR19 0x13
+#define B2056_SYN_RESERVED_ADDR20 0x14
+#define B2056_SYN_RESERVED_ADDR21 0x15
+#define B2056_SYN_RESERVED_ADDR22 0x16
+#define B2056_SYN_RESERVED_ADDR23 0x17
+#define B2056_SYN_RESERVED_ADDR24 0x18
+#define B2056_SYN_RESERVED_ADDR25 0x19
+#define B2056_SYN_RESERVED_ADDR26 0x1A
+#define B2056_SYN_RESERVED_ADDR27 0x1B
+#define B2056_SYN_RESERVED_ADDR28 0x1C
+#define B2056_SYN_RESERVED_ADDR29 0x1D
+#define B2056_SYN_RESERVED_ADDR30 0x1E
+#define B2056_SYN_RESERVED_ADDR31 0x1F
+#define B2056_SYN_GPIO_MASTER1 0x20
+#define B2056_SYN_GPIO_MASTER2 0x21
+#define B2056_SYN_TOPBIAS_MASTER 0x22
+#define B2056_SYN_TOPBIAS_RCAL 0x23
+#define B2056_SYN_AFEREG 0x24
+#define B2056_SYN_TEMPPROCSENSE 0x25
+#define B2056_SYN_TEMPPROCSENSEIDAC 0x26
+#define B2056_SYN_TEMPPROCSENSERCAL 0x27
+#define B2056_SYN_LPO 0x28
+#define B2056_SYN_VDDCAL_MASTER 0x29
+#define B2056_SYN_VDDCAL_IDAC 0x2A
+#define B2056_SYN_VDDCAL_STATUS 0x2B
+#define B2056_SYN_RCAL_MASTER 0x2C
+#define B2056_SYN_RCAL_CODE_OUT 0x2D
+#define B2056_SYN_RCCAL_CTRL0 0x2E
+#define B2056_SYN_RCCAL_CTRL1 0x2F
+#define B2056_SYN_RCCAL_CTRL2 0x30
+#define B2056_SYN_RCCAL_CTRL3 0x31
+#define B2056_SYN_RCCAL_CTRL4 0x32
+#define B2056_SYN_RCCAL_CTRL5 0x33
+#define B2056_SYN_RCCAL_CTRL6 0x34
+#define B2056_SYN_RCCAL_CTRL7 0x35
+#define B2056_SYN_RCCAL_CTRL8 0x36
+#define B2056_SYN_RCCAL_CTRL9 0x37
+#define B2056_SYN_RCCAL_CTRL10 0x38
+#define B2056_SYN_RCCAL_CTRL11 0x39
+#define B2056_SYN_ZCAL_SPARE1 0x3A
+#define B2056_SYN_ZCAL_SPARE2 0x3B
+#define B2056_SYN_PLL_MAST1 0x3C
+#define B2056_SYN_PLL_MAST2 0x3D
+#define B2056_SYN_PLL_MAST3 0x3E
+#define B2056_SYN_PLL_BIAS_RESET 0x3F
+#define B2056_SYN_PLL_XTAL0 0x40
+#define B2056_SYN_PLL_XTAL1 0x41
+#define B2056_SYN_PLL_XTAL3 0x42
+#define B2056_SYN_PLL_XTAL4 0x43
+#define B2056_SYN_PLL_XTAL5 0x44
+#define B2056_SYN_PLL_XTAL6 0x45
+#define B2056_SYN_PLL_REFDIV 0x46
+#define B2056_SYN_PLL_PFD 0x47
+#define B2056_SYN_PLL_CP1 0x48
+#define B2056_SYN_PLL_CP2 0x49
+#define B2056_SYN_PLL_CP3 0x4A
+#define B2056_SYN_PLL_LOOPFILTER1 0x4B
+#define B2056_SYN_PLL_LOOPFILTER2 0x4C
+#define B2056_SYN_PLL_LOOPFILTER3 0x4D
+#define B2056_SYN_PLL_LOOPFILTER4 0x4E
+#define B2056_SYN_PLL_LOOPFILTER5 0x4F
+#define B2056_SYN_PLL_MMD1 0x50
+#define B2056_SYN_PLL_MMD2 0x51
+#define B2056_SYN_PLL_VCO1 0x52
+#define B2056_SYN_PLL_VCO2 0x53
+#define B2056_SYN_PLL_MONITOR1 0x54
+#define B2056_SYN_PLL_MONITOR2 0x55
+#define B2056_SYN_PLL_VCOCAL1 0x56
+#define B2056_SYN_PLL_VCOCAL2 0x57
+#define B2056_SYN_PLL_VCOCAL4 0x58
+#define B2056_SYN_PLL_VCOCAL5 0x59
+#define B2056_SYN_PLL_VCOCAL6 0x5A
+#define B2056_SYN_PLL_VCOCAL7 0x5B
+#define B2056_SYN_PLL_VCOCAL8 0x5C
+#define B2056_SYN_PLL_VCOCAL9 0x5D
+#define B2056_SYN_PLL_VCOCAL10 0x5E
+#define B2056_SYN_PLL_VCOCAL11 0x5F
+#define B2056_SYN_PLL_VCOCAL12 0x60
+#define B2056_SYN_PLL_VCOCAL13 0x61
+#define B2056_SYN_PLL_VREG 0x62
+#define B2056_SYN_PLL_STATUS1 0x63
+#define B2056_SYN_PLL_STATUS2 0x64
+#define B2056_SYN_PLL_STATUS3 0x65
+#define B2056_SYN_LOGEN_PU0 0x66
+#define B2056_SYN_LOGEN_PU1 0x67
+#define B2056_SYN_LOGEN_PU2 0x68
+#define B2056_SYN_LOGEN_PU3 0x69
+#define B2056_SYN_LOGEN_PU5 0x6A
+#define B2056_SYN_LOGEN_PU6 0x6B
+#define B2056_SYN_LOGEN_PU7 0x6C
+#define B2056_SYN_LOGEN_PU8 0x6D
+#define B2056_SYN_LOGEN_BIAS_RESET 0x6E
+#define B2056_SYN_LOGEN_RCCR1 0x6F
+#define B2056_SYN_LOGEN_VCOBUF1 0x70
+#define B2056_SYN_LOGEN_MIXER1 0x71
+#define B2056_SYN_LOGEN_MIXER2 0x72
+#define B2056_SYN_LOGEN_BUF1 0x73
+#define B2056_SYN_LOGENBUF2 0x74
+#define B2056_SYN_LOGEN_BUF3 0x75
+#define B2056_SYN_LOGEN_BUF4 0x76
+#define B2056_SYN_LOGEN_DIV1 0x77
+#define B2056_SYN_LOGEN_DIV2 0x78
+#define B2056_SYN_LOGEN_DIV3 0x79
+#define B2056_SYN_LOGEN_ACL1 0x7A
+#define B2056_SYN_LOGEN_ACL2 0x7B
+#define B2056_SYN_LOGEN_ACL3 0x7C
+#define B2056_SYN_LOGEN_ACL4 0x7D
+#define B2056_SYN_LOGEN_ACL5 0x7E
+#define B2056_SYN_LOGEN_ACL6 0x7F
+#define B2056_SYN_LOGEN_ACLOUT 0x80
+#define B2056_SYN_LOGEN_ACLCAL1 0x81
+#define B2056_SYN_LOGEN_ACLCAL2 0x82
+#define B2056_SYN_LOGEN_ACLCAL3 0x83
+#define B2056_SYN_CALEN 0x84
+#define B2056_SYN_LOGEN_PEAKDET1 0x85
+#define B2056_SYN_LOGEN_CORE_ACL_OVR 0x86
+#define B2056_SYN_LOGEN_RX_DIFF_ACL_OVR 0x87
+#define B2056_SYN_LOGEN_TX_DIFF_ACL_OVR 0x88
+#define B2056_SYN_LOGEN_RX_CMOS_ACL_OVR 0x89
+#define B2056_SYN_LOGEN_TX_CMOS_ACL_OVR 0x8A
+#define B2056_SYN_LOGEN_VCOBUF2 0x8B
+#define B2056_SYN_LOGEN_MIXER3 0x8C
+#define B2056_SYN_LOGEN_BUF5 0x8D
+#define B2056_SYN_LOGEN_BUF6 0x8E
+#define B2056_SYN_LOGEN_CBUFRX1 0x8F
+#define B2056_SYN_LOGEN_CBUFRX2 0x90
+#define B2056_SYN_LOGEN_CBUFRX3 0x91
+#define B2056_SYN_LOGEN_CBUFRX4 0x92
+#define B2056_SYN_LOGEN_CBUFTX1 0x93
+#define B2056_SYN_LOGEN_CBUFTX2 0x94
+#define B2056_SYN_LOGEN_CBUFTX3 0x95
+#define B2056_SYN_LOGEN_CBUFTX4 0x96
+#define B2056_SYN_LOGEN_CMOSRX1 0x97
+#define B2056_SYN_LOGEN_CMOSRX2 0x98
+#define B2056_SYN_LOGEN_CMOSRX3 0x99
+#define B2056_SYN_LOGEN_CMOSRX4 0x9A
+#define B2056_SYN_LOGEN_CMOSTX1 0x9B
+#define B2056_SYN_LOGEN_CMOSTX2 0x9C
+#define B2056_SYN_LOGEN_CMOSTX3 0x9D
+#define B2056_SYN_LOGEN_CMOSTX4 0x9E
+#define B2056_SYN_LOGEN_VCOBUF2_OVRVAL 0x9F
+#define B2056_SYN_LOGEN_MIXER3_OVRVAL 0xA0
+#define B2056_SYN_LOGEN_BUF5_OVRVAL 0xA1
+#define B2056_SYN_LOGEN_BUF6_OVRVAL 0xA2
+#define B2056_SYN_LOGEN_CBUFRX1_OVRVAL 0xA3
+#define B2056_SYN_LOGEN_CBUFRX2_OVRVAL 0xA4
+#define B2056_SYN_LOGEN_CBUFRX3_OVRVAL 0xA5
+#define B2056_SYN_LOGEN_CBUFRX4_OVRVAL 0xA6
+#define B2056_SYN_LOGEN_CBUFTX1_OVRVAL 0xA7
+#define B2056_SYN_LOGEN_CBUFTX2_OVRVAL 0xA8
+#define B2056_SYN_LOGEN_CBUFTX3_OVRVAL 0xA9
+#define B2056_SYN_LOGEN_CBUFTX4_OVRVAL 0xAA
+#define B2056_SYN_LOGEN_CMOSRX1_OVRVAL 0xAB
+#define B2056_SYN_LOGEN_CMOSRX2_OVRVAL 0xAC
+#define B2056_SYN_LOGEN_CMOSRX3_OVRVAL 0xAD
+#define B2056_SYN_LOGEN_CMOSRX4_OVRVAL 0xAE
+#define B2056_SYN_LOGEN_CMOSTX1_OVRVAL 0xAF
+#define B2056_SYN_LOGEN_CMOSTX2_OVRVAL 0xB0
+#define B2056_SYN_LOGEN_CMOSTX3_OVRVAL 0xB1
+#define B2056_SYN_LOGEN_CMOSTX4_OVRVAL 0xB2
+#define B2056_SYN_LOGEN_ACL_WAITCNT 0xB3
+#define B2056_SYN_LOGEN_CORE_CALVALID 0xB4
+#define B2056_SYN_LOGEN_RX_CMOS_CALVALID 0xB5
+#define B2056_SYN_LOGEN_TX_CMOS_VALID 0xB6
+
+#define B2056_TX_RESERVED_ADDR0 0x00
+#define B2056_TX_IDCODE 0x01
+#define B2056_TX_RESERVED_ADDR2 0x02
+#define B2056_TX_RESERVED_ADDR3 0x03
+#define B2056_TX_RESERVED_ADDR4 0x04
+#define B2056_TX_RESERVED_ADDR5 0x05
+#define B2056_TX_RESERVED_ADDR6 0x06
+#define B2056_TX_RESERVED_ADDR7 0x07
+#define B2056_TX_COM_CTRL 0x08
+#define B2056_TX_COM_PU 0x09
+#define B2056_TX_COM_OVR 0x0A
+#define B2056_TX_COM_RESET 0x0B
+#define B2056_TX_COM_RCAL 0x0C
+#define B2056_TX_COM_RC_RXLPF 0x0D
+#define B2056_TX_COM_RC_TXLPF 0x0E
+#define B2056_TX_COM_RC_RXHPF 0x0F
+#define B2056_TX_RESERVED_ADDR16 0x10
+#define B2056_TX_RESERVED_ADDR17 0x11
+#define B2056_TX_RESERVED_ADDR18 0x12
+#define B2056_TX_RESERVED_ADDR19 0x13
+#define B2056_TX_RESERVED_ADDR20 0x14
+#define B2056_TX_RESERVED_ADDR21 0x15
+#define B2056_TX_RESERVED_ADDR22 0x16
+#define B2056_TX_RESERVED_ADDR23 0x17
+#define B2056_TX_RESERVED_ADDR24 0x18
+#define B2056_TX_RESERVED_ADDR25 0x19
+#define B2056_TX_RESERVED_ADDR26 0x1A
+#define B2056_TX_RESERVED_ADDR27 0x1B
+#define B2056_TX_RESERVED_ADDR28 0x1C
+#define B2056_TX_RESERVED_ADDR29 0x1D
+#define B2056_TX_RESERVED_ADDR30 0x1E
+#define B2056_TX_RESERVED_ADDR31 0x1F
+#define B2056_TX_IQCAL_GAIN_BW 0x20
+#define B2056_TX_LOFT_FINE_I 0x21
+#define B2056_TX_LOFT_FINE_Q 0x22
+#define B2056_TX_LOFT_COARSE_I 0x23
+#define B2056_TX_LOFT_COARSE_Q 0x24
+#define B2056_TX_TX_COM_MASTER1 0x25
+#define B2056_TX_TX_COM_MASTER2 0x26
+#define B2056_TX_RXIQCAL_TXMUX 0x27
+#define B2056_TX_TX_SSI_MASTER 0x28
+#define B2056_TX_IQCAL_VCM_HG 0x29
+#define B2056_TX_IQCAL_IDAC 0x2A
+#define B2056_TX_TSSI_VCM 0x2B
+#define B2056_TX_TX_AMP_DET 0x2C
+#define B2056_TX_TX_SSI_MUX 0x2D
+#define B2056_TX_TSSIA 0x2E
+#define B2056_TX_TSSIG 0x2F
+#define B2056_TX_TSSI_MISC1 0x30
+#define B2056_TX_TSSI_MISC2 0x31
+#define B2056_TX_TSSI_MISC3 0x32
+#define B2056_TX_PA_SPARE1 0x33
+#define B2056_TX_PA_SPARE2 0x34
+#define B2056_TX_INTPAA_MASTER 0x35
+#define B2056_TX_INTPAA_GAIN 0x36
+#define B2056_TX_INTPAA_BOOST_TUNE 0x37
+#define B2056_TX_INTPAA_IAUX_STAT 0x38
+#define B2056_TX_INTPAA_IAUX_DYN 0x39
+#define B2056_TX_INTPAA_IMAIN_STAT 0x3A
+#define B2056_TX_INTPAA_IMAIN_DYN 0x3B
+#define B2056_TX_INTPAA_CASCBIAS 0x3C
+#define B2056_TX_INTPAA_PASLOPE 0x3D
+#define B2056_TX_INTPAA_PA_MISC 0x3E
+#define B2056_TX_INTPAG_MASTER 0x3F
+#define B2056_TX_INTPAG_GAIN 0x40
+#define B2056_TX_INTPAG_BOOST_TUNE 0x41
+#define B2056_TX_INTPAG_IAUX_STAT 0x42
+#define B2056_TX_INTPAG_IAUX_DYN 0x43
+#define B2056_TX_INTPAG_IMAIN_STAT 0x44
+#define B2056_TX_INTPAG_IMAIN_DYN 0x45
+#define B2056_TX_INTPAG_CASCBIAS 0x46
+#define B2056_TX_INTPAG_PASLOPE 0x47
+#define B2056_TX_INTPAG_PA_MISC 0x48
+#define B2056_TX_PADA_MASTER 0x49
+#define B2056_TX_PADA_IDAC 0x4A
+#define B2056_TX_PADA_CASCBIAS 0x4B
+#define B2056_TX_PADA_GAIN 0x4C
+#define B2056_TX_PADA_BOOST_TUNE 0x4D
+#define B2056_TX_PADA_SLOPE 0x4E
+#define B2056_TX_PADG_MASTER 0x4F
+#define B2056_TX_PADG_IDAC 0x50
+#define B2056_TX_PADG_CASCBIAS 0x51
+#define B2056_TX_PADG_GAIN 0x52
+#define B2056_TX_PADG_BOOST_TUNE 0x53
+#define B2056_TX_PADG_SLOPE 0x54
+#define B2056_TX_PGAA_MASTER 0x55
+#define B2056_TX_PGAA_IDAC 0x56
+#define B2056_TX_PGAA_GAIN 0x57
+#define B2056_TX_PGAA_BOOST_TUNE 0x58
+#define B2056_TX_PGAA_SLOPE 0x59
+#define B2056_TX_PGAA_MISC 0x5A
+#define B2056_TX_PGAG_MASTER 0x5B
+#define B2056_TX_PGAG_IDAC 0x5C
+#define B2056_TX_PGAG_GAIN 0x5D
+#define B2056_TX_PGAG_BOOST_TUNE 0x5E
+#define B2056_TX_PGAG_SLOPE 0x5F
+#define B2056_TX_PGAG_MISC 0x60
+#define B2056_TX_MIXA_MASTER 0x61
+#define B2056_TX_MIXA_BOOST_TUNE 0x62
+#define B2056_TX_MIXG 0x63
+#define B2056_TX_MIXG_BOOST_TUNE 0x64
+#define B2056_TX_BB_GM_MASTER 0x65
+#define B2056_TX_GMBB_GM 0x66
+#define B2056_TX_GMBB_IDAC 0x67
+#define B2056_TX_TXLPF_MASTER 0x68
+#define B2056_TX_TXLPF_RCCAL 0x69
+#define B2056_TX_TXLPF_RCCAL_OFF0 0x6A
+#define B2056_TX_TXLPF_RCCAL_OFF1 0x6B
+#define B2056_TX_TXLPF_RCCAL_OFF2 0x6C
+#define B2056_TX_TXLPF_RCCAL_OFF3 0x6D
+#define B2056_TX_TXLPF_RCCAL_OFF4 0x6E
+#define B2056_TX_TXLPF_RCCAL_OFF5 0x6F
+#define B2056_TX_TXLPF_RCCAL_OFF6 0x70
+#define B2056_TX_TXLPF_BW 0x71
+#define B2056_TX_TXLPF_GAIN 0x72
+#define B2056_TX_TXLPF_IDAC 0x73
+#define B2056_TX_TXLPF_IDAC_0 0x74
+#define B2056_TX_TXLPF_IDAC_1 0x75
+#define B2056_TX_TXLPF_IDAC_2 0x76
+#define B2056_TX_TXLPF_IDAC_3 0x77
+#define B2056_TX_TXLPF_IDAC_4 0x78
+#define B2056_TX_TXLPF_IDAC_5 0x79
+#define B2056_TX_TXLPF_IDAC_6 0x7A
+#define B2056_TX_TXLPF_OPAMP_IDAC 0x7B
+#define B2056_TX_TXLPF_MISC 0x7C
+#define B2056_TX_TXSPARE1 0x7D
+#define B2056_TX_TXSPARE2 0x7E
+#define B2056_TX_TXSPARE3 0x7F
+#define B2056_TX_TXSPARE4 0x80
+#define B2056_TX_TXSPARE5 0x81
+#define B2056_TX_TXSPARE6 0x82
+#define B2056_TX_TXSPARE7 0x83
+#define B2056_TX_TXSPARE8 0x84
+#define B2056_TX_TXSPARE9 0x85
+#define B2056_TX_TXSPARE10 0x86
+#define B2056_TX_TXSPARE11 0x87
+#define B2056_TX_TXSPARE12 0x88
+#define B2056_TX_TXSPARE13 0x89
+#define B2056_TX_TXSPARE14 0x8A
+#define B2056_TX_TXSPARE15 0x8B
+#define B2056_TX_TXSPARE16 0x8C
+#define B2056_TX_STATUS_INTPA_GAIN 0x8D
+#define B2056_TX_STATUS_PAD_GAIN 0x8E
+#define B2056_TX_STATUS_PGA_GAIN 0x8F
+#define B2056_TX_STATUS_GM_TXLPF_GAIN 0x90
+#define B2056_TX_STATUS_TXLPF_BW 0x91
+#define B2056_TX_STATUS_TXLPF_RC 0x92
+#define B2056_TX_GMBB_IDAC0 0x93
+#define B2056_TX_GMBB_IDAC1 0x94
+#define B2056_TX_GMBB_IDAC2 0x95
+#define B2056_TX_GMBB_IDAC3 0x96
+#define B2056_TX_GMBB_IDAC4 0x97
+#define B2056_TX_GMBB_IDAC5 0x98
+#define B2056_TX_GMBB_IDAC6 0x99
+#define B2056_TX_GMBB_IDAC7 0x9A
+
+#define B2056_RX_RESERVED_ADDR0 0x00
+#define B2056_RX_IDCODE 0x01
+#define B2056_RX_RESERVED_ADDR2 0x02
+#define B2056_RX_RESERVED_ADDR3 0x03
+#define B2056_RX_RESERVED_ADDR4 0x04
+#define B2056_RX_RESERVED_ADDR5 0x05
+#define B2056_RX_RESERVED_ADDR6 0x06
+#define B2056_RX_RESERVED_ADDR7 0x07
+#define B2056_RX_COM_CTRL 0x08
+#define B2056_RX_COM_PU 0x09
+#define B2056_RX_COM_OVR 0x0A
+#define B2056_RX_COM_RESET 0x0B
+#define B2056_RX_COM_RCAL 0x0C
+#define B2056_RX_COM_RC_RXLPF 0x0D
+#define B2056_RX_COM_RC_TXLPF 0x0E
+#define B2056_RX_COM_RC_RXHPF 0x0F
+#define B2056_RX_RESERVED_ADDR16 0x10
+#define B2056_RX_RESERVED_ADDR17 0x11
+#define B2056_RX_RESERVED_ADDR18 0x12
+#define B2056_RX_RESERVED_ADDR19 0x13
+#define B2056_RX_RESERVED_ADDR20 0x14
+#define B2056_RX_RESERVED_ADDR21 0x15
+#define B2056_RX_RESERVED_ADDR22 0x16
+#define B2056_RX_RESERVED_ADDR23 0x17
+#define B2056_RX_RESERVED_ADDR24 0x18
+#define B2056_RX_RESERVED_ADDR25 0x19
+#define B2056_RX_RESERVED_ADDR26 0x1A
+#define B2056_RX_RESERVED_ADDR27 0x1B
+#define B2056_RX_RESERVED_ADDR28 0x1C
+#define B2056_RX_RESERVED_ADDR29 0x1D
+#define B2056_RX_RESERVED_ADDR30 0x1E
+#define B2056_RX_RESERVED_ADDR31 0x1F
+#define B2056_RX_RXIQCAL_RXMUX 0x20
+#define B2056_RX_RSSI_PU 0x21
+#define B2056_RX_RSSI_SEL 0x22
+#define B2056_RX_RSSI_GAIN 0x23
+#define B2056_RX_RSSI_NB_IDAC 0x24
+#define B2056_RX_RSSI_WB2I_IDAC_1 0x25
+#define B2056_RX_RSSI_WB2I_IDAC_2 0x26
+#define B2056_RX_RSSI_WB2Q_IDAC_1 0x27
+#define B2056_RX_RSSI_WB2Q_IDAC_2 0x28
+#define B2056_RX_RSSI_POLE 0x29
+#define B2056_RX_RSSI_WB1_IDAC 0x2A
+#define B2056_RX_RSSI_MISC 0x2B
+#define B2056_RX_LNAA_MASTER 0x2C
+#define B2056_RX_LNAA_TUNE 0x2D
+#define B2056_RX_LNAA_GAIN 0x2E
+#define B2056_RX_LNA_A_SLOPE 0x2F
+#define B2056_RX_BIASPOLE_LNAA1_IDAC 0x30
+#define B2056_RX_LNAA2_IDAC 0x31
+#define B2056_RX_LNA1A_MISC 0x32
+#define B2056_RX_LNAG_MASTER 0x33
+#define B2056_RX_LNAG_TUNE 0x34
+#define B2056_RX_LNAG_GAIN 0x35
+#define B2056_RX_LNA_G_SLOPE 0x36
+#define B2056_RX_BIASPOLE_LNAG1_IDAC 0x37
+#define B2056_RX_LNAG2_IDAC 0x38
+#define B2056_RX_LNA1G_MISC 0x39
+#define B2056_RX_MIXA_MASTER 0x3A
+#define B2056_RX_MIXA_VCM 0x3B
+#define B2056_RX_MIXA_CTRLPTAT 0x3C
+#define B2056_RX_MIXA_LOB_BIAS 0x3D
+#define B2056_RX_MIXA_CORE_IDAC 0x3E
+#define B2056_RX_MIXA_CMFB_IDAC 0x3F
+#define B2056_RX_MIXA_BIAS_AUX 0x40
+#define B2056_RX_MIXA_BIAS_MAIN 0x41
+#define B2056_RX_MIXA_BIAS_MISC 0x42
+#define B2056_RX_MIXA_MAST_BIAS 0x43
+#define B2056_RX_MIXG_MASTER 0x44
+#define B2056_RX_MIXG_VCM 0x45
+#define B2056_RX_MIXG_CTRLPTAT 0x46
+#define B2056_RX_MIXG_LOB_BIAS 0x47
+#define B2056_RX_MIXG_CORE_IDAC 0x48
+#define B2056_RX_MIXG_CMFB_IDAC 0x49
+#define B2056_RX_MIXG_BIAS_AUX 0x4A
+#define B2056_RX_MIXG_BIAS_MAIN 0x4B
+#define B2056_RX_MIXG_BIAS_MISC 0x4C
+#define B2056_RX_MIXG_MAST_BIAS 0x4D
+#define B2056_RX_TIA_MASTER 0x4E
+#define B2056_RX_TIA_IOPAMP 0x4F
+#define B2056_RX_TIA_QOPAMP 0x50
+#define B2056_RX_TIA_IMISC 0x51
+#define B2056_RX_TIA_QMISC 0x52
+#define B2056_RX_TIA_GAIN 0x53
+#define B2056_RX_TIA_SPARE1 0x54
+#define B2056_RX_TIA_SPARE2 0x55
+#define B2056_RX_BB_LPF_MASTER 0x56
+#define B2056_RX_AACI_MASTER 0x57
+#define B2056_RX_RXLPF_IDAC 0x58
+#define B2056_RX_RXLPF_OPAMPBIAS_LOWQ 0x59
+#define B2056_RX_RXLPF_OPAMPBIAS_HIGHQ 0x5A
+#define B2056_RX_RXLPF_BIAS_DCCANCEL 0x5B
+#define B2056_RX_RXLPF_OUTVCM 0x5C
+#define B2056_RX_RXLPF_INVCM_BODY 0x5D
+#define B2056_RX_RXLPF_CC_OP 0x5E
+#define B2056_RX_RXLPF_GAIN 0x5F
+#define B2056_RX_RXLPF_Q_BW 0x60
+#define B2056_RX_RXLPF_HP_CORNER_BW 0x61
+#define B2056_RX_RXLPF_RCCAL_HPC 0x62
+#define B2056_RX_RXHPF_OFF0 0x63
+#define B2056_RX_RXHPF_OFF1 0x64
+#define B2056_RX_RXHPF_OFF2 0x65
+#define B2056_RX_RXHPF_OFF3 0x66
+#define B2056_RX_RXHPF_OFF4 0x67
+#define B2056_RX_RXHPF_OFF5 0x68
+#define B2056_RX_RXHPF_OFF6 0x69
+#define B2056_RX_RXHPF_OFF7 0x6A
+#define B2056_RX_RXLPF_RCCAL_LPC 0x6B
+#define B2056_RX_RXLPF_OFF_0 0x6C
+#define B2056_RX_RXLPF_OFF_1 0x6D
+#define B2056_RX_RXLPF_OFF_2 0x6E
+#define B2056_RX_RXLPF_OFF_3 0x6F
+#define B2056_RX_RXLPF_OFF_4 0x70
+#define B2056_RX_UNUSED 0x71
+#define B2056_RX_VGA_MASTER 0x72
+#define B2056_RX_VGA_BIAS 0x73
+#define B2056_RX_VGA_BIAS_DCCANCEL 0x74
+#define B2056_RX_VGA_GAIN 0x75
+#define B2056_RX_VGA_HP_CORNER_BW 0x76
+#define B2056_RX_VGABUF_BIAS 0x77
+#define B2056_RX_VGABUF_GAIN_BW 0x78
+#define B2056_RX_TXFBMIX_A 0x79
+#define B2056_RX_TXFBMIX_G 0x7A
+#define B2056_RX_RXSPARE1 0x7B
+#define B2056_RX_RXSPARE2 0x7C
+#define B2056_RX_RXSPARE3 0x7D
+#define B2056_RX_RXSPARE4 0x7E
+#define B2056_RX_RXSPARE5 0x7F
+#define B2056_RX_RXSPARE6 0x80
+#define B2056_RX_RXSPARE7 0x81
+#define B2056_RX_RXSPARE8 0x82
+#define B2056_RX_RXSPARE9 0x83
+#define B2056_RX_RXSPARE10 0x84
+#define B2056_RX_RXSPARE11 0x85
+#define B2056_RX_RXSPARE12 0x86
+#define B2056_RX_RXSPARE13 0x87
+#define B2056_RX_RXSPARE14 0x88
+#define B2056_RX_RXSPARE15 0x89
+#define B2056_RX_RXSPARE16 0x8A
+#define B2056_RX_STATUS_LNAA_GAIN 0x8B
+#define B2056_RX_STATUS_LNAG_GAIN 0x8C
+#define B2056_RX_STATUS_MIXTIA_GAIN 0x8D
+#define B2056_RX_STATUS_RXLPF_GAIN 0x8E
+#define B2056_RX_STATUS_VGA_BUF_GAIN 0x8F
+#define B2056_RX_STATUS_RXLPF_Q 0x90
+#define B2056_RX_STATUS_RXLPF_BUF_BW 0x91
+#define B2056_RX_STATUS_RXLPF_VGA_HPC 0x92
+#define B2056_RX_STATUS_RXLPF_RC 0x93
+#define B2056_RX_STATUS_HPC_RC 0x94
+
+#define B2056_LNA1_A_PU 0x01
+#define B2056_LNA2_A_PU 0x02
+#define B2056_LNA1_G_PU 0x01
+#define B2056_LNA2_G_PU 0x02
+#define B2056_MIXA_PU_I 0x01
+#define B2056_MIXA_PU_Q 0x02
+#define B2056_MIXA_PU_GM 0x10
+#define B2056_MIXG_PU_I 0x01
+#define B2056_MIXG_PU_Q 0x02
+#define B2056_MIXG_PU_GM 0x10
+#define B2056_TIA_PU 0x01
+#define B2056_BB_LPF_PU 0x20
+#define B2056_W1_PU 0x02
+#define B2056_W2_PU 0x04
+#define B2056_NB_PU 0x08
+#define B2056_RSSI_W1_SEL 0x02
+#define B2056_RSSI_W2_SEL 0x04
+#define B2056_RSSI_NB_SEL 0x08
+#define B2056_VCM_MASK 0x1C
+#define B2056_RSSI_VCM_SHIFT 0x02
+
+#define B2056_SYN (0x0 << 12)
+#define B2056_TX0 (0x2 << 12)
+#define B2056_TX1 (0x3 << 12)
+#define B2056_RX0 (0x6 << 12)
+#define B2056_RX1 (0x7 << 12)
+#define B2056_ALLTX (0xE << 12)
+#define B2056_ALLRX (0xF << 12)
+
+#define B2056_SYN_RESERVED_ADDR0 0x00
+#define B2056_SYN_IDCODE 0x01
+#define B2056_SYN_RESERVED_ADDR2 0x02
+#define B2056_SYN_RESERVED_ADDR3 0x03
+#define B2056_SYN_RESERVED_ADDR4 0x04
+#define B2056_SYN_RESERVED_ADDR5 0x05
+#define B2056_SYN_RESERVED_ADDR6 0x06
+#define B2056_SYN_RESERVED_ADDR7 0x07
+#define B2056_SYN_COM_CTRL 0x08
+#define B2056_SYN_COM_PU 0x09
+#define B2056_SYN_COM_OVR 0x0A
+#define B2056_SYN_COM_RESET 0x0B
+#define B2056_SYN_COM_RCAL 0x0C
+#define B2056_SYN_COM_RC_RXLPF 0x0D
+#define B2056_SYN_COM_RC_TXLPF 0x0E
+#define B2056_SYN_COM_RC_RXHPF 0x0F
+#define B2056_SYN_RESERVED_ADDR16 0x10
+#define B2056_SYN_RESERVED_ADDR17 0x11
+#define B2056_SYN_RESERVED_ADDR18 0x12
+#define B2056_SYN_RESERVED_ADDR19 0x13
+#define B2056_SYN_RESERVED_ADDR20 0x14
+#define B2056_SYN_RESERVED_ADDR21 0x15
+#define B2056_SYN_RESERVED_ADDR22 0x16
+#define B2056_SYN_RESERVED_ADDR23 0x17
+#define B2056_SYN_RESERVED_ADDR24 0x18
+#define B2056_SYN_RESERVED_ADDR25 0x19
+#define B2056_SYN_RESERVED_ADDR26 0x1A
+#define B2056_SYN_RESERVED_ADDR27 0x1B
+#define B2056_SYN_RESERVED_ADDR28 0x1C
+#define B2056_SYN_RESERVED_ADDR29 0x1D
+#define B2056_SYN_RESERVED_ADDR30 0x1E
+#define B2056_SYN_RESERVED_ADDR31 0x1F
+#define B2056_SYN_GPIO_MASTER1 0x20
+#define B2056_SYN_GPIO_MASTER2 0x21
+#define B2056_SYN_TOPBIAS_MASTER 0x22
+#define B2056_SYN_TOPBIAS_RCAL 0x23
+#define B2056_SYN_AFEREG 0x24
+#define B2056_SYN_TEMPPROCSENSE 0x25
+#define B2056_SYN_TEMPPROCSENSEIDAC 0x26
+#define B2056_SYN_TEMPPROCSENSERCAL 0x27
+#define B2056_SYN_LPO 0x28
+#define B2056_SYN_VDDCAL_MASTER 0x29
+#define B2056_SYN_VDDCAL_IDAC 0x2A
+#define B2056_SYN_VDDCAL_STATUS 0x2B
+#define B2056_SYN_RCAL_MASTER 0x2C
+#define B2056_SYN_RCAL_CODE_OUT 0x2D
+#define B2056_SYN_RCCAL_CTRL0 0x2E
+#define B2056_SYN_RCCAL_CTRL1 0x2F
+#define B2056_SYN_RCCAL_CTRL2 0x30
+#define B2056_SYN_RCCAL_CTRL3 0x31
+#define B2056_SYN_RCCAL_CTRL4 0x32
+#define B2056_SYN_RCCAL_CTRL5 0x33
+#define B2056_SYN_RCCAL_CTRL6 0x34
+#define B2056_SYN_RCCAL_CTRL7 0x35
+#define B2056_SYN_RCCAL_CTRL8 0x36
+#define B2056_SYN_RCCAL_CTRL9 0x37
+#define B2056_SYN_RCCAL_CTRL10 0x38
+#define B2056_SYN_RCCAL_CTRL11 0x39
+#define B2056_SYN_ZCAL_SPARE1 0x3A
+#define B2056_SYN_ZCAL_SPARE2 0x3B
+#define B2056_SYN_PLL_MAST1 0x3C
+#define B2056_SYN_PLL_MAST2 0x3D
+#define B2056_SYN_PLL_MAST3 0x3E
+#define B2056_SYN_PLL_BIAS_RESET 0x3F
+#define B2056_SYN_PLL_XTAL0 0x40
+#define B2056_SYN_PLL_XTAL1 0x41
+#define B2056_SYN_PLL_XTAL3 0x42
+#define B2056_SYN_PLL_XTAL4 0x43
+#define B2056_SYN_PLL_XTAL5 0x44
+#define B2056_SYN_PLL_XTAL6 0x45
+#define B2056_SYN_PLL_REFDIV 0x46
+#define B2056_SYN_PLL_PFD 0x47
+#define B2056_SYN_PLL_CP1 0x48
+#define B2056_SYN_PLL_CP2 0x49
+#define B2056_SYN_PLL_CP3 0x4A
+#define B2056_SYN_PLL_LOOPFILTER1 0x4B
+#define B2056_SYN_PLL_LOOPFILTER2 0x4C
+#define B2056_SYN_PLL_LOOPFILTER3 0x4D
+#define B2056_SYN_PLL_LOOPFILTER4 0x4E
+#define B2056_SYN_PLL_LOOPFILTER5 0x4F
+#define B2056_SYN_PLL_MMD1 0x50
+#define B2056_SYN_PLL_MMD2 0x51
+#define B2056_SYN_PLL_VCO1 0x52
+#define B2056_SYN_PLL_VCO2 0x53
+#define B2056_SYN_PLL_MONITOR1 0x54
+#define B2056_SYN_PLL_MONITOR2 0x55
+#define B2056_SYN_PLL_VCOCAL1 0x56
+#define B2056_SYN_PLL_VCOCAL2 0x57
+#define B2056_SYN_PLL_VCOCAL4 0x58
+#define B2056_SYN_PLL_VCOCAL5 0x59
+#define B2056_SYN_PLL_VCOCAL6 0x5A
+#define B2056_SYN_PLL_VCOCAL7 0x5B
+#define B2056_SYN_PLL_VCOCAL8 0x5C
+#define B2056_SYN_PLL_VCOCAL9 0x5D
+#define B2056_SYN_PLL_VCOCAL10 0x5E
+#define B2056_SYN_PLL_VCOCAL11 0x5F
+#define B2056_SYN_PLL_VCOCAL12 0x60
+#define B2056_SYN_PLL_VCOCAL13 0x61
+#define B2056_SYN_PLL_VREG 0x62
+#define B2056_SYN_PLL_STATUS1 0x63
+#define B2056_SYN_PLL_STATUS2 0x64
+#define B2056_SYN_PLL_STATUS3 0x65
+#define B2056_SYN_LOGEN_PU0 0x66
+#define B2056_SYN_LOGEN_PU1 0x67
+#define B2056_SYN_LOGEN_PU2 0x68
+#define B2056_SYN_LOGEN_PU3 0x69
+#define B2056_SYN_LOGEN_PU5 0x6A
+#define B2056_SYN_LOGEN_PU6 0x6B
+#define B2056_SYN_LOGEN_PU7 0x6C
+#define B2056_SYN_LOGEN_PU8 0x6D
+#define B2056_SYN_LOGEN_BIAS_RESET 0x6E
+#define B2056_SYN_LOGEN_RCCR1 0x6F
+#define B2056_SYN_LOGEN_VCOBUF1 0x70
+#define B2056_SYN_LOGEN_MIXER1 0x71
+#define B2056_SYN_LOGEN_MIXER2 0x72
+#define B2056_SYN_LOGEN_BUF1 0x73
+#define B2056_SYN_LOGENBUF2 0x74
+#define B2056_SYN_LOGEN_BUF3 0x75
+#define B2056_SYN_LOGEN_BUF4 0x76
+#define B2056_SYN_LOGEN_DIV1 0x77
+#define B2056_SYN_LOGEN_DIV2 0x78
+#define B2056_SYN_LOGEN_DIV3 0x79
+#define B2056_SYN_LOGEN_ACL1 0x7A
+#define B2056_SYN_LOGEN_ACL2 0x7B
+#define B2056_SYN_LOGEN_ACL3 0x7C
+#define B2056_SYN_LOGEN_ACL4 0x7D
+#define B2056_SYN_LOGEN_ACL5 0x7E
+#define B2056_SYN_LOGEN_ACL6 0x7F
+#define B2056_SYN_LOGEN_ACLOUT 0x80
+#define B2056_SYN_LOGEN_ACLCAL1 0x81
+#define B2056_SYN_LOGEN_ACLCAL2 0x82
+#define B2056_SYN_LOGEN_ACLCAL3 0x83
+#define B2056_SYN_CALEN 0x84
+#define B2056_SYN_LOGEN_PEAKDET1 0x85
+#define B2056_SYN_LOGEN_CORE_ACL_OVR 0x86
+#define B2056_SYN_LOGEN_RX_DIFF_ACL_OVR 0x87
+#define B2056_SYN_LOGEN_TX_DIFF_ACL_OVR 0x88
+#define B2056_SYN_LOGEN_RX_CMOS_ACL_OVR 0x89
+#define B2056_SYN_LOGEN_TX_CMOS_ACL_OVR 0x8A
+#define B2056_SYN_LOGEN_VCOBUF2 0x8B
+#define B2056_SYN_LOGEN_MIXER3 0x8C
+#define B2056_SYN_LOGEN_BUF5 0x8D
+#define B2056_SYN_LOGEN_BUF6 0x8E
+#define B2056_SYN_LOGEN_CBUFRX1 0x8F
+#define B2056_SYN_LOGEN_CBUFRX2 0x90
+#define B2056_SYN_LOGEN_CBUFRX3 0x91
+#define B2056_SYN_LOGEN_CBUFRX4 0x92
+#define B2056_SYN_LOGEN_CBUFTX1 0x93
+#define B2056_SYN_LOGEN_CBUFTX2 0x94
+#define B2056_SYN_LOGEN_CBUFTX3 0x95
+#define B2056_SYN_LOGEN_CBUFTX4 0x96
+#define B2056_SYN_LOGEN_CMOSRX1 0x97
+#define B2056_SYN_LOGEN_CMOSRX2 0x98
+#define B2056_SYN_LOGEN_CMOSRX3 0x99
+#define B2056_SYN_LOGEN_CMOSRX4 0x9A
+#define B2056_SYN_LOGEN_CMOSTX1 0x9B
+#define B2056_SYN_LOGEN_CMOSTX2 0x9C
+#define B2056_SYN_LOGEN_CMOSTX3 0x9D
+#define B2056_SYN_LOGEN_CMOSTX4 0x9E
+#define B2056_SYN_LOGEN_VCOBUF2_OVRVAL 0x9F
+#define B2056_SYN_LOGEN_MIXER3_OVRVAL 0xA0
+#define B2056_SYN_LOGEN_BUF5_OVRVAL 0xA1
+#define B2056_SYN_LOGEN_BUF6_OVRVAL 0xA2
+#define B2056_SYN_LOGEN_CBUFRX1_OVRVAL 0xA3
+#define B2056_SYN_LOGEN_CBUFRX2_OVRVAL 0xA4
+#define B2056_SYN_LOGEN_CBUFRX3_OVRVAL 0xA5
+#define B2056_SYN_LOGEN_CBUFRX4_OVRVAL 0xA6
+#define B2056_SYN_LOGEN_CBUFTX1_OVRVAL 0xA7
+#define B2056_SYN_LOGEN_CBUFTX2_OVRVAL 0xA8
+#define B2056_SYN_LOGEN_CBUFTX3_OVRVAL 0xA9
+#define B2056_SYN_LOGEN_CBUFTX4_OVRVAL 0xAA
+#define B2056_SYN_LOGEN_CMOSRX1_OVRVAL 0xAB
+#define B2056_SYN_LOGEN_CMOSRX2_OVRVAL 0xAC
+#define B2056_SYN_LOGEN_CMOSRX3_OVRVAL 0xAD
+#define B2056_SYN_LOGEN_CMOSRX4_OVRVAL 0xAE
+#define B2056_SYN_LOGEN_CMOSTX1_OVRVAL 0xAF
+#define B2056_SYN_LOGEN_CMOSTX2_OVRVAL 0xB0
+#define B2056_SYN_LOGEN_CMOSTX3_OVRVAL 0xB1
+#define B2056_SYN_LOGEN_CMOSTX4_OVRVAL 0xB2
+#define B2056_SYN_LOGEN_ACL_WAITCNT 0xB3
+#define B2056_SYN_LOGEN_CORE_CALVALID 0xB4
+#define B2056_SYN_LOGEN_RX_CMOS_CALVALID 0xB5
+#define B2056_SYN_LOGEN_TX_CMOS_VALID 0xB6
+
+#define B2056_TX_RESERVED_ADDR0 0x00
+#define B2056_TX_IDCODE 0x01
+#define B2056_TX_RESERVED_ADDR2 0x02
+#define B2056_TX_RESERVED_ADDR3 0x03
+#define B2056_TX_RESERVED_ADDR4 0x04
+#define B2056_TX_RESERVED_ADDR5 0x05
+#define B2056_TX_RESERVED_ADDR6 0x06
+#define B2056_TX_RESERVED_ADDR7 0x07
+#define B2056_TX_COM_CTRL 0x08
+#define B2056_TX_COM_PU 0x09
+#define B2056_TX_COM_OVR 0x0A
+#define B2056_TX_COM_RESET 0x0B
+#define B2056_TX_COM_RCAL 0x0C
+#define B2056_TX_COM_RC_RXLPF 0x0D
+#define B2056_TX_COM_RC_TXLPF 0x0E
+#define B2056_TX_COM_RC_RXHPF 0x0F
+#define B2056_TX_RESERVED_ADDR16 0x10
+#define B2056_TX_RESERVED_ADDR17 0x11
+#define B2056_TX_RESERVED_ADDR18 0x12
+#define B2056_TX_RESERVED_ADDR19 0x13
+#define B2056_TX_RESERVED_ADDR20 0x14
+#define B2056_TX_RESERVED_ADDR21 0x15
+#define B2056_TX_RESERVED_ADDR22 0x16
+#define B2056_TX_RESERVED_ADDR23 0x17
+#define B2056_TX_RESERVED_ADDR24 0x18
+#define B2056_TX_RESERVED_ADDR25 0x19
+#define B2056_TX_RESERVED_ADDR26 0x1A
+#define B2056_TX_RESERVED_ADDR27 0x1B
+#define B2056_TX_RESERVED_ADDR28 0x1C
+#define B2056_TX_RESERVED_ADDR29 0x1D
+#define B2056_TX_RESERVED_ADDR30 0x1E
+#define B2056_TX_RESERVED_ADDR31 0x1F
+#define B2056_TX_IQCAL_GAIN_BW 0x20
+#define B2056_TX_LOFT_FINE_I 0x21
+#define B2056_TX_LOFT_FINE_Q 0x22
+#define B2056_TX_LOFT_COARSE_I 0x23
+#define B2056_TX_LOFT_COARSE_Q 0x24
+#define B2056_TX_TX_COM_MASTER1 0x25
+#define B2056_TX_TX_COM_MASTER2 0x26
+#define B2056_TX_RXIQCAL_TXMUX 0x27
+#define B2056_TX_TX_SSI_MASTER 0x28
+#define B2056_TX_IQCAL_VCM_HG 0x29
+#define B2056_TX_IQCAL_IDAC 0x2A
+#define B2056_TX_TSSI_VCM 0x2B
+#define B2056_TX_TX_AMP_DET 0x2C
+#define B2056_TX_TX_SSI_MUX 0x2D
+#define B2056_TX_TSSIA 0x2E
+#define B2056_TX_TSSIG 0x2F
+#define B2056_TX_TSSI_MISC1 0x30
+#define B2056_TX_TSSI_MISC2 0x31
+#define B2056_TX_TSSI_MISC3 0x32
+#define B2056_TX_PA_SPARE1 0x33
+#define B2056_TX_PA_SPARE2 0x34
+#define B2056_TX_INTPAA_MASTER 0x35
+#define B2056_TX_INTPAA_GAIN 0x36
+#define B2056_TX_INTPAA_BOOST_TUNE 0x37
+#define B2056_TX_INTPAA_IAUX_STAT 0x38
+#define B2056_TX_INTPAA_IAUX_DYN 0x39
+#define B2056_TX_INTPAA_IMAIN_STAT 0x3A
+#define B2056_TX_INTPAA_IMAIN_DYN 0x3B
+#define B2056_TX_INTPAA_CASCBIAS 0x3C
+#define B2056_TX_INTPAA_PASLOPE 0x3D
+#define B2056_TX_INTPAA_PA_MISC 0x3E
+#define B2056_TX_INTPAG_MASTER 0x3F
+#define B2056_TX_INTPAG_GAIN 0x40
+#define B2056_TX_INTPAG_BOOST_TUNE 0x41
+#define B2056_TX_INTPAG_IAUX_STAT 0x42
+#define B2056_TX_INTPAG_IAUX_DYN 0x43
+#define B2056_TX_INTPAG_IMAIN_STAT 0x44
+#define B2056_TX_INTPAG_IMAIN_DYN 0x45
+#define B2056_TX_INTPAG_CASCBIAS 0x46
+#define B2056_TX_INTPAG_PASLOPE 0x47
+#define B2056_TX_INTPAG_PA_MISC 0x48
+#define B2056_TX_PADA_MASTER 0x49
+#define B2056_TX_PADA_IDAC 0x4A
+#define B2056_TX_PADA_CASCBIAS 0x4B
+#define B2056_TX_PADA_GAIN 0x4C
+#define B2056_TX_PADA_BOOST_TUNE 0x4D
+#define B2056_TX_PADA_SLOPE 0x4E
+#define B2056_TX_PADG_MASTER 0x4F
+#define B2056_TX_PADG_IDAC 0x50
+#define B2056_TX_PADG_CASCBIAS 0x51
+#define B2056_TX_PADG_GAIN 0x52
+#define B2056_TX_PADG_BOOST_TUNE 0x53
+#define B2056_TX_PADG_SLOPE 0x54
+#define B2056_TX_PGAA_MASTER 0x55
+#define B2056_TX_PGAA_IDAC 0x56
+#define B2056_TX_PGAA_GAIN 0x57
+#define B2056_TX_PGAA_BOOST_TUNE 0x58
+#define B2056_TX_PGAA_SLOPE 0x59
+#define B2056_TX_PGAA_MISC 0x5A
+#define B2056_TX_PGAG_MASTER 0x5B
+#define B2056_TX_PGAG_IDAC 0x5C
+#define B2056_TX_PGAG_GAIN 0x5D
+#define B2056_TX_PGAG_BOOST_TUNE 0x5E
+#define B2056_TX_PGAG_SLOPE 0x5F
+#define B2056_TX_PGAG_MISC 0x60
+#define B2056_TX_MIXA_MASTER 0x61
+#define B2056_TX_MIXA_BOOST_TUNE 0x62
+#define B2056_TX_MIXG 0x63
+#define B2056_TX_MIXG_BOOST_TUNE 0x64
+#define B2056_TX_BB_GM_MASTER 0x65
+#define B2056_TX_GMBB_GM 0x66
+#define B2056_TX_GMBB_IDAC 0x67
+#define B2056_TX_TXLPF_MASTER 0x68
+#define B2056_TX_TXLPF_RCCAL 0x69
+#define B2056_TX_TXLPF_RCCAL_OFF0 0x6A
+#define B2056_TX_TXLPF_RCCAL_OFF1 0x6B
+#define B2056_TX_TXLPF_RCCAL_OFF2 0x6C
+#define B2056_TX_TXLPF_RCCAL_OFF3 0x6D
+#define B2056_TX_TXLPF_RCCAL_OFF4 0x6E
+#define B2056_TX_TXLPF_RCCAL_OFF5 0x6F
+#define B2056_TX_TXLPF_RCCAL_OFF6 0x70
+#define B2056_TX_TXLPF_BW 0x71
+#define B2056_TX_TXLPF_GAIN 0x72
+#define B2056_TX_TXLPF_IDAC 0x73
+#define B2056_TX_TXLPF_IDAC_0 0x74
+#define B2056_TX_TXLPF_IDAC_1 0x75
+#define B2056_TX_TXLPF_IDAC_2 0x76
+#define B2056_TX_TXLPF_IDAC_3 0x77
+#define B2056_TX_TXLPF_IDAC_4 0x78
+#define B2056_TX_TXLPF_IDAC_5 0x79
+#define B2056_TX_TXLPF_IDAC_6 0x7A
+#define B2056_TX_TXLPF_OPAMP_IDAC 0x7B
+#define B2056_TX_TXLPF_MISC 0x7C
+#define B2056_TX_TXSPARE1 0x7D
+#define B2056_TX_TXSPARE2 0x7E
+#define B2056_TX_TXSPARE3 0x7F
+#define B2056_TX_TXSPARE4 0x80
+#define B2056_TX_TXSPARE5 0x81
+#define B2056_TX_TXSPARE6 0x82
+#define B2056_TX_TXSPARE7 0x83
+#define B2056_TX_TXSPARE8 0x84
+#define B2056_TX_TXSPARE9 0x85
+#define B2056_TX_TXSPARE10 0x86
+#define B2056_TX_TXSPARE11 0x87
+#define B2056_TX_TXSPARE12 0x88
+#define B2056_TX_TXSPARE13 0x89
+#define B2056_TX_TXSPARE14 0x8A
+#define B2056_TX_TXSPARE15 0x8B
+#define B2056_TX_TXSPARE16 0x8C
+#define B2056_TX_STATUS_INTPA_GAIN 0x8D
+#define B2056_TX_STATUS_PAD_GAIN 0x8E
+#define B2056_TX_STATUS_PGA_GAIN 0x8F
+#define B2056_TX_STATUS_GM_TXLPF_GAIN 0x90
+#define B2056_TX_STATUS_TXLPF_BW 0x91
+#define B2056_TX_STATUS_TXLPF_RC 0x92
+#define B2056_TX_GMBB_IDAC0 0x93
+#define B2056_TX_GMBB_IDAC1 0x94
+#define B2056_TX_GMBB_IDAC2 0x95
+#define B2056_TX_GMBB_IDAC3 0x96
+#define B2056_TX_GMBB_IDAC4 0x97
+#define B2056_TX_GMBB_IDAC5 0x98
+#define B2056_TX_GMBB_IDAC6 0x99
+#define B2056_TX_GMBB_IDAC7 0x9A
+
+#define B2056_RX_RESERVED_ADDR0 0x00
+#define B2056_RX_IDCODE 0x01
+#define B2056_RX_RESERVED_ADDR2 0x02
+#define B2056_RX_RESERVED_ADDR3 0x03
+#define B2056_RX_RESERVED_ADDR4 0x04
+#define B2056_RX_RESERVED_ADDR5 0x05
+#define B2056_RX_RESERVED_ADDR6 0x06
+#define B2056_RX_RESERVED_ADDR7 0x07
+#define B2056_RX_COM_CTRL 0x08
+#define B2056_RX_COM_PU 0x09
+#define B2056_RX_COM_OVR 0x0A
+#define B2056_RX_COM_RESET 0x0B
+#define B2056_RX_COM_RCAL 0x0C
+#define B2056_RX_COM_RC_RXLPF 0x0D
+#define B2056_RX_COM_RC_TXLPF 0x0E
+#define B2056_RX_COM_RC_RXHPF 0x0F
+#define B2056_RX_RESERVED_ADDR16 0x10
+#define B2056_RX_RESERVED_ADDR17 0x11
+#define B2056_RX_RESERVED_ADDR18 0x12
+#define B2056_RX_RESERVED_ADDR19 0x13
+#define B2056_RX_RESERVED_ADDR20 0x14
+#define B2056_RX_RESERVED_ADDR21 0x15
+#define B2056_RX_RESERVED_ADDR22 0x16
+#define B2056_RX_RESERVED_ADDR23 0x17
+#define B2056_RX_RESERVED_ADDR24 0x18
+#define B2056_RX_RESERVED_ADDR25 0x19
+#define B2056_RX_RESERVED_ADDR26 0x1A
+#define B2056_RX_RESERVED_ADDR27 0x1B
+#define B2056_RX_RESERVED_ADDR28 0x1C
+#define B2056_RX_RESERVED_ADDR29 0x1D
+#define B2056_RX_RESERVED_ADDR30 0x1E
+#define B2056_RX_RESERVED_ADDR31 0x1F
+#define B2056_RX_RXIQCAL_RXMUX 0x20
+#define B2056_RX_RSSI_PU 0x21
+#define B2056_RX_RSSI_SEL 0x22
+#define B2056_RX_RSSI_GAIN 0x23
+#define B2056_RX_RSSI_NB_IDAC 0x24
+#define B2056_RX_RSSI_WB2I_IDAC_1 0x25
+#define B2056_RX_RSSI_WB2I_IDAC_2 0x26
+#define B2056_RX_RSSI_WB2Q_IDAC_1 0x27
+#define B2056_RX_RSSI_WB2Q_IDAC_2 0x28
+#define B2056_RX_RSSI_POLE 0x29
+#define B2056_RX_RSSI_WB1_IDAC 0x2A
+#define B2056_RX_RSSI_MISC 0x2B
+#define B2056_RX_LNAA_MASTER 0x2C
+#define B2056_RX_LNAA_TUNE 0x2D
+#define B2056_RX_LNAA_GAIN 0x2E
+#define B2056_RX_LNA_A_SLOPE 0x2F
+#define B2056_RX_BIASPOLE_LNAA1_IDAC 0x30
+#define B2056_RX_LNAA2_IDAC 0x31
+#define B2056_RX_LNA1A_MISC 0x32
+#define B2056_RX_LNAG_MASTER 0x33
+#define B2056_RX_LNAG_TUNE 0x34
+#define B2056_RX_LNAG_GAIN 0x35
+#define B2056_RX_LNA_G_SLOPE 0x36
+#define B2056_RX_BIASPOLE_LNAG1_IDAC 0x37
+#define B2056_RX_LNAG2_IDAC 0x38
+#define B2056_RX_LNA1G_MISC 0x39
+#define B2056_RX_MIXA_MASTER 0x3A
+#define B2056_RX_MIXA_VCM 0x3B
+#define B2056_RX_MIXA_CTRLPTAT 0x3C
+#define B2056_RX_MIXA_LOB_BIAS 0x3D
+#define B2056_RX_MIXA_CORE_IDAC 0x3E
+#define B2056_RX_MIXA_CMFB_IDAC 0x3F
+#define B2056_RX_MIXA_BIAS_AUX 0x40
+#define B2056_RX_MIXA_BIAS_MAIN 0x41
+#define B2056_RX_MIXA_BIAS_MISC 0x42
+#define B2056_RX_MIXA_MAST_BIAS 0x43
+#define B2056_RX_MIXG_MASTER 0x44
+#define B2056_RX_MIXG_VCM 0x45
+#define B2056_RX_MIXG_CTRLPTAT 0x46
+#define B2056_RX_MIXG_LOB_BIAS 0x47
+#define B2056_RX_MIXG_CORE_IDAC 0x48
+#define B2056_RX_MIXG_CMFB_IDAC 0x49
+#define B2056_RX_MIXG_BIAS_AUX 0x4A
+#define B2056_RX_MIXG_BIAS_MAIN 0x4B
+#define B2056_RX_MIXG_BIAS_MISC 0x4C
+#define B2056_RX_MIXG_MAST_BIAS 0x4D
+#define B2056_RX_TIA_MASTER 0x4E
+#define B2056_RX_TIA_IOPAMP 0x4F
+#define B2056_RX_TIA_QOPAMP 0x50
+#define B2056_RX_TIA_IMISC 0x51
+#define B2056_RX_TIA_QMISC 0x52
+#define B2056_RX_TIA_GAIN 0x53
+#define B2056_RX_TIA_SPARE1 0x54
+#define B2056_RX_TIA_SPARE2 0x55
+#define B2056_RX_BB_LPF_MASTER 0x56
+#define B2056_RX_AACI_MASTER 0x57
+#define B2056_RX_RXLPF_IDAC 0x58
+#define B2056_RX_RXLPF_OPAMPBIAS_LOWQ 0x59
+#define B2056_RX_RXLPF_OPAMPBIAS_HIGHQ 0x5A
+#define B2056_RX_RXLPF_BIAS_DCCANCEL 0x5B
+#define B2056_RX_RXLPF_OUTVCM 0x5C
+#define B2056_RX_RXLPF_INVCM_BODY 0x5D
+#define B2056_RX_RXLPF_CC_OP 0x5E
+#define B2056_RX_RXLPF_GAIN 0x5F
+#define B2056_RX_RXLPF_Q_BW 0x60
+#define B2056_RX_RXLPF_HP_CORNER_BW 0x61
+#define B2056_RX_RXLPF_RCCAL_HPC 0x62
+#define B2056_RX_RXHPF_OFF0 0x63
+#define B2056_RX_RXHPF_OFF1 0x64
+#define B2056_RX_RXHPF_OFF2 0x65
+#define B2056_RX_RXHPF_OFF3 0x66
+#define B2056_RX_RXHPF_OFF4 0x67
+#define B2056_RX_RXHPF_OFF5 0x68
+#define B2056_RX_RXHPF_OFF6 0x69
+#define B2056_RX_RXHPF_OFF7 0x6A
+#define B2056_RX_RXLPF_RCCAL_LPC 0x6B
+#define B2056_RX_RXLPF_OFF_0 0x6C
+#define B2056_RX_RXLPF_OFF_1 0x6D
+#define B2056_RX_RXLPF_OFF_2 0x6E
+#define B2056_RX_RXLPF_OFF_3 0x6F
+#define B2056_RX_RXLPF_OFF_4 0x70
+#define B2056_RX_UNUSED 0x71
+#define B2056_RX_VGA_MASTER 0x72
+#define B2056_RX_VGA_BIAS 0x73
+#define B2056_RX_VGA_BIAS_DCCANCEL 0x74
+#define B2056_RX_VGA_GAIN 0x75
+#define B2056_RX_VGA_HP_CORNER_BW 0x76
+#define B2056_RX_VGABUF_BIAS 0x77
+#define B2056_RX_VGABUF_GAIN_BW 0x78
+#define B2056_RX_TXFBMIX_A 0x79
+#define B2056_RX_TXFBMIX_G 0x7A
+#define B2056_RX_RXSPARE1 0x7B
+#define B2056_RX_RXSPARE2 0x7C
+#define B2056_RX_RXSPARE3 0x7D
+#define B2056_RX_RXSPARE4 0x7E
+#define B2056_RX_RXSPARE5 0x7F
+#define B2056_RX_RXSPARE6 0x80
+#define B2056_RX_RXSPARE7 0x81
+#define B2056_RX_RXSPARE8 0x82
+#define B2056_RX_RXSPARE9 0x83
+#define B2056_RX_RXSPARE10 0x84
+#define B2056_RX_RXSPARE11 0x85
+#define B2056_RX_RXSPARE12 0x86
+#define B2056_RX_RXSPARE13 0x87
+#define B2056_RX_RXSPARE14 0x88
+#define B2056_RX_RXSPARE15 0x89
+#define B2056_RX_RXSPARE16 0x8A
+#define B2056_RX_STATUS_LNAA_GAIN 0x8B
+#define B2056_RX_STATUS_LNAG_GAIN 0x8C
+#define B2056_RX_STATUS_MIXTIA_GAIN 0x8D
+#define B2056_RX_STATUS_RXLPF_GAIN 0x8E
+#define B2056_RX_STATUS_VGA_BUF_GAIN 0x8F
+#define B2056_RX_STATUS_RXLPF_Q 0x90
+#define B2056_RX_STATUS_RXLPF_BUF_BW 0x91
+#define B2056_RX_STATUS_RXLPF_VGA_HPC 0x92
+#define B2056_RX_STATUS_RXLPF_RC 0x93
+#define B2056_RX_STATUS_HPC_RC 0x94
+
+#define B2056_LNA1_A_PU 0x01
+#define B2056_LNA2_A_PU 0x02
+#define B2056_LNA1_G_PU 0x01
+#define B2056_LNA2_G_PU 0x02
+#define B2056_MIXA_PU_I 0x01
+#define B2056_MIXA_PU_Q 0x02
+#define B2056_MIXA_PU_GM 0x10
+#define B2056_MIXG_PU_I 0x01
+#define B2056_MIXG_PU_Q 0x02
+#define B2056_MIXG_PU_GM 0x10
+#define B2056_TIA_PU 0x01
+#define B2056_BB_LPF_PU 0x20
+#define B2056_W1_PU 0x02
+#define B2056_W2_PU 0x04
+#define B2056_NB_PU 0x08
+#define B2056_RSSI_W1_SEL 0x02
+#define B2056_RSSI_W2_SEL 0x04
+#define B2056_RSSI_NB_SEL 0x08
+#define B2056_VCM_MASK 0x1C
+#define B2056_RSSI_VCM_SHIFT 0x02
+
struct b43_nphy_channeltab_entry_rev3 {
- /* The channel number */
- u8 channel;
/* The channel frequency in MHz */
u16 freq;
/* Radio register values on channelswitch */
- /* TODO */
+ u8 radio_syn_pll_vcocal1;
+ u8 radio_syn_pll_vcocal2;
+ u8 radio_syn_pll_refdiv;
+ u8 radio_syn_pll_mmd2;
+ u8 radio_syn_pll_mmd1;
+ u8 radio_syn_pll_loopfilter1;
+ u8 radio_syn_pll_loopfilter2;
+ u8 radio_syn_pll_loopfilter3;
+ u8 radio_syn_pll_loopfilter4;
+ u8 radio_syn_pll_loopfilter5;
+ u8 radio_syn_reserved_addr27;
+ u8 radio_syn_reserved_addr28;
+ u8 radio_syn_reserved_addr29;
+ u8 radio_syn_logen_vcobuf1;
+ u8 radio_syn_logen_mixer2;
+ u8 radio_syn_logen_buf3;
+ u8 radio_syn_logen_buf4;
+ u8 radio_rx0_lnaa_tune;
+ u8 radio_rx0_lnag_tune;
+ u8 radio_tx0_intpaa_boost_tune;
+ u8 radio_tx0_intpag_boost_tune;
+ u8 radio_tx0_pada_boost_tune;
+ u8 radio_tx0_padg_boost_tune;
+ u8 radio_tx0_pgaa_boost_tune;
+ u8 radio_tx0_pgag_boost_tune;
+ u8 radio_tx0_mixa_boost_tune;
+ u8 radio_tx0_mixg_boost_tune;
+ u8 radio_rx1_lnaa_tune;
+ u8 radio_rx1_lnag_tune;
+ u8 radio_tx1_intpaa_boost_tune;
+ u8 radio_tx1_intpag_boost_tune;
+ u8 radio_tx1_pada_boost_tune;
+ u8 radio_tx1_padg_boost_tune;
+ u8 radio_tx1_pgaa_boost_tune;
+ u8 radio_tx1_pgag_boost_tune;
+ u8 radio_tx1_mixa_boost_tune;
+ u8 radio_tx1_mixg_boost_tune;
/* PHY register values on channelswitch */
struct b43_phy_n_sfo_cfg phy_regs;
};
diff --git a/drivers/net/wireless/b43/rfkill.c b/drivers/net/wireless/b43/rfkill.c
index 78016ae21c50..86bc0a0f735c 100644
--- a/drivers/net/wireless/b43/rfkill.c
+++ b/drivers/net/wireless/b43/rfkill.c
@@ -28,23 +28,8 @@
/* Returns TRUE, if the radio is enabled in hardware. */
bool b43_is_hw_radio_enabled(struct b43_wldev *dev)
{
- if (dev->phy.rev >= 3 || dev->phy.type == B43_PHYTYPE_LP) {
- if (!(b43_read32(dev, B43_MMIO_RADIO_HWENABLED_HI)
- & B43_MMIO_RADIO_HWENABLED_HI_MASK))
- return 1;
- } else {
- /* To prevent CPU fault on PPC, do not read a register
- * unless the interface is started; however, on resume
- * for hibernation, this routine is entered early. When
- * that happens, unconditionally return TRUE.
- */
- if (b43_status(dev) < B43_STAT_STARTED)
- return 1;
- if (b43_read16(dev, B43_MMIO_RADIO_HWENABLED_LO)
- & B43_MMIO_RADIO_HWENABLED_LO_MASK)
- return 1;
- }
- return 0;
+ return !(b43_read32(dev, B43_MMIO_RADIO_HWENABLED_HI)
+ & B43_MMIO_RADIO_HWENABLED_HI_MASK);
}
/* The poll callback for the hardware button. */
diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c
index d60db078eae2..df61c1610e39 100644
--- a/drivers/net/wireless/b43/tables_nphy.c
+++ b/drivers/net/wireless/b43/tables_nphy.c
@@ -28,41 +28,41 @@
#include "phy_n.h"
static const u8 b43_ntab_adjustpower0[] = {
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
- 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03,
- 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05,
- 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07,
- 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09,
- 0x0A, 0x0A, 0x0A, 0x0A, 0x0B, 0x0B, 0x0B, 0x0B,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F,
- 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11,
- 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13,
- 0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15,
- 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17,
- 0x18, 0x18, 0x18, 0x18, 0x19, 0x19, 0x19, 0x19,
- 0x1A, 0x1A, 0x1A, 0x1A, 0x1B, 0x1B, 0x1B, 0x1B,
- 0x1C, 0x1C, 0x1C, 0x1C, 0x1D, 0x1D, 0x1D, 0x1D,
- 0x1E, 0x1E, 0x1E, 0x1E, 0x1F, 0x1F, 0x1F, 0x1F,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
static const u8 b43_ntab_adjustpower1[] = {
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
- 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03,
- 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05,
- 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07,
- 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09,
- 0x0A, 0x0A, 0x0A, 0x0A, 0x0B, 0x0B, 0x0B, 0x0B,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F,
- 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11,
- 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13,
- 0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15,
- 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17,
- 0x18, 0x18, 0x18, 0x18, 0x19, 0x19, 0x19, 0x19,
- 0x1A, 0x1A, 0x1A, 0x1A, 0x1B, 0x1B, 0x1B, 0x1B,
- 0x1C, 0x1C, 0x1C, 0x1C, 0x1D, 0x1D, 0x1D, 0x1D,
- 0x1E, 0x1E, 0x1E, 0x1E, 0x1F, 0x1F, 0x1F, 0x1F,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
static const u16 b43_ntab_bdi[] = {
@@ -130,8 +130,8 @@ static const u32 b43_ntab_framestruct[] = {
0x09804506, 0x00100030, 0x09804507, 0x00100030,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x08004A0C, 0x00100008, 0x01000A0D, 0x00100028,
- 0x0980450E, 0x00100038, 0x0980450F, 0x00100038,
+ 0x08004A0C, 0x00100004, 0x01000A0D, 0x00100024,
+ 0x0980450E, 0x00100034, 0x0980450F, 0x00100034,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000A04, 0x00100000, 0x11008A05, 0x00100020,
@@ -202,13 +202,13 @@ static const u32 b43_ntab_framestruct[] = {
0x53028A06, 0x01900060, 0x53028A07, 0x01900060,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x4002140C, 0x000F4810, 0x6203140D, 0x00100050,
- 0x53028A0E, 0x01900070, 0x53028A0F, 0x01900070,
+ 0x4002140C, 0x000F4808, 0x6203140D, 0x00100048,
+ 0x53028A0E, 0x01900068, 0x53028A0F, 0x01900068,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000A0C, 0x00100008, 0x11008A0D, 0x00100028,
- 0x1980C50E, 0x00100038, 0x2181050E, 0x00100038,
- 0x2181050E, 0x00100038, 0x0180050C, 0x00100038,
+ 0x00000A0C, 0x00100004, 0x11008A0D, 0x00100024,
+ 0x1980C50E, 0x00100034, 0x2181050E, 0x00100034,
+ 0x2181050E, 0x00100034, 0x0180050C, 0x00100038,
0x1180850D, 0x00100038, 0x1181850D, 0x00100038,
0x2981450F, 0x01100038, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
@@ -238,9 +238,9 @@ static const u32 b43_ntab_framestruct[] = {
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x4002140C, 0x00100010, 0x0200140D, 0x00100050,
- 0x0B004A0E, 0x01900070, 0x13008A0E, 0x01900070,
- 0x13008A0E, 0x01900070, 0x43020A0C, 0x00100070,
+ 0x4002140C, 0x00100008, 0x0200140D, 0x00100048,
+ 0x0B004A0E, 0x01900068, 0x13008A0E, 0x01900068,
+ 0x13008A0E, 0x01900068, 0x43020A0C, 0x00100070,
0x1B00CA0D, 0x00100070, 0x1B014A0D, 0x00100070,
0x23010A0F, 0x01500070, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
@@ -337,73 +337,73 @@ static const u32 b43_ntab_framestruct[] = {
};
static const u32 b43_ntab_gainctl0[] = {
- 0x007F003F, 0x007E013F, 0x007D023E, 0x007C033E,
- 0x007B043D, 0x007A053D, 0x0079063C, 0x0078073C,
- 0x0077083B, 0x0076093B, 0x00750A3A, 0x00740B3A,
- 0x00730C39, 0x00720D39, 0x00710E38, 0x00700F38,
- 0x006F0037, 0x006E0137, 0x006D0236, 0x006C0336,
- 0x006B0435, 0x006A0535, 0x00690634, 0x00680734,
- 0x00670833, 0x00660933, 0x00650A32, 0x00640B32,
- 0x00630C31, 0x00620D31, 0x00610E30, 0x00600F30,
- 0x005F002F, 0x005E012F, 0x005D022E, 0x005C032E,
- 0x005B042D, 0x005A052D, 0x0059062C, 0x0058072C,
- 0x0057082B, 0x0056092B, 0x00550A2A, 0x00540B2A,
- 0x00530C29, 0x00520D29, 0x00510E28, 0x00500F28,
- 0x004F0027, 0x004E0127, 0x004D0226, 0x004C0326,
- 0x004B0425, 0x004A0525, 0x00490624, 0x00480724,
- 0x00470823, 0x00460923, 0x00450A22, 0x00440B22,
- 0x00430C21, 0x00420D21, 0x00410E20, 0x00400F20,
- 0x003F001F, 0x003E011F, 0x003D021E, 0x003C031E,
- 0x003B041D, 0x003A051D, 0x0039061C, 0x0038071C,
- 0x0037081B, 0x0036091B, 0x00350A1A, 0x00340B1A,
- 0x00330C19, 0x00320D19, 0x00310E18, 0x00300F18,
- 0x002F0017, 0x002E0117, 0x002D0216, 0x002C0316,
- 0x002B0415, 0x002A0515, 0x00290614, 0x00280714,
- 0x00270813, 0x00260913, 0x00250A12, 0x00240B12,
- 0x00230C11, 0x00220D11, 0x00210E10, 0x00200F10,
- 0x001F000F, 0x001E010F, 0x001D020E, 0x001C030E,
- 0x001B040D, 0x001A050D, 0x0019060C, 0x0018070C,
- 0x0017080B, 0x0016090B, 0x00150A0A, 0x00140B0A,
- 0x00130C09, 0x00120D09, 0x00110E08, 0x00100F08,
- 0x000F0007, 0x000E0107, 0x000D0206, 0x000C0306,
- 0x000B0405, 0x000A0505, 0x00090604, 0x00080704,
- 0x00070803, 0x00060903, 0x00050A02, 0x00040B02,
- 0x00030C01, 0x00020D01, 0x00010E00, 0x00000F00,
+ 0x03CC2B44, 0x03CC2B42, 0x03CC2B40, 0x03CC2B3E,
+ 0x03CC2B3D, 0x03CC2B3B, 0x03C82B44, 0x03C82B42,
+ 0x03C82B40, 0x03C82B3E, 0x03C82B3D, 0x03C82B3B,
+ 0x03C82B39, 0x03C82B38, 0x03C82B36, 0x03C82B34,
+ 0x03C42B44, 0x03C42B42, 0x03C42B40, 0x03C42B3E,
+ 0x03C42B3D, 0x03C42B3B, 0x03C42B39, 0x03C42B38,
+ 0x03C42B36, 0x03C42B34, 0x03C42B33, 0x03C42B32,
+ 0x03C42B30, 0x03C42B2F, 0x03C42B2D, 0x03C02B44,
+ 0x03C02B42, 0x03C02B40, 0x03C02B3E, 0x03C02B3D,
+ 0x03C02B3B, 0x03C02B39, 0x03C02B38, 0x03C02B36,
+ 0x03C02B34, 0x03B02B44, 0x03B02B42, 0x03B02B40,
+ 0x03B02B3E, 0x03B02B3D, 0x03B02B3B, 0x03B02B39,
+ 0x03B02B38, 0x03B02B36, 0x03B02B34, 0x03B02B33,
+ 0x03B02B32, 0x03B02B30, 0x03B02B2F, 0x03B02B2D,
+ 0x03A02B44, 0x03A02B42, 0x03A02B40, 0x03A02B3E,
+ 0x03A02B3D, 0x03A02B3B, 0x03A02B39, 0x03A02B38,
+ 0x03A02B36, 0x03A02B34, 0x03902B44, 0x03902B42,
+ 0x03902B40, 0x03902B3E, 0x03902B3D, 0x03902B3B,
+ 0x03902B39, 0x03902B38, 0x03902B36, 0x03902B34,
+ 0x03902B33, 0x03902B32, 0x03902B30, 0x03802B44,
+ 0x03802B42, 0x03802B40, 0x03802B3E, 0x03802B3D,
+ 0x03802B3B, 0x03802B39, 0x03802B38, 0x03802B36,
+ 0x03802B34, 0x03802B33, 0x03802B32, 0x03802B30,
+ 0x03802B2F, 0x03802B2D, 0x03802B2C, 0x03802B2B,
+ 0x03802B2A, 0x03802B29, 0x03802B27, 0x03802B26,
+ 0x03802B25, 0x03802B24, 0x03802B23, 0x03802B22,
+ 0x03802B21, 0x03802B20, 0x03802B1F, 0x03802B1E,
+ 0x03802B1E, 0x03802B1D, 0x03802B1C, 0x03802B1B,
+ 0x03802B1A, 0x03802B1A, 0x03802B19, 0x03802B18,
+ 0x03802B18, 0x03802B18, 0x03802B18, 0x03802B18,
+ 0x03802B18, 0x03802B18, 0x03802B18, 0x03802B18,
+ 0x03802B18, 0x03802B18, 0x03802B18, 0x00002B00,
};
static const u32 b43_ntab_gainctl1[] = {
- 0x007F003F, 0x007E013F, 0x007D023E, 0x007C033E,
- 0x007B043D, 0x007A053D, 0x0079063C, 0x0078073C,
- 0x0077083B, 0x0076093B, 0x00750A3A, 0x00740B3A,
- 0x00730C39, 0x00720D39, 0x00710E38, 0x00700F38,
- 0x006F0037, 0x006E0137, 0x006D0236, 0x006C0336,
- 0x006B0435, 0x006A0535, 0x00690634, 0x00680734,
- 0x00670833, 0x00660933, 0x00650A32, 0x00640B32,
- 0x00630C31, 0x00620D31, 0x00610E30, 0x00600F30,
- 0x005F002F, 0x005E012F, 0x005D022E, 0x005C032E,
- 0x005B042D, 0x005A052D, 0x0059062C, 0x0058072C,
- 0x0057082B, 0x0056092B, 0x00550A2A, 0x00540B2A,
- 0x00530C29, 0x00520D29, 0x00510E28, 0x00500F28,
- 0x004F0027, 0x004E0127, 0x004D0226, 0x004C0326,
- 0x004B0425, 0x004A0525, 0x00490624, 0x00480724,
- 0x00470823, 0x00460923, 0x00450A22, 0x00440B22,
- 0x00430C21, 0x00420D21, 0x00410E20, 0x00400F20,
- 0x003F001F, 0x003E011F, 0x003D021E, 0x003C031E,
- 0x003B041D, 0x003A051D, 0x0039061C, 0x0038071C,
- 0x0037081B, 0x0036091B, 0x00350A1A, 0x00340B1A,
- 0x00330C19, 0x00320D19, 0x00310E18, 0x00300F18,
- 0x002F0017, 0x002E0117, 0x002D0216, 0x002C0316,
- 0x002B0415, 0x002A0515, 0x00290614, 0x00280714,
- 0x00270813, 0x00260913, 0x00250A12, 0x00240B12,
- 0x00230C11, 0x00220D11, 0x00210E10, 0x00200F10,
- 0x001F000F, 0x001E010F, 0x001D020E, 0x001C030E,
- 0x001B040D, 0x001A050D, 0x0019060C, 0x0018070C,
- 0x0017080B, 0x0016090B, 0x00150A0A, 0x00140B0A,
- 0x00130C09, 0x00120D09, 0x00110E08, 0x00100F08,
- 0x000F0007, 0x000E0107, 0x000D0206, 0x000C0306,
- 0x000B0405, 0x000A0505, 0x00090604, 0x00080704,
- 0x00070803, 0x00060903, 0x00050A02, 0x00040B02,
- 0x00030C01, 0x00020D01, 0x00010E00, 0x00000F00,
+ 0x03CC2B44, 0x03CC2B42, 0x03CC2B40, 0x03CC2B3E,
+ 0x03CC2B3D, 0x03CC2B3B, 0x03C82B44, 0x03C82B42,
+ 0x03C82B40, 0x03C82B3E, 0x03C82B3D, 0x03C82B3B,
+ 0x03C82B39, 0x03C82B38, 0x03C82B36, 0x03C82B34,
+ 0x03C42B44, 0x03C42B42, 0x03C42B40, 0x03C42B3E,
+ 0x03C42B3D, 0x03C42B3B, 0x03C42B39, 0x03C42B38,
+ 0x03C42B36, 0x03C42B34, 0x03C42B33, 0x03C42B32,
+ 0x03C42B30, 0x03C42B2F, 0x03C42B2D, 0x03C02B44,
+ 0x03C02B42, 0x03C02B40, 0x03C02B3E, 0x03C02B3D,
+ 0x03C02B3B, 0x03C02B39, 0x03C02B38, 0x03C02B36,
+ 0x03C02B34, 0x03B02B44, 0x03B02B42, 0x03B02B40,
+ 0x03B02B3E, 0x03B02B3D, 0x03B02B3B, 0x03B02B39,
+ 0x03B02B38, 0x03B02B36, 0x03B02B34, 0x03B02B33,
+ 0x03B02B32, 0x03B02B30, 0x03B02B2F, 0x03B02B2D,
+ 0x03A02B44, 0x03A02B42, 0x03A02B40, 0x03A02B3E,
+ 0x03A02B3D, 0x03A02B3B, 0x03A02B39, 0x03A02B38,
+ 0x03A02B36, 0x03A02B34, 0x03902B44, 0x03902B42,
+ 0x03902B40, 0x03902B3E, 0x03902B3D, 0x03902B3B,
+ 0x03902B39, 0x03902B38, 0x03902B36, 0x03902B34,
+ 0x03902B33, 0x03902B32, 0x03902B30, 0x03802B44,
+ 0x03802B42, 0x03802B40, 0x03802B3E, 0x03802B3D,
+ 0x03802B3B, 0x03802B39, 0x03802B38, 0x03802B36,
+ 0x03802B34, 0x03802B33, 0x03802B32, 0x03802B30,
+ 0x03802B2F, 0x03802B2D, 0x03802B2C, 0x03802B2B,
+ 0x03802B2A, 0x03802B29, 0x03802B27, 0x03802B26,
+ 0x03802B25, 0x03802B24, 0x03802B23, 0x03802B22,
+ 0x03802B21, 0x03802B20, 0x03802B1F, 0x03802B1E,
+ 0x03802B1E, 0x03802B1D, 0x03802B1C, 0x03802B1B,
+ 0x03802B1A, 0x03802B1A, 0x03802B19, 0x03802B18,
+ 0x03802B18, 0x03802B18, 0x03802B18, 0x03802B18,
+ 0x03802B18, 0x03802B18, 0x03802B18, 0x03802B18,
+ 0x03802B18, 0x03802B18, 0x03802B18, 0x00002B00,
};
static const u32 b43_ntab_intlevel[] = {
@@ -1811,9 +1811,7 @@ void b43_ntab_write_bulk(struct b43_wldev *dev, u32 offset,
}
#define ntab_upload(dev, offset, data) do { \
- unsigned int i; \
- for (i = 0; i < (offset##_SIZE); i++) \
- b43_ntab_write(dev, (offset) + i, (data)[i]); \
+ b43_ntab_write_bulk(dev, offset, offset##_SIZE, data); \
} while (0)
void b43_nphy_rev0_1_2_tables_init(struct b43_wldev *dev)
@@ -1825,18 +1823,18 @@ void b43_nphy_rev0_1_2_tables_init(struct b43_wldev *dev)
ntab_upload(dev, B43_NTAB_TDTRN, b43_ntab_tdtrn);
ntab_upload(dev, B43_NTAB_INTLEVEL, b43_ntab_intlevel);
ntab_upload(dev, B43_NTAB_PILOT, b43_ntab_pilot);
- ntab_upload(dev, B43_NTAB_PILOTLT, b43_ntab_pilotlt);
ntab_upload(dev, B43_NTAB_TDI20A0, b43_ntab_tdi20a0);
ntab_upload(dev, B43_NTAB_TDI20A1, b43_ntab_tdi20a1);
ntab_upload(dev, B43_NTAB_TDI40A0, b43_ntab_tdi40a0);
ntab_upload(dev, B43_NTAB_TDI40A1, b43_ntab_tdi40a1);
- ntab_upload(dev, B43_NTAB_BDI, b43_ntab_bdi);
ntab_upload(dev, B43_NTAB_CHANEST, b43_ntab_channelest);
ntab_upload(dev, B43_NTAB_MCS, b43_ntab_mcs);
-
- /* Volatile tables */
ntab_upload(dev, B43_NTAB_NOISEVAR10, b43_ntab_noisevar10);
ntab_upload(dev, B43_NTAB_NOISEVAR11, b43_ntab_noisevar11);
+
+ /* Volatile tables */
+ ntab_upload(dev, B43_NTAB_BDI, b43_ntab_bdi);
+ ntab_upload(dev, B43_NTAB_PILOTLT, b43_ntab_pilotlt);
ntab_upload(dev, B43_NTAB_C0_ESTPLT, b43_ntab_estimatepowerlt0);
ntab_upload(dev, B43_NTAB_C1_ESTPLT, b43_ntab_estimatepowerlt1);
ntab_upload(dev, B43_NTAB_C0_ADJPLT, b43_ntab_adjustpower0);
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index 67f18ecdb3bf..1f11e1670bf0 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -181,52 +181,75 @@ static int b43legacy_ratelimit(struct b43legacy_wl *wl)
void b43legacyinfo(struct b43legacy_wl *wl, const char *fmt, ...)
{
+ struct va_format vaf;
va_list args;
if (!b43legacy_ratelimit(wl))
return;
+
va_start(args, fmt);
- printk(KERN_INFO "b43legacy-%s: ",
- (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan");
- vprintk(fmt, args);
+
+ vaf.fmt = fmt;
+ vaf.va = &args;
+
+ printk(KERN_INFO "b43legacy-%s: %pV",
+ (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan", &vaf);
+
va_end(args);
}
void b43legacyerr(struct b43legacy_wl *wl, const char *fmt, ...)
{
+ struct va_format vaf;
va_list args;
if (!b43legacy_ratelimit(wl))
return;
+
va_start(args, fmt);
- printk(KERN_ERR "b43legacy-%s ERROR: ",
- (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan");
- vprintk(fmt, args);
+
+ vaf.fmt = fmt;
+ vaf.va = &args;
+
+ printk(KERN_ERR "b43legacy-%s ERROR: %pV",
+ (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan", &vaf);
+
va_end(args);
}
void b43legacywarn(struct b43legacy_wl *wl, const char *fmt, ...)
{
+ struct va_format vaf;
va_list args;
if (!b43legacy_ratelimit(wl))
return;
+
va_start(args, fmt);
- printk(KERN_WARNING "b43legacy-%s warning: ",
- (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan");
- vprintk(fmt, args);
+
+ vaf.fmt = fmt;
+ vaf.va = &args;
+
+ printk(KERN_WARNING "b43legacy-%s warning: %pV",
+ (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan", &vaf);
+
va_end(args);
}
#if B43legacy_DEBUG
void b43legacydbg(struct b43legacy_wl *wl, const char *fmt, ...)
{
+ struct va_format vaf;
va_list args;
va_start(args, fmt);
- printk(KERN_DEBUG "b43legacy-%s debug: ",
- (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan");
- vprintk(fmt, args);
+
+ vaf.fmt = fmt;
+ vaf.va = &args;
+
+ printk(KERN_DEBUG "b43legacy-%s debug: %pV",
+ (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan", &vaf);
+
va_end(args);
}
#endif /* DEBUG */
diff --git a/drivers/net/wireless/b43legacy/rfkill.c b/drivers/net/wireless/b43legacy/rfkill.c
index d579df72b783..b90f223fb31c 100644
--- a/drivers/net/wireless/b43legacy/rfkill.c
+++ b/drivers/net/wireless/b43legacy/rfkill.c
@@ -29,7 +29,7 @@
/* Returns TRUE, if the radio is enabled in hardware. */
bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev)
{
- if (dev->phy.rev >= 3) {
+ if (dev->dev->id.revision >= 3) {
if (!(b43legacy_read32(dev, B43legacy_MMIO_RADIO_HWENABLED_HI)
& B43legacy_MMIO_RADIO_HWENABLED_HI_MASK))
return 1;
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index b82364258dc5..ed424574160e 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -106,6 +106,9 @@ config IWL5000
Intel WiFi Link 1000BGN
Intel Wireless WiFi 5150AGN
Intel Wireless WiFi 5100AGN, 5300AGN, and 5350AGN
+ Intel 6000 Gen 2 Series Wi-Fi Adapters (6000G2A and 6000G2B)
+ Intel WIreless WiFi Link 6050BGN Gen 2 Adapter
+ Intel 100 Series Wi-Fi Adapters (100BGN and 130BGN)
config IWL3945
tristate "Intel PRO/Wireless 3945ABG/BG Network Connection (iwl3945)"
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index 63edbe2e557f..93380f97835f 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -2,20 +2,27 @@ obj-$(CONFIG_IWLWIFI) += iwlcore.o
iwlcore-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o
iwlcore-objs += iwl-rx.o iwl-tx.o iwl-sta.o
iwlcore-objs += iwl-scan.o iwl-led.o
+iwlcore-$(CONFIG_IWL3945) += iwl-legacy.o
+iwlcore-$(CONFIG_IWL4965) += iwl-legacy.o
iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
iwlcore-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o
+# If 3945 is selected only, iwl-legacy.o will be added
+# to iwlcore-m above, but it needs to be built in.
+iwlcore-objs += $(iwlcore-m)
+
CFLAGS_iwl-devtrace.o := -I$(src)
# AGN
obj-$(CONFIG_IWLAGN) += iwlagn.o
-iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o iwl-agn-ict.o
-iwlagn-objs += iwl-agn-ucode.o iwl-agn-hcmd.o iwl-agn-tx.o
+iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o
+iwlagn-objs += iwl-agn-ucode.o iwl-agn-tx.o
iwlagn-objs += iwl-agn-lib.o iwl-agn-rx.o iwl-agn-calib.o
iwlagn-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-eeprom.o
iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-agn-debugfs.o
iwlagn-$(CONFIG_IWL4965) += iwl-4965.o
+iwlagn-$(CONFIG_IWL5000) += iwl-agn-rxon.o iwl-agn-hcmd.o iwl-agn-ict.o
iwlagn-$(CONFIG_IWL5000) += iwl-5000.o
iwlagn-$(CONFIG_IWL5000) += iwl-6000.o
iwlagn-$(CONFIG_IWL5000) += iwl-1000.o
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index db540910b110..3c983e426f25 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -211,14 +211,16 @@ static struct iwl_lib_ops iwl1000_lib = {
.calib_version = iwlagn_eeprom_calib_version,
.query_addr = iwlagn_eeprom_query_addr,
},
- .post_associate = iwl_post_associate,
- .isr = iwl_isr_ict,
- .config_ap = iwl_config_ap,
+ .isr_ops = {
+ .isr = iwl_isr_ict,
+ .free = iwl_free_isr_ict,
+ .alloc = iwl_alloc_isr_ict,
+ .reset = iwl_reset_ict,
+ .disable = iwl_disable_ict,
+ },
.temp_ops = {
.temperature = iwlagn_temperature,
},
- .manage_ibss_station = iwlagn_manage_ibss_station,
- .update_bcast_stations = iwl_update_bcast_stations,
.debugfs_ops = {
.rx_stats_read = iwl_ucode_rx_stats_read,
.tx_stats_read = iwl_ucode_tx_stats_read,
@@ -226,7 +228,6 @@ static struct iwl_lib_ops iwl1000_lib = {
.bt_stats_read = iwl_ucode_bt_stats_read,
.reply_tx_error = iwl_reply_tx_error_read,
},
- .recover_from_tx_stall = iwl_bg_monitor_recover,
.check_plcp_health = iwl_good_plcp_health,
.check_ack_health = iwl_good_ack_health,
.txfifo_flush = iwlagn_txfifo_flush,
@@ -243,6 +244,7 @@ static const struct iwl_ops iwl1000_ops = {
.hcmd = &iwlagn_hcmd,
.utils = &iwlagn_hcmd_utils,
.led = &iwlagn_led_ops,
+ .ieee80211_ops = &iwlagn_hw_ops,
};
static struct iwl_base_params iwl1000_base_params = {
@@ -259,7 +261,7 @@ static struct iwl_base_params iwl1000_base_params = {
.support_ct_kill_exit = true,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF,
.chain_noise_scale = 1000,
- .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
+ .wd_timeout = IWL_DEF_WD_TIMEOUT,
.max_event_log_size = 128,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
@@ -275,15 +277,13 @@ struct iwl_cfg iwl1000_bgn_cfg = {
.fw_name_pre = IWL1000_FW_PRE,
.ucode_api_max = IWL1000_UCODE_API_MAX,
.ucode_api_min = IWL1000_UCODE_API_MIN,
- .sku = IWL_SKU_G|IWL_SKU_N,
- .valid_tx_ant = ANT_A,
- .valid_rx_ant = ANT_AB,
.eeprom_ver = EEPROM_1000_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,
.ops = &iwl1000_ops,
.mod_params = &iwlagn_mod_params,
.base_params = &iwl1000_base_params,
.ht_params = &iwl1000_ht_params,
+ .led_mode = IWL_LED_BLINK,
};
struct iwl_cfg iwl1000_bg_cfg = {
@@ -291,45 +291,39 @@ struct iwl_cfg iwl1000_bg_cfg = {
.fw_name_pre = IWL1000_FW_PRE,
.ucode_api_max = IWL1000_UCODE_API_MAX,
.ucode_api_min = IWL1000_UCODE_API_MIN,
- .sku = IWL_SKU_G,
- .valid_tx_ant = ANT_A,
- .valid_rx_ant = ANT_AB,
.eeprom_ver = EEPROM_1000_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,
.ops = &iwl1000_ops,
.mod_params = &iwlagn_mod_params,
.base_params = &iwl1000_base_params,
+ .led_mode = IWL_LED_BLINK,
};
struct iwl_cfg iwl100_bgn_cfg = {
- .name = "Intel(R) 100 Series 1x1 BGN",
+ .name = "Intel(R) Centrino(R) Wireless-N 100 BGN",
.fw_name_pre = IWL100_FW_PRE,
.ucode_api_max = IWL100_UCODE_API_MAX,
.ucode_api_min = IWL100_UCODE_API_MIN,
- .sku = IWL_SKU_G|IWL_SKU_N,
- .valid_tx_ant = ANT_A,
- .valid_rx_ant = ANT_A,
.eeprom_ver = EEPROM_1000_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,
.ops = &iwl1000_ops,
.mod_params = &iwlagn_mod_params,
.base_params = &iwl1000_base_params,
.ht_params = &iwl1000_ht_params,
+ .led_mode = IWL_LED_RF_STATE,
};
struct iwl_cfg iwl100_bg_cfg = {
- .name = "Intel(R) 100 Series 1x1 BG",
+ .name = "Intel(R) Centrino(R) Wireless-N 100 BG",
.fw_name_pre = IWL100_FW_PRE,
.ucode_api_max = IWL100_UCODE_API_MAX,
.ucode_api_min = IWL100_UCODE_API_MIN,
- .sku = IWL_SKU_G,
- .valid_tx_ant = ANT_A,
- .valid_rx_ant = ANT_A,
.eeprom_ver = EEPROM_1000_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,
.ops = &iwl1000_ops,
.mod_params = &iwlagn_mod_params,
.base_params = &iwl1000_base_params,
+ .led_mode = IWL_LED_RF_STATE,
};
MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 176e52577673..a9b852be4509 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -51,6 +51,7 @@
#include "iwl-led.h"
#include "iwl-3945-led.h"
#include "iwl-3945-debugfs.h"
+#include "iwl-legacy.h"
#define IWL_DECLARE_RATE_INFO(r, ip, in, rp, rn, pp, np) \
[IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \
@@ -115,7 +116,7 @@ void iwl3945_disable_events(struct iwl_priv *priv)
u32 base; /* SRAM address of event log header */
u32 disable_ptr; /* SRAM address of event-disable bitmap array */
u32 array_size; /* # of u32 entries in array */
- u32 evt_disable[IWL_EVT_DISABLE_SIZE] = {
+ static const u32 evt_disable[IWL_EVT_DISABLE_SIZE] = {
0x00000000, /* 31 - 0 Event id numbers */
0x00000000, /* 63 - 32 */
0x00000000, /* 95 - 64 */
@@ -296,7 +297,7 @@ static void iwl3945_tx_queue_reclaim(struct iwl_priv *priv,
if (iwl_queue_space(q) > q->low_mark && (txq_id >= 0) &&
(txq_id != IWL39_CMD_QUEUE_NUM) &&
priv->mac80211_registered)
- iwl_wake_queue(priv, txq_id);
+ iwl_wake_queue(priv, txq);
}
/**
@@ -324,6 +325,7 @@ static void iwl3945_rx_reply_tx(struct iwl_priv *priv,
return;
}
+ txq->time_stamp = jiffies;
info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb);
ieee80211_tx_info_clear_status(info);
@@ -1451,6 +1453,10 @@ static int iwl3945_send_tx_power(struct iwl_priv *priv)
};
u16 chan;
+ if (WARN_ONCE(test_bit(STATUS_SCAN_HW, &priv->status),
+ "TX Power requested while scanning!\n"))
+ return -EAGAIN;
+
chan = le16_to_cpu(priv->contexts[IWL_RXON_CTX_BSS].active.channel);
txpower.band = (priv->band == IEEE80211_BAND_5GHZ) ? 0 : 1;
@@ -1779,6 +1785,9 @@ int iwl3945_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
int rc = 0;
bool new_assoc = !!(staging_rxon->filter_flags & RXON_FILTER_ASSOC_MSK);
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return -EINVAL;
+
if (!iwl_is_alive(priv))
return -1;
@@ -2722,11 +2731,9 @@ static struct iwl_lib_ops iwl3945_lib = {
},
.send_tx_power = iwl3945_send_tx_power,
.is_valid_rtc_data_addr = iwl3945_hw_valid_rtc_data_addr,
- .post_associate = iwl3945_post_associate,
- .isr = iwl_isr_legacy,
- .config_ap = iwl3945_config_ap,
- .manage_ibss_station = iwl3945_manage_ibss_station,
- .recover_from_tx_stall = iwl_bg_monitor_recover,
+ .isr_ops = {
+ .isr = iwl_isr_legacy,
+ },
.check_plcp_health = iwl3945_good_plcp_health,
.debugfs_ops = {
@@ -2736,10 +2743,16 @@ static struct iwl_lib_ops iwl3945_lib = {
},
};
+static const struct iwl_legacy_ops iwl3945_legacy_ops = {
+ .post_associate = iwl3945_post_associate,
+ .config_ap = iwl3945_config_ap,
+ .manage_ibss_station = iwl3945_manage_ibss_station,
+};
+
static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
.get_hcmd_size = iwl3945_get_hcmd_size,
.build_addsta_hcmd = iwl3945_build_addsta_hcmd,
- .tx_cmd_protection = iwlcore_tx_cmd_protection,
+ .tx_cmd_protection = iwl_legacy_tx_cmd_protection,
.request_scan = iwl3945_request_scan,
.post_scan = iwl3945_post_scan,
};
@@ -2749,6 +2762,8 @@ static const struct iwl_ops iwl3945_ops = {
.hcmd = &iwl3945_hcmd,
.utils = &iwl3945_hcmd_utils,
.led = &iwl3945_led_ops,
+ .legacy = &iwl3945_legacy_ops,
+ .ieee80211_ops = &iwl3945_hw_ops,
};
static struct iwl_base_params iwl3945_base_params = {
@@ -2761,7 +2776,7 @@ static struct iwl_base_params iwl3945_base_params = {
.led_compensation = 64,
.broken_powersave = true,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
- .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
+ .wd_timeout = IWL_DEF_WD_TIMEOUT,
.max_event_log_size = 512,
.tx_power_by_driver = true,
};
@@ -2776,6 +2791,7 @@ static struct iwl_cfg iwl3945_bg_cfg = {
.ops = &iwl3945_ops,
.mod_params = &iwl3945_mod_params,
.base_params = &iwl3945_base_params,
+ .led_mode = IWL_LED_BLINK,
};
static struct iwl_cfg iwl3945_abg_cfg = {
@@ -2788,6 +2804,7 @@ static struct iwl_cfg iwl3945_abg_cfg = {
.ops = &iwl3945_ops,
.mod_params = &iwl3945_mod_params,
.base_params = &iwl3945_base_params,
+ .led_mode = IWL_LED_BLINK,
};
DEFINE_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 09391f0ee61f..3eef1eb74a78 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -264,10 +264,8 @@ void iwl3945_reply_statistics(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb);
extern void iwl3945_disable_events(struct iwl_priv *priv);
extern int iwl4965_get_temperature(const struct iwl_priv *priv);
-extern void iwl3945_post_associate(struct iwl_priv *priv,
- struct ieee80211_vif *vif);
-extern void iwl3945_config_ap(struct iwl_priv *priv,
- struct ieee80211_vif *vif);
+extern void iwl3945_post_associate(struct iwl_priv *priv);
+extern void iwl3945_config_ap(struct iwl_priv *priv);
extern int iwl3945_commit_rxon(struct iwl_priv *priv,
struct iwl_rxon_context *ctx);
@@ -282,6 +280,8 @@ extern int iwl3945_commit_rxon(struct iwl_priv *priv,
*/
extern u8 iwl3945_hw_find_station(struct iwl_priv *priv, const u8 *bssid);
+extern struct ieee80211_ops iwl3945_hw_ops;
+
/*
* Forward declare iwl-3945.c functions for iwl-base.c
*/
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index b207e3e9299f..3f1e5f1bf847 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -48,6 +48,7 @@
#include "iwl-agn-led.h"
#include "iwl-agn.h"
#include "iwl-agn-debugfs.h"
+#include "iwl-legacy.h"
static int iwl4965_send_tx_power(struct iwl_priv *priv);
static int iwl4965_hw_get_temperature(struct iwl_priv *priv);
@@ -1377,13 +1378,9 @@ static int iwl4965_send_tx_power(struct iwl_priv *priv)
u8 ctrl_chan_high = 0;
struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
- if (test_bit(STATUS_SCANNING, &priv->status)) {
- /* If this gets hit a lot, switch it to a BUG() and catch
- * the stack trace to find out who is calling this during
- * a scan. */
- IWL_WARN(priv, "TX Power requested while scanning!\n");
+ if (WARN_ONCE(test_bit(STATUS_SCAN_HW, &priv->status),
+ "TX Power requested while scanning!\n"))
return -EAGAIN;
- }
band = priv->band == IEEE80211_BAND_2GHZ;
@@ -1447,6 +1444,142 @@ static int iwl4965_send_rxon_assoc(struct iwl_priv *priv,
return ret;
}
+static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
+{
+ /* cast away the const for active_rxon in this function */
+ struct iwl_rxon_cmd *active_rxon = (void *)&ctx->active;
+ int ret;
+ bool new_assoc =
+ !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK);
+
+ if (!iwl_is_alive(priv))
+ return -EBUSY;
+
+ if (!ctx->is_active)
+ return 0;
+
+ /* always get timestamp with Rx frame */
+ ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK;
+
+ ret = iwl_check_rxon_cmd(priv, ctx);
+ if (ret) {
+ IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");
+ return -EINVAL;
+ }
+
+ /*
+ * receive commit_rxon request
+ * abort any previous channel switch if still in process
+ */
+ if (priv->switch_rxon.switch_in_progress &&
+ (priv->switch_rxon.channel != ctx->staging.channel)) {
+ IWL_DEBUG_11H(priv, "abort channel switch on %d\n",
+ le16_to_cpu(priv->switch_rxon.channel));
+ iwl_chswitch_done(priv, false);
+ }
+
+ /* If we don't need to send a full RXON, we can use
+ * iwl_rxon_assoc_cmd which is used to reconfigure filter
+ * and other flags for the current radio configuration. */
+ if (!iwl_full_rxon_required(priv, ctx)) {
+ ret = iwl_send_rxon_assoc(priv, ctx);
+ if (ret) {
+ IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret);
+ return ret;
+ }
+
+ memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
+ iwl_print_rx_config_cmd(priv, ctx);
+ return 0;
+ }
+
+ /* If we are currently associated and the new config requires
+ * an RXON_ASSOC and the new config wants the associated mask enabled,
+ * we must clear the associated from the active configuration
+ * before we apply the new config */
+ if (iwl_is_associated_ctx(ctx) && new_assoc) {
+ IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n");
+ active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+
+ ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
+ sizeof(struct iwl_rxon_cmd),
+ active_rxon);
+
+ /* If the mask clearing failed then we set
+ * active_rxon back to what it was previously */
+ if (ret) {
+ active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK;
+ IWL_ERR(priv, "Error clearing ASSOC_MSK (%d)\n", ret);
+ return ret;
+ }
+ iwl_clear_ucode_stations(priv, ctx);
+ iwl_restore_stations(priv, ctx);
+ ret = iwl_restore_default_wep_keys(priv, ctx);
+ if (ret) {
+ IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
+ return ret;
+ }
+ }
+
+ IWL_DEBUG_INFO(priv, "Sending RXON\n"
+ "* with%s RXON_FILTER_ASSOC_MSK\n"
+ "* channel = %d\n"
+ "* bssid = %pM\n",
+ (new_assoc ? "" : "out"),
+ le16_to_cpu(ctx->staging.channel),
+ ctx->staging.bssid_addr);
+
+ iwl_set_rxon_hwcrypto(priv, ctx, !priv->cfg->mod_params->sw_crypto);
+
+ /* Apply the new configuration
+ * RXON unassoc clears the station table in uCode so restoration of
+ * stations is needed after it (the RXON command) completes
+ */
+ if (!new_assoc) {
+ ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
+ sizeof(struct iwl_rxon_cmd), &ctx->staging);
+ if (ret) {
+ IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
+ return ret;
+ }
+ IWL_DEBUG_INFO(priv, "Return from !new_assoc RXON.\n");
+ memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
+ iwl_clear_ucode_stations(priv, ctx);
+ iwl_restore_stations(priv, ctx);
+ ret = iwl_restore_default_wep_keys(priv, ctx);
+ if (ret) {
+ IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
+ return ret;
+ }
+ }
+ if (new_assoc) {
+ priv->start_calib = 0;
+ /* Apply the new configuration
+ * RXON assoc doesn't clear the station table in uCode,
+ */
+ ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
+ sizeof(struct iwl_rxon_cmd), &ctx->staging);
+ if (ret) {
+ IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
+ return ret;
+ }
+ memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
+ }
+ iwl_print_rx_config_cmd(priv, ctx);
+
+ iwl_init_sensitivity(priv);
+
+ /* If we issue a new RXON command which required a tune then we must
+ * send a new TXPOWER command or we won't be able to Tx any frames */
+ ret = iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);
+ if (ret) {
+ IWL_ERR(priv, "Error sending TX power (%d)\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
static int iwl4965_hw_channel_switch(struct iwl_priv *priv,
struct ieee80211_channel_switch *ch_switch)
{
@@ -1554,22 +1687,6 @@ static void iwl4965_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
}
/**
- * sign_extend - Sign extend a value using specified bit as sign-bit
- *
- * Example: sign_extend(9, 3) would return -7 as bit3 of 1001b is 1
- * and bit0..2 is 001b which when sign extended to 1111111111111001b is -7.
- *
- * @param oper value to sign extend
- * @param index 0 based bit index (0<=index<32) to sign bit
- */
-static s32 sign_extend(u32 oper, int index)
-{
- u8 shift = 31 - index;
-
- return (s32)(oper << shift) >> shift;
-}
-
-/**
* iwl4965_hw_get_temperature - return the calibrated temperature (in Kelvin)
* @statistics: Provides the temperature reading from the uCode
*
@@ -1606,9 +1723,9 @@ static int iwl4965_hw_get_temperature(struct iwl_priv *priv)
* "initialize" ALIVE response.
*/
if (!test_bit(STATUS_TEMPERATURE, &priv->status))
- vt = sign_extend(R4, 23);
+ vt = sign_extend32(R4, 23);
else
- vt = sign_extend(le32_to_cpu(priv->_agn.statistics.
+ vt = sign_extend32(le32_to_cpu(priv->_agn.statistics.
general.common.temperature), 23);
IWL_DEBUG_TEMP(priv, "Calib values R[1-3]: %d %d %d R4: %d\n", R1, R2, R3, vt);
@@ -2081,6 +2198,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
return;
}
+ txq->time_stamp = jiffies;
info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb);
memset(&info->status, 0, sizeof(info->status));
@@ -2121,12 +2239,8 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
if (priv->mac80211_registered &&
(iwl_queue_space(&txq->q) > txq->q.low_mark) &&
- (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) {
- if (agg->state == IWL_AGG_OFF)
- iwl_wake_queue(priv, txq_id);
- else
- iwl_wake_queue(priv, txq->swq_id);
- }
+ (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA))
+ iwl_wake_queue(priv, txq);
}
} else {
info->status.rates[0].count = tx_resp->failure_frame + 1;
@@ -2150,7 +2264,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
if (priv->mac80211_registered &&
(iwl_queue_space(&txq->q) > txq->q.low_mark))
- iwl_wake_queue(priv, txq_id);
+ iwl_wake_queue(priv, txq);
}
if (qc && likely(sta_id != IWL_INVALID_STATION))
iwlagn_txq_check_empty(priv, sta_id, tid, txq_id);
@@ -2216,7 +2330,7 @@ static void iwl4965_cancel_deferred_work(struct iwl_priv *priv)
static struct iwl_hcmd_ops iwl4965_hcmd = {
.rxon_assoc = iwl4965_send_rxon_assoc,
- .commit_rxon = iwlagn_commit_rxon,
+ .commit_rxon = iwl4965_commit_rxon,
.set_rxon_chain = iwlagn_set_rxon_chain,
.send_bt_config = iwl_send_bt_config,
};
@@ -2233,12 +2347,155 @@ static void iwl4965_post_scan(struct iwl_priv *priv)
iwlcore_commit_rxon(priv, ctx);
}
+static void iwl4965_post_associate(struct iwl_priv *priv)
+{
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
+ struct ieee80211_vif *vif = ctx->vif;
+ struct ieee80211_conf *conf = NULL;
+ int ret = 0;
+
+ if (!vif || !priv->is_open)
+ return;
+
+ if (vif->type == NL80211_IFTYPE_AP) {
+ IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__);
+ return;
+ }
+
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return;
+
+ iwl_scan_cancel_timeout(priv, 200);
+
+ conf = ieee80211_get_hw_conf(priv->hw);
+
+ ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ iwlcore_commit_rxon(priv, ctx);
+
+ ret = iwl_send_rxon_timing(priv, ctx);
+ if (ret)
+ IWL_WARN(priv, "RXON timing - "
+ "Attempting to continue.\n");
+
+ ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
+
+ iwl_set_rxon_ht(priv, &priv->current_ht_config);
+
+ if (priv->cfg->ops->hcmd->set_rxon_chain)
+ priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
+
+ ctx->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid);
+
+ IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
+ vif->bss_conf.aid, vif->bss_conf.beacon_int);
+
+ if (vif->bss_conf.use_short_preamble)
+ ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
+ else
+ ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+
+ if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
+ if (vif->bss_conf.use_short_slot)
+ ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
+ else
+ ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
+ }
+
+ iwlcore_commit_rxon(priv, ctx);
+
+ IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n",
+ vif->bss_conf.aid, ctx->active.bssid_addr);
+
+ switch (vif->type) {
+ case NL80211_IFTYPE_STATION:
+ break;
+ case NL80211_IFTYPE_ADHOC:
+ iwlagn_send_beacon_cmd(priv);
+ break;
+ default:
+ IWL_ERR(priv, "%s Should not be called in %d mode\n",
+ __func__, vif->type);
+ break;
+ }
+
+ /* the chain noise calibration will enabled PM upon completion
+ * If chain noise has already been run, then we need to enable
+ * power management here */
+ if (priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE)
+ iwl_power_update_mode(priv, false);
+
+ /* Enable Rx differential gain and sensitivity calibrations */
+ iwl_chain_noise_reset(priv);
+ priv->start_calib = 1;
+}
+
+static void iwl4965_config_ap(struct iwl_priv *priv)
+{
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
+ struct ieee80211_vif *vif = ctx->vif;
+ int ret = 0;
+
+ lockdep_assert_held(&priv->mutex);
+
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return;
+
+ /* The following should be done only at AP bring up */
+ if (!iwl_is_associated_ctx(ctx)) {
+
+ /* RXON - unassoc (to set timing command) */
+ ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ iwlcore_commit_rxon(priv, ctx);
+
+ /* RXON Timing */
+ ret = iwl_send_rxon_timing(priv, ctx);
+ if (ret)
+ IWL_WARN(priv, "RXON timing failed - "
+ "Attempting to continue.\n");
+
+ /* AP has all antennas */
+ priv->chain_noise_data.active_chains =
+ priv->hw_params.valid_rx_ant;
+ iwl_set_rxon_ht(priv, &priv->current_ht_config);
+ if (priv->cfg->ops->hcmd->set_rxon_chain)
+ priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
+
+ ctx->staging.assoc_id = 0;
+
+ if (vif->bss_conf.use_short_preamble)
+ ctx->staging.flags |=
+ RXON_FLG_SHORT_PREAMBLE_MSK;
+ else
+ ctx->staging.flags &=
+ ~RXON_FLG_SHORT_PREAMBLE_MSK;
+
+ if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
+ if (vif->bss_conf.use_short_slot)
+ ctx->staging.flags |=
+ RXON_FLG_SHORT_SLOT_MSK;
+ else
+ ctx->staging.flags &=
+ ~RXON_FLG_SHORT_SLOT_MSK;
+ }
+ /* need to send beacon cmd before committing assoc RXON! */
+ iwlagn_send_beacon_cmd(priv);
+ /* restore RXON assoc */
+ ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
+ iwlcore_commit_rxon(priv, ctx);
+ }
+ iwlagn_send_beacon_cmd(priv);
+
+ /* FIXME - we need to add code here to detect a totally new
+ * configuration, reset the AP, unassoc, rxon timing, assoc,
+ * clear sta table, add BCAST sta... */
+}
+
static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
.get_hcmd_size = iwl4965_get_hcmd_size,
.build_addsta_hcmd = iwl4965_build_addsta_hcmd,
.chain_noise_reset = iwl4965_chain_noise_reset,
.gain_computation = iwl4965_gain_computation,
- .tx_cmd_protection = iwlcore_tx_cmd_protection,
+ .tx_cmd_protection = iwl_legacy_tx_cmd_protection,
.calc_rssi = iwl4965_calc_rssi,
.request_scan = iwlagn_request_scan,
.post_scan = iwl4965_post_scan,
@@ -2285,14 +2542,12 @@ static struct iwl_lib_ops iwl4965_lib = {
},
.send_tx_power = iwl4965_send_tx_power,
.update_chain_flags = iwl_update_chain_flags,
- .post_associate = iwl_post_associate,
- .config_ap = iwl_config_ap,
- .isr = iwl_isr_legacy,
+ .isr_ops = {
+ .isr = iwl_isr_legacy,
+ },
.temp_ops = {
.temperature = iwl4965_temperature_calib,
},
- .manage_ibss_station = iwlagn_manage_ibss_station,
- .update_bcast_stations = iwl_update_bcast_stations,
.debugfs_ops = {
.rx_stats_read = iwl_ucode_rx_stats_read,
.tx_stats_read = iwl_ucode_tx_stats_read,
@@ -2300,15 +2555,46 @@ static struct iwl_lib_ops iwl4965_lib = {
.bt_stats_read = iwl_ucode_bt_stats_read,
.reply_tx_error = iwl_reply_tx_error_read,
},
- .recover_from_tx_stall = iwl_bg_monitor_recover,
.check_plcp_health = iwl_good_plcp_health,
};
+static const struct iwl_legacy_ops iwl4965_legacy_ops = {
+ .post_associate = iwl4965_post_associate,
+ .config_ap = iwl4965_config_ap,
+ .manage_ibss_station = iwlagn_manage_ibss_station,
+ .update_bcast_stations = iwl_update_bcast_stations,
+};
+
+struct ieee80211_ops iwl4965_hw_ops = {
+ .tx = iwlagn_mac_tx,
+ .start = iwlagn_mac_start,
+ .stop = iwlagn_mac_stop,
+ .add_interface = iwl_mac_add_interface,
+ .remove_interface = iwl_mac_remove_interface,
+ .change_interface = iwl_mac_change_interface,
+ .config = iwl_legacy_mac_config,
+ .configure_filter = iwlagn_configure_filter,
+ .set_key = iwlagn_mac_set_key,
+ .update_tkip_key = iwlagn_mac_update_tkip_key,
+ .conf_tx = iwl_mac_conf_tx,
+ .reset_tsf = iwl_legacy_mac_reset_tsf,
+ .bss_info_changed = iwl_legacy_mac_bss_info_changed,
+ .ampdu_action = iwlagn_mac_ampdu_action,
+ .hw_scan = iwl_mac_hw_scan,
+ .sta_add = iwlagn_mac_sta_add,
+ .sta_remove = iwl_mac_sta_remove,
+ .channel_switch = iwlagn_mac_channel_switch,
+ .flush = iwlagn_mac_flush,
+ .tx_last_beacon = iwl_mac_tx_last_beacon,
+};
+
static const struct iwl_ops iwl4965_ops = {
.lib = &iwl4965_lib,
.hcmd = &iwl4965_hcmd,
.utils = &iwl4965_hcmd_utils,
.led = &iwlagn_led_ops,
+ .legacy = &iwl4965_legacy_ops,
+ .ieee80211_ops = &iwl4965_hw_ops,
};
static struct iwl_base_params iwl4965_base_params = {
@@ -2323,13 +2609,14 @@ static struct iwl_base_params iwl4965_base_params = {
.led_compensation = 61,
.chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
- .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
+ .wd_timeout = IWL_DEF_WD_TIMEOUT,
.temperature_kelvin = true,
.max_event_log_size = 512,
.tx_power_by_driver = true,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
.chain_noise_calib_by_driver = true,
+ .no_agg_framecnt_info = true,
};
struct iwl_cfg iwl4965_agn_cfg = {
@@ -2337,7 +2624,6 @@ struct iwl_cfg iwl4965_agn_cfg = {
.fw_name_pre = IWL4965_FW_PRE,
.ucode_api_max = IWL4965_UCODE_API_MAX,
.ucode_api_min = IWL4965_UCODE_API_MIN,
- .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
.valid_tx_ant = ANT_AB,
.valid_rx_ant = ANT_ABC,
.eeprom_ver = EEPROM_4965_EEPROM_VERSION,
@@ -2345,6 +2631,7 @@ struct iwl_cfg iwl4965_agn_cfg = {
.ops = &iwl4965_ops,
.mod_params = &iwlagn_mod_params,
.base_params = &iwl4965_base_params,
+ .led_mode = IWL_LED_BLINK,
/*
* Force use of chains B and C for scan RX on 5 GHz band
* because the device has off-channel reception on chain A.
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index fd9fbc93ea1b..8435e5a4e69d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -385,14 +385,16 @@ static struct iwl_lib_ops iwl5000_lib = {
.calib_version = iwlagn_eeprom_calib_version,
.query_addr = iwlagn_eeprom_query_addr,
},
- .post_associate = iwl_post_associate,
- .isr = iwl_isr_ict,
- .config_ap = iwl_config_ap,
+ .isr_ops = {
+ .isr = iwl_isr_ict,
+ .free = iwl_free_isr_ict,
+ .alloc = iwl_alloc_isr_ict,
+ .reset = iwl_reset_ict,
+ .disable = iwl_disable_ict,
+ },
.temp_ops = {
.temperature = iwlagn_temperature,
},
- .manage_ibss_station = iwlagn_manage_ibss_station,
- .update_bcast_stations = iwl_update_bcast_stations,
.debugfs_ops = {
.rx_stats_read = iwl_ucode_rx_stats_read,
.tx_stats_read = iwl_ucode_tx_stats_read,
@@ -400,7 +402,6 @@ static struct iwl_lib_ops iwl5000_lib = {
.bt_stats_read = iwl_ucode_bt_stats_read,
.reply_tx_error = iwl_reply_tx_error_read,
},
- .recover_from_tx_stall = iwl_bg_monitor_recover,
.check_plcp_health = iwl_good_plcp_health,
.check_ack_health = iwl_good_ack_health,
.txfifo_flush = iwlagn_txfifo_flush,
@@ -453,14 +454,16 @@ static struct iwl_lib_ops iwl5150_lib = {
.calib_version = iwlagn_eeprom_calib_version,
.query_addr = iwlagn_eeprom_query_addr,
},
- .post_associate = iwl_post_associate,
- .isr = iwl_isr_ict,
- .config_ap = iwl_config_ap,
+ .isr_ops = {
+ .isr = iwl_isr_ict,
+ .free = iwl_free_isr_ict,
+ .alloc = iwl_alloc_isr_ict,
+ .reset = iwl_reset_ict,
+ .disable = iwl_disable_ict,
+ },
.temp_ops = {
.temperature = iwl5150_temperature,
},
- .manage_ibss_station = iwlagn_manage_ibss_station,
- .update_bcast_stations = iwl_update_bcast_stations,
.debugfs_ops = {
.rx_stats_read = iwl_ucode_rx_stats_read,
.tx_stats_read = iwl_ucode_tx_stats_read,
@@ -468,7 +471,6 @@ static struct iwl_lib_ops iwl5150_lib = {
.bt_stats_read = iwl_ucode_bt_stats_read,
.reply_tx_error = iwl_reply_tx_error_read,
},
- .recover_from_tx_stall = iwl_bg_monitor_recover,
.check_plcp_health = iwl_good_plcp_health,
.check_ack_health = iwl_good_ack_health,
.txfifo_flush = iwlagn_txfifo_flush,
@@ -485,6 +487,7 @@ static const struct iwl_ops iwl5000_ops = {
.hcmd = &iwlagn_hcmd,
.utils = &iwlagn_hcmd_utils,
.led = &iwlagn_led_ops,
+ .ieee80211_ops = &iwlagn_hw_ops,
};
static const struct iwl_ops iwl5150_ops = {
@@ -492,6 +495,7 @@ static const struct iwl_ops iwl5150_ops = {
.hcmd = &iwlagn_hcmd,
.utils = &iwlagn_hcmd_utils,
.led = &iwlagn_led_ops,
+ .ieee80211_ops = &iwlagn_hw_ops,
};
static struct iwl_base_params iwl5000_base_params = {
@@ -505,7 +509,7 @@ static struct iwl_base_params iwl5000_base_params = {
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
.chain_noise_scale = 1000,
- .monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
+ .wd_timeout = IWL_LONG_WD_TIMEOUT,
.max_event_log_size = 512,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
@@ -521,15 +525,13 @@ struct iwl_cfg iwl5300_agn_cfg = {
.fw_name_pre = IWL5000_FW_PRE,
.ucode_api_max = IWL5000_UCODE_API_MAX,
.ucode_api_min = IWL5000_UCODE_API_MIN,
- .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
- .valid_tx_ant = ANT_ABC,
- .valid_rx_ant = ANT_ABC,
.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
.ops = &iwl5000_ops,
.mod_params = &iwlagn_mod_params,
.base_params = &iwl5000_base_params,
.ht_params = &iwl5000_ht_params,
+ .led_mode = IWL_LED_BLINK,
};
struct iwl_cfg iwl5100_bgn_cfg = {
@@ -537,15 +539,15 @@ struct iwl_cfg iwl5100_bgn_cfg = {
.fw_name_pre = IWL5000_FW_PRE,
.ucode_api_max = IWL5000_UCODE_API_MAX,
.ucode_api_min = IWL5000_UCODE_API_MIN,
- .sku = IWL_SKU_G|IWL_SKU_N,
- .valid_tx_ant = ANT_B,
- .valid_rx_ant = ANT_AB,
+ .valid_tx_ant = ANT_B, /* .cfg overwrite */
+ .valid_rx_ant = ANT_AB, /* .cfg overwrite */
.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
.ops = &iwl5000_ops,
.mod_params = &iwlagn_mod_params,
.base_params = &iwl5000_base_params,
.ht_params = &iwl5000_ht_params,
+ .led_mode = IWL_LED_BLINK,
};
struct iwl_cfg iwl5100_abg_cfg = {
@@ -553,14 +555,14 @@ struct iwl_cfg iwl5100_abg_cfg = {
.fw_name_pre = IWL5000_FW_PRE,
.ucode_api_max = IWL5000_UCODE_API_MAX,
.ucode_api_min = IWL5000_UCODE_API_MIN,
- .sku = IWL_SKU_A|IWL_SKU_G,
- .valid_tx_ant = ANT_B,
- .valid_rx_ant = ANT_AB,
+ .valid_tx_ant = ANT_B, /* .cfg overwrite */
+ .valid_rx_ant = ANT_AB, /* .cfg overwrite */
.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
.ops = &iwl5000_ops,
.mod_params = &iwlagn_mod_params,
.base_params = &iwl5000_base_params,
+ .led_mode = IWL_LED_BLINK,
};
struct iwl_cfg iwl5100_agn_cfg = {
@@ -568,15 +570,15 @@ struct iwl_cfg iwl5100_agn_cfg = {
.fw_name_pre = IWL5000_FW_PRE,
.ucode_api_max = IWL5000_UCODE_API_MAX,
.ucode_api_min = IWL5000_UCODE_API_MIN,
- .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
- .valid_tx_ant = ANT_B,
- .valid_rx_ant = ANT_AB,
+ .valid_tx_ant = ANT_B, /* .cfg overwrite */
+ .valid_rx_ant = ANT_AB, /* .cfg overwrite */
.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
.ops = &iwl5000_ops,
.mod_params = &iwlagn_mod_params,
.base_params = &iwl5000_base_params,
.ht_params = &iwl5000_ht_params,
+ .led_mode = IWL_LED_BLINK,
};
struct iwl_cfg iwl5350_agn_cfg = {
@@ -584,15 +586,13 @@ struct iwl_cfg iwl5350_agn_cfg = {
.fw_name_pre = IWL5000_FW_PRE,
.ucode_api_max = IWL5000_UCODE_API_MAX,
.ucode_api_min = IWL5000_UCODE_API_MIN,
- .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
- .valid_tx_ant = ANT_ABC,
- .valid_rx_ant = ANT_ABC,
.eeprom_ver = EEPROM_5050_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
.ops = &iwl5000_ops,
.mod_params = &iwlagn_mod_params,
.base_params = &iwl5000_base_params,
.ht_params = &iwl5000_ht_params,
+ .led_mode = IWL_LED_BLINK,
};
struct iwl_cfg iwl5150_agn_cfg = {
@@ -600,9 +600,6 @@ struct iwl_cfg iwl5150_agn_cfg = {
.fw_name_pre = IWL5150_FW_PRE,
.ucode_api_max = IWL5150_UCODE_API_MAX,
.ucode_api_min = IWL5150_UCODE_API_MIN,
- .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
- .valid_tx_ant = ANT_A,
- .valid_rx_ant = ANT_AB,
.eeprom_ver = EEPROM_5050_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
.ops = &iwl5150_ops,
@@ -610,6 +607,7 @@ struct iwl_cfg iwl5150_agn_cfg = {
.base_params = &iwl5000_base_params,
.ht_params = &iwl5000_ht_params,
.need_dc_calib = true,
+ .led_mode = IWL_LED_BLINK,
};
struct iwl_cfg iwl5150_abg_cfg = {
@@ -617,15 +615,13 @@ struct iwl_cfg iwl5150_abg_cfg = {
.fw_name_pre = IWL5150_FW_PRE,
.ucode_api_max = IWL5150_UCODE_API_MAX,
.ucode_api_min = IWL5150_UCODE_API_MIN,
- .sku = IWL_SKU_A|IWL_SKU_G,
- .valid_tx_ant = ANT_A,
- .valid_rx_ant = ANT_AB,
.eeprom_ver = EEPROM_5050_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
.ops = &iwl5150_ops,
.mod_params = &iwlagn_mod_params,
.base_params = &iwl5000_base_params,
.need_dc_calib = true,
+ .led_mode = IWL_LED_BLINK,
};
MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 11e6532fc573..808942cc2991 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -53,13 +53,11 @@
#define IWL6000_UCODE_API_MAX 4
#define IWL6050_UCODE_API_MAX 5
#define IWL6000G2_UCODE_API_MAX 5
-#define IWL130_UCODE_API_MAX 5
/* Lowest firmware API version supported */
#define IWL6000_UCODE_API_MIN 4
#define IWL6050_UCODE_API_MIN 4
#define IWL6000G2_UCODE_API_MIN 4
-#define IWL130_UCODE_API_MIN 5
#define IWL6000_FW_PRE "iwlwifi-6000-"
#define _IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE #api ".ucode"
@@ -77,10 +75,6 @@
#define _IWL6000G2B_MODULE_FIRMWARE(api) IWL6000G2B_FW_PRE #api ".ucode"
#define IWL6000G2B_MODULE_FIRMWARE(api) _IWL6000G2B_MODULE_FIRMWARE(api)
-#define IWL130_FW_PRE "iwlwifi-130-"
-#define _IWL130_MODULE_FIRMWARE(api) IWL130_FW_PRE #api ".ucode"
-#define IWL130_MODULE_FIRMWARE(api) _IWL130_MODULE_FIRMWARE(api)
-
static void iwl6000_set_ct_threshold(struct iwl_priv *priv)
{
/* want Celsius */
@@ -328,14 +322,16 @@ static struct iwl_lib_ops iwl6000_lib = {
.query_addr = iwlagn_eeprom_query_addr,
.update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower,
},
- .post_associate = iwl_post_associate,
- .isr = iwl_isr_ict,
- .config_ap = iwl_config_ap,
+ .isr_ops = {
+ .isr = iwl_isr_ict,
+ .free = iwl_free_isr_ict,
+ .alloc = iwl_alloc_isr_ict,
+ .reset = iwl_reset_ict,
+ .disable = iwl_disable_ict,
+ },
.temp_ops = {
.temperature = iwlagn_temperature,
},
- .manage_ibss_station = iwlagn_manage_ibss_station,
- .update_bcast_stations = iwl_update_bcast_stations,
.debugfs_ops = {
.rx_stats_read = iwl_ucode_rx_stats_read,
.tx_stats_read = iwl_ucode_tx_stats_read,
@@ -343,7 +339,6 @@ static struct iwl_lib_ops iwl6000_lib = {
.bt_stats_read = iwl_ucode_bt_stats_read,
.reply_tx_error = iwl_reply_tx_error_read,
},
- .recover_from_tx_stall = iwl_bg_monitor_recover,
.check_plcp_health = iwl_good_plcp_health,
.check_ack_health = iwl_good_ack_health,
.txfifo_flush = iwlagn_txfifo_flush,
@@ -399,14 +394,16 @@ static struct iwl_lib_ops iwl6000g2b_lib = {
.query_addr = iwlagn_eeprom_query_addr,
.update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower,
},
- .post_associate = iwl_post_associate,
- .isr = iwl_isr_ict,
- .config_ap = iwl_config_ap,
+ .isr_ops = {
+ .isr = iwl_isr_ict,
+ .free = iwl_free_isr_ict,
+ .alloc = iwl_alloc_isr_ict,
+ .reset = iwl_reset_ict,
+ .disable = iwl_disable_ict,
+ },
.temp_ops = {
.temperature = iwlagn_temperature,
},
- .manage_ibss_station = iwlagn_manage_ibss_station,
- .update_bcast_stations = iwl_update_bcast_stations,
.debugfs_ops = {
.rx_stats_read = iwl_ucode_rx_stats_read,
.tx_stats_read = iwl_ucode_tx_stats_read,
@@ -414,7 +411,6 @@ static struct iwl_lib_ops iwl6000g2b_lib = {
.bt_stats_read = iwl_ucode_bt_stats_read,
.reply_tx_error = iwl_reply_tx_error_read,
},
- .recover_from_tx_stall = iwl_bg_monitor_recover,
.check_plcp_health = iwl_good_plcp_health,
.check_ack_health = iwl_good_ack_health,
.txfifo_flush = iwlagn_txfifo_flush,
@@ -439,6 +435,7 @@ static const struct iwl_ops iwl6000_ops = {
.hcmd = &iwlagn_hcmd,
.utils = &iwlagn_hcmd_utils,
.led = &iwlagn_led_ops,
+ .ieee80211_ops = &iwlagn_hw_ops,
};
static const struct iwl_ops iwl6050_ops = {
@@ -447,6 +444,7 @@ static const struct iwl_ops iwl6050_ops = {
.utils = &iwlagn_hcmd_utils,
.led = &iwlagn_led_ops,
.nic = &iwl6050_nic_ops,
+ .ieee80211_ops = &iwlagn_hw_ops,
};
static const struct iwl_ops iwl6050g2_ops = {
@@ -455,6 +453,7 @@ static const struct iwl_ops iwl6050g2_ops = {
.utils = &iwlagn_hcmd_utils,
.led = &iwlagn_led_ops,
.nic = &iwl6050g2_nic_ops,
+ .ieee80211_ops = &iwlagn_hw_ops,
};
static const struct iwl_ops iwl6000g2b_ops = {
@@ -462,6 +461,7 @@ static const struct iwl_ops iwl6000g2b_ops = {
.hcmd = &iwlagn_bt_hcmd,
.utils = &iwlagn_hcmd_utils,
.led = &iwlagn_led_ops,
+ .ieee80211_ops = &iwlagn_hw_ops,
};
static struct iwl_base_params iwl6000_base_params = {
@@ -480,11 +480,12 @@ static struct iwl_base_params iwl6000_base_params = {
.support_ct_kill_exit = true,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
.chain_noise_scale = 1000,
- .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
+ .wd_timeout = IWL_DEF_WD_TIMEOUT,
.max_event_log_size = 512,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
.chain_noise_calib_by_driver = true,
+ .shadow_reg_enable = true,
};
static struct iwl_base_params iwl6050_base_params = {
@@ -503,11 +504,12 @@ static struct iwl_base_params iwl6050_base_params = {
.support_ct_kill_exit = true,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
.chain_noise_scale = 1500,
- .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
+ .wd_timeout = IWL_DEF_WD_TIMEOUT,
.max_event_log_size = 1024,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
.chain_noise_calib_by_driver = true,
+ .shadow_reg_enable = true,
};
static struct iwl_base_params iwl6000_coex_base_params = {
.eeprom_size = OTP_LOW_IMAGE_SIZE,
@@ -525,11 +527,12 @@ static struct iwl_base_params iwl6000_coex_base_params = {
.support_ct_kill_exit = true,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
.chain_noise_scale = 1000,
- .monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
+ .wd_timeout = IWL_LONG_WD_TIMEOUT,
.max_event_log_size = 512,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
.chain_noise_calib_by_driver = true,
+ .shadow_reg_enable = true,
};
static struct iwl_ht_params iwl6000_ht_params = {
@@ -541,18 +544,17 @@ static struct iwl_bt_params iwl6000_bt_params = {
.bt_statistics = true,
/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
.advanced_bt_coexist = true,
+ .agg_time_limit = BT_AGG_THRESHOLD_DEF,
.bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
.bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT,
+ .bt_sco_disable = true,
};
-struct iwl_cfg iwl6000g2a_2agn_cfg = {
- .name = "6000 Series 2x2 AGN Gen2a",
+struct iwl_cfg iwl6005_2agn_cfg = {
+ .name = "Intel(R) Centrino(R) Advanced-N 6205 AGN",
.fw_name_pre = IWL6000G2A_FW_PRE,
.ucode_api_max = IWL6000G2_UCODE_API_MAX,
.ucode_api_min = IWL6000G2_UCODE_API_MIN,
- .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
- .valid_tx_ant = ANT_AB,
- .valid_rx_ant = ANT_AB,
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
.ops = &iwl6000_ops,
@@ -561,16 +563,14 @@ struct iwl_cfg iwl6000g2a_2agn_cfg = {
.ht_params = &iwl6000_ht_params,
.need_dc_calib = true,
.need_temp_offset_calib = true,
+ .led_mode = IWL_LED_RF_STATE,
};
-struct iwl_cfg iwl6000g2a_2abg_cfg = {
- .name = "6000 Series 2x2 ABG Gen2a",
+struct iwl_cfg iwl6005_2abg_cfg = {
+ .name = "Intel(R) Centrino(R) Advanced-N 6205 ABG",
.fw_name_pre = IWL6000G2A_FW_PRE,
.ucode_api_max = IWL6000G2_UCODE_API_MAX,
.ucode_api_min = IWL6000G2_UCODE_API_MIN,
- .sku = IWL_SKU_A|IWL_SKU_G,
- .valid_tx_ant = ANT_AB,
- .valid_rx_ant = ANT_AB,
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
.ops = &iwl6000_ops,
@@ -578,16 +578,14 @@ struct iwl_cfg iwl6000g2a_2abg_cfg = {
.base_params = &iwl6000_base_params,
.need_dc_calib = true,
.need_temp_offset_calib = true,
+ .led_mode = IWL_LED_RF_STATE,
};
-struct iwl_cfg iwl6000g2a_2bg_cfg = {
- .name = "6000 Series 2x2 BG Gen2a",
+struct iwl_cfg iwl6005_2bg_cfg = {
+ .name = "Intel(R) Centrino(R) Advanced-N 6205 BG",
.fw_name_pre = IWL6000G2A_FW_PRE,
.ucode_api_max = IWL6000G2_UCODE_API_MAX,
.ucode_api_min = IWL6000G2_UCODE_API_MIN,
- .sku = IWL_SKU_G,
- .valid_tx_ant = ANT_AB,
- .valid_rx_ant = ANT_AB,
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
.ops = &iwl6000_ops,
@@ -595,16 +593,14 @@ struct iwl_cfg iwl6000g2a_2bg_cfg = {
.base_params = &iwl6000_base_params,
.need_dc_calib = true,
.need_temp_offset_calib = true,
+ .led_mode = IWL_LED_RF_STATE,
};
-struct iwl_cfg iwl6000g2b_2agn_cfg = {
- .name = "6000 Series 2x2 AGN Gen2b",
+struct iwl_cfg iwl6030_2agn_cfg = {
+ .name = "Intel(R) Centrino(R) Advanced-N 6230 AGN",
.fw_name_pre = IWL6000G2B_FW_PRE,
.ucode_api_max = IWL6000G2_UCODE_API_MAX,
.ucode_api_min = IWL6000G2_UCODE_API_MIN,
- .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
- .valid_tx_ant = ANT_AB,
- .valid_rx_ant = ANT_AB,
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
.ops = &iwl6000g2b_ops,
@@ -614,18 +610,17 @@ struct iwl_cfg iwl6000g2b_2agn_cfg = {
.ht_params = &iwl6000_ht_params,
.need_dc_calib = true,
.need_temp_offset_calib = true,
+ .led_mode = IWL_LED_RF_STATE,
+ .adv_pm = true,
/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
.scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
};
-struct iwl_cfg iwl6000g2b_2abg_cfg = {
- .name = "6000 Series 2x2 ABG Gen2b",
+struct iwl_cfg iwl6030_2abg_cfg = {
+ .name = "Intel(R) Centrino(R) Advanced-N 6230 ABG",
.fw_name_pre = IWL6000G2B_FW_PRE,
.ucode_api_max = IWL6000G2_UCODE_API_MAX,
.ucode_api_min = IWL6000G2_UCODE_API_MIN,
- .sku = IWL_SKU_A|IWL_SKU_G,
- .valid_tx_ant = ANT_AB,
- .valid_rx_ant = ANT_AB,
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
.ops = &iwl6000g2b_ops,
@@ -634,18 +629,17 @@ struct iwl_cfg iwl6000g2b_2abg_cfg = {
.bt_params = &iwl6000_bt_params,
.need_dc_calib = true,
.need_temp_offset_calib = true,
+ .led_mode = IWL_LED_RF_STATE,
+ .adv_pm = true,
/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
.scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
};
-struct iwl_cfg iwl6000g2b_2bgn_cfg = {
- .name = "6000 Series 2x2 BGN Gen2b",
+struct iwl_cfg iwl6030_2bgn_cfg = {
+ .name = "Intel(R) Centrino(R) Advanced-N 6230 BGN",
.fw_name_pre = IWL6000G2B_FW_PRE,
.ucode_api_max = IWL6000G2_UCODE_API_MAX,
.ucode_api_min = IWL6000G2_UCODE_API_MIN,
- .sku = IWL_SKU_G|IWL_SKU_N,
- .valid_tx_ant = ANT_AB,
- .valid_rx_ant = ANT_AB,
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
.ops = &iwl6000g2b_ops,
@@ -655,18 +649,17 @@ struct iwl_cfg iwl6000g2b_2bgn_cfg = {
.ht_params = &iwl6000_ht_params,
.need_dc_calib = true,
.need_temp_offset_calib = true,
+ .led_mode = IWL_LED_RF_STATE,
+ .adv_pm = true,
/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
.scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
};
-struct iwl_cfg iwl6000g2b_2bg_cfg = {
- .name = "6000 Series 2x2 BG Gen2b",
+struct iwl_cfg iwl6030_2bg_cfg = {
+ .name = "Intel(R) Centrino(R) Advanced-N 6230 BG",
.fw_name_pre = IWL6000G2B_FW_PRE,
.ucode_api_max = IWL6000G2_UCODE_API_MAX,
.ucode_api_min = IWL6000G2_UCODE_API_MIN,
- .sku = IWL_SKU_G,
- .valid_tx_ant = ANT_AB,
- .valid_rx_ant = ANT_AB,
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
.ops = &iwl6000g2b_ops,
@@ -675,18 +668,17 @@ struct iwl_cfg iwl6000g2b_2bg_cfg = {
.bt_params = &iwl6000_bt_params,
.need_dc_calib = true,
.need_temp_offset_calib = true,
+ .led_mode = IWL_LED_RF_STATE,
+ .adv_pm = true,
/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
.scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
};
-struct iwl_cfg iwl6000g2b_bgn_cfg = {
- .name = "6000 Series 1x2 BGN Gen2b",
+struct iwl_cfg iwl1030_bgn_cfg = {
+ .name = "Intel(R) Centrino(R) Wireless-N 1030 BGN",
.fw_name_pre = IWL6000G2B_FW_PRE,
.ucode_api_max = IWL6000G2_UCODE_API_MAX,
.ucode_api_min = IWL6000G2_UCODE_API_MIN,
- .sku = IWL_SKU_G|IWL_SKU_N,
- .valid_tx_ant = ANT_A,
- .valid_rx_ant = ANT_AB,
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
.ops = &iwl6000g2b_ops,
@@ -696,18 +688,17 @@ struct iwl_cfg iwl6000g2b_bgn_cfg = {
.ht_params = &iwl6000_ht_params,
.need_dc_calib = true,
.need_temp_offset_calib = true,
+ .led_mode = IWL_LED_RF_STATE,
+ .adv_pm = true,
/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
.scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
};
-struct iwl_cfg iwl6000g2b_bg_cfg = {
- .name = "6000 Series 1x2 BG Gen2b",
+struct iwl_cfg iwl1030_bg_cfg = {
+ .name = "Intel(R) Centrino(R) Wireless-N 1030 BG",
.fw_name_pre = IWL6000G2B_FW_PRE,
.ucode_api_max = IWL6000G2_UCODE_API_MAX,
.ucode_api_min = IWL6000G2_UCODE_API_MIN,
- .sku = IWL_SKU_G,
- .valid_tx_ant = ANT_A,
- .valid_rx_ant = ANT_AB,
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
.ops = &iwl6000g2b_ops,
@@ -716,6 +707,8 @@ struct iwl_cfg iwl6000g2b_bg_cfg = {
.bt_params = &iwl6000_bt_params,
.need_dc_calib = true,
.need_temp_offset_calib = true,
+ .led_mode = IWL_LED_RF_STATE,
+ .adv_pm = true,
/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
.scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
};
@@ -728,9 +721,8 @@ struct iwl_cfg iwl6000i_2agn_cfg = {
.fw_name_pre = IWL6000_FW_PRE,
.ucode_api_max = IWL6000_UCODE_API_MAX,
.ucode_api_min = IWL6000_UCODE_API_MIN,
- .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
- .valid_tx_ant = ANT_BC,
- .valid_rx_ant = ANT_BC,
+ .valid_tx_ant = ANT_BC, /* .cfg overwrite */
+ .valid_rx_ant = ANT_BC, /* .cfg overwrite */
.eeprom_ver = EEPROM_6000_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
.ops = &iwl6000_ops,
@@ -738,6 +730,7 @@ struct iwl_cfg iwl6000i_2agn_cfg = {
.base_params = &iwl6000_base_params,
.ht_params = &iwl6000_ht_params,
.pa_type = IWL_PA_INTERNAL,
+ .led_mode = IWL_LED_BLINK,
};
struct iwl_cfg iwl6000i_2abg_cfg = {
@@ -745,15 +738,15 @@ struct iwl_cfg iwl6000i_2abg_cfg = {
.fw_name_pre = IWL6000_FW_PRE,
.ucode_api_max = IWL6000_UCODE_API_MAX,
.ucode_api_min = IWL6000_UCODE_API_MIN,
- .sku = IWL_SKU_A|IWL_SKU_G,
- .valid_tx_ant = ANT_BC,
- .valid_rx_ant = ANT_BC,
+ .valid_tx_ant = ANT_BC, /* .cfg overwrite */
+ .valid_rx_ant = ANT_BC, /* .cfg overwrite */
.eeprom_ver = EEPROM_6000_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
.ops = &iwl6000_ops,
.mod_params = &iwlagn_mod_params,
.base_params = &iwl6000_base_params,
.pa_type = IWL_PA_INTERNAL,
+ .led_mode = IWL_LED_BLINK,
};
struct iwl_cfg iwl6000i_2bg_cfg = {
@@ -761,15 +754,15 @@ struct iwl_cfg iwl6000i_2bg_cfg = {
.fw_name_pre = IWL6000_FW_PRE,
.ucode_api_max = IWL6000_UCODE_API_MAX,
.ucode_api_min = IWL6000_UCODE_API_MIN,
- .sku = IWL_SKU_G,
- .valid_tx_ant = ANT_BC,
- .valid_rx_ant = ANT_BC,
+ .valid_tx_ant = ANT_BC, /* .cfg overwrite */
+ .valid_rx_ant = ANT_BC, /* .cfg overwrite */
.eeprom_ver = EEPROM_6000_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
.ops = &iwl6000_ops,
.mod_params = &iwlagn_mod_params,
.base_params = &iwl6000_base_params,
.pa_type = IWL_PA_INTERNAL,
+ .led_mode = IWL_LED_BLINK,
};
struct iwl_cfg iwl6050_2agn_cfg = {
@@ -777,9 +770,6 @@ struct iwl_cfg iwl6050_2agn_cfg = {
.fw_name_pre = IWL6050_FW_PRE,
.ucode_api_max = IWL6050_UCODE_API_MAX,
.ucode_api_min = IWL6050_UCODE_API_MIN,
- .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
- .valid_tx_ant = ANT_AB,
- .valid_rx_ant = ANT_AB,
.ops = &iwl6050_ops,
.eeprom_ver = EEPROM_6050_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION,
@@ -787,16 +777,14 @@ struct iwl_cfg iwl6050_2agn_cfg = {
.base_params = &iwl6050_base_params,
.ht_params = &iwl6000_ht_params,
.need_dc_calib = true,
+ .led_mode = IWL_LED_BLINK,
};
-struct iwl_cfg iwl6050g2_bgn_cfg = {
- .name = "6050 Series 1x2 BGN Gen2",
+struct iwl_cfg iwl6150_bgn_cfg = {
+ .name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BGN",
.fw_name_pre = IWL6050_FW_PRE,
.ucode_api_max = IWL6050_UCODE_API_MAX,
.ucode_api_min = IWL6050_UCODE_API_MIN,
- .sku = IWL_SKU_G|IWL_SKU_N,
- .valid_tx_ant = ANT_A,
- .valid_rx_ant = ANT_AB,
.eeprom_ver = EEPROM_6050G2_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_6050G2_TX_POWER_VERSION,
.ops = &iwl6050g2_ops,
@@ -804,6 +792,7 @@ struct iwl_cfg iwl6050g2_bgn_cfg = {
.base_params = &iwl6050_base_params,
.ht_params = &iwl6000_ht_params,
.need_dc_calib = true,
+ .led_mode = IWL_LED_RF_STATE,
};
struct iwl_cfg iwl6050_2abg_cfg = {
@@ -811,15 +800,13 @@ struct iwl_cfg iwl6050_2abg_cfg = {
.fw_name_pre = IWL6050_FW_PRE,
.ucode_api_max = IWL6050_UCODE_API_MAX,
.ucode_api_min = IWL6050_UCODE_API_MIN,
- .sku = IWL_SKU_A|IWL_SKU_G,
- .valid_tx_ant = ANT_AB,
- .valid_rx_ant = ANT_AB,
.eeprom_ver = EEPROM_6050_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION,
.ops = &iwl6050_ops,
.mod_params = &iwlagn_mod_params,
.base_params = &iwl6050_base_params,
.need_dc_calib = true,
+ .led_mode = IWL_LED_BLINK,
};
struct iwl_cfg iwl6000_3agn_cfg = {
@@ -827,9 +814,6 @@ struct iwl_cfg iwl6000_3agn_cfg = {
.fw_name_pre = IWL6000_FW_PRE,
.ucode_api_max = IWL6000_UCODE_API_MAX,
.ucode_api_min = IWL6000_UCODE_API_MIN,
- .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
- .valid_tx_ant = ANT_ABC,
- .valid_rx_ant = ANT_ABC,
.eeprom_ver = EEPROM_6000_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
.ops = &iwl6000_ops,
@@ -837,16 +821,14 @@ struct iwl_cfg iwl6000_3agn_cfg = {
.base_params = &iwl6000_base_params,
.ht_params = &iwl6000_ht_params,
.need_dc_calib = true,
+ .led_mode = IWL_LED_BLINK,
};
struct iwl_cfg iwl130_bgn_cfg = {
- .name = "Intel(R) 130 Series 1x1 BGN",
+ .name = "Intel(R) Centrino(R) Wireless-N 130 BGN",
.fw_name_pre = IWL6000G2B_FW_PRE,
- .ucode_api_max = IWL130_UCODE_API_MAX,
- .ucode_api_min = IWL130_UCODE_API_MIN,
- .sku = IWL_SKU_G|IWL_SKU_N,
- .valid_tx_ant = ANT_A,
- .valid_rx_ant = ANT_A,
+ .ucode_api_max = IWL6000G2_UCODE_API_MAX,
+ .ucode_api_min = IWL6000G2_UCODE_API_MIN,
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
.ops = &iwl6000g2b_ops,
@@ -855,18 +837,17 @@ struct iwl_cfg iwl130_bgn_cfg = {
.bt_params = &iwl6000_bt_params,
.ht_params = &iwl6000_ht_params,
.need_dc_calib = true,
+ .led_mode = IWL_LED_RF_STATE,
+ .adv_pm = true,
/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
.scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
};
struct iwl_cfg iwl130_bg_cfg = {
- .name = "Intel(R) 130 Series 1x2 BG",
+ .name = "Intel(R) Centrino(R) Wireless-N 130 BG",
.fw_name_pre = IWL6000G2B_FW_PRE,
- .ucode_api_max = IWL130_UCODE_API_MAX,
- .ucode_api_min = IWL130_UCODE_API_MIN,
- .sku = IWL_SKU_G,
- .valid_tx_ant = ANT_A,
- .valid_rx_ant = ANT_A,
+ .ucode_api_max = IWL6000G2_UCODE_API_MAX,
+ .ucode_api_min = IWL6000G2_UCODE_API_MIN,
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
.ops = &iwl6000g2b_ops,
@@ -874,6 +855,8 @@ struct iwl_cfg iwl130_bg_cfg = {
.base_params = &iwl6000_coex_base_params,
.bt_params = &iwl6000_bt_params,
.need_dc_calib = true,
+ .led_mode = IWL_LED_RF_STATE,
+ .adv_pm = true,
/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
.scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
};
@@ -882,4 +865,3 @@ MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX));
MODULE_FIRMWARE(IWL6000G2A_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX));
MODULE_FIRMWARE(IWL6000G2B_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX));
-MODULE_FIRMWARE(IWL130_MODULE_FIRMWARE(IWL130_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
index e2019e756936..d16bb5ede014 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
@@ -732,8 +732,122 @@ static inline u8 find_first_chain(u8 mask)
return CHAIN_C;
}
+/**
+ * Run disconnected antenna algorithm to find out which antennas are
+ * disconnected.
+ */
+static void iwl_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig,
+ struct iwl_chain_noise_data *data)
+{
+ u32 active_chains = 0;
+ u32 max_average_sig;
+ u16 max_average_sig_antenna_i;
+ u8 num_tx_chains;
+ u8 first_chain;
+ u16 i = 0;
+
+ average_sig[0] = data->chain_signal_a /
+ priv->cfg->base_params->chain_noise_num_beacons;
+ average_sig[1] = data->chain_signal_b /
+ priv->cfg->base_params->chain_noise_num_beacons;
+ average_sig[2] = data->chain_signal_c /
+ priv->cfg->base_params->chain_noise_num_beacons;
+
+ if (average_sig[0] >= average_sig[1]) {
+ max_average_sig = average_sig[0];
+ max_average_sig_antenna_i = 0;
+ active_chains = (1 << max_average_sig_antenna_i);
+ } else {
+ max_average_sig = average_sig[1];
+ max_average_sig_antenna_i = 1;
+ active_chains = (1 << max_average_sig_antenna_i);
+ }
+
+ if (average_sig[2] >= max_average_sig) {
+ max_average_sig = average_sig[2];
+ max_average_sig_antenna_i = 2;
+ active_chains = (1 << max_average_sig_antenna_i);
+ }
+
+ IWL_DEBUG_CALIB(priv, "average_sig: a %d b %d c %d\n",
+ average_sig[0], average_sig[1], average_sig[2]);
+ IWL_DEBUG_CALIB(priv, "max_average_sig = %d, antenna %d\n",
+ max_average_sig, max_average_sig_antenna_i);
+
+ /* Compare signal strengths for all 3 receivers. */
+ for (i = 0; i < NUM_RX_CHAINS; i++) {
+ if (i != max_average_sig_antenna_i) {
+ s32 rssi_delta = (max_average_sig - average_sig[i]);
+
+ /* If signal is very weak, compared with
+ * strongest, mark it as disconnected. */
+ if (rssi_delta > MAXIMUM_ALLOWED_PATHLOSS)
+ data->disconn_array[i] = 1;
+ else
+ active_chains |= (1 << i);
+ IWL_DEBUG_CALIB(priv, "i = %d rssiDelta = %d "
+ "disconn_array[i] = %d\n",
+ i, rssi_delta, data->disconn_array[i]);
+ }
+ }
+
+ /*
+ * The above algorithm sometimes fails when the ucode
+ * reports 0 for all chains. It's not clear why that
+ * happens to start with, but it is then causing trouble
+ * because this can make us enable more chains than the
+ * hardware really has.
+ *
+ * To be safe, simply mask out any chains that we know
+ * are not on the device.
+ */
+ active_chains &= priv->hw_params.valid_rx_ant;
+
+ num_tx_chains = 0;
+ for (i = 0; i < NUM_RX_CHAINS; i++) {
+ /* loops on all the bits of
+ * priv->hw_setting.valid_tx_ant */
+ u8 ant_msk = (1 << i);
+ if (!(priv->hw_params.valid_tx_ant & ant_msk))
+ continue;
+
+ num_tx_chains++;
+ if (data->disconn_array[i] == 0)
+ /* there is a Tx antenna connected */
+ break;
+ if (num_tx_chains == priv->hw_params.tx_chains_num &&
+ data->disconn_array[i]) {
+ /*
+ * If all chains are disconnected
+ * connect the first valid tx chain
+ */
+ first_chain =
+ find_first_chain(priv->cfg->valid_tx_ant);
+ data->disconn_array[first_chain] = 0;
+ active_chains |= BIT(first_chain);
+ IWL_DEBUG_CALIB(priv, "All Tx chains are disconnected \
+ W/A - declare %d as connected\n",
+ first_chain);
+ break;
+ }
+ }
+
+ if (active_chains != priv->hw_params.valid_rx_ant &&
+ active_chains != priv->chain_noise_data.active_chains)
+ IWL_DEBUG_CALIB(priv,
+ "Detected that not all antennas are connected! "
+ "Connected: %#x, valid: %#x.\n",
+ active_chains, priv->hw_params.valid_rx_ant);
+
+ /* Save for use within RXON, TX, SCAN commands, etc. */
+ data->active_chains = active_chains;
+ IWL_DEBUG_CALIB(priv, "active_chains (bitwise) = 0x%x\n",
+ active_chains);
+}
+
+
/*
- * Accumulate 20 beacons of signal and noise statistics for each of
+ * Accumulate 16 beacons of signal and noise statistics for each of
* 3 receivers/antennas/rx-chains, then figure out:
* 1) Which antennas are connected.
* 2) Differential rx gain settings to balance the 3 receivers.
@@ -750,8 +864,6 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
u32 chain_sig_c;
u32 average_sig[NUM_RX_CHAINS] = {INITIALIZATION_VALUE};
u32 average_noise[NUM_RX_CHAINS] = {INITIALIZATION_VALUE};
- u32 max_average_sig;
- u16 max_average_sig_antenna_i;
u32 min_average_noise = MIN_AVERAGE_NOISE_MAX_VALUE;
u16 min_average_noise_antenna_i = INITIALIZATION_VALUE;
u16 i = 0;
@@ -759,11 +871,9 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
u16 stat_chnum = INITIALIZATION_VALUE;
u8 rxon_band24;
u8 stat_band24;
- u32 active_chains = 0;
- u8 num_tx_chains;
unsigned long flags;
struct statistics_rx_non_phy *rx_info;
- u8 first_chain;
+
/*
* MULTI-FIXME:
* When we support multiple interfaces on different channels,
@@ -869,108 +979,16 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
return;
/* Analyze signal for disconnected antenna */
- average_sig[0] = data->chain_signal_a /
- priv->cfg->base_params->chain_noise_num_beacons;
- average_sig[1] = data->chain_signal_b /
- priv->cfg->base_params->chain_noise_num_beacons;
- average_sig[2] = data->chain_signal_c /
- priv->cfg->base_params->chain_noise_num_beacons;
-
- if (average_sig[0] >= average_sig[1]) {
- max_average_sig = average_sig[0];
- max_average_sig_antenna_i = 0;
- active_chains = (1 << max_average_sig_antenna_i);
- } else {
- max_average_sig = average_sig[1];
- max_average_sig_antenna_i = 1;
- active_chains = (1 << max_average_sig_antenna_i);
- }
-
- if (average_sig[2] >= max_average_sig) {
- max_average_sig = average_sig[2];
- max_average_sig_antenna_i = 2;
- active_chains = (1 << max_average_sig_antenna_i);
- }
-
- IWL_DEBUG_CALIB(priv, "average_sig: a %d b %d c %d\n",
- average_sig[0], average_sig[1], average_sig[2]);
- IWL_DEBUG_CALIB(priv, "max_average_sig = %d, antenna %d\n",
- max_average_sig, max_average_sig_antenna_i);
-
- /* Compare signal strengths for all 3 receivers. */
- for (i = 0; i < NUM_RX_CHAINS; i++) {
- if (i != max_average_sig_antenna_i) {
- s32 rssi_delta = (max_average_sig - average_sig[i]);
-
- /* If signal is very weak, compared with
- * strongest, mark it as disconnected. */
- if (rssi_delta > MAXIMUM_ALLOWED_PATHLOSS)
- data->disconn_array[i] = 1;
- else
- active_chains |= (1 << i);
- IWL_DEBUG_CALIB(priv, "i = %d rssiDelta = %d "
- "disconn_array[i] = %d\n",
- i, rssi_delta, data->disconn_array[i]);
- }
- }
-
- /*
- * The above algorithm sometimes fails when the ucode
- * reports 0 for all chains. It's not clear why that
- * happens to start with, but it is then causing trouble
- * because this can make us enable more chains than the
- * hardware really has.
- *
- * To be safe, simply mask out any chains that we know
- * are not on the device.
- */
if (priv->cfg->bt_params &&
- priv->cfg->bt_params->advanced_bt_coexist &&
- priv->bt_full_concurrent) {
- /* operated as 1x1 in full concurrency mode */
- active_chains &= first_antenna(priv->hw_params.valid_rx_ant);
+ priv->cfg->bt_params->advanced_bt_coexist) {
+ /* Disable disconnected antenna algorithm for advanced
+ bt coex, assuming valid antennas are connected */
+ data->active_chains = priv->hw_params.valid_rx_ant;
+ for (i = 0; i < NUM_RX_CHAINS; i++)
+ if (!(data->active_chains & (1<<i)))
+ data->disconn_array[i] = 1;
} else
- active_chains &= priv->hw_params.valid_rx_ant;
-
- num_tx_chains = 0;
- for (i = 0; i < NUM_RX_CHAINS; i++) {
- /* loops on all the bits of
- * priv->hw_setting.valid_tx_ant */
- u8 ant_msk = (1 << i);
- if (!(priv->hw_params.valid_tx_ant & ant_msk))
- continue;
-
- num_tx_chains++;
- if (data->disconn_array[i] == 0)
- /* there is a Tx antenna connected */
- break;
- if (num_tx_chains == priv->hw_params.tx_chains_num &&
- data->disconn_array[i]) {
- /*
- * If all chains are disconnected
- * connect the first valid tx chain
- */
- first_chain =
- find_first_chain(priv->cfg->valid_tx_ant);
- data->disconn_array[first_chain] = 0;
- active_chains |= BIT(first_chain);
- IWL_DEBUG_CALIB(priv, "All Tx chains are disconnected W/A - declare %d as connected\n",
- first_chain);
- break;
- }
- }
-
- if (active_chains != priv->hw_params.valid_rx_ant &&
- active_chains != priv->chain_noise_data.active_chains)
- IWL_DEBUG_CALIB(priv,
- "Detected that not all antennas are connected! "
- "Connected: %#x, valid: %#x.\n",
- active_chains, priv->hw_params.valid_rx_ant);
-
- /* Save for use within RXON, TX, SCAN commands, etc. */
- priv->chain_noise_data.active_chains = active_chains;
- IWL_DEBUG_CALIB(priv, "active_chains (bitwise) = 0x%x\n",
- active_chains);
+ iwl_find_disconn_antenna(priv, average_sig, data);
/* Analyze noise for rx balance */
average_noise[0] = data->chain_noise_a /
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c
index a650baba0809..dbada761624d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c
@@ -248,6 +248,47 @@ err:
}
+int iwl_eeprom_check_sku(struct iwl_priv *priv)
+{
+ u16 eeprom_sku;
+ u16 radio_cfg;
+
+ eeprom_sku = iwl_eeprom_query16(priv, EEPROM_SKU_CAP);
+
+ priv->cfg->sku = ((eeprom_sku & EEPROM_SKU_CAP_BAND_SELECTION) >>
+ EEPROM_SKU_CAP_BAND_POS);
+ if (eeprom_sku & EEPROM_SKU_CAP_11N_ENABLE)
+ priv->cfg->sku |= IWL_SKU_N;
+
+ if (!priv->cfg->sku) {
+ IWL_ERR(priv, "Invalid device sku\n");
+ return -EINVAL;
+ }
+
+ IWL_INFO(priv, "Device SKU: 0X%x\n", priv->cfg->sku);
+
+ if (!priv->cfg->valid_tx_ant && !priv->cfg->valid_rx_ant) {
+ /* not using .cfg overwrite */
+ radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG);
+ priv->cfg->valid_tx_ant = EEPROM_RF_CFG_TX_ANT_MSK(radio_cfg);
+ priv->cfg->valid_rx_ant = EEPROM_RF_CFG_TX_ANT_MSK(radio_cfg);
+ if (!priv->cfg->valid_tx_ant || !priv->cfg->valid_rx_ant) {
+ IWL_ERR(priv, "Invalid chain (0X%x, 0X%x)\n",
+ priv->cfg->valid_tx_ant,
+ priv->cfg->valid_rx_ant);
+ return -EINVAL;
+ }
+ IWL_INFO(priv, "Valid Tx ant: 0X%x, Valid Rx ant: 0X%x\n",
+ priv->cfg->valid_tx_ant, priv->cfg->valid_rx_ant);
+ }
+ /*
+ * for some special cases,
+ * EEPROM did not reflect the correct antenna setting
+ * so overwrite the valid tx/rx antenna from .cfg
+ */
+ return 0;
+}
+
void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac)
{
const u8 *addr = priv->cfg->ops->lib->eeprom_ops.query_addr(priv,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
index ffb2f4111ad0..366340f3fb0f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
@@ -307,6 +307,7 @@ static int iwlagn_set_pan_params(struct iwl_priv *priv)
if (ctx_bss->vif && ctx_pan->vif) {
int bcnint = ctx_pan->vif->bss_conf.beacon_int;
+ int dtim = ctx_pan->vif->bss_conf.dtim_period ?: 1;
/* should be set, but seems unused?? */
cmd.flags |= cpu_to_le16(IWL_WIPAN_PARAMS_FLG_SLOTTED_MODE);
@@ -329,10 +330,10 @@ static int iwlagn_set_pan_params(struct iwl_priv *priv)
if (test_bit(STATUS_SCAN_HW, &priv->status) ||
(!ctx_bss->vif->bss_conf.idle &&
!ctx_bss->vif->bss_conf.assoc)) {
- slot0 = bcnint * 3 - 20;
+ slot0 = dtim * bcnint * 3 - 20;
slot1 = 20;
} else if (!ctx_pan->vif->bss_conf.idle &&
- !ctx_pan->vif->bss_conf.assoc) {
+ !ctx_pan->vif->bss_conf.assoc) {
slot1 = bcnint * 3 - 20;
slot0 = 20;
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index b555edd53354..d941910e7ef4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -405,6 +405,7 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
return;
}
+ txq->time_stamp = jiffies;
info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb);
memset(&info->status, 0, sizeof(info->status));
@@ -445,22 +446,17 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
if (priv->mac80211_registered &&
(iwl_queue_space(&txq->q) > txq->q.low_mark) &&
- (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) {
- if (agg->state == IWL_AGG_OFF)
- iwl_wake_queue(priv, txq_id);
- else
- iwl_wake_queue(priv, txq->swq_id);
- }
+ (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA))
+ iwl_wake_queue(priv, txq);
}
} else {
- BUG_ON(txq_id != txq->swq_id);
iwlagn_set_tx_status(priv, info, tx_resp, txq_id, false);
freed = iwlagn_tx_queue_reclaim(priv, txq_id, index);
iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
if (priv->mac80211_registered &&
(iwl_queue_space(&txq->q) > txq->q.low_mark))
- iwl_wake_queue(priv, txq_id);
+ iwl_wake_queue(priv, txq);
}
iwlagn_txq_check_empty(priv, sta_id, tid, txq_id);
@@ -496,6 +492,10 @@ int iwlagn_send_tx_power(struct iwl_priv *priv)
struct iwlagn_tx_power_dbm_cmd tx_power_cmd;
u8 tx_ant_cfg_cmd;
+ if (WARN_ONCE(test_bit(STATUS_SCAN_HW, &priv->status),
+ "TX Power requested while scanning!\n"))
+ return -EAGAIN;
+
/* half dBm need to multiply */
tx_power_cmd.global_lmt = (s8)(2 * priv->tx_power_user_lmt);
@@ -522,9 +522,8 @@ int iwlagn_send_tx_power(struct iwl_priv *priv)
else
tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD;
- return iwl_send_cmd_pdu_async(priv, tx_ant_cfg_cmd,
- sizeof(tx_power_cmd), &tx_power_cmd,
- NULL);
+ return iwl_send_cmd_pdu(priv, tx_ant_cfg_cmd, sizeof(tx_power_cmd),
+ &tx_power_cmd);
}
void iwlagn_temperature(struct iwl_priv *priv)
@@ -750,6 +749,12 @@ int iwlagn_hw_nic_init(struct iwl_priv *priv)
} else
iwlagn_txq_ctx_reset(priv);
+ if (priv->cfg->base_params->shadow_reg_enable) {
+ /* enable shadow regs in HW */
+ iwl_set_bit(priv, CSR_MAC_SHADOW_REG_CTRL,
+ 0x800FFFFF);
+ }
+
set_bit(STATUS_INIT, &priv->status);
return 0;
@@ -1584,22 +1589,6 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
return ret;
}
-void iwlagn_post_scan(struct iwl_priv *priv)
-{
- struct iwl_rxon_context *ctx;
-
- /*
- * Since setting the RXON may have been deferred while
- * performing the scan, fire one off if needed
- */
- for_each_context(priv, ctx)
- if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))
- iwlagn_commit_rxon(priv, ctx);
-
- if (priv->cfg->ops->hcmd->set_pan_params)
- priv->cfg->ops->hcmd->set_pan_params(priv);
-}
-
int iwlagn_manage_ibss_station(struct iwl_priv *priv,
struct ieee80211_vif *vif, bool add)
{
@@ -1790,7 +1779,7 @@ static const __le32 iwlagn_def_3w_lookup[12] = {
cpu_to_le32(0xc0004000),
cpu_to_le32(0x00004000),
cpu_to_le32(0xf0005000),
- cpu_to_le32(0xf0004000),
+ cpu_to_le32(0xf0005000),
};
static const __le32 iwlagn_concurrent_lookup[12] = {
@@ -1826,6 +1815,7 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv)
bt_cmd.prio_boost = 0;
bt_cmd.kill_ack_mask = priv->kill_ack_mask;
bt_cmd.kill_cts_mask = priv->kill_cts_mask;
+
bt_cmd.valid = priv->bt_valid;
bt_cmd.tx_prio_boost = 0;
bt_cmd.rx_prio_boost = 0;
@@ -1841,6 +1831,10 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv)
} else {
bt_cmd.flags = IWLAGN_BT_FLAG_COEX_MODE_3W <<
IWLAGN_BT_FLAG_COEX_MODE_SHIFT;
+ if (priv->cfg->bt_params &&
+ priv->cfg->bt_params->bt_sco_disable)
+ bt_cmd.flags |= IWLAGN_BT_FLAG_SYNC_2_BT_DISABLE;
+
if (priv->bt_ch_announce)
bt_cmd.flags |= IWLAGN_BT_FLAG_CHANNEL_INHIBITION;
IWL_DEBUG_INFO(priv, "BT coex flag: 0X%x\n", bt_cmd.flags);
@@ -1884,12 +1878,20 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work)
struct iwl_rxon_context *ctx;
int smps_request = -1;
+ /*
+ * Note: bt_traffic_load can be overridden by scan complete and
+ * coex profile notifications. Ignore that since only bad consequence
+ * can be not matching debug print with actual state.
+ */
IWL_DEBUG_INFO(priv, "BT traffic load changes: %d\n",
priv->bt_traffic_load);
switch (priv->bt_traffic_load) {
case IWL_BT_COEX_TRAFFIC_LOAD_NONE:
- smps_request = IEEE80211_SMPS_AUTOMATIC;
+ if (priv->bt_status)
+ smps_request = IEEE80211_SMPS_DYNAMIC;
+ else
+ smps_request = IEEE80211_SMPS_AUTOMATIC;
break;
case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
smps_request = IEEE80211_SMPS_DYNAMIC;
@@ -1906,6 +1908,16 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work)
mutex_lock(&priv->mutex);
+ /*
+ * We can not send command to firmware while scanning. When the scan
+ * complete we will schedule this work again. We do check with mutex
+ * locked to prevent new scan request to arrive. We do not check
+ * STATUS_SCANNING to avoid race when queue_work two times from
+ * different notifications, but quit and not perform any work at all.
+ */
+ if (test_bit(STATUS_SCAN_HW, &priv->status))
+ goto out;
+
if (priv->cfg->ops->lib->update_chain_flags)
priv->cfg->ops->lib->update_chain_flags(priv);
@@ -1915,7 +1927,7 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work)
ieee80211_request_smps(ctx->vif, smps_request);
}
}
-
+out:
mutex_unlock(&priv->mutex);
}
@@ -1986,24 +1998,29 @@ static void iwlagn_print_uartmsg(struct iwl_priv *priv,
BT_UART_MSG_FRAME7CONNECTABLE_POS);
}
-static void iwlagn_set_kill_ack_msk(struct iwl_priv *priv,
- struct iwl_bt_uart_msg *uart_msg)
+static void iwlagn_set_kill_msk(struct iwl_priv *priv,
+ struct iwl_bt_uart_msg *uart_msg)
{
- u8 kill_ack_msk;
- __le32 bt_kill_ack_msg[2] = {
- cpu_to_le32(0xFFFFFFF), cpu_to_le32(0xFFFFFC00) };
-
- kill_ack_msk = (((BT_UART_MSG_FRAME3A2DP_MSK |
- BT_UART_MSG_FRAME3SNIFF_MSK |
- BT_UART_MSG_FRAME3SCOESCO_MSK) &
- uart_msg->frame3) == 0) ? 1 : 0;
- if (priv->kill_ack_mask != bt_kill_ack_msg[kill_ack_msk]) {
+ u8 kill_msk;
+ static const __le32 bt_kill_ack_msg[2] = {
+ IWLAGN_BT_KILL_ACK_MASK_DEFAULT,
+ IWLAGN_BT_KILL_ACK_CTS_MASK_SCO };
+ static const __le32 bt_kill_cts_msg[2] = {
+ IWLAGN_BT_KILL_CTS_MASK_DEFAULT,
+ IWLAGN_BT_KILL_ACK_CTS_MASK_SCO };
+
+ kill_msk = (BT_UART_MSG_FRAME3SCOESCO_MSK & uart_msg->frame3)
+ ? 1 : 0;
+ if (priv->kill_ack_mask != bt_kill_ack_msg[kill_msk] ||
+ priv->kill_cts_mask != bt_kill_cts_msg[kill_msk]) {
priv->bt_valid |= IWLAGN_BT_VALID_KILL_ACK_MASK;
- priv->kill_ack_mask = bt_kill_ack_msg[kill_ack_msk];
+ priv->kill_ack_mask = bt_kill_ack_msg[kill_msk];
+ priv->bt_valid |= IWLAGN_BT_VALID_KILL_CTS_MASK;
+ priv->kill_cts_mask = bt_kill_cts_msg[kill_msk];
+
/* schedule to send runtime bt_config */
queue_work(priv->workqueue, &priv->bt_runtime_config);
}
-
}
void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
@@ -2014,7 +2031,6 @@ void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
struct iwl_bt_coex_profile_notif *coex = &pkt->u.bt_coex_profile_notif;
struct iwlagn_bt_sco_cmd sco_cmd = { .flags = 0 };
struct iwl_bt_uart_msg *uart_msg = &coex->last_bt_uart_msg;
- u8 last_traffic_load;
IWL_DEBUG_NOTIF(priv, "BT Coex notification:\n");
IWL_DEBUG_NOTIF(priv, " status: %d\n", coex->bt_status);
@@ -2023,11 +2039,10 @@ void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
coex->bt_ci_compliance);
iwlagn_print_uartmsg(priv, uart_msg);
- last_traffic_load = priv->notif_bt_traffic_load;
- priv->notif_bt_traffic_load = coex->bt_traffic_load;
+ priv->last_bt_traffic_load = priv->bt_traffic_load;
if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
if (priv->bt_status != coex->bt_status ||
- last_traffic_load != coex->bt_traffic_load) {
+ priv->last_bt_traffic_load != coex->bt_traffic_load) {
if (coex->bt_status) {
/* BT on */
if (!priv->bt_ch_announce)
@@ -2056,7 +2071,7 @@ void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
}
}
- iwlagn_set_kill_ack_msk(priv, uart_msg);
+ iwlagn_set_kill_msk(priv, uart_msg);
/* FIXME: based on notification, adjust the prio_boost */
@@ -2276,7 +2291,7 @@ static const char *get_csr_string(int cmd)
void iwl_dump_csr(struct iwl_priv *priv)
{
int i;
- u32 csr_tbl[] = {
+ static const u32 csr_tbl[] = {
CSR_HW_IF_CONFIG_REG,
CSR_INT_COALESCING,
CSR_INT,
@@ -2335,7 +2350,7 @@ int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display)
int pos = 0;
size_t bufsz = 0;
#endif
- u32 fh_tbl[] = {
+ static const u32 fh_tbl[] = {
FH_RSCSR_CHNL0_STTS_WPTR_REG,
FH_RSCSR_CHNL0_RBDCB_BASE_REG,
FH_RSCSR_CHNL0_WPTR,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 065553629de5..f450adc72361 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -833,17 +833,23 @@ static void rs_bt_update_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
struct iwl_lq_sta *lq_sta)
{
struct iwl_scale_tbl_info *tbl;
- bool full_concurrent;
+ bool full_concurrent = priv->bt_full_concurrent;
unsigned long flags;
- spin_lock_irqsave(&priv->lock, flags);
- if (priv->bt_ci_compliance && priv->bt_ant_couple_ok)
- full_concurrent = true;
- else
- full_concurrent = false;
- spin_unlock_irqrestore(&priv->lock, flags);
-
- if (priv->bt_full_concurrent != full_concurrent) {
+ if (priv->bt_ant_couple_ok) {
+ /*
+ * Is there a need to switch between
+ * full concurrency and 3-wire?
+ */
+ spin_lock_irqsave(&priv->lock, flags);
+ if (priv->bt_ci_compliance && priv->bt_ant_couple_ok)
+ full_concurrent = true;
+ else
+ full_concurrent = false;
+ spin_unlock_irqrestore(&priv->lock, flags);
+ }
+ if ((priv->bt_traffic_load != priv->last_bt_traffic_load) ||
+ (priv->bt_full_concurrent != full_concurrent)) {
priv->bt_full_concurrent = full_concurrent;
/* Update uCode's rate table. */
@@ -1040,8 +1046,7 @@ done:
if (sta && sta->supp_rates[sband->band])
rs_rate_scale_perform(priv, skb, sta, lq_sta);
- /* Is there a need to switch between full concurrency and 3-wire? */
- if (priv->bt_ant_couple_ok)
+ if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist)
rs_bt_update_lq(priv, ctx, lq_sta);
}
@@ -3010,10 +3015,7 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
*/
if (priv && priv->cfg->bt_params &&
priv->cfg->bt_params->agg_time_limit &&
- priv->cfg->bt_params->agg_time_limit >=
- LINK_QUAL_AGG_TIME_LIMIT_MIN &&
- priv->cfg->bt_params->agg_time_limit <=
- LINK_QUAL_AGG_TIME_LIMIT_MAX)
+ priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)
lq_cmd->agg_params.agg_time_limit =
cpu_to_le16(priv->cfg->bt_params->agg_time_limit);
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
new file mode 100644
index 000000000000..4865b82355d7
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
@@ -0,0 +1,635 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ *****************************************************************************/
+
+#include "iwl-dev.h"
+#include "iwl-agn.h"
+#include "iwl-sta.h"
+#include "iwl-core.h"
+#include "iwl-agn-calib.h"
+
+static int iwlagn_disable_bss(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx,
+ struct iwl_rxon_cmd *send)
+{
+ __le32 old_filter = send->filter_flags;
+ int ret;
+
+ send->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, sizeof(*send), send);
+
+ send->filter_flags = old_filter;
+
+ if (ret)
+ IWL_ERR(priv, "Error clearing ASSOC_MSK on BSS (%d)\n", ret);
+
+ return ret;
+}
+
+static int iwlagn_disable_pan(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx,
+ struct iwl_rxon_cmd *send)
+{
+ __le32 old_filter = send->filter_flags;
+ u8 old_dev_type = send->dev_type;
+ int ret;
+
+ send->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ send->dev_type = RXON_DEV_TYPE_P2P;
+ ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, sizeof(*send), send);
+
+ send->filter_flags = old_filter;
+ send->dev_type = old_dev_type;
+
+ if (ret)
+ IWL_ERR(priv, "Error disabling PAN (%d)\n", ret);
+
+ /* FIXME: WAIT FOR PAN DISABLE */
+ msleep(300);
+
+ return ret;
+}
+
+static void iwlagn_update_qos(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx)
+{
+ int ret;
+
+ if (!ctx->is_active)
+ return;
+
+ ctx->qos_data.def_qos_parm.qos_flags = 0;
+
+ if (ctx->qos_data.qos_active)
+ ctx->qos_data.def_qos_parm.qos_flags |=
+ QOS_PARAM_FLG_UPDATE_EDCA_MSK;
+
+ if (ctx->ht.enabled)
+ ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
+
+ IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n",
+ ctx->qos_data.qos_active,
+ ctx->qos_data.def_qos_parm.qos_flags);
+
+ ret = iwl_send_cmd_pdu(priv, ctx->qos_cmd,
+ sizeof(struct iwl_qosparam_cmd),
+ &ctx->qos_data.def_qos_parm);
+ if (ret)
+ IWL_ERR(priv, "Failed to update QoS\n");
+}
+
+static int iwlagn_update_beacon(struct iwl_priv *priv,
+ struct ieee80211_vif *vif)
+{
+ lockdep_assert_held(&priv->mutex);
+
+ dev_kfree_skb(priv->beacon_skb);
+ priv->beacon_skb = ieee80211_beacon_get(priv->hw, vif);
+ if (!priv->beacon_skb)
+ return -ENOMEM;
+ return iwlagn_send_beacon_cmd(priv);
+}
+
+/**
+ * iwlagn_commit_rxon - commit staging_rxon to hardware
+ *
+ * The RXON command in staging_rxon is committed to the hardware and
+ * the active_rxon structure is updated with the new data. This
+ * function correctly transitions out of the RXON_ASSOC_MSK state if
+ * a HW tune is required based on the RXON structure changes.
+ */
+int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
+{
+ /* cast away the const for active_rxon in this function */
+ struct iwl_rxon_cmd *active = (void *)&ctx->active;
+ bool new_assoc = !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK);
+ bool old_assoc = !!(ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK);
+ int ret;
+
+ lockdep_assert_held(&priv->mutex);
+
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return -EINVAL;
+
+ if (!iwl_is_alive(priv))
+ return -EBUSY;
+
+ /* This function hardcodes a bunch of dual-mode assumptions */
+ BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
+
+ if (!ctx->is_active)
+ return 0;
+
+ /* always get timestamp with Rx frame */
+ ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK;
+
+ if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) ||
+ !(ctx->staging.flags & RXON_FLG_BAND_24G_MSK))
+ ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
+ else
+ ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
+
+ ret = iwl_check_rxon_cmd(priv, ctx);
+ if (ret) {
+ IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");
+ return -EINVAL;
+ }
+
+ /*
+ * receive commit_rxon request
+ * abort any previous channel switch if still in process
+ */
+ if (priv->switch_rxon.switch_in_progress &&
+ (priv->switch_rxon.channel != ctx->staging.channel)) {
+ IWL_DEBUG_11H(priv, "abort channel switch on %d\n",
+ le16_to_cpu(priv->switch_rxon.channel));
+ iwl_chswitch_done(priv, false);
+ }
+
+ /*
+ * If we don't need to send a full RXON, we can use
+ * iwl_rxon_assoc_cmd which is used to reconfigure filter
+ * and other flags for the current radio configuration.
+ */
+ if (!iwl_full_rxon_required(priv, ctx)) {
+ ret = iwl_send_rxon_assoc(priv, ctx);
+ if (ret) {
+ IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret);
+ return ret;
+ }
+
+ memcpy(active, &ctx->staging, sizeof(*active));
+ iwl_print_rx_config_cmd(priv, ctx);
+ return 0;
+ }
+
+ if (priv->cfg->ops->hcmd->set_pan_params) {
+ ret = priv->cfg->ops->hcmd->set_pan_params(priv);
+ if (ret)
+ return ret;
+ }
+
+ iwl_set_rxon_hwcrypto(priv, ctx, !priv->cfg->mod_params->sw_crypto);
+
+ IWL_DEBUG_INFO(priv,
+ "Going to commit RXON\n"
+ " * with%s RXON_FILTER_ASSOC_MSK\n"
+ " * channel = %d\n"
+ " * bssid = %pM\n",
+ (new_assoc ? "" : "out"),
+ le16_to_cpu(ctx->staging.channel),
+ ctx->staging.bssid_addr);
+
+ /*
+ * Always clear associated first, but with the correct config.
+ * This is required as for example station addition for the
+ * AP station must be done after the BSSID is set to correctly
+ * set up filters in the device.
+ */
+ if ((old_assoc && new_assoc) || !new_assoc) {
+ if (ctx->ctxid == IWL_RXON_CTX_BSS)
+ ret = iwlagn_disable_bss(priv, ctx, &ctx->staging);
+ else
+ ret = iwlagn_disable_pan(priv, ctx, &ctx->staging);
+ if (ret)
+ return ret;
+
+ memcpy(active, &ctx->staging, sizeof(*active));
+
+ /*
+ * Un-assoc RXON clears the station table and WEP
+ * keys, so we have to restore those afterwards.
+ */
+ iwl_clear_ucode_stations(priv, ctx);
+ iwl_restore_stations(priv, ctx);
+ ret = iwl_restore_default_wep_keys(priv, ctx);
+ if (ret) {
+ IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
+ return ret;
+ }
+ }
+
+ /* RXON timing must be before associated RXON */
+ ret = iwl_send_rxon_timing(priv, ctx);
+ if (ret) {
+ IWL_ERR(priv, "Failed to send timing (%d)!\n", ret);
+ return ret;
+ }
+
+ if (new_assoc) {
+ /* QoS info may be cleared by previous un-assoc RXON */
+ iwlagn_update_qos(priv, ctx);
+
+ /*
+ * We'll run into this code path when beaconing is
+ * enabled, but then we also need to send the beacon
+ * to the device.
+ */
+ if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_AP)) {
+ ret = iwlagn_update_beacon(priv, ctx->vif);
+ if (ret) {
+ IWL_ERR(priv,
+ "Error sending required beacon (%d)!\n",
+ ret);
+ return ret;
+ }
+ }
+
+ priv->start_calib = 0;
+ /*
+ * Apply the new configuration.
+ *
+ * Associated RXON doesn't clear the station table in uCode,
+ * so we don't need to restore stations etc. after this.
+ */
+ ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
+ sizeof(struct iwl_rxon_cmd), &ctx->staging);
+ if (ret) {
+ IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
+ return ret;
+ }
+ memcpy(active, &ctx->staging, sizeof(*active));
+
+ iwl_reprogram_ap_sta(priv, ctx);
+
+ /* IBSS beacon needs to be sent after setting assoc */
+ if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_ADHOC))
+ if (iwlagn_update_beacon(priv, ctx->vif))
+ IWL_ERR(priv, "Error sending IBSS beacon\n");
+ }
+
+ iwl_print_rx_config_cmd(priv, ctx);
+
+ iwl_init_sensitivity(priv);
+
+ /*
+ * If we issue a new RXON command which required a tune then we must
+ * send a new TXPOWER command or we won't be able to Tx any frames.
+ *
+ * FIXME: which RXON requires a tune? Can we optimise this out in
+ * some cases?
+ */
+ ret = iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);
+ if (ret) {
+ IWL_ERR(priv, "Error sending TX power (%d)\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed)
+{
+ struct iwl_priv *priv = hw->priv;
+ struct iwl_rxon_context *ctx;
+ struct ieee80211_conf *conf = &hw->conf;
+ struct ieee80211_channel *channel = conf->channel;
+ const struct iwl_channel_info *ch_info;
+ int ret = 0;
+ bool ht_changed[NUM_IWL_RXON_CTX] = {};
+
+ IWL_DEBUG_MAC80211(priv, "changed %#x", changed);
+
+ mutex_lock(&priv->mutex);
+
+ if (unlikely(test_bit(STATUS_SCANNING, &priv->status))) {
+ IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
+ goto out;
+ }
+
+ if (!iwl_is_ready(priv)) {
+ IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
+ goto out;
+ }
+
+ if (changed & (IEEE80211_CONF_CHANGE_SMPS |
+ IEEE80211_CONF_CHANGE_CHANNEL)) {
+ /* mac80211 uses static for non-HT which is what we want */
+ priv->current_ht_config.smps = conf->smps_mode;
+
+ /*
+ * Recalculate chain counts.
+ *
+ * If monitor mode is enabled then mac80211 will
+ * set up the SM PS mode to OFF if an HT channel is
+ * configured.
+ */
+ if (priv->cfg->ops->hcmd->set_rxon_chain)
+ for_each_context(priv, ctx)
+ priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
+ }
+
+ if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
+ unsigned long flags;
+
+ ch_info = iwl_get_channel_info(priv, channel->band,
+ channel->hw_value);
+ if (!is_channel_valid(ch_info)) {
+ IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ for_each_context(priv, ctx) {
+ /* Configure HT40 channels */
+ if (ctx->ht.enabled != conf_is_ht(conf)) {
+ ctx->ht.enabled = conf_is_ht(conf);
+ ht_changed[ctx->ctxid] = true;
+ }
+
+ if (ctx->ht.enabled) {
+ if (conf_is_ht40_minus(conf)) {
+ ctx->ht.extension_chan_offset =
+ IEEE80211_HT_PARAM_CHA_SEC_BELOW;
+ ctx->ht.is_40mhz = true;
+ } else if (conf_is_ht40_plus(conf)) {
+ ctx->ht.extension_chan_offset =
+ IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
+ ctx->ht.is_40mhz = true;
+ } else {
+ ctx->ht.extension_chan_offset =
+ IEEE80211_HT_PARAM_CHA_SEC_NONE;
+ ctx->ht.is_40mhz = false;
+ }
+ } else
+ ctx->ht.is_40mhz = false;
+
+ /*
+ * Default to no protection. Protection mode will
+ * later be set from BSS config in iwl_ht_conf
+ */
+ ctx->ht.protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE;
+
+ /* if we are switching from ht to 2.4 clear flags
+ * from any ht related info since 2.4 does not
+ * support ht */
+ if (le16_to_cpu(ctx->staging.channel) !=
+ channel->hw_value)
+ ctx->staging.flags = 0;
+
+ iwl_set_rxon_channel(priv, channel, ctx);
+ iwl_set_rxon_ht(priv, &priv->current_ht_config);
+
+ iwl_set_flags_for_band(priv, ctx, channel->band,
+ ctx->vif);
+ }
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ iwl_update_bcast_stations(priv);
+
+ /*
+ * The list of supported rates and rate mask can be different
+ * for each band; since the band may have changed, reset
+ * the rate mask to what mac80211 lists.
+ */
+ iwl_set_rate(priv);
+ }
+
+ if (changed & (IEEE80211_CONF_CHANGE_PS |
+ IEEE80211_CONF_CHANGE_IDLE)) {
+ ret = iwl_power_update_mode(priv, false);
+ if (ret)
+ IWL_DEBUG_MAC80211(priv, "Error setting sleep level\n");
+ }
+
+ if (changed & IEEE80211_CONF_CHANGE_POWER) {
+ IWL_DEBUG_MAC80211(priv, "TX Power old=%d new=%d\n",
+ priv->tx_power_user_lmt, conf->power_level);
+
+ iwl_set_tx_power(priv, conf->power_level, false);
+ }
+
+ for_each_context(priv, ctx) {
+ if (!memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))
+ continue;
+ iwlagn_commit_rxon(priv, ctx);
+ if (ht_changed[ctx->ctxid])
+ iwlagn_update_qos(priv, ctx);
+ }
+ out:
+ mutex_unlock(&priv->mutex);
+ return ret;
+}
+
+static void iwlagn_check_needed_chains(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx,
+ struct ieee80211_bss_conf *bss_conf)
+{
+ struct ieee80211_vif *vif = ctx->vif;
+ struct iwl_rxon_context *tmp;
+ struct ieee80211_sta *sta;
+ struct iwl_ht_config *ht_conf = &priv->current_ht_config;
+ bool need_multiple;
+
+ lockdep_assert_held(&priv->mutex);
+
+ switch (vif->type) {
+ case NL80211_IFTYPE_STATION:
+ rcu_read_lock();
+ sta = ieee80211_find_sta(vif, bss_conf->bssid);
+ if (sta) {
+ struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
+ int maxstreams;
+
+ maxstreams = (ht_cap->mcs.tx_params &
+ IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK)
+ >> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
+ maxstreams += 1;
+
+ need_multiple = true;
+
+ if ((ht_cap->mcs.rx_mask[1] == 0) &&
+ (ht_cap->mcs.rx_mask[2] == 0))
+ need_multiple = false;
+ if (maxstreams <= 1)
+ need_multiple = false;
+ } else {
+ /*
+ * If at all, this can only happen through a race
+ * when the AP disconnects us while we're still
+ * setting up the connection, in that case mac80211
+ * will soon tell us about that.
+ */
+ need_multiple = false;
+ }
+ rcu_read_unlock();
+ break;
+ case NL80211_IFTYPE_ADHOC:
+ /* currently */
+ need_multiple = false;
+ break;
+ default:
+ /* only AP really */
+ need_multiple = true;
+ break;
+ }
+
+ ctx->ht_need_multiple_chains = need_multiple;
+
+ if (!need_multiple) {
+ /* check all contexts */
+ for_each_context(priv, tmp) {
+ if (!tmp->vif)
+ continue;
+ if (tmp->ht_need_multiple_chains) {
+ need_multiple = true;
+ break;
+ }
+ }
+ }
+
+ ht_conf->single_chain_sufficient = !need_multiple;
+}
+
+void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *bss_conf,
+ u32 changes)
+{
+ struct iwl_priv *priv = hw->priv;
+ struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
+ int ret;
+ bool force = false;
+
+ mutex_lock(&priv->mutex);
+
+ if (WARN_ON(!ctx->vif)) {
+ mutex_unlock(&priv->mutex);
+ return;
+ }
+
+ if (changes & BSS_CHANGED_BEACON_INT)
+ force = true;
+
+ if (changes & BSS_CHANGED_QOS) {
+ ctx->qos_data.qos_active = bss_conf->qos;
+ iwlagn_update_qos(priv, ctx);
+ }
+
+ ctx->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid);
+ if (vif->bss_conf.use_short_preamble)
+ ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
+ else
+ ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+
+ if (changes & BSS_CHANGED_ASSOC) {
+ if (bss_conf->assoc) {
+ iwl_led_associate(priv);
+ priv->timestamp = bss_conf->timestamp;
+ ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
+ } else {
+ ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ iwl_led_disassociate(priv);
+ }
+ }
+
+ if (ctx->ht.enabled) {
+ ctx->ht.protection = bss_conf->ht_operation_mode &
+ IEEE80211_HT_OP_MODE_PROTECTION;
+ ctx->ht.non_gf_sta_present = !!(bss_conf->ht_operation_mode &
+ IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
+ iwlagn_check_needed_chains(priv, ctx, bss_conf);
+ iwl_set_rxon_ht(priv, &priv->current_ht_config);
+ }
+
+ if (priv->cfg->ops->hcmd->set_rxon_chain)
+ priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
+
+ if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ))
+ ctx->staging.flags |= RXON_FLG_TGG_PROTECT_MSK;
+ else
+ ctx->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
+
+ if (bss_conf->use_cts_prot)
+ ctx->staging.flags |= RXON_FLG_SELF_CTS_EN;
+ else
+ ctx->staging.flags &= ~RXON_FLG_SELF_CTS_EN;
+
+ memcpy(ctx->staging.bssid_addr, bss_conf->bssid, ETH_ALEN);
+
+ if (vif->type == NL80211_IFTYPE_AP ||
+ vif->type == NL80211_IFTYPE_ADHOC) {
+ if (vif->bss_conf.enable_beacon) {
+ ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
+ priv->beacon_ctx = ctx;
+ } else {
+ ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ priv->beacon_ctx = NULL;
+ }
+ }
+
+ if (force || memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))
+ iwlagn_commit_rxon(priv, ctx);
+
+ if (changes & BSS_CHANGED_ASSOC && bss_conf->assoc) {
+ /*
+ * The chain noise calibration will enable PM upon
+ * completion. If calibration has already been run
+ * then we need to enable power management here.
+ */
+ if (priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE)
+ iwl_power_update_mode(priv, false);
+
+ /* Enable RX differential gain and sensitivity calibrations */
+ iwl_chain_noise_reset(priv);
+ priv->start_calib = 1;
+ }
+
+ if (changes & BSS_CHANGED_IBSS) {
+ ret = iwlagn_manage_ibss_station(priv, vif,
+ bss_conf->ibss_joined);
+ if (ret)
+ IWL_ERR(priv, "failed to %s IBSS station %pM\n",
+ bss_conf->ibss_joined ? "add" : "remove",
+ bss_conf->bssid);
+ }
+
+ if (changes & BSS_CHANGED_BEACON && vif->type == NL80211_IFTYPE_ADHOC &&
+ priv->beacon_ctx) {
+ if (iwlagn_update_beacon(priv, vif))
+ IWL_ERR(priv, "Error sending IBSS beacon\n");
+ }
+
+ mutex_unlock(&priv->mutex);
+}
+
+void iwlagn_post_scan(struct iwl_priv *priv)
+{
+ struct iwl_rxon_context *ctx;
+
+ /*
+ * Since setting the RXON may have been deferred while
+ * performing the scan, fire one off if needed
+ */
+ for_each_context(priv, ctx)
+ if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))
+ iwlagn_commit_rxon(priv, ctx);
+
+ if (priv->cfg->ops->hcmd->set_pan_params)
+ priv->cfg->ops->hcmd->set_pan_params(priv);
+}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
index 35a30d2e0734..35f085ac336b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
@@ -684,7 +684,7 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
}
-void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id)
+static void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id)
{
unsigned long flags;
@@ -714,3 +714,33 @@ void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt)
spin_unlock_irqrestore(&priv->sta_lock, flags);
}
+
+void iwlagn_mac_sta_notify(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ enum sta_notify_cmd cmd,
+ struct ieee80211_sta *sta)
+{
+ struct iwl_priv *priv = hw->priv;
+ struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
+ int sta_id;
+
+ switch (cmd) {
+ case STA_NOTIFY_SLEEP:
+ WARN_ON(!sta_priv->client);
+ sta_priv->asleep = true;
+ if (atomic_read(&sta_priv->pending_frames) > 0)
+ ieee80211_sta_block_awake(hw, sta, true);
+ break;
+ case STA_NOTIFY_AWAKE:
+ WARN_ON(!sta_priv->client);
+ if (!sta_priv->asleep)
+ break;
+ sta_priv->asleep = false;
+ sta_id = iwl_sta_id(sta);
+ if (sta_id != IWL_INVALID_STATION)
+ iwl_sta_modify_ps_wake(priv, sta_id);
+ break;
+ default:
+ break;
+ }
+}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index 2b078a995729..72b1f262796c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -67,8 +67,14 @@
*/
static const u8 tid_to_ac[] = {
- /* this matches the mac80211 numbers */
- 2, 3, 3, 2, 1, 1, 0, 0
+ IEEE80211_AC_BE,
+ IEEE80211_AC_BK,
+ IEEE80211_AC_BK,
+ IEEE80211_AC_BE,
+ IEEE80211_AC_VI,
+ IEEE80211_AC_VI,
+ IEEE80211_AC_VO,
+ IEEE80211_AC_VO
};
static inline int get_ac_from_tid(u16 tid)
@@ -518,11 +524,11 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
struct iwl_cmd_meta *out_meta;
struct iwl_tx_cmd *tx_cmd;
struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
- int swq_id, txq_id;
+ int txq_id;
dma_addr_t phys_addr;
dma_addr_t txcmd_phys;
dma_addr_t scratch_phys;
- u16 len, len_org, firstlen, secondlen;
+ u16 len, firstlen, secondlen;
u16 seq_number = 0;
__le16 fc;
u8 hdr_len;
@@ -531,6 +537,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
u8 tid = 0;
u8 *qc = NULL;
unsigned long flags;
+ bool is_agg = false;
if (info->control.vif)
ctx = iwl_rxon_ctx_from_vif(info->control.vif);
@@ -567,8 +574,8 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
if (sta)
sta_priv = (void *)sta->drv_priv;
- if (sta_priv && sta_priv->asleep) {
- WARN_ON(!(info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE));
+ if (sta_priv && sta_priv->asleep &&
+ (info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE)) {
/*
* This sends an asynchronous command to the device,
* but we can rely on it being processed before the
@@ -616,11 +623,11 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
if (info->flags & IEEE80211_TX_CTL_AMPDU &&
priv->stations[sta_id].tid[tid].agg.state == IWL_AGG_ON) {
txq_id = priv->stations[sta_id].tid[tid].agg.txq_id;
+ is_agg = true;
}
}
txq = &priv->txq[txq_id];
- swq_id = txq->swq_id;
q = &txq->q;
if (unlikely(iwl_queue_space(q) < q->high_mark)) {
@@ -687,30 +694,23 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
*/
len = sizeof(struct iwl_tx_cmd) +
sizeof(struct iwl_cmd_header) + hdr_len;
-
- len_org = len;
- firstlen = len = (len + 3) & ~3;
-
- if (len_org != len)
- len_org = 1;
- else
- len_org = 0;
+ firstlen = (len + 3) & ~3;
/* Tell NIC about any 2-byte padding after MAC header */
- if (len_org)
+ if (firstlen != len)
tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK;
/* Physical address of this Tx command's header (not MAC header!),
* within command buffer array. */
txcmd_phys = pci_map_single(priv->pci_dev,
- &out_cmd->hdr, len,
+ &out_cmd->hdr, firstlen,
PCI_DMA_BIDIRECTIONAL);
dma_unmap_addr_set(out_meta, mapping, txcmd_phys);
- dma_unmap_len_set(out_meta, len, len);
+ dma_unmap_len_set(out_meta, len, firstlen);
/* Add buffer containing Tx command and MAC(!) header to TFD's
* first entry */
priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
- txcmd_phys, len, 1, 0);
+ txcmd_phys, firstlen, 1, 0);
if (!ieee80211_has_morefrags(hdr->frame_control)) {
txq->need_update = 1;
@@ -721,23 +721,21 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
/* Set up TFD's 2nd entry to point directly to remainder of skb,
* if any (802.11 null frames have no payload). */
- secondlen = len = skb->len - hdr_len;
- if (len) {
+ secondlen = skb->len - hdr_len;
+ if (secondlen > 0) {
phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len,
- len, PCI_DMA_TODEVICE);
+ secondlen, PCI_DMA_TODEVICE);
priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
- phys_addr, len,
+ phys_addr, secondlen,
0, 0);
}
scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) +
offsetof(struct iwl_tx_cmd, scratch);
- len = sizeof(struct iwl_tx_cmd) +
- sizeof(struct iwl_cmd_header) + hdr_len;
/* take back ownership of DMA buffer to enable update */
pci_dma_sync_single_for_cpu(priv->pci_dev, txcmd_phys,
- len, PCI_DMA_BIDIRECTIONAL);
+ firstlen, PCI_DMA_BIDIRECTIONAL);
tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys);
tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys);
@@ -753,7 +751,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
le16_to_cpu(tx_cmd->len));
pci_dma_sync_single_for_device(priv->pci_dev, txcmd_phys,
- len, PCI_DMA_BIDIRECTIONAL);
+ firstlen, PCI_DMA_BIDIRECTIONAL);
trace_iwlwifi_dev_tx(priv,
&((struct iwl_tfd *)txq->tfds)[txq->q.write_ptr],
@@ -773,8 +771,14 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
* whether or not we should update the write pointer.
*/
- /* avoid atomic ops if it isn't an associated client */
- if (sta_priv && sta_priv->client)
+ /*
+ * Avoid atomic ops if it isn't an associated client.
+ * Also, if this is a packet for aggregation, don't
+ * increase the counter because the ucode will stop
+ * aggregation queues when their respective station
+ * goes to sleep.
+ */
+ if (sta_priv && sta_priv->client && !is_agg)
atomic_inc(&sta_priv->pending_frames);
if ((iwl_queue_space(q) < q->high_mark) && priv->mac80211_registered) {
@@ -784,7 +788,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
iwl_txq_update_write_ptr(priv, txq);
spin_unlock_irqrestore(&priv->lock, flags);
} else {
- iwl_stop_queue(priv, txq->swq_id);
+ iwl_stop_queue(priv, txq);
}
}
@@ -1013,7 +1017,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
tid_data = &priv->stations[sta_id].tid[tid];
*ssn = SEQ_TO_SN(tid_data->seq_number);
tid_data->agg.txq_id = txq_id;
- priv->txq[txq_id].swq_id = iwl_virtual_agg_queue_num(get_ac_from_tid(tid), txq_id);
+ iwl_set_swq_id(&priv->txq[txq_id], get_ac_from_tid(tid), txq_id);
spin_unlock_irqrestore(&priv->sta_lock, flags);
ret = priv->cfg->ops->lib->txq_agg_enable(priv, txq_id, tx_fifo,
@@ -1153,14 +1157,15 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv,
return 0;
}
-static void iwlagn_tx_status(struct iwl_priv *priv, struct iwl_tx_info *tx_info)
+static void iwlagn_non_agg_tx_status(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx,
+ const u8 *addr1)
{
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx_info->skb->data;
struct ieee80211_sta *sta;
struct iwl_station_priv *sta_priv;
rcu_read_lock();
- sta = ieee80211_find_sta(tx_info->ctx->vif, hdr->addr1);
+ sta = ieee80211_find_sta(ctx->vif, addr1);
if (sta) {
sta_priv = (void *)sta->drv_priv;
/* avoid atomic ops if this isn't a client */
@@ -1169,6 +1174,15 @@ static void iwlagn_tx_status(struct iwl_priv *priv, struct iwl_tx_info *tx_info)
ieee80211_sta_block_awake(priv->hw, sta, false);
}
rcu_read_unlock();
+}
+
+static void iwlagn_tx_status(struct iwl_priv *priv, struct iwl_tx_info *tx_info,
+ bool is_agg)
+{
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx_info->skb->data;
+
+ if (!is_agg)
+ iwlagn_non_agg_tx_status(priv, tx_info->ctx, hdr->addr1);
ieee80211_tx_status_irqsafe(priv->hw, tx_info->skb);
}
@@ -1193,7 +1207,8 @@ int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
tx_info = &txq->txb[txq->q.read_ptr];
- iwlagn_tx_status(priv, tx_info);
+ iwlagn_tx_status(priv, tx_info,
+ txq_id >= IWLAGN_FIRST_AMPDU_QUEUE);
hdr = (struct ieee80211_hdr *)tx_info->skb->data;
if (hdr && ieee80211_is_data_qos(hdr->frame_control))
@@ -1241,37 +1256,61 @@ static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv,
if (sh < 0) /* tbw something is wrong with indices */
sh += 0x100;
- /* don't use 64-bit values for now */
- bitmap = le64_to_cpu(ba_resp->bitmap) >> sh;
-
if (agg->frame_count > (64 - sh)) {
IWL_DEBUG_TX_REPLY(priv, "more frames than bitmap size");
return -1;
}
-
- /* check for success or failure according to the
- * transmitted bitmap and block-ack bitmap */
- sent_bitmap = bitmap & agg->bitmap;
-
- /* For each frame attempted in aggregation,
- * update driver's record of tx frame's status. */
- i = 0;
- while (sent_bitmap) {
- ack = sent_bitmap & 1ULL;
- successes += ack;
- IWL_DEBUG_TX_REPLY(priv, "%s ON i=%d idx=%d raw=%d\n",
- ack ? "ACK" : "NACK", i, (agg->start_idx + i) & 0xff,
- agg->start_idx + i);
- sent_bitmap >>= 1;
- ++i;
+ if (!priv->cfg->base_params->no_agg_framecnt_info && ba_resp->txed) {
+ /*
+ * sent and ack information provided by uCode
+ * use it instead of figure out ourself
+ */
+ if (ba_resp->txed_2_done > ba_resp->txed) {
+ IWL_DEBUG_TX_REPLY(priv,
+ "bogus sent(%d) and ack(%d) count\n",
+ ba_resp->txed, ba_resp->txed_2_done);
+ /*
+ * set txed_2_done = txed,
+ * so it won't impact rate scale
+ */
+ ba_resp->txed = ba_resp->txed_2_done;
+ }
+ IWL_DEBUG_HT(priv, "agg frames sent:%d, acked:%d\n",
+ ba_resp->txed, ba_resp->txed_2_done);
+ } else {
+ /* don't use 64-bit values for now */
+ bitmap = le64_to_cpu(ba_resp->bitmap) >> sh;
+
+ /* check for success or failure according to the
+ * transmitted bitmap and block-ack bitmap */
+ sent_bitmap = bitmap & agg->bitmap;
+
+ /* For each frame attempted in aggregation,
+ * update driver's record of tx frame's status. */
+ i = 0;
+ while (sent_bitmap) {
+ ack = sent_bitmap & 1ULL;
+ successes += ack;
+ IWL_DEBUG_TX_REPLY(priv, "%s ON i=%d idx=%d raw=%d\n",
+ ack ? "ACK" : "NACK", i,
+ (agg->start_idx + i) & 0xff,
+ agg->start_idx + i);
+ sent_bitmap >>= 1;
+ ++i;
+ }
}
-
info = IEEE80211_SKB_CB(priv->txq[scd_flow].txb[agg->start_idx].skb);
memset(&info->status, 0, sizeof(info->status));
info->flags |= IEEE80211_TX_STAT_ACK;
info->flags |= IEEE80211_TX_STAT_AMPDU;
- info->status.ampdu_ack_len = successes;
- info->status.ampdu_len = agg->frame_count;
+ if (!priv->cfg->base_params->no_agg_framecnt_info && ba_resp->txed) {
+ info->status.ampdu_ack_len = ba_resp->txed_2_done;
+ info->status.ampdu_len = ba_resp->txed;
+
+ } else {
+ info->status.ampdu_ack_len = successes;
+ info->status.ampdu_len = agg->frame_count;
+ }
iwlagn_hwrate_to_tx_control(priv, agg->rate_n_flags, info);
IWL_DEBUG_TX_REPLY(priv, "Bitmap %llx\n", (unsigned long long)bitmap);
@@ -1385,7 +1424,7 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
if ((iwl_queue_space(&txq->q) > txq->q.low_mark) &&
priv->mac80211_registered &&
(agg->state != IWL_EMPTYING_HW_QUEUE_DELBA))
- iwl_wake_queue(priv, txq->swq_id);
+ iwl_wake_queue(priv, txq);
iwlagn_txq_check_empty(priv, sta_id, tid, scd_flow);
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
index 703621107dac..24dabcd2a36c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
@@ -40,30 +40,36 @@
#include "iwl-agn.h"
#include "iwl-agn-calib.h"
-static const s8 iwlagn_default_queue_to_tx_fifo[] = {
- IWL_TX_FIFO_VO,
- IWL_TX_FIFO_VI,
- IWL_TX_FIFO_BE,
- IWL_TX_FIFO_BK,
- IWLAGN_CMD_FIFO_NUM,
- IWL_TX_FIFO_UNUSED,
- IWL_TX_FIFO_UNUSED,
- IWL_TX_FIFO_UNUSED,
- IWL_TX_FIFO_UNUSED,
- IWL_TX_FIFO_UNUSED,
+#define IWL_AC_UNSET -1
+
+struct queue_to_fifo_ac {
+ s8 fifo, ac;
+};
+
+static const struct queue_to_fifo_ac iwlagn_default_queue_to_tx_fifo[] = {
+ { IWL_TX_FIFO_VO, IEEE80211_AC_VO, },
+ { IWL_TX_FIFO_VI, IEEE80211_AC_VI, },
+ { IWL_TX_FIFO_BE, IEEE80211_AC_BE, },
+ { IWL_TX_FIFO_BK, IEEE80211_AC_BK, },
+ { IWLAGN_CMD_FIFO_NUM, IWL_AC_UNSET, },
+ { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
+ { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
+ { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
+ { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
+ { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
};
-static const s8 iwlagn_ipan_queue_to_tx_fifo[] = {
- IWL_TX_FIFO_VO,
- IWL_TX_FIFO_VI,
- IWL_TX_FIFO_BE,
- IWL_TX_FIFO_BK,
- IWL_TX_FIFO_BK_IPAN,
- IWL_TX_FIFO_BE_IPAN,
- IWL_TX_FIFO_VI_IPAN,
- IWL_TX_FIFO_VO_IPAN,
- IWL_TX_FIFO_BE_IPAN,
- IWLAGN_CMD_FIFO_NUM,
+static const struct queue_to_fifo_ac iwlagn_ipan_queue_to_tx_fifo[] = {
+ { IWL_TX_FIFO_VO, IEEE80211_AC_VO, },
+ { IWL_TX_FIFO_VI, IEEE80211_AC_VI, },
+ { IWL_TX_FIFO_BE, IEEE80211_AC_BE, },
+ { IWL_TX_FIFO_BK, IEEE80211_AC_BK, },
+ { IWL_TX_FIFO_BK_IPAN, IEEE80211_AC_BK, },
+ { IWL_TX_FIFO_BE_IPAN, IEEE80211_AC_BE, },
+ { IWL_TX_FIFO_VI_IPAN, IEEE80211_AC_VI, },
+ { IWL_TX_FIFO_VO_IPAN, IEEE80211_AC_VO, },
+ { IWL_TX_FIFO_BE_IPAN, 2, },
+ { IWLAGN_CMD_FIFO_NUM, IWL_AC_UNSET, },
};
static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = {
@@ -429,7 +435,7 @@ void iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type)
int iwlagn_alive_notify(struct iwl_priv *priv)
{
- const s8 *queues;
+ const struct queue_to_fifo_ac *queue_to_fifo;
u32 a;
unsigned long flags;
int i, chan;
@@ -492,9 +498,9 @@ int iwlagn_alive_notify(struct iwl_priv *priv)
/* map queues to FIFOs */
if (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS))
- queues = iwlagn_ipan_queue_to_tx_fifo;
+ queue_to_fifo = iwlagn_ipan_queue_to_tx_fifo;
else
- queues = iwlagn_default_queue_to_tx_fifo;
+ queue_to_fifo = iwlagn_default_queue_to_tx_fifo;
iwlagn_set_wr_ptrs(priv, priv->cmd_queue, 0);
@@ -510,18 +516,25 @@ int iwlagn_alive_notify(struct iwl_priv *priv)
BUILD_BUG_ON(ARRAY_SIZE(iwlagn_ipan_queue_to_tx_fifo) != 10);
for (i = 0; i < 10; i++) {
- int ac = queues[i];
+ int fifo = queue_to_fifo[i].fifo;
+ int ac = queue_to_fifo[i].ac;
iwl_txq_ctx_activate(priv, i);
- if (ac == IWL_TX_FIFO_UNUSED)
+ if (fifo == IWL_TX_FIFO_UNUSED)
continue;
- iwlagn_tx_queue_set_status(priv, &priv->txq[i], ac, 0);
+ if (ac != IWL_AC_UNSET)
+ iwl_set_swq_id(&priv->txq[i], ac, i);
+ iwlagn_tx_queue_set_status(priv, &priv->txq[i], fifo, 0);
}
spin_unlock_irqrestore(&priv->lock, flags);
+ /* Enable L1-Active */
+ iwl_clear_bits_prph(priv, APMG_PCIDEV_STT_REG,
+ APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
+
iwlagn_send_wimax_coex(priv);
iwlagn_set_Xtal_calib(priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index c2636a7ab9ee..d4075476670a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -90,170 +90,6 @@ MODULE_ALIAS("iwl4965");
static int iwlagn_ant_coupling;
static bool iwlagn_bt_ch_announce = 1;
-/**
- * iwlagn_commit_rxon - commit staging_rxon to hardware
- *
- * The RXON command in staging_rxon is committed to the hardware and
- * the active_rxon structure is updated with the new data. This
- * function correctly transitions out of the RXON_ASSOC_MSK state if
- * a HW tune is required based on the RXON structure changes.
- */
-int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
-{
- /* cast away the const for active_rxon in this function */
- struct iwl_rxon_cmd *active_rxon = (void *)&ctx->active;
- int ret;
- bool new_assoc =
- !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK);
- bool old_assoc = !!(ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK);
-
- if (!iwl_is_alive(priv))
- return -EBUSY;
-
- if (!ctx->is_active)
- return 0;
-
- /* always get timestamp with Rx frame */
- ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK;
-
- ret = iwl_check_rxon_cmd(priv, ctx);
- if (ret) {
- IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");
- return -EINVAL;
- }
-
- /*
- * receive commit_rxon request
- * abort any previous channel switch if still in process
- */
- if (priv->switch_rxon.switch_in_progress &&
- (priv->switch_rxon.channel != ctx->staging.channel)) {
- IWL_DEBUG_11H(priv, "abort channel switch on %d\n",
- le16_to_cpu(priv->switch_rxon.channel));
- iwl_chswitch_done(priv, false);
- }
-
- /* If we don't need to send a full RXON, we can use
- * iwl_rxon_assoc_cmd which is used to reconfigure filter
- * and other flags for the current radio configuration. */
- if (!iwl_full_rxon_required(priv, ctx)) {
- ret = iwl_send_rxon_assoc(priv, ctx);
- if (ret) {
- IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret);
- return ret;
- }
-
- memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
- iwl_print_rx_config_cmd(priv, ctx);
- return 0;
- }
-
- /* If we are currently associated and the new config requires
- * an RXON_ASSOC and the new config wants the associated mask enabled,
- * we must clear the associated from the active configuration
- * before we apply the new config */
- if (iwl_is_associated_ctx(ctx) && new_assoc) {
- IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n");
- active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-
- ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
- sizeof(struct iwl_rxon_cmd),
- active_rxon);
-
- /* If the mask clearing failed then we set
- * active_rxon back to what it was previously */
- if (ret) {
- active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK;
- IWL_ERR(priv, "Error clearing ASSOC_MSK (%d)\n", ret);
- return ret;
- }
- iwl_clear_ucode_stations(priv, ctx);
- iwl_restore_stations(priv, ctx);
- ret = iwl_restore_default_wep_keys(priv, ctx);
- if (ret) {
- IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
- return ret;
- }
- }
-
- IWL_DEBUG_INFO(priv, "Sending RXON\n"
- "* with%s RXON_FILTER_ASSOC_MSK\n"
- "* channel = %d\n"
- "* bssid = %pM\n",
- (new_assoc ? "" : "out"),
- le16_to_cpu(ctx->staging.channel),
- ctx->staging.bssid_addr);
-
- iwl_set_rxon_hwcrypto(priv, ctx, !priv->cfg->mod_params->sw_crypto);
-
- if (!old_assoc) {
- /*
- * First of all, before setting associated, we need to
- * send RXON timing so the device knows about the DTIM
- * period and other timing values
- */
- ret = iwl_send_rxon_timing(priv, ctx);
- if (ret) {
- IWL_ERR(priv, "Error setting RXON timing!\n");
- return ret;
- }
- }
-
- if (priv->cfg->ops->hcmd->set_pan_params) {
- ret = priv->cfg->ops->hcmd->set_pan_params(priv);
- if (ret)
- return ret;
- }
-
- /* Apply the new configuration
- * RXON unassoc clears the station table in uCode so restoration of
- * stations is needed after it (the RXON command) completes
- */
- if (!new_assoc) {
- ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
- sizeof(struct iwl_rxon_cmd), &ctx->staging);
- if (ret) {
- IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
- return ret;
- }
- IWL_DEBUG_INFO(priv, "Return from !new_assoc RXON.\n");
- memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
- iwl_clear_ucode_stations(priv, ctx);
- iwl_restore_stations(priv, ctx);
- ret = iwl_restore_default_wep_keys(priv, ctx);
- if (ret) {
- IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
- return ret;
- }
- }
- if (new_assoc) {
- priv->start_calib = 0;
- /* Apply the new configuration
- * RXON assoc doesn't clear the station table in uCode,
- */
- ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
- sizeof(struct iwl_rxon_cmd), &ctx->staging);
- if (ret) {
- IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
- return ret;
- }
- memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
- }
- iwl_print_rx_config_cmd(priv, ctx);
-
- iwl_init_sensitivity(priv);
-
- /* If we issue a new RXON command which required a tune then we must
- * send a new TXPOWER command or we won't be able to Tx any frames */
- ret = iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);
- if (ret) {
- IWL_ERR(priv, "Error sending TX power (%d)\n", ret);
- return ret;
- }
-
- return 0;
-}
-
void iwl_update_chain_flags(struct iwl_priv *priv)
{
struct iwl_rxon_context *ctx;
@@ -261,7 +97,8 @@ void iwl_update_chain_flags(struct iwl_priv *priv)
if (priv->cfg->ops->hcmd->set_rxon_chain) {
for_each_context(priv, ctx) {
priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
- iwlcore_commit_rxon(priv, ctx);
+ if (ctx->active.rx_chain != ctx->staging.rx_chain)
+ iwlcore_commit_rxon(priv, ctx);
}
}
}
@@ -411,7 +248,8 @@ static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv,
return sizeof(*tx_beacon_cmd) + frame_size;
}
-static int iwl_send_beacon_cmd(struct iwl_priv *priv)
+
+int iwlagn_send_beacon_cmd(struct iwl_priv *priv)
{
struct iwl_frame *frame;
unsigned int frame_size;
@@ -661,7 +499,7 @@ static void iwl_bg_beacon_update(struct work_struct *work)
priv->beacon_skb = beacon;
- iwl_send_beacon_cmd(priv);
+ iwlagn_send_beacon_cmd(priv);
out:
mutex_unlock(&priv->mutex);
}
@@ -2664,7 +2502,7 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
return pos;
}
- /* enable/disable bt channel announcement */
+ /* enable/disable bt channel inhibition */
priv->bt_ch_announce = iwlagn_bt_ch_announce;
#ifdef CONFIG_IWLWIFI_DEBUG
@@ -2816,13 +2654,8 @@ static void iwl_alive_start(struct iwl_priv *priv)
/* After the ALIVE response, we can send host commands to the uCode */
set_bit(STATUS_ALIVE, &priv->status);
- if (priv->cfg->ops->lib->recover_from_tx_stall) {
- /* Enable timer to monitor the driver queues */
- mod_timer(&priv->monitor_recover,
- jiffies +
- msecs_to_jiffies(
- priv->cfg->base_params->monitor_recover_period));
- }
+ /* Enable watchdog to monitor the driver tx queues */
+ iwl_setup_watchdog(priv);
if (iwl_is_rfkill(priv))
return;
@@ -2879,6 +2712,8 @@ static void iwl_alive_start(struct iwl_priv *priv)
iwl_reset_run_time_calib(priv);
+ set_bit(STATUS_READY, &priv->status);
+
/* Configure the adapter for unassociated operation */
iwlcore_commit_rxon(priv, ctx);
@@ -2888,7 +2723,6 @@ static void iwl_alive_start(struct iwl_priv *priv)
iwl_leds_init(priv);
IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n");
- set_bit(STATUS_READY, &priv->status);
wake_up_interruptible(&priv->wait_command_queue);
iwl_power_update_mode(priv, true);
@@ -2916,8 +2750,7 @@ static void __iwl_down(struct iwl_priv *priv)
/* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set
* to prevent rearm timer */
- if (priv->cfg->ops->lib->recover_from_tx_stall)
- del_timer_sync(&priv->monitor_recover);
+ del_timer_sync(&priv->watchdog);
iwl_clear_ucode_stations(priv, NULL);
iwl_dealloc_bcast_stations(priv);
@@ -2978,7 +2811,8 @@ static void __iwl_down(struct iwl_priv *priv)
STATUS_EXIT_PENDING;
/* device going down, Stop using ICT table */
- iwl_disable_ict(priv);
+ if (priv->cfg->ops->lib->isr_ops.disable)
+ priv->cfg->ops->lib->isr_ops.disable(priv);
iwlagn_txq_ctx_stop(priv);
iwlagn_rxq_stop(priv);
@@ -3201,7 +3035,8 @@ static void iwl_bg_alive_start(struct work_struct *data)
return;
/* enable dram interrupt */
- iwl_reset_ict(priv);
+ if (priv->cfg->ops->lib->isr_ops.reset)
+ priv->cfg->ops->lib->isr_ops.reset(priv);
mutex_lock(&priv->mutex);
iwl_alive_start(priv);
@@ -3309,92 +3144,6 @@ static void iwl_bg_rx_replenish(struct work_struct *data)
mutex_unlock(&priv->mutex);
}
-#define IWL_DELAY_NEXT_SCAN (HZ*2)
-
-void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
-{
- struct iwl_rxon_context *ctx;
- struct ieee80211_conf *conf = NULL;
- int ret = 0;
-
- if (!vif || !priv->is_open)
- return;
-
- ctx = iwl_rxon_ctx_from_vif(vif);
-
- if (vif->type == NL80211_IFTYPE_AP) {
- IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__);
- return;
- }
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- iwl_scan_cancel_timeout(priv, 200);
-
- conf = ieee80211_get_hw_conf(priv->hw);
-
- ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwlcore_commit_rxon(priv, ctx);
-
- ret = iwl_send_rxon_timing(priv, ctx);
- if (ret)
- IWL_WARN(priv, "RXON timing - "
- "Attempting to continue.\n");
-
- ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
-
- iwl_set_rxon_ht(priv, &priv->current_ht_config);
-
- if (priv->cfg->ops->hcmd->set_rxon_chain)
- priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
-
- ctx->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid);
-
- IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
- vif->bss_conf.aid, vif->bss_conf.beacon_int);
-
- if (vif->bss_conf.use_short_preamble)
- ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
- else
- ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
-
- if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
- if (vif->bss_conf.use_short_slot)
- ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
- else
- ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
- }
-
- iwlcore_commit_rxon(priv, ctx);
-
- IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n",
- vif->bss_conf.aid, ctx->active.bssid_addr);
-
- switch (vif->type) {
- case NL80211_IFTYPE_STATION:
- break;
- case NL80211_IFTYPE_ADHOC:
- iwl_send_beacon_cmd(priv);
- break;
- default:
- IWL_ERR(priv, "%s Should not be called in %d mode\n",
- __func__, vif->type);
- break;
- }
-
- /* the chain noise calibration will enabled PM upon completion
- * If chain noise has already been run, then we need to enable
- * power management here */
- if (priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE)
- iwl_power_update_mode(priv, false);
-
- /* Enable Rx differential gain and sensitivity calibrations */
- iwl_chain_noise_reset(priv);
- priv->start_calib = 1;
-
-}
-
/*****************************************************************************
*
* mac80211 entry point functions
@@ -3420,7 +3169,8 @@ static int iwl_mac_setup_register(struct iwl_priv *priv,
hw->flags = IEEE80211_HW_SIGNAL_DBM |
IEEE80211_HW_AMPDU_AGGREGATION |
IEEE80211_HW_NEED_DTIM_PERIOD |
- IEEE80211_HW_SPECTRUM_MGMT;
+ IEEE80211_HW_SPECTRUM_MGMT |
+ IEEE80211_HW_REPORTS_TX_ACK_STATUS;
if (!priv->cfg->base_params->broken_powersave)
hw->flags |= IEEE80211_HW_SUPPORTS_PS |
@@ -3474,7 +3224,7 @@ static int iwl_mac_setup_register(struct iwl_priv *priv,
}
-static int iwl_mac_start(struct ieee80211_hw *hw)
+int iwlagn_mac_start(struct ieee80211_hw *hw)
{
struct iwl_priv *priv = hw->priv;
int ret;
@@ -3515,7 +3265,7 @@ out:
return 0;
}
-static void iwl_mac_stop(struct ieee80211_hw *hw)
+void iwlagn_mac_stop(struct ieee80211_hw *hw)
{
struct iwl_priv *priv = hw->priv;
@@ -3537,7 +3287,7 @@ static void iwl_mac_stop(struct ieee80211_hw *hw)
IWL_DEBUG_MAC80211(priv, "leave\n");
}
-static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+int iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{
struct iwl_priv *priv = hw->priv;
@@ -3553,73 +3303,12 @@ static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
return NETDEV_TX_OK;
}
-void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
-{
- struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
- int ret = 0;
-
- lockdep_assert_held(&priv->mutex);
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- /* The following should be done only at AP bring up */
- if (!iwl_is_associated_ctx(ctx)) {
-
- /* RXON - unassoc (to set timing command) */
- ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwlcore_commit_rxon(priv, ctx);
-
- /* RXON Timing */
- ret = iwl_send_rxon_timing(priv, ctx);
- if (ret)
- IWL_WARN(priv, "RXON timing failed - "
- "Attempting to continue.\n");
-
- /* AP has all antennas */
- priv->chain_noise_data.active_chains =
- priv->hw_params.valid_rx_ant;
- iwl_set_rxon_ht(priv, &priv->current_ht_config);
- if (priv->cfg->ops->hcmd->set_rxon_chain)
- priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
-
- ctx->staging.assoc_id = 0;
-
- if (vif->bss_conf.use_short_preamble)
- ctx->staging.flags |=
- RXON_FLG_SHORT_PREAMBLE_MSK;
- else
- ctx->staging.flags &=
- ~RXON_FLG_SHORT_PREAMBLE_MSK;
-
- if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
- if (vif->bss_conf.use_short_slot)
- ctx->staging.flags |=
- RXON_FLG_SHORT_SLOT_MSK;
- else
- ctx->staging.flags &=
- ~RXON_FLG_SHORT_SLOT_MSK;
- }
- /* need to send beacon cmd before committing assoc RXON! */
- iwl_send_beacon_cmd(priv);
- /* restore RXON assoc */
- ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
- iwlcore_commit_rxon(priv, ctx);
- }
- iwl_send_beacon_cmd(priv);
-
- /* FIXME - we need to add code here to detect a totally new
- * configuration, reset the AP, unassoc, rxon timing, assoc,
- * clear sta table, add BCAST sta... */
-}
-
-static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_key_conf *keyconf,
- struct ieee80211_sta *sta,
- u32 iv32, u16 *phase1key)
+void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_key_conf *keyconf,
+ struct ieee80211_sta *sta,
+ u32 iv32, u16 *phase1key)
{
-
struct iwl_priv *priv = hw->priv;
struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
@@ -3631,10 +3320,9 @@ static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw,
IWL_DEBUG_MAC80211(priv, "leave\n");
}
-static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta,
- struct ieee80211_key_conf *key)
+int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+ struct ieee80211_vif *vif, struct ieee80211_sta *sta,
+ struct ieee80211_key_conf *key)
{
struct iwl_priv *priv = hw->priv;
struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
@@ -3701,10 +3389,10 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
return ret;
}
-static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- enum ieee80211_ampdu_mlme_action action,
- struct ieee80211_sta *sta, u16 tid, u16 *ssn)
+int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ enum ieee80211_ampdu_mlme_action action,
+ struct ieee80211_sta *sta, u16 tid, u16 *ssn)
{
struct iwl_priv *priv = hw->priv;
int ret = -EINVAL;
@@ -3785,39 +3473,9 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
return ret;
}
-static void iwl_mac_sta_notify(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- enum sta_notify_cmd cmd,
- struct ieee80211_sta *sta)
-{
- struct iwl_priv *priv = hw->priv;
- struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
- int sta_id;
-
- switch (cmd) {
- case STA_NOTIFY_SLEEP:
- WARN_ON(!sta_priv->client);
- sta_priv->asleep = true;
- if (atomic_read(&sta_priv->pending_frames) > 0)
- ieee80211_sta_block_awake(hw, sta, true);
- break;
- case STA_NOTIFY_AWAKE:
- WARN_ON(!sta_priv->client);
- if (!sta_priv->asleep)
- break;
- sta_priv->asleep = false;
- sta_id = iwl_sta_id(sta);
- if (sta_id != IWL_INVALID_STATION)
- iwl_sta_modify_ps_wake(priv, sta_id);
- break;
- default:
- break;
- }
-}
-
-static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta)
{
struct iwl_priv *priv = hw->priv;
struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
@@ -3858,8 +3516,8 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
return 0;
}
-static void iwl_mac_channel_switch(struct ieee80211_hw *hw,
- struct ieee80211_channel_switch *ch_switch)
+void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
+ struct ieee80211_channel_switch *ch_switch)
{
struct iwl_priv *priv = hw->priv;
const struct iwl_channel_info *ch_info;
@@ -3956,10 +3614,10 @@ out_exit:
IWL_DEBUG_MAC80211(priv, "leave\n");
}
-static void iwlagn_configure_filter(struct ieee80211_hw *hw,
- unsigned int changed_flags,
- unsigned int *total_flags,
- u64 multicast)
+void iwlagn_configure_filter(struct ieee80211_hw *hw,
+ unsigned int changed_flags,
+ unsigned int *total_flags,
+ u64 multicast)
{
struct iwl_priv *priv = hw->priv;
__le32 filter_or = 0, filter_nand = 0;
@@ -3986,7 +3644,11 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw,
for_each_context(priv, ctx) {
ctx->staging.filter_flags &= ~filter_nand;
ctx->staging.filter_flags |= filter_or;
- iwlcore_commit_rxon(priv, ctx);
+
+ /*
+ * Not committing directly because hardware can perform a scan,
+ * but we'll eventually commit the filter flags change anyway.
+ */
}
mutex_unlock(&priv->mutex);
@@ -4001,7 +3663,7 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw,
FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
}
-static void iwl_mac_flush(struct ieee80211_hw *hw, bool drop)
+void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop)
{
struct iwl_priv *priv = hw->priv;
@@ -4074,12 +3736,9 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
priv->ucode_trace.data = (unsigned long)priv;
priv->ucode_trace.function = iwl_bg_ucode_trace;
- if (priv->cfg->ops->lib->recover_from_tx_stall) {
- init_timer(&priv->monitor_recover);
- priv->monitor_recover.data = (unsigned long)priv;
- priv->monitor_recover.function =
- priv->cfg->ops->lib->recover_from_tx_stall;
- }
+ init_timer(&priv->watchdog);
+ priv->watchdog.data = (unsigned long)priv;
+ priv->watchdog.function = iwl_bg_watchdog;
if (!priv->cfg->base_params->use_isr_legacy)
tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
@@ -4172,13 +3831,13 @@ static int iwl_init_drv(struct iwl_priv *priv)
priv->bt_on_thresh = BT_ON_THRESHOLD_DEF;
priv->bt_duration = BT_DURATION_LIMIT_DEF;
priv->dynamic_frag_thresh = BT_FRAG_THRESHOLD_DEF;
- priv->dynamic_agg_thresh = BT_AGG_THRESHOLD_DEF;
}
/* Set the tx_power_user_lmt to the lowest power level
* this value will get overwritten by channel max power avg
* from eeprom */
priv->tx_power_user_lmt = IWLAGN_TX_POWER_TARGET_POWER_MIN;
+ priv->tx_power_next = IWLAGN_TX_POWER_TARGET_POWER_MIN;
ret = iwl_init_channel_map(priv);
if (ret) {
@@ -4209,28 +3868,30 @@ static void iwl_uninit_drv(struct iwl_priv *priv)
kfree(priv->scan_cmd);
}
-static struct ieee80211_ops iwl_hw_ops = {
- .tx = iwl_mac_tx,
- .start = iwl_mac_start,
- .stop = iwl_mac_stop,
+#ifdef CONFIG_IWL5000
+struct ieee80211_ops iwlagn_hw_ops = {
+ .tx = iwlagn_mac_tx,
+ .start = iwlagn_mac_start,
+ .stop = iwlagn_mac_stop,
.add_interface = iwl_mac_add_interface,
.remove_interface = iwl_mac_remove_interface,
- .config = iwl_mac_config,
+ .change_interface = iwl_mac_change_interface,
+ .config = iwlagn_mac_config,
.configure_filter = iwlagn_configure_filter,
- .set_key = iwl_mac_set_key,
- .update_tkip_key = iwl_mac_update_tkip_key,
+ .set_key = iwlagn_mac_set_key,
+ .update_tkip_key = iwlagn_mac_update_tkip_key,
.conf_tx = iwl_mac_conf_tx,
- .reset_tsf = iwl_mac_reset_tsf,
- .bss_info_changed = iwl_bss_info_changed,
- .ampdu_action = iwl_mac_ampdu_action,
+ .bss_info_changed = iwlagn_bss_info_changed,
+ .ampdu_action = iwlagn_mac_ampdu_action,
.hw_scan = iwl_mac_hw_scan,
- .sta_notify = iwl_mac_sta_notify,
+ .sta_notify = iwlagn_mac_sta_notify,
.sta_add = iwlagn_mac_sta_add,
.sta_remove = iwl_mac_sta_remove,
- .channel_switch = iwl_mac_channel_switch,
- .flush = iwl_mac_flush,
+ .channel_switch = iwlagn_mac_channel_switch,
+ .flush = iwlagn_mac_flush,
.tx_last_beacon = iwl_mac_tx_last_beacon,
};
+#endif
static void iwl_hw_detect(struct iwl_priv *priv)
{
@@ -4298,10 +3959,15 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (cfg->mod_params->disable_hw_scan) {
dev_printk(KERN_DEBUG, &(pdev->dev),
"sw scan support is deprecated\n");
- iwl_hw_ops.hw_scan = NULL;
+#ifdef CONFIG_IWL5000
+ iwlagn_hw_ops.hw_scan = NULL;
+#endif
+#ifdef CONFIG_IWL4965
+ iwl4965_hw_ops.hw_scan = NULL;
+#endif
}
- hw = iwl_alloc_all(cfg, &iwl_hw_ops);
+ hw = iwl_alloc_all(cfg);
if (!hw) {
err = -ENOMEM;
goto out;
@@ -4333,6 +3999,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
BIT(NL80211_IFTYPE_ADHOC);
priv->contexts[IWL_RXON_CTX_BSS].interface_modes =
BIT(NL80211_IFTYPE_STATION);
+ priv->contexts[IWL_RXON_CTX_BSS].ap_devtype = RXON_DEV_TYPE_AP;
priv->contexts[IWL_RXON_CTX_BSS].ibss_devtype = RXON_DEV_TYPE_IBSS;
priv->contexts[IWL_RXON_CTX_BSS].station_devtype = RXON_DEV_TYPE_ESS;
priv->contexts[IWL_RXON_CTX_BSS].unused_devtype = RXON_DEV_TYPE_ESS;
@@ -4368,8 +4035,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
(iwlagn_ant_coupling > IWL_BT_ANTENNA_COUPLING_THRESHOLD) ?
true : false;
- /* enable/disable bt channel announcement */
+ /* enable/disable bt channel inhibition */
priv->bt_ch_announce = iwlagn_bt_ch_announce;
+ IWL_DEBUG_INFO(priv, "BT channel inhibition is %s\n",
+ (priv->bt_ch_announce) ? "On" : "Off");
if (iwl_alloc_traffic_mem(priv))
IWL_ERR(priv, "Not enough memory to generate traffic log\n");
@@ -4461,6 +4130,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (err)
goto out_free_eeprom;
+ err = iwl_eeprom_check_sku(priv);
+ if (err)
+ goto out_free_eeprom;
+
/* extract MAC Address */
iwl_eeprom_get_mac(priv, priv->addresses[0].addr);
IWL_DEBUG_INFO(priv, "MAC address: %pM\n", priv->addresses[0].addr);
@@ -4500,8 +4173,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_enable_msi(priv->pci_dev);
- iwl_alloc_isr_ict(priv);
- err = request_irq(priv->pci_dev->irq, priv->cfg->ops->lib->isr,
+ if (priv->cfg->ops->lib->isr_ops.alloc)
+ priv->cfg->ops->lib->isr_ops.alloc(priv);
+
+ err = request_irq(priv->pci_dev->irq, priv->cfg->ops->lib->isr_ops.isr,
IRQF_SHARED, DRV_NAME, priv);
if (err) {
IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq);
@@ -4548,7 +4223,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
destroy_workqueue(priv->workqueue);
priv->workqueue = NULL;
free_irq(priv->pci_dev->irq, priv);
- iwl_free_isr_ict(priv);
+ if (priv->cfg->ops->lib->isr_ops.free)
+ priv->cfg->ops->lib->isr_ops.free(priv);
out_disable_msi:
pci_disable_msi(priv->pci_dev);
iwl_uninit_drv(priv);
@@ -4643,7 +4319,8 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
iwl_uninit_drv(priv);
- iwl_free_isr_ict(priv);
+ if (priv->cfg->ops->lib->isr_ops.free)
+ priv->cfg->ops->lib->isr_ops.free(priv);
dev_kfree_skb(priv->beacon_skb);
@@ -4735,50 +4412,31 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
{IWL_PCI_DEVICE(0x4239, 0x1316, iwl6000i_2abg_cfg)},
/* 6x00 Series Gen2a */
- {IWL_PCI_DEVICE(0x0082, 0x1201, iwl6000g2a_2agn_cfg)},
- {IWL_PCI_DEVICE(0x0085, 0x1211, iwl6000g2a_2agn_cfg)},
- {IWL_PCI_DEVICE(0x0082, 0x1221, iwl6000g2a_2agn_cfg)},
- {IWL_PCI_DEVICE(0x0082, 0x1206, iwl6000g2a_2abg_cfg)},
- {IWL_PCI_DEVICE(0x0085, 0x1216, iwl6000g2a_2abg_cfg)},
- {IWL_PCI_DEVICE(0x0082, 0x1226, iwl6000g2a_2abg_cfg)},
- {IWL_PCI_DEVICE(0x0082, 0x1207, iwl6000g2a_2bg_cfg)},
- {IWL_PCI_DEVICE(0x0082, 0x1301, iwl6000g2a_2agn_cfg)},
- {IWL_PCI_DEVICE(0x0082, 0x1306, iwl6000g2a_2abg_cfg)},
- {IWL_PCI_DEVICE(0x0082, 0x1307, iwl6000g2a_2bg_cfg)},
- {IWL_PCI_DEVICE(0x0082, 0x1321, iwl6000g2a_2agn_cfg)},
- {IWL_PCI_DEVICE(0x0082, 0x1326, iwl6000g2a_2abg_cfg)},
- {IWL_PCI_DEVICE(0x0085, 0x1311, iwl6000g2a_2agn_cfg)},
- {IWL_PCI_DEVICE(0x0085, 0x1316, iwl6000g2a_2abg_cfg)},
+ {IWL_PCI_DEVICE(0x0082, 0x1301, iwl6005_2agn_cfg)},
+ {IWL_PCI_DEVICE(0x0082, 0x1306, iwl6005_2abg_cfg)},
+ {IWL_PCI_DEVICE(0x0082, 0x1307, iwl6005_2bg_cfg)},
+ {IWL_PCI_DEVICE(0x0082, 0x1321, iwl6005_2agn_cfg)},
+ {IWL_PCI_DEVICE(0x0082, 0x1326, iwl6005_2abg_cfg)},
+ {IWL_PCI_DEVICE(0x0085, 0x1311, iwl6005_2agn_cfg)},
+ {IWL_PCI_DEVICE(0x0085, 0x1316, iwl6005_2abg_cfg)},
/* 6x00 Series Gen2b */
- {IWL_PCI_DEVICE(0x008F, 0x5105, iwl6000g2b_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0090, 0x5115, iwl6000g2b_bgn_cfg)},
- {IWL_PCI_DEVICE(0x008F, 0x5125, iwl6000g2b_bgn_cfg)},
- {IWL_PCI_DEVICE(0x008F, 0x5107, iwl6000g2b_bg_cfg)},
- {IWL_PCI_DEVICE(0x008F, 0x5201, iwl6000g2b_2agn_cfg)},
- {IWL_PCI_DEVICE(0x0090, 0x5211, iwl6000g2b_2agn_cfg)},
- {IWL_PCI_DEVICE(0x008F, 0x5221, iwl6000g2b_2agn_cfg)},
- {IWL_PCI_DEVICE(0x008F, 0x5206, iwl6000g2b_2abg_cfg)},
- {IWL_PCI_DEVICE(0x0090, 0x5216, iwl6000g2b_2abg_cfg)},
- {IWL_PCI_DEVICE(0x008F, 0x5226, iwl6000g2b_2abg_cfg)},
- {IWL_PCI_DEVICE(0x008F, 0x5207, iwl6000g2b_2bg_cfg)},
- {IWL_PCI_DEVICE(0x008A, 0x5301, iwl6000g2b_bgn_cfg)},
- {IWL_PCI_DEVICE(0x008A, 0x5305, iwl6000g2b_bgn_cfg)},
- {IWL_PCI_DEVICE(0x008A, 0x5307, iwl6000g2b_bg_cfg)},
- {IWL_PCI_DEVICE(0x008A, 0x5321, iwl6000g2b_bgn_cfg)},
- {IWL_PCI_DEVICE(0x008A, 0x5325, iwl6000g2b_bgn_cfg)},
- {IWL_PCI_DEVICE(0x008B, 0x5311, iwl6000g2b_bgn_cfg)},
- {IWL_PCI_DEVICE(0x008B, 0x5315, iwl6000g2b_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0090, 0x5211, iwl6000g2b_2agn_cfg)},
- {IWL_PCI_DEVICE(0x0090, 0x5215, iwl6000g2b_2bgn_cfg)},
- {IWL_PCI_DEVICE(0x0090, 0x5216, iwl6000g2b_2abg_cfg)},
- {IWL_PCI_DEVICE(0x0091, 0x5201, iwl6000g2b_2agn_cfg)},
- {IWL_PCI_DEVICE(0x0091, 0x5205, iwl6000g2b_2bgn_cfg)},
- {IWL_PCI_DEVICE(0x0091, 0x5206, iwl6000g2b_2abg_cfg)},
- {IWL_PCI_DEVICE(0x0091, 0x5207, iwl6000g2b_2bg_cfg)},
- {IWL_PCI_DEVICE(0x0091, 0x5221, iwl6000g2b_2agn_cfg)},
- {IWL_PCI_DEVICE(0x0091, 0x5225, iwl6000g2b_2bgn_cfg)},
- {IWL_PCI_DEVICE(0x0091, 0x5226, iwl6000g2b_2abg_cfg)},
+ {IWL_PCI_DEVICE(0x008A, 0x5305, iwl1030_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x008A, 0x5307, iwl1030_bg_cfg)},
+ {IWL_PCI_DEVICE(0x008A, 0x5325, iwl1030_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x008A, 0x5327, iwl1030_bg_cfg)},
+ {IWL_PCI_DEVICE(0x008B, 0x5315, iwl1030_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x008B, 0x5317, iwl1030_bg_cfg)},
+ {IWL_PCI_DEVICE(0x0090, 0x5211, iwl6030_2agn_cfg)},
+ {IWL_PCI_DEVICE(0x0090, 0x5215, iwl6030_2bgn_cfg)},
+ {IWL_PCI_DEVICE(0x0090, 0x5216, iwl6030_2abg_cfg)},
+ {IWL_PCI_DEVICE(0x0091, 0x5201, iwl6030_2agn_cfg)},
+ {IWL_PCI_DEVICE(0x0091, 0x5205, iwl6030_2bgn_cfg)},
+ {IWL_PCI_DEVICE(0x0091, 0x5206, iwl6030_2abg_cfg)},
+ {IWL_PCI_DEVICE(0x0091, 0x5207, iwl6030_2bg_cfg)},
+ {IWL_PCI_DEVICE(0x0091, 0x5221, iwl6030_2agn_cfg)},
+ {IWL_PCI_DEVICE(0x0091, 0x5225, iwl6030_2bgn_cfg)},
+ {IWL_PCI_DEVICE(0x0091, 0x5226, iwl6030_2abg_cfg)},
/* 6x50 WiFi/WiMax Series */
{IWL_PCI_DEVICE(0x0087, 0x1301, iwl6050_2agn_cfg)},
@@ -4789,12 +4447,12 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
{IWL_PCI_DEVICE(0x0089, 0x1316, iwl6050_2abg_cfg)},
/* 6x50 WiFi/WiMax Series Gen2 */
- {IWL_PCI_DEVICE(0x0885, 0x1305, iwl6050g2_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0885, 0x1306, iwl6050g2_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0885, 0x1325, iwl6050g2_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0885, 0x1326, iwl6050g2_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0886, 0x1315, iwl6050g2_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0886, 0x1316, iwl6050g2_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x0885, 0x1305, iwl6150_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x0885, 0x1306, iwl6150_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x0885, 0x1325, iwl6150_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x0885, 0x1326, iwl6150_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x0886, 0x1315, iwl6150_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x0886, 0x1316, iwl6150_bgn_cfg)},
/* 1000 Series WiFi */
{IWL_PCI_DEVICE(0x0083, 0x1205, iwl1000_bgn_cfg)},
@@ -4812,10 +4470,11 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
/* 100 Series WiFi */
{IWL_PCI_DEVICE(0x08AE, 0x1005, iwl100_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x08AE, 0x1007, iwl100_bg_cfg)},
{IWL_PCI_DEVICE(0x08AF, 0x1015, iwl100_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x08AF, 0x1017, iwl100_bg_cfg)},
{IWL_PCI_DEVICE(0x08AE, 0x1025, iwl100_bgn_cfg)},
- {IWL_PCI_DEVICE(0x08AE, 0x1007, iwl100_bg_cfg)},
- {IWL_PCI_DEVICE(0x08AE, 0x1017, iwl100_bg_cfg)},
+ {IWL_PCI_DEVICE(0x08AE, 0x1027, iwl100_bg_cfg)},
/* 130 Series WiFi */
{IWL_PCI_DEVICE(0x0896, 0x5005, iwl130_bgn_cfg)},
@@ -4836,10 +4495,7 @@ static struct pci_driver iwl_driver = {
.id_table = iwl_hw_card_ids,
.probe = iwl_pci_probe,
.remove = __devexit_p(iwl_pci_remove),
-#ifdef CONFIG_PM
- .suspend = iwl_pci_suspend,
- .resume = iwl_pci_resume,
-#endif
+ .driver.pm = IWL_PM_OPS,
};
static int __init iwl_init(void)
@@ -4925,6 +4581,6 @@ module_param_named(antenna_coupling, iwlagn_ant_coupling, int, S_IRUGO);
MODULE_PARM_DESC(antenna_coupling,
"specify antenna coupling in dB (defualt: 0 dB)");
-module_param_named(bt_ch_announce, iwlagn_bt_ch_announce, bool, S_IRUGO);
-MODULE_PARM_DESC(bt_ch_announce,
- "Enable BT channel announcement mode (default: enable)");
+module_param_named(bt_ch_inhibition, iwlagn_bt_ch_announce, bool, S_IRUGO);
+MODULE_PARM_DESC(bt_ch_inhibition,
+ "Disable BT channel inhibition (default: enable)");
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index f525d55f2c0f..da303585f801 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -74,22 +74,22 @@ extern struct iwl_cfg iwl5100_bgn_cfg;
extern struct iwl_cfg iwl5100_abg_cfg;
extern struct iwl_cfg iwl5150_agn_cfg;
extern struct iwl_cfg iwl5150_abg_cfg;
-extern struct iwl_cfg iwl6000g2a_2agn_cfg;
-extern struct iwl_cfg iwl6000g2a_2abg_cfg;
-extern struct iwl_cfg iwl6000g2a_2bg_cfg;
-extern struct iwl_cfg iwl6000g2b_bgn_cfg;
-extern struct iwl_cfg iwl6000g2b_bg_cfg;
-extern struct iwl_cfg iwl6000g2b_2agn_cfg;
-extern struct iwl_cfg iwl6000g2b_2abg_cfg;
-extern struct iwl_cfg iwl6000g2b_2bgn_cfg;
-extern struct iwl_cfg iwl6000g2b_2bg_cfg;
+extern struct iwl_cfg iwl6005_2agn_cfg;
+extern struct iwl_cfg iwl6005_2abg_cfg;
+extern struct iwl_cfg iwl6005_2bg_cfg;
+extern struct iwl_cfg iwl1030_bgn_cfg;
+extern struct iwl_cfg iwl1030_bg_cfg;
+extern struct iwl_cfg iwl6030_2agn_cfg;
+extern struct iwl_cfg iwl6030_2abg_cfg;
+extern struct iwl_cfg iwl6030_2bgn_cfg;
+extern struct iwl_cfg iwl6030_2bg_cfg;
extern struct iwl_cfg iwl6000i_2agn_cfg;
extern struct iwl_cfg iwl6000i_2abg_cfg;
extern struct iwl_cfg iwl6000i_2bg_cfg;
extern struct iwl_cfg iwl6000_3agn_cfg;
extern struct iwl_cfg iwl6050_2agn_cfg;
extern struct iwl_cfg iwl6050_2abg_cfg;
-extern struct iwl_cfg iwl6050g2_bgn_cfg;
+extern struct iwl_cfg iwl6150_bgn_cfg;
extern struct iwl_cfg iwl1000_bgn_cfg;
extern struct iwl_cfg iwl1000_bg_cfg;
extern struct iwl_cfg iwl100_bgn_cfg;
@@ -102,6 +102,9 @@ extern struct iwl_hcmd_ops iwlagn_hcmd;
extern struct iwl_hcmd_ops iwlagn_bt_hcmd;
extern struct iwl_hcmd_utils_ops iwlagn_hcmd_utils;
+extern struct ieee80211_ops iwlagn_hw_ops;
+extern struct ieee80211_ops iwl4965_hw_ops;
+
int iwl_reset_ict(struct iwl_priv *priv);
void iwl_disable_ict(struct iwl_priv *priv);
int iwl_alloc_isr_ict(struct iwl_priv *priv);
@@ -132,6 +135,11 @@ void iwl_free_tfds_in_queue(struct iwl_priv *priv,
/* RXON */
int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
void iwlagn_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
+int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed);
+void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *bss_conf,
+ u32 changes);
/* uCode */
int iwlagn_load_ucode(struct iwl_priv *priv);
@@ -249,6 +257,7 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv,
int iwlagn_send_rxon_assoc(struct iwl_priv *priv,
struct iwl_rxon_context *ctx);
int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant);
+int iwlagn_send_beacon_cmd(struct iwl_priv *priv);
/* bt coex */
void iwlagn_send_advance_bt_config(struct iwl_priv *priv);
@@ -292,9 +301,12 @@ int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta,
int tid, u16 ssn);
int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
int tid);
-void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id);
void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt);
int iwl_update_bcast_stations(struct iwl_priv *priv);
+void iwlagn_mac_sta_notify(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ enum sta_notify_cmd cmd,
+ struct ieee80211_sta *sta);
/* rate */
static inline u32 iwl_ant_idx_to_flags(u8 ant_idx)
@@ -318,4 +330,31 @@ void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac);
int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv);
void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv);
+/* mac80211 handlers (for 4965) */
+int iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
+int iwlagn_mac_start(struct ieee80211_hw *hw);
+void iwlagn_mac_stop(struct ieee80211_hw *hw);
+void iwlagn_configure_filter(struct ieee80211_hw *hw,
+ unsigned int changed_flags,
+ unsigned int *total_flags,
+ u64 multicast);
+int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+ struct ieee80211_vif *vif, struct ieee80211_sta *sta,
+ struct ieee80211_key_conf *key);
+void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_key_conf *keyconf,
+ struct ieee80211_sta *sta,
+ u32 iv32, u16 *phase1key);
+int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ enum ieee80211_ampdu_mlme_action action,
+ struct ieee80211_sta *sta, u16 tid, u16 *ssn);
+int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta);
+void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
+ struct ieee80211_channel_switch *ch_switch);
+void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop);
+
#endif /* __iwl_agn_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 424801abc80e..f893d4a6aa87 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -2022,6 +2022,9 @@ struct iwl_compressed_ba_resp {
__le64 bitmap;
__le16 scd_flow;
__le16 scd_ssn;
+ /* following only for 5000 series and up */
+ u8 txed; /* number of frames sent */
+ u8 txed_2_done; /* number of frames acked */
} __packed;
/*
@@ -2407,9 +2410,9 @@ struct iwl_link_quality_cmd {
#define BT_FRAG_THRESHOLD_MAX 0
#define BT_FRAG_THRESHOLD_MIN 0
-#define BT_AGG_THRESHOLD_DEF 0
-#define BT_AGG_THRESHOLD_MAX 0
-#define BT_AGG_THRESHOLD_MIN 0
+#define BT_AGG_THRESHOLD_DEF 1200
+#define BT_AGG_THRESHOLD_MAX 8000
+#define BT_AGG_THRESHOLD_MIN 400
/*
* REPLY_BT_CONFIG = 0x9b (command, has simple generic response)
@@ -2436,8 +2439,9 @@ struct iwl_bt_cmd {
#define IWLAGN_BT_FLAG_COEX_MODE_3W 2
#define IWLAGN_BT_FLAG_COEX_MODE_4W 3
-#define IWLAGN_BT_FLAG_UCODE_DEFAULT BIT(6)
-#define IWLAGN_BT_FLAG_NOCOEX_NOTIF BIT(7)
+#define IWLAGN_BT_FLAG_UCODE_DEFAULT BIT(6)
+/* Disable Sync PSPoll on SCO/eSCO */
+#define IWLAGN_BT_FLAG_SYNC_2_BT_DISABLE BIT(7)
#define IWLAGN_BT_PRIO_BOOST_MAX 0xFF
#define IWLAGN_BT_PRIO_BOOST_MIN 0x00
@@ -2447,8 +2451,9 @@ struct iwl_bt_cmd {
#define IWLAGN_BT3_T7_DEFAULT 1
-#define IWLAGN_BT_KILL_ACK_MASK_DEFAULT cpu_to_le32(0xffffffff)
-#define IWLAGN_BT_KILL_CTS_MASK_DEFAULT cpu_to_le32(0xffffffff)
+#define IWLAGN_BT_KILL_ACK_MASK_DEFAULT cpu_to_le32(0xffff0000)
+#define IWLAGN_BT_KILL_CTS_MASK_DEFAULT cpu_to_le32(0xffff0000)
+#define IWLAGN_BT_KILL_ACK_CTS_MASK_SCO cpu_to_le32(0xffffffff)
#define IWLAGN_BT3_PRIO_SAMPLE_DEFAULT 2
@@ -2664,9 +2669,16 @@ struct iwl_spectrum_notification {
#define IWL_POWER_VEC_SIZE 5
#define IWL_POWER_DRIVER_ALLOW_SLEEP_MSK cpu_to_le16(BIT(0))
+#define IWL_POWER_POWER_SAVE_ENA_MSK cpu_to_le16(BIT(0))
+#define IWL_POWER_POWER_MANAGEMENT_ENA_MSK cpu_to_le16(BIT(1))
#define IWL_POWER_SLEEP_OVER_DTIM_MSK cpu_to_le16(BIT(2))
#define IWL_POWER_PCI_PM_MSK cpu_to_le16(BIT(3))
#define IWL_POWER_FAST_PD cpu_to_le16(BIT(4))
+#define IWL_POWER_BEACON_FILTERING cpu_to_le16(BIT(5))
+#define IWL_POWER_SHADOW_REG_ENA cpu_to_le16(BIT(6))
+#define IWL_POWER_CT_KILL_SET cpu_to_le16(BIT(7))
+#define IWL_POWER_BT_SCO_ENA cpu_to_le16(BIT(8))
+#define IWL_POWER_ADVANCE_PM_ENA_MSK cpu_to_le16(BIT(9))
struct iwl3945_powertable_cmd {
__le16 flags;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 25fb3912342c..d62b92518417 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -77,15 +77,15 @@ EXPORT_SYMBOL(iwl_bcast_addr);
/* This function both allocates and initializes hw and priv. */
-struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg,
- struct ieee80211_ops *hw_ops)
+struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg)
{
struct iwl_priv *priv;
-
/* mac80211 allocates memory for this device instance, including
* space for this driver's private structure */
- struct ieee80211_hw *hw =
- ieee80211_alloc_hw(sizeof(struct iwl_priv), hw_ops);
+ struct ieee80211_hw *hw;
+
+ hw = ieee80211_alloc_hw(sizeof(struct iwl_priv),
+ cfg->ops->ieee80211_ops);
if (hw == NULL) {
pr_err("%s: Can not allocate network device\n",
cfg->name);
@@ -100,35 +100,6 @@ out:
}
EXPORT_SYMBOL(iwl_alloc_all);
-/*
- * QoS support
-*/
-static void iwl_update_qos(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
-{
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- if (!ctx->is_active)
- return;
-
- ctx->qos_data.def_qos_parm.qos_flags = 0;
-
- if (ctx->qos_data.qos_active)
- ctx->qos_data.def_qos_parm.qos_flags |=
- QOS_PARAM_FLG_UPDATE_EDCA_MSK;
-
- if (ctx->ht.enabled)
- ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
-
- IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n",
- ctx->qos_data.qos_active,
- ctx->qos_data.def_qos_parm.qos_flags);
-
- iwl_send_cmd_pdu_async(priv, ctx->qos_cmd,
- sizeof(struct iwl_qosparam_cmd),
- &ctx->qos_data.def_qos_parm, NULL);
-}
-
#define MAX_BIT_RATE_40_MHZ 150 /* Mbps */
#define MAX_BIT_RATE_20_MHZ 72 /* Mbps */
static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
@@ -317,40 +288,6 @@ void iwlcore_free_geos(struct iwl_priv *priv)
}
EXPORT_SYMBOL(iwlcore_free_geos);
-/*
- * iwlcore_tx_cmd_protection: Set rts/cts. 3945 and 4965 only share this
- * function.
- */
-void iwlcore_tx_cmd_protection(struct iwl_priv *priv,
- struct ieee80211_tx_info *info,
- __le16 fc, __le32 *tx_flags)
-{
- if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) {
- *tx_flags |= TX_CMD_FLG_RTS_MSK;
- *tx_flags &= ~TX_CMD_FLG_CTS_MSK;
- *tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK;
-
- if (!ieee80211_is_mgmt(fc))
- return;
-
- switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
- case cpu_to_le16(IEEE80211_STYPE_AUTH):
- case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
- case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ):
- case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ):
- *tx_flags &= ~TX_CMD_FLG_RTS_MSK;
- *tx_flags |= TX_CMD_FLG_CTS_MSK;
- break;
- }
- } else if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
- *tx_flags &= ~TX_CMD_FLG_RTS_MSK;
- *tx_flags |= TX_CMD_FLG_CTS_MSK;
- *tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK;
- }
-}
-EXPORT_SYMBOL(iwlcore_tx_cmd_protection);
-
-
static bool iwl_is_channel_extension(struct iwl_priv *priv,
enum ieee80211_band band,
u16 channel, u8 extension_chan_offset)
@@ -1206,8 +1143,16 @@ EXPORT_SYMBOL(iwl_apm_init);
int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
{
- int ret = 0;
- s8 prev_tx_power = priv->tx_power_user_lmt;
+ int ret;
+ s8 prev_tx_power;
+
+ lockdep_assert_held(&priv->mutex);
+
+ if (priv->tx_power_user_lmt == tx_power && !force)
+ return 0;
+
+ if (!priv->cfg->ops->lib->send_tx_power)
+ return -EOPNOTSUPP;
if (tx_power < IWLAGN_TX_POWER_TARGET_POWER_MIN) {
IWL_WARN(priv,
@@ -1224,93 +1169,29 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
return -EINVAL;
}
- if (priv->tx_power_user_lmt != tx_power)
- force = true;
+ if (!iwl_is_ready_rf(priv))
+ return -EIO;
- /* if nic is not up don't send command */
- if (iwl_is_ready_rf(priv)) {
- priv->tx_power_user_lmt = tx_power;
- if (force && priv->cfg->ops->lib->send_tx_power)
- ret = priv->cfg->ops->lib->send_tx_power(priv);
- else if (!priv->cfg->ops->lib->send_tx_power)
- ret = -EOPNOTSUPP;
- /*
- * if fail to set tx_power, restore the orig. tx power
- */
- if (ret)
- priv->tx_power_user_lmt = prev_tx_power;
+ /* scan complete use tx_power_next, need to be updated */
+ priv->tx_power_next = tx_power;
+ if (test_bit(STATUS_SCANNING, &priv->status) && !force) {
+ IWL_DEBUG_INFO(priv, "Deferring tx power set while scanning\n");
+ return 0;
}
- /*
- * Even this is an async host command, the command
- * will always report success from uCode
- * So once driver can placing the command into the queue
- * successfully, driver can use priv->tx_power_user_lmt
- * to reflect the current tx power
- */
- return ret;
-}
-EXPORT_SYMBOL(iwl_set_tx_power);
-
-irqreturn_t iwl_isr_legacy(int irq, void *data)
-{
- struct iwl_priv *priv = data;
- u32 inta, inta_mask;
- u32 inta_fh;
- unsigned long flags;
- if (!priv)
- return IRQ_NONE;
-
- spin_lock_irqsave(&priv->lock, flags);
+ prev_tx_power = priv->tx_power_user_lmt;
+ priv->tx_power_user_lmt = tx_power;
- /* Disable (but don't clear!) interrupts here to avoid
- * back-to-back ISRs and sporadic interrupts from our NIC.
- * If we have something to service, the tasklet will re-enable ints.
- * If we *don't* have something, we'll re-enable before leaving here. */
- inta_mask = iwl_read32(priv, CSR_INT_MASK); /* just for debug */
- iwl_write32(priv, CSR_INT_MASK, 0x00000000);
-
- /* Discover which interrupts are active/pending */
- inta = iwl_read32(priv, CSR_INT);
- inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
-
- /* Ignore interrupt if there's nothing in NIC to service.
- * This may be due to IRQ shared with another device,
- * or due to sporadic interrupts thrown from our NIC. */
- if (!inta && !inta_fh) {
- IWL_DEBUG_ISR(priv, "Ignore interrupt, inta == 0, inta_fh == 0\n");
- goto none;
- }
+ ret = priv->cfg->ops->lib->send_tx_power(priv);
- if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) {
- /* Hardware disappeared. It might have already raised
- * an interrupt */
- IWL_WARN(priv, "HARDWARE GONE?? INTA == 0x%08x\n", inta);
- goto unplugged;
+ /* if fail to set tx_power, restore the orig. tx power */
+ if (ret) {
+ priv->tx_power_user_lmt = prev_tx_power;
+ priv->tx_power_next = prev_tx_power;
}
-
- IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
- inta, inta_mask, inta_fh);
-
- inta &= ~CSR_INT_BIT_SCD;
-
- /* iwl_irq_tasklet() will service interrupts and re-enable them */
- if (likely(inta || inta_fh))
- tasklet_schedule(&priv->irq_tasklet);
-
- unplugged:
- spin_unlock_irqrestore(&priv->lock, flags);
- return IRQ_HANDLED;
-
- none:
- /* re-enable interrupts here since we don't have anything to service. */
- /* only Re-enable if diabled by irq */
- if (test_bit(STATUS_INT_ENABLED, &priv->status))
- iwl_enable_interrupts(priv);
- spin_unlock_irqrestore(&priv->lock, flags);
- return IRQ_NONE;
+ return ret;
}
-EXPORT_SYMBOL(iwl_isr_legacy);
+EXPORT_SYMBOL(iwl_set_tx_power);
void iwl_send_bt_config(struct iwl_priv *priv)
{
@@ -1452,318 +1333,51 @@ int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw)
}
EXPORT_SYMBOL_GPL(iwl_mac_tx_last_beacon);
-static void iwl_ht_conf(struct iwl_priv *priv,
- struct ieee80211_vif *vif)
+static int iwl_set_mode(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
{
- struct iwl_ht_config *ht_conf = &priv->current_ht_config;
- struct ieee80211_sta *sta;
- struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
- struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
-
- IWL_DEBUG_MAC80211(priv, "enter:\n");
-
- if (!ctx->ht.enabled)
- return;
-
- ctx->ht.protection =
- bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION;
- ctx->ht.non_gf_sta_present =
- !!(bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
-
- ht_conf->single_chain_sufficient = false;
-
- switch (vif->type) {
- case NL80211_IFTYPE_STATION:
- rcu_read_lock();
- sta = ieee80211_find_sta(vif, bss_conf->bssid);
- if (sta) {
- struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
- int maxstreams;
-
- maxstreams = (ht_cap->mcs.tx_params &
- IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK)
- >> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
- maxstreams += 1;
-
- if ((ht_cap->mcs.rx_mask[1] == 0) &&
- (ht_cap->mcs.rx_mask[2] == 0))
- ht_conf->single_chain_sufficient = true;
- if (maxstreams <= 1)
- ht_conf->single_chain_sufficient = true;
- } else {
- /*
- * If at all, this can only happen through a race
- * when the AP disconnects us while we're still
- * setting up the connection, in that case mac80211
- * will soon tell us about that.
- */
- ht_conf->single_chain_sufficient = true;
- }
- rcu_read_unlock();
- break;
- case NL80211_IFTYPE_ADHOC:
- ht_conf->single_chain_sufficient = true;
- break;
- default:
- break;
- }
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
-}
+ iwl_connection_init_rx_config(priv, ctx);
-static inline void iwl_set_no_assoc(struct iwl_priv *priv,
- struct ieee80211_vif *vif)
-{
- struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
+ if (priv->cfg->ops->hcmd->set_rxon_chain)
+ priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
- iwl_led_disassociate(priv);
- /*
- * inform the ucode that there is no longer an
- * association and that no more packets should be
- * sent
- */
- ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- ctx->staging.assoc_id = 0;
- iwlcore_commit_rxon(priv, ctx);
+ return iwlcore_commit_rxon(priv, ctx);
}
-static void iwlcore_beacon_update(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif)
+static int iwl_setup_interface(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx)
{
- struct iwl_priv *priv = hw->priv;
- unsigned long flags;
- __le64 timestamp;
- struct sk_buff *skb = ieee80211_beacon_get(hw, vif);
-
- if (!skb)
- return;
-
- IWL_DEBUG_ASSOC(priv, "enter\n");
+ struct ieee80211_vif *vif = ctx->vif;
+ int err;
lockdep_assert_held(&priv->mutex);
- if (!priv->beacon_ctx) {
- IWL_ERR(priv, "update beacon but no beacon context!\n");
- dev_kfree_skb(skb);
- return;
- }
-
- spin_lock_irqsave(&priv->lock, flags);
-
- if (priv->beacon_skb)
- dev_kfree_skb(priv->beacon_skb);
-
- priv->beacon_skb = skb;
-
- timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
- priv->timestamp = le64_to_cpu(timestamp);
-
- IWL_DEBUG_ASSOC(priv, "leave\n");
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
- if (!iwl_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
- return;
- }
-
- priv->cfg->ops->lib->post_associate(priv, priv->beacon_ctx->vif);
-}
-
-void iwl_bss_info_changed(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_bss_conf *bss_conf,
- u32 changes)
-{
- struct iwl_priv *priv = hw->priv;
- struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
- int ret;
-
- IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes);
-
- if (!iwl_is_alive(priv))
- return;
-
- mutex_lock(&priv->mutex);
-
- if (changes & BSS_CHANGED_QOS) {
- unsigned long flags;
-
- spin_lock_irqsave(&priv->lock, flags);
- ctx->qos_data.qos_active = bss_conf->qos;
- iwl_update_qos(priv, ctx);
- spin_unlock_irqrestore(&priv->lock, flags);
- }
-
- if (changes & BSS_CHANGED_BEACON_ENABLED) {
- /*
- * the add_interface code must make sure we only ever
- * have a single interface that could be beaconing at
- * any time.
- */
- if (vif->bss_conf.enable_beacon)
- priv->beacon_ctx = ctx;
- else
- priv->beacon_ctx = NULL;
- }
-
- if (changes & BSS_CHANGED_BEACON && vif->type == NL80211_IFTYPE_AP) {
- dev_kfree_skb(priv->beacon_skb);
- priv->beacon_skb = ieee80211_beacon_get(hw, vif);
- }
-
- if (changes & BSS_CHANGED_BEACON_INT && vif->type == NL80211_IFTYPE_AP)
- iwl_send_rxon_timing(priv, ctx);
-
- if (changes & BSS_CHANGED_BSSID) {
- IWL_DEBUG_MAC80211(priv, "BSSID %pM\n", bss_conf->bssid);
-
- /*
- * If there is currently a HW scan going on in the
- * background then we need to cancel it else the RXON
- * below/in post_associate will fail.
- */
- if (iwl_scan_cancel_timeout(priv, 100)) {
- IWL_WARN(priv, "Aborted scan still in progress after 100ms\n");
- IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n");
- mutex_unlock(&priv->mutex);
- return;
- }
-
- /* mac80211 only sets assoc when in STATION mode */
- if (vif->type == NL80211_IFTYPE_ADHOC || bss_conf->assoc) {
- memcpy(ctx->staging.bssid_addr,
- bss_conf->bssid, ETH_ALEN);
-
- /* currently needed in a few places */
- memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN);
- } else {
- ctx->staging.filter_flags &=
- ~RXON_FILTER_ASSOC_MSK;
- }
-
- }
-
/*
- * This needs to be after setting the BSSID in case
- * mac80211 decides to do both changes at once because
- * it will invoke post_associate.
+ * This variable will be correct only when there's just
+ * a single context, but all code using it is for hardware
+ * that supports only one context.
*/
- if (vif->type == NL80211_IFTYPE_ADHOC && changes & BSS_CHANGED_BEACON)
- iwlcore_beacon_update(hw, vif);
-
- if (changes & BSS_CHANGED_ERP_PREAMBLE) {
- IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n",
- bss_conf->use_short_preamble);
- if (bss_conf->use_short_preamble)
- ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
- else
- ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
- }
-
- if (changes & BSS_CHANGED_ERP_CTS_PROT) {
- IWL_DEBUG_MAC80211(priv, "ERP_CTS %d\n", bss_conf->use_cts_prot);
- if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ))
- ctx->staging.flags |= RXON_FLG_TGG_PROTECT_MSK;
- else
- ctx->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
- if (bss_conf->use_cts_prot)
- ctx->staging.flags |= RXON_FLG_SELF_CTS_EN;
- else
- ctx->staging.flags &= ~RXON_FLG_SELF_CTS_EN;
- }
-
- if (changes & BSS_CHANGED_BASIC_RATES) {
- /* XXX use this information
- *
- * To do that, remove code from iwl_set_rate() and put something
- * like this here:
- *
- if (A-band)
- ctx->staging.ofdm_basic_rates =
- bss_conf->basic_rates;
- else
- ctx->staging.ofdm_basic_rates =
- bss_conf->basic_rates >> 4;
- ctx->staging.cck_basic_rates =
- bss_conf->basic_rates & 0xF;
- */
- }
-
- if (changes & BSS_CHANGED_HT) {
- iwl_ht_conf(priv, vif);
-
- if (priv->cfg->ops->hcmd->set_rxon_chain)
- priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
- }
-
- if (changes & BSS_CHANGED_ASSOC) {
- IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc);
- if (bss_conf->assoc) {
- priv->timestamp = bss_conf->timestamp;
-
- iwl_led_associate(priv);
-
- if (!iwl_is_rfkill(priv))
- priv->cfg->ops->lib->post_associate(priv, vif);
- } else
- iwl_set_no_assoc(priv, vif);
- }
-
- if (changes && iwl_is_associated_ctx(ctx) && bss_conf->aid) {
- IWL_DEBUG_MAC80211(priv, "Changes (%#x) while associated\n",
- changes);
- ret = iwl_send_rxon_assoc(priv, ctx);
- if (!ret) {
- /* Sync active_rxon with latest change. */
- memcpy((void *)&ctx->active,
- &ctx->staging,
- sizeof(struct iwl_rxon_cmd));
- }
- }
+ priv->iw_mode = vif->type;
- if (changes & BSS_CHANGED_BEACON_ENABLED) {
- if (vif->bss_conf.enable_beacon) {
- memcpy(ctx->staging.bssid_addr,
- bss_conf->bssid, ETH_ALEN);
- memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN);
- iwl_led_associate(priv);
- iwlcore_config_ap(priv, vif);
- } else
- iwl_set_no_assoc(priv, vif);
- }
+ ctx->is_active = true;
- if (changes & BSS_CHANGED_IBSS) {
- ret = priv->cfg->ops->lib->manage_ibss_station(priv, vif,
- bss_conf->ibss_joined);
- if (ret)
- IWL_ERR(priv, "failed to %s IBSS station %pM\n",
- bss_conf->ibss_joined ? "add" : "remove",
- bss_conf->bssid);
+ err = iwl_set_mode(priv, ctx);
+ if (err) {
+ if (!ctx->always_active)
+ ctx->is_active = false;
+ return err;
}
- if (changes & BSS_CHANGED_IDLE &&
- priv->cfg->ops->hcmd->set_pan_params) {
- if (priv->cfg->ops->hcmd->set_pan_params(priv))
- IWL_ERR(priv, "failed to update PAN params\n");
+ if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist &&
+ vif->type == NL80211_IFTYPE_ADHOC) {
+ /*
+ * pretend to have high BT traffic as long as we
+ * are operating in IBSS mode, as this will cause
+ * the rate scaling etc. to behave as intended.
+ */
+ priv->bt_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_HIGH;
}
- mutex_unlock(&priv->mutex);
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
-}
-EXPORT_SYMBOL(iwl_bss_info_changed);
-
-static int iwl_set_mode(struct iwl_priv *priv, struct ieee80211_vif *vif)
-{
- struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
-
- iwl_connection_init_rx_config(priv, ctx);
-
- if (priv->cfg->ops->hcmd->set_rxon_chain)
- priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
-
- return iwlcore_commit_rxon(priv, ctx);
+ return 0;
}
int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
@@ -1771,7 +1385,7 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
struct iwl_priv *priv = hw->priv;
struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
struct iwl_rxon_context *tmp, *ctx = NULL;
- int err = 0;
+ int err;
IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n",
vif->type, vif->addr);
@@ -1813,36 +1427,11 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
vif_priv->ctx = ctx;
ctx->vif = vif;
- /*
- * This variable will be correct only when there's just
- * a single context, but all code using it is for hardware
- * that supports only one context.
- */
- priv->iw_mode = vif->type;
-
- ctx->is_active = true;
-
- err = iwl_set_mode(priv, vif);
- if (err) {
- if (!ctx->always_active)
- ctx->is_active = false;
- goto out_err;
- }
-
- if (priv->cfg->bt_params &&
- priv->cfg->bt_params->advanced_bt_coexist &&
- vif->type == NL80211_IFTYPE_ADHOC) {
- /*
- * pretend to have high BT traffic as long as we
- * are operating in IBSS mode, as this will cause
- * the rate scaling etc. to behave as intended.
- */
- priv->bt_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_HIGH;
- }
- goto out;
+ err = iwl_setup_interface(priv, ctx);
+ if (!err)
+ goto out;
- out_err:
ctx->vif = NULL;
priv->iw_mode = NL80211_IFTYPE_STATION;
out:
@@ -1853,27 +1442,24 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
}
EXPORT_SYMBOL(iwl_mac_add_interface);
-void iwl_mac_remove_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif)
+static void iwl_teardown_interface(struct iwl_priv *priv,
+ struct ieee80211_vif *vif,
+ bool mode_change)
{
- struct iwl_priv *priv = hw->priv;
struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
- IWL_DEBUG_MAC80211(priv, "enter\n");
-
- mutex_lock(&priv->mutex);
-
- WARN_ON(ctx->vif != vif);
- ctx->vif = NULL;
+ lockdep_assert_held(&priv->mutex);
if (priv->scan_vif == vif) {
iwl_scan_cancel_timeout(priv, 200);
iwl_force_scan_end(priv);
}
- iwl_set_mode(priv, vif);
- if (!ctx->always_active)
- ctx->is_active = false;
+ if (!mode_change) {
+ iwl_set_mode(priv, ctx);
+ if (!ctx->always_active)
+ ctx->is_active = false;
+ }
/*
* When removing the IBSS interface, overwrite the
@@ -1883,211 +1469,31 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw,
* both values are the same and zero.
*/
if (vif->type == NL80211_IFTYPE_ADHOC)
- priv->bt_traffic_load = priv->notif_bt_traffic_load;
-
- memset(priv->bssid, 0, ETH_ALEN);
- mutex_unlock(&priv->mutex);
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
-
-}
-EXPORT_SYMBOL(iwl_mac_remove_interface);
-
-/**
- * iwl_mac_config - mac80211 config callback
- */
-int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
-{
- struct iwl_priv *priv = hw->priv;
- const struct iwl_channel_info *ch_info;
- struct ieee80211_conf *conf = &hw->conf;
- struct ieee80211_channel *channel = conf->channel;
- struct iwl_ht_config *ht_conf = &priv->current_ht_config;
- struct iwl_rxon_context *ctx;
- unsigned long flags = 0;
- int ret = 0;
- u16 ch;
- int scan_active = 0;
-
- mutex_lock(&priv->mutex);
-
- IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n",
- channel->hw_value, changed);
-
- if (unlikely(!priv->cfg->mod_params->disable_hw_scan &&
- test_bit(STATUS_SCANNING, &priv->status))) {
- scan_active = 1;
- IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
- }
-
- if (changed & (IEEE80211_CONF_CHANGE_SMPS |
- IEEE80211_CONF_CHANGE_CHANNEL)) {
- /* mac80211 uses static for non-HT which is what we want */
- priv->current_ht_config.smps = conf->smps_mode;
-
- /*
- * Recalculate chain counts.
- *
- * If monitor mode is enabled then mac80211 will
- * set up the SM PS mode to OFF if an HT channel is
- * configured.
- */
- if (priv->cfg->ops->hcmd->set_rxon_chain)
- for_each_context(priv, ctx)
- priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
- }
-
- /* during scanning mac80211 will delay channel setting until
- * scan finish with changed = 0
- */
- if (!changed || (changed & IEEE80211_CONF_CHANGE_CHANNEL)) {
- if (scan_active)
- goto set_ch_out;
-
- ch = channel->hw_value;
- ch_info = iwl_get_channel_info(priv, channel->band, ch);
- if (!is_channel_valid(ch_info)) {
- IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n");
- ret = -EINVAL;
- goto set_ch_out;
- }
-
- spin_lock_irqsave(&priv->lock, flags);
-
- for_each_context(priv, ctx) {
- /* Configure HT40 channels */
- ctx->ht.enabled = conf_is_ht(conf);
- if (ctx->ht.enabled) {
- if (conf_is_ht40_minus(conf)) {
- ctx->ht.extension_chan_offset =
- IEEE80211_HT_PARAM_CHA_SEC_BELOW;
- ctx->ht.is_40mhz = true;
- } else if (conf_is_ht40_plus(conf)) {
- ctx->ht.extension_chan_offset =
- IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
- ctx->ht.is_40mhz = true;
- } else {
- ctx->ht.extension_chan_offset =
- IEEE80211_HT_PARAM_CHA_SEC_NONE;
- ctx->ht.is_40mhz = false;
- }
- } else
- ctx->ht.is_40mhz = false;
-
- /*
- * Default to no protection. Protection mode will
- * later be set from BSS config in iwl_ht_conf
- */
- ctx->ht.protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE;
-
- /* if we are switching from ht to 2.4 clear flags
- * from any ht related info since 2.4 does not
- * support ht */
- if ((le16_to_cpu(ctx->staging.channel) != ch))
- ctx->staging.flags = 0;
-
- iwl_set_rxon_channel(priv, channel, ctx);
- iwl_set_rxon_ht(priv, ht_conf);
-
- iwl_set_flags_for_band(priv, ctx, channel->band,
- ctx->vif);
- }
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
- if (priv->cfg->ops->lib->update_bcast_stations)
- ret = priv->cfg->ops->lib->update_bcast_stations(priv);
-
- set_ch_out:
- /* The list of supported rates and rate mask can be different
- * for each band; since the band may have changed, reset
- * the rate mask to what mac80211 lists */
- iwl_set_rate(priv);
- }
-
- if (changed & (IEEE80211_CONF_CHANGE_PS |
- IEEE80211_CONF_CHANGE_IDLE)) {
- ret = iwl_power_update_mode(priv, false);
- if (ret)
- IWL_DEBUG_MAC80211(priv, "Error setting sleep level\n");
- }
-
- if (changed & IEEE80211_CONF_CHANGE_POWER) {
- IWL_DEBUG_MAC80211(priv, "TX Power old=%d new=%d\n",
- priv->tx_power_user_lmt, conf->power_level);
-
- iwl_set_tx_power(priv, conf->power_level, false);
- }
-
- if (!iwl_is_ready(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
- goto out;
- }
-
- if (scan_active)
- goto out;
-
- for_each_context(priv, ctx) {
- if (memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging)))
- iwlcore_commit_rxon(priv, ctx);
- else
- IWL_DEBUG_INFO(priv,
- "Not re-sending same RXON configuration.\n");
- }
-
-out:
- IWL_DEBUG_MAC80211(priv, "leave\n");
- mutex_unlock(&priv->mutex);
- return ret;
+ priv->bt_traffic_load = priv->last_bt_traffic_load;
}
-EXPORT_SYMBOL(iwl_mac_config);
-void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
+void iwl_mac_remove_interface(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
{
struct iwl_priv *priv = hw->priv;
- unsigned long flags;
- /* IBSS can only be the IWL_RXON_CTX_BSS context */
- struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
+ struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
- mutex_lock(&priv->mutex);
IWL_DEBUG_MAC80211(priv, "enter\n");
- spin_lock_irqsave(&priv->lock, flags);
- memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_config));
- spin_unlock_irqrestore(&priv->lock, flags);
-
- spin_lock_irqsave(&priv->lock, flags);
-
- /* new association get rid of ibss beacon skb */
- if (priv->beacon_skb)
- dev_kfree_skb(priv->beacon_skb);
-
- priv->beacon_skb = NULL;
-
- priv->timestamp = 0;
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
- iwl_scan_cancel_timeout(priv, 100);
- if (!iwl_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
- mutex_unlock(&priv->mutex);
- return;
- }
+ mutex_lock(&priv->mutex);
- /* we are restarting association process
- * clear RXON_FILTER_ASSOC_MSK bit
- */
- ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwlcore_commit_rxon(priv, ctx);
+ WARN_ON(ctx->vif != vif);
+ ctx->vif = NULL;
- iwl_set_rate(priv);
+ iwl_teardown_interface(priv, vif, false);
+ memset(priv->bssid, 0, ETH_ALEN);
mutex_unlock(&priv->mutex);
IWL_DEBUG_MAC80211(priv, "leave\n");
+
}
-EXPORT_SYMBOL(iwl_mac_reset_tsf);
+EXPORT_SYMBOL(iwl_mac_remove_interface);
int iwl_alloc_txq_mem(struct iwl_priv *priv)
{
@@ -2431,77 +1837,115 @@ int iwl_force_reset(struct iwl_priv *priv, int mode, bool external)
return 0;
}
-/**
- * iwl_bg_monitor_recover - Timer callback to check for stuck queue and recover
- *
- * During normal condition (no queue is stuck), the timer is continually set to
- * execute every monitor_recover_period milliseconds after the last timer
- * expired. When the queue read_ptr is at the same place, the timer is
- * shorten to 100mSecs. This is
- * 1) to reduce the chance that the read_ptr may wrap around (not stuck)
- * 2) to detect the stuck queues quicker before the station and AP can
- * disassociate each other.
- *
- * This function monitors all the tx queues and recover from it if any
- * of the queues are stuck.
- * 1. It first check the cmd queue for stuck conditions. If it is stuck,
- * it will recover by resetting the firmware and return.
- * 2. Then, it checks for station association. If it associates it will check
- * other queues. If any queue is stuck, it will recover by resetting
- * the firmware.
- * Note: It the number of times the queue read_ptr to be at the same place to
- * be MAX_REPEAT+1 in order to consider to be stuck.
- */
+int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ enum nl80211_iftype newtype, bool newp2p)
+{
+ struct iwl_priv *priv = hw->priv;
+ struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
+ struct iwl_rxon_context *tmp;
+ u32 interface_modes;
+ int err;
+
+ newtype = ieee80211_iftype_p2p(newtype, newp2p);
+
+ mutex_lock(&priv->mutex);
+
+ interface_modes = ctx->interface_modes | ctx->exclusive_interface_modes;
+
+ if (!(interface_modes & BIT(newtype))) {
+ err = -EBUSY;
+ goto out;
+ }
+
+ if (ctx->exclusive_interface_modes & BIT(newtype)) {
+ for_each_context(priv, tmp) {
+ if (ctx == tmp)
+ continue;
+
+ if (!tmp->vif)
+ continue;
+
+ /*
+ * The current mode switch would be exclusive, but
+ * another context is active ... refuse the switch.
+ */
+ err = -EBUSY;
+ goto out;
+ }
+ }
+
+ /* success */
+ iwl_teardown_interface(priv, vif, true);
+ vif->type = newtype;
+ err = iwl_setup_interface(priv, ctx);
+ WARN_ON(err);
+ /*
+ * We've switched internally, but submitting to the
+ * device may have failed for some reason. Mask this
+ * error, because otherwise mac80211 will not switch
+ * (and set the interface type back) and we'll be
+ * out of sync with it.
+ */
+ err = 0;
+
+ out:
+ mutex_unlock(&priv->mutex);
+ return err;
+}
+EXPORT_SYMBOL(iwl_mac_change_interface);
+
/*
- * The maximum number of times the read pointer of the tx queue at the
- * same place without considering to be stuck.
+ * On every watchdog tick we check (latest) time stamp. If it does not
+ * change during timeout period and queue is not empty we reset firmware.
*/
-#define MAX_REPEAT (2)
static int iwl_check_stuck_queue(struct iwl_priv *priv, int cnt)
{
- struct iwl_tx_queue *txq;
- struct iwl_queue *q;
+ struct iwl_tx_queue *txq = &priv->txq[cnt];
+ struct iwl_queue *q = &txq->q;
+ unsigned long timeout;
+ int ret;
- txq = &priv->txq[cnt];
- q = &txq->q;
- /* queue is empty, skip */
- if (q->read_ptr == q->write_ptr)
+ if (q->read_ptr == q->write_ptr) {
+ txq->time_stamp = jiffies;
return 0;
+ }
- if (q->read_ptr == q->last_read_ptr) {
- /* a queue has not been read from last time */
- if (q->repeat_same_read_ptr > MAX_REPEAT) {
- IWL_ERR(priv,
- "queue %d stuck %d time. Fw reload.\n",
- q->id, q->repeat_same_read_ptr);
- q->repeat_same_read_ptr = 0;
- iwl_force_reset(priv, IWL_FW_RESET, false);
- } else {
- q->repeat_same_read_ptr++;
- IWL_DEBUG_RADIO(priv,
- "queue %d, not read %d time\n",
- q->id,
- q->repeat_same_read_ptr);
- mod_timer(&priv->monitor_recover,
- jiffies + msecs_to_jiffies(
- IWL_ONE_HUNDRED_MSECS));
- return 1;
- }
- } else {
- q->last_read_ptr = q->read_ptr;
- q->repeat_same_read_ptr = 0;
+ timeout = txq->time_stamp +
+ msecs_to_jiffies(priv->cfg->base_params->wd_timeout);
+
+ if (time_after(jiffies, timeout)) {
+ IWL_ERR(priv, "Queue %d stuck for %u ms.\n",
+ q->id, priv->cfg->base_params->wd_timeout);
+ ret = iwl_force_reset(priv, IWL_FW_RESET, false);
+ return (ret == -EAGAIN) ? 0 : 1;
}
+
return 0;
}
-void iwl_bg_monitor_recover(unsigned long data)
+/*
+ * Making watchdog tick be a quarter of timeout assure we will
+ * discover the queue hung between timeout and 1.25*timeout
+ */
+#define IWL_WD_TICK(timeout) ((timeout) / 4)
+
+/*
+ * Watchdog timer callback, we check each tx queue for stuck, if if hung
+ * we reset the firmware. If everything is fine just rearm the timer.
+ */
+void iwl_bg_watchdog(unsigned long data)
{
struct iwl_priv *priv = (struct iwl_priv *)data;
int cnt;
+ unsigned long timeout;
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
+ timeout = priv->cfg->base_params->wd_timeout;
+ if (timeout == 0)
+ return;
+
/* monitor and check for stuck cmd queue */
if (iwl_check_stuck_queue(priv, priv->cmd_queue))
return;
@@ -2516,17 +1960,23 @@ void iwl_bg_monitor_recover(unsigned long data)
return;
}
}
- if (priv->cfg->base_params->monitor_recover_period) {
- /*
- * Reschedule the timer to occur in
- * priv->cfg->base_params->monitor_recover_period
- */
- mod_timer(&priv->monitor_recover, jiffies + msecs_to_jiffies(
- priv->cfg->base_params->monitor_recover_period));
- }
+
+ mod_timer(&priv->watchdog, jiffies +
+ msecs_to_jiffies(IWL_WD_TICK(timeout)));
}
-EXPORT_SYMBOL(iwl_bg_monitor_recover);
+EXPORT_SYMBOL(iwl_bg_watchdog);
+void iwl_setup_watchdog(struct iwl_priv *priv)
+{
+ unsigned int timeout = priv->cfg->base_params->wd_timeout;
+
+ if (timeout)
+ mod_timer(&priv->watchdog,
+ jiffies + msecs_to_jiffies(IWL_WD_TICK(timeout)));
+ else
+ del_timer(&priv->watchdog);
+}
+EXPORT_SYMBOL(iwl_setup_watchdog);
/*
* extended beacon time format
@@ -2584,8 +2034,9 @@ EXPORT_SYMBOL(iwl_add_beacon_time);
#ifdef CONFIG_PM
-int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+int iwl_pci_suspend(struct device *device)
{
+ struct pci_dev *pdev = to_pci_dev(device);
struct iwl_priv *priv = pci_get_drvdata(pdev);
/*
@@ -2597,18 +2048,14 @@ int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
*/
iwl_apm_stop(priv);
- pci_save_state(pdev);
- pci_disable_device(pdev);
- pci_set_power_state(pdev, PCI_D3hot);
-
return 0;
}
EXPORT_SYMBOL(iwl_pci_suspend);
-int iwl_pci_resume(struct pci_dev *pdev)
+int iwl_pci_resume(struct device *device)
{
+ struct pci_dev *pdev = to_pci_dev(device);
struct iwl_priv *priv = pci_get_drvdata(pdev);
- int ret;
bool hw_rfkill = false;
/*
@@ -2617,11 +2064,6 @@ int iwl_pci_resume(struct pci_dev *pdev)
*/
pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00);
- pci_set_power_state(pdev, PCI_D0);
- ret = pci_enable_device(pdev);
- if (ret)
- return ret;
- pci_restore_state(pdev);
iwl_enable_interrupts(priv);
if (!(iwl_read32(priv, CSR_GP_CNTRL) &
@@ -2639,4 +2081,14 @@ int iwl_pci_resume(struct pci_dev *pdev)
}
EXPORT_SYMBOL(iwl_pci_resume);
+const struct dev_pm_ops iwl_pm_ops = {
+ .suspend = iwl_pci_suspend,
+ .resume = iwl_pci_resume,
+ .freeze = iwl_pci_suspend,
+ .thaw = iwl_pci_resume,
+ .poweroff = iwl_pci_suspend,
+ .restore = iwl_pci_resume,
+};
+EXPORT_SYMBOL(iwl_pm_ops);
+
#endif /* CONFIG_PM */
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 64527def059f..568920ac982d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -120,6 +120,14 @@ struct iwl_apm_ops {
void (*config)(struct iwl_priv *priv);
};
+struct iwl_isr_ops {
+ irqreturn_t (*isr) (int irq, void *data);
+ void (*free)(struct iwl_priv *priv);
+ int (*alloc)(struct iwl_priv *priv);
+ int (*reset)(struct iwl_priv *priv);
+ void (*disable)(struct iwl_priv *priv);
+};
+
struct iwl_debugfs_ops {
ssize_t (*rx_stats_read)(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos);
@@ -193,22 +201,15 @@ struct iwl_lib_ops {
/* power */
int (*send_tx_power) (struct iwl_priv *priv);
void (*update_chain_flags)(struct iwl_priv *priv);
- void (*post_associate)(struct iwl_priv *priv,
- struct ieee80211_vif *vif);
- void (*config_ap)(struct iwl_priv *priv, struct ieee80211_vif *vif);
- irqreturn_t (*isr) (int irq, void *data);
+
+ /* isr */
+ struct iwl_isr_ops isr_ops;
/* eeprom operations (as defined in iwl-eeprom.h) */
struct iwl_eeprom_ops eeprom_ops;
/* temperature */
struct iwl_temp_ops temp_ops;
- /* station management */
- int (*manage_ibss_station)(struct iwl_priv *priv,
- struct ieee80211_vif *vif, bool add);
- int (*update_bcast_stations)(struct iwl_priv *priv);
- /* recover from tx queue stall */
- void (*recover_from_tx_stall)(unsigned long data);
/* check for plcp health */
bool (*check_plcp_health)(struct iwl_priv *priv,
struct iwl_rx_packet *pkt);
@@ -235,12 +236,23 @@ struct iwl_nic_ops {
void (*additional_nic_config)(struct iwl_priv *priv);
};
+struct iwl_legacy_ops {
+ void (*post_associate)(struct iwl_priv *priv);
+ void (*config_ap)(struct iwl_priv *priv);
+ /* station management */
+ int (*update_bcast_stations)(struct iwl_priv *priv);
+ int (*manage_ibss_station)(struct iwl_priv *priv,
+ struct ieee80211_vif *vif, bool add);
+};
+
struct iwl_ops {
const struct iwl_lib_ops *lib;
const struct iwl_hcmd_ops *hcmd;
const struct iwl_hcmd_utils_ops *utils;
const struct iwl_led_ops *led;
const struct iwl_nic_ops *nic;
+ const struct iwl_legacy_ops *legacy;
+ const struct ieee80211_ops *ieee80211_ops;
};
struct iwl_mod_params {
@@ -266,7 +278,7 @@ struct iwl_mod_params {
* @plcp_delta_threshold: plcp error rate threshold used to trigger
* radio tuning when there is a high receiving plcp error rate
* @chain_noise_scale: default chain noise scale used for gain computation
- * @monitor_recover_period: default timer used to check stuck queues
+ * @wd_timeout: TX queues watchdog timeout
* @temperature_kelvin: temperature report by uCode in kelvin
* @max_event_log_size: size of event log buffer size for ucode event logging
* @tx_power_by_driver: tx power calibration performed by driver
@@ -276,7 +288,10 @@ struct iwl_mod_params {
* sensitivity calibration operation
* @chain_noise_calib_by_driver: driver has the capability to perform
* chain noise calibration operation
-*/
+ * @shadow_reg_enable: HW shadhow register bit
+ * @no_agg_framecnt_info: uCode do not provide aggregation frame count
+ * information
+ */
struct iwl_base_params {
int eeprom_size;
int num_of_queues; /* def: HW dependent */
@@ -298,14 +313,15 @@ struct iwl_base_params {
const bool support_wimax_coexist;
u8 plcp_delta_threshold;
s32 chain_noise_scale;
- /* timer period for monitor the driver queues */
- u32 monitor_recover_period;
+ unsigned int wd_timeout;
bool temperature_kelvin;
u32 max_event_log_size;
const bool tx_power_by_driver;
const bool ucode_tracing;
const bool sensitivity_calib_by_driver;
const bool chain_noise_calib_by_driver;
+ const bool shadow_reg_enable;
+ const bool no_agg_framecnt_info;
};
/*
* @advanced_bt_coexist: support advanced bt coexist
@@ -315,6 +331,7 @@ struct iwl_base_params {
* @agg_time_limit: maximum number of uSec in aggregation
* @ampdu_factor: Maximum A-MPDU length factor
* @ampdu_density: Minimum A-MPDU spacing
+ * @bt_sco_disable: uCode should not response to BT in SCO/ESCO mode
*/
struct iwl_bt_params {
bool advanced_bt_coexist;
@@ -324,6 +341,7 @@ struct iwl_bt_params {
u16 agg_time_limit;
u8 ampdu_factor;
u8 ampdu_density;
+ bool bt_sco_disable;
};
/*
* @use_rts_for_aggregation: use rts/cts protection for HT traffic
@@ -344,6 +362,8 @@ struct iwl_ht_params {
* @need_dc_calib: need to perform init dc calibration
* @need_temp_offset_calib: need to perform temperature offset calibration
* @scan_antennas: available antenna for scan operation
+ * @led_mode: 0=blinking, 1=On(RF On)/Off(RF Off)
+ * @adv_pm: advance power management
*
* We enable the driver to be backward compatible wrt API version. The
* driver specifies which APIs it supports (with @ucode_api_max being the
@@ -390,14 +410,15 @@ struct iwl_cfg {
const bool need_temp_offset_calib; /* if used set to true */
u8 scan_rx_antennas[IEEE80211_NUM_BANDS];
u8 scan_tx_antennas[IEEE80211_NUM_BANDS];
+ enum iwl_led_mode led_mode;
+ const bool adv_pm;
};
/***************************
* L i b *
***************************/
-struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg,
- struct ieee80211_ops *hw_ops);
+struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg);
int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params);
int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw);
@@ -425,23 +446,16 @@ int iwl_set_decrypted_flag(struct iwl_priv *priv,
u32 decrypt_res,
struct ieee80211_rx_status *stats);
void iwl_irq_handle_error(struct iwl_priv *priv);
-void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif);
-void iwl_bss_info_changed(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_bss_conf *bss_conf,
- u32 changes);
int iwl_mac_add_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif);
void iwl_mac_remove_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif);
-int iwl_mac_config(struct ieee80211_hw *hw, u32 changed);
-void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif);
-void iwl_mac_reset_tsf(struct ieee80211_hw *hw);
+int iwl_mac_change_interface(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ enum nl80211_iftype newtype, bool newp2p);
int iwl_alloc_txq_mem(struct iwl_priv *priv);
void iwl_free_txq_mem(struct iwl_priv *priv);
-void iwlcore_tx_cmd_protection(struct iwl_priv *priv,
- struct ieee80211_tx_info *info,
- __le16 fc, __le32 *tx_flags);
+
#ifdef CONFIG_IWLWIFI_DEBUGFS
int iwl_alloc_traffic_mem(struct iwl_priv *priv);
void iwl_free_traffic_mem(struct iwl_priv *priv);
@@ -529,6 +543,7 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq,
int slots_num, u32 txq_id);
void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id);
+void iwl_setup_watchdog(struct iwl_priv *priv);
/*****************************************************
* TX power
****************************************************/
@@ -598,7 +613,6 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd);
/*****************************************************
* PCI *
*****************************************************/
-irqreturn_t iwl_isr_legacy(int irq, void *data);
static inline u16 iwl_pcie_link_ctl(struct iwl_priv *priv)
{
@@ -609,15 +623,23 @@ static inline u16 iwl_pcie_link_ctl(struct iwl_priv *priv)
return pci_lnk_ctl;
}
-void iwl_bg_monitor_recover(unsigned long data);
+void iwl_bg_watchdog(unsigned long data);
u32 iwl_usecs_to_beacons(struct iwl_priv *priv, u32 usec, u32 beacon_interval);
__le32 iwl_add_beacon_time(struct iwl_priv *priv, u32 base,
u32 addon, u32 beacon_interval);
#ifdef CONFIG_PM
-int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state);
-int iwl_pci_resume(struct pci_dev *pdev);
-#endif /* CONFIG_PM */
+int iwl_pci_suspend(struct device *device);
+int iwl_pci_resume(struct device *device);
+extern const struct dev_pm_ops iwl_pm_ops;
+
+#define IWL_PM_OPS (&iwl_pm_ops)
+
+#else /* !CONFIG_PM */
+
+#define IWL_PM_OPS NULL
+
+#endif /* !CONFIG_PM */
/*****************************************************
* Error Handling Debugging
@@ -724,11 +746,6 @@ static inline int iwlcore_commit_rxon(struct iwl_priv *priv,
{
return priv->cfg->ops->hcmd->commit_rxon(priv, ctx);
}
-static inline void iwlcore_config_ap(struct iwl_priv *priv,
- struct ieee80211_vif *vif)
-{
- priv->cfg->ops->lib->config_ap(priv, vif);
-}
static inline const struct ieee80211_supported_band *iwl_get_hw_mode(
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 2aa15ab13892..b80bf7dff55b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -132,6 +132,8 @@
#define CSR_LED_REG (CSR_BASE+0x094)
#define CSR_DRAM_INT_TBL_REG (CSR_BASE+0x0A0)
+#define CSR_MAC_SHADOW_REG_CTRL (CSR_BASE+0x0A8) /* 6000 and up */
+
/* GIO Chicken Bits (PCI Express bus link power management) */
#define CSR_GIO_CHICKEN_BITS (CSR_BASE+0x100)
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 8fdd4efdb1d3..d36836376e6b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -992,11 +992,8 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file,
" swq_id=%#.2x (ac %d/hwq %d)\n",
cnt, q->read_ptr, q->write_ptr,
!!test_bit(cnt, priv->queue_stopped),
- txq->swq_id,
- txq->swq_id & 0x80 ? txq->swq_id & 3 :
- txq->swq_id,
- txq->swq_id & 0x80 ? (txq->swq_id >> 2) &
- 0x1f : txq->swq_id);
+ txq->swq_id, txq->swq_id & 3,
+ (txq->swq_id >> 2) & 0x1f);
if (cnt >= 4)
continue;
/* for the ACs, display the stop count too */
@@ -1537,32 +1534,26 @@ static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file,
user_buf, count, ppos);
}
-static ssize_t iwl_dbgfs_monitor_period_write(struct file *file,
+static ssize_t iwl_dbgfs_wd_timeout_write(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos) {
struct iwl_priv *priv = file->private_data;
char buf[8];
int buf_size;
- int period;
+ int timeout;
memset(buf, 0, sizeof(buf));
buf_size = min(count, sizeof(buf) - 1);
if (copy_from_user(buf, user_buf, buf_size))
return -EFAULT;
- if (sscanf(buf, "%d", &period) != 1)
+ if (sscanf(buf, "%d", &timeout) != 1)
return -EINVAL;
- if (period < 0 || period > IWL_MAX_MONITORING_PERIOD)
- priv->cfg->base_params->monitor_recover_period =
- IWL_DEF_MONITORING_PERIOD;
- else
- priv->cfg->base_params->monitor_recover_period = period;
+ if (timeout < 0 || timeout > IWL_MAX_WD_TIMEOUT)
+ timeout = IWL_DEF_WD_TIMEOUT;
- if (priv->cfg->base_params->monitor_recover_period)
- mod_timer(&priv->monitor_recover, jiffies + msecs_to_jiffies(
- priv->cfg->base_params->monitor_recover_period));
- else
- del_timer_sync(&priv->monitor_recover);
+ priv->cfg->base_params->wd_timeout = timeout;
+ iwl_setup_watchdog(priv);
return count;
}
@@ -1580,7 +1571,7 @@ static ssize_t iwl_dbgfs_bt_traffic_read(struct file *file,
priv->bt_full_concurrent ? "full concurrency" : "3-wire");
pos += scnprintf(buf + pos, bufsz - pos, "BT status: %s, "
"last traffic notif: %d\n",
- priv->bt_status ? "On" : "Off", priv->notif_bt_traffic_load);
+ priv->bt_status ? "On" : "Off", priv->last_bt_traffic_load);
pos += scnprintf(buf + pos, bufsz - pos, "ch_announcement: %d, "
"sco_active: %d, kill_ack_mask: %x, "
"kill_cts_mask: %x\n",
@@ -1689,7 +1680,7 @@ DEBUGFS_READ_FILE_OPS(rxon_flags);
DEBUGFS_READ_FILE_OPS(rxon_filter_flags);
DEBUGFS_WRITE_FILE_OPS(txfifo_flush);
DEBUGFS_READ_FILE_OPS(ucode_bt_stats);
-DEBUGFS_WRITE_FILE_OPS(monitor_period);
+DEBUGFS_WRITE_FILE_OPS(wd_timeout);
DEBUGFS_READ_FILE_OPS(bt_traffic);
DEBUGFS_READ_WRITE_FILE_OPS(protection_mode);
DEBUGFS_READ_FILE_OPS(reply_tx_error);
@@ -1766,7 +1757,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
DEBUGFS_ADD_FILE(reply_tx_error, dir_debug, S_IRUSR);
DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR);
DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR);
- DEBUGFS_ADD_FILE(monitor_period, dir_debug, S_IWUSR);
+ DEBUGFS_ADD_FILE(wd_timeout, dir_debug, S_IWUSR);
if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist)
DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR);
if (priv->cfg->base_params->sensitivity_calib_by_driver)
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 70e07fa48405..836f1816b110 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -129,9 +129,6 @@ struct iwl_queue {
int write_ptr; /* 1-st empty entry (index) host_w*/
int read_ptr; /* last used entry (index) host_r*/
/* use for monitoring and recovering the stuck queue */
- int last_read_ptr; /* storing the last read_ptr */
- /* number of time read_ptr and last_read_ptr are the same */
- u8 repeat_same_read_ptr;
dma_addr_t dma_addr; /* physical addr for BD's */
int n_window; /* safe queue window */
u32 id;
@@ -155,6 +152,7 @@ struct iwl_tx_info {
* @meta: array of meta data for each command/tx buffer
* @dma_addr_cmd: physical address of cmd/tx buffer array
* @txb: array of per-TFD driver data
+ * @time_stamp: time (in jiffies) of last read_ptr change
* @need_update: indicates need to update read/write index
* @sched_retry: indicates queue is high-throughput aggregation (HT AGG) enabled
*
@@ -170,6 +168,7 @@ struct iwl_tx_queue {
struct iwl_device_cmd **cmd;
struct iwl_cmd_meta *meta;
struct iwl_tx_info *txb;
+ unsigned long time_stamp;
u8 need_update;
u8 sched_retry;
u8 active;
@@ -1104,11 +1103,10 @@ struct iwl_event_log {
#define IWL_DELAY_NEXT_FORCE_RF_RESET (HZ*3)
#define IWL_DELAY_NEXT_FORCE_FW_RELOAD (HZ*5)
-/* timer constants use to monitor and recover stuck tx queues in mSecs */
-#define IWL_DEF_MONITORING_PERIOD (1000)
-#define IWL_LONG_MONITORING_PERIOD (5000)
-#define IWL_ONE_HUNDRED_MSECS (100)
-#define IWL_MAX_MONITORING_PERIOD (60000)
+/* TX queue watchdog timeouts in mSecs */
+#define IWL_DEF_WD_TIMEOUT (2000)
+#define IWL_LONG_WD_TIMEOUT (10000)
+#define IWL_MAX_WD_TIMEOUT (120000)
/* BT Antenna Coupling Threshold (dB) */
#define IWL_BT_ANTENNA_COUPLING_THRESHOLD (35)
@@ -1162,6 +1160,8 @@ struct iwl_rxon_context {
*/
bool always_active, is_active;
+ bool ht_need_multiple_chains;
+
enum iwl_rxon_context_id ctxid;
u32 interface_modes, exclusive_interface_modes;
@@ -1469,7 +1469,7 @@ struct iwl_priv {
/* bt coex */
u8 bt_status;
- u8 bt_traffic_load, notif_bt_traffic_load;
+ u8 bt_traffic_load, last_bt_traffic_load;
bool bt_ch_announce;
bool bt_sco_active;
bool bt_full_concurrent;
@@ -1480,7 +1480,6 @@ struct iwl_priv {
u16 bt_on_thresh;
u16 bt_duration;
u16 dynamic_frag_thresh;
- u16 dynamic_agg_thresh;
u8 bt_ci_compliance;
struct work_struct bt_traffic_change_work;
@@ -1517,6 +1516,7 @@ struct iwl_priv {
s8 tx_power_user_lmt;
s8 tx_power_device_lmt;
s8 tx_power_lmt_in_half_dbm; /* max tx power in half-dBm format */
+ s8 tx_power_next;
#ifdef CONFIG_IWLWIFI_DEBUG
@@ -1542,7 +1542,7 @@ struct iwl_priv {
struct work_struct run_time_calib_work;
struct timer_list statistics_periodic;
struct timer_list ucode_trace;
- struct timer_list monitor_recover;
+ struct timer_list watchdog;
bool hw_ready;
struct iwl_event_log event_log;
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
index d9b590625ae4..583916db46e4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
@@ -110,9 +110,18 @@ enum {
};
/* SKU Capabilities */
+/* 3945 only */
#define EEPROM_SKU_CAP_SW_RF_KILL_ENABLE (1 << 0)
#define EEPROM_SKU_CAP_HW_RF_KILL_ENABLE (1 << 1)
+/* 5000 and up */
+#define EEPROM_SKU_CAP_BAND_POS (4)
+#define EEPROM_SKU_CAP_BAND_SELECTION \
+ (3 << EEPROM_SKU_CAP_BAND_POS)
+#define EEPROM_SKU_CAP_11N_ENABLE (1 << 6)
+#define EEPROM_SKU_CAP_AMT_ENABLE (1 << 7)
+#define EEPROM_SKU_CAP_IPAN_ENABLE (1 << 8)
+
/* *regulatory* channel data format in eeprom, one for each channel.
* There are separate entries for HT40 (40 MHz) vs. normal (20 MHz) channels. */
struct iwl_eeprom_channel {
@@ -397,11 +406,10 @@ struct iwl_eeprom_calib_info {
#define EEPROM_BOARD_REVISION (2*0x35) /* 2 bytes */
#define EEPROM_BOARD_PBA_NUMBER (2*0x3B+1) /* 9 bytes */
#define EEPROM_VERSION (2*0x44) /* 2 bytes */
-#define EEPROM_SKU_CAP (2*0x45) /* 1 bytes */
+#define EEPROM_SKU_CAP (2*0x45) /* 2 bytes */
#define EEPROM_OEM_MODE (2*0x46) /* 2 bytes */
#define EEPROM_WOWLAN_MODE (2*0x47) /* 2 bytes */
#define EEPROM_RADIO_CONFIG (2*0x48) /* 2 bytes */
-#define EEPROM_3945_M_VERSION (2*0x4A) /* 1 bytes */
#define EEPROM_NUM_MAC_ADDRESS (2*0x4C) /* 2 bytes */
/* The following masks are to be applied on EEPROM_RADIO_CONFIG */
@@ -504,6 +512,7 @@ struct iwl_eeprom_ops {
int iwl_eeprom_init(struct iwl_priv *priv);
void iwl_eeprom_free(struct iwl_priv *priv);
int iwl_eeprom_check_version(struct iwl_priv *priv);
+int iwl_eeprom_check_sku(struct iwl_priv *priv);
const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset);
int iwlcore_eeprom_verify_signature(struct iwl_priv *priv);
u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset);
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h
index 1aaef70deaec..3f5bedd8875f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-helpers.h
+++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h
@@ -44,15 +44,6 @@ static inline struct ieee80211_conf *ieee80211_get_hw_conf(
return &hw->conf;
}
-static inline unsigned long elapsed_jiffies(unsigned long start,
- unsigned long end)
-{
- if (end >= start)
- return end - start;
-
- return end + (MAX_JIFFY_OFFSET - start) + 1;
-}
-
/**
* iwl_queue_inc_wrap - increment queue index, wrap back to beginning
* @index -- current index
@@ -104,42 +95,36 @@ static inline int iwl_alloc_fw_desc(struct pci_dev *pci_dev,
* | | | | | | | |
* | | | | | | +-+-------- AC queue (0-3)
* | | | | | |
- * | +-+-+-+-+------------ HW A-MPDU queue
+ * | +-+-+-+-+------------ HW queue ID
* |
- * +---------------------- indicates agg queue
+ * +---------------------- unused
*/
-static inline u8 iwl_virtual_agg_queue_num(u8 ac, u8 hwq)
+static inline void iwl_set_swq_id(struct iwl_tx_queue *txq, u8 ac, u8 hwq)
{
BUG_ON(ac > 3); /* only have 2 bits */
- BUG_ON(hwq > 31); /* only have 5 bits */
+ BUG_ON(hwq > 31); /* only use 5 bits */
- return 0x80 | (hwq << 2) | ac;
+ txq->swq_id = (hwq << 2) | ac;
}
-static inline void iwl_wake_queue(struct iwl_priv *priv, u8 queue)
+static inline void iwl_wake_queue(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq)
{
- u8 ac = queue;
- u8 hwq = queue;
-
- if (queue & 0x80) {
- ac = queue & 3;
- hwq = (queue >> 2) & 0x1f;
- }
+ u8 queue = txq->swq_id;
+ u8 ac = queue & 3;
+ u8 hwq = (queue >> 2) & 0x1f;
if (test_and_clear_bit(hwq, priv->queue_stopped))
if (atomic_dec_return(&priv->queue_stop_count[ac]) <= 0)
ieee80211_wake_queue(priv->hw, ac);
}
-static inline void iwl_stop_queue(struct iwl_priv *priv, u8 queue)
+static inline void iwl_stop_queue(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq)
{
- u8 ac = queue;
- u8 hwq = queue;
-
- if (queue & 0x80) {
- ac = queue & 3;
- hwq = (queue >> 2) & 0x1f;
- }
+ u8 queue = txq->swq_id;
+ u8 ac = queue & 3;
+ u8 hwq = (queue >> 2) & 0x1f;
if (!test_and_set_bit(hwq, priv->queue_stopped))
if (atomic_inc_return(&priv->queue_stop_count[ac]) > 0)
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c
index 86c2b6fed0c6..516e5577ed2a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-led.c
@@ -45,9 +45,8 @@
/* default: IWL_LED_BLINK(0) using blinking index table */
static int led_mode;
module_param(led_mode, int, S_IRUGO);
-MODULE_PARM_DESC(led_mode, "led mode: 0=blinking, 1=On(RF On)/Off(RF Off), "
- "(default 0)");
-
+MODULE_PARM_DESC(led_mode, "led mode: 0=system default, "
+ "1=On(RF On)/Off(RF Off), 2=blinking");
static const struct {
u16 tpt; /* Mb/s */
@@ -128,12 +127,13 @@ EXPORT_SYMBOL(iwl_led_start);
int iwl_led_associate(struct iwl_priv *priv)
{
IWL_DEBUG_LED(priv, "Associated\n");
- if (led_mode == IWL_LED_BLINK)
+ if (priv->cfg->led_mode == IWL_LED_BLINK)
priv->allow_blinking = 1;
priv->last_blink_time = jiffies;
return 0;
}
+EXPORT_SYMBOL(iwl_led_associate);
int iwl_led_disassociate(struct iwl_priv *priv)
{
@@ -141,6 +141,7 @@ int iwl_led_disassociate(struct iwl_priv *priv)
return 0;
}
+EXPORT_SYMBOL(iwl_led_disassociate);
/*
* calculate blink rate according to last second Tx/Rx activities
@@ -221,5 +222,8 @@ void iwl_leds_init(struct iwl_priv *priv)
priv->last_blink_rate = 0;
priv->last_blink_time = 0;
priv->allow_blinking = 0;
+ if (led_mode != IWL_LED_DEFAULT &&
+ led_mode != priv->cfg->led_mode)
+ priv->cfg->led_mode = led_mode;
}
EXPORT_SYMBOL(iwl_leds_init);
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.h b/drivers/net/wireless/iwlwifi/iwl-led.h
index 49a70baa3fb6..9079b33486ef 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.h
+++ b/drivers/net/wireless/iwlwifi/iwl-led.h
@@ -47,14 +47,16 @@ enum led_type {
/*
* LED mode
- * IWL_LED_BLINK: adjust led blink rate based on blink table
+ * IWL_LED_DEFAULT: use system default
* IWL_LED_RF_STATE: turn LED on/off based on RF state
* LED ON = RF ON
* LED OFF = RF OFF
+ * IWL_LED_BLINK: adjust led blink rate based on blink table
*/
enum iwl_led_mode {
- IWL_LED_BLINK,
+ IWL_LED_DEFAULT,
IWL_LED_RF_STATE,
+ IWL_LED_BLINK,
};
void iwl_leds_init(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-legacy.c b/drivers/net/wireless/iwlwifi/iwl-legacy.c
new file mode 100644
index 000000000000..a08b4e56e6b1
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-legacy.c
@@ -0,0 +1,662 @@
+/******************************************************************************
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ * Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *****************************************************************************/
+
+#include <linux/kernel.h>
+#include <net/mac80211.h>
+
+#include "iwl-dev.h"
+#include "iwl-core.h"
+#include "iwl-helpers.h"
+#include "iwl-legacy.h"
+
+static void iwl_update_qos(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
+{
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return;
+
+ if (!ctx->is_active)
+ return;
+
+ ctx->qos_data.def_qos_parm.qos_flags = 0;
+
+ if (ctx->qos_data.qos_active)
+ ctx->qos_data.def_qos_parm.qos_flags |=
+ QOS_PARAM_FLG_UPDATE_EDCA_MSK;
+
+ if (ctx->ht.enabled)
+ ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
+
+ IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n",
+ ctx->qos_data.qos_active,
+ ctx->qos_data.def_qos_parm.qos_flags);
+
+ iwl_send_cmd_pdu_async(priv, ctx->qos_cmd,
+ sizeof(struct iwl_qosparam_cmd),
+ &ctx->qos_data.def_qos_parm, NULL);
+}
+
+/**
+ * iwl_legacy_mac_config - mac80211 config callback
+ */
+int iwl_legacy_mac_config(struct ieee80211_hw *hw, u32 changed)
+{
+ struct iwl_priv *priv = hw->priv;
+ const struct iwl_channel_info *ch_info;
+ struct ieee80211_conf *conf = &hw->conf;
+ struct ieee80211_channel *channel = conf->channel;
+ struct iwl_ht_config *ht_conf = &priv->current_ht_config;
+ struct iwl_rxon_context *ctx;
+ unsigned long flags = 0;
+ int ret = 0;
+ u16 ch;
+ int scan_active = 0;
+ bool ht_changed[NUM_IWL_RXON_CTX] = {};
+
+ if (WARN_ON(!priv->cfg->ops->legacy))
+ return -EOPNOTSUPP;
+
+ mutex_lock(&priv->mutex);
+
+ IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n",
+ channel->hw_value, changed);
+
+ if (unlikely(!priv->cfg->mod_params->disable_hw_scan &&
+ test_bit(STATUS_SCANNING, &priv->status))) {
+ scan_active = 1;
+ IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
+ }
+
+ if (changed & (IEEE80211_CONF_CHANGE_SMPS |
+ IEEE80211_CONF_CHANGE_CHANNEL)) {
+ /* mac80211 uses static for non-HT which is what we want */
+ priv->current_ht_config.smps = conf->smps_mode;
+
+ /*
+ * Recalculate chain counts.
+ *
+ * If monitor mode is enabled then mac80211 will
+ * set up the SM PS mode to OFF if an HT channel is
+ * configured.
+ */
+ if (priv->cfg->ops->hcmd->set_rxon_chain)
+ for_each_context(priv, ctx)
+ priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
+ }
+
+ /* during scanning mac80211 will delay channel setting until
+ * scan finish with changed = 0
+ */
+ if (!changed || (changed & IEEE80211_CONF_CHANGE_CHANNEL)) {
+ if (scan_active)
+ goto set_ch_out;
+
+ ch = channel->hw_value;
+ ch_info = iwl_get_channel_info(priv, channel->band, ch);
+ if (!is_channel_valid(ch_info)) {
+ IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n");
+ ret = -EINVAL;
+ goto set_ch_out;
+ }
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ for_each_context(priv, ctx) {
+ /* Configure HT40 channels */
+ if (ctx->ht.enabled != conf_is_ht(conf)) {
+ ctx->ht.enabled = conf_is_ht(conf);
+ ht_changed[ctx->ctxid] = true;
+ }
+ if (ctx->ht.enabled) {
+ if (conf_is_ht40_minus(conf)) {
+ ctx->ht.extension_chan_offset =
+ IEEE80211_HT_PARAM_CHA_SEC_BELOW;
+ ctx->ht.is_40mhz = true;
+ } else if (conf_is_ht40_plus(conf)) {
+ ctx->ht.extension_chan_offset =
+ IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
+ ctx->ht.is_40mhz = true;
+ } else {
+ ctx->ht.extension_chan_offset =
+ IEEE80211_HT_PARAM_CHA_SEC_NONE;
+ ctx->ht.is_40mhz = false;
+ }
+ } else
+ ctx->ht.is_40mhz = false;
+
+ /*
+ * Default to no protection. Protection mode will
+ * later be set from BSS config in iwl_ht_conf
+ */
+ ctx->ht.protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE;
+
+ /* if we are switching from ht to 2.4 clear flags
+ * from any ht related info since 2.4 does not
+ * support ht */
+ if ((le16_to_cpu(ctx->staging.channel) != ch))
+ ctx->staging.flags = 0;
+
+ iwl_set_rxon_channel(priv, channel, ctx);
+ iwl_set_rxon_ht(priv, ht_conf);
+
+ iwl_set_flags_for_band(priv, ctx, channel->band,
+ ctx->vif);
+ }
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ if (priv->cfg->ops->legacy->update_bcast_stations)
+ ret = priv->cfg->ops->legacy->update_bcast_stations(priv);
+
+ set_ch_out:
+ /* The list of supported rates and rate mask can be different
+ * for each band; since the band may have changed, reset
+ * the rate mask to what mac80211 lists */
+ iwl_set_rate(priv);
+ }
+
+ if (changed & (IEEE80211_CONF_CHANGE_PS |
+ IEEE80211_CONF_CHANGE_IDLE)) {
+ ret = iwl_power_update_mode(priv, false);
+ if (ret)
+ IWL_DEBUG_MAC80211(priv, "Error setting sleep level\n");
+ }
+
+ if (changed & IEEE80211_CONF_CHANGE_POWER) {
+ IWL_DEBUG_MAC80211(priv, "TX Power old=%d new=%d\n",
+ priv->tx_power_user_lmt, conf->power_level);
+
+ iwl_set_tx_power(priv, conf->power_level, false);
+ }
+
+ if (!iwl_is_ready(priv)) {
+ IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
+ goto out;
+ }
+
+ if (scan_active)
+ goto out;
+
+ for_each_context(priv, ctx) {
+ if (memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging)))
+ iwlcore_commit_rxon(priv, ctx);
+ else
+ IWL_DEBUG_INFO(priv,
+ "Not re-sending same RXON configuration.\n");
+ if (ht_changed[ctx->ctxid])
+ iwl_update_qos(priv, ctx);
+ }
+
+out:
+ IWL_DEBUG_MAC80211(priv, "leave\n");
+ mutex_unlock(&priv->mutex);
+ return ret;
+}
+EXPORT_SYMBOL(iwl_legacy_mac_config);
+
+void iwl_legacy_mac_reset_tsf(struct ieee80211_hw *hw)
+{
+ struct iwl_priv *priv = hw->priv;
+ unsigned long flags;
+ /* IBSS can only be the IWL_RXON_CTX_BSS context */
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
+
+ if (WARN_ON(!priv->cfg->ops->legacy))
+ return;
+
+ mutex_lock(&priv->mutex);
+ IWL_DEBUG_MAC80211(priv, "enter\n");
+
+ spin_lock_irqsave(&priv->lock, flags);
+ memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_config));
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ /* new association get rid of ibss beacon skb */
+ if (priv->beacon_skb)
+ dev_kfree_skb(priv->beacon_skb);
+
+ priv->beacon_skb = NULL;
+
+ priv->timestamp = 0;
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ iwl_scan_cancel_timeout(priv, 100);
+ if (!iwl_is_ready_rf(priv)) {
+ IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
+ mutex_unlock(&priv->mutex);
+ return;
+ }
+
+ /* we are restarting association process
+ * clear RXON_FILTER_ASSOC_MSK bit
+ */
+ ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ iwlcore_commit_rxon(priv, ctx);
+
+ iwl_set_rate(priv);
+
+ mutex_unlock(&priv->mutex);
+
+ IWL_DEBUG_MAC80211(priv, "leave\n");
+}
+EXPORT_SYMBOL(iwl_legacy_mac_reset_tsf);
+
+static void iwl_ht_conf(struct iwl_priv *priv,
+ struct ieee80211_vif *vif)
+{
+ struct iwl_ht_config *ht_conf = &priv->current_ht_config;
+ struct ieee80211_sta *sta;
+ struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
+ struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
+
+ IWL_DEBUG_ASSOC(priv, "enter:\n");
+
+ if (!ctx->ht.enabled)
+ return;
+
+ ctx->ht.protection =
+ bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION;
+ ctx->ht.non_gf_sta_present =
+ !!(bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
+
+ ht_conf->single_chain_sufficient = false;
+
+ switch (vif->type) {
+ case NL80211_IFTYPE_STATION:
+ rcu_read_lock();
+ sta = ieee80211_find_sta(vif, bss_conf->bssid);
+ if (sta) {
+ struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
+ int maxstreams;
+
+ maxstreams = (ht_cap->mcs.tx_params &
+ IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK)
+ >> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
+ maxstreams += 1;
+
+ if ((ht_cap->mcs.rx_mask[1] == 0) &&
+ (ht_cap->mcs.rx_mask[2] == 0))
+ ht_conf->single_chain_sufficient = true;
+ if (maxstreams <= 1)
+ ht_conf->single_chain_sufficient = true;
+ } else {
+ /*
+ * If at all, this can only happen through a race
+ * when the AP disconnects us while we're still
+ * setting up the connection, in that case mac80211
+ * will soon tell us about that.
+ */
+ ht_conf->single_chain_sufficient = true;
+ }
+ rcu_read_unlock();
+ break;
+ case NL80211_IFTYPE_ADHOC:
+ ht_conf->single_chain_sufficient = true;
+ break;
+ default:
+ break;
+ }
+
+ IWL_DEBUG_ASSOC(priv, "leave\n");
+}
+
+static inline void iwl_set_no_assoc(struct iwl_priv *priv,
+ struct ieee80211_vif *vif)
+{
+ struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
+
+ iwl_led_disassociate(priv);
+ /*
+ * inform the ucode that there is no longer an
+ * association and that no more packets should be
+ * sent
+ */
+ ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ ctx->staging.assoc_id = 0;
+ iwlcore_commit_rxon(priv, ctx);
+}
+
+static void iwlcore_beacon_update(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
+{
+ struct iwl_priv *priv = hw->priv;
+ unsigned long flags;
+ __le64 timestamp;
+ struct sk_buff *skb = ieee80211_beacon_get(hw, vif);
+
+ if (!skb)
+ return;
+
+ IWL_DEBUG_MAC80211(priv, "enter\n");
+
+ lockdep_assert_held(&priv->mutex);
+
+ if (!priv->beacon_ctx) {
+ IWL_ERR(priv, "update beacon but no beacon context!\n");
+ dev_kfree_skb(skb);
+ return;
+ }
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ if (priv->beacon_skb)
+ dev_kfree_skb(priv->beacon_skb);
+
+ priv->beacon_skb = skb;
+
+ timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
+ priv->timestamp = le64_to_cpu(timestamp);
+
+ IWL_DEBUG_MAC80211(priv, "leave\n");
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ if (!iwl_is_ready_rf(priv)) {
+ IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
+ return;
+ }
+
+ priv->cfg->ops->legacy->post_associate(priv);
+}
+
+void iwl_legacy_mac_bss_info_changed(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *bss_conf,
+ u32 changes)
+{
+ struct iwl_priv *priv = hw->priv;
+ struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
+ int ret;
+
+ if (WARN_ON(!priv->cfg->ops->legacy))
+ return;
+
+ IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes);
+
+ if (!iwl_is_alive(priv))
+ return;
+
+ mutex_lock(&priv->mutex);
+
+ if (changes & BSS_CHANGED_QOS) {
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ ctx->qos_data.qos_active = bss_conf->qos;
+ iwl_update_qos(priv, ctx);
+ spin_unlock_irqrestore(&priv->lock, flags);
+ }
+
+ if (changes & BSS_CHANGED_BEACON_ENABLED) {
+ /*
+ * the add_interface code must make sure we only ever
+ * have a single interface that could be beaconing at
+ * any time.
+ */
+ if (vif->bss_conf.enable_beacon)
+ priv->beacon_ctx = ctx;
+ else
+ priv->beacon_ctx = NULL;
+ }
+
+ if (changes & BSS_CHANGED_BEACON && vif->type == NL80211_IFTYPE_AP) {
+ dev_kfree_skb(priv->beacon_skb);
+ priv->beacon_skb = ieee80211_beacon_get(hw, vif);
+ }
+
+ if (changes & BSS_CHANGED_BEACON_INT && vif->type == NL80211_IFTYPE_AP)
+ iwl_send_rxon_timing(priv, ctx);
+
+ if (changes & BSS_CHANGED_BSSID) {
+ IWL_DEBUG_MAC80211(priv, "BSSID %pM\n", bss_conf->bssid);
+
+ /*
+ * If there is currently a HW scan going on in the
+ * background then we need to cancel it else the RXON
+ * below/in post_associate will fail.
+ */
+ if (iwl_scan_cancel_timeout(priv, 100)) {
+ IWL_WARN(priv, "Aborted scan still in progress after 100ms\n");
+ IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n");
+ mutex_unlock(&priv->mutex);
+ return;
+ }
+
+ /* mac80211 only sets assoc when in STATION mode */
+ if (vif->type == NL80211_IFTYPE_ADHOC || bss_conf->assoc) {
+ memcpy(ctx->staging.bssid_addr,
+ bss_conf->bssid, ETH_ALEN);
+
+ /* currently needed in a few places */
+ memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN);
+ } else {
+ ctx->staging.filter_flags &=
+ ~RXON_FILTER_ASSOC_MSK;
+ }
+
+ }
+
+ /*
+ * This needs to be after setting the BSSID in case
+ * mac80211 decides to do both changes at once because
+ * it will invoke post_associate.
+ */
+ if (vif->type == NL80211_IFTYPE_ADHOC && changes & BSS_CHANGED_BEACON)
+ iwlcore_beacon_update(hw, vif);
+
+ if (changes & BSS_CHANGED_ERP_PREAMBLE) {
+ IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n",
+ bss_conf->use_short_preamble);
+ if (bss_conf->use_short_preamble)
+ ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
+ else
+ ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+ }
+
+ if (changes & BSS_CHANGED_ERP_CTS_PROT) {
+ IWL_DEBUG_MAC80211(priv, "ERP_CTS %d\n", bss_conf->use_cts_prot);
+ if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ))
+ ctx->staging.flags |= RXON_FLG_TGG_PROTECT_MSK;
+ else
+ ctx->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
+ if (bss_conf->use_cts_prot)
+ ctx->staging.flags |= RXON_FLG_SELF_CTS_EN;
+ else
+ ctx->staging.flags &= ~RXON_FLG_SELF_CTS_EN;
+ }
+
+ if (changes & BSS_CHANGED_BASIC_RATES) {
+ /* XXX use this information
+ *
+ * To do that, remove code from iwl_set_rate() and put something
+ * like this here:
+ *
+ if (A-band)
+ ctx->staging.ofdm_basic_rates =
+ bss_conf->basic_rates;
+ else
+ ctx->staging.ofdm_basic_rates =
+ bss_conf->basic_rates >> 4;
+ ctx->staging.cck_basic_rates =
+ bss_conf->basic_rates & 0xF;
+ */
+ }
+
+ if (changes & BSS_CHANGED_HT) {
+ iwl_ht_conf(priv, vif);
+
+ if (priv->cfg->ops->hcmd->set_rxon_chain)
+ priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
+ }
+
+ if (changes & BSS_CHANGED_ASSOC) {
+ IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc);
+ if (bss_conf->assoc) {
+ priv->timestamp = bss_conf->timestamp;
+
+ iwl_led_associate(priv);
+
+ if (!iwl_is_rfkill(priv))
+ priv->cfg->ops->legacy->post_associate(priv);
+ } else
+ iwl_set_no_assoc(priv, vif);
+ }
+
+ if (changes && iwl_is_associated_ctx(ctx) && bss_conf->aid) {
+ IWL_DEBUG_MAC80211(priv, "Changes (%#x) while associated\n",
+ changes);
+ ret = iwl_send_rxon_assoc(priv, ctx);
+ if (!ret) {
+ /* Sync active_rxon with latest change. */
+ memcpy((void *)&ctx->active,
+ &ctx->staging,
+ sizeof(struct iwl_rxon_cmd));
+ }
+ }
+
+ if (changes & BSS_CHANGED_BEACON_ENABLED) {
+ if (vif->bss_conf.enable_beacon) {
+ memcpy(ctx->staging.bssid_addr,
+ bss_conf->bssid, ETH_ALEN);
+ memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN);
+ iwl_led_associate(priv);
+ priv->cfg->ops->legacy->config_ap(priv);
+ } else
+ iwl_set_no_assoc(priv, vif);
+ }
+
+ if (changes & BSS_CHANGED_IBSS) {
+ ret = priv->cfg->ops->legacy->manage_ibss_station(priv, vif,
+ bss_conf->ibss_joined);
+ if (ret)
+ IWL_ERR(priv, "failed to %s IBSS station %pM\n",
+ bss_conf->ibss_joined ? "add" : "remove",
+ bss_conf->bssid);
+ }
+
+ mutex_unlock(&priv->mutex);
+
+ IWL_DEBUG_MAC80211(priv, "leave\n");
+}
+EXPORT_SYMBOL(iwl_legacy_mac_bss_info_changed);
+
+irqreturn_t iwl_isr_legacy(int irq, void *data)
+{
+ struct iwl_priv *priv = data;
+ u32 inta, inta_mask;
+ u32 inta_fh;
+ unsigned long flags;
+ if (!priv)
+ return IRQ_NONE;
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ /* Disable (but don't clear!) interrupts here to avoid
+ * back-to-back ISRs and sporadic interrupts from our NIC.
+ * If we have something to service, the tasklet will re-enable ints.
+ * If we *don't* have something, we'll re-enable before leaving here. */
+ inta_mask = iwl_read32(priv, CSR_INT_MASK); /* just for debug */
+ iwl_write32(priv, CSR_INT_MASK, 0x00000000);
+
+ /* Discover which interrupts are active/pending */
+ inta = iwl_read32(priv, CSR_INT);
+ inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
+
+ /* Ignore interrupt if there's nothing in NIC to service.
+ * This may be due to IRQ shared with another device,
+ * or due to sporadic interrupts thrown from our NIC. */
+ if (!inta && !inta_fh) {
+ IWL_DEBUG_ISR(priv,
+ "Ignore interrupt, inta == 0, inta_fh == 0\n");
+ goto none;
+ }
+
+ if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) {
+ /* Hardware disappeared. It might have already raised
+ * an interrupt */
+ IWL_WARN(priv, "HARDWARE GONE?? INTA == 0x%08x\n", inta);
+ goto unplugged;
+ }
+
+ IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
+ inta, inta_mask, inta_fh);
+
+ inta &= ~CSR_INT_BIT_SCD;
+
+ /* iwl_irq_tasklet() will service interrupts and re-enable them */
+ if (likely(inta || inta_fh))
+ tasklet_schedule(&priv->irq_tasklet);
+
+unplugged:
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return IRQ_HANDLED;
+
+none:
+ /* re-enable interrupts here since we don't have anything to service. */
+ /* only Re-enable if diabled by irq */
+ if (test_bit(STATUS_INT_ENABLED, &priv->status))
+ iwl_enable_interrupts(priv);
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return IRQ_NONE;
+}
+EXPORT_SYMBOL(iwl_isr_legacy);
+
+/*
+ * iwl_legacy_tx_cmd_protection: Set rts/cts. 3945 and 4965 only share this
+ * function.
+ */
+void iwl_legacy_tx_cmd_protection(struct iwl_priv *priv,
+ struct ieee80211_tx_info *info,
+ __le16 fc, __le32 *tx_flags)
+{
+ if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) {
+ *tx_flags |= TX_CMD_FLG_RTS_MSK;
+ *tx_flags &= ~TX_CMD_FLG_CTS_MSK;
+ *tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK;
+
+ if (!ieee80211_is_mgmt(fc))
+ return;
+
+ switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
+ case cpu_to_le16(IEEE80211_STYPE_AUTH):
+ case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
+ case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ):
+ case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ):
+ *tx_flags &= ~TX_CMD_FLG_RTS_MSK;
+ *tx_flags |= TX_CMD_FLG_CTS_MSK;
+ break;
+ }
+ } else if (info->control.rates[0].flags &
+ IEEE80211_TX_RC_USE_CTS_PROTECT) {
+ *tx_flags &= ~TX_CMD_FLG_RTS_MSK;
+ *tx_flags |= TX_CMD_FLG_CTS_MSK;
+ *tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK;
+ }
+}
+EXPORT_SYMBOL(iwl_legacy_tx_cmd_protection);
diff --git a/drivers/net/wireless/iwlwifi/iwl-legacy.h b/drivers/net/wireless/iwlwifi/iwl-legacy.h
new file mode 100644
index 000000000000..9f7b2f935964
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-legacy.h
@@ -0,0 +1,79 @@
+/******************************************************************************
+ *
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ * Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+#ifndef __iwl_legacy_h__
+#define __iwl_legacy_h__
+
+/* mac80211 handlers */
+int iwl_legacy_mac_config(struct ieee80211_hw *hw, u32 changed);
+void iwl_legacy_mac_reset_tsf(struct ieee80211_hw *hw);
+void iwl_legacy_mac_bss_info_changed(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *bss_conf,
+ u32 changes);
+void iwl_legacy_tx_cmd_protection(struct iwl_priv *priv,
+ struct ieee80211_tx_info *info,
+ __le16 fc, __le32 *tx_flags);
+
+irqreturn_t iwl_isr_legacy(int irq, void *data);
+
+#endif /* __iwl_legacy_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index 49d7788937a9..1eec18d909d8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -75,6 +75,10 @@ struct iwl_power_vec_entry {
#define NOSLP cpu_to_le16(0), 0, 0
#define SLP IWL_POWER_DRIVER_ALLOW_SLEEP_MSK, 0, 0
+#define ASLP (IWL_POWER_POWER_SAVE_ENA_MSK | \
+ IWL_POWER_POWER_MANAGEMENT_ENA_MSK | \
+ IWL_POWER_ADVANCE_PM_ENA_MSK)
+#define ASLP_TOUT(T) cpu_to_le32(T)
#define TU_TO_USEC 1024
#define SLP_TOUT(T) cpu_to_le32((T) * TU_TO_USEC)
#define SLP_VEC(X0, X1, X2, X3, X4) {cpu_to_le32(X0), \
@@ -114,6 +118,52 @@ static const struct iwl_power_vec_entry range_2[IWL_POWER_NUM] = {
{{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(4, 7, 10, 10, 0xFF)}, 0}
};
+/* advance power management */
+/* DTIM 0 - 2 */
+static const struct iwl_power_vec_entry apm_range_0[IWL_POWER_NUM] = {
+ {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50),
+ SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0},
+ {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50),
+ SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0},
+ {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50),
+ SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0},
+ {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50),
+ SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0},
+ {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50),
+ SLP_VEC(1, 2, 6, 8, 0xFF), ASLP_TOUT(2)}, 2}
+};
+
+
+/* for DTIM period IWL_DTIM_RANGE_0_MAX + 1 through IWL_DTIM_RANGE_1_MAX */
+/* DTIM 3 - 10 */
+static const struct iwl_power_vec_entry apm_range_1[IWL_POWER_NUM] = {
+ {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50),
+ SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0},
+ {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50),
+ SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0},
+ {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50),
+ SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0},
+ {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50),
+ SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0},
+ {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50),
+ SLP_VEC(1, 2, 6, 8, 0xFF), 0}, 2}
+};
+
+/* for DTIM period > IWL_DTIM_RANGE_1_MAX */
+/* DTIM 11 - */
+static const struct iwl_power_vec_entry apm_range_2[IWL_POWER_NUM] = {
+ {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50),
+ SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0},
+ {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50),
+ SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0},
+ {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50),
+ SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0},
+ {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50),
+ SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0},
+ {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50),
+ SLP_VEC(1, 2, 6, 8, 0xFF), ASLP_TOUT(2)}, 2}
+};
+
static void iwl_static_sleep_cmd(struct iwl_priv *priv,
struct iwl_powertable_cmd *cmd,
enum iwl_power_level lvl, int period)
@@ -124,11 +174,19 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv,
u8 skip;
u32 slp_itrvl;
- table = range_2;
- if (period <= IWL_DTIM_RANGE_1_MAX)
- table = range_1;
- if (period <= IWL_DTIM_RANGE_0_MAX)
- table = range_0;
+ if (priv->cfg->adv_pm) {
+ table = apm_range_2;
+ if (period <= IWL_DTIM_RANGE_1_MAX)
+ table = apm_range_1;
+ if (period <= IWL_DTIM_RANGE_0_MAX)
+ table = apm_range_0;
+ } else {
+ table = range_2;
+ if (period <= IWL_DTIM_RANGE_1_MAX)
+ table = range_1;
+ if (period <= IWL_DTIM_RANGE_0_MAX)
+ table = range_0;
+ }
BUG_ON(lvl < 0 || lvl >= IWL_POWER_NUM);
@@ -163,6 +221,20 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv,
else
cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK;
+ if (priv->cfg->base_params->shadow_reg_enable)
+ cmd->flags |= IWL_POWER_SHADOW_REG_ENA;
+ else
+ cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA;
+
+ if (priv->cfg->bt_params &&
+ priv->cfg->bt_params->advanced_bt_coexist) {
+ if (!priv->cfg->bt_params->bt_sco_disable)
+ cmd->flags |= IWL_POWER_BT_SCO_ENA;
+ else
+ cmd->flags &= ~IWL_POWER_BT_SCO_ENA;
+ }
+
+
slp_itrvl = le32_to_cpu(cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1]);
if (slp_itrvl > IWL_CONN_MAX_LISTEN_INTERVAL)
cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1] =
@@ -236,6 +308,19 @@ static void iwl_power_fill_sleep_cmd(struct iwl_priv *priv,
if (priv->power_data.pci_pm)
cmd->flags |= IWL_POWER_PCI_PM_MSK;
+ if (priv->cfg->base_params->shadow_reg_enable)
+ cmd->flags |= IWL_POWER_SHADOW_REG_ENA;
+ else
+ cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA;
+
+ if (priv->cfg->bt_params &&
+ priv->cfg->bt_params->advanced_bt_coexist) {
+ if (!priv->cfg->bt_params->bt_sco_disable)
+ cmd->flags |= IWL_POWER_BT_SCO_ENA;
+ else
+ cmd->flags &= ~IWL_POWER_BT_SCO_ENA;
+ }
+
cmd->rx_data_timeout = cpu_to_le32(1000 * dynps_ms);
cmd->tx_data_timeout = cpu_to_le32(1000 * dynps_ms);
@@ -263,70 +348,95 @@ static int iwl_set_power(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd)
sizeof(struct iwl_powertable_cmd), cmd);
}
-/* priv->mutex must be held */
-int iwl_power_update_mode(struct iwl_priv *priv, bool force)
+static void iwl_power_build_cmd(struct iwl_priv *priv,
+ struct iwl_powertable_cmd *cmd)
{
- int ret = 0;
bool enabled = priv->hw->conf.flags & IEEE80211_CONF_PS;
- bool update_chains;
- struct iwl_powertable_cmd cmd;
int dtimper;
- /* Don't update the RX chain when chain noise calibration is running */
- update_chains = priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE ||
- priv->chain_noise_data.state == IWL_CHAIN_NOISE_ALIVE;
-
dtimper = priv->hw->conf.ps_dtim_period ?: 1;
if (priv->cfg->base_params->broken_powersave)
- iwl_power_sleep_cam_cmd(priv, &cmd);
+ iwl_power_sleep_cam_cmd(priv, cmd);
else if (priv->cfg->base_params->supports_idle &&
priv->hw->conf.flags & IEEE80211_CONF_IDLE)
- iwl_static_sleep_cmd(priv, &cmd, IWL_POWER_INDEX_5, 20);
+ iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, 20);
else if (priv->cfg->ops->lib->tt_ops.lower_power_detection &&
priv->cfg->ops->lib->tt_ops.tt_power_mode &&
priv->cfg->ops->lib->tt_ops.lower_power_detection(priv)) {
/* in thermal throttling low power state */
- iwl_static_sleep_cmd(priv, &cmd,
+ iwl_static_sleep_cmd(priv, cmd,
priv->cfg->ops->lib->tt_ops.tt_power_mode(priv), dtimper);
} else if (!enabled)
- iwl_power_sleep_cam_cmd(priv, &cmd);
+ iwl_power_sleep_cam_cmd(priv, cmd);
else if (priv->power_data.debug_sleep_level_override >= 0)
- iwl_static_sleep_cmd(priv, &cmd,
+ iwl_static_sleep_cmd(priv, cmd,
priv->power_data.debug_sleep_level_override,
dtimper);
else if (no_sleep_autoadjust)
- iwl_static_sleep_cmd(priv, &cmd, IWL_POWER_INDEX_1, dtimper);
+ iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_1, dtimper);
else
- iwl_power_fill_sleep_cmd(priv, &cmd,
+ iwl_power_fill_sleep_cmd(priv, cmd,
priv->hw->conf.dynamic_ps_timeout,
priv->hw->conf.max_sleep_period);
+}
+
+int iwl_power_set_mode(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd,
+ bool force)
+{
+ int ret;
+ bool update_chains;
+
+ lockdep_assert_held(&priv->mutex);
+
+ /* Don't update the RX chain when chain noise calibration is running */
+ update_chains = priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE ||
+ priv->chain_noise_data.state == IWL_CHAIN_NOISE_ALIVE;
+
+ if (!memcmp(&priv->power_data.sleep_cmd, cmd, sizeof(*cmd)) && !force)
+ return 0;
+
+ if (!iwl_is_ready_rf(priv))
+ return -EIO;
- if (iwl_is_ready_rf(priv) &&
- (memcmp(&priv->power_data.sleep_cmd, &cmd, sizeof(cmd)) || force)) {
- if (cmd.flags & IWL_POWER_DRIVER_ALLOW_SLEEP_MSK)
- set_bit(STATUS_POWER_PMI, &priv->status);
-
- ret = iwl_set_power(priv, &cmd);
- if (!ret) {
- if (!(cmd.flags & IWL_POWER_DRIVER_ALLOW_SLEEP_MSK))
- clear_bit(STATUS_POWER_PMI, &priv->status);
-
- if (priv->cfg->ops->lib->update_chain_flags &&
- update_chains)
- priv->cfg->ops->lib->update_chain_flags(priv);
- else if (priv->cfg->ops->lib->update_chain_flags)
- IWL_DEBUG_POWER(priv,
+ /* scan complete use sleep_power_next, need to be updated */
+ memcpy(&priv->power_data.sleep_cmd_next, cmd, sizeof(*cmd));
+ if (test_bit(STATUS_SCANNING, &priv->status) && !force) {
+ IWL_DEBUG_INFO(priv, "Defer power set mode while scanning\n");
+ return 0;
+ }
+
+ if (cmd->flags & IWL_POWER_DRIVER_ALLOW_SLEEP_MSK)
+ set_bit(STATUS_POWER_PMI, &priv->status);
+
+ ret = iwl_set_power(priv, cmd);
+ if (!ret) {
+ if (!(cmd->flags & IWL_POWER_DRIVER_ALLOW_SLEEP_MSK))
+ clear_bit(STATUS_POWER_PMI, &priv->status);
+
+ if (priv->cfg->ops->lib->update_chain_flags && update_chains)
+ priv->cfg->ops->lib->update_chain_flags(priv);
+ else if (priv->cfg->ops->lib->update_chain_flags)
+ IWL_DEBUG_POWER(priv,
"Cannot update the power, chain noise "
"calibration running: %d\n",
priv->chain_noise_data.state);
- memcpy(&priv->power_data.sleep_cmd, &cmd, sizeof(cmd));
- } else
- IWL_ERR(priv, "set power fail, ret = %d", ret);
- }
+
+ memcpy(&priv->power_data.sleep_cmd, cmd, sizeof(*cmd));
+ } else
+ IWL_ERR(priv, "set power fail, ret = %d", ret);
return ret;
}
+EXPORT_SYMBOL(iwl_power_set_mode);
+
+int iwl_power_update_mode(struct iwl_priv *priv, bool force)
+{
+ struct iwl_powertable_cmd cmd;
+
+ iwl_power_build_cmd(priv, &cmd);
+ return iwl_power_set_mode(priv, &cmd, force);
+}
EXPORT_SYMBOL(iwl_power_update_mode);
/* initialize to default */
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h
index df81565a7cc4..fe012032c28c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.h
+++ b/drivers/net/wireless/iwlwifi/iwl-power.h
@@ -41,10 +41,13 @@ enum iwl_power_level {
struct iwl_power_mgr {
struct iwl_powertable_cmd sleep_cmd;
+ struct iwl_powertable_cmd sleep_cmd_next;
int debug_sleep_level_override;
bool pci_pm;
};
+int iwl_power_set_mode(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd,
+ bool force);
int iwl_power_update_mode(struct iwl_priv *priv, bool force);
void iwl_power_initialize(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index f436270ca39a..87a6fd84d4d2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -134,28 +134,37 @@ void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q
if (q->need_update == 0)
goto exit_unlock;
- /* If power-saving is in use, make sure device is awake */
- if (test_bit(STATUS_POWER_PMI, &priv->status)) {
- reg = iwl_read32(priv, CSR_UCODE_DRV_GP1);
+ if (priv->cfg->base_params->shadow_reg_enable) {
+ /* shadow register enabled */
+ /* Device expects a multiple of 8 */
+ q->write_actual = (q->write & ~0x7);
+ iwl_write32(priv, rx_wrt_ptr_reg, q->write_actual);
+ } else {
+ /* If power-saving is in use, make sure device is awake */
+ if (test_bit(STATUS_POWER_PMI, &priv->status)) {
+ reg = iwl_read32(priv, CSR_UCODE_DRV_GP1);
- if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
- IWL_DEBUG_INFO(priv, "Rx queue requesting wakeup, GP1 = 0x%x\n",
- reg);
- iwl_set_bit(priv, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
- goto exit_unlock;
- }
+ if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
+ IWL_DEBUG_INFO(priv,
+ "Rx queue requesting wakeup,"
+ " GP1 = 0x%x\n", reg);
+ iwl_set_bit(priv, CSR_GP_CNTRL,
+ CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+ goto exit_unlock;
+ }
- q->write_actual = (q->write & ~0x7);
- iwl_write_direct32(priv, rx_wrt_ptr_reg, q->write_actual);
+ q->write_actual = (q->write & ~0x7);
+ iwl_write_direct32(priv, rx_wrt_ptr_reg,
+ q->write_actual);
- /* Else device is assumed to be awake */
- } else {
- /* Device expects a multiple of 8 */
- q->write_actual = (q->write & ~0x7);
- iwl_write_direct32(priv, rx_wrt_ptr_reg, q->write_actual);
+ /* Else device is assumed to be awake */
+ } else {
+ /* Device expects a multiple of 8 */
+ q->write_actual = (q->write & ~0x7);
+ iwl_write_direct32(priv, rx_wrt_ptr_reg,
+ q->write_actual);
+ }
}
-
q->need_update = 0;
exit_unlock:
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 67da31295781..12d9363d0afe 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -252,8 +252,7 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,
IWL_DEBUG_SCAN(priv, "Scan on %sGHz took %dms\n",
(priv->scan_band == IEEE80211_BAND_2GHZ) ? "2.4" : "5.2",
- jiffies_to_msecs(elapsed_jiffies
- (priv->scan_start, jiffies)));
+ jiffies_to_msecs(jiffies - priv->scan_start));
queue_work(priv->workqueue, &priv->scan_completed);
@@ -603,13 +602,16 @@ out_settings:
if (!iwl_is_ready_rf(priv))
goto out;
- /* Since setting the TXPOWER may have been deferred while
- * performing the scan, fire one off */
- iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);
+ /*
+ * We do not commit power settings while scan is pending,
+ * do it now if the settings changed.
+ */
+ iwl_power_set_mode(priv, &priv->power_data.sleep_cmd_next, false);
+ iwl_set_tx_power(priv, priv->tx_power_next, false);
priv->cfg->ops->utils->post_scan(priv);
- out:
+out:
mutex_unlock(&priv->mutex);
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 7c7f7dcb1b1e..4776323b1eba 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -400,7 +400,8 @@ static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, u8 sta_id)
}
static int iwl_send_remove_station(struct iwl_priv *priv,
- const u8 *addr, int sta_id)
+ const u8 *addr, int sta_id,
+ bool temporary)
{
struct iwl_rx_packet *pkt;
int ret;
@@ -436,9 +437,11 @@ static int iwl_send_remove_station(struct iwl_priv *priv,
if (!ret) {
switch (pkt->u.rem_sta.status) {
case REM_STA_SUCCESS_MSK:
- spin_lock_irqsave(&priv->sta_lock, flags_spin);
- iwl_sta_ucode_deactivate(priv, sta_id);
- spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
+ if (!temporary) {
+ spin_lock_irqsave(&priv->sta_lock, flags_spin);
+ iwl_sta_ucode_deactivate(priv, sta_id);
+ spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
+ }
IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n");
break;
default:
@@ -505,7 +508,7 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
spin_unlock_irqrestore(&priv->sta_lock, flags);
- return iwl_send_remove_station(priv, addr, sta_id);
+ return iwl_send_remove_station(priv, addr, sta_id, false);
out_err:
spin_unlock_irqrestore(&priv->sta_lock, flags);
return -EINVAL;
@@ -624,6 +627,49 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
}
EXPORT_SYMBOL(iwl_restore_stations);
+void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
+{
+ unsigned long flags;
+ int sta_id = ctx->ap_sta_id;
+ int ret;
+ struct iwl_addsta_cmd sta_cmd;
+ struct iwl_link_quality_cmd lq;
+ bool active;
+
+ spin_lock_irqsave(&priv->sta_lock, flags);
+ if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) {
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+ return;
+ }
+
+ memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd));
+ sta_cmd.mode = 0;
+ memcpy(&lq, priv->stations[sta_id].lq, sizeof(lq));
+
+ active = priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE;
+ priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE;
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+ if (active) {
+ ret = iwl_send_remove_station(
+ priv, priv->stations[sta_id].sta.sta.addr,
+ sta_id, true);
+ if (ret)
+ IWL_ERR(priv, "failed to remove STA %pM (%d)\n",
+ priv->stations[sta_id].sta.sta.addr, ret);
+ }
+ spin_lock_irqsave(&priv->sta_lock, flags);
+ priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE;
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+ ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
+ if (ret)
+ IWL_ERR(priv, "failed to re-add STA %pM (%d)\n",
+ priv->stations[sta_id].sta.sta.addr, ret);
+ iwl_send_lq_cmd(priv, ctx, &lq, CMD_SYNC, true);
+}
+EXPORT_SYMBOL(iwl_reprogram_ap_sta);
+
int iwl_get_free_ucode_key_index(struct iwl_priv *priv)
{
int i;
@@ -736,6 +782,14 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
if (WARN_ON(lq->sta_id == IWL_INVALID_STATION))
return -EINVAL;
+
+ spin_lock_irqsave(&priv->sta_lock, flags_spin);
+ if (!(priv->stations[lq->sta_id].used & IWL_STA_DRIVER_ACTIVE)) {
+ spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
+ return -EINVAL;
+ }
+ spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
+
iwl_dump_lq_cmd(priv, lq);
BUG_ON(init && (cmd.flags & CMD_ASYNC));
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index 06475872eee4..206f1e1a0caf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -63,6 +63,7 @@ u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
struct iwl_link_quality_cmd *lq, u8 flags, bool init);
+void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
/**
* iwl_clear_driver_stations - clear knowledge of all stations from driver
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 7261ee49f282..073b6ce6141c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -49,30 +49,39 @@ void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq)
if (txq->need_update == 0)
return;
- /* if we're trying to save power */
- if (test_bit(STATUS_POWER_PMI, &priv->status)) {
- /* wake up nic if it's powered down ...
- * uCode will wake up, and interrupt us again, so next
- * time we'll skip this part. */
- reg = iwl_read32(priv, CSR_UCODE_DRV_GP1);
-
- if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
- IWL_DEBUG_INFO(priv, "Tx queue %d requesting wakeup, GP1 = 0x%x\n",
- txq_id, reg);
- iwl_set_bit(priv, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
- return;
- }
-
- iwl_write_direct32(priv, HBUS_TARG_WRPTR,
- txq->q.write_ptr | (txq_id << 8));
-
- /* else not in power-save mode, uCode will never sleep when we're
- * trying to tx (during RFKILL, we're not trying to tx). */
- } else
+ if (priv->cfg->base_params->shadow_reg_enable) {
+ /* shadow register enabled */
iwl_write32(priv, HBUS_TARG_WRPTR,
txq->q.write_ptr | (txq_id << 8));
+ } else {
+ /* if we're trying to save power */
+ if (test_bit(STATUS_POWER_PMI, &priv->status)) {
+ /* wake up nic if it's powered down ...
+ * uCode will wake up, and interrupt us again, so next
+ * time we'll skip this part. */
+ reg = iwl_read32(priv, CSR_UCODE_DRV_GP1);
+
+ if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
+ IWL_DEBUG_INFO(priv,
+ "Tx queue %d requesting wakeup,"
+ " GP1 = 0x%x\n", txq_id, reg);
+ iwl_set_bit(priv, CSR_GP_CNTRL,
+ CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+ return;
+ }
+
+ iwl_write_direct32(priv, HBUS_TARG_WRPTR,
+ txq->q.write_ptr | (txq_id << 8));
+ /*
+ * else not in power-save mode,
+ * uCode will never sleep when we're
+ * trying to tx (during RFKILL, we're not trying to tx).
+ */
+ } else
+ iwl_write32(priv, HBUS_TARG_WRPTR,
+ txq->q.write_ptr | (txq_id << 8));
+ }
txq->need_update = 0;
}
EXPORT_SYMBOL(iwl_txq_update_write_ptr);
@@ -254,8 +263,6 @@ static int iwl_queue_init(struct iwl_priv *priv, struct iwl_queue *q,
q->high_mark = 2;
q->write_ptr = q->read_ptr = 0;
- q->last_read_ptr = 0;
- q->repeat_same_read_ptr = 0;
return 0;
}
@@ -350,13 +357,12 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
txq->need_update = 0;
/*
- * Aggregation TX queues will get their ID when aggregation begins;
- * they overwrite the setting done here. The command FIFO doesn't
- * need an swq_id so don't set one to catch errors, all others can
- * be set up to the identity mapping.
+ * For the default queues 0-3, set up the swq_id
+ * already -- all others need to get one later
+ * (if they need one at all).
*/
- if (txq_id != priv->cmd_queue)
- txq->swq_id = txq_id;
+ if (txq_id < 4)
+ iwl_set_swq_id(txq, txq_id, txq_id);
/* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise
* iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 7edf8c2fb8c7..371abbf60eac 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -61,6 +61,7 @@
#include "iwl-helpers.h"
#include "iwl-dev.h"
#include "iwl-spectrum.h"
+#include "iwl-legacy.h"
/*
* module name, copyright, version, etc.
@@ -474,7 +475,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
dma_addr_t phys_addr;
dma_addr_t txcmd_phys;
int txq_id = skb_get_queue_mapping(skb);
- u16 len, idx, len_org, hdr_len; /* TODO: len_org is not used */
+ u16 len, idx, hdr_len;
u8 id;
u8 unicast;
u8 sta_id;
@@ -611,15 +612,8 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
*/
len = sizeof(struct iwl3945_tx_cmd) +
sizeof(struct iwl_cmd_header) + hdr_len;
-
- len_org = len;
len = (len + 3) & ~3;
- if (len_org != len)
- len_org = 1;
- else
- len_org = 0;
-
/* Physical address of this Tx command's header (not MAC header!),
* within command buffer array. */
txcmd_phys = pci_map_single(priv->pci_dev, &out_cmd->hdr,
@@ -661,7 +655,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
spin_unlock_irqrestore(&priv->lock, flags);
}
- iwl_stop_queue(priv, skb_get_queue_mapping(skb));
+ iwl_stop_queue(priv, txq);
}
return 0;
@@ -2515,13 +2509,8 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
/* After the ALIVE response, we can send commands to 3945 uCode */
set_bit(STATUS_ALIVE, &priv->status);
- if (priv->cfg->ops->lib->recover_from_tx_stall) {
- /* Enable timer to monitor the driver queues */
- mod_timer(&priv->monitor_recover,
- jiffies +
- msecs_to_jiffies(
- priv->cfg->base_params->monitor_recover_period));
- }
+ /* Enable watchdog to monitor the driver tx queues */
+ iwl_setup_watchdog(priv);
if (iwl_is_rfkill(priv))
return;
@@ -2578,8 +2567,7 @@ static void __iwl3945_down(struct iwl_priv *priv)
/* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set
* to prevent rearm timer */
- if (priv->cfg->ops->lib->recover_from_tx_stall)
- del_timer_sync(&priv->monitor_recover);
+ del_timer_sync(&priv->watchdog);
/* Station information will now be cleared in device */
iwl_clear_ucode_stations(priv, NULL);
@@ -3057,22 +3045,22 @@ static void iwl3945_bg_rx_replenish(struct work_struct *data)
mutex_unlock(&priv->mutex);
}
-void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
+void iwl3945_post_associate(struct iwl_priv *priv)
{
int rc = 0;
struct ieee80211_conf *conf = NULL;
struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
- if (!vif || !priv->is_open)
+ if (!ctx->vif || !priv->is_open)
return;
- if (vif->type == NL80211_IFTYPE_AP) {
+ if (ctx->vif->type == NL80211_IFTYPE_AP) {
IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__);
return;
}
IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n",
- vif->bss_conf.aid, ctx->active.bssid_addr);
+ ctx->vif->bss_conf.aid, ctx->active.bssid_addr);
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
@@ -3091,18 +3079,18 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
- ctx->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid);
+ ctx->staging.assoc_id = cpu_to_le16(ctx->vif->bss_conf.aid);
IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
- vif->bss_conf.aid, vif->bss_conf.beacon_int);
+ ctx->vif->bss_conf.aid, ctx->vif->bss_conf.beacon_int);
- if (vif->bss_conf.use_short_preamble)
+ if (ctx->vif->bss_conf.use_short_preamble)
ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
else
ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
- if (vif->bss_conf.use_short_slot)
+ if (ctx->vif->bss_conf.use_short_slot)
ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
else
ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
@@ -3110,7 +3098,7 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
iwl3945_commit_rxon(priv, ctx);
- switch (vif->type) {
+ switch (ctx->vif->type) {
case NL80211_IFTYPE_STATION:
iwl3945_rate_scale_init(priv->hw, IWL_AP_ID);
break;
@@ -3119,7 +3107,7 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
break;
default:
IWL_ERR(priv, "%s Should not be called in %d mode\n",
- __func__, vif->type);
+ __func__, ctx->vif->type);
break;
}
}
@@ -3234,9 +3222,10 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
return NETDEV_TX_OK;
}
-void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
+void iwl3945_config_ap(struct iwl_priv *priv)
{
struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
+ struct ieee80211_vif *vif = ctx->vif;
int rc = 0;
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
@@ -3407,9 +3396,9 @@ static void iwl3945_configure_filter(struct ieee80211_hw *hw,
ctx->staging.filter_flags |= filter_or;
/*
- * Committing directly here breaks for some reason,
- * but we'll eventually commit the filter flags
- * change anyway.
+ * Not committing directly because hardware can perform a scan,
+ * but even if hw is ready, committing here breaks for some reason,
+ * we'll eventually commit the filter flags change anyway.
*/
mutex_unlock(&priv->mutex);
@@ -3780,12 +3769,9 @@ static void iwl3945_setup_deferred_work(struct iwl_priv *priv)
iwl3945_hw_setup_deferred_work(priv);
- if (priv->cfg->ops->lib->recover_from_tx_stall) {
- init_timer(&priv->monitor_recover);
- priv->monitor_recover.data = (unsigned long)priv;
- priv->monitor_recover.function =
- priv->cfg->ops->lib->recover_from_tx_stall;
- }
+ init_timer(&priv->watchdog);
+ priv->watchdog.data = (unsigned long)priv;
+ priv->watchdog.function = iwl_bg_watchdog;
tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
iwl3945_irq_tasklet, (unsigned long)priv);
@@ -3824,18 +3810,19 @@ static struct attribute_group iwl3945_attribute_group = {
.attrs = iwl3945_sysfs_entries,
};
-static struct ieee80211_ops iwl3945_hw_ops = {
+struct ieee80211_ops iwl3945_hw_ops = {
.tx = iwl3945_mac_tx,
.start = iwl3945_mac_start,
.stop = iwl3945_mac_stop,
.add_interface = iwl_mac_add_interface,
.remove_interface = iwl_mac_remove_interface,
- .config = iwl_mac_config,
+ .change_interface = iwl_mac_change_interface,
+ .config = iwl_legacy_mac_config,
.configure_filter = iwl3945_configure_filter,
.set_key = iwl3945_mac_set_key,
.conf_tx = iwl_mac_conf_tx,
- .reset_tsf = iwl_mac_reset_tsf,
- .bss_info_changed = iwl_bss_info_changed,
+ .reset_tsf = iwl_legacy_mac_reset_tsf,
+ .bss_info_changed = iwl_legacy_mac_bss_info_changed,
.hw_scan = iwl_mac_hw_scan,
.sta_add = iwl3945_mac_sta_add,
.sta_remove = iwl_mac_sta_remove,
@@ -3865,7 +3852,15 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
priv->iw_mode = NL80211_IFTYPE_STATION;
priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF;
+ /* initialize force reset */
+ priv->force_reset[IWL_RF_RESET].reset_duration =
+ IWL_DELAY_NEXT_FORCE_RF_RESET;
+ priv->force_reset[IWL_FW_RESET].reset_duration =
+ IWL_DELAY_NEXT_FORCE_FW_RELOAD;
+
+
priv->tx_power_user_lmt = IWL_DEFAULT_TX_POWER;
+ priv->tx_power_next = IWL_DEFAULT_TX_POWER;
if (eeprom->version < EEPROM_3945_EEPROM_VERSION) {
IWL_WARN(priv, "Unsupported EEPROM version: 0x%04X\n",
@@ -3965,7 +3960,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
/* mac80211 allocates memory for this device instance, including
* space for this driver's private structure */
- hw = iwl_alloc_all(cfg, &iwl3945_hw_ops);
+ hw = iwl_alloc_all(cfg);
if (hw == NULL) {
pr_err("Can not allocate network device\n");
err = -ENOMEM;
@@ -4117,7 +4112,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
pci_enable_msi(priv->pci_dev);
- err = request_irq(priv->pci_dev->irq, priv->cfg->ops->lib->isr,
+ err = request_irq(priv->pci_dev->irq, priv->cfg->ops->lib->isr_ops.isr,
IRQF_SHARED, DRV_NAME, priv);
if (err) {
IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq);
@@ -4275,10 +4270,7 @@ static struct pci_driver iwl3945_driver = {
.id_table = iwl3945_hw_card_ids,
.probe = iwl3945_pci_probe,
.remove = __devexit_p(iwl3945_pci_remove),
-#ifdef CONFIG_PM
- .suspend = iwl_pci_suspend,
- .resume = iwl_pci_resume,
-#endif
+ .driver.pm = IWL_PM_OPS,
};
static int __init iwl3945_init(void)
diff --git a/drivers/net/wireless/iwmc3200wifi/commands.c b/drivers/net/wireless/iwmc3200wifi/commands.c
index 330c7d9cf101..50dee6a0a5ca 100644
--- a/drivers/net/wireless/iwmc3200wifi/commands.c
+++ b/drivers/net/wireless/iwmc3200wifi/commands.c
@@ -908,7 +908,7 @@ int iwm_scan_ssids(struct iwm_priv *iwm, struct cfg80211_ssid *ssids,
return ret;
}
- iwm->scan_id = iwm->scan_id++ % IWM_SCAN_ID_MAX;
+ iwm->scan_id = (iwm->scan_id + 1) % IWM_SCAN_ID_MAX;
return 0;
}
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c
index 373930afc26b..dee32d3681a5 100644
--- a/drivers/net/wireless/libertas/cfg.c
+++ b/drivers/net/wireless/libertas/cfg.c
@@ -9,8 +9,6 @@
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/slab.h>
-#include <linux/sched.h>
-#include <linux/wait.h>
#include <linux/ieee80211.h>
#include <net/cfg80211.h>
#include <asm/unaligned.h>
@@ -2062,7 +2060,7 @@ static void lbs_cfg_set_regulatory_hint(struct lbs_private *priv)
};
/* Section 5.17.2 */
- static struct region_code_mapping regmap[] = {
+ static const struct region_code_mapping regmap[] = {
{"US ", 0x10}, /* US FCC */
{"CA ", 0x20}, /* Canada */
{"EU ", 0x30}, /* ETSI */
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index 70745928f3f8..78c4da150a74 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -177,6 +177,14 @@ int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
struct cmd_ds_host_sleep cmd_config;
int ret;
+ /*
+ * Certain firmware versions do not support EHS_REMOVE_WAKEUP command
+ * and the card will return a failure. Since we need to be
+ * able to reset the mask, in those cases we set a 0 mask instead.
+ */
+ if (criteria == EHS_REMOVE_WAKEUP && !priv->ehs_remove_supported)
+ criteria = 0;
+
cmd_config.hdr.size = cpu_to_le16(sizeof(cmd_config));
cmd_config.criteria = cpu_to_le32(criteria);
cmd_config.gpio = priv->wol_gpio;
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index cb14c38caf3a..18dd9a02c459 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -138,6 +138,7 @@ struct lbs_private {
uint32_t wol_criteria;
uint8_t wol_gpio;
uint8_t wol_gap;
+ bool ehs_remove_supported;
/* Transmitting */
int tx_pending_len; /* -1 while building packet */
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
index efaf85032208..6524c70363d9 100644
--- a/drivers/net/wireless/libertas/if_usb.c
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -345,6 +345,13 @@ static int if_usb_probe(struct usb_interface *intf,
if (device_create_file(&priv->dev->dev, &dev_attr_lbs_flash_boot2))
lbs_pr_err("cannot register lbs_flash_boot2 attribute\n");
+ /*
+ * EHS_REMOVE_WAKEUP is not supported on all versions of the firmware.
+ */
+ priv->wol_criteria = EHS_REMOVE_WAKEUP;
+ if (lbs_host_sleep_cfg(priv, priv->wol_criteria, NULL))
+ priv->ehs_remove_supported = false;
+
return 0;
err_start_card:
@@ -1090,12 +1097,6 @@ static int if_usb_suspend(struct usb_interface *intf, pm_message_t message)
if (priv->psstate != PS_STATE_FULL_POWER)
return -1;
- if (priv->wol_criteria == EHS_REMOVE_WAKEUP) {
- lbs_pr_info("Suspend attempt without "
- "configuring wake params!\n");
- return -ENOSYS;
- }
-
ret = lbs_suspend(priv);
if (ret)
goto out;
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index fcd1bbfc632d..6836a6dd9853 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -851,9 +851,10 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
priv->work_thread = create_singlethread_workqueue("lbs_worker");
INIT_WORK(&priv->mcast_work, lbs_set_mcast_worker);
- priv->wol_criteria = 0xffffffff;
+ priv->wol_criteria = EHS_REMOVE_WAKEUP;
priv->wol_gpio = 0xff;
priv->wol_gap = 20;
+ priv->ehs_remove_supported = true;
goto done;
diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c
index a4d0bca9ef2c..a2b1df21d286 100644
--- a/drivers/net/wireless/libertas/rx.c
+++ b/drivers/net/wireless/libertas/rx.c
@@ -55,7 +55,9 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb)
struct rxpd *p_rx_pd;
int hdrchop;
struct ethhdr *p_ethhdr;
- const u8 rfc1042_eth_hdr[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
+ static const u8 rfc1042_eth_hdr[] = {
+ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00
+ };
lbs_deb_enter(LBS_DEB_RX);
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 7eaaa3bab547..454f045ddff3 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -309,6 +309,8 @@ struct mac80211_hwsim_data {
*/
u64 group;
struct dentry *debugfs_group;
+
+ int power_level;
};
@@ -497,7 +499,7 @@ static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
rx_status.band = data->channel->band;
rx_status.rate_idx = info->control.rates[0].idx;
/* TODO: simulate real signal strength (and optional packet loss) */
- rx_status.signal = -50;
+ rx_status.signal = data->power_level - 50;
if (data->ps != PS_DISABLED)
hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
@@ -698,6 +700,7 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed)
data->idle = !!(conf->flags & IEEE80211_CONF_IDLE);
data->channel = conf->channel;
+ data->power_level = conf->power_level;
if (!data->started || !data->beacon_int)
del_timer(&data->beacon_timer);
else
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index f152a25be59f..9ecf8407cb1b 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -29,6 +29,12 @@
#define MWL8K_NAME KBUILD_MODNAME
#define MWL8K_VERSION "0.12"
+/* Module parameters */
+static unsigned ap_mode_default;
+module_param(ap_mode_default, bool, 0);
+MODULE_PARM_DESC(ap_mode_default,
+ "Set to 1 to make ap mode the default instead of sta mode");
+
/* Register definitions */
#define MWL8K_HIU_GEN_PTR 0x00000c10
#define MWL8K_MODE_STA 0x0000005a
@@ -92,8 +98,10 @@ struct rxd_ops {
struct mwl8k_device_info {
char *part_name;
char *helper_image;
- char *fw_image;
+ char *fw_image_sta;
+ char *fw_image_ap;
struct rxd_ops *ap_rxd_ops;
+ u32 fw_api_ap;
};
struct mwl8k_rx_queue {
@@ -136,8 +144,8 @@ struct mwl8k_priv {
void __iomem *regs;
/* firmware */
- struct firmware *fw_helper;
- struct firmware *fw_ucode;
+ const struct firmware *fw_helper;
+ const struct firmware *fw_ucode;
/* hardware/firmware parameters */
bool ap_fw;
@@ -210,6 +218,18 @@ struct mwl8k_priv {
/* Most recently reported noise in dBm */
s8 noise;
+
+ /*
+ * preserve the queue configurations so they can be restored if/when
+ * the firmware image is swapped.
+ */
+ struct ieee80211_tx_queue_params wmm_params[MWL8K_TX_QUEUES];
+
+ /* async firmware loading state */
+ unsigned fw_state;
+ char *fw_pref;
+ char *fw_alt;
+ struct completion firmware_loading_complete;
};
/* Per interface specific private data */
@@ -285,8 +305,9 @@ static const struct ieee80211_rate mwl8k_rates_50[] = {
};
/* Set or get info from Firmware */
-#define MWL8K_CMD_SET 0x0001
#define MWL8K_CMD_GET 0x0000
+#define MWL8K_CMD_SET 0x0001
+#define MWL8K_CMD_SET_LIST 0x0002
/* Firmware command codes */
#define MWL8K_CMD_CODE_DNLD 0x0001
@@ -296,6 +317,7 @@ static const struct ieee80211_rate mwl8k_rates_50[] = {
#define MWL8K_CMD_GET_STAT 0x0014
#define MWL8K_CMD_RADIO_CONTROL 0x001c
#define MWL8K_CMD_RF_TX_POWER 0x001e
+#define MWL8K_CMD_TX_POWER 0x001f
#define MWL8K_CMD_RF_ANTENNA 0x0020
#define MWL8K_CMD_SET_BEACON 0x0100 /* per-vif */
#define MWL8K_CMD_SET_PRE_SCAN 0x0107
@@ -333,6 +355,7 @@ static const char *mwl8k_cmd_name(__le16 cmd, char *buf, int bufsize)
MWL8K_CMDNAME(GET_STAT);
MWL8K_CMDNAME(RADIO_CONTROL);
MWL8K_CMDNAME(RF_TX_POWER);
+ MWL8K_CMDNAME(TX_POWER);
MWL8K_CMDNAME(RF_ANTENNA);
MWL8K_CMDNAME(SET_BEACON);
MWL8K_CMDNAME(SET_PRE_SCAN);
@@ -372,7 +395,7 @@ static void mwl8k_hw_reset(struct mwl8k_priv *priv)
}
/* Release fw image */
-static void mwl8k_release_fw(struct firmware **fw)
+static void mwl8k_release_fw(const struct firmware **fw)
{
if (*fw == NULL)
return;
@@ -386,37 +409,68 @@ static void mwl8k_release_firmware(struct mwl8k_priv *priv)
mwl8k_release_fw(&priv->fw_helper);
}
+/* states for asynchronous f/w loading */
+static void mwl8k_fw_state_machine(const struct firmware *fw, void *context);
+enum {
+ FW_STATE_INIT = 0,
+ FW_STATE_LOADING_PREF,
+ FW_STATE_LOADING_ALT,
+ FW_STATE_ERROR,
+};
+
/* Request fw image */
static int mwl8k_request_fw(struct mwl8k_priv *priv,
- const char *fname, struct firmware **fw)
+ const char *fname, const struct firmware **fw,
+ bool nowait)
{
/* release current image */
if (*fw != NULL)
mwl8k_release_fw(fw);
- return request_firmware((const struct firmware **)fw,
- fname, &priv->pdev->dev);
+ if (nowait)
+ return request_firmware_nowait(THIS_MODULE, 1, fname,
+ &priv->pdev->dev, GFP_KERNEL,
+ priv, mwl8k_fw_state_machine);
+ else
+ return request_firmware(fw, fname, &priv->pdev->dev);
}
-static int mwl8k_request_firmware(struct mwl8k_priv *priv)
+static int mwl8k_request_firmware(struct mwl8k_priv *priv, char *fw_image,
+ bool nowait)
{
struct mwl8k_device_info *di = priv->device_info;
int rc;
if (di->helper_image != NULL) {
- rc = mwl8k_request_fw(priv, di->helper_image, &priv->fw_helper);
- if (rc) {
- printk(KERN_ERR "%s: Error requesting helper "
- "firmware file %s\n", pci_name(priv->pdev),
- di->helper_image);
+ if (nowait)
+ rc = mwl8k_request_fw(priv, di->helper_image,
+ &priv->fw_helper, true);
+ else
+ rc = mwl8k_request_fw(priv, di->helper_image,
+ &priv->fw_helper, false);
+ if (rc)
+ printk(KERN_ERR "%s: Error requesting helper fw %s\n",
+ pci_name(priv->pdev), di->helper_image);
+
+ if (rc || nowait)
return rc;
- }
}
- rc = mwl8k_request_fw(priv, di->fw_image, &priv->fw_ucode);
+ if (nowait) {
+ /*
+ * if we get here, no helper image is needed. Skip the
+ * FW_STATE_INIT state.
+ */
+ priv->fw_state = FW_STATE_LOADING_PREF;
+ rc = mwl8k_request_fw(priv, fw_image,
+ &priv->fw_ucode,
+ true);
+ } else
+ rc = mwl8k_request_fw(priv, fw_image,
+ &priv->fw_ucode, false);
if (rc) {
printk(KERN_ERR "%s: Error requesting firmware file %s\n",
- pci_name(priv->pdev), di->fw_image);
+ pci_name(priv->pdev), fw_image);
mwl8k_release_fw(&priv->fw_helper);
return rc;
}
@@ -577,12 +631,12 @@ static int mwl8k_feed_fw_image(struct mwl8k_priv *priv,
static int mwl8k_load_firmware(struct ieee80211_hw *hw)
{
struct mwl8k_priv *priv = hw->priv;
- struct firmware *fw = priv->fw_ucode;
+ const struct firmware *fw = priv->fw_ucode;
int rc;
int loops;
if (!memcmp(fw->data, "\x01\x00\x00\x00", 4)) {
- struct firmware *helper = priv->fw_helper;
+ const struct firmware *helper = priv->fw_helper;
if (helper == NULL) {
printk(KERN_ERR "%s: helper image needed but none "
@@ -1811,6 +1865,7 @@ struct mwl8k_cmd_get_hw_spec_ap {
__le32 wcbbase1;
__le32 wcbbase2;
__le32 wcbbase3;
+ __le32 fw_api_version;
} __packed;
static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw)
@@ -1818,6 +1873,7 @@ static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw)
struct mwl8k_priv *priv = hw->priv;
struct mwl8k_cmd_get_hw_spec_ap *cmd;
int rc;
+ u32 api_version;
cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
if (cmd == NULL)
@@ -1834,6 +1890,16 @@ static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw)
if (!rc) {
int off;
+ api_version = le32_to_cpu(cmd->fw_api_version);
+ if (priv->device_info->fw_api_ap != api_version) {
+ printk(KERN_ERR "%s: Unsupported fw API version for %s."
+ " Expected %d got %d.\n", MWL8K_NAME,
+ priv->device_info->part_name,
+ priv->device_info->fw_api_ap,
+ api_version);
+ rc = -EINVAL;
+ goto done;
+ }
SET_IEEE80211_PERM_ADDR(hw, cmd->perm_addr);
priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs);
priv->fw_rev = le32_to_cpu(cmd->fw_rev);
@@ -1861,6 +1927,7 @@ static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw)
iowrite32(priv->txq[3].txd_dma, priv->sram + off);
}
+done:
kfree(cmd);
return rc;
}
@@ -2084,7 +2151,7 @@ mwl8k_set_radio_preamble(struct ieee80211_hw *hw, bool short_preamble)
/*
* CMD_RF_TX_POWER.
*/
-#define MWL8K_TX_POWER_LEVEL_TOTAL 8
+#define MWL8K_RF_TX_POWER_LEVEL_TOTAL 8
struct mwl8k_cmd_rf_tx_power {
struct mwl8k_cmd_pkt header;
@@ -2092,7 +2159,7 @@ struct mwl8k_cmd_rf_tx_power {
__le16 support_level;
__le16 current_level;
__le16 reserved;
- __le16 power_level_list[MWL8K_TX_POWER_LEVEL_TOTAL];
+ __le16 power_level_list[MWL8K_RF_TX_POWER_LEVEL_TOTAL];
} __packed;
static int mwl8k_cmd_rf_tx_power(struct ieee80211_hw *hw, int dBm)
@@ -2116,6 +2183,65 @@ static int mwl8k_cmd_rf_tx_power(struct ieee80211_hw *hw, int dBm)
}
/*
+ * CMD_TX_POWER.
+ */
+#define MWL8K_TX_POWER_LEVEL_TOTAL 12
+
+struct mwl8k_cmd_tx_power {
+ struct mwl8k_cmd_pkt header;
+ __le16 action;
+ __le16 band;
+ __le16 channel;
+ __le16 bw;
+ __le16 sub_ch;
+ __le16 power_level_list[MWL8K_TX_POWER_LEVEL_TOTAL];
+} __attribute__((packed));
+
+static int mwl8k_cmd_tx_power(struct ieee80211_hw *hw,
+ struct ieee80211_conf *conf,
+ unsigned short pwr)
+{
+ struct ieee80211_channel *channel = conf->channel;
+ struct mwl8k_cmd_tx_power *cmd;
+ int rc;
+ int i;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_TX_POWER);
+ cmd->header.length = cpu_to_le16(sizeof(*cmd));
+ cmd->action = cpu_to_le16(MWL8K_CMD_SET_LIST);
+
+ if (channel->band == IEEE80211_BAND_2GHZ)
+ cmd->band = cpu_to_le16(0x1);
+ else if (channel->band == IEEE80211_BAND_5GHZ)
+ cmd->band = cpu_to_le16(0x4);
+
+ cmd->channel = channel->hw_value;
+
+ if (conf->channel_type == NL80211_CHAN_NO_HT ||
+ conf->channel_type == NL80211_CHAN_HT20) {
+ cmd->bw = cpu_to_le16(0x2);
+ } else {
+ cmd->bw = cpu_to_le16(0x4);
+ if (conf->channel_type == NL80211_CHAN_HT40MINUS)
+ cmd->sub_ch = cpu_to_le16(0x3);
+ else if (conf->channel_type == NL80211_CHAN_HT40PLUS)
+ cmd->sub_ch = cpu_to_le16(0x1);
+ }
+
+ for (i = 0; i < MWL8K_TX_POWER_LEVEL_TOTAL; i++)
+ cmd->power_level_list[i] = cpu_to_le16(pwr);
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+ kfree(cmd);
+
+ return rc;
+}
+
+/*
* CMD_RF_ANTENNA.
*/
struct mwl8k_cmd_rf_antenna {
@@ -3283,13 +3409,16 @@ static void mwl8k_stop(struct ieee80211_hw *hw)
mwl8k_txq_reclaim(hw, i, INT_MAX, 1);
}
+static int mwl8k_reload_firmware(struct ieee80211_hw *hw, char *fw_image);
+
static int mwl8k_add_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct mwl8k_priv *priv = hw->priv;
struct mwl8k_vif *mwl8k_vif;
u32 macids_supported;
- int macid;
+ int macid, rc;
+ struct mwl8k_device_info *di;
/*
* Reject interface creation if sniffer mode is active, as
@@ -3302,12 +3431,28 @@ static int mwl8k_add_interface(struct ieee80211_hw *hw,
return -EINVAL;
}
-
+ di = priv->device_info;
switch (vif->type) {
case NL80211_IFTYPE_AP:
+ if (!priv->ap_fw && di->fw_image_ap) {
+ /* we must load the ap fw to meet this request */
+ if (!list_empty(&priv->vif_list))
+ return -EBUSY;
+ rc = mwl8k_reload_firmware(hw, di->fw_image_ap);
+ if (rc)
+ return rc;
+ }
macids_supported = priv->ap_macids_supported;
break;
case NL80211_IFTYPE_STATION:
+ if (priv->ap_fw && di->fw_image_sta) {
+ /* we must load the sta fw to meet this request */
+ if (!list_empty(&priv->vif_list))
+ return -EBUSY;
+ rc = mwl8k_reload_firmware(hw, di->fw_image_sta);
+ if (rc)
+ return rc;
+ }
macids_supported = priv->sta_macids_supported;
break;
default:
@@ -3377,15 +3522,19 @@ static int mwl8k_config(struct ieee80211_hw *hw, u32 changed)
if (conf->power_level > 18)
conf->power_level = 18;
- rc = mwl8k_cmd_rf_tx_power(hw, conf->power_level);
- if (rc)
- goto out;
if (priv->ap_fw) {
+ rc = mwl8k_cmd_tx_power(hw, conf, conf->power_level);
+ if (rc)
+ goto out;
+
rc = mwl8k_cmd_rf_antenna(hw, MWL8K_RF_ANTENNA_RX, 0x7);
if (!rc)
rc = mwl8k_cmd_rf_antenna(hw, MWL8K_RF_ANTENNA_TX, 0x7);
} else {
+ rc = mwl8k_cmd_rf_tx_power(hw, conf->power_level);
+ if (rc)
+ goto out;
rc = mwl8k_cmd_mimo_config(hw, 0x7, 0x7);
}
@@ -3739,6 +3888,9 @@ static int mwl8k_conf_tx(struct ieee80211_hw *hw, u16 queue,
rc = mwl8k_fw_lock(hw);
if (!rc) {
+ BUG_ON(queue > MWL8K_TX_QUEUES - 1);
+ memcpy(&priv->wmm_params[queue], params, sizeof(*params));
+
if (!priv->wmm_enabled)
rc = mwl8k_cmd_set_wmm_mode(hw, 1);
@@ -3838,21 +3990,27 @@ enum {
MWL8366,
};
+#define MWL8K_8366_AP_FW_API 1
+#define _MWL8K_8366_AP_FW(api) "mwl8k/fmimage_8366_ap-" #api ".fw"
+#define MWL8K_8366_AP_FW(api) _MWL8K_8366_AP_FW(api)
+
static struct mwl8k_device_info mwl8k_info_tbl[] __devinitdata = {
[MWL8363] = {
.part_name = "88w8363",
.helper_image = "mwl8k/helper_8363.fw",
- .fw_image = "mwl8k/fmimage_8363.fw",
+ .fw_image_sta = "mwl8k/fmimage_8363.fw",
},
[MWL8687] = {
.part_name = "88w8687",
.helper_image = "mwl8k/helper_8687.fw",
- .fw_image = "mwl8k/fmimage_8687.fw",
+ .fw_image_sta = "mwl8k/fmimage_8687.fw",
},
[MWL8366] = {
.part_name = "88w8366",
.helper_image = "mwl8k/helper_8366.fw",
- .fw_image = "mwl8k/fmimage_8366.fw",
+ .fw_image_sta = "mwl8k/fmimage_8366.fw",
+ .fw_image_ap = MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API),
+ .fw_api_ap = MWL8K_8366_AP_FW_API,
.ap_rxd_ops = &rxd_8366_ap_ops,
},
};
@@ -3863,6 +4021,7 @@ MODULE_FIRMWARE("mwl8k/helper_8687.fw");
MODULE_FIRMWARE("mwl8k/fmimage_8687.fw");
MODULE_FIRMWARE("mwl8k/helper_8366.fw");
MODULE_FIRMWARE("mwl8k/fmimage_8366.fw");
+MODULE_FIRMWARE(MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API));
static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = {
{ PCI_VDEVICE(MARVELL, 0x2a0a), .driver_data = MWL8363, },
@@ -3876,94 +4035,133 @@ static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = {
};
MODULE_DEVICE_TABLE(pci, mwl8k_pci_id_table);
-static int __devinit mwl8k_probe(struct pci_dev *pdev,
- const struct pci_device_id *id)
+static int mwl8k_request_alt_fw(struct mwl8k_priv *priv)
{
- static int printed_version = 0;
- struct ieee80211_hw *hw;
- struct mwl8k_priv *priv;
int rc;
- int i;
-
- if (!printed_version) {
- printk(KERN_INFO "%s version %s\n", MWL8K_DESC, MWL8K_VERSION);
- printed_version = 1;
- }
-
-
- rc = pci_enable_device(pdev);
+ printk(KERN_ERR "%s: Error requesting preferred fw %s.\n"
+ "Trying alternative firmware %s\n", pci_name(priv->pdev),
+ priv->fw_pref, priv->fw_alt);
+ rc = mwl8k_request_fw(priv, priv->fw_alt, &priv->fw_ucode, true);
if (rc) {
- printk(KERN_ERR "%s: Cannot enable new PCI device\n",
- MWL8K_NAME);
+ printk(KERN_ERR "%s: Error requesting alt fw %s\n",
+ pci_name(priv->pdev), priv->fw_alt);
return rc;
}
+ return 0;
+}
- rc = pci_request_regions(pdev, MWL8K_NAME);
- if (rc) {
- printk(KERN_ERR "%s: Cannot obtain PCI resources\n",
- MWL8K_NAME);
- goto err_disable_device;
- }
-
- pci_set_master(pdev);
-
-
- hw = ieee80211_alloc_hw(sizeof(*priv), &mwl8k_ops);
- if (hw == NULL) {
- printk(KERN_ERR "%s: ieee80211 alloc failed\n", MWL8K_NAME);
- rc = -ENOMEM;
- goto err_free_reg;
- }
+static int mwl8k_firmware_load_success(struct mwl8k_priv *priv);
+static void mwl8k_fw_state_machine(const struct firmware *fw, void *context)
+{
+ struct mwl8k_priv *priv = context;
+ struct mwl8k_device_info *di = priv->device_info;
+ int rc;
- SET_IEEE80211_DEV(hw, &pdev->dev);
- pci_set_drvdata(pdev, hw);
+ switch (priv->fw_state) {
+ case FW_STATE_INIT:
+ if (!fw) {
+ printk(KERN_ERR "%s: Error requesting helper fw %s\n",
+ pci_name(priv->pdev), di->helper_image);
+ goto fail;
+ }
+ priv->fw_helper = fw;
+ rc = mwl8k_request_fw(priv, priv->fw_pref, &priv->fw_ucode,
+ true);
+ if (rc && priv->fw_alt) {
+ rc = mwl8k_request_alt_fw(priv);
+ if (rc)
+ goto fail;
+ priv->fw_state = FW_STATE_LOADING_ALT;
+ } else if (rc)
+ goto fail;
+ else
+ priv->fw_state = FW_STATE_LOADING_PREF;
+ break;
- priv = hw->priv;
- priv->hw = hw;
- priv->pdev = pdev;
- priv->device_info = &mwl8k_info_tbl[id->driver_data];
+ case FW_STATE_LOADING_PREF:
+ if (!fw) {
+ if (priv->fw_alt) {
+ rc = mwl8k_request_alt_fw(priv);
+ if (rc)
+ goto fail;
+ priv->fw_state = FW_STATE_LOADING_ALT;
+ } else
+ goto fail;
+ } else {
+ priv->fw_ucode = fw;
+ rc = mwl8k_firmware_load_success(priv);
+ if (rc)
+ goto fail;
+ else
+ complete(&priv->firmware_loading_complete);
+ }
+ break;
+ case FW_STATE_LOADING_ALT:
+ if (!fw) {
+ printk(KERN_ERR "%s: Error requesting alt fw %s\n",
+ pci_name(priv->pdev), di->helper_image);
+ goto fail;
+ }
+ priv->fw_ucode = fw;
+ rc = mwl8k_firmware_load_success(priv);
+ if (rc)
+ goto fail;
+ else
+ complete(&priv->firmware_loading_complete);
+ break;
- priv->sram = pci_iomap(pdev, 0, 0x10000);
- if (priv->sram == NULL) {
- wiphy_err(hw->wiphy, "Cannot map device SRAM\n");
- goto err_iounmap;
+ default:
+ printk(KERN_ERR "%s: Unexpected firmware loading state: %d\n",
+ MWL8K_NAME, priv->fw_state);
+ BUG_ON(1);
}
- /*
- * If BAR0 is a 32 bit BAR, the register BAR will be BAR1.
- * If BAR0 is a 64 bit BAR, the register BAR will be BAR2.
- */
- priv->regs = pci_iomap(pdev, 1, 0x10000);
- if (priv->regs == NULL) {
- priv->regs = pci_iomap(pdev, 2, 0x10000);
- if (priv->regs == NULL) {
- wiphy_err(hw->wiphy, "Cannot map device registers\n");
- goto err_iounmap;
- }
- }
+ return;
+fail:
+ priv->fw_state = FW_STATE_ERROR;
+ complete(&priv->firmware_loading_complete);
+ device_release_driver(&priv->pdev->dev);
+ mwl8k_release_firmware(priv);
+}
+
+static int mwl8k_init_firmware(struct ieee80211_hw *hw, char *fw_image,
+ bool nowait)
+{
+ struct mwl8k_priv *priv = hw->priv;
+ int rc;
/* Reset firmware and hardware */
mwl8k_hw_reset(priv);
/* Ask userland hotplug daemon for the device firmware */
- rc = mwl8k_request_firmware(priv);
+ rc = mwl8k_request_firmware(priv, fw_image, nowait);
if (rc) {
wiphy_err(hw->wiphy, "Firmware files not found\n");
- goto err_stop_firmware;
+ return rc;
}
+ if (nowait)
+ return rc;
+
/* Load firmware into hardware */
rc = mwl8k_load_firmware(hw);
- if (rc) {
+ if (rc)
wiphy_err(hw->wiphy, "Cannot start firmware\n");
- goto err_stop_firmware;
- }
/* Reclaim memory once firmware is successfully loaded */
mwl8k_release_firmware(priv);
+ return rc;
+}
+
+/* initialize hw after successfully loading a firmware image */
+static int mwl8k_probe_hw(struct ieee80211_hw *hw)
+{
+ struct mwl8k_priv *priv = hw->priv;
+ int rc = 0;
+ int i;
if (priv->ap_fw) {
priv->rxd_ops = priv->device_info->ap_rxd_ops;
@@ -3980,58 +4178,11 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
priv->wmm_enabled = false;
priv->pending_tx_pkts = 0;
-
- /*
- * Extra headroom is the size of the required DMA header
- * minus the size of the smallest 802.11 frame (CTS frame).
- */
- hw->extra_tx_headroom =
- sizeof(struct mwl8k_dma_data) - sizeof(struct ieee80211_cts);
-
- hw->channel_change_time = 10;
-
- hw->queues = MWL8K_TX_QUEUES;
-
- /* Set rssi values to dBm */
- hw->flags |= IEEE80211_HW_SIGNAL_DBM;
- hw->vif_data_size = sizeof(struct mwl8k_vif);
- hw->sta_data_size = sizeof(struct mwl8k_sta);
-
- priv->macids_used = 0;
- INIT_LIST_HEAD(&priv->vif_list);
-
- /* Set default radio state and preamble */
- priv->radio_on = 0;
- priv->radio_short_preamble = 0;
-
- /* Finalize join worker */
- INIT_WORK(&priv->finalize_join_worker, mwl8k_finalize_join_worker);
-
- /* TX reclaim and RX tasklets. */
- tasklet_init(&priv->poll_tx_task, mwl8k_tx_poll, (unsigned long)hw);
- tasklet_disable(&priv->poll_tx_task);
- tasklet_init(&priv->poll_rx_task, mwl8k_rx_poll, (unsigned long)hw);
- tasklet_disable(&priv->poll_rx_task);
-
- /* Power management cookie */
- priv->cookie = pci_alloc_consistent(priv->pdev, 4, &priv->cookie_dma);
- if (priv->cookie == NULL)
- goto err_stop_firmware;
-
rc = mwl8k_rxq_init(hw, 0);
if (rc)
- goto err_free_cookie;
+ goto err_stop_firmware;
rxq_refill(hw, 0, INT_MAX);
- mutex_init(&priv->fw_mutex);
- priv->fw_mutex_owner = NULL;
- priv->fw_mutex_depth = 0;
- priv->hostcmd_wait = NULL;
-
- spin_lock_init(&priv->tx_lock);
-
- priv->tx_wait = NULL;
-
for (i = 0; i < MWL8K_TX_QUEUES; i++) {
rc = mwl8k_txq_init(hw, i);
if (rc)
@@ -4071,13 +4222,6 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
goto err_free_irq;
}
- hw->wiphy->interface_modes = 0;
- if (priv->ap_macids_supported)
- hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP);
- if (priv->sta_macids_supported)
- hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_STATION);
-
-
/* Turn radio off */
rc = mwl8k_cmd_radio_disable(hw);
if (rc) {
@@ -4096,12 +4240,6 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
free_irq(priv->pdev->irq, hw);
- rc = ieee80211_register_hw(hw);
- if (rc) {
- wiphy_err(hw->wiphy, "Cannot register device\n");
- goto err_free_queues;
- }
-
wiphy_info(hw->wiphy, "%s v%d, %pm, %s firmware %u.%u.%u.%u\n",
priv->device_info->part_name,
priv->hw_rev, hw->wiphy->perm_addr,
@@ -4120,14 +4258,238 @@ err_free_queues:
mwl8k_txq_deinit(hw, i);
mwl8k_rxq_deinit(hw, 0);
+err_stop_firmware:
+ mwl8k_hw_reset(priv);
+
+ return rc;
+}
+
+/*
+ * invoke mwl8k_reload_firmware to change the firmware image after the device
+ * has already been registered
+ */
+static int mwl8k_reload_firmware(struct ieee80211_hw *hw, char *fw_image)
+{
+ int i, rc = 0;
+ struct mwl8k_priv *priv = hw->priv;
+
+ mwl8k_stop(hw);
+ mwl8k_rxq_deinit(hw, 0);
+
+ for (i = 0; i < MWL8K_TX_QUEUES; i++)
+ mwl8k_txq_deinit(hw, i);
+
+ rc = mwl8k_init_firmware(hw, fw_image, false);
+ if (rc)
+ goto fail;
+
+ rc = mwl8k_probe_hw(hw);
+ if (rc)
+ goto fail;
+
+ rc = mwl8k_start(hw);
+ if (rc)
+ goto fail;
+
+ rc = mwl8k_config(hw, ~0);
+ if (rc)
+ goto fail;
+
+ for (i = 0; i < MWL8K_TX_QUEUES; i++) {
+ rc = mwl8k_conf_tx(hw, i, &priv->wmm_params[i]);
+ if (rc)
+ goto fail;
+ }
+
+ return rc;
+
+fail:
+ printk(KERN_WARNING "mwl8k: Failed to reload firmware image.\n");
+ return rc;
+}
+
+static int mwl8k_firmware_load_success(struct mwl8k_priv *priv)
+{
+ struct ieee80211_hw *hw = priv->hw;
+ int i, rc;
+
+ rc = mwl8k_load_firmware(hw);
+ mwl8k_release_firmware(priv);
+ if (rc) {
+ wiphy_err(hw->wiphy, "Cannot start firmware\n");
+ return rc;
+ }
+
+ /*
+ * Extra headroom is the size of the required DMA header
+ * minus the size of the smallest 802.11 frame (CTS frame).
+ */
+ hw->extra_tx_headroom =
+ sizeof(struct mwl8k_dma_data) - sizeof(struct ieee80211_cts);
+
+ hw->channel_change_time = 10;
+
+ hw->queues = MWL8K_TX_QUEUES;
+
+ /* Set rssi values to dBm */
+ hw->flags |= IEEE80211_HW_SIGNAL_DBM;
+ hw->vif_data_size = sizeof(struct mwl8k_vif);
+ hw->sta_data_size = sizeof(struct mwl8k_sta);
+
+ priv->macids_used = 0;
+ INIT_LIST_HEAD(&priv->vif_list);
+
+ /* Set default radio state and preamble */
+ priv->radio_on = 0;
+ priv->radio_short_preamble = 0;
+
+ /* Finalize join worker */
+ INIT_WORK(&priv->finalize_join_worker, mwl8k_finalize_join_worker);
+
+ /* TX reclaim and RX tasklets. */
+ tasklet_init(&priv->poll_tx_task, mwl8k_tx_poll, (unsigned long)hw);
+ tasklet_disable(&priv->poll_tx_task);
+ tasklet_init(&priv->poll_rx_task, mwl8k_rx_poll, (unsigned long)hw);
+ tasklet_disable(&priv->poll_rx_task);
+
+ /* Power management cookie */
+ priv->cookie = pci_alloc_consistent(priv->pdev, 4, &priv->cookie_dma);
+ if (priv->cookie == NULL)
+ return -ENOMEM;
+
+ mutex_init(&priv->fw_mutex);
+ priv->fw_mutex_owner = NULL;
+ priv->fw_mutex_depth = 0;
+ priv->hostcmd_wait = NULL;
+
+ spin_lock_init(&priv->tx_lock);
+
+ priv->tx_wait = NULL;
+
+ rc = mwl8k_probe_hw(hw);
+ if (rc)
+ goto err_free_cookie;
+
+ hw->wiphy->interface_modes = 0;
+ if (priv->ap_macids_supported || priv->device_info->fw_image_ap)
+ hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP);
+ if (priv->sta_macids_supported || priv->device_info->fw_image_sta)
+ hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_STATION);
+
+ rc = ieee80211_register_hw(hw);
+ if (rc) {
+ wiphy_err(hw->wiphy, "Cannot register device\n");
+ goto err_unprobe_hw;
+ }
+
+ return 0;
+
+err_unprobe_hw:
+ for (i = 0; i < MWL8K_TX_QUEUES; i++)
+ mwl8k_txq_deinit(hw, i);
+ mwl8k_rxq_deinit(hw, 0);
+
err_free_cookie:
if (priv->cookie != NULL)
pci_free_consistent(priv->pdev, 4,
priv->cookie, priv->cookie_dma);
+ return rc;
+}
+static int __devinit mwl8k_probe(struct pci_dev *pdev,
+ const struct pci_device_id *id)
+{
+ static int printed_version;
+ struct ieee80211_hw *hw;
+ struct mwl8k_priv *priv;
+ struct mwl8k_device_info *di;
+ int rc;
+
+ if (!printed_version) {
+ printk(KERN_INFO "%s version %s\n", MWL8K_DESC, MWL8K_VERSION);
+ printed_version = 1;
+ }
+
+
+ rc = pci_enable_device(pdev);
+ if (rc) {
+ printk(KERN_ERR "%s: Cannot enable new PCI device\n",
+ MWL8K_NAME);
+ return rc;
+ }
+
+ rc = pci_request_regions(pdev, MWL8K_NAME);
+ if (rc) {
+ printk(KERN_ERR "%s: Cannot obtain PCI resources\n",
+ MWL8K_NAME);
+ goto err_disable_device;
+ }
+
+ pci_set_master(pdev);
+
+
+ hw = ieee80211_alloc_hw(sizeof(*priv), &mwl8k_ops);
+ if (hw == NULL) {
+ printk(KERN_ERR "%s: ieee80211 alloc failed\n", MWL8K_NAME);
+ rc = -ENOMEM;
+ goto err_free_reg;
+ }
+
+ SET_IEEE80211_DEV(hw, &pdev->dev);
+ pci_set_drvdata(pdev, hw);
+
+ priv = hw->priv;
+ priv->hw = hw;
+ priv->pdev = pdev;
+ priv->device_info = &mwl8k_info_tbl[id->driver_data];
+
+
+ priv->sram = pci_iomap(pdev, 0, 0x10000);
+ if (priv->sram == NULL) {
+ wiphy_err(hw->wiphy, "Cannot map device SRAM\n");
+ goto err_iounmap;
+ }
+
+ /*
+ * If BAR0 is a 32 bit BAR, the register BAR will be BAR1.
+ * If BAR0 is a 64 bit BAR, the register BAR will be BAR2.
+ */
+ priv->regs = pci_iomap(pdev, 1, 0x10000);
+ if (priv->regs == NULL) {
+ priv->regs = pci_iomap(pdev, 2, 0x10000);
+ if (priv->regs == NULL) {
+ wiphy_err(hw->wiphy, "Cannot map device registers\n");
+ goto err_iounmap;
+ }
+ }
+
+ /*
+ * Choose the initial fw image depending on user input. If a second
+ * image is available, make it the alternative image that will be
+ * loaded if the first one fails.
+ */
+ init_completion(&priv->firmware_loading_complete);
+ di = priv->device_info;
+ if (ap_mode_default && di->fw_image_ap) {
+ priv->fw_pref = di->fw_image_ap;
+ priv->fw_alt = di->fw_image_sta;
+ } else if (!ap_mode_default && di->fw_image_sta) {
+ priv->fw_pref = di->fw_image_sta;
+ priv->fw_alt = di->fw_image_ap;
+ } else if (ap_mode_default && !di->fw_image_ap && di->fw_image_sta) {
+ printk(KERN_WARNING "AP fw is unavailable. Using STA fw.");
+ priv->fw_pref = di->fw_image_sta;
+ } else if (!ap_mode_default && !di->fw_image_sta && di->fw_image_ap) {
+ printk(KERN_WARNING "STA fw is unavailable. Using AP fw.");
+ priv->fw_pref = di->fw_image_ap;
+ }
+ rc = mwl8k_init_firmware(hw, priv->fw_pref, true);
+ if (rc)
+ goto err_stop_firmware;
+ return rc;
+
err_stop_firmware:
mwl8k_hw_reset(priv);
- mwl8k_release_firmware(priv);
err_iounmap:
if (priv->regs != NULL)
@@ -4163,6 +4525,13 @@ static void __devexit mwl8k_remove(struct pci_dev *pdev)
return;
priv = hw->priv;
+ wait_for_completion(&priv->firmware_loading_complete);
+
+ if (priv->fw_state == FW_STATE_ERROR) {
+ mwl8k_hw_reset(priv);
+ goto unmap;
+ }
+
ieee80211_stop_queues(hw);
ieee80211_unregister_hw(hw);
@@ -4185,6 +4554,7 @@ static void __devexit mwl8k_remove(struct pci_dev *pdev)
pci_free_consistent(priv->pdev, 4, priv->cookie, priv->cookie_dma);
+unmap:
pci_iounmap(pdev, priv->regs);
pci_iounmap(pdev, priv->sram);
pci_set_drvdata(pdev, NULL);
diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c
index e5afabee60d1..e793679e2e19 100644
--- a/drivers/net/wireless/orinoco/wext.c
+++ b/drivers/net/wireless/orinoco/wext.c
@@ -893,6 +893,14 @@ static int orinoco_ioctl_set_auth(struct net_device *dev,
*/
break;
+ case IW_AUTH_MFP:
+ /* Management Frame Protection not supported.
+ * Only fail if set to required.
+ */
+ if (param->value == IW_AUTH_MFP_REQUIRED)
+ ret = -EINVAL;
+ break;
+
case IW_AUTH_KEY_MGMT:
/* wl_lkm implies value 2 == PSK for Hermes I
* which ties in with WEXT
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
index d5bc21e5a02c..dd4d8fc9ad7a 100644
--- a/drivers/net/wireless/p54/p54usb.c
+++ b/drivers/net/wireless/p54/p54usb.c
@@ -183,7 +183,7 @@ static void p54u_rx_cb(struct urb *urb)
static void p54u_tx_cb(struct urb *urb)
{
struct sk_buff *skb = urb->context;
- struct ieee80211_hw *dev = (struct ieee80211_hw *)
+ struct ieee80211_hw *dev =
usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
p54_free_skb(dev, skb);
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index 97007d9e2c1f..0764d1a30d13 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -1776,11 +1776,8 @@ static void ray_update_multi_list(struct net_device *dev, int all)
/* Copy the kernel's list of MC addresses to card */
netdev_for_each_mc_addr(ha, dev) {
memcpy_toio(p, ha->addr, ETH_ALEN);
- dev_dbg(&link->dev,
- "ray_update_multi add addr %02x%02x%02x%02x%02x%02x\n",
- ha->addr[0], ha->addr[1],
- ha->addr[2], ha->addr[3],
- ha->addr[4], ha->addr[5]);
+ dev_dbg(&link->dev, "ray_update_multi add addr %pm\n",
+ ha->addr);
p += ETH_ALEN;
i++;
}
@@ -2015,11 +2012,8 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id)
memcpy_fromio(&local->bss_id,
prcs->var.rejoin_net_complete.
bssid, ADDRLEN);
- dev_dbg(&link->dev,
- "ray_cs new BSSID = %02x%02x%02x%02x%02x%02x\n",
- local->bss_id[0], local->bss_id[1],
- local->bss_id[2], local->bss_id[3],
- local->bss_id[4], local->bss_id[5]);
+ dev_dbg(&link->dev, "ray_cs new BSSID = %pm\n",
+ local->bss_id);
if (!sniffer)
authenticate(local);
}
@@ -2286,8 +2280,8 @@ static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len)
struct ethhdr *peth;
UCHAR srcaddr[ADDRLEN];
UCHAR destaddr[ADDRLEN];
- static UCHAR org_bridge[3] = { 0, 0, 0xf8 };
- static UCHAR org_1042[3] = { 0, 0, 0 };
+ static const UCHAR org_bridge[3] = { 0, 0, 0xf8 };
+ static const UCHAR org_1042[3] = { 0, 0, 0 };
memcpy(destaddr, ieee80211_get_DA(pmac), ADDRLEN);
memcpy(srcaddr, ieee80211_get_SA(pmac), ADDRLEN);
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 71b5971da597..19f3d568f700 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -156,6 +156,12 @@ MODULE_PARM_DESC(workaround_interval,
#define RNDIS_STATUS_ADAPTER_NOT_OPEN cpu_to_le32(0xc0010012)
+/* Known device types */
+#define RNDIS_UNKNOWN 0
+#define RNDIS_BCM4320A 1
+#define RNDIS_BCM4320B 2
+
+
/* NDIS data structures. Taken from wpa_supplicant driver_ndis.c
* slightly modified for datatype endianess, etc
*/
@@ -478,6 +484,7 @@ struct rndis_wlan_private {
struct ieee80211_rate rates[ARRAY_SIZE(rndis_rates)];
u32 cipher_suites[ARRAY_SIZE(rndis_cipher_suites)];
+ int device_type;
int caps;
int multicast_size;
@@ -810,7 +817,8 @@ exit_unlock:
return ret;
}
-static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len)
+static int rndis_set_oid(struct usbnet *dev, __le32 oid, const void *data,
+ int len)
{
struct rndis_wlan_private *priv = get_rndis_wlan_priv(dev);
union {
@@ -994,7 +1002,18 @@ static int level_to_qual(int level)
*/
static int set_infra_mode(struct usbnet *usbdev, int mode);
static void restore_keys(struct usbnet *usbdev);
-static int rndis_check_bssid_list(struct usbnet *usbdev);
+static int rndis_check_bssid_list(struct usbnet *usbdev, u8 *match_bssid,
+ bool *matched);
+
+static int rndis_start_bssid_list_scan(struct usbnet *usbdev)
+{
+ __le32 tmp;
+
+ /* Note: OID_802_11_BSSID_LIST_SCAN clears internal BSS list. */
+ tmp = cpu_to_le32(1);
+ return rndis_set_oid(usbdev, OID_802_11_BSSID_LIST_SCAN, &tmp,
+ sizeof(tmp));
+}
static int set_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid)
{
@@ -1015,7 +1034,7 @@ static int set_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid)
return ret;
}
-static int set_bssid(struct usbnet *usbdev, u8 bssid[ETH_ALEN])
+static int set_bssid(struct usbnet *usbdev, const u8 *bssid)
{
int ret;
@@ -1031,7 +1050,9 @@ static int set_bssid(struct usbnet *usbdev, u8 bssid[ETH_ALEN])
static int clear_bssid(struct usbnet *usbdev)
{
- u8 broadcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+ static const u8 broadcast_mac[ETH_ALEN] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+ };
return set_bssid(usbdev, broadcast_mac);
}
@@ -1904,14 +1925,14 @@ static int rndis_scan(struct wiphy *wiphy, struct net_device *dev,
struct usbnet *usbdev = netdev_priv(dev);
struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
int ret;
- __le32 tmp;
+ int delay = SCAN_DELAY_JIFFIES;
netdev_dbg(usbdev->net, "cfg80211.scan\n");
/* Get current bssid list from device before new scan, as new scan
* clears internal bssid list.
*/
- rndis_check_bssid_list(usbdev);
+ rndis_check_bssid_list(usbdev, NULL, NULL);
if (!request)
return -EINVAL;
@@ -1921,13 +1942,13 @@ static int rndis_scan(struct wiphy *wiphy, struct net_device *dev,
priv->scan_request = request;
- tmp = cpu_to_le32(1);
- ret = rndis_set_oid(usbdev, OID_802_11_BSSID_LIST_SCAN, &tmp,
- sizeof(tmp));
+ ret = rndis_start_bssid_list_scan(usbdev);
if (ret == 0) {
+ if (priv->device_type == RNDIS_BCM4320A)
+ delay = HZ;
+
/* Wait before retrieving scan results from device */
- queue_delayed_work(priv->workqueue, &priv->scan_work,
- SCAN_DELAY_JIFFIES);
+ queue_delayed_work(priv->workqueue, &priv->scan_work, delay);
}
return ret;
@@ -1981,7 +2002,8 @@ static struct cfg80211_bss *rndis_bss_info_update(struct usbnet *usbdev,
GFP_KERNEL);
}
-static int rndis_check_bssid_list(struct usbnet *usbdev)
+static int rndis_check_bssid_list(struct usbnet *usbdev, u8 *match_bssid,
+ bool *matched)
{
void *buf = NULL;
struct ndis_80211_bssid_list_ex *bssid_list;
@@ -2017,7 +2039,11 @@ resize_buf:
count, len);
while (count && ((void *)bssid + bssid_len) <= (buf + len)) {
- rndis_bss_info_update(usbdev, bssid);
+ if (rndis_bss_info_update(usbdev, bssid) && match_bssid &&
+ matched) {
+ if (compare_ether_addr(bssid->mac, match_bssid))
+ *matched = true;
+ }
bssid = (void *)bssid + bssid_len;
bssid_len = le32_to_cpu(bssid->length);
@@ -2041,7 +2067,7 @@ static void rndis_get_scan_results(struct work_struct *work)
if (!priv->scan_request)
return;
- ret = rndis_check_bssid_list(usbdev);
+ ret = rndis_check_bssid_list(usbdev, NULL, NULL);
cfg80211_scan_done(priv->scan_request, ret < 0);
@@ -2495,6 +2521,91 @@ static int rndis_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
return rndis_set_oid(usbdev, OID_802_11_PMKID, &pmkid, sizeof(pmkid));
}
+static void rndis_wlan_craft_connected_bss(struct usbnet *usbdev, u8 *bssid,
+ struct ndis_80211_assoc_info *info)
+{
+ struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
+ struct ieee80211_channel *channel;
+ struct ndis_80211_conf config;
+ struct ndis_80211_ssid ssid;
+ s32 signal;
+ u64 timestamp;
+ u16 capability;
+ u16 beacon_interval;
+ __le32 rssi;
+ u8 ie_buf[34];
+ int len, ret, ie_len;
+
+ /* Get signal quality, in case of error use rssi=0 and ignore error. */
+ len = sizeof(rssi);
+ rssi = 0;
+ ret = rndis_query_oid(usbdev, OID_802_11_RSSI, &rssi, &len);
+ signal = level_to_qual(le32_to_cpu(rssi));
+
+ netdev_dbg(usbdev->net, "%s(): OID_802_11_RSSI -> %d, "
+ "rssi:%d, qual: %d\n", __func__, ret, le32_to_cpu(rssi),
+ level_to_qual(le32_to_cpu(rssi)));
+
+ /* Get AP capabilities */
+ if (info) {
+ capability = le16_to_cpu(info->resp_ie.capa);
+ } else {
+ /* Set atleast ESS/IBSS capability */
+ capability = (priv->infra_mode == NDIS_80211_INFRA_INFRA) ?
+ WLAN_CAPABILITY_ESS : WLAN_CAPABILITY_IBSS;
+ }
+
+ /* Get channel and beacon interval */
+ len = sizeof(config);
+ ret = rndis_query_oid(usbdev, OID_802_11_CONFIGURATION, &config, &len);
+ netdev_dbg(usbdev->net, "%s(): OID_802_11_CONFIGURATION -> %d\n",
+ __func__, ret);
+ if (ret >= 0) {
+ beacon_interval = le16_to_cpu(config.beacon_period);
+ channel = ieee80211_get_channel(priv->wdev.wiphy,
+ KHZ_TO_MHZ(le32_to_cpu(config.ds_config)));
+ if (!channel) {
+ netdev_warn(usbdev->net, "%s(): could not get channel."
+ "\n", __func__);
+ return;
+ }
+ } else {
+ netdev_warn(usbdev->net, "%s(): could not get configuration.\n",
+ __func__);
+ return;
+ }
+
+ /* Get SSID, in case of error, use zero length SSID and ignore error. */
+ len = sizeof(ssid);
+ memset(&ssid, 0, sizeof(ssid));
+ ret = rndis_query_oid(usbdev, OID_802_11_SSID, &ssid, &len);
+ netdev_dbg(usbdev->net, "%s(): OID_802_11_SSID -> %d, len: %d, ssid: "
+ "'%.32s'\n", __func__, ret,
+ le32_to_cpu(ssid.length), ssid.essid);
+
+ if (le32_to_cpu(ssid.length) > 32)
+ ssid.length = cpu_to_le32(32);
+
+ ie_buf[0] = WLAN_EID_SSID;
+ ie_buf[1] = le32_to_cpu(ssid.length);
+ memcpy(&ie_buf[2], ssid.essid, le32_to_cpu(ssid.length));
+
+ ie_len = le32_to_cpu(ssid.length) + 2;
+
+ /* no tsf */
+ timestamp = 0;
+
+ netdev_dbg(usbdev->net, "%s(): channel:%d(freq), bssid:[%pM], tsf:%d, "
+ "capa:%x, beacon int:%d, resp_ie(len:%d, essid:'%.32s'), "
+ "signal:%d\n", __func__, (channel ? channel->center_freq : -1),
+ bssid, (u32)timestamp, capability, beacon_interval, ie_len,
+ ssid.essid, signal);
+
+ cfg80211_inform_bss(priv->wdev.wiphy, channel, bssid,
+ timestamp, capability, beacon_interval, ie_buf, ie_len,
+ signal, GFP_KERNEL);
+}
+
/*
* workers, indication handlers, device poller
*/
@@ -2507,6 +2618,7 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev)
u8 *req_ie, *resp_ie;
int ret, offset;
bool roamed = false;
+ bool match_bss;
if (priv->infra_mode == NDIS_80211_INFRA_INFRA && priv->connected) {
/* received media connect indication while connected, either
@@ -2558,6 +2670,13 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev)
resp_ie_len =
CONTROL_BUFFER_SIZE - offset;
}
+ } else {
+ /* Since rndis_wlan_craft_connected_bss() might use info
+ * later and expects info to contain valid data if
+ * non-null, free info and set NULL here.
+ */
+ kfree(info);
+ info = NULL;
}
} else if (WARN_ON(priv->infra_mode != NDIS_80211_INFRA_ADHOC))
return;
@@ -2569,13 +2688,26 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev)
netdev_dbg(usbdev->net, "link up work: [%pM]%s\n",
bssid, roamed ? " roamed" : "");
- /* Internal bss list in device always contains at least the currently
+ /* Internal bss list in device should contain at least the currently
* connected bss and we can get it to cfg80211 with
* rndis_check_bssid_list().
- * NOTE: This is true for Broadcom chip, but not mentioned in RNDIS
- * spec.
+ *
+ * NDIS spec says: "If the device is associated, but the associated
+ * BSSID is not in its BSSID scan list, then the driver must add an
+ * entry for the BSSID at the end of the data that it returns in
+ * response to query of OID_802_11_BSSID_LIST."
+ *
+ * NOTE: Seems to be true for BCM4320b variant, but not BCM4320a.
*/
- rndis_check_bssid_list(usbdev);
+ match_bss = false;
+ rndis_check_bssid_list(usbdev, bssid, &match_bss);
+
+ if (!is_zero_ether_addr(bssid) && !match_bss) {
+ /* Couldn't get bss from device, we need to manually craft bss
+ * for cfg80211.
+ */
+ rndis_wlan_craft_connected_bss(usbdev, bssid, info);
+ }
if (priv->infra_mode == NDIS_80211_INFRA_INFRA) {
if (!roamed)
@@ -2934,8 +3066,21 @@ static void rndis_device_poller(struct work_struct *work)
* also polls device with rndis_command() and catches for media link
* indications.
*/
- if (!is_associated(usbdev))
+ if (!is_associated(usbdev)) {
+ /* Workaround bad scanning in BCM4320a devices with active
+ * background scanning when not associated.
+ */
+ if (priv->device_type == RNDIS_BCM4320A && priv->radio_on &&
+ !priv->scan_request) {
+ /* Get previous scan results */
+ rndis_check_bssid_list(usbdev, NULL, NULL);
+
+ /* Initiate new scan */
+ rndis_start_bssid_list_scan(usbdev);
+ }
+
goto end;
+ }
len = sizeof(rssi);
ret = rndis_query_oid(usbdev, OID_802_11_RSSI, &rssi, &len);
@@ -2992,10 +3137,12 @@ end:
/*
* driver/device initialization
*/
-static void rndis_copy_module_params(struct usbnet *usbdev)
+static void rndis_copy_module_params(struct usbnet *usbdev, int device_type)
{
struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
+ priv->device_type = device_type;
+
priv->param_country[0] = modparam_country[0];
priv->param_country[1] = modparam_country[1];
priv->param_country[2] = 0;
@@ -3038,12 +3185,25 @@ static void rndis_copy_module_params(struct usbnet *usbdev)
priv->param_workaround_interval = modparam_workaround_interval;
}
+static int unknown_early_init(struct usbnet *usbdev)
+{
+ /* copy module parameters for unknown so that iwconfig reports txpower
+ * and workaround parameter is copied to private structure correctly.
+ */
+ rndis_copy_module_params(usbdev, RNDIS_UNKNOWN);
+
+ /* This is unknown device, so do not try set configuration parameters.
+ */
+
+ return 0;
+}
+
static int bcm4320a_early_init(struct usbnet *usbdev)
{
/* copy module parameters for bcm4320a so that iwconfig reports txpower
* and workaround parameter is copied to private structure correctly.
*/
- rndis_copy_module_params(usbdev);
+ rndis_copy_module_params(usbdev, RNDIS_BCM4320A);
/* bcm4320a doesn't handle configuration parameters well. Try
* set any and you get partially zeroed mac and broken device.
@@ -3057,7 +3217,7 @@ static int bcm4320b_early_init(struct usbnet *usbdev)
struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
char buf[8];
- rndis_copy_module_params(usbdev);
+ rndis_copy_module_params(usbdev, RNDIS_BCM4320B);
/* Early initialization settings, setting these won't have effect
* if called after generic_rndis_bind().
@@ -3320,7 +3480,7 @@ static const struct driver_info rndis_wlan_info = {
.tx_fixup = rndis_tx_fixup,
.reset = rndis_wlan_reset,
.stop = rndis_wlan_stop,
- .early_init = bcm4320a_early_init,
+ .early_init = unknown_early_init,
.indication = rndis_wlan_indication,
};
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig
index 4396d4b9bfb9..6f383cd684b0 100644
--- a/drivers/net/wireless/rt2x00/Kconfig
+++ b/drivers/net/wireless/rt2x00/Kconfig
@@ -53,51 +53,41 @@ config RT61PCI
When compiled as a module, this driver will be called rt61pci.
-config RT2800PCI_PCI
- boolean
- depends on PCI
- default y
-
-config RT2800PCI_SOC
- boolean
- depends on RALINK_RT288X || RALINK_RT305X
- default y
-
config RT2800PCI
- tristate "Ralink rt28xx/rt30xx/rt35xx (PCI/PCIe/PCMCIA) support (EXPERIMENTAL)"
- depends on (RT2800PCI_PCI || RT2800PCI_SOC) && EXPERIMENTAL
+ tristate "Ralink rt27xx/rt28xx/rt30xx (PCI/PCIe/PCMCIA) support"
+ depends on PCI || RALINK_RT288X || RALINK_RT305X
select RT2800_LIB
- select RT2X00_LIB_PCI if RT2800PCI_PCI
- select RT2X00_LIB_SOC if RT2800PCI_SOC
+ select RT2X00_LIB_PCI if PCI
+ select RT2X00_LIB_SOC if RALINK_RT288X || RALINK_RT305X
select RT2X00_LIB_HT
select RT2X00_LIB_FIRMWARE
select RT2X00_LIB_CRYPTO
select CRC_CCITT
select EEPROM_93CX6
---help---
- This adds support for rt2800/rt3000/rt3500 wireless chipset family.
- Supported chips: RT2760, RT2790, RT2860, RT2880, RT2890 & RT3052
-
- This driver is non-functional at the moment and is intended for
- developers.
+ This adds support for rt27xx/rt28xx/rt30xx wireless chipset family.
+ Supported chips: RT2760, RT2790, RT2860, RT2880, RT2890, RT3052,
+ RT3090, RT3091 & RT3092
When compiled as a module, this driver will be called "rt2800pci.ko".
if RT2800PCI
-config RT2800PCI_RT30XX
- bool "rt2800pci - Include support for rt30xx (PCI/PCIe/PCMCIA) devices"
- default y
+config RT2800PCI_RT33XX
+ bool "rt2800pci - Include support for rt33xx devices (EXPERIMENTAL)"
+ depends on EXPERIMENTAL
+ default n
---help---
- This adds support for rt30xx wireless chipset family to the
+ This adds support for rt33xx wireless chipset family to the
rt2800pci driver.
- Supported chips: RT3090, RT3091 & RT3092
+ Supported chips: RT3390
Support for these devices is non-functional at the moment and is
intended for testers and developers.
config RT2800PCI_RT35XX
- bool "rt2800pci - Include support for rt35xx (PCI/PCIe/PCMCIA) devices"
+ bool "rt2800pci - Include support for rt35xx devices (EXPERIMENTAL)"
+ depends on EXPERIMENTAL
default n
---help---
This adds support for rt35xx wireless chipset family to the
@@ -134,8 +124,8 @@ config RT73USB
When compiled as a module, this driver will be called rt73usb.
config RT2800USB
- tristate "Ralink rt2800 (USB) support (EXPERIMENTAL)"
- depends on USB && EXPERIMENTAL
+ tristate "Ralink rt27xx/rt28xx/rt30xx (USB) support"
+ depends on USB
select RT2800_LIB
select RT2X00_LIB_USB
select RT2X00_LIB_HT
@@ -143,30 +133,28 @@ config RT2800USB
select RT2X00_LIB_CRYPTO
select CRC_CCITT
---help---
- This adds experimental support for rt2800 wireless chipset family.
- Supported chips: RT2770, RT2870 & RT3070.
-
- Known issues:
- - support for RT2870 chips doesn't work with 802.11n APs yet
- - support for RT3070 chips is non-functional at the moment
+ This adds support for rt27xx/rt28xx/rt30xx wireless chipset family.
+ Supported chips: RT2770, RT2870 & RT3070, RT3071 & RT3072
When compiled as a module, this driver will be called "rt2800usb.ko".
if RT2800USB
-config RT2800USB_RT30XX
- bool "rt2800usb - Include support for rt30xx (USB) devices"
- default y
+config RT2800USB_RT33XX
+ bool "rt2800usb - Include support for rt33xx devices (EXPERIMENTAL)"
+ depends on EXPERIMENTAL
+ default n
---help---
- This adds support for rt30xx wireless chipset family to the
+ This adds support for rt33xx wireless chipset family to the
rt2800usb driver.
- Supported chips: RT3070, RT3071 & RT3072
+ Supported chips: RT3370
Support for these devices is non-functional at the moment and is
intended for testers and developers.
config RT2800USB_RT35XX
- bool "rt2800usb - Include support for rt35xx (USB) devices"
+ bool "rt2800usb - Include support for rt35xx devices (EXPERIMENTAL)"
+ depends on EXPERIMENTAL
default n
---help---
This adds support for rt35xx wireless chipset family to the
@@ -180,9 +168,9 @@ config RT2800USB_UNKNOWN
bool "rt2800usb - Include support for unknown (USB) devices"
default n
---help---
- This adds support for rt2800 family devices that are known to
- have a rt2800 family chipset, but for which the exact chipset
- is unknown.
+ This adds support for rt2800usb devices that are known to
+ have a rt28xx family compatible chipset, but for which the exact
+ chipset is unknown.
Support status for these devices is unknown, and enabling these
devices may or may not work.
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 4f420a9ec5dc..9ec6691adf0d 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -885,8 +885,7 @@ static void rt2400pci_toggle_rx(struct rt2x00_dev *rt2x00dev,
rt2x00pci_register_read(rt2x00dev, RXCSR0, &reg);
rt2x00_set_field32(&reg, RXCSR0_DISABLE_RX,
- (state == STATE_RADIO_RX_OFF) ||
- (state == STATE_RADIO_RX_OFF_LINK));
+ (state == STATE_RADIO_RX_OFF));
rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
}
@@ -989,9 +988,7 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev,
rt2400pci_disable_radio(rt2x00dev);
break;
case STATE_RADIO_RX_ON:
- case STATE_RADIO_RX_ON_LINK:
case STATE_RADIO_RX_OFF:
- case STATE_RADIO_RX_OFF_LINK:
rt2400pci_toggle_rx(rt2x00dev, state);
break;
case STATE_RADIO_IRQ_ON:
@@ -1612,6 +1609,7 @@ static const struct ieee80211_ops rt2400pci_mac80211_ops = {
.get_tsf = rt2400pci_get_tsf,
.tx_last_beacon = rt2400pci_tx_last_beacon,
.rfkill_poll = rt2x00mac_rfkill_poll,
+ .flush = rt2x00mac_flush,
};
static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = {
@@ -1640,28 +1638,28 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = {
};
static const struct data_queue_desc rt2400pci_queue_rx = {
- .entry_num = RX_ENTRIES,
+ .entry_num = 24,
.data_size = DATA_FRAME_SIZE,
.desc_size = RXD_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_pci),
};
static const struct data_queue_desc rt2400pci_queue_tx = {
- .entry_num = TX_ENTRIES,
+ .entry_num = 24,
.data_size = DATA_FRAME_SIZE,
.desc_size = TXD_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_pci),
};
static const struct data_queue_desc rt2400pci_queue_bcn = {
- .entry_num = BEACON_ENTRIES,
+ .entry_num = 1,
.data_size = MGMT_FRAME_SIZE,
.desc_size = TXD_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_pci),
};
static const struct data_queue_desc rt2400pci_queue_atim = {
- .entry_num = ATIM_ENTRIES,
+ .entry_num = 8,
.data_size = DATA_FRAME_SIZE,
.desc_size = TXD_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_pci),
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.h b/drivers/net/wireless/rt2x00/rt2400pci.h
index c048b18f4133..d3a4a68cc439 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.h
+++ b/drivers/net/wireless/rt2x00/rt2400pci.h
@@ -809,8 +809,8 @@
/*
* DMA descriptor defines.
*/
-#define TXD_DESC_SIZE ( 8 * sizeof(__le32) )
-#define RXD_DESC_SIZE ( 8 * sizeof(__le32) )
+#define TXD_DESC_SIZE (8 * sizeof(__le32))
+#define RXD_DESC_SIZE (8 * sizeof(__le32))
/*
* TX descriptor format for TX, PRIO, ATIM and Beacon Ring.
@@ -948,6 +948,6 @@
((__CLAMP_TX(__txpower) - MAX_TXPOWER) + MIN_TXPOWER)
#define TXPOWER_TO_DEV(__txpower) \
- MAX_TXPOWER - (__CLAMP_TX(__txpower) - MIN_TXPOWER)
+ (MAX_TXPOWER - (__CLAMP_TX(__txpower) - MIN_TXPOWER))
#endif /* RT2400PCI_H */
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 97feb7aef809..3e7f20346243 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -1040,8 +1040,7 @@ static void rt2500pci_toggle_rx(struct rt2x00_dev *rt2x00dev,
rt2x00pci_register_read(rt2x00dev, RXCSR0, &reg);
rt2x00_set_field32(&reg, RXCSR0_DISABLE_RX,
- (state == STATE_RADIO_RX_OFF) ||
- (state == STATE_RADIO_RX_OFF_LINK));
+ (state == STATE_RADIO_RX_OFF));
rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
}
@@ -1144,9 +1143,7 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev,
rt2500pci_disable_radio(rt2x00dev);
break;
case STATE_RADIO_RX_ON:
- case STATE_RADIO_RX_ON_LINK:
case STATE_RADIO_RX_OFF:
- case STATE_RADIO_RX_OFF_LINK:
rt2500pci_toggle_rx(rt2x00dev, state);
break;
case STATE_RADIO_IRQ_ON:
@@ -1193,9 +1190,9 @@ static void rt2500pci_write_tx_desc(struct queue_entry *entry,
rt2x00_desc_read(txd, 2, &word);
rt2x00_set_field32(&word, TXD_W2_IV_OFFSET, IEEE80211_HEADER);
- rt2x00_set_field32(&word, TXD_W2_AIFS, txdesc->aifs);
- rt2x00_set_field32(&word, TXD_W2_CWMIN, txdesc->cw_min);
- rt2x00_set_field32(&word, TXD_W2_CWMAX, txdesc->cw_max);
+ rt2x00_set_field32(&word, TXD_W2_AIFS, entry->queue->aifs);
+ rt2x00_set_field32(&word, TXD_W2_CWMIN, entry->queue->cw_min);
+ rt2x00_set_field32(&word, TXD_W2_CWMAX, entry->queue->cw_max);
rt2x00_desc_write(txd, 2, word);
rt2x00_desc_read(txd, 3, &word);
@@ -1909,6 +1906,7 @@ static const struct ieee80211_ops rt2500pci_mac80211_ops = {
.get_tsf = rt2500pci_get_tsf,
.tx_last_beacon = rt2500pci_tx_last_beacon,
.rfkill_poll = rt2x00mac_rfkill_poll,
+ .flush = rt2x00mac_flush,
};
static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = {
@@ -1937,28 +1935,28 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = {
};
static const struct data_queue_desc rt2500pci_queue_rx = {
- .entry_num = RX_ENTRIES,
+ .entry_num = 32,
.data_size = DATA_FRAME_SIZE,
.desc_size = RXD_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_pci),
};
static const struct data_queue_desc rt2500pci_queue_tx = {
- .entry_num = TX_ENTRIES,
+ .entry_num = 32,
.data_size = DATA_FRAME_SIZE,
.desc_size = TXD_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_pci),
};
static const struct data_queue_desc rt2500pci_queue_bcn = {
- .entry_num = BEACON_ENTRIES,
+ .entry_num = 1,
.data_size = MGMT_FRAME_SIZE,
.desc_size = TXD_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_pci),
};
static const struct data_queue_desc rt2500pci_queue_atim = {
- .entry_num = ATIM_ENTRIES,
+ .entry_num = 8,
.data_size = DATA_FRAME_SIZE,
.desc_size = TXD_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_pci),
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.h b/drivers/net/wireless/rt2x00/rt2500pci.h
index d708031361ac..2aad7ba8a100 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.h
+++ b/drivers/net/wireless/rt2x00/rt2500pci.h
@@ -1088,8 +1088,8 @@
/*
* DMA descriptor defines.
*/
-#define TXD_DESC_SIZE ( 11 * sizeof(__le32) )
-#define RXD_DESC_SIZE ( 11 * sizeof(__le32) )
+#define TXD_DESC_SIZE (11 * sizeof(__le32))
+#define RXD_DESC_SIZE (11 * sizeof(__le32))
/*
* TX descriptor format for TX, PRIO, ATIM and Beacon Ring.
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 93e44c7f3a74..8152fec31753 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -39,7 +39,7 @@
/*
* Allow hardware encryption to be disabled.
*/
-static int modparam_nohwcrypt = 0;
+static int modparam_nohwcrypt;
module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
@@ -938,8 +938,7 @@ static void rt2500usb_toggle_rx(struct rt2x00_dev *rt2x00dev,
rt2500usb_register_read(rt2x00dev, TXRX_CSR2, &reg);
rt2x00_set_field16(&reg, TXRX_CSR2_DISABLE_RX,
- (state == STATE_RADIO_RX_OFF) ||
- (state == STATE_RADIO_RX_OFF_LINK));
+ (state == STATE_RADIO_RX_OFF));
rt2500usb_register_write(rt2x00dev, TXRX_CSR2, reg);
}
@@ -1019,9 +1018,7 @@ static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev,
rt2500usb_disable_radio(rt2x00dev);
break;
case STATE_RADIO_RX_ON:
- case STATE_RADIO_RX_ON_LINK:
case STATE_RADIO_RX_OFF:
- case STATE_RADIO_RX_OFF_LINK:
rt2500usb_toggle_rx(rt2x00dev, state);
break;
case STATE_RADIO_IRQ_ON:
@@ -1081,9 +1078,9 @@ static void rt2500usb_write_tx_desc(struct queue_entry *entry,
rt2x00_desc_read(txd, 1, &word);
rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, txdesc->iv_offset);
- rt2x00_set_field32(&word, TXD_W1_AIFS, txdesc->aifs);
- rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min);
- rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max);
+ rt2x00_set_field32(&word, TXD_W1_AIFS, entry->queue->aifs);
+ rt2x00_set_field32(&word, TXD_W1_CWMIN, entry->queue->cw_min);
+ rt2x00_set_field32(&word, TXD_W1_CWMAX, entry->queue->cw_max);
rt2x00_desc_write(txd, 1, word);
rt2x00_desc_read(txd, 2, &word);
@@ -1801,6 +1798,7 @@ static const struct ieee80211_ops rt2500usb_mac80211_ops = {
.bss_info_changed = rt2x00mac_bss_info_changed,
.conf_tx = rt2x00mac_conf_tx,
.rfkill_poll = rt2x00mac_rfkill_poll,
+ .flush = rt2x00mac_flush,
};
static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
@@ -1829,28 +1827,28 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
};
static const struct data_queue_desc rt2500usb_queue_rx = {
- .entry_num = RX_ENTRIES,
+ .entry_num = 32,
.data_size = DATA_FRAME_SIZE,
.desc_size = RXD_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_usb),
};
static const struct data_queue_desc rt2500usb_queue_tx = {
- .entry_num = TX_ENTRIES,
+ .entry_num = 32,
.data_size = DATA_FRAME_SIZE,
.desc_size = TXD_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_usb),
};
static const struct data_queue_desc rt2500usb_queue_bcn = {
- .entry_num = BEACON_ENTRIES,
+ .entry_num = 1,
.data_size = MGMT_FRAME_SIZE,
.desc_size = TXD_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_usb_bcn),
};
static const struct data_queue_desc rt2500usb_queue_atim = {
- .entry_num = ATIM_ENTRIES,
+ .entry_num = 8,
.data_size = DATA_FRAME_SIZE,
.desc_size = TXD_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_usb),
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index eb8b6cab9925..a81c4371835b 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -47,6 +47,7 @@
* RF3021 2.4G 1T2R
* RF3022 2.4G 2T2R
* RF3052 2.4G 2T2R
+ * RF3320 2.4G 1T1R
*/
#define RF2820 0x0001
#define RF2850 0x0002
@@ -412,10 +413,22 @@
#define BCN_OFFSET1_BCN7 FIELD32(0xff000000)
/*
- * PBF registers
- * Most are for debug. Driver doesn't touch PBF register.
+ * TXRXQ_PCNT: PBF register
+ * PCNT_TX0Q: Page count for TX hardware queue 0
+ * PCNT_TX1Q: Page count for TX hardware queue 1
+ * PCNT_TX2Q: Page count for TX hardware queue 2
+ * PCNT_RX0Q: Page count for RX hardware queue
*/
#define TXRXQ_PCNT 0x0438
+#define TXRXQ_PCNT_TX0Q FIELD32(0x000000ff)
+#define TXRXQ_PCNT_TX1Q FIELD32(0x0000ff00)
+#define TXRXQ_PCNT_TX2Q FIELD32(0x00ff0000)
+#define TXRXQ_PCNT_RX0Q FIELD32(0xff000000)
+
+/*
+ * PBF register
+ * Debug. Driver doesn't touch PBF register.
+ */
#define PBF_DBG 0x043c
/*
@@ -960,8 +973,31 @@
/*
* TXOP_CTRL_CFG:
+ * TIMEOUT_TRUN_EN: Enable/Disable TXOP timeout truncation
+ * AC_TRUN_EN: Enable/Disable truncation for AC change
+ * TXRATEGRP_TRUN_EN: Enable/Disable truncation for TX rate group change
+ * USER_MODE_TRUN_EN: Enable/Disable truncation for user TXOP mode
+ * MIMO_PS_TRUN_EN: Enable/Disable truncation for MIMO PS RTS/CTS
+ * RESERVED_TRUN_EN: Reserved
+ * LSIG_TXOP_EN: Enable/Disable L-SIG TXOP protection
+ * EXT_CCA_EN: Enable/Disable extension channel CCA reference (Defer 40Mhz
+ * transmissions if extension CCA is clear).
+ * EXT_CCA_DLY: Extension CCA signal delay time (unit: us)
+ * EXT_CWMIN: CwMin for extension channel backoff
+ * 0: Disabled
+ *
*/
#define TXOP_CTRL_CFG 0x1340
+#define TXOP_CTRL_CFG_TIMEOUT_TRUN_EN FIELD32(0x00000001)
+#define TXOP_CTRL_CFG_AC_TRUN_EN FIELD32(0x00000002)
+#define TXOP_CTRL_CFG_TXRATEGRP_TRUN_EN FIELD32(0x00000004)
+#define TXOP_CTRL_CFG_USER_MODE_TRUN_EN FIELD32(0x00000008)
+#define TXOP_CTRL_CFG_MIMO_PS_TRUN_EN FIELD32(0x00000010)
+#define TXOP_CTRL_CFG_RESERVED_TRUN_EN FIELD32(0x00000020)
+#define TXOP_CTRL_CFG_LSIG_TXOP_EN FIELD32(0x00000040)
+#define TXOP_CTRL_CFG_EXT_CCA_EN FIELD32(0x00000080)
+#define TXOP_CTRL_CFG_EXT_CCA_DLY FIELD32(0x0000ff00)
+#define TXOP_CTRL_CFG_EXT_CWMIN FIELD32(0x000f0000)
/*
* TX_RTS_CFG:
@@ -1485,17 +1521,17 @@
#define SHARED_KEY_MODE_BASE 0x7000
#define MAC_WCID_ENTRY(__idx) \
- ( MAC_WCID_BASE + ((__idx) * sizeof(struct mac_wcid_entry)) )
+ (MAC_WCID_BASE + ((__idx) * sizeof(struct mac_wcid_entry)))
#define PAIRWISE_KEY_ENTRY(__idx) \
- ( PAIRWISE_KEY_TABLE_BASE + ((__idx) * sizeof(struct hw_key_entry)) )
+ (PAIRWISE_KEY_TABLE_BASE + ((__idx) * sizeof(struct hw_key_entry)))
#define MAC_IVEIV_ENTRY(__idx) \
- ( MAC_IVEIV_TABLE_BASE + ((__idx) * sizeof(struct mac_iveiv_entry)) )
+ (MAC_IVEIV_TABLE_BASE + ((__idx) * sizeof(struct mac_iveiv_entry)))
#define MAC_WCID_ATTR_ENTRY(__idx) \
- ( MAC_WCID_ATTRIBUTE_BASE + ((__idx) * sizeof(u32)) )
+ (MAC_WCID_ATTRIBUTE_BASE + ((__idx) * sizeof(u32)))
#define SHARED_KEY_ENTRY(__idx) \
- ( SHARED_KEY_TABLE_BASE + ((__idx) * sizeof(struct hw_key_entry)) )
+ (SHARED_KEY_TABLE_BASE + ((__idx) * sizeof(struct hw_key_entry)))
#define SHARED_KEY_MODE_ENTRY(__idx) \
- ( SHARED_KEY_MODE_BASE + ((__idx) * sizeof(u32)) )
+ (SHARED_KEY_MODE_BASE + ((__idx) * sizeof(u32)))
struct mac_wcid_entry {
u8 mac[6];
@@ -1635,9 +1671,9 @@ struct mac_iveiv_entry {
#define HW_BEACON_BASE7 0x5bc0
#define HW_BEACON_OFFSET(__index) \
- ( ((__index) < 4) ? ( HW_BEACON_BASE0 + (__index * 0x0200) ) : \
- (((__index) < 6) ? ( HW_BEACON_BASE4 + ((__index - 4) * 0x0200) ) : \
- (HW_BEACON_BASE6 - ((__index - 6) * 0x0200))) )
+ (((__index) < 4) ? (HW_BEACON_BASE0 + (__index * 0x0200)) : \
+ (((__index) < 6) ? (HW_BEACON_BASE4 + ((__index - 4) * 0x0200)) : \
+ (HW_BEACON_BASE6 - ((__index - 6) * 0x0200))))
/*
* BBP registers.
@@ -1987,8 +2023,8 @@ struct mac_iveiv_entry {
/*
* DMA descriptor defines.
*/
-#define TXWI_DESC_SIZE ( 4 * sizeof(__le32) )
-#define RXWI_DESC_SIZE ( 4 * sizeof(__le32) )
+#define TXWI_DESC_SIZE (4 * sizeof(__le32))
+#define RXWI_DESC_SIZE (4 * sizeof(__le32))
/*
* TX WI structure
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 5f00e00789d8..75631614aba3 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -277,13 +277,17 @@ int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev)
unsigned int i;
u32 reg;
+ /*
+ * Some devices are really slow to respond here. Wait a whole second
+ * before timing out.
+ */
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
if (!rt2x00_get_field32(reg, WPDMA_GLO_CFG_TX_DMA_BUSY) &&
!rt2x00_get_field32(reg, WPDMA_GLO_CFG_RX_DMA_BUSY))
return 0;
- msleep(1);
+ msleep(10);
}
ERROR(rt2x00dev, "WPDMA TX/RX busy, aborting.\n");
@@ -483,7 +487,7 @@ void rt2800_write_tx_data(struct queue_entry *entry,
txdesc->key_idx : 0xff);
rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT,
txdesc->length);
- rt2x00_set_field32(&word, TXWI_W1_PACKETID_QUEUE, txdesc->qid);
+ rt2x00_set_field32(&word, TXWI_W1_PACKETID_QUEUE, entry->queue->qid);
rt2x00_set_field32(&word, TXWI_W1_PACKETID_ENTRY, (entry->entry_idx % 3) + 1);
rt2x00_desc_write(txwi, 1, word);
@@ -727,7 +731,7 @@ void rt2800_txdone(struct rt2x00_dev *rt2x00dev)
* that the TX_STA_FIFO stack has a size of 16. We stick to our
* tx ring size for now.
*/
- for (i = 0; i < TX_ENTRIES; i++) {
+ for (i = 0; i < rt2x00dev->ops->tx->entry_num; i++) {
rt2800_register_read(rt2x00dev, TX_STA_FIFO, &reg);
if (!rt2x00_get_field32(reg, TX_STA_FIFO_VALID))
break;
@@ -824,7 +828,7 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
}
EXPORT_SYMBOL_GPL(rt2800_write_beacon);
-static void inline rt2800_clear_beacon(struct rt2x00_dev *rt2x00dev,
+static inline void rt2800_clear_beacon(struct rt2x00_dev *rt2x00dev,
unsigned int beacon_base)
{
int i;
@@ -1144,6 +1148,7 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf,
struct rt2x00intf_conf *conf, const unsigned int flags)
{
u32 reg;
+ bool update_bssid = false;
if (flags & CONFIG_UPDATE_TYPE) {
/*
@@ -1173,6 +1178,16 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf,
}
if (flags & CONFIG_UPDATE_MAC) {
+ if (flags & CONFIG_UPDATE_TYPE &&
+ conf->sync == TSF_SYNC_AP_NONE) {
+ /*
+ * The BSSID register has to be set to our own mac
+ * address in AP mode.
+ */
+ memcpy(conf->bssid, conf->mac, sizeof(conf->mac));
+ update_bssid = true;
+ }
+
if (!is_zero_ether_addr((const u8 *)conf->mac)) {
reg = le32_to_cpu(conf->mac[1]);
rt2x00_set_field32(&reg, MAC_ADDR_DW1_UNICAST_TO_ME_MASK, 0xff);
@@ -1183,7 +1198,7 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf,
conf->mac, sizeof(conf->mac));
}
- if (flags & CONFIG_UPDATE_BSSID) {
+ if ((flags & CONFIG_UPDATE_BSSID) || update_bssid) {
if (!is_zero_ether_addr((const u8 *)conf->bssid)) {
reg = le32_to_cpu(conf->bssid[1]);
rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_ID_MASK, 3);
@@ -1529,7 +1544,8 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
rt2x00_rf(rt2x00dev, RF3020) ||
rt2x00_rf(rt2x00dev, RF3021) ||
rt2x00_rf(rt2x00dev, RF3022) ||
- rt2x00_rf(rt2x00dev, RF3052))
+ rt2x00_rf(rt2x00dev, RF3052) ||
+ rt2x00_rf(rt2x00dev, RF3320))
rt2800_config_channel_rf3xxx(rt2x00dev, conf, rf, info);
else
rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info);
@@ -2097,7 +2113,23 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
}
- rt2800_register_write(rt2x00dev, TXOP_CTRL_CFG, 0x0000583f);
+ /*
+ * The legacy driver also sets TXOP_CTRL_CFG_RESERVED_TRUN_EN to 1
+ * although it is reserved.
+ */
+ rt2800_register_read(rt2x00dev, TXOP_CTRL_CFG, &reg);
+ rt2x00_set_field32(&reg, TXOP_CTRL_CFG_TIMEOUT_TRUN_EN, 1);
+ rt2x00_set_field32(&reg, TXOP_CTRL_CFG_AC_TRUN_EN, 1);
+ rt2x00_set_field32(&reg, TXOP_CTRL_CFG_TXRATEGRP_TRUN_EN, 1);
+ rt2x00_set_field32(&reg, TXOP_CTRL_CFG_USER_MODE_TRUN_EN, 1);
+ rt2x00_set_field32(&reg, TXOP_CTRL_CFG_MIMO_PS_TRUN_EN, 1);
+ rt2x00_set_field32(&reg, TXOP_CTRL_CFG_RESERVED_TRUN_EN, 1);
+ rt2x00_set_field32(&reg, TXOP_CTRL_CFG_LSIG_TXOP_EN, 0);
+ rt2x00_set_field32(&reg, TXOP_CTRL_CFG_EXT_CCA_EN, 0);
+ rt2x00_set_field32(&reg, TXOP_CTRL_CFG_EXT_CCA_DLY, 88);
+ rt2x00_set_field32(&reg, TXOP_CTRL_CFG_EXT_CWMIN, 0);
+ rt2800_register_write(rt2x00dev, TXOP_CTRL_CFG, reg);
+
rt2800_register_write(rt2x00dev, TXOP_HLDR_ET, 0x00000002);
rt2800_register_read(rt2x00dev, TX_RTS_CFG, &reg);
@@ -2134,7 +2166,7 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
SHARED_KEY_MODE_ENTRY(i), 0);
for (i = 0; i < 256; i++) {
- u32 wcid[2] = { 0xffffffff, 0x00ffffff };
+ static const u32 wcid[2] = { 0xffffffff, 0x00ffffff };
rt2800_register_multiwrite(rt2x00dev, MAC_WCID_ENTRY(i),
wcid, sizeof(wcid));
@@ -2981,7 +3013,8 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
!rt2x00_rf(rt2x00dev, RF2020) &&
!rt2x00_rf(rt2x00dev, RF3021) &&
!rt2x00_rf(rt2x00dev, RF3022) &&
- !rt2x00_rf(rt2x00dev, RF3052)) {
+ !rt2x00_rf(rt2x00dev, RF3052) &&
+ !rt2x00_rf(rt2x00dev, RF3320)) {
ERROR(rt2x00dev, "Invalid RF chipset detected.\n");
return -ENODEV;
}
@@ -3245,7 +3278,8 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
} else if (rt2x00_rf(rt2x00dev, RF3020) ||
rt2x00_rf(rt2x00dev, RF2020) ||
rt2x00_rf(rt2x00dev, RF3021) ||
- rt2x00_rf(rt2x00dev, RF3022)) {
+ rt2x00_rf(rt2x00dev, RF3022) ||
+ rt2x00_rf(rt2x00dev, RF3320)) {
spec->num_channels = 14;
spec->channels = rf_vals_3x;
} else if (rt2x00_rf(rt2x00dev, RF3052)) {
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index b26739535986..b989b0d3ed49 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -84,20 +84,22 @@ static void rt2800pci_mcu_status(struct rt2x00_dev *rt2x00dev, const u8 token)
rt2800_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
}
-#ifdef CONFIG_RT2800PCI_SOC
+#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X)
static void rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev)
{
- u32 *base_addr = (u32 *) KSEG1ADDR(0x1F040000); /* XXX for RT3052 */
+ void __iomem *base_addr = ioremap(0x1F040000, EEPROM_SIZE);
memcpy_fromio(rt2x00dev->eeprom, base_addr, EEPROM_SIZE);
+
+ iounmap(base_addr);
}
#else
static inline void rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev)
{
}
-#endif /* CONFIG_RT2800PCI_SOC */
+#endif /* CONFIG_RALINK_RT288X || CONFIG_RALINK_RT305X */
-#ifdef CONFIG_RT2800PCI_PCI
+#ifdef CONFIG_PCI
static void rt2800pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
{
struct rt2x00_dev *rt2x00dev = eeprom->data;
@@ -181,7 +183,7 @@ static inline int rt2800pci_efuse_detect(struct rt2x00_dev *rt2x00dev)
static inline void rt2800pci_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev)
{
}
-#endif /* CONFIG_RT2800PCI_PCI */
+#endif /* CONFIG_PCI */
/*
* Firmware functions
@@ -328,8 +330,7 @@ static void rt2800pci_toggle_rx(struct rt2x00_dev *rt2x00dev,
rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX,
- (state == STATE_RADIO_RX_ON) ||
- (state == STATE_RADIO_RX_ON_LINK));
+ (state == STATE_RADIO_RX_ON));
rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
}
@@ -442,7 +443,7 @@ static int rt2800pci_set_state(struct rt2x00_dev *rt2x00dev,
* if the device is booting and wasn't asleep it will return
* failure when attempting to wakeup.
*/
- rt2800_mcu_request(rt2x00dev, MCU_SLEEP, 0xff, 0, 2);
+ rt2800_mcu_request(rt2x00dev, MCU_SLEEP, 0xff, 0xff, 2);
if (state == STATE_AWAKE) {
rt2800_mcu_request(rt2x00dev, MCU_WAKEUP, TOKEN_WAKUP, 0, 0);
@@ -477,9 +478,7 @@ static int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev,
rt2800pci_set_state(rt2x00dev, STATE_SLEEP);
break;
case STATE_RADIO_RX_ON:
- case STATE_RADIO_RX_ON_LINK:
case STATE_RADIO_RX_OFF:
- case STATE_RADIO_RX_OFF_LINK:
rt2800pci_toggle_rx(rt2x00dev, state);
break;
case STATE_RADIO_IRQ_ON:
@@ -777,7 +776,7 @@ static void rt2800pci_txstatus_interrupt(struct rt2x00_dev *rt2x00dev)
* Since we have only one producer and one consumer we don't
* need to lock the kfifo.
*/
- for (i = 0; i < TX_ENTRIES; i++) {
+ for (i = 0; i < rt2x00dev->ops->tx->entry_num; i++) {
rt2800_register_read(rt2x00dev, TX_STA_FIFO, &status);
if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID))
@@ -912,6 +911,7 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev)
__set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags);
__set_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags);
__set_bit(DRIVER_REQUIRE_TXSTATUS_FIFO, &rt2x00dev->flags);
+ __set_bit(DRIVER_REQUIRE_TASKLET_CONTEXT, &rt2x00dev->flags);
if (!modparam_nohwcrypt)
__set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags);
__set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags);
@@ -943,6 +943,7 @@ static const struct ieee80211_ops rt2800pci_mac80211_ops = {
.get_tsf = rt2800_get_tsf,
.rfkill_poll = rt2x00mac_rfkill_poll,
.ampdu_action = rt2800_ampdu_action,
+ .flush = rt2x00mac_flush,
};
static const struct rt2800_ops rt2800pci_rt2800_ops = {
@@ -991,21 +992,21 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = {
};
static const struct data_queue_desc rt2800pci_queue_rx = {
- .entry_num = RX_ENTRIES,
+ .entry_num = 128,
.data_size = AGGREGATION_SIZE,
.desc_size = RXD_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_pci),
};
static const struct data_queue_desc rt2800pci_queue_tx = {
- .entry_num = TX_ENTRIES,
+ .entry_num = 64,
.data_size = AGGREGATION_SIZE,
.desc_size = TXD_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_pci),
};
static const struct data_queue_desc rt2800pci_queue_bcn = {
- .entry_num = 8 * BEACON_ENTRIES,
+ .entry_num = 8,
.data_size = 0, /* No DMA required for beacons */
.desc_size = TXWI_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_pci),
@@ -1033,12 +1034,15 @@ static const struct rt2x00_ops rt2800pci_ops = {
/*
* RT2800pci module information.
*/
-#ifdef CONFIG_RT2800PCI_PCI
+#ifdef CONFIG_PCI
static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = {
{ PCI_DEVICE(0x1814, 0x0601), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1814, 0x0681), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1814, 0x0701), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1814, 0x0781), PCI_DEVICE_DATA(&rt2800pci_ops) },
+ { PCI_DEVICE(0x1814, 0x3090), PCI_DEVICE_DATA(&rt2800pci_ops) },
+ { PCI_DEVICE(0x1814, 0x3091), PCI_DEVICE_DATA(&rt2800pci_ops) },
+ { PCI_DEVICE(0x1814, 0x3092), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1432, 0x7708), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1432, 0x7727), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1432, 0x7728), PCI_DEVICE_DATA(&rt2800pci_ops) },
@@ -1046,12 +1050,10 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = {
{ PCI_DEVICE(0x1432, 0x7748), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1432, 0x7758), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1432, 0x7768), PCI_DEVICE_DATA(&rt2800pci_ops) },
- { PCI_DEVICE(0x1a3b, 0x1059), PCI_DEVICE_DATA(&rt2800pci_ops) },
-#ifdef CONFIG_RT2800PCI_RT30XX
- { PCI_DEVICE(0x1814, 0x3090), PCI_DEVICE_DATA(&rt2800pci_ops) },
- { PCI_DEVICE(0x1814, 0x3091), PCI_DEVICE_DATA(&rt2800pci_ops) },
- { PCI_DEVICE(0x1814, 0x3092), PCI_DEVICE_DATA(&rt2800pci_ops) },
{ PCI_DEVICE(0x1462, 0x891a), PCI_DEVICE_DATA(&rt2800pci_ops) },
+ { PCI_DEVICE(0x1a3b, 0x1059), PCI_DEVICE_DATA(&rt2800pci_ops) },
+#ifdef CONFIG_RT2800PCI_RT33XX
+ { PCI_DEVICE(0x1814, 0x3390), PCI_DEVICE_DATA(&rt2800pci_ops) },
#endif
#ifdef CONFIG_RT2800PCI_RT35XX
{ PCI_DEVICE(0x1814, 0x3060), PCI_DEVICE_DATA(&rt2800pci_ops) },
@@ -1062,19 +1064,19 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = {
#endif
{ 0, }
};
-#endif /* CONFIG_RT2800PCI_PCI */
+#endif /* CONFIG_PCI */
MODULE_AUTHOR(DRV_PROJECT);
MODULE_VERSION(DRV_VERSION);
MODULE_DESCRIPTION("Ralink RT2800 PCI & PCMCIA Wireless LAN driver.");
MODULE_SUPPORTED_DEVICE("Ralink RT2860 PCI & PCMCIA chipset based cards");
-#ifdef CONFIG_RT2800PCI_PCI
+#ifdef CONFIG_PCI
MODULE_FIRMWARE(FIRMWARE_RT2860);
MODULE_DEVICE_TABLE(pci, rt2800pci_device_table);
-#endif /* CONFIG_RT2800PCI_PCI */
+#endif /* CONFIG_PCI */
MODULE_LICENSE("GPL");
-#ifdef CONFIG_RT2800PCI_SOC
+#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X)
static int rt2800soc_probe(struct platform_device *pdev)
{
return rt2x00soc_probe(pdev, &rt2800pci_ops);
@@ -1091,9 +1093,9 @@ static struct platform_driver rt2800soc_driver = {
.suspend = rt2x00soc_suspend,
.resume = rt2x00soc_resume,
};
-#endif /* CONFIG_RT2800PCI_SOC */
+#endif /* CONFIG_RALINK_RT288X || CONFIG_RALINK_RT305X */
-#ifdef CONFIG_RT2800PCI_PCI
+#ifdef CONFIG_PCI
static struct pci_driver rt2800pci_driver = {
.name = KBUILD_MODNAME,
.id_table = rt2800pci_device_table,
@@ -1102,21 +1104,21 @@ static struct pci_driver rt2800pci_driver = {
.suspend = rt2x00pci_suspend,
.resume = rt2x00pci_resume,
};
-#endif /* CONFIG_RT2800PCI_PCI */
+#endif /* CONFIG_PCI */
static int __init rt2800pci_init(void)
{
int ret = 0;
-#ifdef CONFIG_RT2800PCI_SOC
+#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X)
ret = platform_driver_register(&rt2800soc_driver);
if (ret)
return ret;
#endif
-#ifdef CONFIG_RT2800PCI_PCI
+#ifdef CONFIG_PCI
ret = pci_register_driver(&rt2800pci_driver);
if (ret) {
-#ifdef CONFIG_RT2800PCI_SOC
+#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X)
platform_driver_unregister(&rt2800soc_driver);
#endif
return ret;
@@ -1128,10 +1130,10 @@ static int __init rt2800pci_init(void)
static void __exit rt2800pci_exit(void)
{
-#ifdef CONFIG_RT2800PCI_PCI
+#ifdef CONFIG_PCI
pci_unregister_driver(&rt2800pci_driver);
#endif
-#ifdef CONFIG_RT2800PCI_SOC
+#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X)
platform_driver_unregister(&rt2800soc_driver);
#endif
}
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.h b/drivers/net/wireless/rt2x00/rt2800pci.h
index 5a8dda9b5b5a..70e050d904c8 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.h
+++ b/drivers/net/wireless/rt2x00/rt2800pci.h
@@ -38,10 +38,10 @@
* Queue register offset macros
*/
#define TX_QUEUE_REG_OFFSET 0x10
-#define TX_BASE_PTR(__x) TX_BASE_PTR0 + ((__x) * TX_QUEUE_REG_OFFSET)
-#define TX_MAX_CNT(__x) TX_MAX_CNT0 + ((__x) * TX_QUEUE_REG_OFFSET)
-#define TX_CTX_IDX(__x) TX_CTX_IDX0 + ((__x) * TX_QUEUE_REG_OFFSET)
-#define TX_DTX_IDX(__x) TX_DTX_IDX0 + ((__x) * TX_QUEUE_REG_OFFSET)
+#define TX_BASE_PTR(__x) (TX_BASE_PTR0 + ((__x) * TX_QUEUE_REG_OFFSET))
+#define TX_MAX_CNT(__x) (TX_MAX_CNT0 + ((__x) * TX_QUEUE_REG_OFFSET))
+#define TX_CTX_IDX(__x) (TX_CTX_IDX0 + ((__x) * TX_QUEUE_REG_OFFSET))
+#define TX_DTX_IDX(__x) (TX_DTX_IDX0 + ((__x) * TX_QUEUE_REG_OFFSET))
/*
* 8051 firmware image.
@@ -52,8 +52,8 @@
/*
* DMA descriptor defines.
*/
-#define TXD_DESC_SIZE ( 4 * sizeof(__le32) )
-#define RXD_DESC_SIZE ( 4 * sizeof(__le32) )
+#define TXD_DESC_SIZE (4 * sizeof(__le32))
+#define RXD_DESC_SIZE (4 * sizeof(__le32))
/*
* TX descriptor format for TX, PRIO and Beacon Ring.
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 3dff56ec195a..935b76d3ce4f 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -45,7 +45,7 @@
/*
* Allow hardware encryption to be disabled.
*/
-static int modparam_nohwcrypt = 0;
+static int modparam_nohwcrypt;
module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
@@ -114,8 +114,7 @@ static void rt2800usb_toggle_rx(struct rt2x00_dev *rt2x00dev,
rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX,
- (state == STATE_RADIO_RX_ON) ||
- (state == STATE_RADIO_RX_ON_LINK));
+ (state == STATE_RADIO_RX_ON));
rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
}
@@ -165,7 +164,8 @@ static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev)
* this limit so reduce the number to prevent errors.
*/
rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_AGG_LIMIT,
- ((RX_ENTRIES * DATA_FRAME_SIZE) / 1024) - 3);
+ ((rt2x00dev->ops->rx->entry_num * DATA_FRAME_SIZE)
+ / 1024) - 3);
rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_EN, 1);
rt2x00_set_field32(&reg, USB_DMA_CFG_TX_BULK_EN, 1);
rt2800_register_write(rt2x00dev, USB_DMA_CFG, reg);
@@ -183,9 +183,9 @@ static int rt2800usb_set_state(struct rt2x00_dev *rt2x00dev,
enum dev_state state)
{
if (state == STATE_AWAKE)
- rt2800_mcu_request(rt2x00dev, MCU_WAKEUP, 0xff, 0, 0);
+ rt2800_mcu_request(rt2x00dev, MCU_WAKEUP, 0xff, 0, 2);
else
- rt2800_mcu_request(rt2x00dev, MCU_SLEEP, 0xff, 0, 2);
+ rt2800_mcu_request(rt2x00dev, MCU_SLEEP, 0xff, 0xff, 2);
return 0;
}
@@ -215,9 +215,7 @@ static int rt2800usb_set_device_state(struct rt2x00_dev *rt2x00dev,
rt2800usb_set_state(rt2x00dev, STATE_SLEEP);
break;
case STATE_RADIO_RX_ON:
- case STATE_RADIO_RX_ON_LINK:
case STATE_RADIO_RX_OFF:
- case STATE_RADIO_RX_OFF_LINK:
rt2800usb_toggle_rx(rt2x00dev, state);
break;
case STATE_RADIO_IRQ_ON:
@@ -245,6 +243,49 @@ static int rt2800usb_set_device_state(struct rt2x00_dev *rt2x00dev,
}
/*
+ * Watchdog handlers
+ */
+static void rt2800usb_watchdog(struct rt2x00_dev *rt2x00dev)
+{
+ unsigned int i;
+ u32 reg;
+
+ rt2800_register_read(rt2x00dev, TXRXQ_PCNT, &reg);
+ if (rt2x00_get_field32(reg, TXRXQ_PCNT_TX0Q)) {
+ WARNING(rt2x00dev, "TX HW queue 0 timed out,"
+ " invoke forced kick");
+
+ rt2800_register_write(rt2x00dev, PBF_CFG, 0xf40012);
+
+ for (i = 0; i < 10; i++) {
+ udelay(10);
+ if (!rt2x00_get_field32(reg, TXRXQ_PCNT_TX0Q))
+ break;
+ }
+
+ rt2800_register_write(rt2x00dev, PBF_CFG, 0xf40006);
+ }
+
+ rt2800_register_read(rt2x00dev, TXRXQ_PCNT, &reg);
+ if (rt2x00_get_field32(reg, TXRXQ_PCNT_TX1Q)) {
+ WARNING(rt2x00dev, "TX HW queue 1 timed out,"
+ " invoke forced kick");
+
+ rt2800_register_write(rt2x00dev, PBF_CFG, 0xf4000a);
+
+ for (i = 0; i < 10; i++) {
+ udelay(10);
+ if (!rt2x00_get_field32(reg, TXRXQ_PCNT_TX1Q))
+ break;
+ }
+
+ rt2800_register_write(rt2x00dev, PBF_CFG, 0xf40006);
+ }
+
+ rt2x00usb_watchdog(rt2x00dev);
+}
+
+/*
* TX descriptor initialization
*/
static __le32 *rt2800usb_get_txwi(struct queue_entry *entry)
@@ -266,8 +307,14 @@ static void rt2800usb_write_tx_desc(struct queue_entry *entry,
* Initialize TXINFO descriptor
*/
rt2x00_desc_read(txi, 0, &word);
+
+ /*
+ * The size of TXINFO_W0_USB_DMA_TX_PKT_LEN is
+ * TXWI + 802.11 header + L2 pad + payload + pad,
+ * so need to decrease size of TXINFO and USB end pad.
+ */
rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_PKT_LEN,
- entry->skb->len - TXINFO_DESC_SIZE);
+ entry->skb->len - TXINFO_DESC_SIZE - 4);
rt2x00_set_field32(&word, TXINFO_W0_WIV,
!test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags));
rt2x00_set_field32(&word, TXINFO_W0_QSEL, 2);
@@ -285,22 +332,29 @@ static void rt2800usb_write_tx_desc(struct queue_entry *entry,
skbdesc->desc_len = TXINFO_DESC_SIZE + TXWI_DESC_SIZE;
}
-/*
- * TX data initialization
- */
-static int rt2800usb_get_tx_data_len(struct queue_entry *entry)
+static void rt2800usb_write_tx_data(struct queue_entry *entry,
+ struct txentry_desc *txdesc)
{
- int length;
+ u8 padding_len;
/*
- * The length _must_ include 4 bytes padding,
- * it should always be multiple of 4,
- * but it must _not_ be a multiple of the USB packet size.
+ * pad(1~3 bytes) is added after each 802.11 payload.
+ * USB end pad(4 bytes) is added at each USB bulk out packet end.
+ * TX frame format is :
+ * | TXINFO | TXWI | 802.11 header | L2 pad | payload | pad | USB end pad |
+ * |<------------- tx_pkt_len ------------->|
*/
- length = roundup(entry->skb->len + 4, 4);
- length += (4 * !(length % entry->queue->usb_maxpacket));
+ rt2800_write_tx_data(entry, txdesc);
+ padding_len = roundup(entry->skb->len + 4, 4) - entry->skb->len;
+ memset(skb_put(entry->skb, padding_len), 0, padding_len);
+}
- return length;
+/*
+ * TX data initialization
+ */
+static int rt2800usb_get_tx_data_len(struct queue_entry *entry)
+{
+ return entry->skb->len;
}
/*
@@ -507,6 +561,7 @@ static const struct ieee80211_ops rt2800usb_mac80211_ops = {
.get_tsf = rt2800_get_tsf,
.rfkill_poll = rt2x00mac_rfkill_poll,
.ampdu_action = rt2800_ampdu_action,
+ .flush = rt2x00mac_flush,
};
static const struct rt2800_ops rt2800usb_rt2800_ops = {
@@ -535,9 +590,9 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {
.link_stats = rt2800_link_stats,
.reset_tuner = rt2800_reset_tuner,
.link_tuner = rt2800_link_tuner,
- .watchdog = rt2x00usb_watchdog,
+ .watchdog = rt2800usb_watchdog,
.write_tx_desc = rt2800usb_write_tx_desc,
- .write_tx_data = rt2800_write_tx_data,
+ .write_tx_data = rt2800usb_write_tx_data,
.write_beacon = rt2800_write_beacon,
.get_tx_data_len = rt2800usb_get_tx_data_len,
.kick_tx_queue = rt2x00usb_kick_tx_queue,
@@ -553,21 +608,21 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {
};
static const struct data_queue_desc rt2800usb_queue_rx = {
- .entry_num = RX_ENTRIES,
+ .entry_num = 128,
.data_size = AGGREGATION_SIZE,
.desc_size = RXINFO_DESC_SIZE + RXWI_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_usb),
};
static const struct data_queue_desc rt2800usb_queue_tx = {
- .entry_num = TX_ENTRIES,
+ .entry_num = 64,
.data_size = AGGREGATION_SIZE,
.desc_size = TXINFO_DESC_SIZE + TXWI_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_usb),
};
static const struct data_queue_desc rt2800usb_queue_bcn = {
- .entry_num = 8 * BEACON_ENTRIES,
+ .entry_num = 8,
.data_size = MGMT_FRAME_SIZE,
.desc_size = TXINFO_DESC_SIZE + TXWI_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_usb),
@@ -599,11 +654,19 @@ static struct usb_device_id rt2800usb_device_table[] = {
/* Abocom */
{ USB_DEVICE(0x07b8, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x07b8, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07b8, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07b8, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07b8, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x1482, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* AirTies */
+ { USB_DEVICE(0x1eda, 0x2310), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Allwin */
{ USB_DEVICE(0x8516, 0x2070), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x8516, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x8516, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x8516, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x8516, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x8516, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Amit */
{ USB_DEVICE(0x15c5, 0x0008), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Askey */
@@ -612,8 +675,13 @@ static struct usb_device_id rt2800usb_device_table[] = {
{ USB_DEVICE(0x0b05, 0x1731), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x0b05, 0x1732), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x0b05, 0x1742), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0b05, 0x1784), USB_DEVICE_DATA(&rt2800usb_ops) },
/* AzureWave */
{ USB_DEVICE(0x13d3, 0x3247), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x13d3, 0x3273), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x13d3, 0x3305), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x13d3, 0x3307), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x13d3, 0x3321), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Belkin */
{ USB_DEVICE(0x050d, 0x8053), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x050d, 0x805c), USB_DEVICE_DATA(&rt2800usb_ops) },
@@ -624,6 +692,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
{ USB_DEVICE(0x14b2, 0x3c06), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x14b2, 0x3c07), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x14b2, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x14b2, 0x3c12), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x14b2, 0x3c23), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x14b2, 0x3c25), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x14b2, 0x3c27), USB_DEVICE_DATA(&rt2800usb_ops) },
@@ -632,17 +701,36 @@ static struct usb_device_id rt2800usb_device_table[] = {
{ USB_DEVICE(0x07aa, 0x002f), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x07aa, 0x003c), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x07aa, 0x003f), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x18c5, 0x0012), USB_DEVICE_DATA(&rt2800usb_ops) },
/* D-Link */
{ USB_DEVICE(0x07d1, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07d1, 0x3c0a), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07d1, 0x3c0d), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07d1, 0x3c0e), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07d1, 0x3c0f), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x07d1, 0x3c11), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x07d1, 0x3c16), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Draytek */
+ { USB_DEVICE(0x07fa, 0x7712), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Edimax */
+ { USB_DEVICE(0x7392, 0x7711), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x7392, 0x7717), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x7392, 0x7718), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Encore */
+ { USB_DEVICE(0x203d, 0x1480), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x203d, 0x14a9), USB_DEVICE_DATA(&rt2800usb_ops) },
/* EnGenius */
{ USB_DEVICE(0x1740, 0x9701), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x1740, 0x9702), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1740, 0x9703), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1740, 0x9705), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1740, 0x9706), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1740, 0x9707), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1740, 0x9708), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1740, 0x9709), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Gigabyte */
{ USB_DEVICE(0x1044, 0x800b), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1044, 0x800d), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Hawking */
{ USB_DEVICE(0x0e66, 0x0001), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x0e66, 0x0003), USB_DEVICE_DATA(&rt2800usb_ops) },
@@ -651,6 +739,10 @@ static struct usb_device_id rt2800usb_device_table[] = {
{ USB_DEVICE(0x0e66, 0x0013), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x0e66, 0x0017), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x0e66, 0x0018), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* I-O DATA */
+ { USB_DEVICE(0x04bb, 0x0945), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x04bb, 0x0947), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x04bb, 0x0948), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Linksys */
{ USB_DEVICE(0x1737, 0x0070), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x1737, 0x0071), USB_DEVICE_DATA(&rt2800usb_ops) },
@@ -658,17 +750,44 @@ static struct usb_device_id rt2800usb_device_table[] = {
{ USB_DEVICE(0x0789, 0x0162), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x0789, 0x0163), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x0789, 0x0164), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0789, 0x0166), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Motorola */
{ USB_DEVICE(0x100d, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) },
/* MSI */
+ { USB_DEVICE(0x0db0, 0x3820), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0db0, 0x3821), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0db0, 0x3822), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0db0, 0x3870), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0db0, 0x3871), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x0db0, 0x6899), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0db0, 0x821a), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0db0, 0x822a), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0db0, 0x822b), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0db0, 0x822c), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0db0, 0x870a), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0db0, 0x871a), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0db0, 0x871b), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0db0, 0x871c), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0db0, 0x899a), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Para */
+ { USB_DEVICE(0x20b8, 0x8888), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Pegatron */
+ { USB_DEVICE(0x1d4d, 0x000c), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x1d4d, 0x000e), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Philips */
{ USB_DEVICE(0x0471, 0x200f), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Planex */
+ { USB_DEVICE(0x2019, 0xab25), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x2019, 0xed06), USB_DEVICE_DATA(&rt2800usb_ops) },
+ /* Quanta */
+ { USB_DEVICE(0x1a32, 0x0304), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Ralink */
+ { USB_DEVICE(0x148f, 0x2070), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x148f, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x148f, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x148f, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x148f, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x148f, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Samsung */
{ USB_DEVICE(0x04e8, 0x2018), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Siemens */
@@ -681,13 +800,22 @@ static struct usb_device_id rt2800usb_device_table[] = {
{ USB_DEVICE(0x0df6, 0x0039), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x0df6, 0x003b), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x0df6, 0x003d), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0df6, 0x003e), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x0df6, 0x003f), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0df6, 0x0040), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0df6, 0x0042), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0df6, 0x0047), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0df6, 0x0048), USB_DEVICE_DATA(&rt2800usb_ops) },
/* SMC */
{ USB_DEVICE(0x083a, 0x6618), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x083a, 0x7511), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x083a, 0x7512), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x083a, 0x7522), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x083a, 0x8522), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x083a, 0xa618), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x083a, 0xa701), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x083a, 0xa702), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x083a, 0xa703), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x083a, 0xb522), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Sparklan */
{ USB_DEVICE(0x15a9, 0x0006), USB_DEVICE_DATA(&rt2800usb_ops) },
@@ -701,101 +829,16 @@ static struct usb_device_id rt2800usb_device_table[] = {
/* Zinwell */
{ USB_DEVICE(0x5a57, 0x0280), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x5a57, 0x0282), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x5a57, 0x0283), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x5a57, 0x5257), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Zyxel */
{ USB_DEVICE(0x0586, 0x3416), USB_DEVICE_DATA(&rt2800usb_ops) },
-#ifdef CONFIG_RT2800USB_RT30XX
- /* Abocom */
- { USB_DEVICE(0x07b8, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x07b8, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x07b8, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* AirTies */
- { USB_DEVICE(0x1eda, 0x2310), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* Allwin */
- { USB_DEVICE(0x8516, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x8516, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x8516, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* ASUS */
- { USB_DEVICE(0x0b05, 0x1784), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* AzureWave */
- { USB_DEVICE(0x13d3, 0x3273), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x13d3, 0x3305), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x13d3, 0x3307), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x13d3, 0x3321), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* Conceptronic */
- { USB_DEVICE(0x14b2, 0x3c12), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* Corega */
- { USB_DEVICE(0x18c5, 0x0012), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* D-Link */
- { USB_DEVICE(0x07d1, 0x3c0a), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x07d1, 0x3c0d), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x07d1, 0x3c0e), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x07d1, 0x3c0f), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x07d1, 0x3c16), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* Draytek */
- { USB_DEVICE(0x07fa, 0x7712), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* Edimax */
- { USB_DEVICE(0x7392, 0x7711), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* Encore */
- { USB_DEVICE(0x203d, 0x1480), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x203d, 0x14a9), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* EnGenius */
- { USB_DEVICE(0x1740, 0x9703), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x1740, 0x9705), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x1740, 0x9706), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x1740, 0x9707), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x1740, 0x9708), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x1740, 0x9709), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* Gigabyte */
- { USB_DEVICE(0x1044, 0x800d), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* I-O DATA */
- { USB_DEVICE(0x04bb, 0x0945), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x04bb, 0x0947), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x04bb, 0x0948), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* Logitec */
- { USB_DEVICE(0x0789, 0x0166), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* MSI */
- { USB_DEVICE(0x0db0, 0x3820), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0db0, 0x3821), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0db0, 0x3822), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0db0, 0x3870), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0db0, 0x3871), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0db0, 0x821a), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0db0, 0x822a), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0db0, 0x822b), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0db0, 0x822c), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0db0, 0x870a), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0db0, 0x871a), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0db0, 0x871b), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0db0, 0x871c), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0db0, 0x899a), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* Para */
- { USB_DEVICE(0x20b8, 0x8888), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* Pegatron */
- { USB_DEVICE(0x1d4d, 0x000c), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x1d4d, 0x000e), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* Planex */
- { USB_DEVICE(0x2019, 0xab25), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* Quanta */
- { USB_DEVICE(0x1a32, 0x0304), USB_DEVICE_DATA(&rt2800usb_ops) },
+#ifdef CONFIG_RT2800USB_RT33XX
/* Ralink */
- { USB_DEVICE(0x148f, 0x2070), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x148f, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x148f, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x148f, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x148f, 0x3370), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x148f, 0x8070), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Sitecom */
- { USB_DEVICE(0x0df6, 0x003e), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0df6, 0x0040), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0df6, 0x0042), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0df6, 0x0047), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0df6, 0x0048), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* SMC */
- { USB_DEVICE(0x083a, 0x7511), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x083a, 0xa701), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x083a, 0xa702), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x083a, 0xa703), USB_DEVICE_DATA(&rt2800usb_ops) },
- /* Zinwell */
- { USB_DEVICE(0x5a57, 0x0283), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x5a57, 0x5257), USB_DEVICE_DATA(&rt2800usb_ops) },
+ { USB_DEVICE(0x0df6, 0x0050), USB_DEVICE_DATA(&rt2800usb_ops) },
#endif
#ifdef CONFIG_RT2800USB_RT35XX
/* Allwin */
@@ -809,12 +852,9 @@ static struct usb_device_id rt2800usb_device_table[] = {
/* I-O DATA */
{ USB_DEVICE(0x04bb, 0x0944), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Ralink */
- { USB_DEVICE(0x148f, 0x3370), USB_DEVICE_DATA(&rt2800usb_ops) },
{ USB_DEVICE(0x148f, 0x3572), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x148f, 0x8070), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Sitecom */
{ USB_DEVICE(0x0df6, 0x0041), USB_DEVICE_DATA(&rt2800usb_ops) },
- { USB_DEVICE(0x0df6, 0x0050), USB_DEVICE_DATA(&rt2800usb_ops) },
/* Zinwell */
{ USB_DEVICE(0x5a57, 0x0284), USB_DEVICE_DATA(&rt2800usb_ops) },
#endif
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.h b/drivers/net/wireless/rt2x00/rt2800usb.h
index 0722badccf86..671ea3592610 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.h
+++ b/drivers/net/wireless/rt2x00/rt2800usb.h
@@ -40,8 +40,8 @@
/*
* DMA descriptor defines.
*/
-#define TXINFO_DESC_SIZE ( 1 * sizeof(__le32) )
-#define RXINFO_DESC_SIZE ( 1 * sizeof(__le32) )
+#define TXINFO_DESC_SIZE (1 * sizeof(__le32))
+#define RXINFO_DESC_SIZE (1 * sizeof(__le32))
/*
* TX Info structure
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 94fe589acfaa..e72117f3fdf5 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -664,6 +664,7 @@ enum rt2x00_flags {
DRIVER_REQUIRE_COPY_IV,
DRIVER_REQUIRE_L2PAD,
DRIVER_REQUIRE_TXSTATUS_FIFO,
+ DRIVER_REQUIRE_TASKLET_CONTEXT,
/*
* Driver features
@@ -915,7 +916,7 @@ struct rt2x00_dev {
* in those cases REGISTER_BUSY_COUNT attempts should be
* taken with a REGISTER_BUSY_DELAY interval.
*/
-#define REGISTER_BUSY_COUNT 5
+#define REGISTER_BUSY_COUNT 100
#define REGISTER_BUSY_DELAY 100
/*
@@ -1133,6 +1134,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
int rt2x00mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params);
void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw);
+void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop);
/*
* Driver allocation handlers.
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index 54ffb5aeb34e..a238e908c854 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -133,7 +133,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
*/
if (!(ant->flags & ANTENNA_RX_DIVERSITY))
config.rx = rt2x00lib_config_antenna_check(config.rx, def->rx);
- else if(config.rx == ANTENNA_SW_DIVERSITY)
+ else if (config.rx == ANTENNA_SW_DIVERSITY)
config.rx = active->rx;
if (!(ant->flags & ANTENNA_TX_DIVERSITY))
@@ -146,7 +146,8 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
* else the changes will be ignored by the device.
*/
if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
- rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF_LINK);
+ rt2x00dev->ops->lib->set_device_state(rt2x00dev,
+ STATE_RADIO_RX_OFF);
/*
* Write new antenna setup to device and reset the link tuner.
@@ -160,7 +161,8 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
memcpy(active, &config, sizeof(config));
if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
- rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON_LINK);
+ rt2x00dev->ops->lib->set_device_state(rt2x00dev,
+ STATE_RADIO_RX_ON);
}
void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c
index fcdb6b0dc40f..64dfb1f6823e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00debug.c
+++ b/drivers/net/wireless/rt2x00/rt2x00debug.c
@@ -162,11 +162,11 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
struct timeval timestamp;
u32 data_len;
- do_gettimeofday(&timestamp);
-
- if (!test_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags))
+ if (likely(!test_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags)))
return;
+ do_gettimeofday(&timestamp);
+
if (skb_queue_len(&intf->frame_dump_skbqueue) > 20) {
DEBUG(rt2x00dev, "txrx dump queue length exceeded.\n");
return;
@@ -342,7 +342,7 @@ static ssize_t rt2x00debug_read_queue_stats(struct file *file,
sprintf(data, "qid\tcount\tlimit\tlength\tindex\tdma done\tdone\n");
queue_for_each(intf->rt2x00dev, queue) {
- spin_lock_irqsave(&queue->lock, irqflags);
+ spin_lock_irqsave(&queue->index_lock, irqflags);
temp += sprintf(temp, "%d\t%d\t%d\t%d\t%d\t%d\t%d\n", queue->qid,
queue->count, queue->limit, queue->length,
@@ -350,7 +350,7 @@ static ssize_t rt2x00debug_read_queue_stats(struct file *file,
queue->index[Q_INDEX_DMA_DONE],
queue->index[Q_INDEX_DONE]);
- spin_unlock_irqrestore(&queue->lock, irqflags);
+ spin_unlock_irqrestore(&queue->index_lock, irqflags);
}
size = strlen(data);
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 5ba79b935f09..bd3afc92f434 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -68,7 +68,8 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev)
/*
* Enable RX.
*/
- rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON);
+ rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_RX_ON);
+ rt2x00link_start_tuner(rt2x00dev);
/*
* Start watchdog monitoring.
@@ -102,7 +103,8 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev)
/*
* Disable RX.
*/
- rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF);
+ rt2x00link_stop_tuner(rt2x00dev);
+ rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_RX_OFF);
/*
* Disable radio.
@@ -113,23 +115,6 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev)
rt2x00leds_led_radio(rt2x00dev, false);
}
-void rt2x00lib_toggle_rx(struct rt2x00_dev *rt2x00dev, enum dev_state state)
-{
- /*
- * When we are disabling the RX, we should also stop the link tuner.
- */
- if (state == STATE_RADIO_RX_OFF)
- rt2x00link_stop_tuner(rt2x00dev);
-
- rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
-
- /*
- * When we are enabling the RX, we should also start the link tuner.
- */
- if (state == STATE_RADIO_RX_ON)
- rt2x00link_start_tuner(rt2x00dev);
-}
-
static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,
struct ieee80211_vif *vif)
{
@@ -265,10 +250,9 @@ void rt2x00lib_txdone(struct queue_entry *entry,
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
enum data_queue_qid qid = skb_get_queue_mapping(entry->skb);
- unsigned int header_length = ieee80211_get_hdrlen_from_skb(entry->skb);
+ unsigned int header_length, i;
u8 rate_idx, rate_flags, retry_rates;
u8 skbdesc_flags = skbdesc->flags;
- unsigned int i;
bool success;
/*
@@ -287,6 +271,11 @@ void rt2x00lib_txdone(struct queue_entry *entry,
skbdesc->flags &= ~SKBDESC_DESC_IN_SKB;
/*
+ * Determine the length of 802.11 header.
+ */
+ header_length = ieee80211_get_hdrlen_from_skb(entry->skb);
+
+ /*
* Remove L2 padding which was added during
*/
if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags))
@@ -390,9 +379,12 @@ void rt2x00lib_txdone(struct queue_entry *entry,
* through a mac80211 library call (RTS/CTS) then we should not
* send the status report back.
*/
- if (!(skbdesc_flags & SKBDESC_NOT_MAC80211))
- ieee80211_tx_status(rt2x00dev->hw, entry->skb);
- else
+ if (!(skbdesc_flags & SKBDESC_NOT_MAC80211)) {
+ if (test_bit(DRIVER_REQUIRE_TASKLET_CONTEXT, &rt2x00dev->flags))
+ ieee80211_tx_status(rt2x00dev->hw, entry->skb);
+ else
+ ieee80211_tx_status_ni(rt2x00dev->hw, entry->skb);
+ } else
dev_kfree_skb_any(entry->skb);
/*
@@ -483,6 +475,10 @@ void rt2x00lib_rxdone(struct queue_entry *entry)
unsigned int header_length;
int rate_idx;
+ if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) ||
+ !test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
+ goto submit_entry;
+
if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags))
goto submit_entry;
@@ -567,9 +563,13 @@ void rt2x00lib_rxdone(struct queue_entry *entry)
entry->skb = skb;
submit_entry:
- rt2x00dev->ops->lib->clear_entry(entry);
- rt2x00queue_index_inc(entry->queue, Q_INDEX);
+ entry->flags = 0;
rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE);
+ if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) &&
+ test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) {
+ rt2x00dev->ops->lib->clear_entry(entry);
+ rt2x00queue_index_inc(entry->queue, Q_INDEX);
+ }
}
EXPORT_SYMBOL_GPL(rt2x00lib_rxdone);
@@ -678,7 +678,7 @@ static void rt2x00lib_rate(struct ieee80211_rate *entry,
{
entry->flags = 0;
entry->bitrate = rate->bitrate;
- entry->hw_value =index;
+ entry->hw_value = index;
entry->hw_value_short = index;
if (rate->flags & DEV_RATE_SHORT_PREAMBLE)
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
index 619da23b7b56..2cf68f82674b 100644
--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
+++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
@@ -57,7 +57,7 @@ static inline const struct rt2x00_rate *rt2x00_get_rate(const u16 hw_value)
}
#define RATE_MCS(__mode, __mcs) \
- ( (((__mode) & 0x00ff) << 8) | ((__mcs) & 0x00ff) )
+ ((((__mode) & 0x00ff) << 8) | ((__mcs) & 0x00ff))
static inline int rt2x00_get_rate_mcs(const u16 mcs_value)
{
@@ -69,7 +69,6 @@ static inline int rt2x00_get_rate_mcs(const u16 mcs_value)
*/
int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev);
void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev);
-void rt2x00lib_toggle_rx(struct rt2x00_dev *rt2x00dev, enum dev_state state);
/*
* Initialization handlers.
diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c
index b971d8798ebf..bfda60eaf4ef 100644
--- a/drivers/net/wireless/rt2x00/rt2x00link.c
+++ b/drivers/net/wireless/rt2x00/rt2x00link.c
@@ -67,7 +67,7 @@
(__avg).avg_weight ? \
((((__avg).avg_weight * ((AVG_SAMPLES) - 1)) + \
((__val) * (AVG_FACTOR))) / \
- (AVG_SAMPLES) ) : \
+ (AVG_SAMPLES)) : \
((__val) * (AVG_FACTOR)); \
__new.avg = __new.avg_weight / (AVG_FACTOR); \
__new; \
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index c3c206a97d54..829bf4be9bc3 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -283,14 +283,8 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
* invalid behavior in the device.
*/
memcpy(&intf->mac, vif->addr, ETH_ALEN);
- if (vif->type == NL80211_IFTYPE_AP) {
- memcpy(&intf->bssid, vif->addr, ETH_ALEN);
- rt2x00lib_config_intf(rt2x00dev, intf, vif->type,
- intf->mac, intf->bssid);
- } else {
- rt2x00lib_config_intf(rt2x00dev, intf, vif->type,
- intf->mac, NULL);
- }
+ rt2x00lib_config_intf(rt2x00dev, intf, vif->type,
+ intf->mac, NULL);
/*
* Some filters depend on the current working mode. We can force
@@ -358,7 +352,7 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
* if for any reason the link tuner must be reset, this will be
* handled by rt2x00lib_config().
*/
- rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF_LINK);
+ rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_RX_OFF);
/*
* When we've just turned on the radio, we want to reprogram
@@ -376,7 +370,7 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
rt2x00lib_config_antenna(rt2x00dev, rt2x00dev->default_ant);
/* Turn RX back on */
- rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON_LINK);
+ rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_RX_ON);
return 0;
}
@@ -719,3 +713,41 @@ void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw)
wiphy_rfkill_set_hw_state(hw->wiphy, !active);
}
EXPORT_SYMBOL_GPL(rt2x00mac_rfkill_poll);
+
+void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop)
+{
+ struct rt2x00_dev *rt2x00dev = hw->priv;
+ struct data_queue *queue;
+ unsigned int i = 0;
+
+ ieee80211_stop_queues(hw);
+
+ /*
+ * Run over all queues to kick them, this will force
+ * any pending frames to be transmitted.
+ */
+ tx_queue_for_each(rt2x00dev, queue) {
+ rt2x00dev->ops->lib->kick_tx_queue(queue);
+ }
+
+ /**
+ * All queues have been kicked, now wait for each queue
+ * to become empty. With a bit of luck, we only have to wait
+ * for the first queue to become empty, because while waiting
+ * for the that queue, the other queues will have transmitted
+ * all their frames as well (since they were already kicked).
+ */
+ tx_queue_for_each(rt2x00dev, queue) {
+ for (i = 0; i < 10; i++) {
+ if (rt2x00queue_empty(queue))
+ break;
+ msleep(100);
+ }
+
+ if (!rt2x00queue_empty(queue))
+ WARNING(rt2x00dev, "Failed to flush queue %d", queue->qid);
+ }
+
+ ieee80211_wake_queues(hw);
+}
+EXPORT_SYMBOL_GPL(rt2x00mac_flush);
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index 2449d785cf8d..868ca19b13ea 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -105,7 +105,7 @@ static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev,
*/
addr = dma_alloc_coherent(rt2x00dev->dev,
queue->limit * queue->desc_size,
- &dma, GFP_KERNEL | GFP_DMA);
+ &dma, GFP_KERNEL);
if (!addr)
return -ENOMEM;
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index e360d287defb..a3d79c7a21c6 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -204,8 +204,10 @@ void rt2x00queue_remove_l2pad(struct sk_buff *skb, unsigned int header_length)
if (!l2pad)
return;
- memmove(skb->data + l2pad, skb->data, header_length);
- skb_pull(skb, l2pad);
+ memmove(skb->data + header_length, skb->data + header_length + l2pad,
+ skb->len - header_length - l2pad);
+
+ skb_trim(skb, skb->len - l2pad);
}
static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry,
@@ -311,14 +313,6 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
memset(txdesc, 0, sizeof(*txdesc));
/*
- * Initialize information from queue
- */
- txdesc->qid = entry->queue->qid;
- txdesc->cw_min = entry->queue->cw_min;
- txdesc->cw_max = entry->queue->cw_max;
- txdesc->aifs = entry->queue->aifs;
-
- /*
* Header and frame information.
*/
txdesc->length = entry->skb->len;
@@ -460,12 +454,9 @@ static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry,
rt2x00debug_dump_frame(queue->rt2x00dev, DUMP_FRAME_TX, entry->skb);
}
-static void rt2x00queue_kick_tx_queue(struct queue_entry *entry,
+static void rt2x00queue_kick_tx_queue(struct data_queue *queue,
struct txentry_desc *txdesc)
{
- struct data_queue *queue = entry->queue;
- struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
-
/*
* Check if we need to kick the queue, there are however a few rules
* 1) Don't kick unless this is the last in frame in a burst.
@@ -477,7 +468,7 @@ static void rt2x00queue_kick_tx_queue(struct queue_entry *entry,
*/
if (rt2x00queue_threshold(queue) ||
!test_bit(ENTRY_TXD_BURST, &txdesc->flags))
- rt2x00dev->ops->lib->kick_tx_queue(queue);
+ queue->rt2x00dev->ops->lib->kick_tx_queue(queue);
}
int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb,
@@ -567,7 +558,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb,
rt2x00queue_index_inc(queue, Q_INDEX);
rt2x00queue_write_tx_descriptor(entry, &txdesc);
- rt2x00queue_kick_tx_queue(entry, &txdesc);
+ rt2x00queue_kick_tx_queue(queue, &txdesc);
return 0;
}
@@ -649,10 +640,10 @@ void rt2x00queue_for_each_entry(struct data_queue *queue,
* it should not be kicked during this run, since it
* is part of another TX operation.
*/
- spin_lock_irqsave(&queue->lock, irqflags);
+ spin_lock_irqsave(&queue->index_lock, irqflags);
index_start = queue->index[start];
index_end = queue->index[end];
- spin_unlock_irqrestore(&queue->lock, irqflags);
+ spin_unlock_irqrestore(&queue->index_lock, irqflags);
/*
* Start from the TX done pointer, this guarentees that we will
@@ -706,11 +697,11 @@ struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue,
return NULL;
}
- spin_lock_irqsave(&queue->lock, irqflags);
+ spin_lock_irqsave(&queue->index_lock, irqflags);
entry = &queue->entries[queue->index[index]];
- spin_unlock_irqrestore(&queue->lock, irqflags);
+ spin_unlock_irqrestore(&queue->index_lock, irqflags);
return entry;
}
@@ -726,7 +717,7 @@ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index)
return;
}
- spin_lock_irqsave(&queue->lock, irqflags);
+ spin_lock_irqsave(&queue->index_lock, irqflags);
queue->index[index]++;
if (queue->index[index] >= queue->limit)
@@ -741,7 +732,7 @@ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index)
queue->count++;
}
- spin_unlock_irqrestore(&queue->lock, irqflags);
+ spin_unlock_irqrestore(&queue->index_lock, irqflags);
}
static void rt2x00queue_reset(struct data_queue *queue)
@@ -749,7 +740,7 @@ static void rt2x00queue_reset(struct data_queue *queue)
unsigned long irqflags;
unsigned int i;
- spin_lock_irqsave(&queue->lock, irqflags);
+ spin_lock_irqsave(&queue->index_lock, irqflags);
queue->count = 0;
queue->length = 0;
@@ -759,7 +750,7 @@ static void rt2x00queue_reset(struct data_queue *queue)
queue->last_action[i] = jiffies;
}
- spin_unlock_irqrestore(&queue->lock, irqflags);
+ spin_unlock_irqrestore(&queue->index_lock, irqflags);
}
void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev)
@@ -809,8 +800,8 @@ static int rt2x00queue_alloc_entries(struct data_queue *queue,
return -ENOMEM;
#define QUEUE_ENTRY_PRIV_OFFSET(__base, __index, __limit, __esize, __psize) \
- ( ((char *)(__base)) + ((__limit) * (__esize)) + \
- ((__index) * (__psize)) )
+ (((char *)(__base)) + ((__limit) * (__esize)) + \
+ ((__index) * (__psize)))
for (i = 0; i < queue->limit; i++) {
entries[i].flags = 0;
@@ -911,7 +902,7 @@ void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev)
static void rt2x00queue_init(struct rt2x00_dev *rt2x00dev,
struct data_queue *queue, enum data_queue_qid qid)
{
- spin_lock_init(&queue->lock);
+ spin_lock_init(&queue->index_lock);
queue->rt2x00dev = rt2x00dev;
queue->qid = qid;
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index d81d85f34866..29b051ac6401 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -43,22 +43,6 @@
#define AGGREGATION_SIZE 3840
/**
- * DOC: Number of entries per queue
- *
- * Under normal load without fragmentation, 12 entries are sufficient
- * without the queue being filled up to the maximum. When using fragmentation
- * and the queue threshold code, we need to add some additional margins to
- * make sure the queue will never (or only under extreme load) fill up
- * completely.
- * Since we don't use preallocated DMA, having a large number of queue entries
- * will have minimal impact on the memory requirements for the queue.
- */
-#define RX_ENTRIES 24
-#define TX_ENTRIES 24
-#define BEACON_ENTRIES 1
-#define ATIM_ENTRIES 8
-
-/**
* enum data_queue_qid: Queue identification
*
* @QID_AC_BE: AC BE queue
@@ -296,7 +280,6 @@ enum txentry_desc_flags {
* Summary of information for the frame descriptor before sending a TX frame.
*
* @flags: Descriptor flags (See &enum queue_entry_flags).
- * @qid: Queue identification (See &enum data_queue_qid).
* @length: Length of the entire frame.
* @header_length: Length of 802.11 header.
* @length_high: PLCP length high word.
@@ -309,11 +292,8 @@ enum txentry_desc_flags {
* @rate_mode: Rate mode (See @enum rate_modulation).
* @mpdu_density: MDPU density.
* @retry_limit: Max number of retries.
- * @aifs: AIFS value.
* @ifs: IFS value.
* @txop: IFS value for 11n capable chips.
- * @cw_min: cwmin value.
- * @cw_max: cwmax value.
* @cipher: Cipher type used for encryption.
* @key_idx: Key index used for encryption.
* @iv_offset: Position where IV should be inserted by hardware.
@@ -322,8 +302,6 @@ enum txentry_desc_flags {
struct txentry_desc {
unsigned long flags;
- enum data_queue_qid qid;
-
u16 length;
u16 header_length;
@@ -339,11 +317,8 @@ struct txentry_desc {
u16 mpdu_density;
short retry_limit;
- short aifs;
short ifs;
short txop;
- short cw_min;
- short cw_max;
enum cipher cipher;
u16 key_idx;
@@ -423,7 +398,7 @@ enum queue_index {
* @entries: Base address of the &struct queue_entry which are
* part of this queue.
* @qid: The queue identification, see &enum data_queue_qid.
- * @lock: Spinlock to protect index handling. Whenever @index, @index_done or
+ * @index_lock: Spinlock to protect index handling. Whenever @index, @index_done or
* @index_crypt needs to be changed this lock should be grabbed to prevent
* index corruption due to concurrency.
* @count: Number of frames handled in the queue.
@@ -447,7 +422,7 @@ struct data_queue {
enum data_queue_qid qid;
- spinlock_t lock;
+ spinlock_t index_lock;
unsigned int count;
unsigned short limit;
unsigned short threshold;
@@ -618,10 +593,10 @@ static inline int rt2x00queue_threshold(struct data_queue *queue)
}
/**
- * rt2x00queue_timeout - Check if a timeout occured for STATUS reorts
+ * rt2x00queue_status_timeout - Check if a timeout occured for STATUS reports
* @queue: Queue to check.
*/
-static inline int rt2x00queue_timeout(struct data_queue *queue)
+static inline int rt2x00queue_status_timeout(struct data_queue *queue)
{
return time_after(queue->last_action[Q_INDEX_DMA_DONE],
queue->last_action[Q_INDEX_DONE] + (HZ / 10));
diff --git a/drivers/net/wireless/rt2x00/rt2x00reg.h b/drivers/net/wireless/rt2x00/rt2x00reg.h
index cef94621cef7..ed71be95136d 100644
--- a/drivers/net/wireless/rt2x00/rt2x00reg.h
+++ b/drivers/net/wireless/rt2x00/rt2x00reg.h
@@ -85,8 +85,6 @@ enum dev_state {
STATE_RADIO_OFF,
STATE_RADIO_RX_ON,
STATE_RADIO_RX_OFF,
- STATE_RADIO_RX_ON_LINK,
- STATE_RADIO_RX_OFF_LINK,
STATE_RADIO_IRQ_ON,
STATE_RADIO_IRQ_OFF,
STATE_RADIO_IRQ_ON_ISR,
diff --git a/drivers/net/wireless/rt2x00/rt2x00soc.c b/drivers/net/wireless/rt2x00/rt2x00soc.c
index fc98063de71d..2aa5c38022f3 100644
--- a/drivers/net/wireless/rt2x00/rt2x00soc.c
+++ b/drivers/net/wireless/rt2x00/rt2x00soc.c
@@ -40,6 +40,8 @@ static void rt2x00soc_free_reg(struct rt2x00_dev *rt2x00dev)
kfree(rt2x00dev->eeprom);
rt2x00dev->eeprom = NULL;
+
+ iounmap(rt2x00dev->csr.base);
}
static int rt2x00soc_alloc_reg(struct rt2x00_dev *rt2x00dev)
@@ -51,9 +53,9 @@ static int rt2x00soc_alloc_reg(struct rt2x00_dev *rt2x00dev)
if (!res)
return -ENODEV;
- rt2x00dev->csr.base = (void __iomem *)KSEG1ADDR(res->start);
+ rt2x00dev->csr.base = ioremap(res->start, resource_size(res));
if (!rt2x00dev->csr.base)
- goto exit;
+ return -ENOMEM;
rt2x00dev->eeprom = kzalloc(rt2x00dev->ops->eeprom_size, GFP_KERNEL);
if (!rt2x00dev->eeprom)
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index b3317df7a7d4..9ac14598e2a0 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -226,9 +226,7 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
* Schedule the delayed work for reading the TX status
* from the device.
*/
- if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) &&
- test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
- ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->txdone_work);
+ ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->txdone_work);
}
static void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
@@ -323,21 +321,6 @@ static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue)
rt2x00dev->txdone_work.func(&rt2x00dev->txdone_work);
/*
- * Security measure: if the driver did override the
- * txdone_work function, and the hardware did arrive
- * in a state which causes it to malfunction, it is
- * possible that the driver couldn't handle the txdone
- * event correctly. So after giving the driver the
- * chance to cleanup, we now force a cleanup of any
- * leftovers.
- */
- if (!rt2x00queue_empty(queue)) {
- WARNING(queue->rt2x00dev, "TX queue %d DMA timed out,"
- " status handling failed, invoke hard reset", queue->qid);
- rt2x00usb_work_txdone(&rt2x00dev->txdone_work);
- }
-
- /*
* The queue has been reset, and mac80211 is allowed to use the
* queue again.
*/
@@ -361,7 +344,7 @@ void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev)
if (!rt2x00queue_empty(queue)) {
if (rt2x00queue_dma_timeout(queue))
rt2x00usb_watchdog_tx_dma(queue);
- if (rt2x00queue_timeout(queue))
+ if (rt2x00queue_status_timeout(queue))
rt2x00usb_watchdog_tx_status(queue);
}
}
@@ -424,9 +407,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
* Schedule the delayed work for reading the RX status
* from the device.
*/
- if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) &&
- test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
- ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->rxdone_work);
+ ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->rxdone_work);
}
/*
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index af548c87f108..6b09b01f634f 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -1623,8 +1623,7 @@ static void rt61pci_toggle_rx(struct rt2x00_dev *rt2x00dev,
rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, &reg);
rt2x00_set_field32(&reg, TXRX_CSR0_DISABLE_RX,
- (state == STATE_RADIO_RX_OFF) ||
- (state == STATE_RADIO_RX_OFF_LINK));
+ (state == STATE_RADIO_RX_OFF));
rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg);
}
@@ -1745,9 +1744,7 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev,
rt61pci_disable_radio(rt2x00dev);
break;
case STATE_RADIO_RX_ON:
- case STATE_RADIO_RX_ON_LINK:
case STATE_RADIO_RX_OFF:
- case STATE_RADIO_RX_OFF_LINK:
rt61pci_toggle_rx(rt2x00dev, state);
break;
case STATE_RADIO_IRQ_ON:
@@ -1789,10 +1786,10 @@ static void rt61pci_write_tx_desc(struct queue_entry *entry,
* Start writing the descriptor words.
*/
rt2x00_desc_read(txd, 1, &word);
- rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->qid);
- rt2x00_set_field32(&word, TXD_W1_AIFSN, txdesc->aifs);
- rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min);
- rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max);
+ rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, entry->queue->qid);
+ rt2x00_set_field32(&word, TXD_W1_AIFSN, entry->queue->aifs);
+ rt2x00_set_field32(&word, TXD_W1_CWMIN, entry->queue->cw_min);
+ rt2x00_set_field32(&word, TXD_W1_CWMAX, entry->queue->cw_max);
rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, txdesc->iv_offset);
rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE,
test_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags));
@@ -1820,7 +1817,7 @@ static void rt61pci_write_tx_desc(struct queue_entry *entry,
rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1);
rt2x00_desc_write(txd, 5, word);
- if (txdesc->qid != QID_BEACON) {
+ if (entry->queue->qid != QID_BEACON) {
rt2x00_desc_read(txd, 6, &word);
rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS,
skbdesc->skb_dma);
@@ -1866,8 +1863,8 @@ static void rt61pci_write_tx_desc(struct queue_entry *entry,
* Register descriptor details in skb frame descriptor.
*/
skbdesc->desc = txd;
- skbdesc->desc_len =
- (txdesc->qid == QID_BEACON) ? TXINFO_SIZE : TXD_DESC_SIZE;
+ skbdesc->desc_len = (entry->queue->qid == QID_BEACON) ? TXINFO_SIZE :
+ TXD_DESC_SIZE;
}
/*
@@ -2078,7 +2075,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev)
* that the TX_STA_FIFO stack has a size of 16. We stick to our
* tx ring size for now.
*/
- for (i = 0; i < TX_ENTRIES; i++) {
+ for (i = 0; i < rt2x00dev->ops->tx->entry_num; i++) {
rt2x00pci_register_read(rt2x00dev, STA_CSR4, &reg);
if (!rt2x00_get_field32(reg, STA_CSR4_VALID))
break;
@@ -2824,6 +2821,7 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = {
.conf_tx = rt61pci_conf_tx,
.get_tsf = rt61pci_get_tsf,
.rfkill_poll = rt2x00mac_rfkill_poll,
+ .flush = rt2x00mac_flush,
};
static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
@@ -2857,21 +2855,21 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
};
static const struct data_queue_desc rt61pci_queue_rx = {
- .entry_num = RX_ENTRIES,
+ .entry_num = 32,
.data_size = DATA_FRAME_SIZE,
.desc_size = RXD_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_pci),
};
static const struct data_queue_desc rt61pci_queue_tx = {
- .entry_num = TX_ENTRIES,
+ .entry_num = 32,
.data_size = DATA_FRAME_SIZE,
.desc_size = TXD_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_pci),
};
static const struct data_queue_desc rt61pci_queue_bcn = {
- .entry_num = 4 * BEACON_ENTRIES,
+ .entry_num = 4,
.data_size = 0, /* No DMA required for beacons */
.desc_size = TXINFO_SIZE,
.priv_size = sizeof(struct queue_entry_priv_pci),
diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h
index e2e728ab0b2e..afc803b7959f 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.h
+++ b/drivers/net/wireless/rt2x00/rt61pci.h
@@ -412,7 +412,7 @@ struct hw_pairwise_ta_entry {
* DROP_VERSION_ERROR: Drop version error frame.
* DROP_MULTICAST: Drop multicast frames.
* DROP_BORADCAST: Drop broadcast frames.
- * ROP_ACK_CTS: Drop received ACK and CTS.
+ * DROP_ACK_CTS: Drop received ACK and CTS.
*/
#define TXRX_CSR0 0x3040
#define TXRX_CSR0_RX_ACK_TIMEOUT FIELD32(0x000001ff)
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 9be8089317e4..6f04552f5819 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -40,7 +40,7 @@
/*
* Allow hardware encryption to be disabled.
*/
-static int modparam_nohwcrypt = 0;
+static int modparam_nohwcrypt;
module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
@@ -1331,8 +1331,7 @@ static void rt73usb_toggle_rx(struct rt2x00_dev *rt2x00dev,
rt2x00usb_register_read(rt2x00dev, TXRX_CSR0, &reg);
rt2x00_set_field32(&reg, TXRX_CSR0_DISABLE_RX,
- (state == STATE_RADIO_RX_OFF) ||
- (state == STATE_RADIO_RX_OFF_LINK));
+ (state == STATE_RADIO_RX_OFF));
rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg);
}
@@ -1403,9 +1402,7 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev,
rt73usb_disable_radio(rt2x00dev);
break;
case STATE_RADIO_RX_ON:
- case STATE_RADIO_RX_ON_LINK:
case STATE_RADIO_RX_OFF:
- case STATE_RADIO_RX_OFF_LINK:
rt73usb_toggle_rx(rt2x00dev, state);
break;
case STATE_RADIO_IRQ_ON:
@@ -1472,10 +1469,10 @@ static void rt73usb_write_tx_desc(struct queue_entry *entry,
rt2x00_desc_write(txd, 0, word);
rt2x00_desc_read(txd, 1, &word);
- rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->qid);
- rt2x00_set_field32(&word, TXD_W1_AIFSN, txdesc->aifs);
- rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min);
- rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max);
+ rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, entry->queue->qid);
+ rt2x00_set_field32(&word, TXD_W1_AIFSN, entry->queue->aifs);
+ rt2x00_set_field32(&word, TXD_W1_CWMIN, entry->queue->cw_min);
+ rt2x00_set_field32(&word, TXD_W1_CWMAX, entry->queue->cw_max);
rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, txdesc->iv_offset);
rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE,
test_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags));
@@ -2264,6 +2261,7 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = {
.conf_tx = rt73usb_conf_tx,
.get_tsf = rt73usb_get_tsf,
.rfkill_poll = rt2x00mac_rfkill_poll,
+ .flush = rt2x00mac_flush,
};
static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
@@ -2296,21 +2294,21 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
};
static const struct data_queue_desc rt73usb_queue_rx = {
- .entry_num = RX_ENTRIES,
+ .entry_num = 32,
.data_size = DATA_FRAME_SIZE,
.desc_size = RXD_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_usb),
};
static const struct data_queue_desc rt73usb_queue_tx = {
- .entry_num = TX_ENTRIES,
+ .entry_num = 32,
.data_size = DATA_FRAME_SIZE,
.desc_size = TXD_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_usb),
};
static const struct data_queue_desc rt73usb_queue_bcn = {
- .entry_num = 4 * BEACON_ENTRIES,
+ .entry_num = 4,
.data_size = MGMT_FRAME_SIZE,
.desc_size = TXINFO_SIZE,
.priv_size = sizeof(struct queue_entry_priv_usb),
diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h
index 44d5b2bebd39..1315ce5c992f 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.h
+++ b/drivers/net/wireless/rt2x00/rt73usb.h
@@ -322,7 +322,7 @@ struct hw_pairwise_ta_entry {
* DROP_VERSION_ERROR: Drop version error frame.
* DROP_MULTICAST: Drop multicast frames.
* DROP_BORADCAST: Drop broadcast frames.
- * ROP_ACK_CTS: Drop received ACK and CTS.
+ * DROP_ACK_CTS: Drop received ACK and CTS.
*/
#define TXRX_CSR0 0x3040
#define TXRX_CSR0_RX_ACK_TIMEOUT FIELD32(0x000001ff)
diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c
index 38fa8244cc96..eeee244fcaab 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c
@@ -553,6 +553,46 @@ static int rtl8187b_init_status_urb(struct ieee80211_hw *dev)
return ret;
}
+static void rtl8187_set_anaparam(struct rtl8187_priv *priv, bool rfon)
+{
+ u32 anaparam, anaparam2;
+ u8 anaparam3, reg;
+
+ if (!priv->is_rtl8187b) {
+ if (rfon) {
+ anaparam = RTL8187_RTL8225_ANAPARAM_ON;
+ anaparam2 = RTL8187_RTL8225_ANAPARAM2_ON;
+ } else {
+ anaparam = RTL8187_RTL8225_ANAPARAM_OFF;
+ anaparam2 = RTL8187_RTL8225_ANAPARAM2_OFF;
+ }
+ } else {
+ if (rfon) {
+ anaparam = RTL8187B_RTL8225_ANAPARAM_ON;
+ anaparam2 = RTL8187B_RTL8225_ANAPARAM2_ON;
+ anaparam3 = RTL8187B_RTL8225_ANAPARAM3_ON;
+ } else {
+ anaparam = RTL8187B_RTL8225_ANAPARAM_OFF;
+ anaparam2 = RTL8187B_RTL8225_ANAPARAM2_OFF;
+ anaparam3 = RTL8187B_RTL8225_ANAPARAM3_OFF;
+ }
+ }
+
+ rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
+ RTL818X_EEPROM_CMD_CONFIG);
+ reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
+ reg |= RTL818X_CONFIG3_ANAPARAM_WRITE;
+ rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg);
+ rtl818x_iowrite32(priv, &priv->map->ANAPARAM, anaparam);
+ rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, anaparam2);
+ if (priv->is_rtl8187b)
+ rtl818x_iowrite8(priv, &priv->map->ANAPARAM3, anaparam3);
+ reg &= ~RTL818X_CONFIG3_ANAPARAM_WRITE;
+ rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg);
+ rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
+ RTL818X_EEPROM_CMD_NORMAL);
+}
+
static int rtl8187_cmd_reset(struct ieee80211_hw *dev)
{
struct rtl8187_priv *priv = dev->priv;
@@ -603,19 +643,7 @@ static int rtl8187_init_hw(struct ieee80211_hw *dev)
int res;
/* reset */
- rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
- RTL818X_EEPROM_CMD_CONFIG);
- reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
- rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg |
- RTL818X_CONFIG3_ANAPARAM_WRITE);
- rtl818x_iowrite32(priv, &priv->map->ANAPARAM,
- RTL8187_RTL8225_ANAPARAM_ON);
- rtl818x_iowrite32(priv, &priv->map->ANAPARAM2,
- RTL8187_RTL8225_ANAPARAM2_ON);
- rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg &
- ~RTL818X_CONFIG3_ANAPARAM_WRITE);
- rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
- RTL818X_EEPROM_CMD_NORMAL);
+ rtl8187_set_anaparam(priv, true);
rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0);
@@ -629,17 +657,7 @@ static int rtl8187_init_hw(struct ieee80211_hw *dev)
if (res)
return res;
- rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
- reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
- rtl818x_iowrite8(priv, &priv->map->CONFIG3,
- reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
- rtl818x_iowrite32(priv, &priv->map->ANAPARAM,
- RTL8187_RTL8225_ANAPARAM_ON);
- rtl818x_iowrite32(priv, &priv->map->ANAPARAM2,
- RTL8187_RTL8225_ANAPARAM2_ON);
- rtl818x_iowrite8(priv, &priv->map->CONFIG3,
- reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
- rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
+ rtl8187_set_anaparam(priv, true);
/* setup card */
rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0);
@@ -712,10 +730,9 @@ static const u8 rtl8187b_reg_table[][3] = {
{0x58, 0x4B, 1}, {0x59, 0x00, 1}, {0x5A, 0x4B, 1}, {0x5B, 0x00, 1},
{0x60, 0x4B, 1}, {0x61, 0x09, 1}, {0x62, 0x4B, 1}, {0x63, 0x09, 1},
- {0xCE, 0x0F, 1}, {0xCF, 0x00, 1}, {0xE0, 0xFF, 1}, {0xE1, 0x0F, 1},
- {0xE2, 0x00, 1}, {0xF0, 0x4E, 1}, {0xF1, 0x01, 1}, {0xF2, 0x02, 1},
- {0xF3, 0x03, 1}, {0xF4, 0x04, 1}, {0xF5, 0x05, 1}, {0xF6, 0x06, 1},
- {0xF7, 0x07, 1}, {0xF8, 0x08, 1},
+ {0xCE, 0x0F, 1}, {0xCF, 0x00, 1}, {0xF0, 0x4E, 1}, {0xF1, 0x01, 1},
+ {0xF2, 0x02, 1}, {0xF3, 0x03, 1}, {0xF4, 0x04, 1}, {0xF5, 0x05, 1},
+ {0xF6, 0x06, 1}, {0xF7, 0x07, 1}, {0xF8, 0x08, 1},
{0x4E, 0x00, 2}, {0x0C, 0x04, 2}, {0x21, 0x61, 2}, {0x22, 0x68, 2},
{0x23, 0x6F, 2}, {0x24, 0x76, 2}, {0x25, 0x7D, 2}, {0x26, 0x84, 2},
@@ -723,14 +740,13 @@ static const u8 rtl8187b_reg_table[][3] = {
{0x52, 0x04, 2}, {0x53, 0xA0, 2}, {0x54, 0x1F, 2}, {0x55, 0x23, 2},
{0x56, 0x45, 2}, {0x57, 0x67, 2}, {0x58, 0x08, 2}, {0x59, 0x08, 2},
{0x5A, 0x08, 2}, {0x5B, 0x08, 2}, {0x60, 0x08, 2}, {0x61, 0x08, 2},
- {0x62, 0x08, 2}, {0x63, 0x08, 2}, {0x64, 0xCF, 2}, {0x72, 0x56, 2},
- {0x73, 0x9A, 2},
+ {0x62, 0x08, 2}, {0x63, 0x08, 2}, {0x64, 0xCF, 2},
- {0x34, 0xF0, 0}, {0x35, 0x0F, 0}, {0x5B, 0x40, 0}, {0x84, 0x88, 0},
- {0x85, 0x24, 0}, {0x88, 0x54, 0}, {0x8B, 0xB8, 0}, {0x8C, 0x07, 0},
- {0x8D, 0x00, 0}, {0x94, 0x1B, 0}, {0x95, 0x12, 0}, {0x96, 0x00, 0},
- {0x97, 0x06, 0}, {0x9D, 0x1A, 0}, {0x9F, 0x10, 0}, {0xB4, 0x22, 0},
- {0xBE, 0x80, 0}, {0xDB, 0x00, 0}, {0xEE, 0x00, 0}, {0x4C, 0x00, 2},
+ {0x5B, 0x40, 0}, {0x84, 0x88, 0}, {0x85, 0x24, 0}, {0x88, 0x54, 0},
+ {0x8B, 0xB8, 0}, {0x8C, 0x07, 0}, {0x8D, 0x00, 0}, {0x94, 0x1B, 0},
+ {0x95, 0x12, 0}, {0x96, 0x00, 0}, {0x97, 0x06, 0}, {0x9D, 0x1A, 0},
+ {0x9F, 0x10, 0}, {0xB4, 0x22, 0}, {0xBE, 0x80, 0}, {0xDB, 0x00, 0},
+ {0xEE, 0x00, 0}, {0x4C, 0x00, 2},
{0x9F, 0x00, 3}, {0x8C, 0x01, 0}, {0x8D, 0x10, 0}, {0x8E, 0x08, 0},
{0x8F, 0x00, 0}
@@ -742,48 +758,34 @@ static int rtl8187b_init_hw(struct ieee80211_hw *dev)
int res, i;
u8 reg;
- rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
- RTL818X_EEPROM_CMD_CONFIG);
-
- reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
- reg |= RTL818X_CONFIG3_ANAPARAM_WRITE | RTL818X_CONFIG3_GNT_SELECT;
- rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg);
- rtl818x_iowrite32(priv, &priv->map->ANAPARAM2,
- RTL8187B_RTL8225_ANAPARAM2_ON);
- rtl818x_iowrite32(priv, &priv->map->ANAPARAM,
- RTL8187B_RTL8225_ANAPARAM_ON);
- rtl818x_iowrite8(priv, &priv->map->ANAPARAM3,
- RTL8187B_RTL8225_ANAPARAM3_ON);
+ rtl8187_set_anaparam(priv, true);
+ /* Reset PLL sequence on 8187B. Realtek note: reduces power
+ * consumption about 30 mA */
rtl818x_iowrite8(priv, (u8 *)0xFF61, 0x10);
reg = rtl818x_ioread8(priv, (u8 *)0xFF62);
rtl818x_iowrite8(priv, (u8 *)0xFF62, reg & ~(1 << 5));
rtl818x_iowrite8(priv, (u8 *)0xFF62, reg | (1 << 5));
- reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
- reg &= ~RTL818X_CONFIG3_ANAPARAM_WRITE;
- rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg);
-
- rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
- RTL818X_EEPROM_CMD_NORMAL);
-
res = rtl8187_cmd_reset(dev);
if (res)
return res;
- rtl818x_iowrite16(priv, (__le16 *)0xFF2D, 0x0FFF);
+ rtl8187_set_anaparam(priv, true);
+
+ /* BRSR (Basic Rate Set Register) on 8187B looks to be the same as
+ * RESP_RATE on 8187L in Realtek sources: each bit should be each
+ * one of the 12 rates, all are enabled */
+ rtl818x_iowrite16(priv, (__le16 *)0xFF34, 0x0FFF);
+
reg = rtl818x_ioread8(priv, &priv->map->CW_CONF);
reg |= RTL818X_CW_CONF_PERPACKET_RETRY_SHIFT;
rtl818x_iowrite8(priv, &priv->map->CW_CONF, reg);
- reg = rtl818x_ioread8(priv, &priv->map->TX_AGC_CTL);
- reg |= RTL818X_TX_AGC_CTL_PERPACKET_GAIN_SHIFT |
- RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT;
- rtl818x_iowrite8(priv, &priv->map->TX_AGC_CTL, reg);
+ /* Auto Rate Fallback Register (ARFR): 1M-54M setting */
rtl818x_iowrite16_idx(priv, (__le16 *)0xFFE0, 0x0FFF, 1);
+ rtl818x_iowrite8_idx(priv, (u8 *)0xFFE2, 0x00, 1);
- rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL, 100);
- rtl818x_iowrite16(priv, &priv->map->ATIM_WND, 2);
rtl818x_iowrite16_idx(priv, (__le16 *)0xFFD4, 0xFFFF, 1);
rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
@@ -811,16 +813,9 @@ static int rtl8187b_init_hw(struct ieee80211_hw *dev)
rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x00004001);
+ /* RFSW_CTRL register */
rtl818x_iowrite16_idx(priv, (__le16 *)0xFF72, 0x569A, 2);
- rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
- RTL818X_EEPROM_CMD_CONFIG);
- reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
- reg |= RTL818X_CONFIG3_ANAPARAM_WRITE;
- rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg);
- rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
- RTL818X_EEPROM_CMD_NORMAL);
-
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480);
rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x2488);
rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
@@ -929,6 +924,12 @@ static int rtl8187_start(struct ieee80211_hw *dev)
priv->rx_conf = reg;
rtl818x_iowrite32(priv, &priv->map->RX_CONF, reg);
+ reg = rtl818x_ioread8(priv, &priv->map->TX_AGC_CTL);
+ reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_GAIN_SHIFT;
+ reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT;
+ reg &= ~RTL818X_TX_AGC_CTL_FEEDBACK_ANT;
+ rtl818x_iowrite8(priv, &priv->map->TX_AGC_CTL, reg);
+
rtl818x_iowrite32(priv, &priv->map->TX_CONF,
RTL818X_TX_CONF_HW_SEQNUM |
RTL818X_TX_CONF_DISREQQSIZE |
@@ -1002,6 +1003,7 @@ static void rtl8187_stop(struct ieee80211_hw *dev)
rtl818x_iowrite8(priv, &priv->map->CMD, reg);
priv->rf->stop(dev);
+ rtl8187_set_anaparam(priv, false);
rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
reg = rtl818x_ioread8(priv, &priv->map->CONFIG4);
diff --git a/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c b/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c
index 97eebdcf7eb9..5c6666f09ac1 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c
@@ -898,29 +898,7 @@ static void rtl8225z2_b_rf_init(struct ieee80211_hw *dev)
static void rtl8225_rf_stop(struct ieee80211_hw *dev)
{
- u8 reg;
- struct rtl8187_priv *priv = dev->priv;
-
rtl8225_write(dev, 0x4, 0x1f);
-
- rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
- reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
- rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
- if (!priv->is_rtl8187b) {
- rtl818x_iowrite32(priv, &priv->map->ANAPARAM2,
- RTL8187_RTL8225_ANAPARAM2_OFF);
- rtl818x_iowrite32(priv, &priv->map->ANAPARAM,
- RTL8187_RTL8225_ANAPARAM_OFF);
- } else {
- rtl818x_iowrite32(priv, &priv->map->ANAPARAM2,
- RTL8187B_RTL8225_ANAPARAM2_OFF);
- rtl818x_iowrite32(priv, &priv->map->ANAPARAM,
- RTL8187B_RTL8225_ANAPARAM_OFF);
- rtl818x_iowrite8(priv, &priv->map->ANAPARAM3,
- RTL8187B_RTL8225_ANAPARAM3_OFF);
- }
- rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
- rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
}
static void rtl8225_rf_set_channel(struct ieee80211_hw *dev,
diff --git a/drivers/net/wireless/wl1251/main.c b/drivers/net/wireless/wl1251/main.c
index 7a8762553cdc..012e1a4016fe 100644
--- a/drivers/net/wireless/wl1251/main.c
+++ b/drivers/net/wireless/wl1251/main.c
@@ -52,14 +52,14 @@ void wl1251_disable_interrupts(struct wl1251 *wl)
wl->if_ops->disable_irq(wl);
}
-static void wl1251_power_off(struct wl1251 *wl)
+static int wl1251_power_off(struct wl1251 *wl)
{
- wl->set_power(false);
+ return wl->if_ops->power(wl, false);
}
-static void wl1251_power_on(struct wl1251 *wl)
+static int wl1251_power_on(struct wl1251 *wl)
{
- wl->set_power(true);
+ return wl->if_ops->power(wl, true);
}
static int wl1251_fetch_firmware(struct wl1251 *wl)
@@ -152,9 +152,12 @@ static void wl1251_fw_wakeup(struct wl1251 *wl)
static int wl1251_chip_wakeup(struct wl1251 *wl)
{
- int ret = 0;
+ int ret;
+
+ ret = wl1251_power_on(wl);
+ if (ret < 0)
+ return ret;
- wl1251_power_on(wl);
msleep(WL1251_POWER_ON_SLEEP);
wl->if_ops->reset(wl);
diff --git a/drivers/net/wireless/wl1251/sdio.c b/drivers/net/wireless/wl1251/sdio.c
index 74ba9ced5393..596d90ecba33 100644
--- a/drivers/net/wireless/wl1251/sdio.c
+++ b/drivers/net/wireless/wl1251/sdio.c
@@ -26,6 +26,7 @@
#include <linux/platform_device.h>
#include <linux/wl12xx.h>
#include <linux/irq.h>
+#include <linux/pm_runtime.h>
#include "wl1251.h"
@@ -42,8 +43,6 @@ struct wl1251_sdio {
u32 elp_val;
};
-static struct wl12xx_platform_data *wl12xx_board_data;
-
static struct sdio_func *wl_to_func(struct wl1251 *wl)
{
struct wl1251_sdio *wl_sdio = wl->if_priv;
@@ -171,8 +170,42 @@ static void wl1251_disable_line_irq(struct wl1251 *wl)
return disable_irq(wl->irq);
}
-static void wl1251_sdio_set_power(bool enable)
+static int wl1251_sdio_set_power(struct wl1251 *wl, bool enable)
{
+ struct sdio_func *func = wl_to_func(wl);
+ int ret;
+
+ if (enable) {
+ /*
+ * Power is controlled by runtime PM, but we still call board
+ * callback in case it wants to do any additional setup,
+ * for example enabling clock buffer for the module.
+ */
+ if (wl->set_power)
+ wl->set_power(true);
+
+ ret = pm_runtime_get_sync(&func->dev);
+ if (ret < 0)
+ goto out;
+
+ sdio_claim_host(func);
+ sdio_enable_func(func);
+ sdio_release_host(func);
+ } else {
+ sdio_claim_host(func);
+ sdio_disable_func(func);
+ sdio_release_host(func);
+
+ ret = pm_runtime_put_sync(&func->dev);
+ if (ret < 0)
+ goto out;
+
+ if (wl->set_power)
+ wl->set_power(false);
+ }
+
+out:
+ return ret;
}
static struct wl1251_if_operations wl1251_sdio_ops = {
@@ -181,30 +214,7 @@ static struct wl1251_if_operations wl1251_sdio_ops = {
.write_elp = wl1251_sdio_write_elp,
.read_elp = wl1251_sdio_read_elp,
.reset = wl1251_sdio_reset,
-};
-
-static int wl1251_platform_probe(struct platform_device *pdev)
-{
- if (pdev->id != -1) {
- wl1251_error("can only handle single device");
- return -ENODEV;
- }
-
- wl12xx_board_data = pdev->dev.platform_data;
- return 0;
-}
-
-/*
- * Dummy platform_driver for passing platform_data to this driver,
- * until we have a way to pass this through SDIO subsystem or
- * some other way.
- */
-static struct platform_driver wl1251_platform_driver = {
- .driver = {
- .name = "wl1251_data",
- .owner = THIS_MODULE,
- },
- .probe = wl1251_platform_probe,
+ .power = wl1251_sdio_set_power,
};
static int wl1251_sdio_probe(struct sdio_func *func,
@@ -214,6 +224,7 @@ static int wl1251_sdio_probe(struct sdio_func *func,
struct wl1251 *wl;
struct ieee80211_hw *hw;
struct wl1251_sdio *wl_sdio;
+ const struct wl12xx_platform_data *wl12xx_board_data;
hw = wl1251_alloc_hw();
if (IS_ERR(hw))
@@ -239,8 +250,8 @@ static int wl1251_sdio_probe(struct sdio_func *func,
wl_sdio->func = func;
wl->if_priv = wl_sdio;
wl->if_ops = &wl1251_sdio_ops;
- wl->set_power = wl1251_sdio_set_power;
+ wl12xx_board_data = wl12xx_get_platform_data();
if (wl12xx_board_data != NULL) {
wl->set_power = wl12xx_board_data->set_power;
wl->irq = wl12xx_board_data->irq;
@@ -273,6 +284,10 @@ static int wl1251_sdio_probe(struct sdio_func *func,
goto out_free_irq;
sdio_set_drvdata(func, wl);
+
+ /* Tell PM core that we don't need the card to be powered now */
+ pm_runtime_put_noidle(&func->dev);
+
return ret;
out_free_irq:
@@ -294,6 +309,9 @@ static void __devexit wl1251_sdio_remove(struct sdio_func *func)
struct wl1251 *wl = sdio_get_drvdata(func);
struct wl1251_sdio *wl_sdio = wl->if_priv;
+ /* Undo decrement done above in wl1251_probe */
+ pm_runtime_get_noresume(&func->dev);
+
if (wl->irq)
free_irq(wl->irq, wl);
kfree(wl_sdio);
@@ -305,23 +323,37 @@ static void __devexit wl1251_sdio_remove(struct sdio_func *func)
sdio_release_host(func);
}
+static int wl1251_suspend(struct device *dev)
+{
+ /*
+ * Tell MMC/SDIO core it's OK to power down the card
+ * (if it isn't already), but not to remove it completely.
+ */
+ return 0;
+}
+
+static int wl1251_resume(struct device *dev)
+{
+ return 0;
+}
+
+static const struct dev_pm_ops wl1251_sdio_pm_ops = {
+ .suspend = wl1251_suspend,
+ .resume = wl1251_resume,
+};
+
static struct sdio_driver wl1251_sdio_driver = {
.name = "wl1251_sdio",
.id_table = wl1251_devices,
.probe = wl1251_sdio_probe,
.remove = __devexit_p(wl1251_sdio_remove),
+ .drv.pm = &wl1251_sdio_pm_ops,
};
static int __init wl1251_sdio_init(void)
{
int err;
- err = platform_driver_register(&wl1251_platform_driver);
- if (err) {
- wl1251_error("failed to register platform driver: %d", err);
- return err;
- }
-
err = sdio_register_driver(&wl1251_sdio_driver);
if (err)
wl1251_error("failed to register sdio driver: %d", err);
@@ -331,7 +363,6 @@ static int __init wl1251_sdio_init(void)
static void __exit wl1251_sdio_exit(void)
{
sdio_unregister_driver(&wl1251_sdio_driver);
- platform_driver_unregister(&wl1251_platform_driver);
wl1251_notice("unloaded");
}
diff --git a/drivers/net/wireless/wl1251/spi.c b/drivers/net/wireless/wl1251/spi.c
index 88fa8e69d0d1..ac872b38960f 100644
--- a/drivers/net/wireless/wl1251/spi.c
+++ b/drivers/net/wireless/wl1251/spi.c
@@ -215,12 +215,21 @@ static void wl1251_spi_disable_irq(struct wl1251 *wl)
return disable_irq(wl->irq);
}
+static int wl1251_spi_set_power(struct wl1251 *wl, bool enable)
+{
+ if (wl->set_power)
+ wl->set_power(enable);
+
+ return 0;
+}
+
static const struct wl1251_if_operations wl1251_spi_ops = {
.read = wl1251_spi_read,
.write = wl1251_spi_write,
.reset = wl1251_spi_reset_wake,
.enable_irq = wl1251_spi_enable_irq,
.disable_irq = wl1251_spi_disable_irq,
+ .power = wl1251_spi_set_power,
};
static int __devinit wl1251_spi_probe(struct spi_device *spi)
diff --git a/drivers/net/wireless/wl1251/wl1251.h b/drivers/net/wireless/wl1251/wl1251.h
index e113d4c1fb35..13fbeeccf609 100644
--- a/drivers/net/wireless/wl1251/wl1251.h
+++ b/drivers/net/wireless/wl1251/wl1251.h
@@ -256,6 +256,7 @@ struct wl1251_if_operations {
void (*write)(struct wl1251 *wl, int addr, void *buf, size_t len);
void (*read_elp)(struct wl1251 *wl, int addr, u32 *val);
void (*write_elp)(struct wl1251 *wl, int addr, u32 val);
+ int (*power)(struct wl1251 *wl, bool enable);
void (*reset)(struct wl1251 *wl);
void (*enable_irq)(struct wl1251 *wl);
void (*disable_irq)(struct wl1251 *wl);
diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig
index b447559f1db5..d2adeb1f72b7 100644
--- a/drivers/net/wireless/wl12xx/Kconfig
+++ b/drivers/net/wireless/wl12xx/Kconfig
@@ -1,46 +1,58 @@
-menuconfig WL12XX
+menuconfig WL12XX_MENU
tristate "TI wl12xx driver support"
depends on MAC80211 && EXPERIMENTAL
---help---
- This will enable TI wl12xx driver support. The drivers make
- use of the mac80211 stack.
+ This will enable TI wl12xx driver support for the following chips:
+ wl1271 and wl1273.
+ The drivers make use of the mac80211 stack.
-config WL1271
- tristate "TI wl1271 support"
- depends on WL12XX && GENERIC_HARDIRQS
+config WL12XX
+ tristate "TI wl12xx support"
+ depends on WL12XX_MENU && GENERIC_HARDIRQS
depends on INET
select FW_LOADER
select CRC7
---help---
- This module adds support for wireless adapters based on the
- TI wl1271 chipset.
+ This module adds support for wireless adapters based on TI wl1271 and
+ TI wl1273 chipsets. This module does *not* include support for wl1251.
+ For wl1251 support, use the separate homonymous driver instead.
- If you choose to build a module, it'll be called wl1271. Say N if
+ If you choose to build a module, it will be called wl12xx. Say N if
unsure.
-config WL1271_SPI
- tristate "TI wl1271 SPI support"
- depends on WL1271 && SPI_MASTER
+config WL12XX_HT
+ bool "TI wl12xx 802.11 HT support (EXPERIMENTAL)"
+ depends on WL12XX && EXPERIMENTAL
+ default n
+ ---help---
+ This will enable 802.11 HT support in the wl12xx module.
+
+ That configuration is temporary due to the code incomplete and
+ still in testing process.
+
+config WL12XX_SPI
+ tristate "TI wl12xx SPI support"
+ depends on WL12XX && SPI_MASTER
---help---
This module adds support for the SPI interface of adapters using
- TI wl1271 chipset. Select this if your platform is using
+ TI wl12xx chipsets. Select this if your platform is using
the SPI bus.
- If you choose to build a module, it'll be called wl1251_spi.
+ If you choose to build a module, it'll be called wl12xx_spi.
Say N if unsure.
-config WL1271_SDIO
- tristate "TI wl1271 SDIO support"
- depends on WL1271 && MMC
+config WL12XX_SDIO
+ tristate "TI wl12xx SDIO support"
+ depends on WL12XX && MMC
---help---
This module adds support for the SDIO interface of adapters using
- TI wl1271 chipset. Select this if your platform is using
+ TI wl12xx chipsets. Select this if your platform is using
the SDIO bus.
- If you choose to build a module, it'll be called
- wl1271_sdio. Say N if unsure.
+ If you choose to build a module, it'll be called wl12xx_sdio.
+ Say N if unsure.
config WL12XX_PLATFORM_DATA
bool
- depends on WL1271_SDIO != n
+ depends on WL12XX_SDIO != n || WL1251_SDIO != n
default y
diff --git a/drivers/net/wireless/wl12xx/Makefile b/drivers/net/wireless/wl12xx/Makefile
index 3a807444b2af..005a758174d9 100644
--- a/drivers/net/wireless/wl12xx/Makefile
+++ b/drivers/net/wireless/wl12xx/Makefile
@@ -1,12 +1,13 @@
-wl1271-objs = wl1271_main.o wl1271_cmd.o wl1271_io.o \
- wl1271_event.o wl1271_tx.o wl1271_rx.o \
- wl1271_ps.o wl1271_acx.o wl1271_boot.o \
- wl1271_init.o wl1271_debugfs.o wl1271_scan.o
+wl12xx-objs = main.o cmd.o io.o event.o tx.o rx.o ps.o acx.o \
+ boot.o init.o debugfs.o scan.o
-wl1271-$(CONFIG_NL80211_TESTMODE) += wl1271_testmode.o
-obj-$(CONFIG_WL1271) += wl1271.o
-obj-$(CONFIG_WL1271_SPI) += wl1271_spi.o
-obj-$(CONFIG_WL1271_SDIO) += wl1271_sdio.o
+wl12xx_spi-objs = spi.o
+wl12xx_sdio-objs = sdio.o
+
+wl12xx-$(CONFIG_NL80211_TESTMODE) += testmode.o
+obj-$(CONFIG_WL12XX) += wl12xx.o
+obj-$(CONFIG_WL12XX_SPI) += wl12xx_spi.o
+obj-$(CONFIG_WL12XX_SDIO) += wl12xx_sdio.o
# small builtin driver bit
obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx_platform_data.o
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.c b/drivers/net/wireless/wl12xx/acx.c
index 618993405262..7cbaeb6d2a37 100644
--- a/drivers/net/wireless/wl12xx/wl1271_acx.c
+++ b/drivers/net/wireless/wl12xx/acx.c
@@ -21,7 +21,7 @@
*
*/
-#include "wl1271_acx.h"
+#include "acx.h"
#include <linux/module.h>
#include <linux/platform_device.h>
@@ -29,10 +29,10 @@
#include <linux/spi/spi.h>
#include <linux/slab.h>
-#include "wl1271.h"
+#include "wl12xx.h"
#include "wl12xx_80211.h"
-#include "wl1271_reg.h"
-#include "wl1271_ps.h"
+#include "reg.h"
+#include "ps.h"
int wl1271_acx_wake_up_conditions(struct wl1271 *wl)
{
@@ -862,7 +862,7 @@ out:
return ret;
}
-int wl1271_acx_frag_threshold(struct wl1271 *wl)
+int wl1271_acx_frag_threshold(struct wl1271 *wl, u16 frag_threshold)
{
struct acx_frag_threshold *acx;
int ret = 0;
@@ -876,7 +876,7 @@ int wl1271_acx_frag_threshold(struct wl1271 *wl)
goto out;
}
- acx->frag_threshold = cpu_to_le16(wl->conf.tx.frag_threshold);
+ acx->frag_threshold = cpu_to_le16(frag_threshold);
ret = wl1271_cmd_configure(wl, ACX_FRAG_CFG, acx, sizeof(*acx));
if (ret < 0) {
wl1271_warning("Setting of frag threshold failed: %d", ret);
@@ -1226,6 +1226,89 @@ out:
return ret;
}
+int wl1271_acx_set_ht_capabilities(struct wl1271 *wl,
+ struct ieee80211_sta_ht_cap *ht_cap,
+ bool allow_ht_operation)
+{
+ struct wl1271_acx_ht_capabilities *acx;
+ u8 mac_address[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+ int ret = 0;
+
+ wl1271_debug(DEBUG_ACX, "acx ht capabilities setting");
+
+ acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+ if (!acx) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ /* Allow HT Operation ? */
+ if (allow_ht_operation) {
+ acx->ht_capabilites =
+ WL1271_ACX_FW_CAP_HT_OPERATION;
+ if (ht_cap->cap & IEEE80211_HT_CAP_GRN_FLD)
+ acx->ht_capabilites |=
+ WL1271_ACX_FW_CAP_GREENFIELD_FRAME_FORMAT;
+ if (ht_cap->cap & IEEE80211_HT_CAP_SGI_20)
+ acx->ht_capabilites |=
+ WL1271_ACX_FW_CAP_SHORT_GI_FOR_20MHZ_PACKETS;
+ if (ht_cap->cap & IEEE80211_HT_CAP_LSIG_TXOP_PROT)
+ acx->ht_capabilites |=
+ WL1271_ACX_FW_CAP_LSIG_TXOP_PROTECTION;
+
+ /* get data from A-MPDU parameters field */
+ acx->ampdu_max_length = ht_cap->ampdu_factor;
+ acx->ampdu_min_spacing = ht_cap->ampdu_density;
+
+ memcpy(acx->mac_address, mac_address, ETH_ALEN);
+ } else { /* HT operations are not allowed */
+ acx->ht_capabilites = 0;
+ }
+
+ ret = wl1271_cmd_configure(wl, ACX_PEER_HT_CAP, acx, sizeof(*acx));
+ if (ret < 0) {
+ wl1271_warning("acx ht capabilities setting failed: %d", ret);
+ goto out;
+ }
+
+out:
+ kfree(acx);
+ return ret;
+}
+
+int wl1271_acx_set_ht_information(struct wl1271 *wl,
+ u16 ht_operation_mode)
+{
+ struct wl1271_acx_ht_information *acx;
+ int ret = 0;
+
+ wl1271_debug(DEBUG_ACX, "acx ht information setting");
+
+ acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+ if (!acx) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ acx->ht_protection =
+ (u8)(ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION);
+ acx->rifs_mode = 0;
+ acx->gf_protection = 0;
+ acx->ht_tx_burst_limit = 0;
+ acx->dual_cts_protection = 0;
+
+ ret = wl1271_cmd_configure(wl, ACX_HT_BSS_OPERATION, acx, sizeof(*acx));
+
+ if (ret < 0) {
+ wl1271_warning("acx ht information setting failed: %d", ret);
+ goto out;
+ }
+
+out:
+ kfree(acx);
+ return ret;
+}
+
int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime)
{
struct wl1271_acx_fw_tsf_information *tsf_info;
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.h b/drivers/net/wireless/wl12xx/acx.h
index ebb341d36e8c..75a6306ff554 100644
--- a/drivers/net/wireless/wl12xx/wl1271_acx.h
+++ b/drivers/net/wireless/wl12xx/acx.h
@@ -22,11 +22,11 @@
*
*/
-#ifndef __WL1271_ACX_H__
-#define __WL1271_ACX_H__
+#ifndef __ACX_H__
+#define __ACX_H__
-#include "wl1271.h"
-#include "wl1271_cmd.h"
+#include "wl12xx.h"
+#include "cmd.h"
/*************************************************************************
@@ -61,7 +61,8 @@
WL1271_ACX_INTR_HW_AVAILABLE | \
WL1271_ACX_INTR_DATA)
-#define WL1271_INTR_MASK (WL1271_ACX_INTR_EVENT_A | \
+#define WL1271_INTR_MASK (WL1271_ACX_INTR_WATCHDOG | \
+ WL1271_ACX_INTR_EVENT_A | \
WL1271_ACX_INTR_EVENT_B | \
WL1271_ACX_INTR_HW_AVAILABLE | \
WL1271_ACX_INTR_DATA)
@@ -964,6 +965,87 @@ struct wl1271_acx_rssi_snr_avg_weights {
u8 snr_data;
};
+/*
+ * ACX_PEER_HT_CAP
+ * Configure HT capabilities - declare the capabilities of the peer
+ * we are connected to.
+ */
+struct wl1271_acx_ht_capabilities {
+ struct acx_header header;
+
+ /*
+ * bit 0 - Allow HT Operation
+ * bit 1 - Allow Greenfield format in TX
+ * bit 2 - Allow Short GI in TX
+ * bit 3 - Allow L-SIG TXOP Protection in TX
+ * bit 4 - Allow HT Control fields in TX.
+ * Note, driver will still leave space for HT control in packets
+ * regardless of the value of this field. FW will be responsible
+ * to drop the HT field from any frame when this Bit set to 0.
+ * bit 5 - Allow RD initiation in TXOP. FW is allowed to initate RD.
+ * Exact policy setting for this feature is TBD.
+ * Note, this bit can only be set to 1 if bit 3 is set to 1.
+ */
+ __le32 ht_capabilites;
+
+ /*
+ * Indicates to which peer these capabilities apply.
+ * For infrastructure use ff:ff:ff:ff:ff:ff that indicates relevance
+ * for all peers.
+ * Only valid for IBSS/DLS operation.
+ */
+ u8 mac_address[ETH_ALEN];
+
+ /*
+ * This the maximum A-MPDU length supported by the AP. The FW may not
+ * exceed this length when sending A-MPDUs
+ */
+ u8 ampdu_max_length;
+
+ /* This is the minimal spacing required when sending A-MPDUs to the AP*/
+ u8 ampdu_min_spacing;
+} __packed;
+
+/* HT Capabilites Fw Bit Mask Mapping */
+#define WL1271_ACX_FW_CAP_HT_OPERATION BIT(0)
+#define WL1271_ACX_FW_CAP_GREENFIELD_FRAME_FORMAT BIT(1)
+#define WL1271_ACX_FW_CAP_SHORT_GI_FOR_20MHZ_PACKETS BIT(2)
+#define WL1271_ACX_FW_CAP_LSIG_TXOP_PROTECTION BIT(3)
+#define WL1271_ACX_FW_CAP_HT_CONTROL_FIELDS BIT(4)
+#define WL1271_ACX_FW_CAP_RD_INITIATION BIT(5)
+
+
+/*
+ * ACX_HT_BSS_OPERATION
+ * Configure HT capabilities - AP rules for behavior in the BSS.
+ */
+struct wl1271_acx_ht_information {
+ struct acx_header header;
+
+ /* Values: 0 - RIFS not allowed, 1 - RIFS allowed */
+ u8 rifs_mode;
+
+ /* Values: 0 - 3 like in spec */
+ u8 ht_protection;
+
+ /* Values: 0 - GF protection not required, 1 - GF protection required */
+ u8 gf_protection;
+
+ /*Values: 0 - TX Burst limit not required, 1 - TX Burst Limit required*/
+ u8 ht_tx_burst_limit;
+
+ /*
+ * Values: 0 - Dual CTS protection not required,
+ * 1 - Dual CTS Protection required
+ * Note: When this value is set to 1 FW will protect all TXOP with RTS
+ * frame and will not use CTS-to-self regardless of the value of the
+ * ACX_CTS_PROTECTION information element
+ */
+ u8 dual_cts_protection;
+
+ u8 padding[3];
+} __packed;
+
struct wl1271_acx_fw_tsf_information {
struct acx_header header;
@@ -1079,7 +1161,7 @@ int wl1271_acx_ac_cfg(struct wl1271 *wl, u8 ac, u8 cw_min, u16 cw_max,
int wl1271_acx_tid_cfg(struct wl1271 *wl, u8 queue_id, u8 channel_type,
u8 tsid, u8 ps_scheme, u8 ack_policy,
u32 apsd_conf0, u32 apsd_conf1);
-int wl1271_acx_frag_threshold(struct wl1271 *wl);
+int wl1271_acx_frag_threshold(struct wl1271 *wl, u16 frag_threshold);
int wl1271_acx_tx_config_options(struct wl1271 *wl);
int wl1271_acx_mem_cfg(struct wl1271 *wl);
int wl1271_acx_init_mem_config(struct wl1271 *wl);
@@ -1093,6 +1175,11 @@ int wl1271_acx_keep_alive_config(struct wl1271 *wl, u8 index, u8 tpl_valid);
int wl1271_acx_rssi_snr_trigger(struct wl1271 *wl, bool enable,
s16 thold, u8 hyst);
int wl1271_acx_rssi_snr_avg_weights(struct wl1271 *wl);
+int wl1271_acx_set_ht_capabilities(struct wl1271 *wl,
+ struct ieee80211_sta_ht_cap *ht_cap,
+ bool allow_ht_operation);
+int wl1271_acx_set_ht_information(struct wl1271 *wl,
+ u16 ht_operation_mode);
int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime);
#endif /* __WL1271_ACX_H__ */
diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.c b/drivers/net/wireless/wl12xx/boot.c
index b91021242098..1eafb8175832 100644
--- a/drivers/net/wireless/wl12xx/wl1271_boot.c
+++ b/drivers/net/wireless/wl12xx/boot.c
@@ -24,11 +24,11 @@
#include <linux/gpio.h>
#include <linux/slab.h>
-#include "wl1271_acx.h"
-#include "wl1271_reg.h"
-#include "wl1271_boot.h"
-#include "wl1271_io.h"
-#include "wl1271_event.h"
+#include "acx.h"
+#include "reg.h"
+#include "boot.h"
+#include "io.h"
+#include "event.h"
static struct wl1271_partition_set part_table[PART_TABLE_LEN] = {
[PART_DOWN] = {
@@ -471,20 +471,19 @@ int wl1271_boot(struct wl1271 *wl)
{
int ret = 0;
u32 tmp, clk, pause;
- int ref_clock = wl->ref_clock;
wl1271_boot_hw_version(wl);
- if (ref_clock == 0 || ref_clock == 2 || ref_clock == 4)
+ if (wl->ref_clock == 0 || wl->ref_clock == 2 || wl->ref_clock == 4)
/* ref clk: 19.2/38.4/38.4-XTAL */
clk = 0x3;
- else if (ref_clock == 1 || ref_clock == 3)
+ else if (wl->ref_clock == 1 || wl->ref_clock == 3)
/* ref clk: 26/52 */
clk = 0x5;
else
return -EINVAL;
- if (ref_clock != 0) {
+ if (wl->ref_clock != 0) {
u16 val;
/* Set clock type (open drain) */
val = wl1271_top_reg_read(wl, OCP_REG_CLK_TYPE);
@@ -529,8 +528,7 @@ int wl1271_boot(struct wl1271 *wl)
wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk);
- /* 2 */
- clk |= (ref_clock << 1) << 4;
+ clk |= (wl->ref_clock << 1) << 4;
wl1271_write32(wl, DRPW_SCRATCH_START, clk);
wl1271_set_partition(wl, &part_table[PART_WORK]);
diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.h b/drivers/net/wireless/wl12xx/boot.h
index f73b0b15a280..c7d771959f3a 100644
--- a/drivers/net/wireless/wl12xx/wl1271_boot.h
+++ b/drivers/net/wireless/wl12xx/boot.h
@@ -24,7 +24,7 @@
#ifndef __BOOT_H__
#define __BOOT_H__
-#include "wl1271.h"
+#include "wl12xx.h"
int wl1271_boot(struct wl1271 *wl);
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.c b/drivers/net/wireless/wl12xx/cmd.c
index 5d3e8485ea4e..f3d0541aaad6 100644
--- a/drivers/net/wireless/wl12xx/wl1271_cmd.c
+++ b/drivers/net/wireless/wl12xx/cmd.c
@@ -29,13 +29,13 @@
#include <linux/ieee80211.h>
#include <linux/slab.h>
-#include "wl1271.h"
-#include "wl1271_reg.h"
-#include "wl1271_io.h"
-#include "wl1271_acx.h"
+#include "wl12xx.h"
+#include "reg.h"
+#include "io.h"
+#include "acx.h"
#include "wl12xx_80211.h"
-#include "wl1271_cmd.h"
-#include "wl1271_event.h"
+#include "cmd.h"
+#include "event.h"
#define WL1271_CMD_FAST_POLL_COUNT 50
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.h b/drivers/net/wireless/wl12xx/cmd.h
index a0caf4fc37b1..16d1bf814e76 100644
--- a/drivers/net/wireless/wl12xx/wl1271_cmd.h
+++ b/drivers/net/wireless/wl12xx/cmd.h
@@ -22,10 +22,10 @@
*
*/
-#ifndef __WL1271_CMD_H__
-#define __WL1271_CMD_H__
+#ifndef __CMD_H__
+#define __CMD_H__
-#include "wl1271.h"
+#include "wl12xx.h"
struct acx_header;
@@ -327,9 +327,6 @@ enum wl1271_channel_tune_bands {
#define WL1271_PD_REFERENCE_POINT_BAND_B_G 0
-#define TEST_CMD_P2G_CAL 0x02
-#define TEST_CMD_CHANNEL_TUNE 0x0d
-#define TEST_CMD_UPDATE_PD_REFERENCE_POINT 0x1d
#define TEST_CMD_INI_FILE_RADIO_PARAM 0x19
#define TEST_CMD_INI_FILE_GENERAL_PARAM 0x1E
#define TEST_CMD_INI_FILE_RF_EXTENDED_PARAM 0x26
@@ -375,51 +372,6 @@ struct wl1271_ext_radio_parms_cmd {
u8 padding[3];
} __packed;
-struct wl1271_cmd_cal_channel_tune {
- struct wl1271_cmd_header header;
-
- struct wl1271_cmd_test_header test;
-
- u8 band;
- u8 channel;
-
- __le16 radio_status;
-} __packed;
-
-struct wl1271_cmd_cal_update_ref_point {
- struct wl1271_cmd_header header;
-
- struct wl1271_cmd_test_header test;
-
- __le32 ref_power;
- __le32 ref_detector;
- u8 sub_band;
- u8 padding[3];
-} __packed;
-
-#define MAX_TLV_LENGTH 400
-#define MAX_NVS_VERSION_LENGTH 12
-
-#define WL1271_CAL_P2G_BAND_B_G BIT(0)
-
-struct wl1271_cmd_cal_p2g {
- struct wl1271_cmd_header header;
-
- struct wl1271_cmd_test_header test;
-
- __le16 len;
- u8 buf[MAX_TLV_LENGTH];
- u8 type;
- u8 padding;
-
- __le16 radio_status;
- u8 nvs_version[MAX_NVS_VERSION_LENGTH];
-
- u8 sub_band_mask;
- u8 padding2;
-} __packed;
-
-
/*
* There are three types of disconnections:
*
diff --git a/drivers/net/wireless/wl12xx/wl1271_conf.h b/drivers/net/wireless/wl12xx/conf.h
index 5f78a6cb1433..a16b3616e430 100644
--- a/drivers/net/wireless/wl12xx/wl1271_conf.h
+++ b/drivers/net/wireless/wl12xx/conf.h
@@ -21,8 +21,8 @@
*
*/
-#ifndef __WL1271_CONF_H__
-#define __WL1271_CONF_H__
+#ifndef __CONF_H__
+#define __CONF_H__
enum {
CONF_HW_BIT_RATE_1MBPS = BIT(0),
diff --git a/drivers/net/wireless/wl12xx/wl1271_debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c
index 66c2b90ddfd4..dd71b7d2105c 100644
--- a/drivers/net/wireless/wl12xx/wl1271_debugfs.c
+++ b/drivers/net/wireless/wl12xx/debugfs.c
@@ -21,31 +21,42 @@
*
*/
-#include "wl1271_debugfs.h"
+#include "debugfs.h"
#include <linux/skbuff.h>
#include <linux/slab.h>
-#include "wl1271.h"
-#include "wl1271_acx.h"
-#include "wl1271_ps.h"
-#include "wl1271_io.h"
+#include "wl12xx.h"
+#include "acx.h"
+#include "ps.h"
+#include "io.h"
/* ms */
#define WL1271_DEBUGFS_STATS_LIFETIME 1000
/* debugfs macros idea from mac80211 */
+#define DEBUGFS_FORMAT_BUFFER_SIZE 100
+static int wl1271_format_buffer(char __user *userbuf, size_t count,
+ loff_t *ppos, char *fmt, ...)
+{
+ va_list args;
+ char buf[DEBUGFS_FORMAT_BUFFER_SIZE];
+ int res;
-#define DEBUGFS_READONLY_FILE(name, buflen, fmt, value...) \
+ va_start(args, fmt);
+ res = vscnprintf(buf, sizeof(buf), fmt, args);
+ va_end(args);
+
+ return simple_read_from_buffer(userbuf, count, ppos, buf, res);
+}
+
+#define DEBUGFS_READONLY_FILE(name, fmt, value...) \
static ssize_t name## _read(struct file *file, char __user *userbuf, \
size_t count, loff_t *ppos) \
{ \
struct wl1271 *wl = file->private_data; \
- char buf[buflen]; \
- int res; \
- \
- res = scnprintf(buf, buflen, fmt "\n", ##value); \
- return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
+ return wl1271_format_buffer(userbuf, count, ppos, \
+ fmt "\n", ##value); \
} \
\
static const struct file_operations name## _ops = { \
@@ -69,20 +80,17 @@ static const struct file_operations name## _ops = { \
wl->debugfs.name = NULL; \
} while (0)
-#define DEBUGFS_FWSTATS_FILE(sub, name, buflen, fmt) \
+#define DEBUGFS_FWSTATS_FILE(sub, name, fmt) \
static ssize_t sub## _ ##name## _read(struct file *file, \
char __user *userbuf, \
size_t count, loff_t *ppos) \
{ \
struct wl1271 *wl = file->private_data; \
- char buf[buflen]; \
- int res; \
\
wl1271_debugfs_update_stats(wl); \
\
- res = scnprintf(buf, buflen, fmt "\n", \
- wl->stats.fw_stats->sub.name); \
- return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
+ return wl1271_format_buffer(userbuf, count, ppos, fmt "\n", \
+ wl->stats.fw_stats->sub.name); \
} \
\
static const struct file_operations sub## _ ##name## _ops = { \
@@ -126,100 +134,99 @@ static int wl1271_open_file_generic(struct inode *inode, struct file *file)
return 0;
}
-DEBUGFS_FWSTATS_FILE(tx, internal_desc_overflow, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(rx, out_of_mem, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rx, hdr_overflow, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rx, hw_stuck, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rx, dropped, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rx, fcs_err, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rx, xfr_hint_trig, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rx, path_reset, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rx, reset_counter, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(dma, rx_requested, 20, "%u");
-DEBUGFS_FWSTATS_FILE(dma, rx_errors, 20, "%u");
-DEBUGFS_FWSTATS_FILE(dma, tx_requested, 20, "%u");
-DEBUGFS_FWSTATS_FILE(dma, tx_errors, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(isr, cmd_cmplt, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, fiqs, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, rx_headers, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, rx_mem_overflow, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, rx_rdys, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, irqs, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, tx_procs, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, decrypt_done, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, dma0_done, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, dma1_done, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, tx_exch_complete, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, commands, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, rx_procs, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, hw_pm_mode_changes, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, host_acknowledges, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, pci_pm, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, wakeups, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, low_rssi, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(wep, addr_key_count, 20, "%u");
-DEBUGFS_FWSTATS_FILE(wep, default_key_count, 20, "%u");
+DEBUGFS_FWSTATS_FILE(tx, internal_desc_overflow, "%u");
+
+DEBUGFS_FWSTATS_FILE(rx, out_of_mem, "%u");
+DEBUGFS_FWSTATS_FILE(rx, hdr_overflow, "%u");
+DEBUGFS_FWSTATS_FILE(rx, hw_stuck, "%u");
+DEBUGFS_FWSTATS_FILE(rx, dropped, "%u");
+DEBUGFS_FWSTATS_FILE(rx, fcs_err, "%u");
+DEBUGFS_FWSTATS_FILE(rx, xfr_hint_trig, "%u");
+DEBUGFS_FWSTATS_FILE(rx, path_reset, "%u");
+DEBUGFS_FWSTATS_FILE(rx, reset_counter, "%u");
+
+DEBUGFS_FWSTATS_FILE(dma, rx_requested, "%u");
+DEBUGFS_FWSTATS_FILE(dma, rx_errors, "%u");
+DEBUGFS_FWSTATS_FILE(dma, tx_requested, "%u");
+DEBUGFS_FWSTATS_FILE(dma, tx_errors, "%u");
+
+DEBUGFS_FWSTATS_FILE(isr, cmd_cmplt, "%u");
+DEBUGFS_FWSTATS_FILE(isr, fiqs, "%u");
+DEBUGFS_FWSTATS_FILE(isr, rx_headers, "%u");
+DEBUGFS_FWSTATS_FILE(isr, rx_mem_overflow, "%u");
+DEBUGFS_FWSTATS_FILE(isr, rx_rdys, "%u");
+DEBUGFS_FWSTATS_FILE(isr, irqs, "%u");
+DEBUGFS_FWSTATS_FILE(isr, tx_procs, "%u");
+DEBUGFS_FWSTATS_FILE(isr, decrypt_done, "%u");
+DEBUGFS_FWSTATS_FILE(isr, dma0_done, "%u");
+DEBUGFS_FWSTATS_FILE(isr, dma1_done, "%u");
+DEBUGFS_FWSTATS_FILE(isr, tx_exch_complete, "%u");
+DEBUGFS_FWSTATS_FILE(isr, commands, "%u");
+DEBUGFS_FWSTATS_FILE(isr, rx_procs, "%u");
+DEBUGFS_FWSTATS_FILE(isr, hw_pm_mode_changes, "%u");
+DEBUGFS_FWSTATS_FILE(isr, host_acknowledges, "%u");
+DEBUGFS_FWSTATS_FILE(isr, pci_pm, "%u");
+DEBUGFS_FWSTATS_FILE(isr, wakeups, "%u");
+DEBUGFS_FWSTATS_FILE(isr, low_rssi, "%u");
+
+DEBUGFS_FWSTATS_FILE(wep, addr_key_count, "%u");
+DEBUGFS_FWSTATS_FILE(wep, default_key_count, "%u");
/* skipping wep.reserved */
-DEBUGFS_FWSTATS_FILE(wep, key_not_found, 20, "%u");
-DEBUGFS_FWSTATS_FILE(wep, decrypt_fail, 20, "%u");
-DEBUGFS_FWSTATS_FILE(wep, packets, 20, "%u");
-DEBUGFS_FWSTATS_FILE(wep, interrupt, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(pwr, ps_enter, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, elp_enter, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, missing_bcns, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, wake_on_host, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, wake_on_timer_exp, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, tx_with_ps, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, tx_without_ps, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, rcvd_beacons, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, power_save_off, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, enable_ps, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, disable_ps, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, fix_tsf_ps, 20, "%u");
+DEBUGFS_FWSTATS_FILE(wep, key_not_found, "%u");
+DEBUGFS_FWSTATS_FILE(wep, decrypt_fail, "%u");
+DEBUGFS_FWSTATS_FILE(wep, packets, "%u");
+DEBUGFS_FWSTATS_FILE(wep, interrupt, "%u");
+
+DEBUGFS_FWSTATS_FILE(pwr, ps_enter, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, elp_enter, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, missing_bcns, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, wake_on_host, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, wake_on_timer_exp, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, tx_with_ps, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, tx_without_ps, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, rcvd_beacons, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, power_save_off, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, enable_ps, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, disable_ps, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, fix_tsf_ps, "%u");
/* skipping cont_miss_bcns_spread for now */
-DEBUGFS_FWSTATS_FILE(pwr, rcvd_awake_beacons, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(mic, rx_pkts, 20, "%u");
-DEBUGFS_FWSTATS_FILE(mic, calc_failure, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(aes, encrypt_fail, 20, "%u");
-DEBUGFS_FWSTATS_FILE(aes, decrypt_fail, 20, "%u");
-DEBUGFS_FWSTATS_FILE(aes, encrypt_packets, 20, "%u");
-DEBUGFS_FWSTATS_FILE(aes, decrypt_packets, 20, "%u");
-DEBUGFS_FWSTATS_FILE(aes, encrypt_interrupt, 20, "%u");
-DEBUGFS_FWSTATS_FILE(aes, decrypt_interrupt, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(event, heart_beat, 20, "%u");
-DEBUGFS_FWSTATS_FILE(event, calibration, 20, "%u");
-DEBUGFS_FWSTATS_FILE(event, rx_mismatch, 20, "%u");
-DEBUGFS_FWSTATS_FILE(event, rx_mem_empty, 20, "%u");
-DEBUGFS_FWSTATS_FILE(event, rx_pool, 20, "%u");
-DEBUGFS_FWSTATS_FILE(event, oom_late, 20, "%u");
-DEBUGFS_FWSTATS_FILE(event, phy_transmit_error, 20, "%u");
-DEBUGFS_FWSTATS_FILE(event, tx_stuck, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(ps, pspoll_timeouts, 20, "%u");
-DEBUGFS_FWSTATS_FILE(ps, upsd_timeouts, 20, "%u");
-DEBUGFS_FWSTATS_FILE(ps, upsd_max_sptime, 20, "%u");
-DEBUGFS_FWSTATS_FILE(ps, upsd_max_apturn, 20, "%u");
-DEBUGFS_FWSTATS_FILE(ps, pspoll_max_apturn, 20, "%u");
-DEBUGFS_FWSTATS_FILE(ps, pspoll_utilization, 20, "%u");
-DEBUGFS_FWSTATS_FILE(ps, upsd_utilization, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(rxpipe, rx_prep_beacon_drop, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rxpipe, descr_host_int_trig_rx_data, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rxpipe, beacon_buffer_thres_host_int_trig_rx_data,
- 20, "%u");
-DEBUGFS_FWSTATS_FILE(rxpipe, missed_beacon_host_int_trig_rx_data, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rxpipe, tx_xfr_host_int_trig_rx_data, 20, "%u");
-
-DEBUGFS_READONLY_FILE(retry_count, 20, "%u", wl->stats.retry_count);
-DEBUGFS_READONLY_FILE(excessive_retries, 20, "%u",
+DEBUGFS_FWSTATS_FILE(pwr, rcvd_awake_beacons, "%u");
+
+DEBUGFS_FWSTATS_FILE(mic, rx_pkts, "%u");
+DEBUGFS_FWSTATS_FILE(mic, calc_failure, "%u");
+
+DEBUGFS_FWSTATS_FILE(aes, encrypt_fail, "%u");
+DEBUGFS_FWSTATS_FILE(aes, decrypt_fail, "%u");
+DEBUGFS_FWSTATS_FILE(aes, encrypt_packets, "%u");
+DEBUGFS_FWSTATS_FILE(aes, decrypt_packets, "%u");
+DEBUGFS_FWSTATS_FILE(aes, encrypt_interrupt, "%u");
+DEBUGFS_FWSTATS_FILE(aes, decrypt_interrupt, "%u");
+
+DEBUGFS_FWSTATS_FILE(event, heart_beat, "%u");
+DEBUGFS_FWSTATS_FILE(event, calibration, "%u");
+DEBUGFS_FWSTATS_FILE(event, rx_mismatch, "%u");
+DEBUGFS_FWSTATS_FILE(event, rx_mem_empty, "%u");
+DEBUGFS_FWSTATS_FILE(event, rx_pool, "%u");
+DEBUGFS_FWSTATS_FILE(event, oom_late, "%u");
+DEBUGFS_FWSTATS_FILE(event, phy_transmit_error, "%u");
+DEBUGFS_FWSTATS_FILE(event, tx_stuck, "%u");
+
+DEBUGFS_FWSTATS_FILE(ps, pspoll_timeouts, "%u");
+DEBUGFS_FWSTATS_FILE(ps, upsd_timeouts, "%u");
+DEBUGFS_FWSTATS_FILE(ps, upsd_max_sptime, "%u");
+DEBUGFS_FWSTATS_FILE(ps, upsd_max_apturn, "%u");
+DEBUGFS_FWSTATS_FILE(ps, pspoll_max_apturn, "%u");
+DEBUGFS_FWSTATS_FILE(ps, pspoll_utilization, "%u");
+DEBUGFS_FWSTATS_FILE(ps, upsd_utilization, "%u");
+
+DEBUGFS_FWSTATS_FILE(rxpipe, rx_prep_beacon_drop, "%u");
+DEBUGFS_FWSTATS_FILE(rxpipe, descr_host_int_trig_rx_data, "%u");
+DEBUGFS_FWSTATS_FILE(rxpipe, beacon_buffer_thres_host_int_trig_rx_data, "%u");
+DEBUGFS_FWSTATS_FILE(rxpipe, missed_beacon_host_int_trig_rx_data, "%u");
+DEBUGFS_FWSTATS_FILE(rxpipe, tx_xfr_host_int_trig_rx_data, "%u");
+
+DEBUGFS_READONLY_FILE(retry_count, "%u", wl->stats.retry_count);
+DEBUGFS_READONLY_FILE(excessive_retries, "%u",
wl->stats.excessive_retries);
static ssize_t tx_queue_len_read(struct file *file, char __user *userbuf,
diff --git a/drivers/net/wireless/wl12xx/wl1271_debugfs.h b/drivers/net/wireless/wl12xx/debugfs.h
index 00a45b2669ad..254c5b292cf6 100644
--- a/drivers/net/wireless/wl12xx/wl1271_debugfs.h
+++ b/drivers/net/wireless/wl12xx/debugfs.h
@@ -21,10 +21,10 @@
*
*/
-#ifndef WL1271_DEBUGFS_H
-#define WL1271_DEBUGFS_H
+#ifndef __DEBUGFS_H__
+#define __DEBUGFS_H__
-#include "wl1271.h"
+#include "wl12xx.h"
int wl1271_debugfs_init(struct wl1271 *wl);
void wl1271_debugfs_exit(struct wl1271 *wl);
diff --git a/drivers/net/wireless/wl12xx/wl1271_event.c b/drivers/net/wireless/wl12xx/event.c
index 7b3f50382963..f9146f5242fb 100644
--- a/drivers/net/wireless/wl12xx/wl1271_event.c
+++ b/drivers/net/wireless/wl12xx/event.c
@@ -21,12 +21,12 @@
*
*/
-#include "wl1271.h"
-#include "wl1271_reg.h"
-#include "wl1271_io.h"
-#include "wl1271_event.h"
-#include "wl1271_ps.h"
-#include "wl1271_scan.h"
+#include "wl12xx.h"
+#include "reg.h"
+#include "io.h"
+#include "event.h"
+#include "ps.h"
+#include "scan.h"
#include "wl12xx_80211.h"
void wl1271_pspoll_work(struct work_struct *work)
@@ -134,8 +134,6 @@ static int wl1271_event_ps_report(struct wl1271 *wl,
/* go to extremely low power mode */
wl1271_ps_elp_sleep(wl);
- if (ret < 0)
- break;
break;
case EVENT_EXIT_POWER_SAVE_FAIL:
wl1271_debug(DEBUG_PSM, "PSM exit failed");
diff --git a/drivers/net/wireless/wl12xx/wl1271_event.h b/drivers/net/wireless/wl12xx/event.h
index e4751667cf5e..6cce0143adb5 100644
--- a/drivers/net/wireless/wl12xx/wl1271_event.h
+++ b/drivers/net/wireless/wl12xx/event.h
@@ -22,8 +22,8 @@
*
*/
-#ifndef __WL1271_EVENT_H__
-#define __WL1271_EVENT_H__
+#ifndef __EVENT_H__
+#define __EVENT_H__
/*
* Mbox events
diff --git a/drivers/net/wireless/wl12xx/wl1271_ini.h b/drivers/net/wireless/wl12xx/ini.h
index 2313047d4015..c330a2583dfd 100644
--- a/drivers/net/wireless/wl12xx/wl1271_ini.h
+++ b/drivers/net/wireless/wl12xx/ini.h
@@ -21,8 +21,8 @@
*
*/
-#ifndef __WL1271_INI_H__
-#define __WL1271_INI_H__
+#ifndef __INI_H__
+#define __INI_H__
#define WL1271_INI_MAX_SMART_REFLEX_PARAM 16
diff --git a/drivers/net/wireless/wl12xx/wl1271_init.c b/drivers/net/wireless/wl12xx/init.c
index 8044bba70ee7..7949d346aadb 100644
--- a/drivers/net/wireless/wl12xx/wl1271_init.c
+++ b/drivers/net/wireless/wl12xx/init.c
@@ -25,11 +25,11 @@
#include <linux/module.h>
#include <linux/slab.h>
-#include "wl1271_init.h"
+#include "init.h"
#include "wl12xx_80211.h"
-#include "wl1271_acx.h"
-#include "wl1271_cmd.h"
-#include "wl1271_reg.h"
+#include "acx.h"
+#include "cmd.h"
+#include "reg.h"
static int wl1271_init_hwenc_config(struct wl1271 *wl)
{
@@ -290,7 +290,7 @@ int wl1271_hw_init(struct wl1271 *wl)
goto out_free_memmap;
/* Default fragmentation threshold */
- ret = wl1271_acx_frag_threshold(wl);
+ ret = wl1271_acx_frag_threshold(wl, wl->conf.tx.frag_threshold);
if (ret < 0)
goto out_free_memmap;
diff --git a/drivers/net/wireless/wl12xx/wl1271_init.h b/drivers/net/wireless/wl12xx/init.h
index bc26f8c53b91..7762421f8602 100644
--- a/drivers/net/wireless/wl12xx/wl1271_init.h
+++ b/drivers/net/wireless/wl12xx/init.h
@@ -21,10 +21,10 @@
*
*/
-#ifndef __WL1271_INIT_H__
-#define __WL1271_INIT_H__
+#ifndef __INIT_H__
+#define __INIT_H__
-#include "wl1271.h"
+#include "wl12xx.h"
int wl1271_hw_init_power_auth(struct wl1271 *wl);
int wl1271_init_templates_config(struct wl1271 *wl);
diff --git a/drivers/net/wireless/wl12xx/wl1271_io.c b/drivers/net/wireless/wl12xx/io.c
index c8759acef131..35c2f1aca6ba 100644
--- a/drivers/net/wireless/wl12xx/wl1271_io.c
+++ b/drivers/net/wireless/wl12xx/io.c
@@ -26,9 +26,9 @@
#include <linux/crc7.h>
#include <linux/spi/spi.h>
-#include "wl1271.h"
+#include "wl12xx.h"
#include "wl12xx_80211.h"
-#include "wl1271_io.h"
+#include "io.h"
#define OCP_CMD_LOOP 32
diff --git a/drivers/net/wireless/wl12xx/wl1271_io.h b/drivers/net/wireless/wl12xx/io.h
index c1f92e65ded0..844b32b170bb 100644
--- a/drivers/net/wireless/wl12xx/wl1271_io.h
+++ b/drivers/net/wireless/wl12xx/io.h
@@ -22,10 +22,10 @@
*
*/
-#ifndef __WL1271_IO_H__
-#define __WL1271_IO_H__
+#ifndef __IO_H__
+#define __IO_H__
-#include "wl1271_reg.h"
+#include "reg.h"
#define HW_ACCESS_MEMORY_MAX_RANGE 0x1FFC0
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/main.c
index 48a4b9961ae6..708ffe304c6d 100644
--- a/drivers/net/wireless/wl12xx/wl1271_main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -31,20 +31,20 @@
#include <linux/platform_device.h>
#include <linux/slab.h>
-#include "wl1271.h"
+#include "wl12xx.h"
#include "wl12xx_80211.h"
-#include "wl1271_reg.h"
-#include "wl1271_io.h"
-#include "wl1271_event.h"
-#include "wl1271_tx.h"
-#include "wl1271_rx.h"
-#include "wl1271_ps.h"
-#include "wl1271_init.h"
-#include "wl1271_debugfs.h"
-#include "wl1271_cmd.h"
-#include "wl1271_boot.h"
-#include "wl1271_testmode.h"
-#include "wl1271_scan.h"
+#include "reg.h"
+#include "io.h"
+#include "event.h"
+#include "tx.h"
+#include "rx.h"
+#include "ps.h"
+#include "init.h"
+#include "debugfs.h"
+#include "cmd.h"
+#include "boot.h"
+#include "testmode.h"
+#include "scan.h"
#define WL1271_BOOT_RETRIES 3
@@ -335,6 +335,27 @@ out:
return NOTIFY_OK;
}
+static int wl1271_reg_notify(struct wiphy *wiphy,
+ struct regulatory_request *request) {
+ struct ieee80211_supported_band *band;
+ struct ieee80211_channel *ch;
+ int i;
+
+ band = wiphy->bands[IEEE80211_BAND_5GHZ];
+ for (i = 0; i < band->n_channels; i++) {
+ ch = &band->channels[i];
+ if (ch->flags & IEEE80211_CHAN_DISABLED)
+ continue;
+
+ if (ch->flags & IEEE80211_CHAN_RADAR)
+ ch->flags |= IEEE80211_CHAN_NO_IBSS |
+ IEEE80211_CHAN_PASSIVE_SCAN;
+
+ }
+
+ return 0;
+}
+
static void wl1271_conf_init(struct wl1271 *wl)
{
@@ -404,7 +425,7 @@ static int wl1271_plt_init(struct wl1271 *wl)
goto out_free_memmap;
/* Default fragmentation threshold */
- ret = wl1271_acx_frag_threshold(wl);
+ ret = wl1271_acx_frag_threshold(wl, wl->conf.tx.frag_threshold);
if (ret < 0)
goto out_free_memmap;
@@ -481,9 +502,9 @@ static void wl1271_fw_status(struct wl1271 *wl,
total += cnt;
}
- /* if more blocks are available now, schedule some tx work */
- if (total && !skb_queue_empty(&wl->tx_queue))
- ieee80211_queue_work(wl->hw, &wl->tx_work);
+ /* if more blocks are available now, tx work can be scheduled */
+ if (total)
+ clear_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags);
/* update the host-chipset time offset */
getnstimeofday(&ts);
@@ -529,6 +550,15 @@ static void wl1271_irq_work(struct work_struct *work)
intr &= WL1271_INTR_MASK;
+ if (unlikely(intr & WL1271_ACX_INTR_WATCHDOG)) {
+ wl1271_error("watchdog interrupt received! "
+ "starting recovery.");
+ ieee80211_queue_work(wl->hw, &wl->recovery_work);
+
+ /* restarting the chip. ignore any other interrupt. */
+ goto out;
+ }
+
if (intr & WL1271_ACX_INTR_DATA) {
wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA");
@@ -537,6 +567,16 @@ static void wl1271_irq_work(struct work_struct *work)
(wl->tx_results_count & 0xff))
wl1271_tx_complete(wl);
+ /* Check if any tx blocks were freed */
+ if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) &&
+ !skb_queue_empty(&wl->tx_queue)) {
+ /*
+ * In order to avoid starvation of the TX path,
+ * call the work function directly.
+ */
+ wl1271_tx_work_locked(wl);
+ }
+
wl1271_rx(wl, wl->fw_status);
}
@@ -851,12 +891,32 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
struct ieee80211_sta *sta = txinfo->control.sta;
unsigned long flags;
- /* peek into the rates configured in the STA entry */
+ /*
+ * peek into the rates configured in the STA entry.
+ * The rates set after connection stage, The first block only BG sets:
+ * the compare is for bit 0-16 of sta_rate_set. The second block add
+ * HT rates in case of HT supported.
+ */
spin_lock_irqsave(&wl->wl_lock, flags);
- if (sta && sta->supp_rates[conf->channel->band] != wl->sta_rate_set) {
+ if (sta &&
+ (sta->supp_rates[conf->channel->band] !=
+ (wl->sta_rate_set & HW_BG_RATES_MASK))) {
wl->sta_rate_set = sta->supp_rates[conf->channel->band];
set_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags);
}
+
+#ifdef CONFIG_WL12XX_HT
+ if (sta &&
+ sta->ht_cap.ht_supported &&
+ ((wl->sta_rate_set >> HW_HT_RATES_OFFSET) !=
+ sta->ht_cap.mcs.rx_mask[0])) {
+ /* Clean MCS bits before setting them */
+ wl->sta_rate_set &= HW_BG_RATES_MASK;
+ wl->sta_rate_set |=
+ (sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET);
+ set_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags);
+ }
+#endif
spin_unlock_irqrestore(&wl->wl_lock, flags);
/* queue the packet */
@@ -867,7 +927,8 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
* before that, the tx_work will not be initialized!
*/
- ieee80211_queue_work(wl->hw, &wl->tx_work);
+ if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags))
+ ieee80211_queue_work(wl->hw, &wl->tx_work);
/*
* The workqueue is slow to process the tx_queue and we need stop
@@ -919,18 +980,19 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
struct wiphy *wiphy = hw->wiphy;
int retries = WL1271_BOOT_RETRIES;
int ret = 0;
+ bool booted = false;
wl1271_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM",
vif->type, vif->addr);
mutex_lock(&wl->mutex);
if (wl->vif) {
+ wl1271_debug(DEBUG_MAC80211,
+ "multiple vifs are not supported yet");
ret = -EBUSY;
goto out;
}
- wl->vif = vif;
-
switch (vif->type) {
case NL80211_IFTYPE_STATION:
wl->bss_type = BSS_TYPE_STA_BSS;
@@ -968,15 +1030,8 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
if (ret < 0)
goto irq_disable;
- wl->state = WL1271_STATE_ON;
- wl1271_info("firmware booted (%s)", wl->chip.fw_ver);
-
- /* update hw/fw version info in wiphy struct */
- wiphy->hw_version = wl->chip.id;
- strncpy(wiphy->fw_version, wl->chip.fw_ver,
- sizeof(wiphy->fw_version));
-
- goto out;
+ booted = true;
+ break;
irq_disable:
wl1271_disable_interrupts(wl);
@@ -994,8 +1049,21 @@ power_off:
wl1271_power_off(wl);
}
- wl1271_error("firmware boot failed despite %d retries",
- WL1271_BOOT_RETRIES);
+ if (!booted) {
+ wl1271_error("firmware boot failed despite %d retries",
+ WL1271_BOOT_RETRIES);
+ goto out;
+ }
+
+ wl->vif = vif;
+ wl->state = WL1271_STATE_ON;
+ wl1271_info("firmware booted (%s)", wl->chip.fw_ver);
+
+ /* update hw/fw version info in wiphy struct */
+ wiphy->hw_version = wl->chip.id;
+ strncpy(wiphy->fw_version, wl->chip.fw_ver,
+ sizeof(wiphy->fw_version));
+
out:
mutex_unlock(&wl->mutex);
@@ -1025,6 +1093,7 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl)
wl->scan.state = WL1271_SCAN_STATE_IDLE;
kfree(wl->scan.scanned_ch);
wl->scan.scanned_ch = NULL;
+ wl->scan.req = NULL;
ieee80211_scan_completed(wl->hw, true);
}
@@ -1312,8 +1381,10 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
mutex_lock(&wl->mutex);
- if (unlikely(wl->state == WL1271_STATE_OFF))
+ if (unlikely(wl->state == WL1271_STATE_OFF)) {
+ ret = -EAGAIN;
goto out;
+ }
ret = wl1271_ps_elp_wakeup(wl, false);
if (ret < 0)
@@ -1536,6 +1607,11 @@ static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
mutex_lock(&wl->mutex);
+ if (unlikely(wl->state == WL1271_STATE_OFF)) {
+ ret = -EAGAIN;
+ goto out_unlock;
+ }
+
ret = wl1271_ps_elp_wakeup(wl, false);
if (ret < 0)
goto out_unlock;
@@ -1645,6 +1721,16 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw,
mutex_lock(&wl->mutex);
+ if (wl->state == WL1271_STATE_OFF) {
+ /*
+ * We cannot return -EBUSY here because cfg80211 will expect
+ * a call to ieee80211_scan_completed if we do - in this case
+ * there won't be any call.
+ */
+ ret = -EAGAIN;
+ goto out;
+ }
+
ret = wl1271_ps_elp_wakeup(wl, false);
if (ret < 0)
goto out;
@@ -1659,6 +1745,34 @@ out:
return ret;
}
+static int wl1271_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
+{
+ struct wl1271 *wl = hw->priv;
+ int ret = 0;
+
+ mutex_lock(&wl->mutex);
+
+ if (unlikely(wl->state == WL1271_STATE_OFF)) {
+ ret = -EAGAIN;
+ goto out;
+ }
+
+ ret = wl1271_ps_elp_wakeup(wl, false);
+ if (ret < 0)
+ goto out;
+
+ ret = wl1271_acx_frag_threshold(wl, (u16)value);
+ if (ret < 0)
+ wl1271_warning("wl1271_op_set_frag_threshold failed: %d", ret);
+
+ wl1271_ps_elp_sleep(wl);
+
+out:
+ mutex_unlock(&wl->mutex);
+
+ return ret;
+}
+
static int wl1271_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
{
struct wl1271 *wl = hw->priv;
@@ -1666,8 +1780,10 @@ static int wl1271_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
mutex_lock(&wl->mutex);
- if (unlikely(wl->state == WL1271_STATE_OFF))
+ if (unlikely(wl->state == WL1271_STATE_OFF)) {
+ ret = -EAGAIN;
goto out;
+ }
ret = wl1271_ps_elp_wakeup(wl, false);
if (ret < 0)
@@ -1709,6 +1825,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
{
enum wl1271_cmd_ps_mode mode;
struct wl1271 *wl = hw->priv;
+ struct ieee80211_sta *sta = ieee80211_find_sta(vif, bss_conf->bssid);
bool do_join = false;
bool set_assoc = false;
int ret;
@@ -1717,6 +1834,9 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
mutex_lock(&wl->mutex);
+ if (unlikely(wl->state == WL1271_STATE_OFF))
+ goto out;
+
ret = wl1271_ps_elp_wakeup(wl, false);
if (ret < 0)
goto out;
@@ -1891,9 +2011,12 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
/* Disable the keep-alive feature */
ret = wl1271_acx_keep_alive_mode(wl, false);
-
if (ret < 0)
goto out_sleep;
+
+ /* restore the bssid filter and go to dummy bssid */
+ wl1271_unjoin(wl);
+ wl1271_dummy_join(wl);
}
}
@@ -1927,6 +2050,37 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
}
}
+ /*
+ * Takes care of: New association with HT enable,
+ * HT information change in beacon.
+ */
+ if (sta &&
+ (changed & BSS_CHANGED_HT) &&
+ (bss_conf->channel_type != NL80211_CHAN_NO_HT)) {
+ ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, true);
+ if (ret < 0) {
+ wl1271_warning("Set ht cap true failed %d", ret);
+ goto out_sleep;
+ }
+ ret = wl1271_acx_set_ht_information(wl,
+ bss_conf->ht_operation_mode);
+ if (ret < 0) {
+ wl1271_warning("Set ht information failed %d", ret);
+ goto out_sleep;
+ }
+ }
+ /*
+ * Takes care of: New association without HT,
+ * Disassociation.
+ */
+ else if (sta && (changed & BSS_CHANGED_ASSOC)) {
+ ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, false);
+ if (ret < 0) {
+ wl1271_warning("Set ht cap false failed %d", ret);
+ goto out_sleep;
+ }
+ }
+
if (changed & BSS_CHANGED_ARP_FILTER) {
__be32 addr = bss_conf->arp_addr_list[0];
WARN_ON(wl->bss_type != BSS_TYPE_STA_BSS);
@@ -1966,6 +2120,11 @@ static int wl1271_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
wl1271_debug(DEBUG_MAC80211, "mac80211 conf tx %d", queue);
+ if (unlikely(wl->state == WL1271_STATE_OFF)) {
+ ret = -EAGAIN;
+ goto out;
+ }
+
ret = wl1271_ps_elp_wakeup(wl, false);
if (ret < 0)
goto out;
@@ -2009,6 +2168,9 @@ static u64 wl1271_op_get_tsf(struct ieee80211_hw *hw)
mutex_lock(&wl->mutex);
+ if (unlikely(wl->state == WL1271_STATE_OFF))
+ goto out;
+
ret = wl1271_ps_elp_wakeup(wl, false);
if (ret < 0)
goto out;
@@ -2030,14 +2192,14 @@ static int wl1271_op_get_survey(struct ieee80211_hw *hw, int idx,
{
struct wl1271 *wl = hw->priv;
struct ieee80211_conf *conf = &hw->conf;
-
+
if (idx != 0)
return -ENOENT;
-
+
survey->channel = conf->channel;
survey->filled = SURVEY_INFO_NOISE_DBM;
survey->noise = wl->noise;
-
+
return 0;
}
@@ -2084,37 +2246,34 @@ static struct ieee80211_rate wl1271_rates[] = {
.hw_value_short = CONF_HW_BIT_RATE_54MBPS, },
};
-/*
- * Can't be const, mac80211 writes to this. The order of the channels here
- * is designed to improve scanning.
- */
+/* can't be const, mac80211 writes to this */
static struct ieee80211_channel wl1271_channels[] = {
{ .hw_value = 1, .center_freq = 2412, .max_power = 25 },
- { .hw_value = 5, .center_freq = 2432, .max_power = 25 },
- { .hw_value = 9, .center_freq = 2452, .max_power = 25 },
- { .hw_value = 13, .center_freq = 2472, .max_power = 25 },
- { .hw_value = 4, .center_freq = 2427, .max_power = 25 },
- { .hw_value = 8, .center_freq = 2447, .max_power = 25 },
- { .hw_value = 12, .center_freq = 2467, .max_power = 25 },
- { .hw_value = 3, .center_freq = 2422, .max_power = 25 },
- { .hw_value = 7, .center_freq = 2442, .max_power = 25 },
- { .hw_value = 11, .center_freq = 2462, .max_power = 25 },
{ .hw_value = 2, .center_freq = 2417, .max_power = 25 },
+ { .hw_value = 3, .center_freq = 2422, .max_power = 25 },
+ { .hw_value = 4, .center_freq = 2427, .max_power = 25 },
+ { .hw_value = 5, .center_freq = 2432, .max_power = 25 },
{ .hw_value = 6, .center_freq = 2437, .max_power = 25 },
+ { .hw_value = 7, .center_freq = 2442, .max_power = 25 },
+ { .hw_value = 8, .center_freq = 2447, .max_power = 25 },
+ { .hw_value = 9, .center_freq = 2452, .max_power = 25 },
{ .hw_value = 10, .center_freq = 2457, .max_power = 25 },
+ { .hw_value = 11, .center_freq = 2462, .max_power = 25 },
+ { .hw_value = 12, .center_freq = 2467, .max_power = 25 },
+ { .hw_value = 13, .center_freq = 2472, .max_power = 25 },
};
/* mapping to indexes for wl1271_rates */
static const u8 wl1271_rate_to_idx_2ghz[] = {
/* MCS rates are used only with 11n */
- CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS7 */
- CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS6 */
- CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS5 */
- CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS4 */
- CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS3 */
- CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS2 */
- CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS1 */
- CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS0 */
+ 7, /* CONF_HW_RXTX_RATE_MCS7 */
+ 6, /* CONF_HW_RXTX_RATE_MCS6 */
+ 5, /* CONF_HW_RXTX_RATE_MCS5 */
+ 4, /* CONF_HW_RXTX_RATE_MCS4 */
+ 3, /* CONF_HW_RXTX_RATE_MCS3 */
+ 2, /* CONF_HW_RXTX_RATE_MCS2 */
+ 1, /* CONF_HW_RXTX_RATE_MCS1 */
+ 0, /* CONF_HW_RXTX_RATE_MCS0 */
11, /* CONF_HW_RXTX_RATE_54 */
10, /* CONF_HW_RXTX_RATE_48 */
@@ -2134,12 +2293,34 @@ static const u8 wl1271_rate_to_idx_2ghz[] = {
0 /* CONF_HW_RXTX_RATE_1 */
};
+/* 11n STA capabilities */
+#define HW_RX_HIGHEST_RATE 72
+
+#ifdef CONFIG_WL12XX_HT
+#define WL12XX_HT_CAP { \
+ .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20, \
+ .ht_supported = true, \
+ .ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K, \
+ .ampdu_density = IEEE80211_HT_MPDU_DENSITY_8, \
+ .mcs = { \
+ .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, \
+ .rx_highest = cpu_to_le16(HW_RX_HIGHEST_RATE), \
+ .tx_params = IEEE80211_HT_MCS_TX_DEFINED, \
+ }, \
+}
+#else
+#define WL12XX_HT_CAP { \
+ .ht_supported = false, \
+}
+#endif
+
/* can't be const, mac80211 writes to this */
static struct ieee80211_supported_band wl1271_band_2ghz = {
.channels = wl1271_channels,
.n_channels = ARRAY_SIZE(wl1271_channels),
.bitrates = wl1271_rates,
.n_bitrates = ARRAY_SIZE(wl1271_rates),
+ .ht_cap = WL12XX_HT_CAP,
};
/* 5 GHz data rates for WL1273 */
@@ -2170,66 +2351,63 @@ static struct ieee80211_rate wl1271_rates_5ghz[] = {
.hw_value_short = CONF_HW_BIT_RATE_54MBPS, },
};
-/*
- * 5 GHz band channels for WL1273 - can't be const, mac80211 writes to this.
- * The order of the channels here is designed to improve scanning.
- */
+/* 5 GHz band channels for WL1273 */
static struct ieee80211_channel wl1271_channels_5ghz[] = {
{ .hw_value = 183, .center_freq = 4915},
- { .hw_value = 188, .center_freq = 4940},
- { .hw_value = 8, .center_freq = 5040},
- { .hw_value = 34, .center_freq = 5170},
- { .hw_value = 44, .center_freq = 5220},
- { .hw_value = 60, .center_freq = 5300},
- { .hw_value = 112, .center_freq = 5560},
- { .hw_value = 132, .center_freq = 5660},
- { .hw_value = 157, .center_freq = 5785},
{ .hw_value = 184, .center_freq = 4920},
+ { .hw_value = 185, .center_freq = 4925},
+ { .hw_value = 187, .center_freq = 4935},
+ { .hw_value = 188, .center_freq = 4940},
{ .hw_value = 189, .center_freq = 4945},
- { .hw_value = 9, .center_freq = 5045},
- { .hw_value = 36, .center_freq = 5180},
- { .hw_value = 46, .center_freq = 5230},
- { .hw_value = 64, .center_freq = 5320},
- { .hw_value = 116, .center_freq = 5580},
- { .hw_value = 136, .center_freq = 5680},
{ .hw_value = 192, .center_freq = 4960},
- { .hw_value = 11, .center_freq = 5055},
- { .hw_value = 38, .center_freq = 5190},
- { .hw_value = 48, .center_freq = 5240},
- { .hw_value = 100, .center_freq = 5500},
- { .hw_value = 120, .center_freq = 5600},
- { .hw_value = 140, .center_freq = 5700},
- { .hw_value = 185, .center_freq = 4925},
{ .hw_value = 196, .center_freq = 4980},
- { .hw_value = 12, .center_freq = 5060},
- { .hw_value = 40, .center_freq = 5200},
- { .hw_value = 52, .center_freq = 5260},
- { .hw_value = 104, .center_freq = 5520},
- { .hw_value = 124, .center_freq = 5620},
- { .hw_value = 149, .center_freq = 5745},
- { .hw_value = 161, .center_freq = 5805},
- { .hw_value = 187, .center_freq = 4935},
{ .hw_value = 7, .center_freq = 5035},
+ { .hw_value = 8, .center_freq = 5040},
+ { .hw_value = 9, .center_freq = 5045},
+ { .hw_value = 11, .center_freq = 5055},
+ { .hw_value = 12, .center_freq = 5060},
{ .hw_value = 16, .center_freq = 5080},
+ { .hw_value = 34, .center_freq = 5170},
+ { .hw_value = 36, .center_freq = 5180},
+ { .hw_value = 38, .center_freq = 5190},
+ { .hw_value = 40, .center_freq = 5200},
{ .hw_value = 42, .center_freq = 5210},
+ { .hw_value = 44, .center_freq = 5220},
+ { .hw_value = 46, .center_freq = 5230},
+ { .hw_value = 48, .center_freq = 5240},
+ { .hw_value = 52, .center_freq = 5260},
{ .hw_value = 56, .center_freq = 5280},
+ { .hw_value = 60, .center_freq = 5300},
+ { .hw_value = 64, .center_freq = 5320},
+ { .hw_value = 100, .center_freq = 5500},
+ { .hw_value = 104, .center_freq = 5520},
{ .hw_value = 108, .center_freq = 5540},
+ { .hw_value = 112, .center_freq = 5560},
+ { .hw_value = 116, .center_freq = 5580},
+ { .hw_value = 120, .center_freq = 5600},
+ { .hw_value = 124, .center_freq = 5620},
{ .hw_value = 128, .center_freq = 5640},
+ { .hw_value = 132, .center_freq = 5660},
+ { .hw_value = 136, .center_freq = 5680},
+ { .hw_value = 140, .center_freq = 5700},
+ { .hw_value = 149, .center_freq = 5745},
{ .hw_value = 153, .center_freq = 5765},
+ { .hw_value = 157, .center_freq = 5785},
+ { .hw_value = 161, .center_freq = 5805},
{ .hw_value = 165, .center_freq = 5825},
};
/* mapping to indexes for wl1271_rates_5ghz */
static const u8 wl1271_rate_to_idx_5ghz[] = {
/* MCS rates are used only with 11n */
- CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS7 */
- CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS6 */
- CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS5 */
- CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS4 */
- CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS3 */
- CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS2 */
- CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS1 */
- CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS0 */
+ 7, /* CONF_HW_RXTX_RATE_MCS7 */
+ 6, /* CONF_HW_RXTX_RATE_MCS6 */
+ 5, /* CONF_HW_RXTX_RATE_MCS5 */
+ 4, /* CONF_HW_RXTX_RATE_MCS4 */
+ 3, /* CONF_HW_RXTX_RATE_MCS3 */
+ 2, /* CONF_HW_RXTX_RATE_MCS2 */
+ 1, /* CONF_HW_RXTX_RATE_MCS1 */
+ 0, /* CONF_HW_RXTX_RATE_MCS0 */
7, /* CONF_HW_RXTX_RATE_54 */
6, /* CONF_HW_RXTX_RATE_48 */
@@ -2254,6 +2432,7 @@ static struct ieee80211_supported_band wl1271_band_5ghz = {
.n_channels = ARRAY_SIZE(wl1271_channels_5ghz),
.bitrates = wl1271_rates_5ghz,
.n_bitrates = ARRAY_SIZE(wl1271_rates_5ghz),
+ .ht_cap = WL12XX_HT_CAP,
};
static const u8 *wl1271_band_rate_to_idx[] = {
@@ -2273,6 +2452,7 @@ static const struct ieee80211_ops wl1271_ops = {
.set_key = wl1271_op_set_key,
.hw_scan = wl1271_op_hw_scan,
.bss_info_changed = wl1271_op_bss_info_changed,
+ .set_frag_threshold = wl1271_op_set_frag_threshold,
.set_rts_threshold = wl1271_op_set_rts_threshold,
.conf_tx = wl1271_op_conf_tx,
.get_tsf = wl1271_op_get_tsf,
@@ -2281,18 +2461,18 @@ static const struct ieee80211_ops wl1271_ops = {
};
-u8 wl1271_rate_to_idx(struct wl1271 *wl, int rate)
+u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band)
{
u8 idx;
- BUG_ON(wl->band >= sizeof(wl1271_band_rate_to_idx)/sizeof(u8 *));
+ BUG_ON(band >= sizeof(wl1271_band_rate_to_idx)/sizeof(u8 *));
if (unlikely(rate >= CONF_HW_RXTX_RATE_MAX)) {
wl1271_error("Illegal RX rate from HW: %d", rate);
return 0;
}
- idx = wl1271_band_rate_to_idx[wl->band][rate];
+ idx = wl1271_band_rate_to_idx[band][rate];
if (unlikely(idx == CONF_HW_RXTX_RATE_UNSUPPORTED)) {
wl1271_error("Unsupported RX rate from HW: %d", rate);
return 0;
@@ -2457,6 +2637,8 @@ int wl1271_init_ieee80211(struct wl1271 *wl)
wl->hw->queues = 4;
wl->hw->max_rates = 1;
+ wl->hw->wiphy->reg_notifier = wl1271_reg_notify;
+
SET_IEEE80211_DEV(wl->hw, wl1271_wl_to_dev(wl));
return 0;
@@ -2521,6 +2703,7 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
wl->sg_enabled = true;
wl->hw_pg_ver = -1;
+ memset(wl->tx_frames_map, 0, sizeof(wl->tx_frames_map));
for (i = 0; i < ACX_TX_DESCRIPTORS; i++)
wl->tx_frames[i] = NULL;
diff --git a/drivers/net/wireless/wl12xx/wl1271_ps.c b/drivers/net/wireless/wl12xx/ps.c
index e3c332e2f97c..60a3738eadb0 100644
--- a/drivers/net/wireless/wl12xx/wl1271_ps.c
+++ b/drivers/net/wireless/wl12xx/ps.c
@@ -21,9 +21,9 @@
*
*/
-#include "wl1271_reg.h"
-#include "wl1271_ps.h"
-#include "wl1271_io.h"
+#include "reg.h"
+#include "ps.h"
+#include "io.h"
#define WL1271_WAKEUP_TIMEOUT 500
diff --git a/drivers/net/wireless/wl12xx/wl1271_ps.h b/drivers/net/wireless/wl12xx/ps.h
index 6ba7b032736f..8415060f08e5 100644
--- a/drivers/net/wireless/wl12xx/wl1271_ps.h
+++ b/drivers/net/wireless/wl12xx/ps.h
@@ -21,11 +21,11 @@
*
*/
-#ifndef __WL1271_PS_H__
-#define __WL1271_PS_H__
+#ifndef __PS_H__
+#define __PS_H__
-#include "wl1271.h"
-#include "wl1271_acx.h"
+#include "wl12xx.h"
+#include "acx.h"
int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode,
u32 rates, bool send);
diff --git a/drivers/net/wireless/wl12xx/wl1271_reg.h b/drivers/net/wireless/wl12xx/reg.h
index 990960771528..990960771528 100644
--- a/drivers/net/wireless/wl12xx/wl1271_reg.h
+++ b/drivers/net/wireless/wl12xx/reg.h
diff --git a/drivers/net/wireless/wl12xx/wl1271_rx.c b/drivers/net/wireless/wl12xx/rx.c
index bea133b6e489..682304c30b81 100644
--- a/drivers/net/wireless/wl12xx/wl1271_rx.c
+++ b/drivers/net/wireless/wl12xx/rx.c
@@ -23,11 +23,11 @@
#include <linux/gfp.h>
-#include "wl1271.h"
-#include "wl1271_acx.h"
-#include "wl1271_reg.h"
-#include "wl1271_rx.h"
-#include "wl1271_io.h"
+#include "wl12xx.h"
+#include "acx.h"
+#include "reg.h"
+#include "rx.h"
+#include "io.h"
static u8 wl1271_rx_get_mem_block(struct wl1271_fw_status *status,
u32 drv_rx_counter)
@@ -48,10 +48,24 @@ static void wl1271_rx_status(struct wl1271 *wl,
struct ieee80211_rx_status *status,
u8 beacon)
{
+ enum ieee80211_band desc_band;
+
memset(status, 0, sizeof(struct ieee80211_rx_status));
status->band = wl->band;
- status->rate_idx = wl1271_rate_to_idx(wl, desc->rate);
+
+ if ((desc->flags & WL1271_RX_DESC_BAND_MASK) == WL1271_RX_DESC_BAND_BG)
+ desc_band = IEEE80211_BAND_2GHZ;
+ else
+ desc_band = IEEE80211_BAND_5GHZ;
+
+ status->rate_idx = wl1271_rate_to_idx(desc->rate, desc_band);
+
+#ifdef CONFIG_WL12XX_HT
+ /* 11n support */
+ if (desc->rate <= CONF_HW_RXTX_RATE_MCS0)
+ status->flag |= RX_FLAG_HT;
+#endif
status->signal = desc->rssi;
@@ -170,10 +184,14 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status)
while (pkt_offset < buf_size) {
pkt_length = wl1271_rx_get_buf_size(status,
drv_rx_counter);
- if (wl1271_rx_handle_data(wl,
- wl->aggr_buf + pkt_offset,
- pkt_length) < 0)
- break;
+ /*
+ * the handle data call can only fail in memory-outage
+ * conditions, in that case the received frame will just
+ * be dropped.
+ */
+ wl1271_rx_handle_data(wl,
+ wl->aggr_buf + pkt_offset,
+ pkt_length);
wl->rx_counter++;
drv_rx_counter++;
drv_rx_counter &= NUM_RX_PKT_DESC_MOD_MASK;
diff --git a/drivers/net/wireless/wl12xx/wl1271_rx.h b/drivers/net/wireless/wl12xx/rx.h
index 13a232333b13..3abb26fe0364 100644
--- a/drivers/net/wireless/wl12xx/wl1271_rx.h
+++ b/drivers/net/wireless/wl12xx/rx.h
@@ -22,8 +22,8 @@
*
*/
-#ifndef __WL1271_RX_H__
-#define __WL1271_RX_H__
+#ifndef __RX_H__
+#define __RX_H__
#include <linux/bitops.h>
@@ -116,6 +116,6 @@ struct wl1271_rx_descriptor {
} __packed;
void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status);
-u8 wl1271_rate_to_idx(struct wl1271 *wl, int rate);
+u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band);
#endif
diff --git a/drivers/net/wireless/wl12xx/wl1271_scan.c b/drivers/net/wireless/wl12xx/scan.c
index 909bb47995b6..f3f2c5b011ee 100644
--- a/drivers/net/wireless/wl12xx/wl1271_scan.c
+++ b/drivers/net/wireless/wl12xx/scan.c
@@ -23,10 +23,10 @@
#include <linux/ieee80211.h>
-#include "wl1271.h"
-#include "wl1271_cmd.h"
-#include "wl1271_scan.h"
-#include "wl1271_acx.h"
+#include "wl12xx.h"
+#include "cmd.h"
+#include "scan.h"
+#include "acx.h"
void wl1271_scan_complete_work(struct work_struct *work)
{
@@ -48,14 +48,15 @@ void wl1271_scan_complete_work(struct work_struct *work)
wl->scan.state = WL1271_SCAN_STATE_IDLE;
kfree(wl->scan.scanned_ch);
wl->scan.scanned_ch = NULL;
- mutex_unlock(&wl->mutex);
-
+ wl->scan.req = NULL;
ieee80211_scan_completed(wl->hw, false);
if (wl->scan.failed) {
wl1271_info("Scan completed due to error.");
ieee80211_queue_work(wl->hw, &wl->recovery_work);
}
+ mutex_unlock(&wl->mutex);
+
}
diff --git a/drivers/net/wireless/wl12xx/wl1271_scan.h b/drivers/net/wireless/wl12xx/scan.h
index 6d57127b5e6b..421a750add5a 100644
--- a/drivers/net/wireless/wl12xx/wl1271_scan.h
+++ b/drivers/net/wireless/wl12xx/scan.h
@@ -21,10 +21,10 @@
*
*/
-#ifndef __WL1271_SCAN_H__
-#define __WL1271_SCAN_H__
+#ifndef __SCAN_H__
+#define __SCAN_H__
-#include "wl1271.h"
+#include "wl12xx.h"
int wl1271_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len,
struct cfg80211_scan_request *req);
diff --git a/drivers/net/wireless/wl12xx/wl1271_sdio.c b/drivers/net/wireless/wl12xx/sdio.c
index 784ef3432641..93cbb8d5aba9 100644
--- a/drivers/net/wireless/wl12xx/wl1271_sdio.c
+++ b/drivers/net/wireless/wl12xx/sdio.c
@@ -32,9 +32,9 @@
#include <linux/wl12xx.h>
#include <linux/pm_runtime.h>
-#include "wl1271.h"
+#include "wl12xx.h"
#include "wl12xx_80211.h"
-#include "wl1271_io.h"
+#include "io.h"
#ifndef SDIO_VENDOR_ID_TI
#define SDIO_VENDOR_ID_TI 0x0097
diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.c b/drivers/net/wireless/wl12xx/spi.c
index ef801680773f..46714910f98c 100644
--- a/drivers/net/wireless/wl12xx/wl1271_spi.c
+++ b/drivers/net/wireless/wl12xx/spi.c
@@ -28,11 +28,11 @@
#include <linux/wl12xx.h>
#include <linux/slab.h>
-#include "wl1271.h"
+#include "wl12xx.h"
#include "wl12xx_80211.h"
-#include "wl1271_io.h"
+#include "io.h"
-#include "wl1271_reg.h"
+#include "reg.h"
#define WSPI_CMD_READ 0x40000000
#define WSPI_CMD_WRITE 0x00000000
diff --git a/drivers/net/wireless/wl12xx/wl1271_testmode.c b/drivers/net/wireless/wl12xx/testmode.c
index a3aa84386c88..e64403b6896d 100644
--- a/drivers/net/wireless/wl12xx/wl1271_testmode.c
+++ b/drivers/net/wireless/wl12xx/testmode.c
@@ -20,13 +20,13 @@
* 02110-1301 USA
*
*/
-#include "wl1271_testmode.h"
+#include "testmode.h"
#include <linux/slab.h>
#include <net/genetlink.h>
-#include "wl1271.h"
-#include "wl1271_acx.h"
+#include "wl12xx.h"
+#include "acx.h"
#define WL1271_TM_MAX_DATA_LENGTH 1024
@@ -37,6 +37,7 @@ enum wl1271_tm_commands {
WL1271_TM_CMD_CONFIGURE,
WL1271_TM_CMD_NVS_PUSH,
WL1271_TM_CMD_SET_PLT_MODE,
+ WL1271_TM_CMD_RECOVER,
__WL1271_TM_CMD_AFTER_LAST
};
@@ -248,6 +249,15 @@ static int wl1271_tm_cmd_set_plt_mode(struct wl1271 *wl, struct nlattr *tb[])
return ret;
}
+static int wl1271_tm_cmd_recover(struct wl1271 *wl, struct nlattr *tb[])
+{
+ wl1271_debug(DEBUG_TESTMODE, "testmode cmd recover");
+
+ ieee80211_queue_work(wl->hw, &wl->recovery_work);
+
+ return 0;
+}
+
int wl1271_tm_cmd(struct ieee80211_hw *hw, void *data, int len)
{
struct wl1271 *wl = hw->priv;
@@ -272,6 +282,8 @@ int wl1271_tm_cmd(struct ieee80211_hw *hw, void *data, int len)
return wl1271_tm_cmd_nvs_push(wl, tb);
case WL1271_TM_CMD_SET_PLT_MODE:
return wl1271_tm_cmd_set_plt_mode(wl, tb);
+ case WL1271_TM_CMD_RECOVER:
+ return wl1271_tm_cmd_recover(wl, tb);
default:
return -EOPNOTSUPP;
}
diff --git a/drivers/net/wireless/wl12xx/wl1271_testmode.h b/drivers/net/wireless/wl12xx/testmode.h
index c196d28f9d9d..8071654259ea 100644
--- a/drivers/net/wireless/wl12xx/wl1271_testmode.h
+++ b/drivers/net/wireless/wl12xx/testmode.h
@@ -21,8 +21,8 @@
*
*/
-#ifndef __WL1271_TESTMODE_H__
-#define __WL1271_TESTMODE_H__
+#ifndef __TESTMODE_H__
+#define __TESTMODE_H__
#include <net/mac80211.h>
diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.c b/drivers/net/wireless/wl12xx/tx.c
index e3dc13c4d01a..d332b3f6d0fa 100644
--- a/drivers/net/wireless/wl12xx/wl1271_tx.c
+++ b/drivers/net/wireless/wl12xx/tx.c
@@ -24,23 +24,32 @@
#include <linux/kernel.h>
#include <linux/module.h>
-#include "wl1271.h"
-#include "wl1271_io.h"
-#include "wl1271_reg.h"
-#include "wl1271_ps.h"
-#include "wl1271_tx.h"
+#include "wl12xx.h"
+#include "io.h"
+#include "reg.h"
+#include "ps.h"
+#include "tx.h"
-static int wl1271_tx_id(struct wl1271 *wl, struct sk_buff *skb)
+static int wl1271_alloc_tx_id(struct wl1271 *wl, struct sk_buff *skb)
{
- int i;
- for (i = 0; i < ACX_TX_DESCRIPTORS; i++)
- if (wl->tx_frames[i] == NULL) {
- wl->tx_frames[i] = skb;
- wl->tx_frames_cnt++;
- return i;
- }
+ int id;
+
+ id = find_first_zero_bit(wl->tx_frames_map, ACX_TX_DESCRIPTORS);
+ if (id >= ACX_TX_DESCRIPTORS)
+ return -EBUSY;
+
+ __set_bit(id, wl->tx_frames_map);
+ wl->tx_frames[id] = skb;
+ wl->tx_frames_cnt++;
+ return id;
+}
- return -EBUSY;
+static void wl1271_free_tx_id(struct wl1271 *wl, int id)
+{
+ if (__test_and_clear_bit(id, wl->tx_frames_map)) {
+ wl->tx_frames[id] = NULL;
+ wl->tx_frames_cnt--;
+ }
}
static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra,
@@ -52,10 +61,10 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra,
int id, ret = -EBUSY;
if (buf_offset + total_len > WL1271_AGGR_BUFFER_SIZE)
- return -EBUSY;
+ return -EAGAIN;
/* allocate free identifier for the packet */
- id = wl1271_tx_id(wl, skb);
+ id = wl1271_alloc_tx_id(wl, skb);
if (id < 0)
return id;
@@ -79,8 +88,7 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra,
"tx_allocate: size: %d, blocks: %d, id: %d",
total_len, total_blocks, id);
} else {
- wl->tx_frames[id] = NULL;
- wl->tx_frames_cnt--;
+ wl1271_free_tx_id(wl, id);
}
return ret;
@@ -201,41 +209,67 @@ u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set)
rate_set >>= 1;
}
+#ifdef CONFIG_WL12XX_HT
+ /* MCS rates indication are on bits 16 - 23 */
+ rate_set >>= HW_HT_RATES_OFFSET - band->n_bitrates;
+
+ for (bit = 0; bit < 8; bit++) {
+ if (rate_set & 0x1)
+ enabled_rates |= (CONF_HW_BIT_RATE_MCS_0 << bit);
+ rate_set >>= 1;
+ }
+#endif
+
return enabled_rates;
}
-void wl1271_tx_work(struct work_struct *work)
+static void handle_tx_low_watermark(struct wl1271 *wl)
+{
+ unsigned long flags;
+
+ if (test_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags) &&
+ skb_queue_len(&wl->tx_queue) <= WL1271_TX_QUEUE_LOW_WATERMARK) {
+ /* firmware buffer has space, restart queues */
+ spin_lock_irqsave(&wl->wl_lock, flags);
+ ieee80211_wake_queues(wl->hw);
+ clear_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags);
+ spin_unlock_irqrestore(&wl->wl_lock, flags);
+ }
+}
+
+void wl1271_tx_work_locked(struct wl1271 *wl)
{
- struct wl1271 *wl = container_of(work, struct wl1271, tx_work);
struct sk_buff *skb;
bool woken_up = false;
u32 sta_rates = 0;
- u32 buf_offset;
+ u32 buf_offset = 0;
+ bool sent_packets = false;
int ret;
/* check if the rates supported by the AP have changed */
if (unlikely(test_and_clear_bit(WL1271_FLAG_STA_RATES_CHANGED,
&wl->flags))) {
unsigned long flags;
+
spin_lock_irqsave(&wl->wl_lock, flags);
sta_rates = wl->sta_rate_set;
spin_unlock_irqrestore(&wl->wl_lock, flags);
}
- mutex_lock(&wl->mutex);
-
if (unlikely(wl->state == WL1271_STATE_OFF))
goto out;
/* if rates have changed, re-configure the rate policy */
if (unlikely(sta_rates)) {
+ ret = wl1271_ps_elp_wakeup(wl, false);
+ if (ret < 0)
+ goto out;
+ woken_up = true;
+
wl->rate_set = wl1271_tx_enabled_rates_get(wl, sta_rates);
wl1271_acx_rate_policies(wl);
}
- /* Prepare the transfer buffer, by aggregating all
- * available packets */
- buf_offset = 0;
while ((skb = skb_dequeue(&wl->tx_queue))) {
if (!woken_up) {
ret = wl1271_ps_elp_wakeup(wl, false);
@@ -245,13 +279,25 @@ void wl1271_tx_work(struct work_struct *work)
}
ret = wl1271_prepare_tx_frame(wl, skb, buf_offset);
- if (ret == -EBUSY) {
+ if (ret == -EAGAIN) {
+ /*
+ * Aggregation buffer is full.
+ * Flush buffer and try again.
+ */
+ skb_queue_head(&wl->tx_queue, skb);
+ wl1271_write(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf,
+ buf_offset, true);
+ sent_packets = true;
+ buf_offset = 0;
+ continue;
+ } else if (ret == -EBUSY) {
/*
- * Either the firmware buffer is full, or the
- * aggregation buffer is.
+ * Firmware buffer is full.
* Queue back last skb, and stop aggregating.
*/
skb_queue_head(&wl->tx_queue, skb);
+ /* No work left, avoid scheduling redundant tx work */
+ set_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags);
goto out_ack;
} else if (ret < 0) {
dev_kfree_skb(skb);
@@ -265,14 +311,25 @@ out_ack:
if (buf_offset) {
wl1271_write(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf,
buf_offset, true);
+ sent_packets = true;
+ }
+ if (sent_packets) {
/* interrupt the firmware with the new packets */
wl1271_write32(wl, WL1271_HOST_WR_ACCESS, wl->tx_packets_count);
+ handle_tx_low_watermark(wl);
}
out:
if (woken_up)
wl1271_ps_elp_sleep(wl);
+}
+
+void wl1271_tx_work(struct work_struct *work)
+{
+ struct wl1271 *wl = container_of(work, struct wl1271, tx_work);
+ mutex_lock(&wl->mutex);
+ wl1271_tx_work_locked(wl);
mutex_unlock(&wl->mutex);
}
@@ -298,7 +355,7 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
if (result->status == TX_SUCCESS) {
if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
info->flags |= IEEE80211_TX_STAT_ACK;
- rate = wl1271_rate_to_idx(wl, result->rate_class_index);
+ rate = wl1271_rate_to_idx(result->rate_class_index, wl->band);
retries = result->ack_failures;
} else if (result->status == TX_RETRY_EXCEEDED) {
wl->stats.excessive_retries++;
@@ -335,8 +392,7 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
/* return the packet to the stack */
ieee80211_tx_status(wl->hw, skb);
- wl->tx_frames[result->id] = NULL;
- wl->tx_frames_cnt--;
+ wl1271_free_tx_id(wl, result->id);
}
/* Called upon reception of a TX complete interrupt */
@@ -375,19 +431,6 @@ void wl1271_tx_complete(struct wl1271 *wl)
wl->tx_results_count++;
}
-
- if (test_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags) &&
- skb_queue_len(&wl->tx_queue) <= WL1271_TX_QUEUE_LOW_WATERMARK) {
- unsigned long flags;
-
- /* firmware buffer has space, restart queues */
- wl1271_debug(DEBUG_TX, "tx_complete: waking queues");
- spin_lock_irqsave(&wl->wl_lock, flags);
- ieee80211_wake_queues(wl->hw);
- clear_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags);
- spin_unlock_irqrestore(&wl->wl_lock, flags);
- ieee80211_queue_work(wl->hw, &wl->tx_work);
- }
}
/* caller must hold wl->mutex */
@@ -402,14 +445,19 @@ void wl1271_tx_reset(struct wl1271 *wl)
ieee80211_tx_status(wl->hw, skb);
}
+ /*
+ * Make sure the driver is at a consistent state, in case this
+ * function is called from a context other than interface removal.
+ */
+ handle_tx_low_watermark(wl);
+
for (i = 0; i < ACX_TX_DESCRIPTORS; i++)
if (wl->tx_frames[i] != NULL) {
skb = wl->tx_frames[i];
- wl->tx_frames[i] = NULL;
+ wl1271_free_tx_id(wl, i);
wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb);
ieee80211_tx_status(wl->hw, skb);
}
- wl->tx_frames_cnt = 0;
}
#define WL1271_TX_FLUSH_TIMEOUT 500000
diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.h b/drivers/net/wireless/wl12xx/tx.h
index d12a129ad11c..903e5dc69b7a 100644
--- a/drivers/net/wireless/wl12xx/wl1271_tx.h
+++ b/drivers/net/wireless/wl12xx/tx.h
@@ -22,8 +22,8 @@
*
*/
-#ifndef __WL1271_TX_H__
-#define __WL1271_TX_H__
+#ifndef __TX_H__
+#define __TX_H__
#define TX_HW_BLOCK_SPARE 2
#define TX_HW_BLOCK_SIZE 252
@@ -140,10 +140,11 @@ static inline int wl1271_tx_get_queue(int queue)
}
void wl1271_tx_work(struct work_struct *work);
+void wl1271_tx_work_locked(struct wl1271 *wl);
void wl1271_tx_complete(struct wl1271 *wl);
void wl1271_tx_reset(struct wl1271 *wl);
void wl1271_tx_flush(struct wl1271 *wl);
-u8 wl1271_rate_to_idx(struct wl1271 *wl, int rate);
+u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band);
u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set);
#endif
diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl12xx.h
index 8a4cd763e5a2..3c836e6063e6 100644
--- a/drivers/net/wireless/wl12xx/wl1271.h
+++ b/drivers/net/wireless/wl12xx/wl12xx.h
@@ -22,8 +22,8 @@
*
*/
-#ifndef __WL1271_H__
-#define __WL1271_H__
+#ifndef __WL12XX_H__
+#define __WL12XX_H__
#include <linux/mutex.h>
#include <linux/completion.h>
@@ -32,8 +32,8 @@
#include <linux/bitops.h>
#include <net/mac80211.h>
-#include "wl1271_conf.h"
-#include "wl1271_ini.h"
+#include "conf.h"
+#include "ini.h"
#define DRIVER_NAME "wl1271"
#define DRIVER_PREFIX DRIVER_NAME ": "
@@ -351,6 +351,7 @@ struct wl1271 {
#define WL1271_FLAG_IDLE_REQUESTED (11)
#define WL1271_FLAG_PSPOLL_FAILURE (12)
#define WL1271_FLAG_STA_STATE_SENT (13)
+#define WL1271_FLAG_FW_TX_BUSY (14)
unsigned long flags;
struct wl1271_partition_set part;
@@ -397,6 +398,7 @@ struct wl1271 {
struct work_struct tx_work;
/* Pending TX frames */
+ unsigned long tx_frames_map[BITS_TO_LONGS(ACX_TX_DESCRIPTORS)];
struct sk_buff *tx_frames[ACX_TX_DESCRIPTORS];
int tx_frames_cnt;
@@ -432,7 +434,12 @@ struct wl1271 {
/* Our association ID */
u16 aid;
- /* currently configured rate set */
+ /*
+ * currently configured rate set:
+ * bits 0-15 - 802.11abg rates
+ * bits 16-23 - 802.11n MCS index mask
+ * support only 1 stream, thus only 8 bits for the MCS rates (0-7).
+ */
u32 sta_rate_set;
u32 basic_rate_set;
u32 basic_rate;
@@ -509,4 +516,8 @@ int wl1271_plt_stop(struct wl1271 *wl);
#define WL1271_PRE_POWER_ON_SLEEP 20 /* in miliseconds */
#define WL1271_POWER_ON_SLEEP 200 /* in miliseconds */
+/* Macros to handle wl1271.sta_rate_set */
+#define HW_BG_RATES_MASK 0xffff
+#define HW_HT_RATES_OFFSET 16
+
#endif
diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c
index 390d77f762c4..415eec401e2e 100644
--- a/drivers/net/wireless/zd1201.c
+++ b/drivers/net/wireless/zd1201.c
@@ -30,6 +30,7 @@ static struct usb_device_id zd1201_table[] = {
{USB_DEVICE(0x0ace, 0x1201)}, /* ZyDAS ZD1201 Wireless USB Adapter */
{USB_DEVICE(0x050d, 0x6051)}, /* Belkin F5D6051 usb adapter */
{USB_DEVICE(0x0db0, 0x6823)}, /* MSI UB11B usb adapter */
+ {USB_DEVICE(0x1044, 0x8004)}, /* Gigabyte GN-WLBZ101 */
{USB_DEVICE(0x1044, 0x8005)}, /* GIGABYTE GN-WLBZ201 usb adapter */
{}
};
@@ -1829,7 +1830,7 @@ err_zd:
static void zd1201_disconnect(struct usb_interface *interface)
{
- struct zd1201 *zd=(struct zd1201 *)usb_get_intfdata(interface);
+ struct zd1201 *zd = usb_get_intfdata(interface);
struct hlist_node *node, *node2;
struct zd1201_frag *frag;
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c
index 87a95bcfee57..30f8d404958b 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.c
+++ b/drivers/net/wireless/zd1211rw/zd_chip.c
@@ -1448,7 +1448,7 @@ int zd_rfwritev_locked(struct zd_chip *chip,
*/
int zd_rfwrite_cr_locked(struct zd_chip *chip, u32 value)
{
- struct zd_ioreq16 ioreqs[] = {
+ const struct zd_ioreq16 ioreqs[] = {
{ CR244, (value >> 16) & 0xff },
{ CR243, (value >> 8) & 0xff },
{ CR242, value & 0xff },
@@ -1475,7 +1475,7 @@ int zd_rfwritev_cr_locked(struct zd_chip *chip,
int zd_chip_set_multicast_hash(struct zd_chip *chip,
struct zd_mc_hash *hash)
{
- struct zd_ioreq32 ioreqs[] = {
+ const struct zd_ioreq32 ioreqs[] = {
{ CR_GROUP_HASH_P1, hash->low },
{ CR_GROUP_HASH_P2, hash->high },
};
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index 818e1480ca93..06041cb1c422 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -55,6 +55,7 @@ static struct usb_device_id usb_ids[] = {
{ USB_DEVICE(0x129b, 0x1666), .driver_info = DEVICE_ZD1211 },
{ USB_DEVICE(0x13b1, 0x001e), .driver_info = DEVICE_ZD1211 },
{ USB_DEVICE(0x1435, 0x0711), .driver_info = DEVICE_ZD1211 },
+ { USB_DEVICE(0x14ea, 0xab10), .driver_info = DEVICE_ZD1211 },
{ USB_DEVICE(0x14ea, 0xab13), .driver_info = DEVICE_ZD1211 },
{ USB_DEVICE(0x157e, 0x300a), .driver_info = DEVICE_ZD1211 },
{ USB_DEVICE(0x157e, 0x300b), .driver_info = DEVICE_ZD1211 },
@@ -92,6 +93,7 @@ static struct usb_device_id usb_ids[] = {
{ USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B },
{ USB_DEVICE(0x1582, 0x6003), .driver_info = DEVICE_ZD1211B },
{ USB_DEVICE(0x2019, 0x5303), .driver_info = DEVICE_ZD1211B },
+ { USB_DEVICE(0x2019, 0xed01), .driver_info = DEVICE_ZD1211B },
/* "Driverless" devices that need ejecting */
{ USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER },
{ USB_DEVICE(0x0ace, 0x20ff), .driver_info = DEVICE_INSTALLER },
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index c68b3dc19e11..3918d2cc5856 100644
--- a/drivers/ssb/main.c
+++ b/drivers/ssb/main.c
@@ -383,6 +383,35 @@ static int ssb_device_uevent(struct device *dev, struct kobj_uevent_env *env)
ssb_dev->id.revision);
}
+#define ssb_config_attr(attrib, field, format_string) \
+static ssize_t \
+attrib##_show(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+ return sprintf(buf, format_string, dev_to_ssb_dev(dev)->field); \
+}
+
+ssb_config_attr(core_num, core_index, "%u\n")
+ssb_config_attr(coreid, id.coreid, "0x%04x\n")
+ssb_config_attr(vendor, id.vendor, "0x%04x\n")
+ssb_config_attr(revision, id.revision, "%u\n")
+ssb_config_attr(irq, irq, "%u\n")
+static ssize_t
+name_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%s\n",
+ ssb_core_name(dev_to_ssb_dev(dev)->id.coreid));
+}
+
+static struct device_attribute ssb_device_attrs[] = {
+ __ATTR_RO(name),
+ __ATTR_RO(core_num),
+ __ATTR_RO(coreid),
+ __ATTR_RO(vendor),
+ __ATTR_RO(revision),
+ __ATTR_RO(irq),
+ __ATTR_NULL,
+};
+
static struct bus_type ssb_bustype = {
.name = "ssb",
.match = ssb_bus_match,
@@ -392,6 +421,7 @@ static struct bus_type ssb_bustype = {
.suspend = ssb_device_suspend,
.resume = ssb_device_resume,
.uevent = ssb_device_uevent,
+ .dev_attrs = ssb_device_attrs,
};
static void ssb_buses_lock(void)
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c
index 6e88d2b603b4..158449e55044 100644
--- a/drivers/ssb/pci.c
+++ b/drivers/ssb/pci.c
@@ -406,6 +406,46 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in)
out->antenna_gain.ghz5.a3 = gain;
}
+/* Revs 4 5 and 8 have partially shared layout */
+static void sprom_extract_r458(struct ssb_sprom *out, const u16 *in)
+{
+ SPEX(txpid2g[0], SSB_SPROM4_TXPID2G01,
+ SSB_SPROM4_TXPID2G0, SSB_SPROM4_TXPID2G0_SHIFT);
+ SPEX(txpid2g[1], SSB_SPROM4_TXPID2G01,
+ SSB_SPROM4_TXPID2G1, SSB_SPROM4_TXPID2G1_SHIFT);
+ SPEX(txpid2g[2], SSB_SPROM4_TXPID2G23,
+ SSB_SPROM4_TXPID2G2, SSB_SPROM4_TXPID2G2_SHIFT);
+ SPEX(txpid2g[3], SSB_SPROM4_TXPID2G23,
+ SSB_SPROM4_TXPID2G3, SSB_SPROM4_TXPID2G3_SHIFT);
+
+ SPEX(txpid5gl[0], SSB_SPROM4_TXPID5GL01,
+ SSB_SPROM4_TXPID5GL0, SSB_SPROM4_TXPID5GL0_SHIFT);
+ SPEX(txpid5gl[1], SSB_SPROM4_TXPID5GL01,
+ SSB_SPROM4_TXPID5GL1, SSB_SPROM4_TXPID5GL1_SHIFT);
+ SPEX(txpid5gl[2], SSB_SPROM4_TXPID5GL23,
+ SSB_SPROM4_TXPID5GL2, SSB_SPROM4_TXPID5GL2_SHIFT);
+ SPEX(txpid5gl[3], SSB_SPROM4_TXPID5GL23,
+ SSB_SPROM4_TXPID5GL3, SSB_SPROM4_TXPID5GL3_SHIFT);
+
+ SPEX(txpid5g[0], SSB_SPROM4_TXPID5G01,
+ SSB_SPROM4_TXPID5G0, SSB_SPROM4_TXPID5G0_SHIFT);
+ SPEX(txpid5g[1], SSB_SPROM4_TXPID5G01,
+ SSB_SPROM4_TXPID5G1, SSB_SPROM4_TXPID5G1_SHIFT);
+ SPEX(txpid5g[2], SSB_SPROM4_TXPID5G23,
+ SSB_SPROM4_TXPID5G2, SSB_SPROM4_TXPID5G2_SHIFT);
+ SPEX(txpid5g[3], SSB_SPROM4_TXPID5G23,
+ SSB_SPROM4_TXPID5G3, SSB_SPROM4_TXPID5G3_SHIFT);
+
+ SPEX(txpid5gh[0], SSB_SPROM4_TXPID5GH01,
+ SSB_SPROM4_TXPID5GH0, SSB_SPROM4_TXPID5GH0_SHIFT);
+ SPEX(txpid5gh[1], SSB_SPROM4_TXPID5GH01,
+ SSB_SPROM4_TXPID5GH1, SSB_SPROM4_TXPID5GH1_SHIFT);
+ SPEX(txpid5gh[2], SSB_SPROM4_TXPID5GH23,
+ SSB_SPROM4_TXPID5GH2, SSB_SPROM4_TXPID5GH2_SHIFT);
+ SPEX(txpid5gh[3], SSB_SPROM4_TXPID5GH23,
+ SSB_SPROM4_TXPID5GH3, SSB_SPROM4_TXPID5GH3_SHIFT);
+}
+
static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in)
{
int i;
@@ -471,6 +511,8 @@ static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in)
memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24,
sizeof(out->antenna_gain.ghz5));
+ sprom_extract_r458(out, in);
+
/* TODO - get remaining rev 4 stuff needed */
}
@@ -561,6 +603,8 @@ static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in)
memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24,
sizeof(out->antenna_gain.ghz5));
+ sprom_extract_r458(out, in);
+
/* TODO - get remaining rev 8 stuff needed */
}
@@ -573,37 +617,34 @@ static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out,
ssb_dprintk(KERN_DEBUG PFX "SPROM revision %d detected.\n", out->revision);
memset(out->et0mac, 0xFF, 6); /* preset et0 and et1 mac */
memset(out->et1mac, 0xFF, 6);
+
if ((bus->chip_id & 0xFF00) == 0x4400) {
/* Workaround: The BCM44XX chip has a stupid revision
* number stored in the SPROM.
* Always extract r1. */
out->revision = 1;
+ ssb_dprintk(KERN_DEBUG PFX "SPROM treated as revision %d\n", out->revision);
+ }
+
+ switch (out->revision) {
+ case 1:
+ case 2:
+ case 3:
sprom_extract_r123(out, in);
- } else if (bus->chip_id == 0x4321) {
- /* the BCM4328 has a chipid == 0x4321 and a rev 4 SPROM */
- out->revision = 4;
+ break;
+ case 4:
+ case 5:
sprom_extract_r45(out, in);
- } else {
- switch (out->revision) {
- case 1:
- case 2:
- case 3:
- sprom_extract_r123(out, in);
- break;
- case 4:
- case 5:
- sprom_extract_r45(out, in);
- break;
- case 8:
- sprom_extract_r8(out, in);
- break;
- default:
- ssb_printk(KERN_WARNING PFX "Unsupported SPROM"
- " revision %d detected. Will extract"
- " v1\n", out->revision);
- out->revision = 1;
- sprom_extract_r123(out, in);
- }
+ break;
+ case 8:
+ sprom_extract_r8(out, in);
+ break;
+ default:
+ ssb_printk(KERN_WARNING PFX "Unsupported SPROM"
+ " revision %d detected. Will extract"
+ " v1\n", out->revision);
+ out->revision = 1;
+ sprom_extract_r123(out, in);
}
if (out->boardflags_lo == 0xFFFF)
@@ -618,7 +659,7 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus,
struct ssb_sprom *sprom)
{
const struct ssb_sprom *fallback;
- int err = -ENOMEM;
+ int err;
u16 *buf;
if (!ssb_is_sprom_available(bus)) {
@@ -645,7 +686,7 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus,
buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL);
if (!buf)
- goto out;
+ return -ENOMEM;
bus->sprom_size = SSB_SPROMSIZE_WORDS_R123;
sprom_do_read(bus, buf);
err = sprom_check_crc(buf, bus->sprom_size);
@@ -655,7 +696,7 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus,
buf = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
GFP_KERNEL);
if (!buf)
- goto out;
+ return -ENOMEM;
bus->sprom_size = SSB_SPROMSIZE_WORDS_R4;
sprom_do_read(bus, buf);
err = sprom_check_crc(buf, bus->sprom_size);
@@ -677,7 +718,6 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus,
out_free:
kfree(buf);
-out:
return err;
}
diff --git a/drivers/ssb/pcihost_wrapper.c b/drivers/ssb/pcihost_wrapper.c
index 6536a041d90d..f6c8c81a0025 100644
--- a/drivers/ssb/pcihost_wrapper.c
+++ b/drivers/ssb/pcihost_wrapper.c
@@ -59,6 +59,7 @@ static int ssb_pcihost_probe(struct pci_dev *dev,
struct ssb_bus *ssb;
int err = -ENOMEM;
const char *name;
+ u32 val;
ssb = kzalloc(sizeof(*ssb), GFP_KERNEL);
if (!ssb)
@@ -74,6 +75,12 @@ static int ssb_pcihost_probe(struct pci_dev *dev,
goto err_pci_disable;
pci_set_master(dev);
+ /* Disable the RETRY_TIMEOUT register (0x41) to keep
+ * PCI Tx retries from interfering with C3 CPU state */
+ pci_read_config_dword(dev, 0x40, &val);
+ if ((val & 0x0000ff00) != 0)
+ pci_write_config_dword(dev, 0x40, val & 0xffff00ff);
+
err = ssb_bus_pcibus_register(ssb, dev);
if (err)
goto err_pci_release_regions;