]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
authorJohn W. Linville <linville@tuxdriver.com>
Fri, 15 Oct 2010 20:11:56 +0000 (16:11 -0400)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 15 Oct 2010 20:11:56 +0000 (16:11 -0400)
151 files changed:
MAINTAINERS
drivers/net/wireless/Kconfig
drivers/net/wireless/Makefile
drivers/net/wireless/at76c50x-usb.c
drivers/net/wireless/ath/ath.h
drivers/net/wireless/ath/ath5k/ani.c
drivers/net/wireless/ath/ath5k/ani.h
drivers/net/wireless/ath/ath5k/ath5k.h
drivers/net/wireless/ath/ath5k/base.c
drivers/net/wireless/ath/ath5k/debug.c
drivers/net/wireless/ath/ath5k/debug.h
drivers/net/wireless/ath/ath5k/pcu.c
drivers/net/wireless/ath/ath5k/phy.c
drivers/net/wireless/ath/ath9k/ani.c
drivers/net/wireless/ath/ath9k/ani.h
drivers/net/wireless/ath/ath9k/ar9003_2p0_initvals.h [deleted file]
drivers/net/wireless/ath/ath9k/ar9003_hw.c
drivers/net/wireless/ath/ath9k/ar9003_phy.c
drivers/net/wireless/ath/ath9k/ath9k.h
drivers/net/wireless/ath/ath9k/beacon.c
drivers/net/wireless/ath/ath9k/debug.c
drivers/net/wireless/ath/ath9k/debug.h
drivers/net/wireless/ath/ath9k/htc_drv_init.c
drivers/net/wireless/ath/ath9k/htc_drv_main.c
drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
drivers/net/wireless/ath/ath9k/hw.c
drivers/net/wireless/ath/ath9k/hw.h
drivers/net/wireless/ath/ath9k/init.c
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/ath/ath9k/rc.c
drivers/net/wireless/ath/ath9k/rc.h
drivers/net/wireless/ath/ath9k/recv.c
drivers/net/wireless/ath/ath9k/reg.h
drivers/net/wireless/ath/ath9k/xmit.c
drivers/net/wireless/ath/carl9170/rx.c
drivers/net/wireless/ath/carl9170/wlan.h
drivers/net/wireless/ath/debug.c
drivers/net/wireless/ath/debug.h
drivers/net/wireless/ath/hw.c
drivers/net/wireless/ath/reg.h
drivers/net/wireless/b43/Makefile
drivers/net/wireless/b43/phy_common.h
drivers/net/wireless/b43/phy_n.c
drivers/net/wireless/b43/phy_n.h
drivers/net/wireless/b43/radio_2055.c [new file with mode: 0644]
drivers/net/wireless/b43/radio_2055.h [new file with mode: 0644]
drivers/net/wireless/b43/radio_2056.c [new file with mode: 0644]
drivers/net/wireless/b43/radio_2056.h [new file with mode: 0644]
drivers/net/wireless/b43/tables_nphy.c
drivers/net/wireless/b43/tables_nphy.h
drivers/net/wireless/iwlwifi/Makefile
drivers/net/wireless/iwlwifi/iwl-1000.c
drivers/net/wireless/iwlwifi/iwl-3945.c
drivers/net/wireless/iwlwifi/iwl-3945.h
drivers/net/wireless/iwlwifi/iwl-4965.c
drivers/net/wireless/iwlwifi/iwl-5000.c
drivers/net/wireless/iwlwifi/iwl-6000.c
drivers/net/wireless/iwlwifi/iwl-agn-calib.c
drivers/net/wireless/iwlwifi/iwl-agn-calib.h [moved from drivers/net/wireless/iwlwifi/iwl-calib.h with 95% similarity]
drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c [new file with mode: 0644]
drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
drivers/net/wireless/iwlwifi/iwl-agn-lib.c
drivers/net/wireless/iwlwifi/iwl-agn-rs.c
drivers/net/wireless/iwlwifi/iwl-agn-rs.h
drivers/net/wireless/iwlwifi/iwl-agn-rx.c
drivers/net/wireless/iwlwifi/iwl-agn-sta.c [new file with mode: 0644]
drivers/net/wireless/iwlwifi/iwl-agn-tt.c
drivers/net/wireless/iwlwifi/iwl-agn-tx.c
drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl-agn.h
drivers/net/wireless/iwlwifi/iwl-commands.h
drivers/net/wireless/iwlwifi/iwl-core.c
drivers/net/wireless/iwlwifi/iwl-core.h
drivers/net/wireless/iwlwifi/iwl-debugfs.c
drivers/net/wireless/iwlwifi/iwl-dev.h
drivers/net/wireless/iwlwifi/iwl-eeprom.c
drivers/net/wireless/iwlwifi/iwl-eeprom.h
drivers/net/wireless/iwlwifi/iwl-helpers.h
drivers/net/wireless/iwlwifi/iwl-rx.c
drivers/net/wireless/iwlwifi/iwl-scan.c
drivers/net/wireless/iwlwifi/iwl-sta.c
drivers/net/wireless/iwlwifi/iwl-sta.h
drivers/net/wireless/iwlwifi/iwl-tx.c
drivers/net/wireless/iwlwifi/iwl3945-base.c
drivers/net/wireless/libertas/if_usb.c
drivers/net/wireless/p54/eeprom.c
drivers/net/wireless/rt2x00/rt2400pci.c
drivers/net/wireless/rt2x00/rt2500pci.c
drivers/net/wireless/rt2x00/rt2800lib.c
drivers/net/wireless/rt2x00/rt2800pci.c
drivers/net/wireless/rt2x00/rt2x00.h
drivers/net/wireless/rt2x00/rt2x00dev.c
drivers/net/wireless/rt2x00/rt2x00lib.h
drivers/net/wireless/rt2x00/rt2x00link.c
drivers/net/wireless/rt2x00/rt2x00pci.c
drivers/net/wireless/rt2x00/rt2x00queue.c
drivers/net/wireless/rt2x00/rt2x00usb.c
drivers/net/wireless/wl1251/Kconfig [new file with mode: 0644]
drivers/net/wireless/wl1251/Makefile [new file with mode: 0644]
drivers/net/wireless/wl1251/acx.c [moved from drivers/net/wireless/wl12xx/wl1251_acx.c with 99% similarity]
drivers/net/wireless/wl1251/acx.h [moved from drivers/net/wireless/wl12xx/wl1251_acx.h with 99% similarity]
drivers/net/wireless/wl1251/boot.c [moved from drivers/net/wireless/wl12xx/wl1251_boot.c with 99% similarity]
drivers/net/wireless/wl1251/boot.h [moved from drivers/net/wireless/wl12xx/wl1251_boot.h with 100% similarity]
drivers/net/wireless/wl1251/cmd.c [moved from drivers/net/wireless/wl12xx/wl1251_cmd.c with 98% similarity]
drivers/net/wireless/wl1251/cmd.h [moved from drivers/net/wireless/wl12xx/wl1251_cmd.h with 100% similarity]
drivers/net/wireless/wl1251/debugfs.c [moved from drivers/net/wireless/wl12xx/wl1251_debugfs.c with 99% similarity]
drivers/net/wireless/wl1251/debugfs.h [moved from drivers/net/wireless/wl12xx/wl1251_debugfs.h with 100% similarity]
drivers/net/wireless/wl1251/event.c [moved from drivers/net/wireless/wl12xx/wl1251_event.c with 97% similarity]
drivers/net/wireless/wl1251/event.h [moved from drivers/net/wireless/wl12xx/wl1251_event.h with 100% similarity]
drivers/net/wireless/wl1251/init.c [moved from drivers/net/wireless/wl12xx/wl1251_init.c with 98% similarity]
drivers/net/wireless/wl1251/init.h [moved from drivers/net/wireless/wl12xx/wl1251_init.h with 100% similarity]
drivers/net/wireless/wl1251/io.c [moved from drivers/net/wireless/wl12xx/wl1251_io.c with 99% similarity]
drivers/net/wireless/wl1251/io.h [moved from drivers/net/wireless/wl12xx/wl1251_io.h with 100% similarity]
drivers/net/wireless/wl1251/main.c [moved from drivers/net/wireless/wl12xx/wl1251_main.c with 99% similarity]
drivers/net/wireless/wl1251/ps.c [moved from drivers/net/wireless/wl12xx/wl1251_ps.c with 97% similarity]
drivers/net/wireless/wl1251/ps.h [moved from drivers/net/wireless/wl12xx/wl1251_ps.h with 97% similarity]
drivers/net/wireless/wl1251/reg.h [moved from drivers/net/wireless/wl12xx/wl1251_reg.h with 100% similarity]
drivers/net/wireless/wl1251/rx.c [moved from drivers/net/wireless/wl12xx/wl1251_rx.c with 97% similarity]
drivers/net/wireless/wl1251/rx.h [moved from drivers/net/wireless/wl12xx/wl1251_rx.h with 100% similarity]
drivers/net/wireless/wl1251/sdio.c [moved from drivers/net/wireless/wl12xx/wl1251_sdio.c with 100% similarity]
drivers/net/wireless/wl1251/spi.c [moved from drivers/net/wireless/wl12xx/wl1251_spi.c with 99% similarity]
drivers/net/wireless/wl1251/spi.h [moved from drivers/net/wireless/wl12xx/wl1251_spi.h with 96% similarity]
drivers/net/wireless/wl1251/tx.c [moved from drivers/net/wireless/wl12xx/wl1251_tx.c with 99% similarity]
drivers/net/wireless/wl1251/tx.h [moved from drivers/net/wireless/wl12xx/wl1251_tx.h with 99% similarity]
drivers/net/wireless/wl1251/wl1251.h [moved from drivers/net/wireless/wl12xx/wl1251.h with 100% similarity]
drivers/net/wireless/wl1251/wl12xx_80211.h [new file with mode: 0644]
drivers/net/wireless/wl12xx/Kconfig
drivers/net/wireless/wl12xx/Makefile
drivers/net/wireless/wl12xx/wl1271_sdio.c
include/linux/ieee80211.h
include/linux/nl80211.h
include/linux/wireless.h
include/net/cfg80211.h
include/net/mac80211.h
net/mac80211/cfg.c
net/mac80211/ht.c
net/mac80211/ieee80211_i.h
net/mac80211/iface.c
net/mac80211/main.c
net/mac80211/mesh_plink.c
net/mac80211/mlme.c
net/mac80211/rc80211_minstrel_ht.c
net/mac80211/rx.c
net/mac80211/wep.c
net/wireless/core.c
net/wireless/mlme.c
net/wireless/nl80211.c
net/wireless/radiotap.c
net/wireless/sysfs.c
net/wireless/wext-compat.c

index c539910b1f76b0314d5d954058449438270f4b34..476fb3a123cafe8651a453552fe1142cdd601f4e 100644 (file)
@@ -6461,8 +6461,7 @@ L:        linux-wireless@vger.kernel.org
 W:     http://wireless.kernel.org
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
 S:     Maintained
-F:     drivers/net/wireless/wl12xx/*
-X:     drivers/net/wireless/wl12xx/wl1271*
+F:     drivers/net/wireless/wl1251/*
 
 WL1271 WIRELESS DRIVER
 M:     Luciano Coelho <luciano.coelho@nokia.com>
index 174e3442d5190df936544854787b919d3e0f4945..4de4410cd38ed7fd34e5d74adc5bba8b77ba3f23 100644 (file)
@@ -279,6 +279,7 @@ source "drivers/net/wireless/libertas/Kconfig"
 source "drivers/net/wireless/orinoco/Kconfig"
 source "drivers/net/wireless/p54/Kconfig"
 source "drivers/net/wireless/rt2x00/Kconfig"
+source "drivers/net/wireless/wl1251/Kconfig"
 source "drivers/net/wireless/wl12xx/Kconfig"
 source "drivers/net/wireless/zd1211rw/Kconfig"
 
index a13a602edb137ab1211eee95fced85aba596225a..06f8ca26c5c17d9006b1ef8bdba3b59e50e1931d 100644 (file)
@@ -49,6 +49,7 @@ obj-$(CONFIG_ATH_COMMON)      += ath/
 
 obj-$(CONFIG_MAC80211_HWSIM)   += mac80211_hwsim.o
 
+obj-$(CONFIG_WL1251)   += wl1251/
 obj-$(CONFIG_WL12XX)   += wl12xx/
 obj-$(CONFIG_WL12XX_PLATFORM_DATA)     += wl12xx/
 
index 91c5f73b5ba33d5d21e98aa138806224d65eadd1..1476314afa8a5dfb2811d4805d36c3eef2602d5b 100644 (file)
@@ -1525,8 +1525,7 @@ static void at76_rx_tasklet(unsigned long param)
 
        if (priv->device_unplugged) {
                at76_dbg(DBG_DEVSTART, "device unplugged");
-               if (urb)
-                       at76_dbg(DBG_DEVSTART, "urb status %d", urb->status);
+               at76_dbg(DBG_DEVSTART, "urb status %d", urb->status);
                return;
        }
 
index cee0191704f513251d083cfdc9a0b78198d5e0c3..501050c0296f10a3e7ea6abb4a45170fffa2b095 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <linux/skbuff.h>
 #include <linux/if_ether.h>
+#include <linux/spinlock.h>
 #include <net/mac80211.h>
 
 /*
@@ -42,6 +43,13 @@ struct ath_ani {
        struct timer_list timer;
 };
 
+struct ath_cycle_counters {
+       u32 cycles;
+       u32 rx_busy;
+       u32 rx_frame;
+       u32 tx_frame;
+};
+
 enum ath_device_state {
        ATH_HW_UNAVAILABLE,
        ATH_HW_INITIALIZED,
@@ -145,6 +153,12 @@ struct ath_common {
        DECLARE_BITMAP(tkip_keymap, ATH_KEYMAX);
        enum ath_crypt_caps crypt_caps;
 
+       unsigned int clockrate;
+
+       spinlock_t cc_lock;
+       struct ath_cycle_counters cc_ani;
+       struct ath_cycle_counters cc_survey;
+
        struct ath_regulatory regulatory;
        const struct ath_ops *ops;
        const struct ath_bus_ops *bus_ops;
@@ -161,5 +175,7 @@ int ath_key_config(struct ath_common *common,
                          struct ieee80211_sta *sta,
                          struct ieee80211_key_conf *key);
 bool ath_hw_keyreset(struct ath_common *common, u16 entry);
+void ath_hw_cycle_counters_update(struct ath_common *common);
+int32_t ath_hw_get_listen_time(struct ath_common *common);
 
 #endif /* ATH_H */
index e4a5f046bba47146135136ea9040a55144c607b5..f1419198a479511f995b9e290b2316b0181bd677 100644 (file)
@@ -355,41 +355,28 @@ ath5k_ani_lower_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as)
 
 
 /**
- * ath5k_hw_ani_get_listen_time() - Calculate time spent listening
+ * ath5k_hw_ani_get_listen_time() - Update counters and return listening time
  *
  * Return an approximation of the time spent "listening" in milliseconds (ms)
- * since the last call of this function by deducting the cycles spent
- * transmitting and receiving from the total cycle count.
- * Save profile count values for debugging/statistics and because we might want
- * to use them later.
- *
- * We assume no one else clears these registers!
+ * since the last call of this function.
+ * Save a snapshot of the counter values for debugging/statistics.
  */
 static int
 ath5k_hw_ani_get_listen_time(struct ath5k_hw *ah, struct ath5k_ani_state *as)
 {
+       struct ath_common *common = ath5k_hw_common(ah);
        int listen;
 
-       /* freeze */
-       ath5k_hw_reg_write(ah, AR5K_MIBC_FMC, AR5K_MIBC);
-       /* read */
-       as->pfc_cycles = ath5k_hw_reg_read(ah, AR5K_PROFCNT_CYCLE);
-       as->pfc_busy = ath5k_hw_reg_read(ah, AR5K_PROFCNT_RXCLR);
-       as->pfc_tx = ath5k_hw_reg_read(ah, AR5K_PROFCNT_TX);
-       as->pfc_rx = ath5k_hw_reg_read(ah, AR5K_PROFCNT_RX);
-       /* clear */
-       ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_TX);
-       ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RX);
-       ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RXCLR);
-       ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_CYCLE);
-       /* un-freeze */
-       ath5k_hw_reg_write(ah, 0, AR5K_MIBC);
-
-       /* TODO: where does 44000 come from? (11g clock rate?) */
-       listen = (as->pfc_cycles - as->pfc_rx - as->pfc_tx) / 44000;
-
-       if (as->pfc_cycles == 0 || listen < 0)
-               return 0;
+       spin_lock_bh(&common->cc_lock);
+
+       ath_hw_cycle_counters_update(common);
+       memcpy(&as->last_cc, &common->cc_ani, sizeof(as->last_cc));
+
+       /* clears common->cc_ani */
+       listen = ath_hw_get_listen_time(common);
+
+       spin_unlock_bh(&common->cc_lock);
+
        return listen;
 }
 
index 55cf26d8522c7d78c1bffe4b7dddb3bb85913317..d0a664039c877c2f4e8f064c499833a9bf0a3883 100644 (file)
@@ -75,10 +75,7 @@ struct ath5k_ani_state {
        unsigned int            cck_errors;
 
        /* debug/statistics only: numbers from last ANI calibration */
-       unsigned int            pfc_tx;
-       unsigned int            pfc_rx;
-       unsigned int            pfc_busy;
-       unsigned int            pfc_cycles;
+       struct ath_cycle_counters last_cc;
        unsigned int            last_listen;
        unsigned int            last_ofdm_errors;
        unsigned int            last_cck_errors;
index 0cba2e315d9af18191b61905e59ba9d8166f8f39..4a367cdb3eb93b93d369f56aa40f81f5d3a95f43 100644 (file)
@@ -1201,7 +1201,7 @@ void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high);
 /* Clock rate related functions */
 unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec);
 unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock);
-unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah);
+void ath5k_hw_set_clockrate(struct ath5k_hw *ah);
 
 /* Queue Control Unit, DFS Control Unit Functions */
 int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue,
index dad726585637146a62b282f6facce9636cfab57b..f1ae75d35d5d4680085c2a9d8148fc2a04233a6b 100644 (file)
@@ -62,6 +62,7 @@
 #include "reg.h"
 #include "debug.h"
 #include "ani.h"
+#include "../debug.h"
 
 static int modparam_nohwcrypt;
 module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
@@ -517,12 +518,14 @@ struct ath_vif_iter_data {
        bool            need_set_hw_addr;
        bool            found_active;
        bool            any_assoc;
+       enum nl80211_iftype opmode;
 };
 
 static void ath_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
 {
        struct ath_vif_iter_data *iter_data = data;
        int i;
+       struct ath5k_vif *avf = (void *)vif->drv_priv;
 
        if (iter_data->hw_macaddr)
                for (i = 0; i < ETH_ALEN; i++)
@@ -539,13 +542,32 @@ static void ath_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
                        iter_data->need_set_hw_addr = false;
 
        if (!iter_data->any_assoc) {
-               struct ath5k_vif *avf = (void *)vif->drv_priv;
                if (avf->assoc)
                        iter_data->any_assoc = true;
        }
+
+       /* Calculate combined mode - when APs are active, operate in AP mode.
+        * Otherwise use the mode of the new interface. This can currently
+        * only deal with combinations of APs and STAs. Only one ad-hoc
+        * interfaces is allowed above.
+        */
+       if (avf->opmode == NL80211_IFTYPE_AP)
+               iter_data->opmode = NL80211_IFTYPE_AP;
+       else
+               if (iter_data->opmode == NL80211_IFTYPE_UNSPECIFIED)
+                       iter_data->opmode = avf->opmode;
 }
 
-void ath5k_update_bssid_mask(struct ath5k_softc *sc, struct ieee80211_vif *vif)
+static void ath_do_set_opmode(struct ath5k_softc *sc)
+{
+       struct ath5k_hw *ah = sc->ah;
+       ath5k_hw_set_opmode(ah, sc->opmode);
+       ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "mode setup opmode %d (%s)\n",
+                 sc->opmode, ath_opmode_to_string(sc->opmode));
+}
+
+void ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc,
+                                       struct ieee80211_vif *vif)
 {
        struct ath_common *common = ath5k_hw_common(sc->ah);
        struct ath_vif_iter_data iter_data;
@@ -558,6 +580,7 @@ void ath5k_update_bssid_mask(struct ath5k_softc *sc, struct ieee80211_vif *vif)
        memset(&iter_data.mask, 0xff, ETH_ALEN);
        iter_data.found_active = false;
        iter_data.need_set_hw_addr = true;
+       iter_data.opmode = NL80211_IFTYPE_UNSPECIFIED;
 
        if (vif)
                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)
                                                   &iter_data);
        memcpy(sc->bssidmask, iter_data.mask, ETH_ALEN);
 
+       sc->opmode = iter_data.opmode;
+       if (sc->opmode == NL80211_IFTYPE_UNSPECIFIED)
+               /* Nothing active, default to station mode */
+               sc->opmode = NL80211_IFTYPE_STATION;
+
+       ath_do_set_opmode(sc);
+
        if (iter_data.need_set_hw_addr && iter_data.found_active)
                ath5k_hw_set_lladdr(sc->ah, iter_data.active_mac);
 
-       ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask);
+       if (ath5k_hw_hasbssidmask(sc->ah))
+               ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask);
 }
 
 static void
@@ -582,15 +613,9 @@ ath5k_mode_setup(struct ath5k_softc *sc, struct ieee80211_vif *vif)
        /* configure rx filter */
        rfilt = sc->filter_flags;
        ath5k_hw_set_rx_filter(ah, rfilt);
-
-       if (ath5k_hw_hasbssidmask(ah))
-               ath5k_update_bssid_mask(sc, vif);
-
-       /* configure operational mode */
-       ath5k_hw_set_opmode(ah, sc->opmode);
-
-       ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "mode setup opmode %d\n", sc->opmode);
        ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt);
+
+       ath5k_update_bssid_mask_and_opmode(sc, vif);
 }
 
 static inline int
@@ -2688,7 +2713,7 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
        SET_IEEE80211_PERM_ADDR(hw, mac);
        memcpy(&sc->lladdr, mac, ETH_ALEN);
        /* All MAC address bits matter for ACKs */
-       ath5k_update_bssid_mask(sc, NULL);
+       ath5k_update_bssid_mask_and_opmode(sc, NULL);
 
        regulatory->current_rd = ah->ah_capabilities.cap_eeprom.ee_regdomain;
        ret = ath_regd_init(regulatory, hw->wiphy, ath5k_reg_notifier);
@@ -2786,7 +2811,6 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
 {
        struct ath5k_softc *sc = hw->priv;
        int ret;
-       struct ath5k_hw *ah = sc->ah;
        struct ath5k_vif *avf = (void *)vif->drv_priv;
 
        mutex_lock(&sc->lock);
@@ -2850,18 +2874,6 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
                        sc->num_adhoc_vifs++;
        }
 
-       /* Set combined mode - when APs are configured, operate in AP mode.
-        * Otherwise use the mode of the new interface. This can currently
-        * only deal with combinations of APs and STAs. Only one ad-hoc
-        * interfaces is allowed above.
-        */
-       if (sc->num_ap_vifs)
-               sc->opmode = NL80211_IFTYPE_AP;
-       else
-               sc->opmode = vif->type;
-
-       ath5k_hw_set_opmode(ah, sc->opmode);
-
        /* Any MAC address is fine, all others are included through the
         * filter.
         */
@@ -2905,7 +2917,7 @@ ath5k_remove_interface(struct ieee80211_hw *hw,
        else if (avf->opmode == NL80211_IFTYPE_ADHOC)
                sc->num_adhoc_vifs--;
 
-       ath5k_update_bssid_mask(sc, NULL);
+       ath5k_update_bssid_mask_and_opmode(sc, NULL);
        mutex_unlock(&sc->lock);
 }
 
@@ -3529,8 +3541,6 @@ ath5k_pci_probe(struct pci_dev *pdev,
        sc->hw = hw;
        sc->pdev = pdev;
 
-       ath5k_debug_init_device(sc);
-
        /*
         * Mark the device as detached to avoid processing
         * interrupts until setup is complete.
@@ -3638,6 +3648,7 @@ ath5k_pci_probe(struct pci_dev *pdev,
                }
        }
 
+       ath5k_debug_init_device(sc);
 
        /* ready to process interrupts */
        __clear_bit(ATH_STAT_INVALID, sc->status);
@@ -3724,8 +3735,6 @@ init_ath5k_pci(void)
 {
        int ret;
 
-       ath5k_debug_init();
-
        ret = pci_register_driver(&ath5k_pci_driver);
        if (ret) {
                printk(KERN_ERR "ath5k_pci: can't register pci driver\n");
@@ -3739,8 +3748,6 @@ static void __exit
 exit_ath5k_pci(void)
 {
        pci_unregister_driver(&ath5k_pci_driver);
-
-       ath5k_debug_finish();
 }
 
 module_init(init_ath5k_pci);
index c2d549f871f936075ed64587690273c5717edd10..42ea5b1bdb122303753af6c16b830707772bbf67 100644 (file)
@@ -60,6 +60,7 @@
 
 #include "base.h"
 #include "debug.h"
+#include "../debug.h"
 
 static unsigned int ath5k_debug;
 module_param_named(debug, ath5k_debug, uint, 0);
@@ -71,8 +72,6 @@ module_param_named(debug, ath5k_debug, uint, 0);
 #include "reg.h"
 #include "ani.h"
 
-static struct dentry *ath5k_global_debugfs;
-
 static int ath5k_debugfs_open(struct inode *inode, struct file *file)
 {
        file->private_data = inode->i_private;
@@ -520,9 +519,10 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf,
        if (filt & AR5K_RX_FILTER_PHYERR_5211)
                snprintf(buf+len, sizeof(buf)-len, " PHYERR-5211");
        if (filt & AR5K_RX_FILTER_RADARERR_5211)
-               len += snprintf(buf+len, sizeof(buf)-len, " RADARERR-5211\n");
-       else
-               len += snprintf(buf+len, sizeof(buf)-len, "\n");
+               len += snprintf(buf+len, sizeof(buf)-len, " RADARERR-5211");
+
+       len += snprintf(buf+len, sizeof(buf)-len, "\nopmode: %s (%d)\n",
+                       ath_opmode_to_string(sc->opmode), sc->opmode);
 
        if (len > sizeof(buf))
                len = sizeof(buf);
@@ -715,20 +715,21 @@ static ssize_t read_file_ani(struct file *file, char __user *user_buf,
        len += snprintf(buf+len, sizeof(buf)-len,
                        "beacon RSSI average:\t%d\n",
                        sc->ah->ah_beacon_rssi_avg.avg);
+
+#define CC_PRINT(_struct, _field) \
+       _struct._field, \
+       _struct.cycles > 0 ? \
+       _struct._field*100/_struct.cycles : 0
+
        len += snprintf(buf+len, sizeof(buf)-len, "profcnt tx\t\t%u\t(%d%%)\n",
-                       as->pfc_tx,
-                       as->pfc_cycles > 0 ?
-                       as->pfc_tx*100/as->pfc_cycles : 0);
+                       CC_PRINT(as->last_cc, tx_frame));
        len += snprintf(buf+len, sizeof(buf)-len, "profcnt rx\t\t%u\t(%d%%)\n",
-                       as->pfc_rx,
-                       as->pfc_cycles > 0 ?
-                       as->pfc_rx*100/as->pfc_cycles : 0);
+                       CC_PRINT(as->last_cc, rx_frame));
        len += snprintf(buf+len, sizeof(buf)-len, "profcnt busy\t\t%u\t(%d%%)\n",
-                       as->pfc_busy,
-                       as->pfc_cycles > 0 ?
-                       as->pfc_busy*100/as->pfc_cycles : 0);
+                       CC_PRINT(as->last_cc, rx_busy));
+#undef CC_PRINT
        len += snprintf(buf+len, sizeof(buf)-len, "profcnt cycles\t\t%u\n",
-                       as->pfc_cycles);
+                       as->last_cc.cycles);
        len += snprintf(buf+len, sizeof(buf)-len,
                        "listen time\t\t%d\tlast: %d\n",
                        as->listen_time, as->last_listen);
@@ -879,21 +880,13 @@ static const struct file_operations fops_queue = {
 };
 
 
-/* init */
-
-void
-ath5k_debug_init(void)
-{
-       ath5k_global_debugfs = debugfs_create_dir("ath5k", NULL);
-}
-
 void
 ath5k_debug_init_device(struct ath5k_softc *sc)
 {
        sc->debug.level = ath5k_debug;
 
-       sc->debug.debugfs_phydir = debugfs_create_dir(wiphy_name(sc->hw->wiphy),
-                               ath5k_global_debugfs);
+       sc->debug.debugfs_phydir = debugfs_create_dir("ath5k",
+                               sc->hw->wiphy->debugfsdir);
 
        sc->debug.debugfs_debug = debugfs_create_file("debug",
                                S_IWUSR | S_IRUSR,
@@ -933,12 +926,6 @@ ath5k_debug_init_device(struct ath5k_softc *sc)
                                &fops_queue);
 }
 
-void
-ath5k_debug_finish(void)
-{
-       debugfs_remove(ath5k_global_debugfs);
-}
-
 void
 ath5k_debug_finish_device(struct ath5k_softc *sc)
 {
index 4f078b134015c2a91680e60f973f18d3065c0c7b..236edbd2507ddaa4a7a26eecadc79aadfe4f9219 100644 (file)
@@ -137,15 +137,9 @@ enum ath5k_debug_level {
                        __func__, __LINE__, ##__VA_ARGS__); \
        } while (0)
 
-void
-ath5k_debug_init(void);
-
 void
 ath5k_debug_init_device(struct ath5k_softc *sc);
 
-void
-ath5k_debug_finish(void);
-
 void
 ath5k_debug_finish_device(struct ath5k_softc *sc);
 
@@ -173,15 +167,9 @@ static inline void __attribute__ ((format (printf, 3, 4)))
 ATH5K_DBG_UNLIMIT(struct ath5k_softc *sc, unsigned int m, const char *fmt, ...)
 {}
 
-static inline void
-ath5k_debug_init(void) {}
-
 static inline void
 ath5k_debug_init_device(struct ath5k_softc *sc) {}
 
-static inline void
-ath5k_debug_finish(void) {}
-
 static inline void
 ath5k_debug_finish_device(struct ath5k_softc *sc) {}
 
index 095d30b50ec7edbb5d82b77e188605d3a458d291..074b4c644399c8f5f3790a1d6ff0f8be9f8b2ccc 100644 (file)
@@ -207,7 +207,8 @@ static int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout)
  */
 unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec)
 {
-       return usec * ath5k_hw_get_clockrate(ah);
+       struct ath_common *common = ath5k_hw_common(ah);
+       return usec * common->clockrate;
 }
 
 /**
@@ -216,17 +217,19 @@ unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec)
  */
 unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock)
 {
-       return clock / ath5k_hw_get_clockrate(ah);
+       struct ath_common *common = ath5k_hw_common(ah);
+       return clock / common->clockrate;
 }
 
 /**
- * ath5k_hw_get_clockrate - Get the clock rate for current mode
+ * ath5k_hw_set_clockrate - Set common->clockrate for the current channel
  *
  * @ah: The &struct ath5k_hw
  */
-unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah)
+void ath5k_hw_set_clockrate(struct ath5k_hw *ah)
 {
        struct ieee80211_channel *channel = ah->ah_current_channel;
+       struct ath_common *common = ath5k_hw_common(ah);
        int clock;
 
        if (channel->hw_value & CHANNEL_5GHZ)
@@ -240,7 +243,7 @@ unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah)
        if (channel->hw_value & CHANNEL_TURBO)
                clock *= 2;
 
-       return clock;
+       common->clockrate = clock;
 }
 
 /**
index 61da913e7c8fb05a7492ffefc7be9b06b4fc0662..219367884e640a60a99a99eba59478aaba9bc1da 100644 (file)
@@ -1093,6 +1093,7 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel)
 
        ah->ah_current_channel = channel;
        ah->ah_turbo = channel->hw_value == CHANNEL_T ? true : false;
+       ath5k_hw_set_clockrate(ah);
 
        return 0;
 }
index f2a907b4acb80dfc178829de9e16e467939ba2a8..63ccb39cdcd4abc42717ea4bccc5c442c6c97f39 100644 (file)
@@ -465,40 +465,6 @@ static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah)
                ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel - 1);
 }
 
-static u8 ath9k_hw_chan_2_clockrate_mhz(struct ath_hw *ah)
-{
-       struct ath9k_channel *chan = ah->curchan;
-       struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
-       u8 clockrate; /* in MHz */
-
-       if (!ah->curchan) /* should really check for CCK instead */
-               clockrate = ATH9K_CLOCK_RATE_CCK;
-       else if (conf->channel->band == IEEE80211_BAND_2GHZ)
-               clockrate = ATH9K_CLOCK_RATE_2GHZ_OFDM;
-       else if (IS_CHAN_A_FAST_CLOCK(ah, chan))
-               clockrate = ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM;
-       else
-               clockrate = ATH9K_CLOCK_RATE_5GHZ_OFDM;
-
-       if (conf_is_ht40(conf))
-               return clockrate * 2;
-
-       return clockrate;
-}
-
-static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah)
-{
-       int32_t listen_time;
-       int32_t clock_rate;
-
-       ath9k_hw_update_cycle_counters(ah);
-       clock_rate = ath9k_hw_chan_2_clockrate_mhz(ah) * 1000;
-       listen_time = ah->listen_time / clock_rate;
-       ah->listen_time = 0;
-
-       return listen_time;
-}
-
 static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
 {
        struct ar5416AniState *aniState;
@@ -667,7 +633,7 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning)
        REGWRITE_BUFFER_FLUSH(ah);
 }
 
-static void ath9k_hw_ani_read_counters(struct ath_hw *ah)
+static bool ath9k_hw_ani_read_counters(struct ath_hw *ah)
 {
        struct ath_common *common = ath9k_hw_common(ah);
        struct ar5416AniState *aniState = &ah->curchan->ani;
@@ -677,11 +643,13 @@ static void ath9k_hw_ani_read_counters(struct ath_hw *ah)
        u32 phyCnt1, phyCnt2;
        int32_t listenTime;
 
-       listenTime = ath9k_hw_ani_get_listen_time(ah);
-       if (listenTime < 0) {
+       ath_hw_cycle_counters_update(common);
+       listenTime = ath_hw_get_listen_time(common);
+
+       if (listenTime <= 0) {
                ah->stats.ast_ani_lneg++;
                ath9k_ani_restart(ah);
-               return;
+               return false;
        }
 
        if (!use_new_ani(ah)) {
@@ -696,7 +664,7 @@ static void ath9k_hw_ani_read_counters(struct ath_hw *ah)
        phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
        phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
 
-       if (use_new_ani(ah) && (phyCnt1 < ofdm_base || phyCnt2 < cck_base)) {
+       if (!use_new_ani(ah) && (phyCnt1 < ofdm_base || phyCnt2 < cck_base)) {
                if (phyCnt1 < ofdm_base) {
                        ath_print(common, ATH_DBG_ANI,
                                  "phyCnt1 0x%x, resetting "
@@ -715,7 +683,7 @@ static void ath9k_hw_ani_read_counters(struct ath_hw *ah)
                        REG_WRITE(ah, AR_PHY_ERR_MASK_2,
                                  AR_PHY_ERR_CCK_TIMING);
                }
-               return;
+               return false;
        }
 
        ofdmPhyErrCnt = phyCnt1 - ofdm_base;
@@ -727,7 +695,7 @@ static void ath9k_hw_ani_read_counters(struct ath_hw *ah)
        ah->stats.ast_ani_cckerrs +=
                cckPhyErrCnt - aniState->cckPhyErrCount;
        aniState->cckPhyErrCount = cckPhyErrCnt;
-
+       return true;
 }
 
 void 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)
        if (WARN_ON(!aniState))
                return;
 
-       ath9k_hw_ani_read_counters(ah);
+       if (!ath9k_hw_ani_read_counters(ah))
+               return;
 
        ofdmPhyErrRate = aniState->ofdmPhyErrCount * 1000 /
                         aniState->listenTime;
@@ -818,54 +787,6 @@ void ath9k_hw_disable_mib_counters(struct ath_hw *ah)
 }
 EXPORT_SYMBOL(ath9k_hw_disable_mib_counters);
 
-void ath9k_hw_update_cycle_counters(struct ath_hw *ah)
-{
-       struct ath_cycle_counters cc;
-       bool clear;
-
-       memcpy(&cc, &ah->cc, sizeof(cc));
-
-       /* freeze counters */
-       REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC);
-
-       ah->cc.cycles = REG_READ(ah, AR_CCCNT);
-       if (ah->cc.cycles < cc.cycles) {
-               clear = true;
-               goto skip;
-       }
-
-       ah->cc.rx_clear = REG_READ(ah, AR_RCCNT);
-       ah->cc.rx_frame = REG_READ(ah, AR_RFCNT);
-       ah->cc.tx_frame = REG_READ(ah, AR_TFCNT);
-
-       /* prevent wraparound */
-       if (ah->cc.cycles & BIT(31))
-               clear = true;
-
-#define CC_DELTA(_field, _reg) ah->cc_delta._field += ah->cc._field - cc._field
-       CC_DELTA(cycles, AR_CCCNT);
-       CC_DELTA(rx_frame, AR_RFCNT);
-       CC_DELTA(rx_clear, AR_RCCNT);
-       CC_DELTA(tx_frame, AR_TFCNT);
-#undef CC_DELTA
-
-       ah->listen_time += (ah->cc.cycles - cc.cycles) -
-                ((ah->cc.rx_frame - cc.rx_frame) +
-                 (ah->cc.tx_frame - cc.tx_frame));
-
-skip:
-       if (clear) {
-               REG_WRITE(ah, AR_CCCNT, 0);
-               REG_WRITE(ah, AR_RFCNT, 0);
-               REG_WRITE(ah, AR_RCCNT, 0);
-               REG_WRITE(ah, AR_TFCNT, 0);
-               memset(&ah->cc, 0, sizeof(ah->cc));
-       }
-
-       /* unfreeze counters */
-       REG_WRITE(ah, AR_MIBC, 0);
-}
-
 /*
  * Process a MIB interrupt.  We may potentially be invoked because
  * any of the MIB counters overflow/trigger so don't assume we're
index 98cfd8154c71d5b90a9a0dd44c05c09446f97b1a..0cd6783de883668d2f433bfb07f5ffe0c47863cb 100644 (file)
@@ -93,13 +93,6 @@ struct ath9k_mib_stats {
        u32 beacons;
 };
 
-struct ath_cycle_counters {
-       u32 cycles;
-       u32 rx_frame;
-       u32 rx_clear;
-       u32 tx_frame;
-};
-
 /* INI default values for ANI registers */
 struct ath9k_ani_default {
        u16 m1ThreshLow;
@@ -164,7 +157,6 @@ struct ar5416Stats {
 
 void ath9k_enable_mib_counters(struct ath_hw *ah);
 void ath9k_hw_disable_mib_counters(struct ath_hw *ah);
-void ath9k_hw_update_cycle_counters(struct ath_hw *ah);
 void ath9k_hw_ani_setup(struct ath_hw *ah);
 void ath9k_hw_ani_init(struct ath_hw *ah);
 int 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 (file)
index d3375fc..0000000
+++ /dev/null
@@ -1,1784 +0,0 @@
-/*
- * Copyright (c) 2010 Atheros Communications Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef INITVALS_9003_2P0_H
-#define INITVALS_9003_2P0_H
-
-/* AR9003 2.0 */
-
-static const u32 ar9300_2p0_radio_postamble[][5] = {
-       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-       {0x0001609c, 0x0dd08f29, 0x0dd08f29, 0x0b283f31, 0x0b283f31},
-       {0x000160ac, 0xa4653c00, 0xa4653c00, 0x24652800, 0x24652800},
-       {0x000160b0, 0x03284f3e, 0x03284f3e, 0x05d08f20, 0x05d08f20},
-       {0x0001610c, 0x08000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
-       {0x0001650c, 0x08000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
-       {0x0001690c, 0x08000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x00016940, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
-};
-
-static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p0[][5] = {
-       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-       {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
-       {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
-       {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
-       {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
-       {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
-       {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400},
-       {0x0000a518, 0x21020220, 0x21020220, 0x16000402, 0x16000402},
-       {0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404},
-       {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603},
-       {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02},
-       {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04},
-       {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20},
-       {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20},
-       {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22},
-       {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24},
-       {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640},
-       {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660},
-       {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861},
-       {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81},
-       {0x0000a54c, 0x5c04286b, 0x5c04286b, 0x47001a83, 0x47001a83},
-       {0x0000a550, 0x61042a6c, 0x61042a6c, 0x4a001c84, 0x4a001c84},
-       {0x0000a554, 0x66062a6c, 0x66062a6c, 0x4e001ce3, 0x4e001ce3},
-       {0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x52001ce5, 0x52001ce5},
-       {0x0000a55c, 0x7006308c, 0x7006308c, 0x56001ce9, 0x56001ce9},
-       {0x0000a560, 0x730a308a, 0x730a308a, 0x5a001ceb, 0x5a001ceb},
-       {0x0000a564, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
-       {0x0000a568, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
-       {0x0000a56c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
-       {0x0000a570, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
-       {0x0000a574, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
-       {0x0000a578, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
-       {0x0000a57c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
-       {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
-       {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
-       {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
-       {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
-       {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202},
-       {0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400},
-       {0x0000a598, 0x21820220, 0x21820220, 0x16800402, 0x16800402},
-       {0x0000a59c, 0x27820223, 0x27820223, 0x19800404, 0x19800404},
-       {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603},
-       {0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02},
-       {0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04},
-       {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20},
-       {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20},
-       {0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22},
-       {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24},
-       {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640},
-       {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660},
-       {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861},
-       {0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81},
-       {0x0000a5cc, 0x5c84286b, 0x5c84286b, 0x47801a83, 0x47801a83},
-       {0x0000a5d0, 0x61842a6c, 0x61842a6c, 0x4a801c84, 0x4a801c84},
-       {0x0000a5d4, 0x66862a6c, 0x66862a6c, 0x4e801ce3, 0x4e801ce3},
-       {0x0000a5d8, 0x6b862e6c, 0x6b862e6c, 0x52801ce5, 0x52801ce5},
-       {0x0000a5dc, 0x7086308c, 0x7086308c, 0x56801ce9, 0x56801ce9},
-       {0x0000a5e0, 0x738a308a, 0x738a308a, 0x5a801ceb, 0x5a801ceb},
-       {0x0000a5e4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
-       {0x0000a5e8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
-       {0x0000a5ec, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
-       {0x0000a5f0, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
-       {0x0000a5f4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
-       {0x0000a5f8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
-       {0x0000a5fc, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
-       {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
-       {0x00016048, 0x62480001, 0x62480001, 0x62480001, 0x62480001},
-       {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
-       {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
-       {0x00016448, 0x62480001, 0x62480001, 0x62480001, 0x62480001},
-       {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
-       {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
-       {0x00016848, 0x62480001, 0x62480001, 0x62480001, 0x62480001},
-       {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
-};
-
-static const u32 ar9300Modes_fast_clock_2p0[][3] = {
-       /* Addr      5G_HT20     5G_HT40   */
-       {0x00001030, 0x00000268, 0x000004d0},
-       {0x00001070, 0x0000018c, 0x00000318},
-       {0x000010b0, 0x00000fd0, 0x00001fa0},
-       {0x00008014, 0x044c044c, 0x08980898},
-       {0x0000801c, 0x148ec02b, 0x148ec057},
-       {0x00008318, 0x000044c0, 0x00008980},
-       {0x00009e00, 0x03721821, 0x03721821},
-       {0x0000a230, 0x0000000b, 0x00000016},
-       {0x0000a254, 0x00000898, 0x00001130},
-};
-
-static const u32 ar9300_2p0_radio_core[][2] = {
-       /* Addr      allmodes  */
-       {0x00016000, 0x36db6db6},
-       {0x00016004, 0x6db6db40},
-       {0x00016008, 0x73f00000},
-       {0x0001600c, 0x00000000},
-       {0x00016040, 0x7f80fff8},
-       {0x0001604c, 0x76d005b5},
-       {0x00016050, 0x556cf031},
-       {0x00016054, 0x13449440},
-       {0x00016058, 0x0c51c92c},
-       {0x0001605c, 0x3db7fffc},
-       {0x00016060, 0xfffffffc},
-       {0x00016064, 0x000f0278},
-       {0x0001606c, 0x6db60000},
-       {0x00016080, 0x00000000},
-       {0x00016084, 0x0e48048c},
-       {0x00016088, 0x54214514},
-       {0x0001608c, 0x119f481e},
-       {0x00016090, 0x24926490},
-       {0x00016098, 0xd2888888},
-       {0x000160a0, 0x0a108ffe},
-       {0x000160a4, 0x812fc370},
-       {0x000160a8, 0x423c8000},
-       {0x000160b4, 0x92480080},
-       {0x000160c0, 0x00adb6d0},
-       {0x000160c4, 0x6db6db60},
-       {0x000160c8, 0x6db6db6c},
-       {0x000160cc, 0x01e6c000},
-       {0x00016100, 0x3fffbe01},
-       {0x00016104, 0xfff80000},
-       {0x00016108, 0x00080010},
-       {0x00016144, 0x02084080},
-       {0x00016148, 0x00000000},
-       {0x00016280, 0x058a0001},
-       {0x00016284, 0x3d840208},
-       {0x00016288, 0x05a20408},
-       {0x0001628c, 0x00038c07},
-       {0x00016290, 0x40000004},
-       {0x00016294, 0x458aa14f},
-       {0x00016380, 0x00000000},
-       {0x00016384, 0x00000000},
-       {0x00016388, 0x00800700},
-       {0x0001638c, 0x00800700},
-       {0x00016390, 0x00800700},
-       {0x00016394, 0x00000000},
-       {0x00016398, 0x00000000},
-       {0x0001639c, 0x00000000},
-       {0x000163a0, 0x00000001},
-       {0x000163a4, 0x00000001},
-       {0x000163a8, 0x00000000},
-       {0x000163ac, 0x00000000},
-       {0x000163b0, 0x00000000},
-       {0x000163b4, 0x00000000},
-       {0x000163b8, 0x00000000},
-       {0x000163bc, 0x00000000},
-       {0x000163c0, 0x000000a0},
-       {0x000163c4, 0x000c0000},
-       {0x000163c8, 0x14021402},
-       {0x000163cc, 0x00001402},
-       {0x000163d0, 0x00000000},
-       {0x000163d4, 0x00000000},
-       {0x00016400, 0x36db6db6},
-       {0x00016404, 0x6db6db40},
-       {0x00016408, 0x73f00000},
-       {0x0001640c, 0x00000000},
-       {0x00016440, 0x7f80fff8},
-       {0x0001644c, 0x76d005b5},
-       {0x00016450, 0x556cf031},
-       {0x00016454, 0x13449440},
-       {0x00016458, 0x0c51c92c},
-       {0x0001645c, 0x3db7fffc},
-       {0x00016460, 0xfffffffc},
-       {0x00016464, 0x000f0278},
-       {0x0001646c, 0x6db60000},
-       {0x00016500, 0x3fffbe01},
-       {0x00016504, 0xfff80000},
-       {0x00016508, 0x00080010},
-       {0x00016544, 0x02084080},
-       {0x00016548, 0x00000000},
-       {0x00016780, 0x00000000},
-       {0x00016784, 0x00000000},
-       {0x00016788, 0x00800700},
-       {0x0001678c, 0x00800700},
-       {0x00016790, 0x00800700},
-       {0x00016794, 0x00000000},
-       {0x00016798, 0x00000000},
-       {0x0001679c, 0x00000000},
-       {0x000167a0, 0x00000001},
-       {0x000167a4, 0x00000001},
-       {0x000167a8, 0x00000000},
-       {0x000167ac, 0x00000000},
-       {0x000167b0, 0x00000000},
-       {0x000167b4, 0x00000000},
-       {0x000167b8, 0x00000000},
-       {0x000167bc, 0x00000000},
-       {0x000167c0, 0x000000a0},
-       {0x000167c4, 0x000c0000},
-       {0x000167c8, 0x14021402},
-       {0x000167cc, 0x00001402},
-       {0x000167d0, 0x00000000},
-       {0x000167d4, 0x00000000},
-       {0x00016800, 0x36db6db6},
-       {0x00016804, 0x6db6db40},
-       {0x00016808, 0x73f00000},
-       {0x0001680c, 0x00000000},
-       {0x00016840, 0x7f80fff8},
-       {0x0001684c, 0x76d005b5},
-       {0x00016850, 0x556cf031},
-       {0x00016854, 0x13449440},
-       {0x00016858, 0x0c51c92c},
-       {0x0001685c, 0x3db7fffc},
-       {0x00016860, 0xfffffffc},
-       {0x00016864, 0x000f0278},
-       {0x0001686c, 0x6db60000},
-       {0x00016900, 0x3fffbe01},
-       {0x00016904, 0xfff80000},
-       {0x00016908, 0x00080010},
-       {0x00016944, 0x02084080},
-       {0x00016948, 0x00000000},
-       {0x00016b80, 0x00000000},
-       {0x00016b84, 0x00000000},
-       {0x00016b88, 0x00800700},
-       {0x00016b8c, 0x00800700},
-       {0x00016b90, 0x00800700},
-       {0x00016b94, 0x00000000},
-       {0x00016b98, 0x00000000},
-       {0x00016b9c, 0x00000000},
-       {0x00016ba0, 0x00000001},
-       {0x00016ba4, 0x00000001},
-       {0x00016ba8, 0x00000000},
-       {0x00016bac, 0x00000000},
-       {0x00016bb0, 0x00000000},
-       {0x00016bb4, 0x00000000},
-       {0x00016bb8, 0x00000000},
-       {0x00016bbc, 0x00000000},
-       {0x00016bc0, 0x000000a0},
-       {0x00016bc4, 0x000c0000},
-       {0x00016bc8, 0x14021402},
-       {0x00016bcc, 0x00001402},
-       {0x00016bd0, 0x00000000},
-       {0x00016bd4, 0x00000000},
-};
-
-static const u32 ar9300Common_rx_gain_table_merlin_2p0[][2] = {
-       /* Addr      allmodes  */
-       {0x0000a000, 0x02000101},
-       {0x0000a004, 0x02000102},
-       {0x0000a008, 0x02000103},
-       {0x0000a00c, 0x02000104},
-       {0x0000a010, 0x02000200},
-       {0x0000a014, 0x02000201},
-       {0x0000a018, 0x02000202},
-       {0x0000a01c, 0x02000203},
-       {0x0000a020, 0x02000204},
-       {0x0000a024, 0x02000205},
-       {0x0000a028, 0x02000208},
-       {0x0000a02c, 0x02000302},
-       {0x0000a030, 0x02000303},
-       {0x0000a034, 0x02000304},
-       {0x0000a038, 0x02000400},
-       {0x0000a03c, 0x02010300},
-       {0x0000a040, 0x02010301},
-       {0x0000a044, 0x02010302},
-       {0x0000a048, 0x02000500},
-       {0x0000a04c, 0x02010400},
-       {0x0000a050, 0x02020300},
-       {0x0000a054, 0x02020301},
-       {0x0000a058, 0x02020302},
-       {0x0000a05c, 0x02020303},
-       {0x0000a060, 0x02020400},
-       {0x0000a064, 0x02030300},
-       {0x0000a068, 0x02030301},
-       {0x0000a06c, 0x02030302},
-       {0x0000a070, 0x02030303},
-       {0x0000a074, 0x02030400},
-       {0x0000a078, 0x02040300},
-       {0x0000a07c, 0x02040301},
-       {0x0000a080, 0x02040302},
-       {0x0000a084, 0x02040303},
-       {0x0000a088, 0x02030500},
-       {0x0000a08c, 0x02040400},
-       {0x0000a090, 0x02050203},
-       {0x0000a094, 0x02050204},
-       {0x0000a098, 0x02050205},
-       {0x0000a09c, 0x02040500},
-       {0x0000a0a0, 0x02050301},
-       {0x0000a0a4, 0x02050302},
-       {0x0000a0a8, 0x02050303},
-       {0x0000a0ac, 0x02050400},
-       {0x0000a0b0, 0x02050401},
-       {0x0000a0b4, 0x02050402},
-       {0x0000a0b8, 0x02050403},
-       {0x0000a0bc, 0x02050500},
-       {0x0000a0c0, 0x02050501},
-       {0x0000a0c4, 0x02050502},
-       {0x0000a0c8, 0x02050503},
-       {0x0000a0cc, 0x02050504},
-       {0x0000a0d0, 0x02050600},
-       {0x0000a0d4, 0x02050601},
-       {0x0000a0d8, 0x02050602},
-       {0x0000a0dc, 0x02050603},
-       {0x0000a0e0, 0x02050604},
-       {0x0000a0e4, 0x02050700},
-       {0x0000a0e8, 0x02050701},
-       {0x0000a0ec, 0x02050702},
-       {0x0000a0f0, 0x02050703},
-       {0x0000a0f4, 0x02050704},
-       {0x0000a0f8, 0x02050705},
-       {0x0000a0fc, 0x02050708},
-       {0x0000a100, 0x02050709},
-       {0x0000a104, 0x0205070a},
-       {0x0000a108, 0x0205070b},
-       {0x0000a10c, 0x0205070c},
-       {0x0000a110, 0x0205070d},
-       {0x0000a114, 0x02050710},
-       {0x0000a118, 0x02050711},
-       {0x0000a11c, 0x02050712},
-       {0x0000a120, 0x02050713},
-       {0x0000a124, 0x02050714},
-       {0x0000a128, 0x02050715},
-       {0x0000a12c, 0x02050730},
-       {0x0000a130, 0x02050731},
-       {0x0000a134, 0x02050732},
-       {0x0000a138, 0x02050733},
-       {0x0000a13c, 0x02050734},
-       {0x0000a140, 0x02050735},
-       {0x0000a144, 0x02050750},
-       {0x0000a148, 0x02050751},
-       {0x0000a14c, 0x02050752},
-       {0x0000a150, 0x02050753},
-       {0x0000a154, 0x02050754},
-       {0x0000a158, 0x02050755},
-       {0x0000a15c, 0x02050770},
-       {0x0000a160, 0x02050771},
-       {0x0000a164, 0x02050772},
-       {0x0000a168, 0x02050773},
-       {0x0000a16c, 0x02050774},
-       {0x0000a170, 0x02050775},
-       {0x0000a174, 0x00000776},
-       {0x0000a178, 0x00000776},
-       {0x0000a17c, 0x00000776},
-       {0x0000a180, 0x00000776},
-       {0x0000a184, 0x00000776},
-       {0x0000a188, 0x00000776},
-       {0x0000a18c, 0x00000776},
-       {0x0000a190, 0x00000776},
-       {0x0000a194, 0x00000776},
-       {0x0000a198, 0x00000776},
-       {0x0000a19c, 0x00000776},
-       {0x0000a1a0, 0x00000776},
-       {0x0000a1a4, 0x00000776},
-       {0x0000a1a8, 0x00000776},
-       {0x0000a1ac, 0x00000776},
-       {0x0000a1b0, 0x00000776},
-       {0x0000a1b4, 0x00000776},
-       {0x0000a1b8, 0x00000776},
-       {0x0000a1bc, 0x00000776},
-       {0x0000a1c0, 0x00000776},
-       {0x0000a1c4, 0x00000776},
-       {0x0000a1c8, 0x00000776},
-       {0x0000a1cc, 0x00000776},
-       {0x0000a1d0, 0x00000776},
-       {0x0000a1d4, 0x00000776},
-       {0x0000a1d8, 0x00000776},
-       {0x0000a1dc, 0x00000776},
-       {0x0000a1e0, 0x00000776},
-       {0x0000a1e4, 0x00000776},
-       {0x0000a1e8, 0x00000776},
-       {0x0000a1ec, 0x00000776},
-       {0x0000a1f0, 0x00000776},
-       {0x0000a1f4, 0x00000776},
-       {0x0000a1f8, 0x00000776},
-       {0x0000a1fc, 0x00000776},
-       {0x0000b000, 0x02000101},
-       {0x0000b004, 0x02000102},
-       {0x0000b008, 0x02000103},
-       {0x0000b00c, 0x02000104},
-       {0x0000b010, 0x02000200},
-       {0x0000b014, 0x02000201},
-       {0x0000b018, 0x02000202},
-       {0x0000b01c, 0x02000203},
-       {0x0000b020, 0x02000204},
-       {0x0000b024, 0x02000205},
-       {0x0000b028, 0x02000208},
-       {0x0000b02c, 0x02000302},
-       {0x0000b030, 0x02000303},
-       {0x0000b034, 0x02000304},
-       {0x0000b038, 0x02000400},
-       {0x0000b03c, 0x02010300},
-       {0x0000b040, 0x02010301},
-       {0x0000b044, 0x02010302},
-       {0x0000b048, 0x02000500},
-       {0x0000b04c, 0x02010400},
-       {0x0000b050, 0x02020300},
-       {0x0000b054, 0x02020301},
-       {0x0000b058, 0x02020302},
-       {0x0000b05c, 0x02020303},
-       {0x0000b060, 0x02020400},
-       {0x0000b064, 0x02030300},
-       {0x0000b068, 0x02030301},
-       {0x0000b06c, 0x02030302},
-       {0x0000b070, 0x02030303},
-       {0x0000b074, 0x02030400},
-       {0x0000b078, 0x02040300},
-       {0x0000b07c, 0x02040301},
-       {0x0000b080, 0x02040302},
-       {0x0000b084, 0x02040303},
-       {0x0000b088, 0x02030500},
-       {0x0000b08c, 0x02040400},
-       {0x0000b090, 0x02050203},
-       {0x0000b094, 0x02050204},
-       {0x0000b098, 0x02050205},
-       {0x0000b09c, 0x02040500},
-       {0x0000b0a0, 0x02050301},
-       {0x0000b0a4, 0x02050302},
-       {0x0000b0a8, 0x02050303},
-       {0x0000b0ac, 0x02050400},
-       {0x0000b0b0, 0x02050401},
-       {0x0000b0b4, 0x02050402},
-       {0x0000b0b8, 0x02050403},
-       {0x0000b0bc, 0x02050500},
-       {0x0000b0c0, 0x02050501},
-       {0x0000b0c4, 0x02050502},
-       {0x0000b0c8, 0x02050503},
-       {0x0000b0cc, 0x02050504},
-       {0x0000b0d0, 0x02050600},
-       {0x0000b0d4, 0x02050601},
-       {0x0000b0d8, 0x02050602},
-       {0x0000b0dc, 0x02050603},
-       {0x0000b0e0, 0x02050604},
-       {0x0000b0e4, 0x02050700},
-       {0x0000b0e8, 0x02050701},
-       {0x0000b0ec, 0x02050702},
-       {0x0000b0f0, 0x02050703},
-       {0x0000b0f4, 0x02050704},
-       {0x0000b0f8, 0x02050705},
-       {0x0000b0fc, 0x02050708},
-       {0x0000b100, 0x02050709},
-       {0x0000b104, 0x0205070a},
-       {0x0000b108, 0x0205070b},
-       {0x0000b10c, 0x0205070c},
-       {0x0000b110, 0x0205070d},
-       {0x0000b114, 0x02050710},
-       {0x0000b118, 0x02050711},
-       {0x0000b11c, 0x02050712},
-       {0x0000b120, 0x02050713},
-       {0x0000b124, 0x02050714},
-       {0x0000b128, 0x02050715},
-       {0x0000b12c, 0x02050730},
-       {0x0000b130, 0x02050731},
-       {0x0000b134, 0x02050732},
-       {0x0000b138, 0x02050733},
-       {0x0000b13c, 0x02050734},
-       {0x0000b140, 0x02050735},
-       {0x0000b144, 0x02050750},
-       {0x0000b148, 0x02050751},
-       {0x0000b14c, 0x02050752},
-       {0x0000b150, 0x02050753},
-       {0x0000b154, 0x02050754},
-       {0x0000b158, 0x02050755},
-       {0x0000b15c, 0x02050770},
-       {0x0000b160, 0x02050771},
-       {0x0000b164, 0x02050772},
-       {0x0000b168, 0x02050773},
-       {0x0000b16c, 0x02050774},
-       {0x0000b170, 0x02050775},
-       {0x0000b174, 0x00000776},
-       {0x0000b178, 0x00000776},
-       {0x0000b17c, 0x00000776},
-       {0x0000b180, 0x00000776},
-       {0x0000b184, 0x00000776},
-       {0x0000b188, 0x00000776},
-       {0x0000b18c, 0x00000776},
-       {0x0000b190, 0x00000776},
-       {0x0000b194, 0x00000776},
-       {0x0000b198, 0x00000776},
-       {0x0000b19c, 0x00000776},
-       {0x0000b1a0, 0x00000776},
-       {0x0000b1a4, 0x00000776},
-       {0x0000b1a8, 0x00000776},
-       {0x0000b1ac, 0x00000776},
-       {0x0000b1b0, 0x00000776},
-       {0x0000b1b4, 0x00000776},
-       {0x0000b1b8, 0x00000776},
-       {0x0000b1bc, 0x00000776},
-       {0x0000b1c0, 0x00000776},
-       {0x0000b1c4, 0x00000776},
-       {0x0000b1c8, 0x00000776},
-       {0x0000b1cc, 0x00000776},
-       {0x0000b1d0, 0x00000776},
-       {0x0000b1d4, 0x00000776},
-       {0x0000b1d8, 0x00000776},
-       {0x0000b1dc, 0x00000776},
-       {0x0000b1e0, 0x00000776},
-       {0x0000b1e4, 0x00000776},
-       {0x0000b1e8, 0x00000776},
-       {0x0000b1ec, 0x00000776},
-       {0x0000b1f0, 0x00000776},
-       {0x0000b1f4, 0x00000776},
-       {0x0000b1f8, 0x00000776},
-       {0x0000b1fc, 0x00000776},
-};
-
-static const u32 ar9300_2p0_mac_postamble[][5] = {
-       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-       {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
-       {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c},
-       {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38},
-       {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00},
-       {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b},
-       {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810},
-       {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a},
-       {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440},
-};
-
-static const u32 ar9300_2p0_soc_postamble[][5] = {
-       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-       {0x00007010, 0x00000023, 0x00000023, 0x00000023, 0x00000023},
-};
-
-static const u32 ar9200_merlin_2p0_radio_core[][2] = {
-       /* Addr      allmodes  */
-       {0x00007800, 0x00040000},
-       {0x00007804, 0xdb005012},
-       {0x00007808, 0x04924914},
-       {0x0000780c, 0x21084210},
-       {0x00007810, 0x6d801300},
-       {0x00007814, 0x0019beff},
-       {0x00007818, 0x07e41000},
-       {0x0000781c, 0x00392000},
-       {0x00007820, 0x92592480},
-       {0x00007824, 0x00040000},
-       {0x00007828, 0xdb005012},
-       {0x0000782c, 0x04924914},
-       {0x00007830, 0x21084210},
-       {0x00007834, 0x6d801300},
-       {0x00007838, 0x0019beff},
-       {0x0000783c, 0x07e40000},
-       {0x00007840, 0x00392000},
-       {0x00007844, 0x92592480},
-       {0x00007848, 0x00100000},
-       {0x0000784c, 0x773f0567},
-       {0x00007850, 0x54214514},
-       {0x00007854, 0x12035828},
-       {0x00007858, 0x92592692},
-       {0x0000785c, 0x00000000},
-       {0x00007860, 0x56400000},
-       {0x00007864, 0x0a8e370e},
-       {0x00007868, 0xc0102850},
-       {0x0000786c, 0x812d4000},
-       {0x00007870, 0x807ec400},
-       {0x00007874, 0x001b6db0},
-       {0x00007878, 0x00376b63},
-       {0x0000787c, 0x06db6db6},
-       {0x00007880, 0x006d8000},
-       {0x00007884, 0xffeffffe},
-       {0x00007888, 0xffeffffe},
-       {0x0000788c, 0x00010000},
-       {0x00007890, 0x02060aeb},
-       {0x00007894, 0x5a108000},
-};
-
-static const u32 ar9300_2p0_baseband_postamble[][5] = {
-       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-       {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011},
-       {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e},
-       {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0},
-       {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881},
-       {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
-       {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c},
-       {0x00009c00, 0x00000044, 0x000000c4, 0x000000c4, 0x00000044},
-       {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0},
-       {0x00009e04, 0x00802020, 0x00802020, 0x00802020, 0x00802020},
-       {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2},
-       {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec84d2e},
-       {0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e},
-       {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c},
-       {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce},
-       {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021},
-       {0x00009e44, 0x02321e27, 0x02321e27, 0x02291e27, 0x02291e27},
-       {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012},
-       {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000},
-       {0x0000a204, 0x000037c0, 0x000037c4, 0x000037c4, 0x000037c0},
-       {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004},
-       {0x0000a230, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b},
-       {0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018},
-       {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108},
-       {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898},
-       {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002},
-       {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e},
-       {0x0000a260, 0x0a021501, 0x0a021501, 0x3a021501, 0x3a021501},
-       {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e},
-       {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b},
-       {0x0000a284, 0x00000000, 0x00000000, 0x00000150, 0x00000150},
-       {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110},
-       {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222},
-       {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18},
-       {0x0000a2d0, 0x00071981, 0x00071981, 0x00071981, 0x00071982},
-       {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a},
-       {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
-       {0x0000ae04, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
-       {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
-       {0x0000ae20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce},
-       {0x0000b284, 0x00000000, 0x00000000, 0x00000150, 0x00000150},
-       {0x0000b830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
-       {0x0000be04, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
-       {0x0000be18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x0000be1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
-       {0x0000be20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce},
-       {0x0000c284, 0x00000000, 0x00000000, 0x00000150, 0x00000150},
-};
-
-static const u32 ar9300_2p0_baseband_core[][2] = {
-       /* Addr      allmodes  */
-       {0x00009800, 0xafe68e30},
-       {0x00009804, 0xfd14e000},
-       {0x00009808, 0x9c0a9f6b},
-       {0x0000980c, 0x04900000},
-       {0x00009814, 0x9280c00a},
-       {0x00009818, 0x00000000},
-       {0x0000981c, 0x00020028},
-       {0x00009834, 0x5f3ca3de},
-       {0x00009838, 0x0108ecff},
-       {0x0000983c, 0x14750600},
-       {0x00009880, 0x201fff00},
-       {0x00009884, 0x00001042},
-       {0x000098a4, 0x00200400},
-       {0x000098b0, 0x52440bbe},
-       {0x000098d0, 0x004b6a8e},
-       {0x000098d4, 0x00000820},
-       {0x000098dc, 0x00000000},
-       {0x000098f0, 0x00000000},
-       {0x000098f4, 0x00000000},
-       {0x00009c04, 0xff55ff55},
-       {0x00009c08, 0x0320ff55},
-       {0x00009c0c, 0x00000000},
-       {0x00009c10, 0x00000000},
-       {0x00009c14, 0x00046384},
-       {0x00009c18, 0x05b6b440},
-       {0x00009c1c, 0x00b6b440},
-       {0x00009d00, 0xc080a333},
-       {0x00009d04, 0x40206c10},
-       {0x00009d08, 0x009c4060},
-       {0x00009d0c, 0x9883800a},
-       {0x00009d10, 0x01834061},
-       {0x00009d14, 0x00c0040b},
-       {0x00009d18, 0x00000000},
-       {0x00009e08, 0x0038230c},
-       {0x00009e24, 0x990bb515},
-       {0x00009e28, 0x0c6f0000},
-       {0x00009e30, 0x06336f77},
-       {0x00009e34, 0x6af6532f},
-       {0x00009e38, 0x0cc80c00},
-       {0x00009e3c, 0xcf946222},
-       {0x00009e40, 0x0d261820},
-       {0x00009e4c, 0x00001004},
-       {0x00009e50, 0x00ff03f1},
-       {0x00009e54, 0x00000000},
-       {0x00009fc0, 0x803e4788},
-       {0x00009fc4, 0x0001efb5},
-       {0x00009fcc, 0x40000014},
-       {0x00009fd0, 0x01193b93},
-       {0x0000a20c, 0x00000000},
-       {0x0000a220, 0x00000000},
-       {0x0000a224, 0x00000000},
-       {0x0000a228, 0x10002310},
-       {0x0000a22c, 0x01036a1e},
-       {0x0000a234, 0x10000fff},
-       {0x0000a23c, 0x00000000},
-       {0x0000a244, 0x0c000000},
-       {0x0000a2a0, 0x00000001},
-       {0x0000a2c0, 0x00000001},
-       {0x0000a2c8, 0x00000000},
-       {0x0000a2cc, 0x18c43433},
-       {0x0000a2d4, 0x00000000},
-       {0x0000a2dc, 0x00000000},
-       {0x0000a2e0, 0x00000000},
-       {0x0000a2e4, 0x00000000},
-       {0x0000a2e8, 0x00000000},
-       {0x0000a2ec, 0x00000000},
-       {0x0000a2f0, 0x00000000},
-       {0x0000a2f4, 0x00000000},
-       {0x0000a2f8, 0x00000000},
-       {0x0000a344, 0x00000000},
-       {0x0000a34c, 0x00000000},
-       {0x0000a350, 0x0000a000},
-       {0x0000a364, 0x00000000},
-       {0x0000a370, 0x00000000},
-       {0x0000a390, 0x00000001},
-       {0x0000a394, 0x00000444},
-       {0x0000a398, 0x001f0e0f},
-       {0x0000a39c, 0x0075393f},
-       {0x0000a3a0, 0xb79f6427},
-       {0x0000a3a4, 0x00000000},
-       {0x0000a3a8, 0xaaaaaaaa},
-       {0x0000a3ac, 0x3c466478},
-       {0x0000a3c0, 0x20202020},
-       {0x0000a3c4, 0x22222220},
-       {0x0000a3c8, 0x20200020},
-       {0x0000a3cc, 0x20202020},
-       {0x0000a3d0, 0x20202020},
-       {0x0000a3d4, 0x20202020},
-       {0x0000a3d8, 0x20202020},
-       {0x0000a3dc, 0x20202020},
-       {0x0000a3e0, 0x20202020},
-       {0x0000a3e4, 0x20202020},
-       {0x0000a3e8, 0x20202020},
-       {0x0000a3ec, 0x20202020},
-       {0x0000a3f0, 0x00000000},
-       {0x0000a3f4, 0x00000246},
-       {0x0000a3f8, 0x0cdbd380},
-       {0x0000a3fc, 0x000f0f01},
-       {0x0000a400, 0x8fa91f01},
-       {0x0000a404, 0x00000000},
-       {0x0000a408, 0x0e79e5c6},
-       {0x0000a40c, 0x00820820},
-       {0x0000a414, 0x1ce739ce},
-       {0x0000a418, 0x2d001dce},
-       {0x0000a41c, 0x1ce739ce},
-       {0x0000a420, 0x000001ce},
-       {0x0000a424, 0x1ce739ce},
-       {0x0000a428, 0x000001ce},
-       {0x0000a42c, 0x1ce739ce},
-       {0x0000a430, 0x1ce739ce},
-       {0x0000a434, 0x00000000},
-       {0x0000a438, 0x00001801},
-       {0x0000a43c, 0x00000000},
-       {0x0000a440, 0x00000000},
-       {0x0000a444, 0x00000000},
-       {0x0000a448, 0x04000080},
-       {0x0000a44c, 0x00000001},
-       {0x0000a450, 0x00010000},
-       {0x0000a458, 0x00000000},
-       {0x0000a600, 0x00000000},
-       {0x0000a604, 0x00000000},
-       {0x0000a608, 0x00000000},
-       {0x0000a60c, 0x00000000},
-       {0x0000a610, 0x00000000},
-       {0x0000a614, 0x00000000},
-       {0x0000a618, 0x00000000},
-       {0x0000a61c, 0x00000000},
-       {0x0000a620, 0x00000000},
-       {0x0000a624, 0x00000000},
-       {0x0000a628, 0x00000000},
-       {0x0000a62c, 0x00000000},
-       {0x0000a630, 0x00000000},
-       {0x0000a634, 0x00000000},
-       {0x0000a638, 0x00000000},
-       {0x0000a63c, 0x00000000},
-       {0x0000a640, 0x00000000},
-       {0x0000a644, 0x3fad9d74},
-       {0x0000a648, 0x0048060a},
-       {0x0000a64c, 0x00000637},
-       {0x0000a670, 0x03020100},
-       {0x0000a674, 0x09080504},
-       {0x0000a678, 0x0d0c0b0a},
-       {0x0000a67c, 0x13121110},
-       {0x0000a680, 0x31301514},
-       {0x0000a684, 0x35343332},
-       {0x0000a688, 0x00000036},
-       {0x0000a690, 0x00000838},
-       {0x0000a7c0, 0x00000000},
-       {0x0000a7c4, 0xfffffffc},
-       {0x0000a7c8, 0x00000000},
-       {0x0000a7cc, 0x00000000},
-       {0x0000a7d0, 0x00000000},
-       {0x0000a7d4, 0x00000004},
-       {0x0000a7dc, 0x00000001},
-       {0x0000a8d0, 0x004b6a8e},
-       {0x0000a8d4, 0x00000820},
-       {0x0000a8dc, 0x00000000},
-       {0x0000a8f0, 0x00000000},
-       {0x0000a8f4, 0x00000000},
-       {0x0000b2d0, 0x00000080},
-       {0x0000b2d4, 0x00000000},
-       {0x0000b2dc, 0x00000000},
-       {0x0000b2e0, 0x00000000},
-       {0x0000b2e4, 0x00000000},
-       {0x0000b2e8, 0x00000000},
-       {0x0000b2ec, 0x00000000},
-       {0x0000b2f0, 0x00000000},
-       {0x0000b2f4, 0x00000000},
-       {0x0000b2f8, 0x00000000},
-       {0x0000b408, 0x0e79e5c0},
-       {0x0000b40c, 0x00820820},
-       {0x0000b420, 0x00000000},
-       {0x0000b8d0, 0x004b6a8e},
-       {0x0000b8d4, 0x00000820},
-       {0x0000b8dc, 0x00000000},
-       {0x0000b8f0, 0x00000000},
-       {0x0000b8f4, 0x00000000},
-       {0x0000c2d0, 0x00000080},
-       {0x0000c2d4, 0x00000000},
-       {0x0000c2dc, 0x00000000},
-       {0x0000c2e0, 0x00000000},
-       {0x0000c2e4, 0x00000000},
-       {0x0000c2e8, 0x00000000},
-       {0x0000c2ec, 0x00000000},
-       {0x0000c2f0, 0x00000000},
-       {0x0000c2f4, 0x00000000},
-       {0x0000c2f8, 0x00000000},
-       {0x0000c408, 0x0e79e5c0},
-       {0x0000c40c, 0x00820820},
-       {0x0000c420, 0x00000000},
-};
-
-static const u32 ar9300Modes_high_power_tx_gain_table_2p0[][5] = {
-       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-       {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9},
-       {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
-       {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002},
-       {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004},
-       {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200},
-       {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202},
-       {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400},
-       {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402},
-       {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404},
-       {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603},
-       {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02},
-       {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04},
-       {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20},
-       {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20},
-       {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22},
-       {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24},
-       {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640},
-       {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660},
-       {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861},
-       {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81},
-       {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83},
-       {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84},
-       {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3},
-       {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5},
-       {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9},
-       {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb},
-       {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
-       {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
-       {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
-       {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
-       {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
-       {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
-       {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
-       {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000},
-       {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002},
-       {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004},
-       {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200},
-       {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202},
-       {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400},
-       {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402},
-       {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404},
-       {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603},
-       {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02},
-       {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04},
-       {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20},
-       {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20},
-       {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22},
-       {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24},
-       {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640},
-       {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660},
-       {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861},
-       {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81},
-       {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83},
-       {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84},
-       {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3},
-       {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5},
-       {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9},
-       {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb},
-       {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
-       {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
-       {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
-       {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
-       {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
-       {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
-       {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
-       {0x00016044, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6},
-       {0x00016048, 0xae480001, 0xae480001, 0xae480001, 0xae480001},
-       {0x00016068, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c},
-       {0x00016444, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6},
-       {0x00016448, 0xae480001, 0xae480001, 0xae480001, 0xae480001},
-       {0x00016468, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c},
-       {0x00016844, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6},
-       {0x00016848, 0xae480001, 0xae480001, 0xae480001, 0xae480001},
-       {0x00016868, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c},
-};
-
-static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p0[][5] = {
-       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-       {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9},
-       {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
-       {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002},
-       {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004},
-       {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200},
-       {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202},
-       {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400},
-       {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402},
-       {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404},
-       {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603},
-       {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02},
-       {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04},
-       {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20},
-       {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20},
-       {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22},
-       {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24},
-       {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640},
-       {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660},
-       {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861},
-       {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81},
-       {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83},
-       {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84},
-       {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3},
-       {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5},
-       {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9},
-       {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb},
-       {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
-       {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
-       {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
-       {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
-       {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
-       {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
-       {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
-       {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000},
-       {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002},
-       {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004},
-       {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200},
-       {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202},
-       {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400},
-       {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402},
-       {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404},
-       {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603},
-       {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02},
-       {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04},
-       {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20},
-       {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20},
-       {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22},
-       {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24},
-       {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640},
-       {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660},
-       {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861},
-       {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81},
-       {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83},
-       {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84},
-       {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3},
-       {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5},
-       {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9},
-       {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb},
-       {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
-       {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
-       {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
-       {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
-       {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
-       {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
-       {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
-       {0x00016044, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4},
-       {0x00016048, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001},
-       {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
-       {0x00016444, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4},
-       {0x00016448, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001},
-       {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
-       {0x00016844, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4},
-       {0x00016848, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001},
-       {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
-};
-
-static const u32 ar9300Common_rx_gain_table_2p0[][2] = {
-       /* Addr      allmodes  */
-       {0x0000a000, 0x00010000},
-       {0x0000a004, 0x00030002},
-       {0x0000a008, 0x00050004},
-       {0x0000a00c, 0x00810080},
-       {0x0000a010, 0x00830082},
-       {0x0000a014, 0x01810180},
-       {0x0000a018, 0x01830182},
-       {0x0000a01c, 0x01850184},
-       {0x0000a020, 0x01890188},
-       {0x0000a024, 0x018b018a},
-       {0x0000a028, 0x018d018c},
-       {0x0000a02c, 0x01910190},
-       {0x0000a030, 0x01930192},
-       {0x0000a034, 0x01950194},
-       {0x0000a038, 0x038a0196},
-       {0x0000a03c, 0x038c038b},
-       {0x0000a040, 0x0390038d},
-       {0x0000a044, 0x03920391},
-       {0x0000a048, 0x03940393},
-       {0x0000a04c, 0x03960395},
-       {0x0000a050, 0x00000000},
-       {0x0000a054, 0x00000000},
-       {0x0000a058, 0x00000000},
-       {0x0000a05c, 0x00000000},
-       {0x0000a060, 0x00000000},
-       {0x0000a064, 0x00000000},
-       {0x0000a068, 0x00000000},
-       {0x0000a06c, 0x00000000},
-       {0x0000a070, 0x00000000},
-       {0x0000a074, 0x00000000},
-       {0x0000a078, 0x00000000},
-       {0x0000a07c, 0x00000000},
-       {0x0000a080, 0x22222229},
-       {0x0000a084, 0x1d1d1d1d},
-       {0x0000a088, 0x1d1d1d1d},
-       {0x0000a08c, 0x1d1d1d1d},
-       {0x0000a090, 0x171d1d1d},
-       {0x0000a094, 0x11111717},
-       {0x0000a098, 0x00030311},
-       {0x0000a09c, 0x00000000},
-       {0x0000a0a0, 0x00000000},
-       {0x0000a0a4, 0x00000000},
-       {0x0000a0a8, 0x00000000},
-       {0x0000a0ac, 0x00000000},
-       {0x0000a0b0, 0x00000000},
-       {0x0000a0b4, 0x00000000},
-       {0x0000a0b8, 0x00000000},
-       {0x0000a0bc, 0x00000000},
-       {0x0000a0c0, 0x001f0000},
-       {0x0000a0c4, 0x01000101},
-       {0x0000a0c8, 0x011e011f},
-       {0x0000a0cc, 0x011c011d},
-       {0x0000a0d0, 0x02030204},
-       {0x0000a0d4, 0x02010202},
-       {0x0000a0d8, 0x021f0200},
-       {0x0000a0dc, 0x0302021e},
-       {0x0000a0e0, 0x03000301},
-       {0x0000a0e4, 0x031e031f},
-       {0x0000a0e8, 0x0402031d},
-       {0x0000a0ec, 0x04000401},
-       {0x0000a0f0, 0x041e041f},
-       {0x0000a0f4, 0x0502041d},
-       {0x0000a0f8, 0x05000501},
-       {0x0000a0fc, 0x051e051f},
-       {0x0000a100, 0x06010602},
-       {0x0000a104, 0x061f0600},
-       {0x0000a108, 0x061d061e},
-       {0x0000a10c, 0x07020703},
-       {0x0000a110, 0x07000701},
-       {0x0000a114, 0x00000000},
-       {0x0000a118, 0x00000000},
-       {0x0000a11c, 0x00000000},
-       {0x0000a120, 0x00000000},
-       {0x0000a124, 0x00000000},
-       {0x0000a128, 0x00000000},
-       {0x0000a12c, 0x00000000},
-       {0x0000a130, 0x00000000},
-       {0x0000a134, 0x00000000},
-       {0x0000a138, 0x00000000},
-       {0x0000a13c, 0x00000000},
-       {0x0000a140, 0x001f0000},
-       {0x0000a144, 0x01000101},
-       {0x0000a148, 0x011e011f},
-       {0x0000a14c, 0x011c011d},
-       {0x0000a150, 0x02030204},
-       {0x0000a154, 0x02010202},
-       {0x0000a158, 0x021f0200},
-       {0x0000a15c, 0x0302021e},
-       {0x0000a160, 0x03000301},
-       {0x0000a164, 0x031e031f},
-       {0x0000a168, 0x0402031d},
-       {0x0000a16c, 0x04000401},
-       {0x0000a170, 0x041e041f},
-       {0x0000a174, 0x0502041d},
-       {0x0000a178, 0x05000501},
-       {0x0000a17c, 0x051e051f},
-       {0x0000a180, 0x06010602},
-       {0x0000a184, 0x061f0600},
-       {0x0000a188, 0x061d061e},
-       {0x0000a18c, 0x07020703},
-       {0x0000a190, 0x07000701},
-       {0x0000a194, 0x00000000},
-       {0x0000a198, 0x00000000},
-       {0x0000a19c, 0x00000000},
-       {0x0000a1a0, 0x00000000},
-       {0x0000a1a4, 0x00000000},
-       {0x0000a1a8, 0x00000000},
-       {0x0000a1ac, 0x00000000},
-       {0x0000a1b0, 0x00000000},
-       {0x0000a1b4, 0x00000000},
-       {0x0000a1b8, 0x00000000},
-       {0x0000a1bc, 0x00000000},
-       {0x0000a1c0, 0x00000000},
-       {0x0000a1c4, 0x00000000},
-       {0x0000a1c8, 0x00000000},
-       {0x0000a1cc, 0x00000000},
-       {0x0000a1d0, 0x00000000},
-       {0x0000a1d4, 0x00000000},
-       {0x0000a1d8, 0x00000000},
-       {0x0000a1dc, 0x00000000},
-       {0x0000a1e0, 0x00000000},
-       {0x0000a1e4, 0x00000000},
-       {0x0000a1e8, 0x00000000},
-       {0x0000a1ec, 0x00000000},
-       {0x0000a1f0, 0x00000396},
-       {0x0000a1f4, 0x00000396},
-       {0x0000a1f8, 0x00000396},
-       {0x0000a1fc, 0x00000196},
-       {0x0000b000, 0x00010000},
-       {0x0000b004, 0x00030002},
-       {0x0000b008, 0x00050004},
-       {0x0000b00c, 0x00810080},
-       {0x0000b010, 0x00830082},
-       {0x0000b014, 0x01810180},
-       {0x0000b018, 0x01830182},
-       {0x0000b01c, 0x01850184},
-       {0x0000b020, 0x02810280},
-       {0x0000b024, 0x02830282},
-       {0x0000b028, 0x02850284},
-       {0x0000b02c, 0x02890288},
-       {0x0000b030, 0x028b028a},
-       {0x0000b034, 0x0388028c},
-       {0x0000b038, 0x038a0389},
-       {0x0000b03c, 0x038c038b},
-       {0x0000b040, 0x0390038d},
-       {0x0000b044, 0x03920391},
-       {0x0000b048, 0x03940393},
-       {0x0000b04c, 0x03960395},
-       {0x0000b050, 0x00000000},
-       {0x0000b054, 0x00000000},
-       {0x0000b058, 0x00000000},
-       {0x0000b05c, 0x00000000},
-       {0x0000b060, 0x00000000},
-       {0x0000b064, 0x00000000},
-       {0x0000b068, 0x00000000},
-       {0x0000b06c, 0x00000000},
-       {0x0000b070, 0x00000000},
-       {0x0000b074, 0x00000000},
-       {0x0000b078, 0x00000000},
-       {0x0000b07c, 0x00000000},
-       {0x0000b080, 0x32323232},
-       {0x0000b084, 0x2f2f3232},
-       {0x0000b088, 0x23282a2d},
-       {0x0000b08c, 0x1c1e2123},
-       {0x0000b090, 0x14171919},
-       {0x0000b094, 0x0e0e1214},
-       {0x0000b098, 0x03050707},
-       {0x0000b09c, 0x00030303},
-       {0x0000b0a0, 0x00000000},
-       {0x0000b0a4, 0x00000000},
-       {0x0000b0a8, 0x00000000},
-       {0x0000b0ac, 0x00000000},
-       {0x0000b0b0, 0x00000000},
-       {0x0000b0b4, 0x00000000},
-       {0x0000b0b8, 0x00000000},
-       {0x0000b0bc, 0x00000000},
-       {0x0000b0c0, 0x003f0020},
-       {0x0000b0c4, 0x00400041},
-       {0x0000b0c8, 0x0140005f},
-       {0x0000b0cc, 0x0160015f},
-       {0x0000b0d0, 0x017e017f},
-       {0x0000b0d4, 0x02410242},
-       {0x0000b0d8, 0x025f0240},
-       {0x0000b0dc, 0x027f0260},
-       {0x0000b0e0, 0x0341027e},
-       {0x0000b0e4, 0x035f0340},
-       {0x0000b0e8, 0x037f0360},
-       {0x0000b0ec, 0x04400441},
-       {0x0000b0f0, 0x0460045f},
-       {0x0000b0f4, 0x0541047f},
-       {0x0000b0f8, 0x055f0540},
-       {0x0000b0fc, 0x057f0560},
-       {0x0000b100, 0x06400641},
-       {0x0000b104, 0x0660065f},
-       {0x0000b108, 0x067e067f},
-       {0x0000b10c, 0x07410742},
-       {0x0000b110, 0x075f0740},
-       {0x0000b114, 0x077f0760},
-       {0x0000b118, 0x07800781},
-       {0x0000b11c, 0x07a0079f},
-       {0x0000b120, 0x07c107bf},
-       {0x0000b124, 0x000007c0},
-       {0x0000b128, 0x00000000},
-       {0x0000b12c, 0x00000000},
-       {0x0000b130, 0x00000000},
-       {0x0000b134, 0x00000000},
-       {0x0000b138, 0x00000000},
-       {0x0000b13c, 0x00000000},
-       {0x0000b140, 0x003f0020},
-       {0x0000b144, 0x00400041},
-       {0x0000b148, 0x0140005f},
-       {0x0000b14c, 0x0160015f},
-       {0x0000b150, 0x017e017f},
-       {0x0000b154, 0x02410242},
-       {0x0000b158, 0x025f0240},
-       {0x0000b15c, 0x027f0260},
-       {0x0000b160, 0x0341027e},
-       {0x0000b164, 0x035f0340},
-       {0x0000b168, 0x037f0360},
-       {0x0000b16c, 0x04400441},
-       {0x0000b170, 0x0460045f},
-       {0x0000b174, 0x0541047f},
-       {0x0000b178, 0x055f0540},
-       {0x0000b17c, 0x057f0560},
-       {0x0000b180, 0x06400641},
-       {0x0000b184, 0x0660065f},
-       {0x0000b188, 0x067e067f},
-       {0x0000b18c, 0x07410742},
-       {0x0000b190, 0x075f0740},
-       {0x0000b194, 0x077f0760},
-       {0x0000b198, 0x07800781},
-       {0x0000b19c, 0x07a0079f},
-       {0x0000b1a0, 0x07c107bf},
-       {0x0000b1a4, 0x000007c0},
-       {0x0000b1a8, 0x00000000},
-       {0x0000b1ac, 0x00000000},
-       {0x0000b1b0, 0x00000000},
-       {0x0000b1b4, 0x00000000},
-       {0x0000b1b8, 0x00000000},
-       {0x0000b1bc, 0x00000000},
-       {0x0000b1c0, 0x00000000},
-       {0x0000b1c4, 0x00000000},
-       {0x0000b1c8, 0x00000000},
-       {0x0000b1cc, 0x00000000},
-       {0x0000b1d0, 0x00000000},
-       {0x0000b1d4, 0x00000000},
-       {0x0000b1d8, 0x00000000},
-       {0x0000b1dc, 0x00000000},
-       {0x0000b1e0, 0x00000000},
-       {0x0000b1e4, 0x00000000},
-       {0x0000b1e8, 0x00000000},
-       {0x0000b1ec, 0x00000000},
-       {0x0000b1f0, 0x00000396},
-       {0x0000b1f4, 0x00000396},
-       {0x0000b1f8, 0x00000396},
-       {0x0000b1fc, 0x00000196},
-};
-
-static const u32 ar9300Modes_low_ob_db_tx_gain_table_2p0[][5] = {
-       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-       {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
-       {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
-       {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
-       {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
-       {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
-       {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400},
-       {0x0000a518, 0x21020220, 0x21020220, 0x16000402, 0x16000402},
-       {0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404},
-       {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603},
-       {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02},
-       {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04},
-       {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20},
-       {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20},
-       {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22},
-       {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24},
-       {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640},
-       {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660},
-       {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861},
-       {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81},
-       {0x0000a54c, 0x5c04286b, 0x5c04286b, 0x47001a83, 0x47001a83},
-       {0x0000a550, 0x61042a6c, 0x61042a6c, 0x4a001c84, 0x4a001c84},
-       {0x0000a554, 0x66062a6c, 0x66062a6c, 0x4e001ce3, 0x4e001ce3},
-       {0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x52001ce5, 0x52001ce5},
-       {0x0000a55c, 0x7006308c, 0x7006308c, 0x56001ce9, 0x56001ce9},
-       {0x0000a560, 0x730a308a, 0x730a308a, 0x5a001ceb, 0x5a001ceb},
-       {0x0000a564, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
-       {0x0000a568, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
-       {0x0000a56c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
-       {0x0000a570, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
-       {0x0000a574, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
-       {0x0000a578, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
-       {0x0000a57c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
-       {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
-       {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
-       {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
-       {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
-       {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202},
-       {0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400},
-       {0x0000a598, 0x21820220, 0x21820220, 0x16800402, 0x16800402},
-       {0x0000a59c, 0x27820223, 0x27820223, 0x19800404, 0x19800404},
-       {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603},
-       {0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02},
-       {0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04},
-       {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20},
-       {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20},
-       {0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22},
-       {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24},
-       {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640},
-       {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660},
-       {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861},
-       {0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81},
-       {0x0000a5cc, 0x5c84286b, 0x5c84286b, 0x47801a83, 0x47801a83},
-       {0x0000a5d0, 0x61842a6c, 0x61842a6c, 0x4a801c84, 0x4a801c84},
-       {0x0000a5d4, 0x66862a6c, 0x66862a6c, 0x4e801ce3, 0x4e801ce3},
-       {0x0000a5d8, 0x6b862e6c, 0x6b862e6c, 0x52801ce5, 0x52801ce5},
-       {0x0000a5dc, 0x7086308c, 0x7086308c, 0x56801ce9, 0x56801ce9},
-       {0x0000a5e0, 0x738a308a, 0x738a308a, 0x5a801ceb, 0x5a801ceb},
-       {0x0000a5e4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
-       {0x0000a5e8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
-       {0x0000a5ec, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
-       {0x0000a5f0, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
-       {0x0000a5f4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
-       {0x0000a5f8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
-       {0x0000a5fc, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
-       {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
-       {0x00016048, 0x64000001, 0x64000001, 0x64000001, 0x64000001},
-       {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
-       {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
-       {0x00016448, 0x64000001, 0x64000001, 0x64000001, 0x64000001},
-       {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
-       {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
-       {0x00016848, 0x64000001, 0x64000001, 0x64000001, 0x64000001},
-       {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
-};
-
-static const u32 ar9300_2p0_mac_core[][2] = {
-       /* Addr      allmodes  */
-       {0x00000008, 0x00000000},
-       {0x00000030, 0x00020085},
-       {0x00000034, 0x00000005},
-       {0x00000040, 0x00000000},
-       {0x00000044, 0x00000000},
-       {0x00000048, 0x00000008},
-       {0x0000004c, 0x00000010},
-       {0x00000050, 0x00000000},
-       {0x00001040, 0x002ffc0f},
-       {0x00001044, 0x002ffc0f},
-       {0x00001048, 0x002ffc0f},
-       {0x0000104c, 0x002ffc0f},
-       {0x00001050, 0x002ffc0f},
-       {0x00001054, 0x002ffc0f},
-       {0x00001058, 0x002ffc0f},
-       {0x0000105c, 0x002ffc0f},
-       {0x00001060, 0x002ffc0f},
-       {0x00001064, 0x002ffc0f},
-       {0x000010f0, 0x00000100},
-       {0x00001270, 0x00000000},
-       {0x000012b0, 0x00000000},
-       {0x000012f0, 0x00000000},
-       {0x0000143c, 0x00000000},
-       {0x0000147c, 0x00000000},
-       {0x00008000, 0x00000000},
-       {0x00008004, 0x00000000},
-       {0x00008008, 0x00000000},
-       {0x0000800c, 0x00000000},
-       {0x00008018, 0x00000000},
-       {0x00008020, 0x00000000},
-       {0x00008038, 0x00000000},
-       {0x0000803c, 0x00000000},
-       {0x00008040, 0x00000000},
-       {0x00008044, 0x00000000},
-       {0x00008048, 0x00000000},
-       {0x0000804c, 0xffffffff},
-       {0x00008054, 0x00000000},
-       {0x00008058, 0x00000000},
-       {0x0000805c, 0x000fc78f},
-       {0x00008060, 0x0000000f},
-       {0x00008064, 0x00000000},
-       {0x00008070, 0x00000310},
-       {0x00008074, 0x00000020},
-       {0x00008078, 0x00000000},
-       {0x0000809c, 0x0000000f},
-       {0x000080a0, 0x00000000},
-       {0x000080a4, 0x02ff0000},
-       {0x000080a8, 0x0e070605},
-       {0x000080ac, 0x0000000d},
-       {0x000080b0, 0x00000000},
-       {0x000080b4, 0x00000000},
-       {0x000080b8, 0x00000000},
-       {0x000080bc, 0x00000000},
-       {0x000080c0, 0x2a800000},
-       {0x000080c4, 0x06900168},
-       {0x000080c8, 0x13881c20},
-       {0x000080cc, 0x01f40000},
-       {0x000080d0, 0x00252500},
-       {0x000080d4, 0x00a00000},
-       {0x000080d8, 0x00400000},
-       {0x000080dc, 0x00000000},
-       {0x000080e0, 0xffffffff},
-       {0x000080e4, 0x0000ffff},
-       {0x000080e8, 0x3f3f3f3f},
-       {0x000080ec, 0x00000000},
-       {0x000080f0, 0x00000000},
-       {0x000080f4, 0x00000000},
-       {0x000080fc, 0x00020000},
-       {0x00008100, 0x00000000},
-       {0x00008108, 0x00000052},
-       {0x0000810c, 0x00000000},
-       {0x00008110, 0x00000000},
-       {0x00008114, 0x000007ff},
-       {0x00008118, 0x000000aa},
-       {0x0000811c, 0x00003210},
-       {0x00008124, 0x00000000},
-       {0x00008128, 0x00000000},
-       {0x0000812c, 0x00000000},
-       {0x00008130, 0x00000000},
-       {0x00008134, 0x00000000},
-       {0x00008138, 0x00000000},
-       {0x0000813c, 0x0000ffff},
-       {0x00008144, 0xffffffff},
-       {0x00008168, 0x00000000},
-       {0x0000816c, 0x00000000},
-       {0x00008170, 0x18486200},
-       {0x00008174, 0x33332210},
-       {0x00008178, 0x00000000},
-       {0x0000817c, 0x00020000},
-       {0x000081c0, 0x00000000},
-       {0x000081c4, 0x33332210},
-       {0x000081c8, 0x00000000},
-       {0x000081cc, 0x00000000},
-       {0x000081d4, 0x00000000},
-       {0x000081ec, 0x00000000},
-       {0x000081f0, 0x00000000},
-       {0x000081f4, 0x00000000},
-       {0x000081f8, 0x00000000},
-       {0x000081fc, 0x00000000},
-       {0x00008240, 0x00100000},
-       {0x00008244, 0x0010f424},
-       {0x00008248, 0x00000800},
-       {0x0000824c, 0x0001e848},
-       {0x00008250, 0x00000000},
-       {0x00008254, 0x00000000},
-       {0x00008258, 0x00000000},
-       {0x0000825c, 0x40000000},
-       {0x00008260, 0x00080922},
-       {0x00008264, 0x98a00010},
-       {0x00008268, 0xffffffff},
-       {0x0000826c, 0x0000ffff},
-       {0x00008270, 0x00000000},
-       {0x00008274, 0x40000000},
-       {0x00008278, 0x003e4180},
-       {0x0000827c, 0x00000004},
-       {0x00008284, 0x0000002c},
-       {0x00008288, 0x0000002c},
-       {0x0000828c, 0x000000ff},
-       {0x00008294, 0x00000000},
-       {0x00008298, 0x00000000},
-       {0x0000829c, 0x00000000},
-       {0x00008300, 0x00000140},
-       {0x00008314, 0x00000000},
-       {0x0000831c, 0x0000010d},
-       {0x00008328, 0x00000000},
-       {0x0000832c, 0x00000007},
-       {0x00008330, 0x00000302},
-       {0x00008334, 0x00000700},
-       {0x00008338, 0x00ff0000},
-       {0x0000833c, 0x02400000},
-       {0x00008340, 0x000107ff},
-       {0x00008344, 0xaa48105b},
-       {0x00008348, 0x008f0000},
-       {0x0000835c, 0x00000000},
-       {0x00008360, 0xffffffff},
-       {0x00008364, 0xffffffff},
-       {0x00008368, 0x00000000},
-       {0x00008370, 0x00000000},
-       {0x00008374, 0x000000ff},
-       {0x00008378, 0x00000000},
-       {0x0000837c, 0x00000000},
-       {0x00008380, 0xffffffff},
-       {0x00008384, 0xffffffff},
-       {0x00008390, 0xffffffff},
-       {0x00008394, 0xffffffff},
-       {0x00008398, 0x00000000},
-       {0x0000839c, 0x00000000},
-       {0x000083a0, 0x00000000},
-       {0x000083a4, 0x0000fa14},
-       {0x000083a8, 0x000f0c00},
-       {0x000083ac, 0x33332210},
-       {0x000083b0, 0x33332210},
-       {0x000083b4, 0x33332210},
-       {0x000083b8, 0x33332210},
-       {0x000083bc, 0x00000000},
-       {0x000083c0, 0x00000000},
-       {0x000083c4, 0x00000000},
-       {0x000083c8, 0x00000000},
-       {0x000083cc, 0x00000200},
-       {0x000083d0, 0x000301ff},
-};
-
-static const u32 ar9300Common_wo_xlna_rx_gain_table_2p0[][2] = {
-       /* Addr      allmodes  */
-       {0x0000a000, 0x00010000},
-       {0x0000a004, 0x00030002},
-       {0x0000a008, 0x00050004},
-       {0x0000a00c, 0x00810080},
-       {0x0000a010, 0x00830082},
-       {0x0000a014, 0x01810180},
-       {0x0000a018, 0x01830182},
-       {0x0000a01c, 0x01850184},
-       {0x0000a020, 0x01890188},
-       {0x0000a024, 0x018b018a},
-       {0x0000a028, 0x018d018c},
-       {0x0000a02c, 0x03820190},
-       {0x0000a030, 0x03840383},
-       {0x0000a034, 0x03880385},
-       {0x0000a038, 0x038a0389},
-       {0x0000a03c, 0x038c038b},
-       {0x0000a040, 0x0390038d},
-       {0x0000a044, 0x03920391},
-       {0x0000a048, 0x03940393},
-       {0x0000a04c, 0x03960395},
-       {0x0000a050, 0x00000000},
-       {0x0000a054, 0x00000000},
-       {0x0000a058, 0x00000000},
-       {0x0000a05c, 0x00000000},
-       {0x0000a060, 0x00000000},
-       {0x0000a064, 0x00000000},
-       {0x0000a068, 0x00000000},
-       {0x0000a06c, 0x00000000},
-       {0x0000a070, 0x00000000},
-       {0x0000a074, 0x00000000},
-       {0x0000a078, 0x00000000},
-       {0x0000a07c, 0x00000000},
-       {0x0000a080, 0x29292929},
-       {0x0000a084, 0x29292929},
-       {0x0000a088, 0x29292929},
-       {0x0000a08c, 0x29292929},
-       {0x0000a090, 0x22292929},
-       {0x0000a094, 0x1d1d2222},
-       {0x0000a098, 0x0c111117},
-       {0x0000a09c, 0x00030303},
-       {0x0000a0a0, 0x00000000},
-       {0x0000a0a4, 0x00000000},
-       {0x0000a0a8, 0x00000000},
-       {0x0000a0ac, 0x00000000},
-       {0x0000a0b0, 0x00000000},
-       {0x0000a0b4, 0x00000000},
-       {0x0000a0b8, 0x00000000},
-       {0x0000a0bc, 0x00000000},
-       {0x0000a0c0, 0x001f0000},
-       {0x0000a0c4, 0x01000101},
-       {0x0000a0c8, 0x011e011f},
-       {0x0000a0cc, 0x011c011d},
-       {0x0000a0d0, 0x02030204},
-       {0x0000a0d4, 0x02010202},
-       {0x0000a0d8, 0x021f0200},
-       {0x0000a0dc, 0x0302021e},
-       {0x0000a0e0, 0x03000301},
-       {0x0000a0e4, 0x031e031f},
-       {0x0000a0e8, 0x0402031d},
-       {0x0000a0ec, 0x04000401},
-       {0x0000a0f0, 0x041e041f},
-       {0x0000a0f4, 0x0502041d},
-       {0x0000a0f8, 0x05000501},
-       {0x0000a0fc, 0x051e051f},
-       {0x0000a100, 0x06010602},
-       {0x0000a104, 0x061f0600},
-       {0x0000a108, 0x061d061e},
-       {0x0000a10c, 0x07020703},
-       {0x0000a110, 0x07000701},
-       {0x0000a114, 0x00000000},
-       {0x0000a118, 0x00000000},
-       {0x0000a11c, 0x00000000},
-       {0x0000a120, 0x00000000},
-       {0x0000a124, 0x00000000},
-       {0x0000a128, 0x00000000},
-       {0x0000a12c, 0x00000000},
-       {0x0000a130, 0x00000000},
-       {0x0000a134, 0x00000000},
-       {0x0000a138, 0x00000000},
-       {0x0000a13c, 0x00000000},
-       {0x0000a140, 0x001f0000},
-       {0x0000a144, 0x01000101},
-       {0x0000a148, 0x011e011f},
-       {0x0000a14c, 0x011c011d},
-       {0x0000a150, 0x02030204},
-       {0x0000a154, 0x02010202},
-       {0x0000a158, 0x021f0200},
-       {0x0000a15c, 0x0302021e},
-       {0x0000a160, 0x03000301},
-       {0x0000a164, 0x031e031f},
-       {0x0000a168, 0x0402031d},
-       {0x0000a16c, 0x04000401},
-       {0x0000a170, 0x041e041f},
-       {0x0000a174, 0x0502041d},
-       {0x0000a178, 0x05000501},
-       {0x0000a17c, 0x051e051f},
-       {0x0000a180, 0x06010602},
-       {0x0000a184, 0x061f0600},
-       {0x0000a188, 0x061d061e},
-       {0x0000a18c, 0x07020703},
-       {0x0000a190, 0x07000701},
-       {0x0000a194, 0x00000000},
-       {0x0000a198, 0x00000000},
-       {0x0000a19c, 0x00000000},
-       {0x0000a1a0, 0x00000000},
-       {0x0000a1a4, 0x00000000},
-       {0x0000a1a8, 0x00000000},
-       {0x0000a1ac, 0x00000000},
-       {0x0000a1b0, 0x00000000},
-       {0x0000a1b4, 0x00000000},
-       {0x0000a1b8, 0x00000000},
-       {0x0000a1bc, 0x00000000},
-       {0x0000a1c0, 0x00000000},
-       {0x0000a1c4, 0x00000000},
-       {0x0000a1c8, 0x00000000},
-       {0x0000a1cc, 0x00000000},
-       {0x0000a1d0, 0x00000000},
-       {0x0000a1d4, 0x00000000},
-       {0x0000a1d8, 0x00000000},
-       {0x0000a1dc, 0x00000000},
-       {0x0000a1e0, 0x00000000},
-       {0x0000a1e4, 0x00000000},
-       {0x0000a1e8, 0x00000000},
-       {0x0000a1ec, 0x00000000},
-       {0x0000a1f0, 0x00000396},
-       {0x0000a1f4, 0x00000396},
-       {0x0000a1f8, 0x00000396},
-       {0x0000a1fc, 0x00000196},
-       {0x0000b000, 0x00010000},
-       {0x0000b004, 0x00030002},
-       {0x0000b008, 0x00050004},
-       {0x0000b00c, 0x00810080},
-       {0x0000b010, 0x00830082},
-       {0x0000b014, 0x01810180},
-       {0x0000b018, 0x01830182},
-       {0x0000b01c, 0x01850184},
-       {0x0000b020, 0x02810280},
-       {0x0000b024, 0x02830282},
-       {0x0000b028, 0x02850284},
-       {0x0000b02c, 0x02890288},
-       {0x0000b030, 0x028b028a},
-       {0x0000b034, 0x0388028c},
-       {0x0000b038, 0x038a0389},
-       {0x0000b03c, 0x038c038b},
-       {0x0000b040, 0x0390038d},
-       {0x0000b044, 0x03920391},
-       {0x0000b048, 0x03940393},
-       {0x0000b04c, 0x03960395},
-       {0x0000b050, 0x00000000},
-       {0x0000b054, 0x00000000},
-       {0x0000b058, 0x00000000},
-       {0x0000b05c, 0x00000000},
-       {0x0000b060, 0x00000000},
-       {0x0000b064, 0x00000000},
-       {0x0000b068, 0x00000000},
-       {0x0000b06c, 0x00000000},
-       {0x0000b070, 0x00000000},
-       {0x0000b074, 0x00000000},
-       {0x0000b078, 0x00000000},
-       {0x0000b07c, 0x00000000},
-       {0x0000b080, 0x32323232},
-       {0x0000b084, 0x2f2f3232},
-       {0x0000b088, 0x23282a2d},
-       {0x0000b08c, 0x1c1e2123},
-       {0x0000b090, 0x14171919},
-       {0x0000b094, 0x0e0e1214},
-       {0x0000b098, 0x03050707},
-       {0x0000b09c, 0x00030303},
-       {0x0000b0a0, 0x00000000},
-       {0x0000b0a4, 0x00000000},
-       {0x0000b0a8, 0x00000000},
-       {0x0000b0ac, 0x00000000},
-       {0x0000b0b0, 0x00000000},
-       {0x0000b0b4, 0x00000000},
-       {0x0000b0b8, 0x00000000},
-       {0x0000b0bc, 0x00000000},
-       {0x0000b0c0, 0x003f0020},
-       {0x0000b0c4, 0x00400041},
-       {0x0000b0c8, 0x0140005f},
-       {0x0000b0cc, 0x0160015f},
-       {0x0000b0d0, 0x017e017f},
-       {0x0000b0d4, 0x02410242},
-       {0x0000b0d8, 0x025f0240},
-       {0x0000b0dc, 0x027f0260},
-       {0x0000b0e0, 0x0341027e},
-       {0x0000b0e4, 0x035f0340},
-       {0x0000b0e8, 0x037f0360},
-       {0x0000b0ec, 0x04400441},
-       {0x0000b0f0, 0x0460045f},
-       {0x0000b0f4, 0x0541047f},
-       {0x0000b0f8, 0x055f0540},
-       {0x0000b0fc, 0x057f0560},
-       {0x0000b100, 0x06400641},
-       {0x0000b104, 0x0660065f},
-       {0x0000b108, 0x067e067f},
-       {0x0000b10c, 0x07410742},
-       {0x0000b110, 0x075f0740},
-       {0x0000b114, 0x077f0760},
-       {0x0000b118, 0x07800781},
-       {0x0000b11c, 0x07a0079f},
-       {0x0000b120, 0x07c107bf},
-       {0x0000b124, 0x000007c0},
-       {0x0000b128, 0x00000000},
-       {0x0000b12c, 0x00000000},
-       {0x0000b130, 0x00000000},
-       {0x0000b134, 0x00000000},
-       {0x0000b138, 0x00000000},
-       {0x0000b13c, 0x00000000},
-       {0x0000b140, 0x003f0020},
-       {0x0000b144, 0x00400041},
-       {0x0000b148, 0x0140005f},
-       {0x0000b14c, 0x0160015f},
-       {0x0000b150, 0x017e017f},
-       {0x0000b154, 0x02410242},
-       {0x0000b158, 0x025f0240},
-       {0x0000b15c, 0x027f0260},
-       {0x0000b160, 0x0341027e},
-       {0x0000b164, 0x035f0340},
-       {0x0000b168, 0x037f0360},
-       {0x0000b16c, 0x04400441},
-       {0x0000b170, 0x0460045f},
-       {0x0000b174, 0x0541047f},
-       {0x0000b178, 0x055f0540},
-       {0x0000b17c, 0x057f0560},
-       {0x0000b180, 0x06400641},
-       {0x0000b184, 0x0660065f},
-       {0x0000b188, 0x067e067f},
-       {0x0000b18c, 0x07410742},
-       {0x0000b190, 0x075f0740},
-       {0x0000b194, 0x077f0760},
-       {0x0000b198, 0x07800781},
-       {0x0000b19c, 0x07a0079f},
-       {0x0000b1a0, 0x07c107bf},
-       {0x0000b1a4, 0x000007c0},
-       {0x0000b1a8, 0x00000000},
-       {0x0000b1ac, 0x00000000},
-       {0x0000b1b0, 0x00000000},
-       {0x0000b1b4, 0x00000000},
-       {0x0000b1b8, 0x00000000},
-       {0x0000b1bc, 0x00000000},
-       {0x0000b1c0, 0x00000000},
-       {0x0000b1c4, 0x00000000},
-       {0x0000b1c8, 0x00000000},
-       {0x0000b1cc, 0x00000000},
-       {0x0000b1d0, 0x00000000},
-       {0x0000b1d4, 0x00000000},
-       {0x0000b1d8, 0x00000000},
-       {0x0000b1dc, 0x00000000},
-       {0x0000b1e0, 0x00000000},
-       {0x0000b1e4, 0x00000000},
-       {0x0000b1e8, 0x00000000},
-       {0x0000b1ec, 0x00000000},
-       {0x0000b1f0, 0x00000396},
-       {0x0000b1f4, 0x00000396},
-       {0x0000b1f8, 0x00000396},
-       {0x0000b1fc, 0x00000196},
-};
-
-static const u32 ar9300_2p0_soc_preamble[][2] = {
-       /* Addr      allmodes  */
-       {0x000040a4, 0x00a0c1c9},
-       {0x00007008, 0x00000000},
-       {0x00007020, 0x00000000},
-       {0x00007034, 0x00000002},
-       {0x00007038, 0x000004c2},
-};
-
-static const u32 ar9300PciePhy_pll_on_clkreq_disable_L1_2p0[][2] = {
-       /* Addr      allmodes  */
-       {0x00004040, 0x08212e5e},
-       {0x00004040, 0x0008003b},
-       {0x00004044, 0x00000000},
-};
-
-static const u32 ar9300PciePhy_clkreq_enable_L1_2p0[][2] = {
-       /* Addr      allmodes  */
-       {0x00004040, 0x08253e5e},
-       {0x00004040, 0x0008003b},
-       {0x00004044, 0x00000000},
-};
-
-static const u32 ar9300PciePhy_clkreq_disable_L1_2p0[][2] = {
-       /* Addr      allmodes  */
-       {0x00004040, 0x08213e5e},
-       {0x00004040, 0x0008003b},
-       {0x00004044, 0x00000000},
-};
-
-#endif /* INITVALS_9003_2P0_H */
index 02c970819f794015a693cd7a7fda1bc391cd0d0f..c2a057156bfa19c7c9db6862bb3233254fb0d452 100644 (file)
@@ -16,7 +16,6 @@
 
 #include "hw.h"
 #include "ar9003_mac.h"
-#include "ar9003_2p0_initvals.h"
 #include "ar9003_2p2_initvals.h"
 
 /* General hardware code for the AR9003 hadware family */
@@ -32,79 +31,12 @@ static bool ar9003_hw_macversion_supported(u32 macversion)
        return false;
 }
 
-/* AR9003 2.0 */
-static void ar9003_2p0_hw_init_mode_regs(struct ath_hw *ah)
-{
-       /* mac */
-       INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
-       INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
-                      ar9300_2p0_mac_core,
-                      ARRAY_SIZE(ar9300_2p0_mac_core), 2);
-       INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
-                      ar9300_2p0_mac_postamble,
-                      ARRAY_SIZE(ar9300_2p0_mac_postamble), 5);
-
-       /* bb */
-       INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
-       INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
-                      ar9300_2p0_baseband_core,
-                      ARRAY_SIZE(ar9300_2p0_baseband_core), 2);
-       INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
-                      ar9300_2p0_baseband_postamble,
-                      ARRAY_SIZE(ar9300_2p0_baseband_postamble), 5);
-
-       /* radio */
-       INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
-       INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
-                      ar9300_2p0_radio_core,
-                      ARRAY_SIZE(ar9300_2p0_radio_core), 2);
-       INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
-                      ar9300_2p0_radio_postamble,
-                      ARRAY_SIZE(ar9300_2p0_radio_postamble), 5);
-
-       /* soc */
-       INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
-                      ar9300_2p0_soc_preamble,
-                      ARRAY_SIZE(ar9300_2p0_soc_preamble), 2);
-       INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
-       INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
-                      ar9300_2p0_soc_postamble,
-                      ARRAY_SIZE(ar9300_2p0_soc_postamble), 5);
-
-       /* rx/tx gain */
-       INIT_INI_ARRAY(&ah->iniModesRxGain,
-                      ar9300Common_rx_gain_table_2p0,
-                      ARRAY_SIZE(ar9300Common_rx_gain_table_2p0), 2);
-       INIT_INI_ARRAY(&ah->iniModesTxGain,
-                      ar9300Modes_lowest_ob_db_tx_gain_table_2p0,
-                      ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p0),
-                      5);
-
-       /* Load PCIE SERDES settings from INI */
-
-       /* Awake Setting */
-
-       INIT_INI_ARRAY(&ah->iniPcieSerdes,
-                      ar9300PciePhy_pll_on_clkreq_disable_L1_2p0,
-                      ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p0),
-                      2);
-
-       /* Sleep Setting */
-
-       INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
-                      ar9300PciePhy_clkreq_enable_L1_2p0,
-                      ARRAY_SIZE(ar9300PciePhy_clkreq_enable_L1_2p0),
-                      2);
-
-       /* Fast clock modal settings */
-       INIT_INI_ARRAY(&ah->iniModesAdditional,
-                      ar9300Modes_fast_clock_2p0,
-                      ARRAY_SIZE(ar9300Modes_fast_clock_2p0),
-                      3);
-}
-
-/* AR9003 2.2 */
-static void ar9003_2p2_hw_init_mode_regs(struct ath_hw *ah)
+/*
+ * The AR9003 family uses a new INI format (pre, core, post
+ * arrays per subsystem). This provides support for the
+ * AR9003 2.2 chipsets.
+ */
+static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
 {
        /* mac */
        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)
                       3);
 }
 
-/*
- * The AR9003 family uses a new INI format (pre, core, post
- * arrays per subsystem).
- */
-static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
-{
-       if (AR_SREV_9300_20(ah))
-               ar9003_2p0_hw_init_mode_regs(ah);
-       else
-               ar9003_2p2_hw_init_mode_regs(ah);
-}
-
 static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
 {
        switch (ar9003_hw_get_tx_gain_idx(ah)) {
        case 0:
        default:
-               if (AR_SREV_9300_20(ah))
-                       INIT_INI_ARRAY(&ah->iniModesTxGain,
-                                      ar9300Modes_lowest_ob_db_tx_gain_table_2p0,
-                                      ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p0),
-                                      5);
-               else
-                       INIT_INI_ARRAY(&ah->iniModesTxGain,
-                                      ar9300Modes_lowest_ob_db_tx_gain_table_2p2,
-                                      ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2),
-                                      5);
+               INIT_INI_ARRAY(&ah->iniModesTxGain,
+                              ar9300Modes_lowest_ob_db_tx_gain_table_2p2,
+                              ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2),
+                              5);
                break;
        case 1:
-               if (AR_SREV_9300_20(ah))
-                       INIT_INI_ARRAY(&ah->iniModesTxGain,
-                                      ar9300Modes_high_ob_db_tx_gain_table_2p0,
-                                      ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p0),
-                                      5);
-               else
-                       INIT_INI_ARRAY(&ah->iniModesTxGain,
-                                      ar9300Modes_high_ob_db_tx_gain_table_2p2,
-                                      ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p2),
-                                      5);
+               INIT_INI_ARRAY(&ah->iniModesTxGain,
+                              ar9300Modes_high_ob_db_tx_gain_table_2p2,
+                              ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p2),
+                              5);
                break;
        case 2:
-               if (AR_SREV_9300_20(ah))
-                       INIT_INI_ARRAY(&ah->iniModesTxGain,
-                                      ar9300Modes_low_ob_db_tx_gain_table_2p0,
-                                      ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p0),
-                                      5);
-               else
-                       INIT_INI_ARRAY(&ah->iniModesTxGain,
-                                      ar9300Modes_low_ob_db_tx_gain_table_2p2,
-                                      ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p2),
-                                      5);
+               INIT_INI_ARRAY(&ah->iniModesTxGain,
+                              ar9300Modes_low_ob_db_tx_gain_table_2p2,
+                              ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p2),
+                              5);
                break;
        }
 }
@@ -234,28 +136,16 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
        switch (ar9003_hw_get_rx_gain_idx(ah)) {
        case 0:
        default:
-               if (AR_SREV_9300_20(ah))
-                       INIT_INI_ARRAY(&ah->iniModesRxGain,
-                                      ar9300Common_rx_gain_table_2p0,
-                                      ARRAY_SIZE(ar9300Common_rx_gain_table_2p0),
-                                      2);
-               else
-                       INIT_INI_ARRAY(&ah->iniModesRxGain,
-                                      ar9300Common_rx_gain_table_2p2,
-                                      ARRAY_SIZE(ar9300Common_rx_gain_table_2p2),
-                                      2);
+               INIT_INI_ARRAY(&ah->iniModesRxGain,
+                              ar9300Common_rx_gain_table_2p2,
+                              ARRAY_SIZE(ar9300Common_rx_gain_table_2p2),
+                              2);
                break;
        case 1:
-               if (AR_SREV_9300_20(ah))
-                       INIT_INI_ARRAY(&ah->iniModesRxGain,
-                                      ar9300Common_wo_xlna_rx_gain_table_2p0,
-                                      ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p0),
-                                      2);
-               else
-                       INIT_INI_ARRAY(&ah->iniModesRxGain,
-                                      ar9300Common_wo_xlna_rx_gain_table_2p2,
-                                      ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p2),
-                                      2);
+               INIT_INI_ARRAY(&ah->iniModesRxGain,
+                              ar9300Common_wo_xlna_rx_gain_table_2p2,
+                              ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p2),
+                              2);
                break;
        }
 }
index efb05599b84c52c55dff8d28d86227e170dd4575..669b777729b314161a99987812ed1b93ef16c168 100644 (file)
@@ -1254,13 +1254,12 @@ void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah)
                  "** BB mode: BB_gen_controls=0x%08x **\n",
                  REG_READ(ah, AR_PHY_GEN_CTRL));
 
-       ath9k_hw_update_cycle_counters(ah);
-#define PCT(_field) (ah->cc_delta._field * 100 / ah->cc_delta.cycles)
-       if (ah->cc_delta.cycles)
+#define PCT(_field) (common->cc_survey._field * 100 / common->cc_survey.cycles)
+       if (common->cc_survey.cycles)
                ath_print(common, ATH_DBG_RESET,
                          "** BB busy times: rx_clear=%d%%, "
                          "rx_frame=%d%%, tx_frame=%d%% **\n",
-                         PCT(rx_clear), PCT(rx_frame), PCT(tx_frame));
+                         PCT(rx_busy), PCT(rx_frame), PCT(tx_frame));
 
        ath_print(common, ATH_DBG_RESET,
                  "==== BB update: done ====\n\n");
index de2b18ee7f771eba0f66d5fb880266d5c1f1e2be..973c919fdd27f5ece00c29a023c598f9054d4f2f 100644 (file)
@@ -239,12 +239,11 @@ struct ath_buf {
        struct sk_buff *bf_mpdu;        /* enclosing frame structure */
        void *bf_desc;                  /* virtual addr of desc */
        dma_addr_t bf_daddr;            /* physical addr of desc */
-       dma_addr_t bf_buf_addr;         /* physical addr of data buffer */
+       dma_addr_t bf_buf_addr; /* physical addr of data buffer, for DMA */
        bool bf_stale;
        bool bf_tx_aborted;
        u16 bf_flags;
        struct ath_buf_state bf_state;
-       dma_addr_t bf_dmacontext;
        struct ath_wiphy *aphy;
 };
 
@@ -593,6 +592,8 @@ struct ath_softc {
        struct delayed_work wiphy_work;
        unsigned long wiphy_scheduler_int;
        int wiphy_scheduler_index;
+       struct survey_info *cur_survey;
+       struct survey_info survey[ATH9K_NUM_CHANNELS];
 
        struct tasklet_struct intr_tq;
        struct tasklet_struct bcon_tasklet;
@@ -621,8 +622,6 @@ struct ath_softc {
        struct ath_rx rx;
        struct ath_tx tx;
        struct ath_beacon beacon;
-       const struct ath_rate_table *cur_rate_table;
-       enum wireless_mode cur_rate_mode;
        struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
 
        struct ath_led radio_led;
index 081192e78a466169936bd956257b4e6348d6ae8f..4ed010d4ef96d9f3288cc9d1c81dbcd8d24e50fa 100644 (file)
@@ -136,9 +136,10 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
        bf = avp->av_bcbuf;
        skb = bf->bf_mpdu;
        if (skb) {
-               dma_unmap_single(sc->dev, bf->bf_dmacontext,
+               dma_unmap_single(sc->dev, bf->bf_buf_addr,
                                 skb->len, DMA_TO_DEVICE);
                dev_kfree_skb_any(skb);
+               bf->bf_buf_addr = 0;
        }
 
        /* Get a new beacon from mac80211 */
@@ -162,12 +163,12 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
                hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
        }
 
-       bf->bf_buf_addr = bf->bf_dmacontext =
-               dma_map_single(sc->dev, skb->data,
-                              skb->len, DMA_TO_DEVICE);
+       bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
+                                        skb->len, DMA_TO_DEVICE);
        if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) {
                dev_kfree_skb_any(skb);
                bf->bf_mpdu = NULL;
+               bf->bf_buf_addr = 0;
                ath_print(common, ATH_DBG_FATAL,
                          "dma_mapping_error on beaconing\n");
                return NULL;
@@ -252,10 +253,11 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
        bf = avp->av_bcbuf;
        if (bf->bf_mpdu != NULL) {
                skb = bf->bf_mpdu;
-               dma_unmap_single(sc->dev, bf->bf_dmacontext,
+               dma_unmap_single(sc->dev, bf->bf_buf_addr,
                                 skb->len, DMA_TO_DEVICE);
                dev_kfree_skb_any(skb);
                bf->bf_mpdu = NULL;
+               bf->bf_buf_addr = 0;
        }
 
        /* 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)
                avp->tsf_adjust = cpu_to_le64(0);
 
        bf->bf_mpdu = skb;
-       bf->bf_buf_addr = bf->bf_dmacontext =
-               dma_map_single(sc->dev, skb->data,
-                              skb->len, DMA_TO_DEVICE);
+       bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
+                                        skb->len, DMA_TO_DEVICE);
        if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) {
                dev_kfree_skb_any(skb);
                bf->bf_mpdu = NULL;
+               bf->bf_buf_addr = 0;
                ath_print(common, ATH_DBG_FATAL,
                          "dma_mapping_error on beacon alloc\n");
                return -ENOMEM;
@@ -324,10 +326,11 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp)
                bf = avp->av_bcbuf;
                if (bf->bf_mpdu != NULL) {
                        struct sk_buff *skb = bf->bf_mpdu;
-                       dma_unmap_single(sc->dev, bf->bf_dmacontext,
+                       dma_unmap_single(sc->dev, bf->bf_buf_addr,
                                         skb->len, DMA_TO_DEVICE);
                        dev_kfree_skb_any(skb);
                        bf->bf_mpdu = NULL;
+                       bf->bf_buf_addr = 0;
                }
                list_add_tail(&bf->list, &sc->beacon.bbuf);
 
index 74a4570dc87f35c066e7299be7c1d0323a5002b4..7f764e3d1c0a92d788c3bff3ede92a02a1d64e93 100644 (file)
@@ -378,95 +378,6 @@ static const struct file_operations fops_interrupt = {
        .owner = THIS_MODULE
 };
 
-void ath_debug_stat_rc(struct ath_softc *sc, int final_rate)
-{
-       struct ath_rc_stats *stats;
-
-       stats = &sc->debug.stats.rcstats[final_rate];
-       stats->success++;
-}
-
-void ath_debug_stat_retries(struct ath_softc *sc, int rix,
-                           int xretries, int retries, u8 per)
-{
-       struct ath_rc_stats *stats = &sc->debug.stats.rcstats[rix];
-
-       stats->xretries += xretries;
-       stats->retries += retries;
-       stats->per = per;
-}
-
-static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
-                               size_t count, loff_t *ppos)
-{
-       struct ath_softc *sc = file->private_data;
-       char *buf;
-       unsigned int len = 0, max;
-       int i = 0;
-       ssize_t retval;
-
-       if (sc->cur_rate_table == NULL)
-               return 0;
-
-       max = 80 + sc->cur_rate_table->rate_cnt * 1024 + 1;
-       buf = kmalloc(max, GFP_KERNEL);
-       if (buf == NULL)
-               return -ENOMEM;
-
-       len += sprintf(buf, "%6s %6s %6s "
-                      "%10s %10s %10s %10s\n",
-                      "HT", "MCS", "Rate",
-                      "Success", "Retries", "XRetries", "PER");
-
-       for (i = 0; i < sc->cur_rate_table->rate_cnt; i++) {
-               u32 ratekbps = sc->cur_rate_table->info[i].ratekbps;
-               struct ath_rc_stats *stats = &sc->debug.stats.rcstats[i];
-               char mcs[5];
-               char htmode[5];
-               int used_mcs = 0, used_htmode = 0;
-
-               if (WLAN_RC_PHY_HT(sc->cur_rate_table->info[i].phy)) {
-                       used_mcs = snprintf(mcs, 5, "%d",
-                               sc->cur_rate_table->info[i].ratecode);
-
-                       if (WLAN_RC_PHY_40(sc->cur_rate_table->info[i].phy))
-                               used_htmode = snprintf(htmode, 5, "HT40");
-                       else if (WLAN_RC_PHY_20(sc->cur_rate_table->info[i].phy))
-                               used_htmode = snprintf(htmode, 5, "HT20");
-                       else
-                               used_htmode = snprintf(htmode, 5, "????");
-               }
-
-               mcs[used_mcs] = '\0';
-               htmode[used_htmode] = '\0';
-
-               len += snprintf(buf + len, max - len,
-                       "%6s %6s %3u.%d: "
-                       "%10u %10u %10u %10u\n",
-                       htmode,
-                       mcs,
-                       ratekbps / 1000,
-                       (ratekbps % 1000) / 100,
-                       stats->success,
-                       stats->retries,
-                       stats->xretries,
-                       stats->per);
-       }
-
-       if (len > max)
-               len = max;
-
-       retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
-       kfree(buf);
-       return retval;
-}
-
-static const struct file_operations fops_rcstat = {
-       .read = read_file_rcstat,
-       .open = ath9k_debugfs_open,
-       .owner = THIS_MODULE
-};
-
 static const char * ath_wiphy_state_str(enum ath_wiphy_state state)
 {
        switch (state) {
@@ -977,10 +888,6 @@ int ath9k_init_debug(struct ath_hw *ah)
                        sc, &fops_interrupt))
                goto err;
 
-       if (!debugfs_create_file("rcstat", S_IRUSR, sc->debug.debugfs_phy,
-                       sc, &fops_rcstat))
-               goto err;
-
        if (!debugfs_create_file("wiphy", S_IRUSR | S_IWUSR,
                        sc->debug.debugfs_phy, sc, &fops_wiphy))
                goto err;
index 822b6f3f23c573467b62a563b2258d372128da1d..bb0823242ba008e0ccc4cbe0b169539ffa8c8dd3 100644 (file)
@@ -80,13 +80,6 @@ struct ath_interrupt_stats {
        u32 bb_watchdog;
 };
 
-struct ath_rc_stats {
-       u32 success;
-       u32 retries;
-       u32 xretries;
-       u8 per;
-};
-
 /**
  * struct ath_tx_stats - Statistics about TX
  * @tx_pkts_all:  No. of total frames transmitted, including ones that
@@ -160,7 +153,6 @@ struct ath_rx_stats {
 
 struct ath_stats {
        struct ath_interrupt_stats istats;
-       struct ath_rc_stats rcstats[RATE_TABLE_SIZE];
        struct ath_tx_stats txstats[ATH9K_NUM_TX_QUEUES];
        struct ath_rx_stats rxstats;
 };
@@ -177,12 +169,9 @@ void ath9k_exit_debug(struct ath_hw *ah);
 int ath9k_debug_create_root(void);
 void ath9k_debug_remove_root(void);
 void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
-void ath_debug_stat_rc(struct ath_softc *sc, int final_rate);
 void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq,
                       struct ath_buf *bf, struct ath_tx_status *ts);
 void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs);
-void ath_debug_stat_retries(struct ath_softc *sc, int rix,
-                           int xretries, int retries, u8 per);
 
 #else
 
@@ -209,11 +198,6 @@ static inline void ath_debug_stat_interrupt(struct ath_softc *sc,
 {
 }
 
-static inline void ath_debug_stat_rc(struct ath_softc *sc,
-                                    int final_rate)
-{
-}
-
 static inline void ath_debug_stat_tx(struct ath_softc *sc,
                                     struct ath_txq *txq,
                                     struct ath_buf *bf,
@@ -226,11 +210,6 @@ static inline void ath_debug_stat_rx(struct ath_softc *sc,
 {
 }
 
-static inline void ath_debug_stat_retries(struct ath_softc *sc, int rix,
-                                         int xretries, int retries, u8 per)
-{
-}
-
 #endif /* CONFIG_ATH9K_DEBUGFS */
 
 #endif /* DEBUG_H */
index bbb54bc28a44d277ccc274e10feee6195794c610..3d7b97f1b3aeebe5840c438b5ccf631de702d6c2 100644 (file)
@@ -566,7 +566,7 @@ static void ath9k_init_crypto(struct ath9k_htc_priv *priv)
 
 static void ath9k_init_channels_rates(struct ath9k_htc_priv *priv)
 {
-       if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes)) {
+       if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) {
                priv->sbands[IEEE80211_BAND_2GHZ].channels =
                        ath9k_2ghz_channels;
                priv->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
@@ -577,7 +577,7 @@ static void ath9k_init_channels_rates(struct ath9k_htc_priv *priv)
                        ARRAY_SIZE(ath9k_legacy_rates);
        }
 
-       if (test_bit(ATH9K_MODE_11A, priv->ah->caps.wireless_modes)) {
+       if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) {
                priv->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_channels;
                priv->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ;
                priv->sbands[IEEE80211_BAND_5GHZ].n_channels =
@@ -740,18 +740,18 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
        hw->extra_tx_headroom = sizeof(struct tx_frame_hdr) +
                sizeof(struct htc_frame_hdr) + 4;
 
-       if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes))
+       if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
                hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
                        &priv->sbands[IEEE80211_BAND_2GHZ];
-       if (test_bit(ATH9K_MODE_11A, priv->ah->caps.wireless_modes))
+       if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
                hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
                        &priv->sbands[IEEE80211_BAND_5GHZ];
 
        if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
-               if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes))
+               if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
                        setup_ht_cap(priv,
                                     &priv->sbands[IEEE80211_BAND_2GHZ].ht_cap);
-               if (test_bit(ATH9K_MODE_11A, priv->ah->caps.wireless_modes))
+               if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
                        setup_ht_cap(priv,
                                     &priv->sbands[IEEE80211_BAND_5GHZ].ht_cap);
        }
index f12591f5d02aa4e7bb792ee944b6932355f9e1e2..55c80866dfc6dcbbcd9af6d1ee06e237b7733aa8 100644 (file)
@@ -1454,6 +1454,7 @@ out:
        FIF_PSPOLL |                            \
        FIF_OTHER_BSS |                         \
        FIF_BCN_PRBRESP_PROMISC |               \
+       FIF_PROBE_REQ |                         \
        FIF_FCSFAIL)
 
 static void ath9k_htc_configure_filter(struct ieee80211_hw *hw,
index c99600aff76d463f9caa531a1d64b1e4504c12a7..3d19b5bc937f9c1c285e23645fcbf6a929037b21 100644 (file)
@@ -369,8 +369,7 @@ u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv)
                | ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST
                | ATH9K_RX_FILTER_MCAST;
 
-       /* If not a STA, enable processing of Probe Requests */
-       if (ah->opmode != NL80211_IFTYPE_STATION)
+       if (priv->rxfilter & FIF_PROBE_REQ)
                rfilt |= ATH9K_RX_FILTER_PROBEREQ;
 
        /*
index 05e9935ef1602326e9beb1d5bff776ad4c2983ba..cc13ee1178237da72617f92bf7b3a103c82e772b 100644 (file)
@@ -88,29 +88,32 @@ static void ath9k_hw_ani_cache_ini_regs(struct ath_hw *ah)
 /* Helper Functions */
 /********************/
 
-static u32 ath9k_hw_mac_clks(struct ath_hw *ah, u32 usecs)
+static void ath9k_hw_set_clockrate(struct ath_hw *ah)
 {
        struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
+       struct ath_common *common = ath9k_hw_common(ah);
+       unsigned int clockrate;
 
        if (!ah->curchan) /* should really check for CCK instead */
-               return usecs *ATH9K_CLOCK_RATE_CCK;
-       if (conf->channel->band == IEEE80211_BAND_2GHZ)
-               return usecs *ATH9K_CLOCK_RATE_2GHZ_OFDM;
-
-       if (ah->caps.hw_caps & ATH9K_HW_CAP_FASTCLOCK)
-               return usecs * ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM;
+               clockrate = ATH9K_CLOCK_RATE_CCK;
+       else if (conf->channel->band == IEEE80211_BAND_2GHZ)
+               clockrate = ATH9K_CLOCK_RATE_2GHZ_OFDM;
+       else if (ah->caps.hw_caps & ATH9K_HW_CAP_FASTCLOCK)
+               clockrate = ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM;
        else
-               return usecs * ATH9K_CLOCK_RATE_5GHZ_OFDM;
+               clockrate = ATH9K_CLOCK_RATE_5GHZ_OFDM;
+
+       if (conf_is_ht40(conf))
+               clockrate *= 2;
+
+       common->clockrate = clockrate;
 }
 
 static u32 ath9k_hw_mac_to_clks(struct ath_hw *ah, u32 usecs)
 {
-       struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
+       struct ath_common *common = ath9k_hw_common(ah);
 
-       if (conf_is_ht40(conf))
-               return ath9k_hw_mac_clks(ah, usecs) * 2;
-       else
-               return ath9k_hw_mac_clks(ah, usecs);
+       return usecs * common->clockrate;
 }
 
 bool 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,
                          "Failed to set channel\n");
                return false;
        }
+       ath9k_hw_set_clockrate(ah);
 
        ah->eep_ops->set_txpower(ah, chan,
                             ath9k_regd_get_ctl(regulatory, chan),
@@ -1368,6 +1372,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
        if (r)
                return r;
 
+       ath9k_hw_set_clockrate(ah);
+
        ENABLE_REGWRITE_BUFFER(ah);
 
        for (i = 0; i < AR_NUM_DCU; i++)
@@ -1794,37 +1800,11 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
                return -EINVAL;
        }
 
-       bitmap_zero(pCap->wireless_modes, ATH9K_MODE_MAX);
-
-       if (eeval & AR5416_OPFLAGS_11A) {
-               set_bit(ATH9K_MODE_11A, pCap->wireless_modes);
-               if (ah->config.ht_enable) {
-                       if (!(eeval & AR5416_OPFLAGS_N_5G_HT20))
-                               set_bit(ATH9K_MODE_11NA_HT20,
-                                       pCap->wireless_modes);
-                       if (!(eeval & AR5416_OPFLAGS_N_5G_HT40)) {
-                               set_bit(ATH9K_MODE_11NA_HT40PLUS,
-                                       pCap->wireless_modes);
-                               set_bit(ATH9K_MODE_11NA_HT40MINUS,
-                                       pCap->wireless_modes);
-                       }
-               }
-       }
+       if (eeval & AR5416_OPFLAGS_11A)
+               pCap->hw_caps |= ATH9K_HW_CAP_5GHZ;
 
-       if (eeval & AR5416_OPFLAGS_11G) {
-               set_bit(ATH9K_MODE_11G, pCap->wireless_modes);
-               if (ah->config.ht_enable) {
-                       if (!(eeval & AR5416_OPFLAGS_N_2G_HT20))
-                               set_bit(ATH9K_MODE_11NG_HT20,
-                                       pCap->wireless_modes);
-                       if (!(eeval & AR5416_OPFLAGS_N_2G_HT40)) {
-                               set_bit(ATH9K_MODE_11NG_HT40PLUS,
-                                       pCap->wireless_modes);
-                               set_bit(ATH9K_MODE_11NG_HT40MINUS,
-                                       pCap->wireless_modes);
-                       }
-               }
-       }
+       if (eeval & AR5416_OPFLAGS_11G)
+               pCap->hw_caps |= ATH9K_HW_CAP_2GHZ;
 
        pCap->tx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_TX_MASK);
        /*
index 87627dd634635ea5f116471940f5d3edac0eff4f..d032939768b073aa80e672641f805ac416e1ce22 100644 (file)
@@ -61,6 +61,8 @@
 
 #define ATH9K_RSSI_BAD                 -128
 
+#define ATH9K_NUM_CHANNELS     38
+
 /* Register read/write primitives */
 #define REG_WRITE(_ah, _reg, _val) \
        ath9k_hw_common(_ah)->ops->write((_ah), (_val), (_reg))
@@ -162,18 +164,6 @@ enum ath_ini_subsys {
        ATH_INI_NUM_SPLIT,
 };
 
-enum wireless_mode {
-       ATH9K_MODE_11A = 0,
-       ATH9K_MODE_11G,
-       ATH9K_MODE_11NA_HT20,
-       ATH9K_MODE_11NG_HT20,
-       ATH9K_MODE_11NA_HT40PLUS,
-       ATH9K_MODE_11NA_HT40MINUS,
-       ATH9K_MODE_11NG_HT40PLUS,
-       ATH9K_MODE_11NG_HT40MINUS,
-       ATH9K_MODE_MAX,
-};
-
 enum ath9k_hw_caps {
        ATH9K_HW_CAP_HT                         = BIT(0),
        ATH9K_HW_CAP_RFSILENT                   = BIT(1),
@@ -188,11 +178,12 @@ enum ath9k_hw_caps {
        ATH9K_HW_CAP_SGI_20                     = BIT(10),
        ATH9K_HW_CAP_PAPRD                      = BIT(11),
        ATH9K_HW_CAP_ANT_DIV_COMB               = BIT(12),
+       ATH9K_HW_CAP_2GHZ                       = BIT(13),
+       ATH9K_HW_CAP_5GHZ                       = BIT(14),
 };
 
 struct ath9k_hw_capabilities {
        u32 hw_caps; /* ATH9K_HW_CAP_* from ath9k_hw_caps */
-       DECLARE_BITMAP(wireless_modes, ATH9K_MODE_MAX); /* ATH9K_MODE_* */
        u16 total_queues;
        u16 keycache_size;
        u16 low_5ghz_chan, high_5ghz_chan;
@@ -618,7 +609,7 @@ struct ath_hw {
        struct ath9k_hw_version hw_version;
        struct ath9k_ops_config config;
        struct ath9k_hw_capabilities caps;
-       struct ath9k_channel channels[38];
+       struct ath9k_channel channels[ATH9K_NUM_CHANNELS];
        struct ath9k_channel *curchan;
 
        union {
@@ -740,8 +731,6 @@ struct ath_hw {
        int coarse_low[5];
        int firpwr[5];
        enum ath9k_ani_cmd ani_function;
-       struct ath_cycle_counters cc, cc_delta;
-       int32_t listen_time;
 
        /* Bluetooth coexistance */
        struct ath_btcoex_hw btcoex_hw;
index d76003c06fe4dc1a53be4b82a9010213a1bcf7ad..bc6c4df9712c5b921041fdc7d1f49a1214a5a091 100644 (file)
@@ -481,7 +481,11 @@ static int ath9k_init_channels_rates(struct ath_softc *sc)
 {
        void *channels;
 
-       if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) {
+       BUILD_BUG_ON(ARRAY_SIZE(ath9k_2ghz_chantable) +
+                    ARRAY_SIZE(ath9k_5ghz_chantable) !=
+                    ATH9K_NUM_CHANNELS);
+
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) {
                channels = kmemdup(ath9k_2ghz_chantable,
                        sizeof(ath9k_2ghz_chantable), GFP_KERNEL);
                if (!channels)
@@ -496,7 +500,7 @@ static int ath9k_init_channels_rates(struct ath_softc *sc)
                        ARRAY_SIZE(ath9k_legacy_rates);
        }
 
-       if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) {
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) {
                channels = kmemdup(ath9k_5ghz_chantable,
                        sizeof(ath9k_5ghz_chantable), GFP_KERNEL);
                if (!channels) {
@@ -677,17 +681,17 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
        hw->rate_control_algorithm = "ath9k_rate_control";
 #endif
 
-       if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes))
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
                hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
                        &sc->sbands[IEEE80211_BAND_2GHZ];
-       if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes))
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
                hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
                        &sc->sbands[IEEE80211_BAND_5GHZ];
 
        if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
-               if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes))
+               if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
                        setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap);
-               if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes))
+               if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
                        setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap);
        }
 
index 74c2dc8a8b8ac4978a5381ecad40ba1f6c275aed..3ff0e476c2b3d7ad4cc209360042c6c5097d87a8 100644 (file)
 #include "ath9k.h"
 #include "btcoex.h"
 
-static void ath_cache_conf_rate(struct ath_softc *sc,
-                               struct ieee80211_conf *conf)
-{
-       switch (conf->channel->band) {
-       case IEEE80211_BAND_2GHZ:
-               if (conf_is_ht20(conf))
-                       sc->cur_rate_mode = ATH9K_MODE_11NG_HT20;
-               else if (conf_is_ht40_minus(conf))
-                       sc->cur_rate_mode = ATH9K_MODE_11NG_HT40MINUS;
-               else if (conf_is_ht40_plus(conf))
-                       sc->cur_rate_mode = ATH9K_MODE_11NG_HT40PLUS;
-               else
-                       sc->cur_rate_mode = ATH9K_MODE_11G;
-               break;
-       case IEEE80211_BAND_5GHZ:
-               if (conf_is_ht20(conf))
-                       sc->cur_rate_mode = ATH9K_MODE_11NA_HT20;
-               else if (conf_is_ht40_minus(conf))
-                       sc->cur_rate_mode = ATH9K_MODE_11NA_HT40MINUS;
-               else if (conf_is_ht40_plus(conf))
-                       sc->cur_rate_mode = ATH9K_MODE_11NA_HT40PLUS;
-               else
-                       sc->cur_rate_mode = ATH9K_MODE_11A;
-               break;
-       default:
-               BUG_ON(1);
-               break;
-       }
-}
-
 static void ath_update_txpow(struct ath_softc *sc)
 {
        struct ath_hw *ah = sc->sc_ah;
@@ -121,6 +91,7 @@ bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode)
 
 void ath9k_ps_wakeup(struct ath_softc *sc)
 {
+       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
        unsigned long flags;
 
        spin_lock_irqsave(&sc->sc_pm_lock, flags);
@@ -129,18 +100,33 @@ void ath9k_ps_wakeup(struct ath_softc *sc)
 
        ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
 
+       /*
+        * While the hardware is asleep, the cycle counters contain no
+        * useful data. Better clear them now so that they don't mess up
+        * survey data results.
+        */
+       spin_lock(&common->cc_lock);
+       ath_hw_cycle_counters_update(common);
+       memset(&common->cc_survey, 0, sizeof(common->cc_survey));
+       spin_unlock(&common->cc_lock);
+
  unlock:
        spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
 }
 
 void ath9k_ps_restore(struct ath_softc *sc)
 {
+       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
        unsigned long flags;
 
        spin_lock_irqsave(&sc->sc_pm_lock, flags);
        if (--sc->ps_usecount != 0)
                goto unlock;
 
+       spin_lock(&common->cc_lock);
+       ath_hw_cycle_counters_update(common);
+       spin_unlock(&common->cc_lock);
+
        if (sc->ps_idle)
                ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP);
        else if (sc->ps_enabled &&
@@ -175,6 +161,45 @@ static void ath_start_ani(struct ath_common *common)
                        msecs_to_jiffies((u32)ah->config.ani_poll_interval));
 }
 
+static void ath_update_survey_nf(struct ath_softc *sc, int channel)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath9k_channel *chan = &ah->channels[channel];
+       struct survey_info *survey = &sc->survey[channel];
+
+       if (chan->noisefloor) {
+               survey->filled |= SURVEY_INFO_NOISE_DBM;
+               survey->noise = chan->noisefloor;
+       }
+}
+
+static void ath_update_survey_stats(struct ath_softc *sc)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_common *common = ath9k_hw_common(ah);
+       int pos = ah->curchan - &ah->channels[0];
+       struct survey_info *survey = &sc->survey[pos];
+       struct ath_cycle_counters *cc = &common->cc_survey;
+       unsigned int div = common->clockrate * 1000;
+
+       if (ah->power_mode == ATH9K_PM_AWAKE)
+               ath_hw_cycle_counters_update(common);
+
+       if (cc->cycles > 0) {
+               survey->filled |= SURVEY_INFO_CHANNEL_TIME |
+                       SURVEY_INFO_CHANNEL_TIME_BUSY |
+                       SURVEY_INFO_CHANNEL_TIME_RX |
+                       SURVEY_INFO_CHANNEL_TIME_TX;
+               survey->channel_time += cc->cycles / div;
+               survey->channel_time_busy += cc->rx_busy / div;
+               survey->channel_time_rx += cc->rx_frame / div;
+               survey->channel_time_tx += cc->tx_frame / div;
+       }
+       memset(cc, 0, sizeof(*cc));
+
+       ath_update_survey_nf(sc, pos);
+}
+
 /*
  * Set/change channels.  If the channel is really being changed, it's done
  * 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,
                goto ps_restore;
        }
 
-       ath_cache_conf_rate(sc, &hw->conf);
        ath_update_txpow(sc);
        ath9k_hw_set_interrupts(ah, ah->imask);
 
@@ -399,6 +423,7 @@ void ath_ani_calibrate(unsigned long data)
        bool aniflag = false;
        unsigned int timestamp = jiffies_to_msecs(jiffies);
        u32 cal_interval, short_cal_interval, long_cal_interval;
+       unsigned long flags;
 
        if (ah->caldata && ah->caldata->nfcal_interference)
                long_cal_interval = ATH_LONG_CALINTERVAL_INT;
@@ -449,8 +474,12 @@ void ath_ani_calibrate(unsigned long data)
        /* Skip all processing if there's nothing to do. */
        if (longcal || shortcal || aniflag) {
                /* Call ANI routine if necessary */
-               if (aniflag)
+               if (aniflag) {
+                       spin_lock_irqsave(&common->cc_lock, flags);
                        ath9k_hw_ani_monitor(ah, ah->curchan);
+                       ath_update_survey_stats(sc);
+                       spin_unlock_irqrestore(&common->cc_lock, flags);
+               }
 
                /* Perform calibration if necessary */
                if (longcal || shortcal) {
@@ -635,6 +664,7 @@ irqreturn_t ath_isr(int irq, void *dev)
 
        struct ath_softc *sc = dev;
        struct ath_hw *ah = sc->sc_ah;
+       struct ath_common *common = ath9k_hw_common(ah);
        enum ath9k_int status;
        bool sched = false;
 
@@ -684,7 +714,12 @@ irqreturn_t ath_isr(int irq, void *dev)
 
        if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) &&
            (status & ATH9K_INT_BB_WATCHDOG)) {
+
+               spin_lock(&common->cc_lock);
+               ath_hw_cycle_counters_update(common);
                ar9003_hw_bb_watchdog_dbg_info(ah);
+               spin_unlock(&common->cc_lock);
+
                goto chip_reset;
        }
 
@@ -713,7 +748,9 @@ irqreturn_t ath_isr(int irq, void *dev)
                 * it will clear whatever condition caused
                 * the interrupt.
                 */
+               spin_lock(&common->cc_lock);
                ath9k_hw_proc_mib_event(ah);
+               spin_unlock(&common->cc_lock);
                ath9k_hw_set_interrupts(ah, ah->imask);
        }
 
@@ -945,8 +982,6 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
         * that changes the channel so update any state that
         * might change as a result.
         */
-       ath_cache_conf_rate(sc, &hw->conf);
-
        ath_update_txpow(sc);
 
        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)
        if (ah->caps.hw_caps & ATH9K_HW_CAP_HT)
                ah->imask |= ATH9K_INT_CST;
 
-       ath_cache_conf_rate(sc, &hw->conf);
-
        sc->sc_flags &= ~SC_OP_INVALID;
 
        /* Disable BMISS interrupt when we're not associated */
@@ -1522,7 +1555,8 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
 {
        struct ath_wiphy *aphy = hw->priv;
        struct ath_softc *sc = aphy->sc;
-       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_common *common = ath9k_hw_common(ah);
        struct ieee80211_conf *conf = &hw->conf;
        bool disable_radio;
 
@@ -1588,6 +1622,11 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
        if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
                struct ieee80211_channel *curchan = hw->conf.channel;
                int pos = curchan->hw_value;
+               int old_pos = -1;
+               unsigned long flags;
+
+               if (ah->curchan)
+                       old_pos = ah->curchan - &ah->channels[0];
 
                aphy->chan_idx = pos;
                aphy->chan_is_ht = conf_is_ht(conf);
@@ -1615,12 +1654,45 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
 
                ath_update_chainmask(sc, conf_is_ht(conf));
 
+               /* update survey stats for the old channel before switching */
+               spin_lock_irqsave(&common->cc_lock, flags);
+               ath_update_survey_stats(sc);
+               spin_unlock_irqrestore(&common->cc_lock, flags);
+
+               /*
+                * If the operating channel changes, change the survey in-use flags
+                * along with it.
+                * Reset the survey data for the new channel, unless we're switching
+                * back to the operating channel from an off-channel operation.
+                */
+               if (!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) &&
+                   sc->cur_survey != &sc->survey[pos]) {
+
+                       if (sc->cur_survey)
+                               sc->cur_survey->filled &= ~SURVEY_INFO_IN_USE;
+
+                       sc->cur_survey = &sc->survey[pos];
+
+                       memset(sc->cur_survey, 0, sizeof(struct survey_info));
+                       sc->cur_survey->filled |= SURVEY_INFO_IN_USE;
+               } else if (!(sc->survey[pos].filled & SURVEY_INFO_IN_USE)) {
+                       memset(&sc->survey[pos], 0, sizeof(struct survey_info));
+               }
+
                if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) {
                        ath_print(common, ATH_DBG_FATAL,
                                  "Unable to set channel\n");
                        mutex_unlock(&sc->mutex);
                        return -EINVAL;
                }
+
+               /*
+                * The most recent snapshot of channel->noisefloor for the old
+                * channel is only available after the hardware reset. Copy it to
+                * the survey stats now.
+                */
+               if (old_pos >= 0)
+                       ath_update_survey_nf(sc, old_pos);
        }
 
 skip_chan_change:
@@ -1651,6 +1723,7 @@ skip_chan_change:
        FIF_PSPOLL |                            \
        FIF_OTHER_BSS |                         \
        FIF_BCN_PRBRESP_PROMISC |               \
+       FIF_PROBE_REQ |                         \
        FIF_FCSFAIL)
 
 /* FIXME: sc->sc_full_reset ? */
@@ -1990,9 +2063,15 @@ static int ath9k_get_survey(struct ieee80211_hw *hw, int idx,
 {
        struct ath_wiphy *aphy = hw->priv;
        struct ath_softc *sc = aphy->sc;
-       struct ath_hw *ah = sc->sc_ah;
+       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
        struct ieee80211_supported_band *sband;
-       struct ath9k_channel *chan;
+       struct ieee80211_channel *chan;
+       unsigned long flags;
+       int pos;
+
+       spin_lock_irqsave(&common->cc_lock, flags);
+       if (idx == 0)
+               ath_update_survey_stats(sc);
 
        sband = hw->wiphy->bands[IEEE80211_BAND_2GHZ];
        if (sband && idx >= sband->n_channels) {
@@ -2003,21 +2082,17 @@ static int ath9k_get_survey(struct ieee80211_hw *hw, int idx,
        if (!sband)
                sband = hw->wiphy->bands[IEEE80211_BAND_5GHZ];
 
-       if (!sband || idx >= sband->n_channels)
-           return -ENOENT;
-
-       survey->channel = &sband->channels[idx];
-       chan = &ah->channels[survey->channel->hw_value];
-       survey->filled = 0;
-
-       if (chan == ah->curchan)
-               survey->filled |= SURVEY_INFO_IN_USE;
-
-       if (chan->noisefloor) {
-               survey->filled |= SURVEY_INFO_NOISE_DBM;
-               survey->noise = chan->noisefloor;
+       if (!sband || idx >= sband->n_channels) {
+               spin_unlock_irqrestore(&common->cc_lock, flags);
+               return -ENOENT;
        }
 
+       chan = &sband->channels[idx];
+       pos = chan->hw_value;
+       memcpy(survey, &sc->survey[pos], sizeof(*survey));
+       survey->channel = chan;
+       spin_unlock_irqrestore(&common->cc_lock, flags);
+
        return 0;
 }
 
index ce1cd6d858474f76f6ceebe20af14416346f29ed..0cee90cf8dc9dcb4529db6e783a10f2cc819161a 100644 (file)
@@ -302,7 +302,7 @@ static const struct ath_rate_table ar5416_11ng_ratetable = {
                [64] = {  RC_INVALID, WLAN_RC_PHY_HT_40_TS, 243000,
                        205100, 20, 20, 8, 64, 65, 65 }, /* 243 Mb */
                [65] = {  RC_INVALID, WLAN_RC_PHY_HT_40_TS_HGI, 270000,
-                       224700, 20, 20, 8, 64, 65, 65 }, /* 170 Mb */
+                       224700, 20, 20, 8, 64, 65, 65 }, /* 270 Mb */
                [66] = {  RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 324000,
                        263100, 21, 21, 8, 66, 67, 67 }, /* 324 Mb */
                [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 = {
        0,   /* Phy rates allowed initially */
 };
 
-static const struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX] = {
-       [ATH9K_MODE_11A] = &ar5416_11a_ratetable,
-       [ATH9K_MODE_11G] = &ar5416_11g_ratetable,
-       [ATH9K_MODE_11NA_HT20] = &ar5416_11na_ratetable,
-       [ATH9K_MODE_11NG_HT20] = &ar5416_11ng_ratetable,
-       [ATH9K_MODE_11NA_HT40PLUS] = &ar5416_11na_ratetable,
-       [ATH9K_MODE_11NA_HT40MINUS] = &ar5416_11na_ratetable,
-       [ATH9K_MODE_11NG_HT40PLUS] = &ar5416_11ng_ratetable,
-       [ATH9K_MODE_11NG_HT40MINUS] = &ar5416_11ng_ratetable,
-};
-
 static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table,
                                struct ieee80211_tx_rate *rate);
 
@@ -791,7 +780,7 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
         */
        try_per_rate = 4;
 
-       rate_table = sc->cur_rate_table;
+       rate_table = ath_rc_priv->rate_table;
        rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe);
 
        /*
@@ -1026,6 +1015,16 @@ static bool ath_rc_update_per(struct ath_softc *sc,
        return state_change;
 }
 
+static void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix,
+                                  int xretries, int retries, u8 per)
+{
+       struct ath_rc_stats *stats = &rc->rcstats[rix];
+
+       stats->xretries += xretries;
+       stats->retries += retries;
+       stats->per = per;
+}
+
 /* Update PER, RSSI and whatever else that the code thinks it is doing.
    If you can make sense of all this, you really need to go out more. */
 
@@ -1038,7 +1037,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
        int rate;
        u8 last_per;
        bool state_change = false;
-       const struct ath_rate_table *rate_table = sc->cur_rate_table;
+       const struct ath_rate_table *rate_table = ath_rc_priv->rate_table;
        int size = ath_rc_priv->rate_table_size;
 
        if ((tx_rate < 0) || (tx_rate > rate_table->rate_cnt))
@@ -1098,7 +1097,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
                ath_rc_priv->per_down_time = now_msec;
        }
 
-       ath_debug_stat_retries(sc, tx_rate, xretries, retries,
+       ath_debug_stat_retries(ath_rc_priv, tx_rate, xretries, retries,
                               ath_rc_priv->per[tx_rate]);
 
 }
@@ -1140,7 +1139,7 @@ static void ath_rc_tx_status(struct ath_softc *sc,
        u8 flags;
        u32 i = 0, rix;
 
-       rate_table = sc->cur_rate_table;
+       rate_table = ath_rc_priv->rate_table;
 
        /*
         * If the first rate is not the final index, there
@@ -1190,39 +1189,23 @@ static void ath_rc_tx_status(struct ath_softc *sc,
 static const
 struct ath_rate_table *ath_choose_rate_table(struct ath_softc *sc,
                                             enum ieee80211_band band,
-                                            bool is_ht,
-                                            bool is_cw_40)
+                                            bool is_ht)
 {
-       int mode = 0;
        struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 
        switch(band) {
        case IEEE80211_BAND_2GHZ:
-               mode = ATH9K_MODE_11G;
                if (is_ht)
-                       mode = ATH9K_MODE_11NG_HT20;
-               if (is_cw_40)
-                       mode = ATH9K_MODE_11NG_HT40PLUS;
-               break;
+                       return &ar5416_11ng_ratetable;
+               return &ar5416_11g_ratetable;
        case IEEE80211_BAND_5GHZ:
-               mode = ATH9K_MODE_11A;
                if (is_ht)
-                       mode = ATH9K_MODE_11NA_HT20;
-               if (is_cw_40)
-                       mode = ATH9K_MODE_11NA_HT40PLUS;
-               break;
+                       return &ar5416_11na_ratetable;
+               return &ar5416_11a_ratetable;
        default:
                ath_print(common, ATH_DBG_CONFIG, "Invalid band\n");
                return NULL;
        }
-
-       BUG_ON(mode >= ATH9K_MODE_MAX);
-
-       ath_print(common, ATH_DBG_CONFIG,
-                 "Choosing rate table for mode: %d\n", mode);
-
-       sc->cur_rate_mode = mode;
-       return hw_rate_table[mode];
 }
 
 static void ath_rc_init(struct ath_softc *sc,
@@ -1293,7 +1276,7 @@ static void ath_rc_init(struct ath_softc *sc,
        ath_rc_priv->max_valid_rate = k;
        ath_rc_sort_validrates(rate_table, ath_rc_priv);
        ath_rc_priv->rate_max_phy = ath_rc_priv->valid_rate_index[k-4];
-       sc->cur_rate_table = rate_table;
+       ath_rc_priv->rate_table = rate_table;
 
        ath_print(common, ATH_DBG_CONFIG,
                  "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,
 /* mac80211 Rate Control callbacks */
 /***********************************/
 
+static void ath_debug_stat_rc(struct ath_rate_priv *rc, int final_rate)
+{
+       struct ath_rc_stats *stats;
+
+       stats = &rc->rcstats[final_rate];
+       stats->success++;
+}
+
+
 static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
                          struct ieee80211_sta *sta, void *priv_sta,
                          struct sk_buff *skb)
@@ -1375,6 +1367,12 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
        if (tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED)
                return;
 
+       if (!(tx_info->flags & IEEE80211_TX_STAT_AMPDU)) {
+               tx_info->status.ampdu_ack_len =
+                       (tx_info->flags & IEEE80211_TX_STAT_ACK ? 1 : 0);
+               tx_info->status.ampdu_len = 1;
+       }
+
        /*
         * If an underrun error is seen assume it as an excessive retry only
         * if max frame trigger level has been reached (2 KB for singel stream,
@@ -1413,8 +1411,9 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
                }
        }
 
-       ath_debug_stat_rc(sc, ath_rc_get_rateindex(sc->cur_rate_table,
-               &tx_info->status.rates[final_ts_idx]));
+       ath_debug_stat_rc(ath_rc_priv,
+               ath_rc_get_rateindex(ath_rc_priv->rate_table,
+                       &tx_info->status.rates[final_ts_idx]));
 }
 
 static 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,
 
        /* Choose rate table first */
 
-       if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) ||
-           (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT) ||
-           (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)) {
-               rate_table = ath_choose_rate_table(sc, sband->band,
-                                     sta->ht_cap.ht_supported, is_cw40);
-       } else {
-               rate_table = hw_rate_table[sc->cur_rate_mode];
-       }
+       rate_table = ath_choose_rate_table(sc, sband->band,
+                             sta->ht_cap.ht_supported);
 
        ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta, is_cw40, is_sgi);
        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,
 
                if ((local_cw40 != oper_cw40) || (local_sgi != oper_sgi)) {
                        rate_table = ath_choose_rate_table(sc, sband->band,
-                                                  sta->ht_cap.ht_supported,
-                                                  oper_cw40);
+                                                  sta->ht_cap.ht_supported);
                        ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta,
                                                   oper_cw40, oper_sgi);
                        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,
                        ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG,
                                  "Operating HT Bandwidth changed to: %d\n",
                                  sc->hw->conf.channel_type);
-                       sc->cur_rate_table = hw_rate_table[sc->cur_rate_mode];
                }
        }
 }
 
+#ifdef CONFIG_ATH9K_DEBUGFS
+
+static int ath9k_debugfs_open(struct inode *inode, struct file *file)
+{
+       file->private_data = inode->i_private;
+       return 0;
+}
+
+static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
+                               size_t count, loff_t *ppos)
+{
+       struct ath_rate_priv *rc = file->private_data;
+       char *buf;
+       unsigned int len = 0, max;
+       int i = 0;
+       ssize_t retval;
+
+       if (rc->rate_table == NULL)
+               return 0;
+
+       max = 80 + rc->rate_table->rate_cnt * 1024 + 1;
+       buf = kmalloc(max, GFP_KERNEL);
+       if (buf == NULL)
+               return -ENOMEM;
+
+       len += sprintf(buf, "%6s %6s %6s "
+                      "%10s %10s %10s %10s\n",
+                      "HT", "MCS", "Rate",
+                      "Success", "Retries", "XRetries", "PER");
+
+       for (i = 0; i < rc->rate_table->rate_cnt; i++) {
+               u32 ratekbps = rc->rate_table->info[i].ratekbps;
+               struct ath_rc_stats *stats = &rc->rcstats[i];
+               char mcs[5];
+               char htmode[5];
+               int used_mcs = 0, used_htmode = 0;
+
+               if (WLAN_RC_PHY_HT(rc->rate_table->info[i].phy)) {
+                       used_mcs = snprintf(mcs, 5, "%d",
+                               rc->rate_table->info[i].ratecode);
+
+                       if (WLAN_RC_PHY_40(rc->rate_table->info[i].phy))
+                               used_htmode = snprintf(htmode, 5, "HT40");
+                       else if (WLAN_RC_PHY_20(rc->rate_table->info[i].phy))
+                               used_htmode = snprintf(htmode, 5, "HT20");
+                       else
+                               used_htmode = snprintf(htmode, 5, "????");
+               }
+
+               mcs[used_mcs] = '\0';
+               htmode[used_htmode] = '\0';
+
+               len += snprintf(buf + len, max - len,
+                       "%6s %6s %3u.%d: "
+                       "%10u %10u %10u %10u\n",
+                       htmode,
+                       mcs,
+                       ratekbps / 1000,
+                       (ratekbps % 1000) / 100,
+                       stats->success,
+                       stats->retries,
+                       stats->xretries,
+                       stats->per);
+       }
+
+       if (len > max)
+               len = max;
+
+       retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+       kfree(buf);
+       return retval;
+}
+
+static const struct file_operations fops_rcstat = {
+       .read = read_file_rcstat,
+       .open = ath9k_debugfs_open,
+       .owner = THIS_MODULE
+};
+
+static void ath_rate_add_sta_debugfs(void *priv, void *priv_sta,
+                                    struct dentry *dir)
+{
+       struct ath_rate_priv *rc = priv_sta;
+       debugfs_create_file("rc_stats", S_IRUGO, dir, rc, &fops_rcstat);
+}
+
+#endif /* CONFIG_ATH9K_DEBUGFS */
+
 static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
 {
        struct ath_wiphy *aphy = hw->priv;
@@ -1561,6 +1640,9 @@ static struct rate_control_ops ath_rate_ops = {
        .free = ath_rate_free,
        .alloc_sta = ath_rate_alloc_sta,
        .free_sta = ath_rate_free_sta,
+#ifdef CONFIG_ATH9K_DEBUGFS
+       .add_sta_debugfs = ath_rate_add_sta_debugfs,
+#endif
 };
 
 int ath_rate_control_register(void)
index 268072fd3c1c148784f23e432d1bce72de6843d5..2f46a2266ba1d2e0efeb32caef1a50eb0c13ef80 100644 (file)
@@ -135,20 +135,21 @@ enum {
 
 /**
  * struct ath_rate_table - Rate Control table
- * @valid: valid for use in rate control
- * @valid_single_stream: valid for use in rate control for
- *     single stream operation
- * @phy: CCK/OFDM
+ * @rate_cnt: total number of rates for the given wireless mode
+ * @mcs_start: MCS rate index offset
+ * @rate_flags: Rate Control flags
+ * @phy: CCK/OFDM/HT20/HT40
  * @ratekbps: rate in Kbits per second
  * @user_ratekbps: user rate in Kbits per second
  * @ratecode: rate that goes into HW descriptors
- * @short_preamble: Mask for enabling short preamble in ratecode for CCK
  * @dot11rate: value that goes into supported
  *     rates info element of MLME
  * @ctrl_rate: Index of next lower basic rate, used for duration computation
- * @max_4ms_framelen: maximum frame length(bytes) for tx duration
+ * @cw40index: Index of rates having 40MHz channel width
+ * @sgi_index: Index of rates having Short Guard Interval
+ * @ht_index: high throughput rates having 40MHz channel width and
+ *     Short Guard Interval
  * @probe_interval: interval for rate control to probe for other rates
- * @rssi_reduce_interval: interval for rate control to reduce rssi
  * @initial_ratemax: initial ratemax value
  */
 struct ath_rate_table {
@@ -175,6 +176,13 @@ struct ath_rateset {
        u8 rs_rates[ATH_RATE_MAX];
 };
 
+struct ath_rc_stats {
+       u32 success;
+       u32 retries;
+       u32 xretries;
+       u8 per;
+};
+
 /**
  * struct ath_rate_priv - Rate Control priv data
  * @state: RC state
@@ -211,6 +219,10 @@ struct ath_rate_priv {
        struct ath_rateset neg_rates;
        struct ath_rateset neg_ht_rates;
        struct ath_rate_softc *asc;
+       const struct ath_rate_table *rate_table;
+
+       struct dentry *debugfs_rcstats;
+       struct ath_rc_stats rcstats[RATE_TABLE_SIZE];
 };
 
 #define ATH_TX_INFO_FRAME_TYPE_INTERNAL        (1 << 0)
index 9c166f3804ab7c9feb3f785e7790c0a825e20017..fe73fc50082a2c4d681dab51058615a66ceacdfd 100644 (file)
@@ -268,6 +268,7 @@ static int ath_rx_edma_init(struct ath_softc *sc, int nbufs)
                                                bf->bf_buf_addr))) {
                                dev_kfree_skb_any(skb);
                                bf->bf_mpdu = NULL;
+                               bf->bf_buf_addr = 0;
                                ath_print(common, ATH_DBG_FATAL,
                                        "dma_mapping_error() on RX init\n");
                                error = -ENOMEM;
@@ -358,12 +359,12 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
                                                        bf->bf_buf_addr))) {
                                dev_kfree_skb_any(skb);
                                bf->bf_mpdu = NULL;
+                               bf->bf_buf_addr = 0;
                                ath_print(common, ATH_DBG_FATAL,
                                          "dma_mapping_error() on RX init\n");
                                error = -ENOMEM;
                                goto err;
                        }
-                       bf->bf_dmacontext = bf->bf_buf_addr;
                }
                sc->rx.rxlink = NULL;
        }
@@ -393,6 +394,8 @@ void ath_rx_cleanup(struct ath_softc *sc)
                                                common->rx_bufsize,
                                                DMA_FROM_DEVICE);
                                dev_kfree_skb(skb);
+                               bf->bf_buf_addr = 0;
+                               bf->bf_mpdu = NULL;
                        }
                }
 
@@ -430,8 +433,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
                | ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST
                | ATH9K_RX_FILTER_MCAST;
 
-       /* If not a STA, enable processing of Probe Requests */
-       if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION)
+       if (sc->rx.rxfilter & FIF_PROBE_REQ)
                rfilt |= ATH9K_RX_FILTER_PROBEREQ;
 
        /*
@@ -1735,12 +1737,12 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
                          bf->bf_buf_addr))) {
                        dev_kfree_skb_any(requeue_skb);
                        bf->bf_mpdu = NULL;
+                       bf->bf_buf_addr = 0;
                        ath_print(common, ATH_DBG_FATAL,
                                  "dma_mapping_error() on RX\n");
                        ath_rx_send_to_mac80211(hw, sc, skb, rxs);
                        break;
                }
-               bf->bf_dmacontext = bf->bf_buf_addr;
 
                /*
                 * change the default rx antenna if rx diversity chooses the
index 6d01e501b9b4e28cf6415e46dd97ac1133270b89..42976b0a01c115692566fe0f7f416c5aa9949b9f 100644 (file)
 #define AR_RXCFG_DMASZ_256B  6
 #define AR_RXCFG_DMASZ_512B  7
 
-#define AR_MIBC              0x0040
-#define AR_MIBC_COW          0x00000001
-#define AR_MIBC_FMC          0x00000002
-#define AR_MIBC_CMC          0x00000004
-#define AR_MIBC_MCS          0x00000008
-
 #define AR_TOPS              0x0044
 #define AR_TOPS_MASK         0x0000FFFF
 
 
 #define AR_SREV_9300(_ah) \
        (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300))
-#define AR_SREV_9300_20(_ah) \
-       (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300) && \
-        ((_ah)->hw_version.macRev == AR_SREV_REVISION_9300_20))
 #define AR_SREV_9300_20_OR_LATER(_ah) \
        (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9300) || \
         (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300) && \
@@ -1524,11 +1515,6 @@ enum {
 #define AR_TPC_CHIRP           0x003f0000
 #define AR_TPC_CHIRP_S         0x16
 
-#define AR_TFCNT           0x80ec
-#define AR_RFCNT           0x80f0
-#define AR_RCCNT           0x80f4
-#define AR_CCCNT           0x80f8
-
 #define AR_QUIET1          0x80fc
 #define AR_QUIET1_NEXT_QUIET_S         0
 #define AR_QUIET1_NEXT_QUIET_M         0x0000ffff
index aa447770eb2b606ed2ccffed3880b993f9cc3200..d077186da870ea2ccc507b168fba81d21ffcac8d 100644 (file)
@@ -294,7 +294,6 @@ static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf)
        tbf->bf_buf_addr = bf->bf_buf_addr;
        memcpy(tbf->bf_desc, bf->bf_desc, sc->sc_ah->caps.tx_desc_len);
        tbf->bf_state = bf->bf_state;
-       tbf->bf_dmacontext = bf->bf_dmacontext;
 
        return tbf;
 }
@@ -317,6 +316,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
        int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0;
        bool rc_update = true;
        struct ieee80211_tx_rate rates[4];
+       int nframes;
 
        skb = bf->bf_mpdu;
        hdr = (struct ieee80211_hdr *)skb->data;
@@ -325,6 +325,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
        hw = bf->aphy->hw;
 
        memcpy(rates, tx_info->control.rates, sizeof(rates));
+       nframes = bf->bf_nframes;
 
        rcu_read_lock();
 
@@ -341,7 +342,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
                            !bf->bf_stale || bf_next != NULL)
                                list_move_tail(&bf->list, &bf_head);
 
-                       ath_tx_rc_status(bf, ts, 0, 0, false);
+                       ath_tx_rc_status(bf, ts, 1, 0, false);
                        ath_tx_complete_buf(sc, bf, txq, &bf_head, ts,
                                0, 0);
 
@@ -446,6 +447,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
 
                        if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) {
                                memcpy(tx_info->control.rates, rates, sizeof(rates));
+                               bf->bf_nframes = nframes;
                                ath_tx_rc_status(bf, ts, nbad, txok, true);
                                rc_update = false;
                        } else {
@@ -1637,17 +1639,16 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
 
        bf->bf_mpdu = skb;
 
-       bf->bf_dmacontext = dma_map_single(sc->dev, skb->data,
-                                          skb->len, DMA_TO_DEVICE);
-       if (unlikely(dma_mapping_error(sc->dev, bf->bf_dmacontext))) {
+       bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
+                                        skb->len, DMA_TO_DEVICE);
+       if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) {
                bf->bf_mpdu = NULL;
+               bf->bf_buf_addr = 0;
                ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
                          "dma_mapping_error() on TX\n");
                return -ENOMEM;
        }
 
-       bf->bf_buf_addr = bf->bf_dmacontext;
-
        bf->bf_tx_aborted = false;
 
        return 0;
@@ -1911,7 +1912,8 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
                        tx_flags |= ATH_TX_XRETRY;
        }
 
-       dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE);
+       dma_unmap_single(sc->dev, bf->bf_buf_addr, skb->len, DMA_TO_DEVICE);
+       bf->bf_buf_addr = 0;
 
        if (bf->bf_state.bfs_paprd) {
                if (time_after(jiffies,
@@ -1921,9 +1923,13 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
                else
                        complete(&sc->paprd_complete);
        } else {
-               ath_tx_complete(sc, skb, bf->aphy, tx_flags);
                ath_debug_stat_tx(sc, txq, bf, ts);
+               ath_tx_complete(sc, skb, bf->aphy, tx_flags);
        }
+       /* At this point, skb (bf->bf_mpdu) is consumed...make sure we don't
+        * accidentally reference it later.
+        */
+       bf->bf_mpdu = NULL;
 
        /*
         * 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,
 
        if (ts->ts_status & ATH9K_TXERR_FILT)
                tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
-       if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && update_rc)
+       if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && update_rc) {
                tx_info->flags |= IEEE80211_TX_STAT_AMPDU;
 
+               BUG_ON(nbad > bf->bf_nframes);
+
+               tx_info->status.ampdu_len = bf->bf_nframes;
+               tx_info->status.ampdu_ack_len = bf->bf_nframes - nbad;
+       }
+
        if ((ts->ts_status & ATH9K_TXERR_FILT) == 0 &&
            (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) {
                if (ieee80211_is_data(hdr->frame_control)) {
@@ -1991,8 +2003,6 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts,
                        if ((ts->ts_status & ATH9K_TXERR_XRETRY) ||
                            (ts->ts_status & ATH9K_TXERR_FIFO))
                                tx_info->pad[0] |= ATH_TX_INFO_XRETRY;
-                       tx_info->status.ampdu_len = bf->bf_nframes;
-                       tx_info->status.ampdu_ack_len = bf->bf_nframes - nbad;
                }
        }
 
@@ -2102,7 +2112,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
                         */
                        if (ts.ts_status & ATH9K_TXERR_XRETRY)
                                bf->bf_state.bf_type |= BUF_XRETRY;
-                       ath_tx_rc_status(bf, &ts, 0, txok, true);
+                       ath_tx_rc_status(bf, &ts, txok ? 0 : 1, txok, true);
                }
 
                if (bf_isampdu(bf))
@@ -2220,7 +2230,7 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
                if (!bf_isampdu(bf)) {
                        if (txs.ts_status & ATH9K_TXERR_XRETRY)
                                bf->bf_state.bf_type |= BUF_XRETRY;
-                       ath_tx_rc_status(bf, &txs, 0, txok, true);
+                       ath_tx_rc_status(bf, &txs, txok ? 0 : 1, txok, true);
                }
 
                if (bf_isampdu(bf))
index 671dbc429547d27b05ae07459fe02dbeae21e887..939a0e96ed1f512f8ce22cacfd8b0c49a4633ed1 100644 (file)
@@ -576,6 +576,41 @@ static void carl9170_ps_beacon(struct ar9170 *ar, void *data, unsigned int len)
        }
 }
 
+static bool carl9170_ampdu_check(struct ar9170 *ar, u8 *buf, u8 ms)
+{
+       __le16 fc;
+
+       if ((ms & AR9170_RX_STATUS_MPDU) == AR9170_RX_STATUS_MPDU_SINGLE) {
+               /*
+                * This frame is not part of an aMPDU.
+                * Therefore it is not subjected to any
+                * of the following content restrictions.
+                */
+               return true;
+       }
+
+       /*
+        * "802.11n - 7.4a.3 A-MPDU contents" describes in which contexts
+        * certain frame types can be part of an aMPDU.
+        *
+        * In order to keep the processing cost down, I opted for a
+        * stateless filter solely based on the frame control field.
+        */
+
+       fc = ((struct ieee80211_hdr *)buf)->frame_control;
+       if (ieee80211_is_data_qos(fc) && ieee80211_is_data_present(fc))
+               return true;
+
+       if (ieee80211_is_ack(fc) || ieee80211_is_back(fc) ||
+           ieee80211_is_back_req(fc))
+               return true;
+
+       if (ieee80211_is_action(fc))
+               return true;
+
+       return false;
+}
+
 /*
  * If the frame alignment is right (or the kernel has
  * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS), and there
@@ -594,24 +629,19 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
        struct ieee80211_rx_status status;
        struct sk_buff *skb;
        int mpdu_len;
+       u8 mac_status;
 
        if (!IS_STARTED(ar))
                return;
 
-       if (unlikely(len < sizeof(*mac))) {
-               ar->rx_dropped++;
-               return;
-       }
+       if (unlikely(len < sizeof(*mac)))
+               goto drop;
 
        mpdu_len = len - sizeof(*mac);
 
        mac = (void *)(buf + mpdu_len);
-       if (unlikely(mac->error & AR9170_RX_ERROR_FATAL)) {
-               ar->rx_dropped++;
-               return;
-       }
-
-       switch (mac->status & AR9170_RX_STATUS_MPDU) {
+       mac_status = mac->status;
+       switch (mac_status & AR9170_RX_STATUS_MPDU) {
        case AR9170_RX_STATUS_MPDU_FIRST:
                /* Aggregated MPDUs start with an PLCP header */
                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)
                                        "is clipped.\n");
                        }
 
-                       ar->rx_dropped++;
-                       return;
+                       goto drop;
                }
                break;
 
@@ -659,8 +688,7 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
                                        "is clipped.\n");
                        }
 
-                       ar->rx_dropped++;
-                       return;
+                       goto drop;
                }
 
        case AR9170_RX_STATUS_MPDU_MIDDLE:
@@ -672,8 +700,7 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
                        wiphy_err(ar->hw->wiphy, "rx stream does not start "
                                        "with a first_mpdu frame tag.\n");
 
-                       ar->rx_dropped++;
-                       return;
+                       goto drop;
                }
 
                head = &ar->rx_plcp;
@@ -696,16 +723,15 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
        }
 
        /* FC + DU + RA + FCS */
-       if (unlikely(mpdu_len < (2 + 2 + 6 + FCS_LEN))) {
-               ar->rx_dropped++;
-               return;
-       }
+       if (unlikely(mpdu_len < (2 + 2 + ETH_ALEN + FCS_LEN)))
+               goto drop;
 
        memset(&status, 0, sizeof(status));
-       if (unlikely(carl9170_rx_mac_status(ar, head, mac, &status))) {
-               ar->rx_dropped++;
-               return;
-       }
+       if (unlikely(carl9170_rx_mac_status(ar, head, mac, &status)))
+               goto drop;
+
+       if (!carl9170_ampdu_check(ar, buf, mac_status))
+               goto drop;
 
        if (phy)
                carl9170_rx_phy_status(ar, phy, &status);
@@ -713,12 +739,15 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
        carl9170_ps_beacon(ar, buf, mpdu_len);
 
        skb = carl9170_rx_copy_data(buf, mpdu_len);
-       if (likely(skb)) {
-               memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
-               ieee80211_rx(ar->hw, skb);
-       } else {
-               ar->rx_dropped++;
-       }
+       if (!skb)
+               goto drop;
+
+       memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
+       ieee80211_rx(ar->hw, skb);
+       return;
+
+drop:
+       ar->rx_dropped++;
 }
 
 static void carl9170_rx_untie_cmds(struct ar9170 *ar, const u8 *respbuf,
index 48ead2268f505308eb623f081eeb2c320ae04a48..24d63b583b6b08459d657055d70836c621106177 100644 (file)
@@ -74,6 +74,9 @@
 #define        AR9170_RX_STATUS_MPDU_MIDDLE            0x30
 #define        AR9170_RX_STATUS_MPDU_LAST              0x10
 
+#define        AR9170_RX_STATUS_CONT_AGGR              0x40
+#define        AR9170_RX_STATUS_TOTAL_ERROR            0x80
+
 #define        AR9170_RX_ERROR_RXTO                    0x01
 #define        AR9170_RX_ERROR_OVERRUN                 0x02
 #define        AR9170_RX_ERROR_DECRYPT                 0x04
@@ -81,7 +84,6 @@
 #define        AR9170_RX_ERROR_WRONG_RA                0x10
 #define        AR9170_RX_ERROR_PLCP                    0x20
 #define        AR9170_RX_ERROR_MMIC                    0x40
-#define        AR9170_RX_ERROR_FATAL                   0x80
 
 /* these are either-or */
 #define        AR9170_TX_MAC_PROT_RTS                  0x0001
@@ -329,13 +331,15 @@ struct _carl9170_tx_superframe {
 
 #define        CARL9170_TX_SUPERDESC_LEN               24
 #define        AR9170_TX_HWDESC_LEN                    8
-#define        AR9170_TX_SUPERFRAME_LEN                (CARL9170_TX_HWDESC_LEN + \
-                                                AR9170_TX_SUPERDESC_LEN)
+#define        CARL9170_TX_SUPERFRAME_LEN              (CARL9170_TX_SUPERDESC_LEN + \
+                                                AR9170_TX_HWDESC_LEN)
 
 struct ar9170_rx_head {
        u8 plcp[12];
 } __packed;
 
+#define        AR9170_RX_HEAD_LEN                      12
+
 struct ar9170_rx_phystatus {
        union {
                struct {
@@ -350,12 +354,16 @@ struct ar9170_rx_phystatus {
        u8 phy_err;
 } __packed;
 
+#define        AR9170_RX_PHYSTATUS_LEN                 20
+
 struct ar9170_rx_macstatus {
        u8 SAidx, DAidx;
        u8 error;
        u8 status;
 } __packed;
 
+#define        AR9170_RX_MACSTATUS_LEN                 4
+
 struct ar9170_rx_frame_single {
        struct ar9170_rx_head phy_head;
        struct ieee80211_hdr i3e;
index 53e77bd131b925937cd432f347b31e16855be9a8..dacfb234f491053278dce7b502f763d07bda4d48 100644 (file)
@@ -30,3 +30,32 @@ void ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...)
        va_end(args);
 }
 EXPORT_SYMBOL(ath_print);
+
+const char *ath_opmode_to_string(enum nl80211_iftype opmode)
+{
+       switch (opmode) {
+       case NL80211_IFTYPE_UNSPECIFIED:
+               return "UNSPEC";
+       case NL80211_IFTYPE_ADHOC:
+               return "ADHOC";
+       case NL80211_IFTYPE_STATION:
+               return "STATION";
+       case NL80211_IFTYPE_AP:
+               return "AP";
+       case NL80211_IFTYPE_AP_VLAN:
+               return "AP-VLAN";
+       case NL80211_IFTYPE_WDS:
+               return "WDS";
+       case NL80211_IFTYPE_MONITOR:
+               return "MONITOR";
+       case NL80211_IFTYPE_MESH_POINT:
+               return "MESH";
+       case NL80211_IFTYPE_P2P_CLIENT:
+               return "P2P-CLIENT";
+       case NL80211_IFTYPE_P2P_GO:
+               return "P2P-GO";
+       default:
+               return "UNKNOWN";
+       }
+}
+EXPORT_SYMBOL(ath_opmode_to_string);
index fd3a020682dc2dee0dbb2339b4ea1b25d36c4303..64e4af2c2887338b597412421f717099ff5bc078 100644 (file)
@@ -77,4 +77,14 @@ ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...)
 }
 #endif /* CONFIG_ATH_DEBUG */
 
+/** Returns string describing opmode, or NULL if unknown mode. */
+#ifdef CONFIG_ATH_DEBUG
+const char *ath_opmode_to_string(enum nl80211_iftype opmode);
+#else
+static inline const char *ath_opmode_to_string(enum nl80211_iftype opmode)
+{
+       return "UNKNOWN";
+}
+#endif
+
 #endif /* ATH_DEBUG_H */
index a8f81ea09f143cc56c981f80db73469196ddb4c6..183c28281385b255a0cd86d579cfc33885882abd 100644 (file)
@@ -124,3 +124,62 @@ void ath_hw_setbssidmask(struct ath_common *common)
        REG_WRITE(ah, get_unaligned_le16(common->bssidmask + 4), AR_BSSMSKU);
 }
 EXPORT_SYMBOL(ath_hw_setbssidmask);
+
+
+/**
+ * ath_hw_cycle_counters_update - common function to update cycle counters
+ *
+ * @common: the ath_common struct for the device.
+ *
+ * This function is used to update all cycle counters in one place.
+ * It has to be called while holding common->cc_lock!
+ */
+void ath_hw_cycle_counters_update(struct ath_common *common)
+{
+       u32 cycles, busy, rx, tx;
+       void *ah = common->ah;
+
+       /* freeze */
+       REG_WRITE(ah, AR_MIBC_FMC, AR_MIBC);
+
+       /* read */
+       cycles = REG_READ(ah, AR_CCCNT);
+       busy = REG_READ(ah, AR_RCCNT);
+       rx = REG_READ(ah, AR_RFCNT);
+       tx = REG_READ(ah, AR_TFCNT);
+
+       /* clear */
+       REG_WRITE(ah, 0, AR_CCCNT);
+       REG_WRITE(ah, 0, AR_RFCNT);
+       REG_WRITE(ah, 0, AR_RCCNT);
+       REG_WRITE(ah, 0, AR_TFCNT);
+
+       /* unfreeze */
+       REG_WRITE(ah, 0, AR_MIBC);
+
+       /* update all cycle counters here */
+       common->cc_ani.cycles += cycles;
+       common->cc_ani.rx_busy += busy;
+       common->cc_ani.rx_frame += rx;
+       common->cc_ani.tx_frame += tx;
+
+       common->cc_survey.cycles += cycles;
+       common->cc_survey.rx_busy += busy;
+       common->cc_survey.rx_frame += rx;
+       common->cc_survey.tx_frame += tx;
+}
+EXPORT_SYMBOL(ath_hw_cycle_counters_update);
+
+int32_t ath_hw_get_listen_time(struct ath_common *common)
+{
+       struct ath_cycle_counters *cc = &common->cc_ani;
+       int32_t listen_time;
+
+       listen_time = (cc->cycles - cc->rx_frame - cc->tx_frame) /
+                     (common->clockrate * 1000);
+
+       memset(cc, 0, sizeof(*cc));
+
+       return listen_time;
+}
+EXPORT_SYMBOL(ath_hw_get_listen_time);
index e798ef476581a7c7ac508416659aa7b544f7dec5..298e53f3fa4834939ae75fdaf6a531467d10839a 100644 (file)
 #ifndef ATH_REGISTERS_H
 #define ATH_REGISTERS_H
 
+#define AR_MIBC                        0x0040
+#define AR_MIBC_COW            0x00000001
+#define AR_MIBC_FMC            0x00000002
+#define AR_MIBC_CMC            0x00000004
+#define AR_MIBC_MCS            0x00000008
+
 /*
  * BSSID mask registers. See ath_hw_set_bssid_mask()
  * for detailed documentation about these registers.
 #define AR_BSSMSKL             0x80e0
 #define AR_BSSMSKU             0x80e4
 
+#define AR_TFCNT               0x80ec
+#define AR_RFCNT               0x80f0
+#define AR_RCCNT               0x80f4
+#define AR_CCCNT               0x80f8
+
 #define AR_KEYTABLE_0           0x8800
 #define AR_KEYTABLE(_n)         (AR_KEYTABLE_0 + ((_n)*32))
 #define AR_KEY_CACHE_SIZE       128
index 5e83b6f0a3a013aeeb8cd090fd2bcd9267223356..69d4af09a6cbc9e08fca385fb9a7c1d33665326a 100644 (file)
@@ -1,6 +1,8 @@
 b43-y                          += main.o
 b43-y                          += tables.o
 b43-$(CONFIG_B43_NPHY)         += tables_nphy.o
+b43-$(CONFIG_B43_NPHY)         += radio_2055.o
+b43-$(CONFIG_B43_NPHY)         += radio_2056.o
 b43-y                          += phy_common.o
 b43-y                          += phy_g.o
 b43-y                          += phy_a.o
index bd480b481bfc387da47d8744e2174e3f5da7111f..0e6194228845565e89adf54ec92b5553c3baf776 100644 (file)
@@ -2,6 +2,7 @@
 #define LINUX_B43_PHY_COMMON_H_
 
 #include <linux/types.h>
+#include <linux/nl80211.h>
 
 struct b43_wldev;
 
@@ -250,8 +251,10 @@ struct b43_phy {
         * check is needed. */
        unsigned long next_txpwr_check_time;
 
-       /* current channel */
+       /* Current channel */
        unsigned int channel;
+       u16 channel_freq;
+       enum nl80211_channel_type channel_type;
 
        /* PHY TX errors counter. */
        atomic_t txerr_cnt;
index f575e757caeb549ba71ed5a61ab28a63080eac41..dfec5496055e410b7beffdb02e8d2cac556e016f 100644 (file)
@@ -29,6 +29,8 @@
 #include "b43.h"
 #include "phy_n.h"
 #include "tables_nphy.h"
+#include "radio_2055.h"
+#include "radio_2056.h"
 #include "main.h"
 
 struct nphy_txgains {
@@ -74,19 +76,11 @@ static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field,
 static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field,
                                                u16 value, u8 core);
 
-static inline bool b43_empty_chanspec(struct b43_chanspec *chanspec)
+static inline bool b43_channel_type_is_40mhz(
+                                       enum nl80211_channel_type channel_type)
 {
-       return !chanspec->channel && !chanspec->sideband &&
-               !chanspec->b_width && !chanspec->b_freq;
-}
-
-static inline bool b43_eq_chanspecs(struct b43_chanspec *chanspec1,
-                                       struct b43_chanspec *chanspec2)
-{
-       return (chanspec1->channel == chanspec2->channel &&
-               chanspec1->sideband == chanspec2->sideband &&
-               chanspec1->b_width == chanspec2->b_width &&
-               chanspec1->b_freq == chanspec2->b_freq);
+       return (channel_type == NL80211_CHAN_HT40MINUS ||
+               channel_type == NL80211_CHAN_HT40PLUS);
 }
 
 void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna)
@@ -781,7 +775,7 @@ static void b43_nphy_spur_workaround(struct b43_wldev *dev)
 {
        struct b43_phy_n *nphy = dev->phy.n;
 
-       u8 channel = nphy->radio_chanspec.channel;
+       u8 channel = dev->phy.channel;
        int tone[2] = { 57, 58 };
        u32 noise[2] = { 0x3FF, 0x3FF };
 
@@ -855,9 +849,9 @@ static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev)
                        gain[0] = 6;
                        gain[1] = 6;
                } else {
-                       tmp = 40370 - 315 * nphy->radio_chanspec.channel;
+                       tmp = 40370 - 315 * dev->phy.channel;
                        gain[0] = ((tmp >> 13) + ((tmp >> 12) & 1));
-                       tmp = 23242 - 224 * nphy->radio_chanspec.channel;
+                       tmp = 23242 - 224 * dev->phy.channel;
                        gain[1] = ((tmp >> 13) + ((tmp >> 12) & 1));
                }
        } else {
@@ -2083,12 +2077,12 @@ static void b43_nphy_restore_rssi_cal(struct b43_wldev *dev)
        u16 *rssical_phy_regs = NULL;
 
        if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
-               if (b43_empty_chanspec(&nphy->rssical_chanspec_2G))
+               if (!nphy->rssical_chanspec_2G.center_freq)
                        return;
                rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_2G;
                rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_2G;
        } else {
-               if (b43_empty_chanspec(&nphy->rssical_chanspec_5G))
+               if (!nphy->rssical_chanspec_5G.center_freq)
                        return;
                rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_5G;
                rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G;
@@ -2544,8 +2538,9 @@ static void b43_nphy_save_cal(struct b43_wldev *dev)
                txcal_radio_regs[2] = b43_radio_read(dev, 0x8D);
                txcal_radio_regs[3] = b43_radio_read(dev, 0xBC);
        }
-       *iqcal_chanspec = nphy->radio_chanspec;
-       b43_ntab_write_bulk(dev, B43_NTAB16(15, 80), 8, table);
+       iqcal_chanspec->center_freq = dev->phy.channel_freq;
+       iqcal_chanspec->channel_type = dev->phy.channel_type;
+       b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 8, table);
 
        if (nphy->hang_avoid)
                b43_nphy_stay_in_carrier_search(dev, 0);
@@ -2565,12 +2560,12 @@ static void b43_nphy_restore_cal(struct b43_wldev *dev)
        struct b43_phy_n_iq_comp *rxcal_coeffs = NULL;
 
        if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
-               if (b43_empty_chanspec(&nphy->iqcal_chanspec_2G))
+               if (!nphy->iqcal_chanspec_2G.center_freq)
                        return;
                table = nphy->cal_cache.txcal_coeffs_2G;
                loft = &nphy->cal_cache.txcal_coeffs_2G[5];
        } else {
-               if (b43_empty_chanspec(&nphy->iqcal_chanspec_5G))
+               if (!nphy->iqcal_chanspec_5G.center_freq)
                        return;
                table = nphy->cal_cache.txcal_coeffs_5G;
                loft = &nphy->cal_cache.txcal_coeffs_5G[5];
@@ -2815,7 +2810,10 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev,
                        b43_ntab_read_bulk(dev, B43_NTAB16(15, 96), length,
                                                nphy->txiqlocal_bestc);
                        nphy->txiqlocal_coeffsvalid = true;
-                       nphy->txiqlocal_chanspec = nphy->radio_chanspec;
+                       nphy->txiqlocal_chanspec.center_freq =
+                                                       dev->phy.channel_freq;
+                       nphy->txiqlocal_chanspec.channel_type =
+                                                       dev->phy.channel_type;
                } else {
                        length = 11;
                        if (dev->phy.rev < 3)
@@ -2851,7 +2849,8 @@ static void b43_nphy_reapply_tx_cal_coeffs(struct b43_wldev *dev)
        bool equal = true;
 
        if (!nphy->txiqlocal_coeffsvalid ||
-           b43_eq_chanspecs(&nphy->txiqlocal_chanspec, &nphy->radio_chanspec))
+           nphy->txiqlocal_chanspec.center_freq != dev->phy.channel_freq ||
+           nphy->txiqlocal_chanspec.channel_type != dev->phy.channel_type)
                return;
 
        b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 7, buffer);
@@ -3257,11 +3256,9 @@ int b43_phy_initn(struct b43_wldev *dev)
        do_rssi_cal = false;
        if (phy->rev >= 3) {
                if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
-                       do_rssi_cal =
-                               b43_empty_chanspec(&nphy->rssical_chanspec_2G);
+                       do_rssi_cal = !nphy->rssical_chanspec_2G.center_freq;
                else
-                       do_rssi_cal =
-                               b43_empty_chanspec(&nphy->rssical_chanspec_5G);
+                       do_rssi_cal = !nphy->rssical_chanspec_5G.center_freq;
 
                if (do_rssi_cal)
                        b43_nphy_rssi_cal(dev);
@@ -3273,9 +3270,9 @@ int b43_phy_initn(struct b43_wldev *dev)
 
        if (!((nphy->measure_hold & 0x6) != 0)) {
                if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
-                       do_cal = b43_empty_chanspec(&nphy->iqcal_chanspec_2G);
+                       do_cal = !nphy->iqcal_chanspec_2G.center_freq;
                else
-                       do_cal = b43_empty_chanspec(&nphy->iqcal_chanspec_5G);
+                       do_cal = !nphy->iqcal_chanspec_5G.center_freq;
 
                if (nphy->mute)
                        do_cal = false;
@@ -3323,24 +3320,25 @@ int b43_phy_initn(struct b43_wldev *dev)
 }
 
 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ChanspecSetup */
-static void b43_nphy_chanspec_setup(struct b43_wldev *dev,
+static void b43_nphy_channel_setup(struct b43_wldev *dev,
                                const struct b43_phy_n_sfo_cfg *e,
-                               struct b43_chanspec chanspec)
+                               struct ieee80211_channel *new_channel)
 {
        struct b43_phy *phy = &dev->phy;
        struct b43_phy_n *nphy = dev->phy.n;
 
-       u16 tmp;
+       u16 old_band_5ghz;
        u32 tmp32;
 
-       tmp = b43_phy_read(dev, B43_NPHY_BANDCTL) & B43_NPHY_BANDCTL_5GHZ;
-       if (chanspec.b_freq == 1 && tmp == 0) {
+       old_band_5ghz =
+               b43_phy_read(dev, B43_NPHY_BANDCTL) & B43_NPHY_BANDCTL_5GHZ;
+       if (new_channel->band == IEEE80211_BAND_5GHZ && !old_band_5ghz) {
                tmp32 = b43_read32(dev, B43_MMIO_PSM_PHY_HDR);
                b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32 | 4);
                b43_phy_set(dev, B43_PHY_B_BBCFG, 0xC000);
                b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32);
                b43_phy_set(dev, B43_NPHY_BANDCTL, B43_NPHY_BANDCTL_5GHZ);
-       } else if (chanspec.b_freq == 1) {
+       } else if (new_channel->band == IEEE80211_BAND_2GHZ && old_band_5ghz) {
                b43_phy_mask(dev, B43_NPHY_BANDCTL, ~B43_NPHY_BANDCTL_5GHZ);
                tmp32 = b43_read32(dev, B43_MMIO_PSM_PHY_HDR);
                b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32 | 4);
@@ -3350,13 +3348,12 @@ static void b43_nphy_chanspec_setup(struct b43_wldev *dev,
 
        b43_chantab_phy_upload(dev, e);
 
-
-       if (nphy->radio_chanspec.channel == 14) {
+       if (new_channel->hw_value == 14) {
                b43_nphy_classifier(dev, 2, 0);
                b43_phy_set(dev, B43_PHY_B_TEST, 0x0800);
        } else {
                b43_nphy_classifier(dev, 2, 2);
-               if (chanspec.b_freq == 2)
+               if (new_channel->band == IEEE80211_BAND_2GHZ)
                        b43_phy_mask(dev, B43_PHY_B_TEST, ~0x840);
        }
 
@@ -3379,53 +3376,57 @@ static void b43_nphy_chanspec_setup(struct b43_wldev *dev,
 }
 
 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetChanspec */
-static int b43_nphy_set_chanspec(struct b43_wldev *dev,
-                                       struct b43_chanspec chanspec)
+static int b43_nphy_set_channel(struct b43_wldev *dev,
+                               struct ieee80211_channel *channel,
+                               enum nl80211_channel_type channel_type)
 {
+       struct b43_phy *phy = &dev->phy;
        struct b43_phy_n *nphy = dev->phy.n;
 
        const struct b43_nphy_channeltab_entry_rev2 *tabent_r2;
        const struct b43_nphy_channeltab_entry_rev3 *tabent_r3;
 
        u8 tmp;
-       u8 channel = chanspec.channel;
 
        if (dev->phy.rev >= 3) {
-               /* TODO */
+               tabent_r3 = b43_nphy_get_chantabent_rev3(dev,
+                                                       channel->center_freq);
                tabent_r3 = NULL;
                if (!tabent_r3)
                        return -ESRCH;
        } else {
-               tabent_r2 = b43_nphy_get_chantabent_rev2(dev, channel);
+               tabent_r2 = b43_nphy_get_chantabent_rev2(dev,
+                                                       channel->hw_value);
                if (!tabent_r2)
                        return -ESRCH;
        }
 
-       nphy->radio_chanspec = chanspec;
+       /* Channel is set later in common code, but we need to set it on our
+          own to let this function's subcalls work properly. */
+       phy->channel = channel->hw_value;
+       phy->channel_freq = channel->center_freq;
 
-       if (chanspec.b_width != nphy->b_width)
-               ; /* TODO: BMAC BW Set (chanspec.b_width) */
+       if (b43_channel_type_is_40mhz(phy->channel_type) !=
+               b43_channel_type_is_40mhz(channel_type))
+               ; /* TODO: BMAC BW Set (channel_type) */
 
-       /* TODO: use defines */
-       if (chanspec.b_width == 3) {
-               if (chanspec.sideband == 2)
-                       b43_phy_set(dev, B43_NPHY_RXCTL,
-                                       B43_NPHY_RXCTL_BSELU20);
-               else
-                       b43_phy_mask(dev, B43_NPHY_RXCTL,
-                                       ~B43_NPHY_RXCTL_BSELU20);
-       }
+       if (channel_type == NL80211_CHAN_HT40PLUS)
+               b43_phy_set(dev, B43_NPHY_RXCTL,
+                               B43_NPHY_RXCTL_BSELU20);
+       else if (channel_type == NL80211_CHAN_HT40MINUS)
+               b43_phy_mask(dev, B43_NPHY_RXCTL,
+                               ~B43_NPHY_RXCTL_BSELU20);
 
        if (dev->phy.rev >= 3) {
-               tmp = (chanspec.b_freq == 1) ? 4 : 0;
+               tmp = (channel->band == IEEE80211_BAND_5GHZ) ? 4 : 0;
                b43_radio_maskset(dev, 0x08, 0xFFFB, tmp);
                /* TODO: PHY Radio2056 Setup (dev, tabent_r3); */
-               b43_nphy_chanspec_setup(dev, &(tabent_r3->phy_regs), chanspec);
+               b43_nphy_channel_setup(dev, &(tabent_r3->phy_regs), channel);
        } else {
-               tmp = (chanspec.b_freq == 1) ? 0x0020 : 0x0050;
+               tmp = (channel->band == IEEE80211_BAND_5GHZ) ? 0x0020 : 0x0050;
                b43_radio_maskset(dev, B2055_MASTER1, 0xFF8F, tmp);
                b43_radio_2055_setup(dev, tabent_r2);
-               b43_nphy_chanspec_setup(dev, &(tabent_r2->phy_regs), chanspec);
+               b43_nphy_channel_setup(dev, &(tabent_r2->phy_regs), channel);
        }
 
        return 0;
@@ -3567,8 +3568,8 @@ static void b43_nphy_op_switch_analog(struct b43_wldev *dev, bool on)
 static int b43_nphy_op_switch_channel(struct b43_wldev *dev,
                                      unsigned int new_channel)
 {
-       struct b43_phy_n *nphy = dev->phy.n;
-       struct b43_chanspec chanspec;
+       struct ieee80211_channel *channel = dev->wl->hw->conf.channel;
+       enum nl80211_channel_type channel_type = dev->wl->hw->conf.channel_type;
 
        if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
                if ((new_channel < 1) || (new_channel > 14))
@@ -3578,10 +3579,7 @@ static int b43_nphy_op_switch_channel(struct b43_wldev *dev,
                        return -EINVAL;
        }
 
-       chanspec = nphy->radio_chanspec;
-       chanspec.channel = new_channel;
-
-       return b43_nphy_set_chanspec(dev, chanspec);
+       return b43_nphy_set_channel(dev, channel, channel_type);
 }
 
 static unsigned int b43_nphy_op_get_default_chan(struct b43_wldev *dev)
index 8b6d570dd0aa963878b31e8b76fda75e9ea92d1b..c144e59a708bc5b4257181fd8044a4f757a11996 100644 (file)
 #define B43_PHY_B_BBCFG                                B43_PHY_N_BMODE(0x001) /* BB config */
 #define B43_PHY_B_TEST                         B43_PHY_N_BMODE(0x00A)
 
-
-/* Broadcom 2055 radio registers */
-
-#define B2055_GEN_SPARE                        0x00 /* GEN spare */
-#define B2055_SP_PINPD                 0x02 /* SP PIN PD */
-#define B2055_C1_SP_RSSI               0x03 /* SP RSSI Core 1 */
-#define B2055_C1_SP_PDMISC             0x04 /* SP PD MISC Core 1 */
-#define B2055_C2_SP_RSSI               0x05 /* SP RSSI Core 2 */
-#define B2055_C2_SP_PDMISC             0x06 /* SP PD MISC Core 2 */
-#define B2055_C1_SP_RXGC1              0x07 /* SP RX GC1 Core 1 */
-#define B2055_C1_SP_RXGC2              0x08 /* SP RX GC2 Core 1 */
-#define B2055_C2_SP_RXGC1              0x09 /* SP RX GC1 Core 2 */
-#define B2055_C2_SP_RXGC2              0x0A /* SP RX GC2 Core 2 */
-#define B2055_C1_SP_LPFBWSEL           0x0B /* SP LPF BW select Core 1 */
-#define B2055_C2_SP_LPFBWSEL           0x0C /* SP LPF BW select Core 2 */
-#define B2055_C1_SP_TXGC1              0x0D /* SP TX GC1 Core 1 */
-#define B2055_C1_SP_TXGC2              0x0E /* SP TX GC2 Core 1 */
-#define B2055_C2_SP_TXGC1              0x0F /* SP TX GC1 Core 2 */
-#define B2055_C2_SP_TXGC2              0x10 /* SP TX GC2 Core 2 */
-#define B2055_MASTER1                  0x11 /* Master control 1 */
-#define B2055_MASTER2                  0x12 /* Master control 2 */
-#define B2055_PD_LGEN                  0x13 /* PD LGEN */
-#define B2055_PD_PLLTS                 0x14 /* PD PLL TS */
-#define B2055_C1_PD_LGBUF              0x15 /* PD Core 1 LGBUF */
-#define B2055_C1_PD_TX                 0x16 /* PD Core 1 TX */
-#define B2055_C1_PD_RXTX               0x17 /* PD Core 1 RXTX */
-#define B2055_C1_PD_RSSIMISC           0x18 /* PD Core 1 RSSI MISC */
-#define B2055_C2_PD_LGBUF              0x19 /* PD Core 2 LGBUF */
-#define B2055_C2_PD_TX                 0x1A /* PD Core 2 TX */
-#define B2055_C2_PD_RXTX               0x1B /* PD Core 2 RXTX */
-#define B2055_C2_PD_RSSIMISC           0x1C /* PD Core 2 RSSI MISC */
-#define B2055_PWRDET_LGEN              0x1D /* PWRDET LGEN */
-#define B2055_C1_PWRDET_LGBUF          0x1E /* PWRDET LGBUF Core 1 */
-#define B2055_C1_PWRDET_RXTX           0x1F /* PWRDET RXTX Core 1 */
-#define B2055_C2_PWRDET_LGBUF          0x20 /* PWRDET LGBUF Core 2 */
-#define B2055_C2_PWRDET_RXTX           0x21 /* PWRDET RXTX Core 2 */
-#define B2055_RRCCAL_CS                        0x22 /* RRCCAL Control spare */
-#define B2055_RRCCAL_NOPTSEL           0x23 /* RRCCAL N OPT SEL */
-#define B2055_CAL_MISC                 0x24 /* CAL MISC */
-#define B2055_CAL_COUT                 0x25 /* CAL Counter out */
-#define B2055_CAL_COUT2                        0x26 /* CAL Counter out 2 */
-#define B2055_CAL_CVARCTL              0x27 /* CAL CVAR Control */
-#define B2055_CAL_RVARCTL              0x28 /* CAL RVAR Control */
-#define B2055_CAL_LPOCTL               0x29 /* CAL LPO Control */
-#define B2055_CAL_TS                   0x2A /* CAL TS */
-#define B2055_CAL_RCCALRTS             0x2B /* CAL RCCAL READ TS */
-#define B2055_CAL_RCALRTS              0x2C /* CAL RCAL READ TS */
-#define B2055_PADDRV                   0x2D /* PAD driver */
-#define B2055_XOCTL1                   0x2E /* XO Control 1 */
-#define B2055_XOCTL2                   0x2F /* XO Control 2 */
-#define B2055_XOREGUL                  0x30 /* XO Regulator */
-#define B2055_XOMISC                   0x31 /* XO misc */
-#define B2055_PLL_LFC1                 0x32 /* PLL LF C1 */
-#define B2055_PLL_CALVTH               0x33 /* PLL CAL VTH */
-#define B2055_PLL_LFC2                 0x34 /* PLL LF C2 */
-#define B2055_PLL_REF                  0x35 /* PLL reference */
-#define B2055_PLL_LFR1                 0x36 /* PLL LF R1 */
-#define B2055_PLL_PFDCP                        0x37 /* PLL PFD CP */
-#define B2055_PLL_IDAC_CPOPAMP         0x38 /* PLL IDAC CPOPAMP */
-#define B2055_PLL_CPREG                        0x39 /* PLL CP Regulator */
-#define B2055_PLL_RCAL                 0x3A /* PLL RCAL */
-#define B2055_RF_PLLMOD0               0x3B /* RF PLL MOD0 */
-#define B2055_RF_PLLMOD1               0x3C /* RF PLL MOD1 */
-#define B2055_RF_MMDIDAC1              0x3D /* RF MMD IDAC 1 */
-#define B2055_RF_MMDIDAC0              0x3E /* RF MMD IDAC 0 */
-#define B2055_RF_MMDSP                 0x3F /* RF MMD spare */
-#define B2055_VCO_CAL1                 0x40 /* VCO cal 1 */
-#define B2055_VCO_CAL2                 0x41 /* VCO cal 2 */
-#define B2055_VCO_CAL3                 0x42 /* VCO cal 3 */
-#define B2055_VCO_CAL4                 0x43 /* VCO cal 4 */
-#define B2055_VCO_CAL5                 0x44 /* VCO cal 5 */
-#define B2055_VCO_CAL6                 0x45 /* VCO cal 6 */
-#define B2055_VCO_CAL7                 0x46 /* VCO cal 7 */
-#define B2055_VCO_CAL8                 0x47 /* VCO cal 8 */
-#define B2055_VCO_CAL9                 0x48 /* VCO cal 9 */
-#define B2055_VCO_CAL10                        0x49 /* VCO cal 10 */
-#define B2055_VCO_CAL11                        0x4A /* VCO cal 11 */
-#define B2055_VCO_CAL12                        0x4B /* VCO cal 12 */
-#define B2055_VCO_CAL13                        0x4C /* VCO cal 13 */
-#define B2055_VCO_CAL14                        0x4D /* VCO cal 14 */
-#define B2055_VCO_CAL15                        0x4E /* VCO cal 15 */
-#define B2055_VCO_CAL16                        0x4F /* VCO cal 16 */
-#define B2055_VCO_KVCO                 0x50 /* VCO KVCO */
-#define B2055_VCO_CAPTAIL              0x51 /* VCO CAP TAIL */
-#define B2055_VCO_IDACVCO              0x52 /* VCO IDAC VCO */
-#define B2055_VCO_REG                  0x53 /* VCO Regulator */
-#define B2055_PLL_RFVTH                        0x54 /* PLL RF VTH */
-#define B2055_LGBUF_CENBUF             0x55 /* LGBUF CEN BUF */
-#define B2055_LGEN_TUNE1               0x56 /* LGEN tune 1 */
-#define B2055_LGEN_TUNE2               0x57 /* LGEN tune 2 */
-#define B2055_LGEN_IDAC1               0x58 /* LGEN IDAC 1 */
-#define B2055_LGEN_IDAC2               0x59 /* LGEN IDAC 2 */
-#define B2055_LGEN_BIASC               0x5A /* LGEN BIAS counter */
-#define B2055_LGEN_BIASIDAC            0x5B /* LGEN BIAS IDAC */
-#define B2055_LGEN_RCAL                        0x5C /* LGEN RCAL */
-#define B2055_LGEN_DIV                 0x5D /* LGEN div */
-#define B2055_LGEN_SPARE2              0x5E /* LGEN spare 2 */
-#define B2055_C1_LGBUF_ATUNE           0x5F /* Core 1 LGBUF A tune */
-#define B2055_C1_LGBUF_GTUNE           0x60 /* Core 1 LGBUF G tune */
-#define B2055_C1_LGBUF_DIV             0x61 /* Core 1 LGBUF div */
-#define B2055_C1_LGBUF_AIDAC           0x62 /* Core 1 LGBUF A IDAC */
-#define B2055_C1_LGBUF_GIDAC           0x63 /* Core 1 LGBUF G IDAC */
-#define B2055_C1_LGBUF_IDACFO          0x64 /* Core 1 LGBUF IDAC filter override */
-#define B2055_C1_LGBUF_SPARE           0x65 /* Core 1 LGBUF spare */
-#define B2055_C1_RX_RFSPC1             0x66 /* Core 1 RX RF SPC1 */
-#define B2055_C1_RX_RFR1               0x67 /* Core 1 RX RF reg 1 */
-#define B2055_C1_RX_RFR2               0x68 /* Core 1 RX RF reg 2 */
-#define B2055_C1_RX_RFRCAL             0x69 /* Core 1 RX RF RCAL */
-#define B2055_C1_RX_BB_BLCMP           0x6A /* Core 1 RX Baseband BUFI LPF CMP */
-#define B2055_C1_RX_BB_LPF             0x6B /* Core 1 RX Baseband LPF */
-#define B2055_C1_RX_BB_MIDACHP         0x6C /* Core 1 RX Baseband MIDAC High-pass */
-#define B2055_C1_RX_BB_VGA1IDAC                0x6D /* Core 1 RX Baseband VGA1 IDAC */
-#define B2055_C1_RX_BB_VGA2IDAC                0x6E /* Core 1 RX Baseband VGA2 IDAC */
-#define B2055_C1_RX_BB_VGA3IDAC                0x6F /* Core 1 RX Baseband VGA3 IDAC */
-#define B2055_C1_RX_BB_BUFOCTL         0x70 /* Core 1 RX Baseband BUFO Control */
-#define B2055_C1_RX_BB_RCCALCTL                0x71 /* Core 1 RX Baseband RCCAL Control */
-#define B2055_C1_RX_BB_RSSICTL1                0x72 /* Core 1 RX Baseband RSSI Control 1 */
-#define B2055_C1_RX_BB_RSSICTL2                0x73 /* Core 1 RX Baseband RSSI Control 2 */
-#define B2055_C1_RX_BB_RSSICTL3                0x74 /* Core 1 RX Baseband RSSI Control 3 */
-#define B2055_C1_RX_BB_RSSICTL4                0x75 /* Core 1 RX Baseband RSSI Control 4 */
-#define B2055_C1_RX_BB_RSSICTL5                0x76 /* Core 1 RX Baseband RSSI Control 5 */
-#define B2055_C1_RX_BB_REG             0x77 /* Core 1 RX Baseband Regulator */
-#define B2055_C1_RX_BB_SPARE1          0x78 /* Core 1 RX Baseband spare 1 */
-#define B2055_C1_RX_TXBBRCAL           0x79 /* Core 1 RX TX BB RCAL */
-#define B2055_C1_TX_RF_SPGA            0x7A /* Core 1 TX RF SGM PGA */
-#define B2055_C1_TX_RF_SPAD            0x7B /* Core 1 TX RF SGM PAD */
-#define B2055_C1_TX_RF_CNTPGA1         0x7C /* Core 1 TX RF counter PGA 1 */
-#define B2055_C1_TX_RF_CNTPAD1         0x7D /* Core 1 TX RF counter PAD 1 */
-#define B2055_C1_TX_RF_PGAIDAC         0x7E /* Core 1 TX RF PGA IDAC */
-#define B2055_C1_TX_PGAPADTN           0x7F /* Core 1 TX PGA PAD TN */
-#define B2055_C1_TX_PADIDAC1           0x80 /* Core 1 TX PAD IDAC 1 */
-#define B2055_C1_TX_PADIDAC2           0x81 /* Core 1 TX PAD IDAC 2 */
-#define B2055_C1_TX_MXBGTRIM           0x82 /* Core 1 TX MX B/G TRIM */
-#define B2055_C1_TX_RF_RCAL            0x83 /* Core 1 TX RF RCAL */
-#define B2055_C1_TX_RF_PADTSSI1                0x84 /* Core 1 TX RF PAD TSSI1 */
-#define B2055_C1_TX_RF_PADTSSI2                0x85 /* Core 1 TX RF PAD TSSI2 */
-#define B2055_C1_TX_RF_SPARE           0x86 /* Core 1 TX RF spare */
-#define B2055_C1_TX_RF_IQCAL1          0x87 /* Core 1 TX RF I/Q CAL 1 */
-#define B2055_C1_TX_RF_IQCAL2          0x88 /* Core 1 TX RF I/Q CAL 2 */
-#define B2055_C1_TXBB_RCCAL            0x89 /* Core 1 TXBB RC CAL Control */
-#define B2055_C1_TXBB_LPF1             0x8A /* Core 1 TXBB LPF 1 */
-#define B2055_C1_TX_VOSCNCL            0x8B /* Core 1 TX VOS CNCL */
-#define B2055_C1_TX_LPF_MXGMIDAC       0x8C /* Core 1 TX LPF MXGM IDAC */
-#define B2055_C1_TX_BB_MXGM            0x8D /* Core 1 TX BB MXGM */
-#define B2055_C2_LGBUF_ATUNE           0x8E /* Core 2 LGBUF A tune */
-#define B2055_C2_LGBUF_GTUNE           0x8F /* Core 2 LGBUF G tune */
-#define B2055_C2_LGBUF_DIV             0x90 /* Core 2 LGBUF div */
-#define B2055_C2_LGBUF_AIDAC           0x91 /* Core 2 LGBUF A IDAC */
-#define B2055_C2_LGBUF_GIDAC           0x92 /* Core 2 LGBUF G IDAC */
-#define B2055_C2_LGBUF_IDACFO          0x93 /* Core 2 LGBUF IDAC filter override */
-#define B2055_C2_LGBUF_SPARE           0x94 /* Core 2 LGBUF spare */
-#define B2055_C2_RX_RFSPC1             0x95 /* Core 2 RX RF SPC1 */
-#define B2055_C2_RX_RFR1               0x96 /* Core 2 RX RF reg 1 */
-#define B2055_C2_RX_RFR2               0x97 /* Core 2 RX RF reg 2 */
-#define B2055_C2_RX_RFRCAL             0x98 /* Core 2 RX RF RCAL */
-#define B2055_C2_RX_BB_BLCMP           0x99 /* Core 2 RX Baseband BUFI LPF CMP */
-#define B2055_C2_RX_BB_LPF             0x9A /* Core 2 RX Baseband LPF */
-#define B2055_C2_RX_BB_MIDACHP         0x9B /* Core 2 RX Baseband MIDAC High-pass */
-#define B2055_C2_RX_BB_VGA1IDAC                0x9C /* Core 2 RX Baseband VGA1 IDAC */
-#define B2055_C2_RX_BB_VGA2IDAC                0x9D /* Core 2 RX Baseband VGA2 IDAC */
-#define B2055_C2_RX_BB_VGA3IDAC                0x9E /* Core 2 RX Baseband VGA3 IDAC */
-#define B2055_C2_RX_BB_BUFOCTL         0x9F /* Core 2 RX Baseband BUFO Control */
-#define B2055_C2_RX_BB_RCCALCTL                0xA0 /* Core 2 RX Baseband RCCAL Control */
-#define B2055_C2_RX_BB_RSSICTL1                0xA1 /* Core 2 RX Baseband RSSI Control 1 */
-#define B2055_C2_RX_BB_RSSICTL2                0xA2 /* Core 2 RX Baseband RSSI Control 2 */
-#define B2055_C2_RX_BB_RSSICTL3                0xA3 /* Core 2 RX Baseband RSSI Control 3 */
-#define B2055_C2_RX_BB_RSSICTL4                0xA4 /* Core 2 RX Baseband RSSI Control 4 */
-#define B2055_C2_RX_BB_RSSICTL5                0xA5 /* Core 2 RX Baseband RSSI Control 5 */
-#define B2055_C2_RX_BB_REG             0xA6 /* Core 2 RX Baseband Regulator */
-#define B2055_C2_RX_BB_SPARE1          0xA7 /* Core 2 RX Baseband spare 1 */
-#define B2055_C2_RX_TXBBRCAL           0xA8 /* Core 2 RX TX BB RCAL */
-#define B2055_C2_TX_RF_SPGA            0xA9 /* Core 2 TX RF SGM PGA */
-#define B2055_C2_TX_RF_SPAD            0xAA /* Core 2 TX RF SGM PAD */
-#define B2055_C2_TX_RF_CNTPGA1         0xAB /* Core 2 TX RF counter PGA 1 */
-#define B2055_C2_TX_RF_CNTPAD1         0xAC /* Core 2 TX RF counter PAD 1 */
-#define B2055_C2_TX_RF_PGAIDAC         0xAD /* Core 2 TX RF PGA IDAC */
-#define B2055_C2_TX_PGAPADTN           0xAE /* Core 2 TX PGA PAD TN */
-#define B2055_C2_TX_PADIDAC1           0xAF /* Core 2 TX PAD IDAC 1 */
-#define B2055_C2_TX_PADIDAC2           0xB0 /* Core 2 TX PAD IDAC 2 */
-#define B2055_C2_TX_MXBGTRIM           0xB1 /* Core 2 TX MX B/G TRIM */
-#define B2055_C2_TX_RF_RCAL            0xB2 /* Core 2 TX RF RCAL */
-#define B2055_C2_TX_RF_PADTSSI1                0xB3 /* Core 2 TX RF PAD TSSI1 */
-#define B2055_C2_TX_RF_PADTSSI2                0xB4 /* Core 2 TX RF PAD TSSI2 */
-#define B2055_C2_TX_RF_SPARE           0xB5 /* Core 2 TX RF spare */
-#define B2055_C2_TX_RF_IQCAL1          0xB6 /* Core 2 TX RF I/Q CAL 1 */
-#define B2055_C2_TX_RF_IQCAL2          0xB7 /* Core 2 TX RF I/Q CAL 2 */
-#define B2055_C2_TXBB_RCCAL            0xB8 /* Core 2 TXBB RC CAL Control */
-#define B2055_C2_TXBB_LPF1             0xB9 /* Core 2 TXBB LPF 1 */
-#define B2055_C2_TX_VOSCNCL            0xBA /* Core 2 TX VOS CNCL */
-#define B2055_C2_TX_LPF_MXGMIDAC       0xBB /* Core 2 TX LPF MXGM IDAC */
-#define B2055_C2_TX_BB_MXGM            0xBC /* Core 2 TX BB MXGM */
-#define B2055_PRG_GCHP21               0xBD /* PRG GC HPVGA23 21 */
-#define B2055_PRG_GCHP22               0xBE /* PRG GC HPVGA23 22 */
-#define B2055_PRG_GCHP23               0xBF /* PRG GC HPVGA23 23 */
-#define B2055_PRG_GCHP24               0xC0 /* PRG GC HPVGA23 24 */
-#define B2055_PRG_GCHP25               0xC1 /* PRG GC HPVGA23 25 */
-#define B2055_PRG_GCHP26               0xC2 /* PRG GC HPVGA23 26 */
-#define B2055_PRG_GCHP27               0xC3 /* PRG GC HPVGA23 27 */
-#define B2055_PRG_GCHP28               0xC4 /* PRG GC HPVGA23 28 */
-#define B2055_PRG_GCHP29               0xC5 /* PRG GC HPVGA23 29 */
-#define B2055_PRG_GCHP30               0xC6 /* PRG GC HPVGA23 30 */
-#define B2055_C1_LNA_GAINBST           0xCD /* Core 1 LNA GAINBST */
-#define B2055_C1_B0NB_RSSIVCM          0xD2 /* Core 1 B0 narrow-band RSSI VCM */
-#define B2055_C1_GENSPARE2             0xD6 /* Core 1 GEN spare 2 */
-#define B2055_C2_LNA_GAINBST           0xD9 /* Core 2 LNA GAINBST */
-#define B2055_C2_B0NB_RSSIVCM          0xDE /* Core 2 B0 narrow-band RSSI VCM */
-#define B2055_C2_GENSPARE2             0xE2 /* Core 2 GEN spare 2 */
-
-
-
 struct b43_wldev;
 
 struct b43_chanspec {
-       u8 channel;
-       u8 sideband;
-       u8 b_width;
-       u8 b_freq;
+       u16 center_freq;
+       enum nl80211_channel_type channel_type;
 };
 
 struct b43_phy_n_iq_comp {
@@ -984,8 +772,6 @@ struct b43_phy_n {
        u16 papd_epsilon_offset[2];
        s32 preamble_override;
        u32 bb_mult_save;
-       u8 b_width;
-       struct b43_chanspec radio_chanspec;
 
        bool gain_boost;
        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 (file)
index 0000000..1b53165
--- /dev/null
@@ -0,0 +1,1332 @@
+/*
+
+  Broadcom B43 wireless driver
+  IEEE 802.11n PHY and radio device data tables
+
+  Copyright (c) 2008 Michael Buesch <mb@bu3sch.de>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; see the file COPYING.  If not, write to
+  the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
+  Boston, MA 02110-1301, USA.
+
+*/
+
+#include "b43.h"
+#include "radio_2055.h"
+#include "phy_common.h"
+
+struct b2055_inittab_entry {
+       /* Value to write if we use the 5GHz band. */
+       u16 ghz5;
+       /* Value to write if we use the 2.4GHz band. */
+       u16 ghz2;
+       /* Flags */
+       u8 flags;
+#define B2055_INITTAB_ENTRY_OK 0x01
+#define B2055_INITTAB_UPLOAD   0x02
+};
+#define UPLOAD         .flags = B2055_INITTAB_ENTRY_OK | B2055_INITTAB_UPLOAD
+#define NOUPLOAD       .flags = B2055_INITTAB_ENTRY_OK
+
+static const struct b2055_inittab_entry b2055_inittab [] = {
+  [B2055_SP_PINPD]             = { .ghz5 = 0x0080, .ghz2 = 0x0080, NOUPLOAD, },
+  [B2055_C1_SP_RSSI]           = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C1_SP_PDMISC]         = { .ghz5 = 0x0027, .ghz2 = 0x0027, NOUPLOAD, },
+  [B2055_C2_SP_RSSI]           = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C2_SP_PDMISC]         = { .ghz5 = 0x0027, .ghz2 = 0x0027, NOUPLOAD, },
+  [B2055_C1_SP_RXGC1]          = { .ghz5 = 0x007F, .ghz2 = 0x007F, UPLOAD, },
+  [B2055_C1_SP_RXGC2]          = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, },
+  [B2055_C2_SP_RXGC1]          = { .ghz5 = 0x007F, .ghz2 = 0x007F, UPLOAD, },
+  [B2055_C2_SP_RXGC2]          = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, },
+  [B2055_C1_SP_LPFBWSEL]       = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
+  [B2055_C2_SP_LPFBWSEL]       = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
+  [B2055_C1_SP_TXGC1]          = { .ghz5 = 0x004F, .ghz2 = 0x004F, UPLOAD, },
+  [B2055_C1_SP_TXGC2]          = { .ghz5 = 0x0005, .ghz2 = 0x0005, UPLOAD, },
+  [B2055_C2_SP_TXGC1]          = { .ghz5 = 0x004F, .ghz2 = 0x004F, UPLOAD, },
+  [B2055_C2_SP_TXGC2]          = { .ghz5 = 0x0005, .ghz2 = 0x0005, UPLOAD, },
+  [B2055_MASTER1]              = { .ghz5 = 0x00D0, .ghz2 = 0x00D0, NOUPLOAD, },
+  [B2055_MASTER2]              = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+  [B2055_PD_LGEN]              = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_PD_PLLTS]             = { .ghz5 = 0x0040, .ghz2 = 0x0040, NOUPLOAD, },
+  [B2055_C1_PD_LGBUF]          = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C1_PD_TX]             = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C1_PD_RXTX]           = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C1_PD_RSSIMISC]       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C2_PD_LGBUF]          = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C2_PD_TX]             = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C2_PD_RXTX]           = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C2_PD_RSSIMISC]       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_PWRDET_LGEN]          = { .ghz5 = 0x00C0, .ghz2 = 0x00C0, NOUPLOAD, },
+  [B2055_C1_PWRDET_LGBUF]      = { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, },
+  [B2055_C1_PWRDET_RXTX]       = { .ghz5 = 0x00C0, .ghz2 = 0x00C0, NOUPLOAD, },
+  [B2055_C2_PWRDET_LGBUF]      = { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, },
+  [B2055_C2_PWRDET_RXTX]       = { .ghz5 = 0x00C0, .ghz2 = 0x00C0, NOUPLOAD, },
+  [B2055_RRCCAL_CS]            = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_RRCCAL_NOPTSEL]       = { .ghz5 = 0x002C, .ghz2 = 0x002C, NOUPLOAD, },
+  [B2055_CAL_MISC]             = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_CAL_COUT]             = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_CAL_COUT2]            = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_CAL_CVARCTL]          = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_CAL_RVARCTL]          = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_CAL_LPOCTL]           = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_CAL_TS]               = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_CAL_RCCALRTS]         = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_CAL_RCALRTS]          = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_PADDRV]               = { .ghz5 = 0x00A4, .ghz2 = 0x00A4, NOUPLOAD, },
+  [B2055_XOCTL1]               = { .ghz5 = 0x0038, .ghz2 = 0x0038, NOUPLOAD, },
+  [B2055_XOCTL2]               = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_XOREGUL]              = { .ghz5 = 0x0004, .ghz2 = 0x0004, UPLOAD, },
+  [B2055_XOMISC]               = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_PLL_LFC1]             = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
+  [B2055_PLL_CALVTH]           = { .ghz5 = 0x0087, .ghz2 = 0x0087, NOUPLOAD, },
+  [B2055_PLL_LFC2]             = { .ghz5 = 0x0009, .ghz2 = 0x0009, NOUPLOAD, },
+  [B2055_PLL_REF]              = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, },
+  [B2055_PLL_LFR1]             = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, },
+  [B2055_PLL_PFDCP]            = { .ghz5 = 0x0018, .ghz2 = 0x0018, UPLOAD, },
+  [B2055_PLL_IDAC_CPOPAMP]     = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+  [B2055_PLL_CPREG]            = { .ghz5 = 0x0004, .ghz2 = 0x0004, UPLOAD, },
+  [B2055_PLL_RCAL]             = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+  [B2055_RF_PLLMOD0]           = { .ghz5 = 0x009E, .ghz2 = 0x009E, NOUPLOAD, },
+  [B2055_RF_PLLMOD1]           = { .ghz5 = 0x0009, .ghz2 = 0x0009, NOUPLOAD, },
+  [B2055_RF_MMDIDAC1]          = { .ghz5 = 0x00C8, .ghz2 = 0x00C8, UPLOAD, },
+  [B2055_RF_MMDIDAC0]          = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+  [B2055_RF_MMDSP]             = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_VCO_CAL1]             = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_VCO_CAL2]             = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_VCO_CAL3]             = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+  [B2055_VCO_CAL4]             = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+  [B2055_VCO_CAL5]             = { .ghz5 = 0x0096, .ghz2 = 0x0096, NOUPLOAD, },
+  [B2055_VCO_CAL6]             = { .ghz5 = 0x003E, .ghz2 = 0x003E, NOUPLOAD, },
+  [B2055_VCO_CAL7]             = { .ghz5 = 0x003E, .ghz2 = 0x003E, NOUPLOAD, },
+  [B2055_VCO_CAL8]             = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, },
+  [B2055_VCO_CAL9]             = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+  [B2055_VCO_CAL10]            = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
+  [B2055_VCO_CAL11]            = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+  [B2055_VCO_CAL12]            = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_VCO_CAL13]            = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_VCO_CAL14]            = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_VCO_CAL15]            = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_VCO_CAL16]            = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_VCO_KVCO]             = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+  [B2055_VCO_CAPTAIL]          = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+  [B2055_VCO_IDACVCO]          = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+  [B2055_VCO_REG]              = { .ghz5 = 0x0084, .ghz2 = 0x0084, UPLOAD, },
+  [B2055_PLL_RFVTH]            = { .ghz5 = 0x00C3, .ghz2 = 0x00C3, NOUPLOAD, },
+  [B2055_LGBUF_CENBUF]         = { .ghz5 = 0x008F, .ghz2 = 0x008F, NOUPLOAD, },
+  [B2055_LGEN_TUNE1]           = { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, },
+  [B2055_LGEN_TUNE2]           = { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, },
+  [B2055_LGEN_IDAC1]           = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+  [B2055_LGEN_IDAC2]           = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+  [B2055_LGEN_BIASC]           = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_LGEN_BIASIDAC]                = { .ghz5 = 0x00CC, .ghz2 = 0x00CC, NOUPLOAD, },
+  [B2055_LGEN_RCAL]            = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+  [B2055_LGEN_DIV]             = { .ghz5 = 0x0080, .ghz2 = 0x0080, NOUPLOAD, },
+  [B2055_LGEN_SPARE2]          = { .ghz5 = 0x0080, .ghz2 = 0x0080, NOUPLOAD, },
+  [B2055_C1_LGBUF_ATUNE]       = { .ghz5 = 0x00F8, .ghz2 = 0x00F8, NOUPLOAD, },
+  [B2055_C1_LGBUF_GTUNE]       = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+  [B2055_C1_LGBUF_DIV]         = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+  [B2055_C1_LGBUF_AIDAC]       = { .ghz5 = 0x0088, .ghz2 = 0x0008, UPLOAD, },
+  [B2055_C1_LGBUF_GIDAC]       = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+  [B2055_C1_LGBUF_IDACFO]      = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C1_LGBUF_SPARE]       = { .ghz5 = 0x0001, .ghz2 = 0x0001, UPLOAD, },
+  [B2055_C1_RX_RFSPC1]         = { .ghz5 = 0x008A, .ghz2 = 0x008A, NOUPLOAD, },
+  [B2055_C1_RX_RFR1]           = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+  [B2055_C1_RX_RFR2]           = { .ghz5 = 0x0083, .ghz2 = 0x0083, NOUPLOAD, },
+  [B2055_C1_RX_RFRCAL]         = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+  [B2055_C1_RX_BB_BLCMP]       = { .ghz5 = 0x00A0, .ghz2 = 0x00A0, NOUPLOAD, },
+  [B2055_C1_RX_BB_LPF]         = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
+  [B2055_C1_RX_BB_MIDACHP]     = { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, },
+  [B2055_C1_RX_BB_VGA1IDAC]    = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
+  [B2055_C1_RX_BB_VGA2IDAC]    = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
+  [B2055_C1_RX_BB_VGA3IDAC]    = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
+  [B2055_C1_RX_BB_BUFOCTL]     = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
+  [B2055_C1_RX_BB_RCCALCTL]    = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
+  [B2055_C1_RX_BB_RSSICTL1]    = { .ghz5 = 0x006A, .ghz2 = 0x006A, UPLOAD, },
+  [B2055_C1_RX_BB_RSSICTL2]    = { .ghz5 = 0x00AB, .ghz2 = 0x00AB, UPLOAD, },
+  [B2055_C1_RX_BB_RSSICTL3]    = { .ghz5 = 0x0013, .ghz2 = 0x0013, UPLOAD, },
+  [B2055_C1_RX_BB_RSSICTL4]    = { .ghz5 = 0x00C1, .ghz2 = 0x00C1, UPLOAD, },
+  [B2055_C1_RX_BB_RSSICTL5]    = { .ghz5 = 0x00AA, .ghz2 = 0x00AA, UPLOAD, },
+  [B2055_C1_RX_BB_REG]         = { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, },
+  [B2055_C1_RX_BB_SPARE1]      = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C1_RX_TXBBRCAL]       = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+  [B2055_C1_TX_RF_SPGA]                = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+  [B2055_C1_TX_RF_SPAD]                = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+  [B2055_C1_TX_RF_CNTPGA1]     = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
+  [B2055_C1_TX_RF_CNTPAD1]     = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, },
+  [B2055_C1_TX_RF_PGAIDAC]     = { .ghz5 = 0x0097, .ghz2 = 0x0097, UPLOAD, },
+  [B2055_C1_TX_PGAPADTN]       = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+  [B2055_C1_TX_PADIDAC1]       = { .ghz5 = 0x0014, .ghz2 = 0x0014, UPLOAD, },
+  [B2055_C1_TX_PADIDAC2]       = { .ghz5 = 0x0033, .ghz2 = 0x0033, NOUPLOAD, },
+  [B2055_C1_TX_MXBGTRIM]       = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+  [B2055_C1_TX_RF_RCAL]                = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+  [B2055_C1_TX_RF_PADTSSI1]    = { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, },
+  [B2055_C1_TX_RF_PADTSSI2]    = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
+  [B2055_C1_TX_RF_SPARE]       = { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, },
+  [B2055_C1_TX_RF_IQCAL1]      = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
+  [B2055_C1_TX_RF_IQCAL2]      = { .ghz5 = 0x00A4, .ghz2 = 0x00A4, NOUPLOAD, },
+  [B2055_C1_TXBB_RCCAL]                = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
+  [B2055_C1_TXBB_LPF1]         = { .ghz5 = 0x0028, .ghz2 = 0x0028, NOUPLOAD, },
+  [B2055_C1_TX_VOSCNCL]                = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C1_TX_LPF_MXGMIDAC]   = { .ghz5 = 0x004A, .ghz2 = 0x004A, NOUPLOAD, },
+  [B2055_C1_TX_BB_MXGM]                = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C2_LGBUF_ATUNE]       = { .ghz5 = 0x00F8, .ghz2 = 0x00F8, NOUPLOAD, },
+  [B2055_C2_LGBUF_GTUNE]       = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+  [B2055_C2_LGBUF_DIV]         = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+  [B2055_C2_LGBUF_AIDAC]       = { .ghz5 = 0x0088, .ghz2 = 0x0008, UPLOAD, },
+  [B2055_C2_LGBUF_GIDAC]       = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+  [B2055_C2_LGBUF_IDACFO]      = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C2_LGBUF_SPARE]       = { .ghz5 = 0x0001, .ghz2 = 0x0001, UPLOAD, },
+  [B2055_C2_RX_RFSPC1]         = { .ghz5 = 0x008A, .ghz2 = 0x008A, NOUPLOAD, },
+  [B2055_C2_RX_RFR1]           = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+  [B2055_C2_RX_RFR2]           = { .ghz5 = 0x0083, .ghz2 = 0x0083, NOUPLOAD, },
+  [B2055_C2_RX_RFRCAL]         = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+  [B2055_C2_RX_BB_BLCMP]       = { .ghz5 = 0x00A0, .ghz2 = 0x00A0, NOUPLOAD, },
+  [B2055_C2_RX_BB_LPF]         = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
+  [B2055_C2_RX_BB_MIDACHP]     = { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, },
+  [B2055_C2_RX_BB_VGA1IDAC]    = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
+  [B2055_C2_RX_BB_VGA2IDAC]    = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
+  [B2055_C2_RX_BB_VGA3IDAC]    = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
+  [B2055_C2_RX_BB_BUFOCTL]     = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
+  [B2055_C2_RX_BB_RCCALCTL]    = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
+  [B2055_C2_RX_BB_RSSICTL1]    = { .ghz5 = 0x006A, .ghz2 = 0x006A, UPLOAD, },
+  [B2055_C2_RX_BB_RSSICTL2]    = { .ghz5 = 0x00AB, .ghz2 = 0x00AB, UPLOAD, },
+  [B2055_C2_RX_BB_RSSICTL3]    = { .ghz5 = 0x0013, .ghz2 = 0x0013, UPLOAD, },
+  [B2055_C2_RX_BB_RSSICTL4]    = { .ghz5 = 0x00C1, .ghz2 = 0x00C1, UPLOAD, },
+  [B2055_C2_RX_BB_RSSICTL5]    = { .ghz5 = 0x00AA, .ghz2 = 0x00AA, UPLOAD, },
+  [B2055_C2_RX_BB_REG]         = { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, },
+  [B2055_C2_RX_BB_SPARE1]      = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C2_RX_TXBBRCAL]       = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+  [B2055_C2_TX_RF_SPGA]                = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+  [B2055_C2_TX_RF_SPAD]                = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+  [B2055_C2_TX_RF_CNTPGA1]     = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
+  [B2055_C2_TX_RF_CNTPAD1]     = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, },
+  [B2055_C2_TX_RF_PGAIDAC]     = { .ghz5 = 0x0097, .ghz2 = 0x0097, UPLOAD, },
+  [B2055_C2_TX_PGAPADTN]       = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+  [B2055_C2_TX_PADIDAC1]       = { .ghz5 = 0x0014, .ghz2 = 0x0014, UPLOAD, },
+  [B2055_C2_TX_PADIDAC2]       = { .ghz5 = 0x0033, .ghz2 = 0x0033, NOUPLOAD, },
+  [B2055_C2_TX_MXBGTRIM]       = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+  [B2055_C2_TX_RF_RCAL]                = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+  [B2055_C2_TX_RF_PADTSSI1]    = { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, },
+  [B2055_C2_TX_RF_PADTSSI2]    = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
+  [B2055_C2_TX_RF_SPARE]       = { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, },
+  [B2055_C2_TX_RF_IQCAL1]      = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
+  [B2055_C2_TX_RF_IQCAL2]      = { .ghz5 = 0x00A4, .ghz2 = 0x00A4, NOUPLOAD, },
+  [B2055_C2_TXBB_RCCAL]                = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
+  [B2055_C2_TXBB_LPF1]         = { .ghz5 = 0x0028, .ghz2 = 0x0028, NOUPLOAD, },
+  [B2055_C2_TX_VOSCNCL]                = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C2_TX_LPF_MXGMIDAC]   = { .ghz5 = 0x004A, .ghz2 = 0x004A, NOUPLOAD, },
+  [B2055_C2_TX_BB_MXGM]                = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_PRG_GCHP21]           = { .ghz5 = 0x0071, .ghz2 = 0x0071, NOUPLOAD, },
+  [B2055_PRG_GCHP22]           = { .ghz5 = 0x0072, .ghz2 = 0x0072, NOUPLOAD, },
+  [B2055_PRG_GCHP23]           = { .ghz5 = 0x0073, .ghz2 = 0x0073, NOUPLOAD, },
+  [B2055_PRG_GCHP24]           = { .ghz5 = 0x0074, .ghz2 = 0x0074, NOUPLOAD, },
+  [B2055_PRG_GCHP25]           = { .ghz5 = 0x0075, .ghz2 = 0x0075, NOUPLOAD, },
+  [B2055_PRG_GCHP26]           = { .ghz5 = 0x0076, .ghz2 = 0x0076, NOUPLOAD, },
+  [B2055_PRG_GCHP27]           = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, },
+  [B2055_PRG_GCHP28]           = { .ghz5 = 0x0078, .ghz2 = 0x0078, NOUPLOAD, },
+  [B2055_PRG_GCHP29]           = { .ghz5 = 0x0079, .ghz2 = 0x0079, NOUPLOAD, },
+  [B2055_PRG_GCHP30]           = { .ghz5 = 0x007A, .ghz2 = 0x007A, NOUPLOAD, },
+  [0xC7]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xC8]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xC9]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xCA]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xCB]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xCC]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C1_LNA_GAINBST]       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xCE]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xCF]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xD0]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xD1]                       = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
+  [B2055_C1_B0NB_RSSIVCM]      = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+  [0xD3]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xD4]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xD5]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C1_GENSPARE2]         = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xD7]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xD8]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C2_LNA_GAINBST]       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xDA]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xDB]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xDC]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xDD]                       = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
+  [B2055_C2_B0NB_RSSIVCM]      = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+  [0xDF]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xE0]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xE1]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C2_GENSPARE2]         = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+};
+
+#define RADIOREGS(r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, \
+                 r12, r13, r14, r15, r16, r17, r18, r19, r20, r21) \
+       .radio_pll_ref          = r0,   \
+       .radio_rf_pllmod0       = r1,   \
+       .radio_rf_pllmod1       = r2,   \
+       .radio_vco_captail      = r3,   \
+       .radio_vco_cal1         = r4,   \
+       .radio_vco_cal2         = r5,   \
+       .radio_pll_lfc1         = r6,   \
+       .radio_pll_lfr1         = r7,   \
+       .radio_pll_lfc2         = r8,   \
+       .radio_lgbuf_cenbuf     = r9,   \
+       .radio_lgen_tune1       = r10,  \
+       .radio_lgen_tune2       = r11,  \
+       .radio_c1_lgbuf_atune   = r12,  \
+       .radio_c1_lgbuf_gtune   = r13,  \
+       .radio_c1_rx_rfr1       = r14,  \
+       .radio_c1_tx_pgapadtn   = r15,  \
+       .radio_c1_tx_mxbgtrim   = r16,  \
+       .radio_c2_lgbuf_atune   = r17,  \
+       .radio_c2_lgbuf_gtune   = r18,  \
+       .radio_c2_rx_rfr1       = r19,  \
+       .radio_c2_tx_pgapadtn   = r20,  \
+       .radio_c2_tx_mxbgtrim   = r21
+
+#define PHYREGS(r0, r1, r2, r3, r4, r5)        \
+       .phy_regs.phy_bw1a      = r0,   \
+       .phy_regs.phy_bw2       = r1,   \
+       .phy_regs.phy_bw3       = r2,   \
+       .phy_regs.phy_bw4       = r3,   \
+       .phy_regs.phy_bw5       = r4,   \
+       .phy_regs.phy_bw6       = r5
+
+static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = {
+  {    .channel                = 184,
+       .freq                   = 4920, /* MHz */
+       .unk2                   = 3280,
+       RADIOREGS(0x71, 0x01, 0xEC, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+                 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F,
+                 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+       PHYREGS(0xB407, 0xB007, 0xAC07, 0x1402, 0x1502, 0x1602),
+  },
+  {    .channel                = 186,
+       .freq                   = 4930, /* MHz */
+       .unk2                   = 3287,
+       RADIOREGS(0x71, 0x01, 0xED, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+                 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F,
+                 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+       PHYREGS(0xB807, 0xB407, 0xB007, 0x1302, 0x1402, 0x1502),
+  },
+  {    .channel                = 188,
+       .freq                   = 4940, /* MHz */
+       .unk2                   = 3293,
+       RADIOREGS(0x71, 0x01, 0xEE, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+                 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
+                 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+       PHYREGS(0xBC07, 0xB807, 0xB407, 0x1202, 0x1302, 0x1402),
+  },
+  {    .channel                = 190,
+       .freq                   = 4950, /* MHz */
+       .unk2                   = 3300,
+       RADIOREGS(0x71, 0x01, 0xEF, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+                 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
+                 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+       PHYREGS(0xC007, 0xBC07, 0xB807, 0x1102, 0x1202, 0x1302),
+  },
+  {    .channel                = 192,
+       .freq                   = 4960, /* MHz */
+       .unk2                   = 3307,
+       RADIOREGS(0x71, 0x01, 0xF0, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+                 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
+                 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+       PHYREGS(0xC407, 0xC007, 0xBC07, 0x0F02, 0x1102, 0x1202),
+  },
+  {    .channel                = 194,
+       .freq                   = 4970, /* MHz */
+       .unk2                   = 3313,
+       RADIOREGS(0x71, 0x01, 0xF1, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+                 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
+                 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+       PHYREGS(0xC807, 0xC407, 0xC007, 0x0E02, 0x0F02, 0x1102),
+  },
+  {    .channel                = 196,
+       .freq                   = 4980, /* MHz */
+       .unk2                   = 3320,
+       RADIOREGS(0x71, 0x01, 0xF2, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
+                 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
+                 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+       PHYREGS(0xCC07, 0xC807, 0xC407, 0x0D02, 0x0E02, 0x0F02),
+  },
+  {    .channel                = 198,
+       .freq                   = 4990, /* MHz */
+       .unk2                   = 3327,
+       RADIOREGS(0x71, 0x01, 0xF3, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
+                 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
+                 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+       PHYREGS(0xD007, 0xCC07, 0xC807, 0x0C02, 0x0D02, 0x0E02),
+  },
+  {    .channel                = 200,
+       .freq                   = 5000, /* MHz */
+       .unk2                   = 3333,
+       RADIOREGS(0x71, 0x01, 0xF4, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
+                 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
+                 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+       PHYREGS(0xD407, 0xD007, 0xCC07, 0x0B02, 0x0C02, 0x0D02),
+  },
+  {    .channel                = 202,
+       .freq                   = 5010, /* MHz */
+       .unk2                   = 3340,
+       RADIOREGS(0x71, 0x01, 0xF5, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
+                 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
+                 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+       PHYREGS(0xD807, 0xD407, 0xD007, 0x0A02, 0x0B02, 0x0C02),
+  },
+  {    .channel                = 204,
+       .freq                   = 5020, /* MHz */
+       .unk2                   = 3347,
+       RADIOREGS(0x71, 0x01, 0xF6, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
+                 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
+                 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+       PHYREGS(0xDC07, 0xD807, 0xD407, 0x0902, 0x0A02, 0x0B02),
+  },
+  {    .channel                = 206,
+       .freq                   = 5030, /* MHz */
+       .unk2                   = 3353,
+       RADIOREGS(0x71, 0x01, 0xF7, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
+                 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
+                 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+       PHYREGS(0xE007, 0xDC07, 0xD807, 0x0802, 0x0902, 0x0A02),
+  },
+  {    .channel                = 208,
+       .freq                   = 5040, /* MHz */
+       .unk2                   = 3360,
+       RADIOREGS(0x71, 0x01, 0xF8, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
+                 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
+                 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+       PHYREGS(0xE407, 0xE007, 0xDC07, 0x0702, 0x0802, 0x0902),
+  },
+  {    .channel                = 210,
+       .freq                   = 5050, /* MHz */
+       .unk2                   = 3367,
+       RADIOREGS(0x71, 0x01, 0xF9, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
+                 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
+                 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+       PHYREGS(0xE807, 0xE407, 0xE007, 0x0602, 0x0702, 0x0802),
+  },
+  {    .channel                = 212,
+       .freq                   = 5060, /* MHz */
+       .unk2                   = 3373,
+       RADIOREGS(0x71, 0x01, 0xFA, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
+                 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F,
+                 0x8E, 0xFF, 0x00, 0x0E, 0x0F, 0x8E),
+       PHYREGS(0xEC07, 0xE807, 0xE407, 0x0502, 0x0602, 0x0702),
+  },
+  {    .channel                = 214,
+       .freq                   = 5070, /* MHz */
+       .unk2                   = 3380,
+       RADIOREGS(0x71, 0x01, 0xFB, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
+                 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F,
+                 0x8E, 0xFF, 0x00, 0x0E, 0x0F, 0x8E),
+       PHYREGS(0xF007, 0xEC07, 0xE807, 0x0402, 0x0502, 0x0602),
+  },
+  {    .channel                = 216,
+       .freq                   = 5080, /* MHz */
+       .unk2                   = 3387,
+       RADIOREGS(0x71, 0x01, 0xFC, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
+                 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F,
+                 0x8D, 0xEE, 0x00, 0x0E, 0x0F, 0x8D),
+       PHYREGS(0xF407, 0xF007, 0xEC07, 0x0302, 0x0402, 0x0502),
+  },
+  {    .channel                = 218,
+       .freq                   = 5090, /* MHz */
+       .unk2                   = 3393,
+       RADIOREGS(0x71, 0x01, 0xFD, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
+                 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F,
+                 0x8D, 0xEE, 0x00, 0x0E, 0x0F, 0x8D),
+       PHYREGS(0xF807, 0xF407, 0xF007, 0x0202, 0x0302, 0x0402),
+  },
+  {    .channel                = 220,
+       .freq                   = 5100, /* MHz */
+       .unk2                   = 3400,
+       RADIOREGS(0x71, 0x01, 0xFE, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
+                 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F,
+                 0x8D, 0xEE, 0x00, 0x0D, 0x0F, 0x8D),
+       PHYREGS(0xFC07, 0xF807, 0xF407, 0x0102, 0x0202, 0x0302),
+  },
+  {    .channel                = 222,
+       .freq                   = 5110, /* MHz */
+       .unk2                   = 3407,
+       RADIOREGS(0x71, 0x01, 0xFF, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
+                 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F,
+                 0x8D, 0xEE, 0x00, 0x0D, 0x0F, 0x8D),
+       PHYREGS(0x0008, 0xFC07, 0xF807, 0x0002, 0x0102, 0x0202),
+  },
+  {    .channel                = 224,
+       .freq                   = 5120, /* MHz */
+       .unk2                   = 3413,
+       RADIOREGS(0x71, 0x02, 0x00, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
+                 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F,
+                 0x8C, 0xDD, 0x00, 0x0D, 0x0F, 0x8C),
+       PHYREGS(0x0408, 0x0008, 0xFC07, 0xFF01, 0x0002, 0x0102),
+  },
+  {    .channel                = 226,
+       .freq                   = 5130, /* MHz */
+       .unk2                   = 3420,
+       RADIOREGS(0x71, 0x02, 0x01, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
+                 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F,
+                 0x8C, 0xDD, 0x00, 0x0D, 0x0F, 0x8C),
+       PHYREGS(0x0808, 0x0408, 0x0008, 0xFE01, 0xFF01, 0x0002),
+  },
+  {    .channel                = 228,
+       .freq                   = 5140, /* MHz */
+       .unk2                   = 3427,
+       RADIOREGS(0x71, 0x02, 0x02, 0x0C, 0xC6, 0x01, 0x04, 0x0A,
+                 0x00, 0x8D, 0x99, 0x99, 0xDD, 0x00, 0x0C, 0x0E,
+                 0x8B, 0xDD, 0x00, 0x0C, 0x0E, 0x8B),
+       PHYREGS(0x0C08, 0x0808, 0x0408, 0xFD01, 0xFE01, 0xFF01),
+  },
+  {    .channel                = 32,
+       .freq                   = 5160, /* MHz */
+       .unk2                   = 3440,
+       RADIOREGS(0x71, 0x02, 0x04, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
+                 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D,
+                 0x8A, 0xCC, 0x00, 0x0B, 0x0D, 0x8A),
+       PHYREGS(0x1408, 0x1008, 0x0C08, 0xFB01, 0xFC01, 0xFD01),
+  },
+  {    .channel                = 34,
+       .freq                   = 5170, /* MHz */
+       .unk2                   = 3447,
+       RADIOREGS(0x71, 0x02, 0x05, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
+                 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D,
+                 0x8A, 0xCC, 0x00, 0x0B, 0x0D, 0x8A),
+       PHYREGS(0x1808, 0x1408, 0x1008, 0xFA01, 0xFB01, 0xFC01),
+  },
+  {    .channel                = 36,
+       .freq                   = 5180, /* MHz */
+       .unk2                   = 3453,
+       RADIOREGS(0x71, 0x02, 0x06, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
+                 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C,
+                 0x89, 0xCC, 0x00, 0x0B, 0x0C, 0x89),
+       PHYREGS(0x1C08, 0x1808, 0x1408, 0xF901, 0xFA01, 0xFB01),
+  },
+  {    .channel                = 38,
+       .freq                   = 5190, /* MHz */
+       .unk2                   = 3460,
+       RADIOREGS(0x71, 0x02, 0x07, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
+                 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C,
+                 0x89, 0xCC, 0x00, 0x0B, 0x0C, 0x89),
+       PHYREGS(0x2008, 0x1C08, 0x1808, 0xF801, 0xF901, 0xFA01),
+  },
+  {    .channel                = 40,
+       .freq                   = 5200, /* MHz */
+       .unk2                   = 3467,
+       RADIOREGS(0x71, 0x02, 0x08, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
+                 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B,
+                 0x89, 0xBB, 0x00, 0x0A, 0x0B, 0x89),
+       PHYREGS(0x2408, 0x2008, 0x1C08, 0xF701, 0xF801, 0xF901),
+  },
+  {    .channel                = 42,
+       .freq                   = 5210, /* MHz */
+       .unk2                   = 3473,
+       RADIOREGS(0x71, 0x02, 0x09, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
+                 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B,
+                 0x89, 0xBB, 0x00, 0x0A, 0x0B, 0x89),
+       PHYREGS(0x2808, 0x2408, 0x2008, 0xF601, 0xF701, 0xF801),
+  },
+  {    .channel                = 44,
+       .freq                   = 5220, /* MHz */
+       .unk2                   = 3480,
+       RADIOREGS(0x71, 0x02, 0x0A, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
+                 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A,
+                 0x88, 0xBB, 0x00, 0x09, 0x0A, 0x88),
+       PHYREGS(0x2C08, 0x2808, 0x2408, 0xF501, 0xF601, 0xF701),
+  },
+  {    .channel                = 46,
+       .freq                   = 5230, /* MHz */
+       .unk2                   = 3487,
+       RADIOREGS(0x71, 0x02, 0x0B, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
+                 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A,
+                 0x88, 0xBB, 0x00, 0x09, 0x0A, 0x88),
+       PHYREGS(0x3008, 0x2C08, 0x2808, 0xF401, 0xF501, 0xF601),
+  },
+  {    .channel                = 48,
+       .freq                   = 5240, /* MHz */
+       .unk2                   = 3493,
+       RADIOREGS(0x71, 0x02, 0x0C, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
+                 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A,
+                 0x87, 0xAA, 0x00, 0x09, 0x0A, 0x87),
+       PHYREGS(0x3408, 0x3008, 0x2C08, 0xF301, 0xF401, 0xF501),
+  },
+  {    .channel                = 50,
+       .freq                   = 5250, /* MHz */
+       .unk2                   = 3500,
+       RADIOREGS(0x71, 0x02, 0x0D, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
+                 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A,
+                 0x87, 0xAA, 0x00, 0x09, 0x0A, 0x87),
+       PHYREGS(0x3808, 0x3408, 0x3008, 0xF201, 0xF301, 0xF401),
+  },
+  {    .channel                = 52,
+       .freq                   = 5260, /* MHz */
+       .unk2                   = 3507,
+       RADIOREGS(0x71, 0x02, 0x0E, 0x0A, 0x98, 0x01, 0x04, 0x0A,
+                 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09,
+                 0x87, 0xAA, 0x00, 0x08, 0x09, 0x87),
+       PHYREGS(0x3C08, 0x3808, 0x3408, 0xF101, 0xF201, 0xF301),
+  },
+  {    .channel                = 54,
+       .freq                   = 5270, /* MHz */
+       .unk2                   = 3513,
+       RADIOREGS(0x71, 0x02, 0x0F, 0x0A, 0x98, 0x01, 0x04, 0x0A,
+                 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09,
+                 0x87, 0xAA, 0x00, 0x08, 0x09, 0x87),
+       PHYREGS(0x4008, 0x3C08, 0x3808, 0xF001, 0xF101, 0xF201),
+  },
+  {    .channel                = 56,
+       .freq                   = 5280, /* MHz */
+       .unk2                   = 3520,
+       RADIOREGS(0x71, 0x02, 0x10, 0x09, 0x91, 0x01, 0x04, 0x0A,
+                 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08,
+                 0x86, 0x99, 0x00, 0x08, 0x08, 0x86),
+       PHYREGS(0x4408, 0x4008, 0x3C08, 0xF001, 0xF001, 0xF101),
+  },
+  {    .channel                = 58,
+       .freq                   = 5290, /* MHz */
+       .unk2                   = 3527,
+       RADIOREGS(0x71, 0x02, 0x11, 0x09, 0x91, 0x01, 0x04, 0x0A,
+                 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08,
+                 0x86, 0x99, 0x00, 0x08, 0x08, 0x86),
+       PHYREGS(0x4808, 0x4408, 0x4008, 0xEF01, 0xF001, 0xF001),
+  },
+  {    .channel                = 60,
+       .freq                   = 5300, /* MHz */
+       .unk2                   = 3533,
+       RADIOREGS(0x71, 0x02, 0x12, 0x09, 0x8A, 0x01, 0x04, 0x0A,
+                 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07,
+                 0x85, 0x99, 0x00, 0x08, 0x07, 0x85),
+       PHYREGS(0x4C08, 0x4808, 0x4408, 0xEE01, 0xEF01, 0xF001),
+  },
+  {    .channel                = 62,
+       .freq                   = 5310, /* MHz */
+       .unk2                   = 3540,
+       RADIOREGS(0x71, 0x02, 0x13, 0x09, 0x8A, 0x01, 0x04, 0x0A,
+                 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07,
+                 0x85, 0x99, 0x00, 0x08, 0x07, 0x85),
+       PHYREGS(0x5008, 0x4C08, 0x4808, 0xED01, 0xEE01, 0xEF01),
+  },
+  {    .channel                = 64,
+       .freq                   = 5320, /* MHz */
+       .unk2                   = 3547,
+       RADIOREGS(0x71, 0x02, 0x14, 0x09, 0x83, 0x01, 0x04, 0x0A,
+                 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07,
+                 0x84, 0x88, 0x00, 0x07, 0x07, 0x84),
+       PHYREGS(0x5408, 0x5008, 0x4C08, 0xEC01, 0xED01, 0xEE01),
+  },
+  {    .channel                = 66,
+       .freq                   = 5330, /* MHz */
+       .unk2                   = 3553,
+       RADIOREGS(0x71, 0x02, 0x15, 0x09, 0x83, 0x01, 0x04, 0x0A,
+                 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07,
+                 0x84, 0x88, 0x00, 0x07, 0x07, 0x84),
+       PHYREGS(0x5808, 0x5408, 0x5008, 0xEB01, 0xEC01, 0xED01),
+  },
+  {    .channel                = 68,
+       .freq                   = 5340, /* MHz */
+       .unk2                   = 3560,
+       RADIOREGS(0x71, 0x02, 0x16, 0x08, 0x7C, 0x01, 0x04, 0x0A,
+                 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06,
+                 0x84, 0x88, 0x00, 0x07, 0x06, 0x84),
+       PHYREGS(0x5C08, 0x5808, 0x5408, 0xEA01, 0xEB01, 0xEC01),
+  },
+  {    .channel                = 70,
+       .freq                   = 5350, /* MHz */
+       .unk2                   = 3567,
+       RADIOREGS(0x71, 0x02, 0x17, 0x08, 0x7C, 0x01, 0x04, 0x0A,
+                 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06,
+                 0x84, 0x88, 0x00, 0x07, 0x06, 0x84),
+       PHYREGS(0x6008, 0x5C08, 0x5808, 0xE901, 0xEA01, 0xEB01),
+  },
+  {    .channel                = 72,
+       .freq                   = 5360, /* MHz */
+       .unk2                   = 3573,
+       RADIOREGS(0x71, 0x02, 0x18, 0x08, 0x75, 0x01, 0x04, 0x0A,
+                 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05,
+                 0x83, 0x77, 0x00, 0x06, 0x05, 0x83),
+       PHYREGS(0x6408, 0x6008, 0x5C08, 0xE801, 0xE901, 0xEA01),
+  },
+  {    .channel                = 74,
+       .freq                   = 5370, /* MHz */
+       .unk2                   = 3580,
+       RADIOREGS(0x71, 0x02, 0x19, 0x08, 0x75, 0x01, 0x04, 0x0A,
+                 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05,
+                 0x83, 0x77, 0x00, 0x06, 0x05, 0x83),
+       PHYREGS(0x6808, 0x6408, 0x6008, 0xE701, 0xE801, 0xE901),
+  },
+  {    .channel                = 76,
+       .freq                   = 5380, /* MHz */
+       .unk2                   = 3587,
+       RADIOREGS(0x71, 0x02, 0x1A, 0x08, 0x6E, 0x01, 0x04, 0x0A,
+                 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04,
+                 0x82, 0x77, 0x00, 0x06, 0x04, 0x82),
+       PHYREGS(0x6C08, 0x6808, 0x6408, 0xE601, 0xE701, 0xE801),
+  },
+  {    .channel                = 78,
+       .freq                   = 5390, /* MHz */
+       .unk2                   = 3593,
+       RADIOREGS(0x71, 0x02, 0x1B, 0x08, 0x6E, 0x01, 0x04, 0x0A,
+                 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04,
+                 0x82, 0x77, 0x00, 0x06, 0x04, 0x82),
+       PHYREGS(0x7008, 0x6C08, 0x6808, 0xE501, 0xE601, 0xE701),
+  },
+  {    .channel                = 80,
+       .freq                   = 5400, /* MHz */
+       .unk2                   = 3600,
+       RADIOREGS(0x71, 0x02, 0x1C, 0x07, 0x67, 0x01, 0x04, 0x0A,
+                 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04,
+                 0x81, 0x66, 0x00, 0x05, 0x04, 0x81),
+       PHYREGS(0x7408, 0x7008, 0x6C08, 0xE501, 0xE501, 0xE601),
+  },
+  {    .channel                = 82,
+       .freq                   = 5410, /* MHz */
+       .unk2                   = 3607,
+       RADIOREGS(0x71, 0x02, 0x1D, 0x07, 0x67, 0x01, 0x04, 0x0A,
+                 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04,
+                 0x81, 0x66, 0x00, 0x05, 0x04, 0x81),
+       PHYREGS(0x7808, 0x7408, 0x7008, 0xE401, 0xE501, 0xE501),
+  },
+  {    .channel                = 84,
+       .freq                   = 5420, /* MHz */
+       .unk2                   = 3613,
+       RADIOREGS(0x71, 0x02, 0x1E, 0x07, 0x61, 0x01, 0x04, 0x0A,
+                 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03,
+                 0x80, 0x66, 0x00, 0x05, 0x03, 0x80),
+       PHYREGS(0x7C08, 0x7808, 0x7408, 0xE301, 0xE401, 0xE501),
+  },
+  {    .channel                = 86,
+       .freq                   = 5430, /* MHz */
+       .unk2                   = 3620,
+       RADIOREGS(0x71, 0x02, 0x1F, 0x07, 0x61, 0x01, 0x04, 0x0A,
+                 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03,
+                 0x80, 0x66, 0x00, 0x05, 0x03, 0x80),
+       PHYREGS(0x8008, 0x7C08, 0x7808, 0xE201, 0xE301, 0xE401),
+  },
+  {    .channel                = 88,
+       .freq                   = 5440, /* MHz */
+       .unk2                   = 3627,
+       RADIOREGS(0x71, 0x02, 0x20, 0x07, 0x5A, 0x01, 0x04, 0x0A,
+                 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02,
+                 0x80, 0x55, 0x00, 0x04, 0x02, 0x80),
+       PHYREGS(0x8408, 0x8008, 0x7C08, 0xE101, 0xE201, 0xE301),
+  },
+  {    .channel                = 90,
+       .freq                   = 5450, /* MHz */
+       .unk2                   = 3633,
+       RADIOREGS(0x71, 0x02, 0x21, 0x07, 0x5A, 0x01, 0x04, 0x0A,
+                 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02,
+                 0x80, 0x55, 0x00, 0x04, 0x02, 0x80),
+       PHYREGS(0x8808, 0x8408, 0x8008, 0xE001, 0xE101, 0xE201),
+  },
+  {    .channel                = 92,
+       .freq                   = 5460, /* MHz */
+       .unk2                   = 3640,
+       RADIOREGS(0x71, 0x02, 0x22, 0x06, 0x53, 0x01, 0x04, 0x0A,
+                 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01,
+                 0x80, 0x55, 0x00, 0x04, 0x01, 0x80),
+       PHYREGS(0x8C08, 0x8808, 0x8408, 0xDF01, 0xE001, 0xE101),
+  },
+  {    .channel                = 94,
+       .freq                   = 5470, /* MHz */
+       .unk2                   = 3647,
+       RADIOREGS(0x71, 0x02, 0x23, 0x06, 0x53, 0x01, 0x04, 0x0A,
+                 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01,
+                 0x80, 0x55, 0x00, 0x04, 0x01, 0x80),
+       PHYREGS(0x9008, 0x8C08, 0x8808, 0xDE01, 0xDF01, 0xE001),
+  },
+  {    .channel                = 96,
+       .freq                   = 5480, /* MHz */
+       .unk2                   = 3653,
+       RADIOREGS(0x71, 0x02, 0x24, 0x06, 0x4D, 0x01, 0x04, 0x0A,
+                 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00,
+                 0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
+       PHYREGS(0x9408, 0x9008, 0x8C08, 0xDD01, 0xDE01, 0xDF01),
+  },
+  {    .channel                = 98,
+       .freq                   = 5490, /* MHz */
+       .unk2                   = 3660,
+       RADIOREGS(0x71, 0x02, 0x25, 0x06, 0x4D, 0x01, 0x04, 0x0A,
+                 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00,
+                 0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
+       PHYREGS(0x9808, 0x9408, 0x9008, 0xDD01, 0xDD01, 0xDE01),
+  },
+  {    .channel                = 100,
+       .freq                   = 5500, /* MHz */
+       .unk2                   = 3667,
+       RADIOREGS(0x71, 0x02, 0x26, 0x06, 0x47, 0x01, 0x04, 0x0A,
+                 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00,
+                 0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
+       PHYREGS(0x9C08, 0x9808, 0x9408, 0xDC01, 0xDD01, 0xDD01),
+  },
+  {    .channel                = 102,
+       .freq                   = 5510, /* MHz */
+       .unk2                   = 3673,
+       RADIOREGS(0x71, 0x02, 0x27, 0x06, 0x47, 0x01, 0x04, 0x0A,
+                 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00,
+                 0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
+       PHYREGS(0xA008, 0x9C08, 0x9808, 0xDB01, 0xDC01, 0xDD01),
+  },
+  {    .channel                = 104,
+       .freq                   = 5520, /* MHz */
+       .unk2                   = 3680,
+       RADIOREGS(0x71, 0x02, 0x28, 0x05, 0x40, 0x01, 0x04, 0x0A,
+                 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
+                 0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
+       PHYREGS(0xA408, 0xA008, 0x9C08, 0xDA01, 0xDB01, 0xDC01),
+  },
+  {    .channel                = 106,
+       .freq                   = 5530, /* MHz */
+       .unk2                   = 3687,
+       RADIOREGS(0x71, 0x02, 0x29, 0x05, 0x40, 0x01, 0x04, 0x0A,
+                 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
+                 0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
+       PHYREGS(0xA808, 0xA408, 0xA008, 0xD901, 0xDA01, 0xDB01),
+  },
+  {    .channel                = 108,
+       .freq                   = 5540, /* MHz */
+       .unk2                   = 3693,
+       RADIOREGS(0x71, 0x02, 0x2A, 0x05, 0x3A, 0x01, 0x04, 0x0A,
+                 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
+                 0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
+       PHYREGS(0xAC08, 0xA808, 0xA408, 0xD801, 0xD901, 0xDA01),
+  },
+  {    .channel                = 110,
+       .freq                   = 5550, /* MHz */
+       .unk2                   = 3700,
+       RADIOREGS(0x71, 0x02, 0x2B, 0x05, 0x3A, 0x01, 0x04, 0x0A,
+                 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
+                 0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
+       PHYREGS(0xB008, 0xAC08, 0xA808, 0xD701, 0xD801, 0xD901),
+  },
+  {    .channel                = 112,
+       .freq                   = 5560, /* MHz */
+       .unk2                   = 3707,
+       RADIOREGS(0x71, 0x02, 0x2C, 0x05, 0x34, 0x01, 0x04, 0x0A,
+                 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
+                 0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
+       PHYREGS(0xB408, 0xB008, 0xAC08, 0xD701, 0xD701, 0xD801),
+  },
+  {    .channel                = 114,
+       .freq                   = 5570, /* MHz */
+       .unk2                   = 3713,
+       RADIOREGS(0x71, 0x02, 0x2D, 0x05, 0x34, 0x01, 0x04, 0x0A,
+                 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
+                 0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
+       PHYREGS(0xB808, 0xB408, 0xB008, 0xD601, 0xD701, 0xD701),
+  },
+  {    .channel                = 116,
+       .freq                   = 5580, /* MHz */
+       .unk2                   = 3720,
+       RADIOREGS(0x71, 0x02, 0x2E, 0x04, 0x2E, 0x01, 0x04, 0x0A,
+                 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
+                 0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
+       PHYREGS(0xBC08, 0xB808, 0xB408, 0xD501, 0xD601, 0xD701),
+  },
+  {    .channel                = 118,
+       .freq                   = 5590, /* MHz */
+       .unk2                   = 3727,
+       RADIOREGS(0x71, 0x02, 0x2F, 0x04, 0x2E, 0x01, 0x04, 0x0A,
+                 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
+                 0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
+       PHYREGS(0xC008, 0xBC08, 0xB808, 0xD401, 0xD501, 0xD601),
+  },
+  {    .channel                = 120,
+       .freq                   = 5600, /* MHz */
+       .unk2                   = 3733,
+       RADIOREGS(0x71, 0x02, 0x30, 0x04, 0x28, 0x01, 0x04, 0x0A,
+                 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00,
+                 0x80, 0x11, 0x00, 0x01, 0x00, 0x80),
+       PHYREGS(0xC408, 0xC008, 0xBC08, 0xD301, 0xD401, 0xD501),
+  },
+  {    .channel                = 122,
+       .freq                   = 5610, /* MHz */
+       .unk2                   = 3740,
+       RADIOREGS(0x71, 0x02, 0x31, 0x04, 0x28, 0x01, 0x04, 0x0A,
+                 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00,
+                 0x80, 0x11, 0x00, 0x01, 0x00, 0x80),
+       PHYREGS(0xC808, 0xC408, 0xC008, 0xD201, 0xD301, 0xD401),
+  },
+  {    .channel                = 124,
+       .freq                   = 5620, /* MHz */
+       .unk2                   = 3747,
+       RADIOREGS(0x71, 0x02, 0x32, 0x04, 0x21, 0x01, 0x04, 0x0A,
+                 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
+                 0x80, 0x11, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0xCC08, 0xC808, 0xC408, 0xD201, 0xD201, 0xD301),
+  },
+  {    .channel                = 126,
+       .freq                   = 5630, /* MHz */
+       .unk2                   = 3753,
+       RADIOREGS(0x71, 0x02, 0x33, 0x04, 0x21, 0x01, 0x04, 0x0A,
+                 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
+                 0x80, 0x11, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0xD008, 0xCC08, 0xC808, 0xD101, 0xD201, 0xD201),
+  },
+  {    .channel                = 128,
+       .freq                   = 5640, /* MHz */
+       .unk2                   = 3760,
+       RADIOREGS(0x71, 0x02, 0x34, 0x03, 0x1C, 0x01, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0xD408, 0xD008, 0xCC08, 0xD001, 0xD101, 0xD201),
+  },
+  {    .channel                = 130,
+       .freq                   = 5650, /* MHz */
+       .unk2                   = 3767,
+       RADIOREGS(0x71, 0x02, 0x35, 0x03, 0x1C, 0x01, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0xD808, 0xD408, 0xD008, 0xCF01, 0xD001, 0xD101),
+  },
+  {    .channel                = 132,
+       .freq                   = 5660, /* MHz */
+       .unk2                   = 3773,
+       RADIOREGS(0x71, 0x02, 0x36, 0x03, 0x16, 0x01, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0xDC08, 0xD808, 0xD408, 0xCE01, 0xCF01, 0xD001),
+  },
+  {    .channel                = 134,
+       .freq                   = 5670, /* MHz */
+       .unk2                   = 3780,
+       RADIOREGS(0x71, 0x02, 0x37, 0x03, 0x16, 0x01, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0xE008, 0xDC08, 0xD808, 0xCE01, 0xCE01, 0xCF01),
+  },
+  {    .channel                = 136,
+       .freq                   = 5680, /* MHz */
+       .unk2                   = 3787,
+       RADIOREGS(0x71, 0x02, 0x38, 0x03, 0x10, 0x01, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0xE408, 0xE008, 0xDC08, 0xCD01, 0xCE01, 0xCE01),
+  },
+  {    .channel                = 138,
+       .freq                   = 5690, /* MHz */
+       .unk2                   = 3793,
+       RADIOREGS(0x71, 0x02, 0x39, 0x03, 0x10, 0x01, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0xE808, 0xE408, 0xE008, 0xCC01, 0xCD01, 0xCE01),
+  },
+  {    .channel                = 140,
+       .freq                   = 5700, /* MHz */
+       .unk2                   = 3800,
+       RADIOREGS(0x71, 0x02, 0x3A, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0xEC08, 0xE808, 0xE408, 0xCB01, 0xCC01, 0xCD01),
+  },
+  {    .channel                = 142,
+       .freq                   = 5710, /* MHz */
+       .unk2                   = 3807,
+       RADIOREGS(0x71, 0x02, 0x3B, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0xF008, 0xEC08, 0xE808, 0xCA01, 0xCB01, 0xCC01),
+  },
+  {    .channel                = 144,
+       .freq                   = 5720, /* MHz */
+       .unk2                   = 3813,
+       RADIOREGS(0x71, 0x02, 0x3C, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0xF408, 0xF008, 0xEC08, 0xC901, 0xCA01, 0xCB01),
+  },
+  {    .channel                = 145,
+       .freq                   = 5725, /* MHz */
+       .unk2                   = 3817,
+       RADIOREGS(0x72, 0x04, 0x79, 0x02, 0x03, 0x01, 0x03, 0x14,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0xF608, 0xF208, 0xEE08, 0xC901, 0xCA01, 0xCB01),
+  },
+  {    .channel                = 146,
+       .freq                   = 5730, /* MHz */
+       .unk2                   = 3820,
+       RADIOREGS(0x71, 0x02, 0x3D, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0xF808, 0xF408, 0xF008, 0xC901, 0xC901, 0xCA01),
+  },
+  {    .channel                = 147,
+       .freq                   = 5735, /* MHz */
+       .unk2                   = 3823,
+       RADIOREGS(0x72, 0x04, 0x7B, 0x02, 0x03, 0x01, 0x03, 0x14,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0xFA08, 0xF608, 0xF208, 0xC801, 0xC901, 0xCA01),
+  },
+  {    .channel                = 148,
+       .freq                   = 5740, /* MHz */
+       .unk2                   = 3827,
+       RADIOREGS(0x71, 0x02, 0x3E, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0xFC08, 0xF808, 0xF408, 0xC801, 0xC901, 0xC901),
+  },
+  {    .channel                = 149,
+       .freq                   = 5745, /* MHz */
+       .unk2                   = 3830,
+       RADIOREGS(0x72, 0x04, 0x7D, 0x02, 0xFE, 0x00, 0x03, 0x14,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0xFE08, 0xFA08, 0xF608, 0xC801, 0xC801, 0xC901),
+  },
+  {    .channel                = 150,
+       .freq                   = 5750, /* MHz */
+       .unk2                   = 3833,
+       RADIOREGS(0x71, 0x02, 0x3F, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x0009, 0xFC08, 0xF808, 0xC701, 0xC801, 0xC901),
+  },
+  {    .channel                = 151,
+       .freq                   = 5755, /* MHz */
+       .unk2                   = 3837,
+       RADIOREGS(0x72, 0x04, 0x7F, 0x02, 0xFE, 0x00, 0x03, 0x14,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x0209, 0xFE08, 0xFA08, 0xC701, 0xC801, 0xC801),
+  },
+  {    .channel                = 152,
+       .freq                   = 5760, /* MHz */
+       .unk2                   = 3840,
+       RADIOREGS(0x71, 0x02, 0x40, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x0409, 0x0009, 0xFC08, 0xC601, 0xC701, 0xC801),
+  },
+  {    .channel                = 153,
+       .freq                   = 5765, /* MHz */
+       .unk2                   = 3843,
+       RADIOREGS(0x72, 0x04, 0x81, 0x02, 0xF8, 0x00, 0x03, 0x14,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x0609, 0x0209, 0xFE08, 0xC601, 0xC701, 0xC801),
+  },
+  {    .channel                = 154,
+       .freq                   = 5770, /* MHz */
+       .unk2                   = 3847,
+       RADIOREGS(0x71, 0x02, 0x41, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x0809, 0x0409, 0x0009, 0xC601, 0xC601, 0xC701),
+  },
+  {    .channel                = 155,
+       .freq                   = 5775, /* MHz */
+       .unk2                   = 3850,
+       RADIOREGS(0x72, 0x04, 0x83, 0x02, 0xF8, 0x00, 0x03, 0x14,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x0A09, 0x0609, 0x0209, 0xC501, 0xC601, 0xC701),
+  },
+  {    .channel                = 156,
+       .freq                   = 5780, /* MHz */
+       .unk2                   = 3853,
+       RADIOREGS(0x71, 0x02, 0x42, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x0C09, 0x0809, 0x0409, 0xC501, 0xC601, 0xC601),
+  },
+  {    .channel                = 157,
+       .freq                   = 5785, /* MHz */
+       .unk2                   = 3857,
+       RADIOREGS(0x72, 0x04, 0x85, 0x02, 0xF2, 0x00, 0x03, 0x14,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x0E09, 0x0A09, 0x0609, 0xC401, 0xC501, 0xC601),
+  },
+  {    .channel                = 158,
+       .freq                   = 5790, /* MHz */
+       .unk2                   = 3860,
+       RADIOREGS(0x71, 0x02, 0x43, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x1009, 0x0C09, 0x0809, 0xC401, 0xC501, 0xC601),
+  },
+  {    .channel                = 159,
+       .freq                   = 5795, /* MHz */
+       .unk2                   = 3863,
+       RADIOREGS(0x72, 0x04, 0x87, 0x02, 0xF2, 0x00, 0x03, 0x14,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x1209, 0x0E09, 0x0A09, 0xC401, 0xC401, 0xC501),
+  },
+  {    .channel                = 160,
+       .freq                   = 5800, /* MHz */
+       .unk2                   = 3867,
+       RADIOREGS(0x71, 0x02, 0x44, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x1409, 0x1009, 0x0C09, 0xC301, 0xC401, 0xC501),
+  },
+  {    .channel                = 161,
+       .freq                   = 5805, /* MHz */
+       .unk2                   = 3870,
+       RADIOREGS(0x72, 0x04, 0x89, 0x01, 0xED, 0x00, 0x03, 0x14,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x1609, 0x1209, 0x0E09, 0xC301, 0xC401, 0xC401),
+  },
+  {    .channel                = 162,
+       .freq                   = 5810, /* MHz */
+       .unk2                   = 3873,
+       RADIOREGS(0x71, 0x02, 0x45, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x1809, 0x1409, 0x1009, 0xC201, 0xC301, 0xC401),
+  },
+  {    .channel                = 163,
+       .freq                   = 5815, /* MHz */
+       .unk2                   = 3877,
+       RADIOREGS(0x72, 0x04, 0x8B, 0x01, 0xED, 0x00, 0x03, 0x14,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x1A09, 0x1609, 0x1209, 0xC201, 0xC301, 0xC401),
+  },
+  {    .channel                = 164,
+       .freq                   = 5820, /* MHz */
+       .unk2                   = 3880,
+       RADIOREGS(0x71, 0x02, 0x46, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x1C09, 0x1809, 0x1409, 0xC201, 0xC201, 0xC301),
+  },
+  {    .channel                = 165,
+       .freq                   = 5825, /* MHz */
+       .unk2                   = 3883,
+       RADIOREGS(0x72, 0x04, 0x8D, 0x01, 0xED, 0x00, 0x03, 0x14,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x1E09, 0x1A09, 0x1609, 0xC101, 0xC201, 0xC301),
+  },
+  {    .channel                = 166,
+       .freq                   = 5830, /* MHz */
+       .unk2                   = 3887,
+       RADIOREGS(0x71, 0x02, 0x47, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x2009, 0x1C09, 0x1809, 0xC101, 0xC201, 0xC201),
+  },
+  {    .channel                = 168,
+       .freq                   = 5840, /* MHz */
+       .unk2                   = 3893,
+       RADIOREGS(0x71, 0x02, 0x48, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x2409, 0x2009, 0x1C09, 0xC001, 0xC101, 0xC201),
+  },
+  {    .channel                = 170,
+       .freq                   = 5850, /* MHz */
+       .unk2                   = 3900,
+       RADIOREGS(0x71, 0x02, 0x49, 0x01, 0xE0, 0x00, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x2809, 0x2409, 0x2009, 0xBF01, 0xC001, 0xC101),
+  },
+  {    .channel                = 172,
+       .freq                   = 5860, /* MHz */
+       .unk2                   = 3907,
+       RADIOREGS(0x71, 0x02, 0x4A, 0x01, 0xDE, 0x00, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x2C09, 0x2809, 0x2409, 0xBF01, 0xBF01, 0xC001),
+  },
+  {    .channel                = 174,
+       .freq                   = 5870, /* MHz */
+       .unk2                   = 3913,
+       RADIOREGS(0x71, 0x02, 0x4B, 0x00, 0xDB, 0x00, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x3009, 0x2C09, 0x2809, 0xBE01, 0xBF01, 0xBF01),
+  },
+  {    .channel                = 176,
+       .freq                   = 5880, /* MHz */
+       .unk2                   = 3920,
+       RADIOREGS(0x71, 0x02, 0x4C, 0x00, 0xD8, 0x00, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x3409, 0x3009, 0x2C09, 0xBD01, 0xBE01, 0xBF01),
+  },
+  {    .channel                = 178,
+       .freq                   = 5890, /* MHz */
+       .unk2                   = 3927,
+       RADIOREGS(0x71, 0x02, 0x4D, 0x00, 0xD6, 0x00, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x3809, 0x3409, 0x3009, 0xBC01, 0xBD01, 0xBE01),
+  },
+  {    .channel                = 180,
+       .freq                   = 5900, /* MHz */
+       .unk2                   = 3933,
+       RADIOREGS(0x71, 0x02, 0x4E, 0x00, 0xD3, 0x00, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x3C09, 0x3809, 0x3409, 0xBC01, 0xBC01, 0xBD01),
+  },
+  {    .channel                = 182,
+       .freq                   = 5910, /* MHz */
+       .unk2                   = 3940,
+       RADIOREGS(0x71, 0x02, 0x4F, 0x00, 0xD6, 0x00, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x4009, 0x3C09, 0x3809, 0xBB01, 0xBC01, 0xBC01),
+  },
+  {    .channel                = 1,
+       .freq                   = 2412, /* MHz */
+       .unk2                   = 3216,
+       RADIOREGS(0x73, 0x09, 0x6C, 0x0F, 0x00, 0x01, 0x07, 0x15,
+                 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0D, 0x0C,
+                 0x80, 0xFF, 0x88, 0x0D, 0x0C, 0x80),
+       PHYREGS(0xC903, 0xC503, 0xC103, 0x3A04, 0x3F04, 0x4304),
+  },
+  {    .channel                = 2,
+       .freq                   = 2417, /* MHz */
+       .unk2                   = 3223,
+       RADIOREGS(0x73, 0x09, 0x71, 0x0F, 0x00, 0x01, 0x07, 0x15,
+                 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0B,
+                 0x80, 0xFF, 0x88, 0x0C, 0x0B, 0x80),
+       PHYREGS(0xCB03, 0xC703, 0xC303, 0x3804, 0x3D04, 0x4104),
+  },
+  {    .channel                = 3,
+       .freq                   = 2422, /* MHz */
+       .unk2                   = 3229,
+       RADIOREGS(0x73, 0x09, 0x76, 0x0F, 0x00, 0x01, 0x07, 0x15,
+                 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A,
+                 0x80, 0xFF, 0x88, 0x0C, 0x0A, 0x80),
+       PHYREGS(0xCD03, 0xC903, 0xC503, 0x3604, 0x3A04, 0x3F04),
+  },
+  {    .channel                = 4,
+       .freq                   = 2427, /* MHz */
+       .unk2                   = 3236,
+       RADIOREGS(0x73, 0x09, 0x7B, 0x0F, 0x00, 0x01, 0x07, 0x15,
+                 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A,
+                 0x80, 0xFF, 0x88, 0x0C, 0x0A, 0x80),
+       PHYREGS(0xCF03, 0xCB03, 0xC703, 0x3404, 0x3804, 0x3D04),
+  },
+  {    .channel                = 5,
+       .freq                   = 2432, /* MHz */
+       .unk2                   = 3243,
+       RADIOREGS(0x73, 0x09, 0x80, 0x0F, 0x00, 0x01, 0x07, 0x15,
+                 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x09,
+                 0x80, 0xFF, 0x88, 0x0C, 0x09, 0x80),
+       PHYREGS(0xD103, 0xCD03, 0xC903, 0x3104, 0x3604, 0x3A04),
+  },
+  {    .channel                = 6,
+       .freq                   = 2437, /* MHz */
+       .unk2                   = 3249,
+       RADIOREGS(0x73, 0x09, 0x85, 0x0F, 0x00, 0x01, 0x07, 0x15,
+                 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0B, 0x08,
+                 0x80, 0xFF, 0x88, 0x0B, 0x08, 0x80),
+       PHYREGS(0xD303, 0xCF03, 0xCB03, 0x2F04, 0x3404, 0x3804),
+  },
+  {    .channel                = 7,
+       .freq                   = 2442, /* MHz */
+       .unk2                   = 3256,
+       RADIOREGS(0x73, 0x09, 0x8A, 0x0F, 0x00, 0x01, 0x07, 0x15,
+                 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x07,
+                 0x80, 0xFF, 0x88, 0x0A, 0x07, 0x80),
+       PHYREGS(0xD503, 0xD103, 0xCD03, 0x2D04, 0x3104, 0x3604),
+  },
+  {    .channel                = 8,
+       .freq                   = 2447, /* MHz */
+       .unk2                   = 3263,
+       RADIOREGS(0x73, 0x09, 0x8F, 0x0F, 0x00, 0x01, 0x07, 0x15,
+                 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x06,
+                 0x80, 0xFF, 0x88, 0x0A, 0x06, 0x80),
+       PHYREGS(0xD703, 0xD303, 0xCF03, 0x2B04, 0x2F04, 0x3404),
+  },
+  {    .channel                = 9,
+       .freq                   = 2452, /* MHz */
+       .unk2                   = 3269,
+       RADIOREGS(0x73, 0x09, 0x94, 0x0F, 0x00, 0x01, 0x07, 0x15,
+                 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x09, 0x06,
+                 0x80, 0xFF, 0x88, 0x09, 0x06, 0x80),
+       PHYREGS(0xD903, 0xD503, 0xD103, 0x2904, 0x2D04, 0x3104),
+  },
+  {    .channel                = 10,
+       .freq                   = 2457, /* MHz */
+       .unk2                   = 3276,
+       RADIOREGS(0x73, 0x09, 0x99, 0x0F, 0x00, 0x01, 0x07, 0x15,
+                 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x05,
+                 0x80, 0xFF, 0x88, 0x08, 0x05, 0x80),
+       PHYREGS(0xDB03, 0xD703, 0xD303, 0x2704, 0x2B04, 0x2F04),
+  },
+  {    .channel                = 11,
+       .freq                   = 2462, /* MHz */
+       .unk2                   = 3283,
+       RADIOREGS(0x73, 0x09, 0x9E, 0x0F, 0x00, 0x01, 0x07, 0x15,
+                 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x04,
+                 0x80, 0xFF, 0x88, 0x08, 0x04, 0x80),
+       PHYREGS(0xDD03, 0xD903, 0xD503, 0x2404, 0x2904, 0x2D04),
+  },
+  {    .channel                = 12,
+       .freq                   = 2467, /* MHz */
+       .unk2                   = 3289,
+       RADIOREGS(0x73, 0x09, 0xA3, 0x0F, 0x00, 0x01, 0x07, 0x15,
+                 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x03,
+                 0x80, 0xFF, 0x88, 0x08, 0x03, 0x80),
+       PHYREGS(0xDF03, 0xDB03, 0xD703, 0x2204, 0x2704, 0x2B04),
+  },
+  {    .channel                = 13,
+       .freq                   = 2472, /* MHz */
+       .unk2                   = 3296,
+       RADIOREGS(0x73, 0x09, 0xA8, 0x0F, 0x00, 0x01, 0x07, 0x15,
+                 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x03,
+                 0x80, 0xFF, 0x88, 0x07, 0x03, 0x80),
+       PHYREGS(0xE103, 0xDD03, 0xD903, 0x2004, 0x2404, 0x2904),
+  },
+  {    .channel                = 14,
+       .freq                   = 2484, /* MHz */
+       .unk2                   = 3312,
+       RADIOREGS(0x73, 0x09, 0xB4, 0x0F, 0xFF, 0x01, 0x07, 0x15,
+                 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x01,
+                 0x80, 0xFF, 0x88, 0x07, 0x01, 0x80),
+       PHYREGS(0xE603, 0xE203, 0xDE03, 0x1B04, 0x1F04, 0x2404),
+  },
+};
+
+void b2055_upload_inittab(struct b43_wldev *dev,
+                         bool ghz5, bool ignore_uploadflag)
+{
+       const struct b2055_inittab_entry *e;
+       unsigned int i;
+       u16 value;
+
+       for (i = 0; i < ARRAY_SIZE(b2055_inittab); i++) {
+               e = &(b2055_inittab[i]);
+               if (!(e->flags & B2055_INITTAB_ENTRY_OK))
+                       continue;
+               if ((e->flags & B2055_INITTAB_UPLOAD) || ignore_uploadflag) {
+                       if (ghz5)
+                               value = e->ghz5;
+                       else
+                               value = e->ghz2;
+                       b43_radio_write16(dev, i, value);
+               }
+       }
+}
+
+const struct b43_nphy_channeltab_entry_rev2 *
+b43_nphy_get_chantabent_rev2(struct b43_wldev *dev, u8 channel)
+{
+       const struct b43_nphy_channeltab_entry_rev2 *e;
+       unsigned int i;
+
+       for (i = 0; i < ARRAY_SIZE(b43_nphy_channeltab_rev2); i++) {
+               e = &(b43_nphy_channeltab_rev2[i]);
+               if (e->channel == channel)
+                       return e;
+       }
+
+       return NULL;
+}
diff --git a/drivers/net/wireless/b43/radio_2055.h b/drivers/net/wireless/b43/radio_2055.h
new file mode 100644 (file)
index 0000000..d9bfa0f
--- /dev/null
@@ -0,0 +1,254 @@
+#ifndef B43_RADIO_2055_H_
+#define B43_RADIO_2055_H_
+
+#include <linux/types.h>
+
+#include "tables_nphy.h"
+
+#define B2055_GEN_SPARE                        0x00 /* GEN spare */
+#define B2055_SP_PINPD                 0x02 /* SP PIN PD */
+#define B2055_C1_SP_RSSI               0x03 /* SP RSSI Core 1 */
+#define B2055_C1_SP_PDMISC             0x04 /* SP PD MISC Core 1 */
+#define B2055_C2_SP_RSSI               0x05 /* SP RSSI Core 2 */
+#define B2055_C2_SP_PDMISC             0x06 /* SP PD MISC Core 2 */
+#define B2055_C1_SP_RXGC1              0x07 /* SP RX GC1 Core 1 */
+#define B2055_C1_SP_RXGC2              0x08 /* SP RX GC2 Core 1 */
+#define B2055_C2_SP_RXGC1              0x09 /* SP RX GC1 Core 2 */
+#define B2055_C2_SP_RXGC2              0x0A /* SP RX GC2 Core 2 */
+#define B2055_C1_SP_LPFBWSEL           0x0B /* SP LPF BW select Core 1 */
+#define B2055_C2_SP_LPFBWSEL           0x0C /* SP LPF BW select Core 2 */
+#define B2055_C1_SP_TXGC1              0x0D /* SP TX GC1 Core 1 */
+#define B2055_C1_SP_TXGC2              0x0E /* SP TX GC2 Core 1 */
+#define B2055_C2_SP_TXGC1              0x0F /* SP TX GC1 Core 2 */
+#define B2055_C2_SP_TXGC2              0x10 /* SP TX GC2 Core 2 */
+#define B2055_MASTER1                  0x11 /* Master control 1 */
+#define B2055_MASTER2                  0x12 /* Master control 2 */
+#define B2055_PD_LGEN                  0x13 /* PD LGEN */
+#define B2055_PD_PLLTS                 0x14 /* PD PLL TS */
+#define B2055_C1_PD_LGBUF              0x15 /* PD Core 1 LGBUF */
+#define B2055_C1_PD_TX                 0x16 /* PD Core 1 TX */
+#define B2055_C1_PD_RXTX               0x17 /* PD Core 1 RXTX */
+#define B2055_C1_PD_RSSIMISC           0x18 /* PD Core 1 RSSI MISC */
+#define B2055_C2_PD_LGBUF              0x19 /* PD Core 2 LGBUF */
+#define B2055_C2_PD_TX                 0x1A /* PD Core 2 TX */
+#define B2055_C2_PD_RXTX               0x1B /* PD Core 2 RXTX */
+#define B2055_C2_PD_RSSIMISC           0x1C /* PD Core 2 RSSI MISC */
+#define B2055_PWRDET_LGEN              0x1D /* PWRDET LGEN */
+#define B2055_C1_PWRDET_LGBUF          0x1E /* PWRDET LGBUF Core 1 */
+#define B2055_C1_PWRDET_RXTX           0x1F /* PWRDET RXTX Core 1 */
+#define B2055_C2_PWRDET_LGBUF          0x20 /* PWRDET LGBUF Core 2 */
+#define B2055_C2_PWRDET_RXTX           0x21 /* PWRDET RXTX Core 2 */
+#define B2055_RRCCAL_CS                        0x22 /* RRCCAL Control spare */
+#define B2055_RRCCAL_NOPTSEL           0x23 /* RRCCAL N OPT SEL */
+#define B2055_CAL_MISC                 0x24 /* CAL MISC */
+#define B2055_CAL_COUT                 0x25 /* CAL Counter out */
+#define B2055_CAL_COUT2                        0x26 /* CAL Counter out 2 */
+#define B2055_CAL_CVARCTL              0x27 /* CAL CVAR Control */
+#define B2055_CAL_RVARCTL              0x28 /* CAL RVAR Control */
+#define B2055_CAL_LPOCTL               0x29 /* CAL LPO Control */
+#define B2055_CAL_TS                   0x2A /* CAL TS */
+#define B2055_CAL_RCCALRTS             0x2B /* CAL RCCAL READ TS */
+#define B2055_CAL_RCALRTS              0x2C /* CAL RCAL READ TS */
+#define B2055_PADDRV                   0x2D /* PAD driver */
+#define B2055_XOCTL1                   0x2E /* XO Control 1 */
+#define B2055_XOCTL2                   0x2F /* XO Control 2 */
+#define B2055_XOREGUL                  0x30 /* XO Regulator */
+#define B2055_XOMISC                   0x31 /* XO misc */
+#define B2055_PLL_LFC1                 0x32 /* PLL LF C1 */
+#define B2055_PLL_CALVTH               0x33 /* PLL CAL VTH */
+#define B2055_PLL_LFC2                 0x34 /* PLL LF C2 */
+#define B2055_PLL_REF                  0x35 /* PLL reference */
+#define B2055_PLL_LFR1                 0x36 /* PLL LF R1 */
+#define B2055_PLL_PFDCP                        0x37 /* PLL PFD CP */
+#define B2055_PLL_IDAC_CPOPAMP         0x38 /* PLL IDAC CPOPAMP */
+#define B2055_PLL_CPREG                        0x39 /* PLL CP Regulator */
+#define B2055_PLL_RCAL                 0x3A /* PLL RCAL */
+#define B2055_RF_PLLMOD0               0x3B /* RF PLL MOD0 */
+#define B2055_RF_PLLMOD1               0x3C /* RF PLL MOD1 */
+#define B2055_RF_MMDIDAC1              0x3D /* RF MMD IDAC 1 */
+#define B2055_RF_MMDIDAC0              0x3E /* RF MMD IDAC 0 */
+#define B2055_RF_MMDSP                 0x3F /* RF MMD spare */
+#define B2055_VCO_CAL1                 0x40 /* VCO cal 1 */
+#define B2055_VCO_CAL2                 0x41 /* VCO cal 2 */
+#define B2055_VCO_CAL3                 0x42 /* VCO cal 3 */
+#define B2055_VCO_CAL4                 0x43 /* VCO cal 4 */
+#define B2055_VCO_CAL5                 0x44 /* VCO cal 5 */
+#define B2055_VCO_CAL6                 0x45 /* VCO cal 6 */
+#define B2055_VCO_CAL7                 0x46 /* VCO cal 7 */
+#define B2055_VCO_CAL8                 0x47 /* VCO cal 8 */
+#define B2055_VCO_CAL9                 0x48 /* VCO cal 9 */
+#define B2055_VCO_CAL10                        0x49 /* VCO cal 10 */
+#define B2055_VCO_CAL11                        0x4A /* VCO cal 11 */
+#define B2055_VCO_CAL12                        0x4B /* VCO cal 12 */
+#define B2055_VCO_CAL13                        0x4C /* VCO cal 13 */
+#define B2055_VCO_CAL14                        0x4D /* VCO cal 14 */
+#define B2055_VCO_CAL15                        0x4E /* VCO cal 15 */
+#define B2055_VCO_CAL16                        0x4F /* VCO cal 16 */
+#define B2055_VCO_KVCO                 0x50 /* VCO KVCO */
+#define B2055_VCO_CAPTAIL              0x51 /* VCO CAP TAIL */
+#define B2055_VCO_IDACVCO              0x52 /* VCO IDAC VCO */
+#define B2055_VCO_REG                  0x53 /* VCO Regulator */
+#define B2055_PLL_RFVTH                        0x54 /* PLL RF VTH */
+#define B2055_LGBUF_CENBUF             0x55 /* LGBUF CEN BUF */
+#define B2055_LGEN_TUNE1               0x56 /* LGEN tune 1 */
+#define B2055_LGEN_TUNE2               0x57 /* LGEN tune 2 */
+#define B2055_LGEN_IDAC1               0x58 /* LGEN IDAC 1 */
+#define B2055_LGEN_IDAC2               0x59 /* LGEN IDAC 2 */
+#define B2055_LGEN_BIASC               0x5A /* LGEN BIAS counter */
+#define B2055_LGEN_BIASIDAC            0x5B /* LGEN BIAS IDAC */
+#define B2055_LGEN_RCAL                        0x5C /* LGEN RCAL */
+#define B2055_LGEN_DIV                 0x5D /* LGEN div */
+#define B2055_LGEN_SPARE2              0x5E /* LGEN spare 2 */
+#define B2055_C1_LGBUF_ATUNE           0x5F /* Core 1 LGBUF A tune */
+#define B2055_C1_LGBUF_GTUNE           0x60 /* Core 1 LGBUF G tune */
+#define B2055_C1_LGBUF_DIV             0x61 /* Core 1 LGBUF div */
+#define B2055_C1_LGBUF_AIDAC           0x62 /* Core 1 LGBUF A IDAC */
+#define B2055_C1_LGBUF_GIDAC           0x63 /* Core 1 LGBUF G IDAC */
+#define B2055_C1_LGBUF_IDACFO          0x64 /* Core 1 LGBUF IDAC filter override */
+#define B2055_C1_LGBUF_SPARE           0x65 /* Core 1 LGBUF spare */
+#define B2055_C1_RX_RFSPC1             0x66 /* Core 1 RX RF SPC1 */
+#define B2055_C1_RX_RFR1               0x67 /* Core 1 RX RF reg 1 */
+#define B2055_C1_RX_RFR2               0x68 /* Core 1 RX RF reg 2 */
+#define B2055_C1_RX_RFRCAL             0x69 /* Core 1 RX RF RCAL */
+#define B2055_C1_RX_BB_BLCMP           0x6A /* Core 1 RX Baseband BUFI LPF CMP */
+#define B2055_C1_RX_BB_LPF             0x6B /* Core 1 RX Baseband LPF */
+#define B2055_C1_RX_BB_MIDACHP         0x6C /* Core 1 RX Baseband MIDAC High-pass */
+#define B2055_C1_RX_BB_VGA1IDAC                0x6D /* Core 1 RX Baseband VGA1 IDAC */
+#define B2055_C1_RX_BB_VGA2IDAC                0x6E /* Core 1 RX Baseband VGA2 IDAC */
+#define B2055_C1_RX_BB_VGA3IDAC                0x6F /* Core 1 RX Baseband VGA3 IDAC */
+#define B2055_C1_RX_BB_BUFOCTL         0x70 /* Core 1 RX Baseband BUFO Control */
+#define B2055_C1_RX_BB_RCCALCTL                0x71 /* Core 1 RX Baseband RCCAL Control */
+#define B2055_C1_RX_BB_RSSICTL1                0x72 /* Core 1 RX Baseband RSSI Control 1 */
+#define B2055_C1_RX_BB_RSSICTL2                0x73 /* Core 1 RX Baseband RSSI Control 2 */
+#define B2055_C1_RX_BB_RSSICTL3                0x74 /* Core 1 RX Baseband RSSI Control 3 */
+#define B2055_C1_RX_BB_RSSICTL4                0x75 /* Core 1 RX Baseband RSSI Control 4 */
+#define B2055_C1_RX_BB_RSSICTL5                0x76 /* Core 1 RX Baseband RSSI Control 5 */
+#define B2055_C1_RX_BB_REG             0x77 /* Core 1 RX Baseband Regulator */
+#define B2055_C1_RX_BB_SPARE1          0x78 /* Core 1 RX Baseband spare 1 */
+#define B2055_C1_RX_TXBBRCAL           0x79 /* Core 1 RX TX BB RCAL */
+#define B2055_C1_TX_RF_SPGA            0x7A /* Core 1 TX RF SGM PGA */
+#define B2055_C1_TX_RF_SPAD            0x7B /* Core 1 TX RF SGM PAD */
+#define B2055_C1_TX_RF_CNTPGA1         0x7C /* Core 1 TX RF counter PGA 1 */
+#define B2055_C1_TX_RF_CNTPAD1         0x7D /* Core 1 TX RF counter PAD 1 */
+#define B2055_C1_TX_RF_PGAIDAC         0x7E /* Core 1 TX RF PGA IDAC */
+#define B2055_C1_TX_PGAPADTN           0x7F /* Core 1 TX PGA PAD TN */
+#define B2055_C1_TX_PADIDAC1           0x80 /* Core 1 TX PAD IDAC 1 */
+#define B2055_C1_TX_PADIDAC2           0x81 /* Core 1 TX PAD IDAC 2 */
+#define B2055_C1_TX_MXBGTRIM           0x82 /* Core 1 TX MX B/G TRIM */
+#define B2055_C1_TX_RF_RCAL            0x83 /* Core 1 TX RF RCAL */
+#define B2055_C1_TX_RF_PADTSSI1                0x84 /* Core 1 TX RF PAD TSSI1 */
+#define B2055_C1_TX_RF_PADTSSI2                0x85 /* Core 1 TX RF PAD TSSI2 */
+#define B2055_C1_TX_RF_SPARE           0x86 /* Core 1 TX RF spare */
+#define B2055_C1_TX_RF_IQCAL1          0x87 /* Core 1 TX RF I/Q CAL 1 */
+#define B2055_C1_TX_RF_IQCAL2          0x88 /* Core 1 TX RF I/Q CAL 2 */
+#define B2055_C1_TXBB_RCCAL            0x89 /* Core 1 TXBB RC CAL Control */
+#define B2055_C1_TXBB_LPF1             0x8A /* Core 1 TXBB LPF 1 */
+#define B2055_C1_TX_VOSCNCL            0x8B /* Core 1 TX VOS CNCL */
+#define B2055_C1_TX_LPF_MXGMIDAC       0x8C /* Core 1 TX LPF MXGM IDAC */
+#define B2055_C1_TX_BB_MXGM            0x8D /* Core 1 TX BB MXGM */
+#define B2055_C2_LGBUF_ATUNE           0x8E /* Core 2 LGBUF A tune */
+#define B2055_C2_LGBUF_GTUNE           0x8F /* Core 2 LGBUF G tune */
+#define B2055_C2_LGBUF_DIV             0x90 /* Core 2 LGBUF div */
+#define B2055_C2_LGBUF_AIDAC           0x91 /* Core 2 LGBUF A IDAC */
+#define B2055_C2_LGBUF_GIDAC           0x92 /* Core 2 LGBUF G IDAC */
+#define B2055_C2_LGBUF_IDACFO          0x93 /* Core 2 LGBUF IDAC filter override */
+#define B2055_C2_LGBUF_SPARE           0x94 /* Core 2 LGBUF spare */
+#define B2055_C2_RX_RFSPC1             0x95 /* Core 2 RX RF SPC1 */
+#define B2055_C2_RX_RFR1               0x96 /* Core 2 RX RF reg 1 */
+#define B2055_C2_RX_RFR2               0x97 /* Core 2 RX RF reg 2 */
+#define B2055_C2_RX_RFRCAL             0x98 /* Core 2 RX RF RCAL */
+#define B2055_C2_RX_BB_BLCMP           0x99 /* Core 2 RX Baseband BUFI LPF CMP */
+#define B2055_C2_RX_BB_LPF             0x9A /* Core 2 RX Baseband LPF */
+#define B2055_C2_RX_BB_MIDACHP         0x9B /* Core 2 RX Baseband MIDAC High-pass */
+#define B2055_C2_RX_BB_VGA1IDAC                0x9C /* Core 2 RX Baseband VGA1 IDAC */
+#define B2055_C2_RX_BB_VGA2IDAC                0x9D /* Core 2 RX Baseband VGA2 IDAC */
+#define B2055_C2_RX_BB_VGA3IDAC                0x9E /* Core 2 RX Baseband VGA3 IDAC */
+#define B2055_C2_RX_BB_BUFOCTL         0x9F /* Core 2 RX Baseband BUFO Control */
+#define B2055_C2_RX_BB_RCCALCTL                0xA0 /* Core 2 RX Baseband RCCAL Control */
+#define B2055_C2_RX_BB_RSSICTL1                0xA1 /* Core 2 RX Baseband RSSI Control 1 */
+#define B2055_C2_RX_BB_RSSICTL2                0xA2 /* Core 2 RX Baseband RSSI Control 2 */
+#define B2055_C2_RX_BB_RSSICTL3                0xA3 /* Core 2 RX Baseband RSSI Control 3 */
+#define B2055_C2_RX_BB_RSSICTL4                0xA4 /* Core 2 RX Baseband RSSI Control 4 */
+#define B2055_C2_RX_BB_RSSICTL5                0xA5 /* Core 2 RX Baseband RSSI Control 5 */
+#define B2055_C2_RX_BB_REG             0xA6 /* Core 2 RX Baseband Regulator */
+#define B2055_C2_RX_BB_SPARE1          0xA7 /* Core 2 RX Baseband spare 1 */
+#define B2055_C2_RX_TXBBRCAL           0xA8 /* Core 2 RX TX BB RCAL */
+#define B2055_C2_TX_RF_SPGA            0xA9 /* Core 2 TX RF SGM PGA */
+#define B2055_C2_TX_RF_SPAD            0xAA /* Core 2 TX RF SGM PAD */
+#define B2055_C2_TX_RF_CNTPGA1         0xAB /* Core 2 TX RF counter PGA 1 */
+#define B2055_C2_TX_RF_CNTPAD1         0xAC /* Core 2 TX RF counter PAD 1 */
+#define B2055_C2_TX_RF_PGAIDAC         0xAD /* Core 2 TX RF PGA IDAC */
+#define B2055_C2_TX_PGAPADTN           0xAE /* Core 2 TX PGA PAD TN */
+#define B2055_C2_TX_PADIDAC1           0xAF /* Core 2 TX PAD IDAC 1 */
+#define B2055_C2_TX_PADIDAC2           0xB0 /* Core 2 TX PAD IDAC 2 */
+#define B2055_C2_TX_MXBGTRIM           0xB1 /* Core 2 TX MX B/G TRIM */
+#define B2055_C2_TX_RF_RCAL            0xB2 /* Core 2 TX RF RCAL */
+#define B2055_C2_TX_RF_PADTSSI1                0xB3 /* Core 2 TX RF PAD TSSI1 */
+#define B2055_C2_TX_RF_PADTSSI2                0xB4 /* Core 2 TX RF PAD TSSI2 */
+#define B2055_C2_TX_RF_SPARE           0xB5 /* Core 2 TX RF spare */
+#define B2055_C2_TX_RF_IQCAL1          0xB6 /* Core 2 TX RF I/Q CAL 1 */
+#define B2055_C2_TX_RF_IQCAL2          0xB7 /* Core 2 TX RF I/Q CAL 2 */
+#define B2055_C2_TXBB_RCCAL            0xB8 /* Core 2 TXBB RC CAL Control */
+#define B2055_C2_TXBB_LPF1             0xB9 /* Core 2 TXBB LPF 1 */
+#define B2055_C2_TX_VOSCNCL            0xBA /* Core 2 TX VOS CNCL */
+#define B2055_C2_TX_LPF_MXGMIDAC       0xBB /* Core 2 TX LPF MXGM IDAC */
+#define B2055_C2_TX_BB_MXGM            0xBC /* Core 2 TX BB MXGM */
+#define B2055_PRG_GCHP21               0xBD /* PRG GC HPVGA23 21 */
+#define B2055_PRG_GCHP22               0xBE /* PRG GC HPVGA23 22 */
+#define B2055_PRG_GCHP23               0xBF /* PRG GC HPVGA23 23 */
+#define B2055_PRG_GCHP24               0xC0 /* PRG GC HPVGA23 24 */
+#define B2055_PRG_GCHP25               0xC1 /* PRG GC HPVGA23 25 */
+#define B2055_PRG_GCHP26               0xC2 /* PRG GC HPVGA23 26 */
+#define B2055_PRG_GCHP27               0xC3 /* PRG GC HPVGA23 27 */
+#define B2055_PRG_GCHP28               0xC4 /* PRG GC HPVGA23 28 */
+#define B2055_PRG_GCHP29               0xC5 /* PRG GC HPVGA23 29 */
+#define B2055_PRG_GCHP30               0xC6 /* PRG GC HPVGA23 30 */
+#define B2055_C1_LNA_GAINBST           0xCD /* Core 1 LNA GAINBST */
+#define B2055_C1_B0NB_RSSIVCM          0xD2 /* Core 1 B0 narrow-band RSSI VCM */
+#define B2055_C1_GENSPARE2             0xD6 /* Core 1 GEN spare 2 */
+#define B2055_C2_LNA_GAINBST           0xD9 /* Core 2 LNA GAINBST */
+#define B2055_C2_B0NB_RSSIVCM          0xDE /* Core 2 B0 narrow-band RSSI VCM */
+#define B2055_C2_GENSPARE2             0xE2 /* Core 2 GEN spare 2 */
+
+struct b43_nphy_channeltab_entry_rev2 {
+       /* The channel number */
+       u8 channel;
+       /* The channel frequency in MHz */
+       u16 freq;
+       /* An unknown value */
+       u16 unk2;
+       /* Radio register values on channelswitch */
+       u8 radio_pll_ref;
+       u8 radio_rf_pllmod0;
+       u8 radio_rf_pllmod1;
+       u8 radio_vco_captail;
+       u8 radio_vco_cal1;
+       u8 radio_vco_cal2;
+       u8 radio_pll_lfc1;
+       u8 radio_pll_lfr1;
+       u8 radio_pll_lfc2;
+       u8 radio_lgbuf_cenbuf;
+       u8 radio_lgen_tune1;
+       u8 radio_lgen_tune2;
+       u8 radio_c1_lgbuf_atune;
+       u8 radio_c1_lgbuf_gtune;
+       u8 radio_c1_rx_rfr1;
+       u8 radio_c1_tx_pgapadtn;
+       u8 radio_c1_tx_mxbgtrim;
+       u8 radio_c2_lgbuf_atune;
+       u8 radio_c2_lgbuf_gtune;
+       u8 radio_c2_rx_rfr1;
+       u8 radio_c2_tx_pgapadtn;
+       u8 radio_c2_tx_mxbgtrim;
+       /* PHY register values on channelswitch */
+       struct b43_phy_n_sfo_cfg phy_regs;
+};
+
+/* Upload the default register value table.
+ * If "ghz5" is true, we upload the 5Ghz table. Otherwise the 2.4Ghz
+ * table is uploaded. If "ignore_uploadflag" is true, we upload any value
+ * and ignore the "UPLOAD" flag. */
+void b2055_upload_inittab(struct b43_wldev *dev,
+                         bool ghz5, bool ignore_uploadflag);
+
+#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 (file)
index 0000000..d856319
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+
+  Broadcom B43 wireless driver
+  IEEE 802.11n 2056 radio device data tables
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; see the file COPYING.  If not, write to
+  the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
+  Boston, MA 02110-1301, USA.
+
+*/
+
+#include "b43.h"
+#include "radio_2056.h"
+#include "phy_common.h"
+
+static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev3[] = {
+};
+
+const struct b43_nphy_channeltab_entry_rev3 *
+b43_nphy_get_chantabent_rev3(struct b43_wldev *dev, u16 freq)
+{
+       const struct b43_nphy_channeltab_entry_rev3 *e;
+       unsigned int i;
+
+       for (i = 0; i < ARRAY_SIZE(b43_nphy_channeltab_rev3); i++) {
+               e = &(b43_nphy_channeltab_rev3[i]);
+               if (e->freq == freq)
+                       return e;
+       }
+
+       return NULL;
+}
diff --git a/drivers/net/wireless/b43/radio_2056.h b/drivers/net/wireless/b43/radio_2056.h
new file mode 100644 (file)
index 0000000..fda6daf
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+
+  Broadcom B43 wireless driver
+
+  Copyright (c) 2010 RafaÅ‚ MiÅ‚ecki <zajec5@gmail.com>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; see the file COPYING.  If not, write to
+  the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
+  Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef B43_RADIO_2056_H_
+#define B43_RADIO_2056_H_
+
+#include <linux/types.h>
+
+#include "tables_nphy.h"
+
+struct b43_nphy_channeltab_entry_rev3 {
+       /* The channel number */
+       u8 channel;
+       /* The channel frequency in MHz */
+       u16 freq;
+       /* Radio register values on channelswitch */
+       /* TODO */
+       /* PHY register values on channelswitch */
+       struct b43_phy_n_sfo_cfg phy_regs;
+};
+
+#endif /* B43_RADIO_2056_H_ */
index d96e870ab8fe8cea97c821c27076b2b99a47dfc8..d60db078eae20127f394bc9fd1a0591d5d7f0e73 100644 (file)
@@ -1,7 +1,7 @@
 /*
 
   Broadcom B43 wireless driver
-  IEEE 802.11n PHY and radio device data tables
+  IEEE 802.11n PHY data tables
 
   Copyright (c) 2008 Michael Buesch <mb@bu3sch.de>
 
 #include "phy_common.h"
 #include "phy_n.h"
 
-
-struct b2055_inittab_entry {
-       /* Value to write if we use the 5GHz band. */
-       u16 ghz5;
-       /* Value to write if we use the 2.4GHz band. */
-       u16 ghz2;
-       /* Flags */
-       u8 flags;
-#define B2055_INITTAB_ENTRY_OK 0x01
-#define B2055_INITTAB_UPLOAD   0x02
-};
-#define UPLOAD         .flags = B2055_INITTAB_ENTRY_OK | B2055_INITTAB_UPLOAD
-#define NOUPLOAD       .flags = B2055_INITTAB_ENTRY_OK
-
-static const struct b2055_inittab_entry b2055_inittab [] = {
-  [B2055_SP_PINPD]             = { .ghz5 = 0x0080, .ghz2 = 0x0080, NOUPLOAD, },
-  [B2055_C1_SP_RSSI]           = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_C1_SP_PDMISC]         = { .ghz5 = 0x0027, .ghz2 = 0x0027, NOUPLOAD, },
-  [B2055_C2_SP_RSSI]           = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_C2_SP_PDMISC]         = { .ghz5 = 0x0027, .ghz2 = 0x0027, NOUPLOAD, },
-  [B2055_C1_SP_RXGC1]          = { .ghz5 = 0x007F, .ghz2 = 0x007F, UPLOAD, },
-  [B2055_C1_SP_RXGC2]          = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, },
-  [B2055_C2_SP_RXGC1]          = { .ghz5 = 0x007F, .ghz2 = 0x007F, UPLOAD, },
-  [B2055_C2_SP_RXGC2]          = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, },
-  [B2055_C1_SP_LPFBWSEL]       = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
-  [B2055_C2_SP_LPFBWSEL]       = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
-  [B2055_C1_SP_TXGC1]          = { .ghz5 = 0x004F, .ghz2 = 0x004F, UPLOAD, },
-  [B2055_C1_SP_TXGC2]          = { .ghz5 = 0x0005, .ghz2 = 0x0005, UPLOAD, },
-  [B2055_C2_SP_TXGC1]          = { .ghz5 = 0x004F, .ghz2 = 0x004F, UPLOAD, },
-  [B2055_C2_SP_TXGC2]          = { .ghz5 = 0x0005, .ghz2 = 0x0005, UPLOAD, },
-  [B2055_MASTER1]              = { .ghz5 = 0x00D0, .ghz2 = 0x00D0, NOUPLOAD, },
-  [B2055_MASTER2]              = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
-  [B2055_PD_LGEN]              = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_PD_PLLTS]             = { .ghz5 = 0x0040, .ghz2 = 0x0040, NOUPLOAD, },
-  [B2055_C1_PD_LGBUF]          = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_C1_PD_TX]             = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_C1_PD_RXTX]           = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_C1_PD_RSSIMISC]       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_C2_PD_LGBUF]          = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_C2_PD_TX]             = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_C2_PD_RXTX]           = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_C2_PD_RSSIMISC]       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_PWRDET_LGEN]          = { .ghz5 = 0x00C0, .ghz2 = 0x00C0, NOUPLOAD, },
-  [B2055_C1_PWRDET_LGBUF]      = { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, },
-  [B2055_C1_PWRDET_RXTX]       = { .ghz5 = 0x00C0, .ghz2 = 0x00C0, NOUPLOAD, },
-  [B2055_C2_PWRDET_LGBUF]      = { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, },
-  [B2055_C2_PWRDET_RXTX]       = { .ghz5 = 0x00C0, .ghz2 = 0x00C0, NOUPLOAD, },
-  [B2055_RRCCAL_CS]            = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_RRCCAL_NOPTSEL]       = { .ghz5 = 0x002C, .ghz2 = 0x002C, NOUPLOAD, },
-  [B2055_CAL_MISC]             = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_CAL_COUT]             = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_CAL_COUT2]            = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_CAL_CVARCTL]          = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_CAL_RVARCTL]          = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_CAL_LPOCTL]           = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_CAL_TS]               = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_CAL_RCCALRTS]         = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_CAL_RCALRTS]          = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_PADDRV]               = { .ghz5 = 0x00A4, .ghz2 = 0x00A4, NOUPLOAD, },
-  [B2055_XOCTL1]               = { .ghz5 = 0x0038, .ghz2 = 0x0038, NOUPLOAD, },
-  [B2055_XOCTL2]               = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_XOREGUL]              = { .ghz5 = 0x0004, .ghz2 = 0x0004, UPLOAD, },
-  [B2055_XOMISC]               = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_PLL_LFC1]             = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
-  [B2055_PLL_CALVTH]           = { .ghz5 = 0x0087, .ghz2 = 0x0087, NOUPLOAD, },
-  [B2055_PLL_LFC2]             = { .ghz5 = 0x0009, .ghz2 = 0x0009, NOUPLOAD, },
-  [B2055_PLL_REF]              = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, },
-  [B2055_PLL_LFR1]             = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, },
-  [B2055_PLL_PFDCP]            = { .ghz5 = 0x0018, .ghz2 = 0x0018, UPLOAD, },
-  [B2055_PLL_IDAC_CPOPAMP]     = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
-  [B2055_PLL_CPREG]            = { .ghz5 = 0x0004, .ghz2 = 0x0004, UPLOAD, },
-  [B2055_PLL_RCAL]             = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
-  [B2055_RF_PLLMOD0]           = { .ghz5 = 0x009E, .ghz2 = 0x009E, NOUPLOAD, },
-  [B2055_RF_PLLMOD1]           = { .ghz5 = 0x0009, .ghz2 = 0x0009, NOUPLOAD, },
-  [B2055_RF_MMDIDAC1]          = { .ghz5 = 0x00C8, .ghz2 = 0x00C8, UPLOAD, },
-  [B2055_RF_MMDIDAC0]          = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
-  [B2055_RF_MMDSP]             = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_VCO_CAL1]             = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_VCO_CAL2]             = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_VCO_CAL3]             = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
-  [B2055_VCO_CAL4]             = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
-  [B2055_VCO_CAL5]             = { .ghz5 = 0x0096, .ghz2 = 0x0096, NOUPLOAD, },
-  [B2055_VCO_CAL6]             = { .ghz5 = 0x003E, .ghz2 = 0x003E, NOUPLOAD, },
-  [B2055_VCO_CAL7]             = { .ghz5 = 0x003E, .ghz2 = 0x003E, NOUPLOAD, },
-  [B2055_VCO_CAL8]             = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, },
-  [B2055_VCO_CAL9]             = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
-  [B2055_VCO_CAL10]            = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
-  [B2055_VCO_CAL11]            = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
-  [B2055_VCO_CAL12]            = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_VCO_CAL13]            = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_VCO_CAL14]            = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_VCO_CAL15]            = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_VCO_CAL16]            = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_VCO_KVCO]             = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
-  [B2055_VCO_CAPTAIL]          = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
-  [B2055_VCO_IDACVCO]          = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
-  [B2055_VCO_REG]              = { .ghz5 = 0x0084, .ghz2 = 0x0084, UPLOAD, },
-  [B2055_PLL_RFVTH]            = { .ghz5 = 0x00C3, .ghz2 = 0x00C3, NOUPLOAD, },
-  [B2055_LGBUF_CENBUF]         = { .ghz5 = 0x008F, .ghz2 = 0x008F, NOUPLOAD, },
-  [B2055_LGEN_TUNE1]           = { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, },
-  [B2055_LGEN_TUNE2]           = { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, },
-  [B2055_LGEN_IDAC1]           = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
-  [B2055_LGEN_IDAC2]           = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
-  [B2055_LGEN_BIASC]           = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_LGEN_BIASIDAC]                = { .ghz5 = 0x00CC, .ghz2 = 0x00CC, NOUPLOAD, },
-  [B2055_LGEN_RCAL]            = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
-  [B2055_LGEN_DIV]             = { .ghz5 = 0x0080, .ghz2 = 0x0080, NOUPLOAD, },
-  [B2055_LGEN_SPARE2]          = { .ghz5 = 0x0080, .ghz2 = 0x0080, NOUPLOAD, },
-  [B2055_C1_LGBUF_ATUNE]       = { .ghz5 = 0x00F8, .ghz2 = 0x00F8, NOUPLOAD, },
-  [B2055_C1_LGBUF_GTUNE]       = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
-  [B2055_C1_LGBUF_DIV]         = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
-  [B2055_C1_LGBUF_AIDAC]       = { .ghz5 = 0x0088, .ghz2 = 0x0008, UPLOAD, },
-  [B2055_C1_LGBUF_GIDAC]       = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
-  [B2055_C1_LGBUF_IDACFO]      = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_C1_LGBUF_SPARE]       = { .ghz5 = 0x0001, .ghz2 = 0x0001, UPLOAD, },
-  [B2055_C1_RX_RFSPC1]         = { .ghz5 = 0x008A, .ghz2 = 0x008A, NOUPLOAD, },
-  [B2055_C1_RX_RFR1]           = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
-  [B2055_C1_RX_RFR2]           = { .ghz5 = 0x0083, .ghz2 = 0x0083, NOUPLOAD, },
-  [B2055_C1_RX_RFRCAL]         = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
-  [B2055_C1_RX_BB_BLCMP]       = { .ghz5 = 0x00A0, .ghz2 = 0x00A0, NOUPLOAD, },
-  [B2055_C1_RX_BB_LPF]         = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
-  [B2055_C1_RX_BB_MIDACHP]     = { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, },
-  [B2055_C1_RX_BB_VGA1IDAC]    = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
-  [B2055_C1_RX_BB_VGA2IDAC]    = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
-  [B2055_C1_RX_BB_VGA3IDAC]    = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
-  [B2055_C1_RX_BB_BUFOCTL]     = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
-  [B2055_C1_RX_BB_RCCALCTL]    = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
-  [B2055_C1_RX_BB_RSSICTL1]    = { .ghz5 = 0x006A, .ghz2 = 0x006A, UPLOAD, },
-  [B2055_C1_RX_BB_RSSICTL2]    = { .ghz5 = 0x00AB, .ghz2 = 0x00AB, UPLOAD, },
-  [B2055_C1_RX_BB_RSSICTL3]    = { .ghz5 = 0x0013, .ghz2 = 0x0013, UPLOAD, },
-  [B2055_C1_RX_BB_RSSICTL4]    = { .ghz5 = 0x00C1, .ghz2 = 0x00C1, UPLOAD, },
-  [B2055_C1_RX_BB_RSSICTL5]    = { .ghz5 = 0x00AA, .ghz2 = 0x00AA, UPLOAD, },
-  [B2055_C1_RX_BB_REG]         = { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, },
-  [B2055_C1_RX_BB_SPARE1]      = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_C1_RX_TXBBRCAL]       = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
-  [B2055_C1_TX_RF_SPGA]                = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
-  [B2055_C1_TX_RF_SPAD]                = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
-  [B2055_C1_TX_RF_CNTPGA1]     = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
-  [B2055_C1_TX_RF_CNTPAD1]     = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, },
-  [B2055_C1_TX_RF_PGAIDAC]     = { .ghz5 = 0x0097, .ghz2 = 0x0097, UPLOAD, },
-  [B2055_C1_TX_PGAPADTN]       = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
-  [B2055_C1_TX_PADIDAC1]       = { .ghz5 = 0x0014, .ghz2 = 0x0014, UPLOAD, },
-  [B2055_C1_TX_PADIDAC2]       = { .ghz5 = 0x0033, .ghz2 = 0x0033, NOUPLOAD, },
-  [B2055_C1_TX_MXBGTRIM]       = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
-  [B2055_C1_TX_RF_RCAL]                = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
-  [B2055_C1_TX_RF_PADTSSI1]    = { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, },
-  [B2055_C1_TX_RF_PADTSSI2]    = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
-  [B2055_C1_TX_RF_SPARE]       = { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, },
-  [B2055_C1_TX_RF_IQCAL1]      = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
-  [B2055_C1_TX_RF_IQCAL2]      = { .ghz5 = 0x00A4, .ghz2 = 0x00A4, NOUPLOAD, },
-  [B2055_C1_TXBB_RCCAL]                = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
-  [B2055_C1_TXBB_LPF1]         = { .ghz5 = 0x0028, .ghz2 = 0x0028, NOUPLOAD, },
-  [B2055_C1_TX_VOSCNCL]                = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_C1_TX_LPF_MXGMIDAC]   = { .ghz5 = 0x004A, .ghz2 = 0x004A, NOUPLOAD, },
-  [B2055_C1_TX_BB_MXGM]                = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_C2_LGBUF_ATUNE]       = { .ghz5 = 0x00F8, .ghz2 = 0x00F8, NOUPLOAD, },
-  [B2055_C2_LGBUF_GTUNE]       = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
-  [B2055_C2_LGBUF_DIV]         = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
-  [B2055_C2_LGBUF_AIDAC]       = { .ghz5 = 0x0088, .ghz2 = 0x0008, UPLOAD, },
-  [B2055_C2_LGBUF_GIDAC]       = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
-  [B2055_C2_LGBUF_IDACFO]      = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_C2_LGBUF_SPARE]       = { .ghz5 = 0x0001, .ghz2 = 0x0001, UPLOAD, },
-  [B2055_C2_RX_RFSPC1]         = { .ghz5 = 0x008A, .ghz2 = 0x008A, NOUPLOAD, },
-  [B2055_C2_RX_RFR1]           = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
-  [B2055_C2_RX_RFR2]           = { .ghz5 = 0x0083, .ghz2 = 0x0083, NOUPLOAD, },
-  [B2055_C2_RX_RFRCAL]         = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
-  [B2055_C2_RX_BB_BLCMP]       = { .ghz5 = 0x00A0, .ghz2 = 0x00A0, NOUPLOAD, },
-  [B2055_C2_RX_BB_LPF]         = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
-  [B2055_C2_RX_BB_MIDACHP]     = { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, },
-  [B2055_C2_RX_BB_VGA1IDAC]    = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
-  [B2055_C2_RX_BB_VGA2IDAC]    = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
-  [B2055_C2_RX_BB_VGA3IDAC]    = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
-  [B2055_C2_RX_BB_BUFOCTL]     = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
-  [B2055_C2_RX_BB_RCCALCTL]    = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
-  [B2055_C2_RX_BB_RSSICTL1]    = { .ghz5 = 0x006A, .ghz2 = 0x006A, UPLOAD, },
-  [B2055_C2_RX_BB_RSSICTL2]    = { .ghz5 = 0x00AB, .ghz2 = 0x00AB, UPLOAD, },
-  [B2055_C2_RX_BB_RSSICTL3]    = { .ghz5 = 0x0013, .ghz2 = 0x0013, UPLOAD, },
-  [B2055_C2_RX_BB_RSSICTL4]    = { .ghz5 = 0x00C1, .ghz2 = 0x00C1, UPLOAD, },
-  [B2055_C2_RX_BB_RSSICTL5]    = { .ghz5 = 0x00AA, .ghz2 = 0x00AA, UPLOAD, },
-  [B2055_C2_RX_BB_REG]         = { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, },
-  [B2055_C2_RX_BB_SPARE1]      = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_C2_RX_TXBBRCAL]       = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
-  [B2055_C2_TX_RF_SPGA]                = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
-  [B2055_C2_TX_RF_SPAD]                = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
-  [B2055_C2_TX_RF_CNTPGA1]     = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
-  [B2055_C2_TX_RF_CNTPAD1]     = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, },
-  [B2055_C2_TX_RF_PGAIDAC]     = { .ghz5 = 0x0097, .ghz2 = 0x0097, UPLOAD, },
-  [B2055_C2_TX_PGAPADTN]       = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
-  [B2055_C2_TX_PADIDAC1]       = { .ghz5 = 0x0014, .ghz2 = 0x0014, UPLOAD, },
-  [B2055_C2_TX_PADIDAC2]       = { .ghz5 = 0x0033, .ghz2 = 0x0033, NOUPLOAD, },
-  [B2055_C2_TX_MXBGTRIM]       = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
-  [B2055_C2_TX_RF_RCAL]                = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
-  [B2055_C2_TX_RF_PADTSSI1]    = { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, },
-  [B2055_C2_TX_RF_PADTSSI2]    = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
-  [B2055_C2_TX_RF_SPARE]       = { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, },
-  [B2055_C2_TX_RF_IQCAL1]      = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
-  [B2055_C2_TX_RF_IQCAL2]      = { .ghz5 = 0x00A4, .ghz2 = 0x00A4, NOUPLOAD, },
-  [B2055_C2_TXBB_RCCAL]                = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
-  [B2055_C2_TXBB_LPF1]         = { .ghz5 = 0x0028, .ghz2 = 0x0028, NOUPLOAD, },
-  [B2055_C2_TX_VOSCNCL]                = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_C2_TX_LPF_MXGMIDAC]   = { .ghz5 = 0x004A, .ghz2 = 0x004A, NOUPLOAD, },
-  [B2055_C2_TX_BB_MXGM]                = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_PRG_GCHP21]           = { .ghz5 = 0x0071, .ghz2 = 0x0071, NOUPLOAD, },
-  [B2055_PRG_GCHP22]           = { .ghz5 = 0x0072, .ghz2 = 0x0072, NOUPLOAD, },
-  [B2055_PRG_GCHP23]           = { .ghz5 = 0x0073, .ghz2 = 0x0073, NOUPLOAD, },
-  [B2055_PRG_GCHP24]           = { .ghz5 = 0x0074, .ghz2 = 0x0074, NOUPLOAD, },
-  [B2055_PRG_GCHP25]           = { .ghz5 = 0x0075, .ghz2 = 0x0075, NOUPLOAD, },
-  [B2055_PRG_GCHP26]           = { .ghz5 = 0x0076, .ghz2 = 0x0076, NOUPLOAD, },
-  [B2055_PRG_GCHP27]           = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, },
-  [B2055_PRG_GCHP28]           = { .ghz5 = 0x0078, .ghz2 = 0x0078, NOUPLOAD, },
-  [B2055_PRG_GCHP29]           = { .ghz5 = 0x0079, .ghz2 = 0x0079, NOUPLOAD, },
-  [B2055_PRG_GCHP30]           = { .ghz5 = 0x007A, .ghz2 = 0x007A, NOUPLOAD, },
-  [0xC7]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [0xC8]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [0xC9]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [0xCA]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [0xCB]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [0xCC]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_C1_LNA_GAINBST]       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [0xCE]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [0xCF]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [0xD0]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [0xD1]                       = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
-  [B2055_C1_B0NB_RSSIVCM]      = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
-  [0xD3]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [0xD4]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [0xD5]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_C1_GENSPARE2]         = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [0xD7]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [0xD8]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_C2_LNA_GAINBST]       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [0xDA]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [0xDB]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [0xDC]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [0xDD]                       = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
-  [B2055_C2_B0NB_RSSIVCM]      = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
-  [0xDF]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [0xE0]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [0xE1]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-  [B2055_C2_GENSPARE2]         = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
-};
-
-
-void b2055_upload_inittab(struct b43_wldev *dev,
-                         bool ghz5, bool ignore_uploadflag)
-{
-       const struct b2055_inittab_entry *e;
-       unsigned int i;
-       u16 value;
-
-       for (i = 0; i < ARRAY_SIZE(b2055_inittab); i++) {
-               e = &(b2055_inittab[i]);
-               if (!(e->flags & B2055_INITTAB_ENTRY_OK))
-                       continue;
-               if ((e->flags & B2055_INITTAB_UPLOAD) || ignore_uploadflag) {
-                       if (ghz5)
-                               value = e->ghz5;
-                       else
-                               value = e->ghz2;
-                       b43_radio_write16(dev, i, value);
-               }
-       }
-}
-
-
-#define RADIOREGS(r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, \
-                 r12, r13, r14, r15, r16, r17, r18, r19, r20, r21) \
-       .radio_pll_ref          = r0,   \
-       .radio_rf_pllmod0       = r1,   \
-       .radio_rf_pllmod1       = r2,   \
-       .radio_vco_captail      = r3,   \
-       .radio_vco_cal1         = r4,   \
-       .radio_vco_cal2         = r5,   \
-       .radio_pll_lfc1         = r6,   \
-       .radio_pll_lfr1         = r7,   \
-       .radio_pll_lfc2         = r8,   \
-       .radio_lgbuf_cenbuf     = r9,   \
-       .radio_lgen_tune1       = r10,  \
-       .radio_lgen_tune2       = r11,  \
-       .radio_c1_lgbuf_atune   = r12,  \
-       .radio_c1_lgbuf_gtune   = r13,  \
-       .radio_c1_rx_rfr1       = r14,  \
-       .radio_c1_tx_pgapadtn   = r15,  \
-       .radio_c1_tx_mxbgtrim   = r16,  \
-       .radio_c2_lgbuf_atune   = r17,  \
-       .radio_c2_lgbuf_gtune   = r18,  \
-       .radio_c2_rx_rfr1       = r19,  \
-       .radio_c2_tx_pgapadtn   = r20,  \
-       .radio_c2_tx_mxbgtrim   = r21
-
-#define PHYREGS(r0, r1, r2, r3, r4, r5)        \
-       .phy_regs.phy_bw1a      = r0,   \
-       .phy_regs.phy_bw2       = r1,   \
-       .phy_regs.phy_bw3       = r2,   \
-       .phy_regs.phy_bw4       = r3,   \
-       .phy_regs.phy_bw5       = r4,   \
-       .phy_regs.phy_bw6       = r5
-
-static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab[] = {
-  {    .channel                = 184,
-       .freq                   = 4920, /* MHz */
-       .unk2                   = 3280,
-       RADIOREGS(0x71, 0x01, 0xEC, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
-                 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F,
-                 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
-       PHYREGS(0xB407, 0xB007, 0xAC07, 0x1402, 0x1502, 0x1602),
-  },
-  {    .channel                = 186,
-       .freq                   = 4930, /* MHz */
-       .unk2                   = 3287,
-       RADIOREGS(0x71, 0x01, 0xED, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
-                 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F,
-                 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
-       PHYREGS(0xB807, 0xB407, 0xB007, 0x1302, 0x1402, 0x1502),
-  },
-  {    .channel                = 188,
-       .freq                   = 4940, /* MHz */
-       .unk2                   = 3293,
-       RADIOREGS(0x71, 0x01, 0xEE, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
-                 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
-                 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
-       PHYREGS(0xBC07, 0xB807, 0xB407, 0x1202, 0x1302, 0x1402),
-  },
-  {    .channel                = 190,
-       .freq                   = 4950, /* MHz */
-       .unk2                   = 3300,
-       RADIOREGS(0x71, 0x01, 0xEF, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
-                 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
-                 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
-       PHYREGS(0xC007, 0xBC07, 0xB807, 0x1102, 0x1202, 0x1302),
-  },
-  {    .channel                = 192,
-       .freq                   = 4960, /* MHz */
-       .unk2                   = 3307,
-       RADIOREGS(0x71, 0x01, 0xF0, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
-                 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
-                 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
-       PHYREGS(0xC407, 0xC007, 0xBC07, 0x0F02, 0x1102, 0x1202),
-  },
-  {    .channel                = 194,
-       .freq                   = 4970, /* MHz */
-       .unk2                   = 3313,
-       RADIOREGS(0x71, 0x01, 0xF1, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
-                 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
-                 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
-       PHYREGS(0xC807, 0xC407, 0xC007, 0x0E02, 0x0F02, 0x1102),
-  },
-  {    .channel                = 196,
-       .freq                   = 4980, /* MHz */
-       .unk2                   = 3320,
-       RADIOREGS(0x71, 0x01, 0xF2, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
-                 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
-                 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
-       PHYREGS(0xCC07, 0xC807, 0xC407, 0x0D02, 0x0E02, 0x0F02),
-  },
-  {    .channel                = 198,
-       .freq                   = 4990, /* MHz */
-       .unk2                   = 3327,
-       RADIOREGS(0x71, 0x01, 0xF3, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
-                 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
-                 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
-       PHYREGS(0xD007, 0xCC07, 0xC807, 0x0C02, 0x0D02, 0x0E02),
-  },
-  {    .channel                = 200,
-       .freq                   = 5000, /* MHz */
-       .unk2                   = 3333,
-       RADIOREGS(0x71, 0x01, 0xF4, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
-                 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
-                 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
-       PHYREGS(0xD407, 0xD007, 0xCC07, 0x0B02, 0x0C02, 0x0D02),
-  },
-  {    .channel                = 202,
-       .freq                   = 5010, /* MHz */
-       .unk2                   = 3340,
-       RADIOREGS(0x71, 0x01, 0xF5, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
-                 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
-                 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
-       PHYREGS(0xD807, 0xD407, 0xD007, 0x0A02, 0x0B02, 0x0C02),
-  },
-  {    .channel                = 204,
-       .freq                   = 5020, /* MHz */
-       .unk2                   = 3347,
-       RADIOREGS(0x71, 0x01, 0xF6, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
-                 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
-                 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
-       PHYREGS(0xDC07, 0xD807, 0xD407, 0x0902, 0x0A02, 0x0B02),
-  },
-  {    .channel                = 206,
-       .freq                   = 5030, /* MHz */
-       .unk2                   = 3353,
-       RADIOREGS(0x71, 0x01, 0xF7, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
-                 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
-                 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
-       PHYREGS(0xE007, 0xDC07, 0xD807, 0x0802, 0x0902, 0x0A02),
-  },
-  {    .channel                = 208,
-       .freq                   = 5040, /* MHz */
-       .unk2                   = 3360,
-       RADIOREGS(0x71, 0x01, 0xF8, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
-                 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
-                 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
-       PHYREGS(0xE407, 0xE007, 0xDC07, 0x0702, 0x0802, 0x0902),
-  },
-  {    .channel                = 210,
-       .freq                   = 5050, /* MHz */
-       .unk2                   = 3367,
-       RADIOREGS(0x71, 0x01, 0xF9, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
-                 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
-                 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
-       PHYREGS(0xE807, 0xE407, 0xE007, 0x0602, 0x0702, 0x0802),
-  },
-  {    .channel                = 212,
-       .freq                   = 5060, /* MHz */
-       .unk2                   = 3373,
-       RADIOREGS(0x71, 0x01, 0xFA, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
-                 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F,
-                 0x8E, 0xFF, 0x00, 0x0E, 0x0F, 0x8E),
-       PHYREGS(0xEC07, 0xE807, 0xE407, 0x0502, 0x0602, 0x0702),
-  },
-  {    .channel                = 214,
-       .freq                   = 5070, /* MHz */
-       .unk2                   = 3380,
-       RADIOREGS(0x71, 0x01, 0xFB, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
-                 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F,
-                 0x8E, 0xFF, 0x00, 0x0E, 0x0F, 0x8E),
-       PHYREGS(0xF007, 0xEC07, 0xE807, 0x0402, 0x0502, 0x0602),
-  },
-  {    .channel                = 216,
-       .freq                   = 5080, /* MHz */
-       .unk2                   = 3387,
-       RADIOREGS(0x71, 0x01, 0xFC, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
-                 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F,
-                 0x8D, 0xEE, 0x00, 0x0E, 0x0F, 0x8D),
-       PHYREGS(0xF407, 0xF007, 0xEC07, 0x0302, 0x0402, 0x0502),
-  },
-  {    .channel                = 218,
-       .freq                   = 5090, /* MHz */
-       .unk2                   = 3393,
-       RADIOREGS(0x71, 0x01, 0xFD, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
-                 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F,
-                 0x8D, 0xEE, 0x00, 0x0E, 0x0F, 0x8D),
-       PHYREGS(0xF807, 0xF407, 0xF007, 0x0202, 0x0302, 0x0402),
-  },
-  {    .channel                = 220,
-       .freq                   = 5100, /* MHz */
-       .unk2                   = 3400,
-       RADIOREGS(0x71, 0x01, 0xFE, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
-                 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F,
-                 0x8D, 0xEE, 0x00, 0x0D, 0x0F, 0x8D),
-       PHYREGS(0xFC07, 0xF807, 0xF407, 0x0102, 0x0202, 0x0302),
-  },
-  {    .channel                = 222,
-       .freq                   = 5110, /* MHz */
-       .unk2                   = 3407,
-       RADIOREGS(0x71, 0x01, 0xFF, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
-                 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F,
-                 0x8D, 0xEE, 0x00, 0x0D, 0x0F, 0x8D),
-       PHYREGS(0x0008, 0xFC07, 0xF807, 0x0002, 0x0102, 0x0202),
-  },
-  {    .channel                = 224,
-       .freq                   = 5120, /* MHz */
-       .unk2                   = 3413,
-       RADIOREGS(0x71, 0x02, 0x00, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
-                 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F,
-                 0x8C, 0xDD, 0x00, 0x0D, 0x0F, 0x8C),
-       PHYREGS(0x0408, 0x0008, 0xFC07, 0xFF01, 0x0002, 0x0102),
-  },
-  {    .channel                = 226,
-       .freq                   = 5130, /* MHz */
-       .unk2                   = 3420,
-       RADIOREGS(0x71, 0x02, 0x01, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
-                 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F,
-                 0x8C, 0xDD, 0x00, 0x0D, 0x0F, 0x8C),
-       PHYREGS(0x0808, 0x0408, 0x0008, 0xFE01, 0xFF01, 0x0002),
-  },
-  {    .channel                = 228,
-       .freq                   = 5140, /* MHz */
-       .unk2                   = 3427,
-       RADIOREGS(0x71, 0x02, 0x02, 0x0C, 0xC6, 0x01, 0x04, 0x0A,
-                 0x00, 0x8D, 0x99, 0x99, 0xDD, 0x00, 0x0C, 0x0E,
-                 0x8B, 0xDD, 0x00, 0x0C, 0x0E, 0x8B),
-       PHYREGS(0x0C08, 0x0808, 0x0408, 0xFD01, 0xFE01, 0xFF01),
-  },
-  {    .channel                = 32,
-       .freq                   = 5160, /* MHz */
-       .unk2                   = 3440,
-       RADIOREGS(0x71, 0x02, 0x04, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
-                 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D,
-                 0x8A, 0xCC, 0x00, 0x0B, 0x0D, 0x8A),
-       PHYREGS(0x1408, 0x1008, 0x0C08, 0xFB01, 0xFC01, 0xFD01),
-  },
-  {    .channel                = 34,
-       .freq                   = 5170, /* MHz */
-       .unk2                   = 3447,
-       RADIOREGS(0x71, 0x02, 0x05, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
-                 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D,
-                 0x8A, 0xCC, 0x00, 0x0B, 0x0D, 0x8A),
-       PHYREGS(0x1808, 0x1408, 0x1008, 0xFA01, 0xFB01, 0xFC01),
-  },
-  {    .channel                = 36,
-       .freq                   = 5180, /* MHz */
-       .unk2                   = 3453,
-       RADIOREGS(0x71, 0x02, 0x06, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
-                 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C,
-                 0x89, 0xCC, 0x00, 0x0B, 0x0C, 0x89),
-       PHYREGS(0x1C08, 0x1808, 0x1408, 0xF901, 0xFA01, 0xFB01),
-  },
-  {    .channel                = 38,
-       .freq                   = 5190, /* MHz */
-       .unk2                   = 3460,
-       RADIOREGS(0x71, 0x02, 0x07, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
-                 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C,
-                 0x89, 0xCC, 0x00, 0x0B, 0x0C, 0x89),
-       PHYREGS(0x2008, 0x1C08, 0x1808, 0xF801, 0xF901, 0xFA01),
-  },
-  {    .channel                = 40,
-       .freq                   = 5200, /* MHz */
-       .unk2                   = 3467,
-       RADIOREGS(0x71, 0x02, 0x08, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
-                 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B,
-                 0x89, 0xBB, 0x00, 0x0A, 0x0B, 0x89),
-       PHYREGS(0x2408, 0x2008, 0x1C08, 0xF701, 0xF801, 0xF901),
-  },
-  {    .channel                = 42,
-       .freq                   = 5210, /* MHz */
-       .unk2                   = 3473,
-       RADIOREGS(0x71, 0x02, 0x09, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
-                 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B,
-                 0x89, 0xBB, 0x00, 0x0A, 0x0B, 0x89),
-       PHYREGS(0x2808, 0x2408, 0x2008, 0xF601, 0xF701, 0xF801),
-  },
-  {    .channel                = 44,
-       .freq                   = 5220, /* MHz */
-       .unk2                   = 3480,
-       RADIOREGS(0x71, 0x02, 0x0A, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
-                 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A,
-                 0x88, 0xBB, 0x00, 0x09, 0x0A, 0x88),
-       PHYREGS(0x2C08, 0x2808, 0x2408, 0xF501, 0xF601, 0xF701),
-  },
-  {    .channel                = 46,
-       .freq                   = 5230, /* MHz */
-       .unk2                   = 3487,
-       RADIOREGS(0x71, 0x02, 0x0B, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
-                 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A,
-                 0x88, 0xBB, 0x00, 0x09, 0x0A, 0x88),
-       PHYREGS(0x3008, 0x2C08, 0x2808, 0xF401, 0xF501, 0xF601),
-  },
-  {    .channel                = 48,
-       .freq                   = 5240, /* MHz */
-       .unk2                   = 3493,
-       RADIOREGS(0x71, 0x02, 0x0C, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
-                 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A,
-                 0x87, 0xAA, 0x00, 0x09, 0x0A, 0x87),
-       PHYREGS(0x3408, 0x3008, 0x2C08, 0xF301, 0xF401, 0xF501),
-  },
-  {    .channel                = 50,
-       .freq                   = 5250, /* MHz */
-       .unk2                   = 3500,
-       RADIOREGS(0x71, 0x02, 0x0D, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
-                 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A,
-                 0x87, 0xAA, 0x00, 0x09, 0x0A, 0x87),
-       PHYREGS(0x3808, 0x3408, 0x3008, 0xF201, 0xF301, 0xF401),
-  },
-  {    .channel                = 52,
-       .freq                   = 5260, /* MHz */
-       .unk2                   = 3507,
-       RADIOREGS(0x71, 0x02, 0x0E, 0x0A, 0x98, 0x01, 0x04, 0x0A,
-                 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09,
-                 0x87, 0xAA, 0x00, 0x08, 0x09, 0x87),
-       PHYREGS(0x3C08, 0x3808, 0x3408, 0xF101, 0xF201, 0xF301),
-  },
-  {    .channel                = 54,
-       .freq                   = 5270, /* MHz */
-       .unk2                   = 3513,
-       RADIOREGS(0x71, 0x02, 0x0F, 0x0A, 0x98, 0x01, 0x04, 0x0A,
-                 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09,
-                 0x87, 0xAA, 0x00, 0x08, 0x09, 0x87),
-       PHYREGS(0x4008, 0x3C08, 0x3808, 0xF001, 0xF101, 0xF201),
-  },
-  {    .channel                = 56,
-       .freq                   = 5280, /* MHz */
-       .unk2                   = 3520,
-       RADIOREGS(0x71, 0x02, 0x10, 0x09, 0x91, 0x01, 0x04, 0x0A,
-                 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08,
-                 0x86, 0x99, 0x00, 0x08, 0x08, 0x86),
-       PHYREGS(0x4408, 0x4008, 0x3C08, 0xF001, 0xF001, 0xF101),
-  },
-  {    .channel                = 58,
-       .freq                   = 5290, /* MHz */
-       .unk2                   = 3527,
-       RADIOREGS(0x71, 0x02, 0x11, 0x09, 0x91, 0x01, 0x04, 0x0A,
-                 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08,
-                 0x86, 0x99, 0x00, 0x08, 0x08, 0x86),
-       PHYREGS(0x4808, 0x4408, 0x4008, 0xEF01, 0xF001, 0xF001),
-  },
-  {    .channel                = 60,
-       .freq                   = 5300, /* MHz */
-       .unk2                   = 3533,
-       RADIOREGS(0x71, 0x02, 0x12, 0x09, 0x8A, 0x01, 0x04, 0x0A,
-                 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07,
-                 0x85, 0x99, 0x00, 0x08, 0x07, 0x85),
-       PHYREGS(0x4C08, 0x4808, 0x4408, 0xEE01, 0xEF01, 0xF001),
-  },
-  {    .channel                = 62,
-       .freq                   = 5310, /* MHz */
-       .unk2                   = 3540,
-       RADIOREGS(0x71, 0x02, 0x13, 0x09, 0x8A, 0x01, 0x04, 0x0A,
-                 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07,
-                 0x85, 0x99, 0x00, 0x08, 0x07, 0x85),
-       PHYREGS(0x5008, 0x4C08, 0x4808, 0xED01, 0xEE01, 0xEF01),
-  },
-  {    .channel                = 64,
-       .freq                   = 5320, /* MHz */
-       .unk2                   = 3547,
-       RADIOREGS(0x71, 0x02, 0x14, 0x09, 0x83, 0x01, 0x04, 0x0A,
-                 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07,
-                 0x84, 0x88, 0x00, 0x07, 0x07, 0x84),
-       PHYREGS(0x5408, 0x5008, 0x4C08, 0xEC01, 0xED01, 0xEE01),
-  },
-  {    .channel                = 66,
-       .freq                   = 5330, /* MHz */
-       .unk2                   = 3553,
-       RADIOREGS(0x71, 0x02, 0x15, 0x09, 0x83, 0x01, 0x04, 0x0A,
-                 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07,
-                 0x84, 0x88, 0x00, 0x07, 0x07, 0x84),
-       PHYREGS(0x5808, 0x5408, 0x5008, 0xEB01, 0xEC01, 0xED01),
-  },
-  {    .channel                = 68,
-       .freq                   = 5340, /* MHz */
-       .unk2                   = 3560,
-       RADIOREGS(0x71, 0x02, 0x16, 0x08, 0x7C, 0x01, 0x04, 0x0A,
-                 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06,
-                 0x84, 0x88, 0x00, 0x07, 0x06, 0x84),
-       PHYREGS(0x5C08, 0x5808, 0x5408, 0xEA01, 0xEB01, 0xEC01),
-  },
-  {    .channel                = 70,
-       .freq                   = 5350, /* MHz */
-       .unk2                   = 3567,
-       RADIOREGS(0x71, 0x02, 0x17, 0x08, 0x7C, 0x01, 0x04, 0x0A,
-                 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06,
-                 0x84, 0x88, 0x00, 0x07, 0x06, 0x84),
-       PHYREGS(0x6008, 0x5C08, 0x5808, 0xE901, 0xEA01, 0xEB01),
-  },
-  {    .channel                = 72,
-       .freq                   = 5360, /* MHz */
-       .unk2                   = 3573,
-       RADIOREGS(0x71, 0x02, 0x18, 0x08, 0x75, 0x01, 0x04, 0x0A,
-                 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05,
-                 0x83, 0x77, 0x00, 0x06, 0x05, 0x83),
-       PHYREGS(0x6408, 0x6008, 0x5C08, 0xE801, 0xE901, 0xEA01),
-  },
-  {    .channel                = 74,
-       .freq                   = 5370, /* MHz */
-       .unk2                   = 3580,
-       RADIOREGS(0x71, 0x02, 0x19, 0x08, 0x75, 0x01, 0x04, 0x0A,
-                 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05,
-                 0x83, 0x77, 0x00, 0x06, 0x05, 0x83),
-       PHYREGS(0x6808, 0x6408, 0x6008, 0xE701, 0xE801, 0xE901),
-  },
-  {    .channel                = 76,
-       .freq                   = 5380, /* MHz */
-       .unk2                   = 3587,
-       RADIOREGS(0x71, 0x02, 0x1A, 0x08, 0x6E, 0x01, 0x04, 0x0A,
-                 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04,
-                 0x82, 0x77, 0x00, 0x06, 0x04, 0x82),
-       PHYREGS(0x6C08, 0x6808, 0x6408, 0xE601, 0xE701, 0xE801),
-  },
-  {    .channel                = 78,
-       .freq                   = 5390, /* MHz */
-       .unk2                   = 3593,
-       RADIOREGS(0x71, 0x02, 0x1B, 0x08, 0x6E, 0x01, 0x04, 0x0A,
-                 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04,
-                 0x82, 0x77, 0x00, 0x06, 0x04, 0x82),
-       PHYREGS(0x7008, 0x6C08, 0x6808, 0xE501, 0xE601, 0xE701),
-  },
-  {    .channel                = 80,
-       .freq                   = 5400, /* MHz */
-       .unk2                   = 3600,
-       RADIOREGS(0x71, 0x02, 0x1C, 0x07, 0x67, 0x01, 0x04, 0x0A,
-                 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04,
-                 0x81, 0x66, 0x00, 0x05, 0x04, 0x81),
-       PHYREGS(0x7408, 0x7008, 0x6C08, 0xE501, 0xE501, 0xE601),
-  },
-  {    .channel                = 82,
-       .freq                   = 5410, /* MHz */
-       .unk2                   = 3607,
-       RADIOREGS(0x71, 0x02, 0x1D, 0x07, 0x67, 0x01, 0x04, 0x0A,
-                 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04,
-                 0x81, 0x66, 0x00, 0x05, 0x04, 0x81),
-       PHYREGS(0x7808, 0x7408, 0x7008, 0xE401, 0xE501, 0xE501),
-  },
-  {    .channel                = 84,
-       .freq                   = 5420, /* MHz */
-       .unk2                   = 3613,
-       RADIOREGS(0x71, 0x02, 0x1E, 0x07, 0x61, 0x01, 0x04, 0x0A,
-                 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03,
-                 0x80, 0x66, 0x00, 0x05, 0x03, 0x80),
-       PHYREGS(0x7C08, 0x7808, 0x7408, 0xE301, 0xE401, 0xE501),
-  },
-  {    .channel                = 86,
-       .freq                   = 5430, /* MHz */
-       .unk2                   = 3620,
-       RADIOREGS(0x71, 0x02, 0x1F, 0x07, 0x61, 0x01, 0x04, 0x0A,
-                 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03,
-                 0x80, 0x66, 0x00, 0x05, 0x03, 0x80),
-       PHYREGS(0x8008, 0x7C08, 0x7808, 0xE201, 0xE301, 0xE401),
-  },
-  {    .channel                = 88,
-       .freq                   = 5440, /* MHz */
-       .unk2                   = 3627,
-       RADIOREGS(0x71, 0x02, 0x20, 0x07, 0x5A, 0x01, 0x04, 0x0A,
-                 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02,
-                 0x80, 0x55, 0x00, 0x04, 0x02, 0x80),
-       PHYREGS(0x8408, 0x8008, 0x7C08, 0xE101, 0xE201, 0xE301),
-  },
-  {    .channel                = 90,
-       .freq                   = 5450, /* MHz */
-       .unk2                   = 3633,
-       RADIOREGS(0x71, 0x02, 0x21, 0x07, 0x5A, 0x01, 0x04, 0x0A,
-                 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02,
-                 0x80, 0x55, 0x00, 0x04, 0x02, 0x80),
-       PHYREGS(0x8808, 0x8408, 0x8008, 0xE001, 0xE101, 0xE201),
-  },
-  {    .channel                = 92,
-       .freq                   = 5460, /* MHz */
-       .unk2                   = 3640,
-       RADIOREGS(0x71, 0x02, 0x22, 0x06, 0x53, 0x01, 0x04, 0x0A,
-                 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01,
-                 0x80, 0x55, 0x00, 0x04, 0x01, 0x80),
-       PHYREGS(0x8C08, 0x8808, 0x8408, 0xDF01, 0xE001, 0xE101),
-  },
-  {    .channel                = 94,
-       .freq                   = 5470, /* MHz */
-       .unk2                   = 3647,
-       RADIOREGS(0x71, 0x02, 0x23, 0x06, 0x53, 0x01, 0x04, 0x0A,
-                 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01,
-                 0x80, 0x55, 0x00, 0x04, 0x01, 0x80),
-       PHYREGS(0x9008, 0x8C08, 0x8808, 0xDE01, 0xDF01, 0xE001),
-  },
-  {    .channel                = 96,
-       .freq                   = 5480, /* MHz */
-       .unk2                   = 3653,
-       RADIOREGS(0x71, 0x02, 0x24, 0x06, 0x4D, 0x01, 0x04, 0x0A,
-                 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00,
-                 0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
-       PHYREGS(0x9408, 0x9008, 0x8C08, 0xDD01, 0xDE01, 0xDF01),
-  },
-  {    .channel                = 98,
-       .freq                   = 5490, /* MHz */
-       .unk2                   = 3660,
-       RADIOREGS(0x71, 0x02, 0x25, 0x06, 0x4D, 0x01, 0x04, 0x0A,
-                 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00,
-                 0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
-       PHYREGS(0x9808, 0x9408, 0x9008, 0xDD01, 0xDD01, 0xDE01),
-  },
-  {    .channel                = 100,
-       .freq                   = 5500, /* MHz */
-       .unk2                   = 3667,
-       RADIOREGS(0x71, 0x02, 0x26, 0x06, 0x47, 0x01, 0x04, 0x0A,
-                 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00,
-                 0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
-       PHYREGS(0x9C08, 0x9808, 0x9408, 0xDC01, 0xDD01, 0xDD01),
-  },
-  {    .channel                = 102,
-       .freq                   = 5510, /* MHz */
-       .unk2                   = 3673,
-       RADIOREGS(0x71, 0x02, 0x27, 0x06, 0x47, 0x01, 0x04, 0x0A,
-                 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00,
-                 0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
-       PHYREGS(0xA008, 0x9C08, 0x9808, 0xDB01, 0xDC01, 0xDD01),
-  },
-  {    .channel                = 104,
-       .freq                   = 5520, /* MHz */
-       .unk2                   = 3680,
-       RADIOREGS(0x71, 0x02, 0x28, 0x05, 0x40, 0x01, 0x04, 0x0A,
-                 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
-                 0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
-       PHYREGS(0xA408, 0xA008, 0x9C08, 0xDA01, 0xDB01, 0xDC01),
-  },
-  {    .channel                = 106,
-       .freq                   = 5530, /* MHz */
-       .unk2                   = 3687,
-       RADIOREGS(0x71, 0x02, 0x29, 0x05, 0x40, 0x01, 0x04, 0x0A,
-                 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
-                 0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
-       PHYREGS(0xA808, 0xA408, 0xA008, 0xD901, 0xDA01, 0xDB01),
-  },
-  {    .channel                = 108,
-       .freq                   = 5540, /* MHz */
-       .unk2                   = 3693,
-       RADIOREGS(0x71, 0x02, 0x2A, 0x05, 0x3A, 0x01, 0x04, 0x0A,
-                 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
-                 0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
-       PHYREGS(0xAC08, 0xA808, 0xA408, 0xD801, 0xD901, 0xDA01),
-  },
-  {    .channel                = 110,
-       .freq                   = 5550, /* MHz */
-       .unk2                   = 3700,
-       RADIOREGS(0x71, 0x02, 0x2B, 0x05, 0x3A, 0x01, 0x04, 0x0A,
-                 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
-                 0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
-       PHYREGS(0xB008, 0xAC08, 0xA808, 0xD701, 0xD801, 0xD901),
-  },
-  {    .channel                = 112,
-       .freq                   = 5560, /* MHz */
-       .unk2                   = 3707,
-       RADIOREGS(0x71, 0x02, 0x2C, 0x05, 0x34, 0x01, 0x04, 0x0A,
-                 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
-                 0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
-       PHYREGS(0xB408, 0xB008, 0xAC08, 0xD701, 0xD701, 0xD801),
-  },
-  {    .channel                = 114,
-       .freq                   = 5570, /* MHz */
-       .unk2                   = 3713,
-       RADIOREGS(0x71, 0x02, 0x2D, 0x05, 0x34, 0x01, 0x04, 0x0A,
-                 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
-                 0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
-       PHYREGS(0xB808, 0xB408, 0xB008, 0xD601, 0xD701, 0xD701),
-  },
-  {    .channel                = 116,
-       .freq                   = 5580, /* MHz */
-       .unk2                   = 3720,
-       RADIOREGS(0x71, 0x02, 0x2E, 0x04, 0x2E, 0x01, 0x04, 0x0A,
-                 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
-                 0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
-       PHYREGS(0xBC08, 0xB808, 0xB408, 0xD501, 0xD601, 0xD701),
-  },
-  {    .channel                = 118,
-       .freq                   = 5590, /* MHz */
-       .unk2                   = 3727,
-       RADIOREGS(0x71, 0x02, 0x2F, 0x04, 0x2E, 0x01, 0x04, 0x0A,
-                 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
-                 0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
-       PHYREGS(0xC008, 0xBC08, 0xB808, 0xD401, 0xD501, 0xD601),
-  },
-  {    .channel                = 120,
-       .freq                   = 5600, /* MHz */
-       .unk2                   = 3733,
-       RADIOREGS(0x71, 0x02, 0x30, 0x04, 0x28, 0x01, 0x04, 0x0A,
-                 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00,
-                 0x80, 0x11, 0x00, 0x01, 0x00, 0x80),
-       PHYREGS(0xC408, 0xC008, 0xBC08, 0xD301, 0xD401, 0xD501),
-  },
-  {    .channel                = 122,
-       .freq                   = 5610, /* MHz */
-       .unk2                   = 3740,
-       RADIOREGS(0x71, 0x02, 0x31, 0x04, 0x28, 0x01, 0x04, 0x0A,
-                 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00,
-                 0x80, 0x11, 0x00, 0x01, 0x00, 0x80),
-       PHYREGS(0xC808, 0xC408, 0xC008, 0xD201, 0xD301, 0xD401),
-  },
-  {    .channel                = 124,
-       .freq                   = 5620, /* MHz */
-       .unk2                   = 3747,
-       RADIOREGS(0x71, 0x02, 0x32, 0x04, 0x21, 0x01, 0x04, 0x0A,
-                 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
-                 0x80, 0x11, 0x00, 0x00, 0x00, 0x80),
-       PHYREGS(0xCC08, 0xC808, 0xC408, 0xD201, 0xD201, 0xD301),
-  },
-  {    .channel                = 126,
-       .freq                   = 5630, /* MHz */
-       .unk2                   = 3753,
-       RADIOREGS(0x71, 0x02, 0x33, 0x04, 0x21, 0x01, 0x04, 0x0A,
-                 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
-                 0x80, 0x11, 0x00, 0x00, 0x00, 0x80),
-       PHYREGS(0xD008, 0xCC08, 0xC808, 0xD101, 0xD201, 0xD201),
-  },
-  {    .channel                = 128,
-       .freq                   = 5640, /* MHz */
-       .unk2                   = 3760,
-       RADIOREGS(0x71, 0x02, 0x34, 0x03, 0x1C, 0x01, 0x04, 0x0A,
-                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-       PHYREGS(0xD408, 0xD008, 0xCC08, 0xD001, 0xD101, 0xD201),
-  },
-  {    .channel                = 130,
-       .freq                   = 5650, /* MHz */
-       .unk2                   = 3767,
-       RADIOREGS(0x71, 0x02, 0x35, 0x03, 0x1C, 0x01, 0x04, 0x0A,
-                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-       PHYREGS(0xD808, 0xD408, 0xD008, 0xCF01, 0xD001, 0xD101),
-  },
-  {    .channel                = 132,
-       .freq                   = 5660, /* MHz */
-       .unk2                   = 3773,
-       RADIOREGS(0x71, 0x02, 0x36, 0x03, 0x16, 0x01, 0x04, 0x0A,
-                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-       PHYREGS(0xDC08, 0xD808, 0xD408, 0xCE01, 0xCF01, 0xD001),
-  },
-  {    .channel                = 134,
-       .freq                   = 5670, /* MHz */
-       .unk2                   = 3780,
-       RADIOREGS(0x71, 0x02, 0x37, 0x03, 0x16, 0x01, 0x04, 0x0A,
-                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-       PHYREGS(0xE008, 0xDC08, 0xD808, 0xCE01, 0xCE01, 0xCF01),
-  },
-  {    .channel                = 136,
-       .freq                   = 5680, /* MHz */
-       .unk2                   = 3787,
-       RADIOREGS(0x71, 0x02, 0x38, 0x03, 0x10, 0x01, 0x04, 0x0A,
-                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-       PHYREGS(0xE408, 0xE008, 0xDC08, 0xCD01, 0xCE01, 0xCE01),
-  },
-  {    .channel                = 138,
-       .freq                   = 5690, /* MHz */
-       .unk2                   = 3793,
-       RADIOREGS(0x71, 0x02, 0x39, 0x03, 0x10, 0x01, 0x04, 0x0A,
-                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-       PHYREGS(0xE808, 0xE408, 0xE008, 0xCC01, 0xCD01, 0xCE01),
-  },
-  {    .channel                = 140,
-       .freq                   = 5700, /* MHz */
-       .unk2                   = 3800,
-       RADIOREGS(0x71, 0x02, 0x3A, 0x02, 0x0A, 0x01, 0x04, 0x0A,
-                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-       PHYREGS(0xEC08, 0xE808, 0xE408, 0xCB01, 0xCC01, 0xCD01),
-  },
-  {    .channel                = 142,
-       .freq                   = 5710, /* MHz */
-       .unk2                   = 3807,
-       RADIOREGS(0x71, 0x02, 0x3B, 0x02, 0x0A, 0x01, 0x04, 0x0A,
-                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-       PHYREGS(0xF008, 0xEC08, 0xE808, 0xCA01, 0xCB01, 0xCC01),
-  },
-  {    .channel                = 144,
-       .freq                   = 5720, /* MHz */
-       .unk2                   = 3813,
-       RADIOREGS(0x71, 0x02, 0x3C, 0x02, 0x0A, 0x01, 0x04, 0x0A,
-                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-       PHYREGS(0xF408, 0xF008, 0xEC08, 0xC901, 0xCA01, 0xCB01),
-  },
-  {    .channel                = 145,
-       .freq                   = 5725, /* MHz */
-       .unk2                   = 3817,
-       RADIOREGS(0x72, 0x04, 0x79, 0x02, 0x03, 0x01, 0x03, 0x14,
-                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-       PHYREGS(0xF608, 0xF208, 0xEE08, 0xC901, 0xCA01, 0xCB01),
-  },
-  {    .channel                = 146,
-       .freq                   = 5730, /* MHz */
-       .unk2                   = 3820,
-       RADIOREGS(0x71, 0x02, 0x3D, 0x02, 0x0A, 0x01, 0x04, 0x0A,
-                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-       PHYREGS(0xF808, 0xF408, 0xF008, 0xC901, 0xC901, 0xCA01),
-  },
-  {    .channel                = 147,
-       .freq                   = 5735, /* MHz */
-       .unk2                   = 3823,
-       RADIOREGS(0x72, 0x04, 0x7B, 0x02, 0x03, 0x01, 0x03, 0x14,
-                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-       PHYREGS(0xFA08, 0xF608, 0xF208, 0xC801, 0xC901, 0xCA01),
-  },
-  {    .channel                = 148,
-       .freq                   = 5740, /* MHz */
-       .unk2                   = 3827,
-       RADIOREGS(0x71, 0x02, 0x3E, 0x02, 0x0A, 0x01, 0x04, 0x0A,
-                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-       PHYREGS(0xFC08, 0xF808, 0xF408, 0xC801, 0xC901, 0xC901),
-  },
-  {    .channel                = 149,
-       .freq                   = 5745, /* MHz */
-       .unk2                   = 3830,
-       RADIOREGS(0x72, 0x04, 0x7D, 0x02, 0xFE, 0x00, 0x03, 0x14,
-                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-       PHYREGS(0xFE08, 0xFA08, 0xF608, 0xC801, 0xC801, 0xC901),
-  },
-  {    .channel                = 150,
-       .freq                   = 5750, /* MHz */
-       .unk2                   = 3833,
-       RADIOREGS(0x71, 0x02, 0x3F, 0x02, 0x0A, 0x01, 0x04, 0x0A,
-                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-       PHYREGS(0x0009, 0xFC08, 0xF808, 0xC701, 0xC801, 0xC901),
-  },
-  {    .channel                = 151,
-       .freq                   = 5755, /* MHz */
-       .unk2                   = 3837,
-       RADIOREGS(0x72, 0x04, 0x7F, 0x02, 0xFE, 0x00, 0x03, 0x14,
-                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-       PHYREGS(0x0209, 0xFE08, 0xFA08, 0xC701, 0xC801, 0xC801),
-  },
-  {    .channel                = 152,
-       .freq                   = 5760, /* MHz */
-       .unk2                   = 3840,
-       RADIOREGS(0x71, 0x02, 0x40, 0x02, 0x0A, 0x01, 0x04, 0x0A,
-                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-       PHYREGS(0x0409, 0x0009, 0xFC08, 0xC601, 0xC701, 0xC801),
-  },
-  {    .channel                = 153,
-       .freq                   = 5765, /* MHz */
-       .unk2                   = 3843,
-       RADIOREGS(0x72, 0x04, 0x81, 0x02, 0xF8, 0x00, 0x03, 0x14,
-                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-       PHYREGS(0x0609, 0x0209, 0xFE08, 0xC601, 0xC701, 0xC801),
-  },
-  {    .channel                = 154,
-       .freq                   = 5770, /* MHz */
-       .unk2                   = 3847,
-       RADIOREGS(0x71, 0x02, 0x41, 0x02, 0x0A, 0x01, 0x04, 0x0A,
-                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-       PHYREGS(0x0809, 0x0409, 0x0009, 0xC601, 0xC601, 0xC701),
-  },
-  {    .channel                = 155,
-       .freq                   = 5775, /* MHz */
-       .unk2                   = 3850,
-       RADIOREGS(0x72, 0x04, 0x83, 0x02, 0xF8, 0x00, 0x03, 0x14,
-                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-       PHYREGS(0x0A09, 0x0609, 0x0209, 0xC501, 0xC601, 0xC701),
-  },
-  {    .channel                = 156,
-       .freq                   = 5780, /* MHz */
-       .unk2                   = 3853,
-       RADIOREGS(0x71, 0x02, 0x42, 0x02, 0x0A, 0x01, 0x04, 0x0A,
-                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-       PHYREGS(0x0C09, 0x0809, 0x0409, 0xC501, 0xC601, 0xC601),
-  },
-  {    .channel                = 157,
-       .freq                   = 5785, /* MHz */
-       .unk2                   = 3857,
-       RADIOREGS(0x72, 0x04, 0x85, 0x02, 0xF2, 0x00, 0x03, 0x14,
-                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-       PHYREGS(0x0E09, 0x0A09, 0x0609, 0xC401, 0xC501, 0xC601),
-  },
-  {    .channel                = 158,
-       .freq                   = 5790, /* MHz */
-       .unk2                   = 3860,
-       RADIOREGS(0x71, 0x02, 0x43, 0x02, 0x0A, 0x01, 0x04, 0x0A,
-                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-       PHYREGS(0x1009, 0x0C09, 0x0809, 0xC401, 0xC501, 0xC601),
-  },
-  {    .channel                = 159,
-       .freq                   = 5795, /* MHz */
-       .unk2                   = 3863,
-       RADIOREGS(0x72, 0x04, 0x87, 0x02, 0xF2, 0x00, 0x03, 0x14,
-                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-       PHYREGS(0x1209, 0x0E09, 0x0A09, 0xC401, 0xC401, 0xC501),
-  },
-  {    .channel                = 160,
-       .freq                   = 5800, /* MHz */
-       .unk2                   = 3867,
-       RADIOREGS(0x71, 0x02, 0x44, 0x01, 0x0A, 0x01, 0x04, 0x0A,
-                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-       PHYREGS(0x1409, 0x1009, 0x0C09, 0xC301, 0xC401, 0xC501),
-  },
-  {    .channel                = 161,
-       .freq                   = 5805, /* MHz */
-       .unk2                   = 3870,
-       RADIOREGS(0x72, 0x04, 0x89, 0x01, 0xED, 0x00, 0x03, 0x14,
-                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-       PHYREGS(0x1609, 0x1209, 0x0E09, 0xC301, 0xC401, 0xC401),
-  },
-  {    .channel                = 162,
-       .freq                   = 5810, /* MHz */
-       .unk2                   = 3873,
-       RADIOREGS(0x71, 0x02, 0x45, 0x01, 0x0A, 0x01, 0x04, 0x0A,
-                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-       PHYREGS(0x1809, 0x1409, 0x1009, 0xC201, 0xC301, 0xC401),
-  },
-  {    .channel                = 163,
-       .freq                   = 5815, /* MHz */
-       .unk2                   = 3877,
-       RADIOREGS(0x72, 0x04, 0x8B, 0x01, 0xED, 0x00, 0x03, 0x14,
-                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-       PHYREGS(0x1A09, 0x1609, 0x1209, 0xC201, 0xC301, 0xC401),
-  },
-  {    .channel                = 164,
-       .freq                   = 5820, /* MHz */
-       .unk2                   = 3880,
-       RADIOREGS(0x71, 0x02, 0x46, 0x01, 0x0A, 0x01, 0x04, 0x0A,
-                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-       PHYREGS(0x1C09, 0x1809, 0x1409, 0xC201, 0xC201, 0xC301),
-  },
-  {    .channel                = 165,
-       .freq                   = 5825, /* MHz */
-       .unk2                   = 3883,
-       RADIOREGS(0x72, 0x04, 0x8D, 0x01, 0xED, 0x00, 0x03, 0x14,
-                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-       PHYREGS(0x1E09, 0x1A09, 0x1609, 0xC101, 0xC201, 0xC301),
-  },
-  {    .channel                = 166,
-       .freq                   = 5830, /* MHz */
-       .unk2                   = 3887,
-       RADIOREGS(0x71, 0x02, 0x47, 0x01, 0x0A, 0x01, 0x04, 0x0A,
-                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-       PHYREGS(0x2009, 0x1C09, 0x1809, 0xC101, 0xC201, 0xC201),
-  },
-  {    .channel                = 168,
-       .freq                   = 5840, /* MHz */
-       .unk2                   = 3893,
-       RADIOREGS(0x71, 0x02, 0x48, 0x01, 0x0A, 0x01, 0x04, 0x0A,
-                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-       PHYREGS(0x2409, 0x2009, 0x1C09, 0xC001, 0xC101, 0xC201),
-  },
-  {    .channel                = 170,
-       .freq                   = 5850, /* MHz */
-       .unk2                   = 3900,
-       RADIOREGS(0x71, 0x02, 0x49, 0x01, 0xE0, 0x00, 0x04, 0x0A,
-                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-       PHYREGS(0x2809, 0x2409, 0x2009, 0xBF01, 0xC001, 0xC101),
-  },
-  {    .channel                = 172,
-       .freq                   = 5860, /* MHz */
-       .unk2                   = 3907,
-       RADIOREGS(0x71, 0x02, 0x4A, 0x01, 0xDE, 0x00, 0x04, 0x0A,
-                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-       PHYREGS(0x2C09, 0x2809, 0x2409, 0xBF01, 0xBF01, 0xC001),
-  },
-  {    .channel                = 174,
-       .freq                   = 5870, /* MHz */
-       .unk2                   = 3913,
-       RADIOREGS(0x71, 0x02, 0x4B, 0x00, 0xDB, 0x00, 0x04, 0x0A,
-                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-       PHYREGS(0x3009, 0x2C09, 0x2809, 0xBE01, 0xBF01, 0xBF01),
-  },
-  {    .channel                = 176,
-       .freq                   = 5880, /* MHz */
-       .unk2                   = 3920,
-       RADIOREGS(0x71, 0x02, 0x4C, 0x00, 0xD8, 0x00, 0x04, 0x0A,
-                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-       PHYREGS(0x3409, 0x3009, 0x2C09, 0xBD01, 0xBE01, 0xBF01),
-  },
-  {    .channel                = 178,
-       .freq                   = 5890, /* MHz */
-       .unk2                   = 3927,
-       RADIOREGS(0x71, 0x02, 0x4D, 0x00, 0xD6, 0x00, 0x04, 0x0A,
-                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-       PHYREGS(0x3809, 0x3409, 0x3009, 0xBC01, 0xBD01, 0xBE01),
-  },
-  {    .channel                = 180,
-       .freq                   = 5900, /* MHz */
-       .unk2                   = 3933,
-       RADIOREGS(0x71, 0x02, 0x4E, 0x00, 0xD3, 0x00, 0x04, 0x0A,
-                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-       PHYREGS(0x3C09, 0x3809, 0x3409, 0xBC01, 0xBC01, 0xBD01),
-  },
-  {    .channel                = 182,
-       .freq                   = 5910, /* MHz */
-       .unk2                   = 3940,
-       RADIOREGS(0x71, 0x02, 0x4F, 0x00, 0xD6, 0x00, 0x04, 0x0A,
-                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
-       PHYREGS(0x4009, 0x3C09, 0x3809, 0xBB01, 0xBC01, 0xBC01),
-  },
-  {    .channel                = 1,
-       .freq                   = 2412, /* MHz */
-       .unk2                   = 3216,
-       RADIOREGS(0x73, 0x09, 0x6C, 0x0F, 0x00, 0x01, 0x07, 0x15,
-                 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0D, 0x0C,
-                 0x80, 0xFF, 0x88, 0x0D, 0x0C, 0x80),
-       PHYREGS(0xC903, 0xC503, 0xC103, 0x3A04, 0x3F04, 0x4304),
-  },
-  {    .channel                = 2,
-       .freq                   = 2417, /* MHz */
-       .unk2                   = 3223,
-       RADIOREGS(0x73, 0x09, 0x71, 0x0F, 0x00, 0x01, 0x07, 0x15,
-                 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0B,
-                 0x80, 0xFF, 0x88, 0x0C, 0x0B, 0x80),
-       PHYREGS(0xCB03, 0xC703, 0xC303, 0x3804, 0x3D04, 0x4104),
-  },
-  {    .channel                = 3,
-       .freq                   = 2422, /* MHz */
-       .unk2                   = 3229,
-       RADIOREGS(0x73, 0x09, 0x76, 0x0F, 0x00, 0x01, 0x07, 0x15,
-                 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A,
-                 0x80, 0xFF, 0x88, 0x0C, 0x0A, 0x80),
-       PHYREGS(0xCD03, 0xC903, 0xC503, 0x3604, 0x3A04, 0x3F04),
-  },
-  {    .channel                = 4,
-       .freq                   = 2427, /* MHz */
-       .unk2                   = 3236,
-       RADIOREGS(0x73, 0x09, 0x7B, 0x0F, 0x00, 0x01, 0x07, 0x15,
-                 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A,
-                 0x80, 0xFF, 0x88, 0x0C, 0x0A, 0x80),
-       PHYREGS(0xCF03, 0xCB03, 0xC703, 0x3404, 0x3804, 0x3D04),
-  },
-  {    .channel                = 5,
-       .freq                   = 2432, /* MHz */
-       .unk2                   = 3243,
-       RADIOREGS(0x73, 0x09, 0x80, 0x0F, 0x00, 0x01, 0x07, 0x15,
-                 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x09,
-                 0x80, 0xFF, 0x88, 0x0C, 0x09, 0x80),
-       PHYREGS(0xD103, 0xCD03, 0xC903, 0x3104, 0x3604, 0x3A04),
-  },
-  {    .channel                = 6,
-       .freq                   = 2437, /* MHz */
-       .unk2                   = 3249,
-       RADIOREGS(0x73, 0x09, 0x85, 0x0F, 0x00, 0x01, 0x07, 0x15,
-                 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0B, 0x08,
-                 0x80, 0xFF, 0x88, 0x0B, 0x08, 0x80),
-       PHYREGS(0xD303, 0xCF03, 0xCB03, 0x2F04, 0x3404, 0x3804),
-  },
-  {    .channel                = 7,
-       .freq                   = 2442, /* MHz */
-       .unk2                   = 3256,
-       RADIOREGS(0x73, 0x09, 0x8A, 0x0F, 0x00, 0x01, 0x07, 0x15,
-                 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x07,
-                 0x80, 0xFF, 0x88, 0x0A, 0x07, 0x80),
-       PHYREGS(0xD503, 0xD103, 0xCD03, 0x2D04, 0x3104, 0x3604),
-  },
-  {    .channel                = 8,
-       .freq                   = 2447, /* MHz */
-       .unk2                   = 3263,
-       RADIOREGS(0x73, 0x09, 0x8F, 0x0F, 0x00, 0x01, 0x07, 0x15,
-                 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x06,
-                 0x80, 0xFF, 0x88, 0x0A, 0x06, 0x80),
-       PHYREGS(0xD703, 0xD303, 0xCF03, 0x2B04, 0x2F04, 0x3404),
-  },
-  {    .channel                = 9,
-       .freq                   = 2452, /* MHz */
-       .unk2                   = 3269,
-       RADIOREGS(0x73, 0x09, 0x94, 0x0F, 0x00, 0x01, 0x07, 0x15,
-                 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x09, 0x06,
-                 0x80, 0xFF, 0x88, 0x09, 0x06, 0x80),
-       PHYREGS(0xD903, 0xD503, 0xD103, 0x2904, 0x2D04, 0x3104),
-  },
-  {    .channel                = 10,
-       .freq                   = 2457, /* MHz */
-       .unk2                   = 3276,
-       RADIOREGS(0x73, 0x09, 0x99, 0x0F, 0x00, 0x01, 0x07, 0x15,
-                 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x05,
-                 0x80, 0xFF, 0x88, 0x08, 0x05, 0x80),
-       PHYREGS(0xDB03, 0xD703, 0xD303, 0x2704, 0x2B04, 0x2F04),
-  },
-  {    .channel                = 11,
-       .freq                   = 2462, /* MHz */
-       .unk2                   = 3283,
-       RADIOREGS(0x73, 0x09, 0x9E, 0x0F, 0x00, 0x01, 0x07, 0x15,
-                 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x04,
-                 0x80, 0xFF, 0x88, 0x08, 0x04, 0x80),
-       PHYREGS(0xDD03, 0xD903, 0xD503, 0x2404, 0x2904, 0x2D04),
-  },
-  {    .channel                = 12,
-       .freq                   = 2467, /* MHz */
-       .unk2                   = 3289,
-       RADIOREGS(0x73, 0x09, 0xA3, 0x0F, 0x00, 0x01, 0x07, 0x15,
-                 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x03,
-                 0x80, 0xFF, 0x88, 0x08, 0x03, 0x80),
-       PHYREGS(0xDF03, 0xDB03, 0xD703, 0x2204, 0x2704, 0x2B04),
-  },
-  {    .channel                = 13,
-       .freq                   = 2472, /* MHz */
-       .unk2                   = 3296,
-       RADIOREGS(0x73, 0x09, 0xA8, 0x0F, 0x00, 0x01, 0x07, 0x15,
-                 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x03,
-                 0x80, 0xFF, 0x88, 0x07, 0x03, 0x80),
-       PHYREGS(0xE103, 0xDD03, 0xD903, 0x2004, 0x2404, 0x2904),
-  },
-  {    .channel                = 14,
-       .freq                   = 2484, /* MHz */
-       .unk2                   = 3312,
-       RADIOREGS(0x73, 0x09, 0xB4, 0x0F, 0xFF, 0x01, 0x07, 0x15,
-                 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x01,
-                 0x80, 0xFF, 0x88, 0x07, 0x01, 0x80),
-       PHYREGS(0xE603, 0xE203, 0xDE03, 0x1B04, 0x1F04, 0x2404),
-  },
-};
-
-const struct b43_nphy_channeltab_entry_rev2 *
-b43_nphy_get_chantabent_rev2(struct b43_wldev *dev, u8 channel)
-{
-       const struct b43_nphy_channeltab_entry_rev2 *e;
-       unsigned int i;
-
-       for (i = 0; i < ARRAY_SIZE(b43_nphy_channeltab); i++) {
-               e = &(b43_nphy_channeltab[i]);
-               if (e->channel == channel)
-                       return e;
-       }
-
-       return NULL;
-}
-
-
 static const u8 b43_ntab_adjustpower0[] = {
        0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
        0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03,
index 8fc1da9f8fe57bce8bf0a531f4ef56b2d248dac9..4ec593ba3eef16930974ee0aeaf4dea64e2eaa53 100644 (file)
@@ -3,7 +3,6 @@
 
 #include <linux/types.h>
 
-
 struct b43_phy_n_sfo_cfg {
        u16 phy_bw1a;
        u16 phy_bw2;
@@ -13,52 +12,6 @@ struct b43_phy_n_sfo_cfg {
        u16 phy_bw6;
 };
 
-struct b43_nphy_channeltab_entry_rev2 {
-       /* The channel number */
-       u8 channel;
-       /* The channel frequency in MHz */
-       u16 freq;
-       /* An unknown value */
-       u16 unk2;
-       /* Radio register values on channelswitch */
-       u8 radio_pll_ref;
-       u8 radio_rf_pllmod0;
-       u8 radio_rf_pllmod1;
-       u8 radio_vco_captail;
-       u8 radio_vco_cal1;
-       u8 radio_vco_cal2;
-       u8 radio_pll_lfc1;
-       u8 radio_pll_lfr1;
-       u8 radio_pll_lfc2;
-       u8 radio_lgbuf_cenbuf;
-       u8 radio_lgen_tune1;
-       u8 radio_lgen_tune2;
-       u8 radio_c1_lgbuf_atune;
-       u8 radio_c1_lgbuf_gtune;
-       u8 radio_c1_rx_rfr1;
-       u8 radio_c1_tx_pgapadtn;
-       u8 radio_c1_tx_mxbgtrim;
-       u8 radio_c2_lgbuf_atune;
-       u8 radio_c2_lgbuf_gtune;
-       u8 radio_c2_rx_rfr1;
-       u8 radio_c2_tx_pgapadtn;
-       u8 radio_c2_tx_mxbgtrim;
-       /* PHY register values on channelswitch */
-       struct b43_phy_n_sfo_cfg phy_regs;
-};
-
-struct b43_nphy_channeltab_entry_rev3 {
-       /* The channel number */
-       u8 channel;
-       /* The channel frequency in MHz */
-       u16 freq;
-       /* Radio register values on channelswitch */
-       /* TODO */
-       /* PHY register values on channelswitch */
-       struct b43_phy_n_sfo_cfg phy_regs;
-};
-
-
 struct b43_wldev;
 
 struct nphy_txiqcal_ladder {
@@ -82,18 +35,12 @@ struct nphy_rf_control_override_rev3 {
        u8 val_addr1;
 };
 
-/* Upload the default register value table.
- * If "ghz5" is true, we upload the 5Ghz table. Otherwise the 2.4Ghz
- * table is uploaded. If "ignore_uploadflag" is true, we upload any value
- * and ignore the "UPLOAD" flag. */
-void b2055_upload_inittab(struct b43_wldev *dev,
-                         bool ghz5, bool ignore_uploadflag);
-
-
-/* Get the NPHY Channel Switch Table entry for a channel number.
+/* Get the NPHY Channel Switch Table entry for a channel.
  * Returns NULL on failure to find an entry. */
 const struct b43_nphy_channeltab_entry_rev2 *
 b43_nphy_get_chantabent_rev2(struct b43_wldev *dev, u8 channel);
+const struct b43_nphy_channeltab_entry_rev3 *
+b43_nphy_get_chantabent_rev3(struct b43_wldev *dev, u16 freq);
 
 
 /* The N-PHY tables. */
index 493163925a4588d1733b08a37ec30c5b045e2267..63edbe2e557f7544163597741ef44484f23a06bf 100644 (file)
@@ -12,7 +12,7 @@ obj-$(CONFIG_IWLAGN)  += iwlagn.o
 iwlagn-objs            := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o iwl-agn-ict.o
 iwlagn-objs            += iwl-agn-ucode.o iwl-agn-hcmd.o iwl-agn-tx.o
 iwlagn-objs            += iwl-agn-lib.o iwl-agn-rx.o iwl-agn-calib.o
-iwlagn-objs            += iwl-agn-tt.o
+iwlagn-objs            += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-eeprom.o
 iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-agn-debugfs.o
 
 iwlagn-$(CONFIG_IWL4965) += iwl-4965.o
index 134f54541330c8d58a117d7a43d0a6f9408ab642..db540910b1104d42b5d20d15e542c3fc5da7649c 100644 (file)
@@ -151,8 +151,7 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
        priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
        priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
 
-       if (priv->cfg->ops->lib->temp_ops.set_ct_kill)
-               priv->cfg->ops->lib->temp_ops.set_ct_kill(priv);
+       iwl1000_set_ct_threshold(priv);
 
        /* Set initial sensitivity parameters */
        /* Set initial calibration set */
@@ -195,9 +194,7 @@ static struct iwl_lib_ops iwl1000_lib = {
        .update_chain_flags = iwl_update_chain_flags,
        .apm_ops = {
                .init = iwl_apm_init,
-               .stop = iwl_apm_stop,
                .config = iwl1000_nic_config,
-               .set_pwr_src = iwl_set_pwr_src,
        },
        .eeprom_ops = {
                .regulatory_bands = {
@@ -209,7 +206,6 @@ static struct iwl_lib_ops iwl1000_lib = {
                        EEPROM_REG_BAND_24_HT40_CHANNELS,
                        EEPROM_REG_BAND_52_HT40_CHANNELS
                },
-               .verify_signature  = iwlcore_eeprom_verify_signature,
                .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
                .release_semaphore = iwlcore_eeprom_release_semaphore,
                .calib_version  = iwlagn_eeprom_calib_version,
@@ -220,7 +216,6 @@ static struct iwl_lib_ops iwl1000_lib = {
        .config_ap = iwl_config_ap,
        .temp_ops = {
                .temperature = iwlagn_temperature,
-               .set_ct_kill = iwl1000_set_ct_threshold,
         },
        .manage_ibss_station = iwlagn_manage_ibss_station,
        .update_bcast_stations = iwl_update_bcast_stations,
index cfdff5487e3c2d3e239de2f3199a33175011d774..176e525776734bbabbdcf3f0801b3720779688b6 100644 (file)
@@ -87,6 +87,15 @@ const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT_3945] = {
        IWL_DECLARE_RATE_INFO(54, 48, INV, 48, INV, 48, INV),/* 54mbps */
 };
 
+static inline u8 iwl3945_get_prev_ieee_rate(u8 rate_index)
+{
+       u8 rate = iwl3945_rates[rate_index].prev_ieee;
+
+       if (rate == IWL_RATE_INVALID)
+               rate = rate_index;
+       return rate;
+}
+
 /* 1 = enable the iwl3945_disable_events() function */
 #define IWL_EVT_DISABLE (0)
 #define IWL_EVT_DISABLE_SIZE (1532/32)
@@ -339,7 +348,7 @@ static void iwl3945_rx_reply_tx(struct iwl_priv *priv,
        IWL_DEBUG_TX_REPLY(priv, "Tx queue reclaim %d\n", index);
        iwl3945_tx_queue_reclaim(priv, txq_id, index);
 
-       if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
+       if (status & TX_ABORT_REQUIRED_MSK)
                IWL_ERR(priv, "TODO:  Implement Tx ABORT REQUIRED!!!\n");
 }
 
@@ -807,9 +816,12 @@ static u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate)
        return sta_id;
 }
 
-static int iwl3945_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
+static void iwl3945_set_pwr_vmain(struct iwl_priv *priv)
 {
-       if (src == IWL_PWR_SRC_VAUX) {
+/*
+ * (for documentation purposes)
+ * to set power to V_AUX, do
+
                if (pci_pme_capable(priv->pci_dev, PCI_D3cold)) {
                        iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
                                        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)
                                     CSR_GPIO_IN_VAL_VAUX_PWR_SRC,
                                     CSR_GPIO_IN_BIT_AUX_POWER, 5000);
                }
-       } else {
-               iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
-                               APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
-                               ~APMG_PS_CTRL_MSK_PWR_SRC);
+ */
 
-               iwl_poll_bit(priv, CSR_GPIO_IN, CSR_GPIO_IN_VAL_VMAIN_PWR_SRC,
-                            CSR_GPIO_IN_BIT_AUX_POWER, 5000);  /* uS */
-       }
+       iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
+                       APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
+                       ~APMG_PS_CTRL_MSK_PWR_SRC);
 
-       return 0;
+       iwl_poll_bit(priv, CSR_GPIO_IN, CSR_GPIO_IN_VAL_VMAIN_PWR_SRC,
+                    CSR_GPIO_IN_BIT_AUX_POWER, 5000);  /* uS */
 }
 
 static 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)
        priv->cfg->ops->lib->apm_ops.init(priv);
        spin_unlock_irqrestore(&priv->lock, flags);
 
-       rc = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN);
-       if (rc)
-               return rc;
+       iwl3945_set_pwr_vmain(priv);
 
        priv->cfg->ops->lib->apm_ops.config(priv);
 
@@ -1763,8 +1771,7 @@ static int iwl3945_send_rxon_assoc(struct iwl_priv *priv,
  * function correctly transitions out of the RXON_ASSOC_MSK state if
  * a HW tune is required based on the RXON structure changes.
  */
-static int iwl3945_commit_rxon(struct iwl_priv *priv,
-                              struct iwl_rxon_context *ctx)
+int iwl3945_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
 {
        /* cast away the const for active_rxon in this function */
        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)
        return (u16)sizeof(struct iwl3945_addsta_cmd);
 }
 
+static int iwl3945_add_bssid_station(struct iwl_priv *priv,
+                                    const u8 *addr, u8 *sta_id_r)
+{
+       struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
+       int ret;
+       u8 sta_id;
+       unsigned long flags;
+
+       if (sta_id_r)
+               *sta_id_r = IWL_INVALID_STATION;
+
+       ret = iwl_add_station_common(priv, ctx, addr, 0, NULL, &sta_id);
+       if (ret) {
+               IWL_ERR(priv, "Unable to add station %pM\n", addr);
+               return ret;
+       }
+
+       if (sta_id_r)
+               *sta_id_r = sta_id;
+
+       spin_lock_irqsave(&priv->sta_lock, flags);
+       priv->stations[sta_id].used |= IWL_STA_LOCAL;
+       spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+       return 0;
+}
 static int iwl3945_manage_ibss_station(struct iwl_priv *priv,
                                       struct ieee80211_vif *vif, bool add)
 {
@@ -2307,10 +2340,8 @@ static int iwl3945_manage_ibss_station(struct iwl_priv *priv,
        int ret;
 
        if (add) {
-               ret = iwl_add_bssid_station(
-                               priv, &priv->contexts[IWL_RXON_CTX_BSS],
-                               vif->bss_conf.bssid, false,
-                               &vif_priv->ibss_bssid_sta_id);
+               ret = iwl3945_add_bssid_station(priv, vif->bss_conf.bssid,
+                                               &vif_priv->ibss_bssid_sta_id);
                if (ret)
                        return ret;
 
@@ -2673,9 +2704,7 @@ static struct iwl_lib_ops iwl3945_lib = {
        .dump_nic_error_log = iwl3945_dump_nic_error_log,
        .apm_ops = {
                .init = iwl3945_apm_init,
-               .stop = iwl_apm_stop,
                .config = iwl3945_nic_config,
-               .set_pwr_src = iwl3945_set_pwr_src,
        },
        .eeprom_ops = {
                .regulatory_bands = {
@@ -2687,7 +2716,6 @@ static struct iwl_lib_ops iwl3945_lib = {
                        EEPROM_REGULATORY_BAND_NO_HT40,
                        EEPROM_REGULATORY_BAND_NO_HT40,
                },
-               .verify_signature  = iwlcore_eeprom_verify_signature,
                .acquire_semaphore = iwl3945_eeprom_acquire_semaphore,
                .release_semaphore = iwl3945_eeprom_release_semaphore,
                .query_addr = iwlcore_eeprom_query_addr,
@@ -2713,6 +2741,7 @@ static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
        .build_addsta_hcmd = iwl3945_build_addsta_hcmd,
        .tx_cmd_protection = iwlcore_tx_cmd_protection,
        .request_scan = iwl3945_request_scan,
+       .post_scan = iwl3945_post_scan,
 };
 
 static const struct iwl_ops iwl3945_ops = {
@@ -2724,6 +2753,7 @@ static const struct iwl_ops iwl3945_ops = {
 
 static struct iwl_base_params iwl3945_base_params = {
        .eeprom_size = IWL3945_EEPROM_IMG_SIZE,
+       .num_of_queues = IWL39_NUM_QUEUES,
        .pll_cfg_val = CSR39_ANA_PLL_CFG_VAL,
        .set_l0s = false,
        .use_bsm = true,
index 98509c5e708d20bf30b0ac27758e3b979822c1e3..09391f0ee61f03c9d486a75f5f3c195b04381e24 100644 (file)
@@ -138,8 +138,6 @@ enum iwl3945_antenna {
 #define        DEFAULT_SHORT_RETRY_LIMIT 7U
 #define        DEFAULT_LONG_RETRY_LIMIT  4U
 
-#include "iwl-agn-rs.h"
-
 #define IWL_TX_FIFO_AC0        0
 #define IWL_TX_FIFO_AC1        1
 #define IWL_TX_FIFO_AC2        2
@@ -271,6 +269,9 @@ extern void iwl3945_post_associate(struct iwl_priv *priv,
 extern void iwl3945_config_ap(struct iwl_priv *priv,
                              struct ieee80211_vif *vif);
 
+extern int iwl3945_commit_rxon(struct iwl_priv *priv,
+                              struct iwl_rxon_context *ctx);
+
 /**
  * iwl3945_hw_find_station - Find station id for a given BSSID
  * @bssid: MAC address of station ID to find
@@ -296,6 +297,10 @@ extern int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate);
 
 /* scanning */
 int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif);
+void iwl3945_post_scan(struct iwl_priv *priv);
+
+/* rates */
+extern const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT_3945];
 
 /* Requires full declaration of iwl_priv before including */
 #include "iwl-io.h"
index 834c2f9c15d748b61b85174a11fce20b7838ac48..b207e3e9299f11dd6b8d02edf7e4b148b07c98d4 100644 (file)
@@ -43,7 +43,7 @@
 #include "iwl-core.h"
 #include "iwl-io.h"
 #include "iwl-helpers.h"
-#include "iwl-calib.h"
+#include "iwl-agn-calib.h"
 #include "iwl-sta.h"
 #include "iwl-agn-led.h"
 #include "iwl-agn.h"
@@ -669,8 +669,8 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
        priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant);
        priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
        priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
-       if (priv->cfg->ops->lib->temp_ops.set_ct_kill)
-               priv->cfg->ops->lib->temp_ops.set_ct_kill(priv);
+
+       iwl4965_set_ct_threshold(priv);
 
        priv->hw_params.sens = &iwl4965_sensitivity;
        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)
 
 static struct iwl_hcmd_ops iwl4965_hcmd = {
        .rxon_assoc = iwl4965_send_rxon_assoc,
-       .commit_rxon = iwl_commit_rxon,
-       .set_rxon_chain = iwl_set_rxon_chain,
+       .commit_rxon = iwlagn_commit_rxon,
+       .set_rxon_chain = iwlagn_set_rxon_chain,
        .send_bt_config = iwl_send_bt_config,
 };
 
+static void iwl4965_post_scan(struct iwl_priv *priv)
+{
+       struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
+
+       /*
+        * Since setting the RXON may have been deferred while
+        * performing the scan, fire one off if needed
+        */
+       if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))
+               iwlcore_commit_rxon(priv, ctx);
+}
+
 static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
        .get_hcmd_size = iwl4965_get_hcmd_size,
        .build_addsta_hcmd = iwl4965_build_addsta_hcmd,
@@ -2229,6 +2241,7 @@ static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
        .tx_cmd_protection = iwlcore_tx_cmd_protection,
        .calc_rssi = iwl4965_calc_rssi,
        .request_scan = iwlagn_request_scan,
+       .post_scan = iwl4965_post_scan,
 };
 
 static struct iwl_lib_ops iwl4965_lib = {
@@ -2253,9 +2266,7 @@ static struct iwl_lib_ops iwl4965_lib = {
        .set_channel_switch = iwl4965_hw_channel_switch,
        .apm_ops = {
                .init = iwl_apm_init,
-               .stop = iwl_apm_stop,
                .config = iwl4965_nic_config,
-               .set_pwr_src = iwl_set_pwr_src,
        },
        .eeprom_ops = {
                .regulatory_bands = {
@@ -2267,7 +2278,6 @@ static struct iwl_lib_ops iwl4965_lib = {
                        EEPROM_4965_REGULATORY_BAND_24_HT40_CHANNELS,
                        EEPROM_4965_REGULATORY_BAND_52_HT40_CHANNELS
                },
-               .verify_signature  = iwlcore_eeprom_verify_signature,
                .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
                .release_semaphore = iwlcore_eeprom_release_semaphore,
                .calib_version = iwl4965_eeprom_calib_version,
@@ -2280,7 +2290,6 @@ static struct iwl_lib_ops iwl4965_lib = {
        .isr = iwl_isr_legacy,
        .temp_ops = {
                .temperature = iwl4965_temperature_calib,
-               .set_ct_kill = iwl4965_set_ct_threshold,
        },
        .manage_ibss_station = iwlagn_manage_ibss_station,
        .update_bcast_stations = iwl_update_bcast_stations,
index 1b25ad63b5c1adb7a1f52589a8a54199954db7ef..fd9fbc93ea1b21d20b9d494f7f7a6a04422e679b 100644 (file)
@@ -195,8 +195,7 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
        priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
        priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
 
-       if (priv->cfg->ops->lib->temp_ops.set_ct_kill)
-               priv->cfg->ops->lib->temp_ops.set_ct_kill(priv);
+       iwl5000_set_ct_threshold(priv);
 
        /* Set initial sensitivity parameters */
        /* Set initial calibration set */
@@ -242,8 +241,7 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv)
        priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
        priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
 
-       if (priv->cfg->ops->lib->temp_ops.set_ct_kill)
-               priv->cfg->ops->lib->temp_ops.set_ct_kill(priv);
+       iwl5150_set_ct_threshold(priv);
 
        /* Set initial sensitivity parameters */
        /* Set initial calibration set */
@@ -370,9 +368,7 @@ static struct iwl_lib_ops iwl5000_lib = {
        .set_channel_switch = iwl5000_hw_channel_switch,
        .apm_ops = {
                .init = iwl_apm_init,
-               .stop = iwl_apm_stop,
                .config = iwl5000_nic_config,
-               .set_pwr_src = iwl_set_pwr_src,
        },
        .eeprom_ops = {
                .regulatory_bands = {
@@ -384,7 +380,6 @@ static struct iwl_lib_ops iwl5000_lib = {
                        EEPROM_REG_BAND_24_HT40_CHANNELS,
                        EEPROM_REG_BAND_52_HT40_CHANNELS
                },
-               .verify_signature  = iwlcore_eeprom_verify_signature,
                .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
                .release_semaphore = iwlcore_eeprom_release_semaphore,
                .calib_version  = iwlagn_eeprom_calib_version,
@@ -395,7 +390,6 @@ static struct iwl_lib_ops iwl5000_lib = {
        .config_ap = iwl_config_ap,
        .temp_ops = {
                .temperature = iwlagn_temperature,
-               .set_ct_kill = iwl5000_set_ct_threshold,
         },
        .manage_ibss_station = iwlagn_manage_ibss_station,
        .update_bcast_stations = iwl_update_bcast_stations,
@@ -442,9 +436,7 @@ static struct iwl_lib_ops iwl5150_lib = {
        .set_channel_switch = iwl5000_hw_channel_switch,
        .apm_ops = {
                .init = iwl_apm_init,
-               .stop = iwl_apm_stop,
                .config = iwl5000_nic_config,
-               .set_pwr_src = iwl_set_pwr_src,
        },
        .eeprom_ops = {
                .regulatory_bands = {
@@ -456,7 +448,6 @@ static struct iwl_lib_ops iwl5150_lib = {
                        EEPROM_REG_BAND_24_HT40_CHANNELS,
                        EEPROM_REG_BAND_52_HT40_CHANNELS
                },
-               .verify_signature  = iwlcore_eeprom_verify_signature,
                .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
                .release_semaphore = iwlcore_eeprom_release_semaphore,
                .calib_version  = iwlagn_eeprom_calib_version,
@@ -467,7 +458,6 @@ static struct iwl_lib_ops iwl5150_lib = {
        .config_ap = iwl_config_ap,
        .temp_ops = {
                .temperature = iwl5150_temperature,
-               .set_ct_kill = iwl5150_set_ct_threshold,
         },
        .manage_ibss_station = iwlagn_manage_ibss_station,
        .update_bcast_stations = iwl_update_bcast_stations,
index 6261aec5ebdc143eb8510ad484bb757e53b4ea44..11e6532fc573d1ed93d5ec4aaf886342d0fe8073 100644 (file)
@@ -192,8 +192,7 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
        priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
        priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
 
-       if (priv->cfg->ops->lib->temp_ops.set_ct_kill)
-               priv->cfg->ops->lib->temp_ops.set_ct_kill(priv);
+       iwl6000_set_ct_threshold(priv);
 
        /* Set initial sensitivity parameters */
        /* Set initial calibration set */
@@ -205,6 +204,8 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
                BIT(IWL_CALIB_BASE_BAND);
        if (priv->cfg->need_dc_calib)
                priv->hw_params.calib_rt_cfg |= BIT(IWL_CALIB_CFG_DC_IDX);
+       if (priv->cfg->need_temp_offset_calib)
+               priv->hw_params.calib_init_cfg |= BIT(IWL_CALIB_TEMP_OFFSET);
 
        priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS;
 
@@ -309,9 +310,7 @@ static struct iwl_lib_ops iwl6000_lib = {
        .set_channel_switch = iwl6000_hw_channel_switch,
        .apm_ops = {
                .init = iwl_apm_init,
-               .stop = iwl_apm_stop,
                .config = iwl6000_nic_config,
-               .set_pwr_src = iwl_set_pwr_src,
        },
        .eeprom_ops = {
                .regulatory_bands = {
@@ -323,7 +322,6 @@ static struct iwl_lib_ops iwl6000_lib = {
                        EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
                        EEPROM_REG_BAND_52_HT40_CHANNELS
                },
-               .verify_signature  = iwlcore_eeprom_verify_signature,
                .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
                .release_semaphore = iwlcore_eeprom_release_semaphore,
                .calib_version  = iwlagn_eeprom_calib_version,
@@ -335,7 +333,6 @@ static struct iwl_lib_ops iwl6000_lib = {
        .config_ap = iwl_config_ap,
        .temp_ops = {
                .temperature = iwlagn_temperature,
-               .set_ct_kill = iwl6000_set_ct_threshold,
         },
        .manage_ibss_station = iwlagn_manage_ibss_station,
        .update_bcast_stations = iwl_update_bcast_stations,
@@ -384,9 +381,7 @@ static struct iwl_lib_ops iwl6000g2b_lib = {
        .set_channel_switch = iwl6000_hw_channel_switch,
        .apm_ops = {
                .init = iwl_apm_init,
-               .stop = iwl_apm_stop,
                .config = iwl6000_nic_config,
-               .set_pwr_src = iwl_set_pwr_src,
        },
        .eeprom_ops = {
                .regulatory_bands = {
@@ -398,7 +393,6 @@ static struct iwl_lib_ops iwl6000g2b_lib = {
                        EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
                        EEPROM_REG_BAND_52_HT40_CHANNELS
                },
-               .verify_signature  = iwlcore_eeprom_verify_signature,
                .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
                .release_semaphore = iwlcore_eeprom_release_semaphore,
                .calib_version  = iwlagn_eeprom_calib_version,
@@ -410,7 +404,6 @@ static struct iwl_lib_ops iwl6000g2b_lib = {
        .config_ap = iwl_config_ap,
        .temp_ops = {
                .temperature = iwlagn_temperature,
-               .set_ct_kill = iwl6000_set_ct_threshold,
         },
        .manage_ibss_station = iwlagn_manage_ibss_station,
        .update_bcast_stations = iwl_update_bcast_stations,
@@ -516,6 +509,28 @@ static struct iwl_base_params iwl6050_base_params = {
        .sensitivity_calib_by_driver = true,
        .chain_noise_calib_by_driver = true,
 };
+static struct iwl_base_params iwl6000_coex_base_params = {
+       .eeprom_size = OTP_LOW_IMAGE_SIZE,
+       .num_of_queues = IWLAGN_NUM_QUEUES,
+       .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
+       .pll_cfg_val = 0,
+       .set_l0s = true,
+       .use_bsm = false,
+       .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
+       .shadow_ram_support = true,
+       .led_compensation = 51,
+       .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
+       .supports_idle = true,
+       .adv_thermal_throttle = true,
+       .support_ct_kill_exit = true,
+       .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
+       .chain_noise_scale = 1000,
+       .monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
+       .max_event_log_size = 512,
+       .ucode_tracing = true,
+       .sensitivity_calib_by_driver = true,
+       .chain_noise_calib_by_driver = true,
+};
 
 static struct iwl_ht_params iwl6000_ht_params = {
        .ht_greenfield_support = true,
@@ -545,6 +560,7 @@ struct iwl_cfg iwl6000g2a_2agn_cfg = {
        .base_params = &iwl6000_base_params,
        .ht_params = &iwl6000_ht_params,
        .need_dc_calib = true,
+       .need_temp_offset_calib = true,
 };
 
 struct iwl_cfg iwl6000g2a_2abg_cfg = {
@@ -561,6 +577,7 @@ struct iwl_cfg iwl6000g2a_2abg_cfg = {
        .mod_params = &iwlagn_mod_params,
        .base_params = &iwl6000_base_params,
        .need_dc_calib = true,
+       .need_temp_offset_calib = true,
 };
 
 struct iwl_cfg iwl6000g2a_2bg_cfg = {
@@ -577,6 +594,7 @@ struct iwl_cfg iwl6000g2a_2bg_cfg = {
        .mod_params = &iwlagn_mod_params,
        .base_params = &iwl6000_base_params,
        .need_dc_calib = true,
+       .need_temp_offset_calib = true,
 };
 
 struct iwl_cfg iwl6000g2b_2agn_cfg = {
@@ -591,10 +609,11 @@ struct iwl_cfg iwl6000g2b_2agn_cfg = {
        .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
        .ops = &iwl6000g2b_ops,
        .mod_params = &iwlagn_mod_params,
-       .base_params = &iwl6000_base_params,
+       .base_params = &iwl6000_coex_base_params,
        .bt_params = &iwl6000_bt_params,
        .ht_params = &iwl6000_ht_params,
        .need_dc_calib = true,
+       .need_temp_offset_calib = true,
        /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
        .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
 };
@@ -611,9 +630,10 @@ struct iwl_cfg iwl6000g2b_2abg_cfg = {
        .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
        .ops = &iwl6000g2b_ops,
        .mod_params = &iwlagn_mod_params,
-       .base_params = &iwl6000_base_params,
+       .base_params = &iwl6000_coex_base_params,
        .bt_params = &iwl6000_bt_params,
        .need_dc_calib = true,
+       .need_temp_offset_calib = true,
        /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
        .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
 };
@@ -630,10 +650,11 @@ struct iwl_cfg iwl6000g2b_2bgn_cfg = {
        .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
        .ops = &iwl6000g2b_ops,
        .mod_params = &iwlagn_mod_params,
-       .base_params = &iwl6000_base_params,
+       .base_params = &iwl6000_coex_base_params,
        .bt_params = &iwl6000_bt_params,
        .ht_params = &iwl6000_ht_params,
        .need_dc_calib = true,
+       .need_temp_offset_calib = true,
        /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
        .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
 };
@@ -650,9 +671,10 @@ struct iwl_cfg iwl6000g2b_2bg_cfg = {
        .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
        .ops = &iwl6000g2b_ops,
        .mod_params = &iwlagn_mod_params,
-       .base_params = &iwl6000_base_params,
+       .base_params = &iwl6000_coex_base_params,
        .bt_params = &iwl6000_bt_params,
        .need_dc_calib = true,
+       .need_temp_offset_calib = true,
        /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
        .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
 };
@@ -669,10 +691,11 @@ struct iwl_cfg iwl6000g2b_bgn_cfg = {
        .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
        .ops = &iwl6000g2b_ops,
        .mod_params = &iwlagn_mod_params,
-       .base_params = &iwl6000_base_params,
+       .base_params = &iwl6000_coex_base_params,
        .bt_params = &iwl6000_bt_params,
        .ht_params = &iwl6000_ht_params,
        .need_dc_calib = true,
+       .need_temp_offset_calib = true,
        /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
        .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
 };
@@ -689,9 +712,10 @@ struct iwl_cfg iwl6000g2b_bg_cfg = {
        .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
        .ops = &iwl6000g2b_ops,
        .mod_params = &iwlagn_mod_params,
-       .base_params = &iwl6000_base_params,
+       .base_params = &iwl6000_coex_base_params,
        .bt_params = &iwl6000_bt_params,
        .need_dc_calib = true,
+       .need_temp_offset_calib = true,
        /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
        .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
 };
@@ -756,7 +780,7 @@ struct iwl_cfg iwl6050_2agn_cfg = {
        .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
        .valid_tx_ant = ANT_AB,
        .valid_rx_ant = ANT_AB,
-       .ops = &iwl6000_ops,
+       .ops = &iwl6050_ops,
        .eeprom_ver = EEPROM_6050_EEPROM_VERSION,
        .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION,
        .mod_params = &iwlagn_mod_params,
@@ -827,7 +851,7 @@ struct iwl_cfg iwl130_bgn_cfg = {
        .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
        .ops = &iwl6000g2b_ops,
        .mod_params = &iwlagn_mod_params,
-       .base_params = &iwl6000_base_params,
+       .base_params = &iwl6000_coex_base_params,
        .bt_params = &iwl6000_bt_params,
        .ht_params = &iwl6000_ht_params,
        .need_dc_calib = true,
@@ -847,7 +871,7 @@ struct iwl_cfg iwl130_bg_cfg = {
        .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
        .ops = &iwl6000g2b_ops,
        .mod_params = &iwlagn_mod_params,
-       .base_params = &iwl6000_base_params,
+       .base_params = &iwl6000_coex_base_params,
        .bt_params = &iwl6000_bt_params,
        .need_dc_calib = true,
        /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
index 4c5ab783737f8623cb239da1e1c3f37a7680ca4c..e2019e756936e2280fa8f1365fe31ca0bb295a51 100644 (file)
@@ -65,7 +65,7 @@
 
 #include "iwl-dev.h"
 #include "iwl-core.h"
-#include "iwl-calib.h"
+#include "iwl-agn-calib.h"
 
 /*****************************************************************************
  * INIT calibrations framework
similarity index 95%
rename from drivers/net/wireless/iwlwifi/iwl-calib.h
rename to drivers/net/wireless/iwlwifi/iwl-agn-calib.h
index ba9523fbb300dcc6974f0a526c4ebe91877b37c9..e37ae72616308f785cf87e8a37d02c3001d83d44 100644 (file)
@@ -79,4 +79,8 @@ static inline void iwl_chain_noise_reset(struct iwl_priv *priv)
                priv->cfg->ops->utils->chain_noise_reset(priv);
 }
 
+int iwl_send_calib_results(struct iwl_priv *priv);
+int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len);
+void iwl_calib_free_results(struct iwl_priv *priv);
+
 #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 (file)
index 0000000..a650bab
--- /dev/null
@@ -0,0 +1,454 @@
+/******************************************************************************
+ *
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ *  Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Intel Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+
+#include <net/mac80211.h>
+
+#include "iwl-commands.h"
+#include "iwl-dev.h"
+#include "iwl-core.h"
+#include "iwl-debug.h"
+#include "iwl-agn.h"
+#include "iwl-io.h"
+
+/************************** EEPROM BANDS ****************************
+ *
+ * The iwl_eeprom_band definitions below provide the mapping from the
+ * EEPROM contents to the specific channel number supported for each
+ * band.
+ *
+ * For example, iwl_priv->eeprom.band_3_channels[4] from the band_3
+ * definition below maps to physical channel 42 in the 5.2GHz spectrum.
+ * The specific geography and calibration information for that channel
+ * is contained in the eeprom map itself.
+ *
+ * During init, we copy the eeprom information and channel map
+ * information into priv->channel_info_24/52 and priv->channel_map_24/52
+ *
+ * channel_map_24/52 provides the index in the channel_info array for a
+ * given channel.  We have to have two separate maps as there is channel
+ * overlap with the 2.4GHz and 5.2GHz spectrum as seen in band_1 and
+ * band_2
+ *
+ * A value of 0xff stored in the channel_map indicates that the channel
+ * is not supported by the hardware at all.
+ *
+ * A value of 0xfe in the channel_map indicates that the channel is not
+ * valid for Tx with the current hardware.  This means that
+ * while the system can tune and receive on a given channel, it may not
+ * be able to associate or transmit any frames on that
+ * channel.  There is no corresponding channel information for that
+ * entry.
+ *
+ *********************************************************************/
+
+/**
+ * struct iwl_txpwr_section: eeprom section information
+ * @offset: indirect address into eeprom image
+ * @count: number of "struct iwl_eeprom_enhanced_txpwr" in this section
+ * @band: band type for the section
+ * @is_common - true: common section, false: channel section
+ * @is_cck - true: cck section, false: not cck section
+ * @is_ht_40 - true: all channel in the section are HT40 channel,
+ *            false: legacy or HT 20 MHz
+ *            ignore if it is common section
+ * @iwl_eeprom_section_channel: channel array in the section,
+ *            ignore if common section
+ */
+struct iwl_txpwr_section {
+       u32 offset;
+       u8 count;
+       enum ieee80211_band band;
+       bool is_common;
+       bool is_cck;
+       bool is_ht40;
+       u8 iwl_eeprom_section_channel[EEPROM_MAX_TXPOWER_SECTION_ELEMENTS];
+};
+
+/**
+ * section 1 - 3 are regulatory tx power apply to all channels based on
+ *    modulation: CCK, OFDM
+ *    Band: 2.4GHz, 5.2GHz
+ * section 4 - 10 are regulatory tx power apply to specified channels
+ *    For example:
+ *     1L - Channel 1 Legacy
+ *     1HT - Channel 1 HT
+ *     (1,+1) - Channel 1 HT40 "_above_"
+ *
+ * Section 1: all CCK channels
+ * Section 2: all 2.4 GHz OFDM (Legacy, HT and HT40) channels
+ * Section 3: all 5.2 GHz OFDM (Legacy, HT and HT40) channels
+ * Section 4: 2.4 GHz 20MHz channels: 1L, 1HT, 2L, 2HT, 10L, 10HT, 11L, 11HT
+ * Section 5: 2.4 GHz 40MHz channels: (1,+1) (2,+1) (6,+1) (7,+1) (9,+1)
+ * Section 6: 5.2 GHz 20MHz channels: 36L, 64L, 100L, 36HT, 64HT, 100HT
+ * Section 7: 5.2 GHz 40MHz channels: (36,+1) (60,+1) (100,+1)
+ * Section 8: 2.4 GHz channel: 13L, 13HT
+ * Section 9: 2.4 GHz channel: 140L, 140HT
+ * Section 10: 2.4 GHz 40MHz channels: (132,+1)  (44,+1)
+ *
+ */
+static const struct iwl_txpwr_section enhinfo[] = {
+       { EEPROM_LB_CCK_20_COMMON, 1, IEEE80211_BAND_2GHZ, true, true, false },
+       { EEPROM_LB_OFDM_COMMON, 3, IEEE80211_BAND_2GHZ, true, false, false },
+       { EEPROM_HB_OFDM_COMMON, 3, IEEE80211_BAND_5GHZ, true, false, false },
+       { EEPROM_LB_OFDM_20_BAND, 8, IEEE80211_BAND_2GHZ,
+               false, false, false,
+               {1, 1, 2, 2, 10, 10, 11, 11 } },
+       { EEPROM_LB_OFDM_HT40_BAND, 5, IEEE80211_BAND_2GHZ,
+               false, false, true,
+               { 1, 2, 6, 7, 9 } },
+       { EEPROM_HB_OFDM_20_BAND, 6, IEEE80211_BAND_5GHZ,
+               false, false, false,
+               { 36, 64, 100, 36, 64, 100 } },
+       { EEPROM_HB_OFDM_HT40_BAND, 3, IEEE80211_BAND_5GHZ,
+               false, false, true,
+               { 36, 60, 100 } },
+       { EEPROM_LB_OFDM_20_CHANNEL_13, 2, IEEE80211_BAND_2GHZ,
+               false, false, false,
+               { 13, 13 } },
+       { EEPROM_HB_OFDM_20_CHANNEL_140, 2, IEEE80211_BAND_5GHZ,
+               false, false, false,
+               { 140, 140 } },
+       { EEPROM_HB_OFDM_HT40_BAND_1, 2, IEEE80211_BAND_5GHZ,
+               false, false, true,
+               { 132, 44 } },
+};
+
+/******************************************************************************
+ *
+ * EEPROM related functions
+ *
+******************************************************************************/
+
+/*
+ * The device's EEPROM semaphore prevents conflicts between driver and uCode
+ * when accessing the EEPROM; each access is a series of pulses to/from the
+ * EEPROM chip, not a single event, so even reads could conflict if they
+ * weren't arbitrated by the semaphore.
+ */
+int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv)
+{
+       u16 count;
+       int ret;
+
+       for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) {
+               /* Request semaphore */
+               iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+                           CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
+
+               /* See if we got it */
+               ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG,
+                               CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
+                               CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
+                               EEPROM_SEM_TIMEOUT);
+               if (ret >= 0) {
+                       IWL_DEBUG_IO(priv,
+                               "Acquired semaphore after %d tries.\n",
+                               count+1);
+                       return ret;
+               }
+       }
+
+       return ret;
+}
+
+void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv)
+{
+       iwl_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
+               CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
+
+}
+
+int iwl_eeprom_check_version(struct iwl_priv *priv)
+{
+       u16 eeprom_ver;
+       u16 calib_ver;
+
+       eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
+       calib_ver = priv->cfg->ops->lib->eeprom_ops.calib_version(priv);
+
+       if (eeprom_ver < priv->cfg->eeprom_ver ||
+           calib_ver < priv->cfg->eeprom_calib_ver)
+               goto err;
+
+       IWL_INFO(priv, "device EEPROM VER=0x%x, CALIB=0x%x\n",
+                eeprom_ver, calib_ver);
+
+       return 0;
+err:
+       IWL_ERR(priv, "Unsupported (too old) EEPROM VER=0x%x < 0x%x "
+                 "CALIB=0x%x < 0x%x\n",
+                 eeprom_ver, priv->cfg->eeprom_ver,
+                 calib_ver,  priv->cfg->eeprom_calib_ver);
+       return -EINVAL;
+
+}
+
+void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac)
+{
+       const u8 *addr = priv->cfg->ops->lib->eeprom_ops.query_addr(priv,
+                                       EEPROM_MAC_ADDRESS);
+       memcpy(mac, addr, ETH_ALEN);
+}
+
+/**
+ * iwl_get_max_txpower_avg - get the highest tx power from all chains.
+ *     find the highest tx power from all chains for the channel
+ */
+static s8 iwl_get_max_txpower_avg(struct iwl_priv *priv,
+               struct iwl_eeprom_enhanced_txpwr *enhanced_txpower,
+               int element, s8 *max_txpower_in_half_dbm)
+{
+       s8 max_txpower_avg = 0; /* (dBm) */
+
+       IWL_DEBUG_INFO(priv, "%d - "
+                       "chain_a: %d dB chain_b: %d dB "
+                       "chain_c: %d dB mimo2: %d dB mimo3: %d dB\n",
+                       element,
+                       enhanced_txpower[element].chain_a_max >> 1,
+                       enhanced_txpower[element].chain_b_max >> 1,
+                       enhanced_txpower[element].chain_c_max >> 1,
+                       enhanced_txpower[element].mimo2_max >> 1,
+                       enhanced_txpower[element].mimo3_max >> 1);
+       /* Take the highest tx power from any valid chains */
+       if ((priv->cfg->valid_tx_ant & ANT_A) &&
+           (enhanced_txpower[element].chain_a_max > max_txpower_avg))
+               max_txpower_avg = enhanced_txpower[element].chain_a_max;
+       if ((priv->cfg->valid_tx_ant & ANT_B) &&
+           (enhanced_txpower[element].chain_b_max > max_txpower_avg))
+               max_txpower_avg = enhanced_txpower[element].chain_b_max;
+       if ((priv->cfg->valid_tx_ant & ANT_C) &&
+           (enhanced_txpower[element].chain_c_max > max_txpower_avg))
+               max_txpower_avg = enhanced_txpower[element].chain_c_max;
+       if (((priv->cfg->valid_tx_ant == ANT_AB) |
+           (priv->cfg->valid_tx_ant == ANT_BC) |
+           (priv->cfg->valid_tx_ant == ANT_AC)) &&
+           (enhanced_txpower[element].mimo2_max > max_txpower_avg))
+               max_txpower_avg =  enhanced_txpower[element].mimo2_max;
+       if ((priv->cfg->valid_tx_ant == ANT_ABC) &&
+           (enhanced_txpower[element].mimo3_max > max_txpower_avg))
+               max_txpower_avg = enhanced_txpower[element].mimo3_max;
+
+       /*
+        * max. tx power in EEPROM is in 1/2 dBm format
+        * convert from 1/2 dBm to dBm (round-up convert)
+        * but we also do not want to loss 1/2 dBm resolution which
+        * will impact performance
+        */
+       *max_txpower_in_half_dbm = max_txpower_avg;
+       return (max_txpower_avg & 0x01) + (max_txpower_avg >> 1);
+}
+
+/**
+ * iwl_update_common_txpower: update channel tx power
+ *     update tx power per band based on EEPROM enhanced tx power info.
+ */
+static s8 iwl_update_common_txpower(struct iwl_priv *priv,
+               struct iwl_eeprom_enhanced_txpwr *enhanced_txpower,
+               int section, int element, s8 *max_txpower_in_half_dbm)
+{
+       struct iwl_channel_info *ch_info;
+       int ch;
+       bool is_ht40 = false;
+       s8 max_txpower_avg; /* (dBm) */
+
+       /* it is common section, contain all type (Legacy, HT and HT40)
+        * based on the element in the section to determine
+        * is it HT 40 or not
+        */
+       if (element == EEPROM_TXPOWER_COMMON_HT40_INDEX)
+               is_ht40 = true;
+       max_txpower_avg =
+               iwl_get_max_txpower_avg(priv, enhanced_txpower,
+                                       element, max_txpower_in_half_dbm);
+
+       ch_info = priv->channel_info;
+
+       for (ch = 0; ch < priv->channel_count; ch++) {
+               /* find matching band and update tx power if needed */
+               if ((ch_info->band == enhinfo[section].band) &&
+                   (ch_info->max_power_avg < max_txpower_avg) &&
+                   (!is_ht40)) {
+                       /* Update regulatory-based run-time data */
+                       ch_info->max_power_avg = ch_info->curr_txpow =
+                               max_txpower_avg;
+                       ch_info->scan_power = max_txpower_avg;
+               }
+               if ((ch_info->band == enhinfo[section].band) && is_ht40 &&
+                   (ch_info->ht40_max_power_avg < max_txpower_avg)) {
+                       /* Update regulatory-based run-time data */
+                       ch_info->ht40_max_power_avg = max_txpower_avg;
+               }
+               ch_info++;
+       }
+       return max_txpower_avg;
+}
+
+/**
+ * iwl_update_channel_txpower: update channel tx power
+ *      update channel tx power based on EEPROM enhanced tx power info.
+ */
+static s8 iwl_update_channel_txpower(struct iwl_priv *priv,
+               struct iwl_eeprom_enhanced_txpwr *enhanced_txpower,
+               int section, int element, s8 *max_txpower_in_half_dbm)
+{
+       struct iwl_channel_info *ch_info;
+       int ch;
+       u8 channel;
+       s8 max_txpower_avg; /* (dBm) */
+
+       channel = enhinfo[section].iwl_eeprom_section_channel[element];
+       max_txpower_avg =
+               iwl_get_max_txpower_avg(priv, enhanced_txpower,
+                                       element, max_txpower_in_half_dbm);
+
+       ch_info = priv->channel_info;
+       for (ch = 0; ch < priv->channel_count; ch++) {
+               /* find matching channel and update tx power if needed */
+               if (ch_info->channel == channel) {
+                       if ((ch_info->max_power_avg < max_txpower_avg) &&
+                           (!enhinfo[section].is_ht40)) {
+                               /* Update regulatory-based run-time data */
+                               ch_info->max_power_avg = max_txpower_avg;
+                               ch_info->curr_txpow = max_txpower_avg;
+                               ch_info->scan_power = max_txpower_avg;
+                       }
+                       if ((enhinfo[section].is_ht40) &&
+                           (ch_info->ht40_max_power_avg < max_txpower_avg)) {
+                               /* Update regulatory-based run-time data */
+                               ch_info->ht40_max_power_avg = max_txpower_avg;
+                       }
+                       break;
+               }
+               ch_info++;
+       }
+       return max_txpower_avg;
+}
+
+/**
+ * iwlcore_eeprom_enhanced_txpower: process enhanced tx power info
+ */
+void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv)
+{
+       int eeprom_section_count = 0;
+       int section, element;
+       struct iwl_eeprom_enhanced_txpwr *enhanced_txpower;
+       u32 offset;
+       s8 max_txpower_avg; /* (dBm) */
+       s8 max_txpower_in_half_dbm; /* (half-dBm) */
+
+       /* Loop through all the sections
+        * adjust bands and channel's max tx power
+        * Set the tx_power_user_lmt to the highest power
+        * supported by any channels and chains
+        */
+       for (section = 0; section < ARRAY_SIZE(enhinfo); section++) {
+               eeprom_section_count = enhinfo[section].count;
+               offset = enhinfo[section].offset;
+               enhanced_txpower = (struct iwl_eeprom_enhanced_txpwr *)
+                               iwl_eeprom_query_addr(priv, offset);
+
+               /*
+                * check for valid entry -
+                * different version of EEPROM might contain different set
+                * of enhanced tx power table
+                * always check for valid entry before process
+                * the information
+                */
+               if (!enhanced_txpower->common || enhanced_txpower->reserved)
+                       continue;
+
+               for (element = 0; element < eeprom_section_count; element++) {
+                       if (enhinfo[section].is_common)
+                               max_txpower_avg =
+                                       iwl_update_common_txpower(priv,
+                                               enhanced_txpower, section,
+                                               element,
+                                               &max_txpower_in_half_dbm);
+                       else
+                               max_txpower_avg =
+                                       iwl_update_channel_txpower(priv,
+                                               enhanced_txpower, section,
+                                               element,
+                                               &max_txpower_in_half_dbm);
+
+                       /* Update the tx_power_user_lmt to the highest power
+                        * supported by any channel */
+                       if (max_txpower_avg > priv->tx_power_user_lmt)
+                               priv->tx_power_user_lmt = max_txpower_avg;
+
+                       /*
+                        * Update the tx_power_lmt_in_half_dbm to
+                        * the highest power supported by any channel
+                        */
+                       if (max_txpower_in_half_dbm >
+                           priv->tx_power_lmt_in_half_dbm)
+                               priv->tx_power_lmt_in_half_dbm =
+                                       max_txpower_in_half_dbm;
+               }
+       }
+}
index 9ca6c91eaae61384a9bc9edb0ea46dc03f0c7b4e..ffb2f4111ad0bbbec4db0b19c7edd74425a8d476 100644 (file)
@@ -360,8 +360,8 @@ static int iwlagn_set_pan_params(struct iwl_priv *priv)
 
 struct iwl_hcmd_ops iwlagn_hcmd = {
        .rxon_assoc = iwlagn_send_rxon_assoc,
-       .commit_rxon = iwl_commit_rxon,
-       .set_rxon_chain = iwl_set_rxon_chain,
+       .commit_rxon = iwlagn_commit_rxon,
+       .set_rxon_chain = iwlagn_set_rxon_chain,
        .set_tx_ant = iwlagn_send_tx_ant_config,
        .send_bt_config = iwl_send_bt_config,
        .set_pan_params = iwlagn_set_pan_params,
@@ -369,8 +369,8 @@ struct iwl_hcmd_ops iwlagn_hcmd = {
 
 struct iwl_hcmd_ops iwlagn_bt_hcmd = {
        .rxon_assoc = iwlagn_send_rxon_assoc,
-       .commit_rxon = iwl_commit_rxon,
-       .set_rxon_chain = iwl_set_rxon_chain,
+       .commit_rxon = iwlagn_commit_rxon,
+       .set_rxon_chain = iwlagn_set_rxon_chain,
        .set_tx_ant = iwlagn_send_tx_ant_config,
        .send_bt_config = iwlagn_send_advance_bt_config,
        .set_pan_params = iwlagn_set_pan_params,
@@ -384,4 +384,5 @@ struct iwl_hcmd_utils_ops iwlagn_hcmd_utils = {
        .tx_cmd_protection = iwlagn_tx_cmd_protection,
        .calc_rssi = iwlagn_calc_rssi,
        .request_scan = iwlagn_request_scan,
+       .post_scan = iwlagn_post_scan,
 };
index f5445d575fec64f785f0506ee15675e77dce877d..b555edd533547e3bf98eed8e948a276ef141aace 100644 (file)
@@ -685,6 +685,23 @@ int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
        return 0;
 }
 
+static void iwlagn_set_pwr_vmain(struct iwl_priv *priv)
+{
+/*
+ * (for documentation purposes)
+ * to set power to V_AUX, do:
+
+               if (pci_pme_capable(priv->pci_dev, PCI_D3cold))
+                       iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
+                                              APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
+                                              ~APMG_PS_CTRL_MSK_PWR_SRC);
+ */
+
+       iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
+                              APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
+                              ~APMG_PS_CTRL_MSK_PWR_SRC);
+}
+
 int iwlagn_hw_nic_init(struct iwl_priv *priv)
 {
        unsigned long flags;
@@ -700,7 +717,7 @@ int iwlagn_hw_nic_init(struct iwl_priv *priv)
 
        spin_unlock_irqrestore(&priv->lock, flags);
 
-       ret = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN);
+       iwlagn_set_pwr_vmain(priv);
 
        priv->cfg->ops->lib->apm_ops.config(priv);
 
@@ -1430,35 +1447,35 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
                if (priv->cfg->bt_params &&
                    priv->cfg->bt_params->advanced_bt_coexist)
                        scan->tx_cmd.tx_flags |= TX_CMD_FLG_IGNORE_BT;
-               scan->good_CRC_th = IWL_GOOD_CRC_TH_DISABLED;
                break;
        case IEEE80211_BAND_5GHZ:
                rate = IWL_RATE_6M_PLCP;
-               /*
-                * If active scanning is requested but a certain channel is
-                * marked passive, we can do active scanning if we detect
-                * transmissions.
-                *
-                * There is an issue with some firmware versions that triggers
-                * a sysassert on a "good CRC threshold" of zero (== disabled),
-                * on a radar channel even though this means that we should NOT
-                * send probes.
-                *
-                * The "good CRC threshold" is the number of frames that we
-                * need to receive during our dwell time on a channel before
-                * sending out probes -- setting this to a huge value will
-                * mean we never reach it, but at the same time work around
-                * the aforementioned issue. Thus use IWL_GOOD_CRC_TH_NEVER
-                * here instead of IWL_GOOD_CRC_TH_DISABLED.
-                */
-               scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
-                                               IWL_GOOD_CRC_TH_NEVER;
                break;
        default:
                IWL_WARN(priv, "Invalid scan band\n");
                return -EIO;
        }
 
+       /*
+        * If active scanning is requested but a certain channel is
+        * marked passive, we can do active scanning if we detect
+        * transmissions.
+        *
+        * There is an issue with some firmware versions that triggers
+        * a sysassert on a "good CRC threshold" of zero (== disabled),
+        * on a radar channel even though this means that we should NOT
+        * send probes.
+        *
+        * The "good CRC threshold" is the number of frames that we
+        * need to receive during our dwell time on a channel before
+        * sending out probes -- setting this to a huge value will
+        * mean we never reach it, but at the same time work around
+        * the aforementioned issue. Thus use IWL_GOOD_CRC_TH_NEVER
+        * here instead of IWL_GOOD_CRC_TH_DISABLED.
+        */
+       scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
+                                       IWL_GOOD_CRC_TH_NEVER;
+
        band = priv->scan_band;
 
        if (priv->cfg->scan_rx_antennas[band])
@@ -1548,13 +1565,15 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
        cmd.data = scan;
        scan->len = cpu_to_le16(cmd.len);
 
+       /* set scan bit here for PAN params */
+       set_bit(STATUS_SCAN_HW, &priv->status);
+
        if (priv->cfg->ops->hcmd->set_pan_params) {
                ret = priv->cfg->ops->hcmd->set_pan_params(priv);
                if (ret)
                        return ret;
        }
 
-       set_bit(STATUS_SCAN_HW, &priv->status);
        ret = iwl_send_cmd_sync(priv, &cmd);
        if (ret) {
                clear_bit(STATUS_SCAN_HW, &priv->status);
@@ -1565,15 +1584,31 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
        return ret;
 }
 
+void iwlagn_post_scan(struct iwl_priv *priv)
+{
+       struct iwl_rxon_context *ctx;
+
+       /*
+        * Since setting the RXON may have been deferred while
+        * performing the scan, fire one off if needed
+        */
+       for_each_context(priv, ctx)
+               if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))
+                       iwlagn_commit_rxon(priv, ctx);
+
+       if (priv->cfg->ops->hcmd->set_pan_params)
+               priv->cfg->ops->hcmd->set_pan_params(priv);
+}
+
 int iwlagn_manage_ibss_station(struct iwl_priv *priv,
                               struct ieee80211_vif *vif, bool add)
 {
        struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
 
        if (add)
-               return iwl_add_bssid_station(priv, vif_priv->ctx,
-                                            vif->bss_conf.bssid, true,
-                                            &vif_priv->ibss_bssid_sta_id);
+               return iwlagn_add_bssid_station(priv, vif_priv->ctx,
+                                               vif->bss_conf.bssid,
+                                               &vif_priv->ibss_bssid_sta_id);
        return iwl_remove_station(priv, vif_priv->ibss_bssid_sta_id,
                                  vif->bss_conf.bssid);
 }
@@ -2049,3 +2084,290 @@ void iwlagn_bt_cancel_deferred_work(struct iwl_priv *priv)
 {
        cancel_work_sync(&priv->bt_traffic_change_work);
 }
+
+static bool is_single_rx_stream(struct iwl_priv *priv)
+{
+       return priv->current_ht_config.smps == IEEE80211_SMPS_STATIC ||
+              priv->current_ht_config.single_chain_sufficient;
+}
+
+#define IWL_NUM_RX_CHAINS_MULTIPLE     3
+#define IWL_NUM_RX_CHAINS_SINGLE       2
+#define IWL_NUM_IDLE_CHAINS_DUAL       2
+#define IWL_NUM_IDLE_CHAINS_SINGLE     1
+
+/*
+ * Determine how many receiver/antenna chains to use.
+ *
+ * More provides better reception via diversity.  Fewer saves power
+ * at the expense of throughput, but only when not in powersave to
+ * start with.
+ *
+ * MIMO (dual stream) requires at least 2, but works better with 3.
+ * This does not determine *which* chains to use, just how many.
+ */
+static int iwl_get_active_rx_chain_count(struct iwl_priv *priv)
+{
+       if (priv->cfg->bt_params &&
+           priv->cfg->bt_params->advanced_bt_coexist &&
+           (priv->bt_full_concurrent ||
+            priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) {
+               /*
+                * only use chain 'A' in bt high traffic load or
+                * full concurrency mode
+                */
+               return IWL_NUM_RX_CHAINS_SINGLE;
+       }
+       /* # of Rx chains to use when expecting MIMO. */
+       if (is_single_rx_stream(priv))
+               return IWL_NUM_RX_CHAINS_SINGLE;
+       else
+               return IWL_NUM_RX_CHAINS_MULTIPLE;
+}
+
+/*
+ * When we are in power saving mode, unless device support spatial
+ * multiplexing power save, use the active count for rx chain count.
+ */
+static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt)
+{
+       /* # Rx chains when idling, depending on SMPS mode */
+       switch (priv->current_ht_config.smps) {
+       case IEEE80211_SMPS_STATIC:
+       case IEEE80211_SMPS_DYNAMIC:
+               return IWL_NUM_IDLE_CHAINS_SINGLE;
+       case IEEE80211_SMPS_OFF:
+               return active_cnt;
+       default:
+               WARN(1, "invalid SMPS mode %d",
+                    priv->current_ht_config.smps);
+               return active_cnt;
+       }
+}
+
+/* up to 4 chains */
+static u8 iwl_count_chain_bitmap(u32 chain_bitmap)
+{
+       u8 res;
+       res = (chain_bitmap & BIT(0)) >> 0;
+       res += (chain_bitmap & BIT(1)) >> 1;
+       res += (chain_bitmap & BIT(2)) >> 2;
+       res += (chain_bitmap & BIT(3)) >> 3;
+       return res;
+}
+
+/**
+ * iwlagn_set_rxon_chain - Set up Rx chain usage in "staging" RXON image
+ *
+ * Selects how many and which Rx receivers/antennas/chains to use.
+ * This should not be used for scan command ... it puts data in wrong place.
+ */
+void iwlagn_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
+{
+       bool is_single = is_single_rx_stream(priv);
+       bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status);
+       u8 idle_rx_cnt, active_rx_cnt, valid_rx_cnt;
+       u32 active_chains;
+       u16 rx_chain;
+
+       /* Tell uCode which antennas are actually connected.
+        * Before first association, we assume all antennas are connected.
+        * Just after first association, iwl_chain_noise_calibration()
+        *    checks which antennas actually *are* connected. */
+       if (priv->chain_noise_data.active_chains)
+               active_chains = priv->chain_noise_data.active_chains;
+       else
+               active_chains = priv->hw_params.valid_rx_ant;
+
+       if (priv->cfg->bt_params &&
+           priv->cfg->bt_params->advanced_bt_coexist &&
+           (priv->bt_full_concurrent ||
+            priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) {
+               /*
+                * only use chain 'A' in bt high traffic load or
+                * full concurrency mode
+                */
+               active_chains = first_antenna(active_chains);
+       }
+
+       rx_chain = active_chains << RXON_RX_CHAIN_VALID_POS;
+
+       /* How many receivers should we use? */
+       active_rx_cnt = iwl_get_active_rx_chain_count(priv);
+       idle_rx_cnt = iwl_get_idle_rx_chain_count(priv, active_rx_cnt);
+
+
+       /* correct rx chain count according hw settings
+        * and chain noise calibration
+        */
+       valid_rx_cnt = iwl_count_chain_bitmap(active_chains);
+       if (valid_rx_cnt < active_rx_cnt)
+               active_rx_cnt = valid_rx_cnt;
+
+       if (valid_rx_cnt < idle_rx_cnt)
+               idle_rx_cnt = valid_rx_cnt;
+
+       rx_chain |= active_rx_cnt << RXON_RX_CHAIN_MIMO_CNT_POS;
+       rx_chain |= idle_rx_cnt  << RXON_RX_CHAIN_CNT_POS;
+
+       ctx->staging.rx_chain = cpu_to_le16(rx_chain);
+
+       if (!is_single && (active_rx_cnt >= IWL_NUM_RX_CHAINS_SINGLE) && is_cam)
+               ctx->staging.rx_chain |= RXON_RX_CHAIN_MIMO_FORCE_MSK;
+       else
+               ctx->staging.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK;
+
+       IWL_DEBUG_ASSOC(priv, "rx_chain=0x%X active=%d idle=%d\n",
+                       ctx->staging.rx_chain,
+                       active_rx_cnt, idle_rx_cnt);
+
+       WARN_ON(active_rx_cnt == 0 || idle_rx_cnt == 0 ||
+               active_rx_cnt < idle_rx_cnt);
+}
+
+u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant, u8 valid)
+{
+       int i;
+       u8 ind = ant;
+
+       if (priv->band == IEEE80211_BAND_2GHZ &&
+           priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)
+               return 0;
+
+       for (i = 0; i < RATE_ANT_NUM - 1; i++) {
+               ind = (ind + 1) < RATE_ANT_NUM ?  ind + 1 : 0;
+               if (valid & BIT(ind))
+                       return ind;
+       }
+       return ant;
+}
+
+static const char *get_csr_string(int cmd)
+{
+       switch (cmd) {
+       IWL_CMD(CSR_HW_IF_CONFIG_REG);
+       IWL_CMD(CSR_INT_COALESCING);
+       IWL_CMD(CSR_INT);
+       IWL_CMD(CSR_INT_MASK);
+       IWL_CMD(CSR_FH_INT_STATUS);
+       IWL_CMD(CSR_GPIO_IN);
+       IWL_CMD(CSR_RESET);
+       IWL_CMD(CSR_GP_CNTRL);
+       IWL_CMD(CSR_HW_REV);
+       IWL_CMD(CSR_EEPROM_REG);
+       IWL_CMD(CSR_EEPROM_GP);
+       IWL_CMD(CSR_OTP_GP_REG);
+       IWL_CMD(CSR_GIO_REG);
+       IWL_CMD(CSR_GP_UCODE_REG);
+       IWL_CMD(CSR_GP_DRIVER_REG);
+       IWL_CMD(CSR_UCODE_DRV_GP1);
+       IWL_CMD(CSR_UCODE_DRV_GP2);
+       IWL_CMD(CSR_LED_REG);
+       IWL_CMD(CSR_DRAM_INT_TBL_REG);
+       IWL_CMD(CSR_GIO_CHICKEN_BITS);
+       IWL_CMD(CSR_ANA_PLL_CFG);
+       IWL_CMD(CSR_HW_REV_WA_REG);
+       IWL_CMD(CSR_DBG_HPET_MEM_REG);
+       default:
+               return "UNKNOWN";
+       }
+}
+
+void iwl_dump_csr(struct iwl_priv *priv)
+{
+       int i;
+       u32 csr_tbl[] = {
+               CSR_HW_IF_CONFIG_REG,
+               CSR_INT_COALESCING,
+               CSR_INT,
+               CSR_INT_MASK,
+               CSR_FH_INT_STATUS,
+               CSR_GPIO_IN,
+               CSR_RESET,
+               CSR_GP_CNTRL,
+               CSR_HW_REV,
+               CSR_EEPROM_REG,
+               CSR_EEPROM_GP,
+               CSR_OTP_GP_REG,
+               CSR_GIO_REG,
+               CSR_GP_UCODE_REG,
+               CSR_GP_DRIVER_REG,
+               CSR_UCODE_DRV_GP1,
+               CSR_UCODE_DRV_GP2,
+               CSR_LED_REG,
+               CSR_DRAM_INT_TBL_REG,
+               CSR_GIO_CHICKEN_BITS,
+               CSR_ANA_PLL_CFG,
+               CSR_HW_REV_WA_REG,
+               CSR_DBG_HPET_MEM_REG
+       };
+       IWL_ERR(priv, "CSR values:\n");
+       IWL_ERR(priv, "(2nd byte of CSR_INT_COALESCING is "
+               "CSR_INT_PERIODIC_REG)\n");
+       for (i = 0; i <  ARRAY_SIZE(csr_tbl); i++) {
+               IWL_ERR(priv, "  %25s: 0X%08x\n",
+                       get_csr_string(csr_tbl[i]),
+                       iwl_read32(priv, csr_tbl[i]));
+       }
+}
+
+static const char *get_fh_string(int cmd)
+{
+       switch (cmd) {
+       IWL_CMD(FH_RSCSR_CHNL0_STTS_WPTR_REG);
+       IWL_CMD(FH_RSCSR_CHNL0_RBDCB_BASE_REG);
+       IWL_CMD(FH_RSCSR_CHNL0_WPTR);
+       IWL_CMD(FH_MEM_RCSR_CHNL0_CONFIG_REG);
+       IWL_CMD(FH_MEM_RSSR_SHARED_CTRL_REG);
+       IWL_CMD(FH_MEM_RSSR_RX_STATUS_REG);
+       IWL_CMD(FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV);
+       IWL_CMD(FH_TSSR_TX_STATUS_REG);
+       IWL_CMD(FH_TSSR_TX_ERROR_REG);
+       default:
+               return "UNKNOWN";
+       }
+}
+
+int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display)
+{
+       int i;
+#ifdef CONFIG_IWLWIFI_DEBUG
+       int pos = 0;
+       size_t bufsz = 0;
+#endif
+       u32 fh_tbl[] = {
+               FH_RSCSR_CHNL0_STTS_WPTR_REG,
+               FH_RSCSR_CHNL0_RBDCB_BASE_REG,
+               FH_RSCSR_CHNL0_WPTR,
+               FH_MEM_RCSR_CHNL0_CONFIG_REG,
+               FH_MEM_RSSR_SHARED_CTRL_REG,
+               FH_MEM_RSSR_RX_STATUS_REG,
+               FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV,
+               FH_TSSR_TX_STATUS_REG,
+               FH_TSSR_TX_ERROR_REG
+       };
+#ifdef CONFIG_IWLWIFI_DEBUG
+       if (display) {
+               bufsz = ARRAY_SIZE(fh_tbl) * 48 + 40;
+               *buf = kmalloc(bufsz, GFP_KERNEL);
+               if (!*buf)
+                       return -ENOMEM;
+               pos += scnprintf(*buf + pos, bufsz - pos,
+                               "FH register values:\n");
+               for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) {
+                       pos += scnprintf(*buf + pos, bufsz - pos,
+                               "  %34s: 0X%08x\n",
+                               get_fh_string(fh_tbl[i]),
+                               iwl_read_direct32(priv, fh_tbl[i]));
+               }
+               return pos;
+       }
+#endif
+       IWL_ERR(priv, "FH register values:\n");
+       for (i = 0; i <  ARRAY_SIZE(fh_tbl); i++) {
+               IWL_ERR(priv, "  %34s: 0X%08x\n",
+                       get_fh_string(fh_tbl[i]),
+                       iwl_read_direct32(priv, fh_tbl[i]));
+       }
+       return 0;
+}
index f865685fd5f547b53dd2acc0103445839c3f4a56..5abe2e9ff0d2e35f924639adb96adc197ce1589b 100644 (file)
@@ -39,6 +39,7 @@
 #include "iwl-dev.h"
 #include "iwl-sta.h"
 #include "iwl-core.h"
+#include "iwl-agn.h"
 
 #define RS_NAME "iwl-agn-rs"
 
@@ -76,6 +77,74 @@ static const u8 ant_toggle_lookup[] = {
        /*ANT_ABC  -> */ ANT_ABC,
 };
 
+#define IWL_DECLARE_RATE_INFO(r, s, ip, in, rp, rn, pp, np)    \
+       [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP,      \
+                                   IWL_RATE_SISO_##s##M_PLCP, \
+                                   IWL_RATE_MIMO2_##s##M_PLCP,\
+                                   IWL_RATE_MIMO3_##s##M_PLCP,\
+                                   IWL_RATE_##r##M_IEEE,      \
+                                   IWL_RATE_##ip##M_INDEX,    \
+                                   IWL_RATE_##in##M_INDEX,    \
+                                   IWL_RATE_##rp##M_INDEX,    \
+                                   IWL_RATE_##rn##M_INDEX,    \
+                                   IWL_RATE_##pp##M_INDEX,    \
+                                   IWL_RATE_##np##M_INDEX }
+
+/*
+ * Parameter order:
+ *   rate, ht rate, prev rate, next rate, prev tgg rate, next tgg rate
+ *
+ * If there isn't a valid next or previous rate then INV is used which
+ * maps to IWL_RATE_INVALID
+ *
+ */
+const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT] = {
+       IWL_DECLARE_RATE_INFO(1, INV, INV, 2, INV, 2, INV, 2),    /*  1mbps */
+       IWL_DECLARE_RATE_INFO(2, INV, 1, 5, 1, 5, 1, 5),          /*  2mbps */
+       IWL_DECLARE_RATE_INFO(5, INV, 2, 6, 2, 11, 2, 11),        /*5.5mbps */
+       IWL_DECLARE_RATE_INFO(11, INV, 9, 12, 9, 12, 5, 18),      /* 11mbps */
+       IWL_DECLARE_RATE_INFO(6, 6, 5, 9, 5, 11, 5, 11),        /*  6mbps */
+       IWL_DECLARE_RATE_INFO(9, 6, 6, 11, 6, 11, 5, 11),       /*  9mbps */
+       IWL_DECLARE_RATE_INFO(12, 12, 11, 18, 11, 18, 11, 18),   /* 12mbps */
+       IWL_DECLARE_RATE_INFO(18, 18, 12, 24, 12, 24, 11, 24),   /* 18mbps */
+       IWL_DECLARE_RATE_INFO(24, 24, 18, 36, 18, 36, 18, 36),   /* 24mbps */
+       IWL_DECLARE_RATE_INFO(36, 36, 24, 48, 24, 48, 24, 48),   /* 36mbps */
+       IWL_DECLARE_RATE_INFO(48, 48, 36, 54, 36, 54, 36, 54),   /* 48mbps */
+       IWL_DECLARE_RATE_INFO(54, 54, 48, INV, 48, INV, 48, INV),/* 54mbps */
+       IWL_DECLARE_RATE_INFO(60, 60, 48, INV, 48, INV, 48, INV),/* 60mbps */
+       /* FIXME:RS:          ^^    should be INV (legacy) */
+};
+
+static int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
+{
+       int idx = 0;
+
+       /* HT rate format */
+       if (rate_n_flags & RATE_MCS_HT_MSK) {
+               idx = (rate_n_flags & 0xff);
+
+               if (idx >= IWL_RATE_MIMO3_6M_PLCP)
+                       idx = idx - IWL_RATE_MIMO3_6M_PLCP;
+               else if (idx >= IWL_RATE_MIMO2_6M_PLCP)
+                       idx = idx - IWL_RATE_MIMO2_6M_PLCP;
+
+               idx += IWL_FIRST_OFDM_RATE;
+               /* skip 9M not supported in ht*/
+               if (idx >= IWL_RATE_9M_INDEX)
+                       idx += 1;
+               if ((idx >= IWL_FIRST_OFDM_RATE) && (idx <= IWL_LAST_OFDM_RATE))
+                       return idx;
+
+       /* legacy rate format, search for match in table */
+       } else {
+               for (idx = 0; idx < ARRAY_SIZE(iwl_rates); idx++)
+                       if (iwl_rates[idx].plcp == (rate_n_flags & 0xFF))
+                               return idx;
+       }
+
+       return -1;
+}
+
 static void rs_rate_scale_perform(struct iwl_priv *priv,
                                   struct sk_buff *skb,
                                   struct ieee80211_sta *sta,
index 357cdb26f16d7aa644ae317999fac4d00ef100f5..75e50d33ecb3a14a9d304b0ffe0342dc0d81a81d 100644 (file)
@@ -299,7 +299,6 @@ enum {
 #define TIME_WRAP_AROUND(x, y) (((y) > (x)) ? (y) - (x) : (0-(x)) + (y))
 
 extern const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT];
-extern const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT_3945];
 
 enum iwl_table_type {
        LQ_NONE,
@@ -453,15 +452,6 @@ static inline u8 first_antenna(u8 mask)
 }
 
 
-static inline u8 iwl3945_get_prev_ieee_rate(u8 rate_index)
-{
-       u8 rate = iwl3945_rates[rate_index].prev_ieee;
-
-       if (rate == IWL_RATE_INVALID)
-               rate = rate_index;
-       return rate;
-}
-
 /**
  * iwl3945_rate_scale_init - Initialize the rate scale table based on assoc info
  *
index 1e08eb455474877824e4148dba3fe25980f68c66..bbd40b7dd597996ca0c9313a7338ee37448dcd91 100644 (file)
@@ -34,7 +34,7 @@
 
 #include "iwl-dev.h"
 #include "iwl-core.h"
-#include "iwl-calib.h"
+#include "iwl-agn-calib.h"
 #include "iwl-sta.h"
 #include "iwl-io.h"
 #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 (file)
index 0000000..35a30d2
--- /dev/null
@@ -0,0 +1,716 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ *
+ * Portions of this file are derived from the ipw3945 project, as well
+ * as portions of the ieee80211 subsystem header files.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ *  Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ *****************************************************************************/
+
+#include <net/mac80211.h>
+
+#include "iwl-dev.h"
+#include "iwl-core.h"
+#include "iwl-sta.h"
+#include "iwl-agn.h"
+
+static struct iwl_link_quality_cmd *
+iwl_sta_alloc_lq(struct iwl_priv *priv, u8 sta_id)
+{
+       int i, r;
+       struct iwl_link_quality_cmd *link_cmd;
+       u32 rate_flags = 0;
+       __le32 rate_n_flags;
+
+       link_cmd = kzalloc(sizeof(struct iwl_link_quality_cmd), GFP_KERNEL);
+       if (!link_cmd) {
+               IWL_ERR(priv, "Unable to allocate memory for LQ cmd.\n");
+               return NULL;
+       }
+       /* Set up the rate scaling to start at selected rate, fall back
+        * all the way down to 1M in IEEE order, and then spin on 1M */
+       if (priv->band == IEEE80211_BAND_5GHZ)
+               r = IWL_RATE_6M_INDEX;
+       else
+               r = IWL_RATE_1M_INDEX;
+
+       if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE)
+               rate_flags |= RATE_MCS_CCK_MSK;
+
+       rate_flags |= first_antenna(priv->hw_params.valid_tx_ant) <<
+                               RATE_MCS_ANT_POS;
+       rate_n_flags = iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags);
+       for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++)
+               link_cmd->rs_table[i].rate_n_flags = rate_n_flags;
+
+       link_cmd->general_params.single_stream_ant_msk =
+                               first_antenna(priv->hw_params.valid_tx_ant);
+
+       link_cmd->general_params.dual_stream_ant_msk =
+               priv->hw_params.valid_tx_ant &
+               ~first_antenna(priv->hw_params.valid_tx_ant);
+       if (!link_cmd->general_params.dual_stream_ant_msk) {
+               link_cmd->general_params.dual_stream_ant_msk = ANT_AB;
+       } else if (num_of_ant(priv->hw_params.valid_tx_ant) == 2) {
+               link_cmd->general_params.dual_stream_ant_msk =
+                       priv->hw_params.valid_tx_ant;
+       }
+
+       link_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
+       link_cmd->agg_params.agg_time_limit =
+               cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
+
+       link_cmd->sta_id = sta_id;
+
+       return link_cmd;
+}
+
+/*
+ * iwlagn_add_bssid_station - Add the special IBSS BSSID station
+ *
+ * Function sleeps.
+ */
+int iwlagn_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+                            const u8 *addr, u8 *sta_id_r)
+{
+       int ret;
+       u8 sta_id;
+       struct iwl_link_quality_cmd *link_cmd;
+       unsigned long flags;
+
+       if (sta_id_r)
+               *sta_id_r = IWL_INVALID_STATION;
+
+       ret = iwl_add_station_common(priv, ctx, addr, 0, NULL, &sta_id);
+       if (ret) {
+               IWL_ERR(priv, "Unable to add station %pM\n", addr);
+               return ret;
+       }
+
+       if (sta_id_r)
+               *sta_id_r = sta_id;
+
+       spin_lock_irqsave(&priv->sta_lock, flags);
+       priv->stations[sta_id].used |= IWL_STA_LOCAL;
+       spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+       /* Set up default rate scaling table in device's station table */
+       link_cmd = iwl_sta_alloc_lq(priv, sta_id);
+       if (!link_cmd) {
+               IWL_ERR(priv, "Unable to initialize rate scaling for station %pM.\n",
+                       addr);
+               return -ENOMEM;
+       }
+
+       ret = iwl_send_lq_cmd(priv, ctx, link_cmd, CMD_SYNC, true);
+       if (ret)
+               IWL_ERR(priv, "Link quality command failed (%d)\n", ret);
+
+       spin_lock_irqsave(&priv->sta_lock, flags);
+       priv->stations[sta_id].lq = link_cmd;
+       spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+       return 0;
+}
+
+static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv,
+                                     struct iwl_rxon_context *ctx,
+                                     bool send_if_empty)
+{
+       int i, not_empty = 0;
+       u8 buff[sizeof(struct iwl_wep_cmd) +
+               sizeof(struct iwl_wep_key) * WEP_KEYS_MAX];
+       struct iwl_wep_cmd *wep_cmd = (struct iwl_wep_cmd *)buff;
+       size_t cmd_size  = sizeof(struct iwl_wep_cmd);
+       struct iwl_host_cmd cmd = {
+               .id = ctx->wep_key_cmd,
+               .data = wep_cmd,
+               .flags = CMD_SYNC,
+       };
+
+       might_sleep();
+
+       memset(wep_cmd, 0, cmd_size +
+                       (sizeof(struct iwl_wep_key) * WEP_KEYS_MAX));
+
+       for (i = 0; i < WEP_KEYS_MAX ; i++) {
+               wep_cmd->key[i].key_index = i;
+               if (ctx->wep_keys[i].key_size) {
+                       wep_cmd->key[i].key_offset = i;
+                       not_empty = 1;
+               } else {
+                       wep_cmd->key[i].key_offset = WEP_INVALID_OFFSET;
+               }
+
+               wep_cmd->key[i].key_size = ctx->wep_keys[i].key_size;
+               memcpy(&wep_cmd->key[i].key[3], ctx->wep_keys[i].key,
+                               ctx->wep_keys[i].key_size);
+       }
+
+       wep_cmd->global_key_type = WEP_KEY_WEP_TYPE;
+       wep_cmd->num_keys = WEP_KEYS_MAX;
+
+       cmd_size += sizeof(struct iwl_wep_key) * WEP_KEYS_MAX;
+
+       cmd.len = cmd_size;
+
+       if (not_empty || send_if_empty)
+               return iwl_send_cmd(priv, &cmd);
+       else
+               return 0;
+}
+
+int iwl_restore_default_wep_keys(struct iwl_priv *priv,
+                                struct iwl_rxon_context *ctx)
+{
+       lockdep_assert_held(&priv->mutex);
+
+       return iwl_send_static_wepkey_cmd(priv, ctx, false);
+}
+
+int iwl_remove_default_wep_key(struct iwl_priv *priv,
+                              struct iwl_rxon_context *ctx,
+                              struct ieee80211_key_conf *keyconf)
+{
+       int ret;
+
+       lockdep_assert_held(&priv->mutex);
+
+       IWL_DEBUG_WEP(priv, "Removing default WEP key: idx=%d\n",
+                     keyconf->keyidx);
+
+       memset(&ctx->wep_keys[keyconf->keyidx], 0, sizeof(ctx->wep_keys[0]));
+       if (iwl_is_rfkill(priv)) {
+               IWL_DEBUG_WEP(priv, "Not sending REPLY_WEPKEY command due to RFKILL.\n");
+               /* but keys in device are clear anyway so return success */
+               return 0;
+       }
+       ret = iwl_send_static_wepkey_cmd(priv, ctx, 1);
+       IWL_DEBUG_WEP(priv, "Remove default WEP key: idx=%d ret=%d\n",
+                     keyconf->keyidx, ret);
+
+       return ret;
+}
+
+int iwl_set_default_wep_key(struct iwl_priv *priv,
+                           struct iwl_rxon_context *ctx,
+                           struct ieee80211_key_conf *keyconf)
+{
+       int ret;
+
+       lockdep_assert_held(&priv->mutex);
+
+       if (keyconf->keylen != WEP_KEY_LEN_128 &&
+           keyconf->keylen != WEP_KEY_LEN_64) {
+               IWL_DEBUG_WEP(priv, "Bad WEP key length %d\n", keyconf->keylen);
+               return -EINVAL;
+       }
+
+       keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV;
+       keyconf->hw_key_idx = HW_KEY_DEFAULT;
+       priv->stations[ctx->ap_sta_id].keyinfo.cipher = keyconf->cipher;
+
+       ctx->wep_keys[keyconf->keyidx].key_size = keyconf->keylen;
+       memcpy(&ctx->wep_keys[keyconf->keyidx].key, &keyconf->key,
+                                                       keyconf->keylen);
+
+       ret = iwl_send_static_wepkey_cmd(priv, ctx, false);
+       IWL_DEBUG_WEP(priv, "Set default WEP key: len=%d idx=%d ret=%d\n",
+               keyconf->keylen, keyconf->keyidx, ret);
+
+       return ret;
+}
+
+static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv,
+                                       struct iwl_rxon_context *ctx,
+                                       struct ieee80211_key_conf *keyconf,
+                                       u8 sta_id)
+{
+       unsigned long flags;
+       __le16 key_flags = 0;
+       struct iwl_addsta_cmd sta_cmd;
+
+       lockdep_assert_held(&priv->mutex);
+
+       keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV;
+
+       key_flags |= (STA_KEY_FLG_WEP | STA_KEY_FLG_MAP_KEY_MSK);
+       key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
+       key_flags &= ~STA_KEY_FLG_INVALID;
+
+       if (keyconf->keylen == WEP_KEY_LEN_128)
+               key_flags |= STA_KEY_FLG_KEY_SIZE_MSK;
+
+       if (sta_id == ctx->bcast_sta_id)
+               key_flags |= STA_KEY_MULTICAST_MSK;
+
+       spin_lock_irqsave(&priv->sta_lock, flags);
+
+       priv->stations[sta_id].keyinfo.cipher = keyconf->cipher;
+       priv->stations[sta_id].keyinfo.keylen = keyconf->keylen;
+       priv->stations[sta_id].keyinfo.keyidx = keyconf->keyidx;
+
+       memcpy(priv->stations[sta_id].keyinfo.key,
+                               keyconf->key, keyconf->keylen);
+
+       memcpy(&priv->stations[sta_id].sta.key.key[3],
+                               keyconf->key, keyconf->keylen);
+
+       if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
+                       == STA_KEY_FLG_NO_ENC)
+               priv->stations[sta_id].sta.key.key_offset =
+                                iwl_get_free_ucode_key_index(priv);
+       /* else, we are overriding an existing key => no need to allocated room
+        * in uCode. */
+
+       WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
+               "no space for a new key");
+
+       priv->stations[sta_id].sta.key.key_flags = key_flags;
+       priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
+       priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
+
+       memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
+       spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+       return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
+}
+
+static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
+                                        struct iwl_rxon_context *ctx,
+                                        struct ieee80211_key_conf *keyconf,
+                                        u8 sta_id)
+{
+       unsigned long flags;
+       __le16 key_flags = 0;
+       struct iwl_addsta_cmd sta_cmd;
+
+       lockdep_assert_held(&priv->mutex);
+
+       key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK);
+       key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
+       key_flags &= ~STA_KEY_FLG_INVALID;
+
+       if (sta_id == ctx->bcast_sta_id)
+               key_flags |= STA_KEY_MULTICAST_MSK;
+
+       keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+
+       spin_lock_irqsave(&priv->sta_lock, flags);
+       priv->stations[sta_id].keyinfo.cipher = keyconf->cipher;
+       priv->stations[sta_id].keyinfo.keylen = keyconf->keylen;
+
+       memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key,
+              keyconf->keylen);
+
+       memcpy(priv->stations[sta_id].sta.key.key, keyconf->key,
+              keyconf->keylen);
+
+       if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
+                       == STA_KEY_FLG_NO_ENC)
+               priv->stations[sta_id].sta.key.key_offset =
+                                iwl_get_free_ucode_key_index(priv);
+       /* else, we are overriding an existing key => no need to allocated room
+        * in uCode. */
+
+       WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
+               "no space for a new key");
+
+       priv->stations[sta_id].sta.key.key_flags = key_flags;
+       priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
+       priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
+
+       memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
+       spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+       return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
+}
+
+static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv,
+                                        struct iwl_rxon_context *ctx,
+                                        struct ieee80211_key_conf *keyconf,
+                                        u8 sta_id)
+{
+       unsigned long flags;
+       int ret = 0;
+       __le16 key_flags = 0;
+
+       key_flags |= (STA_KEY_FLG_TKIP | STA_KEY_FLG_MAP_KEY_MSK);
+       key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
+       key_flags &= ~STA_KEY_FLG_INVALID;
+
+       if (sta_id == ctx->bcast_sta_id)
+               key_flags |= STA_KEY_MULTICAST_MSK;
+
+       keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+       keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
+
+       spin_lock_irqsave(&priv->sta_lock, flags);
+
+       priv->stations[sta_id].keyinfo.cipher = keyconf->cipher;
+       priv->stations[sta_id].keyinfo.keylen = 16;
+
+       if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
+                       == STA_KEY_FLG_NO_ENC)
+               priv->stations[sta_id].sta.key.key_offset =
+                                iwl_get_free_ucode_key_index(priv);
+       /* else, we are overriding an existing key => no need to allocated room
+        * in uCode. */
+
+       WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
+               "no space for a new key");
+
+       priv->stations[sta_id].sta.key.key_flags = key_flags;
+
+
+       /* This copy is acutally not needed: we get the key with each TX */
+       memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, 16);
+
+       memcpy(priv->stations[sta_id].sta.key.key, keyconf->key, 16);
+
+       spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+       return ret;
+}
+
+void iwl_update_tkip_key(struct iwl_priv *priv,
+                        struct iwl_rxon_context *ctx,
+                        struct ieee80211_key_conf *keyconf,
+                        struct ieee80211_sta *sta, u32 iv32, u16 *phase1key)
+{
+       u8 sta_id;
+       unsigned long flags;
+       int i;
+
+       if (iwl_scan_cancel(priv)) {
+               /* cancel scan failed, just live w/ bad key and rely
+                  briefly on SW decryption */
+               return;
+       }
+
+       sta_id = iwl_sta_id_or_broadcast(priv, ctx, sta);
+       if (sta_id == IWL_INVALID_STATION)
+               return;
+
+       spin_lock_irqsave(&priv->sta_lock, flags);
+
+       priv->stations[sta_id].sta.key.tkip_rx_tsc_byte2 = (u8) iv32;
+
+       for (i = 0; i < 5; i++)
+               priv->stations[sta_id].sta.key.tkip_rx_ttak[i] =
+                       cpu_to_le16(phase1key[i]);
+
+       priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
+       priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
+
+       iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
+
+       spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+}
+
+int iwl_remove_dynamic_key(struct iwl_priv *priv,
+                          struct iwl_rxon_context *ctx,
+                          struct ieee80211_key_conf *keyconf,
+                          u8 sta_id)
+{
+       unsigned long flags;
+       u16 key_flags;
+       u8 keyidx;
+       struct iwl_addsta_cmd sta_cmd;
+
+       lockdep_assert_held(&priv->mutex);
+
+       ctx->key_mapping_keys--;
+
+       spin_lock_irqsave(&priv->sta_lock, flags);
+       key_flags = le16_to_cpu(priv->stations[sta_id].sta.key.key_flags);
+       keyidx = (key_flags >> STA_KEY_FLG_KEYID_POS) & 0x3;
+
+       IWL_DEBUG_WEP(priv, "Remove dynamic key: idx=%d sta=%d\n",
+                     keyconf->keyidx, sta_id);
+
+       if (keyconf->keyidx != keyidx) {
+               /* We need to remove a key with index different that the one
+                * in the uCode. This means that the key we need to remove has
+                * been replaced by another one with different index.
+                * Don't do anything and return ok
+                */
+               spin_unlock_irqrestore(&priv->sta_lock, flags);
+               return 0;
+       }
+
+       if (priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET) {
+               IWL_WARN(priv, "Removing wrong key %d 0x%x\n",
+                           keyconf->keyidx, key_flags);
+               spin_unlock_irqrestore(&priv->sta_lock, flags);
+               return 0;
+       }
+
+       if (!test_and_clear_bit(priv->stations[sta_id].sta.key.key_offset,
+               &priv->ucode_key_table))
+               IWL_ERR(priv, "index %d not used in uCode key table.\n",
+                       priv->stations[sta_id].sta.key.key_offset);
+       memset(&priv->stations[sta_id].keyinfo, 0,
+                                       sizeof(struct iwl_hw_key));
+       memset(&priv->stations[sta_id].sta.key, 0,
+                                       sizeof(struct iwl4965_keyinfo));
+       priv->stations[sta_id].sta.key.key_flags =
+                       STA_KEY_FLG_NO_ENC | STA_KEY_FLG_INVALID;
+       priv->stations[sta_id].sta.key.key_offset = WEP_INVALID_OFFSET;
+       priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
+       priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
+
+       if (iwl_is_rfkill(priv)) {
+               IWL_DEBUG_WEP(priv, "Not sending REPLY_ADD_STA command because RFKILL enabled.\n");
+               spin_unlock_irqrestore(&priv->sta_lock, flags);
+               return 0;
+       }
+       memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
+       spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+       return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
+}
+
+int iwl_set_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+                       struct ieee80211_key_conf *keyconf, u8 sta_id)
+{
+       int ret;
+
+       lockdep_assert_held(&priv->mutex);
+
+       ctx->key_mapping_keys++;
+       keyconf->hw_key_idx = HW_KEY_DYNAMIC;
+
+       switch (keyconf->cipher) {
+       case WLAN_CIPHER_SUITE_CCMP:
+               ret = iwl_set_ccmp_dynamic_key_info(priv, ctx, keyconf, sta_id);
+               break;
+       case WLAN_CIPHER_SUITE_TKIP:
+               ret = iwl_set_tkip_dynamic_key_info(priv, ctx, keyconf, sta_id);
+               break;
+       case WLAN_CIPHER_SUITE_WEP40:
+       case WLAN_CIPHER_SUITE_WEP104:
+               ret = iwl_set_wep_dynamic_key_info(priv, ctx, keyconf, sta_id);
+               break;
+       default:
+               IWL_ERR(priv,
+                       "Unknown alg: %s cipher = %x\n", __func__,
+                       keyconf->cipher);
+               ret = -EINVAL;
+       }
+
+       IWL_DEBUG_WEP(priv, "Set dynamic key: cipher=%x len=%d idx=%d sta=%d ret=%d\n",
+                     keyconf->cipher, keyconf->keylen, keyconf->keyidx,
+                     sta_id, ret);
+
+       return ret;
+}
+
+/**
+ * iwlagn_alloc_bcast_station - add broadcast station into driver's station table.
+ *
+ * This adds the broadcast station into the driver's station table
+ * and marks it driver active, so that it will be restored to the
+ * device at the next best time.
+ */
+int iwlagn_alloc_bcast_station(struct iwl_priv *priv,
+                              struct iwl_rxon_context *ctx)
+{
+       struct iwl_link_quality_cmd *link_cmd;
+       unsigned long flags;
+       u8 sta_id;
+
+       spin_lock_irqsave(&priv->sta_lock, flags);
+       sta_id = iwl_prep_station(priv, ctx, iwl_bcast_addr, false, NULL);
+       if (sta_id == IWL_INVALID_STATION) {
+               IWL_ERR(priv, "Unable to prepare broadcast station\n");
+               spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+               return -EINVAL;
+       }
+
+       priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE;
+       priv->stations[sta_id].used |= IWL_STA_BCAST;
+       spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+       link_cmd = iwl_sta_alloc_lq(priv, sta_id);
+       if (!link_cmd) {
+               IWL_ERR(priv,
+                       "Unable to initialize rate scaling for bcast station.\n");
+               return -ENOMEM;
+       }
+
+       spin_lock_irqsave(&priv->sta_lock, flags);
+       priv->stations[sta_id].lq = link_cmd;
+       spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+       return 0;
+}
+
+/**
+ * iwl_update_bcast_station - update broadcast station's LQ command
+ *
+ * Only used by iwlagn. Placed here to have all bcast station management
+ * code together.
+ */
+static int iwl_update_bcast_station(struct iwl_priv *priv,
+                                   struct iwl_rxon_context *ctx)
+{
+       unsigned long flags;
+       struct iwl_link_quality_cmd *link_cmd;
+       u8 sta_id = ctx->bcast_sta_id;
+
+       link_cmd = iwl_sta_alloc_lq(priv, sta_id);
+       if (!link_cmd) {
+               IWL_ERR(priv, "Unable to initialize rate scaling for bcast station.\n");
+               return -ENOMEM;
+       }
+
+       spin_lock_irqsave(&priv->sta_lock, flags);
+       if (priv->stations[sta_id].lq)
+               kfree(priv->stations[sta_id].lq);
+       else
+               IWL_DEBUG_INFO(priv, "Bcast station rate scaling has not been initialized yet.\n");
+       priv->stations[sta_id].lq = link_cmd;
+       spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+       return 0;
+}
+
+int iwl_update_bcast_stations(struct iwl_priv *priv)
+{
+       struct iwl_rxon_context *ctx;
+       int ret = 0;
+
+       for_each_context(priv, ctx) {
+               ret = iwl_update_bcast_station(priv, ctx);
+               if (ret)
+                       break;
+       }
+
+       return ret;
+}
+
+/**
+ * iwl_sta_tx_modify_enable_tid - Enable Tx for this TID in station table
+ */
+int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid)
+{
+       unsigned long flags;
+       struct iwl_addsta_cmd sta_cmd;
+
+       lockdep_assert_held(&priv->mutex);
+
+       /* Remove "disable" flag, to enable Tx for this TID */
+       spin_lock_irqsave(&priv->sta_lock, flags);
+       priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_TID_DISABLE_TX;
+       priv->stations[sta_id].sta.tid_disable_tx &= cpu_to_le16(~(1 << tid));
+       priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
+       memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
+       spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+       return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
+}
+
+int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta,
+                        int tid, u16 ssn)
+{
+       unsigned long flags;
+       int sta_id;
+       struct iwl_addsta_cmd sta_cmd;
+
+       lockdep_assert_held(&priv->mutex);
+
+       sta_id = iwl_sta_id(sta);
+       if (sta_id == IWL_INVALID_STATION)
+               return -ENXIO;
+
+       spin_lock_irqsave(&priv->sta_lock, flags);
+       priv->stations[sta_id].sta.station_flags_msk = 0;
+       priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_ADDBA_TID_MSK;
+       priv->stations[sta_id].sta.add_immediate_ba_tid = (u8)tid;
+       priv->stations[sta_id].sta.add_immediate_ba_ssn = cpu_to_le16(ssn);
+       priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
+       memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
+       spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+       return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
+}
+
+int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
+                       int tid)
+{
+       unsigned long flags;
+       int sta_id;
+       struct iwl_addsta_cmd sta_cmd;
+
+       lockdep_assert_held(&priv->mutex);
+
+       sta_id = iwl_sta_id(sta);
+       if (sta_id == IWL_INVALID_STATION) {
+               IWL_ERR(priv, "Invalid station for AGG tid %d\n", tid);
+               return -ENXIO;
+       }
+
+       spin_lock_irqsave(&priv->sta_lock, flags);
+       priv->stations[sta_id].sta.station_flags_msk = 0;
+       priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_DELBA_TID_MSK;
+       priv->stations[sta_id].sta.remove_immediate_ba_tid = (u8)tid;
+       priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
+       memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
+       spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+       return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
+}
+
+void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&priv->sta_lock, flags);
+       priv->stations[sta_id].sta.station_flags &= ~STA_FLG_PWR_SAVE_MSK;
+       priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK;
+       priv->stations[sta_id].sta.sta.modify_mask = 0;
+       priv->stations[sta_id].sta.sleep_tx_count = 0;
+       priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
+       iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
+       spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+}
+
+void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&priv->sta_lock, flags);
+       priv->stations[sta_id].sta.station_flags |= STA_FLG_PWR_SAVE_MSK;
+       priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK;
+       priv->stations[sta_id].sta.sta.modify_mask =
+                                       STA_MODIFY_SLEEP_TX_COUNT_MSK;
+       priv->stations[sta_id].sta.sleep_tx_count = cpu_to_le16(cnt);
+       priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
+       iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
+       spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+}
index 0c6c4d96970673bbf280cf4705d0802dd7637768..e3a8216a033cf574d31fdca786d488edd78d5bfe 100644 (file)
@@ -571,7 +571,6 @@ void iwl_tt_enter_ct_kill(struct iwl_priv *priv)
        IWL_DEBUG_POWER(priv, "Queueing critical temperature enter.\n");
        queue_work(priv->workqueue, &priv->ct_enter);
 }
-EXPORT_SYMBOL(iwl_tt_enter_ct_kill);
 
 void iwl_tt_exit_ct_kill(struct iwl_priv *priv)
 {
@@ -581,7 +580,6 @@ void iwl_tt_exit_ct_kill(struct iwl_priv *priv)
        IWL_DEBUG_POWER(priv, "Queueing critical temperature exit.\n");
        queue_work(priv->workqueue, &priv->ct_exit);
 }
-EXPORT_SYMBOL(iwl_tt_exit_ct_kill);
 
 static void iwl_bg_tt_work(struct work_struct *work)
 {
@@ -608,7 +606,6 @@ void iwl_tt_handler(struct iwl_priv *priv)
        IWL_DEBUG_POWER(priv, "Queueing thermal throttling work.\n");
        queue_work(priv->workqueue, &priv->tt_work);
 }
-EXPORT_SYMBOL(iwl_tt_handler);
 
 /* Thermal throttling initialization
  * For advance thermal throttling:
@@ -678,7 +675,6 @@ void iwl_tt_initialize(struct iwl_priv *priv)
                priv->thermal_throttle.advanced_tt = false;
        }
 }
-EXPORT_SYMBOL(iwl_tt_initialize);
 
 /* cleanup thermal throttling management related memory and timer */
 void iwl_tt_exit(struct iwl_priv *priv)
@@ -701,4 +697,3 @@ void iwl_tt_exit(struct iwl_priv *priv)
                tt->transaction = NULL;
        }
 }
-EXPORT_SYMBOL(iwl_tt_exit);
index 77753b72f23680b36677fad7fc271d2e0cd52017..db57aea629d93857e6a3b068ce74059b87c0d771 100644 (file)
@@ -1391,3 +1391,43 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
 
        spin_unlock_irqrestore(&priv->sta_lock, flags);
 }
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+const char *iwl_get_tx_fail_reason(u32 status)
+{
+#define TX_STATUS_FAIL(x) case TX_STATUS_FAIL_ ## x: return #x
+#define TX_STATUS_POSTPONE(x) case TX_STATUS_POSTPONE_ ## x: return #x
+
+       switch (status & TX_STATUS_MSK) {
+       case TX_STATUS_SUCCESS:
+               return "SUCCESS";
+       TX_STATUS_POSTPONE(DELAY);
+       TX_STATUS_POSTPONE(FEW_BYTES);
+       TX_STATUS_POSTPONE(BT_PRIO);
+       TX_STATUS_POSTPONE(QUIET_PERIOD);
+       TX_STATUS_POSTPONE(CALC_TTAK);
+       TX_STATUS_FAIL(INTERNAL_CROSSED_RETRY);
+       TX_STATUS_FAIL(SHORT_LIMIT);
+       TX_STATUS_FAIL(LONG_LIMIT);
+       TX_STATUS_FAIL(FIFO_UNDERRUN);
+       TX_STATUS_FAIL(DRAIN_FLOW);
+       TX_STATUS_FAIL(RFKILL_FLUSH);
+       TX_STATUS_FAIL(LIFE_EXPIRE);
+       TX_STATUS_FAIL(DEST_PS);
+       TX_STATUS_FAIL(HOST_ABORTED);
+       TX_STATUS_FAIL(BT_RETRY);
+       TX_STATUS_FAIL(STA_INVALID);
+       TX_STATUS_FAIL(FRAG_DROPPED);
+       TX_STATUS_FAIL(TID_DISABLE);
+       TX_STATUS_FAIL(FIFO_FLUSHED);
+       TX_STATUS_FAIL(INSUFFICIENT_CF_POLL);
+       TX_STATUS_FAIL(PASSIVE_NO_RX);
+       TX_STATUS_FAIL(NO_BEACON_ON_RADAR);
+       }
+
+       return "UNKNOWN";
+
+#undef TX_STATUS_FAIL
+#undef TX_STATUS_POSTPONE
+}
+#endif /* CONFIG_IWLWIFI_DEBUG */
index e1dd76267dca2fdcc08d4c40ace5118d2e0310e6..703621107dac8cbcb7f10a5f1265576c169fb48b 100644 (file)
@@ -38,6 +38,7 @@
 #include "iwl-helpers.h"
 #include "iwl-agn-hw.h"
 #include "iwl-agn.h"
+#include "iwl-agn-calib.h"
 
 static const s8 iwlagn_default_queue_to_tx_fifo[] = {
        IWL_TX_FIFO_VO,
@@ -214,6 +215,25 @@ static int iwlagn_set_Xtal_calib(struct iwl_priv *priv)
                             (u8 *)&cmd, sizeof(cmd));
 }
 
+static int iwlagn_set_temperature_offset_calib(struct iwl_priv *priv)
+{
+       struct iwl_calib_temperature_offset_cmd cmd;
+       __le16 *offset_calib =
+               (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_TEMPERATURE);
+       cmd.hdr.op_code = IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD;
+       cmd.hdr.first_group = 0;
+       cmd.hdr.groups_num = 1;
+       cmd.hdr.data_valid = 1;
+       cmd.radio_sensor_offset = le16_to_cpu(offset_calib[1]);
+       if (!(cmd.radio_sensor_offset))
+               cmd.radio_sensor_offset = DEFAULT_RADIO_SENSOR_OFFSET;
+       cmd.reserved = 0;
+       IWL_DEBUG_CALIB(priv, "Radio sensor offset: %d\n",
+                       cmd.radio_sensor_offset);
+       return iwl_calib_set(&priv->calib_results[IWL_CALIB_TEMP_OFFSET],
+                            (u8 *)&cmd, sizeof(cmd));
+}
+
 static int iwlagn_send_calib_cfg(struct iwl_priv *priv)
 {
        struct iwl_calib_cfg_cmd calib_cfg_cmd;
@@ -320,6 +340,14 @@ void iwlagn_init_alive_start(struct iwl_priv *priv)
 
        }
        iwlagn_send_calib_cfg(priv);
+
+       /**
+        * temperature offset calibration is only needed for runtime ucode,
+        * so prepare the value now.
+        */
+       if (priv->cfg->need_temp_offset_calib)
+               iwlagn_set_temperature_offset_calib(priv);
+
        return;
 
 restart:
index a6dce616ee3c8ecd523ad241a23dac0e64430611..c2636a7ab9eed9840f1fe0ec0aa466ec610aee57 100644 (file)
@@ -57,7 +57,7 @@
 #include "iwl-io.h"
 #include "iwl-helpers.h"
 #include "iwl-sta.h"
-#include "iwl-calib.h"
+#include "iwl-agn-calib.h"
 #include "iwl-agn.h"
 
 
@@ -91,14 +91,14 @@ static int iwlagn_ant_coupling;
 static bool iwlagn_bt_ch_announce = 1;
 
 /**
- * iwl_commit_rxon - commit staging_rxon to hardware
+ * iwlagn_commit_rxon - commit staging_rxon to hardware
  *
  * The RXON command in staging_rxon is committed to the hardware and
  * the active_rxon structure is updated with the new data.  This
  * function correctly transitions out of the RXON_ASSOC_MSK state if
  * a HW tune is required based on the RXON structure changes.
  */
-int iwl_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
+int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
 {
        /* cast away the const for active_rxon in this function */
        struct iwl_rxon_cmd *active_rxon = (void *)&ctx->active;
@@ -314,24 +314,26 @@ static void iwl_free_frame(struct iwl_priv *priv, struct iwl_frame *frame)
 }
 
 static u32 iwl_fill_beacon_frame(struct iwl_priv *priv,
-                                         struct ieee80211_hdr *hdr,
-                                         int left)
+                                struct ieee80211_hdr *hdr,
+                                int left)
 {
-       if (!priv->ibss_beacon)
+       lockdep_assert_held(&priv->mutex);
+
+       if (!priv->beacon_skb)
                return 0;
 
-       if (priv->ibss_beacon->len > left)
+       if (priv->beacon_skb->len > left)
                return 0;
 
-       memcpy(hdr, priv->ibss_beacon->data, priv->ibss_beacon->len);
+       memcpy(hdr, priv->beacon_skb->data, priv->beacon_skb->len);
 
-       return priv->ibss_beacon->len;
+       return priv->beacon_skb->len;
 }
 
 /* Parse the beacon frame to find the TIM element and set tim_idx & tim_size */
 static void iwl_set_beacon_tim(struct iwl_priv *priv,
-               struct iwl_tx_beacon_cmd *tx_beacon_cmd,
-               u8 *beacon, u32 frame_size)
+                              struct iwl_tx_beacon_cmd *tx_beacon_cmd,
+                              u8 *beacon, u32 frame_size)
 {
        u16 tim_idx;
        struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)beacon;
@@ -383,6 +385,8 @@ static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv,
                                sizeof(frame->u) - sizeof(*tx_beacon_cmd));
        if (WARN_ON_ONCE(frame_size > MAX_MPDU_SIZE))
                return 0;
+       if (!frame_size)
+               return 0;
 
        /* Set up TX command fields */
        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,
 
        /* Set up TX beacon command fields */
        iwl_set_beacon_tim(priv, tx_beacon_cmd, (u8 *)tx_beacon_cmd->frame,
-                       frame_size);
+                          frame_size);
 
        /* Set up packet rate and flags */
        rate = iwl_rate_get_lowest_plcp(priv, priv->beacon_ctx);
@@ -648,15 +652,14 @@ static void iwl_bg_beacon_update(struct work_struct *work)
        /* Pull updated AP beacon from mac80211. will fail if not in AP mode */
        beacon = ieee80211_beacon_get(priv->hw, priv->beacon_ctx->vif);
        if (!beacon) {
-               IWL_ERR(priv, "update beacon failed\n");
+               IWL_ERR(priv, "update beacon failed -- keeping old\n");
                goto out;
        }
 
        /* new beacon skb is allocated every time; dispose previous.*/
-       if (priv->ibss_beacon)
-               dev_kfree_skb(priv->ibss_beacon);
+       dev_kfree_skb(priv->beacon_skb);
 
-       priv->ibss_beacon = beacon;
+       priv->beacon_skb = beacon;
 
        iwl_send_beacon_cmd(priv);
  out:
@@ -935,22 +938,6 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv,
                wake_up_interruptible(&priv->wait_command_queue);
 }
 
-int iwl_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
-{
-       if (src == IWL_PWR_SRC_VAUX) {
-               if (pci_pme_capable(priv->pci_dev, PCI_D3cold))
-                       iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
-                                              APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
-                                              ~APMG_PS_CTRL_MSK_PWR_SRC);
-       } else {
-               iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
-                                      APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
-                                      ~APMG_PS_CTRL_MSK_PWR_SRC);
-       }
-
-       return 0;
-}
-
 static void iwl_bg_tx_flush(struct work_struct *work)
 {
        struct iwl_priv *priv =
@@ -2078,7 +2065,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
        struct iwlagn_ucode_capabilities ucode_capa = {
                .max_probe_length = 200,
                .standard_phy_calibration_size =
-                       IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE,
+                       IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE,
        };
 
        memset(&pieces, 0, sizeof(pieces));
@@ -2120,18 +2107,23 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
         * firmware filename ... but we don't check for that and only rely
         * on the API version read from firmware header from here on forward
         */
-       if (api_ver < api_min || api_ver > api_max) {
-               IWL_ERR(priv, "Driver unable to support your firmware API. "
-                         "Driver supports v%u, firmware is v%u.\n",
-                         api_max, api_ver);
-               goto try_again;
-       }
+       /* no api version check required for experimental uCode */
+       if (priv->fw_index != UCODE_EXPERIMENTAL_INDEX) {
+               if (api_ver < api_min || api_ver > api_max) {
+                       IWL_ERR(priv,
+                               "Driver unable to support your firmware API. "
+                               "Driver supports v%u, firmware is v%u.\n",
+                               api_max, api_ver);
+                       goto try_again;
+               }
 
-       if (api_ver != api_max)
-               IWL_ERR(priv, "Firmware has old API version. Expected v%u, "
-                         "got v%u. New firmware can be obtained "
-                         "from http://www.intellinuxwireless.org.\n",
-                         api_max, api_ver);
+               if (api_ver != api_max)
+                       IWL_ERR(priv,
+                               "Firmware has old API version. Expected v%u, "
+                               "got v%u. New firmware can be obtained "
+                               "from http://www.intellinuxwireless.org.\n",
+                               api_max, api_ver);
+       }
 
        if (build)
                sprintf(buildstr, " build %u%s", build,
@@ -2820,9 +2812,6 @@ static void iwl_alive_start(struct iwl_priv *priv)
                goto restart;
        }
 
-       if (priv->hw_params.calib_rt_cfg)
-               iwlagn_send_calib_cfg_rt(priv, priv->hw_params.calib_rt_cfg);
-
 
        /* After the ALIVE response, we can send host commands to the uCode */
        set_bit(STATUS_ALIVE, &priv->status);
@@ -2838,6 +2827,7 @@ static void iwl_alive_start(struct iwl_priv *priv)
        if (iwl_is_rfkill(priv))
                return;
 
+       /* download priority table before any calibration request */
        if (priv->cfg->bt_params &&
            priv->cfg->bt_params->advanced_bt_coexist) {
                /* Configure Bluetooth device coexistence support */
@@ -2846,8 +2836,7 @@ static void iwl_alive_start(struct iwl_priv *priv)
                priv->kill_cts_mask = IWLAGN_BT_KILL_CTS_MASK_DEFAULT;
                priv->cfg->ops->hcmd->send_bt_config(priv);
                priv->bt_valid = IWLAGN_BT_VALID_ENABLE_FLAGS;
-               if (bt_coex_active && priv->iw_mode != NL80211_IFTYPE_ADHOC)
-                       iwlagn_send_prio_tbl(priv);
+               iwlagn_send_prio_tbl(priv);
 
                /* FIXME: w/a to force change uCode BT state machine */
                iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN,
@@ -2855,6 +2844,9 @@ static void iwl_alive_start(struct iwl_priv *priv)
                iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_CLOSE,
                        BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
        }
+       if (priv->hw_params.calib_rt_cfg)
+               iwlagn_send_calib_cfg_rt(priv, priv->hw_params.calib_rt_cfg);
+
        ieee80211_wake_queues(priv->hw);
 
        priv->active_rate = IWL_RATES_MASK;
@@ -2999,14 +2991,13 @@ static void __iwl_down(struct iwl_priv *priv)
        iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
 
        /* Stop the device, and put it in low power state */
-       priv->cfg->ops->lib->apm_ops.stop(priv);
+       iwl_apm_stop(priv);
 
  exit:
        memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp));
 
-       if (priv->ibss_beacon)
-               dev_kfree_skb(priv->ibss_beacon);
-       priv->ibss_beacon = NULL;
+       dev_kfree_skb(priv->beacon_skb);
+       priv->beacon_skb = NULL;
 
        /* clear out any free frames */
        iwl_clear_free_frames(priv);
@@ -3089,7 +3080,7 @@ static int __iwl_up(struct iwl_priv *priv)
        }
 
        for_each_context(priv, ctx) {
-               ret = iwl_alloc_bcast_station(priv, ctx, true);
+               ret = iwlagn_alloc_bcast_station(priv, ctx);
                if (ret) {
                        iwl_dealloc_bcast_stations(priv);
                        return ret;
@@ -4142,8 +4133,6 @@ static int iwl_init_drv(struct iwl_priv *priv)
 {
        int ret;
 
-       priv->ibss_beacon = NULL;
-
        spin_lock_init(&priv->sta_lock);
        spin_lock_init(&priv->hcmd_lock);
 
@@ -4613,7 +4602,7 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
         * paths to avoid running iwl_down() at all before leaving driver.
         * This (inexpensive) call *makes sure* device is reset.
         */
-       priv->cfg->ops->lib->apm_ops.stop(priv);
+       iwl_apm_stop(priv);
 
        iwl_tt_exit(priv);
 
@@ -4656,8 +4645,7 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
 
        iwl_free_isr_ict(priv);
 
-       if (priv->ibss_beacon)
-               dev_kfree_skb(priv->ibss_beacon);
+       dev_kfree_skb(priv->beacon_skb);
 
        ieee80211_free_hw(priv->hw);
 }
index eb3812a358623d1f7a6957f3ef908ecae10582a3..f525d55f2c0fb208c92b5e60d56ab5386da4acc4 100644 (file)
@@ -129,6 +129,10 @@ void iwlagn_txq_set_sched(struct iwl_priv *priv, u32 mask);
 void iwl_free_tfds_in_queue(struct iwl_priv *priv,
                            int sta_id, int tid, int freed);
 
+/* RXON */
+int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
+void iwlagn_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
+
 /* uCode */
 int iwlagn_load_ucode(struct iwl_priv *priv);
 void iwlagn_rx_calib_result(struct iwl_priv *priv,
@@ -158,6 +162,8 @@ int iwlagn_hw_nic_init(struct iwl_priv *priv);
 int iwlagn_wait_tx_queue_empty(struct iwl_priv *priv);
 int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control);
 void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control);
+void iwl_dump_csr(struct iwl_priv *priv);
+int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display);
 
 /* rx */
 void iwlagn_rx_queue_restock(struct iwl_priv *priv);
@@ -171,8 +177,15 @@ void iwlagn_rx_reply_rx(struct iwl_priv *priv,
                     struct iwl_rx_mem_buffer *rxb);
 void iwlagn_rx_reply_rx_phy(struct iwl_priv *priv,
                         struct iwl_rx_mem_buffer *rxb);
+void iwl_rx_handle(struct iwl_priv *priv);
 
 /* tx */
+void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq);
+int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
+                                struct iwl_tx_queue *txq,
+                                dma_addr_t addr, u16 len, u8 reset, u8 pad);
+int iwl_hw_tx_queue_init(struct iwl_priv *priv,
+                        struct iwl_tx_queue *txq);
 void iwlagn_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
                              struct ieee80211_tx_info *info);
 int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb);
@@ -212,6 +225,8 @@ static inline bool iwl_is_tx_success(u32 status)
               (status == TX_STATUS_DIRECT_DONE);
 }
 
+u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx, u8 valid);
+
 /* rx */
 void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
                                struct iwl_rx_mem_buffer *rxb);
@@ -224,6 +239,7 @@ void iwl_reply_statistics(struct iwl_priv *priv,
 
 /* scan */
 int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif);
+void iwlagn_post_scan(struct iwl_priv *priv);
 
 /* station mgmt */
 int iwlagn_manage_ibss_station(struct iwl_priv *priv,
@@ -243,8 +259,63 @@ void iwlagn_bt_setup_deferred_work(struct iwl_priv *priv);
 void iwlagn_bt_cancel_deferred_work(struct iwl_priv *priv);
 
 #ifdef CONFIG_IWLWIFI_DEBUG
+const char *iwl_get_tx_fail_reason(u32 status);
 const char *iwl_get_agg_tx_fail_reason(u16 status);
 #else
+static inline const char *iwl_get_tx_fail_reason(u32 status) { return ""; }
 static inline const char *iwl_get_agg_tx_fail_reason(u16 status) { return ""; }
 #endif
+
+/* station management */
+int iwlagn_alloc_bcast_station(struct iwl_priv *priv,
+                              struct iwl_rxon_context *ctx);
+int iwlagn_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+                            const u8 *addr, u8 *sta_id_r);
+int iwl_remove_default_wep_key(struct iwl_priv *priv,
+                              struct iwl_rxon_context *ctx,
+                              struct ieee80211_key_conf *key);
+int iwl_set_default_wep_key(struct iwl_priv *priv,
+                           struct iwl_rxon_context *ctx,
+                           struct ieee80211_key_conf *key);
+int iwl_restore_default_wep_keys(struct iwl_priv *priv,
+                                struct iwl_rxon_context *ctx);
+int iwl_set_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+                       struct ieee80211_key_conf *key, u8 sta_id);
+int iwl_remove_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+                          struct ieee80211_key_conf *key, u8 sta_id);
+void iwl_update_tkip_key(struct iwl_priv *priv,
+                        struct iwl_rxon_context *ctx,
+                        struct ieee80211_key_conf *keyconf,
+                        struct ieee80211_sta *sta, u32 iv32, u16 *phase1key);
+int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid);
+int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta,
+                        int tid, u16 ssn);
+int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
+                       int tid);
+void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id);
+void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt);
+int iwl_update_bcast_stations(struct iwl_priv *priv);
+
+/* rate */
+static inline u32 iwl_ant_idx_to_flags(u8 ant_idx)
+{
+       return BIT(ant_idx) << RATE_MCS_ANT_POS;
+}
+
+static inline u8 iwl_hw_get_rate(__le32 rate_n_flags)
+{
+       return le32_to_cpu(rate_n_flags) & 0xFF;
+}
+
+static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags)
+{
+       return cpu_to_le32(flags|(u32)rate);
+}
+
+/* eeprom */
+void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv);
+void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac);
+int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv);
+void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv);
+
 #endif /* __iwl_agn_h__ */
index fe652568fec7547535e7d8d7d1a226c9bf5025ea..424801abc80eae92a5d39a777c08a73baf13c7a6 100644 (file)
@@ -3784,7 +3784,8 @@ struct iwl_enhance_sensitivity_cmd {
  */
 
 /* Phy calibration command for series */
-
+/* The default calibrate table size if not specified by firmware */
+#define IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE    18
 enum {
        IWL_PHY_CALIBRATE_DIFF_GAIN_CMD         = 7,
        IWL_PHY_CALIBRATE_DC_CMD                = 8,
@@ -3793,7 +3794,8 @@ enum {
        IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD       = 15,
        IWL_PHY_CALIBRATE_BASE_BAND_CMD         = 16,
        IWL_PHY_CALIBRATE_TX_IQ_PERD_CMD        = 17,
-       IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE = 18,
+       IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD       = 18,
+       IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE = 19,
 };
 
 #define IWL_MAX_PHY_CALIBRATE_TBL_SIZE         (253)
@@ -3863,6 +3865,13 @@ struct iwl_calib_xtal_freq_cmd {
        u8 pad[2];
 } __packed;
 
+#define DEFAULT_RADIO_SENSOR_OFFSET    2700
+struct iwl_calib_temperature_offset_cmd {
+       struct iwl_calib_hdr hdr;
+       s16 radio_sensor_offset;
+       s16 reserved;
+} __packed;
+
 /* IWL_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD */
 struct iwl_calib_chain_noise_reset_cmd {
        struct iwl_calib_hdr hdr;
index 516c55ae38aad4ea10bf957283d6d5a6a98234ae..25fb3912342ceff334f6c2d82cb61defc5b0ee75 100644 (file)
@@ -69,97 +69,9 @@ EXPORT_SYMBOL_GPL(bt_coex_active);
 module_param(bt_coex_active, bool, S_IRUGO);
 MODULE_PARM_DESC(bt_coex_active, "enable wifi/bluetooth co-exist");
 
-#define IWL_DECLARE_RATE_INFO(r, s, ip, in, rp, rn, pp, np)    \
-       [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP,      \
-                                   IWL_RATE_SISO_##s##M_PLCP, \
-                                   IWL_RATE_MIMO2_##s##M_PLCP,\
-                                   IWL_RATE_MIMO3_##s##M_PLCP,\
-                                   IWL_RATE_##r##M_IEEE,      \
-                                   IWL_RATE_##ip##M_INDEX,    \
-                                   IWL_RATE_##in##M_INDEX,    \
-                                   IWL_RATE_##rp##M_INDEX,    \
-                                   IWL_RATE_##rn##M_INDEX,    \
-                                   IWL_RATE_##pp##M_INDEX,    \
-                                   IWL_RATE_##np##M_INDEX }
-
 u32 iwl_debug_level;
 EXPORT_SYMBOL(iwl_debug_level);
 
-/*
- * Parameter order:
- *   rate, ht rate, prev rate, next rate, prev tgg rate, next tgg rate
- *
- * If there isn't a valid next or previous rate then INV is used which
- * maps to IWL_RATE_INVALID
- *
- */
-const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT] = {
-       IWL_DECLARE_RATE_INFO(1, INV, INV, 2, INV, 2, INV, 2),    /*  1mbps */
-       IWL_DECLARE_RATE_INFO(2, INV, 1, 5, 1, 5, 1, 5),          /*  2mbps */
-       IWL_DECLARE_RATE_INFO(5, INV, 2, 6, 2, 11, 2, 11),        /*5.5mbps */
-       IWL_DECLARE_RATE_INFO(11, INV, 9, 12, 9, 12, 5, 18),      /* 11mbps */
-       IWL_DECLARE_RATE_INFO(6, 6, 5, 9, 5, 11, 5, 11),        /*  6mbps */
-       IWL_DECLARE_RATE_INFO(9, 6, 6, 11, 6, 11, 5, 11),       /*  9mbps */
-       IWL_DECLARE_RATE_INFO(12, 12, 11, 18, 11, 18, 11, 18),   /* 12mbps */
-       IWL_DECLARE_RATE_INFO(18, 18, 12, 24, 12, 24, 11, 24),   /* 18mbps */
-       IWL_DECLARE_RATE_INFO(24, 24, 18, 36, 18, 36, 18, 36),   /* 24mbps */
-       IWL_DECLARE_RATE_INFO(36, 36, 24, 48, 24, 48, 24, 48),   /* 36mbps */
-       IWL_DECLARE_RATE_INFO(48, 48, 36, 54, 36, 54, 36, 54),   /* 48mbps */
-       IWL_DECLARE_RATE_INFO(54, 54, 48, INV, 48, INV, 48, INV),/* 54mbps */
-       IWL_DECLARE_RATE_INFO(60, 60, 48, INV, 48, INV, 48, INV),/* 60mbps */
-       /* FIXME:RS:          ^^    should be INV (legacy) */
-};
-EXPORT_SYMBOL(iwl_rates);
-
-int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
-{
-       int idx = 0;
-
-       /* HT rate format */
-       if (rate_n_flags & RATE_MCS_HT_MSK) {
-               idx = (rate_n_flags & 0xff);
-
-               if (idx >= IWL_RATE_MIMO3_6M_PLCP)
-                       idx = idx - IWL_RATE_MIMO3_6M_PLCP;
-               else if (idx >= IWL_RATE_MIMO2_6M_PLCP)
-                       idx = idx - IWL_RATE_MIMO2_6M_PLCP;
-
-               idx += IWL_FIRST_OFDM_RATE;
-               /* skip 9M not supported in ht*/
-               if (idx >= IWL_RATE_9M_INDEX)
-                       idx += 1;
-               if ((idx >= IWL_FIRST_OFDM_RATE) && (idx <= IWL_LAST_OFDM_RATE))
-                       return idx;
-
-       /* legacy rate format, search for match in table */
-       } else {
-               for (idx = 0; idx < ARRAY_SIZE(iwl_rates); idx++)
-                       if (iwl_rates[idx].plcp == (rate_n_flags & 0xFF))
-                               return idx;
-       }
-
-       return -1;
-}
-EXPORT_SYMBOL(iwl_hwrate_to_plcp_idx);
-
-u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant, u8 valid)
-{
-       int i;
-       u8 ind = ant;
-
-       if (priv->band == IEEE80211_BAND_2GHZ &&
-           priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)
-               return 0;
-
-       for (i = 0; i < RATE_ANT_NUM - 1; i++) {
-               ind = (ind + 1) < RATE_ANT_NUM ?  ind + 1 : 0;
-               if (valid & BIT(ind))
-                       return ind;
-       }
-       return ant;
-}
-EXPORT_SYMBOL(iwl_toggle_tx_ant);
-
 const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
 EXPORT_SYMBOL(iwl_bcast_addr);
 
@@ -439,12 +351,6 @@ void iwlcore_tx_cmd_protection(struct iwl_priv *priv,
 EXPORT_SYMBOL(iwlcore_tx_cmd_protection);
 
 
-static bool is_single_rx_stream(struct iwl_priv *priv)
-{
-       return priv->current_ht_config.smps == IEEE80211_SMPS_STATIC ||
-              priv->current_ht_config.single_chain_sufficient;
-}
-
 static bool iwl_is_channel_extension(struct iwl_priv *priv,
                                     enum ieee80211_band band,
                                     u16 channel, u8 extension_chan_offset)
@@ -604,76 +510,74 @@ void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
 }
 EXPORT_SYMBOL(iwl_set_rxon_hwcrypto);
 
-/**
- * iwl_check_rxon_cmd - validate RXON structure is valid
- *
- * NOTE:  This is really only useful during development and can eventually
- * be #ifdef'd out once the driver is stable and folks aren't actively
- * making changes
- */
+/* validate RXON structure is valid */
 int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
 {
-       int error = 0;
-       int counter = 1;
        struct iwl_rxon_cmd *rxon = &ctx->staging;
+       bool error = false;
 
        if (rxon->flags & RXON_FLG_BAND_24G_MSK) {
-               error |= le32_to_cpu(rxon->flags &
-                               (RXON_FLG_TGJ_NARROW_BAND_MSK |
-                                RXON_FLG_RADAR_DETECT_MSK));
-               if (error)
-                       IWL_WARN(priv, "check 24G fields %d | %d\n",
-                                   counter++, error);
+               if (rxon->flags & RXON_FLG_TGJ_NARROW_BAND_MSK) {
+                       IWL_WARN(priv, "check 2.4G: wrong narrow\n");
+                       error = true;
+               }
+               if (rxon->flags & RXON_FLG_RADAR_DETECT_MSK) {
+                       IWL_WARN(priv, "check 2.4G: wrong radar\n");
+                       error = true;
+               }
        } else {
-               error |= (rxon->flags & RXON_FLG_SHORT_SLOT_MSK) ?
-                               0 : le32_to_cpu(RXON_FLG_SHORT_SLOT_MSK);
-               if (error)
-                       IWL_WARN(priv, "check 52 fields %d | %d\n",
-                                   counter++, error);
-               error |= le32_to_cpu(rxon->flags & RXON_FLG_CCK_MSK);
-               if (error)
-                       IWL_WARN(priv, "check 52 CCK %d | %d\n",
-                                   counter++, error);
-       }
-       error |= (rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1;
-       if (error)
-               IWL_WARN(priv, "check mac addr %d | %d\n", counter++, error);
+               if (!(rxon->flags & RXON_FLG_SHORT_SLOT_MSK)) {
+                       IWL_WARN(priv, "check 5.2G: not short slot!\n");
+                       error = true;
+               }
+               if (rxon->flags & RXON_FLG_CCK_MSK) {
+                       IWL_WARN(priv, "check 5.2G: CCK!\n");
+                       error = true;
+               }
+       }
+       if ((rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1) {
+               IWL_WARN(priv, "mac/bssid mcast!\n");
+               error = true;
+       }
 
        /* make sure basic rates 6Mbps and 1Mbps are supported */
-       error |= (((rxon->ofdm_basic_rates & IWL_RATE_6M_MASK) == 0) &&
-                 ((rxon->cck_basic_rates & IWL_RATE_1M_MASK) == 0));
-       if (error)
-               IWL_WARN(priv, "check basic rate %d | %d\n", counter++, error);
+       if ((rxon->ofdm_basic_rates & IWL_RATE_6M_MASK) == 0 &&
+           (rxon->cck_basic_rates & IWL_RATE_1M_MASK) == 0) {
+               IWL_WARN(priv, "neither 1 nor 6 are basic\n");
+               error = true;
+       }
 
-       error |= (le16_to_cpu(rxon->assoc_id) > 2007);
-       if (error)
-               IWL_WARN(priv, "check assoc id %d | %d\n", counter++, error);
+       if (le16_to_cpu(rxon->assoc_id) > 2007) {
+               IWL_WARN(priv, "aid > 2007\n");
+               error = true;
+       }
 
-       error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK))
-                       == (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK));
-       if (error)
-               IWL_WARN(priv, "check CCK and short slot %d | %d\n",
-                           counter++, error);
+       if ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK))
+                       == (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)) {
+               IWL_WARN(priv, "CCK and short slot\n");
+               error = true;
+       }
 
-       error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK))
-                       == (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK));
-       if (error)
-               IWL_WARN(priv, "check CCK & auto detect %d | %d\n",
-                           counter++, error);
+       if ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK))
+                       == (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)) {
+               IWL_WARN(priv, "CCK and auto detect");
+               error = true;
+       }
 
-       error |= ((rxon->flags & (RXON_FLG_AUTO_DETECT_MSK |
-                       RXON_FLG_TGG_PROTECT_MSK)) == RXON_FLG_TGG_PROTECT_MSK);
-       if (error)
-               IWL_WARN(priv, "check TGG and auto detect %d | %d\n",
-                           counter++, error);
+       if ((rxon->flags & (RXON_FLG_AUTO_DETECT_MSK |
+                           RXON_FLG_TGG_PROTECT_MSK)) ==
+                           RXON_FLG_TGG_PROTECT_MSK) {
+               IWL_WARN(priv, "TGg but no auto-detect\n");
+               error = true;
+       }
 
        if (error)
                IWL_WARN(priv, "Tuning to channel %d\n",
                            le16_to_cpu(rxon->channel));
 
        if (error) {
-               IWL_ERR(priv, "Not a valid iwl_rxon_assoc_cmd field values\n");
-               return -1;
+               IWL_ERR(priv, "Invalid RXON\n");
+               return -EINVAL;
        }
        return 0;
 }
@@ -834,141 +738,6 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf)
 }
 EXPORT_SYMBOL(iwl_set_rxon_ht);
 
-#define IWL_NUM_RX_CHAINS_MULTIPLE     3
-#define IWL_NUM_RX_CHAINS_SINGLE       2
-#define IWL_NUM_IDLE_CHAINS_DUAL       2
-#define IWL_NUM_IDLE_CHAINS_SINGLE     1
-
-/*
- * Determine how many receiver/antenna chains to use.
- *
- * More provides better reception via diversity.  Fewer saves power
- * at the expense of throughput, but only when not in powersave to
- * start with.
- *
- * MIMO (dual stream) requires at least 2, but works better with 3.
- * This does not determine *which* chains to use, just how many.
- */
-static int iwl_get_active_rx_chain_count(struct iwl_priv *priv)
-{
-       if (priv->cfg->bt_params &&
-           priv->cfg->bt_params->advanced_bt_coexist &&
-           (priv->bt_full_concurrent ||
-            priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) {
-               /*
-                * only use chain 'A' in bt high traffic load or
-                * full concurrency mode
-                */
-               return IWL_NUM_RX_CHAINS_SINGLE;
-       }
-       /* # of Rx chains to use when expecting MIMO. */
-       if (is_single_rx_stream(priv))
-               return IWL_NUM_RX_CHAINS_SINGLE;
-       else
-               return IWL_NUM_RX_CHAINS_MULTIPLE;
-}
-
-/*
- * When we are in power saving mode, unless device support spatial
- * multiplexing power save, use the active count for rx chain count.
- */
-static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt)
-{
-       /* # Rx chains when idling, depending on SMPS mode */
-       switch (priv->current_ht_config.smps) {
-       case IEEE80211_SMPS_STATIC:
-       case IEEE80211_SMPS_DYNAMIC:
-               return IWL_NUM_IDLE_CHAINS_SINGLE;
-       case IEEE80211_SMPS_OFF:
-               return active_cnt;
-       default:
-               WARN(1, "invalid SMPS mode %d",
-                    priv->current_ht_config.smps);
-               return active_cnt;
-       }
-}
-
-/* up to 4 chains */
-static u8 iwl_count_chain_bitmap(u32 chain_bitmap)
-{
-       u8 res;
-       res = (chain_bitmap & BIT(0)) >> 0;
-       res += (chain_bitmap & BIT(1)) >> 1;
-       res += (chain_bitmap & BIT(2)) >> 2;
-       res += (chain_bitmap & BIT(3)) >> 3;
-       return res;
-}
-
-/**
- * iwl_set_rxon_chain - Set up Rx chain usage in "staging" RXON image
- *
- * Selects how many and which Rx receivers/antennas/chains to use.
- * This should not be used for scan command ... it puts data in wrong place.
- */
-void iwl_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
-{
-       bool is_single = is_single_rx_stream(priv);
-       bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status);
-       u8 idle_rx_cnt, active_rx_cnt, valid_rx_cnt;
-       u32 active_chains;
-       u16 rx_chain;
-
-       /* Tell uCode which antennas are actually connected.
-        * Before first association, we assume all antennas are connected.
-        * Just after first association, iwl_chain_noise_calibration()
-        *    checks which antennas actually *are* connected. */
-       if (priv->chain_noise_data.active_chains)
-               active_chains = priv->chain_noise_data.active_chains;
-       else
-               active_chains = priv->hw_params.valid_rx_ant;
-
-       if (priv->cfg->bt_params &&
-           priv->cfg->bt_params->advanced_bt_coexist &&
-           (priv->bt_full_concurrent ||
-            priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) {
-               /*
-                * only use chain 'A' in bt high traffic load or
-                * full concurrency mode
-                */
-               active_chains = first_antenna(active_chains);
-       }
-
-       rx_chain = active_chains << RXON_RX_CHAIN_VALID_POS;
-
-       /* How many receivers should we use? */
-       active_rx_cnt = iwl_get_active_rx_chain_count(priv);
-       idle_rx_cnt = iwl_get_idle_rx_chain_count(priv, active_rx_cnt);
-
-
-       /* correct rx chain count according hw settings
-        * and chain noise calibration
-        */
-       valid_rx_cnt = iwl_count_chain_bitmap(active_chains);
-       if (valid_rx_cnt < active_rx_cnt)
-               active_rx_cnt = valid_rx_cnt;
-
-       if (valid_rx_cnt < idle_rx_cnt)
-               idle_rx_cnt = valid_rx_cnt;
-
-       rx_chain |= active_rx_cnt << RXON_RX_CHAIN_MIMO_CNT_POS;
-       rx_chain |= idle_rx_cnt  << RXON_RX_CHAIN_CNT_POS;
-
-       ctx->staging.rx_chain = cpu_to_le16(rx_chain);
-
-       if (!is_single && (active_rx_cnt >= IWL_NUM_RX_CHAINS_SINGLE) && is_cam)
-               ctx->staging.rx_chain |= RXON_RX_CHAIN_MIMO_FORCE_MSK;
-       else
-               ctx->staging.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK;
-
-       IWL_DEBUG_ASSOC(priv, "rx_chain=0x%X active=%d idle=%d\n",
-                       ctx->staging.rx_chain,
-                       active_rx_cnt, idle_rx_cnt);
-
-       WARN_ON(active_rx_cnt == 0 || idle_rx_cnt == 0 ||
-               active_rx_cnt < idle_rx_cnt);
-}
-EXPORT_SYMBOL(iwl_set_rxon_chain);
-
 /* Return valid, unused, channel for a passive scan to reset the RF */
 u8 iwl_get_single_channel_number(struct iwl_priv *priv,
                                 enum ieee80211_band band)
@@ -1758,43 +1527,47 @@ static inline void iwl_set_no_assoc(struct iwl_priv *priv,
        iwlcore_commit_rxon(priv, ctx);
 }
 
-static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
+static void iwlcore_beacon_update(struct ieee80211_hw *hw,
+                                 struct ieee80211_vif *vif)
 {
        struct iwl_priv *priv = hw->priv;
        unsigned long flags;
        __le64 timestamp;
+       struct sk_buff *skb = ieee80211_beacon_get(hw, vif);
 
-       IWL_DEBUG_MAC80211(priv, "enter\n");
+       if (!skb)
+               return;
+
+       IWL_DEBUG_ASSOC(priv, "enter\n");
 
        lockdep_assert_held(&priv->mutex);
 
        if (!priv->beacon_ctx) {
                IWL_ERR(priv, "update beacon but no beacon context!\n");
                dev_kfree_skb(skb);
-               return -EINVAL;
-       }
-
-       if (!iwl_is_ready_rf(priv)) {
-               IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
-               return -EIO;
+               return;
        }
 
        spin_lock_irqsave(&priv->lock, flags);
 
-       if (priv->ibss_beacon)
-               dev_kfree_skb(priv->ibss_beacon);
+       if (priv->beacon_skb)
+               dev_kfree_skb(priv->beacon_skb);
 
-       priv->ibss_beacon = skb;
+       priv->beacon_skb = skb;
 
        timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
        priv->timestamp = le64_to_cpu(timestamp);
 
-       IWL_DEBUG_MAC80211(priv, "leave\n");
+       IWL_DEBUG_ASSOC(priv, "leave\n");
+
        spin_unlock_irqrestore(&priv->lock, flags);
 
-       priv->cfg->ops->lib->post_associate(priv, priv->beacon_ctx->vif);
+       if (!iwl_is_ready_rf(priv)) {
+               IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
+               return;
+       }
 
-       return 0;
+       priv->cfg->ops->lib->post_associate(priv, priv->beacon_ctx->vif);
 }
 
 void iwl_bss_info_changed(struct ieee80211_hw *hw,
@@ -1835,8 +1608,8 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
        }
 
        if (changes & BSS_CHANGED_BEACON && vif->type == NL80211_IFTYPE_AP) {
-               dev_kfree_skb(priv->ibss_beacon);
-               priv->ibss_beacon = ieee80211_beacon_get(hw, vif);
+               dev_kfree_skb(priv->beacon_skb);
+               priv->beacon_skb = ieee80211_beacon_get(hw, vif);
        }
 
        if (changes & BSS_CHANGED_BEACON_INT && vif->type == NL80211_IFTYPE_AP)
@@ -1876,13 +1649,8 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
         * mac80211 decides to do both changes at once because
         * it will invoke post_associate.
         */
-       if (vif->type == NL80211_IFTYPE_ADHOC &&
-           changes & BSS_CHANGED_BEACON) {
-               struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
-
-               if (beacon)
-                       iwl_mac_beacon_update(hw, beacon);
-       }
+       if (vif->type == NL80211_IFTYPE_ADHOC && changes & BSS_CHANGED_BEACON)
+               iwlcore_beacon_update(hw, vif);
 
        if (changes & BSS_CHANGED_ERP_PREAMBLE) {
                IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n",
@@ -1959,6 +1727,7 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
                        memcpy(ctx->staging.bssid_addr,
                               bss_conf->bssid, ETH_ALEN);
                        memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN);
+                       iwl_led_associate(priv);
                        iwlcore_config_ap(priv, vif);
                } else
                        iwl_set_no_assoc(priv, vif);
@@ -2290,10 +2059,10 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
        spin_lock_irqsave(&priv->lock, flags);
 
        /* new association get rid of ibss beacon skb */
-       if (priv->ibss_beacon)
-               dev_kfree_skb(priv->ibss_beacon);
+       if (priv->beacon_skb)
+               dev_kfree_skb(priv->beacon_skb);
 
-       priv->ibss_beacon = NULL;
+       priv->beacon_skb = NULL;
 
        priv->timestamp = 0;
 
@@ -2581,140 +2350,6 @@ void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len)
 EXPORT_SYMBOL(iwl_update_stats);
 #endif
 
-static const char *get_csr_string(int cmd)
-{
-       switch (cmd) {
-               IWL_CMD(CSR_HW_IF_CONFIG_REG);
-               IWL_CMD(CSR_INT_COALESCING);
-               IWL_CMD(CSR_INT);
-               IWL_CMD(CSR_INT_MASK);
-               IWL_CMD(CSR_FH_INT_STATUS);
-               IWL_CMD(CSR_GPIO_IN);
-               IWL_CMD(CSR_RESET);
-               IWL_CMD(CSR_GP_CNTRL);
-               IWL_CMD(CSR_HW_REV);
-               IWL_CMD(CSR_EEPROM_REG);
-               IWL_CMD(CSR_EEPROM_GP);
-               IWL_CMD(CSR_OTP_GP_REG);
-               IWL_CMD(CSR_GIO_REG);
-               IWL_CMD(CSR_GP_UCODE_REG);
-               IWL_CMD(CSR_GP_DRIVER_REG);
-               IWL_CMD(CSR_UCODE_DRV_GP1);
-               IWL_CMD(CSR_UCODE_DRV_GP2);
-               IWL_CMD(CSR_LED_REG);
-               IWL_CMD(CSR_DRAM_INT_TBL_REG);
-               IWL_CMD(CSR_GIO_CHICKEN_BITS);
-               IWL_CMD(CSR_ANA_PLL_CFG);
-               IWL_CMD(CSR_HW_REV_WA_REG);
-               IWL_CMD(CSR_DBG_HPET_MEM_REG);
-       default:
-               return "UNKNOWN";
-
-       }
-}
-
-void iwl_dump_csr(struct iwl_priv *priv)
-{
-       int i;
-       u32 csr_tbl[] = {
-               CSR_HW_IF_CONFIG_REG,
-               CSR_INT_COALESCING,
-               CSR_INT,
-               CSR_INT_MASK,
-               CSR_FH_INT_STATUS,
-               CSR_GPIO_IN,
-               CSR_RESET,
-               CSR_GP_CNTRL,
-               CSR_HW_REV,
-               CSR_EEPROM_REG,
-               CSR_EEPROM_GP,
-               CSR_OTP_GP_REG,
-               CSR_GIO_REG,
-               CSR_GP_UCODE_REG,
-               CSR_GP_DRIVER_REG,
-               CSR_UCODE_DRV_GP1,
-               CSR_UCODE_DRV_GP2,
-               CSR_LED_REG,
-               CSR_DRAM_INT_TBL_REG,
-               CSR_GIO_CHICKEN_BITS,
-               CSR_ANA_PLL_CFG,
-               CSR_HW_REV_WA_REG,
-               CSR_DBG_HPET_MEM_REG
-       };
-       IWL_ERR(priv, "CSR values:\n");
-       IWL_ERR(priv, "(2nd byte of CSR_INT_COALESCING is "
-               "CSR_INT_PERIODIC_REG)\n");
-       for (i = 0; i <  ARRAY_SIZE(csr_tbl); i++) {
-               IWL_ERR(priv, "  %25s: 0X%08x\n",
-                       get_csr_string(csr_tbl[i]),
-                       iwl_read32(priv, csr_tbl[i]));
-       }
-}
-EXPORT_SYMBOL(iwl_dump_csr);
-
-static const char *get_fh_string(int cmd)
-{
-       switch (cmd) {
-               IWL_CMD(FH_RSCSR_CHNL0_STTS_WPTR_REG);
-               IWL_CMD(FH_RSCSR_CHNL0_RBDCB_BASE_REG);
-               IWL_CMD(FH_RSCSR_CHNL0_WPTR);
-               IWL_CMD(FH_MEM_RCSR_CHNL0_CONFIG_REG);
-               IWL_CMD(FH_MEM_RSSR_SHARED_CTRL_REG);
-               IWL_CMD(FH_MEM_RSSR_RX_STATUS_REG);
-               IWL_CMD(FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV);
-               IWL_CMD(FH_TSSR_TX_STATUS_REG);
-               IWL_CMD(FH_TSSR_TX_ERROR_REG);
-       default:
-               return "UNKNOWN";
-
-       }
-}
-
-int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display)
-{
-       int i;
-#ifdef CONFIG_IWLWIFI_DEBUG
-       int pos = 0;
-       size_t bufsz = 0;
-#endif
-       u32 fh_tbl[] = {
-               FH_RSCSR_CHNL0_STTS_WPTR_REG,
-               FH_RSCSR_CHNL0_RBDCB_BASE_REG,
-               FH_RSCSR_CHNL0_WPTR,
-               FH_MEM_RCSR_CHNL0_CONFIG_REG,
-               FH_MEM_RSSR_SHARED_CTRL_REG,
-               FH_MEM_RSSR_RX_STATUS_REG,
-               FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV,
-               FH_TSSR_TX_STATUS_REG,
-               FH_TSSR_TX_ERROR_REG
-       };
-#ifdef CONFIG_IWLWIFI_DEBUG
-       if (display) {
-               bufsz = ARRAY_SIZE(fh_tbl) * 48 + 40;
-               *buf = kmalloc(bufsz, GFP_KERNEL);
-               if (!*buf)
-                       return -ENOMEM;
-               pos += scnprintf(*buf + pos, bufsz - pos,
-                               "FH register values:\n");
-               for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) {
-                       pos += scnprintf(*buf + pos, bufsz - pos,
-                               "  %34s: 0X%08x\n",
-                               get_fh_string(fh_tbl[i]),
-                               iwl_read_direct32(priv, fh_tbl[i]));
-               }
-               return pos;
-       }
-#endif
-       IWL_ERR(priv, "FH register values:\n");
-       for (i = 0; i <  ARRAY_SIZE(fh_tbl); i++) {
-               IWL_ERR(priv, "  %34s: 0X%08x\n",
-                       get_fh_string(fh_tbl[i]),
-                       iwl_read_direct32(priv, fh_tbl[i]));
-       }
-       return 0;
-}
-EXPORT_SYMBOL(iwl_dump_fh);
-
 static void iwl_force_rf_reset(struct iwl_priv *priv)
 {
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
@@ -2795,7 +2430,6 @@ int iwl_force_reset(struct iwl_priv *priv, int mode, bool external)
        }
        return 0;
 }
-EXPORT_SYMBOL(iwl_force_reset);
 
 /**
  * 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)
                                        "queue %d, not read %d time\n",
                                        q->id,
                                        q->repeat_same_read_ptr);
-                       if (priv->cfg->bt_params &&
-                           !priv->cfg->bt_params->advanced_bt_coexist) {
-                               mod_timer(&priv->monitor_recover,
-                                       jiffies + msecs_to_jiffies(
-                                       IWL_ONE_HUNDRED_MSECS));
-                               return 1;
-                       }
+                       mod_timer(&priv->monitor_recover,
+                               jiffies + msecs_to_jiffies(
+                               IWL_ONE_HUNDRED_MSECS));
+                       return 1;
                }
        } else {
                q->last_read_ptr = q->read_ptr;
@@ -2964,7 +2595,7 @@ int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
         * it will not call apm_ops.stop() to stop the DMA operation.
         * Calling apm_ops.stop here to make sure we stop the DMA.
         */
-       priv->cfg->ops->lib->apm_ops.stop(priv);
+       iwl_apm_stop(priv);
 
        pci_save_state(pdev);
        pci_disable_device(pdev);
index 6228b1c2ec966487f71a2df350d83db74a4d04ea..64527def059f7de76ac0e4bdcadd0147576805c1 100644 (file)
@@ -112,13 +112,12 @@ struct iwl_hcmd_utils_ops {
        int  (*calc_rssi)(struct iwl_priv *priv,
                          struct iwl_rx_phy_res *rx_resp);
        int (*request_scan)(struct iwl_priv *priv, struct ieee80211_vif *vif);
+       void (*post_scan)(struct iwl_priv *priv);
 };
 
 struct iwl_apm_ops {
        int (*init)(struct iwl_priv *priv);
-       void (*stop)(struct iwl_priv *priv);
        void (*config)(struct iwl_priv *priv);
-       int (*set_pwr_src)(struct iwl_priv *priv, enum iwl_pwr_src src);
 };
 
 struct iwl_debugfs_ops {
@@ -136,7 +135,6 @@ struct iwl_debugfs_ops {
 
 struct iwl_temp_ops {
        void (*temperature)(struct iwl_priv *priv);
-       void (*set_ct_kill)(struct iwl_priv *priv);
 };
 
 struct iwl_tt_ops {
@@ -344,6 +342,7 @@ struct iwl_ht_params {
  * @ucode_api_min: Lowest version of uCode API supported by driver.
  * @pa_type: used by 6000 series only to identify the type of Power Amplifier
  * @need_dc_calib: need to perform init dc calibration
+ * @need_temp_offset_calib: need to perform temperature offset calibration
  * @scan_antennas: available antenna for scan operation
  *
  * We enable the driver to be backward compatible wrt API version. The
@@ -388,6 +387,7 @@ struct iwl_cfg {
        struct iwl_bt_params *bt_params;
        enum iwl_pa_type pa_type;         /* if used set to IWL_PA_SYSTEM */
        const bool need_dc_calib;         /* if used set to true */
+       const bool need_temp_offset_calib; /* if used set to true */
        u8 scan_rx_antennas[IEEE80211_NUM_BANDS];
        u8 scan_tx_antennas[IEEE80211_NUM_BANDS];
 };
@@ -398,7 +398,6 @@ struct iwl_cfg {
 
 struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg,
                struct ieee80211_ops *hw_ops);
-void iwl_activate_qos(struct iwl_priv *priv);
 int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
                    const struct ieee80211_tx_queue_params *params);
 int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw);
@@ -406,7 +405,6 @@ void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
                           int hw_decrypt);
 int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
 int iwl_full_rxon_required(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
-void iwl_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
 int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch,
                         struct iwl_rxon_context *ctx);
 void iwl_set_flags_for_band(struct iwl_priv *priv,
@@ -432,7 +430,6 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
                                     struct ieee80211_vif *vif,
                                     struct ieee80211_bss_conf *bss_conf,
                                     u32 changes);
-int iwl_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
 int iwl_mac_add_interface(struct ieee80211_hw *hw,
                          struct ieee80211_vif *vif);
 void iwl_mac_remove_interface(struct ieee80211_hw *hw,
@@ -509,7 +506,6 @@ void iwl_rx_reply_error(struct iwl_priv *priv,
 ******************************************************/
 void iwl_cmd_queue_free(struct iwl_priv *priv);
 int iwl_rx_queue_alloc(struct iwl_priv *priv);
-void iwl_rx_handle(struct iwl_priv *priv);
 void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv,
                                  struct iwl_rx_queue *q);
 int 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);
 /*****************************************************
 * TX
 ******************************************************/
-void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq);
-int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
-                                struct iwl_tx_queue *txq,
-                                dma_addr_t addr, u16 len, u8 reset, u8 pad);
-int iwl_hw_tx_queue_init(struct iwl_priv *priv,
-                        struct iwl_tx_queue *txq);
 void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq);
 int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
                      int slots_num, u32 txq_id);
@@ -548,31 +538,9 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force);
  * Rate
  ******************************************************************************/
 
-int iwl_hwrate_to_plcp_idx(u32 rate_n_flags);
-
 u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv,
                            struct iwl_rxon_context *ctx);
 
-u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx, u8 valid);
-
-static inline u32 iwl_ant_idx_to_flags(u8 ant_idx)
-{
-       return BIT(ant_idx) << RATE_MCS_ANT_POS;
-}
-
-static inline u8 iwl_hw_get_rate(__le32 rate_n_flags)
-{
-       return le32_to_cpu(rate_n_flags) & 0xFF;
-}
-static inline u32 iwl_hw_get_rate_n_flags(__le32 rate_n_flags)
-{
-       return le32_to_cpu(rate_n_flags) & 0x1FFFF;
-}
-static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags)
-{
-       return cpu_to_le32(flags|(u32)rate);
-}
-
 /*******************************************************************************
  * Scanning
  ******************************************************************************/
@@ -608,13 +576,6 @@ void iwl_cancel_scan_deferred_work(struct iwl_priv *priv);
 
 #define IWL_SCAN_CHECK_WATCHDOG                (HZ * 7)
 
-/*******************************************************************************
- * Calibrations - implemented in iwl-calib.c
- ******************************************************************************/
-int iwl_send_calib_results(struct iwl_priv *priv);
-int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len);
-void iwl_calib_free_results(struct iwl_priv *priv);
-
 /*****************************************************
  *   S e n d i n g     H o s t     C o m m a n d s   *
  *****************************************************/
@@ -664,8 +625,6 @@ int iwl_pci_resume(struct pci_dev *pdev);
 void iwl_dump_nic_error_log(struct iwl_priv *priv);
 int iwl_dump_nic_event_log(struct iwl_priv *priv,
                           bool full_log, char **buf, bool display);
-void iwl_dump_csr(struct iwl_priv *priv);
-int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display);
 #ifdef CONFIG_IWLWIFI_DEBUG
 void iwl_print_rx_config_cmd(struct iwl_priv *priv,
                             struct iwl_rxon_context *ctx);
@@ -751,8 +710,6 @@ static inline int iwl_is_ready_rf(struct iwl_priv *priv)
 extern void iwl_send_bt_config(struct iwl_priv *priv);
 extern int iwl_send_statistics_request(struct iwl_priv *priv,
                                       u8 flags, bool clear);
-extern int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
-               struct iwl_link_quality_cmd *lq, u8 flags, bool init);
 void iwl_apm_stop(struct iwl_priv *priv);
 int iwl_apm_init(struct iwl_priv *priv);
 
index fc340311ea0a81cc89ccf56387168bfc441b0600..96d9085639e30b46c5332bb182cf0dc62c6cec85 100644 (file)
@@ -39,7 +39,6 @@
 #include "iwl-debug.h"
 #include "iwl-core.h"
 #include "iwl-io.h"
-#include "iwl-calib.h"
 
 /* create and remove of files */
 #define DEBUGFS_ADD_FILE(name, parent, mode) do {                      \
index 90a37a94c69876c034ba168437fb764912445ef3..70e07fa48405b5558a4cb95a6535178cb7265f1f 100644 (file)
@@ -282,13 +282,6 @@ struct iwl_channel_info {
  */
 #define IWL_IPAN_MCAST_QUEUE           8
 
-/* Power management (not Tx power) structures */
-
-enum iwl_pwr_src {
-       IWL_PWR_SRC_VMAIN,
-       IWL_PWR_SRC_VAUX,
-};
-
 #define IEEE80211_DATA_LEN              2304
 #define IEEE80211_4ADDR_LEN             30
 #define IEEE80211_HLEN                  (IEEE80211_4ADDR_LEN)
@@ -732,7 +725,6 @@ struct iwl_hw_params {
  *
  ****************************************************************************/
 extern void iwl_update_chain_flags(struct iwl_priv *priv);
-extern int iwl_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src);
 extern const u8 iwl_bcast_addr[ETH_ALEN];
 extern int iwl_rxq_stop(struct iwl_priv *priv);
 extern void iwl_txq_ctx_stop(struct iwl_priv *priv);
@@ -843,6 +835,7 @@ enum iwl_calib {
        IWL_CALIB_TX_IQ,
        IWL_CALIB_TX_IQ_PERD,
        IWL_CALIB_BASE_BAND,
+       IWL_CALIB_TEMP_OFFSET,
        IWL_CALIB_MAX
 };
 
@@ -1390,8 +1383,6 @@ struct iwl_priv {
 
        enum nl80211_iftype iw_mode;
 
-       struct sk_buff *ibss_beacon;
-
        /* Last Rx'd beacon timestamp */
        u64 timestamp;
 
@@ -1503,8 +1494,10 @@ struct iwl_priv {
        struct work_struct scan_completed;
        struct work_struct rx_replenish;
        struct work_struct abort_scan;
+
        struct work_struct beacon_update;
        struct iwl_rxon_context *beacon_ctx;
+       struct sk_buff *beacon_skb;
 
        struct work_struct tt_work;
        struct work_struct ct_enter;
@@ -1566,7 +1559,6 @@ static inline void iwl_txq_ctx_deactivate(struct iwl_priv *priv, int txq_id)
 }
 
 #ifdef CONFIG_IWLWIFI_DEBUG
-const char *iwl_get_tx_fail_reason(u32 status);
 /*
  * iwl_get_debug_level: Return active debug level for device
  *
@@ -1582,8 +1574,6 @@ static inline u32 iwl_get_debug_level(struct iwl_priv *priv)
                return iwl_debug_level;
 }
 #else
-static inline const char *iwl_get_tx_fail_reason(u32 status) { return ""; }
-
 static inline u32 iwl_get_debug_level(struct iwl_priv *priv)
 {
        return iwl_debug_level;
index 88f4a80d4733bafff85a1894db1a7d690f62ea2f..87cd10ff285d0800dd0b575324a41553dab59110 100644 (file)
@@ -136,85 +136,13 @@ static const u8 iwl_eeprom_band_7[] = {       /* 5.2 ht40 channel */
        36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157
 };
 
-/**
- * struct iwl_txpwr_section: eeprom section information
- * @offset: indirect address into eeprom image
- * @count: number of "struct iwl_eeprom_enhanced_txpwr" in this section
- * @band: band type for the section
- * @is_common - true: common section, false: channel section
- * @is_cck - true: cck section, false: not cck section
- * @is_ht_40 - true: all channel in the section are HT40 channel,
- *            false: legacy or HT 20 MHz
- *            ignore if it is common section
- * @iwl_eeprom_section_channel: channel array in the section,
- *            ignore if common section
- */
-struct iwl_txpwr_section {
-       u32 offset;
-       u8 count;
-       enum ieee80211_band band;
-       bool is_common;
-       bool is_cck;
-       bool is_ht40;
-       u8 iwl_eeprom_section_channel[EEPROM_MAX_TXPOWER_SECTION_ELEMENTS];
-};
-
-/**
- * section 1 - 3 are regulatory tx power apply to all channels based on
- *    modulation: CCK, OFDM
- *    Band: 2.4GHz, 5.2GHz
- * section 4 - 10 are regulatory tx power apply to specified channels
- *    For example:
- *     1L - Channel 1 Legacy
- *     1HT - Channel 1 HT
- *     (1,+1) - Channel 1 HT40 "_above_"
- *
- * Section 1: all CCK channels
- * Section 2: all 2.4 GHz OFDM (Legacy, HT and HT40) channels
- * Section 3: all 5.2 GHz OFDM (Legacy, HT and HT40) channels
- * Section 4: 2.4 GHz 20MHz channels: 1L, 1HT, 2L, 2HT, 10L, 10HT, 11L, 11HT
- * Section 5: 2.4 GHz 40MHz channels: (1,+1) (2,+1) (6,+1) (7,+1) (9,+1)
- * Section 6: 5.2 GHz 20MHz channels: 36L, 64L, 100L, 36HT, 64HT, 100HT
- * Section 7: 5.2 GHz 40MHz channels: (36,+1) (60,+1) (100,+1)
- * Section 8: 2.4 GHz channel: 13L, 13HT
- * Section 9: 2.4 GHz channel: 140L, 140HT
- * Section 10: 2.4 GHz 40MHz channels: (132,+1)  (44,+1)
- *
- */
-static const struct iwl_txpwr_section enhinfo[] = {
-       { EEPROM_LB_CCK_20_COMMON, 1, IEEE80211_BAND_2GHZ, true, true, false },
-       { EEPROM_LB_OFDM_COMMON, 3, IEEE80211_BAND_2GHZ, true, false, false },
-       { EEPROM_HB_OFDM_COMMON, 3, IEEE80211_BAND_5GHZ, true, false, false },
-       { EEPROM_LB_OFDM_20_BAND, 8, IEEE80211_BAND_2GHZ,
-               false, false, false,
-               {1, 1, 2, 2, 10, 10, 11, 11 } },
-       { EEPROM_LB_OFDM_HT40_BAND, 5, IEEE80211_BAND_2GHZ,
-               false, false, true,
-               { 1, 2, 6, 7, 9 } },
-       { EEPROM_HB_OFDM_20_BAND, 6, IEEE80211_BAND_5GHZ,
-               false, false, false,
-               { 36, 64, 100, 36, 64, 100 } },
-       { EEPROM_HB_OFDM_HT40_BAND, 3, IEEE80211_BAND_5GHZ,
-               false, false, true,
-               { 36, 60, 100 } },
-       { EEPROM_LB_OFDM_20_CHANNEL_13, 2, IEEE80211_BAND_2GHZ,
-               false, false, false,
-               { 13, 13 } },
-       { EEPROM_HB_OFDM_20_CHANNEL_140, 2, IEEE80211_BAND_5GHZ,
-               false, false, false,
-               { 140, 140 } },
-       { EEPROM_HB_OFDM_HT40_BAND_1, 2, IEEE80211_BAND_5GHZ,
-               false, false, true,
-               { 132, 44 } },
-};
-
 /******************************************************************************
  *
  * EEPROM related functions
  *
 ******************************************************************************/
 
-int iwlcore_eeprom_verify_signature(struct iwl_priv *priv)
+static int iwl_eeprom_verify_signature(struct iwl_priv *priv)
 {
        u32 gp = iwl_read32(priv, CSR_EEPROM_GP) & CSR_EEPROM_GP_VALID_MSK;
        int ret = 0;
@@ -246,7 +174,6 @@ int iwlcore_eeprom_verify_signature(struct iwl_priv *priv)
        }
        return ret;
 }
-EXPORT_SYMBOL(iwlcore_eeprom_verify_signature);
 
 static void iwl_set_otp_access(struct iwl_priv *priv, enum iwl_access_mode mode)
 {
@@ -290,46 +217,6 @@ static int iwlcore_get_nvm_type(struct iwl_priv *priv)
        return  nvm_type;
 }
 
-/*
- * The device's EEPROM semaphore prevents conflicts between driver and uCode
- * when accessing the EEPROM; each access is a series of pulses to/from the
- * EEPROM chip, not a single event, so even reads could conflict if they
- * weren't arbitrated by the semaphore.
- */
-int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv)
-{
-       u16 count;
-       int ret;
-
-       for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) {
-               /* Request semaphore */
-               iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
-                           CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
-
-               /* See if we got it */
-               ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG,
-                               CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
-                               CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
-                               EEPROM_SEM_TIMEOUT);
-               if (ret >= 0) {
-                       IWL_DEBUG_IO(priv, "Acquired semaphore after %d tries.\n",
-                               count+1);
-                       return ret;
-               }
-       }
-
-       return ret;
-}
-EXPORT_SYMBOL(iwlcore_eeprom_acquire_semaphore);
-
-void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv)
-{
-       iwl_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
-               CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
-
-}
-EXPORT_SYMBOL(iwlcore_eeprom_release_semaphore);
-
 const u8 *iwlcore_eeprom_query_addr(const struct iwl_priv *priv, size_t offset)
 {
        BUG_ON(offset >= priv->cfg->base_params->eeprom_size);
@@ -491,6 +378,20 @@ static int iwl_find_otp_image(struct iwl_priv *priv,
        return -EINVAL;
 }
 
+const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset)
+{
+       return priv->cfg->ops->lib->eeprom_ops.query_addr(priv, offset);
+}
+EXPORT_SYMBOL(iwl_eeprom_query_addr);
+
+u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset)
+{
+       if (!priv->eeprom)
+               return 0;
+       return (u16)priv->eeprom[offset] | ((u16)priv->eeprom[offset + 1] << 8);
+}
+EXPORT_SYMBOL(iwl_eeprom_query16);
+
 /**
  * iwl_eeprom_init - read EEPROM contents
  *
@@ -523,7 +424,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
 
        priv->cfg->ops->lib->apm_ops.init(priv);
 
-       ret = priv->cfg->ops->lib->eeprom_ops.verify_signature(priv);
+       ret = iwl_eeprom_verify_signature(priv);
        if (ret < 0) {
                IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp);
                ret = -ENOENT;
@@ -604,7 +505,7 @@ err:
        if (ret)
                iwl_eeprom_free(priv);
        /* Reset chip to save power until we load uCode during "up". */
-       priv->cfg->ops->lib->apm_ops.stop(priv);
+       iwl_apm_stop(priv);
 alloc_err:
        return ret;
 }
@@ -617,53 +518,6 @@ void iwl_eeprom_free(struct iwl_priv *priv)
 }
 EXPORT_SYMBOL(iwl_eeprom_free);
 
-int iwl_eeprom_check_version(struct iwl_priv *priv)
-{
-       u16 eeprom_ver;
-       u16 calib_ver;
-
-       eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
-       calib_ver = priv->cfg->ops->lib->eeprom_ops.calib_version(priv);
-
-       if (eeprom_ver < priv->cfg->eeprom_ver ||
-           calib_ver < priv->cfg->eeprom_calib_ver)
-               goto err;
-
-       IWL_INFO(priv, "device EEPROM VER=0x%x, CALIB=0x%x\n",
-                eeprom_ver, calib_ver);
-
-       return 0;
-err:
-       IWL_ERR(priv, "Unsupported (too old) EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n",
-                 eeprom_ver, priv->cfg->eeprom_ver,
-                 calib_ver,  priv->cfg->eeprom_calib_ver);
-       return -EINVAL;
-
-}
-EXPORT_SYMBOL(iwl_eeprom_check_version);
-
-const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset)
-{
-       return priv->cfg->ops->lib->eeprom_ops.query_addr(priv, offset);
-}
-EXPORT_SYMBOL(iwl_eeprom_query_addr);
-
-u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset)
-{
-       if (!priv->eeprom)
-               return 0;
-       return (u16)priv->eeprom[offset] | ((u16)priv->eeprom[offset + 1] << 8);
-}
-EXPORT_SYMBOL(iwl_eeprom_query16);
-
-void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac)
-{
-       const u8 *addr = priv->cfg->ops->lib->eeprom_ops.query_addr(priv,
-                                       EEPROM_MAC_ADDRESS);
-       memcpy(mac, addr, ETH_ALEN);
-}
-EXPORT_SYMBOL(iwl_eeprom_get_mac);
-
 static void iwl_init_band_reference(const struct iwl_priv *priv,
                        int eep_band, int *eeprom_ch_count,
                        const struct iwl_eeprom_channel **eeprom_ch_info,
@@ -722,7 +576,6 @@ static void iwl_init_band_reference(const struct iwl_priv *priv,
 
 #define CHECK_AND_PRINT(x) ((eeprom_ch->flags & EEPROM_CHANNEL_##x) \
                            ? # x " " : "")
-
 /**
  * iwl_mod_ht40_chan_info - Copy ht40 channel info into driver's priv.
  *
@@ -766,205 +619,6 @@ static int iwl_mod_ht40_chan_info(struct iwl_priv *priv,
        return 0;
 }
 
-/**
- * iwl_get_max_txpower_avg - get the highest tx power from all chains.
- *     find the highest tx power from all chains for the channel
- */
-static s8 iwl_get_max_txpower_avg(struct iwl_priv *priv,
-               struct iwl_eeprom_enhanced_txpwr *enhanced_txpower,
-               int element, s8 *max_txpower_in_half_dbm)
-{
-       s8 max_txpower_avg = 0; /* (dBm) */
-
-       IWL_DEBUG_INFO(priv, "%d - "
-                       "chain_a: %d dB chain_b: %d dB "
-                       "chain_c: %d dB mimo2: %d dB mimo3: %d dB\n",
-                       element,
-                       enhanced_txpower[element].chain_a_max >> 1,
-                       enhanced_txpower[element].chain_b_max >> 1,
-                       enhanced_txpower[element].chain_c_max >> 1,
-                       enhanced_txpower[element].mimo2_max >> 1,
-                       enhanced_txpower[element].mimo3_max >> 1);
-       /* Take the highest tx power from any valid chains */
-       if ((priv->cfg->valid_tx_ant & ANT_A) &&
-           (enhanced_txpower[element].chain_a_max > max_txpower_avg))
-               max_txpower_avg = enhanced_txpower[element].chain_a_max;
-       if ((priv->cfg->valid_tx_ant & ANT_B) &&
-           (enhanced_txpower[element].chain_b_max > max_txpower_avg))
-               max_txpower_avg = enhanced_txpower[element].chain_b_max;
-       if ((priv->cfg->valid_tx_ant & ANT_C) &&
-           (enhanced_txpower[element].chain_c_max > max_txpower_avg))
-               max_txpower_avg = enhanced_txpower[element].chain_c_max;
-       if (((priv->cfg->valid_tx_ant == ANT_AB) |
-           (priv->cfg->valid_tx_ant == ANT_BC) |
-           (priv->cfg->valid_tx_ant == ANT_AC)) &&
-           (enhanced_txpower[element].mimo2_max > max_txpower_avg))
-               max_txpower_avg =  enhanced_txpower[element].mimo2_max;
-       if ((priv->cfg->valid_tx_ant == ANT_ABC) &&
-           (enhanced_txpower[element].mimo3_max > max_txpower_avg))
-               max_txpower_avg = enhanced_txpower[element].mimo3_max;
-
-       /*
-        * max. tx power in EEPROM is in 1/2 dBm format
-        * convert from 1/2 dBm to dBm (round-up convert)
-        * but we also do not want to loss 1/2 dBm resolution which
-        * will impact performance
-        */
-       *max_txpower_in_half_dbm = max_txpower_avg;
-       return (max_txpower_avg & 0x01) + (max_txpower_avg >> 1);
-}
-
-/**
- * iwl_update_common_txpower: update channel tx power
- *     update tx power per band based on EEPROM enhanced tx power info.
- */
-static s8 iwl_update_common_txpower(struct iwl_priv *priv,
-               struct iwl_eeprom_enhanced_txpwr *enhanced_txpower,
-               int section, int element, s8 *max_txpower_in_half_dbm)
-{
-       struct iwl_channel_info *ch_info;
-       int ch;
-       bool is_ht40 = false;
-       s8 max_txpower_avg; /* (dBm) */
-
-       /* it is common section, contain all type (Legacy, HT and HT40)
-        * based on the element in the section to determine
-        * is it HT 40 or not
-        */
-       if (element == EEPROM_TXPOWER_COMMON_HT40_INDEX)
-               is_ht40 = true;
-       max_txpower_avg =
-               iwl_get_max_txpower_avg(priv, enhanced_txpower,
-                                       element, max_txpower_in_half_dbm);
-
-       ch_info = priv->channel_info;
-
-       for (ch = 0; ch < priv->channel_count; ch++) {
-               /* find matching band and update tx power if needed */
-               if ((ch_info->band == enhinfo[section].band) &&
-                   (ch_info->max_power_avg < max_txpower_avg) &&
-                   (!is_ht40)) {
-                       /* Update regulatory-based run-time data */
-                       ch_info->max_power_avg = ch_info->curr_txpow =
-                               max_txpower_avg;
-                       ch_info->scan_power = max_txpower_avg;
-               }
-               if ((ch_info->band == enhinfo[section].band) && is_ht40 &&
-                   (ch_info->ht40_max_power_avg < max_txpower_avg)) {
-                       /* Update regulatory-based run-time data */
-                       ch_info->ht40_max_power_avg = max_txpower_avg;
-               }
-               ch_info++;
-       }
-       return max_txpower_avg;
-}
-
-/**
- * iwl_update_channel_txpower: update channel tx power
- *      update channel tx power based on EEPROM enhanced tx power info.
- */
-static s8 iwl_update_channel_txpower(struct iwl_priv *priv,
-               struct iwl_eeprom_enhanced_txpwr *enhanced_txpower,
-               int section, int element, s8 *max_txpower_in_half_dbm)
-{
-       struct iwl_channel_info *ch_info;
-       int ch;
-       u8 channel;
-       s8 max_txpower_avg; /* (dBm) */
-
-       channel = enhinfo[section].iwl_eeprom_section_channel[element];
-       max_txpower_avg =
-               iwl_get_max_txpower_avg(priv, enhanced_txpower,
-                                       element, max_txpower_in_half_dbm);
-
-       ch_info = priv->channel_info;
-       for (ch = 0; ch < priv->channel_count; ch++) {
-               /* find matching channel and update tx power if needed */
-               if (ch_info->channel == channel) {
-                       if ((ch_info->max_power_avg < max_txpower_avg) &&
-                           (!enhinfo[section].is_ht40)) {
-                               /* Update regulatory-based run-time data */
-                               ch_info->max_power_avg = max_txpower_avg;
-                               ch_info->curr_txpow = max_txpower_avg;
-                               ch_info->scan_power = max_txpower_avg;
-                       }
-                       if ((enhinfo[section].is_ht40) &&
-                           (ch_info->ht40_max_power_avg < max_txpower_avg)) {
-                               /* Update regulatory-based run-time data */
-                               ch_info->ht40_max_power_avg = max_txpower_avg;
-                       }
-                       break;
-               }
-               ch_info++;
-       }
-       return max_txpower_avg;
-}
-
-/**
- * iwlcore_eeprom_enhanced_txpower: process enhanced tx power info
- */
-void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv)
-{
-       int eeprom_section_count = 0;
-       int section, element;
-       struct iwl_eeprom_enhanced_txpwr *enhanced_txpower;
-       u32 offset;
-       s8 max_txpower_avg; /* (dBm) */
-       s8 max_txpower_in_half_dbm; /* (half-dBm) */
-
-       /* Loop through all the sections
-        * adjust bands and channel's max tx power
-        * Set the tx_power_user_lmt to the highest power
-        * supported by any channels and chains
-        */
-       for (section = 0; section < ARRAY_SIZE(enhinfo); section++) {
-               eeprom_section_count = enhinfo[section].count;
-               offset = enhinfo[section].offset;
-               enhanced_txpower = (struct iwl_eeprom_enhanced_txpwr *)
-                               iwl_eeprom_query_addr(priv, offset);
-
-               /*
-                * check for valid entry -
-                * different version of EEPROM might contain different set
-                * of enhanced tx power table
-                * always check for valid entry before process
-                * the information
-                */
-               if (!enhanced_txpower->common || enhanced_txpower->reserved)
-                       continue;
-
-               for (element = 0; element < eeprom_section_count; element++) {
-                       if (enhinfo[section].is_common)
-                               max_txpower_avg =
-                                       iwl_update_common_txpower(priv,
-                                               enhanced_txpower, section,
-                                               element,
-                                               &max_txpower_in_half_dbm);
-                       else
-                               max_txpower_avg =
-                                       iwl_update_channel_txpower(priv,
-                                               enhanced_txpower, section,
-                                               element,
-                                               &max_txpower_in_half_dbm);
-
-                       /* Update the tx_power_user_lmt to the highest power
-                        * supported by any channel */
-                       if (max_txpower_avg > priv->tx_power_user_lmt)
-                               priv->tx_power_user_lmt = max_txpower_avg;
-
-                       /*
-                        * Update the tx_power_lmt_in_half_dbm to
-                        * the highest power supported by any channel
-                        */
-                       if (max_txpower_in_half_dbm >
-                           priv->tx_power_lmt_in_half_dbm)
-                               priv->tx_power_lmt_in_half_dbm =
-                                       max_txpower_in_half_dbm;
-               }
-       }
-}
-EXPORT_SYMBOL(iwlcore_eeprom_enhanced_txpower);
-
 #define CHECK_AND_PRINT_I(x) ((eeprom_ch_info[ch].flags & EEPROM_CHANNEL_##x) \
                            ? # x " " : "")
 
@@ -1162,4 +816,3 @@ const struct iwl_channel_info *iwl_get_channel_info(const struct iwl_priv *priv,
        return NULL;
 }
 EXPORT_SYMBOL(iwl_get_channel_info);
-
index a4772aff51fe0479fc5e522a4a1c59df18a68de2..d9b590625ae4eb16ba996d0bbd8d794acc30dae9 100644 (file)
@@ -493,7 +493,6 @@ struct iwl_eeprom_calib_info {
 
 struct iwl_eeprom_ops {
        const u32 regulatory_bands[7];
-       int (*verify_signature) (struct iwl_priv *priv);
        int (*acquire_semaphore) (struct iwl_priv *priv);
        void (*release_semaphore) (struct iwl_priv *priv);
        u16 (*calib_version) (struct iwl_priv *priv);
@@ -502,18 +501,13 @@ struct iwl_eeprom_ops {
 };
 
 
-void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac);
 int iwl_eeprom_init(struct iwl_priv *priv);
 void iwl_eeprom_free(struct iwl_priv *priv);
 int  iwl_eeprom_check_version(struct iwl_priv *priv);
 const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset);
-u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset);
-
 int iwlcore_eeprom_verify_signature(struct iwl_priv *priv);
-int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv);
-void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv);
+u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset);
 const u8 *iwlcore_eeprom_query_addr(const struct iwl_priv *priv, size_t offset);
-void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv);
 int iwl_init_channel_map(struct iwl_priv *priv);
 void iwl_free_channel_map(struct iwl_priv *priv);
 const struct iwl_channel_info *iwl_get_channel_info(
index 621abe3c5afce3fc2b73b66e37c82c7b4d8fcf66..1aaef70deaecf58d85c7fac8d218578dee97c025 100644 (file)
@@ -44,11 +44,6 @@ static inline struct ieee80211_conf *ieee80211_get_hw_conf(
        return &hw->conf;
 }
 
-static inline int iwl_check_bits(unsigned long field, unsigned long mask)
-{
-       return ((field & mask) == mask) ? 1 : 0;
-}
-
 static inline unsigned long elapsed_jiffies(unsigned long start,
                                            unsigned long end)
 {
index 10be197b0f2294b92643baf5a96d4ebd141552c7..f436270ca39af6adb3290a137cd68a84138d4835 100644 (file)
@@ -36,7 +36,6 @@
 #include "iwl-core.h"
 #include "iwl-sta.h"
 #include "iwl-io.h"
-#include "iwl-calib.h"
 #include "iwl-helpers.h"
 /************************** RX-FUNCTIONS ****************************/
 /*
index eaae49ee0c60a1e36e564911bf4bf507fe5053b0..67da31295781192a6e8446e46634772426735949 100644 (file)
@@ -121,7 +121,6 @@ void iwl_force_scan_end(struct iwl_priv *priv)
        clear_bit(STATUS_SCAN_ABORTING, &priv->status);
        iwl_complete_scan(priv, true);
 }
-EXPORT_SYMBOL(iwl_force_scan_end);
 
 static void iwl_do_scan_abort(struct iwl_priv *priv)
 {
@@ -559,7 +558,6 @@ static void iwl_bg_scan_completed(struct work_struct *work)
        struct iwl_priv *priv =
            container_of(work, struct iwl_priv, scan_completed);
        bool aborted;
-       struct iwl_rxon_context *ctx;
 
        IWL_DEBUG_SCAN(priv, "Completed %sscan.\n",
                       priv->is_internal_short_scan ? "internal short " : "");
@@ -609,15 +607,7 @@ out_settings:
         * performing the scan, fire one off */
        iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);
 
-       /*
-        * Since setting the RXON may have been deferred while
-        * performing the scan, fire one off if needed
-        */
-       for_each_context(priv, ctx)
-               iwlcore_commit_rxon(priv, ctx);
-
-       if (priv->cfg->ops->hcmd->set_pan_params)
-               priv->cfg->ops->hcmd->set_pan_params(priv);
+       priv->cfg->ops->utils->post_scan(priv);
 
  out:
        mutex_unlock(&priv->mutex);
index 6edd0341dfe2b1572ab0e888c482e3855e8ee8d0..7c7f7dcb1b1e190611a8134177966729cf04d60e 100644 (file)
@@ -228,9 +228,8 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
  *
  * should be called with sta_lock held
  */
-static u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
-                          const u8 *addr, bool is_ap,
-                          struct ieee80211_sta *sta)
+u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+                   const u8 *addr, bool is_ap, struct ieee80211_sta *sta)
 {
        struct iwl_station_entry *station;
        int i;
@@ -317,6 +316,7 @@ static u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
        return sta_id;
 
 }
+EXPORT_SYMBOL_GPL(iwl_prep_station);
 
 #define STA_WAIT_TIMEOUT (HZ/2)
 
@@ -381,108 +381,6 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
 }
 EXPORT_SYMBOL(iwl_add_station_common);
 
-static struct iwl_link_quality_cmd *iwl_sta_alloc_lq(struct iwl_priv *priv,
-                                                    u8 sta_id)
-{
-       int i, r;
-       struct iwl_link_quality_cmd *link_cmd;
-       u32 rate_flags = 0;
-       __le32 rate_n_flags;
-
-       link_cmd = kzalloc(sizeof(struct iwl_link_quality_cmd), GFP_KERNEL);
-       if (!link_cmd) {
-               IWL_ERR(priv, "Unable to allocate memory for LQ cmd.\n");
-               return NULL;
-       }
-       /* Set up the rate scaling to start at selected rate, fall back
-        * all the way down to 1M in IEEE order, and then spin on 1M */
-       if (priv->band == IEEE80211_BAND_5GHZ)
-               r = IWL_RATE_6M_INDEX;
-       else
-               r = IWL_RATE_1M_INDEX;
-
-       if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE)
-               rate_flags |= RATE_MCS_CCK_MSK;
-
-       rate_flags |= first_antenna(priv->hw_params.valid_tx_ant) <<
-                               RATE_MCS_ANT_POS;
-       rate_n_flags = iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags);
-       for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++)
-               link_cmd->rs_table[i].rate_n_flags = rate_n_flags;
-
-       link_cmd->general_params.single_stream_ant_msk =
-                               first_antenna(priv->hw_params.valid_tx_ant);
-
-       link_cmd->general_params.dual_stream_ant_msk =
-               priv->hw_params.valid_tx_ant &
-               ~first_antenna(priv->hw_params.valid_tx_ant);
-       if (!link_cmd->general_params.dual_stream_ant_msk) {
-               link_cmd->general_params.dual_stream_ant_msk = ANT_AB;
-       } else if (num_of_ant(priv->hw_params.valid_tx_ant) == 2) {
-               link_cmd->general_params.dual_stream_ant_msk =
-                       priv->hw_params.valid_tx_ant;
-       }
-
-       link_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
-       link_cmd->agg_params.agg_time_limit =
-               cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
-
-       link_cmd->sta_id = sta_id;
-
-       return link_cmd;
-}
-
-/*
- * iwl_add_bssid_station - Add the special IBSS BSSID station
- *
- * Function sleeps.
- */
-int iwl_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
-                         const u8 *addr, bool init_rs, u8 *sta_id_r)
-{
-       int ret;
-       u8 sta_id;
-       struct iwl_link_quality_cmd *link_cmd;
-       unsigned long flags;
-
-       if (sta_id_r)
-               *sta_id_r = IWL_INVALID_STATION;
-
-       ret = iwl_add_station_common(priv, ctx, addr, 0, NULL, &sta_id);
-       if (ret) {
-               IWL_ERR(priv, "Unable to add station %pM\n", addr);
-               return ret;
-       }
-
-       if (sta_id_r)
-               *sta_id_r = sta_id;
-
-       spin_lock_irqsave(&priv->sta_lock, flags);
-       priv->stations[sta_id].used |= IWL_STA_LOCAL;
-       spin_unlock_irqrestore(&priv->sta_lock, flags);
-
-       if (init_rs) {
-               /* Set up default rate scaling table in device's station table */
-               link_cmd = iwl_sta_alloc_lq(priv, sta_id);
-               if (!link_cmd) {
-                       IWL_ERR(priv, "Unable to initialize rate scaling for station %pM.\n",
-                               addr);
-                       return -ENOMEM;
-               }
-
-               ret = iwl_send_lq_cmd(priv, ctx, link_cmd, CMD_SYNC, true);
-               if (ret)
-                       IWL_ERR(priv, "Link quality command failed (%d)\n", ret);
-
-               spin_lock_irqsave(&priv->sta_lock, flags);
-               priv->stations[sta_id].lq = link_cmd;
-               spin_unlock_irqrestore(&priv->sta_lock, flags);
-       }
-
-       return 0;
-}
-EXPORT_SYMBOL(iwl_add_bssid_station);
-
 /**
  * iwl_sta_ucode_deactivate - deactivate ucode status for a station
  *
@@ -738,405 +636,25 @@ int iwl_get_free_ucode_key_index(struct iwl_priv *priv)
 }
 EXPORT_SYMBOL(iwl_get_free_ucode_key_index);
 
-static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv,
-                                     struct iwl_rxon_context *ctx,
-                                     bool send_if_empty)
-{
-       int i, not_empty = 0;
-       u8 buff[sizeof(struct iwl_wep_cmd) +
-               sizeof(struct iwl_wep_key) * WEP_KEYS_MAX];
-       struct iwl_wep_cmd *wep_cmd = (struct iwl_wep_cmd *)buff;
-       size_t cmd_size  = sizeof(struct iwl_wep_cmd);
-       struct iwl_host_cmd cmd = {
-               .id = ctx->wep_key_cmd,
-               .data = wep_cmd,
-               .flags = CMD_SYNC,
-       };
-
-       might_sleep();
-
-       memset(wep_cmd, 0, cmd_size +
-                       (sizeof(struct iwl_wep_key) * WEP_KEYS_MAX));
-
-       for (i = 0; i < WEP_KEYS_MAX ; i++) {
-               wep_cmd->key[i].key_index = i;
-               if (ctx->wep_keys[i].key_size) {
-                       wep_cmd->key[i].key_offset = i;
-                       not_empty = 1;
-               } else {
-                       wep_cmd->key[i].key_offset = WEP_INVALID_OFFSET;
-               }
-
-               wep_cmd->key[i].key_size = ctx->wep_keys[i].key_size;
-               memcpy(&wep_cmd->key[i].key[3], ctx->wep_keys[i].key,
-                               ctx->wep_keys[i].key_size);
-       }
-
-       wep_cmd->global_key_type = WEP_KEY_WEP_TYPE;
-       wep_cmd->num_keys = WEP_KEYS_MAX;
-
-       cmd_size += sizeof(struct iwl_wep_key) * WEP_KEYS_MAX;
-
-       cmd.len = cmd_size;
-
-       if (not_empty || send_if_empty)
-               return iwl_send_cmd(priv, &cmd);
-       else
-               return 0;
-}
-
-int iwl_restore_default_wep_keys(struct iwl_priv *priv,
-                                struct iwl_rxon_context *ctx)
-{
-       lockdep_assert_held(&priv->mutex);
-
-       return iwl_send_static_wepkey_cmd(priv, ctx, false);
-}
-EXPORT_SYMBOL(iwl_restore_default_wep_keys);
-
-int iwl_remove_default_wep_key(struct iwl_priv *priv,
-                              struct iwl_rxon_context *ctx,
-                              struct ieee80211_key_conf *keyconf)
-{
-       int ret;
-
-       lockdep_assert_held(&priv->mutex);
-
-       IWL_DEBUG_WEP(priv, "Removing default WEP key: idx=%d\n",
-                     keyconf->keyidx);
-
-       memset(&ctx->wep_keys[keyconf->keyidx], 0, sizeof(ctx->wep_keys[0]));
-       if (iwl_is_rfkill(priv)) {
-               IWL_DEBUG_WEP(priv, "Not sending REPLY_WEPKEY command due to RFKILL.\n");
-               /* but keys in device are clear anyway so return success */
-               return 0;
-       }
-       ret = iwl_send_static_wepkey_cmd(priv, ctx, 1);
-       IWL_DEBUG_WEP(priv, "Remove default WEP key: idx=%d ret=%d\n",
-                     keyconf->keyidx, ret);
-
-       return ret;
-}
-EXPORT_SYMBOL(iwl_remove_default_wep_key);
-
-int iwl_set_default_wep_key(struct iwl_priv *priv,
-                           struct iwl_rxon_context *ctx,
-                           struct ieee80211_key_conf *keyconf)
-{
-       int ret;
-
-       lockdep_assert_held(&priv->mutex);
-
-       if (keyconf->keylen != WEP_KEY_LEN_128 &&
-           keyconf->keylen != WEP_KEY_LEN_64) {
-               IWL_DEBUG_WEP(priv, "Bad WEP key length %d\n", keyconf->keylen);
-               return -EINVAL;
-       }
-
-       keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV;
-       keyconf->hw_key_idx = HW_KEY_DEFAULT;
-       priv->stations[ctx->ap_sta_id].keyinfo.cipher = keyconf->cipher;
-
-       ctx->wep_keys[keyconf->keyidx].key_size = keyconf->keylen;
-       memcpy(&ctx->wep_keys[keyconf->keyidx].key, &keyconf->key,
-                                                       keyconf->keylen);
-
-       ret = iwl_send_static_wepkey_cmd(priv, ctx, false);
-       IWL_DEBUG_WEP(priv, "Set default WEP key: len=%d idx=%d ret=%d\n",
-               keyconf->keylen, keyconf->keyidx, ret);
-
-       return ret;
-}
-EXPORT_SYMBOL(iwl_set_default_wep_key);
-
-static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv,
-                                       struct iwl_rxon_context *ctx,
-                                       struct ieee80211_key_conf *keyconf,
-                                       u8 sta_id)
-{
-       unsigned long flags;
-       __le16 key_flags = 0;
-       struct iwl_addsta_cmd sta_cmd;
-
-       lockdep_assert_held(&priv->mutex);
-
-       keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV;
-
-       key_flags |= (STA_KEY_FLG_WEP | STA_KEY_FLG_MAP_KEY_MSK);
-       key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
-       key_flags &= ~STA_KEY_FLG_INVALID;
-
-       if (keyconf->keylen == WEP_KEY_LEN_128)
-               key_flags |= STA_KEY_FLG_KEY_SIZE_MSK;
-
-       if (sta_id == ctx->bcast_sta_id)
-               key_flags |= STA_KEY_MULTICAST_MSK;
-
-       spin_lock_irqsave(&priv->sta_lock, flags);
-
-       priv->stations[sta_id].keyinfo.cipher = keyconf->cipher;
-       priv->stations[sta_id].keyinfo.keylen = keyconf->keylen;
-       priv->stations[sta_id].keyinfo.keyidx = keyconf->keyidx;
-
-       memcpy(priv->stations[sta_id].keyinfo.key,
-                               keyconf->key, keyconf->keylen);
-
-       memcpy(&priv->stations[sta_id].sta.key.key[3],
-                               keyconf->key, keyconf->keylen);
-
-       if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
-                       == STA_KEY_FLG_NO_ENC)
-               priv->stations[sta_id].sta.key.key_offset =
-                                iwl_get_free_ucode_key_index(priv);
-       /* else, we are overriding an existing key => no need to allocated room
-        * in uCode. */
-
-       WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
-               "no space for a new key");
-
-       priv->stations[sta_id].sta.key.key_flags = key_flags;
-       priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
-       priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
-
-       memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
-       spin_unlock_irqrestore(&priv->sta_lock, flags);
-
-       return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
-}
-
-static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
-                                        struct iwl_rxon_context *ctx,
-                                        struct ieee80211_key_conf *keyconf,
-                                        u8 sta_id)
-{
-       unsigned long flags;
-       __le16 key_flags = 0;
-       struct iwl_addsta_cmd sta_cmd;
-
-       lockdep_assert_held(&priv->mutex);
-
-       key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK);
-       key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
-       key_flags &= ~STA_KEY_FLG_INVALID;
-
-       if (sta_id == ctx->bcast_sta_id)
-               key_flags |= STA_KEY_MULTICAST_MSK;
-
-       keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
-
-       spin_lock_irqsave(&priv->sta_lock, flags);
-       priv->stations[sta_id].keyinfo.cipher = keyconf->cipher;
-       priv->stations[sta_id].keyinfo.keylen = keyconf->keylen;
-
-       memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key,
-              keyconf->keylen);
-
-       memcpy(priv->stations[sta_id].sta.key.key, keyconf->key,
-              keyconf->keylen);
-
-       if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
-                       == STA_KEY_FLG_NO_ENC)
-               priv->stations[sta_id].sta.key.key_offset =
-                                iwl_get_free_ucode_key_index(priv);
-       /* else, we are overriding an existing key => no need to allocated room
-        * in uCode. */
-
-       WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
-               "no space for a new key");
-
-       priv->stations[sta_id].sta.key.key_flags = key_flags;
-       priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
-       priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
-
-       memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
-       spin_unlock_irqrestore(&priv->sta_lock, flags);
-
-       return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
-}
-
-static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv,
-                                        struct iwl_rxon_context *ctx,
-                                        struct ieee80211_key_conf *keyconf,
-                                        u8 sta_id)
-{
-       unsigned long flags;
-       int ret = 0;
-       __le16 key_flags = 0;
-
-       key_flags |= (STA_KEY_FLG_TKIP | STA_KEY_FLG_MAP_KEY_MSK);
-       key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
-       key_flags &= ~STA_KEY_FLG_INVALID;
-
-       if (sta_id == ctx->bcast_sta_id)
-               key_flags |= STA_KEY_MULTICAST_MSK;
-
-       keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
-       keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
-
-       spin_lock_irqsave(&priv->sta_lock, flags);
-
-       priv->stations[sta_id].keyinfo.cipher = keyconf->cipher;
-       priv->stations[sta_id].keyinfo.keylen = 16;
-
-       if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
-                       == STA_KEY_FLG_NO_ENC)
-               priv->stations[sta_id].sta.key.key_offset =
-                                iwl_get_free_ucode_key_index(priv);
-       /* else, we are overriding an existing key => no need to allocated room
-        * in uCode. */
-
-       WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
-               "no space for a new key");
-
-       priv->stations[sta_id].sta.key.key_flags = key_flags;
-
-
-       /* This copy is acutally not needed: we get the key with each TX */
-       memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, 16);
-
-       memcpy(priv->stations[sta_id].sta.key.key, keyconf->key, 16);
-
-       spin_unlock_irqrestore(&priv->sta_lock, flags);
-
-       return ret;
-}
-
-void iwl_update_tkip_key(struct iwl_priv *priv,
-                        struct iwl_rxon_context *ctx,
-                        struct ieee80211_key_conf *keyconf,
-                        struct ieee80211_sta *sta, u32 iv32, u16 *phase1key)
+void iwl_dealloc_bcast_stations(struct iwl_priv *priv)
 {
-       u8 sta_id;
        unsigned long flags;
        int i;
 
-       if (iwl_scan_cancel(priv)) {
-               /* cancel scan failed, just live w/ bad key and rely
-                  briefly on SW decryption */
-               return;
-       }
-
-       sta_id = iwl_sta_id_or_broadcast(priv, ctx, sta);
-       if (sta_id == IWL_INVALID_STATION)
-               return;
-
-       spin_lock_irqsave(&priv->sta_lock, flags);
-
-       priv->stations[sta_id].sta.key.tkip_rx_tsc_byte2 = (u8) iv32;
-
-       for (i = 0; i < 5; i++)
-               priv->stations[sta_id].sta.key.tkip_rx_ttak[i] =
-                       cpu_to_le16(phase1key[i]);
-
-       priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
-       priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
-
-       iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
-
-       spin_unlock_irqrestore(&priv->sta_lock, flags);
-
-}
-EXPORT_SYMBOL(iwl_update_tkip_key);
-
-int iwl_remove_dynamic_key(struct iwl_priv *priv,
-                          struct iwl_rxon_context *ctx,
-                          struct ieee80211_key_conf *keyconf,
-                          u8 sta_id)
-{
-       unsigned long flags;
-       u16 key_flags;
-       u8 keyidx;
-       struct iwl_addsta_cmd sta_cmd;
-
-       lockdep_assert_held(&priv->mutex);
-
-       ctx->key_mapping_keys--;
-
        spin_lock_irqsave(&priv->sta_lock, flags);
-       key_flags = le16_to_cpu(priv->stations[sta_id].sta.key.key_flags);
-       keyidx = (key_flags >> STA_KEY_FLG_KEYID_POS) & 0x3;
-
-       IWL_DEBUG_WEP(priv, "Remove dynamic key: idx=%d sta=%d\n",
-                     keyconf->keyidx, sta_id);
-
-       if (keyconf->keyidx != keyidx) {
-               /* We need to remove a key with index different that the one
-                * in the uCode. This means that the key we need to remove has
-                * been replaced by another one with different index.
-                * Don't do anything and return ok
-                */
-               spin_unlock_irqrestore(&priv->sta_lock, flags);
-               return 0;
-       }
-
-       if (priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET) {
-               IWL_WARN(priv, "Removing wrong key %d 0x%x\n",
-                           keyconf->keyidx, key_flags);
-               spin_unlock_irqrestore(&priv->sta_lock, flags);
-               return 0;
-       }
+       for (i = 0; i < priv->hw_params.max_stations; i++) {
+               if (!(priv->stations[i].used & IWL_STA_BCAST))
+                       continue;
 
-       if (!test_and_clear_bit(priv->stations[sta_id].sta.key.key_offset,
-               &priv->ucode_key_table))
-               IWL_ERR(priv, "index %d not used in uCode key table.\n",
-                       priv->stations[sta_id].sta.key.key_offset);
-       memset(&priv->stations[sta_id].keyinfo, 0,
-                                       sizeof(struct iwl_hw_key));
-       memset(&priv->stations[sta_id].sta.key, 0,
-                                       sizeof(struct iwl4965_keyinfo));
-       priv->stations[sta_id].sta.key.key_flags =
-                       STA_KEY_FLG_NO_ENC | STA_KEY_FLG_INVALID;
-       priv->stations[sta_id].sta.key.key_offset = WEP_INVALID_OFFSET;
-       priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
-       priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
-
-       if (iwl_is_rfkill(priv)) {
-               IWL_DEBUG_WEP(priv, "Not sending REPLY_ADD_STA command because RFKILL enabled.\n");
-               spin_unlock_irqrestore(&priv->sta_lock, flags);
-               return 0;
+               priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE;
+               priv->num_stations--;
+               BUG_ON(priv->num_stations < 0);
+               kfree(priv->stations[i].lq);
+               priv->stations[i].lq = NULL;
        }
-       memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
        spin_unlock_irqrestore(&priv->sta_lock, flags);
-
-       return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
-}
-EXPORT_SYMBOL(iwl_remove_dynamic_key);
-
-int iwl_set_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
-                       struct ieee80211_key_conf *keyconf, u8 sta_id)
-{
-       int ret;
-
-       lockdep_assert_held(&priv->mutex);
-
-       ctx->key_mapping_keys++;
-       keyconf->hw_key_idx = HW_KEY_DYNAMIC;
-
-       switch (keyconf->cipher) {
-       case WLAN_CIPHER_SUITE_CCMP:
-               ret = iwl_set_ccmp_dynamic_key_info(priv, ctx, keyconf, sta_id);
-               break;
-       case WLAN_CIPHER_SUITE_TKIP:
-               ret = iwl_set_tkip_dynamic_key_info(priv, ctx, keyconf, sta_id);
-               break;
-       case WLAN_CIPHER_SUITE_WEP40:
-       case WLAN_CIPHER_SUITE_WEP104:
-               ret = iwl_set_wep_dynamic_key_info(priv, ctx, keyconf, sta_id);
-               break;
-       default:
-               IWL_ERR(priv,
-                       "Unknown alg: %s cipher = %x\n", __func__,
-                       keyconf->cipher);
-               ret = -EINVAL;
-       }
-
-       IWL_DEBUG_WEP(priv, "Set dynamic key: cipher=%x len=%d idx=%d sta=%d ret=%d\n",
-                     keyconf->cipher, keyconf->keylen, keyconf->keyidx,
-                     sta_id, ret);
-
-       return ret;
 }
-EXPORT_SYMBOL(iwl_set_dynamic_key);
+EXPORT_SYMBOL_GPL(iwl_dealloc_bcast_stations);
 
 #ifdef CONFIG_IWLWIFI_DEBUG
 static 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,
 }
 EXPORT_SYMBOL(iwl_send_lq_cmd);
 
-/**
- * iwl_alloc_bcast_station - add broadcast station into driver's station table.
- *
- * This adds the broadcast station into the driver's station table
- * and marks it driver active, so that it will be restored to the
- * device at the next best time.
- */
-int iwl_alloc_bcast_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
-                           bool init_lq)
-{
-       struct iwl_link_quality_cmd *link_cmd;
-       unsigned long flags;
-       u8 sta_id;
-
-       spin_lock_irqsave(&priv->sta_lock, flags);
-       sta_id = iwl_prep_station(priv, ctx, iwl_bcast_addr, false, NULL);
-       if (sta_id == IWL_INVALID_STATION) {
-               IWL_ERR(priv, "Unable to prepare broadcast station\n");
-               spin_unlock_irqrestore(&priv->sta_lock, flags);
-
-               return -EINVAL;
-       }
-
-       priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE;
-       priv->stations[sta_id].used |= IWL_STA_BCAST;
-       spin_unlock_irqrestore(&priv->sta_lock, flags);
-
-       if (init_lq) {
-               link_cmd = iwl_sta_alloc_lq(priv, sta_id);
-               if (!link_cmd) {
-                       IWL_ERR(priv,
-                               "Unable to initialize rate scaling for bcast station.\n");
-                       return -ENOMEM;
-               }
-
-               spin_lock_irqsave(&priv->sta_lock, flags);
-               priv->stations[sta_id].lq = link_cmd;
-               spin_unlock_irqrestore(&priv->sta_lock, flags);
-       }
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(iwl_alloc_bcast_station);
-
-/**
- * iwl_update_bcast_station - update broadcast station's LQ command
- *
- * Only used by iwlagn. Placed here to have all bcast station management
- * code together.
- */
-static int iwl_update_bcast_station(struct iwl_priv *priv,
-                                   struct iwl_rxon_context *ctx)
-{
-       unsigned long flags;
-       struct iwl_link_quality_cmd *link_cmd;
-       u8 sta_id = ctx->bcast_sta_id;
-
-       link_cmd = iwl_sta_alloc_lq(priv, sta_id);
-       if (!link_cmd) {
-               IWL_ERR(priv, "Unable to initialize rate scaling for bcast station.\n");
-               return -ENOMEM;
-       }
-
-       spin_lock_irqsave(&priv->sta_lock, flags);
-       if (priv->stations[sta_id].lq)
-               kfree(priv->stations[sta_id].lq);
-       else
-               IWL_DEBUG_INFO(priv, "Bcast station rate scaling has not been initialized yet.\n");
-       priv->stations[sta_id].lq = link_cmd;
-       spin_unlock_irqrestore(&priv->sta_lock, flags);
-
-       return 0;
-}
-
-int iwl_update_bcast_stations(struct iwl_priv *priv)
-{
-       struct iwl_rxon_context *ctx;
-       int ret = 0;
-
-       for_each_context(priv, ctx) {
-               ret = iwl_update_bcast_station(priv, ctx);
-               if (ret)
-                       break;
-       }
-
-       return ret;
-}
-EXPORT_SYMBOL_GPL(iwl_update_bcast_stations);
-
-void iwl_dealloc_bcast_stations(struct iwl_priv *priv)
-{
-       unsigned long flags;
-       int i;
-
-       spin_lock_irqsave(&priv->sta_lock, flags);
-       for (i = 0; i < priv->hw_params.max_stations; i++) {
-               if (!(priv->stations[i].used & IWL_STA_BCAST))
-                       continue;
-
-               priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE;
-               priv->num_stations--;
-               BUG_ON(priv->num_stations < 0);
-               kfree(priv->stations[i].lq);
-               priv->stations[i].lq = NULL;
-       }
-       spin_unlock_irqrestore(&priv->sta_lock, flags);
-}
-EXPORT_SYMBOL_GPL(iwl_dealloc_bcast_stations);
-
-/**
- * iwl_sta_tx_modify_enable_tid - Enable Tx for this TID in station table
- */
-int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid)
-{
-       unsigned long flags;
-       struct iwl_addsta_cmd sta_cmd;
-
-       lockdep_assert_held(&priv->mutex);
-
-       /* Remove "disable" flag, to enable Tx for this TID */
-       spin_lock_irqsave(&priv->sta_lock, flags);
-       priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_TID_DISABLE_TX;
-       priv->stations[sta_id].sta.tid_disable_tx &= cpu_to_le16(~(1 << tid));
-       priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
-       memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
-       spin_unlock_irqrestore(&priv->sta_lock, flags);
-
-       return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
-}
-EXPORT_SYMBOL(iwl_sta_tx_modify_enable_tid);
-
-int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta,
-                        int tid, u16 ssn)
-{
-       unsigned long flags;
-       int sta_id;
-       struct iwl_addsta_cmd sta_cmd;
-
-       lockdep_assert_held(&priv->mutex);
-
-       sta_id = iwl_sta_id(sta);
-       if (sta_id == IWL_INVALID_STATION)
-               return -ENXIO;
-
-       spin_lock_irqsave(&priv->sta_lock, flags);
-       priv->stations[sta_id].sta.station_flags_msk = 0;
-       priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_ADDBA_TID_MSK;
-       priv->stations[sta_id].sta.add_immediate_ba_tid = (u8)tid;
-       priv->stations[sta_id].sta.add_immediate_ba_ssn = cpu_to_le16(ssn);
-       priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
-       memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
-       spin_unlock_irqrestore(&priv->sta_lock, flags);
-
-       return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
-}
-EXPORT_SYMBOL(iwl_sta_rx_agg_start);
-
-int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
-                       int tid)
-{
-       unsigned long flags;
-       int sta_id;
-       struct iwl_addsta_cmd sta_cmd;
-
-       lockdep_assert_held(&priv->mutex);
-
-       sta_id = iwl_sta_id(sta);
-       if (sta_id == IWL_INVALID_STATION) {
-               IWL_ERR(priv, "Invalid station for AGG tid %d\n", tid);
-               return -ENXIO;
-       }
-
-       spin_lock_irqsave(&priv->sta_lock, flags);
-       priv->stations[sta_id].sta.station_flags_msk = 0;
-       priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_DELBA_TID_MSK;
-       priv->stations[sta_id].sta.remove_immediate_ba_tid = (u8)tid;
-       priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
-       memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
-       spin_unlock_irqrestore(&priv->sta_lock, flags);
-
-       return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
-}
-EXPORT_SYMBOL(iwl_sta_rx_agg_stop);
-
-void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&priv->sta_lock, flags);
-       priv->stations[sta_id].sta.station_flags &= ~STA_FLG_PWR_SAVE_MSK;
-       priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK;
-       priv->stations[sta_id].sta.sta.modify_mask = 0;
-       priv->stations[sta_id].sta.sleep_tx_count = 0;
-       priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
-       iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
-       spin_unlock_irqrestore(&priv->sta_lock, flags);
-
-}
-EXPORT_SYMBOL(iwl_sta_modify_ps_wake);
-
-void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&priv->sta_lock, flags);
-       priv->stations[sta_id].sta.station_flags |= STA_FLG_PWR_SAVE_MSK;
-       priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK;
-       priv->stations[sta_id].sta.sta.modify_mask =
-                                       STA_MODIFY_SLEEP_TX_COUNT_MSK;
-       priv->stations[sta_id].sta.sleep_tx_count = cpu_to_le16(cnt);
-       priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
-       iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
-       spin_unlock_irqrestore(&priv->sta_lock, flags);
-
-}
-EXPORT_SYMBOL(iwl_sta_modify_sleep_tx_count);
-
 int iwl_mac_sta_remove(struct ieee80211_hw *hw,
                       struct ieee80211_vif *vif,
                       struct ieee80211_sta *sta)
index 56bad3f60d8131c74d3874472370e1ca0d241bdb..06475872eee4e2690023206918b3e944f5e7e5d8 100644 (file)
 #define IWL_STA_BCAST BIT(4) /* this station is the special bcast station */
 
 
-int iwl_remove_default_wep_key(struct iwl_priv *priv,
-                              struct iwl_rxon_context *ctx,
-                              struct ieee80211_key_conf *key);
-int iwl_set_default_wep_key(struct iwl_priv *priv,
-                           struct iwl_rxon_context *ctx,
-                           struct ieee80211_key_conf *key);
-int iwl_restore_default_wep_keys(struct iwl_priv *priv,
-                                struct iwl_rxon_context *ctx);
-int iwl_set_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
-                       struct ieee80211_key_conf *key, u8 sta_id);
-int iwl_remove_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
-                          struct ieee80211_key_conf *key, u8 sta_id);
-void iwl_update_tkip_key(struct iwl_priv *priv,
-                        struct iwl_rxon_context *ctx,
-                        struct ieee80211_key_conf *keyconf,
-                        struct ieee80211_sta *sta, u32 iv32, u16 *phase1key);
-
 void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
 void iwl_clear_ucode_stations(struct iwl_priv *priv,
                              struct iwl_rxon_context *ctx);
-int iwl_alloc_bcast_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
-                           bool init_lq);
 void iwl_dealloc_bcast_stations(struct iwl_priv *priv);
-int iwl_update_bcast_stations(struct iwl_priv *priv);
 int iwl_get_free_ucode_key_index(struct iwl_priv *priv);
 int iwl_send_add_sta(struct iwl_priv *priv,
                     struct iwl_addsta_cmd *sta, u8 flags);
-int iwl_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
-                         const u8 *addr, bool init_rs, u8 *sta_id_r);
 int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
                           const u8 *addr, bool is_ap,
                           struct ieee80211_sta *sta, u8 *sta_id_r);
@@ -79,13 +57,12 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
                       const u8 *addr);
 int iwl_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                       struct ieee80211_sta *sta);
-int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid);
-int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta,
-                        int tid, u16 ssn);
-int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
-                       int tid);
-void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id);
-void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt);
+
+u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+                   const u8 *addr, bool is_ap, struct ieee80211_sta *sta);
+
+int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+                   struct iwl_link_quality_cmd *lq, u8 flags, bool init);
 
 /**
  * iwl_clear_driver_stations - clear knowledge of all stations from driver
index 3290b1552f5a8dd9f035ff5b09af51348369fed2..7261ee49f282f2c1e3a6d027a2aad2954c9b85a3 100644 (file)
@@ -636,41 +636,3 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
        meta->flags = 0;
 }
 EXPORT_SYMBOL(iwl_tx_cmd_complete);
-
-#ifdef CONFIG_IWLWIFI_DEBUG
-#define TX_STATUS_FAIL(x) case TX_STATUS_FAIL_ ## x: return #x
-#define TX_STATUS_POSTPONE(x) case TX_STATUS_POSTPONE_ ## x: return #x
-
-const char *iwl_get_tx_fail_reason(u32 status)
-{
-       switch (status & TX_STATUS_MSK) {
-       case TX_STATUS_SUCCESS:
-               return "SUCCESS";
-               TX_STATUS_POSTPONE(DELAY);
-               TX_STATUS_POSTPONE(FEW_BYTES);
-               TX_STATUS_POSTPONE(BT_PRIO);
-               TX_STATUS_POSTPONE(QUIET_PERIOD);
-               TX_STATUS_POSTPONE(CALC_TTAK);
-               TX_STATUS_FAIL(INTERNAL_CROSSED_RETRY);
-               TX_STATUS_FAIL(SHORT_LIMIT);
-               TX_STATUS_FAIL(LONG_LIMIT);
-               TX_STATUS_FAIL(FIFO_UNDERRUN);
-               TX_STATUS_FAIL(DRAIN_FLOW);
-               TX_STATUS_FAIL(RFKILL_FLUSH);
-               TX_STATUS_FAIL(LIFE_EXPIRE);
-               TX_STATUS_FAIL(DEST_PS);
-               TX_STATUS_FAIL(HOST_ABORTED);
-               TX_STATUS_FAIL(BT_RETRY);
-               TX_STATUS_FAIL(STA_INVALID);
-               TX_STATUS_FAIL(FRAG_DROPPED);
-               TX_STATUS_FAIL(TID_DISABLE);
-               TX_STATUS_FAIL(FIFO_FLUSHED);
-               TX_STATUS_FAIL(INSUFFICIENT_CF_POLL);
-               TX_STATUS_FAIL(PASSIVE_NO_RX);
-               TX_STATUS_FAIL(NO_BEACON_ON_RADAR);
-       }
-
-       return "UNKNOWN";
-}
-EXPORT_SYMBOL(iwl_get_tx_fail_reason);
-#endif /* CONFIG_IWLWIFI_DEBUG */
index 43db5f38e3e6cc2cd8a23bdd9dcae21f23d0ea2c..8f8c4b73f8b9667a245f764360058be740f38b03 100644 (file)
@@ -317,15 +317,15 @@ unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv,
                                int left)
 {
 
-       if (!iwl_is_associated(priv, IWL_RXON_CTX_BSS) || !priv->ibss_beacon)
+       if (!iwl_is_associated(priv, IWL_RXON_CTX_BSS) || !priv->beacon_skb)
                return 0;
 
-       if (priv->ibss_beacon->len > left)
+       if (priv->beacon_skb->len > left)
                return 0;
 
-       memcpy(hdr, priv->ibss_beacon->data, priv->ibss_beacon->len);
+       memcpy(hdr, priv->beacon_skb->data, priv->beacon_skb->len);
 
-       return priv->ibss_beacon->len;
+       return priv->beacon_skb->len;
 }
 
 static int iwl3945_send_beacon_cmd(struct iwl_priv *priv)
@@ -813,10 +813,10 @@ static void iwl3945_bg_beacon_update(struct work_struct *work)
 
        mutex_lock(&priv->mutex);
        /* new beacon skb is allocated every time; dispose previous.*/
-       if (priv->ibss_beacon)
-               dev_kfree_skb(priv->ibss_beacon);
+       if (priv->beacon_skb)
+               dev_kfree_skb(priv->beacon_skb);
 
-       priv->ibss_beacon = beacon;
+       priv->beacon_skb = beacon;
        mutex_unlock(&priv->mutex);
 
        iwl3945_send_beacon_cmd(priv);
@@ -2547,7 +2547,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
        priv->cfg->ops->hcmd->send_bt_config(priv);
 
        /* Configure the adapter for unassociated operation */
-       iwlcore_commit_rxon(priv, ctx);
+       iwl3945_commit_rxon(priv, ctx);
 
        iwl3945_reg_txpower_periodic(priv);
 
@@ -2637,14 +2637,14 @@ static void __iwl3945_down(struct iwl_priv *priv)
        udelay(5);
 
        /* Stop the device, and put it in low power state */
-       priv->cfg->ops->lib->apm_ops.stop(priv);
+       iwl_apm_stop(priv);
 
  exit:
        memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp));
 
-       if (priv->ibss_beacon)
-               dev_kfree_skb(priv->ibss_beacon);
-       priv->ibss_beacon = NULL;
+       if (priv->beacon_skb)
+               dev_kfree_skb(priv->beacon_skb);
+       priv->beacon_skb = NULL;
 
        /* clear out any free frames */
        iwl3945_clear_free_frames(priv);
@@ -2661,12 +2661,33 @@ static void iwl3945_down(struct iwl_priv *priv)
 
 #define MAX_HW_RESTARTS 5
 
+static int iwl3945_alloc_bcast_station(struct iwl_priv *priv)
+{
+       struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
+       unsigned long flags;
+       u8 sta_id;
+
+       spin_lock_irqsave(&priv->sta_lock, flags);
+       sta_id = iwl_prep_station(priv, ctx, iwl_bcast_addr, false, NULL);
+       if (sta_id == IWL_INVALID_STATION) {
+               IWL_ERR(priv, "Unable to prepare broadcast station\n");
+               spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+               return -EINVAL;
+       }
+
+       priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE;
+       priv->stations[sta_id].used |= IWL_STA_BCAST;
+       spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+       return 0;
+}
+
 static int __iwl3945_up(struct iwl_priv *priv)
 {
        int rc, i;
 
-       rc = iwl_alloc_bcast_station(priv, &priv->contexts[IWL_RXON_CTX_BSS],
-                                    false);
+       rc = iwl3945_alloc_bcast_station(priv);
        if (rc)
                return rc;
 
@@ -2917,18 +2938,10 @@ int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
        case IEEE80211_BAND_2GHZ:
                scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;
                scan->tx_cmd.rate = IWL_RATE_1M_PLCP;
-               scan->good_CRC_th = 0;
                band = IEEE80211_BAND_2GHZ;
                break;
        case IEEE80211_BAND_5GHZ:
                scan->tx_cmd.rate = IWL_RATE_6M_PLCP;
-               /*
-                * If active scaning is requested but a certain channel
-                * is marked passive, we can do active scanning if we
-                * detect transmissions.
-                */
-               scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
-                                               IWL_GOOD_CRC_TH_DISABLED;
                band = IEEE80211_BAND_5GHZ;
                break;
        default:
@@ -2936,6 +2949,14 @@ int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
                return -EIO;
        }
 
+       /*
+        * If active scaning is requested but a certain channel
+        * is marked passive, we can do active scanning if we
+        * detect transmissions.
+        */
+       scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
+                                       IWL_GOOD_CRC_TH_DISABLED;
+
        if (!priv->is_internal_short_scan) {
                scan->tx_cmd.len = cpu_to_le16(
                        iwl_fill_probe_req(priv,
@@ -2983,6 +3004,18 @@ int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
        return ret;
 }
 
+void iwl3945_post_scan(struct iwl_priv *priv)
+{
+       struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
+
+       /*
+        * Since setting the RXON may have been deferred while
+        * performing the scan, fire one off if needed
+        */
+       if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))
+               iwl3945_commit_rxon(priv, ctx);
+}
+
 static void iwl3945_bg_restart(struct work_struct *data)
 {
        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)
        conf = ieee80211_get_hw_conf(priv->hw);
 
        ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-       iwlcore_commit_rxon(priv, ctx);
+       iwl3945_commit_rxon(priv, ctx);
 
        rc = iwl_send_rxon_timing(priv, ctx);
        if (rc)
@@ -3075,7 +3108,7 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
                        ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
        }
 
-       iwlcore_commit_rxon(priv, ctx);
+       iwl3945_commit_rxon(priv, ctx);
 
        switch (vif->type) {
        case NL80211_IFTYPE_STATION:
@@ -3214,7 +3247,7 @@ void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
 
                /* RXON - unassoc (to set timing command) */
                ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-               iwlcore_commit_rxon(priv, ctx);
+               iwl3945_commit_rxon(priv, ctx);
 
                /* RXON Timing */
                rc = iwl_send_rxon_timing(priv, ctx);
@@ -3241,7 +3274,7 @@ void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
                }
                /* restore RXON assoc */
                ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
-               iwlcore_commit_rxon(priv, ctx);
+               iwl3945_commit_rxon(priv, ctx);
        }
        iwl3945_send_beacon_cmd(priv);
 
@@ -3507,7 +3540,7 @@ static ssize_t store_flags(struct device *d,
                        IWL_DEBUG_INFO(priv, "Committing rxon.flags = 0x%04X\n",
                                       flags);
                        ctx->staging.flags = cpu_to_le32(flags);
-                       iwlcore_commit_rxon(priv, ctx);
+                       iwl3945_commit_rxon(priv, ctx);
                }
        }
        mutex_unlock(&priv->mutex);
@@ -3545,7 +3578,7 @@ static ssize_t store_filter_flags(struct device *d,
                                       "0x%04X\n", filter_flags);
                        ctx->staging.filter_flags =
                                cpu_to_le32(filter_flags);
-                       iwlcore_commit_rxon(priv, ctx);
+                       iwl3945_commit_rxon(priv, ctx);
                }
        }
        mutex_unlock(&priv->mutex);
@@ -3815,7 +3848,7 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
        struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
 
        priv->retry_rate = 1;
-       priv->ibss_beacon = NULL;
+       priv->beacon_skb = NULL;
 
        spin_lock_init(&priv->sta_lock);
        spin_lock_init(&priv->hcmd_lock);
@@ -4179,7 +4212,7 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
         * paths to avoid running iwl_down() at all before leaving driver.
         * This (inexpensive) call *makes sure* device is reset.
         */
-       priv->cfg->ops->lib->apm_ops.stop(priv);
+       iwl_apm_stop(priv);
 
        /* make sure we flush any pending irq or
         * tasklet for the driver
@@ -4223,8 +4256,8 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
        iwl_free_channel_map(priv);
        iwlcore_free_geos(priv);
        kfree(priv->scan_cmd);
-       if (priv->ibss_beacon)
-               dev_kfree_skb(priv->ibss_beacon);
+       if (priv->beacon_skb)
+               dev_kfree_skb(priv->beacon_skb);
 
        ieee80211_free_hw(priv->hw);
 }
index e906616232a2f4bea102426dea77285637148046..efaf850322089b3f6ef1c40219dc547020976767 100644 (file)
@@ -487,11 +487,12 @@ static int if_usb_reset_device(struct if_usb_card *cardp)
  */
 static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload, uint16_t nb)
 {
-       int ret = -1;
+       int ret;
 
        /* check if device is removed */
        if (cardp->surprise_removed) {
                lbs_deb_usbd(&cardp->udev->dev, "Device removed\n");
+               ret = -ENODEV;
                goto tx_ret;
        }
 
@@ -504,7 +505,6 @@ static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload, uint16_t nb
 
        if ((ret = usb_submit_urb(cardp->tx_urb, GFP_ATOMIC))) {
                lbs_deb_usbd(&cardp->udev->dev, "usb_submit_urb failed: %d\n", ret);
-               ret = -1;
        } else {
                lbs_deb_usb2(&cardp->udev->dev, "usb_submit_urb success\n");
                ret = 0;
index 8c05266d37f46f071760b7107c96357fa89c9ef2..35b09aa0529bf6cb6f142680d045c0e894c44df9 100644 (file)
@@ -261,8 +261,10 @@ static int p54_generate_channel_lists(struct ieee80211_hw *dev)
        list->max_entries = max_channel_num;
        list->channels = kzalloc(sizeof(struct p54_channel_entry) *
                                 max_channel_num, GFP_KERNEL);
-       if (!list->channels)
+       if (!list->channels) {
+               ret = -ENOMEM;
                goto free;
+       }
 
        for (i = 0; i < max_channel_num; i++) {
                if (i < priv->iq_autocal_len) {
index d49e830fa1da8fde6730ef75858f4594d05e6d24..4f420a9ec5dc26f9b8f1bb663a3c39aaccf54330 100644 (file)
@@ -1104,7 +1104,7 @@ static void rt2400pci_write_beacon(struct queue_entry *entry,
        rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
        rt2x00pci_register_write(rt2x00dev, CSR14, reg);
 
-       rt2x00queue_map_txskb(rt2x00dev, entry->skb);
+       rt2x00queue_map_txskb(entry);
 
        /*
         * Write the TX descriptor for the beacon.
index 2214c32317273058c14613e1a3926c78790c5882..97feb7aef80929946714e97ed8931bf514487109 100644 (file)
@@ -1258,7 +1258,7 @@ static void rt2500pci_write_beacon(struct queue_entry *entry,
        rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
        rt2x00pci_register_write(rt2x00dev, CSR14, reg);
 
-       rt2x00queue_map_txskb(rt2x00dev, entry->skb);
+       rt2x00queue_map_txskb(entry);
 
        /*
         * Write the TX descriptor for the beacon.
index 10aefc4fb0ccef1266547b2c5a419767ef660869..5f00e00789d823bad28752516a4789da7057d8f9 100644 (file)
@@ -499,7 +499,7 @@ void rt2800_write_tx_data(struct queue_entry *entry,
 }
 EXPORT_SYMBOL_GPL(rt2800_write_tx_data);
 
-static int rt2800_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxwi_w2)
+static int rt2800_agc_to_rssi(struct rt2x00_dev *rt2x00dev, u32 rxwi_w2)
 {
        int rssi0 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI0);
        int rssi1 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI1);
index 85a134cd62bfdade64d2a448c5e0b742af60bfe2..b267395359863ca10a55fe8a39f186e5bf08deb9 100644 (file)
@@ -573,7 +573,7 @@ static void rt2800pci_kick_tx_queue(struct data_queue *queue)
 {
        struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
        struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX);
-       unsigned int qidx = 0;
+       unsigned int qidx;
 
        if (queue->qid == QID_MGMT)
                qidx = 5;
@@ -676,7 +676,7 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
                        break;
                }
 
-               qid = rt2x00_get_field32(status, TX_STA_FIFO_PID_TYPE) - 1;
+               qid = rt2x00_get_field32(status, TX_STA_FIFO_PID_QUEUE);
                if (qid >= QID_RX) {
                        /*
                         * Unknown queue, this shouldn't happen. Just drop
index 75ac6624bf9e3914d9e571d03526cf5ea19cd4eb..94fe589acfaabff06eac097fe7e3ae3e2f7ea310 100644 (file)
@@ -338,6 +338,11 @@ struct link {
 
        /*
         * Work structure for scheduling periodic watchdog monitoring.
+        * This work must be scheduled on the kernel workqueue, while
+        * all other work structures must be queued on the mac80211
+        * workqueue. This guarantees that the watchdog can schedule
+        * other work structures and wait for their completion in order
+        * to bring the device/driver back into the desired state.
         */
        struct delayed_work watchdog_work;
 };
@@ -1036,17 +1041,15 @@ static inline bool rt2x00_is_soc(struct rt2x00_dev *rt2x00dev)
 
 /**
  * rt2x00queue_map_txskb - Map a skb into DMA for TX purposes.
- * @rt2x00dev: Pointer to &struct rt2x00_dev.
- * @skb: The skb to map.
+ * @entry: Pointer to &struct queue_entry
  */
-void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
+void rt2x00queue_map_txskb(struct queue_entry *entry);
 
 /**
  * rt2x00queue_unmap_skb - Unmap a skb from DMA.
- * @rt2x00dev: Pointer to &struct rt2x00_dev.
- * @skb: The skb to unmap.
+ * @entry: Pointer to &struct queue_entry
  */
-void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
+void rt2x00queue_unmap_skb(struct queue_entry *entry);
 
 /**
  * rt2x00queue_get_queue - Convert queue index to queue pointer
@@ -1093,8 +1096,7 @@ void rt2x00lib_dmadone(struct queue_entry *entry);
 void rt2x00lib_txdone(struct queue_entry *entry,
                      struct txdone_entry_desc *txdesc);
 void rt2x00lib_txdone_noinfo(struct queue_entry *entry, u32 status);
-void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
-                     struct queue_entry *entry);
+void rt2x00lib_rxdone(struct queue_entry *entry);
 
 /*
  * mac80211 handlers.
index 6f442b02b83ed0282c41b1ee2710d52f967ad43d..5ba79b935f09f5bed56f999653338501584cf141 100644 (file)
@@ -253,6 +253,7 @@ EXPORT_SYMBOL_GPL(rt2x00lib_pretbtt);
 
 void rt2x00lib_dmadone(struct queue_entry *entry)
 {
+       clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
        rt2x00queue_index_inc(entry->queue, Q_INDEX_DMA_DONE);
 }
 EXPORT_SYMBOL_GPL(rt2x00lib_dmadone);
@@ -273,7 +274,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
        /*
         * Unmap the skb.
         */
-       rt2x00queue_unmap_skb(rt2x00dev, entry->skb);
+       rt2x00queue_unmap_skb(entry);
 
        /*
         * Remove the extra tx headroom from the skb.
@@ -432,42 +433,50 @@ static int rt2x00lib_rxdone_read_signal(struct rt2x00_dev *rt2x00dev,
        struct ieee80211_supported_band *sband;
        const struct rt2x00_rate *rate;
        unsigned int i;
-       int signal;
-       int type;
+       int signal = rxdesc->signal;
+       int type = (rxdesc->dev_flags & RXDONE_SIGNAL_MASK);
 
-       /*
-        * For non-HT rates the MCS value needs to contain the
-        * actually used rate modulation (CCK or OFDM).
-        */
-       if (rxdesc->dev_flags & RXDONE_SIGNAL_MCS)
-               signal = RATE_MCS(rxdesc->rate_mode, rxdesc->signal);
-       else
-               signal = rxdesc->signal;
-
-       type = (rxdesc->dev_flags & RXDONE_SIGNAL_MASK);
-
-       sband = &rt2x00dev->bands[rt2x00dev->curr_band];
-       for (i = 0; i < sband->n_bitrates; i++) {
-               rate = rt2x00_get_rate(sband->bitrates[i].hw_value);
-
-               if (((type == RXDONE_SIGNAL_PLCP) &&
-                    (rate->plcp == signal)) ||
-                   ((type == RXDONE_SIGNAL_BITRATE) &&
-                     (rate->bitrate == signal)) ||
-                   ((type == RXDONE_SIGNAL_MCS) &&
-                     (rate->mcs == signal))) {
-                       return i;
+       switch (rxdesc->rate_mode) {
+       case RATE_MODE_CCK:
+       case RATE_MODE_OFDM:
+               /*
+                * For non-HT rates the MCS value needs to contain the
+                * actually used rate modulation (CCK or OFDM).
+                */
+               if (rxdesc->dev_flags & RXDONE_SIGNAL_MCS)
+                       signal = RATE_MCS(rxdesc->rate_mode, signal);
+
+               sband = &rt2x00dev->bands[rt2x00dev->curr_band];
+               for (i = 0; i < sband->n_bitrates; i++) {
+                       rate = rt2x00_get_rate(sband->bitrates[i].hw_value);
+                       if (((type == RXDONE_SIGNAL_PLCP) &&
+                            (rate->plcp == signal)) ||
+                           ((type == RXDONE_SIGNAL_BITRATE) &&
+                             (rate->bitrate == signal)) ||
+                           ((type == RXDONE_SIGNAL_MCS) &&
+                             (rate->mcs == signal))) {
+                               return i;
+                       }
                }
+               break;
+       case RATE_MODE_HT_MIX:
+       case RATE_MODE_HT_GREENFIELD:
+               if (signal >= 0 && signal <= 76)
+                       return signal;
+               break;
+       default:
+               break;
        }
 
        WARNING(rt2x00dev, "Frame received with unrecognized signal, "
-               "signal=0x%.4x, type=%d.\n", signal, type);
+               "mode=0x%.4x, signal=0x%.4x, type=%d.\n",
+               rxdesc->rate_mode, signal, type);
        return 0;
 }
 
-void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
-                     struct queue_entry *entry)
+void rt2x00lib_rxdone(struct queue_entry *entry)
 {
+       struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
        struct rxdone_entry_desc rxdesc;
        struct sk_buff *skb;
        struct ieee80211_rx_status *rx_status;
@@ -481,14 +490,14 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
         * Allocate a new sk_buffer. If no new buffer available, drop the
         * received frame and reuse the existing buffer.
         */
-       skb = rt2x00queue_alloc_rxskb(rt2x00dev, entry);
+       skb = rt2x00queue_alloc_rxskb(entry);
        if (!skb)
-               return;
+               goto submit_entry;
 
        /*
         * Unmap the skb.
         */
-       rt2x00queue_unmap_skb(rt2x00dev, entry->skb);
+       rt2x00queue_unmap_skb(entry);
 
        /*
         * Extract the RXD details.
@@ -523,18 +532,12 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
        skb_trim(entry->skb, rxdesc.size);
 
        /*
-        * Check if the frame was received using HT. In that case,
-        * the rate is the MCS index and should be passed to mac80211
-        * directly. Otherwise we need to translate the signal to
-        * the correct bitrate index.
+        * Translate the signal to the correct bitrate index.
         */
-       if (rxdesc.rate_mode == RATE_MODE_CCK ||
-           rxdesc.rate_mode == RATE_MODE_OFDM) {
-               rate_idx = rt2x00lib_rxdone_read_signal(rt2x00dev, &rxdesc);
-       } else {
+       rate_idx = rt2x00lib_rxdone_read_signal(rt2x00dev, &rxdesc);
+       if (rxdesc.rate_mode == RATE_MODE_HT_MIX ||
+           rxdesc.rate_mode == RATE_MODE_HT_GREENFIELD)
                rxdesc.flags |= RX_FLAG_HT;
-               rate_idx = rxdesc.signal;
-       }
 
        /*
         * Update extra components
index 70c85ac2e53ec15e2ec200581ea210db306a6159..619da23b7b56004cec3e3d327100449e9269b500 100644 (file)
@@ -100,18 +100,15 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
 
 /**
  * rt2x00queue_alloc_rxskb - allocate a skb for RX purposes.
- * @rt2x00dev: Pointer to &struct rt2x00_dev.
- * @queue: The queue for which the skb will be applicable.
+ * @entry: The entry for which the skb will be applicable.
  */
-struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev,
-                                       struct queue_entry *entry);
+struct sk_buff *rt2x00queue_alloc_rxskb(struct queue_entry *entry);
 
 /**
  * rt2x00queue_free_skb - free a skb
- * @rt2x00dev: Pointer to &struct rt2x00_dev.
- * @skb: The skb to free.
+ * @entry: The entry for which the skb will be applicable.
  */
-void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
+void rt2x00queue_free_skb(struct queue_entry *entry);
 
 /**
  * rt2x00queue_align_frame - Align 802.11 frame to 4-byte boundary
index 4d534e9dc6286a7d6ff06d5d7874037f72aeb743..b971d8798ebf8ce23e7efbc2d7b1c7b88233d107 100644 (file)
@@ -235,6 +235,12 @@ void rt2x00link_update_stats(struct rt2x00_dev *rt2x00dev,
        struct link_ant *ant = &rt2x00dev->link.ant;
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 
+       /*
+        * No need to update the stats for !=STA interfaces
+        */
+       if (!rt2x00dev->intf_sta_count)
+               return;
+
        /*
         * Frame was received successfully since non-succesfull
         * frames would have been dropped by the hardware.
@@ -411,8 +417,7 @@ void rt2x00link_start_watchdog(struct rt2x00_dev *rt2x00dev)
            !test_bit(DRIVER_SUPPORT_WATCHDOG, &rt2x00dev->flags))
                return;
 
-       ieee80211_queue_delayed_work(rt2x00dev->hw,
-                                    &link->watchdog_work, WATCHDOG_INTERVAL);
+       schedule_delayed_work(&link->watchdog_work, WATCHDOG_INTERVAL);
 }
 
 void rt2x00link_stop_watchdog(struct rt2x00_dev *rt2x00dev)
@@ -436,8 +441,7 @@ static void rt2x00link_watchdog(struct work_struct *work)
        rt2x00dev->ops->lib->watchdog(rt2x00dev);
 
        if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
-               ieee80211_queue_delayed_work(rt2x00dev->hw,
-                                            &link->watchdog_work, WATCHDOG_INTERVAL);
+               schedule_delayed_work(&link->watchdog_work, WATCHDOG_INTERVAL);
 }
 
 void rt2x00link_register(struct rt2x00_dev *rt2x00dev)
index 63c2cc408e154705967677b287e0b4da85a5e727..2449d785cf8d5b4d9b5260a0a2e4f79d0506fdd9 100644 (file)
@@ -84,7 +84,7 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
                /*
                 * Send the frame to rt2x00lib for further processing.
                 */
-               rt2x00lib_rxdone(rt2x00dev, entry);
+               rt2x00lib_rxdone(entry);
        }
 }
 EXPORT_SYMBOL_GPL(rt2x00pci_rxdone);
index eede99939db917936462a3e7372b5bb010413541..e360d287defb01ae61672feae4e3618b3a8bea79 100644 (file)
@@ -33,9 +33,9 @@
 #include "rt2x00.h"
 #include "rt2x00lib.h"
 
-struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev,
-                                       struct queue_entry *entry)
+struct sk_buff *rt2x00queue_alloc_rxskb(struct queue_entry *entry)
 {
+       struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
        struct sk_buff *skb;
        struct skb_frame_desc *skbdesc;
        unsigned int frame_size;
@@ -97,41 +97,42 @@ struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev,
        return skb;
 }
 
-void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
+void rt2x00queue_map_txskb(struct queue_entry *entry)
 {
-       struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
+       struct device *dev = entry->queue->rt2x00dev->dev;
+       struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
 
        skbdesc->skb_dma =
-           dma_map_single(rt2x00dev->dev, skb->data, skb->len, DMA_TO_DEVICE);
+           dma_map_single(dev, entry->skb->data, entry->skb->len, DMA_TO_DEVICE);
        skbdesc->flags |= SKBDESC_DMA_MAPPED_TX;
 }
 EXPORT_SYMBOL_GPL(rt2x00queue_map_txskb);
 
-void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
+void rt2x00queue_unmap_skb(struct queue_entry *entry)
 {
-       struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
+       struct device *dev = entry->queue->rt2x00dev->dev;
+       struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
 
        if (skbdesc->flags & SKBDESC_DMA_MAPPED_RX) {
-               dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, skb->len,
+               dma_unmap_single(dev, skbdesc->skb_dma, entry->skb->len,
                                 DMA_FROM_DEVICE);
                skbdesc->flags &= ~SKBDESC_DMA_MAPPED_RX;
-       }
-
-       if (skbdesc->flags & SKBDESC_DMA_MAPPED_TX) {
-               dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, skb->len,
+       } else if (skbdesc->flags & SKBDESC_DMA_MAPPED_TX) {
+               dma_unmap_single(dev, skbdesc->skb_dma, entry->skb->len,
                                 DMA_TO_DEVICE);
                skbdesc->flags &= ~SKBDESC_DMA_MAPPED_TX;
        }
 }
 EXPORT_SYMBOL_GPL(rt2x00queue_unmap_skb);
 
-void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
+void rt2x00queue_free_skb(struct queue_entry *entry)
 {
-       if (!skb)
+       if (!entry->skb)
                return;
 
-       rt2x00queue_unmap_skb(rt2x00dev, skb);
-       dev_kfree_skb_any(skb);
+       rt2x00queue_unmap_skb(entry);
+       dev_kfree_skb_any(entry->skb);
+       entry->skb = NULL;
 }
 
 void rt2x00queue_align_frame(struct sk_buff *skb)
@@ -440,7 +441,7 @@ static int rt2x00queue_write_tx_data(struct queue_entry *entry,
         * Map the skb to DMA.
         */
        if (test_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags))
-               rt2x00queue_map_txskb(rt2x00dev, entry->skb);
+               rt2x00queue_map_txskb(entry);
 
        return 0;
 }
@@ -491,7 +492,8 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb,
        if (unlikely(rt2x00queue_full(queue)))
                return -ENOBUFS;
 
-       if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) {
+       if (unlikely(test_and_set_bit(ENTRY_OWNER_DEVICE_DATA,
+                                     &entry->flags))) {
                ERROR(queue->rt2x00dev,
                      "Arrived at non-free entry in the non-full queue %d.\n"
                      "Please file bug report to %s.\n",
@@ -586,8 +588,7 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
        /*
         * Clean up the beacon skb.
         */
-       rt2x00queue_free_skb(rt2x00dev, intf->beacon->skb);
-       intf->beacon->skb = NULL;
+       rt2x00queue_free_skb(intf->beacon);
 
        if (!enable_beacon) {
                rt2x00dev->ops->lib->kill_tx_queue(intf->beacon->queue);
@@ -828,8 +829,7 @@ static int rt2x00queue_alloc_entries(struct data_queue *queue,
        return 0;
 }
 
-static void rt2x00queue_free_skbs(struct rt2x00_dev *rt2x00dev,
-                                 struct data_queue *queue)
+static void rt2x00queue_free_skbs(struct data_queue *queue)
 {
        unsigned int i;
 
@@ -837,19 +837,17 @@ static void rt2x00queue_free_skbs(struct rt2x00_dev *rt2x00dev,
                return;
 
        for (i = 0; i < queue->limit; i++) {
-               if (queue->entries[i].skb)
-                       rt2x00queue_free_skb(rt2x00dev, queue->entries[i].skb);
+               rt2x00queue_free_skb(&queue->entries[i]);
        }
 }
 
-static int rt2x00queue_alloc_rxskbs(struct rt2x00_dev *rt2x00dev,
-                                   struct data_queue *queue)
+static int rt2x00queue_alloc_rxskbs(struct data_queue *queue)
 {
        unsigned int i;
        struct sk_buff *skb;
 
        for (i = 0; i < queue->limit; i++) {
-               skb = rt2x00queue_alloc_rxskb(rt2x00dev, &queue->entries[i]);
+               skb = rt2x00queue_alloc_rxskb(&queue->entries[i]);
                if (!skb)
                        return -ENOMEM;
                queue->entries[i].skb = skb;
@@ -884,7 +882,7 @@ int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev)
                        goto exit;
        }
 
-       status = rt2x00queue_alloc_rxskbs(rt2x00dev, rt2x00dev->rx);
+       status = rt2x00queue_alloc_rxskbs(rt2x00dev->rx);
        if (status)
                goto exit;
 
@@ -902,7 +900,7 @@ void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev)
 {
        struct data_queue *queue;
 
-       rt2x00queue_free_skbs(rt2x00dev, rt2x00dev->rx);
+       rt2x00queue_free_skbs(rt2x00dev->rx);
 
        queue_for_each(rt2x00dev, queue) {
                kfree(queue->entries);
index 4c5ae3d456253ac0a1525fbe592ff9869c06bbc1..b3317df7a7d4afdd88169c8ad16f2ad99984bc9e 100644 (file)
@@ -208,7 +208,7 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
        struct queue_entry *entry = (struct queue_entry *)urb->context;
        struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
 
-       if (!__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
+       if (!test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
                return;
 
        /*
@@ -220,7 +220,7 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
         * Check if the frame was correctly uploaded
         */
        if (urb->status)
-               __set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
+               set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
 
        /*
         * Schedule the delayed work for reading the TX status
@@ -253,7 +253,10 @@ static void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
                          entry->skb->data, length,
                          rt2x00usb_interrupt_txdone, entry);
 
-       usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
+       if (usb_submit_urb(entry_priv->urb, GFP_ATOMIC)) {
+               set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
+               rt2x00lib_dmadone(entry);
+       }
 }
 
 void rt2x00usb_kick_tx_queue(struct data_queue *queue)
@@ -280,14 +283,6 @@ static void rt2x00usb_kill_tx_entry(struct queue_entry *entry)
        if ((entry->queue->qid == QID_BEACON) &&
            (test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags)))
                usb_kill_urb(bcn_priv->guardian_urb);
-
-       /*
-        * We need a short delay here to wait for
-        * the URB to be canceled
-        */
-       do {
-               udelay(100);
-       } while (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags));
 }
 
 void rt2x00usb_kill_tx_queue(struct data_queue *queue)
@@ -363,10 +358,12 @@ void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev)
        struct data_queue *queue;
 
        tx_queue_for_each(rt2x00dev, queue) {
-               if (rt2x00queue_dma_timeout(queue))
-                       rt2x00usb_watchdog_tx_dma(queue);
-               if (rt2x00queue_timeout(queue))
-                       rt2x00usb_watchdog_tx_status(queue);
+               if (!rt2x00queue_empty(queue)) {
+                       if (rt2x00queue_dma_timeout(queue))
+                               rt2x00usb_watchdog_tx_dma(queue);
+                       if (rt2x00queue_timeout(queue))
+                               rt2x00usb_watchdog_tx_status(queue);
+               }
        }
 }
 EXPORT_SYMBOL_GPL(rt2x00usb_watchdog);
@@ -398,7 +395,7 @@ static void rt2x00usb_work_rxdone(struct work_struct *work)
                /*
                 * Send the frame to rt2x00lib for further processing.
                 */
-               rt2x00lib_rxdone(rt2x00dev, entry);
+               rt2x00lib_rxdone(entry);
        }
 }
 
@@ -407,7 +404,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
        struct queue_entry *entry = (struct queue_entry *)urb->context;
        struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
 
-       if (!__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
+       if (!test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
                return;
 
        /*
@@ -421,7 +418,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
         * a problem.
         */
        if (urb->actual_length < entry->queue->desc_size || urb->status)
-               __set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
+               set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
 
        /*
         * Schedule the delayed work for reading the RX status
@@ -467,7 +464,10 @@ void rt2x00usb_clear_entry(struct queue_entry *entry)
                                rt2x00usb_interrupt_rxdone, entry);
 
                set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
-               usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
+               if (usb_submit_urb(entry_priv->urb, GFP_ATOMIC)) {
+                       set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
+                       rt2x00lib_dmadone(entry);
+               }
        }
 }
 EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry);
@@ -542,9 +542,9 @@ static int rt2x00usb_find_endpoints(struct rt2x00_dev *rt2x00dev)
        return 0;
 }
 
-static int rt2x00usb_alloc_urb(struct rt2x00_dev *rt2x00dev,
-                              struct data_queue *queue)
+static int rt2x00usb_alloc_entries(struct data_queue *queue)
 {
+       struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
        struct queue_entry_priv_usb *entry_priv;
        struct queue_entry_priv_usb_bcn *bcn_priv;
        unsigned int i;
@@ -561,7 +561,7 @@ static int rt2x00usb_alloc_urb(struct rt2x00_dev *rt2x00dev,
         * no guardian byte was required for the beacon,
         * then we are done.
         */
-       if (rt2x00dev->bcn != queue ||
+       if (queue->qid != QID_BEACON ||
            !test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags))
                return 0;
 
@@ -575,9 +575,9 @@ static int rt2x00usb_alloc_urb(struct rt2x00_dev *rt2x00dev,
        return 0;
 }
 
-static void rt2x00usb_free_urb(struct rt2x00_dev *rt2x00dev,
-                              struct data_queue *queue)
+static void rt2x00usb_free_entries(struct data_queue *queue)
 {
+       struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
        struct queue_entry_priv_usb *entry_priv;
        struct queue_entry_priv_usb_bcn *bcn_priv;
        unsigned int i;
@@ -596,7 +596,7 @@ static void rt2x00usb_free_urb(struct rt2x00_dev *rt2x00dev,
         * no guardian byte was required for the beacon,
         * then we are done.
         */
-       if (rt2x00dev->bcn != queue ||
+       if (queue->qid != QID_BEACON ||
            !test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags))
                return;
 
@@ -623,7 +623,7 @@ int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev)
         * Allocate DMA
         */
        queue_for_each(rt2x00dev, queue) {
-               status = rt2x00usb_alloc_urb(rt2x00dev, queue);
+               status = rt2x00usb_alloc_entries(queue);
                if (status)
                        goto exit;
        }
@@ -642,7 +642,7 @@ void rt2x00usb_uninitialize(struct rt2x00_dev *rt2x00dev)
        struct data_queue *queue;
 
        queue_for_each(rt2x00dev, queue)
-               rt2x00usb_free_urb(rt2x00dev, queue);
+               rt2x00usb_free_entries(queue);
 }
 EXPORT_SYMBOL_GPL(rt2x00usb_uninitialize);
 
diff --git a/drivers/net/wireless/wl1251/Kconfig b/drivers/net/wireless/wl1251/Kconfig
new file mode 100644 (file)
index 0000000..1fb6584
--- /dev/null
@@ -0,0 +1,33 @@
+menuconfig WL1251
+       tristate "TI wl1251 driver support"
+       depends on MAC80211 && EXPERIMENTAL && GENERIC_HARDIRQS
+       select FW_LOADER
+       select CRC7
+       ---help---
+         This will enable TI wl1251 driver support. The drivers make
+         use of the mac80211 stack.
+
+         If you choose to build a module, it'll be called wl1251. Say
+         N if unsure.
+
+config WL1251_SPI
+       tristate "TI wl1251 SPI support"
+       depends on WL1251 && SPI_MASTER
+       ---help---
+         This module adds support for the SPI interface of adapters using
+         TI wl1251 chipset.  Select this if your platform is using
+         the SPI bus.
+
+         If you choose to build a module, it'll be called wl1251_spi.
+         Say N if unsure.
+
+config WL1251_SDIO
+       tristate "TI wl1251 SDIO support"
+       depends on WL1251 && MMC
+       ---help---
+         This module adds support for the SDIO interface of adapters using
+         TI wl1251 chipset.  Select this if your platform is using
+         the SDIO bus.
+
+         If you choose to build a module, it'll be called
+         wl1251_sdio. Say N if unsure.
diff --git a/drivers/net/wireless/wl1251/Makefile b/drivers/net/wireless/wl1251/Makefile
new file mode 100644 (file)
index 0000000..4fe2468
--- /dev/null
@@ -0,0 +1,6 @@
+wl1251-objs            = main.o event.o tx.o rx.o ps.o cmd.o \
+                         acx.o boot.o init.o debugfs.o io.o
+
+obj-$(CONFIG_WL1251)   += wl1251.o
+obj-$(CONFIG_WL1251_SPI)       += spi.o
+obj-$(CONFIG_WL1251_SDIO)      += sdio.o
similarity index 99%
rename from drivers/net/wireless/wl12xx/wl1251_acx.c
rename to drivers/net/wireless/wl1251/acx.c
index 2f8a2ba744dce84c6afdb6336272abe0fdfb8d90..64a0214cfb29b2b23df56b988e882841e2743edb 100644 (file)
@@ -1,13 +1,13 @@
-#include "wl1251_acx.h"
+#include "acx.h"
 
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/crc7.h>
 
 #include "wl1251.h"
-#include "wl1251_reg.h"
-#include "wl1251_cmd.h"
-#include "wl1251_ps.h"
+#include "reg.h"
+#include "cmd.h"
+#include "ps.h"
 
 int wl1251_acx_frame_rates(struct wl1251 *wl, u8 ctrl_rate, u8 ctrl_mod,
                           u8 mgt_rate, u8 mgt_mod)
similarity index 99%
rename from drivers/net/wireless/wl12xx/wl1251_acx.h
rename to drivers/net/wireless/wl1251/acx.h
index c7cc5c1e8a7571a5f3098a87ad71c83238a1a7e0..e54b21a4f8b195b014998faa2f8bd50875a19ea4 100644 (file)
@@ -24,7 +24,7 @@
 #define __WL1251_ACX_H__
 
 #include "wl1251.h"
-#include "wl1251_cmd.h"
+#include "cmd.h"
 
 /* Target's information element */
 struct acx_header {
similarity index 99%
rename from drivers/net/wireless/wl12xx/wl1251_boot.c
rename to drivers/net/wireless/wl1251/boot.c
index 468b47b0328a01c65b63318e78b49bfc0fd0b8b8..61572dfa1f6059916f068ba7f334c6cd6a9f031d 100644 (file)
 #include <linux/gpio.h>
 #include <linux/slab.h>
 
-#include "wl1251_reg.h"
-#include "wl1251_boot.h"
-#include "wl1251_io.h"
-#include "wl1251_spi.h"
-#include "wl1251_event.h"
-#include "wl1251_acx.h"
+#include "reg.h"
+#include "boot.h"
+#include "io.h"
+#include "spi.h"
+#include "event.h"
+#include "acx.h"
 
 void wl1251_boot_target_enable_interrupts(struct wl1251 *wl)
 {
similarity index 98%
rename from drivers/net/wireless/wl12xx/wl1251_cmd.c
rename to drivers/net/wireless/wl1251/cmd.c
index 15fb68c6b542629bd2d2c389380c489751cd2e41..0ade4bd617c03bcf5486354ea91e66aee55a2567 100644 (file)
@@ -1,14 +1,14 @@
-#include "wl1251_cmd.h"
+#include "cmd.h"
 
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/crc7.h>
 
 #include "wl1251.h"
-#include "wl1251_reg.h"
-#include "wl1251_io.h"
-#include "wl1251_ps.h"
-#include "wl1251_acx.h"
+#include "reg.h"
+#include "io.h"
+#include "ps.h"
+#include "acx.h"
 
 /**
  * send command to firmware
similarity index 99%
rename from drivers/net/wireless/wl12xx/wl1251_debugfs.c
rename to drivers/net/wireless/wl1251/debugfs.c
index 6ffe4cd5856140caf384ecbd4d638c86e54a2538..6e5caaa9f613a4340d9078f70b61a210d2f32c65 100644 (file)
  *
  */
 
-#include "wl1251_debugfs.h"
+#include "debugfs.h"
 
 #include <linux/skbuff.h>
 #include <linux/slab.h>
 
 #include "wl1251.h"
-#include "wl1251_acx.h"
-#include "wl1251_ps.h"
+#include "acx.h"
+#include "ps.h"
 
 /* ms */
 #define WL1251_DEBUGFS_STATS_LIFETIME 1000
similarity index 97%
rename from drivers/net/wireless/wl12xx/wl1251_event.c
rename to drivers/net/wireless/wl1251/event.c
index 54223556b3088d1b9078d6b8131ba6b2f08e185a..712372e50a8794ae550f91709a31589d83e4b90a 100644 (file)
  */
 
 #include "wl1251.h"
-#include "wl1251_reg.h"
-#include "wl1251_io.h"
-#include "wl1251_event.h"
-#include "wl1251_ps.h"
+#include "reg.h"
+#include "io.h"
+#include "event.h"
+#include "ps.h"
 
 static int wl1251_event_scan_complete(struct wl1251 *wl,
                                      struct event_mailbox *mbox)
similarity index 98%
rename from drivers/net/wireless/wl12xx/wl1251_init.c
rename to drivers/net/wireless/wl1251/init.c
index c5daec05d9eedf058804484a0544c32f5f1fea05..89b43d35473c662a6f5763c992dbb1f35e8f18c0 100644 (file)
 #include <linux/module.h>
 #include <linux/slab.h>
 
-#include "wl1251_init.h"
+#include "init.h"
 #include "wl12xx_80211.h"
-#include "wl1251_acx.h"
-#include "wl1251_cmd.h"
-#include "wl1251_reg.h"
+#include "acx.h"
+#include "cmd.h"
+#include "reg.h"
 
 int wl1251_hw_init_hwenc_config(struct wl1251 *wl)
 {
similarity index 99%
rename from drivers/net/wireless/wl12xx/wl1251_io.c
rename to drivers/net/wireless/wl1251/io.c
index ad6ca68b303ffce05ee9855176e060ac8c5e4345..cdcadbf6ac2cfff37a99fa31d34d71933cd34339 100644 (file)
@@ -20,8 +20,8 @@
  */
 
 #include "wl1251.h"
-#include "wl1251_reg.h"
-#include "wl1251_io.h"
+#include "reg.h"
+#include "io.h"
 
 /* FIXME: this is static data nowadays and the table can be removed */
 static enum wl12xx_acx_int_reg wl1251_io_reg_table[ACX_REG_TABLE_LEN] = {
similarity index 99%
rename from drivers/net/wireless/wl12xx/wl1251_main.c
rename to drivers/net/wireless/wl1251/main.c
index faf221ca3f41b6aa4646c633d18c9620bfb55e1e..7a8762553cdcb54470d5b430fa7019fabf6b471c 100644 (file)
 
 #include "wl1251.h"
 #include "wl12xx_80211.h"
-#include "wl1251_reg.h"
-#include "wl1251_io.h"
-#include "wl1251_cmd.h"
-#include "wl1251_event.h"
-#include "wl1251_tx.h"
-#include "wl1251_rx.h"
-#include "wl1251_ps.h"
-#include "wl1251_init.h"
-#include "wl1251_debugfs.h"
-#include "wl1251_boot.h"
+#include "reg.h"
+#include "io.h"
+#include "cmd.h"
+#include "event.h"
+#include "tx.h"
+#include "rx.h"
+#include "ps.h"
+#include "init.h"
+#include "debugfs.h"
+#include "boot.h"
 
 void wl1251_enable_interrupts(struct wl1251 *wl)
 {
similarity index 97%
rename from drivers/net/wireless/wl12xx/wl1251_ps.c
rename to drivers/net/wireless/wl1251/ps.c
index 0b997bdfec09498f9ca5c562eac2becc202cdec0..5ed47c8373d2ae846db307b9d7306781f69564a6 100644 (file)
  *
  */
 
-#include "wl1251_reg.h"
-#include "wl1251_ps.h"
-#include "wl1251_cmd.h"
-#include "wl1251_io.h"
+#include "reg.h"
+#include "ps.h"
+#include "cmd.h"
+#include "io.h"
 
 /* in ms */
 #define WL1251_WAKEUP_TIMEOUT 100
similarity index 97%
rename from drivers/net/wireless/wl12xx/wl1251_ps.h
rename to drivers/net/wireless/wl1251/ps.h
index e5db81fc1dfcc8d710c6761593f6f2dcd0a3d300..55c3dda75e699f45f13beb0f43ed00ad0cee2c14 100644 (file)
@@ -24,7 +24,7 @@
 #define __WL1251_PS_H__
 
 #include "wl1251.h"
-#include "wl1251_acx.h"
+#include "acx.h"
 
 int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode);
 void wl1251_ps_elp_sleep(struct wl1251 *wl);
similarity index 97%
rename from drivers/net/wireless/wl12xx/wl1251_rx.c
rename to drivers/net/wireless/wl1251/rx.c
index 25764592a596c26e412d300bc36d6028cfb34ce8..efa53607d5c9ac9e5ef2f572739f46b562334117 100644 (file)
 #include <net/mac80211.h>
 
 #include "wl1251.h"
-#include "wl1251_reg.h"
-#include "wl1251_io.h"
-#include "wl1251_rx.h"
-#include "wl1251_cmd.h"
-#include "wl1251_acx.h"
+#include "reg.h"
+#include "io.h"
+#include "rx.h"
+#include "cmd.h"
+#include "acx.h"
 
 static void wl1251_rx_header(struct wl1251 *wl,
                             struct wl1251_rx_descriptor *desc)
similarity index 99%
rename from drivers/net/wireless/wl12xx/wl1251_spi.c
rename to drivers/net/wireless/wl1251/spi.c
index 320de79667a6be19caa8f0127f882d84e01dcbeb..88fa8e69d0d1d30b06c76a64cdc8d00f5592754a 100644 (file)
@@ -27,8 +27,8 @@
 #include <linux/wl12xx.h>
 
 #include "wl1251.h"
-#include "wl1251_reg.h"
-#include "wl1251_spi.h"
+#include "reg.h"
+#include "spi.h"
 
 static irqreturn_t wl1251_irq(int irq, void *cookie)
 {
similarity index 96%
rename from drivers/net/wireless/wl12xx/wl1251_spi.h
rename to drivers/net/wireless/wl1251/spi.h
index 7dcf3cf7ae406f148dd94231cccaa51bc91a18ae..16d506955cc0515f797838dd4414e6e0f30b1dcc 100644 (file)
@@ -23,9 +23,9 @@
 #ifndef __WL1251_SPI_H__
 #define __WL1251_SPI_H__
 
-#include "wl1251_cmd.h"
-#include "wl1251_acx.h"
-#include "wl1251_reg.h"
+#include "cmd.h"
+#include "acx.h"
+#include "reg.h"
 
 #define WSPI_CMD_READ                 0x40000000
 #define WSPI_CMD_WRITE                0x00000000
similarity index 99%
rename from drivers/net/wireless/wl12xx/wl1251_tx.c
rename to drivers/net/wireless/wl1251/tx.c
index 388492a7f41f0202028c49e8badbe009bcb46da8..554b4f9a3d3ecf3141ebdec2e0773fb967fcefa6 100644 (file)
 #include <linux/module.h>
 
 #include "wl1251.h"
-#include "wl1251_reg.h"
-#include "wl1251_tx.h"
-#include "wl1251_ps.h"
-#include "wl1251_io.h"
+#include "reg.h"
+#include "tx.h"
+#include "ps.h"
+#include "io.h"
 
 static bool wl1251_tx_double_buffer_busy(struct wl1251 *wl, u32 data_out_count)
 {
similarity index 99%
rename from drivers/net/wireless/wl12xx/wl1251_tx.h
rename to drivers/net/wireless/wl1251/tx.h
index 96011e78cd5a6751059dffb9ee3661e68d82c557..81338d39b43e367300dd139c532eb5f0f908b360 100644 (file)
@@ -24,7 +24,7 @@
 #define __WL1251_TX_H__
 
 #include <linux/bitops.h>
-#include "wl1251_acx.h"
+#include "acx.h"
 
 /*
  *
diff --git a/drivers/net/wireless/wl1251/wl12xx_80211.h b/drivers/net/wireless/wl1251/wl12xx_80211.h
new file mode 100644 (file)
index 0000000..1846280
--- /dev/null
@@ -0,0 +1,156 @@
+#ifndef __WL12XX_80211_H__
+#define __WL12XX_80211_H__
+
+#include <linux/if_ether.h>    /* ETH_ALEN */
+
+/* RATES */
+#define IEEE80211_CCK_RATE_1MB                 0x02
+#define IEEE80211_CCK_RATE_2MB                 0x04
+#define IEEE80211_CCK_RATE_5MB                 0x0B
+#define IEEE80211_CCK_RATE_11MB                        0x16
+#define IEEE80211_OFDM_RATE_6MB                        0x0C
+#define IEEE80211_OFDM_RATE_9MB                        0x12
+#define IEEE80211_OFDM_RATE_12MB               0x18
+#define IEEE80211_OFDM_RATE_18MB               0x24
+#define IEEE80211_OFDM_RATE_24MB               0x30
+#define IEEE80211_OFDM_RATE_36MB               0x48
+#define IEEE80211_OFDM_RATE_48MB               0x60
+#define IEEE80211_OFDM_RATE_54MB               0x6C
+#define IEEE80211_BASIC_RATE_MASK              0x80
+
+#define IEEE80211_CCK_RATE_1MB_MASK            (1<<0)
+#define IEEE80211_CCK_RATE_2MB_MASK            (1<<1)
+#define IEEE80211_CCK_RATE_5MB_MASK            (1<<2)
+#define IEEE80211_CCK_RATE_11MB_MASK           (1<<3)
+#define IEEE80211_OFDM_RATE_6MB_MASK           (1<<4)
+#define IEEE80211_OFDM_RATE_9MB_MASK           (1<<5)
+#define IEEE80211_OFDM_RATE_12MB_MASK          (1<<6)
+#define IEEE80211_OFDM_RATE_18MB_MASK          (1<<7)
+#define IEEE80211_OFDM_RATE_24MB_MASK          (1<<8)
+#define IEEE80211_OFDM_RATE_36MB_MASK          (1<<9)
+#define IEEE80211_OFDM_RATE_48MB_MASK          (1<<10)
+#define IEEE80211_OFDM_RATE_54MB_MASK          (1<<11)
+
+#define IEEE80211_CCK_RATES_MASK         0x0000000F
+#define IEEE80211_CCK_BASIC_RATES_MASK  (IEEE80211_CCK_RATE_1MB_MASK | \
+       IEEE80211_CCK_RATE_2MB_MASK)
+#define IEEE80211_CCK_DEFAULT_RATES_MASK (IEEE80211_CCK_BASIC_RATES_MASK | \
+       IEEE80211_CCK_RATE_5MB_MASK | \
+       IEEE80211_CCK_RATE_11MB_MASK)
+
+#define IEEE80211_OFDM_RATES_MASK        0x00000FF0
+#define IEEE80211_OFDM_BASIC_RATES_MASK          (IEEE80211_OFDM_RATE_6MB_MASK | \
+       IEEE80211_OFDM_RATE_12MB_MASK | \
+       IEEE80211_OFDM_RATE_24MB_MASK)
+#define IEEE80211_OFDM_DEFAULT_RATES_MASK (IEEE80211_OFDM_BASIC_RATES_MASK | \
+       IEEE80211_OFDM_RATE_9MB_MASK  | \
+       IEEE80211_OFDM_RATE_18MB_MASK | \
+       IEEE80211_OFDM_RATE_36MB_MASK | \
+       IEEE80211_OFDM_RATE_48MB_MASK | \
+       IEEE80211_OFDM_RATE_54MB_MASK)
+#define IEEE80211_DEFAULT_RATES_MASK (IEEE80211_OFDM_DEFAULT_RATES_MASK | \
+                                     IEEE80211_CCK_DEFAULT_RATES_MASK)
+
+
+/* This really should be 8, but not for our firmware */
+#define MAX_SUPPORTED_RATES 32
+#define COUNTRY_STRING_LEN 3
+#define MAX_COUNTRY_TRIPLETS 32
+
+/* Headers */
+struct ieee80211_header {
+       __le16 frame_ctl;
+       __le16 duration_id;
+       u8 da[ETH_ALEN];
+       u8 sa[ETH_ALEN];
+       u8 bssid[ETH_ALEN];
+       __le16 seq_ctl;
+       u8 payload[0];
+} __packed;
+
+struct wl12xx_ie_header {
+       u8 id;
+       u8 len;
+} __packed;
+
+/* IEs */
+
+struct wl12xx_ie_ssid {
+       struct wl12xx_ie_header header;
+       char ssid[IW_ESSID_MAX_SIZE];
+} __packed;
+
+struct wl12xx_ie_rates {
+       struct wl12xx_ie_header header;
+       u8 rates[MAX_SUPPORTED_RATES];
+} __packed;
+
+struct wl12xx_ie_ds_params {
+       struct wl12xx_ie_header header;
+       u8 channel;
+} __packed;
+
+struct country_triplet {
+       u8 channel;
+       u8 num_channels;
+       u8 max_tx_power;
+} __packed;
+
+struct wl12xx_ie_country {
+       struct wl12xx_ie_header header;
+       u8 country_string[COUNTRY_STRING_LEN];
+       struct country_triplet triplets[MAX_COUNTRY_TRIPLETS];
+} __packed;
+
+
+/* Templates */
+
+struct wl12xx_beacon_template {
+       struct ieee80211_header header;
+       __le32 time_stamp[2];
+       __le16 beacon_interval;
+       __le16 capability;
+       struct wl12xx_ie_ssid ssid;
+       struct wl12xx_ie_rates rates;
+       struct wl12xx_ie_rates ext_rates;
+       struct wl12xx_ie_ds_params ds_params;
+       struct wl12xx_ie_country country;
+} __packed;
+
+struct wl12xx_null_data_template {
+       struct ieee80211_header header;
+} __packed;
+
+struct wl12xx_ps_poll_template {
+       __le16 fc;
+       __le16 aid;
+       u8 bssid[ETH_ALEN];
+       u8 ta[ETH_ALEN];
+} __packed;
+
+struct wl12xx_qos_null_data_template {
+       struct ieee80211_header header;
+       __le16 qos_ctl;
+} __packed;
+
+struct wl12xx_probe_req_template {
+       struct ieee80211_header header;
+       struct wl12xx_ie_ssid ssid;
+       struct wl12xx_ie_rates rates;
+       struct wl12xx_ie_rates ext_rates;
+} __packed;
+
+
+struct wl12xx_probe_resp_template {
+       struct ieee80211_header header;
+       __le32 time_stamp[2];
+       __le16 beacon_interval;
+       __le16 capability;
+       struct wl12xx_ie_ssid ssid;
+       struct wl12xx_ie_rates rates;
+       struct wl12xx_ie_rates ext_rates;
+       struct wl12xx_ie_ds_params ds_params;
+       struct wl12xx_ie_country country;
+} __packed;
+
+#endif
index 4a8bb25c1739d610295dfeeefe119ae06ca5ee45..b447559f1db52dbf2780afff4ca3454fbecf6dbd 100644 (file)
@@ -5,40 +5,6 @@ menuconfig WL12XX
          This will enable TI wl12xx driver support. The drivers make
          use of the mac80211 stack.
 
-config WL1251
-       tristate "TI wl1251 support"
-       depends on WL12XX && GENERIC_HARDIRQS
-       select FW_LOADER
-       select CRC7
-       ---help---
-         This module adds support for wireless adapters based on
-         TI wl1251 chipset.
-
-         If you choose to build a module, it'll be called wl1251. Say
-         N if unsure.
-
-config WL1251_SPI
-       tristate "TI wl1251 SPI support"
-       depends on WL1251 && SPI_MASTER
-       ---help---
-         This module adds support for the SPI interface of adapters using
-         TI wl1251 chipset.  Select this if your platform is using
-         the SPI bus.
-
-         If you choose to build a module, it'll be called wl1251_spi.
-         Say N if unsure.
-
-config WL1251_SDIO
-       tristate "TI wl1251 SDIO support"
-       depends on WL1251 && MMC
-       ---help---
-         This module adds support for the SDIO interface of adapters using
-         TI wl1251 chipset.  Select this if your platform is using
-         the SDIO bus.
-
-         If you choose to build a module, it'll be called
-         wl1251_sdio. Say N if unsure.
-
 config WL1271
        tristate "TI wl1271 support"
        depends on WL12XX && GENERIC_HARDIRQS
index 0d334d6f86f4261a12b3531a13976ebcde935348..3a807444b2af425f251f41ae026bfa1d350100e7 100644 (file)
@@ -1,12 +1,3 @@
-wl1251-objs            = wl1251_main.o wl1251_event.o \
-                         wl1251_tx.o wl1251_rx.o wl1251_ps.o wl1251_cmd.o \
-                         wl1251_acx.o wl1251_boot.o wl1251_init.o \
-                         wl1251_debugfs.o wl1251_io.o
-
-obj-$(CONFIG_WL1251)   += wl1251.o
-obj-$(CONFIG_WL1251_SPI)       += wl1251_spi.o
-obj-$(CONFIG_WL1251_SDIO)      += wl1251_sdio.o
-
 wl1271-objs            = wl1271_main.o  wl1271_cmd.o wl1271_io.o \
                          wl1271_event.o wl1271_tx.o  wl1271_rx.o   \
                          wl1271_ps.o    wl1271_acx.o wl1271_boot.o \
index 4c250d7dc3fa436d53d9c73362622d188f4d965d..784ef343264139082d12286a816e7c8fa1dc65f1 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/mmc/card.h>
 #include <linux/gpio.h>
 #include <linux/wl12xx.h>
+#include <linux/pm_runtime.h>
 
 #include "wl1271.h"
 #include "wl12xx_80211.h"
@@ -160,12 +161,19 @@ static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf,
 static int wl1271_sdio_power_on(struct wl1271 *wl)
 {
        struct sdio_func *func = wl_to_func(wl);
+       int ret;
+
+       /* Power up the card */
+       ret = pm_runtime_get_sync(&func->dev);
+       if (ret < 0)
+               goto out;
 
        sdio_claim_host(func);
        sdio_enable_func(func);
        sdio_release_host(func);
 
-       return 0;
+out:
+       return ret;
 }
 
 static int wl1271_sdio_power_off(struct wl1271 *wl)
@@ -176,15 +184,12 @@ static int wl1271_sdio_power_off(struct wl1271 *wl)
        sdio_disable_func(func);
        sdio_release_host(func);
 
-       return 0;
+       /* Power down the card */
+       return pm_runtime_put_sync(&func->dev);
 }
 
 static int wl1271_sdio_set_power(struct wl1271 *wl, bool enable)
 {
-       /* Let the SDIO stack handle wlan_enable control, so we
-        * keep host claimed while wlan is in use to keep wl1271
-        * alive.
-        */
        if (enable)
                return wl1271_sdio_power_on(wl);
        else
@@ -256,6 +261,9 @@ static int __devinit wl1271_probe(struct sdio_func *func,
 
        sdio_set_drvdata(func, wl);
 
+       /* Tell PM core that we don't need the card to be powered now */
+       pm_runtime_put_noidle(&func->dev);
+
        wl1271_notice("initialized");
 
        return 0;
@@ -274,16 +282,39 @@ static void __devexit wl1271_remove(struct sdio_func *func)
 {
        struct wl1271 *wl = sdio_get_drvdata(func);
 
+       /* Undo decrement done above in wl1271_probe */
+       pm_runtime_get_noresume(&func->dev);
+
        wl1271_unregister_hw(wl);
        free_irq(wl->irq, wl);
        wl1271_free_hw(wl);
 }
 
+static int wl1271_suspend(struct device *dev)
+{
+       /* Tell MMC/SDIO core it's OK to power down the card
+        * (if it isn't already), but not to remove it completely */
+       return 0;
+}
+
+static int wl1271_resume(struct device *dev)
+{
+       return 0;
+}
+
+static const struct dev_pm_ops wl1271_sdio_pm_ops = {
+       .suspend        = wl1271_suspend,
+       .resume         = wl1271_resume,
+};
+
 static struct sdio_driver wl1271_sdio_driver = {
        .name           = "wl1271_sdio",
        .id_table       = wl1271_devices,
        .probe          = wl1271_probe,
        .remove         = __devexit_p(wl1271_remove),
+       .drv = {
+               .pm = &wl1271_sdio_pm_ops,
+       },
 };
 
 static int __init wl1271_init(void)
index 97b2eae6a22cfe302d9a5956830a93c8cc37dab0..ed5a03cbe184eba3c77799d164d5e8b9b77c0780 100644 (file)
@@ -986,6 +986,7 @@ struct ieee80211_ht_info {
 #define WLAN_AUTH_OPEN 0
 #define WLAN_AUTH_SHARED_KEY 1
 #define WLAN_AUTH_FT 2
+#define WLAN_AUTH_SAE 3
 #define WLAN_AUTH_LEAP 128
 
 #define WLAN_AUTH_CHALLENGE_LEN 128
@@ -1072,6 +1073,10 @@ enum ieee80211_statuscode {
        WLAN_STATUS_NO_DIRECT_LINK = 48,
        WLAN_STATUS_STA_NOT_PRESENT = 49,
        WLAN_STATUS_STA_NOT_QSTA = 50,
+       /* 802.11s */
+       WLAN_STATUS_ANTI_CLOG_REQUIRED = 76,
+       WLAN_STATUS_FCG_NOT_SUPP = 78,
+       WLAN_STATUS_STA_NO_TBTT = 78,
 };
 
 
@@ -1112,6 +1117,22 @@ enum ieee80211_reasoncode {
        WLAN_REASON_QSTA_REQUIRE_SETUP = 38,
        WLAN_REASON_QSTA_TIMEOUT = 39,
        WLAN_REASON_QSTA_CIPHER_NOT_SUPP = 45,
+       /* 802.11s */
+       WLAN_REASON_MESH_PEER_CANCELED = 52,
+       WLAN_REASON_MESH_MAX_PEERS = 53,
+       WLAN_REASON_MESH_CONFIG = 54,
+       WLAN_REASON_MESH_CLOSE = 55,
+       WLAN_REASON_MESH_MAX_RETRIES = 56,
+       WLAN_REASON_MESH_CONFIRM_TIMEOUT = 57,
+       WLAN_REASON_MESH_INVALID_GTK = 58,
+       WLAN_REASON_MESH_INCONSISTENT_PARAM = 59,
+       WLAN_REASON_MESH_INVALID_SECURITY = 60,
+       WLAN_REASON_MESH_PATH_ERROR = 61,
+       WLAN_REASON_MESH_PATH_NOFORWARD = 62,
+       WLAN_REASON_MESH_PATH_DEST_UNREACHABLE = 63,
+       WLAN_REASON_MAC_EXISTS_IN_MBSS = 64,
+       WLAN_REASON_MESH_CHAN_REGULATORY = 65,
+       WLAN_REASON_MESH_CHAN = 66,
 };
 
 
@@ -1139,20 +1160,33 @@ enum ieee80211_eid {
        WLAN_EID_TS_DELAY = 43,
        WLAN_EID_TCLAS_PROCESSING = 44,
        WLAN_EID_QOS_CAPA = 46,
-       /* 802.11s
-        *
-        * All mesh EID numbers are pending IEEE 802.11 ANA approval.
-        * The numbers have been incremented from those suggested in
-        * 802.11s/D2.0 so that MESH_CONFIG does not conflict with
-        * EXT_SUPP_RATES.
+       /* 802.11s */
+       WLAN_EID_MESH_CONFIG = 113,
+       WLAN_EID_MESH_ID = 114,
+       WLAN_EID_LINK_METRIC_REPORT = 115,
+       WLAN_EID_CONGESTION_NOTIFICATION = 116,
+       /* Note that the Peer Link IE has been replaced with the similar
+        * Peer Management IE.  We will keep the former definition until mesh
+        * code is changed to comply with latest 802.11s drafts.
         */
-       WLAN_EID_MESH_CONFIG = 51,
-       WLAN_EID_MESH_ID = 52,
-       WLAN_EID_PEER_LINK = 55,
-       WLAN_EID_PREQ = 68,
-       WLAN_EID_PREP = 69,
-       WLAN_EID_PERR = 70,
-       WLAN_EID_RANN = 49,     /* compatible with FreeBSD */
+       WLAN_EID_PEER_LINK = 55,  /* no longer in 802.11s drafts */
+       WLAN_EID_PEER_MGMT = 117,
+       WLAN_EID_CHAN_SWITCH_PARAM = 118,
+       WLAN_EID_MESH_AWAKE_WINDOW = 119,
+       WLAN_EID_BEACON_TIMING = 120,
+       WLAN_EID_MCCAOP_SETUP_REQ = 121,
+       WLAN_EID_MCCAOP_SETUP_RESP = 122,
+       WLAN_EID_MCCAOP_ADVERT = 123,
+       WLAN_EID_MCCAOP_TEARDOWN = 124,
+       WLAN_EID_GANN = 125,
+       WLAN_EID_RANN = 126,
+       WLAN_EID_PREQ = 130,
+       WLAN_EID_PREP = 131,
+       WLAN_EID_PERR = 132,
+       WLAN_EID_PXU = 137,
+       WLAN_EID_PXUC = 138,
+       WLAN_EID_AUTH_MESH_PEER_EXCH = 139,
+       WLAN_EID_MIC = 140,
 
        WLAN_EID_PWR_CONSTRAINT = 32,
        WLAN_EID_PWR_CAPABILITY = 33,
@@ -1211,9 +1245,14 @@ enum ieee80211_category {
        WLAN_CATEGORY_HT = 7,
        WLAN_CATEGORY_SA_QUERY = 8,
        WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION = 9,
+       WLAN_CATEGORY_MESH_ACTION = 13,
+       WLAN_CATEGORY_MULTIHOP_ACTION = 14,
+       WLAN_CATEGORY_SELF_PROTECTED = 15,
        WLAN_CATEGORY_WMM = 17,
-       WLAN_CATEGORY_MESH_PLINK = 30,          /* Pending ANA approval */
-       WLAN_CATEGORY_MESH_PATH_SEL = 32,       /* Pending ANA approval */
+       /* TODO: remove MESH_PLINK and MESH_PATH_SEL after */
+       /*       mesh is updated to current 802.11s draft  */
+       WLAN_CATEGORY_MESH_PLINK = 30,
+       WLAN_CATEGORY_MESH_PATH_SEL = 32,
        WLAN_CATEGORY_VENDOR_SPECIFIC_PROTECTED = 126,
        WLAN_CATEGORY_VENDOR_SPECIFIC = 127,
 };
@@ -1351,6 +1390,8 @@ enum ieee80211_sa_query_action {
 /* AKM suite selectors */
 #define WLAN_AKM_SUITE_8021X           0x000FAC01
 #define WLAN_AKM_SUITE_PSK             0x000FAC02
+#define WLAN_AKM_SUITE_SAE                     0x000FAC08
+#define WLAN_AKM_SUITE_FT_OVER_SAE     0x000FAC09
 
 #define WLAN_MAX_KEY_LEN               32
 
index c08709fe36fc93f842cb4a6e0149741e0f6efaa6..0edb2566c14ca6602a188c422fe0a10fdc17bdff 100644 (file)
@@ -1413,6 +1413,16 @@ enum nl80211_reg_rule_flags {
  * @NL80211_SURVEY_INFO_FREQUENCY: center frequency of channel
  * @NL80211_SURVEY_INFO_NOISE: noise level of channel (u8, dBm)
  * @NL80211_SURVEY_INFO_IN_USE: channel is currently being used
+ * @NL80211_SURVEY_INFO_CHANNEL_TIME: amount of time (in ms) that the radio
+ *     spent on this channel
+ * @NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY: amount of the time the primary
+ *     channel was sensed busy (either due to activity or energy detect)
+ * @NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY: amount of time the extension
+ *     channel was sensed busy
+ * @NL80211_SURVEY_INFO_CHANNEL_TIME_RX: amount of time the radio spent
+ *     receiving data
+ * @NL80211_SURVEY_INFO_CHANNEL_TIME_TX: amount of time the radio spent
+ *     transmitting data
  * @NL80211_SURVEY_INFO_MAX: highest survey info attribute number
  *     currently defined
  * @__NL80211_SURVEY_INFO_AFTER_LAST: internal use
@@ -1422,6 +1432,11 @@ enum nl80211_survey_info {
        NL80211_SURVEY_INFO_FREQUENCY,
        NL80211_SURVEY_INFO_NOISE,
        NL80211_SURVEY_INFO_IN_USE,
+       NL80211_SURVEY_INFO_CHANNEL_TIME,
+       NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY,
+       NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY,
+       NL80211_SURVEY_INFO_CHANNEL_TIME_RX,
+       NL80211_SURVEY_INFO_CHANNEL_TIME_TX,
 
        /* keep last */
        __NL80211_SURVEY_INFO_AFTER_LAST,
index e6827eedf18bc4934f0f6b47e7b7a7c4de76f0df..4395b28bb86c3bc2db796c284eec108fb4baab4c 100644 (file)
@@ -1157,6 +1157,6 @@ struct __compat_iw_event {
 #define IW_EV_PARAM_PK_LEN     (IW_EV_LCP_PK_LEN + sizeof(struct iw_param))
 #define IW_EV_ADDR_PK_LEN      (IW_EV_LCP_PK_LEN + sizeof(struct sockaddr))
 #define IW_EV_QUAL_PK_LEN      (IW_EV_LCP_PK_LEN + sizeof(struct iw_quality))
-#define IW_EV_POINT_PK_LEN     (IW_EV_LCP_LEN + 4)
+#define IW_EV_POINT_PK_LEN     (IW_EV_LCP_PK_LEN + 4)
 
 #endif /* _LINUX_WIRELESS_H */
index 0778d04b3bbe48ae52eabef6027cbbb3f0bec556..2a7936d7851d55de60251fc708672a87d5beb81b 100644 (file)
@@ -294,6 +294,11 @@ struct key_params {
  *
  * @SURVEY_INFO_NOISE_DBM: noise (in dBm) was filled in
  * @SURVEY_INFO_IN_USE: channel is currently being used
+ * @SURVEY_INFO_CHANNEL_TIME: channel active time (in ms) was filled in
+ * @SURVEY_INFO_CHANNEL_TIME_BUSY: channel busy time was filled in
+ * @SURVEY_INFO_CHANNEL_TIME_EXT_BUSY: extension channel busy time was filled in
+ * @SURVEY_INFO_CHANNEL_TIME_RX: channel receive time was filled in
+ * @SURVEY_INFO_CHANNEL_TIME_TX: channel transmit time was filled in
  *
  * Used by the driver to indicate which info in &struct survey_info
  * it has filled in during the get_survey().
@@ -301,6 +306,11 @@ struct key_params {
 enum survey_info_flags {
        SURVEY_INFO_NOISE_DBM = 1<<0,
        SURVEY_INFO_IN_USE = 1<<1,
+       SURVEY_INFO_CHANNEL_TIME = 1<<2,
+       SURVEY_INFO_CHANNEL_TIME_BUSY = 1<<3,
+       SURVEY_INFO_CHANNEL_TIME_EXT_BUSY = 1<<4,
+       SURVEY_INFO_CHANNEL_TIME_RX = 1<<5,
+       SURVEY_INFO_CHANNEL_TIME_TX = 1<<6,
 };
 
 /**
@@ -310,6 +320,11 @@ enum survey_info_flags {
  * @filled: bitflag of flags from &enum survey_info_flags
  * @noise: channel noise in dBm. This and all following fields are
  *     optional
+ * @channel_time: amount of time in ms the radio spent on the channel
+ * @channel_time_busy: amount of time the primary channel was sensed busy
+ * @channel_time_ext_busy: amount of time the extension channel was sensed busy
+ * @channel_time_rx: amount of time the radio spent receiving data
+ * @channel_time_tx: amount of time the radio spent transmitting data
  *
  * Used by dump_survey() to report back per-channel survey information.
  *
@@ -318,6 +333,11 @@ enum survey_info_flags {
  */
 struct survey_info {
        struct ieee80211_channel *channel;
+       u64 channel_time;
+       u64 channel_time_busy;
+       u64 channel_time_ext_busy;
+       u64 channel_time_rx;
+       u64 channel_time_tx;
        u32 filled;
        s8 noise;
 };
@@ -403,6 +423,7 @@ struct station_parameters {
  * @STATION_INFO_TX_PACKETS: @tx_packets filled
  * @STATION_INFO_TX_RETRIES: @tx_retries filled
  * @STATION_INFO_TX_FAILED: @tx_failed filled
+ * @STATION_INFO_RX_DROP_MISC: @rx_dropped_misc filled
  */
 enum station_info_flags {
        STATION_INFO_INACTIVE_TIME      = 1<<0,
@@ -417,6 +438,7 @@ enum station_info_flags {
        STATION_INFO_TX_PACKETS         = 1<<9,
        STATION_INFO_TX_RETRIES         = 1<<10,
        STATION_INFO_TX_FAILED          = 1<<11,
+       STATION_INFO_RX_DROP_MISC       = 1<<12,
 };
 
 /**
@@ -468,6 +490,7 @@ struct rate_info {
  * @tx_packets: packets transmitted to this station
  * @tx_retries: cumulative retry counts
  * @tx_failed: number of failed transmissions (retries exceeded, no ACK)
+ * @rx_dropped_misc:  Dropped for un-specified reason.
  * @generation: generation number for nl80211 dumps.
  *     This number should increase every time the list of stations
  *     changes, i.e. when a station is added or removed, so that
@@ -487,6 +510,7 @@ struct station_info {
        u32 tx_packets;
        u32 tx_retries;
        u32 tx_failed;
+       u32 rx_dropped_misc;
 
        int generation;
 };
@@ -1123,6 +1147,9 @@ struct cfg80211_pmksa {
  *     allows the driver to adjust the dynamic ps timeout value.
  * @set_cqm_rssi_config: Configure connection quality monitor RSSI threshold.
  *
+ * @mgmt_frame_register: Notify driver that a management frame type was
+ *     registered. Note that this callback may not sleep, and cannot run
+ *     concurrently with itself.
  */
 struct cfg80211_ops {
        int     (*suspend)(struct wiphy *wiphy);
@@ -1273,6 +1300,10 @@ struct cfg80211_ops {
        int     (*set_cqm_rssi_config)(struct wiphy *wiphy,
                                       struct net_device *dev,
                                       s32 rssi_thold, u32 rssi_hyst);
+
+       void    (*mgmt_frame_register)(struct wiphy *wiphy,
+                                      struct net_device *dev,
+                                      u16 frame_type, bool reg);
 };
 
 /*
index 33aa2e39147b12baff9542729c70af6675898e01..9fdf982d1286a95c02a73bae4131746f05de9343 100644 (file)
@@ -1478,12 +1478,14 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw,
  *     honour this flag if possible.
  *
  * @FIF_CONTROL: pass control frames (except for PS Poll), if PROMISC_IN_BSS
- *  is not set then only those addressed to this station.
+ *     is not set then only those addressed to this station.
  *
  * @FIF_OTHER_BSS: pass frames destined to other BSSes
  *
- * @FIF_PSPOLL: pass PS Poll frames, if PROMISC_IN_BSS  is not set then only
- *  those addressed to this station.
+ * @FIF_PSPOLL: pass PS Poll frames, if PROMISC_IN_BSS is not set then only
+ *     those addressed to this station.
+ *
+ * @FIF_PROBE_REQ: pass probe request frames
  */
 enum ieee80211_filter_flags {
        FIF_PROMISC_IN_BSS      = 1<<0,
@@ -1494,6 +1496,7 @@ enum ieee80211_filter_flags {
        FIF_CONTROL             = 1<<5,
        FIF_OTHER_BSS           = 1<<6,
        FIF_PSPOLL              = 1<<7,
+       FIF_PROBE_REQ           = 1<<8,
 };
 
 /**
index ecf9b7166ed151f044755534fe4b071c9ad382c5..18bd0e550600fccac46a106d3f29ffd7d609ce5b 100644 (file)
@@ -329,7 +329,8 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
                        STATION_INFO_TX_PACKETS |
                        STATION_INFO_TX_RETRIES |
                        STATION_INFO_TX_FAILED |
-                       STATION_INFO_TX_BITRATE;
+                       STATION_INFO_TX_BITRATE |
+                       STATION_INFO_RX_DROP_MISC;
 
        sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx);
        sinfo->rx_bytes = sta->rx_bytes;
@@ -338,6 +339,7 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
        sinfo->tx_packets = sta->tx_packets;
        sinfo->tx_retries = sta->tx_retry_count;
        sinfo->tx_failed = sta->tx_retry_failed;
+       sinfo->rx_dropped_misc = sta->rx_dropped;
 
        if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) ||
            (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) {
@@ -1602,6 +1604,23 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
        return 0;
 }
 
+static void ieee80211_mgmt_frame_register(struct wiphy *wiphy,
+                                         struct net_device *dev,
+                                         u16 frame_type, bool reg)
+{
+       struct ieee80211_local *local = wiphy_priv(wiphy);
+
+       if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ))
+               return;
+
+       if (reg)
+               local->probe_req_reg++;
+       else
+               local->probe_req_reg--;
+
+       ieee80211_queue_work(&local->hw, &local->reconfig_filter);
+}
+
 struct cfg80211_ops mac80211_config_ops = {
        .add_virtual_intf = ieee80211_add_iface,
        .del_virtual_intf = ieee80211_del_iface,
@@ -1653,4 +1672,5 @@ struct cfg80211_ops mac80211_config_ops = {
        .cancel_remain_on_channel = ieee80211_cancel_remain_on_channel,
        .mgmt_tx = ieee80211_mgmt_tx,
        .set_cqm_rssi_config = ieee80211_set_cqm_rssi_config,
+       .mgmt_frame_register = ieee80211_mgmt_frame_register,
 };
index 4214bb6e12fc501cf55749dda1574e3fcd4696eb..75d679d75e63e92143d55a47601a1dfc1377ba03 100644 (file)
@@ -291,6 +291,8 @@ void ieee80211_request_smps(struct ieee80211_vif *vif,
        if (WARN_ON(smps_mode == IEEE80211_SMPS_OFF))
                smps_mode = IEEE80211_SMPS_AUTOMATIC;
 
+       sdata->u.mgd.driver_smps_mode = smps_mode;
+
        ieee80211_queue_work(&sdata->local->hw,
                             &sdata->u.mgd.request_smps_work);
 }
index f0610fa4fbe078efce627592e4dad49015362ce6..b80c386899276dd436ebc93caab1957622389be5 100644 (file)
@@ -707,7 +707,9 @@ struct ieee80211_local {
        int open_count;
        int monitors, cooked_mntrs;
        /* number of interfaces with corresponding FIF_ flags */
-       int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll;
+       int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll,
+           fif_probe_req;
+       int probe_req_reg;
        unsigned int filter_flags; /* FIF_* */
 
        bool wiphy_ciphers_allocated;
index e99d1b60557cb0f932ec570acb08b11f26738ed9..f9163b12c7f17aca87970366d3069f563b8a6655 100644 (file)
@@ -280,8 +280,11 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
                        ieee80211_start_mesh(sdata);
                } else if (sdata->vif.type == NL80211_IFTYPE_AP) {
                        local->fif_pspoll++;
+                       local->fif_probe_req++;
 
                        ieee80211_configure_filter(local);
+               } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
+                       local->fif_probe_req++;
                }
 
                changed |= ieee80211_reset_erp_info(sdata);
@@ -428,8 +431,12 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
        if (sdata->flags & IEEE80211_SDATA_PROMISC)
                atomic_dec(&local->iff_promiscs);
 
-       if (sdata->vif.type == NL80211_IFTYPE_AP)
+       if (sdata->vif.type == NL80211_IFTYPE_AP) {
                local->fif_pspoll--;
+               local->fif_probe_req--;
+       } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
+               local->fif_probe_req--;
+       }
 
        netif_addr_lock_bh(sdata->dev);
        spin_lock_bh(&local->filter_lock);
index eb0f5997767610f6466032adfb7a529b5ad80aa3..22bc42b18991c2c61c8562f8a5d841e53ed73e37 100644 (file)
@@ -54,6 +54,9 @@ void ieee80211_configure_filter(struct ieee80211_local *local)
        if (local->monitors || local->scanning)
                new_flags |= FIF_BCN_PRBRESP_PROMISC;
 
+       if (local->fif_probe_req || local->probe_req_reg)
+               new_flags |= FIF_PROBE_REQ;
+
        if (local->fif_fcsfail)
                new_flags |= FIF_FCSFAIL;
 
index ea13a80a476c1fe0db6dc5e0059e2014f340926e..1c91f0f3c3079ba9f6a8d94097d6e637b948cdad 100644 (file)
@@ -412,7 +412,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
        enum plink_event event;
        enum plink_frame_type ftype;
        size_t baselen;
-       bool deactivated;
+       bool deactivated, matches_local = true;
        u8 ie_len;
        u8 *baseaddr;
        __le16 plid, llid, reason;
@@ -487,6 +487,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
        /* Now we will figure out the appropriate event... */
        event = PLINK_UNDEFINED;
        if (ftype != PLINK_CLOSE && (!mesh_matches_local(&elems, sdata))) {
+               matches_local = false;
                switch (ftype) {
                case PLINK_OPEN:
                        event = OPN_RJCT;
@@ -498,7 +499,15 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
                        /* avoid warning */
                        break;
                }
-               spin_lock_bh(&sta->lock);
+       }
+
+       if (!sta && !matches_local) {
+               rcu_read_unlock();
+               reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION);
+               llid = 0;
+               mesh_plink_frame_tx(sdata, PLINK_CLOSE, mgmt->sa, llid,
+                                   plid, reason);
+               return;
        } else if (!sta) {
                /* ftype == PLINK_OPEN */
                u32 rates;
@@ -522,7 +531,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
                }
                event = OPN_ACPT;
                spin_lock_bh(&sta->lock);
-       } else {
+       } else if (matches_local) {
                spin_lock_bh(&sta->lock);
                switch (ftype) {
                case PLINK_OPEN:
@@ -564,6 +573,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
                        rcu_read_unlock();
                        return;
                }
+       } else {
+               spin_lock_bh(&sta->lock);
        }
 
        mpl_dbg("Mesh plink (peer, state, llid, plid, event): %pM %s %d %d %d\n",
index 5695c94c49aac10f074da18868263d5d1b9a58d3..a3a9421555af30201e13d8ea24c36f4bb759680f 100644 (file)
@@ -1864,10 +1864,12 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
 
                else if (ifmgd->probe_send_count < IEEE80211_MAX_PROBE_TRIES) {
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
-                       printk(KERN_DEBUG "No probe response from AP %pM"
-                               " after %dms, try %d\n", bssid,
-                               (1000 * IEEE80211_PROBE_WAIT)/HZ,
-                               ifmgd->probe_send_count);
+                       wiphy_debug(local->hw.wiphy,
+                                   "%s: No probe response from AP %pM"
+                                   " after %dms, try %d\n",
+                                   sdata->name,
+                                   bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ,
+                                   ifmgd->probe_send_count);
 #endif
                        ieee80211_mgd_probe_ap_send(sdata);
                } else {
@@ -1877,9 +1879,11 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
                         */
                        ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL |
                                          IEEE80211_STA_BEACON_POLL);
-                       printk(KERN_DEBUG "No probe response from AP %pM"
-                               " after %dms, disconnecting.\n",
-                               bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ);
+                       wiphy_debug(local->hw.wiphy,
+                                   "%s: No probe response from AP %pM"
+                                   " after %dms, disconnecting.\n",
+                                   sdata->name,
+                                   bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ);
                        ieee80211_set_disassoc(sdata, true, true);
                        mutex_unlock(&ifmgd->mtx);
                        mutex_lock(&local->mtx);
index c5b465904e3bfcec2ac0199e64dda46072022330..2a18d6602d4ade8bc385fecc4bca919811875ba1 100644 (file)
@@ -397,8 +397,9 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband,
            !(info->flags & IEEE80211_TX_STAT_AMPDU))
                return;
 
-       if (!info->status.ampdu_len) {
-               info->status.ampdu_ack_len = 1;
+       if (!(info->flags & IEEE80211_TX_STAT_AMPDU)) {
+               info->status.ampdu_ack_len =
+                       (info->flags & IEEE80211_TX_STAT_ACK ? 1 : 0);
                info->status.ampdu_len = 1;
        }
 
@@ -426,7 +427,7 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband,
                group = minstrel_ht_get_group_idx(&ar[i]);
                rate = &mi->groups[group].rates[ar[i].idx % 8];
 
-               if (last && (info->flags & IEEE80211_TX_STAT_ACK))
+               if (last)
                        rate->success += info->status.ampdu_ack_len;
 
                rate->attempts += ar[i].count * info->status.ampdu_len;
index b67221def5844fa50edd3b246227c80bb95b463e..902b03ee8f60789bab002691e2db69d1f8c12cf4 100644 (file)
@@ -622,6 +622,26 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw,
                                                        tid_agg_rx->buf_size;
        }
 
+       /*
+        * Disable the reorder release timer for now.
+        *
+        * The current implementation lacks a proper locking scheme
+        * which would protect vital statistic and debug counters
+        * from being updated by two different but concurrent BHs.
+        *
+        * More information about the topic is available from:
+        * - thread: http://marc.info/?t=128635927000001
+        *
+        * What was wrong:
+        * =>  http://marc.info/?l=linux-wireless&m=128636170811964
+        * "Basically the thing is that until your patch, the data
+        *  in the struct didn't actually need locking because it
+        *  was accessed by the RX path only which is not concurrent."
+        *
+        * List of what needs to be fixed:
+        * => http://marc.info/?l=linux-wireless&m=128656352920957
+        *
+
        if (tid_agg_rx->stored_mpdu_num) {
                j = index = seq_sub(tid_agg_rx->head_seq_num,
                                    tid_agg_rx->ssn) % tid_agg_rx->buf_size;
@@ -640,6 +660,10 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw,
        } else {
                del_timer(&tid_agg_rx->reorder_timer);
        }
+       */
+
+set_release_timer:
+       return;
 }
 
 /*
index f27484c22b9f40bf3876825b451e63670523ea39..2ff6d1e3ed21565524fc55c724b24bbee67dd0c6 100644 (file)
@@ -222,7 +222,7 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local,
                                 struct ieee80211_key *key)
 {
        u32 klen;
-       u8 *rc4key;
+       u8 rc4key[3 + WLAN_KEY_LEN_WEP104];
        u8 keyidx;
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
        unsigned int hdrlen;
@@ -245,10 +245,6 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local,
 
        klen = 3 + key->conf.keylen;
 
-       rc4key = kmalloc(klen, GFP_ATOMIC);
-       if (!rc4key)
-               return -1;
-
        /* Prepend 24-bit IV to RC4 key */
        memcpy(rc4key, skb->data + hdrlen, 3);
 
@@ -260,8 +256,6 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local,
                                       len))
                ret = -1;
 
-       kfree(rc4key);
-
        /* Trim ICV */
        skb_trim(skb, skb->len - WEP_ICV_LEN);
 
index 1684ad91763ced2f059e944d46b39d4729939f4d..9c21ebf9780ea21ff22c9326da29a423061d088b 100644 (file)
@@ -178,10 +178,26 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
                        char *newname)
 {
        struct cfg80211_registered_device *rdev2;
-       int result;
+       int wiphy_idx, taken = -1, result, digits;
 
        assert_cfg80211_lock();
 
+       /* prohibit calling the thing phy%d when %d is not its number */
+       sscanf(newname, PHY_NAME "%d%n", &wiphy_idx, &taken);
+       if (taken == strlen(newname) && wiphy_idx != rdev->wiphy_idx) {
+               /* count number of places needed to print wiphy_idx */
+               digits = 1;
+               while (wiphy_idx /= 10)
+                       digits++;
+               /*
+                * deny the name if it is phy<idx> where <idx> is printed
+                * without leading zeroes. taken == strlen(newname) here
+                */
+               if (taken == strlen(PHY_NAME) + digits)
+                       return -EINVAL;
+       }
+
+
        /* Ignore nop renames */
        if (strcmp(newname, dev_name(&rdev->wiphy.dev)) == 0)
                return 0;
@@ -189,7 +205,7 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
        /* Ensure another device does not already have this name. */
        list_for_each_entry(rdev2, &cfg80211_rdev_list, list)
                if (strcmp(newname, dev_name(&rdev2->wiphy.dev)) == 0)
-                       return -EEXIST;
+                       return -EINVAL;
 
        result = device_rename(&rdev->wiphy.dev, newname);
        if (result)
@@ -304,11 +320,9 @@ static void cfg80211_event_work(struct work_struct *work)
 struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
 {
        static int wiphy_counter;
-       int i;
-       struct cfg80211_registered_device *rdev, *rdev2;
+
+       struct cfg80211_registered_device *rdev;
        int alloc_size;
-       char nname[IFNAMSIZ + 1];
-       bool found = false;
 
        WARN_ON(ops->add_key && (!ops->del_key || !ops->set_default_key));
        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)
 
        if (unlikely(!wiphy_idx_valid(rdev->wiphy_idx))) {
                wiphy_counter--;
-               goto too_many_devs;
-       }
-
-       /* 64k wiphy devices is enough for anyone! */
-       for (i = 0; i < 0xFFFF; i++) {
-               found = false;
-               snprintf(nname, sizeof(nname)-1, PHY_NAME "%d", i);
-               nname[sizeof(nname)-1] = 0;
-               list_for_each_entry(rdev2, &cfg80211_rdev_list, list)
-                       if (strcmp(nname, dev_name(&rdev2->wiphy.dev)) == 0) {
-                               found = true;
-                               break;
-                       }
-
-               if (!found)
-                       break;
-       }
-
-       if (unlikely(found)) {
-too_many_devs:
                mutex_unlock(&cfg80211_mutex);
-               /* ugh, too many devices already! */
+               /* ugh, wrapped! */
                kfree(rdev);
                return NULL;
        }
 
-       /* give it a proper name */
-       dev_set_name(&rdev->wiphy.dev, "%s", nname);
-
        mutex_unlock(&cfg80211_mutex);
 
+       /* give it a proper name */
+       dev_set_name(&rdev->wiphy.dev, PHY_NAME "%d", rdev->wiphy_idx);
+
        mutex_init(&rdev->mtx);
        mutex_init(&rdev->devlist_mtx);
        INIT_LIST_HEAD(&rdev->netdev_list);
index caf11a4275073c7fc7ba0f47937adf67da41384a..26838d903b9a962b2efb5f274cad5ef01c24c4fc 100644 (file)
@@ -764,6 +764,8 @@ int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid,
                                u16 frame_type, const u8 *match_data,
                                int match_len)
 {
+       struct wiphy *wiphy = wdev->wiphy;
+       struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
        struct cfg80211_mgmt_registration *reg, *nreg;
        int err = 0;
        u16 mgmt_type;
@@ -810,22 +812,37 @@ int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid,
        nreg->frame_type = cpu_to_le16(frame_type);
        list_add(&nreg->list, &wdev->mgmt_registrations);
 
+       if (rdev->ops->mgmt_frame_register)
+               rdev->ops->mgmt_frame_register(wiphy, wdev->netdev,
+                                              frame_type, true);
+
  out:
        spin_unlock_bh(&wdev->mgmt_registrations_lock);
+
        return err;
 }
 
 void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid)
 {
+       struct wiphy *wiphy = wdev->wiphy;
+       struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
        struct cfg80211_mgmt_registration *reg, *tmp;
 
        spin_lock_bh(&wdev->mgmt_registrations_lock);
 
        list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) {
-               if (reg->nlpid == nlpid) {
-                       list_del(&reg->list);
-                       kfree(reg);
+               if (reg->nlpid != nlpid)
+                       continue;
+
+               if (rdev->ops->mgmt_frame_register) {
+                       u16 frame_type = le16_to_cpu(reg->frame_type);
+
+                       rdev->ops->mgmt_frame_register(wiphy, wdev->netdev,
+                                                      frame_type, false);
                }
+
+               list_del(&reg->list);
+               kfree(reg);
        }
 
        spin_unlock_bh(&wdev->mgmt_registrations_lock);
index 882dc921103ba91d29b630a703752b7d3a322ed2..c506241f863706426e76d66736d0258eda34d769 100644 (file)
@@ -3153,6 +3153,21 @@ static int nl80211_send_survey(struct sk_buff *msg, u32 pid, u32 seq,
                            survey->noise);
        if (survey->filled & SURVEY_INFO_IN_USE)
                NLA_PUT_FLAG(msg, NL80211_SURVEY_INFO_IN_USE);
+       if (survey->filled & SURVEY_INFO_CHANNEL_TIME)
+               NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME,
+                           survey->channel_time);
+       if (survey->filled & SURVEY_INFO_CHANNEL_TIME_BUSY)
+               NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY,
+                           survey->channel_time_busy);
+       if (survey->filled & SURVEY_INFO_CHANNEL_TIME_EXT_BUSY)
+               NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY,
+                           survey->channel_time_ext_busy);
+       if (survey->filled & SURVEY_INFO_CHANNEL_TIME_RX)
+               NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_RX,
+                           survey->channel_time_rx);
+       if (survey->filled & SURVEY_INFO_CHANNEL_TIME_TX)
+               NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_TX,
+                           survey->channel_time_tx);
 
        nla_nest_end(msg, infoattr);
 
index c774bc0f155ecb381ae3069f486f661ee31aac1c..dbe35e138e945f1bfc63aae4fdcb3a0c1e371b0b 100644 (file)
@@ -201,7 +201,7 @@ int ieee80211_radiotap_iterator_next(
 {
        while (1) {
                int hit = 0;
-               int pad, align, size, subns, vnslen;
+               int pad, align, size, subns;
                uint32_t oui;
 
                /* if no more EXT bits, that's it */
@@ -261,6 +261,27 @@ int ieee80211_radiotap_iterator_next(
                if (pad)
                        iterator->_arg += align - pad;
 
+               if (iterator->_arg_index % 32 == IEEE80211_RADIOTAP_VENDOR_NAMESPACE) {
+                       int vnslen;
+
+                       if ((unsigned long)iterator->_arg + size -
+                           (unsigned long)iterator->_rtheader >
+                           (unsigned long)iterator->_max_length)
+                               return -EINVAL;
+
+                       oui = (*iterator->_arg << 16) |
+                               (*(iterator->_arg + 1) << 8) |
+                               *(iterator->_arg + 2);
+                       subns = *(iterator->_arg + 3);
+
+                       find_ns(iterator, oui, subns);
+
+                       vnslen = get_unaligned_le16(iterator->_arg + 4);
+                       iterator->_next_ns_data = iterator->_arg + size + vnslen;
+                       if (!iterator->current_namespace)
+                               size += vnslen;
+               }
+
                /*
                 * this is what we will return to user, but we need to
                 * move on first so next call has something fresh to test
@@ -287,40 +308,25 @@ int ieee80211_radiotap_iterator_next(
                /* these special ones are valid in each bitmap word */
                switch (iterator->_arg_index % 32) {
                case IEEE80211_RADIOTAP_VENDOR_NAMESPACE:
-                       iterator->_bitmap_shifter >>= 1;
-                       iterator->_arg_index++;
-
                        iterator->_reset_on_ext = 1;
 
-                       vnslen = get_unaligned_le16(iterator->this_arg + 4);
-                       iterator->_next_ns_data = iterator->_arg + vnslen;
-                       oui = (*iterator->this_arg << 16) |
-                               (*(iterator->this_arg + 1) << 8) |
-                               *(iterator->this_arg + 2);
-                       subns = *(iterator->this_arg + 3);
-
-                       find_ns(iterator, oui, subns);
-
                        iterator->is_radiotap_ns = 0;
-                       /* allow parsers to show this information */
+                       /*
+                        * If parser didn't register this vendor
+                        * namespace with us, allow it to show it
+                        * as 'raw. Do do that, set argument index
+                        * to vendor namespace.
+                        */
                        iterator->this_arg_index =
                                IEEE80211_RADIOTAP_VENDOR_NAMESPACE;
-                       iterator->this_arg_size += vnslen;
-                       if ((unsigned long)iterator->this_arg +
-                           iterator->this_arg_size -
-                           (unsigned long)iterator->_rtheader >
-                           (unsigned long)(unsigned long)iterator->_max_length)
-                               return -EINVAL;
-                       hit = 1;
-                       break;
+                       if (!iterator->current_namespace)
+                               hit = 1;
+                       goto next_entry;
                case IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE:
-                       iterator->_bitmap_shifter >>= 1;
-                       iterator->_arg_index++;
-
                        iterator->_reset_on_ext = 1;
                        iterator->current_namespace = &radiotap_ns;
                        iterator->is_radiotap_ns = 1;
-                       break;
+                       goto next_entry;
                case IEEE80211_RADIOTAP_EXT:
                        /*
                         * bit 31 was set, there is more
index 74a9e3cce45249a4ab21a909fa28806127409f7f..4294fa22bb2dfc15cbd6d0d2e7c0303a42f7d278 100644 (file)
@@ -35,6 +35,14 @@ SHOW_FMT(index, "%d", wiphy_idx);
 SHOW_FMT(macaddress, "%pM", wiphy.perm_addr);
 SHOW_FMT(address_mask, "%pM", wiphy.addr_mask);
 
+static ssize_t name_show(struct device *dev,
+                        struct device_attribute *attr,
+                        char *buf) {
+       struct wiphy *wiphy = &dev_to_rdev(dev)->wiphy;
+       return sprintf(buf, "%s\n", dev_name(&wiphy->dev));
+}
+
+
 static ssize_t addresses_show(struct device *dev,
                              struct device_attribute *attr,
                              char *buf)
@@ -57,6 +65,7 @@ static struct device_attribute ieee80211_dev_attrs[] = {
        __ATTR_RO(macaddress),
        __ATTR_RO(address_mask),
        __ATTR_RO(addresses),
+       __ATTR_RO(name),
        {}
 };
 
index 6002265289c6267ce182531865c8e4f6db3d947e..12222ee6ebf2f3a5e6a7c1f7782e4979a95b227e 100644 (file)
@@ -1366,6 +1366,10 @@ struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev)
        }
 
        wstats.qual.updated |= IW_QUAL_NOISE_INVALID;
+       if (sinfo.filled & STATION_INFO_RX_DROP_MISC)
+               wstats.discard.misc = sinfo.rx_dropped_misc;
+       if (sinfo.filled & STATION_INFO_TX_FAILED)
+               wstats.discard.retries = sinfo.tx_failed;
 
        return &wstats;
 }