aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS3
-rw-r--r--drivers/net/wireless/Kconfig1
-rw-r--r--drivers/net/wireless/Makefile1
-rw-r--r--drivers/net/wireless/at76c50x-usb.c3
-rw-r--r--drivers/net/wireless/ath/ath.h16
-rw-r--r--drivers/net/wireless/ath/ath5k/ani.c41
-rw-r--r--drivers/net/wireless/ath/ath5k/ani.h5
-rw-r--r--drivers/net/wireless/ath/ath5k/ath5k.h2
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c71
-rw-r--r--drivers/net/wireless/ath/ath5k/debug.c49
-rw-r--r--drivers/net/wireless/ath/ath5k/debug.h12
-rw-r--r--drivers/net/wireless/ath/ath5k/pcu.c13
-rw-r--r--drivers/net/wireless/ath/ath5k/phy.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.c101
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.h8
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_2p0_initvals.h1784
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_hw.c162
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c7
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h7
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c21
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c93
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.h21
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_init.c12
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_txrx.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c66
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h21
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c16
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c179
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.c184
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.h26
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c10
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h14
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c38
-rw-r--r--drivers/net/wireless/ath/carl9170/rx.c89
-rw-r--r--drivers/net/wireless/ath/carl9170/wlan.h14
-rw-r--r--drivers/net/wireless/ath/debug.c29
-rw-r--r--drivers/net/wireless/ath/debug.h10
-rw-r--r--drivers/net/wireless/ath/hw.c59
-rw-r--r--drivers/net/wireless/ath/reg.h11
-rw-r--r--drivers/net/wireless/b43/Makefile2
-rw-r--r--drivers/net/wireless/b43/phy_common.h5
-rw-r--r--drivers/net/wireless/b43/phy_n.c128
-rw-r--r--drivers/net/wireless/b43/phy_n.h218
-rw-r--r--drivers/net/wireless/b43/radio_2055.c1332
-rw-r--r--drivers/net/wireless/b43/radio_2055.h254
-rw-r--r--drivers/net/wireless/b43/radio_2056.c43
-rw-r--r--drivers/net/wireless/b43/radio_2056.h42
-rw-r--r--drivers/net/wireless/b43/tables_nphy.c1311
-rw-r--r--drivers/net/wireless/b43/tables_nphy.h59
-rw-r--r--drivers/net/wireless/iwlwifi/Makefile2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c76
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c27
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c62
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-calib.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-calib.h (renamed from drivers/net/wireless/iwlwifi/iwl-calib.h)4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c454
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c372
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c69
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.h10
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rx.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-sta.c716
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tt.c5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c40
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-ucode.c28
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c106
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.h71
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h13
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c531
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h49
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h16
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.c381
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.h8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-helpers.h5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c725
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.h35
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c38
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c97
-rw-r--r--drivers/net/wireless/libertas/if_usb.c4
-rw-r--r--drivers/net/wireless/p54/eeprom.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h18
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c85
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00lib.h11
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00link.c12
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c56
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c54
-rw-r--r--drivers/net/wireless/wl1251/Kconfig33
-rw-r--r--drivers/net/wireless/wl1251/Makefile6
-rw-r--r--drivers/net/wireless/wl1251/acx.c (renamed from drivers/net/wireless/wl12xx/wl1251_acx.c)8
-rw-r--r--drivers/net/wireless/wl1251/acx.h (renamed from drivers/net/wireless/wl12xx/wl1251_acx.h)2
-rw-r--r--drivers/net/wireless/wl1251/boot.c (renamed from drivers/net/wireless/wl12xx/wl1251_boot.c)12
-rw-r--r--drivers/net/wireless/wl1251/boot.h (renamed from drivers/net/wireless/wl12xx/wl1251_boot.h)0
-rw-r--r--drivers/net/wireless/wl1251/cmd.c (renamed from drivers/net/wireless/wl12xx/wl1251_cmd.c)10
-rw-r--r--drivers/net/wireless/wl1251/cmd.h (renamed from drivers/net/wireless/wl12xx/wl1251_cmd.h)0
-rw-r--r--drivers/net/wireless/wl1251/debugfs.c (renamed from drivers/net/wireless/wl12xx/wl1251_debugfs.c)6
-rw-r--r--drivers/net/wireless/wl1251/debugfs.h (renamed from drivers/net/wireless/wl12xx/wl1251_debugfs.h)0
-rw-r--r--drivers/net/wireless/wl1251/event.c (renamed from drivers/net/wireless/wl12xx/wl1251_event.c)8
-rw-r--r--drivers/net/wireless/wl1251/event.h (renamed from drivers/net/wireless/wl12xx/wl1251_event.h)0
-rw-r--r--drivers/net/wireless/wl1251/init.c (renamed from drivers/net/wireless/wl12xx/wl1251_init.c)8
-rw-r--r--drivers/net/wireless/wl1251/init.h (renamed from drivers/net/wireless/wl12xx/wl1251_init.h)0
-rw-r--r--drivers/net/wireless/wl1251/io.c (renamed from drivers/net/wireless/wl12xx/wl1251_io.c)4
-rw-r--r--drivers/net/wireless/wl1251/io.h (renamed from drivers/net/wireless/wl12xx/wl1251_io.h)0
-rw-r--r--drivers/net/wireless/wl1251/main.c (renamed from drivers/net/wireless/wl12xx/wl1251_main.c)20
-rw-r--r--drivers/net/wireless/wl1251/ps.c (renamed from drivers/net/wireless/wl12xx/wl1251_ps.c)8
-rw-r--r--drivers/net/wireless/wl1251/ps.h (renamed from drivers/net/wireless/wl12xx/wl1251_ps.h)2
-rw-r--r--drivers/net/wireless/wl1251/reg.h (renamed from drivers/net/wireless/wl12xx/wl1251_reg.h)0
-rw-r--r--drivers/net/wireless/wl1251/rx.c (renamed from drivers/net/wireless/wl12xx/wl1251_rx.c)10
-rw-r--r--drivers/net/wireless/wl1251/rx.h (renamed from drivers/net/wireless/wl12xx/wl1251_rx.h)0
-rw-r--r--drivers/net/wireless/wl1251/sdio.c (renamed from drivers/net/wireless/wl12xx/wl1251_sdio.c)0
-rw-r--r--drivers/net/wireless/wl1251/spi.c (renamed from drivers/net/wireless/wl12xx/wl1251_spi.c)4
-rw-r--r--drivers/net/wireless/wl1251/spi.h (renamed from drivers/net/wireless/wl12xx/wl1251_spi.h)6
-rw-r--r--drivers/net/wireless/wl1251/tx.c (renamed from drivers/net/wireless/wl12xx/wl1251_tx.c)8
-rw-r--r--drivers/net/wireless/wl1251/tx.h (renamed from drivers/net/wireless/wl12xx/wl1251_tx.h)2
-rw-r--r--drivers/net/wireless/wl1251/wl1251.h (renamed from drivers/net/wireless/wl12xx/wl1251.h)0
-rw-r--r--drivers/net/wireless/wl1251/wl12xx_80211.h156
-rw-r--r--drivers/net/wireless/wl12xx/Kconfig34
-rw-r--r--drivers/net/wireless/wl12xx/Makefile9
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_sdio.c43
-rw-r--r--include/linux/ieee80211.h71
-rw-r--r--include/linux/nl80211.h15
-rw-r--r--include/linux/wireless.h2
-rw-r--r--include/net/cfg80211.h31
-rw-r--r--include/net/mac80211.h9
-rw-r--r--net/mac80211/cfg.c22
-rw-r--r--net/mac80211/ht.c2
-rw-r--r--net/mac80211/ieee80211_i.h4
-rw-r--r--net/mac80211/iface.c9
-rw-r--r--net/mac80211/main.c3
-rw-r--r--net/mac80211/mesh_plink.c17
-rw-r--r--net/mac80211/mlme.c18
-rw-r--r--net/mac80211/rc80211_minstrel_ht.c7
-rw-r--r--net/mac80211/rx.c24
-rw-r--r--net/mac80211/wep.c8
-rw-r--r--net/wireless/core.c54
-rw-r--r--net/wireless/mlme.c23
-rw-r--r--net/wireless/nl80211.c15
-rw-r--r--net/wireless/radiotap.c58
-rw-r--r--net/wireless/sysfs.c9
-rw-r--r--net/wireless/wext-compat.c4
151 files changed, 5272 insertions, 6383 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index c539910b1f76..476fb3a123ca 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6461,8 +6461,7 @@ L: linux-wireless@vger.kernel.org
6461W: http://wireless.kernel.org 6461W: http://wireless.kernel.org
6462T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git 6462T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
6463S: Maintained 6463S: Maintained
6464F: drivers/net/wireless/wl12xx/* 6464F: drivers/net/wireless/wl1251/*
6465X: drivers/net/wireless/wl12xx/wl1271*
6466 6465
6467WL1271 WIRELESS DRIVER 6466WL1271 WIRELESS DRIVER
6468M: Luciano Coelho <luciano.coelho@nokia.com> 6467M: Luciano Coelho <luciano.coelho@nokia.com>
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 174e3442d519..4de4410cd38e 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -279,6 +279,7 @@ source "drivers/net/wireless/libertas/Kconfig"
279source "drivers/net/wireless/orinoco/Kconfig" 279source "drivers/net/wireless/orinoco/Kconfig"
280source "drivers/net/wireless/p54/Kconfig" 280source "drivers/net/wireless/p54/Kconfig"
281source "drivers/net/wireless/rt2x00/Kconfig" 281source "drivers/net/wireless/rt2x00/Kconfig"
282source "drivers/net/wireless/wl1251/Kconfig"
282source "drivers/net/wireless/wl12xx/Kconfig" 283source "drivers/net/wireless/wl12xx/Kconfig"
283source "drivers/net/wireless/zd1211rw/Kconfig" 284source "drivers/net/wireless/zd1211rw/Kconfig"
284 285
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index a13a602edb13..06f8ca26c5c1 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -49,6 +49,7 @@ obj-$(CONFIG_ATH_COMMON) += ath/
49 49
50obj-$(CONFIG_MAC80211_HWSIM) += mac80211_hwsim.o 50obj-$(CONFIG_MAC80211_HWSIM) += mac80211_hwsim.o
51 51
52obj-$(CONFIG_WL1251) += wl1251/
52obj-$(CONFIG_WL12XX) += wl12xx/ 53obj-$(CONFIG_WL12XX) += wl12xx/
53obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx/ 54obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx/
54 55
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c
index 91c5f73b5ba3..1476314afa8a 100644
--- a/drivers/net/wireless/at76c50x-usb.c
+++ b/drivers/net/wireless/at76c50x-usb.c
@@ -1525,8 +1525,7 @@ static void at76_rx_tasklet(unsigned long param)
1525 1525
1526 if (priv->device_unplugged) { 1526 if (priv->device_unplugged) {
1527 at76_dbg(DBG_DEVSTART, "device unplugged"); 1527 at76_dbg(DBG_DEVSTART, "device unplugged");
1528 if (urb) 1528 at76_dbg(DBG_DEVSTART, "urb status %d", urb->status);
1529 at76_dbg(DBG_DEVSTART, "urb status %d", urb->status);
1530 return; 1529 return;
1531 } 1530 }
1532 1531
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index cee0191704f5..501050c0296f 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -19,6 +19,7 @@
19 19
20#include <linux/skbuff.h> 20#include <linux/skbuff.h>
21#include <linux/if_ether.h> 21#include <linux/if_ether.h>
22#include <linux/spinlock.h>
22#include <net/mac80211.h> 23#include <net/mac80211.h>
23 24
24/* 25/*
@@ -42,6 +43,13 @@ struct ath_ani {
42 struct timer_list timer; 43 struct timer_list timer;
43}; 44};
44 45
46struct ath_cycle_counters {
47 u32 cycles;
48 u32 rx_busy;
49 u32 rx_frame;
50 u32 tx_frame;
51};
52
45enum ath_device_state { 53enum ath_device_state {
46 ATH_HW_UNAVAILABLE, 54 ATH_HW_UNAVAILABLE,
47 ATH_HW_INITIALIZED, 55 ATH_HW_INITIALIZED,
@@ -145,6 +153,12 @@ struct ath_common {
145 DECLARE_BITMAP(tkip_keymap, ATH_KEYMAX); 153 DECLARE_BITMAP(tkip_keymap, ATH_KEYMAX);
146 enum ath_crypt_caps crypt_caps; 154 enum ath_crypt_caps crypt_caps;
147 155
156 unsigned int clockrate;
157
158 spinlock_t cc_lock;
159 struct ath_cycle_counters cc_ani;
160 struct ath_cycle_counters cc_survey;
161
148 struct ath_regulatory regulatory; 162 struct ath_regulatory regulatory;
149 const struct ath_ops *ops; 163 const struct ath_ops *ops;
150 const struct ath_bus_ops *bus_ops; 164 const struct ath_bus_ops *bus_ops;
@@ -161,5 +175,7 @@ int ath_key_config(struct ath_common *common,
161 struct ieee80211_sta *sta, 175 struct ieee80211_sta *sta,
162 struct ieee80211_key_conf *key); 176 struct ieee80211_key_conf *key);
163bool ath_hw_keyreset(struct ath_common *common, u16 entry); 177bool ath_hw_keyreset(struct ath_common *common, u16 entry);
178void ath_hw_cycle_counters_update(struct ath_common *common);
179int32_t ath_hw_get_listen_time(struct ath_common *common);
164 180
165#endif /* ATH_H */ 181#endif /* ATH_H */
diff --git a/drivers/net/wireless/ath/ath5k/ani.c b/drivers/net/wireless/ath/ath5k/ani.c
index e4a5f046bba4..f1419198a479 100644
--- a/drivers/net/wireless/ath/ath5k/ani.c
+++ b/drivers/net/wireless/ath/ath5k/ani.c
@@ -355,41 +355,28 @@ ath5k_ani_lower_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as)
355 355
356 356
357/** 357/**
358 * ath5k_hw_ani_get_listen_time() - Calculate time spent listening 358 * ath5k_hw_ani_get_listen_time() - Update counters and return listening time
359 * 359 *
360 * Return an approximation of the time spent "listening" in milliseconds (ms) 360 * Return an approximation of the time spent "listening" in milliseconds (ms)
361 * since the last call of this function by deducting the cycles spent 361 * since the last call of this function.
362 * transmitting and receiving from the total cycle count. 362 * Save a snapshot of the counter values for debugging/statistics.
363 * Save profile count values for debugging/statistics and because we might want
364 * to use them later.
365 *
366 * We assume no one else clears these registers!
367 */ 363 */
368static int 364static int
369ath5k_hw_ani_get_listen_time(struct ath5k_hw *ah, struct ath5k_ani_state *as) 365ath5k_hw_ani_get_listen_time(struct ath5k_hw *ah, struct ath5k_ani_state *as)
370{ 366{
367 struct ath_common *common = ath5k_hw_common(ah);
371 int listen; 368 int listen;
372 369
373 /* freeze */ 370 spin_lock_bh(&common->cc_lock);
374 ath5k_hw_reg_write(ah, AR5K_MIBC_FMC, AR5K_MIBC); 371
375 /* read */ 372 ath_hw_cycle_counters_update(common);
376 as->pfc_cycles = ath5k_hw_reg_read(ah, AR5K_PROFCNT_CYCLE); 373 memcpy(&as->last_cc, &common->cc_ani, sizeof(as->last_cc));
377 as->pfc_busy = ath5k_hw_reg_read(ah, AR5K_PROFCNT_RXCLR); 374
378 as->pfc_tx = ath5k_hw_reg_read(ah, AR5K_PROFCNT_TX); 375 /* clears common->cc_ani */
379 as->pfc_rx = ath5k_hw_reg_read(ah, AR5K_PROFCNT_RX); 376 listen = ath_hw_get_listen_time(common);
380 /* clear */ 377
381 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_TX); 378 spin_unlock_bh(&common->cc_lock);
382 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RX); 379
383 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RXCLR);
384 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_CYCLE);
385 /* un-freeze */
386 ath5k_hw_reg_write(ah, 0, AR5K_MIBC);
387
388 /* TODO: where does 44000 come from? (11g clock rate?) */
389 listen = (as->pfc_cycles - as->pfc_rx - as->pfc_tx) / 44000;
390
391 if (as->pfc_cycles == 0 || listen < 0)
392 return 0;
393 return listen; 380 return listen;
394} 381}
395 382
diff --git a/drivers/net/wireless/ath/ath5k/ani.h b/drivers/net/wireless/ath/ath5k/ani.h
index 55cf26d8522c..d0a664039c87 100644
--- a/drivers/net/wireless/ath/ath5k/ani.h
+++ b/drivers/net/wireless/ath/ath5k/ani.h
@@ -75,10 +75,7 @@ struct ath5k_ani_state {
75 unsigned int cck_errors; 75 unsigned int cck_errors;
76 76
77 /* debug/statistics only: numbers from last ANI calibration */ 77 /* debug/statistics only: numbers from last ANI calibration */
78 unsigned int pfc_tx; 78 struct ath_cycle_counters last_cc;
79 unsigned int pfc_rx;
80 unsigned int pfc_busy;
81 unsigned int pfc_cycles;
82 unsigned int last_listen; 79 unsigned int last_listen;
83 unsigned int last_ofdm_errors; 80 unsigned int last_ofdm_errors;
84 unsigned int last_cck_errors; 81 unsigned int last_cck_errors;
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 0cba2e315d9a..4a367cdb3eb9 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -1201,7 +1201,7 @@ void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high);
1201/* Clock rate related functions */ 1201/* Clock rate related functions */
1202unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec); 1202unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec);
1203unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock); 1203unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock);
1204unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah); 1204void ath5k_hw_set_clockrate(struct ath5k_hw *ah);
1205 1205
1206/* Queue Control Unit, DFS Control Unit Functions */ 1206/* Queue Control Unit, DFS Control Unit Functions */
1207int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue, 1207int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue,
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index dad726585637..f1ae75d35d5d 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -62,6 +62,7 @@
62#include "reg.h" 62#include "reg.h"
63#include "debug.h" 63#include "debug.h"
64#include "ani.h" 64#include "ani.h"
65#include "../debug.h"
65 66
66static int modparam_nohwcrypt; 67static int modparam_nohwcrypt;
67module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); 68module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
@@ -517,12 +518,14 @@ struct ath_vif_iter_data {
517 bool need_set_hw_addr; 518 bool need_set_hw_addr;
518 bool found_active; 519 bool found_active;
519 bool any_assoc; 520 bool any_assoc;
521 enum nl80211_iftype opmode;
520}; 522};
521 523
522static void ath_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) 524static void ath_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
523{ 525{
524 struct ath_vif_iter_data *iter_data = data; 526 struct ath_vif_iter_data *iter_data = data;
525 int i; 527 int i;
528 struct ath5k_vif *avf = (void *)vif->drv_priv;
526 529
527 if (iter_data->hw_macaddr) 530 if (iter_data->hw_macaddr)
528 for (i = 0; i < ETH_ALEN; i++) 531 for (i = 0; i < ETH_ALEN; i++)
@@ -539,13 +542,32 @@ static void ath_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
539 iter_data->need_set_hw_addr = false; 542 iter_data->need_set_hw_addr = false;
540 543
541 if (!iter_data->any_assoc) { 544 if (!iter_data->any_assoc) {
542 struct ath5k_vif *avf = (void *)vif->drv_priv;
543 if (avf->assoc) 545 if (avf->assoc)
544 iter_data->any_assoc = true; 546 iter_data->any_assoc = true;
545 } 547 }
548
549 /* Calculate combined mode - when APs are active, operate in AP mode.
550 * Otherwise use the mode of the new interface. This can currently
551 * only deal with combinations of APs and STAs. Only one ad-hoc
552 * interfaces is allowed above.
553 */
554 if (avf->opmode == NL80211_IFTYPE_AP)
555 iter_data->opmode = NL80211_IFTYPE_AP;
556 else
557 if (iter_data->opmode == NL80211_IFTYPE_UNSPECIFIED)
558 iter_data->opmode = avf->opmode;
546} 559}
547 560
548void ath5k_update_bssid_mask(struct ath5k_softc *sc, struct ieee80211_vif *vif) 561static void ath_do_set_opmode(struct ath5k_softc *sc)
562{
563 struct ath5k_hw *ah = sc->ah;
564 ath5k_hw_set_opmode(ah, sc->opmode);
565 ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "mode setup opmode %d (%s)\n",
566 sc->opmode, ath_opmode_to_string(sc->opmode));
567}
568
569void ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc,
570 struct ieee80211_vif *vif)
549{ 571{
550 struct ath_common *common = ath5k_hw_common(sc->ah); 572 struct ath_common *common = ath5k_hw_common(sc->ah);
551 struct ath_vif_iter_data iter_data; 573 struct ath_vif_iter_data iter_data;
@@ -558,6 +580,7 @@ void ath5k_update_bssid_mask(struct ath5k_softc *sc, struct ieee80211_vif *vif)
558 memset(&iter_data.mask, 0xff, ETH_ALEN); 580 memset(&iter_data.mask, 0xff, ETH_ALEN);
559 iter_data.found_active = false; 581 iter_data.found_active = false;
560 iter_data.need_set_hw_addr = true; 582 iter_data.need_set_hw_addr = true;
583 iter_data.opmode = NL80211_IFTYPE_UNSPECIFIED;
561 584
562 if (vif) 585 if (vif)
563 ath_vif_iter(&iter_data, vif->addr, vif); 586 ath_vif_iter(&iter_data, vif->addr, vif);
@@ -567,10 +590,18 @@ void ath5k_update_bssid_mask(struct ath5k_softc *sc, struct ieee80211_vif *vif)
567 &iter_data); 590 &iter_data);
568 memcpy(sc->bssidmask, iter_data.mask, ETH_ALEN); 591 memcpy(sc->bssidmask, iter_data.mask, ETH_ALEN);
569 592
593 sc->opmode = iter_data.opmode;
594 if (sc->opmode == NL80211_IFTYPE_UNSPECIFIED)
595 /* Nothing active, default to station mode */
596 sc->opmode = NL80211_IFTYPE_STATION;
597
598 ath_do_set_opmode(sc);
599
570 if (iter_data.need_set_hw_addr && iter_data.found_active) 600 if (iter_data.need_set_hw_addr && iter_data.found_active)
571 ath5k_hw_set_lladdr(sc->ah, iter_data.active_mac); 601 ath5k_hw_set_lladdr(sc->ah, iter_data.active_mac);
572 602
573 ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask); 603 if (ath5k_hw_hasbssidmask(sc->ah))
604 ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask);
574} 605}
575 606
576static void 607static void
@@ -582,15 +613,9 @@ ath5k_mode_setup(struct ath5k_softc *sc, struct ieee80211_vif *vif)
582 /* configure rx filter */ 613 /* configure rx filter */
583 rfilt = sc->filter_flags; 614 rfilt = sc->filter_flags;
584 ath5k_hw_set_rx_filter(ah, rfilt); 615 ath5k_hw_set_rx_filter(ah, rfilt);
585
586 if (ath5k_hw_hasbssidmask(ah))
587 ath5k_update_bssid_mask(sc, vif);
588
589 /* configure operational mode */
590 ath5k_hw_set_opmode(ah, sc->opmode);
591
592 ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "mode setup opmode %d\n", sc->opmode);
593 ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt); 616 ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt);
617
618 ath5k_update_bssid_mask_and_opmode(sc, vif);
594} 619}
595 620
596static inline int 621static inline int
@@ -2688,7 +2713,7 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
2688 SET_IEEE80211_PERM_ADDR(hw, mac); 2713 SET_IEEE80211_PERM_ADDR(hw, mac);
2689 memcpy(&sc->lladdr, mac, ETH_ALEN); 2714 memcpy(&sc->lladdr, mac, ETH_ALEN);
2690 /* All MAC address bits matter for ACKs */ 2715 /* All MAC address bits matter for ACKs */
2691 ath5k_update_bssid_mask(sc, NULL); 2716 ath5k_update_bssid_mask_and_opmode(sc, NULL);
2692 2717
2693 regulatory->current_rd = ah->ah_capabilities.cap_eeprom.ee_regdomain; 2718 regulatory->current_rd = ah->ah_capabilities.cap_eeprom.ee_regdomain;
2694 ret = ath_regd_init(regulatory, hw->wiphy, ath5k_reg_notifier); 2719 ret = ath_regd_init(regulatory, hw->wiphy, ath5k_reg_notifier);
@@ -2786,7 +2811,6 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
2786{ 2811{
2787 struct ath5k_softc *sc = hw->priv; 2812 struct ath5k_softc *sc = hw->priv;
2788 int ret; 2813 int ret;
2789 struct ath5k_hw *ah = sc->ah;
2790 struct ath5k_vif *avf = (void *)vif->drv_priv; 2814 struct ath5k_vif *avf = (void *)vif->drv_priv;
2791 2815
2792 mutex_lock(&sc->lock); 2816 mutex_lock(&sc->lock);
@@ -2850,18 +2874,6 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
2850 sc->num_adhoc_vifs++; 2874 sc->num_adhoc_vifs++;
2851 } 2875 }
2852 2876
2853 /* Set combined mode - when APs are configured, operate in AP mode.
2854 * Otherwise use the mode of the new interface. This can currently
2855 * only deal with combinations of APs and STAs. Only one ad-hoc
2856 * interfaces is allowed above.
2857 */
2858 if (sc->num_ap_vifs)
2859 sc->opmode = NL80211_IFTYPE_AP;
2860 else
2861 sc->opmode = vif->type;
2862
2863 ath5k_hw_set_opmode(ah, sc->opmode);
2864
2865 /* Any MAC address is fine, all others are included through the 2877 /* Any MAC address is fine, all others are included through the
2866 * filter. 2878 * filter.
2867 */ 2879 */
@@ -2905,7 +2917,7 @@ ath5k_remove_interface(struct ieee80211_hw *hw,
2905 else if (avf->opmode == NL80211_IFTYPE_ADHOC) 2917 else if (avf->opmode == NL80211_IFTYPE_ADHOC)
2906 sc->num_adhoc_vifs--; 2918 sc->num_adhoc_vifs--;
2907 2919
2908 ath5k_update_bssid_mask(sc, NULL); 2920 ath5k_update_bssid_mask_and_opmode(sc, NULL);
2909 mutex_unlock(&sc->lock); 2921 mutex_unlock(&sc->lock);
2910} 2922}
2911 2923
@@ -3529,8 +3541,6 @@ ath5k_pci_probe(struct pci_dev *pdev,
3529 sc->hw = hw; 3541 sc->hw = hw;
3530 sc->pdev = pdev; 3542 sc->pdev = pdev;
3531 3543
3532 ath5k_debug_init_device(sc);
3533
3534 /* 3544 /*
3535 * Mark the device as detached to avoid processing 3545 * Mark the device as detached to avoid processing
3536 * interrupts until setup is complete. 3546 * interrupts until setup is complete.
@@ -3638,6 +3648,7 @@ ath5k_pci_probe(struct pci_dev *pdev,
3638 } 3648 }
3639 } 3649 }
3640 3650
3651 ath5k_debug_init_device(sc);
3641 3652
3642 /* ready to process interrupts */ 3653 /* ready to process interrupts */
3643 __clear_bit(ATH_STAT_INVALID, sc->status); 3654 __clear_bit(ATH_STAT_INVALID, sc->status);
@@ -3724,8 +3735,6 @@ init_ath5k_pci(void)
3724{ 3735{
3725 int ret; 3736 int ret;
3726 3737
3727 ath5k_debug_init();
3728
3729 ret = pci_register_driver(&ath5k_pci_driver); 3738 ret = pci_register_driver(&ath5k_pci_driver);
3730 if (ret) { 3739 if (ret) {
3731 printk(KERN_ERR "ath5k_pci: can't register pci driver\n"); 3740 printk(KERN_ERR "ath5k_pci: can't register pci driver\n");
@@ -3739,8 +3748,6 @@ static void __exit
3739exit_ath5k_pci(void) 3748exit_ath5k_pci(void)
3740{ 3749{
3741 pci_unregister_driver(&ath5k_pci_driver); 3750 pci_unregister_driver(&ath5k_pci_driver);
3742
3743 ath5k_debug_finish();
3744} 3751}
3745 3752
3746module_init(init_ath5k_pci); 3753module_init(init_ath5k_pci);
diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c
index c2d549f871f9..42ea5b1bdb12 100644
--- a/drivers/net/wireless/ath/ath5k/debug.c
+++ b/drivers/net/wireless/ath/ath5k/debug.c
@@ -60,6 +60,7 @@
60 60
61#include "base.h" 61#include "base.h"
62#include "debug.h" 62#include "debug.h"
63#include "../debug.h"
63 64
64static unsigned int ath5k_debug; 65static unsigned int ath5k_debug;
65module_param_named(debug, ath5k_debug, uint, 0); 66module_param_named(debug, ath5k_debug, uint, 0);
@@ -71,8 +72,6 @@ module_param_named(debug, ath5k_debug, uint, 0);
71#include "reg.h" 72#include "reg.h"
72#include "ani.h" 73#include "ani.h"
73 74
74static struct dentry *ath5k_global_debugfs;
75
76static int ath5k_debugfs_open(struct inode *inode, struct file *file) 75static int ath5k_debugfs_open(struct inode *inode, struct file *file)
77{ 76{
78 file->private_data = inode->i_private; 77 file->private_data = inode->i_private;
@@ -520,9 +519,10 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf,
520 if (filt & AR5K_RX_FILTER_PHYERR_5211) 519 if (filt & AR5K_RX_FILTER_PHYERR_5211)
521 snprintf(buf+len, sizeof(buf)-len, " PHYERR-5211"); 520 snprintf(buf+len, sizeof(buf)-len, " PHYERR-5211");
522 if (filt & AR5K_RX_FILTER_RADARERR_5211) 521 if (filt & AR5K_RX_FILTER_RADARERR_5211)
523 len += snprintf(buf+len, sizeof(buf)-len, " RADARERR-5211\n"); 522 len += snprintf(buf+len, sizeof(buf)-len, " RADARERR-5211");
524 else 523
525 len += snprintf(buf+len, sizeof(buf)-len, "\n"); 524 len += snprintf(buf+len, sizeof(buf)-len, "\nopmode: %s (%d)\n",
525 ath_opmode_to_string(sc->opmode), sc->opmode);
526 526
527 if (len > sizeof(buf)) 527 if (len > sizeof(buf))
528 len = sizeof(buf); 528 len = sizeof(buf);
@@ -715,20 +715,21 @@ static ssize_t read_file_ani(struct file *file, char __user *user_buf,
715 len += snprintf(buf+len, sizeof(buf)-len, 715 len += snprintf(buf+len, sizeof(buf)-len,
716 "beacon RSSI average:\t%d\n", 716 "beacon RSSI average:\t%d\n",
717 sc->ah->ah_beacon_rssi_avg.avg); 717 sc->ah->ah_beacon_rssi_avg.avg);
718
719#define CC_PRINT(_struct, _field) \
720 _struct._field, \
721 _struct.cycles > 0 ? \
722 _struct._field*100/_struct.cycles : 0
723
718 len += snprintf(buf+len, sizeof(buf)-len, "profcnt tx\t\t%u\t(%d%%)\n", 724 len += snprintf(buf+len, sizeof(buf)-len, "profcnt tx\t\t%u\t(%d%%)\n",
719 as->pfc_tx, 725 CC_PRINT(as->last_cc, tx_frame));
720 as->pfc_cycles > 0 ?
721 as->pfc_tx*100/as->pfc_cycles : 0);
722 len += snprintf(buf+len, sizeof(buf)-len, "profcnt rx\t\t%u\t(%d%%)\n", 726 len += snprintf(buf+len, sizeof(buf)-len, "profcnt rx\t\t%u\t(%d%%)\n",
723 as->pfc_rx, 727 CC_PRINT(as->last_cc, rx_frame));
724 as->pfc_cycles > 0 ?
725 as->pfc_rx*100/as->pfc_cycles : 0);
726 len += snprintf(buf+len, sizeof(buf)-len, "profcnt busy\t\t%u\t(%d%%)\n", 728 len += snprintf(buf+len, sizeof(buf)-len, "profcnt busy\t\t%u\t(%d%%)\n",
727 as->pfc_busy, 729 CC_PRINT(as->last_cc, rx_busy));
728 as->pfc_cycles > 0 ? 730#undef CC_PRINT
729 as->pfc_busy*100/as->pfc_cycles : 0);
730 len += snprintf(buf+len, sizeof(buf)-len, "profcnt cycles\t\t%u\n", 731 len += snprintf(buf+len, sizeof(buf)-len, "profcnt cycles\t\t%u\n",
731 as->pfc_cycles); 732 as->last_cc.cycles);
732 len += snprintf(buf+len, sizeof(buf)-len, 733 len += snprintf(buf+len, sizeof(buf)-len,
733 "listen time\t\t%d\tlast: %d\n", 734 "listen time\t\t%d\tlast: %d\n",
734 as->listen_time, as->last_listen); 735 as->listen_time, as->last_listen);
@@ -879,21 +880,13 @@ static const struct file_operations fops_queue = {
879}; 880};
880 881
881 882
882/* init */
883
884void
885ath5k_debug_init(void)
886{
887 ath5k_global_debugfs = debugfs_create_dir("ath5k", NULL);
888}
889
890void 883void
891ath5k_debug_init_device(struct ath5k_softc *sc) 884ath5k_debug_init_device(struct ath5k_softc *sc)
892{ 885{
893 sc->debug.level = ath5k_debug; 886 sc->debug.level = ath5k_debug;
894 887
895 sc->debug.debugfs_phydir = debugfs_create_dir(wiphy_name(sc->hw->wiphy), 888 sc->debug.debugfs_phydir = debugfs_create_dir("ath5k",
896 ath5k_global_debugfs); 889 sc->hw->wiphy->debugfsdir);
897 890
898 sc->debug.debugfs_debug = debugfs_create_file("debug", 891 sc->debug.debugfs_debug = debugfs_create_file("debug",
899 S_IWUSR | S_IRUSR, 892 S_IWUSR | S_IRUSR,
@@ -934,12 +927,6 @@ ath5k_debug_init_device(struct ath5k_softc *sc)
934} 927}
935 928
936void 929void
937ath5k_debug_finish(void)
938{
939 debugfs_remove(ath5k_global_debugfs);
940}
941
942void
943ath5k_debug_finish_device(struct ath5k_softc *sc) 930ath5k_debug_finish_device(struct ath5k_softc *sc)
944{ 931{
945 debugfs_remove(sc->debug.debugfs_debug); 932 debugfs_remove(sc->debug.debugfs_debug);
diff --git a/drivers/net/wireless/ath/ath5k/debug.h b/drivers/net/wireless/ath/ath5k/debug.h
index 4f078b134015..236edbd2507d 100644
--- a/drivers/net/wireless/ath/ath5k/debug.h
+++ b/drivers/net/wireless/ath/ath5k/debug.h
@@ -138,15 +138,9 @@ enum ath5k_debug_level {
138 } while (0) 138 } while (0)
139 139
140void 140void
141ath5k_debug_init(void);
142
143void
144ath5k_debug_init_device(struct ath5k_softc *sc); 141ath5k_debug_init_device(struct ath5k_softc *sc);
145 142
146void 143void
147ath5k_debug_finish(void);
148
149void
150ath5k_debug_finish_device(struct ath5k_softc *sc); 144ath5k_debug_finish_device(struct ath5k_softc *sc);
151 145
152void 146void
@@ -174,15 +168,9 @@ ATH5K_DBG_UNLIMIT(struct ath5k_softc *sc, unsigned int m, const char *fmt, ...)
174{} 168{}
175 169
176static inline void 170static inline void
177ath5k_debug_init(void) {}
178
179static inline void
180ath5k_debug_init_device(struct ath5k_softc *sc) {} 171ath5k_debug_init_device(struct ath5k_softc *sc) {}
181 172
182static inline void 173static inline void
183ath5k_debug_finish(void) {}
184
185static inline void
186ath5k_debug_finish_device(struct ath5k_softc *sc) {} 174ath5k_debug_finish_device(struct ath5k_softc *sc) {}
187 175
188static inline void 176static inline void
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c
index 095d30b50ec7..074b4c644399 100644
--- a/drivers/net/wireless/ath/ath5k/pcu.c
+++ b/drivers/net/wireless/ath/ath5k/pcu.c
@@ -207,7 +207,8 @@ static int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout)
207 */ 207 */
208unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec) 208unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec)
209{ 209{
210 return usec * ath5k_hw_get_clockrate(ah); 210 struct ath_common *common = ath5k_hw_common(ah);
211 return usec * common->clockrate;
211} 212}
212 213
213/** 214/**
@@ -216,17 +217,19 @@ unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec)
216 */ 217 */
217unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock) 218unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock)
218{ 219{
219 return clock / ath5k_hw_get_clockrate(ah); 220 struct ath_common *common = ath5k_hw_common(ah);
221 return clock / common->clockrate;
220} 222}
221 223
222/** 224/**
223 * ath5k_hw_get_clockrate - Get the clock rate for current mode 225 * ath5k_hw_set_clockrate - Set common->clockrate for the current channel
224 * 226 *
225 * @ah: The &struct ath5k_hw 227 * @ah: The &struct ath5k_hw
226 */ 228 */
227unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah) 229void ath5k_hw_set_clockrate(struct ath5k_hw *ah)
228{ 230{
229 struct ieee80211_channel *channel = ah->ah_current_channel; 231 struct ieee80211_channel *channel = ah->ah_current_channel;
232 struct ath_common *common = ath5k_hw_common(ah);
230 int clock; 233 int clock;
231 234
232 if (channel->hw_value & CHANNEL_5GHZ) 235 if (channel->hw_value & CHANNEL_5GHZ)
@@ -240,7 +243,7 @@ unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah)
240 if (channel->hw_value & CHANNEL_TURBO) 243 if (channel->hw_value & CHANNEL_TURBO)
241 clock *= 2; 244 clock *= 2;
242 245
243 return clock; 246 common->clockrate = clock;
244} 247}
245 248
246/** 249/**
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
index 61da913e7c8f..219367884e64 100644
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -1093,6 +1093,7 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel)
1093 1093
1094 ah->ah_current_channel = channel; 1094 ah->ah_current_channel = channel;
1095 ah->ah_turbo = channel->hw_value == CHANNEL_T ? true : false; 1095 ah->ah_turbo = channel->hw_value == CHANNEL_T ? true : false;
1096 ath5k_hw_set_clockrate(ah);
1096 1097
1097 return 0; 1098 return 0;
1098} 1099}
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index f2a907b4acb8..63ccb39cdcd4 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -465,40 +465,6 @@ static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah)
465 ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel - 1); 465 ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel - 1);
466} 466}
467 467
468static u8 ath9k_hw_chan_2_clockrate_mhz(struct ath_hw *ah)
469{
470 struct ath9k_channel *chan = ah->curchan;
471 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
472 u8 clockrate; /* in MHz */
473
474 if (!ah->curchan) /* should really check for CCK instead */
475 clockrate = ATH9K_CLOCK_RATE_CCK;
476 else if (conf->channel->band == IEEE80211_BAND_2GHZ)
477 clockrate = ATH9K_CLOCK_RATE_2GHZ_OFDM;
478 else if (IS_CHAN_A_FAST_CLOCK(ah, chan))
479 clockrate = ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM;
480 else
481 clockrate = ATH9K_CLOCK_RATE_5GHZ_OFDM;
482
483 if (conf_is_ht40(conf))
484 return clockrate * 2;
485
486 return clockrate;
487}
488
489static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah)
490{
491 int32_t listen_time;
492 int32_t clock_rate;
493
494 ath9k_hw_update_cycle_counters(ah);
495 clock_rate = ath9k_hw_chan_2_clockrate_mhz(ah) * 1000;
496 listen_time = ah->listen_time / clock_rate;
497 ah->listen_time = 0;
498
499 return listen_time;
500}
501
502static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning) 468static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
503{ 469{
504 struct ar5416AniState *aniState; 470 struct ar5416AniState *aniState;
@@ -667,7 +633,7 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning)
667 REGWRITE_BUFFER_FLUSH(ah); 633 REGWRITE_BUFFER_FLUSH(ah);
668} 634}
669 635
670static void ath9k_hw_ani_read_counters(struct ath_hw *ah) 636static bool ath9k_hw_ani_read_counters(struct ath_hw *ah)
671{ 637{
672 struct ath_common *common = ath9k_hw_common(ah); 638 struct ath_common *common = ath9k_hw_common(ah);
673 struct ar5416AniState *aniState = &ah->curchan->ani; 639 struct ar5416AniState *aniState = &ah->curchan->ani;
@@ -677,11 +643,13 @@ static void ath9k_hw_ani_read_counters(struct ath_hw *ah)
677 u32 phyCnt1, phyCnt2; 643 u32 phyCnt1, phyCnt2;
678 int32_t listenTime; 644 int32_t listenTime;
679 645
680 listenTime = ath9k_hw_ani_get_listen_time(ah); 646 ath_hw_cycle_counters_update(common);
681 if (listenTime < 0) { 647 listenTime = ath_hw_get_listen_time(common);
648
649 if (listenTime <= 0) {
682 ah->stats.ast_ani_lneg++; 650 ah->stats.ast_ani_lneg++;
683 ath9k_ani_restart(ah); 651 ath9k_ani_restart(ah);
684 return; 652 return false;
685 } 653 }
686 654
687 if (!use_new_ani(ah)) { 655 if (!use_new_ani(ah)) {
@@ -696,7 +664,7 @@ static void ath9k_hw_ani_read_counters(struct ath_hw *ah)
696 phyCnt1 = REG_READ(ah, AR_PHY_ERR_1); 664 phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
697 phyCnt2 = REG_READ(ah, AR_PHY_ERR_2); 665 phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
698 666
699 if (use_new_ani(ah) && (phyCnt1 < ofdm_base || phyCnt2 < cck_base)) { 667 if (!use_new_ani(ah) && (phyCnt1 < ofdm_base || phyCnt2 < cck_base)) {
700 if (phyCnt1 < ofdm_base) { 668 if (phyCnt1 < ofdm_base) {
701 ath_print(common, ATH_DBG_ANI, 669 ath_print(common, ATH_DBG_ANI,
702 "phyCnt1 0x%x, resetting " 670 "phyCnt1 0x%x, resetting "
@@ -715,7 +683,7 @@ static void ath9k_hw_ani_read_counters(struct ath_hw *ah)
715 REG_WRITE(ah, AR_PHY_ERR_MASK_2, 683 REG_WRITE(ah, AR_PHY_ERR_MASK_2,
716 AR_PHY_ERR_CCK_TIMING); 684 AR_PHY_ERR_CCK_TIMING);
717 } 685 }
718 return; 686 return false;
719 } 687 }
720 688
721 ofdmPhyErrCnt = phyCnt1 - ofdm_base; 689 ofdmPhyErrCnt = phyCnt1 - ofdm_base;
@@ -727,7 +695,7 @@ static void ath9k_hw_ani_read_counters(struct ath_hw *ah)
727 ah->stats.ast_ani_cckerrs += 695 ah->stats.ast_ani_cckerrs +=
728 cckPhyErrCnt - aniState->cckPhyErrCount; 696 cckPhyErrCnt - aniState->cckPhyErrCount;
729 aniState->cckPhyErrCount = cckPhyErrCnt; 697 aniState->cckPhyErrCount = cckPhyErrCnt;
730 698 return true;
731} 699}
732 700
733void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan) 701void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan)
@@ -743,7 +711,8 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan)
743 if (WARN_ON(!aniState)) 711 if (WARN_ON(!aniState))
744 return; 712 return;
745 713
746 ath9k_hw_ani_read_counters(ah); 714 if (!ath9k_hw_ani_read_counters(ah))
715 return;
747 716
748 ofdmPhyErrRate = aniState->ofdmPhyErrCount * 1000 / 717 ofdmPhyErrRate = aniState->ofdmPhyErrCount * 1000 /
749 aniState->listenTime; 718 aniState->listenTime;
@@ -818,54 +787,6 @@ void ath9k_hw_disable_mib_counters(struct ath_hw *ah)
818} 787}
819EXPORT_SYMBOL(ath9k_hw_disable_mib_counters); 788EXPORT_SYMBOL(ath9k_hw_disable_mib_counters);
820 789
821void ath9k_hw_update_cycle_counters(struct ath_hw *ah)
822{
823 struct ath_cycle_counters cc;
824 bool clear;
825
826 memcpy(&cc, &ah->cc, sizeof(cc));
827
828 /* freeze counters */
829 REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC);
830
831 ah->cc.cycles = REG_READ(ah, AR_CCCNT);
832 if (ah->cc.cycles < cc.cycles) {
833 clear = true;
834 goto skip;
835 }
836
837 ah->cc.rx_clear = REG_READ(ah, AR_RCCNT);
838 ah->cc.rx_frame = REG_READ(ah, AR_RFCNT);
839 ah->cc.tx_frame = REG_READ(ah, AR_TFCNT);
840
841 /* prevent wraparound */
842 if (ah->cc.cycles & BIT(31))
843 clear = true;
844
845#define CC_DELTA(_field, _reg) ah->cc_delta._field += ah->cc._field - cc._field
846 CC_DELTA(cycles, AR_CCCNT);
847 CC_DELTA(rx_frame, AR_RFCNT);
848 CC_DELTA(rx_clear, AR_RCCNT);
849 CC_DELTA(tx_frame, AR_TFCNT);
850#undef CC_DELTA
851
852 ah->listen_time += (ah->cc.cycles - cc.cycles) -
853 ((ah->cc.rx_frame - cc.rx_frame) +
854 (ah->cc.tx_frame - cc.tx_frame));
855
856skip:
857 if (clear) {
858 REG_WRITE(ah, AR_CCCNT, 0);
859 REG_WRITE(ah, AR_RFCNT, 0);
860 REG_WRITE(ah, AR_RCCNT, 0);
861 REG_WRITE(ah, AR_TFCNT, 0);
862 memset(&ah->cc, 0, sizeof(ah->cc));
863 }
864
865 /* unfreeze counters */
866 REG_WRITE(ah, AR_MIBC, 0);
867}
868
869/* 790/*
870 * Process a MIB interrupt. We may potentially be invoked because 791 * Process a MIB interrupt. We may potentially be invoked because
871 * any of the MIB counters overflow/trigger so don't assume we're 792 * any of the MIB counters overflow/trigger so don't assume we're
diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h
index 98cfd8154c71..0cd6783de883 100644
--- a/drivers/net/wireless/ath/ath9k/ani.h
+++ b/drivers/net/wireless/ath/ath9k/ani.h
@@ -93,13 +93,6 @@ struct ath9k_mib_stats {
93 u32 beacons; 93 u32 beacons;
94}; 94};
95 95
96struct ath_cycle_counters {
97 u32 cycles;
98 u32 rx_frame;
99 u32 rx_clear;
100 u32 tx_frame;
101};
102
103/* INI default values for ANI registers */ 96/* INI default values for ANI registers */
104struct ath9k_ani_default { 97struct ath9k_ani_default {
105 u16 m1ThreshLow; 98 u16 m1ThreshLow;
@@ -164,7 +157,6 @@ struct ar5416Stats {
164 157
165void ath9k_enable_mib_counters(struct ath_hw *ah); 158void ath9k_enable_mib_counters(struct ath_hw *ah);
166void ath9k_hw_disable_mib_counters(struct ath_hw *ah); 159void ath9k_hw_disable_mib_counters(struct ath_hw *ah);
167void ath9k_hw_update_cycle_counters(struct ath_hw *ah);
168void ath9k_hw_ani_setup(struct ath_hw *ah); 160void ath9k_hw_ani_setup(struct ath_hw *ah);
169void ath9k_hw_ani_init(struct ath_hw *ah); 161void ath9k_hw_ani_init(struct ath_hw *ah);
170int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah, 162int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah,
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p0_initvals.h
deleted file mode 100644
index d3375fc4ce8b..000000000000
--- a/drivers/net/wireless/ath/ath9k/ar9003_2p0_initvals.h
+++ /dev/null
@@ -1,1784 +0,0 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef INITVALS_9003_2P0_H
18#define INITVALS_9003_2P0_H
19
20/* AR9003 2.0 */
21
22static const u32 ar9300_2p0_radio_postamble[][5] = {
23 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
24 {0x0001609c, 0x0dd08f29, 0x0dd08f29, 0x0b283f31, 0x0b283f31},
25 {0x000160ac, 0xa4653c00, 0xa4653c00, 0x24652800, 0x24652800},
26 {0x000160b0, 0x03284f3e, 0x03284f3e, 0x05d08f20, 0x05d08f20},
27 {0x0001610c, 0x08000000, 0x00000000, 0x00000000, 0x00000000},
28 {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
29 {0x0001650c, 0x08000000, 0x00000000, 0x00000000, 0x00000000},
30 {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
31 {0x0001690c, 0x08000000, 0x00000000, 0x00000000, 0x00000000},
32 {0x00016940, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
33};
34
35static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p0[][5] = {
36 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
37 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
38 {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
39 {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
40 {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
41 {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
42 {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
43 {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400},
44 {0x0000a518, 0x21020220, 0x21020220, 0x16000402, 0x16000402},
45 {0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404},
46 {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603},
47 {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02},
48 {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04},
49 {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20},
50 {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20},
51 {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22},
52 {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24},
53 {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640},
54 {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660},
55 {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861},
56 {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81},
57 {0x0000a54c, 0x5c04286b, 0x5c04286b, 0x47001a83, 0x47001a83},
58 {0x0000a550, 0x61042a6c, 0x61042a6c, 0x4a001c84, 0x4a001c84},
59 {0x0000a554, 0x66062a6c, 0x66062a6c, 0x4e001ce3, 0x4e001ce3},
60 {0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x52001ce5, 0x52001ce5},
61 {0x0000a55c, 0x7006308c, 0x7006308c, 0x56001ce9, 0x56001ce9},
62 {0x0000a560, 0x730a308a, 0x730a308a, 0x5a001ceb, 0x5a001ceb},
63 {0x0000a564, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
64 {0x0000a568, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
65 {0x0000a56c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
66 {0x0000a570, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
67 {0x0000a574, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
68 {0x0000a578, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
69 {0x0000a57c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
70 {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
71 {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
72 {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
73 {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
74 {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202},
75 {0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400},
76 {0x0000a598, 0x21820220, 0x21820220, 0x16800402, 0x16800402},
77 {0x0000a59c, 0x27820223, 0x27820223, 0x19800404, 0x19800404},
78 {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603},
79 {0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02},
80 {0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04},
81 {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20},
82 {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20},
83 {0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22},
84 {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24},
85 {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640},
86 {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660},
87 {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861},
88 {0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81},
89 {0x0000a5cc, 0x5c84286b, 0x5c84286b, 0x47801a83, 0x47801a83},
90 {0x0000a5d0, 0x61842a6c, 0x61842a6c, 0x4a801c84, 0x4a801c84},
91 {0x0000a5d4, 0x66862a6c, 0x66862a6c, 0x4e801ce3, 0x4e801ce3},
92 {0x0000a5d8, 0x6b862e6c, 0x6b862e6c, 0x52801ce5, 0x52801ce5},
93 {0x0000a5dc, 0x7086308c, 0x7086308c, 0x56801ce9, 0x56801ce9},
94 {0x0000a5e0, 0x738a308a, 0x738a308a, 0x5a801ceb, 0x5a801ceb},
95 {0x0000a5e4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
96 {0x0000a5e8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
97 {0x0000a5ec, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
98 {0x0000a5f0, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
99 {0x0000a5f4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
100 {0x0000a5f8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
101 {0x0000a5fc, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
102 {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
103 {0x00016048, 0x62480001, 0x62480001, 0x62480001, 0x62480001},
104 {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
105 {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
106 {0x00016448, 0x62480001, 0x62480001, 0x62480001, 0x62480001},
107 {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
108 {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
109 {0x00016848, 0x62480001, 0x62480001, 0x62480001, 0x62480001},
110 {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
111};
112
113static const u32 ar9300Modes_fast_clock_2p0[][3] = {
114 /* Addr 5G_HT20 5G_HT40 */
115 {0x00001030, 0x00000268, 0x000004d0},
116 {0x00001070, 0x0000018c, 0x00000318},
117 {0x000010b0, 0x00000fd0, 0x00001fa0},
118 {0x00008014, 0x044c044c, 0x08980898},
119 {0x0000801c, 0x148ec02b, 0x148ec057},
120 {0x00008318, 0x000044c0, 0x00008980},
121 {0x00009e00, 0x03721821, 0x03721821},
122 {0x0000a230, 0x0000000b, 0x00000016},
123 {0x0000a254, 0x00000898, 0x00001130},
124};
125
126static const u32 ar9300_2p0_radio_core[][2] = {
127 /* Addr allmodes */
128 {0x00016000, 0x36db6db6},
129 {0x00016004, 0x6db6db40},
130 {0x00016008, 0x73f00000},
131 {0x0001600c, 0x00000000},
132 {0x00016040, 0x7f80fff8},
133 {0x0001604c, 0x76d005b5},
134 {0x00016050, 0x556cf031},
135 {0x00016054, 0x13449440},
136 {0x00016058, 0x0c51c92c},
137 {0x0001605c, 0x3db7fffc},
138 {0x00016060, 0xfffffffc},
139 {0x00016064, 0x000f0278},
140 {0x0001606c, 0x6db60000},
141 {0x00016080, 0x00000000},
142 {0x00016084, 0x0e48048c},
143 {0x00016088, 0x54214514},
144 {0x0001608c, 0x119f481e},
145 {0x00016090, 0x24926490},
146 {0x00016098, 0xd2888888},
147 {0x000160a0, 0x0a108ffe},
148 {0x000160a4, 0x812fc370},
149 {0x000160a8, 0x423c8000},
150 {0x000160b4, 0x92480080},
151 {0x000160c0, 0x00adb6d0},
152 {0x000160c4, 0x6db6db60},
153 {0x000160c8, 0x6db6db6c},
154 {0x000160cc, 0x01e6c000},
155 {0x00016100, 0x3fffbe01},
156 {0x00016104, 0xfff80000},
157 {0x00016108, 0x00080010},
158 {0x00016144, 0x02084080},
159 {0x00016148, 0x00000000},
160 {0x00016280, 0x058a0001},
161 {0x00016284, 0x3d840208},
162 {0x00016288, 0x05a20408},
163 {0x0001628c, 0x00038c07},
164 {0x00016290, 0x40000004},
165 {0x00016294, 0x458aa14f},
166 {0x00016380, 0x00000000},
167 {0x00016384, 0x00000000},
168 {0x00016388, 0x00800700},
169 {0x0001638c, 0x00800700},
170 {0x00016390, 0x00800700},
171 {0x00016394, 0x00000000},
172 {0x00016398, 0x00000000},
173 {0x0001639c, 0x00000000},
174 {0x000163a0, 0x00000001},
175 {0x000163a4, 0x00000001},
176 {0x000163a8, 0x00000000},
177 {0x000163ac, 0x00000000},
178 {0x000163b0, 0x00000000},
179 {0x000163b4, 0x00000000},
180 {0x000163b8, 0x00000000},
181 {0x000163bc, 0x00000000},
182 {0x000163c0, 0x000000a0},
183 {0x000163c4, 0x000c0000},
184 {0x000163c8, 0x14021402},
185 {0x000163cc, 0x00001402},
186 {0x000163d0, 0x00000000},
187 {0x000163d4, 0x00000000},
188 {0x00016400, 0x36db6db6},
189 {0x00016404, 0x6db6db40},
190 {0x00016408, 0x73f00000},
191 {0x0001640c, 0x00000000},
192 {0x00016440, 0x7f80fff8},
193 {0x0001644c, 0x76d005b5},
194 {0x00016450, 0x556cf031},
195 {0x00016454, 0x13449440},
196 {0x00016458, 0x0c51c92c},
197 {0x0001645c, 0x3db7fffc},
198 {0x00016460, 0xfffffffc},
199 {0x00016464, 0x000f0278},
200 {0x0001646c, 0x6db60000},
201 {0x00016500, 0x3fffbe01},
202 {0x00016504, 0xfff80000},
203 {0x00016508, 0x00080010},
204 {0x00016544, 0x02084080},
205 {0x00016548, 0x00000000},
206 {0x00016780, 0x00000000},
207 {0x00016784, 0x00000000},
208 {0x00016788, 0x00800700},
209 {0x0001678c, 0x00800700},
210 {0x00016790, 0x00800700},
211 {0x00016794, 0x00000000},
212 {0x00016798, 0x00000000},
213 {0x0001679c, 0x00000000},
214 {0x000167a0, 0x00000001},
215 {0x000167a4, 0x00000001},
216 {0x000167a8, 0x00000000},
217 {0x000167ac, 0x00000000},
218 {0x000167b0, 0x00000000},
219 {0x000167b4, 0x00000000},
220 {0x000167b8, 0x00000000},
221 {0x000167bc, 0x00000000},
222 {0x000167c0, 0x000000a0},
223 {0x000167c4, 0x000c0000},
224 {0x000167c8, 0x14021402},
225 {0x000167cc, 0x00001402},
226 {0x000167d0, 0x00000000},
227 {0x000167d4, 0x00000000},
228 {0x00016800, 0x36db6db6},
229 {0x00016804, 0x6db6db40},
230 {0x00016808, 0x73f00000},
231 {0x0001680c, 0x00000000},
232 {0x00016840, 0x7f80fff8},
233 {0x0001684c, 0x76d005b5},
234 {0x00016850, 0x556cf031},
235 {0x00016854, 0x13449440},
236 {0x00016858, 0x0c51c92c},
237 {0x0001685c, 0x3db7fffc},
238 {0x00016860, 0xfffffffc},
239 {0x00016864, 0x000f0278},
240 {0x0001686c, 0x6db60000},
241 {0x00016900, 0x3fffbe01},
242 {0x00016904, 0xfff80000},
243 {0x00016908, 0x00080010},
244 {0x00016944, 0x02084080},
245 {0x00016948, 0x00000000},
246 {0x00016b80, 0x00000000},
247 {0x00016b84, 0x00000000},
248 {0x00016b88, 0x00800700},
249 {0x00016b8c, 0x00800700},
250 {0x00016b90, 0x00800700},
251 {0x00016b94, 0x00000000},
252 {0x00016b98, 0x00000000},
253 {0x00016b9c, 0x00000000},
254 {0x00016ba0, 0x00000001},
255 {0x00016ba4, 0x00000001},
256 {0x00016ba8, 0x00000000},
257 {0x00016bac, 0x00000000},
258 {0x00016bb0, 0x00000000},
259 {0x00016bb4, 0x00000000},
260 {0x00016bb8, 0x00000000},
261 {0x00016bbc, 0x00000000},
262 {0x00016bc0, 0x000000a0},
263 {0x00016bc4, 0x000c0000},
264 {0x00016bc8, 0x14021402},
265 {0x00016bcc, 0x00001402},
266 {0x00016bd0, 0x00000000},
267 {0x00016bd4, 0x00000000},
268};
269
270static const u32 ar9300Common_rx_gain_table_merlin_2p0[][2] = {
271 /* Addr allmodes */
272 {0x0000a000, 0x02000101},
273 {0x0000a004, 0x02000102},
274 {0x0000a008, 0x02000103},
275 {0x0000a00c, 0x02000104},
276 {0x0000a010, 0x02000200},
277 {0x0000a014, 0x02000201},
278 {0x0000a018, 0x02000202},
279 {0x0000a01c, 0x02000203},
280 {0x0000a020, 0x02000204},
281 {0x0000a024, 0x02000205},
282 {0x0000a028, 0x02000208},
283 {0x0000a02c, 0x02000302},
284 {0x0000a030, 0x02000303},
285 {0x0000a034, 0x02000304},
286 {0x0000a038, 0x02000400},
287 {0x0000a03c, 0x02010300},
288 {0x0000a040, 0x02010301},
289 {0x0000a044, 0x02010302},
290 {0x0000a048, 0x02000500},
291 {0x0000a04c, 0x02010400},
292 {0x0000a050, 0x02020300},
293 {0x0000a054, 0x02020301},
294 {0x0000a058, 0x02020302},
295 {0x0000a05c, 0x02020303},
296 {0x0000a060, 0x02020400},
297 {0x0000a064, 0x02030300},
298 {0x0000a068, 0x02030301},
299 {0x0000a06c, 0x02030302},
300 {0x0000a070, 0x02030303},
301 {0x0000a074, 0x02030400},
302 {0x0000a078, 0x02040300},
303 {0x0000a07c, 0x02040301},
304 {0x0000a080, 0x02040302},
305 {0x0000a084, 0x02040303},
306 {0x0000a088, 0x02030500},
307 {0x0000a08c, 0x02040400},
308 {0x0000a090, 0x02050203},
309 {0x0000a094, 0x02050204},
310 {0x0000a098, 0x02050205},
311 {0x0000a09c, 0x02040500},
312 {0x0000a0a0, 0x02050301},
313 {0x0000a0a4, 0x02050302},
314 {0x0000a0a8, 0x02050303},
315 {0x0000a0ac, 0x02050400},
316 {0x0000a0b0, 0x02050401},
317 {0x0000a0b4, 0x02050402},
318 {0x0000a0b8, 0x02050403},
319 {0x0000a0bc, 0x02050500},
320 {0x0000a0c0, 0x02050501},
321 {0x0000a0c4, 0x02050502},
322 {0x0000a0c8, 0x02050503},
323 {0x0000a0cc, 0x02050504},
324 {0x0000a0d0, 0x02050600},
325 {0x0000a0d4, 0x02050601},
326 {0x0000a0d8, 0x02050602},
327 {0x0000a0dc, 0x02050603},
328 {0x0000a0e0, 0x02050604},
329 {0x0000a0e4, 0x02050700},
330 {0x0000a0e8, 0x02050701},
331 {0x0000a0ec, 0x02050702},
332 {0x0000a0f0, 0x02050703},
333 {0x0000a0f4, 0x02050704},
334 {0x0000a0f8, 0x02050705},
335 {0x0000a0fc, 0x02050708},
336 {0x0000a100, 0x02050709},
337 {0x0000a104, 0x0205070a},
338 {0x0000a108, 0x0205070b},
339 {0x0000a10c, 0x0205070c},
340 {0x0000a110, 0x0205070d},
341 {0x0000a114, 0x02050710},
342 {0x0000a118, 0x02050711},
343 {0x0000a11c, 0x02050712},
344 {0x0000a120, 0x02050713},
345 {0x0000a124, 0x02050714},
346 {0x0000a128, 0x02050715},
347 {0x0000a12c, 0x02050730},
348 {0x0000a130, 0x02050731},
349 {0x0000a134, 0x02050732},
350 {0x0000a138, 0x02050733},
351 {0x0000a13c, 0x02050734},
352 {0x0000a140, 0x02050735},
353 {0x0000a144, 0x02050750},
354 {0x0000a148, 0x02050751},
355 {0x0000a14c, 0x02050752},
356 {0x0000a150, 0x02050753},
357 {0x0000a154, 0x02050754},
358 {0x0000a158, 0x02050755},
359 {0x0000a15c, 0x02050770},
360 {0x0000a160, 0x02050771},
361 {0x0000a164, 0x02050772},
362 {0x0000a168, 0x02050773},
363 {0x0000a16c, 0x02050774},
364 {0x0000a170, 0x02050775},
365 {0x0000a174, 0x00000776},
366 {0x0000a178, 0x00000776},
367 {0x0000a17c, 0x00000776},
368 {0x0000a180, 0x00000776},
369 {0x0000a184, 0x00000776},
370 {0x0000a188, 0x00000776},
371 {0x0000a18c, 0x00000776},
372 {0x0000a190, 0x00000776},
373 {0x0000a194, 0x00000776},
374 {0x0000a198, 0x00000776},
375 {0x0000a19c, 0x00000776},
376 {0x0000a1a0, 0x00000776},
377 {0x0000a1a4, 0x00000776},
378 {0x0000a1a8, 0x00000776},
379 {0x0000a1ac, 0x00000776},
380 {0x0000a1b0, 0x00000776},
381 {0x0000a1b4, 0x00000776},
382 {0x0000a1b8, 0x00000776},
383 {0x0000a1bc, 0x00000776},
384 {0x0000a1c0, 0x00000776},
385 {0x0000a1c4, 0x00000776},
386 {0x0000a1c8, 0x00000776},
387 {0x0000a1cc, 0x00000776},
388 {0x0000a1d0, 0x00000776},
389 {0x0000a1d4, 0x00000776},
390 {0x0000a1d8, 0x00000776},
391 {0x0000a1dc, 0x00000776},
392 {0x0000a1e0, 0x00000776},
393 {0x0000a1e4, 0x00000776},
394 {0x0000a1e8, 0x00000776},
395 {0x0000a1ec, 0x00000776},
396 {0x0000a1f0, 0x00000776},
397 {0x0000a1f4, 0x00000776},
398 {0x0000a1f8, 0x00000776},
399 {0x0000a1fc, 0x00000776},
400 {0x0000b000, 0x02000101},
401 {0x0000b004, 0x02000102},
402 {0x0000b008, 0x02000103},
403 {0x0000b00c, 0x02000104},
404 {0x0000b010, 0x02000200},
405 {0x0000b014, 0x02000201},
406 {0x0000b018, 0x02000202},
407 {0x0000b01c, 0x02000203},
408 {0x0000b020, 0x02000204},
409 {0x0000b024, 0x02000205},
410 {0x0000b028, 0x02000208},
411 {0x0000b02c, 0x02000302},
412 {0x0000b030, 0x02000303},
413 {0x0000b034, 0x02000304},
414 {0x0000b038, 0x02000400},
415 {0x0000b03c, 0x02010300},
416 {0x0000b040, 0x02010301},
417 {0x0000b044, 0x02010302},
418 {0x0000b048, 0x02000500},
419 {0x0000b04c, 0x02010400},
420 {0x0000b050, 0x02020300},
421 {0x0000b054, 0x02020301},
422 {0x0000b058, 0x02020302},
423 {0x0000b05c, 0x02020303},
424 {0x0000b060, 0x02020400},
425 {0x0000b064, 0x02030300},
426 {0x0000b068, 0x02030301},
427 {0x0000b06c, 0x02030302},
428 {0x0000b070, 0x02030303},
429 {0x0000b074, 0x02030400},
430 {0x0000b078, 0x02040300},
431 {0x0000b07c, 0x02040301},
432 {0x0000b080, 0x02040302},
433 {0x0000b084, 0x02040303},
434 {0x0000b088, 0x02030500},
435 {0x0000b08c, 0x02040400},
436 {0x0000b090, 0x02050203},
437 {0x0000b094, 0x02050204},
438 {0x0000b098, 0x02050205},
439 {0x0000b09c, 0x02040500},
440 {0x0000b0a0, 0x02050301},
441 {0x0000b0a4, 0x02050302},
442 {0x0000b0a8, 0x02050303},
443 {0x0000b0ac, 0x02050400},
444 {0x0000b0b0, 0x02050401},
445 {0x0000b0b4, 0x02050402},
446 {0x0000b0b8, 0x02050403},
447 {0x0000b0bc, 0x02050500},
448 {0x0000b0c0, 0x02050501},
449 {0x0000b0c4, 0x02050502},
450 {0x0000b0c8, 0x02050503},
451 {0x0000b0cc, 0x02050504},
452 {0x0000b0d0, 0x02050600},
453 {0x0000b0d4, 0x02050601},
454 {0x0000b0d8, 0x02050602},
455 {0x0000b0dc, 0x02050603},
456 {0x0000b0e0, 0x02050604},
457 {0x0000b0e4, 0x02050700},
458 {0x0000b0e8, 0x02050701},
459 {0x0000b0ec, 0x02050702},
460 {0x0000b0f0, 0x02050703},
461 {0x0000b0f4, 0x02050704},
462 {0x0000b0f8, 0x02050705},
463 {0x0000b0fc, 0x02050708},
464 {0x0000b100, 0x02050709},
465 {0x0000b104, 0x0205070a},
466 {0x0000b108, 0x0205070b},
467 {0x0000b10c, 0x0205070c},
468 {0x0000b110, 0x0205070d},
469 {0x0000b114, 0x02050710},
470 {0x0000b118, 0x02050711},
471 {0x0000b11c, 0x02050712},
472 {0x0000b120, 0x02050713},
473 {0x0000b124, 0x02050714},
474 {0x0000b128, 0x02050715},
475 {0x0000b12c, 0x02050730},
476 {0x0000b130, 0x02050731},
477 {0x0000b134, 0x02050732},
478 {0x0000b138, 0x02050733},
479 {0x0000b13c, 0x02050734},
480 {0x0000b140, 0x02050735},
481 {0x0000b144, 0x02050750},
482 {0x0000b148, 0x02050751},
483 {0x0000b14c, 0x02050752},
484 {0x0000b150, 0x02050753},
485 {0x0000b154, 0x02050754},
486 {0x0000b158, 0x02050755},
487 {0x0000b15c, 0x02050770},
488 {0x0000b160, 0x02050771},
489 {0x0000b164, 0x02050772},
490 {0x0000b168, 0x02050773},
491 {0x0000b16c, 0x02050774},
492 {0x0000b170, 0x02050775},
493 {0x0000b174, 0x00000776},
494 {0x0000b178, 0x00000776},
495 {0x0000b17c, 0x00000776},
496 {0x0000b180, 0x00000776},
497 {0x0000b184, 0x00000776},
498 {0x0000b188, 0x00000776},
499 {0x0000b18c, 0x00000776},
500 {0x0000b190, 0x00000776},
501 {0x0000b194, 0x00000776},
502 {0x0000b198, 0x00000776},
503 {0x0000b19c, 0x00000776},
504 {0x0000b1a0, 0x00000776},
505 {0x0000b1a4, 0x00000776},
506 {0x0000b1a8, 0x00000776},
507 {0x0000b1ac, 0x00000776},
508 {0x0000b1b0, 0x00000776},
509 {0x0000b1b4, 0x00000776},
510 {0x0000b1b8, 0x00000776},
511 {0x0000b1bc, 0x00000776},
512 {0x0000b1c0, 0x00000776},
513 {0x0000b1c4, 0x00000776},
514 {0x0000b1c8, 0x00000776},
515 {0x0000b1cc, 0x00000776},
516 {0x0000b1d0, 0x00000776},
517 {0x0000b1d4, 0x00000776},
518 {0x0000b1d8, 0x00000776},
519 {0x0000b1dc, 0x00000776},
520 {0x0000b1e0, 0x00000776},
521 {0x0000b1e4, 0x00000776},
522 {0x0000b1e8, 0x00000776},
523 {0x0000b1ec, 0x00000776},
524 {0x0000b1f0, 0x00000776},
525 {0x0000b1f4, 0x00000776},
526 {0x0000b1f8, 0x00000776},
527 {0x0000b1fc, 0x00000776},
528};
529
530static const u32 ar9300_2p0_mac_postamble[][5] = {
531 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
532 {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
533 {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c},
534 {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38},
535 {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00},
536 {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b},
537 {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810},
538 {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a},
539 {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440},
540};
541
542static const u32 ar9300_2p0_soc_postamble[][5] = {
543 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
544 {0x00007010, 0x00000023, 0x00000023, 0x00000023, 0x00000023},
545};
546
547static const u32 ar9200_merlin_2p0_radio_core[][2] = {
548 /* Addr allmodes */
549 {0x00007800, 0x00040000},
550 {0x00007804, 0xdb005012},
551 {0x00007808, 0x04924914},
552 {0x0000780c, 0x21084210},
553 {0x00007810, 0x6d801300},
554 {0x00007814, 0x0019beff},
555 {0x00007818, 0x07e41000},
556 {0x0000781c, 0x00392000},
557 {0x00007820, 0x92592480},
558 {0x00007824, 0x00040000},
559 {0x00007828, 0xdb005012},
560 {0x0000782c, 0x04924914},
561 {0x00007830, 0x21084210},
562 {0x00007834, 0x6d801300},
563 {0x00007838, 0x0019beff},
564 {0x0000783c, 0x07e40000},
565 {0x00007840, 0x00392000},
566 {0x00007844, 0x92592480},
567 {0x00007848, 0x00100000},
568 {0x0000784c, 0x773f0567},
569 {0x00007850, 0x54214514},
570 {0x00007854, 0x12035828},
571 {0x00007858, 0x92592692},
572 {0x0000785c, 0x00000000},
573 {0x00007860, 0x56400000},
574 {0x00007864, 0x0a8e370e},
575 {0x00007868, 0xc0102850},
576 {0x0000786c, 0x812d4000},
577 {0x00007870, 0x807ec400},
578 {0x00007874, 0x001b6db0},
579 {0x00007878, 0x00376b63},
580 {0x0000787c, 0x06db6db6},
581 {0x00007880, 0x006d8000},
582 {0x00007884, 0xffeffffe},
583 {0x00007888, 0xffeffffe},
584 {0x0000788c, 0x00010000},
585 {0x00007890, 0x02060aeb},
586 {0x00007894, 0x5a108000},
587};
588
589static const u32 ar9300_2p0_baseband_postamble[][5] = {
590 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
591 {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011},
592 {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e},
593 {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0},
594 {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881},
595 {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
596 {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c},
597 {0x00009c00, 0x00000044, 0x000000c4, 0x000000c4, 0x00000044},
598 {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0},
599 {0x00009e04, 0x00802020, 0x00802020, 0x00802020, 0x00802020},
600 {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2},
601 {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec84d2e},
602 {0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e},
603 {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
604 {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c},
605 {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce},
606 {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021},
607 {0x00009e44, 0x02321e27, 0x02321e27, 0x02291e27, 0x02291e27},
608 {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012},
609 {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000},
610 {0x0000a204, 0x000037c0, 0x000037c4, 0x000037c4, 0x000037c0},
611 {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004},
612 {0x0000a230, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b},
613 {0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018},
614 {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108},
615 {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898},
616 {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002},
617 {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e},
618 {0x0000a260, 0x0a021501, 0x0a021501, 0x3a021501, 0x3a021501},
619 {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e},
620 {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b},
621 {0x0000a284, 0x00000000, 0x00000000, 0x00000150, 0x00000150},
622 {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110},
623 {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222},
624 {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18},
625 {0x0000a2d0, 0x00071981, 0x00071981, 0x00071981, 0x00071982},
626 {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a},
627 {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
628 {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
629 {0x0000ae04, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
630 {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
631 {0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
632 {0x0000ae20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce},
633 {0x0000b284, 0x00000000, 0x00000000, 0x00000150, 0x00000150},
634 {0x0000b830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
635 {0x0000be04, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
636 {0x0000be18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
637 {0x0000be1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
638 {0x0000be20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce},
639 {0x0000c284, 0x00000000, 0x00000000, 0x00000150, 0x00000150},
640};
641
642static const u32 ar9300_2p0_baseband_core[][2] = {
643 /* Addr allmodes */
644 {0x00009800, 0xafe68e30},
645 {0x00009804, 0xfd14e000},
646 {0x00009808, 0x9c0a9f6b},
647 {0x0000980c, 0x04900000},
648 {0x00009814, 0x9280c00a},
649 {0x00009818, 0x00000000},
650 {0x0000981c, 0x00020028},
651 {0x00009834, 0x5f3ca3de},
652 {0x00009838, 0x0108ecff},
653 {0x0000983c, 0x14750600},
654 {0x00009880, 0x201fff00},
655 {0x00009884, 0x00001042},
656 {0x000098a4, 0x00200400},
657 {0x000098b0, 0x52440bbe},
658 {0x000098d0, 0x004b6a8e},
659 {0x000098d4, 0x00000820},
660 {0x000098dc, 0x00000000},
661 {0x000098f0, 0x00000000},
662 {0x000098f4, 0x00000000},
663 {0x00009c04, 0xff55ff55},
664 {0x00009c08, 0x0320ff55},
665 {0x00009c0c, 0x00000000},
666 {0x00009c10, 0x00000000},
667 {0x00009c14, 0x00046384},
668 {0x00009c18, 0x05b6b440},
669 {0x00009c1c, 0x00b6b440},
670 {0x00009d00, 0xc080a333},
671 {0x00009d04, 0x40206c10},
672 {0x00009d08, 0x009c4060},
673 {0x00009d0c, 0x9883800a},
674 {0x00009d10, 0x01834061},
675 {0x00009d14, 0x00c0040b},
676 {0x00009d18, 0x00000000},
677 {0x00009e08, 0x0038230c},
678 {0x00009e24, 0x990bb515},
679 {0x00009e28, 0x0c6f0000},
680 {0x00009e30, 0x06336f77},
681 {0x00009e34, 0x6af6532f},
682 {0x00009e38, 0x0cc80c00},
683 {0x00009e3c, 0xcf946222},
684 {0x00009e40, 0x0d261820},
685 {0x00009e4c, 0x00001004},
686 {0x00009e50, 0x00ff03f1},
687 {0x00009e54, 0x00000000},
688 {0x00009fc0, 0x803e4788},
689 {0x00009fc4, 0x0001efb5},
690 {0x00009fcc, 0x40000014},
691 {0x00009fd0, 0x01193b93},
692 {0x0000a20c, 0x00000000},
693 {0x0000a220, 0x00000000},
694 {0x0000a224, 0x00000000},
695 {0x0000a228, 0x10002310},
696 {0x0000a22c, 0x01036a1e},
697 {0x0000a234, 0x10000fff},
698 {0x0000a23c, 0x00000000},
699 {0x0000a244, 0x0c000000},
700 {0x0000a2a0, 0x00000001},
701 {0x0000a2c0, 0x00000001},
702 {0x0000a2c8, 0x00000000},
703 {0x0000a2cc, 0x18c43433},
704 {0x0000a2d4, 0x00000000},
705 {0x0000a2dc, 0x00000000},
706 {0x0000a2e0, 0x00000000},
707 {0x0000a2e4, 0x00000000},
708 {0x0000a2e8, 0x00000000},
709 {0x0000a2ec, 0x00000000},
710 {0x0000a2f0, 0x00000000},
711 {0x0000a2f4, 0x00000000},
712 {0x0000a2f8, 0x00000000},
713 {0x0000a344, 0x00000000},
714 {0x0000a34c, 0x00000000},
715 {0x0000a350, 0x0000a000},
716 {0x0000a364, 0x00000000},
717 {0x0000a370, 0x00000000},
718 {0x0000a390, 0x00000001},
719 {0x0000a394, 0x00000444},
720 {0x0000a398, 0x001f0e0f},
721 {0x0000a39c, 0x0075393f},
722 {0x0000a3a0, 0xb79f6427},
723 {0x0000a3a4, 0x00000000},
724 {0x0000a3a8, 0xaaaaaaaa},
725 {0x0000a3ac, 0x3c466478},
726 {0x0000a3c0, 0x20202020},
727 {0x0000a3c4, 0x22222220},
728 {0x0000a3c8, 0x20200020},
729 {0x0000a3cc, 0x20202020},
730 {0x0000a3d0, 0x20202020},
731 {0x0000a3d4, 0x20202020},
732 {0x0000a3d8, 0x20202020},
733 {0x0000a3dc, 0x20202020},
734 {0x0000a3e0, 0x20202020},
735 {0x0000a3e4, 0x20202020},
736 {0x0000a3e8, 0x20202020},
737 {0x0000a3ec, 0x20202020},
738 {0x0000a3f0, 0x00000000},
739 {0x0000a3f4, 0x00000246},
740 {0x0000a3f8, 0x0cdbd380},
741 {0x0000a3fc, 0x000f0f01},
742 {0x0000a400, 0x8fa91f01},
743 {0x0000a404, 0x00000000},
744 {0x0000a408, 0x0e79e5c6},
745 {0x0000a40c, 0x00820820},
746 {0x0000a414, 0x1ce739ce},
747 {0x0000a418, 0x2d001dce},
748 {0x0000a41c, 0x1ce739ce},
749 {0x0000a420, 0x000001ce},
750 {0x0000a424, 0x1ce739ce},
751 {0x0000a428, 0x000001ce},
752 {0x0000a42c, 0x1ce739ce},
753 {0x0000a430, 0x1ce739ce},
754 {0x0000a434, 0x00000000},
755 {0x0000a438, 0x00001801},
756 {0x0000a43c, 0x00000000},
757 {0x0000a440, 0x00000000},
758 {0x0000a444, 0x00000000},
759 {0x0000a448, 0x04000080},
760 {0x0000a44c, 0x00000001},
761 {0x0000a450, 0x00010000},
762 {0x0000a458, 0x00000000},
763 {0x0000a600, 0x00000000},
764 {0x0000a604, 0x00000000},
765 {0x0000a608, 0x00000000},
766 {0x0000a60c, 0x00000000},
767 {0x0000a610, 0x00000000},
768 {0x0000a614, 0x00000000},
769 {0x0000a618, 0x00000000},
770 {0x0000a61c, 0x00000000},
771 {0x0000a620, 0x00000000},
772 {0x0000a624, 0x00000000},
773 {0x0000a628, 0x00000000},
774 {0x0000a62c, 0x00000000},
775 {0x0000a630, 0x00000000},
776 {0x0000a634, 0x00000000},
777 {0x0000a638, 0x00000000},
778 {0x0000a63c, 0x00000000},
779 {0x0000a640, 0x00000000},
780 {0x0000a644, 0x3fad9d74},
781 {0x0000a648, 0x0048060a},
782 {0x0000a64c, 0x00000637},
783 {0x0000a670, 0x03020100},
784 {0x0000a674, 0x09080504},
785 {0x0000a678, 0x0d0c0b0a},
786 {0x0000a67c, 0x13121110},
787 {0x0000a680, 0x31301514},
788 {0x0000a684, 0x35343332},
789 {0x0000a688, 0x00000036},
790 {0x0000a690, 0x00000838},
791 {0x0000a7c0, 0x00000000},
792 {0x0000a7c4, 0xfffffffc},
793 {0x0000a7c8, 0x00000000},
794 {0x0000a7cc, 0x00000000},
795 {0x0000a7d0, 0x00000000},
796 {0x0000a7d4, 0x00000004},
797 {0x0000a7dc, 0x00000001},
798 {0x0000a8d0, 0x004b6a8e},
799 {0x0000a8d4, 0x00000820},
800 {0x0000a8dc, 0x00000000},
801 {0x0000a8f0, 0x00000000},
802 {0x0000a8f4, 0x00000000},
803 {0x0000b2d0, 0x00000080},
804 {0x0000b2d4, 0x00000000},
805 {0x0000b2dc, 0x00000000},
806 {0x0000b2e0, 0x00000000},
807 {0x0000b2e4, 0x00000000},
808 {0x0000b2e8, 0x00000000},
809 {0x0000b2ec, 0x00000000},
810 {0x0000b2f0, 0x00000000},
811 {0x0000b2f4, 0x00000000},
812 {0x0000b2f8, 0x00000000},
813 {0x0000b408, 0x0e79e5c0},
814 {0x0000b40c, 0x00820820},
815 {0x0000b420, 0x00000000},
816 {0x0000b8d0, 0x004b6a8e},
817 {0x0000b8d4, 0x00000820},
818 {0x0000b8dc, 0x00000000},
819 {0x0000b8f0, 0x00000000},
820 {0x0000b8f4, 0x00000000},
821 {0x0000c2d0, 0x00000080},
822 {0x0000c2d4, 0x00000000},
823 {0x0000c2dc, 0x00000000},
824 {0x0000c2e0, 0x00000000},
825 {0x0000c2e4, 0x00000000},
826 {0x0000c2e8, 0x00000000},
827 {0x0000c2ec, 0x00000000},
828 {0x0000c2f0, 0x00000000},
829 {0x0000c2f4, 0x00000000},
830 {0x0000c2f8, 0x00000000},
831 {0x0000c408, 0x0e79e5c0},
832 {0x0000c40c, 0x00820820},
833 {0x0000c420, 0x00000000},
834};
835
836static const u32 ar9300Modes_high_power_tx_gain_table_2p0[][5] = {
837 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
838 {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9},
839 {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
840 {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002},
841 {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004},
842 {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200},
843 {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202},
844 {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400},
845 {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402},
846 {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404},
847 {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603},
848 {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02},
849 {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04},
850 {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20},
851 {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20},
852 {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22},
853 {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24},
854 {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640},
855 {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660},
856 {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861},
857 {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81},
858 {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83},
859 {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84},
860 {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3},
861 {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5},
862 {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9},
863 {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb},
864 {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
865 {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
866 {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
867 {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
868 {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
869 {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
870 {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
871 {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000},
872 {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002},
873 {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004},
874 {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200},
875 {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202},
876 {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400},
877 {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402},
878 {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404},
879 {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603},
880 {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02},
881 {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04},
882 {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20},
883 {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20},
884 {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22},
885 {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24},
886 {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640},
887 {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660},
888 {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861},
889 {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81},
890 {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83},
891 {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84},
892 {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3},
893 {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5},
894 {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9},
895 {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb},
896 {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
897 {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
898 {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
899 {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
900 {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
901 {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
902 {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
903 {0x00016044, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6},
904 {0x00016048, 0xae480001, 0xae480001, 0xae480001, 0xae480001},
905 {0x00016068, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c},
906 {0x00016444, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6},
907 {0x00016448, 0xae480001, 0xae480001, 0xae480001, 0xae480001},
908 {0x00016468, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c},
909 {0x00016844, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6},
910 {0x00016848, 0xae480001, 0xae480001, 0xae480001, 0xae480001},
911 {0x00016868, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c},
912};
913
914static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p0[][5] = {
915 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
916 {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9},
917 {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
918 {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002},
919 {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004},
920 {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200},
921 {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202},
922 {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400},
923 {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402},
924 {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404},
925 {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603},
926 {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02},
927 {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04},
928 {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20},
929 {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20},
930 {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22},
931 {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24},
932 {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640},
933 {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660},
934 {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861},
935 {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81},
936 {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83},
937 {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84},
938 {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3},
939 {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5},
940 {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9},
941 {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb},
942 {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
943 {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
944 {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
945 {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
946 {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
947 {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
948 {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
949 {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000},
950 {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002},
951 {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004},
952 {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200},
953 {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202},
954 {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400},
955 {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402},
956 {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404},
957 {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603},
958 {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02},
959 {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04},
960 {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20},
961 {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20},
962 {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22},
963 {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24},
964 {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640},
965 {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660},
966 {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861},
967 {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81},
968 {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83},
969 {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84},
970 {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3},
971 {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5},
972 {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9},
973 {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb},
974 {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
975 {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
976 {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
977 {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
978 {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
979 {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
980 {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
981 {0x00016044, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4},
982 {0x00016048, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001},
983 {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
984 {0x00016444, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4},
985 {0x00016448, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001},
986 {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
987 {0x00016844, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4},
988 {0x00016848, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001},
989 {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
990};
991
992static const u32 ar9300Common_rx_gain_table_2p0[][2] = {
993 /* Addr allmodes */
994 {0x0000a000, 0x00010000},
995 {0x0000a004, 0x00030002},
996 {0x0000a008, 0x00050004},
997 {0x0000a00c, 0x00810080},
998 {0x0000a010, 0x00830082},
999 {0x0000a014, 0x01810180},
1000 {0x0000a018, 0x01830182},
1001 {0x0000a01c, 0x01850184},
1002 {0x0000a020, 0x01890188},
1003 {0x0000a024, 0x018b018a},
1004 {0x0000a028, 0x018d018c},
1005 {0x0000a02c, 0x01910190},
1006 {0x0000a030, 0x01930192},
1007 {0x0000a034, 0x01950194},
1008 {0x0000a038, 0x038a0196},
1009 {0x0000a03c, 0x038c038b},
1010 {0x0000a040, 0x0390038d},
1011 {0x0000a044, 0x03920391},
1012 {0x0000a048, 0x03940393},
1013 {0x0000a04c, 0x03960395},
1014 {0x0000a050, 0x00000000},
1015 {0x0000a054, 0x00000000},
1016 {0x0000a058, 0x00000000},
1017 {0x0000a05c, 0x00000000},
1018 {0x0000a060, 0x00000000},
1019 {0x0000a064, 0x00000000},
1020 {0x0000a068, 0x00000000},
1021 {0x0000a06c, 0x00000000},
1022 {0x0000a070, 0x00000000},
1023 {0x0000a074, 0x00000000},
1024 {0x0000a078, 0x00000000},
1025 {0x0000a07c, 0x00000000},
1026 {0x0000a080, 0x22222229},
1027 {0x0000a084, 0x1d1d1d1d},
1028 {0x0000a088, 0x1d1d1d1d},
1029 {0x0000a08c, 0x1d1d1d1d},
1030 {0x0000a090, 0x171d1d1d},
1031 {0x0000a094, 0x11111717},
1032 {0x0000a098, 0x00030311},
1033 {0x0000a09c, 0x00000000},
1034 {0x0000a0a0, 0x00000000},
1035 {0x0000a0a4, 0x00000000},
1036 {0x0000a0a8, 0x00000000},
1037 {0x0000a0ac, 0x00000000},
1038 {0x0000a0b0, 0x00000000},
1039 {0x0000a0b4, 0x00000000},
1040 {0x0000a0b8, 0x00000000},
1041 {0x0000a0bc, 0x00000000},
1042 {0x0000a0c0, 0x001f0000},
1043 {0x0000a0c4, 0x01000101},
1044 {0x0000a0c8, 0x011e011f},
1045 {0x0000a0cc, 0x011c011d},
1046 {0x0000a0d0, 0x02030204},
1047 {0x0000a0d4, 0x02010202},
1048 {0x0000a0d8, 0x021f0200},
1049 {0x0000a0dc, 0x0302021e},
1050 {0x0000a0e0, 0x03000301},
1051 {0x0000a0e4, 0x031e031f},
1052 {0x0000a0e8, 0x0402031d},
1053 {0x0000a0ec, 0x04000401},
1054 {0x0000a0f0, 0x041e041f},
1055 {0x0000a0f4, 0x0502041d},
1056 {0x0000a0f8, 0x05000501},
1057 {0x0000a0fc, 0x051e051f},
1058 {0x0000a100, 0x06010602},
1059 {0x0000a104, 0x061f0600},
1060 {0x0000a108, 0x061d061e},
1061 {0x0000a10c, 0x07020703},
1062 {0x0000a110, 0x07000701},
1063 {0x0000a114, 0x00000000},
1064 {0x0000a118, 0x00000000},
1065 {0x0000a11c, 0x00000000},
1066 {0x0000a120, 0x00000000},
1067 {0x0000a124, 0x00000000},
1068 {0x0000a128, 0x00000000},
1069 {0x0000a12c, 0x00000000},
1070 {0x0000a130, 0x00000000},
1071 {0x0000a134, 0x00000000},
1072 {0x0000a138, 0x00000000},
1073 {0x0000a13c, 0x00000000},
1074 {0x0000a140, 0x001f0000},
1075 {0x0000a144, 0x01000101},
1076 {0x0000a148, 0x011e011f},
1077 {0x0000a14c, 0x011c011d},
1078 {0x0000a150, 0x02030204},
1079 {0x0000a154, 0x02010202},
1080 {0x0000a158, 0x021f0200},
1081 {0x0000a15c, 0x0302021e},
1082 {0x0000a160, 0x03000301},
1083 {0x0000a164, 0x031e031f},
1084 {0x0000a168, 0x0402031d},
1085 {0x0000a16c, 0x04000401},
1086 {0x0000a170, 0x041e041f},
1087 {0x0000a174, 0x0502041d},
1088 {0x0000a178, 0x05000501},
1089 {0x0000a17c, 0x051e051f},
1090 {0x0000a180, 0x06010602},
1091 {0x0000a184, 0x061f0600},
1092 {0x0000a188, 0x061d061e},
1093 {0x0000a18c, 0x07020703},
1094 {0x0000a190, 0x07000701},
1095 {0x0000a194, 0x00000000},
1096 {0x0000a198, 0x00000000},
1097 {0x0000a19c, 0x00000000},
1098 {0x0000a1a0, 0x00000000},
1099 {0x0000a1a4, 0x00000000},
1100 {0x0000a1a8, 0x00000000},
1101 {0x0000a1ac, 0x00000000},
1102 {0x0000a1b0, 0x00000000},
1103 {0x0000a1b4, 0x00000000},
1104 {0x0000a1b8, 0x00000000},
1105 {0x0000a1bc, 0x00000000},
1106 {0x0000a1c0, 0x00000000},
1107 {0x0000a1c4, 0x00000000},
1108 {0x0000a1c8, 0x00000000},
1109 {0x0000a1cc, 0x00000000},
1110 {0x0000a1d0, 0x00000000},
1111 {0x0000a1d4, 0x00000000},
1112 {0x0000a1d8, 0x00000000},
1113 {0x0000a1dc, 0x00000000},
1114 {0x0000a1e0, 0x00000000},
1115 {0x0000a1e4, 0x00000000},
1116 {0x0000a1e8, 0x00000000},
1117 {0x0000a1ec, 0x00000000},
1118 {0x0000a1f0, 0x00000396},
1119 {0x0000a1f4, 0x00000396},
1120 {0x0000a1f8, 0x00000396},
1121 {0x0000a1fc, 0x00000196},
1122 {0x0000b000, 0x00010000},
1123 {0x0000b004, 0x00030002},
1124 {0x0000b008, 0x00050004},
1125 {0x0000b00c, 0x00810080},
1126 {0x0000b010, 0x00830082},
1127 {0x0000b014, 0x01810180},
1128 {0x0000b018, 0x01830182},
1129 {0x0000b01c, 0x01850184},
1130 {0x0000b020, 0x02810280},
1131 {0x0000b024, 0x02830282},
1132 {0x0000b028, 0x02850284},
1133 {0x0000b02c, 0x02890288},
1134 {0x0000b030, 0x028b028a},
1135 {0x0000b034, 0x0388028c},
1136 {0x0000b038, 0x038a0389},
1137 {0x0000b03c, 0x038c038b},
1138 {0x0000b040, 0x0390038d},
1139 {0x0000b044, 0x03920391},
1140 {0x0000b048, 0x03940393},
1141 {0x0000b04c, 0x03960395},
1142 {0x0000b050, 0x00000000},
1143 {0x0000b054, 0x00000000},
1144 {0x0000b058, 0x00000000},
1145 {0x0000b05c, 0x00000000},
1146 {0x0000b060, 0x00000000},
1147 {0x0000b064, 0x00000000},
1148 {0x0000b068, 0x00000000},
1149 {0x0000b06c, 0x00000000},
1150 {0x0000b070, 0x00000000},
1151 {0x0000b074, 0x00000000},
1152 {0x0000b078, 0x00000000},
1153 {0x0000b07c, 0x00000000},
1154 {0x0000b080, 0x32323232},
1155 {0x0000b084, 0x2f2f3232},
1156 {0x0000b088, 0x23282a2d},
1157 {0x0000b08c, 0x1c1e2123},
1158 {0x0000b090, 0x14171919},
1159 {0x0000b094, 0x0e0e1214},
1160 {0x0000b098, 0x03050707},
1161 {0x0000b09c, 0x00030303},
1162 {0x0000b0a0, 0x00000000},
1163 {0x0000b0a4, 0x00000000},
1164 {0x0000b0a8, 0x00000000},
1165 {0x0000b0ac, 0x00000000},
1166 {0x0000b0b0, 0x00000000},
1167 {0x0000b0b4, 0x00000000},
1168 {0x0000b0b8, 0x00000000},
1169 {0x0000b0bc, 0x00000000},
1170 {0x0000b0c0, 0x003f0020},
1171 {0x0000b0c4, 0x00400041},
1172 {0x0000b0c8, 0x0140005f},
1173 {0x0000b0cc, 0x0160015f},
1174 {0x0000b0d0, 0x017e017f},
1175 {0x0000b0d4, 0x02410242},
1176 {0x0000b0d8, 0x025f0240},
1177 {0x0000b0dc, 0x027f0260},
1178 {0x0000b0e0, 0x0341027e},
1179 {0x0000b0e4, 0x035f0340},
1180 {0x0000b0e8, 0x037f0360},
1181 {0x0000b0ec, 0x04400441},
1182 {0x0000b0f0, 0x0460045f},
1183 {0x0000b0f4, 0x0541047f},
1184 {0x0000b0f8, 0x055f0540},
1185 {0x0000b0fc, 0x057f0560},
1186 {0x0000b100, 0x06400641},
1187 {0x0000b104, 0x0660065f},
1188 {0x0000b108, 0x067e067f},
1189 {0x0000b10c, 0x07410742},
1190 {0x0000b110, 0x075f0740},
1191 {0x0000b114, 0x077f0760},
1192 {0x0000b118, 0x07800781},
1193 {0x0000b11c, 0x07a0079f},
1194 {0x0000b120, 0x07c107bf},
1195 {0x0000b124, 0x000007c0},
1196 {0x0000b128, 0x00000000},
1197 {0x0000b12c, 0x00000000},
1198 {0x0000b130, 0x00000000},
1199 {0x0000b134, 0x00000000},
1200 {0x0000b138, 0x00000000},
1201 {0x0000b13c, 0x00000000},
1202 {0x0000b140, 0x003f0020},
1203 {0x0000b144, 0x00400041},
1204 {0x0000b148, 0x0140005f},
1205 {0x0000b14c, 0x0160015f},
1206 {0x0000b150, 0x017e017f},
1207 {0x0000b154, 0x02410242},
1208 {0x0000b158, 0x025f0240},
1209 {0x0000b15c, 0x027f0260},
1210 {0x0000b160, 0x0341027e},
1211 {0x0000b164, 0x035f0340},
1212 {0x0000b168, 0x037f0360},
1213 {0x0000b16c, 0x04400441},
1214 {0x0000b170, 0x0460045f},
1215 {0x0000b174, 0x0541047f},
1216 {0x0000b178, 0x055f0540},
1217 {0x0000b17c, 0x057f0560},
1218 {0x0000b180, 0x06400641},
1219 {0x0000b184, 0x0660065f},
1220 {0x0000b188, 0x067e067f},
1221 {0x0000b18c, 0x07410742},
1222 {0x0000b190, 0x075f0740},
1223 {0x0000b194, 0x077f0760},
1224 {0x0000b198, 0x07800781},
1225 {0x0000b19c, 0x07a0079f},
1226 {0x0000b1a0, 0x07c107bf},
1227 {0x0000b1a4, 0x000007c0},
1228 {0x0000b1a8, 0x00000000},
1229 {0x0000b1ac, 0x00000000},
1230 {0x0000b1b0, 0x00000000},
1231 {0x0000b1b4, 0x00000000},
1232 {0x0000b1b8, 0x00000000},
1233 {0x0000b1bc, 0x00000000},
1234 {0x0000b1c0, 0x00000000},
1235 {0x0000b1c4, 0x00000000},
1236 {0x0000b1c8, 0x00000000},
1237 {0x0000b1cc, 0x00000000},
1238 {0x0000b1d0, 0x00000000},
1239 {0x0000b1d4, 0x00000000},
1240 {0x0000b1d8, 0x00000000},
1241 {0x0000b1dc, 0x00000000},
1242 {0x0000b1e0, 0x00000000},
1243 {0x0000b1e4, 0x00000000},
1244 {0x0000b1e8, 0x00000000},
1245 {0x0000b1ec, 0x00000000},
1246 {0x0000b1f0, 0x00000396},
1247 {0x0000b1f4, 0x00000396},
1248 {0x0000b1f8, 0x00000396},
1249 {0x0000b1fc, 0x00000196},
1250};
1251
1252static const u32 ar9300Modes_low_ob_db_tx_gain_table_2p0[][5] = {
1253 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1254 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
1255 {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1256 {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
1257 {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
1258 {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
1259 {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
1260 {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400},
1261 {0x0000a518, 0x21020220, 0x21020220, 0x16000402, 0x16000402},
1262 {0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404},
1263 {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603},
1264 {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02},
1265 {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04},
1266 {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20},
1267 {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20},
1268 {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22},
1269 {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24},
1270 {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640},
1271 {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660},
1272 {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861},
1273 {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81},
1274 {0x0000a54c, 0x5c04286b, 0x5c04286b, 0x47001a83, 0x47001a83},
1275 {0x0000a550, 0x61042a6c, 0x61042a6c, 0x4a001c84, 0x4a001c84},
1276 {0x0000a554, 0x66062a6c, 0x66062a6c, 0x4e001ce3, 0x4e001ce3},
1277 {0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x52001ce5, 0x52001ce5},
1278 {0x0000a55c, 0x7006308c, 0x7006308c, 0x56001ce9, 0x56001ce9},
1279 {0x0000a560, 0x730a308a, 0x730a308a, 0x5a001ceb, 0x5a001ceb},
1280 {0x0000a564, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
1281 {0x0000a568, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
1282 {0x0000a56c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
1283 {0x0000a570, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
1284 {0x0000a574, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
1285 {0x0000a578, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
1286 {0x0000a57c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
1287 {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
1288 {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
1289 {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
1290 {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
1291 {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202},
1292 {0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400},
1293 {0x0000a598, 0x21820220, 0x21820220, 0x16800402, 0x16800402},
1294 {0x0000a59c, 0x27820223, 0x27820223, 0x19800404, 0x19800404},
1295 {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603},
1296 {0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02},
1297 {0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04},
1298 {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20},
1299 {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20},
1300 {0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22},
1301 {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24},
1302 {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640},
1303 {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660},
1304 {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861},
1305 {0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81},
1306 {0x0000a5cc, 0x5c84286b, 0x5c84286b, 0x47801a83, 0x47801a83},
1307 {0x0000a5d0, 0x61842a6c, 0x61842a6c, 0x4a801c84, 0x4a801c84},
1308 {0x0000a5d4, 0x66862a6c, 0x66862a6c, 0x4e801ce3, 0x4e801ce3},
1309 {0x0000a5d8, 0x6b862e6c, 0x6b862e6c, 0x52801ce5, 0x52801ce5},
1310 {0x0000a5dc, 0x7086308c, 0x7086308c, 0x56801ce9, 0x56801ce9},
1311 {0x0000a5e0, 0x738a308a, 0x738a308a, 0x5a801ceb, 0x5a801ceb},
1312 {0x0000a5e4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
1313 {0x0000a5e8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
1314 {0x0000a5ec, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
1315 {0x0000a5f0, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
1316 {0x0000a5f4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
1317 {0x0000a5f8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
1318 {0x0000a5fc, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
1319 {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
1320 {0x00016048, 0x64000001, 0x64000001, 0x64000001, 0x64000001},
1321 {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
1322 {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
1323 {0x00016448, 0x64000001, 0x64000001, 0x64000001, 0x64000001},
1324 {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
1325 {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
1326 {0x00016848, 0x64000001, 0x64000001, 0x64000001, 0x64000001},
1327 {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
1328};
1329
1330static const u32 ar9300_2p0_mac_core[][2] = {
1331 /* Addr allmodes */
1332 {0x00000008, 0x00000000},
1333 {0x00000030, 0x00020085},
1334 {0x00000034, 0x00000005},
1335 {0x00000040, 0x00000000},
1336 {0x00000044, 0x00000000},
1337 {0x00000048, 0x00000008},
1338 {0x0000004c, 0x00000010},
1339 {0x00000050, 0x00000000},
1340 {0x00001040, 0x002ffc0f},
1341 {0x00001044, 0x002ffc0f},
1342 {0x00001048, 0x002ffc0f},
1343 {0x0000104c, 0x002ffc0f},
1344 {0x00001050, 0x002ffc0f},
1345 {0x00001054, 0x002ffc0f},
1346 {0x00001058, 0x002ffc0f},
1347 {0x0000105c, 0x002ffc0f},
1348 {0x00001060, 0x002ffc0f},
1349 {0x00001064, 0x002ffc0f},
1350 {0x000010f0, 0x00000100},
1351 {0x00001270, 0x00000000},
1352 {0x000012b0, 0x00000000},
1353 {0x000012f0, 0x00000000},
1354 {0x0000143c, 0x00000000},
1355 {0x0000147c, 0x00000000},
1356 {0x00008000, 0x00000000},
1357 {0x00008004, 0x00000000},
1358 {0x00008008, 0x00000000},
1359 {0x0000800c, 0x00000000},
1360 {0x00008018, 0x00000000},
1361 {0x00008020, 0x00000000},
1362 {0x00008038, 0x00000000},
1363 {0x0000803c, 0x00000000},
1364 {0x00008040, 0x00000000},
1365 {0x00008044, 0x00000000},
1366 {0x00008048, 0x00000000},
1367 {0x0000804c, 0xffffffff},
1368 {0x00008054, 0x00000000},
1369 {0x00008058, 0x00000000},
1370 {0x0000805c, 0x000fc78f},
1371 {0x00008060, 0x0000000f},
1372 {0x00008064, 0x00000000},
1373 {0x00008070, 0x00000310},
1374 {0x00008074, 0x00000020},
1375 {0x00008078, 0x00000000},
1376 {0x0000809c, 0x0000000f},
1377 {0x000080a0, 0x00000000},
1378 {0x000080a4, 0x02ff0000},
1379 {0x000080a8, 0x0e070605},
1380 {0x000080ac, 0x0000000d},
1381 {0x000080b0, 0x00000000},
1382 {0x000080b4, 0x00000000},
1383 {0x000080b8, 0x00000000},
1384 {0x000080bc, 0x00000000},
1385 {0x000080c0, 0x2a800000},
1386 {0x000080c4, 0x06900168},
1387 {0x000080c8, 0x13881c20},
1388 {0x000080cc, 0x01f40000},
1389 {0x000080d0, 0x00252500},
1390 {0x000080d4, 0x00a00000},
1391 {0x000080d8, 0x00400000},
1392 {0x000080dc, 0x00000000},
1393 {0x000080e0, 0xffffffff},
1394 {0x000080e4, 0x0000ffff},
1395 {0x000080e8, 0x3f3f3f3f},
1396 {0x000080ec, 0x00000000},
1397 {0x000080f0, 0x00000000},
1398 {0x000080f4, 0x00000000},
1399 {0x000080fc, 0x00020000},
1400 {0x00008100, 0x00000000},
1401 {0x00008108, 0x00000052},
1402 {0x0000810c, 0x00000000},
1403 {0x00008110, 0x00000000},
1404 {0x00008114, 0x000007ff},
1405 {0x00008118, 0x000000aa},
1406 {0x0000811c, 0x00003210},
1407 {0x00008124, 0x00000000},
1408 {0x00008128, 0x00000000},
1409 {0x0000812c, 0x00000000},
1410 {0x00008130, 0x00000000},
1411 {0x00008134, 0x00000000},
1412 {0x00008138, 0x00000000},
1413 {0x0000813c, 0x0000ffff},
1414 {0x00008144, 0xffffffff},
1415 {0x00008168, 0x00000000},
1416 {0x0000816c, 0x00000000},
1417 {0x00008170, 0x18486200},
1418 {0x00008174, 0x33332210},
1419 {0x00008178, 0x00000000},
1420 {0x0000817c, 0x00020000},
1421 {0x000081c0, 0x00000000},
1422 {0x000081c4, 0x33332210},
1423 {0x000081c8, 0x00000000},
1424 {0x000081cc, 0x00000000},
1425 {0x000081d4, 0x00000000},
1426 {0x000081ec, 0x00000000},
1427 {0x000081f0, 0x00000000},
1428 {0x000081f4, 0x00000000},
1429 {0x000081f8, 0x00000000},
1430 {0x000081fc, 0x00000000},
1431 {0x00008240, 0x00100000},
1432 {0x00008244, 0x0010f424},
1433 {0x00008248, 0x00000800},
1434 {0x0000824c, 0x0001e848},
1435 {0x00008250, 0x00000000},
1436 {0x00008254, 0x00000000},
1437 {0x00008258, 0x00000000},
1438 {0x0000825c, 0x40000000},
1439 {0x00008260, 0x00080922},
1440 {0x00008264, 0x98a00010},
1441 {0x00008268, 0xffffffff},
1442 {0x0000826c, 0x0000ffff},
1443 {0x00008270, 0x00000000},
1444 {0x00008274, 0x40000000},
1445 {0x00008278, 0x003e4180},
1446 {0x0000827c, 0x00000004},
1447 {0x00008284, 0x0000002c},
1448 {0x00008288, 0x0000002c},
1449 {0x0000828c, 0x000000ff},
1450 {0x00008294, 0x00000000},
1451 {0x00008298, 0x00000000},
1452 {0x0000829c, 0x00000000},
1453 {0x00008300, 0x00000140},
1454 {0x00008314, 0x00000000},
1455 {0x0000831c, 0x0000010d},
1456 {0x00008328, 0x00000000},
1457 {0x0000832c, 0x00000007},
1458 {0x00008330, 0x00000302},
1459 {0x00008334, 0x00000700},
1460 {0x00008338, 0x00ff0000},
1461 {0x0000833c, 0x02400000},
1462 {0x00008340, 0x000107ff},
1463 {0x00008344, 0xaa48105b},
1464 {0x00008348, 0x008f0000},
1465 {0x0000835c, 0x00000000},
1466 {0x00008360, 0xffffffff},
1467 {0x00008364, 0xffffffff},
1468 {0x00008368, 0x00000000},
1469 {0x00008370, 0x00000000},
1470 {0x00008374, 0x000000ff},
1471 {0x00008378, 0x00000000},
1472 {0x0000837c, 0x00000000},
1473 {0x00008380, 0xffffffff},
1474 {0x00008384, 0xffffffff},
1475 {0x00008390, 0xffffffff},
1476 {0x00008394, 0xffffffff},
1477 {0x00008398, 0x00000000},
1478 {0x0000839c, 0x00000000},
1479 {0x000083a0, 0x00000000},
1480 {0x000083a4, 0x0000fa14},
1481 {0x000083a8, 0x000f0c00},
1482 {0x000083ac, 0x33332210},
1483 {0x000083b0, 0x33332210},
1484 {0x000083b4, 0x33332210},
1485 {0x000083b8, 0x33332210},
1486 {0x000083bc, 0x00000000},
1487 {0x000083c0, 0x00000000},
1488 {0x000083c4, 0x00000000},
1489 {0x000083c8, 0x00000000},
1490 {0x000083cc, 0x00000200},
1491 {0x000083d0, 0x000301ff},
1492};
1493
1494static const u32 ar9300Common_wo_xlna_rx_gain_table_2p0[][2] = {
1495 /* Addr allmodes */
1496 {0x0000a000, 0x00010000},
1497 {0x0000a004, 0x00030002},
1498 {0x0000a008, 0x00050004},
1499 {0x0000a00c, 0x00810080},
1500 {0x0000a010, 0x00830082},
1501 {0x0000a014, 0x01810180},
1502 {0x0000a018, 0x01830182},
1503 {0x0000a01c, 0x01850184},
1504 {0x0000a020, 0x01890188},
1505 {0x0000a024, 0x018b018a},
1506 {0x0000a028, 0x018d018c},
1507 {0x0000a02c, 0x03820190},
1508 {0x0000a030, 0x03840383},
1509 {0x0000a034, 0x03880385},
1510 {0x0000a038, 0x038a0389},
1511 {0x0000a03c, 0x038c038b},
1512 {0x0000a040, 0x0390038d},
1513 {0x0000a044, 0x03920391},
1514 {0x0000a048, 0x03940393},
1515 {0x0000a04c, 0x03960395},
1516 {0x0000a050, 0x00000000},
1517 {0x0000a054, 0x00000000},
1518 {0x0000a058, 0x00000000},
1519 {0x0000a05c, 0x00000000},
1520 {0x0000a060, 0x00000000},
1521 {0x0000a064, 0x00000000},
1522 {0x0000a068, 0x00000000},
1523 {0x0000a06c, 0x00000000},
1524 {0x0000a070, 0x00000000},
1525 {0x0000a074, 0x00000000},
1526 {0x0000a078, 0x00000000},
1527 {0x0000a07c, 0x00000000},
1528 {0x0000a080, 0x29292929},
1529 {0x0000a084, 0x29292929},
1530 {0x0000a088, 0x29292929},
1531 {0x0000a08c, 0x29292929},
1532 {0x0000a090, 0x22292929},
1533 {0x0000a094, 0x1d1d2222},
1534 {0x0000a098, 0x0c111117},
1535 {0x0000a09c, 0x00030303},
1536 {0x0000a0a0, 0x00000000},
1537 {0x0000a0a4, 0x00000000},
1538 {0x0000a0a8, 0x00000000},
1539 {0x0000a0ac, 0x00000000},
1540 {0x0000a0b0, 0x00000000},
1541 {0x0000a0b4, 0x00000000},
1542 {0x0000a0b8, 0x00000000},
1543 {0x0000a0bc, 0x00000000},
1544 {0x0000a0c0, 0x001f0000},
1545 {0x0000a0c4, 0x01000101},
1546 {0x0000a0c8, 0x011e011f},
1547 {0x0000a0cc, 0x011c011d},
1548 {0x0000a0d0, 0x02030204},
1549 {0x0000a0d4, 0x02010202},
1550 {0x0000a0d8, 0x021f0200},
1551 {0x0000a0dc, 0x0302021e},
1552 {0x0000a0e0, 0x03000301},
1553 {0x0000a0e4, 0x031e031f},
1554 {0x0000a0e8, 0x0402031d},
1555 {0x0000a0ec, 0x04000401},
1556 {0x0000a0f0, 0x041e041f},
1557 {0x0000a0f4, 0x0502041d},
1558 {0x0000a0f8, 0x05000501},
1559 {0x0000a0fc, 0x051e051f},
1560 {0x0000a100, 0x06010602},
1561 {0x0000a104, 0x061f0600},
1562 {0x0000a108, 0x061d061e},
1563 {0x0000a10c, 0x07020703},
1564 {0x0000a110, 0x07000701},
1565 {0x0000a114, 0x00000000},
1566 {0x0000a118, 0x00000000},
1567 {0x0000a11c, 0x00000000},
1568 {0x0000a120, 0x00000000},
1569 {0x0000a124, 0x00000000},
1570 {0x0000a128, 0x00000000},
1571 {0x0000a12c, 0x00000000},
1572 {0x0000a130, 0x00000000},
1573 {0x0000a134, 0x00000000},
1574 {0x0000a138, 0x00000000},
1575 {0x0000a13c, 0x00000000},
1576 {0x0000a140, 0x001f0000},
1577 {0x0000a144, 0x01000101},
1578 {0x0000a148, 0x011e011f},
1579 {0x0000a14c, 0x011c011d},
1580 {0x0000a150, 0x02030204},
1581 {0x0000a154, 0x02010202},
1582 {0x0000a158, 0x021f0200},
1583 {0x0000a15c, 0x0302021e},
1584 {0x0000a160, 0x03000301},
1585 {0x0000a164, 0x031e031f},
1586 {0x0000a168, 0x0402031d},
1587 {0x0000a16c, 0x04000401},
1588 {0x0000a170, 0x041e041f},
1589 {0x0000a174, 0x0502041d},
1590 {0x0000a178, 0x05000501},
1591 {0x0000a17c, 0x051e051f},
1592 {0x0000a180, 0x06010602},
1593 {0x0000a184, 0x061f0600},
1594 {0x0000a188, 0x061d061e},
1595 {0x0000a18c, 0x07020703},
1596 {0x0000a190, 0x07000701},
1597 {0x0000a194, 0x00000000},
1598 {0x0000a198, 0x00000000},
1599 {0x0000a19c, 0x00000000},
1600 {0x0000a1a0, 0x00000000},
1601 {0x0000a1a4, 0x00000000},
1602 {0x0000a1a8, 0x00000000},
1603 {0x0000a1ac, 0x00000000},
1604 {0x0000a1b0, 0x00000000},
1605 {0x0000a1b4, 0x00000000},
1606 {0x0000a1b8, 0x00000000},
1607 {0x0000a1bc, 0x00000000},
1608 {0x0000a1c0, 0x00000000},
1609 {0x0000a1c4, 0x00000000},
1610 {0x0000a1c8, 0x00000000},
1611 {0x0000a1cc, 0x00000000},
1612 {0x0000a1d0, 0x00000000},
1613 {0x0000a1d4, 0x00000000},
1614 {0x0000a1d8, 0x00000000},
1615 {0x0000a1dc, 0x00000000},
1616 {0x0000a1e0, 0x00000000},
1617 {0x0000a1e4, 0x00000000},
1618 {0x0000a1e8, 0x00000000},
1619 {0x0000a1ec, 0x00000000},
1620 {0x0000a1f0, 0x00000396},
1621 {0x0000a1f4, 0x00000396},
1622 {0x0000a1f8, 0x00000396},
1623 {0x0000a1fc, 0x00000196},
1624 {0x0000b000, 0x00010000},
1625 {0x0000b004, 0x00030002},
1626 {0x0000b008, 0x00050004},
1627 {0x0000b00c, 0x00810080},
1628 {0x0000b010, 0x00830082},
1629 {0x0000b014, 0x01810180},
1630 {0x0000b018, 0x01830182},
1631 {0x0000b01c, 0x01850184},
1632 {0x0000b020, 0x02810280},
1633 {0x0000b024, 0x02830282},
1634 {0x0000b028, 0x02850284},
1635 {0x0000b02c, 0x02890288},
1636 {0x0000b030, 0x028b028a},
1637 {0x0000b034, 0x0388028c},
1638 {0x0000b038, 0x038a0389},
1639 {0x0000b03c, 0x038c038b},
1640 {0x0000b040, 0x0390038d},
1641 {0x0000b044, 0x03920391},
1642 {0x0000b048, 0x03940393},
1643 {0x0000b04c, 0x03960395},
1644 {0x0000b050, 0x00000000},
1645 {0x0000b054, 0x00000000},
1646 {0x0000b058, 0x00000000},
1647 {0x0000b05c, 0x00000000},
1648 {0x0000b060, 0x00000000},
1649 {0x0000b064, 0x00000000},
1650 {0x0000b068, 0x00000000},
1651 {0x0000b06c, 0x00000000},
1652 {0x0000b070, 0x00000000},
1653 {0x0000b074, 0x00000000},
1654 {0x0000b078, 0x00000000},
1655 {0x0000b07c, 0x00000000},
1656 {0x0000b080, 0x32323232},
1657 {0x0000b084, 0x2f2f3232},
1658 {0x0000b088, 0x23282a2d},
1659 {0x0000b08c, 0x1c1e2123},
1660 {0x0000b090, 0x14171919},
1661 {0x0000b094, 0x0e0e1214},
1662 {0x0000b098, 0x03050707},
1663 {0x0000b09c, 0x00030303},
1664 {0x0000b0a0, 0x00000000},
1665 {0x0000b0a4, 0x00000000},
1666 {0x0000b0a8, 0x00000000},
1667 {0x0000b0ac, 0x00000000},
1668 {0x0000b0b0, 0x00000000},
1669 {0x0000b0b4, 0x00000000},
1670 {0x0000b0b8, 0x00000000},
1671 {0x0000b0bc, 0x00000000},
1672 {0x0000b0c0, 0x003f0020},
1673 {0x0000b0c4, 0x00400041},
1674 {0x0000b0c8, 0x0140005f},
1675 {0x0000b0cc, 0x0160015f},
1676 {0x0000b0d0, 0x017e017f},
1677 {0x0000b0d4, 0x02410242},
1678 {0x0000b0d8, 0x025f0240},
1679 {0x0000b0dc, 0x027f0260},
1680 {0x0000b0e0, 0x0341027e},
1681 {0x0000b0e4, 0x035f0340},
1682 {0x0000b0e8, 0x037f0360},
1683 {0x0000b0ec, 0x04400441},
1684 {0x0000b0f0, 0x0460045f},
1685 {0x0000b0f4, 0x0541047f},
1686 {0x0000b0f8, 0x055f0540},
1687 {0x0000b0fc, 0x057f0560},
1688 {0x0000b100, 0x06400641},
1689 {0x0000b104, 0x0660065f},
1690 {0x0000b108, 0x067e067f},
1691 {0x0000b10c, 0x07410742},
1692 {0x0000b110, 0x075f0740},
1693 {0x0000b114, 0x077f0760},
1694 {0x0000b118, 0x07800781},
1695 {0x0000b11c, 0x07a0079f},
1696 {0x0000b120, 0x07c107bf},
1697 {0x0000b124, 0x000007c0},
1698 {0x0000b128, 0x00000000},
1699 {0x0000b12c, 0x00000000},
1700 {0x0000b130, 0x00000000},
1701 {0x0000b134, 0x00000000},
1702 {0x0000b138, 0x00000000},
1703 {0x0000b13c, 0x00000000},
1704 {0x0000b140, 0x003f0020},
1705 {0x0000b144, 0x00400041},
1706 {0x0000b148, 0x0140005f},
1707 {0x0000b14c, 0x0160015f},
1708 {0x0000b150, 0x017e017f},
1709 {0x0000b154, 0x02410242},
1710 {0x0000b158, 0x025f0240},
1711 {0x0000b15c, 0x027f0260},
1712 {0x0000b160, 0x0341027e},
1713 {0x0000b164, 0x035f0340},
1714 {0x0000b168, 0x037f0360},
1715 {0x0000b16c, 0x04400441},
1716 {0x0000b170, 0x0460045f},
1717 {0x0000b174, 0x0541047f},
1718 {0x0000b178, 0x055f0540},
1719 {0x0000b17c, 0x057f0560},
1720 {0x0000b180, 0x06400641},
1721 {0x0000b184, 0x0660065f},
1722 {0x0000b188, 0x067e067f},
1723 {0x0000b18c, 0x07410742},
1724 {0x0000b190, 0x075f0740},
1725 {0x0000b194, 0x077f0760},
1726 {0x0000b198, 0x07800781},
1727 {0x0000b19c, 0x07a0079f},
1728 {0x0000b1a0, 0x07c107bf},
1729 {0x0000b1a4, 0x000007c0},
1730 {0x0000b1a8, 0x00000000},
1731 {0x0000b1ac, 0x00000000},
1732 {0x0000b1b0, 0x00000000},
1733 {0x0000b1b4, 0x00000000},
1734 {0x0000b1b8, 0x00000000},
1735 {0x0000b1bc, 0x00000000},
1736 {0x0000b1c0, 0x00000000},
1737 {0x0000b1c4, 0x00000000},
1738 {0x0000b1c8, 0x00000000},
1739 {0x0000b1cc, 0x00000000},
1740 {0x0000b1d0, 0x00000000},
1741 {0x0000b1d4, 0x00000000},
1742 {0x0000b1d8, 0x00000000},
1743 {0x0000b1dc, 0x00000000},
1744 {0x0000b1e0, 0x00000000},
1745 {0x0000b1e4, 0x00000000},
1746 {0x0000b1e8, 0x00000000},
1747 {0x0000b1ec, 0x00000000},
1748 {0x0000b1f0, 0x00000396},
1749 {0x0000b1f4, 0x00000396},
1750 {0x0000b1f8, 0x00000396},
1751 {0x0000b1fc, 0x00000196},
1752};
1753
1754static const u32 ar9300_2p0_soc_preamble[][2] = {
1755 /* Addr allmodes */
1756 {0x000040a4, 0x00a0c1c9},
1757 {0x00007008, 0x00000000},
1758 {0x00007020, 0x00000000},
1759 {0x00007034, 0x00000002},
1760 {0x00007038, 0x000004c2},
1761};
1762
1763static const u32 ar9300PciePhy_pll_on_clkreq_disable_L1_2p0[][2] = {
1764 /* Addr allmodes */
1765 {0x00004040, 0x08212e5e},
1766 {0x00004040, 0x0008003b},
1767 {0x00004044, 0x00000000},
1768};
1769
1770static const u32 ar9300PciePhy_clkreq_enable_L1_2p0[][2] = {
1771 /* Addr allmodes */
1772 {0x00004040, 0x08253e5e},
1773 {0x00004040, 0x0008003b},
1774 {0x00004044, 0x00000000},
1775};
1776
1777static const u32 ar9300PciePhy_clkreq_disable_L1_2p0[][2] = {
1778 /* Addr allmodes */
1779 {0x00004040, 0x08213e5e},
1780 {0x00004040, 0x0008003b},
1781 {0x00004044, 0x00000000},
1782};
1783
1784#endif /* INITVALS_9003_2P0_H */
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
index 02c970819f79..c2a057156bfa 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -16,7 +16,6 @@
16 16
17#include "hw.h" 17#include "hw.h"
18#include "ar9003_mac.h" 18#include "ar9003_mac.h"
19#include "ar9003_2p0_initvals.h"
20#include "ar9003_2p2_initvals.h" 19#include "ar9003_2p2_initvals.h"
21 20
22/* General hardware code for the AR9003 hadware family */ 21/* General hardware code for the AR9003 hadware family */
@@ -32,79 +31,12 @@ static bool ar9003_hw_macversion_supported(u32 macversion)
32 return false; 31 return false;
33} 32}
34 33
35/* AR9003 2.0 */ 34/*
36static void ar9003_2p0_hw_init_mode_regs(struct ath_hw *ah) 35 * The AR9003 family uses a new INI format (pre, core, post
37{ 36 * arrays per subsystem). This provides support for the
38 /* mac */ 37 * AR9003 2.2 chipsets.
39 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); 38 */
40 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], 39static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
41 ar9300_2p0_mac_core,
42 ARRAY_SIZE(ar9300_2p0_mac_core), 2);
43 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
44 ar9300_2p0_mac_postamble,
45 ARRAY_SIZE(ar9300_2p0_mac_postamble), 5);
46
47 /* bb */
48 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
49 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
50 ar9300_2p0_baseband_core,
51 ARRAY_SIZE(ar9300_2p0_baseband_core), 2);
52 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
53 ar9300_2p0_baseband_postamble,
54 ARRAY_SIZE(ar9300_2p0_baseband_postamble), 5);
55
56 /* radio */
57 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
58 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
59 ar9300_2p0_radio_core,
60 ARRAY_SIZE(ar9300_2p0_radio_core), 2);
61 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
62 ar9300_2p0_radio_postamble,
63 ARRAY_SIZE(ar9300_2p0_radio_postamble), 5);
64
65 /* soc */
66 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
67 ar9300_2p0_soc_preamble,
68 ARRAY_SIZE(ar9300_2p0_soc_preamble), 2);
69 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
70 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
71 ar9300_2p0_soc_postamble,
72 ARRAY_SIZE(ar9300_2p0_soc_postamble), 5);
73
74 /* rx/tx gain */
75 INIT_INI_ARRAY(&ah->iniModesRxGain,
76 ar9300Common_rx_gain_table_2p0,
77 ARRAY_SIZE(ar9300Common_rx_gain_table_2p0), 2);
78 INIT_INI_ARRAY(&ah->iniModesTxGain,
79 ar9300Modes_lowest_ob_db_tx_gain_table_2p0,
80 ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p0),
81 5);
82
83 /* Load PCIE SERDES settings from INI */
84
85 /* Awake Setting */
86
87 INIT_INI_ARRAY(&ah->iniPcieSerdes,
88 ar9300PciePhy_pll_on_clkreq_disable_L1_2p0,
89 ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p0),
90 2);
91
92 /* Sleep Setting */
93
94 INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
95 ar9300PciePhy_clkreq_enable_L1_2p0,
96 ARRAY_SIZE(ar9300PciePhy_clkreq_enable_L1_2p0),
97 2);
98
99 /* Fast clock modal settings */
100 INIT_INI_ARRAY(&ah->iniModesAdditional,
101 ar9300Modes_fast_clock_2p0,
102 ARRAY_SIZE(ar9300Modes_fast_clock_2p0),
103 3);
104}
105
106/* AR9003 2.2 */
107static void ar9003_2p2_hw_init_mode_regs(struct ath_hw *ah)
108{ 40{
109 /* mac */ 41 /* mac */
110 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); 42 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
@@ -174,57 +106,27 @@ static void ar9003_2p2_hw_init_mode_regs(struct ath_hw *ah)
174 3); 106 3);
175} 107}
176 108
177/*
178 * The AR9003 family uses a new INI format (pre, core, post
179 * arrays per subsystem).
180 */
181static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
182{
183 if (AR_SREV_9300_20(ah))
184 ar9003_2p0_hw_init_mode_regs(ah);
185 else
186 ar9003_2p2_hw_init_mode_regs(ah);
187}
188
189static void ar9003_tx_gain_table_apply(struct ath_hw *ah) 109static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
190{ 110{
191 switch (ar9003_hw_get_tx_gain_idx(ah)) { 111 switch (ar9003_hw_get_tx_gain_idx(ah)) {
192 case 0: 112 case 0:
193 default: 113 default:
194 if (AR_SREV_9300_20(ah)) 114 INIT_INI_ARRAY(&ah->iniModesTxGain,
195 INIT_INI_ARRAY(&ah->iniModesTxGain, 115 ar9300Modes_lowest_ob_db_tx_gain_table_2p2,
196 ar9300Modes_lowest_ob_db_tx_gain_table_2p0, 116 ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2),
197 ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p0), 117 5);
198 5);
199 else
200 INIT_INI_ARRAY(&ah->iniModesTxGain,
201 ar9300Modes_lowest_ob_db_tx_gain_table_2p2,
202 ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2),
203 5);
204 break; 118 break;
205 case 1: 119 case 1:
206 if (AR_SREV_9300_20(ah)) 120 INIT_INI_ARRAY(&ah->iniModesTxGain,
207 INIT_INI_ARRAY(&ah->iniModesTxGain, 121 ar9300Modes_high_ob_db_tx_gain_table_2p2,
208 ar9300Modes_high_ob_db_tx_gain_table_2p0, 122 ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p2),
209 ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p0), 123 5);
210 5);
211 else
212 INIT_INI_ARRAY(&ah->iniModesTxGain,
213 ar9300Modes_high_ob_db_tx_gain_table_2p2,
214 ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p2),
215 5);
216 break; 124 break;
217 case 2: 125 case 2:
218 if (AR_SREV_9300_20(ah)) 126 INIT_INI_ARRAY(&ah->iniModesTxGain,
219 INIT_INI_ARRAY(&ah->iniModesTxGain, 127 ar9300Modes_low_ob_db_tx_gain_table_2p2,
220 ar9300Modes_low_ob_db_tx_gain_table_2p0, 128 ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p2),
221 ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p0), 129 5);
222 5);
223 else
224 INIT_INI_ARRAY(&ah->iniModesTxGain,
225 ar9300Modes_low_ob_db_tx_gain_table_2p2,
226 ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p2),
227 5);
228 break; 130 break;
229 } 131 }
230} 132}
@@ -234,28 +136,16 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
234 switch (ar9003_hw_get_rx_gain_idx(ah)) { 136 switch (ar9003_hw_get_rx_gain_idx(ah)) {
235 case 0: 137 case 0:
236 default: 138 default:
237 if (AR_SREV_9300_20(ah)) 139 INIT_INI_ARRAY(&ah->iniModesRxGain,
238 INIT_INI_ARRAY(&ah->iniModesRxGain, 140 ar9300Common_rx_gain_table_2p2,
239 ar9300Common_rx_gain_table_2p0, 141 ARRAY_SIZE(ar9300Common_rx_gain_table_2p2),
240 ARRAY_SIZE(ar9300Common_rx_gain_table_2p0), 142 2);
241 2);
242 else
243 INIT_INI_ARRAY(&ah->iniModesRxGain,
244 ar9300Common_rx_gain_table_2p2,
245 ARRAY_SIZE(ar9300Common_rx_gain_table_2p2),
246 2);
247 break; 143 break;
248 case 1: 144 case 1:
249 if (AR_SREV_9300_20(ah)) 145 INIT_INI_ARRAY(&ah->iniModesRxGain,
250 INIT_INI_ARRAY(&ah->iniModesRxGain, 146 ar9300Common_wo_xlna_rx_gain_table_2p2,
251 ar9300Common_wo_xlna_rx_gain_table_2p0, 147 ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p2),
252 ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p0), 148 2);
253 2);
254 else
255 INIT_INI_ARRAY(&ah->iniModesRxGain,
256 ar9300Common_wo_xlna_rx_gain_table_2p2,
257 ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p2),
258 2);
259 break; 149 break;
260 } 150 }
261} 151}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index efb05599b84c..669b777729b3 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -1254,13 +1254,12 @@ void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah)
1254 "** BB mode: BB_gen_controls=0x%08x **\n", 1254 "** BB mode: BB_gen_controls=0x%08x **\n",
1255 REG_READ(ah, AR_PHY_GEN_CTRL)); 1255 REG_READ(ah, AR_PHY_GEN_CTRL));
1256 1256
1257 ath9k_hw_update_cycle_counters(ah); 1257#define PCT(_field) (common->cc_survey._field * 100 / common->cc_survey.cycles)
1258#define PCT(_field) (ah->cc_delta._field * 100 / ah->cc_delta.cycles) 1258 if (common->cc_survey.cycles)
1259 if (ah->cc_delta.cycles)
1260 ath_print(common, ATH_DBG_RESET, 1259 ath_print(common, ATH_DBG_RESET,
1261 "** BB busy times: rx_clear=%d%%, " 1260 "** BB busy times: rx_clear=%d%%, "
1262 "rx_frame=%d%%, tx_frame=%d%% **\n", 1261 "rx_frame=%d%%, tx_frame=%d%% **\n",
1263 PCT(rx_clear), PCT(rx_frame), PCT(tx_frame)); 1262 PCT(rx_busy), PCT(rx_frame), PCT(tx_frame));
1264 1263
1265 ath_print(common, ATH_DBG_RESET, 1264 ath_print(common, ATH_DBG_RESET,
1266 "==== BB update: done ====\n\n"); 1265 "==== BB update: done ====\n\n");
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index de2b18ee7f77..973c919fdd27 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -239,12 +239,11 @@ struct ath_buf {
239 struct sk_buff *bf_mpdu; /* enclosing frame structure */ 239 struct sk_buff *bf_mpdu; /* enclosing frame structure */
240 void *bf_desc; /* virtual addr of desc */ 240 void *bf_desc; /* virtual addr of desc */
241 dma_addr_t bf_daddr; /* physical addr of desc */ 241 dma_addr_t bf_daddr; /* physical addr of desc */
242 dma_addr_t bf_buf_addr; /* physical addr of data buffer */ 242 dma_addr_t bf_buf_addr; /* physical addr of data buffer, for DMA */
243 bool bf_stale; 243 bool bf_stale;
244 bool bf_tx_aborted; 244 bool bf_tx_aborted;
245 u16 bf_flags; 245 u16 bf_flags;
246 struct ath_buf_state bf_state; 246 struct ath_buf_state bf_state;
247 dma_addr_t bf_dmacontext;
248 struct ath_wiphy *aphy; 247 struct ath_wiphy *aphy;
249}; 248};
250 249
@@ -593,6 +592,8 @@ struct ath_softc {
593 struct delayed_work wiphy_work; 592 struct delayed_work wiphy_work;
594 unsigned long wiphy_scheduler_int; 593 unsigned long wiphy_scheduler_int;
595 int wiphy_scheduler_index; 594 int wiphy_scheduler_index;
595 struct survey_info *cur_survey;
596 struct survey_info survey[ATH9K_NUM_CHANNELS];
596 597
597 struct tasklet_struct intr_tq; 598 struct tasklet_struct intr_tq;
598 struct tasklet_struct bcon_tasklet; 599 struct tasklet_struct bcon_tasklet;
@@ -621,8 +622,6 @@ struct ath_softc {
621 struct ath_rx rx; 622 struct ath_rx rx;
622 struct ath_tx tx; 623 struct ath_tx tx;
623 struct ath_beacon beacon; 624 struct ath_beacon beacon;
624 const struct ath_rate_table *cur_rate_table;
625 enum wireless_mode cur_rate_mode;
626 struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; 625 struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
627 626
628 struct ath_led radio_led; 627 struct ath_led radio_led;
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index 081192e78a46..4ed010d4ef96 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -136,9 +136,10 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
136 bf = avp->av_bcbuf; 136 bf = avp->av_bcbuf;
137 skb = bf->bf_mpdu; 137 skb = bf->bf_mpdu;
138 if (skb) { 138 if (skb) {
139 dma_unmap_single(sc->dev, bf->bf_dmacontext, 139 dma_unmap_single(sc->dev, bf->bf_buf_addr,
140 skb->len, DMA_TO_DEVICE); 140 skb->len, DMA_TO_DEVICE);
141 dev_kfree_skb_any(skb); 141 dev_kfree_skb_any(skb);
142 bf->bf_buf_addr = 0;
142 } 143 }
143 144
144 /* Get a new beacon from mac80211 */ 145 /* Get a new beacon from mac80211 */
@@ -162,12 +163,12 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
162 hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no); 163 hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
163 } 164 }
164 165
165 bf->bf_buf_addr = bf->bf_dmacontext = 166 bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
166 dma_map_single(sc->dev, skb->data, 167 skb->len, DMA_TO_DEVICE);
167 skb->len, DMA_TO_DEVICE);
168 if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) { 168 if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) {
169 dev_kfree_skb_any(skb); 169 dev_kfree_skb_any(skb);
170 bf->bf_mpdu = NULL; 170 bf->bf_mpdu = NULL;
171 bf->bf_buf_addr = 0;
171 ath_print(common, ATH_DBG_FATAL, 172 ath_print(common, ATH_DBG_FATAL,
172 "dma_mapping_error on beaconing\n"); 173 "dma_mapping_error on beaconing\n");
173 return NULL; 174 return NULL;
@@ -252,10 +253,11 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
252 bf = avp->av_bcbuf; 253 bf = avp->av_bcbuf;
253 if (bf->bf_mpdu != NULL) { 254 if (bf->bf_mpdu != NULL) {
254 skb = bf->bf_mpdu; 255 skb = bf->bf_mpdu;
255 dma_unmap_single(sc->dev, bf->bf_dmacontext, 256 dma_unmap_single(sc->dev, bf->bf_buf_addr,
256 skb->len, DMA_TO_DEVICE); 257 skb->len, DMA_TO_DEVICE);
257 dev_kfree_skb_any(skb); 258 dev_kfree_skb_any(skb);
258 bf->bf_mpdu = NULL; 259 bf->bf_mpdu = NULL;
260 bf->bf_buf_addr = 0;
259 } 261 }
260 262
261 /* NB: the beacon data buffer must be 32-bit aligned. */ 263 /* NB: the beacon data buffer must be 32-bit aligned. */
@@ -296,12 +298,12 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
296 avp->tsf_adjust = cpu_to_le64(0); 298 avp->tsf_adjust = cpu_to_le64(0);
297 299
298 bf->bf_mpdu = skb; 300 bf->bf_mpdu = skb;
299 bf->bf_buf_addr = bf->bf_dmacontext = 301 bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
300 dma_map_single(sc->dev, skb->data, 302 skb->len, DMA_TO_DEVICE);
301 skb->len, DMA_TO_DEVICE);
302 if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) { 303 if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) {
303 dev_kfree_skb_any(skb); 304 dev_kfree_skb_any(skb);
304 bf->bf_mpdu = NULL; 305 bf->bf_mpdu = NULL;
306 bf->bf_buf_addr = 0;
305 ath_print(common, ATH_DBG_FATAL, 307 ath_print(common, ATH_DBG_FATAL,
306 "dma_mapping_error on beacon alloc\n"); 308 "dma_mapping_error on beacon alloc\n");
307 return -ENOMEM; 309 return -ENOMEM;
@@ -324,10 +326,11 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp)
324 bf = avp->av_bcbuf; 326 bf = avp->av_bcbuf;
325 if (bf->bf_mpdu != NULL) { 327 if (bf->bf_mpdu != NULL) {
326 struct sk_buff *skb = bf->bf_mpdu; 328 struct sk_buff *skb = bf->bf_mpdu;
327 dma_unmap_single(sc->dev, bf->bf_dmacontext, 329 dma_unmap_single(sc->dev, bf->bf_buf_addr,
328 skb->len, DMA_TO_DEVICE); 330 skb->len, DMA_TO_DEVICE);
329 dev_kfree_skb_any(skb); 331 dev_kfree_skb_any(skb);
330 bf->bf_mpdu = NULL; 332 bf->bf_mpdu = NULL;
333 bf->bf_buf_addr = 0;
331 } 334 }
332 list_add_tail(&bf->list, &sc->beacon.bbuf); 335 list_add_tail(&bf->list, &sc->beacon.bbuf);
333 336
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 74a4570dc87f..7f764e3d1c0a 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -378,95 +378,6 @@ static const struct file_operations fops_interrupt = {
378 .owner = THIS_MODULE 378 .owner = THIS_MODULE
379}; 379};
380 380
381void ath_debug_stat_rc(struct ath_softc *sc, int final_rate)
382{
383 struct ath_rc_stats *stats;
384
385 stats = &sc->debug.stats.rcstats[final_rate];
386 stats->success++;
387}
388
389void ath_debug_stat_retries(struct ath_softc *sc, int rix,
390 int xretries, int retries, u8 per)
391{
392 struct ath_rc_stats *stats = &sc->debug.stats.rcstats[rix];
393
394 stats->xretries += xretries;
395 stats->retries += retries;
396 stats->per = per;
397}
398
399static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
400 size_t count, loff_t *ppos)
401{
402 struct ath_softc *sc = file->private_data;
403 char *buf;
404 unsigned int len = 0, max;
405 int i = 0;
406 ssize_t retval;
407
408 if (sc->cur_rate_table == NULL)
409 return 0;
410
411 max = 80 + sc->cur_rate_table->rate_cnt * 1024 + 1;
412 buf = kmalloc(max, GFP_KERNEL);
413 if (buf == NULL)
414 return -ENOMEM;
415
416 len += sprintf(buf, "%6s %6s %6s "
417 "%10s %10s %10s %10s\n",
418 "HT", "MCS", "Rate",
419 "Success", "Retries", "XRetries", "PER");
420
421 for (i = 0; i < sc->cur_rate_table->rate_cnt; i++) {
422 u32 ratekbps = sc->cur_rate_table->info[i].ratekbps;
423 struct ath_rc_stats *stats = &sc->debug.stats.rcstats[i];
424 char mcs[5];
425 char htmode[5];
426 int used_mcs = 0, used_htmode = 0;
427
428 if (WLAN_RC_PHY_HT(sc->cur_rate_table->info[i].phy)) {
429 used_mcs = snprintf(mcs, 5, "%d",
430 sc->cur_rate_table->info[i].ratecode);
431
432 if (WLAN_RC_PHY_40(sc->cur_rate_table->info[i].phy))
433 used_htmode = snprintf(htmode, 5, "HT40");
434 else if (WLAN_RC_PHY_20(sc->cur_rate_table->info[i].phy))
435 used_htmode = snprintf(htmode, 5, "HT20");
436 else
437 used_htmode = snprintf(htmode, 5, "????");
438 }
439
440 mcs[used_mcs] = '\0';
441 htmode[used_htmode] = '\0';
442
443 len += snprintf(buf + len, max - len,
444 "%6s %6s %3u.%d: "
445 "%10u %10u %10u %10u\n",
446 htmode,
447 mcs,
448 ratekbps / 1000,
449 (ratekbps % 1000) / 100,
450 stats->success,
451 stats->retries,
452 stats->xretries,
453 stats->per);
454 }
455
456 if (len > max)
457 len = max;
458
459 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
460 kfree(buf);
461 return retval;
462}
463
464static const struct file_operations fops_rcstat = {
465 .read = read_file_rcstat,
466 .open = ath9k_debugfs_open,
467 .owner = THIS_MODULE
468};
469
470static const char * ath_wiphy_state_str(enum ath_wiphy_state state) 381static const char * ath_wiphy_state_str(enum ath_wiphy_state state)
471{ 382{
472 switch (state) { 383 switch (state) {
@@ -977,10 +888,6 @@ int ath9k_init_debug(struct ath_hw *ah)
977 sc, &fops_interrupt)) 888 sc, &fops_interrupt))
978 goto err; 889 goto err;
979 890
980 if (!debugfs_create_file("rcstat", S_IRUSR, sc->debug.debugfs_phy,
981 sc, &fops_rcstat))
982 goto err;
983
984 if (!debugfs_create_file("wiphy", S_IRUSR | S_IWUSR, 891 if (!debugfs_create_file("wiphy", S_IRUSR | S_IWUSR,
985 sc->debug.debugfs_phy, sc, &fops_wiphy)) 892 sc->debug.debugfs_phy, sc, &fops_wiphy))
986 goto err; 893 goto err;
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index 822b6f3f23c5..bb0823242ba0 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -80,13 +80,6 @@ struct ath_interrupt_stats {
80 u32 bb_watchdog; 80 u32 bb_watchdog;
81}; 81};
82 82
83struct ath_rc_stats {
84 u32 success;
85 u32 retries;
86 u32 xretries;
87 u8 per;
88};
89
90/** 83/**
91 * struct ath_tx_stats - Statistics about TX 84 * struct ath_tx_stats - Statistics about TX
92 * @tx_pkts_all: No. of total frames transmitted, including ones that 85 * @tx_pkts_all: No. of total frames transmitted, including ones that
@@ -160,7 +153,6 @@ struct ath_rx_stats {
160 153
161struct ath_stats { 154struct ath_stats {
162 struct ath_interrupt_stats istats; 155 struct ath_interrupt_stats istats;
163 struct ath_rc_stats rcstats[RATE_TABLE_SIZE];
164 struct ath_tx_stats txstats[ATH9K_NUM_TX_QUEUES]; 156 struct ath_tx_stats txstats[ATH9K_NUM_TX_QUEUES];
165 struct ath_rx_stats rxstats; 157 struct ath_rx_stats rxstats;
166}; 158};
@@ -177,12 +169,9 @@ void ath9k_exit_debug(struct ath_hw *ah);
177int ath9k_debug_create_root(void); 169int ath9k_debug_create_root(void);
178void ath9k_debug_remove_root(void); 170void ath9k_debug_remove_root(void);
179void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status); 171void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
180void ath_debug_stat_rc(struct ath_softc *sc, int final_rate);
181void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq, 172void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq,
182 struct ath_buf *bf, struct ath_tx_status *ts); 173 struct ath_buf *bf, struct ath_tx_status *ts);
183void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs); 174void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs);
184void ath_debug_stat_retries(struct ath_softc *sc, int rix,
185 int xretries, int retries, u8 per);
186 175
187#else 176#else
188 177
@@ -209,11 +198,6 @@ static inline void ath_debug_stat_interrupt(struct ath_softc *sc,
209{ 198{
210} 199}
211 200
212static inline void ath_debug_stat_rc(struct ath_softc *sc,
213 int final_rate)
214{
215}
216
217static inline void ath_debug_stat_tx(struct ath_softc *sc, 201static inline void ath_debug_stat_tx(struct ath_softc *sc,
218 struct ath_txq *txq, 202 struct ath_txq *txq,
219 struct ath_buf *bf, 203 struct ath_buf *bf,
@@ -226,11 +210,6 @@ static inline void ath_debug_stat_rx(struct ath_softc *sc,
226{ 210{
227} 211}
228 212
229static inline void ath_debug_stat_retries(struct ath_softc *sc, int rix,
230 int xretries, int retries, u8 per)
231{
232}
233
234#endif /* CONFIG_ATH9K_DEBUGFS */ 213#endif /* CONFIG_ATH9K_DEBUGFS */
235 214
236#endif /* DEBUG_H */ 215#endif /* DEBUG_H */
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index bbb54bc28a44..3d7b97f1b3ae 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -566,7 +566,7 @@ static void ath9k_init_crypto(struct ath9k_htc_priv *priv)
566 566
567static void ath9k_init_channels_rates(struct ath9k_htc_priv *priv) 567static void ath9k_init_channels_rates(struct ath9k_htc_priv *priv)
568{ 568{
569 if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes)) { 569 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) {
570 priv->sbands[IEEE80211_BAND_2GHZ].channels = 570 priv->sbands[IEEE80211_BAND_2GHZ].channels =
571 ath9k_2ghz_channels; 571 ath9k_2ghz_channels;
572 priv->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ; 572 priv->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
@@ -577,7 +577,7 @@ static void ath9k_init_channels_rates(struct ath9k_htc_priv *priv)
577 ARRAY_SIZE(ath9k_legacy_rates); 577 ARRAY_SIZE(ath9k_legacy_rates);
578 } 578 }
579 579
580 if (test_bit(ATH9K_MODE_11A, priv->ah->caps.wireless_modes)) { 580 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) {
581 priv->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_channels; 581 priv->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_channels;
582 priv->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ; 582 priv->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ;
583 priv->sbands[IEEE80211_BAND_5GHZ].n_channels = 583 priv->sbands[IEEE80211_BAND_5GHZ].n_channels =
@@ -740,18 +740,18 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
740 hw->extra_tx_headroom = sizeof(struct tx_frame_hdr) + 740 hw->extra_tx_headroom = sizeof(struct tx_frame_hdr) +
741 sizeof(struct htc_frame_hdr) + 4; 741 sizeof(struct htc_frame_hdr) + 4;
742 742
743 if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes)) 743 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
744 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = 744 hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
745 &priv->sbands[IEEE80211_BAND_2GHZ]; 745 &priv->sbands[IEEE80211_BAND_2GHZ];
746 if (test_bit(ATH9K_MODE_11A, priv->ah->caps.wireless_modes)) 746 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
747 hw->wiphy->bands[IEEE80211_BAND_5GHZ] = 747 hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
748 &priv->sbands[IEEE80211_BAND_5GHZ]; 748 &priv->sbands[IEEE80211_BAND_5GHZ];
749 749
750 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_HT) { 750 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
751 if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes)) 751 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
752 setup_ht_cap(priv, 752 setup_ht_cap(priv,
753 &priv->sbands[IEEE80211_BAND_2GHZ].ht_cap); 753 &priv->sbands[IEEE80211_BAND_2GHZ].ht_cap);
754 if (test_bit(ATH9K_MODE_11A, priv->ah->caps.wireless_modes)) 754 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
755 setup_ht_cap(priv, 755 setup_ht_cap(priv,
756 &priv->sbands[IEEE80211_BAND_5GHZ].ht_cap); 756 &priv->sbands[IEEE80211_BAND_5GHZ].ht_cap);
757 } 757 }
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index f12591f5d02a..55c80866dfc6 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -1454,6 +1454,7 @@ out:
1454 FIF_PSPOLL | \ 1454 FIF_PSPOLL | \
1455 FIF_OTHER_BSS | \ 1455 FIF_OTHER_BSS | \
1456 FIF_BCN_PRBRESP_PROMISC | \ 1456 FIF_BCN_PRBRESP_PROMISC | \
1457 FIF_PROBE_REQ | \
1457 FIF_FCSFAIL) 1458 FIF_FCSFAIL)
1458 1459
1459static void ath9k_htc_configure_filter(struct ieee80211_hw *hw, 1460static void ath9k_htc_configure_filter(struct ieee80211_hw *hw,
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
index c99600aff76d..3d19b5bc937f 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
@@ -369,8 +369,7 @@ u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv)
369 | ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST 369 | ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST
370 | ATH9K_RX_FILTER_MCAST; 370 | ATH9K_RX_FILTER_MCAST;
371 371
372 /* If not a STA, enable processing of Probe Requests */ 372 if (priv->rxfilter & FIF_PROBE_REQ)
373 if (ah->opmode != NL80211_IFTYPE_STATION)
374 rfilt |= ATH9K_RX_FILTER_PROBEREQ; 373 rfilt |= ATH9K_RX_FILTER_PROBEREQ;
375 374
376 /* 375 /*
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 05e9935ef160..cc13ee117823 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -88,29 +88,32 @@ static void ath9k_hw_ani_cache_ini_regs(struct ath_hw *ah)
88/* Helper Functions */ 88/* Helper Functions */
89/********************/ 89/********************/
90 90
91static u32 ath9k_hw_mac_clks(struct ath_hw *ah, u32 usecs) 91static void ath9k_hw_set_clockrate(struct ath_hw *ah)
92{ 92{
93 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; 93 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
94 struct ath_common *common = ath9k_hw_common(ah);
95 unsigned int clockrate;
94 96
95 if (!ah->curchan) /* should really check for CCK instead */ 97 if (!ah->curchan) /* should really check for CCK instead */
96 return usecs *ATH9K_CLOCK_RATE_CCK; 98 clockrate = ATH9K_CLOCK_RATE_CCK;
97 if (conf->channel->band == IEEE80211_BAND_2GHZ) 99 else if (conf->channel->band == IEEE80211_BAND_2GHZ)
98 return usecs *ATH9K_CLOCK_RATE_2GHZ_OFDM; 100 clockrate = ATH9K_CLOCK_RATE_2GHZ_OFDM;
99 101 else if (ah->caps.hw_caps & ATH9K_HW_CAP_FASTCLOCK)
100 if (ah->caps.hw_caps & ATH9K_HW_CAP_FASTCLOCK) 102 clockrate = ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM;
101 return usecs * ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM;
102 else 103 else
103 return usecs * ATH9K_CLOCK_RATE_5GHZ_OFDM; 104 clockrate = ATH9K_CLOCK_RATE_5GHZ_OFDM;
105
106 if (conf_is_ht40(conf))
107 clockrate *= 2;
108
109 common->clockrate = clockrate;
104} 110}
105 111
106static u32 ath9k_hw_mac_to_clks(struct ath_hw *ah, u32 usecs) 112static u32 ath9k_hw_mac_to_clks(struct ath_hw *ah, u32 usecs)
107{ 113{
108 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; 114 struct ath_common *common = ath9k_hw_common(ah);
109 115
110 if (conf_is_ht40(conf)) 116 return usecs * common->clockrate;
111 return ath9k_hw_mac_clks(ah, usecs) * 2;
112 else
113 return ath9k_hw_mac_clks(ah, usecs);
114} 117}
115 118
116bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout) 119bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout)
@@ -1156,6 +1159,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
1156 "Failed to set channel\n"); 1159 "Failed to set channel\n");
1157 return false; 1160 return false;
1158 } 1161 }
1162 ath9k_hw_set_clockrate(ah);
1159 1163
1160 ah->eep_ops->set_txpower(ah, chan, 1164 ah->eep_ops->set_txpower(ah, chan,
1161 ath9k_regd_get_ctl(regulatory, chan), 1165 ath9k_regd_get_ctl(regulatory, chan),
@@ -1368,6 +1372,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1368 if (r) 1372 if (r)
1369 return r; 1373 return r;
1370 1374
1375 ath9k_hw_set_clockrate(ah);
1376
1371 ENABLE_REGWRITE_BUFFER(ah); 1377 ENABLE_REGWRITE_BUFFER(ah);
1372 1378
1373 for (i = 0; i < AR_NUM_DCU; i++) 1379 for (i = 0; i < AR_NUM_DCU; i++)
@@ -1794,37 +1800,11 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
1794 return -EINVAL; 1800 return -EINVAL;
1795 } 1801 }
1796 1802
1797 bitmap_zero(pCap->wireless_modes, ATH9K_MODE_MAX); 1803 if (eeval & AR5416_OPFLAGS_11A)
1798 1804 pCap->hw_caps |= ATH9K_HW_CAP_5GHZ;
1799 if (eeval & AR5416_OPFLAGS_11A) {
1800 set_bit(ATH9K_MODE_11A, pCap->wireless_modes);
1801 if (ah->config.ht_enable) {
1802 if (!(eeval & AR5416_OPFLAGS_N_5G_HT20))
1803 set_bit(ATH9K_MODE_11NA_HT20,
1804 pCap->wireless_modes);
1805 if (!(eeval & AR5416_OPFLAGS_N_5G_HT40)) {
1806 set_bit(ATH9K_MODE_11NA_HT40PLUS,
1807 pCap->wireless_modes);
1808 set_bit(ATH9K_MODE_11NA_HT40MINUS,
1809 pCap->wireless_modes);
1810 }
1811 }
1812 }
1813 1805
1814 if (eeval & AR5416_OPFLAGS_11G) { 1806 if (eeval & AR5416_OPFLAGS_11G)
1815 set_bit(ATH9K_MODE_11G, pCap->wireless_modes); 1807 pCap->hw_caps |= ATH9K_HW_CAP_2GHZ;
1816 if (ah->config.ht_enable) {
1817 if (!(eeval & AR5416_OPFLAGS_N_2G_HT20))
1818 set_bit(ATH9K_MODE_11NG_HT20,
1819 pCap->wireless_modes);
1820 if (!(eeval & AR5416_OPFLAGS_N_2G_HT40)) {
1821 set_bit(ATH9K_MODE_11NG_HT40PLUS,
1822 pCap->wireless_modes);
1823 set_bit(ATH9K_MODE_11NG_HT40MINUS,
1824 pCap->wireless_modes);
1825 }
1826 }
1827 }
1828 1808
1829 pCap->tx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_TX_MASK); 1809 pCap->tx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_TX_MASK);
1830 /* 1810 /*
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 87627dd63463..d032939768b0 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -61,6 +61,8 @@
61 61
62#define ATH9K_RSSI_BAD -128 62#define ATH9K_RSSI_BAD -128
63 63
64#define ATH9K_NUM_CHANNELS 38
65
64/* Register read/write primitives */ 66/* Register read/write primitives */
65#define REG_WRITE(_ah, _reg, _val) \ 67#define REG_WRITE(_ah, _reg, _val) \
66 ath9k_hw_common(_ah)->ops->write((_ah), (_val), (_reg)) 68 ath9k_hw_common(_ah)->ops->write((_ah), (_val), (_reg))
@@ -162,18 +164,6 @@ enum ath_ini_subsys {
162 ATH_INI_NUM_SPLIT, 164 ATH_INI_NUM_SPLIT,
163}; 165};
164 166
165enum wireless_mode {
166 ATH9K_MODE_11A = 0,
167 ATH9K_MODE_11G,
168 ATH9K_MODE_11NA_HT20,
169 ATH9K_MODE_11NG_HT20,
170 ATH9K_MODE_11NA_HT40PLUS,
171 ATH9K_MODE_11NA_HT40MINUS,
172 ATH9K_MODE_11NG_HT40PLUS,
173 ATH9K_MODE_11NG_HT40MINUS,
174 ATH9K_MODE_MAX,
175};
176
177enum ath9k_hw_caps { 167enum ath9k_hw_caps {
178 ATH9K_HW_CAP_HT = BIT(0), 168 ATH9K_HW_CAP_HT = BIT(0),
179 ATH9K_HW_CAP_RFSILENT = BIT(1), 169 ATH9K_HW_CAP_RFSILENT = BIT(1),
@@ -188,11 +178,12 @@ enum ath9k_hw_caps {
188 ATH9K_HW_CAP_SGI_20 = BIT(10), 178 ATH9K_HW_CAP_SGI_20 = BIT(10),
189 ATH9K_HW_CAP_PAPRD = BIT(11), 179 ATH9K_HW_CAP_PAPRD = BIT(11),
190 ATH9K_HW_CAP_ANT_DIV_COMB = BIT(12), 180 ATH9K_HW_CAP_ANT_DIV_COMB = BIT(12),
181 ATH9K_HW_CAP_2GHZ = BIT(13),
182 ATH9K_HW_CAP_5GHZ = BIT(14),
191}; 183};
192 184
193struct ath9k_hw_capabilities { 185struct ath9k_hw_capabilities {
194 u32 hw_caps; /* ATH9K_HW_CAP_* from ath9k_hw_caps */ 186 u32 hw_caps; /* ATH9K_HW_CAP_* from ath9k_hw_caps */
195 DECLARE_BITMAP(wireless_modes, ATH9K_MODE_MAX); /* ATH9K_MODE_* */
196 u16 total_queues; 187 u16 total_queues;
197 u16 keycache_size; 188 u16 keycache_size;
198 u16 low_5ghz_chan, high_5ghz_chan; 189 u16 low_5ghz_chan, high_5ghz_chan;
@@ -618,7 +609,7 @@ struct ath_hw {
618 struct ath9k_hw_version hw_version; 609 struct ath9k_hw_version hw_version;
619 struct ath9k_ops_config config; 610 struct ath9k_ops_config config;
620 struct ath9k_hw_capabilities caps; 611 struct ath9k_hw_capabilities caps;
621 struct ath9k_channel channels[38]; 612 struct ath9k_channel channels[ATH9K_NUM_CHANNELS];
622 struct ath9k_channel *curchan; 613 struct ath9k_channel *curchan;
623 614
624 union { 615 union {
@@ -740,8 +731,6 @@ struct ath_hw {
740 int coarse_low[5]; 731 int coarse_low[5];
741 int firpwr[5]; 732 int firpwr[5];
742 enum ath9k_ani_cmd ani_function; 733 enum ath9k_ani_cmd ani_function;
743 struct ath_cycle_counters cc, cc_delta;
744 int32_t listen_time;
745 734
746 /* Bluetooth coexistance */ 735 /* Bluetooth coexistance */
747 struct ath_btcoex_hw btcoex_hw; 736 struct ath_btcoex_hw btcoex_hw;
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index d76003c06fe4..bc6c4df9712c 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -481,7 +481,11 @@ static int ath9k_init_channels_rates(struct ath_softc *sc)
481{ 481{
482 void *channels; 482 void *channels;
483 483
484 if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) { 484 BUILD_BUG_ON(ARRAY_SIZE(ath9k_2ghz_chantable) +
485 ARRAY_SIZE(ath9k_5ghz_chantable) !=
486 ATH9K_NUM_CHANNELS);
487
488 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) {
485 channels = kmemdup(ath9k_2ghz_chantable, 489 channels = kmemdup(ath9k_2ghz_chantable,
486 sizeof(ath9k_2ghz_chantable), GFP_KERNEL); 490 sizeof(ath9k_2ghz_chantable), GFP_KERNEL);
487 if (!channels) 491 if (!channels)
@@ -496,7 +500,7 @@ static int ath9k_init_channels_rates(struct ath_softc *sc)
496 ARRAY_SIZE(ath9k_legacy_rates); 500 ARRAY_SIZE(ath9k_legacy_rates);
497 } 501 }
498 502
499 if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) { 503 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) {
500 channels = kmemdup(ath9k_5ghz_chantable, 504 channels = kmemdup(ath9k_5ghz_chantable,
501 sizeof(ath9k_5ghz_chantable), GFP_KERNEL); 505 sizeof(ath9k_5ghz_chantable), GFP_KERNEL);
502 if (!channels) { 506 if (!channels) {
@@ -677,17 +681,17 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
677 hw->rate_control_algorithm = "ath9k_rate_control"; 681 hw->rate_control_algorithm = "ath9k_rate_control";
678#endif 682#endif
679 683
680 if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) 684 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
681 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = 685 hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
682 &sc->sbands[IEEE80211_BAND_2GHZ]; 686 &sc->sbands[IEEE80211_BAND_2GHZ];
683 if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) 687 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
684 hw->wiphy->bands[IEEE80211_BAND_5GHZ] = 688 hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
685 &sc->sbands[IEEE80211_BAND_5GHZ]; 689 &sc->sbands[IEEE80211_BAND_5GHZ];
686 690
687 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) { 691 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
688 if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) 692 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
689 setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap); 693 setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap);
690 if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) 694 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
691 setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap); 695 setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap);
692 } 696 }
693 697
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 74c2dc8a8b8a..3ff0e476c2b3 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -18,36 +18,6 @@
18#include "ath9k.h" 18#include "ath9k.h"
19#include "btcoex.h" 19#include "btcoex.h"
20 20
21static void ath_cache_conf_rate(struct ath_softc *sc,
22 struct ieee80211_conf *conf)
23{
24 switch (conf->channel->band) {
25 case IEEE80211_BAND_2GHZ:
26 if (conf_is_ht20(conf))
27 sc->cur_rate_mode = ATH9K_MODE_11NG_HT20;
28 else if (conf_is_ht40_minus(conf))
29 sc->cur_rate_mode = ATH9K_MODE_11NG_HT40MINUS;
30 else if (conf_is_ht40_plus(conf))
31 sc->cur_rate_mode = ATH9K_MODE_11NG_HT40PLUS;
32 else
33 sc->cur_rate_mode = ATH9K_MODE_11G;
34 break;
35 case IEEE80211_BAND_5GHZ:
36 if (conf_is_ht20(conf))
37 sc->cur_rate_mode = ATH9K_MODE_11NA_HT20;
38 else if (conf_is_ht40_minus(conf))
39 sc->cur_rate_mode = ATH9K_MODE_11NA_HT40MINUS;
40 else if (conf_is_ht40_plus(conf))
41 sc->cur_rate_mode = ATH9K_MODE_11NA_HT40PLUS;
42 else
43 sc->cur_rate_mode = ATH9K_MODE_11A;
44 break;
45 default:
46 BUG_ON(1);
47 break;
48 }
49}
50
51static void ath_update_txpow(struct ath_softc *sc) 21static void ath_update_txpow(struct ath_softc *sc)
52{ 22{
53 struct ath_hw *ah = sc->sc_ah; 23 struct ath_hw *ah = sc->sc_ah;
@@ -121,6 +91,7 @@ bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode)
121 91
122void ath9k_ps_wakeup(struct ath_softc *sc) 92void ath9k_ps_wakeup(struct ath_softc *sc)
123{ 93{
94 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
124 unsigned long flags; 95 unsigned long flags;
125 96
126 spin_lock_irqsave(&sc->sc_pm_lock, flags); 97 spin_lock_irqsave(&sc->sc_pm_lock, flags);
@@ -129,18 +100,33 @@ void ath9k_ps_wakeup(struct ath_softc *sc)
129 100
130 ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE); 101 ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
131 102
103 /*
104 * While the hardware is asleep, the cycle counters contain no
105 * useful data. Better clear them now so that they don't mess up
106 * survey data results.
107 */
108 spin_lock(&common->cc_lock);
109 ath_hw_cycle_counters_update(common);
110 memset(&common->cc_survey, 0, sizeof(common->cc_survey));
111 spin_unlock(&common->cc_lock);
112
132 unlock: 113 unlock:
133 spin_unlock_irqrestore(&sc->sc_pm_lock, flags); 114 spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
134} 115}
135 116
136void ath9k_ps_restore(struct ath_softc *sc) 117void ath9k_ps_restore(struct ath_softc *sc)
137{ 118{
119 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
138 unsigned long flags; 120 unsigned long flags;
139 121
140 spin_lock_irqsave(&sc->sc_pm_lock, flags); 122 spin_lock_irqsave(&sc->sc_pm_lock, flags);
141 if (--sc->ps_usecount != 0) 123 if (--sc->ps_usecount != 0)
142 goto unlock; 124 goto unlock;
143 125
126 spin_lock(&common->cc_lock);
127 ath_hw_cycle_counters_update(common);
128 spin_unlock(&common->cc_lock);
129
144 if (sc->ps_idle) 130 if (sc->ps_idle)
145 ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP); 131 ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP);
146 else if (sc->ps_enabled && 132 else if (sc->ps_enabled &&
@@ -175,6 +161,45 @@ static void ath_start_ani(struct ath_common *common)
175 msecs_to_jiffies((u32)ah->config.ani_poll_interval)); 161 msecs_to_jiffies((u32)ah->config.ani_poll_interval));
176} 162}
177 163
164static void ath_update_survey_nf(struct ath_softc *sc, int channel)
165{
166 struct ath_hw *ah = sc->sc_ah;
167 struct ath9k_channel *chan = &ah->channels[channel];
168 struct survey_info *survey = &sc->survey[channel];
169
170 if (chan->noisefloor) {
171 survey->filled |= SURVEY_INFO_NOISE_DBM;
172 survey->noise = chan->noisefloor;
173 }
174}
175
176static void ath_update_survey_stats(struct ath_softc *sc)
177{
178 struct ath_hw *ah = sc->sc_ah;
179 struct ath_common *common = ath9k_hw_common(ah);
180 int pos = ah->curchan - &ah->channels[0];
181 struct survey_info *survey = &sc->survey[pos];
182 struct ath_cycle_counters *cc = &common->cc_survey;
183 unsigned int div = common->clockrate * 1000;
184
185 if (ah->power_mode == ATH9K_PM_AWAKE)
186 ath_hw_cycle_counters_update(common);
187
188 if (cc->cycles > 0) {
189 survey->filled |= SURVEY_INFO_CHANNEL_TIME |
190 SURVEY_INFO_CHANNEL_TIME_BUSY |
191 SURVEY_INFO_CHANNEL_TIME_RX |
192 SURVEY_INFO_CHANNEL_TIME_TX;
193 survey->channel_time += cc->cycles / div;
194 survey->channel_time_busy += cc->rx_busy / div;
195 survey->channel_time_rx += cc->rx_frame / div;
196 survey->channel_time_tx += cc->tx_frame / div;
197 }
198 memset(cc, 0, sizeof(*cc));
199
200 ath_update_survey_nf(sc, pos);
201}
202
178/* 203/*
179 * Set/change channels. If the channel is really being changed, it's done 204 * Set/change channels. If the channel is really being changed, it's done
180 * by reseting the chip. To accomplish this we must first cleanup any pending 205 * by reseting the chip. To accomplish this we must first cleanup any pending
@@ -251,7 +276,6 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
251 goto ps_restore; 276 goto ps_restore;
252 } 277 }
253 278
254 ath_cache_conf_rate(sc, &hw->conf);
255 ath_update_txpow(sc); 279 ath_update_txpow(sc);
256 ath9k_hw_set_interrupts(ah, ah->imask); 280 ath9k_hw_set_interrupts(ah, ah->imask);
257 281
@@ -399,6 +423,7 @@ void ath_ani_calibrate(unsigned long data)
399 bool aniflag = false; 423 bool aniflag = false;
400 unsigned int timestamp = jiffies_to_msecs(jiffies); 424 unsigned int timestamp = jiffies_to_msecs(jiffies);
401 u32 cal_interval, short_cal_interval, long_cal_interval; 425 u32 cal_interval, short_cal_interval, long_cal_interval;
426 unsigned long flags;
402 427
403 if (ah->caldata && ah->caldata->nfcal_interference) 428 if (ah->caldata && ah->caldata->nfcal_interference)
404 long_cal_interval = ATH_LONG_CALINTERVAL_INT; 429 long_cal_interval = ATH_LONG_CALINTERVAL_INT;
@@ -449,8 +474,12 @@ void ath_ani_calibrate(unsigned long data)
449 /* Skip all processing if there's nothing to do. */ 474 /* Skip all processing if there's nothing to do. */
450 if (longcal || shortcal || aniflag) { 475 if (longcal || shortcal || aniflag) {
451 /* Call ANI routine if necessary */ 476 /* Call ANI routine if necessary */
452 if (aniflag) 477 if (aniflag) {
478 spin_lock_irqsave(&common->cc_lock, flags);
453 ath9k_hw_ani_monitor(ah, ah->curchan); 479 ath9k_hw_ani_monitor(ah, ah->curchan);
480 ath_update_survey_stats(sc);
481 spin_unlock_irqrestore(&common->cc_lock, flags);
482 }
454 483
455 /* Perform calibration if necessary */ 484 /* Perform calibration if necessary */
456 if (longcal || shortcal) { 485 if (longcal || shortcal) {
@@ -635,6 +664,7 @@ irqreturn_t ath_isr(int irq, void *dev)
635 664
636 struct ath_softc *sc = dev; 665 struct ath_softc *sc = dev;
637 struct ath_hw *ah = sc->sc_ah; 666 struct ath_hw *ah = sc->sc_ah;
667 struct ath_common *common = ath9k_hw_common(ah);
638 enum ath9k_int status; 668 enum ath9k_int status;
639 bool sched = false; 669 bool sched = false;
640 670
@@ -684,7 +714,12 @@ irqreturn_t ath_isr(int irq, void *dev)
684 714
685 if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) && 715 if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) &&
686 (status & ATH9K_INT_BB_WATCHDOG)) { 716 (status & ATH9K_INT_BB_WATCHDOG)) {
717
718 spin_lock(&common->cc_lock);
719 ath_hw_cycle_counters_update(common);
687 ar9003_hw_bb_watchdog_dbg_info(ah); 720 ar9003_hw_bb_watchdog_dbg_info(ah);
721 spin_unlock(&common->cc_lock);
722
688 goto chip_reset; 723 goto chip_reset;
689 } 724 }
690 725
@@ -713,7 +748,9 @@ irqreturn_t ath_isr(int irq, void *dev)
713 * it will clear whatever condition caused 748 * it will clear whatever condition caused
714 * the interrupt. 749 * the interrupt.
715 */ 750 */
751 spin_lock(&common->cc_lock);
716 ath9k_hw_proc_mib_event(ah); 752 ath9k_hw_proc_mib_event(ah);
753 spin_unlock(&common->cc_lock);
717 ath9k_hw_set_interrupts(ah, ah->imask); 754 ath9k_hw_set_interrupts(ah, ah->imask);
718 } 755 }
719 756
@@ -945,8 +982,6 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
945 * that changes the channel so update any state that 982 * that changes the channel so update any state that
946 * might change as a result. 983 * might change as a result.
947 */ 984 */
948 ath_cache_conf_rate(sc, &hw->conf);
949
950 ath_update_txpow(sc); 985 ath_update_txpow(sc);
951 986
952 if ((sc->sc_flags & SC_OP_BEACONS) || !(sc->sc_flags & (SC_OP_OFFCHANNEL))) 987 if ((sc->sc_flags & SC_OP_BEACONS) || !(sc->sc_flags & (SC_OP_OFFCHANNEL)))
@@ -1153,8 +1188,6 @@ static int ath9k_start(struct ieee80211_hw *hw)
1153 if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) 1188 if (ah->caps.hw_caps & ATH9K_HW_CAP_HT)
1154 ah->imask |= ATH9K_INT_CST; 1189 ah->imask |= ATH9K_INT_CST;
1155 1190
1156 ath_cache_conf_rate(sc, &hw->conf);
1157
1158 sc->sc_flags &= ~SC_OP_INVALID; 1191 sc->sc_flags &= ~SC_OP_INVALID;
1159 1192
1160 /* Disable BMISS interrupt when we're not associated */ 1193 /* Disable BMISS interrupt when we're not associated */
@@ -1522,7 +1555,8 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
1522{ 1555{
1523 struct ath_wiphy *aphy = hw->priv; 1556 struct ath_wiphy *aphy = hw->priv;
1524 struct ath_softc *sc = aphy->sc; 1557 struct ath_softc *sc = aphy->sc;
1525 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 1558 struct ath_hw *ah = sc->sc_ah;
1559 struct ath_common *common = ath9k_hw_common(ah);
1526 struct ieee80211_conf *conf = &hw->conf; 1560 struct ieee80211_conf *conf = &hw->conf;
1527 bool disable_radio; 1561 bool disable_radio;
1528 1562
@@ -1588,6 +1622,11 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
1588 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { 1622 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
1589 struct ieee80211_channel *curchan = hw->conf.channel; 1623 struct ieee80211_channel *curchan = hw->conf.channel;
1590 int pos = curchan->hw_value; 1624 int pos = curchan->hw_value;
1625 int old_pos = -1;
1626 unsigned long flags;
1627
1628 if (ah->curchan)
1629 old_pos = ah->curchan - &ah->channels[0];
1591 1630
1592 aphy->chan_idx = pos; 1631 aphy->chan_idx = pos;
1593 aphy->chan_is_ht = conf_is_ht(conf); 1632 aphy->chan_is_ht = conf_is_ht(conf);
@@ -1615,12 +1654,45 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
1615 1654
1616 ath_update_chainmask(sc, conf_is_ht(conf)); 1655 ath_update_chainmask(sc, conf_is_ht(conf));
1617 1656
1657 /* update survey stats for the old channel before switching */
1658 spin_lock_irqsave(&common->cc_lock, flags);
1659 ath_update_survey_stats(sc);
1660 spin_unlock_irqrestore(&common->cc_lock, flags);
1661
1662 /*
1663 * If the operating channel changes, change the survey in-use flags
1664 * along with it.
1665 * Reset the survey data for the new channel, unless we're switching
1666 * back to the operating channel from an off-channel operation.
1667 */
1668 if (!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) &&
1669 sc->cur_survey != &sc->survey[pos]) {
1670
1671 if (sc->cur_survey)
1672 sc->cur_survey->filled &= ~SURVEY_INFO_IN_USE;
1673
1674 sc->cur_survey = &sc->survey[pos];
1675
1676 memset(sc->cur_survey, 0, sizeof(struct survey_info));
1677 sc->cur_survey->filled |= SURVEY_INFO_IN_USE;
1678 } else if (!(sc->survey[pos].filled & SURVEY_INFO_IN_USE)) {
1679 memset(&sc->survey[pos], 0, sizeof(struct survey_info));
1680 }
1681
1618 if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) { 1682 if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) {
1619 ath_print(common, ATH_DBG_FATAL, 1683 ath_print(common, ATH_DBG_FATAL,
1620 "Unable to set channel\n"); 1684 "Unable to set channel\n");
1621 mutex_unlock(&sc->mutex); 1685 mutex_unlock(&sc->mutex);
1622 return -EINVAL; 1686 return -EINVAL;
1623 } 1687 }
1688
1689 /*
1690 * The most recent snapshot of channel->noisefloor for the old
1691 * channel is only available after the hardware reset. Copy it to
1692 * the survey stats now.
1693 */
1694 if (old_pos >= 0)
1695 ath_update_survey_nf(sc, old_pos);
1624 } 1696 }
1625 1697
1626skip_chan_change: 1698skip_chan_change:
@@ -1651,6 +1723,7 @@ skip_chan_change:
1651 FIF_PSPOLL | \ 1723 FIF_PSPOLL | \
1652 FIF_OTHER_BSS | \ 1724 FIF_OTHER_BSS | \
1653 FIF_BCN_PRBRESP_PROMISC | \ 1725 FIF_BCN_PRBRESP_PROMISC | \
1726 FIF_PROBE_REQ | \
1654 FIF_FCSFAIL) 1727 FIF_FCSFAIL)
1655 1728
1656/* FIXME: sc->sc_full_reset ? */ 1729/* FIXME: sc->sc_full_reset ? */
@@ -1990,9 +2063,15 @@ static int ath9k_get_survey(struct ieee80211_hw *hw, int idx,
1990{ 2063{
1991 struct ath_wiphy *aphy = hw->priv; 2064 struct ath_wiphy *aphy = hw->priv;
1992 struct ath_softc *sc = aphy->sc; 2065 struct ath_softc *sc = aphy->sc;
1993 struct ath_hw *ah = sc->sc_ah; 2066 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1994 struct ieee80211_supported_band *sband; 2067 struct ieee80211_supported_band *sband;
1995 struct ath9k_channel *chan; 2068 struct ieee80211_channel *chan;
2069 unsigned long flags;
2070 int pos;
2071
2072 spin_lock_irqsave(&common->cc_lock, flags);
2073 if (idx == 0)
2074 ath_update_survey_stats(sc);
1996 2075
1997 sband = hw->wiphy->bands[IEEE80211_BAND_2GHZ]; 2076 sband = hw->wiphy->bands[IEEE80211_BAND_2GHZ];
1998 if (sband && idx >= sband->n_channels) { 2077 if (sband && idx >= sband->n_channels) {
@@ -2003,21 +2082,17 @@ static int ath9k_get_survey(struct ieee80211_hw *hw, int idx,
2003 if (!sband) 2082 if (!sband)
2004 sband = hw->wiphy->bands[IEEE80211_BAND_5GHZ]; 2083 sband = hw->wiphy->bands[IEEE80211_BAND_5GHZ];
2005 2084
2006 if (!sband || idx >= sband->n_channels) 2085 if (!sband || idx >= sband->n_channels) {
2007 return -ENOENT; 2086 spin_unlock_irqrestore(&common->cc_lock, flags);
2008 2087 return -ENOENT;
2009 survey->channel = &sband->channels[idx];
2010 chan = &ah->channels[survey->channel->hw_value];
2011 survey->filled = 0;
2012
2013 if (chan == ah->curchan)
2014 survey->filled |= SURVEY_INFO_IN_USE;
2015
2016 if (chan->noisefloor) {
2017 survey->filled |= SURVEY_INFO_NOISE_DBM;
2018 survey->noise = chan->noisefloor;
2019 } 2088 }
2020 2089
2090 chan = &sband->channels[idx];
2091 pos = chan->hw_value;
2092 memcpy(survey, &sc->survey[pos], sizeof(*survey));
2093 survey->channel = chan;
2094 spin_unlock_irqrestore(&common->cc_lock, flags);
2095
2021 return 0; 2096 return 0;
2022} 2097}
2023 2098
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index ce1cd6d85847..0cee90cf8dc9 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -302,7 +302,7 @@ static const struct ath_rate_table ar5416_11ng_ratetable = {
302 [64] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 243000, 302 [64] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 243000,
303 205100, 20, 20, 8, 64, 65, 65 }, /* 243 Mb */ 303 205100, 20, 20, 8, 64, 65, 65 }, /* 243 Mb */
304 [65] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS_HGI, 270000, 304 [65] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS_HGI, 270000,
305 224700, 20, 20, 8, 64, 65, 65 }, /* 170 Mb */ 305 224700, 20, 20, 8, 64, 65, 65 }, /* 270 Mb */
306 [66] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 324000, 306 [66] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 324000,
307 263100, 21, 21, 8, 66, 67, 67 }, /* 324 Mb */ 307 263100, 21, 21, 8, 66, 67, 67 }, /* 324 Mb */
308 [67] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 360000, 308 [67] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 360000,
@@ -378,17 +378,6 @@ static const struct ath_rate_table ar5416_11g_ratetable = {
378 0, /* Phy rates allowed initially */ 378 0, /* Phy rates allowed initially */
379}; 379};
380 380
381static const struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX] = {
382 [ATH9K_MODE_11A] = &ar5416_11a_ratetable,
383 [ATH9K_MODE_11G] = &ar5416_11g_ratetable,
384 [ATH9K_MODE_11NA_HT20] = &ar5416_11na_ratetable,
385 [ATH9K_MODE_11NG_HT20] = &ar5416_11ng_ratetable,
386 [ATH9K_MODE_11NA_HT40PLUS] = &ar5416_11na_ratetable,
387 [ATH9K_MODE_11NA_HT40MINUS] = &ar5416_11na_ratetable,
388 [ATH9K_MODE_11NG_HT40PLUS] = &ar5416_11ng_ratetable,
389 [ATH9K_MODE_11NG_HT40MINUS] = &ar5416_11ng_ratetable,
390};
391
392static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table, 381static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table,
393 struct ieee80211_tx_rate *rate); 382 struct ieee80211_tx_rate *rate);
394 383
@@ -791,7 +780,7 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
791 */ 780 */
792 try_per_rate = 4; 781 try_per_rate = 4;
793 782
794 rate_table = sc->cur_rate_table; 783 rate_table = ath_rc_priv->rate_table;
795 rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe); 784 rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe);
796 785
797 /* 786 /*
@@ -1026,6 +1015,16 @@ static bool ath_rc_update_per(struct ath_softc *sc,
1026 return state_change; 1015 return state_change;
1027} 1016}
1028 1017
1018static void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix,
1019 int xretries, int retries, u8 per)
1020{
1021 struct ath_rc_stats *stats = &rc->rcstats[rix];
1022
1023 stats->xretries += xretries;
1024 stats->retries += retries;
1025 stats->per = per;
1026}
1027
1029/* Update PER, RSSI and whatever else that the code thinks it is doing. 1028/* Update PER, RSSI and whatever else that the code thinks it is doing.
1030 If you can make sense of all this, you really need to go out more. */ 1029 If you can make sense of all this, you really need to go out more. */
1031 1030
@@ -1038,7 +1037,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
1038 int rate; 1037 int rate;
1039 u8 last_per; 1038 u8 last_per;
1040 bool state_change = false; 1039 bool state_change = false;
1041 const struct ath_rate_table *rate_table = sc->cur_rate_table; 1040 const struct ath_rate_table *rate_table = ath_rc_priv->rate_table;
1042 int size = ath_rc_priv->rate_table_size; 1041 int size = ath_rc_priv->rate_table_size;
1043 1042
1044 if ((tx_rate < 0) || (tx_rate > rate_table->rate_cnt)) 1043 if ((tx_rate < 0) || (tx_rate > rate_table->rate_cnt))
@@ -1098,7 +1097,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
1098 ath_rc_priv->per_down_time = now_msec; 1097 ath_rc_priv->per_down_time = now_msec;
1099 } 1098 }
1100 1099
1101 ath_debug_stat_retries(sc, tx_rate, xretries, retries, 1100 ath_debug_stat_retries(ath_rc_priv, tx_rate, xretries, retries,
1102 ath_rc_priv->per[tx_rate]); 1101 ath_rc_priv->per[tx_rate]);
1103 1102
1104} 1103}
@@ -1140,7 +1139,7 @@ static void ath_rc_tx_status(struct ath_softc *sc,
1140 u8 flags; 1139 u8 flags;
1141 u32 i = 0, rix; 1140 u32 i = 0, rix;
1142 1141
1143 rate_table = sc->cur_rate_table; 1142 rate_table = ath_rc_priv->rate_table;
1144 1143
1145 /* 1144 /*
1146 * If the first rate is not the final index, there 1145 * If the first rate is not the final index, there
@@ -1190,39 +1189,23 @@ static void ath_rc_tx_status(struct ath_softc *sc,
1190static const 1189static const
1191struct ath_rate_table *ath_choose_rate_table(struct ath_softc *sc, 1190struct ath_rate_table *ath_choose_rate_table(struct ath_softc *sc,
1192 enum ieee80211_band band, 1191 enum ieee80211_band band,
1193 bool is_ht, 1192 bool is_ht)
1194 bool is_cw_40)
1195{ 1193{
1196 int mode = 0;
1197 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 1194 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1198 1195
1199 switch(band) { 1196 switch(band) {
1200 case IEEE80211_BAND_2GHZ: 1197 case IEEE80211_BAND_2GHZ:
1201 mode = ATH9K_MODE_11G;
1202 if (is_ht) 1198 if (is_ht)
1203 mode = ATH9K_MODE_11NG_HT20; 1199 return &ar5416_11ng_ratetable;
1204 if (is_cw_40) 1200 return &ar5416_11g_ratetable;
1205 mode = ATH9K_MODE_11NG_HT40PLUS;
1206 break;
1207 case IEEE80211_BAND_5GHZ: 1201 case IEEE80211_BAND_5GHZ:
1208 mode = ATH9K_MODE_11A;
1209 if (is_ht) 1202 if (is_ht)
1210 mode = ATH9K_MODE_11NA_HT20; 1203 return &ar5416_11na_ratetable;
1211 if (is_cw_40) 1204 return &ar5416_11a_ratetable;
1212 mode = ATH9K_MODE_11NA_HT40PLUS;
1213 break;
1214 default: 1205 default:
1215 ath_print(common, ATH_DBG_CONFIG, "Invalid band\n"); 1206 ath_print(common, ATH_DBG_CONFIG, "Invalid band\n");
1216 return NULL; 1207 return NULL;
1217 } 1208 }
1218
1219 BUG_ON(mode >= ATH9K_MODE_MAX);
1220
1221 ath_print(common, ATH_DBG_CONFIG,
1222 "Choosing rate table for mode: %d\n", mode);
1223
1224 sc->cur_rate_mode = mode;
1225 return hw_rate_table[mode];
1226} 1209}
1227 1210
1228static void ath_rc_init(struct ath_softc *sc, 1211static void ath_rc_init(struct ath_softc *sc,
@@ -1293,7 +1276,7 @@ static void ath_rc_init(struct ath_softc *sc,
1293 ath_rc_priv->max_valid_rate = k; 1276 ath_rc_priv->max_valid_rate = k;
1294 ath_rc_sort_validrates(rate_table, ath_rc_priv); 1277 ath_rc_sort_validrates(rate_table, ath_rc_priv);
1295 ath_rc_priv->rate_max_phy = ath_rc_priv->valid_rate_index[k-4]; 1278 ath_rc_priv->rate_max_phy = ath_rc_priv->valid_rate_index[k-4];
1296 sc->cur_rate_table = rate_table; 1279 ath_rc_priv->rate_table = rate_table;
1297 1280
1298 ath_print(common, ATH_DBG_CONFIG, 1281 ath_print(common, ATH_DBG_CONFIG,
1299 "RC Initialized with capabilities: 0x%x\n", 1282 "RC Initialized with capabilities: 0x%x\n",
@@ -1340,6 +1323,15 @@ static bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an,
1340/* mac80211 Rate Control callbacks */ 1323/* mac80211 Rate Control callbacks */
1341/***********************************/ 1324/***********************************/
1342 1325
1326static void ath_debug_stat_rc(struct ath_rate_priv *rc, int final_rate)
1327{
1328 struct ath_rc_stats *stats;
1329
1330 stats = &rc->rcstats[final_rate];
1331 stats->success++;
1332}
1333
1334
1343static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, 1335static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
1344 struct ieee80211_sta *sta, void *priv_sta, 1336 struct ieee80211_sta *sta, void *priv_sta,
1345 struct sk_buff *skb) 1337 struct sk_buff *skb)
@@ -1375,6 +1367,12 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
1375 if (tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) 1367 if (tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED)
1376 return; 1368 return;
1377 1369
1370 if (!(tx_info->flags & IEEE80211_TX_STAT_AMPDU)) {
1371 tx_info->status.ampdu_ack_len =
1372 (tx_info->flags & IEEE80211_TX_STAT_ACK ? 1 : 0);
1373 tx_info->status.ampdu_len = 1;
1374 }
1375
1378 /* 1376 /*
1379 * If an underrun error is seen assume it as an excessive retry only 1377 * If an underrun error is seen assume it as an excessive retry only
1380 * if max frame trigger level has been reached (2 KB for singel stream, 1378 * if max frame trigger level has been reached (2 KB for singel stream,
@@ -1413,8 +1411,9 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
1413 } 1411 }
1414 } 1412 }
1415 1413
1416 ath_debug_stat_rc(sc, ath_rc_get_rateindex(sc->cur_rate_table, 1414 ath_debug_stat_rc(ath_rc_priv,
1417 &tx_info->status.rates[final_ts_idx])); 1415 ath_rc_get_rateindex(ath_rc_priv->rate_table,
1416 &tx_info->status.rates[final_ts_idx]));
1418} 1417}
1419 1418
1420static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband, 1419static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
@@ -1454,14 +1453,8 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
1454 1453
1455 /* Choose rate table first */ 1454 /* Choose rate table first */
1456 1455
1457 if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) || 1456 rate_table = ath_choose_rate_table(sc, sband->band,
1458 (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT) || 1457 sta->ht_cap.ht_supported);
1459 (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)) {
1460 rate_table = ath_choose_rate_table(sc, sband->band,
1461 sta->ht_cap.ht_supported, is_cw40);
1462 } else {
1463 rate_table = hw_rate_table[sc->cur_rate_mode];
1464 }
1465 1458
1466 ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta, is_cw40, is_sgi); 1459 ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta, is_cw40, is_sgi);
1467 ath_rc_init(sc, priv_sta, sband, sta, rate_table); 1460 ath_rc_init(sc, priv_sta, sband, sta, rate_table);
@@ -1501,8 +1494,7 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
1501 1494
1502 if ((local_cw40 != oper_cw40) || (local_sgi != oper_sgi)) { 1495 if ((local_cw40 != oper_cw40) || (local_sgi != oper_sgi)) {
1503 rate_table = ath_choose_rate_table(sc, sband->band, 1496 rate_table = ath_choose_rate_table(sc, sband->band,
1504 sta->ht_cap.ht_supported, 1497 sta->ht_cap.ht_supported);
1505 oper_cw40);
1506 ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta, 1498 ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta,
1507 oper_cw40, oper_sgi); 1499 oper_cw40, oper_sgi);
1508 ath_rc_init(sc, priv_sta, sband, sta, rate_table); 1500 ath_rc_init(sc, priv_sta, sband, sta, rate_table);
@@ -1510,11 +1502,98 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
1510 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG, 1502 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG,
1511 "Operating HT Bandwidth changed to: %d\n", 1503 "Operating HT Bandwidth changed to: %d\n",
1512 sc->hw->conf.channel_type); 1504 sc->hw->conf.channel_type);
1513 sc->cur_rate_table = hw_rate_table[sc->cur_rate_mode];
1514 } 1505 }
1515 } 1506 }
1516} 1507}
1517 1508
1509#ifdef CONFIG_ATH9K_DEBUGFS
1510
1511static int ath9k_debugfs_open(struct inode *inode, struct file *file)
1512{
1513 file->private_data = inode->i_private;
1514 return 0;
1515}
1516
1517static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
1518 size_t count, loff_t *ppos)
1519{
1520 struct ath_rate_priv *rc = file->private_data;
1521 char *buf;
1522 unsigned int len = 0, max;
1523 int i = 0;
1524 ssize_t retval;
1525
1526 if (rc->rate_table == NULL)
1527 return 0;
1528
1529 max = 80 + rc->rate_table->rate_cnt * 1024 + 1;
1530 buf = kmalloc(max, GFP_KERNEL);
1531 if (buf == NULL)
1532 return -ENOMEM;
1533
1534 len += sprintf(buf, "%6s %6s %6s "
1535 "%10s %10s %10s %10s\n",
1536 "HT", "MCS", "Rate",
1537 "Success", "Retries", "XRetries", "PER");
1538
1539 for (i = 0; i < rc->rate_table->rate_cnt; i++) {
1540 u32 ratekbps = rc->rate_table->info[i].ratekbps;
1541 struct ath_rc_stats *stats = &rc->rcstats[i];
1542 char mcs[5];
1543 char htmode[5];
1544 int used_mcs = 0, used_htmode = 0;
1545
1546 if (WLAN_RC_PHY_HT(rc->rate_table->info[i].phy)) {
1547 used_mcs = snprintf(mcs, 5, "%d",
1548 rc->rate_table->info[i].ratecode);
1549
1550 if (WLAN_RC_PHY_40(rc->rate_table->info[i].phy))
1551 used_htmode = snprintf(htmode, 5, "HT40");
1552 else if (WLAN_RC_PHY_20(rc->rate_table->info[i].phy))
1553 used_htmode = snprintf(htmode, 5, "HT20");
1554 else
1555 used_htmode = snprintf(htmode, 5, "????");
1556 }
1557
1558 mcs[used_mcs] = '\0';
1559 htmode[used_htmode] = '\0';
1560
1561 len += snprintf(buf + len, max - len,
1562 "%6s %6s %3u.%d: "
1563 "%10u %10u %10u %10u\n",
1564 htmode,
1565 mcs,
1566 ratekbps / 1000,
1567 (ratekbps % 1000) / 100,
1568 stats->success,
1569 stats->retries,
1570 stats->xretries,
1571 stats->per);
1572 }
1573
1574 if (len > max)
1575 len = max;
1576
1577 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
1578 kfree(buf);
1579 return retval;
1580}
1581
1582static const struct file_operations fops_rcstat = {
1583 .read = read_file_rcstat,
1584 .open = ath9k_debugfs_open,
1585 .owner = THIS_MODULE
1586};
1587
1588static void ath_rate_add_sta_debugfs(void *priv, void *priv_sta,
1589 struct dentry *dir)
1590{
1591 struct ath_rate_priv *rc = priv_sta;
1592 debugfs_create_file("rc_stats", S_IRUGO, dir, rc, &fops_rcstat);
1593}
1594
1595#endif /* CONFIG_ATH9K_DEBUGFS */
1596
1518static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) 1597static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
1519{ 1598{
1520 struct ath_wiphy *aphy = hw->priv; 1599 struct ath_wiphy *aphy = hw->priv;
@@ -1561,6 +1640,9 @@ static struct rate_control_ops ath_rate_ops = {
1561 .free = ath_rate_free, 1640 .free = ath_rate_free,
1562 .alloc_sta = ath_rate_alloc_sta, 1641 .alloc_sta = ath_rate_alloc_sta,
1563 .free_sta = ath_rate_free_sta, 1642 .free_sta = ath_rate_free_sta,
1643#ifdef CONFIG_ATH9K_DEBUGFS
1644 .add_sta_debugfs = ath_rate_add_sta_debugfs,
1645#endif
1564}; 1646};
1565 1647
1566int ath_rate_control_register(void) 1648int ath_rate_control_register(void)
diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h
index 268072fd3c1c..2f46a2266ba1 100644
--- a/drivers/net/wireless/ath/ath9k/rc.h
+++ b/drivers/net/wireless/ath/ath9k/rc.h
@@ -135,20 +135,21 @@ enum {
135 135
136/** 136/**
137 * struct ath_rate_table - Rate Control table 137 * struct ath_rate_table - Rate Control table
138 * @valid: valid for use in rate control 138 * @rate_cnt: total number of rates for the given wireless mode
139 * @valid_single_stream: valid for use in rate control for 139 * @mcs_start: MCS rate index offset
140 * single stream operation 140 * @rate_flags: Rate Control flags
141 * @phy: CCK/OFDM 141 * @phy: CCK/OFDM/HT20/HT40
142 * @ratekbps: rate in Kbits per second 142 * @ratekbps: rate in Kbits per second
143 * @user_ratekbps: user rate in Kbits per second 143 * @user_ratekbps: user rate in Kbits per second
144 * @ratecode: rate that goes into HW descriptors 144 * @ratecode: rate that goes into HW descriptors
145 * @short_preamble: Mask for enabling short preamble in ratecode for CCK
146 * @dot11rate: value that goes into supported 145 * @dot11rate: value that goes into supported
147 * rates info element of MLME 146 * rates info element of MLME
148 * @ctrl_rate: Index of next lower basic rate, used for duration computation 147 * @ctrl_rate: Index of next lower basic rate, used for duration computation
149 * @max_4ms_framelen: maximum frame length(bytes) for tx duration 148 * @cw40index: Index of rates having 40MHz channel width
149 * @sgi_index: Index of rates having Short Guard Interval
150 * @ht_index: high throughput rates having 40MHz channel width and
151 * Short Guard Interval
150 * @probe_interval: interval for rate control to probe for other rates 152 * @probe_interval: interval for rate control to probe for other rates
151 * @rssi_reduce_interval: interval for rate control to reduce rssi
152 * @initial_ratemax: initial ratemax value 153 * @initial_ratemax: initial ratemax value
153 */ 154 */
154struct ath_rate_table { 155struct ath_rate_table {
@@ -175,6 +176,13 @@ struct ath_rateset {
175 u8 rs_rates[ATH_RATE_MAX]; 176 u8 rs_rates[ATH_RATE_MAX];
176}; 177};
177 178
179struct ath_rc_stats {
180 u32 success;
181 u32 retries;
182 u32 xretries;
183 u8 per;
184};
185
178/** 186/**
179 * struct ath_rate_priv - Rate Control priv data 187 * struct ath_rate_priv - Rate Control priv data
180 * @state: RC state 188 * @state: RC state
@@ -211,6 +219,10 @@ struct ath_rate_priv {
211 struct ath_rateset neg_rates; 219 struct ath_rateset neg_rates;
212 struct ath_rateset neg_ht_rates; 220 struct ath_rateset neg_ht_rates;
213 struct ath_rate_softc *asc; 221 struct ath_rate_softc *asc;
222 const struct ath_rate_table *rate_table;
223
224 struct dentry *debugfs_rcstats;
225 struct ath_rc_stats rcstats[RATE_TABLE_SIZE];
214}; 226};
215 227
216#define ATH_TX_INFO_FRAME_TYPE_INTERNAL (1 << 0) 228#define ATH_TX_INFO_FRAME_TYPE_INTERNAL (1 << 0)
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 9c166f3804ab..fe73fc50082a 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -268,6 +268,7 @@ static int ath_rx_edma_init(struct ath_softc *sc, int nbufs)
268 bf->bf_buf_addr))) { 268 bf->bf_buf_addr))) {
269 dev_kfree_skb_any(skb); 269 dev_kfree_skb_any(skb);
270 bf->bf_mpdu = NULL; 270 bf->bf_mpdu = NULL;
271 bf->bf_buf_addr = 0;
271 ath_print(common, ATH_DBG_FATAL, 272 ath_print(common, ATH_DBG_FATAL,
272 "dma_mapping_error() on RX init\n"); 273 "dma_mapping_error() on RX init\n");
273 error = -ENOMEM; 274 error = -ENOMEM;
@@ -358,12 +359,12 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
358 bf->bf_buf_addr))) { 359 bf->bf_buf_addr))) {
359 dev_kfree_skb_any(skb); 360 dev_kfree_skb_any(skb);
360 bf->bf_mpdu = NULL; 361 bf->bf_mpdu = NULL;
362 bf->bf_buf_addr = 0;
361 ath_print(common, ATH_DBG_FATAL, 363 ath_print(common, ATH_DBG_FATAL,
362 "dma_mapping_error() on RX init\n"); 364 "dma_mapping_error() on RX init\n");
363 error = -ENOMEM; 365 error = -ENOMEM;
364 goto err; 366 goto err;
365 } 367 }
366 bf->bf_dmacontext = bf->bf_buf_addr;
367 } 368 }
368 sc->rx.rxlink = NULL; 369 sc->rx.rxlink = NULL;
369 } 370 }
@@ -393,6 +394,8 @@ void ath_rx_cleanup(struct ath_softc *sc)
393 common->rx_bufsize, 394 common->rx_bufsize,
394 DMA_FROM_DEVICE); 395 DMA_FROM_DEVICE);
395 dev_kfree_skb(skb); 396 dev_kfree_skb(skb);
397 bf->bf_buf_addr = 0;
398 bf->bf_mpdu = NULL;
396 } 399 }
397 } 400 }
398 401
@@ -430,8 +433,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
430 | ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST 433 | ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST
431 | ATH9K_RX_FILTER_MCAST; 434 | ATH9K_RX_FILTER_MCAST;
432 435
433 /* If not a STA, enable processing of Probe Requests */ 436 if (sc->rx.rxfilter & FIF_PROBE_REQ)
434 if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION)
435 rfilt |= ATH9K_RX_FILTER_PROBEREQ; 437 rfilt |= ATH9K_RX_FILTER_PROBEREQ;
436 438
437 /* 439 /*
@@ -1735,12 +1737,12 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
1735 bf->bf_buf_addr))) { 1737 bf->bf_buf_addr))) {
1736 dev_kfree_skb_any(requeue_skb); 1738 dev_kfree_skb_any(requeue_skb);
1737 bf->bf_mpdu = NULL; 1739 bf->bf_mpdu = NULL;
1740 bf->bf_buf_addr = 0;
1738 ath_print(common, ATH_DBG_FATAL, 1741 ath_print(common, ATH_DBG_FATAL,
1739 "dma_mapping_error() on RX\n"); 1742 "dma_mapping_error() on RX\n");
1740 ath_rx_send_to_mac80211(hw, sc, skb, rxs); 1743 ath_rx_send_to_mac80211(hw, sc, skb, rxs);
1741 break; 1744 break;
1742 } 1745 }
1743 bf->bf_dmacontext = bf->bf_buf_addr;
1744 1746
1745 /* 1747 /*
1746 * change the default rx antenna if rx diversity chooses the 1748 * change the default rx antenna if rx diversity chooses the
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index 6d01e501b9b4..42976b0a01c1 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -107,12 +107,6 @@
107#define AR_RXCFG_DMASZ_256B 6 107#define AR_RXCFG_DMASZ_256B 6
108#define AR_RXCFG_DMASZ_512B 7 108#define AR_RXCFG_DMASZ_512B 7
109 109
110#define AR_MIBC 0x0040
111#define AR_MIBC_COW 0x00000001
112#define AR_MIBC_FMC 0x00000002
113#define AR_MIBC_CMC 0x00000004
114#define AR_MIBC_MCS 0x00000008
115
116#define AR_TOPS 0x0044 110#define AR_TOPS 0x0044
117#define AR_TOPS_MASK 0x0000FFFF 111#define AR_TOPS_MASK 0x0000FFFF
118 112
@@ -859,9 +853,6 @@
859 853
860#define AR_SREV_9300(_ah) \ 854#define AR_SREV_9300(_ah) \
861 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300)) 855 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300))
862#define AR_SREV_9300_20(_ah) \
863 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300) && \
864 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9300_20))
865#define AR_SREV_9300_20_OR_LATER(_ah) \ 856#define AR_SREV_9300_20_OR_LATER(_ah) \
866 (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9300) || \ 857 (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9300) || \
867 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300) && \ 858 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300) && \
@@ -1524,11 +1515,6 @@ enum {
1524#define AR_TPC_CHIRP 0x003f0000 1515#define AR_TPC_CHIRP 0x003f0000
1525#define AR_TPC_CHIRP_S 0x16 1516#define AR_TPC_CHIRP_S 0x16
1526 1517
1527#define AR_TFCNT 0x80ec
1528#define AR_RFCNT 0x80f0
1529#define AR_RCCNT 0x80f4
1530#define AR_CCCNT 0x80f8
1531
1532#define AR_QUIET1 0x80fc 1518#define AR_QUIET1 0x80fc
1533#define AR_QUIET1_NEXT_QUIET_S 0 1519#define AR_QUIET1_NEXT_QUIET_S 0
1534#define AR_QUIET1_NEXT_QUIET_M 0x0000ffff 1520#define AR_QUIET1_NEXT_QUIET_M 0x0000ffff
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index aa447770eb2b..d077186da870 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -294,7 +294,6 @@ static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf)
294 tbf->bf_buf_addr = bf->bf_buf_addr; 294 tbf->bf_buf_addr = bf->bf_buf_addr;
295 memcpy(tbf->bf_desc, bf->bf_desc, sc->sc_ah->caps.tx_desc_len); 295 memcpy(tbf->bf_desc, bf->bf_desc, sc->sc_ah->caps.tx_desc_len);
296 tbf->bf_state = bf->bf_state; 296 tbf->bf_state = bf->bf_state;
297 tbf->bf_dmacontext = bf->bf_dmacontext;
298 297
299 return tbf; 298 return tbf;
300} 299}
@@ -317,6 +316,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
317 int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0; 316 int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0;
318 bool rc_update = true; 317 bool rc_update = true;
319 struct ieee80211_tx_rate rates[4]; 318 struct ieee80211_tx_rate rates[4];
319 int nframes;
320 320
321 skb = bf->bf_mpdu; 321 skb = bf->bf_mpdu;
322 hdr = (struct ieee80211_hdr *)skb->data; 322 hdr = (struct ieee80211_hdr *)skb->data;
@@ -325,6 +325,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
325 hw = bf->aphy->hw; 325 hw = bf->aphy->hw;
326 326
327 memcpy(rates, tx_info->control.rates, sizeof(rates)); 327 memcpy(rates, tx_info->control.rates, sizeof(rates));
328 nframes = bf->bf_nframes;
328 329
329 rcu_read_lock(); 330 rcu_read_lock();
330 331
@@ -341,7 +342,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
341 !bf->bf_stale || bf_next != NULL) 342 !bf->bf_stale || bf_next != NULL)
342 list_move_tail(&bf->list, &bf_head); 343 list_move_tail(&bf->list, &bf_head);
343 344
344 ath_tx_rc_status(bf, ts, 0, 0, false); 345 ath_tx_rc_status(bf, ts, 1, 0, false);
345 ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, 346 ath_tx_complete_buf(sc, bf, txq, &bf_head, ts,
346 0, 0); 347 0, 0);
347 348
@@ -446,6 +447,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
446 447
447 if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) { 448 if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) {
448 memcpy(tx_info->control.rates, rates, sizeof(rates)); 449 memcpy(tx_info->control.rates, rates, sizeof(rates));
450 bf->bf_nframes = nframes;
449 ath_tx_rc_status(bf, ts, nbad, txok, true); 451 ath_tx_rc_status(bf, ts, nbad, txok, true);
450 rc_update = false; 452 rc_update = false;
451 } else { 453 } else {
@@ -1637,17 +1639,16 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
1637 1639
1638 bf->bf_mpdu = skb; 1640 bf->bf_mpdu = skb;
1639 1641
1640 bf->bf_dmacontext = dma_map_single(sc->dev, skb->data, 1642 bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
1641 skb->len, DMA_TO_DEVICE); 1643 skb->len, DMA_TO_DEVICE);
1642 if (unlikely(dma_mapping_error(sc->dev, bf->bf_dmacontext))) { 1644 if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) {
1643 bf->bf_mpdu = NULL; 1645 bf->bf_mpdu = NULL;
1646 bf->bf_buf_addr = 0;
1644 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, 1647 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
1645 "dma_mapping_error() on TX\n"); 1648 "dma_mapping_error() on TX\n");
1646 return -ENOMEM; 1649 return -ENOMEM;
1647 } 1650 }
1648 1651
1649 bf->bf_buf_addr = bf->bf_dmacontext;
1650
1651 bf->bf_tx_aborted = false; 1652 bf->bf_tx_aborted = false;
1652 1653
1653 return 0; 1654 return 0;
@@ -1911,7 +1912,8 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
1911 tx_flags |= ATH_TX_XRETRY; 1912 tx_flags |= ATH_TX_XRETRY;
1912 } 1913 }
1913 1914
1914 dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE); 1915 dma_unmap_single(sc->dev, bf->bf_buf_addr, skb->len, DMA_TO_DEVICE);
1916 bf->bf_buf_addr = 0;
1915 1917
1916 if (bf->bf_state.bfs_paprd) { 1918 if (bf->bf_state.bfs_paprd) {
1917 if (time_after(jiffies, 1919 if (time_after(jiffies,
@@ -1921,9 +1923,13 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
1921 else 1923 else
1922 complete(&sc->paprd_complete); 1924 complete(&sc->paprd_complete);
1923 } else { 1925 } else {
1924 ath_tx_complete(sc, skb, bf->aphy, tx_flags);
1925 ath_debug_stat_tx(sc, txq, bf, ts); 1926 ath_debug_stat_tx(sc, txq, bf, ts);
1927 ath_tx_complete(sc, skb, bf->aphy, tx_flags);
1926 } 1928 }
1929 /* At this point, skb (bf->bf_mpdu) is consumed...make sure we don't
1930 * accidentally reference it later.
1931 */
1932 bf->bf_mpdu = NULL;
1927 1933
1928 /* 1934 /*
1929 * Return the list of ath_buf of this mpdu to free queue 1935 * Return the list of ath_buf of this mpdu to free queue
@@ -1979,9 +1985,15 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts,
1979 1985
1980 if (ts->ts_status & ATH9K_TXERR_FILT) 1986 if (ts->ts_status & ATH9K_TXERR_FILT)
1981 tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; 1987 tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
1982 if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && update_rc) 1988 if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && update_rc) {
1983 tx_info->flags |= IEEE80211_TX_STAT_AMPDU; 1989 tx_info->flags |= IEEE80211_TX_STAT_AMPDU;
1984 1990
1991 BUG_ON(nbad > bf->bf_nframes);
1992
1993 tx_info->status.ampdu_len = bf->bf_nframes;
1994 tx_info->status.ampdu_ack_len = bf->bf_nframes - nbad;
1995 }
1996
1985 if ((ts->ts_status & ATH9K_TXERR_FILT) == 0 && 1997 if ((ts->ts_status & ATH9K_TXERR_FILT) == 0 &&
1986 (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) { 1998 (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) {
1987 if (ieee80211_is_data(hdr->frame_control)) { 1999 if (ieee80211_is_data(hdr->frame_control)) {
@@ -1991,8 +2003,6 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts,
1991 if ((ts->ts_status & ATH9K_TXERR_XRETRY) || 2003 if ((ts->ts_status & ATH9K_TXERR_XRETRY) ||
1992 (ts->ts_status & ATH9K_TXERR_FIFO)) 2004 (ts->ts_status & ATH9K_TXERR_FIFO))
1993 tx_info->pad[0] |= ATH_TX_INFO_XRETRY; 2005 tx_info->pad[0] |= ATH_TX_INFO_XRETRY;
1994 tx_info->status.ampdu_len = bf->bf_nframes;
1995 tx_info->status.ampdu_ack_len = bf->bf_nframes - nbad;
1996 } 2006 }
1997 } 2007 }
1998 2008
@@ -2102,7 +2112,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
2102 */ 2112 */
2103 if (ts.ts_status & ATH9K_TXERR_XRETRY) 2113 if (ts.ts_status & ATH9K_TXERR_XRETRY)
2104 bf->bf_state.bf_type |= BUF_XRETRY; 2114 bf->bf_state.bf_type |= BUF_XRETRY;
2105 ath_tx_rc_status(bf, &ts, 0, txok, true); 2115 ath_tx_rc_status(bf, &ts, txok ? 0 : 1, txok, true);
2106 } 2116 }
2107 2117
2108 if (bf_isampdu(bf)) 2118 if (bf_isampdu(bf))
@@ -2220,7 +2230,7 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
2220 if (!bf_isampdu(bf)) { 2230 if (!bf_isampdu(bf)) {
2221 if (txs.ts_status & ATH9K_TXERR_XRETRY) 2231 if (txs.ts_status & ATH9K_TXERR_XRETRY)
2222 bf->bf_state.bf_type |= BUF_XRETRY; 2232 bf->bf_state.bf_type |= BUF_XRETRY;
2223 ath_tx_rc_status(bf, &txs, 0, txok, true); 2233 ath_tx_rc_status(bf, &txs, txok ? 0 : 1, txok, true);
2224 } 2234 }
2225 2235
2226 if (bf_isampdu(bf)) 2236 if (bf_isampdu(bf))
diff --git a/drivers/net/wireless/ath/carl9170/rx.c b/drivers/net/wireless/ath/carl9170/rx.c
index 671dbc429547..939a0e96ed1f 100644
--- a/drivers/net/wireless/ath/carl9170/rx.c
+++ b/drivers/net/wireless/ath/carl9170/rx.c
@@ -576,6 +576,41 @@ static void carl9170_ps_beacon(struct ar9170 *ar, void *data, unsigned int len)
576 } 576 }
577} 577}
578 578
579static bool carl9170_ampdu_check(struct ar9170 *ar, u8 *buf, u8 ms)
580{
581 __le16 fc;
582
583 if ((ms & AR9170_RX_STATUS_MPDU) == AR9170_RX_STATUS_MPDU_SINGLE) {
584 /*
585 * This frame is not part of an aMPDU.
586 * Therefore it is not subjected to any
587 * of the following content restrictions.
588 */
589 return true;
590 }
591
592 /*
593 * "802.11n - 7.4a.3 A-MPDU contents" describes in which contexts
594 * certain frame types can be part of an aMPDU.
595 *
596 * In order to keep the processing cost down, I opted for a
597 * stateless filter solely based on the frame control field.
598 */
599
600 fc = ((struct ieee80211_hdr *)buf)->frame_control;
601 if (ieee80211_is_data_qos(fc) && ieee80211_is_data_present(fc))
602 return true;
603
604 if (ieee80211_is_ack(fc) || ieee80211_is_back(fc) ||
605 ieee80211_is_back_req(fc))
606 return true;
607
608 if (ieee80211_is_action(fc))
609 return true;
610
611 return false;
612}
613
579/* 614/*
580 * If the frame alignment is right (or the kernel has 615 * If the frame alignment is right (or the kernel has
581 * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS), and there 616 * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS), and there
@@ -594,24 +629,19 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
594 struct ieee80211_rx_status status; 629 struct ieee80211_rx_status status;
595 struct sk_buff *skb; 630 struct sk_buff *skb;
596 int mpdu_len; 631 int mpdu_len;
632 u8 mac_status;
597 633
598 if (!IS_STARTED(ar)) 634 if (!IS_STARTED(ar))
599 return; 635 return;
600 636
601 if (unlikely(len < sizeof(*mac))) { 637 if (unlikely(len < sizeof(*mac)))
602 ar->rx_dropped++; 638 goto drop;
603 return;
604 }
605 639
606 mpdu_len = len - sizeof(*mac); 640 mpdu_len = len - sizeof(*mac);
607 641
608 mac = (void *)(buf + mpdu_len); 642 mac = (void *)(buf + mpdu_len);
609 if (unlikely(mac->error & AR9170_RX_ERROR_FATAL)) { 643 mac_status = mac->status;
610 ar->rx_dropped++; 644 switch (mac_status & AR9170_RX_STATUS_MPDU) {
611 return;
612 }
613
614 switch (mac->status & AR9170_RX_STATUS_MPDU) {
615 case AR9170_RX_STATUS_MPDU_FIRST: 645 case AR9170_RX_STATUS_MPDU_FIRST:
616 /* Aggregated MPDUs start with an PLCP header */ 646 /* Aggregated MPDUs start with an PLCP header */
617 if (likely(mpdu_len >= sizeof(struct ar9170_rx_head))) { 647 if (likely(mpdu_len >= sizeof(struct ar9170_rx_head))) {
@@ -638,8 +668,7 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
638 "is clipped.\n"); 668 "is clipped.\n");
639 } 669 }
640 670
641 ar->rx_dropped++; 671 goto drop;
642 return;
643 } 672 }
644 break; 673 break;
645 674
@@ -659,8 +688,7 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
659 "is clipped.\n"); 688 "is clipped.\n");
660 } 689 }
661 690
662 ar->rx_dropped++; 691 goto drop;
663 return;
664 } 692 }
665 693
666 case AR9170_RX_STATUS_MPDU_MIDDLE: 694 case AR9170_RX_STATUS_MPDU_MIDDLE:
@@ -672,8 +700,7 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
672 wiphy_err(ar->hw->wiphy, "rx stream does not start " 700 wiphy_err(ar->hw->wiphy, "rx stream does not start "
673 "with a first_mpdu frame tag.\n"); 701 "with a first_mpdu frame tag.\n");
674 702
675 ar->rx_dropped++; 703 goto drop;
676 return;
677 } 704 }
678 705
679 head = &ar->rx_plcp; 706 head = &ar->rx_plcp;
@@ -696,16 +723,15 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
696 } 723 }
697 724
698 /* FC + DU + RA + FCS */ 725 /* FC + DU + RA + FCS */
699 if (unlikely(mpdu_len < (2 + 2 + 6 + FCS_LEN))) { 726 if (unlikely(mpdu_len < (2 + 2 + ETH_ALEN + FCS_LEN)))
700 ar->rx_dropped++; 727 goto drop;
701 return;
702 }
703 728
704 memset(&status, 0, sizeof(status)); 729 memset(&status, 0, sizeof(status));
705 if (unlikely(carl9170_rx_mac_status(ar, head, mac, &status))) { 730 if (unlikely(carl9170_rx_mac_status(ar, head, mac, &status)))
706 ar->rx_dropped++; 731 goto drop;
707 return; 732
708 } 733 if (!carl9170_ampdu_check(ar, buf, mac_status))
734 goto drop;
709 735
710 if (phy) 736 if (phy)
711 carl9170_rx_phy_status(ar, phy, &status); 737 carl9170_rx_phy_status(ar, phy, &status);
@@ -713,12 +739,15 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
713 carl9170_ps_beacon(ar, buf, mpdu_len); 739 carl9170_ps_beacon(ar, buf, mpdu_len);
714 740
715 skb = carl9170_rx_copy_data(buf, mpdu_len); 741 skb = carl9170_rx_copy_data(buf, mpdu_len);
716 if (likely(skb)) { 742 if (!skb)
717 memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status)); 743 goto drop;
718 ieee80211_rx(ar->hw, skb); 744
719 } else { 745 memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
720 ar->rx_dropped++; 746 ieee80211_rx(ar->hw, skb);
721 } 747 return;
748
749drop:
750 ar->rx_dropped++;
722} 751}
723 752
724static void carl9170_rx_untie_cmds(struct ar9170 *ar, const u8 *respbuf, 753static void carl9170_rx_untie_cmds(struct ar9170 *ar, const u8 *respbuf,
diff --git a/drivers/net/wireless/ath/carl9170/wlan.h b/drivers/net/wireless/ath/carl9170/wlan.h
index 48ead2268f50..24d63b583b6b 100644
--- a/drivers/net/wireless/ath/carl9170/wlan.h
+++ b/drivers/net/wireless/ath/carl9170/wlan.h
@@ -74,6 +74,9 @@
74#define AR9170_RX_STATUS_MPDU_MIDDLE 0x30 74#define AR9170_RX_STATUS_MPDU_MIDDLE 0x30
75#define AR9170_RX_STATUS_MPDU_LAST 0x10 75#define AR9170_RX_STATUS_MPDU_LAST 0x10
76 76
77#define AR9170_RX_STATUS_CONT_AGGR 0x40
78#define AR9170_RX_STATUS_TOTAL_ERROR 0x80
79
77#define AR9170_RX_ERROR_RXTO 0x01 80#define AR9170_RX_ERROR_RXTO 0x01
78#define AR9170_RX_ERROR_OVERRUN 0x02 81#define AR9170_RX_ERROR_OVERRUN 0x02
79#define AR9170_RX_ERROR_DECRYPT 0x04 82#define AR9170_RX_ERROR_DECRYPT 0x04
@@ -81,7 +84,6 @@
81#define AR9170_RX_ERROR_WRONG_RA 0x10 84#define AR9170_RX_ERROR_WRONG_RA 0x10
82#define AR9170_RX_ERROR_PLCP 0x20 85#define AR9170_RX_ERROR_PLCP 0x20
83#define AR9170_RX_ERROR_MMIC 0x40 86#define AR9170_RX_ERROR_MMIC 0x40
84#define AR9170_RX_ERROR_FATAL 0x80
85 87
86/* these are either-or */ 88/* these are either-or */
87#define AR9170_TX_MAC_PROT_RTS 0x0001 89#define AR9170_TX_MAC_PROT_RTS 0x0001
@@ -329,13 +331,15 @@ struct _carl9170_tx_superframe {
329 331
330#define CARL9170_TX_SUPERDESC_LEN 24 332#define CARL9170_TX_SUPERDESC_LEN 24
331#define AR9170_TX_HWDESC_LEN 8 333#define AR9170_TX_HWDESC_LEN 8
332#define AR9170_TX_SUPERFRAME_LEN (CARL9170_TX_HWDESC_LEN + \ 334#define CARL9170_TX_SUPERFRAME_LEN (CARL9170_TX_SUPERDESC_LEN + \
333 AR9170_TX_SUPERDESC_LEN) 335 AR9170_TX_HWDESC_LEN)
334 336
335struct ar9170_rx_head { 337struct ar9170_rx_head {
336 u8 plcp[12]; 338 u8 plcp[12];
337} __packed; 339} __packed;
338 340
341#define AR9170_RX_HEAD_LEN 12
342
339struct ar9170_rx_phystatus { 343struct ar9170_rx_phystatus {
340 union { 344 union {
341 struct { 345 struct {
@@ -350,12 +354,16 @@ struct ar9170_rx_phystatus {
350 u8 phy_err; 354 u8 phy_err;
351} __packed; 355} __packed;
352 356
357#define AR9170_RX_PHYSTATUS_LEN 20
358
353struct ar9170_rx_macstatus { 359struct ar9170_rx_macstatus {
354 u8 SAidx, DAidx; 360 u8 SAidx, DAidx;
355 u8 error; 361 u8 error;
356 u8 status; 362 u8 status;
357} __packed; 363} __packed;
358 364
365#define AR9170_RX_MACSTATUS_LEN 4
366
359struct ar9170_rx_frame_single { 367struct ar9170_rx_frame_single {
360 struct ar9170_rx_head phy_head; 368 struct ar9170_rx_head phy_head;
361 struct ieee80211_hdr i3e; 369 struct ieee80211_hdr i3e;
diff --git a/drivers/net/wireless/ath/debug.c b/drivers/net/wireless/ath/debug.c
index 53e77bd131b9..dacfb234f491 100644
--- a/drivers/net/wireless/ath/debug.c
+++ b/drivers/net/wireless/ath/debug.c
@@ -30,3 +30,32 @@ void ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...)
30 va_end(args); 30 va_end(args);
31} 31}
32EXPORT_SYMBOL(ath_print); 32EXPORT_SYMBOL(ath_print);
33
34const char *ath_opmode_to_string(enum nl80211_iftype opmode)
35{
36 switch (opmode) {
37 case NL80211_IFTYPE_UNSPECIFIED:
38 return "UNSPEC";
39 case NL80211_IFTYPE_ADHOC:
40 return "ADHOC";
41 case NL80211_IFTYPE_STATION:
42 return "STATION";
43 case NL80211_IFTYPE_AP:
44 return "AP";
45 case NL80211_IFTYPE_AP_VLAN:
46 return "AP-VLAN";
47 case NL80211_IFTYPE_WDS:
48 return "WDS";
49 case NL80211_IFTYPE_MONITOR:
50 return "MONITOR";
51 case NL80211_IFTYPE_MESH_POINT:
52 return "MESH";
53 case NL80211_IFTYPE_P2P_CLIENT:
54 return "P2P-CLIENT";
55 case NL80211_IFTYPE_P2P_GO:
56 return "P2P-GO";
57 default:
58 return "UNKNOWN";
59 }
60}
61EXPORT_SYMBOL(ath_opmode_to_string);
diff --git a/drivers/net/wireless/ath/debug.h b/drivers/net/wireless/ath/debug.h
index fd3a020682dc..64e4af2c2887 100644
--- a/drivers/net/wireless/ath/debug.h
+++ b/drivers/net/wireless/ath/debug.h
@@ -77,4 +77,14 @@ ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...)
77} 77}
78#endif /* CONFIG_ATH_DEBUG */ 78#endif /* CONFIG_ATH_DEBUG */
79 79
80/** Returns string describing opmode, or NULL if unknown mode. */
81#ifdef CONFIG_ATH_DEBUG
82const char *ath_opmode_to_string(enum nl80211_iftype opmode);
83#else
84static inline const char *ath_opmode_to_string(enum nl80211_iftype opmode)
85{
86 return "UNKNOWN";
87}
88#endif
89
80#endif /* ATH_DEBUG_H */ 90#endif /* ATH_DEBUG_H */
diff --git a/drivers/net/wireless/ath/hw.c b/drivers/net/wireless/ath/hw.c
index a8f81ea09f14..183c28281385 100644
--- a/drivers/net/wireless/ath/hw.c
+++ b/drivers/net/wireless/ath/hw.c
@@ -124,3 +124,62 @@ void ath_hw_setbssidmask(struct ath_common *common)
124 REG_WRITE(ah, get_unaligned_le16(common->bssidmask + 4), AR_BSSMSKU); 124 REG_WRITE(ah, get_unaligned_le16(common->bssidmask + 4), AR_BSSMSKU);
125} 125}
126EXPORT_SYMBOL(ath_hw_setbssidmask); 126EXPORT_SYMBOL(ath_hw_setbssidmask);
127
128
129/**
130 * ath_hw_cycle_counters_update - common function to update cycle counters
131 *
132 * @common: the ath_common struct for the device.
133 *
134 * This function is used to update all cycle counters in one place.
135 * It has to be called while holding common->cc_lock!
136 */
137void ath_hw_cycle_counters_update(struct ath_common *common)
138{
139 u32 cycles, busy, rx, tx;
140 void *ah = common->ah;
141
142 /* freeze */
143 REG_WRITE(ah, AR_MIBC_FMC, AR_MIBC);
144
145 /* read */
146 cycles = REG_READ(ah, AR_CCCNT);
147 busy = REG_READ(ah, AR_RCCNT);
148 rx = REG_READ(ah, AR_RFCNT);
149 tx = REG_READ(ah, AR_TFCNT);
150
151 /* clear */
152 REG_WRITE(ah, 0, AR_CCCNT);
153 REG_WRITE(ah, 0, AR_RFCNT);
154 REG_WRITE(ah, 0, AR_RCCNT);
155 REG_WRITE(ah, 0, AR_TFCNT);
156
157 /* unfreeze */
158 REG_WRITE(ah, 0, AR_MIBC);
159
160 /* update all cycle counters here */
161 common->cc_ani.cycles += cycles;
162 common->cc_ani.rx_busy += busy;
163 common->cc_ani.rx_frame += rx;
164 common->cc_ani.tx_frame += tx;
165
166 common->cc_survey.cycles += cycles;
167 common->cc_survey.rx_busy += busy;
168 common->cc_survey.rx_frame += rx;
169 common->cc_survey.tx_frame += tx;
170}
171EXPORT_SYMBOL(ath_hw_cycle_counters_update);
172
173int32_t ath_hw_get_listen_time(struct ath_common *common)
174{
175 struct ath_cycle_counters *cc = &common->cc_ani;
176 int32_t listen_time;
177
178 listen_time = (cc->cycles - cc->rx_frame - cc->tx_frame) /
179 (common->clockrate * 1000);
180
181 memset(cc, 0, sizeof(*cc));
182
183 return listen_time;
184}
185EXPORT_SYMBOL(ath_hw_get_listen_time);
diff --git a/drivers/net/wireless/ath/reg.h b/drivers/net/wireless/ath/reg.h
index e798ef476581..298e53f3fa48 100644
--- a/drivers/net/wireless/ath/reg.h
+++ b/drivers/net/wireless/ath/reg.h
@@ -17,6 +17,12 @@
17#ifndef ATH_REGISTERS_H 17#ifndef ATH_REGISTERS_H
18#define ATH_REGISTERS_H 18#define ATH_REGISTERS_H
19 19
20#define AR_MIBC 0x0040
21#define AR_MIBC_COW 0x00000001
22#define AR_MIBC_FMC 0x00000002
23#define AR_MIBC_CMC 0x00000004
24#define AR_MIBC_MCS 0x00000008
25
20/* 26/*
21 * BSSID mask registers. See ath_hw_set_bssid_mask() 27 * BSSID mask registers. See ath_hw_set_bssid_mask()
22 * for detailed documentation about these registers. 28 * for detailed documentation about these registers.
@@ -24,6 +30,11 @@
24#define AR_BSSMSKL 0x80e0 30#define AR_BSSMSKL 0x80e0
25#define AR_BSSMSKU 0x80e4 31#define AR_BSSMSKU 0x80e4
26 32
33#define AR_TFCNT 0x80ec
34#define AR_RFCNT 0x80f0
35#define AR_RCCNT 0x80f4
36#define AR_CCCNT 0x80f8
37
27#define AR_KEYTABLE_0 0x8800 38#define AR_KEYTABLE_0 0x8800
28#define AR_KEYTABLE(_n) (AR_KEYTABLE_0 + ((_n)*32)) 39#define AR_KEYTABLE(_n) (AR_KEYTABLE_0 + ((_n)*32))
29#define AR_KEY_CACHE_SIZE 128 40#define AR_KEY_CACHE_SIZE 128
diff --git a/drivers/net/wireless/b43/Makefile b/drivers/net/wireless/b43/Makefile
index 5e83b6f0a3a0..69d4af09a6cb 100644
--- a/drivers/net/wireless/b43/Makefile
+++ b/drivers/net/wireless/b43/Makefile
@@ -1,6 +1,8 @@
1b43-y += main.o 1b43-y += main.o
2b43-y += tables.o 2b43-y += tables.o
3b43-$(CONFIG_B43_NPHY) += tables_nphy.o 3b43-$(CONFIG_B43_NPHY) += tables_nphy.o
4b43-$(CONFIG_B43_NPHY) += radio_2055.o
5b43-$(CONFIG_B43_NPHY) += radio_2056.o
4b43-y += phy_common.o 6b43-y += phy_common.o
5b43-y += phy_g.o 7b43-y += phy_g.o
6b43-y += phy_a.o 8b43-y += phy_a.o
diff --git a/drivers/net/wireless/b43/phy_common.h b/drivers/net/wireless/b43/phy_common.h
index bd480b481bfc..0e6194228845 100644
--- a/drivers/net/wireless/b43/phy_common.h
+++ b/drivers/net/wireless/b43/phy_common.h
@@ -2,6 +2,7 @@
2#define LINUX_B43_PHY_COMMON_H_ 2#define LINUX_B43_PHY_COMMON_H_
3 3
4#include <linux/types.h> 4#include <linux/types.h>
5#include <linux/nl80211.h>
5 6
6struct b43_wldev; 7struct b43_wldev;
7 8
@@ -250,8 +251,10 @@ struct b43_phy {
250 * check is needed. */ 251 * check is needed. */
251 unsigned long next_txpwr_check_time; 252 unsigned long next_txpwr_check_time;
252 253
253 /* current channel */ 254 /* Current channel */
254 unsigned int channel; 255 unsigned int channel;
256 u16 channel_freq;
257 enum nl80211_channel_type channel_type;
255 258
256 /* PHY TX errors counter. */ 259 /* PHY TX errors counter. */
257 atomic_t txerr_cnt; 260 atomic_t txerr_cnt;
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index f575e757caeb..dfec5496055e 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -29,6 +29,8 @@
29#include "b43.h" 29#include "b43.h"
30#include "phy_n.h" 30#include "phy_n.h"
31#include "tables_nphy.h" 31#include "tables_nphy.h"
32#include "radio_2055.h"
33#include "radio_2056.h"
32#include "main.h" 34#include "main.h"
33 35
34struct nphy_txgains { 36struct nphy_txgains {
@@ -74,19 +76,11 @@ static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field,
74static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field, 76static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field,
75 u16 value, u8 core); 77 u16 value, u8 core);
76 78
77static inline bool b43_empty_chanspec(struct b43_chanspec *chanspec) 79static inline bool b43_channel_type_is_40mhz(
80 enum nl80211_channel_type channel_type)
78{ 81{
79 return !chanspec->channel && !chanspec->sideband && 82 return (channel_type == NL80211_CHAN_HT40MINUS ||
80 !chanspec->b_width && !chanspec->b_freq; 83 channel_type == NL80211_CHAN_HT40PLUS);
81}
82
83static inline bool b43_eq_chanspecs(struct b43_chanspec *chanspec1,
84 struct b43_chanspec *chanspec2)
85{
86 return (chanspec1->channel == chanspec2->channel &&
87 chanspec1->sideband == chanspec2->sideband &&
88 chanspec1->b_width == chanspec2->b_width &&
89 chanspec1->b_freq == chanspec2->b_freq);
90} 84}
91 85
92void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna) 86void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna)
@@ -781,7 +775,7 @@ static void b43_nphy_spur_workaround(struct b43_wldev *dev)
781{ 775{
782 struct b43_phy_n *nphy = dev->phy.n; 776 struct b43_phy_n *nphy = dev->phy.n;
783 777
784 u8 channel = nphy->radio_chanspec.channel; 778 u8 channel = dev->phy.channel;
785 int tone[2] = { 57, 58 }; 779 int tone[2] = { 57, 58 };
786 u32 noise[2] = { 0x3FF, 0x3FF }; 780 u32 noise[2] = { 0x3FF, 0x3FF };
787 781
@@ -855,9 +849,9 @@ static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev)
855 gain[0] = 6; 849 gain[0] = 6;
856 gain[1] = 6; 850 gain[1] = 6;
857 } else { 851 } else {
858 tmp = 40370 - 315 * nphy->radio_chanspec.channel; 852 tmp = 40370 - 315 * dev->phy.channel;
859 gain[0] = ((tmp >> 13) + ((tmp >> 12) & 1)); 853 gain[0] = ((tmp >> 13) + ((tmp >> 12) & 1));
860 tmp = 23242 - 224 * nphy->radio_chanspec.channel; 854 tmp = 23242 - 224 * dev->phy.channel;
861 gain[1] = ((tmp >> 13) + ((tmp >> 12) & 1)); 855 gain[1] = ((tmp >> 13) + ((tmp >> 12) & 1));
862 } 856 }
863 } else { 857 } else {
@@ -2083,12 +2077,12 @@ static void b43_nphy_restore_rssi_cal(struct b43_wldev *dev)
2083 u16 *rssical_phy_regs = NULL; 2077 u16 *rssical_phy_regs = NULL;
2084 2078
2085 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { 2079 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
2086 if (b43_empty_chanspec(&nphy->rssical_chanspec_2G)) 2080 if (!nphy->rssical_chanspec_2G.center_freq)
2087 return; 2081 return;
2088 rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_2G; 2082 rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_2G;
2089 rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_2G; 2083 rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_2G;
2090 } else { 2084 } else {
2091 if (b43_empty_chanspec(&nphy->rssical_chanspec_5G)) 2085 if (!nphy->rssical_chanspec_5G.center_freq)
2092 return; 2086 return;
2093 rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_5G; 2087 rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_5G;
2094 rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G; 2088 rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G;
@@ -2544,8 +2538,9 @@ static void b43_nphy_save_cal(struct b43_wldev *dev)
2544 txcal_radio_regs[2] = b43_radio_read(dev, 0x8D); 2538 txcal_radio_regs[2] = b43_radio_read(dev, 0x8D);
2545 txcal_radio_regs[3] = b43_radio_read(dev, 0xBC); 2539 txcal_radio_regs[3] = b43_radio_read(dev, 0xBC);
2546 } 2540 }
2547 *iqcal_chanspec = nphy->radio_chanspec; 2541 iqcal_chanspec->center_freq = dev->phy.channel_freq;
2548 b43_ntab_write_bulk(dev, B43_NTAB16(15, 80), 8, table); 2542 iqcal_chanspec->channel_type = dev->phy.channel_type;
2543 b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 8, table);
2549 2544
2550 if (nphy->hang_avoid) 2545 if (nphy->hang_avoid)
2551 b43_nphy_stay_in_carrier_search(dev, 0); 2546 b43_nphy_stay_in_carrier_search(dev, 0);
@@ -2565,12 +2560,12 @@ static void b43_nphy_restore_cal(struct b43_wldev *dev)
2565 struct b43_phy_n_iq_comp *rxcal_coeffs = NULL; 2560 struct b43_phy_n_iq_comp *rxcal_coeffs = NULL;
2566 2561
2567 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { 2562 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
2568 if (b43_empty_chanspec(&nphy->iqcal_chanspec_2G)) 2563 if (!nphy->iqcal_chanspec_2G.center_freq)
2569 return; 2564 return;
2570 table = nphy->cal_cache.txcal_coeffs_2G; 2565 table = nphy->cal_cache.txcal_coeffs_2G;
2571 loft = &nphy->cal_cache.txcal_coeffs_2G[5]; 2566 loft = &nphy->cal_cache.txcal_coeffs_2G[5];
2572 } else { 2567 } else {
2573 if (b43_empty_chanspec(&nphy->iqcal_chanspec_5G)) 2568 if (!nphy->iqcal_chanspec_5G.center_freq)
2574 return; 2569 return;
2575 table = nphy->cal_cache.txcal_coeffs_5G; 2570 table = nphy->cal_cache.txcal_coeffs_5G;
2576 loft = &nphy->cal_cache.txcal_coeffs_5G[5]; 2571 loft = &nphy->cal_cache.txcal_coeffs_5G[5];
@@ -2815,7 +2810,10 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev,
2815 b43_ntab_read_bulk(dev, B43_NTAB16(15, 96), length, 2810 b43_ntab_read_bulk(dev, B43_NTAB16(15, 96), length,
2816 nphy->txiqlocal_bestc); 2811 nphy->txiqlocal_bestc);
2817 nphy->txiqlocal_coeffsvalid = true; 2812 nphy->txiqlocal_coeffsvalid = true;
2818 nphy->txiqlocal_chanspec = nphy->radio_chanspec; 2813 nphy->txiqlocal_chanspec.center_freq =
2814 dev->phy.channel_freq;
2815 nphy->txiqlocal_chanspec.channel_type =
2816 dev->phy.channel_type;
2819 } else { 2817 } else {
2820 length = 11; 2818 length = 11;
2821 if (dev->phy.rev < 3) 2819 if (dev->phy.rev < 3)
@@ -2851,7 +2849,8 @@ static void b43_nphy_reapply_tx_cal_coeffs(struct b43_wldev *dev)
2851 bool equal = true; 2849 bool equal = true;
2852 2850
2853 if (!nphy->txiqlocal_coeffsvalid || 2851 if (!nphy->txiqlocal_coeffsvalid ||
2854 b43_eq_chanspecs(&nphy->txiqlocal_chanspec, &nphy->radio_chanspec)) 2852 nphy->txiqlocal_chanspec.center_freq != dev->phy.channel_freq ||
2853 nphy->txiqlocal_chanspec.channel_type != dev->phy.channel_type)
2855 return; 2854 return;
2856 2855
2857 b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 7, buffer); 2856 b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 7, buffer);
@@ -3257,11 +3256,9 @@ int b43_phy_initn(struct b43_wldev *dev)
3257 do_rssi_cal = false; 3256 do_rssi_cal = false;
3258 if (phy->rev >= 3) { 3257 if (phy->rev >= 3) {
3259 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) 3258 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
3260 do_rssi_cal = 3259 do_rssi_cal = !nphy->rssical_chanspec_2G.center_freq;
3261 b43_empty_chanspec(&nphy->rssical_chanspec_2G);
3262 else 3260 else
3263 do_rssi_cal = 3261 do_rssi_cal = !nphy->rssical_chanspec_5G.center_freq;
3264 b43_empty_chanspec(&nphy->rssical_chanspec_5G);
3265 3262
3266 if (do_rssi_cal) 3263 if (do_rssi_cal)
3267 b43_nphy_rssi_cal(dev); 3264 b43_nphy_rssi_cal(dev);
@@ -3273,9 +3270,9 @@ int b43_phy_initn(struct b43_wldev *dev)
3273 3270
3274 if (!((nphy->measure_hold & 0x6) != 0)) { 3271 if (!((nphy->measure_hold & 0x6) != 0)) {
3275 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) 3272 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
3276 do_cal = b43_empty_chanspec(&nphy->iqcal_chanspec_2G); 3273 do_cal = !nphy->iqcal_chanspec_2G.center_freq;
3277 else 3274 else
3278 do_cal = b43_empty_chanspec(&nphy->iqcal_chanspec_5G); 3275 do_cal = !nphy->iqcal_chanspec_5G.center_freq;
3279 3276
3280 if (nphy->mute) 3277 if (nphy->mute)
3281 do_cal = false; 3278 do_cal = false;
@@ -3323,24 +3320,25 @@ int b43_phy_initn(struct b43_wldev *dev)
3323} 3320}
3324 3321
3325/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ChanspecSetup */ 3322/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ChanspecSetup */
3326static void b43_nphy_chanspec_setup(struct b43_wldev *dev, 3323static void b43_nphy_channel_setup(struct b43_wldev *dev,
3327 const struct b43_phy_n_sfo_cfg *e, 3324 const struct b43_phy_n_sfo_cfg *e,
3328 struct b43_chanspec chanspec) 3325 struct ieee80211_channel *new_channel)
3329{ 3326{
3330 struct b43_phy *phy = &dev->phy; 3327 struct b43_phy *phy = &dev->phy;
3331 struct b43_phy_n *nphy = dev->phy.n; 3328 struct b43_phy_n *nphy = dev->phy.n;
3332 3329
3333 u16 tmp; 3330 u16 old_band_5ghz;
3334 u32 tmp32; 3331 u32 tmp32;
3335 3332
3336 tmp = b43_phy_read(dev, B43_NPHY_BANDCTL) & B43_NPHY_BANDCTL_5GHZ; 3333 old_band_5ghz =
3337 if (chanspec.b_freq == 1 && tmp == 0) { 3334 b43_phy_read(dev, B43_NPHY_BANDCTL) & B43_NPHY_BANDCTL_5GHZ;
3335 if (new_channel->band == IEEE80211_BAND_5GHZ && !old_band_5ghz) {
3338 tmp32 = b43_read32(dev, B43_MMIO_PSM_PHY_HDR); 3336 tmp32 = b43_read32(dev, B43_MMIO_PSM_PHY_HDR);
3339 b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32 | 4); 3337 b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32 | 4);
3340 b43_phy_set(dev, B43_PHY_B_BBCFG, 0xC000); 3338 b43_phy_set(dev, B43_PHY_B_BBCFG, 0xC000);
3341 b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32); 3339 b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32);
3342 b43_phy_set(dev, B43_NPHY_BANDCTL, B43_NPHY_BANDCTL_5GHZ); 3340 b43_phy_set(dev, B43_NPHY_BANDCTL, B43_NPHY_BANDCTL_5GHZ);
3343 } else if (chanspec.b_freq == 1) { 3341 } else if (new_channel->band == IEEE80211_BAND_2GHZ && old_band_5ghz) {
3344 b43_phy_mask(dev, B43_NPHY_BANDCTL, ~B43_NPHY_BANDCTL_5GHZ); 3342 b43_phy_mask(dev, B43_NPHY_BANDCTL, ~B43_NPHY_BANDCTL_5GHZ);
3345 tmp32 = b43_read32(dev, B43_MMIO_PSM_PHY_HDR); 3343 tmp32 = b43_read32(dev, B43_MMIO_PSM_PHY_HDR);
3346 b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32 | 4); 3344 b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32 | 4);
@@ -3350,13 +3348,12 @@ static void b43_nphy_chanspec_setup(struct b43_wldev *dev,
3350 3348
3351 b43_chantab_phy_upload(dev, e); 3349 b43_chantab_phy_upload(dev, e);
3352 3350
3353 3351 if (new_channel->hw_value == 14) {
3354 if (nphy->radio_chanspec.channel == 14) {
3355 b43_nphy_classifier(dev, 2, 0); 3352 b43_nphy_classifier(dev, 2, 0);
3356 b43_phy_set(dev, B43_PHY_B_TEST, 0x0800); 3353 b43_phy_set(dev, B43_PHY_B_TEST, 0x0800);
3357 } else { 3354 } else {
3358 b43_nphy_classifier(dev, 2, 2); 3355 b43_nphy_classifier(dev, 2, 2);
3359 if (chanspec.b_freq == 2) 3356 if (new_channel->band == IEEE80211_BAND_2GHZ)
3360 b43_phy_mask(dev, B43_PHY_B_TEST, ~0x840); 3357 b43_phy_mask(dev, B43_PHY_B_TEST, ~0x840);
3361 } 3358 }
3362 3359
@@ -3379,53 +3376,57 @@ static void b43_nphy_chanspec_setup(struct b43_wldev *dev,
3379} 3376}
3380 3377
3381/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetChanspec */ 3378/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetChanspec */
3382static int b43_nphy_set_chanspec(struct b43_wldev *dev, 3379static int b43_nphy_set_channel(struct b43_wldev *dev,
3383 struct b43_chanspec chanspec) 3380 struct ieee80211_channel *channel,
3381 enum nl80211_channel_type channel_type)
3384{ 3382{
3383 struct b43_phy *phy = &dev->phy;
3385 struct b43_phy_n *nphy = dev->phy.n; 3384 struct b43_phy_n *nphy = dev->phy.n;
3386 3385
3387 const struct b43_nphy_channeltab_entry_rev2 *tabent_r2; 3386 const struct b43_nphy_channeltab_entry_rev2 *tabent_r2;
3388 const struct b43_nphy_channeltab_entry_rev3 *tabent_r3; 3387 const struct b43_nphy_channeltab_entry_rev3 *tabent_r3;
3389 3388
3390 u8 tmp; 3389 u8 tmp;
3391 u8 channel = chanspec.channel;
3392 3390
3393 if (dev->phy.rev >= 3) { 3391 if (dev->phy.rev >= 3) {
3394 /* TODO */ 3392 tabent_r3 = b43_nphy_get_chantabent_rev3(dev,
3393 channel->center_freq);
3395 tabent_r3 = NULL; 3394 tabent_r3 = NULL;
3396 if (!tabent_r3) 3395 if (!tabent_r3)
3397 return -ESRCH; 3396 return -ESRCH;
3398 } else { 3397 } else {
3399 tabent_r2 = b43_nphy_get_chantabent_rev2(dev, channel); 3398 tabent_r2 = b43_nphy_get_chantabent_rev2(dev,
3399 channel->hw_value);
3400 if (!tabent_r2) 3400 if (!tabent_r2)
3401 return -ESRCH; 3401 return -ESRCH;
3402 } 3402 }
3403 3403
3404 nphy->radio_chanspec = chanspec; 3404 /* Channel is set later in common code, but we need to set it on our
3405 own to let this function's subcalls work properly. */
3406 phy->channel = channel->hw_value;
3407 phy->channel_freq = channel->center_freq;
3405 3408
3406 if (chanspec.b_width != nphy->b_width) 3409 if (b43_channel_type_is_40mhz(phy->channel_type) !=
3407 ; /* TODO: BMAC BW Set (chanspec.b_width) */ 3410 b43_channel_type_is_40mhz(channel_type))
3411 ; /* TODO: BMAC BW Set (channel_type) */
3408 3412
3409 /* TODO: use defines */ 3413 if (channel_type == NL80211_CHAN_HT40PLUS)
3410 if (chanspec.b_width == 3) { 3414 b43_phy_set(dev, B43_NPHY_RXCTL,
3411 if (chanspec.sideband == 2) 3415 B43_NPHY_RXCTL_BSELU20);
3412 b43_phy_set(dev, B43_NPHY_RXCTL, 3416 else if (channel_type == NL80211_CHAN_HT40MINUS)
3413 B43_NPHY_RXCTL_BSELU20); 3417 b43_phy_mask(dev, B43_NPHY_RXCTL,
3414 else 3418 ~B43_NPHY_RXCTL_BSELU20);
3415 b43_phy_mask(dev, B43_NPHY_RXCTL,
3416 ~B43_NPHY_RXCTL_BSELU20);
3417 }
3418 3419
3419 if (dev->phy.rev >= 3) { 3420 if (dev->phy.rev >= 3) {
3420 tmp = (chanspec.b_freq == 1) ? 4 : 0; 3421 tmp = (channel->band == IEEE80211_BAND_5GHZ) ? 4 : 0;
3421 b43_radio_maskset(dev, 0x08, 0xFFFB, tmp); 3422 b43_radio_maskset(dev, 0x08, 0xFFFB, tmp);
3422 /* TODO: PHY Radio2056 Setup (dev, tabent_r3); */ 3423 /* TODO: PHY Radio2056 Setup (dev, tabent_r3); */
3423 b43_nphy_chanspec_setup(dev, &(tabent_r3->phy_regs), chanspec); 3424 b43_nphy_channel_setup(dev, &(tabent_r3->phy_regs), channel);
3424 } else { 3425 } else {
3425 tmp = (chanspec.b_freq == 1) ? 0x0020 : 0x0050; 3426 tmp = (channel->band == IEEE80211_BAND_5GHZ) ? 0x0020 : 0x0050;
3426 b43_radio_maskset(dev, B2055_MASTER1, 0xFF8F, tmp); 3427 b43_radio_maskset(dev, B2055_MASTER1, 0xFF8F, tmp);
3427 b43_radio_2055_setup(dev, tabent_r2); 3428 b43_radio_2055_setup(dev, tabent_r2);
3428 b43_nphy_chanspec_setup(dev, &(tabent_r2->phy_regs), chanspec); 3429 b43_nphy_channel_setup(dev, &(tabent_r2->phy_regs), channel);
3429 } 3430 }
3430 3431
3431 return 0; 3432 return 0;
@@ -3567,8 +3568,8 @@ static void b43_nphy_op_switch_analog(struct b43_wldev *dev, bool on)
3567static int b43_nphy_op_switch_channel(struct b43_wldev *dev, 3568static int b43_nphy_op_switch_channel(struct b43_wldev *dev,
3568 unsigned int new_channel) 3569 unsigned int new_channel)
3569{ 3570{
3570 struct b43_phy_n *nphy = dev->phy.n; 3571 struct ieee80211_channel *channel = dev->wl->hw->conf.channel;
3571 struct b43_chanspec chanspec; 3572 enum nl80211_channel_type channel_type = dev->wl->hw->conf.channel_type;
3572 3573
3573 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { 3574 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
3574 if ((new_channel < 1) || (new_channel > 14)) 3575 if ((new_channel < 1) || (new_channel > 14))
@@ -3578,10 +3579,7 @@ static int b43_nphy_op_switch_channel(struct b43_wldev *dev,
3578 return -EINVAL; 3579 return -EINVAL;
3579 } 3580 }
3580 3581
3581 chanspec = nphy->radio_chanspec; 3582 return b43_nphy_set_channel(dev, channel, channel_type);
3582 chanspec.channel = new_channel;
3583
3584 return b43_nphy_set_chanspec(dev, chanspec);
3585} 3583}
3586 3584
3587static unsigned int b43_nphy_op_get_default_chan(struct b43_wldev *dev) 3585static unsigned int b43_nphy_op_get_default_chan(struct b43_wldev *dev)
diff --git a/drivers/net/wireless/b43/phy_n.h b/drivers/net/wireless/b43/phy_n.h
index 8b6d570dd0aa..c144e59a708b 100644
--- a/drivers/net/wireless/b43/phy_n.h
+++ b/drivers/net/wireless/b43/phy_n.h
@@ -714,223 +714,11 @@
714#define B43_PHY_B_BBCFG B43_PHY_N_BMODE(0x001) /* BB config */ 714#define B43_PHY_B_BBCFG B43_PHY_N_BMODE(0x001) /* BB config */
715#define B43_PHY_B_TEST B43_PHY_N_BMODE(0x00A) 715#define B43_PHY_B_TEST B43_PHY_N_BMODE(0x00A)
716 716
717
718/* Broadcom 2055 radio registers */
719
720#define B2055_GEN_SPARE 0x00 /* GEN spare */
721#define B2055_SP_PINPD 0x02 /* SP PIN PD */
722#define B2055_C1_SP_RSSI 0x03 /* SP RSSI Core 1 */
723#define B2055_C1_SP_PDMISC 0x04 /* SP PD MISC Core 1 */
724#define B2055_C2_SP_RSSI 0x05 /* SP RSSI Core 2 */
725#define B2055_C2_SP_PDMISC 0x06 /* SP PD MISC Core 2 */
726#define B2055_C1_SP_RXGC1 0x07 /* SP RX GC1 Core 1 */
727#define B2055_C1_SP_RXGC2 0x08 /* SP RX GC2 Core 1 */
728#define B2055_C2_SP_RXGC1 0x09 /* SP RX GC1 Core 2 */
729#define B2055_C2_SP_RXGC2 0x0A /* SP RX GC2 Core 2 */
730#define B2055_C1_SP_LPFBWSEL 0x0B /* SP LPF BW select Core 1 */
731#define B2055_C2_SP_LPFBWSEL 0x0C /* SP LPF BW select Core 2 */
732#define B2055_C1_SP_TXGC1 0x0D /* SP TX GC1 Core 1 */
733#define B2055_C1_SP_TXGC2 0x0E /* SP TX GC2 Core 1 */
734#define B2055_C2_SP_TXGC1 0x0F /* SP TX GC1 Core 2 */
735#define B2055_C2_SP_TXGC2 0x10 /* SP TX GC2 Core 2 */
736#define B2055_MASTER1 0x11 /* Master control 1 */
737#define B2055_MASTER2 0x12 /* Master control 2 */
738#define B2055_PD_LGEN 0x13 /* PD LGEN */
739#define B2055_PD_PLLTS 0x14 /* PD PLL TS */
740#define B2055_C1_PD_LGBUF 0x15 /* PD Core 1 LGBUF */
741#define B2055_C1_PD_TX 0x16 /* PD Core 1 TX */
742#define B2055_C1_PD_RXTX 0x17 /* PD Core 1 RXTX */
743#define B2055_C1_PD_RSSIMISC 0x18 /* PD Core 1 RSSI MISC */
744#define B2055_C2_PD_LGBUF 0x19 /* PD Core 2 LGBUF */
745#define B2055_C2_PD_TX 0x1A /* PD Core 2 TX */
746#define B2055_C2_PD_RXTX 0x1B /* PD Core 2 RXTX */
747#define B2055_C2_PD_RSSIMISC 0x1C /* PD Core 2 RSSI MISC */
748#define B2055_PWRDET_LGEN 0x1D /* PWRDET LGEN */
749#define B2055_C1_PWRDET_LGBUF 0x1E /* PWRDET LGBUF Core 1 */
750#define B2055_C1_PWRDET_RXTX 0x1F /* PWRDET RXTX Core 1 */
751#define B2055_C2_PWRDET_LGBUF 0x20 /* PWRDET LGBUF Core 2 */
752#define B2055_C2_PWRDET_RXTX 0x21 /* PWRDET RXTX Core 2 */
753#define B2055_RRCCAL_CS 0x22 /* RRCCAL Control spare */
754#define B2055_RRCCAL_NOPTSEL 0x23 /* RRCCAL N OPT SEL */
755#define B2055_CAL_MISC 0x24 /* CAL MISC */
756#define B2055_CAL_COUT 0x25 /* CAL Counter out */
757#define B2055_CAL_COUT2 0x26 /* CAL Counter out 2 */
758#define B2055_CAL_CVARCTL 0x27 /* CAL CVAR Control */
759#define B2055_CAL_RVARCTL 0x28 /* CAL RVAR Control */
760#define B2055_CAL_LPOCTL 0x29 /* CAL LPO Control */
761#define B2055_CAL_TS 0x2A /* CAL TS */
762#define B2055_CAL_RCCALRTS 0x2B /* CAL RCCAL READ TS */
763#define B2055_CAL_RCALRTS 0x2C /* CAL RCAL READ TS */
764#define B2055_PADDRV 0x2D /* PAD driver */
765#define B2055_XOCTL1 0x2E /* XO Control 1 */
766#define B2055_XOCTL2 0x2F /* XO Control 2 */
767#define B2055_XOREGUL 0x30 /* XO Regulator */
768#define B2055_XOMISC 0x31 /* XO misc */
769#define B2055_PLL_LFC1 0x32 /* PLL LF C1 */
770#define B2055_PLL_CALVTH 0x33 /* PLL CAL VTH */
771#define B2055_PLL_LFC2 0x34 /* PLL LF C2 */
772#define B2055_PLL_REF 0x35 /* PLL reference */
773#define B2055_PLL_LFR1 0x36 /* PLL LF R1 */
774#define B2055_PLL_PFDCP 0x37 /* PLL PFD CP */
775#define B2055_PLL_IDAC_CPOPAMP 0x38 /* PLL IDAC CPOPAMP */
776#define B2055_PLL_CPREG 0x39 /* PLL CP Regulator */
777#define B2055_PLL_RCAL 0x3A /* PLL RCAL */
778#define B2055_RF_PLLMOD0 0x3B /* RF PLL MOD0 */
779#define B2055_RF_PLLMOD1 0x3C /* RF PLL MOD1 */
780#define B2055_RF_MMDIDAC1 0x3D /* RF MMD IDAC 1 */
781#define B2055_RF_MMDIDAC0 0x3E /* RF MMD IDAC 0 */
782#define B2055_RF_MMDSP 0x3F /* RF MMD spare */
783#define B2055_VCO_CAL1 0x40 /* VCO cal 1 */
784#define B2055_VCO_CAL2 0x41 /* VCO cal 2 */
785#define B2055_VCO_CAL3 0x42 /* VCO cal 3 */
786#define B2055_VCO_CAL4 0x43 /* VCO cal 4 */
787#define B2055_VCO_CAL5 0x44 /* VCO cal 5 */
788#define B2055_VCO_CAL6 0x45 /* VCO cal 6 */
789#define B2055_VCO_CAL7 0x46 /* VCO cal 7 */
790#define B2055_VCO_CAL8 0x47 /* VCO cal 8 */
791#define B2055_VCO_CAL9 0x48 /* VCO cal 9 */
792#define B2055_VCO_CAL10 0x49 /* VCO cal 10 */
793#define B2055_VCO_CAL11 0x4A /* VCO cal 11 */
794#define B2055_VCO_CAL12 0x4B /* VCO cal 12 */
795#define B2055_VCO_CAL13 0x4C /* VCO cal 13 */
796#define B2055_VCO_CAL14 0x4D /* VCO cal 14 */
797#define B2055_VCO_CAL15 0x4E /* VCO cal 15 */
798#define B2055_VCO_CAL16 0x4F /* VCO cal 16 */
799#define B2055_VCO_KVCO 0x50 /* VCO KVCO */
800#define B2055_VCO_CAPTAIL 0x51 /* VCO CAP TAIL */
801#define B2055_VCO_IDACVCO 0x52 /* VCO IDAC VCO */
802#define B2055_VCO_REG 0x53 /* VCO Regulator */
803#define B2055_PLL_RFVTH 0x54 /* PLL RF VTH */
804#define B2055_LGBUF_CENBUF 0x55 /* LGBUF CEN BUF */
805#define B2055_LGEN_TUNE1 0x56 /* LGEN tune 1 */
806#define B2055_LGEN_TUNE2 0x57 /* LGEN tune 2 */
807#define B2055_LGEN_IDAC1 0x58 /* LGEN IDAC 1 */
808#define B2055_LGEN_IDAC2 0x59 /* LGEN IDAC 2 */
809#define B2055_LGEN_BIASC 0x5A /* LGEN BIAS counter */
810#define B2055_LGEN_BIASIDAC 0x5B /* LGEN BIAS IDAC */
811#define B2055_LGEN_RCAL 0x5C /* LGEN RCAL */
812#define B2055_LGEN_DIV 0x5D /* LGEN div */
813#define B2055_LGEN_SPARE2 0x5E /* LGEN spare 2 */
814#define B2055_C1_LGBUF_ATUNE 0x5F /* Core 1 LGBUF A tune */
815#define B2055_C1_LGBUF_GTUNE 0x60 /* Core 1 LGBUF G tune */
816#define B2055_C1_LGBUF_DIV 0x61 /* Core 1 LGBUF div */
817#define B2055_C1_LGBUF_AIDAC 0x62 /* Core 1 LGBUF A IDAC */
818#define B2055_C1_LGBUF_GIDAC 0x63 /* Core 1 LGBUF G IDAC */
819#define B2055_C1_LGBUF_IDACFO 0x64 /* Core 1 LGBUF IDAC filter override */
820#define B2055_C1_LGBUF_SPARE 0x65 /* Core 1 LGBUF spare */
821#define B2055_C1_RX_RFSPC1 0x66 /* Core 1 RX RF SPC1 */
822#define B2055_C1_RX_RFR1 0x67 /* Core 1 RX RF reg 1 */
823#define B2055_C1_RX_RFR2 0x68 /* Core 1 RX RF reg 2 */
824#define B2055_C1_RX_RFRCAL 0x69 /* Core 1 RX RF RCAL */
825#define B2055_C1_RX_BB_BLCMP 0x6A /* Core 1 RX Baseband BUFI LPF CMP */
826#define B2055_C1_RX_BB_LPF 0x6B /* Core 1 RX Baseband LPF */
827#define B2055_C1_RX_BB_MIDACHP 0x6C /* Core 1 RX Baseband MIDAC High-pass */
828#define B2055_C1_RX_BB_VGA1IDAC 0x6D /* Core 1 RX Baseband VGA1 IDAC */
829#define B2055_C1_RX_BB_VGA2IDAC 0x6E /* Core 1 RX Baseband VGA2 IDAC */
830#define B2055_C1_RX_BB_VGA3IDAC 0x6F /* Core 1 RX Baseband VGA3 IDAC */
831#define B2055_C1_RX_BB_BUFOCTL 0x70 /* Core 1 RX Baseband BUFO Control */
832#define B2055_C1_RX_BB_RCCALCTL 0x71 /* Core 1 RX Baseband RCCAL Control */
833#define B2055_C1_RX_BB_RSSICTL1 0x72 /* Core 1 RX Baseband RSSI Control 1 */
834#define B2055_C1_RX_BB_RSSICTL2 0x73 /* Core 1 RX Baseband RSSI Control 2 */
835#define B2055_C1_RX_BB_RSSICTL3 0x74 /* Core 1 RX Baseband RSSI Control 3 */
836#define B2055_C1_RX_BB_RSSICTL4 0x75 /* Core 1 RX Baseband RSSI Control 4 */
837#define B2055_C1_RX_BB_RSSICTL5 0x76 /* Core 1 RX Baseband RSSI Control 5 */
838#define B2055_C1_RX_BB_REG 0x77 /* Core 1 RX Baseband Regulator */
839#define B2055_C1_RX_BB_SPARE1 0x78 /* Core 1 RX Baseband spare 1 */
840#define B2055_C1_RX_TXBBRCAL 0x79 /* Core 1 RX TX BB RCAL */
841#define B2055_C1_TX_RF_SPGA 0x7A /* Core 1 TX RF SGM PGA */
842#define B2055_C1_TX_RF_SPAD 0x7B /* Core 1 TX RF SGM PAD */
843#define B2055_C1_TX_RF_CNTPGA1 0x7C /* Core 1 TX RF counter PGA 1 */
844#define B2055_C1_TX_RF_CNTPAD1 0x7D /* Core 1 TX RF counter PAD 1 */
845#define B2055_C1_TX_RF_PGAIDAC 0x7E /* Core 1 TX RF PGA IDAC */
846#define B2055_C1_TX_PGAPADTN 0x7F /* Core 1 TX PGA PAD TN */
847#define B2055_C1_TX_PADIDAC1 0x80 /* Core 1 TX PAD IDAC 1 */
848#define B2055_C1_TX_PADIDAC2 0x81 /* Core 1 TX PAD IDAC 2 */
849#define B2055_C1_TX_MXBGTRIM 0x82 /* Core 1 TX MX B/G TRIM */
850#define B2055_C1_TX_RF_RCAL 0x83 /* Core 1 TX RF RCAL */
851#define B2055_C1_TX_RF_PADTSSI1 0x84 /* Core 1 TX RF PAD TSSI1 */
852#define B2055_C1_TX_RF_PADTSSI2 0x85 /* Core 1 TX RF PAD TSSI2 */
853#define B2055_C1_TX_RF_SPARE 0x86 /* Core 1 TX RF spare */
854#define B2055_C1_TX_RF_IQCAL1 0x87 /* Core 1 TX RF I/Q CAL 1 */
855#define B2055_C1_TX_RF_IQCAL2 0x88 /* Core 1 TX RF I/Q CAL 2 */
856#define B2055_C1_TXBB_RCCAL 0x89 /* Core 1 TXBB RC CAL Control */
857#define B2055_C1_TXBB_LPF1 0x8A /* Core 1 TXBB LPF 1 */
858#define B2055_C1_TX_VOSCNCL 0x8B /* Core 1 TX VOS CNCL */
859#define B2055_C1_TX_LPF_MXGMIDAC 0x8C /* Core 1 TX LPF MXGM IDAC */
860#define B2055_C1_TX_BB_MXGM 0x8D /* Core 1 TX BB MXGM */
861#define B2055_C2_LGBUF_ATUNE 0x8E /* Core 2 LGBUF A tune */
862#define B2055_C2_LGBUF_GTUNE 0x8F /* Core 2 LGBUF G tune */
863#define B2055_C2_LGBUF_DIV 0x90 /* Core 2 LGBUF div */
864#define B2055_C2_LGBUF_AIDAC 0x91 /* Core 2 LGBUF A IDAC */
865#define B2055_C2_LGBUF_GIDAC 0x92 /* Core 2 LGBUF G IDAC */
866#define B2055_C2_LGBUF_IDACFO 0x93 /* Core 2 LGBUF IDAC filter override */
867#define B2055_C2_LGBUF_SPARE 0x94 /* Core 2 LGBUF spare */
868#define B2055_C2_RX_RFSPC1 0x95 /* Core 2 RX RF SPC1 */
869#define B2055_C2_RX_RFR1 0x96 /* Core 2 RX RF reg 1 */
870#define B2055_C2_RX_RFR2 0x97 /* Core 2 RX RF reg 2 */
871#define B2055_C2_RX_RFRCAL 0x98 /* Core 2 RX RF RCAL */
872#define B2055_C2_RX_BB_BLCMP 0x99 /* Core 2 RX Baseband BUFI LPF CMP */
873#define B2055_C2_RX_BB_LPF 0x9A /* Core 2 RX Baseband LPF */
874#define B2055_C2_RX_BB_MIDACHP 0x9B /* Core 2 RX Baseband MIDAC High-pass */
875#define B2055_C2_RX_BB_VGA1IDAC 0x9C /* Core 2 RX Baseband VGA1 IDAC */
876#define B2055_C2_RX_BB_VGA2IDAC 0x9D /* Core 2 RX Baseband VGA2 IDAC */
877#define B2055_C2_RX_BB_VGA3IDAC 0x9E /* Core 2 RX Baseband VGA3 IDAC */
878#define B2055_C2_RX_BB_BUFOCTL 0x9F /* Core 2 RX Baseband BUFO Control */
879#define B2055_C2_RX_BB_RCCALCTL 0xA0 /* Core 2 RX Baseband RCCAL Control */
880#define B2055_C2_RX_BB_RSSICTL1 0xA1 /* Core 2 RX Baseband RSSI Control 1 */
881#define B2055_C2_RX_BB_RSSICTL2 0xA2 /* Core 2 RX Baseband RSSI Control 2 */
882#define B2055_C2_RX_BB_RSSICTL3 0xA3 /* Core 2 RX Baseband RSSI Control 3 */
883#define B2055_C2_RX_BB_RSSICTL4 0xA4 /* Core 2 RX Baseband RSSI Control 4 */
884#define B2055_C2_RX_BB_RSSICTL5 0xA5 /* Core 2 RX Baseband RSSI Control 5 */
885#define B2055_C2_RX_BB_REG 0xA6 /* Core 2 RX Baseband Regulator */
886#define B2055_C2_RX_BB_SPARE1 0xA7 /* Core 2 RX Baseband spare 1 */
887#define B2055_C2_RX_TXBBRCAL 0xA8 /* Core 2 RX TX BB RCAL */
888#define B2055_C2_TX_RF_SPGA 0xA9 /* Core 2 TX RF SGM PGA */
889#define B2055_C2_TX_RF_SPAD 0xAA /* Core 2 TX RF SGM PAD */
890#define B2055_C2_TX_RF_CNTPGA1 0xAB /* Core 2 TX RF counter PGA 1 */
891#define B2055_C2_TX_RF_CNTPAD1 0xAC /* Core 2 TX RF counter PAD 1 */
892#define B2055_C2_TX_RF_PGAIDAC 0xAD /* Core 2 TX RF PGA IDAC */
893#define B2055_C2_TX_PGAPADTN 0xAE /* Core 2 TX PGA PAD TN */
894#define B2055_C2_TX_PADIDAC1 0xAF /* Core 2 TX PAD IDAC 1 */
895#define B2055_C2_TX_PADIDAC2 0xB0 /* Core 2 TX PAD IDAC 2 */
896#define B2055_C2_TX_MXBGTRIM 0xB1 /* Core 2 TX MX B/G TRIM */
897#define B2055_C2_TX_RF_RCAL 0xB2 /* Core 2 TX RF RCAL */
898#define B2055_C2_TX_RF_PADTSSI1 0xB3 /* Core 2 TX RF PAD TSSI1 */
899#define B2055_C2_TX_RF_PADTSSI2 0xB4 /* Core 2 TX RF PAD TSSI2 */
900#define B2055_C2_TX_RF_SPARE 0xB5 /* Core 2 TX RF spare */
901#define B2055_C2_TX_RF_IQCAL1 0xB6 /* Core 2 TX RF I/Q CAL 1 */
902#define B2055_C2_TX_RF_IQCAL2 0xB7 /* Core 2 TX RF I/Q CAL 2 */
903#define B2055_C2_TXBB_RCCAL 0xB8 /* Core 2 TXBB RC CAL Control */
904#define B2055_C2_TXBB_LPF1 0xB9 /* Core 2 TXBB LPF 1 */
905#define B2055_C2_TX_VOSCNCL 0xBA /* Core 2 TX VOS CNCL */
906#define B2055_C2_TX_LPF_MXGMIDAC 0xBB /* Core 2 TX LPF MXGM IDAC */
907#define B2055_C2_TX_BB_MXGM 0xBC /* Core 2 TX BB MXGM */
908#define B2055_PRG_GCHP21 0xBD /* PRG GC HPVGA23 21 */
909#define B2055_PRG_GCHP22 0xBE /* PRG GC HPVGA23 22 */
910#define B2055_PRG_GCHP23 0xBF /* PRG GC HPVGA23 23 */
911#define B2055_PRG_GCHP24 0xC0 /* PRG GC HPVGA23 24 */
912#define B2055_PRG_GCHP25 0xC1 /* PRG GC HPVGA23 25 */
913#define B2055_PRG_GCHP26 0xC2 /* PRG GC HPVGA23 26 */
914#define B2055_PRG_GCHP27 0xC3 /* PRG GC HPVGA23 27 */
915#define B2055_PRG_GCHP28 0xC4 /* PRG GC HPVGA23 28 */
916#define B2055_PRG_GCHP29 0xC5 /* PRG GC HPVGA23 29 */
917#define B2055_PRG_GCHP30 0xC6 /* PRG GC HPVGA23 30 */
918#define B2055_C1_LNA_GAINBST 0xCD /* Core 1 LNA GAINBST */
919#define B2055_C1_B0NB_RSSIVCM 0xD2 /* Core 1 B0 narrow-band RSSI VCM */
920#define B2055_C1_GENSPARE2 0xD6 /* Core 1 GEN spare 2 */
921#define B2055_C2_LNA_GAINBST 0xD9 /* Core 2 LNA GAINBST */
922#define B2055_C2_B0NB_RSSIVCM 0xDE /* Core 2 B0 narrow-band RSSI VCM */
923#define B2055_C2_GENSPARE2 0xE2 /* Core 2 GEN spare 2 */
924
925
926
927struct b43_wldev; 717struct b43_wldev;
928 718
929struct b43_chanspec { 719struct b43_chanspec {
930 u8 channel; 720 u16 center_freq;
931 u8 sideband; 721 enum nl80211_channel_type channel_type;
932 u8 b_width;
933 u8 b_freq;
934}; 722};
935 723
936struct b43_phy_n_iq_comp { 724struct b43_phy_n_iq_comp {
@@ -984,8 +772,6 @@ struct b43_phy_n {
984 u16 papd_epsilon_offset[2]; 772 u16 papd_epsilon_offset[2];
985 s32 preamble_override; 773 s32 preamble_override;
986 u32 bb_mult_save; 774 u32 bb_mult_save;
987 u8 b_width;
988 struct b43_chanspec radio_chanspec;
989 775
990 bool gain_boost; 776 bool gain_boost;
991 bool elna_gain_config; 777 bool elna_gain_config;
diff --git a/drivers/net/wireless/b43/radio_2055.c b/drivers/net/wireless/b43/radio_2055.c
new file mode 100644
index 000000000000..1b5316586cbf
--- /dev/null
+++ b/drivers/net/wireless/b43/radio_2055.c
@@ -0,0 +1,1332 @@
1/*
2
3 Broadcom B43 wireless driver
4 IEEE 802.11n PHY and radio device data tables
5
6 Copyright (c) 2008 Michael Buesch <mb@bu3sch.de>
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; see the file COPYING. If not, write to
20 the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
21 Boston, MA 02110-1301, USA.
22
23*/
24
25#include "b43.h"
26#include "radio_2055.h"
27#include "phy_common.h"
28
29struct b2055_inittab_entry {
30 /* Value to write if we use the 5GHz band. */
31 u16 ghz5;
32 /* Value to write if we use the 2.4GHz band. */
33 u16 ghz2;
34 /* Flags */
35 u8 flags;
36#define B2055_INITTAB_ENTRY_OK 0x01
37#define B2055_INITTAB_UPLOAD 0x02
38};
39#define UPLOAD .flags = B2055_INITTAB_ENTRY_OK | B2055_INITTAB_UPLOAD
40#define NOUPLOAD .flags = B2055_INITTAB_ENTRY_OK
41
42static const struct b2055_inittab_entry b2055_inittab [] = {
43 [B2055_SP_PINPD] = { .ghz5 = 0x0080, .ghz2 = 0x0080, NOUPLOAD, },
44 [B2055_C1_SP_RSSI] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
45 [B2055_C1_SP_PDMISC] = { .ghz5 = 0x0027, .ghz2 = 0x0027, NOUPLOAD, },
46 [B2055_C2_SP_RSSI] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
47 [B2055_C2_SP_PDMISC] = { .ghz5 = 0x0027, .ghz2 = 0x0027, NOUPLOAD, },
48 [B2055_C1_SP_RXGC1] = { .ghz5 = 0x007F, .ghz2 = 0x007F, UPLOAD, },
49 [B2055_C1_SP_RXGC2] = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, },
50 [B2055_C2_SP_RXGC1] = { .ghz5 = 0x007F, .ghz2 = 0x007F, UPLOAD, },
51 [B2055_C2_SP_RXGC2] = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, },
52 [B2055_C1_SP_LPFBWSEL] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
53 [B2055_C2_SP_LPFBWSEL] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
54 [B2055_C1_SP_TXGC1] = { .ghz5 = 0x004F, .ghz2 = 0x004F, UPLOAD, },
55 [B2055_C1_SP_TXGC2] = { .ghz5 = 0x0005, .ghz2 = 0x0005, UPLOAD, },
56 [B2055_C2_SP_TXGC1] = { .ghz5 = 0x004F, .ghz2 = 0x004F, UPLOAD, },
57 [B2055_C2_SP_TXGC2] = { .ghz5 = 0x0005, .ghz2 = 0x0005, UPLOAD, },
58 [B2055_MASTER1] = { .ghz5 = 0x00D0, .ghz2 = 0x00D0, NOUPLOAD, },
59 [B2055_MASTER2] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
60 [B2055_PD_LGEN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
61 [B2055_PD_PLLTS] = { .ghz5 = 0x0040, .ghz2 = 0x0040, NOUPLOAD, },
62 [B2055_C1_PD_LGBUF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
63 [B2055_C1_PD_TX] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
64 [B2055_C1_PD_RXTX] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
65 [B2055_C1_PD_RSSIMISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
66 [B2055_C2_PD_LGBUF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
67 [B2055_C2_PD_TX] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
68 [B2055_C2_PD_RXTX] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
69 [B2055_C2_PD_RSSIMISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
70 [B2055_PWRDET_LGEN] = { .ghz5 = 0x00C0, .ghz2 = 0x00C0, NOUPLOAD, },
71 [B2055_C1_PWRDET_LGBUF] = { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, },
72 [B2055_C1_PWRDET_RXTX] = { .ghz5 = 0x00C0, .ghz2 = 0x00C0, NOUPLOAD, },
73 [B2055_C2_PWRDET_LGBUF] = { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, },
74 [B2055_C2_PWRDET_RXTX] = { .ghz5 = 0x00C0, .ghz2 = 0x00C0, NOUPLOAD, },
75 [B2055_RRCCAL_CS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
76 [B2055_RRCCAL_NOPTSEL] = { .ghz5 = 0x002C, .ghz2 = 0x002C, NOUPLOAD, },
77 [B2055_CAL_MISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
78 [B2055_CAL_COUT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
79 [B2055_CAL_COUT2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
80 [B2055_CAL_CVARCTL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
81 [B2055_CAL_RVARCTL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
82 [B2055_CAL_LPOCTL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
83 [B2055_CAL_TS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
84 [B2055_CAL_RCCALRTS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
85 [B2055_CAL_RCALRTS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
86 [B2055_PADDRV] = { .ghz5 = 0x00A4, .ghz2 = 0x00A4, NOUPLOAD, },
87 [B2055_XOCTL1] = { .ghz5 = 0x0038, .ghz2 = 0x0038, NOUPLOAD, },
88 [B2055_XOCTL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
89 [B2055_XOREGUL] = { .ghz5 = 0x0004, .ghz2 = 0x0004, UPLOAD, },
90 [B2055_XOMISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
91 [B2055_PLL_LFC1] = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
92 [B2055_PLL_CALVTH] = { .ghz5 = 0x0087, .ghz2 = 0x0087, NOUPLOAD, },
93 [B2055_PLL_LFC2] = { .ghz5 = 0x0009, .ghz2 = 0x0009, NOUPLOAD, },
94 [B2055_PLL_REF] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, },
95 [B2055_PLL_LFR1] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, },
96 [B2055_PLL_PFDCP] = { .ghz5 = 0x0018, .ghz2 = 0x0018, UPLOAD, },
97 [B2055_PLL_IDAC_CPOPAMP] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
98 [B2055_PLL_CPREG] = { .ghz5 = 0x0004, .ghz2 = 0x0004, UPLOAD, },
99 [B2055_PLL_RCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
100 [B2055_RF_PLLMOD0] = { .ghz5 = 0x009E, .ghz2 = 0x009E, NOUPLOAD, },
101 [B2055_RF_PLLMOD1] = { .ghz5 = 0x0009, .ghz2 = 0x0009, NOUPLOAD, },
102 [B2055_RF_MMDIDAC1] = { .ghz5 = 0x00C8, .ghz2 = 0x00C8, UPLOAD, },
103 [B2055_RF_MMDIDAC0] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
104 [B2055_RF_MMDSP] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
105 [B2055_VCO_CAL1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
106 [B2055_VCO_CAL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
107 [B2055_VCO_CAL3] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
108 [B2055_VCO_CAL4] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
109 [B2055_VCO_CAL5] = { .ghz5 = 0x0096, .ghz2 = 0x0096, NOUPLOAD, },
110 [B2055_VCO_CAL6] = { .ghz5 = 0x003E, .ghz2 = 0x003E, NOUPLOAD, },
111 [B2055_VCO_CAL7] = { .ghz5 = 0x003E, .ghz2 = 0x003E, NOUPLOAD, },
112 [B2055_VCO_CAL8] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, },
113 [B2055_VCO_CAL9] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
114 [B2055_VCO_CAL10] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
115 [B2055_VCO_CAL11] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
116 [B2055_VCO_CAL12] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
117 [B2055_VCO_CAL13] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
118 [B2055_VCO_CAL14] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
119 [B2055_VCO_CAL15] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
120 [B2055_VCO_CAL16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
121 [B2055_VCO_KVCO] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
122 [B2055_VCO_CAPTAIL] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
123 [B2055_VCO_IDACVCO] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
124 [B2055_VCO_REG] = { .ghz5 = 0x0084, .ghz2 = 0x0084, UPLOAD, },
125 [B2055_PLL_RFVTH] = { .ghz5 = 0x00C3, .ghz2 = 0x00C3, NOUPLOAD, },
126 [B2055_LGBUF_CENBUF] = { .ghz5 = 0x008F, .ghz2 = 0x008F, NOUPLOAD, },
127 [B2055_LGEN_TUNE1] = { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, },
128 [B2055_LGEN_TUNE2] = { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, },
129 [B2055_LGEN_IDAC1] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
130 [B2055_LGEN_IDAC2] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
131 [B2055_LGEN_BIASC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
132 [B2055_LGEN_BIASIDAC] = { .ghz5 = 0x00CC, .ghz2 = 0x00CC, NOUPLOAD, },
133 [B2055_LGEN_RCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
134 [B2055_LGEN_DIV] = { .ghz5 = 0x0080, .ghz2 = 0x0080, NOUPLOAD, },
135 [B2055_LGEN_SPARE2] = { .ghz5 = 0x0080, .ghz2 = 0x0080, NOUPLOAD, },
136 [B2055_C1_LGBUF_ATUNE] = { .ghz5 = 0x00F8, .ghz2 = 0x00F8, NOUPLOAD, },
137 [B2055_C1_LGBUF_GTUNE] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
138 [B2055_C1_LGBUF_DIV] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
139 [B2055_C1_LGBUF_AIDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0008, UPLOAD, },
140 [B2055_C1_LGBUF_GIDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
141 [B2055_C1_LGBUF_IDACFO] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
142 [B2055_C1_LGBUF_SPARE] = { .ghz5 = 0x0001, .ghz2 = 0x0001, UPLOAD, },
143 [B2055_C1_RX_RFSPC1] = { .ghz5 = 0x008A, .ghz2 = 0x008A, NOUPLOAD, },
144 [B2055_C1_RX_RFR1] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
145 [B2055_C1_RX_RFR2] = { .ghz5 = 0x0083, .ghz2 = 0x0083, NOUPLOAD, },
146 [B2055_C1_RX_RFRCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
147 [B2055_C1_RX_BB_BLCMP] = { .ghz5 = 0x00A0, .ghz2 = 0x00A0, NOUPLOAD, },
148 [B2055_C1_RX_BB_LPF] = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
149 [B2055_C1_RX_BB_MIDACHP] = { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, },
150 [B2055_C1_RX_BB_VGA1IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
151 [B2055_C1_RX_BB_VGA2IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
152 [B2055_C1_RX_BB_VGA3IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
153 [B2055_C1_RX_BB_BUFOCTL] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
154 [B2055_C1_RX_BB_RCCALCTL] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
155 [B2055_C1_RX_BB_RSSICTL1] = { .ghz5 = 0x006A, .ghz2 = 0x006A, UPLOAD, },
156 [B2055_C1_RX_BB_RSSICTL2] = { .ghz5 = 0x00AB, .ghz2 = 0x00AB, UPLOAD, },
157 [B2055_C1_RX_BB_RSSICTL3] = { .ghz5 = 0x0013, .ghz2 = 0x0013, UPLOAD, },
158 [B2055_C1_RX_BB_RSSICTL4] = { .ghz5 = 0x00C1, .ghz2 = 0x00C1, UPLOAD, },
159 [B2055_C1_RX_BB_RSSICTL5] = { .ghz5 = 0x00AA, .ghz2 = 0x00AA, UPLOAD, },
160 [B2055_C1_RX_BB_REG] = { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, },
161 [B2055_C1_RX_BB_SPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
162 [B2055_C1_RX_TXBBRCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
163 [B2055_C1_TX_RF_SPGA] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
164 [B2055_C1_TX_RF_SPAD] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
165 [B2055_C1_TX_RF_CNTPGA1] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
166 [B2055_C1_TX_RF_CNTPAD1] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, },
167 [B2055_C1_TX_RF_PGAIDAC] = { .ghz5 = 0x0097, .ghz2 = 0x0097, UPLOAD, },
168 [B2055_C1_TX_PGAPADTN] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
169 [B2055_C1_TX_PADIDAC1] = { .ghz5 = 0x0014, .ghz2 = 0x0014, UPLOAD, },
170 [B2055_C1_TX_PADIDAC2] = { .ghz5 = 0x0033, .ghz2 = 0x0033, NOUPLOAD, },
171 [B2055_C1_TX_MXBGTRIM] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
172 [B2055_C1_TX_RF_RCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
173 [B2055_C1_TX_RF_PADTSSI1] = { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, },
174 [B2055_C1_TX_RF_PADTSSI2] = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
175 [B2055_C1_TX_RF_SPARE] = { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, },
176 [B2055_C1_TX_RF_IQCAL1] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
177 [B2055_C1_TX_RF_IQCAL2] = { .ghz5 = 0x00A4, .ghz2 = 0x00A4, NOUPLOAD, },
178 [B2055_C1_TXBB_RCCAL] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
179 [B2055_C1_TXBB_LPF1] = { .ghz5 = 0x0028, .ghz2 = 0x0028, NOUPLOAD, },
180 [B2055_C1_TX_VOSCNCL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
181 [B2055_C1_TX_LPF_MXGMIDAC] = { .ghz5 = 0x004A, .ghz2 = 0x004A, NOUPLOAD, },
182 [B2055_C1_TX_BB_MXGM] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
183 [B2055_C2_LGBUF_ATUNE] = { .ghz5 = 0x00F8, .ghz2 = 0x00F8, NOUPLOAD, },
184 [B2055_C2_LGBUF_GTUNE] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
185 [B2055_C2_LGBUF_DIV] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
186 [B2055_C2_LGBUF_AIDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0008, UPLOAD, },
187 [B2055_C2_LGBUF_GIDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
188 [B2055_C2_LGBUF_IDACFO] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
189 [B2055_C2_LGBUF_SPARE] = { .ghz5 = 0x0001, .ghz2 = 0x0001, UPLOAD, },
190 [B2055_C2_RX_RFSPC1] = { .ghz5 = 0x008A, .ghz2 = 0x008A, NOUPLOAD, },
191 [B2055_C2_RX_RFR1] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
192 [B2055_C2_RX_RFR2] = { .ghz5 = 0x0083, .ghz2 = 0x0083, NOUPLOAD, },
193 [B2055_C2_RX_RFRCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
194 [B2055_C2_RX_BB_BLCMP] = { .ghz5 = 0x00A0, .ghz2 = 0x00A0, NOUPLOAD, },
195 [B2055_C2_RX_BB_LPF] = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
196 [B2055_C2_RX_BB_MIDACHP] = { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, },
197 [B2055_C2_RX_BB_VGA1IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
198 [B2055_C2_RX_BB_VGA2IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
199 [B2055_C2_RX_BB_VGA3IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
200 [B2055_C2_RX_BB_BUFOCTL] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
201 [B2055_C2_RX_BB_RCCALCTL] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
202 [B2055_C2_RX_BB_RSSICTL1] = { .ghz5 = 0x006A, .ghz2 = 0x006A, UPLOAD, },
203 [B2055_C2_RX_BB_RSSICTL2] = { .ghz5 = 0x00AB, .ghz2 = 0x00AB, UPLOAD, },
204 [B2055_C2_RX_BB_RSSICTL3] = { .ghz5 = 0x0013, .ghz2 = 0x0013, UPLOAD, },
205 [B2055_C2_RX_BB_RSSICTL4] = { .ghz5 = 0x00C1, .ghz2 = 0x00C1, UPLOAD, },
206 [B2055_C2_RX_BB_RSSICTL5] = { .ghz5 = 0x00AA, .ghz2 = 0x00AA, UPLOAD, },
207 [B2055_C2_RX_BB_REG] = { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, },
208 [B2055_C2_RX_BB_SPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
209 [B2055_C2_RX_TXBBRCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
210 [B2055_C2_TX_RF_SPGA] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
211 [B2055_C2_TX_RF_SPAD] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
212 [B2055_C2_TX_RF_CNTPGA1] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
213 [B2055_C2_TX_RF_CNTPAD1] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, },
214 [B2055_C2_TX_RF_PGAIDAC] = { .ghz5 = 0x0097, .ghz2 = 0x0097, UPLOAD, },
215 [B2055_C2_TX_PGAPADTN] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
216 [B2055_C2_TX_PADIDAC1] = { .ghz5 = 0x0014, .ghz2 = 0x0014, UPLOAD, },
217 [B2055_C2_TX_PADIDAC2] = { .ghz5 = 0x0033, .ghz2 = 0x0033, NOUPLOAD, },
218 [B2055_C2_TX_MXBGTRIM] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
219 [B2055_C2_TX_RF_RCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
220 [B2055_C2_TX_RF_PADTSSI1] = { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, },
221 [B2055_C2_TX_RF_PADTSSI2] = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
222 [B2055_C2_TX_RF_SPARE] = { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, },
223 [B2055_C2_TX_RF_IQCAL1] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
224 [B2055_C2_TX_RF_IQCAL2] = { .ghz5 = 0x00A4, .ghz2 = 0x00A4, NOUPLOAD, },
225 [B2055_C2_TXBB_RCCAL] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
226 [B2055_C2_TXBB_LPF1] = { .ghz5 = 0x0028, .ghz2 = 0x0028, NOUPLOAD, },
227 [B2055_C2_TX_VOSCNCL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
228 [B2055_C2_TX_LPF_MXGMIDAC] = { .ghz5 = 0x004A, .ghz2 = 0x004A, NOUPLOAD, },
229 [B2055_C2_TX_BB_MXGM] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
230 [B2055_PRG_GCHP21] = { .ghz5 = 0x0071, .ghz2 = 0x0071, NOUPLOAD, },
231 [B2055_PRG_GCHP22] = { .ghz5 = 0x0072, .ghz2 = 0x0072, NOUPLOAD, },
232 [B2055_PRG_GCHP23] = { .ghz5 = 0x0073, .ghz2 = 0x0073, NOUPLOAD, },
233 [B2055_PRG_GCHP24] = { .ghz5 = 0x0074, .ghz2 = 0x0074, NOUPLOAD, },
234 [B2055_PRG_GCHP25] = { .ghz5 = 0x0075, .ghz2 = 0x0075, NOUPLOAD, },
235 [B2055_PRG_GCHP26] = { .ghz5 = 0x0076, .ghz2 = 0x0076, NOUPLOAD, },
236 [B2055_PRG_GCHP27] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, },
237 [B2055_PRG_GCHP28] = { .ghz5 = 0x0078, .ghz2 = 0x0078, NOUPLOAD, },
238 [B2055_PRG_GCHP29] = { .ghz5 = 0x0079, .ghz2 = 0x0079, NOUPLOAD, },
239 [B2055_PRG_GCHP30] = { .ghz5 = 0x007A, .ghz2 = 0x007A, NOUPLOAD, },
240 [0xC7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
241 [0xC8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
242 [0xC9] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
243 [0xCA] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
244 [0xCB] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
245 [0xCC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
246 [B2055_C1_LNA_GAINBST] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
247 [0xCE] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
248 [0xCF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
249 [0xD0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
250 [0xD1] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
251 [B2055_C1_B0NB_RSSIVCM] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
252 [0xD3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
253 [0xD4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
254 [0xD5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
255 [B2055_C1_GENSPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
256 [0xD7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
257 [0xD8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
258 [B2055_C2_LNA_GAINBST] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
259 [0xDA] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
260 [0xDB] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
261 [0xDC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
262 [0xDD] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
263 [B2055_C2_B0NB_RSSIVCM] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
264 [0xDF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
265 [0xE0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
266 [0xE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
267 [B2055_C2_GENSPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
268};
269
270#define RADIOREGS(r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, \
271 r12, r13, r14, r15, r16, r17, r18, r19, r20, r21) \
272 .radio_pll_ref = r0, \
273 .radio_rf_pllmod0 = r1, \
274 .radio_rf_pllmod1 = r2, \
275 .radio_vco_captail = r3, \
276 .radio_vco_cal1 = r4, \
277 .radio_vco_cal2 = r5, \
278 .radio_pll_lfc1 = r6, \
279 .radio_pll_lfr1 = r7, \
280 .radio_pll_lfc2 = r8, \
281 .radio_lgbuf_cenbuf = r9, \
282 .radio_lgen_tune1 = r10, \
283 .radio_lgen_tune2 = r11, \
284 .radio_c1_lgbuf_atune = r12, \
285 .radio_c1_lgbuf_gtune = r13, \
286 .radio_c1_rx_rfr1 = r14, \
287 .radio_c1_tx_pgapadtn = r15, \
288 .radio_c1_tx_mxbgtrim = r16, \
289 .radio_c2_lgbuf_atune = r17, \
290 .radio_c2_lgbuf_gtune = r18, \
291 .radio_c2_rx_rfr1 = r19, \
292 .radio_c2_tx_pgapadtn = r20, \
293 .radio_c2_tx_mxbgtrim = r21
294
295#define PHYREGS(r0, r1, r2, r3, r4, r5) \
296 .phy_regs.phy_bw1a = r0, \
297 .phy_regs.phy_bw2 = r1, \
298 .phy_regs.phy_bw3 = r2, \
299 .phy_regs.phy_bw4 = r3, \
300 .phy_regs.phy_bw5 = r4, \
301 .phy_regs.phy_bw6 = r5
302
303static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = {
304 { .channel = 184,
305 .freq = 4920, /* MHz */
306 .unk2 = 3280,
307 RADIOREGS(0x71, 0x01, 0xEC, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
308 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F,
309 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
310 PHYREGS(0xB407, 0xB007, 0xAC07, 0x1402, 0x1502, 0x1602),
311 },
312 { .channel = 186,
313 .freq = 4930, /* MHz */
314 .unk2 = 3287,
315 RADIOREGS(0x71, 0x01, 0xED, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
316 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F,
317 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
318 PHYREGS(0xB807, 0xB407, 0xB007, 0x1302, 0x1402, 0x1502),
319 },
320 { .channel = 188,
321 .freq = 4940, /* MHz */
322 .unk2 = 3293,
323 RADIOREGS(0x71, 0x01, 0xEE, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
324 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
325 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
326 PHYREGS(0xBC07, 0xB807, 0xB407, 0x1202, 0x1302, 0x1402),
327 },
328 { .channel = 190,
329 .freq = 4950, /* MHz */
330 .unk2 = 3300,
331 RADIOREGS(0x71, 0x01, 0xEF, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
332 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
333 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
334 PHYREGS(0xC007, 0xBC07, 0xB807, 0x1102, 0x1202, 0x1302),
335 },
336 { .channel = 192,
337 .freq = 4960, /* MHz */
338 .unk2 = 3307,
339 RADIOREGS(0x71, 0x01, 0xF0, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
340 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
341 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
342 PHYREGS(0xC407, 0xC007, 0xBC07, 0x0F02, 0x1102, 0x1202),
343 },
344 { .channel = 194,
345 .freq = 4970, /* MHz */
346 .unk2 = 3313,
347 RADIOREGS(0x71, 0x01, 0xF1, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
348 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
349 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
350 PHYREGS(0xC807, 0xC407, 0xC007, 0x0E02, 0x0F02, 0x1102),
351 },
352 { .channel = 196,
353 .freq = 4980, /* MHz */
354 .unk2 = 3320,
355 RADIOREGS(0x71, 0x01, 0xF2, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
356 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
357 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
358 PHYREGS(0xCC07, 0xC807, 0xC407, 0x0D02, 0x0E02, 0x0F02),
359 },
360 { .channel = 198,
361 .freq = 4990, /* MHz */
362 .unk2 = 3327,
363 RADIOREGS(0x71, 0x01, 0xF3, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
364 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
365 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
366 PHYREGS(0xD007, 0xCC07, 0xC807, 0x0C02, 0x0D02, 0x0E02),
367 },
368 { .channel = 200,
369 .freq = 5000, /* MHz */
370 .unk2 = 3333,
371 RADIOREGS(0x71, 0x01, 0xF4, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
372 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
373 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
374 PHYREGS(0xD407, 0xD007, 0xCC07, 0x0B02, 0x0C02, 0x0D02),
375 },
376 { .channel = 202,
377 .freq = 5010, /* MHz */
378 .unk2 = 3340,
379 RADIOREGS(0x71, 0x01, 0xF5, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
380 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
381 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
382 PHYREGS(0xD807, 0xD407, 0xD007, 0x0A02, 0x0B02, 0x0C02),
383 },
384 { .channel = 204,
385 .freq = 5020, /* MHz */
386 .unk2 = 3347,
387 RADIOREGS(0x71, 0x01, 0xF6, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
388 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
389 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
390 PHYREGS(0xDC07, 0xD807, 0xD407, 0x0902, 0x0A02, 0x0B02),
391 },
392 { .channel = 206,
393 .freq = 5030, /* MHz */
394 .unk2 = 3353,
395 RADIOREGS(0x71, 0x01, 0xF7, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
396 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
397 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
398 PHYREGS(0xE007, 0xDC07, 0xD807, 0x0802, 0x0902, 0x0A02),
399 },
400 { .channel = 208,
401 .freq = 5040, /* MHz */
402 .unk2 = 3360,
403 RADIOREGS(0x71, 0x01, 0xF8, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
404 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
405 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
406 PHYREGS(0xE407, 0xE007, 0xDC07, 0x0702, 0x0802, 0x0902),
407 },
408 { .channel = 210,
409 .freq = 5050, /* MHz */
410 .unk2 = 3367,
411 RADIOREGS(0x71, 0x01, 0xF9, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
412 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
413 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
414 PHYREGS(0xE807, 0xE407, 0xE007, 0x0602, 0x0702, 0x0802),
415 },
416 { .channel = 212,
417 .freq = 5060, /* MHz */
418 .unk2 = 3373,
419 RADIOREGS(0x71, 0x01, 0xFA, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
420 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F,
421 0x8E, 0xFF, 0x00, 0x0E, 0x0F, 0x8E),
422 PHYREGS(0xEC07, 0xE807, 0xE407, 0x0502, 0x0602, 0x0702),
423 },
424 { .channel = 214,
425 .freq = 5070, /* MHz */
426 .unk2 = 3380,
427 RADIOREGS(0x71, 0x01, 0xFB, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
428 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F,
429 0x8E, 0xFF, 0x00, 0x0E, 0x0F, 0x8E),
430 PHYREGS(0xF007, 0xEC07, 0xE807, 0x0402, 0x0502, 0x0602),
431 },
432 { .channel = 216,
433 .freq = 5080, /* MHz */
434 .unk2 = 3387,
435 RADIOREGS(0x71, 0x01, 0xFC, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
436 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F,
437 0x8D, 0xEE, 0x00, 0x0E, 0x0F, 0x8D),
438 PHYREGS(0xF407, 0xF007, 0xEC07, 0x0302, 0x0402, 0x0502),
439 },
440 { .channel = 218,
441 .freq = 5090, /* MHz */
442 .unk2 = 3393,
443 RADIOREGS(0x71, 0x01, 0xFD, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
444 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F,
445 0x8D, 0xEE, 0x00, 0x0E, 0x0F, 0x8D),
446 PHYREGS(0xF807, 0xF407, 0xF007, 0x0202, 0x0302, 0x0402),
447 },
448 { .channel = 220,
449 .freq = 5100, /* MHz */
450 .unk2 = 3400,
451 RADIOREGS(0x71, 0x01, 0xFE, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
452 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F,
453 0x8D, 0xEE, 0x00, 0x0D, 0x0F, 0x8D),
454 PHYREGS(0xFC07, 0xF807, 0xF407, 0x0102, 0x0202, 0x0302),
455 },
456 { .channel = 222,
457 .freq = 5110, /* MHz */
458 .unk2 = 3407,
459 RADIOREGS(0x71, 0x01, 0xFF, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
460 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F,
461 0x8D, 0xEE, 0x00, 0x0D, 0x0F, 0x8D),
462 PHYREGS(0x0008, 0xFC07, 0xF807, 0x0002, 0x0102, 0x0202),
463 },
464 { .channel = 224,
465 .freq = 5120, /* MHz */
466 .unk2 = 3413,
467 RADIOREGS(0x71, 0x02, 0x00, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
468 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F,
469 0x8C, 0xDD, 0x00, 0x0D, 0x0F, 0x8C),
470 PHYREGS(0x0408, 0x0008, 0xFC07, 0xFF01, 0x0002, 0x0102),
471 },
472 { .channel = 226,
473 .freq = 5130, /* MHz */
474 .unk2 = 3420,
475 RADIOREGS(0x71, 0x02, 0x01, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
476 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F,
477 0x8C, 0xDD, 0x00, 0x0D, 0x0F, 0x8C),
478 PHYREGS(0x0808, 0x0408, 0x0008, 0xFE01, 0xFF01, 0x0002),
479 },
480 { .channel = 228,
481 .freq = 5140, /* MHz */
482 .unk2 = 3427,
483 RADIOREGS(0x71, 0x02, 0x02, 0x0C, 0xC6, 0x01, 0x04, 0x0A,
484 0x00, 0x8D, 0x99, 0x99, 0xDD, 0x00, 0x0C, 0x0E,
485 0x8B, 0xDD, 0x00, 0x0C, 0x0E, 0x8B),
486 PHYREGS(0x0C08, 0x0808, 0x0408, 0xFD01, 0xFE01, 0xFF01),
487 },
488 { .channel = 32,
489 .freq = 5160, /* MHz */
490 .unk2 = 3440,
491 RADIOREGS(0x71, 0x02, 0x04, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
492 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D,
493 0x8A, 0xCC, 0x00, 0x0B, 0x0D, 0x8A),
494 PHYREGS(0x1408, 0x1008, 0x0C08, 0xFB01, 0xFC01, 0xFD01),
495 },
496 { .channel = 34,
497 .freq = 5170, /* MHz */
498 .unk2 = 3447,
499 RADIOREGS(0x71, 0x02, 0x05, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
500 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D,
501 0x8A, 0xCC, 0x00, 0x0B, 0x0D, 0x8A),
502 PHYREGS(0x1808, 0x1408, 0x1008, 0xFA01, 0xFB01, 0xFC01),
503 },
504 { .channel = 36,
505 .freq = 5180, /* MHz */
506 .unk2 = 3453,
507 RADIOREGS(0x71, 0x02, 0x06, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
508 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C,
509 0x89, 0xCC, 0x00, 0x0B, 0x0C, 0x89),
510 PHYREGS(0x1C08, 0x1808, 0x1408, 0xF901, 0xFA01, 0xFB01),
511 },
512 { .channel = 38,
513 .freq = 5190, /* MHz */
514 .unk2 = 3460,
515 RADIOREGS(0x71, 0x02, 0x07, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
516 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C,
517 0x89, 0xCC, 0x00, 0x0B, 0x0C, 0x89),
518 PHYREGS(0x2008, 0x1C08, 0x1808, 0xF801, 0xF901, 0xFA01),
519 },
520 { .channel = 40,
521 .freq = 5200, /* MHz */
522 .unk2 = 3467,
523 RADIOREGS(0x71, 0x02, 0x08, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
524 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B,
525 0x89, 0xBB, 0x00, 0x0A, 0x0B, 0x89),
526 PHYREGS(0x2408, 0x2008, 0x1C08, 0xF701, 0xF801, 0xF901),
527 },
528 { .channel = 42,
529 .freq = 5210, /* MHz */
530 .unk2 = 3473,
531 RADIOREGS(0x71, 0x02, 0x09, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
532 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B,
533 0x89, 0xBB, 0x00, 0x0A, 0x0B, 0x89),
534 PHYREGS(0x2808, 0x2408, 0x2008, 0xF601, 0xF701, 0xF801),
535 },
536 { .channel = 44,
537 .freq = 5220, /* MHz */
538 .unk2 = 3480,
539 RADIOREGS(0x71, 0x02, 0x0A, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
540 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A,
541 0x88, 0xBB, 0x00, 0x09, 0x0A, 0x88),
542 PHYREGS(0x2C08, 0x2808, 0x2408, 0xF501, 0xF601, 0xF701),
543 },
544 { .channel = 46,
545 .freq = 5230, /* MHz */
546 .unk2 = 3487,
547 RADIOREGS(0x71, 0x02, 0x0B, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
548 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A,
549 0x88, 0xBB, 0x00, 0x09, 0x0A, 0x88),
550 PHYREGS(0x3008, 0x2C08, 0x2808, 0xF401, 0xF501, 0xF601),
551 },
552 { .channel = 48,
553 .freq = 5240, /* MHz */
554 .unk2 = 3493,
555 RADIOREGS(0x71, 0x02, 0x0C, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
556 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A,
557 0x87, 0xAA, 0x00, 0x09, 0x0A, 0x87),
558 PHYREGS(0x3408, 0x3008, 0x2C08, 0xF301, 0xF401, 0xF501),
559 },
560 { .channel = 50,
561 .freq = 5250, /* MHz */
562 .unk2 = 3500,
563 RADIOREGS(0x71, 0x02, 0x0D, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
564 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A,
565 0x87, 0xAA, 0x00, 0x09, 0x0A, 0x87),
566 PHYREGS(0x3808, 0x3408, 0x3008, 0xF201, 0xF301, 0xF401),
567 },
568 { .channel = 52,
569 .freq = 5260, /* MHz */
570 .unk2 = 3507,
571 RADIOREGS(0x71, 0x02, 0x0E, 0x0A, 0x98, 0x01, 0x04, 0x0A,
572 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09,
573 0x87, 0xAA, 0x00, 0x08, 0x09, 0x87),
574 PHYREGS(0x3C08, 0x3808, 0x3408, 0xF101, 0xF201, 0xF301),
575 },
576 { .channel = 54,
577 .freq = 5270, /* MHz */
578 .unk2 = 3513,
579 RADIOREGS(0x71, 0x02, 0x0F, 0x0A, 0x98, 0x01, 0x04, 0x0A,
580 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09,
581 0x87, 0xAA, 0x00, 0x08, 0x09, 0x87),
582 PHYREGS(0x4008, 0x3C08, 0x3808, 0xF001, 0xF101, 0xF201),
583 },
584 { .channel = 56,
585 .freq = 5280, /* MHz */
586 .unk2 = 3520,
587 RADIOREGS(0x71, 0x02, 0x10, 0x09, 0x91, 0x01, 0x04, 0x0A,
588 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08,
589 0x86, 0x99, 0x00, 0x08, 0x08, 0x86),
590 PHYREGS(0x4408, 0x4008, 0x3C08, 0xF001, 0xF001, 0xF101),
591 },
592 { .channel = 58,
593 .freq = 5290, /* MHz */
594 .unk2 = 3527,
595 RADIOREGS(0x71, 0x02, 0x11, 0x09, 0x91, 0x01, 0x04, 0x0A,
596 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08,
597 0x86, 0x99, 0x00, 0x08, 0x08, 0x86),
598 PHYREGS(0x4808, 0x4408, 0x4008, 0xEF01, 0xF001, 0xF001),
599 },
600 { .channel = 60,
601 .freq = 5300, /* MHz */
602 .unk2 = 3533,
603 RADIOREGS(0x71, 0x02, 0x12, 0x09, 0x8A, 0x01, 0x04, 0x0A,
604 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07,
605 0x85, 0x99, 0x00, 0x08, 0x07, 0x85),
606 PHYREGS(0x4C08, 0x4808, 0x4408, 0xEE01, 0xEF01, 0xF001),
607 },
608 { .channel = 62,
609 .freq = 5310, /* MHz */
610 .unk2 = 3540,
611 RADIOREGS(0x71, 0x02, 0x13, 0x09, 0x8A, 0x01, 0x04, 0x0A,
612 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07,
613 0x85, 0x99, 0x00, 0x08, 0x07, 0x85),
614 PHYREGS(0x5008, 0x4C08, 0x4808, 0xED01, 0xEE01, 0xEF01),
615 },
616 { .channel = 64,
617 .freq = 5320, /* MHz */
618 .unk2 = 3547,
619 RADIOREGS(0x71, 0x02, 0x14, 0x09, 0x83, 0x01, 0x04, 0x0A,
620 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07,
621 0x84, 0x88, 0x00, 0x07, 0x07, 0x84),
622 PHYREGS(0x5408, 0x5008, 0x4C08, 0xEC01, 0xED01, 0xEE01),
623 },
624 { .channel = 66,
625 .freq = 5330, /* MHz */
626 .unk2 = 3553,
627 RADIOREGS(0x71, 0x02, 0x15, 0x09, 0x83, 0x01, 0x04, 0x0A,
628 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07,
629 0x84, 0x88, 0x00, 0x07, 0x07, 0x84),
630 PHYREGS(0x5808, 0x5408, 0x5008, 0xEB01, 0xEC01, 0xED01),
631 },
632 { .channel = 68,
633 .freq = 5340, /* MHz */
634 .unk2 = 3560,
635 RADIOREGS(0x71, 0x02, 0x16, 0x08, 0x7C, 0x01, 0x04, 0x0A,
636 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06,
637 0x84, 0x88, 0x00, 0x07, 0x06, 0x84),
638 PHYREGS(0x5C08, 0x5808, 0x5408, 0xEA01, 0xEB01, 0xEC01),
639 },
640 { .channel = 70,
641 .freq = 5350, /* MHz */
642 .unk2 = 3567,
643 RADIOREGS(0x71, 0x02, 0x17, 0x08, 0x7C, 0x01, 0x04, 0x0A,
644 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06,
645 0x84, 0x88, 0x00, 0x07, 0x06, 0x84),
646 PHYREGS(0x6008, 0x5C08, 0x5808, 0xE901, 0xEA01, 0xEB01),
647 },
648 { .channel = 72,
649 .freq = 5360, /* MHz */
650 .unk2 = 3573,
651 RADIOREGS(0x71, 0x02, 0x18, 0x08, 0x75, 0x01, 0x04, 0x0A,
652 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05,
653 0x83, 0x77, 0x00, 0x06, 0x05, 0x83),
654 PHYREGS(0x6408, 0x6008, 0x5C08, 0xE801, 0xE901, 0xEA01),
655 },
656 { .channel = 74,
657 .freq = 5370, /* MHz */
658 .unk2 = 3580,
659 RADIOREGS(0x71, 0x02, 0x19, 0x08, 0x75, 0x01, 0x04, 0x0A,
660 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05,
661 0x83, 0x77, 0x00, 0x06, 0x05, 0x83),
662 PHYREGS(0x6808, 0x6408, 0x6008, 0xE701, 0xE801, 0xE901),
663 },
664 { .channel = 76,
665 .freq = 5380, /* MHz */
666 .unk2 = 3587,
667 RADIOREGS(0x71, 0x02, 0x1A, 0x08, 0x6E, 0x01, 0x04, 0x0A,
668 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04,
669 0x82, 0x77, 0x00, 0x06, 0x04, 0x82),
670 PHYREGS(0x6C08, 0x6808, 0x6408, 0xE601, 0xE701, 0xE801),
671 },
672 { .channel = 78,
673 .freq = 5390, /* MHz */
674 .unk2 = 3593,
675 RADIOREGS(0x71, 0x02, 0x1B, 0x08, 0x6E, 0x01, 0x04, 0x0A,
676 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04,
677 0x82, 0x77, 0x00, 0x06, 0x04, 0x82),
678 PHYREGS(0x7008, 0x6C08, 0x6808, 0xE501, 0xE601, 0xE701),
679 },
680 { .channel = 80,
681 .freq = 5400, /* MHz */
682 .unk2 = 3600,
683 RADIOREGS(0x71, 0x02, 0x1C, 0x07, 0x67, 0x01, 0x04, 0x0A,
684 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04,
685 0x81, 0x66, 0x00, 0x05, 0x04, 0x81),
686 PHYREGS(0x7408, 0x7008, 0x6C08, 0xE501, 0xE501, 0xE601),
687 },
688 { .channel = 82,
689 .freq = 5410, /* MHz */
690 .unk2 = 3607,
691 RADIOREGS(0x71, 0x02, 0x1D, 0x07, 0x67, 0x01, 0x04, 0x0A,
692 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04,
693 0x81, 0x66, 0x00, 0x05, 0x04, 0x81),
694 PHYREGS(0x7808, 0x7408, 0x7008, 0xE401, 0xE501, 0xE501),
695 },
696 { .channel = 84,
697 .freq = 5420, /* MHz */
698 .unk2 = 3613,
699 RADIOREGS(0x71, 0x02, 0x1E, 0x07, 0x61, 0x01, 0x04, 0x0A,
700 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03,
701 0x80, 0x66, 0x00, 0x05, 0x03, 0x80),
702 PHYREGS(0x7C08, 0x7808, 0x7408, 0xE301, 0xE401, 0xE501),
703 },
704 { .channel = 86,
705 .freq = 5430, /* MHz */
706 .unk2 = 3620,
707 RADIOREGS(0x71, 0x02, 0x1F, 0x07, 0x61, 0x01, 0x04, 0x0A,
708 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03,
709 0x80, 0x66, 0x00, 0x05, 0x03, 0x80),
710 PHYREGS(0x8008, 0x7C08, 0x7808, 0xE201, 0xE301, 0xE401),
711 },
712 { .channel = 88,
713 .freq = 5440, /* MHz */
714 .unk2 = 3627,
715 RADIOREGS(0x71, 0x02, 0x20, 0x07, 0x5A, 0x01, 0x04, 0x0A,
716 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02,
717 0x80, 0x55, 0x00, 0x04, 0x02, 0x80),
718 PHYREGS(0x8408, 0x8008, 0x7C08, 0xE101, 0xE201, 0xE301),
719 },
720 { .channel = 90,
721 .freq = 5450, /* MHz */
722 .unk2 = 3633,
723 RADIOREGS(0x71, 0x02, 0x21, 0x07, 0x5A, 0x01, 0x04, 0x0A,
724 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02,
725 0x80, 0x55, 0x00, 0x04, 0x02, 0x80),
726 PHYREGS(0x8808, 0x8408, 0x8008, 0xE001, 0xE101, 0xE201),
727 },
728 { .channel = 92,
729 .freq = 5460, /* MHz */
730 .unk2 = 3640,
731 RADIOREGS(0x71, 0x02, 0x22, 0x06, 0x53, 0x01, 0x04, 0x0A,
732 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01,
733 0x80, 0x55, 0x00, 0x04, 0x01, 0x80),
734 PHYREGS(0x8C08, 0x8808, 0x8408, 0xDF01, 0xE001, 0xE101),
735 },
736 { .channel = 94,
737 .freq = 5470, /* MHz */
738 .unk2 = 3647,
739 RADIOREGS(0x71, 0x02, 0x23, 0x06, 0x53, 0x01, 0x04, 0x0A,
740 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01,
741 0x80, 0x55, 0x00, 0x04, 0x01, 0x80),
742 PHYREGS(0x9008, 0x8C08, 0x8808, 0xDE01, 0xDF01, 0xE001),
743 },
744 { .channel = 96,
745 .freq = 5480, /* MHz */
746 .unk2 = 3653,
747 RADIOREGS(0x71, 0x02, 0x24, 0x06, 0x4D, 0x01, 0x04, 0x0A,
748 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00,
749 0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
750 PHYREGS(0x9408, 0x9008, 0x8C08, 0xDD01, 0xDE01, 0xDF01),
751 },
752 { .channel = 98,
753 .freq = 5490, /* MHz */
754 .unk2 = 3660,
755 RADIOREGS(0x71, 0x02, 0x25, 0x06, 0x4D, 0x01, 0x04, 0x0A,
756 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00,
757 0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
758 PHYREGS(0x9808, 0x9408, 0x9008, 0xDD01, 0xDD01, 0xDE01),
759 },
760 { .channel = 100,
761 .freq = 5500, /* MHz */
762 .unk2 = 3667,
763 RADIOREGS(0x71, 0x02, 0x26, 0x06, 0x47, 0x01, 0x04, 0x0A,
764 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00,
765 0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
766 PHYREGS(0x9C08, 0x9808, 0x9408, 0xDC01, 0xDD01, 0xDD01),
767 },
768 { .channel = 102,
769 .freq = 5510, /* MHz */
770 .unk2 = 3673,
771 RADIOREGS(0x71, 0x02, 0x27, 0x06, 0x47, 0x01, 0x04, 0x0A,
772 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00,
773 0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
774 PHYREGS(0xA008, 0x9C08, 0x9808, 0xDB01, 0xDC01, 0xDD01),
775 },
776 { .channel = 104,
777 .freq = 5520, /* MHz */
778 .unk2 = 3680,
779 RADIOREGS(0x71, 0x02, 0x28, 0x05, 0x40, 0x01, 0x04, 0x0A,
780 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
781 0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
782 PHYREGS(0xA408, 0xA008, 0x9C08, 0xDA01, 0xDB01, 0xDC01),
783 },
784 { .channel = 106,
785 .freq = 5530, /* MHz */
786 .unk2 = 3687,
787 RADIOREGS(0x71, 0x02, 0x29, 0x05, 0x40, 0x01, 0x04, 0x0A,
788 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
789 0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
790 PHYREGS(0xA808, 0xA408, 0xA008, 0xD901, 0xDA01, 0xDB01),
791 },
792 { .channel = 108,
793 .freq = 5540, /* MHz */
794 .unk2 = 3693,
795 RADIOREGS(0x71, 0x02, 0x2A, 0x05, 0x3A, 0x01, 0x04, 0x0A,
796 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
797 0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
798 PHYREGS(0xAC08, 0xA808, 0xA408, 0xD801, 0xD901, 0xDA01),
799 },
800 { .channel = 110,
801 .freq = 5550, /* MHz */
802 .unk2 = 3700,
803 RADIOREGS(0x71, 0x02, 0x2B, 0x05, 0x3A, 0x01, 0x04, 0x0A,
804 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
805 0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
806 PHYREGS(0xB008, 0xAC08, 0xA808, 0xD701, 0xD801, 0xD901),
807 },
808 { .channel = 112,
809 .freq = 5560, /* MHz */
810 .unk2 = 3707,
811 RADIOREGS(0x71, 0x02, 0x2C, 0x05, 0x34, 0x01, 0x04, 0x0A,
812 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
813 0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
814 PHYREGS(0xB408, 0xB008, 0xAC08, 0xD701, 0xD701, 0xD801),
815 },
816 { .channel = 114,
817 .freq = 5570, /* MHz */
818 .unk2 = 3713,
819 RADIOREGS(0x71, 0x02, 0x2D, 0x05, 0x34, 0x01, 0x04, 0x0A,
820 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
821 0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
822 PHYREGS(0xB808, 0xB408, 0xB008, 0xD601, 0xD701, 0xD701),
823 },
824 { .channel = 116,
825 .freq = 5580, /* MHz */
826 .unk2 = 3720,
827 RADIOREGS(0x71, 0x02, 0x2E, 0x04, 0x2E, 0x01, 0x04, 0x0A,
828 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
829 0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
830 PHYREGS(0xBC08, 0xB808, 0xB408, 0xD501, 0xD601, 0xD701),
831 },
832 { .channel = 118,
833 .freq = 5590, /* MHz */
834 .unk2 = 3727,
835 RADIOREGS(0x71, 0x02, 0x2F, 0x04, 0x2E, 0x01, 0x04, 0x0A,
836 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
837 0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
838 PHYREGS(0xC008, 0xBC08, 0xB808, 0xD401, 0xD501, 0xD601),
839 },
840 { .channel = 120,
841 .freq = 5600, /* MHz */
842 .unk2 = 3733,
843 RADIOREGS(0x71, 0x02, 0x30, 0x04, 0x28, 0x01, 0x04, 0x0A,
844 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00,
845 0x80, 0x11, 0x00, 0x01, 0x00, 0x80),
846 PHYREGS(0xC408, 0xC008, 0xBC08, 0xD301, 0xD401, 0xD501),
847 },
848 { .channel = 122,
849 .freq = 5610, /* MHz */
850 .unk2 = 3740,
851 RADIOREGS(0x71, 0x02, 0x31, 0x04, 0x28, 0x01, 0x04, 0x0A,
852 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00,
853 0x80, 0x11, 0x00, 0x01, 0x00, 0x80),
854 PHYREGS(0xC808, 0xC408, 0xC008, 0xD201, 0xD301, 0xD401),
855 },
856 { .channel = 124,
857 .freq = 5620, /* MHz */
858 .unk2 = 3747,
859 RADIOREGS(0x71, 0x02, 0x32, 0x04, 0x21, 0x01, 0x04, 0x0A,
860 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
861 0x80, 0x11, 0x00, 0x00, 0x00, 0x80),
862 PHYREGS(0xCC08, 0xC808, 0xC408, 0xD201, 0xD201, 0xD301),
863 },
864 { .channel = 126,
865 .freq = 5630, /* MHz */
866 .unk2 = 3753,
867 RADIOREGS(0x71, 0x02, 0x33, 0x04, 0x21, 0x01, 0x04, 0x0A,
868 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
869 0x80, 0x11, 0x00, 0x00, 0x00, 0x80),
870 PHYREGS(0xD008, 0xCC08, 0xC808, 0xD101, 0xD201, 0xD201),
871 },
872 { .channel = 128,
873 .freq = 5640, /* MHz */
874 .unk2 = 3760,
875 RADIOREGS(0x71, 0x02, 0x34, 0x03, 0x1C, 0x01, 0x04, 0x0A,
876 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
877 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
878 PHYREGS(0xD408, 0xD008, 0xCC08, 0xD001, 0xD101, 0xD201),
879 },
880 { .channel = 130,
881 .freq = 5650, /* MHz */
882 .unk2 = 3767,
883 RADIOREGS(0x71, 0x02, 0x35, 0x03, 0x1C, 0x01, 0x04, 0x0A,
884 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
885 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
886 PHYREGS(0xD808, 0xD408, 0xD008, 0xCF01, 0xD001, 0xD101),
887 },
888 { .channel = 132,
889 .freq = 5660, /* MHz */
890 .unk2 = 3773,
891 RADIOREGS(0x71, 0x02, 0x36, 0x03, 0x16, 0x01, 0x04, 0x0A,
892 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
893 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
894 PHYREGS(0xDC08, 0xD808, 0xD408, 0xCE01, 0xCF01, 0xD001),
895 },
896 { .channel = 134,
897 .freq = 5670, /* MHz */
898 .unk2 = 3780,
899 RADIOREGS(0x71, 0x02, 0x37, 0x03, 0x16, 0x01, 0x04, 0x0A,
900 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
901 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
902 PHYREGS(0xE008, 0xDC08, 0xD808, 0xCE01, 0xCE01, 0xCF01),
903 },
904 { .channel = 136,
905 .freq = 5680, /* MHz */
906 .unk2 = 3787,
907 RADIOREGS(0x71, 0x02, 0x38, 0x03, 0x10, 0x01, 0x04, 0x0A,
908 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
909 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
910 PHYREGS(0xE408, 0xE008, 0xDC08, 0xCD01, 0xCE01, 0xCE01),
911 },
912 { .channel = 138,
913 .freq = 5690, /* MHz */
914 .unk2 = 3793,
915 RADIOREGS(0x71, 0x02, 0x39, 0x03, 0x10, 0x01, 0x04, 0x0A,
916 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
917 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
918 PHYREGS(0xE808, 0xE408, 0xE008, 0xCC01, 0xCD01, 0xCE01),
919 },
920 { .channel = 140,
921 .freq = 5700, /* MHz */
922 .unk2 = 3800,
923 RADIOREGS(0x71, 0x02, 0x3A, 0x02, 0x0A, 0x01, 0x04, 0x0A,
924 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
925 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
926 PHYREGS(0xEC08, 0xE808, 0xE408, 0xCB01, 0xCC01, 0xCD01),
927 },
928 { .channel = 142,
929 .freq = 5710, /* MHz */
930 .unk2 = 3807,
931 RADIOREGS(0x71, 0x02, 0x3B, 0x02, 0x0A, 0x01, 0x04, 0x0A,
932 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
933 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
934 PHYREGS(0xF008, 0xEC08, 0xE808, 0xCA01, 0xCB01, 0xCC01),
935 },
936 { .channel = 144,
937 .freq = 5720, /* MHz */
938 .unk2 = 3813,
939 RADIOREGS(0x71, 0x02, 0x3C, 0x02, 0x0A, 0x01, 0x04, 0x0A,
940 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
941 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
942 PHYREGS(0xF408, 0xF008, 0xEC08, 0xC901, 0xCA01, 0xCB01),
943 },
944 { .channel = 145,
945 .freq = 5725, /* MHz */
946 .unk2 = 3817,
947 RADIOREGS(0x72, 0x04, 0x79, 0x02, 0x03, 0x01, 0x03, 0x14,
948 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
949 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
950 PHYREGS(0xF608, 0xF208, 0xEE08, 0xC901, 0xCA01, 0xCB01),
951 },
952 { .channel = 146,
953 .freq = 5730, /* MHz */
954 .unk2 = 3820,
955 RADIOREGS(0x71, 0x02, 0x3D, 0x02, 0x0A, 0x01, 0x04, 0x0A,
956 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
957 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
958 PHYREGS(0xF808, 0xF408, 0xF008, 0xC901, 0xC901, 0xCA01),
959 },
960 { .channel = 147,
961 .freq = 5735, /* MHz */
962 .unk2 = 3823,
963 RADIOREGS(0x72, 0x04, 0x7B, 0x02, 0x03, 0x01, 0x03, 0x14,
964 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
965 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
966 PHYREGS(0xFA08, 0xF608, 0xF208, 0xC801, 0xC901, 0xCA01),
967 },
968 { .channel = 148,
969 .freq = 5740, /* MHz */
970 .unk2 = 3827,
971 RADIOREGS(0x71, 0x02, 0x3E, 0x02, 0x0A, 0x01, 0x04, 0x0A,
972 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
973 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
974 PHYREGS(0xFC08, 0xF808, 0xF408, 0xC801, 0xC901, 0xC901),
975 },
976 { .channel = 149,
977 .freq = 5745, /* MHz */
978 .unk2 = 3830,
979 RADIOREGS(0x72, 0x04, 0x7D, 0x02, 0xFE, 0x00, 0x03, 0x14,
980 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
981 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
982 PHYREGS(0xFE08, 0xFA08, 0xF608, 0xC801, 0xC801, 0xC901),
983 },
984 { .channel = 150,
985 .freq = 5750, /* MHz */
986 .unk2 = 3833,
987 RADIOREGS(0x71, 0x02, 0x3F, 0x02, 0x0A, 0x01, 0x04, 0x0A,
988 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
989 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
990 PHYREGS(0x0009, 0xFC08, 0xF808, 0xC701, 0xC801, 0xC901),
991 },
992 { .channel = 151,
993 .freq = 5755, /* MHz */
994 .unk2 = 3837,
995 RADIOREGS(0x72, 0x04, 0x7F, 0x02, 0xFE, 0x00, 0x03, 0x14,
996 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
997 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
998 PHYREGS(0x0209, 0xFE08, 0xFA08, 0xC701, 0xC801, 0xC801),
999 },
1000 { .channel = 152,
1001 .freq = 5760, /* MHz */
1002 .unk2 = 3840,
1003 RADIOREGS(0x71, 0x02, 0x40, 0x02, 0x0A, 0x01, 0x04, 0x0A,
1004 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1005 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1006 PHYREGS(0x0409, 0x0009, 0xFC08, 0xC601, 0xC701, 0xC801),
1007 },
1008 { .channel = 153,
1009 .freq = 5765, /* MHz */
1010 .unk2 = 3843,
1011 RADIOREGS(0x72, 0x04, 0x81, 0x02, 0xF8, 0x00, 0x03, 0x14,
1012 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1013 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1014 PHYREGS(0x0609, 0x0209, 0xFE08, 0xC601, 0xC701, 0xC801),
1015 },
1016 { .channel = 154,
1017 .freq = 5770, /* MHz */
1018 .unk2 = 3847,
1019 RADIOREGS(0x71, 0x02, 0x41, 0x02, 0x0A, 0x01, 0x04, 0x0A,
1020 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1021 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1022 PHYREGS(0x0809, 0x0409, 0x0009, 0xC601, 0xC601, 0xC701),
1023 },
1024 { .channel = 155,
1025 .freq = 5775, /* MHz */
1026 .unk2 = 3850,
1027 RADIOREGS(0x72, 0x04, 0x83, 0x02, 0xF8, 0x00, 0x03, 0x14,
1028 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1029 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1030 PHYREGS(0x0A09, 0x0609, 0x0209, 0xC501, 0xC601, 0xC701),
1031 },
1032 { .channel = 156,
1033 .freq = 5780, /* MHz */
1034 .unk2 = 3853,
1035 RADIOREGS(0x71, 0x02, 0x42, 0x02, 0x0A, 0x01, 0x04, 0x0A,
1036 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1037 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1038 PHYREGS(0x0C09, 0x0809, 0x0409, 0xC501, 0xC601, 0xC601),
1039 },
1040 { .channel = 157,
1041 .freq = 5785, /* MHz */
1042 .unk2 = 3857,
1043 RADIOREGS(0x72, 0x04, 0x85, 0x02, 0xF2, 0x00, 0x03, 0x14,
1044 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1045 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1046 PHYREGS(0x0E09, 0x0A09, 0x0609, 0xC401, 0xC501, 0xC601),
1047 },
1048 { .channel = 158,
1049 .freq = 5790, /* MHz */
1050 .unk2 = 3860,
1051 RADIOREGS(0x71, 0x02, 0x43, 0x02, 0x0A, 0x01, 0x04, 0x0A,
1052 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1053 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1054 PHYREGS(0x1009, 0x0C09, 0x0809, 0xC401, 0xC501, 0xC601),
1055 },
1056 { .channel = 159,
1057 .freq = 5795, /* MHz */
1058 .unk2 = 3863,
1059 RADIOREGS(0x72, 0x04, 0x87, 0x02, 0xF2, 0x00, 0x03, 0x14,
1060 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1061 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1062 PHYREGS(0x1209, 0x0E09, 0x0A09, 0xC401, 0xC401, 0xC501),
1063 },
1064 { .channel = 160,
1065 .freq = 5800, /* MHz */
1066 .unk2 = 3867,
1067 RADIOREGS(0x71, 0x02, 0x44, 0x01, 0x0A, 0x01, 0x04, 0x0A,
1068 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1069 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1070 PHYREGS(0x1409, 0x1009, 0x0C09, 0xC301, 0xC401, 0xC501),
1071 },
1072 { .channel = 161,
1073 .freq = 5805, /* MHz */
1074 .unk2 = 3870,
1075 RADIOREGS(0x72, 0x04, 0x89, 0x01, 0xED, 0x00, 0x03, 0x14,
1076 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1077 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1078 PHYREGS(0x1609, 0x1209, 0x0E09, 0xC301, 0xC401, 0xC401),
1079 },
1080 { .channel = 162,
1081 .freq = 5810, /* MHz */
1082 .unk2 = 3873,
1083 RADIOREGS(0x71, 0x02, 0x45, 0x01, 0x0A, 0x01, 0x04, 0x0A,
1084 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1085 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1086 PHYREGS(0x1809, 0x1409, 0x1009, 0xC201, 0xC301, 0xC401),
1087 },
1088 { .channel = 163,
1089 .freq = 5815, /* MHz */
1090 .unk2 = 3877,
1091 RADIOREGS(0x72, 0x04, 0x8B, 0x01, 0xED, 0x00, 0x03, 0x14,
1092 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1093 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1094 PHYREGS(0x1A09, 0x1609, 0x1209, 0xC201, 0xC301, 0xC401),
1095 },
1096 { .channel = 164,
1097 .freq = 5820, /* MHz */
1098 .unk2 = 3880,
1099 RADIOREGS(0x71, 0x02, 0x46, 0x01, 0x0A, 0x01, 0x04, 0x0A,
1100 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1101 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1102 PHYREGS(0x1C09, 0x1809, 0x1409, 0xC201, 0xC201, 0xC301),
1103 },
1104 { .channel = 165,
1105 .freq = 5825, /* MHz */
1106 .unk2 = 3883,
1107 RADIOREGS(0x72, 0x04, 0x8D, 0x01, 0xED, 0x00, 0x03, 0x14,
1108 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1109 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1110 PHYREGS(0x1E09, 0x1A09, 0x1609, 0xC101, 0xC201, 0xC301),
1111 },
1112 { .channel = 166,
1113 .freq = 5830, /* MHz */
1114 .unk2 = 3887,
1115 RADIOREGS(0x71, 0x02, 0x47, 0x01, 0x0A, 0x01, 0x04, 0x0A,
1116 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1117 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1118 PHYREGS(0x2009, 0x1C09, 0x1809, 0xC101, 0xC201, 0xC201),
1119 },
1120 { .channel = 168,
1121 .freq = 5840, /* MHz */
1122 .unk2 = 3893,
1123 RADIOREGS(0x71, 0x02, 0x48, 0x01, 0x0A, 0x01, 0x04, 0x0A,
1124 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1125 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1126 PHYREGS(0x2409, 0x2009, 0x1C09, 0xC001, 0xC101, 0xC201),
1127 },
1128 { .channel = 170,
1129 .freq = 5850, /* MHz */
1130 .unk2 = 3900,
1131 RADIOREGS(0x71, 0x02, 0x49, 0x01, 0xE0, 0x00, 0x04, 0x0A,
1132 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1133 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1134 PHYREGS(0x2809, 0x2409, 0x2009, 0xBF01, 0xC001, 0xC101),
1135 },
1136 { .channel = 172,
1137 .freq = 5860, /* MHz */
1138 .unk2 = 3907,
1139 RADIOREGS(0x71, 0x02, 0x4A, 0x01, 0xDE, 0x00, 0x04, 0x0A,
1140 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1141 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1142 PHYREGS(0x2C09, 0x2809, 0x2409, 0xBF01, 0xBF01, 0xC001),
1143 },
1144 { .channel = 174,
1145 .freq = 5870, /* MHz */
1146 .unk2 = 3913,
1147 RADIOREGS(0x71, 0x02, 0x4B, 0x00, 0xDB, 0x00, 0x04, 0x0A,
1148 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1149 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1150 PHYREGS(0x3009, 0x2C09, 0x2809, 0xBE01, 0xBF01, 0xBF01),
1151 },
1152 { .channel = 176,
1153 .freq = 5880, /* MHz */
1154 .unk2 = 3920,
1155 RADIOREGS(0x71, 0x02, 0x4C, 0x00, 0xD8, 0x00, 0x04, 0x0A,
1156 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1157 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1158 PHYREGS(0x3409, 0x3009, 0x2C09, 0xBD01, 0xBE01, 0xBF01),
1159 },
1160 { .channel = 178,
1161 .freq = 5890, /* MHz */
1162 .unk2 = 3927,
1163 RADIOREGS(0x71, 0x02, 0x4D, 0x00, 0xD6, 0x00, 0x04, 0x0A,
1164 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1165 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1166 PHYREGS(0x3809, 0x3409, 0x3009, 0xBC01, 0xBD01, 0xBE01),
1167 },
1168 { .channel = 180,
1169 .freq = 5900, /* MHz */
1170 .unk2 = 3933,
1171 RADIOREGS(0x71, 0x02, 0x4E, 0x00, 0xD3, 0x00, 0x04, 0x0A,
1172 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1173 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1174 PHYREGS(0x3C09, 0x3809, 0x3409, 0xBC01, 0xBC01, 0xBD01),
1175 },
1176 { .channel = 182,
1177 .freq = 5910, /* MHz */
1178 .unk2 = 3940,
1179 RADIOREGS(0x71, 0x02, 0x4F, 0x00, 0xD6, 0x00, 0x04, 0x0A,
1180 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1181 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1182 PHYREGS(0x4009, 0x3C09, 0x3809, 0xBB01, 0xBC01, 0xBC01),
1183 },
1184 { .channel = 1,
1185 .freq = 2412, /* MHz */
1186 .unk2 = 3216,
1187 RADIOREGS(0x73, 0x09, 0x6C, 0x0F, 0x00, 0x01, 0x07, 0x15,
1188 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0D, 0x0C,
1189 0x80, 0xFF, 0x88, 0x0D, 0x0C, 0x80),
1190 PHYREGS(0xC903, 0xC503, 0xC103, 0x3A04, 0x3F04, 0x4304),
1191 },
1192 { .channel = 2,
1193 .freq = 2417, /* MHz */
1194 .unk2 = 3223,
1195 RADIOREGS(0x73, 0x09, 0x71, 0x0F, 0x00, 0x01, 0x07, 0x15,
1196 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0B,
1197 0x80, 0xFF, 0x88, 0x0C, 0x0B, 0x80),
1198 PHYREGS(0xCB03, 0xC703, 0xC303, 0x3804, 0x3D04, 0x4104),
1199 },
1200 { .channel = 3,
1201 .freq = 2422, /* MHz */
1202 .unk2 = 3229,
1203 RADIOREGS(0x73, 0x09, 0x76, 0x0F, 0x00, 0x01, 0x07, 0x15,
1204 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A,
1205 0x80, 0xFF, 0x88, 0x0C, 0x0A, 0x80),
1206 PHYREGS(0xCD03, 0xC903, 0xC503, 0x3604, 0x3A04, 0x3F04),
1207 },
1208 { .channel = 4,
1209 .freq = 2427, /* MHz */
1210 .unk2 = 3236,
1211 RADIOREGS(0x73, 0x09, 0x7B, 0x0F, 0x00, 0x01, 0x07, 0x15,
1212 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A,
1213 0x80, 0xFF, 0x88, 0x0C, 0x0A, 0x80),
1214 PHYREGS(0xCF03, 0xCB03, 0xC703, 0x3404, 0x3804, 0x3D04),
1215 },
1216 { .channel = 5,
1217 .freq = 2432, /* MHz */
1218 .unk2 = 3243,
1219 RADIOREGS(0x73, 0x09, 0x80, 0x0F, 0x00, 0x01, 0x07, 0x15,
1220 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x09,
1221 0x80, 0xFF, 0x88, 0x0C, 0x09, 0x80),
1222 PHYREGS(0xD103, 0xCD03, 0xC903, 0x3104, 0x3604, 0x3A04),
1223 },
1224 { .channel = 6,
1225 .freq = 2437, /* MHz */
1226 .unk2 = 3249,
1227 RADIOREGS(0x73, 0x09, 0x85, 0x0F, 0x00, 0x01, 0x07, 0x15,
1228 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0B, 0x08,
1229 0x80, 0xFF, 0x88, 0x0B, 0x08, 0x80),
1230 PHYREGS(0xD303, 0xCF03, 0xCB03, 0x2F04, 0x3404, 0x3804),
1231 },
1232 { .channel = 7,
1233 .freq = 2442, /* MHz */
1234 .unk2 = 3256,
1235 RADIOREGS(0x73, 0x09, 0x8A, 0x0F, 0x00, 0x01, 0x07, 0x15,
1236 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x07,
1237 0x80, 0xFF, 0x88, 0x0A, 0x07, 0x80),
1238 PHYREGS(0xD503, 0xD103, 0xCD03, 0x2D04, 0x3104, 0x3604),
1239 },
1240 { .channel = 8,
1241 .freq = 2447, /* MHz */
1242 .unk2 = 3263,
1243 RADIOREGS(0x73, 0x09, 0x8F, 0x0F, 0x00, 0x01, 0x07, 0x15,
1244 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x06,
1245 0x80, 0xFF, 0x88, 0x0A, 0x06, 0x80),
1246 PHYREGS(0xD703, 0xD303, 0xCF03, 0x2B04, 0x2F04, 0x3404),
1247 },
1248 { .channel = 9,
1249 .freq = 2452, /* MHz */
1250 .unk2 = 3269,
1251 RADIOREGS(0x73, 0x09, 0x94, 0x0F, 0x00, 0x01, 0x07, 0x15,
1252 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x09, 0x06,
1253 0x80, 0xFF, 0x88, 0x09, 0x06, 0x80),
1254 PHYREGS(0xD903, 0xD503, 0xD103, 0x2904, 0x2D04, 0x3104),
1255 },
1256 { .channel = 10,
1257 .freq = 2457, /* MHz */
1258 .unk2 = 3276,
1259 RADIOREGS(0x73, 0x09, 0x99, 0x0F, 0x00, 0x01, 0x07, 0x15,
1260 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x05,
1261 0x80, 0xFF, 0x88, 0x08, 0x05, 0x80),
1262 PHYREGS(0xDB03, 0xD703, 0xD303, 0x2704, 0x2B04, 0x2F04),
1263 },
1264 { .channel = 11,
1265 .freq = 2462, /* MHz */
1266 .unk2 = 3283,
1267 RADIOREGS(0x73, 0x09, 0x9E, 0x0F, 0x00, 0x01, 0x07, 0x15,
1268 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x04,
1269 0x80, 0xFF, 0x88, 0x08, 0x04, 0x80),
1270 PHYREGS(0xDD03, 0xD903, 0xD503, 0x2404, 0x2904, 0x2D04),
1271 },
1272 { .channel = 12,
1273 .freq = 2467, /* MHz */
1274 .unk2 = 3289,
1275 RADIOREGS(0x73, 0x09, 0xA3, 0x0F, 0x00, 0x01, 0x07, 0x15,
1276 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x03,
1277 0x80, 0xFF, 0x88, 0x08, 0x03, 0x80),
1278 PHYREGS(0xDF03, 0xDB03, 0xD703, 0x2204, 0x2704, 0x2B04),
1279 },
1280 { .channel = 13,
1281 .freq = 2472, /* MHz */
1282 .unk2 = 3296,
1283 RADIOREGS(0x73, 0x09, 0xA8, 0x0F, 0x00, 0x01, 0x07, 0x15,
1284 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x03,
1285 0x80, 0xFF, 0x88, 0x07, 0x03, 0x80),
1286 PHYREGS(0xE103, 0xDD03, 0xD903, 0x2004, 0x2404, 0x2904),
1287 },
1288 { .channel = 14,
1289 .freq = 2484, /* MHz */
1290 .unk2 = 3312,
1291 RADIOREGS(0x73, 0x09, 0xB4, 0x0F, 0xFF, 0x01, 0x07, 0x15,
1292 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x01,
1293 0x80, 0xFF, 0x88, 0x07, 0x01, 0x80),
1294 PHYREGS(0xE603, 0xE203, 0xDE03, 0x1B04, 0x1F04, 0x2404),
1295 },
1296};
1297
1298void b2055_upload_inittab(struct b43_wldev *dev,
1299 bool ghz5, bool ignore_uploadflag)
1300{
1301 const struct b2055_inittab_entry *e;
1302 unsigned int i;
1303 u16 value;
1304
1305 for (i = 0; i < ARRAY_SIZE(b2055_inittab); i++) {
1306 e = &(b2055_inittab[i]);
1307 if (!(e->flags & B2055_INITTAB_ENTRY_OK))
1308 continue;
1309 if ((e->flags & B2055_INITTAB_UPLOAD) || ignore_uploadflag) {
1310 if (ghz5)
1311 value = e->ghz5;
1312 else
1313 value = e->ghz2;
1314 b43_radio_write16(dev, i, value);
1315 }
1316 }
1317}
1318
1319const struct b43_nphy_channeltab_entry_rev2 *
1320b43_nphy_get_chantabent_rev2(struct b43_wldev *dev, u8 channel)
1321{
1322 const struct b43_nphy_channeltab_entry_rev2 *e;
1323 unsigned int i;
1324
1325 for (i = 0; i < ARRAY_SIZE(b43_nphy_channeltab_rev2); i++) {
1326 e = &(b43_nphy_channeltab_rev2[i]);
1327 if (e->channel == channel)
1328 return e;
1329 }
1330
1331 return NULL;
1332}
diff --git a/drivers/net/wireless/b43/radio_2055.h b/drivers/net/wireless/b43/radio_2055.h
new file mode 100644
index 000000000000..d9bfa0f21b72
--- /dev/null
+++ b/drivers/net/wireless/b43/radio_2055.h
@@ -0,0 +1,254 @@
1#ifndef B43_RADIO_2055_H_
2#define B43_RADIO_2055_H_
3
4#include <linux/types.h>
5
6#include "tables_nphy.h"
7
8#define B2055_GEN_SPARE 0x00 /* GEN spare */
9#define B2055_SP_PINPD 0x02 /* SP PIN PD */
10#define B2055_C1_SP_RSSI 0x03 /* SP RSSI Core 1 */
11#define B2055_C1_SP_PDMISC 0x04 /* SP PD MISC Core 1 */
12#define B2055_C2_SP_RSSI 0x05 /* SP RSSI Core 2 */
13#define B2055_C2_SP_PDMISC 0x06 /* SP PD MISC Core 2 */
14#define B2055_C1_SP_RXGC1 0x07 /* SP RX GC1 Core 1 */
15#define B2055_C1_SP_RXGC2 0x08 /* SP RX GC2 Core 1 */
16#define B2055_C2_SP_RXGC1 0x09 /* SP RX GC1 Core 2 */
17#define B2055_C2_SP_RXGC2 0x0A /* SP RX GC2 Core 2 */
18#define B2055_C1_SP_LPFBWSEL 0x0B /* SP LPF BW select Core 1 */
19#define B2055_C2_SP_LPFBWSEL 0x0C /* SP LPF BW select Core 2 */
20#define B2055_C1_SP_TXGC1 0x0D /* SP TX GC1 Core 1 */
21#define B2055_C1_SP_TXGC2 0x0E /* SP TX GC2 Core 1 */
22#define B2055_C2_SP_TXGC1 0x0F /* SP TX GC1 Core 2 */
23#define B2055_C2_SP_TXGC2 0x10 /* SP TX GC2 Core 2 */
24#define B2055_MASTER1 0x11 /* Master control 1 */
25#define B2055_MASTER2 0x12 /* Master control 2 */
26#define B2055_PD_LGEN 0x13 /* PD LGEN */
27#define B2055_PD_PLLTS 0x14 /* PD PLL TS */
28#define B2055_C1_PD_LGBUF 0x15 /* PD Core 1 LGBUF */
29#define B2055_C1_PD_TX 0x16 /* PD Core 1 TX */
30#define B2055_C1_PD_RXTX 0x17 /* PD Core 1 RXTX */
31#define B2055_C1_PD_RSSIMISC 0x18 /* PD Core 1 RSSI MISC */
32#define B2055_C2_PD_LGBUF 0x19 /* PD Core 2 LGBUF */
33#define B2055_C2_PD_TX 0x1A /* PD Core 2 TX */
34#define B2055_C2_PD_RXTX 0x1B /* PD Core 2 RXTX */
35#define B2055_C2_PD_RSSIMISC 0x1C /* PD Core 2 RSSI MISC */
36#define B2055_PWRDET_LGEN 0x1D /* PWRDET LGEN */
37#define B2055_C1_PWRDET_LGBUF 0x1E /* PWRDET LGBUF Core 1 */
38#define B2055_C1_PWRDET_RXTX 0x1F /* PWRDET RXTX Core 1 */
39#define B2055_C2_PWRDET_LGBUF 0x20 /* PWRDET LGBUF Core 2 */
40#define B2055_C2_PWRDET_RXTX 0x21 /* PWRDET RXTX Core 2 */
41#define B2055_RRCCAL_CS 0x22 /* RRCCAL Control spare */
42#define B2055_RRCCAL_NOPTSEL 0x23 /* RRCCAL N OPT SEL */
43#define B2055_CAL_MISC 0x24 /* CAL MISC */
44#define B2055_CAL_COUT 0x25 /* CAL Counter out */
45#define B2055_CAL_COUT2 0x26 /* CAL Counter out 2 */
46#define B2055_CAL_CVARCTL 0x27 /* CAL CVAR Control */
47#define B2055_CAL_RVARCTL 0x28 /* CAL RVAR Control */
48#define B2055_CAL_LPOCTL 0x29 /* CAL LPO Control */
49#define B2055_CAL_TS 0x2A /* CAL TS */
50#define B2055_CAL_RCCALRTS 0x2B /* CAL RCCAL READ TS */
51#define B2055_CAL_RCALRTS 0x2C /* CAL RCAL READ TS */
52#define B2055_PADDRV 0x2D /* PAD driver */
53#define B2055_XOCTL1 0x2E /* XO Control 1 */
54#define B2055_XOCTL2 0x2F /* XO Control 2 */
55#define B2055_XOREGUL 0x30 /* XO Regulator */
56#define B2055_XOMISC 0x31 /* XO misc */
57#define B2055_PLL_LFC1 0x32 /* PLL LF C1 */
58#define B2055_PLL_CALVTH 0x33 /* PLL CAL VTH */
59#define B2055_PLL_LFC2 0x34 /* PLL LF C2 */
60#define B2055_PLL_REF 0x35 /* PLL reference */
61#define B2055_PLL_LFR1 0x36 /* PLL LF R1 */
62#define B2055_PLL_PFDCP 0x37 /* PLL PFD CP */
63#define B2055_PLL_IDAC_CPOPAMP 0x38 /* PLL IDAC CPOPAMP */
64#define B2055_PLL_CPREG 0x39 /* PLL CP Regulator */
65#define B2055_PLL_RCAL 0x3A /* PLL RCAL */
66#define B2055_RF_PLLMOD0 0x3B /* RF PLL MOD0 */
67#define B2055_RF_PLLMOD1 0x3C /* RF PLL MOD1 */
68#define B2055_RF_MMDIDAC1 0x3D /* RF MMD IDAC 1 */
69#define B2055_RF_MMDIDAC0 0x3E /* RF MMD IDAC 0 */
70#define B2055_RF_MMDSP 0x3F /* RF MMD spare */
71#define B2055_VCO_CAL1 0x40 /* VCO cal 1 */
72#define B2055_VCO_CAL2 0x41 /* VCO cal 2 */
73#define B2055_VCO_CAL3 0x42 /* VCO cal 3 */
74#define B2055_VCO_CAL4 0x43 /* VCO cal 4 */
75#define B2055_VCO_CAL5 0x44 /* VCO cal 5 */
76#define B2055_VCO_CAL6 0x45 /* VCO cal 6 */
77#define B2055_VCO_CAL7 0x46 /* VCO cal 7 */
78#define B2055_VCO_CAL8 0x47 /* VCO cal 8 */
79#define B2055_VCO_CAL9 0x48 /* VCO cal 9 */
80#define B2055_VCO_CAL10 0x49 /* VCO cal 10 */
81#define B2055_VCO_CAL11 0x4A /* VCO cal 11 */
82#define B2055_VCO_CAL12 0x4B /* VCO cal 12 */
83#define B2055_VCO_CAL13 0x4C /* VCO cal 13 */
84#define B2055_VCO_CAL14 0x4D /* VCO cal 14 */
85#define B2055_VCO_CAL15 0x4E /* VCO cal 15 */
86#define B2055_VCO_CAL16 0x4F /* VCO cal 16 */
87#define B2055_VCO_KVCO 0x50 /* VCO KVCO */
88#define B2055_VCO_CAPTAIL 0x51 /* VCO CAP TAIL */
89#define B2055_VCO_IDACVCO 0x52 /* VCO IDAC VCO */
90#define B2055_VCO_REG 0x53 /* VCO Regulator */
91#define B2055_PLL_RFVTH 0x54 /* PLL RF VTH */
92#define B2055_LGBUF_CENBUF 0x55 /* LGBUF CEN BUF */
93#define B2055_LGEN_TUNE1 0x56 /* LGEN tune 1 */
94#define B2055_LGEN_TUNE2 0x57 /* LGEN tune 2 */
95#define B2055_LGEN_IDAC1 0x58 /* LGEN IDAC 1 */
96#define B2055_LGEN_IDAC2 0x59 /* LGEN IDAC 2 */
97#define B2055_LGEN_BIASC 0x5A /* LGEN BIAS counter */
98#define B2055_LGEN_BIASIDAC 0x5B /* LGEN BIAS IDAC */
99#define B2055_LGEN_RCAL 0x5C /* LGEN RCAL */
100#define B2055_LGEN_DIV 0x5D /* LGEN div */
101#define B2055_LGEN_SPARE2 0x5E /* LGEN spare 2 */
102#define B2055_C1_LGBUF_ATUNE 0x5F /* Core 1 LGBUF A tune */
103#define B2055_C1_LGBUF_GTUNE 0x60 /* Core 1 LGBUF G tune */
104#define B2055_C1_LGBUF_DIV 0x61 /* Core 1 LGBUF div */
105#define B2055_C1_LGBUF_AIDAC 0x62 /* Core 1 LGBUF A IDAC */
106#define B2055_C1_LGBUF_GIDAC 0x63 /* Core 1 LGBUF G IDAC */
107#define B2055_C1_LGBUF_IDACFO 0x64 /* Core 1 LGBUF IDAC filter override */
108#define B2055_C1_LGBUF_SPARE 0x65 /* Core 1 LGBUF spare */
109#define B2055_C1_RX_RFSPC1 0x66 /* Core 1 RX RF SPC1 */
110#define B2055_C1_RX_RFR1 0x67 /* Core 1 RX RF reg 1 */
111#define B2055_C1_RX_RFR2 0x68 /* Core 1 RX RF reg 2 */
112#define B2055_C1_RX_RFRCAL 0x69 /* Core 1 RX RF RCAL */
113#define B2055_C1_RX_BB_BLCMP 0x6A /* Core 1 RX Baseband BUFI LPF CMP */
114#define B2055_C1_RX_BB_LPF 0x6B /* Core 1 RX Baseband LPF */
115#define B2055_C1_RX_BB_MIDACHP 0x6C /* Core 1 RX Baseband MIDAC High-pass */
116#define B2055_C1_RX_BB_VGA1IDAC 0x6D /* Core 1 RX Baseband VGA1 IDAC */
117#define B2055_C1_RX_BB_VGA2IDAC 0x6E /* Core 1 RX Baseband VGA2 IDAC */
118#define B2055_C1_RX_BB_VGA3IDAC 0x6F /* Core 1 RX Baseband VGA3 IDAC */
119#define B2055_C1_RX_BB_BUFOCTL 0x70 /* Core 1 RX Baseband BUFO Control */
120#define B2055_C1_RX_BB_RCCALCTL 0x71 /* Core 1 RX Baseband RCCAL Control */
121#define B2055_C1_RX_BB_RSSICTL1 0x72 /* Core 1 RX Baseband RSSI Control 1 */
122#define B2055_C1_RX_BB_RSSICTL2 0x73 /* Core 1 RX Baseband RSSI Control 2 */
123#define B2055_C1_RX_BB_RSSICTL3 0x74 /* Core 1 RX Baseband RSSI Control 3 */
124#define B2055_C1_RX_BB_RSSICTL4 0x75 /* Core 1 RX Baseband RSSI Control 4 */
125#define B2055_C1_RX_BB_RSSICTL5 0x76 /* Core 1 RX Baseband RSSI Control 5 */
126#define B2055_C1_RX_BB_REG 0x77 /* Core 1 RX Baseband Regulator */
127#define B2055_C1_RX_BB_SPARE1 0x78 /* Core 1 RX Baseband spare 1 */
128#define B2055_C1_RX_TXBBRCAL 0x79 /* Core 1 RX TX BB RCAL */
129#define B2055_C1_TX_RF_SPGA 0x7A /* Core 1 TX RF SGM PGA */
130#define B2055_C1_TX_RF_SPAD 0x7B /* Core 1 TX RF SGM PAD */
131#define B2055_C1_TX_RF_CNTPGA1 0x7C /* Core 1 TX RF counter PGA 1 */
132#define B2055_C1_TX_RF_CNTPAD1 0x7D /* Core 1 TX RF counter PAD 1 */
133#define B2055_C1_TX_RF_PGAIDAC 0x7E /* Core 1 TX RF PGA IDAC */
134#define B2055_C1_TX_PGAPADTN 0x7F /* Core 1 TX PGA PAD TN */
135#define B2055_C1_TX_PADIDAC1 0x80 /* Core 1 TX PAD IDAC 1 */
136#define B2055_C1_TX_PADIDAC2 0x81 /* Core 1 TX PAD IDAC 2 */
137#define B2055_C1_TX_MXBGTRIM 0x82 /* Core 1 TX MX B/G TRIM */
138#define B2055_C1_TX_RF_RCAL 0x83 /* Core 1 TX RF RCAL */
139#define B2055_C1_TX_RF_PADTSSI1 0x84 /* Core 1 TX RF PAD TSSI1 */
140#define B2055_C1_TX_RF_PADTSSI2 0x85 /* Core 1 TX RF PAD TSSI2 */
141#define B2055_C1_TX_RF_SPARE 0x86 /* Core 1 TX RF spare */
142#define B2055_C1_TX_RF_IQCAL1 0x87 /* Core 1 TX RF I/Q CAL 1 */
143#define B2055_C1_TX_RF_IQCAL2 0x88 /* Core 1 TX RF I/Q CAL 2 */
144#define B2055_C1_TXBB_RCCAL 0x89 /* Core 1 TXBB RC CAL Control */
145#define B2055_C1_TXBB_LPF1 0x8A /* Core 1 TXBB LPF 1 */
146#define B2055_C1_TX_VOSCNCL 0x8B /* Core 1 TX VOS CNCL */
147#define B2055_C1_TX_LPF_MXGMIDAC 0x8C /* Core 1 TX LPF MXGM IDAC */
148#define B2055_C1_TX_BB_MXGM 0x8D /* Core 1 TX BB MXGM */
149#define B2055_C2_LGBUF_ATUNE 0x8E /* Core 2 LGBUF A tune */
150#define B2055_C2_LGBUF_GTUNE 0x8F /* Core 2 LGBUF G tune */
151#define B2055_C2_LGBUF_DIV 0x90 /* Core 2 LGBUF div */
152#define B2055_C2_LGBUF_AIDAC 0x91 /* Core 2 LGBUF A IDAC */
153#define B2055_C2_LGBUF_GIDAC 0x92 /* Core 2 LGBUF G IDAC */
154#define B2055_C2_LGBUF_IDACFO 0x93 /* Core 2 LGBUF IDAC filter override */
155#define B2055_C2_LGBUF_SPARE 0x94 /* Core 2 LGBUF spare */
156#define B2055_C2_RX_RFSPC1 0x95 /* Core 2 RX RF SPC1 */
157#define B2055_C2_RX_RFR1 0x96 /* Core 2 RX RF reg 1 */
158#define B2055_C2_RX_RFR2 0x97 /* Core 2 RX RF reg 2 */
159#define B2055_C2_RX_RFRCAL 0x98 /* Core 2 RX RF RCAL */
160#define B2055_C2_RX_BB_BLCMP 0x99 /* Core 2 RX Baseband BUFI LPF CMP */
161#define B2055_C2_RX_BB_LPF 0x9A /* Core 2 RX Baseband LPF */
162#define B2055_C2_RX_BB_MIDACHP 0x9B /* Core 2 RX Baseband MIDAC High-pass */
163#define B2055_C2_RX_BB_VGA1IDAC 0x9C /* Core 2 RX Baseband VGA1 IDAC */
164#define B2055_C2_RX_BB_VGA2IDAC 0x9D /* Core 2 RX Baseband VGA2 IDAC */
165#define B2055_C2_RX_BB_VGA3IDAC 0x9E /* Core 2 RX Baseband VGA3 IDAC */
166#define B2055_C2_RX_BB_BUFOCTL 0x9F /* Core 2 RX Baseband BUFO Control */
167#define B2055_C2_RX_BB_RCCALCTL 0xA0 /* Core 2 RX Baseband RCCAL Control */
168#define B2055_C2_RX_BB_RSSICTL1 0xA1 /* Core 2 RX Baseband RSSI Control 1 */
169#define B2055_C2_RX_BB_RSSICTL2 0xA2 /* Core 2 RX Baseband RSSI Control 2 */
170#define B2055_C2_RX_BB_RSSICTL3 0xA3 /* Core 2 RX Baseband RSSI Control 3 */
171#define B2055_C2_RX_BB_RSSICTL4 0xA4 /* Core 2 RX Baseband RSSI Control 4 */
172#define B2055_C2_RX_BB_RSSICTL5 0xA5 /* Core 2 RX Baseband RSSI Control 5 */
173#define B2055_C2_RX_BB_REG 0xA6 /* Core 2 RX Baseband Regulator */
174#define B2055_C2_RX_BB_SPARE1 0xA7 /* Core 2 RX Baseband spare 1 */
175#define B2055_C2_RX_TXBBRCAL 0xA8 /* Core 2 RX TX BB RCAL */
176#define B2055_C2_TX_RF_SPGA 0xA9 /* Core 2 TX RF SGM PGA */
177#define B2055_C2_TX_RF_SPAD 0xAA /* Core 2 TX RF SGM PAD */
178#define B2055_C2_TX_RF_CNTPGA1 0xAB /* Core 2 TX RF counter PGA 1 */
179#define B2055_C2_TX_RF_CNTPAD1 0xAC /* Core 2 TX RF counter PAD 1 */
180#define B2055_C2_TX_RF_PGAIDAC 0xAD /* Core 2 TX RF PGA IDAC */
181#define B2055_C2_TX_PGAPADTN 0xAE /* Core 2 TX PGA PAD TN */
182#define B2055_C2_TX_PADIDAC1 0xAF /* Core 2 TX PAD IDAC 1 */
183#define B2055_C2_TX_PADIDAC2 0xB0 /* Core 2 TX PAD IDAC 2 */
184#define B2055_C2_TX_MXBGTRIM 0xB1 /* Core 2 TX MX B/G TRIM */
185#define B2055_C2_TX_RF_RCAL 0xB2 /* Core 2 TX RF RCAL */
186#define B2055_C2_TX_RF_PADTSSI1 0xB3 /* Core 2 TX RF PAD TSSI1 */
187#define B2055_C2_TX_RF_PADTSSI2 0xB4 /* Core 2 TX RF PAD TSSI2 */
188#define B2055_C2_TX_RF_SPARE 0xB5 /* Core 2 TX RF spare */
189#define B2055_C2_TX_RF_IQCAL1 0xB6 /* Core 2 TX RF I/Q CAL 1 */
190#define B2055_C2_TX_RF_IQCAL2 0xB7 /* Core 2 TX RF I/Q CAL 2 */
191#define B2055_C2_TXBB_RCCAL 0xB8 /* Core 2 TXBB RC CAL Control */
192#define B2055_C2_TXBB_LPF1 0xB9 /* Core 2 TXBB LPF 1 */
193#define B2055_C2_TX_VOSCNCL 0xBA /* Core 2 TX VOS CNCL */
194#define B2055_C2_TX_LPF_MXGMIDAC 0xBB /* Core 2 TX LPF MXGM IDAC */
195#define B2055_C2_TX_BB_MXGM 0xBC /* Core 2 TX BB MXGM */
196#define B2055_PRG_GCHP21 0xBD /* PRG GC HPVGA23 21 */
197#define B2055_PRG_GCHP22 0xBE /* PRG GC HPVGA23 22 */
198#define B2055_PRG_GCHP23 0xBF /* PRG GC HPVGA23 23 */
199#define B2055_PRG_GCHP24 0xC0 /* PRG GC HPVGA23 24 */
200#define B2055_PRG_GCHP25 0xC1 /* PRG GC HPVGA23 25 */
201#define B2055_PRG_GCHP26 0xC2 /* PRG GC HPVGA23 26 */
202#define B2055_PRG_GCHP27 0xC3 /* PRG GC HPVGA23 27 */
203#define B2055_PRG_GCHP28 0xC4 /* PRG GC HPVGA23 28 */
204#define B2055_PRG_GCHP29 0xC5 /* PRG GC HPVGA23 29 */
205#define B2055_PRG_GCHP30 0xC6 /* PRG GC HPVGA23 30 */
206#define B2055_C1_LNA_GAINBST 0xCD /* Core 1 LNA GAINBST */
207#define B2055_C1_B0NB_RSSIVCM 0xD2 /* Core 1 B0 narrow-band RSSI VCM */
208#define B2055_C1_GENSPARE2 0xD6 /* Core 1 GEN spare 2 */
209#define B2055_C2_LNA_GAINBST 0xD9 /* Core 2 LNA GAINBST */
210#define B2055_C2_B0NB_RSSIVCM 0xDE /* Core 2 B0 narrow-band RSSI VCM */
211#define B2055_C2_GENSPARE2 0xE2 /* Core 2 GEN spare 2 */
212
213struct b43_nphy_channeltab_entry_rev2 {
214 /* The channel number */
215 u8 channel;
216 /* The channel frequency in MHz */
217 u16 freq;
218 /* An unknown value */
219 u16 unk2;
220 /* Radio register values on channelswitch */
221 u8 radio_pll_ref;
222 u8 radio_rf_pllmod0;
223 u8 radio_rf_pllmod1;
224 u8 radio_vco_captail;
225 u8 radio_vco_cal1;
226 u8 radio_vco_cal2;
227 u8 radio_pll_lfc1;
228 u8 radio_pll_lfr1;
229 u8 radio_pll_lfc2;
230 u8 radio_lgbuf_cenbuf;
231 u8 radio_lgen_tune1;
232 u8 radio_lgen_tune2;
233 u8 radio_c1_lgbuf_atune;
234 u8 radio_c1_lgbuf_gtune;
235 u8 radio_c1_rx_rfr1;
236 u8 radio_c1_tx_pgapadtn;
237 u8 radio_c1_tx_mxbgtrim;
238 u8 radio_c2_lgbuf_atune;
239 u8 radio_c2_lgbuf_gtune;
240 u8 radio_c2_rx_rfr1;
241 u8 radio_c2_tx_pgapadtn;
242 u8 radio_c2_tx_mxbgtrim;
243 /* PHY register values on channelswitch */
244 struct b43_phy_n_sfo_cfg phy_regs;
245};
246
247/* Upload the default register value table.
248 * If "ghz5" is true, we upload the 5Ghz table. Otherwise the 2.4Ghz
249 * table is uploaded. If "ignore_uploadflag" is true, we upload any value
250 * and ignore the "UPLOAD" flag. */
251void b2055_upload_inittab(struct b43_wldev *dev,
252 bool ghz5, bool ignore_uploadflag);
253
254#endif /* B43_RADIO_2055_H_ */
diff --git a/drivers/net/wireless/b43/radio_2056.c b/drivers/net/wireless/b43/radio_2056.c
new file mode 100644
index 000000000000..d8563192ce56
--- /dev/null
+++ b/drivers/net/wireless/b43/radio_2056.c
@@ -0,0 +1,43 @@
1/*
2
3 Broadcom B43 wireless driver
4 IEEE 802.11n 2056 radio device data tables
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
19 Boston, MA 02110-1301, USA.
20
21*/
22
23#include "b43.h"
24#include "radio_2056.h"
25#include "phy_common.h"
26
27static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev3[] = {
28};
29
30const struct b43_nphy_channeltab_entry_rev3 *
31b43_nphy_get_chantabent_rev3(struct b43_wldev *dev, u16 freq)
32{
33 const struct b43_nphy_channeltab_entry_rev3 *e;
34 unsigned int i;
35
36 for (i = 0; i < ARRAY_SIZE(b43_nphy_channeltab_rev3); i++) {
37 e = &(b43_nphy_channeltab_rev3[i]);
38 if (e->freq == freq)
39 return e;
40 }
41
42 return NULL;
43}
diff --git a/drivers/net/wireless/b43/radio_2056.h b/drivers/net/wireless/b43/radio_2056.h
new file mode 100644
index 000000000000..fda6dafecb8c
--- /dev/null
+++ b/drivers/net/wireless/b43/radio_2056.h
@@ -0,0 +1,42 @@
1/*
2
3 Broadcom B43 wireless driver
4
5 Copyright (c) 2010 Rafał Miłecki <zajec5@gmail.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
20 Boston, MA 02110-1301, USA.
21
22*/
23
24#ifndef B43_RADIO_2056_H_
25#define B43_RADIO_2056_H_
26
27#include <linux/types.h>
28
29#include "tables_nphy.h"
30
31struct b43_nphy_channeltab_entry_rev3 {
32 /* The channel number */
33 u8 channel;
34 /* The channel frequency in MHz */
35 u16 freq;
36 /* Radio register values on channelswitch */
37 /* TODO */
38 /* PHY register values on channelswitch */
39 struct b43_phy_n_sfo_cfg phy_regs;
40};
41
42#endif /* B43_RADIO_2056_H_ */
diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c
index d96e870ab8fe..d60db078eae2 100644
--- a/drivers/net/wireless/b43/tables_nphy.c
+++ b/drivers/net/wireless/b43/tables_nphy.c
@@ -1,7 +1,7 @@
1/* 1/*
2 2
3 Broadcom B43 wireless driver 3 Broadcom B43 wireless driver
4 IEEE 802.11n PHY and radio device data tables 4 IEEE 802.11n PHY data tables
5 5
6 Copyright (c) 2008 Michael Buesch <mb@bu3sch.de> 6 Copyright (c) 2008 Michael Buesch <mb@bu3sch.de>
7 7
@@ -27,1315 +27,6 @@
27#include "phy_common.h" 27#include "phy_common.h"
28#include "phy_n.h" 28#include "phy_n.h"
29 29
30
31struct b2055_inittab_entry {
32 /* Value to write if we use the 5GHz band. */
33 u16 ghz5;
34 /* Value to write if we use the 2.4GHz band. */
35 u16 ghz2;
36 /* Flags */
37 u8 flags;
38#define B2055_INITTAB_ENTRY_OK 0x01
39#define B2055_INITTAB_UPLOAD 0x02
40};
41#define UPLOAD .flags = B2055_INITTAB_ENTRY_OK | B2055_INITTAB_UPLOAD
42#define NOUPLOAD .flags = B2055_INITTAB_ENTRY_OK
43
44static const struct b2055_inittab_entry b2055_inittab [] = {
45 [B2055_SP_PINPD] = { .ghz5 = 0x0080, .ghz2 = 0x0080, NOUPLOAD, },
46 [B2055_C1_SP_RSSI] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
47 [B2055_C1_SP_PDMISC] = { .ghz5 = 0x0027, .ghz2 = 0x0027, NOUPLOAD, },
48 [B2055_C2_SP_RSSI] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
49 [B2055_C2_SP_PDMISC] = { .ghz5 = 0x0027, .ghz2 = 0x0027, NOUPLOAD, },
50 [B2055_C1_SP_RXGC1] = { .ghz5 = 0x007F, .ghz2 = 0x007F, UPLOAD, },
51 [B2055_C1_SP_RXGC2] = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, },
52 [B2055_C2_SP_RXGC1] = { .ghz5 = 0x007F, .ghz2 = 0x007F, UPLOAD, },
53 [B2055_C2_SP_RXGC2] = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, },
54 [B2055_C1_SP_LPFBWSEL] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
55 [B2055_C2_SP_LPFBWSEL] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
56 [B2055_C1_SP_TXGC1] = { .ghz5 = 0x004F, .ghz2 = 0x004F, UPLOAD, },
57 [B2055_C1_SP_TXGC2] = { .ghz5 = 0x0005, .ghz2 = 0x0005, UPLOAD, },
58 [B2055_C2_SP_TXGC1] = { .ghz5 = 0x004F, .ghz2 = 0x004F, UPLOAD, },
59 [B2055_C2_SP_TXGC2] = { .ghz5 = 0x0005, .ghz2 = 0x0005, UPLOAD, },
60 [B2055_MASTER1] = { .ghz5 = 0x00D0, .ghz2 = 0x00D0, NOUPLOAD, },
61 [B2055_MASTER2] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
62 [B2055_PD_LGEN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
63 [B2055_PD_PLLTS] = { .ghz5 = 0x0040, .ghz2 = 0x0040, NOUPLOAD, },
64 [B2055_C1_PD_LGBUF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
65 [B2055_C1_PD_TX] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
66 [B2055_C1_PD_RXTX] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
67 [B2055_C1_PD_RSSIMISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
68 [B2055_C2_PD_LGBUF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
69 [B2055_C2_PD_TX] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
70 [B2055_C2_PD_RXTX] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
71 [B2055_C2_PD_RSSIMISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
72 [B2055_PWRDET_LGEN] = { .ghz5 = 0x00C0, .ghz2 = 0x00C0, NOUPLOAD, },
73 [B2055_C1_PWRDET_LGBUF] = { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, },
74 [B2055_C1_PWRDET_RXTX] = { .ghz5 = 0x00C0, .ghz2 = 0x00C0, NOUPLOAD, },
75 [B2055_C2_PWRDET_LGBUF] = { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, },
76 [B2055_C2_PWRDET_RXTX] = { .ghz5 = 0x00C0, .ghz2 = 0x00C0, NOUPLOAD, },
77 [B2055_RRCCAL_CS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
78 [B2055_RRCCAL_NOPTSEL] = { .ghz5 = 0x002C, .ghz2 = 0x002C, NOUPLOAD, },
79 [B2055_CAL_MISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
80 [B2055_CAL_COUT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
81 [B2055_CAL_COUT2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
82 [B2055_CAL_CVARCTL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
83 [B2055_CAL_RVARCTL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
84 [B2055_CAL_LPOCTL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
85 [B2055_CAL_TS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
86 [B2055_CAL_RCCALRTS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
87 [B2055_CAL_RCALRTS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
88 [B2055_PADDRV] = { .ghz5 = 0x00A4, .ghz2 = 0x00A4, NOUPLOAD, },
89 [B2055_XOCTL1] = { .ghz5 = 0x0038, .ghz2 = 0x0038, NOUPLOAD, },
90 [B2055_XOCTL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
91 [B2055_XOREGUL] = { .ghz5 = 0x0004, .ghz2 = 0x0004, UPLOAD, },
92 [B2055_XOMISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
93 [B2055_PLL_LFC1] = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
94 [B2055_PLL_CALVTH] = { .ghz5 = 0x0087, .ghz2 = 0x0087, NOUPLOAD, },
95 [B2055_PLL_LFC2] = { .ghz5 = 0x0009, .ghz2 = 0x0009, NOUPLOAD, },
96 [B2055_PLL_REF] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, },
97 [B2055_PLL_LFR1] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, },
98 [B2055_PLL_PFDCP] = { .ghz5 = 0x0018, .ghz2 = 0x0018, UPLOAD, },
99 [B2055_PLL_IDAC_CPOPAMP] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
100 [B2055_PLL_CPREG] = { .ghz5 = 0x0004, .ghz2 = 0x0004, UPLOAD, },
101 [B2055_PLL_RCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
102 [B2055_RF_PLLMOD0] = { .ghz5 = 0x009E, .ghz2 = 0x009E, NOUPLOAD, },
103 [B2055_RF_PLLMOD1] = { .ghz5 = 0x0009, .ghz2 = 0x0009, NOUPLOAD, },
104 [B2055_RF_MMDIDAC1] = { .ghz5 = 0x00C8, .ghz2 = 0x00C8, UPLOAD, },
105 [B2055_RF_MMDIDAC0] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
106 [B2055_RF_MMDSP] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
107 [B2055_VCO_CAL1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
108 [B2055_VCO_CAL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
109 [B2055_VCO_CAL3] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
110 [B2055_VCO_CAL4] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
111 [B2055_VCO_CAL5] = { .ghz5 = 0x0096, .ghz2 = 0x0096, NOUPLOAD, },
112 [B2055_VCO_CAL6] = { .ghz5 = 0x003E, .ghz2 = 0x003E, NOUPLOAD, },
113 [B2055_VCO_CAL7] = { .ghz5 = 0x003E, .ghz2 = 0x003E, NOUPLOAD, },
114 [B2055_VCO_CAL8] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, },
115 [B2055_VCO_CAL9] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
116 [B2055_VCO_CAL10] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
117 [B2055_VCO_CAL11] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
118 [B2055_VCO_CAL12] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
119 [B2055_VCO_CAL13] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
120 [B2055_VCO_CAL14] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
121 [B2055_VCO_CAL15] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
122 [B2055_VCO_CAL16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
123 [B2055_VCO_KVCO] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
124 [B2055_VCO_CAPTAIL] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
125 [B2055_VCO_IDACVCO] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
126 [B2055_VCO_REG] = { .ghz5 = 0x0084, .ghz2 = 0x0084, UPLOAD, },
127 [B2055_PLL_RFVTH] = { .ghz5 = 0x00C3, .ghz2 = 0x00C3, NOUPLOAD, },
128 [B2055_LGBUF_CENBUF] = { .ghz5 = 0x008F, .ghz2 = 0x008F, NOUPLOAD, },
129 [B2055_LGEN_TUNE1] = { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, },
130 [B2055_LGEN_TUNE2] = { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, },
131 [B2055_LGEN_IDAC1] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
132 [B2055_LGEN_IDAC2] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
133 [B2055_LGEN_BIASC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
134 [B2055_LGEN_BIASIDAC] = { .ghz5 = 0x00CC, .ghz2 = 0x00CC, NOUPLOAD, },
135 [B2055_LGEN_RCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
136 [B2055_LGEN_DIV] = { .ghz5 = 0x0080, .ghz2 = 0x0080, NOUPLOAD, },
137 [B2055_LGEN_SPARE2] = { .ghz5 = 0x0080, .ghz2 = 0x0080, NOUPLOAD, },
138 [B2055_C1_LGBUF_ATUNE] = { .ghz5 = 0x00F8, .ghz2 = 0x00F8, NOUPLOAD, },
139 [B2055_C1_LGBUF_GTUNE] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
140 [B2055_C1_LGBUF_DIV] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
141 [B2055_C1_LGBUF_AIDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0008, UPLOAD, },
142 [B2055_C1_LGBUF_GIDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
143 [B2055_C1_LGBUF_IDACFO] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
144 [B2055_C1_LGBUF_SPARE] = { .ghz5 = 0x0001, .ghz2 = 0x0001, UPLOAD, },
145 [B2055_C1_RX_RFSPC1] = { .ghz5 = 0x008A, .ghz2 = 0x008A, NOUPLOAD, },
146 [B2055_C1_RX_RFR1] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
147 [B2055_C1_RX_RFR2] = { .ghz5 = 0x0083, .ghz2 = 0x0083, NOUPLOAD, },
148 [B2055_C1_RX_RFRCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
149 [B2055_C1_RX_BB_BLCMP] = { .ghz5 = 0x00A0, .ghz2 = 0x00A0, NOUPLOAD, },
150 [B2055_C1_RX_BB_LPF] = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
151 [B2055_C1_RX_BB_MIDACHP] = { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, },
152 [B2055_C1_RX_BB_VGA1IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
153 [B2055_C1_RX_BB_VGA2IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
154 [B2055_C1_RX_BB_VGA3IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
155 [B2055_C1_RX_BB_BUFOCTL] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
156 [B2055_C1_RX_BB_RCCALCTL] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
157 [B2055_C1_RX_BB_RSSICTL1] = { .ghz5 = 0x006A, .ghz2 = 0x006A, UPLOAD, },
158 [B2055_C1_RX_BB_RSSICTL2] = { .ghz5 = 0x00AB, .ghz2 = 0x00AB, UPLOAD, },
159 [B2055_C1_RX_BB_RSSICTL3] = { .ghz5 = 0x0013, .ghz2 = 0x0013, UPLOAD, },
160 [B2055_C1_RX_BB_RSSICTL4] = { .ghz5 = 0x00C1, .ghz2 = 0x00C1, UPLOAD, },
161 [B2055_C1_RX_BB_RSSICTL5] = { .ghz5 = 0x00AA, .ghz2 = 0x00AA, UPLOAD, },
162 [B2055_C1_RX_BB_REG] = { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, },
163 [B2055_C1_RX_BB_SPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
164 [B2055_C1_RX_TXBBRCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
165 [B2055_C1_TX_RF_SPGA] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
166 [B2055_C1_TX_RF_SPAD] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
167 [B2055_C1_TX_RF_CNTPGA1] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
168 [B2055_C1_TX_RF_CNTPAD1] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, },
169 [B2055_C1_TX_RF_PGAIDAC] = { .ghz5 = 0x0097, .ghz2 = 0x0097, UPLOAD, },
170 [B2055_C1_TX_PGAPADTN] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
171 [B2055_C1_TX_PADIDAC1] = { .ghz5 = 0x0014, .ghz2 = 0x0014, UPLOAD, },
172 [B2055_C1_TX_PADIDAC2] = { .ghz5 = 0x0033, .ghz2 = 0x0033, NOUPLOAD, },
173 [B2055_C1_TX_MXBGTRIM] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
174 [B2055_C1_TX_RF_RCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
175 [B2055_C1_TX_RF_PADTSSI1] = { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, },
176 [B2055_C1_TX_RF_PADTSSI2] = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
177 [B2055_C1_TX_RF_SPARE] = { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, },
178 [B2055_C1_TX_RF_IQCAL1] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
179 [B2055_C1_TX_RF_IQCAL2] = { .ghz5 = 0x00A4, .ghz2 = 0x00A4, NOUPLOAD, },
180 [B2055_C1_TXBB_RCCAL] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
181 [B2055_C1_TXBB_LPF1] = { .ghz5 = 0x0028, .ghz2 = 0x0028, NOUPLOAD, },
182 [B2055_C1_TX_VOSCNCL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
183 [B2055_C1_TX_LPF_MXGMIDAC] = { .ghz5 = 0x004A, .ghz2 = 0x004A, NOUPLOAD, },
184 [B2055_C1_TX_BB_MXGM] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
185 [B2055_C2_LGBUF_ATUNE] = { .ghz5 = 0x00F8, .ghz2 = 0x00F8, NOUPLOAD, },
186 [B2055_C2_LGBUF_GTUNE] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
187 [B2055_C2_LGBUF_DIV] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
188 [B2055_C2_LGBUF_AIDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0008, UPLOAD, },
189 [B2055_C2_LGBUF_GIDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
190 [B2055_C2_LGBUF_IDACFO] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
191 [B2055_C2_LGBUF_SPARE] = { .ghz5 = 0x0001, .ghz2 = 0x0001, UPLOAD, },
192 [B2055_C2_RX_RFSPC1] = { .ghz5 = 0x008A, .ghz2 = 0x008A, NOUPLOAD, },
193 [B2055_C2_RX_RFR1] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
194 [B2055_C2_RX_RFR2] = { .ghz5 = 0x0083, .ghz2 = 0x0083, NOUPLOAD, },
195 [B2055_C2_RX_RFRCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
196 [B2055_C2_RX_BB_BLCMP] = { .ghz5 = 0x00A0, .ghz2 = 0x00A0, NOUPLOAD, },
197 [B2055_C2_RX_BB_LPF] = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
198 [B2055_C2_RX_BB_MIDACHP] = { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, },
199 [B2055_C2_RX_BB_VGA1IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
200 [B2055_C2_RX_BB_VGA2IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
201 [B2055_C2_RX_BB_VGA3IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
202 [B2055_C2_RX_BB_BUFOCTL] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
203 [B2055_C2_RX_BB_RCCALCTL] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
204 [B2055_C2_RX_BB_RSSICTL1] = { .ghz5 = 0x006A, .ghz2 = 0x006A, UPLOAD, },
205 [B2055_C2_RX_BB_RSSICTL2] = { .ghz5 = 0x00AB, .ghz2 = 0x00AB, UPLOAD, },
206 [B2055_C2_RX_BB_RSSICTL3] = { .ghz5 = 0x0013, .ghz2 = 0x0013, UPLOAD, },
207 [B2055_C2_RX_BB_RSSICTL4] = { .ghz5 = 0x00C1, .ghz2 = 0x00C1, UPLOAD, },
208 [B2055_C2_RX_BB_RSSICTL5] = { .ghz5 = 0x00AA, .ghz2 = 0x00AA, UPLOAD, },
209 [B2055_C2_RX_BB_REG] = { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, },
210 [B2055_C2_RX_BB_SPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
211 [B2055_C2_RX_TXBBRCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
212 [B2055_C2_TX_RF_SPGA] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
213 [B2055_C2_TX_RF_SPAD] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
214 [B2055_C2_TX_RF_CNTPGA1] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
215 [B2055_C2_TX_RF_CNTPAD1] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, },
216 [B2055_C2_TX_RF_PGAIDAC] = { .ghz5 = 0x0097, .ghz2 = 0x0097, UPLOAD, },
217 [B2055_C2_TX_PGAPADTN] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
218 [B2055_C2_TX_PADIDAC1] = { .ghz5 = 0x0014, .ghz2 = 0x0014, UPLOAD, },
219 [B2055_C2_TX_PADIDAC2] = { .ghz5 = 0x0033, .ghz2 = 0x0033, NOUPLOAD, },
220 [B2055_C2_TX_MXBGTRIM] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
221 [B2055_C2_TX_RF_RCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
222 [B2055_C2_TX_RF_PADTSSI1] = { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, },
223 [B2055_C2_TX_RF_PADTSSI2] = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
224 [B2055_C2_TX_RF_SPARE] = { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, },
225 [B2055_C2_TX_RF_IQCAL1] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
226 [B2055_C2_TX_RF_IQCAL2] = { .ghz5 = 0x00A4, .ghz2 = 0x00A4, NOUPLOAD, },
227 [B2055_C2_TXBB_RCCAL] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
228 [B2055_C2_TXBB_LPF1] = { .ghz5 = 0x0028, .ghz2 = 0x0028, NOUPLOAD, },
229 [B2055_C2_TX_VOSCNCL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
230 [B2055_C2_TX_LPF_MXGMIDAC] = { .ghz5 = 0x004A, .ghz2 = 0x004A, NOUPLOAD, },
231 [B2055_C2_TX_BB_MXGM] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
232 [B2055_PRG_GCHP21] = { .ghz5 = 0x0071, .ghz2 = 0x0071, NOUPLOAD, },
233 [B2055_PRG_GCHP22] = { .ghz5 = 0x0072, .ghz2 = 0x0072, NOUPLOAD, },
234 [B2055_PRG_GCHP23] = { .ghz5 = 0x0073, .ghz2 = 0x0073, NOUPLOAD, },
235 [B2055_PRG_GCHP24] = { .ghz5 = 0x0074, .ghz2 = 0x0074, NOUPLOAD, },
236 [B2055_PRG_GCHP25] = { .ghz5 = 0x0075, .ghz2 = 0x0075, NOUPLOAD, },
237 [B2055_PRG_GCHP26] = { .ghz5 = 0x0076, .ghz2 = 0x0076, NOUPLOAD, },
238 [B2055_PRG_GCHP27] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, },
239 [B2055_PRG_GCHP28] = { .ghz5 = 0x0078, .ghz2 = 0x0078, NOUPLOAD, },
240 [B2055_PRG_GCHP29] = { .ghz5 = 0x0079, .ghz2 = 0x0079, NOUPLOAD, },
241 [B2055_PRG_GCHP30] = { .ghz5 = 0x007A, .ghz2 = 0x007A, NOUPLOAD, },
242 [0xC7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
243 [0xC8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
244 [0xC9] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
245 [0xCA] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
246 [0xCB] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
247 [0xCC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
248 [B2055_C1_LNA_GAINBST] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
249 [0xCE] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
250 [0xCF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
251 [0xD0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
252 [0xD1] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
253 [B2055_C1_B0NB_RSSIVCM] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
254 [0xD3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
255 [0xD4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
256 [0xD5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
257 [B2055_C1_GENSPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
258 [0xD7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
259 [0xD8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
260 [B2055_C2_LNA_GAINBST] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
261 [0xDA] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
262 [0xDB] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
263 [0xDC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
264 [0xDD] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
265 [B2055_C2_B0NB_RSSIVCM] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
266 [0xDF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
267 [0xE0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
268 [0xE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
269 [B2055_C2_GENSPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
270};
271
272
273void b2055_upload_inittab(struct b43_wldev *dev,
274 bool ghz5, bool ignore_uploadflag)
275{
276 const struct b2055_inittab_entry *e;
277 unsigned int i;
278 u16 value;
279
280 for (i = 0; i < ARRAY_SIZE(b2055_inittab); i++) {
281 e = &(b2055_inittab[i]);
282 if (!(e->flags & B2055_INITTAB_ENTRY_OK))
283 continue;
284 if ((e->flags & B2055_INITTAB_UPLOAD) || ignore_uploadflag) {
285 if (ghz5)
286 value = e->ghz5;
287 else
288 value = e->ghz2;
289 b43_radio_write16(dev, i, value);
290 }
291 }
292}
293
294
295#define RADIOREGS(r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, \
296 r12, r13, r14, r15, r16, r17, r18, r19, r20, r21) \
297 .radio_pll_ref = r0, \
298 .radio_rf_pllmod0 = r1, \
299 .radio_rf_pllmod1 = r2, \
300 .radio_vco_captail = r3, \
301 .radio_vco_cal1 = r4, \
302 .radio_vco_cal2 = r5, \
303 .radio_pll_lfc1 = r6, \
304 .radio_pll_lfr1 = r7, \
305 .radio_pll_lfc2 = r8, \
306 .radio_lgbuf_cenbuf = r9, \
307 .radio_lgen_tune1 = r10, \
308 .radio_lgen_tune2 = r11, \
309 .radio_c1_lgbuf_atune = r12, \
310 .radio_c1_lgbuf_gtune = r13, \
311 .radio_c1_rx_rfr1 = r14, \
312 .radio_c1_tx_pgapadtn = r15, \
313 .radio_c1_tx_mxbgtrim = r16, \
314 .radio_c2_lgbuf_atune = r17, \
315 .radio_c2_lgbuf_gtune = r18, \
316 .radio_c2_rx_rfr1 = r19, \
317 .radio_c2_tx_pgapadtn = r20, \
318 .radio_c2_tx_mxbgtrim = r21
319
320#define PHYREGS(r0, r1, r2, r3, r4, r5) \
321 .phy_regs.phy_bw1a = r0, \
322 .phy_regs.phy_bw2 = r1, \
323 .phy_regs.phy_bw3 = r2, \
324 .phy_regs.phy_bw4 = r3, \
325 .phy_regs.phy_bw5 = r4, \
326 .phy_regs.phy_bw6 = r5
327
328static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab[] = {
329 { .channel = 184,
330 .freq = 4920, /* MHz */
331 .unk2 = 3280,
332 RADIOREGS(0x71, 0x01, 0xEC, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
333 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F,
334 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
335 PHYREGS(0xB407, 0xB007, 0xAC07, 0x1402, 0x1502, 0x1602),
336 },
337 { .channel = 186,
338 .freq = 4930, /* MHz */
339 .unk2 = 3287,
340 RADIOREGS(0x71, 0x01, 0xED, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
341 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F,
342 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
343 PHYREGS(0xB807, 0xB407, 0xB007, 0x1302, 0x1402, 0x1502),
344 },
345 { .channel = 188,
346 .freq = 4940, /* MHz */
347 .unk2 = 3293,
348 RADIOREGS(0x71, 0x01, 0xEE, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
349 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
350 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
351 PHYREGS(0xBC07, 0xB807, 0xB407, 0x1202, 0x1302, 0x1402),
352 },
353 { .channel = 190,
354 .freq = 4950, /* MHz */
355 .unk2 = 3300,
356 RADIOREGS(0x71, 0x01, 0xEF, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
357 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
358 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
359 PHYREGS(0xC007, 0xBC07, 0xB807, 0x1102, 0x1202, 0x1302),
360 },
361 { .channel = 192,
362 .freq = 4960, /* MHz */
363 .unk2 = 3307,
364 RADIOREGS(0x71, 0x01, 0xF0, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
365 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
366 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
367 PHYREGS(0xC407, 0xC007, 0xBC07, 0x0F02, 0x1102, 0x1202),
368 },
369 { .channel = 194,
370 .freq = 4970, /* MHz */
371 .unk2 = 3313,
372 RADIOREGS(0x71, 0x01, 0xF1, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
373 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
374 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
375 PHYREGS(0xC807, 0xC407, 0xC007, 0x0E02, 0x0F02, 0x1102),
376 },
377 { .channel = 196,
378 .freq = 4980, /* MHz */
379 .unk2 = 3320,
380 RADIOREGS(0x71, 0x01, 0xF2, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
381 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
382 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
383 PHYREGS(0xCC07, 0xC807, 0xC407, 0x0D02, 0x0E02, 0x0F02),
384 },
385 { .channel = 198,
386 .freq = 4990, /* MHz */
387 .unk2 = 3327,
388 RADIOREGS(0x71, 0x01, 0xF3, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
389 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
390 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
391 PHYREGS(0xD007, 0xCC07, 0xC807, 0x0C02, 0x0D02, 0x0E02),
392 },
393 { .channel = 200,
394 .freq = 5000, /* MHz */
395 .unk2 = 3333,
396 RADIOREGS(0x71, 0x01, 0xF4, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
397 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
398 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
399 PHYREGS(0xD407, 0xD007, 0xCC07, 0x0B02, 0x0C02, 0x0D02),
400 },
401 { .channel = 202,
402 .freq = 5010, /* MHz */
403 .unk2 = 3340,
404 RADIOREGS(0x71, 0x01, 0xF5, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
405 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
406 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
407 PHYREGS(0xD807, 0xD407, 0xD007, 0x0A02, 0x0B02, 0x0C02),
408 },
409 { .channel = 204,
410 .freq = 5020, /* MHz */
411 .unk2 = 3347,
412 RADIOREGS(0x71, 0x01, 0xF6, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
413 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
414 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
415 PHYREGS(0xDC07, 0xD807, 0xD407, 0x0902, 0x0A02, 0x0B02),
416 },
417 { .channel = 206,
418 .freq = 5030, /* MHz */
419 .unk2 = 3353,
420 RADIOREGS(0x71, 0x01, 0xF7, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
421 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
422 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
423 PHYREGS(0xE007, 0xDC07, 0xD807, 0x0802, 0x0902, 0x0A02),
424 },
425 { .channel = 208,
426 .freq = 5040, /* MHz */
427 .unk2 = 3360,
428 RADIOREGS(0x71, 0x01, 0xF8, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
429 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
430 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
431 PHYREGS(0xE407, 0xE007, 0xDC07, 0x0702, 0x0802, 0x0902),
432 },
433 { .channel = 210,
434 .freq = 5050, /* MHz */
435 .unk2 = 3367,
436 RADIOREGS(0x71, 0x01, 0xF9, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
437 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
438 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
439 PHYREGS(0xE807, 0xE407, 0xE007, 0x0602, 0x0702, 0x0802),
440 },
441 { .channel = 212,
442 .freq = 5060, /* MHz */
443 .unk2 = 3373,
444 RADIOREGS(0x71, 0x01, 0xFA, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
445 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F,
446 0x8E, 0xFF, 0x00, 0x0E, 0x0F, 0x8E),
447 PHYREGS(0xEC07, 0xE807, 0xE407, 0x0502, 0x0602, 0x0702),
448 },
449 { .channel = 214,
450 .freq = 5070, /* MHz */
451 .unk2 = 3380,
452 RADIOREGS(0x71, 0x01, 0xFB, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
453 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F,
454 0x8E, 0xFF, 0x00, 0x0E, 0x0F, 0x8E),
455 PHYREGS(0xF007, 0xEC07, 0xE807, 0x0402, 0x0502, 0x0602),
456 },
457 { .channel = 216,
458 .freq = 5080, /* MHz */
459 .unk2 = 3387,
460 RADIOREGS(0x71, 0x01, 0xFC, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
461 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F,
462 0x8D, 0xEE, 0x00, 0x0E, 0x0F, 0x8D),
463 PHYREGS(0xF407, 0xF007, 0xEC07, 0x0302, 0x0402, 0x0502),
464 },
465 { .channel = 218,
466 .freq = 5090, /* MHz */
467 .unk2 = 3393,
468 RADIOREGS(0x71, 0x01, 0xFD, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
469 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F,
470 0x8D, 0xEE, 0x00, 0x0E, 0x0F, 0x8D),
471 PHYREGS(0xF807, 0xF407, 0xF007, 0x0202, 0x0302, 0x0402),
472 },
473 { .channel = 220,
474 .freq = 5100, /* MHz */
475 .unk2 = 3400,
476 RADIOREGS(0x71, 0x01, 0xFE, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
477 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F,
478 0x8D, 0xEE, 0x00, 0x0D, 0x0F, 0x8D),
479 PHYREGS(0xFC07, 0xF807, 0xF407, 0x0102, 0x0202, 0x0302),
480 },
481 { .channel = 222,
482 .freq = 5110, /* MHz */
483 .unk2 = 3407,
484 RADIOREGS(0x71, 0x01, 0xFF, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
485 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F,
486 0x8D, 0xEE, 0x00, 0x0D, 0x0F, 0x8D),
487 PHYREGS(0x0008, 0xFC07, 0xF807, 0x0002, 0x0102, 0x0202),
488 },
489 { .channel = 224,
490 .freq = 5120, /* MHz */
491 .unk2 = 3413,
492 RADIOREGS(0x71, 0x02, 0x00, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
493 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F,
494 0x8C, 0xDD, 0x00, 0x0D, 0x0F, 0x8C),
495 PHYREGS(0x0408, 0x0008, 0xFC07, 0xFF01, 0x0002, 0x0102),
496 },
497 { .channel = 226,
498 .freq = 5130, /* MHz */
499 .unk2 = 3420,
500 RADIOREGS(0x71, 0x02, 0x01, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
501 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F,
502 0x8C, 0xDD, 0x00, 0x0D, 0x0F, 0x8C),
503 PHYREGS(0x0808, 0x0408, 0x0008, 0xFE01, 0xFF01, 0x0002),
504 },
505 { .channel = 228,
506 .freq = 5140, /* MHz */
507 .unk2 = 3427,
508 RADIOREGS(0x71, 0x02, 0x02, 0x0C, 0xC6, 0x01, 0x04, 0x0A,
509 0x00, 0x8D, 0x99, 0x99, 0xDD, 0x00, 0x0C, 0x0E,
510 0x8B, 0xDD, 0x00, 0x0C, 0x0E, 0x8B),
511 PHYREGS(0x0C08, 0x0808, 0x0408, 0xFD01, 0xFE01, 0xFF01),
512 },
513 { .channel = 32,
514 .freq = 5160, /* MHz */
515 .unk2 = 3440,
516 RADIOREGS(0x71, 0x02, 0x04, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
517 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D,
518 0x8A, 0xCC, 0x00, 0x0B, 0x0D, 0x8A),
519 PHYREGS(0x1408, 0x1008, 0x0C08, 0xFB01, 0xFC01, 0xFD01),
520 },
521 { .channel = 34,
522 .freq = 5170, /* MHz */
523 .unk2 = 3447,
524 RADIOREGS(0x71, 0x02, 0x05, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
525 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D,
526 0x8A, 0xCC, 0x00, 0x0B, 0x0D, 0x8A),
527 PHYREGS(0x1808, 0x1408, 0x1008, 0xFA01, 0xFB01, 0xFC01),
528 },
529 { .channel = 36,
530 .freq = 5180, /* MHz */
531 .unk2 = 3453,
532 RADIOREGS(0x71, 0x02, 0x06, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
533 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C,
534 0x89, 0xCC, 0x00, 0x0B, 0x0C, 0x89),
535 PHYREGS(0x1C08, 0x1808, 0x1408, 0xF901, 0xFA01, 0xFB01),
536 },
537 { .channel = 38,
538 .freq = 5190, /* MHz */
539 .unk2 = 3460,
540 RADIOREGS(0x71, 0x02, 0x07, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
541 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C,
542 0x89, 0xCC, 0x00, 0x0B, 0x0C, 0x89),
543 PHYREGS(0x2008, 0x1C08, 0x1808, 0xF801, 0xF901, 0xFA01),
544 },
545 { .channel = 40,
546 .freq = 5200, /* MHz */
547 .unk2 = 3467,
548 RADIOREGS(0x71, 0x02, 0x08, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
549 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B,
550 0x89, 0xBB, 0x00, 0x0A, 0x0B, 0x89),
551 PHYREGS(0x2408, 0x2008, 0x1C08, 0xF701, 0xF801, 0xF901),
552 },
553 { .channel = 42,
554 .freq = 5210, /* MHz */
555 .unk2 = 3473,
556 RADIOREGS(0x71, 0x02, 0x09, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
557 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B,
558 0x89, 0xBB, 0x00, 0x0A, 0x0B, 0x89),
559 PHYREGS(0x2808, 0x2408, 0x2008, 0xF601, 0xF701, 0xF801),
560 },
561 { .channel = 44,
562 .freq = 5220, /* MHz */
563 .unk2 = 3480,
564 RADIOREGS(0x71, 0x02, 0x0A, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
565 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A,
566 0x88, 0xBB, 0x00, 0x09, 0x0A, 0x88),
567 PHYREGS(0x2C08, 0x2808, 0x2408, 0xF501, 0xF601, 0xF701),
568 },
569 { .channel = 46,
570 .freq = 5230, /* MHz */
571 .unk2 = 3487,
572 RADIOREGS(0x71, 0x02, 0x0B, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
573 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A,
574 0x88, 0xBB, 0x00, 0x09, 0x0A, 0x88),
575 PHYREGS(0x3008, 0x2C08, 0x2808, 0xF401, 0xF501, 0xF601),
576 },
577 { .channel = 48,
578 .freq = 5240, /* MHz */
579 .unk2 = 3493,
580 RADIOREGS(0x71, 0x02, 0x0C, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
581 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A,
582 0x87, 0xAA, 0x00, 0x09, 0x0A, 0x87),
583 PHYREGS(0x3408, 0x3008, 0x2C08, 0xF301, 0xF401, 0xF501),
584 },
585 { .channel = 50,
586 .freq = 5250, /* MHz */
587 .unk2 = 3500,
588 RADIOREGS(0x71, 0x02, 0x0D, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
589 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A,
590 0x87, 0xAA, 0x00, 0x09, 0x0A, 0x87),
591 PHYREGS(0x3808, 0x3408, 0x3008, 0xF201, 0xF301, 0xF401),
592 },
593 { .channel = 52,
594 .freq = 5260, /* MHz */
595 .unk2 = 3507,
596 RADIOREGS(0x71, 0x02, 0x0E, 0x0A, 0x98, 0x01, 0x04, 0x0A,
597 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09,
598 0x87, 0xAA, 0x00, 0x08, 0x09, 0x87),
599 PHYREGS(0x3C08, 0x3808, 0x3408, 0xF101, 0xF201, 0xF301),
600 },
601 { .channel = 54,
602 .freq = 5270, /* MHz */
603 .unk2 = 3513,
604 RADIOREGS(0x71, 0x02, 0x0F, 0x0A, 0x98, 0x01, 0x04, 0x0A,
605 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09,
606 0x87, 0xAA, 0x00, 0x08, 0x09, 0x87),
607 PHYREGS(0x4008, 0x3C08, 0x3808, 0xF001, 0xF101, 0xF201),
608 },
609 { .channel = 56,
610 .freq = 5280, /* MHz */
611 .unk2 = 3520,
612 RADIOREGS(0x71, 0x02, 0x10, 0x09, 0x91, 0x01, 0x04, 0x0A,
613 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08,
614 0x86, 0x99, 0x00, 0x08, 0x08, 0x86),
615 PHYREGS(0x4408, 0x4008, 0x3C08, 0xF001, 0xF001, 0xF101),
616 },
617 { .channel = 58,
618 .freq = 5290, /* MHz */
619 .unk2 = 3527,
620 RADIOREGS(0x71, 0x02, 0x11, 0x09, 0x91, 0x01, 0x04, 0x0A,
621 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08,
622 0x86, 0x99, 0x00, 0x08, 0x08, 0x86),
623 PHYREGS(0x4808, 0x4408, 0x4008, 0xEF01, 0xF001, 0xF001),
624 },
625 { .channel = 60,
626 .freq = 5300, /* MHz */
627 .unk2 = 3533,
628 RADIOREGS(0x71, 0x02, 0x12, 0x09, 0x8A, 0x01, 0x04, 0x0A,
629 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07,
630 0x85, 0x99, 0x00, 0x08, 0x07, 0x85),
631 PHYREGS(0x4C08, 0x4808, 0x4408, 0xEE01, 0xEF01, 0xF001),
632 },
633 { .channel = 62,
634 .freq = 5310, /* MHz */
635 .unk2 = 3540,
636 RADIOREGS(0x71, 0x02, 0x13, 0x09, 0x8A, 0x01, 0x04, 0x0A,
637 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07,
638 0x85, 0x99, 0x00, 0x08, 0x07, 0x85),
639 PHYREGS(0x5008, 0x4C08, 0x4808, 0xED01, 0xEE01, 0xEF01),
640 },
641 { .channel = 64,
642 .freq = 5320, /* MHz */
643 .unk2 = 3547,
644 RADIOREGS(0x71, 0x02, 0x14, 0x09, 0x83, 0x01, 0x04, 0x0A,
645 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07,
646 0x84, 0x88, 0x00, 0x07, 0x07, 0x84),
647 PHYREGS(0x5408, 0x5008, 0x4C08, 0xEC01, 0xED01, 0xEE01),
648 },
649 { .channel = 66,
650 .freq = 5330, /* MHz */
651 .unk2 = 3553,
652 RADIOREGS(0x71, 0x02, 0x15, 0x09, 0x83, 0x01, 0x04, 0x0A,
653 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07,
654 0x84, 0x88, 0x00, 0x07, 0x07, 0x84),
655 PHYREGS(0x5808, 0x5408, 0x5008, 0xEB01, 0xEC01, 0xED01),
656 },
657 { .channel = 68,
658 .freq = 5340, /* MHz */
659 .unk2 = 3560,
660 RADIOREGS(0x71, 0x02, 0x16, 0x08, 0x7C, 0x01, 0x04, 0x0A,
661 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06,
662 0x84, 0x88, 0x00, 0x07, 0x06, 0x84),
663 PHYREGS(0x5C08, 0x5808, 0x5408, 0xEA01, 0xEB01, 0xEC01),
664 },
665 { .channel = 70,
666 .freq = 5350, /* MHz */
667 .unk2 = 3567,
668 RADIOREGS(0x71, 0x02, 0x17, 0x08, 0x7C, 0x01, 0x04, 0x0A,
669 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06,
670 0x84, 0x88, 0x00, 0x07, 0x06, 0x84),
671 PHYREGS(0x6008, 0x5C08, 0x5808, 0xE901, 0xEA01, 0xEB01),
672 },
673 { .channel = 72,
674 .freq = 5360, /* MHz */
675 .unk2 = 3573,
676 RADIOREGS(0x71, 0x02, 0x18, 0x08, 0x75, 0x01, 0x04, 0x0A,
677 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05,
678 0x83, 0x77, 0x00, 0x06, 0x05, 0x83),
679 PHYREGS(0x6408, 0x6008, 0x5C08, 0xE801, 0xE901, 0xEA01),
680 },
681 { .channel = 74,
682 .freq = 5370, /* MHz */
683 .unk2 = 3580,
684 RADIOREGS(0x71, 0x02, 0x19, 0x08, 0x75, 0x01, 0x04, 0x0A,
685 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05,
686 0x83, 0x77, 0x00, 0x06, 0x05, 0x83),
687 PHYREGS(0x6808, 0x6408, 0x6008, 0xE701, 0xE801, 0xE901),
688 },
689 { .channel = 76,
690 .freq = 5380, /* MHz */
691 .unk2 = 3587,
692 RADIOREGS(0x71, 0x02, 0x1A, 0x08, 0x6E, 0x01, 0x04, 0x0A,
693 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04,
694 0x82, 0x77, 0x00, 0x06, 0x04, 0x82),
695 PHYREGS(0x6C08, 0x6808, 0x6408, 0xE601, 0xE701, 0xE801),
696 },
697 { .channel = 78,
698 .freq = 5390, /* MHz */
699 .unk2 = 3593,
700 RADIOREGS(0x71, 0x02, 0x1B, 0x08, 0x6E, 0x01, 0x04, 0x0A,
701 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04,
702 0x82, 0x77, 0x00, 0x06, 0x04, 0x82),
703 PHYREGS(0x7008, 0x6C08, 0x6808, 0xE501, 0xE601, 0xE701),
704 },
705 { .channel = 80,
706 .freq = 5400, /* MHz */
707 .unk2 = 3600,
708 RADIOREGS(0x71, 0x02, 0x1C, 0x07, 0x67, 0x01, 0x04, 0x0A,
709 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04,
710 0x81, 0x66, 0x00, 0x05, 0x04, 0x81),
711 PHYREGS(0x7408, 0x7008, 0x6C08, 0xE501, 0xE501, 0xE601),
712 },
713 { .channel = 82,
714 .freq = 5410, /* MHz */
715 .unk2 = 3607,
716 RADIOREGS(0x71, 0x02, 0x1D, 0x07, 0x67, 0x01, 0x04, 0x0A,
717 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04,
718 0x81, 0x66, 0x00, 0x05, 0x04, 0x81),
719 PHYREGS(0x7808, 0x7408, 0x7008, 0xE401, 0xE501, 0xE501),
720 },
721 { .channel = 84,
722 .freq = 5420, /* MHz */
723 .unk2 = 3613,
724 RADIOREGS(0x71, 0x02, 0x1E, 0x07, 0x61, 0x01, 0x04, 0x0A,
725 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03,
726 0x80, 0x66, 0x00, 0x05, 0x03, 0x80),
727 PHYREGS(0x7C08, 0x7808, 0x7408, 0xE301, 0xE401, 0xE501),
728 },
729 { .channel = 86,
730 .freq = 5430, /* MHz */
731 .unk2 = 3620,
732 RADIOREGS(0x71, 0x02, 0x1F, 0x07, 0x61, 0x01, 0x04, 0x0A,
733 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03,
734 0x80, 0x66, 0x00, 0x05, 0x03, 0x80),
735 PHYREGS(0x8008, 0x7C08, 0x7808, 0xE201, 0xE301, 0xE401),
736 },
737 { .channel = 88,
738 .freq = 5440, /* MHz */
739 .unk2 = 3627,
740 RADIOREGS(0x71, 0x02, 0x20, 0x07, 0x5A, 0x01, 0x04, 0x0A,
741 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02,
742 0x80, 0x55, 0x00, 0x04, 0x02, 0x80),
743 PHYREGS(0x8408, 0x8008, 0x7C08, 0xE101, 0xE201, 0xE301),
744 },
745 { .channel = 90,
746 .freq = 5450, /* MHz */
747 .unk2 = 3633,
748 RADIOREGS(0x71, 0x02, 0x21, 0x07, 0x5A, 0x01, 0x04, 0x0A,
749 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02,
750 0x80, 0x55, 0x00, 0x04, 0x02, 0x80),
751 PHYREGS(0x8808, 0x8408, 0x8008, 0xE001, 0xE101, 0xE201),
752 },
753 { .channel = 92,
754 .freq = 5460, /* MHz */
755 .unk2 = 3640,
756 RADIOREGS(0x71, 0x02, 0x22, 0x06, 0x53, 0x01, 0x04, 0x0A,
757 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01,
758 0x80, 0x55, 0x00, 0x04, 0x01, 0x80),
759 PHYREGS(0x8C08, 0x8808, 0x8408, 0xDF01, 0xE001, 0xE101),
760 },
761 { .channel = 94,
762 .freq = 5470, /* MHz */
763 .unk2 = 3647,
764 RADIOREGS(0x71, 0x02, 0x23, 0x06, 0x53, 0x01, 0x04, 0x0A,
765 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01,
766 0x80, 0x55, 0x00, 0x04, 0x01, 0x80),
767 PHYREGS(0x9008, 0x8C08, 0x8808, 0xDE01, 0xDF01, 0xE001),
768 },
769 { .channel = 96,
770 .freq = 5480, /* MHz */
771 .unk2 = 3653,
772 RADIOREGS(0x71, 0x02, 0x24, 0x06, 0x4D, 0x01, 0x04, 0x0A,
773 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00,
774 0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
775 PHYREGS(0x9408, 0x9008, 0x8C08, 0xDD01, 0xDE01, 0xDF01),
776 },
777 { .channel = 98,
778 .freq = 5490, /* MHz */
779 .unk2 = 3660,
780 RADIOREGS(0x71, 0x02, 0x25, 0x06, 0x4D, 0x01, 0x04, 0x0A,
781 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00,
782 0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
783 PHYREGS(0x9808, 0x9408, 0x9008, 0xDD01, 0xDD01, 0xDE01),
784 },
785 { .channel = 100,
786 .freq = 5500, /* MHz */
787 .unk2 = 3667,
788 RADIOREGS(0x71, 0x02, 0x26, 0x06, 0x47, 0x01, 0x04, 0x0A,
789 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00,
790 0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
791 PHYREGS(0x9C08, 0x9808, 0x9408, 0xDC01, 0xDD01, 0xDD01),
792 },
793 { .channel = 102,
794 .freq = 5510, /* MHz */
795 .unk2 = 3673,
796 RADIOREGS(0x71, 0x02, 0x27, 0x06, 0x47, 0x01, 0x04, 0x0A,
797 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00,
798 0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
799 PHYREGS(0xA008, 0x9C08, 0x9808, 0xDB01, 0xDC01, 0xDD01),
800 },
801 { .channel = 104,
802 .freq = 5520, /* MHz */
803 .unk2 = 3680,
804 RADIOREGS(0x71, 0x02, 0x28, 0x05, 0x40, 0x01, 0x04, 0x0A,
805 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
806 0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
807 PHYREGS(0xA408, 0xA008, 0x9C08, 0xDA01, 0xDB01, 0xDC01),
808 },
809 { .channel = 106,
810 .freq = 5530, /* MHz */
811 .unk2 = 3687,
812 RADIOREGS(0x71, 0x02, 0x29, 0x05, 0x40, 0x01, 0x04, 0x0A,
813 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
814 0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
815 PHYREGS(0xA808, 0xA408, 0xA008, 0xD901, 0xDA01, 0xDB01),
816 },
817 { .channel = 108,
818 .freq = 5540, /* MHz */
819 .unk2 = 3693,
820 RADIOREGS(0x71, 0x02, 0x2A, 0x05, 0x3A, 0x01, 0x04, 0x0A,
821 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
822 0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
823 PHYREGS(0xAC08, 0xA808, 0xA408, 0xD801, 0xD901, 0xDA01),
824 },
825 { .channel = 110,
826 .freq = 5550, /* MHz */
827 .unk2 = 3700,
828 RADIOREGS(0x71, 0x02, 0x2B, 0x05, 0x3A, 0x01, 0x04, 0x0A,
829 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
830 0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
831 PHYREGS(0xB008, 0xAC08, 0xA808, 0xD701, 0xD801, 0xD901),
832 },
833 { .channel = 112,
834 .freq = 5560, /* MHz */
835 .unk2 = 3707,
836 RADIOREGS(0x71, 0x02, 0x2C, 0x05, 0x34, 0x01, 0x04, 0x0A,
837 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
838 0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
839 PHYREGS(0xB408, 0xB008, 0xAC08, 0xD701, 0xD701, 0xD801),
840 },
841 { .channel = 114,
842 .freq = 5570, /* MHz */
843 .unk2 = 3713,
844 RADIOREGS(0x71, 0x02, 0x2D, 0x05, 0x34, 0x01, 0x04, 0x0A,
845 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
846 0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
847 PHYREGS(0xB808, 0xB408, 0xB008, 0xD601, 0xD701, 0xD701),
848 },
849 { .channel = 116,
850 .freq = 5580, /* MHz */
851 .unk2 = 3720,
852 RADIOREGS(0x71, 0x02, 0x2E, 0x04, 0x2E, 0x01, 0x04, 0x0A,
853 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
854 0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
855 PHYREGS(0xBC08, 0xB808, 0xB408, 0xD501, 0xD601, 0xD701),
856 },
857 { .channel = 118,
858 .freq = 5590, /* MHz */
859 .unk2 = 3727,
860 RADIOREGS(0x71, 0x02, 0x2F, 0x04, 0x2E, 0x01, 0x04, 0x0A,
861 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
862 0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
863 PHYREGS(0xC008, 0xBC08, 0xB808, 0xD401, 0xD501, 0xD601),
864 },
865 { .channel = 120,
866 .freq = 5600, /* MHz */
867 .unk2 = 3733,
868 RADIOREGS(0x71, 0x02, 0x30, 0x04, 0x28, 0x01, 0x04, 0x0A,
869 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00,
870 0x80, 0x11, 0x00, 0x01, 0x00, 0x80),
871 PHYREGS(0xC408, 0xC008, 0xBC08, 0xD301, 0xD401, 0xD501),
872 },
873 { .channel = 122,
874 .freq = 5610, /* MHz */
875 .unk2 = 3740,
876 RADIOREGS(0x71, 0x02, 0x31, 0x04, 0x28, 0x01, 0x04, 0x0A,
877 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00,
878 0x80, 0x11, 0x00, 0x01, 0x00, 0x80),
879 PHYREGS(0xC808, 0xC408, 0xC008, 0xD201, 0xD301, 0xD401),
880 },
881 { .channel = 124,
882 .freq = 5620, /* MHz */
883 .unk2 = 3747,
884 RADIOREGS(0x71, 0x02, 0x32, 0x04, 0x21, 0x01, 0x04, 0x0A,
885 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
886 0x80, 0x11, 0x00, 0x00, 0x00, 0x80),
887 PHYREGS(0xCC08, 0xC808, 0xC408, 0xD201, 0xD201, 0xD301),
888 },
889 { .channel = 126,
890 .freq = 5630, /* MHz */
891 .unk2 = 3753,
892 RADIOREGS(0x71, 0x02, 0x33, 0x04, 0x21, 0x01, 0x04, 0x0A,
893 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
894 0x80, 0x11, 0x00, 0x00, 0x00, 0x80),
895 PHYREGS(0xD008, 0xCC08, 0xC808, 0xD101, 0xD201, 0xD201),
896 },
897 { .channel = 128,
898 .freq = 5640, /* MHz */
899 .unk2 = 3760,
900 RADIOREGS(0x71, 0x02, 0x34, 0x03, 0x1C, 0x01, 0x04, 0x0A,
901 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
902 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
903 PHYREGS(0xD408, 0xD008, 0xCC08, 0xD001, 0xD101, 0xD201),
904 },
905 { .channel = 130,
906 .freq = 5650, /* MHz */
907 .unk2 = 3767,
908 RADIOREGS(0x71, 0x02, 0x35, 0x03, 0x1C, 0x01, 0x04, 0x0A,
909 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
910 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
911 PHYREGS(0xD808, 0xD408, 0xD008, 0xCF01, 0xD001, 0xD101),
912 },
913 { .channel = 132,
914 .freq = 5660, /* MHz */
915 .unk2 = 3773,
916 RADIOREGS(0x71, 0x02, 0x36, 0x03, 0x16, 0x01, 0x04, 0x0A,
917 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
918 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
919 PHYREGS(0xDC08, 0xD808, 0xD408, 0xCE01, 0xCF01, 0xD001),
920 },
921 { .channel = 134,
922 .freq = 5670, /* MHz */
923 .unk2 = 3780,
924 RADIOREGS(0x71, 0x02, 0x37, 0x03, 0x16, 0x01, 0x04, 0x0A,
925 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
926 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
927 PHYREGS(0xE008, 0xDC08, 0xD808, 0xCE01, 0xCE01, 0xCF01),
928 },
929 { .channel = 136,
930 .freq = 5680, /* MHz */
931 .unk2 = 3787,
932 RADIOREGS(0x71, 0x02, 0x38, 0x03, 0x10, 0x01, 0x04, 0x0A,
933 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
934 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
935 PHYREGS(0xE408, 0xE008, 0xDC08, 0xCD01, 0xCE01, 0xCE01),
936 },
937 { .channel = 138,
938 .freq = 5690, /* MHz */
939 .unk2 = 3793,
940 RADIOREGS(0x71, 0x02, 0x39, 0x03, 0x10, 0x01, 0x04, 0x0A,
941 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
942 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
943 PHYREGS(0xE808, 0xE408, 0xE008, 0xCC01, 0xCD01, 0xCE01),
944 },
945 { .channel = 140,
946 .freq = 5700, /* MHz */
947 .unk2 = 3800,
948 RADIOREGS(0x71, 0x02, 0x3A, 0x02, 0x0A, 0x01, 0x04, 0x0A,
949 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
950 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
951 PHYREGS(0xEC08, 0xE808, 0xE408, 0xCB01, 0xCC01, 0xCD01),
952 },
953 { .channel = 142,
954 .freq = 5710, /* MHz */
955 .unk2 = 3807,
956 RADIOREGS(0x71, 0x02, 0x3B, 0x02, 0x0A, 0x01, 0x04, 0x0A,
957 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
958 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
959 PHYREGS(0xF008, 0xEC08, 0xE808, 0xCA01, 0xCB01, 0xCC01),
960 },
961 { .channel = 144,
962 .freq = 5720, /* MHz */
963 .unk2 = 3813,
964 RADIOREGS(0x71, 0x02, 0x3C, 0x02, 0x0A, 0x01, 0x04, 0x0A,
965 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
966 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
967 PHYREGS(0xF408, 0xF008, 0xEC08, 0xC901, 0xCA01, 0xCB01),
968 },
969 { .channel = 145,
970 .freq = 5725, /* MHz */
971 .unk2 = 3817,
972 RADIOREGS(0x72, 0x04, 0x79, 0x02, 0x03, 0x01, 0x03, 0x14,
973 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
974 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
975 PHYREGS(0xF608, 0xF208, 0xEE08, 0xC901, 0xCA01, 0xCB01),
976 },
977 { .channel = 146,
978 .freq = 5730, /* MHz */
979 .unk2 = 3820,
980 RADIOREGS(0x71, 0x02, 0x3D, 0x02, 0x0A, 0x01, 0x04, 0x0A,
981 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
982 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
983 PHYREGS(0xF808, 0xF408, 0xF008, 0xC901, 0xC901, 0xCA01),
984 },
985 { .channel = 147,
986 .freq = 5735, /* MHz */
987 .unk2 = 3823,
988 RADIOREGS(0x72, 0x04, 0x7B, 0x02, 0x03, 0x01, 0x03, 0x14,
989 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
990 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
991 PHYREGS(0xFA08, 0xF608, 0xF208, 0xC801, 0xC901, 0xCA01),
992 },
993 { .channel = 148,
994 .freq = 5740, /* MHz */
995 .unk2 = 3827,
996 RADIOREGS(0x71, 0x02, 0x3E, 0x02, 0x0A, 0x01, 0x04, 0x0A,
997 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
998 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
999 PHYREGS(0xFC08, 0xF808, 0xF408, 0xC801, 0xC901, 0xC901),
1000 },
1001 { .channel = 149,
1002 .freq = 5745, /* MHz */
1003 .unk2 = 3830,
1004 RADIOREGS(0x72, 0x04, 0x7D, 0x02, 0xFE, 0x00, 0x03, 0x14,
1005 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1006 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1007 PHYREGS(0xFE08, 0xFA08, 0xF608, 0xC801, 0xC801, 0xC901),
1008 },
1009 { .channel = 150,
1010 .freq = 5750, /* MHz */
1011 .unk2 = 3833,
1012 RADIOREGS(0x71, 0x02, 0x3F, 0x02, 0x0A, 0x01, 0x04, 0x0A,
1013 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1014 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1015 PHYREGS(0x0009, 0xFC08, 0xF808, 0xC701, 0xC801, 0xC901),
1016 },
1017 { .channel = 151,
1018 .freq = 5755, /* MHz */
1019 .unk2 = 3837,
1020 RADIOREGS(0x72, 0x04, 0x7F, 0x02, 0xFE, 0x00, 0x03, 0x14,
1021 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1022 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1023 PHYREGS(0x0209, 0xFE08, 0xFA08, 0xC701, 0xC801, 0xC801),
1024 },
1025 { .channel = 152,
1026 .freq = 5760, /* MHz */
1027 .unk2 = 3840,
1028 RADIOREGS(0x71, 0x02, 0x40, 0x02, 0x0A, 0x01, 0x04, 0x0A,
1029 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1030 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1031 PHYREGS(0x0409, 0x0009, 0xFC08, 0xC601, 0xC701, 0xC801),
1032 },
1033 { .channel = 153,
1034 .freq = 5765, /* MHz */
1035 .unk2 = 3843,
1036 RADIOREGS(0x72, 0x04, 0x81, 0x02, 0xF8, 0x00, 0x03, 0x14,
1037 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1038 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1039 PHYREGS(0x0609, 0x0209, 0xFE08, 0xC601, 0xC701, 0xC801),
1040 },
1041 { .channel = 154,
1042 .freq = 5770, /* MHz */
1043 .unk2 = 3847,
1044 RADIOREGS(0x71, 0x02, 0x41, 0x02, 0x0A, 0x01, 0x04, 0x0A,
1045 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1046 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1047 PHYREGS(0x0809, 0x0409, 0x0009, 0xC601, 0xC601, 0xC701),
1048 },
1049 { .channel = 155,
1050 .freq = 5775, /* MHz */
1051 .unk2 = 3850,
1052 RADIOREGS(0x72, 0x04, 0x83, 0x02, 0xF8, 0x00, 0x03, 0x14,
1053 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1054 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1055 PHYREGS(0x0A09, 0x0609, 0x0209, 0xC501, 0xC601, 0xC701),
1056 },
1057 { .channel = 156,
1058 .freq = 5780, /* MHz */
1059 .unk2 = 3853,
1060 RADIOREGS(0x71, 0x02, 0x42, 0x02, 0x0A, 0x01, 0x04, 0x0A,
1061 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1062 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1063 PHYREGS(0x0C09, 0x0809, 0x0409, 0xC501, 0xC601, 0xC601),
1064 },
1065 { .channel = 157,
1066 .freq = 5785, /* MHz */
1067 .unk2 = 3857,
1068 RADIOREGS(0x72, 0x04, 0x85, 0x02, 0xF2, 0x00, 0x03, 0x14,
1069 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1070 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1071 PHYREGS(0x0E09, 0x0A09, 0x0609, 0xC401, 0xC501, 0xC601),
1072 },
1073 { .channel = 158,
1074 .freq = 5790, /* MHz */
1075 .unk2 = 3860,
1076 RADIOREGS(0x71, 0x02, 0x43, 0x02, 0x0A, 0x01, 0x04, 0x0A,
1077 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1078 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1079 PHYREGS(0x1009, 0x0C09, 0x0809, 0xC401, 0xC501, 0xC601),
1080 },
1081 { .channel = 159,
1082 .freq = 5795, /* MHz */
1083 .unk2 = 3863,
1084 RADIOREGS(0x72, 0x04, 0x87, 0x02, 0xF2, 0x00, 0x03, 0x14,
1085 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1086 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1087 PHYREGS(0x1209, 0x0E09, 0x0A09, 0xC401, 0xC401, 0xC501),
1088 },
1089 { .channel = 160,
1090 .freq = 5800, /* MHz */
1091 .unk2 = 3867,
1092 RADIOREGS(0x71, 0x02, 0x44, 0x01, 0x0A, 0x01, 0x04, 0x0A,
1093 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1094 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1095 PHYREGS(0x1409, 0x1009, 0x0C09, 0xC301, 0xC401, 0xC501),
1096 },
1097 { .channel = 161,
1098 .freq = 5805, /* MHz */
1099 .unk2 = 3870,
1100 RADIOREGS(0x72, 0x04, 0x89, 0x01, 0xED, 0x00, 0x03, 0x14,
1101 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1102 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1103 PHYREGS(0x1609, 0x1209, 0x0E09, 0xC301, 0xC401, 0xC401),
1104 },
1105 { .channel = 162,
1106 .freq = 5810, /* MHz */
1107 .unk2 = 3873,
1108 RADIOREGS(0x71, 0x02, 0x45, 0x01, 0x0A, 0x01, 0x04, 0x0A,
1109 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1110 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1111 PHYREGS(0x1809, 0x1409, 0x1009, 0xC201, 0xC301, 0xC401),
1112 },
1113 { .channel = 163,
1114 .freq = 5815, /* MHz */
1115 .unk2 = 3877,
1116 RADIOREGS(0x72, 0x04, 0x8B, 0x01, 0xED, 0x00, 0x03, 0x14,
1117 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1118 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1119 PHYREGS(0x1A09, 0x1609, 0x1209, 0xC201, 0xC301, 0xC401),
1120 },
1121 { .channel = 164,
1122 .freq = 5820, /* MHz */
1123 .unk2 = 3880,
1124 RADIOREGS(0x71, 0x02, 0x46, 0x01, 0x0A, 0x01, 0x04, 0x0A,
1125 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1126 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1127 PHYREGS(0x1C09, 0x1809, 0x1409, 0xC201, 0xC201, 0xC301),
1128 },
1129 { .channel = 165,
1130 .freq = 5825, /* MHz */
1131 .unk2 = 3883,
1132 RADIOREGS(0x72, 0x04, 0x8D, 0x01, 0xED, 0x00, 0x03, 0x14,
1133 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1134 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1135 PHYREGS(0x1E09, 0x1A09, 0x1609, 0xC101, 0xC201, 0xC301),
1136 },
1137 { .channel = 166,
1138 .freq = 5830, /* MHz */
1139 .unk2 = 3887,
1140 RADIOREGS(0x71, 0x02, 0x47, 0x01, 0x0A, 0x01, 0x04, 0x0A,
1141 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1142 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1143 PHYREGS(0x2009, 0x1C09, 0x1809, 0xC101, 0xC201, 0xC201),
1144 },
1145 { .channel = 168,
1146 .freq = 5840, /* MHz */
1147 .unk2 = 3893,
1148 RADIOREGS(0x71, 0x02, 0x48, 0x01, 0x0A, 0x01, 0x04, 0x0A,
1149 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1150 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1151 PHYREGS(0x2409, 0x2009, 0x1C09, 0xC001, 0xC101, 0xC201),
1152 },
1153 { .channel = 170,
1154 .freq = 5850, /* MHz */
1155 .unk2 = 3900,
1156 RADIOREGS(0x71, 0x02, 0x49, 0x01, 0xE0, 0x00, 0x04, 0x0A,
1157 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1158 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1159 PHYREGS(0x2809, 0x2409, 0x2009, 0xBF01, 0xC001, 0xC101),
1160 },
1161 { .channel = 172,
1162 .freq = 5860, /* MHz */
1163 .unk2 = 3907,
1164 RADIOREGS(0x71, 0x02, 0x4A, 0x01, 0xDE, 0x00, 0x04, 0x0A,
1165 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1166 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1167 PHYREGS(0x2C09, 0x2809, 0x2409, 0xBF01, 0xBF01, 0xC001),
1168 },
1169 { .channel = 174,
1170 .freq = 5870, /* MHz */
1171 .unk2 = 3913,
1172 RADIOREGS(0x71, 0x02, 0x4B, 0x00, 0xDB, 0x00, 0x04, 0x0A,
1173 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1174 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1175 PHYREGS(0x3009, 0x2C09, 0x2809, 0xBE01, 0xBF01, 0xBF01),
1176 },
1177 { .channel = 176,
1178 .freq = 5880, /* MHz */
1179 .unk2 = 3920,
1180 RADIOREGS(0x71, 0x02, 0x4C, 0x00, 0xD8, 0x00, 0x04, 0x0A,
1181 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1182 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1183 PHYREGS(0x3409, 0x3009, 0x2C09, 0xBD01, 0xBE01, 0xBF01),
1184 },
1185 { .channel = 178,
1186 .freq = 5890, /* MHz */
1187 .unk2 = 3927,
1188 RADIOREGS(0x71, 0x02, 0x4D, 0x00, 0xD6, 0x00, 0x04, 0x0A,
1189 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1190 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1191 PHYREGS(0x3809, 0x3409, 0x3009, 0xBC01, 0xBD01, 0xBE01),
1192 },
1193 { .channel = 180,
1194 .freq = 5900, /* MHz */
1195 .unk2 = 3933,
1196 RADIOREGS(0x71, 0x02, 0x4E, 0x00, 0xD3, 0x00, 0x04, 0x0A,
1197 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1198 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1199 PHYREGS(0x3C09, 0x3809, 0x3409, 0xBC01, 0xBC01, 0xBD01),
1200 },
1201 { .channel = 182,
1202 .freq = 5910, /* MHz */
1203 .unk2 = 3940,
1204 RADIOREGS(0x71, 0x02, 0x4F, 0x00, 0xD6, 0x00, 0x04, 0x0A,
1205 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1206 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
1207 PHYREGS(0x4009, 0x3C09, 0x3809, 0xBB01, 0xBC01, 0xBC01),
1208 },
1209 { .channel = 1,
1210 .freq = 2412, /* MHz */
1211 .unk2 = 3216,
1212 RADIOREGS(0x73, 0x09, 0x6C, 0x0F, 0x00, 0x01, 0x07, 0x15,
1213 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0D, 0x0C,
1214 0x80, 0xFF, 0x88, 0x0D, 0x0C, 0x80),
1215 PHYREGS(0xC903, 0xC503, 0xC103, 0x3A04, 0x3F04, 0x4304),
1216 },
1217 { .channel = 2,
1218 .freq = 2417, /* MHz */
1219 .unk2 = 3223,
1220 RADIOREGS(0x73, 0x09, 0x71, 0x0F, 0x00, 0x01, 0x07, 0x15,
1221 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0B,
1222 0x80, 0xFF, 0x88, 0x0C, 0x0B, 0x80),
1223 PHYREGS(0xCB03, 0xC703, 0xC303, 0x3804, 0x3D04, 0x4104),
1224 },
1225 { .channel = 3,
1226 .freq = 2422, /* MHz */
1227 .unk2 = 3229,
1228 RADIOREGS(0x73, 0x09, 0x76, 0x0F, 0x00, 0x01, 0x07, 0x15,
1229 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A,
1230 0x80, 0xFF, 0x88, 0x0C, 0x0A, 0x80),
1231 PHYREGS(0xCD03, 0xC903, 0xC503, 0x3604, 0x3A04, 0x3F04),
1232 },
1233 { .channel = 4,
1234 .freq = 2427, /* MHz */
1235 .unk2 = 3236,
1236 RADIOREGS(0x73, 0x09, 0x7B, 0x0F, 0x00, 0x01, 0x07, 0x15,
1237 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A,
1238 0x80, 0xFF, 0x88, 0x0C, 0x0A, 0x80),
1239 PHYREGS(0xCF03, 0xCB03, 0xC703, 0x3404, 0x3804, 0x3D04),
1240 },
1241 { .channel = 5,
1242 .freq = 2432, /* MHz */
1243 .unk2 = 3243,
1244 RADIOREGS(0x73, 0x09, 0x80, 0x0F, 0x00, 0x01, 0x07, 0x15,
1245 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x09,
1246 0x80, 0xFF, 0x88, 0x0C, 0x09, 0x80),
1247 PHYREGS(0xD103, 0xCD03, 0xC903, 0x3104, 0x3604, 0x3A04),
1248 },
1249 { .channel = 6,
1250 .freq = 2437, /* MHz */
1251 .unk2 = 3249,
1252 RADIOREGS(0x73, 0x09, 0x85, 0x0F, 0x00, 0x01, 0x07, 0x15,
1253 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0B, 0x08,
1254 0x80, 0xFF, 0x88, 0x0B, 0x08, 0x80),
1255 PHYREGS(0xD303, 0xCF03, 0xCB03, 0x2F04, 0x3404, 0x3804),
1256 },
1257 { .channel = 7,
1258 .freq = 2442, /* MHz */
1259 .unk2 = 3256,
1260 RADIOREGS(0x73, 0x09, 0x8A, 0x0F, 0x00, 0x01, 0x07, 0x15,
1261 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x07,
1262 0x80, 0xFF, 0x88, 0x0A, 0x07, 0x80),
1263 PHYREGS(0xD503, 0xD103, 0xCD03, 0x2D04, 0x3104, 0x3604),
1264 },
1265 { .channel = 8,
1266 .freq = 2447, /* MHz */
1267 .unk2 = 3263,
1268 RADIOREGS(0x73, 0x09, 0x8F, 0x0F, 0x00, 0x01, 0x07, 0x15,
1269 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x06,
1270 0x80, 0xFF, 0x88, 0x0A, 0x06, 0x80),
1271 PHYREGS(0xD703, 0xD303, 0xCF03, 0x2B04, 0x2F04, 0x3404),
1272 },
1273 { .channel = 9,
1274 .freq = 2452, /* MHz */
1275 .unk2 = 3269,
1276 RADIOREGS(0x73, 0x09, 0x94, 0x0F, 0x00, 0x01, 0x07, 0x15,
1277 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x09, 0x06,
1278 0x80, 0xFF, 0x88, 0x09, 0x06, 0x80),
1279 PHYREGS(0xD903, 0xD503, 0xD103, 0x2904, 0x2D04, 0x3104),
1280 },
1281 { .channel = 10,
1282 .freq = 2457, /* MHz */
1283 .unk2 = 3276,
1284 RADIOREGS(0x73, 0x09, 0x99, 0x0F, 0x00, 0x01, 0x07, 0x15,
1285 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x05,
1286 0x80, 0xFF, 0x88, 0x08, 0x05, 0x80),
1287 PHYREGS(0xDB03, 0xD703, 0xD303, 0x2704, 0x2B04, 0x2F04),
1288 },
1289 { .channel = 11,
1290 .freq = 2462, /* MHz */
1291 .unk2 = 3283,
1292 RADIOREGS(0x73, 0x09, 0x9E, 0x0F, 0x00, 0x01, 0x07, 0x15,
1293 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x04,
1294 0x80, 0xFF, 0x88, 0x08, 0x04, 0x80),
1295 PHYREGS(0xDD03, 0xD903, 0xD503, 0x2404, 0x2904, 0x2D04),
1296 },
1297 { .channel = 12,
1298 .freq = 2467, /* MHz */
1299 .unk2 = 3289,
1300 RADIOREGS(0x73, 0x09, 0xA3, 0x0F, 0x00, 0x01, 0x07, 0x15,
1301 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x03,
1302 0x80, 0xFF, 0x88, 0x08, 0x03, 0x80),
1303 PHYREGS(0xDF03, 0xDB03, 0xD703, 0x2204, 0x2704, 0x2B04),
1304 },
1305 { .channel = 13,
1306 .freq = 2472, /* MHz */
1307 .unk2 = 3296,
1308 RADIOREGS(0x73, 0x09, 0xA8, 0x0F, 0x00, 0x01, 0x07, 0x15,
1309 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x03,
1310 0x80, 0xFF, 0x88, 0x07, 0x03, 0x80),
1311 PHYREGS(0xE103, 0xDD03, 0xD903, 0x2004, 0x2404, 0x2904),
1312 },
1313 { .channel = 14,
1314 .freq = 2484, /* MHz */
1315 .unk2 = 3312,
1316 RADIOREGS(0x73, 0x09, 0xB4, 0x0F, 0xFF, 0x01, 0x07, 0x15,
1317 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x01,
1318 0x80, 0xFF, 0x88, 0x07, 0x01, 0x80),
1319 PHYREGS(0xE603, 0xE203, 0xDE03, 0x1B04, 0x1F04, 0x2404),
1320 },
1321};
1322
1323const struct b43_nphy_channeltab_entry_rev2 *
1324b43_nphy_get_chantabent_rev2(struct b43_wldev *dev, u8 channel)
1325{
1326 const struct b43_nphy_channeltab_entry_rev2 *e;
1327 unsigned int i;
1328
1329 for (i = 0; i < ARRAY_SIZE(b43_nphy_channeltab); i++) {
1330 e = &(b43_nphy_channeltab[i]);
1331 if (e->channel == channel)
1332 return e;
1333 }
1334
1335 return NULL;
1336}
1337
1338
1339static const u8 b43_ntab_adjustpower0[] = { 30static const u8 b43_ntab_adjustpower0[] = {
1340 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 31 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
1341 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 32 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03,
diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h
index 8fc1da9f8fe5..4ec593ba3eef 100644
--- a/drivers/net/wireless/b43/tables_nphy.h
+++ b/drivers/net/wireless/b43/tables_nphy.h
@@ -3,7 +3,6 @@
3 3
4#include <linux/types.h> 4#include <linux/types.h>
5 5
6
7struct b43_phy_n_sfo_cfg { 6struct b43_phy_n_sfo_cfg {
8 u16 phy_bw1a; 7 u16 phy_bw1a;
9 u16 phy_bw2; 8 u16 phy_bw2;
@@ -13,52 +12,6 @@ struct b43_phy_n_sfo_cfg {
13 u16 phy_bw6; 12 u16 phy_bw6;
14}; 13};
15 14
16struct b43_nphy_channeltab_entry_rev2 {
17 /* The channel number */
18 u8 channel;
19 /* The channel frequency in MHz */
20 u16 freq;
21 /* An unknown value */
22 u16 unk2;
23 /* Radio register values on channelswitch */
24 u8 radio_pll_ref;
25 u8 radio_rf_pllmod0;
26 u8 radio_rf_pllmod1;
27 u8 radio_vco_captail;
28 u8 radio_vco_cal1;
29 u8 radio_vco_cal2;
30 u8 radio_pll_lfc1;
31 u8 radio_pll_lfr1;
32 u8 radio_pll_lfc2;
33 u8 radio_lgbuf_cenbuf;
34 u8 radio_lgen_tune1;
35 u8 radio_lgen_tune2;
36 u8 radio_c1_lgbuf_atune;
37 u8 radio_c1_lgbuf_gtune;
38 u8 radio_c1_rx_rfr1;
39 u8 radio_c1_tx_pgapadtn;
40 u8 radio_c1_tx_mxbgtrim;
41 u8 radio_c2_lgbuf_atune;
42 u8 radio_c2_lgbuf_gtune;
43 u8 radio_c2_rx_rfr1;
44 u8 radio_c2_tx_pgapadtn;
45 u8 radio_c2_tx_mxbgtrim;
46 /* PHY register values on channelswitch */
47 struct b43_phy_n_sfo_cfg phy_regs;
48};
49
50struct b43_nphy_channeltab_entry_rev3 {
51 /* The channel number */
52 u8 channel;
53 /* The channel frequency in MHz */
54 u16 freq;
55 /* Radio register values on channelswitch */
56 /* TODO */
57 /* PHY register values on channelswitch */
58 struct b43_phy_n_sfo_cfg phy_regs;
59};
60
61
62struct b43_wldev; 15struct b43_wldev;
63 16
64struct nphy_txiqcal_ladder { 17struct nphy_txiqcal_ladder {
@@ -82,18 +35,12 @@ struct nphy_rf_control_override_rev3 {
82 u8 val_addr1; 35 u8 val_addr1;
83}; 36};
84 37
85/* Upload the default register value table. 38/* Get the NPHY Channel Switch Table entry for a channel.
86 * If "ghz5" is true, we upload the 5Ghz table. Otherwise the 2.4Ghz
87 * table is uploaded. If "ignore_uploadflag" is true, we upload any value
88 * and ignore the "UPLOAD" flag. */
89void b2055_upload_inittab(struct b43_wldev *dev,
90 bool ghz5, bool ignore_uploadflag);
91
92
93/* Get the NPHY Channel Switch Table entry for a channel number.
94 * Returns NULL on failure to find an entry. */ 39 * Returns NULL on failure to find an entry. */
95const struct b43_nphy_channeltab_entry_rev2 * 40const struct b43_nphy_channeltab_entry_rev2 *
96b43_nphy_get_chantabent_rev2(struct b43_wldev *dev, u8 channel); 41b43_nphy_get_chantabent_rev2(struct b43_wldev *dev, u8 channel);
42const struct b43_nphy_channeltab_entry_rev3 *
43b43_nphy_get_chantabent_rev3(struct b43_wldev *dev, u16 freq);
97 44
98 45
99/* The N-PHY tables. */ 46/* The N-PHY tables. */
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index 493163925a45..63edbe2e557f 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -12,7 +12,7 @@ obj-$(CONFIG_IWLAGN) += iwlagn.o
12iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o iwl-agn-ict.o 12iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o iwl-agn-ict.o
13iwlagn-objs += iwl-agn-ucode.o iwl-agn-hcmd.o iwl-agn-tx.o 13iwlagn-objs += iwl-agn-ucode.o iwl-agn-hcmd.o iwl-agn-tx.o
14iwlagn-objs += iwl-agn-lib.o iwl-agn-rx.o iwl-agn-calib.o 14iwlagn-objs += iwl-agn-lib.o iwl-agn-rx.o iwl-agn-calib.o
15iwlagn-objs += iwl-agn-tt.o 15iwlagn-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-eeprom.o
16iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-agn-debugfs.o 16iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-agn-debugfs.o
17 17
18iwlagn-$(CONFIG_IWL4965) += iwl-4965.o 18iwlagn-$(CONFIG_IWL4965) += iwl-4965.o
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 134f54541330..db540910b110 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -151,8 +151,7 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
151 priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant; 151 priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
152 priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant; 152 priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
153 153
154 if (priv->cfg->ops->lib->temp_ops.set_ct_kill) 154 iwl1000_set_ct_threshold(priv);
155 priv->cfg->ops->lib->temp_ops.set_ct_kill(priv);
156 155
157 /* Set initial sensitivity parameters */ 156 /* Set initial sensitivity parameters */
158 /* Set initial calibration set */ 157 /* Set initial calibration set */
@@ -195,9 +194,7 @@ static struct iwl_lib_ops iwl1000_lib = {
195 .update_chain_flags = iwl_update_chain_flags, 194 .update_chain_flags = iwl_update_chain_flags,
196 .apm_ops = { 195 .apm_ops = {
197 .init = iwl_apm_init, 196 .init = iwl_apm_init,
198 .stop = iwl_apm_stop,
199 .config = iwl1000_nic_config, 197 .config = iwl1000_nic_config,
200 .set_pwr_src = iwl_set_pwr_src,
201 }, 198 },
202 .eeprom_ops = { 199 .eeprom_ops = {
203 .regulatory_bands = { 200 .regulatory_bands = {
@@ -209,7 +206,6 @@ static struct iwl_lib_ops iwl1000_lib = {
209 EEPROM_REG_BAND_24_HT40_CHANNELS, 206 EEPROM_REG_BAND_24_HT40_CHANNELS,
210 EEPROM_REG_BAND_52_HT40_CHANNELS 207 EEPROM_REG_BAND_52_HT40_CHANNELS
211 }, 208 },
212 .verify_signature = iwlcore_eeprom_verify_signature,
213 .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, 209 .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
214 .release_semaphore = iwlcore_eeprom_release_semaphore, 210 .release_semaphore = iwlcore_eeprom_release_semaphore,
215 .calib_version = iwlagn_eeprom_calib_version, 211 .calib_version = iwlagn_eeprom_calib_version,
@@ -220,7 +216,6 @@ static struct iwl_lib_ops iwl1000_lib = {
220 .config_ap = iwl_config_ap, 216 .config_ap = iwl_config_ap,
221 .temp_ops = { 217 .temp_ops = {
222 .temperature = iwlagn_temperature, 218 .temperature = iwlagn_temperature,
223 .set_ct_kill = iwl1000_set_ct_threshold,
224 }, 219 },
225 .manage_ibss_station = iwlagn_manage_ibss_station, 220 .manage_ibss_station = iwlagn_manage_ibss_station,
226 .update_bcast_stations = iwl_update_bcast_stations, 221 .update_bcast_stations = iwl_update_bcast_stations,
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index cfdff5487e3c..176e52577673 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -87,6 +87,15 @@ const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT_3945] = {
87 IWL_DECLARE_RATE_INFO(54, 48, INV, 48, INV, 48, INV),/* 54mbps */ 87 IWL_DECLARE_RATE_INFO(54, 48, INV, 48, INV, 48, INV),/* 54mbps */
88}; 88};
89 89
90static inline u8 iwl3945_get_prev_ieee_rate(u8 rate_index)
91{
92 u8 rate = iwl3945_rates[rate_index].prev_ieee;
93
94 if (rate == IWL_RATE_INVALID)
95 rate = rate_index;
96 return rate;
97}
98
90/* 1 = enable the iwl3945_disable_events() function */ 99/* 1 = enable the iwl3945_disable_events() function */
91#define IWL_EVT_DISABLE (0) 100#define IWL_EVT_DISABLE (0)
92#define IWL_EVT_DISABLE_SIZE (1532/32) 101#define IWL_EVT_DISABLE_SIZE (1532/32)
@@ -339,7 +348,7 @@ static void iwl3945_rx_reply_tx(struct iwl_priv *priv,
339 IWL_DEBUG_TX_REPLY(priv, "Tx queue reclaim %d\n", index); 348 IWL_DEBUG_TX_REPLY(priv, "Tx queue reclaim %d\n", index);
340 iwl3945_tx_queue_reclaim(priv, txq_id, index); 349 iwl3945_tx_queue_reclaim(priv, txq_id, index);
341 350
342 if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) 351 if (status & TX_ABORT_REQUIRED_MSK)
343 IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n"); 352 IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n");
344} 353}
345 354
@@ -807,9 +816,12 @@ static u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate)
807 return sta_id; 816 return sta_id;
808} 817}
809 818
810static int iwl3945_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src) 819static void iwl3945_set_pwr_vmain(struct iwl_priv *priv)
811{ 820{
812 if (src == IWL_PWR_SRC_VAUX) { 821/*
822 * (for documentation purposes)
823 * to set power to V_AUX, do
824
813 if (pci_pme_capable(priv->pci_dev, PCI_D3cold)) { 825 if (pci_pme_capable(priv->pci_dev, PCI_D3cold)) {
814 iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG, 826 iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
815 APMG_PS_CTRL_VAL_PWR_SRC_VAUX, 827 APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
@@ -819,16 +831,14 @@ static int iwl3945_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
819 CSR_GPIO_IN_VAL_VAUX_PWR_SRC, 831 CSR_GPIO_IN_VAL_VAUX_PWR_SRC,
820 CSR_GPIO_IN_BIT_AUX_POWER, 5000); 832 CSR_GPIO_IN_BIT_AUX_POWER, 5000);
821 } 833 }
822 } else { 834 */
823 iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
824 APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
825 ~APMG_PS_CTRL_MSK_PWR_SRC);
826 835
827 iwl_poll_bit(priv, CSR_GPIO_IN, CSR_GPIO_IN_VAL_VMAIN_PWR_SRC, 836 iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
828 CSR_GPIO_IN_BIT_AUX_POWER, 5000); /* uS */ 837 APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
829 } 838 ~APMG_PS_CTRL_MSK_PWR_SRC);
830 839
831 return 0; 840 iwl_poll_bit(priv, CSR_GPIO_IN, CSR_GPIO_IN_VAL_VMAIN_PWR_SRC,
841 CSR_GPIO_IN_BIT_AUX_POWER, 5000); /* uS */
832} 842}
833 843
834static int iwl3945_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq) 844static int iwl3945_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
@@ -1022,9 +1032,7 @@ int iwl3945_hw_nic_init(struct iwl_priv *priv)
1022 priv->cfg->ops->lib->apm_ops.init(priv); 1032 priv->cfg->ops->lib->apm_ops.init(priv);
1023 spin_unlock_irqrestore(&priv->lock, flags); 1033 spin_unlock_irqrestore(&priv->lock, flags);
1024 1034
1025 rc = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN); 1035 iwl3945_set_pwr_vmain(priv);
1026 if (rc)
1027 return rc;
1028 1036
1029 priv->cfg->ops->lib->apm_ops.config(priv); 1037 priv->cfg->ops->lib->apm_ops.config(priv);
1030 1038
@@ -1763,8 +1771,7 @@ static int iwl3945_send_rxon_assoc(struct iwl_priv *priv,
1763 * function correctly transitions out of the RXON_ASSOC_MSK state if 1771 * function correctly transitions out of the RXON_ASSOC_MSK state if
1764 * a HW tune is required based on the RXON structure changes. 1772 * a HW tune is required based on the RXON structure changes.
1765 */ 1773 */
1766static int iwl3945_commit_rxon(struct iwl_priv *priv, 1774int iwl3945_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
1767 struct iwl_rxon_context *ctx)
1768{ 1775{
1769 /* cast away the const for active_rxon in this function */ 1776 /* cast away the const for active_rxon in this function */
1770 struct iwl3945_rxon_cmd *active_rxon = (void *)&ctx->active; 1777 struct iwl3945_rxon_cmd *active_rxon = (void *)&ctx->active;
@@ -2300,6 +2307,32 @@ static u16 iwl3945_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
2300 return (u16)sizeof(struct iwl3945_addsta_cmd); 2307 return (u16)sizeof(struct iwl3945_addsta_cmd);
2301} 2308}
2302 2309
2310static int iwl3945_add_bssid_station(struct iwl_priv *priv,
2311 const u8 *addr, u8 *sta_id_r)
2312{
2313 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
2314 int ret;
2315 u8 sta_id;
2316 unsigned long flags;
2317
2318 if (sta_id_r)
2319 *sta_id_r = IWL_INVALID_STATION;
2320
2321 ret = iwl_add_station_common(priv, ctx, addr, 0, NULL, &sta_id);
2322 if (ret) {
2323 IWL_ERR(priv, "Unable to add station %pM\n", addr);
2324 return ret;
2325 }
2326
2327 if (sta_id_r)
2328 *sta_id_r = sta_id;
2329
2330 spin_lock_irqsave(&priv->sta_lock, flags);
2331 priv->stations[sta_id].used |= IWL_STA_LOCAL;
2332 spin_unlock_irqrestore(&priv->sta_lock, flags);
2333
2334 return 0;
2335}
2303static int iwl3945_manage_ibss_station(struct iwl_priv *priv, 2336static int iwl3945_manage_ibss_station(struct iwl_priv *priv,
2304 struct ieee80211_vif *vif, bool add) 2337 struct ieee80211_vif *vif, bool add)
2305{ 2338{
@@ -2307,10 +2340,8 @@ static int iwl3945_manage_ibss_station(struct iwl_priv *priv,
2307 int ret; 2340 int ret;
2308 2341
2309 if (add) { 2342 if (add) {
2310 ret = iwl_add_bssid_station( 2343 ret = iwl3945_add_bssid_station(priv, vif->bss_conf.bssid,
2311 priv, &priv->contexts[IWL_RXON_CTX_BSS], 2344 &vif_priv->ibss_bssid_sta_id);
2312 vif->bss_conf.bssid, false,
2313 &vif_priv->ibss_bssid_sta_id);
2314 if (ret) 2345 if (ret)
2315 return ret; 2346 return ret;
2316 2347
@@ -2673,9 +2704,7 @@ static struct iwl_lib_ops iwl3945_lib = {
2673 .dump_nic_error_log = iwl3945_dump_nic_error_log, 2704 .dump_nic_error_log = iwl3945_dump_nic_error_log,
2674 .apm_ops = { 2705 .apm_ops = {
2675 .init = iwl3945_apm_init, 2706 .init = iwl3945_apm_init,
2676 .stop = iwl_apm_stop,
2677 .config = iwl3945_nic_config, 2707 .config = iwl3945_nic_config,
2678 .set_pwr_src = iwl3945_set_pwr_src,
2679 }, 2708 },
2680 .eeprom_ops = { 2709 .eeprom_ops = {
2681 .regulatory_bands = { 2710 .regulatory_bands = {
@@ -2687,7 +2716,6 @@ static struct iwl_lib_ops iwl3945_lib = {
2687 EEPROM_REGULATORY_BAND_NO_HT40, 2716 EEPROM_REGULATORY_BAND_NO_HT40,
2688 EEPROM_REGULATORY_BAND_NO_HT40, 2717 EEPROM_REGULATORY_BAND_NO_HT40,
2689 }, 2718 },
2690 .verify_signature = iwlcore_eeprom_verify_signature,
2691 .acquire_semaphore = iwl3945_eeprom_acquire_semaphore, 2719 .acquire_semaphore = iwl3945_eeprom_acquire_semaphore,
2692 .release_semaphore = iwl3945_eeprom_release_semaphore, 2720 .release_semaphore = iwl3945_eeprom_release_semaphore,
2693 .query_addr = iwlcore_eeprom_query_addr, 2721 .query_addr = iwlcore_eeprom_query_addr,
@@ -2713,6 +2741,7 @@ static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
2713 .build_addsta_hcmd = iwl3945_build_addsta_hcmd, 2741 .build_addsta_hcmd = iwl3945_build_addsta_hcmd,
2714 .tx_cmd_protection = iwlcore_tx_cmd_protection, 2742 .tx_cmd_protection = iwlcore_tx_cmd_protection,
2715 .request_scan = iwl3945_request_scan, 2743 .request_scan = iwl3945_request_scan,
2744 .post_scan = iwl3945_post_scan,
2716}; 2745};
2717 2746
2718static const struct iwl_ops iwl3945_ops = { 2747static const struct iwl_ops iwl3945_ops = {
@@ -2724,6 +2753,7 @@ static const struct iwl_ops iwl3945_ops = {
2724 2753
2725static struct iwl_base_params iwl3945_base_params = { 2754static struct iwl_base_params iwl3945_base_params = {
2726 .eeprom_size = IWL3945_EEPROM_IMG_SIZE, 2755 .eeprom_size = IWL3945_EEPROM_IMG_SIZE,
2756 .num_of_queues = IWL39_NUM_QUEUES,
2727 .pll_cfg_val = CSR39_ANA_PLL_CFG_VAL, 2757 .pll_cfg_val = CSR39_ANA_PLL_CFG_VAL,
2728 .set_l0s = false, 2758 .set_l0s = false,
2729 .use_bsm = true, 2759 .use_bsm = true,
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index 98509c5e708d..09391f0ee61f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -138,8 +138,6 @@ enum iwl3945_antenna {
138#define DEFAULT_SHORT_RETRY_LIMIT 7U 138#define DEFAULT_SHORT_RETRY_LIMIT 7U
139#define DEFAULT_LONG_RETRY_LIMIT 4U 139#define DEFAULT_LONG_RETRY_LIMIT 4U
140 140
141#include "iwl-agn-rs.h"
142
143#define IWL_TX_FIFO_AC0 0 141#define IWL_TX_FIFO_AC0 0
144#define IWL_TX_FIFO_AC1 1 142#define IWL_TX_FIFO_AC1 1
145#define IWL_TX_FIFO_AC2 2 143#define IWL_TX_FIFO_AC2 2
@@ -271,6 +269,9 @@ extern void iwl3945_post_associate(struct iwl_priv *priv,
271extern void iwl3945_config_ap(struct iwl_priv *priv, 269extern void iwl3945_config_ap(struct iwl_priv *priv,
272 struct ieee80211_vif *vif); 270 struct ieee80211_vif *vif);
273 271
272extern int iwl3945_commit_rxon(struct iwl_priv *priv,
273 struct iwl_rxon_context *ctx);
274
274/** 275/**
275 * iwl3945_hw_find_station - Find station id for a given BSSID 276 * iwl3945_hw_find_station - Find station id for a given BSSID
276 * @bssid: MAC address of station ID to find 277 * @bssid: MAC address of station ID to find
@@ -296,6 +297,10 @@ extern int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate);
296 297
297/* scanning */ 298/* scanning */
298int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif); 299int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif);
300void iwl3945_post_scan(struct iwl_priv *priv);
301
302/* rates */
303extern const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT_3945];
299 304
300/* Requires full declaration of iwl_priv before including */ 305/* Requires full declaration of iwl_priv before including */
301#include "iwl-io.h" 306#include "iwl-io.h"
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 834c2f9c15d7..b207e3e9299f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -43,7 +43,7 @@
43#include "iwl-core.h" 43#include "iwl-core.h"
44#include "iwl-io.h" 44#include "iwl-io.h"
45#include "iwl-helpers.h" 45#include "iwl-helpers.h"
46#include "iwl-calib.h" 46#include "iwl-agn-calib.h"
47#include "iwl-sta.h" 47#include "iwl-sta.h"
48#include "iwl-agn-led.h" 48#include "iwl-agn-led.h"
49#include "iwl-agn.h" 49#include "iwl-agn.h"
@@ -669,8 +669,8 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
669 priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant); 669 priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant);
670 priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant; 670 priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
671 priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant; 671 priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
672 if (priv->cfg->ops->lib->temp_ops.set_ct_kill) 672
673 priv->cfg->ops->lib->temp_ops.set_ct_kill(priv); 673 iwl4965_set_ct_threshold(priv);
674 674
675 priv->hw_params.sens = &iwl4965_sensitivity; 675 priv->hw_params.sens = &iwl4965_sensitivity;
676 priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS; 676 priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS;
@@ -2216,11 +2216,23 @@ static void iwl4965_cancel_deferred_work(struct iwl_priv *priv)
2216 2216
2217static struct iwl_hcmd_ops iwl4965_hcmd = { 2217static struct iwl_hcmd_ops iwl4965_hcmd = {
2218 .rxon_assoc = iwl4965_send_rxon_assoc, 2218 .rxon_assoc = iwl4965_send_rxon_assoc,
2219 .commit_rxon = iwl_commit_rxon, 2219 .commit_rxon = iwlagn_commit_rxon,
2220 .set_rxon_chain = iwl_set_rxon_chain, 2220 .set_rxon_chain = iwlagn_set_rxon_chain,
2221 .send_bt_config = iwl_send_bt_config, 2221 .send_bt_config = iwl_send_bt_config,
2222}; 2222};
2223 2223
2224static void iwl4965_post_scan(struct iwl_priv *priv)
2225{
2226 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
2227
2228 /*
2229 * Since setting the RXON may have been deferred while
2230 * performing the scan, fire one off if needed
2231 */
2232 if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))
2233 iwlcore_commit_rxon(priv, ctx);
2234}
2235
2224static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = { 2236static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
2225 .get_hcmd_size = iwl4965_get_hcmd_size, 2237 .get_hcmd_size = iwl4965_get_hcmd_size,
2226 .build_addsta_hcmd = iwl4965_build_addsta_hcmd, 2238 .build_addsta_hcmd = iwl4965_build_addsta_hcmd,
@@ -2229,6 +2241,7 @@ static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
2229 .tx_cmd_protection = iwlcore_tx_cmd_protection, 2241 .tx_cmd_protection = iwlcore_tx_cmd_protection,
2230 .calc_rssi = iwl4965_calc_rssi, 2242 .calc_rssi = iwl4965_calc_rssi,
2231 .request_scan = iwlagn_request_scan, 2243 .request_scan = iwlagn_request_scan,
2244 .post_scan = iwl4965_post_scan,
2232}; 2245};
2233 2246
2234static struct iwl_lib_ops iwl4965_lib = { 2247static struct iwl_lib_ops iwl4965_lib = {
@@ -2253,9 +2266,7 @@ static struct iwl_lib_ops iwl4965_lib = {
2253 .set_channel_switch = iwl4965_hw_channel_switch, 2266 .set_channel_switch = iwl4965_hw_channel_switch,
2254 .apm_ops = { 2267 .apm_ops = {
2255 .init = iwl_apm_init, 2268 .init = iwl_apm_init,
2256 .stop = iwl_apm_stop,
2257 .config = iwl4965_nic_config, 2269 .config = iwl4965_nic_config,
2258 .set_pwr_src = iwl_set_pwr_src,
2259 }, 2270 },
2260 .eeprom_ops = { 2271 .eeprom_ops = {
2261 .regulatory_bands = { 2272 .regulatory_bands = {
@@ -2267,7 +2278,6 @@ static struct iwl_lib_ops iwl4965_lib = {
2267 EEPROM_4965_REGULATORY_BAND_24_HT40_CHANNELS, 2278 EEPROM_4965_REGULATORY_BAND_24_HT40_CHANNELS,
2268 EEPROM_4965_REGULATORY_BAND_52_HT40_CHANNELS 2279 EEPROM_4965_REGULATORY_BAND_52_HT40_CHANNELS
2269 }, 2280 },
2270 .verify_signature = iwlcore_eeprom_verify_signature,
2271 .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, 2281 .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
2272 .release_semaphore = iwlcore_eeprom_release_semaphore, 2282 .release_semaphore = iwlcore_eeprom_release_semaphore,
2273 .calib_version = iwl4965_eeprom_calib_version, 2283 .calib_version = iwl4965_eeprom_calib_version,
@@ -2280,7 +2290,6 @@ static struct iwl_lib_ops iwl4965_lib = {
2280 .isr = iwl_isr_legacy, 2290 .isr = iwl_isr_legacy,
2281 .temp_ops = { 2291 .temp_ops = {
2282 .temperature = iwl4965_temperature_calib, 2292 .temperature = iwl4965_temperature_calib,
2283 .set_ct_kill = iwl4965_set_ct_threshold,
2284 }, 2293 },
2285 .manage_ibss_station = iwlagn_manage_ibss_station, 2294 .manage_ibss_station = iwlagn_manage_ibss_station,
2286 .update_bcast_stations = iwl_update_bcast_stations, 2295 .update_bcast_stations = iwl_update_bcast_stations,
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 1b25ad63b5c1..fd9fbc93ea1b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -195,8 +195,7 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
195 priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant; 195 priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
196 priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant; 196 priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
197 197
198 if (priv->cfg->ops->lib->temp_ops.set_ct_kill) 198 iwl5000_set_ct_threshold(priv);
199 priv->cfg->ops->lib->temp_ops.set_ct_kill(priv);
200 199
201 /* Set initial sensitivity parameters */ 200 /* Set initial sensitivity parameters */
202 /* Set initial calibration set */ 201 /* Set initial calibration set */
@@ -242,8 +241,7 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv)
242 priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant; 241 priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
243 priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant; 242 priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
244 243
245 if (priv->cfg->ops->lib->temp_ops.set_ct_kill) 244 iwl5150_set_ct_threshold(priv);
246 priv->cfg->ops->lib->temp_ops.set_ct_kill(priv);
247 245
248 /* Set initial sensitivity parameters */ 246 /* Set initial sensitivity parameters */
249 /* Set initial calibration set */ 247 /* Set initial calibration set */
@@ -370,9 +368,7 @@ static struct iwl_lib_ops iwl5000_lib = {
370 .set_channel_switch = iwl5000_hw_channel_switch, 368 .set_channel_switch = iwl5000_hw_channel_switch,
371 .apm_ops = { 369 .apm_ops = {
372 .init = iwl_apm_init, 370 .init = iwl_apm_init,
373 .stop = iwl_apm_stop,
374 .config = iwl5000_nic_config, 371 .config = iwl5000_nic_config,
375 .set_pwr_src = iwl_set_pwr_src,
376 }, 372 },
377 .eeprom_ops = { 373 .eeprom_ops = {
378 .regulatory_bands = { 374 .regulatory_bands = {
@@ -384,7 +380,6 @@ static struct iwl_lib_ops iwl5000_lib = {
384 EEPROM_REG_BAND_24_HT40_CHANNELS, 380 EEPROM_REG_BAND_24_HT40_CHANNELS,
385 EEPROM_REG_BAND_52_HT40_CHANNELS 381 EEPROM_REG_BAND_52_HT40_CHANNELS
386 }, 382 },
387 .verify_signature = iwlcore_eeprom_verify_signature,
388 .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, 383 .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
389 .release_semaphore = iwlcore_eeprom_release_semaphore, 384 .release_semaphore = iwlcore_eeprom_release_semaphore,
390 .calib_version = iwlagn_eeprom_calib_version, 385 .calib_version = iwlagn_eeprom_calib_version,
@@ -395,7 +390,6 @@ static struct iwl_lib_ops iwl5000_lib = {
395 .config_ap = iwl_config_ap, 390 .config_ap = iwl_config_ap,
396 .temp_ops = { 391 .temp_ops = {
397 .temperature = iwlagn_temperature, 392 .temperature = iwlagn_temperature,
398 .set_ct_kill = iwl5000_set_ct_threshold,
399 }, 393 },
400 .manage_ibss_station = iwlagn_manage_ibss_station, 394 .manage_ibss_station = iwlagn_manage_ibss_station,
401 .update_bcast_stations = iwl_update_bcast_stations, 395 .update_bcast_stations = iwl_update_bcast_stations,
@@ -442,9 +436,7 @@ static struct iwl_lib_ops iwl5150_lib = {
442 .set_channel_switch = iwl5000_hw_channel_switch, 436 .set_channel_switch = iwl5000_hw_channel_switch,
443 .apm_ops = { 437 .apm_ops = {
444 .init = iwl_apm_init, 438 .init = iwl_apm_init,
445 .stop = iwl_apm_stop,
446 .config = iwl5000_nic_config, 439 .config = iwl5000_nic_config,
447 .set_pwr_src = iwl_set_pwr_src,
448 }, 440 },
449 .eeprom_ops = { 441 .eeprom_ops = {
450 .regulatory_bands = { 442 .regulatory_bands = {
@@ -456,7 +448,6 @@ static struct iwl_lib_ops iwl5150_lib = {
456 EEPROM_REG_BAND_24_HT40_CHANNELS, 448 EEPROM_REG_BAND_24_HT40_CHANNELS,
457 EEPROM_REG_BAND_52_HT40_CHANNELS 449 EEPROM_REG_BAND_52_HT40_CHANNELS
458 }, 450 },
459 .verify_signature = iwlcore_eeprom_verify_signature,
460 .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, 451 .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
461 .release_semaphore = iwlcore_eeprom_release_semaphore, 452 .release_semaphore = iwlcore_eeprom_release_semaphore,
462 .calib_version = iwlagn_eeprom_calib_version, 453 .calib_version = iwlagn_eeprom_calib_version,
@@ -467,7 +458,6 @@ static struct iwl_lib_ops iwl5150_lib = {
467 .config_ap = iwl_config_ap, 458 .config_ap = iwl_config_ap,
468 .temp_ops = { 459 .temp_ops = {
469 .temperature = iwl5150_temperature, 460 .temperature = iwl5150_temperature,
470 .set_ct_kill = iwl5150_set_ct_threshold,
471 }, 461 },
472 .manage_ibss_station = iwlagn_manage_ibss_station, 462 .manage_ibss_station = iwlagn_manage_ibss_station,
473 .update_bcast_stations = iwl_update_bcast_stations, 463 .update_bcast_stations = iwl_update_bcast_stations,
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 6261aec5ebdc..11e6532fc573 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -192,8 +192,7 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
192 priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant; 192 priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
193 priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant; 193 priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
194 194
195 if (priv->cfg->ops->lib->temp_ops.set_ct_kill) 195 iwl6000_set_ct_threshold(priv);
196 priv->cfg->ops->lib->temp_ops.set_ct_kill(priv);
197 196
198 /* Set initial sensitivity parameters */ 197 /* Set initial sensitivity parameters */
199 /* Set initial calibration set */ 198 /* Set initial calibration set */
@@ -205,6 +204,8 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
205 BIT(IWL_CALIB_BASE_BAND); 204 BIT(IWL_CALIB_BASE_BAND);
206 if (priv->cfg->need_dc_calib) 205 if (priv->cfg->need_dc_calib)
207 priv->hw_params.calib_rt_cfg |= BIT(IWL_CALIB_CFG_DC_IDX); 206 priv->hw_params.calib_rt_cfg |= BIT(IWL_CALIB_CFG_DC_IDX);
207 if (priv->cfg->need_temp_offset_calib)
208 priv->hw_params.calib_init_cfg |= BIT(IWL_CALIB_TEMP_OFFSET);
208 209
209 priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS; 210 priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS;
210 211
@@ -309,9 +310,7 @@ static struct iwl_lib_ops iwl6000_lib = {
309 .set_channel_switch = iwl6000_hw_channel_switch, 310 .set_channel_switch = iwl6000_hw_channel_switch,
310 .apm_ops = { 311 .apm_ops = {
311 .init = iwl_apm_init, 312 .init = iwl_apm_init,
312 .stop = iwl_apm_stop,
313 .config = iwl6000_nic_config, 313 .config = iwl6000_nic_config,
314 .set_pwr_src = iwl_set_pwr_src,
315 }, 314 },
316 .eeprom_ops = { 315 .eeprom_ops = {
317 .regulatory_bands = { 316 .regulatory_bands = {
@@ -323,7 +322,6 @@ static struct iwl_lib_ops iwl6000_lib = {
323 EEPROM_6000_REG_BAND_24_HT40_CHANNELS, 322 EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
324 EEPROM_REG_BAND_52_HT40_CHANNELS 323 EEPROM_REG_BAND_52_HT40_CHANNELS
325 }, 324 },
326 .verify_signature = iwlcore_eeprom_verify_signature,
327 .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, 325 .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
328 .release_semaphore = iwlcore_eeprom_release_semaphore, 326 .release_semaphore = iwlcore_eeprom_release_semaphore,
329 .calib_version = iwlagn_eeprom_calib_version, 327 .calib_version = iwlagn_eeprom_calib_version,
@@ -335,7 +333,6 @@ static struct iwl_lib_ops iwl6000_lib = {
335 .config_ap = iwl_config_ap, 333 .config_ap = iwl_config_ap,
336 .temp_ops = { 334 .temp_ops = {
337 .temperature = iwlagn_temperature, 335 .temperature = iwlagn_temperature,
338 .set_ct_kill = iwl6000_set_ct_threshold,
339 }, 336 },
340 .manage_ibss_station = iwlagn_manage_ibss_station, 337 .manage_ibss_station = iwlagn_manage_ibss_station,
341 .update_bcast_stations = iwl_update_bcast_stations, 338 .update_bcast_stations = iwl_update_bcast_stations,
@@ -384,9 +381,7 @@ static struct iwl_lib_ops iwl6000g2b_lib = {
384 .set_channel_switch = iwl6000_hw_channel_switch, 381 .set_channel_switch = iwl6000_hw_channel_switch,
385 .apm_ops = { 382 .apm_ops = {
386 .init = iwl_apm_init, 383 .init = iwl_apm_init,
387 .stop = iwl_apm_stop,
388 .config = iwl6000_nic_config, 384 .config = iwl6000_nic_config,
389 .set_pwr_src = iwl_set_pwr_src,
390 }, 385 },
391 .eeprom_ops = { 386 .eeprom_ops = {
392 .regulatory_bands = { 387 .regulatory_bands = {
@@ -398,7 +393,6 @@ static struct iwl_lib_ops iwl6000g2b_lib = {
398 EEPROM_6000_REG_BAND_24_HT40_CHANNELS, 393 EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
399 EEPROM_REG_BAND_52_HT40_CHANNELS 394 EEPROM_REG_BAND_52_HT40_CHANNELS
400 }, 395 },
401 .verify_signature = iwlcore_eeprom_verify_signature,
402 .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, 396 .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
403 .release_semaphore = iwlcore_eeprom_release_semaphore, 397 .release_semaphore = iwlcore_eeprom_release_semaphore,
404 .calib_version = iwlagn_eeprom_calib_version, 398 .calib_version = iwlagn_eeprom_calib_version,
@@ -410,7 +404,6 @@ static struct iwl_lib_ops iwl6000g2b_lib = {
410 .config_ap = iwl_config_ap, 404 .config_ap = iwl_config_ap,
411 .temp_ops = { 405 .temp_ops = {
412 .temperature = iwlagn_temperature, 406 .temperature = iwlagn_temperature,
413 .set_ct_kill = iwl6000_set_ct_threshold,
414 }, 407 },
415 .manage_ibss_station = iwlagn_manage_ibss_station, 408 .manage_ibss_station = iwlagn_manage_ibss_station,
416 .update_bcast_stations = iwl_update_bcast_stations, 409 .update_bcast_stations = iwl_update_bcast_stations,
@@ -516,6 +509,28 @@ static struct iwl_base_params iwl6050_base_params = {
516 .sensitivity_calib_by_driver = true, 509 .sensitivity_calib_by_driver = true,
517 .chain_noise_calib_by_driver = true, 510 .chain_noise_calib_by_driver = true,
518}; 511};
512static struct iwl_base_params iwl6000_coex_base_params = {
513 .eeprom_size = OTP_LOW_IMAGE_SIZE,
514 .num_of_queues = IWLAGN_NUM_QUEUES,
515 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
516 .pll_cfg_val = 0,
517 .set_l0s = true,
518 .use_bsm = false,
519 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
520 .shadow_ram_support = true,
521 .led_compensation = 51,
522 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
523 .supports_idle = true,
524 .adv_thermal_throttle = true,
525 .support_ct_kill_exit = true,
526 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
527 .chain_noise_scale = 1000,
528 .monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
529 .max_event_log_size = 512,
530 .ucode_tracing = true,
531 .sensitivity_calib_by_driver = true,
532 .chain_noise_calib_by_driver = true,
533};
519 534
520static struct iwl_ht_params iwl6000_ht_params = { 535static struct iwl_ht_params iwl6000_ht_params = {
521 .ht_greenfield_support = true, 536 .ht_greenfield_support = true,
@@ -545,6 +560,7 @@ struct iwl_cfg iwl6000g2a_2agn_cfg = {
545 .base_params = &iwl6000_base_params, 560 .base_params = &iwl6000_base_params,
546 .ht_params = &iwl6000_ht_params, 561 .ht_params = &iwl6000_ht_params,
547 .need_dc_calib = true, 562 .need_dc_calib = true,
563 .need_temp_offset_calib = true,
548}; 564};
549 565
550struct iwl_cfg iwl6000g2a_2abg_cfg = { 566struct iwl_cfg iwl6000g2a_2abg_cfg = {
@@ -561,6 +577,7 @@ struct iwl_cfg iwl6000g2a_2abg_cfg = {
561 .mod_params = &iwlagn_mod_params, 577 .mod_params = &iwlagn_mod_params,
562 .base_params = &iwl6000_base_params, 578 .base_params = &iwl6000_base_params,
563 .need_dc_calib = true, 579 .need_dc_calib = true,
580 .need_temp_offset_calib = true,
564}; 581};
565 582
566struct iwl_cfg iwl6000g2a_2bg_cfg = { 583struct iwl_cfg iwl6000g2a_2bg_cfg = {
@@ -577,6 +594,7 @@ struct iwl_cfg iwl6000g2a_2bg_cfg = {
577 .mod_params = &iwlagn_mod_params, 594 .mod_params = &iwlagn_mod_params,
578 .base_params = &iwl6000_base_params, 595 .base_params = &iwl6000_base_params,
579 .need_dc_calib = true, 596 .need_dc_calib = true,
597 .need_temp_offset_calib = true,
580}; 598};
581 599
582struct iwl_cfg iwl6000g2b_2agn_cfg = { 600struct iwl_cfg iwl6000g2b_2agn_cfg = {
@@ -591,10 +609,11 @@ struct iwl_cfg iwl6000g2b_2agn_cfg = {
591 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, 609 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
592 .ops = &iwl6000g2b_ops, 610 .ops = &iwl6000g2b_ops,
593 .mod_params = &iwlagn_mod_params, 611 .mod_params = &iwlagn_mod_params,
594 .base_params = &iwl6000_base_params, 612 .base_params = &iwl6000_coex_base_params,
595 .bt_params = &iwl6000_bt_params, 613 .bt_params = &iwl6000_bt_params,
596 .ht_params = &iwl6000_ht_params, 614 .ht_params = &iwl6000_ht_params,
597 .need_dc_calib = true, 615 .need_dc_calib = true,
616 .need_temp_offset_calib = true,
598 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ 617 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
599 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, 618 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
600}; 619};
@@ -611,9 +630,10 @@ struct iwl_cfg iwl6000g2b_2abg_cfg = {
611 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, 630 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
612 .ops = &iwl6000g2b_ops, 631 .ops = &iwl6000g2b_ops,
613 .mod_params = &iwlagn_mod_params, 632 .mod_params = &iwlagn_mod_params,
614 .base_params = &iwl6000_base_params, 633 .base_params = &iwl6000_coex_base_params,
615 .bt_params = &iwl6000_bt_params, 634 .bt_params = &iwl6000_bt_params,
616 .need_dc_calib = true, 635 .need_dc_calib = true,
636 .need_temp_offset_calib = true,
617 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ 637 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
618 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, 638 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
619}; 639};
@@ -630,10 +650,11 @@ struct iwl_cfg iwl6000g2b_2bgn_cfg = {
630 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, 650 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
631 .ops = &iwl6000g2b_ops, 651 .ops = &iwl6000g2b_ops,
632 .mod_params = &iwlagn_mod_params, 652 .mod_params = &iwlagn_mod_params,
633 .base_params = &iwl6000_base_params, 653 .base_params = &iwl6000_coex_base_params,
634 .bt_params = &iwl6000_bt_params, 654 .bt_params = &iwl6000_bt_params,
635 .ht_params = &iwl6000_ht_params, 655 .ht_params = &iwl6000_ht_params,
636 .need_dc_calib = true, 656 .need_dc_calib = true,
657 .need_temp_offset_calib = true,
637 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ 658 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
638 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, 659 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
639}; 660};
@@ -650,9 +671,10 @@ struct iwl_cfg iwl6000g2b_2bg_cfg = {
650 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, 671 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
651 .ops = &iwl6000g2b_ops, 672 .ops = &iwl6000g2b_ops,
652 .mod_params = &iwlagn_mod_params, 673 .mod_params = &iwlagn_mod_params,
653 .base_params = &iwl6000_base_params, 674 .base_params = &iwl6000_coex_base_params,
654 .bt_params = &iwl6000_bt_params, 675 .bt_params = &iwl6000_bt_params,
655 .need_dc_calib = true, 676 .need_dc_calib = true,
677 .need_temp_offset_calib = true,
656 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ 678 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
657 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, 679 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
658}; 680};
@@ -669,10 +691,11 @@ struct iwl_cfg iwl6000g2b_bgn_cfg = {
669 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, 691 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
670 .ops = &iwl6000g2b_ops, 692 .ops = &iwl6000g2b_ops,
671 .mod_params = &iwlagn_mod_params, 693 .mod_params = &iwlagn_mod_params,
672 .base_params = &iwl6000_base_params, 694 .base_params = &iwl6000_coex_base_params,
673 .bt_params = &iwl6000_bt_params, 695 .bt_params = &iwl6000_bt_params,
674 .ht_params = &iwl6000_ht_params, 696 .ht_params = &iwl6000_ht_params,
675 .need_dc_calib = true, 697 .need_dc_calib = true,
698 .need_temp_offset_calib = true,
676 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ 699 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
677 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, 700 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
678}; 701};
@@ -689,9 +712,10 @@ struct iwl_cfg iwl6000g2b_bg_cfg = {
689 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, 712 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
690 .ops = &iwl6000g2b_ops, 713 .ops = &iwl6000g2b_ops,
691 .mod_params = &iwlagn_mod_params, 714 .mod_params = &iwlagn_mod_params,
692 .base_params = &iwl6000_base_params, 715 .base_params = &iwl6000_coex_base_params,
693 .bt_params = &iwl6000_bt_params, 716 .bt_params = &iwl6000_bt_params,
694 .need_dc_calib = true, 717 .need_dc_calib = true,
718 .need_temp_offset_calib = true,
695 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ 719 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
696 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, 720 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
697}; 721};
@@ -756,7 +780,7 @@ struct iwl_cfg iwl6050_2agn_cfg = {
756 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, 780 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
757 .valid_tx_ant = ANT_AB, 781 .valid_tx_ant = ANT_AB,
758 .valid_rx_ant = ANT_AB, 782 .valid_rx_ant = ANT_AB,
759 .ops = &iwl6000_ops, 783 .ops = &iwl6050_ops,
760 .eeprom_ver = EEPROM_6050_EEPROM_VERSION, 784 .eeprom_ver = EEPROM_6050_EEPROM_VERSION,
761 .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION, 785 .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION,
762 .mod_params = &iwlagn_mod_params, 786 .mod_params = &iwlagn_mod_params,
@@ -827,7 +851,7 @@ struct iwl_cfg iwl130_bgn_cfg = {
827 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, 851 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
828 .ops = &iwl6000g2b_ops, 852 .ops = &iwl6000g2b_ops,
829 .mod_params = &iwlagn_mod_params, 853 .mod_params = &iwlagn_mod_params,
830 .base_params = &iwl6000_base_params, 854 .base_params = &iwl6000_coex_base_params,
831 .bt_params = &iwl6000_bt_params, 855 .bt_params = &iwl6000_bt_params,
832 .ht_params = &iwl6000_ht_params, 856 .ht_params = &iwl6000_ht_params,
833 .need_dc_calib = true, 857 .need_dc_calib = true,
@@ -847,7 +871,7 @@ struct iwl_cfg iwl130_bg_cfg = {
847 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, 871 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
848 .ops = &iwl6000g2b_ops, 872 .ops = &iwl6000g2b_ops,
849 .mod_params = &iwlagn_mod_params, 873 .mod_params = &iwlagn_mod_params,
850 .base_params = &iwl6000_base_params, 874 .base_params = &iwl6000_coex_base_params,
851 .bt_params = &iwl6000_bt_params, 875 .bt_params = &iwl6000_bt_params,
852 .need_dc_calib = true, 876 .need_dc_calib = true,
853 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ 877 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
index 4c5ab783737f..e2019e756936 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
@@ -65,7 +65,7 @@
65 65
66#include "iwl-dev.h" 66#include "iwl-dev.h"
67#include "iwl-core.h" 67#include "iwl-core.h"
68#include "iwl-calib.h" 68#include "iwl-agn-calib.h"
69 69
70/***************************************************************************** 70/*****************************************************************************
71 * INIT calibrations framework 71 * INIT calibrations framework
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.h b/drivers/net/wireless/iwlwifi/iwl-agn-calib.h
index ba9523fbb300..e37ae7261630 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.h
@@ -79,4 +79,8 @@ static inline void iwl_chain_noise_reset(struct iwl_priv *priv)
79 priv->cfg->ops->utils->chain_noise_reset(priv); 79 priv->cfg->ops->utils->chain_noise_reset(priv);
80} 80}
81 81
82int iwl_send_calib_results(struct iwl_priv *priv);
83int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len);
84void iwl_calib_free_results(struct iwl_priv *priv);
85
82#endif /* __iwl_calib_h__ */ 86#endif /* __iwl_calib_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c
new file mode 100644
index 000000000000..a650baba0809
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c
@@ -0,0 +1,454 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *****************************************************************************/
62
63
64#include <linux/kernel.h>
65#include <linux/module.h>
66#include <linux/slab.h>
67#include <linux/init.h>
68
69#include <net/mac80211.h>
70
71#include "iwl-commands.h"
72#include "iwl-dev.h"
73#include "iwl-core.h"
74#include "iwl-debug.h"
75#include "iwl-agn.h"
76#include "iwl-io.h"
77
78/************************** EEPROM BANDS ****************************
79 *
80 * The iwl_eeprom_band definitions below provide the mapping from the
81 * EEPROM contents to the specific channel number supported for each
82 * band.
83 *
84 * For example, iwl_priv->eeprom.band_3_channels[4] from the band_3
85 * definition below maps to physical channel 42 in the 5.2GHz spectrum.
86 * The specific geography and calibration information for that channel
87 * is contained in the eeprom map itself.
88 *
89 * During init, we copy the eeprom information and channel map
90 * information into priv->channel_info_24/52 and priv->channel_map_24/52
91 *
92 * channel_map_24/52 provides the index in the channel_info array for a
93 * given channel. We have to have two separate maps as there is channel
94 * overlap with the 2.4GHz and 5.2GHz spectrum as seen in band_1 and
95 * band_2
96 *
97 * A value of 0xff stored in the channel_map indicates that the channel
98 * is not supported by the hardware at all.
99 *
100 * A value of 0xfe in the channel_map indicates that the channel is not
101 * valid for Tx with the current hardware. This means that
102 * while the system can tune and receive on a given channel, it may not
103 * be able to associate or transmit any frames on that
104 * channel. There is no corresponding channel information for that
105 * entry.
106 *
107 *********************************************************************/
108
109/**
110 * struct iwl_txpwr_section: eeprom section information
111 * @offset: indirect address into eeprom image
112 * @count: number of "struct iwl_eeprom_enhanced_txpwr" in this section
113 * @band: band type for the section
114 * @is_common - true: common section, false: channel section
115 * @is_cck - true: cck section, false: not cck section
116 * @is_ht_40 - true: all channel in the section are HT40 channel,
117 * false: legacy or HT 20 MHz
118 * ignore if it is common section
119 * @iwl_eeprom_section_channel: channel array in the section,
120 * ignore if common section
121 */
122struct iwl_txpwr_section {
123 u32 offset;
124 u8 count;
125 enum ieee80211_band band;
126 bool is_common;
127 bool is_cck;
128 bool is_ht40;
129 u8 iwl_eeprom_section_channel[EEPROM_MAX_TXPOWER_SECTION_ELEMENTS];
130};
131
132/**
133 * section 1 - 3 are regulatory tx power apply to all channels based on
134 * modulation: CCK, OFDM
135 * Band: 2.4GHz, 5.2GHz
136 * section 4 - 10 are regulatory tx power apply to specified channels
137 * For example:
138 * 1L - Channel 1 Legacy
139 * 1HT - Channel 1 HT
140 * (1,+1) - Channel 1 HT40 "_above_"
141 *
142 * Section 1: all CCK channels
143 * Section 2: all 2.4 GHz OFDM (Legacy, HT and HT40) channels
144 * Section 3: all 5.2 GHz OFDM (Legacy, HT and HT40) channels
145 * Section 4: 2.4 GHz 20MHz channels: 1L, 1HT, 2L, 2HT, 10L, 10HT, 11L, 11HT
146 * Section 5: 2.4 GHz 40MHz channels: (1,+1) (2,+1) (6,+1) (7,+1) (9,+1)
147 * Section 6: 5.2 GHz 20MHz channels: 36L, 64L, 100L, 36HT, 64HT, 100HT
148 * Section 7: 5.2 GHz 40MHz channels: (36,+1) (60,+1) (100,+1)
149 * Section 8: 2.4 GHz channel: 13L, 13HT
150 * Section 9: 2.4 GHz channel: 140L, 140HT
151 * Section 10: 2.4 GHz 40MHz channels: (132,+1) (44,+1)
152 *
153 */
154static const struct iwl_txpwr_section enhinfo[] = {
155 { EEPROM_LB_CCK_20_COMMON, 1, IEEE80211_BAND_2GHZ, true, true, false },
156 { EEPROM_LB_OFDM_COMMON, 3, IEEE80211_BAND_2GHZ, true, false, false },
157 { EEPROM_HB_OFDM_COMMON, 3, IEEE80211_BAND_5GHZ, true, false, false },
158 { EEPROM_LB_OFDM_20_BAND, 8, IEEE80211_BAND_2GHZ,
159 false, false, false,
160 {1, 1, 2, 2, 10, 10, 11, 11 } },
161 { EEPROM_LB_OFDM_HT40_BAND, 5, IEEE80211_BAND_2GHZ,
162 false, false, true,
163 { 1, 2, 6, 7, 9 } },
164 { EEPROM_HB_OFDM_20_BAND, 6, IEEE80211_BAND_5GHZ,
165 false, false, false,
166 { 36, 64, 100, 36, 64, 100 } },
167 { EEPROM_HB_OFDM_HT40_BAND, 3, IEEE80211_BAND_5GHZ,
168 false, false, true,
169 { 36, 60, 100 } },
170 { EEPROM_LB_OFDM_20_CHANNEL_13, 2, IEEE80211_BAND_2GHZ,
171 false, false, false,
172 { 13, 13 } },
173 { EEPROM_HB_OFDM_20_CHANNEL_140, 2, IEEE80211_BAND_5GHZ,
174 false, false, false,
175 { 140, 140 } },
176 { EEPROM_HB_OFDM_HT40_BAND_1, 2, IEEE80211_BAND_5GHZ,
177 false, false, true,
178 { 132, 44 } },
179};
180
181/******************************************************************************
182 *
183 * EEPROM related functions
184 *
185******************************************************************************/
186
187/*
188 * The device's EEPROM semaphore prevents conflicts between driver and uCode
189 * when accessing the EEPROM; each access is a series of pulses to/from the
190 * EEPROM chip, not a single event, so even reads could conflict if they
191 * weren't arbitrated by the semaphore.
192 */
193int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv)
194{
195 u16 count;
196 int ret;
197
198 for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) {
199 /* Request semaphore */
200 iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
201 CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
202
203 /* See if we got it */
204 ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG,
205 CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
206 CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
207 EEPROM_SEM_TIMEOUT);
208 if (ret >= 0) {
209 IWL_DEBUG_IO(priv,
210 "Acquired semaphore after %d tries.\n",
211 count+1);
212 return ret;
213 }
214 }
215
216 return ret;
217}
218
219void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv)
220{
221 iwl_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
222 CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
223
224}
225
226int iwl_eeprom_check_version(struct iwl_priv *priv)
227{
228 u16 eeprom_ver;
229 u16 calib_ver;
230
231 eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
232 calib_ver = priv->cfg->ops->lib->eeprom_ops.calib_version(priv);
233
234 if (eeprom_ver < priv->cfg->eeprom_ver ||
235 calib_ver < priv->cfg->eeprom_calib_ver)
236 goto err;
237
238 IWL_INFO(priv, "device EEPROM VER=0x%x, CALIB=0x%x\n",
239 eeprom_ver, calib_ver);
240
241 return 0;
242err:
243 IWL_ERR(priv, "Unsupported (too old) EEPROM VER=0x%x < 0x%x "
244 "CALIB=0x%x < 0x%x\n",
245 eeprom_ver, priv->cfg->eeprom_ver,
246 calib_ver, priv->cfg->eeprom_calib_ver);
247 return -EINVAL;
248
249}
250
251void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac)
252{
253 const u8 *addr = priv->cfg->ops->lib->eeprom_ops.query_addr(priv,
254 EEPROM_MAC_ADDRESS);
255 memcpy(mac, addr, ETH_ALEN);
256}
257
258/**
259 * iwl_get_max_txpower_avg - get the highest tx power from all chains.
260 * find the highest tx power from all chains for the channel
261 */
262static s8 iwl_get_max_txpower_avg(struct iwl_priv *priv,
263 struct iwl_eeprom_enhanced_txpwr *enhanced_txpower,
264 int element, s8 *max_txpower_in_half_dbm)
265{
266 s8 max_txpower_avg = 0; /* (dBm) */
267
268 IWL_DEBUG_INFO(priv, "%d - "
269 "chain_a: %d dB chain_b: %d dB "
270 "chain_c: %d dB mimo2: %d dB mimo3: %d dB\n",
271 element,
272 enhanced_txpower[element].chain_a_max >> 1,
273 enhanced_txpower[element].chain_b_max >> 1,
274 enhanced_txpower[element].chain_c_max >> 1,
275 enhanced_txpower[element].mimo2_max >> 1,
276 enhanced_txpower[element].mimo3_max >> 1);
277 /* Take the highest tx power from any valid chains */
278 if ((priv->cfg->valid_tx_ant & ANT_A) &&
279 (enhanced_txpower[element].chain_a_max > max_txpower_avg))
280 max_txpower_avg = enhanced_txpower[element].chain_a_max;
281 if ((priv->cfg->valid_tx_ant & ANT_B) &&
282 (enhanced_txpower[element].chain_b_max > max_txpower_avg))
283 max_txpower_avg = enhanced_txpower[element].chain_b_max;
284 if ((priv->cfg->valid_tx_ant & ANT_C) &&
285 (enhanced_txpower[element].chain_c_max > max_txpower_avg))
286 max_txpower_avg = enhanced_txpower[element].chain_c_max;
287 if (((priv->cfg->valid_tx_ant == ANT_AB) |
288 (priv->cfg->valid_tx_ant == ANT_BC) |
289 (priv->cfg->valid_tx_ant == ANT_AC)) &&
290 (enhanced_txpower[element].mimo2_max > max_txpower_avg))
291 max_txpower_avg = enhanced_txpower[element].mimo2_max;
292 if ((priv->cfg->valid_tx_ant == ANT_ABC) &&
293 (enhanced_txpower[element].mimo3_max > max_txpower_avg))
294 max_txpower_avg = enhanced_txpower[element].mimo3_max;
295
296 /*
297 * max. tx power in EEPROM is in 1/2 dBm format
298 * convert from 1/2 dBm to dBm (round-up convert)
299 * but we also do not want to loss 1/2 dBm resolution which
300 * will impact performance
301 */
302 *max_txpower_in_half_dbm = max_txpower_avg;
303 return (max_txpower_avg & 0x01) + (max_txpower_avg >> 1);
304}
305
306/**
307 * iwl_update_common_txpower: update channel tx power
308 * update tx power per band based on EEPROM enhanced tx power info.
309 */
310static s8 iwl_update_common_txpower(struct iwl_priv *priv,
311 struct iwl_eeprom_enhanced_txpwr *enhanced_txpower,
312 int section, int element, s8 *max_txpower_in_half_dbm)
313{
314 struct iwl_channel_info *ch_info;
315 int ch;
316 bool is_ht40 = false;
317 s8 max_txpower_avg; /* (dBm) */
318
319 /* it is common section, contain all type (Legacy, HT and HT40)
320 * based on the element in the section to determine
321 * is it HT 40 or not
322 */
323 if (element == EEPROM_TXPOWER_COMMON_HT40_INDEX)
324 is_ht40 = true;
325 max_txpower_avg =
326 iwl_get_max_txpower_avg(priv, enhanced_txpower,
327 element, max_txpower_in_half_dbm);
328
329 ch_info = priv->channel_info;
330
331 for (ch = 0; ch < priv->channel_count; ch++) {
332 /* find matching band and update tx power if needed */
333 if ((ch_info->band == enhinfo[section].band) &&
334 (ch_info->max_power_avg < max_txpower_avg) &&
335 (!is_ht40)) {
336 /* Update regulatory-based run-time data */
337 ch_info->max_power_avg = ch_info->curr_txpow =
338 max_txpower_avg;
339 ch_info->scan_power = max_txpower_avg;
340 }
341 if ((ch_info->band == enhinfo[section].band) && is_ht40 &&
342 (ch_info->ht40_max_power_avg < max_txpower_avg)) {
343 /* Update regulatory-based run-time data */
344 ch_info->ht40_max_power_avg = max_txpower_avg;
345 }
346 ch_info++;
347 }
348 return max_txpower_avg;
349}
350
351/**
352 * iwl_update_channel_txpower: update channel tx power
353 * update channel tx power based on EEPROM enhanced tx power info.
354 */
355static s8 iwl_update_channel_txpower(struct iwl_priv *priv,
356 struct iwl_eeprom_enhanced_txpwr *enhanced_txpower,
357 int section, int element, s8 *max_txpower_in_half_dbm)
358{
359 struct iwl_channel_info *ch_info;
360 int ch;
361 u8 channel;
362 s8 max_txpower_avg; /* (dBm) */
363
364 channel = enhinfo[section].iwl_eeprom_section_channel[element];
365 max_txpower_avg =
366 iwl_get_max_txpower_avg(priv, enhanced_txpower,
367 element, max_txpower_in_half_dbm);
368
369 ch_info = priv->channel_info;
370 for (ch = 0; ch < priv->channel_count; ch++) {
371 /* find matching channel and update tx power if needed */
372 if (ch_info->channel == channel) {
373 if ((ch_info->max_power_avg < max_txpower_avg) &&
374 (!enhinfo[section].is_ht40)) {
375 /* Update regulatory-based run-time data */
376 ch_info->max_power_avg = max_txpower_avg;
377 ch_info->curr_txpow = max_txpower_avg;
378 ch_info->scan_power = max_txpower_avg;
379 }
380 if ((enhinfo[section].is_ht40) &&
381 (ch_info->ht40_max_power_avg < max_txpower_avg)) {
382 /* Update regulatory-based run-time data */
383 ch_info->ht40_max_power_avg = max_txpower_avg;
384 }
385 break;
386 }
387 ch_info++;
388 }
389 return max_txpower_avg;
390}
391
392/**
393 * iwlcore_eeprom_enhanced_txpower: process enhanced tx power info
394 */
395void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv)
396{
397 int eeprom_section_count = 0;
398 int section, element;
399 struct iwl_eeprom_enhanced_txpwr *enhanced_txpower;
400 u32 offset;
401 s8 max_txpower_avg; /* (dBm) */
402 s8 max_txpower_in_half_dbm; /* (half-dBm) */
403
404 /* Loop through all the sections
405 * adjust bands and channel's max tx power
406 * Set the tx_power_user_lmt to the highest power
407 * supported by any channels and chains
408 */
409 for (section = 0; section < ARRAY_SIZE(enhinfo); section++) {
410 eeprom_section_count = enhinfo[section].count;
411 offset = enhinfo[section].offset;
412 enhanced_txpower = (struct iwl_eeprom_enhanced_txpwr *)
413 iwl_eeprom_query_addr(priv, offset);
414
415 /*
416 * check for valid entry -
417 * different version of EEPROM might contain different set
418 * of enhanced tx power table
419 * always check for valid entry before process
420 * the information
421 */
422 if (!enhanced_txpower->common || enhanced_txpower->reserved)
423 continue;
424
425 for (element = 0; element < eeprom_section_count; element++) {
426 if (enhinfo[section].is_common)
427 max_txpower_avg =
428 iwl_update_common_txpower(priv,
429 enhanced_txpower, section,
430 element,
431 &max_txpower_in_half_dbm);
432 else
433 max_txpower_avg =
434 iwl_update_channel_txpower(priv,
435 enhanced_txpower, section,
436 element,
437 &max_txpower_in_half_dbm);
438
439 /* Update the tx_power_user_lmt to the highest power
440 * supported by any channel */
441 if (max_txpower_avg > priv->tx_power_user_lmt)
442 priv->tx_power_user_lmt = max_txpower_avg;
443
444 /*
445 * Update the tx_power_lmt_in_half_dbm to
446 * the highest power supported by any channel
447 */
448 if (max_txpower_in_half_dbm >
449 priv->tx_power_lmt_in_half_dbm)
450 priv->tx_power_lmt_in_half_dbm =
451 max_txpower_in_half_dbm;
452 }
453 }
454}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
index 9ca6c91eaae6..ffb2f4111ad0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
@@ -360,8 +360,8 @@ static int iwlagn_set_pan_params(struct iwl_priv *priv)
360 360
361struct iwl_hcmd_ops iwlagn_hcmd = { 361struct iwl_hcmd_ops iwlagn_hcmd = {
362 .rxon_assoc = iwlagn_send_rxon_assoc, 362 .rxon_assoc = iwlagn_send_rxon_assoc,
363 .commit_rxon = iwl_commit_rxon, 363 .commit_rxon = iwlagn_commit_rxon,
364 .set_rxon_chain = iwl_set_rxon_chain, 364 .set_rxon_chain = iwlagn_set_rxon_chain,
365 .set_tx_ant = iwlagn_send_tx_ant_config, 365 .set_tx_ant = iwlagn_send_tx_ant_config,
366 .send_bt_config = iwl_send_bt_config, 366 .send_bt_config = iwl_send_bt_config,
367 .set_pan_params = iwlagn_set_pan_params, 367 .set_pan_params = iwlagn_set_pan_params,
@@ -369,8 +369,8 @@ struct iwl_hcmd_ops iwlagn_hcmd = {
369 369
370struct iwl_hcmd_ops iwlagn_bt_hcmd = { 370struct iwl_hcmd_ops iwlagn_bt_hcmd = {
371 .rxon_assoc = iwlagn_send_rxon_assoc, 371 .rxon_assoc = iwlagn_send_rxon_assoc,
372 .commit_rxon = iwl_commit_rxon, 372 .commit_rxon = iwlagn_commit_rxon,
373 .set_rxon_chain = iwl_set_rxon_chain, 373 .set_rxon_chain = iwlagn_set_rxon_chain,
374 .set_tx_ant = iwlagn_send_tx_ant_config, 374 .set_tx_ant = iwlagn_send_tx_ant_config,
375 .send_bt_config = iwlagn_send_advance_bt_config, 375 .send_bt_config = iwlagn_send_advance_bt_config,
376 .set_pan_params = iwlagn_set_pan_params, 376 .set_pan_params = iwlagn_set_pan_params,
@@ -384,4 +384,5 @@ struct iwl_hcmd_utils_ops iwlagn_hcmd_utils = {
384 .tx_cmd_protection = iwlagn_tx_cmd_protection, 384 .tx_cmd_protection = iwlagn_tx_cmd_protection,
385 .calc_rssi = iwlagn_calc_rssi, 385 .calc_rssi = iwlagn_calc_rssi,
386 .request_scan = iwlagn_request_scan, 386 .request_scan = iwlagn_request_scan,
387 .post_scan = iwlagn_post_scan,
387}; 388};
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index f5445d575fec..b555edd53354 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -685,6 +685,23 @@ int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
685 return 0; 685 return 0;
686} 686}
687 687
688static void iwlagn_set_pwr_vmain(struct iwl_priv *priv)
689{
690/*
691 * (for documentation purposes)
692 * to set power to V_AUX, do:
693
694 if (pci_pme_capable(priv->pci_dev, PCI_D3cold))
695 iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
696 APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
697 ~APMG_PS_CTRL_MSK_PWR_SRC);
698 */
699
700 iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
701 APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
702 ~APMG_PS_CTRL_MSK_PWR_SRC);
703}
704
688int iwlagn_hw_nic_init(struct iwl_priv *priv) 705int iwlagn_hw_nic_init(struct iwl_priv *priv)
689{ 706{
690 unsigned long flags; 707 unsigned long flags;
@@ -700,7 +717,7 @@ int iwlagn_hw_nic_init(struct iwl_priv *priv)
700 717
701 spin_unlock_irqrestore(&priv->lock, flags); 718 spin_unlock_irqrestore(&priv->lock, flags);
702 719
703 ret = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN); 720 iwlagn_set_pwr_vmain(priv);
704 721
705 priv->cfg->ops->lib->apm_ops.config(priv); 722 priv->cfg->ops->lib->apm_ops.config(priv);
706 723
@@ -1430,35 +1447,35 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
1430 if (priv->cfg->bt_params && 1447 if (priv->cfg->bt_params &&
1431 priv->cfg->bt_params->advanced_bt_coexist) 1448 priv->cfg->bt_params->advanced_bt_coexist)
1432 scan->tx_cmd.tx_flags |= TX_CMD_FLG_IGNORE_BT; 1449 scan->tx_cmd.tx_flags |= TX_CMD_FLG_IGNORE_BT;
1433 scan->good_CRC_th = IWL_GOOD_CRC_TH_DISABLED;
1434 break; 1450 break;
1435 case IEEE80211_BAND_5GHZ: 1451 case IEEE80211_BAND_5GHZ:
1436 rate = IWL_RATE_6M_PLCP; 1452 rate = IWL_RATE_6M_PLCP;
1437 /*
1438 * If active scanning is requested but a certain channel is
1439 * marked passive, we can do active scanning if we detect
1440 * transmissions.
1441 *
1442 * There is an issue with some firmware versions that triggers
1443 * a sysassert on a "good CRC threshold" of zero (== disabled),
1444 * on a radar channel even though this means that we should NOT
1445 * send probes.
1446 *
1447 * The "good CRC threshold" is the number of frames that we
1448 * need to receive during our dwell time on a channel before
1449 * sending out probes -- setting this to a huge value will
1450 * mean we never reach it, but at the same time work around
1451 * the aforementioned issue. Thus use IWL_GOOD_CRC_TH_NEVER
1452 * here instead of IWL_GOOD_CRC_TH_DISABLED.
1453 */
1454 scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
1455 IWL_GOOD_CRC_TH_NEVER;
1456 break; 1453 break;
1457 default: 1454 default:
1458 IWL_WARN(priv, "Invalid scan band\n"); 1455 IWL_WARN(priv, "Invalid scan band\n");
1459 return -EIO; 1456 return -EIO;
1460 } 1457 }
1461 1458
1459 /*
1460 * If active scanning is requested but a certain channel is
1461 * marked passive, we can do active scanning if we detect
1462 * transmissions.
1463 *
1464 * There is an issue with some firmware versions that triggers
1465 * a sysassert on a "good CRC threshold" of zero (== disabled),
1466 * on a radar channel even though this means that we should NOT
1467 * send probes.
1468 *
1469 * The "good CRC threshold" is the number of frames that we
1470 * need to receive during our dwell time on a channel before
1471 * sending out probes -- setting this to a huge value will
1472 * mean we never reach it, but at the same time work around
1473 * the aforementioned issue. Thus use IWL_GOOD_CRC_TH_NEVER
1474 * here instead of IWL_GOOD_CRC_TH_DISABLED.
1475 */
1476 scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
1477 IWL_GOOD_CRC_TH_NEVER;
1478
1462 band = priv->scan_band; 1479 band = priv->scan_band;
1463 1480
1464 if (priv->cfg->scan_rx_antennas[band]) 1481 if (priv->cfg->scan_rx_antennas[band])
@@ -1548,13 +1565,15 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
1548 cmd.data = scan; 1565 cmd.data = scan;
1549 scan->len = cpu_to_le16(cmd.len); 1566 scan->len = cpu_to_le16(cmd.len);
1550 1567
1568 /* set scan bit here for PAN params */
1569 set_bit(STATUS_SCAN_HW, &priv->status);
1570
1551 if (priv->cfg->ops->hcmd->set_pan_params) { 1571 if (priv->cfg->ops->hcmd->set_pan_params) {
1552 ret = priv->cfg->ops->hcmd->set_pan_params(priv); 1572 ret = priv->cfg->ops->hcmd->set_pan_params(priv);
1553 if (ret) 1573 if (ret)
1554 return ret; 1574 return ret;
1555 } 1575 }
1556 1576
1557 set_bit(STATUS_SCAN_HW, &priv->status);
1558 ret = iwl_send_cmd_sync(priv, &cmd); 1577 ret = iwl_send_cmd_sync(priv, &cmd);
1559 if (ret) { 1578 if (ret) {
1560 clear_bit(STATUS_SCAN_HW, &priv->status); 1579 clear_bit(STATUS_SCAN_HW, &priv->status);
@@ -1565,15 +1584,31 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
1565 return ret; 1584 return ret;
1566} 1585}
1567 1586
1587void iwlagn_post_scan(struct iwl_priv *priv)
1588{
1589 struct iwl_rxon_context *ctx;
1590
1591 /*
1592 * Since setting the RXON may have been deferred while
1593 * performing the scan, fire one off if needed
1594 */
1595 for_each_context(priv, ctx)
1596 if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))
1597 iwlagn_commit_rxon(priv, ctx);
1598
1599 if (priv->cfg->ops->hcmd->set_pan_params)
1600 priv->cfg->ops->hcmd->set_pan_params(priv);
1601}
1602
1568int iwlagn_manage_ibss_station(struct iwl_priv *priv, 1603int iwlagn_manage_ibss_station(struct iwl_priv *priv,
1569 struct ieee80211_vif *vif, bool add) 1604 struct ieee80211_vif *vif, bool add)
1570{ 1605{
1571 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; 1606 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
1572 1607
1573 if (add) 1608 if (add)
1574 return iwl_add_bssid_station(priv, vif_priv->ctx, 1609 return iwlagn_add_bssid_station(priv, vif_priv->ctx,
1575 vif->bss_conf.bssid, true, 1610 vif->bss_conf.bssid,
1576 &vif_priv->ibss_bssid_sta_id); 1611 &vif_priv->ibss_bssid_sta_id);
1577 return iwl_remove_station(priv, vif_priv->ibss_bssid_sta_id, 1612 return iwl_remove_station(priv, vif_priv->ibss_bssid_sta_id,
1578 vif->bss_conf.bssid); 1613 vif->bss_conf.bssid);
1579} 1614}
@@ -2049,3 +2084,290 @@ void iwlagn_bt_cancel_deferred_work(struct iwl_priv *priv)
2049{ 2084{
2050 cancel_work_sync(&priv->bt_traffic_change_work); 2085 cancel_work_sync(&priv->bt_traffic_change_work);
2051} 2086}
2087
2088static bool is_single_rx_stream(struct iwl_priv *priv)
2089{
2090 return priv->current_ht_config.smps == IEEE80211_SMPS_STATIC ||
2091 priv->current_ht_config.single_chain_sufficient;
2092}
2093
2094#define IWL_NUM_RX_CHAINS_MULTIPLE 3
2095#define IWL_NUM_RX_CHAINS_SINGLE 2
2096#define IWL_NUM_IDLE_CHAINS_DUAL 2
2097#define IWL_NUM_IDLE_CHAINS_SINGLE 1
2098
2099/*
2100 * Determine how many receiver/antenna chains to use.
2101 *
2102 * More provides better reception via diversity. Fewer saves power
2103 * at the expense of throughput, but only when not in powersave to
2104 * start with.
2105 *
2106 * MIMO (dual stream) requires at least 2, but works better with 3.
2107 * This does not determine *which* chains to use, just how many.
2108 */
2109static int iwl_get_active_rx_chain_count(struct iwl_priv *priv)
2110{
2111 if (priv->cfg->bt_params &&
2112 priv->cfg->bt_params->advanced_bt_coexist &&
2113 (priv->bt_full_concurrent ||
2114 priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) {
2115 /*
2116 * only use chain 'A' in bt high traffic load or
2117 * full concurrency mode
2118 */
2119 return IWL_NUM_RX_CHAINS_SINGLE;
2120 }
2121 /* # of Rx chains to use when expecting MIMO. */
2122 if (is_single_rx_stream(priv))
2123 return IWL_NUM_RX_CHAINS_SINGLE;
2124 else
2125 return IWL_NUM_RX_CHAINS_MULTIPLE;
2126}
2127
2128/*
2129 * When we are in power saving mode, unless device support spatial
2130 * multiplexing power save, use the active count for rx chain count.
2131 */
2132static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt)
2133{
2134 /* # Rx chains when idling, depending on SMPS mode */
2135 switch (priv->current_ht_config.smps) {
2136 case IEEE80211_SMPS_STATIC:
2137 case IEEE80211_SMPS_DYNAMIC:
2138 return IWL_NUM_IDLE_CHAINS_SINGLE;
2139 case IEEE80211_SMPS_OFF:
2140 return active_cnt;
2141 default:
2142 WARN(1, "invalid SMPS mode %d",
2143 priv->current_ht_config.smps);
2144 return active_cnt;
2145 }
2146}
2147
2148/* up to 4 chains */
2149static u8 iwl_count_chain_bitmap(u32 chain_bitmap)
2150{
2151 u8 res;
2152 res = (chain_bitmap & BIT(0)) >> 0;
2153 res += (chain_bitmap & BIT(1)) >> 1;
2154 res += (chain_bitmap & BIT(2)) >> 2;
2155 res += (chain_bitmap & BIT(3)) >> 3;
2156 return res;
2157}
2158
2159/**
2160 * iwlagn_set_rxon_chain - Set up Rx chain usage in "staging" RXON image
2161 *
2162 * Selects how many and which Rx receivers/antennas/chains to use.
2163 * This should not be used for scan command ... it puts data in wrong place.
2164 */
2165void iwlagn_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
2166{
2167 bool is_single = is_single_rx_stream(priv);
2168 bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status);
2169 u8 idle_rx_cnt, active_rx_cnt, valid_rx_cnt;
2170 u32 active_chains;
2171 u16 rx_chain;
2172
2173 /* Tell uCode which antennas are actually connected.
2174 * Before first association, we assume all antennas are connected.
2175 * Just after first association, iwl_chain_noise_calibration()
2176 * checks which antennas actually *are* connected. */
2177 if (priv->chain_noise_data.active_chains)
2178 active_chains = priv->chain_noise_data.active_chains;
2179 else
2180 active_chains = priv->hw_params.valid_rx_ant;
2181
2182 if (priv->cfg->bt_params &&
2183 priv->cfg->bt_params->advanced_bt_coexist &&
2184 (priv->bt_full_concurrent ||
2185 priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) {
2186 /*
2187 * only use chain 'A' in bt high traffic load or
2188 * full concurrency mode
2189 */
2190 active_chains = first_antenna(active_chains);
2191 }
2192
2193 rx_chain = active_chains << RXON_RX_CHAIN_VALID_POS;
2194
2195 /* How many receivers should we use? */
2196 active_rx_cnt = iwl_get_active_rx_chain_count(priv);
2197 idle_rx_cnt = iwl_get_idle_rx_chain_count(priv, active_rx_cnt);
2198
2199
2200 /* correct rx chain count according hw settings
2201 * and chain noise calibration
2202 */
2203 valid_rx_cnt = iwl_count_chain_bitmap(active_chains);
2204 if (valid_rx_cnt < active_rx_cnt)
2205 active_rx_cnt = valid_rx_cnt;
2206
2207 if (valid_rx_cnt < idle_rx_cnt)
2208 idle_rx_cnt = valid_rx_cnt;
2209
2210 rx_chain |= active_rx_cnt << RXON_RX_CHAIN_MIMO_CNT_POS;
2211 rx_chain |= idle_rx_cnt << RXON_RX_CHAIN_CNT_POS;
2212
2213 ctx->staging.rx_chain = cpu_to_le16(rx_chain);
2214
2215 if (!is_single && (active_rx_cnt >= IWL_NUM_RX_CHAINS_SINGLE) && is_cam)
2216 ctx->staging.rx_chain |= RXON_RX_CHAIN_MIMO_FORCE_MSK;
2217 else
2218 ctx->staging.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK;
2219
2220 IWL_DEBUG_ASSOC(priv, "rx_chain=0x%X active=%d idle=%d\n",
2221 ctx->staging.rx_chain,
2222 active_rx_cnt, idle_rx_cnt);
2223
2224 WARN_ON(active_rx_cnt == 0 || idle_rx_cnt == 0 ||
2225 active_rx_cnt < idle_rx_cnt);
2226}
2227
2228u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant, u8 valid)
2229{
2230 int i;
2231 u8 ind = ant;
2232
2233 if (priv->band == IEEE80211_BAND_2GHZ &&
2234 priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)
2235 return 0;
2236
2237 for (i = 0; i < RATE_ANT_NUM - 1; i++) {
2238 ind = (ind + 1) < RATE_ANT_NUM ? ind + 1 : 0;
2239 if (valid & BIT(ind))
2240 return ind;
2241 }
2242 return ant;
2243}
2244
2245static const char *get_csr_string(int cmd)
2246{
2247 switch (cmd) {
2248 IWL_CMD(CSR_HW_IF_CONFIG_REG);
2249 IWL_CMD(CSR_INT_COALESCING);
2250 IWL_CMD(CSR_INT);
2251 IWL_CMD(CSR_INT_MASK);
2252 IWL_CMD(CSR_FH_INT_STATUS);
2253 IWL_CMD(CSR_GPIO_IN);
2254 IWL_CMD(CSR_RESET);
2255 IWL_CMD(CSR_GP_CNTRL);
2256 IWL_CMD(CSR_HW_REV);
2257 IWL_CMD(CSR_EEPROM_REG);
2258 IWL_CMD(CSR_EEPROM_GP);
2259 IWL_CMD(CSR_OTP_GP_REG);
2260 IWL_CMD(CSR_GIO_REG);
2261 IWL_CMD(CSR_GP_UCODE_REG);
2262 IWL_CMD(CSR_GP_DRIVER_REG);
2263 IWL_CMD(CSR_UCODE_DRV_GP1);
2264 IWL_CMD(CSR_UCODE_DRV_GP2);
2265 IWL_CMD(CSR_LED_REG);
2266 IWL_CMD(CSR_DRAM_INT_TBL_REG);
2267 IWL_CMD(CSR_GIO_CHICKEN_BITS);
2268 IWL_CMD(CSR_ANA_PLL_CFG);
2269 IWL_CMD(CSR_HW_REV_WA_REG);
2270 IWL_CMD(CSR_DBG_HPET_MEM_REG);
2271 default:
2272 return "UNKNOWN";
2273 }
2274}
2275
2276void iwl_dump_csr(struct iwl_priv *priv)
2277{
2278 int i;
2279 u32 csr_tbl[] = {
2280 CSR_HW_IF_CONFIG_REG,
2281 CSR_INT_COALESCING,
2282 CSR_INT,
2283 CSR_INT_MASK,
2284 CSR_FH_INT_STATUS,
2285 CSR_GPIO_IN,
2286 CSR_RESET,
2287 CSR_GP_CNTRL,
2288 CSR_HW_REV,
2289 CSR_EEPROM_REG,
2290 CSR_EEPROM_GP,
2291 CSR_OTP_GP_REG,
2292 CSR_GIO_REG,
2293 CSR_GP_UCODE_REG,
2294 CSR_GP_DRIVER_REG,
2295 CSR_UCODE_DRV_GP1,
2296 CSR_UCODE_DRV_GP2,
2297 CSR_LED_REG,
2298 CSR_DRAM_INT_TBL_REG,
2299 CSR_GIO_CHICKEN_BITS,
2300 CSR_ANA_PLL_CFG,
2301 CSR_HW_REV_WA_REG,
2302 CSR_DBG_HPET_MEM_REG
2303 };
2304 IWL_ERR(priv, "CSR values:\n");
2305 IWL_ERR(priv, "(2nd byte of CSR_INT_COALESCING is "
2306 "CSR_INT_PERIODIC_REG)\n");
2307 for (i = 0; i < ARRAY_SIZE(csr_tbl); i++) {
2308 IWL_ERR(priv, " %25s: 0X%08x\n",
2309 get_csr_string(csr_tbl[i]),
2310 iwl_read32(priv, csr_tbl[i]));
2311 }
2312}
2313
2314static const char *get_fh_string(int cmd)
2315{
2316 switch (cmd) {
2317 IWL_CMD(FH_RSCSR_CHNL0_STTS_WPTR_REG);
2318 IWL_CMD(FH_RSCSR_CHNL0_RBDCB_BASE_REG);
2319 IWL_CMD(FH_RSCSR_CHNL0_WPTR);
2320 IWL_CMD(FH_MEM_RCSR_CHNL0_CONFIG_REG);
2321 IWL_CMD(FH_MEM_RSSR_SHARED_CTRL_REG);
2322 IWL_CMD(FH_MEM_RSSR_RX_STATUS_REG);
2323 IWL_CMD(FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV);
2324 IWL_CMD(FH_TSSR_TX_STATUS_REG);
2325 IWL_CMD(FH_TSSR_TX_ERROR_REG);
2326 default:
2327 return "UNKNOWN";
2328 }
2329}
2330
2331int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display)
2332{
2333 int i;
2334#ifdef CONFIG_IWLWIFI_DEBUG
2335 int pos = 0;
2336 size_t bufsz = 0;
2337#endif
2338 u32 fh_tbl[] = {
2339 FH_RSCSR_CHNL0_STTS_WPTR_REG,
2340 FH_RSCSR_CHNL0_RBDCB_BASE_REG,
2341 FH_RSCSR_CHNL0_WPTR,
2342 FH_MEM_RCSR_CHNL0_CONFIG_REG,
2343 FH_MEM_RSSR_SHARED_CTRL_REG,
2344 FH_MEM_RSSR_RX_STATUS_REG,
2345 FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV,
2346 FH_TSSR_TX_STATUS_REG,
2347 FH_TSSR_TX_ERROR_REG
2348 };
2349#ifdef CONFIG_IWLWIFI_DEBUG
2350 if (display) {
2351 bufsz = ARRAY_SIZE(fh_tbl) * 48 + 40;
2352 *buf = kmalloc(bufsz, GFP_KERNEL);
2353 if (!*buf)
2354 return -ENOMEM;
2355 pos += scnprintf(*buf + pos, bufsz - pos,
2356 "FH register values:\n");
2357 for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) {
2358 pos += scnprintf(*buf + pos, bufsz - pos,
2359 " %34s: 0X%08x\n",
2360 get_fh_string(fh_tbl[i]),
2361 iwl_read_direct32(priv, fh_tbl[i]));
2362 }
2363 return pos;
2364 }
2365#endif
2366 IWL_ERR(priv, "FH register values:\n");
2367 for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) {
2368 IWL_ERR(priv, " %34s: 0X%08x\n",
2369 get_fh_string(fh_tbl[i]),
2370 iwl_read_direct32(priv, fh_tbl[i]));
2371 }
2372 return 0;
2373}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index f865685fd5f5..5abe2e9ff0d2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -39,6 +39,7 @@
39#include "iwl-dev.h" 39#include "iwl-dev.h"
40#include "iwl-sta.h" 40#include "iwl-sta.h"
41#include "iwl-core.h" 41#include "iwl-core.h"
42#include "iwl-agn.h"
42 43
43#define RS_NAME "iwl-agn-rs" 44#define RS_NAME "iwl-agn-rs"
44 45
@@ -76,6 +77,74 @@ static const u8 ant_toggle_lookup[] = {
76 /*ANT_ABC -> */ ANT_ABC, 77 /*ANT_ABC -> */ ANT_ABC,
77}; 78};
78 79
80#define IWL_DECLARE_RATE_INFO(r, s, ip, in, rp, rn, pp, np) \
81 [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \
82 IWL_RATE_SISO_##s##M_PLCP, \
83 IWL_RATE_MIMO2_##s##M_PLCP,\
84 IWL_RATE_MIMO3_##s##M_PLCP,\
85 IWL_RATE_##r##M_IEEE, \
86 IWL_RATE_##ip##M_INDEX, \
87 IWL_RATE_##in##M_INDEX, \
88 IWL_RATE_##rp##M_INDEX, \
89 IWL_RATE_##rn##M_INDEX, \
90 IWL_RATE_##pp##M_INDEX, \
91 IWL_RATE_##np##M_INDEX }
92
93/*
94 * Parameter order:
95 * rate, ht rate, prev rate, next rate, prev tgg rate, next tgg rate
96 *
97 * If there isn't a valid next or previous rate then INV is used which
98 * maps to IWL_RATE_INVALID
99 *
100 */
101const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT] = {
102 IWL_DECLARE_RATE_INFO(1, INV, INV, 2, INV, 2, INV, 2), /* 1mbps */
103 IWL_DECLARE_RATE_INFO(2, INV, 1, 5, 1, 5, 1, 5), /* 2mbps */
104 IWL_DECLARE_RATE_INFO(5, INV, 2, 6, 2, 11, 2, 11), /*5.5mbps */
105 IWL_DECLARE_RATE_INFO(11, INV, 9, 12, 9, 12, 5, 18), /* 11mbps */
106 IWL_DECLARE_RATE_INFO(6, 6, 5, 9, 5, 11, 5, 11), /* 6mbps */
107 IWL_DECLARE_RATE_INFO(9, 6, 6, 11, 6, 11, 5, 11), /* 9mbps */
108 IWL_DECLARE_RATE_INFO(12, 12, 11, 18, 11, 18, 11, 18), /* 12mbps */
109 IWL_DECLARE_RATE_INFO(18, 18, 12, 24, 12, 24, 11, 24), /* 18mbps */
110 IWL_DECLARE_RATE_INFO(24, 24, 18, 36, 18, 36, 18, 36), /* 24mbps */
111 IWL_DECLARE_RATE_INFO(36, 36, 24, 48, 24, 48, 24, 48), /* 36mbps */
112 IWL_DECLARE_RATE_INFO(48, 48, 36, 54, 36, 54, 36, 54), /* 48mbps */
113 IWL_DECLARE_RATE_INFO(54, 54, 48, INV, 48, INV, 48, INV),/* 54mbps */
114 IWL_DECLARE_RATE_INFO(60, 60, 48, INV, 48, INV, 48, INV),/* 60mbps */
115 /* FIXME:RS: ^^ should be INV (legacy) */
116};
117
118static int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
119{
120 int idx = 0;
121
122 /* HT rate format */
123 if (rate_n_flags & RATE_MCS_HT_MSK) {
124 idx = (rate_n_flags & 0xff);
125
126 if (idx >= IWL_RATE_MIMO3_6M_PLCP)
127 idx = idx - IWL_RATE_MIMO3_6M_PLCP;
128 else if (idx >= IWL_RATE_MIMO2_6M_PLCP)
129 idx = idx - IWL_RATE_MIMO2_6M_PLCP;
130
131 idx += IWL_FIRST_OFDM_RATE;
132 /* skip 9M not supported in ht*/
133 if (idx >= IWL_RATE_9M_INDEX)
134 idx += 1;
135 if ((idx >= IWL_FIRST_OFDM_RATE) && (idx <= IWL_LAST_OFDM_RATE))
136 return idx;
137
138 /* legacy rate format, search for match in table */
139 } else {
140 for (idx = 0; idx < ARRAY_SIZE(iwl_rates); idx++)
141 if (iwl_rates[idx].plcp == (rate_n_flags & 0xFF))
142 return idx;
143 }
144
145 return -1;
146}
147
79static void rs_rate_scale_perform(struct iwl_priv *priv, 148static void rs_rate_scale_perform(struct iwl_priv *priv,
80 struct sk_buff *skb, 149 struct sk_buff *skb,
81 struct ieee80211_sta *sta, 150 struct ieee80211_sta *sta,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
index 357cdb26f16d..75e50d33ecb3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
@@ -299,7 +299,6 @@ enum {
299#define TIME_WRAP_AROUND(x, y) (((y) > (x)) ? (y) - (x) : (0-(x)) + (y)) 299#define TIME_WRAP_AROUND(x, y) (((y) > (x)) ? (y) - (x) : (0-(x)) + (y))
300 300
301extern const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT]; 301extern const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT];
302extern const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT_3945];
303 302
304enum iwl_table_type { 303enum iwl_table_type {
305 LQ_NONE, 304 LQ_NONE,
@@ -453,15 +452,6 @@ static inline u8 first_antenna(u8 mask)
453} 452}
454 453
455 454
456static inline u8 iwl3945_get_prev_ieee_rate(u8 rate_index)
457{
458 u8 rate = iwl3945_rates[rate_index].prev_ieee;
459
460 if (rate == IWL_RATE_INVALID)
461 rate = rate_index;
462 return rate;
463}
464
465/** 455/**
466 * iwl3945_rate_scale_init - Initialize the rate scale table based on assoc info 456 * iwl3945_rate_scale_init - Initialize the rate scale table based on assoc info
467 * 457 *
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
index 1e08eb455474..bbd40b7dd597 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
@@ -34,7 +34,7 @@
34 34
35#include "iwl-dev.h" 35#include "iwl-dev.h"
36#include "iwl-core.h" 36#include "iwl-core.h"
37#include "iwl-calib.h" 37#include "iwl-agn-calib.h"
38#include "iwl-sta.h" 38#include "iwl-sta.h"
39#include "iwl-io.h" 39#include "iwl-io.h"
40#include "iwl-helpers.h" 40#include "iwl-helpers.h"
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
new file mode 100644
index 000000000000..35a30d2e0734
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
@@ -0,0 +1,716 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 *
5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of version 2 of the GNU General Public License as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
20 *
21 * The full GNU General Public License is included in this distribution in the
22 * file called LICENSE.
23 *
24 * Contact Information:
25 * Intel Linux Wireless <ilw@linux.intel.com>
26 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27 *
28 *****************************************************************************/
29
30#include <net/mac80211.h>
31
32#include "iwl-dev.h"
33#include "iwl-core.h"
34#include "iwl-sta.h"
35#include "iwl-agn.h"
36
37static struct iwl_link_quality_cmd *
38iwl_sta_alloc_lq(struct iwl_priv *priv, u8 sta_id)
39{
40 int i, r;
41 struct iwl_link_quality_cmd *link_cmd;
42 u32 rate_flags = 0;
43 __le32 rate_n_flags;
44
45 link_cmd = kzalloc(sizeof(struct iwl_link_quality_cmd), GFP_KERNEL);
46 if (!link_cmd) {
47 IWL_ERR(priv, "Unable to allocate memory for LQ cmd.\n");
48 return NULL;
49 }
50 /* Set up the rate scaling to start at selected rate, fall back
51 * all the way down to 1M in IEEE order, and then spin on 1M */
52 if (priv->band == IEEE80211_BAND_5GHZ)
53 r = IWL_RATE_6M_INDEX;
54 else
55 r = IWL_RATE_1M_INDEX;
56
57 if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE)
58 rate_flags |= RATE_MCS_CCK_MSK;
59
60 rate_flags |= first_antenna(priv->hw_params.valid_tx_ant) <<
61 RATE_MCS_ANT_POS;
62 rate_n_flags = iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags);
63 for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++)
64 link_cmd->rs_table[i].rate_n_flags = rate_n_flags;
65
66 link_cmd->general_params.single_stream_ant_msk =
67 first_antenna(priv->hw_params.valid_tx_ant);
68
69 link_cmd->general_params.dual_stream_ant_msk =
70 priv->hw_params.valid_tx_ant &
71 ~first_antenna(priv->hw_params.valid_tx_ant);
72 if (!link_cmd->general_params.dual_stream_ant_msk) {
73 link_cmd->general_params.dual_stream_ant_msk = ANT_AB;
74 } else if (num_of_ant(priv->hw_params.valid_tx_ant) == 2) {
75 link_cmd->general_params.dual_stream_ant_msk =
76 priv->hw_params.valid_tx_ant;
77 }
78
79 link_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
80 link_cmd->agg_params.agg_time_limit =
81 cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
82
83 link_cmd->sta_id = sta_id;
84
85 return link_cmd;
86}
87
88/*
89 * iwlagn_add_bssid_station - Add the special IBSS BSSID station
90 *
91 * Function sleeps.
92 */
93int iwlagn_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
94 const u8 *addr, u8 *sta_id_r)
95{
96 int ret;
97 u8 sta_id;
98 struct iwl_link_quality_cmd *link_cmd;
99 unsigned long flags;
100
101 if (sta_id_r)
102 *sta_id_r = IWL_INVALID_STATION;
103
104 ret = iwl_add_station_common(priv, ctx, addr, 0, NULL, &sta_id);
105 if (ret) {
106 IWL_ERR(priv, "Unable to add station %pM\n", addr);
107 return ret;
108 }
109
110 if (sta_id_r)
111 *sta_id_r = sta_id;
112
113 spin_lock_irqsave(&priv->sta_lock, flags);
114 priv->stations[sta_id].used |= IWL_STA_LOCAL;
115 spin_unlock_irqrestore(&priv->sta_lock, flags);
116
117 /* Set up default rate scaling table in device's station table */
118 link_cmd = iwl_sta_alloc_lq(priv, sta_id);
119 if (!link_cmd) {
120 IWL_ERR(priv, "Unable to initialize rate scaling for station %pM.\n",
121 addr);
122 return -ENOMEM;
123 }
124
125 ret = iwl_send_lq_cmd(priv, ctx, link_cmd, CMD_SYNC, true);
126 if (ret)
127 IWL_ERR(priv, "Link quality command failed (%d)\n", ret);
128
129 spin_lock_irqsave(&priv->sta_lock, flags);
130 priv->stations[sta_id].lq = link_cmd;
131 spin_unlock_irqrestore(&priv->sta_lock, flags);
132
133 return 0;
134}
135
136static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv,
137 struct iwl_rxon_context *ctx,
138 bool send_if_empty)
139{
140 int i, not_empty = 0;
141 u8 buff[sizeof(struct iwl_wep_cmd) +
142 sizeof(struct iwl_wep_key) * WEP_KEYS_MAX];
143 struct iwl_wep_cmd *wep_cmd = (struct iwl_wep_cmd *)buff;
144 size_t cmd_size = sizeof(struct iwl_wep_cmd);
145 struct iwl_host_cmd cmd = {
146 .id = ctx->wep_key_cmd,
147 .data = wep_cmd,
148 .flags = CMD_SYNC,
149 };
150
151 might_sleep();
152
153 memset(wep_cmd, 0, cmd_size +
154 (sizeof(struct iwl_wep_key) * WEP_KEYS_MAX));
155
156 for (i = 0; i < WEP_KEYS_MAX ; i++) {
157 wep_cmd->key[i].key_index = i;
158 if (ctx->wep_keys[i].key_size) {
159 wep_cmd->key[i].key_offset = i;
160 not_empty = 1;
161 } else {
162 wep_cmd->key[i].key_offset = WEP_INVALID_OFFSET;
163 }
164
165 wep_cmd->key[i].key_size = ctx->wep_keys[i].key_size;
166 memcpy(&wep_cmd->key[i].key[3], ctx->wep_keys[i].key,
167 ctx->wep_keys[i].key_size);
168 }
169
170 wep_cmd->global_key_type = WEP_KEY_WEP_TYPE;
171 wep_cmd->num_keys = WEP_KEYS_MAX;
172
173 cmd_size += sizeof(struct iwl_wep_key) * WEP_KEYS_MAX;
174
175 cmd.len = cmd_size;
176
177 if (not_empty || send_if_empty)
178 return iwl_send_cmd(priv, &cmd);
179 else
180 return 0;
181}
182
183int iwl_restore_default_wep_keys(struct iwl_priv *priv,
184 struct iwl_rxon_context *ctx)
185{
186 lockdep_assert_held(&priv->mutex);
187
188 return iwl_send_static_wepkey_cmd(priv, ctx, false);
189}
190
191int iwl_remove_default_wep_key(struct iwl_priv *priv,
192 struct iwl_rxon_context *ctx,
193 struct ieee80211_key_conf *keyconf)
194{
195 int ret;
196
197 lockdep_assert_held(&priv->mutex);
198
199 IWL_DEBUG_WEP(priv, "Removing default WEP key: idx=%d\n",
200 keyconf->keyidx);
201
202 memset(&ctx->wep_keys[keyconf->keyidx], 0, sizeof(ctx->wep_keys[0]));
203 if (iwl_is_rfkill(priv)) {
204 IWL_DEBUG_WEP(priv, "Not sending REPLY_WEPKEY command due to RFKILL.\n");
205 /* but keys in device are clear anyway so return success */
206 return 0;
207 }
208 ret = iwl_send_static_wepkey_cmd(priv, ctx, 1);
209 IWL_DEBUG_WEP(priv, "Remove default WEP key: idx=%d ret=%d\n",
210 keyconf->keyidx, ret);
211
212 return ret;
213}
214
215int iwl_set_default_wep_key(struct iwl_priv *priv,
216 struct iwl_rxon_context *ctx,
217 struct ieee80211_key_conf *keyconf)
218{
219 int ret;
220
221 lockdep_assert_held(&priv->mutex);
222
223 if (keyconf->keylen != WEP_KEY_LEN_128 &&
224 keyconf->keylen != WEP_KEY_LEN_64) {
225 IWL_DEBUG_WEP(priv, "Bad WEP key length %d\n", keyconf->keylen);
226 return -EINVAL;
227 }
228
229 keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV;
230 keyconf->hw_key_idx = HW_KEY_DEFAULT;
231 priv->stations[ctx->ap_sta_id].keyinfo.cipher = keyconf->cipher;
232
233 ctx->wep_keys[keyconf->keyidx].key_size = keyconf->keylen;
234 memcpy(&ctx->wep_keys[keyconf->keyidx].key, &keyconf->key,
235 keyconf->keylen);
236
237 ret = iwl_send_static_wepkey_cmd(priv, ctx, false);
238 IWL_DEBUG_WEP(priv, "Set default WEP key: len=%d idx=%d ret=%d\n",
239 keyconf->keylen, keyconf->keyidx, ret);
240
241 return ret;
242}
243
244static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv,
245 struct iwl_rxon_context *ctx,
246 struct ieee80211_key_conf *keyconf,
247 u8 sta_id)
248{
249 unsigned long flags;
250 __le16 key_flags = 0;
251 struct iwl_addsta_cmd sta_cmd;
252
253 lockdep_assert_held(&priv->mutex);
254
255 keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV;
256
257 key_flags |= (STA_KEY_FLG_WEP | STA_KEY_FLG_MAP_KEY_MSK);
258 key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
259 key_flags &= ~STA_KEY_FLG_INVALID;
260
261 if (keyconf->keylen == WEP_KEY_LEN_128)
262 key_flags |= STA_KEY_FLG_KEY_SIZE_MSK;
263
264 if (sta_id == ctx->bcast_sta_id)
265 key_flags |= STA_KEY_MULTICAST_MSK;
266
267 spin_lock_irqsave(&priv->sta_lock, flags);
268
269 priv->stations[sta_id].keyinfo.cipher = keyconf->cipher;
270 priv->stations[sta_id].keyinfo.keylen = keyconf->keylen;
271 priv->stations[sta_id].keyinfo.keyidx = keyconf->keyidx;
272
273 memcpy(priv->stations[sta_id].keyinfo.key,
274 keyconf->key, keyconf->keylen);
275
276 memcpy(&priv->stations[sta_id].sta.key.key[3],
277 keyconf->key, keyconf->keylen);
278
279 if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
280 == STA_KEY_FLG_NO_ENC)
281 priv->stations[sta_id].sta.key.key_offset =
282 iwl_get_free_ucode_key_index(priv);
283 /* else, we are overriding an existing key => no need to allocated room
284 * in uCode. */
285
286 WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
287 "no space for a new key");
288
289 priv->stations[sta_id].sta.key.key_flags = key_flags;
290 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
291 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
292
293 memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
294 spin_unlock_irqrestore(&priv->sta_lock, flags);
295
296 return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
297}
298
299static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
300 struct iwl_rxon_context *ctx,
301 struct ieee80211_key_conf *keyconf,
302 u8 sta_id)
303{
304 unsigned long flags;
305 __le16 key_flags = 0;
306 struct iwl_addsta_cmd sta_cmd;
307
308 lockdep_assert_held(&priv->mutex);
309
310 key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK);
311 key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
312 key_flags &= ~STA_KEY_FLG_INVALID;
313
314 if (sta_id == ctx->bcast_sta_id)
315 key_flags |= STA_KEY_MULTICAST_MSK;
316
317 keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
318
319 spin_lock_irqsave(&priv->sta_lock, flags);
320 priv->stations[sta_id].keyinfo.cipher = keyconf->cipher;
321 priv->stations[sta_id].keyinfo.keylen = keyconf->keylen;
322
323 memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key,
324 keyconf->keylen);
325
326 memcpy(priv->stations[sta_id].sta.key.key, keyconf->key,
327 keyconf->keylen);
328
329 if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
330 == STA_KEY_FLG_NO_ENC)
331 priv->stations[sta_id].sta.key.key_offset =
332 iwl_get_free_ucode_key_index(priv);
333 /* else, we are overriding an existing key => no need to allocated room
334 * in uCode. */
335
336 WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
337 "no space for a new key");
338
339 priv->stations[sta_id].sta.key.key_flags = key_flags;
340 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
341 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
342
343 memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
344 spin_unlock_irqrestore(&priv->sta_lock, flags);
345
346 return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
347}
348
349static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv,
350 struct iwl_rxon_context *ctx,
351 struct ieee80211_key_conf *keyconf,
352 u8 sta_id)
353{
354 unsigned long flags;
355 int ret = 0;
356 __le16 key_flags = 0;
357
358 key_flags |= (STA_KEY_FLG_TKIP | STA_KEY_FLG_MAP_KEY_MSK);
359 key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
360 key_flags &= ~STA_KEY_FLG_INVALID;
361
362 if (sta_id == ctx->bcast_sta_id)
363 key_flags |= STA_KEY_MULTICAST_MSK;
364
365 keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
366 keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
367
368 spin_lock_irqsave(&priv->sta_lock, flags);
369
370 priv->stations[sta_id].keyinfo.cipher = keyconf->cipher;
371 priv->stations[sta_id].keyinfo.keylen = 16;
372
373 if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
374 == STA_KEY_FLG_NO_ENC)
375 priv->stations[sta_id].sta.key.key_offset =
376 iwl_get_free_ucode_key_index(priv);
377 /* else, we are overriding an existing key => no need to allocated room
378 * in uCode. */
379
380 WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
381 "no space for a new key");
382
383 priv->stations[sta_id].sta.key.key_flags = key_flags;
384
385
386 /* This copy is acutally not needed: we get the key with each TX */
387 memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, 16);
388
389 memcpy(priv->stations[sta_id].sta.key.key, keyconf->key, 16);
390
391 spin_unlock_irqrestore(&priv->sta_lock, flags);
392
393 return ret;
394}
395
396void iwl_update_tkip_key(struct iwl_priv *priv,
397 struct iwl_rxon_context *ctx,
398 struct ieee80211_key_conf *keyconf,
399 struct ieee80211_sta *sta, u32 iv32, u16 *phase1key)
400{
401 u8 sta_id;
402 unsigned long flags;
403 int i;
404
405 if (iwl_scan_cancel(priv)) {
406 /* cancel scan failed, just live w/ bad key and rely
407 briefly on SW decryption */
408 return;
409 }
410
411 sta_id = iwl_sta_id_or_broadcast(priv, ctx, sta);
412 if (sta_id == IWL_INVALID_STATION)
413 return;
414
415 spin_lock_irqsave(&priv->sta_lock, flags);
416
417 priv->stations[sta_id].sta.key.tkip_rx_tsc_byte2 = (u8) iv32;
418
419 for (i = 0; i < 5; i++)
420 priv->stations[sta_id].sta.key.tkip_rx_ttak[i] =
421 cpu_to_le16(phase1key[i]);
422
423 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
424 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
425
426 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
427
428 spin_unlock_irqrestore(&priv->sta_lock, flags);
429
430}
431
432int iwl_remove_dynamic_key(struct iwl_priv *priv,
433 struct iwl_rxon_context *ctx,
434 struct ieee80211_key_conf *keyconf,
435 u8 sta_id)
436{
437 unsigned long flags;
438 u16 key_flags;
439 u8 keyidx;
440 struct iwl_addsta_cmd sta_cmd;
441
442 lockdep_assert_held(&priv->mutex);
443
444 ctx->key_mapping_keys--;
445
446 spin_lock_irqsave(&priv->sta_lock, flags);
447 key_flags = le16_to_cpu(priv->stations[sta_id].sta.key.key_flags);
448 keyidx = (key_flags >> STA_KEY_FLG_KEYID_POS) & 0x3;
449
450 IWL_DEBUG_WEP(priv, "Remove dynamic key: idx=%d sta=%d\n",
451 keyconf->keyidx, sta_id);
452
453 if (keyconf->keyidx != keyidx) {
454 /* We need to remove a key with index different that the one
455 * in the uCode. This means that the key we need to remove has
456 * been replaced by another one with different index.
457 * Don't do anything and return ok
458 */
459 spin_unlock_irqrestore(&priv->sta_lock, flags);
460 return 0;
461 }
462
463 if (priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET) {
464 IWL_WARN(priv, "Removing wrong key %d 0x%x\n",
465 keyconf->keyidx, key_flags);
466 spin_unlock_irqrestore(&priv->sta_lock, flags);
467 return 0;
468 }
469
470 if (!test_and_clear_bit(priv->stations[sta_id].sta.key.key_offset,
471 &priv->ucode_key_table))
472 IWL_ERR(priv, "index %d not used in uCode key table.\n",
473 priv->stations[sta_id].sta.key.key_offset);
474 memset(&priv->stations[sta_id].keyinfo, 0,
475 sizeof(struct iwl_hw_key));
476 memset(&priv->stations[sta_id].sta.key, 0,
477 sizeof(struct iwl4965_keyinfo));
478 priv->stations[sta_id].sta.key.key_flags =
479 STA_KEY_FLG_NO_ENC | STA_KEY_FLG_INVALID;
480 priv->stations[sta_id].sta.key.key_offset = WEP_INVALID_OFFSET;
481 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
482 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
483
484 if (iwl_is_rfkill(priv)) {
485 IWL_DEBUG_WEP(priv, "Not sending REPLY_ADD_STA command because RFKILL enabled.\n");
486 spin_unlock_irqrestore(&priv->sta_lock, flags);
487 return 0;
488 }
489 memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
490 spin_unlock_irqrestore(&priv->sta_lock, flags);
491
492 return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
493}
494
495int iwl_set_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
496 struct ieee80211_key_conf *keyconf, u8 sta_id)
497{
498 int ret;
499
500 lockdep_assert_held(&priv->mutex);
501
502 ctx->key_mapping_keys++;
503 keyconf->hw_key_idx = HW_KEY_DYNAMIC;
504
505 switch (keyconf->cipher) {
506 case WLAN_CIPHER_SUITE_CCMP:
507 ret = iwl_set_ccmp_dynamic_key_info(priv, ctx, keyconf, sta_id);
508 break;
509 case WLAN_CIPHER_SUITE_TKIP:
510 ret = iwl_set_tkip_dynamic_key_info(priv, ctx, keyconf, sta_id);
511 break;
512 case WLAN_CIPHER_SUITE_WEP40:
513 case WLAN_CIPHER_SUITE_WEP104:
514 ret = iwl_set_wep_dynamic_key_info(priv, ctx, keyconf, sta_id);
515 break;
516 default:
517 IWL_ERR(priv,
518 "Unknown alg: %s cipher = %x\n", __func__,
519 keyconf->cipher);
520 ret = -EINVAL;
521 }
522
523 IWL_DEBUG_WEP(priv, "Set dynamic key: cipher=%x len=%d idx=%d sta=%d ret=%d\n",
524 keyconf->cipher, keyconf->keylen, keyconf->keyidx,
525 sta_id, ret);
526
527 return ret;
528}
529
530/**
531 * iwlagn_alloc_bcast_station - add broadcast station into driver's station table.
532 *
533 * This adds the broadcast station into the driver's station table
534 * and marks it driver active, so that it will be restored to the
535 * device at the next best time.
536 */
537int iwlagn_alloc_bcast_station(struct iwl_priv *priv,
538 struct iwl_rxon_context *ctx)
539{
540 struct iwl_link_quality_cmd *link_cmd;
541 unsigned long flags;
542 u8 sta_id;
543
544 spin_lock_irqsave(&priv->sta_lock, flags);
545 sta_id = iwl_prep_station(priv, ctx, iwl_bcast_addr, false, NULL);
546 if (sta_id == IWL_INVALID_STATION) {
547 IWL_ERR(priv, "Unable to prepare broadcast station\n");
548 spin_unlock_irqrestore(&priv->sta_lock, flags);
549
550 return -EINVAL;
551 }
552
553 priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE;
554 priv->stations[sta_id].used |= IWL_STA_BCAST;
555 spin_unlock_irqrestore(&priv->sta_lock, flags);
556
557 link_cmd = iwl_sta_alloc_lq(priv, sta_id);
558 if (!link_cmd) {
559 IWL_ERR(priv,
560 "Unable to initialize rate scaling for bcast station.\n");
561 return -ENOMEM;
562 }
563
564 spin_lock_irqsave(&priv->sta_lock, flags);
565 priv->stations[sta_id].lq = link_cmd;
566 spin_unlock_irqrestore(&priv->sta_lock, flags);
567
568 return 0;
569}
570
571/**
572 * iwl_update_bcast_station - update broadcast station's LQ command
573 *
574 * Only used by iwlagn. Placed here to have all bcast station management
575 * code together.
576 */
577static int iwl_update_bcast_station(struct iwl_priv *priv,
578 struct iwl_rxon_context *ctx)
579{
580 unsigned long flags;
581 struct iwl_link_quality_cmd *link_cmd;
582 u8 sta_id = ctx->bcast_sta_id;
583
584 link_cmd = iwl_sta_alloc_lq(priv, sta_id);
585 if (!link_cmd) {
586 IWL_ERR(priv, "Unable to initialize rate scaling for bcast station.\n");
587 return -ENOMEM;
588 }
589
590 spin_lock_irqsave(&priv->sta_lock, flags);
591 if (priv->stations[sta_id].lq)
592 kfree(priv->stations[sta_id].lq);
593 else
594 IWL_DEBUG_INFO(priv, "Bcast station rate scaling has not been initialized yet.\n");
595 priv->stations[sta_id].lq = link_cmd;
596 spin_unlock_irqrestore(&priv->sta_lock, flags);
597
598 return 0;
599}
600
601int iwl_update_bcast_stations(struct iwl_priv *priv)
602{
603 struct iwl_rxon_context *ctx;
604 int ret = 0;
605
606 for_each_context(priv, ctx) {
607 ret = iwl_update_bcast_station(priv, ctx);
608 if (ret)
609 break;
610 }
611
612 return ret;
613}
614
615/**
616 * iwl_sta_tx_modify_enable_tid - Enable Tx for this TID in station table
617 */
618int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid)
619{
620 unsigned long flags;
621 struct iwl_addsta_cmd sta_cmd;
622
623 lockdep_assert_held(&priv->mutex);
624
625 /* Remove "disable" flag, to enable Tx for this TID */
626 spin_lock_irqsave(&priv->sta_lock, flags);
627 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_TID_DISABLE_TX;
628 priv->stations[sta_id].sta.tid_disable_tx &= cpu_to_le16(~(1 << tid));
629 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
630 memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
631 spin_unlock_irqrestore(&priv->sta_lock, flags);
632
633 return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
634}
635
636int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta,
637 int tid, u16 ssn)
638{
639 unsigned long flags;
640 int sta_id;
641 struct iwl_addsta_cmd sta_cmd;
642
643 lockdep_assert_held(&priv->mutex);
644
645 sta_id = iwl_sta_id(sta);
646 if (sta_id == IWL_INVALID_STATION)
647 return -ENXIO;
648
649 spin_lock_irqsave(&priv->sta_lock, flags);
650 priv->stations[sta_id].sta.station_flags_msk = 0;
651 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_ADDBA_TID_MSK;
652 priv->stations[sta_id].sta.add_immediate_ba_tid = (u8)tid;
653 priv->stations[sta_id].sta.add_immediate_ba_ssn = cpu_to_le16(ssn);
654 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
655 memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
656 spin_unlock_irqrestore(&priv->sta_lock, flags);
657
658 return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
659}
660
661int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
662 int tid)
663{
664 unsigned long flags;
665 int sta_id;
666 struct iwl_addsta_cmd sta_cmd;
667
668 lockdep_assert_held(&priv->mutex);
669
670 sta_id = iwl_sta_id(sta);
671 if (sta_id == IWL_INVALID_STATION) {
672 IWL_ERR(priv, "Invalid station for AGG tid %d\n", tid);
673 return -ENXIO;
674 }
675
676 spin_lock_irqsave(&priv->sta_lock, flags);
677 priv->stations[sta_id].sta.station_flags_msk = 0;
678 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_DELBA_TID_MSK;
679 priv->stations[sta_id].sta.remove_immediate_ba_tid = (u8)tid;
680 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
681 memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
682 spin_unlock_irqrestore(&priv->sta_lock, flags);
683
684 return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
685}
686
687void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id)
688{
689 unsigned long flags;
690
691 spin_lock_irqsave(&priv->sta_lock, flags);
692 priv->stations[sta_id].sta.station_flags &= ~STA_FLG_PWR_SAVE_MSK;
693 priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK;
694 priv->stations[sta_id].sta.sta.modify_mask = 0;
695 priv->stations[sta_id].sta.sleep_tx_count = 0;
696 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
697 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
698 spin_unlock_irqrestore(&priv->sta_lock, flags);
699
700}
701
702void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt)
703{
704 unsigned long flags;
705
706 spin_lock_irqsave(&priv->sta_lock, flags);
707 priv->stations[sta_id].sta.station_flags |= STA_FLG_PWR_SAVE_MSK;
708 priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK;
709 priv->stations[sta_id].sta.sta.modify_mask =
710 STA_MODIFY_SLEEP_TX_COUNT_MSK;
711 priv->stations[sta_id].sta.sleep_tx_count = cpu_to_le16(cnt);
712 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
713 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
714 spin_unlock_irqrestore(&priv->sta_lock, flags);
715
716}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c
index 0c6c4d969706..e3a8216a033c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c
@@ -571,7 +571,6 @@ void iwl_tt_enter_ct_kill(struct iwl_priv *priv)
571 IWL_DEBUG_POWER(priv, "Queueing critical temperature enter.\n"); 571 IWL_DEBUG_POWER(priv, "Queueing critical temperature enter.\n");
572 queue_work(priv->workqueue, &priv->ct_enter); 572 queue_work(priv->workqueue, &priv->ct_enter);
573} 573}
574EXPORT_SYMBOL(iwl_tt_enter_ct_kill);
575 574
576void iwl_tt_exit_ct_kill(struct iwl_priv *priv) 575void iwl_tt_exit_ct_kill(struct iwl_priv *priv)
577{ 576{
@@ -581,7 +580,6 @@ void iwl_tt_exit_ct_kill(struct iwl_priv *priv)
581 IWL_DEBUG_POWER(priv, "Queueing critical temperature exit.\n"); 580 IWL_DEBUG_POWER(priv, "Queueing critical temperature exit.\n");
582 queue_work(priv->workqueue, &priv->ct_exit); 581 queue_work(priv->workqueue, &priv->ct_exit);
583} 582}
584EXPORT_SYMBOL(iwl_tt_exit_ct_kill);
585 583
586static void iwl_bg_tt_work(struct work_struct *work) 584static void iwl_bg_tt_work(struct work_struct *work)
587{ 585{
@@ -608,7 +606,6 @@ void iwl_tt_handler(struct iwl_priv *priv)
608 IWL_DEBUG_POWER(priv, "Queueing thermal throttling work.\n"); 606 IWL_DEBUG_POWER(priv, "Queueing thermal throttling work.\n");
609 queue_work(priv->workqueue, &priv->tt_work); 607 queue_work(priv->workqueue, &priv->tt_work);
610} 608}
611EXPORT_SYMBOL(iwl_tt_handler);
612 609
613/* Thermal throttling initialization 610/* Thermal throttling initialization
614 * For advance thermal throttling: 611 * For advance thermal throttling:
@@ -678,7 +675,6 @@ void iwl_tt_initialize(struct iwl_priv *priv)
678 priv->thermal_throttle.advanced_tt = false; 675 priv->thermal_throttle.advanced_tt = false;
679 } 676 }
680} 677}
681EXPORT_SYMBOL(iwl_tt_initialize);
682 678
683/* cleanup thermal throttling management related memory and timer */ 679/* cleanup thermal throttling management related memory and timer */
684void iwl_tt_exit(struct iwl_priv *priv) 680void iwl_tt_exit(struct iwl_priv *priv)
@@ -701,4 +697,3 @@ void iwl_tt_exit(struct iwl_priv *priv)
701 tt->transaction = NULL; 697 tt->transaction = NULL;
702 } 698 }
703} 699}
704EXPORT_SYMBOL(iwl_tt_exit);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index 77753b72f236..db57aea629d9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -1391,3 +1391,43 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
1391 1391
1392 spin_unlock_irqrestore(&priv->sta_lock, flags); 1392 spin_unlock_irqrestore(&priv->sta_lock, flags);
1393} 1393}
1394
1395#ifdef CONFIG_IWLWIFI_DEBUG
1396const char *iwl_get_tx_fail_reason(u32 status)
1397{
1398#define TX_STATUS_FAIL(x) case TX_STATUS_FAIL_ ## x: return #x
1399#define TX_STATUS_POSTPONE(x) case TX_STATUS_POSTPONE_ ## x: return #x
1400
1401 switch (status & TX_STATUS_MSK) {
1402 case TX_STATUS_SUCCESS:
1403 return "SUCCESS";
1404 TX_STATUS_POSTPONE(DELAY);
1405 TX_STATUS_POSTPONE(FEW_BYTES);
1406 TX_STATUS_POSTPONE(BT_PRIO);
1407 TX_STATUS_POSTPONE(QUIET_PERIOD);
1408 TX_STATUS_POSTPONE(CALC_TTAK);
1409 TX_STATUS_FAIL(INTERNAL_CROSSED_RETRY);
1410 TX_STATUS_FAIL(SHORT_LIMIT);
1411 TX_STATUS_FAIL(LONG_LIMIT);
1412 TX_STATUS_FAIL(FIFO_UNDERRUN);
1413 TX_STATUS_FAIL(DRAIN_FLOW);
1414 TX_STATUS_FAIL(RFKILL_FLUSH);
1415 TX_STATUS_FAIL(LIFE_EXPIRE);
1416 TX_STATUS_FAIL(DEST_PS);
1417 TX_STATUS_FAIL(HOST_ABORTED);
1418 TX_STATUS_FAIL(BT_RETRY);
1419 TX_STATUS_FAIL(STA_INVALID);
1420 TX_STATUS_FAIL(FRAG_DROPPED);
1421 TX_STATUS_FAIL(TID_DISABLE);
1422 TX_STATUS_FAIL(FIFO_FLUSHED);
1423 TX_STATUS_FAIL(INSUFFICIENT_CF_POLL);
1424 TX_STATUS_FAIL(PASSIVE_NO_RX);
1425 TX_STATUS_FAIL(NO_BEACON_ON_RADAR);
1426 }
1427
1428 return "UNKNOWN";
1429
1430#undef TX_STATUS_FAIL
1431#undef TX_STATUS_POSTPONE
1432}
1433#endif /* CONFIG_IWLWIFI_DEBUG */
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
index e1dd76267dca..703621107dac 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
@@ -38,6 +38,7 @@
38#include "iwl-helpers.h" 38#include "iwl-helpers.h"
39#include "iwl-agn-hw.h" 39#include "iwl-agn-hw.h"
40#include "iwl-agn.h" 40#include "iwl-agn.h"
41#include "iwl-agn-calib.h"
41 42
42static const s8 iwlagn_default_queue_to_tx_fifo[] = { 43static const s8 iwlagn_default_queue_to_tx_fifo[] = {
43 IWL_TX_FIFO_VO, 44 IWL_TX_FIFO_VO,
@@ -214,6 +215,25 @@ static int iwlagn_set_Xtal_calib(struct iwl_priv *priv)
214 (u8 *)&cmd, sizeof(cmd)); 215 (u8 *)&cmd, sizeof(cmd));
215} 216}
216 217
218static int iwlagn_set_temperature_offset_calib(struct iwl_priv *priv)
219{
220 struct iwl_calib_temperature_offset_cmd cmd;
221 __le16 *offset_calib =
222 (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_TEMPERATURE);
223 cmd.hdr.op_code = IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD;
224 cmd.hdr.first_group = 0;
225 cmd.hdr.groups_num = 1;
226 cmd.hdr.data_valid = 1;
227 cmd.radio_sensor_offset = le16_to_cpu(offset_calib[1]);
228 if (!(cmd.radio_sensor_offset))
229 cmd.radio_sensor_offset = DEFAULT_RADIO_SENSOR_OFFSET;
230 cmd.reserved = 0;
231 IWL_DEBUG_CALIB(priv, "Radio sensor offset: %d\n",
232 cmd.radio_sensor_offset);
233 return iwl_calib_set(&priv->calib_results[IWL_CALIB_TEMP_OFFSET],
234 (u8 *)&cmd, sizeof(cmd));
235}
236
217static int iwlagn_send_calib_cfg(struct iwl_priv *priv) 237static int iwlagn_send_calib_cfg(struct iwl_priv *priv)
218{ 238{
219 struct iwl_calib_cfg_cmd calib_cfg_cmd; 239 struct iwl_calib_cfg_cmd calib_cfg_cmd;
@@ -320,6 +340,14 @@ void iwlagn_init_alive_start(struct iwl_priv *priv)
320 340
321 } 341 }
322 iwlagn_send_calib_cfg(priv); 342 iwlagn_send_calib_cfg(priv);
343
344 /**
345 * temperature offset calibration is only needed for runtime ucode,
346 * so prepare the value now.
347 */
348 if (priv->cfg->need_temp_offset_calib)
349 iwlagn_set_temperature_offset_calib(priv);
350
323 return; 351 return;
324 352
325restart: 353restart:
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index a6dce616ee3c..c2636a7ab9ee 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -57,7 +57,7 @@
57#include "iwl-io.h" 57#include "iwl-io.h"
58#include "iwl-helpers.h" 58#include "iwl-helpers.h"
59#include "iwl-sta.h" 59#include "iwl-sta.h"
60#include "iwl-calib.h" 60#include "iwl-agn-calib.h"
61#include "iwl-agn.h" 61#include "iwl-agn.h"
62 62
63 63
@@ -91,14 +91,14 @@ static int iwlagn_ant_coupling;
91static bool iwlagn_bt_ch_announce = 1; 91static bool iwlagn_bt_ch_announce = 1;
92 92
93/** 93/**
94 * iwl_commit_rxon - commit staging_rxon to hardware 94 * iwlagn_commit_rxon - commit staging_rxon to hardware
95 * 95 *
96 * The RXON command in staging_rxon is committed to the hardware and 96 * The RXON command in staging_rxon is committed to the hardware and
97 * the active_rxon structure is updated with the new data. This 97 * the active_rxon structure is updated with the new data. This
98 * function correctly transitions out of the RXON_ASSOC_MSK state if 98 * function correctly transitions out of the RXON_ASSOC_MSK state if
99 * a HW tune is required based on the RXON structure changes. 99 * a HW tune is required based on the RXON structure changes.
100 */ 100 */
101int iwl_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) 101int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
102{ 102{
103 /* cast away the const for active_rxon in this function */ 103 /* cast away the const for active_rxon in this function */
104 struct iwl_rxon_cmd *active_rxon = (void *)&ctx->active; 104 struct iwl_rxon_cmd *active_rxon = (void *)&ctx->active;
@@ -314,24 +314,26 @@ static void iwl_free_frame(struct iwl_priv *priv, struct iwl_frame *frame)
314} 314}
315 315
316static u32 iwl_fill_beacon_frame(struct iwl_priv *priv, 316static u32 iwl_fill_beacon_frame(struct iwl_priv *priv,
317 struct ieee80211_hdr *hdr, 317 struct ieee80211_hdr *hdr,
318 int left) 318 int left)
319{ 319{
320 if (!priv->ibss_beacon) 320 lockdep_assert_held(&priv->mutex);
321
322 if (!priv->beacon_skb)
321 return 0; 323 return 0;
322 324
323 if (priv->ibss_beacon->len > left) 325 if (priv->beacon_skb->len > left)
324 return 0; 326 return 0;
325 327
326 memcpy(hdr, priv->ibss_beacon->data, priv->ibss_beacon->len); 328 memcpy(hdr, priv->beacon_skb->data, priv->beacon_skb->len);
327 329
328 return priv->ibss_beacon->len; 330 return priv->beacon_skb->len;
329} 331}
330 332
331/* Parse the beacon frame to find the TIM element and set tim_idx & tim_size */ 333/* Parse the beacon frame to find the TIM element and set tim_idx & tim_size */
332static void iwl_set_beacon_tim(struct iwl_priv *priv, 334static void iwl_set_beacon_tim(struct iwl_priv *priv,
333 struct iwl_tx_beacon_cmd *tx_beacon_cmd, 335 struct iwl_tx_beacon_cmd *tx_beacon_cmd,
334 u8 *beacon, u32 frame_size) 336 u8 *beacon, u32 frame_size)
335{ 337{
336 u16 tim_idx; 338 u16 tim_idx;
337 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)beacon; 339 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)beacon;
@@ -383,6 +385,8 @@ static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv,
383 sizeof(frame->u) - sizeof(*tx_beacon_cmd)); 385 sizeof(frame->u) - sizeof(*tx_beacon_cmd));
384 if (WARN_ON_ONCE(frame_size > MAX_MPDU_SIZE)) 386 if (WARN_ON_ONCE(frame_size > MAX_MPDU_SIZE))
385 return 0; 387 return 0;
388 if (!frame_size)
389 return 0;
386 390
387 /* Set up TX command fields */ 391 /* Set up TX command fields */
388 tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size); 392 tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size);
@@ -393,7 +397,7 @@ static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv,
393 397
394 /* Set up TX beacon command fields */ 398 /* Set up TX beacon command fields */
395 iwl_set_beacon_tim(priv, tx_beacon_cmd, (u8 *)tx_beacon_cmd->frame, 399 iwl_set_beacon_tim(priv, tx_beacon_cmd, (u8 *)tx_beacon_cmd->frame,
396 frame_size); 400 frame_size);
397 401
398 /* Set up packet rate and flags */ 402 /* Set up packet rate and flags */
399 rate = iwl_rate_get_lowest_plcp(priv, priv->beacon_ctx); 403 rate = iwl_rate_get_lowest_plcp(priv, priv->beacon_ctx);
@@ -648,15 +652,14 @@ static void iwl_bg_beacon_update(struct work_struct *work)
648 /* Pull updated AP beacon from mac80211. will fail if not in AP mode */ 652 /* Pull updated AP beacon from mac80211. will fail if not in AP mode */
649 beacon = ieee80211_beacon_get(priv->hw, priv->beacon_ctx->vif); 653 beacon = ieee80211_beacon_get(priv->hw, priv->beacon_ctx->vif);
650 if (!beacon) { 654 if (!beacon) {
651 IWL_ERR(priv, "update beacon failed\n"); 655 IWL_ERR(priv, "update beacon failed -- keeping old\n");
652 goto out; 656 goto out;
653 } 657 }
654 658
655 /* new beacon skb is allocated every time; dispose previous.*/ 659 /* new beacon skb is allocated every time; dispose previous.*/
656 if (priv->ibss_beacon) 660 dev_kfree_skb(priv->beacon_skb);
657 dev_kfree_skb(priv->ibss_beacon);
658 661
659 priv->ibss_beacon = beacon; 662 priv->beacon_skb = beacon;
660 663
661 iwl_send_beacon_cmd(priv); 664 iwl_send_beacon_cmd(priv);
662 out: 665 out:
@@ -935,22 +938,6 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv,
935 wake_up_interruptible(&priv->wait_command_queue); 938 wake_up_interruptible(&priv->wait_command_queue);
936} 939}
937 940
938int iwl_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
939{
940 if (src == IWL_PWR_SRC_VAUX) {
941 if (pci_pme_capable(priv->pci_dev, PCI_D3cold))
942 iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
943 APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
944 ~APMG_PS_CTRL_MSK_PWR_SRC);
945 } else {
946 iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
947 APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
948 ~APMG_PS_CTRL_MSK_PWR_SRC);
949 }
950
951 return 0;
952}
953
954static void iwl_bg_tx_flush(struct work_struct *work) 941static void iwl_bg_tx_flush(struct work_struct *work)
955{ 942{
956 struct iwl_priv *priv = 943 struct iwl_priv *priv =
@@ -2078,7 +2065,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
2078 struct iwlagn_ucode_capabilities ucode_capa = { 2065 struct iwlagn_ucode_capabilities ucode_capa = {
2079 .max_probe_length = 200, 2066 .max_probe_length = 200,
2080 .standard_phy_calibration_size = 2067 .standard_phy_calibration_size =
2081 IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE, 2068 IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE,
2082 }; 2069 };
2083 2070
2084 memset(&pieces, 0, sizeof(pieces)); 2071 memset(&pieces, 0, sizeof(pieces));
@@ -2120,18 +2107,23 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
2120 * firmware filename ... but we don't check for that and only rely 2107 * firmware filename ... but we don't check for that and only rely
2121 * on the API version read from firmware header from here on forward 2108 * on the API version read from firmware header from here on forward
2122 */ 2109 */
2123 if (api_ver < api_min || api_ver > api_max) { 2110 /* no api version check required for experimental uCode */
2124 IWL_ERR(priv, "Driver unable to support your firmware API. " 2111 if (priv->fw_index != UCODE_EXPERIMENTAL_INDEX) {
2125 "Driver supports v%u, firmware is v%u.\n", 2112 if (api_ver < api_min || api_ver > api_max) {
2126 api_max, api_ver); 2113 IWL_ERR(priv,
2127 goto try_again; 2114 "Driver unable to support your firmware API. "
2128 } 2115 "Driver supports v%u, firmware is v%u.\n",
2116 api_max, api_ver);
2117 goto try_again;
2118 }
2129 2119
2130 if (api_ver != api_max) 2120 if (api_ver != api_max)
2131 IWL_ERR(priv, "Firmware has old API version. Expected v%u, " 2121 IWL_ERR(priv,
2132 "got v%u. New firmware can be obtained " 2122 "Firmware has old API version. Expected v%u, "
2133 "from http://www.intellinuxwireless.org.\n", 2123 "got v%u. New firmware can be obtained "
2134 api_max, api_ver); 2124 "from http://www.intellinuxwireless.org.\n",
2125 api_max, api_ver);
2126 }
2135 2127
2136 if (build) 2128 if (build)
2137 sprintf(buildstr, " build %u%s", build, 2129 sprintf(buildstr, " build %u%s", build,
@@ -2820,9 +2812,6 @@ static void iwl_alive_start(struct iwl_priv *priv)
2820 goto restart; 2812 goto restart;
2821 } 2813 }
2822 2814
2823 if (priv->hw_params.calib_rt_cfg)
2824 iwlagn_send_calib_cfg_rt(priv, priv->hw_params.calib_rt_cfg);
2825
2826 2815
2827 /* After the ALIVE response, we can send host commands to the uCode */ 2816 /* After the ALIVE response, we can send host commands to the uCode */
2828 set_bit(STATUS_ALIVE, &priv->status); 2817 set_bit(STATUS_ALIVE, &priv->status);
@@ -2838,6 +2827,7 @@ static void iwl_alive_start(struct iwl_priv *priv)
2838 if (iwl_is_rfkill(priv)) 2827 if (iwl_is_rfkill(priv))
2839 return; 2828 return;
2840 2829
2830 /* download priority table before any calibration request */
2841 if (priv->cfg->bt_params && 2831 if (priv->cfg->bt_params &&
2842 priv->cfg->bt_params->advanced_bt_coexist) { 2832 priv->cfg->bt_params->advanced_bt_coexist) {
2843 /* Configure Bluetooth device coexistence support */ 2833 /* Configure Bluetooth device coexistence support */
@@ -2846,8 +2836,7 @@ static void iwl_alive_start(struct iwl_priv *priv)
2846 priv->kill_cts_mask = IWLAGN_BT_KILL_CTS_MASK_DEFAULT; 2836 priv->kill_cts_mask = IWLAGN_BT_KILL_CTS_MASK_DEFAULT;
2847 priv->cfg->ops->hcmd->send_bt_config(priv); 2837 priv->cfg->ops->hcmd->send_bt_config(priv);
2848 priv->bt_valid = IWLAGN_BT_VALID_ENABLE_FLAGS; 2838 priv->bt_valid = IWLAGN_BT_VALID_ENABLE_FLAGS;
2849 if (bt_coex_active && priv->iw_mode != NL80211_IFTYPE_ADHOC) 2839 iwlagn_send_prio_tbl(priv);
2850 iwlagn_send_prio_tbl(priv);
2851 2840
2852 /* FIXME: w/a to force change uCode BT state machine */ 2841 /* FIXME: w/a to force change uCode BT state machine */
2853 iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN, 2842 iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN,
@@ -2855,6 +2844,9 @@ static void iwl_alive_start(struct iwl_priv *priv)
2855 iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_CLOSE, 2844 iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_CLOSE,
2856 BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); 2845 BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
2857 } 2846 }
2847 if (priv->hw_params.calib_rt_cfg)
2848 iwlagn_send_calib_cfg_rt(priv, priv->hw_params.calib_rt_cfg);
2849
2858 ieee80211_wake_queues(priv->hw); 2850 ieee80211_wake_queues(priv->hw);
2859 2851
2860 priv->active_rate = IWL_RATES_MASK; 2852 priv->active_rate = IWL_RATES_MASK;
@@ -2999,14 +2991,13 @@ static void __iwl_down(struct iwl_priv *priv)
2999 iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 2991 iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
3000 2992
3001 /* Stop the device, and put it in low power state */ 2993 /* Stop the device, and put it in low power state */
3002 priv->cfg->ops->lib->apm_ops.stop(priv); 2994 iwl_apm_stop(priv);
3003 2995
3004 exit: 2996 exit:
3005 memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp)); 2997 memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp));
3006 2998
3007 if (priv->ibss_beacon) 2999 dev_kfree_skb(priv->beacon_skb);
3008 dev_kfree_skb(priv->ibss_beacon); 3000 priv->beacon_skb = NULL;
3009 priv->ibss_beacon = NULL;
3010 3001
3011 /* clear out any free frames */ 3002 /* clear out any free frames */
3012 iwl_clear_free_frames(priv); 3003 iwl_clear_free_frames(priv);
@@ -3089,7 +3080,7 @@ static int __iwl_up(struct iwl_priv *priv)
3089 } 3080 }
3090 3081
3091 for_each_context(priv, ctx) { 3082 for_each_context(priv, ctx) {
3092 ret = iwl_alloc_bcast_station(priv, ctx, true); 3083 ret = iwlagn_alloc_bcast_station(priv, ctx);
3093 if (ret) { 3084 if (ret) {
3094 iwl_dealloc_bcast_stations(priv); 3085 iwl_dealloc_bcast_stations(priv);
3095 return ret; 3086 return ret;
@@ -4142,8 +4133,6 @@ static int iwl_init_drv(struct iwl_priv *priv)
4142{ 4133{
4143 int ret; 4134 int ret;
4144 4135
4145 priv->ibss_beacon = NULL;
4146
4147 spin_lock_init(&priv->sta_lock); 4136 spin_lock_init(&priv->sta_lock);
4148 spin_lock_init(&priv->hcmd_lock); 4137 spin_lock_init(&priv->hcmd_lock);
4149 4138
@@ -4613,7 +4602,7 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
4613 * paths to avoid running iwl_down() at all before leaving driver. 4602 * paths to avoid running iwl_down() at all before leaving driver.
4614 * This (inexpensive) call *makes sure* device is reset. 4603 * This (inexpensive) call *makes sure* device is reset.
4615 */ 4604 */
4616 priv->cfg->ops->lib->apm_ops.stop(priv); 4605 iwl_apm_stop(priv);
4617 4606
4618 iwl_tt_exit(priv); 4607 iwl_tt_exit(priv);
4619 4608
@@ -4656,8 +4645,7 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
4656 4645
4657 iwl_free_isr_ict(priv); 4646 iwl_free_isr_ict(priv);
4658 4647
4659 if (priv->ibss_beacon) 4648 dev_kfree_skb(priv->beacon_skb);
4660 dev_kfree_skb(priv->ibss_beacon);
4661 4649
4662 ieee80211_free_hw(priv->hw); 4650 ieee80211_free_hw(priv->hw);
4663} 4651}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index eb3812a35862..f525d55f2c0f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -129,6 +129,10 @@ void iwlagn_txq_set_sched(struct iwl_priv *priv, u32 mask);
129void iwl_free_tfds_in_queue(struct iwl_priv *priv, 129void iwl_free_tfds_in_queue(struct iwl_priv *priv,
130 int sta_id, int tid, int freed); 130 int sta_id, int tid, int freed);
131 131
132/* RXON */
133int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
134void iwlagn_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
135
132/* uCode */ 136/* uCode */
133int iwlagn_load_ucode(struct iwl_priv *priv); 137int iwlagn_load_ucode(struct iwl_priv *priv);
134void iwlagn_rx_calib_result(struct iwl_priv *priv, 138void iwlagn_rx_calib_result(struct iwl_priv *priv,
@@ -158,6 +162,8 @@ int iwlagn_hw_nic_init(struct iwl_priv *priv);
158int iwlagn_wait_tx_queue_empty(struct iwl_priv *priv); 162int iwlagn_wait_tx_queue_empty(struct iwl_priv *priv);
159int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control); 163int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control);
160void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control); 164void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control);
165void iwl_dump_csr(struct iwl_priv *priv);
166int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display);
161 167
162/* rx */ 168/* rx */
163void iwlagn_rx_queue_restock(struct iwl_priv *priv); 169void iwlagn_rx_queue_restock(struct iwl_priv *priv);
@@ -171,8 +177,15 @@ void iwlagn_rx_reply_rx(struct iwl_priv *priv,
171 struct iwl_rx_mem_buffer *rxb); 177 struct iwl_rx_mem_buffer *rxb);
172void iwlagn_rx_reply_rx_phy(struct iwl_priv *priv, 178void iwlagn_rx_reply_rx_phy(struct iwl_priv *priv,
173 struct iwl_rx_mem_buffer *rxb); 179 struct iwl_rx_mem_buffer *rxb);
180void iwl_rx_handle(struct iwl_priv *priv);
174 181
175/* tx */ 182/* tx */
183void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq);
184int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
185 struct iwl_tx_queue *txq,
186 dma_addr_t addr, u16 len, u8 reset, u8 pad);
187int iwl_hw_tx_queue_init(struct iwl_priv *priv,
188 struct iwl_tx_queue *txq);
176void iwlagn_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags, 189void iwlagn_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
177 struct ieee80211_tx_info *info); 190 struct ieee80211_tx_info *info);
178int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb); 191int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb);
@@ -212,6 +225,8 @@ static inline bool iwl_is_tx_success(u32 status)
212 (status == TX_STATUS_DIRECT_DONE); 225 (status == TX_STATUS_DIRECT_DONE);
213} 226}
214 227
228u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx, u8 valid);
229
215/* rx */ 230/* rx */
216void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, 231void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
217 struct iwl_rx_mem_buffer *rxb); 232 struct iwl_rx_mem_buffer *rxb);
@@ -224,6 +239,7 @@ void iwl_reply_statistics(struct iwl_priv *priv,
224 239
225/* scan */ 240/* scan */
226int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif); 241int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif);
242void iwlagn_post_scan(struct iwl_priv *priv);
227 243
228/* station mgmt */ 244/* station mgmt */
229int iwlagn_manage_ibss_station(struct iwl_priv *priv, 245int iwlagn_manage_ibss_station(struct iwl_priv *priv,
@@ -243,8 +259,63 @@ void iwlagn_bt_setup_deferred_work(struct iwl_priv *priv);
243void iwlagn_bt_cancel_deferred_work(struct iwl_priv *priv); 259void iwlagn_bt_cancel_deferred_work(struct iwl_priv *priv);
244 260
245#ifdef CONFIG_IWLWIFI_DEBUG 261#ifdef CONFIG_IWLWIFI_DEBUG
262const char *iwl_get_tx_fail_reason(u32 status);
246const char *iwl_get_agg_tx_fail_reason(u16 status); 263const char *iwl_get_agg_tx_fail_reason(u16 status);
247#else 264#else
265static inline const char *iwl_get_tx_fail_reason(u32 status) { return ""; }
248static inline const char *iwl_get_agg_tx_fail_reason(u16 status) { return ""; } 266static inline const char *iwl_get_agg_tx_fail_reason(u16 status) { return ""; }
249#endif 267#endif
268
269/* station management */
270int iwlagn_alloc_bcast_station(struct iwl_priv *priv,
271 struct iwl_rxon_context *ctx);
272int iwlagn_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
273 const u8 *addr, u8 *sta_id_r);
274int iwl_remove_default_wep_key(struct iwl_priv *priv,
275 struct iwl_rxon_context *ctx,
276 struct ieee80211_key_conf *key);
277int iwl_set_default_wep_key(struct iwl_priv *priv,
278 struct iwl_rxon_context *ctx,
279 struct ieee80211_key_conf *key);
280int iwl_restore_default_wep_keys(struct iwl_priv *priv,
281 struct iwl_rxon_context *ctx);
282int iwl_set_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
283 struct ieee80211_key_conf *key, u8 sta_id);
284int iwl_remove_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
285 struct ieee80211_key_conf *key, u8 sta_id);
286void iwl_update_tkip_key(struct iwl_priv *priv,
287 struct iwl_rxon_context *ctx,
288 struct ieee80211_key_conf *keyconf,
289 struct ieee80211_sta *sta, u32 iv32, u16 *phase1key);
290int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid);
291int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta,
292 int tid, u16 ssn);
293int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
294 int tid);
295void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id);
296void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt);
297int iwl_update_bcast_stations(struct iwl_priv *priv);
298
299/* rate */
300static inline u32 iwl_ant_idx_to_flags(u8 ant_idx)
301{
302 return BIT(ant_idx) << RATE_MCS_ANT_POS;
303}
304
305static inline u8 iwl_hw_get_rate(__le32 rate_n_flags)
306{
307 return le32_to_cpu(rate_n_flags) & 0xFF;
308}
309
310static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags)
311{
312 return cpu_to_le32(flags|(u32)rate);
313}
314
315/* eeprom */
316void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv);
317void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac);
318int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv);
319void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv);
320
250#endif /* __iwl_agn_h__ */ 321#endif /* __iwl_agn_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index fe652568fec7..424801abc80e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -3784,7 +3784,8 @@ struct iwl_enhance_sensitivity_cmd {
3784 */ 3784 */
3785 3785
3786/* Phy calibration command for series */ 3786/* Phy calibration command for series */
3787 3787/* The default calibrate table size if not specified by firmware */
3788#define IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE 18
3788enum { 3789enum {
3789 IWL_PHY_CALIBRATE_DIFF_GAIN_CMD = 7, 3790 IWL_PHY_CALIBRATE_DIFF_GAIN_CMD = 7,
3790 IWL_PHY_CALIBRATE_DC_CMD = 8, 3791 IWL_PHY_CALIBRATE_DC_CMD = 8,
@@ -3793,7 +3794,8 @@ enum {
3793 IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD = 15, 3794 IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD = 15,
3794 IWL_PHY_CALIBRATE_BASE_BAND_CMD = 16, 3795 IWL_PHY_CALIBRATE_BASE_BAND_CMD = 16,
3795 IWL_PHY_CALIBRATE_TX_IQ_PERD_CMD = 17, 3796 IWL_PHY_CALIBRATE_TX_IQ_PERD_CMD = 17,
3796 IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE = 18, 3797 IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD = 18,
3798 IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE = 19,
3797}; 3799};
3798 3800
3799#define IWL_MAX_PHY_CALIBRATE_TBL_SIZE (253) 3801#define IWL_MAX_PHY_CALIBRATE_TBL_SIZE (253)
@@ -3863,6 +3865,13 @@ struct iwl_calib_xtal_freq_cmd {
3863 u8 pad[2]; 3865 u8 pad[2];
3864} __packed; 3866} __packed;
3865 3867
3868#define DEFAULT_RADIO_SENSOR_OFFSET 2700
3869struct iwl_calib_temperature_offset_cmd {
3870 struct iwl_calib_hdr hdr;
3871 s16 radio_sensor_offset;
3872 s16 reserved;
3873} __packed;
3874
3866/* IWL_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD */ 3875/* IWL_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD */
3867struct iwl_calib_chain_noise_reset_cmd { 3876struct iwl_calib_chain_noise_reset_cmd {
3868 struct iwl_calib_hdr hdr; 3877 struct iwl_calib_hdr hdr;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 516c55ae38aa..25fb3912342c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -69,97 +69,9 @@ EXPORT_SYMBOL_GPL(bt_coex_active);
69module_param(bt_coex_active, bool, S_IRUGO); 69module_param(bt_coex_active, bool, S_IRUGO);
70MODULE_PARM_DESC(bt_coex_active, "enable wifi/bluetooth co-exist"); 70MODULE_PARM_DESC(bt_coex_active, "enable wifi/bluetooth co-exist");
71 71
72#define IWL_DECLARE_RATE_INFO(r, s, ip, in, rp, rn, pp, np) \
73 [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \
74 IWL_RATE_SISO_##s##M_PLCP, \
75 IWL_RATE_MIMO2_##s##M_PLCP,\
76 IWL_RATE_MIMO3_##s##M_PLCP,\
77 IWL_RATE_##r##M_IEEE, \
78 IWL_RATE_##ip##M_INDEX, \
79 IWL_RATE_##in##M_INDEX, \
80 IWL_RATE_##rp##M_INDEX, \
81 IWL_RATE_##rn##M_INDEX, \
82 IWL_RATE_##pp##M_INDEX, \
83 IWL_RATE_##np##M_INDEX }
84
85u32 iwl_debug_level; 72u32 iwl_debug_level;
86EXPORT_SYMBOL(iwl_debug_level); 73EXPORT_SYMBOL(iwl_debug_level);
87 74
88/*
89 * Parameter order:
90 * rate, ht rate, prev rate, next rate, prev tgg rate, next tgg rate
91 *
92 * If there isn't a valid next or previous rate then INV is used which
93 * maps to IWL_RATE_INVALID
94 *
95 */
96const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT] = {
97 IWL_DECLARE_RATE_INFO(1, INV, INV, 2, INV, 2, INV, 2), /* 1mbps */
98 IWL_DECLARE_RATE_INFO(2, INV, 1, 5, 1, 5, 1, 5), /* 2mbps */
99 IWL_DECLARE_RATE_INFO(5, INV, 2, 6, 2, 11, 2, 11), /*5.5mbps */
100 IWL_DECLARE_RATE_INFO(11, INV, 9, 12, 9, 12, 5, 18), /* 11mbps */
101 IWL_DECLARE_RATE_INFO(6, 6, 5, 9, 5, 11, 5, 11), /* 6mbps */
102 IWL_DECLARE_RATE_INFO(9, 6, 6, 11, 6, 11, 5, 11), /* 9mbps */
103 IWL_DECLARE_RATE_INFO(12, 12, 11, 18, 11, 18, 11, 18), /* 12mbps */
104 IWL_DECLARE_RATE_INFO(18, 18, 12, 24, 12, 24, 11, 24), /* 18mbps */
105 IWL_DECLARE_RATE_INFO(24, 24, 18, 36, 18, 36, 18, 36), /* 24mbps */
106 IWL_DECLARE_RATE_INFO(36, 36, 24, 48, 24, 48, 24, 48), /* 36mbps */
107 IWL_DECLARE_RATE_INFO(48, 48, 36, 54, 36, 54, 36, 54), /* 48mbps */
108 IWL_DECLARE_RATE_INFO(54, 54, 48, INV, 48, INV, 48, INV),/* 54mbps */
109 IWL_DECLARE_RATE_INFO(60, 60, 48, INV, 48, INV, 48, INV),/* 60mbps */
110 /* FIXME:RS: ^^ should be INV (legacy) */
111};
112EXPORT_SYMBOL(iwl_rates);
113
114int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
115{
116 int idx = 0;
117
118 /* HT rate format */
119 if (rate_n_flags & RATE_MCS_HT_MSK) {
120 idx = (rate_n_flags & 0xff);
121
122 if (idx >= IWL_RATE_MIMO3_6M_PLCP)
123 idx = idx - IWL_RATE_MIMO3_6M_PLCP;
124 else if (idx >= IWL_RATE_MIMO2_6M_PLCP)
125 idx = idx - IWL_RATE_MIMO2_6M_PLCP;
126
127 idx += IWL_FIRST_OFDM_RATE;
128 /* skip 9M not supported in ht*/
129 if (idx >= IWL_RATE_9M_INDEX)
130 idx += 1;
131 if ((idx >= IWL_FIRST_OFDM_RATE) && (idx <= IWL_LAST_OFDM_RATE))
132 return idx;
133
134 /* legacy rate format, search for match in table */
135 } else {
136 for (idx = 0; idx < ARRAY_SIZE(iwl_rates); idx++)
137 if (iwl_rates[idx].plcp == (rate_n_flags & 0xFF))
138 return idx;
139 }
140
141 return -1;
142}
143EXPORT_SYMBOL(iwl_hwrate_to_plcp_idx);
144
145u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant, u8 valid)
146{
147 int i;
148 u8 ind = ant;
149
150 if (priv->band == IEEE80211_BAND_2GHZ &&
151 priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)
152 return 0;
153
154 for (i = 0; i < RATE_ANT_NUM - 1; i++) {
155 ind = (ind + 1) < RATE_ANT_NUM ? ind + 1 : 0;
156 if (valid & BIT(ind))
157 return ind;
158 }
159 return ant;
160}
161EXPORT_SYMBOL(iwl_toggle_tx_ant);
162
163const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; 75const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
164EXPORT_SYMBOL(iwl_bcast_addr); 76EXPORT_SYMBOL(iwl_bcast_addr);
165 77
@@ -439,12 +351,6 @@ void iwlcore_tx_cmd_protection(struct iwl_priv *priv,
439EXPORT_SYMBOL(iwlcore_tx_cmd_protection); 351EXPORT_SYMBOL(iwlcore_tx_cmd_protection);
440 352
441 353
442static bool is_single_rx_stream(struct iwl_priv *priv)
443{
444 return priv->current_ht_config.smps == IEEE80211_SMPS_STATIC ||
445 priv->current_ht_config.single_chain_sufficient;
446}
447
448static bool iwl_is_channel_extension(struct iwl_priv *priv, 354static bool iwl_is_channel_extension(struct iwl_priv *priv,
449 enum ieee80211_band band, 355 enum ieee80211_band band,
450 u16 channel, u8 extension_chan_offset) 356 u16 channel, u8 extension_chan_offset)
@@ -604,76 +510,74 @@ void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
604} 510}
605EXPORT_SYMBOL(iwl_set_rxon_hwcrypto); 511EXPORT_SYMBOL(iwl_set_rxon_hwcrypto);
606 512
607/** 513/* validate RXON structure is valid */
608 * iwl_check_rxon_cmd - validate RXON structure is valid
609 *
610 * NOTE: This is really only useful during development and can eventually
611 * be #ifdef'd out once the driver is stable and folks aren't actively
612 * making changes
613 */
614int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx) 514int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
615{ 515{
616 int error = 0;
617 int counter = 1;
618 struct iwl_rxon_cmd *rxon = &ctx->staging; 516 struct iwl_rxon_cmd *rxon = &ctx->staging;
517 bool error = false;
619 518
620 if (rxon->flags & RXON_FLG_BAND_24G_MSK) { 519 if (rxon->flags & RXON_FLG_BAND_24G_MSK) {
621 error |= le32_to_cpu(rxon->flags & 520 if (rxon->flags & RXON_FLG_TGJ_NARROW_BAND_MSK) {
622 (RXON_FLG_TGJ_NARROW_BAND_MSK | 521 IWL_WARN(priv, "check 2.4G: wrong narrow\n");
623 RXON_FLG_RADAR_DETECT_MSK)); 522 error = true;
624 if (error) 523 }
625 IWL_WARN(priv, "check 24G fields %d | %d\n", 524 if (rxon->flags & RXON_FLG_RADAR_DETECT_MSK) {
626 counter++, error); 525 IWL_WARN(priv, "check 2.4G: wrong radar\n");
526 error = true;
527 }
627 } else { 528 } else {
628 error |= (rxon->flags & RXON_FLG_SHORT_SLOT_MSK) ? 529 if (!(rxon->flags & RXON_FLG_SHORT_SLOT_MSK)) {
629 0 : le32_to_cpu(RXON_FLG_SHORT_SLOT_MSK); 530 IWL_WARN(priv, "check 5.2G: not short slot!\n");
630 if (error) 531 error = true;
631 IWL_WARN(priv, "check 52 fields %d | %d\n", 532 }
632 counter++, error); 533 if (rxon->flags & RXON_FLG_CCK_MSK) {
633 error |= le32_to_cpu(rxon->flags & RXON_FLG_CCK_MSK); 534 IWL_WARN(priv, "check 5.2G: CCK!\n");
634 if (error) 535 error = true;
635 IWL_WARN(priv, "check 52 CCK %d | %d\n", 536 }
636 counter++, error); 537 }
637 } 538 if ((rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1) {
638 error |= (rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1; 539 IWL_WARN(priv, "mac/bssid mcast!\n");
639 if (error) 540 error = true;
640 IWL_WARN(priv, "check mac addr %d | %d\n", counter++, error); 541 }
641 542
642 /* make sure basic rates 6Mbps and 1Mbps are supported */ 543 /* make sure basic rates 6Mbps and 1Mbps are supported */
643 error |= (((rxon->ofdm_basic_rates & IWL_RATE_6M_MASK) == 0) && 544 if ((rxon->ofdm_basic_rates & IWL_RATE_6M_MASK) == 0 &&
644 ((rxon->cck_basic_rates & IWL_RATE_1M_MASK) == 0)); 545 (rxon->cck_basic_rates & IWL_RATE_1M_MASK) == 0) {
645 if (error) 546 IWL_WARN(priv, "neither 1 nor 6 are basic\n");
646 IWL_WARN(priv, "check basic rate %d | %d\n", counter++, error); 547 error = true;
548 }
647 549
648 error |= (le16_to_cpu(rxon->assoc_id) > 2007); 550 if (le16_to_cpu(rxon->assoc_id) > 2007) {
649 if (error) 551 IWL_WARN(priv, "aid > 2007\n");
650 IWL_WARN(priv, "check assoc id %d | %d\n", counter++, error); 552 error = true;
553 }
651 554
652 error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)) 555 if ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK))
653 == (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)); 556 == (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)) {
654 if (error) 557 IWL_WARN(priv, "CCK and short slot\n");
655 IWL_WARN(priv, "check CCK and short slot %d | %d\n", 558 error = true;
656 counter++, error); 559 }
657 560
658 error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)) 561 if ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK))
659 == (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)); 562 == (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)) {
660 if (error) 563 IWL_WARN(priv, "CCK and auto detect");
661 IWL_WARN(priv, "check CCK & auto detect %d | %d\n", 564 error = true;
662 counter++, error); 565 }
663 566
664 error |= ((rxon->flags & (RXON_FLG_AUTO_DETECT_MSK | 567 if ((rxon->flags & (RXON_FLG_AUTO_DETECT_MSK |
665 RXON_FLG_TGG_PROTECT_MSK)) == RXON_FLG_TGG_PROTECT_MSK); 568 RXON_FLG_TGG_PROTECT_MSK)) ==
666 if (error) 569 RXON_FLG_TGG_PROTECT_MSK) {
667 IWL_WARN(priv, "check TGG and auto detect %d | %d\n", 570 IWL_WARN(priv, "TGg but no auto-detect\n");
668 counter++, error); 571 error = true;
572 }
669 573
670 if (error) 574 if (error)
671 IWL_WARN(priv, "Tuning to channel %d\n", 575 IWL_WARN(priv, "Tuning to channel %d\n",
672 le16_to_cpu(rxon->channel)); 576 le16_to_cpu(rxon->channel));
673 577
674 if (error) { 578 if (error) {
675 IWL_ERR(priv, "Not a valid iwl_rxon_assoc_cmd field values\n"); 579 IWL_ERR(priv, "Invalid RXON\n");
676 return -1; 580 return -EINVAL;
677 } 581 }
678 return 0; 582 return 0;
679} 583}
@@ -834,141 +738,6 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf)
834} 738}
835EXPORT_SYMBOL(iwl_set_rxon_ht); 739EXPORT_SYMBOL(iwl_set_rxon_ht);
836 740
837#define IWL_NUM_RX_CHAINS_MULTIPLE 3
838#define IWL_NUM_RX_CHAINS_SINGLE 2
839#define IWL_NUM_IDLE_CHAINS_DUAL 2
840#define IWL_NUM_IDLE_CHAINS_SINGLE 1
841
842/*
843 * Determine how many receiver/antenna chains to use.
844 *
845 * More provides better reception via diversity. Fewer saves power
846 * at the expense of throughput, but only when not in powersave to
847 * start with.
848 *
849 * MIMO (dual stream) requires at least 2, but works better with 3.
850 * This does not determine *which* chains to use, just how many.
851 */
852static int iwl_get_active_rx_chain_count(struct iwl_priv *priv)
853{
854 if (priv->cfg->bt_params &&
855 priv->cfg->bt_params->advanced_bt_coexist &&
856 (priv->bt_full_concurrent ||
857 priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) {
858 /*
859 * only use chain 'A' in bt high traffic load or
860 * full concurrency mode
861 */
862 return IWL_NUM_RX_CHAINS_SINGLE;
863 }
864 /* # of Rx chains to use when expecting MIMO. */
865 if (is_single_rx_stream(priv))
866 return IWL_NUM_RX_CHAINS_SINGLE;
867 else
868 return IWL_NUM_RX_CHAINS_MULTIPLE;
869}
870
871/*
872 * When we are in power saving mode, unless device support spatial
873 * multiplexing power save, use the active count for rx chain count.
874 */
875static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt)
876{
877 /* # Rx chains when idling, depending on SMPS mode */
878 switch (priv->current_ht_config.smps) {
879 case IEEE80211_SMPS_STATIC:
880 case IEEE80211_SMPS_DYNAMIC:
881 return IWL_NUM_IDLE_CHAINS_SINGLE;
882 case IEEE80211_SMPS_OFF:
883 return active_cnt;
884 default:
885 WARN(1, "invalid SMPS mode %d",
886 priv->current_ht_config.smps);
887 return active_cnt;
888 }
889}
890
891/* up to 4 chains */
892static u8 iwl_count_chain_bitmap(u32 chain_bitmap)
893{
894 u8 res;
895 res = (chain_bitmap & BIT(0)) >> 0;
896 res += (chain_bitmap & BIT(1)) >> 1;
897 res += (chain_bitmap & BIT(2)) >> 2;
898 res += (chain_bitmap & BIT(3)) >> 3;
899 return res;
900}
901
902/**
903 * iwl_set_rxon_chain - Set up Rx chain usage in "staging" RXON image
904 *
905 * Selects how many and which Rx receivers/antennas/chains to use.
906 * This should not be used for scan command ... it puts data in wrong place.
907 */
908void iwl_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
909{
910 bool is_single = is_single_rx_stream(priv);
911 bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status);
912 u8 idle_rx_cnt, active_rx_cnt, valid_rx_cnt;
913 u32 active_chains;
914 u16 rx_chain;
915
916 /* Tell uCode which antennas are actually connected.
917 * Before first association, we assume all antennas are connected.
918 * Just after first association, iwl_chain_noise_calibration()
919 * checks which antennas actually *are* connected. */
920 if (priv->chain_noise_data.active_chains)
921 active_chains = priv->chain_noise_data.active_chains;
922 else
923 active_chains = priv->hw_params.valid_rx_ant;
924
925 if (priv->cfg->bt_params &&
926 priv->cfg->bt_params->advanced_bt_coexist &&
927 (priv->bt_full_concurrent ||
928 priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) {
929 /*
930 * only use chain 'A' in bt high traffic load or
931 * full concurrency mode
932 */
933 active_chains = first_antenna(active_chains);
934 }
935
936 rx_chain = active_chains << RXON_RX_CHAIN_VALID_POS;
937
938 /* How many receivers should we use? */
939 active_rx_cnt = iwl_get_active_rx_chain_count(priv);
940 idle_rx_cnt = iwl_get_idle_rx_chain_count(priv, active_rx_cnt);
941
942
943 /* correct rx chain count according hw settings
944 * and chain noise calibration
945 */
946 valid_rx_cnt = iwl_count_chain_bitmap(active_chains);
947 if (valid_rx_cnt < active_rx_cnt)
948 active_rx_cnt = valid_rx_cnt;
949
950 if (valid_rx_cnt < idle_rx_cnt)
951 idle_rx_cnt = valid_rx_cnt;
952
953 rx_chain |= active_rx_cnt << RXON_RX_CHAIN_MIMO_CNT_POS;
954 rx_chain |= idle_rx_cnt << RXON_RX_CHAIN_CNT_POS;
955
956 ctx->staging.rx_chain = cpu_to_le16(rx_chain);
957
958 if (!is_single && (active_rx_cnt >= IWL_NUM_RX_CHAINS_SINGLE) && is_cam)
959 ctx->staging.rx_chain |= RXON_RX_CHAIN_MIMO_FORCE_MSK;
960 else
961 ctx->staging.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK;
962
963 IWL_DEBUG_ASSOC(priv, "rx_chain=0x%X active=%d idle=%d\n",
964 ctx->staging.rx_chain,
965 active_rx_cnt, idle_rx_cnt);
966
967 WARN_ON(active_rx_cnt == 0 || idle_rx_cnt == 0 ||
968 active_rx_cnt < idle_rx_cnt);
969}
970EXPORT_SYMBOL(iwl_set_rxon_chain);
971
972/* Return valid, unused, channel for a passive scan to reset the RF */ 741/* Return valid, unused, channel for a passive scan to reset the RF */
973u8 iwl_get_single_channel_number(struct iwl_priv *priv, 742u8 iwl_get_single_channel_number(struct iwl_priv *priv,
974 enum ieee80211_band band) 743 enum ieee80211_band band)
@@ -1758,43 +1527,47 @@ static inline void iwl_set_no_assoc(struct iwl_priv *priv,
1758 iwlcore_commit_rxon(priv, ctx); 1527 iwlcore_commit_rxon(priv, ctx);
1759} 1528}
1760 1529
1761static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) 1530static void iwlcore_beacon_update(struct ieee80211_hw *hw,
1531 struct ieee80211_vif *vif)
1762{ 1532{
1763 struct iwl_priv *priv = hw->priv; 1533 struct iwl_priv *priv = hw->priv;
1764 unsigned long flags; 1534 unsigned long flags;
1765 __le64 timestamp; 1535 __le64 timestamp;
1536 struct sk_buff *skb = ieee80211_beacon_get(hw, vif);
1766 1537
1767 IWL_DEBUG_MAC80211(priv, "enter\n"); 1538 if (!skb)
1539 return;
1540
1541 IWL_DEBUG_ASSOC(priv, "enter\n");
1768 1542
1769 lockdep_assert_held(&priv->mutex); 1543 lockdep_assert_held(&priv->mutex);
1770 1544
1771 if (!priv->beacon_ctx) { 1545 if (!priv->beacon_ctx) {
1772 IWL_ERR(priv, "update beacon but no beacon context!\n"); 1546 IWL_ERR(priv, "update beacon but no beacon context!\n");
1773 dev_kfree_skb(skb); 1547 dev_kfree_skb(skb);
1774 return -EINVAL; 1548 return;
1775 }
1776
1777 if (!iwl_is_ready_rf(priv)) {
1778 IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
1779 return -EIO;
1780 } 1549 }
1781 1550
1782 spin_lock_irqsave(&priv->lock, flags); 1551 spin_lock_irqsave(&priv->lock, flags);
1783 1552
1784 if (priv->ibss_beacon) 1553 if (priv->beacon_skb)
1785 dev_kfree_skb(priv->ibss_beacon); 1554 dev_kfree_skb(priv->beacon_skb);
1786 1555
1787 priv->ibss_beacon = skb; 1556 priv->beacon_skb = skb;
1788 1557
1789 timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; 1558 timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
1790 priv->timestamp = le64_to_cpu(timestamp); 1559 priv->timestamp = le64_to_cpu(timestamp);
1791 1560
1792 IWL_DEBUG_MAC80211(priv, "leave\n"); 1561 IWL_DEBUG_ASSOC(priv, "leave\n");
1562
1793 spin_unlock_irqrestore(&priv->lock, flags); 1563 spin_unlock_irqrestore(&priv->lock, flags);
1794 1564
1795 priv->cfg->ops->lib->post_associate(priv, priv->beacon_ctx->vif); 1565 if (!iwl_is_ready_rf(priv)) {
1566 IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
1567 return;
1568 }
1796 1569
1797 return 0; 1570 priv->cfg->ops->lib->post_associate(priv, priv->beacon_ctx->vif);
1798} 1571}
1799 1572
1800void iwl_bss_info_changed(struct ieee80211_hw *hw, 1573void iwl_bss_info_changed(struct ieee80211_hw *hw,
@@ -1835,8 +1608,8 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
1835 } 1608 }
1836 1609
1837 if (changes & BSS_CHANGED_BEACON && vif->type == NL80211_IFTYPE_AP) { 1610 if (changes & BSS_CHANGED_BEACON && vif->type == NL80211_IFTYPE_AP) {
1838 dev_kfree_skb(priv->ibss_beacon); 1611 dev_kfree_skb(priv->beacon_skb);
1839 priv->ibss_beacon = ieee80211_beacon_get(hw, vif); 1612 priv->beacon_skb = ieee80211_beacon_get(hw, vif);
1840 } 1613 }
1841 1614
1842 if (changes & BSS_CHANGED_BEACON_INT && vif->type == NL80211_IFTYPE_AP) 1615 if (changes & BSS_CHANGED_BEACON_INT && vif->type == NL80211_IFTYPE_AP)
@@ -1876,13 +1649,8 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
1876 * mac80211 decides to do both changes at once because 1649 * mac80211 decides to do both changes at once because
1877 * it will invoke post_associate. 1650 * it will invoke post_associate.
1878 */ 1651 */
1879 if (vif->type == NL80211_IFTYPE_ADHOC && 1652 if (vif->type == NL80211_IFTYPE_ADHOC && changes & BSS_CHANGED_BEACON)
1880 changes & BSS_CHANGED_BEACON) { 1653 iwlcore_beacon_update(hw, vif);
1881 struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
1882
1883 if (beacon)
1884 iwl_mac_beacon_update(hw, beacon);
1885 }
1886 1654
1887 if (changes & BSS_CHANGED_ERP_PREAMBLE) { 1655 if (changes & BSS_CHANGED_ERP_PREAMBLE) {
1888 IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n", 1656 IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n",
@@ -1959,6 +1727,7 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
1959 memcpy(ctx->staging.bssid_addr, 1727 memcpy(ctx->staging.bssid_addr,
1960 bss_conf->bssid, ETH_ALEN); 1728 bss_conf->bssid, ETH_ALEN);
1961 memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN); 1729 memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN);
1730 iwl_led_associate(priv);
1962 iwlcore_config_ap(priv, vif); 1731 iwlcore_config_ap(priv, vif);
1963 } else 1732 } else
1964 iwl_set_no_assoc(priv, vif); 1733 iwl_set_no_assoc(priv, vif);
@@ -2290,10 +2059,10 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
2290 spin_lock_irqsave(&priv->lock, flags); 2059 spin_lock_irqsave(&priv->lock, flags);
2291 2060
2292 /* new association get rid of ibss beacon skb */ 2061 /* new association get rid of ibss beacon skb */
2293 if (priv->ibss_beacon) 2062 if (priv->beacon_skb)
2294 dev_kfree_skb(priv->ibss_beacon); 2063 dev_kfree_skb(priv->beacon_skb);
2295 2064
2296 priv->ibss_beacon = NULL; 2065 priv->beacon_skb = NULL;
2297 2066
2298 priv->timestamp = 0; 2067 priv->timestamp = 0;
2299 2068
@@ -2581,140 +2350,6 @@ void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len)
2581EXPORT_SYMBOL(iwl_update_stats); 2350EXPORT_SYMBOL(iwl_update_stats);
2582#endif 2351#endif
2583 2352
2584static const char *get_csr_string(int cmd)
2585{
2586 switch (cmd) {
2587 IWL_CMD(CSR_HW_IF_CONFIG_REG);
2588 IWL_CMD(CSR_INT_COALESCING);
2589 IWL_CMD(CSR_INT);
2590 IWL_CMD(CSR_INT_MASK);
2591 IWL_CMD(CSR_FH_INT_STATUS);
2592 IWL_CMD(CSR_GPIO_IN);
2593 IWL_CMD(CSR_RESET);
2594 IWL_CMD(CSR_GP_CNTRL);
2595 IWL_CMD(CSR_HW_REV);
2596 IWL_CMD(CSR_EEPROM_REG);
2597 IWL_CMD(CSR_EEPROM_GP);
2598 IWL_CMD(CSR_OTP_GP_REG);
2599 IWL_CMD(CSR_GIO_REG);
2600 IWL_CMD(CSR_GP_UCODE_REG);
2601 IWL_CMD(CSR_GP_DRIVER_REG);
2602 IWL_CMD(CSR_UCODE_DRV_GP1);
2603 IWL_CMD(CSR_UCODE_DRV_GP2);
2604 IWL_CMD(CSR_LED_REG);
2605 IWL_CMD(CSR_DRAM_INT_TBL_REG);
2606 IWL_CMD(CSR_GIO_CHICKEN_BITS);
2607 IWL_CMD(CSR_ANA_PLL_CFG);
2608 IWL_CMD(CSR_HW_REV_WA_REG);
2609 IWL_CMD(CSR_DBG_HPET_MEM_REG);
2610 default:
2611 return "UNKNOWN";
2612
2613 }
2614}
2615
2616void iwl_dump_csr(struct iwl_priv *priv)
2617{
2618 int i;
2619 u32 csr_tbl[] = {
2620 CSR_HW_IF_CONFIG_REG,
2621 CSR_INT_COALESCING,
2622 CSR_INT,
2623 CSR_INT_MASK,
2624 CSR_FH_INT_STATUS,
2625 CSR_GPIO_IN,
2626 CSR_RESET,
2627 CSR_GP_CNTRL,
2628 CSR_HW_REV,
2629 CSR_EEPROM_REG,
2630 CSR_EEPROM_GP,
2631 CSR_OTP_GP_REG,
2632 CSR_GIO_REG,
2633 CSR_GP_UCODE_REG,
2634 CSR_GP_DRIVER_REG,
2635 CSR_UCODE_DRV_GP1,
2636 CSR_UCODE_DRV_GP2,
2637 CSR_LED_REG,
2638 CSR_DRAM_INT_TBL_REG,
2639 CSR_GIO_CHICKEN_BITS,
2640 CSR_ANA_PLL_CFG,
2641 CSR_HW_REV_WA_REG,
2642 CSR_DBG_HPET_MEM_REG
2643 };
2644 IWL_ERR(priv, "CSR values:\n");
2645 IWL_ERR(priv, "(2nd byte of CSR_INT_COALESCING is "
2646 "CSR_INT_PERIODIC_REG)\n");
2647 for (i = 0; i < ARRAY_SIZE(csr_tbl); i++) {
2648 IWL_ERR(priv, " %25s: 0X%08x\n",
2649 get_csr_string(csr_tbl[i]),
2650 iwl_read32(priv, csr_tbl[i]));
2651 }
2652}
2653EXPORT_SYMBOL(iwl_dump_csr);
2654
2655static const char *get_fh_string(int cmd)
2656{
2657 switch (cmd) {
2658 IWL_CMD(FH_RSCSR_CHNL0_STTS_WPTR_REG);
2659 IWL_CMD(FH_RSCSR_CHNL0_RBDCB_BASE_REG);
2660 IWL_CMD(FH_RSCSR_CHNL0_WPTR);
2661 IWL_CMD(FH_MEM_RCSR_CHNL0_CONFIG_REG);
2662 IWL_CMD(FH_MEM_RSSR_SHARED_CTRL_REG);
2663 IWL_CMD(FH_MEM_RSSR_RX_STATUS_REG);
2664 IWL_CMD(FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV);
2665 IWL_CMD(FH_TSSR_TX_STATUS_REG);
2666 IWL_CMD(FH_TSSR_TX_ERROR_REG);
2667 default:
2668 return "UNKNOWN";
2669
2670 }
2671}
2672
2673int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display)
2674{
2675 int i;
2676#ifdef CONFIG_IWLWIFI_DEBUG
2677 int pos = 0;
2678 size_t bufsz = 0;
2679#endif
2680 u32 fh_tbl[] = {
2681 FH_RSCSR_CHNL0_STTS_WPTR_REG,
2682 FH_RSCSR_CHNL0_RBDCB_BASE_REG,
2683 FH_RSCSR_CHNL0_WPTR,
2684 FH_MEM_RCSR_CHNL0_CONFIG_REG,
2685 FH_MEM_RSSR_SHARED_CTRL_REG,
2686 FH_MEM_RSSR_RX_STATUS_REG,
2687 FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV,
2688 FH_TSSR_TX_STATUS_REG,
2689 FH_TSSR_TX_ERROR_REG
2690 };
2691#ifdef CONFIG_IWLWIFI_DEBUG
2692 if (display) {
2693 bufsz = ARRAY_SIZE(fh_tbl) * 48 + 40;
2694 *buf = kmalloc(bufsz, GFP_KERNEL);
2695 if (!*buf)
2696 return -ENOMEM;
2697 pos += scnprintf(*buf + pos, bufsz - pos,
2698 "FH register values:\n");
2699 for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) {
2700 pos += scnprintf(*buf + pos, bufsz - pos,
2701 " %34s: 0X%08x\n",
2702 get_fh_string(fh_tbl[i]),
2703 iwl_read_direct32(priv, fh_tbl[i]));
2704 }
2705 return pos;
2706 }
2707#endif
2708 IWL_ERR(priv, "FH register values:\n");
2709 for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) {
2710 IWL_ERR(priv, " %34s: 0X%08x\n",
2711 get_fh_string(fh_tbl[i]),
2712 iwl_read_direct32(priv, fh_tbl[i]));
2713 }
2714 return 0;
2715}
2716EXPORT_SYMBOL(iwl_dump_fh);
2717
2718static void iwl_force_rf_reset(struct iwl_priv *priv) 2353static void iwl_force_rf_reset(struct iwl_priv *priv)
2719{ 2354{
2720 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 2355 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
@@ -2795,7 +2430,6 @@ int iwl_force_reset(struct iwl_priv *priv, int mode, bool external)
2795 } 2430 }
2796 return 0; 2431 return 0;
2797} 2432}
2798EXPORT_SYMBOL(iwl_force_reset);
2799 2433
2800/** 2434/**
2801 * iwl_bg_monitor_recover - Timer callback to check for stuck queue and recover 2435 * iwl_bg_monitor_recover - Timer callback to check for stuck queue and recover
@@ -2848,13 +2482,10 @@ static int iwl_check_stuck_queue(struct iwl_priv *priv, int cnt)
2848 "queue %d, not read %d time\n", 2482 "queue %d, not read %d time\n",
2849 q->id, 2483 q->id,
2850 q->repeat_same_read_ptr); 2484 q->repeat_same_read_ptr);
2851 if (priv->cfg->bt_params && 2485 mod_timer(&priv->monitor_recover,
2852 !priv->cfg->bt_params->advanced_bt_coexist) { 2486 jiffies + msecs_to_jiffies(
2853 mod_timer(&priv->monitor_recover, 2487 IWL_ONE_HUNDRED_MSECS));
2854 jiffies + msecs_to_jiffies( 2488 return 1;
2855 IWL_ONE_HUNDRED_MSECS));
2856 return 1;
2857 }
2858 } 2489 }
2859 } else { 2490 } else {
2860 q->last_read_ptr = q->read_ptr; 2491 q->last_read_ptr = q->read_ptr;
@@ -2964,7 +2595,7 @@ int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
2964 * it will not call apm_ops.stop() to stop the DMA operation. 2595 * it will not call apm_ops.stop() to stop the DMA operation.
2965 * Calling apm_ops.stop here to make sure we stop the DMA. 2596 * Calling apm_ops.stop here to make sure we stop the DMA.
2966 */ 2597 */
2967 priv->cfg->ops->lib->apm_ops.stop(priv); 2598 iwl_apm_stop(priv);
2968 2599
2969 pci_save_state(pdev); 2600 pci_save_state(pdev);
2970 pci_disable_device(pdev); 2601 pci_disable_device(pdev);
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 6228b1c2ec96..64527def059f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -112,13 +112,12 @@ struct iwl_hcmd_utils_ops {
112 int (*calc_rssi)(struct iwl_priv *priv, 112 int (*calc_rssi)(struct iwl_priv *priv,
113 struct iwl_rx_phy_res *rx_resp); 113 struct iwl_rx_phy_res *rx_resp);
114 int (*request_scan)(struct iwl_priv *priv, struct ieee80211_vif *vif); 114 int (*request_scan)(struct iwl_priv *priv, struct ieee80211_vif *vif);
115 void (*post_scan)(struct iwl_priv *priv);
115}; 116};
116 117
117struct iwl_apm_ops { 118struct iwl_apm_ops {
118 int (*init)(struct iwl_priv *priv); 119 int (*init)(struct iwl_priv *priv);
119 void (*stop)(struct iwl_priv *priv);
120 void (*config)(struct iwl_priv *priv); 120 void (*config)(struct iwl_priv *priv);
121 int (*set_pwr_src)(struct iwl_priv *priv, enum iwl_pwr_src src);
122}; 121};
123 122
124struct iwl_debugfs_ops { 123struct iwl_debugfs_ops {
@@ -136,7 +135,6 @@ struct iwl_debugfs_ops {
136 135
137struct iwl_temp_ops { 136struct iwl_temp_ops {
138 void (*temperature)(struct iwl_priv *priv); 137 void (*temperature)(struct iwl_priv *priv);
139 void (*set_ct_kill)(struct iwl_priv *priv);
140}; 138};
141 139
142struct iwl_tt_ops { 140struct iwl_tt_ops {
@@ -344,6 +342,7 @@ struct iwl_ht_params {
344 * @ucode_api_min: Lowest version of uCode API supported by driver. 342 * @ucode_api_min: Lowest version of uCode API supported by driver.
345 * @pa_type: used by 6000 series only to identify the type of Power Amplifier 343 * @pa_type: used by 6000 series only to identify the type of Power Amplifier
346 * @need_dc_calib: need to perform init dc calibration 344 * @need_dc_calib: need to perform init dc calibration
345 * @need_temp_offset_calib: need to perform temperature offset calibration
347 * @scan_antennas: available antenna for scan operation 346 * @scan_antennas: available antenna for scan operation
348 * 347 *
349 * We enable the driver to be backward compatible wrt API version. The 348 * We enable the driver to be backward compatible wrt API version. The
@@ -388,6 +387,7 @@ struct iwl_cfg {
388 struct iwl_bt_params *bt_params; 387 struct iwl_bt_params *bt_params;
389 enum iwl_pa_type pa_type; /* if used set to IWL_PA_SYSTEM */ 388 enum iwl_pa_type pa_type; /* if used set to IWL_PA_SYSTEM */
390 const bool need_dc_calib; /* if used set to true */ 389 const bool need_dc_calib; /* if used set to true */
390 const bool need_temp_offset_calib; /* if used set to true */
391 u8 scan_rx_antennas[IEEE80211_NUM_BANDS]; 391 u8 scan_rx_antennas[IEEE80211_NUM_BANDS];
392 u8 scan_tx_antennas[IEEE80211_NUM_BANDS]; 392 u8 scan_tx_antennas[IEEE80211_NUM_BANDS];
393}; 393};
@@ -398,7 +398,6 @@ struct iwl_cfg {
398 398
399struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg, 399struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg,
400 struct ieee80211_ops *hw_ops); 400 struct ieee80211_ops *hw_ops);
401void iwl_activate_qos(struct iwl_priv *priv);
402int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, 401int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
403 const struct ieee80211_tx_queue_params *params); 402 const struct ieee80211_tx_queue_params *params);
404int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw); 403int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw);
@@ -406,7 +405,6 @@ void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
406 int hw_decrypt); 405 int hw_decrypt);
407int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx); 406int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
408int iwl_full_rxon_required(struct iwl_priv *priv, struct iwl_rxon_context *ctx); 407int iwl_full_rxon_required(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
409void iwl_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
410int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch, 408int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch,
411 struct iwl_rxon_context *ctx); 409 struct iwl_rxon_context *ctx);
412void iwl_set_flags_for_band(struct iwl_priv *priv, 410void iwl_set_flags_for_band(struct iwl_priv *priv,
@@ -432,7 +430,6 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
432 struct ieee80211_vif *vif, 430 struct ieee80211_vif *vif,
433 struct ieee80211_bss_conf *bss_conf, 431 struct ieee80211_bss_conf *bss_conf,
434 u32 changes); 432 u32 changes);
435int iwl_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
436int iwl_mac_add_interface(struct ieee80211_hw *hw, 433int iwl_mac_add_interface(struct ieee80211_hw *hw,
437 struct ieee80211_vif *vif); 434 struct ieee80211_vif *vif);
438void iwl_mac_remove_interface(struct ieee80211_hw *hw, 435void iwl_mac_remove_interface(struct ieee80211_hw *hw,
@@ -509,7 +506,6 @@ void iwl_rx_reply_error(struct iwl_priv *priv,
509******************************************************/ 506******************************************************/
510void iwl_cmd_queue_free(struct iwl_priv *priv); 507void iwl_cmd_queue_free(struct iwl_priv *priv);
511int iwl_rx_queue_alloc(struct iwl_priv *priv); 508int iwl_rx_queue_alloc(struct iwl_priv *priv);
512void iwl_rx_handle(struct iwl_priv *priv);
513void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, 509void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv,
514 struct iwl_rx_queue *q); 510 struct iwl_rx_queue *q);
515int iwl_rx_queue_space(const struct iwl_rx_queue *q); 511int iwl_rx_queue_space(const struct iwl_rx_queue *q);
@@ -527,12 +523,6 @@ void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
527/***************************************************** 523/*****************************************************
528* TX 524* TX
529******************************************************/ 525******************************************************/
530void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq);
531int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
532 struct iwl_tx_queue *txq,
533 dma_addr_t addr, u16 len, u8 reset, u8 pad);
534int iwl_hw_tx_queue_init(struct iwl_priv *priv,
535 struct iwl_tx_queue *txq);
536void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq); 526void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq);
537int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, 527int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
538 int slots_num, u32 txq_id); 528 int slots_num, u32 txq_id);
@@ -548,31 +538,9 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force);
548 * Rate 538 * Rate
549 ******************************************************************************/ 539 ******************************************************************************/
550 540
551int iwl_hwrate_to_plcp_idx(u32 rate_n_flags);
552
553u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv, 541u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv,
554 struct iwl_rxon_context *ctx); 542 struct iwl_rxon_context *ctx);
555 543
556u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx, u8 valid);
557
558static inline u32 iwl_ant_idx_to_flags(u8 ant_idx)
559{
560 return BIT(ant_idx) << RATE_MCS_ANT_POS;
561}
562
563static inline u8 iwl_hw_get_rate(__le32 rate_n_flags)
564{
565 return le32_to_cpu(rate_n_flags) & 0xFF;
566}
567static inline u32 iwl_hw_get_rate_n_flags(__le32 rate_n_flags)
568{
569 return le32_to_cpu(rate_n_flags) & 0x1FFFF;
570}
571static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags)
572{
573 return cpu_to_le32(flags|(u32)rate);
574}
575
576/******************************************************************************* 544/*******************************************************************************
577 * Scanning 545 * Scanning
578 ******************************************************************************/ 546 ******************************************************************************/
@@ -608,13 +576,6 @@ void iwl_cancel_scan_deferred_work(struct iwl_priv *priv);
608 576
609#define IWL_SCAN_CHECK_WATCHDOG (HZ * 7) 577#define IWL_SCAN_CHECK_WATCHDOG (HZ * 7)
610 578
611/*******************************************************************************
612 * Calibrations - implemented in iwl-calib.c
613 ******************************************************************************/
614int iwl_send_calib_results(struct iwl_priv *priv);
615int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len);
616void iwl_calib_free_results(struct iwl_priv *priv);
617
618/***************************************************** 579/*****************************************************
619 * S e n d i n g H o s t C o m m a n d s * 580 * S e n d i n g H o s t C o m m a n d s *
620 *****************************************************/ 581 *****************************************************/
@@ -664,8 +625,6 @@ int iwl_pci_resume(struct pci_dev *pdev);
664void iwl_dump_nic_error_log(struct iwl_priv *priv); 625void iwl_dump_nic_error_log(struct iwl_priv *priv);
665int iwl_dump_nic_event_log(struct iwl_priv *priv, 626int iwl_dump_nic_event_log(struct iwl_priv *priv,
666 bool full_log, char **buf, bool display); 627 bool full_log, char **buf, bool display);
667void iwl_dump_csr(struct iwl_priv *priv);
668int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display);
669#ifdef CONFIG_IWLWIFI_DEBUG 628#ifdef CONFIG_IWLWIFI_DEBUG
670void iwl_print_rx_config_cmd(struct iwl_priv *priv, 629void iwl_print_rx_config_cmd(struct iwl_priv *priv,
671 struct iwl_rxon_context *ctx); 630 struct iwl_rxon_context *ctx);
@@ -751,8 +710,6 @@ static inline int iwl_is_ready_rf(struct iwl_priv *priv)
751extern void iwl_send_bt_config(struct iwl_priv *priv); 710extern void iwl_send_bt_config(struct iwl_priv *priv);
752extern int iwl_send_statistics_request(struct iwl_priv *priv, 711extern int iwl_send_statistics_request(struct iwl_priv *priv,
753 u8 flags, bool clear); 712 u8 flags, bool clear);
754extern int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
755 struct iwl_link_quality_cmd *lq, u8 flags, bool init);
756void iwl_apm_stop(struct iwl_priv *priv); 713void iwl_apm_stop(struct iwl_priv *priv);
757int iwl_apm_init(struct iwl_priv *priv); 714int iwl_apm_init(struct iwl_priv *priv);
758 715
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index fc340311ea0a..96d9085639e3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -39,7 +39,6 @@
39#include "iwl-debug.h" 39#include "iwl-debug.h"
40#include "iwl-core.h" 40#include "iwl-core.h"
41#include "iwl-io.h" 41#include "iwl-io.h"
42#include "iwl-calib.h"
43 42
44/* create and remove of files */ 43/* create and remove of files */
45#define DEBUGFS_ADD_FILE(name, parent, mode) do { \ 44#define DEBUGFS_ADD_FILE(name, parent, mode) do { \
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 90a37a94c698..70e07fa48405 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -282,13 +282,6 @@ struct iwl_channel_info {
282 */ 282 */
283#define IWL_IPAN_MCAST_QUEUE 8 283#define IWL_IPAN_MCAST_QUEUE 8
284 284
285/* Power management (not Tx power) structures */
286
287enum iwl_pwr_src {
288 IWL_PWR_SRC_VMAIN,
289 IWL_PWR_SRC_VAUX,
290};
291
292#define IEEE80211_DATA_LEN 2304 285#define IEEE80211_DATA_LEN 2304
293#define IEEE80211_4ADDR_LEN 30 286#define IEEE80211_4ADDR_LEN 30
294#define IEEE80211_HLEN (IEEE80211_4ADDR_LEN) 287#define IEEE80211_HLEN (IEEE80211_4ADDR_LEN)
@@ -732,7 +725,6 @@ struct iwl_hw_params {
732 * 725 *
733 ****************************************************************************/ 726 ****************************************************************************/
734extern void iwl_update_chain_flags(struct iwl_priv *priv); 727extern void iwl_update_chain_flags(struct iwl_priv *priv);
735extern int iwl_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src);
736extern const u8 iwl_bcast_addr[ETH_ALEN]; 728extern const u8 iwl_bcast_addr[ETH_ALEN];
737extern int iwl_rxq_stop(struct iwl_priv *priv); 729extern int iwl_rxq_stop(struct iwl_priv *priv);
738extern void iwl_txq_ctx_stop(struct iwl_priv *priv); 730extern void iwl_txq_ctx_stop(struct iwl_priv *priv);
@@ -843,6 +835,7 @@ enum iwl_calib {
843 IWL_CALIB_TX_IQ, 835 IWL_CALIB_TX_IQ,
844 IWL_CALIB_TX_IQ_PERD, 836 IWL_CALIB_TX_IQ_PERD,
845 IWL_CALIB_BASE_BAND, 837 IWL_CALIB_BASE_BAND,
838 IWL_CALIB_TEMP_OFFSET,
846 IWL_CALIB_MAX 839 IWL_CALIB_MAX
847}; 840};
848 841
@@ -1390,8 +1383,6 @@ struct iwl_priv {
1390 1383
1391 enum nl80211_iftype iw_mode; 1384 enum nl80211_iftype iw_mode;
1392 1385
1393 struct sk_buff *ibss_beacon;
1394
1395 /* Last Rx'd beacon timestamp */ 1386 /* Last Rx'd beacon timestamp */
1396 u64 timestamp; 1387 u64 timestamp;
1397 1388
@@ -1503,8 +1494,10 @@ struct iwl_priv {
1503 struct work_struct scan_completed; 1494 struct work_struct scan_completed;
1504 struct work_struct rx_replenish; 1495 struct work_struct rx_replenish;
1505 struct work_struct abort_scan; 1496 struct work_struct abort_scan;
1497
1506 struct work_struct beacon_update; 1498 struct work_struct beacon_update;
1507 struct iwl_rxon_context *beacon_ctx; 1499 struct iwl_rxon_context *beacon_ctx;
1500 struct sk_buff *beacon_skb;
1508 1501
1509 struct work_struct tt_work; 1502 struct work_struct tt_work;
1510 struct work_struct ct_enter; 1503 struct work_struct ct_enter;
@@ -1566,7 +1559,6 @@ static inline void iwl_txq_ctx_deactivate(struct iwl_priv *priv, int txq_id)
1566} 1559}
1567 1560
1568#ifdef CONFIG_IWLWIFI_DEBUG 1561#ifdef CONFIG_IWLWIFI_DEBUG
1569const char *iwl_get_tx_fail_reason(u32 status);
1570/* 1562/*
1571 * iwl_get_debug_level: Return active debug level for device 1563 * iwl_get_debug_level: Return active debug level for device
1572 * 1564 *
@@ -1582,8 +1574,6 @@ static inline u32 iwl_get_debug_level(struct iwl_priv *priv)
1582 return iwl_debug_level; 1574 return iwl_debug_level;
1583} 1575}
1584#else 1576#else
1585static inline const char *iwl_get_tx_fail_reason(u32 status) { return ""; }
1586
1587static inline u32 iwl_get_debug_level(struct iwl_priv *priv) 1577static inline u32 iwl_get_debug_level(struct iwl_priv *priv)
1588{ 1578{
1589 return iwl_debug_level; 1579 return iwl_debug_level;
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index 88f4a80d4733..87cd10ff285d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -136,85 +136,13 @@ static const u8 iwl_eeprom_band_7[] = { /* 5.2 ht40 channel */
136 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157 136 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157
137}; 137};
138 138
139/**
140 * struct iwl_txpwr_section: eeprom section information
141 * @offset: indirect address into eeprom image
142 * @count: number of "struct iwl_eeprom_enhanced_txpwr" in this section
143 * @band: band type for the section
144 * @is_common - true: common section, false: channel section
145 * @is_cck - true: cck section, false: not cck section
146 * @is_ht_40 - true: all channel in the section are HT40 channel,
147 * false: legacy or HT 20 MHz
148 * ignore if it is common section
149 * @iwl_eeprom_section_channel: channel array in the section,
150 * ignore if common section
151 */
152struct iwl_txpwr_section {
153 u32 offset;
154 u8 count;
155 enum ieee80211_band band;
156 bool is_common;
157 bool is_cck;
158 bool is_ht40;
159 u8 iwl_eeprom_section_channel[EEPROM_MAX_TXPOWER_SECTION_ELEMENTS];
160};
161
162/**
163 * section 1 - 3 are regulatory tx power apply to all channels based on
164 * modulation: CCK, OFDM
165 * Band: 2.4GHz, 5.2GHz
166 * section 4 - 10 are regulatory tx power apply to specified channels
167 * For example:
168 * 1L - Channel 1 Legacy
169 * 1HT - Channel 1 HT
170 * (1,+1) - Channel 1 HT40 "_above_"
171 *
172 * Section 1: all CCK channels
173 * Section 2: all 2.4 GHz OFDM (Legacy, HT and HT40) channels
174 * Section 3: all 5.2 GHz OFDM (Legacy, HT and HT40) channels
175 * Section 4: 2.4 GHz 20MHz channels: 1L, 1HT, 2L, 2HT, 10L, 10HT, 11L, 11HT
176 * Section 5: 2.4 GHz 40MHz channels: (1,+1) (2,+1) (6,+1) (7,+1) (9,+1)
177 * Section 6: 5.2 GHz 20MHz channels: 36L, 64L, 100L, 36HT, 64HT, 100HT
178 * Section 7: 5.2 GHz 40MHz channels: (36,+1) (60,+1) (100,+1)
179 * Section 8: 2.4 GHz channel: 13L, 13HT
180 * Section 9: 2.4 GHz channel: 140L, 140HT
181 * Section 10: 2.4 GHz 40MHz channels: (132,+1) (44,+1)
182 *
183 */
184static const struct iwl_txpwr_section enhinfo[] = {
185 { EEPROM_LB_CCK_20_COMMON, 1, IEEE80211_BAND_2GHZ, true, true, false },
186 { EEPROM_LB_OFDM_COMMON, 3, IEEE80211_BAND_2GHZ, true, false, false },
187 { EEPROM_HB_OFDM_COMMON, 3, IEEE80211_BAND_5GHZ, true, false, false },
188 { EEPROM_LB_OFDM_20_BAND, 8, IEEE80211_BAND_2GHZ,
189 false, false, false,
190 {1, 1, 2, 2, 10, 10, 11, 11 } },
191 { EEPROM_LB_OFDM_HT40_BAND, 5, IEEE80211_BAND_2GHZ,
192 false, false, true,
193 { 1, 2, 6, 7, 9 } },
194 { EEPROM_HB_OFDM_20_BAND, 6, IEEE80211_BAND_5GHZ,
195 false, false, false,
196 { 36, 64, 100, 36, 64, 100 } },
197 { EEPROM_HB_OFDM_HT40_BAND, 3, IEEE80211_BAND_5GHZ,
198 false, false, true,
199 { 36, 60, 100 } },
200 { EEPROM_LB_OFDM_20_CHANNEL_13, 2, IEEE80211_BAND_2GHZ,
201 false, false, false,
202 { 13, 13 } },
203 { EEPROM_HB_OFDM_20_CHANNEL_140, 2, IEEE80211_BAND_5GHZ,
204 false, false, false,
205 { 140, 140 } },
206 { EEPROM_HB_OFDM_HT40_BAND_1, 2, IEEE80211_BAND_5GHZ,
207 false, false, true,
208 { 132, 44 } },
209};
210
211/****************************************************************************** 139/******************************************************************************
212 * 140 *
213 * EEPROM related functions 141 * EEPROM related functions
214 * 142 *
215******************************************************************************/ 143******************************************************************************/
216 144
217int iwlcore_eeprom_verify_signature(struct iwl_priv *priv) 145static int iwl_eeprom_verify_signature(struct iwl_priv *priv)
218{ 146{
219 u32 gp = iwl_read32(priv, CSR_EEPROM_GP) & CSR_EEPROM_GP_VALID_MSK; 147 u32 gp = iwl_read32(priv, CSR_EEPROM_GP) & CSR_EEPROM_GP_VALID_MSK;
220 int ret = 0; 148 int ret = 0;
@@ -246,7 +174,6 @@ int iwlcore_eeprom_verify_signature(struct iwl_priv *priv)
246 } 174 }
247 return ret; 175 return ret;
248} 176}
249EXPORT_SYMBOL(iwlcore_eeprom_verify_signature);
250 177
251static void iwl_set_otp_access(struct iwl_priv *priv, enum iwl_access_mode mode) 178static void iwl_set_otp_access(struct iwl_priv *priv, enum iwl_access_mode mode)
252{ 179{
@@ -290,46 +217,6 @@ static int iwlcore_get_nvm_type(struct iwl_priv *priv)
290 return nvm_type; 217 return nvm_type;
291} 218}
292 219
293/*
294 * The device's EEPROM semaphore prevents conflicts between driver and uCode
295 * when accessing the EEPROM; each access is a series of pulses to/from the
296 * EEPROM chip, not a single event, so even reads could conflict if they
297 * weren't arbitrated by the semaphore.
298 */
299int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv)
300{
301 u16 count;
302 int ret;
303
304 for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) {
305 /* Request semaphore */
306 iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
307 CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
308
309 /* See if we got it */
310 ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG,
311 CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
312 CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
313 EEPROM_SEM_TIMEOUT);
314 if (ret >= 0) {
315 IWL_DEBUG_IO(priv, "Acquired semaphore after %d tries.\n",
316 count+1);
317 return ret;
318 }
319 }
320
321 return ret;
322}
323EXPORT_SYMBOL(iwlcore_eeprom_acquire_semaphore);
324
325void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv)
326{
327 iwl_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
328 CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
329
330}
331EXPORT_SYMBOL(iwlcore_eeprom_release_semaphore);
332
333const u8 *iwlcore_eeprom_query_addr(const struct iwl_priv *priv, size_t offset) 220const u8 *iwlcore_eeprom_query_addr(const struct iwl_priv *priv, size_t offset)
334{ 221{
335 BUG_ON(offset >= priv->cfg->base_params->eeprom_size); 222 BUG_ON(offset >= priv->cfg->base_params->eeprom_size);
@@ -491,6 +378,20 @@ static int iwl_find_otp_image(struct iwl_priv *priv,
491 return -EINVAL; 378 return -EINVAL;
492} 379}
493 380
381const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset)
382{
383 return priv->cfg->ops->lib->eeprom_ops.query_addr(priv, offset);
384}
385EXPORT_SYMBOL(iwl_eeprom_query_addr);
386
387u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset)
388{
389 if (!priv->eeprom)
390 return 0;
391 return (u16)priv->eeprom[offset] | ((u16)priv->eeprom[offset + 1] << 8);
392}
393EXPORT_SYMBOL(iwl_eeprom_query16);
394
494/** 395/**
495 * iwl_eeprom_init - read EEPROM contents 396 * iwl_eeprom_init - read EEPROM contents
496 * 397 *
@@ -523,7 +424,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
523 424
524 priv->cfg->ops->lib->apm_ops.init(priv); 425 priv->cfg->ops->lib->apm_ops.init(priv);
525 426
526 ret = priv->cfg->ops->lib->eeprom_ops.verify_signature(priv); 427 ret = iwl_eeprom_verify_signature(priv);
527 if (ret < 0) { 428 if (ret < 0) {
528 IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp); 429 IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp);
529 ret = -ENOENT; 430 ret = -ENOENT;
@@ -604,7 +505,7 @@ err:
604 if (ret) 505 if (ret)
605 iwl_eeprom_free(priv); 506 iwl_eeprom_free(priv);
606 /* Reset chip to save power until we load uCode during "up". */ 507 /* Reset chip to save power until we load uCode during "up". */
607 priv->cfg->ops->lib->apm_ops.stop(priv); 508 iwl_apm_stop(priv);
608alloc_err: 509alloc_err:
609 return ret; 510 return ret;
610} 511}
@@ -617,53 +518,6 @@ void iwl_eeprom_free(struct iwl_priv *priv)
617} 518}
618EXPORT_SYMBOL(iwl_eeprom_free); 519EXPORT_SYMBOL(iwl_eeprom_free);
619 520
620int iwl_eeprom_check_version(struct iwl_priv *priv)
621{
622 u16 eeprom_ver;
623 u16 calib_ver;
624
625 eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
626 calib_ver = priv->cfg->ops->lib->eeprom_ops.calib_version(priv);
627
628 if (eeprom_ver < priv->cfg->eeprom_ver ||
629 calib_ver < priv->cfg->eeprom_calib_ver)
630 goto err;
631
632 IWL_INFO(priv, "device EEPROM VER=0x%x, CALIB=0x%x\n",
633 eeprom_ver, calib_ver);
634
635 return 0;
636err:
637 IWL_ERR(priv, "Unsupported (too old) EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n",
638 eeprom_ver, priv->cfg->eeprom_ver,
639 calib_ver, priv->cfg->eeprom_calib_ver);
640 return -EINVAL;
641
642}
643EXPORT_SYMBOL(iwl_eeprom_check_version);
644
645const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset)
646{
647 return priv->cfg->ops->lib->eeprom_ops.query_addr(priv, offset);
648}
649EXPORT_SYMBOL(iwl_eeprom_query_addr);
650
651u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset)
652{
653 if (!priv->eeprom)
654 return 0;
655 return (u16)priv->eeprom[offset] | ((u16)priv->eeprom[offset + 1] << 8);
656}
657EXPORT_SYMBOL(iwl_eeprom_query16);
658
659void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac)
660{
661 const u8 *addr = priv->cfg->ops->lib->eeprom_ops.query_addr(priv,
662 EEPROM_MAC_ADDRESS);
663 memcpy(mac, addr, ETH_ALEN);
664}
665EXPORT_SYMBOL(iwl_eeprom_get_mac);
666
667static void iwl_init_band_reference(const struct iwl_priv *priv, 521static void iwl_init_band_reference(const struct iwl_priv *priv,
668 int eep_band, int *eeprom_ch_count, 522 int eep_band, int *eeprom_ch_count,
669 const struct iwl_eeprom_channel **eeprom_ch_info, 523 const struct iwl_eeprom_channel **eeprom_ch_info,
@@ -722,7 +576,6 @@ static void iwl_init_band_reference(const struct iwl_priv *priv,
722 576
723#define CHECK_AND_PRINT(x) ((eeprom_ch->flags & EEPROM_CHANNEL_##x) \ 577#define CHECK_AND_PRINT(x) ((eeprom_ch->flags & EEPROM_CHANNEL_##x) \
724 ? # x " " : "") 578 ? # x " " : "")
725
726/** 579/**
727 * iwl_mod_ht40_chan_info - Copy ht40 channel info into driver's priv. 580 * iwl_mod_ht40_chan_info - Copy ht40 channel info into driver's priv.
728 * 581 *
@@ -766,205 +619,6 @@ static int iwl_mod_ht40_chan_info(struct iwl_priv *priv,
766 return 0; 619 return 0;
767} 620}
768 621
769/**
770 * iwl_get_max_txpower_avg - get the highest tx power from all chains.
771 * find the highest tx power from all chains for the channel
772 */
773static s8 iwl_get_max_txpower_avg(struct iwl_priv *priv,
774 struct iwl_eeprom_enhanced_txpwr *enhanced_txpower,
775 int element, s8 *max_txpower_in_half_dbm)
776{
777 s8 max_txpower_avg = 0; /* (dBm) */
778
779 IWL_DEBUG_INFO(priv, "%d - "
780 "chain_a: %d dB chain_b: %d dB "
781 "chain_c: %d dB mimo2: %d dB mimo3: %d dB\n",
782 element,
783 enhanced_txpower[element].chain_a_max >> 1,
784 enhanced_txpower[element].chain_b_max >> 1,
785 enhanced_txpower[element].chain_c_max >> 1,
786 enhanced_txpower[element].mimo2_max >> 1,
787 enhanced_txpower[element].mimo3_max >> 1);
788 /* Take the highest tx power from any valid chains */
789 if ((priv->cfg->valid_tx_ant & ANT_A) &&
790 (enhanced_txpower[element].chain_a_max > max_txpower_avg))
791 max_txpower_avg = enhanced_txpower[element].chain_a_max;
792 if ((priv->cfg->valid_tx_ant & ANT_B) &&
793 (enhanced_txpower[element].chain_b_max > max_txpower_avg))
794 max_txpower_avg = enhanced_txpower[element].chain_b_max;
795 if ((priv->cfg->valid_tx_ant & ANT_C) &&
796 (enhanced_txpower[element].chain_c_max > max_txpower_avg))
797 max_txpower_avg = enhanced_txpower[element].chain_c_max;
798 if (((priv->cfg->valid_tx_ant == ANT_AB) |
799 (priv->cfg->valid_tx_ant == ANT_BC) |
800 (priv->cfg->valid_tx_ant == ANT_AC)) &&
801 (enhanced_txpower[element].mimo2_max > max_txpower_avg))
802 max_txpower_avg = enhanced_txpower[element].mimo2_max;
803 if ((priv->cfg->valid_tx_ant == ANT_ABC) &&
804 (enhanced_txpower[element].mimo3_max > max_txpower_avg))
805 max_txpower_avg = enhanced_txpower[element].mimo3_max;
806
807 /*
808 * max. tx power in EEPROM is in 1/2 dBm format
809 * convert from 1/2 dBm to dBm (round-up convert)
810 * but we also do not want to loss 1/2 dBm resolution which
811 * will impact performance
812 */
813 *max_txpower_in_half_dbm = max_txpower_avg;
814 return (max_txpower_avg & 0x01) + (max_txpower_avg >> 1);
815}
816
817/**
818 * iwl_update_common_txpower: update channel tx power
819 * update tx power per band based on EEPROM enhanced tx power info.
820 */
821static s8 iwl_update_common_txpower(struct iwl_priv *priv,
822 struct iwl_eeprom_enhanced_txpwr *enhanced_txpower,
823 int section, int element, s8 *max_txpower_in_half_dbm)
824{
825 struct iwl_channel_info *ch_info;
826 int ch;
827 bool is_ht40 = false;
828 s8 max_txpower_avg; /* (dBm) */
829
830 /* it is common section, contain all type (Legacy, HT and HT40)
831 * based on the element in the section to determine
832 * is it HT 40 or not
833 */
834 if (element == EEPROM_TXPOWER_COMMON_HT40_INDEX)
835 is_ht40 = true;
836 max_txpower_avg =
837 iwl_get_max_txpower_avg(priv, enhanced_txpower,
838 element, max_txpower_in_half_dbm);
839
840 ch_info = priv->channel_info;
841
842 for (ch = 0; ch < priv->channel_count; ch++) {
843 /* find matching band and update tx power if needed */
844 if ((ch_info->band == enhinfo[section].band) &&
845 (ch_info->max_power_avg < max_txpower_avg) &&
846 (!is_ht40)) {
847 /* Update regulatory-based run-time data */
848 ch_info->max_power_avg = ch_info->curr_txpow =
849 max_txpower_avg;
850 ch_info->scan_power = max_txpower_avg;
851 }
852 if ((ch_info->band == enhinfo[section].band) && is_ht40 &&
853 (ch_info->ht40_max_power_avg < max_txpower_avg)) {
854 /* Update regulatory-based run-time data */
855 ch_info->ht40_max_power_avg = max_txpower_avg;
856 }
857 ch_info++;
858 }
859 return max_txpower_avg;
860}
861
862/**
863 * iwl_update_channel_txpower: update channel tx power
864 * update channel tx power based on EEPROM enhanced tx power info.
865 */
866static s8 iwl_update_channel_txpower(struct iwl_priv *priv,
867 struct iwl_eeprom_enhanced_txpwr *enhanced_txpower,
868 int section, int element, s8 *max_txpower_in_half_dbm)
869{
870 struct iwl_channel_info *ch_info;
871 int ch;
872 u8 channel;
873 s8 max_txpower_avg; /* (dBm) */
874
875 channel = enhinfo[section].iwl_eeprom_section_channel[element];
876 max_txpower_avg =
877 iwl_get_max_txpower_avg(priv, enhanced_txpower,
878 element, max_txpower_in_half_dbm);
879
880 ch_info = priv->channel_info;
881 for (ch = 0; ch < priv->channel_count; ch++) {
882 /* find matching channel and update tx power if needed */
883 if (ch_info->channel == channel) {
884 if ((ch_info->max_power_avg < max_txpower_avg) &&
885 (!enhinfo[section].is_ht40)) {
886 /* Update regulatory-based run-time data */
887 ch_info->max_power_avg = max_txpower_avg;
888 ch_info->curr_txpow = max_txpower_avg;
889 ch_info->scan_power = max_txpower_avg;
890 }
891 if ((enhinfo[section].is_ht40) &&
892 (ch_info->ht40_max_power_avg < max_txpower_avg)) {
893 /* Update regulatory-based run-time data */
894 ch_info->ht40_max_power_avg = max_txpower_avg;
895 }
896 break;
897 }
898 ch_info++;
899 }
900 return max_txpower_avg;
901}
902
903/**
904 * iwlcore_eeprom_enhanced_txpower: process enhanced tx power info
905 */
906void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv)
907{
908 int eeprom_section_count = 0;
909 int section, element;
910 struct iwl_eeprom_enhanced_txpwr *enhanced_txpower;
911 u32 offset;
912 s8 max_txpower_avg; /* (dBm) */
913 s8 max_txpower_in_half_dbm; /* (half-dBm) */
914
915 /* Loop through all the sections
916 * adjust bands and channel's max tx power
917 * Set the tx_power_user_lmt to the highest power
918 * supported by any channels and chains
919 */
920 for (section = 0; section < ARRAY_SIZE(enhinfo); section++) {
921 eeprom_section_count = enhinfo[section].count;
922 offset = enhinfo[section].offset;
923 enhanced_txpower = (struct iwl_eeprom_enhanced_txpwr *)
924 iwl_eeprom_query_addr(priv, offset);
925
926 /*
927 * check for valid entry -
928 * different version of EEPROM might contain different set
929 * of enhanced tx power table
930 * always check for valid entry before process
931 * the information
932 */
933 if (!enhanced_txpower->common || enhanced_txpower->reserved)
934 continue;
935
936 for (element = 0; element < eeprom_section_count; element++) {
937 if (enhinfo[section].is_common)
938 max_txpower_avg =
939 iwl_update_common_txpower(priv,
940 enhanced_txpower, section,
941 element,
942 &max_txpower_in_half_dbm);
943 else
944 max_txpower_avg =
945 iwl_update_channel_txpower(priv,
946 enhanced_txpower, section,
947 element,
948 &max_txpower_in_half_dbm);
949
950 /* Update the tx_power_user_lmt to the highest power
951 * supported by any channel */
952 if (max_txpower_avg > priv->tx_power_user_lmt)
953 priv->tx_power_user_lmt = max_txpower_avg;
954
955 /*
956 * Update the tx_power_lmt_in_half_dbm to
957 * the highest power supported by any channel
958 */
959 if (max_txpower_in_half_dbm >
960 priv->tx_power_lmt_in_half_dbm)
961 priv->tx_power_lmt_in_half_dbm =
962 max_txpower_in_half_dbm;
963 }
964 }
965}
966EXPORT_SYMBOL(iwlcore_eeprom_enhanced_txpower);
967
968#define CHECK_AND_PRINT_I(x) ((eeprom_ch_info[ch].flags & EEPROM_CHANNEL_##x) \ 622#define CHECK_AND_PRINT_I(x) ((eeprom_ch_info[ch].flags & EEPROM_CHANNEL_##x) \
969 ? # x " " : "") 623 ? # x " " : "")
970 624
@@ -1162,4 +816,3 @@ const struct iwl_channel_info *iwl_get_channel_info(const struct iwl_priv *priv,
1162 return NULL; 816 return NULL;
1163} 817}
1164EXPORT_SYMBOL(iwl_get_channel_info); 818EXPORT_SYMBOL(iwl_get_channel_info);
1165
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
index a4772aff51fe..d9b590625ae4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
@@ -493,7 +493,6 @@ struct iwl_eeprom_calib_info {
493 493
494struct iwl_eeprom_ops { 494struct iwl_eeprom_ops {
495 const u32 regulatory_bands[7]; 495 const u32 regulatory_bands[7];
496 int (*verify_signature) (struct iwl_priv *priv);
497 int (*acquire_semaphore) (struct iwl_priv *priv); 496 int (*acquire_semaphore) (struct iwl_priv *priv);
498 void (*release_semaphore) (struct iwl_priv *priv); 497 void (*release_semaphore) (struct iwl_priv *priv);
499 u16 (*calib_version) (struct iwl_priv *priv); 498 u16 (*calib_version) (struct iwl_priv *priv);
@@ -502,18 +501,13 @@ struct iwl_eeprom_ops {
502}; 501};
503 502
504 503
505void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac);
506int iwl_eeprom_init(struct iwl_priv *priv); 504int iwl_eeprom_init(struct iwl_priv *priv);
507void iwl_eeprom_free(struct iwl_priv *priv); 505void iwl_eeprom_free(struct iwl_priv *priv);
508int iwl_eeprom_check_version(struct iwl_priv *priv); 506int iwl_eeprom_check_version(struct iwl_priv *priv);
509const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset); 507const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset);
510u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset);
511
512int iwlcore_eeprom_verify_signature(struct iwl_priv *priv); 508int iwlcore_eeprom_verify_signature(struct iwl_priv *priv);
513int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv); 509u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset);
514void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv);
515const u8 *iwlcore_eeprom_query_addr(const struct iwl_priv *priv, size_t offset); 510const u8 *iwlcore_eeprom_query_addr(const struct iwl_priv *priv, size_t offset);
516void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv);
517int iwl_init_channel_map(struct iwl_priv *priv); 511int iwl_init_channel_map(struct iwl_priv *priv);
518void iwl_free_channel_map(struct iwl_priv *priv); 512void iwl_free_channel_map(struct iwl_priv *priv);
519const struct iwl_channel_info *iwl_get_channel_info( 513const struct iwl_channel_info *iwl_get_channel_info(
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h
index 621abe3c5afc..1aaef70deaec 100644
--- a/drivers/net/wireless/iwlwifi/iwl-helpers.h
+++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h
@@ -44,11 +44,6 @@ static inline struct ieee80211_conf *ieee80211_get_hw_conf(
44 return &hw->conf; 44 return &hw->conf;
45} 45}
46 46
47static inline int iwl_check_bits(unsigned long field, unsigned long mask)
48{
49 return ((field & mask) == mask) ? 1 : 0;
50}
51
52static inline unsigned long elapsed_jiffies(unsigned long start, 47static inline unsigned long elapsed_jiffies(unsigned long start,
53 unsigned long end) 48 unsigned long end)
54{ 49{
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index 10be197b0f22..f436270ca39a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -36,7 +36,6 @@
36#include "iwl-core.h" 36#include "iwl-core.h"
37#include "iwl-sta.h" 37#include "iwl-sta.h"
38#include "iwl-io.h" 38#include "iwl-io.h"
39#include "iwl-calib.h"
40#include "iwl-helpers.h" 39#include "iwl-helpers.h"
41/************************** RX-FUNCTIONS ****************************/ 40/************************** RX-FUNCTIONS ****************************/
42/* 41/*
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index eaae49ee0c60..67da31295781 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -121,7 +121,6 @@ void iwl_force_scan_end(struct iwl_priv *priv)
121 clear_bit(STATUS_SCAN_ABORTING, &priv->status); 121 clear_bit(STATUS_SCAN_ABORTING, &priv->status);
122 iwl_complete_scan(priv, true); 122 iwl_complete_scan(priv, true);
123} 123}
124EXPORT_SYMBOL(iwl_force_scan_end);
125 124
126static void iwl_do_scan_abort(struct iwl_priv *priv) 125static void iwl_do_scan_abort(struct iwl_priv *priv)
127{ 126{
@@ -559,7 +558,6 @@ static void iwl_bg_scan_completed(struct work_struct *work)
559 struct iwl_priv *priv = 558 struct iwl_priv *priv =
560 container_of(work, struct iwl_priv, scan_completed); 559 container_of(work, struct iwl_priv, scan_completed);
561 bool aborted; 560 bool aborted;
562 struct iwl_rxon_context *ctx;
563 561
564 IWL_DEBUG_SCAN(priv, "Completed %sscan.\n", 562 IWL_DEBUG_SCAN(priv, "Completed %sscan.\n",
565 priv->is_internal_short_scan ? "internal short " : ""); 563 priv->is_internal_short_scan ? "internal short " : "");
@@ -609,15 +607,7 @@ out_settings:
609 * performing the scan, fire one off */ 607 * performing the scan, fire one off */
610 iwl_set_tx_power(priv, priv->tx_power_user_lmt, true); 608 iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);
611 609
612 /* 610 priv->cfg->ops->utils->post_scan(priv);
613 * Since setting the RXON may have been deferred while
614 * performing the scan, fire one off if needed
615 */
616 for_each_context(priv, ctx)
617 iwlcore_commit_rxon(priv, ctx);
618
619 if (priv->cfg->ops->hcmd->set_pan_params)
620 priv->cfg->ops->hcmd->set_pan_params(priv);
621 611
622 out: 612 out:
623 mutex_unlock(&priv->mutex); 613 mutex_unlock(&priv->mutex);
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 6edd0341dfe2..7c7f7dcb1b1e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -228,9 +228,8 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
228 * 228 *
229 * should be called with sta_lock held 229 * should be called with sta_lock held
230 */ 230 */
231static u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, 231u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
232 const u8 *addr, bool is_ap, 232 const u8 *addr, bool is_ap, struct ieee80211_sta *sta)
233 struct ieee80211_sta *sta)
234{ 233{
235 struct iwl_station_entry *station; 234 struct iwl_station_entry *station;
236 int i; 235 int i;
@@ -317,6 +316,7 @@ static u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
317 return sta_id; 316 return sta_id;
318 317
319} 318}
319EXPORT_SYMBOL_GPL(iwl_prep_station);
320 320
321#define STA_WAIT_TIMEOUT (HZ/2) 321#define STA_WAIT_TIMEOUT (HZ/2)
322 322
@@ -381,108 +381,6 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
381} 381}
382EXPORT_SYMBOL(iwl_add_station_common); 382EXPORT_SYMBOL(iwl_add_station_common);
383 383
384static struct iwl_link_quality_cmd *iwl_sta_alloc_lq(struct iwl_priv *priv,
385 u8 sta_id)
386{
387 int i, r;
388 struct iwl_link_quality_cmd *link_cmd;
389 u32 rate_flags = 0;
390 __le32 rate_n_flags;
391
392 link_cmd = kzalloc(sizeof(struct iwl_link_quality_cmd), GFP_KERNEL);
393 if (!link_cmd) {
394 IWL_ERR(priv, "Unable to allocate memory for LQ cmd.\n");
395 return NULL;
396 }
397 /* Set up the rate scaling to start at selected rate, fall back
398 * all the way down to 1M in IEEE order, and then spin on 1M */
399 if (priv->band == IEEE80211_BAND_5GHZ)
400 r = IWL_RATE_6M_INDEX;
401 else
402 r = IWL_RATE_1M_INDEX;
403
404 if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE)
405 rate_flags |= RATE_MCS_CCK_MSK;
406
407 rate_flags |= first_antenna(priv->hw_params.valid_tx_ant) <<
408 RATE_MCS_ANT_POS;
409 rate_n_flags = iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags);
410 for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++)
411 link_cmd->rs_table[i].rate_n_flags = rate_n_flags;
412
413 link_cmd->general_params.single_stream_ant_msk =
414 first_antenna(priv->hw_params.valid_tx_ant);
415
416 link_cmd->general_params.dual_stream_ant_msk =
417 priv->hw_params.valid_tx_ant &
418 ~first_antenna(priv->hw_params.valid_tx_ant);
419 if (!link_cmd->general_params.dual_stream_ant_msk) {
420 link_cmd->general_params.dual_stream_ant_msk = ANT_AB;
421 } else if (num_of_ant(priv->hw_params.valid_tx_ant) == 2) {
422 link_cmd->general_params.dual_stream_ant_msk =
423 priv->hw_params.valid_tx_ant;
424 }
425
426 link_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
427 link_cmd->agg_params.agg_time_limit =
428 cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
429
430 link_cmd->sta_id = sta_id;
431
432 return link_cmd;
433}
434
435/*
436 * iwl_add_bssid_station - Add the special IBSS BSSID station
437 *
438 * Function sleeps.
439 */
440int iwl_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
441 const u8 *addr, bool init_rs, u8 *sta_id_r)
442{
443 int ret;
444 u8 sta_id;
445 struct iwl_link_quality_cmd *link_cmd;
446 unsigned long flags;
447
448 if (sta_id_r)
449 *sta_id_r = IWL_INVALID_STATION;
450
451 ret = iwl_add_station_common(priv, ctx, addr, 0, NULL, &sta_id);
452 if (ret) {
453 IWL_ERR(priv, "Unable to add station %pM\n", addr);
454 return ret;
455 }
456
457 if (sta_id_r)
458 *sta_id_r = sta_id;
459
460 spin_lock_irqsave(&priv->sta_lock, flags);
461 priv->stations[sta_id].used |= IWL_STA_LOCAL;
462 spin_unlock_irqrestore(&priv->sta_lock, flags);
463
464 if (init_rs) {
465 /* Set up default rate scaling table in device's station table */
466 link_cmd = iwl_sta_alloc_lq(priv, sta_id);
467 if (!link_cmd) {
468 IWL_ERR(priv, "Unable to initialize rate scaling for station %pM.\n",
469 addr);
470 return -ENOMEM;
471 }
472
473 ret = iwl_send_lq_cmd(priv, ctx, link_cmd, CMD_SYNC, true);
474 if (ret)
475 IWL_ERR(priv, "Link quality command failed (%d)\n", ret);
476
477 spin_lock_irqsave(&priv->sta_lock, flags);
478 priv->stations[sta_id].lq = link_cmd;
479 spin_unlock_irqrestore(&priv->sta_lock, flags);
480 }
481
482 return 0;
483}
484EXPORT_SYMBOL(iwl_add_bssid_station);
485
486/** 384/**
487 * iwl_sta_ucode_deactivate - deactivate ucode status for a station 385 * iwl_sta_ucode_deactivate - deactivate ucode status for a station
488 * 386 *
@@ -738,405 +636,25 @@ int iwl_get_free_ucode_key_index(struct iwl_priv *priv)
738} 636}
739EXPORT_SYMBOL(iwl_get_free_ucode_key_index); 637EXPORT_SYMBOL(iwl_get_free_ucode_key_index);
740 638
741static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, 639void iwl_dealloc_bcast_stations(struct iwl_priv *priv)
742 struct iwl_rxon_context *ctx,
743 bool send_if_empty)
744{
745 int i, not_empty = 0;
746 u8 buff[sizeof(struct iwl_wep_cmd) +
747 sizeof(struct iwl_wep_key) * WEP_KEYS_MAX];
748 struct iwl_wep_cmd *wep_cmd = (struct iwl_wep_cmd *)buff;
749 size_t cmd_size = sizeof(struct iwl_wep_cmd);
750 struct iwl_host_cmd cmd = {
751 .id = ctx->wep_key_cmd,
752 .data = wep_cmd,
753 .flags = CMD_SYNC,
754 };
755
756 might_sleep();
757
758 memset(wep_cmd, 0, cmd_size +
759 (sizeof(struct iwl_wep_key) * WEP_KEYS_MAX));
760
761 for (i = 0; i < WEP_KEYS_MAX ; i++) {
762 wep_cmd->key[i].key_index = i;
763 if (ctx->wep_keys[i].key_size) {
764 wep_cmd->key[i].key_offset = i;
765 not_empty = 1;
766 } else {
767 wep_cmd->key[i].key_offset = WEP_INVALID_OFFSET;
768 }
769
770 wep_cmd->key[i].key_size = ctx->wep_keys[i].key_size;
771 memcpy(&wep_cmd->key[i].key[3], ctx->wep_keys[i].key,
772 ctx->wep_keys[i].key_size);
773 }
774
775 wep_cmd->global_key_type = WEP_KEY_WEP_TYPE;
776 wep_cmd->num_keys = WEP_KEYS_MAX;
777
778 cmd_size += sizeof(struct iwl_wep_key) * WEP_KEYS_MAX;
779
780 cmd.len = cmd_size;
781
782 if (not_empty || send_if_empty)
783 return iwl_send_cmd(priv, &cmd);
784 else
785 return 0;
786}
787
788int iwl_restore_default_wep_keys(struct iwl_priv *priv,
789 struct iwl_rxon_context *ctx)
790{
791 lockdep_assert_held(&priv->mutex);
792
793 return iwl_send_static_wepkey_cmd(priv, ctx, false);
794}
795EXPORT_SYMBOL(iwl_restore_default_wep_keys);
796
797int iwl_remove_default_wep_key(struct iwl_priv *priv,
798 struct iwl_rxon_context *ctx,
799 struct ieee80211_key_conf *keyconf)
800{
801 int ret;
802
803 lockdep_assert_held(&priv->mutex);
804
805 IWL_DEBUG_WEP(priv, "Removing default WEP key: idx=%d\n",
806 keyconf->keyidx);
807
808 memset(&ctx->wep_keys[keyconf->keyidx], 0, sizeof(ctx->wep_keys[0]));
809 if (iwl_is_rfkill(priv)) {
810 IWL_DEBUG_WEP(priv, "Not sending REPLY_WEPKEY command due to RFKILL.\n");
811 /* but keys in device are clear anyway so return success */
812 return 0;
813 }
814 ret = iwl_send_static_wepkey_cmd(priv, ctx, 1);
815 IWL_DEBUG_WEP(priv, "Remove default WEP key: idx=%d ret=%d\n",
816 keyconf->keyidx, ret);
817
818 return ret;
819}
820EXPORT_SYMBOL(iwl_remove_default_wep_key);
821
822int iwl_set_default_wep_key(struct iwl_priv *priv,
823 struct iwl_rxon_context *ctx,
824 struct ieee80211_key_conf *keyconf)
825{
826 int ret;
827
828 lockdep_assert_held(&priv->mutex);
829
830 if (keyconf->keylen != WEP_KEY_LEN_128 &&
831 keyconf->keylen != WEP_KEY_LEN_64) {
832 IWL_DEBUG_WEP(priv, "Bad WEP key length %d\n", keyconf->keylen);
833 return -EINVAL;
834 }
835
836 keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV;
837 keyconf->hw_key_idx = HW_KEY_DEFAULT;
838 priv->stations[ctx->ap_sta_id].keyinfo.cipher = keyconf->cipher;
839
840 ctx->wep_keys[keyconf->keyidx].key_size = keyconf->keylen;
841 memcpy(&ctx->wep_keys[keyconf->keyidx].key, &keyconf->key,
842 keyconf->keylen);
843
844 ret = iwl_send_static_wepkey_cmd(priv, ctx, false);
845 IWL_DEBUG_WEP(priv, "Set default WEP key: len=%d idx=%d ret=%d\n",
846 keyconf->keylen, keyconf->keyidx, ret);
847
848 return ret;
849}
850EXPORT_SYMBOL(iwl_set_default_wep_key);
851
852static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv,
853 struct iwl_rxon_context *ctx,
854 struct ieee80211_key_conf *keyconf,
855 u8 sta_id)
856{
857 unsigned long flags;
858 __le16 key_flags = 0;
859 struct iwl_addsta_cmd sta_cmd;
860
861 lockdep_assert_held(&priv->mutex);
862
863 keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV;
864
865 key_flags |= (STA_KEY_FLG_WEP | STA_KEY_FLG_MAP_KEY_MSK);
866 key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
867 key_flags &= ~STA_KEY_FLG_INVALID;
868
869 if (keyconf->keylen == WEP_KEY_LEN_128)
870 key_flags |= STA_KEY_FLG_KEY_SIZE_MSK;
871
872 if (sta_id == ctx->bcast_sta_id)
873 key_flags |= STA_KEY_MULTICAST_MSK;
874
875 spin_lock_irqsave(&priv->sta_lock, flags);
876
877 priv->stations[sta_id].keyinfo.cipher = keyconf->cipher;
878 priv->stations[sta_id].keyinfo.keylen = keyconf->keylen;
879 priv->stations[sta_id].keyinfo.keyidx = keyconf->keyidx;
880
881 memcpy(priv->stations[sta_id].keyinfo.key,
882 keyconf->key, keyconf->keylen);
883
884 memcpy(&priv->stations[sta_id].sta.key.key[3],
885 keyconf->key, keyconf->keylen);
886
887 if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
888 == STA_KEY_FLG_NO_ENC)
889 priv->stations[sta_id].sta.key.key_offset =
890 iwl_get_free_ucode_key_index(priv);
891 /* else, we are overriding an existing key => no need to allocated room
892 * in uCode. */
893
894 WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
895 "no space for a new key");
896
897 priv->stations[sta_id].sta.key.key_flags = key_flags;
898 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
899 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
900
901 memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
902 spin_unlock_irqrestore(&priv->sta_lock, flags);
903
904 return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
905}
906
907static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
908 struct iwl_rxon_context *ctx,
909 struct ieee80211_key_conf *keyconf,
910 u8 sta_id)
911{
912 unsigned long flags;
913 __le16 key_flags = 0;
914 struct iwl_addsta_cmd sta_cmd;
915
916 lockdep_assert_held(&priv->mutex);
917
918 key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK);
919 key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
920 key_flags &= ~STA_KEY_FLG_INVALID;
921
922 if (sta_id == ctx->bcast_sta_id)
923 key_flags |= STA_KEY_MULTICAST_MSK;
924
925 keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
926
927 spin_lock_irqsave(&priv->sta_lock, flags);
928 priv->stations[sta_id].keyinfo.cipher = keyconf->cipher;
929 priv->stations[sta_id].keyinfo.keylen = keyconf->keylen;
930
931 memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key,
932 keyconf->keylen);
933
934 memcpy(priv->stations[sta_id].sta.key.key, keyconf->key,
935 keyconf->keylen);
936
937 if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
938 == STA_KEY_FLG_NO_ENC)
939 priv->stations[sta_id].sta.key.key_offset =
940 iwl_get_free_ucode_key_index(priv);
941 /* else, we are overriding an existing key => no need to allocated room
942 * in uCode. */
943
944 WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
945 "no space for a new key");
946
947 priv->stations[sta_id].sta.key.key_flags = key_flags;
948 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
949 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
950
951 memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
952 spin_unlock_irqrestore(&priv->sta_lock, flags);
953
954 return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
955}
956
957static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv,
958 struct iwl_rxon_context *ctx,
959 struct ieee80211_key_conf *keyconf,
960 u8 sta_id)
961{
962 unsigned long flags;
963 int ret = 0;
964 __le16 key_flags = 0;
965
966 key_flags |= (STA_KEY_FLG_TKIP | STA_KEY_FLG_MAP_KEY_MSK);
967 key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
968 key_flags &= ~STA_KEY_FLG_INVALID;
969
970 if (sta_id == ctx->bcast_sta_id)
971 key_flags |= STA_KEY_MULTICAST_MSK;
972
973 keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
974 keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
975
976 spin_lock_irqsave(&priv->sta_lock, flags);
977
978 priv->stations[sta_id].keyinfo.cipher = keyconf->cipher;
979 priv->stations[sta_id].keyinfo.keylen = 16;
980
981 if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
982 == STA_KEY_FLG_NO_ENC)
983 priv->stations[sta_id].sta.key.key_offset =
984 iwl_get_free_ucode_key_index(priv);
985 /* else, we are overriding an existing key => no need to allocated room
986 * in uCode. */
987
988 WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
989 "no space for a new key");
990
991 priv->stations[sta_id].sta.key.key_flags = key_flags;
992
993
994 /* This copy is acutally not needed: we get the key with each TX */
995 memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, 16);
996
997 memcpy(priv->stations[sta_id].sta.key.key, keyconf->key, 16);
998
999 spin_unlock_irqrestore(&priv->sta_lock, flags);
1000
1001 return ret;
1002}
1003
1004void iwl_update_tkip_key(struct iwl_priv *priv,
1005 struct iwl_rxon_context *ctx,
1006 struct ieee80211_key_conf *keyconf,
1007 struct ieee80211_sta *sta, u32 iv32, u16 *phase1key)
1008{ 640{
1009 u8 sta_id;
1010 unsigned long flags; 641 unsigned long flags;
1011 int i; 642 int i;
1012 643
1013 if (iwl_scan_cancel(priv)) {
1014 /* cancel scan failed, just live w/ bad key and rely
1015 briefly on SW decryption */
1016 return;
1017 }
1018
1019 sta_id = iwl_sta_id_or_broadcast(priv, ctx, sta);
1020 if (sta_id == IWL_INVALID_STATION)
1021 return;
1022
1023 spin_lock_irqsave(&priv->sta_lock, flags);
1024
1025 priv->stations[sta_id].sta.key.tkip_rx_tsc_byte2 = (u8) iv32;
1026
1027 for (i = 0; i < 5; i++)
1028 priv->stations[sta_id].sta.key.tkip_rx_ttak[i] =
1029 cpu_to_le16(phase1key[i]);
1030
1031 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
1032 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
1033
1034 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
1035
1036 spin_unlock_irqrestore(&priv->sta_lock, flags);
1037
1038}
1039EXPORT_SYMBOL(iwl_update_tkip_key);
1040
1041int iwl_remove_dynamic_key(struct iwl_priv *priv,
1042 struct iwl_rxon_context *ctx,
1043 struct ieee80211_key_conf *keyconf,
1044 u8 sta_id)
1045{
1046 unsigned long flags;
1047 u16 key_flags;
1048 u8 keyidx;
1049 struct iwl_addsta_cmd sta_cmd;
1050
1051 lockdep_assert_held(&priv->mutex);
1052
1053 ctx->key_mapping_keys--;
1054
1055 spin_lock_irqsave(&priv->sta_lock, flags); 644 spin_lock_irqsave(&priv->sta_lock, flags);
1056 key_flags = le16_to_cpu(priv->stations[sta_id].sta.key.key_flags); 645 for (i = 0; i < priv->hw_params.max_stations; i++) {
1057 keyidx = (key_flags >> STA_KEY_FLG_KEYID_POS) & 0x3; 646 if (!(priv->stations[i].used & IWL_STA_BCAST))
1058 647 continue;
1059 IWL_DEBUG_WEP(priv, "Remove dynamic key: idx=%d sta=%d\n",
1060 keyconf->keyidx, sta_id);
1061
1062 if (keyconf->keyidx != keyidx) {
1063 /* We need to remove a key with index different that the one
1064 * in the uCode. This means that the key we need to remove has
1065 * been replaced by another one with different index.
1066 * Don't do anything and return ok
1067 */
1068 spin_unlock_irqrestore(&priv->sta_lock, flags);
1069 return 0;
1070 }
1071
1072 if (priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET) {
1073 IWL_WARN(priv, "Removing wrong key %d 0x%x\n",
1074 keyconf->keyidx, key_flags);
1075 spin_unlock_irqrestore(&priv->sta_lock, flags);
1076 return 0;
1077 }
1078 648
1079 if (!test_and_clear_bit(priv->stations[sta_id].sta.key.key_offset, 649 priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE;
1080 &priv->ucode_key_table)) 650 priv->num_stations--;
1081 IWL_ERR(priv, "index %d not used in uCode key table.\n", 651 BUG_ON(priv->num_stations < 0);
1082 priv->stations[sta_id].sta.key.key_offset); 652 kfree(priv->stations[i].lq);
1083 memset(&priv->stations[sta_id].keyinfo, 0, 653 priv->stations[i].lq = NULL;
1084 sizeof(struct iwl_hw_key));
1085 memset(&priv->stations[sta_id].sta.key, 0,
1086 sizeof(struct iwl4965_keyinfo));
1087 priv->stations[sta_id].sta.key.key_flags =
1088 STA_KEY_FLG_NO_ENC | STA_KEY_FLG_INVALID;
1089 priv->stations[sta_id].sta.key.key_offset = WEP_INVALID_OFFSET;
1090 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
1091 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
1092
1093 if (iwl_is_rfkill(priv)) {
1094 IWL_DEBUG_WEP(priv, "Not sending REPLY_ADD_STA command because RFKILL enabled.\n");
1095 spin_unlock_irqrestore(&priv->sta_lock, flags);
1096 return 0;
1097 } 654 }
1098 memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
1099 spin_unlock_irqrestore(&priv->sta_lock, flags); 655 spin_unlock_irqrestore(&priv->sta_lock, flags);
1100
1101 return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
1102}
1103EXPORT_SYMBOL(iwl_remove_dynamic_key);
1104
1105int iwl_set_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
1106 struct ieee80211_key_conf *keyconf, u8 sta_id)
1107{
1108 int ret;
1109
1110 lockdep_assert_held(&priv->mutex);
1111
1112 ctx->key_mapping_keys++;
1113 keyconf->hw_key_idx = HW_KEY_DYNAMIC;
1114
1115 switch (keyconf->cipher) {
1116 case WLAN_CIPHER_SUITE_CCMP:
1117 ret = iwl_set_ccmp_dynamic_key_info(priv, ctx, keyconf, sta_id);
1118 break;
1119 case WLAN_CIPHER_SUITE_TKIP:
1120 ret = iwl_set_tkip_dynamic_key_info(priv, ctx, keyconf, sta_id);
1121 break;
1122 case WLAN_CIPHER_SUITE_WEP40:
1123 case WLAN_CIPHER_SUITE_WEP104:
1124 ret = iwl_set_wep_dynamic_key_info(priv, ctx, keyconf, sta_id);
1125 break;
1126 default:
1127 IWL_ERR(priv,
1128 "Unknown alg: %s cipher = %x\n", __func__,
1129 keyconf->cipher);
1130 ret = -EINVAL;
1131 }
1132
1133 IWL_DEBUG_WEP(priv, "Set dynamic key: cipher=%x len=%d idx=%d sta=%d ret=%d\n",
1134 keyconf->cipher, keyconf->keylen, keyconf->keyidx,
1135 sta_id, ret);
1136
1137 return ret;
1138} 656}
1139EXPORT_SYMBOL(iwl_set_dynamic_key); 657EXPORT_SYMBOL_GPL(iwl_dealloc_bcast_stations);
1140 658
1141#ifdef CONFIG_IWLWIFI_DEBUG 659#ifdef CONFIG_IWLWIFI_DEBUG
1142static void iwl_dump_lq_cmd(struct iwl_priv *priv, 660static void iwl_dump_lq_cmd(struct iwl_priv *priv,
@@ -1240,223 +758,6 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
1240} 758}
1241EXPORT_SYMBOL(iwl_send_lq_cmd); 759EXPORT_SYMBOL(iwl_send_lq_cmd);
1242 760
1243/**
1244 * iwl_alloc_bcast_station - add broadcast station into driver's station table.
1245 *
1246 * This adds the broadcast station into the driver's station table
1247 * and marks it driver active, so that it will be restored to the
1248 * device at the next best time.
1249 */
1250int iwl_alloc_bcast_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
1251 bool init_lq)
1252{
1253 struct iwl_link_quality_cmd *link_cmd;
1254 unsigned long flags;
1255 u8 sta_id;
1256
1257 spin_lock_irqsave(&priv->sta_lock, flags);
1258 sta_id = iwl_prep_station(priv, ctx, iwl_bcast_addr, false, NULL);
1259 if (sta_id == IWL_INVALID_STATION) {
1260 IWL_ERR(priv, "Unable to prepare broadcast station\n");
1261 spin_unlock_irqrestore(&priv->sta_lock, flags);
1262
1263 return -EINVAL;
1264 }
1265
1266 priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE;
1267 priv->stations[sta_id].used |= IWL_STA_BCAST;
1268 spin_unlock_irqrestore(&priv->sta_lock, flags);
1269
1270 if (init_lq) {
1271 link_cmd = iwl_sta_alloc_lq(priv, sta_id);
1272 if (!link_cmd) {
1273 IWL_ERR(priv,
1274 "Unable to initialize rate scaling for bcast station.\n");
1275 return -ENOMEM;
1276 }
1277
1278 spin_lock_irqsave(&priv->sta_lock, flags);
1279 priv->stations[sta_id].lq = link_cmd;
1280 spin_unlock_irqrestore(&priv->sta_lock, flags);
1281 }
1282
1283 return 0;
1284}
1285EXPORT_SYMBOL_GPL(iwl_alloc_bcast_station);
1286
1287/**
1288 * iwl_update_bcast_station - update broadcast station's LQ command
1289 *
1290 * Only used by iwlagn. Placed here to have all bcast station management
1291 * code together.
1292 */
1293static int iwl_update_bcast_station(struct iwl_priv *priv,
1294 struct iwl_rxon_context *ctx)
1295{
1296 unsigned long flags;
1297 struct iwl_link_quality_cmd *link_cmd;
1298 u8 sta_id = ctx->bcast_sta_id;
1299
1300 link_cmd = iwl_sta_alloc_lq(priv, sta_id);
1301 if (!link_cmd) {
1302 IWL_ERR(priv, "Unable to initialize rate scaling for bcast station.\n");
1303 return -ENOMEM;
1304 }
1305
1306 spin_lock_irqsave(&priv->sta_lock, flags);
1307 if (priv->stations[sta_id].lq)
1308 kfree(priv->stations[sta_id].lq);
1309 else
1310 IWL_DEBUG_INFO(priv, "Bcast station rate scaling has not been initialized yet.\n");
1311 priv->stations[sta_id].lq = link_cmd;
1312 spin_unlock_irqrestore(&priv->sta_lock, flags);
1313
1314 return 0;
1315}
1316
1317int iwl_update_bcast_stations(struct iwl_priv *priv)
1318{
1319 struct iwl_rxon_context *ctx;
1320 int ret = 0;
1321
1322 for_each_context(priv, ctx) {
1323 ret = iwl_update_bcast_station(priv, ctx);
1324 if (ret)
1325 break;
1326 }
1327
1328 return ret;
1329}
1330EXPORT_SYMBOL_GPL(iwl_update_bcast_stations);
1331
1332void iwl_dealloc_bcast_stations(struct iwl_priv *priv)
1333{
1334 unsigned long flags;
1335 int i;
1336
1337 spin_lock_irqsave(&priv->sta_lock, flags);
1338 for (i = 0; i < priv->hw_params.max_stations; i++) {
1339 if (!(priv->stations[i].used & IWL_STA_BCAST))
1340 continue;
1341
1342 priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE;
1343 priv->num_stations--;
1344 BUG_ON(priv->num_stations < 0);
1345 kfree(priv->stations[i].lq);
1346 priv->stations[i].lq = NULL;
1347 }
1348 spin_unlock_irqrestore(&priv->sta_lock, flags);
1349}
1350EXPORT_SYMBOL_GPL(iwl_dealloc_bcast_stations);
1351
1352/**
1353 * iwl_sta_tx_modify_enable_tid - Enable Tx for this TID in station table
1354 */
1355int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid)
1356{
1357 unsigned long flags;
1358 struct iwl_addsta_cmd sta_cmd;
1359
1360 lockdep_assert_held(&priv->mutex);
1361
1362 /* Remove "disable" flag, to enable Tx for this TID */
1363 spin_lock_irqsave(&priv->sta_lock, flags);
1364 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_TID_DISABLE_TX;
1365 priv->stations[sta_id].sta.tid_disable_tx &= cpu_to_le16(~(1 << tid));
1366 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
1367 memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
1368 spin_unlock_irqrestore(&priv->sta_lock, flags);
1369
1370 return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
1371}
1372EXPORT_SYMBOL(iwl_sta_tx_modify_enable_tid);
1373
1374int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta,
1375 int tid, u16 ssn)
1376{
1377 unsigned long flags;
1378 int sta_id;
1379 struct iwl_addsta_cmd sta_cmd;
1380
1381 lockdep_assert_held(&priv->mutex);
1382
1383 sta_id = iwl_sta_id(sta);
1384 if (sta_id == IWL_INVALID_STATION)
1385 return -ENXIO;
1386
1387 spin_lock_irqsave(&priv->sta_lock, flags);
1388 priv->stations[sta_id].sta.station_flags_msk = 0;
1389 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_ADDBA_TID_MSK;
1390 priv->stations[sta_id].sta.add_immediate_ba_tid = (u8)tid;
1391 priv->stations[sta_id].sta.add_immediate_ba_ssn = cpu_to_le16(ssn);
1392 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
1393 memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
1394 spin_unlock_irqrestore(&priv->sta_lock, flags);
1395
1396 return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
1397}
1398EXPORT_SYMBOL(iwl_sta_rx_agg_start);
1399
1400int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
1401 int tid)
1402{
1403 unsigned long flags;
1404 int sta_id;
1405 struct iwl_addsta_cmd sta_cmd;
1406
1407 lockdep_assert_held(&priv->mutex);
1408
1409 sta_id = iwl_sta_id(sta);
1410 if (sta_id == IWL_INVALID_STATION) {
1411 IWL_ERR(priv, "Invalid station for AGG tid %d\n", tid);
1412 return -ENXIO;
1413 }
1414
1415 spin_lock_irqsave(&priv->sta_lock, flags);
1416 priv->stations[sta_id].sta.station_flags_msk = 0;
1417 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_DELBA_TID_MSK;
1418 priv->stations[sta_id].sta.remove_immediate_ba_tid = (u8)tid;
1419 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
1420 memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
1421 spin_unlock_irqrestore(&priv->sta_lock, flags);
1422
1423 return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
1424}
1425EXPORT_SYMBOL(iwl_sta_rx_agg_stop);
1426
1427void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id)
1428{
1429 unsigned long flags;
1430
1431 spin_lock_irqsave(&priv->sta_lock, flags);
1432 priv->stations[sta_id].sta.station_flags &= ~STA_FLG_PWR_SAVE_MSK;
1433 priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK;
1434 priv->stations[sta_id].sta.sta.modify_mask = 0;
1435 priv->stations[sta_id].sta.sleep_tx_count = 0;
1436 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
1437 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
1438 spin_unlock_irqrestore(&priv->sta_lock, flags);
1439
1440}
1441EXPORT_SYMBOL(iwl_sta_modify_ps_wake);
1442
1443void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt)
1444{
1445 unsigned long flags;
1446
1447 spin_lock_irqsave(&priv->sta_lock, flags);
1448 priv->stations[sta_id].sta.station_flags |= STA_FLG_PWR_SAVE_MSK;
1449 priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK;
1450 priv->stations[sta_id].sta.sta.modify_mask =
1451 STA_MODIFY_SLEEP_TX_COUNT_MSK;
1452 priv->stations[sta_id].sta.sleep_tx_count = cpu_to_le16(cnt);
1453 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
1454 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
1455 spin_unlock_irqrestore(&priv->sta_lock, flags);
1456
1457}
1458EXPORT_SYMBOL(iwl_sta_modify_sleep_tx_count);
1459
1460int iwl_mac_sta_remove(struct ieee80211_hw *hw, 761int iwl_mac_sta_remove(struct ieee80211_hw *hw,
1461 struct ieee80211_vif *vif, 762 struct ieee80211_vif *vif,
1462 struct ieee80211_sta *sta) 763 struct ieee80211_sta *sta)
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index 56bad3f60d81..06475872eee4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -43,35 +43,13 @@
43#define IWL_STA_BCAST BIT(4) /* this station is the special bcast station */ 43#define IWL_STA_BCAST BIT(4) /* this station is the special bcast station */
44 44
45 45
46int iwl_remove_default_wep_key(struct iwl_priv *priv,
47 struct iwl_rxon_context *ctx,
48 struct ieee80211_key_conf *key);
49int iwl_set_default_wep_key(struct iwl_priv *priv,
50 struct iwl_rxon_context *ctx,
51 struct ieee80211_key_conf *key);
52int iwl_restore_default_wep_keys(struct iwl_priv *priv,
53 struct iwl_rxon_context *ctx);
54int iwl_set_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
55 struct ieee80211_key_conf *key, u8 sta_id);
56int iwl_remove_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
57 struct ieee80211_key_conf *key, u8 sta_id);
58void iwl_update_tkip_key(struct iwl_priv *priv,
59 struct iwl_rxon_context *ctx,
60 struct ieee80211_key_conf *keyconf,
61 struct ieee80211_sta *sta, u32 iv32, u16 *phase1key);
62
63void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx); 46void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
64void iwl_clear_ucode_stations(struct iwl_priv *priv, 47void iwl_clear_ucode_stations(struct iwl_priv *priv,
65 struct iwl_rxon_context *ctx); 48 struct iwl_rxon_context *ctx);
66int iwl_alloc_bcast_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
67 bool init_lq);
68void iwl_dealloc_bcast_stations(struct iwl_priv *priv); 49void iwl_dealloc_bcast_stations(struct iwl_priv *priv);
69int iwl_update_bcast_stations(struct iwl_priv *priv);
70int iwl_get_free_ucode_key_index(struct iwl_priv *priv); 50int iwl_get_free_ucode_key_index(struct iwl_priv *priv);
71int iwl_send_add_sta(struct iwl_priv *priv, 51int iwl_send_add_sta(struct iwl_priv *priv,
72 struct iwl_addsta_cmd *sta, u8 flags); 52 struct iwl_addsta_cmd *sta, u8 flags);
73int iwl_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
74 const u8 *addr, bool init_rs, u8 *sta_id_r);
75int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx, 53int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
76 const u8 *addr, bool is_ap, 54 const u8 *addr, bool is_ap,
77 struct ieee80211_sta *sta, u8 *sta_id_r); 55 struct ieee80211_sta *sta, u8 *sta_id_r);
@@ -79,13 +57,12 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
79 const u8 *addr); 57 const u8 *addr);
80int iwl_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 58int iwl_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
81 struct ieee80211_sta *sta); 59 struct ieee80211_sta *sta);
82int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid); 60
83int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta, 61u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
84 int tid, u16 ssn); 62 const u8 *addr, bool is_ap, struct ieee80211_sta *sta);
85int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, 63
86 int tid); 64int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
87void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id); 65 struct iwl_link_quality_cmd *lq, u8 flags, bool init);
88void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt);
89 66
90/** 67/**
91 * iwl_clear_driver_stations - clear knowledge of all stations from driver 68 * 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 3290b1552f5a..7261ee49f282 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -636,41 +636,3 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
636 meta->flags = 0; 636 meta->flags = 0;
637} 637}
638EXPORT_SYMBOL(iwl_tx_cmd_complete); 638EXPORT_SYMBOL(iwl_tx_cmd_complete);
639
640#ifdef CONFIG_IWLWIFI_DEBUG
641#define TX_STATUS_FAIL(x) case TX_STATUS_FAIL_ ## x: return #x
642#define TX_STATUS_POSTPONE(x) case TX_STATUS_POSTPONE_ ## x: return #x
643
644const char *iwl_get_tx_fail_reason(u32 status)
645{
646 switch (status & TX_STATUS_MSK) {
647 case TX_STATUS_SUCCESS:
648 return "SUCCESS";
649 TX_STATUS_POSTPONE(DELAY);
650 TX_STATUS_POSTPONE(FEW_BYTES);
651 TX_STATUS_POSTPONE(BT_PRIO);
652 TX_STATUS_POSTPONE(QUIET_PERIOD);
653 TX_STATUS_POSTPONE(CALC_TTAK);
654 TX_STATUS_FAIL(INTERNAL_CROSSED_RETRY);
655 TX_STATUS_FAIL(SHORT_LIMIT);
656 TX_STATUS_FAIL(LONG_LIMIT);
657 TX_STATUS_FAIL(FIFO_UNDERRUN);
658 TX_STATUS_FAIL(DRAIN_FLOW);
659 TX_STATUS_FAIL(RFKILL_FLUSH);
660 TX_STATUS_FAIL(LIFE_EXPIRE);
661 TX_STATUS_FAIL(DEST_PS);
662 TX_STATUS_FAIL(HOST_ABORTED);
663 TX_STATUS_FAIL(BT_RETRY);
664 TX_STATUS_FAIL(STA_INVALID);
665 TX_STATUS_FAIL(FRAG_DROPPED);
666 TX_STATUS_FAIL(TID_DISABLE);
667 TX_STATUS_FAIL(FIFO_FLUSHED);
668 TX_STATUS_FAIL(INSUFFICIENT_CF_POLL);
669 TX_STATUS_FAIL(PASSIVE_NO_RX);
670 TX_STATUS_FAIL(NO_BEACON_ON_RADAR);
671 }
672
673 return "UNKNOWN";
674}
675EXPORT_SYMBOL(iwl_get_tx_fail_reason);
676#endif /* CONFIG_IWLWIFI_DEBUG */
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 43db5f38e3e6..8f8c4b73f8b9 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -317,15 +317,15 @@ unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv,
317 int left) 317 int left)
318{ 318{
319 319
320 if (!iwl_is_associated(priv, IWL_RXON_CTX_BSS) || !priv->ibss_beacon) 320 if (!iwl_is_associated(priv, IWL_RXON_CTX_BSS) || !priv->beacon_skb)
321 return 0; 321 return 0;
322 322
323 if (priv->ibss_beacon->len > left) 323 if (priv->beacon_skb->len > left)
324 return 0; 324 return 0;
325 325
326 memcpy(hdr, priv->ibss_beacon->data, priv->ibss_beacon->len); 326 memcpy(hdr, priv->beacon_skb->data, priv->beacon_skb->len);
327 327
328 return priv->ibss_beacon->len; 328 return priv->beacon_skb->len;
329} 329}
330 330
331static int iwl3945_send_beacon_cmd(struct iwl_priv *priv) 331static int iwl3945_send_beacon_cmd(struct iwl_priv *priv)
@@ -813,10 +813,10 @@ static void iwl3945_bg_beacon_update(struct work_struct *work)
813 813
814 mutex_lock(&priv->mutex); 814 mutex_lock(&priv->mutex);
815 /* new beacon skb is allocated every time; dispose previous.*/ 815 /* new beacon skb is allocated every time; dispose previous.*/
816 if (priv->ibss_beacon) 816 if (priv->beacon_skb)
817 dev_kfree_skb(priv->ibss_beacon); 817 dev_kfree_skb(priv->beacon_skb);
818 818
819 priv->ibss_beacon = beacon; 819 priv->beacon_skb = beacon;
820 mutex_unlock(&priv->mutex); 820 mutex_unlock(&priv->mutex);
821 821
822 iwl3945_send_beacon_cmd(priv); 822 iwl3945_send_beacon_cmd(priv);
@@ -2547,7 +2547,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
2547 priv->cfg->ops->hcmd->send_bt_config(priv); 2547 priv->cfg->ops->hcmd->send_bt_config(priv);
2548 2548
2549 /* Configure the adapter for unassociated operation */ 2549 /* Configure the adapter for unassociated operation */
2550 iwlcore_commit_rxon(priv, ctx); 2550 iwl3945_commit_rxon(priv, ctx);
2551 2551
2552 iwl3945_reg_txpower_periodic(priv); 2552 iwl3945_reg_txpower_periodic(priv);
2553 2553
@@ -2637,14 +2637,14 @@ static void __iwl3945_down(struct iwl_priv *priv)
2637 udelay(5); 2637 udelay(5);
2638 2638
2639 /* Stop the device, and put it in low power state */ 2639 /* Stop the device, and put it in low power state */
2640 priv->cfg->ops->lib->apm_ops.stop(priv); 2640 iwl_apm_stop(priv);
2641 2641
2642 exit: 2642 exit:
2643 memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp)); 2643 memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp));
2644 2644
2645 if (priv->ibss_beacon) 2645 if (priv->beacon_skb)
2646 dev_kfree_skb(priv->ibss_beacon); 2646 dev_kfree_skb(priv->beacon_skb);
2647 priv->ibss_beacon = NULL; 2647 priv->beacon_skb = NULL;
2648 2648
2649 /* clear out any free frames */ 2649 /* clear out any free frames */
2650 iwl3945_clear_free_frames(priv); 2650 iwl3945_clear_free_frames(priv);
@@ -2661,12 +2661,33 @@ static void iwl3945_down(struct iwl_priv *priv)
2661 2661
2662#define MAX_HW_RESTARTS 5 2662#define MAX_HW_RESTARTS 5
2663 2663
2664static int iwl3945_alloc_bcast_station(struct iwl_priv *priv)
2665{
2666 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
2667 unsigned long flags;
2668 u8 sta_id;
2669
2670 spin_lock_irqsave(&priv->sta_lock, flags);
2671 sta_id = iwl_prep_station(priv, ctx, iwl_bcast_addr, false, NULL);
2672 if (sta_id == IWL_INVALID_STATION) {
2673 IWL_ERR(priv, "Unable to prepare broadcast station\n");
2674 spin_unlock_irqrestore(&priv->sta_lock, flags);
2675
2676 return -EINVAL;
2677 }
2678
2679 priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE;
2680 priv->stations[sta_id].used |= IWL_STA_BCAST;
2681 spin_unlock_irqrestore(&priv->sta_lock, flags);
2682
2683 return 0;
2684}
2685
2664static int __iwl3945_up(struct iwl_priv *priv) 2686static int __iwl3945_up(struct iwl_priv *priv)
2665{ 2687{
2666 int rc, i; 2688 int rc, i;
2667 2689
2668 rc = iwl_alloc_bcast_station(priv, &priv->contexts[IWL_RXON_CTX_BSS], 2690 rc = iwl3945_alloc_bcast_station(priv);
2669 false);
2670 if (rc) 2691 if (rc)
2671 return rc; 2692 return rc;
2672 2693
@@ -2917,18 +2938,10 @@ int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
2917 case IEEE80211_BAND_2GHZ: 2938 case IEEE80211_BAND_2GHZ:
2918 scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; 2939 scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;
2919 scan->tx_cmd.rate = IWL_RATE_1M_PLCP; 2940 scan->tx_cmd.rate = IWL_RATE_1M_PLCP;
2920 scan->good_CRC_th = 0;
2921 band = IEEE80211_BAND_2GHZ; 2941 band = IEEE80211_BAND_2GHZ;
2922 break; 2942 break;
2923 case IEEE80211_BAND_5GHZ: 2943 case IEEE80211_BAND_5GHZ:
2924 scan->tx_cmd.rate = IWL_RATE_6M_PLCP; 2944 scan->tx_cmd.rate = IWL_RATE_6M_PLCP;
2925 /*
2926 * If active scaning is requested but a certain channel
2927 * is marked passive, we can do active scanning if we
2928 * detect transmissions.
2929 */
2930 scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
2931 IWL_GOOD_CRC_TH_DISABLED;
2932 band = IEEE80211_BAND_5GHZ; 2945 band = IEEE80211_BAND_5GHZ;
2933 break; 2946 break;
2934 default: 2947 default:
@@ -2936,6 +2949,14 @@ int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
2936 return -EIO; 2949 return -EIO;
2937 } 2950 }
2938 2951
2952 /*
2953 * If active scaning is requested but a certain channel
2954 * is marked passive, we can do active scanning if we
2955 * detect transmissions.
2956 */
2957 scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
2958 IWL_GOOD_CRC_TH_DISABLED;
2959
2939 if (!priv->is_internal_short_scan) { 2960 if (!priv->is_internal_short_scan) {
2940 scan->tx_cmd.len = cpu_to_le16( 2961 scan->tx_cmd.len = cpu_to_le16(
2941 iwl_fill_probe_req(priv, 2962 iwl_fill_probe_req(priv,
@@ -2983,6 +3004,18 @@ int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
2983 return ret; 3004 return ret;
2984} 3005}
2985 3006
3007void iwl3945_post_scan(struct iwl_priv *priv)
3008{
3009 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
3010
3011 /*
3012 * Since setting the RXON may have been deferred while
3013 * performing the scan, fire one off if needed
3014 */
3015 if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))
3016 iwl3945_commit_rxon(priv, ctx);
3017}
3018
2986static void iwl3945_bg_restart(struct work_struct *data) 3019static void iwl3945_bg_restart(struct work_struct *data)
2987{ 3020{
2988 struct iwl_priv *priv = container_of(data, struct iwl_priv, restart); 3021 struct iwl_priv *priv = container_of(data, struct iwl_priv, restart);
@@ -3049,7 +3082,7 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
3049 conf = ieee80211_get_hw_conf(priv->hw); 3082 conf = ieee80211_get_hw_conf(priv->hw);
3050 3083
3051 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 3084 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
3052 iwlcore_commit_rxon(priv, ctx); 3085 iwl3945_commit_rxon(priv, ctx);
3053 3086
3054 rc = iwl_send_rxon_timing(priv, ctx); 3087 rc = iwl_send_rxon_timing(priv, ctx);
3055 if (rc) 3088 if (rc)
@@ -3075,7 +3108,7 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
3075 ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; 3108 ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
3076 } 3109 }
3077 3110
3078 iwlcore_commit_rxon(priv, ctx); 3111 iwl3945_commit_rxon(priv, ctx);
3079 3112
3080 switch (vif->type) { 3113 switch (vif->type) {
3081 case NL80211_IFTYPE_STATION: 3114 case NL80211_IFTYPE_STATION:
@@ -3214,7 +3247,7 @@ void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
3214 3247
3215 /* RXON - unassoc (to set timing command) */ 3248 /* RXON - unassoc (to set timing command) */
3216 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 3249 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
3217 iwlcore_commit_rxon(priv, ctx); 3250 iwl3945_commit_rxon(priv, ctx);
3218 3251
3219 /* RXON Timing */ 3252 /* RXON Timing */
3220 rc = iwl_send_rxon_timing(priv, ctx); 3253 rc = iwl_send_rxon_timing(priv, ctx);
@@ -3241,7 +3274,7 @@ void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
3241 } 3274 }
3242 /* restore RXON assoc */ 3275 /* restore RXON assoc */
3243 ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; 3276 ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
3244 iwlcore_commit_rxon(priv, ctx); 3277 iwl3945_commit_rxon(priv, ctx);
3245 } 3278 }
3246 iwl3945_send_beacon_cmd(priv); 3279 iwl3945_send_beacon_cmd(priv);
3247 3280
@@ -3507,7 +3540,7 @@ static ssize_t store_flags(struct device *d,
3507 IWL_DEBUG_INFO(priv, "Committing rxon.flags = 0x%04X\n", 3540 IWL_DEBUG_INFO(priv, "Committing rxon.flags = 0x%04X\n",
3508 flags); 3541 flags);
3509 ctx->staging.flags = cpu_to_le32(flags); 3542 ctx->staging.flags = cpu_to_le32(flags);
3510 iwlcore_commit_rxon(priv, ctx); 3543 iwl3945_commit_rxon(priv, ctx);
3511 } 3544 }
3512 } 3545 }
3513 mutex_unlock(&priv->mutex); 3546 mutex_unlock(&priv->mutex);
@@ -3545,7 +3578,7 @@ static ssize_t store_filter_flags(struct device *d,
3545 "0x%04X\n", filter_flags); 3578 "0x%04X\n", filter_flags);
3546 ctx->staging.filter_flags = 3579 ctx->staging.filter_flags =
3547 cpu_to_le32(filter_flags); 3580 cpu_to_le32(filter_flags);
3548 iwlcore_commit_rxon(priv, ctx); 3581 iwl3945_commit_rxon(priv, ctx);
3549 } 3582 }
3550 } 3583 }
3551 mutex_unlock(&priv->mutex); 3584 mutex_unlock(&priv->mutex);
@@ -3815,7 +3848,7 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
3815 struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; 3848 struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
3816 3849
3817 priv->retry_rate = 1; 3850 priv->retry_rate = 1;
3818 priv->ibss_beacon = NULL; 3851 priv->beacon_skb = NULL;
3819 3852
3820 spin_lock_init(&priv->sta_lock); 3853 spin_lock_init(&priv->sta_lock);
3821 spin_lock_init(&priv->hcmd_lock); 3854 spin_lock_init(&priv->hcmd_lock);
@@ -4179,7 +4212,7 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
4179 * paths to avoid running iwl_down() at all before leaving driver. 4212 * paths to avoid running iwl_down() at all before leaving driver.
4180 * This (inexpensive) call *makes sure* device is reset. 4213 * This (inexpensive) call *makes sure* device is reset.
4181 */ 4214 */
4182 priv->cfg->ops->lib->apm_ops.stop(priv); 4215 iwl_apm_stop(priv);
4183 4216
4184 /* make sure we flush any pending irq or 4217 /* make sure we flush any pending irq or
4185 * tasklet for the driver 4218 * tasklet for the driver
@@ -4223,8 +4256,8 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
4223 iwl_free_channel_map(priv); 4256 iwl_free_channel_map(priv);
4224 iwlcore_free_geos(priv); 4257 iwlcore_free_geos(priv);
4225 kfree(priv->scan_cmd); 4258 kfree(priv->scan_cmd);
4226 if (priv->ibss_beacon) 4259 if (priv->beacon_skb)
4227 dev_kfree_skb(priv->ibss_beacon); 4260 dev_kfree_skb(priv->beacon_skb);
4228 4261
4229 ieee80211_free_hw(priv->hw); 4262 ieee80211_free_hw(priv->hw);
4230} 4263}
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
index e906616232a2..efaf85032208 100644
--- a/drivers/net/wireless/libertas/if_usb.c
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -487,11 +487,12 @@ static int if_usb_reset_device(struct if_usb_card *cardp)
487 */ 487 */
488static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload, uint16_t nb) 488static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload, uint16_t nb)
489{ 489{
490 int ret = -1; 490 int ret;
491 491
492 /* check if device is removed */ 492 /* check if device is removed */
493 if (cardp->surprise_removed) { 493 if (cardp->surprise_removed) {
494 lbs_deb_usbd(&cardp->udev->dev, "Device removed\n"); 494 lbs_deb_usbd(&cardp->udev->dev, "Device removed\n");
495 ret = -ENODEV;
495 goto tx_ret; 496 goto tx_ret;
496 } 497 }
497 498
@@ -504,7 +505,6 @@ static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload, uint16_t nb
504 505
505 if ((ret = usb_submit_urb(cardp->tx_urb, GFP_ATOMIC))) { 506 if ((ret = usb_submit_urb(cardp->tx_urb, GFP_ATOMIC))) {
506 lbs_deb_usbd(&cardp->udev->dev, "usb_submit_urb failed: %d\n", ret); 507 lbs_deb_usbd(&cardp->udev->dev, "usb_submit_urb failed: %d\n", ret);
507 ret = -1;
508 } else { 508 } else {
509 lbs_deb_usb2(&cardp->udev->dev, "usb_submit_urb success\n"); 509 lbs_deb_usb2(&cardp->udev->dev, "usb_submit_urb success\n");
510 ret = 0; 510 ret = 0;
diff --git a/drivers/net/wireless/p54/eeprom.c b/drivers/net/wireless/p54/eeprom.c
index 8c05266d37f4..35b09aa0529b 100644
--- a/drivers/net/wireless/p54/eeprom.c
+++ b/drivers/net/wireless/p54/eeprom.c
@@ -261,8 +261,10 @@ static int p54_generate_channel_lists(struct ieee80211_hw *dev)
261 list->max_entries = max_channel_num; 261 list->max_entries = max_channel_num;
262 list->channels = kzalloc(sizeof(struct p54_channel_entry) * 262 list->channels = kzalloc(sizeof(struct p54_channel_entry) *
263 max_channel_num, GFP_KERNEL); 263 max_channel_num, GFP_KERNEL);
264 if (!list->channels) 264 if (!list->channels) {
265 ret = -ENOMEM;
265 goto free; 266 goto free;
267 }
266 268
267 for (i = 0; i < max_channel_num; i++) { 269 for (i = 0; i < max_channel_num; i++) {
268 if (i < priv->iq_autocal_len) { 270 if (i < priv->iq_autocal_len) {
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index d49e830fa1da..4f420a9ec5dc 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -1104,7 +1104,7 @@ static void rt2400pci_write_beacon(struct queue_entry *entry,
1104 rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0); 1104 rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
1105 rt2x00pci_register_write(rt2x00dev, CSR14, reg); 1105 rt2x00pci_register_write(rt2x00dev, CSR14, reg);
1106 1106
1107 rt2x00queue_map_txskb(rt2x00dev, entry->skb); 1107 rt2x00queue_map_txskb(entry);
1108 1108
1109 /* 1109 /*
1110 * Write the TX descriptor for the beacon. 1110 * Write the TX descriptor for the beacon.
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 2214c3231727..97feb7aef809 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -1258,7 +1258,7 @@ static void rt2500pci_write_beacon(struct queue_entry *entry,
1258 rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0); 1258 rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
1259 rt2x00pci_register_write(rt2x00dev, CSR14, reg); 1259 rt2x00pci_register_write(rt2x00dev, CSR14, reg);
1260 1260
1261 rt2x00queue_map_txskb(rt2x00dev, entry->skb); 1261 rt2x00queue_map_txskb(entry);
1262 1262
1263 /* 1263 /*
1264 * Write the TX descriptor for the beacon. 1264 * Write the TX descriptor for the beacon.
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 10aefc4fb0cc..5f00e00789d8 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -499,7 +499,7 @@ void rt2800_write_tx_data(struct queue_entry *entry,
499} 499}
500EXPORT_SYMBOL_GPL(rt2800_write_tx_data); 500EXPORT_SYMBOL_GPL(rt2800_write_tx_data);
501 501
502static int rt2800_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxwi_w2) 502static int rt2800_agc_to_rssi(struct rt2x00_dev *rt2x00dev, u32 rxwi_w2)
503{ 503{
504 int rssi0 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI0); 504 int rssi0 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI0);
505 int rssi1 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI1); 505 int rssi1 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI1);
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index 85a134cd62bf..b26739535986 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -573,7 +573,7 @@ static void rt2800pci_kick_tx_queue(struct data_queue *queue)
573{ 573{
574 struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; 574 struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
575 struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); 575 struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX);
576 unsigned int qidx = 0; 576 unsigned int qidx;
577 577
578 if (queue->qid == QID_MGMT) 578 if (queue->qid == QID_MGMT)
579 qidx = 5; 579 qidx = 5;
@@ -676,7 +676,7 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
676 break; 676 break;
677 } 677 }
678 678
679 qid = rt2x00_get_field32(status, TX_STA_FIFO_PID_TYPE) - 1; 679 qid = rt2x00_get_field32(status, TX_STA_FIFO_PID_QUEUE);
680 if (qid >= QID_RX) { 680 if (qid >= QID_RX) {
681 /* 681 /*
682 * Unknown queue, this shouldn't happen. Just drop 682 * Unknown queue, this shouldn't happen. Just drop
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 75ac6624bf9e..94fe589acfaa 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -338,6 +338,11 @@ struct link {
338 338
339 /* 339 /*
340 * Work structure for scheduling periodic watchdog monitoring. 340 * Work structure for scheduling periodic watchdog monitoring.
341 * This work must be scheduled on the kernel workqueue, while
342 * all other work structures must be queued on the mac80211
343 * workqueue. This guarantees that the watchdog can schedule
344 * other work structures and wait for their completion in order
345 * to bring the device/driver back into the desired state.
341 */ 346 */
342 struct delayed_work watchdog_work; 347 struct delayed_work watchdog_work;
343}; 348};
@@ -1036,17 +1041,15 @@ static inline bool rt2x00_is_soc(struct rt2x00_dev *rt2x00dev)
1036 1041
1037/** 1042/**
1038 * rt2x00queue_map_txskb - Map a skb into DMA for TX purposes. 1043 * rt2x00queue_map_txskb - Map a skb into DMA for TX purposes.
1039 * @rt2x00dev: Pointer to &struct rt2x00_dev. 1044 * @entry: Pointer to &struct queue_entry
1040 * @skb: The skb to map.
1041 */ 1045 */
1042void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); 1046void rt2x00queue_map_txskb(struct queue_entry *entry);
1043 1047
1044/** 1048/**
1045 * rt2x00queue_unmap_skb - Unmap a skb from DMA. 1049 * rt2x00queue_unmap_skb - Unmap a skb from DMA.
1046 * @rt2x00dev: Pointer to &struct rt2x00_dev. 1050 * @entry: Pointer to &struct queue_entry
1047 * @skb: The skb to unmap.
1048 */ 1051 */
1049void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); 1052void rt2x00queue_unmap_skb(struct queue_entry *entry);
1050 1053
1051/** 1054/**
1052 * rt2x00queue_get_queue - Convert queue index to queue pointer 1055 * rt2x00queue_get_queue - Convert queue index to queue pointer
@@ -1093,8 +1096,7 @@ void rt2x00lib_dmadone(struct queue_entry *entry);
1093void rt2x00lib_txdone(struct queue_entry *entry, 1096void rt2x00lib_txdone(struct queue_entry *entry,
1094 struct txdone_entry_desc *txdesc); 1097 struct txdone_entry_desc *txdesc);
1095void rt2x00lib_txdone_noinfo(struct queue_entry *entry, u32 status); 1098void rt2x00lib_txdone_noinfo(struct queue_entry *entry, u32 status);
1096void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev, 1099void rt2x00lib_rxdone(struct queue_entry *entry);
1097 struct queue_entry *entry);
1098 1100
1099/* 1101/*
1100 * mac80211 handlers. 1102 * mac80211 handlers.
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 6f442b02b83e..5ba79b935f09 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -253,6 +253,7 @@ EXPORT_SYMBOL_GPL(rt2x00lib_pretbtt);
253 253
254void rt2x00lib_dmadone(struct queue_entry *entry) 254void rt2x00lib_dmadone(struct queue_entry *entry)
255{ 255{
256 clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
256 rt2x00queue_index_inc(entry->queue, Q_INDEX_DMA_DONE); 257 rt2x00queue_index_inc(entry->queue, Q_INDEX_DMA_DONE);
257} 258}
258EXPORT_SYMBOL_GPL(rt2x00lib_dmadone); 259EXPORT_SYMBOL_GPL(rt2x00lib_dmadone);
@@ -273,7 +274,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
273 /* 274 /*
274 * Unmap the skb. 275 * Unmap the skb.
275 */ 276 */
276 rt2x00queue_unmap_skb(rt2x00dev, entry->skb); 277 rt2x00queue_unmap_skb(entry);
277 278
278 /* 279 /*
279 * Remove the extra tx headroom from the skb. 280 * Remove the extra tx headroom from the skb.
@@ -432,42 +433,50 @@ static int rt2x00lib_rxdone_read_signal(struct rt2x00_dev *rt2x00dev,
432 struct ieee80211_supported_band *sband; 433 struct ieee80211_supported_band *sband;
433 const struct rt2x00_rate *rate; 434 const struct rt2x00_rate *rate;
434 unsigned int i; 435 unsigned int i;
435 int signal; 436 int signal = rxdesc->signal;
436 int type; 437 int type = (rxdesc->dev_flags & RXDONE_SIGNAL_MASK);
437 438
438 /* 439 switch (rxdesc->rate_mode) {
439 * For non-HT rates the MCS value needs to contain the 440 case RATE_MODE_CCK:
440 * actually used rate modulation (CCK or OFDM). 441 case RATE_MODE_OFDM:
441 */ 442 /*
442 if (rxdesc->dev_flags & RXDONE_SIGNAL_MCS) 443 * For non-HT rates the MCS value needs to contain the
443 signal = RATE_MCS(rxdesc->rate_mode, rxdesc->signal); 444 * actually used rate modulation (CCK or OFDM).
444 else 445 */
445 signal = rxdesc->signal; 446 if (rxdesc->dev_flags & RXDONE_SIGNAL_MCS)
446 447 signal = RATE_MCS(rxdesc->rate_mode, signal);
447 type = (rxdesc->dev_flags & RXDONE_SIGNAL_MASK); 448
448 449 sband = &rt2x00dev->bands[rt2x00dev->curr_band];
449 sband = &rt2x00dev->bands[rt2x00dev->curr_band]; 450 for (i = 0; i < sband->n_bitrates; i++) {
450 for (i = 0; i < sband->n_bitrates; i++) { 451 rate = rt2x00_get_rate(sband->bitrates[i].hw_value);
451 rate = rt2x00_get_rate(sband->bitrates[i].hw_value); 452 if (((type == RXDONE_SIGNAL_PLCP) &&
452 453 (rate->plcp == signal)) ||
453 if (((type == RXDONE_SIGNAL_PLCP) && 454 ((type == RXDONE_SIGNAL_BITRATE) &&
454 (rate->plcp == signal)) || 455 (rate->bitrate == signal)) ||
455 ((type == RXDONE_SIGNAL_BITRATE) && 456 ((type == RXDONE_SIGNAL_MCS) &&
456 (rate->bitrate == signal)) || 457 (rate->mcs == signal))) {
457 ((type == RXDONE_SIGNAL_MCS) && 458 return i;
458 (rate->mcs == signal))) { 459 }
459 return i;
460 } 460 }
461 break;
462 case RATE_MODE_HT_MIX:
463 case RATE_MODE_HT_GREENFIELD:
464 if (signal >= 0 && signal <= 76)
465 return signal;
466 break;
467 default:
468 break;
461 } 469 }
462 470
463 WARNING(rt2x00dev, "Frame received with unrecognized signal, " 471 WARNING(rt2x00dev, "Frame received with unrecognized signal, "
464 "signal=0x%.4x, type=%d.\n", signal, type); 472 "mode=0x%.4x, signal=0x%.4x, type=%d.\n",
473 rxdesc->rate_mode, signal, type);
465 return 0; 474 return 0;
466} 475}
467 476
468void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev, 477void rt2x00lib_rxdone(struct queue_entry *entry)
469 struct queue_entry *entry)
470{ 478{
479 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
471 struct rxdone_entry_desc rxdesc; 480 struct rxdone_entry_desc rxdesc;
472 struct sk_buff *skb; 481 struct sk_buff *skb;
473 struct ieee80211_rx_status *rx_status; 482 struct ieee80211_rx_status *rx_status;
@@ -481,14 +490,14 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
481 * Allocate a new sk_buffer. If no new buffer available, drop the 490 * Allocate a new sk_buffer. If no new buffer available, drop the
482 * received frame and reuse the existing buffer. 491 * received frame and reuse the existing buffer.
483 */ 492 */
484 skb = rt2x00queue_alloc_rxskb(rt2x00dev, entry); 493 skb = rt2x00queue_alloc_rxskb(entry);
485 if (!skb) 494 if (!skb)
486 return; 495 goto submit_entry;
487 496
488 /* 497 /*
489 * Unmap the skb. 498 * Unmap the skb.
490 */ 499 */
491 rt2x00queue_unmap_skb(rt2x00dev, entry->skb); 500 rt2x00queue_unmap_skb(entry);
492 501
493 /* 502 /*
494 * Extract the RXD details. 503 * Extract the RXD details.
@@ -523,18 +532,12 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
523 skb_trim(entry->skb, rxdesc.size); 532 skb_trim(entry->skb, rxdesc.size);
524 533
525 /* 534 /*
526 * Check if the frame was received using HT. In that case, 535 * Translate the signal to the correct bitrate index.
527 * the rate is the MCS index and should be passed to mac80211
528 * directly. Otherwise we need to translate the signal to
529 * the correct bitrate index.
530 */ 536 */
531 if (rxdesc.rate_mode == RATE_MODE_CCK || 537 rate_idx = rt2x00lib_rxdone_read_signal(rt2x00dev, &rxdesc);
532 rxdesc.rate_mode == RATE_MODE_OFDM) { 538 if (rxdesc.rate_mode == RATE_MODE_HT_MIX ||
533 rate_idx = rt2x00lib_rxdone_read_signal(rt2x00dev, &rxdesc); 539 rxdesc.rate_mode == RATE_MODE_HT_GREENFIELD)
534 } else {
535 rxdesc.flags |= RX_FLAG_HT; 540 rxdesc.flags |= RX_FLAG_HT;
536 rate_idx = rxdesc.signal;
537 }
538 541
539 /* 542 /*
540 * Update extra components 543 * Update extra components
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
index 70c85ac2e53e..619da23b7b56 100644
--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
+++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
@@ -100,18 +100,15 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
100 100
101/** 101/**
102 * rt2x00queue_alloc_rxskb - allocate a skb for RX purposes. 102 * rt2x00queue_alloc_rxskb - allocate a skb for RX purposes.
103 * @rt2x00dev: Pointer to &struct rt2x00_dev. 103 * @entry: The entry for which the skb will be applicable.
104 * @queue: The queue for which the skb will be applicable.
105 */ 104 */
106struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev, 105struct sk_buff *rt2x00queue_alloc_rxskb(struct queue_entry *entry);
107 struct queue_entry *entry);
108 106
109/** 107/**
110 * rt2x00queue_free_skb - free a skb 108 * rt2x00queue_free_skb - free a skb
111 * @rt2x00dev: Pointer to &struct rt2x00_dev. 109 * @entry: The entry for which the skb will be applicable.
112 * @skb: The skb to free.
113 */ 110 */
114void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); 111void rt2x00queue_free_skb(struct queue_entry *entry);
115 112
116/** 113/**
117 * rt2x00queue_align_frame - Align 802.11 frame to 4-byte boundary 114 * rt2x00queue_align_frame - Align 802.11 frame to 4-byte boundary
diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c
index 4d534e9dc628..b971d8798ebf 100644
--- a/drivers/net/wireless/rt2x00/rt2x00link.c
+++ b/drivers/net/wireless/rt2x00/rt2x00link.c
@@ -236,6 +236,12 @@ void rt2x00link_update_stats(struct rt2x00_dev *rt2x00dev,
236 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 236 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
237 237
238 /* 238 /*
239 * No need to update the stats for !=STA interfaces
240 */
241 if (!rt2x00dev->intf_sta_count)
242 return;
243
244 /*
239 * Frame was received successfully since non-succesfull 245 * Frame was received successfully since non-succesfull
240 * frames would have been dropped by the hardware. 246 * frames would have been dropped by the hardware.
241 */ 247 */
@@ -411,8 +417,7 @@ void rt2x00link_start_watchdog(struct rt2x00_dev *rt2x00dev)
411 !test_bit(DRIVER_SUPPORT_WATCHDOG, &rt2x00dev->flags)) 417 !test_bit(DRIVER_SUPPORT_WATCHDOG, &rt2x00dev->flags))
412 return; 418 return;
413 419
414 ieee80211_queue_delayed_work(rt2x00dev->hw, 420 schedule_delayed_work(&link->watchdog_work, WATCHDOG_INTERVAL);
415 &link->watchdog_work, WATCHDOG_INTERVAL);
416} 421}
417 422
418void rt2x00link_stop_watchdog(struct rt2x00_dev *rt2x00dev) 423void rt2x00link_stop_watchdog(struct rt2x00_dev *rt2x00dev)
@@ -436,8 +441,7 @@ static void rt2x00link_watchdog(struct work_struct *work)
436 rt2x00dev->ops->lib->watchdog(rt2x00dev); 441 rt2x00dev->ops->lib->watchdog(rt2x00dev);
437 442
438 if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) 443 if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
439 ieee80211_queue_delayed_work(rt2x00dev->hw, 444 schedule_delayed_work(&link->watchdog_work, WATCHDOG_INTERVAL);
440 &link->watchdog_work, WATCHDOG_INTERVAL);
441} 445}
442 446
443void rt2x00link_register(struct rt2x00_dev *rt2x00dev) 447void rt2x00link_register(struct rt2x00_dev *rt2x00dev)
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index 63c2cc408e15..2449d785cf8d 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -84,7 +84,7 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
84 /* 84 /*
85 * Send the frame to rt2x00lib for further processing. 85 * Send the frame to rt2x00lib for further processing.
86 */ 86 */
87 rt2x00lib_rxdone(rt2x00dev, entry); 87 rt2x00lib_rxdone(entry);
88 } 88 }
89} 89}
90EXPORT_SYMBOL_GPL(rt2x00pci_rxdone); 90EXPORT_SYMBOL_GPL(rt2x00pci_rxdone);
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index eede99939db9..e360d287defb 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -33,9 +33,9 @@
33#include "rt2x00.h" 33#include "rt2x00.h"
34#include "rt2x00lib.h" 34#include "rt2x00lib.h"
35 35
36struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev, 36struct sk_buff *rt2x00queue_alloc_rxskb(struct queue_entry *entry)
37 struct queue_entry *entry)
38{ 37{
38 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
39 struct sk_buff *skb; 39 struct sk_buff *skb;
40 struct skb_frame_desc *skbdesc; 40 struct skb_frame_desc *skbdesc;
41 unsigned int frame_size; 41 unsigned int frame_size;
@@ -97,41 +97,42 @@ struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev,
97 return skb; 97 return skb;
98} 98}
99 99
100void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) 100void rt2x00queue_map_txskb(struct queue_entry *entry)
101{ 101{
102 struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); 102 struct device *dev = entry->queue->rt2x00dev->dev;
103 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
103 104
104 skbdesc->skb_dma = 105 skbdesc->skb_dma =
105 dma_map_single(rt2x00dev->dev, skb->data, skb->len, DMA_TO_DEVICE); 106 dma_map_single(dev, entry->skb->data, entry->skb->len, DMA_TO_DEVICE);
106 skbdesc->flags |= SKBDESC_DMA_MAPPED_TX; 107 skbdesc->flags |= SKBDESC_DMA_MAPPED_TX;
107} 108}
108EXPORT_SYMBOL_GPL(rt2x00queue_map_txskb); 109EXPORT_SYMBOL_GPL(rt2x00queue_map_txskb);
109 110
110void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) 111void rt2x00queue_unmap_skb(struct queue_entry *entry)
111{ 112{
112 struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); 113 struct device *dev = entry->queue->rt2x00dev->dev;
114 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
113 115
114 if (skbdesc->flags & SKBDESC_DMA_MAPPED_RX) { 116 if (skbdesc->flags & SKBDESC_DMA_MAPPED_RX) {
115 dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, skb->len, 117 dma_unmap_single(dev, skbdesc->skb_dma, entry->skb->len,
116 DMA_FROM_DEVICE); 118 DMA_FROM_DEVICE);
117 skbdesc->flags &= ~SKBDESC_DMA_MAPPED_RX; 119 skbdesc->flags &= ~SKBDESC_DMA_MAPPED_RX;
118 } 120 } else if (skbdesc->flags & SKBDESC_DMA_MAPPED_TX) {
119 121 dma_unmap_single(dev, skbdesc->skb_dma, entry->skb->len,
120 if (skbdesc->flags & SKBDESC_DMA_MAPPED_TX) {
121 dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, skb->len,
122 DMA_TO_DEVICE); 122 DMA_TO_DEVICE);
123 skbdesc->flags &= ~SKBDESC_DMA_MAPPED_TX; 123 skbdesc->flags &= ~SKBDESC_DMA_MAPPED_TX;
124 } 124 }
125} 125}
126EXPORT_SYMBOL_GPL(rt2x00queue_unmap_skb); 126EXPORT_SYMBOL_GPL(rt2x00queue_unmap_skb);
127 127
128void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) 128void rt2x00queue_free_skb(struct queue_entry *entry)
129{ 129{
130 if (!skb) 130 if (!entry->skb)
131 return; 131 return;
132 132
133 rt2x00queue_unmap_skb(rt2x00dev, skb); 133 rt2x00queue_unmap_skb(entry);
134 dev_kfree_skb_any(skb); 134 dev_kfree_skb_any(entry->skb);
135 entry->skb = NULL;
135} 136}
136 137
137void rt2x00queue_align_frame(struct sk_buff *skb) 138void rt2x00queue_align_frame(struct sk_buff *skb)
@@ -440,7 +441,7 @@ static int rt2x00queue_write_tx_data(struct queue_entry *entry,
440 * Map the skb to DMA. 441 * Map the skb to DMA.
441 */ 442 */
442 if (test_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags)) 443 if (test_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags))
443 rt2x00queue_map_txskb(rt2x00dev, entry->skb); 444 rt2x00queue_map_txskb(entry);
444 445
445 return 0; 446 return 0;
446} 447}
@@ -491,7 +492,8 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb,
491 if (unlikely(rt2x00queue_full(queue))) 492 if (unlikely(rt2x00queue_full(queue)))
492 return -ENOBUFS; 493 return -ENOBUFS;
493 494
494 if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) { 495 if (unlikely(test_and_set_bit(ENTRY_OWNER_DEVICE_DATA,
496 &entry->flags))) {
495 ERROR(queue->rt2x00dev, 497 ERROR(queue->rt2x00dev,
496 "Arrived at non-free entry in the non-full queue %d.\n" 498 "Arrived at non-free entry in the non-full queue %d.\n"
497 "Please file bug report to %s.\n", 499 "Please file bug report to %s.\n",
@@ -586,8 +588,7 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
586 /* 588 /*
587 * Clean up the beacon skb. 589 * Clean up the beacon skb.
588 */ 590 */
589 rt2x00queue_free_skb(rt2x00dev, intf->beacon->skb); 591 rt2x00queue_free_skb(intf->beacon);
590 intf->beacon->skb = NULL;
591 592
592 if (!enable_beacon) { 593 if (!enable_beacon) {
593 rt2x00dev->ops->lib->kill_tx_queue(intf->beacon->queue); 594 rt2x00dev->ops->lib->kill_tx_queue(intf->beacon->queue);
@@ -828,8 +829,7 @@ static int rt2x00queue_alloc_entries(struct data_queue *queue,
828 return 0; 829 return 0;
829} 830}
830 831
831static void rt2x00queue_free_skbs(struct rt2x00_dev *rt2x00dev, 832static void rt2x00queue_free_skbs(struct data_queue *queue)
832 struct data_queue *queue)
833{ 833{
834 unsigned int i; 834 unsigned int i;
835 835
@@ -837,19 +837,17 @@ static void rt2x00queue_free_skbs(struct rt2x00_dev *rt2x00dev,
837 return; 837 return;
838 838
839 for (i = 0; i < queue->limit; i++) { 839 for (i = 0; i < queue->limit; i++) {
840 if (queue->entries[i].skb) 840 rt2x00queue_free_skb(&queue->entries[i]);
841 rt2x00queue_free_skb(rt2x00dev, queue->entries[i].skb);
842 } 841 }
843} 842}
844 843
845static int rt2x00queue_alloc_rxskbs(struct rt2x00_dev *rt2x00dev, 844static int rt2x00queue_alloc_rxskbs(struct data_queue *queue)
846 struct data_queue *queue)
847{ 845{
848 unsigned int i; 846 unsigned int i;
849 struct sk_buff *skb; 847 struct sk_buff *skb;
850 848
851 for (i = 0; i < queue->limit; i++) { 849 for (i = 0; i < queue->limit; i++) {
852 skb = rt2x00queue_alloc_rxskb(rt2x00dev, &queue->entries[i]); 850 skb = rt2x00queue_alloc_rxskb(&queue->entries[i]);
853 if (!skb) 851 if (!skb)
854 return -ENOMEM; 852 return -ENOMEM;
855 queue->entries[i].skb = skb; 853 queue->entries[i].skb = skb;
@@ -884,7 +882,7 @@ int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev)
884 goto exit; 882 goto exit;
885 } 883 }
886 884
887 status = rt2x00queue_alloc_rxskbs(rt2x00dev, rt2x00dev->rx); 885 status = rt2x00queue_alloc_rxskbs(rt2x00dev->rx);
888 if (status) 886 if (status)
889 goto exit; 887 goto exit;
890 888
@@ -902,7 +900,7 @@ void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev)
902{ 900{
903 struct data_queue *queue; 901 struct data_queue *queue;
904 902
905 rt2x00queue_free_skbs(rt2x00dev, rt2x00dev->rx); 903 rt2x00queue_free_skbs(rt2x00dev->rx);
906 904
907 queue_for_each(rt2x00dev, queue) { 905 queue_for_each(rt2x00dev, queue) {
908 kfree(queue->entries); 906 kfree(queue->entries);
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 4c5ae3d45625..b3317df7a7d4 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -208,7 +208,7 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
208 struct queue_entry *entry = (struct queue_entry *)urb->context; 208 struct queue_entry *entry = (struct queue_entry *)urb->context;
209 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 209 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
210 210
211 if (!__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) 211 if (!test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
212 return; 212 return;
213 213
214 /* 214 /*
@@ -220,7 +220,7 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
220 * Check if the frame was correctly uploaded 220 * Check if the frame was correctly uploaded
221 */ 221 */
222 if (urb->status) 222 if (urb->status)
223 __set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); 223 set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
224 224
225 /* 225 /*
226 * Schedule the delayed work for reading the TX status 226 * Schedule the delayed work for reading the TX status
@@ -253,7 +253,10 @@ static void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
253 entry->skb->data, length, 253 entry->skb->data, length,
254 rt2x00usb_interrupt_txdone, entry); 254 rt2x00usb_interrupt_txdone, entry);
255 255
256 usb_submit_urb(entry_priv->urb, GFP_ATOMIC); 256 if (usb_submit_urb(entry_priv->urb, GFP_ATOMIC)) {
257 set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
258 rt2x00lib_dmadone(entry);
259 }
257} 260}
258 261
259void rt2x00usb_kick_tx_queue(struct data_queue *queue) 262void rt2x00usb_kick_tx_queue(struct data_queue *queue)
@@ -280,14 +283,6 @@ static void rt2x00usb_kill_tx_entry(struct queue_entry *entry)
280 if ((entry->queue->qid == QID_BEACON) && 283 if ((entry->queue->qid == QID_BEACON) &&
281 (test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags))) 284 (test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags)))
282 usb_kill_urb(bcn_priv->guardian_urb); 285 usb_kill_urb(bcn_priv->guardian_urb);
283
284 /*
285 * We need a short delay here to wait for
286 * the URB to be canceled
287 */
288 do {
289 udelay(100);
290 } while (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags));
291} 286}
292 287
293void rt2x00usb_kill_tx_queue(struct data_queue *queue) 288void rt2x00usb_kill_tx_queue(struct data_queue *queue)
@@ -363,10 +358,12 @@ void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev)
363 struct data_queue *queue; 358 struct data_queue *queue;
364 359
365 tx_queue_for_each(rt2x00dev, queue) { 360 tx_queue_for_each(rt2x00dev, queue) {
366 if (rt2x00queue_dma_timeout(queue)) 361 if (!rt2x00queue_empty(queue)) {
367 rt2x00usb_watchdog_tx_dma(queue); 362 if (rt2x00queue_dma_timeout(queue))
368 if (rt2x00queue_timeout(queue)) 363 rt2x00usb_watchdog_tx_dma(queue);
369 rt2x00usb_watchdog_tx_status(queue); 364 if (rt2x00queue_timeout(queue))
365 rt2x00usb_watchdog_tx_status(queue);
366 }
370 } 367 }
371} 368}
372EXPORT_SYMBOL_GPL(rt2x00usb_watchdog); 369EXPORT_SYMBOL_GPL(rt2x00usb_watchdog);
@@ -398,7 +395,7 @@ static void rt2x00usb_work_rxdone(struct work_struct *work)
398 /* 395 /*
399 * Send the frame to rt2x00lib for further processing. 396 * Send the frame to rt2x00lib for further processing.
400 */ 397 */
401 rt2x00lib_rxdone(rt2x00dev, entry); 398 rt2x00lib_rxdone(entry);
402 } 399 }
403} 400}
404 401
@@ -407,7 +404,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
407 struct queue_entry *entry = (struct queue_entry *)urb->context; 404 struct queue_entry *entry = (struct queue_entry *)urb->context;
408 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 405 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
409 406
410 if (!__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) 407 if (!test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
411 return; 408 return;
412 409
413 /* 410 /*
@@ -421,7 +418,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
421 * a problem. 418 * a problem.
422 */ 419 */
423 if (urb->actual_length < entry->queue->desc_size || urb->status) 420 if (urb->actual_length < entry->queue->desc_size || urb->status)
424 __set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); 421 set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
425 422
426 /* 423 /*
427 * Schedule the delayed work for reading the RX status 424 * Schedule the delayed work for reading the RX status
@@ -467,7 +464,10 @@ void rt2x00usb_clear_entry(struct queue_entry *entry)
467 rt2x00usb_interrupt_rxdone, entry); 464 rt2x00usb_interrupt_rxdone, entry);
468 465
469 set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); 466 set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
470 usb_submit_urb(entry_priv->urb, GFP_ATOMIC); 467 if (usb_submit_urb(entry_priv->urb, GFP_ATOMIC)) {
468 set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
469 rt2x00lib_dmadone(entry);
470 }
471 } 471 }
472} 472}
473EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry); 473EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry);
@@ -542,9 +542,9 @@ static int rt2x00usb_find_endpoints(struct rt2x00_dev *rt2x00dev)
542 return 0; 542 return 0;
543} 543}
544 544
545static int rt2x00usb_alloc_urb(struct rt2x00_dev *rt2x00dev, 545static int rt2x00usb_alloc_entries(struct data_queue *queue)
546 struct data_queue *queue)
547{ 546{
547 struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
548 struct queue_entry_priv_usb *entry_priv; 548 struct queue_entry_priv_usb *entry_priv;
549 struct queue_entry_priv_usb_bcn *bcn_priv; 549 struct queue_entry_priv_usb_bcn *bcn_priv;
550 unsigned int i; 550 unsigned int i;
@@ -561,7 +561,7 @@ static int rt2x00usb_alloc_urb(struct rt2x00_dev *rt2x00dev,
561 * no guardian byte was required for the beacon, 561 * no guardian byte was required for the beacon,
562 * then we are done. 562 * then we are done.
563 */ 563 */
564 if (rt2x00dev->bcn != queue || 564 if (queue->qid != QID_BEACON ||
565 !test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags)) 565 !test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags))
566 return 0; 566 return 0;
567 567
@@ -575,9 +575,9 @@ static int rt2x00usb_alloc_urb(struct rt2x00_dev *rt2x00dev,
575 return 0; 575 return 0;
576} 576}
577 577
578static void rt2x00usb_free_urb(struct rt2x00_dev *rt2x00dev, 578static void rt2x00usb_free_entries(struct data_queue *queue)
579 struct data_queue *queue)
580{ 579{
580 struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
581 struct queue_entry_priv_usb *entry_priv; 581 struct queue_entry_priv_usb *entry_priv;
582 struct queue_entry_priv_usb_bcn *bcn_priv; 582 struct queue_entry_priv_usb_bcn *bcn_priv;
583 unsigned int i; 583 unsigned int i;
@@ -596,7 +596,7 @@ static void rt2x00usb_free_urb(struct rt2x00_dev *rt2x00dev,
596 * no guardian byte was required for the beacon, 596 * no guardian byte was required for the beacon,
597 * then we are done. 597 * then we are done.
598 */ 598 */
599 if (rt2x00dev->bcn != queue || 599 if (queue->qid != QID_BEACON ||
600 !test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags)) 600 !test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags))
601 return; 601 return;
602 602
@@ -623,7 +623,7 @@ int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev)
623 * Allocate DMA 623 * Allocate DMA
624 */ 624 */
625 queue_for_each(rt2x00dev, queue) { 625 queue_for_each(rt2x00dev, queue) {
626 status = rt2x00usb_alloc_urb(rt2x00dev, queue); 626 status = rt2x00usb_alloc_entries(queue);
627 if (status) 627 if (status)
628 goto exit; 628 goto exit;
629 } 629 }
@@ -642,7 +642,7 @@ void rt2x00usb_uninitialize(struct rt2x00_dev *rt2x00dev)
642 struct data_queue *queue; 642 struct data_queue *queue;
643 643
644 queue_for_each(rt2x00dev, queue) 644 queue_for_each(rt2x00dev, queue)
645 rt2x00usb_free_urb(rt2x00dev, queue); 645 rt2x00usb_free_entries(queue);
646} 646}
647EXPORT_SYMBOL_GPL(rt2x00usb_uninitialize); 647EXPORT_SYMBOL_GPL(rt2x00usb_uninitialize);
648 648
diff --git a/drivers/net/wireless/wl1251/Kconfig b/drivers/net/wireless/wl1251/Kconfig
new file mode 100644
index 000000000000..1fb65849414f
--- /dev/null
+++ b/drivers/net/wireless/wl1251/Kconfig
@@ -0,0 +1,33 @@
1menuconfig WL1251
2 tristate "TI wl1251 driver support"
3 depends on MAC80211 && EXPERIMENTAL && GENERIC_HARDIRQS
4 select FW_LOADER
5 select CRC7
6 ---help---
7 This will enable TI wl1251 driver support. The drivers make
8 use of the mac80211 stack.
9
10 If you choose to build a module, it'll be called wl1251. Say
11 N if unsure.
12
13config WL1251_SPI
14 tristate "TI wl1251 SPI support"
15 depends on WL1251 && SPI_MASTER
16 ---help---
17 This module adds support for the SPI interface of adapters using
18 TI wl1251 chipset. Select this if your platform is using
19 the SPI bus.
20
21 If you choose to build a module, it'll be called wl1251_spi.
22 Say N if unsure.
23
24config WL1251_SDIO
25 tristate "TI wl1251 SDIO support"
26 depends on WL1251 && MMC
27 ---help---
28 This module adds support for the SDIO interface of adapters using
29 TI wl1251 chipset. Select this if your platform is using
30 the SDIO bus.
31
32 If you choose to build a module, it'll be called
33 wl1251_sdio. Say N if unsure.
diff --git a/drivers/net/wireless/wl1251/Makefile b/drivers/net/wireless/wl1251/Makefile
new file mode 100644
index 000000000000..4fe246824db3
--- /dev/null
+++ b/drivers/net/wireless/wl1251/Makefile
@@ -0,0 +1,6 @@
1wl1251-objs = main.o event.o tx.o rx.o ps.o cmd.o \
2 acx.o boot.o init.o debugfs.o io.o
3
4obj-$(CONFIG_WL1251) += wl1251.o
5obj-$(CONFIG_WL1251_SPI) += spi.o
6obj-$(CONFIG_WL1251_SDIO) += sdio.o
diff --git a/drivers/net/wireless/wl12xx/wl1251_acx.c b/drivers/net/wireless/wl1251/acx.c
index 2f8a2ba744dc..64a0214cfb29 100644
--- a/drivers/net/wireless/wl12xx/wl1251_acx.c
+++ b/drivers/net/wireless/wl1251/acx.c
@@ -1,13 +1,13 @@
1#include "wl1251_acx.h" 1#include "acx.h"
2 2
3#include <linux/module.h> 3#include <linux/module.h>
4#include <linux/slab.h> 4#include <linux/slab.h>
5#include <linux/crc7.h> 5#include <linux/crc7.h>
6 6
7#include "wl1251.h" 7#include "wl1251.h"
8#include "wl1251_reg.h" 8#include "reg.h"
9#include "wl1251_cmd.h" 9#include "cmd.h"
10#include "wl1251_ps.h" 10#include "ps.h"
11 11
12int wl1251_acx_frame_rates(struct wl1251 *wl, u8 ctrl_rate, u8 ctrl_mod, 12int wl1251_acx_frame_rates(struct wl1251 *wl, u8 ctrl_rate, u8 ctrl_mod,
13 u8 mgt_rate, u8 mgt_mod) 13 u8 mgt_rate, u8 mgt_mod)
diff --git a/drivers/net/wireless/wl12xx/wl1251_acx.h b/drivers/net/wireless/wl1251/acx.h
index c7cc5c1e8a75..e54b21a4f8b1 100644
--- a/drivers/net/wireless/wl12xx/wl1251_acx.h
+++ b/drivers/net/wireless/wl1251/acx.h
@@ -24,7 +24,7 @@
24#define __WL1251_ACX_H__ 24#define __WL1251_ACX_H__
25 25
26#include "wl1251.h" 26#include "wl1251.h"
27#include "wl1251_cmd.h" 27#include "cmd.h"
28 28
29/* Target's information element */ 29/* Target's information element */
30struct acx_header { 30struct acx_header {
diff --git a/drivers/net/wireless/wl12xx/wl1251_boot.c b/drivers/net/wireless/wl1251/boot.c
index 468b47b0328a..61572dfa1f60 100644
--- a/drivers/net/wireless/wl12xx/wl1251_boot.c
+++ b/drivers/net/wireless/wl1251/boot.c
@@ -22,12 +22,12 @@
22#include <linux/gpio.h> 22#include <linux/gpio.h>
23#include <linux/slab.h> 23#include <linux/slab.h>
24 24
25#include "wl1251_reg.h" 25#include "reg.h"
26#include "wl1251_boot.h" 26#include "boot.h"
27#include "wl1251_io.h" 27#include "io.h"
28#include "wl1251_spi.h" 28#include "spi.h"
29#include "wl1251_event.h" 29#include "event.h"
30#include "wl1251_acx.h" 30#include "acx.h"
31 31
32void wl1251_boot_target_enable_interrupts(struct wl1251 *wl) 32void wl1251_boot_target_enable_interrupts(struct wl1251 *wl)
33{ 33{
diff --git a/drivers/net/wireless/wl12xx/wl1251_boot.h b/drivers/net/wireless/wl1251/boot.h
index 7661bc5e4662..7661bc5e4662 100644
--- a/drivers/net/wireless/wl12xx/wl1251_boot.h
+++ b/drivers/net/wireless/wl1251/boot.h
diff --git a/drivers/net/wireless/wl12xx/wl1251_cmd.c b/drivers/net/wireless/wl1251/cmd.c
index 15fb68c6b542..0ade4bd617c0 100644
--- a/drivers/net/wireless/wl12xx/wl1251_cmd.c
+++ b/drivers/net/wireless/wl1251/cmd.c
@@ -1,14 +1,14 @@
1#include "wl1251_cmd.h" 1#include "cmd.h"
2 2
3#include <linux/module.h> 3#include <linux/module.h>
4#include <linux/slab.h> 4#include <linux/slab.h>
5#include <linux/crc7.h> 5#include <linux/crc7.h>
6 6
7#include "wl1251.h" 7#include "wl1251.h"
8#include "wl1251_reg.h" 8#include "reg.h"
9#include "wl1251_io.h" 9#include "io.h"
10#include "wl1251_ps.h" 10#include "ps.h"
11#include "wl1251_acx.h" 11#include "acx.h"
12 12
13/** 13/**
14 * send command to firmware 14 * send command to firmware
diff --git a/drivers/net/wireless/wl12xx/wl1251_cmd.h b/drivers/net/wireless/wl1251/cmd.h
index e5c74c631374..e5c74c631374 100644
--- a/drivers/net/wireless/wl12xx/wl1251_cmd.h
+++ b/drivers/net/wireless/wl1251/cmd.h
diff --git a/drivers/net/wireless/wl12xx/wl1251_debugfs.c b/drivers/net/wireless/wl1251/debugfs.c
index 6ffe4cd58561..6e5caaa9f613 100644
--- a/drivers/net/wireless/wl12xx/wl1251_debugfs.c
+++ b/drivers/net/wireless/wl1251/debugfs.c
@@ -19,14 +19,14 @@
19 * 19 *
20 */ 20 */
21 21
22#include "wl1251_debugfs.h" 22#include "debugfs.h"
23 23
24#include <linux/skbuff.h> 24#include <linux/skbuff.h>
25#include <linux/slab.h> 25#include <linux/slab.h>
26 26
27#include "wl1251.h" 27#include "wl1251.h"
28#include "wl1251_acx.h" 28#include "acx.h"
29#include "wl1251_ps.h" 29#include "ps.h"
30 30
31/* ms */ 31/* ms */
32#define WL1251_DEBUGFS_STATS_LIFETIME 1000 32#define WL1251_DEBUGFS_STATS_LIFETIME 1000
diff --git a/drivers/net/wireless/wl12xx/wl1251_debugfs.h b/drivers/net/wireless/wl1251/debugfs.h
index b3417c02a218..b3417c02a218 100644
--- a/drivers/net/wireless/wl12xx/wl1251_debugfs.h
+++ b/drivers/net/wireless/wl1251/debugfs.h
diff --git a/drivers/net/wireless/wl12xx/wl1251_event.c b/drivers/net/wireless/wl1251/event.c
index 54223556b308..712372e50a87 100644
--- a/drivers/net/wireless/wl12xx/wl1251_event.c
+++ b/drivers/net/wireless/wl1251/event.c
@@ -21,10 +21,10 @@
21 */ 21 */
22 22
23#include "wl1251.h" 23#include "wl1251.h"
24#include "wl1251_reg.h" 24#include "reg.h"
25#include "wl1251_io.h" 25#include "io.h"
26#include "wl1251_event.h" 26#include "event.h"
27#include "wl1251_ps.h" 27#include "ps.h"
28 28
29static int wl1251_event_scan_complete(struct wl1251 *wl, 29static int wl1251_event_scan_complete(struct wl1251 *wl,
30 struct event_mailbox *mbox) 30 struct event_mailbox *mbox)
diff --git a/drivers/net/wireless/wl12xx/wl1251_event.h b/drivers/net/wireless/wl1251/event.h
index 30eb5d150bf7..30eb5d150bf7 100644
--- a/drivers/net/wireless/wl12xx/wl1251_event.h
+++ b/drivers/net/wireless/wl1251/event.h
diff --git a/drivers/net/wireless/wl12xx/wl1251_init.c b/drivers/net/wireless/wl1251/init.c
index c5daec05d9ee..89b43d35473c 100644
--- a/drivers/net/wireless/wl12xx/wl1251_init.c
+++ b/drivers/net/wireless/wl1251/init.c
@@ -23,11 +23,11 @@
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/slab.h> 24#include <linux/slab.h>
25 25
26#include "wl1251_init.h" 26#include "init.h"
27#include "wl12xx_80211.h" 27#include "wl12xx_80211.h"
28#include "wl1251_acx.h" 28#include "acx.h"
29#include "wl1251_cmd.h" 29#include "cmd.h"
30#include "wl1251_reg.h" 30#include "reg.h"
31 31
32int wl1251_hw_init_hwenc_config(struct wl1251 *wl) 32int wl1251_hw_init_hwenc_config(struct wl1251 *wl)
33{ 33{
diff --git a/drivers/net/wireless/wl12xx/wl1251_init.h b/drivers/net/wireless/wl1251/init.h
index 543f17582ead..543f17582ead 100644
--- a/drivers/net/wireless/wl12xx/wl1251_init.h
+++ b/drivers/net/wireless/wl1251/init.h
diff --git a/drivers/net/wireless/wl12xx/wl1251_io.c b/drivers/net/wireless/wl1251/io.c
index ad6ca68b303f..cdcadbf6ac2c 100644
--- a/drivers/net/wireless/wl12xx/wl1251_io.c
+++ b/drivers/net/wireless/wl1251/io.c
@@ -20,8 +20,8 @@
20 */ 20 */
21 21
22#include "wl1251.h" 22#include "wl1251.h"
23#include "wl1251_reg.h" 23#include "reg.h"
24#include "wl1251_io.h" 24#include "io.h"
25 25
26/* FIXME: this is static data nowadays and the table can be removed */ 26/* FIXME: this is static data nowadays and the table can be removed */
27static enum wl12xx_acx_int_reg wl1251_io_reg_table[ACX_REG_TABLE_LEN] = { 27static enum wl12xx_acx_int_reg wl1251_io_reg_table[ACX_REG_TABLE_LEN] = {
diff --git a/drivers/net/wireless/wl12xx/wl1251_io.h b/drivers/net/wireless/wl1251/io.h
index c545e9d5f512..c545e9d5f512 100644
--- a/drivers/net/wireless/wl12xx/wl1251_io.h
+++ b/drivers/net/wireless/wl1251/io.h
diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl1251/main.c
index faf221ca3f41..7a8762553cdc 100644
--- a/drivers/net/wireless/wl12xx/wl1251_main.c
+++ b/drivers/net/wireless/wl1251/main.c
@@ -31,16 +31,16 @@
31 31
32#include "wl1251.h" 32#include "wl1251.h"
33#include "wl12xx_80211.h" 33#include "wl12xx_80211.h"
34#include "wl1251_reg.h" 34#include "reg.h"
35#include "wl1251_io.h" 35#include "io.h"
36#include "wl1251_cmd.h" 36#include "cmd.h"
37#include "wl1251_event.h" 37#include "event.h"
38#include "wl1251_tx.h" 38#include "tx.h"
39#include "wl1251_rx.h" 39#include "rx.h"
40#include "wl1251_ps.h" 40#include "ps.h"
41#include "wl1251_init.h" 41#include "init.h"
42#include "wl1251_debugfs.h" 42#include "debugfs.h"
43#include "wl1251_boot.h" 43#include "boot.h"
44 44
45void wl1251_enable_interrupts(struct wl1251 *wl) 45void wl1251_enable_interrupts(struct wl1251 *wl)
46{ 46{
diff --git a/drivers/net/wireless/wl12xx/wl1251_ps.c b/drivers/net/wireless/wl1251/ps.c
index 0b997bdfec09..5ed47c8373d2 100644
--- a/drivers/net/wireless/wl12xx/wl1251_ps.c
+++ b/drivers/net/wireless/wl1251/ps.c
@@ -19,10 +19,10 @@
19 * 19 *
20 */ 20 */
21 21
22#include "wl1251_reg.h" 22#include "reg.h"
23#include "wl1251_ps.h" 23#include "ps.h"
24#include "wl1251_cmd.h" 24#include "cmd.h"
25#include "wl1251_io.h" 25#include "io.h"
26 26
27/* in ms */ 27/* in ms */
28#define WL1251_WAKEUP_TIMEOUT 100 28#define WL1251_WAKEUP_TIMEOUT 100
diff --git a/drivers/net/wireless/wl12xx/wl1251_ps.h b/drivers/net/wireless/wl1251/ps.h
index e5db81fc1dfc..55c3dda75e69 100644
--- a/drivers/net/wireless/wl12xx/wl1251_ps.h
+++ b/drivers/net/wireless/wl1251/ps.h
@@ -24,7 +24,7 @@
24#define __WL1251_PS_H__ 24#define __WL1251_PS_H__
25 25
26#include "wl1251.h" 26#include "wl1251.h"
27#include "wl1251_acx.h" 27#include "acx.h"
28 28
29int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode); 29int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode);
30void wl1251_ps_elp_sleep(struct wl1251 *wl); 30void wl1251_ps_elp_sleep(struct wl1251 *wl);
diff --git a/drivers/net/wireless/wl12xx/wl1251_reg.h b/drivers/net/wireless/wl1251/reg.h
index a5809019c5c1..a5809019c5c1 100644
--- a/drivers/net/wireless/wl12xx/wl1251_reg.h
+++ b/drivers/net/wireless/wl1251/reg.h
diff --git a/drivers/net/wireless/wl12xx/wl1251_rx.c b/drivers/net/wireless/wl1251/rx.c
index 25764592a596..efa53607d5c9 100644
--- a/drivers/net/wireless/wl12xx/wl1251_rx.c
+++ b/drivers/net/wireless/wl1251/rx.c
@@ -25,11 +25,11 @@
25#include <net/mac80211.h> 25#include <net/mac80211.h>
26 26
27#include "wl1251.h" 27#include "wl1251.h"
28#include "wl1251_reg.h" 28#include "reg.h"
29#include "wl1251_io.h" 29#include "io.h"
30#include "wl1251_rx.h" 30#include "rx.h"
31#include "wl1251_cmd.h" 31#include "cmd.h"
32#include "wl1251_acx.h" 32#include "acx.h"
33 33
34static void wl1251_rx_header(struct wl1251 *wl, 34static void wl1251_rx_header(struct wl1251 *wl,
35 struct wl1251_rx_descriptor *desc) 35 struct wl1251_rx_descriptor *desc)
diff --git a/drivers/net/wireless/wl12xx/wl1251_rx.h b/drivers/net/wireless/wl1251/rx.h
index 4448f635a4d8..4448f635a4d8 100644
--- a/drivers/net/wireless/wl12xx/wl1251_rx.h
+++ b/drivers/net/wireless/wl1251/rx.h
diff --git a/drivers/net/wireless/wl12xx/wl1251_sdio.c b/drivers/net/wireless/wl1251/sdio.c
index 74ba9ced5393..74ba9ced5393 100644
--- a/drivers/net/wireless/wl12xx/wl1251_sdio.c
+++ b/drivers/net/wireless/wl1251/sdio.c
diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.c b/drivers/net/wireless/wl1251/spi.c
index 320de79667a6..88fa8e69d0d1 100644
--- a/drivers/net/wireless/wl12xx/wl1251_spi.c
+++ b/drivers/net/wireless/wl1251/spi.c
@@ -27,8 +27,8 @@
27#include <linux/wl12xx.h> 27#include <linux/wl12xx.h>
28 28
29#include "wl1251.h" 29#include "wl1251.h"
30#include "wl1251_reg.h" 30#include "reg.h"
31#include "wl1251_spi.h" 31#include "spi.h"
32 32
33static irqreturn_t wl1251_irq(int irq, void *cookie) 33static irqreturn_t wl1251_irq(int irq, void *cookie)
34{ 34{
diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.h b/drivers/net/wireless/wl1251/spi.h
index 7dcf3cf7ae40..16d506955cc0 100644
--- a/drivers/net/wireless/wl12xx/wl1251_spi.h
+++ b/drivers/net/wireless/wl1251/spi.h
@@ -23,9 +23,9 @@
23#ifndef __WL1251_SPI_H__ 23#ifndef __WL1251_SPI_H__
24#define __WL1251_SPI_H__ 24#define __WL1251_SPI_H__
25 25
26#include "wl1251_cmd.h" 26#include "cmd.h"
27#include "wl1251_acx.h" 27#include "acx.h"
28#include "wl1251_reg.h" 28#include "reg.h"
29 29
30#define WSPI_CMD_READ 0x40000000 30#define WSPI_CMD_READ 0x40000000
31#define WSPI_CMD_WRITE 0x00000000 31#define WSPI_CMD_WRITE 0x00000000
diff --git a/drivers/net/wireless/wl12xx/wl1251_tx.c b/drivers/net/wireless/wl1251/tx.c
index 388492a7f41f..554b4f9a3d3e 100644
--- a/drivers/net/wireless/wl12xx/wl1251_tx.c
+++ b/drivers/net/wireless/wl1251/tx.c
@@ -24,10 +24,10 @@
24#include <linux/module.h> 24#include <linux/module.h>
25 25
26#include "wl1251.h" 26#include "wl1251.h"
27#include "wl1251_reg.h" 27#include "reg.h"
28#include "wl1251_tx.h" 28#include "tx.h"
29#include "wl1251_ps.h" 29#include "ps.h"
30#include "wl1251_io.h" 30#include "io.h"
31 31
32static bool wl1251_tx_double_buffer_busy(struct wl1251 *wl, u32 data_out_count) 32static bool wl1251_tx_double_buffer_busy(struct wl1251 *wl, u32 data_out_count)
33{ 33{
diff --git a/drivers/net/wireless/wl12xx/wl1251_tx.h b/drivers/net/wireless/wl1251/tx.h
index 96011e78cd5a..81338d39b43e 100644
--- a/drivers/net/wireless/wl12xx/wl1251_tx.h
+++ b/drivers/net/wireless/wl1251/tx.h
@@ -24,7 +24,7 @@
24#define __WL1251_TX_H__ 24#define __WL1251_TX_H__
25 25
26#include <linux/bitops.h> 26#include <linux/bitops.h>
27#include "wl1251_acx.h" 27#include "acx.h"
28 28
29/* 29/*
30 * 30 *
diff --git a/drivers/net/wireless/wl12xx/wl1251.h b/drivers/net/wireless/wl1251/wl1251.h
index e113d4c1fb35..e113d4c1fb35 100644
--- a/drivers/net/wireless/wl12xx/wl1251.h
+++ b/drivers/net/wireless/wl1251/wl1251.h
diff --git a/drivers/net/wireless/wl1251/wl12xx_80211.h b/drivers/net/wireless/wl1251/wl12xx_80211.h
new file mode 100644
index 000000000000..184628027213
--- /dev/null
+++ b/drivers/net/wireless/wl1251/wl12xx_80211.h
@@ -0,0 +1,156 @@
1#ifndef __WL12XX_80211_H__
2#define __WL12XX_80211_H__
3
4#include <linux/if_ether.h> /* ETH_ALEN */
5
6/* RATES */
7#define IEEE80211_CCK_RATE_1MB 0x02
8#define IEEE80211_CCK_RATE_2MB 0x04
9#define IEEE80211_CCK_RATE_5MB 0x0B
10#define IEEE80211_CCK_RATE_11MB 0x16
11#define IEEE80211_OFDM_RATE_6MB 0x0C
12#define IEEE80211_OFDM_RATE_9MB 0x12
13#define IEEE80211_OFDM_RATE_12MB 0x18
14#define IEEE80211_OFDM_RATE_18MB 0x24
15#define IEEE80211_OFDM_RATE_24MB 0x30
16#define IEEE80211_OFDM_RATE_36MB 0x48
17#define IEEE80211_OFDM_RATE_48MB 0x60
18#define IEEE80211_OFDM_RATE_54MB 0x6C
19#define IEEE80211_BASIC_RATE_MASK 0x80
20
21#define IEEE80211_CCK_RATE_1MB_MASK (1<<0)
22#define IEEE80211_CCK_RATE_2MB_MASK (1<<1)
23#define IEEE80211_CCK_RATE_5MB_MASK (1<<2)
24#define IEEE80211_CCK_RATE_11MB_MASK (1<<3)
25#define IEEE80211_OFDM_RATE_6MB_MASK (1<<4)
26#define IEEE80211_OFDM_RATE_9MB_MASK (1<<5)
27#define IEEE80211_OFDM_RATE_12MB_MASK (1<<6)
28#define IEEE80211_OFDM_RATE_18MB_MASK (1<<7)
29#define IEEE80211_OFDM_RATE_24MB_MASK (1<<8)
30#define IEEE80211_OFDM_RATE_36MB_MASK (1<<9)
31#define IEEE80211_OFDM_RATE_48MB_MASK (1<<10)
32#define IEEE80211_OFDM_RATE_54MB_MASK (1<<11)
33
34#define IEEE80211_CCK_RATES_MASK 0x0000000F
35#define IEEE80211_CCK_BASIC_RATES_MASK (IEEE80211_CCK_RATE_1MB_MASK | \
36 IEEE80211_CCK_RATE_2MB_MASK)
37#define IEEE80211_CCK_DEFAULT_RATES_MASK (IEEE80211_CCK_BASIC_RATES_MASK | \
38 IEEE80211_CCK_RATE_5MB_MASK | \
39 IEEE80211_CCK_RATE_11MB_MASK)
40
41#define IEEE80211_OFDM_RATES_MASK 0x00000FF0
42#define IEEE80211_OFDM_BASIC_RATES_MASK (IEEE80211_OFDM_RATE_6MB_MASK | \
43 IEEE80211_OFDM_RATE_12MB_MASK | \
44 IEEE80211_OFDM_RATE_24MB_MASK)
45#define IEEE80211_OFDM_DEFAULT_RATES_MASK (IEEE80211_OFDM_BASIC_RATES_MASK | \
46 IEEE80211_OFDM_RATE_9MB_MASK | \
47 IEEE80211_OFDM_RATE_18MB_MASK | \
48 IEEE80211_OFDM_RATE_36MB_MASK | \
49 IEEE80211_OFDM_RATE_48MB_MASK | \
50 IEEE80211_OFDM_RATE_54MB_MASK)
51#define IEEE80211_DEFAULT_RATES_MASK (IEEE80211_OFDM_DEFAULT_RATES_MASK | \
52 IEEE80211_CCK_DEFAULT_RATES_MASK)
53
54
55/* This really should be 8, but not for our firmware */
56#define MAX_SUPPORTED_RATES 32
57#define COUNTRY_STRING_LEN 3
58#define MAX_COUNTRY_TRIPLETS 32
59
60/* Headers */
61struct ieee80211_header {
62 __le16 frame_ctl;
63 __le16 duration_id;
64 u8 da[ETH_ALEN];
65 u8 sa[ETH_ALEN];
66 u8 bssid[ETH_ALEN];
67 __le16 seq_ctl;
68 u8 payload[0];
69} __packed;
70
71struct wl12xx_ie_header {
72 u8 id;
73 u8 len;
74} __packed;
75
76/* IEs */
77
78struct wl12xx_ie_ssid {
79 struct wl12xx_ie_header header;
80 char ssid[IW_ESSID_MAX_SIZE];
81} __packed;
82
83struct wl12xx_ie_rates {
84 struct wl12xx_ie_header header;
85 u8 rates[MAX_SUPPORTED_RATES];
86} __packed;
87
88struct wl12xx_ie_ds_params {
89 struct wl12xx_ie_header header;
90 u8 channel;
91} __packed;
92
93struct country_triplet {
94 u8 channel;
95 u8 num_channels;
96 u8 max_tx_power;
97} __packed;
98
99struct wl12xx_ie_country {
100 struct wl12xx_ie_header header;
101 u8 country_string[COUNTRY_STRING_LEN];
102 struct country_triplet triplets[MAX_COUNTRY_TRIPLETS];
103} __packed;
104
105
106/* Templates */
107
108struct wl12xx_beacon_template {
109 struct ieee80211_header header;
110 __le32 time_stamp[2];
111 __le16 beacon_interval;
112 __le16 capability;
113 struct wl12xx_ie_ssid ssid;
114 struct wl12xx_ie_rates rates;
115 struct wl12xx_ie_rates ext_rates;
116 struct wl12xx_ie_ds_params ds_params;
117 struct wl12xx_ie_country country;
118} __packed;
119
120struct wl12xx_null_data_template {
121 struct ieee80211_header header;
122} __packed;
123
124struct wl12xx_ps_poll_template {
125 __le16 fc;
126 __le16 aid;
127 u8 bssid[ETH_ALEN];
128 u8 ta[ETH_ALEN];
129} __packed;
130
131struct wl12xx_qos_null_data_template {
132 struct ieee80211_header header;
133 __le16 qos_ctl;
134} __packed;
135
136struct wl12xx_probe_req_template {
137 struct ieee80211_header header;
138 struct wl12xx_ie_ssid ssid;
139 struct wl12xx_ie_rates rates;
140 struct wl12xx_ie_rates ext_rates;
141} __packed;
142
143
144struct wl12xx_probe_resp_template {
145 struct ieee80211_header header;
146 __le32 time_stamp[2];
147 __le16 beacon_interval;
148 __le16 capability;
149 struct wl12xx_ie_ssid ssid;
150 struct wl12xx_ie_rates rates;
151 struct wl12xx_ie_rates ext_rates;
152 struct wl12xx_ie_ds_params ds_params;
153 struct wl12xx_ie_country country;
154} __packed;
155
156#endif
diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig
index 4a8bb25c1739..b447559f1db5 100644
--- a/drivers/net/wireless/wl12xx/Kconfig
+++ b/drivers/net/wireless/wl12xx/Kconfig
@@ -5,40 +5,6 @@ menuconfig WL12XX
5 This will enable TI wl12xx driver support. The drivers make 5 This will enable TI wl12xx driver support. The drivers make
6 use of the mac80211 stack. 6 use of the mac80211 stack.
7 7
8config WL1251
9 tristate "TI wl1251 support"
10 depends on WL12XX && GENERIC_HARDIRQS
11 select FW_LOADER
12 select CRC7
13 ---help---
14 This module adds support for wireless adapters based on
15 TI wl1251 chipset.
16
17 If you choose to build a module, it'll be called wl1251. Say
18 N if unsure.
19
20config WL1251_SPI
21 tristate "TI wl1251 SPI support"
22 depends on WL1251 && SPI_MASTER
23 ---help---
24 This module adds support for the SPI interface of adapters using
25 TI wl1251 chipset. Select this if your platform is using
26 the SPI bus.
27
28 If you choose to build a module, it'll be called wl1251_spi.
29 Say N if unsure.
30
31config WL1251_SDIO
32 tristate "TI wl1251 SDIO support"
33 depends on WL1251 && MMC
34 ---help---
35 This module adds support for the SDIO interface of adapters using
36 TI wl1251 chipset. Select this if your platform is using
37 the SDIO bus.
38
39 If you choose to build a module, it'll be called
40 wl1251_sdio. Say N if unsure.
41
42config WL1271 8config WL1271
43 tristate "TI wl1271 support" 9 tristate "TI wl1271 support"
44 depends on WL12XX && GENERIC_HARDIRQS 10 depends on WL12XX && GENERIC_HARDIRQS
diff --git a/drivers/net/wireless/wl12xx/Makefile b/drivers/net/wireless/wl12xx/Makefile
index 0d334d6f86f4..3a807444b2af 100644
--- a/drivers/net/wireless/wl12xx/Makefile
+++ b/drivers/net/wireless/wl12xx/Makefile
@@ -1,12 +1,3 @@
1wl1251-objs = wl1251_main.o wl1251_event.o \
2 wl1251_tx.o wl1251_rx.o wl1251_ps.o wl1251_cmd.o \
3 wl1251_acx.o wl1251_boot.o wl1251_init.o \
4 wl1251_debugfs.o wl1251_io.o
5
6obj-$(CONFIG_WL1251) += wl1251.o
7obj-$(CONFIG_WL1251_SPI) += wl1251_spi.o
8obj-$(CONFIG_WL1251_SDIO) += wl1251_sdio.o
9
10wl1271-objs = wl1271_main.o wl1271_cmd.o wl1271_io.o \ 1wl1271-objs = wl1271_main.o wl1271_cmd.o wl1271_io.o \
11 wl1271_event.o wl1271_tx.o wl1271_rx.o \ 2 wl1271_event.o wl1271_tx.o wl1271_rx.o \
12 wl1271_ps.o wl1271_acx.o wl1271_boot.o \ 3 wl1271_ps.o wl1271_acx.o wl1271_boot.o \
diff --git a/drivers/net/wireless/wl12xx/wl1271_sdio.c b/drivers/net/wireless/wl12xx/wl1271_sdio.c
index 4c250d7dc3fa..784ef3432641 100644
--- a/drivers/net/wireless/wl12xx/wl1271_sdio.c
+++ b/drivers/net/wireless/wl12xx/wl1271_sdio.c
@@ -30,6 +30,7 @@
30#include <linux/mmc/card.h> 30#include <linux/mmc/card.h>
31#include <linux/gpio.h> 31#include <linux/gpio.h>
32#include <linux/wl12xx.h> 32#include <linux/wl12xx.h>
33#include <linux/pm_runtime.h>
33 34
34#include "wl1271.h" 35#include "wl1271.h"
35#include "wl12xx_80211.h" 36#include "wl12xx_80211.h"
@@ -160,12 +161,19 @@ static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf,
160static int wl1271_sdio_power_on(struct wl1271 *wl) 161static int wl1271_sdio_power_on(struct wl1271 *wl)
161{ 162{
162 struct sdio_func *func = wl_to_func(wl); 163 struct sdio_func *func = wl_to_func(wl);
164 int ret;
165
166 /* Power up the card */
167 ret = pm_runtime_get_sync(&func->dev);
168 if (ret < 0)
169 goto out;
163 170
164 sdio_claim_host(func); 171 sdio_claim_host(func);
165 sdio_enable_func(func); 172 sdio_enable_func(func);
166 sdio_release_host(func); 173 sdio_release_host(func);
167 174
168 return 0; 175out:
176 return ret;
169} 177}
170 178
171static int wl1271_sdio_power_off(struct wl1271 *wl) 179static int wl1271_sdio_power_off(struct wl1271 *wl)
@@ -176,15 +184,12 @@ static int wl1271_sdio_power_off(struct wl1271 *wl)
176 sdio_disable_func(func); 184 sdio_disable_func(func);
177 sdio_release_host(func); 185 sdio_release_host(func);
178 186
179 return 0; 187 /* Power down the card */
188 return pm_runtime_put_sync(&func->dev);
180} 189}
181 190
182static int wl1271_sdio_set_power(struct wl1271 *wl, bool enable) 191static int wl1271_sdio_set_power(struct wl1271 *wl, bool enable)
183{ 192{
184 /* Let the SDIO stack handle wlan_enable control, so we
185 * keep host claimed while wlan is in use to keep wl1271
186 * alive.
187 */
188 if (enable) 193 if (enable)
189 return wl1271_sdio_power_on(wl); 194 return wl1271_sdio_power_on(wl);
190 else 195 else
@@ -256,6 +261,9 @@ static int __devinit wl1271_probe(struct sdio_func *func,
256 261
257 sdio_set_drvdata(func, wl); 262 sdio_set_drvdata(func, wl);
258 263
264 /* Tell PM core that we don't need the card to be powered now */
265 pm_runtime_put_noidle(&func->dev);
266
259 wl1271_notice("initialized"); 267 wl1271_notice("initialized");
260 268
261 return 0; 269 return 0;
@@ -274,16 +282,39 @@ static void __devexit wl1271_remove(struct sdio_func *func)
274{ 282{
275 struct wl1271 *wl = sdio_get_drvdata(func); 283 struct wl1271 *wl = sdio_get_drvdata(func);
276 284
285 /* Undo decrement done above in wl1271_probe */
286 pm_runtime_get_noresume(&func->dev);
287
277 wl1271_unregister_hw(wl); 288 wl1271_unregister_hw(wl);
278 free_irq(wl->irq, wl); 289 free_irq(wl->irq, wl);
279 wl1271_free_hw(wl); 290 wl1271_free_hw(wl);
280} 291}
281 292
293static int wl1271_suspend(struct device *dev)
294{
295 /* Tell MMC/SDIO core it's OK to power down the card
296 * (if it isn't already), but not to remove it completely */
297 return 0;
298}
299
300static int wl1271_resume(struct device *dev)
301{
302 return 0;
303}
304
305static const struct dev_pm_ops wl1271_sdio_pm_ops = {
306 .suspend = wl1271_suspend,
307 .resume = wl1271_resume,
308};
309
282static struct sdio_driver wl1271_sdio_driver = { 310static struct sdio_driver wl1271_sdio_driver = {
283 .name = "wl1271_sdio", 311 .name = "wl1271_sdio",
284 .id_table = wl1271_devices, 312 .id_table = wl1271_devices,
285 .probe = wl1271_probe, 313 .probe = wl1271_probe,
286 .remove = __devexit_p(wl1271_remove), 314 .remove = __devexit_p(wl1271_remove),
315 .drv = {
316 .pm = &wl1271_sdio_pm_ops,
317 },
287}; 318};
288 319
289static int __init wl1271_init(void) 320static int __init wl1271_init(void)
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 97b2eae6a22c..ed5a03cbe184 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -986,6 +986,7 @@ struct ieee80211_ht_info {
986#define WLAN_AUTH_OPEN 0 986#define WLAN_AUTH_OPEN 0
987#define WLAN_AUTH_SHARED_KEY 1 987#define WLAN_AUTH_SHARED_KEY 1
988#define WLAN_AUTH_FT 2 988#define WLAN_AUTH_FT 2
989#define WLAN_AUTH_SAE 3
989#define WLAN_AUTH_LEAP 128 990#define WLAN_AUTH_LEAP 128
990 991
991#define WLAN_AUTH_CHALLENGE_LEN 128 992#define WLAN_AUTH_CHALLENGE_LEN 128
@@ -1072,6 +1073,10 @@ enum ieee80211_statuscode {
1072 WLAN_STATUS_NO_DIRECT_LINK = 48, 1073 WLAN_STATUS_NO_DIRECT_LINK = 48,
1073 WLAN_STATUS_STA_NOT_PRESENT = 49, 1074 WLAN_STATUS_STA_NOT_PRESENT = 49,
1074 WLAN_STATUS_STA_NOT_QSTA = 50, 1075 WLAN_STATUS_STA_NOT_QSTA = 50,
1076 /* 802.11s */
1077 WLAN_STATUS_ANTI_CLOG_REQUIRED = 76,
1078 WLAN_STATUS_FCG_NOT_SUPP = 78,
1079 WLAN_STATUS_STA_NO_TBTT = 78,
1075}; 1080};
1076 1081
1077 1082
@@ -1112,6 +1117,22 @@ enum ieee80211_reasoncode {
1112 WLAN_REASON_QSTA_REQUIRE_SETUP = 38, 1117 WLAN_REASON_QSTA_REQUIRE_SETUP = 38,
1113 WLAN_REASON_QSTA_TIMEOUT = 39, 1118 WLAN_REASON_QSTA_TIMEOUT = 39,
1114 WLAN_REASON_QSTA_CIPHER_NOT_SUPP = 45, 1119 WLAN_REASON_QSTA_CIPHER_NOT_SUPP = 45,
1120 /* 802.11s */
1121 WLAN_REASON_MESH_PEER_CANCELED = 52,
1122 WLAN_REASON_MESH_MAX_PEERS = 53,
1123 WLAN_REASON_MESH_CONFIG = 54,
1124 WLAN_REASON_MESH_CLOSE = 55,
1125 WLAN_REASON_MESH_MAX_RETRIES = 56,
1126 WLAN_REASON_MESH_CONFIRM_TIMEOUT = 57,
1127 WLAN_REASON_MESH_INVALID_GTK = 58,
1128 WLAN_REASON_MESH_INCONSISTENT_PARAM = 59,
1129 WLAN_REASON_MESH_INVALID_SECURITY = 60,
1130 WLAN_REASON_MESH_PATH_ERROR = 61,
1131 WLAN_REASON_MESH_PATH_NOFORWARD = 62,
1132 WLAN_REASON_MESH_PATH_DEST_UNREACHABLE = 63,
1133 WLAN_REASON_MAC_EXISTS_IN_MBSS = 64,
1134 WLAN_REASON_MESH_CHAN_REGULATORY = 65,
1135 WLAN_REASON_MESH_CHAN = 66,
1115}; 1136};
1116 1137
1117 1138
@@ -1139,20 +1160,33 @@ enum ieee80211_eid {
1139 WLAN_EID_TS_DELAY = 43, 1160 WLAN_EID_TS_DELAY = 43,
1140 WLAN_EID_TCLAS_PROCESSING = 44, 1161 WLAN_EID_TCLAS_PROCESSING = 44,
1141 WLAN_EID_QOS_CAPA = 46, 1162 WLAN_EID_QOS_CAPA = 46,
1142 /* 802.11s 1163 /* 802.11s */
1143 * 1164 WLAN_EID_MESH_CONFIG = 113,
1144 * All mesh EID numbers are pending IEEE 802.11 ANA approval. 1165 WLAN_EID_MESH_ID = 114,
1145 * The numbers have been incremented from those suggested in 1166 WLAN_EID_LINK_METRIC_REPORT = 115,
1146 * 802.11s/D2.0 so that MESH_CONFIG does not conflict with 1167 WLAN_EID_CONGESTION_NOTIFICATION = 116,
1147 * EXT_SUPP_RATES. 1168 /* Note that the Peer Link IE has been replaced with the similar
1169 * Peer Management IE. We will keep the former definition until mesh
1170 * code is changed to comply with latest 802.11s drafts.
1148 */ 1171 */
1149 WLAN_EID_MESH_CONFIG = 51, 1172 WLAN_EID_PEER_LINK = 55, /* no longer in 802.11s drafts */
1150 WLAN_EID_MESH_ID = 52, 1173 WLAN_EID_PEER_MGMT = 117,
1151 WLAN_EID_PEER_LINK = 55, 1174 WLAN_EID_CHAN_SWITCH_PARAM = 118,
1152 WLAN_EID_PREQ = 68, 1175 WLAN_EID_MESH_AWAKE_WINDOW = 119,
1153 WLAN_EID_PREP = 69, 1176 WLAN_EID_BEACON_TIMING = 120,
1154 WLAN_EID_PERR = 70, 1177 WLAN_EID_MCCAOP_SETUP_REQ = 121,
1155 WLAN_EID_RANN = 49, /* compatible with FreeBSD */ 1178 WLAN_EID_MCCAOP_SETUP_RESP = 122,
1179 WLAN_EID_MCCAOP_ADVERT = 123,
1180 WLAN_EID_MCCAOP_TEARDOWN = 124,
1181 WLAN_EID_GANN = 125,
1182 WLAN_EID_RANN = 126,
1183 WLAN_EID_PREQ = 130,
1184 WLAN_EID_PREP = 131,
1185 WLAN_EID_PERR = 132,
1186 WLAN_EID_PXU = 137,
1187 WLAN_EID_PXUC = 138,
1188 WLAN_EID_AUTH_MESH_PEER_EXCH = 139,
1189 WLAN_EID_MIC = 140,
1156 1190
1157 WLAN_EID_PWR_CONSTRAINT = 32, 1191 WLAN_EID_PWR_CONSTRAINT = 32,
1158 WLAN_EID_PWR_CAPABILITY = 33, 1192 WLAN_EID_PWR_CAPABILITY = 33,
@@ -1211,9 +1245,14 @@ enum ieee80211_category {
1211 WLAN_CATEGORY_HT = 7, 1245 WLAN_CATEGORY_HT = 7,
1212 WLAN_CATEGORY_SA_QUERY = 8, 1246 WLAN_CATEGORY_SA_QUERY = 8,
1213 WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION = 9, 1247 WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION = 9,
1248 WLAN_CATEGORY_MESH_ACTION = 13,
1249 WLAN_CATEGORY_MULTIHOP_ACTION = 14,
1250 WLAN_CATEGORY_SELF_PROTECTED = 15,
1214 WLAN_CATEGORY_WMM = 17, 1251 WLAN_CATEGORY_WMM = 17,
1215 WLAN_CATEGORY_MESH_PLINK = 30, /* Pending ANA approval */ 1252 /* TODO: remove MESH_PLINK and MESH_PATH_SEL after */
1216 WLAN_CATEGORY_MESH_PATH_SEL = 32, /* Pending ANA approval */ 1253 /* mesh is updated to current 802.11s draft */
1254 WLAN_CATEGORY_MESH_PLINK = 30,
1255 WLAN_CATEGORY_MESH_PATH_SEL = 32,
1217 WLAN_CATEGORY_VENDOR_SPECIFIC_PROTECTED = 126, 1256 WLAN_CATEGORY_VENDOR_SPECIFIC_PROTECTED = 126,
1218 WLAN_CATEGORY_VENDOR_SPECIFIC = 127, 1257 WLAN_CATEGORY_VENDOR_SPECIFIC = 127,
1219}; 1258};
@@ -1351,6 +1390,8 @@ enum ieee80211_sa_query_action {
1351/* AKM suite selectors */ 1390/* AKM suite selectors */
1352#define WLAN_AKM_SUITE_8021X 0x000FAC01 1391#define WLAN_AKM_SUITE_8021X 0x000FAC01
1353#define WLAN_AKM_SUITE_PSK 0x000FAC02 1392#define WLAN_AKM_SUITE_PSK 0x000FAC02
1393#define WLAN_AKM_SUITE_SAE 0x000FAC08
1394#define WLAN_AKM_SUITE_FT_OVER_SAE 0x000FAC09
1354 1395
1355#define WLAN_MAX_KEY_LEN 32 1396#define WLAN_MAX_KEY_LEN 32
1356 1397
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index c08709fe36fc..0edb2566c14c 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -1413,6 +1413,16 @@ enum nl80211_reg_rule_flags {
1413 * @NL80211_SURVEY_INFO_FREQUENCY: center frequency of channel 1413 * @NL80211_SURVEY_INFO_FREQUENCY: center frequency of channel
1414 * @NL80211_SURVEY_INFO_NOISE: noise level of channel (u8, dBm) 1414 * @NL80211_SURVEY_INFO_NOISE: noise level of channel (u8, dBm)
1415 * @NL80211_SURVEY_INFO_IN_USE: channel is currently being used 1415 * @NL80211_SURVEY_INFO_IN_USE: channel is currently being used
1416 * @NL80211_SURVEY_INFO_CHANNEL_TIME: amount of time (in ms) that the radio
1417 * spent on this channel
1418 * @NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY: amount of the time the primary
1419 * channel was sensed busy (either due to activity or energy detect)
1420 * @NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY: amount of time the extension
1421 * channel was sensed busy
1422 * @NL80211_SURVEY_INFO_CHANNEL_TIME_RX: amount of time the radio spent
1423 * receiving data
1424 * @NL80211_SURVEY_INFO_CHANNEL_TIME_TX: amount of time the radio spent
1425 * transmitting data
1416 * @NL80211_SURVEY_INFO_MAX: highest survey info attribute number 1426 * @NL80211_SURVEY_INFO_MAX: highest survey info attribute number
1417 * currently defined 1427 * currently defined
1418 * @__NL80211_SURVEY_INFO_AFTER_LAST: internal use 1428 * @__NL80211_SURVEY_INFO_AFTER_LAST: internal use
@@ -1422,6 +1432,11 @@ enum nl80211_survey_info {
1422 NL80211_SURVEY_INFO_FREQUENCY, 1432 NL80211_SURVEY_INFO_FREQUENCY,
1423 NL80211_SURVEY_INFO_NOISE, 1433 NL80211_SURVEY_INFO_NOISE,
1424 NL80211_SURVEY_INFO_IN_USE, 1434 NL80211_SURVEY_INFO_IN_USE,
1435 NL80211_SURVEY_INFO_CHANNEL_TIME,
1436 NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY,
1437 NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY,
1438 NL80211_SURVEY_INFO_CHANNEL_TIME_RX,
1439 NL80211_SURVEY_INFO_CHANNEL_TIME_TX,
1425 1440
1426 /* keep last */ 1441 /* keep last */
1427 __NL80211_SURVEY_INFO_AFTER_LAST, 1442 __NL80211_SURVEY_INFO_AFTER_LAST,
diff --git a/include/linux/wireless.h b/include/linux/wireless.h
index e6827eedf18b..4395b28bb86c 100644
--- a/include/linux/wireless.h
+++ b/include/linux/wireless.h
@@ -1157,6 +1157,6 @@ struct __compat_iw_event {
1157#define IW_EV_PARAM_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct iw_param)) 1157#define IW_EV_PARAM_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct iw_param))
1158#define IW_EV_ADDR_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct sockaddr)) 1158#define IW_EV_ADDR_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct sockaddr))
1159#define IW_EV_QUAL_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct iw_quality)) 1159#define IW_EV_QUAL_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct iw_quality))
1160#define IW_EV_POINT_PK_LEN (IW_EV_LCP_LEN + 4) 1160#define IW_EV_POINT_PK_LEN (IW_EV_LCP_PK_LEN + 4)
1161 1161
1162#endif /* _LINUX_WIRELESS_H */ 1162#endif /* _LINUX_WIRELESS_H */
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 0778d04b3bbe..2a7936d7851d 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -294,6 +294,11 @@ struct key_params {
294 * 294 *
295 * @SURVEY_INFO_NOISE_DBM: noise (in dBm) was filled in 295 * @SURVEY_INFO_NOISE_DBM: noise (in dBm) was filled in
296 * @SURVEY_INFO_IN_USE: channel is currently being used 296 * @SURVEY_INFO_IN_USE: channel is currently being used
297 * @SURVEY_INFO_CHANNEL_TIME: channel active time (in ms) was filled in
298 * @SURVEY_INFO_CHANNEL_TIME_BUSY: channel busy time was filled in
299 * @SURVEY_INFO_CHANNEL_TIME_EXT_BUSY: extension channel busy time was filled in
300 * @SURVEY_INFO_CHANNEL_TIME_RX: channel receive time was filled in
301 * @SURVEY_INFO_CHANNEL_TIME_TX: channel transmit time was filled in
297 * 302 *
298 * Used by the driver to indicate which info in &struct survey_info 303 * Used by the driver to indicate which info in &struct survey_info
299 * it has filled in during the get_survey(). 304 * it has filled in during the get_survey().
@@ -301,6 +306,11 @@ struct key_params {
301enum survey_info_flags { 306enum survey_info_flags {
302 SURVEY_INFO_NOISE_DBM = 1<<0, 307 SURVEY_INFO_NOISE_DBM = 1<<0,
303 SURVEY_INFO_IN_USE = 1<<1, 308 SURVEY_INFO_IN_USE = 1<<1,
309 SURVEY_INFO_CHANNEL_TIME = 1<<2,
310 SURVEY_INFO_CHANNEL_TIME_BUSY = 1<<3,
311 SURVEY_INFO_CHANNEL_TIME_EXT_BUSY = 1<<4,
312 SURVEY_INFO_CHANNEL_TIME_RX = 1<<5,
313 SURVEY_INFO_CHANNEL_TIME_TX = 1<<6,
304}; 314};
305 315
306/** 316/**
@@ -310,6 +320,11 @@ enum survey_info_flags {
310 * @filled: bitflag of flags from &enum survey_info_flags 320 * @filled: bitflag of flags from &enum survey_info_flags
311 * @noise: channel noise in dBm. This and all following fields are 321 * @noise: channel noise in dBm. This and all following fields are
312 * optional 322 * optional
323 * @channel_time: amount of time in ms the radio spent on the channel
324 * @channel_time_busy: amount of time the primary channel was sensed busy
325 * @channel_time_ext_busy: amount of time the extension channel was sensed busy
326 * @channel_time_rx: amount of time the radio spent receiving data
327 * @channel_time_tx: amount of time the radio spent transmitting data
313 * 328 *
314 * Used by dump_survey() to report back per-channel survey information. 329 * Used by dump_survey() to report back per-channel survey information.
315 * 330 *
@@ -318,6 +333,11 @@ enum survey_info_flags {
318 */ 333 */
319struct survey_info { 334struct survey_info {
320 struct ieee80211_channel *channel; 335 struct ieee80211_channel *channel;
336 u64 channel_time;
337 u64 channel_time_busy;
338 u64 channel_time_ext_busy;
339 u64 channel_time_rx;
340 u64 channel_time_tx;
321 u32 filled; 341 u32 filled;
322 s8 noise; 342 s8 noise;
323}; 343};
@@ -403,6 +423,7 @@ struct station_parameters {
403 * @STATION_INFO_TX_PACKETS: @tx_packets filled 423 * @STATION_INFO_TX_PACKETS: @tx_packets filled
404 * @STATION_INFO_TX_RETRIES: @tx_retries filled 424 * @STATION_INFO_TX_RETRIES: @tx_retries filled
405 * @STATION_INFO_TX_FAILED: @tx_failed filled 425 * @STATION_INFO_TX_FAILED: @tx_failed filled
426 * @STATION_INFO_RX_DROP_MISC: @rx_dropped_misc filled
406 */ 427 */
407enum station_info_flags { 428enum station_info_flags {
408 STATION_INFO_INACTIVE_TIME = 1<<0, 429 STATION_INFO_INACTIVE_TIME = 1<<0,
@@ -417,6 +438,7 @@ enum station_info_flags {
417 STATION_INFO_TX_PACKETS = 1<<9, 438 STATION_INFO_TX_PACKETS = 1<<9,
418 STATION_INFO_TX_RETRIES = 1<<10, 439 STATION_INFO_TX_RETRIES = 1<<10,
419 STATION_INFO_TX_FAILED = 1<<11, 440 STATION_INFO_TX_FAILED = 1<<11,
441 STATION_INFO_RX_DROP_MISC = 1<<12,
420}; 442};
421 443
422/** 444/**
@@ -468,6 +490,7 @@ struct rate_info {
468 * @tx_packets: packets transmitted to this station 490 * @tx_packets: packets transmitted to this station
469 * @tx_retries: cumulative retry counts 491 * @tx_retries: cumulative retry counts
470 * @tx_failed: number of failed transmissions (retries exceeded, no ACK) 492 * @tx_failed: number of failed transmissions (retries exceeded, no ACK)
493 * @rx_dropped_misc: Dropped for un-specified reason.
471 * @generation: generation number for nl80211 dumps. 494 * @generation: generation number for nl80211 dumps.
472 * This number should increase every time the list of stations 495 * This number should increase every time the list of stations
473 * changes, i.e. when a station is added or removed, so that 496 * changes, i.e. when a station is added or removed, so that
@@ -487,6 +510,7 @@ struct station_info {
487 u32 tx_packets; 510 u32 tx_packets;
488 u32 tx_retries; 511 u32 tx_retries;
489 u32 tx_failed; 512 u32 tx_failed;
513 u32 rx_dropped_misc;
490 514
491 int generation; 515 int generation;
492}; 516};
@@ -1123,6 +1147,9 @@ struct cfg80211_pmksa {
1123 * allows the driver to adjust the dynamic ps timeout value. 1147 * allows the driver to adjust the dynamic ps timeout value.
1124 * @set_cqm_rssi_config: Configure connection quality monitor RSSI threshold. 1148 * @set_cqm_rssi_config: Configure connection quality monitor RSSI threshold.
1125 * 1149 *
1150 * @mgmt_frame_register: Notify driver that a management frame type was
1151 * registered. Note that this callback may not sleep, and cannot run
1152 * concurrently with itself.
1126 */ 1153 */
1127struct cfg80211_ops { 1154struct cfg80211_ops {
1128 int (*suspend)(struct wiphy *wiphy); 1155 int (*suspend)(struct wiphy *wiphy);
@@ -1273,6 +1300,10 @@ struct cfg80211_ops {
1273 int (*set_cqm_rssi_config)(struct wiphy *wiphy, 1300 int (*set_cqm_rssi_config)(struct wiphy *wiphy,
1274 struct net_device *dev, 1301 struct net_device *dev,
1275 s32 rssi_thold, u32 rssi_hyst); 1302 s32 rssi_thold, u32 rssi_hyst);
1303
1304 void (*mgmt_frame_register)(struct wiphy *wiphy,
1305 struct net_device *dev,
1306 u16 frame_type, bool reg);
1276}; 1307};
1277 1308
1278/* 1309/*
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 33aa2e39147b..9fdf982d1286 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1478,12 +1478,14 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw,
1478 * honour this flag if possible. 1478 * honour this flag if possible.
1479 * 1479 *
1480 * @FIF_CONTROL: pass control frames (except for PS Poll), if PROMISC_IN_BSS 1480 * @FIF_CONTROL: pass control frames (except for PS Poll), if PROMISC_IN_BSS
1481 * is not set then only those addressed to this station. 1481 * is not set then only those addressed to this station.
1482 * 1482 *
1483 * @FIF_OTHER_BSS: pass frames destined to other BSSes 1483 * @FIF_OTHER_BSS: pass frames destined to other BSSes
1484 * 1484 *
1485 * @FIF_PSPOLL: pass PS Poll frames, if PROMISC_IN_BSS is not set then only 1485 * @FIF_PSPOLL: pass PS Poll frames, if PROMISC_IN_BSS is not set then only
1486 * those addressed to this station. 1486 * those addressed to this station.
1487 *
1488 * @FIF_PROBE_REQ: pass probe request frames
1487 */ 1489 */
1488enum ieee80211_filter_flags { 1490enum ieee80211_filter_flags {
1489 FIF_PROMISC_IN_BSS = 1<<0, 1491 FIF_PROMISC_IN_BSS = 1<<0,
@@ -1494,6 +1496,7 @@ enum ieee80211_filter_flags {
1494 FIF_CONTROL = 1<<5, 1496 FIF_CONTROL = 1<<5,
1495 FIF_OTHER_BSS = 1<<6, 1497 FIF_OTHER_BSS = 1<<6,
1496 FIF_PSPOLL = 1<<7, 1498 FIF_PSPOLL = 1<<7,
1499 FIF_PROBE_REQ = 1<<8,
1497}; 1500};
1498 1501
1499/** 1502/**
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index ecf9b7166ed1..18bd0e550600 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -329,7 +329,8 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
329 STATION_INFO_TX_PACKETS | 329 STATION_INFO_TX_PACKETS |
330 STATION_INFO_TX_RETRIES | 330 STATION_INFO_TX_RETRIES |
331 STATION_INFO_TX_FAILED | 331 STATION_INFO_TX_FAILED |
332 STATION_INFO_TX_BITRATE; 332 STATION_INFO_TX_BITRATE |
333 STATION_INFO_RX_DROP_MISC;
333 334
334 sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); 335 sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx);
335 sinfo->rx_bytes = sta->rx_bytes; 336 sinfo->rx_bytes = sta->rx_bytes;
@@ -338,6 +339,7 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
338 sinfo->tx_packets = sta->tx_packets; 339 sinfo->tx_packets = sta->tx_packets;
339 sinfo->tx_retries = sta->tx_retry_count; 340 sinfo->tx_retries = sta->tx_retry_count;
340 sinfo->tx_failed = sta->tx_retry_failed; 341 sinfo->tx_failed = sta->tx_retry_failed;
342 sinfo->rx_dropped_misc = sta->rx_dropped;
341 343
342 if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) || 344 if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) ||
343 (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) { 345 (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) {
@@ -1602,6 +1604,23 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
1602 return 0; 1604 return 0;
1603} 1605}
1604 1606
1607static void ieee80211_mgmt_frame_register(struct wiphy *wiphy,
1608 struct net_device *dev,
1609 u16 frame_type, bool reg)
1610{
1611 struct ieee80211_local *local = wiphy_priv(wiphy);
1612
1613 if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ))
1614 return;
1615
1616 if (reg)
1617 local->probe_req_reg++;
1618 else
1619 local->probe_req_reg--;
1620
1621 ieee80211_queue_work(&local->hw, &local->reconfig_filter);
1622}
1623
1605struct cfg80211_ops mac80211_config_ops = { 1624struct cfg80211_ops mac80211_config_ops = {
1606 .add_virtual_intf = ieee80211_add_iface, 1625 .add_virtual_intf = ieee80211_add_iface,
1607 .del_virtual_intf = ieee80211_del_iface, 1626 .del_virtual_intf = ieee80211_del_iface,
@@ -1653,4 +1672,5 @@ struct cfg80211_ops mac80211_config_ops = {
1653 .cancel_remain_on_channel = ieee80211_cancel_remain_on_channel, 1672 .cancel_remain_on_channel = ieee80211_cancel_remain_on_channel,
1654 .mgmt_tx = ieee80211_mgmt_tx, 1673 .mgmt_tx = ieee80211_mgmt_tx,
1655 .set_cqm_rssi_config = ieee80211_set_cqm_rssi_config, 1674 .set_cqm_rssi_config = ieee80211_set_cqm_rssi_config,
1675 .mgmt_frame_register = ieee80211_mgmt_frame_register,
1656}; 1676};
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
index 4214bb6e12fc..75d679d75e63 100644
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -291,6 +291,8 @@ void ieee80211_request_smps(struct ieee80211_vif *vif,
291 if (WARN_ON(smps_mode == IEEE80211_SMPS_OFF)) 291 if (WARN_ON(smps_mode == IEEE80211_SMPS_OFF))
292 smps_mode = IEEE80211_SMPS_AUTOMATIC; 292 smps_mode = IEEE80211_SMPS_AUTOMATIC;
293 293
294 sdata->u.mgd.driver_smps_mode = smps_mode;
295
294 ieee80211_queue_work(&sdata->local->hw, 296 ieee80211_queue_work(&sdata->local->hw,
295 &sdata->u.mgd.request_smps_work); 297 &sdata->u.mgd.request_smps_work);
296} 298}
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index f0610fa4fbe0..b80c38689927 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -707,7 +707,9 @@ struct ieee80211_local {
707 int open_count; 707 int open_count;
708 int monitors, cooked_mntrs; 708 int monitors, cooked_mntrs;
709 /* number of interfaces with corresponding FIF_ flags */ 709 /* number of interfaces with corresponding FIF_ flags */
710 int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll; 710 int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll,
711 fif_probe_req;
712 int probe_req_reg;
711 unsigned int filter_flags; /* FIF_* */ 713 unsigned int filter_flags; /* FIF_* */
712 714
713 bool wiphy_ciphers_allocated; 715 bool wiphy_ciphers_allocated;
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index e99d1b60557c..f9163b12c7f1 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -280,8 +280,11 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
280 ieee80211_start_mesh(sdata); 280 ieee80211_start_mesh(sdata);
281 } else if (sdata->vif.type == NL80211_IFTYPE_AP) { 281 } else if (sdata->vif.type == NL80211_IFTYPE_AP) {
282 local->fif_pspoll++; 282 local->fif_pspoll++;
283 local->fif_probe_req++;
283 284
284 ieee80211_configure_filter(local); 285 ieee80211_configure_filter(local);
286 } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
287 local->fif_probe_req++;
285 } 288 }
286 289
287 changed |= ieee80211_reset_erp_info(sdata); 290 changed |= ieee80211_reset_erp_info(sdata);
@@ -428,8 +431,12 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
428 if (sdata->flags & IEEE80211_SDATA_PROMISC) 431 if (sdata->flags & IEEE80211_SDATA_PROMISC)
429 atomic_dec(&local->iff_promiscs); 432 atomic_dec(&local->iff_promiscs);
430 433
431 if (sdata->vif.type == NL80211_IFTYPE_AP) 434 if (sdata->vif.type == NL80211_IFTYPE_AP) {
432 local->fif_pspoll--; 435 local->fif_pspoll--;
436 local->fif_probe_req--;
437 } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
438 local->fif_probe_req--;
439 }
433 440
434 netif_addr_lock_bh(sdata->dev); 441 netif_addr_lock_bh(sdata->dev);
435 spin_lock_bh(&local->filter_lock); 442 spin_lock_bh(&local->filter_lock);
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index eb0f59977676..22bc42b18991 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -54,6 +54,9 @@ void ieee80211_configure_filter(struct ieee80211_local *local)
54 if (local->monitors || local->scanning) 54 if (local->monitors || local->scanning)
55 new_flags |= FIF_BCN_PRBRESP_PROMISC; 55 new_flags |= FIF_BCN_PRBRESP_PROMISC;
56 56
57 if (local->fif_probe_req || local->probe_req_reg)
58 new_flags |= FIF_PROBE_REQ;
59
57 if (local->fif_fcsfail) 60 if (local->fif_fcsfail)
58 new_flags |= FIF_FCSFAIL; 61 new_flags |= FIF_FCSFAIL;
59 62
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index ea13a80a476c..1c91f0f3c307 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -412,7 +412,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
412 enum plink_event event; 412 enum plink_event event;
413 enum plink_frame_type ftype; 413 enum plink_frame_type ftype;
414 size_t baselen; 414 size_t baselen;
415 bool deactivated; 415 bool deactivated, matches_local = true;
416 u8 ie_len; 416 u8 ie_len;
417 u8 *baseaddr; 417 u8 *baseaddr;
418 __le16 plid, llid, reason; 418 __le16 plid, llid, reason;
@@ -487,6 +487,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
487 /* Now we will figure out the appropriate event... */ 487 /* Now we will figure out the appropriate event... */
488 event = PLINK_UNDEFINED; 488 event = PLINK_UNDEFINED;
489 if (ftype != PLINK_CLOSE && (!mesh_matches_local(&elems, sdata))) { 489 if (ftype != PLINK_CLOSE && (!mesh_matches_local(&elems, sdata))) {
490 matches_local = false;
490 switch (ftype) { 491 switch (ftype) {
491 case PLINK_OPEN: 492 case PLINK_OPEN:
492 event = OPN_RJCT; 493 event = OPN_RJCT;
@@ -498,7 +499,15 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
498 /* avoid warning */ 499 /* avoid warning */
499 break; 500 break;
500 } 501 }
501 spin_lock_bh(&sta->lock); 502 }
503
504 if (!sta && !matches_local) {
505 rcu_read_unlock();
506 reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION);
507 llid = 0;
508 mesh_plink_frame_tx(sdata, PLINK_CLOSE, mgmt->sa, llid,
509 plid, reason);
510 return;
502 } else if (!sta) { 511 } else if (!sta) {
503 /* ftype == PLINK_OPEN */ 512 /* ftype == PLINK_OPEN */
504 u32 rates; 513 u32 rates;
@@ -522,7 +531,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
522 } 531 }
523 event = OPN_ACPT; 532 event = OPN_ACPT;
524 spin_lock_bh(&sta->lock); 533 spin_lock_bh(&sta->lock);
525 } else { 534 } else if (matches_local) {
526 spin_lock_bh(&sta->lock); 535 spin_lock_bh(&sta->lock);
527 switch (ftype) { 536 switch (ftype) {
528 case PLINK_OPEN: 537 case PLINK_OPEN:
@@ -564,6 +573,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
564 rcu_read_unlock(); 573 rcu_read_unlock();
565 return; 574 return;
566 } 575 }
576 } else {
577 spin_lock_bh(&sta->lock);
567 } 578 }
568 579
569 mpl_dbg("Mesh plink (peer, state, llid, plid, event): %pM %s %d %d %d\n", 580 mpl_dbg("Mesh plink (peer, state, llid, plid, event): %pM %s %d %d %d\n",
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 5695c94c49aa..a3a9421555af 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1864,10 +1864,12 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
1864 1864
1865 else if (ifmgd->probe_send_count < IEEE80211_MAX_PROBE_TRIES) { 1865 else if (ifmgd->probe_send_count < IEEE80211_MAX_PROBE_TRIES) {
1866#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 1866#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
1867 printk(KERN_DEBUG "No probe response from AP %pM" 1867 wiphy_debug(local->hw.wiphy,
1868 " after %dms, try %d\n", bssid, 1868 "%s: No probe response from AP %pM"
1869 (1000 * IEEE80211_PROBE_WAIT)/HZ, 1869 " after %dms, try %d\n",
1870 ifmgd->probe_send_count); 1870 sdata->name,
1871 bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ,
1872 ifmgd->probe_send_count);
1871#endif 1873#endif
1872 ieee80211_mgd_probe_ap_send(sdata); 1874 ieee80211_mgd_probe_ap_send(sdata);
1873 } else { 1875 } else {
@@ -1877,9 +1879,11 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
1877 */ 1879 */
1878 ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL | 1880 ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL |
1879 IEEE80211_STA_BEACON_POLL); 1881 IEEE80211_STA_BEACON_POLL);
1880 printk(KERN_DEBUG "No probe response from AP %pM" 1882 wiphy_debug(local->hw.wiphy,
1881 " after %dms, disconnecting.\n", 1883 "%s: No probe response from AP %pM"
1882 bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ); 1884 " after %dms, disconnecting.\n",
1885 sdata->name,
1886 bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ);
1883 ieee80211_set_disassoc(sdata, true, true); 1887 ieee80211_set_disassoc(sdata, true, true);
1884 mutex_unlock(&ifmgd->mtx); 1888 mutex_unlock(&ifmgd->mtx);
1885 mutex_lock(&local->mtx); 1889 mutex_lock(&local->mtx);
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index c5b465904e3b..2a18d6602d4a 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -397,8 +397,9 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband,
397 !(info->flags & IEEE80211_TX_STAT_AMPDU)) 397 !(info->flags & IEEE80211_TX_STAT_AMPDU))
398 return; 398 return;
399 399
400 if (!info->status.ampdu_len) { 400 if (!(info->flags & IEEE80211_TX_STAT_AMPDU)) {
401 info->status.ampdu_ack_len = 1; 401 info->status.ampdu_ack_len =
402 (info->flags & IEEE80211_TX_STAT_ACK ? 1 : 0);
402 info->status.ampdu_len = 1; 403 info->status.ampdu_len = 1;
403 } 404 }
404 405
@@ -426,7 +427,7 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband,
426 group = minstrel_ht_get_group_idx(&ar[i]); 427 group = minstrel_ht_get_group_idx(&ar[i]);
427 rate = &mi->groups[group].rates[ar[i].idx % 8]; 428 rate = &mi->groups[group].rates[ar[i].idx % 8];
428 429
429 if (last && (info->flags & IEEE80211_TX_STAT_ACK)) 430 if (last)
430 rate->success += info->status.ampdu_ack_len; 431 rate->success += info->status.ampdu_ack_len;
431 432
432 rate->attempts += ar[i].count * info->status.ampdu_len; 433 rate->attempts += ar[i].count * info->status.ampdu_len;
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index b67221def584..902b03ee8f60 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -622,6 +622,26 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw,
622 tid_agg_rx->buf_size; 622 tid_agg_rx->buf_size;
623 } 623 }
624 624
625 /*
626 * Disable the reorder release timer for now.
627 *
628 * The current implementation lacks a proper locking scheme
629 * which would protect vital statistic and debug counters
630 * from being updated by two different but concurrent BHs.
631 *
632 * More information about the topic is available from:
633 * - thread: http://marc.info/?t=128635927000001
634 *
635 * What was wrong:
636 * => http://marc.info/?l=linux-wireless&m=128636170811964
637 * "Basically the thing is that until your patch, the data
638 * in the struct didn't actually need locking because it
639 * was accessed by the RX path only which is not concurrent."
640 *
641 * List of what needs to be fixed:
642 * => http://marc.info/?l=linux-wireless&m=128656352920957
643 *
644
625 if (tid_agg_rx->stored_mpdu_num) { 645 if (tid_agg_rx->stored_mpdu_num) {
626 j = index = seq_sub(tid_agg_rx->head_seq_num, 646 j = index = seq_sub(tid_agg_rx->head_seq_num,
627 tid_agg_rx->ssn) % tid_agg_rx->buf_size; 647 tid_agg_rx->ssn) % tid_agg_rx->buf_size;
@@ -640,6 +660,10 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw,
640 } else { 660 } else {
641 del_timer(&tid_agg_rx->reorder_timer); 661 del_timer(&tid_agg_rx->reorder_timer);
642 } 662 }
663 */
664
665set_release_timer:
666 return;
643} 667}
644 668
645/* 669/*
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index f27484c22b9f..2ff6d1e3ed21 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -222,7 +222,7 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local,
222 struct ieee80211_key *key) 222 struct ieee80211_key *key)
223{ 223{
224 u32 klen; 224 u32 klen;
225 u8 *rc4key; 225 u8 rc4key[3 + WLAN_KEY_LEN_WEP104];
226 u8 keyidx; 226 u8 keyidx;
227 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 227 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
228 unsigned int hdrlen; 228 unsigned int hdrlen;
@@ -245,10 +245,6 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local,
245 245
246 klen = 3 + key->conf.keylen; 246 klen = 3 + key->conf.keylen;
247 247
248 rc4key = kmalloc(klen, GFP_ATOMIC);
249 if (!rc4key)
250 return -1;
251
252 /* Prepend 24-bit IV to RC4 key */ 248 /* Prepend 24-bit IV to RC4 key */
253 memcpy(rc4key, skb->data + hdrlen, 3); 249 memcpy(rc4key, skb->data + hdrlen, 3);
254 250
@@ -260,8 +256,6 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local,
260 len)) 256 len))
261 ret = -1; 257 ret = -1;
262 258
263 kfree(rc4key);
264
265 /* Trim ICV */ 259 /* Trim ICV */
266 skb_trim(skb, skb->len - WEP_ICV_LEN); 260 skb_trim(skb, skb->len - WEP_ICV_LEN);
267 261
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 1684ad91763c..9c21ebf9780e 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -178,10 +178,26 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
178 char *newname) 178 char *newname)
179{ 179{
180 struct cfg80211_registered_device *rdev2; 180 struct cfg80211_registered_device *rdev2;
181 int result; 181 int wiphy_idx, taken = -1, result, digits;
182 182
183 assert_cfg80211_lock(); 183 assert_cfg80211_lock();
184 184
185 /* prohibit calling the thing phy%d when %d is not its number */
186 sscanf(newname, PHY_NAME "%d%n", &wiphy_idx, &taken);
187 if (taken == strlen(newname) && wiphy_idx != rdev->wiphy_idx) {
188 /* count number of places needed to print wiphy_idx */
189 digits = 1;
190 while (wiphy_idx /= 10)
191 digits++;
192 /*
193 * deny the name if it is phy<idx> where <idx> is printed
194 * without leading zeroes. taken == strlen(newname) here
195 */
196 if (taken == strlen(PHY_NAME) + digits)
197 return -EINVAL;
198 }
199
200
185 /* Ignore nop renames */ 201 /* Ignore nop renames */
186 if (strcmp(newname, dev_name(&rdev->wiphy.dev)) == 0) 202 if (strcmp(newname, dev_name(&rdev->wiphy.dev)) == 0)
187 return 0; 203 return 0;
@@ -189,7 +205,7 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
189 /* Ensure another device does not already have this name. */ 205 /* Ensure another device does not already have this name. */
190 list_for_each_entry(rdev2, &cfg80211_rdev_list, list) 206 list_for_each_entry(rdev2, &cfg80211_rdev_list, list)
191 if (strcmp(newname, dev_name(&rdev2->wiphy.dev)) == 0) 207 if (strcmp(newname, dev_name(&rdev2->wiphy.dev)) == 0)
192 return -EEXIST; 208 return -EINVAL;
193 209
194 result = device_rename(&rdev->wiphy.dev, newname); 210 result = device_rename(&rdev->wiphy.dev, newname);
195 if (result) 211 if (result)
@@ -304,11 +320,9 @@ static void cfg80211_event_work(struct work_struct *work)
304struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) 320struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
305{ 321{
306 static int wiphy_counter; 322 static int wiphy_counter;
307 int i; 323
308 struct cfg80211_registered_device *rdev, *rdev2; 324 struct cfg80211_registered_device *rdev;
309 int alloc_size; 325 int alloc_size;
310 char nname[IFNAMSIZ + 1];
311 bool found = false;
312 326
313 WARN_ON(ops->add_key && (!ops->del_key || !ops->set_default_key)); 327 WARN_ON(ops->add_key && (!ops->del_key || !ops->set_default_key));
314 WARN_ON(ops->auth && (!ops->assoc || !ops->deauth || !ops->disassoc)); 328 WARN_ON(ops->auth && (!ops->assoc || !ops->deauth || !ops->disassoc));
@@ -332,37 +346,17 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
332 346
333 if (unlikely(!wiphy_idx_valid(rdev->wiphy_idx))) { 347 if (unlikely(!wiphy_idx_valid(rdev->wiphy_idx))) {
334 wiphy_counter--; 348 wiphy_counter--;
335 goto too_many_devs;
336 }
337
338 /* 64k wiphy devices is enough for anyone! */
339 for (i = 0; i < 0xFFFF; i++) {
340 found = false;
341 snprintf(nname, sizeof(nname)-1, PHY_NAME "%d", i);
342 nname[sizeof(nname)-1] = 0;
343 list_for_each_entry(rdev2, &cfg80211_rdev_list, list)
344 if (strcmp(nname, dev_name(&rdev2->wiphy.dev)) == 0) {
345 found = true;
346 break;
347 }
348
349 if (!found)
350 break;
351 }
352
353 if (unlikely(found)) {
354too_many_devs:
355 mutex_unlock(&cfg80211_mutex); 349 mutex_unlock(&cfg80211_mutex);
356 /* ugh, too many devices already! */ 350 /* ugh, wrapped! */
357 kfree(rdev); 351 kfree(rdev);
358 return NULL; 352 return NULL;
359 } 353 }
360 354
361 /* give it a proper name */
362 dev_set_name(&rdev->wiphy.dev, "%s", nname);
363
364 mutex_unlock(&cfg80211_mutex); 355 mutex_unlock(&cfg80211_mutex);
365 356
357 /* give it a proper name */
358 dev_set_name(&rdev->wiphy.dev, PHY_NAME "%d", rdev->wiphy_idx);
359
366 mutex_init(&rdev->mtx); 360 mutex_init(&rdev->mtx);
367 mutex_init(&rdev->devlist_mtx); 361 mutex_init(&rdev->devlist_mtx);
368 INIT_LIST_HEAD(&rdev->netdev_list); 362 INIT_LIST_HEAD(&rdev->netdev_list);
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index caf11a427507..26838d903b9a 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -764,6 +764,8 @@ int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid,
764 u16 frame_type, const u8 *match_data, 764 u16 frame_type, const u8 *match_data,
765 int match_len) 765 int match_len)
766{ 766{
767 struct wiphy *wiphy = wdev->wiphy;
768 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
767 struct cfg80211_mgmt_registration *reg, *nreg; 769 struct cfg80211_mgmt_registration *reg, *nreg;
768 int err = 0; 770 int err = 0;
769 u16 mgmt_type; 771 u16 mgmt_type;
@@ -810,22 +812,37 @@ int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid,
810 nreg->frame_type = cpu_to_le16(frame_type); 812 nreg->frame_type = cpu_to_le16(frame_type);
811 list_add(&nreg->list, &wdev->mgmt_registrations); 813 list_add(&nreg->list, &wdev->mgmt_registrations);
812 814
815 if (rdev->ops->mgmt_frame_register)
816 rdev->ops->mgmt_frame_register(wiphy, wdev->netdev,
817 frame_type, true);
818
813 out: 819 out:
814 spin_unlock_bh(&wdev->mgmt_registrations_lock); 820 spin_unlock_bh(&wdev->mgmt_registrations_lock);
821
815 return err; 822 return err;
816} 823}
817 824
818void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid) 825void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid)
819{ 826{
827 struct wiphy *wiphy = wdev->wiphy;
828 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
820 struct cfg80211_mgmt_registration *reg, *tmp; 829 struct cfg80211_mgmt_registration *reg, *tmp;
821 830
822 spin_lock_bh(&wdev->mgmt_registrations_lock); 831 spin_lock_bh(&wdev->mgmt_registrations_lock);
823 832
824 list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) { 833 list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) {
825 if (reg->nlpid == nlpid) { 834 if (reg->nlpid != nlpid)
826 list_del(&reg->list); 835 continue;
827 kfree(reg); 836
837 if (rdev->ops->mgmt_frame_register) {
838 u16 frame_type = le16_to_cpu(reg->frame_type);
839
840 rdev->ops->mgmt_frame_register(wiphy, wdev->netdev,
841 frame_type, false);
828 } 842 }
843
844 list_del(&reg->list);
845 kfree(reg);
829 } 846 }
830 847
831 spin_unlock_bh(&wdev->mgmt_registrations_lock); 848 spin_unlock_bh(&wdev->mgmt_registrations_lock);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 882dc921103b..c506241f8637 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3153,6 +3153,21 @@ static int nl80211_send_survey(struct sk_buff *msg, u32 pid, u32 seq,
3153 survey->noise); 3153 survey->noise);
3154 if (survey->filled & SURVEY_INFO_IN_USE) 3154 if (survey->filled & SURVEY_INFO_IN_USE)
3155 NLA_PUT_FLAG(msg, NL80211_SURVEY_INFO_IN_USE); 3155 NLA_PUT_FLAG(msg, NL80211_SURVEY_INFO_IN_USE);
3156 if (survey->filled & SURVEY_INFO_CHANNEL_TIME)
3157 NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME,
3158 survey->channel_time);
3159 if (survey->filled & SURVEY_INFO_CHANNEL_TIME_BUSY)
3160 NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY,
3161 survey->channel_time_busy);
3162 if (survey->filled & SURVEY_INFO_CHANNEL_TIME_EXT_BUSY)
3163 NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY,
3164 survey->channel_time_ext_busy);
3165 if (survey->filled & SURVEY_INFO_CHANNEL_TIME_RX)
3166 NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_RX,
3167 survey->channel_time_rx);
3168 if (survey->filled & SURVEY_INFO_CHANNEL_TIME_TX)
3169 NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_TX,
3170 survey->channel_time_tx);
3156 3171
3157 nla_nest_end(msg, infoattr); 3172 nla_nest_end(msg, infoattr);
3158 3173
diff --git a/net/wireless/radiotap.c b/net/wireless/radiotap.c
index c774bc0f155e..dbe35e138e94 100644
--- a/net/wireless/radiotap.c
+++ b/net/wireless/radiotap.c
@@ -201,7 +201,7 @@ int ieee80211_radiotap_iterator_next(
201{ 201{
202 while (1) { 202 while (1) {
203 int hit = 0; 203 int hit = 0;
204 int pad, align, size, subns, vnslen; 204 int pad, align, size, subns;
205 uint32_t oui; 205 uint32_t oui;
206 206
207 /* if no more EXT bits, that's it */ 207 /* if no more EXT bits, that's it */
@@ -261,6 +261,27 @@ int ieee80211_radiotap_iterator_next(
261 if (pad) 261 if (pad)
262 iterator->_arg += align - pad; 262 iterator->_arg += align - pad;
263 263
264 if (iterator->_arg_index % 32 == IEEE80211_RADIOTAP_VENDOR_NAMESPACE) {
265 int vnslen;
266
267 if ((unsigned long)iterator->_arg + size -
268 (unsigned long)iterator->_rtheader >
269 (unsigned long)iterator->_max_length)
270 return -EINVAL;
271
272 oui = (*iterator->_arg << 16) |
273 (*(iterator->_arg + 1) << 8) |
274 *(iterator->_arg + 2);
275 subns = *(iterator->_arg + 3);
276
277 find_ns(iterator, oui, subns);
278
279 vnslen = get_unaligned_le16(iterator->_arg + 4);
280 iterator->_next_ns_data = iterator->_arg + size + vnslen;
281 if (!iterator->current_namespace)
282 size += vnslen;
283 }
284
264 /* 285 /*
265 * this is what we will return to user, but we need to 286 * this is what we will return to user, but we need to
266 * move on first so next call has something fresh to test 287 * move on first so next call has something fresh to test
@@ -287,40 +308,25 @@ int ieee80211_radiotap_iterator_next(
287 /* these special ones are valid in each bitmap word */ 308 /* these special ones are valid in each bitmap word */
288 switch (iterator->_arg_index % 32) { 309 switch (iterator->_arg_index % 32) {
289 case IEEE80211_RADIOTAP_VENDOR_NAMESPACE: 310 case IEEE80211_RADIOTAP_VENDOR_NAMESPACE:
290 iterator->_bitmap_shifter >>= 1;
291 iterator->_arg_index++;
292
293 iterator->_reset_on_ext = 1; 311 iterator->_reset_on_ext = 1;
294 312
295 vnslen = get_unaligned_le16(iterator->this_arg + 4);
296 iterator->_next_ns_data = iterator->_arg + vnslen;
297 oui = (*iterator->this_arg << 16) |
298 (*(iterator->this_arg + 1) << 8) |
299 *(iterator->this_arg + 2);
300 subns = *(iterator->this_arg + 3);
301
302 find_ns(iterator, oui, subns);
303
304 iterator->is_radiotap_ns = 0; 313 iterator->is_radiotap_ns = 0;
305 /* allow parsers to show this information */ 314 /*
315 * If parser didn't register this vendor
316 * namespace with us, allow it to show it
317 * as 'raw. Do do that, set argument index
318 * to vendor namespace.
319 */
306 iterator->this_arg_index = 320 iterator->this_arg_index =
307 IEEE80211_RADIOTAP_VENDOR_NAMESPACE; 321 IEEE80211_RADIOTAP_VENDOR_NAMESPACE;
308 iterator->this_arg_size += vnslen; 322 if (!iterator->current_namespace)
309 if ((unsigned long)iterator->this_arg + 323 hit = 1;
310 iterator->this_arg_size - 324 goto next_entry;
311 (unsigned long)iterator->_rtheader >
312 (unsigned long)(unsigned long)iterator->_max_length)
313 return -EINVAL;
314 hit = 1;
315 break;
316 case IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE: 325 case IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE:
317 iterator->_bitmap_shifter >>= 1;
318 iterator->_arg_index++;
319
320 iterator->_reset_on_ext = 1; 326 iterator->_reset_on_ext = 1;
321 iterator->current_namespace = &radiotap_ns; 327 iterator->current_namespace = &radiotap_ns;
322 iterator->is_radiotap_ns = 1; 328 iterator->is_radiotap_ns = 1;
323 break; 329 goto next_entry;
324 case IEEE80211_RADIOTAP_EXT: 330 case IEEE80211_RADIOTAP_EXT:
325 /* 331 /*
326 * bit 31 was set, there is more 332 * bit 31 was set, there is more
diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c
index 74a9e3cce452..4294fa22bb2d 100644
--- a/net/wireless/sysfs.c
+++ b/net/wireless/sysfs.c
@@ -35,6 +35,14 @@ SHOW_FMT(index, "%d", wiphy_idx);
35SHOW_FMT(macaddress, "%pM", wiphy.perm_addr); 35SHOW_FMT(macaddress, "%pM", wiphy.perm_addr);
36SHOW_FMT(address_mask, "%pM", wiphy.addr_mask); 36SHOW_FMT(address_mask, "%pM", wiphy.addr_mask);
37 37
38static ssize_t name_show(struct device *dev,
39 struct device_attribute *attr,
40 char *buf) {
41 struct wiphy *wiphy = &dev_to_rdev(dev)->wiphy;
42 return sprintf(buf, "%s\n", dev_name(&wiphy->dev));
43}
44
45
38static ssize_t addresses_show(struct device *dev, 46static ssize_t addresses_show(struct device *dev,
39 struct device_attribute *attr, 47 struct device_attribute *attr,
40 char *buf) 48 char *buf)
@@ -57,6 +65,7 @@ static struct device_attribute ieee80211_dev_attrs[] = {
57 __ATTR_RO(macaddress), 65 __ATTR_RO(macaddress),
58 __ATTR_RO(address_mask), 66 __ATTR_RO(address_mask),
59 __ATTR_RO(addresses), 67 __ATTR_RO(addresses),
68 __ATTR_RO(name),
60 {} 69 {}
61}; 70};
62 71
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 6002265289c6..12222ee6ebf2 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -1366,6 +1366,10 @@ struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev)
1366 } 1366 }
1367 1367
1368 wstats.qual.updated |= IW_QUAL_NOISE_INVALID; 1368 wstats.qual.updated |= IW_QUAL_NOISE_INVALID;
1369 if (sinfo.filled & STATION_INFO_RX_DROP_MISC)
1370 wstats.discard.misc = sinfo.rx_dropped_misc;
1371 if (sinfo.filled & STATION_INFO_TX_FAILED)
1372 wstats.discard.retries = sinfo.tx_failed;
1369 1373
1370 return &wstats; 1374 return &wstats;
1371} 1375}