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)
178 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 [new file with mode: 0644]
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-calib.h [deleted file]
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 [new file with mode: 0644]
drivers/net/wireless/wl1251/acx.h [new file with mode: 0644]
drivers/net/wireless/wl1251/boot.c [new file with mode: 0644]
drivers/net/wireless/wl1251/boot.h [new file with mode: 0644]
drivers/net/wireless/wl1251/cmd.c [new file with mode: 0644]
drivers/net/wireless/wl1251/cmd.h [new file with mode: 0644]
drivers/net/wireless/wl1251/debugfs.c [new file with mode: 0644]
drivers/net/wireless/wl1251/debugfs.h [new file with mode: 0644]
drivers/net/wireless/wl1251/event.c [new file with mode: 0644]
drivers/net/wireless/wl1251/event.h [new file with mode: 0644]
drivers/net/wireless/wl1251/init.c [new file with mode: 0644]
drivers/net/wireless/wl1251/init.h [new file with mode: 0644]
drivers/net/wireless/wl1251/io.c [new file with mode: 0644]
drivers/net/wireless/wl1251/io.h [new file with mode: 0644]
drivers/net/wireless/wl1251/main.c [new file with mode: 0644]
drivers/net/wireless/wl1251/ps.c [new file with mode: 0644]
drivers/net/wireless/wl1251/ps.h [new file with mode: 0644]
drivers/net/wireless/wl1251/reg.h [new file with mode: 0644]
drivers/net/wireless/wl1251/rx.c [new file with mode: 0644]
drivers/net/wireless/wl1251/rx.h [new file with mode: 0644]
drivers/net/wireless/wl1251/sdio.c [new file with mode: 0644]
drivers/net/wireless/wl1251/spi.c [new file with mode: 0644]
drivers/net/wireless/wl1251/spi.h [new file with mode: 0644]
drivers/net/wireless/wl1251/tx.c [new file with mode: 0644]
drivers/net/wireless/wl1251/tx.h [new file with mode: 0644]
drivers/net/wireless/wl1251/wl1251.h [new file with mode: 0644]
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/wl1251.h [deleted file]
drivers/net/wireless/wl12xx/wl1251_acx.c [deleted file]
drivers/net/wireless/wl12xx/wl1251_acx.h [deleted file]
drivers/net/wireless/wl12xx/wl1251_boot.c [deleted file]
drivers/net/wireless/wl12xx/wl1251_boot.h [deleted file]
drivers/net/wireless/wl12xx/wl1251_cmd.c [deleted file]
drivers/net/wireless/wl12xx/wl1251_cmd.h [deleted file]
drivers/net/wireless/wl12xx/wl1251_debugfs.c [deleted file]
drivers/net/wireless/wl12xx/wl1251_debugfs.h [deleted file]
drivers/net/wireless/wl12xx/wl1251_event.c [deleted file]
drivers/net/wireless/wl12xx/wl1251_event.h [deleted file]
drivers/net/wireless/wl12xx/wl1251_init.c [deleted file]
drivers/net/wireless/wl12xx/wl1251_init.h [deleted file]
drivers/net/wireless/wl12xx/wl1251_io.c [deleted file]
drivers/net/wireless/wl12xx/wl1251_io.h [deleted file]
drivers/net/wireless/wl12xx/wl1251_main.c [deleted file]
drivers/net/wireless/wl12xx/wl1251_ps.c [deleted file]
drivers/net/wireless/wl12xx/wl1251_ps.h [deleted file]
drivers/net/wireless/wl12xx/wl1251_reg.h [deleted file]
drivers/net/wireless/wl12xx/wl1251_rx.c [deleted file]
drivers/net/wireless/wl12xx/wl1251_rx.h [deleted file]
drivers/net/wireless/wl12xx/wl1251_sdio.c [deleted file]
drivers/net/wireless/wl12xx/wl1251_spi.c [deleted file]
drivers/net/wireless/wl12xx/wl1251_spi.h [deleted file]
drivers/net/wireless/wl12xx/wl1251_tx.c [deleted file]
drivers/net/wireless/wl12xx/wl1251_tx.h [deleted file]
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
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.h b/drivers/net/wireless/iwlwifi/iwl-agn-calib.h
new file mode 100644 (file)
index 0000000..e37ae72
--- /dev/null
@@ -0,0 +1,86 @@
+/******************************************************************************
+ *
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ *  Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Intel Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+#ifndef __iwl_calib_h__
+#define __iwl_calib_h__
+
+#include "iwl-dev.h"
+#include "iwl-core.h"
+#include "iwl-commands.h"
+
+void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp);
+void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp);
+
+void iwl_init_sensitivity(struct iwl_priv *priv);
+void iwl_reset_run_time_calib(struct iwl_priv *priv);
+static inline void iwl_chain_noise_reset(struct iwl_priv *priv)
+{
+
+       if (!priv->disable_chain_noise_cal &&
+           priv->cfg->ops->utils->chain_noise_reset)
+               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__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.h b/drivers/net/wireless/iwlwifi/iwl-calib.h
deleted file mode 100644 (file)
index ba9523f..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/******************************************************************************
- *
- * This file is provided under a dual BSD/GPLv2 license.  When using or
- * redistributing this file, you may do so under either license.
- *
- * GPL LICENSE SUMMARY
- *
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
- * USA
- *
- * The full GNU General Public License is included in this distribution
- * in the file called LICENSE.GPL.
- *
- * Contact Information:
- *  Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- * BSD LICENSE
- *
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *  * Neither the name Intel Corporation nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *****************************************************************************/
-#ifndef __iwl_calib_h__
-#define __iwl_calib_h__
-
-#include "iwl-dev.h"
-#include "iwl-core.h"
-#include "iwl-commands.h"
-
-void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp);
-void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp);
-
-void iwl_init_sensitivity(struct iwl_priv *priv);
-void iwl_reset_run_time_calib(struct iwl_priv *priv);
-static inline void iwl_chain_noise_reset(struct iwl_priv *priv)
-{
-
-       if (!priv->disable_chain_noise_cal &&
-           priv->cfg->ops->utils->chain_noise_reset)
-               priv->cfg->ops->utils->chain_noise_reset(priv);
-}
-
-#endif /* __iwl_calib_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
diff --git a/drivers/net/wireless/wl1251/acx.c b/drivers/net/wireless/wl1251/acx.c
new file mode 100644 (file)
index 0000000..64a0214
--- /dev/null
@@ -0,0 +1,1048 @@
+#include "acx.h"
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/crc7.h>
+
+#include "wl1251.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)
+{
+       struct acx_fw_gen_frame_rates *rates;
+       int ret;
+
+       wl1251_debug(DEBUG_ACX, "acx frame rates");
+
+       rates = kzalloc(sizeof(*rates), GFP_KERNEL);
+       if (!rates) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       rates->tx_ctrl_frame_rate = ctrl_rate;
+       rates->tx_ctrl_frame_mod = ctrl_mod;
+       rates->tx_mgt_frame_rate = mgt_rate;
+       rates->tx_mgt_frame_mod = mgt_mod;
+
+       ret = wl1251_cmd_configure(wl, ACX_FW_GEN_FRAME_RATES,
+                                  rates, sizeof(*rates));
+       if (ret < 0) {
+               wl1251_error("Failed to set FW rates and modulation");
+               goto out;
+       }
+
+out:
+       kfree(rates);
+       return ret;
+}
+
+
+int wl1251_acx_station_id(struct wl1251 *wl)
+{
+       struct acx_dot11_station_id *mac;
+       int ret, i;
+
+       wl1251_debug(DEBUG_ACX, "acx dot11_station_id");
+
+       mac = kzalloc(sizeof(*mac), GFP_KERNEL);
+       if (!mac) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       for (i = 0; i < ETH_ALEN; i++)
+               mac->mac[i] = wl->mac_addr[ETH_ALEN - 1 - i];
+
+       ret = wl1251_cmd_configure(wl, DOT11_STATION_ID, mac, sizeof(*mac));
+       if (ret < 0)
+               goto out;
+
+out:
+       kfree(mac);
+       return ret;
+}
+
+int wl1251_acx_default_key(struct wl1251 *wl, u8 key_id)
+{
+       struct acx_dot11_default_key *default_key;
+       int ret;
+
+       wl1251_debug(DEBUG_ACX, "acx dot11_default_key (%d)", key_id);
+
+       default_key = kzalloc(sizeof(*default_key), GFP_KERNEL);
+       if (!default_key) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       default_key->id = key_id;
+
+       ret = wl1251_cmd_configure(wl, DOT11_DEFAULT_KEY,
+                                  default_key, sizeof(*default_key));
+       if (ret < 0) {
+               wl1251_error("Couldn't set default key");
+               goto out;
+       }
+
+       wl->default_key = key_id;
+
+out:
+       kfree(default_key);
+       return ret;
+}
+
+int wl1251_acx_wake_up_conditions(struct wl1251 *wl, u8 wake_up_event,
+                                 u8 listen_interval)
+{
+       struct acx_wake_up_condition *wake_up;
+       int ret;
+
+       wl1251_debug(DEBUG_ACX, "acx wake up conditions");
+
+       wake_up = kzalloc(sizeof(*wake_up), GFP_KERNEL);
+       if (!wake_up) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       wake_up->wake_up_event = wake_up_event;
+       wake_up->listen_interval = listen_interval;
+
+       ret = wl1251_cmd_configure(wl, ACX_WAKE_UP_CONDITIONS,
+                                  wake_up, sizeof(*wake_up));
+       if (ret < 0) {
+               wl1251_warning("could not set wake up conditions: %d", ret);
+               goto out;
+       }
+
+out:
+       kfree(wake_up);
+       return ret;
+}
+
+int wl1251_acx_sleep_auth(struct wl1251 *wl, u8 sleep_auth)
+{
+       struct acx_sleep_auth *auth;
+       int ret;
+
+       wl1251_debug(DEBUG_ACX, "acx sleep auth");
+
+       auth = kzalloc(sizeof(*auth), GFP_KERNEL);
+       if (!auth) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       auth->sleep_auth = sleep_auth;
+
+       ret = wl1251_cmd_configure(wl, ACX_SLEEP_AUTH, auth, sizeof(*auth));
+       if (ret < 0)
+               return ret;
+
+out:
+       kfree(auth);
+       return ret;
+}
+
+int wl1251_acx_fw_version(struct wl1251 *wl, char *buf, size_t len)
+{
+       struct acx_revision *rev;
+       int ret;
+
+       wl1251_debug(DEBUG_ACX, "acx fw rev");
+
+       rev = kzalloc(sizeof(*rev), GFP_KERNEL);
+       if (!rev) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       ret = wl1251_cmd_interrogate(wl, ACX_FW_REV, rev, sizeof(*rev));
+       if (ret < 0) {
+               wl1251_warning("ACX_FW_REV interrogate failed");
+               goto out;
+       }
+
+       /* be careful with the buffer sizes */
+       strncpy(buf, rev->fw_version, min(len, sizeof(rev->fw_version)));
+
+       /*
+        * if the firmware version string is exactly
+        * sizeof(rev->fw_version) long or fw_len is less than
+        * sizeof(rev->fw_version) it won't be null terminated
+        */
+       buf[min(len, sizeof(rev->fw_version)) - 1] = '\0';
+
+out:
+       kfree(rev);
+       return ret;
+}
+
+int wl1251_acx_tx_power(struct wl1251 *wl, int power)
+{
+       struct acx_current_tx_power *acx;
+       int ret;
+
+       wl1251_debug(DEBUG_ACX, "acx dot11_cur_tx_pwr");
+
+       if (power < 0 || power > 25)
+               return -EINVAL;
+
+       acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+       if (!acx) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       acx->current_tx_power = power * 10;
+
+       ret = wl1251_cmd_configure(wl, DOT11_CUR_TX_PWR, acx, sizeof(*acx));
+       if (ret < 0) {
+               wl1251_warning("configure of tx power failed: %d", ret);
+               goto out;
+       }
+
+out:
+       kfree(acx);
+       return ret;
+}
+
+int wl1251_acx_feature_cfg(struct wl1251 *wl)
+{
+       struct acx_feature_config *feature;
+       int ret;
+
+       wl1251_debug(DEBUG_ACX, "acx feature cfg");
+
+       feature = kzalloc(sizeof(*feature), GFP_KERNEL);
+       if (!feature) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       /* DF_ENCRYPTION_DISABLE and DF_SNIFF_MODE_ENABLE are disabled */
+       feature->data_flow_options = 0;
+       feature->options = 0;
+
+       ret = wl1251_cmd_configure(wl, ACX_FEATURE_CFG,
+                                  feature, sizeof(*feature));
+       if (ret < 0) {
+               wl1251_error("Couldn't set HW encryption");
+               goto out;
+       }
+
+out:
+       kfree(feature);
+       return ret;
+}
+
+int wl1251_acx_mem_map(struct wl1251 *wl, struct acx_header *mem_map,
+                      size_t len)
+{
+       int ret;
+
+       wl1251_debug(DEBUG_ACX, "acx mem map");
+
+       ret = wl1251_cmd_interrogate(wl, ACX_MEM_MAP, mem_map, len);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+int wl1251_acx_data_path_params(struct wl1251 *wl,
+                               struct acx_data_path_params_resp *resp)
+{
+       struct acx_data_path_params *params;
+       int ret;
+
+       wl1251_debug(DEBUG_ACX, "acx data path params");
+
+       params = kzalloc(sizeof(*params), GFP_KERNEL);
+       if (!params) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       params->rx_packet_ring_chunk_size = DP_RX_PACKET_RING_CHUNK_SIZE;
+       params->tx_packet_ring_chunk_size = DP_TX_PACKET_RING_CHUNK_SIZE;
+
+       params->rx_packet_ring_chunk_num = DP_RX_PACKET_RING_CHUNK_NUM;
+       params->tx_packet_ring_chunk_num = DP_TX_PACKET_RING_CHUNK_NUM;
+
+       params->tx_complete_threshold = 1;
+
+       params->tx_complete_ring_depth = FW_TX_CMPLT_BLOCK_SIZE;
+
+       params->tx_complete_timeout = DP_TX_COMPLETE_TIME_OUT;
+
+       ret = wl1251_cmd_configure(wl, ACX_DATA_PATH_PARAMS,
+                                  params, sizeof(*params));
+       if (ret < 0)
+               goto out;
+
+       /* FIXME: shouldn't this be ACX_DATA_PATH_RESP_PARAMS? */
+       ret = wl1251_cmd_interrogate(wl, ACX_DATA_PATH_PARAMS,
+                                    resp, sizeof(*resp));
+
+       if (ret < 0) {
+               wl1251_warning("failed to read data path parameters: %d", ret);
+               goto out;
+       } else if (resp->header.cmd.status != CMD_STATUS_SUCCESS) {
+               wl1251_warning("data path parameter acx status failed");
+               ret = -EIO;
+               goto out;
+       }
+
+out:
+       kfree(params);
+       return ret;
+}
+
+int wl1251_acx_rx_msdu_life_time(struct wl1251 *wl, u32 life_time)
+{
+       struct acx_rx_msdu_lifetime *acx;
+       int ret;
+
+       wl1251_debug(DEBUG_ACX, "acx rx msdu life time");
+
+       acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+       if (!acx) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       acx->lifetime = life_time;
+       ret = wl1251_cmd_configure(wl, DOT11_RX_MSDU_LIFE_TIME,
+                                  acx, sizeof(*acx));
+       if (ret < 0) {
+               wl1251_warning("failed to set rx msdu life time: %d", ret);
+               goto out;
+       }
+
+out:
+       kfree(acx);
+       return ret;
+}
+
+int wl1251_acx_rx_config(struct wl1251 *wl, u32 config, u32 filter)
+{
+       struct acx_rx_config *rx_config;
+       int ret;
+
+       wl1251_debug(DEBUG_ACX, "acx rx config");
+
+       rx_config = kzalloc(sizeof(*rx_config), GFP_KERNEL);
+       if (!rx_config) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       rx_config->config_options = config;
+       rx_config->filter_options = filter;
+
+       ret = wl1251_cmd_configure(wl, ACX_RX_CFG,
+                                  rx_config, sizeof(*rx_config));
+       if (ret < 0) {
+               wl1251_warning("failed to set rx config: %d", ret);
+               goto out;
+       }
+
+out:
+       kfree(rx_config);
+       return ret;
+}
+
+int wl1251_acx_pd_threshold(struct wl1251 *wl)
+{
+       struct acx_packet_detection *pd;
+       int ret;
+
+       wl1251_debug(DEBUG_ACX, "acx data pd threshold");
+
+       pd = kzalloc(sizeof(*pd), GFP_KERNEL);
+       if (!pd) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       /* FIXME: threshold value not set */
+
+       ret = wl1251_cmd_configure(wl, ACX_PD_THRESHOLD, pd, sizeof(*pd));
+       if (ret < 0) {
+               wl1251_warning("failed to set pd threshold: %d", ret);
+               goto out;
+       }
+
+out:
+       kfree(pd);
+       return ret;
+}
+
+int wl1251_acx_slot(struct wl1251 *wl, enum acx_slot_type slot_time)
+{
+       struct acx_slot *slot;
+       int ret;
+
+       wl1251_debug(DEBUG_ACX, "acx slot");
+
+       slot = kzalloc(sizeof(*slot), GFP_KERNEL);
+       if (!slot) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       slot->wone_index = STATION_WONE_INDEX;
+       slot->slot_time = slot_time;
+
+       ret = wl1251_cmd_configure(wl, ACX_SLOT, slot, sizeof(*slot));
+       if (ret < 0) {
+               wl1251_warning("failed to set slot time: %d", ret);
+               goto out;
+       }
+
+out:
+       kfree(slot);
+       return ret;
+}
+
+int wl1251_acx_group_address_tbl(struct wl1251 *wl)
+{
+       struct acx_dot11_grp_addr_tbl *acx;
+       int ret;
+
+       wl1251_debug(DEBUG_ACX, "acx group address tbl");
+
+       acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+       if (!acx) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       /* MAC filtering */
+       acx->enabled = 0;
+       acx->num_groups = 0;
+       memset(acx->mac_table, 0, ADDRESS_GROUP_MAX_LEN);
+
+       ret = wl1251_cmd_configure(wl, DOT11_GROUP_ADDRESS_TBL,
+                                  acx, sizeof(*acx));
+       if (ret < 0) {
+               wl1251_warning("failed to set group addr table: %d", ret);
+               goto out;
+       }
+
+out:
+       kfree(acx);
+       return ret;
+}
+
+int wl1251_acx_service_period_timeout(struct wl1251 *wl)
+{
+       struct acx_rx_timeout *rx_timeout;
+       int ret;
+
+       rx_timeout = kzalloc(sizeof(*rx_timeout), GFP_KERNEL);
+       if (!rx_timeout) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       wl1251_debug(DEBUG_ACX, "acx service period timeout");
+
+       rx_timeout->ps_poll_timeout = RX_TIMEOUT_PS_POLL_DEF;
+       rx_timeout->upsd_timeout = RX_TIMEOUT_UPSD_DEF;
+
+       ret = wl1251_cmd_configure(wl, ACX_SERVICE_PERIOD_TIMEOUT,
+                                  rx_timeout, sizeof(*rx_timeout));
+       if (ret < 0) {
+               wl1251_warning("failed to set service period timeout: %d",
+                              ret);
+               goto out;
+       }
+
+out:
+       kfree(rx_timeout);
+       return ret;
+}
+
+int wl1251_acx_rts_threshold(struct wl1251 *wl, u16 rts_threshold)
+{
+       struct acx_rts_threshold *rts;
+       int ret;
+
+       wl1251_debug(DEBUG_ACX, "acx rts threshold");
+
+       rts = kzalloc(sizeof(*rts), GFP_KERNEL);
+       if (!rts) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       rts->threshold = rts_threshold;
+
+       ret = wl1251_cmd_configure(wl, DOT11_RTS_THRESHOLD, rts, sizeof(*rts));
+       if (ret < 0) {
+               wl1251_warning("failed to set rts threshold: %d", ret);
+               goto out;
+       }
+
+out:
+       kfree(rts);
+       return ret;
+}
+
+int wl1251_acx_beacon_filter_opt(struct wl1251 *wl, bool enable_filter)
+{
+       struct acx_beacon_filter_option *beacon_filter;
+       int ret;
+
+       wl1251_debug(DEBUG_ACX, "acx beacon filter opt");
+
+       beacon_filter = kzalloc(sizeof(*beacon_filter), GFP_KERNEL);
+       if (!beacon_filter) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       beacon_filter->enable = enable_filter;
+       beacon_filter->max_num_beacons = 0;
+
+       ret = wl1251_cmd_configure(wl, ACX_BEACON_FILTER_OPT,
+                                  beacon_filter, sizeof(*beacon_filter));
+       if (ret < 0) {
+               wl1251_warning("failed to set beacon filter opt: %d", ret);
+               goto out;
+       }
+
+out:
+       kfree(beacon_filter);
+       return ret;
+}
+
+int wl1251_acx_beacon_filter_table(struct wl1251 *wl)
+{
+       struct acx_beacon_filter_ie_table *ie_table;
+       int idx = 0;
+       int ret;
+
+       wl1251_debug(DEBUG_ACX, "acx beacon filter table");
+
+       ie_table = kzalloc(sizeof(*ie_table), GFP_KERNEL);
+       if (!ie_table) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       /* configure default beacon pass-through rules */
+       ie_table->num_ie = 1;
+       ie_table->table[idx++] = BEACON_FILTER_IE_ID_CHANNEL_SWITCH_ANN;
+       ie_table->table[idx++] = BEACON_RULE_PASS_ON_APPEARANCE;
+
+       ret = wl1251_cmd_configure(wl, ACX_BEACON_FILTER_TABLE,
+                                  ie_table, sizeof(*ie_table));
+       if (ret < 0) {
+               wl1251_warning("failed to set beacon filter table: %d", ret);
+               goto out;
+       }
+
+out:
+       kfree(ie_table);
+       return ret;
+}
+
+int wl1251_acx_conn_monit_params(struct wl1251 *wl)
+{
+       struct acx_conn_monit_params *acx;
+       int ret;
+
+       wl1251_debug(DEBUG_ACX, "acx connection monitor parameters");
+
+       acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+       if (!acx) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       acx->synch_fail_thold = SYNCH_FAIL_DEFAULT_THRESHOLD;
+       acx->bss_lose_timeout = NO_BEACON_DEFAULT_TIMEOUT;
+
+       ret = wl1251_cmd_configure(wl, ACX_CONN_MONIT_PARAMS,
+                                  acx, sizeof(*acx));
+       if (ret < 0) {
+               wl1251_warning("failed to set connection monitor "
+                              "parameters: %d", ret);
+               goto out;
+       }
+
+out:
+       kfree(acx);
+       return ret;
+}
+
+int wl1251_acx_sg_enable(struct wl1251 *wl)
+{
+       struct acx_bt_wlan_coex *pta;
+       int ret;
+
+       wl1251_debug(DEBUG_ACX, "acx sg enable");
+
+       pta = kzalloc(sizeof(*pta), GFP_KERNEL);
+       if (!pta) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       pta->enable = SG_ENABLE;
+
+       ret = wl1251_cmd_configure(wl, ACX_SG_ENABLE, pta, sizeof(*pta));
+       if (ret < 0) {
+               wl1251_warning("failed to set softgemini enable: %d", ret);
+               goto out;
+       }
+
+out:
+       kfree(pta);
+       return ret;
+}
+
+int wl1251_acx_sg_cfg(struct wl1251 *wl)
+{
+       struct acx_bt_wlan_coex_param *param;
+       int ret;
+
+       wl1251_debug(DEBUG_ACX, "acx sg cfg");
+
+       param = kzalloc(sizeof(*param), GFP_KERNEL);
+       if (!param) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       /* BT-WLAN coext parameters */
+       param->min_rate = RATE_INDEX_24MBPS;
+       param->bt_hp_max_time = PTA_BT_HP_MAXTIME_DEF;
+       param->wlan_hp_max_time = PTA_WLAN_HP_MAX_TIME_DEF;
+       param->sense_disable_timer = PTA_SENSE_DISABLE_TIMER_DEF;
+       param->rx_time_bt_hp = PTA_PROTECTIVE_RX_TIME_DEF;
+       param->tx_time_bt_hp = PTA_PROTECTIVE_TX_TIME_DEF;
+       param->rx_time_bt_hp_fast = PTA_PROTECTIVE_RX_TIME_FAST_DEF;
+       param->tx_time_bt_hp_fast = PTA_PROTECTIVE_TX_TIME_FAST_DEF;
+       param->wlan_cycle_fast = PTA_CYCLE_TIME_FAST_DEF;
+       param->bt_anti_starvation_period = PTA_ANTI_STARVE_PERIOD_DEF;
+       param->next_bt_lp_packet = PTA_TIMEOUT_NEXT_BT_LP_PACKET_DEF;
+       param->wake_up_beacon = PTA_TIME_BEFORE_BEACON_DEF;
+       param->hp_dm_max_guard_time = PTA_HPDM_MAX_TIME_DEF;
+       param->next_wlan_packet = PTA_TIME_OUT_NEXT_WLAN_DEF;
+       param->antenna_type = PTA_ANTENNA_TYPE_DEF;
+       param->signal_type = PTA_SIGNALING_TYPE_DEF;
+       param->afh_leverage_on = PTA_AFH_LEVERAGE_ON_DEF;
+       param->quiet_cycle_num = PTA_NUMBER_QUIET_CYCLE_DEF;
+       param->max_cts = PTA_MAX_NUM_CTS_DEF;
+       param->wlan_packets_num = PTA_NUMBER_OF_WLAN_PACKETS_DEF;
+       param->bt_packets_num = PTA_NUMBER_OF_BT_PACKETS_DEF;
+       param->missed_rx_avalanche = PTA_RX_FOR_AVALANCHE_DEF;
+       param->wlan_elp_hp = PTA_ELP_HP_DEF;
+       param->bt_anti_starvation_cycles = PTA_ANTI_STARVE_NUM_CYCLE_DEF;
+       param->ack_mode_dual_ant = PTA_ACK_MODE_DEF;
+       param->pa_sd_enable = PTA_ALLOW_PA_SD_DEF;
+       param->pta_auto_mode_enable = PTA_AUTO_MODE_NO_CTS_DEF;
+       param->bt_hp_respected_num = PTA_BT_HP_RESPECTED_DEF;
+
+       ret = wl1251_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param));
+       if (ret < 0) {
+               wl1251_warning("failed to set sg config: %d", ret);
+               goto out;
+       }
+
+out:
+       kfree(param);
+       return ret;
+}
+
+int wl1251_acx_cca_threshold(struct wl1251 *wl)
+{
+       struct acx_energy_detection *detection;
+       int ret;
+
+       wl1251_debug(DEBUG_ACX, "acx cca threshold");
+
+       detection = kzalloc(sizeof(*detection), GFP_KERNEL);
+       if (!detection) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       detection->rx_cca_threshold = CCA_THRSH_DISABLE_ENERGY_D;
+       detection->tx_energy_detection = 0;
+
+       ret = wl1251_cmd_configure(wl, ACX_CCA_THRESHOLD,
+                                  detection, sizeof(*detection));
+       if (ret < 0) {
+               wl1251_warning("failed to set cca threshold: %d", ret);
+               return ret;
+       }
+
+out:
+       kfree(detection);
+       return ret;
+}
+
+int wl1251_acx_bcn_dtim_options(struct wl1251 *wl)
+{
+       struct acx_beacon_broadcast *bb;
+       int ret;
+
+       wl1251_debug(DEBUG_ACX, "acx bcn dtim options");
+
+       bb = kzalloc(sizeof(*bb), GFP_KERNEL);
+       if (!bb) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       bb->beacon_rx_timeout = BCN_RX_TIMEOUT_DEF_VALUE;
+       bb->broadcast_timeout = BROADCAST_RX_TIMEOUT_DEF_VALUE;
+       bb->rx_broadcast_in_ps = RX_BROADCAST_IN_PS_DEF_VALUE;
+       bb->ps_poll_threshold = CONSECUTIVE_PS_POLL_FAILURE_DEF;
+
+       ret = wl1251_cmd_configure(wl, ACX_BCN_DTIM_OPTIONS, bb, sizeof(*bb));
+       if (ret < 0) {
+               wl1251_warning("failed to set rx config: %d", ret);
+               goto out;
+       }
+
+out:
+       kfree(bb);
+       return ret;
+}
+
+int wl1251_acx_aid(struct wl1251 *wl, u16 aid)
+{
+       struct acx_aid *acx_aid;
+       int ret;
+
+       wl1251_debug(DEBUG_ACX, "acx aid");
+
+       acx_aid = kzalloc(sizeof(*acx_aid), GFP_KERNEL);
+       if (!acx_aid) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       acx_aid->aid = aid;
+
+       ret = wl1251_cmd_configure(wl, ACX_AID, acx_aid, sizeof(*acx_aid));
+       if (ret < 0) {
+               wl1251_warning("failed to set aid: %d", ret);
+               goto out;
+       }
+
+out:
+       kfree(acx_aid);
+       return ret;
+}
+
+int wl1251_acx_event_mbox_mask(struct wl1251 *wl, u32 event_mask)
+{
+       struct acx_event_mask *mask;
+       int ret;
+
+       wl1251_debug(DEBUG_ACX, "acx event mbox mask");
+
+       mask = kzalloc(sizeof(*mask), GFP_KERNEL);
+       if (!mask) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       /* high event mask is unused */
+       mask->high_event_mask = 0xffffffff;
+
+       mask->event_mask = event_mask;
+
+       ret = wl1251_cmd_configure(wl, ACX_EVENT_MBOX_MASK,
+                                  mask, sizeof(*mask));
+       if (ret < 0) {
+               wl1251_warning("failed to set acx_event_mbox_mask: %d", ret);
+               goto out;
+       }
+
+out:
+       kfree(mask);
+       return ret;
+}
+
+int wl1251_acx_set_preamble(struct wl1251 *wl, enum acx_preamble_type preamble)
+{
+       struct acx_preamble *acx;
+       int ret;
+
+       wl1251_debug(DEBUG_ACX, "acx_set_preamble");
+
+       acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+       if (!acx) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       acx->preamble = preamble;
+
+       ret = wl1251_cmd_configure(wl, ACX_PREAMBLE_TYPE, acx, sizeof(*acx));
+       if (ret < 0) {
+               wl1251_warning("Setting of preamble failed: %d", ret);
+               goto out;
+       }
+
+out:
+       kfree(acx);
+       return ret;
+}
+
+int wl1251_acx_cts_protect(struct wl1251 *wl,
+                          enum acx_ctsprotect_type ctsprotect)
+{
+       struct acx_ctsprotect *acx;
+       int ret;
+
+       wl1251_debug(DEBUG_ACX, "acx_set_ctsprotect");
+
+       acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+       if (!acx) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       acx->ctsprotect = ctsprotect;
+
+       ret = wl1251_cmd_configure(wl, ACX_CTS_PROTECTION, acx, sizeof(*acx));
+       if (ret < 0) {
+               wl1251_warning("Setting of ctsprotect failed: %d", ret);
+               goto out;
+       }
+
+out:
+       kfree(acx);
+       return ret;
+}
+
+int wl1251_acx_tsf_info(struct wl1251 *wl, u64 *mactime)
+{
+       struct acx_tsf_info *tsf_info;
+       int ret;
+
+       tsf_info = kzalloc(sizeof(*tsf_info), GFP_KERNEL);
+       if (!tsf_info) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       ret = wl1251_cmd_interrogate(wl, ACX_TSF_INFO,
+                                    tsf_info, sizeof(*tsf_info));
+       if (ret < 0) {
+               wl1251_warning("ACX_FW_REV interrogate failed");
+               goto out;
+       }
+
+       *mactime = tsf_info->current_tsf_lsb |
+               (tsf_info->current_tsf_msb << 31);
+
+out:
+       kfree(tsf_info);
+       return ret;
+}
+
+int wl1251_acx_statistics(struct wl1251 *wl, struct acx_statistics *stats)
+{
+       int ret;
+
+       wl1251_debug(DEBUG_ACX, "acx statistics");
+
+       ret = wl1251_cmd_interrogate(wl, ACX_STATISTICS, stats,
+                                    sizeof(*stats));
+       if (ret < 0) {
+               wl1251_warning("acx statistics failed: %d", ret);
+               return -ENOMEM;
+       }
+
+       return 0;
+}
+
+int wl1251_acx_rate_policies(struct wl1251 *wl)
+{
+       struct acx_rate_policy *acx;
+       int ret = 0;
+
+       wl1251_debug(DEBUG_ACX, "acx rate policies");
+
+       acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+
+       if (!acx) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       /* configure one default (one-size-fits-all) rate class */
+       acx->rate_class_cnt = 1;
+       acx->rate_class[0].enabled_rates = ACX_RATE_MASK_UNSPECIFIED;
+       acx->rate_class[0].short_retry_limit = ACX_RATE_RETRY_LIMIT;
+       acx->rate_class[0].long_retry_limit = ACX_RATE_RETRY_LIMIT;
+       acx->rate_class[0].aflags = 0;
+
+       ret = wl1251_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx));
+       if (ret < 0) {
+               wl1251_warning("Setting of rate policies failed: %d", ret);
+               goto out;
+       }
+
+out:
+       kfree(acx);
+       return ret;
+}
+
+int wl1251_acx_mem_cfg(struct wl1251 *wl)
+{
+       struct wl1251_acx_config_memory *mem_conf;
+       int ret, i;
+
+       wl1251_debug(DEBUG_ACX, "acx mem cfg");
+
+       mem_conf = kzalloc(sizeof(*mem_conf), GFP_KERNEL);
+       if (!mem_conf) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       /* memory config */
+       mem_conf->mem_config.num_stations = cpu_to_le16(DEFAULT_NUM_STATIONS);
+       mem_conf->mem_config.rx_mem_block_num = 35;
+       mem_conf->mem_config.tx_min_mem_block_num = 64;
+       mem_conf->mem_config.num_tx_queues = MAX_TX_QUEUES;
+       mem_conf->mem_config.host_if_options = HOSTIF_PKT_RING;
+       mem_conf->mem_config.num_ssid_profiles = 1;
+       mem_conf->mem_config.debug_buffer_size =
+               cpu_to_le16(TRACE_BUFFER_MAX_SIZE);
+
+       /* RX queue config */
+       mem_conf->rx_queue_config.dma_address = 0;
+       mem_conf->rx_queue_config.num_descs = ACX_RX_DESC_DEF;
+       mem_conf->rx_queue_config.priority = DEFAULT_RXQ_PRIORITY;
+       mem_conf->rx_queue_config.type = DEFAULT_RXQ_TYPE;
+
+       /* TX queue config */
+       for (i = 0; i < MAX_TX_QUEUES; i++) {
+               mem_conf->tx_queue_config[i].num_descs = ACX_TX_DESC_DEF;
+               mem_conf->tx_queue_config[i].attributes = i;
+       }
+
+       ret = wl1251_cmd_configure(wl, ACX_MEM_CFG, mem_conf,
+                                  sizeof(*mem_conf));
+       if (ret < 0) {
+               wl1251_warning("wl1251 mem config failed: %d", ret);
+               goto out;
+       }
+
+out:
+       kfree(mem_conf);
+       return ret;
+}
+
+int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim)
+{
+       struct wl1251_acx_wr_tbtt_and_dtim *acx;
+       int ret;
+
+       wl1251_debug(DEBUG_ACX, "acx tbtt and dtim");
+
+       acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+       if (!acx) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       acx->tbtt = tbtt;
+       acx->dtim = dtim;
+
+       ret = wl1251_cmd_configure(wl, ACX_WR_TBTT_AND_DTIM,
+                                  acx, sizeof(*acx));
+       if (ret < 0) {
+               wl1251_warning("failed to set tbtt and dtim: %d", ret);
+               goto out;
+       }
+
+out:
+       kfree(acx);
+       return ret;
+}
+
+int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max,
+                     u8 aifs, u16 txop)
+{
+       struct wl1251_acx_ac_cfg *acx;
+       int ret = 0;
+
+       wl1251_debug(DEBUG_ACX, "acx ac cfg %d cw_ming %d cw_max %d "
+                    "aifs %d txop %d", ac, cw_min, cw_max, aifs, txop);
+
+       acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+
+       if (!acx) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       acx->ac = ac;
+       acx->cw_min = cw_min;
+       acx->cw_max = cw_max;
+       acx->aifsn = aifs;
+       acx->txop_limit = txop;
+
+       ret = wl1251_cmd_configure(wl, ACX_AC_CFG, acx, sizeof(*acx));
+       if (ret < 0) {
+               wl1251_warning("acx ac cfg failed: %d", ret);
+               goto out;
+       }
+
+out:
+       kfree(acx);
+       return ret;
+}
+
+int wl1251_acx_tid_cfg(struct wl1251 *wl, u8 queue,
+                      enum wl1251_acx_channel_type type,
+                      u8 tsid, enum wl1251_acx_ps_scheme ps_scheme,
+                      enum wl1251_acx_ack_policy ack_policy)
+{
+       struct wl1251_acx_tid_cfg *acx;
+       int ret = 0;
+
+       wl1251_debug(DEBUG_ACX, "acx tid cfg %d type %d tsid %d "
+                    "ps_scheme %d ack_policy %d", queue, type, tsid,
+                    ps_scheme, ack_policy);
+
+       acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+
+       if (!acx) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       acx->queue = queue;
+       acx->type = type;
+       acx->tsid = tsid;
+       acx->ps_scheme = ps_scheme;
+       acx->ack_policy = ack_policy;
+
+       ret = wl1251_cmd_configure(wl, ACX_TID_CFG, acx, sizeof(*acx));
+       if (ret < 0) {
+               wl1251_warning("acx tid cfg failed: %d", ret);
+               goto out;
+       }
+
+out:
+       kfree(acx);
+       return ret;
+}
diff --git a/drivers/net/wireless/wl1251/acx.h b/drivers/net/wireless/wl1251/acx.h
new file mode 100644 (file)
index 0000000..e54b21a
--- /dev/null
@@ -0,0 +1,1411 @@
+/*
+ * This file is part of wl1251
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 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 St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __WL1251_ACX_H__
+#define __WL1251_ACX_H__
+
+#include "wl1251.h"
+#include "cmd.h"
+
+/* Target's information element */
+struct acx_header {
+       struct wl1251_cmd_header cmd;
+
+       /* acx (or information element) header */
+       u16 id;
+
+       /* payload length (not including headers */
+       u16 len;
+} __packed;
+
+struct acx_error_counter {
+       struct acx_header header;
+
+       /* The number of PLCP errors since the last time this */
+       /* information element was interrogated. This field is */
+       /* automatically cleared when it is interrogated.*/
+       u32 PLCP_error;
+
+       /* The number of FCS errors since the last time this */
+       /* information element was interrogated. This field is */
+       /* automatically cleared when it is interrogated.*/
+       u32 FCS_error;
+
+       /* The number of MPDUs without PLCP header errors received*/
+       /* since the last time this information element was interrogated. */
+       /* This field is automatically cleared when it is interrogated.*/
+       u32 valid_frame;
+
+       /* the number of missed sequence numbers in the squentially */
+       /* values of frames seq numbers */
+       u32 seq_num_miss;
+} __packed;
+
+struct acx_revision {
+       struct acx_header header;
+
+       /*
+        * The WiLink firmware version, an ASCII string x.x.x.x,
+        * that uniquely identifies the current firmware.
+        * The left most digit is incremented each time a
+        * significant change is made to the firmware, such as
+        * code redesign or new platform support.
+        * The second digit is incremented when major enhancements
+        * are added or major fixes are made.
+        * The third digit is incremented for each GA release.
+        * The fourth digit is incremented for each build.
+        * The first two digits identify a firmware release version,
+        * in other words, a unique set of features.
+        * The first three digits identify a GA release.
+        */
+       char fw_version[20];
+
+       /*
+        * This 4 byte field specifies the WiLink hardware version.
+        * bits 0  - 15: Reserved.
+        * bits 16 - 23: Version ID - The WiLink version ID
+        *              (1 = first spin, 2 = second spin, and so on).
+        * bits 24 - 31: Chip ID - The WiLink chip ID.
+        */
+       u32 hw_version;
+} __packed;
+
+enum wl1251_psm_mode {
+       /* Active mode */
+       WL1251_PSM_CAM = 0,
+
+       /* Power save mode */
+       WL1251_PSM_PS = 1,
+
+       /* Extreme low power */
+       WL1251_PSM_ELP = 2,
+};
+
+struct acx_sleep_auth {
+       struct acx_header header;
+
+       /* The sleep level authorization of the device. */
+       /* 0 - Always active*/
+       /* 1 - Power down mode: light / fast sleep*/
+       /* 2 - ELP mode: Deep / Max sleep*/
+       u8  sleep_auth;
+       u8  padding[3];
+} __packed;
+
+enum {
+       HOSTIF_PCI_MASTER_HOST_INDIRECT,
+       HOSTIF_PCI_MASTER_HOST_DIRECT,
+       HOSTIF_SLAVE,
+       HOSTIF_PKT_RING,
+       HOSTIF_DONTCARE = 0xFF
+};
+
+#define DEFAULT_UCAST_PRIORITY          0
+#define DEFAULT_RX_Q_PRIORITY           0
+#define DEFAULT_NUM_STATIONS            1
+#define DEFAULT_RXQ_PRIORITY            0 /* low 0 .. 15 high  */
+#define DEFAULT_RXQ_TYPE                0x07    /* All frames, Data/Ctrl/Mgmt */
+#define TRACE_BUFFER_MAX_SIZE           256
+
+#define  DP_RX_PACKET_RING_CHUNK_SIZE 1600
+#define  DP_TX_PACKET_RING_CHUNK_SIZE 1600
+#define  DP_RX_PACKET_RING_CHUNK_NUM 2
+#define  DP_TX_PACKET_RING_CHUNK_NUM 2
+#define  DP_TX_COMPLETE_TIME_OUT 20
+#define  FW_TX_CMPLT_BLOCK_SIZE 16
+
+struct acx_data_path_params {
+       struct acx_header header;
+
+       u16 rx_packet_ring_chunk_size;
+       u16 tx_packet_ring_chunk_size;
+
+       u8 rx_packet_ring_chunk_num;
+       u8 tx_packet_ring_chunk_num;
+
+       /*
+        * Maximum number of packets that can be gathered
+        * in the TX complete ring before an interrupt
+        * is generated.
+        */
+       u8 tx_complete_threshold;
+
+       /* Number of pending TX complete entries in cyclic ring.*/
+       u8 tx_complete_ring_depth;
+
+       /*
+        * Max num microseconds since a packet enters the TX
+        * complete ring until an interrupt is generated.
+        */
+       u32 tx_complete_timeout;
+} __packed;
+
+
+struct acx_data_path_params_resp {
+       struct acx_header header;
+
+       u16 rx_packet_ring_chunk_size;
+       u16 tx_packet_ring_chunk_size;
+
+       u8 rx_packet_ring_chunk_num;
+       u8 tx_packet_ring_chunk_num;
+
+       u8 pad[2];
+
+       u32 rx_packet_ring_addr;
+       u32 tx_packet_ring_addr;
+
+       u32 rx_control_addr;
+       u32 tx_control_addr;
+
+       u32 tx_complete_addr;
+} __packed;
+
+#define TX_MSDU_LIFETIME_MIN       0
+#define TX_MSDU_LIFETIME_MAX       3000
+#define TX_MSDU_LIFETIME_DEF       512
+#define RX_MSDU_LIFETIME_MIN       0
+#define RX_MSDU_LIFETIME_MAX       0xFFFFFFFF
+#define RX_MSDU_LIFETIME_DEF       512000
+
+struct acx_rx_msdu_lifetime {
+       struct acx_header header;
+
+       /*
+        * The maximum amount of time, in TU, before the
+        * firmware discards the MSDU.
+        */
+       u32 lifetime;
+} __packed;
+
+/*
+ * RX Config Options Table
+ * Bit         Definition
+ * ===         ==========
+ * 31:14               Reserved
+ * 13          Copy RX Status - when set, write three receive status words
+ *             to top of rx'd MPDUs.
+ *             When cleared, do not write three status words (added rev 1.5)
+ * 12          Reserved
+ * 11          RX Complete upon FCS error - when set, give rx complete
+ *             interrupt for FCS errors, after the rx filtering, e.g. unicast
+ *             frames not to us with FCS error will not generate an interrupt.
+ * 10          SSID Filter Enable - When set, the WiLink discards all beacon,
+ *             probe request, and probe response frames with an SSID that does
+ *             not match the SSID specified by the host in the START/JOIN
+ *             command.
+ *             When clear, the WiLink receives frames with any SSID.
+ * 9           Broadcast Filter Enable - When set, the WiLink discards all
+ *             broadcast frames. When clear, the WiLink receives all received
+ *             broadcast frames.
+ * 8:6         Reserved
+ * 5           BSSID Filter Enable - When set, the WiLink discards any frames
+ *             with a BSSID that does not match the BSSID specified by the
+ *             host.
+ *             When clear, the WiLink receives frames from any BSSID.
+ * 4           MAC Addr Filter - When set, the WiLink discards any frames
+ *             with a destination address that does not match the MAC address
+ *             of the adaptor.
+ *             When clear, the WiLink receives frames destined to any MAC
+ *             address.
+ * 3           Promiscuous - When set, the WiLink receives all valid frames
+ *             (i.e., all frames that pass the FCS check).
+ *             When clear, only frames that pass the other filters specified
+ *             are received.
+ * 2           FCS - When set, the WiLink includes the FCS with the received
+ *             frame.
+ *             When cleared, the FCS is discarded.
+ * 1           PLCP header - When set, write all data from baseband to frame
+ *             buffer including PHY header.
+ * 0           Reserved - Always equal to 0.
+ *
+ * RX Filter Options Table
+ * Bit         Definition
+ * ===         ==========
+ * 31:12               Reserved - Always equal to 0.
+ * 11          Association - When set, the WiLink receives all association
+ *             related frames (association request/response, reassocation
+ *             request/response, and disassociation). When clear, these frames
+ *             are discarded.
+ * 10          Auth/De auth - When set, the WiLink receives all authentication
+ *             and de-authentication frames. When clear, these frames are
+ *             discarded.
+ * 9           Beacon - When set, the WiLink receives all beacon frames.
+ *             When clear, these frames are discarded.
+ * 8           Contention Free - When set, the WiLink receives all contention
+ *             free frames.
+ *             When clear, these frames are discarded.
+ * 7           Control - When set, the WiLink receives all control frames.
+ *             When clear, these frames are discarded.
+ * 6           Data - When set, the WiLink receives all data frames.
+ *             When clear, these frames are discarded.
+ * 5           FCS Error - When set, the WiLink receives frames that have FCS
+ *             errors.
+ *             When clear, these frames are discarded.
+ * 4           Management - When set, the WiLink receives all management
+ *             frames.
+ *             When clear, these frames are discarded.
+ * 3           Probe Request - When set, the WiLink receives all probe request
+ *             frames.
+ *             When clear, these frames are discarded.
+ * 2           Probe Response - When set, the WiLink receives all probe
+ *             response frames.
+ *             When clear, these frames are discarded.
+ * 1           RTS/CTS/ACK - When set, the WiLink receives all RTS, CTS and ACK
+ *             frames.
+ *             When clear, these frames are discarded.
+ * 0           Rsvd Type/Sub Type - When set, the WiLink receives all frames
+ *             that have reserved frame types and sub types as defined by the
+ *             802.11 specification.
+ *             When clear, these frames are discarded.
+ */
+struct acx_rx_config {
+       struct acx_header header;
+
+       u32 config_options;
+       u32 filter_options;
+} __packed;
+
+enum {
+       QOS_AC_BE = 0,
+       QOS_AC_BK,
+       QOS_AC_VI,
+       QOS_AC_VO,
+       QOS_HIGHEST_AC_INDEX = QOS_AC_VO,
+};
+
+#define MAX_NUM_OF_AC             (QOS_HIGHEST_AC_INDEX+1)
+#define FIRST_AC_INDEX            QOS_AC_BE
+#define MAX_NUM_OF_802_1d_TAGS    8
+#define AC_PARAMS_MAX_TSID        15
+#define MAX_APSD_CONF             0xffff
+
+#define  QOS_TX_HIGH_MIN      (0)
+#define  QOS_TX_HIGH_MAX      (100)
+
+#define  QOS_TX_HIGH_BK_DEF   (25)
+#define  QOS_TX_HIGH_BE_DEF   (35)
+#define  QOS_TX_HIGH_VI_DEF   (35)
+#define  QOS_TX_HIGH_VO_DEF   (35)
+
+#define  QOS_TX_LOW_BK_DEF    (15)
+#define  QOS_TX_LOW_BE_DEF    (25)
+#define  QOS_TX_LOW_VI_DEF    (25)
+#define  QOS_TX_LOW_VO_DEF    (25)
+
+struct acx_tx_queue_qos_config {
+       struct acx_header header;
+
+       u8 qid;
+       u8 pad[3];
+
+       /* Max number of blocks allowd in the queue */
+       u16 high_threshold;
+
+       /* Lowest memory blocks guaranteed for this queue */
+       u16 low_threshold;
+} __packed;
+
+struct acx_packet_detection {
+       struct acx_header header;
+
+       u32 threshold;
+} __packed;
+
+
+enum acx_slot_type {
+       SLOT_TIME_LONG = 0,
+       SLOT_TIME_SHORT = 1,
+       DEFAULT_SLOT_TIME = SLOT_TIME_SHORT,
+       MAX_SLOT_TIMES = 0xFF
+};
+
+#define STATION_WONE_INDEX 0
+
+struct acx_slot {
+       struct acx_header header;
+
+       u8 wone_index; /* Reserved */
+       u8 slot_time;
+       u8 reserved[6];
+} __packed;
+
+
+#define ADDRESS_GROUP_MAX      (8)
+#define ADDRESS_GROUP_MAX_LEN  (ETH_ALEN * ADDRESS_GROUP_MAX)
+
+struct acx_dot11_grp_addr_tbl {
+       struct acx_header header;
+
+       u8 enabled;
+       u8 num_groups;
+       u8 pad[2];
+       u8 mac_table[ADDRESS_GROUP_MAX_LEN];
+} __packed;
+
+
+#define  RX_TIMEOUT_PS_POLL_MIN    0
+#define  RX_TIMEOUT_PS_POLL_MAX    (200000)
+#define  RX_TIMEOUT_PS_POLL_DEF    (15)
+#define  RX_TIMEOUT_UPSD_MIN       0
+#define  RX_TIMEOUT_UPSD_MAX       (200000)
+#define  RX_TIMEOUT_UPSD_DEF       (15)
+
+struct acx_rx_timeout {
+       struct acx_header header;
+
+       /*
+        * The longest time the STA will wait to receive
+        * traffic from the AP after a PS-poll has been
+        * transmitted.
+        */
+       u16 ps_poll_timeout;
+
+       /*
+        * The longest time the STA will wait to receive
+        * traffic from the AP after a frame has been sent
+        * from an UPSD enabled queue.
+        */
+       u16 upsd_timeout;
+} __packed;
+
+#define RTS_THRESHOLD_MIN              0
+#define RTS_THRESHOLD_MAX              4096
+#define RTS_THRESHOLD_DEF              2347
+
+struct acx_rts_threshold {
+       struct acx_header header;
+
+       u16 threshold;
+       u8 pad[2];
+} __packed;
+
+struct acx_beacon_filter_option {
+       struct acx_header header;
+
+       u8 enable;
+
+       /*
+        * The number of beacons without the unicast TIM
+        * bit set that the firmware buffers before
+        * signaling the host about ready frames.
+        * When set to 0 and the filter is enabled, beacons
+        * without the unicast TIM bit set are dropped.
+        */
+       u8 max_num_beacons;
+       u8 pad[2];
+} __packed;
+
+/*
+ * ACXBeaconFilterEntry (not 221)
+ * Byte Offset     Size (Bytes)    Definition
+ * ===========     ============    ==========
+ * 0                           1               IE identifier
+ * 1               1               Treatment bit mask
+ *
+ * ACXBeaconFilterEntry (221)
+ * Byte Offset     Size (Bytes)    Definition
+ * ===========     ============    ==========
+ * 0               1               IE identifier
+ * 1               1               Treatment bit mask
+ * 2               3               OUI
+ * 5               1               Type
+ * 6               2               Version
+ *
+ *
+ * Treatment bit mask - The information element handling:
+ * bit 0 - The information element is compared and transferred
+ * in case of change.
+ * bit 1 - The information element is transferred to the host
+ * with each appearance or disappearance.
+ * Note that both bits can be set at the same time.
+ */
+#define        BEACON_FILTER_TABLE_MAX_IE_NUM                 (32)
+#define BEACON_FILTER_TABLE_MAX_VENDOR_SPECIFIC_IE_NUM (6)
+#define BEACON_FILTER_TABLE_IE_ENTRY_SIZE             (2)
+#define BEACON_FILTER_TABLE_EXTRA_VENDOR_SPECIFIC_IE_SIZE (6)
+#define BEACON_FILTER_TABLE_MAX_SIZE ((BEACON_FILTER_TABLE_MAX_IE_NUM * \
+                           BEACON_FILTER_TABLE_IE_ENTRY_SIZE) + \
+                          (BEACON_FILTER_TABLE_MAX_VENDOR_SPECIFIC_IE_NUM * \
+                           BEACON_FILTER_TABLE_EXTRA_VENDOR_SPECIFIC_IE_SIZE))
+
+#define BEACON_RULE_PASS_ON_CHANGE                     BIT(0)
+#define BEACON_RULE_PASS_ON_APPEARANCE                 BIT(1)
+
+#define BEACON_FILTER_IE_ID_CHANNEL_SWITCH_ANN         (37)
+
+struct acx_beacon_filter_ie_table {
+       struct acx_header header;
+
+       u8 num_ie;
+       u8 pad[3];
+       u8 table[BEACON_FILTER_TABLE_MAX_SIZE];
+} __packed;
+
+#define SYNCH_FAIL_DEFAULT_THRESHOLD    10     /* number of beacons */
+#define NO_BEACON_DEFAULT_TIMEOUT       (500) /* in microseconds */
+
+struct acx_conn_monit_params {
+       struct acx_header header;
+
+       u32 synch_fail_thold; /* number of beacons missed */
+       u32 bss_lose_timeout; /* number of TU's from synch fail */
+} __packed;
+
+enum {
+       SG_ENABLE = 0,
+       SG_DISABLE,
+       SG_SENSE_NO_ACTIVITY,
+       SG_SENSE_ACTIVE
+};
+
+struct acx_bt_wlan_coex {
+       struct acx_header header;
+
+       /*
+        * 0 -> PTA enabled
+        * 1 -> PTA disabled
+        * 2 -> sense no active mode, i.e.
+        *      an interrupt is sent upon
+        *      BT activity.
+        * 3 -> PTA is switched on in response
+        *      to the interrupt sending.
+        */
+       u8 enable;
+       u8 pad[3];
+} __packed;
+
+#define PTA_ANTENNA_TYPE_DEF             (0)
+#define PTA_BT_HP_MAXTIME_DEF            (2000)
+#define PTA_WLAN_HP_MAX_TIME_DEF         (5000)
+#define PTA_SENSE_DISABLE_TIMER_DEF      (1350)
+#define PTA_PROTECTIVE_RX_TIME_DEF       (1500)
+#define PTA_PROTECTIVE_TX_TIME_DEF       (1500)
+#define PTA_TIMEOUT_NEXT_BT_LP_PACKET_DEF (3000)
+#define PTA_SIGNALING_TYPE_DEF           (1)
+#define PTA_AFH_LEVERAGE_ON_DEF                  (0)
+#define PTA_NUMBER_QUIET_CYCLE_DEF       (0)
+#define PTA_MAX_NUM_CTS_DEF              (3)
+#define PTA_NUMBER_OF_WLAN_PACKETS_DEF   (2)
+#define PTA_NUMBER_OF_BT_PACKETS_DEF     (2)
+#define PTA_PROTECTIVE_RX_TIME_FAST_DEF          (1500)
+#define PTA_PROTECTIVE_TX_TIME_FAST_DEF          (3000)
+#define PTA_CYCLE_TIME_FAST_DEF                  (8700)
+#define PTA_RX_FOR_AVALANCHE_DEF         (5)
+#define PTA_ELP_HP_DEF                   (0)
+#define PTA_ANTI_STARVE_PERIOD_DEF       (500)
+#define PTA_ANTI_STARVE_NUM_CYCLE_DEF    (4)
+#define PTA_ALLOW_PA_SD_DEF              (1)
+#define PTA_TIME_BEFORE_BEACON_DEF       (6300)
+#define PTA_HPDM_MAX_TIME_DEF            (1600)
+#define PTA_TIME_OUT_NEXT_WLAN_DEF       (2550)
+#define PTA_AUTO_MODE_NO_CTS_DEF         (0)
+#define PTA_BT_HP_RESPECTED_DEF                  (3)
+#define PTA_WLAN_RX_MIN_RATE_DEF         (24)
+#define PTA_ACK_MODE_DEF                 (1)
+
+struct acx_bt_wlan_coex_param {
+       struct acx_header header;
+
+       /*
+        * The minimum rate of a received WLAN packet in the STA,
+        * during protective mode, of which a new BT-HP request
+        * during this Rx will always be respected and gain the antenna.
+        */
+       u32 min_rate;
+
+       /* Max time the BT HP will be respected. */
+       u16 bt_hp_max_time;
+
+       /* Max time the WLAN HP will be respected. */
+       u16 wlan_hp_max_time;
+
+       /*
+        * The time between the last BT activity
+        * and the moment when the sense mode returns
+        * to SENSE_INACTIVE.
+        */
+       u16 sense_disable_timer;
+
+       /* Time before the next BT HP instance */
+       u16 rx_time_bt_hp;
+       u16 tx_time_bt_hp;
+
+       /* range: 10-20000    default: 1500 */
+       u16 rx_time_bt_hp_fast;
+       u16 tx_time_bt_hp_fast;
+
+       /* range: 2000-65535  default: 8700 */
+       u16 wlan_cycle_fast;
+
+       /* range: 0 - 15000 (Msec) default: 1000 */
+       u16 bt_anti_starvation_period;
+
+       /* range 400-10000(Usec) default: 3000 */
+       u16 next_bt_lp_packet;
+
+       /* Deafult: worst case for BT DH5 traffic */
+       u16 wake_up_beacon;
+
+       /* range: 0-50000(Usec) default: 1050 */
+       u16 hp_dm_max_guard_time;
+
+       /*
+        * This is to prevent both BT & WLAN antenna
+        * starvation.
+        * Range: 100-50000(Usec) default:2550
+        */
+       u16 next_wlan_packet;
+
+       /* 0 -> shared antenna */
+       u8 antenna_type;
+
+       /*
+        * 0 -> TI legacy
+        * 1 -> Palau
+        */
+       u8 signal_type;
+
+       /*
+        * BT AFH status
+        * 0 -> no AFH
+        * 1 -> from dedicated GPIO
+        * 2 -> AFH on (from host)
+        */
+       u8 afh_leverage_on;
+
+       /*
+        * The number of cycles during which no
+        * TX will be sent after 1 cycle of RX
+        * transaction in protective mode
+        */
+       u8 quiet_cycle_num;
+
+       /*
+        * The maximum number of CTSs that will
+        * be sent for receiving RX packet in
+        * protective mode
+        */
+       u8 max_cts;
+
+       /*
+        * The number of WLAN packets
+        * transferred in common mode before
+        * switching to BT.
+        */
+       u8 wlan_packets_num;
+
+       /*
+        * The number of BT packets
+        * transferred in common mode before
+        * switching to WLAN.
+        */
+       u8 bt_packets_num;
+
+       /* range: 1-255  default: 5 */
+       u8 missed_rx_avalanche;
+
+       /* range: 0-1    default: 1 */
+       u8 wlan_elp_hp;
+
+       /* range: 0 - 15  default: 4 */
+       u8 bt_anti_starvation_cycles;
+
+       u8 ack_mode_dual_ant;
+
+       /*
+        * Allow PA_SD assertion/de-assertion
+        * during enabled BT activity.
+        */
+       u8 pa_sd_enable;
+
+       /*
+        * Enable/Disable PTA in auto mode:
+        * Support Both Active & P.S modes
+        */
+       u8 pta_auto_mode_enable;
+
+       /* range: 0 - 20  default: 1 */
+       u8 bt_hp_respected_num;
+} __packed;
+
+#define CCA_THRSH_ENABLE_ENERGY_D       0x140A
+#define CCA_THRSH_DISABLE_ENERGY_D      0xFFEF
+
+struct acx_energy_detection {
+       struct acx_header header;
+
+       /* The RX Clear Channel Assessment threshold in the PHY */
+       u16 rx_cca_threshold;
+       u8 tx_energy_detection;
+       u8 pad;
+} __packed;
+
+#define BCN_RX_TIMEOUT_DEF_VALUE        10000
+#define BROADCAST_RX_TIMEOUT_DEF_VALUE  20000
+#define RX_BROADCAST_IN_PS_DEF_VALUE    1
+#define CONSECUTIVE_PS_POLL_FAILURE_DEF 4
+
+struct acx_beacon_broadcast {
+       struct acx_header header;
+
+       u16 beacon_rx_timeout;
+       u16 broadcast_timeout;
+
+       /* Enables receiving of broadcast packets in PS mode */
+       u8 rx_broadcast_in_ps;
+
+       /* Consecutive PS Poll failures before updating the host */
+       u8 ps_poll_threshold;
+       u8 pad[2];
+} __packed;
+
+struct acx_event_mask {
+       struct acx_header header;
+
+       u32 event_mask;
+       u32 high_event_mask; /* Unused */
+} __packed;
+
+#define CFG_RX_FCS             BIT(2)
+#define CFG_RX_ALL_GOOD                BIT(3)
+#define CFG_UNI_FILTER_EN      BIT(4)
+#define CFG_BSSID_FILTER_EN    BIT(5)
+#define CFG_MC_FILTER_EN       BIT(6)
+#define CFG_MC_ADDR0_EN                BIT(7)
+#define CFG_MC_ADDR1_EN                BIT(8)
+#define CFG_BC_REJECT_EN       BIT(9)
+#define CFG_SSID_FILTER_EN     BIT(10)
+#define CFG_RX_INT_FCS_ERROR   BIT(11)
+#define CFG_RX_INT_ENCRYPTED   BIT(12)
+#define CFG_RX_WR_RX_STATUS    BIT(13)
+#define CFG_RX_FILTER_NULTI    BIT(14)
+#define CFG_RX_RESERVE         BIT(15)
+#define CFG_RX_TIMESTAMP_TSF   BIT(16)
+
+#define CFG_RX_RSV_EN          BIT(0)
+#define CFG_RX_RCTS_ACK                BIT(1)
+#define CFG_RX_PRSP_EN         BIT(2)
+#define CFG_RX_PREQ_EN         BIT(3)
+#define CFG_RX_MGMT_EN         BIT(4)
+#define CFG_RX_FCS_ERROR       BIT(5)
+#define CFG_RX_DATA_EN         BIT(6)
+#define CFG_RX_CTL_EN          BIT(7)
+#define CFG_RX_CF_EN           BIT(8)
+#define CFG_RX_BCN_EN          BIT(9)
+#define CFG_RX_AUTH_EN         BIT(10)
+#define CFG_RX_ASSOC_EN                BIT(11)
+
+#define SCAN_PASSIVE           BIT(0)
+#define SCAN_5GHZ_BAND         BIT(1)
+#define SCAN_TRIGGERED         BIT(2)
+#define SCAN_PRIORITY_HIGH     BIT(3)
+
+struct acx_fw_gen_frame_rates {
+       struct acx_header header;
+
+       u8 tx_ctrl_frame_rate; /* RATE_* */
+       u8 tx_ctrl_frame_mod; /* CCK_* or PBCC_* */
+       u8 tx_mgt_frame_rate;
+       u8 tx_mgt_frame_mod;
+} __packed;
+
+/* STA MAC */
+struct acx_dot11_station_id {
+       struct acx_header header;
+
+       u8 mac[ETH_ALEN];
+       u8 pad[2];
+} __packed;
+
+struct acx_feature_config {
+       struct acx_header header;
+
+       u32 options;
+       u32 data_flow_options;
+} __packed;
+
+struct acx_current_tx_power {
+       struct acx_header header;
+
+       u8  current_tx_power;
+       u8  padding[3];
+} __packed;
+
+struct acx_dot11_default_key {
+       struct acx_header header;
+
+       u8 id;
+       u8 pad[3];
+} __packed;
+
+struct acx_tsf_info {
+       struct acx_header header;
+
+       u32 current_tsf_msb;
+       u32 current_tsf_lsb;
+       u32 last_TBTT_msb;
+       u32 last_TBTT_lsb;
+       u8 last_dtim_count;
+       u8 pad[3];
+} __packed;
+
+enum acx_wake_up_event {
+       WAKE_UP_EVENT_BEACON_BITMAP     = 0x01, /* Wake on every Beacon*/
+       WAKE_UP_EVENT_DTIM_BITMAP       = 0x02, /* Wake on every DTIM*/
+       WAKE_UP_EVENT_N_DTIM_BITMAP     = 0x04, /* Wake on every Nth DTIM */
+       WAKE_UP_EVENT_N_BEACONS_BITMAP  = 0x08, /* Wake on every Nth Beacon */
+       WAKE_UP_EVENT_BITS_MASK         = 0x0F
+};
+
+struct acx_wake_up_condition {
+       struct acx_header header;
+
+       u8 wake_up_event; /* Only one bit can be set */
+       u8 listen_interval;
+       u8 pad[2];
+} __packed;
+
+struct acx_aid {
+       struct acx_header header;
+
+       /*
+        * To be set when associated with an AP.
+        */
+       u16 aid;
+       u8 pad[2];
+} __packed;
+
+enum acx_preamble_type {
+       ACX_PREAMBLE_LONG = 0,
+       ACX_PREAMBLE_SHORT = 1
+};
+
+struct acx_preamble {
+       struct acx_header header;
+
+       /*
+        * When set, the WiLink transmits the frames with a short preamble and
+        * when cleared, the WiLink transmits the frames with a long preamble.
+        */
+       u8 preamble;
+       u8 padding[3];
+} __packed;
+
+enum acx_ctsprotect_type {
+       CTSPROTECT_DISABLE = 0,
+       CTSPROTECT_ENABLE = 1
+};
+
+struct acx_ctsprotect {
+       struct acx_header header;
+       u8 ctsprotect;
+       u8 padding[3];
+} __packed;
+
+struct acx_tx_statistics {
+       u32 internal_desc_overflow;
+}  __packed;
+
+struct acx_rx_statistics {
+       u32 out_of_mem;
+       u32 hdr_overflow;
+       u32 hw_stuck;
+       u32 dropped;
+       u32 fcs_err;
+       u32 xfr_hint_trig;
+       u32 path_reset;
+       u32 reset_counter;
+} __packed;
+
+struct acx_dma_statistics {
+       u32 rx_requested;
+       u32 rx_errors;
+       u32 tx_requested;
+       u32 tx_errors;
+}  __packed;
+
+struct acx_isr_statistics {
+       /* host command complete */
+       u32 cmd_cmplt;
+
+       /* fiqisr() */
+       u32 fiqs;
+
+       /* (INT_STS_ND & INT_TRIG_RX_HEADER) */
+       u32 rx_headers;
+
+       /* (INT_STS_ND & INT_TRIG_RX_CMPLT) */
+       u32 rx_completes;
+
+       /* (INT_STS_ND & INT_TRIG_NO_RX_BUF) */
+       u32 rx_mem_overflow;
+
+       /* (INT_STS_ND & INT_TRIG_S_RX_RDY) */
+       u32 rx_rdys;
+
+       /* irqisr() */
+       u32 irqs;
+
+       /* (INT_STS_ND & INT_TRIG_TX_PROC) */
+       u32 tx_procs;
+
+       /* (INT_STS_ND & INT_TRIG_DECRYPT_DONE) */
+       u32 decrypt_done;
+
+       /* (INT_STS_ND & INT_TRIG_DMA0) */
+       u32 dma0_done;
+
+       /* (INT_STS_ND & INT_TRIG_DMA1) */
+       u32 dma1_done;
+
+       /* (INT_STS_ND & INT_TRIG_TX_EXC_CMPLT) */
+       u32 tx_exch_complete;
+
+       /* (INT_STS_ND & INT_TRIG_COMMAND) */
+       u32 commands;
+
+       /* (INT_STS_ND & INT_TRIG_RX_PROC) */
+       u32 rx_procs;
+
+       /* (INT_STS_ND & INT_TRIG_PM_802) */
+       u32 hw_pm_mode_changes;
+
+       /* (INT_STS_ND & INT_TRIG_ACKNOWLEDGE) */
+       u32 host_acknowledges;
+
+       /* (INT_STS_ND & INT_TRIG_PM_PCI) */
+       u32 pci_pm;
+
+       /* (INT_STS_ND & INT_TRIG_ACM_WAKEUP) */
+       u32 wakeups;
+
+       /* (INT_STS_ND & INT_TRIG_LOW_RSSI) */
+       u32 low_rssi;
+} __packed;
+
+struct acx_wep_statistics {
+       /* WEP address keys configured */
+       u32 addr_key_count;
+
+       /* default keys configured */
+       u32 default_key_count;
+
+       u32 reserved;
+
+       /* number of times that WEP key not found on lookup */
+       u32 key_not_found;
+
+       /* number of times that WEP key decryption failed */
+       u32 decrypt_fail;
+
+       /* WEP packets decrypted */
+       u32 packets;
+
+       /* WEP decrypt interrupts */
+       u32 interrupt;
+} __packed;
+
+#define ACX_MISSED_BEACONS_SPREAD 10
+
+struct acx_pwr_statistics {
+       /* the amount of enters into power save mode (both PD & ELP) */
+       u32 ps_enter;
+
+       /* the amount of enters into ELP mode */
+       u32 elp_enter;
+
+       /* the amount of missing beacon interrupts to the host */
+       u32 missing_bcns;
+
+       /* the amount of wake on host-access times */
+       u32 wake_on_host;
+
+       /* the amount of wake on timer-expire */
+       u32 wake_on_timer_exp;
+
+       /* the number of packets that were transmitted with PS bit set */
+       u32 tx_with_ps;
+
+       /* the number of packets that were transmitted with PS bit clear */
+       u32 tx_without_ps;
+
+       /* the number of received beacons */
+       u32 rcvd_beacons;
+
+       /* the number of entering into PowerOn (power save off) */
+       u32 power_save_off;
+
+       /* the number of entries into power save mode */
+       u16 enable_ps;
+
+       /*
+        * the number of exits from power save, not including failed PS
+        * transitions
+        */
+       u16 disable_ps;
+
+       /*
+        * the number of times the TSF counter was adjusted because
+        * of drift
+        */
+       u32 fix_tsf_ps;
+
+       /* Gives statistics about the spread continuous missed beacons.
+        * The 16 LSB are dedicated for the PS mode.
+        * The 16 MSB are dedicated for the PS mode.
+        * cont_miss_bcns_spread[0] - single missed beacon.
+        * cont_miss_bcns_spread[1] - two continuous missed beacons.
+        * cont_miss_bcns_spread[2] - three continuous missed beacons.
+        * ...
+        * cont_miss_bcns_spread[9] - ten and more continuous missed beacons.
+       */
+       u32 cont_miss_bcns_spread[ACX_MISSED_BEACONS_SPREAD];
+
+       /* the number of beacons in awake mode */
+       u32 rcvd_awake_beacons;
+} __packed;
+
+struct acx_mic_statistics {
+       u32 rx_pkts;
+       u32 calc_failure;
+} __packed;
+
+struct acx_aes_statistics {
+       u32 encrypt_fail;
+       u32 decrypt_fail;
+       u32 encrypt_packets;
+       u32 decrypt_packets;
+       u32 encrypt_interrupt;
+       u32 decrypt_interrupt;
+} __packed;
+
+struct acx_event_statistics {
+       u32 heart_beat;
+       u32 calibration;
+       u32 rx_mismatch;
+       u32 rx_mem_empty;
+       u32 rx_pool;
+       u32 oom_late;
+       u32 phy_transmit_error;
+       u32 tx_stuck;
+} __packed;
+
+struct acx_ps_statistics {
+       u32 pspoll_timeouts;
+       u32 upsd_timeouts;
+       u32 upsd_max_sptime;
+       u32 upsd_max_apturn;
+       u32 pspoll_max_apturn;
+       u32 pspoll_utilization;
+       u32 upsd_utilization;
+} __packed;
+
+struct acx_rxpipe_statistics {
+       u32 rx_prep_beacon_drop;
+       u32 descr_host_int_trig_rx_data;
+       u32 beacon_buffer_thres_host_int_trig_rx_data;
+       u32 missed_beacon_host_int_trig_rx_data;
+       u32 tx_xfr_host_int_trig_rx_data;
+} __packed;
+
+struct acx_statistics {
+       struct acx_header header;
+
+       struct acx_tx_statistics tx;
+       struct acx_rx_statistics rx;
+       struct acx_dma_statistics dma;
+       struct acx_isr_statistics isr;
+       struct acx_wep_statistics wep;
+       struct acx_pwr_statistics pwr;
+       struct acx_aes_statistics aes;
+       struct acx_mic_statistics mic;
+       struct acx_event_statistics event;
+       struct acx_ps_statistics ps;
+       struct acx_rxpipe_statistics rxpipe;
+} __packed;
+
+#define ACX_MAX_RATE_CLASSES       8
+#define ACX_RATE_MASK_UNSPECIFIED  0
+#define ACX_RATE_RETRY_LIMIT      10
+
+struct acx_rate_class {
+       u32 enabled_rates;
+       u8 short_retry_limit;
+       u8 long_retry_limit;
+       u8 aflags;
+       u8 reserved;
+} __packed;
+
+struct acx_rate_policy {
+       struct acx_header header;
+
+       u32 rate_class_cnt;
+       struct acx_rate_class rate_class[ACX_MAX_RATE_CLASSES];
+} __packed;
+
+struct wl1251_acx_memory {
+       __le16 num_stations; /* number of STAs to be supported. */
+       u16 reserved_1;
+
+       /*
+        * Nmber of memory buffers for the RX mem pool.
+        * The actual number may be less if there are
+        * not enough blocks left for the minimum num
+        * of TX ones.
+        */
+       u8 rx_mem_block_num;
+       u8 reserved_2;
+       u8 num_tx_queues; /* From 1 to 16 */
+       u8 host_if_options; /* HOST_IF* */
+       u8 tx_min_mem_block_num;
+       u8 num_ssid_profiles;
+       __le16 debug_buffer_size;
+} __packed;
+
+
+#define ACX_RX_DESC_MIN                1
+#define ACX_RX_DESC_MAX                127
+#define ACX_RX_DESC_DEF                32
+struct wl1251_acx_rx_queue_config {
+       u8 num_descs;
+       u8 pad;
+       u8 type;
+       u8 priority;
+       __le32 dma_address;
+} __packed;
+
+#define ACX_TX_DESC_MIN                1
+#define ACX_TX_DESC_MAX                127
+#define ACX_TX_DESC_DEF                16
+struct wl1251_acx_tx_queue_config {
+    u8 num_descs;
+    u8 pad[2];
+    u8 attributes;
+} __packed;
+
+#define MAX_TX_QUEUE_CONFIGS 5
+#define MAX_TX_QUEUES 4
+struct wl1251_acx_config_memory {
+       struct acx_header header;
+
+       struct wl1251_acx_memory mem_config;
+       struct wl1251_acx_rx_queue_config rx_queue_config;
+       struct wl1251_acx_tx_queue_config tx_queue_config[MAX_TX_QUEUE_CONFIGS];
+} __packed;
+
+struct wl1251_acx_mem_map {
+       struct acx_header header;
+
+       void *code_start;
+       void *code_end;
+
+       void *wep_defkey_start;
+       void *wep_defkey_end;
+
+       void *sta_table_start;
+       void *sta_table_end;
+
+       void *packet_template_start;
+       void *packet_template_end;
+
+       void *queue_memory_start;
+       void *queue_memory_end;
+
+       void *packet_memory_pool_start;
+       void *packet_memory_pool_end;
+
+       void *debug_buffer1_start;
+       void *debug_buffer1_end;
+
+       void *debug_buffer2_start;
+       void *debug_buffer2_end;
+
+       /* Number of blocks FW allocated for TX packets */
+       u32 num_tx_mem_blocks;
+
+       /* Number of blocks FW allocated for RX packets */
+       u32 num_rx_mem_blocks;
+} __packed;
+
+
+struct wl1251_acx_wr_tbtt_and_dtim {
+
+       struct acx_header header;
+
+       /* Time in TUs between two consecutive beacons */
+       u16 tbtt;
+
+       /*
+        * DTIM period
+        * For BSS: Number of TBTTs in a DTIM period (range: 1-10)
+        * For IBSS: value shall be set to 1
+       */
+       u8  dtim;
+       u8  padding;
+} __packed;
+
+struct wl1251_acx_ac_cfg {
+       struct acx_header header;
+
+       /*
+        * Access Category - The TX queue's access category
+        * (refer to AccessCategory_enum)
+        */
+       u8 ac;
+
+       /*
+        * The contention window minimum size (in slots) for
+        * the access class.
+        */
+       u8 cw_min;
+
+       /*
+        * The contention window maximum size (in slots) for
+        * the access class.
+        */
+       u16 cw_max;
+
+       /* The AIF value (in slots) for the access class. */
+       u8 aifsn;
+
+       u8 reserved;
+
+       /* The TX Op Limit (in microseconds) for the access class. */
+       u16 txop_limit;
+} __packed;
+
+
+enum wl1251_acx_channel_type {
+       CHANNEL_TYPE_DCF        = 0,
+       CHANNEL_TYPE_EDCF       = 1,
+       CHANNEL_TYPE_HCCA       = 2,
+};
+
+enum wl1251_acx_ps_scheme {
+       /* regular ps: simple sending of packets */
+       WL1251_ACX_PS_SCHEME_LEGACY     = 0,
+
+       /* sending a packet triggers a unscheduled apsd downstream */
+       WL1251_ACX_PS_SCHEME_UPSD_TRIGGER       = 1,
+
+       /* a pspoll packet will be sent before every data packet */
+       WL1251_ACX_PS_SCHEME_LEGACY_PSPOLL      = 2,
+
+       /* scheduled apsd mode */
+       WL1251_ACX_PS_SCHEME_SAPSD              = 3,
+};
+
+enum wl1251_acx_ack_policy {
+       WL1251_ACX_ACK_POLICY_LEGACY    = 0,
+       WL1251_ACX_ACK_POLICY_NO_ACK    = 1,
+       WL1251_ACX_ACK_POLICY_BLOCK     = 2,
+};
+
+struct wl1251_acx_tid_cfg {
+       struct acx_header header;
+
+       /* tx queue id number (0-7) */
+       u8 queue;
+
+       /* channel access type for the queue, enum wl1251_acx_channel_type */
+       u8 type;
+
+       /* EDCA: ac index (0-3), HCCA: traffic stream id (8-15) */
+       u8 tsid;
+
+       /* ps scheme of the specified queue, enum wl1251_acx_ps_scheme */
+       u8 ps_scheme;
+
+       /* the tx queue ack policy, enum wl1251_acx_ack_policy */
+       u8 ack_policy;
+
+       u8 padding[3];
+
+       /* not supported */
+       u32 apsdconf[2];
+} __packed;
+
+/*************************************************************************
+
+    Host Interrupt Register (WiLink -> Host)
+
+**************************************************************************/
+
+/* RX packet is ready in Xfer buffer #0 */
+#define WL1251_ACX_INTR_RX0_DATA      BIT(0)
+
+/* TX result(s) are in the TX complete buffer */
+#define WL1251_ACX_INTR_TX_RESULT      BIT(1)
+
+/* OBSOLETE */
+#define WL1251_ACX_INTR_TX_XFR         BIT(2)
+
+/* RX packet is ready in Xfer buffer #1 */
+#define WL1251_ACX_INTR_RX1_DATA       BIT(3)
+
+/* Event was entered to Event MBOX #A */
+#define WL1251_ACX_INTR_EVENT_A                BIT(4)
+
+/* Event was entered to Event MBOX #B */
+#define WL1251_ACX_INTR_EVENT_B                BIT(5)
+
+/* OBSOLETE */
+#define WL1251_ACX_INTR_WAKE_ON_HOST   BIT(6)
+
+/* Trace meassge on MBOX #A */
+#define WL1251_ACX_INTR_TRACE_A                BIT(7)
+
+/* Trace meassge on MBOX #B */
+#define WL1251_ACX_INTR_TRACE_B                BIT(8)
+
+/* Command processing completion */
+#define WL1251_ACX_INTR_CMD_COMPLETE   BIT(9)
+
+/* Init sequence is done */
+#define WL1251_ACX_INTR_INIT_COMPLETE  BIT(14)
+
+#define WL1251_ACX_INTR_ALL           0xFFFFFFFF
+
+enum {
+       ACX_WAKE_UP_CONDITIONS      = 0x0002,
+       ACX_MEM_CFG                 = 0x0003,
+       ACX_SLOT                    = 0x0004,
+       ACX_QUEUE_HEAD              = 0x0005, /* for MASTER mode only */
+       ACX_AC_CFG                  = 0x0007,
+       ACX_MEM_MAP                 = 0x0008,
+       ACX_AID                     = 0x000A,
+       ACX_RADIO_PARAM             = 0x000B, /* Not used */
+       ACX_CFG                     = 0x000C, /* Not used */
+       ACX_FW_REV                  = 0x000D,
+       ACX_MEDIUM_USAGE            = 0x000F,
+       ACX_RX_CFG                  = 0x0010,
+       ACX_TX_QUEUE_CFG            = 0x0011, /* FIXME: only used by wl1251 */
+       ACX_BSS_IN_PS               = 0x0012, /* for AP only */
+       ACX_STATISTICS              = 0x0013, /* Debug API */
+       ACX_FEATURE_CFG             = 0x0015,
+       ACX_MISC_CFG                = 0x0017, /* Not used */
+       ACX_TID_CFG                 = 0x001A,
+       ACX_BEACON_FILTER_OPT       = 0x001F,
+       ACX_LOW_RSSI                = 0x0020,
+       ACX_NOISE_HIST              = 0x0021,
+       ACX_HDK_VERSION             = 0x0022, /* ??? */
+       ACX_PD_THRESHOLD            = 0x0023,
+       ACX_DATA_PATH_PARAMS        = 0x0024, /* WO */
+       ACX_DATA_PATH_RESP_PARAMS   = 0x0024, /* RO */
+       ACX_CCA_THRESHOLD           = 0x0025,
+       ACX_EVENT_MBOX_MASK         = 0x0026,
+#ifdef FW_RUNNING_AS_AP
+       ACX_DTIM_PERIOD             = 0x0027, /* for AP only */
+#else
+       ACX_WR_TBTT_AND_DTIM        = 0x0027, /* STA only */
+#endif
+       ACX_ACI_OPTION_CFG          = 0x0029, /* OBSOLETE (for 1251)*/
+       ACX_GPIO_CFG                = 0x002A, /* Not used */
+       ACX_GPIO_SET                = 0x002B, /* Not used */
+       ACX_PM_CFG                  = 0x002C, /* To Be Documented */
+       ACX_CONN_MONIT_PARAMS       = 0x002D,
+       ACX_AVERAGE_RSSI            = 0x002E, /* Not used */
+       ACX_CONS_TX_FAILURE         = 0x002F,
+       ACX_BCN_DTIM_OPTIONS        = 0x0031,
+       ACX_SG_ENABLE               = 0x0032,
+       ACX_SG_CFG                  = 0x0033,
+       ACX_ANTENNA_DIVERSITY_CFG   = 0x0035, /* To Be Documented */
+       ACX_LOW_SNR                 = 0x0037, /* To Be Documented */
+       ACX_BEACON_FILTER_TABLE     = 0x0038,
+       ACX_ARP_IP_FILTER           = 0x0039,
+       ACX_ROAMING_STATISTICS_TBL  = 0x003B,
+       ACX_RATE_POLICY             = 0x003D,
+       ACX_CTS_PROTECTION          = 0x003E,
+       ACX_SLEEP_AUTH              = 0x003F,
+       ACX_PREAMBLE_TYPE           = 0x0040,
+       ACX_ERROR_CNT               = 0x0041,
+       ACX_FW_GEN_FRAME_RATES      = 0x0042,
+       ACX_IBSS_FILTER             = 0x0044,
+       ACX_SERVICE_PERIOD_TIMEOUT  = 0x0045,
+       ACX_TSF_INFO                = 0x0046,
+       ACX_CONFIG_PS_WMM           = 0x0049,
+       ACX_ENABLE_RX_DATA_FILTER   = 0x004A,
+       ACX_SET_RX_DATA_FILTER      = 0x004B,
+       ACX_GET_DATA_FILTER_STATISTICS = 0x004C,
+       ACX_POWER_LEVEL_TABLE       = 0x004D,
+       ACX_BET_ENABLE              = 0x0050,
+       DOT11_STATION_ID            = 0x1001,
+       DOT11_RX_MSDU_LIFE_TIME     = 0x1004,
+       DOT11_CUR_TX_PWR            = 0x100D,
+       DOT11_DEFAULT_KEY           = 0x1010,
+       DOT11_RX_DOT11_MODE         = 0x1012,
+       DOT11_RTS_THRESHOLD         = 0x1013,
+       DOT11_GROUP_ADDRESS_TBL     = 0x1014,
+
+       MAX_DOT11_IE = DOT11_GROUP_ADDRESS_TBL,
+
+       MAX_IE = 0xFFFF
+};
+
+
+int wl1251_acx_frame_rates(struct wl1251 *wl, u8 ctrl_rate, u8 ctrl_mod,
+                          u8 mgt_rate, u8 mgt_mod);
+int wl1251_acx_station_id(struct wl1251 *wl);
+int wl1251_acx_default_key(struct wl1251 *wl, u8 key_id);
+int wl1251_acx_wake_up_conditions(struct wl1251 *wl, u8 wake_up_event,
+                                 u8 listen_interval);
+int wl1251_acx_sleep_auth(struct wl1251 *wl, u8 sleep_auth);
+int wl1251_acx_fw_version(struct wl1251 *wl, char *buf, size_t len);
+int wl1251_acx_tx_power(struct wl1251 *wl, int power);
+int wl1251_acx_feature_cfg(struct wl1251 *wl);
+int wl1251_acx_mem_map(struct wl1251 *wl,
+                      struct acx_header *mem_map, size_t len);
+int wl1251_acx_data_path_params(struct wl1251 *wl,
+                               struct acx_data_path_params_resp *data_path);
+int wl1251_acx_rx_msdu_life_time(struct wl1251 *wl, u32 life_time);
+int wl1251_acx_rx_config(struct wl1251 *wl, u32 config, u32 filter);
+int wl1251_acx_pd_threshold(struct wl1251 *wl);
+int wl1251_acx_slot(struct wl1251 *wl, enum acx_slot_type slot_time);
+int wl1251_acx_group_address_tbl(struct wl1251 *wl);
+int wl1251_acx_service_period_timeout(struct wl1251 *wl);
+int wl1251_acx_rts_threshold(struct wl1251 *wl, u16 rts_threshold);
+int wl1251_acx_beacon_filter_opt(struct wl1251 *wl, bool enable_filter);
+int wl1251_acx_beacon_filter_table(struct wl1251 *wl);
+int wl1251_acx_conn_monit_params(struct wl1251 *wl);
+int wl1251_acx_sg_enable(struct wl1251 *wl);
+int wl1251_acx_sg_cfg(struct wl1251 *wl);
+int wl1251_acx_cca_threshold(struct wl1251 *wl);
+int wl1251_acx_bcn_dtim_options(struct wl1251 *wl);
+int wl1251_acx_aid(struct wl1251 *wl, u16 aid);
+int wl1251_acx_event_mbox_mask(struct wl1251 *wl, u32 event_mask);
+int wl1251_acx_set_preamble(struct wl1251 *wl, enum acx_preamble_type preamble);
+int wl1251_acx_cts_protect(struct wl1251 *wl,
+                           enum acx_ctsprotect_type ctsprotect);
+int wl1251_acx_statistics(struct wl1251 *wl, struct acx_statistics *stats);
+int wl1251_acx_tsf_info(struct wl1251 *wl, u64 *mactime);
+int wl1251_acx_rate_policies(struct wl1251 *wl);
+int wl1251_acx_mem_cfg(struct wl1251 *wl);
+int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim);
+int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max,
+                     u8 aifs, u16 txop);
+int wl1251_acx_tid_cfg(struct wl1251 *wl, u8 queue,
+                      enum wl1251_acx_channel_type type,
+                      u8 tsid, enum wl1251_acx_ps_scheme ps_scheme,
+                      enum wl1251_acx_ack_policy ack_policy);
+
+#endif /* __WL1251_ACX_H__ */
diff --git a/drivers/net/wireless/wl1251/boot.c b/drivers/net/wireless/wl1251/boot.c
new file mode 100644 (file)
index 0000000..61572df
--- /dev/null
@@ -0,0 +1,557 @@
+/*
+ * This file is part of wl1251
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 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 St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/gpio.h>
+#include <linux/slab.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)
+{
+       wl1251_reg_write32(wl, ACX_REG_INTERRUPT_MASK, ~(wl->intr_mask));
+       wl1251_reg_write32(wl, HI_CFG, HI_CFG_DEF_VAL);
+}
+
+int wl1251_boot_soft_reset(struct wl1251 *wl)
+{
+       unsigned long timeout;
+       u32 boot_data;
+
+       /* perform soft reset */
+       wl1251_reg_write32(wl, ACX_REG_SLV_SOFT_RESET, ACX_SLV_SOFT_RESET_BIT);
+
+       /* SOFT_RESET is self clearing */
+       timeout = jiffies + usecs_to_jiffies(SOFT_RESET_MAX_TIME);
+       while (1) {
+               boot_data = wl1251_reg_read32(wl, ACX_REG_SLV_SOFT_RESET);
+               wl1251_debug(DEBUG_BOOT, "soft reset bootdata 0x%x", boot_data);
+               if ((boot_data & ACX_SLV_SOFT_RESET_BIT) == 0)
+                       break;
+
+               if (time_after(jiffies, timeout)) {
+                       /* 1.2 check pWhalBus->uSelfClearTime if the
+                        * timeout was reached */
+                       wl1251_error("soft reset timeout");
+                       return -1;
+               }
+
+               udelay(SOFT_RESET_STALL_TIME);
+       }
+
+       /* disable Rx/Tx */
+       wl1251_reg_write32(wl, ENABLE, 0x0);
+
+       /* disable auto calibration on start*/
+       wl1251_reg_write32(wl, SPARE_A2, 0xffff);
+
+       return 0;
+}
+
+int wl1251_boot_init_seq(struct wl1251 *wl)
+{
+       u32 scr_pad6, init_data, tmp, elp_cmd, ref_freq;
+
+       /*
+        * col #1: INTEGER_DIVIDER
+        * col #2: FRACTIONAL_DIVIDER
+        * col #3: ATTN_BB
+        * col #4: ALPHA_BB
+        * col #5: STOP_TIME_BB
+        * col #6: BB_PLL_LOOP_FILTER
+        */
+       static const u32 LUT[REF_FREQ_NUM][LUT_PARAM_NUM] = {
+
+               {   83, 87381,  0xB, 5, 0xF00,  3}, /* REF_FREQ_19_2*/
+               {   61, 141154, 0xB, 5, 0x1450, 2}, /* REF_FREQ_26_0*/
+               {   41, 174763, 0xC, 6, 0x2D00, 1}, /* REF_FREQ_38_4*/
+               {   40, 0,      0xC, 6, 0x2EE0, 1}, /* REF_FREQ_40_0*/
+               {   47, 162280, 0xC, 6, 0x2760, 1}  /* REF_FREQ_33_6        */
+       };
+
+       /* read NVS params */
+       scr_pad6 = wl1251_reg_read32(wl, SCR_PAD6);
+       wl1251_debug(DEBUG_BOOT, "scr_pad6 0x%x", scr_pad6);
+
+       /* read ELP_CMD */
+       elp_cmd = wl1251_reg_read32(wl, ELP_CMD);
+       wl1251_debug(DEBUG_BOOT, "elp_cmd 0x%x", elp_cmd);
+
+       /* set the BB calibration time to be 300 usec (PLL_CAL_TIME) */
+       ref_freq = scr_pad6 & 0x000000FF;
+       wl1251_debug(DEBUG_BOOT, "ref_freq 0x%x", ref_freq);
+
+       wl1251_reg_write32(wl, PLL_CAL_TIME, 0x9);
+
+       /*
+        * PG 1.2: set the clock buffer time to be 210 usec (CLK_BUF_TIME)
+        */
+       wl1251_reg_write32(wl, CLK_BUF_TIME, 0x6);
+
+       /*
+        * set the clock detect feature to work in the restart wu procedure
+        * (ELP_CFG_MODE[14]) and Select the clock source type
+        * (ELP_CFG_MODE[13:12])
+        */
+       tmp = ((scr_pad6 & 0x0000FF00) << 4) | 0x00004000;
+       wl1251_reg_write32(wl, ELP_CFG_MODE, tmp);
+
+       /* PG 1.2: enable the BB PLL fix. Enable the PLL_LIMP_CLK_EN_CMD */
+       elp_cmd |= 0x00000040;
+       wl1251_reg_write32(wl, ELP_CMD, elp_cmd);
+
+       /* PG 1.2: Set the BB PLL stable time to be 1000usec
+        * (PLL_STABLE_TIME) */
+       wl1251_reg_write32(wl, CFG_PLL_SYNC_CNT, 0x20);
+
+       /* PG 1.2: read clock request time */
+       init_data = wl1251_reg_read32(wl, CLK_REQ_TIME);
+
+       /*
+        * PG 1.2: set the clock request time to be ref_clk_settling_time -
+        * 1ms = 4ms
+        */
+       if (init_data > 0x21)
+               tmp = init_data - 0x21;
+       else
+               tmp = 0;
+       wl1251_reg_write32(wl, CLK_REQ_TIME, tmp);
+
+       /* set BB PLL configurations in RF AFE */
+       wl1251_reg_write32(wl, 0x003058cc, 0x4B5);
+
+       /* set RF_AFE_REG_5 */
+       wl1251_reg_write32(wl, 0x003058d4, 0x50);
+
+       /* set RF_AFE_CTRL_REG_2 */
+       wl1251_reg_write32(wl, 0x00305948, 0x11c001);
+
+       /*
+        * change RF PLL and BB PLL divider for VCO clock and adjust VCO
+        * bais current(RF_AFE_REG_13)
+        */
+       wl1251_reg_write32(wl, 0x003058f4, 0x1e);
+
+       /* set BB PLL configurations */
+       tmp = LUT[ref_freq][LUT_PARAM_INTEGER_DIVIDER] | 0x00017000;
+       wl1251_reg_write32(wl, 0x00305840, tmp);
+
+       /* set fractional divider according to Appendix C-BB PLL
+        * Calculations
+        */
+       tmp = LUT[ref_freq][LUT_PARAM_FRACTIONAL_DIVIDER];
+       wl1251_reg_write32(wl, 0x00305844, tmp);
+
+       /* set the initial data for the sigma delta */
+       wl1251_reg_write32(wl, 0x00305848, 0x3039);
+
+       /*
+        * set the accumulator attenuation value, calibration loop1
+        * (alpha), calibration loop2 (beta), calibration loop3 (gamma) and
+        * the VCO gain
+        */
+       tmp = (LUT[ref_freq][LUT_PARAM_ATTN_BB] << 16) |
+               (LUT[ref_freq][LUT_PARAM_ALPHA_BB] << 12) | 0x1;
+       wl1251_reg_write32(wl, 0x00305854, tmp);
+
+       /*
+        * set the calibration stop time after holdoff time expires and set
+        * settling time HOLD_OFF_TIME_BB
+        */
+       tmp = LUT[ref_freq][LUT_PARAM_STOP_TIME_BB] | 0x000A0000;
+       wl1251_reg_write32(wl, 0x00305858, tmp);
+
+       /*
+        * set BB PLL Loop filter capacitor3- BB_C3[2:0] and set BB PLL
+        * constant leakage current to linearize PFD to 0uA -
+        * BB_ILOOPF[7:3]
+        */
+       tmp = LUT[ref_freq][LUT_PARAM_BB_PLL_LOOP_FILTER] | 0x00000030;
+       wl1251_reg_write32(wl, 0x003058f8, tmp);
+
+       /*
+        * set regulator output voltage for n divider to
+        * 1.35-BB_REFDIV[1:0], set charge pump current- BB_CPGAIN[4:2],
+        * set BB PLL Loop filter capacitor2- BB_C2[7:5], set gain of BB
+        * PLL auto-call to normal mode- BB_CALGAIN_3DB[8]
+        */
+       wl1251_reg_write32(wl, 0x003058f0, 0x29);
+
+       /* enable restart wakeup sequence (ELP_CMD[0]) */
+       wl1251_reg_write32(wl, ELP_CMD, elp_cmd | 0x1);
+
+       /* restart sequence completed */
+       udelay(2000);
+
+       return 0;
+}
+
+static void wl1251_boot_set_ecpu_ctrl(struct wl1251 *wl, u32 flag)
+{
+       u32 cpu_ctrl;
+
+       /* 10.5.0 run the firmware (I) */
+       cpu_ctrl = wl1251_reg_read32(wl, ACX_REG_ECPU_CONTROL);
+
+       /* 10.5.1 run the firmware (II) */
+       cpu_ctrl &= ~flag;
+       wl1251_reg_write32(wl, ACX_REG_ECPU_CONTROL, cpu_ctrl);
+}
+
+int wl1251_boot_run_firmware(struct wl1251 *wl)
+{
+       int loop, ret;
+       u32 chip_id, acx_intr;
+
+       wl1251_boot_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT);
+
+       chip_id = wl1251_reg_read32(wl, CHIP_ID_B);
+
+       wl1251_debug(DEBUG_BOOT, "chip id after firmware boot: 0x%x", chip_id);
+
+       if (chip_id != wl->chip_id) {
+               wl1251_error("chip id doesn't match after firmware boot");
+               return -EIO;
+       }
+
+       /* wait for init to complete */
+       loop = 0;
+       while (loop++ < INIT_LOOP) {
+               udelay(INIT_LOOP_DELAY);
+               acx_intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
+
+               if (acx_intr == 0xffffffff) {
+                       wl1251_error("error reading hardware complete "
+                                    "init indication");
+                       return -EIO;
+               }
+               /* check that ACX_INTR_INIT_COMPLETE is enabled */
+               else if (acx_intr & WL1251_ACX_INTR_INIT_COMPLETE) {
+                       wl1251_reg_write32(wl, ACX_REG_INTERRUPT_ACK,
+                                          WL1251_ACX_INTR_INIT_COMPLETE);
+                       break;
+               }
+       }
+
+       if (loop > INIT_LOOP) {
+               wl1251_error("timeout waiting for the hardware to "
+                            "complete initialization");
+               return -EIO;
+       }
+
+       /* get hardware config command mail box */
+       wl->cmd_box_addr = wl1251_reg_read32(wl, REG_COMMAND_MAILBOX_PTR);
+
+       /* get hardware config event mail box */
+       wl->event_box_addr = wl1251_reg_read32(wl, REG_EVENT_MAILBOX_PTR);
+
+       /* set the working partition to its "running" mode offset */
+       wl1251_set_partition(wl, WL1251_PART_WORK_MEM_START,
+                            WL1251_PART_WORK_MEM_SIZE,
+                            WL1251_PART_WORK_REG_START,
+                            WL1251_PART_WORK_REG_SIZE);
+
+       wl1251_debug(DEBUG_MAILBOX, "cmd_box_addr 0x%x event_box_addr 0x%x",
+                    wl->cmd_box_addr, wl->event_box_addr);
+
+       wl1251_acx_fw_version(wl, wl->fw_ver, sizeof(wl->fw_ver));
+
+       /*
+        * in case of full asynchronous mode the firmware event must be
+        * ready to receive event from the command mailbox
+        */
+
+       /* enable gpio interrupts */
+       wl1251_enable_interrupts(wl);
+
+       /* Enable target's interrupts */
+       wl->intr_mask = WL1251_ACX_INTR_RX0_DATA |
+               WL1251_ACX_INTR_RX1_DATA |
+               WL1251_ACX_INTR_TX_RESULT |
+               WL1251_ACX_INTR_EVENT_A |
+               WL1251_ACX_INTR_EVENT_B |
+               WL1251_ACX_INTR_INIT_COMPLETE;
+       wl1251_boot_target_enable_interrupts(wl);
+
+       wl->event_mask = SCAN_COMPLETE_EVENT_ID | BSS_LOSE_EVENT_ID |
+               SYNCHRONIZATION_TIMEOUT_EVENT_ID |
+               ROAMING_TRIGGER_LOW_RSSI_EVENT_ID |
+               ROAMING_TRIGGER_REGAINED_RSSI_EVENT_ID |
+               REGAINED_BSS_EVENT_ID | BT_PTA_SENSE_EVENT_ID |
+               BT_PTA_PREDICTION_EVENT_ID | JOIN_EVENT_COMPLETE_ID;
+
+       ret = wl1251_event_unmask(wl);
+       if (ret < 0) {
+               wl1251_error("EVENT mask setting failed");
+               return ret;
+       }
+
+       wl1251_event_mbox_config(wl);
+
+       /* firmware startup completed */
+       return 0;
+}
+
+static int wl1251_boot_upload_firmware(struct wl1251 *wl)
+{
+       int addr, chunk_num, partition_limit;
+       size_t fw_data_len, len;
+       u8 *p, *buf;
+
+       /* whal_FwCtrl_LoadFwImageSm() */
+
+       wl1251_debug(DEBUG_BOOT, "chip id before fw upload: 0x%x",
+                    wl1251_reg_read32(wl, CHIP_ID_B));
+
+       /* 10.0 check firmware length and set partition */
+       fw_data_len =  (wl->fw[4] << 24) | (wl->fw[5] << 16) |
+               (wl->fw[6] << 8) | (wl->fw[7]);
+
+       wl1251_debug(DEBUG_BOOT, "fw_data_len %zu chunk_size %d", fw_data_len,
+               CHUNK_SIZE);
+
+       if ((fw_data_len % 4) != 0) {
+               wl1251_error("firmware length not multiple of four");
+               return -EIO;
+       }
+
+       buf = kmalloc(CHUNK_SIZE, GFP_KERNEL);
+       if (!buf) {
+               wl1251_error("allocation for firmware upload chunk failed");
+               return -ENOMEM;
+       }
+
+       wl1251_set_partition(wl, WL1251_PART_DOWN_MEM_START,
+                            WL1251_PART_DOWN_MEM_SIZE,
+                            WL1251_PART_DOWN_REG_START,
+                            WL1251_PART_DOWN_REG_SIZE);
+
+       /* 10.1 set partition limit and chunk num */
+       chunk_num = 0;
+       partition_limit = WL1251_PART_DOWN_MEM_SIZE;
+
+       while (chunk_num < fw_data_len / CHUNK_SIZE) {
+               /* 10.2 update partition, if needed */
+               addr = WL1251_PART_DOWN_MEM_START +
+                       (chunk_num + 2) * CHUNK_SIZE;
+               if (addr > partition_limit) {
+                       addr = WL1251_PART_DOWN_MEM_START +
+                               chunk_num * CHUNK_SIZE;
+                       partition_limit = chunk_num * CHUNK_SIZE +
+                               WL1251_PART_DOWN_MEM_SIZE;
+                       wl1251_set_partition(wl,
+                                            addr,
+                                            WL1251_PART_DOWN_MEM_SIZE,
+                                            WL1251_PART_DOWN_REG_START,
+                                            WL1251_PART_DOWN_REG_SIZE);
+               }
+
+               /* 10.3 upload the chunk */
+               addr = WL1251_PART_DOWN_MEM_START + chunk_num * CHUNK_SIZE;
+               p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE;
+               wl1251_debug(DEBUG_BOOT, "uploading fw chunk 0x%p to 0x%x",
+                            p, addr);
+
+               /* need to copy the chunk for dma */
+               len = CHUNK_SIZE;
+               memcpy(buf, p, len);
+               wl1251_mem_write(wl, addr, buf, len);
+
+               chunk_num++;
+       }
+
+       /* 10.4 upload the last chunk */
+       addr = WL1251_PART_DOWN_MEM_START + chunk_num * CHUNK_SIZE;
+       p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE;
+
+       /* need to copy the chunk for dma */
+       len = fw_data_len % CHUNK_SIZE;
+       memcpy(buf, p, len);
+
+       wl1251_debug(DEBUG_BOOT, "uploading fw last chunk (%zu B) 0x%p to 0x%x",
+                    len, p, addr);
+       wl1251_mem_write(wl, addr, buf, len);
+
+       kfree(buf);
+
+       return 0;
+}
+
+static int wl1251_boot_upload_nvs(struct wl1251 *wl)
+{
+       size_t nvs_len, nvs_bytes_written, burst_len;
+       int nvs_start, i;
+       u32 dest_addr, val;
+       u8 *nvs_ptr, *nvs;
+
+       nvs = wl->nvs;
+       if (nvs == NULL)
+               return -ENODEV;
+
+       nvs_ptr = nvs;
+
+       nvs_len = wl->nvs_len;
+       nvs_start = wl->fw_len;
+
+       /*
+        * Layout before the actual NVS tables:
+        * 1 byte : burst length.
+        * 2 bytes: destination address.
+        * n bytes: data to burst copy.
+        *
+        * This is ended by a 0 length, then the NVS tables.
+        */
+
+       while (nvs_ptr[0]) {
+               burst_len = nvs_ptr[0];
+               dest_addr = (nvs_ptr[1] & 0xfe) | ((u32)(nvs_ptr[2] << 8));
+
+               /* We move our pointer to the data */
+               nvs_ptr += 3;
+
+               for (i = 0; i < burst_len; i++) {
+                       val = (nvs_ptr[0] | (nvs_ptr[1] << 8)
+                              | (nvs_ptr[2] << 16) | (nvs_ptr[3] << 24));
+
+                       wl1251_debug(DEBUG_BOOT,
+                                    "nvs burst write 0x%x: 0x%x",
+                                    dest_addr, val);
+                       wl1251_mem_write32(wl, dest_addr, val);
+
+                       nvs_ptr += 4;
+                       dest_addr += 4;
+               }
+       }
+
+       /*
+        * We've reached the first zero length, the first NVS table
+        * is 7 bytes further.
+        */
+       nvs_ptr += 7;
+       nvs_len -= nvs_ptr - nvs;
+       nvs_len = ALIGN(nvs_len, 4);
+
+       /* Now we must set the partition correctly */
+       wl1251_set_partition(wl, nvs_start,
+                            WL1251_PART_DOWN_MEM_SIZE,
+                            WL1251_PART_DOWN_REG_START,
+                            WL1251_PART_DOWN_REG_SIZE);
+
+       /* And finally we upload the NVS tables */
+       nvs_bytes_written = 0;
+       while (nvs_bytes_written < nvs_len) {
+               val = (nvs_ptr[0] | (nvs_ptr[1] << 8)
+                      | (nvs_ptr[2] << 16) | (nvs_ptr[3] << 24));
+
+               val = cpu_to_le32(val);
+
+               wl1251_debug(DEBUG_BOOT,
+                            "nvs write table 0x%x: 0x%x",
+                            nvs_start, val);
+               wl1251_mem_write32(wl, nvs_start, val);
+
+               nvs_ptr += 4;
+               nvs_bytes_written += 4;
+               nvs_start += 4;
+       }
+
+       return 0;
+}
+
+int wl1251_boot(struct wl1251 *wl)
+{
+       int ret = 0, minor_minor_e2_ver;
+       u32 tmp, boot_data;
+
+       /* halt embedded ARM CPU while loading firmware */
+       wl1251_reg_write32(wl, ACX_REG_ECPU_CONTROL, ECPU_CONTROL_HALT);
+
+       ret = wl1251_boot_soft_reset(wl);
+       if (ret < 0)
+               goto out;
+
+       /* 2. start processing NVS file */
+       if (wl->use_eeprom) {
+               wl1251_reg_write32(wl, ACX_REG_EE_START, START_EEPROM_MGR);
+               /* Wait for EEPROM NVS burst read to complete */
+               msleep(40);
+               wl1251_reg_write32(wl, ACX_EEPROMLESS_IND_REG, USE_EEPROM);
+       } else {
+               ret = wl1251_boot_upload_nvs(wl);
+               if (ret < 0)
+                       goto out;
+
+               /* write firmware's last address (ie. it's length) to
+                * ACX_EEPROMLESS_IND_REG */
+               wl1251_reg_write32(wl, ACX_EEPROMLESS_IND_REG, wl->fw_len);
+       }
+
+       /* 6. read the EEPROM parameters */
+       tmp = wl1251_reg_read32(wl, SCR_PAD2);
+
+       /* 7. read bootdata */
+       wl->boot_attr.radio_type = (tmp & 0x0000FF00) >> 8;
+       wl->boot_attr.major = (tmp & 0x00FF0000) >> 16;
+       tmp = wl1251_reg_read32(wl, SCR_PAD3);
+
+       /* 8. check bootdata and call restart sequence */
+       wl->boot_attr.minor = (tmp & 0x00FF0000) >> 16;
+       minor_minor_e2_ver = (tmp & 0xFF000000) >> 24;
+
+       wl1251_debug(DEBUG_BOOT, "radioType 0x%x majorE2Ver 0x%x "
+                    "minorE2Ver 0x%x minor_minor_e2_ver 0x%x",
+                    wl->boot_attr.radio_type, wl->boot_attr.major,
+                    wl->boot_attr.minor, minor_minor_e2_ver);
+
+       ret = wl1251_boot_init_seq(wl);
+       if (ret < 0)
+               goto out;
+
+       /* 9. NVS processing done */
+       boot_data = wl1251_reg_read32(wl, ACX_REG_ECPU_CONTROL);
+
+       wl1251_debug(DEBUG_BOOT, "halt boot_data 0x%x", boot_data);
+
+       /* 10. check that ECPU_CONTROL_HALT bits are set in
+        * pWhalBus->uBootData and start uploading firmware
+        */
+       if ((boot_data & ECPU_CONTROL_HALT) == 0) {
+               wl1251_error("boot failed, ECPU_CONTROL_HALT not set");
+               ret = -EIO;
+               goto out;
+       }
+
+       ret = wl1251_boot_upload_firmware(wl);
+       if (ret < 0)
+               goto out;
+
+       /* 10.5 start firmware */
+       ret = wl1251_boot_run_firmware(wl);
+       if (ret < 0)
+               goto out;
+
+out:
+       return ret;
+}
diff --git a/drivers/net/wireless/wl1251/boot.h b/drivers/net/wireless/wl1251/boot.h
new file mode 100644 (file)
index 0000000..7661bc5
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * This file is part of wl1251
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 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 St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __BOOT_H__
+#define __BOOT_H__
+
+#include "wl1251.h"
+
+int wl1251_boot_soft_reset(struct wl1251 *wl);
+int wl1251_boot_init_seq(struct wl1251 *wl);
+int wl1251_boot_run_firmware(struct wl1251 *wl);
+void wl1251_boot_target_enable_interrupts(struct wl1251 *wl);
+int wl1251_boot(struct wl1251 *wl);
+
+/* number of times we try to read the INIT interrupt */
+#define INIT_LOOP 20000
+
+/* delay between retries */
+#define INIT_LOOP_DELAY 50
+
+#endif
diff --git a/drivers/net/wireless/wl1251/cmd.c b/drivers/net/wireless/wl1251/cmd.c
new file mode 100644 (file)
index 0000000..0ade4bd
--- /dev/null
@@ -0,0 +1,496 @@
+#include "cmd.h"
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/crc7.h>
+
+#include "wl1251.h"
+#include "reg.h"
+#include "io.h"
+#include "ps.h"
+#include "acx.h"
+
+/**
+ * send command to firmware
+ *
+ * @wl: wl struct
+ * @id: command id
+ * @buf: buffer containing the command, must work with dma
+ * @len: length of the buffer
+ */
+int wl1251_cmd_send(struct wl1251 *wl, u16 id, void *buf, size_t len)
+{
+       struct wl1251_cmd_header *cmd;
+       unsigned long timeout;
+       u32 intr;
+       int ret = 0;
+
+       cmd = buf;
+       cmd->id = id;
+       cmd->status = 0;
+
+       WARN_ON(len % 4 != 0);
+
+       wl1251_mem_write(wl, wl->cmd_box_addr, buf, len);
+
+       wl1251_reg_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_CMD);
+
+       timeout = jiffies + msecs_to_jiffies(WL1251_COMMAND_TIMEOUT);
+
+       intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
+       while (!(intr & WL1251_ACX_INTR_CMD_COMPLETE)) {
+               if (time_after(jiffies, timeout)) {
+                       wl1251_error("command complete timeout");
+                       ret = -ETIMEDOUT;
+                       goto out;
+               }
+
+               msleep(1);
+
+               intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
+       }
+
+       wl1251_reg_write32(wl, ACX_REG_INTERRUPT_ACK,
+                          WL1251_ACX_INTR_CMD_COMPLETE);
+
+out:
+       return ret;
+}
+
+/**
+ * send test command to firmware
+ *
+ * @wl: wl struct
+ * @buf: buffer containing the command, with all headers, must work with dma
+ * @len: length of the buffer
+ * @answer: is answer needed
+ */
+int wl1251_cmd_test(struct wl1251 *wl, void *buf, size_t buf_len, u8 answer)
+{
+       int ret;
+
+       wl1251_debug(DEBUG_CMD, "cmd test");
+
+       ret = wl1251_cmd_send(wl, CMD_TEST, buf, buf_len);
+
+       if (ret < 0) {
+               wl1251_warning("TEST command failed");
+               return ret;
+       }
+
+       if (answer) {
+               struct wl1251_command *cmd_answer;
+
+               /*
+                * The test command got in, we can read the answer.
+                * The answer would be a wl1251_command, where the
+                * parameter array contains the actual answer.
+                */
+               wl1251_mem_read(wl, wl->cmd_box_addr, buf, buf_len);
+
+               cmd_answer = buf;
+
+               if (cmd_answer->header.status != CMD_STATUS_SUCCESS)
+                       wl1251_error("TEST command answer error: %d",
+                                    cmd_answer->header.status);
+       }
+
+       return 0;
+}
+
+/**
+ * read acx from firmware
+ *
+ * @wl: wl struct
+ * @id: acx id
+ * @buf: buffer for the response, including all headers, must work with dma
+ * @len: lenght of buf
+ */
+int wl1251_cmd_interrogate(struct wl1251 *wl, u16 id, void *buf, size_t len)
+{
+       struct acx_header *acx = buf;
+       int ret;
+
+       wl1251_debug(DEBUG_CMD, "cmd interrogate");
+
+       acx->id = id;
+
+       /* payload length, does not include any headers */
+       acx->len = len - sizeof(*acx);
+
+       ret = wl1251_cmd_send(wl, CMD_INTERROGATE, acx, sizeof(*acx));
+       if (ret < 0) {
+               wl1251_error("INTERROGATE command failed");
+               goto out;
+       }
+
+       /* the interrogate command got in, we can read the answer */
+       wl1251_mem_read(wl, wl->cmd_box_addr, buf, len);
+
+       acx = buf;
+       if (acx->cmd.status != CMD_STATUS_SUCCESS)
+               wl1251_error("INTERROGATE command error: %d",
+                            acx->cmd.status);
+
+out:
+       return ret;
+}
+
+/**
+ * write acx value to firmware
+ *
+ * @wl: wl struct
+ * @id: acx id
+ * @buf: buffer containing acx, including all headers, must work with dma
+ * @len: length of buf
+ */
+int wl1251_cmd_configure(struct wl1251 *wl, u16 id, void *buf, size_t len)
+{
+       struct acx_header *acx = buf;
+       int ret;
+
+       wl1251_debug(DEBUG_CMD, "cmd configure");
+
+       acx->id = id;
+
+       /* payload length, does not include any headers */
+       acx->len = len - sizeof(*acx);
+
+       ret = wl1251_cmd_send(wl, CMD_CONFIGURE, acx, len);
+       if (ret < 0) {
+               wl1251_warning("CONFIGURE command NOK");
+               return ret;
+       }
+
+       return 0;
+}
+
+int wl1251_cmd_vbm(struct wl1251 *wl, u8 identity,
+                  void *bitmap, u16 bitmap_len, u8 bitmap_control)
+{
+       struct wl1251_cmd_vbm_update *vbm;
+       int ret;
+
+       wl1251_debug(DEBUG_CMD, "cmd vbm");
+
+       vbm = kzalloc(sizeof(*vbm), GFP_KERNEL);
+       if (!vbm) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       /* Count and period will be filled by the target */
+       vbm->tim.bitmap_ctrl = bitmap_control;
+       if (bitmap_len > PARTIAL_VBM_MAX) {
+               wl1251_warning("cmd vbm len is %d B, truncating to %d",
+                              bitmap_len, PARTIAL_VBM_MAX);
+               bitmap_len = PARTIAL_VBM_MAX;
+       }
+       memcpy(vbm->tim.pvb_field, bitmap, bitmap_len);
+       vbm->tim.identity = identity;
+       vbm->tim.length = bitmap_len + 3;
+
+       vbm->len = cpu_to_le16(bitmap_len + 5);
+
+       ret = wl1251_cmd_send(wl, CMD_VBM, vbm, sizeof(*vbm));
+       if (ret < 0) {
+               wl1251_error("VBM command failed");
+               goto out;
+       }
+
+out:
+       kfree(vbm);
+       return ret;
+}
+
+int wl1251_cmd_data_path(struct wl1251 *wl, u8 channel, bool enable)
+{
+       struct cmd_enabledisable_path *cmd;
+       int ret;
+       u16 cmd_rx, cmd_tx;
+
+       wl1251_debug(DEBUG_CMD, "cmd data path");
+
+       cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+       if (!cmd) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       cmd->channel = channel;
+
+       if (enable) {
+               cmd_rx = CMD_ENABLE_RX;
+               cmd_tx = CMD_ENABLE_TX;
+       } else {
+               cmd_rx = CMD_DISABLE_RX;
+               cmd_tx = CMD_DISABLE_TX;
+       }
+
+       ret = wl1251_cmd_send(wl, cmd_rx, cmd, sizeof(*cmd));
+       if (ret < 0) {
+               wl1251_error("rx %s cmd for channel %d failed",
+                            enable ? "start" : "stop", channel);
+               goto out;
+       }
+
+       wl1251_debug(DEBUG_BOOT, "rx %s cmd channel %d",
+                    enable ? "start" : "stop", channel);
+
+       ret = wl1251_cmd_send(wl, cmd_tx, cmd, sizeof(*cmd));
+       if (ret < 0) {
+               wl1251_error("tx %s cmd for channel %d failed",
+                            enable ? "start" : "stop", channel);
+               return ret;
+       }
+
+       wl1251_debug(DEBUG_BOOT, "tx %s cmd channel %d",
+                    enable ? "start" : "stop", channel);
+
+out:
+       kfree(cmd);
+       return ret;
+}
+
+int wl1251_cmd_join(struct wl1251 *wl, u8 bss_type, u8 channel,
+                   u16 beacon_interval, u8 dtim_interval)
+{
+       struct cmd_join *join;
+       int ret, i;
+       u8 *bssid;
+
+       join = kzalloc(sizeof(*join), GFP_KERNEL);
+       if (!join) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       wl1251_debug(DEBUG_CMD, "cmd join%s ch %d %d/%d",
+                    bss_type == BSS_TYPE_IBSS ? " ibss" : "",
+                    channel, beacon_interval, dtim_interval);
+
+       /* Reverse order BSSID */
+       bssid = (u8 *) &join->bssid_lsb;
+       for (i = 0; i < ETH_ALEN; i++)
+               bssid[i] = wl->bssid[ETH_ALEN - i - 1];
+
+       join->rx_config_options = wl->rx_config;
+       join->rx_filter_options = wl->rx_filter;
+
+       /*
+        * FIXME: disable temporarily all filters because after commit
+        * 9cef8737 "mac80211: fix managed mode BSSID handling" broke
+        * association. The filter logic needs to be implemented properly
+        * and once that is done, this hack can be removed.
+        */
+       join->rx_config_options = 0;
+       join->rx_filter_options = WL1251_DEFAULT_RX_FILTER;
+
+       join->basic_rate_set = RATE_MASK_1MBPS | RATE_MASK_2MBPS |
+               RATE_MASK_5_5MBPS | RATE_MASK_11MBPS;
+
+       join->beacon_interval = beacon_interval;
+       join->dtim_interval = dtim_interval;
+       join->bss_type = bss_type;
+       join->channel = channel;
+       join->ctrl = JOIN_CMD_CTRL_TX_FLUSH;
+
+       ret = wl1251_cmd_send(wl, CMD_START_JOIN, join, sizeof(*join));
+       if (ret < 0) {
+               wl1251_error("failed to initiate cmd join");
+               goto out;
+       }
+
+out:
+       kfree(join);
+       return ret;
+}
+
+int wl1251_cmd_ps_mode(struct wl1251 *wl, u8 ps_mode)
+{
+       struct wl1251_cmd_ps_params *ps_params = NULL;
+       int ret = 0;
+
+       wl1251_debug(DEBUG_CMD, "cmd set ps mode");
+
+       ps_params = kzalloc(sizeof(*ps_params), GFP_KERNEL);
+       if (!ps_params) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       ps_params->ps_mode = ps_mode;
+       ps_params->send_null_data = 1;
+       ps_params->retries = 5;
+       ps_params->hang_over_period = 128;
+       ps_params->null_data_rate = 1; /* 1 Mbps */
+
+       ret = wl1251_cmd_send(wl, CMD_SET_PS_MODE, ps_params,
+                             sizeof(*ps_params));
+       if (ret < 0) {
+               wl1251_error("cmd set_ps_mode failed");
+               goto out;
+       }
+
+out:
+       kfree(ps_params);
+       return ret;
+}
+
+int wl1251_cmd_read_memory(struct wl1251 *wl, u32 addr, void *answer,
+                          size_t len)
+{
+       struct cmd_read_write_memory *cmd;
+       int ret = 0;
+
+       wl1251_debug(DEBUG_CMD, "cmd read memory");
+
+       cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+       if (!cmd) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       WARN_ON(len > MAX_READ_SIZE);
+       len = min_t(size_t, len, MAX_READ_SIZE);
+
+       cmd->addr = addr;
+       cmd->size = len;
+
+       ret = wl1251_cmd_send(wl, CMD_READ_MEMORY, cmd, sizeof(*cmd));
+       if (ret < 0) {
+               wl1251_error("read memory command failed: %d", ret);
+               goto out;
+       }
+
+       /* the read command got in, we can now read the answer */
+       wl1251_mem_read(wl, wl->cmd_box_addr, cmd, sizeof(*cmd));
+
+       if (cmd->header.status != CMD_STATUS_SUCCESS)
+               wl1251_error("error in read command result: %d",
+                            cmd->header.status);
+
+       memcpy(answer, cmd->value, len);
+
+out:
+       kfree(cmd);
+       return ret;
+}
+
+int wl1251_cmd_template_set(struct wl1251 *wl, u16 cmd_id,
+                           void *buf, size_t buf_len)
+{
+       struct wl1251_cmd_packet_template *cmd;
+       size_t cmd_len;
+       int ret = 0;
+
+       wl1251_debug(DEBUG_CMD, "cmd template %d", cmd_id);
+
+       WARN_ON(buf_len > WL1251_MAX_TEMPLATE_SIZE);
+       buf_len = min_t(size_t, buf_len, WL1251_MAX_TEMPLATE_SIZE);
+       cmd_len = ALIGN(sizeof(*cmd) + buf_len, 4);
+
+       cmd = kzalloc(cmd_len, GFP_KERNEL);
+       if (!cmd) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       cmd->size = cpu_to_le16(buf_len);
+
+       if (buf)
+               memcpy(cmd->data, buf, buf_len);
+
+       ret = wl1251_cmd_send(wl, cmd_id, cmd, cmd_len);
+       if (ret < 0) {
+               wl1251_warning("cmd set_template failed: %d", ret);
+               goto out;
+       }
+
+out:
+       kfree(cmd);
+       return ret;
+}
+
+int wl1251_cmd_scan(struct wl1251 *wl, u8 *ssid, size_t ssid_len,
+                   struct ieee80211_channel *channels[],
+                   unsigned int n_channels, unsigned int n_probes)
+{
+       struct wl1251_cmd_scan *cmd;
+       int i, ret = 0;
+
+       wl1251_debug(DEBUG_CMD, "cmd scan");
+
+       cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+       if (!cmd)
+               return -ENOMEM;
+
+       cmd->params.rx_config_options = cpu_to_le32(CFG_RX_ALL_GOOD);
+       cmd->params.rx_filter_options = cpu_to_le32(CFG_RX_PRSP_EN |
+                                                   CFG_RX_MGMT_EN |
+                                                   CFG_RX_BCN_EN);
+       cmd->params.scan_options = 0;
+       cmd->params.num_channels = n_channels;
+       cmd->params.num_probe_requests = n_probes;
+       cmd->params.tx_rate = cpu_to_le16(1 << 1); /* 2 Mbps */
+       cmd->params.tid_trigger = 0;
+
+       for (i = 0; i < n_channels; i++) {
+               cmd->channels[i].min_duration =
+                       cpu_to_le32(WL1251_SCAN_MIN_DURATION);
+               cmd->channels[i].max_duration =
+                       cpu_to_le32(WL1251_SCAN_MAX_DURATION);
+               memset(&cmd->channels[i].bssid_lsb, 0xff, 4);
+               memset(&cmd->channels[i].bssid_msb, 0xff, 2);
+               cmd->channels[i].early_termination = 0;
+               cmd->channels[i].tx_power_att = 0;
+               cmd->channels[i].channel = channels[i]->hw_value;
+       }
+
+       cmd->params.ssid_len = ssid_len;
+       if (ssid)
+               memcpy(cmd->params.ssid, ssid, ssid_len);
+
+       ret = wl1251_cmd_send(wl, CMD_SCAN, cmd, sizeof(*cmd));
+       if (ret < 0) {
+               wl1251_error("cmd scan failed: %d", ret);
+               goto out;
+       }
+
+       wl1251_mem_read(wl, wl->cmd_box_addr, cmd, sizeof(*cmd));
+
+       if (cmd->header.status != CMD_STATUS_SUCCESS) {
+               wl1251_error("cmd scan status wasn't success: %d",
+                            cmd->header.status);
+               ret = -EIO;
+               goto out;
+       }
+
+out:
+       kfree(cmd);
+       return ret;
+}
+
+int wl1251_cmd_trigger_scan_to(struct wl1251 *wl, u32 timeout)
+{
+       struct wl1251_cmd_trigger_scan_to *cmd;
+       int ret;
+
+       wl1251_debug(DEBUG_CMD, "cmd trigger scan to");
+
+       cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+       if (!cmd)
+               return -ENOMEM;
+
+       cmd->timeout = timeout;
+
+       ret = wl1251_cmd_send(wl, CMD_TRIGGER_SCAN_TO, cmd, sizeof(*cmd));
+       if (ret < 0) {
+               wl1251_error("cmd trigger scan to failed: %d", ret);
+               goto out;
+       }
+
+out:
+       kfree(cmd);
+       return ret;
+}
diff --git a/drivers/net/wireless/wl1251/cmd.h b/drivers/net/wireless/wl1251/cmd.h
new file mode 100644 (file)
index 0000000..e5c74c6
--- /dev/null
@@ -0,0 +1,415 @@
+/*
+ * This file is part of wl1251
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 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 St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __WL1251_CMD_H__
+#define __WL1251_CMD_H__
+
+#include "wl1251.h"
+
+#include <net/cfg80211.h>
+
+struct acx_header;
+
+int wl1251_cmd_send(struct wl1251 *wl, u16 type, void *buf, size_t buf_len);
+int wl1251_cmd_test(struct wl1251 *wl, void *buf, size_t buf_len, u8 answer);
+int wl1251_cmd_interrogate(struct wl1251 *wl, u16 id, void *buf, size_t len);
+int wl1251_cmd_configure(struct wl1251 *wl, u16 id, void *buf, size_t len);
+int wl1251_cmd_vbm(struct wl1251 *wl, u8 identity,
+                  void *bitmap, u16 bitmap_len, u8 bitmap_control);
+int wl1251_cmd_data_path(struct wl1251 *wl, u8 channel, bool enable);
+int wl1251_cmd_join(struct wl1251 *wl, u8 bss_type, u8 channel,
+                   u16 beacon_interval, u8 dtim_interval);
+int wl1251_cmd_ps_mode(struct wl1251 *wl, u8 ps_mode);
+int wl1251_cmd_read_memory(struct wl1251 *wl, u32 addr, void *answer,
+                          size_t len);
+int wl1251_cmd_template_set(struct wl1251 *wl, u16 cmd_id,
+                           void *buf, size_t buf_len);
+int wl1251_cmd_scan(struct wl1251 *wl, u8 *ssid, size_t ssid_len,
+                   struct ieee80211_channel *channels[],
+                   unsigned int n_channels, unsigned int n_probes);
+int wl1251_cmd_trigger_scan_to(struct wl1251 *wl, u32 timeout);
+
+/* unit ms */
+#define WL1251_COMMAND_TIMEOUT 2000
+
+enum wl1251_commands {
+       CMD_RESET           = 0,
+       CMD_INTERROGATE     = 1,    /*use this to read information elements*/
+       CMD_CONFIGURE       = 2,    /*use this to write information elements*/
+       CMD_ENABLE_RX       = 3,
+       CMD_ENABLE_TX       = 4,
+       CMD_DISABLE_RX      = 5,
+       CMD_DISABLE_TX      = 6,
+       CMD_SCAN            = 8,
+       CMD_STOP_SCAN       = 9,
+       CMD_VBM             = 10,
+       CMD_START_JOIN      = 11,
+       CMD_SET_KEYS        = 12,
+       CMD_READ_MEMORY     = 13,
+       CMD_WRITE_MEMORY    = 14,
+       CMD_BEACON          = 19,
+       CMD_PROBE_RESP      = 20,
+       CMD_NULL_DATA       = 21,
+       CMD_PROBE_REQ       = 22,
+       CMD_TEST            = 23,
+       CMD_RADIO_CALIBRATE     = 25,   /* OBSOLETE */
+       CMD_ENABLE_RX_PATH      = 27,   /* OBSOLETE */
+       CMD_NOISE_HIST      = 28,
+       CMD_RX_RESET        = 29,
+       CMD_PS_POLL         = 30,
+       CMD_QOS_NULL_DATA   = 31,
+       CMD_LNA_CONTROL     = 32,
+       CMD_SET_BCN_MODE    = 33,
+       CMD_MEASUREMENT      = 34,
+       CMD_STOP_MEASUREMENT = 35,
+       CMD_DISCONNECT       = 36,
+       CMD_SET_PS_MODE      = 37,
+       CMD_CHANNEL_SWITCH   = 38,
+       CMD_STOP_CHANNEL_SWICTH = 39,
+       CMD_AP_DISCOVERY     = 40,
+       CMD_STOP_AP_DISCOVERY = 41,
+       CMD_SPS_SCAN = 42,
+       CMD_STOP_SPS_SCAN = 43,
+       CMD_HEALTH_CHECK     = 45,
+       CMD_DEBUG            = 46,
+       CMD_TRIGGER_SCAN_TO  = 47,
+
+       NUM_COMMANDS,
+       MAX_COMMAND_ID = 0xFFFF,
+};
+
+#define MAX_CMD_PARAMS 572
+
+struct wl1251_cmd_header {
+       u16 id;
+       u16 status;
+       /* payload */
+       u8 data[0];
+} __packed;
+
+struct  wl1251_command {
+       struct wl1251_cmd_header header;
+       u8  parameters[MAX_CMD_PARAMS];
+} __packed;
+
+enum {
+       CMD_MAILBOX_IDLE                        =  0,
+       CMD_STATUS_SUCCESS                      =  1,
+       CMD_STATUS_UNKNOWN_CMD                  =  2,
+       CMD_STATUS_UNKNOWN_IE                   =  3,
+       CMD_STATUS_REJECT_MEAS_SG_ACTIVE        = 11,
+       CMD_STATUS_RX_BUSY                      = 13,
+       CMD_STATUS_INVALID_PARAM                = 14,
+       CMD_STATUS_TEMPLATE_TOO_LARGE           = 15,
+       CMD_STATUS_OUT_OF_MEMORY                = 16,
+       CMD_STATUS_STA_TABLE_FULL               = 17,
+       CMD_STATUS_RADIO_ERROR                  = 18,
+       CMD_STATUS_WRONG_NESTING                = 19,
+       CMD_STATUS_TIMEOUT                      = 21, /* Driver internal use.*/
+       CMD_STATUS_FW_RESET                     = 22, /* Driver internal use.*/
+       MAX_COMMAND_STATUS                      = 0xff
+};
+
+
+/*
+ * CMD_READ_MEMORY
+ *
+ * The host issues this command to read the WiLink device memory/registers.
+ *
+ * Note: The Base Band address has special handling (16 bits registers and
+ * addresses). For more information, see the hardware specification.
+ */
+/*
+ * CMD_WRITE_MEMORY
+ *
+ * The host issues this command to write the WiLink device memory/registers.
+ *
+ * The Base Band address has special handling (16 bits registers and
+ * addresses). For more information, see the hardware specification.
+ */
+#define MAX_READ_SIZE 256
+
+struct cmd_read_write_memory {
+       struct wl1251_cmd_header header;
+
+       /* The address of the memory to read from or write to.*/
+       u32 addr;
+
+       /* The amount of data in bytes to read from or write to the WiLink
+        * device.*/
+       u32 size;
+
+       /* The actual value read from or written to the Wilink. The source
+          of this field is the Host in WRITE command or the Wilink in READ
+          command. */
+       u8 value[MAX_READ_SIZE];
+} __packed;
+
+#define CMDMBOX_HEADER_LEN 4
+#define CMDMBOX_INFO_ELEM_HEADER_LEN 4
+
+#define WL1251_SCAN_MIN_DURATION 30000
+#define WL1251_SCAN_MAX_DURATION 60000
+
+#define WL1251_SCAN_NUM_PROBES 3
+
+struct wl1251_scan_parameters {
+       __le32 rx_config_options;
+       __le32 rx_filter_options;
+
+       /*
+        * Scan options:
+        * bit 0: When this bit is set, passive scan.
+        * bit 1: Band, when this bit is set we scan
+        * in the 5Ghz band.
+        * bit 2: voice mode, 0 for normal scan.
+        * bit 3: scan priority, 1 for high priority.
+        */
+       __le16 scan_options;
+
+       /* Number of channels to scan */
+       u8 num_channels;
+
+       /* Number opf probe requests to send, per channel */
+       u8 num_probe_requests;
+
+       /* Rate and modulation for probe requests */
+       __le16 tx_rate;
+
+       u8 tid_trigger;
+       u8 ssid_len;
+       u8 ssid[32];
+
+} __packed;
+
+struct wl1251_scan_ch_parameters {
+       __le32 min_duration; /* in TU */
+       __le32 max_duration; /* in TU */
+       u32 bssid_lsb;
+       u16 bssid_msb;
+
+       /*
+        * bits 0-3: Early termination count.
+        * bits 4-5: Early termination condition.
+        */
+       u8 early_termination;
+
+       u8 tx_power_att;
+       u8 channel;
+       u8 pad[3];
+} __packed;
+
+/* SCAN parameters */
+#define SCAN_MAX_NUM_OF_CHANNELS 16
+
+struct wl1251_cmd_scan {
+       struct wl1251_cmd_header header;
+
+       struct wl1251_scan_parameters params;
+       struct wl1251_scan_ch_parameters channels[SCAN_MAX_NUM_OF_CHANNELS];
+} __packed;
+
+enum {
+       BSS_TYPE_IBSS = 0,
+       BSS_TYPE_STA_BSS = 2,
+       BSS_TYPE_AP_BSS = 3,
+       MAX_BSS_TYPE = 0xFF
+};
+
+#define JOIN_CMD_CTRL_TX_FLUSH             0x80 /* Firmware flushes all Tx */
+#define JOIN_CMD_CTRL_EARLY_WAKEUP_ENABLE  0x01 /* Early wakeup time */
+
+
+struct cmd_join {
+       struct wl1251_cmd_header header;
+
+       u32 bssid_lsb;
+       u16 bssid_msb;
+       u16 beacon_interval; /* in TBTTs */
+       u32 rx_config_options;
+       u32 rx_filter_options;
+
+       /*
+        * The target uses this field to determine the rate at
+        * which to transmit control frame responses (such as
+        * ACK or CTS frames).
+        */
+       u16 basic_rate_set;
+       u8 dtim_interval;
+       u8 tx_ctrl_frame_rate; /* OBSOLETE */
+       u8 tx_ctrl_frame_mod;  /* OBSOLETE */
+       /*
+        * bits 0-2: This bitwise field specifies the type
+        * of BSS to start or join (BSS_TYPE_*).
+        * bit 4: Band - The radio band in which to join
+        * or start.
+        *  0 - 2.4GHz band
+        *  1 - 5GHz band
+        * bits 3, 5-7: Reserved
+        */
+       u8 bss_type;
+       u8 channel;
+       u8 ssid_len;
+       u8 ssid[IW_ESSID_MAX_SIZE];
+       u8 ctrl; /* JOIN_CMD_CTRL_* */
+       u8 tx_mgt_frame_rate; /* OBSOLETE */
+       u8 tx_mgt_frame_mod;  /* OBSOLETE */
+       u8 reserved;
+} __packed;
+
+struct cmd_enabledisable_path {
+       struct wl1251_cmd_header header;
+
+       u8 channel;
+       u8 padding[3];
+} __packed;
+
+#define WL1251_MAX_TEMPLATE_SIZE 300
+
+struct wl1251_cmd_packet_template {
+       struct wl1251_cmd_header header;
+
+       __le16 size;
+       u8 data[0];
+} __packed;
+
+#define TIM_ELE_ID    5
+#define PARTIAL_VBM_MAX    251
+
+struct wl1251_tim {
+       u8 identity;
+       u8 length;
+       u8 dtim_count;
+       u8 dtim_period;
+       u8 bitmap_ctrl;
+       u8 pvb_field[PARTIAL_VBM_MAX]; /* Partial Virtual Bitmap */
+} __packed;
+
+/* Virtual Bit Map update */
+struct wl1251_cmd_vbm_update {
+       struct wl1251_cmd_header header;
+       __le16 len;
+       u8  padding[2];
+       struct wl1251_tim tim;
+} __packed;
+
+enum wl1251_cmd_ps_mode {
+       STATION_ACTIVE_MODE,
+       STATION_POWER_SAVE_MODE
+};
+
+struct wl1251_cmd_ps_params {
+       struct wl1251_cmd_header header;
+
+       u8 ps_mode; /* STATION_* */
+       u8 send_null_data; /* Do we have to send NULL data packet ? */
+       u8 retries; /* Number of retires for the initial NULL data packet */
+
+        /*
+         * TUs during which the target stays awake after switching
+         * to power save mode.
+         */
+       u8 hang_over_period;
+       u16 null_data_rate;
+       u8 pad[2];
+} __packed;
+
+struct wl1251_cmd_trigger_scan_to {
+       struct wl1251_cmd_header header;
+
+       u32 timeout;
+} __packed;
+
+/* HW encryption keys */
+#define NUM_ACCESS_CATEGORIES_COPY 4
+#define MAX_KEY_SIZE 32
+
+/* When set, disable HW encryption */
+#define DF_ENCRYPTION_DISABLE      0x01
+/* When set, disable HW decryption */
+#define DF_SNIFF_MODE_ENABLE       0x80
+
+enum wl1251_cmd_key_action {
+       KEY_ADD_OR_REPLACE = 1,
+       KEY_REMOVE         = 2,
+       KEY_SET_ID         = 3,
+       MAX_KEY_ACTION     = 0xffff,
+};
+
+enum wl1251_cmd_key_type {
+       KEY_WEP_DEFAULT       = 0,
+       KEY_WEP_ADDR          = 1,
+       KEY_AES_GROUP         = 4,
+       KEY_AES_PAIRWISE      = 5,
+       KEY_WEP_GROUP         = 6,
+       KEY_TKIP_MIC_GROUP    = 10,
+       KEY_TKIP_MIC_PAIRWISE = 11,
+};
+
+/*
+ *
+ * key_type_e   key size    key format
+ * ----------   ---------   ----------
+ * 0x00         5, 13, 29   Key data
+ * 0x01         5, 13, 29   Key data
+ * 0x04         16          16 bytes of key data
+ * 0x05         16          16 bytes of key data
+ * 0x0a         32          16 bytes of TKIP key data
+ *                          8 bytes of RX MIC key data
+ *                          8 bytes of TX MIC key data
+ * 0x0b         32          16 bytes of TKIP key data
+ *                          8 bytes of RX MIC key data
+ *                          8 bytes of TX MIC key data
+ *
+ */
+
+struct wl1251_cmd_set_keys {
+       struct wl1251_cmd_header header;
+
+       /* Ignored for default WEP key */
+       u8 addr[ETH_ALEN];
+
+       /* key_action_e */
+       u16 key_action;
+
+       u16 reserved_1;
+
+       /* key size in bytes */
+       u8 key_size;
+
+       /* key_type_e */
+       u8 key_type;
+       u8 ssid_profile;
+
+       /*
+        * TKIP, AES: frame's key id field.
+        * For WEP default key: key id;
+        */
+       u8 id;
+       u8 reserved_2[6];
+       u8 key[MAX_KEY_SIZE];
+       u16 ac_seq_num16[NUM_ACCESS_CATEGORIES_COPY];
+       u32 ac_seq_num32[NUM_ACCESS_CATEGORIES_COPY];
+} __packed;
+
+
+#endif /* __WL1251_CMD_H__ */
diff --git a/drivers/net/wireless/wl1251/debugfs.c b/drivers/net/wireless/wl1251/debugfs.c
new file mode 100644 (file)
index 0000000..6e5caaa
--- /dev/null
@@ -0,0 +1,541 @@
+/*
+ * This file is part of wl1251
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 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 St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include "debugfs.h"
+
+#include <linux/skbuff.h>
+#include <linux/slab.h>
+
+#include "wl1251.h"
+#include "acx.h"
+#include "ps.h"
+
+/* ms */
+#define WL1251_DEBUGFS_STATS_LIFETIME 1000
+
+/* debugfs macros idea from mac80211 */
+
+#define DEBUGFS_READONLY_FILE(name, buflen, fmt, value...)             \
+static ssize_t name## _read(struct file *file, char __user *userbuf,   \
+                           size_t count, loff_t *ppos)                 \
+{                                                                      \
+       struct wl1251 *wl = file->private_data;                         \
+       char buf[buflen];                                               \
+       int res;                                                        \
+                                                                       \
+       res = scnprintf(buf, buflen, fmt "\n", ##value);                \
+       return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
+}                                                                      \
+                                                                       \
+static const struct file_operations name## _ops = {                    \
+       .read = name## _read,                                           \
+       .open = wl1251_open_file_generic,                               \
+};
+
+#define DEBUGFS_ADD(name, parent)                                      \
+       wl->debugfs.name = debugfs_create_file(#name, 0400, parent,     \
+                                              wl, &name## _ops);       \
+       if (IS_ERR(wl->debugfs.name)) {                                 \
+               ret = PTR_ERR(wl->debugfs.name);                        \
+               wl->debugfs.name = NULL;                                \
+               goto out;                                               \
+       }
+
+#define DEBUGFS_DEL(name)                                              \
+       do {                                                            \
+               debugfs_remove(wl->debugfs.name);                       \
+               wl->debugfs.name = NULL;                                \
+       } while (0)
+
+#define DEBUGFS_FWSTATS_FILE(sub, name, buflen, fmt)                   \
+static ssize_t sub## _ ##name## _read(struct file *file,               \
+                                     char __user *userbuf,             \
+                                     size_t count, loff_t *ppos)       \
+{                                                                      \
+       struct wl1251 *wl = file->private_data;                         \
+       char buf[buflen];                                               \
+       int res;                                                        \
+                                                                       \
+       wl1251_debugfs_update_stats(wl);                                \
+                                                                       \
+       res = scnprintf(buf, buflen, fmt "\n",                          \
+                       wl->stats.fw_stats->sub.name);                  \
+       return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
+}                                                                      \
+                                                                       \
+static const struct file_operations sub## _ ##name## _ops = {          \
+       .read = sub## _ ##name## _read,                                 \
+       .open = wl1251_open_file_generic,                               \
+};
+
+#define DEBUGFS_FWSTATS_ADD(sub, name)                         \
+       DEBUGFS_ADD(sub## _ ##name, wl->debugfs.fw_statistics)
+
+#define DEBUGFS_FWSTATS_DEL(sub, name)                         \
+       DEBUGFS_DEL(sub## _ ##name)
+
+static void wl1251_debugfs_update_stats(struct wl1251 *wl)
+{
+       int ret;
+
+       mutex_lock(&wl->mutex);
+
+       ret = wl1251_ps_elp_wakeup(wl);
+       if (ret < 0)
+               goto out;
+
+       if (wl->state == WL1251_STATE_ON &&
+           time_after(jiffies, wl->stats.fw_stats_update +
+                      msecs_to_jiffies(WL1251_DEBUGFS_STATS_LIFETIME))) {
+               wl1251_acx_statistics(wl, wl->stats.fw_stats);
+               wl->stats.fw_stats_update = jiffies;
+       }
+
+       wl1251_ps_elp_sleep(wl);
+
+out:
+       mutex_unlock(&wl->mutex);
+}
+
+static int wl1251_open_file_generic(struct inode *inode, struct file *file)
+{
+       file->private_data = inode->i_private;
+       return 0;
+}
+
+DEBUGFS_FWSTATS_FILE(tx, internal_desc_overflow, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(rx, out_of_mem, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rx, hdr_overflow, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rx, hw_stuck, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rx, dropped, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rx, fcs_err, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rx, xfr_hint_trig, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rx, path_reset, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rx, reset_counter, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(dma, rx_requested, 20, "%u");
+DEBUGFS_FWSTATS_FILE(dma, rx_errors, 20, "%u");
+DEBUGFS_FWSTATS_FILE(dma, tx_requested, 20, "%u");
+DEBUGFS_FWSTATS_FILE(dma, tx_errors, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(isr, cmd_cmplt, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, fiqs, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, rx_headers, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, rx_mem_overflow, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, rx_rdys, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, irqs, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, tx_procs, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, decrypt_done, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, dma0_done, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, dma1_done, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, tx_exch_complete, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, commands, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, rx_procs, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, hw_pm_mode_changes, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, host_acknowledges, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, pci_pm, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, wakeups, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, low_rssi, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(wep, addr_key_count, 20, "%u");
+DEBUGFS_FWSTATS_FILE(wep, default_key_count, 20, "%u");
+/* skipping wep.reserved */
+DEBUGFS_FWSTATS_FILE(wep, key_not_found, 20, "%u");
+DEBUGFS_FWSTATS_FILE(wep, decrypt_fail, 20, "%u");
+DEBUGFS_FWSTATS_FILE(wep, packets, 20, "%u");
+DEBUGFS_FWSTATS_FILE(wep, interrupt, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(pwr, ps_enter, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, elp_enter, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, missing_bcns, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, wake_on_host, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, wake_on_timer_exp, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, tx_with_ps, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, tx_without_ps, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, rcvd_beacons, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, power_save_off, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, enable_ps, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, disable_ps, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, fix_tsf_ps, 20, "%u");
+/* skipping cont_miss_bcns_spread for now */
+DEBUGFS_FWSTATS_FILE(pwr, rcvd_awake_beacons, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(mic, rx_pkts, 20, "%u");
+DEBUGFS_FWSTATS_FILE(mic, calc_failure, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(aes, encrypt_fail, 20, "%u");
+DEBUGFS_FWSTATS_FILE(aes, decrypt_fail, 20, "%u");
+DEBUGFS_FWSTATS_FILE(aes, encrypt_packets, 20, "%u");
+DEBUGFS_FWSTATS_FILE(aes, decrypt_packets, 20, "%u");
+DEBUGFS_FWSTATS_FILE(aes, encrypt_interrupt, 20, "%u");
+DEBUGFS_FWSTATS_FILE(aes, decrypt_interrupt, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(event, heart_beat, 20, "%u");
+DEBUGFS_FWSTATS_FILE(event, calibration, 20, "%u");
+DEBUGFS_FWSTATS_FILE(event, rx_mismatch, 20, "%u");
+DEBUGFS_FWSTATS_FILE(event, rx_mem_empty, 20, "%u");
+DEBUGFS_FWSTATS_FILE(event, rx_pool, 20, "%u");
+DEBUGFS_FWSTATS_FILE(event, oom_late, 20, "%u");
+DEBUGFS_FWSTATS_FILE(event, phy_transmit_error, 20, "%u");
+DEBUGFS_FWSTATS_FILE(event, tx_stuck, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(ps, pspoll_timeouts, 20, "%u");
+DEBUGFS_FWSTATS_FILE(ps, upsd_timeouts, 20, "%u");
+DEBUGFS_FWSTATS_FILE(ps, upsd_max_sptime, 20, "%u");
+DEBUGFS_FWSTATS_FILE(ps, upsd_max_apturn, 20, "%u");
+DEBUGFS_FWSTATS_FILE(ps, pspoll_max_apturn, 20, "%u");
+DEBUGFS_FWSTATS_FILE(ps, pspoll_utilization, 20, "%u");
+DEBUGFS_FWSTATS_FILE(ps, upsd_utilization, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(rxpipe, rx_prep_beacon_drop, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rxpipe, descr_host_int_trig_rx_data, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rxpipe, beacon_buffer_thres_host_int_trig_rx_data,
+                    20, "%u");
+DEBUGFS_FWSTATS_FILE(rxpipe, missed_beacon_host_int_trig_rx_data, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rxpipe, tx_xfr_host_int_trig_rx_data, 20, "%u");
+
+DEBUGFS_READONLY_FILE(retry_count, 20, "%u", wl->stats.retry_count);
+DEBUGFS_READONLY_FILE(excessive_retries, 20, "%u",
+                     wl->stats.excessive_retries);
+
+static ssize_t tx_queue_len_read(struct file *file, char __user *userbuf,
+                                size_t count, loff_t *ppos)
+{
+       struct wl1251 *wl = file->private_data;
+       u32 queue_len;
+       char buf[20];
+       int res;
+
+       queue_len = skb_queue_len(&wl->tx_queue);
+
+       res = scnprintf(buf, sizeof(buf), "%u\n", queue_len);
+       return simple_read_from_buffer(userbuf, count, ppos, buf, res);
+}
+
+static const struct file_operations tx_queue_len_ops = {
+       .read = tx_queue_len_read,
+       .open = wl1251_open_file_generic,
+};
+
+static ssize_t tx_queue_status_read(struct file *file, char __user *userbuf,
+                                   size_t count, loff_t *ppos)
+{
+       struct wl1251 *wl = file->private_data;
+       char buf[3], status;
+       int len;
+
+       if (wl->tx_queue_stopped)
+               status = 's';
+       else
+               status = 'r';
+
+       len = scnprintf(buf, sizeof(buf), "%c\n", status);
+       return simple_read_from_buffer(userbuf, count, ppos, buf, len);
+}
+
+static const struct file_operations tx_queue_status_ops = {
+       .read = tx_queue_status_read,
+       .open = wl1251_open_file_generic,
+};
+
+static void wl1251_debugfs_delete_files(struct wl1251 *wl)
+{
+       DEBUGFS_FWSTATS_DEL(tx, internal_desc_overflow);
+
+       DEBUGFS_FWSTATS_DEL(rx, out_of_mem);
+       DEBUGFS_FWSTATS_DEL(rx, hdr_overflow);
+       DEBUGFS_FWSTATS_DEL(rx, hw_stuck);
+       DEBUGFS_FWSTATS_DEL(rx, dropped);
+       DEBUGFS_FWSTATS_DEL(rx, fcs_err);
+       DEBUGFS_FWSTATS_DEL(rx, xfr_hint_trig);
+       DEBUGFS_FWSTATS_DEL(rx, path_reset);
+       DEBUGFS_FWSTATS_DEL(rx, reset_counter);
+
+       DEBUGFS_FWSTATS_DEL(dma, rx_requested);
+       DEBUGFS_FWSTATS_DEL(dma, rx_errors);
+       DEBUGFS_FWSTATS_DEL(dma, tx_requested);
+       DEBUGFS_FWSTATS_DEL(dma, tx_errors);
+
+       DEBUGFS_FWSTATS_DEL(isr, cmd_cmplt);
+       DEBUGFS_FWSTATS_DEL(isr, fiqs);
+       DEBUGFS_FWSTATS_DEL(isr, rx_headers);
+       DEBUGFS_FWSTATS_DEL(isr, rx_mem_overflow);
+       DEBUGFS_FWSTATS_DEL(isr, rx_rdys);
+       DEBUGFS_FWSTATS_DEL(isr, irqs);
+       DEBUGFS_FWSTATS_DEL(isr, tx_procs);
+       DEBUGFS_FWSTATS_DEL(isr, decrypt_done);
+       DEBUGFS_FWSTATS_DEL(isr, dma0_done);
+       DEBUGFS_FWSTATS_DEL(isr, dma1_done);
+       DEBUGFS_FWSTATS_DEL(isr, tx_exch_complete);
+       DEBUGFS_FWSTATS_DEL(isr, commands);
+       DEBUGFS_FWSTATS_DEL(isr, rx_procs);
+       DEBUGFS_FWSTATS_DEL(isr, hw_pm_mode_changes);
+       DEBUGFS_FWSTATS_DEL(isr, host_acknowledges);
+       DEBUGFS_FWSTATS_DEL(isr, pci_pm);
+       DEBUGFS_FWSTATS_DEL(isr, wakeups);
+       DEBUGFS_FWSTATS_DEL(isr, low_rssi);
+
+       DEBUGFS_FWSTATS_DEL(wep, addr_key_count);
+       DEBUGFS_FWSTATS_DEL(wep, default_key_count);
+       /* skipping wep.reserved */
+       DEBUGFS_FWSTATS_DEL(wep, key_not_found);
+       DEBUGFS_FWSTATS_DEL(wep, decrypt_fail);
+       DEBUGFS_FWSTATS_DEL(wep, packets);
+       DEBUGFS_FWSTATS_DEL(wep, interrupt);
+
+       DEBUGFS_FWSTATS_DEL(pwr, ps_enter);
+       DEBUGFS_FWSTATS_DEL(pwr, elp_enter);
+       DEBUGFS_FWSTATS_DEL(pwr, missing_bcns);
+       DEBUGFS_FWSTATS_DEL(pwr, wake_on_host);
+       DEBUGFS_FWSTATS_DEL(pwr, wake_on_timer_exp);
+       DEBUGFS_FWSTATS_DEL(pwr, tx_with_ps);
+       DEBUGFS_FWSTATS_DEL(pwr, tx_without_ps);
+       DEBUGFS_FWSTATS_DEL(pwr, rcvd_beacons);
+       DEBUGFS_FWSTATS_DEL(pwr, power_save_off);
+       DEBUGFS_FWSTATS_DEL(pwr, enable_ps);
+       DEBUGFS_FWSTATS_DEL(pwr, disable_ps);
+       DEBUGFS_FWSTATS_DEL(pwr, fix_tsf_ps);
+       /* skipping cont_miss_bcns_spread for now */
+       DEBUGFS_FWSTATS_DEL(pwr, rcvd_awake_beacons);
+
+       DEBUGFS_FWSTATS_DEL(mic, rx_pkts);
+       DEBUGFS_FWSTATS_DEL(mic, calc_failure);
+
+       DEBUGFS_FWSTATS_DEL(aes, encrypt_fail);
+       DEBUGFS_FWSTATS_DEL(aes, decrypt_fail);
+       DEBUGFS_FWSTATS_DEL(aes, encrypt_packets);
+       DEBUGFS_FWSTATS_DEL(aes, decrypt_packets);
+       DEBUGFS_FWSTATS_DEL(aes, encrypt_interrupt);
+       DEBUGFS_FWSTATS_DEL(aes, decrypt_interrupt);
+
+       DEBUGFS_FWSTATS_DEL(event, heart_beat);
+       DEBUGFS_FWSTATS_DEL(event, calibration);
+       DEBUGFS_FWSTATS_DEL(event, rx_mismatch);
+       DEBUGFS_FWSTATS_DEL(event, rx_mem_empty);
+       DEBUGFS_FWSTATS_DEL(event, rx_pool);
+       DEBUGFS_FWSTATS_DEL(event, oom_late);
+       DEBUGFS_FWSTATS_DEL(event, phy_transmit_error);
+       DEBUGFS_FWSTATS_DEL(event, tx_stuck);
+
+       DEBUGFS_FWSTATS_DEL(ps, pspoll_timeouts);
+       DEBUGFS_FWSTATS_DEL(ps, upsd_timeouts);
+       DEBUGFS_FWSTATS_DEL(ps, upsd_max_sptime);
+       DEBUGFS_FWSTATS_DEL(ps, upsd_max_apturn);
+       DEBUGFS_FWSTATS_DEL(ps, pspoll_max_apturn);
+       DEBUGFS_FWSTATS_DEL(ps, pspoll_utilization);
+       DEBUGFS_FWSTATS_DEL(ps, upsd_utilization);
+
+       DEBUGFS_FWSTATS_DEL(rxpipe, rx_prep_beacon_drop);
+       DEBUGFS_FWSTATS_DEL(rxpipe, descr_host_int_trig_rx_data);
+       DEBUGFS_FWSTATS_DEL(rxpipe, beacon_buffer_thres_host_int_trig_rx_data);
+       DEBUGFS_FWSTATS_DEL(rxpipe, missed_beacon_host_int_trig_rx_data);
+       DEBUGFS_FWSTATS_DEL(rxpipe, tx_xfr_host_int_trig_rx_data);
+
+       DEBUGFS_DEL(tx_queue_len);
+       DEBUGFS_DEL(tx_queue_status);
+       DEBUGFS_DEL(retry_count);
+       DEBUGFS_DEL(excessive_retries);
+}
+
+static int wl1251_debugfs_add_files(struct wl1251 *wl)
+{
+       int ret = 0;
+
+       DEBUGFS_FWSTATS_ADD(tx, internal_desc_overflow);
+
+       DEBUGFS_FWSTATS_ADD(rx, out_of_mem);
+       DEBUGFS_FWSTATS_ADD(rx, hdr_overflow);
+       DEBUGFS_FWSTATS_ADD(rx, hw_stuck);
+       DEBUGFS_FWSTATS_ADD(rx, dropped);
+       DEBUGFS_FWSTATS_ADD(rx, fcs_err);
+       DEBUGFS_FWSTATS_ADD(rx, xfr_hint_trig);
+       DEBUGFS_FWSTATS_ADD(rx, path_reset);
+       DEBUGFS_FWSTATS_ADD(rx, reset_counter);
+
+       DEBUGFS_FWSTATS_ADD(dma, rx_requested);
+       DEBUGFS_FWSTATS_ADD(dma, rx_errors);
+       DEBUGFS_FWSTATS_ADD(dma, tx_requested);
+       DEBUGFS_FWSTATS_ADD(dma, tx_errors);
+
+       DEBUGFS_FWSTATS_ADD(isr, cmd_cmplt);
+       DEBUGFS_FWSTATS_ADD(isr, fiqs);
+       DEBUGFS_FWSTATS_ADD(isr, rx_headers);
+       DEBUGFS_FWSTATS_ADD(isr, rx_mem_overflow);
+       DEBUGFS_FWSTATS_ADD(isr, rx_rdys);
+       DEBUGFS_FWSTATS_ADD(isr, irqs);
+       DEBUGFS_FWSTATS_ADD(isr, tx_procs);
+       DEBUGFS_FWSTATS_ADD(isr, decrypt_done);
+       DEBUGFS_FWSTATS_ADD(isr, dma0_done);
+       DEBUGFS_FWSTATS_ADD(isr, dma1_done);
+       DEBUGFS_FWSTATS_ADD(isr, tx_exch_complete);
+       DEBUGFS_FWSTATS_ADD(isr, commands);
+       DEBUGFS_FWSTATS_ADD(isr, rx_procs);
+       DEBUGFS_FWSTATS_ADD(isr, hw_pm_mode_changes);
+       DEBUGFS_FWSTATS_ADD(isr, host_acknowledges);
+       DEBUGFS_FWSTATS_ADD(isr, pci_pm);
+       DEBUGFS_FWSTATS_ADD(isr, wakeups);
+       DEBUGFS_FWSTATS_ADD(isr, low_rssi);
+
+       DEBUGFS_FWSTATS_ADD(wep, addr_key_count);
+       DEBUGFS_FWSTATS_ADD(wep, default_key_count);
+       /* skipping wep.reserved */
+       DEBUGFS_FWSTATS_ADD(wep, key_not_found);
+       DEBUGFS_FWSTATS_ADD(wep, decrypt_fail);
+       DEBUGFS_FWSTATS_ADD(wep, packets);
+       DEBUGFS_FWSTATS_ADD(wep, interrupt);
+
+       DEBUGFS_FWSTATS_ADD(pwr, ps_enter);
+       DEBUGFS_FWSTATS_ADD(pwr, elp_enter);
+       DEBUGFS_FWSTATS_ADD(pwr, missing_bcns);
+       DEBUGFS_FWSTATS_ADD(pwr, wake_on_host);
+       DEBUGFS_FWSTATS_ADD(pwr, wake_on_timer_exp);
+       DEBUGFS_FWSTATS_ADD(pwr, tx_with_ps);
+       DEBUGFS_FWSTATS_ADD(pwr, tx_without_ps);
+       DEBUGFS_FWSTATS_ADD(pwr, rcvd_beacons);
+       DEBUGFS_FWSTATS_ADD(pwr, power_save_off);
+       DEBUGFS_FWSTATS_ADD(pwr, enable_ps);
+       DEBUGFS_FWSTATS_ADD(pwr, disable_ps);
+       DEBUGFS_FWSTATS_ADD(pwr, fix_tsf_ps);
+       /* skipping cont_miss_bcns_spread for now */
+       DEBUGFS_FWSTATS_ADD(pwr, rcvd_awake_beacons);
+
+       DEBUGFS_FWSTATS_ADD(mic, rx_pkts);
+       DEBUGFS_FWSTATS_ADD(mic, calc_failure);
+
+       DEBUGFS_FWSTATS_ADD(aes, encrypt_fail);
+       DEBUGFS_FWSTATS_ADD(aes, decrypt_fail);
+       DEBUGFS_FWSTATS_ADD(aes, encrypt_packets);
+       DEBUGFS_FWSTATS_ADD(aes, decrypt_packets);
+       DEBUGFS_FWSTATS_ADD(aes, encrypt_interrupt);
+       DEBUGFS_FWSTATS_ADD(aes, decrypt_interrupt);
+
+       DEBUGFS_FWSTATS_ADD(event, heart_beat);
+       DEBUGFS_FWSTATS_ADD(event, calibration);
+       DEBUGFS_FWSTATS_ADD(event, rx_mismatch);
+       DEBUGFS_FWSTATS_ADD(event, rx_mem_empty);
+       DEBUGFS_FWSTATS_ADD(event, rx_pool);
+       DEBUGFS_FWSTATS_ADD(event, oom_late);
+       DEBUGFS_FWSTATS_ADD(event, phy_transmit_error);
+       DEBUGFS_FWSTATS_ADD(event, tx_stuck);
+
+       DEBUGFS_FWSTATS_ADD(ps, pspoll_timeouts);
+       DEBUGFS_FWSTATS_ADD(ps, upsd_timeouts);
+       DEBUGFS_FWSTATS_ADD(ps, upsd_max_sptime);
+       DEBUGFS_FWSTATS_ADD(ps, upsd_max_apturn);
+       DEBUGFS_FWSTATS_ADD(ps, pspoll_max_apturn);
+       DEBUGFS_FWSTATS_ADD(ps, pspoll_utilization);
+       DEBUGFS_FWSTATS_ADD(ps, upsd_utilization);
+
+       DEBUGFS_FWSTATS_ADD(rxpipe, rx_prep_beacon_drop);
+       DEBUGFS_FWSTATS_ADD(rxpipe, descr_host_int_trig_rx_data);
+       DEBUGFS_FWSTATS_ADD(rxpipe, beacon_buffer_thres_host_int_trig_rx_data);
+       DEBUGFS_FWSTATS_ADD(rxpipe, missed_beacon_host_int_trig_rx_data);
+       DEBUGFS_FWSTATS_ADD(rxpipe, tx_xfr_host_int_trig_rx_data);
+
+       DEBUGFS_ADD(tx_queue_len, wl->debugfs.rootdir);
+       DEBUGFS_ADD(tx_queue_status, wl->debugfs.rootdir);
+       DEBUGFS_ADD(retry_count, wl->debugfs.rootdir);
+       DEBUGFS_ADD(excessive_retries, wl->debugfs.rootdir);
+
+out:
+       if (ret < 0)
+               wl1251_debugfs_delete_files(wl);
+
+       return ret;
+}
+
+void wl1251_debugfs_reset(struct wl1251 *wl)
+{
+       if (wl->stats.fw_stats != NULL)
+               memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats));
+       wl->stats.retry_count = 0;
+       wl->stats.excessive_retries = 0;
+}
+
+int wl1251_debugfs_init(struct wl1251 *wl)
+{
+       int ret;
+
+       wl->debugfs.rootdir = debugfs_create_dir(KBUILD_MODNAME, NULL);
+
+       if (IS_ERR(wl->debugfs.rootdir)) {
+               ret = PTR_ERR(wl->debugfs.rootdir);
+               wl->debugfs.rootdir = NULL;
+               goto err;
+       }
+
+       wl->debugfs.fw_statistics = debugfs_create_dir("fw-statistics",
+                                                      wl->debugfs.rootdir);
+
+       if (IS_ERR(wl->debugfs.fw_statistics)) {
+               ret = PTR_ERR(wl->debugfs.fw_statistics);
+               wl->debugfs.fw_statistics = NULL;
+               goto err_root;
+       }
+
+       wl->stats.fw_stats = kzalloc(sizeof(*wl->stats.fw_stats),
+                                     GFP_KERNEL);
+
+       if (!wl->stats.fw_stats) {
+               ret = -ENOMEM;
+               goto err_fw;
+       }
+
+       wl->stats.fw_stats_update = jiffies;
+
+       ret = wl1251_debugfs_add_files(wl);
+
+       if (ret < 0)
+               goto err_file;
+
+       return 0;
+
+err_file:
+       kfree(wl->stats.fw_stats);
+       wl->stats.fw_stats = NULL;
+
+err_fw:
+       debugfs_remove(wl->debugfs.fw_statistics);
+       wl->debugfs.fw_statistics = NULL;
+
+err_root:
+       debugfs_remove(wl->debugfs.rootdir);
+       wl->debugfs.rootdir = NULL;
+
+err:
+       return ret;
+}
+
+void wl1251_debugfs_exit(struct wl1251 *wl)
+{
+       wl1251_debugfs_delete_files(wl);
+
+       kfree(wl->stats.fw_stats);
+       wl->stats.fw_stats = NULL;
+
+       debugfs_remove(wl->debugfs.fw_statistics);
+       wl->debugfs.fw_statistics = NULL;
+
+       debugfs_remove(wl->debugfs.rootdir);
+       wl->debugfs.rootdir = NULL;
+
+}
diff --git a/drivers/net/wireless/wl1251/debugfs.h b/drivers/net/wireless/wl1251/debugfs.h
new file mode 100644 (file)
index 0000000..b3417c0
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * This file is part of wl1251
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 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 St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef WL1251_DEBUGFS_H
+#define WL1251_DEBUGFS_H
+
+#include "wl1251.h"
+
+int wl1251_debugfs_init(struct wl1251 *wl);
+void wl1251_debugfs_exit(struct wl1251 *wl);
+void wl1251_debugfs_reset(struct wl1251 *wl);
+
+#endif /* WL1251_DEBUGFS_H */
diff --git a/drivers/net/wireless/wl1251/event.c b/drivers/net/wireless/wl1251/event.c
new file mode 100644 (file)
index 0000000..712372e
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ * This file is part of wl1251
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 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 St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include "wl1251.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)
+{
+       wl1251_debug(DEBUG_EVENT, "status: 0x%x, channels: %d",
+                    mbox->scheduled_scan_status,
+                    mbox->scheduled_scan_channels);
+
+       if (wl->scanning) {
+               ieee80211_scan_completed(wl->hw, false);
+               wl1251_debug(DEBUG_MAC80211, "mac80211 hw scan completed");
+               wl->scanning = false;
+       }
+
+       return 0;
+}
+
+static void wl1251_event_mbox_dump(struct event_mailbox *mbox)
+{
+       wl1251_debug(DEBUG_EVENT, "MBOX DUMP:");
+       wl1251_debug(DEBUG_EVENT, "\tvector: 0x%x", mbox->events_vector);
+       wl1251_debug(DEBUG_EVENT, "\tmask: 0x%x", mbox->events_mask);
+}
+
+static int wl1251_event_process(struct wl1251 *wl, struct event_mailbox *mbox)
+{
+       int ret;
+       u32 vector;
+
+       wl1251_event_mbox_dump(mbox);
+
+       vector = mbox->events_vector & ~(mbox->events_mask);
+       wl1251_debug(DEBUG_EVENT, "vector: 0x%x", vector);
+
+       if (vector & SCAN_COMPLETE_EVENT_ID) {
+               ret = wl1251_event_scan_complete(wl, mbox);
+               if (ret < 0)
+                       return ret;
+       }
+
+       if (vector & BSS_LOSE_EVENT_ID) {
+               wl1251_debug(DEBUG_EVENT, "BSS_LOSE_EVENT");
+
+               if (wl->psm_requested && wl->psm) {
+                       ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE);
+                       if (ret < 0)
+                               return ret;
+               }
+       }
+
+       if (vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID && wl->psm) {
+               wl1251_debug(DEBUG_EVENT, "SYNCHRONIZATION_TIMEOUT_EVENT");
+
+               /* indicate to the stack, that beacons have been lost */
+               ieee80211_beacon_loss(wl->vif);
+       }
+
+       if (vector & REGAINED_BSS_EVENT_ID) {
+               if (wl->psm_requested) {
+                       ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
+                       if (ret < 0)
+                               return ret;
+               }
+       }
+
+       return 0;
+}
+
+/*
+ * Poll the mailbox event field until any of the bits in the mask is set or a
+ * timeout occurs (WL1251_EVENT_TIMEOUT in msecs)
+ */
+int wl1251_event_wait(struct wl1251 *wl, u32 mask, int timeout_ms)
+{
+       u32 events_vector, event;
+       unsigned long timeout;
+
+       timeout = jiffies + msecs_to_jiffies(timeout_ms);
+
+       do {
+               if (time_after(jiffies, timeout))
+                       return -ETIMEDOUT;
+
+               msleep(1);
+
+               /* read from both event fields */
+               wl1251_mem_read(wl, wl->mbox_ptr[0], &events_vector,
+                               sizeof(events_vector));
+               event = events_vector & mask;
+               wl1251_mem_read(wl, wl->mbox_ptr[1], &events_vector,
+                               sizeof(events_vector));
+               event |= events_vector & mask;
+       } while (!event);
+
+       return 0;
+}
+
+int wl1251_event_unmask(struct wl1251 *wl)
+{
+       int ret;
+
+       ret = wl1251_acx_event_mbox_mask(wl, ~(wl->event_mask));
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+void wl1251_event_mbox_config(struct wl1251 *wl)
+{
+       wl->mbox_ptr[0] = wl1251_reg_read32(wl, REG_EVENT_MAILBOX_PTR);
+       wl->mbox_ptr[1] = wl->mbox_ptr[0] + sizeof(struct event_mailbox);
+
+       wl1251_debug(DEBUG_EVENT, "MBOX ptrs: 0x%x 0x%x",
+                    wl->mbox_ptr[0], wl->mbox_ptr[1]);
+}
+
+int wl1251_event_handle(struct wl1251 *wl, u8 mbox_num)
+{
+       struct event_mailbox mbox;
+       int ret;
+
+       wl1251_debug(DEBUG_EVENT, "EVENT on mbox %d", mbox_num);
+
+       if (mbox_num > 1)
+               return -EINVAL;
+
+       /* first we read the mbox descriptor */
+       wl1251_mem_read(wl, wl->mbox_ptr[mbox_num], &mbox,
+                           sizeof(struct event_mailbox));
+
+       /* process the descriptor */
+       ret = wl1251_event_process(wl, &mbox);
+       if (ret < 0)
+               return ret;
+
+       /* then we let the firmware know it can go on...*/
+       wl1251_reg_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_EVENT_ACK);
+
+       return 0;
+}
diff --git a/drivers/net/wireless/wl1251/event.h b/drivers/net/wireless/wl1251/event.h
new file mode 100644 (file)
index 0000000..30eb5d1
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * This file is part of wl1251
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 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 St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __WL1251_EVENT_H__
+#define __WL1251_EVENT_H__
+
+/*
+ * Mbox events
+ *
+ * The event mechanism is based on a pair of event buffers (buffers A and
+ * B) at fixed locations in the target's memory. The host processes one
+ * buffer while the other buffer continues to collect events. If the host
+ * is not processing events, an interrupt is issued to signal that a buffer
+ * is ready. Once the host is done with processing events from one buffer,
+ * it signals the target (with an ACK interrupt) that the event buffer is
+ * free.
+ */
+
+enum {
+       RESERVED1_EVENT_ID                       = BIT(0),
+       RESERVED2_EVENT_ID                       = BIT(1),
+       MEASUREMENT_START_EVENT_ID               = BIT(2),
+       SCAN_COMPLETE_EVENT_ID                   = BIT(3),
+       CALIBRATION_COMPLETE_EVENT_ID            = BIT(4),
+       ROAMING_TRIGGER_LOW_RSSI_EVENT_ID        = BIT(5),
+       PS_REPORT_EVENT_ID                       = BIT(6),
+       SYNCHRONIZATION_TIMEOUT_EVENT_ID         = BIT(7),
+       HEALTH_REPORT_EVENT_ID                   = BIT(8),
+       ACI_DETECTION_EVENT_ID                   = BIT(9),
+       DEBUG_REPORT_EVENT_ID                    = BIT(10),
+       MAC_STATUS_EVENT_ID                      = BIT(11),
+       DISCONNECT_EVENT_COMPLETE_ID             = BIT(12),
+       JOIN_EVENT_COMPLETE_ID                   = BIT(13),
+       CHANNEL_SWITCH_COMPLETE_EVENT_ID         = BIT(14),
+       BSS_LOSE_EVENT_ID                        = BIT(15),
+       ROAMING_TRIGGER_MAX_TX_RETRY_EVENT_ID    = BIT(16),
+       MEASUREMENT_COMPLETE_EVENT_ID            = BIT(17),
+       AP_DISCOVERY_COMPLETE_EVENT_ID           = BIT(18),
+       SCHEDULED_SCAN_COMPLETE_EVENT_ID         = BIT(19),
+       PSPOLL_DELIVERY_FAILURE_EVENT_ID         = BIT(20),
+       RESET_BSS_EVENT_ID                       = BIT(21),
+       REGAINED_BSS_EVENT_ID                    = BIT(22),
+       ROAMING_TRIGGER_REGAINED_RSSI_EVENT_ID   = BIT(23),
+       ROAMING_TRIGGER_LOW_SNR_EVENT_ID         = BIT(24),
+       ROAMING_TRIGGER_REGAINED_SNR_EVENT_ID    = BIT(25),
+
+       DBG_EVENT_ID                             = BIT(26),
+       BT_PTA_SENSE_EVENT_ID                    = BIT(27),
+       BT_PTA_PREDICTION_EVENT_ID               = BIT(28),
+       BT_PTA_AVALANCHE_EVENT_ID                = BIT(29),
+
+       PLT_RX_CALIBRATION_COMPLETE_EVENT_ID     = BIT(30),
+
+       EVENT_MBOX_ALL_EVENT_ID                  = 0x7fffffff,
+};
+
+struct event_debug_report {
+       u8 debug_event_id;
+       u8 num_params;
+       u16 pad;
+       u32 report_1;
+       u32 report_2;
+       u32 report_3;
+} __packed;
+
+struct event_mailbox {
+       u32 events_vector;
+       u32 events_mask;
+       u32 reserved_1;
+       u32 reserved_2;
+
+       char average_rssi_level;
+       u8 ps_status;
+       u8 channel_switch_status;
+       u8 scheduled_scan_status;
+
+       /* Channels scanned by the scheduled scan */
+       u16 scheduled_scan_channels;
+
+       /* If bit 0 is set -> target's fatal error */
+       u16 health_report;
+       u16 bad_fft_counter;
+       u8 bt_pta_sense_info;
+       u8 bt_pta_protective_info;
+       u32 reserved;
+       u32 debug_report[2];
+
+       /* Number of FCS errors since last event */
+       u32 fcs_err_counter;
+
+       struct event_debug_report report;
+       u8 average_snr_level;
+       u8 padding[19];
+} __packed;
+
+int wl1251_event_unmask(struct wl1251 *wl);
+void wl1251_event_mbox_config(struct wl1251 *wl);
+int wl1251_event_handle(struct wl1251 *wl, u8 mbox);
+int wl1251_event_wait(struct wl1251 *wl, u32 mask, int timeout_ms);
+
+#endif
diff --git a/drivers/net/wireless/wl1251/init.c b/drivers/net/wireless/wl1251/init.c
new file mode 100644 (file)
index 0000000..89b43d3
--- /dev/null
@@ -0,0 +1,423 @@
+/*
+ * This file is part of wl1251
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 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 St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#include "init.h"
+#include "wl12xx_80211.h"
+#include "acx.h"
+#include "cmd.h"
+#include "reg.h"
+
+int wl1251_hw_init_hwenc_config(struct wl1251 *wl)
+{
+       int ret;
+
+       ret = wl1251_acx_feature_cfg(wl);
+       if (ret < 0) {
+               wl1251_warning("couldn't set feature config");
+               return ret;
+       }
+
+       ret = wl1251_acx_default_key(wl, wl->default_key);
+       if (ret < 0) {
+               wl1251_warning("couldn't set default key");
+               return ret;
+       }
+
+       return 0;
+}
+
+int wl1251_hw_init_templates_config(struct wl1251 *wl)
+{
+       int ret;
+       u8 partial_vbm[PARTIAL_VBM_MAX];
+
+       /* send empty templates for fw memory reservation */
+       ret = wl1251_cmd_template_set(wl, CMD_PROBE_REQ, NULL,
+                                     sizeof(struct wl12xx_probe_req_template));
+       if (ret < 0)
+               return ret;
+
+       ret = wl1251_cmd_template_set(wl, CMD_NULL_DATA, NULL,
+                                     sizeof(struct wl12xx_null_data_template));
+       if (ret < 0)
+               return ret;
+
+       ret = wl1251_cmd_template_set(wl, CMD_PS_POLL, NULL,
+                                     sizeof(struct wl12xx_ps_poll_template));
+       if (ret < 0)
+               return ret;
+
+       ret = wl1251_cmd_template_set(wl, CMD_QOS_NULL_DATA, NULL,
+                                     sizeof
+                                     (struct wl12xx_qos_null_data_template));
+       if (ret < 0)
+               return ret;
+
+       ret = wl1251_cmd_template_set(wl, CMD_PROBE_RESP, NULL,
+                                     sizeof
+                                     (struct wl12xx_probe_resp_template));
+       if (ret < 0)
+               return ret;
+
+       ret = wl1251_cmd_template_set(wl, CMD_BEACON, NULL,
+                                     sizeof
+                                     (struct wl12xx_beacon_template));
+       if (ret < 0)
+               return ret;
+
+       /* tim templates, first reserve space then allocate an empty one */
+       memset(partial_vbm, 0, PARTIAL_VBM_MAX);
+       ret = wl1251_cmd_vbm(wl, TIM_ELE_ID, partial_vbm, PARTIAL_VBM_MAX, 0);
+       if (ret < 0)
+               return ret;
+
+       ret = wl1251_cmd_vbm(wl, TIM_ELE_ID, partial_vbm, 1, 0);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+int wl1251_hw_init_rx_config(struct wl1251 *wl, u32 config, u32 filter)
+{
+       int ret;
+
+       ret = wl1251_acx_rx_msdu_life_time(wl, RX_MSDU_LIFETIME_DEF);
+       if (ret < 0)
+               return ret;
+
+       ret = wl1251_acx_rx_config(wl, config, filter);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+int wl1251_hw_init_phy_config(struct wl1251 *wl)
+{
+       int ret;
+
+       ret = wl1251_acx_pd_threshold(wl);
+       if (ret < 0)
+               return ret;
+
+       ret = wl1251_acx_slot(wl, DEFAULT_SLOT_TIME);
+       if (ret < 0)
+               return ret;
+
+       ret = wl1251_acx_group_address_tbl(wl);
+       if (ret < 0)
+               return ret;
+
+       ret = wl1251_acx_service_period_timeout(wl);
+       if (ret < 0)
+               return ret;
+
+       ret = wl1251_acx_rts_threshold(wl, RTS_THRESHOLD_DEF);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+int wl1251_hw_init_beacon_filter(struct wl1251 *wl)
+{
+       int ret;
+
+       /* disable beacon filtering at this stage */
+       ret = wl1251_acx_beacon_filter_opt(wl, false);
+       if (ret < 0)
+               return ret;
+
+       ret = wl1251_acx_beacon_filter_table(wl);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+int wl1251_hw_init_pta(struct wl1251 *wl)
+{
+       int ret;
+
+       ret = wl1251_acx_sg_enable(wl);
+       if (ret < 0)
+               return ret;
+
+       ret = wl1251_acx_sg_cfg(wl);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+int wl1251_hw_init_energy_detection(struct wl1251 *wl)
+{
+       int ret;
+
+       ret = wl1251_acx_cca_threshold(wl);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+int wl1251_hw_init_beacon_broadcast(struct wl1251 *wl)
+{
+       int ret;
+
+       ret = wl1251_acx_bcn_dtim_options(wl);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+int wl1251_hw_init_power_auth(struct wl1251 *wl)
+{
+       return wl1251_acx_sleep_auth(wl, WL1251_PSM_CAM);
+}
+
+int wl1251_hw_init_mem_config(struct wl1251 *wl)
+{
+       int ret;
+
+       ret = wl1251_acx_mem_cfg(wl);
+       if (ret < 0)
+               return ret;
+
+       wl->target_mem_map = kzalloc(sizeof(struct wl1251_acx_mem_map),
+                                         GFP_KERNEL);
+       if (!wl->target_mem_map) {
+               wl1251_error("couldn't allocate target memory map");
+               return -ENOMEM;
+       }
+
+       /* we now ask for the firmware built memory map */
+       ret = wl1251_acx_mem_map(wl, wl->target_mem_map,
+                                sizeof(struct wl1251_acx_mem_map));
+       if (ret < 0) {
+               wl1251_error("couldn't retrieve firmware memory map");
+               kfree(wl->target_mem_map);
+               wl->target_mem_map = NULL;
+               return ret;
+       }
+
+       return 0;
+}
+
+static int wl1251_hw_init_txq_fill(u8 qid,
+                                  struct acx_tx_queue_qos_config *config,
+                                  u32 num_blocks)
+{
+       config->qid = qid;
+
+       switch (qid) {
+       case QOS_AC_BE:
+               config->high_threshold =
+                       (QOS_TX_HIGH_BE_DEF * num_blocks) / 100;
+               config->low_threshold =
+                       (QOS_TX_LOW_BE_DEF * num_blocks) / 100;
+               break;
+       case QOS_AC_BK:
+               config->high_threshold =
+                       (QOS_TX_HIGH_BK_DEF * num_blocks) / 100;
+               config->low_threshold =
+                       (QOS_TX_LOW_BK_DEF * num_blocks) / 100;
+               break;
+       case QOS_AC_VI:
+               config->high_threshold =
+                       (QOS_TX_HIGH_VI_DEF * num_blocks) / 100;
+               config->low_threshold =
+                       (QOS_TX_LOW_VI_DEF * num_blocks) / 100;
+               break;
+       case QOS_AC_VO:
+               config->high_threshold =
+                       (QOS_TX_HIGH_VO_DEF * num_blocks) / 100;
+               config->low_threshold =
+                       (QOS_TX_LOW_VO_DEF * num_blocks) / 100;
+               break;
+       default:
+               wl1251_error("Invalid TX queue id: %d", qid);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int wl1251_hw_init_tx_queue_config(struct wl1251 *wl)
+{
+       struct acx_tx_queue_qos_config *config;
+       struct wl1251_acx_mem_map *wl_mem_map = wl->target_mem_map;
+       int ret, i;
+
+       wl1251_debug(DEBUG_ACX, "acx tx queue config");
+
+       config = kzalloc(sizeof(*config), GFP_KERNEL);
+       if (!config) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       for (i = 0; i < MAX_NUM_OF_AC; i++) {
+               ret = wl1251_hw_init_txq_fill(i, config,
+                                             wl_mem_map->num_tx_mem_blocks);
+               if (ret < 0)
+                       goto out;
+
+               ret = wl1251_cmd_configure(wl, ACX_TX_QUEUE_CFG,
+                                          config, sizeof(*config));
+               if (ret < 0)
+                       goto out;
+       }
+
+       wl1251_acx_ac_cfg(wl, AC_BE, CWMIN_BE, CWMAX_BE, AIFS_DIFS, TXOP_BE);
+       wl1251_acx_ac_cfg(wl, AC_BK, CWMIN_BK, CWMAX_BK, AIFS_DIFS, TXOP_BK);
+       wl1251_acx_ac_cfg(wl, AC_VI, CWMIN_VI, CWMAX_VI, AIFS_DIFS, TXOP_VI);
+       wl1251_acx_ac_cfg(wl, AC_VO, CWMIN_VO, CWMAX_VO, AIFS_DIFS, TXOP_VO);
+
+out:
+       kfree(config);
+       return ret;
+}
+
+static int wl1251_hw_init_data_path_config(struct wl1251 *wl)
+{
+       int ret;
+
+       /* asking for the data path parameters */
+       wl->data_path = kzalloc(sizeof(struct acx_data_path_params_resp),
+                               GFP_KERNEL);
+       if (!wl->data_path) {
+               wl1251_error("Couldnt allocate data path parameters");
+               return -ENOMEM;
+       }
+
+       ret = wl1251_acx_data_path_params(wl, wl->data_path);
+       if (ret < 0) {
+               kfree(wl->data_path);
+               wl->data_path = NULL;
+               return ret;
+       }
+
+       return 0;
+}
+
+
+int wl1251_hw_init(struct wl1251 *wl)
+{
+       struct wl1251_acx_mem_map *wl_mem_map;
+       int ret;
+
+       ret = wl1251_hw_init_hwenc_config(wl);
+       if (ret < 0)
+               return ret;
+
+       /* Template settings */
+       ret = wl1251_hw_init_templates_config(wl);
+       if (ret < 0)
+               return ret;
+
+       /* Default memory configuration */
+       ret = wl1251_hw_init_mem_config(wl);
+       if (ret < 0)
+               return ret;
+
+       /* Default data path configuration  */
+       ret = wl1251_hw_init_data_path_config(wl);
+       if (ret < 0)
+               goto out_free_memmap;
+
+       /* RX config */
+       ret = wl1251_hw_init_rx_config(wl,
+                                      RX_CFG_PROMISCUOUS | RX_CFG_TSF,
+                                      RX_FILTER_OPTION_DEF);
+       /* RX_CONFIG_OPTION_ANY_DST_ANY_BSS,
+          RX_FILTER_OPTION_FILTER_ALL); */
+       if (ret < 0)
+               goto out_free_data_path;
+
+       /* TX queues config */
+       ret = wl1251_hw_init_tx_queue_config(wl);
+       if (ret < 0)
+               goto out_free_data_path;
+
+       /* PHY layer config */
+       ret = wl1251_hw_init_phy_config(wl);
+       if (ret < 0)
+               goto out_free_data_path;
+
+       /* Initialize connection monitoring thresholds */
+       ret = wl1251_acx_conn_monit_params(wl);
+       if (ret < 0)
+               goto out_free_data_path;
+
+       /* Beacon filtering */
+       ret = wl1251_hw_init_beacon_filter(wl);
+       if (ret < 0)
+               goto out_free_data_path;
+
+       /* Bluetooth WLAN coexistence */
+       ret = wl1251_hw_init_pta(wl);
+       if (ret < 0)
+               goto out_free_data_path;
+
+       /* Energy detection */
+       ret = wl1251_hw_init_energy_detection(wl);
+       if (ret < 0)
+               goto out_free_data_path;
+
+       /* Beacons and boradcast settings */
+       ret = wl1251_hw_init_beacon_broadcast(wl);
+       if (ret < 0)
+               goto out_free_data_path;
+
+       /* Enable data path */
+       ret = wl1251_cmd_data_path(wl, wl->channel, 1);
+       if (ret < 0)
+               goto out_free_data_path;
+
+       /* Default power state */
+       ret = wl1251_hw_init_power_auth(wl);
+       if (ret < 0)
+               goto out_free_data_path;
+
+       wl_mem_map = wl->target_mem_map;
+       wl1251_info("%d tx blocks at 0x%x, %d rx blocks at 0x%x",
+                   wl_mem_map->num_tx_mem_blocks,
+                   wl->data_path->tx_control_addr,
+                   wl_mem_map->num_rx_mem_blocks,
+                   wl->data_path->rx_control_addr);
+
+       return 0;
+
+ out_free_data_path:
+       kfree(wl->data_path);
+
+ out_free_memmap:
+       kfree(wl->target_mem_map);
+
+       return ret;
+}
diff --git a/drivers/net/wireless/wl1251/init.h b/drivers/net/wireless/wl1251/init.h
new file mode 100644 (file)
index 0000000..543f175
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * This file is part of wl1251
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 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 St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __WL1251_INIT_H__
+#define __WL1251_INIT_H__
+
+#include "wl1251.h"
+
+enum {
+       /* best effort/legacy */
+       AC_BE = 0,
+
+       /* background */
+       AC_BK = 1,
+
+       /* video */
+       AC_VI = 2,
+
+       /* voice */
+       AC_VO = 3,
+
+       /* broadcast dummy access category */
+       AC_BCAST = 4,
+
+       NUM_ACCESS_CATEGORIES = 4
+};
+
+/* following are defult values for the IE fields*/
+#define CWMIN_BK  15
+#define CWMIN_BE  15
+#define CWMIN_VI  7
+#define CWMIN_VO  3
+#define CWMAX_BK  1023
+#define CWMAX_BE  63
+#define CWMAX_VI  15
+#define CWMAX_VO  7
+
+/* slot number setting to start transmission at PIFS interval */
+#define AIFS_PIFS 1
+
+/*
+ * slot number setting to start transmission at DIFS interval - normal DCF
+ * access
+ */
+#define AIFS_DIFS 2
+
+#define AIFSN_BK  7
+#define AIFSN_BE  3
+#define AIFSN_VI  AIFS_PIFS
+#define AIFSN_VO  AIFS_PIFS
+#define TXOP_BK   0
+#define TXOP_BE   0
+#define TXOP_VI   3008
+#define TXOP_VO   1504
+
+int wl1251_hw_init_hwenc_config(struct wl1251 *wl);
+int wl1251_hw_init_templates_config(struct wl1251 *wl);
+int wl1251_hw_init_rx_config(struct wl1251 *wl, u32 config, u32 filter);
+int wl1251_hw_init_phy_config(struct wl1251 *wl);
+int wl1251_hw_init_beacon_filter(struct wl1251 *wl);
+int wl1251_hw_init_pta(struct wl1251 *wl);
+int wl1251_hw_init_energy_detection(struct wl1251 *wl);
+int wl1251_hw_init_beacon_broadcast(struct wl1251 *wl);
+int wl1251_hw_init_power_auth(struct wl1251 *wl);
+int wl1251_hw_init_mem_config(struct wl1251 *wl);
+int wl1251_hw_init(struct wl1251 *wl);
+
+#endif
diff --git a/drivers/net/wireless/wl1251/io.c b/drivers/net/wireless/wl1251/io.c
new file mode 100644 (file)
index 0000000..cdcadbf
--- /dev/null
@@ -0,0 +1,194 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 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 St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include "wl1251.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] = {
+       [ACX_REG_INTERRUPT_TRIG]     = (REGISTERS_BASE + 0x0474),
+       [ACX_REG_INTERRUPT_TRIG_H]   = (REGISTERS_BASE + 0x0478),
+       [ACX_REG_INTERRUPT_MASK]     = (REGISTERS_BASE + 0x0494),
+       [ACX_REG_HINT_MASK_SET]      = (REGISTERS_BASE + 0x0498),
+       [ACX_REG_HINT_MASK_CLR]      = (REGISTERS_BASE + 0x049C),
+       [ACX_REG_INTERRUPT_NO_CLEAR] = (REGISTERS_BASE + 0x04B0),
+       [ACX_REG_INTERRUPT_CLEAR]    = (REGISTERS_BASE + 0x04A4),
+       [ACX_REG_INTERRUPT_ACK]      = (REGISTERS_BASE + 0x04A8),
+       [ACX_REG_SLV_SOFT_RESET]     = (REGISTERS_BASE + 0x0000),
+       [ACX_REG_EE_START]           = (REGISTERS_BASE + 0x080C),
+       [ACX_REG_ECPU_CONTROL]       = (REGISTERS_BASE + 0x0804)
+};
+
+static int wl1251_translate_reg_addr(struct wl1251 *wl, int addr)
+{
+       /* If the address is lower than REGISTERS_BASE, it means that this is
+        * a chip-specific register address, so look it up in the registers
+        * table */
+       if (addr < REGISTERS_BASE) {
+               /* Make sure we don't go over the table */
+               if (addr >= ACX_REG_TABLE_LEN) {
+                       wl1251_error("address out of range (%d)", addr);
+                       return -EINVAL;
+               }
+               addr = wl1251_io_reg_table[addr];
+       }
+
+       return addr - wl->physical_reg_addr + wl->virtual_reg_addr;
+}
+
+static int wl1251_translate_mem_addr(struct wl1251 *wl, int addr)
+{
+       return addr - wl->physical_mem_addr + wl->virtual_mem_addr;
+}
+
+void wl1251_mem_read(struct wl1251 *wl, int addr, void *buf, size_t len)
+{
+       int physical;
+
+       physical = wl1251_translate_mem_addr(wl, addr);
+
+       wl->if_ops->read(wl, physical, buf, len);
+}
+
+void wl1251_mem_write(struct wl1251 *wl, int addr, void *buf, size_t len)
+{
+       int physical;
+
+       physical = wl1251_translate_mem_addr(wl, addr);
+
+       wl->if_ops->write(wl, physical, buf, len);
+}
+
+u32 wl1251_mem_read32(struct wl1251 *wl, int addr)
+{
+       return wl1251_read32(wl, wl1251_translate_mem_addr(wl, addr));
+}
+
+void wl1251_mem_write32(struct wl1251 *wl, int addr, u32 val)
+{
+       wl1251_write32(wl, wl1251_translate_mem_addr(wl, addr), val);
+}
+
+u32 wl1251_reg_read32(struct wl1251 *wl, int addr)
+{
+       return wl1251_read32(wl, wl1251_translate_reg_addr(wl, addr));
+}
+
+void wl1251_reg_write32(struct wl1251 *wl, int addr, u32 val)
+{
+       wl1251_write32(wl, wl1251_translate_reg_addr(wl, addr), val);
+}
+
+/* Set the partitions to access the chip addresses.
+ *
+ * There are two VIRTUAL partitions (the memory partition and the
+ * registers partition), which are mapped to two different areas of the
+ * PHYSICAL (hardware) memory.  This function also makes other checks to
+ * ensure that the partitions are not overlapping.  In the diagram below, the
+ * memory partition comes before the register partition, but the opposite is
+ * also supported.
+ *
+ *                               PHYSICAL address
+ *                                     space
+ *
+ *                                    |    |
+ *                                 ...+----+--> mem_start
+ *          VIRTUAL address     ...   |    |
+ *               space       ...      |    | [PART_0]
+ *                        ...         |    |
+ * 0x00000000 <--+----+...         ...+----+--> mem_start + mem_size
+ *               |    |         ...   |    |
+ *               |MEM |      ...      |    |
+ *               |    |   ...         |    |
+ *  part_size <--+----+...            |    | {unused area)
+ *               |    |   ...         |    |
+ *               |REG |      ...      |    |
+ *  part_size    |    |         ...   |    |
+ *      +     <--+----+...         ...+----+--> reg_start
+ *  reg_size              ...         |    |
+ *                           ...      |    | [PART_1]
+ *                              ...   |    |
+ *                                 ...+----+--> reg_start + reg_size
+ *                                    |    |
+ *
+ */
+void wl1251_set_partition(struct wl1251 *wl,
+                         u32 mem_start, u32 mem_size,
+                         u32 reg_start, u32 reg_size)
+{
+       struct wl1251_partition partition[2];
+
+       wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
+                    mem_start, mem_size);
+       wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
+                    reg_start, reg_size);
+
+       /* Make sure that the two partitions together don't exceed the
+        * address range */
+       if ((mem_size + reg_size) > HW_ACCESS_MEMORY_MAX_RANGE) {
+               wl1251_debug(DEBUG_SPI, "Total size exceeds maximum virtual"
+                            " address range.  Truncating partition[0].");
+               mem_size = HW_ACCESS_MEMORY_MAX_RANGE - reg_size;
+               wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
+                            mem_start, mem_size);
+               wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
+                            reg_start, reg_size);
+       }
+
+       if ((mem_start < reg_start) &&
+           ((mem_start + mem_size) > reg_start)) {
+               /* Guarantee that the memory partition doesn't overlap the
+                * registers partition */
+               wl1251_debug(DEBUG_SPI, "End of partition[0] is "
+                            "overlapping partition[1].  Adjusted.");
+               mem_size = reg_start - mem_start;
+               wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
+                            mem_start, mem_size);
+               wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
+                            reg_start, reg_size);
+       } else if ((reg_start < mem_start) &&
+                  ((reg_start + reg_size) > mem_start)) {
+               /* Guarantee that the register partition doesn't overlap the
+                * memory partition */
+               wl1251_debug(DEBUG_SPI, "End of partition[1] is"
+                            " overlapping partition[0].  Adjusted.");
+               reg_size = mem_start - reg_start;
+               wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
+                            mem_start, mem_size);
+               wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
+                            reg_start, reg_size);
+       }
+
+       partition[0].start = mem_start;
+       partition[0].size  = mem_size;
+       partition[1].start = reg_start;
+       partition[1].size  = reg_size;
+
+       wl->physical_mem_addr = mem_start;
+       wl->physical_reg_addr = reg_start;
+
+       wl->virtual_mem_addr = 0;
+       wl->virtual_reg_addr = mem_size;
+
+       wl->if_ops->write(wl, HW_ACCESS_PART0_SIZE_ADDR, partition,
+               sizeof(partition));
+}
diff --git a/drivers/net/wireless/wl1251/io.h b/drivers/net/wireless/wl1251/io.h
new file mode 100644 (file)
index 0000000..c545e9d
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 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 St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+#ifndef __WL1251_IO_H__
+#define __WL1251_IO_H__
+
+#include "wl1251.h"
+
+#define HW_ACCESS_MEMORY_MAX_RANGE             0x1FFC0
+
+#define HW_ACCESS_PART0_SIZE_ADDR           0x1FFC0
+#define HW_ACCESS_PART0_START_ADDR          0x1FFC4
+#define HW_ACCESS_PART1_SIZE_ADDR           0x1FFC8
+#define HW_ACCESS_PART1_START_ADDR          0x1FFCC
+
+#define HW_ACCESS_REGISTER_SIZE             4
+
+#define HW_ACCESS_PRAM_MAX_RANGE               0x3c000
+
+static inline u32 wl1251_read32(struct wl1251 *wl, int addr)
+{
+       u32 response;
+
+       wl->if_ops->read(wl, addr, &response, sizeof(u32));
+
+       return response;
+}
+
+static inline void wl1251_write32(struct wl1251 *wl, int addr, u32 val)
+{
+       wl->if_ops->write(wl, addr, &val, sizeof(u32));
+}
+
+static inline u32 wl1251_read_elp(struct wl1251 *wl, int addr)
+{
+       u32 response;
+
+       if (wl->if_ops->read_elp)
+               wl->if_ops->read_elp(wl, addr, &response);
+       else
+               wl->if_ops->read(wl, addr, &response, sizeof(u32));
+
+       return response;
+}
+
+static inline void wl1251_write_elp(struct wl1251 *wl, int addr, u32 val)
+{
+       if (wl->if_ops->write_elp)
+               wl->if_ops->write_elp(wl, addr, val);
+       else
+               wl->if_ops->write(wl, addr, &val, sizeof(u32));
+}
+
+/* Memory target IO, address is translated to partition 0 */
+void wl1251_mem_read(struct wl1251 *wl, int addr, void *buf, size_t len);
+void wl1251_mem_write(struct wl1251 *wl, int addr, void *buf, size_t len);
+u32 wl1251_mem_read32(struct wl1251 *wl, int addr);
+void wl1251_mem_write32(struct wl1251 *wl, int addr, u32 val);
+/* Registers IO */
+u32 wl1251_reg_read32(struct wl1251 *wl, int addr);
+void wl1251_reg_write32(struct wl1251 *wl, int addr, u32 val);
+
+void wl1251_set_partition(struct wl1251 *wl,
+                         u32 part_start, u32 part_size,
+                         u32 reg_start,  u32 reg_size);
+
+#endif
diff --git a/drivers/net/wireless/wl1251/main.c b/drivers/net/wireless/wl1251/main.c
new file mode 100644 (file)
index 0000000..7a87625
--- /dev/null
@@ -0,0 +1,1435 @@
+/*
+ * This file is part of wl1251
+ *
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 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 St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/firmware.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/crc32.h>
+#include <linux/etherdevice.h>
+#include <linux/vmalloc.h>
+#include <linux/slab.h>
+
+#include "wl1251.h"
+#include "wl12xx_80211.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)
+{
+       wl->if_ops->enable_irq(wl);
+}
+
+void wl1251_disable_interrupts(struct wl1251 *wl)
+{
+       wl->if_ops->disable_irq(wl);
+}
+
+static void wl1251_power_off(struct wl1251 *wl)
+{
+       wl->set_power(false);
+}
+
+static void wl1251_power_on(struct wl1251 *wl)
+{
+       wl->set_power(true);
+}
+
+static int wl1251_fetch_firmware(struct wl1251 *wl)
+{
+       const struct firmware *fw;
+       struct device *dev = wiphy_dev(wl->hw->wiphy);
+       int ret;
+
+       ret = request_firmware(&fw, WL1251_FW_NAME, dev);
+
+       if (ret < 0) {
+               wl1251_error("could not get firmware: %d", ret);
+               return ret;
+       }
+
+       if (fw->size % 4) {
+               wl1251_error("firmware size is not multiple of 32 bits: %zu",
+                            fw->size);
+               ret = -EILSEQ;
+               goto out;
+       }
+
+       wl->fw_len = fw->size;
+       wl->fw = vmalloc(wl->fw_len);
+
+       if (!wl->fw) {
+               wl1251_error("could not allocate memory for the firmware");
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       memcpy(wl->fw, fw->data, wl->fw_len);
+
+       ret = 0;
+
+out:
+       release_firmware(fw);
+
+       return ret;
+}
+
+static int wl1251_fetch_nvs(struct wl1251 *wl)
+{
+       const struct firmware *fw;
+       struct device *dev = wiphy_dev(wl->hw->wiphy);
+       int ret;
+
+       ret = request_firmware(&fw, WL1251_NVS_NAME, dev);
+
+       if (ret < 0) {
+               wl1251_error("could not get nvs file: %d", ret);
+               return ret;
+       }
+
+       if (fw->size % 4) {
+               wl1251_error("nvs size is not multiple of 32 bits: %zu",
+                            fw->size);
+               ret = -EILSEQ;
+               goto out;
+       }
+
+       wl->nvs_len = fw->size;
+       wl->nvs = kmemdup(fw->data, wl->nvs_len, GFP_KERNEL);
+
+       if (!wl->nvs) {
+               wl1251_error("could not allocate memory for the nvs file");
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       ret = 0;
+
+out:
+       release_firmware(fw);
+
+       return ret;
+}
+
+static void wl1251_fw_wakeup(struct wl1251 *wl)
+{
+       u32 elp_reg;
+
+       elp_reg = ELPCTRL_WAKE_UP;
+       wl1251_write_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg);
+       elp_reg = wl1251_read_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR);
+
+       if (!(elp_reg & ELPCTRL_WLAN_READY))
+               wl1251_warning("WLAN not ready");
+}
+
+static int wl1251_chip_wakeup(struct wl1251 *wl)
+{
+       int ret = 0;
+
+       wl1251_power_on(wl);
+       msleep(WL1251_POWER_ON_SLEEP);
+       wl->if_ops->reset(wl);
+
+       /* We don't need a real memory partition here, because we only want
+        * to use the registers at this point. */
+       wl1251_set_partition(wl,
+                            0x00000000,
+                            0x00000000,
+                            REGISTERS_BASE,
+                            REGISTERS_DOWN_SIZE);
+
+       /* ELP module wake up */
+       wl1251_fw_wakeup(wl);
+
+       /* whal_FwCtrl_BootSm() */
+
+       /* 0. read chip id from CHIP_ID */
+       wl->chip_id = wl1251_reg_read32(wl, CHIP_ID_B);
+
+       /* 1. check if chip id is valid */
+
+       switch (wl->chip_id) {
+       case CHIP_ID_1251_PG12:
+               wl1251_debug(DEBUG_BOOT, "chip id 0x%x (1251 PG12)",
+                            wl->chip_id);
+               break;
+       case CHIP_ID_1251_PG11:
+               wl1251_debug(DEBUG_BOOT, "chip id 0x%x (1251 PG11)",
+                            wl->chip_id);
+               break;
+       case CHIP_ID_1251_PG10:
+       default:
+               wl1251_error("unsupported chip id: 0x%x", wl->chip_id);
+               ret = -ENODEV;
+               goto out;
+       }
+
+       if (wl->fw == NULL) {
+               ret = wl1251_fetch_firmware(wl);
+               if (ret < 0)
+                       goto out;
+       }
+
+       if (wl->nvs == NULL && !wl->use_eeprom) {
+               /* No NVS from netlink, try to get it from the filesystem */
+               ret = wl1251_fetch_nvs(wl);
+               if (ret < 0)
+                       goto out;
+       }
+
+out:
+       return ret;
+}
+
+#define WL1251_IRQ_LOOP_COUNT 10
+static void wl1251_irq_work(struct work_struct *work)
+{
+       u32 intr, ctr = WL1251_IRQ_LOOP_COUNT;
+       struct wl1251 *wl =
+               container_of(work, struct wl1251, irq_work);
+       int ret;
+
+       mutex_lock(&wl->mutex);
+
+       wl1251_debug(DEBUG_IRQ, "IRQ work");
+
+       if (wl->state == WL1251_STATE_OFF)
+               goto out;
+
+       ret = wl1251_ps_elp_wakeup(wl);
+       if (ret < 0)
+               goto out;
+
+       wl1251_reg_write32(wl, ACX_REG_INTERRUPT_MASK, WL1251_ACX_INTR_ALL);
+
+       intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_CLEAR);
+       wl1251_debug(DEBUG_IRQ, "intr: 0x%x", intr);
+
+       do {
+               if (wl->data_path) {
+                       wl->rx_counter = wl1251_mem_read32(
+                               wl, wl->data_path->rx_control_addr);
+
+                       /* We handle a frmware bug here */
+                       switch ((wl->rx_counter - wl->rx_handled) & 0xf) {
+                       case 0:
+                               wl1251_debug(DEBUG_IRQ,
+                                            "RX: FW and host in sync");
+                               intr &= ~WL1251_ACX_INTR_RX0_DATA;
+                               intr &= ~WL1251_ACX_INTR_RX1_DATA;
+                               break;
+                       case 1:
+                               wl1251_debug(DEBUG_IRQ, "RX: FW +1");
+                               intr |= WL1251_ACX_INTR_RX0_DATA;
+                               intr &= ~WL1251_ACX_INTR_RX1_DATA;
+                               break;
+                       case 2:
+                               wl1251_debug(DEBUG_IRQ, "RX: FW +2");
+                               intr |= WL1251_ACX_INTR_RX0_DATA;
+                               intr |= WL1251_ACX_INTR_RX1_DATA;
+                               break;
+                       default:
+                               wl1251_warning(
+                                       "RX: FW and host out of sync: %d",
+                                       wl->rx_counter - wl->rx_handled);
+                               break;
+                       }
+
+                       wl->rx_handled = wl->rx_counter;
+
+                       wl1251_debug(DEBUG_IRQ, "RX counter: %d",
+                                    wl->rx_counter);
+               }
+
+               intr &= wl->intr_mask;
+
+               if (intr == 0) {
+                       wl1251_debug(DEBUG_IRQ, "INTR is 0");
+                       goto out_sleep;
+               }
+
+               if (intr & WL1251_ACX_INTR_RX0_DATA) {
+                       wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_RX0_DATA");
+                       wl1251_rx(wl);
+               }
+
+               if (intr & WL1251_ACX_INTR_RX1_DATA) {
+                       wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_RX1_DATA");
+                       wl1251_rx(wl);
+               }
+
+               if (intr & WL1251_ACX_INTR_TX_RESULT) {
+                       wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_TX_RESULT");
+                       wl1251_tx_complete(wl);
+               }
+
+               if (intr & WL1251_ACX_INTR_EVENT_A) {
+                       wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_EVENT_A");
+                       wl1251_event_handle(wl, 0);
+               }
+
+               if (intr & WL1251_ACX_INTR_EVENT_B) {
+                       wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_EVENT_B");
+                       wl1251_event_handle(wl, 1);
+               }
+
+               if (intr & WL1251_ACX_INTR_INIT_COMPLETE)
+                       wl1251_debug(DEBUG_IRQ,
+                                    "WL1251_ACX_INTR_INIT_COMPLETE");
+
+               if (--ctr == 0)
+                       break;
+
+               intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_CLEAR);
+       } while (intr);
+
+out_sleep:
+       wl1251_reg_write32(wl, ACX_REG_INTERRUPT_MASK, ~(wl->intr_mask));
+       wl1251_ps_elp_sleep(wl);
+
+out:
+       mutex_unlock(&wl->mutex);
+}
+
+static int wl1251_join(struct wl1251 *wl, u8 bss_type, u8 channel,
+                      u16 beacon_interval, u8 dtim_period)
+{
+       int ret;
+
+       ret = wl1251_acx_frame_rates(wl, DEFAULT_HW_GEN_TX_RATE,
+                                    DEFAULT_HW_GEN_MODULATION_TYPE,
+                                    wl->tx_mgmt_frm_rate,
+                                    wl->tx_mgmt_frm_mod);
+       if (ret < 0)
+               goto out;
+
+
+       ret = wl1251_cmd_join(wl, bss_type, channel, beacon_interval,
+                             dtim_period);
+       if (ret < 0)
+               goto out;
+
+       ret = wl1251_event_wait(wl, JOIN_EVENT_COMPLETE_ID, 100);
+       if (ret < 0)
+               wl1251_warning("join timeout");
+
+out:
+       return ret;
+}
+
+static void wl1251_filter_work(struct work_struct *work)
+{
+       struct wl1251 *wl =
+               container_of(work, struct wl1251, filter_work);
+       int ret;
+
+       mutex_lock(&wl->mutex);
+
+       if (wl->state == WL1251_STATE_OFF)
+               goto out;
+
+       ret = wl1251_ps_elp_wakeup(wl);
+       if (ret < 0)
+               goto out;
+
+       ret = wl1251_join(wl, wl->bss_type, wl->channel, wl->beacon_int,
+                         wl->dtim_period);
+       if (ret < 0)
+               goto out_sleep;
+
+out_sleep:
+       wl1251_ps_elp_sleep(wl);
+
+out:
+       mutex_unlock(&wl->mutex);
+}
+
+static int wl1251_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+       struct wl1251 *wl = hw->priv;
+       unsigned long flags;
+
+       skb_queue_tail(&wl->tx_queue, skb);
+
+       /*
+        * The chip specific setup must run before the first TX packet -
+        * before that, the tx_work will not be initialized!
+        */
+
+       ieee80211_queue_work(wl->hw, &wl->tx_work);
+
+       /*
+        * The workqueue is slow to process the tx_queue and we need stop
+        * the queue here, otherwise the queue will get too long.
+        */
+       if (skb_queue_len(&wl->tx_queue) >= WL1251_TX_QUEUE_HIGH_WATERMARK) {
+               wl1251_debug(DEBUG_TX, "op_tx: tx_queue full, stop queues");
+
+               spin_lock_irqsave(&wl->wl_lock, flags);
+               ieee80211_stop_queues(wl->hw);
+               wl->tx_queue_stopped = true;
+               spin_unlock_irqrestore(&wl->wl_lock, flags);
+       }
+
+       return NETDEV_TX_OK;
+}
+
+static int wl1251_op_start(struct ieee80211_hw *hw)
+{
+       struct wl1251 *wl = hw->priv;
+       struct wiphy *wiphy = hw->wiphy;
+       int ret = 0;
+
+       wl1251_debug(DEBUG_MAC80211, "mac80211 start");
+
+       mutex_lock(&wl->mutex);
+
+       if (wl->state != WL1251_STATE_OFF) {
+               wl1251_error("cannot start because not in off state: %d",
+                            wl->state);
+               ret = -EBUSY;
+               goto out;
+       }
+
+       ret = wl1251_chip_wakeup(wl);
+       if (ret < 0)
+               goto out;
+
+       ret = wl1251_boot(wl);
+       if (ret < 0)
+               goto out;
+
+       ret = wl1251_hw_init(wl);
+       if (ret < 0)
+               goto out;
+
+       ret = wl1251_acx_station_id(wl);
+       if (ret < 0)
+               goto out;
+
+       wl->state = WL1251_STATE_ON;
+
+       wl1251_info("firmware booted (%s)", wl->fw_ver);
+
+       /* update hw/fw version info in wiphy struct */
+       wiphy->hw_version = wl->chip_id;
+       strncpy(wiphy->fw_version, wl->fw_ver, sizeof(wiphy->fw_version));
+
+out:
+       if (ret < 0)
+               wl1251_power_off(wl);
+
+       mutex_unlock(&wl->mutex);
+
+       return ret;
+}
+
+static void wl1251_op_stop(struct ieee80211_hw *hw)
+{
+       struct wl1251 *wl = hw->priv;
+
+       wl1251_info("down");
+
+       wl1251_debug(DEBUG_MAC80211, "mac80211 stop");
+
+       mutex_lock(&wl->mutex);
+
+       WARN_ON(wl->state != WL1251_STATE_ON);
+
+       if (wl->scanning) {
+               ieee80211_scan_completed(wl->hw, true);
+               wl->scanning = false;
+       }
+
+       wl->state = WL1251_STATE_OFF;
+
+       wl1251_disable_interrupts(wl);
+
+       mutex_unlock(&wl->mutex);
+
+       cancel_work_sync(&wl->irq_work);
+       cancel_work_sync(&wl->tx_work);
+       cancel_work_sync(&wl->filter_work);
+
+       mutex_lock(&wl->mutex);
+
+       /* let's notify MAC80211 about the remaining pending TX frames */
+       wl1251_tx_flush(wl);
+       wl1251_power_off(wl);
+
+       memset(wl->bssid, 0, ETH_ALEN);
+       wl->listen_int = 1;
+       wl->bss_type = MAX_BSS_TYPE;
+
+       wl->data_in_count = 0;
+       wl->rx_counter = 0;
+       wl->rx_handled = 0;
+       wl->rx_current_buffer = 0;
+       wl->rx_last_id = 0;
+       wl->next_tx_complete = 0;
+       wl->elp = false;
+       wl->psm = 0;
+       wl->tx_queue_stopped = false;
+       wl->power_level = WL1251_DEFAULT_POWER_LEVEL;
+       wl->channel = WL1251_DEFAULT_CHANNEL;
+
+       wl1251_debugfs_reset(wl);
+
+       mutex_unlock(&wl->mutex);
+}
+
+static int wl1251_op_add_interface(struct ieee80211_hw *hw,
+                                  struct ieee80211_vif *vif)
+{
+       struct wl1251 *wl = hw->priv;
+       int ret = 0;
+
+       wl1251_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM",
+                    vif->type, vif->addr);
+
+       mutex_lock(&wl->mutex);
+       if (wl->vif) {
+               ret = -EBUSY;
+               goto out;
+       }
+
+       wl->vif = vif;
+
+       switch (vif->type) {
+       case NL80211_IFTYPE_STATION:
+               wl->bss_type = BSS_TYPE_STA_BSS;
+               break;
+       case NL80211_IFTYPE_ADHOC:
+               wl->bss_type = BSS_TYPE_IBSS;
+               break;
+       default:
+               ret = -EOPNOTSUPP;
+               goto out;
+       }
+
+       if (memcmp(wl->mac_addr, vif->addr, ETH_ALEN)) {
+               memcpy(wl->mac_addr, vif->addr, ETH_ALEN);
+               SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr);
+               ret = wl1251_acx_station_id(wl);
+               if (ret < 0)
+                       goto out;
+       }
+
+out:
+       mutex_unlock(&wl->mutex);
+       return ret;
+}
+
+static void wl1251_op_remove_interface(struct ieee80211_hw *hw,
+                                        struct ieee80211_vif *vif)
+{
+       struct wl1251 *wl = hw->priv;
+
+       mutex_lock(&wl->mutex);
+       wl1251_debug(DEBUG_MAC80211, "mac80211 remove interface");
+       wl->vif = NULL;
+       mutex_unlock(&wl->mutex);
+}
+
+static int wl1251_build_qos_null_data(struct wl1251 *wl)
+{
+       struct ieee80211_qos_hdr template;
+
+       memset(&template, 0, sizeof(template));
+
+       memcpy(template.addr1, wl->bssid, ETH_ALEN);
+       memcpy(template.addr2, wl->mac_addr, ETH_ALEN);
+       memcpy(template.addr3, wl->bssid, ETH_ALEN);
+
+       template.frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
+                                            IEEE80211_STYPE_QOS_NULLFUNC |
+                                            IEEE80211_FCTL_TODS);
+
+       /* FIXME: not sure what priority to use here */
+       template.qos_ctrl = cpu_to_le16(0);
+
+       return wl1251_cmd_template_set(wl, CMD_QOS_NULL_DATA, &template,
+                                      sizeof(template));
+}
+
+static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed)
+{
+       struct wl1251 *wl = hw->priv;
+       struct ieee80211_conf *conf = &hw->conf;
+       int channel, ret = 0;
+
+       channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
+
+       wl1251_debug(DEBUG_MAC80211, "mac80211 config ch %d psm %s power %d",
+                    channel,
+                    conf->flags & IEEE80211_CONF_PS ? "on" : "off",
+                    conf->power_level);
+
+       mutex_lock(&wl->mutex);
+
+       ret = wl1251_ps_elp_wakeup(wl);
+       if (ret < 0)
+               goto out;
+
+       if (channel != wl->channel) {
+               wl->channel = channel;
+
+               ret = wl1251_join(wl, wl->bss_type, wl->channel,
+                                 wl->beacon_int, wl->dtim_period);
+               if (ret < 0)
+                       goto out_sleep;
+       }
+
+       if (conf->flags & IEEE80211_CONF_PS && !wl->psm_requested) {
+               wl1251_debug(DEBUG_PSM, "psm enabled");
+
+               wl->psm_requested = true;
+
+               wl->dtim_period = conf->ps_dtim_period;
+
+               ret = wl1251_acx_wr_tbtt_and_dtim(wl, wl->beacon_int,
+                                                 wl->dtim_period);
+
+               /*
+                * mac80211 enables PSM only if we're already associated.
+                */
+               ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
+               if (ret < 0)
+                       goto out_sleep;
+       } else if (!(conf->flags & IEEE80211_CONF_PS) &&
+                  wl->psm_requested) {
+               wl1251_debug(DEBUG_PSM, "psm disabled");
+
+               wl->psm_requested = false;
+
+               if (wl->psm) {
+                       ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE);
+                       if (ret < 0)
+                               goto out_sleep;
+               }
+       }
+
+       if (conf->power_level != wl->power_level) {
+               ret = wl1251_acx_tx_power(wl, conf->power_level);
+               if (ret < 0)
+                       goto out_sleep;
+
+               wl->power_level = conf->power_level;
+       }
+
+out_sleep:
+       wl1251_ps_elp_sleep(wl);
+
+out:
+       mutex_unlock(&wl->mutex);
+
+       return ret;
+}
+
+#define WL1251_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \
+                                 FIF_ALLMULTI | \
+                                 FIF_FCSFAIL | \
+                                 FIF_BCN_PRBRESP_PROMISC | \
+                                 FIF_CONTROL | \
+                                 FIF_OTHER_BSS)
+
+static void wl1251_op_configure_filter(struct ieee80211_hw *hw,
+                                      unsigned int changed,
+                                      unsigned int *total,u64 multicast)
+{
+       struct wl1251 *wl = hw->priv;
+
+       wl1251_debug(DEBUG_MAC80211, "mac80211 configure filter");
+
+       *total &= WL1251_SUPPORTED_FILTERS;
+       changed &= WL1251_SUPPORTED_FILTERS;
+
+       if (changed == 0)
+               /* no filters which we support changed */
+               return;
+
+       /* FIXME: wl->rx_config and wl->rx_filter are not protected */
+
+       wl->rx_config = WL1251_DEFAULT_RX_CONFIG;
+       wl->rx_filter = WL1251_DEFAULT_RX_FILTER;
+
+       if (*total & FIF_PROMISC_IN_BSS) {
+               wl->rx_config |= CFG_BSSID_FILTER_EN;
+               wl->rx_config |= CFG_RX_ALL_GOOD;
+       }
+       if (*total & FIF_ALLMULTI)
+               /*
+                * CFG_MC_FILTER_EN in rx_config needs to be 0 to receive
+                * all multicast frames
+                */
+               wl->rx_config &= ~CFG_MC_FILTER_EN;
+       if (*total & FIF_FCSFAIL)
+               wl->rx_filter |= CFG_RX_FCS_ERROR;
+       if (*total & FIF_BCN_PRBRESP_PROMISC) {
+               wl->rx_config &= ~CFG_BSSID_FILTER_EN;
+               wl->rx_config &= ~CFG_SSID_FILTER_EN;
+       }
+       if (*total & FIF_CONTROL)
+               wl->rx_filter |= CFG_RX_CTL_EN;
+       if (*total & FIF_OTHER_BSS)
+               wl->rx_filter &= ~CFG_BSSID_FILTER_EN;
+
+       /*
+        * FIXME: workqueues need to be properly cancelled on stop(), for
+        * now let's just disable changing the filter settings. They will
+        * be updated any on config().
+        */
+       /* schedule_work(&wl->filter_work); */
+}
+
+/* HW encryption */
+static int wl1251_set_key_type(struct wl1251 *wl,
+                              struct wl1251_cmd_set_keys *key,
+                              enum set_key_cmd cmd,
+                              struct ieee80211_key_conf *mac80211_key,
+                              const u8 *addr)
+{
+       switch (mac80211_key->cipher) {
+       case WLAN_CIPHER_SUITE_WEP40:
+       case WLAN_CIPHER_SUITE_WEP104:
+               if (is_broadcast_ether_addr(addr))
+                       key->key_type = KEY_WEP_DEFAULT;
+               else
+                       key->key_type = KEY_WEP_ADDR;
+
+               mac80211_key->hw_key_idx = mac80211_key->keyidx;
+               break;
+       case WLAN_CIPHER_SUITE_TKIP:
+               if (is_broadcast_ether_addr(addr))
+                       key->key_type = KEY_TKIP_MIC_GROUP;
+               else
+                       key->key_type = KEY_TKIP_MIC_PAIRWISE;
+
+               mac80211_key->hw_key_idx = mac80211_key->keyidx;
+               break;
+       case WLAN_CIPHER_SUITE_CCMP:
+               if (is_broadcast_ether_addr(addr))
+                       key->key_type = KEY_AES_GROUP;
+               else
+                       key->key_type = KEY_AES_PAIRWISE;
+               mac80211_key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+               break;
+       default:
+               wl1251_error("Unknown key cipher 0x%x", mac80211_key->cipher);
+               return -EOPNOTSUPP;
+       }
+
+       return 0;
+}
+
+static int wl1251_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+                            struct ieee80211_vif *vif,
+                            struct ieee80211_sta *sta,
+                            struct ieee80211_key_conf *key)
+{
+       struct wl1251 *wl = hw->priv;
+       struct wl1251_cmd_set_keys *wl_cmd;
+       const u8 *addr;
+       int ret;
+
+       static const u8 bcast_addr[ETH_ALEN] =
+               { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+
+       wl1251_debug(DEBUG_MAC80211, "mac80211 set key");
+
+       wl_cmd = kzalloc(sizeof(*wl_cmd), GFP_KERNEL);
+       if (!wl_cmd) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       addr = sta ? sta->addr : bcast_addr;
+
+       wl1251_debug(DEBUG_CRYPT, "CMD: 0x%x", cmd);
+       wl1251_dump(DEBUG_CRYPT, "ADDR: ", addr, ETH_ALEN);
+       wl1251_debug(DEBUG_CRYPT, "Key: algo:0x%x, id:%d, len:%d flags 0x%x",
+                    key->cipher, key->keyidx, key->keylen, key->flags);
+       wl1251_dump(DEBUG_CRYPT, "KEY: ", key->key, key->keylen);
+
+       if (is_zero_ether_addr(addr)) {
+               /* We dont support TX only encryption */
+               ret = -EOPNOTSUPP;
+               goto out;
+       }
+
+       mutex_lock(&wl->mutex);
+
+       ret = wl1251_ps_elp_wakeup(wl);
+       if (ret < 0)
+               goto out_unlock;
+
+       switch (cmd) {
+       case SET_KEY:
+               wl_cmd->key_action = KEY_ADD_OR_REPLACE;
+               break;
+       case DISABLE_KEY:
+               wl_cmd->key_action = KEY_REMOVE;
+               break;
+       default:
+               wl1251_error("Unsupported key cmd 0x%x", cmd);
+               break;
+       }
+
+       ret = wl1251_set_key_type(wl, wl_cmd, cmd, key, addr);
+       if (ret < 0) {
+               wl1251_error("Set KEY type failed");
+               goto out_sleep;
+       }
+
+       if (wl_cmd->key_type != KEY_WEP_DEFAULT)
+               memcpy(wl_cmd->addr, addr, ETH_ALEN);
+
+       if ((wl_cmd->key_type == KEY_TKIP_MIC_GROUP) ||
+           (wl_cmd->key_type == KEY_TKIP_MIC_PAIRWISE)) {
+               /*
+                * We get the key in the following form:
+                * TKIP (16 bytes) - TX MIC (8 bytes) - RX MIC (8 bytes)
+                * but the target is expecting:
+                * TKIP - RX MIC - TX MIC
+                */
+               memcpy(wl_cmd->key, key->key, 16);
+               memcpy(wl_cmd->key + 16, key->key + 24, 8);
+               memcpy(wl_cmd->key + 24, key->key + 16, 8);
+
+       } else {
+               memcpy(wl_cmd->key, key->key, key->keylen);
+       }
+       wl_cmd->key_size = key->keylen;
+
+       wl_cmd->id = key->keyidx;
+       wl_cmd->ssid_profile = 0;
+
+       wl1251_dump(DEBUG_CRYPT, "TARGET KEY: ", wl_cmd, sizeof(*wl_cmd));
+
+       ret = wl1251_cmd_send(wl, CMD_SET_KEYS, wl_cmd, sizeof(*wl_cmd));
+       if (ret < 0) {
+               wl1251_warning("could not set keys");
+               goto out_sleep;
+       }
+
+out_sleep:
+       wl1251_ps_elp_sleep(wl);
+
+out_unlock:
+       mutex_unlock(&wl->mutex);
+
+out:
+       kfree(wl_cmd);
+
+       return ret;
+}
+
+static int wl1251_op_hw_scan(struct ieee80211_hw *hw,
+                            struct ieee80211_vif *vif,
+                            struct cfg80211_scan_request *req)
+{
+       struct wl1251 *wl = hw->priv;
+       struct sk_buff *skb;
+       size_t ssid_len = 0;
+       u8 *ssid = NULL;
+       int ret;
+
+       wl1251_debug(DEBUG_MAC80211, "mac80211 hw scan");
+
+       if (req->n_ssids) {
+               ssid = req->ssids[0].ssid;
+               ssid_len = req->ssids[0].ssid_len;
+       }
+
+       mutex_lock(&wl->mutex);
+
+       if (wl->scanning) {
+               wl1251_debug(DEBUG_SCAN, "scan already in progress");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       ret = wl1251_ps_elp_wakeup(wl);
+       if (ret < 0)
+               goto out;
+
+       skb = ieee80211_probereq_get(wl->hw, wl->vif, ssid, ssid_len,
+                                    req->ie, req->ie_len);
+       if (!skb) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       ret = wl1251_cmd_template_set(wl, CMD_PROBE_REQ, skb->data,
+                                     skb->len);
+       dev_kfree_skb(skb);
+       if (ret < 0)
+               goto out_sleep;
+
+       ret = wl1251_cmd_trigger_scan_to(wl, 0);
+       if (ret < 0)
+               goto out_sleep;
+
+       wl->scanning = true;
+
+       ret = wl1251_cmd_scan(wl, ssid, ssid_len, req->channels,
+                             req->n_channels, WL1251_SCAN_NUM_PROBES);
+       if (ret < 0) {
+               wl->scanning = false;
+               goto out_sleep;
+       }
+
+out_sleep:
+       wl1251_ps_elp_sleep(wl);
+
+out:
+       mutex_unlock(&wl->mutex);
+
+       return ret;
+}
+
+static int wl1251_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
+{
+       struct wl1251 *wl = hw->priv;
+       int ret;
+
+       mutex_lock(&wl->mutex);
+
+       ret = wl1251_ps_elp_wakeup(wl);
+       if (ret < 0)
+               goto out;
+
+       ret = wl1251_acx_rts_threshold(wl, (u16) value);
+       if (ret < 0)
+               wl1251_warning("wl1251_op_set_rts_threshold failed: %d", ret);
+
+       wl1251_ps_elp_sleep(wl);
+
+out:
+       mutex_unlock(&wl->mutex);
+
+       return ret;
+}
+
+static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
+                                      struct ieee80211_vif *vif,
+                                      struct ieee80211_bss_conf *bss_conf,
+                                      u32 changed)
+{
+       struct wl1251 *wl = hw->priv;
+       struct sk_buff *beacon, *skb;
+       int ret;
+
+       wl1251_debug(DEBUG_MAC80211, "mac80211 bss info changed");
+
+       mutex_lock(&wl->mutex);
+
+       ret = wl1251_ps_elp_wakeup(wl);
+       if (ret < 0)
+               goto out;
+
+       if (changed & BSS_CHANGED_BSSID) {
+               memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN);
+
+               skb = ieee80211_nullfunc_get(wl->hw, wl->vif);
+               if (!skb)
+                       goto out_sleep;
+
+               ret = wl1251_cmd_template_set(wl, CMD_NULL_DATA,
+                                             skb->data, skb->len);
+               dev_kfree_skb(skb);
+               if (ret < 0)
+                       goto out_sleep;
+
+               ret = wl1251_build_qos_null_data(wl);
+               if (ret < 0)
+                       goto out;
+
+               if (wl->bss_type != BSS_TYPE_IBSS) {
+                       ret = wl1251_join(wl, wl->bss_type, wl->channel,
+                                         wl->beacon_int, wl->dtim_period);
+                       if (ret < 0)
+                               goto out_sleep;
+               }
+       }
+
+       if (changed & BSS_CHANGED_ASSOC) {
+               if (bss_conf->assoc) {
+                       wl->beacon_int = bss_conf->beacon_int;
+
+                       skb = ieee80211_pspoll_get(wl->hw, wl->vif);
+                       if (!skb)
+                               goto out_sleep;
+
+                       ret = wl1251_cmd_template_set(wl, CMD_PS_POLL,
+                                                     skb->data,
+                                                     skb->len);
+                       dev_kfree_skb(skb);
+                       if (ret < 0)
+                               goto out_sleep;
+
+                       ret = wl1251_acx_aid(wl, bss_conf->aid);
+                       if (ret < 0)
+                               goto out_sleep;
+               } else {
+                       /* use defaults when not associated */
+                       wl->beacon_int = WL1251_DEFAULT_BEACON_INT;
+                       wl->dtim_period = WL1251_DEFAULT_DTIM_PERIOD;
+               }
+       }
+       if (changed & BSS_CHANGED_ERP_SLOT) {
+               if (bss_conf->use_short_slot)
+                       ret = wl1251_acx_slot(wl, SLOT_TIME_SHORT);
+               else
+                       ret = wl1251_acx_slot(wl, SLOT_TIME_LONG);
+               if (ret < 0) {
+                       wl1251_warning("Set slot time failed %d", ret);
+                       goto out_sleep;
+               }
+       }
+
+       if (changed & BSS_CHANGED_ERP_PREAMBLE) {
+               if (bss_conf->use_short_preamble)
+                       wl1251_acx_set_preamble(wl, ACX_PREAMBLE_SHORT);
+               else
+                       wl1251_acx_set_preamble(wl, ACX_PREAMBLE_LONG);
+       }
+
+       if (changed & BSS_CHANGED_ERP_CTS_PROT) {
+               if (bss_conf->use_cts_prot)
+                       ret = wl1251_acx_cts_protect(wl, CTSPROTECT_ENABLE);
+               else
+                       ret = wl1251_acx_cts_protect(wl, CTSPROTECT_DISABLE);
+               if (ret < 0) {
+                       wl1251_warning("Set ctsprotect failed %d", ret);
+                       goto out_sleep;
+               }
+       }
+
+       if (changed & BSS_CHANGED_BEACON) {
+               beacon = ieee80211_beacon_get(hw, vif);
+               ret = wl1251_cmd_template_set(wl, CMD_BEACON, beacon->data,
+                                             beacon->len);
+
+               if (ret < 0) {
+                       dev_kfree_skb(beacon);
+                       goto out_sleep;
+               }
+
+               ret = wl1251_cmd_template_set(wl, CMD_PROBE_RESP, beacon->data,
+                                             beacon->len);
+
+               dev_kfree_skb(beacon);
+
+               if (ret < 0)
+                       goto out_sleep;
+
+               ret = wl1251_join(wl, wl->bss_type, wl->beacon_int,
+                                 wl->channel, wl->dtim_period);
+
+               if (ret < 0)
+                       goto out_sleep;
+       }
+
+out_sleep:
+       wl1251_ps_elp_sleep(wl);
+
+out:
+       mutex_unlock(&wl->mutex);
+}
+
+
+/* can't be const, mac80211 writes to this */
+static struct ieee80211_rate wl1251_rates[] = {
+       { .bitrate = 10,
+         .hw_value = 0x1,
+         .hw_value_short = 0x1, },
+       { .bitrate = 20,
+         .hw_value = 0x2,
+         .hw_value_short = 0x2,
+         .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+       { .bitrate = 55,
+         .hw_value = 0x4,
+         .hw_value_short = 0x4,
+         .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+       { .bitrate = 110,
+         .hw_value = 0x20,
+         .hw_value_short = 0x20,
+         .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+       { .bitrate = 60,
+         .hw_value = 0x8,
+         .hw_value_short = 0x8, },
+       { .bitrate = 90,
+         .hw_value = 0x10,
+         .hw_value_short = 0x10, },
+       { .bitrate = 120,
+         .hw_value = 0x40,
+         .hw_value_short = 0x40, },
+       { .bitrate = 180,
+         .hw_value = 0x80,
+         .hw_value_short = 0x80, },
+       { .bitrate = 240,
+         .hw_value = 0x200,
+         .hw_value_short = 0x200, },
+       { .bitrate = 360,
+        .hw_value = 0x400,
+        .hw_value_short = 0x400, },
+       { .bitrate = 480,
+         .hw_value = 0x800,
+         .hw_value_short = 0x800, },
+       { .bitrate = 540,
+         .hw_value = 0x1000,
+         .hw_value_short = 0x1000, },
+};
+
+/* can't be const, mac80211 writes to this */
+static struct ieee80211_channel wl1251_channels[] = {
+       { .hw_value = 1, .center_freq = 2412},
+       { .hw_value = 2, .center_freq = 2417},
+       { .hw_value = 3, .center_freq = 2422},
+       { .hw_value = 4, .center_freq = 2427},
+       { .hw_value = 5, .center_freq = 2432},
+       { .hw_value = 6, .center_freq = 2437},
+       { .hw_value = 7, .center_freq = 2442},
+       { .hw_value = 8, .center_freq = 2447},
+       { .hw_value = 9, .center_freq = 2452},
+       { .hw_value = 10, .center_freq = 2457},
+       { .hw_value = 11, .center_freq = 2462},
+       { .hw_value = 12, .center_freq = 2467},
+       { .hw_value = 13, .center_freq = 2472},
+};
+
+static int wl1251_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
+                            const struct ieee80211_tx_queue_params *params)
+{
+       enum wl1251_acx_ps_scheme ps_scheme;
+       struct wl1251 *wl = hw->priv;
+       int ret;
+
+       mutex_lock(&wl->mutex);
+
+       wl1251_debug(DEBUG_MAC80211, "mac80211 conf tx %d", queue);
+
+       ret = wl1251_ps_elp_wakeup(wl);
+       if (ret < 0)
+               goto out;
+
+       /* mac80211 uses units of 32 usec */
+       ret = wl1251_acx_ac_cfg(wl, wl1251_tx_get_queue(queue),
+                               params->cw_min, params->cw_max,
+                               params->aifs, params->txop * 32);
+       if (ret < 0)
+               goto out_sleep;
+
+       if (params->uapsd)
+               ps_scheme = WL1251_ACX_PS_SCHEME_UPSD_TRIGGER;
+       else
+               ps_scheme = WL1251_ACX_PS_SCHEME_LEGACY;
+
+       ret = wl1251_acx_tid_cfg(wl, wl1251_tx_get_queue(queue),
+                                CHANNEL_TYPE_EDCF,
+                                wl1251_tx_get_queue(queue), ps_scheme,
+                                WL1251_ACX_ACK_POLICY_LEGACY);
+       if (ret < 0)
+               goto out_sleep;
+
+out_sleep:
+       wl1251_ps_elp_sleep(wl);
+
+out:
+       mutex_unlock(&wl->mutex);
+
+       return ret;
+}
+
+static int wl1251_op_get_survey(struct ieee80211_hw *hw, int idx,
+                               struct survey_info *survey)
+{
+       struct wl1251 *wl = hw->priv;
+       struct ieee80211_conf *conf = &hw->conf;
+       if (idx != 0)
+               return -ENOENT;
+       survey->channel = conf->channel;
+       survey->filled = SURVEY_INFO_NOISE_DBM;
+       survey->noise = wl->noise;
+       return 0;
+}
+
+/* can't be const, mac80211 writes to this */
+static struct ieee80211_supported_band wl1251_band_2ghz = {
+       .channels = wl1251_channels,
+       .n_channels = ARRAY_SIZE(wl1251_channels),
+       .bitrates = wl1251_rates,
+       .n_bitrates = ARRAY_SIZE(wl1251_rates),
+};
+
+static const struct ieee80211_ops wl1251_ops = {
+       .start = wl1251_op_start,
+       .stop = wl1251_op_stop,
+       .add_interface = wl1251_op_add_interface,
+       .remove_interface = wl1251_op_remove_interface,
+       .config = wl1251_op_config,
+       .configure_filter = wl1251_op_configure_filter,
+       .tx = wl1251_op_tx,
+       .set_key = wl1251_op_set_key,
+       .hw_scan = wl1251_op_hw_scan,
+       .bss_info_changed = wl1251_op_bss_info_changed,
+       .set_rts_threshold = wl1251_op_set_rts_threshold,
+       .conf_tx = wl1251_op_conf_tx,
+       .get_survey = wl1251_op_get_survey,
+};
+
+static int wl1251_read_eeprom_byte(struct wl1251 *wl, off_t offset, u8 *data)
+{
+       unsigned long timeout;
+
+       wl1251_reg_write32(wl, EE_ADDR, offset);
+       wl1251_reg_write32(wl, EE_CTL, EE_CTL_READ);
+
+       /* EE_CTL_READ clears when data is ready */
+       timeout = jiffies + msecs_to_jiffies(100);
+       while (1) {
+               if (!(wl1251_reg_read32(wl, EE_CTL) & EE_CTL_READ))
+                       break;
+
+               if (time_after(jiffies, timeout))
+                       return -ETIMEDOUT;
+
+               msleep(1);
+       }
+
+       *data = wl1251_reg_read32(wl, EE_DATA);
+       return 0;
+}
+
+static int wl1251_read_eeprom(struct wl1251 *wl, off_t offset,
+                             u8 *data, size_t len)
+{
+       size_t i;
+       int ret;
+
+       wl1251_reg_write32(wl, EE_START, 0);
+
+       for (i = 0; i < len; i++) {
+               ret = wl1251_read_eeprom_byte(wl, offset + i, &data[i]);
+               if (ret < 0)
+                       return ret;
+       }
+
+       return 0;
+}
+
+static int wl1251_read_eeprom_mac(struct wl1251 *wl)
+{
+       u8 mac[ETH_ALEN];
+       int i, ret;
+
+       wl1251_set_partition(wl, 0, 0, REGISTERS_BASE, REGISTERS_DOWN_SIZE);
+
+       ret = wl1251_read_eeprom(wl, 0x1c, mac, sizeof(mac));
+       if (ret < 0) {
+               wl1251_warning("failed to read MAC address from EEPROM");
+               return ret;
+       }
+
+       /* MAC is stored in reverse order */
+       for (i = 0; i < ETH_ALEN; i++)
+               wl->mac_addr[i] = mac[ETH_ALEN - i - 1];
+
+       return 0;
+}
+
+static int wl1251_register_hw(struct wl1251 *wl)
+{
+       int ret;
+
+       if (wl->mac80211_registered)
+               return 0;
+
+       SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr);
+
+       ret = ieee80211_register_hw(wl->hw);
+       if (ret < 0) {
+               wl1251_error("unable to register mac80211 hw: %d", ret);
+               return ret;
+       }
+
+       wl->mac80211_registered = true;
+
+       wl1251_notice("loaded");
+
+       return 0;
+}
+
+int wl1251_init_ieee80211(struct wl1251 *wl)
+{
+       int ret;
+
+       /* The tx descriptor buffer and the TKIP space */
+       wl->hw->extra_tx_headroom = sizeof(struct tx_double_buffer_desc)
+               + WL1251_TKIP_IV_SPACE;
+
+       /* unit us */
+       /* FIXME: find a proper value */
+       wl->hw->channel_change_time = 10000;
+
+       wl->hw->flags = IEEE80211_HW_SIGNAL_DBM |
+               IEEE80211_HW_SUPPORTS_PS |
+               IEEE80211_HW_BEACON_FILTER |
+               IEEE80211_HW_SUPPORTS_UAPSD;
+
+       wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
+       wl->hw->wiphy->max_scan_ssids = 1;
+       wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl1251_band_2ghz;
+
+       wl->hw->queues = 4;
+
+       if (wl->use_eeprom)
+               wl1251_read_eeprom_mac(wl);
+
+       ret = wl1251_register_hw(wl);
+       if (ret)
+               goto out;
+
+       wl1251_debugfs_init(wl);
+       wl1251_notice("initialized");
+
+       ret = 0;
+
+out:
+       return ret;
+}
+EXPORT_SYMBOL_GPL(wl1251_init_ieee80211);
+
+struct ieee80211_hw *wl1251_alloc_hw(void)
+{
+       struct ieee80211_hw *hw;
+       struct wl1251 *wl;
+       int i;
+       static const u8 nokia_oui[3] = {0x00, 0x1f, 0xdf};
+
+       hw = ieee80211_alloc_hw(sizeof(*wl), &wl1251_ops);
+       if (!hw) {
+               wl1251_error("could not alloc ieee80211_hw");
+               return ERR_PTR(-ENOMEM);
+       }
+
+       wl = hw->priv;
+       memset(wl, 0, sizeof(*wl));
+
+       wl->hw = hw;
+
+       wl->data_in_count = 0;
+
+       skb_queue_head_init(&wl->tx_queue);
+
+       INIT_WORK(&wl->filter_work, wl1251_filter_work);
+       INIT_DELAYED_WORK(&wl->elp_work, wl1251_elp_work);
+       wl->channel = WL1251_DEFAULT_CHANNEL;
+       wl->scanning = false;
+       wl->default_key = 0;
+       wl->listen_int = 1;
+       wl->rx_counter = 0;
+       wl->rx_handled = 0;
+       wl->rx_current_buffer = 0;
+       wl->rx_last_id = 0;
+       wl->rx_config = WL1251_DEFAULT_RX_CONFIG;
+       wl->rx_filter = WL1251_DEFAULT_RX_FILTER;
+       wl->elp = false;
+       wl->psm = 0;
+       wl->psm_requested = false;
+       wl->tx_queue_stopped = false;
+       wl->power_level = WL1251_DEFAULT_POWER_LEVEL;
+       wl->beacon_int = WL1251_DEFAULT_BEACON_INT;
+       wl->dtim_period = WL1251_DEFAULT_DTIM_PERIOD;
+       wl->vif = NULL;
+
+       for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++)
+               wl->tx_frames[i] = NULL;
+
+       wl->next_tx_complete = 0;
+
+       INIT_WORK(&wl->irq_work, wl1251_irq_work);
+       INIT_WORK(&wl->tx_work, wl1251_tx_work);
+
+       /*
+        * In case our MAC address is not correctly set,
+        * we use a random but Nokia MAC.
+        */
+       memcpy(wl->mac_addr, nokia_oui, 3);
+       get_random_bytes(wl->mac_addr + 3, 3);
+
+       wl->state = WL1251_STATE_OFF;
+       mutex_init(&wl->mutex);
+
+       wl->tx_mgmt_frm_rate = DEFAULT_HW_GEN_TX_RATE;
+       wl->tx_mgmt_frm_mod = DEFAULT_HW_GEN_MODULATION_TYPE;
+
+       wl->rx_descriptor = kmalloc(sizeof(*wl->rx_descriptor), GFP_KERNEL);
+       if (!wl->rx_descriptor) {
+               wl1251_error("could not allocate memory for rx descriptor");
+               ieee80211_free_hw(hw);
+               return ERR_PTR(-ENOMEM);
+       }
+
+       return hw;
+}
+EXPORT_SYMBOL_GPL(wl1251_alloc_hw);
+
+int wl1251_free_hw(struct wl1251 *wl)
+{
+       ieee80211_unregister_hw(wl->hw);
+
+       wl1251_debugfs_exit(wl);
+
+       kfree(wl->target_mem_map);
+       kfree(wl->data_path);
+       vfree(wl->fw);
+       wl->fw = NULL;
+       kfree(wl->nvs);
+       wl->nvs = NULL;
+
+       kfree(wl->rx_descriptor);
+       wl->rx_descriptor = NULL;
+
+       ieee80211_free_hw(wl->hw);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(wl1251_free_hw);
+
+MODULE_DESCRIPTION("TI wl1251 Wireles LAN Driver Core");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Kalle Valo <kvalo@adurom.com>");
+MODULE_FIRMWARE(WL1251_FW_NAME);
diff --git a/drivers/net/wireless/wl1251/ps.c b/drivers/net/wireless/wl1251/ps.c
new file mode 100644 (file)
index 0000000..5ed47c8
--- /dev/null
@@ -0,0 +1,194 @@
+/*
+ * This file is part of wl1251
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 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 St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include "reg.h"
+#include "ps.h"
+#include "cmd.h"
+#include "io.h"
+
+/* in ms */
+#define WL1251_WAKEUP_TIMEOUT 100
+
+void wl1251_elp_work(struct work_struct *work)
+{
+       struct delayed_work *dwork;
+       struct wl1251 *wl;
+
+       dwork = container_of(work, struct delayed_work, work);
+       wl = container_of(dwork, struct wl1251, elp_work);
+
+       wl1251_debug(DEBUG_PSM, "elp work");
+
+       mutex_lock(&wl->mutex);
+
+       if (wl->elp || !wl->psm)
+               goto out;
+
+       wl1251_debug(DEBUG_PSM, "chip to elp");
+       wl1251_write_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP);
+       wl->elp = true;
+
+out:
+       mutex_unlock(&wl->mutex);
+}
+
+#define ELP_ENTRY_DELAY  5
+
+/* Routines to toggle sleep mode while in ELP */
+void wl1251_ps_elp_sleep(struct wl1251 *wl)
+{
+       unsigned long delay;
+
+       if (wl->psm) {
+               cancel_delayed_work(&wl->elp_work);
+               delay = msecs_to_jiffies(ELP_ENTRY_DELAY);
+               ieee80211_queue_delayed_work(wl->hw, &wl->elp_work, delay);
+       }
+}
+
+int wl1251_ps_elp_wakeup(struct wl1251 *wl)
+{
+       unsigned long timeout, start;
+       u32 elp_reg;
+
+       if (!wl->elp)
+               return 0;
+
+       wl1251_debug(DEBUG_PSM, "waking up chip from elp");
+
+       start = jiffies;
+       timeout = jiffies + msecs_to_jiffies(WL1251_WAKEUP_TIMEOUT);
+
+       wl1251_write_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_WAKE_UP);
+
+       elp_reg = wl1251_read_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR);
+
+       /*
+        * FIXME: we should wait for irq from chip but, as a temporary
+        * solution to simplify locking, let's poll instead
+        */
+       while (!(elp_reg & ELPCTRL_WLAN_READY)) {
+               if (time_after(jiffies, timeout)) {
+                       wl1251_error("elp wakeup timeout");
+                       return -ETIMEDOUT;
+               }
+               msleep(1);
+               elp_reg = wl1251_read_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR);
+       }
+
+       wl1251_debug(DEBUG_PSM, "wakeup time: %u ms",
+                    jiffies_to_msecs(jiffies - start));
+
+       wl->elp = false;
+
+       return 0;
+}
+
+static int wl1251_ps_set_elp(struct wl1251 *wl, bool enable)
+{
+       int ret;
+
+       if (enable) {
+               wl1251_debug(DEBUG_PSM, "sleep auth psm/elp");
+
+               ret = wl1251_acx_sleep_auth(wl, WL1251_PSM_ELP);
+               if (ret < 0)
+                       return ret;
+
+               wl1251_ps_elp_sleep(wl);
+       } else {
+               wl1251_debug(DEBUG_PSM, "sleep auth cam");
+
+               /*
+                * When the target is in ELP, we can only
+                * access the ELP control register. Thus,
+                * we have to wake the target up before
+                * changing the power authorization.
+                */
+
+               wl1251_ps_elp_wakeup(wl);
+
+               ret = wl1251_acx_sleep_auth(wl, WL1251_PSM_CAM);
+               if (ret < 0)
+                       return ret;
+       }
+
+       return 0;
+}
+
+int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode)
+{
+       int ret;
+
+       switch (mode) {
+       case STATION_POWER_SAVE_MODE:
+               wl1251_debug(DEBUG_PSM, "entering psm");
+
+               /* enable beacon filtering */
+               ret = wl1251_acx_beacon_filter_opt(wl, true);
+               if (ret < 0)
+                       return ret;
+
+               ret = wl1251_acx_wake_up_conditions(wl,
+                                                   WAKE_UP_EVENT_DTIM_BITMAP,
+                                                   wl->listen_int);
+               if (ret < 0)
+                       return ret;
+
+               ret = wl1251_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE);
+               if (ret < 0)
+                       return ret;
+
+               ret = wl1251_ps_set_elp(wl, true);
+               if (ret < 0)
+                       return ret;
+
+               wl->psm = 1;
+               break;
+       case STATION_ACTIVE_MODE:
+       default:
+               wl1251_debug(DEBUG_PSM, "leaving psm");
+               ret = wl1251_ps_set_elp(wl, false);
+               if (ret < 0)
+                       return ret;
+
+               /* disable beacon filtering */
+               ret = wl1251_acx_beacon_filter_opt(wl, false);
+               if (ret < 0)
+                       return ret;
+
+               ret = wl1251_acx_wake_up_conditions(wl,
+                                                   WAKE_UP_EVENT_DTIM_BITMAP,
+                                                   wl->listen_int);
+               if (ret < 0)
+                       return ret;
+
+               ret = wl1251_cmd_ps_mode(wl, STATION_ACTIVE_MODE);
+               if (ret < 0)
+                       return ret;
+
+               wl->psm = 0;
+               break;
+       }
+
+       return ret;
+}
+
diff --git a/drivers/net/wireless/wl1251/ps.h b/drivers/net/wireless/wl1251/ps.h
new file mode 100644 (file)
index 0000000..55c3dda
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * This file is part of wl1251
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 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 St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __WL1251_PS_H__
+#define __WL1251_PS_H__
+
+#include "wl1251.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);
+int wl1251_ps_elp_wakeup(struct wl1251 *wl);
+void wl1251_elp_work(struct work_struct *work);
+
+
+#endif /* __WL1251_PS_H__ */
diff --git a/drivers/net/wireless/wl1251/reg.h b/drivers/net/wireless/wl1251/reg.h
new file mode 100644 (file)
index 0000000..a580901
--- /dev/null
@@ -0,0 +1,655 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 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 St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __REG_H__
+#define __REG_H__
+
+#include <linux/bitops.h>
+
+#define REGISTERS_BASE 0x00300000
+#define DRPW_BASE      0x00310000
+
+#define REGISTERS_DOWN_SIZE 0x00008800
+#define REGISTERS_WORK_SIZE 0x0000b000
+
+#define HW_ACCESS_ELP_CTRL_REG_ADDR         0x1FFFC
+
+/* ELP register commands */
+#define ELPCTRL_WAKE_UP             0x1
+#define ELPCTRL_WAKE_UP_WLAN_READY  0x5
+#define ELPCTRL_SLEEP               0x0
+/* ELP WLAN_READY bit */
+#define ELPCTRL_WLAN_READY          0x2
+
+/* Device Configuration registers*/
+#define SOR_CFG                        (REGISTERS_BASE + 0x0800)
+#define ECPU_CTRL                      (REGISTERS_BASE + 0x0804)
+#define HI_CFG                         (REGISTERS_BASE + 0x0808)
+
+/* EEPROM registers */
+#define EE_START                       (REGISTERS_BASE + 0x080C)
+#define EE_CTL                         (REGISTERS_BASE + 0x2000)
+#define EE_DATA                        (REGISTERS_BASE + 0x2004)
+#define EE_ADDR                        (REGISTERS_BASE + 0x2008)
+
+#define EE_CTL_READ                   2
+
+#define CHIP_ID_B                      (REGISTERS_BASE + 0x5674)
+
+#define CHIP_ID_1251_PG10                 (0x7010101)
+#define CHIP_ID_1251_PG11                 (0x7020101)
+#define CHIP_ID_1251_PG12                 (0x7030101)
+
+#define ENABLE                         (REGISTERS_BASE + 0x5450)
+
+/* Power Management registers */
+#define ELP_CFG_MODE                   (REGISTERS_BASE + 0x5804)
+#define ELP_CMD                        (REGISTERS_BASE + 0x5808)
+#define PLL_CAL_TIME                   (REGISTERS_BASE + 0x5810)
+#define CLK_REQ_TIME                   (REGISTERS_BASE + 0x5814)
+#define CLK_BUF_TIME                   (REGISTERS_BASE + 0x5818)
+
+#define CFG_PLL_SYNC_CNT               (REGISTERS_BASE + 0x5820)
+
+/* Scratch Pad registers*/
+#define SCR_PAD0                       (REGISTERS_BASE + 0x5608)
+#define SCR_PAD1                       (REGISTERS_BASE + 0x560C)
+#define SCR_PAD2                       (REGISTERS_BASE + 0x5610)
+#define SCR_PAD3                       (REGISTERS_BASE + 0x5614)
+#define SCR_PAD4                       (REGISTERS_BASE + 0x5618)
+#define SCR_PAD4_SET                   (REGISTERS_BASE + 0x561C)
+#define SCR_PAD4_CLR                   (REGISTERS_BASE + 0x5620)
+#define SCR_PAD5                       (REGISTERS_BASE + 0x5624)
+#define SCR_PAD5_SET                   (REGISTERS_BASE + 0x5628)
+#define SCR_PAD5_CLR                   (REGISTERS_BASE + 0x562C)
+#define SCR_PAD6                       (REGISTERS_BASE + 0x5630)
+#define SCR_PAD7                       (REGISTERS_BASE + 0x5634)
+#define SCR_PAD8                       (REGISTERS_BASE + 0x5638)
+#define SCR_PAD9                       (REGISTERS_BASE + 0x563C)
+
+/* Spare registers*/
+#define SPARE_A1                       (REGISTERS_BASE + 0x0994)
+#define SPARE_A2                       (REGISTERS_BASE + 0x0998)
+#define SPARE_A3                       (REGISTERS_BASE + 0x099C)
+#define SPARE_A4                       (REGISTERS_BASE + 0x09A0)
+#define SPARE_A5                       (REGISTERS_BASE + 0x09A4)
+#define SPARE_A6                       (REGISTERS_BASE + 0x09A8)
+#define SPARE_A7                       (REGISTERS_BASE + 0x09AC)
+#define SPARE_A8                       (REGISTERS_BASE + 0x09B0)
+#define SPARE_B1                       (REGISTERS_BASE + 0x5420)
+#define SPARE_B2                       (REGISTERS_BASE + 0x5424)
+#define SPARE_B3                       (REGISTERS_BASE + 0x5428)
+#define SPARE_B4                       (REGISTERS_BASE + 0x542C)
+#define SPARE_B5                       (REGISTERS_BASE + 0x5430)
+#define SPARE_B6                       (REGISTERS_BASE + 0x5434)
+#define SPARE_B7                       (REGISTERS_BASE + 0x5438)
+#define SPARE_B8                       (REGISTERS_BASE + 0x543C)
+
+enum wl12xx_acx_int_reg {
+       ACX_REG_INTERRUPT_TRIG,
+       ACX_REG_INTERRUPT_TRIG_H,
+
+/*=============================================
+  Host Interrupt Mask Register - 32bit (RW)
+  ------------------------------------------
+  Setting a bit in this register masks the
+  corresponding interrupt to the host.
+  0 - RX0              - Rx first dubble buffer Data Interrupt
+  1 - TXD              - Tx Data Interrupt
+  2 - TXXFR            - Tx Transfer Interrupt
+  3 - RX1              - Rx second dubble buffer Data Interrupt
+  4 - RXXFR            - Rx Transfer Interrupt
+  5 - EVENT_A  - Event Mailbox interrupt
+  6 - EVENT_B  - Event Mailbox interrupt
+  7 - WNONHST  - Wake On Host Interrupt
+  8 - TRACE_A  - Debug Trace interrupt
+  9 - TRACE_B  - Debug Trace interrupt
+ 10 - CDCMP            - Command Complete Interrupt
+ 11 -
+ 12 -
+ 13 -
+ 14 - ICOMP            - Initialization Complete Interrupt
+ 16 - SG SE            - Soft Gemini - Sense enable interrupt
+ 17 - SG SD            - Soft Gemini - Sense disable interrupt
+ 18 -                  -
+ 19 -                  -
+ 20 -                  -
+ 21-                   -
+ Default: 0x0001
+*==============================================*/
+       ACX_REG_INTERRUPT_MASK,
+
+/*=============================================
+  Host Interrupt Mask Set 16bit, (Write only)
+  ------------------------------------------
+ Setting a bit in this register sets
+ the corresponding bin in ACX_HINT_MASK register
+ without effecting the mask
+ state of other bits (0 = no effect).
+==============================================*/
+       ACX_REG_HINT_MASK_SET,
+
+/*=============================================
+  Host Interrupt Mask Clear 16bit,(Write only)
+  ------------------------------------------
+ Setting a bit in this register clears
+ the corresponding bin in ACX_HINT_MASK register
+ without effecting the mask
+ state of other bits (0 = no effect).
+=============================================*/
+       ACX_REG_HINT_MASK_CLR,
+
+/*=============================================
+  Host Interrupt Status Nondestructive Read
+  16bit,(Read only)
+  ------------------------------------------
+ The host can read this register to determine
+ which interrupts are active.
+ Reading this register doesn't
+ effect its content.
+=============================================*/
+       ACX_REG_INTERRUPT_NO_CLEAR,
+
+/*=============================================
+  Host Interrupt Status Clear on Read  Register
+  16bit,(Read only)
+  ------------------------------------------
+ The host can read this register to determine
+ which interrupts are active.
+ Reading this register clears it,
+ thus making all interrupts inactive.
+==============================================*/
+       ACX_REG_INTERRUPT_CLEAR,
+
+/*=============================================
+  Host Interrupt Acknowledge Register
+  16bit,(Write only)
+  ------------------------------------------
+ The host can set individual bits in this
+ register to clear (acknowledge) the corresp.
+ interrupt status bits in the HINT_STS_CLR and
+ HINT_STS_ND registers, thus making the
+ assotiated interrupt inactive. (0-no effect)
+==============================================*/
+       ACX_REG_INTERRUPT_ACK,
+
+/*===============================================
+   Host Software Reset - 32bit RW
+ ------------------------------------------
+    [31:1] Reserved
+    0  SOFT_RESET Soft Reset  - When this bit is set,
+    it holds the Wlan hardware in a soft reset state.
+    This reset disables all MAC and baseband processor
+    clocks except the CardBus/PCI interface clock.
+    It also initializes all MAC state machines except
+    the host interface. It does not reload the
+    contents of the EEPROM. When this bit is cleared
+    (not self-clearing), the Wlan hardware
+    exits the software reset state.
+===============================================*/
+       ACX_REG_SLV_SOFT_RESET,
+
+/*===============================================
+ EEPROM Burst Read Start  - 32bit RW
+ ------------------------------------------
+ [31:1] Reserved
+ 0  ACX_EE_START -  EEPROM Burst Read Start 0
+ Setting this bit starts a burst read from
+ the external EEPROM.
+ If this bit is set (after reset) before an EEPROM read/write,
+ the burst read starts at EEPROM address 0.
+ Otherwise, it starts at the address
+ following the address of the previous access.
+ TheWlan hardware hardware clears this bit automatically.
+
+ Default: 0x00000000
+*================================================*/
+       ACX_REG_EE_START,
+
+/* Embedded ARM CPU Control */
+
+/*===============================================
+ Halt eCPU   - 32bit RW
+ ------------------------------------------
+ 0 HALT_ECPU Halt Embedded CPU - This bit is the
+ compliment of bit 1 (MDATA2) in the SOR_CFG register.
+ During a hardware reset, this bit holds
+ the inverse of MDATA2.
+ When downloading firmware from the host,
+ set this bit (pull down MDATA2).
+ The host clears this bit after downloading the firmware into
+ zero-wait-state SSRAM.
+ When loading firmware from Flash, clear this bit (pull up MDATA2)
+ so that the eCPU can run the bootloader code in Flash
+ HALT_ECPU eCPU State
+ --------------------
+ 1 halt eCPU
+ 0 enable eCPU
+ ===============================================*/
+       ACX_REG_ECPU_CONTROL,
+
+       ACX_REG_TABLE_LEN
+};
+
+#define ACX_SLV_SOFT_RESET_BIT   BIT(0)
+#define ACX_REG_EEPROM_START_BIT BIT(0)
+
+/* Command/Information Mailbox Pointers */
+
+/*===============================================
+  Command Mailbox Pointer - 32bit RW
+ ------------------------------------------
+ This register holds the start address of
+ the command mailbox located in the Wlan hardware memory.
+ The host must read this pointer after a reset to
+ find the location of the command mailbox.
+ The Wlan hardware initializes the command mailbox
+ pointer with the default address of the command mailbox.
+ The command mailbox pointer is not valid until after
+ the host receives the Init Complete interrupt from
+ the Wlan hardware.
+ ===============================================*/
+#define REG_COMMAND_MAILBOX_PTR                                (SCR_PAD0)
+
+/*===============================================
+  Information Mailbox Pointer - 32bit RW
+ ------------------------------------------
+ This register holds the start address of
+ the information mailbox located in the Wlan hardware memory.
+ The host must read this pointer after a reset to find
+ the location of the information mailbox.
+ The Wlan hardware initializes the information mailbox pointer
+ with the default address of the information mailbox.
+ The information mailbox pointer is not valid
+ until after the host receives the Init Complete interrupt from
+ the Wlan hardware.
+ ===============================================*/
+#define REG_EVENT_MAILBOX_PTR                          (SCR_PAD1)
+
+
+/* Misc */
+
+#define REG_ENABLE_TX_RX                               (ENABLE)
+/*
+ * Rx configuration (filter) information element
+ * ---------------------------------------------
+ */
+#define REG_RX_CONFIG                          (RX_CFG)
+#define REG_RX_FILTER                          (RX_FILTER_CFG)
+
+
+#define RX_CFG_ENABLE_PHY_HEADER_PLCP   0x0002
+
+/* promiscuous - receives all valid frames */
+#define RX_CFG_PROMISCUOUS              0x0008
+
+/* receives frames from any BSSID */
+#define RX_CFG_BSSID                    0x0020
+
+/* receives frames destined to any MAC address */
+#define RX_CFG_MAC                      0x0010
+
+#define RX_CFG_ENABLE_ONLY_MY_DEST_MAC  0x0010
+#define RX_CFG_ENABLE_ANY_DEST_MAC      0x0000
+#define RX_CFG_ENABLE_ONLY_MY_BSSID     0x0020
+#define RX_CFG_ENABLE_ANY_BSSID                 0x0000
+
+/* discards all broadcast frames */
+#define RX_CFG_DISABLE_BCAST            0x0200
+
+#define RX_CFG_ENABLE_ONLY_MY_SSID      0x0400
+#define RX_CFG_ENABLE_RX_CMPLT_FCS_ERROR 0x0800
+#define RX_CFG_COPY_RX_STATUS           0x2000
+#define RX_CFG_TSF                      0x10000
+
+#define RX_CONFIG_OPTION_ANY_DST_MY_BSS         (RX_CFG_ENABLE_ANY_DEST_MAC | \
+                                         RX_CFG_ENABLE_ONLY_MY_BSSID)
+
+#define RX_CONFIG_OPTION_MY_DST_ANY_BSS         (RX_CFG_ENABLE_ONLY_MY_DEST_MAC\
+                                         | RX_CFG_ENABLE_ANY_BSSID)
+
+#define RX_CONFIG_OPTION_ANY_DST_ANY_BSS (RX_CFG_ENABLE_ANY_DEST_MAC | \
+                                         RX_CFG_ENABLE_ANY_BSSID)
+
+#define RX_CONFIG_OPTION_MY_DST_MY_BSS  (RX_CFG_ENABLE_ONLY_MY_DEST_MAC\
+                                         | RX_CFG_ENABLE_ONLY_MY_BSSID)
+
+#define RX_CONFIG_OPTION_FOR_SCAN  (RX_CFG_ENABLE_PHY_HEADER_PLCP \
+                                   | RX_CFG_ENABLE_RX_CMPLT_FCS_ERROR \
+                                   | RX_CFG_COPY_RX_STATUS | RX_CFG_TSF)
+
+#define RX_CONFIG_OPTION_FOR_MEASUREMENT (RX_CFG_ENABLE_ANY_DEST_MAC)
+
+#define RX_CONFIG_OPTION_FOR_JOIN       (RX_CFG_ENABLE_ONLY_MY_BSSID | \
+                                         RX_CFG_ENABLE_ONLY_MY_DEST_MAC)
+
+#define RX_CONFIG_OPTION_FOR_IBSS_JOIN   (RX_CFG_ENABLE_ONLY_MY_SSID | \
+                                         RX_CFG_ENABLE_ONLY_MY_DEST_MAC)
+
+#define RX_FILTER_OPTION_DEF         (CFG_RX_MGMT_EN | CFG_RX_DATA_EN\
+                                      | CFG_RX_CTL_EN | CFG_RX_BCN_EN\
+                                      | CFG_RX_AUTH_EN | CFG_RX_ASSOC_EN)
+
+#define RX_FILTER_OPTION_FILTER_ALL     0
+
+#define RX_FILTER_OPTION_DEF_PRSP_BCN  (CFG_RX_PRSP_EN | CFG_RX_MGMT_EN\
+                                       | CFG_RX_RCTS_ACK | CFG_RX_BCN_EN)
+
+#define RX_FILTER_OPTION_JOIN       (CFG_RX_MGMT_EN | CFG_RX_DATA_EN\
+                                     | CFG_RX_BCN_EN | CFG_RX_AUTH_EN\
+                                     | CFG_RX_ASSOC_EN | CFG_RX_RCTS_ACK\
+                                     | CFG_RX_PRSP_EN)
+
+
+/*===============================================
+ EEPROM Read/Write Request 32bit RW
+ ------------------------------------------
+ 1 EE_READ - EEPROM Read Request 1 - Setting this bit
+ loads a single byte of data into the EE_DATA
+ register from the EEPROM location specified in
+ the EE_ADDR register.
+ The Wlan hardware hardware clears this bit automatically.
+ EE_DATA is valid when this bit is cleared.
+
+ 0 EE_WRITE  - EEPROM Write Request  - Setting this bit
+ writes a single byte of data from the EE_DATA register into the
+ EEPROM location specified in the EE_ADDR register.
+ The Wlan hardware hardware clears this bit automatically.
+*===============================================*/
+#define EE_CTL                              (REGISTERS_BASE + 0x2000)
+#define ACX_EE_CTL_REG                      EE_CTL
+#define EE_WRITE                            0x00000001ul
+#define EE_READ                             0x00000002ul
+
+/*===============================================
+  EEPROM Address  - 32bit RW
+  ------------------------------------------
+  This register specifies the address
+  within the EEPROM from/to which to read/write data.
+  ===============================================*/
+#define EE_ADDR                             (REGISTERS_BASE + 0x2008)
+#define ACX_EE_ADDR_REG                     EE_ADDR
+
+/*===============================================
+  EEPROM Data  - 32bit RW
+  ------------------------------------------
+  This register either holds the read 8 bits of
+  data from the EEPROM or the write data
+  to be written to the EEPROM.
+  ===============================================*/
+#define EE_DATA                             (REGISTERS_BASE + 0x2004)
+#define ACX_EE_DATA_REG                     EE_DATA
+
+#define EEPROM_ACCESS_TO                    10000   /* timeout counter */
+#define START_EEPROM_MGR                    0x00000001
+
+/*===============================================
+  EEPROM Base Address  - 32bit RW
+  ------------------------------------------
+  This register holds the upper nine bits
+  [23:15] of the 24-bit Wlan hardware memory
+  address for burst reads from EEPROM accesses.
+  The EEPROM provides the lower 15 bits of this address.
+  The MSB of the address from the EEPROM is ignored.
+  ===============================================*/
+#define ACX_EE_CFG                          EE_CFG
+
+/*===============================================
+  GPIO Output Values  -32bit, RW
+  ------------------------------------------
+  [31:16]  Reserved
+  [15: 0]  Specify the output values (at the output driver inputs) for
+  GPIO[15:0], respectively.
+  ===============================================*/
+#define ACX_GPIO_OUT_REG            GPIO_OUT
+#define ACX_MAX_GPIO_LINES          15
+
+/*===============================================
+  Contention window  -32bit, RW
+  ------------------------------------------
+  [31:26]  Reserved
+  [25:16]  Max (0x3ff)
+  [15:07]  Reserved
+  [06:00]  Current contention window value - default is 0x1F
+  ===============================================*/
+#define ACX_CONT_WIND_CFG_REG    CONT_WIND_CFG
+#define ACX_CONT_WIND_MIN_MASK   0x0000007f
+#define ACX_CONT_WIND_MAX        0x03ff0000
+
+/*===============================================
+  HI_CFG Interface Configuration Register Values
+  ------------------------------------------
+  ===============================================*/
+#define HI_CFG_UART_ENABLE          0x00000004
+#define HI_CFG_RST232_ENABLE        0x00000008
+#define HI_CFG_CLOCK_REQ_SELECT     0x00000010
+#define HI_CFG_HOST_INT_ENABLE      0x00000020
+#define HI_CFG_VLYNQ_OUTPUT_ENABLE  0x00000040
+#define HI_CFG_HOST_INT_ACTIVE_LOW  0x00000080
+#define HI_CFG_UART_TX_OUT_GPIO_15  0x00000100
+#define HI_CFG_UART_TX_OUT_GPIO_14  0x00000200
+#define HI_CFG_UART_TX_OUT_GPIO_7   0x00000400
+
+/*
+ * NOTE: USE_ACTIVE_HIGH compilation flag should be defined in makefile
+ *       for platforms using active high interrupt level
+ */
+#ifdef USE_ACTIVE_HIGH
+#define HI_CFG_DEF_VAL              \
+       (HI_CFG_UART_ENABLE |        \
+       HI_CFG_RST232_ENABLE |      \
+       HI_CFG_CLOCK_REQ_SELECT |   \
+       HI_CFG_HOST_INT_ENABLE)
+#else
+#define HI_CFG_DEF_VAL              \
+       (HI_CFG_UART_ENABLE |        \
+       HI_CFG_RST232_ENABLE |      \
+       HI_CFG_CLOCK_REQ_SELECT |   \
+       HI_CFG_HOST_INT_ENABLE)
+
+#endif
+
+#define REF_FREQ_19_2                       0
+#define REF_FREQ_26_0                       1
+#define REF_FREQ_38_4                       2
+#define REF_FREQ_40_0                       3
+#define REF_FREQ_33_6                       4
+#define REF_FREQ_NUM                        5
+
+#define LUT_PARAM_INTEGER_DIVIDER           0
+#define LUT_PARAM_FRACTIONAL_DIVIDER        1
+#define LUT_PARAM_ATTN_BB                   2
+#define LUT_PARAM_ALPHA_BB                  3
+#define LUT_PARAM_STOP_TIME_BB              4
+#define LUT_PARAM_BB_PLL_LOOP_FILTER        5
+#define LUT_PARAM_NUM                       6
+
+#define ACX_EEPROMLESS_IND_REG              (SCR_PAD4)
+#define USE_EEPROM                          0
+#define SOFT_RESET_MAX_TIME                 1000000
+#define SOFT_RESET_STALL_TIME               1000
+#define NVS_DATA_BUNDARY_ALIGNMENT          4
+
+
+/* Firmware image load chunk size */
+#define CHUNK_SIZE          512
+
+/* Firmware image header size */
+#define FW_HDR_SIZE 8
+
+#define ECPU_CONTROL_HALT                                      0x00000101
+
+
+/******************************************************************************
+
+    CHANNELS, BAND & REG DOMAINS definitions
+
+******************************************************************************/
+
+
+enum {
+       RADIO_BAND_2_4GHZ = 0,  /* 2.4 Ghz band */
+       RADIO_BAND_5GHZ = 1,    /* 5 Ghz band */
+       RADIO_BAND_JAPAN_4_9_GHZ = 2,
+       DEFAULT_BAND = RADIO_BAND_2_4GHZ,
+       INVALID_BAND = 0xFE,
+       MAX_RADIO_BANDS = 0xFF
+};
+
+enum {
+       NO_RATE      = 0,
+       RATE_1MBPS   = 0x0A,
+       RATE_2MBPS   = 0x14,
+       RATE_5_5MBPS = 0x37,
+       RATE_6MBPS   = 0x0B,
+       RATE_9MBPS   = 0x0F,
+       RATE_11MBPS  = 0x6E,
+       RATE_12MBPS  = 0x0A,
+       RATE_18MBPS  = 0x0E,
+       RATE_22MBPS  = 0xDC,
+       RATE_24MBPS  = 0x09,
+       RATE_36MBPS  = 0x0D,
+       RATE_48MBPS  = 0x08,
+       RATE_54MBPS  = 0x0C
+};
+
+enum {
+       RATE_INDEX_1MBPS   =  0,
+       RATE_INDEX_2MBPS   =  1,
+       RATE_INDEX_5_5MBPS =  2,
+       RATE_INDEX_6MBPS   =  3,
+       RATE_INDEX_9MBPS   =  4,
+       RATE_INDEX_11MBPS  =  5,
+       RATE_INDEX_12MBPS  =  6,
+       RATE_INDEX_18MBPS  =  7,
+       RATE_INDEX_22MBPS  =  8,
+       RATE_INDEX_24MBPS  =  9,
+       RATE_INDEX_36MBPS  =  10,
+       RATE_INDEX_48MBPS  =  11,
+       RATE_INDEX_54MBPS  =  12,
+       RATE_INDEX_MAX     =  RATE_INDEX_54MBPS,
+       MAX_RATE_INDEX,
+       INVALID_RATE_INDEX = MAX_RATE_INDEX,
+       RATE_INDEX_ENUM_MAX_SIZE = 0x7FFFFFFF
+};
+
+enum {
+       RATE_MASK_1MBPS = 0x1,
+       RATE_MASK_2MBPS = 0x2,
+       RATE_MASK_5_5MBPS = 0x4,
+       RATE_MASK_11MBPS = 0x20,
+};
+
+#define SHORT_PREAMBLE_BIT   BIT(0) /* CCK or Barker depending on the rate */
+#define OFDM_RATE_BIT        BIT(6)
+#define PBCC_RATE_BIT        BIT(7)
+
+enum {
+       CCK_LONG = 0,
+       CCK_SHORT = SHORT_PREAMBLE_BIT,
+       PBCC_LONG = PBCC_RATE_BIT,
+       PBCC_SHORT = PBCC_RATE_BIT | SHORT_PREAMBLE_BIT,
+       OFDM = OFDM_RATE_BIT
+};
+
+/******************************************************************************
+
+Transmit-Descriptor RATE-SET field definitions...
+
+Define a new "Rate-Set" for TX path that incorporates the
+Rate & Modulation info into a single 16-bit field.
+
+TxdRateSet_t:
+b15   - Indicates Preamble type (1=SHORT, 0=LONG).
+       Notes:
+       Must be LONG (0) for 1Mbps rate.
+       Does not apply (set to 0) for RevG-OFDM rates.
+b14   - Indicates PBCC encoding (1=PBCC, 0=not).
+       Notes:
+       Does not apply (set to 0) for rates 1 and 2 Mbps.
+       Does not apply (set to 0) for RevG-OFDM rates.
+b13    - Unused (set to 0).
+b12-b0 - Supported Rate indicator bits as defined below.
+
+******************************************************************************/
+
+
+/*************************************************************************
+
+    Interrupt Trigger Register (Host -> WiLink)
+
+**************************************************************************/
+
+/* Hardware to Embedded CPU Interrupts - first 32-bit register set */
+
+/*
+ * Host Command Interrupt. Setting this bit masks
+ * the interrupt that the host issues to inform
+ * the FW that it has sent a command
+ * to the Wlan hardware Command Mailbox.
+ */
+#define INTR_TRIG_CMD       BIT(0)
+
+/*
+ * Host Event Acknowlegde Interrupt. The host
+ * sets this bit to acknowledge that it received
+ * the unsolicited information from the event
+ * mailbox.
+ */
+#define INTR_TRIG_EVENT_ACK BIT(1)
+
+/*
+ * The host sets this bit to inform the Wlan
+ * FW that a TX packet is in the XFER
+ * Buffer #0.
+ */
+#define INTR_TRIG_TX_PROC0 BIT(2)
+
+/*
+ * The host sets this bit to inform the FW
+ * that it read a packet from RX XFER
+ * Buffer #0.
+ */
+#define INTR_TRIG_RX_PROC0 BIT(3)
+
+#define INTR_TRIG_DEBUG_ACK BIT(4)
+
+#define INTR_TRIG_STATE_CHANGED BIT(5)
+
+
+/* Hardware to Embedded CPU Interrupts - second 32-bit register set */
+
+/*
+ * The host sets this bit to inform the FW
+ * that it read a packet from RX XFER
+ * Buffer #1.
+ */
+#define INTR_TRIG_RX_PROC1 BIT(17)
+
+/*
+ * The host sets this bit to inform the Wlan
+ * hardware that a TX packet is in the XFER
+ * Buffer #1.
+ */
+#define INTR_TRIG_TX_PROC1 BIT(18)
+
+#endif
diff --git a/drivers/net/wireless/wl1251/rx.c b/drivers/net/wireless/wl1251/rx.c
new file mode 100644 (file)
index 0000000..efa5360
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+ * This file is part of wl1251
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 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 St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/skbuff.h>
+#include <linux/gfp.h>
+#include <net/mac80211.h>
+
+#include "wl1251.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)
+{
+       u32 rx_packet_ring_addr;
+
+       rx_packet_ring_addr = wl->data_path->rx_packet_ring_addr;
+       if (wl->rx_current_buffer)
+               rx_packet_ring_addr += wl->data_path->rx_packet_ring_chunk_size;
+
+       wl1251_mem_read(wl, rx_packet_ring_addr, desc, sizeof(*desc));
+}
+
+static void wl1251_rx_status(struct wl1251 *wl,
+                            struct wl1251_rx_descriptor *desc,
+                            struct ieee80211_rx_status *status,
+                            u8 beacon)
+{
+       u64 mactime;
+       int ret;
+
+       memset(status, 0, sizeof(struct ieee80211_rx_status));
+
+       status->band = IEEE80211_BAND_2GHZ;
+       status->mactime = desc->timestamp;
+
+       /*
+        * The rx status timestamp is a 32 bits value while the TSF is a
+        * 64 bits one.
+        * For IBSS merging, TSF is mandatory, so we have to get it
+        * somehow, so we ask for ACX_TSF_INFO.
+        * That could be moved to the get_tsf() hook, but unfortunately,
+        * this one must be atomic, while our SPI routines can sleep.
+        */
+       if ((wl->bss_type == BSS_TYPE_IBSS) && beacon) {
+               ret = wl1251_acx_tsf_info(wl, &mactime);
+               if (ret == 0)
+                       status->mactime = mactime;
+       }
+
+       status->signal = desc->rssi;
+
+       /*
+        * FIXME: guessing that snr needs to be divided by two, otherwise
+        * the values don't make any sense
+        */
+       wl->noise = desc->rssi - desc->snr / 2;
+
+       status->freq = ieee80211_channel_to_frequency(desc->channel);
+
+       status->flag |= RX_FLAG_TSFT;
+
+       if (desc->flags & RX_DESC_ENCRYPTION_MASK) {
+               status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED;
+
+               if (likely(!(desc->flags & RX_DESC_DECRYPT_FAIL)))
+                       status->flag |= RX_FLAG_DECRYPTED;
+
+               if (unlikely(desc->flags & RX_DESC_MIC_FAIL))
+                       status->flag |= RX_FLAG_MMIC_ERROR;
+       }
+
+       if (unlikely(!(desc->flags & RX_DESC_VALID_FCS)))
+               status->flag |= RX_FLAG_FAILED_FCS_CRC;
+
+
+       /* FIXME: set status->rate_idx */
+}
+
+static void wl1251_rx_body(struct wl1251 *wl,
+                          struct wl1251_rx_descriptor *desc)
+{
+       struct sk_buff *skb;
+       struct ieee80211_rx_status status;
+       u8 *rx_buffer, beacon = 0;
+       u16 length, *fc;
+       u32 curr_id, last_id_inc, rx_packet_ring_addr;
+
+       length = WL1251_RX_ALIGN(desc->length  - PLCP_HEADER_LENGTH);
+       curr_id = (desc->flags & RX_DESC_SEQNUM_MASK) >> RX_DESC_PACKETID_SHIFT;
+       last_id_inc = (wl->rx_last_id + 1) % (RX_MAX_PACKET_ID + 1);
+
+       if (last_id_inc != curr_id) {
+               wl1251_warning("curr ID:%d, last ID inc:%d",
+                              curr_id, last_id_inc);
+               wl->rx_last_id = curr_id;
+       } else {
+               wl->rx_last_id = last_id_inc;
+       }
+
+       rx_packet_ring_addr = wl->data_path->rx_packet_ring_addr +
+               sizeof(struct wl1251_rx_descriptor) + 20;
+       if (wl->rx_current_buffer)
+               rx_packet_ring_addr += wl->data_path->rx_packet_ring_chunk_size;
+
+       skb = __dev_alloc_skb(length, GFP_KERNEL);
+       if (!skb) {
+               wl1251_error("Couldn't allocate RX frame");
+               return;
+       }
+
+       rx_buffer = skb_put(skb, length);
+       wl1251_mem_read(wl, rx_packet_ring_addr, rx_buffer, length);
+
+       /* The actual lenght doesn't include the target's alignment */
+       skb->len = desc->length  - PLCP_HEADER_LENGTH;
+
+       fc = (u16 *)skb->data;
+
+       if ((*fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON)
+               beacon = 1;
+
+       wl1251_rx_status(wl, desc, &status, beacon);
+
+       wl1251_debug(DEBUG_RX, "rx skb 0x%p: %d B %s", skb, skb->len,
+                    beacon ? "beacon" : "");
+
+       memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
+       ieee80211_rx_ni(wl->hw, skb);
+}
+
+static void wl1251_rx_ack(struct wl1251 *wl)
+{
+       u32 data, addr;
+
+       if (wl->rx_current_buffer) {
+               addr = ACX_REG_INTERRUPT_TRIG_H;
+               data = INTR_TRIG_RX_PROC1;
+       } else {
+               addr = ACX_REG_INTERRUPT_TRIG;
+               data = INTR_TRIG_RX_PROC0;
+       }
+
+       wl1251_reg_write32(wl, addr, data);
+
+       /* Toggle buffer ring */
+       wl->rx_current_buffer = !wl->rx_current_buffer;
+}
+
+
+void wl1251_rx(struct wl1251 *wl)
+{
+       struct wl1251_rx_descriptor *rx_desc;
+
+       if (wl->state != WL1251_STATE_ON)
+               return;
+
+       rx_desc = wl->rx_descriptor;
+
+       /* We first read the frame's header */
+       wl1251_rx_header(wl, rx_desc);
+
+       /* Now we can read the body */
+       wl1251_rx_body(wl, rx_desc);
+
+       /* Finally, we need to ACK the RX */
+       wl1251_rx_ack(wl);
+}
diff --git a/drivers/net/wireless/wl1251/rx.h b/drivers/net/wireless/wl1251/rx.h
new file mode 100644 (file)
index 0000000..4448f63
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * This file is part of wl1251
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 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 St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __WL1251_RX_H__
+#define __WL1251_RX_H__
+
+#include <linux/bitops.h>
+
+#include "wl1251.h"
+
+/*
+ * RX PATH
+ *
+ * The Rx path uses a double buffer and an rx_contro structure, each located
+ * at a fixed address in the device memory. The host keeps track of which
+ * buffer is available and alternates between them on a per packet basis.
+ * The size of each of the two buffers is large enough to hold the longest
+ * 802.3 packet.
+ * The RX path goes like that:
+ * 1) The target generates an interrupt each time a new packet is received.
+ *   There are 2 RX interrupts, one for each buffer.
+ * 2) The host reads the received packet from one of the double buffers.
+ * 3) The host triggers a target interrupt.
+ * 4) The target prepares the next RX packet.
+ */
+
+#define WL1251_RX_MAX_RSSI -30
+#define WL1251_RX_MIN_RSSI -95
+
+#define WL1251_RX_ALIGN_TO 4
+#define WL1251_RX_ALIGN(len) (((len) + WL1251_RX_ALIGN_TO - 1) & \
+                            ~(WL1251_RX_ALIGN_TO - 1))
+
+#define SHORT_PREAMBLE_BIT   BIT(0)
+#define OFDM_RATE_BIT        BIT(6)
+#define PBCC_RATE_BIT        BIT(7)
+
+#define PLCP_HEADER_LENGTH 8
+#define RX_DESC_PACKETID_SHIFT 11
+#define RX_MAX_PACKET_ID 3
+
+#define RX_DESC_VALID_FCS         0x0001
+#define RX_DESC_MATCH_RXADDR1     0x0002
+#define RX_DESC_MCAST             0x0004
+#define RX_DESC_STAINTIM          0x0008
+#define RX_DESC_VIRTUAL_BM        0x0010
+#define RX_DESC_BCAST             0x0020
+#define RX_DESC_MATCH_SSID        0x0040
+#define RX_DESC_MATCH_BSSID       0x0080
+#define RX_DESC_ENCRYPTION_MASK   0x0300
+#define RX_DESC_MEASURMENT        0x0400
+#define RX_DESC_SEQNUM_MASK       0x1800
+#define        RX_DESC_MIC_FAIL          0x2000
+#define        RX_DESC_DECRYPT_FAIL      0x4000
+
+struct wl1251_rx_descriptor {
+       u32 timestamp; /* In microseconds */
+       u16 length; /* Paylod length, including headers */
+       u16 flags;
+
+       /*
+        * 0 - 802.11
+        * 1 - 802.3
+        * 2 - IP
+        * 3 - Raw Codec
+        */
+       u8 type;
+
+       /*
+        * Received Rate:
+        * 0x0A - 1MBPS
+        * 0x14 - 2MBPS
+        * 0x37 - 5_5MBPS
+        * 0x0B - 6MBPS
+        * 0x0F - 9MBPS
+        * 0x6E - 11MBPS
+        * 0x0A - 12MBPS
+        * 0x0E - 18MBPS
+        * 0xDC - 22MBPS
+        * 0x09 - 24MBPS
+        * 0x0D - 36MBPS
+        * 0x08 - 48MBPS
+        * 0x0C - 54MBPS
+        */
+       u8 rate;
+
+       u8 mod_pre; /* Modulation and preamble */
+       u8 channel;
+
+       /*
+        * 0 - 2.4 Ghz
+        * 1 - 5 Ghz
+        */
+       u8 band;
+
+       s8 rssi; /* in dB */
+       u8 rcpi; /* in dB */
+       u8 snr; /* in dB */
+} __packed;
+
+void wl1251_rx(struct wl1251 *wl);
+
+#endif
diff --git a/drivers/net/wireless/wl1251/sdio.c b/drivers/net/wireless/wl1251/sdio.c
new file mode 100644 (file)
index 0000000..74ba9ce
--- /dev/null
@@ -0,0 +1,342 @@
+/*
+ * wl12xx SDIO routines
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 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 St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ * Copyright (C) 2005 Texas Instruments Incorporated
+ * Copyright (C) 2008 Google Inc
+ * Copyright (C) 2009 Bob Copeland (me@bobcopeland.com)
+ */
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/mmc/sdio_func.h>
+#include <linux/mmc/sdio_ids.h>
+#include <linux/platform_device.h>
+#include <linux/wl12xx.h>
+#include <linux/irq.h>
+
+#include "wl1251.h"
+
+#ifndef SDIO_VENDOR_ID_TI
+#define SDIO_VENDOR_ID_TI              0x104c
+#endif
+
+#ifndef SDIO_DEVICE_ID_TI_WL1251
+#define SDIO_DEVICE_ID_TI_WL1251       0x9066
+#endif
+
+struct wl1251_sdio {
+       struct sdio_func *func;
+       u32 elp_val;
+};
+
+static struct wl12xx_platform_data *wl12xx_board_data;
+
+static struct sdio_func *wl_to_func(struct wl1251 *wl)
+{
+       struct wl1251_sdio *wl_sdio = wl->if_priv;
+       return wl_sdio->func;
+}
+
+static void wl1251_sdio_interrupt(struct sdio_func *func)
+{
+       struct wl1251 *wl = sdio_get_drvdata(func);
+
+       wl1251_debug(DEBUG_IRQ, "IRQ");
+
+       /* FIXME should be synchronous for sdio */
+       ieee80211_queue_work(wl->hw, &wl->irq_work);
+}
+
+static const struct sdio_device_id wl1251_devices[] = {
+       { SDIO_DEVICE(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1251) },
+       {}
+};
+MODULE_DEVICE_TABLE(sdio, wl1251_devices);
+
+
+static void wl1251_sdio_read(struct wl1251 *wl, int addr,
+                            void *buf, size_t len)
+{
+       int ret;
+       struct sdio_func *func = wl_to_func(wl);
+
+       sdio_claim_host(func);
+       ret = sdio_memcpy_fromio(func, buf, addr, len);
+       if (ret)
+               wl1251_error("sdio read failed (%d)", ret);
+       sdio_release_host(func);
+}
+
+static void wl1251_sdio_write(struct wl1251 *wl, int addr,
+                             void *buf, size_t len)
+{
+       int ret;
+       struct sdio_func *func = wl_to_func(wl);
+
+       sdio_claim_host(func);
+       ret = sdio_memcpy_toio(func, addr, buf, len);
+       if (ret)
+               wl1251_error("sdio write failed (%d)", ret);
+       sdio_release_host(func);
+}
+
+static void wl1251_sdio_read_elp(struct wl1251 *wl, int addr, u32 *val)
+{
+       int ret = 0;
+       struct wl1251_sdio *wl_sdio = wl->if_priv;
+       struct sdio_func *func = wl_sdio->func;
+
+       /*
+        * The hardware only supports RAW (read after write) access for
+        * reading, regular sdio_readb won't work here (it interprets
+        * the unused bits of CMD52 as write data even if we send read
+        * request).
+        */
+       sdio_claim_host(func);
+       *val = sdio_writeb_readb(func, wl_sdio->elp_val, addr, &ret);
+       sdio_release_host(func);
+
+       if (ret)
+               wl1251_error("sdio_readb failed (%d)", ret);
+}
+
+static void wl1251_sdio_write_elp(struct wl1251 *wl, int addr, u32 val)
+{
+       int ret = 0;
+       struct wl1251_sdio *wl_sdio = wl->if_priv;
+       struct sdio_func *func = wl_sdio->func;
+
+       sdio_claim_host(func);
+       sdio_writeb(func, val, addr, &ret);
+       sdio_release_host(func);
+
+       if (ret)
+               wl1251_error("sdio_writeb failed (%d)", ret);
+       else
+               wl_sdio->elp_val = val;
+}
+
+static void wl1251_sdio_reset(struct wl1251 *wl)
+{
+}
+
+static void wl1251_sdio_enable_irq(struct wl1251 *wl)
+{
+       struct sdio_func *func = wl_to_func(wl);
+
+       sdio_claim_host(func);
+       sdio_claim_irq(func, wl1251_sdio_interrupt);
+       sdio_release_host(func);
+}
+
+static void wl1251_sdio_disable_irq(struct wl1251 *wl)
+{
+       struct sdio_func *func = wl_to_func(wl);
+
+       sdio_claim_host(func);
+       sdio_release_irq(func);
+       sdio_release_host(func);
+}
+
+/* Interrupts when using dedicated WLAN_IRQ pin */
+static irqreturn_t wl1251_line_irq(int irq, void *cookie)
+{
+       struct wl1251 *wl = cookie;
+
+       ieee80211_queue_work(wl->hw, &wl->irq_work);
+
+       return IRQ_HANDLED;
+}
+
+static void wl1251_enable_line_irq(struct wl1251 *wl)
+{
+       return enable_irq(wl->irq);
+}
+
+static void wl1251_disable_line_irq(struct wl1251 *wl)
+{
+       return disable_irq(wl->irq);
+}
+
+static void wl1251_sdio_set_power(bool enable)
+{
+}
+
+static struct wl1251_if_operations wl1251_sdio_ops = {
+       .read = wl1251_sdio_read,
+       .write = wl1251_sdio_write,
+       .write_elp = wl1251_sdio_write_elp,
+       .read_elp = wl1251_sdio_read_elp,
+       .reset = wl1251_sdio_reset,
+};
+
+static int wl1251_platform_probe(struct platform_device *pdev)
+{
+       if (pdev->id != -1) {
+               wl1251_error("can only handle single device");
+               return -ENODEV;
+       }
+
+       wl12xx_board_data = pdev->dev.platform_data;
+       return 0;
+}
+
+/*
+ * Dummy platform_driver for passing platform_data to this driver,
+ * until we have a way to pass this through SDIO subsystem or
+ * some other way.
+ */
+static struct platform_driver wl1251_platform_driver = {
+       .driver = {
+               .name   = "wl1251_data",
+               .owner  = THIS_MODULE,
+       },
+       .probe  = wl1251_platform_probe,
+};
+
+static int wl1251_sdio_probe(struct sdio_func *func,
+                            const struct sdio_device_id *id)
+{
+       int ret;
+       struct wl1251 *wl;
+       struct ieee80211_hw *hw;
+       struct wl1251_sdio *wl_sdio;
+
+       hw = wl1251_alloc_hw();
+       if (IS_ERR(hw))
+               return PTR_ERR(hw);
+
+       wl = hw->priv;
+
+       wl_sdio = kzalloc(sizeof(*wl_sdio), GFP_KERNEL);
+       if (wl_sdio == NULL) {
+               ret = -ENOMEM;
+               goto out_free_hw;
+       }
+
+       sdio_claim_host(func);
+       ret = sdio_enable_func(func);
+       if (ret)
+               goto release;
+
+       sdio_set_block_size(func, 512);
+       sdio_release_host(func);
+
+       SET_IEEE80211_DEV(hw, &func->dev);
+       wl_sdio->func = func;
+       wl->if_priv = wl_sdio;
+       wl->if_ops = &wl1251_sdio_ops;
+       wl->set_power = wl1251_sdio_set_power;
+
+       if (wl12xx_board_data != NULL) {
+               wl->set_power = wl12xx_board_data->set_power;
+               wl->irq = wl12xx_board_data->irq;
+               wl->use_eeprom = wl12xx_board_data->use_eeprom;
+       }
+
+       if (wl->irq) {
+               ret = request_irq(wl->irq, wl1251_line_irq, 0, "wl1251", wl);
+               if (ret < 0) {
+                       wl1251_error("request_irq() failed: %d", ret);
+                       goto disable;
+               }
+
+               set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
+               disable_irq(wl->irq);
+
+               wl1251_sdio_ops.enable_irq = wl1251_enable_line_irq;
+               wl1251_sdio_ops.disable_irq = wl1251_disable_line_irq;
+
+               wl1251_info("using dedicated interrupt line");
+       } else {
+               wl1251_sdio_ops.enable_irq = wl1251_sdio_enable_irq;
+               wl1251_sdio_ops.disable_irq = wl1251_sdio_disable_irq;
+
+               wl1251_info("using SDIO interrupt");
+       }
+
+       ret = wl1251_init_ieee80211(wl);
+       if (ret)
+               goto out_free_irq;
+
+       sdio_set_drvdata(func, wl);
+       return ret;
+
+out_free_irq:
+       if (wl->irq)
+               free_irq(wl->irq, wl);
+disable:
+       sdio_claim_host(func);
+       sdio_disable_func(func);
+release:
+       sdio_release_host(func);
+       kfree(wl_sdio);
+out_free_hw:
+       wl1251_free_hw(wl);
+       return ret;
+}
+
+static void __devexit wl1251_sdio_remove(struct sdio_func *func)
+{
+       struct wl1251 *wl = sdio_get_drvdata(func);
+       struct wl1251_sdio *wl_sdio = wl->if_priv;
+
+       if (wl->irq)
+               free_irq(wl->irq, wl);
+       kfree(wl_sdio);
+       wl1251_free_hw(wl);
+
+       sdio_claim_host(func);
+       sdio_release_irq(func);
+       sdio_disable_func(func);
+       sdio_release_host(func);
+}
+
+static struct sdio_driver wl1251_sdio_driver = {
+       .name           = "wl1251_sdio",
+       .id_table       = wl1251_devices,
+       .probe          = wl1251_sdio_probe,
+       .remove         = __devexit_p(wl1251_sdio_remove),
+};
+
+static int __init wl1251_sdio_init(void)
+{
+       int err;
+
+       err = platform_driver_register(&wl1251_platform_driver);
+       if (err) {
+               wl1251_error("failed to register platform driver: %d", err);
+               return err;
+       }
+
+       err = sdio_register_driver(&wl1251_sdio_driver);
+       if (err)
+               wl1251_error("failed to register sdio driver: %d", err);
+       return err;
+}
+
+static void __exit wl1251_sdio_exit(void)
+{
+       sdio_unregister_driver(&wl1251_sdio_driver);
+       platform_driver_unregister(&wl1251_platform_driver);
+       wl1251_notice("unloaded");
+}
+
+module_init(wl1251_sdio_init);
+module_exit(wl1251_sdio_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Kalle Valo <kvalo@adurom.com>");
diff --git a/drivers/net/wireless/wl1251/spi.c b/drivers/net/wireless/wl1251/spi.c
new file mode 100644 (file)
index 0000000..88fa8e6
--- /dev/null
@@ -0,0 +1,346 @@
+/*
+ * This file is part of wl1251
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 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 St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/crc7.h>
+#include <linux/spi/spi.h>
+#include <linux/wl12xx.h>
+
+#include "wl1251.h"
+#include "reg.h"
+#include "spi.h"
+
+static irqreturn_t wl1251_irq(int irq, void *cookie)
+{
+       struct wl1251 *wl;
+
+       wl1251_debug(DEBUG_IRQ, "IRQ");
+
+       wl = cookie;
+
+       ieee80211_queue_work(wl->hw, &wl->irq_work);
+
+       return IRQ_HANDLED;
+}
+
+static struct spi_device *wl_to_spi(struct wl1251 *wl)
+{
+       return wl->if_priv;
+}
+
+static void wl1251_spi_reset(struct wl1251 *wl)
+{
+       u8 *cmd;
+       struct spi_transfer t;
+       struct spi_message m;
+
+       cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL);
+       if (!cmd) {
+               wl1251_error("could not allocate cmd for spi reset");
+               return;
+       }
+
+       memset(&t, 0, sizeof(t));
+       spi_message_init(&m);
+
+       memset(cmd, 0xff, WSPI_INIT_CMD_LEN);
+
+       t.tx_buf = cmd;
+       t.len = WSPI_INIT_CMD_LEN;
+       spi_message_add_tail(&t, &m);
+
+       spi_sync(wl_to_spi(wl), &m);
+
+       wl1251_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN);
+}
+
+static void wl1251_spi_wake(struct wl1251 *wl)
+{
+       u8 crc[WSPI_INIT_CMD_CRC_LEN], *cmd;
+       struct spi_transfer t;
+       struct spi_message m;
+
+       cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL);
+       if (!cmd) {
+               wl1251_error("could not allocate cmd for spi init");
+               return;
+       }
+
+       memset(crc, 0, sizeof(crc));
+       memset(&t, 0, sizeof(t));
+       spi_message_init(&m);
+
+       /*
+        * Set WSPI_INIT_COMMAND
+        * the data is being send from the MSB to LSB
+        */
+       cmd[2] = 0xff;
+       cmd[3] = 0xff;
+       cmd[1] = WSPI_INIT_CMD_START | WSPI_INIT_CMD_TX;
+       cmd[0] = 0;
+       cmd[7] = 0;
+       cmd[6] |= HW_ACCESS_WSPI_INIT_CMD_MASK << 3;
+       cmd[6] |= HW_ACCESS_WSPI_FIXED_BUSY_LEN & WSPI_INIT_CMD_FIXEDBUSY_LEN;
+
+       if (HW_ACCESS_WSPI_FIXED_BUSY_LEN == 0)
+               cmd[5] |=  WSPI_INIT_CMD_DIS_FIXEDBUSY;
+       else
+               cmd[5] |= WSPI_INIT_CMD_EN_FIXEDBUSY;
+
+       cmd[5] |= WSPI_INIT_CMD_IOD | WSPI_INIT_CMD_IP | WSPI_INIT_CMD_CS
+               | WSPI_INIT_CMD_WSPI | WSPI_INIT_CMD_WS;
+
+       crc[0] = cmd[1];
+       crc[1] = cmd[0];
+       crc[2] = cmd[7];
+       crc[3] = cmd[6];
+       crc[4] = cmd[5];
+
+       cmd[4] |= crc7(0, crc, WSPI_INIT_CMD_CRC_LEN) << 1;
+       cmd[4] |= WSPI_INIT_CMD_END;
+
+       t.tx_buf = cmd;
+       t.len = WSPI_INIT_CMD_LEN;
+       spi_message_add_tail(&t, &m);
+
+       spi_sync(wl_to_spi(wl), &m);
+
+       wl1251_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN);
+}
+
+static void wl1251_spi_reset_wake(struct wl1251 *wl)
+{
+       wl1251_spi_reset(wl);
+       wl1251_spi_wake(wl);
+}
+
+static void wl1251_spi_read(struct wl1251 *wl, int addr, void *buf,
+                           size_t len)
+{
+       struct spi_transfer t[3];
+       struct spi_message m;
+       u8 *busy_buf;
+       u32 *cmd;
+
+       cmd = &wl->buffer_cmd;
+       busy_buf = wl->buffer_busyword;
+
+       *cmd = 0;
+       *cmd |= WSPI_CMD_READ;
+       *cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
+       *cmd |= addr & WSPI_CMD_BYTE_ADDR;
+
+       spi_message_init(&m);
+       memset(t, 0, sizeof(t));
+
+       t[0].tx_buf = cmd;
+       t[0].len = 4;
+       spi_message_add_tail(&t[0], &m);
+
+       /* Busy and non busy words read */
+       t[1].rx_buf = busy_buf;
+       t[1].len = WL1251_BUSY_WORD_LEN;
+       spi_message_add_tail(&t[1], &m);
+
+       t[2].rx_buf = buf;
+       t[2].len = len;
+       spi_message_add_tail(&t[2], &m);
+
+       spi_sync(wl_to_spi(wl), &m);
+
+       /* FIXME: check busy words */
+
+       wl1251_dump(DEBUG_SPI, "spi_read cmd -> ", cmd, sizeof(*cmd));
+       wl1251_dump(DEBUG_SPI, "spi_read buf <- ", buf, len);
+}
+
+static void wl1251_spi_write(struct wl1251 *wl, int addr, void *buf,
+                            size_t len)
+{
+       struct spi_transfer t[2];
+       struct spi_message m;
+       u32 *cmd;
+
+       cmd = &wl->buffer_cmd;
+
+       *cmd = 0;
+       *cmd |= WSPI_CMD_WRITE;
+       *cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
+       *cmd |= addr & WSPI_CMD_BYTE_ADDR;
+
+       spi_message_init(&m);
+       memset(t, 0, sizeof(t));
+
+       t[0].tx_buf = cmd;
+       t[0].len = sizeof(*cmd);
+       spi_message_add_tail(&t[0], &m);
+
+       t[1].tx_buf = buf;
+       t[1].len = len;
+       spi_message_add_tail(&t[1], &m);
+
+       spi_sync(wl_to_spi(wl), &m);
+
+       wl1251_dump(DEBUG_SPI, "spi_write cmd -> ", cmd, sizeof(*cmd));
+       wl1251_dump(DEBUG_SPI, "spi_write buf -> ", buf, len);
+}
+
+static void wl1251_spi_enable_irq(struct wl1251 *wl)
+{
+       return enable_irq(wl->irq);
+}
+
+static void wl1251_spi_disable_irq(struct wl1251 *wl)
+{
+       return disable_irq(wl->irq);
+}
+
+static const struct wl1251_if_operations wl1251_spi_ops = {
+       .read = wl1251_spi_read,
+       .write = wl1251_spi_write,
+       .reset = wl1251_spi_reset_wake,
+       .enable_irq = wl1251_spi_enable_irq,
+       .disable_irq = wl1251_spi_disable_irq,
+};
+
+static int __devinit wl1251_spi_probe(struct spi_device *spi)
+{
+       struct wl12xx_platform_data *pdata;
+       struct ieee80211_hw *hw;
+       struct wl1251 *wl;
+       int ret;
+
+       pdata = spi->dev.platform_data;
+       if (!pdata) {
+               wl1251_error("no platform data");
+               return -ENODEV;
+       }
+
+       hw = wl1251_alloc_hw();
+       if (IS_ERR(hw))
+               return PTR_ERR(hw);
+
+       wl = hw->priv;
+
+       SET_IEEE80211_DEV(hw, &spi->dev);
+       dev_set_drvdata(&spi->dev, wl);
+       wl->if_priv = spi;
+       wl->if_ops = &wl1251_spi_ops;
+
+       /* This is the only SPI value that we need to set here, the rest
+        * comes from the board-peripherals file */
+       spi->bits_per_word = 32;
+
+       ret = spi_setup(spi);
+       if (ret < 0) {
+               wl1251_error("spi_setup failed");
+               goto out_free;
+       }
+
+       wl->set_power = pdata->set_power;
+       if (!wl->set_power) {
+               wl1251_error("set power function missing in platform data");
+               return -ENODEV;
+       }
+
+       wl->irq = spi->irq;
+       if (wl->irq < 0) {
+               wl1251_error("irq missing in platform data");
+               return -ENODEV;
+       }
+
+       wl->use_eeprom = pdata->use_eeprom;
+
+       ret = request_irq(wl->irq, wl1251_irq, 0, DRIVER_NAME, wl);
+       if (ret < 0) {
+               wl1251_error("request_irq() failed: %d", ret);
+               goto out_free;
+       }
+
+       set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
+
+       disable_irq(wl->irq);
+
+       ret = wl1251_init_ieee80211(wl);
+       if (ret)
+               goto out_irq;
+
+       return 0;
+
+ out_irq:
+       free_irq(wl->irq, wl);
+
+ out_free:
+       ieee80211_free_hw(hw);
+
+       return ret;
+}
+
+static int __devexit wl1251_spi_remove(struct spi_device *spi)
+{
+       struct wl1251 *wl = dev_get_drvdata(&spi->dev);
+
+       free_irq(wl->irq, wl);
+       wl1251_free_hw(wl);
+
+       return 0;
+}
+
+static struct spi_driver wl1251_spi_driver = {
+       .driver = {
+               .name           = DRIVER_NAME,
+               .bus            = &spi_bus_type,
+               .owner          = THIS_MODULE,
+       },
+
+       .probe          = wl1251_spi_probe,
+       .remove         = __devexit_p(wl1251_spi_remove),
+};
+
+static int __init wl1251_spi_init(void)
+{
+       int ret;
+
+       ret = spi_register_driver(&wl1251_spi_driver);
+       if (ret < 0) {
+               wl1251_error("failed to register spi driver: %d", ret);
+               goto out;
+       }
+
+out:
+       return ret;
+}
+
+static void __exit wl1251_spi_exit(void)
+{
+       spi_unregister_driver(&wl1251_spi_driver);
+
+       wl1251_notice("unloaded");
+}
+
+module_init(wl1251_spi_init);
+module_exit(wl1251_spi_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Kalle Valo <kvalo@adurom.com>");
+MODULE_ALIAS("spi:wl1251");
diff --git a/drivers/net/wireless/wl1251/spi.h b/drivers/net/wireless/wl1251/spi.h
new file mode 100644 (file)
index 0000000..16d5069
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * This file is part of wl1251
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 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 St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __WL1251_SPI_H__
+#define __WL1251_SPI_H__
+
+#include "cmd.h"
+#include "acx.h"
+#include "reg.h"
+
+#define WSPI_CMD_READ                 0x40000000
+#define WSPI_CMD_WRITE                0x00000000
+#define WSPI_CMD_FIXED                0x20000000
+#define WSPI_CMD_BYTE_LENGTH          0x1FFE0000
+#define WSPI_CMD_BYTE_LENGTH_OFFSET   17
+#define WSPI_CMD_BYTE_ADDR            0x0001FFFF
+
+#define WSPI_INIT_CMD_CRC_LEN       5
+
+#define WSPI_INIT_CMD_START         0x00
+#define WSPI_INIT_CMD_TX            0x40
+/* the extra bypass bit is sampled by the TNET as '1' */
+#define WSPI_INIT_CMD_BYPASS_BIT    0x80
+#define WSPI_INIT_CMD_FIXEDBUSY_LEN 0x07
+#define WSPI_INIT_CMD_EN_FIXEDBUSY  0x80
+#define WSPI_INIT_CMD_DIS_FIXEDBUSY 0x00
+#define WSPI_INIT_CMD_IOD           0x40
+#define WSPI_INIT_CMD_IP            0x20
+#define WSPI_INIT_CMD_CS            0x10
+#define WSPI_INIT_CMD_WS            0x08
+#define WSPI_INIT_CMD_WSPI          0x01
+#define WSPI_INIT_CMD_END           0x01
+
+#define WSPI_INIT_CMD_LEN           8
+
+#define HW_ACCESS_WSPI_FIXED_BUSY_LEN \
+               ((WL1251_BUSY_WORD_LEN - 4) / sizeof(u32))
+#define HW_ACCESS_WSPI_INIT_CMD_MASK  0
+
+#endif /* __WL1251_SPI_H__ */
diff --git a/drivers/net/wireless/wl1251/tx.c b/drivers/net/wireless/wl1251/tx.c
new file mode 100644 (file)
index 0000000..554b4f9
--- /dev/null
@@ -0,0 +1,570 @@
+/*
+ * This file is part of wl1251
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 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 St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include "wl1251.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)
+{
+       int used, data_in_count;
+
+       data_in_count = wl->data_in_count;
+
+       if (data_in_count < data_out_count)
+               /* data_in_count has wrapped */
+               data_in_count += TX_STATUS_DATA_OUT_COUNT_MASK + 1;
+
+       used = data_in_count - data_out_count;
+
+       WARN_ON(used < 0);
+       WARN_ON(used > DP_TX_PACKET_RING_CHUNK_NUM);
+
+       if (used >= DP_TX_PACKET_RING_CHUNK_NUM)
+               return true;
+       else
+               return false;
+}
+
+static int wl1251_tx_path_status(struct wl1251 *wl)
+{
+       u32 status, addr, data_out_count;
+       bool busy;
+
+       addr = wl->data_path->tx_control_addr;
+       status = wl1251_mem_read32(wl, addr);
+       data_out_count = status & TX_STATUS_DATA_OUT_COUNT_MASK;
+       busy = wl1251_tx_double_buffer_busy(wl, data_out_count);
+
+       if (busy)
+               return -EBUSY;
+
+       return 0;
+}
+
+static int wl1251_tx_id(struct wl1251 *wl, struct sk_buff *skb)
+{
+       int i;
+
+       for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++)
+               if (wl->tx_frames[i] == NULL) {
+                       wl->tx_frames[i] = skb;
+                       return i;
+               }
+
+       return -EBUSY;
+}
+
+static void wl1251_tx_control(struct tx_double_buffer_desc *tx_hdr,
+                             struct ieee80211_tx_info *control, u16 fc)
+{
+       *(u16 *)&tx_hdr->control = 0;
+
+       tx_hdr->control.rate_policy = 0;
+
+       /* 802.11 packets */
+       tx_hdr->control.packet_type = 0;
+
+       if (control->flags & IEEE80211_TX_CTL_NO_ACK)
+               tx_hdr->control.ack_policy = 1;
+
+       tx_hdr->control.tx_complete = 1;
+
+       if ((fc & IEEE80211_FTYPE_DATA) &&
+           ((fc & IEEE80211_STYPE_QOS_DATA) ||
+            (fc & IEEE80211_STYPE_QOS_NULLFUNC)))
+               tx_hdr->control.qos = 1;
+}
+
+/* RSN + MIC = 8 + 8 = 16 bytes (worst case - AES). */
+#define MAX_MSDU_SECURITY_LENGTH      16
+#define MAX_MPDU_SECURITY_LENGTH      16
+#define WLAN_QOS_HDR_LEN              26
+#define MAX_MPDU_HEADER_AND_SECURITY  (MAX_MPDU_SECURITY_LENGTH + \
+                                      WLAN_QOS_HDR_LEN)
+#define HW_BLOCK_SIZE                 252
+static void wl1251_tx_frag_block_num(struct tx_double_buffer_desc *tx_hdr)
+{
+       u16 payload_len, frag_threshold, mem_blocks;
+       u16 num_mpdus, mem_blocks_per_frag;
+
+       frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
+       tx_hdr->frag_threshold = cpu_to_le16(frag_threshold);
+
+       payload_len = le16_to_cpu(tx_hdr->length) + MAX_MSDU_SECURITY_LENGTH;
+
+       if (payload_len > frag_threshold) {
+               mem_blocks_per_frag =
+                       ((frag_threshold + MAX_MPDU_HEADER_AND_SECURITY) /
+                        HW_BLOCK_SIZE) + 1;
+               num_mpdus = payload_len / frag_threshold;
+               mem_blocks = num_mpdus * mem_blocks_per_frag;
+               payload_len -= num_mpdus * frag_threshold;
+               num_mpdus++;
+
+       } else {
+               mem_blocks_per_frag = 0;
+               mem_blocks = 0;
+               num_mpdus = 1;
+       }
+
+       mem_blocks += (payload_len / HW_BLOCK_SIZE) + 1;
+
+       if (num_mpdus > 1)
+               mem_blocks += min(num_mpdus, mem_blocks_per_frag);
+
+       tx_hdr->num_mem_blocks = mem_blocks;
+}
+
+static int wl1251_tx_fill_hdr(struct wl1251 *wl, struct sk_buff *skb,
+                             struct ieee80211_tx_info *control)
+{
+       struct tx_double_buffer_desc *tx_hdr;
+       struct ieee80211_rate *rate;
+       int id;
+       u16 fc;
+
+       if (!skb)
+               return -EINVAL;
+
+       id = wl1251_tx_id(wl, skb);
+       if (id < 0)
+               return id;
+
+       fc = *(u16 *)skb->data;
+       tx_hdr = (struct tx_double_buffer_desc *) skb_push(skb,
+                                                          sizeof(*tx_hdr));
+
+       tx_hdr->length = cpu_to_le16(skb->len - sizeof(*tx_hdr));
+       rate = ieee80211_get_tx_rate(wl->hw, control);
+       tx_hdr->rate = cpu_to_le16(rate->hw_value);
+       tx_hdr->expiry_time = cpu_to_le32(1 << 16);
+       tx_hdr->id = id;
+
+       tx_hdr->xmit_queue = wl1251_tx_get_queue(skb_get_queue_mapping(skb));
+
+       wl1251_tx_control(tx_hdr, control, fc);
+       wl1251_tx_frag_block_num(tx_hdr);
+
+       return 0;
+}
+
+/* We copy the packet to the target */
+static int wl1251_tx_send_packet(struct wl1251 *wl, struct sk_buff *skb,
+                                struct ieee80211_tx_info *control)
+{
+       struct tx_double_buffer_desc *tx_hdr;
+       int len;
+       u32 addr;
+
+       if (!skb)
+               return -EINVAL;
+
+       tx_hdr = (struct tx_double_buffer_desc *) skb->data;
+
+       if (control->control.hw_key &&
+           control->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) {
+               int hdrlen;
+               __le16 fc;
+               u16 length;
+               u8 *pos;
+
+               fc = *(__le16 *)(skb->data + sizeof(*tx_hdr));
+               length = le16_to_cpu(tx_hdr->length) + WL1251_TKIP_IV_SPACE;
+               tx_hdr->length = cpu_to_le16(length);
+
+               hdrlen = ieee80211_hdrlen(fc);
+
+               pos = skb_push(skb, WL1251_TKIP_IV_SPACE);
+               memmove(pos, pos + WL1251_TKIP_IV_SPACE,
+                       sizeof(*tx_hdr) + hdrlen);
+       }
+
+       /* Revisit. This is a workaround for getting non-aligned packets.
+          This happens at least with EAPOL packets from the user space.
+          Our DMA requires packets to be aligned on a 4-byte boundary.
+       */
+       if (unlikely((long)skb->data & 0x03)) {
+               int offset = (4 - (long)skb->data) & 0x03;
+               wl1251_debug(DEBUG_TX, "skb offset %d", offset);
+
+               /* check whether the current skb can be used */
+               if (!skb_cloned(skb) && (skb_tailroom(skb) >= offset)) {
+                       unsigned char *src = skb->data;
+
+                       /* align the buffer on a 4-byte boundary */
+                       skb_reserve(skb, offset);
+                       memmove(skb->data, src, skb->len);
+                       tx_hdr = (struct tx_double_buffer_desc *) skb->data;
+               } else {
+                       wl1251_info("No handler, fixme!");
+                       return -EINVAL;
+               }
+       }
+
+       /* Our skb->data at this point includes the HW header */
+       len = WL1251_TX_ALIGN(skb->len);
+
+       if (wl->data_in_count & 0x1)
+               addr = wl->data_path->tx_packet_ring_addr +
+                       wl->data_path->tx_packet_ring_chunk_size;
+       else
+               addr = wl->data_path->tx_packet_ring_addr;
+
+       wl1251_mem_write(wl, addr, skb->data, len);
+
+       wl1251_debug(DEBUG_TX, "tx id %u skb 0x%p payload %u rate 0x%x "
+                    "queue %d", tx_hdr->id, skb, tx_hdr->length,
+                    tx_hdr->rate, tx_hdr->xmit_queue);
+
+       return 0;
+}
+
+static void wl1251_tx_trigger(struct wl1251 *wl)
+{
+       u32 data, addr;
+
+       if (wl->data_in_count & 0x1) {
+               addr = ACX_REG_INTERRUPT_TRIG_H;
+               data = INTR_TRIG_TX_PROC1;
+       } else {
+               addr = ACX_REG_INTERRUPT_TRIG;
+               data = INTR_TRIG_TX_PROC0;
+       }
+
+       wl1251_reg_write32(wl, addr, data);
+
+       /* Bumping data in */
+       wl->data_in_count = (wl->data_in_count + 1) &
+               TX_STATUS_DATA_OUT_COUNT_MASK;
+}
+
+/* caller must hold wl->mutex */
+static int wl1251_tx_frame(struct wl1251 *wl, struct sk_buff *skb)
+{
+       struct ieee80211_tx_info *info;
+       int ret = 0;
+       u8 idx;
+
+       info = IEEE80211_SKB_CB(skb);
+
+       if (info->control.hw_key) {
+               idx = info->control.hw_key->hw_key_idx;
+               if (unlikely(wl->default_key != idx)) {
+                       ret = wl1251_acx_default_key(wl, idx);
+                       if (ret < 0)
+                               return ret;
+               }
+       }
+
+       ret = wl1251_tx_path_status(wl);
+       if (ret < 0)
+               return ret;
+
+       ret = wl1251_tx_fill_hdr(wl, skb, info);
+       if (ret < 0)
+               return ret;
+
+       ret = wl1251_tx_send_packet(wl, skb, info);
+       if (ret < 0)
+               return ret;
+
+       wl1251_tx_trigger(wl);
+
+       return ret;
+}
+
+void wl1251_tx_work(struct work_struct *work)
+{
+       struct wl1251 *wl = container_of(work, struct wl1251, tx_work);
+       struct sk_buff *skb;
+       bool woken_up = false;
+       int ret;
+
+       mutex_lock(&wl->mutex);
+
+       if (unlikely(wl->state == WL1251_STATE_OFF))
+               goto out;
+
+       while ((skb = skb_dequeue(&wl->tx_queue))) {
+               if (!woken_up) {
+                       ret = wl1251_ps_elp_wakeup(wl);
+                       if (ret < 0)
+                               goto out;
+                       woken_up = true;
+               }
+
+               ret = wl1251_tx_frame(wl, skb);
+               if (ret == -EBUSY) {
+                       skb_queue_head(&wl->tx_queue, skb);
+                       goto out;
+               } else if (ret < 0) {
+                       dev_kfree_skb(skb);
+                       goto out;
+               }
+       }
+
+out:
+       if (woken_up)
+               wl1251_ps_elp_sleep(wl);
+
+       mutex_unlock(&wl->mutex);
+}
+
+static const char *wl1251_tx_parse_status(u8 status)
+{
+       /* 8 bit status field, one character per bit plus null */
+       static char buf[9];
+       int i = 0;
+
+       memset(buf, 0, sizeof(buf));
+
+       if (status & TX_DMA_ERROR)
+               buf[i++] = 'm';
+       if (status & TX_DISABLED)
+               buf[i++] = 'd';
+       if (status & TX_RETRY_EXCEEDED)
+               buf[i++] = 'r';
+       if (status & TX_TIMEOUT)
+               buf[i++] = 't';
+       if (status & TX_KEY_NOT_FOUND)
+               buf[i++] = 'k';
+       if (status & TX_ENCRYPT_FAIL)
+               buf[i++] = 'e';
+       if (status & TX_UNAVAILABLE_PRIORITY)
+               buf[i++] = 'p';
+
+       /* bit 0 is unused apparently */
+
+       return buf;
+}
+
+static void wl1251_tx_packet_cb(struct wl1251 *wl,
+                               struct tx_result *result)
+{
+       struct ieee80211_tx_info *info;
+       struct sk_buff *skb;
+       int hdrlen, ret;
+       u8 *frame;
+
+       skb = wl->tx_frames[result->id];
+       if (skb == NULL) {
+               wl1251_error("SKB for packet %d is NULL", result->id);
+               return;
+       }
+
+       info = IEEE80211_SKB_CB(skb);
+
+       if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
+           (result->status == TX_SUCCESS))
+               info->flags |= IEEE80211_TX_STAT_ACK;
+
+       info->status.rates[0].count = result->ack_failures + 1;
+       wl->stats.retry_count += result->ack_failures;
+
+       /*
+        * We have to remove our private TX header before pushing
+        * the skb back to mac80211.
+        */
+       frame = skb_pull(skb, sizeof(struct tx_double_buffer_desc));
+       if (info->control.hw_key &&
+           info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) {
+               hdrlen = ieee80211_get_hdrlen_from_skb(skb);
+               memmove(frame + WL1251_TKIP_IV_SPACE, frame, hdrlen);
+               skb_pull(skb, WL1251_TKIP_IV_SPACE);
+       }
+
+       wl1251_debug(DEBUG_TX, "tx status id %u skb 0x%p failures %u rate 0x%x"
+                    " status 0x%x (%s)",
+                    result->id, skb, result->ack_failures, result->rate,
+                    result->status, wl1251_tx_parse_status(result->status));
+
+
+       ieee80211_tx_status(wl->hw, skb);
+
+       wl->tx_frames[result->id] = NULL;
+
+       if (wl->tx_queue_stopped) {
+               wl1251_debug(DEBUG_TX, "cb: queue was stopped");
+
+               skb = skb_dequeue(&wl->tx_queue);
+
+               /* The skb can be NULL because tx_work might have been
+                  scheduled before the queue was stopped making the
+                  queue empty */
+
+               if (skb) {
+                       ret = wl1251_tx_frame(wl, skb);
+                       if (ret == -EBUSY) {
+                               /* firmware buffer is still full */
+                               wl1251_debug(DEBUG_TX, "cb: fw buffer "
+                                            "still full");
+                               skb_queue_head(&wl->tx_queue, skb);
+                               return;
+                       } else if (ret < 0) {
+                               dev_kfree_skb(skb);
+                               return;
+                       }
+               }
+
+               wl1251_debug(DEBUG_TX, "cb: waking queues");
+               ieee80211_wake_queues(wl->hw);
+               wl->tx_queue_stopped = false;
+       }
+}
+
+/* Called upon reception of a TX complete interrupt */
+void wl1251_tx_complete(struct wl1251 *wl)
+{
+       int i, result_index, num_complete = 0;
+       struct tx_result result[FW_TX_CMPLT_BLOCK_SIZE], *result_ptr;
+       unsigned long flags;
+
+       if (unlikely(wl->state != WL1251_STATE_ON))
+               return;
+
+       /* First we read the result */
+       wl1251_mem_read(wl, wl->data_path->tx_complete_addr,
+                           result, sizeof(result));
+
+       result_index = wl->next_tx_complete;
+
+       for (i = 0; i < ARRAY_SIZE(result); i++) {
+               result_ptr = &result[result_index];
+
+               if (result_ptr->done_1 == 1 &&
+                   result_ptr->done_2 == 1) {
+                       wl1251_tx_packet_cb(wl, result_ptr);
+
+                       result_ptr->done_1 = 0;
+                       result_ptr->done_2 = 0;
+
+                       result_index = (result_index + 1) &
+                               (FW_TX_CMPLT_BLOCK_SIZE - 1);
+                       num_complete++;
+               } else {
+                       break;
+               }
+       }
+
+       if (wl->tx_queue_stopped
+           &&
+           skb_queue_len(&wl->tx_queue) <= WL1251_TX_QUEUE_LOW_WATERMARK){
+
+               /* firmware buffer has space, restart queues */
+               wl1251_debug(DEBUG_TX, "tx_complete: waking queues");
+               spin_lock_irqsave(&wl->wl_lock, flags);
+               ieee80211_wake_queues(wl->hw);
+               wl->tx_queue_stopped = false;
+               spin_unlock_irqrestore(&wl->wl_lock, flags);
+               ieee80211_queue_work(wl->hw, &wl->tx_work);
+
+       }
+
+       /* Every completed frame needs to be acknowledged */
+       if (num_complete) {
+               /*
+                * If we've wrapped, we have to clear
+                * the results in 2 steps.
+                */
+               if (result_index > wl->next_tx_complete) {
+                       /* Only 1 write is needed */
+                       wl1251_mem_write(wl,
+                                        wl->data_path->tx_complete_addr +
+                                        (wl->next_tx_complete *
+                                         sizeof(struct tx_result)),
+                                        &result[wl->next_tx_complete],
+                                        num_complete *
+                                        sizeof(struct tx_result));
+
+
+               } else if (result_index < wl->next_tx_complete) {
+                       /* 2 writes are needed */
+                       wl1251_mem_write(wl,
+                                        wl->data_path->tx_complete_addr +
+                                        (wl->next_tx_complete *
+                                         sizeof(struct tx_result)),
+                                        &result[wl->next_tx_complete],
+                                        (FW_TX_CMPLT_BLOCK_SIZE -
+                                         wl->next_tx_complete) *
+                                        sizeof(struct tx_result));
+
+                       wl1251_mem_write(wl,
+                                        wl->data_path->tx_complete_addr,
+                                        result,
+                                        (num_complete -
+                                         FW_TX_CMPLT_BLOCK_SIZE +
+                                         wl->next_tx_complete) *
+                                        sizeof(struct tx_result));
+
+               } else {
+                       /* We have to write the whole array */
+                       wl1251_mem_write(wl,
+                                        wl->data_path->tx_complete_addr,
+                                        result,
+                                        FW_TX_CMPLT_BLOCK_SIZE *
+                                        sizeof(struct tx_result));
+               }
+
+       }
+
+       wl->next_tx_complete = result_index;
+}
+
+/* caller must hold wl->mutex */
+void wl1251_tx_flush(struct wl1251 *wl)
+{
+       int i;
+       struct sk_buff *skb;
+       struct ieee80211_tx_info *info;
+
+       /* TX failure */
+/*     control->flags = 0; FIXME */
+
+       while ((skb = skb_dequeue(&wl->tx_queue))) {
+               info = IEEE80211_SKB_CB(skb);
+
+               wl1251_debug(DEBUG_TX, "flushing skb 0x%p", skb);
+
+               if (!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS))
+                               continue;
+
+               ieee80211_tx_status(wl->hw, skb);
+       }
+
+       for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++)
+               if (wl->tx_frames[i] != NULL) {
+                       skb = wl->tx_frames[i];
+                       info = IEEE80211_SKB_CB(skb);
+
+                       if (!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS))
+                               continue;
+
+                       ieee80211_tx_status(wl->hw, skb);
+                       wl->tx_frames[i] = NULL;
+               }
+}
diff --git a/drivers/net/wireless/wl1251/tx.h b/drivers/net/wireless/wl1251/tx.h
new file mode 100644 (file)
index 0000000..81338d3
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+ * This file is part of wl1251
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 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 St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __WL1251_TX_H__
+#define __WL1251_TX_H__
+
+#include <linux/bitops.h>
+#include "acx.h"
+
+/*
+ *
+ * TX PATH
+ *
+ * The Tx path uses a double buffer and a tx_control structure, each located
+ * at a fixed address in the device's memory. On startup, the host retrieves
+ * the pointers to these addresses. A double buffer allows for continuous data
+ * flow towards the device. The host keeps track of which buffer is available
+ * and alternates between these two buffers on a per packet basis.
+ *
+ * The size of each of the two buffers is large enough to hold the longest
+ * 802.3 packet - maximum size Ethernet packet + header + descriptor.
+ * TX complete indication will be received a-synchronously in a TX done cyclic
+ * buffer which is composed of 16 tx_result descriptors structures and is used
+ * in a cyclic manner.
+ *
+ * The TX (HOST) procedure is as follows:
+ * 1. Read the Tx path status, that will give the data_out_count.
+ * 2. goto 1, if not possible.
+ *    i.e. if data_in_count - data_out_count >= HwBuffer size (2 for double
+ *    buffer).
+ * 3. Copy the packet (preceded by double_buffer_desc), if possible.
+ *    i.e. if data_in_count - data_out_count < HwBuffer size (2 for double
+ *    buffer).
+ * 4. increment data_in_count.
+ * 5. Inform the firmware by generating a firmware internal interrupt.
+ * 6. FW will increment data_out_count after it reads the buffer.
+ *
+ * The TX Complete procedure:
+ * 1. To get a TX complete indication the host enables the tx_complete flag in
+ *    the TX descriptor Structure.
+ * 2. For each packet with a Tx Complete field set, the firmware adds the
+ *    transmit results to the cyclic buffer (txDoneRing) and sets both done_1
+ *    and done_2 to 1 to indicate driver ownership.
+ * 3. The firmware sends a Tx Complete interrupt to the host to trigger the
+ *    host to process the new data. Note: interrupt will be send per packet if
+ *    TX complete indication was requested in tx_control or per crossing
+ *    aggregation threshold.
+ * 4. After receiving the Tx Complete interrupt, the host reads the
+ *    TxDescriptorDone information in a cyclic manner and clears both done_1
+ *    and done_2 fields.
+ *
+ */
+
+#define TX_COMPLETE_REQUIRED_BIT       0x80
+#define TX_STATUS_DATA_OUT_COUNT_MASK   0xf
+
+#define WL1251_TX_ALIGN_TO 4
+#define WL1251_TX_ALIGN(len) (((len) + WL1251_TX_ALIGN_TO - 1) & \
+                            ~(WL1251_TX_ALIGN_TO - 1))
+#define WL1251_TKIP_IV_SPACE 4
+
+struct tx_control {
+       /* Rate Policy (class) index */
+       unsigned rate_policy:3;
+
+       /* When set, no ack policy is expected */
+       unsigned ack_policy:1;
+
+       /*
+        * Packet type:
+        * 0 -> 802.11
+        * 1 -> 802.3
+        * 2 -> IP
+        * 3 -> raw codec
+        */
+       unsigned packet_type:2;
+
+       /* If set, this is a QoS-Null or QoS-Data frame */
+       unsigned qos:1;
+
+       /*
+        * If set, the target triggers the tx complete INT
+        * upon frame sending completion.
+        */
+       unsigned tx_complete:1;
+
+       /* 2 bytes padding before packet header */
+       unsigned xfer_pad:1;
+
+       unsigned reserved:7;
+} __packed;
+
+
+struct tx_double_buffer_desc {
+       /* Length of payload, including headers. */
+       __le16 length;
+
+       /*
+        * A bit mask that specifies the initial rate to be used
+        * Possible values are:
+        * 0x0001 - 1Mbits
+        * 0x0002 - 2Mbits
+        * 0x0004 - 5.5Mbits
+        * 0x0008 - 6Mbits
+        * 0x0010 - 9Mbits
+        * 0x0020 - 11Mbits
+        * 0x0040 - 12Mbits
+        * 0x0080 - 18Mbits
+        * 0x0100 - 22Mbits
+        * 0x0200 - 24Mbits
+        * 0x0400 - 36Mbits
+        * 0x0800 - 48Mbits
+        * 0x1000 - 54Mbits
+        */
+       __le16 rate;
+
+       /* Time in us that a packet can spend in the target */
+       __le32 expiry_time;
+
+       /* index of the TX queue used for this packet */
+       u8 xmit_queue;
+
+       /* Used to identify a packet */
+       u8 id;
+
+       struct tx_control control;
+
+       /*
+        * The FW should cut the packet into fragments
+        * of this size.
+        */
+       __le16 frag_threshold;
+
+       /* Numbers of HW queue blocks to be allocated */
+       u8 num_mem_blocks;
+
+       u8 reserved;
+} __packed;
+
+enum {
+       TX_SUCCESS              = 0,
+       TX_DMA_ERROR            = BIT(7),
+       TX_DISABLED             = BIT(6),
+       TX_RETRY_EXCEEDED       = BIT(5),
+       TX_TIMEOUT              = BIT(4),
+       TX_KEY_NOT_FOUND        = BIT(3),
+       TX_ENCRYPT_FAIL         = BIT(2),
+       TX_UNAVAILABLE_PRIORITY = BIT(1),
+};
+
+struct tx_result {
+       /*
+        * Ownership synchronization between the host and
+        * the firmware. If done_1 and done_2 are cleared,
+        * owned by the FW (no info ready).
+        */
+       u8 done_1;
+
+       /* same as double_buffer_desc->id */
+       u8 id;
+
+       /*
+        * Total air access duration consumed by this
+        * packet, including all retries and overheads.
+        */
+       u16 medium_usage;
+
+       /* Total media delay (from 1st EDCA AIFS counter until TX Complete). */
+       u32 medium_delay;
+
+       /* Time between host xfer and tx complete */
+       u32 fw_hnadling_time;
+
+       /* The LS-byte of the last TKIP sequence number. */
+       u8 lsb_seq_num;
+
+       /* Retry count */
+       u8 ack_failures;
+
+       /* At which rate we got a ACK */
+       u16 rate;
+
+       u16 reserved;
+
+       /* TX_* */
+       u8 status;
+
+       /* See done_1 */
+       u8 done_2;
+} __packed;
+
+static inline int wl1251_tx_get_queue(int queue)
+{
+       switch (queue) {
+       case 0:
+               return QOS_AC_VO;
+       case 1:
+               return QOS_AC_VI;
+       case 2:
+               return QOS_AC_BE;
+       case 3:
+               return QOS_AC_BK;
+       default:
+               return QOS_AC_BE;
+       }
+}
+
+void wl1251_tx_work(struct work_struct *work);
+void wl1251_tx_complete(struct wl1251 *wl);
+void wl1251_tx_flush(struct wl1251 *wl);
+
+#endif
diff --git a/drivers/net/wireless/wl1251/wl1251.h b/drivers/net/wireless/wl1251/wl1251.h
new file mode 100644 (file)
index 0000000..e113d4c
--- /dev/null
@@ -0,0 +1,433 @@
+/*
+ * This file is part of wl1251
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 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 St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __WL1251_H__
+#define __WL1251_H__
+
+#include <linux/mutex.h>
+#include <linux/list.h>
+#include <linux/bitops.h>
+#include <net/mac80211.h>
+
+#define DRIVER_NAME "wl1251"
+#define DRIVER_PREFIX DRIVER_NAME ": "
+
+enum {
+       DEBUG_NONE      = 0,
+       DEBUG_IRQ       = BIT(0),
+       DEBUG_SPI       = BIT(1),
+       DEBUG_BOOT      = BIT(2),
+       DEBUG_MAILBOX   = BIT(3),
+       DEBUG_NETLINK   = BIT(4),
+       DEBUG_EVENT     = BIT(5),
+       DEBUG_TX        = BIT(6),
+       DEBUG_RX        = BIT(7),
+       DEBUG_SCAN      = BIT(8),
+       DEBUG_CRYPT     = BIT(9),
+       DEBUG_PSM       = BIT(10),
+       DEBUG_MAC80211  = BIT(11),
+       DEBUG_CMD       = BIT(12),
+       DEBUG_ACX       = BIT(13),
+       DEBUG_ALL       = ~0,
+};
+
+#define DEBUG_LEVEL (DEBUG_NONE)
+
+#define DEBUG_DUMP_LIMIT 1024
+
+#define wl1251_error(fmt, arg...) \
+       printk(KERN_ERR DRIVER_PREFIX "ERROR " fmt "\n", ##arg)
+
+#define wl1251_warning(fmt, arg...) \
+       printk(KERN_WARNING DRIVER_PREFIX "WARNING " fmt "\n", ##arg)
+
+#define wl1251_notice(fmt, arg...) \
+       printk(KERN_INFO DRIVER_PREFIX fmt "\n", ##arg)
+
+#define wl1251_info(fmt, arg...) \
+       printk(KERN_DEBUG DRIVER_PREFIX fmt "\n", ##arg)
+
+#define wl1251_debug(level, fmt, arg...) \
+       do { \
+               if (level & DEBUG_LEVEL) \
+                       printk(KERN_DEBUG DRIVER_PREFIX fmt "\n", ##arg); \
+       } while (0)
+
+#define wl1251_dump(level, prefix, buf, len)   \
+       do { \
+               if (level & DEBUG_LEVEL) \
+                       print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \
+                                      DUMP_PREFIX_OFFSET, 16, 1,       \
+                                      buf,                             \
+                                      min_t(size_t, len, DEBUG_DUMP_LIMIT), \
+                                      0);                              \
+       } while (0)
+
+#define wl1251_dump_ascii(level, prefix, buf, len)     \
+       do { \
+               if (level & DEBUG_LEVEL) \
+                       print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \
+                                      DUMP_PREFIX_OFFSET, 16, 1,       \
+                                      buf,                             \
+                                      min_t(size_t, len, DEBUG_DUMP_LIMIT), \
+                                      true);                           \
+       } while (0)
+
+#define WL1251_DEFAULT_RX_CONFIG (CFG_UNI_FILTER_EN |  \
+                                 CFG_BSSID_FILTER_EN)
+
+#define WL1251_DEFAULT_RX_FILTER (CFG_RX_PRSP_EN |  \
+                                 CFG_RX_MGMT_EN |  \
+                                 CFG_RX_DATA_EN |  \
+                                 CFG_RX_CTL_EN |   \
+                                 CFG_RX_BCN_EN |   \
+                                 CFG_RX_AUTH_EN |  \
+                                 CFG_RX_ASSOC_EN)
+
+#define WL1251_BUSY_WORD_LEN 8
+
+struct boot_attr {
+       u32 radio_type;
+       u8 mac_clock;
+       u8 arm_clock;
+       int firmware_debug;
+       u32 minor;
+       u32 major;
+       u32 bugfix;
+};
+
+enum wl1251_state {
+       WL1251_STATE_OFF,
+       WL1251_STATE_ON,
+       WL1251_STATE_PLT,
+};
+
+enum wl1251_partition_type {
+       PART_DOWN,
+       PART_WORK,
+       PART_DRPW,
+
+       PART_TABLE_LEN
+};
+
+struct wl1251_partition {
+       u32 size;
+       u32 start;
+};
+
+struct wl1251_partition_set {
+       struct wl1251_partition mem;
+       struct wl1251_partition reg;
+};
+
+struct wl1251;
+
+struct wl1251_stats {
+       struct acx_statistics *fw_stats;
+       unsigned long fw_stats_update;
+
+       unsigned int retry_count;
+       unsigned int excessive_retries;
+};
+
+struct wl1251_debugfs {
+       struct dentry *rootdir;
+       struct dentry *fw_statistics;
+
+       struct dentry *tx_internal_desc_overflow;
+
+       struct dentry *rx_out_of_mem;
+       struct dentry *rx_hdr_overflow;
+       struct dentry *rx_hw_stuck;
+       struct dentry *rx_dropped;
+       struct dentry *rx_fcs_err;
+       struct dentry *rx_xfr_hint_trig;
+       struct dentry *rx_path_reset;
+       struct dentry *rx_reset_counter;
+
+       struct dentry *dma_rx_requested;
+       struct dentry *dma_rx_errors;
+       struct dentry *dma_tx_requested;
+       struct dentry *dma_tx_errors;
+
+       struct dentry *isr_cmd_cmplt;
+       struct dentry *isr_fiqs;
+       struct dentry *isr_rx_headers;
+       struct dentry *isr_rx_mem_overflow;
+       struct dentry *isr_rx_rdys;
+       struct dentry *isr_irqs;
+       struct dentry *isr_tx_procs;
+       struct dentry *isr_decrypt_done;
+       struct dentry *isr_dma0_done;
+       struct dentry *isr_dma1_done;
+       struct dentry *isr_tx_exch_complete;
+       struct dentry *isr_commands;
+       struct dentry *isr_rx_procs;
+       struct dentry *isr_hw_pm_mode_changes;
+       struct dentry *isr_host_acknowledges;
+       struct dentry *isr_pci_pm;
+       struct dentry *isr_wakeups;
+       struct dentry *isr_low_rssi;
+
+       struct dentry *wep_addr_key_count;
+       struct dentry *wep_default_key_count;
+       /* skipping wep.reserved */
+       struct dentry *wep_key_not_found;
+       struct dentry *wep_decrypt_fail;
+       struct dentry *wep_packets;
+       struct dentry *wep_interrupt;
+
+       struct dentry *pwr_ps_enter;
+       struct dentry *pwr_elp_enter;
+       struct dentry *pwr_missing_bcns;
+       struct dentry *pwr_wake_on_host;
+       struct dentry *pwr_wake_on_timer_exp;
+       struct dentry *pwr_tx_with_ps;
+       struct dentry *pwr_tx_without_ps;
+       struct dentry *pwr_rcvd_beacons;
+       struct dentry *pwr_power_save_off;
+       struct dentry *pwr_enable_ps;
+       struct dentry *pwr_disable_ps;
+       struct dentry *pwr_fix_tsf_ps;
+       /* skipping cont_miss_bcns_spread for now */
+       struct dentry *pwr_rcvd_awake_beacons;
+
+       struct dentry *mic_rx_pkts;
+       struct dentry *mic_calc_failure;
+
+       struct dentry *aes_encrypt_fail;
+       struct dentry *aes_decrypt_fail;
+       struct dentry *aes_encrypt_packets;
+       struct dentry *aes_decrypt_packets;
+       struct dentry *aes_encrypt_interrupt;
+       struct dentry *aes_decrypt_interrupt;
+
+       struct dentry *event_heart_beat;
+       struct dentry *event_calibration;
+       struct dentry *event_rx_mismatch;
+       struct dentry *event_rx_mem_empty;
+       struct dentry *event_rx_pool;
+       struct dentry *event_oom_late;
+       struct dentry *event_phy_transmit_error;
+       struct dentry *event_tx_stuck;
+
+       struct dentry *ps_pspoll_timeouts;
+       struct dentry *ps_upsd_timeouts;
+       struct dentry *ps_upsd_max_sptime;
+       struct dentry *ps_upsd_max_apturn;
+       struct dentry *ps_pspoll_max_apturn;
+       struct dentry *ps_pspoll_utilization;
+       struct dentry *ps_upsd_utilization;
+
+       struct dentry *rxpipe_rx_prep_beacon_drop;
+       struct dentry *rxpipe_descr_host_int_trig_rx_data;
+       struct dentry *rxpipe_beacon_buffer_thres_host_int_trig_rx_data;
+       struct dentry *rxpipe_missed_beacon_host_int_trig_rx_data;
+       struct dentry *rxpipe_tx_xfr_host_int_trig_rx_data;
+
+       struct dentry *tx_queue_len;
+       struct dentry *tx_queue_status;
+
+       struct dentry *retry_count;
+       struct dentry *excessive_retries;
+};
+
+struct wl1251_if_operations {
+       void (*read)(struct wl1251 *wl, int addr, void *buf, size_t len);
+       void (*write)(struct wl1251 *wl, int addr, void *buf, size_t len);
+       void (*read_elp)(struct wl1251 *wl, int addr, u32 *val);
+       void (*write_elp)(struct wl1251 *wl, int addr, u32 val);
+       void (*reset)(struct wl1251 *wl);
+       void (*enable_irq)(struct wl1251 *wl);
+       void (*disable_irq)(struct wl1251 *wl);
+};
+
+struct wl1251 {
+       struct ieee80211_hw *hw;
+       bool mac80211_registered;
+
+       void *if_priv;
+       const struct wl1251_if_operations *if_ops;
+
+       void (*set_power)(bool enable);
+       int irq;
+       bool use_eeprom;
+
+       spinlock_t wl_lock;
+
+       enum wl1251_state state;
+       struct mutex mutex;
+
+       int physical_mem_addr;
+       int physical_reg_addr;
+       int virtual_mem_addr;
+       int virtual_reg_addr;
+
+       int cmd_box_addr;
+       int event_box_addr;
+       struct boot_attr boot_attr;
+
+       u8 *fw;
+       size_t fw_len;
+       u8 *nvs;
+       size_t nvs_len;
+
+       u8 bssid[ETH_ALEN];
+       u8 mac_addr[ETH_ALEN];
+       u8 bss_type;
+       u8 listen_int;
+       int channel;
+
+       void *target_mem_map;
+       struct acx_data_path_params_resp *data_path;
+
+       /* Number of TX packets transferred to the FW, modulo 16 */
+       u32 data_in_count;
+
+       /* Frames scheduled for transmission, not handled yet */
+       struct sk_buff_head tx_queue;
+       bool tx_queue_stopped;
+
+       struct work_struct tx_work;
+       struct work_struct filter_work;
+
+       /* Pending TX frames */
+       struct sk_buff *tx_frames[16];
+
+       /*
+        * Index pointing to the next TX complete entry
+        * in the cyclic XT complete array we get from
+        * the FW.
+        */
+       u32 next_tx_complete;
+
+       /* FW Rx counter */
+       u32 rx_counter;
+
+       /* Rx frames handled */
+       u32 rx_handled;
+
+       /* Current double buffer */
+       u32 rx_current_buffer;
+       u32 rx_last_id;
+
+       /* The target interrupt mask */
+       u32 intr_mask;
+       struct work_struct irq_work;
+
+       /* The mbox event mask */
+       u32 event_mask;
+
+       /* Mailbox pointers */
+       u32 mbox_ptr[2];
+
+       /* Are we currently scanning */
+       bool scanning;
+
+       /* Default key (for WEP) */
+       u32 default_key;
+
+       unsigned int tx_mgmt_frm_rate;
+       unsigned int tx_mgmt_frm_mod;
+
+       unsigned int rx_config;
+       unsigned int rx_filter;
+
+       /* is firmware in elp mode */
+       bool elp;
+
+       struct delayed_work elp_work;
+
+       /* we can be in psm, but not in elp, we have to differentiate */
+       bool psm;
+
+       /* PSM mode requested */
+       bool psm_requested;
+
+       u16 beacon_int;
+       u8 dtim_period;
+
+       /* in dBm */
+       int power_level;
+
+       struct wl1251_stats stats;
+       struct wl1251_debugfs debugfs;
+
+       u32 buffer_32;
+       u32 buffer_cmd;
+       u8 buffer_busyword[WL1251_BUSY_WORD_LEN];
+       struct wl1251_rx_descriptor *rx_descriptor;
+
+       struct ieee80211_vif *vif;
+
+       u32 chip_id;
+       char fw_ver[21];
+
+       /* Most recently reported noise in dBm */
+       s8 noise;
+};
+
+int wl1251_plt_start(struct wl1251 *wl);
+int wl1251_plt_stop(struct wl1251 *wl);
+
+struct ieee80211_hw *wl1251_alloc_hw(void);
+int wl1251_free_hw(struct wl1251 *wl);
+int wl1251_init_ieee80211(struct wl1251 *wl);
+void wl1251_enable_interrupts(struct wl1251 *wl);
+void wl1251_disable_interrupts(struct wl1251 *wl);
+
+#define DEFAULT_HW_GEN_MODULATION_TYPE    CCK_LONG /* Long Preamble */
+#define DEFAULT_HW_GEN_TX_RATE          RATE_2MBPS
+#define JOIN_TIMEOUT 5000 /* 5000 milliseconds to join */
+
+#define WL1251_DEFAULT_POWER_LEVEL 20
+
+#define WL1251_TX_QUEUE_LOW_WATERMARK  10
+#define WL1251_TX_QUEUE_HIGH_WATERMARK 25
+
+#define WL1251_DEFAULT_BEACON_INT 100
+#define WL1251_DEFAULT_DTIM_PERIOD 1
+
+#define WL1251_DEFAULT_CHANNEL 0
+
+#define CHIP_ID_1251_PG10                 (0x7010101)
+#define CHIP_ID_1251_PG11                 (0x7020101)
+#define CHIP_ID_1251_PG12                 (0x7030101)
+#define CHIP_ID_1271_PG10                 (0x4030101)
+#define CHIP_ID_1271_PG20                 (0x4030111)
+
+#define WL1251_FW_NAME "wl1251-fw.bin"
+#define WL1251_NVS_NAME "wl1251-nvs.bin"
+
+#define WL1251_POWER_ON_SLEEP 10 /* in miliseconds */
+
+#define WL1251_PART_DOWN_MEM_START     0x0
+#define WL1251_PART_DOWN_MEM_SIZE      0x16800
+#define WL1251_PART_DOWN_REG_START     REGISTERS_BASE
+#define WL1251_PART_DOWN_REG_SIZE      REGISTERS_DOWN_SIZE
+
+#define WL1251_PART_WORK_MEM_START     0x28000
+#define WL1251_PART_WORK_MEM_SIZE      0x14000
+#define WL1251_PART_WORK_REG_START     REGISTERS_BASE
+#define WL1251_PART_WORK_REG_SIZE      REGISTERS_WORK_SIZE
+
+#endif
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 \
diff --git a/drivers/net/wireless/wl12xx/wl1251.h b/drivers/net/wireless/wl12xx/wl1251.h
deleted file mode 100644 (file)
index e113d4c..0000000
+++ /dev/null
@@ -1,433 +0,0 @@
-/*
- * This file is part of wl1251
- *
- * Copyright (c) 1998-2007 Texas Instruments Incorporated
- * Copyright (C) 2008-2009 Nokia Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __WL1251_H__
-#define __WL1251_H__
-
-#include <linux/mutex.h>
-#include <linux/list.h>
-#include <linux/bitops.h>
-#include <net/mac80211.h>
-
-#define DRIVER_NAME "wl1251"
-#define DRIVER_PREFIX DRIVER_NAME ": "
-
-enum {
-       DEBUG_NONE      = 0,
-       DEBUG_IRQ       = BIT(0),
-       DEBUG_SPI       = BIT(1),
-       DEBUG_BOOT      = BIT(2),
-       DEBUG_MAILBOX   = BIT(3),
-       DEBUG_NETLINK   = BIT(4),
-       DEBUG_EVENT     = BIT(5),
-       DEBUG_TX        = BIT(6),
-       DEBUG_RX        = BIT(7),
-       DEBUG_SCAN      = BIT(8),
-       DEBUG_CRYPT     = BIT(9),
-       DEBUG_PSM       = BIT(10),
-       DEBUG_MAC80211  = BIT(11),
-       DEBUG_CMD       = BIT(12),
-       DEBUG_ACX       = BIT(13),
-       DEBUG_ALL       = ~0,
-};
-
-#define DEBUG_LEVEL (DEBUG_NONE)
-
-#define DEBUG_DUMP_LIMIT 1024
-
-#define wl1251_error(fmt, arg...) \
-       printk(KERN_ERR DRIVER_PREFIX "ERROR " fmt "\n", ##arg)
-
-#define wl1251_warning(fmt, arg...) \
-       printk(KERN_WARNING DRIVER_PREFIX "WARNING " fmt "\n", ##arg)
-
-#define wl1251_notice(fmt, arg...) \
-       printk(KERN_INFO DRIVER_PREFIX fmt "\n", ##arg)
-
-#define wl1251_info(fmt, arg...) \
-       printk(KERN_DEBUG DRIVER_PREFIX fmt "\n", ##arg)
-
-#define wl1251_debug(level, fmt, arg...) \
-       do { \
-               if (level & DEBUG_LEVEL) \
-                       printk(KERN_DEBUG DRIVER_PREFIX fmt "\n", ##arg); \
-       } while (0)
-
-#define wl1251_dump(level, prefix, buf, len)   \
-       do { \
-               if (level & DEBUG_LEVEL) \
-                       print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \
-                                      DUMP_PREFIX_OFFSET, 16, 1,       \
-                                      buf,                             \
-                                      min_t(size_t, len, DEBUG_DUMP_LIMIT), \
-                                      0);                              \
-       } while (0)
-
-#define wl1251_dump_ascii(level, prefix, buf, len)     \
-       do { \
-               if (level & DEBUG_LEVEL) \
-                       print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \
-                                      DUMP_PREFIX_OFFSET, 16, 1,       \
-                                      buf,                             \
-                                      min_t(size_t, len, DEBUG_DUMP_LIMIT), \
-                                      true);                           \
-       } while (0)
-
-#define WL1251_DEFAULT_RX_CONFIG (CFG_UNI_FILTER_EN |  \
-                                 CFG_BSSID_FILTER_EN)
-
-#define WL1251_DEFAULT_RX_FILTER (CFG_RX_PRSP_EN |  \
-                                 CFG_RX_MGMT_EN |  \
-                                 CFG_RX_DATA_EN |  \
-                                 CFG_RX_CTL_EN |   \
-                                 CFG_RX_BCN_EN |   \
-                                 CFG_RX_AUTH_EN |  \
-                                 CFG_RX_ASSOC_EN)
-
-#define WL1251_BUSY_WORD_LEN 8
-
-struct boot_attr {
-       u32 radio_type;
-       u8 mac_clock;
-       u8 arm_clock;
-       int firmware_debug;
-       u32 minor;
-       u32 major;
-       u32 bugfix;
-};
-
-enum wl1251_state {
-       WL1251_STATE_OFF,
-       WL1251_STATE_ON,
-       WL1251_STATE_PLT,
-};
-
-enum wl1251_partition_type {
-       PART_DOWN,
-       PART_WORK,
-       PART_DRPW,
-
-       PART_TABLE_LEN
-};
-
-struct wl1251_partition {
-       u32 size;
-       u32 start;
-};
-
-struct wl1251_partition_set {
-       struct wl1251_partition mem;
-       struct wl1251_partition reg;
-};
-
-struct wl1251;
-
-struct wl1251_stats {
-       struct acx_statistics *fw_stats;
-       unsigned long fw_stats_update;
-
-       unsigned int retry_count;
-       unsigned int excessive_retries;
-};
-
-struct wl1251_debugfs {
-       struct dentry *rootdir;
-       struct dentry *fw_statistics;
-
-       struct dentry *tx_internal_desc_overflow;
-
-       struct dentry *rx_out_of_mem;
-       struct dentry *rx_hdr_overflow;
-       struct dentry *rx_hw_stuck;
-       struct dentry *rx_dropped;
-       struct dentry *rx_fcs_err;
-       struct dentry *rx_xfr_hint_trig;
-       struct dentry *rx_path_reset;
-       struct dentry *rx_reset_counter;
-
-       struct dentry *dma_rx_requested;
-       struct dentry *dma_rx_errors;
-       struct dentry *dma_tx_requested;
-       struct dentry *dma_tx_errors;
-
-       struct dentry *isr_cmd_cmplt;
-       struct dentry *isr_fiqs;
-       struct dentry *isr_rx_headers;
-       struct dentry *isr_rx_mem_overflow;
-       struct dentry *isr_rx_rdys;
-       struct dentry *isr_irqs;
-       struct dentry *isr_tx_procs;
-       struct dentry *isr_decrypt_done;
-       struct dentry *isr_dma0_done;
-       struct dentry *isr_dma1_done;
-       struct dentry *isr_tx_exch_complete;
-       struct dentry *isr_commands;
-       struct dentry *isr_rx_procs;
-       struct dentry *isr_hw_pm_mode_changes;
-       struct dentry *isr_host_acknowledges;
-       struct dentry *isr_pci_pm;
-       struct dentry *isr_wakeups;
-       struct dentry *isr_low_rssi;
-
-       struct dentry *wep_addr_key_count;
-       struct dentry *wep_default_key_count;
-       /* skipping wep.reserved */
-       struct dentry *wep_key_not_found;
-       struct dentry *wep_decrypt_fail;
-       struct dentry *wep_packets;
-       struct dentry *wep_interrupt;
-
-       struct dentry *pwr_ps_enter;
-       struct dentry *pwr_elp_enter;
-       struct dentry *pwr_missing_bcns;
-       struct dentry *pwr_wake_on_host;
-       struct dentry *pwr_wake_on_timer_exp;
-       struct dentry *pwr_tx_with_ps;
-       struct dentry *pwr_tx_without_ps;
-       struct dentry *pwr_rcvd_beacons;
-       struct dentry *pwr_power_save_off;
-       struct dentry *pwr_enable_ps;
-       struct dentry *pwr_disable_ps;
-       struct dentry *pwr_fix_tsf_ps;
-       /* skipping cont_miss_bcns_spread for now */
-       struct dentry *pwr_rcvd_awake_beacons;
-
-       struct dentry *mic_rx_pkts;
-       struct dentry *mic_calc_failure;
-
-       struct dentry *aes_encrypt_fail;
-       struct dentry *aes_decrypt_fail;
-       struct dentry *aes_encrypt_packets;
-       struct dentry *aes_decrypt_packets;
-       struct dentry *aes_encrypt_interrupt;
-       struct dentry *aes_decrypt_interrupt;
-
-       struct dentry *event_heart_beat;
-       struct dentry *event_calibration;
-       struct dentry *event_rx_mismatch;
-       struct dentry *event_rx_mem_empty;
-       struct dentry *event_rx_pool;
-       struct dentry *event_oom_late;
-       struct dentry *event_phy_transmit_error;
-       struct dentry *event_tx_stuck;
-
-       struct dentry *ps_pspoll_timeouts;
-       struct dentry *ps_upsd_timeouts;
-       struct dentry *ps_upsd_max_sptime;
-       struct dentry *ps_upsd_max_apturn;
-       struct dentry *ps_pspoll_max_apturn;
-       struct dentry *ps_pspoll_utilization;
-       struct dentry *ps_upsd_utilization;
-
-       struct dentry *rxpipe_rx_prep_beacon_drop;
-       struct dentry *rxpipe_descr_host_int_trig_rx_data;
-       struct dentry *rxpipe_beacon_buffer_thres_host_int_trig_rx_data;
-       struct dentry *rxpipe_missed_beacon_host_int_trig_rx_data;
-       struct dentry *rxpipe_tx_xfr_host_int_trig_rx_data;
-
-       struct dentry *tx_queue_len;
-       struct dentry *tx_queue_status;
-
-       struct dentry *retry_count;
-       struct dentry *excessive_retries;
-};
-
-struct wl1251_if_operations {
-       void (*read)(struct wl1251 *wl, int addr, void *buf, size_t len);
-       void (*write)(struct wl1251 *wl, int addr, void *buf, size_t len);
-       void (*read_elp)(struct wl1251 *wl, int addr, u32 *val);
-       void (*write_elp)(struct wl1251 *wl, int addr, u32 val);
-       void (*reset)(struct wl1251 *wl);
-       void (*enable_irq)(struct wl1251 *wl);
-       void (*disable_irq)(struct wl1251 *wl);
-};
-
-struct wl1251 {
-       struct ieee80211_hw *hw;
-       bool mac80211_registered;
-
-       void *if_priv;
-       const struct wl1251_if_operations *if_ops;
-
-       void (*set_power)(bool enable);
-       int irq;
-       bool use_eeprom;
-
-       spinlock_t wl_lock;
-
-       enum wl1251_state state;
-       struct mutex mutex;
-
-       int physical_mem_addr;
-       int physical_reg_addr;
-       int virtual_mem_addr;
-       int virtual_reg_addr;
-
-       int cmd_box_addr;
-       int event_box_addr;
-       struct boot_attr boot_attr;
-
-       u8 *fw;
-       size_t fw_len;
-       u8 *nvs;
-       size_t nvs_len;
-
-       u8 bssid[ETH_ALEN];
-       u8 mac_addr[ETH_ALEN];
-       u8 bss_type;
-       u8 listen_int;
-       int channel;
-
-       void *target_mem_map;
-       struct acx_data_path_params_resp *data_path;
-
-       /* Number of TX packets transferred to the FW, modulo 16 */
-       u32 data_in_count;
-
-       /* Frames scheduled for transmission, not handled yet */
-       struct sk_buff_head tx_queue;
-       bool tx_queue_stopped;
-
-       struct work_struct tx_work;
-       struct work_struct filter_work;
-
-       /* Pending TX frames */
-       struct sk_buff *tx_frames[16];
-
-       /*
-        * Index pointing to the next TX complete entry
-        * in the cyclic XT complete array we get from
-        * the FW.
-        */
-       u32 next_tx_complete;
-
-       /* FW Rx counter */
-       u32 rx_counter;
-
-       /* Rx frames handled */
-       u32 rx_handled;
-
-       /* Current double buffer */
-       u32 rx_current_buffer;
-       u32 rx_last_id;
-
-       /* The target interrupt mask */
-       u32 intr_mask;
-       struct work_struct irq_work;
-
-       /* The mbox event mask */
-       u32 event_mask;
-
-       /* Mailbox pointers */
-       u32 mbox_ptr[2];
-
-       /* Are we currently scanning */
-       bool scanning;
-
-       /* Default key (for WEP) */
-       u32 default_key;
-
-       unsigned int tx_mgmt_frm_rate;
-       unsigned int tx_mgmt_frm_mod;
-
-       unsigned int rx_config;
-       unsigned int rx_filter;
-
-       /* is firmware in elp mode */
-       bool elp;
-
-       struct delayed_work elp_work;
-
-       /* we can be in psm, but not in elp, we have to differentiate */
-       bool psm;
-
-       /* PSM mode requested */
-       bool psm_requested;
-
-       u16 beacon_int;
-       u8 dtim_period;
-
-       /* in dBm */
-       int power_level;
-
-       struct wl1251_stats stats;
-       struct wl1251_debugfs debugfs;
-
-       u32 buffer_32;
-       u32 buffer_cmd;
-       u8 buffer_busyword[WL1251_BUSY_WORD_LEN];
-       struct wl1251_rx_descriptor *rx_descriptor;
-
-       struct ieee80211_vif *vif;
-
-       u32 chip_id;
-       char fw_ver[21];
-
-       /* Most recently reported noise in dBm */
-       s8 noise;
-};
-
-int wl1251_plt_start(struct wl1251 *wl);
-int wl1251_plt_stop(struct wl1251 *wl);
-
-struct ieee80211_hw *wl1251_alloc_hw(void);
-int wl1251_free_hw(struct wl1251 *wl);
-int wl1251_init_ieee80211(struct wl1251 *wl);
-void wl1251_enable_interrupts(struct wl1251 *wl);
-void wl1251_disable_interrupts(struct wl1251 *wl);
-
-#define DEFAULT_HW_GEN_MODULATION_TYPE    CCK_LONG /* Long Preamble */
-#define DEFAULT_HW_GEN_TX_RATE          RATE_2MBPS
-#define JOIN_TIMEOUT 5000 /* 5000 milliseconds to join */
-
-#define WL1251_DEFAULT_POWER_LEVEL 20
-
-#define WL1251_TX_QUEUE_LOW_WATERMARK  10
-#define WL1251_TX_QUEUE_HIGH_WATERMARK 25
-
-#define WL1251_DEFAULT_BEACON_INT 100
-#define WL1251_DEFAULT_DTIM_PERIOD 1
-
-#define WL1251_DEFAULT_CHANNEL 0
-
-#define CHIP_ID_1251_PG10                 (0x7010101)
-#define CHIP_ID_1251_PG11                 (0x7020101)
-#define CHIP_ID_1251_PG12                 (0x7030101)
-#define CHIP_ID_1271_PG10                 (0x4030101)
-#define CHIP_ID_1271_PG20                 (0x4030111)
-
-#define WL1251_FW_NAME "wl1251-fw.bin"
-#define WL1251_NVS_NAME "wl1251-nvs.bin"
-
-#define WL1251_POWER_ON_SLEEP 10 /* in miliseconds */
-
-#define WL1251_PART_DOWN_MEM_START     0x0
-#define WL1251_PART_DOWN_MEM_SIZE      0x16800
-#define WL1251_PART_DOWN_REG_START     REGISTERS_BASE
-#define WL1251_PART_DOWN_REG_SIZE      REGISTERS_DOWN_SIZE
-
-#define WL1251_PART_WORK_MEM_START     0x28000
-#define WL1251_PART_WORK_MEM_SIZE      0x14000
-#define WL1251_PART_WORK_REG_START     REGISTERS_BASE
-#define WL1251_PART_WORK_REG_SIZE      REGISTERS_WORK_SIZE
-
-#endif
diff --git a/drivers/net/wireless/wl12xx/wl1251_acx.c b/drivers/net/wireless/wl12xx/wl1251_acx.c
deleted file mode 100644 (file)
index 2f8a2ba..0000000
+++ /dev/null
@@ -1,1048 +0,0 @@
-#include "wl1251_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"
-
-int wl1251_acx_frame_rates(struct wl1251 *wl, u8 ctrl_rate, u8 ctrl_mod,
-                          u8 mgt_rate, u8 mgt_mod)
-{
-       struct acx_fw_gen_frame_rates *rates;
-       int ret;
-
-       wl1251_debug(DEBUG_ACX, "acx frame rates");
-
-       rates = kzalloc(sizeof(*rates), GFP_KERNEL);
-       if (!rates) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       rates->tx_ctrl_frame_rate = ctrl_rate;
-       rates->tx_ctrl_frame_mod = ctrl_mod;
-       rates->tx_mgt_frame_rate = mgt_rate;
-       rates->tx_mgt_frame_mod = mgt_mod;
-
-       ret = wl1251_cmd_configure(wl, ACX_FW_GEN_FRAME_RATES,
-                                  rates, sizeof(*rates));
-       if (ret < 0) {
-               wl1251_error("Failed to set FW rates and modulation");
-               goto out;
-       }
-
-out:
-       kfree(rates);
-       return ret;
-}
-
-
-int wl1251_acx_station_id(struct wl1251 *wl)
-{
-       struct acx_dot11_station_id *mac;
-       int ret, i;
-
-       wl1251_debug(DEBUG_ACX, "acx dot11_station_id");
-
-       mac = kzalloc(sizeof(*mac), GFP_KERNEL);
-       if (!mac) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       for (i = 0; i < ETH_ALEN; i++)
-               mac->mac[i] = wl->mac_addr[ETH_ALEN - 1 - i];
-
-       ret = wl1251_cmd_configure(wl, DOT11_STATION_ID, mac, sizeof(*mac));
-       if (ret < 0)
-               goto out;
-
-out:
-       kfree(mac);
-       return ret;
-}
-
-int wl1251_acx_default_key(struct wl1251 *wl, u8 key_id)
-{
-       struct acx_dot11_default_key *default_key;
-       int ret;
-
-       wl1251_debug(DEBUG_ACX, "acx dot11_default_key (%d)", key_id);
-
-       default_key = kzalloc(sizeof(*default_key), GFP_KERNEL);
-       if (!default_key) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       default_key->id = key_id;
-
-       ret = wl1251_cmd_configure(wl, DOT11_DEFAULT_KEY,
-                                  default_key, sizeof(*default_key));
-       if (ret < 0) {
-               wl1251_error("Couldn't set default key");
-               goto out;
-       }
-
-       wl->default_key = key_id;
-
-out:
-       kfree(default_key);
-       return ret;
-}
-
-int wl1251_acx_wake_up_conditions(struct wl1251 *wl, u8 wake_up_event,
-                                 u8 listen_interval)
-{
-       struct acx_wake_up_condition *wake_up;
-       int ret;
-
-       wl1251_debug(DEBUG_ACX, "acx wake up conditions");
-
-       wake_up = kzalloc(sizeof(*wake_up), GFP_KERNEL);
-       if (!wake_up) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       wake_up->wake_up_event = wake_up_event;
-       wake_up->listen_interval = listen_interval;
-
-       ret = wl1251_cmd_configure(wl, ACX_WAKE_UP_CONDITIONS,
-                                  wake_up, sizeof(*wake_up));
-       if (ret < 0) {
-               wl1251_warning("could not set wake up conditions: %d", ret);
-               goto out;
-       }
-
-out:
-       kfree(wake_up);
-       return ret;
-}
-
-int wl1251_acx_sleep_auth(struct wl1251 *wl, u8 sleep_auth)
-{
-       struct acx_sleep_auth *auth;
-       int ret;
-
-       wl1251_debug(DEBUG_ACX, "acx sleep auth");
-
-       auth = kzalloc(sizeof(*auth), GFP_KERNEL);
-       if (!auth) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       auth->sleep_auth = sleep_auth;
-
-       ret = wl1251_cmd_configure(wl, ACX_SLEEP_AUTH, auth, sizeof(*auth));
-       if (ret < 0)
-               return ret;
-
-out:
-       kfree(auth);
-       return ret;
-}
-
-int wl1251_acx_fw_version(struct wl1251 *wl, char *buf, size_t len)
-{
-       struct acx_revision *rev;
-       int ret;
-
-       wl1251_debug(DEBUG_ACX, "acx fw rev");
-
-       rev = kzalloc(sizeof(*rev), GFP_KERNEL);
-       if (!rev) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       ret = wl1251_cmd_interrogate(wl, ACX_FW_REV, rev, sizeof(*rev));
-       if (ret < 0) {
-               wl1251_warning("ACX_FW_REV interrogate failed");
-               goto out;
-       }
-
-       /* be careful with the buffer sizes */
-       strncpy(buf, rev->fw_version, min(len, sizeof(rev->fw_version)));
-
-       /*
-        * if the firmware version string is exactly
-        * sizeof(rev->fw_version) long or fw_len is less than
-        * sizeof(rev->fw_version) it won't be null terminated
-        */
-       buf[min(len, sizeof(rev->fw_version)) - 1] = '\0';
-
-out:
-       kfree(rev);
-       return ret;
-}
-
-int wl1251_acx_tx_power(struct wl1251 *wl, int power)
-{
-       struct acx_current_tx_power *acx;
-       int ret;
-
-       wl1251_debug(DEBUG_ACX, "acx dot11_cur_tx_pwr");
-
-       if (power < 0 || power > 25)
-               return -EINVAL;
-
-       acx = kzalloc(sizeof(*acx), GFP_KERNEL);
-       if (!acx) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       acx->current_tx_power = power * 10;
-
-       ret = wl1251_cmd_configure(wl, DOT11_CUR_TX_PWR, acx, sizeof(*acx));
-       if (ret < 0) {
-               wl1251_warning("configure of tx power failed: %d", ret);
-               goto out;
-       }
-
-out:
-       kfree(acx);
-       return ret;
-}
-
-int wl1251_acx_feature_cfg(struct wl1251 *wl)
-{
-       struct acx_feature_config *feature;
-       int ret;
-
-       wl1251_debug(DEBUG_ACX, "acx feature cfg");
-
-       feature = kzalloc(sizeof(*feature), GFP_KERNEL);
-       if (!feature) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       /* DF_ENCRYPTION_DISABLE and DF_SNIFF_MODE_ENABLE are disabled */
-       feature->data_flow_options = 0;
-       feature->options = 0;
-
-       ret = wl1251_cmd_configure(wl, ACX_FEATURE_CFG,
-                                  feature, sizeof(*feature));
-       if (ret < 0) {
-               wl1251_error("Couldn't set HW encryption");
-               goto out;
-       }
-
-out:
-       kfree(feature);
-       return ret;
-}
-
-int wl1251_acx_mem_map(struct wl1251 *wl, struct acx_header *mem_map,
-                      size_t len)
-{
-       int ret;
-
-       wl1251_debug(DEBUG_ACX, "acx mem map");
-
-       ret = wl1251_cmd_interrogate(wl, ACX_MEM_MAP, mem_map, len);
-       if (ret < 0)
-               return ret;
-
-       return 0;
-}
-
-int wl1251_acx_data_path_params(struct wl1251 *wl,
-                               struct acx_data_path_params_resp *resp)
-{
-       struct acx_data_path_params *params;
-       int ret;
-
-       wl1251_debug(DEBUG_ACX, "acx data path params");
-
-       params = kzalloc(sizeof(*params), GFP_KERNEL);
-       if (!params) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       params->rx_packet_ring_chunk_size = DP_RX_PACKET_RING_CHUNK_SIZE;
-       params->tx_packet_ring_chunk_size = DP_TX_PACKET_RING_CHUNK_SIZE;
-
-       params->rx_packet_ring_chunk_num = DP_RX_PACKET_RING_CHUNK_NUM;
-       params->tx_packet_ring_chunk_num = DP_TX_PACKET_RING_CHUNK_NUM;
-
-       params->tx_complete_threshold = 1;
-
-       params->tx_complete_ring_depth = FW_TX_CMPLT_BLOCK_SIZE;
-
-       params->tx_complete_timeout = DP_TX_COMPLETE_TIME_OUT;
-
-       ret = wl1251_cmd_configure(wl, ACX_DATA_PATH_PARAMS,
-                                  params, sizeof(*params));
-       if (ret < 0)
-               goto out;
-
-       /* FIXME: shouldn't this be ACX_DATA_PATH_RESP_PARAMS? */
-       ret = wl1251_cmd_interrogate(wl, ACX_DATA_PATH_PARAMS,
-                                    resp, sizeof(*resp));
-
-       if (ret < 0) {
-               wl1251_warning("failed to read data path parameters: %d", ret);
-               goto out;
-       } else if (resp->header.cmd.status != CMD_STATUS_SUCCESS) {
-               wl1251_warning("data path parameter acx status failed");
-               ret = -EIO;
-               goto out;
-       }
-
-out:
-       kfree(params);
-       return ret;
-}
-
-int wl1251_acx_rx_msdu_life_time(struct wl1251 *wl, u32 life_time)
-{
-       struct acx_rx_msdu_lifetime *acx;
-       int ret;
-
-       wl1251_debug(DEBUG_ACX, "acx rx msdu life time");
-
-       acx = kzalloc(sizeof(*acx), GFP_KERNEL);
-       if (!acx) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       acx->lifetime = life_time;
-       ret = wl1251_cmd_configure(wl, DOT11_RX_MSDU_LIFE_TIME,
-                                  acx, sizeof(*acx));
-       if (ret < 0) {
-               wl1251_warning("failed to set rx msdu life time: %d", ret);
-               goto out;
-       }
-
-out:
-       kfree(acx);
-       return ret;
-}
-
-int wl1251_acx_rx_config(struct wl1251 *wl, u32 config, u32 filter)
-{
-       struct acx_rx_config *rx_config;
-       int ret;
-
-       wl1251_debug(DEBUG_ACX, "acx rx config");
-
-       rx_config = kzalloc(sizeof(*rx_config), GFP_KERNEL);
-       if (!rx_config) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       rx_config->config_options = config;
-       rx_config->filter_options = filter;
-
-       ret = wl1251_cmd_configure(wl, ACX_RX_CFG,
-                                  rx_config, sizeof(*rx_config));
-       if (ret < 0) {
-               wl1251_warning("failed to set rx config: %d", ret);
-               goto out;
-       }
-
-out:
-       kfree(rx_config);
-       return ret;
-}
-
-int wl1251_acx_pd_threshold(struct wl1251 *wl)
-{
-       struct acx_packet_detection *pd;
-       int ret;
-
-       wl1251_debug(DEBUG_ACX, "acx data pd threshold");
-
-       pd = kzalloc(sizeof(*pd), GFP_KERNEL);
-       if (!pd) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       /* FIXME: threshold value not set */
-
-       ret = wl1251_cmd_configure(wl, ACX_PD_THRESHOLD, pd, sizeof(*pd));
-       if (ret < 0) {
-               wl1251_warning("failed to set pd threshold: %d", ret);
-               goto out;
-       }
-
-out:
-       kfree(pd);
-       return ret;
-}
-
-int wl1251_acx_slot(struct wl1251 *wl, enum acx_slot_type slot_time)
-{
-       struct acx_slot *slot;
-       int ret;
-
-       wl1251_debug(DEBUG_ACX, "acx slot");
-
-       slot = kzalloc(sizeof(*slot), GFP_KERNEL);
-       if (!slot) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       slot->wone_index = STATION_WONE_INDEX;
-       slot->slot_time = slot_time;
-
-       ret = wl1251_cmd_configure(wl, ACX_SLOT, slot, sizeof(*slot));
-       if (ret < 0) {
-               wl1251_warning("failed to set slot time: %d", ret);
-               goto out;
-       }
-
-out:
-       kfree(slot);
-       return ret;
-}
-
-int wl1251_acx_group_address_tbl(struct wl1251 *wl)
-{
-       struct acx_dot11_grp_addr_tbl *acx;
-       int ret;
-
-       wl1251_debug(DEBUG_ACX, "acx group address tbl");
-
-       acx = kzalloc(sizeof(*acx), GFP_KERNEL);
-       if (!acx) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       /* MAC filtering */
-       acx->enabled = 0;
-       acx->num_groups = 0;
-       memset(acx->mac_table, 0, ADDRESS_GROUP_MAX_LEN);
-
-       ret = wl1251_cmd_configure(wl, DOT11_GROUP_ADDRESS_TBL,
-                                  acx, sizeof(*acx));
-       if (ret < 0) {
-               wl1251_warning("failed to set group addr table: %d", ret);
-               goto out;
-       }
-
-out:
-       kfree(acx);
-       return ret;
-}
-
-int wl1251_acx_service_period_timeout(struct wl1251 *wl)
-{
-       struct acx_rx_timeout *rx_timeout;
-       int ret;
-
-       rx_timeout = kzalloc(sizeof(*rx_timeout), GFP_KERNEL);
-       if (!rx_timeout) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       wl1251_debug(DEBUG_ACX, "acx service period timeout");
-
-       rx_timeout->ps_poll_timeout = RX_TIMEOUT_PS_POLL_DEF;
-       rx_timeout->upsd_timeout = RX_TIMEOUT_UPSD_DEF;
-
-       ret = wl1251_cmd_configure(wl, ACX_SERVICE_PERIOD_TIMEOUT,
-                                  rx_timeout, sizeof(*rx_timeout));
-       if (ret < 0) {
-               wl1251_warning("failed to set service period timeout: %d",
-                              ret);
-               goto out;
-       }
-
-out:
-       kfree(rx_timeout);
-       return ret;
-}
-
-int wl1251_acx_rts_threshold(struct wl1251 *wl, u16 rts_threshold)
-{
-       struct acx_rts_threshold *rts;
-       int ret;
-
-       wl1251_debug(DEBUG_ACX, "acx rts threshold");
-
-       rts = kzalloc(sizeof(*rts), GFP_KERNEL);
-       if (!rts) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       rts->threshold = rts_threshold;
-
-       ret = wl1251_cmd_configure(wl, DOT11_RTS_THRESHOLD, rts, sizeof(*rts));
-       if (ret < 0) {
-               wl1251_warning("failed to set rts threshold: %d", ret);
-               goto out;
-       }
-
-out:
-       kfree(rts);
-       return ret;
-}
-
-int wl1251_acx_beacon_filter_opt(struct wl1251 *wl, bool enable_filter)
-{
-       struct acx_beacon_filter_option *beacon_filter;
-       int ret;
-
-       wl1251_debug(DEBUG_ACX, "acx beacon filter opt");
-
-       beacon_filter = kzalloc(sizeof(*beacon_filter), GFP_KERNEL);
-       if (!beacon_filter) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       beacon_filter->enable = enable_filter;
-       beacon_filter->max_num_beacons = 0;
-
-       ret = wl1251_cmd_configure(wl, ACX_BEACON_FILTER_OPT,
-                                  beacon_filter, sizeof(*beacon_filter));
-       if (ret < 0) {
-               wl1251_warning("failed to set beacon filter opt: %d", ret);
-               goto out;
-       }
-
-out:
-       kfree(beacon_filter);
-       return ret;
-}
-
-int wl1251_acx_beacon_filter_table(struct wl1251 *wl)
-{
-       struct acx_beacon_filter_ie_table *ie_table;
-       int idx = 0;
-       int ret;
-
-       wl1251_debug(DEBUG_ACX, "acx beacon filter table");
-
-       ie_table = kzalloc(sizeof(*ie_table), GFP_KERNEL);
-       if (!ie_table) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       /* configure default beacon pass-through rules */
-       ie_table->num_ie = 1;
-       ie_table->table[idx++] = BEACON_FILTER_IE_ID_CHANNEL_SWITCH_ANN;
-       ie_table->table[idx++] = BEACON_RULE_PASS_ON_APPEARANCE;
-
-       ret = wl1251_cmd_configure(wl, ACX_BEACON_FILTER_TABLE,
-                                  ie_table, sizeof(*ie_table));
-       if (ret < 0) {
-               wl1251_warning("failed to set beacon filter table: %d", ret);
-               goto out;
-       }
-
-out:
-       kfree(ie_table);
-       return ret;
-}
-
-int wl1251_acx_conn_monit_params(struct wl1251 *wl)
-{
-       struct acx_conn_monit_params *acx;
-       int ret;
-
-       wl1251_debug(DEBUG_ACX, "acx connection monitor parameters");
-
-       acx = kzalloc(sizeof(*acx), GFP_KERNEL);
-       if (!acx) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       acx->synch_fail_thold = SYNCH_FAIL_DEFAULT_THRESHOLD;
-       acx->bss_lose_timeout = NO_BEACON_DEFAULT_TIMEOUT;
-
-       ret = wl1251_cmd_configure(wl, ACX_CONN_MONIT_PARAMS,
-                                  acx, sizeof(*acx));
-       if (ret < 0) {
-               wl1251_warning("failed to set connection monitor "
-                              "parameters: %d", ret);
-               goto out;
-       }
-
-out:
-       kfree(acx);
-       return ret;
-}
-
-int wl1251_acx_sg_enable(struct wl1251 *wl)
-{
-       struct acx_bt_wlan_coex *pta;
-       int ret;
-
-       wl1251_debug(DEBUG_ACX, "acx sg enable");
-
-       pta = kzalloc(sizeof(*pta), GFP_KERNEL);
-       if (!pta) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       pta->enable = SG_ENABLE;
-
-       ret = wl1251_cmd_configure(wl, ACX_SG_ENABLE, pta, sizeof(*pta));
-       if (ret < 0) {
-               wl1251_warning("failed to set softgemini enable: %d", ret);
-               goto out;
-       }
-
-out:
-       kfree(pta);
-       return ret;
-}
-
-int wl1251_acx_sg_cfg(struct wl1251 *wl)
-{
-       struct acx_bt_wlan_coex_param *param;
-       int ret;
-
-       wl1251_debug(DEBUG_ACX, "acx sg cfg");
-
-       param = kzalloc(sizeof(*param), GFP_KERNEL);
-       if (!param) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       /* BT-WLAN coext parameters */
-       param->min_rate = RATE_INDEX_24MBPS;
-       param->bt_hp_max_time = PTA_BT_HP_MAXTIME_DEF;
-       param->wlan_hp_max_time = PTA_WLAN_HP_MAX_TIME_DEF;
-       param->sense_disable_timer = PTA_SENSE_DISABLE_TIMER_DEF;
-       param->rx_time_bt_hp = PTA_PROTECTIVE_RX_TIME_DEF;
-       param->tx_time_bt_hp = PTA_PROTECTIVE_TX_TIME_DEF;
-       param->rx_time_bt_hp_fast = PTA_PROTECTIVE_RX_TIME_FAST_DEF;
-       param->tx_time_bt_hp_fast = PTA_PROTECTIVE_TX_TIME_FAST_DEF;
-       param->wlan_cycle_fast = PTA_CYCLE_TIME_FAST_DEF;
-       param->bt_anti_starvation_period = PTA_ANTI_STARVE_PERIOD_DEF;
-       param->next_bt_lp_packet = PTA_TIMEOUT_NEXT_BT_LP_PACKET_DEF;
-       param->wake_up_beacon = PTA_TIME_BEFORE_BEACON_DEF;
-       param->hp_dm_max_guard_time = PTA_HPDM_MAX_TIME_DEF;
-       param->next_wlan_packet = PTA_TIME_OUT_NEXT_WLAN_DEF;
-       param->antenna_type = PTA_ANTENNA_TYPE_DEF;
-       param->signal_type = PTA_SIGNALING_TYPE_DEF;
-       param->afh_leverage_on = PTA_AFH_LEVERAGE_ON_DEF;
-       param->quiet_cycle_num = PTA_NUMBER_QUIET_CYCLE_DEF;
-       param->max_cts = PTA_MAX_NUM_CTS_DEF;
-       param->wlan_packets_num = PTA_NUMBER_OF_WLAN_PACKETS_DEF;
-       param->bt_packets_num = PTA_NUMBER_OF_BT_PACKETS_DEF;
-       param->missed_rx_avalanche = PTA_RX_FOR_AVALANCHE_DEF;
-       param->wlan_elp_hp = PTA_ELP_HP_DEF;
-       param->bt_anti_starvation_cycles = PTA_ANTI_STARVE_NUM_CYCLE_DEF;
-       param->ack_mode_dual_ant = PTA_ACK_MODE_DEF;
-       param->pa_sd_enable = PTA_ALLOW_PA_SD_DEF;
-       param->pta_auto_mode_enable = PTA_AUTO_MODE_NO_CTS_DEF;
-       param->bt_hp_respected_num = PTA_BT_HP_RESPECTED_DEF;
-
-       ret = wl1251_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param));
-       if (ret < 0) {
-               wl1251_warning("failed to set sg config: %d", ret);
-               goto out;
-       }
-
-out:
-       kfree(param);
-       return ret;
-}
-
-int wl1251_acx_cca_threshold(struct wl1251 *wl)
-{
-       struct acx_energy_detection *detection;
-       int ret;
-
-       wl1251_debug(DEBUG_ACX, "acx cca threshold");
-
-       detection = kzalloc(sizeof(*detection), GFP_KERNEL);
-       if (!detection) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       detection->rx_cca_threshold = CCA_THRSH_DISABLE_ENERGY_D;
-       detection->tx_energy_detection = 0;
-
-       ret = wl1251_cmd_configure(wl, ACX_CCA_THRESHOLD,
-                                  detection, sizeof(*detection));
-       if (ret < 0) {
-               wl1251_warning("failed to set cca threshold: %d", ret);
-               return ret;
-       }
-
-out:
-       kfree(detection);
-       return ret;
-}
-
-int wl1251_acx_bcn_dtim_options(struct wl1251 *wl)
-{
-       struct acx_beacon_broadcast *bb;
-       int ret;
-
-       wl1251_debug(DEBUG_ACX, "acx bcn dtim options");
-
-       bb = kzalloc(sizeof(*bb), GFP_KERNEL);
-       if (!bb) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       bb->beacon_rx_timeout = BCN_RX_TIMEOUT_DEF_VALUE;
-       bb->broadcast_timeout = BROADCAST_RX_TIMEOUT_DEF_VALUE;
-       bb->rx_broadcast_in_ps = RX_BROADCAST_IN_PS_DEF_VALUE;
-       bb->ps_poll_threshold = CONSECUTIVE_PS_POLL_FAILURE_DEF;
-
-       ret = wl1251_cmd_configure(wl, ACX_BCN_DTIM_OPTIONS, bb, sizeof(*bb));
-       if (ret < 0) {
-               wl1251_warning("failed to set rx config: %d", ret);
-               goto out;
-       }
-
-out:
-       kfree(bb);
-       return ret;
-}
-
-int wl1251_acx_aid(struct wl1251 *wl, u16 aid)
-{
-       struct acx_aid *acx_aid;
-       int ret;
-
-       wl1251_debug(DEBUG_ACX, "acx aid");
-
-       acx_aid = kzalloc(sizeof(*acx_aid), GFP_KERNEL);
-       if (!acx_aid) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       acx_aid->aid = aid;
-
-       ret = wl1251_cmd_configure(wl, ACX_AID, acx_aid, sizeof(*acx_aid));
-       if (ret < 0) {
-               wl1251_warning("failed to set aid: %d", ret);
-               goto out;
-       }
-
-out:
-       kfree(acx_aid);
-       return ret;
-}
-
-int wl1251_acx_event_mbox_mask(struct wl1251 *wl, u32 event_mask)
-{
-       struct acx_event_mask *mask;
-       int ret;
-
-       wl1251_debug(DEBUG_ACX, "acx event mbox mask");
-
-       mask = kzalloc(sizeof(*mask), GFP_KERNEL);
-       if (!mask) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       /* high event mask is unused */
-       mask->high_event_mask = 0xffffffff;
-
-       mask->event_mask = event_mask;
-
-       ret = wl1251_cmd_configure(wl, ACX_EVENT_MBOX_MASK,
-                                  mask, sizeof(*mask));
-       if (ret < 0) {
-               wl1251_warning("failed to set acx_event_mbox_mask: %d", ret);
-               goto out;
-       }
-
-out:
-       kfree(mask);
-       return ret;
-}
-
-int wl1251_acx_set_preamble(struct wl1251 *wl, enum acx_preamble_type preamble)
-{
-       struct acx_preamble *acx;
-       int ret;
-
-       wl1251_debug(DEBUG_ACX, "acx_set_preamble");
-
-       acx = kzalloc(sizeof(*acx), GFP_KERNEL);
-       if (!acx) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       acx->preamble = preamble;
-
-       ret = wl1251_cmd_configure(wl, ACX_PREAMBLE_TYPE, acx, sizeof(*acx));
-       if (ret < 0) {
-               wl1251_warning("Setting of preamble failed: %d", ret);
-               goto out;
-       }
-
-out:
-       kfree(acx);
-       return ret;
-}
-
-int wl1251_acx_cts_protect(struct wl1251 *wl,
-                          enum acx_ctsprotect_type ctsprotect)
-{
-       struct acx_ctsprotect *acx;
-       int ret;
-
-       wl1251_debug(DEBUG_ACX, "acx_set_ctsprotect");
-
-       acx = kzalloc(sizeof(*acx), GFP_KERNEL);
-       if (!acx) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       acx->ctsprotect = ctsprotect;
-
-       ret = wl1251_cmd_configure(wl, ACX_CTS_PROTECTION, acx, sizeof(*acx));
-       if (ret < 0) {
-               wl1251_warning("Setting of ctsprotect failed: %d", ret);
-               goto out;
-       }
-
-out:
-       kfree(acx);
-       return ret;
-}
-
-int wl1251_acx_tsf_info(struct wl1251 *wl, u64 *mactime)
-{
-       struct acx_tsf_info *tsf_info;
-       int ret;
-
-       tsf_info = kzalloc(sizeof(*tsf_info), GFP_KERNEL);
-       if (!tsf_info) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       ret = wl1251_cmd_interrogate(wl, ACX_TSF_INFO,
-                                    tsf_info, sizeof(*tsf_info));
-       if (ret < 0) {
-               wl1251_warning("ACX_FW_REV interrogate failed");
-               goto out;
-       }
-
-       *mactime = tsf_info->current_tsf_lsb |
-               (tsf_info->current_tsf_msb << 31);
-
-out:
-       kfree(tsf_info);
-       return ret;
-}
-
-int wl1251_acx_statistics(struct wl1251 *wl, struct acx_statistics *stats)
-{
-       int ret;
-
-       wl1251_debug(DEBUG_ACX, "acx statistics");
-
-       ret = wl1251_cmd_interrogate(wl, ACX_STATISTICS, stats,
-                                    sizeof(*stats));
-       if (ret < 0) {
-               wl1251_warning("acx statistics failed: %d", ret);
-               return -ENOMEM;
-       }
-
-       return 0;
-}
-
-int wl1251_acx_rate_policies(struct wl1251 *wl)
-{
-       struct acx_rate_policy *acx;
-       int ret = 0;
-
-       wl1251_debug(DEBUG_ACX, "acx rate policies");
-
-       acx = kzalloc(sizeof(*acx), GFP_KERNEL);
-
-       if (!acx) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       /* configure one default (one-size-fits-all) rate class */
-       acx->rate_class_cnt = 1;
-       acx->rate_class[0].enabled_rates = ACX_RATE_MASK_UNSPECIFIED;
-       acx->rate_class[0].short_retry_limit = ACX_RATE_RETRY_LIMIT;
-       acx->rate_class[0].long_retry_limit = ACX_RATE_RETRY_LIMIT;
-       acx->rate_class[0].aflags = 0;
-
-       ret = wl1251_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx));
-       if (ret < 0) {
-               wl1251_warning("Setting of rate policies failed: %d", ret);
-               goto out;
-       }
-
-out:
-       kfree(acx);
-       return ret;
-}
-
-int wl1251_acx_mem_cfg(struct wl1251 *wl)
-{
-       struct wl1251_acx_config_memory *mem_conf;
-       int ret, i;
-
-       wl1251_debug(DEBUG_ACX, "acx mem cfg");
-
-       mem_conf = kzalloc(sizeof(*mem_conf), GFP_KERNEL);
-       if (!mem_conf) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       /* memory config */
-       mem_conf->mem_config.num_stations = cpu_to_le16(DEFAULT_NUM_STATIONS);
-       mem_conf->mem_config.rx_mem_block_num = 35;
-       mem_conf->mem_config.tx_min_mem_block_num = 64;
-       mem_conf->mem_config.num_tx_queues = MAX_TX_QUEUES;
-       mem_conf->mem_config.host_if_options = HOSTIF_PKT_RING;
-       mem_conf->mem_config.num_ssid_profiles = 1;
-       mem_conf->mem_config.debug_buffer_size =
-               cpu_to_le16(TRACE_BUFFER_MAX_SIZE);
-
-       /* RX queue config */
-       mem_conf->rx_queue_config.dma_address = 0;
-       mem_conf->rx_queue_config.num_descs = ACX_RX_DESC_DEF;
-       mem_conf->rx_queue_config.priority = DEFAULT_RXQ_PRIORITY;
-       mem_conf->rx_queue_config.type = DEFAULT_RXQ_TYPE;
-
-       /* TX queue config */
-       for (i = 0; i < MAX_TX_QUEUES; i++) {
-               mem_conf->tx_queue_config[i].num_descs = ACX_TX_DESC_DEF;
-               mem_conf->tx_queue_config[i].attributes = i;
-       }
-
-       ret = wl1251_cmd_configure(wl, ACX_MEM_CFG, mem_conf,
-                                  sizeof(*mem_conf));
-       if (ret < 0) {
-               wl1251_warning("wl1251 mem config failed: %d", ret);
-               goto out;
-       }
-
-out:
-       kfree(mem_conf);
-       return ret;
-}
-
-int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim)
-{
-       struct wl1251_acx_wr_tbtt_and_dtim *acx;
-       int ret;
-
-       wl1251_debug(DEBUG_ACX, "acx tbtt and dtim");
-
-       acx = kzalloc(sizeof(*acx), GFP_KERNEL);
-       if (!acx) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       acx->tbtt = tbtt;
-       acx->dtim = dtim;
-
-       ret = wl1251_cmd_configure(wl, ACX_WR_TBTT_AND_DTIM,
-                                  acx, sizeof(*acx));
-       if (ret < 0) {
-               wl1251_warning("failed to set tbtt and dtim: %d", ret);
-               goto out;
-       }
-
-out:
-       kfree(acx);
-       return ret;
-}
-
-int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max,
-                     u8 aifs, u16 txop)
-{
-       struct wl1251_acx_ac_cfg *acx;
-       int ret = 0;
-
-       wl1251_debug(DEBUG_ACX, "acx ac cfg %d cw_ming %d cw_max %d "
-                    "aifs %d txop %d", ac, cw_min, cw_max, aifs, txop);
-
-       acx = kzalloc(sizeof(*acx), GFP_KERNEL);
-
-       if (!acx) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       acx->ac = ac;
-       acx->cw_min = cw_min;
-       acx->cw_max = cw_max;
-       acx->aifsn = aifs;
-       acx->txop_limit = txop;
-
-       ret = wl1251_cmd_configure(wl, ACX_AC_CFG, acx, sizeof(*acx));
-       if (ret < 0) {
-               wl1251_warning("acx ac cfg failed: %d", ret);
-               goto out;
-       }
-
-out:
-       kfree(acx);
-       return ret;
-}
-
-int wl1251_acx_tid_cfg(struct wl1251 *wl, u8 queue,
-                      enum wl1251_acx_channel_type type,
-                      u8 tsid, enum wl1251_acx_ps_scheme ps_scheme,
-                      enum wl1251_acx_ack_policy ack_policy)
-{
-       struct wl1251_acx_tid_cfg *acx;
-       int ret = 0;
-
-       wl1251_debug(DEBUG_ACX, "acx tid cfg %d type %d tsid %d "
-                    "ps_scheme %d ack_policy %d", queue, type, tsid,
-                    ps_scheme, ack_policy);
-
-       acx = kzalloc(sizeof(*acx), GFP_KERNEL);
-
-       if (!acx) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       acx->queue = queue;
-       acx->type = type;
-       acx->tsid = tsid;
-       acx->ps_scheme = ps_scheme;
-       acx->ack_policy = ack_policy;
-
-       ret = wl1251_cmd_configure(wl, ACX_TID_CFG, acx, sizeof(*acx));
-       if (ret < 0) {
-               wl1251_warning("acx tid cfg failed: %d", ret);
-               goto out;
-       }
-
-out:
-       kfree(acx);
-       return ret;
-}
diff --git a/drivers/net/wireless/wl12xx/wl1251_acx.h b/drivers/net/wireless/wl12xx/wl1251_acx.h
deleted file mode 100644 (file)
index c7cc5c1..0000000
+++ /dev/null
@@ -1,1411 +0,0 @@
-/*
- * This file is part of wl1251
- *
- * Copyright (c) 1998-2007 Texas Instruments Incorporated
- * Copyright (C) 2008 Nokia Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __WL1251_ACX_H__
-#define __WL1251_ACX_H__
-
-#include "wl1251.h"
-#include "wl1251_cmd.h"
-
-/* Target's information element */
-struct acx_header {
-       struct wl1251_cmd_header cmd;
-
-       /* acx (or information element) header */
-       u16 id;
-
-       /* payload length (not including headers */
-       u16 len;
-} __packed;
-
-struct acx_error_counter {
-       struct acx_header header;
-
-       /* The number of PLCP errors since the last time this */
-       /* information element was interrogated. This field is */
-       /* automatically cleared when it is interrogated.*/
-       u32 PLCP_error;
-
-       /* The number of FCS errors since the last time this */
-       /* information element was interrogated. This field is */
-       /* automatically cleared when it is interrogated.*/
-       u32 FCS_error;
-
-       /* The number of MPDUs without PLCP header errors received*/
-       /* since the last time this information element was interrogated. */
-       /* This field is automatically cleared when it is interrogated.*/
-       u32 valid_frame;
-
-       /* the number of missed sequence numbers in the squentially */
-       /* values of frames seq numbers */
-       u32 seq_num_miss;
-} __packed;
-
-struct acx_revision {
-       struct acx_header header;
-
-       /*
-        * The WiLink firmware version, an ASCII string x.x.x.x,
-        * that uniquely identifies the current firmware.
-        * The left most digit is incremented each time a
-        * significant change is made to the firmware, such as
-        * code redesign or new platform support.
-        * The second digit is incremented when major enhancements
-        * are added or major fixes are made.
-        * The third digit is incremented for each GA release.
-        * The fourth digit is incremented for each build.
-        * The first two digits identify a firmware release version,
-        * in other words, a unique set of features.
-        * The first three digits identify a GA release.
-        */
-       char fw_version[20];
-
-       /*
-        * This 4 byte field specifies the WiLink hardware version.
-        * bits 0  - 15: Reserved.
-        * bits 16 - 23: Version ID - The WiLink version ID
-        *              (1 = first spin, 2 = second spin, and so on).
-        * bits 24 - 31: Chip ID - The WiLink chip ID.
-        */
-       u32 hw_version;
-} __packed;
-
-enum wl1251_psm_mode {
-       /* Active mode */
-       WL1251_PSM_CAM = 0,
-
-       /* Power save mode */
-       WL1251_PSM_PS = 1,
-
-       /* Extreme low power */
-       WL1251_PSM_ELP = 2,
-};
-
-struct acx_sleep_auth {
-       struct acx_header header;
-
-       /* The sleep level authorization of the device. */
-       /* 0 - Always active*/
-       /* 1 - Power down mode: light / fast sleep*/
-       /* 2 - ELP mode: Deep / Max sleep*/
-       u8  sleep_auth;
-       u8  padding[3];
-} __packed;
-
-enum {
-       HOSTIF_PCI_MASTER_HOST_INDIRECT,
-       HOSTIF_PCI_MASTER_HOST_DIRECT,
-       HOSTIF_SLAVE,
-       HOSTIF_PKT_RING,
-       HOSTIF_DONTCARE = 0xFF
-};
-
-#define DEFAULT_UCAST_PRIORITY          0
-#define DEFAULT_RX_Q_PRIORITY           0
-#define DEFAULT_NUM_STATIONS            1
-#define DEFAULT_RXQ_PRIORITY            0 /* low 0 .. 15 high  */
-#define DEFAULT_RXQ_TYPE                0x07    /* All frames, Data/Ctrl/Mgmt */
-#define TRACE_BUFFER_MAX_SIZE           256
-
-#define  DP_RX_PACKET_RING_CHUNK_SIZE 1600
-#define  DP_TX_PACKET_RING_CHUNK_SIZE 1600
-#define  DP_RX_PACKET_RING_CHUNK_NUM 2
-#define  DP_TX_PACKET_RING_CHUNK_NUM 2
-#define  DP_TX_COMPLETE_TIME_OUT 20
-#define  FW_TX_CMPLT_BLOCK_SIZE 16
-
-struct acx_data_path_params {
-       struct acx_header header;
-
-       u16 rx_packet_ring_chunk_size;
-       u16 tx_packet_ring_chunk_size;
-
-       u8 rx_packet_ring_chunk_num;
-       u8 tx_packet_ring_chunk_num;
-
-       /*
-        * Maximum number of packets that can be gathered
-        * in the TX complete ring before an interrupt
-        * is generated.
-        */
-       u8 tx_complete_threshold;
-
-       /* Number of pending TX complete entries in cyclic ring.*/
-       u8 tx_complete_ring_depth;
-
-       /*
-        * Max num microseconds since a packet enters the TX
-        * complete ring until an interrupt is generated.
-        */
-       u32 tx_complete_timeout;
-} __packed;
-
-
-struct acx_data_path_params_resp {
-       struct acx_header header;
-
-       u16 rx_packet_ring_chunk_size;
-       u16 tx_packet_ring_chunk_size;
-
-       u8 rx_packet_ring_chunk_num;
-       u8 tx_packet_ring_chunk_num;
-
-       u8 pad[2];
-
-       u32 rx_packet_ring_addr;
-       u32 tx_packet_ring_addr;
-
-       u32 rx_control_addr;
-       u32 tx_control_addr;
-
-       u32 tx_complete_addr;
-} __packed;
-
-#define TX_MSDU_LIFETIME_MIN       0
-#define TX_MSDU_LIFETIME_MAX       3000
-#define TX_MSDU_LIFETIME_DEF       512
-#define RX_MSDU_LIFETIME_MIN       0
-#define RX_MSDU_LIFETIME_MAX       0xFFFFFFFF
-#define RX_MSDU_LIFETIME_DEF       512000
-
-struct acx_rx_msdu_lifetime {
-       struct acx_header header;
-
-       /*
-        * The maximum amount of time, in TU, before the
-        * firmware discards the MSDU.
-        */
-       u32 lifetime;
-} __packed;
-
-/*
- * RX Config Options Table
- * Bit         Definition
- * ===         ==========
- * 31:14               Reserved
- * 13          Copy RX Status - when set, write three receive status words
- *             to top of rx'd MPDUs.
- *             When cleared, do not write three status words (added rev 1.5)
- * 12          Reserved
- * 11          RX Complete upon FCS error - when set, give rx complete
- *             interrupt for FCS errors, after the rx filtering, e.g. unicast
- *             frames not to us with FCS error will not generate an interrupt.
- * 10          SSID Filter Enable - When set, the WiLink discards all beacon,
- *             probe request, and probe response frames with an SSID that does
- *             not match the SSID specified by the host in the START/JOIN
- *             command.
- *             When clear, the WiLink receives frames with any SSID.
- * 9           Broadcast Filter Enable - When set, the WiLink discards all
- *             broadcast frames. When clear, the WiLink receives all received
- *             broadcast frames.
- * 8:6         Reserved
- * 5           BSSID Filter Enable - When set, the WiLink discards any frames
- *             with a BSSID that does not match the BSSID specified by the
- *             host.
- *             When clear, the WiLink receives frames from any BSSID.
- * 4           MAC Addr Filter - When set, the WiLink discards any frames
- *             with a destination address that does not match the MAC address
- *             of the adaptor.
- *             When clear, the WiLink receives frames destined to any MAC
- *             address.
- * 3           Promiscuous - When set, the WiLink receives all valid frames
- *             (i.e., all frames that pass the FCS check).
- *             When clear, only frames that pass the other filters specified
- *             are received.
- * 2           FCS - When set, the WiLink includes the FCS with the received
- *             frame.
- *             When cleared, the FCS is discarded.
- * 1           PLCP header - When set, write all data from baseband to frame
- *             buffer including PHY header.
- * 0           Reserved - Always equal to 0.
- *
- * RX Filter Options Table
- * Bit         Definition
- * ===         ==========
- * 31:12               Reserved - Always equal to 0.
- * 11          Association - When set, the WiLink receives all association
- *             related frames (association request/response, reassocation
- *             request/response, and disassociation). When clear, these frames
- *             are discarded.
- * 10          Auth/De auth - When set, the WiLink receives all authentication
- *             and de-authentication frames. When clear, these frames are
- *             discarded.
- * 9           Beacon - When set, the WiLink receives all beacon frames.
- *             When clear, these frames are discarded.
- * 8           Contention Free - When set, the WiLink receives all contention
- *             free frames.
- *             When clear, these frames are discarded.
- * 7           Control - When set, the WiLink receives all control frames.
- *             When clear, these frames are discarded.
- * 6           Data - When set, the WiLink receives all data frames.
- *             When clear, these frames are discarded.
- * 5           FCS Error - When set, the WiLink receives frames that have FCS
- *             errors.
- *             When clear, these frames are discarded.
- * 4           Management - When set, the WiLink receives all management
- *             frames.
- *             When clear, these frames are discarded.
- * 3           Probe Request - When set, the WiLink receives all probe request
- *             frames.
- *             When clear, these frames are discarded.
- * 2           Probe Response - When set, the WiLink receives all probe
- *             response frames.
- *             When clear, these frames are discarded.
- * 1           RTS/CTS/ACK - When set, the WiLink receives all RTS, CTS and ACK
- *             frames.
- *             When clear, these frames are discarded.
- * 0           Rsvd Type/Sub Type - When set, the WiLink receives all frames
- *             that have reserved frame types and sub types as defined by the
- *             802.11 specification.
- *             When clear, these frames are discarded.
- */
-struct acx_rx_config {
-       struct acx_header header;
-
-       u32 config_options;
-       u32 filter_options;
-} __packed;
-
-enum {
-       QOS_AC_BE = 0,
-       QOS_AC_BK,
-       QOS_AC_VI,
-       QOS_AC_VO,
-       QOS_HIGHEST_AC_INDEX = QOS_AC_VO,
-};
-
-#define MAX_NUM_OF_AC             (QOS_HIGHEST_AC_INDEX+1)
-#define FIRST_AC_INDEX            QOS_AC_BE
-#define MAX_NUM_OF_802_1d_TAGS    8
-#define AC_PARAMS_MAX_TSID        15
-#define MAX_APSD_CONF             0xffff
-
-#define  QOS_TX_HIGH_MIN      (0)
-#define  QOS_TX_HIGH_MAX      (100)
-
-#define  QOS_TX_HIGH_BK_DEF   (25)
-#define  QOS_TX_HIGH_BE_DEF   (35)
-#define  QOS_TX_HIGH_VI_DEF   (35)
-#define  QOS_TX_HIGH_VO_DEF   (35)
-
-#define  QOS_TX_LOW_BK_DEF    (15)
-#define  QOS_TX_LOW_BE_DEF    (25)
-#define  QOS_TX_LOW_VI_DEF    (25)
-#define  QOS_TX_LOW_VO_DEF    (25)
-
-struct acx_tx_queue_qos_config {
-       struct acx_header header;
-
-       u8 qid;
-       u8 pad[3];
-
-       /* Max number of blocks allowd in the queue */
-       u16 high_threshold;
-
-       /* Lowest memory blocks guaranteed for this queue */
-       u16 low_threshold;
-} __packed;
-
-struct acx_packet_detection {
-       struct acx_header header;
-
-       u32 threshold;
-} __packed;
-
-
-enum acx_slot_type {
-       SLOT_TIME_LONG = 0,
-       SLOT_TIME_SHORT = 1,
-       DEFAULT_SLOT_TIME = SLOT_TIME_SHORT,
-       MAX_SLOT_TIMES = 0xFF
-};
-
-#define STATION_WONE_INDEX 0
-
-struct acx_slot {
-       struct acx_header header;
-
-       u8 wone_index; /* Reserved */
-       u8 slot_time;
-       u8 reserved[6];
-} __packed;
-
-
-#define ADDRESS_GROUP_MAX      (8)
-#define ADDRESS_GROUP_MAX_LEN  (ETH_ALEN * ADDRESS_GROUP_MAX)
-
-struct acx_dot11_grp_addr_tbl {
-       struct acx_header header;
-
-       u8 enabled;
-       u8 num_groups;
-       u8 pad[2];
-       u8 mac_table[ADDRESS_GROUP_MAX_LEN];
-} __packed;
-
-
-#define  RX_TIMEOUT_PS_POLL_MIN    0
-#define  RX_TIMEOUT_PS_POLL_MAX    (200000)
-#define  RX_TIMEOUT_PS_POLL_DEF    (15)
-#define  RX_TIMEOUT_UPSD_MIN       0
-#define  RX_TIMEOUT_UPSD_MAX       (200000)
-#define  RX_TIMEOUT_UPSD_DEF       (15)
-
-struct acx_rx_timeout {
-       struct acx_header header;
-
-       /*
-        * The longest time the STA will wait to receive
-        * traffic from the AP after a PS-poll has been
-        * transmitted.
-        */
-       u16 ps_poll_timeout;
-
-       /*
-        * The longest time the STA will wait to receive
-        * traffic from the AP after a frame has been sent
-        * from an UPSD enabled queue.
-        */
-       u16 upsd_timeout;
-} __packed;
-
-#define RTS_THRESHOLD_MIN              0
-#define RTS_THRESHOLD_MAX              4096
-#define RTS_THRESHOLD_DEF              2347
-
-struct acx_rts_threshold {
-       struct acx_header header;
-
-       u16 threshold;
-       u8 pad[2];
-} __packed;
-
-struct acx_beacon_filter_option {
-       struct acx_header header;
-
-       u8 enable;
-
-       /*
-        * The number of beacons without the unicast TIM
-        * bit set that the firmware buffers before
-        * signaling the host about ready frames.
-        * When set to 0 and the filter is enabled, beacons
-        * without the unicast TIM bit set are dropped.
-        */
-       u8 max_num_beacons;
-       u8 pad[2];
-} __packed;
-
-/*
- * ACXBeaconFilterEntry (not 221)
- * Byte Offset     Size (Bytes)    Definition
- * ===========     ============    ==========
- * 0                           1               IE identifier
- * 1               1               Treatment bit mask
- *
- * ACXBeaconFilterEntry (221)
- * Byte Offset     Size (Bytes)    Definition
- * ===========     ============    ==========
- * 0               1               IE identifier
- * 1               1               Treatment bit mask
- * 2               3               OUI
- * 5               1               Type
- * 6               2               Version
- *
- *
- * Treatment bit mask - The information element handling:
- * bit 0 - The information element is compared and transferred
- * in case of change.
- * bit 1 - The information element is transferred to the host
- * with each appearance or disappearance.
- * Note that both bits can be set at the same time.
- */
-#define        BEACON_FILTER_TABLE_MAX_IE_NUM                 (32)
-#define BEACON_FILTER_TABLE_MAX_VENDOR_SPECIFIC_IE_NUM (6)
-#define BEACON_FILTER_TABLE_IE_ENTRY_SIZE             (2)
-#define BEACON_FILTER_TABLE_EXTRA_VENDOR_SPECIFIC_IE_SIZE (6)
-#define BEACON_FILTER_TABLE_MAX_SIZE ((BEACON_FILTER_TABLE_MAX_IE_NUM * \
-                           BEACON_FILTER_TABLE_IE_ENTRY_SIZE) + \
-                          (BEACON_FILTER_TABLE_MAX_VENDOR_SPECIFIC_IE_NUM * \
-                           BEACON_FILTER_TABLE_EXTRA_VENDOR_SPECIFIC_IE_SIZE))
-
-#define BEACON_RULE_PASS_ON_CHANGE                     BIT(0)
-#define BEACON_RULE_PASS_ON_APPEARANCE                 BIT(1)
-
-#define BEACON_FILTER_IE_ID_CHANNEL_SWITCH_ANN         (37)
-
-struct acx_beacon_filter_ie_table {
-       struct acx_header header;
-
-       u8 num_ie;
-       u8 pad[3];
-       u8 table[BEACON_FILTER_TABLE_MAX_SIZE];
-} __packed;
-
-#define SYNCH_FAIL_DEFAULT_THRESHOLD    10     /* number of beacons */
-#define NO_BEACON_DEFAULT_TIMEOUT       (500) /* in microseconds */
-
-struct acx_conn_monit_params {
-       struct acx_header header;
-
-       u32 synch_fail_thold; /* number of beacons missed */
-       u32 bss_lose_timeout; /* number of TU's from synch fail */
-} __packed;
-
-enum {
-       SG_ENABLE = 0,
-       SG_DISABLE,
-       SG_SENSE_NO_ACTIVITY,
-       SG_SENSE_ACTIVE
-};
-
-struct acx_bt_wlan_coex {
-       struct acx_header header;
-
-       /*
-        * 0 -> PTA enabled
-        * 1 -> PTA disabled
-        * 2 -> sense no active mode, i.e.
-        *      an interrupt is sent upon
-        *      BT activity.
-        * 3 -> PTA is switched on in response
-        *      to the interrupt sending.
-        */
-       u8 enable;
-       u8 pad[3];
-} __packed;
-
-#define PTA_ANTENNA_TYPE_DEF             (0)
-#define PTA_BT_HP_MAXTIME_DEF            (2000)
-#define PTA_WLAN_HP_MAX_TIME_DEF         (5000)
-#define PTA_SENSE_DISABLE_TIMER_DEF      (1350)
-#define PTA_PROTECTIVE_RX_TIME_DEF       (1500)
-#define PTA_PROTECTIVE_TX_TIME_DEF       (1500)
-#define PTA_TIMEOUT_NEXT_BT_LP_PACKET_DEF (3000)
-#define PTA_SIGNALING_TYPE_DEF           (1)
-#define PTA_AFH_LEVERAGE_ON_DEF                  (0)
-#define PTA_NUMBER_QUIET_CYCLE_DEF       (0)
-#define PTA_MAX_NUM_CTS_DEF              (3)
-#define PTA_NUMBER_OF_WLAN_PACKETS_DEF   (2)
-#define PTA_NUMBER_OF_BT_PACKETS_DEF     (2)
-#define PTA_PROTECTIVE_RX_TIME_FAST_DEF          (1500)
-#define PTA_PROTECTIVE_TX_TIME_FAST_DEF          (3000)
-#define PTA_CYCLE_TIME_FAST_DEF                  (8700)
-#define PTA_RX_FOR_AVALANCHE_DEF         (5)
-#define PTA_ELP_HP_DEF                   (0)
-#define PTA_ANTI_STARVE_PERIOD_DEF       (500)
-#define PTA_ANTI_STARVE_NUM_CYCLE_DEF    (4)
-#define PTA_ALLOW_PA_SD_DEF              (1)
-#define PTA_TIME_BEFORE_BEACON_DEF       (6300)
-#define PTA_HPDM_MAX_TIME_DEF            (1600)
-#define PTA_TIME_OUT_NEXT_WLAN_DEF       (2550)
-#define PTA_AUTO_MODE_NO_CTS_DEF         (0)
-#define PTA_BT_HP_RESPECTED_DEF                  (3)
-#define PTA_WLAN_RX_MIN_RATE_DEF         (24)
-#define PTA_ACK_MODE_DEF                 (1)
-
-struct acx_bt_wlan_coex_param {
-       struct acx_header header;
-
-       /*
-        * The minimum rate of a received WLAN packet in the STA,
-        * during protective mode, of which a new BT-HP request
-        * during this Rx will always be respected and gain the antenna.
-        */
-       u32 min_rate;
-
-       /* Max time the BT HP will be respected. */
-       u16 bt_hp_max_time;
-
-       /* Max time the WLAN HP will be respected. */
-       u16 wlan_hp_max_time;
-
-       /*
-        * The time between the last BT activity
-        * and the moment when the sense mode returns
-        * to SENSE_INACTIVE.
-        */
-       u16 sense_disable_timer;
-
-       /* Time before the next BT HP instance */
-       u16 rx_time_bt_hp;
-       u16 tx_time_bt_hp;
-
-       /* range: 10-20000    default: 1500 */
-       u16 rx_time_bt_hp_fast;
-       u16 tx_time_bt_hp_fast;
-
-       /* range: 2000-65535  default: 8700 */
-       u16 wlan_cycle_fast;
-
-       /* range: 0 - 15000 (Msec) default: 1000 */
-       u16 bt_anti_starvation_period;
-
-       /* range 400-10000(Usec) default: 3000 */
-       u16 next_bt_lp_packet;
-
-       /* Deafult: worst case for BT DH5 traffic */
-       u16 wake_up_beacon;
-
-       /* range: 0-50000(Usec) default: 1050 */
-       u16 hp_dm_max_guard_time;
-
-       /*
-        * This is to prevent both BT & WLAN antenna
-        * starvation.
-        * Range: 100-50000(Usec) default:2550
-        */
-       u16 next_wlan_packet;
-
-       /* 0 -> shared antenna */
-       u8 antenna_type;
-
-       /*
-        * 0 -> TI legacy
-        * 1 -> Palau
-        */
-       u8 signal_type;
-
-       /*
-        * BT AFH status
-        * 0 -> no AFH
-        * 1 -> from dedicated GPIO
-        * 2 -> AFH on (from host)
-        */
-       u8 afh_leverage_on;
-
-       /*
-        * The number of cycles during which no
-        * TX will be sent after 1 cycle of RX
-        * transaction in protective mode
-        */
-       u8 quiet_cycle_num;
-
-       /*
-        * The maximum number of CTSs that will
-        * be sent for receiving RX packet in
-        * protective mode
-        */
-       u8 max_cts;
-
-       /*
-        * The number of WLAN packets
-        * transferred in common mode before
-        * switching to BT.
-        */
-       u8 wlan_packets_num;
-
-       /*
-        * The number of BT packets
-        * transferred in common mode before
-        * switching to WLAN.
-        */
-       u8 bt_packets_num;
-
-       /* range: 1-255  default: 5 */
-       u8 missed_rx_avalanche;
-
-       /* range: 0-1    default: 1 */
-       u8 wlan_elp_hp;
-
-       /* range: 0 - 15  default: 4 */
-       u8 bt_anti_starvation_cycles;
-
-       u8 ack_mode_dual_ant;
-
-       /*
-        * Allow PA_SD assertion/de-assertion
-        * during enabled BT activity.
-        */
-       u8 pa_sd_enable;
-
-       /*
-        * Enable/Disable PTA in auto mode:
-        * Support Both Active & P.S modes
-        */
-       u8 pta_auto_mode_enable;
-
-       /* range: 0 - 20  default: 1 */
-       u8 bt_hp_respected_num;
-} __packed;
-
-#define CCA_THRSH_ENABLE_ENERGY_D       0x140A
-#define CCA_THRSH_DISABLE_ENERGY_D      0xFFEF
-
-struct acx_energy_detection {
-       struct acx_header header;
-
-       /* The RX Clear Channel Assessment threshold in the PHY */
-       u16 rx_cca_threshold;
-       u8 tx_energy_detection;
-       u8 pad;
-} __packed;
-
-#define BCN_RX_TIMEOUT_DEF_VALUE        10000
-#define BROADCAST_RX_TIMEOUT_DEF_VALUE  20000
-#define RX_BROADCAST_IN_PS_DEF_VALUE    1
-#define CONSECUTIVE_PS_POLL_FAILURE_DEF 4
-
-struct acx_beacon_broadcast {
-       struct acx_header header;
-
-       u16 beacon_rx_timeout;
-       u16 broadcast_timeout;
-
-       /* Enables receiving of broadcast packets in PS mode */
-       u8 rx_broadcast_in_ps;
-
-       /* Consecutive PS Poll failures before updating the host */
-       u8 ps_poll_threshold;
-       u8 pad[2];
-} __packed;
-
-struct acx_event_mask {
-       struct acx_header header;
-
-       u32 event_mask;
-       u32 high_event_mask; /* Unused */
-} __packed;
-
-#define CFG_RX_FCS             BIT(2)
-#define CFG_RX_ALL_GOOD                BIT(3)
-#define CFG_UNI_FILTER_EN      BIT(4)
-#define CFG_BSSID_FILTER_EN    BIT(5)
-#define CFG_MC_FILTER_EN       BIT(6)
-#define CFG_MC_ADDR0_EN                BIT(7)
-#define CFG_MC_ADDR1_EN                BIT(8)
-#define CFG_BC_REJECT_EN       BIT(9)
-#define CFG_SSID_FILTER_EN     BIT(10)
-#define CFG_RX_INT_FCS_ERROR   BIT(11)
-#define CFG_RX_INT_ENCRYPTED   BIT(12)
-#define CFG_RX_WR_RX_STATUS    BIT(13)
-#define CFG_RX_FILTER_NULTI    BIT(14)
-#define CFG_RX_RESERVE         BIT(15)
-#define CFG_RX_TIMESTAMP_TSF   BIT(16)
-
-#define CFG_RX_RSV_EN          BIT(0)
-#define CFG_RX_RCTS_ACK                BIT(1)
-#define CFG_RX_PRSP_EN         BIT(2)
-#define CFG_RX_PREQ_EN         BIT(3)
-#define CFG_RX_MGMT_EN         BIT(4)
-#define CFG_RX_FCS_ERROR       BIT(5)
-#define CFG_RX_DATA_EN         BIT(6)
-#define CFG_RX_CTL_EN          BIT(7)
-#define CFG_RX_CF_EN           BIT(8)
-#define CFG_RX_BCN_EN          BIT(9)
-#define CFG_RX_AUTH_EN         BIT(10)
-#define CFG_RX_ASSOC_EN                BIT(11)
-
-#define SCAN_PASSIVE           BIT(0)
-#define SCAN_5GHZ_BAND         BIT(1)
-#define SCAN_TRIGGERED         BIT(2)
-#define SCAN_PRIORITY_HIGH     BIT(3)
-
-struct acx_fw_gen_frame_rates {
-       struct acx_header header;
-
-       u8 tx_ctrl_frame_rate; /* RATE_* */
-       u8 tx_ctrl_frame_mod; /* CCK_* or PBCC_* */
-       u8 tx_mgt_frame_rate;
-       u8 tx_mgt_frame_mod;
-} __packed;
-
-/* STA MAC */
-struct acx_dot11_station_id {
-       struct acx_header header;
-
-       u8 mac[ETH_ALEN];
-       u8 pad[2];
-} __packed;
-
-struct acx_feature_config {
-       struct acx_header header;
-
-       u32 options;
-       u32 data_flow_options;
-} __packed;
-
-struct acx_current_tx_power {
-       struct acx_header header;
-
-       u8  current_tx_power;
-       u8  padding[3];
-} __packed;
-
-struct acx_dot11_default_key {
-       struct acx_header header;
-
-       u8 id;
-       u8 pad[3];
-} __packed;
-
-struct acx_tsf_info {
-       struct acx_header header;
-
-       u32 current_tsf_msb;
-       u32 current_tsf_lsb;
-       u32 last_TBTT_msb;
-       u32 last_TBTT_lsb;
-       u8 last_dtim_count;
-       u8 pad[3];
-} __packed;
-
-enum acx_wake_up_event {
-       WAKE_UP_EVENT_BEACON_BITMAP     = 0x01, /* Wake on every Beacon*/
-       WAKE_UP_EVENT_DTIM_BITMAP       = 0x02, /* Wake on every DTIM*/
-       WAKE_UP_EVENT_N_DTIM_BITMAP     = 0x04, /* Wake on every Nth DTIM */
-       WAKE_UP_EVENT_N_BEACONS_BITMAP  = 0x08, /* Wake on every Nth Beacon */
-       WAKE_UP_EVENT_BITS_MASK         = 0x0F
-};
-
-struct acx_wake_up_condition {
-       struct acx_header header;
-
-       u8 wake_up_event; /* Only one bit can be set */
-       u8 listen_interval;
-       u8 pad[2];
-} __packed;
-
-struct acx_aid {
-       struct acx_header header;
-
-       /*
-        * To be set when associated with an AP.
-        */
-       u16 aid;
-       u8 pad[2];
-} __packed;
-
-enum acx_preamble_type {
-       ACX_PREAMBLE_LONG = 0,
-       ACX_PREAMBLE_SHORT = 1
-};
-
-struct acx_preamble {
-       struct acx_header header;
-
-       /*
-        * When set, the WiLink transmits the frames with a short preamble and
-        * when cleared, the WiLink transmits the frames with a long preamble.
-        */
-       u8 preamble;
-       u8 padding[3];
-} __packed;
-
-enum acx_ctsprotect_type {
-       CTSPROTECT_DISABLE = 0,
-       CTSPROTECT_ENABLE = 1
-};
-
-struct acx_ctsprotect {
-       struct acx_header header;
-       u8 ctsprotect;
-       u8 padding[3];
-} __packed;
-
-struct acx_tx_statistics {
-       u32 internal_desc_overflow;
-}  __packed;
-
-struct acx_rx_statistics {
-       u32 out_of_mem;
-       u32 hdr_overflow;
-       u32 hw_stuck;
-       u32 dropped;
-       u32 fcs_err;
-       u32 xfr_hint_trig;
-       u32 path_reset;
-       u32 reset_counter;
-} __packed;
-
-struct acx_dma_statistics {
-       u32 rx_requested;
-       u32 rx_errors;
-       u32 tx_requested;
-       u32 tx_errors;
-}  __packed;
-
-struct acx_isr_statistics {
-       /* host command complete */
-       u32 cmd_cmplt;
-
-       /* fiqisr() */
-       u32 fiqs;
-
-       /* (INT_STS_ND & INT_TRIG_RX_HEADER) */
-       u32 rx_headers;
-
-       /* (INT_STS_ND & INT_TRIG_RX_CMPLT) */
-       u32 rx_completes;
-
-       /* (INT_STS_ND & INT_TRIG_NO_RX_BUF) */
-       u32 rx_mem_overflow;
-
-       /* (INT_STS_ND & INT_TRIG_S_RX_RDY) */
-       u32 rx_rdys;
-
-       /* irqisr() */
-       u32 irqs;
-
-       /* (INT_STS_ND & INT_TRIG_TX_PROC) */
-       u32 tx_procs;
-
-       /* (INT_STS_ND & INT_TRIG_DECRYPT_DONE) */
-       u32 decrypt_done;
-
-       /* (INT_STS_ND & INT_TRIG_DMA0) */
-       u32 dma0_done;
-
-       /* (INT_STS_ND & INT_TRIG_DMA1) */
-       u32 dma1_done;
-
-       /* (INT_STS_ND & INT_TRIG_TX_EXC_CMPLT) */
-       u32 tx_exch_complete;
-
-       /* (INT_STS_ND & INT_TRIG_COMMAND) */
-       u32 commands;
-
-       /* (INT_STS_ND & INT_TRIG_RX_PROC) */
-       u32 rx_procs;
-
-       /* (INT_STS_ND & INT_TRIG_PM_802) */
-       u32 hw_pm_mode_changes;
-
-       /* (INT_STS_ND & INT_TRIG_ACKNOWLEDGE) */
-       u32 host_acknowledges;
-
-       /* (INT_STS_ND & INT_TRIG_PM_PCI) */
-       u32 pci_pm;
-
-       /* (INT_STS_ND & INT_TRIG_ACM_WAKEUP) */
-       u32 wakeups;
-
-       /* (INT_STS_ND & INT_TRIG_LOW_RSSI) */
-       u32 low_rssi;
-} __packed;
-
-struct acx_wep_statistics {
-       /* WEP address keys configured */
-       u32 addr_key_count;
-
-       /* default keys configured */
-       u32 default_key_count;
-
-       u32 reserved;
-
-       /* number of times that WEP key not found on lookup */
-       u32 key_not_found;
-
-       /* number of times that WEP key decryption failed */
-       u32 decrypt_fail;
-
-       /* WEP packets decrypted */
-       u32 packets;
-
-       /* WEP decrypt interrupts */
-       u32 interrupt;
-} __packed;
-
-#define ACX_MISSED_BEACONS_SPREAD 10
-
-struct acx_pwr_statistics {
-       /* the amount of enters into power save mode (both PD & ELP) */
-       u32 ps_enter;
-
-       /* the amount of enters into ELP mode */
-       u32 elp_enter;
-
-       /* the amount of missing beacon interrupts to the host */
-       u32 missing_bcns;
-
-       /* the amount of wake on host-access times */
-       u32 wake_on_host;
-
-       /* the amount of wake on timer-expire */
-       u32 wake_on_timer_exp;
-
-       /* the number of packets that were transmitted with PS bit set */
-       u32 tx_with_ps;
-
-       /* the number of packets that were transmitted with PS bit clear */
-       u32 tx_without_ps;
-
-       /* the number of received beacons */
-       u32 rcvd_beacons;
-
-       /* the number of entering into PowerOn (power save off) */
-       u32 power_save_off;
-
-       /* the number of entries into power save mode */
-       u16 enable_ps;
-
-       /*
-        * the number of exits from power save, not including failed PS
-        * transitions
-        */
-       u16 disable_ps;
-
-       /*
-        * the number of times the TSF counter was adjusted because
-        * of drift
-        */
-       u32 fix_tsf_ps;
-
-       /* Gives statistics about the spread continuous missed beacons.
-        * The 16 LSB are dedicated for the PS mode.
-        * The 16 MSB are dedicated for the PS mode.
-        * cont_miss_bcns_spread[0] - single missed beacon.
-        * cont_miss_bcns_spread[1] - two continuous missed beacons.
-        * cont_miss_bcns_spread[2] - three continuous missed beacons.
-        * ...
-        * cont_miss_bcns_spread[9] - ten and more continuous missed beacons.
-       */
-       u32 cont_miss_bcns_spread[ACX_MISSED_BEACONS_SPREAD];
-
-       /* the number of beacons in awake mode */
-       u32 rcvd_awake_beacons;
-} __packed;
-
-struct acx_mic_statistics {
-       u32 rx_pkts;
-       u32 calc_failure;
-} __packed;
-
-struct acx_aes_statistics {
-       u32 encrypt_fail;
-       u32 decrypt_fail;
-       u32 encrypt_packets;
-       u32 decrypt_packets;
-       u32 encrypt_interrupt;
-       u32 decrypt_interrupt;
-} __packed;
-
-struct acx_event_statistics {
-       u32 heart_beat;
-       u32 calibration;
-       u32 rx_mismatch;
-       u32 rx_mem_empty;
-       u32 rx_pool;
-       u32 oom_late;
-       u32 phy_transmit_error;
-       u32 tx_stuck;
-} __packed;
-
-struct acx_ps_statistics {
-       u32 pspoll_timeouts;
-       u32 upsd_timeouts;
-       u32 upsd_max_sptime;
-       u32 upsd_max_apturn;
-       u32 pspoll_max_apturn;
-       u32 pspoll_utilization;
-       u32 upsd_utilization;
-} __packed;
-
-struct acx_rxpipe_statistics {
-       u32 rx_prep_beacon_drop;
-       u32 descr_host_int_trig_rx_data;
-       u32 beacon_buffer_thres_host_int_trig_rx_data;
-       u32 missed_beacon_host_int_trig_rx_data;
-       u32 tx_xfr_host_int_trig_rx_data;
-} __packed;
-
-struct acx_statistics {
-       struct acx_header header;
-
-       struct acx_tx_statistics tx;
-       struct acx_rx_statistics rx;
-       struct acx_dma_statistics dma;
-       struct acx_isr_statistics isr;
-       struct acx_wep_statistics wep;
-       struct acx_pwr_statistics pwr;
-       struct acx_aes_statistics aes;
-       struct acx_mic_statistics mic;
-       struct acx_event_statistics event;
-       struct acx_ps_statistics ps;
-       struct acx_rxpipe_statistics rxpipe;
-} __packed;
-
-#define ACX_MAX_RATE_CLASSES       8
-#define ACX_RATE_MASK_UNSPECIFIED  0
-#define ACX_RATE_RETRY_LIMIT      10
-
-struct acx_rate_class {
-       u32 enabled_rates;
-       u8 short_retry_limit;
-       u8 long_retry_limit;
-       u8 aflags;
-       u8 reserved;
-} __packed;
-
-struct acx_rate_policy {
-       struct acx_header header;
-
-       u32 rate_class_cnt;
-       struct acx_rate_class rate_class[ACX_MAX_RATE_CLASSES];
-} __packed;
-
-struct wl1251_acx_memory {
-       __le16 num_stations; /* number of STAs to be supported. */
-       u16 reserved_1;
-
-       /*
-        * Nmber of memory buffers for the RX mem pool.
-        * The actual number may be less if there are
-        * not enough blocks left for the minimum num
-        * of TX ones.
-        */
-       u8 rx_mem_block_num;
-       u8 reserved_2;
-       u8 num_tx_queues; /* From 1 to 16 */
-       u8 host_if_options; /* HOST_IF* */
-       u8 tx_min_mem_block_num;
-       u8 num_ssid_profiles;
-       __le16 debug_buffer_size;
-} __packed;
-
-
-#define ACX_RX_DESC_MIN                1
-#define ACX_RX_DESC_MAX                127
-#define ACX_RX_DESC_DEF                32
-struct wl1251_acx_rx_queue_config {
-       u8 num_descs;
-       u8 pad;
-       u8 type;
-       u8 priority;
-       __le32 dma_address;
-} __packed;
-
-#define ACX_TX_DESC_MIN                1
-#define ACX_TX_DESC_MAX                127
-#define ACX_TX_DESC_DEF                16
-struct wl1251_acx_tx_queue_config {
-    u8 num_descs;
-    u8 pad[2];
-    u8 attributes;
-} __packed;
-
-#define MAX_TX_QUEUE_CONFIGS 5
-#define MAX_TX_QUEUES 4
-struct wl1251_acx_config_memory {
-       struct acx_header header;
-
-       struct wl1251_acx_memory mem_config;
-       struct wl1251_acx_rx_queue_config rx_queue_config;
-       struct wl1251_acx_tx_queue_config tx_queue_config[MAX_TX_QUEUE_CONFIGS];
-} __packed;
-
-struct wl1251_acx_mem_map {
-       struct acx_header header;
-
-       void *code_start;
-       void *code_end;
-
-       void *wep_defkey_start;
-       void *wep_defkey_end;
-
-       void *sta_table_start;
-       void *sta_table_end;
-
-       void *packet_template_start;
-       void *packet_template_end;
-
-       void *queue_memory_start;
-       void *queue_memory_end;
-
-       void *packet_memory_pool_start;
-       void *packet_memory_pool_end;
-
-       void *debug_buffer1_start;
-       void *debug_buffer1_end;
-
-       void *debug_buffer2_start;
-       void *debug_buffer2_end;
-
-       /* Number of blocks FW allocated for TX packets */
-       u32 num_tx_mem_blocks;
-
-       /* Number of blocks FW allocated for RX packets */
-       u32 num_rx_mem_blocks;
-} __packed;
-
-
-struct wl1251_acx_wr_tbtt_and_dtim {
-
-       struct acx_header header;
-
-       /* Time in TUs between two consecutive beacons */
-       u16 tbtt;
-
-       /*
-        * DTIM period
-        * For BSS: Number of TBTTs in a DTIM period (range: 1-10)
-        * For IBSS: value shall be set to 1
-       */
-       u8  dtim;
-       u8  padding;
-} __packed;
-
-struct wl1251_acx_ac_cfg {
-       struct acx_header header;
-
-       /*
-        * Access Category - The TX queue's access category
-        * (refer to AccessCategory_enum)
-        */
-       u8 ac;
-
-       /*
-        * The contention window minimum size (in slots) for
-        * the access class.
-        */
-       u8 cw_min;
-
-       /*
-        * The contention window maximum size (in slots) for
-        * the access class.
-        */
-       u16 cw_max;
-
-       /* The AIF value (in slots) for the access class. */
-       u8 aifsn;
-
-       u8 reserved;
-
-       /* The TX Op Limit (in microseconds) for the access class. */
-       u16 txop_limit;
-} __packed;
-
-
-enum wl1251_acx_channel_type {
-       CHANNEL_TYPE_DCF        = 0,
-       CHANNEL_TYPE_EDCF       = 1,
-       CHANNEL_TYPE_HCCA       = 2,
-};
-
-enum wl1251_acx_ps_scheme {
-       /* regular ps: simple sending of packets */
-       WL1251_ACX_PS_SCHEME_LEGACY     = 0,
-
-       /* sending a packet triggers a unscheduled apsd downstream */
-       WL1251_ACX_PS_SCHEME_UPSD_TRIGGER       = 1,
-
-       /* a pspoll packet will be sent before every data packet */
-       WL1251_ACX_PS_SCHEME_LEGACY_PSPOLL      = 2,
-
-       /* scheduled apsd mode */
-       WL1251_ACX_PS_SCHEME_SAPSD              = 3,
-};
-
-enum wl1251_acx_ack_policy {
-       WL1251_ACX_ACK_POLICY_LEGACY    = 0,
-       WL1251_ACX_ACK_POLICY_NO_ACK    = 1,
-       WL1251_ACX_ACK_POLICY_BLOCK     = 2,
-};
-
-struct wl1251_acx_tid_cfg {
-       struct acx_header header;
-
-       /* tx queue id number (0-7) */
-       u8 queue;
-
-       /* channel access type for the queue, enum wl1251_acx_channel_type */
-       u8 type;
-
-       /* EDCA: ac index (0-3), HCCA: traffic stream id (8-15) */
-       u8 tsid;
-
-       /* ps scheme of the specified queue, enum wl1251_acx_ps_scheme */
-       u8 ps_scheme;
-
-       /* the tx queue ack policy, enum wl1251_acx_ack_policy */
-       u8 ack_policy;
-
-       u8 padding[3];
-
-       /* not supported */
-       u32 apsdconf[2];
-} __packed;
-
-/*************************************************************************
-
-    Host Interrupt Register (WiLink -> Host)
-
-**************************************************************************/
-
-/* RX packet is ready in Xfer buffer #0 */
-#define WL1251_ACX_INTR_RX0_DATA      BIT(0)
-
-/* TX result(s) are in the TX complete buffer */
-#define WL1251_ACX_INTR_TX_RESULT      BIT(1)
-
-/* OBSOLETE */
-#define WL1251_ACX_INTR_TX_XFR         BIT(2)
-
-/* RX packet is ready in Xfer buffer #1 */
-#define WL1251_ACX_INTR_RX1_DATA       BIT(3)
-
-/* Event was entered to Event MBOX #A */
-#define WL1251_ACX_INTR_EVENT_A                BIT(4)
-
-/* Event was entered to Event MBOX #B */
-#define WL1251_ACX_INTR_EVENT_B                BIT(5)
-
-/* OBSOLETE */
-#define WL1251_ACX_INTR_WAKE_ON_HOST   BIT(6)
-
-/* Trace meassge on MBOX #A */
-#define WL1251_ACX_INTR_TRACE_A                BIT(7)
-
-/* Trace meassge on MBOX #B */
-#define WL1251_ACX_INTR_TRACE_B                BIT(8)
-
-/* Command processing completion */
-#define WL1251_ACX_INTR_CMD_COMPLETE   BIT(9)
-
-/* Init sequence is done */
-#define WL1251_ACX_INTR_INIT_COMPLETE  BIT(14)
-
-#define WL1251_ACX_INTR_ALL           0xFFFFFFFF
-
-enum {
-       ACX_WAKE_UP_CONDITIONS      = 0x0002,
-       ACX_MEM_CFG                 = 0x0003,
-       ACX_SLOT                    = 0x0004,
-       ACX_QUEUE_HEAD              = 0x0005, /* for MASTER mode only */
-       ACX_AC_CFG                  = 0x0007,
-       ACX_MEM_MAP                 = 0x0008,
-       ACX_AID                     = 0x000A,
-       ACX_RADIO_PARAM             = 0x000B, /* Not used */
-       ACX_CFG                     = 0x000C, /* Not used */
-       ACX_FW_REV                  = 0x000D,
-       ACX_MEDIUM_USAGE            = 0x000F,
-       ACX_RX_CFG                  = 0x0010,
-       ACX_TX_QUEUE_CFG            = 0x0011, /* FIXME: only used by wl1251 */
-       ACX_BSS_IN_PS               = 0x0012, /* for AP only */
-       ACX_STATISTICS              = 0x0013, /* Debug API */
-       ACX_FEATURE_CFG             = 0x0015,
-       ACX_MISC_CFG                = 0x0017, /* Not used */
-       ACX_TID_CFG                 = 0x001A,
-       ACX_BEACON_FILTER_OPT       = 0x001F,
-       ACX_LOW_RSSI                = 0x0020,
-       ACX_NOISE_HIST              = 0x0021,
-       ACX_HDK_VERSION             = 0x0022, /* ??? */
-       ACX_PD_THRESHOLD            = 0x0023,
-       ACX_DATA_PATH_PARAMS        = 0x0024, /* WO */
-       ACX_DATA_PATH_RESP_PARAMS   = 0x0024, /* RO */
-       ACX_CCA_THRESHOLD           = 0x0025,
-       ACX_EVENT_MBOX_MASK         = 0x0026,
-#ifdef FW_RUNNING_AS_AP
-       ACX_DTIM_PERIOD             = 0x0027, /* for AP only */
-#else
-       ACX_WR_TBTT_AND_DTIM        = 0x0027, /* STA only */
-#endif
-       ACX_ACI_OPTION_CFG          = 0x0029, /* OBSOLETE (for 1251)*/
-       ACX_GPIO_CFG                = 0x002A, /* Not used */
-       ACX_GPIO_SET                = 0x002B, /* Not used */
-       ACX_PM_CFG                  = 0x002C, /* To Be Documented */
-       ACX_CONN_MONIT_PARAMS       = 0x002D,
-       ACX_AVERAGE_RSSI            = 0x002E, /* Not used */
-       ACX_CONS_TX_FAILURE         = 0x002F,
-       ACX_BCN_DTIM_OPTIONS        = 0x0031,
-       ACX_SG_ENABLE               = 0x0032,
-       ACX_SG_CFG                  = 0x0033,
-       ACX_ANTENNA_DIVERSITY_CFG   = 0x0035, /* To Be Documented */
-       ACX_LOW_SNR                 = 0x0037, /* To Be Documented */
-       ACX_BEACON_FILTER_TABLE     = 0x0038,
-       ACX_ARP_IP_FILTER           = 0x0039,
-       ACX_ROAMING_STATISTICS_TBL  = 0x003B,
-       ACX_RATE_POLICY             = 0x003D,
-       ACX_CTS_PROTECTION          = 0x003E,
-       ACX_SLEEP_AUTH              = 0x003F,
-       ACX_PREAMBLE_TYPE           = 0x0040,
-       ACX_ERROR_CNT               = 0x0041,
-       ACX_FW_GEN_FRAME_RATES      = 0x0042,
-       ACX_IBSS_FILTER             = 0x0044,
-       ACX_SERVICE_PERIOD_TIMEOUT  = 0x0045,
-       ACX_TSF_INFO                = 0x0046,
-       ACX_CONFIG_PS_WMM           = 0x0049,
-       ACX_ENABLE_RX_DATA_FILTER   = 0x004A,
-       ACX_SET_RX_DATA_FILTER      = 0x004B,
-       ACX_GET_DATA_FILTER_STATISTICS = 0x004C,
-       ACX_POWER_LEVEL_TABLE       = 0x004D,
-       ACX_BET_ENABLE              = 0x0050,
-       DOT11_STATION_ID            = 0x1001,
-       DOT11_RX_MSDU_LIFE_TIME     = 0x1004,
-       DOT11_CUR_TX_PWR            = 0x100D,
-       DOT11_DEFAULT_KEY           = 0x1010,
-       DOT11_RX_DOT11_MODE         = 0x1012,
-       DOT11_RTS_THRESHOLD         = 0x1013,
-       DOT11_GROUP_ADDRESS_TBL     = 0x1014,
-
-       MAX_DOT11_IE = DOT11_GROUP_ADDRESS_TBL,
-
-       MAX_IE = 0xFFFF
-};
-
-
-int wl1251_acx_frame_rates(struct wl1251 *wl, u8 ctrl_rate, u8 ctrl_mod,
-                          u8 mgt_rate, u8 mgt_mod);
-int wl1251_acx_station_id(struct wl1251 *wl);
-int wl1251_acx_default_key(struct wl1251 *wl, u8 key_id);
-int wl1251_acx_wake_up_conditions(struct wl1251 *wl, u8 wake_up_event,
-                                 u8 listen_interval);
-int wl1251_acx_sleep_auth(struct wl1251 *wl, u8 sleep_auth);
-int wl1251_acx_fw_version(struct wl1251 *wl, char *buf, size_t len);
-int wl1251_acx_tx_power(struct wl1251 *wl, int power);
-int wl1251_acx_feature_cfg(struct wl1251 *wl);
-int wl1251_acx_mem_map(struct wl1251 *wl,
-                      struct acx_header *mem_map, size_t len);
-int wl1251_acx_data_path_params(struct wl1251 *wl,
-                               struct acx_data_path_params_resp *data_path);
-int wl1251_acx_rx_msdu_life_time(struct wl1251 *wl, u32 life_time);
-int wl1251_acx_rx_config(struct wl1251 *wl, u32 config, u32 filter);
-int wl1251_acx_pd_threshold(struct wl1251 *wl);
-int wl1251_acx_slot(struct wl1251 *wl, enum acx_slot_type slot_time);
-int wl1251_acx_group_address_tbl(struct wl1251 *wl);
-int wl1251_acx_service_period_timeout(struct wl1251 *wl);
-int wl1251_acx_rts_threshold(struct wl1251 *wl, u16 rts_threshold);
-int wl1251_acx_beacon_filter_opt(struct wl1251 *wl, bool enable_filter);
-int wl1251_acx_beacon_filter_table(struct wl1251 *wl);
-int wl1251_acx_conn_monit_params(struct wl1251 *wl);
-int wl1251_acx_sg_enable(struct wl1251 *wl);
-int wl1251_acx_sg_cfg(struct wl1251 *wl);
-int wl1251_acx_cca_threshold(struct wl1251 *wl);
-int wl1251_acx_bcn_dtim_options(struct wl1251 *wl);
-int wl1251_acx_aid(struct wl1251 *wl, u16 aid);
-int wl1251_acx_event_mbox_mask(struct wl1251 *wl, u32 event_mask);
-int wl1251_acx_set_preamble(struct wl1251 *wl, enum acx_preamble_type preamble);
-int wl1251_acx_cts_protect(struct wl1251 *wl,
-                           enum acx_ctsprotect_type ctsprotect);
-int wl1251_acx_statistics(struct wl1251 *wl, struct acx_statistics *stats);
-int wl1251_acx_tsf_info(struct wl1251 *wl, u64 *mactime);
-int wl1251_acx_rate_policies(struct wl1251 *wl);
-int wl1251_acx_mem_cfg(struct wl1251 *wl);
-int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim);
-int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max,
-                     u8 aifs, u16 txop);
-int wl1251_acx_tid_cfg(struct wl1251 *wl, u8 queue,
-                      enum wl1251_acx_channel_type type,
-                      u8 tsid, enum wl1251_acx_ps_scheme ps_scheme,
-                      enum wl1251_acx_ack_policy ack_policy);
-
-#endif /* __WL1251_ACX_H__ */
diff --git a/drivers/net/wireless/wl12xx/wl1251_boot.c b/drivers/net/wireless/wl12xx/wl1251_boot.c
deleted file mode 100644 (file)
index 468b47b..0000000
+++ /dev/null
@@ -1,557 +0,0 @@
-/*
- * This file is part of wl1251
- *
- * Copyright (C) 2008 Nokia Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#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"
-
-void wl1251_boot_target_enable_interrupts(struct wl1251 *wl)
-{
-       wl1251_reg_write32(wl, ACX_REG_INTERRUPT_MASK, ~(wl->intr_mask));
-       wl1251_reg_write32(wl, HI_CFG, HI_CFG_DEF_VAL);
-}
-
-int wl1251_boot_soft_reset(struct wl1251 *wl)
-{
-       unsigned long timeout;
-       u32 boot_data;
-
-       /* perform soft reset */
-       wl1251_reg_write32(wl, ACX_REG_SLV_SOFT_RESET, ACX_SLV_SOFT_RESET_BIT);
-
-       /* SOFT_RESET is self clearing */
-       timeout = jiffies + usecs_to_jiffies(SOFT_RESET_MAX_TIME);
-       while (1) {
-               boot_data = wl1251_reg_read32(wl, ACX_REG_SLV_SOFT_RESET);
-               wl1251_debug(DEBUG_BOOT, "soft reset bootdata 0x%x", boot_data);
-               if ((boot_data & ACX_SLV_SOFT_RESET_BIT) == 0)
-                       break;
-
-               if (time_after(jiffies, timeout)) {
-                       /* 1.2 check pWhalBus->uSelfClearTime if the
-                        * timeout was reached */
-                       wl1251_error("soft reset timeout");
-                       return -1;
-               }
-
-               udelay(SOFT_RESET_STALL_TIME);
-       }
-
-       /* disable Rx/Tx */
-       wl1251_reg_write32(wl, ENABLE, 0x0);
-
-       /* disable auto calibration on start*/
-       wl1251_reg_write32(wl, SPARE_A2, 0xffff);
-
-       return 0;
-}
-
-int wl1251_boot_init_seq(struct wl1251 *wl)
-{
-       u32 scr_pad6, init_data, tmp, elp_cmd, ref_freq;
-
-       /*
-        * col #1: INTEGER_DIVIDER
-        * col #2: FRACTIONAL_DIVIDER
-        * col #3: ATTN_BB
-        * col #4: ALPHA_BB
-        * col #5: STOP_TIME_BB
-        * col #6: BB_PLL_LOOP_FILTER
-        */
-       static const u32 LUT[REF_FREQ_NUM][LUT_PARAM_NUM] = {
-
-               {   83, 87381,  0xB, 5, 0xF00,  3}, /* REF_FREQ_19_2*/
-               {   61, 141154, 0xB, 5, 0x1450, 2}, /* REF_FREQ_26_0*/
-               {   41, 174763, 0xC, 6, 0x2D00, 1}, /* REF_FREQ_38_4*/
-               {   40, 0,      0xC, 6, 0x2EE0, 1}, /* REF_FREQ_40_0*/
-               {   47, 162280, 0xC, 6, 0x2760, 1}  /* REF_FREQ_33_6        */
-       };
-
-       /* read NVS params */
-       scr_pad6 = wl1251_reg_read32(wl, SCR_PAD6);
-       wl1251_debug(DEBUG_BOOT, "scr_pad6 0x%x", scr_pad6);
-
-       /* read ELP_CMD */
-       elp_cmd = wl1251_reg_read32(wl, ELP_CMD);
-       wl1251_debug(DEBUG_BOOT, "elp_cmd 0x%x", elp_cmd);
-
-       /* set the BB calibration time to be 300 usec (PLL_CAL_TIME) */
-       ref_freq = scr_pad6 & 0x000000FF;
-       wl1251_debug(DEBUG_BOOT, "ref_freq 0x%x", ref_freq);
-
-       wl1251_reg_write32(wl, PLL_CAL_TIME, 0x9);
-
-       /*
-        * PG 1.2: set the clock buffer time to be 210 usec (CLK_BUF_TIME)
-        */
-       wl1251_reg_write32(wl, CLK_BUF_TIME, 0x6);
-
-       /*
-        * set the clock detect feature to work in the restart wu procedure
-        * (ELP_CFG_MODE[14]) and Select the clock source type
-        * (ELP_CFG_MODE[13:12])
-        */
-       tmp = ((scr_pad6 & 0x0000FF00) << 4) | 0x00004000;
-       wl1251_reg_write32(wl, ELP_CFG_MODE, tmp);
-
-       /* PG 1.2: enable the BB PLL fix. Enable the PLL_LIMP_CLK_EN_CMD */
-       elp_cmd |= 0x00000040;
-       wl1251_reg_write32(wl, ELP_CMD, elp_cmd);
-
-       /* PG 1.2: Set the BB PLL stable time to be 1000usec
-        * (PLL_STABLE_TIME) */
-       wl1251_reg_write32(wl, CFG_PLL_SYNC_CNT, 0x20);
-
-       /* PG 1.2: read clock request time */
-       init_data = wl1251_reg_read32(wl, CLK_REQ_TIME);
-
-       /*
-        * PG 1.2: set the clock request time to be ref_clk_settling_time -
-        * 1ms = 4ms
-        */
-       if (init_data > 0x21)
-               tmp = init_data - 0x21;
-       else
-               tmp = 0;
-       wl1251_reg_write32(wl, CLK_REQ_TIME, tmp);
-
-       /* set BB PLL configurations in RF AFE */
-       wl1251_reg_write32(wl, 0x003058cc, 0x4B5);
-
-       /* set RF_AFE_REG_5 */
-       wl1251_reg_write32(wl, 0x003058d4, 0x50);
-
-       /* set RF_AFE_CTRL_REG_2 */
-       wl1251_reg_write32(wl, 0x00305948, 0x11c001);
-
-       /*
-        * change RF PLL and BB PLL divider for VCO clock and adjust VCO
-        * bais current(RF_AFE_REG_13)
-        */
-       wl1251_reg_write32(wl, 0x003058f4, 0x1e);
-
-       /* set BB PLL configurations */
-       tmp = LUT[ref_freq][LUT_PARAM_INTEGER_DIVIDER] | 0x00017000;
-       wl1251_reg_write32(wl, 0x00305840, tmp);
-
-       /* set fractional divider according to Appendix C-BB PLL
-        * Calculations
-        */
-       tmp = LUT[ref_freq][LUT_PARAM_FRACTIONAL_DIVIDER];
-       wl1251_reg_write32(wl, 0x00305844, tmp);
-
-       /* set the initial data for the sigma delta */
-       wl1251_reg_write32(wl, 0x00305848, 0x3039);
-
-       /*
-        * set the accumulator attenuation value, calibration loop1
-        * (alpha), calibration loop2 (beta), calibration loop3 (gamma) and
-        * the VCO gain
-        */
-       tmp = (LUT[ref_freq][LUT_PARAM_ATTN_BB] << 16) |
-               (LUT[ref_freq][LUT_PARAM_ALPHA_BB] << 12) | 0x1;
-       wl1251_reg_write32(wl, 0x00305854, tmp);
-
-       /*
-        * set the calibration stop time after holdoff time expires and set
-        * settling time HOLD_OFF_TIME_BB
-        */
-       tmp = LUT[ref_freq][LUT_PARAM_STOP_TIME_BB] | 0x000A0000;
-       wl1251_reg_write32(wl, 0x00305858, tmp);
-
-       /*
-        * set BB PLL Loop filter capacitor3- BB_C3[2:0] and set BB PLL
-        * constant leakage current to linearize PFD to 0uA -
-        * BB_ILOOPF[7:3]
-        */
-       tmp = LUT[ref_freq][LUT_PARAM_BB_PLL_LOOP_FILTER] | 0x00000030;
-       wl1251_reg_write32(wl, 0x003058f8, tmp);
-
-       /*
-        * set regulator output voltage for n divider to
-        * 1.35-BB_REFDIV[1:0], set charge pump current- BB_CPGAIN[4:2],
-        * set BB PLL Loop filter capacitor2- BB_C2[7:5], set gain of BB
-        * PLL auto-call to normal mode- BB_CALGAIN_3DB[8]
-        */
-       wl1251_reg_write32(wl, 0x003058f0, 0x29);
-
-       /* enable restart wakeup sequence (ELP_CMD[0]) */
-       wl1251_reg_write32(wl, ELP_CMD, elp_cmd | 0x1);
-
-       /* restart sequence completed */
-       udelay(2000);
-
-       return 0;
-}
-
-static void wl1251_boot_set_ecpu_ctrl(struct wl1251 *wl, u32 flag)
-{
-       u32 cpu_ctrl;
-
-       /* 10.5.0 run the firmware (I) */
-       cpu_ctrl = wl1251_reg_read32(wl, ACX_REG_ECPU_CONTROL);
-
-       /* 10.5.1 run the firmware (II) */
-       cpu_ctrl &= ~flag;
-       wl1251_reg_write32(wl, ACX_REG_ECPU_CONTROL, cpu_ctrl);
-}
-
-int wl1251_boot_run_firmware(struct wl1251 *wl)
-{
-       int loop, ret;
-       u32 chip_id, acx_intr;
-
-       wl1251_boot_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT);
-
-       chip_id = wl1251_reg_read32(wl, CHIP_ID_B);
-
-       wl1251_debug(DEBUG_BOOT, "chip id after firmware boot: 0x%x", chip_id);
-
-       if (chip_id != wl->chip_id) {
-               wl1251_error("chip id doesn't match after firmware boot");
-               return -EIO;
-       }
-
-       /* wait for init to complete */
-       loop = 0;
-       while (loop++ < INIT_LOOP) {
-               udelay(INIT_LOOP_DELAY);
-               acx_intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
-
-               if (acx_intr == 0xffffffff) {
-                       wl1251_error("error reading hardware complete "
-                                    "init indication");
-                       return -EIO;
-               }
-               /* check that ACX_INTR_INIT_COMPLETE is enabled */
-               else if (acx_intr & WL1251_ACX_INTR_INIT_COMPLETE) {
-                       wl1251_reg_write32(wl, ACX_REG_INTERRUPT_ACK,
-                                          WL1251_ACX_INTR_INIT_COMPLETE);
-                       break;
-               }
-       }
-
-       if (loop > INIT_LOOP) {
-               wl1251_error("timeout waiting for the hardware to "
-                            "complete initialization");
-               return -EIO;
-       }
-
-       /* get hardware config command mail box */
-       wl->cmd_box_addr = wl1251_reg_read32(wl, REG_COMMAND_MAILBOX_PTR);
-
-       /* get hardware config event mail box */
-       wl->event_box_addr = wl1251_reg_read32(wl, REG_EVENT_MAILBOX_PTR);
-
-       /* set the working partition to its "running" mode offset */
-       wl1251_set_partition(wl, WL1251_PART_WORK_MEM_START,
-                            WL1251_PART_WORK_MEM_SIZE,
-                            WL1251_PART_WORK_REG_START,
-                            WL1251_PART_WORK_REG_SIZE);
-
-       wl1251_debug(DEBUG_MAILBOX, "cmd_box_addr 0x%x event_box_addr 0x%x",
-                    wl->cmd_box_addr, wl->event_box_addr);
-
-       wl1251_acx_fw_version(wl, wl->fw_ver, sizeof(wl->fw_ver));
-
-       /*
-        * in case of full asynchronous mode the firmware event must be
-        * ready to receive event from the command mailbox
-        */
-
-       /* enable gpio interrupts */
-       wl1251_enable_interrupts(wl);
-
-       /* Enable target's interrupts */
-       wl->intr_mask = WL1251_ACX_INTR_RX0_DATA |
-               WL1251_ACX_INTR_RX1_DATA |
-               WL1251_ACX_INTR_TX_RESULT |
-               WL1251_ACX_INTR_EVENT_A |
-               WL1251_ACX_INTR_EVENT_B |
-               WL1251_ACX_INTR_INIT_COMPLETE;
-       wl1251_boot_target_enable_interrupts(wl);
-
-       wl->event_mask = SCAN_COMPLETE_EVENT_ID | BSS_LOSE_EVENT_ID |
-               SYNCHRONIZATION_TIMEOUT_EVENT_ID |
-               ROAMING_TRIGGER_LOW_RSSI_EVENT_ID |
-               ROAMING_TRIGGER_REGAINED_RSSI_EVENT_ID |
-               REGAINED_BSS_EVENT_ID | BT_PTA_SENSE_EVENT_ID |
-               BT_PTA_PREDICTION_EVENT_ID | JOIN_EVENT_COMPLETE_ID;
-
-       ret = wl1251_event_unmask(wl);
-       if (ret < 0) {
-               wl1251_error("EVENT mask setting failed");
-               return ret;
-       }
-
-       wl1251_event_mbox_config(wl);
-
-       /* firmware startup completed */
-       return 0;
-}
-
-static int wl1251_boot_upload_firmware(struct wl1251 *wl)
-{
-       int addr, chunk_num, partition_limit;
-       size_t fw_data_len, len;
-       u8 *p, *buf;
-
-       /* whal_FwCtrl_LoadFwImageSm() */
-
-       wl1251_debug(DEBUG_BOOT, "chip id before fw upload: 0x%x",
-                    wl1251_reg_read32(wl, CHIP_ID_B));
-
-       /* 10.0 check firmware length and set partition */
-       fw_data_len =  (wl->fw[4] << 24) | (wl->fw[5] << 16) |
-               (wl->fw[6] << 8) | (wl->fw[7]);
-
-       wl1251_debug(DEBUG_BOOT, "fw_data_len %zu chunk_size %d", fw_data_len,
-               CHUNK_SIZE);
-
-       if ((fw_data_len % 4) != 0) {
-               wl1251_error("firmware length not multiple of four");
-               return -EIO;
-       }
-
-       buf = kmalloc(CHUNK_SIZE, GFP_KERNEL);
-       if (!buf) {
-               wl1251_error("allocation for firmware upload chunk failed");
-               return -ENOMEM;
-       }
-
-       wl1251_set_partition(wl, WL1251_PART_DOWN_MEM_START,
-                            WL1251_PART_DOWN_MEM_SIZE,
-                            WL1251_PART_DOWN_REG_START,
-                            WL1251_PART_DOWN_REG_SIZE);
-
-       /* 10.1 set partition limit and chunk num */
-       chunk_num = 0;
-       partition_limit = WL1251_PART_DOWN_MEM_SIZE;
-
-       while (chunk_num < fw_data_len / CHUNK_SIZE) {
-               /* 10.2 update partition, if needed */
-               addr = WL1251_PART_DOWN_MEM_START +
-                       (chunk_num + 2) * CHUNK_SIZE;
-               if (addr > partition_limit) {
-                       addr = WL1251_PART_DOWN_MEM_START +
-                               chunk_num * CHUNK_SIZE;
-                       partition_limit = chunk_num * CHUNK_SIZE +
-                               WL1251_PART_DOWN_MEM_SIZE;
-                       wl1251_set_partition(wl,
-                                            addr,
-                                            WL1251_PART_DOWN_MEM_SIZE,
-                                            WL1251_PART_DOWN_REG_START,
-                                            WL1251_PART_DOWN_REG_SIZE);
-               }
-
-               /* 10.3 upload the chunk */
-               addr = WL1251_PART_DOWN_MEM_START + chunk_num * CHUNK_SIZE;
-               p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE;
-               wl1251_debug(DEBUG_BOOT, "uploading fw chunk 0x%p to 0x%x",
-                            p, addr);
-
-               /* need to copy the chunk for dma */
-               len = CHUNK_SIZE;
-               memcpy(buf, p, len);
-               wl1251_mem_write(wl, addr, buf, len);
-
-               chunk_num++;
-       }
-
-       /* 10.4 upload the last chunk */
-       addr = WL1251_PART_DOWN_MEM_START + chunk_num * CHUNK_SIZE;
-       p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE;
-
-       /* need to copy the chunk for dma */
-       len = fw_data_len % CHUNK_SIZE;
-       memcpy(buf, p, len);
-
-       wl1251_debug(DEBUG_BOOT, "uploading fw last chunk (%zu B) 0x%p to 0x%x",
-                    len, p, addr);
-       wl1251_mem_write(wl, addr, buf, len);
-
-       kfree(buf);
-
-       return 0;
-}
-
-static int wl1251_boot_upload_nvs(struct wl1251 *wl)
-{
-       size_t nvs_len, nvs_bytes_written, burst_len;
-       int nvs_start, i;
-       u32 dest_addr, val;
-       u8 *nvs_ptr, *nvs;
-
-       nvs = wl->nvs;
-       if (nvs == NULL)
-               return -ENODEV;
-
-       nvs_ptr = nvs;
-
-       nvs_len = wl->nvs_len;
-       nvs_start = wl->fw_len;
-
-       /*
-        * Layout before the actual NVS tables:
-        * 1 byte : burst length.
-        * 2 bytes: destination address.
-        * n bytes: data to burst copy.
-        *
-        * This is ended by a 0 length, then the NVS tables.
-        */
-
-       while (nvs_ptr[0]) {
-               burst_len = nvs_ptr[0];
-               dest_addr = (nvs_ptr[1] & 0xfe) | ((u32)(nvs_ptr[2] << 8));
-
-               /* We move our pointer to the data */
-               nvs_ptr += 3;
-
-               for (i = 0; i < burst_len; i++) {
-                       val = (nvs_ptr[0] | (nvs_ptr[1] << 8)
-                              | (nvs_ptr[2] << 16) | (nvs_ptr[3] << 24));
-
-                       wl1251_debug(DEBUG_BOOT,
-                                    "nvs burst write 0x%x: 0x%x",
-                                    dest_addr, val);
-                       wl1251_mem_write32(wl, dest_addr, val);
-
-                       nvs_ptr += 4;
-                       dest_addr += 4;
-               }
-       }
-
-       /*
-        * We've reached the first zero length, the first NVS table
-        * is 7 bytes further.
-        */
-       nvs_ptr += 7;
-       nvs_len -= nvs_ptr - nvs;
-       nvs_len = ALIGN(nvs_len, 4);
-
-       /* Now we must set the partition correctly */
-       wl1251_set_partition(wl, nvs_start,
-                            WL1251_PART_DOWN_MEM_SIZE,
-                            WL1251_PART_DOWN_REG_START,
-                            WL1251_PART_DOWN_REG_SIZE);
-
-       /* And finally we upload the NVS tables */
-       nvs_bytes_written = 0;
-       while (nvs_bytes_written < nvs_len) {
-               val = (nvs_ptr[0] | (nvs_ptr[1] << 8)
-                      | (nvs_ptr[2] << 16) | (nvs_ptr[3] << 24));
-
-               val = cpu_to_le32(val);
-
-               wl1251_debug(DEBUG_BOOT,
-                            "nvs write table 0x%x: 0x%x",
-                            nvs_start, val);
-               wl1251_mem_write32(wl, nvs_start, val);
-
-               nvs_ptr += 4;
-               nvs_bytes_written += 4;
-               nvs_start += 4;
-       }
-
-       return 0;
-}
-
-int wl1251_boot(struct wl1251 *wl)
-{
-       int ret = 0, minor_minor_e2_ver;
-       u32 tmp, boot_data;
-
-       /* halt embedded ARM CPU while loading firmware */
-       wl1251_reg_write32(wl, ACX_REG_ECPU_CONTROL, ECPU_CONTROL_HALT);
-
-       ret = wl1251_boot_soft_reset(wl);
-       if (ret < 0)
-               goto out;
-
-       /* 2. start processing NVS file */
-       if (wl->use_eeprom) {
-               wl1251_reg_write32(wl, ACX_REG_EE_START, START_EEPROM_MGR);
-               /* Wait for EEPROM NVS burst read to complete */
-               msleep(40);
-               wl1251_reg_write32(wl, ACX_EEPROMLESS_IND_REG, USE_EEPROM);
-       } else {
-               ret = wl1251_boot_upload_nvs(wl);
-               if (ret < 0)
-                       goto out;
-
-               /* write firmware's last address (ie. it's length) to
-                * ACX_EEPROMLESS_IND_REG */
-               wl1251_reg_write32(wl, ACX_EEPROMLESS_IND_REG, wl->fw_len);
-       }
-
-       /* 6. read the EEPROM parameters */
-       tmp = wl1251_reg_read32(wl, SCR_PAD2);
-
-       /* 7. read bootdata */
-       wl->boot_attr.radio_type = (tmp & 0x0000FF00) >> 8;
-       wl->boot_attr.major = (tmp & 0x00FF0000) >> 16;
-       tmp = wl1251_reg_read32(wl, SCR_PAD3);
-
-       /* 8. check bootdata and call restart sequence */
-       wl->boot_attr.minor = (tmp & 0x00FF0000) >> 16;
-       minor_minor_e2_ver = (tmp & 0xFF000000) >> 24;
-
-       wl1251_debug(DEBUG_BOOT, "radioType 0x%x majorE2Ver 0x%x "
-                    "minorE2Ver 0x%x minor_minor_e2_ver 0x%x",
-                    wl->boot_attr.radio_type, wl->boot_attr.major,
-                    wl->boot_attr.minor, minor_minor_e2_ver);
-
-       ret = wl1251_boot_init_seq(wl);
-       if (ret < 0)
-               goto out;
-
-       /* 9. NVS processing done */
-       boot_data = wl1251_reg_read32(wl, ACX_REG_ECPU_CONTROL);
-
-       wl1251_debug(DEBUG_BOOT, "halt boot_data 0x%x", boot_data);
-
-       /* 10. check that ECPU_CONTROL_HALT bits are set in
-        * pWhalBus->uBootData and start uploading firmware
-        */
-       if ((boot_data & ECPU_CONTROL_HALT) == 0) {
-               wl1251_error("boot failed, ECPU_CONTROL_HALT not set");
-               ret = -EIO;
-               goto out;
-       }
-
-       ret = wl1251_boot_upload_firmware(wl);
-       if (ret < 0)
-               goto out;
-
-       /* 10.5 start firmware */
-       ret = wl1251_boot_run_firmware(wl);
-       if (ret < 0)
-               goto out;
-
-out:
-       return ret;
-}
diff --git a/drivers/net/wireless/wl12xx/wl1251_boot.h b/drivers/net/wireless/wl12xx/wl1251_boot.h
deleted file mode 100644 (file)
index 7661bc5..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * This file is part of wl1251
- *
- * Copyright (C) 2008 Nokia Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __BOOT_H__
-#define __BOOT_H__
-
-#include "wl1251.h"
-
-int wl1251_boot_soft_reset(struct wl1251 *wl);
-int wl1251_boot_init_seq(struct wl1251 *wl);
-int wl1251_boot_run_firmware(struct wl1251 *wl);
-void wl1251_boot_target_enable_interrupts(struct wl1251 *wl);
-int wl1251_boot(struct wl1251 *wl);
-
-/* number of times we try to read the INIT interrupt */
-#define INIT_LOOP 20000
-
-/* delay between retries */
-#define INIT_LOOP_DELAY 50
-
-#endif
diff --git a/drivers/net/wireless/wl12xx/wl1251_cmd.c b/drivers/net/wireless/wl12xx/wl1251_cmd.c
deleted file mode 100644 (file)
index 15fb68c..0000000
+++ /dev/null
@@ -1,496 +0,0 @@
-#include "wl1251_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"
-
-/**
- * send command to firmware
- *
- * @wl: wl struct
- * @id: command id
- * @buf: buffer containing the command, must work with dma
- * @len: length of the buffer
- */
-int wl1251_cmd_send(struct wl1251 *wl, u16 id, void *buf, size_t len)
-{
-       struct wl1251_cmd_header *cmd;
-       unsigned long timeout;
-       u32 intr;
-       int ret = 0;
-
-       cmd = buf;
-       cmd->id = id;
-       cmd->status = 0;
-
-       WARN_ON(len % 4 != 0);
-
-       wl1251_mem_write(wl, wl->cmd_box_addr, buf, len);
-
-       wl1251_reg_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_CMD);
-
-       timeout = jiffies + msecs_to_jiffies(WL1251_COMMAND_TIMEOUT);
-
-       intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
-       while (!(intr & WL1251_ACX_INTR_CMD_COMPLETE)) {
-               if (time_after(jiffies, timeout)) {
-                       wl1251_error("command complete timeout");
-                       ret = -ETIMEDOUT;
-                       goto out;
-               }
-
-               msleep(1);
-
-               intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
-       }
-
-       wl1251_reg_write32(wl, ACX_REG_INTERRUPT_ACK,
-                          WL1251_ACX_INTR_CMD_COMPLETE);
-
-out:
-       return ret;
-}
-
-/**
- * send test command to firmware
- *
- * @wl: wl struct
- * @buf: buffer containing the command, with all headers, must work with dma
- * @len: length of the buffer
- * @answer: is answer needed
- */
-int wl1251_cmd_test(struct wl1251 *wl, void *buf, size_t buf_len, u8 answer)
-{
-       int ret;
-
-       wl1251_debug(DEBUG_CMD, "cmd test");
-
-       ret = wl1251_cmd_send(wl, CMD_TEST, buf, buf_len);
-
-       if (ret < 0) {
-               wl1251_warning("TEST command failed");
-               return ret;
-       }
-
-       if (answer) {
-               struct wl1251_command *cmd_answer;
-
-               /*
-                * The test command got in, we can read the answer.
-                * The answer would be a wl1251_command, where the
-                * parameter array contains the actual answer.
-                */
-               wl1251_mem_read(wl, wl->cmd_box_addr, buf, buf_len);
-
-               cmd_answer = buf;
-
-               if (cmd_answer->header.status != CMD_STATUS_SUCCESS)
-                       wl1251_error("TEST command answer error: %d",
-                                    cmd_answer->header.status);
-       }
-
-       return 0;
-}
-
-/**
- * read acx from firmware
- *
- * @wl: wl struct
- * @id: acx id
- * @buf: buffer for the response, including all headers, must work with dma
- * @len: lenght of buf
- */
-int wl1251_cmd_interrogate(struct wl1251 *wl, u16 id, void *buf, size_t len)
-{
-       struct acx_header *acx = buf;
-       int ret;
-
-       wl1251_debug(DEBUG_CMD, "cmd interrogate");
-
-       acx->id = id;
-
-       /* payload length, does not include any headers */
-       acx->len = len - sizeof(*acx);
-
-       ret = wl1251_cmd_send(wl, CMD_INTERROGATE, acx, sizeof(*acx));
-       if (ret < 0) {
-               wl1251_error("INTERROGATE command failed");
-               goto out;
-       }
-
-       /* the interrogate command got in, we can read the answer */
-       wl1251_mem_read(wl, wl->cmd_box_addr, buf, len);
-
-       acx = buf;
-       if (acx->cmd.status != CMD_STATUS_SUCCESS)
-               wl1251_error("INTERROGATE command error: %d",
-                            acx->cmd.status);
-
-out:
-       return ret;
-}
-
-/**
- * write acx value to firmware
- *
- * @wl: wl struct
- * @id: acx id
- * @buf: buffer containing acx, including all headers, must work with dma
- * @len: length of buf
- */
-int wl1251_cmd_configure(struct wl1251 *wl, u16 id, void *buf, size_t len)
-{
-       struct acx_header *acx = buf;
-       int ret;
-
-       wl1251_debug(DEBUG_CMD, "cmd configure");
-
-       acx->id = id;
-
-       /* payload length, does not include any headers */
-       acx->len = len - sizeof(*acx);
-
-       ret = wl1251_cmd_send(wl, CMD_CONFIGURE, acx, len);
-       if (ret < 0) {
-               wl1251_warning("CONFIGURE command NOK");
-               return ret;
-       }
-
-       return 0;
-}
-
-int wl1251_cmd_vbm(struct wl1251 *wl, u8 identity,
-                  void *bitmap, u16 bitmap_len, u8 bitmap_control)
-{
-       struct wl1251_cmd_vbm_update *vbm;
-       int ret;
-
-       wl1251_debug(DEBUG_CMD, "cmd vbm");
-
-       vbm = kzalloc(sizeof(*vbm), GFP_KERNEL);
-       if (!vbm) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       /* Count and period will be filled by the target */
-       vbm->tim.bitmap_ctrl = bitmap_control;
-       if (bitmap_len > PARTIAL_VBM_MAX) {
-               wl1251_warning("cmd vbm len is %d B, truncating to %d",
-                              bitmap_len, PARTIAL_VBM_MAX);
-               bitmap_len = PARTIAL_VBM_MAX;
-       }
-       memcpy(vbm->tim.pvb_field, bitmap, bitmap_len);
-       vbm->tim.identity = identity;
-       vbm->tim.length = bitmap_len + 3;
-
-       vbm->len = cpu_to_le16(bitmap_len + 5);
-
-       ret = wl1251_cmd_send(wl, CMD_VBM, vbm, sizeof(*vbm));
-       if (ret < 0) {
-               wl1251_error("VBM command failed");
-               goto out;
-       }
-
-out:
-       kfree(vbm);
-       return ret;
-}
-
-int wl1251_cmd_data_path(struct wl1251 *wl, u8 channel, bool enable)
-{
-       struct cmd_enabledisable_path *cmd;
-       int ret;
-       u16 cmd_rx, cmd_tx;
-
-       wl1251_debug(DEBUG_CMD, "cmd data path");
-
-       cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
-       if (!cmd) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       cmd->channel = channel;
-
-       if (enable) {
-               cmd_rx = CMD_ENABLE_RX;
-               cmd_tx = CMD_ENABLE_TX;
-       } else {
-               cmd_rx = CMD_DISABLE_RX;
-               cmd_tx = CMD_DISABLE_TX;
-       }
-
-       ret = wl1251_cmd_send(wl, cmd_rx, cmd, sizeof(*cmd));
-       if (ret < 0) {
-               wl1251_error("rx %s cmd for channel %d failed",
-                            enable ? "start" : "stop", channel);
-               goto out;
-       }
-
-       wl1251_debug(DEBUG_BOOT, "rx %s cmd channel %d",
-                    enable ? "start" : "stop", channel);
-
-       ret = wl1251_cmd_send(wl, cmd_tx, cmd, sizeof(*cmd));
-       if (ret < 0) {
-               wl1251_error("tx %s cmd for channel %d failed",
-                            enable ? "start" : "stop", channel);
-               return ret;
-       }
-
-       wl1251_debug(DEBUG_BOOT, "tx %s cmd channel %d",
-                    enable ? "start" : "stop", channel);
-
-out:
-       kfree(cmd);
-       return ret;
-}
-
-int wl1251_cmd_join(struct wl1251 *wl, u8 bss_type, u8 channel,
-                   u16 beacon_interval, u8 dtim_interval)
-{
-       struct cmd_join *join;
-       int ret, i;
-       u8 *bssid;
-
-       join = kzalloc(sizeof(*join), GFP_KERNEL);
-       if (!join) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       wl1251_debug(DEBUG_CMD, "cmd join%s ch %d %d/%d",
-                    bss_type == BSS_TYPE_IBSS ? " ibss" : "",
-                    channel, beacon_interval, dtim_interval);
-
-       /* Reverse order BSSID */
-       bssid = (u8 *) &join->bssid_lsb;
-       for (i = 0; i < ETH_ALEN; i++)
-               bssid[i] = wl->bssid[ETH_ALEN - i - 1];
-
-       join->rx_config_options = wl->rx_config;
-       join->rx_filter_options = wl->rx_filter;
-
-       /*
-        * FIXME: disable temporarily all filters because after commit
-        * 9cef8737 "mac80211: fix managed mode BSSID handling" broke
-        * association. The filter logic needs to be implemented properly
-        * and once that is done, this hack can be removed.
-        */
-       join->rx_config_options = 0;
-       join->rx_filter_options = WL1251_DEFAULT_RX_FILTER;
-
-       join->basic_rate_set = RATE_MASK_1MBPS | RATE_MASK_2MBPS |
-               RATE_MASK_5_5MBPS | RATE_MASK_11MBPS;
-
-       join->beacon_interval = beacon_interval;
-       join->dtim_interval = dtim_interval;
-       join->bss_type = bss_type;
-       join->channel = channel;
-       join->ctrl = JOIN_CMD_CTRL_TX_FLUSH;
-
-       ret = wl1251_cmd_send(wl, CMD_START_JOIN, join, sizeof(*join));
-       if (ret < 0) {
-               wl1251_error("failed to initiate cmd join");
-               goto out;
-       }
-
-out:
-       kfree(join);
-       return ret;
-}
-
-int wl1251_cmd_ps_mode(struct wl1251 *wl, u8 ps_mode)
-{
-       struct wl1251_cmd_ps_params *ps_params = NULL;
-       int ret = 0;
-
-       wl1251_debug(DEBUG_CMD, "cmd set ps mode");
-
-       ps_params = kzalloc(sizeof(*ps_params), GFP_KERNEL);
-       if (!ps_params) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       ps_params->ps_mode = ps_mode;
-       ps_params->send_null_data = 1;
-       ps_params->retries = 5;
-       ps_params->hang_over_period = 128;
-       ps_params->null_data_rate = 1; /* 1 Mbps */
-
-       ret = wl1251_cmd_send(wl, CMD_SET_PS_MODE, ps_params,
-                             sizeof(*ps_params));
-       if (ret < 0) {
-               wl1251_error("cmd set_ps_mode failed");
-               goto out;
-       }
-
-out:
-       kfree(ps_params);
-       return ret;
-}
-
-int wl1251_cmd_read_memory(struct wl1251 *wl, u32 addr, void *answer,
-                          size_t len)
-{
-       struct cmd_read_write_memory *cmd;
-       int ret = 0;
-
-       wl1251_debug(DEBUG_CMD, "cmd read memory");
-
-       cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
-       if (!cmd) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       WARN_ON(len > MAX_READ_SIZE);
-       len = min_t(size_t, len, MAX_READ_SIZE);
-
-       cmd->addr = addr;
-       cmd->size = len;
-
-       ret = wl1251_cmd_send(wl, CMD_READ_MEMORY, cmd, sizeof(*cmd));
-       if (ret < 0) {
-               wl1251_error("read memory command failed: %d", ret);
-               goto out;
-       }
-
-       /* the read command got in, we can now read the answer */
-       wl1251_mem_read(wl, wl->cmd_box_addr, cmd, sizeof(*cmd));
-
-       if (cmd->header.status != CMD_STATUS_SUCCESS)
-               wl1251_error("error in read command result: %d",
-                            cmd->header.status);
-
-       memcpy(answer, cmd->value, len);
-
-out:
-       kfree(cmd);
-       return ret;
-}
-
-int wl1251_cmd_template_set(struct wl1251 *wl, u16 cmd_id,
-                           void *buf, size_t buf_len)
-{
-       struct wl1251_cmd_packet_template *cmd;
-       size_t cmd_len;
-       int ret = 0;
-
-       wl1251_debug(DEBUG_CMD, "cmd template %d", cmd_id);
-
-       WARN_ON(buf_len > WL1251_MAX_TEMPLATE_SIZE);
-       buf_len = min_t(size_t, buf_len, WL1251_MAX_TEMPLATE_SIZE);
-       cmd_len = ALIGN(sizeof(*cmd) + buf_len, 4);
-
-       cmd = kzalloc(cmd_len, GFP_KERNEL);
-       if (!cmd) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       cmd->size = cpu_to_le16(buf_len);
-
-       if (buf)
-               memcpy(cmd->data, buf, buf_len);
-
-       ret = wl1251_cmd_send(wl, cmd_id, cmd, cmd_len);
-       if (ret < 0) {
-               wl1251_warning("cmd set_template failed: %d", ret);
-               goto out;
-       }
-
-out:
-       kfree(cmd);
-       return ret;
-}
-
-int wl1251_cmd_scan(struct wl1251 *wl, u8 *ssid, size_t ssid_len,
-                   struct ieee80211_channel *channels[],
-                   unsigned int n_channels, unsigned int n_probes)
-{
-       struct wl1251_cmd_scan *cmd;
-       int i, ret = 0;
-
-       wl1251_debug(DEBUG_CMD, "cmd scan");
-
-       cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
-       if (!cmd)
-               return -ENOMEM;
-
-       cmd->params.rx_config_options = cpu_to_le32(CFG_RX_ALL_GOOD);
-       cmd->params.rx_filter_options = cpu_to_le32(CFG_RX_PRSP_EN |
-                                                   CFG_RX_MGMT_EN |
-                                                   CFG_RX_BCN_EN);
-       cmd->params.scan_options = 0;
-       cmd->params.num_channels = n_channels;
-       cmd->params.num_probe_requests = n_probes;
-       cmd->params.tx_rate = cpu_to_le16(1 << 1); /* 2 Mbps */
-       cmd->params.tid_trigger = 0;
-
-       for (i = 0; i < n_channels; i++) {
-               cmd->channels[i].min_duration =
-                       cpu_to_le32(WL1251_SCAN_MIN_DURATION);
-               cmd->channels[i].max_duration =
-                       cpu_to_le32(WL1251_SCAN_MAX_DURATION);
-               memset(&cmd->channels[i].bssid_lsb, 0xff, 4);
-               memset(&cmd->channels[i].bssid_msb, 0xff, 2);
-               cmd->channels[i].early_termination = 0;
-               cmd->channels[i].tx_power_att = 0;
-               cmd->channels[i].channel = channels[i]->hw_value;
-       }
-
-       cmd->params.ssid_len = ssid_len;
-       if (ssid)
-               memcpy(cmd->params.ssid, ssid, ssid_len);
-
-       ret = wl1251_cmd_send(wl, CMD_SCAN, cmd, sizeof(*cmd));
-       if (ret < 0) {
-               wl1251_error("cmd scan failed: %d", ret);
-               goto out;
-       }
-
-       wl1251_mem_read(wl, wl->cmd_box_addr, cmd, sizeof(*cmd));
-
-       if (cmd->header.status != CMD_STATUS_SUCCESS) {
-               wl1251_error("cmd scan status wasn't success: %d",
-                            cmd->header.status);
-               ret = -EIO;
-               goto out;
-       }
-
-out:
-       kfree(cmd);
-       return ret;
-}
-
-int wl1251_cmd_trigger_scan_to(struct wl1251 *wl, u32 timeout)
-{
-       struct wl1251_cmd_trigger_scan_to *cmd;
-       int ret;
-
-       wl1251_debug(DEBUG_CMD, "cmd trigger scan to");
-
-       cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
-       if (!cmd)
-               return -ENOMEM;
-
-       cmd->timeout = timeout;
-
-       ret = wl1251_cmd_send(wl, CMD_TRIGGER_SCAN_TO, cmd, sizeof(*cmd));
-       if (ret < 0) {
-               wl1251_error("cmd trigger scan to failed: %d", ret);
-               goto out;
-       }
-
-out:
-       kfree(cmd);
-       return ret;
-}
diff --git a/drivers/net/wireless/wl12xx/wl1251_cmd.h b/drivers/net/wireless/wl12xx/wl1251_cmd.h
deleted file mode 100644 (file)
index e5c74c6..0000000
+++ /dev/null
@@ -1,415 +0,0 @@
-/*
- * This file is part of wl1251
- *
- * Copyright (c) 1998-2007 Texas Instruments Incorporated
- * Copyright (C) 2008 Nokia Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __WL1251_CMD_H__
-#define __WL1251_CMD_H__
-
-#include "wl1251.h"
-
-#include <net/cfg80211.h>
-
-struct acx_header;
-
-int wl1251_cmd_send(struct wl1251 *wl, u16 type, void *buf, size_t buf_len);
-int wl1251_cmd_test(struct wl1251 *wl, void *buf, size_t buf_len, u8 answer);
-int wl1251_cmd_interrogate(struct wl1251 *wl, u16 id, void *buf, size_t len);
-int wl1251_cmd_configure(struct wl1251 *wl, u16 id, void *buf, size_t len);
-int wl1251_cmd_vbm(struct wl1251 *wl, u8 identity,
-                  void *bitmap, u16 bitmap_len, u8 bitmap_control);
-int wl1251_cmd_data_path(struct wl1251 *wl, u8 channel, bool enable);
-int wl1251_cmd_join(struct wl1251 *wl, u8 bss_type, u8 channel,
-                   u16 beacon_interval, u8 dtim_interval);
-int wl1251_cmd_ps_mode(struct wl1251 *wl, u8 ps_mode);
-int wl1251_cmd_read_memory(struct wl1251 *wl, u32 addr, void *answer,
-                          size_t len);
-int wl1251_cmd_template_set(struct wl1251 *wl, u16 cmd_id,
-                           void *buf, size_t buf_len);
-int wl1251_cmd_scan(struct wl1251 *wl, u8 *ssid, size_t ssid_len,
-                   struct ieee80211_channel *channels[],
-                   unsigned int n_channels, unsigned int n_probes);
-int wl1251_cmd_trigger_scan_to(struct wl1251 *wl, u32 timeout);
-
-/* unit ms */
-#define WL1251_COMMAND_TIMEOUT 2000
-
-enum wl1251_commands {
-       CMD_RESET           = 0,
-       CMD_INTERROGATE     = 1,    /*use this to read information elements*/
-       CMD_CONFIGURE       = 2,    /*use this to write information elements*/
-       CMD_ENABLE_RX       = 3,
-       CMD_ENABLE_TX       = 4,
-       CMD_DISABLE_RX      = 5,
-       CMD_DISABLE_TX      = 6,
-       CMD_SCAN            = 8,
-       CMD_STOP_SCAN       = 9,
-       CMD_VBM             = 10,
-       CMD_START_JOIN      = 11,
-       CMD_SET_KEYS        = 12,
-       CMD_READ_MEMORY     = 13,
-       CMD_WRITE_MEMORY    = 14,
-       CMD_BEACON          = 19,
-       CMD_PROBE_RESP      = 20,
-       CMD_NULL_DATA       = 21,
-       CMD_PROBE_REQ       = 22,
-       CMD_TEST            = 23,
-       CMD_RADIO_CALIBRATE     = 25,   /* OBSOLETE */
-       CMD_ENABLE_RX_PATH      = 27,   /* OBSOLETE */
-       CMD_NOISE_HIST      = 28,
-       CMD_RX_RESET        = 29,
-       CMD_PS_POLL         = 30,
-       CMD_QOS_NULL_DATA   = 31,
-       CMD_LNA_CONTROL     = 32,
-       CMD_SET_BCN_MODE    = 33,
-       CMD_MEASUREMENT      = 34,
-       CMD_STOP_MEASUREMENT = 35,
-       CMD_DISCONNECT       = 36,
-       CMD_SET_PS_MODE      = 37,
-       CMD_CHANNEL_SWITCH   = 38,
-       CMD_STOP_CHANNEL_SWICTH = 39,
-       CMD_AP_DISCOVERY     = 40,
-       CMD_STOP_AP_DISCOVERY = 41,
-       CMD_SPS_SCAN = 42,
-       CMD_STOP_SPS_SCAN = 43,
-       CMD_HEALTH_CHECK     = 45,
-       CMD_DEBUG            = 46,
-       CMD_TRIGGER_SCAN_TO  = 47,
-
-       NUM_COMMANDS,
-       MAX_COMMAND_ID = 0xFFFF,
-};
-
-#define MAX_CMD_PARAMS 572
-
-struct wl1251_cmd_header {
-       u16 id;
-       u16 status;
-       /* payload */
-       u8 data[0];
-} __packed;
-
-struct  wl1251_command {
-       struct wl1251_cmd_header header;
-       u8  parameters[MAX_CMD_PARAMS];
-} __packed;
-
-enum {
-       CMD_MAILBOX_IDLE                        =  0,
-       CMD_STATUS_SUCCESS                      =  1,
-       CMD_STATUS_UNKNOWN_CMD                  =  2,
-       CMD_STATUS_UNKNOWN_IE                   =  3,
-       CMD_STATUS_REJECT_MEAS_SG_ACTIVE        = 11,
-       CMD_STATUS_RX_BUSY                      = 13,
-       CMD_STATUS_INVALID_PARAM                = 14,
-       CMD_STATUS_TEMPLATE_TOO_LARGE           = 15,
-       CMD_STATUS_OUT_OF_MEMORY                = 16,
-       CMD_STATUS_STA_TABLE_FULL               = 17,
-       CMD_STATUS_RADIO_ERROR                  = 18,
-       CMD_STATUS_WRONG_NESTING                = 19,
-       CMD_STATUS_TIMEOUT                      = 21, /* Driver internal use.*/
-       CMD_STATUS_FW_RESET                     = 22, /* Driver internal use.*/
-       MAX_COMMAND_STATUS                      = 0xff
-};
-
-
-/*
- * CMD_READ_MEMORY
- *
- * The host issues this command to read the WiLink device memory/registers.
- *
- * Note: The Base Band address has special handling (16 bits registers and
- * addresses). For more information, see the hardware specification.
- */
-/*
- * CMD_WRITE_MEMORY
- *
- * The host issues this command to write the WiLink device memory/registers.
- *
- * The Base Band address has special handling (16 bits registers and
- * addresses). For more information, see the hardware specification.
- */
-#define MAX_READ_SIZE 256
-
-struct cmd_read_write_memory {
-       struct wl1251_cmd_header header;
-
-       /* The address of the memory to read from or write to.*/
-       u32 addr;
-
-       /* The amount of data in bytes to read from or write to the WiLink
-        * device.*/
-       u32 size;
-
-       /* The actual value read from or written to the Wilink. The source
-          of this field is the Host in WRITE command or the Wilink in READ
-          command. */
-       u8 value[MAX_READ_SIZE];
-} __packed;
-
-#define CMDMBOX_HEADER_LEN 4
-#define CMDMBOX_INFO_ELEM_HEADER_LEN 4
-
-#define WL1251_SCAN_MIN_DURATION 30000
-#define WL1251_SCAN_MAX_DURATION 60000
-
-#define WL1251_SCAN_NUM_PROBES 3
-
-struct wl1251_scan_parameters {
-       __le32 rx_config_options;
-       __le32 rx_filter_options;
-
-       /*
-        * Scan options:
-        * bit 0: When this bit is set, passive scan.
-        * bit 1: Band, when this bit is set we scan
-        * in the 5Ghz band.
-        * bit 2: voice mode, 0 for normal scan.
-        * bit 3: scan priority, 1 for high priority.
-        */
-       __le16 scan_options;
-
-       /* Number of channels to scan */
-       u8 num_channels;
-
-       /* Number opf probe requests to send, per channel */
-       u8 num_probe_requests;
-
-       /* Rate and modulation for probe requests */
-       __le16 tx_rate;
-
-       u8 tid_trigger;
-       u8 ssid_len;
-       u8 ssid[32];
-
-} __packed;
-
-struct wl1251_scan_ch_parameters {
-       __le32 min_duration; /* in TU */
-       __le32 max_duration; /* in TU */
-       u32 bssid_lsb;
-       u16 bssid_msb;
-
-       /*
-        * bits 0-3: Early termination count.
-        * bits 4-5: Early termination condition.
-        */
-       u8 early_termination;
-
-       u8 tx_power_att;
-       u8 channel;
-       u8 pad[3];
-} __packed;
-
-/* SCAN parameters */
-#define SCAN_MAX_NUM_OF_CHANNELS 16
-
-struct wl1251_cmd_scan {
-       struct wl1251_cmd_header header;
-
-       struct wl1251_scan_parameters params;
-       struct wl1251_scan_ch_parameters channels[SCAN_MAX_NUM_OF_CHANNELS];
-} __packed;
-
-enum {
-       BSS_TYPE_IBSS = 0,
-       BSS_TYPE_STA_BSS = 2,
-       BSS_TYPE_AP_BSS = 3,
-       MAX_BSS_TYPE = 0xFF
-};
-
-#define JOIN_CMD_CTRL_TX_FLUSH             0x80 /* Firmware flushes all Tx */
-#define JOIN_CMD_CTRL_EARLY_WAKEUP_ENABLE  0x01 /* Early wakeup time */
-
-
-struct cmd_join {
-       struct wl1251_cmd_header header;
-
-       u32 bssid_lsb;
-       u16 bssid_msb;
-       u16 beacon_interval; /* in TBTTs */
-       u32 rx_config_options;
-       u32 rx_filter_options;
-
-       /*
-        * The target uses this field to determine the rate at
-        * which to transmit control frame responses (such as
-        * ACK or CTS frames).
-        */
-       u16 basic_rate_set;
-       u8 dtim_interval;
-       u8 tx_ctrl_frame_rate; /* OBSOLETE */
-       u8 tx_ctrl_frame_mod;  /* OBSOLETE */
-       /*
-        * bits 0-2: This bitwise field specifies the type
-        * of BSS to start or join (BSS_TYPE_*).
-        * bit 4: Band - The radio band in which to join
-        * or start.
-        *  0 - 2.4GHz band
-        *  1 - 5GHz band
-        * bits 3, 5-7: Reserved
-        */
-       u8 bss_type;
-       u8 channel;
-       u8 ssid_len;
-       u8 ssid[IW_ESSID_MAX_SIZE];
-       u8 ctrl; /* JOIN_CMD_CTRL_* */
-       u8 tx_mgt_frame_rate; /* OBSOLETE */
-       u8 tx_mgt_frame_mod;  /* OBSOLETE */
-       u8 reserved;
-} __packed;
-
-struct cmd_enabledisable_path {
-       struct wl1251_cmd_header header;
-
-       u8 channel;
-       u8 padding[3];
-} __packed;
-
-#define WL1251_MAX_TEMPLATE_SIZE 300
-
-struct wl1251_cmd_packet_template {
-       struct wl1251_cmd_header header;
-
-       __le16 size;
-       u8 data[0];
-} __packed;
-
-#define TIM_ELE_ID    5
-#define PARTIAL_VBM_MAX    251
-
-struct wl1251_tim {
-       u8 identity;
-       u8 length;
-       u8 dtim_count;
-       u8 dtim_period;
-       u8 bitmap_ctrl;
-       u8 pvb_field[PARTIAL_VBM_MAX]; /* Partial Virtual Bitmap */
-} __packed;
-
-/* Virtual Bit Map update */
-struct wl1251_cmd_vbm_update {
-       struct wl1251_cmd_header header;
-       __le16 len;
-       u8  padding[2];
-       struct wl1251_tim tim;
-} __packed;
-
-enum wl1251_cmd_ps_mode {
-       STATION_ACTIVE_MODE,
-       STATION_POWER_SAVE_MODE
-};
-
-struct wl1251_cmd_ps_params {
-       struct wl1251_cmd_header header;
-
-       u8 ps_mode; /* STATION_* */
-       u8 send_null_data; /* Do we have to send NULL data packet ? */
-       u8 retries; /* Number of retires for the initial NULL data packet */
-
-        /*
-         * TUs during which the target stays awake after switching
-         * to power save mode.
-         */
-       u8 hang_over_period;
-       u16 null_data_rate;
-       u8 pad[2];
-} __packed;
-
-struct wl1251_cmd_trigger_scan_to {
-       struct wl1251_cmd_header header;
-
-       u32 timeout;
-} __packed;
-
-/* HW encryption keys */
-#define NUM_ACCESS_CATEGORIES_COPY 4
-#define MAX_KEY_SIZE 32
-
-/* When set, disable HW encryption */
-#define DF_ENCRYPTION_DISABLE      0x01
-/* When set, disable HW decryption */
-#define DF_SNIFF_MODE_ENABLE       0x80
-
-enum wl1251_cmd_key_action {
-       KEY_ADD_OR_REPLACE = 1,
-       KEY_REMOVE         = 2,
-       KEY_SET_ID         = 3,
-       MAX_KEY_ACTION     = 0xffff,
-};
-
-enum wl1251_cmd_key_type {
-       KEY_WEP_DEFAULT       = 0,
-       KEY_WEP_ADDR          = 1,
-       KEY_AES_GROUP         = 4,
-       KEY_AES_PAIRWISE      = 5,
-       KEY_WEP_GROUP         = 6,
-       KEY_TKIP_MIC_GROUP    = 10,
-       KEY_TKIP_MIC_PAIRWISE = 11,
-};
-
-/*
- *
- * key_type_e   key size    key format
- * ----------   ---------   ----------
- * 0x00         5, 13, 29   Key data
- * 0x01         5, 13, 29   Key data
- * 0x04         16          16 bytes of key data
- * 0x05         16          16 bytes of key data
- * 0x0a         32          16 bytes of TKIP key data
- *                          8 bytes of RX MIC key data
- *                          8 bytes of TX MIC key data
- * 0x0b         32          16 bytes of TKIP key data
- *                          8 bytes of RX MIC key data
- *                          8 bytes of TX MIC key data
- *
- */
-
-struct wl1251_cmd_set_keys {
-       struct wl1251_cmd_header header;
-
-       /* Ignored for default WEP key */
-       u8 addr[ETH_ALEN];
-
-       /* key_action_e */
-       u16 key_action;
-
-       u16 reserved_1;
-
-       /* key size in bytes */
-       u8 key_size;
-
-       /* key_type_e */
-       u8 key_type;
-       u8 ssid_profile;
-
-       /*
-        * TKIP, AES: frame's key id field.
-        * For WEP default key: key id;
-        */
-       u8 id;
-       u8 reserved_2[6];
-       u8 key[MAX_KEY_SIZE];
-       u16 ac_seq_num16[NUM_ACCESS_CATEGORIES_COPY];
-       u32 ac_seq_num32[NUM_ACCESS_CATEGORIES_COPY];
-} __packed;
-
-
-#endif /* __WL1251_CMD_H__ */
diff --git a/drivers/net/wireless/wl12xx/wl1251_debugfs.c b/drivers/net/wireless/wl12xx/wl1251_debugfs.c
deleted file mode 100644 (file)
index 6ffe4cd..0000000
+++ /dev/null
@@ -1,541 +0,0 @@
-/*
- * This file is part of wl1251
- *
- * Copyright (C) 2009 Nokia Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include "wl1251_debugfs.h"
-
-#include <linux/skbuff.h>
-#include <linux/slab.h>
-
-#include "wl1251.h"
-#include "wl1251_acx.h"
-#include "wl1251_ps.h"
-
-/* ms */
-#define WL1251_DEBUGFS_STATS_LIFETIME 1000
-
-/* debugfs macros idea from mac80211 */
-
-#define DEBUGFS_READONLY_FILE(name, buflen, fmt, value...)             \
-static ssize_t name## _read(struct file *file, char __user *userbuf,   \
-                           size_t count, loff_t *ppos)                 \
-{                                                                      \
-       struct wl1251 *wl = file->private_data;                         \
-       char buf[buflen];                                               \
-       int res;                                                        \
-                                                                       \
-       res = scnprintf(buf, buflen, fmt "\n", ##value);                \
-       return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
-}                                                                      \
-                                                                       \
-static const struct file_operations name## _ops = {                    \
-       .read = name## _read,                                           \
-       .open = wl1251_open_file_generic,                               \
-};
-
-#define DEBUGFS_ADD(name, parent)                                      \
-       wl->debugfs.name = debugfs_create_file(#name, 0400, parent,     \
-                                              wl, &name## _ops);       \
-       if (IS_ERR(wl->debugfs.name)) {                                 \
-               ret = PTR_ERR(wl->debugfs.name);                        \
-               wl->debugfs.name = NULL;                                \
-               goto out;                                               \
-       }
-
-#define DEBUGFS_DEL(name)                                              \
-       do {                                                            \
-               debugfs_remove(wl->debugfs.name);                       \
-               wl->debugfs.name = NULL;                                \
-       } while (0)
-
-#define DEBUGFS_FWSTATS_FILE(sub, name, buflen, fmt)                   \
-static ssize_t sub## _ ##name## _read(struct file *file,               \
-                                     char __user *userbuf,             \
-                                     size_t count, loff_t *ppos)       \
-{                                                                      \
-       struct wl1251 *wl = file->private_data;                         \
-       char buf[buflen];                                               \
-       int res;                                                        \
-                                                                       \
-       wl1251_debugfs_update_stats(wl);                                \
-                                                                       \
-       res = scnprintf(buf, buflen, fmt "\n",                          \
-                       wl->stats.fw_stats->sub.name);                  \
-       return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
-}                                                                      \
-                                                                       \
-static const struct file_operations sub## _ ##name## _ops = {          \
-       .read = sub## _ ##name## _read,                                 \
-       .open = wl1251_open_file_generic,                               \
-};
-
-#define DEBUGFS_FWSTATS_ADD(sub, name)                         \
-       DEBUGFS_ADD(sub## _ ##name, wl->debugfs.fw_statistics)
-
-#define DEBUGFS_FWSTATS_DEL(sub, name)                         \
-       DEBUGFS_DEL(sub## _ ##name)
-
-static void wl1251_debugfs_update_stats(struct wl1251 *wl)
-{
-       int ret;
-
-       mutex_lock(&wl->mutex);
-
-       ret = wl1251_ps_elp_wakeup(wl);
-       if (ret < 0)
-               goto out;
-
-       if (wl->state == WL1251_STATE_ON &&
-           time_after(jiffies, wl->stats.fw_stats_update +
-                      msecs_to_jiffies(WL1251_DEBUGFS_STATS_LIFETIME))) {
-               wl1251_acx_statistics(wl, wl->stats.fw_stats);
-               wl->stats.fw_stats_update = jiffies;
-       }
-
-       wl1251_ps_elp_sleep(wl);
-
-out:
-       mutex_unlock(&wl->mutex);
-}
-
-static int wl1251_open_file_generic(struct inode *inode, struct file *file)
-{
-       file->private_data = inode->i_private;
-       return 0;
-}
-
-DEBUGFS_FWSTATS_FILE(tx, internal_desc_overflow, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(rx, out_of_mem, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rx, hdr_overflow, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rx, hw_stuck, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rx, dropped, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rx, fcs_err, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rx, xfr_hint_trig, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rx, path_reset, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rx, reset_counter, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(dma, rx_requested, 20, "%u");
-DEBUGFS_FWSTATS_FILE(dma, rx_errors, 20, "%u");
-DEBUGFS_FWSTATS_FILE(dma, tx_requested, 20, "%u");
-DEBUGFS_FWSTATS_FILE(dma, tx_errors, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(isr, cmd_cmplt, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, fiqs, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, rx_headers, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, rx_mem_overflow, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, rx_rdys, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, irqs, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, tx_procs, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, decrypt_done, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, dma0_done, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, dma1_done, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, tx_exch_complete, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, commands, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, rx_procs, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, hw_pm_mode_changes, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, host_acknowledges, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, pci_pm, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, wakeups, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, low_rssi, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(wep, addr_key_count, 20, "%u");
-DEBUGFS_FWSTATS_FILE(wep, default_key_count, 20, "%u");
-/* skipping wep.reserved */
-DEBUGFS_FWSTATS_FILE(wep, key_not_found, 20, "%u");
-DEBUGFS_FWSTATS_FILE(wep, decrypt_fail, 20, "%u");
-DEBUGFS_FWSTATS_FILE(wep, packets, 20, "%u");
-DEBUGFS_FWSTATS_FILE(wep, interrupt, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(pwr, ps_enter, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, elp_enter, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, missing_bcns, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, wake_on_host, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, wake_on_timer_exp, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, tx_with_ps, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, tx_without_ps, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, rcvd_beacons, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, power_save_off, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, enable_ps, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, disable_ps, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, fix_tsf_ps, 20, "%u");
-/* skipping cont_miss_bcns_spread for now */
-DEBUGFS_FWSTATS_FILE(pwr, rcvd_awake_beacons, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(mic, rx_pkts, 20, "%u");
-DEBUGFS_FWSTATS_FILE(mic, calc_failure, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(aes, encrypt_fail, 20, "%u");
-DEBUGFS_FWSTATS_FILE(aes, decrypt_fail, 20, "%u");
-DEBUGFS_FWSTATS_FILE(aes, encrypt_packets, 20, "%u");
-DEBUGFS_FWSTATS_FILE(aes, decrypt_packets, 20, "%u");
-DEBUGFS_FWSTATS_FILE(aes, encrypt_interrupt, 20, "%u");
-DEBUGFS_FWSTATS_FILE(aes, decrypt_interrupt, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(event, heart_beat, 20, "%u");
-DEBUGFS_FWSTATS_FILE(event, calibration, 20, "%u");
-DEBUGFS_FWSTATS_FILE(event, rx_mismatch, 20, "%u");
-DEBUGFS_FWSTATS_FILE(event, rx_mem_empty, 20, "%u");
-DEBUGFS_FWSTATS_FILE(event, rx_pool, 20, "%u");
-DEBUGFS_FWSTATS_FILE(event, oom_late, 20, "%u");
-DEBUGFS_FWSTATS_FILE(event, phy_transmit_error, 20, "%u");
-DEBUGFS_FWSTATS_FILE(event, tx_stuck, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(ps, pspoll_timeouts, 20, "%u");
-DEBUGFS_FWSTATS_FILE(ps, upsd_timeouts, 20, "%u");
-DEBUGFS_FWSTATS_FILE(ps, upsd_max_sptime, 20, "%u");
-DEBUGFS_FWSTATS_FILE(ps, upsd_max_apturn, 20, "%u");
-DEBUGFS_FWSTATS_FILE(ps, pspoll_max_apturn, 20, "%u");
-DEBUGFS_FWSTATS_FILE(ps, pspoll_utilization, 20, "%u");
-DEBUGFS_FWSTATS_FILE(ps, upsd_utilization, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(rxpipe, rx_prep_beacon_drop, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rxpipe, descr_host_int_trig_rx_data, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rxpipe, beacon_buffer_thres_host_int_trig_rx_data,
-                    20, "%u");
-DEBUGFS_FWSTATS_FILE(rxpipe, missed_beacon_host_int_trig_rx_data, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rxpipe, tx_xfr_host_int_trig_rx_data, 20, "%u");
-
-DEBUGFS_READONLY_FILE(retry_count, 20, "%u", wl->stats.retry_count);
-DEBUGFS_READONLY_FILE(excessive_retries, 20, "%u",
-                     wl->stats.excessive_retries);
-
-static ssize_t tx_queue_len_read(struct file *file, char __user *userbuf,
-                                size_t count, loff_t *ppos)
-{
-       struct wl1251 *wl = file->private_data;
-       u32 queue_len;
-       char buf[20];
-       int res;
-
-       queue_len = skb_queue_len(&wl->tx_queue);
-
-       res = scnprintf(buf, sizeof(buf), "%u\n", queue_len);
-       return simple_read_from_buffer(userbuf, count, ppos, buf, res);
-}
-
-static const struct file_operations tx_queue_len_ops = {
-       .read = tx_queue_len_read,
-       .open = wl1251_open_file_generic,
-};
-
-static ssize_t tx_queue_status_read(struct file *file, char __user *userbuf,
-                                   size_t count, loff_t *ppos)
-{
-       struct wl1251 *wl = file->private_data;
-       char buf[3], status;
-       int len;
-
-       if (wl->tx_queue_stopped)
-               status = 's';
-       else
-               status = 'r';
-
-       len = scnprintf(buf, sizeof(buf), "%c\n", status);
-       return simple_read_from_buffer(userbuf, count, ppos, buf, len);
-}
-
-static const struct file_operations tx_queue_status_ops = {
-       .read = tx_queue_status_read,
-       .open = wl1251_open_file_generic,
-};
-
-static void wl1251_debugfs_delete_files(struct wl1251 *wl)
-{
-       DEBUGFS_FWSTATS_DEL(tx, internal_desc_overflow);
-
-       DEBUGFS_FWSTATS_DEL(rx, out_of_mem);
-       DEBUGFS_FWSTATS_DEL(rx, hdr_overflow);
-       DEBUGFS_FWSTATS_DEL(rx, hw_stuck);
-       DEBUGFS_FWSTATS_DEL(rx, dropped);
-       DEBUGFS_FWSTATS_DEL(rx, fcs_err);
-       DEBUGFS_FWSTATS_DEL(rx, xfr_hint_trig);
-       DEBUGFS_FWSTATS_DEL(rx, path_reset);
-       DEBUGFS_FWSTATS_DEL(rx, reset_counter);
-
-       DEBUGFS_FWSTATS_DEL(dma, rx_requested);
-       DEBUGFS_FWSTATS_DEL(dma, rx_errors);
-       DEBUGFS_FWSTATS_DEL(dma, tx_requested);
-       DEBUGFS_FWSTATS_DEL(dma, tx_errors);
-
-       DEBUGFS_FWSTATS_DEL(isr, cmd_cmplt);
-       DEBUGFS_FWSTATS_DEL(isr, fiqs);
-       DEBUGFS_FWSTATS_DEL(isr, rx_headers);
-       DEBUGFS_FWSTATS_DEL(isr, rx_mem_overflow);
-       DEBUGFS_FWSTATS_DEL(isr, rx_rdys);
-       DEBUGFS_FWSTATS_DEL(isr, irqs);
-       DEBUGFS_FWSTATS_DEL(isr, tx_procs);
-       DEBUGFS_FWSTATS_DEL(isr, decrypt_done);
-       DEBUGFS_FWSTATS_DEL(isr, dma0_done);
-       DEBUGFS_FWSTATS_DEL(isr, dma1_done);
-       DEBUGFS_FWSTATS_DEL(isr, tx_exch_complete);
-       DEBUGFS_FWSTATS_DEL(isr, commands);
-       DEBUGFS_FWSTATS_DEL(isr, rx_procs);
-       DEBUGFS_FWSTATS_DEL(isr, hw_pm_mode_changes);
-       DEBUGFS_FWSTATS_DEL(isr, host_acknowledges);
-       DEBUGFS_FWSTATS_DEL(isr, pci_pm);
-       DEBUGFS_FWSTATS_DEL(isr, wakeups);
-       DEBUGFS_FWSTATS_DEL(isr, low_rssi);
-
-       DEBUGFS_FWSTATS_DEL(wep, addr_key_count);
-       DEBUGFS_FWSTATS_DEL(wep, default_key_count);
-       /* skipping wep.reserved */
-       DEBUGFS_FWSTATS_DEL(wep, key_not_found);
-       DEBUGFS_FWSTATS_DEL(wep, decrypt_fail);
-       DEBUGFS_FWSTATS_DEL(wep, packets);
-       DEBUGFS_FWSTATS_DEL(wep, interrupt);
-
-       DEBUGFS_FWSTATS_DEL(pwr, ps_enter);
-       DEBUGFS_FWSTATS_DEL(pwr, elp_enter);
-       DEBUGFS_FWSTATS_DEL(pwr, missing_bcns);
-       DEBUGFS_FWSTATS_DEL(pwr, wake_on_host);
-       DEBUGFS_FWSTATS_DEL(pwr, wake_on_timer_exp);
-       DEBUGFS_FWSTATS_DEL(pwr, tx_with_ps);
-       DEBUGFS_FWSTATS_DEL(pwr, tx_without_ps);
-       DEBUGFS_FWSTATS_DEL(pwr, rcvd_beacons);
-       DEBUGFS_FWSTATS_DEL(pwr, power_save_off);
-       DEBUGFS_FWSTATS_DEL(pwr, enable_ps);
-       DEBUGFS_FWSTATS_DEL(pwr, disable_ps);
-       DEBUGFS_FWSTATS_DEL(pwr, fix_tsf_ps);
-       /* skipping cont_miss_bcns_spread for now */
-       DEBUGFS_FWSTATS_DEL(pwr, rcvd_awake_beacons);
-
-       DEBUGFS_FWSTATS_DEL(mic, rx_pkts);
-       DEBUGFS_FWSTATS_DEL(mic, calc_failure);
-
-       DEBUGFS_FWSTATS_DEL(aes, encrypt_fail);
-       DEBUGFS_FWSTATS_DEL(aes, decrypt_fail);
-       DEBUGFS_FWSTATS_DEL(aes, encrypt_packets);
-       DEBUGFS_FWSTATS_DEL(aes, decrypt_packets);
-       DEBUGFS_FWSTATS_DEL(aes, encrypt_interrupt);
-       DEBUGFS_FWSTATS_DEL(aes, decrypt_interrupt);
-
-       DEBUGFS_FWSTATS_DEL(event, heart_beat);
-       DEBUGFS_FWSTATS_DEL(event, calibration);
-       DEBUGFS_FWSTATS_DEL(event, rx_mismatch);
-       DEBUGFS_FWSTATS_DEL(event, rx_mem_empty);
-       DEBUGFS_FWSTATS_DEL(event, rx_pool);
-       DEBUGFS_FWSTATS_DEL(event, oom_late);
-       DEBUGFS_FWSTATS_DEL(event, phy_transmit_error);
-       DEBUGFS_FWSTATS_DEL(event, tx_stuck);
-
-       DEBUGFS_FWSTATS_DEL(ps, pspoll_timeouts);
-       DEBUGFS_FWSTATS_DEL(ps, upsd_timeouts);
-       DEBUGFS_FWSTATS_DEL(ps, upsd_max_sptime);
-       DEBUGFS_FWSTATS_DEL(ps, upsd_max_apturn);
-       DEBUGFS_FWSTATS_DEL(ps, pspoll_max_apturn);
-       DEBUGFS_FWSTATS_DEL(ps, pspoll_utilization);
-       DEBUGFS_FWSTATS_DEL(ps, upsd_utilization);
-
-       DEBUGFS_FWSTATS_DEL(rxpipe, rx_prep_beacon_drop);
-       DEBUGFS_FWSTATS_DEL(rxpipe, descr_host_int_trig_rx_data);
-       DEBUGFS_FWSTATS_DEL(rxpipe, beacon_buffer_thres_host_int_trig_rx_data);
-       DEBUGFS_FWSTATS_DEL(rxpipe, missed_beacon_host_int_trig_rx_data);
-       DEBUGFS_FWSTATS_DEL(rxpipe, tx_xfr_host_int_trig_rx_data);
-
-       DEBUGFS_DEL(tx_queue_len);
-       DEBUGFS_DEL(tx_queue_status);
-       DEBUGFS_DEL(retry_count);
-       DEBUGFS_DEL(excessive_retries);
-}
-
-static int wl1251_debugfs_add_files(struct wl1251 *wl)
-{
-       int ret = 0;
-
-       DEBUGFS_FWSTATS_ADD(tx, internal_desc_overflow);
-
-       DEBUGFS_FWSTATS_ADD(rx, out_of_mem);
-       DEBUGFS_FWSTATS_ADD(rx, hdr_overflow);
-       DEBUGFS_FWSTATS_ADD(rx, hw_stuck);
-       DEBUGFS_FWSTATS_ADD(rx, dropped);
-       DEBUGFS_FWSTATS_ADD(rx, fcs_err);
-       DEBUGFS_FWSTATS_ADD(rx, xfr_hint_trig);
-       DEBUGFS_FWSTATS_ADD(rx, path_reset);
-       DEBUGFS_FWSTATS_ADD(rx, reset_counter);
-
-       DEBUGFS_FWSTATS_ADD(dma, rx_requested);
-       DEBUGFS_FWSTATS_ADD(dma, rx_errors);
-       DEBUGFS_FWSTATS_ADD(dma, tx_requested);
-       DEBUGFS_FWSTATS_ADD(dma, tx_errors);
-
-       DEBUGFS_FWSTATS_ADD(isr, cmd_cmplt);
-       DEBUGFS_FWSTATS_ADD(isr, fiqs);
-       DEBUGFS_FWSTATS_ADD(isr, rx_headers);
-       DEBUGFS_FWSTATS_ADD(isr, rx_mem_overflow);
-       DEBUGFS_FWSTATS_ADD(isr, rx_rdys);
-       DEBUGFS_FWSTATS_ADD(isr, irqs);
-       DEBUGFS_FWSTATS_ADD(isr, tx_procs);
-       DEBUGFS_FWSTATS_ADD(isr, decrypt_done);
-       DEBUGFS_FWSTATS_ADD(isr, dma0_done);
-       DEBUGFS_FWSTATS_ADD(isr, dma1_done);
-       DEBUGFS_FWSTATS_ADD(isr, tx_exch_complete);
-       DEBUGFS_FWSTATS_ADD(isr, commands);
-       DEBUGFS_FWSTATS_ADD(isr, rx_procs);
-       DEBUGFS_FWSTATS_ADD(isr, hw_pm_mode_changes);
-       DEBUGFS_FWSTATS_ADD(isr, host_acknowledges);
-       DEBUGFS_FWSTATS_ADD(isr, pci_pm);
-       DEBUGFS_FWSTATS_ADD(isr, wakeups);
-       DEBUGFS_FWSTATS_ADD(isr, low_rssi);
-
-       DEBUGFS_FWSTATS_ADD(wep, addr_key_count);
-       DEBUGFS_FWSTATS_ADD(wep, default_key_count);
-       /* skipping wep.reserved */
-       DEBUGFS_FWSTATS_ADD(wep, key_not_found);
-       DEBUGFS_FWSTATS_ADD(wep, decrypt_fail);
-       DEBUGFS_FWSTATS_ADD(wep, packets);
-       DEBUGFS_FWSTATS_ADD(wep, interrupt);
-
-       DEBUGFS_FWSTATS_ADD(pwr, ps_enter);
-       DEBUGFS_FWSTATS_ADD(pwr, elp_enter);
-       DEBUGFS_FWSTATS_ADD(pwr, missing_bcns);
-       DEBUGFS_FWSTATS_ADD(pwr, wake_on_host);
-       DEBUGFS_FWSTATS_ADD(pwr, wake_on_timer_exp);
-       DEBUGFS_FWSTATS_ADD(pwr, tx_with_ps);
-       DEBUGFS_FWSTATS_ADD(pwr, tx_without_ps);
-       DEBUGFS_FWSTATS_ADD(pwr, rcvd_beacons);
-       DEBUGFS_FWSTATS_ADD(pwr, power_save_off);
-       DEBUGFS_FWSTATS_ADD(pwr, enable_ps);
-       DEBUGFS_FWSTATS_ADD(pwr, disable_ps);
-       DEBUGFS_FWSTATS_ADD(pwr, fix_tsf_ps);
-       /* skipping cont_miss_bcns_spread for now */
-       DEBUGFS_FWSTATS_ADD(pwr, rcvd_awake_beacons);
-
-       DEBUGFS_FWSTATS_ADD(mic, rx_pkts);
-       DEBUGFS_FWSTATS_ADD(mic, calc_failure);
-
-       DEBUGFS_FWSTATS_ADD(aes, encrypt_fail);
-       DEBUGFS_FWSTATS_ADD(aes, decrypt_fail);
-       DEBUGFS_FWSTATS_ADD(aes, encrypt_packets);
-       DEBUGFS_FWSTATS_ADD(aes, decrypt_packets);
-       DEBUGFS_FWSTATS_ADD(aes, encrypt_interrupt);
-       DEBUGFS_FWSTATS_ADD(aes, decrypt_interrupt);
-
-       DEBUGFS_FWSTATS_ADD(event, heart_beat);
-       DEBUGFS_FWSTATS_ADD(event, calibration);
-       DEBUGFS_FWSTATS_ADD(event, rx_mismatch);
-       DEBUGFS_FWSTATS_ADD(event, rx_mem_empty);
-       DEBUGFS_FWSTATS_ADD(event, rx_pool);
-       DEBUGFS_FWSTATS_ADD(event, oom_late);
-       DEBUGFS_FWSTATS_ADD(event, phy_transmit_error);
-       DEBUGFS_FWSTATS_ADD(event, tx_stuck);
-
-       DEBUGFS_FWSTATS_ADD(ps, pspoll_timeouts);
-       DEBUGFS_FWSTATS_ADD(ps, upsd_timeouts);
-       DEBUGFS_FWSTATS_ADD(ps, upsd_max_sptime);
-       DEBUGFS_FWSTATS_ADD(ps, upsd_max_apturn);
-       DEBUGFS_FWSTATS_ADD(ps, pspoll_max_apturn);
-       DEBUGFS_FWSTATS_ADD(ps, pspoll_utilization);
-       DEBUGFS_FWSTATS_ADD(ps, upsd_utilization);
-
-       DEBUGFS_FWSTATS_ADD(rxpipe, rx_prep_beacon_drop);
-       DEBUGFS_FWSTATS_ADD(rxpipe, descr_host_int_trig_rx_data);
-       DEBUGFS_FWSTATS_ADD(rxpipe, beacon_buffer_thres_host_int_trig_rx_data);
-       DEBUGFS_FWSTATS_ADD(rxpipe, missed_beacon_host_int_trig_rx_data);
-       DEBUGFS_FWSTATS_ADD(rxpipe, tx_xfr_host_int_trig_rx_data);
-
-       DEBUGFS_ADD(tx_queue_len, wl->debugfs.rootdir);
-       DEBUGFS_ADD(tx_queue_status, wl->debugfs.rootdir);
-       DEBUGFS_ADD(retry_count, wl->debugfs.rootdir);
-       DEBUGFS_ADD(excessive_retries, wl->debugfs.rootdir);
-
-out:
-       if (ret < 0)
-               wl1251_debugfs_delete_files(wl);
-
-       return ret;
-}
-
-void wl1251_debugfs_reset(struct wl1251 *wl)
-{
-       if (wl->stats.fw_stats != NULL)
-               memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats));
-       wl->stats.retry_count = 0;
-       wl->stats.excessive_retries = 0;
-}
-
-int wl1251_debugfs_init(struct wl1251 *wl)
-{
-       int ret;
-
-       wl->debugfs.rootdir = debugfs_create_dir(KBUILD_MODNAME, NULL);
-
-       if (IS_ERR(wl->debugfs.rootdir)) {
-               ret = PTR_ERR(wl->debugfs.rootdir);
-               wl->debugfs.rootdir = NULL;
-               goto err;
-       }
-
-       wl->debugfs.fw_statistics = debugfs_create_dir("fw-statistics",
-                                                      wl->debugfs.rootdir);
-
-       if (IS_ERR(wl->debugfs.fw_statistics)) {
-               ret = PTR_ERR(wl->debugfs.fw_statistics);
-               wl->debugfs.fw_statistics = NULL;
-               goto err_root;
-       }
-
-       wl->stats.fw_stats = kzalloc(sizeof(*wl->stats.fw_stats),
-                                     GFP_KERNEL);
-
-       if (!wl->stats.fw_stats) {
-               ret = -ENOMEM;
-               goto err_fw;
-       }
-
-       wl->stats.fw_stats_update = jiffies;
-
-       ret = wl1251_debugfs_add_files(wl);
-
-       if (ret < 0)
-               goto err_file;
-
-       return 0;
-
-err_file:
-       kfree(wl->stats.fw_stats);
-       wl->stats.fw_stats = NULL;
-
-err_fw:
-       debugfs_remove(wl->debugfs.fw_statistics);
-       wl->debugfs.fw_statistics = NULL;
-
-err_root:
-       debugfs_remove(wl->debugfs.rootdir);
-       wl->debugfs.rootdir = NULL;
-
-err:
-       return ret;
-}
-
-void wl1251_debugfs_exit(struct wl1251 *wl)
-{
-       wl1251_debugfs_delete_files(wl);
-
-       kfree(wl->stats.fw_stats);
-       wl->stats.fw_stats = NULL;
-
-       debugfs_remove(wl->debugfs.fw_statistics);
-       wl->debugfs.fw_statistics = NULL;
-
-       debugfs_remove(wl->debugfs.rootdir);
-       wl->debugfs.rootdir = NULL;
-
-}
diff --git a/drivers/net/wireless/wl12xx/wl1251_debugfs.h b/drivers/net/wireless/wl12xx/wl1251_debugfs.h
deleted file mode 100644 (file)
index b3417c0..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * This file is part of wl1251
- *
- * Copyright (C) 2009 Nokia Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef WL1251_DEBUGFS_H
-#define WL1251_DEBUGFS_H
-
-#include "wl1251.h"
-
-int wl1251_debugfs_init(struct wl1251 *wl);
-void wl1251_debugfs_exit(struct wl1251 *wl);
-void wl1251_debugfs_reset(struct wl1251 *wl);
-
-#endif /* WL1251_DEBUGFS_H */
diff --git a/drivers/net/wireless/wl12xx/wl1251_event.c b/drivers/net/wireless/wl12xx/wl1251_event.c
deleted file mode 100644 (file)
index 5422355..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * This file is part of wl1251
- *
- * Copyright (c) 1998-2007 Texas Instruments Incorporated
- * Copyright (C) 2008 Nokia Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include "wl1251.h"
-#include "wl1251_reg.h"
-#include "wl1251_io.h"
-#include "wl1251_event.h"
-#include "wl1251_ps.h"
-
-static int wl1251_event_scan_complete(struct wl1251 *wl,
-                                     struct event_mailbox *mbox)
-{
-       wl1251_debug(DEBUG_EVENT, "status: 0x%x, channels: %d",
-                    mbox->scheduled_scan_status,
-                    mbox->scheduled_scan_channels);
-
-       if (wl->scanning) {
-               ieee80211_scan_completed(wl->hw, false);
-               wl1251_debug(DEBUG_MAC80211, "mac80211 hw scan completed");
-               wl->scanning = false;
-       }
-
-       return 0;
-}
-
-static void wl1251_event_mbox_dump(struct event_mailbox *mbox)
-{
-       wl1251_debug(DEBUG_EVENT, "MBOX DUMP:");
-       wl1251_debug(DEBUG_EVENT, "\tvector: 0x%x", mbox->events_vector);
-       wl1251_debug(DEBUG_EVENT, "\tmask: 0x%x", mbox->events_mask);
-}
-
-static int wl1251_event_process(struct wl1251 *wl, struct event_mailbox *mbox)
-{
-       int ret;
-       u32 vector;
-
-       wl1251_event_mbox_dump(mbox);
-
-       vector = mbox->events_vector & ~(mbox->events_mask);
-       wl1251_debug(DEBUG_EVENT, "vector: 0x%x", vector);
-
-       if (vector & SCAN_COMPLETE_EVENT_ID) {
-               ret = wl1251_event_scan_complete(wl, mbox);
-               if (ret < 0)
-                       return ret;
-       }
-
-       if (vector & BSS_LOSE_EVENT_ID) {
-               wl1251_debug(DEBUG_EVENT, "BSS_LOSE_EVENT");
-
-               if (wl->psm_requested && wl->psm) {
-                       ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE);
-                       if (ret < 0)
-                               return ret;
-               }
-       }
-
-       if (vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID && wl->psm) {
-               wl1251_debug(DEBUG_EVENT, "SYNCHRONIZATION_TIMEOUT_EVENT");
-
-               /* indicate to the stack, that beacons have been lost */
-               ieee80211_beacon_loss(wl->vif);
-       }
-
-       if (vector & REGAINED_BSS_EVENT_ID) {
-               if (wl->psm_requested) {
-                       ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
-                       if (ret < 0)
-                               return ret;
-               }
-       }
-
-       return 0;
-}
-
-/*
- * Poll the mailbox event field until any of the bits in the mask is set or a
- * timeout occurs (WL1251_EVENT_TIMEOUT in msecs)
- */
-int wl1251_event_wait(struct wl1251 *wl, u32 mask, int timeout_ms)
-{
-       u32 events_vector, event;
-       unsigned long timeout;
-
-       timeout = jiffies + msecs_to_jiffies(timeout_ms);
-
-       do {
-               if (time_after(jiffies, timeout))
-                       return -ETIMEDOUT;
-
-               msleep(1);
-
-               /* read from both event fields */
-               wl1251_mem_read(wl, wl->mbox_ptr[0], &events_vector,
-                               sizeof(events_vector));
-               event = events_vector & mask;
-               wl1251_mem_read(wl, wl->mbox_ptr[1], &events_vector,
-                               sizeof(events_vector));
-               event |= events_vector & mask;
-       } while (!event);
-
-       return 0;
-}
-
-int wl1251_event_unmask(struct wl1251 *wl)
-{
-       int ret;
-
-       ret = wl1251_acx_event_mbox_mask(wl, ~(wl->event_mask));
-       if (ret < 0)
-               return ret;
-
-       return 0;
-}
-
-void wl1251_event_mbox_config(struct wl1251 *wl)
-{
-       wl->mbox_ptr[0] = wl1251_reg_read32(wl, REG_EVENT_MAILBOX_PTR);
-       wl->mbox_ptr[1] = wl->mbox_ptr[0] + sizeof(struct event_mailbox);
-
-       wl1251_debug(DEBUG_EVENT, "MBOX ptrs: 0x%x 0x%x",
-                    wl->mbox_ptr[0], wl->mbox_ptr[1]);
-}
-
-int wl1251_event_handle(struct wl1251 *wl, u8 mbox_num)
-{
-       struct event_mailbox mbox;
-       int ret;
-
-       wl1251_debug(DEBUG_EVENT, "EVENT on mbox %d", mbox_num);
-
-       if (mbox_num > 1)
-               return -EINVAL;
-
-       /* first we read the mbox descriptor */
-       wl1251_mem_read(wl, wl->mbox_ptr[mbox_num], &mbox,
-                           sizeof(struct event_mailbox));
-
-       /* process the descriptor */
-       ret = wl1251_event_process(wl, &mbox);
-       if (ret < 0)
-               return ret;
-
-       /* then we let the firmware know it can go on...*/
-       wl1251_reg_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_EVENT_ACK);
-
-       return 0;
-}
diff --git a/drivers/net/wireless/wl12xx/wl1251_event.h b/drivers/net/wireless/wl12xx/wl1251_event.h
deleted file mode 100644 (file)
index 30eb5d1..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * This file is part of wl1251
- *
- * Copyright (c) 1998-2007 Texas Instruments Incorporated
- * Copyright (C) 2008 Nokia Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __WL1251_EVENT_H__
-#define __WL1251_EVENT_H__
-
-/*
- * Mbox events
- *
- * The event mechanism is based on a pair of event buffers (buffers A and
- * B) at fixed locations in the target's memory. The host processes one
- * buffer while the other buffer continues to collect events. If the host
- * is not processing events, an interrupt is issued to signal that a buffer
- * is ready. Once the host is done with processing events from one buffer,
- * it signals the target (with an ACK interrupt) that the event buffer is
- * free.
- */
-
-enum {
-       RESERVED1_EVENT_ID                       = BIT(0),
-       RESERVED2_EVENT_ID                       = BIT(1),
-       MEASUREMENT_START_EVENT_ID               = BIT(2),
-       SCAN_COMPLETE_EVENT_ID                   = BIT(3),
-       CALIBRATION_COMPLETE_EVENT_ID            = BIT(4),
-       ROAMING_TRIGGER_LOW_RSSI_EVENT_ID        = BIT(5),
-       PS_REPORT_EVENT_ID                       = BIT(6),
-       SYNCHRONIZATION_TIMEOUT_EVENT_ID         = BIT(7),
-       HEALTH_REPORT_EVENT_ID                   = BIT(8),
-       ACI_DETECTION_EVENT_ID                   = BIT(9),
-       DEBUG_REPORT_EVENT_ID                    = BIT(10),
-       MAC_STATUS_EVENT_ID                      = BIT(11),
-       DISCONNECT_EVENT_COMPLETE_ID             = BIT(12),
-       JOIN_EVENT_COMPLETE_ID                   = BIT(13),
-       CHANNEL_SWITCH_COMPLETE_EVENT_ID         = BIT(14),
-       BSS_LOSE_EVENT_ID                        = BIT(15),
-       ROAMING_TRIGGER_MAX_TX_RETRY_EVENT_ID    = BIT(16),
-       MEASUREMENT_COMPLETE_EVENT_ID            = BIT(17),
-       AP_DISCOVERY_COMPLETE_EVENT_ID           = BIT(18),
-       SCHEDULED_SCAN_COMPLETE_EVENT_ID         = BIT(19),
-       PSPOLL_DELIVERY_FAILURE_EVENT_ID         = BIT(20),
-       RESET_BSS_EVENT_ID                       = BIT(21),
-       REGAINED_BSS_EVENT_ID                    = BIT(22),
-       ROAMING_TRIGGER_REGAINED_RSSI_EVENT_ID   = BIT(23),
-       ROAMING_TRIGGER_LOW_SNR_EVENT_ID         = BIT(24),
-       ROAMING_TRIGGER_REGAINED_SNR_EVENT_ID    = BIT(25),
-
-       DBG_EVENT_ID                             = BIT(26),
-       BT_PTA_SENSE_EVENT_ID                    = BIT(27),
-       BT_PTA_PREDICTION_EVENT_ID               = BIT(28),
-       BT_PTA_AVALANCHE_EVENT_ID                = BIT(29),
-
-       PLT_RX_CALIBRATION_COMPLETE_EVENT_ID     = BIT(30),
-
-       EVENT_MBOX_ALL_EVENT_ID                  = 0x7fffffff,
-};
-
-struct event_debug_report {
-       u8 debug_event_id;
-       u8 num_params;
-       u16 pad;
-       u32 report_1;
-       u32 report_2;
-       u32 report_3;
-} __packed;
-
-struct event_mailbox {
-       u32 events_vector;
-       u32 events_mask;
-       u32 reserved_1;
-       u32 reserved_2;
-
-       char average_rssi_level;
-       u8 ps_status;
-       u8 channel_switch_status;
-       u8 scheduled_scan_status;
-
-       /* Channels scanned by the scheduled scan */
-       u16 scheduled_scan_channels;
-
-       /* If bit 0 is set -> target's fatal error */
-       u16 health_report;
-       u16 bad_fft_counter;
-       u8 bt_pta_sense_info;
-       u8 bt_pta_protective_info;
-       u32 reserved;
-       u32 debug_report[2];
-
-       /* Number of FCS errors since last event */
-       u32 fcs_err_counter;
-
-       struct event_debug_report report;
-       u8 average_snr_level;
-       u8 padding[19];
-} __packed;
-
-int wl1251_event_unmask(struct wl1251 *wl);
-void wl1251_event_mbox_config(struct wl1251 *wl);
-int wl1251_event_handle(struct wl1251 *wl, u8 mbox);
-int wl1251_event_wait(struct wl1251 *wl, u32 mask, int timeout_ms);
-
-#endif
diff --git a/drivers/net/wireless/wl12xx/wl1251_init.c b/drivers/net/wireless/wl12xx/wl1251_init.c
deleted file mode 100644 (file)
index c5daec0..0000000
+++ /dev/null
@@ -1,423 +0,0 @@
-/*
- * This file is part of wl1251
- *
- * Copyright (C) 2009 Nokia Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-
-#include "wl1251_init.h"
-#include "wl12xx_80211.h"
-#include "wl1251_acx.h"
-#include "wl1251_cmd.h"
-#include "wl1251_reg.h"
-
-int wl1251_hw_init_hwenc_config(struct wl1251 *wl)
-{
-       int ret;
-
-       ret = wl1251_acx_feature_cfg(wl);
-       if (ret < 0) {
-               wl1251_warning("couldn't set feature config");
-               return ret;
-       }
-
-       ret = wl1251_acx_default_key(wl, wl->default_key);
-       if (ret < 0) {
-               wl1251_warning("couldn't set default key");
-               return ret;
-       }
-
-       return 0;
-}
-
-int wl1251_hw_init_templates_config(struct wl1251 *wl)
-{
-       int ret;
-       u8 partial_vbm[PARTIAL_VBM_MAX];
-
-       /* send empty templates for fw memory reservation */
-       ret = wl1251_cmd_template_set(wl, CMD_PROBE_REQ, NULL,
-                                     sizeof(struct wl12xx_probe_req_template));
-       if (ret < 0)
-               return ret;
-
-       ret = wl1251_cmd_template_set(wl, CMD_NULL_DATA, NULL,
-                                     sizeof(struct wl12xx_null_data_template));
-       if (ret < 0)
-               return ret;
-
-       ret = wl1251_cmd_template_set(wl, CMD_PS_POLL, NULL,
-                                     sizeof(struct wl12xx_ps_poll_template));
-       if (ret < 0)
-               return ret;
-
-       ret = wl1251_cmd_template_set(wl, CMD_QOS_NULL_DATA, NULL,
-                                     sizeof
-                                     (struct wl12xx_qos_null_data_template));
-       if (ret < 0)
-               return ret;
-
-       ret = wl1251_cmd_template_set(wl, CMD_PROBE_RESP, NULL,
-                                     sizeof
-                                     (struct wl12xx_probe_resp_template));
-       if (ret < 0)
-               return ret;
-
-       ret = wl1251_cmd_template_set(wl, CMD_BEACON, NULL,
-                                     sizeof
-                                     (struct wl12xx_beacon_template));
-       if (ret < 0)
-               return ret;
-
-       /* tim templates, first reserve space then allocate an empty one */
-       memset(partial_vbm, 0, PARTIAL_VBM_MAX);
-       ret = wl1251_cmd_vbm(wl, TIM_ELE_ID, partial_vbm, PARTIAL_VBM_MAX, 0);
-       if (ret < 0)
-               return ret;
-
-       ret = wl1251_cmd_vbm(wl, TIM_ELE_ID, partial_vbm, 1, 0);
-       if (ret < 0)
-               return ret;
-
-       return 0;
-}
-
-int wl1251_hw_init_rx_config(struct wl1251 *wl, u32 config, u32 filter)
-{
-       int ret;
-
-       ret = wl1251_acx_rx_msdu_life_time(wl, RX_MSDU_LIFETIME_DEF);
-       if (ret < 0)
-               return ret;
-
-       ret = wl1251_acx_rx_config(wl, config, filter);
-       if (ret < 0)
-               return ret;
-
-       return 0;
-}
-
-int wl1251_hw_init_phy_config(struct wl1251 *wl)
-{
-       int ret;
-
-       ret = wl1251_acx_pd_threshold(wl);
-       if (ret < 0)
-               return ret;
-
-       ret = wl1251_acx_slot(wl, DEFAULT_SLOT_TIME);
-       if (ret < 0)
-               return ret;
-
-       ret = wl1251_acx_group_address_tbl(wl);
-       if (ret < 0)
-               return ret;
-
-       ret = wl1251_acx_service_period_timeout(wl);
-       if (ret < 0)
-               return ret;
-
-       ret = wl1251_acx_rts_threshold(wl, RTS_THRESHOLD_DEF);
-       if (ret < 0)
-               return ret;
-
-       return 0;
-}
-
-int wl1251_hw_init_beacon_filter(struct wl1251 *wl)
-{
-       int ret;
-
-       /* disable beacon filtering at this stage */
-       ret = wl1251_acx_beacon_filter_opt(wl, false);
-       if (ret < 0)
-               return ret;
-
-       ret = wl1251_acx_beacon_filter_table(wl);
-       if (ret < 0)
-               return ret;
-
-       return 0;
-}
-
-int wl1251_hw_init_pta(struct wl1251 *wl)
-{
-       int ret;
-
-       ret = wl1251_acx_sg_enable(wl);
-       if (ret < 0)
-               return ret;
-
-       ret = wl1251_acx_sg_cfg(wl);
-       if (ret < 0)
-               return ret;
-
-       return 0;
-}
-
-int wl1251_hw_init_energy_detection(struct wl1251 *wl)
-{
-       int ret;
-
-       ret = wl1251_acx_cca_threshold(wl);
-       if (ret < 0)
-               return ret;
-
-       return 0;
-}
-
-int wl1251_hw_init_beacon_broadcast(struct wl1251 *wl)
-{
-       int ret;
-
-       ret = wl1251_acx_bcn_dtim_options(wl);
-       if (ret < 0)
-               return ret;
-
-       return 0;
-}
-
-int wl1251_hw_init_power_auth(struct wl1251 *wl)
-{
-       return wl1251_acx_sleep_auth(wl, WL1251_PSM_CAM);
-}
-
-int wl1251_hw_init_mem_config(struct wl1251 *wl)
-{
-       int ret;
-
-       ret = wl1251_acx_mem_cfg(wl);
-       if (ret < 0)
-               return ret;
-
-       wl->target_mem_map = kzalloc(sizeof(struct wl1251_acx_mem_map),
-                                         GFP_KERNEL);
-       if (!wl->target_mem_map) {
-               wl1251_error("couldn't allocate target memory map");
-               return -ENOMEM;
-       }
-
-       /* we now ask for the firmware built memory map */
-       ret = wl1251_acx_mem_map(wl, wl->target_mem_map,
-                                sizeof(struct wl1251_acx_mem_map));
-       if (ret < 0) {
-               wl1251_error("couldn't retrieve firmware memory map");
-               kfree(wl->target_mem_map);
-               wl->target_mem_map = NULL;
-               return ret;
-       }
-
-       return 0;
-}
-
-static int wl1251_hw_init_txq_fill(u8 qid,
-                                  struct acx_tx_queue_qos_config *config,
-                                  u32 num_blocks)
-{
-       config->qid = qid;
-
-       switch (qid) {
-       case QOS_AC_BE:
-               config->high_threshold =
-                       (QOS_TX_HIGH_BE_DEF * num_blocks) / 100;
-               config->low_threshold =
-                       (QOS_TX_LOW_BE_DEF * num_blocks) / 100;
-               break;
-       case QOS_AC_BK:
-               config->high_threshold =
-                       (QOS_TX_HIGH_BK_DEF * num_blocks) / 100;
-               config->low_threshold =
-                       (QOS_TX_LOW_BK_DEF * num_blocks) / 100;
-               break;
-       case QOS_AC_VI:
-               config->high_threshold =
-                       (QOS_TX_HIGH_VI_DEF * num_blocks) / 100;
-               config->low_threshold =
-                       (QOS_TX_LOW_VI_DEF * num_blocks) / 100;
-               break;
-       case QOS_AC_VO:
-               config->high_threshold =
-                       (QOS_TX_HIGH_VO_DEF * num_blocks) / 100;
-               config->low_threshold =
-                       (QOS_TX_LOW_VO_DEF * num_blocks) / 100;
-               break;
-       default:
-               wl1251_error("Invalid TX queue id: %d", qid);
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static int wl1251_hw_init_tx_queue_config(struct wl1251 *wl)
-{
-       struct acx_tx_queue_qos_config *config;
-       struct wl1251_acx_mem_map *wl_mem_map = wl->target_mem_map;
-       int ret, i;
-
-       wl1251_debug(DEBUG_ACX, "acx tx queue config");
-
-       config = kzalloc(sizeof(*config), GFP_KERNEL);
-       if (!config) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       for (i = 0; i < MAX_NUM_OF_AC; i++) {
-               ret = wl1251_hw_init_txq_fill(i, config,
-                                             wl_mem_map->num_tx_mem_blocks);
-               if (ret < 0)
-                       goto out;
-
-               ret = wl1251_cmd_configure(wl, ACX_TX_QUEUE_CFG,
-                                          config, sizeof(*config));
-               if (ret < 0)
-                       goto out;
-       }
-
-       wl1251_acx_ac_cfg(wl, AC_BE, CWMIN_BE, CWMAX_BE, AIFS_DIFS, TXOP_BE);
-       wl1251_acx_ac_cfg(wl, AC_BK, CWMIN_BK, CWMAX_BK, AIFS_DIFS, TXOP_BK);
-       wl1251_acx_ac_cfg(wl, AC_VI, CWMIN_VI, CWMAX_VI, AIFS_DIFS, TXOP_VI);
-       wl1251_acx_ac_cfg(wl, AC_VO, CWMIN_VO, CWMAX_VO, AIFS_DIFS, TXOP_VO);
-
-out:
-       kfree(config);
-       return ret;
-}
-
-static int wl1251_hw_init_data_path_config(struct wl1251 *wl)
-{
-       int ret;
-
-       /* asking for the data path parameters */
-       wl->data_path = kzalloc(sizeof(struct acx_data_path_params_resp),
-                               GFP_KERNEL);
-       if (!wl->data_path) {
-               wl1251_error("Couldnt allocate data path parameters");
-               return -ENOMEM;
-       }
-
-       ret = wl1251_acx_data_path_params(wl, wl->data_path);
-       if (ret < 0) {
-               kfree(wl->data_path);
-               wl->data_path = NULL;
-               return ret;
-       }
-
-       return 0;
-}
-
-
-int wl1251_hw_init(struct wl1251 *wl)
-{
-       struct wl1251_acx_mem_map *wl_mem_map;
-       int ret;
-
-       ret = wl1251_hw_init_hwenc_config(wl);
-       if (ret < 0)
-               return ret;
-
-       /* Template settings */
-       ret = wl1251_hw_init_templates_config(wl);
-       if (ret < 0)
-               return ret;
-
-       /* Default memory configuration */
-       ret = wl1251_hw_init_mem_config(wl);
-       if (ret < 0)
-               return ret;
-
-       /* Default data path configuration  */
-       ret = wl1251_hw_init_data_path_config(wl);
-       if (ret < 0)
-               goto out_free_memmap;
-
-       /* RX config */
-       ret = wl1251_hw_init_rx_config(wl,
-                                      RX_CFG_PROMISCUOUS | RX_CFG_TSF,
-                                      RX_FILTER_OPTION_DEF);
-       /* RX_CONFIG_OPTION_ANY_DST_ANY_BSS,
-          RX_FILTER_OPTION_FILTER_ALL); */
-       if (ret < 0)
-               goto out_free_data_path;
-
-       /* TX queues config */
-       ret = wl1251_hw_init_tx_queue_config(wl);
-       if (ret < 0)
-               goto out_free_data_path;
-
-       /* PHY layer config */
-       ret = wl1251_hw_init_phy_config(wl);
-       if (ret < 0)
-               goto out_free_data_path;
-
-       /* Initialize connection monitoring thresholds */
-       ret = wl1251_acx_conn_monit_params(wl);
-       if (ret < 0)
-               goto out_free_data_path;
-
-       /* Beacon filtering */
-       ret = wl1251_hw_init_beacon_filter(wl);
-       if (ret < 0)
-               goto out_free_data_path;
-
-       /* Bluetooth WLAN coexistence */
-       ret = wl1251_hw_init_pta(wl);
-       if (ret < 0)
-               goto out_free_data_path;
-
-       /* Energy detection */
-       ret = wl1251_hw_init_energy_detection(wl);
-       if (ret < 0)
-               goto out_free_data_path;
-
-       /* Beacons and boradcast settings */
-       ret = wl1251_hw_init_beacon_broadcast(wl);
-       if (ret < 0)
-               goto out_free_data_path;
-
-       /* Enable data path */
-       ret = wl1251_cmd_data_path(wl, wl->channel, 1);
-       if (ret < 0)
-               goto out_free_data_path;
-
-       /* Default power state */
-       ret = wl1251_hw_init_power_auth(wl);
-       if (ret < 0)
-               goto out_free_data_path;
-
-       wl_mem_map = wl->target_mem_map;
-       wl1251_info("%d tx blocks at 0x%x, %d rx blocks at 0x%x",
-                   wl_mem_map->num_tx_mem_blocks,
-                   wl->data_path->tx_control_addr,
-                   wl_mem_map->num_rx_mem_blocks,
-                   wl->data_path->rx_control_addr);
-
-       return 0;
-
- out_free_data_path:
-       kfree(wl->data_path);
-
- out_free_memmap:
-       kfree(wl->target_mem_map);
-
-       return ret;
-}
diff --git a/drivers/net/wireless/wl12xx/wl1251_init.h b/drivers/net/wireless/wl12xx/wl1251_init.h
deleted file mode 100644 (file)
index 543f175..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * This file is part of wl1251
- *
- * Copyright (C) 2009 Nokia Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __WL1251_INIT_H__
-#define __WL1251_INIT_H__
-
-#include "wl1251.h"
-
-enum {
-       /* best effort/legacy */
-       AC_BE = 0,
-
-       /* background */
-       AC_BK = 1,
-
-       /* video */
-       AC_VI = 2,
-
-       /* voice */
-       AC_VO = 3,
-
-       /* broadcast dummy access category */
-       AC_BCAST = 4,
-
-       NUM_ACCESS_CATEGORIES = 4
-};
-
-/* following are defult values for the IE fields*/
-#define CWMIN_BK  15
-#define CWMIN_BE  15
-#define CWMIN_VI  7
-#define CWMIN_VO  3
-#define CWMAX_BK  1023
-#define CWMAX_BE  63
-#define CWMAX_VI  15
-#define CWMAX_VO  7
-
-/* slot number setting to start transmission at PIFS interval */
-#define AIFS_PIFS 1
-
-/*
- * slot number setting to start transmission at DIFS interval - normal DCF
- * access
- */
-#define AIFS_DIFS 2
-
-#define AIFSN_BK  7
-#define AIFSN_BE  3
-#define AIFSN_VI  AIFS_PIFS
-#define AIFSN_VO  AIFS_PIFS
-#define TXOP_BK   0
-#define TXOP_BE   0
-#define TXOP_VI   3008
-#define TXOP_VO   1504
-
-int wl1251_hw_init_hwenc_config(struct wl1251 *wl);
-int wl1251_hw_init_templates_config(struct wl1251 *wl);
-int wl1251_hw_init_rx_config(struct wl1251 *wl, u32 config, u32 filter);
-int wl1251_hw_init_phy_config(struct wl1251 *wl);
-int wl1251_hw_init_beacon_filter(struct wl1251 *wl);
-int wl1251_hw_init_pta(struct wl1251 *wl);
-int wl1251_hw_init_energy_detection(struct wl1251 *wl);
-int wl1251_hw_init_beacon_broadcast(struct wl1251 *wl);
-int wl1251_hw_init_power_auth(struct wl1251 *wl);
-int wl1251_hw_init_mem_config(struct wl1251 *wl);
-int wl1251_hw_init(struct wl1251 *wl);
-
-#endif
diff --git a/drivers/net/wireless/wl12xx/wl1251_io.c b/drivers/net/wireless/wl12xx/wl1251_io.c
deleted file mode 100644 (file)
index ad6ca68..0000000
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * This file is part of wl12xx
- *
- * Copyright (C) 2008 Nokia Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include "wl1251.h"
-#include "wl1251_reg.h"
-#include "wl1251_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] = {
-       [ACX_REG_INTERRUPT_TRIG]     = (REGISTERS_BASE + 0x0474),
-       [ACX_REG_INTERRUPT_TRIG_H]   = (REGISTERS_BASE + 0x0478),
-       [ACX_REG_INTERRUPT_MASK]     = (REGISTERS_BASE + 0x0494),
-       [ACX_REG_HINT_MASK_SET]      = (REGISTERS_BASE + 0x0498),
-       [ACX_REG_HINT_MASK_CLR]      = (REGISTERS_BASE + 0x049C),
-       [ACX_REG_INTERRUPT_NO_CLEAR] = (REGISTERS_BASE + 0x04B0),
-       [ACX_REG_INTERRUPT_CLEAR]    = (REGISTERS_BASE + 0x04A4),
-       [ACX_REG_INTERRUPT_ACK]      = (REGISTERS_BASE + 0x04A8),
-       [ACX_REG_SLV_SOFT_RESET]     = (REGISTERS_BASE + 0x0000),
-       [ACX_REG_EE_START]           = (REGISTERS_BASE + 0x080C),
-       [ACX_REG_ECPU_CONTROL]       = (REGISTERS_BASE + 0x0804)
-};
-
-static int wl1251_translate_reg_addr(struct wl1251 *wl, int addr)
-{
-       /* If the address is lower than REGISTERS_BASE, it means that this is
-        * a chip-specific register address, so look it up in the registers
-        * table */
-       if (addr < REGISTERS_BASE) {
-               /* Make sure we don't go over the table */
-               if (addr >= ACX_REG_TABLE_LEN) {
-                       wl1251_error("address out of range (%d)", addr);
-                       return -EINVAL;
-               }
-               addr = wl1251_io_reg_table[addr];
-       }
-
-       return addr - wl->physical_reg_addr + wl->virtual_reg_addr;
-}
-
-static int wl1251_translate_mem_addr(struct wl1251 *wl, int addr)
-{
-       return addr - wl->physical_mem_addr + wl->virtual_mem_addr;
-}
-
-void wl1251_mem_read(struct wl1251 *wl, int addr, void *buf, size_t len)
-{
-       int physical;
-
-       physical = wl1251_translate_mem_addr(wl, addr);
-
-       wl->if_ops->read(wl, physical, buf, len);
-}
-
-void wl1251_mem_write(struct wl1251 *wl, int addr, void *buf, size_t len)
-{
-       int physical;
-
-       physical = wl1251_translate_mem_addr(wl, addr);
-
-       wl->if_ops->write(wl, physical, buf, len);
-}
-
-u32 wl1251_mem_read32(struct wl1251 *wl, int addr)
-{
-       return wl1251_read32(wl, wl1251_translate_mem_addr(wl, addr));
-}
-
-void wl1251_mem_write32(struct wl1251 *wl, int addr, u32 val)
-{
-       wl1251_write32(wl, wl1251_translate_mem_addr(wl, addr), val);
-}
-
-u32 wl1251_reg_read32(struct wl1251 *wl, int addr)
-{
-       return wl1251_read32(wl, wl1251_translate_reg_addr(wl, addr));
-}
-
-void wl1251_reg_write32(struct wl1251 *wl, int addr, u32 val)
-{
-       wl1251_write32(wl, wl1251_translate_reg_addr(wl, addr), val);
-}
-
-/* Set the partitions to access the chip addresses.
- *
- * There are two VIRTUAL partitions (the memory partition and the
- * registers partition), which are mapped to two different areas of the
- * PHYSICAL (hardware) memory.  This function also makes other checks to
- * ensure that the partitions are not overlapping.  In the diagram below, the
- * memory partition comes before the register partition, but the opposite is
- * also supported.
- *
- *                               PHYSICAL address
- *                                     space
- *
- *                                    |    |
- *                                 ...+----+--> mem_start
- *          VIRTUAL address     ...   |    |
- *               space       ...      |    | [PART_0]
- *                        ...         |    |
- * 0x00000000 <--+----+...         ...+----+--> mem_start + mem_size
- *               |    |         ...   |    |
- *               |MEM |      ...      |    |
- *               |    |   ...         |    |
- *  part_size <--+----+...            |    | {unused area)
- *               |    |   ...         |    |
- *               |REG |      ...      |    |
- *  part_size    |    |         ...   |    |
- *      +     <--+----+...         ...+----+--> reg_start
- *  reg_size              ...         |    |
- *                           ...      |    | [PART_1]
- *                              ...   |    |
- *                                 ...+----+--> reg_start + reg_size
- *                                    |    |
- *
- */
-void wl1251_set_partition(struct wl1251 *wl,
-                         u32 mem_start, u32 mem_size,
-                         u32 reg_start, u32 reg_size)
-{
-       struct wl1251_partition partition[2];
-
-       wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
-                    mem_start, mem_size);
-       wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
-                    reg_start, reg_size);
-
-       /* Make sure that the two partitions together don't exceed the
-        * address range */
-       if ((mem_size + reg_size) > HW_ACCESS_MEMORY_MAX_RANGE) {
-               wl1251_debug(DEBUG_SPI, "Total size exceeds maximum virtual"
-                            " address range.  Truncating partition[0].");
-               mem_size = HW_ACCESS_MEMORY_MAX_RANGE - reg_size;
-               wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
-                            mem_start, mem_size);
-               wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
-                            reg_start, reg_size);
-       }
-
-       if ((mem_start < reg_start) &&
-           ((mem_start + mem_size) > reg_start)) {
-               /* Guarantee that the memory partition doesn't overlap the
-                * registers partition */
-               wl1251_debug(DEBUG_SPI, "End of partition[0] is "
-                            "overlapping partition[1].  Adjusted.");
-               mem_size = reg_start - mem_start;
-               wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
-                            mem_start, mem_size);
-               wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
-                            reg_start, reg_size);
-       } else if ((reg_start < mem_start) &&
-                  ((reg_start + reg_size) > mem_start)) {
-               /* Guarantee that the register partition doesn't overlap the
-                * memory partition */
-               wl1251_debug(DEBUG_SPI, "End of partition[1] is"
-                            " overlapping partition[0].  Adjusted.");
-               reg_size = mem_start - reg_start;
-               wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
-                            mem_start, mem_size);
-               wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
-                            reg_start, reg_size);
-       }
-
-       partition[0].start = mem_start;
-       partition[0].size  = mem_size;
-       partition[1].start = reg_start;
-       partition[1].size  = reg_size;
-
-       wl->physical_mem_addr = mem_start;
-       wl->physical_reg_addr = reg_start;
-
-       wl->virtual_mem_addr = 0;
-       wl->virtual_reg_addr = mem_size;
-
-       wl->if_ops->write(wl, HW_ACCESS_PART0_SIZE_ADDR, partition,
-               sizeof(partition));
-}
diff --git a/drivers/net/wireless/wl12xx/wl1251_io.h b/drivers/net/wireless/wl12xx/wl1251_io.h
deleted file mode 100644 (file)
index c545e9d..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * This file is part of wl12xx
- *
- * Copyright (C) 2008 Nokia Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-#ifndef __WL1251_IO_H__
-#define __WL1251_IO_H__
-
-#include "wl1251.h"
-
-#define HW_ACCESS_MEMORY_MAX_RANGE             0x1FFC0
-
-#define HW_ACCESS_PART0_SIZE_ADDR           0x1FFC0
-#define HW_ACCESS_PART0_START_ADDR          0x1FFC4
-#define HW_ACCESS_PART1_SIZE_ADDR           0x1FFC8
-#define HW_ACCESS_PART1_START_ADDR          0x1FFCC
-
-#define HW_ACCESS_REGISTER_SIZE             4
-
-#define HW_ACCESS_PRAM_MAX_RANGE               0x3c000
-
-static inline u32 wl1251_read32(struct wl1251 *wl, int addr)
-{
-       u32 response;
-
-       wl->if_ops->read(wl, addr, &response, sizeof(u32));
-
-       return response;
-}
-
-static inline void wl1251_write32(struct wl1251 *wl, int addr, u32 val)
-{
-       wl->if_ops->write(wl, addr, &val, sizeof(u32));
-}
-
-static inline u32 wl1251_read_elp(struct wl1251 *wl, int addr)
-{
-       u32 response;
-
-       if (wl->if_ops->read_elp)
-               wl->if_ops->read_elp(wl, addr, &response);
-       else
-               wl->if_ops->read(wl, addr, &response, sizeof(u32));
-
-       return response;
-}
-
-static inline void wl1251_write_elp(struct wl1251 *wl, int addr, u32 val)
-{
-       if (wl->if_ops->write_elp)
-               wl->if_ops->write_elp(wl, addr, val);
-       else
-               wl->if_ops->write(wl, addr, &val, sizeof(u32));
-}
-
-/* Memory target IO, address is translated to partition 0 */
-void wl1251_mem_read(struct wl1251 *wl, int addr, void *buf, size_t len);
-void wl1251_mem_write(struct wl1251 *wl, int addr, void *buf, size_t len);
-u32 wl1251_mem_read32(struct wl1251 *wl, int addr);
-void wl1251_mem_write32(struct wl1251 *wl, int addr, u32 val);
-/* Registers IO */
-u32 wl1251_reg_read32(struct wl1251 *wl, int addr);
-void wl1251_reg_write32(struct wl1251 *wl, int addr, u32 val);
-
-void wl1251_set_partition(struct wl1251 *wl,
-                         u32 part_start, u32 part_size,
-                         u32 reg_start,  u32 reg_size);
-
-#endif
diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c
deleted file mode 100644 (file)
index faf221c..0000000
+++ /dev/null
@@ -1,1435 +0,0 @@
-/*
- * This file is part of wl1251
- *
- * Copyright (C) 2008-2009 Nokia Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/firmware.h>
-#include <linux/delay.h>
-#include <linux/irq.h>
-#include <linux/crc32.h>
-#include <linux/etherdevice.h>
-#include <linux/vmalloc.h>
-#include <linux/slab.h>
-
-#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"
-
-void wl1251_enable_interrupts(struct wl1251 *wl)
-{
-       wl->if_ops->enable_irq(wl);
-}
-
-void wl1251_disable_interrupts(struct wl1251 *wl)
-{
-       wl->if_ops->disable_irq(wl);
-}
-
-static void wl1251_power_off(struct wl1251 *wl)
-{
-       wl->set_power(false);
-}
-
-static void wl1251_power_on(struct wl1251 *wl)
-{
-       wl->set_power(true);
-}
-
-static int wl1251_fetch_firmware(struct wl1251 *wl)
-{
-       const struct firmware *fw;
-       struct device *dev = wiphy_dev(wl->hw->wiphy);
-       int ret;
-
-       ret = request_firmware(&fw, WL1251_FW_NAME, dev);
-
-       if (ret < 0) {
-               wl1251_error("could not get firmware: %d", ret);
-               return ret;
-       }
-
-       if (fw->size % 4) {
-               wl1251_error("firmware size is not multiple of 32 bits: %zu",
-                            fw->size);
-               ret = -EILSEQ;
-               goto out;
-       }
-
-       wl->fw_len = fw->size;
-       wl->fw = vmalloc(wl->fw_len);
-
-       if (!wl->fw) {
-               wl1251_error("could not allocate memory for the firmware");
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       memcpy(wl->fw, fw->data, wl->fw_len);
-
-       ret = 0;
-
-out:
-       release_firmware(fw);
-
-       return ret;
-}
-
-static int wl1251_fetch_nvs(struct wl1251 *wl)
-{
-       const struct firmware *fw;
-       struct device *dev = wiphy_dev(wl->hw->wiphy);
-       int ret;
-
-       ret = request_firmware(&fw, WL1251_NVS_NAME, dev);
-
-       if (ret < 0) {
-               wl1251_error("could not get nvs file: %d", ret);
-               return ret;
-       }
-
-       if (fw->size % 4) {
-               wl1251_error("nvs size is not multiple of 32 bits: %zu",
-                            fw->size);
-               ret = -EILSEQ;
-               goto out;
-       }
-
-       wl->nvs_len = fw->size;
-       wl->nvs = kmemdup(fw->data, wl->nvs_len, GFP_KERNEL);
-
-       if (!wl->nvs) {
-               wl1251_error("could not allocate memory for the nvs file");
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       ret = 0;
-
-out:
-       release_firmware(fw);
-
-       return ret;
-}
-
-static void wl1251_fw_wakeup(struct wl1251 *wl)
-{
-       u32 elp_reg;
-
-       elp_reg = ELPCTRL_WAKE_UP;
-       wl1251_write_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg);
-       elp_reg = wl1251_read_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR);
-
-       if (!(elp_reg & ELPCTRL_WLAN_READY))
-               wl1251_warning("WLAN not ready");
-}
-
-static int wl1251_chip_wakeup(struct wl1251 *wl)
-{
-       int ret = 0;
-
-       wl1251_power_on(wl);
-       msleep(WL1251_POWER_ON_SLEEP);
-       wl->if_ops->reset(wl);
-
-       /* We don't need a real memory partition here, because we only want
-        * to use the registers at this point. */
-       wl1251_set_partition(wl,
-                            0x00000000,
-                            0x00000000,
-                            REGISTERS_BASE,
-                            REGISTERS_DOWN_SIZE);
-
-       /* ELP module wake up */
-       wl1251_fw_wakeup(wl);
-
-       /* whal_FwCtrl_BootSm() */
-
-       /* 0. read chip id from CHIP_ID */
-       wl->chip_id = wl1251_reg_read32(wl, CHIP_ID_B);
-
-       /* 1. check if chip id is valid */
-
-       switch (wl->chip_id) {
-       case CHIP_ID_1251_PG12:
-               wl1251_debug(DEBUG_BOOT, "chip id 0x%x (1251 PG12)",
-                            wl->chip_id);
-               break;
-       case CHIP_ID_1251_PG11:
-               wl1251_debug(DEBUG_BOOT, "chip id 0x%x (1251 PG11)",
-                            wl->chip_id);
-               break;
-       case CHIP_ID_1251_PG10:
-       default:
-               wl1251_error("unsupported chip id: 0x%x", wl->chip_id);
-               ret = -ENODEV;
-               goto out;
-       }
-
-       if (wl->fw == NULL) {
-               ret = wl1251_fetch_firmware(wl);
-               if (ret < 0)
-                       goto out;
-       }
-
-       if (wl->nvs == NULL && !wl->use_eeprom) {
-               /* No NVS from netlink, try to get it from the filesystem */
-               ret = wl1251_fetch_nvs(wl);
-               if (ret < 0)
-                       goto out;
-       }
-
-out:
-       return ret;
-}
-
-#define WL1251_IRQ_LOOP_COUNT 10
-static void wl1251_irq_work(struct work_struct *work)
-{
-       u32 intr, ctr = WL1251_IRQ_LOOP_COUNT;
-       struct wl1251 *wl =
-               container_of(work, struct wl1251, irq_work);
-       int ret;
-
-       mutex_lock(&wl->mutex);
-
-       wl1251_debug(DEBUG_IRQ, "IRQ work");
-
-       if (wl->state == WL1251_STATE_OFF)
-               goto out;
-
-       ret = wl1251_ps_elp_wakeup(wl);
-       if (ret < 0)
-               goto out;
-
-       wl1251_reg_write32(wl, ACX_REG_INTERRUPT_MASK, WL1251_ACX_INTR_ALL);
-
-       intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_CLEAR);
-       wl1251_debug(DEBUG_IRQ, "intr: 0x%x", intr);
-
-       do {
-               if (wl->data_path) {
-                       wl->rx_counter = wl1251_mem_read32(
-                               wl, wl->data_path->rx_control_addr);
-
-                       /* We handle a frmware bug here */
-                       switch ((wl->rx_counter - wl->rx_handled) & 0xf) {
-                       case 0:
-                               wl1251_debug(DEBUG_IRQ,
-                                            "RX: FW and host in sync");
-                               intr &= ~WL1251_ACX_INTR_RX0_DATA;
-                               intr &= ~WL1251_ACX_INTR_RX1_DATA;
-                               break;
-                       case 1:
-                               wl1251_debug(DEBUG_IRQ, "RX: FW +1");
-                               intr |= WL1251_ACX_INTR_RX0_DATA;
-                               intr &= ~WL1251_ACX_INTR_RX1_DATA;
-                               break;
-                       case 2:
-                               wl1251_debug(DEBUG_IRQ, "RX: FW +2");
-                               intr |= WL1251_ACX_INTR_RX0_DATA;
-                               intr |= WL1251_ACX_INTR_RX1_DATA;
-                               break;
-                       default:
-                               wl1251_warning(
-                                       "RX: FW and host out of sync: %d",
-                                       wl->rx_counter - wl->rx_handled);
-                               break;
-                       }
-
-                       wl->rx_handled = wl->rx_counter;
-
-                       wl1251_debug(DEBUG_IRQ, "RX counter: %d",
-                                    wl->rx_counter);
-               }
-
-               intr &= wl->intr_mask;
-
-               if (intr == 0) {
-                       wl1251_debug(DEBUG_IRQ, "INTR is 0");
-                       goto out_sleep;
-               }
-
-               if (intr & WL1251_ACX_INTR_RX0_DATA) {
-                       wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_RX0_DATA");
-                       wl1251_rx(wl);
-               }
-
-               if (intr & WL1251_ACX_INTR_RX1_DATA) {
-                       wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_RX1_DATA");
-                       wl1251_rx(wl);
-               }
-
-               if (intr & WL1251_ACX_INTR_TX_RESULT) {
-                       wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_TX_RESULT");
-                       wl1251_tx_complete(wl);
-               }
-
-               if (intr & WL1251_ACX_INTR_EVENT_A) {
-                       wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_EVENT_A");
-                       wl1251_event_handle(wl, 0);
-               }
-
-               if (intr & WL1251_ACX_INTR_EVENT_B) {
-                       wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_EVENT_B");
-                       wl1251_event_handle(wl, 1);
-               }
-
-               if (intr & WL1251_ACX_INTR_INIT_COMPLETE)
-                       wl1251_debug(DEBUG_IRQ,
-                                    "WL1251_ACX_INTR_INIT_COMPLETE");
-
-               if (--ctr == 0)
-                       break;
-
-               intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_CLEAR);
-       } while (intr);
-
-out_sleep:
-       wl1251_reg_write32(wl, ACX_REG_INTERRUPT_MASK, ~(wl->intr_mask));
-       wl1251_ps_elp_sleep(wl);
-
-out:
-       mutex_unlock(&wl->mutex);
-}
-
-static int wl1251_join(struct wl1251 *wl, u8 bss_type, u8 channel,
-                      u16 beacon_interval, u8 dtim_period)
-{
-       int ret;
-
-       ret = wl1251_acx_frame_rates(wl, DEFAULT_HW_GEN_TX_RATE,
-                                    DEFAULT_HW_GEN_MODULATION_TYPE,
-                                    wl->tx_mgmt_frm_rate,
-                                    wl->tx_mgmt_frm_mod);
-       if (ret < 0)
-               goto out;
-
-
-       ret = wl1251_cmd_join(wl, bss_type, channel, beacon_interval,
-                             dtim_period);
-       if (ret < 0)
-               goto out;
-
-       ret = wl1251_event_wait(wl, JOIN_EVENT_COMPLETE_ID, 100);
-       if (ret < 0)
-               wl1251_warning("join timeout");
-
-out:
-       return ret;
-}
-
-static void wl1251_filter_work(struct work_struct *work)
-{
-       struct wl1251 *wl =
-               container_of(work, struct wl1251, filter_work);
-       int ret;
-
-       mutex_lock(&wl->mutex);
-
-       if (wl->state == WL1251_STATE_OFF)
-               goto out;
-
-       ret = wl1251_ps_elp_wakeup(wl);
-       if (ret < 0)
-               goto out;
-
-       ret = wl1251_join(wl, wl->bss_type, wl->channel, wl->beacon_int,
-                         wl->dtim_period);
-       if (ret < 0)
-               goto out_sleep;
-
-out_sleep:
-       wl1251_ps_elp_sleep(wl);
-
-out:
-       mutex_unlock(&wl->mutex);
-}
-
-static int wl1251_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
-{
-       struct wl1251 *wl = hw->priv;
-       unsigned long flags;
-
-       skb_queue_tail(&wl->tx_queue, skb);
-
-       /*
-        * The chip specific setup must run before the first TX packet -
-        * before that, the tx_work will not be initialized!
-        */
-
-       ieee80211_queue_work(wl->hw, &wl->tx_work);
-
-       /*
-        * The workqueue is slow to process the tx_queue and we need stop
-        * the queue here, otherwise the queue will get too long.
-        */
-       if (skb_queue_len(&wl->tx_queue) >= WL1251_TX_QUEUE_HIGH_WATERMARK) {
-               wl1251_debug(DEBUG_TX, "op_tx: tx_queue full, stop queues");
-
-               spin_lock_irqsave(&wl->wl_lock, flags);
-               ieee80211_stop_queues(wl->hw);
-               wl->tx_queue_stopped = true;
-               spin_unlock_irqrestore(&wl->wl_lock, flags);
-       }
-
-       return NETDEV_TX_OK;
-}
-
-static int wl1251_op_start(struct ieee80211_hw *hw)
-{
-       struct wl1251 *wl = hw->priv;
-       struct wiphy *wiphy = hw->wiphy;
-       int ret = 0;
-
-       wl1251_debug(DEBUG_MAC80211, "mac80211 start");
-
-       mutex_lock(&wl->mutex);
-
-       if (wl->state != WL1251_STATE_OFF) {
-               wl1251_error("cannot start because not in off state: %d",
-                            wl->state);
-               ret = -EBUSY;
-               goto out;
-       }
-
-       ret = wl1251_chip_wakeup(wl);
-       if (ret < 0)
-               goto out;
-
-       ret = wl1251_boot(wl);
-       if (ret < 0)
-               goto out;
-
-       ret = wl1251_hw_init(wl);
-       if (ret < 0)
-               goto out;
-
-       ret = wl1251_acx_station_id(wl);
-       if (ret < 0)
-               goto out;
-
-       wl->state = WL1251_STATE_ON;
-
-       wl1251_info("firmware booted (%s)", wl->fw_ver);
-
-       /* update hw/fw version info in wiphy struct */
-       wiphy->hw_version = wl->chip_id;
-       strncpy(wiphy->fw_version, wl->fw_ver, sizeof(wiphy->fw_version));
-
-out:
-       if (ret < 0)
-               wl1251_power_off(wl);
-
-       mutex_unlock(&wl->mutex);
-
-       return ret;
-}
-
-static void wl1251_op_stop(struct ieee80211_hw *hw)
-{
-       struct wl1251 *wl = hw->priv;
-
-       wl1251_info("down");
-
-       wl1251_debug(DEBUG_MAC80211, "mac80211 stop");
-
-       mutex_lock(&wl->mutex);
-
-       WARN_ON(wl->state != WL1251_STATE_ON);
-
-       if (wl->scanning) {
-               ieee80211_scan_completed(wl->hw, true);
-               wl->scanning = false;
-       }
-
-       wl->state = WL1251_STATE_OFF;
-
-       wl1251_disable_interrupts(wl);
-
-       mutex_unlock(&wl->mutex);
-
-       cancel_work_sync(&wl->irq_work);
-       cancel_work_sync(&wl->tx_work);
-       cancel_work_sync(&wl->filter_work);
-
-       mutex_lock(&wl->mutex);
-
-       /* let's notify MAC80211 about the remaining pending TX frames */
-       wl1251_tx_flush(wl);
-       wl1251_power_off(wl);
-
-       memset(wl->bssid, 0, ETH_ALEN);
-       wl->listen_int = 1;
-       wl->bss_type = MAX_BSS_TYPE;
-
-       wl->data_in_count = 0;
-       wl->rx_counter = 0;
-       wl->rx_handled = 0;
-       wl->rx_current_buffer = 0;
-       wl->rx_last_id = 0;
-       wl->next_tx_complete = 0;
-       wl->elp = false;
-       wl->psm = 0;
-       wl->tx_queue_stopped = false;
-       wl->power_level = WL1251_DEFAULT_POWER_LEVEL;
-       wl->channel = WL1251_DEFAULT_CHANNEL;
-
-       wl1251_debugfs_reset(wl);
-
-       mutex_unlock(&wl->mutex);
-}
-
-static int wl1251_op_add_interface(struct ieee80211_hw *hw,
-                                  struct ieee80211_vif *vif)
-{
-       struct wl1251 *wl = hw->priv;
-       int ret = 0;
-
-       wl1251_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM",
-                    vif->type, vif->addr);
-
-       mutex_lock(&wl->mutex);
-       if (wl->vif) {
-               ret = -EBUSY;
-               goto out;
-       }
-
-       wl->vif = vif;
-
-       switch (vif->type) {
-       case NL80211_IFTYPE_STATION:
-               wl->bss_type = BSS_TYPE_STA_BSS;
-               break;
-       case NL80211_IFTYPE_ADHOC:
-               wl->bss_type = BSS_TYPE_IBSS;
-               break;
-       default:
-               ret = -EOPNOTSUPP;
-               goto out;
-       }
-
-       if (memcmp(wl->mac_addr, vif->addr, ETH_ALEN)) {
-               memcpy(wl->mac_addr, vif->addr, ETH_ALEN);
-               SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr);
-               ret = wl1251_acx_station_id(wl);
-               if (ret < 0)
-                       goto out;
-       }
-
-out:
-       mutex_unlock(&wl->mutex);
-       return ret;
-}
-
-static void wl1251_op_remove_interface(struct ieee80211_hw *hw,
-                                        struct ieee80211_vif *vif)
-{
-       struct wl1251 *wl = hw->priv;
-
-       mutex_lock(&wl->mutex);
-       wl1251_debug(DEBUG_MAC80211, "mac80211 remove interface");
-       wl->vif = NULL;
-       mutex_unlock(&wl->mutex);
-}
-
-static int wl1251_build_qos_null_data(struct wl1251 *wl)
-{
-       struct ieee80211_qos_hdr template;
-
-       memset(&template, 0, sizeof(template));
-
-       memcpy(template.addr1, wl->bssid, ETH_ALEN);
-       memcpy(template.addr2, wl->mac_addr, ETH_ALEN);
-       memcpy(template.addr3, wl->bssid, ETH_ALEN);
-
-       template.frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
-                                            IEEE80211_STYPE_QOS_NULLFUNC |
-                                            IEEE80211_FCTL_TODS);
-
-       /* FIXME: not sure what priority to use here */
-       template.qos_ctrl = cpu_to_le16(0);
-
-       return wl1251_cmd_template_set(wl, CMD_QOS_NULL_DATA, &template,
-                                      sizeof(template));
-}
-
-static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed)
-{
-       struct wl1251 *wl = hw->priv;
-       struct ieee80211_conf *conf = &hw->conf;
-       int channel, ret = 0;
-
-       channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
-
-       wl1251_debug(DEBUG_MAC80211, "mac80211 config ch %d psm %s power %d",
-                    channel,
-                    conf->flags & IEEE80211_CONF_PS ? "on" : "off",
-                    conf->power_level);
-
-       mutex_lock(&wl->mutex);
-
-       ret = wl1251_ps_elp_wakeup(wl);
-       if (ret < 0)
-               goto out;
-
-       if (channel != wl->channel) {
-               wl->channel = channel;
-
-               ret = wl1251_join(wl, wl->bss_type, wl->channel,
-                                 wl->beacon_int, wl->dtim_period);
-               if (ret < 0)
-                       goto out_sleep;
-       }
-
-       if (conf->flags & IEEE80211_CONF_PS && !wl->psm_requested) {
-               wl1251_debug(DEBUG_PSM, "psm enabled");
-
-               wl->psm_requested = true;
-
-               wl->dtim_period = conf->ps_dtim_period;
-
-               ret = wl1251_acx_wr_tbtt_and_dtim(wl, wl->beacon_int,
-                                                 wl->dtim_period);
-
-               /*
-                * mac80211 enables PSM only if we're already associated.
-                */
-               ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
-               if (ret < 0)
-                       goto out_sleep;
-       } else if (!(conf->flags & IEEE80211_CONF_PS) &&
-                  wl->psm_requested) {
-               wl1251_debug(DEBUG_PSM, "psm disabled");
-
-               wl->psm_requested = false;
-
-               if (wl->psm) {
-                       ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE);
-                       if (ret < 0)
-                               goto out_sleep;
-               }
-       }
-
-       if (conf->power_level != wl->power_level) {
-               ret = wl1251_acx_tx_power(wl, conf->power_level);
-               if (ret < 0)
-                       goto out_sleep;
-
-               wl->power_level = conf->power_level;
-       }
-
-out_sleep:
-       wl1251_ps_elp_sleep(wl);
-
-out:
-       mutex_unlock(&wl->mutex);
-
-       return ret;
-}
-
-#define WL1251_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \
-                                 FIF_ALLMULTI | \
-                                 FIF_FCSFAIL | \
-                                 FIF_BCN_PRBRESP_PROMISC | \
-                                 FIF_CONTROL | \
-                                 FIF_OTHER_BSS)
-
-static void wl1251_op_configure_filter(struct ieee80211_hw *hw,
-                                      unsigned int changed,
-                                      unsigned int *total,u64 multicast)
-{
-       struct wl1251 *wl = hw->priv;
-
-       wl1251_debug(DEBUG_MAC80211, "mac80211 configure filter");
-
-       *total &= WL1251_SUPPORTED_FILTERS;
-       changed &= WL1251_SUPPORTED_FILTERS;
-
-       if (changed == 0)
-               /* no filters which we support changed */
-               return;
-
-       /* FIXME: wl->rx_config and wl->rx_filter are not protected */
-
-       wl->rx_config = WL1251_DEFAULT_RX_CONFIG;
-       wl->rx_filter = WL1251_DEFAULT_RX_FILTER;
-
-       if (*total & FIF_PROMISC_IN_BSS) {
-               wl->rx_config |= CFG_BSSID_FILTER_EN;
-               wl->rx_config |= CFG_RX_ALL_GOOD;
-       }
-       if (*total & FIF_ALLMULTI)
-               /*
-                * CFG_MC_FILTER_EN in rx_config needs to be 0 to receive
-                * all multicast frames
-                */
-               wl->rx_config &= ~CFG_MC_FILTER_EN;
-       if (*total & FIF_FCSFAIL)
-               wl->rx_filter |= CFG_RX_FCS_ERROR;
-       if (*total & FIF_BCN_PRBRESP_PROMISC) {
-               wl->rx_config &= ~CFG_BSSID_FILTER_EN;
-               wl->rx_config &= ~CFG_SSID_FILTER_EN;
-       }
-       if (*total & FIF_CONTROL)
-               wl->rx_filter |= CFG_RX_CTL_EN;
-       if (*total & FIF_OTHER_BSS)
-               wl->rx_filter &= ~CFG_BSSID_FILTER_EN;
-
-       /*
-        * FIXME: workqueues need to be properly cancelled on stop(), for
-        * now let's just disable changing the filter settings. They will
-        * be updated any on config().
-        */
-       /* schedule_work(&wl->filter_work); */
-}
-
-/* HW encryption */
-static int wl1251_set_key_type(struct wl1251 *wl,
-                              struct wl1251_cmd_set_keys *key,
-                              enum set_key_cmd cmd,
-                              struct ieee80211_key_conf *mac80211_key,
-                              const u8 *addr)
-{
-       switch (mac80211_key->cipher) {
-       case WLAN_CIPHER_SUITE_WEP40:
-       case WLAN_CIPHER_SUITE_WEP104:
-               if (is_broadcast_ether_addr(addr))
-                       key->key_type = KEY_WEP_DEFAULT;
-               else
-                       key->key_type = KEY_WEP_ADDR;
-
-               mac80211_key->hw_key_idx = mac80211_key->keyidx;
-               break;
-       case WLAN_CIPHER_SUITE_TKIP:
-               if (is_broadcast_ether_addr(addr))
-                       key->key_type = KEY_TKIP_MIC_GROUP;
-               else
-                       key->key_type = KEY_TKIP_MIC_PAIRWISE;
-
-               mac80211_key->hw_key_idx = mac80211_key->keyidx;
-               break;
-       case WLAN_CIPHER_SUITE_CCMP:
-               if (is_broadcast_ether_addr(addr))
-                       key->key_type = KEY_AES_GROUP;
-               else
-                       key->key_type = KEY_AES_PAIRWISE;
-               mac80211_key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
-               break;
-       default:
-               wl1251_error("Unknown key cipher 0x%x", mac80211_key->cipher);
-               return -EOPNOTSUPP;
-       }
-
-       return 0;
-}
-
-static int wl1251_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
-                            struct ieee80211_vif *vif,
-                            struct ieee80211_sta *sta,
-                            struct ieee80211_key_conf *key)
-{
-       struct wl1251 *wl = hw->priv;
-       struct wl1251_cmd_set_keys *wl_cmd;
-       const u8 *addr;
-       int ret;
-
-       static const u8 bcast_addr[ETH_ALEN] =
-               { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-
-       wl1251_debug(DEBUG_MAC80211, "mac80211 set key");
-
-       wl_cmd = kzalloc(sizeof(*wl_cmd), GFP_KERNEL);
-       if (!wl_cmd) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       addr = sta ? sta->addr : bcast_addr;
-
-       wl1251_debug(DEBUG_CRYPT, "CMD: 0x%x", cmd);
-       wl1251_dump(DEBUG_CRYPT, "ADDR: ", addr, ETH_ALEN);
-       wl1251_debug(DEBUG_CRYPT, "Key: algo:0x%x, id:%d, len:%d flags 0x%x",
-                    key->cipher, key->keyidx, key->keylen, key->flags);
-       wl1251_dump(DEBUG_CRYPT, "KEY: ", key->key, key->keylen);
-
-       if (is_zero_ether_addr(addr)) {
-               /* We dont support TX only encryption */
-               ret = -EOPNOTSUPP;
-               goto out;
-       }
-
-       mutex_lock(&wl->mutex);
-
-       ret = wl1251_ps_elp_wakeup(wl);
-       if (ret < 0)
-               goto out_unlock;
-
-       switch (cmd) {
-       case SET_KEY:
-               wl_cmd->key_action = KEY_ADD_OR_REPLACE;
-               break;
-       case DISABLE_KEY:
-               wl_cmd->key_action = KEY_REMOVE;
-               break;
-       default:
-               wl1251_error("Unsupported key cmd 0x%x", cmd);
-               break;
-       }
-
-       ret = wl1251_set_key_type(wl, wl_cmd, cmd, key, addr);
-       if (ret < 0) {
-               wl1251_error("Set KEY type failed");
-               goto out_sleep;
-       }
-
-       if (wl_cmd->key_type != KEY_WEP_DEFAULT)
-               memcpy(wl_cmd->addr, addr, ETH_ALEN);
-
-       if ((wl_cmd->key_type == KEY_TKIP_MIC_GROUP) ||
-           (wl_cmd->key_type == KEY_TKIP_MIC_PAIRWISE)) {
-               /*
-                * We get the key in the following form:
-                * TKIP (16 bytes) - TX MIC (8 bytes) - RX MIC (8 bytes)
-                * but the target is expecting:
-                * TKIP - RX MIC - TX MIC
-                */
-               memcpy(wl_cmd->key, key->key, 16);
-               memcpy(wl_cmd->key + 16, key->key + 24, 8);
-               memcpy(wl_cmd->key + 24, key->key + 16, 8);
-
-       } else {
-               memcpy(wl_cmd->key, key->key, key->keylen);
-       }
-       wl_cmd->key_size = key->keylen;
-
-       wl_cmd->id = key->keyidx;
-       wl_cmd->ssid_profile = 0;
-
-       wl1251_dump(DEBUG_CRYPT, "TARGET KEY: ", wl_cmd, sizeof(*wl_cmd));
-
-       ret = wl1251_cmd_send(wl, CMD_SET_KEYS, wl_cmd, sizeof(*wl_cmd));
-       if (ret < 0) {
-               wl1251_warning("could not set keys");
-               goto out_sleep;
-       }
-
-out_sleep:
-       wl1251_ps_elp_sleep(wl);
-
-out_unlock:
-       mutex_unlock(&wl->mutex);
-
-out:
-       kfree(wl_cmd);
-
-       return ret;
-}
-
-static int wl1251_op_hw_scan(struct ieee80211_hw *hw,
-                            struct ieee80211_vif *vif,
-                            struct cfg80211_scan_request *req)
-{
-       struct wl1251 *wl = hw->priv;
-       struct sk_buff *skb;
-       size_t ssid_len = 0;
-       u8 *ssid = NULL;
-       int ret;
-
-       wl1251_debug(DEBUG_MAC80211, "mac80211 hw scan");
-
-       if (req->n_ssids) {
-               ssid = req->ssids[0].ssid;
-               ssid_len = req->ssids[0].ssid_len;
-       }
-
-       mutex_lock(&wl->mutex);
-
-       if (wl->scanning) {
-               wl1251_debug(DEBUG_SCAN, "scan already in progress");
-               ret = -EINVAL;
-               goto out;
-       }
-
-       ret = wl1251_ps_elp_wakeup(wl);
-       if (ret < 0)
-               goto out;
-
-       skb = ieee80211_probereq_get(wl->hw, wl->vif, ssid, ssid_len,
-                                    req->ie, req->ie_len);
-       if (!skb) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       ret = wl1251_cmd_template_set(wl, CMD_PROBE_REQ, skb->data,
-                                     skb->len);
-       dev_kfree_skb(skb);
-       if (ret < 0)
-               goto out_sleep;
-
-       ret = wl1251_cmd_trigger_scan_to(wl, 0);
-       if (ret < 0)
-               goto out_sleep;
-
-       wl->scanning = true;
-
-       ret = wl1251_cmd_scan(wl, ssid, ssid_len, req->channels,
-                             req->n_channels, WL1251_SCAN_NUM_PROBES);
-       if (ret < 0) {
-               wl->scanning = false;
-               goto out_sleep;
-       }
-
-out_sleep:
-       wl1251_ps_elp_sleep(wl);
-
-out:
-       mutex_unlock(&wl->mutex);
-
-       return ret;
-}
-
-static int wl1251_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
-{
-       struct wl1251 *wl = hw->priv;
-       int ret;
-
-       mutex_lock(&wl->mutex);
-
-       ret = wl1251_ps_elp_wakeup(wl);
-       if (ret < 0)
-               goto out;
-
-       ret = wl1251_acx_rts_threshold(wl, (u16) value);
-       if (ret < 0)
-               wl1251_warning("wl1251_op_set_rts_threshold failed: %d", ret);
-
-       wl1251_ps_elp_sleep(wl);
-
-out:
-       mutex_unlock(&wl->mutex);
-
-       return ret;
-}
-
-static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
-                                      struct ieee80211_vif *vif,
-                                      struct ieee80211_bss_conf *bss_conf,
-                                      u32 changed)
-{
-       struct wl1251 *wl = hw->priv;
-       struct sk_buff *beacon, *skb;
-       int ret;
-
-       wl1251_debug(DEBUG_MAC80211, "mac80211 bss info changed");
-
-       mutex_lock(&wl->mutex);
-
-       ret = wl1251_ps_elp_wakeup(wl);
-       if (ret < 0)
-               goto out;
-
-       if (changed & BSS_CHANGED_BSSID) {
-               memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN);
-
-               skb = ieee80211_nullfunc_get(wl->hw, wl->vif);
-               if (!skb)
-                       goto out_sleep;
-
-               ret = wl1251_cmd_template_set(wl, CMD_NULL_DATA,
-                                             skb->data, skb->len);
-               dev_kfree_skb(skb);
-               if (ret < 0)
-                       goto out_sleep;
-
-               ret = wl1251_build_qos_null_data(wl);
-               if (ret < 0)
-                       goto out;
-
-               if (wl->bss_type != BSS_TYPE_IBSS) {
-                       ret = wl1251_join(wl, wl->bss_type, wl->channel,
-                                         wl->beacon_int, wl->dtim_period);
-                       if (ret < 0)
-                               goto out_sleep;
-               }
-       }
-
-       if (changed & BSS_CHANGED_ASSOC) {
-               if (bss_conf->assoc) {
-                       wl->beacon_int = bss_conf->beacon_int;
-
-                       skb = ieee80211_pspoll_get(wl->hw, wl->vif);
-                       if (!skb)
-                               goto out_sleep;
-
-                       ret = wl1251_cmd_template_set(wl, CMD_PS_POLL,
-                                                     skb->data,
-                                                     skb->len);
-                       dev_kfree_skb(skb);
-                       if (ret < 0)
-                               goto out_sleep;
-
-                       ret = wl1251_acx_aid(wl, bss_conf->aid);
-                       if (ret < 0)
-                               goto out_sleep;
-               } else {
-                       /* use defaults when not associated */
-                       wl->beacon_int = WL1251_DEFAULT_BEACON_INT;
-                       wl->dtim_period = WL1251_DEFAULT_DTIM_PERIOD;
-               }
-       }
-       if (changed & BSS_CHANGED_ERP_SLOT) {
-               if (bss_conf->use_short_slot)
-                       ret = wl1251_acx_slot(wl, SLOT_TIME_SHORT);
-               else
-                       ret = wl1251_acx_slot(wl, SLOT_TIME_LONG);
-               if (ret < 0) {
-                       wl1251_warning("Set slot time failed %d", ret);
-                       goto out_sleep;
-               }
-       }
-
-       if (changed & BSS_CHANGED_ERP_PREAMBLE) {
-               if (bss_conf->use_short_preamble)
-                       wl1251_acx_set_preamble(wl, ACX_PREAMBLE_SHORT);
-               else
-                       wl1251_acx_set_preamble(wl, ACX_PREAMBLE_LONG);
-       }
-
-       if (changed & BSS_CHANGED_ERP_CTS_PROT) {
-               if (bss_conf->use_cts_prot)
-                       ret = wl1251_acx_cts_protect(wl, CTSPROTECT_ENABLE);
-               else
-                       ret = wl1251_acx_cts_protect(wl, CTSPROTECT_DISABLE);
-               if (ret < 0) {
-                       wl1251_warning("Set ctsprotect failed %d", ret);
-                       goto out_sleep;
-               }
-       }
-
-       if (changed & BSS_CHANGED_BEACON) {
-               beacon = ieee80211_beacon_get(hw, vif);
-               ret = wl1251_cmd_template_set(wl, CMD_BEACON, beacon->data,
-                                             beacon->len);
-
-               if (ret < 0) {
-                       dev_kfree_skb(beacon);
-                       goto out_sleep;
-               }
-
-               ret = wl1251_cmd_template_set(wl, CMD_PROBE_RESP, beacon->data,
-                                             beacon->len);
-
-               dev_kfree_skb(beacon);
-
-               if (ret < 0)
-                       goto out_sleep;
-
-               ret = wl1251_join(wl, wl->bss_type, wl->beacon_int,
-                                 wl->channel, wl->dtim_period);
-
-               if (ret < 0)
-                       goto out_sleep;
-       }
-
-out_sleep:
-       wl1251_ps_elp_sleep(wl);
-
-out:
-       mutex_unlock(&wl->mutex);
-}
-
-
-/* can't be const, mac80211 writes to this */
-static struct ieee80211_rate wl1251_rates[] = {
-       { .bitrate = 10,
-         .hw_value = 0x1,
-         .hw_value_short = 0x1, },
-       { .bitrate = 20,
-         .hw_value = 0x2,
-         .hw_value_short = 0x2,
-         .flags = IEEE80211_RATE_SHORT_PREAMBLE },
-       { .bitrate = 55,
-         .hw_value = 0x4,
-         .hw_value_short = 0x4,
-         .flags = IEEE80211_RATE_SHORT_PREAMBLE },
-       { .bitrate = 110,
-         .hw_value = 0x20,
-         .hw_value_short = 0x20,
-         .flags = IEEE80211_RATE_SHORT_PREAMBLE },
-       { .bitrate = 60,
-         .hw_value = 0x8,
-         .hw_value_short = 0x8, },
-       { .bitrate = 90,
-         .hw_value = 0x10,
-         .hw_value_short = 0x10, },
-       { .bitrate = 120,
-         .hw_value = 0x40,
-         .hw_value_short = 0x40, },
-       { .bitrate = 180,
-         .hw_value = 0x80,
-         .hw_value_short = 0x80, },
-       { .bitrate = 240,
-         .hw_value = 0x200,
-         .hw_value_short = 0x200, },
-       { .bitrate = 360,
-        .hw_value = 0x400,
-        .hw_value_short = 0x400, },
-       { .bitrate = 480,
-         .hw_value = 0x800,
-         .hw_value_short = 0x800, },
-       { .bitrate = 540,
-         .hw_value = 0x1000,
-         .hw_value_short = 0x1000, },
-};
-
-/* can't be const, mac80211 writes to this */
-static struct ieee80211_channel wl1251_channels[] = {
-       { .hw_value = 1, .center_freq = 2412},
-       { .hw_value = 2, .center_freq = 2417},
-       { .hw_value = 3, .center_freq = 2422},
-       { .hw_value = 4, .center_freq = 2427},
-       { .hw_value = 5, .center_freq = 2432},
-       { .hw_value = 6, .center_freq = 2437},
-       { .hw_value = 7, .center_freq = 2442},
-       { .hw_value = 8, .center_freq = 2447},
-       { .hw_value = 9, .center_freq = 2452},
-       { .hw_value = 10, .center_freq = 2457},
-       { .hw_value = 11, .center_freq = 2462},
-       { .hw_value = 12, .center_freq = 2467},
-       { .hw_value = 13, .center_freq = 2472},
-};
-
-static int wl1251_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
-                            const struct ieee80211_tx_queue_params *params)
-{
-       enum wl1251_acx_ps_scheme ps_scheme;
-       struct wl1251 *wl = hw->priv;
-       int ret;
-
-       mutex_lock(&wl->mutex);
-
-       wl1251_debug(DEBUG_MAC80211, "mac80211 conf tx %d", queue);
-
-       ret = wl1251_ps_elp_wakeup(wl);
-       if (ret < 0)
-               goto out;
-
-       /* mac80211 uses units of 32 usec */
-       ret = wl1251_acx_ac_cfg(wl, wl1251_tx_get_queue(queue),
-                               params->cw_min, params->cw_max,
-                               params->aifs, params->txop * 32);
-       if (ret < 0)
-               goto out_sleep;
-
-       if (params->uapsd)
-               ps_scheme = WL1251_ACX_PS_SCHEME_UPSD_TRIGGER;
-       else
-               ps_scheme = WL1251_ACX_PS_SCHEME_LEGACY;
-
-       ret = wl1251_acx_tid_cfg(wl, wl1251_tx_get_queue(queue),
-                                CHANNEL_TYPE_EDCF,
-                                wl1251_tx_get_queue(queue), ps_scheme,
-                                WL1251_ACX_ACK_POLICY_LEGACY);
-       if (ret < 0)
-               goto out_sleep;
-
-out_sleep:
-       wl1251_ps_elp_sleep(wl);
-
-out:
-       mutex_unlock(&wl->mutex);
-
-       return ret;
-}
-
-static int wl1251_op_get_survey(struct ieee80211_hw *hw, int idx,
-                               struct survey_info *survey)
-{
-       struct wl1251 *wl = hw->priv;
-       struct ieee80211_conf *conf = &hw->conf;
-       if (idx != 0)
-               return -ENOENT;
-       survey->channel = conf->channel;
-       survey->filled = SURVEY_INFO_NOISE_DBM;
-       survey->noise = wl->noise;
-       return 0;
-}
-
-/* can't be const, mac80211 writes to this */
-static struct ieee80211_supported_band wl1251_band_2ghz = {
-       .channels = wl1251_channels,
-       .n_channels = ARRAY_SIZE(wl1251_channels),
-       .bitrates = wl1251_rates,
-       .n_bitrates = ARRAY_SIZE(wl1251_rates),
-};
-
-static const struct ieee80211_ops wl1251_ops = {
-       .start = wl1251_op_start,
-       .stop = wl1251_op_stop,
-       .add_interface = wl1251_op_add_interface,
-       .remove_interface = wl1251_op_remove_interface,
-       .config = wl1251_op_config,
-       .configure_filter = wl1251_op_configure_filter,
-       .tx = wl1251_op_tx,
-       .set_key = wl1251_op_set_key,
-       .hw_scan = wl1251_op_hw_scan,
-       .bss_info_changed = wl1251_op_bss_info_changed,
-       .set_rts_threshold = wl1251_op_set_rts_threshold,
-       .conf_tx = wl1251_op_conf_tx,
-       .get_survey = wl1251_op_get_survey,
-};
-
-static int wl1251_read_eeprom_byte(struct wl1251 *wl, off_t offset, u8 *data)
-{
-       unsigned long timeout;
-
-       wl1251_reg_write32(wl, EE_ADDR, offset);
-       wl1251_reg_write32(wl, EE_CTL, EE_CTL_READ);
-
-       /* EE_CTL_READ clears when data is ready */
-       timeout = jiffies + msecs_to_jiffies(100);
-       while (1) {
-               if (!(wl1251_reg_read32(wl, EE_CTL) & EE_CTL_READ))
-                       break;
-
-               if (time_after(jiffies, timeout))
-                       return -ETIMEDOUT;
-
-               msleep(1);
-       }
-
-       *data = wl1251_reg_read32(wl, EE_DATA);
-       return 0;
-}
-
-static int wl1251_read_eeprom(struct wl1251 *wl, off_t offset,
-                             u8 *data, size_t len)
-{
-       size_t i;
-       int ret;
-
-       wl1251_reg_write32(wl, EE_START, 0);
-
-       for (i = 0; i < len; i++) {
-               ret = wl1251_read_eeprom_byte(wl, offset + i, &data[i]);
-               if (ret < 0)
-                       return ret;
-       }
-
-       return 0;
-}
-
-static int wl1251_read_eeprom_mac(struct wl1251 *wl)
-{
-       u8 mac[ETH_ALEN];
-       int i, ret;
-
-       wl1251_set_partition(wl, 0, 0, REGISTERS_BASE, REGISTERS_DOWN_SIZE);
-
-       ret = wl1251_read_eeprom(wl, 0x1c, mac, sizeof(mac));
-       if (ret < 0) {
-               wl1251_warning("failed to read MAC address from EEPROM");
-               return ret;
-       }
-
-       /* MAC is stored in reverse order */
-       for (i = 0; i < ETH_ALEN; i++)
-               wl->mac_addr[i] = mac[ETH_ALEN - i - 1];
-
-       return 0;
-}
-
-static int wl1251_register_hw(struct wl1251 *wl)
-{
-       int ret;
-
-       if (wl->mac80211_registered)
-               return 0;
-
-       SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr);
-
-       ret = ieee80211_register_hw(wl->hw);
-       if (ret < 0) {
-               wl1251_error("unable to register mac80211 hw: %d", ret);
-               return ret;
-       }
-
-       wl->mac80211_registered = true;
-
-       wl1251_notice("loaded");
-
-       return 0;
-}
-
-int wl1251_init_ieee80211(struct wl1251 *wl)
-{
-       int ret;
-
-       /* The tx descriptor buffer and the TKIP space */
-       wl->hw->extra_tx_headroom = sizeof(struct tx_double_buffer_desc)
-               + WL1251_TKIP_IV_SPACE;
-
-       /* unit us */
-       /* FIXME: find a proper value */
-       wl->hw->channel_change_time = 10000;
-
-       wl->hw->flags = IEEE80211_HW_SIGNAL_DBM |
-               IEEE80211_HW_SUPPORTS_PS |
-               IEEE80211_HW_BEACON_FILTER |
-               IEEE80211_HW_SUPPORTS_UAPSD;
-
-       wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
-       wl->hw->wiphy->max_scan_ssids = 1;
-       wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl1251_band_2ghz;
-
-       wl->hw->queues = 4;
-
-       if (wl->use_eeprom)
-               wl1251_read_eeprom_mac(wl);
-
-       ret = wl1251_register_hw(wl);
-       if (ret)
-               goto out;
-
-       wl1251_debugfs_init(wl);
-       wl1251_notice("initialized");
-
-       ret = 0;
-
-out:
-       return ret;
-}
-EXPORT_SYMBOL_GPL(wl1251_init_ieee80211);
-
-struct ieee80211_hw *wl1251_alloc_hw(void)
-{
-       struct ieee80211_hw *hw;
-       struct wl1251 *wl;
-       int i;
-       static const u8 nokia_oui[3] = {0x00, 0x1f, 0xdf};
-
-       hw = ieee80211_alloc_hw(sizeof(*wl), &wl1251_ops);
-       if (!hw) {
-               wl1251_error("could not alloc ieee80211_hw");
-               return ERR_PTR(-ENOMEM);
-       }
-
-       wl = hw->priv;
-       memset(wl, 0, sizeof(*wl));
-
-       wl->hw = hw;
-
-       wl->data_in_count = 0;
-
-       skb_queue_head_init(&wl->tx_queue);
-
-       INIT_WORK(&wl->filter_work, wl1251_filter_work);
-       INIT_DELAYED_WORK(&wl->elp_work, wl1251_elp_work);
-       wl->channel = WL1251_DEFAULT_CHANNEL;
-       wl->scanning = false;
-       wl->default_key = 0;
-       wl->listen_int = 1;
-       wl->rx_counter = 0;
-       wl->rx_handled = 0;
-       wl->rx_current_buffer = 0;
-       wl->rx_last_id = 0;
-       wl->rx_config = WL1251_DEFAULT_RX_CONFIG;
-       wl->rx_filter = WL1251_DEFAULT_RX_FILTER;
-       wl->elp = false;
-       wl->psm = 0;
-       wl->psm_requested = false;
-       wl->tx_queue_stopped = false;
-       wl->power_level = WL1251_DEFAULT_POWER_LEVEL;
-       wl->beacon_int = WL1251_DEFAULT_BEACON_INT;
-       wl->dtim_period = WL1251_DEFAULT_DTIM_PERIOD;
-       wl->vif = NULL;
-
-       for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++)
-               wl->tx_frames[i] = NULL;
-
-       wl->next_tx_complete = 0;
-
-       INIT_WORK(&wl->irq_work, wl1251_irq_work);
-       INIT_WORK(&wl->tx_work, wl1251_tx_work);
-
-       /*
-        * In case our MAC address is not correctly set,
-        * we use a random but Nokia MAC.
-        */
-       memcpy(wl->mac_addr, nokia_oui, 3);
-       get_random_bytes(wl->mac_addr + 3, 3);
-
-       wl->state = WL1251_STATE_OFF;
-       mutex_init(&wl->mutex);
-
-       wl->tx_mgmt_frm_rate = DEFAULT_HW_GEN_TX_RATE;
-       wl->tx_mgmt_frm_mod = DEFAULT_HW_GEN_MODULATION_TYPE;
-
-       wl->rx_descriptor = kmalloc(sizeof(*wl->rx_descriptor), GFP_KERNEL);
-       if (!wl->rx_descriptor) {
-               wl1251_error("could not allocate memory for rx descriptor");
-               ieee80211_free_hw(hw);
-               return ERR_PTR(-ENOMEM);
-       }
-
-       return hw;
-}
-EXPORT_SYMBOL_GPL(wl1251_alloc_hw);
-
-int wl1251_free_hw(struct wl1251 *wl)
-{
-       ieee80211_unregister_hw(wl->hw);
-
-       wl1251_debugfs_exit(wl);
-
-       kfree(wl->target_mem_map);
-       kfree(wl->data_path);
-       vfree(wl->fw);
-       wl->fw = NULL;
-       kfree(wl->nvs);
-       wl->nvs = NULL;
-
-       kfree(wl->rx_descriptor);
-       wl->rx_descriptor = NULL;
-
-       ieee80211_free_hw(wl->hw);
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(wl1251_free_hw);
-
-MODULE_DESCRIPTION("TI wl1251 Wireles LAN Driver Core");
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Kalle Valo <kvalo@adurom.com>");
-MODULE_FIRMWARE(WL1251_FW_NAME);
diff --git a/drivers/net/wireless/wl12xx/wl1251_ps.c b/drivers/net/wireless/wl12xx/wl1251_ps.c
deleted file mode 100644 (file)
index 0b997bd..0000000
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * This file is part of wl1251
- *
- * Copyright (C) 2008 Nokia Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include "wl1251_reg.h"
-#include "wl1251_ps.h"
-#include "wl1251_cmd.h"
-#include "wl1251_io.h"
-
-/* in ms */
-#define WL1251_WAKEUP_TIMEOUT 100
-
-void wl1251_elp_work(struct work_struct *work)
-{
-       struct delayed_work *dwork;
-       struct wl1251 *wl;
-
-       dwork = container_of(work, struct delayed_work, work);
-       wl = container_of(dwork, struct wl1251, elp_work);
-
-       wl1251_debug(DEBUG_PSM, "elp work");
-
-       mutex_lock(&wl->mutex);
-
-       if (wl->elp || !wl->psm)
-               goto out;
-
-       wl1251_debug(DEBUG_PSM, "chip to elp");
-       wl1251_write_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP);
-       wl->elp = true;
-
-out:
-       mutex_unlock(&wl->mutex);
-}
-
-#define ELP_ENTRY_DELAY  5
-
-/* Routines to toggle sleep mode while in ELP */
-void wl1251_ps_elp_sleep(struct wl1251 *wl)
-{
-       unsigned long delay;
-
-       if (wl->psm) {
-               cancel_delayed_work(&wl->elp_work);
-               delay = msecs_to_jiffies(ELP_ENTRY_DELAY);
-               ieee80211_queue_delayed_work(wl->hw, &wl->elp_work, delay);
-       }
-}
-
-int wl1251_ps_elp_wakeup(struct wl1251 *wl)
-{
-       unsigned long timeout, start;
-       u32 elp_reg;
-
-       if (!wl->elp)
-               return 0;
-
-       wl1251_debug(DEBUG_PSM, "waking up chip from elp");
-
-       start = jiffies;
-       timeout = jiffies + msecs_to_jiffies(WL1251_WAKEUP_TIMEOUT);
-
-       wl1251_write_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_WAKE_UP);
-
-       elp_reg = wl1251_read_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR);
-
-       /*
-        * FIXME: we should wait for irq from chip but, as a temporary
-        * solution to simplify locking, let's poll instead
-        */
-       while (!(elp_reg & ELPCTRL_WLAN_READY)) {
-               if (time_after(jiffies, timeout)) {
-                       wl1251_error("elp wakeup timeout");
-                       return -ETIMEDOUT;
-               }
-               msleep(1);
-               elp_reg = wl1251_read_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR);
-       }
-
-       wl1251_debug(DEBUG_PSM, "wakeup time: %u ms",
-                    jiffies_to_msecs(jiffies - start));
-
-       wl->elp = false;
-
-       return 0;
-}
-
-static int wl1251_ps_set_elp(struct wl1251 *wl, bool enable)
-{
-       int ret;
-
-       if (enable) {
-               wl1251_debug(DEBUG_PSM, "sleep auth psm/elp");
-
-               ret = wl1251_acx_sleep_auth(wl, WL1251_PSM_ELP);
-               if (ret < 0)
-                       return ret;
-
-               wl1251_ps_elp_sleep(wl);
-       } else {
-               wl1251_debug(DEBUG_PSM, "sleep auth cam");
-
-               /*
-                * When the target is in ELP, we can only
-                * access the ELP control register. Thus,
-                * we have to wake the target up before
-                * changing the power authorization.
-                */
-
-               wl1251_ps_elp_wakeup(wl);
-
-               ret = wl1251_acx_sleep_auth(wl, WL1251_PSM_CAM);
-               if (ret < 0)
-                       return ret;
-       }
-
-       return 0;
-}
-
-int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode)
-{
-       int ret;
-
-       switch (mode) {
-       case STATION_POWER_SAVE_MODE:
-               wl1251_debug(DEBUG_PSM, "entering psm");
-
-               /* enable beacon filtering */
-               ret = wl1251_acx_beacon_filter_opt(wl, true);
-               if (ret < 0)
-                       return ret;
-
-               ret = wl1251_acx_wake_up_conditions(wl,
-                                                   WAKE_UP_EVENT_DTIM_BITMAP,
-                                                   wl->listen_int);
-               if (ret < 0)
-                       return ret;
-
-               ret = wl1251_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE);
-               if (ret < 0)
-                       return ret;
-
-               ret = wl1251_ps_set_elp(wl, true);
-               if (ret < 0)
-                       return ret;
-
-               wl->psm = 1;
-               break;
-       case STATION_ACTIVE_MODE:
-       default:
-               wl1251_debug(DEBUG_PSM, "leaving psm");
-               ret = wl1251_ps_set_elp(wl, false);
-               if (ret < 0)
-                       return ret;
-
-               /* disable beacon filtering */
-               ret = wl1251_acx_beacon_filter_opt(wl, false);
-               if (ret < 0)
-                       return ret;
-
-               ret = wl1251_acx_wake_up_conditions(wl,
-                                                   WAKE_UP_EVENT_DTIM_BITMAP,
-                                                   wl->listen_int);
-               if (ret < 0)
-                       return ret;
-
-               ret = wl1251_cmd_ps_mode(wl, STATION_ACTIVE_MODE);
-               if (ret < 0)
-                       return ret;
-
-               wl->psm = 0;
-               break;
-       }
-
-       return ret;
-}
-
diff --git a/drivers/net/wireless/wl12xx/wl1251_ps.h b/drivers/net/wireless/wl12xx/wl1251_ps.h
deleted file mode 100644 (file)
index e5db81f..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * This file is part of wl1251
- *
- * Copyright (c) 1998-2007 Texas Instruments Incorporated
- * Copyright (C) 2008 Nokia Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __WL1251_PS_H__
-#define __WL1251_PS_H__
-
-#include "wl1251.h"
-#include "wl1251_acx.h"
-
-int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode);
-void wl1251_ps_elp_sleep(struct wl1251 *wl);
-int wl1251_ps_elp_wakeup(struct wl1251 *wl);
-void wl1251_elp_work(struct work_struct *work);
-
-
-#endif /* __WL1251_PS_H__ */
diff --git a/drivers/net/wireless/wl12xx/wl1251_reg.h b/drivers/net/wireless/wl12xx/wl1251_reg.h
deleted file mode 100644 (file)
index a580901..0000000
+++ /dev/null
@@ -1,655 +0,0 @@
-/*
- * This file is part of wl12xx
- *
- * Copyright (c) 1998-2007 Texas Instruments Incorporated
- * Copyright (C) 2008 Nokia Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __REG_H__
-#define __REG_H__
-
-#include <linux/bitops.h>
-
-#define REGISTERS_BASE 0x00300000
-#define DRPW_BASE      0x00310000
-
-#define REGISTERS_DOWN_SIZE 0x00008800
-#define REGISTERS_WORK_SIZE 0x0000b000
-
-#define HW_ACCESS_ELP_CTRL_REG_ADDR         0x1FFFC
-
-/* ELP register commands */
-#define ELPCTRL_WAKE_UP             0x1
-#define ELPCTRL_WAKE_UP_WLAN_READY  0x5
-#define ELPCTRL_SLEEP               0x0
-/* ELP WLAN_READY bit */
-#define ELPCTRL_WLAN_READY          0x2
-
-/* Device Configuration registers*/
-#define SOR_CFG                        (REGISTERS_BASE + 0x0800)
-#define ECPU_CTRL                      (REGISTERS_BASE + 0x0804)
-#define HI_CFG                         (REGISTERS_BASE + 0x0808)
-
-/* EEPROM registers */
-#define EE_START                       (REGISTERS_BASE + 0x080C)
-#define EE_CTL                         (REGISTERS_BASE + 0x2000)
-#define EE_DATA                        (REGISTERS_BASE + 0x2004)
-#define EE_ADDR                        (REGISTERS_BASE + 0x2008)
-
-#define EE_CTL_READ                   2
-
-#define CHIP_ID_B                      (REGISTERS_BASE + 0x5674)
-
-#define CHIP_ID_1251_PG10                 (0x7010101)
-#define CHIP_ID_1251_PG11                 (0x7020101)
-#define CHIP_ID_1251_PG12                 (0x7030101)
-
-#define ENABLE                         (REGISTERS_BASE + 0x5450)
-
-/* Power Management registers */
-#define ELP_CFG_MODE                   (REGISTERS_BASE + 0x5804)
-#define ELP_CMD                        (REGISTERS_BASE + 0x5808)
-#define PLL_CAL_TIME                   (REGISTERS_BASE + 0x5810)
-#define CLK_REQ_TIME                   (REGISTERS_BASE + 0x5814)
-#define CLK_BUF_TIME                   (REGISTERS_BASE + 0x5818)
-
-#define CFG_PLL_SYNC_CNT               (REGISTERS_BASE + 0x5820)
-
-/* Scratch Pad registers*/
-#define SCR_PAD0                       (REGISTERS_BASE + 0x5608)
-#define SCR_PAD1                       (REGISTERS_BASE + 0x560C)
-#define SCR_PAD2                       (REGISTERS_BASE + 0x5610)
-#define SCR_PAD3                       (REGISTERS_BASE + 0x5614)
-#define SCR_PAD4                       (REGISTERS_BASE + 0x5618)
-#define SCR_PAD4_SET                   (REGISTERS_BASE + 0x561C)
-#define SCR_PAD4_CLR                   (REGISTERS_BASE + 0x5620)
-#define SCR_PAD5                       (REGISTERS_BASE + 0x5624)
-#define SCR_PAD5_SET                   (REGISTERS_BASE + 0x5628)
-#define SCR_PAD5_CLR                   (REGISTERS_BASE + 0x562C)
-#define SCR_PAD6                       (REGISTERS_BASE + 0x5630)
-#define SCR_PAD7                       (REGISTERS_BASE + 0x5634)
-#define SCR_PAD8                       (REGISTERS_BASE + 0x5638)
-#define SCR_PAD9                       (REGISTERS_BASE + 0x563C)
-
-/* Spare registers*/
-#define SPARE_A1                       (REGISTERS_BASE + 0x0994)
-#define SPARE_A2                       (REGISTERS_BASE + 0x0998)
-#define SPARE_A3                       (REGISTERS_BASE + 0x099C)
-#define SPARE_A4                       (REGISTERS_BASE + 0x09A0)
-#define SPARE_A5                       (REGISTERS_BASE + 0x09A4)
-#define SPARE_A6                       (REGISTERS_BASE + 0x09A8)
-#define SPARE_A7                       (REGISTERS_BASE + 0x09AC)
-#define SPARE_A8                       (REGISTERS_BASE + 0x09B0)
-#define SPARE_B1                       (REGISTERS_BASE + 0x5420)
-#define SPARE_B2                       (REGISTERS_BASE + 0x5424)
-#define SPARE_B3                       (REGISTERS_BASE + 0x5428)
-#define SPARE_B4                       (REGISTERS_BASE + 0x542C)
-#define SPARE_B5                       (REGISTERS_BASE + 0x5430)
-#define SPARE_B6                       (REGISTERS_BASE + 0x5434)
-#define SPARE_B7                       (REGISTERS_BASE + 0x5438)
-#define SPARE_B8                       (REGISTERS_BASE + 0x543C)
-
-enum wl12xx_acx_int_reg {
-       ACX_REG_INTERRUPT_TRIG,
-       ACX_REG_INTERRUPT_TRIG_H,
-
-/*=============================================
-  Host Interrupt Mask Register - 32bit (RW)
-  ------------------------------------------
-  Setting a bit in this register masks the
-  corresponding interrupt to the host.
-  0 - RX0              - Rx first dubble buffer Data Interrupt
-  1 - TXD              - Tx Data Interrupt
-  2 - TXXFR            - Tx Transfer Interrupt
-  3 - RX1              - Rx second dubble buffer Data Interrupt
-  4 - RXXFR            - Rx Transfer Interrupt
-  5 - EVENT_A  - Event Mailbox interrupt
-  6 - EVENT_B  - Event Mailbox interrupt
-  7 - WNONHST  - Wake On Host Interrupt
-  8 - TRACE_A  - Debug Trace interrupt
-  9 - TRACE_B  - Debug Trace interrupt
- 10 - CDCMP            - Command Complete Interrupt
- 11 -
- 12 -
- 13 -
- 14 - ICOMP            - Initialization Complete Interrupt
- 16 - SG SE            - Soft Gemini - Sense enable interrupt
- 17 - SG SD            - Soft Gemini - Sense disable interrupt
- 18 -                  -
- 19 -                  -
- 20 -                  -
- 21-                   -
- Default: 0x0001
-*==============================================*/
-       ACX_REG_INTERRUPT_MASK,
-
-/*=============================================
-  Host Interrupt Mask Set 16bit, (Write only)
-  ------------------------------------------
- Setting a bit in this register sets
- the corresponding bin in ACX_HINT_MASK register
- without effecting the mask
- state of other bits (0 = no effect).
-==============================================*/
-       ACX_REG_HINT_MASK_SET,
-
-/*=============================================
-  Host Interrupt Mask Clear 16bit,(Write only)
-  ------------------------------------------
- Setting a bit in this register clears
- the corresponding bin in ACX_HINT_MASK register
- without effecting the mask
- state of other bits (0 = no effect).
-=============================================*/
-       ACX_REG_HINT_MASK_CLR,
-
-/*=============================================
-  Host Interrupt Status Nondestructive Read
-  16bit,(Read only)
-  ------------------------------------------
- The host can read this register to determine
- which interrupts are active.
- Reading this register doesn't
- effect its content.
-=============================================*/
-       ACX_REG_INTERRUPT_NO_CLEAR,
-
-/*=============================================
-  Host Interrupt Status Clear on Read  Register
-  16bit,(Read only)
-  ------------------------------------------
- The host can read this register to determine
- which interrupts are active.
- Reading this register clears it,
- thus making all interrupts inactive.
-==============================================*/
-       ACX_REG_INTERRUPT_CLEAR,
-
-/*=============================================
-  Host Interrupt Acknowledge Register
-  16bit,(Write only)
-  ------------------------------------------
- The host can set individual bits in this
- register to clear (acknowledge) the corresp.
- interrupt status bits in the HINT_STS_CLR and
- HINT_STS_ND registers, thus making the
- assotiated interrupt inactive. (0-no effect)
-==============================================*/
-       ACX_REG_INTERRUPT_ACK,
-
-/*===============================================
-   Host Software Reset - 32bit RW
- ------------------------------------------
-    [31:1] Reserved
-    0  SOFT_RESET Soft Reset  - When this bit is set,
-    it holds the Wlan hardware in a soft reset state.
-    This reset disables all MAC and baseband processor
-    clocks except the CardBus/PCI interface clock.
-    It also initializes all MAC state machines except
-    the host interface. It does not reload the
-    contents of the EEPROM. When this bit is cleared
-    (not self-clearing), the Wlan hardware
-    exits the software reset state.
-===============================================*/
-       ACX_REG_SLV_SOFT_RESET,
-
-/*===============================================
- EEPROM Burst Read Start  - 32bit RW
- ------------------------------------------
- [31:1] Reserved
- 0  ACX_EE_START -  EEPROM Burst Read Start 0
- Setting this bit starts a burst read from
- the external EEPROM.
- If this bit is set (after reset) before an EEPROM read/write,
- the burst read starts at EEPROM address 0.
- Otherwise, it starts at the address
- following the address of the previous access.
- TheWlan hardware hardware clears this bit automatically.
-
- Default: 0x00000000
-*================================================*/
-       ACX_REG_EE_START,
-
-/* Embedded ARM CPU Control */
-
-/*===============================================
- Halt eCPU   - 32bit RW
- ------------------------------------------
- 0 HALT_ECPU Halt Embedded CPU - This bit is the
- compliment of bit 1 (MDATA2) in the SOR_CFG register.
- During a hardware reset, this bit holds
- the inverse of MDATA2.
- When downloading firmware from the host,
- set this bit (pull down MDATA2).
- The host clears this bit after downloading the firmware into
- zero-wait-state SSRAM.
- When loading firmware from Flash, clear this bit (pull up MDATA2)
- so that the eCPU can run the bootloader code in Flash
- HALT_ECPU eCPU State
- --------------------
- 1 halt eCPU
- 0 enable eCPU
- ===============================================*/
-       ACX_REG_ECPU_CONTROL,
-
-       ACX_REG_TABLE_LEN
-};
-
-#define ACX_SLV_SOFT_RESET_BIT   BIT(0)
-#define ACX_REG_EEPROM_START_BIT BIT(0)
-
-/* Command/Information Mailbox Pointers */
-
-/*===============================================
-  Command Mailbox Pointer - 32bit RW
- ------------------------------------------
- This register holds the start address of
- the command mailbox located in the Wlan hardware memory.
- The host must read this pointer after a reset to
- find the location of the command mailbox.
- The Wlan hardware initializes the command mailbox
- pointer with the default address of the command mailbox.
- The command mailbox pointer is not valid until after
- the host receives the Init Complete interrupt from
- the Wlan hardware.
- ===============================================*/
-#define REG_COMMAND_MAILBOX_PTR                                (SCR_PAD0)
-
-/*===============================================
-  Information Mailbox Pointer - 32bit RW
- ------------------------------------------
- This register holds the start address of
- the information mailbox located in the Wlan hardware memory.
- The host must read this pointer after a reset to find
- the location of the information mailbox.
- The Wlan hardware initializes the information mailbox pointer
- with the default address of the information mailbox.
- The information mailbox pointer is not valid
- until after the host receives the Init Complete interrupt from
- the Wlan hardware.
- ===============================================*/
-#define REG_EVENT_MAILBOX_PTR                          (SCR_PAD1)
-
-
-/* Misc */
-
-#define REG_ENABLE_TX_RX                               (ENABLE)
-/*
- * Rx configuration (filter) information element
- * ---------------------------------------------
- */
-#define REG_RX_CONFIG                          (RX_CFG)
-#define REG_RX_FILTER                          (RX_FILTER_CFG)
-
-
-#define RX_CFG_ENABLE_PHY_HEADER_PLCP   0x0002
-
-/* promiscuous - receives all valid frames */
-#define RX_CFG_PROMISCUOUS              0x0008
-
-/* receives frames from any BSSID */
-#define RX_CFG_BSSID                    0x0020
-
-/* receives frames destined to any MAC address */
-#define RX_CFG_MAC                      0x0010
-
-#define RX_CFG_ENABLE_ONLY_MY_DEST_MAC  0x0010
-#define RX_CFG_ENABLE_ANY_DEST_MAC      0x0000
-#define RX_CFG_ENABLE_ONLY_MY_BSSID     0x0020
-#define RX_CFG_ENABLE_ANY_BSSID                 0x0000
-
-/* discards all broadcast frames */
-#define RX_CFG_DISABLE_BCAST            0x0200
-
-#define RX_CFG_ENABLE_ONLY_MY_SSID      0x0400
-#define RX_CFG_ENABLE_RX_CMPLT_FCS_ERROR 0x0800
-#define RX_CFG_COPY_RX_STATUS           0x2000
-#define RX_CFG_TSF                      0x10000
-
-#define RX_CONFIG_OPTION_ANY_DST_MY_BSS         (RX_CFG_ENABLE_ANY_DEST_MAC | \
-                                         RX_CFG_ENABLE_ONLY_MY_BSSID)
-
-#define RX_CONFIG_OPTION_MY_DST_ANY_BSS         (RX_CFG_ENABLE_ONLY_MY_DEST_MAC\
-                                         | RX_CFG_ENABLE_ANY_BSSID)
-
-#define RX_CONFIG_OPTION_ANY_DST_ANY_BSS (RX_CFG_ENABLE_ANY_DEST_MAC | \
-                                         RX_CFG_ENABLE_ANY_BSSID)
-
-#define RX_CONFIG_OPTION_MY_DST_MY_BSS  (RX_CFG_ENABLE_ONLY_MY_DEST_MAC\
-                                         | RX_CFG_ENABLE_ONLY_MY_BSSID)
-
-#define RX_CONFIG_OPTION_FOR_SCAN  (RX_CFG_ENABLE_PHY_HEADER_PLCP \
-                                   | RX_CFG_ENABLE_RX_CMPLT_FCS_ERROR \
-                                   | RX_CFG_COPY_RX_STATUS | RX_CFG_TSF)
-
-#define RX_CONFIG_OPTION_FOR_MEASUREMENT (RX_CFG_ENABLE_ANY_DEST_MAC)
-
-#define RX_CONFIG_OPTION_FOR_JOIN       (RX_CFG_ENABLE_ONLY_MY_BSSID | \
-                                         RX_CFG_ENABLE_ONLY_MY_DEST_MAC)
-
-#define RX_CONFIG_OPTION_FOR_IBSS_JOIN   (RX_CFG_ENABLE_ONLY_MY_SSID | \
-                                         RX_CFG_ENABLE_ONLY_MY_DEST_MAC)
-
-#define RX_FILTER_OPTION_DEF         (CFG_RX_MGMT_EN | CFG_RX_DATA_EN\
-                                      | CFG_RX_CTL_EN | CFG_RX_BCN_EN\
-                                      | CFG_RX_AUTH_EN | CFG_RX_ASSOC_EN)
-
-#define RX_FILTER_OPTION_FILTER_ALL     0
-
-#define RX_FILTER_OPTION_DEF_PRSP_BCN  (CFG_RX_PRSP_EN | CFG_RX_MGMT_EN\
-                                       | CFG_RX_RCTS_ACK | CFG_RX_BCN_EN)
-
-#define RX_FILTER_OPTION_JOIN       (CFG_RX_MGMT_EN | CFG_RX_DATA_EN\
-                                     | CFG_RX_BCN_EN | CFG_RX_AUTH_EN\
-                                     | CFG_RX_ASSOC_EN | CFG_RX_RCTS_ACK\
-                                     | CFG_RX_PRSP_EN)
-
-
-/*===============================================
- EEPROM Read/Write Request 32bit RW
- ------------------------------------------
- 1 EE_READ - EEPROM Read Request 1 - Setting this bit
- loads a single byte of data into the EE_DATA
- register from the EEPROM location specified in
- the EE_ADDR register.
- The Wlan hardware hardware clears this bit automatically.
- EE_DATA is valid when this bit is cleared.
-
- 0 EE_WRITE  - EEPROM Write Request  - Setting this bit
- writes a single byte of data from the EE_DATA register into the
- EEPROM location specified in the EE_ADDR register.
- The Wlan hardware hardware clears this bit automatically.
-*===============================================*/
-#define EE_CTL                              (REGISTERS_BASE + 0x2000)
-#define ACX_EE_CTL_REG                      EE_CTL
-#define EE_WRITE                            0x00000001ul
-#define EE_READ                             0x00000002ul
-
-/*===============================================
-  EEPROM Address  - 32bit RW
-  ------------------------------------------
-  This register specifies the address
-  within the EEPROM from/to which to read/write data.
-  ===============================================*/
-#define EE_ADDR                             (REGISTERS_BASE + 0x2008)
-#define ACX_EE_ADDR_REG                     EE_ADDR
-
-/*===============================================
-  EEPROM Data  - 32bit RW
-  ------------------------------------------
-  This register either holds the read 8 bits of
-  data from the EEPROM or the write data
-  to be written to the EEPROM.
-  ===============================================*/
-#define EE_DATA                             (REGISTERS_BASE + 0x2004)
-#define ACX_EE_DATA_REG                     EE_DATA
-
-#define EEPROM_ACCESS_TO                    10000   /* timeout counter */
-#define START_EEPROM_MGR                    0x00000001
-
-/*===============================================
-  EEPROM Base Address  - 32bit RW
-  ------------------------------------------
-  This register holds the upper nine bits
-  [23:15] of the 24-bit Wlan hardware memory
-  address for burst reads from EEPROM accesses.
-  The EEPROM provides the lower 15 bits of this address.
-  The MSB of the address from the EEPROM is ignored.
-  ===============================================*/
-#define ACX_EE_CFG                          EE_CFG
-
-/*===============================================
-  GPIO Output Values  -32bit, RW
-  ------------------------------------------
-  [31:16]  Reserved
-  [15: 0]  Specify the output values (at the output driver inputs) for
-  GPIO[15:0], respectively.
-  ===============================================*/
-#define ACX_GPIO_OUT_REG            GPIO_OUT
-#define ACX_MAX_GPIO_LINES          15
-
-/*===============================================
-  Contention window  -32bit, RW
-  ------------------------------------------
-  [31:26]  Reserved
-  [25:16]  Max (0x3ff)
-  [15:07]  Reserved
-  [06:00]  Current contention window value - default is 0x1F
-  ===============================================*/
-#define ACX_CONT_WIND_CFG_REG    CONT_WIND_CFG
-#define ACX_CONT_WIND_MIN_MASK   0x0000007f
-#define ACX_CONT_WIND_MAX        0x03ff0000
-
-/*===============================================
-  HI_CFG Interface Configuration Register Values
-  ------------------------------------------
-  ===============================================*/
-#define HI_CFG_UART_ENABLE          0x00000004
-#define HI_CFG_RST232_ENABLE        0x00000008
-#define HI_CFG_CLOCK_REQ_SELECT     0x00000010
-#define HI_CFG_HOST_INT_ENABLE      0x00000020
-#define HI_CFG_VLYNQ_OUTPUT_ENABLE  0x00000040
-#define HI_CFG_HOST_INT_ACTIVE_LOW  0x00000080
-#define HI_CFG_UART_TX_OUT_GPIO_15  0x00000100
-#define HI_CFG_UART_TX_OUT_GPIO_14  0x00000200
-#define HI_CFG_UART_TX_OUT_GPIO_7   0x00000400
-
-/*
- * NOTE: USE_ACTIVE_HIGH compilation flag should be defined in makefile
- *       for platforms using active high interrupt level
- */
-#ifdef USE_ACTIVE_HIGH
-#define HI_CFG_DEF_VAL              \
-       (HI_CFG_UART_ENABLE |        \
-       HI_CFG_RST232_ENABLE |      \
-       HI_CFG_CLOCK_REQ_SELECT |   \
-       HI_CFG_HOST_INT_ENABLE)
-#else
-#define HI_CFG_DEF_VAL              \
-       (HI_CFG_UART_ENABLE |        \
-       HI_CFG_RST232_ENABLE |      \
-       HI_CFG_CLOCK_REQ_SELECT |   \
-       HI_CFG_HOST_INT_ENABLE)
-
-#endif
-
-#define REF_FREQ_19_2                       0
-#define REF_FREQ_26_0                       1
-#define REF_FREQ_38_4                       2
-#define REF_FREQ_40_0                       3
-#define REF_FREQ_33_6                       4
-#define REF_FREQ_NUM                        5
-
-#define LUT_PARAM_INTEGER_DIVIDER           0
-#define LUT_PARAM_FRACTIONAL_DIVIDER        1
-#define LUT_PARAM_ATTN_BB                   2
-#define LUT_PARAM_ALPHA_BB                  3
-#define LUT_PARAM_STOP_TIME_BB              4
-#define LUT_PARAM_BB_PLL_LOOP_FILTER        5
-#define LUT_PARAM_NUM                       6
-
-#define ACX_EEPROMLESS_IND_REG              (SCR_PAD4)
-#define USE_EEPROM                          0
-#define SOFT_RESET_MAX_TIME                 1000000
-#define SOFT_RESET_STALL_TIME               1000
-#define NVS_DATA_BUNDARY_ALIGNMENT          4
-
-
-/* Firmware image load chunk size */
-#define CHUNK_SIZE          512
-
-/* Firmware image header size */
-#define FW_HDR_SIZE 8
-
-#define ECPU_CONTROL_HALT                                      0x00000101
-
-
-/******************************************************************************
-
-    CHANNELS, BAND & REG DOMAINS definitions
-
-******************************************************************************/
-
-
-enum {
-       RADIO_BAND_2_4GHZ = 0,  /* 2.4 Ghz band */
-       RADIO_BAND_5GHZ = 1,    /* 5 Ghz band */
-       RADIO_BAND_JAPAN_4_9_GHZ = 2,
-       DEFAULT_BAND = RADIO_BAND_2_4GHZ,
-       INVALID_BAND = 0xFE,
-       MAX_RADIO_BANDS = 0xFF
-};
-
-enum {
-       NO_RATE      = 0,
-       RATE_1MBPS   = 0x0A,
-       RATE_2MBPS   = 0x14,
-       RATE_5_5MBPS = 0x37,
-       RATE_6MBPS   = 0x0B,
-       RATE_9MBPS   = 0x0F,
-       RATE_11MBPS  = 0x6E,
-       RATE_12MBPS  = 0x0A,
-       RATE_18MBPS  = 0x0E,
-       RATE_22MBPS  = 0xDC,
-       RATE_24MBPS  = 0x09,
-       RATE_36MBPS  = 0x0D,
-       RATE_48MBPS  = 0x08,
-       RATE_54MBPS  = 0x0C
-};
-
-enum {
-       RATE_INDEX_1MBPS   =  0,
-       RATE_INDEX_2MBPS   =  1,
-       RATE_INDEX_5_5MBPS =  2,
-       RATE_INDEX_6MBPS   =  3,
-       RATE_INDEX_9MBPS   =  4,
-       RATE_INDEX_11MBPS  =  5,
-       RATE_INDEX_12MBPS  =  6,
-       RATE_INDEX_18MBPS  =  7,
-       RATE_INDEX_22MBPS  =  8,
-       RATE_INDEX_24MBPS  =  9,
-       RATE_INDEX_36MBPS  =  10,
-       RATE_INDEX_48MBPS  =  11,
-       RATE_INDEX_54MBPS  =  12,
-       RATE_INDEX_MAX     =  RATE_INDEX_54MBPS,
-       MAX_RATE_INDEX,
-       INVALID_RATE_INDEX = MAX_RATE_INDEX,
-       RATE_INDEX_ENUM_MAX_SIZE = 0x7FFFFFFF
-};
-
-enum {
-       RATE_MASK_1MBPS = 0x1,
-       RATE_MASK_2MBPS = 0x2,
-       RATE_MASK_5_5MBPS = 0x4,
-       RATE_MASK_11MBPS = 0x20,
-};
-
-#define SHORT_PREAMBLE_BIT   BIT(0) /* CCK or Barker depending on the rate */
-#define OFDM_RATE_BIT        BIT(6)
-#define PBCC_RATE_BIT        BIT(7)
-
-enum {
-       CCK_LONG = 0,
-       CCK_SHORT = SHORT_PREAMBLE_BIT,
-       PBCC_LONG = PBCC_RATE_BIT,
-       PBCC_SHORT = PBCC_RATE_BIT | SHORT_PREAMBLE_BIT,
-       OFDM = OFDM_RATE_BIT
-};
-
-/******************************************************************************
-
-Transmit-Descriptor RATE-SET field definitions...
-
-Define a new "Rate-Set" for TX path that incorporates the
-Rate & Modulation info into a single 16-bit field.
-
-TxdRateSet_t:
-b15   - Indicates Preamble type (1=SHORT, 0=LONG).
-       Notes:
-       Must be LONG (0) for 1Mbps rate.
-       Does not apply (set to 0) for RevG-OFDM rates.
-b14   - Indicates PBCC encoding (1=PBCC, 0=not).
-       Notes:
-       Does not apply (set to 0) for rates 1 and 2 Mbps.
-       Does not apply (set to 0) for RevG-OFDM rates.
-b13    - Unused (set to 0).
-b12-b0 - Supported Rate indicator bits as defined below.
-
-******************************************************************************/
-
-
-/*************************************************************************
-
-    Interrupt Trigger Register (Host -> WiLink)
-
-**************************************************************************/
-
-/* Hardware to Embedded CPU Interrupts - first 32-bit register set */
-
-/*
- * Host Command Interrupt. Setting this bit masks
- * the interrupt that the host issues to inform
- * the FW that it has sent a command
- * to the Wlan hardware Command Mailbox.
- */
-#define INTR_TRIG_CMD       BIT(0)
-
-/*
- * Host Event Acknowlegde Interrupt. The host
- * sets this bit to acknowledge that it received
- * the unsolicited information from the event
- * mailbox.
- */
-#define INTR_TRIG_EVENT_ACK BIT(1)
-
-/*
- * The host sets this bit to inform the Wlan
- * FW that a TX packet is in the XFER
- * Buffer #0.
- */
-#define INTR_TRIG_TX_PROC0 BIT(2)
-
-/*
- * The host sets this bit to inform the FW
- * that it read a packet from RX XFER
- * Buffer #0.
- */
-#define INTR_TRIG_RX_PROC0 BIT(3)
-
-#define INTR_TRIG_DEBUG_ACK BIT(4)
-
-#define INTR_TRIG_STATE_CHANGED BIT(5)
-
-
-/* Hardware to Embedded CPU Interrupts - second 32-bit register set */
-
-/*
- * The host sets this bit to inform the FW
- * that it read a packet from RX XFER
- * Buffer #1.
- */
-#define INTR_TRIG_RX_PROC1 BIT(17)
-
-/*
- * The host sets this bit to inform the Wlan
- * hardware that a TX packet is in the XFER
- * Buffer #1.
- */
-#define INTR_TRIG_TX_PROC1 BIT(18)
-
-#endif
diff --git a/drivers/net/wireless/wl12xx/wl1251_rx.c b/drivers/net/wireless/wl12xx/wl1251_rx.c
deleted file mode 100644 (file)
index 2576459..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * This file is part of wl1251
- *
- * Copyright (c) 1998-2007 Texas Instruments Incorporated
- * Copyright (C) 2008 Nokia Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/skbuff.h>
-#include <linux/gfp.h>
-#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"
-
-static void wl1251_rx_header(struct wl1251 *wl,
-                            struct wl1251_rx_descriptor *desc)
-{
-       u32 rx_packet_ring_addr;
-
-       rx_packet_ring_addr = wl->data_path->rx_packet_ring_addr;
-       if (wl->rx_current_buffer)
-               rx_packet_ring_addr += wl->data_path->rx_packet_ring_chunk_size;
-
-       wl1251_mem_read(wl, rx_packet_ring_addr, desc, sizeof(*desc));
-}
-
-static void wl1251_rx_status(struct wl1251 *wl,
-                            struct wl1251_rx_descriptor *desc,
-                            struct ieee80211_rx_status *status,
-                            u8 beacon)
-{
-       u64 mactime;
-       int ret;
-
-       memset(status, 0, sizeof(struct ieee80211_rx_status));
-
-       status->band = IEEE80211_BAND_2GHZ;
-       status->mactime = desc->timestamp;
-
-       /*
-        * The rx status timestamp is a 32 bits value while the TSF is a
-        * 64 bits one.
-        * For IBSS merging, TSF is mandatory, so we have to get it
-        * somehow, so we ask for ACX_TSF_INFO.
-        * That could be moved to the get_tsf() hook, but unfortunately,
-        * this one must be atomic, while our SPI routines can sleep.
-        */
-       if ((wl->bss_type == BSS_TYPE_IBSS) && beacon) {
-               ret = wl1251_acx_tsf_info(wl, &mactime);
-               if (ret == 0)
-                       status->mactime = mactime;
-       }
-
-       status->signal = desc->rssi;
-
-       /*
-        * FIXME: guessing that snr needs to be divided by two, otherwise
-        * the values don't make any sense
-        */
-       wl->noise = desc->rssi - desc->snr / 2;
-
-       status->freq = ieee80211_channel_to_frequency(desc->channel);
-
-       status->flag |= RX_FLAG_TSFT;
-
-       if (desc->flags & RX_DESC_ENCRYPTION_MASK) {
-               status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED;
-
-               if (likely(!(desc->flags & RX_DESC_DECRYPT_FAIL)))
-                       status->flag |= RX_FLAG_DECRYPTED;
-
-               if (unlikely(desc->flags & RX_DESC_MIC_FAIL))
-                       status->flag |= RX_FLAG_MMIC_ERROR;
-       }
-
-       if (unlikely(!(desc->flags & RX_DESC_VALID_FCS)))
-               status->flag |= RX_FLAG_FAILED_FCS_CRC;
-
-
-       /* FIXME: set status->rate_idx */
-}
-
-static void wl1251_rx_body(struct wl1251 *wl,
-                          struct wl1251_rx_descriptor *desc)
-{
-       struct sk_buff *skb;
-       struct ieee80211_rx_status status;
-       u8 *rx_buffer, beacon = 0;
-       u16 length, *fc;
-       u32 curr_id, last_id_inc, rx_packet_ring_addr;
-
-       length = WL1251_RX_ALIGN(desc->length  - PLCP_HEADER_LENGTH);
-       curr_id = (desc->flags & RX_DESC_SEQNUM_MASK) >> RX_DESC_PACKETID_SHIFT;
-       last_id_inc = (wl->rx_last_id + 1) % (RX_MAX_PACKET_ID + 1);
-
-       if (last_id_inc != curr_id) {
-               wl1251_warning("curr ID:%d, last ID inc:%d",
-                              curr_id, last_id_inc);
-               wl->rx_last_id = curr_id;
-       } else {
-               wl->rx_last_id = last_id_inc;
-       }
-
-       rx_packet_ring_addr = wl->data_path->rx_packet_ring_addr +
-               sizeof(struct wl1251_rx_descriptor) + 20;
-       if (wl->rx_current_buffer)
-               rx_packet_ring_addr += wl->data_path->rx_packet_ring_chunk_size;
-
-       skb = __dev_alloc_skb(length, GFP_KERNEL);
-       if (!skb) {
-               wl1251_error("Couldn't allocate RX frame");
-               return;
-       }
-
-       rx_buffer = skb_put(skb, length);
-       wl1251_mem_read(wl, rx_packet_ring_addr, rx_buffer, length);
-
-       /* The actual lenght doesn't include the target's alignment */
-       skb->len = desc->length  - PLCP_HEADER_LENGTH;
-
-       fc = (u16 *)skb->data;
-
-       if ((*fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON)
-               beacon = 1;
-
-       wl1251_rx_status(wl, desc, &status, beacon);
-
-       wl1251_debug(DEBUG_RX, "rx skb 0x%p: %d B %s", skb, skb->len,
-                    beacon ? "beacon" : "");
-
-       memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
-       ieee80211_rx_ni(wl->hw, skb);
-}
-
-static void wl1251_rx_ack(struct wl1251 *wl)
-{
-       u32 data, addr;
-
-       if (wl->rx_current_buffer) {
-               addr = ACX_REG_INTERRUPT_TRIG_H;
-               data = INTR_TRIG_RX_PROC1;
-       } else {
-               addr = ACX_REG_INTERRUPT_TRIG;
-               data = INTR_TRIG_RX_PROC0;
-       }
-
-       wl1251_reg_write32(wl, addr, data);
-
-       /* Toggle buffer ring */
-       wl->rx_current_buffer = !wl->rx_current_buffer;
-}
-
-
-void wl1251_rx(struct wl1251 *wl)
-{
-       struct wl1251_rx_descriptor *rx_desc;
-
-       if (wl->state != WL1251_STATE_ON)
-               return;
-
-       rx_desc = wl->rx_descriptor;
-
-       /* We first read the frame's header */
-       wl1251_rx_header(wl, rx_desc);
-
-       /* Now we can read the body */
-       wl1251_rx_body(wl, rx_desc);
-
-       /* Finally, we need to ACK the RX */
-       wl1251_rx_ack(wl);
-}
diff --git a/drivers/net/wireless/wl12xx/wl1251_rx.h b/drivers/net/wireless/wl12xx/wl1251_rx.h
deleted file mode 100644 (file)
index 4448f63..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * This file is part of wl1251
- *
- * Copyright (c) 1998-2007 Texas Instruments Incorporated
- * Copyright (C) 2008 Nokia Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __WL1251_RX_H__
-#define __WL1251_RX_H__
-
-#include <linux/bitops.h>
-
-#include "wl1251.h"
-
-/*
- * RX PATH
- *
- * The Rx path uses a double buffer and an rx_contro structure, each located
- * at a fixed address in the device memory. The host keeps track of which
- * buffer is available and alternates between them on a per packet basis.
- * The size of each of the two buffers is large enough to hold the longest
- * 802.3 packet.
- * The RX path goes like that:
- * 1) The target generates an interrupt each time a new packet is received.
- *   There are 2 RX interrupts, one for each buffer.
- * 2) The host reads the received packet from one of the double buffers.
- * 3) The host triggers a target interrupt.
- * 4) The target prepares the next RX packet.
- */
-
-#define WL1251_RX_MAX_RSSI -30
-#define WL1251_RX_MIN_RSSI -95
-
-#define WL1251_RX_ALIGN_TO 4
-#define WL1251_RX_ALIGN(len) (((len) + WL1251_RX_ALIGN_TO - 1) & \
-                            ~(WL1251_RX_ALIGN_TO - 1))
-
-#define SHORT_PREAMBLE_BIT   BIT(0)
-#define OFDM_RATE_BIT        BIT(6)
-#define PBCC_RATE_BIT        BIT(7)
-
-#define PLCP_HEADER_LENGTH 8
-#define RX_DESC_PACKETID_SHIFT 11
-#define RX_MAX_PACKET_ID 3
-
-#define RX_DESC_VALID_FCS         0x0001
-#define RX_DESC_MATCH_RXADDR1     0x0002
-#define RX_DESC_MCAST             0x0004
-#define RX_DESC_STAINTIM          0x0008
-#define RX_DESC_VIRTUAL_BM        0x0010
-#define RX_DESC_BCAST             0x0020
-#define RX_DESC_MATCH_SSID        0x0040
-#define RX_DESC_MATCH_BSSID       0x0080
-#define RX_DESC_ENCRYPTION_MASK   0x0300
-#define RX_DESC_MEASURMENT        0x0400
-#define RX_DESC_SEQNUM_MASK       0x1800
-#define        RX_DESC_MIC_FAIL          0x2000
-#define        RX_DESC_DECRYPT_FAIL      0x4000
-
-struct wl1251_rx_descriptor {
-       u32 timestamp; /* In microseconds */
-       u16 length; /* Paylod length, including headers */
-       u16 flags;
-
-       /*
-        * 0 - 802.11
-        * 1 - 802.3
-        * 2 - IP
-        * 3 - Raw Codec
-        */
-       u8 type;
-
-       /*
-        * Received Rate:
-        * 0x0A - 1MBPS
-        * 0x14 - 2MBPS
-        * 0x37 - 5_5MBPS
-        * 0x0B - 6MBPS
-        * 0x0F - 9MBPS
-        * 0x6E - 11MBPS
-        * 0x0A - 12MBPS
-        * 0x0E - 18MBPS
-        * 0xDC - 22MBPS
-        * 0x09 - 24MBPS
-        * 0x0D - 36MBPS
-        * 0x08 - 48MBPS
-        * 0x0C - 54MBPS
-        */
-       u8 rate;
-
-       u8 mod_pre; /* Modulation and preamble */
-       u8 channel;
-
-       /*
-        * 0 - 2.4 Ghz
-        * 1 - 5 Ghz
-        */
-       u8 band;
-
-       s8 rssi; /* in dB */
-       u8 rcpi; /* in dB */
-       u8 snr; /* in dB */
-} __packed;
-
-void wl1251_rx(struct wl1251 *wl);
-
-#endif
diff --git a/drivers/net/wireless/wl12xx/wl1251_sdio.c b/drivers/net/wireless/wl12xx/wl1251_sdio.c
deleted file mode 100644 (file)
index 74ba9ce..0000000
+++ /dev/null
@@ -1,342 +0,0 @@
-/*
- * wl12xx SDIO routines
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- * Copyright (C) 2005 Texas Instruments Incorporated
- * Copyright (C) 2008 Google Inc
- * Copyright (C) 2009 Bob Copeland (me@bobcopeland.com)
- */
-#include <linux/module.h>
-#include <linux/mod_devicetable.h>
-#include <linux/mmc/sdio_func.h>
-#include <linux/mmc/sdio_ids.h>
-#include <linux/platform_device.h>
-#include <linux/wl12xx.h>
-#include <linux/irq.h>
-
-#include "wl1251.h"
-
-#ifndef SDIO_VENDOR_ID_TI
-#define SDIO_VENDOR_ID_TI              0x104c
-#endif
-
-#ifndef SDIO_DEVICE_ID_TI_WL1251
-#define SDIO_DEVICE_ID_TI_WL1251       0x9066
-#endif
-
-struct wl1251_sdio {
-       struct sdio_func *func;
-       u32 elp_val;
-};
-
-static struct wl12xx_platform_data *wl12xx_board_data;
-
-static struct sdio_func *wl_to_func(struct wl1251 *wl)
-{
-       struct wl1251_sdio *wl_sdio = wl->if_priv;
-       return wl_sdio->func;
-}
-
-static void wl1251_sdio_interrupt(struct sdio_func *func)
-{
-       struct wl1251 *wl = sdio_get_drvdata(func);
-
-       wl1251_debug(DEBUG_IRQ, "IRQ");
-
-       /* FIXME should be synchronous for sdio */
-       ieee80211_queue_work(wl->hw, &wl->irq_work);
-}
-
-static const struct sdio_device_id wl1251_devices[] = {
-       { SDIO_DEVICE(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1251) },
-       {}
-};
-MODULE_DEVICE_TABLE(sdio, wl1251_devices);
-
-
-static void wl1251_sdio_read(struct wl1251 *wl, int addr,
-                            void *buf, size_t len)
-{
-       int ret;
-       struct sdio_func *func = wl_to_func(wl);
-
-       sdio_claim_host(func);
-       ret = sdio_memcpy_fromio(func, buf, addr, len);
-       if (ret)
-               wl1251_error("sdio read failed (%d)", ret);
-       sdio_release_host(func);
-}
-
-static void wl1251_sdio_write(struct wl1251 *wl, int addr,
-                             void *buf, size_t len)
-{
-       int ret;
-       struct sdio_func *func = wl_to_func(wl);
-
-       sdio_claim_host(func);
-       ret = sdio_memcpy_toio(func, addr, buf, len);
-       if (ret)
-               wl1251_error("sdio write failed (%d)", ret);
-       sdio_release_host(func);
-}
-
-static void wl1251_sdio_read_elp(struct wl1251 *wl, int addr, u32 *val)
-{
-       int ret = 0;
-       struct wl1251_sdio *wl_sdio = wl->if_priv;
-       struct sdio_func *func = wl_sdio->func;
-
-       /*
-        * The hardware only supports RAW (read after write) access for
-        * reading, regular sdio_readb won't work here (it interprets
-        * the unused bits of CMD52 as write data even if we send read
-        * request).
-        */
-       sdio_claim_host(func);
-       *val = sdio_writeb_readb(func, wl_sdio->elp_val, addr, &ret);
-       sdio_release_host(func);
-
-       if (ret)
-               wl1251_error("sdio_readb failed (%d)", ret);
-}
-
-static void wl1251_sdio_write_elp(struct wl1251 *wl, int addr, u32 val)
-{
-       int ret = 0;
-       struct wl1251_sdio *wl_sdio = wl->if_priv;
-       struct sdio_func *func = wl_sdio->func;
-
-       sdio_claim_host(func);
-       sdio_writeb(func, val, addr, &ret);
-       sdio_release_host(func);
-
-       if (ret)
-               wl1251_error("sdio_writeb failed (%d)", ret);
-       else
-               wl_sdio->elp_val = val;
-}
-
-static void wl1251_sdio_reset(struct wl1251 *wl)
-{
-}
-
-static void wl1251_sdio_enable_irq(struct wl1251 *wl)
-{
-       struct sdio_func *func = wl_to_func(wl);
-
-       sdio_claim_host(func);
-       sdio_claim_irq(func, wl1251_sdio_interrupt);
-       sdio_release_host(func);
-}
-
-static void wl1251_sdio_disable_irq(struct wl1251 *wl)
-{
-       struct sdio_func *func = wl_to_func(wl);
-
-       sdio_claim_host(func);
-       sdio_release_irq(func);
-       sdio_release_host(func);
-}
-
-/* Interrupts when using dedicated WLAN_IRQ pin */
-static irqreturn_t wl1251_line_irq(int irq, void *cookie)
-{
-       struct wl1251 *wl = cookie;
-
-       ieee80211_queue_work(wl->hw, &wl->irq_work);
-
-       return IRQ_HANDLED;
-}
-
-static void wl1251_enable_line_irq(struct wl1251 *wl)
-{
-       return enable_irq(wl->irq);
-}
-
-static void wl1251_disable_line_irq(struct wl1251 *wl)
-{
-       return disable_irq(wl->irq);
-}
-
-static void wl1251_sdio_set_power(bool enable)
-{
-}
-
-static struct wl1251_if_operations wl1251_sdio_ops = {
-       .read = wl1251_sdio_read,
-       .write = wl1251_sdio_write,
-       .write_elp = wl1251_sdio_write_elp,
-       .read_elp = wl1251_sdio_read_elp,
-       .reset = wl1251_sdio_reset,
-};
-
-static int wl1251_platform_probe(struct platform_device *pdev)
-{
-       if (pdev->id != -1) {
-               wl1251_error("can only handle single device");
-               return -ENODEV;
-       }
-
-       wl12xx_board_data = pdev->dev.platform_data;
-       return 0;
-}
-
-/*
- * Dummy platform_driver for passing platform_data to this driver,
- * until we have a way to pass this through SDIO subsystem or
- * some other way.
- */
-static struct platform_driver wl1251_platform_driver = {
-       .driver = {
-               .name   = "wl1251_data",
-               .owner  = THIS_MODULE,
-       },
-       .probe  = wl1251_platform_probe,
-};
-
-static int wl1251_sdio_probe(struct sdio_func *func,
-                            const struct sdio_device_id *id)
-{
-       int ret;
-       struct wl1251 *wl;
-       struct ieee80211_hw *hw;
-       struct wl1251_sdio *wl_sdio;
-
-       hw = wl1251_alloc_hw();
-       if (IS_ERR(hw))
-               return PTR_ERR(hw);
-
-       wl = hw->priv;
-
-       wl_sdio = kzalloc(sizeof(*wl_sdio), GFP_KERNEL);
-       if (wl_sdio == NULL) {
-               ret = -ENOMEM;
-               goto out_free_hw;
-       }
-
-       sdio_claim_host(func);
-       ret = sdio_enable_func(func);
-       if (ret)
-               goto release;
-
-       sdio_set_block_size(func, 512);
-       sdio_release_host(func);
-
-       SET_IEEE80211_DEV(hw, &func->dev);
-       wl_sdio->func = func;
-       wl->if_priv = wl_sdio;
-       wl->if_ops = &wl1251_sdio_ops;
-       wl->set_power = wl1251_sdio_set_power;
-
-       if (wl12xx_board_data != NULL) {
-               wl->set_power = wl12xx_board_data->set_power;
-               wl->irq = wl12xx_board_data->irq;
-               wl->use_eeprom = wl12xx_board_data->use_eeprom;
-       }
-
-       if (wl->irq) {
-               ret = request_irq(wl->irq, wl1251_line_irq, 0, "wl1251", wl);
-               if (ret < 0) {
-                       wl1251_error("request_irq() failed: %d", ret);
-                       goto disable;
-               }
-
-               set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
-               disable_irq(wl->irq);
-
-               wl1251_sdio_ops.enable_irq = wl1251_enable_line_irq;
-               wl1251_sdio_ops.disable_irq = wl1251_disable_line_irq;
-
-               wl1251_info("using dedicated interrupt line");
-       } else {
-               wl1251_sdio_ops.enable_irq = wl1251_sdio_enable_irq;
-               wl1251_sdio_ops.disable_irq = wl1251_sdio_disable_irq;
-
-               wl1251_info("using SDIO interrupt");
-       }
-
-       ret = wl1251_init_ieee80211(wl);
-       if (ret)
-               goto out_free_irq;
-
-       sdio_set_drvdata(func, wl);
-       return ret;
-
-out_free_irq:
-       if (wl->irq)
-               free_irq(wl->irq, wl);
-disable:
-       sdio_claim_host(func);
-       sdio_disable_func(func);
-release:
-       sdio_release_host(func);
-       kfree(wl_sdio);
-out_free_hw:
-       wl1251_free_hw(wl);
-       return ret;
-}
-
-static void __devexit wl1251_sdio_remove(struct sdio_func *func)
-{
-       struct wl1251 *wl = sdio_get_drvdata(func);
-       struct wl1251_sdio *wl_sdio = wl->if_priv;
-
-       if (wl->irq)
-               free_irq(wl->irq, wl);
-       kfree(wl_sdio);
-       wl1251_free_hw(wl);
-
-       sdio_claim_host(func);
-       sdio_release_irq(func);
-       sdio_disable_func(func);
-       sdio_release_host(func);
-}
-
-static struct sdio_driver wl1251_sdio_driver = {
-       .name           = "wl1251_sdio",
-       .id_table       = wl1251_devices,
-       .probe          = wl1251_sdio_probe,
-       .remove         = __devexit_p(wl1251_sdio_remove),
-};
-
-static int __init wl1251_sdio_init(void)
-{
-       int err;
-
-       err = platform_driver_register(&wl1251_platform_driver);
-       if (err) {
-               wl1251_error("failed to register platform driver: %d", err);
-               return err;
-       }
-
-       err = sdio_register_driver(&wl1251_sdio_driver);
-       if (err)
-               wl1251_error("failed to register sdio driver: %d", err);
-       return err;
-}
-
-static void __exit wl1251_sdio_exit(void)
-{
-       sdio_unregister_driver(&wl1251_sdio_driver);
-       platform_driver_unregister(&wl1251_platform_driver);
-       wl1251_notice("unloaded");
-}
-
-module_init(wl1251_sdio_init);
-module_exit(wl1251_sdio_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Kalle Valo <kvalo@adurom.com>");
diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.c b/drivers/net/wireless/wl12xx/wl1251_spi.c
deleted file mode 100644 (file)
index 320de79..0000000
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * This file is part of wl1251
- *
- * Copyright (C) 2008 Nokia Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/irq.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/crc7.h>
-#include <linux/spi/spi.h>
-#include <linux/wl12xx.h>
-
-#include "wl1251.h"
-#include "wl1251_reg.h"
-#include "wl1251_spi.h"
-
-static irqreturn_t wl1251_irq(int irq, void *cookie)
-{
-       struct wl1251 *wl;
-
-       wl1251_debug(DEBUG_IRQ, "IRQ");
-
-       wl = cookie;
-
-       ieee80211_queue_work(wl->hw, &wl->irq_work);
-
-       return IRQ_HANDLED;
-}
-
-static struct spi_device *wl_to_spi(struct wl1251 *wl)
-{
-       return wl->if_priv;
-}
-
-static void wl1251_spi_reset(struct wl1251 *wl)
-{
-       u8 *cmd;
-       struct spi_transfer t;
-       struct spi_message m;
-
-       cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL);
-       if (!cmd) {
-               wl1251_error("could not allocate cmd for spi reset");
-               return;
-       }
-
-       memset(&t, 0, sizeof(t));
-       spi_message_init(&m);
-
-       memset(cmd, 0xff, WSPI_INIT_CMD_LEN);
-
-       t.tx_buf = cmd;
-       t.len = WSPI_INIT_CMD_LEN;
-       spi_message_add_tail(&t, &m);
-
-       spi_sync(wl_to_spi(wl), &m);
-
-       wl1251_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN);
-}
-
-static void wl1251_spi_wake(struct wl1251 *wl)
-{
-       u8 crc[WSPI_INIT_CMD_CRC_LEN], *cmd;
-       struct spi_transfer t;
-       struct spi_message m;
-
-       cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL);
-       if (!cmd) {
-               wl1251_error("could not allocate cmd for spi init");
-               return;
-       }
-
-       memset(crc, 0, sizeof(crc));
-       memset(&t, 0, sizeof(t));
-       spi_message_init(&m);
-
-       /*
-        * Set WSPI_INIT_COMMAND
-        * the data is being send from the MSB to LSB
-        */
-       cmd[2] = 0xff;
-       cmd[3] = 0xff;
-       cmd[1] = WSPI_INIT_CMD_START | WSPI_INIT_CMD_TX;
-       cmd[0] = 0;
-       cmd[7] = 0;
-       cmd[6] |= HW_ACCESS_WSPI_INIT_CMD_MASK << 3;
-       cmd[6] |= HW_ACCESS_WSPI_FIXED_BUSY_LEN & WSPI_INIT_CMD_FIXEDBUSY_LEN;
-
-       if (HW_ACCESS_WSPI_FIXED_BUSY_LEN == 0)
-               cmd[5] |=  WSPI_INIT_CMD_DIS_FIXEDBUSY;
-       else
-               cmd[5] |= WSPI_INIT_CMD_EN_FIXEDBUSY;
-
-       cmd[5] |= WSPI_INIT_CMD_IOD | WSPI_INIT_CMD_IP | WSPI_INIT_CMD_CS
-               | WSPI_INIT_CMD_WSPI | WSPI_INIT_CMD_WS;
-
-       crc[0] = cmd[1];
-       crc[1] = cmd[0];
-       crc[2] = cmd[7];
-       crc[3] = cmd[6];
-       crc[4] = cmd[5];
-
-       cmd[4] |= crc7(0, crc, WSPI_INIT_CMD_CRC_LEN) << 1;
-       cmd[4] |= WSPI_INIT_CMD_END;
-
-       t.tx_buf = cmd;
-       t.len = WSPI_INIT_CMD_LEN;
-       spi_message_add_tail(&t, &m);
-
-       spi_sync(wl_to_spi(wl), &m);
-
-       wl1251_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN);
-}
-
-static void wl1251_spi_reset_wake(struct wl1251 *wl)
-{
-       wl1251_spi_reset(wl);
-       wl1251_spi_wake(wl);
-}
-
-static void wl1251_spi_read(struct wl1251 *wl, int addr, void *buf,
-                           size_t len)
-{
-       struct spi_transfer t[3];
-       struct spi_message m;
-       u8 *busy_buf;
-       u32 *cmd;
-
-       cmd = &wl->buffer_cmd;
-       busy_buf = wl->buffer_busyword;
-
-       *cmd = 0;
-       *cmd |= WSPI_CMD_READ;
-       *cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
-       *cmd |= addr & WSPI_CMD_BYTE_ADDR;
-
-       spi_message_init(&m);
-       memset(t, 0, sizeof(t));
-
-       t[0].tx_buf = cmd;
-       t[0].len = 4;
-       spi_message_add_tail(&t[0], &m);
-
-       /* Busy and non busy words read */
-       t[1].rx_buf = busy_buf;
-       t[1].len = WL1251_BUSY_WORD_LEN;
-       spi_message_add_tail(&t[1], &m);
-
-       t[2].rx_buf = buf;
-       t[2].len = len;
-       spi_message_add_tail(&t[2], &m);
-
-       spi_sync(wl_to_spi(wl), &m);
-
-       /* FIXME: check busy words */
-
-       wl1251_dump(DEBUG_SPI, "spi_read cmd -> ", cmd, sizeof(*cmd));
-       wl1251_dump(DEBUG_SPI, "spi_read buf <- ", buf, len);
-}
-
-static void wl1251_spi_write(struct wl1251 *wl, int addr, void *buf,
-                            size_t len)
-{
-       struct spi_transfer t[2];
-       struct spi_message m;
-       u32 *cmd;
-
-       cmd = &wl->buffer_cmd;
-
-       *cmd = 0;
-       *cmd |= WSPI_CMD_WRITE;
-       *cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
-       *cmd |= addr & WSPI_CMD_BYTE_ADDR;
-
-       spi_message_init(&m);
-       memset(t, 0, sizeof(t));
-
-       t[0].tx_buf = cmd;
-       t[0].len = sizeof(*cmd);
-       spi_message_add_tail(&t[0], &m);
-
-       t[1].tx_buf = buf;
-       t[1].len = len;
-       spi_message_add_tail(&t[1], &m);
-
-       spi_sync(wl_to_spi(wl), &m);
-
-       wl1251_dump(DEBUG_SPI, "spi_write cmd -> ", cmd, sizeof(*cmd));
-       wl1251_dump(DEBUG_SPI, "spi_write buf -> ", buf, len);
-}
-
-static void wl1251_spi_enable_irq(struct wl1251 *wl)
-{
-       return enable_irq(wl->irq);
-}
-
-static void wl1251_spi_disable_irq(struct wl1251 *wl)
-{
-       return disable_irq(wl->irq);
-}
-
-static const struct wl1251_if_operations wl1251_spi_ops = {
-       .read = wl1251_spi_read,
-       .write = wl1251_spi_write,
-       .reset = wl1251_spi_reset_wake,
-       .enable_irq = wl1251_spi_enable_irq,
-       .disable_irq = wl1251_spi_disable_irq,
-};
-
-static int __devinit wl1251_spi_probe(struct spi_device *spi)
-{
-       struct wl12xx_platform_data *pdata;
-       struct ieee80211_hw *hw;
-       struct wl1251 *wl;
-       int ret;
-
-       pdata = spi->dev.platform_data;
-       if (!pdata) {
-               wl1251_error("no platform data");
-               return -ENODEV;
-       }
-
-       hw = wl1251_alloc_hw();
-       if (IS_ERR(hw))
-               return PTR_ERR(hw);
-
-       wl = hw->priv;
-
-       SET_IEEE80211_DEV(hw, &spi->dev);
-       dev_set_drvdata(&spi->dev, wl);
-       wl->if_priv = spi;
-       wl->if_ops = &wl1251_spi_ops;
-
-       /* This is the only SPI value that we need to set here, the rest
-        * comes from the board-peripherals file */
-       spi->bits_per_word = 32;
-
-       ret = spi_setup(spi);
-       if (ret < 0) {
-               wl1251_error("spi_setup failed");
-               goto out_free;
-       }
-
-       wl->set_power = pdata->set_power;
-       if (!wl->set_power) {
-               wl1251_error("set power function missing in platform data");
-               return -ENODEV;
-       }
-
-       wl->irq = spi->irq;
-       if (wl->irq < 0) {
-               wl1251_error("irq missing in platform data");
-               return -ENODEV;
-       }
-
-       wl->use_eeprom = pdata->use_eeprom;
-
-       ret = request_irq(wl->irq, wl1251_irq, 0, DRIVER_NAME, wl);
-       if (ret < 0) {
-               wl1251_error("request_irq() failed: %d", ret);
-               goto out_free;
-       }
-
-       set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
-
-       disable_irq(wl->irq);
-
-       ret = wl1251_init_ieee80211(wl);
-       if (ret)
-               goto out_irq;
-
-       return 0;
-
- out_irq:
-       free_irq(wl->irq, wl);
-
- out_free:
-       ieee80211_free_hw(hw);
-
-       return ret;
-}
-
-static int __devexit wl1251_spi_remove(struct spi_device *spi)
-{
-       struct wl1251 *wl = dev_get_drvdata(&spi->dev);
-
-       free_irq(wl->irq, wl);
-       wl1251_free_hw(wl);
-
-       return 0;
-}
-
-static struct spi_driver wl1251_spi_driver = {
-       .driver = {
-               .name           = DRIVER_NAME,
-               .bus            = &spi_bus_type,
-               .owner          = THIS_MODULE,
-       },
-
-       .probe          = wl1251_spi_probe,
-       .remove         = __devexit_p(wl1251_spi_remove),
-};
-
-static int __init wl1251_spi_init(void)
-{
-       int ret;
-
-       ret = spi_register_driver(&wl1251_spi_driver);
-       if (ret < 0) {
-               wl1251_error("failed to register spi driver: %d", ret);
-               goto out;
-       }
-
-out:
-       return ret;
-}
-
-static void __exit wl1251_spi_exit(void)
-{
-       spi_unregister_driver(&wl1251_spi_driver);
-
-       wl1251_notice("unloaded");
-}
-
-module_init(wl1251_spi_init);
-module_exit(wl1251_spi_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Kalle Valo <kvalo@adurom.com>");
-MODULE_ALIAS("spi:wl1251");
diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.h b/drivers/net/wireless/wl12xx/wl1251_spi.h
deleted file mode 100644 (file)
index 7dcf3cf..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * This file is part of wl1251
- *
- * Copyright (c) 1998-2007 Texas Instruments Incorporated
- * Copyright (C) 2008 Nokia Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __WL1251_SPI_H__
-#define __WL1251_SPI_H__
-
-#include "wl1251_cmd.h"
-#include "wl1251_acx.h"
-#include "wl1251_reg.h"
-
-#define WSPI_CMD_READ                 0x40000000
-#define WSPI_CMD_WRITE                0x00000000
-#define WSPI_CMD_FIXED                0x20000000
-#define WSPI_CMD_BYTE_LENGTH          0x1FFE0000
-#define WSPI_CMD_BYTE_LENGTH_OFFSET   17
-#define WSPI_CMD_BYTE_ADDR            0x0001FFFF
-
-#define WSPI_INIT_CMD_CRC_LEN       5
-
-#define WSPI_INIT_CMD_START         0x00
-#define WSPI_INIT_CMD_TX            0x40
-/* the extra bypass bit is sampled by the TNET as '1' */
-#define WSPI_INIT_CMD_BYPASS_BIT    0x80
-#define WSPI_INIT_CMD_FIXEDBUSY_LEN 0x07
-#define WSPI_INIT_CMD_EN_FIXEDBUSY  0x80
-#define WSPI_INIT_CMD_DIS_FIXEDBUSY 0x00
-#define WSPI_INIT_CMD_IOD           0x40
-#define WSPI_INIT_CMD_IP            0x20
-#define WSPI_INIT_CMD_CS            0x10
-#define WSPI_INIT_CMD_WS            0x08
-#define WSPI_INIT_CMD_WSPI          0x01
-#define WSPI_INIT_CMD_END           0x01
-
-#define WSPI_INIT_CMD_LEN           8
-
-#define HW_ACCESS_WSPI_FIXED_BUSY_LEN \
-               ((WL1251_BUSY_WORD_LEN - 4) / sizeof(u32))
-#define HW_ACCESS_WSPI_INIT_CMD_MASK  0
-
-#endif /* __WL1251_SPI_H__ */
diff --git a/drivers/net/wireless/wl12xx/wl1251_tx.c b/drivers/net/wireless/wl12xx/wl1251_tx.c
deleted file mode 100644 (file)
index 388492a..0000000
+++ /dev/null
@@ -1,570 +0,0 @@
-/*
- * This file is part of wl1251
- *
- * Copyright (c) 1998-2007 Texas Instruments Incorporated
- * Copyright (C) 2008 Nokia Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-#include "wl1251.h"
-#include "wl1251_reg.h"
-#include "wl1251_tx.h"
-#include "wl1251_ps.h"
-#include "wl1251_io.h"
-
-static bool wl1251_tx_double_buffer_busy(struct wl1251 *wl, u32 data_out_count)
-{
-       int used, data_in_count;
-
-       data_in_count = wl->data_in_count;
-
-       if (data_in_count < data_out_count)
-               /* data_in_count has wrapped */
-               data_in_count += TX_STATUS_DATA_OUT_COUNT_MASK + 1;
-
-       used = data_in_count - data_out_count;
-
-       WARN_ON(used < 0);
-       WARN_ON(used > DP_TX_PACKET_RING_CHUNK_NUM);
-
-       if (used >= DP_TX_PACKET_RING_CHUNK_NUM)
-               return true;
-       else
-               return false;
-}
-
-static int wl1251_tx_path_status(struct wl1251 *wl)
-{
-       u32 status, addr, data_out_count;
-       bool busy;
-
-       addr = wl->data_path->tx_control_addr;
-       status = wl1251_mem_read32(wl, addr);
-       data_out_count = status & TX_STATUS_DATA_OUT_COUNT_MASK;
-       busy = wl1251_tx_double_buffer_busy(wl, data_out_count);
-
-       if (busy)
-               return -EBUSY;
-
-       return 0;
-}
-
-static int wl1251_tx_id(struct wl1251 *wl, struct sk_buff *skb)
-{
-       int i;
-
-       for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++)
-               if (wl->tx_frames[i] == NULL) {
-                       wl->tx_frames[i] = skb;
-                       return i;
-               }
-
-       return -EBUSY;
-}
-
-static void wl1251_tx_control(struct tx_double_buffer_desc *tx_hdr,
-                             struct ieee80211_tx_info *control, u16 fc)
-{
-       *(u16 *)&tx_hdr->control = 0;
-
-       tx_hdr->control.rate_policy = 0;
-
-       /* 802.11 packets */
-       tx_hdr->control.packet_type = 0;
-
-       if (control->flags & IEEE80211_TX_CTL_NO_ACK)
-               tx_hdr->control.ack_policy = 1;
-
-       tx_hdr->control.tx_complete = 1;
-
-       if ((fc & IEEE80211_FTYPE_DATA) &&
-           ((fc & IEEE80211_STYPE_QOS_DATA) ||
-            (fc & IEEE80211_STYPE_QOS_NULLFUNC)))
-               tx_hdr->control.qos = 1;
-}
-
-/* RSN + MIC = 8 + 8 = 16 bytes (worst case - AES). */
-#define MAX_MSDU_SECURITY_LENGTH      16
-#define MAX_MPDU_SECURITY_LENGTH      16
-#define WLAN_QOS_HDR_LEN              26
-#define MAX_MPDU_HEADER_AND_SECURITY  (MAX_MPDU_SECURITY_LENGTH + \
-                                      WLAN_QOS_HDR_LEN)
-#define HW_BLOCK_SIZE                 252
-static void wl1251_tx_frag_block_num(struct tx_double_buffer_desc *tx_hdr)
-{
-       u16 payload_len, frag_threshold, mem_blocks;
-       u16 num_mpdus, mem_blocks_per_frag;
-
-       frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
-       tx_hdr->frag_threshold = cpu_to_le16(frag_threshold);
-
-       payload_len = le16_to_cpu(tx_hdr->length) + MAX_MSDU_SECURITY_LENGTH;
-
-       if (payload_len > frag_threshold) {
-               mem_blocks_per_frag =
-                       ((frag_threshold + MAX_MPDU_HEADER_AND_SECURITY) /
-                        HW_BLOCK_SIZE) + 1;
-               num_mpdus = payload_len / frag_threshold;
-               mem_blocks = num_mpdus * mem_blocks_per_frag;
-               payload_len -= num_mpdus * frag_threshold;
-               num_mpdus++;
-
-       } else {
-               mem_blocks_per_frag = 0;
-               mem_blocks = 0;
-               num_mpdus = 1;
-       }
-
-       mem_blocks += (payload_len / HW_BLOCK_SIZE) + 1;
-
-       if (num_mpdus > 1)
-               mem_blocks += min(num_mpdus, mem_blocks_per_frag);
-
-       tx_hdr->num_mem_blocks = mem_blocks;
-}
-
-static int wl1251_tx_fill_hdr(struct wl1251 *wl, struct sk_buff *skb,
-                             struct ieee80211_tx_info *control)
-{
-       struct tx_double_buffer_desc *tx_hdr;
-       struct ieee80211_rate *rate;
-       int id;
-       u16 fc;
-
-       if (!skb)
-               return -EINVAL;
-
-       id = wl1251_tx_id(wl, skb);
-       if (id < 0)
-               return id;
-
-       fc = *(u16 *)skb->data;
-       tx_hdr = (struct tx_double_buffer_desc *) skb_push(skb,
-                                                          sizeof(*tx_hdr));
-
-       tx_hdr->length = cpu_to_le16(skb->len - sizeof(*tx_hdr));
-       rate = ieee80211_get_tx_rate(wl->hw, control);
-       tx_hdr->rate = cpu_to_le16(rate->hw_value);
-       tx_hdr->expiry_time = cpu_to_le32(1 << 16);
-       tx_hdr->id = id;
-
-       tx_hdr->xmit_queue = wl1251_tx_get_queue(skb_get_queue_mapping(skb));
-
-       wl1251_tx_control(tx_hdr, control, fc);
-       wl1251_tx_frag_block_num(tx_hdr);
-
-       return 0;
-}
-
-/* We copy the packet to the target */
-static int wl1251_tx_send_packet(struct wl1251 *wl, struct sk_buff *skb,
-                                struct ieee80211_tx_info *control)
-{
-       struct tx_double_buffer_desc *tx_hdr;
-       int len;
-       u32 addr;
-
-       if (!skb)
-               return -EINVAL;
-
-       tx_hdr = (struct tx_double_buffer_desc *) skb->data;
-
-       if (control->control.hw_key &&
-           control->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) {
-               int hdrlen;
-               __le16 fc;
-               u16 length;
-               u8 *pos;
-
-               fc = *(__le16 *)(skb->data + sizeof(*tx_hdr));
-               length = le16_to_cpu(tx_hdr->length) + WL1251_TKIP_IV_SPACE;
-               tx_hdr->length = cpu_to_le16(length);
-
-               hdrlen = ieee80211_hdrlen(fc);
-
-               pos = skb_push(skb, WL1251_TKIP_IV_SPACE);
-               memmove(pos, pos + WL1251_TKIP_IV_SPACE,
-                       sizeof(*tx_hdr) + hdrlen);
-       }
-
-       /* Revisit. This is a workaround for getting non-aligned packets.
-          This happens at least with EAPOL packets from the user space.
-          Our DMA requires packets to be aligned on a 4-byte boundary.
-       */
-       if (unlikely((long)skb->data & 0x03)) {
-               int offset = (4 - (long)skb->data) & 0x03;
-               wl1251_debug(DEBUG_TX, "skb offset %d", offset);
-
-               /* check whether the current skb can be used */
-               if (!skb_cloned(skb) && (skb_tailroom(skb) >= offset)) {
-                       unsigned char *src = skb->data;
-
-                       /* align the buffer on a 4-byte boundary */
-                       skb_reserve(skb, offset);
-                       memmove(skb->data, src, skb->len);
-                       tx_hdr = (struct tx_double_buffer_desc *) skb->data;
-               } else {
-                       wl1251_info("No handler, fixme!");
-                       return -EINVAL;
-               }
-       }
-
-       /* Our skb->data at this point includes the HW header */
-       len = WL1251_TX_ALIGN(skb->len);
-
-       if (wl->data_in_count & 0x1)
-               addr = wl->data_path->tx_packet_ring_addr +
-                       wl->data_path->tx_packet_ring_chunk_size;
-       else
-               addr = wl->data_path->tx_packet_ring_addr;
-
-       wl1251_mem_write(wl, addr, skb->data, len);
-
-       wl1251_debug(DEBUG_TX, "tx id %u skb 0x%p payload %u rate 0x%x "
-                    "queue %d", tx_hdr->id, skb, tx_hdr->length,
-                    tx_hdr->rate, tx_hdr->xmit_queue);
-
-       return 0;
-}
-
-static void wl1251_tx_trigger(struct wl1251 *wl)
-{
-       u32 data, addr;
-
-       if (wl->data_in_count & 0x1) {
-               addr = ACX_REG_INTERRUPT_TRIG_H;
-               data = INTR_TRIG_TX_PROC1;
-       } else {
-               addr = ACX_REG_INTERRUPT_TRIG;
-               data = INTR_TRIG_TX_PROC0;
-       }
-
-       wl1251_reg_write32(wl, addr, data);
-
-       /* Bumping data in */
-       wl->data_in_count = (wl->data_in_count + 1) &
-               TX_STATUS_DATA_OUT_COUNT_MASK;
-}
-
-/* caller must hold wl->mutex */
-static int wl1251_tx_frame(struct wl1251 *wl, struct sk_buff *skb)
-{
-       struct ieee80211_tx_info *info;
-       int ret = 0;
-       u8 idx;
-
-       info = IEEE80211_SKB_CB(skb);
-
-       if (info->control.hw_key) {
-               idx = info->control.hw_key->hw_key_idx;
-               if (unlikely(wl->default_key != idx)) {
-                       ret = wl1251_acx_default_key(wl, idx);
-                       if (ret < 0)
-                               return ret;
-               }
-       }
-
-       ret = wl1251_tx_path_status(wl);
-       if (ret < 0)
-               return ret;
-
-       ret = wl1251_tx_fill_hdr(wl, skb, info);
-       if (ret < 0)
-               return ret;
-
-       ret = wl1251_tx_send_packet(wl, skb, info);
-       if (ret < 0)
-               return ret;
-
-       wl1251_tx_trigger(wl);
-
-       return ret;
-}
-
-void wl1251_tx_work(struct work_struct *work)
-{
-       struct wl1251 *wl = container_of(work, struct wl1251, tx_work);
-       struct sk_buff *skb;
-       bool woken_up = false;
-       int ret;
-
-       mutex_lock(&wl->mutex);
-
-       if (unlikely(wl->state == WL1251_STATE_OFF))
-               goto out;
-
-       while ((skb = skb_dequeue(&wl->tx_queue))) {
-               if (!woken_up) {
-                       ret = wl1251_ps_elp_wakeup(wl);
-                       if (ret < 0)
-                               goto out;
-                       woken_up = true;
-               }
-
-               ret = wl1251_tx_frame(wl, skb);
-               if (ret == -EBUSY) {
-                       skb_queue_head(&wl->tx_queue, skb);
-                       goto out;
-               } else if (ret < 0) {
-                       dev_kfree_skb(skb);
-                       goto out;
-               }
-       }
-
-out:
-       if (woken_up)
-               wl1251_ps_elp_sleep(wl);
-
-       mutex_unlock(&wl->mutex);
-}
-
-static const char *wl1251_tx_parse_status(u8 status)
-{
-       /* 8 bit status field, one character per bit plus null */
-       static char buf[9];
-       int i = 0;
-
-       memset(buf, 0, sizeof(buf));
-
-       if (status & TX_DMA_ERROR)
-               buf[i++] = 'm';
-       if (status & TX_DISABLED)
-               buf[i++] = 'd';
-       if (status & TX_RETRY_EXCEEDED)
-               buf[i++] = 'r';
-       if (status & TX_TIMEOUT)
-               buf[i++] = 't';
-       if (status & TX_KEY_NOT_FOUND)
-               buf[i++] = 'k';
-       if (status & TX_ENCRYPT_FAIL)
-               buf[i++] = 'e';
-       if (status & TX_UNAVAILABLE_PRIORITY)
-               buf[i++] = 'p';
-
-       /* bit 0 is unused apparently */
-
-       return buf;
-}
-
-static void wl1251_tx_packet_cb(struct wl1251 *wl,
-                               struct tx_result *result)
-{
-       struct ieee80211_tx_info *info;
-       struct sk_buff *skb;
-       int hdrlen, ret;
-       u8 *frame;
-
-       skb = wl->tx_frames[result->id];
-       if (skb == NULL) {
-               wl1251_error("SKB for packet %d is NULL", result->id);
-               return;
-       }
-
-       info = IEEE80211_SKB_CB(skb);
-
-       if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
-           (result->status == TX_SUCCESS))
-               info->flags |= IEEE80211_TX_STAT_ACK;
-
-       info->status.rates[0].count = result->ack_failures + 1;
-       wl->stats.retry_count += result->ack_failures;
-
-       /*
-        * We have to remove our private TX header before pushing
-        * the skb back to mac80211.
-        */
-       frame = skb_pull(skb, sizeof(struct tx_double_buffer_desc));
-       if (info->control.hw_key &&
-           info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) {
-               hdrlen = ieee80211_get_hdrlen_from_skb(skb);
-               memmove(frame + WL1251_TKIP_IV_SPACE, frame, hdrlen);
-               skb_pull(skb, WL1251_TKIP_IV_SPACE);
-       }
-
-       wl1251_debug(DEBUG_TX, "tx status id %u skb 0x%p failures %u rate 0x%x"
-                    " status 0x%x (%s)",
-                    result->id, skb, result->ack_failures, result->rate,
-                    result->status, wl1251_tx_parse_status(result->status));
-
-
-       ieee80211_tx_status(wl->hw, skb);
-
-       wl->tx_frames[result->id] = NULL;
-
-       if (wl->tx_queue_stopped) {
-               wl1251_debug(DEBUG_TX, "cb: queue was stopped");
-
-               skb = skb_dequeue(&wl->tx_queue);
-
-               /* The skb can be NULL because tx_work might have been
-                  scheduled before the queue was stopped making the
-                  queue empty */
-
-               if (skb) {
-                       ret = wl1251_tx_frame(wl, skb);
-                       if (ret == -EBUSY) {
-                               /* firmware buffer is still full */
-                               wl1251_debug(DEBUG_TX, "cb: fw buffer "
-                                            "still full");
-                               skb_queue_head(&wl->tx_queue, skb);
-                               return;
-                       } else if (ret < 0) {
-                               dev_kfree_skb(skb);
-                               return;
-                       }
-               }
-
-               wl1251_debug(DEBUG_TX, "cb: waking queues");
-               ieee80211_wake_queues(wl->hw);
-               wl->tx_queue_stopped = false;
-       }
-}
-
-/* Called upon reception of a TX complete interrupt */
-void wl1251_tx_complete(struct wl1251 *wl)
-{
-       int i, result_index, num_complete = 0;
-       struct tx_result result[FW_TX_CMPLT_BLOCK_SIZE], *result_ptr;
-       unsigned long flags;
-
-       if (unlikely(wl->state != WL1251_STATE_ON))
-               return;
-
-       /* First we read the result */
-       wl1251_mem_read(wl, wl->data_path->tx_complete_addr,
-                           result, sizeof(result));
-
-       result_index = wl->next_tx_complete;
-
-       for (i = 0; i < ARRAY_SIZE(result); i++) {
-               result_ptr = &result[result_index];
-
-               if (result_ptr->done_1 == 1 &&
-                   result_ptr->done_2 == 1) {
-                       wl1251_tx_packet_cb(wl, result_ptr);
-
-                       result_ptr->done_1 = 0;
-                       result_ptr->done_2 = 0;
-
-                       result_index = (result_index + 1) &
-                               (FW_TX_CMPLT_BLOCK_SIZE - 1);
-                       num_complete++;
-               } else {
-                       break;
-               }
-       }
-
-       if (wl->tx_queue_stopped
-           &&
-           skb_queue_len(&wl->tx_queue) <= WL1251_TX_QUEUE_LOW_WATERMARK){
-
-               /* firmware buffer has space, restart queues */
-               wl1251_debug(DEBUG_TX, "tx_complete: waking queues");
-               spin_lock_irqsave(&wl->wl_lock, flags);
-               ieee80211_wake_queues(wl->hw);
-               wl->tx_queue_stopped = false;
-               spin_unlock_irqrestore(&wl->wl_lock, flags);
-               ieee80211_queue_work(wl->hw, &wl->tx_work);
-
-       }
-
-       /* Every completed frame needs to be acknowledged */
-       if (num_complete) {
-               /*
-                * If we've wrapped, we have to clear
-                * the results in 2 steps.
-                */
-               if (result_index > wl->next_tx_complete) {
-                       /* Only 1 write is needed */
-                       wl1251_mem_write(wl,
-                                        wl->data_path->tx_complete_addr +
-                                        (wl->next_tx_complete *
-                                         sizeof(struct tx_result)),
-                                        &result[wl->next_tx_complete],
-                                        num_complete *
-                                        sizeof(struct tx_result));
-
-
-               } else if (result_index < wl->next_tx_complete) {
-                       /* 2 writes are needed */
-                       wl1251_mem_write(wl,
-                                        wl->data_path->tx_complete_addr +
-                                        (wl->next_tx_complete *
-                                         sizeof(struct tx_result)),
-                                        &result[wl->next_tx_complete],
-                                        (FW_TX_CMPLT_BLOCK_SIZE -
-                                         wl->next_tx_complete) *
-                                        sizeof(struct tx_result));
-
-                       wl1251_mem_write(wl,
-                                        wl->data_path->tx_complete_addr,
-                                        result,
-                                        (num_complete -
-                                         FW_TX_CMPLT_BLOCK_SIZE +
-                                         wl->next_tx_complete) *
-                                        sizeof(struct tx_result));
-
-               } else {
-                       /* We have to write the whole array */
-                       wl1251_mem_write(wl,
-                                        wl->data_path->tx_complete_addr,
-                                        result,
-                                        FW_TX_CMPLT_BLOCK_SIZE *
-                                        sizeof(struct tx_result));
-               }
-
-       }
-
-       wl->next_tx_complete = result_index;
-}
-
-/* caller must hold wl->mutex */
-void wl1251_tx_flush(struct wl1251 *wl)
-{
-       int i;
-       struct sk_buff *skb;
-       struct ieee80211_tx_info *info;
-
-       /* TX failure */
-/*     control->flags = 0; FIXME */
-
-       while ((skb = skb_dequeue(&wl->tx_queue))) {
-               info = IEEE80211_SKB_CB(skb);
-
-               wl1251_debug(DEBUG_TX, "flushing skb 0x%p", skb);
-
-               if (!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS))
-                               continue;
-
-               ieee80211_tx_status(wl->hw, skb);
-       }
-
-       for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++)
-               if (wl->tx_frames[i] != NULL) {
-                       skb = wl->tx_frames[i];
-                       info = IEEE80211_SKB_CB(skb);
-
-                       if (!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS))
-                               continue;
-
-                       ieee80211_tx_status(wl->hw, skb);
-                       wl->tx_frames[i] = NULL;
-               }
-}
diff --git a/drivers/net/wireless/wl12xx/wl1251_tx.h b/drivers/net/wireless/wl12xx/wl1251_tx.h
deleted file mode 100644 (file)
index 96011e7..0000000
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * This file is part of wl1251
- *
- * Copyright (c) 1998-2007 Texas Instruments Incorporated
- * Copyright (C) 2008 Nokia Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __WL1251_TX_H__
-#define __WL1251_TX_H__
-
-#include <linux/bitops.h>
-#include "wl1251_acx.h"
-
-/*
- *
- * TX PATH
- *
- * The Tx path uses a double buffer and a tx_control structure, each located
- * at a fixed address in the device's memory. On startup, the host retrieves
- * the pointers to these addresses. A double buffer allows for continuous data
- * flow towards the device. The host keeps track of which buffer is available
- * and alternates between these two buffers on a per packet basis.
- *
- * The size of each of the two buffers is large enough to hold the longest
- * 802.3 packet - maximum size Ethernet packet + header + descriptor.
- * TX complete indication will be received a-synchronously in a TX done cyclic
- * buffer which is composed of 16 tx_result descriptors structures and is used
- * in a cyclic manner.
- *
- * The TX (HOST) procedure is as follows:
- * 1. Read the Tx path status, that will give the data_out_count.
- * 2. goto 1, if not possible.
- *    i.e. if data_in_count - data_out_count >= HwBuffer size (2 for double
- *    buffer).
- * 3. Copy the packet (preceded by double_buffer_desc), if possible.
- *    i.e. if data_in_count - data_out_count < HwBuffer size (2 for double
- *    buffer).
- * 4. increment data_in_count.
- * 5. Inform the firmware by generating a firmware internal interrupt.
- * 6. FW will increment data_out_count after it reads the buffer.
- *
- * The TX Complete procedure:
- * 1. To get a TX complete indication the host enables the tx_complete flag in
- *    the TX descriptor Structure.
- * 2. For each packet with a Tx Complete field set, the firmware adds the
- *    transmit results to the cyclic buffer (txDoneRing) and sets both done_1
- *    and done_2 to 1 to indicate driver ownership.
- * 3. The firmware sends a Tx Complete interrupt to the host to trigger the
- *    host to process the new data. Note: interrupt will be send per packet if
- *    TX complete indication was requested in tx_control or per crossing
- *    aggregation threshold.
- * 4. After receiving the Tx Complete interrupt, the host reads the
- *    TxDescriptorDone information in a cyclic manner and clears both done_1
- *    and done_2 fields.
- *
- */
-
-#define TX_COMPLETE_REQUIRED_BIT       0x80
-#define TX_STATUS_DATA_OUT_COUNT_MASK   0xf
-
-#define WL1251_TX_ALIGN_TO 4
-#define WL1251_TX_ALIGN(len) (((len) + WL1251_TX_ALIGN_TO - 1) & \
-                            ~(WL1251_TX_ALIGN_TO - 1))
-#define WL1251_TKIP_IV_SPACE 4
-
-struct tx_control {
-       /* Rate Policy (class) index */
-       unsigned rate_policy:3;
-
-       /* When set, no ack policy is expected */
-       unsigned ack_policy:1;
-
-       /*
-        * Packet type:
-        * 0 -> 802.11
-        * 1 -> 802.3
-        * 2 -> IP
-        * 3 -> raw codec
-        */
-       unsigned packet_type:2;
-
-       /* If set, this is a QoS-Null or QoS-Data frame */
-       unsigned qos:1;
-
-       /*
-        * If set, the target triggers the tx complete INT
-        * upon frame sending completion.
-        */
-       unsigned tx_complete:1;
-
-       /* 2 bytes padding before packet header */
-       unsigned xfer_pad:1;
-
-       unsigned reserved:7;
-} __packed;
-
-
-struct tx_double_buffer_desc {
-       /* Length of payload, including headers. */
-       __le16 length;
-
-       /*
-        * A bit mask that specifies the initial rate to be used
-        * Possible values are:
-        * 0x0001 - 1Mbits
-        * 0x0002 - 2Mbits
-        * 0x0004 - 5.5Mbits
-        * 0x0008 - 6Mbits
-        * 0x0010 - 9Mbits
-        * 0x0020 - 11Mbits
-        * 0x0040 - 12Mbits
-        * 0x0080 - 18Mbits
-        * 0x0100 - 22Mbits
-        * 0x0200 - 24Mbits
-        * 0x0400 - 36Mbits
-        * 0x0800 - 48Mbits
-        * 0x1000 - 54Mbits
-        */
-       __le16 rate;
-
-       /* Time in us that a packet can spend in the target */
-       __le32 expiry_time;
-
-       /* index of the TX queue used for this packet */
-       u8 xmit_queue;
-
-       /* Used to identify a packet */
-       u8 id;
-
-       struct tx_control control;
-
-       /*
-        * The FW should cut the packet into fragments
-        * of this size.
-        */
-       __le16 frag_threshold;
-
-       /* Numbers of HW queue blocks to be allocated */
-       u8 num_mem_blocks;
-
-       u8 reserved;
-} __packed;
-
-enum {
-       TX_SUCCESS              = 0,
-       TX_DMA_ERROR            = BIT(7),
-       TX_DISABLED             = BIT(6),
-       TX_RETRY_EXCEEDED       = BIT(5),
-       TX_TIMEOUT              = BIT(4),
-       TX_KEY_NOT_FOUND        = BIT(3),
-       TX_ENCRYPT_FAIL         = BIT(2),
-       TX_UNAVAILABLE_PRIORITY = BIT(1),
-};
-
-struct tx_result {
-       /*
-        * Ownership synchronization between the host and
-        * the firmware. If done_1 and done_2 are cleared,
-        * owned by the FW (no info ready).
-        */
-       u8 done_1;
-
-       /* same as double_buffer_desc->id */
-       u8 id;
-
-       /*
-        * Total air access duration consumed by this
-        * packet, including all retries and overheads.
-        */
-       u16 medium_usage;
-
-       /* Total media delay (from 1st EDCA AIFS counter until TX Complete). */
-       u32 medium_delay;
-
-       /* Time between host xfer and tx complete */
-       u32 fw_hnadling_time;
-
-       /* The LS-byte of the last TKIP sequence number. */
-       u8 lsb_seq_num;
-
-       /* Retry count */
-       u8 ack_failures;
-
-       /* At which rate we got a ACK */
-       u16 rate;
-
-       u16 reserved;
-
-       /* TX_* */
-       u8 status;
-
-       /* See done_1 */
-       u8 done_2;
-} __packed;
-
-static inline int wl1251_tx_get_queue(int queue)
-{
-       switch (queue) {
-       case 0:
-               return QOS_AC_VO;
-       case 1:
-               return QOS_AC_VI;
-       case 2:
-               return QOS_AC_BE;
-       case 3:
-               return QOS_AC_BK;
-       default:
-               return QOS_AC_BE;
-       }
-}
-
-void wl1251_tx_work(struct work_struct *work);
-void wl1251_tx_complete(struct wl1251 *wl);
-void wl1251_tx_flush(struct wl1251 *wl);
-
-#endif
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;
 }