Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
authorJohn W. Linville <linville@tuxdriver.com>
Fri, 4 Mar 2011 19:10:40 +0000 (14:10 -0500)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 4 Mar 2011 19:10:40 +0000 (14:10 -0500)
201 files changed:
drivers/net/wireless/Kconfig
drivers/net/wireless/Makefile
drivers/net/wireless/adm8211.c
drivers/net/wireless/at76c50x-usb.c
drivers/net/wireless/ath/ar9170/ar9170.h
drivers/net/wireless/ath/ar9170/main.c
drivers/net/wireless/ath/ath5k/ath5k.h
drivers/net/wireless/ath/ath5k/base.c
drivers/net/wireless/ath/ath5k/mac80211-ops.c
drivers/net/wireless/ath/ath9k/ar9003_hw.c
drivers/net/wireless/ath/ath9k/ath9k.h
drivers/net/wireless/ath/ath9k/gpio.c
drivers/net/wireless/ath/ath9k/hif_usb.c
drivers/net/wireless/ath/ath9k/htc.h
drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
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/init.c
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/ath/ath9k/recv.c
drivers/net/wireless/ath/ath9k/reg.h
drivers/net/wireless/ath/ath9k/wmi.c
drivers/net/wireless/ath/carl9170/carl9170.h
drivers/net/wireless/ath/carl9170/tx.c
drivers/net/wireless/b43/main.c
drivers/net/wireless/b43/phy_n.c
drivers/net/wireless/b43/tables_nphy.c
drivers/net/wireless/b43/tables_nphy.h
drivers/net/wireless/b43/xmit.c
drivers/net/wireless/b43/xmit.h
drivers/net/wireless/b43legacy/main.c
drivers/net/wireless/b43legacy/xmit.c
drivers/net/wireless/iwlegacy/Kconfig [new file with mode: 0644]
drivers/net/wireless/iwlegacy/Makefile [new file with mode: 0644]
drivers/net/wireless/iwlegacy/iwl-3945-debugfs.c [moved from drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c with 99% similarity]
drivers/net/wireless/iwlegacy/iwl-3945-debugfs.h [moved from drivers/net/wireless/iwlwifi/iwl-3945-debugfs.h with 95% similarity]
drivers/net/wireless/iwlegacy/iwl-3945-fh.h [moved from drivers/net/wireless/iwlwifi/iwl-3945-fh.h with 98% similarity]
drivers/net/wireless/iwlegacy/iwl-3945-hw.h [moved from drivers/net/wireless/iwlwifi/iwl-3945-hw.h with 96% similarity]
drivers/net/wireless/iwlegacy/iwl-3945-led.c [moved from drivers/net/wireless/iwlwifi/iwl-3945-led.c with 94% similarity]
drivers/net/wireless/iwlegacy/iwl-3945-led.h [moved from drivers/net/wireless/iwlwifi/iwl-3945-led.h with 95% similarity]
drivers/net/wireless/iwlegacy/iwl-3945-rs.c [moved from drivers/net/wireless/iwlwifi/iwl-3945-rs.c with 96% similarity]
drivers/net/wireless/iwlegacy/iwl-3945.c [moved from drivers/net/wireless/iwlwifi/iwl-3945.c with 92% similarity]
drivers/net/wireless/iwlegacy/iwl-3945.h [moved from drivers/net/wireless/iwlwifi/iwl-3945.h with 97% similarity]
drivers/net/wireless/iwlegacy/iwl-4965-calib.c [new file with mode: 0644]
drivers/net/wireless/iwlegacy/iwl-4965-calib.h [moved from drivers/net/wireless/iwlwifi/iwl-legacy.h with 80% similarity]
drivers/net/wireless/iwlegacy/iwl-4965-debugfs.c [new file with mode: 0644]
drivers/net/wireless/iwlegacy/iwl-4965-debugfs.h [new file with mode: 0644]
drivers/net/wireless/iwlegacy/iwl-4965-eeprom.c [new file with mode: 0644]
drivers/net/wireless/iwlegacy/iwl-4965-hw.h [moved from drivers/net/wireless/iwlwifi/iwl-4965-hw.h with 97% similarity]
drivers/net/wireless/iwlegacy/iwl-4965-led.c [new file with mode: 0644]
drivers/net/wireless/iwlegacy/iwl-4965-led.h [moved from drivers/net/wireless/rtlwifi/rtl8192cu/fw.c with 71% similarity]
drivers/net/wireless/iwlegacy/iwl-4965-lib.c [new file with mode: 0644]
drivers/net/wireless/iwlegacy/iwl-4965-rs.c [new file with mode: 0644]
drivers/net/wireless/iwlegacy/iwl-4965-rx.c [moved from drivers/net/wireless/iwlwifi/iwl-agn-rx.c with 60% similarity]
drivers/net/wireless/iwlegacy/iwl-4965-sta.c [new file with mode: 0644]
drivers/net/wireless/iwlegacy/iwl-4965-tx.c [new file with mode: 0644]
drivers/net/wireless/iwlegacy/iwl-4965-ucode.c [new file with mode: 0644]
drivers/net/wireless/iwlegacy/iwl-4965.c [moved from drivers/net/wireless/iwlwifi/iwl-4965.c with 71% similarity]
drivers/net/wireless/iwlegacy/iwl-4965.h [new file with mode: 0644]
drivers/net/wireless/iwlegacy/iwl-commands.h [new file with mode: 0644]
drivers/net/wireless/iwlegacy/iwl-core.c [new file with mode: 0644]
drivers/net/wireless/iwlegacy/iwl-core.h [new file with mode: 0644]
drivers/net/wireless/iwlegacy/iwl-csr.h [new file with mode: 0644]
drivers/net/wireless/iwlegacy/iwl-debug.h [new file with mode: 0644]
drivers/net/wireless/iwlegacy/iwl-debugfs.c [new file with mode: 0644]
drivers/net/wireless/iwlegacy/iwl-dev.h [new file with mode: 0644]
drivers/net/wireless/iwlegacy/iwl-devtrace.c [new file with mode: 0644]
drivers/net/wireless/iwlegacy/iwl-devtrace.h [new file with mode: 0644]
drivers/net/wireless/iwlegacy/iwl-eeprom.c [new file with mode: 0644]
drivers/net/wireless/iwlegacy/iwl-eeprom.h [new file with mode: 0644]
drivers/net/wireless/iwlegacy/iwl-fh.h [new file with mode: 0644]
drivers/net/wireless/iwlegacy/iwl-hcmd.c [new file with mode: 0644]
drivers/net/wireless/iwlegacy/iwl-helpers.h [new file with mode: 0644]
drivers/net/wireless/iwlegacy/iwl-io.h [new file with mode: 0644]
drivers/net/wireless/iwlegacy/iwl-led.c [new file with mode: 0644]
drivers/net/wireless/iwlegacy/iwl-led.h [new file with mode: 0644]
drivers/net/wireless/iwlegacy/iwl-legacy-rs.h [new file with mode: 0644]
drivers/net/wireless/iwlegacy/iwl-power.c [new file with mode: 0644]
drivers/net/wireless/iwlegacy/iwl-power.h [new file with mode: 0644]
drivers/net/wireless/iwlegacy/iwl-prph.h [new file with mode: 0644]
drivers/net/wireless/iwlegacy/iwl-rx.c [new file with mode: 0644]
drivers/net/wireless/iwlegacy/iwl-scan.c [new file with mode: 0644]
drivers/net/wireless/iwlegacy/iwl-spectrum.h [new file with mode: 0644]
drivers/net/wireless/iwlegacy/iwl-sta.c [new file with mode: 0644]
drivers/net/wireless/iwlegacy/iwl-sta.h [new file with mode: 0644]
drivers/net/wireless/iwlegacy/iwl-tx.c [new file with mode: 0644]
drivers/net/wireless/iwlegacy/iwl3945-base.c [moved from drivers/net/wireless/iwlwifi/iwl3945-base.c with 90% similarity]
drivers/net/wireless/iwlegacy/iwl4965-base.c [new file with mode: 0644]
drivers/net/wireless/iwlwifi/Kconfig
drivers/net/wireless/iwlwifi/Makefile
drivers/net/wireless/iwlwifi/iwl-1000.c
drivers/net/wireless/iwlwifi/iwl-2000.c
drivers/net/wireless/iwlwifi/iwl-5000.c
drivers/net/wireless/iwlwifi/iwl-6000.c
drivers/net/wireless/iwlwifi/iwl-agn-lib.c
drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
drivers/net/wireless/iwlwifi/iwl-agn-tx.c
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl-agn.h
drivers/net/wireless/iwlwifi/iwl-commands.h
drivers/net/wireless/iwlwifi/iwl-core.c
drivers/net/wireless/iwlwifi/iwl-core.h
drivers/net/wireless/iwlwifi/iwl-debugfs.c
drivers/net/wireless/iwlwifi/iwl-dev.h
drivers/net/wireless/iwlwifi/iwl-eeprom.c
drivers/net/wireless/iwlwifi/iwl-hcmd.c
drivers/net/wireless/iwlwifi/iwl-led.c
drivers/net/wireless/iwlwifi/iwl-legacy.c [deleted file]
drivers/net/wireless/iwlwifi/iwl-power.c
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-tx.c
drivers/net/wireless/libertas_tf/main.c
drivers/net/wireless/mac80211_hwsim.c
drivers/net/wireless/mwl8k.c
drivers/net/wireless/orinoco/scan.c
drivers/net/wireless/p54/eeprom.c
drivers/net/wireless/p54/fwio.c
drivers/net/wireless/p54/lmac.h
drivers/net/wireless/p54/main.c
drivers/net/wireless/p54/p54.h
drivers/net/wireless/p54/txrx.c
drivers/net/wireless/rt2x00/rt2x00.h
drivers/net/wireless/rt2x00/rt2x00mac.c
drivers/net/wireless/rtl818x/rtl8180/dev.c
drivers/net/wireless/rtl818x/rtl8187/dev.c
drivers/net/wireless/rtlwifi/Kconfig
drivers/net/wireless/rtlwifi/Makefile
drivers/net/wireless/rtlwifi/base.c
drivers/net/wireless/rtlwifi/core.c
drivers/net/wireless/rtlwifi/efuse.c
drivers/net/wireless/rtlwifi/efuse.h
drivers/net/wireless/rtlwifi/rtl8192c/Makefile [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c [moved from drivers/net/wireless/rtlwifi/rtl8192ce/fw.c with 98% similarity]
drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h [moved from drivers/net/wireless/rtlwifi/rtl8192ce/fw.h with 100% similarity]
drivers/net/wireless/rtlwifi/rtl8192c/main.c [moved from drivers/net/wireless/rtlwifi/rtl8192cu/fw.h with 75% similarity]
drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c
drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192ce/Makefile
drivers/net/wireless/rtlwifi/rtl8192ce/dm.c
drivers/net/wireless/rtlwifi/rtl8192ce/dm.h
drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
drivers/net/wireless/rtlwifi/rtl8192ce/hw.h
drivers/net/wireless/rtlwifi/rtl8192ce/phy.c
drivers/net/wireless/rtlwifi/rtl8192ce/phy.h
drivers/net/wireless/rtlwifi/rtl8192ce/rf.c
drivers/net/wireless/rtlwifi/rtl8192ce/rf.h
drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
drivers/net/wireless/rtlwifi/rtl8192ce/sw.h
drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
drivers/net/wireless/rtlwifi/rtl8192cu/Makefile
drivers/net/wireless/rtlwifi/rtl8192cu/dm.c
drivers/net/wireless/rtlwifi/rtl8192cu/dm.h
drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
drivers/net/wireless/rtlwifi/rtl8192cu/hw.h
drivers/net/wireless/rtlwifi/rtl8192cu/phy.c
drivers/net/wireless/rtlwifi/rtl8192cu/phy.h
drivers/net/wireless/rtlwifi/rtl8192cu/rf.c
drivers/net/wireless/rtlwifi/rtl8192cu/rf.h
drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
drivers/net/wireless/rtlwifi/rtl8192cu/sw.h
drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
drivers/net/wireless/rtlwifi/wifi.h
drivers/net/wireless/wl1251/main.c
drivers/net/wireless/wl1251/rx.c
drivers/net/wireless/wl12xx/acx.c
drivers/net/wireless/wl12xx/acx.h
drivers/net/wireless/wl12xx/init.c
drivers/net/wireless/wl12xx/main.c
drivers/net/wireless/wl12xx/ps.c
drivers/net/wireless/wl12xx/ps.h
drivers/net/wireless/wl12xx/rx.c
drivers/net/wireless/wl12xx/rx.h
drivers/net/wireless/wl12xx/tx.c
drivers/net/wireless/wl12xx/tx.h
drivers/net/wireless/wl12xx/wl12xx.h
drivers/net/wireless/zd1211rw/zd_mac.c
drivers/staging/brcm80211/sys/wl_mac80211.c
drivers/staging/brcm80211/sys/wlc_mac80211.c
drivers/staging/winbond/wbusb.c
include/linux/nl80211.h
include/net/cfg80211.h
include/net/mac80211.h
net/bluetooth/Kconfig
net/mac80211/Kconfig
net/mac80211/cfg.c
net/mac80211/driver-ops.h
net/mac80211/driver-trace.h
net/mac80211/ht.c
net/mac80211/ibss.c
net/mac80211/ieee80211_i.h
net/mac80211/mlme.c
net/mac80211/rx.c
net/mac80211/sta_info.h
net/mac80211/status.c
net/mac80211/tx.c
net/wireless/nl80211.c

index b4338f3..7aeb113 100644 (file)
@@ -274,6 +274,7 @@ source "drivers/net/wireless/b43legacy/Kconfig"
 source "drivers/net/wireless/hostap/Kconfig"
 source "drivers/net/wireless/ipw2x00/Kconfig"
 source "drivers/net/wireless/iwlwifi/Kconfig"
+source "drivers/net/wireless/iwlegacy/Kconfig"
 source "drivers/net/wireless/iwmc3200wifi/Kconfig"
 source "drivers/net/wireless/libertas/Kconfig"
 source "drivers/net/wireless/orinoco/Kconfig"
index 9760561..ddd3fb6 100644 (file)
@@ -24,7 +24,7 @@ obj-$(CONFIG_B43LEGACY)               += b43legacy/
 obj-$(CONFIG_ZD1211RW)         += zd1211rw/
 obj-$(CONFIG_RTL8180)          += rtl818x/
 obj-$(CONFIG_RTL8187)          += rtl818x/
-obj-$(CONFIG_RTL8192CE)                += rtlwifi/
+obj-$(CONFIG_RTLWIFI)          += rtlwifi/
 
 # 16-bit wireless PCMCIA client drivers
 obj-$(CONFIG_PCMCIA_RAYCS)     += ray_cs.o
@@ -41,7 +41,8 @@ obj-$(CONFIG_ADM8211) += adm8211.o
 
 obj-$(CONFIG_MWL8K)    += mwl8k.o
 
-obj-$(CONFIG_IWLWIFI)  += iwlwifi/
+obj-$(CONFIG_IWLAGN)   += iwlwifi/
+obj-$(CONFIG_IWLWIFI_LEGACY)   += iwlegacy/
 obj-$(CONFIG_RT2X00)   += rt2x00/
 
 obj-$(CONFIG_P54_COMMON)       += p54/
index f9aa1bc..afe2cbc 100644 (file)
@@ -1658,7 +1658,7 @@ static void adm8211_tx_raw(struct ieee80211_hw *dev, struct sk_buff *skb,
 }
 
 /* Put adm8211_tx_hdr on skb and transmit */
-static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
+static void adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
 {
        struct adm8211_tx_hdr *txhdr;
        size_t payload_len, hdrlen;
@@ -1707,8 +1707,6 @@ static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
        txhdr->retry_limit = info->control.rates[0].count;
 
        adm8211_tx_raw(dev, skb, plcp_signal, hdrlen);
-
-       return NETDEV_TX_OK;
 }
 
 static int adm8211_alloc_rings(struct ieee80211_hw *dev)
index 1476314..2986014 100644 (file)
@@ -1728,7 +1728,7 @@ static void at76_mac80211_tx_callback(struct urb *urb)
        ieee80211_wake_queues(priv->hw);
 }
 
-static int at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+static void at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
        struct at76_priv *priv = hw->priv;
        struct at76_tx_buffer *tx_buffer = priv->bulk_out_buffer;
@@ -1741,7 +1741,8 @@ static int at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
        if (priv->tx_urb->status == -EINPROGRESS) {
                wiphy_err(priv->hw->wiphy,
                          "%s called while tx urb is pending\n", __func__);
-               return NETDEV_TX_BUSY;
+               dev_kfree_skb_any(skb);
+               return;
        }
 
        /* The following code lines are important when the device is going to
@@ -1755,7 +1756,8 @@ static int at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
                if (compare_ether_addr(priv->bssid, mgmt->bssid)) {
                        memcpy(priv->bssid, mgmt->bssid, ETH_ALEN);
                        ieee80211_queue_work(hw, &priv->work_join_bssid);
-                       return NETDEV_TX_BUSY;
+                       dev_kfree_skb_any(skb);
+                       return;
                }
        }
 
@@ -1795,8 +1797,6 @@ static int at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
                                  priv->tx_urb,
                                  priv->tx_urb->hcpriv, priv->tx_urb->complete);
        }
-
-       return 0;
 }
 
 static int at76_mac80211_start(struct ieee80211_hw *hw)
index 4f845f8..371e4ce 100644 (file)
@@ -224,7 +224,7 @@ void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len);
 int ar9170_nag_limiter(struct ar9170 *ar);
 
 /* MAC */
-int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
+void ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
 int ar9170_init_mac(struct ar9170 *ar);
 int ar9170_set_qos(struct ar9170 *ar);
 int ar9170_update_multicast(struct ar9170 *ar, const u64 mc_hast);
index a9111e1..b761fec 100644 (file)
@@ -1475,7 +1475,7 @@ static void ar9170_tx(struct ar9170 *ar)
                                     msecs_to_jiffies(AR9170_JANITOR_DELAY));
 }
 
-int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+void ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
        struct ar9170 *ar = hw->priv;
        struct ieee80211_tx_info *info;
@@ -1493,11 +1493,10 @@ int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
        skb_queue_tail(&ar->tx_pending[queue], skb);
 
        ar9170_tx(ar);
-       return NETDEV_TX_OK;
+       return;
 
 err_free:
        dev_kfree_skb_any(skb);
-       return NETDEV_TX_OK;
 }
 
 static int ar9170_op_add_interface(struct ieee80211_hw *hw,
index 70abb61..0ee54eb 100644 (file)
@@ -1164,8 +1164,8 @@ struct ath5k_txq;
 
 void set_beacon_filter(struct ieee80211_hw *hw, bool enable);
 bool ath_any_vif_assoc(struct ath5k_softc *sc);
-int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
-                  struct ath5k_txq *txq);
+void ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
+                   struct ath5k_txq *txq);
 int ath5k_init_hw(struct ath5k_softc *sc);
 int ath5k_stop_hw(struct ath5k_softc *sc);
 void ath5k_mode_setup(struct ath5k_softc *sc, struct ieee80211_vif *vif);
index dbc45e0..91411e9 100644 (file)
@@ -1361,7 +1361,7 @@ ath5k_receive_frame(struct ath5k_softc *sc, struct sk_buff *skb,
         * right now, so it's not too bad...
         */
        rxs->mactime = ath5k_extend_tsf(sc->ah, rs->rs_tstamp);
-       rxs->flag |= RX_FLAG_TSFT;
+       rxs->flag |= RX_FLAG_MACTIME_MPDU;
 
        rxs->freq = sc->curchan->center_freq;
        rxs->band = sc->curchan->band;
@@ -1518,7 +1518,7 @@ unlock:
 * TX Handling *
 \*************/
 
-int
+void
 ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
               struct ath5k_txq *txq)
 {
@@ -1567,11 +1567,10 @@ ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
                spin_unlock_irqrestore(&sc->txbuflock, flags);
                goto drop_packet;
        }
-       return NETDEV_TX_OK;
+       return;
 
 drop_packet:
        dev_kfree_skb_any(skb);
-       return NETDEV_TX_OK;
 }
 
 static void
index a60a726..1fbe3c0 100644 (file)
@@ -52,7 +52,7 @@ extern int ath5k_modparam_nohwcrypt;
 * Mac80211 functions *
 \********************/
 
-static int
+static void
 ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
        struct ath5k_softc *sc = hw->priv;
@@ -60,10 +60,10 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 
        if (WARN_ON(qnum >= sc->ah->ah_capabilities.cap_queues.q_tx_num)) {
                dev_kfree_skb_any(skb);
-               return 0;
+               return;
        }
 
-       return ath5k_tx_queue(hw, skb, &sc->txqs[qnum]);
+       ath5k_tx_queue(hw, skb, &sc->txqs[qnum]);
 }
 
 
index 6fa3c24..7f5de6e 100644 (file)
@@ -78,15 +78,15 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
                /* Awake Setting */
 
                INIT_INI_ARRAY(&ah->iniPcieSerdes,
-                               ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1,
-                               ARRAY_SIZE(ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1),
+                               ar9485_1_1_pcie_phy_clkreq_disable_L1,
+                               ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1),
                                2);
 
                /* Sleep Setting */
 
                INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
-                               ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1,
-                               ARRAY_SIZE(ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1),
+                               ar9485_1_1_pcie_phy_clkreq_disable_L1,
+                               ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1),
                                2);
        } else if (AR_SREV_9485(ah)) {
                /* mac */
index f9f0389..c718ab5 100644 (file)
@@ -449,26 +449,21 @@ void ath9k_btcoex_timer_pause(struct ath_softc *sc);
 
 #define ATH_LED_PIN_DEF                1
 #define ATH_LED_PIN_9287               8
-#define ATH_LED_ON_DURATION_IDLE       350     /* in msecs */
-#define ATH_LED_OFF_DURATION_IDLE      250     /* in msecs */
-
-enum ath_led_type {
-       ATH_LED_RADIO,
-       ATH_LED_ASSOC,
-       ATH_LED_TX,
-       ATH_LED_RX
-};
-
-struct ath_led {
-       struct ath_softc *sc;
-       struct led_classdev led_cdev;
-       enum ath_led_type led_type;
-       char name[32];
-       bool registered;
-};
+#define ATH_LED_PIN_9485               6
 
+#ifdef CONFIG_MAC80211_LEDS
 void ath_init_leds(struct ath_softc *sc);
 void ath_deinit_leds(struct ath_softc *sc);
+#else
+static inline void ath_init_leds(struct ath_softc *sc)
+{
+}
+
+static inline void ath_deinit_leds(struct ath_softc *sc)
+{
+}
+#endif
+
 
 /* Antenna diversity/combining */
 #define ATH_ANT_RX_CURRENT_SHIFT 4
@@ -620,15 +615,11 @@ struct ath_softc {
        struct ath_beacon beacon;
        struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
 
-       struct ath_led radio_led;
-       struct ath_led assoc_led;
-       struct ath_led tx_led;
-       struct ath_led rx_led;
-       struct delayed_work ath_led_blink_work;
-       int led_on_duration;
-       int led_off_duration;
-       int led_on_cnt;
-       int led_off_cnt;
+#ifdef CONFIG_MAC80211_LEDS
+       bool led_registered;
+       char led_name[32];
+       struct led_classdev led_cdev;
+#endif
 
        struct ath9k_hw_cal_data caldata;
        int last_rssi;
index fb4f17a..0fb8f8a 100644 (file)
 /*      LED functions          */
 /********************************/
 
-static void ath_led_blink_work(struct work_struct *work)
-{
-       struct ath_softc *sc = container_of(work, struct ath_softc,
-                                           ath_led_blink_work.work);
-
-       if (!(sc->sc_flags & SC_OP_LED_ASSOCIATED))
-               return;
-
-       if ((sc->led_on_duration == ATH_LED_ON_DURATION_IDLE) ||
-           (sc->led_off_duration == ATH_LED_OFF_DURATION_IDLE))
-               ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0);
-       else
-               ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin,
-                                 (sc->sc_flags & SC_OP_LED_ON) ? 1 : 0);
-
-       ieee80211_queue_delayed_work(sc->hw,
-                                    &sc->ath_led_blink_work,
-                                    (sc->sc_flags & SC_OP_LED_ON) ?
-                                       msecs_to_jiffies(sc->led_off_duration) :
-                                       msecs_to_jiffies(sc->led_on_duration));
-
-       sc->led_on_duration = sc->led_on_cnt ?
-                       max((ATH_LED_ON_DURATION_IDLE - sc->led_on_cnt), 25) :
-                       ATH_LED_ON_DURATION_IDLE;
-       sc->led_off_duration = sc->led_off_cnt ?
-                       max((ATH_LED_OFF_DURATION_IDLE - sc->led_off_cnt), 10) :
-                       ATH_LED_OFF_DURATION_IDLE;
-       sc->led_on_cnt = sc->led_off_cnt = 0;
-       if (sc->sc_flags & SC_OP_LED_ON)
-               sc->sc_flags &= ~SC_OP_LED_ON;
-       else
-               sc->sc_flags |= SC_OP_LED_ON;
-}
-
+#ifdef CONFIG_MAC80211_LEDS
 static void ath_led_brightness(struct led_classdev *led_cdev,
                               enum led_brightness brightness)
 {
-       struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev);
-       struct ath_softc *sc = led->sc;
-
-       switch (brightness) {
-       case LED_OFF:
-               if (led->led_type == ATH_LED_ASSOC ||
-                   led->led_type == ATH_LED_RADIO) {
-                       ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin,
-                               (led->led_type == ATH_LED_RADIO));
-                       sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
-                       if (led->led_type == ATH_LED_RADIO)
-                               sc->sc_flags &= ~SC_OP_LED_ON;
-               } else {
-                       sc->led_off_cnt++;
-               }
-               break;
-       case LED_FULL:
-               if (led->led_type == ATH_LED_ASSOC) {
-                       sc->sc_flags |= SC_OP_LED_ASSOCIATED;
-                       if (led_blink)
-                               ieee80211_queue_delayed_work(sc->hw,
-                                                    &sc->ath_led_blink_work, 0);
-               } else if (led->led_type == ATH_LED_RADIO) {
-                       ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0);
-                       sc->sc_flags |= SC_OP_LED_ON;
-               } else {
-                       sc->led_on_cnt++;
-               }
-               break;
-       default:
-               break;
-       }
-}
-
-static int ath_register_led(struct ath_softc *sc, struct ath_led *led,
-                           char *trigger)
-{
-       int ret;
-
-       led->sc = sc;
-       led->led_cdev.name = led->name;
-       led->led_cdev.default_trigger = trigger;
-       led->led_cdev.brightness_set = ath_led_brightness;
-
-       ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &led->led_cdev);
-       if (ret)
-               ath_err(ath9k_hw_common(sc->sc_ah),
-                       "Failed to register led:%s", led->name);
-       else
-               led->registered = 1;
-       return ret;
-}
-
-static void ath_unregister_led(struct ath_led *led)
-{
-       if (led->registered) {
-               led_classdev_unregister(&led->led_cdev);
-               led->registered = 0;
-       }
+       struct ath_softc *sc = container_of(led_cdev, struct ath_softc, led_cdev);
+       ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, (brightness == LED_OFF));
 }
 
 void ath_deinit_leds(struct ath_softc *sc)
 {
-       ath_unregister_led(&sc->assoc_led);
-       sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
-       ath_unregister_led(&sc->tx_led);
-       ath_unregister_led(&sc->rx_led);
-       ath_unregister_led(&sc->radio_led);
-       ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
+       if (!sc->led_registered)
+               return;
+
+       ath_led_brightness(&sc->led_cdev, LED_OFF);
+       led_classdev_unregister(&sc->led_cdev);
 }
 
 void ath_init_leds(struct ath_softc *sc)
 {
-       char *trigger;
        int ret;
 
        if (AR_SREV_9287(sc->sc_ah))
                sc->sc_ah->led_pin = ATH_LED_PIN_9287;
+       else if (AR_SREV_9485(sc->sc_ah))
+               sc->sc_ah->led_pin = ATH_LED_PIN_9485;
        else
                sc->sc_ah->led_pin = ATH_LED_PIN_DEF;
 
@@ -144,48 +54,22 @@ void ath_init_leds(struct ath_softc *sc)
        /* LED off, active low */
        ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
 
-       if (led_blink)
-               INIT_DELAYED_WORK(&sc->ath_led_blink_work, ath_led_blink_work);
-
-       trigger = ieee80211_get_radio_led_name(sc->hw);
-       snprintf(sc->radio_led.name, sizeof(sc->radio_led.name),
-               "ath9k-%s::radio", wiphy_name(sc->hw->wiphy));
-       ret = ath_register_led(sc, &sc->radio_led, trigger);
-       sc->radio_led.led_type = ATH_LED_RADIO;
-       if (ret)
-               goto fail;
-
-       trigger = ieee80211_get_assoc_led_name(sc->hw);
-       snprintf(sc->assoc_led.name, sizeof(sc->assoc_led.name),
-               "ath9k-%s::assoc", wiphy_name(sc->hw->wiphy));
-       ret = ath_register_led(sc, &sc->assoc_led, trigger);
-       sc->assoc_led.led_type = ATH_LED_ASSOC;
-       if (ret)
-               goto fail;
-
-       trigger = ieee80211_get_tx_led_name(sc->hw);
-       snprintf(sc->tx_led.name, sizeof(sc->tx_led.name),
-               "ath9k-%s::tx", wiphy_name(sc->hw->wiphy));
-       ret = ath_register_led(sc, &sc->tx_led, trigger);
-       sc->tx_led.led_type = ATH_LED_TX;
-       if (ret)
-               goto fail;
-
-       trigger = ieee80211_get_rx_led_name(sc->hw);
-       snprintf(sc->rx_led.name, sizeof(sc->rx_led.name),
-               "ath9k-%s::rx", wiphy_name(sc->hw->wiphy));
-       ret = ath_register_led(sc, &sc->rx_led, trigger);
-       sc->rx_led.led_type = ATH_LED_RX;
-       if (ret)
-               goto fail;
-
-       return;
-
-fail:
-       if (led_blink)
-               cancel_delayed_work_sync(&sc->ath_led_blink_work);
-       ath_deinit_leds(sc);
+       if (!led_blink)
+               sc->led_cdev.default_trigger =
+                       ieee80211_get_radio_led_name(sc->hw);
+
+       snprintf(sc->led_name, sizeof(sc->led_name),
+               "ath9k-%s", wiphy_name(sc->hw->wiphy));
+       sc->led_cdev.name = sc->led_name;
+       sc->led_cdev.brightness_set = ath_led_brightness;
+
+       ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &sc->led_cdev);
+       if (ret < 0)
+               return;
+
+       sc->led_registered = true;
 }
+#endif
 
 /*******************/
 /*     Rfkill     */
index 5ab3084..7dc2048 100644 (file)
@@ -52,6 +52,9 @@ static struct usb_device_id ath9k_hif_usb_ids[] = {
        { USB_DEVICE(0x083A, 0xA704),
          .driver_info = AR9280_USB },  /* SMC Networks */
 
+       { USB_DEVICE(0x0cf3, 0x20ff),
+         .driver_info = STORAGE_DEVICE },
+
        { },
 };
 
@@ -913,13 +916,11 @@ static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev, u32 drv_info)
        if (ret) {
                dev_err(&hif_dev->udev->dev,
                        "ath9k_htc: Unable to allocate URBs\n");
-               goto err_urb;
+               goto err_fw_download;
        }
 
        return 0;
 
-err_urb:
-       ath9k_hif_usb_dealloc_urbs(hif_dev);
 err_fw_download:
        release_firmware(hif_dev->firmware);
 err_fw_req:
@@ -934,6 +935,61 @@ static void ath9k_hif_usb_dev_deinit(struct hif_device_usb *hif_dev)
                release_firmware(hif_dev->firmware);
 }
 
+/*
+ * An exact copy of the function from zd1211rw.
+ */
+static int send_eject_command(struct usb_interface *interface)
+{
+       struct usb_device *udev = interface_to_usbdev(interface);
+       struct usb_host_interface *iface_desc = &interface->altsetting[0];
+       struct usb_endpoint_descriptor *endpoint;
+       unsigned char *cmd;
+       u8 bulk_out_ep;
+       int r;
+
+       /* Find bulk out endpoint */
+       for (r = 1; r >= 0; r--) {
+               endpoint = &iface_desc->endpoint[r].desc;
+               if (usb_endpoint_dir_out(endpoint) &&
+                   usb_endpoint_xfer_bulk(endpoint)) {
+                       bulk_out_ep = endpoint->bEndpointAddress;
+                       break;
+               }
+       }
+       if (r == -1) {
+               dev_err(&udev->dev,
+                       "ath9k_htc: Could not find bulk out endpoint\n");
+               return -ENODEV;
+       }
+
+       cmd = kzalloc(31, GFP_KERNEL);
+       if (cmd == NULL)
+               return -ENODEV;
+
+       /* USB bulk command block */
+       cmd[0] = 0x55;  /* bulk command signature */
+       cmd[1] = 0x53;  /* bulk command signature */
+       cmd[2] = 0x42;  /* bulk command signature */
+       cmd[3] = 0x43;  /* bulk command signature */
+       cmd[14] = 6;    /* command length */
+
+       cmd[15] = 0x1b; /* SCSI command: START STOP UNIT */
+       cmd[19] = 0x2;  /* eject disc */
+
+       dev_info(&udev->dev, "Ejecting storage device...\n");
+       r = usb_bulk_msg(udev, usb_sndbulkpipe(udev, bulk_out_ep),
+               cmd, 31, NULL, 2000);
+       kfree(cmd);
+       if (r)
+               return r;
+
+       /* At this point, the device disconnects and reconnects with the real
+        * ID numbers. */
+
+       usb_set_intfdata(interface, NULL);
+       return 0;
+}
+
 static int ath9k_hif_usb_probe(struct usb_interface *interface,
                               const struct usb_device_id *id)
 {
@@ -941,6 +997,9 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface,
        struct hif_device_usb *hif_dev;
        int ret = 0;
 
+       if (id->driver_info == STORAGE_DEVICE)
+               return send_eject_command(interface);
+
        hif_dev = kzalloc(sizeof(struct hif_device_usb), GFP_KERNEL);
        if (!hif_dev) {
                ret = -ENOMEM;
@@ -1027,12 +1086,13 @@ static void ath9k_hif_usb_disconnect(struct usb_interface *interface)
        struct hif_device_usb *hif_dev = usb_get_intfdata(interface);
        bool unplugged = (udev->state == USB_STATE_NOTATTACHED) ? true : false;
 
-       if (hif_dev) {
-               ath9k_htc_hw_deinit(hif_dev->htc_handle, unplugged);
-               ath9k_htc_hw_free(hif_dev->htc_handle);
-               ath9k_hif_usb_dev_deinit(hif_dev);
-               usb_set_intfdata(interface, NULL);
-       }
+       if (!hif_dev)
+               return;
+
+       ath9k_htc_hw_deinit(hif_dev->htc_handle, unplugged);
+       ath9k_htc_hw_free(hif_dev->htc_handle);
+       ath9k_hif_usb_dev_deinit(hif_dev);
+       usb_set_intfdata(interface, NULL);
 
        if (!unplugged && (hif_dev->flags & HIF_USB_START))
                ath9k_hif_usb_reboot(udev);
index 0cb504d..753a245 100644 (file)
@@ -32,6 +32,7 @@
 #include "wmi.h"
 
 #define ATH_STA_SHORT_CALINTERVAL 1000    /* 1 second */
+#define ATH_AP_SHORT_CALINTERVAL  100     /* 100 ms */
 #define ATH_ANI_POLLINTERVAL      100     /* 100 ms */
 #define ATH_LONG_CALINTERVAL      30000   /* 30 seconds */
 #define ATH_RESTART_CALINTERVAL   1200000 /* 20 minutes */
@@ -204,8 +205,50 @@ struct ath9k_htc_target_stats {
        __be32 ht_tx_xretries;
 } __packed;
 
+#define ATH9K_HTC_MAX_VIF 2
+#define ATH9K_HTC_MAX_BCN_VIF 2
+
+#define INC_VIF(_priv, _type) do {             \
+               switch (_type) {                \
+               case NL80211_IFTYPE_STATION:    \
+                       _priv->num_sta_vif++;   \
+                       break;                  \
+               case NL80211_IFTYPE_ADHOC:      \
+                       _priv->num_ibss_vif++;  \
+                       break;                  \
+               case NL80211_IFTYPE_AP:         \
+                       _priv->num_ap_vif++;    \
+                       break;                  \
+               default:                        \
+                       break;                  \
+               }                               \
+       } while (0)
+
+#define DEC_VIF(_priv, _type) do {             \
+               switch (_type) {                \
+               case NL80211_IFTYPE_STATION:    \
+                       _priv->num_sta_vif--;   \
+                       break;                  \
+               case NL80211_IFTYPE_ADHOC:      \
+                       _priv->num_ibss_vif--;  \
+                       break;                  \
+               case NL80211_IFTYPE_AP:         \
+                       _priv->num_ap_vif--;    \
+                       break;                  \
+               default:                        \
+                       break;                  \
+               }                               \
+       } while (0)
+
 struct ath9k_htc_vif {
        u8 index;
+       u16 seq_no;
+       bool beacon_configured;
+};
+
+struct ath9k_vif_iter_data {
+       const u8 *hw_macaddr;
+       u8 mask[ETH_ALEN];
 };
 
 #define ATH9K_HTC_MAX_STA 8
@@ -310,10 +353,8 @@ struct ath_led {
 
 struct htc_beacon_config {
        u16 beacon_interval;
-       u16 listen_interval;
        u16 dtim_period;
        u16 bmiss_timeout;
-       u8 dtim_count;
 };
 
 struct ath_btcoex {
@@ -333,13 +374,12 @@ void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv);
 #define OP_SCANNING               BIT(1)
 #define OP_LED_ASSOCIATED         BIT(2)
 #define OP_LED_ON                 BIT(3)
-#define OP_PREAMBLE_SHORT         BIT(4)
-#define OP_PROTECT_ENABLE         BIT(5)
-#define OP_ASSOCIATED             BIT(6)
-#define OP_ENABLE_BEACON          BIT(7)
-#define OP_LED_DEINIT             BIT(8)
-#define OP_BT_PRIORITY_DETECTED    BIT(9)
-#define OP_BT_SCAN                 BIT(10)
+#define OP_ENABLE_BEACON          BIT(4)
+#define OP_LED_DEINIT             BIT(5)
+#define OP_BT_PRIORITY_DETECTED    BIT(6)
+#define OP_BT_SCAN                 BIT(7)
+#define OP_ANI_RUNNING             BIT(8)
+#define OP_TSF_RESET               BIT(9)
 
 struct ath9k_htc_priv {
        struct device *dev;
@@ -358,13 +398,22 @@ struct ath9k_htc_priv {
        enum htc_endpoint_id data_vi_ep;
        enum htc_endpoint_id data_vo_ep;
 
+       u8 vif_slot;
+       u8 mon_vif_idx;
+       u8 sta_slot;
+       u8 vif_sta_pos[ATH9K_HTC_MAX_VIF];
+       u8 num_ibss_vif;
+       u8 num_sta_vif;
+       u8 num_ap_vif;
+
        u16 op_flags;
        u16 curtxpow;
        u16 txpowlimit;
        u16 nvifs;
        u16 nstations;
-       u16 seq_no;
        u32 bmiss_cnt;
+       bool rearm_ani;
+       bool reconfig_beacon;
 
        struct ath9k_hw_cal_data caldata;
 
@@ -382,7 +431,7 @@ struct ath9k_htc_priv {
        struct ath9k_htc_rx rx;
        struct tasklet_struct tx_tasklet;
        struct sk_buff_head tx_queue;
-       struct delayed_work ath9k_ani_work;
+       struct delayed_work ani_work;
        struct work_struct ps_work;
        struct work_struct fatal_work;
 
@@ -424,6 +473,7 @@ void ath9k_htc_reset(struct ath9k_htc_priv *priv);
 void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv);
 void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv,
                             struct ieee80211_vif *vif);
+void ath9k_htc_beacon_reconfig(struct ath9k_htc_priv *priv);
 void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending);
 
 void ath9k_htc_rxep(void *priv, struct sk_buff *skb,
@@ -436,8 +486,9 @@ void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb,
 int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv);
 void ath9k_htc_station_work(struct work_struct *work);
 void ath9k_htc_aggr_work(struct work_struct *work);
-void ath9k_ani_work(struct work_struct *work);;
-void ath_start_ani(struct ath9k_htc_priv *priv);
+void ath9k_htc_ani_work(struct work_struct *work);
+void ath9k_htc_start_ani(struct ath9k_htc_priv *priv);
+void ath9k_htc_stop_ani(struct ath9k_htc_priv *priv);
 
 int ath9k_tx_init(struct ath9k_htc_priv *priv);
 void ath9k_tx_tasklet(unsigned long data);
index 87cc65a..8d1d879 100644 (file)
@@ -123,8 +123,9 @@ static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv,
        /* TSF out of range threshold fixed at 1 second */
        bs.bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD;
 
-       ath_dbg(common, ATH_DBG_BEACON, "tsf: %llu tsftu: %u\n", tsf, tsftu);
-       ath_dbg(common, ATH_DBG_BEACON,
+       ath_dbg(common, ATH_DBG_CONFIG, "intval: %u tsf: %llu tsftu: %u\n",
+               intval, tsf, tsftu);
+       ath_dbg(common, ATH_DBG_CONFIG,
                "bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n",
                bs.bs_bmissthreshold, bs.bs_sleepduration,
                bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext);
@@ -138,25 +139,81 @@ static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv,
        WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask);
 }
 
+static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv,
+                                      struct htc_beacon_config *bss_conf)
+{
+       struct ath_common *common = ath9k_hw_common(priv->ah);
+       enum ath9k_int imask = 0;
+       u32 nexttbtt, intval, tsftu;
+       __be32 htc_imask = 0;
+       int ret;
+       u8 cmd_rsp;
+       u64 tsf;
+
+       intval = bss_conf->beacon_interval & ATH9K_BEACON_PERIOD;
+       intval /= ATH9K_HTC_MAX_BCN_VIF;
+       nexttbtt = intval;
+
+       if (priv->op_flags & OP_TSF_RESET) {
+               intval |= ATH9K_BEACON_RESET_TSF;
+               priv->op_flags &= ~OP_TSF_RESET;
+       } else {
+               /*
+                * Pull nexttbtt forward to reflect the current TSF.
+                */
+               tsf = ath9k_hw_gettsf64(priv->ah);
+               tsftu = TSF_TO_TU(tsf >> 32, tsf) + FUDGE;
+               do {
+                       nexttbtt += intval;
+               } while (nexttbtt < tsftu);
+       }
+
+       intval |= ATH9K_BEACON_ENA;
+
+       if (priv->op_flags & OP_ENABLE_BEACON)
+               imask |= ATH9K_INT_SWBA;
+
+       ath_dbg(common, ATH_DBG_CONFIG,
+               "AP Beacon config, intval: %d, nexttbtt: %u imask: 0x%x\n",
+               bss_conf->beacon_interval, nexttbtt, imask);
+
+       WMI_CMD(WMI_DISABLE_INTR_CMDID);
+       ath9k_hw_beaconinit(priv->ah, nexttbtt, intval);
+       priv->bmiss_cnt = 0;
+       htc_imask = cpu_to_be32(imask);
+       WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask);
+}
+
 static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv,
                                          struct htc_beacon_config *bss_conf)
 {
        struct ath_common *common = ath9k_hw_common(priv->ah);
        enum ath9k_int imask = 0;
-       u32 nexttbtt, intval;
+       u32 nexttbtt, intval, tsftu;
        __be32 htc_imask = 0;
        int ret;
        u8 cmd_rsp;
+       u64 tsf;
 
        intval = bss_conf->beacon_interval & ATH9K_BEACON_PERIOD;
        nexttbtt = intval;
+
+       /*
+        * Pull nexttbtt forward to reflect the current TSF.
+        */
+       tsf = ath9k_hw_gettsf64(priv->ah);
+       tsftu = TSF_TO_TU(tsf >> 32, tsf) + FUDGE;
+       do {
+               nexttbtt += intval;
+       } while (nexttbtt < tsftu);
+
        intval |= ATH9K_BEACON_ENA;
        if (priv->op_flags & OP_ENABLE_BEACON)
                imask |= ATH9K_INT_SWBA;
 
-       ath_dbg(common, ATH_DBG_BEACON,
-               "IBSS Beacon config, intval: %d, imask: 0x%x\n",
-               bss_conf->beacon_interval, imask);
+       ath_dbg(common, ATH_DBG_CONFIG,
+               "IBSS Beacon config, intval: %d, nexttbtt: %u, imask: 0x%x\n",
+               bss_conf->beacon_interval, nexttbtt, imask);
 
        WMI_CMD(WMI_DISABLE_INTR_CMDID);
        ath9k_hw_beaconinit(priv->ah, nexttbtt, intval);
@@ -207,9 +264,9 @@ void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending)
        if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
                struct ieee80211_hdr *hdr =
                        (struct ieee80211_hdr *) beacon->data;
-               priv->seq_no += 0x10;
+               avp->seq_no += 0x10;
                hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
-               hdr->seq_ctrl |= cpu_to_le16(priv->seq_no);
+               hdr->seq_ctrl |= cpu_to_le16(avp->seq_no);
        }
 
        tx_ctl.type = ATH9K_HTC_NORMAL;
@@ -253,30 +310,123 @@ void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv)
        }
 }
 
+static void ath9k_htc_beacon_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
+{
+       bool *beacon_configured = (bool *)data;
+       struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *) vif->drv_priv;
+
+       if (vif->type == NL80211_IFTYPE_STATION &&
+           avp->beacon_configured)
+               *beacon_configured = true;
+}
+
+static bool ath9k_htc_check_beacon_config(struct ath9k_htc_priv *priv,
+                                         struct ieee80211_vif *vif)
+{
+       struct ath_common *common = ath9k_hw_common(priv->ah);
+       struct htc_beacon_config *cur_conf = &priv->cur_beacon_conf;
+       struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
+       bool beacon_configured;
+
+       /*
+        * Changing the beacon interval when multiple AP interfaces
+        * are configured will affect beacon transmission of all
+        * of them.
+        */
+       if ((priv->ah->opmode == NL80211_IFTYPE_AP) &&
+           (priv->num_ap_vif > 1) &&
+           (vif->type == NL80211_IFTYPE_AP) &&
+           (cur_conf->beacon_interval != bss_conf->beacon_int)) {
+               ath_dbg(common, ATH_DBG_CONFIG,
+                       "Changing beacon interval of multiple AP interfaces !\n");
+               return false;
+       }
+
+       /*
+        * If the HW is operating in AP mode, any new station interfaces that
+        * are added cannot change the beacon parameters.
+        */
+       if (priv->num_ap_vif &&
+           (vif->type != NL80211_IFTYPE_AP)) {
+               ath_dbg(common, ATH_DBG_CONFIG,
+                       "HW in AP mode, cannot set STA beacon parameters\n");
+               return false;
+       }
+
+       /*
+        * The beacon parameters are configured only for the first
+        * station interface.
+        */
+       if ((priv->ah->opmode == NL80211_IFTYPE_STATION) &&
+           (priv->num_sta_vif > 1) &&
+           (vif->type == NL80211_IFTYPE_STATION)) {
+               beacon_configured = false;
+               ieee80211_iterate_active_interfaces_atomic(priv->hw,
+                                                          ath9k_htc_beacon_iter,
+                                                          &beacon_configured);
+
+               if (beacon_configured) {
+                       ath_dbg(common, ATH_DBG_CONFIG,
+                               "Beacon already configured for a station interface\n");
+                       return false;
+               }
+       }
+
+       return true;
+}
+
 void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv,
                             struct ieee80211_vif *vif)
 {
        struct ath_common *common = ath9k_hw_common(priv->ah);
        struct htc_beacon_config *cur_conf = &priv->cur_beacon_conf;
        struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
+       struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *) vif->drv_priv;
+
+       if (!ath9k_htc_check_beacon_config(priv, vif))
+               return;
 
        cur_conf->beacon_interval = bss_conf->beacon_int;
        if (cur_conf->beacon_interval == 0)
                cur_conf->beacon_interval = 100;
 
        cur_conf->dtim_period = bss_conf->dtim_period;
-       cur_conf->listen_interval = 1;
-       cur_conf->dtim_count = 1;
        cur_conf->bmiss_timeout =
                ATH_DEFAULT_BMISS_LIMIT * cur_conf->beacon_interval;
 
        switch (vif->type) {
+       case NL80211_IFTYPE_STATION:
+               ath9k_htc_beacon_config_sta(priv, cur_conf);
+               avp->beacon_configured = true;
+               break;
+       case NL80211_IFTYPE_ADHOC:
+               ath9k_htc_beacon_config_adhoc(priv, cur_conf);
+               break;
+       case NL80211_IFTYPE_AP:
+               ath9k_htc_beacon_config_ap(priv, cur_conf);
+               break;
+       default:
+               ath_dbg(common, ATH_DBG_CONFIG,
+                       "Unsupported beaconing mode\n");
+               return;
+       }
+}
+
+void ath9k_htc_beacon_reconfig(struct ath9k_htc_priv *priv)
+{
+       struct ath_common *common = ath9k_hw_common(priv->ah);
+       struct htc_beacon_config *cur_conf = &priv->cur_beacon_conf;
+
+       switch (priv->ah->opmode) {
        case NL80211_IFTYPE_STATION:
                ath9k_htc_beacon_config_sta(priv, cur_conf);
                break;
        case NL80211_IFTYPE_ADHOC:
                ath9k_htc_beacon_config_adhoc(priv, cur_conf);
                break;
+       case NL80211_IFTYPE_AP:
+               ath9k_htc_beacon_config_ap(priv, cur_conf);
+               break;
        default:
                ath_dbg(common, ATH_DBG_CONFIG,
                        "Unsupported beaconing mode\n");
index a7bc26d..fc67c93 100644 (file)
@@ -679,7 +679,7 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv,
                     (unsigned long)priv);
        tasklet_init(&priv->tx_tasklet, ath9k_tx_tasklet,
                     (unsigned long)priv);
-       INIT_DELAYED_WORK(&priv->ath9k_ani_work, ath9k_ani_work);
+       INIT_DELAYED_WORK(&priv->ani_work, ath9k_htc_ani_work);
        INIT_WORK(&priv->ps_work, ath9k_ps_work);
        INIT_WORK(&priv->fatal_work, ath9k_fatal_work);
 
@@ -787,6 +787,7 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv,
        struct ath_hw *ah;
        int error = 0;
        struct ath_regulatory *reg;
+       char hw_name[64];
 
        /* Bring up device */
        error = ath9k_init_priv(priv, devid, product, drv_info);
@@ -827,6 +828,22 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv,
                        goto err_world;
        }
 
+       ath_dbg(common, ATH_DBG_CONFIG,
+               "WMI:%d, BCN:%d, CAB:%d, UAPSD:%d, MGMT:%d, "
+               "BE:%d, BK:%d, VI:%d, VO:%d\n",
+               priv->wmi_cmd_ep,
+               priv->beacon_ep,
+               priv->cab_ep,
+               priv->uapsd_ep,
+               priv->mgmt_ep,
+               priv->data_be_ep,
+               priv->data_bk_ep,
+               priv->data_vi_ep,
+               priv->data_vo_ep);
+
+       ath9k_hw_name(priv->ah, hw_name, sizeof(hw_name));
+       wiphy_info(hw->wiphy, "%s\n", hw_name);
+
        ath9k_init_leds(priv);
        ath9k_start_rfkill_poll(priv);
 
index 50fde0e..db8c0c0 100644 (file)
@@ -105,6 +105,82 @@ void ath9k_ps_work(struct work_struct *work)
        ath9k_htc_setpower(priv, ATH9K_PM_NETWORK_SLEEP);
 }
 
+static void ath9k_htc_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
+{
+       struct ath9k_htc_priv *priv = data;
+       struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
+
+       if ((vif->type == NL80211_IFTYPE_AP) && bss_conf->enable_beacon)
+               priv->reconfig_beacon = true;
+
+       if (bss_conf->assoc) {
+               priv->rearm_ani = true;
+               priv->reconfig_beacon = true;
+       }
+}
+
+static void ath9k_htc_vif_reconfig(struct ath9k_htc_priv *priv)
+{
+       priv->rearm_ani = false;
+       priv->reconfig_beacon = false;
+
+       ieee80211_iterate_active_interfaces_atomic(priv->hw,
+                                                  ath9k_htc_vif_iter, priv);
+       if (priv->rearm_ani)
+               ath9k_htc_start_ani(priv);
+
+       if (priv->reconfig_beacon) {
+               ath9k_htc_ps_wakeup(priv);
+               ath9k_htc_beacon_reconfig(priv);
+               ath9k_htc_ps_restore(priv);
+       }
+}
+
+static void ath9k_htc_bssid_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
+{
+       struct ath9k_vif_iter_data *iter_data = data;
+       int i;
+
+       for (i = 0; i < ETH_ALEN; i++)
+               iter_data->mask[i] &= ~(iter_data->hw_macaddr[i] ^ mac[i]);
+}
+
+static void ath9k_htc_set_bssid_mask(struct ath9k_htc_priv *priv,
+                                    struct ieee80211_vif *vif)
+{
+       struct ath_common *common = ath9k_hw_common(priv->ah);
+       struct ath9k_vif_iter_data iter_data;
+
+       /*
+        * Use the hardware MAC address as reference, the hardware uses it
+        * together with the BSSID mask when matching addresses.
+        */
+       iter_data.hw_macaddr = common->macaddr;
+       memset(&iter_data.mask, 0xff, ETH_ALEN);
+
+       if (vif)
+               ath9k_htc_bssid_iter(&iter_data, vif->addr, vif);
+
+       /* Get list of all active MAC addresses */
+       ieee80211_iterate_active_interfaces_atomic(priv->hw, ath9k_htc_bssid_iter,
+                                                  &iter_data);
+
+       memcpy(common->bssidmask, iter_data.mask, ETH_ALEN);
+       ath_hw_setbssidmask(common);
+}
+
+static void ath9k_htc_set_opmode(struct ath9k_htc_priv *priv)
+{
+       if (priv->num_ibss_vif)
+               priv->ah->opmode = NL80211_IFTYPE_ADHOC;
+       else if (priv->num_ap_vif)
+               priv->ah->opmode = NL80211_IFTYPE_AP;
+       else
+               priv->ah->opmode = NL80211_IFTYPE_STATION;
+
+       ath9k_hw_setopmode(priv->ah);
+}
+
 void ath9k_htc_reset(struct ath9k_htc_priv *priv)
 {
        struct ath_hw *ah = priv->ah;
@@ -119,9 +195,7 @@ void ath9k_htc_reset(struct ath9k_htc_priv *priv)
        mutex_lock(&priv->mutex);
        ath9k_htc_ps_wakeup(priv);
 
-       if (priv->op_flags & OP_ASSOCIATED)
-               cancel_delayed_work_sync(&priv->ath9k_ani_work);
-
+       ath9k_htc_stop_ani(priv);
        ieee80211_stop_queues(priv->hw);
        htc_stop(priv->htc);
        WMI_CMD(WMI_DISABLE_INTR_CMDID);
@@ -148,12 +222,7 @@ void ath9k_htc_reset(struct ath9k_htc_priv *priv)
 
        WMI_CMD(WMI_ENABLE_INTR_CMDID);
        htc_start(priv->htc);
-
-       if (priv->op_flags & OP_ASSOCIATED) {
-               ath9k_htc_beacon_config(priv, priv->vif);
-               ath_start_ani(priv);
-       }
-
+       ath9k_htc_vif_reconfig(priv);
        ieee80211_wake_queues(priv->hw);
 
        ath9k_htc_ps_restore(priv);
@@ -222,11 +291,23 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
                goto err;
 
        htc_start(priv->htc);
+
+       if (!(priv->op_flags & OP_SCANNING) &&
+           !(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL))
+               ath9k_htc_vif_reconfig(priv);
+
 err:
        ath9k_htc_ps_restore(priv);
        return ret;
 }
 
+/*
+ * Monitor mode handling is a tad complicated because the firmware requires
+ * an interface to be created exclusively, while mac80211 doesn't associate
+ * an interface with the mode.
+ *
+ * So, for now, only one monitor interface can be configured.
+ */
 static void __ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv)
 {
        struct ath_common *common = ath9k_hw_common(priv->ah);
@@ -236,9 +317,10 @@ static void __ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv)
 
        memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
        memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
-       hvif.index = 0; /* Should do for now */
+       hvif.index = priv->mon_vif_idx;
        WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
        priv->nvifs--;
+       priv->vif_slot &= ~(1 << priv->mon_vif_idx);
 }
 
 static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv)
@@ -246,70 +328,87 @@ static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv)
        struct ath_common *common = ath9k_hw_common(priv->ah);
        struct ath9k_htc_target_vif hvif;
        struct ath9k_htc_target_sta tsta;
-       int ret = 0;
+       int ret = 0, sta_idx;
        u8 cmd_rsp;
 
-       if (priv->nvifs > 0)
-               return -ENOBUFS;
+       if ((priv->nvifs >= ATH9K_HTC_MAX_VIF) ||
+           (priv->nstations >= ATH9K_HTC_MAX_STA)) {
+               ret = -ENOBUFS;
+               goto err_vif;
+       }
 
-       if (priv->nstations >= ATH9K_HTC_MAX_STA)
-               return -ENOBUFS;
+       sta_idx = ffz(priv->sta_slot);
+       if ((sta_idx < 0) || (sta_idx > ATH9K_HTC_MAX_STA)) {
+               ret = -ENOBUFS;
+               goto err_vif;
+       }
 
        /*
         * Add an interface.
         */
-
        memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
        memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
 
        hvif.opmode = cpu_to_be32(HTC_M_MONITOR);
-       priv->ah->opmode = NL80211_IFTYPE_MONITOR;
-       hvif.index = priv->nvifs;
+       hvif.index = ffz(priv->vif_slot);
 
        WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif);
        if (ret)
-               return ret;
+               goto err_vif;
+
+       /*
+        * Assign the monitor interface index as a special case here.
+        * This is needed when the interface is brought down.
+        */
+       priv->mon_vif_idx = hvif.index;
+       priv->vif_slot |= (1 << hvif.index);
+
+       /*
+        * Set the hardware mode to monitor only if there are no
+        * other interfaces.
+        */
+       if (!priv->nvifs)
+               priv->ah->opmode = NL80211_IFTYPE_MONITOR;
 
        priv->nvifs++;
 
        /*
         * Associate a station with the interface for packet injection.
         */
-
        memset(&tsta, 0, sizeof(struct ath9k_htc_target_sta));
 
        memcpy(&tsta.macaddr, common->macaddr, ETH_ALEN);
 
        tsta.is_vif_sta = 1;
-       tsta.sta_index = priv->nstations;
+       tsta.sta_index = sta_idx;
        tsta.vif_index = hvif.index;
        tsta.maxampdu = 0xffff;
 
        WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta);
        if (ret) {
                ath_err(common, "Unable to add station entry for monitor mode\n");
-               goto err_vif;
+               goto err_sta;
        }
 
+       priv->sta_slot |= (1 << sta_idx);
        priv->nstations++;
-
-       /*
-        * Set chainmask etc. on the target.
-        */
-       ret = ath9k_htc_update_cap_target(priv);
-       if (ret)
-               ath_dbg(common, ATH_DBG_CONFIG,
-                       "Failed to update capability in target\n");
-
+       priv->vif_sta_pos[priv->mon_vif_idx] = sta_idx;
        priv->ah->is_monitoring = true;
 
+       ath_dbg(common, ATH_DBG_CONFIG,
+               "Attached a monitor interface at idx: %d, sta idx: %d\n",
+               priv->mon_vif_idx, sta_idx);
+
        return 0;
 
-err_vif:
+err_sta:
        /*
         * Remove the interface from the target.
         */
        __ath9k_htc_remove_monitor_interface(priv);
+err_vif:
+       ath_dbg(common, ATH_DBG_FATAL, "Unable to attach a monitor interface\n");
+
        return ret;
 }
 
@@ -321,7 +420,7 @@ static int ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv)
 
        __ath9k_htc_remove_monitor_interface(priv);
 
-       sta_idx = 0; /* Only single interface, for now */
+       sta_idx = priv->vif_sta_pos[priv->mon_vif_idx];
 
        WMI_CMD_BUF(WMI_NODE_REMOVE_CMDID, &sta_idx);
        if (ret) {
@@ -329,9 +428,14 @@ static int ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv)
                return ret;
        }
 
+       priv->sta_slot &= ~(1 << sta_idx);
        priv->nstations--;
        priv->ah->is_monitoring = false;
 
+       ath_dbg(common, ATH_DBG_CONFIG,
+               "Removed a monitor interface at idx: %d, sta idx: %d\n",
+               priv->mon_vif_idx, sta_idx);
+
        return 0;
 }
 
@@ -343,12 +447,16 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,
        struct ath9k_htc_target_sta tsta;
        struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *) vif->drv_priv;
        struct ath9k_htc_sta *ista;
-       int ret;
+       int ret, sta_idx;
        u8 cmd_rsp;
 
        if (priv->nstations >= ATH9K_HTC_MAX_STA)
                return -ENOBUFS;
 
+       sta_idx = ffz(priv->sta_slot);
+       if ((sta_idx < 0) || (sta_idx > ATH9K_HTC_MAX_STA))
+               return -ENOBUFS;
+
        memset(&tsta, 0, sizeof(struct ath9k_htc_target_sta));
 
        if (sta) {
@@ -358,13 +466,13 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,
                tsta.associd = common->curaid;
                tsta.is_vif_sta = 0;
                tsta.valid = true;
-               ista->index = priv->nstations;
+               ista->index = sta_idx;
        } else {
                memcpy(&tsta.macaddr, vif->addr, ETH_ALEN);
                tsta.is_vif_sta = 1;
        }
 
-       tsta.sta_index = priv->nstations;
+       tsta.sta_index = sta_idx;
        tsta.vif_index = avp->index;
        tsta.maxampdu = 0xffff;
        if (sta && sta->ht_cap.ht_supported)
@@ -379,12 +487,21 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,
                return ret;
        }
 
-       if (sta)
+       if (sta) {
                ath_dbg(common, ATH_DBG_CONFIG,
                        "Added a station entry for: %pM (idx: %d)\n",
                        sta->addr, tsta.sta_index);
+       } else {
+               ath_dbg(common, ATH_DBG_CONFIG,
+                       "Added a station entry for VIF %d (idx: %d)\n",
+                       avp->index, tsta.sta_index);
+       }
 
+       priv->sta_slot |= (1 << sta_idx);
        priv->nstations++;
+       if (!sta)
+               priv->vif_sta_pos[avp->index] = sta_idx;
+
        return 0;
 }
 
@@ -393,6 +510,7 @@ static int ath9k_htc_remove_station(struct ath9k_htc_priv *priv,
                                    struct ieee80211_sta *sta)
 {
        struct ath_common *common = ath9k_hw_common(priv->ah);
+       struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *) vif->drv_priv;
        struct ath9k_htc_sta *ista;
        int ret;
        u8 cmd_rsp, sta_idx;
@@ -401,7 +519,7 @@ static int ath9k_htc_remove_station(struct ath9k_htc_priv *priv,
                ista = (struct ath9k_htc_sta *) sta->drv_priv;
                sta_idx = ista->index;
        } else {
-               sta_idx = 0;
+               sta_idx = priv->vif_sta_pos[avp->index];
        }
 
        WMI_CMD_BUF(WMI_NODE_REMOVE_CMDID, &sta_idx);
@@ -413,12 +531,19 @@ static int ath9k_htc_remove_station(struct ath9k_htc_priv *priv,
                return ret;
        }
 
-       if (sta)
+       if (sta) {
                ath_dbg(common, ATH_DBG_CONFIG,
                        "Removed a station entry for: %pM (idx: %d)\n",
                        sta->addr, sta_idx);
+       } else {
+               ath_dbg(common, ATH_DBG_CONFIG,
+                       "Removed a station entry for VIF %d (idx: %d)\n",
+                       avp->index, sta_idx);
+       }
 
+       priv->sta_slot &= ~(1 << sta_idx);
        priv->nstations--;
+
        return 0;
 }
 
@@ -800,7 +925,7 @@ void ath9k_htc_debug_remove_root(void)
 /* ANI */
 /*******/
 
-void ath_start_ani(struct ath9k_htc_priv *priv)
+void ath9k_htc_start_ani(struct ath9k_htc_priv *priv)
 {
        struct ath_common *common = ath9k_hw_common(priv->ah);
        unsigned long timestamp = jiffies_to_msecs(jiffies);
@@ -809,15 +934,22 @@ void ath_start_ani(struct ath9k_htc_priv *priv)
        common->ani.shortcal_timer = timestamp;
        common->ani.checkani_timer = timestamp;
 
-       ieee80211_queue_delayed_work(common->hw, &priv->ath9k_ani_work,
+       priv->op_flags |= OP_ANI_RUNNING;
+
+       ieee80211_queue_delayed_work(common->hw, &priv->ani_work,
                                     msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
 }
 
-void ath9k_ani_work(struct work_struct *work)
+void ath9k_htc_stop_ani(struct ath9k_htc_priv *priv)
+{
+       cancel_delayed_work_sync(&priv->ani_work);
+       priv->op_flags &= ~OP_ANI_RUNNING;
+}
+
+void ath9k_htc_ani_work(struct work_struct *work)
 {
        struct ath9k_htc_priv *priv =
-               container_of(work, struct ath9k_htc_priv,
-                            ath9k_ani_work.work);
+               container_of(work, struct ath9k_htc_priv, ani_work.work);
        struct ath_hw *ah = priv->ah;
        struct ath_common *common = ath9k_hw_common(ah);
        bool longcal = false;
@@ -826,7 +958,8 @@ void ath9k_ani_work(struct work_struct *work)
        unsigned int timestamp = jiffies_to_msecs(jiffies);
        u32 cal_interval, short_cal_interval;
 
-       short_cal_interval = ATH_STA_SHORT_CALINTERVAL;
+       short_cal_interval = (ah->opmode == NL80211_IFTYPE_AP) ?
+               ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL;
 
        /* Only calibrate if awake */
        if (ah->power_mode != ATH9K_PM_AWAKE)
@@ -895,7 +1028,7 @@ set_timer:
        if (!common->ani.caldone)
                cal_interval = min(cal_interval, (u32)short_cal_interval);
 
-       ieee80211_queue_delayed_work(common->hw, &priv->ath9k_ani_work,
+       ieee80211_queue_delayed_work(common->hw, &priv->ani_work,
                                     msecs_to_jiffies(cal_interval));
 }
 
@@ -903,7 +1036,7 @@ set_timer:
 /* mac80211 Callbacks */
 /**********************/
 
-static int ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+static void ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
        struct ieee80211_hdr *hdr;
        struct ath9k_htc_priv *priv = hw->priv;
@@ -916,7 +1049,7 @@ static int ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
        padsize = padpos & 3;
        if (padsize && skb->len > padpos) {
                if (skb_headroom(skb) < padsize)
-                       return -1;
+                       goto fail_tx;
                skb_push(skb, padsize);
                memmove(skb->data, skb->data + padsize, padpos);
        }
@@ -937,11 +1070,10 @@ static int ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
                goto fail_tx;
        }
 
-       return 0;
+       return;
 
 fail_tx:
        dev_kfree_skb_any(skb);
-       return 0;
 }
 
 static int ath9k_htc_start(struct ieee80211_hw *hw)
@@ -990,6 +1122,11 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
 
        ath9k_host_rx_init(priv);
 
+       ret = ath9k_htc_update_cap_target(priv);
+       if (ret)
+               ath_dbg(common, ATH_DBG_CONFIG,
+                       "Failed to update capability in target\n");
+
        priv->op_flags &= ~OP_INVALID;
        htc_start(priv->htc);
 
@@ -1044,26 +1181,21 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
        cancel_work_sync(&priv->fatal_work);
        cancel_work_sync(&priv->ps_work);
        cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
-       cancel_delayed_work_sync(&priv->ath9k_ani_work);
+       ath9k_htc_stop_ani(priv);
        ath9k_led_stop_brightness(priv);
 
        mutex_lock(&priv->mutex);
 
-       /* Remove monitor interface here */
-       if (ah->opmode == NL80211_IFTYPE_MONITOR) {
-               if (ath9k_htc_remove_monitor_interface(priv))
-                       ath_err(common, "Unable to remove monitor interface\n");
-               else
-                       ath_dbg(common, ATH_DBG_CONFIG,
-                               "Monitor interface removed\n");
-       }
-
        if (ah->btcoex_hw.enabled) {
                ath9k_hw_btcoex_disable(ah);
                if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
                        ath_htc_cancel_btcoex_work(priv);
        }
 
+       /* Remove a monitor interface if it's present. */
+       if (priv->ah->is_monitoring)
+               ath9k_htc_remove_monitor_interface(priv);
+
        ath9k_hw_phy_disable(ah);
        ath9k_hw_disable(ah);
        ath9k_htc_ps_restore(priv);
@@ -1087,10 +1219,24 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw,
 
        mutex_lock(&priv->mutex);
 
-       /* Only one interface for now */
-       if (priv->nvifs > 0) {
-               ret = -ENOBUFS;
-               goto out;
+       if (priv->nvifs >= ATH9K_HTC_MAX_VIF) {
+               mutex_unlock(&priv->mutex);
+               return -ENOBUFS;
+       }
+
+       if (priv->num_ibss_vif ||
+           (priv->nvifs && vif->type == NL80211_IFTYPE_ADHOC)) {
+               ath_err(common, "IBSS coexistence with other modes is not allowed\n");
+               mutex_unlock(&priv->mutex);
+               return -ENOBUFS;
+       }
+
+       if (((vif->type == NL80211_IFTYPE_AP) ||
+            (vif->type == NL80211_IFTYPE_ADHOC)) &&
+           ((priv->num_ap_vif + priv->num_ibss_vif) >= ATH9K_HTC_MAX_BCN_VIF)) {
+               ath_err(common, "Max. number of beaconing interfaces reached\n");
+               mutex_unlock(&priv->mutex);
+               return -ENOBUFS;
        }
 
        ath9k_htc_ps_wakeup(priv);
@@ -1104,6 +1250,9 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw,
        case NL80211_IFTYPE_ADHOC:
                hvif.opmode = cpu_to_be32(HTC_M_IBSS);
                break;
+       case NL80211_IFTYPE_AP:
+               hvif.opmode = cpu_to_be32(HTC_M_HOSTAP);
+               break;
        default:
                ath_err(common,
                        "Interface type %d not yet supported\n", vif->type);
@@ -1111,34 +1260,39 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw,
                goto out;
        }
 
-       ath_dbg(common, ATH_DBG_CONFIG,
-               "Attach a VIF of type: %d\n", vif->type);
-
-       priv->ah->opmode = vif->type;
-
        /* Index starts from zero on the target */
-       avp->index = hvif.index = priv->nvifs;
+       avp->index = hvif.index = ffz(priv->vif_slot);
        hvif.rtsthreshold = cpu_to_be16(2304);
        WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif);
        if (ret)
                goto out;
 
-       priv->nvifs++;
-
        /*
         * We need a node in target to tx mgmt frames
         * before association.
         */
        ret = ath9k_htc_add_station(priv, vif, NULL);
-       if (ret)
+       if (ret) {
+               WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
                goto out;
+       }
 
-       ret = ath9k_htc_update_cap_target(priv);
-       if (ret)
-               ath_dbg(common, ATH_DBG_CONFIG,
-                       "Failed to update capability in target\n");
+       ath9k_htc_set_bssid_mask(priv, vif);
 
+       priv->vif_slot |= (1 << avp->index);
+       priv->nvifs++;
        priv->vif = vif;
+
+       INC_VIF(priv, vif->type);
+       ath9k_htc_set_opmode(priv);
+
+       if ((priv->ah->opmode == NL80211_IFTYPE_AP) &&
+           !(priv->op_flags & OP_ANI_RUNNING))
+               ath9k_htc_start_ani(priv);
+
+       ath_dbg(common, ATH_DBG_CONFIG,
+               "Attach a VIF of type: %d at idx: %d\n", vif->type, avp->index);
+
 out:
        ath9k_htc_ps_restore(priv);
        mutex_unlock(&priv->mutex);
@@ -1156,8 +1310,6 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,
        int ret = 0;
        u8 cmd_rsp;
 
-       ath_dbg(common, ATH_DBG_CONFIG, "Detach Interface\n");
-
        mutex_lock(&priv->mutex);
        ath9k_htc_ps_wakeup(priv);
 
@@ -1166,10 +1318,27 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,
        hvif.index = avp->index;
        WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
        priv->nvifs--;
+       priv->vif_slot &= ~(1 << avp->index);
 
        ath9k_htc_remove_station(priv, vif, NULL);
        priv->vif = NULL;
 
+       DEC_VIF(priv, vif->type);
+       ath9k_htc_set_opmode(priv);
+
+       /*
+        * Stop ANI only if there are no associated station interfaces.
+        */
+       if ((vif->type == NL80211_IFTYPE_AP) && (priv->num_ap_vif == 0)) {
+               priv->rearm_ani = false;
+               ieee80211_iterate_active_interfaces_atomic(priv->hw,
+                                                  ath9k_htc_vif_iter, priv);
+               if (!priv->rearm_ani)
+                       ath9k_htc_stop_ani(priv);
+       }
+
+       ath_dbg(common, ATH_DBG_CONFIG, "Detach Interface at idx: %d\n", avp->index);
+
        ath9k_htc_ps_restore(priv);
        mutex_unlock(&priv->mutex);
 }
@@ -1205,13 +1374,11 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
         * IEEE80211_CONF_CHANGE_CHANNEL is handled.
         */
        if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
-               if (conf->flags & IEEE80211_CONF_MONITOR) {
-                       if (ath9k_htc_add_monitor_interface(priv))
-                               ath_err(common, "Failed to set monitor mode\n");
-                       else
-                               ath_dbg(common, ATH_DBG_CONFIG,
-                                       "HW opmode set to Monitor mode\n");
-               }
+               if ((conf->flags & IEEE80211_CONF_MONITOR) &&
+                   !priv->ah->is_monitoring)
+                       ath9k_htc_add_monitor_interface(priv);
+               else if (priv->ah->is_monitoring)
+                       ath9k_htc_remove_monitor_interface(priv);
        }
 
        if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
@@ -1434,66 +1601,81 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
        struct ath9k_htc_priv *priv = hw->priv;
        struct ath_hw *ah = priv->ah;
        struct ath_common *common = ath9k_hw_common(ah);
+       bool set_assoc;
 
        mutex_lock(&priv->mutex);
        ath9k_htc_ps_wakeup(priv);
 
+       /*
+        * Set the HW AID/BSSID only for the first station interface
+        * or in IBSS mode.
+        */
+       set_assoc = !!((priv->ah->opmode == NL80211_IFTYPE_ADHOC) ||
+                      ((priv->ah->opmode == NL80211_IFTYPE_STATION) &&
+                       (priv->num_sta_vif == 1)));
+
+
        if (changed & BSS_CHANGED_ASSOC) {
-               common->curaid = bss_conf->assoc ?
-                                bss_conf->aid : 0;
-               ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
-                       bss_conf->assoc);
-
-               if (bss_conf->assoc) {
-                       priv->op_flags |= OP_ASSOCIATED;
-                       ath_start_ani(priv);
-               } else {
-                       priv->op_flags &= ~OP_ASSOCIATED;
-                       cancel_delayed_work_sync(&priv->ath9k_ani_work);
+               if (set_assoc) {
+                       ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
+                               bss_conf->assoc);
+
+                       common->curaid = bss_conf->assoc ?
+                               bss_conf->aid : 0;
+
+                       if (bss_conf->assoc)
+                               ath9k_htc_start_ani(priv);
+                       else
+                               ath9k_htc_stop_ani(priv);
                }
        }
 
        if (changed & BSS_CHANGED_BSSID) {
-               /* Set BSSID */
-               memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
-               ath9k_hw_write_associd(ah);
+               if (set_assoc) {
+                       memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
+                       ath9k_hw_write_associd(ah);
 
-               ath_dbg(common, ATH_DBG_CONFIG,
-                       "BSSID: %pM aid: 0x%x\n",
-                       common->curbssid, common->curaid);
+                       ath_dbg(common, ATH_DBG_CONFIG,
+                               "BSSID: %pM aid: 0x%x\n",
+                               common->curbssid, common->curaid);
+               }
        }
 
-       if ((changed & BSS_CHANGED_BEACON_INT) ||
-           (changed & BSS_CHANGED_BEACON) ||
-           ((changed & BSS_CHANGED_BEACON_ENABLED) &&
-           bss_conf->enable_beacon)) {
+       if ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon) {
+               ath_dbg(common, ATH_DBG_CONFIG,
+                       "Beacon enabled for BSS: %pM\n", bss_conf->bssid);
                priv->op_flags |= OP_ENABLE_BEACON;
                ath9k_htc_beacon_config(priv, vif);
        }
 
-       if ((changed & BSS_CHANGED_BEACON_ENABLED) &&
-           !bss_conf->enable_beacon) {
-               priv->op_flags &= ~OP_ENABLE_BEACON;
-               ath9k_htc_beacon_config(priv, vif);
-       }
-
-       if (changed & BSS_CHANGED_ERP_PREAMBLE) {
-               ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n",
-                       bss_conf->use_short_preamble);
-               if (bss_conf->use_short_preamble)
-                       priv->op_flags |= OP_PREAMBLE_SHORT;
-               else
-                       priv->op_flags &= ~OP_PREAMBLE_SHORT;
+       if ((changed & BSS_CHANGED_BEACON_ENABLED) && !bss_conf->enable_beacon) {
+               /*
+                * Disable SWBA interrupt only if there are no
+                * AP/IBSS interfaces.
+                */
+               if ((priv->num_ap_vif <= 1) || priv->num_ibss_vif) {
+                       ath_dbg(common, ATH_DBG_CONFIG,
+                               "Beacon disabled for BSS: %pM\n",
+                               bss_conf->bssid);
+                       priv->op_flags &= ~OP_ENABLE_BEACON;
+                       ath9k_htc_beacon_config(priv, vif);
+               }
        }
 
-       if (changed & BSS_CHANGED_ERP_CTS_PROT) {
-               ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n",
-                       bss_conf->use_cts_prot);
-               if (bss_conf->use_cts_prot &&
-                   hw->conf.channel->band != IEEE80211_BAND_5GHZ)
-                       priv->op_flags |= OP_PROTECT_ENABLE;
-               else
-                       priv->op_flags &= ~OP_PROTECT_ENABLE;
+       if (changed & BSS_CHANGED_BEACON_INT) {
+               /*
+                * Reset the HW TSF for the first AP interface.
+                */
+               if ((priv->ah->opmode == NL80211_IFTYPE_AP) &&
+                   (priv->nvifs == 1) &&
+                   (priv->num_ap_vif == 1) &&
+                   (vif->type == NL80211_IFTYPE_AP)) {
+                       priv->op_flags |= OP_TSF_RESET;
+               }
+               ath_dbg(common, ATH_DBG_CONFIG,
+                       "Beacon interval changed for BSS: %pM\n",
+                       bss_conf->bssid);
+               ath9k_htc_beacon_config(priv, vif);
        }
 
        if (changed & BSS_CHANGED_ERP_SLOT) {
@@ -1558,6 +1740,8 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,
        struct ath9k_htc_sta *ista;
        int ret = 0;
 
+       mutex_lock(&priv->mutex);
+
        switch (action) {
        case IEEE80211_AMPDU_RX_START:
                break;
@@ -1582,6 +1766,8 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,
                ath_err(ath9k_hw_common(priv->ah), "Unknown AMPDU action\n");
        }
 
+       mutex_unlock(&priv->mutex);
+
        return ret;
 }
 
@@ -1594,8 +1780,7 @@ static void ath9k_htc_sw_scan_start(struct ieee80211_hw *hw)
        priv->op_flags |= OP_SCANNING;
        spin_unlock_bh(&priv->beacon_lock);
        cancel_work_sync(&priv->ps_work);
-       if (priv->op_flags & OP_ASSOCIATED)
-               cancel_delayed_work_sync(&priv->ath9k_ani_work);
+       ath9k_htc_stop_ani(priv);
        mutex_unlock(&priv->mutex);
 }
 
@@ -1604,14 +1789,11 @@ static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw)
        struct ath9k_htc_priv *priv = hw->priv;
 
        mutex_lock(&priv->mutex);
-       ath9k_htc_ps_wakeup(priv);
        spin_lock_bh(&priv->beacon_lock);
        priv->op_flags &= ~OP_SCANNING;
        spin_unlock_bh(&priv->beacon_lock);
-       if (priv->op_flags & OP_ASSOCIATED) {
-               ath9k_htc_beacon_config(priv, priv->vif);
-               ath_start_ani(priv);
-       }
+       ath9k_htc_ps_wakeup(priv);
+       ath9k_htc_vif_reconfig(priv);
        ath9k_htc_ps_restore(priv);
        mutex_unlock(&priv->mutex);
 }
index 7a5ffca..4a4f27b 100644 (file)
@@ -84,7 +84,9 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb)
        struct ieee80211_hdr *hdr;
        struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
        struct ieee80211_sta *sta = tx_info->control.sta;
+       struct ieee80211_vif *vif = tx_info->control.vif;
        struct ath9k_htc_sta *ista;
+       struct ath9k_htc_vif *avp;
        struct ath9k_htc_tx_ctl tx_ctl;
        enum htc_endpoint_id epid;
        u16 qnum;
@@ -95,18 +97,31 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb)
        hdr = (struct ieee80211_hdr *) skb->data;
        fc = hdr->frame_control;
 
-       if (tx_info->control.vif &&
-                       (struct ath9k_htc_vif *) tx_info->control.vif->drv_priv)
-               vif_idx = ((struct ath9k_htc_vif *)
-                               tx_info->control.vif->drv_priv)->index;
-       else
-               vif_idx = priv->nvifs;
+       /*
+        * Find out on which interface this packet has to be
+        * sent out.
+        */
+       if (vif) {
+               avp = (struct ath9k_htc_vif *) vif->drv_priv;
+               vif_idx = avp->index;
+       } else {
+               if (!priv->ah->is_monitoring) {
+                       ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT,
+                               "VIF is null, but no monitor interface !\n");
+                       return -EINVAL;
+               }
 
+               vif_idx = priv->mon_vif_idx;
+       }
+
+       /*
+        * Find out which station this packet is destined for.
+        */
        if (sta) {
                ista = (struct ath9k_htc_sta *) sta->drv_priv;
                sta_idx = ista->index;
        } else {
-               sta_idx = 0;
+               sta_idx = priv->vif_sta_pos[vif_idx];
        }
 
        memset(&tx_ctl, 0, sizeof(struct ath9k_htc_tx_ctl));
@@ -141,7 +156,7 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb)
 
                /* CTS-to-self */
                if (!(flags & ATH9K_HTC_TX_RTSCTS) &&
-                   (priv->op_flags & OP_PROTECT_ENABLE))
+                   (vif && vif->bss_conf.use_cts_prot))
                        flags |= ATH9K_HTC_TX_CTSONLY;
 
                tx_hdr.flags = cpu_to_be32(flags);
@@ -217,6 +232,7 @@ static bool ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv,
 void ath9k_tx_tasklet(unsigned long data)
 {
        struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
+       struct ieee80211_vif *vif;
        struct ieee80211_sta *sta;
        struct ieee80211_hdr *hdr;
        struct ieee80211_tx_info *tx_info;
@@ -228,12 +244,16 @@ void ath9k_tx_tasklet(unsigned long data)
                hdr = (struct ieee80211_hdr *) skb->data;
                fc = hdr->frame_control;
                tx_info = IEEE80211_SKB_CB(skb);
+               vif = tx_info->control.vif;
 
                memset(&tx_info->status, 0, sizeof(tx_info->status));
 
+               if (!vif)
+                       goto send_mac80211;
+
                rcu_read_lock();
 
-               sta = ieee80211_find_sta(priv->vif, hdr->addr1);
+               sta = ieee80211_find_sta(vif, hdr->addr1);
                if (!sta) {
                        rcu_read_unlock();
                        ieee80211_tx_status(priv->hw, skb);
@@ -263,6 +283,7 @@ void ath9k_tx_tasklet(unsigned long data)
 
                rcu_read_unlock();
 
+       send_mac80211:
                /* Send status to mac80211 */
                ieee80211_tx_status(priv->hw, skb);
        }
@@ -386,7 +407,7 @@ u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv)
         */
        if (((ah->opmode != NL80211_IFTYPE_AP) &&
             (priv->rxfilter & FIF_PROMISC_IN_BSS)) ||
-           (ah->opmode == NL80211_IFTYPE_MONITOR))
+           ah->is_monitoring)
                rfilt |= ATH9K_RX_FILTER_PROM;
 
        if (priv->rxfilter & FIF_CONTROL)
@@ -398,8 +419,13 @@ u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv)
        else
                rfilt |= ATH9K_RX_FILTER_BEACON;
 
-       if (conf_is_ht(&priv->hw->conf))
+       if (conf_is_ht(&priv->hw->conf)) {
                rfilt |= ATH9K_RX_FILTER_COMP_BAR;
+               rfilt |= ATH9K_RX_FILTER_UNCOMP_BA_BAR;
+       }
+
+       if (priv->rxfilter & FIF_PSPOLL)
+               rfilt |= ATH9K_RX_FILTER_PSPOLL;
 
        return rfilt;
 
@@ -412,20 +438,12 @@ u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv)
 static void ath9k_htc_opmode_init(struct ath9k_htc_priv *priv)
 {
        struct ath_hw *ah = priv->ah;
-       struct ath_common *common = ath9k_hw_common(ah);
-
        u32 rfilt, mfilt[2];
 
        /* configure rx filter */
        rfilt = ath9k_htc_calcrxfilter(priv);
        ath9k_hw_setrxfilter(ah, rfilt);
 
-       /* configure bssid mask */
-       ath_hw_setbssidmask(common);
-
-       /* configure operational mode */
-       ath9k_hw_setopmode(ah);
-
        /* calculate and install multicast filter */
        mfilt[0] = mfilt[1] = ~0;
        ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]);
@@ -576,31 +594,29 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv,
        ath9k_process_rate(hw, rx_status, rxbuf->rxstatus.rs_rate,
                           rxbuf->rxstatus.rs_flags);
 
-       if (priv->op_flags & OP_ASSOCIATED) {
-               if (rxbuf->rxstatus.rs_rssi != ATH9K_RSSI_BAD &&
-                   !rxbuf->rxstatus.rs_moreaggr)
-                       ATH_RSSI_LPF(priv->rx.last_rssi,
-                                    rxbuf->rxstatus.rs_rssi);
+       if (rxbuf->rxstatus.rs_rssi != ATH9K_RSSI_BAD &&
+           !rxbuf->rxstatus.rs_moreaggr)
+               ATH_RSSI_LPF(priv->rx.last_rssi,
+                            rxbuf->rxstatus.rs_rssi);
 
-               last_rssi = priv->rx.last_rssi;
+       last_rssi = priv->rx.last_rssi;
 
-               if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
-                       rxbuf->rxstatus.rs_rssi = ATH_EP_RND(last_rssi,
-                                                            ATH_RSSI_EP_MULTIPLIER);
+       if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
+               rxbuf->rxstatus.rs_rssi = ATH_EP_RND(last_rssi,
+                                                    ATH_RSSI_EP_MULTIPLIER);
 
-               if (rxbuf->rxstatus.rs_rssi < 0)
-                       rxbuf->rxstatus.rs_rssi = 0;
+       if (rxbuf->rxstatus.rs_rssi < 0)
+               rxbuf->rxstatus.rs_rssi = 0;
 
-               if (ieee80211_is_beacon(fc))
-                       priv->ah->stats.avgbrssi = rxbuf->rxstatus.rs_rssi;
-       }
+       if (ieee80211_is_beacon(fc))
+               priv->ah->stats.avgbrssi = rxbuf->rxstatus.rs_rssi;
 
        rx_status->mactime = be64_to_cpu(rxbuf->rxstatus.rs_tstamp);
        rx_status->band = hw->conf.channel->band;
        rx_status->freq = hw->conf.channel->center_freq;
        rx_status->signal =  rxbuf->rxstatus.rs_rssi + ATH_DEFAULT_NOISE_FLOOR;
        rx_status->antenna = rxbuf->rxstatus.rs_antenna;
-       rx_status->flag |= RX_FLAG_TSFT;
+       rx_status->flag |= RX_FLAG_MACTIME_MPDU;
 
        return true;
 
index f66c882..79aec98 100644 (file)
@@ -140,6 +140,21 @@ static struct ieee80211_rate ath9k_legacy_rates[] = {
        RATE(540, 0x0c, 0),
 };
 
+#ifdef CONFIG_MAC80211_LEDS
+static const struct ieee80211_tpt_blink ath9k_tpt_blink[] = {
+       { .throughput = 0 * 1024, .blink_time = 334 },
+       { .throughput = 1 * 1024, .blink_time = 260 },
+       { .throughput = 5 * 1024, .blink_time = 220 },
+       { .throughput = 10 * 1024, .blink_time = 190 },
+       { .throughput = 20 * 1024, .blink_time = 170 },
+       { .throughput = 50 * 1024, .blink_time = 150 },
+       { .throughput = 70 * 1024, .blink_time = 130 },
+       { .throughput = 100 * 1024, .blink_time = 110 },
+       { .throughput = 200 * 1024, .blink_time = 80 },
+       { .throughput = 300 * 1024, .blink_time = 50 },
+};
+#endif
+
 static void ath9k_deinit_softc(struct ath_softc *sc);
 
 /*
@@ -731,6 +746,13 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
 
        ath9k_init_txpower_limits(sc);
 
+#ifdef CONFIG_MAC80211_LEDS
+       /* must be initialized before ieee80211_register_hw */
+       sc->led_cdev.default_trigger = ieee80211_create_tpt_led_trigger(sc->hw,
+               IEEE80211_TPT_LEDTRIG_FL_RADIO, ath9k_tpt_blink,
+               ARRAY_SIZE(ath9k_tpt_blink));
+#endif
+
        /* Register with mac80211 */
        error = ieee80211_register_hw(hw);
        if (error)
index a715500..2e228aa 100644 (file)
@@ -910,6 +910,8 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
        ath9k_hw_set_gpio(ah, ah->led_pin, 0);
 
        ieee80211_wake_queues(hw);
+       ieee80211_queue_delayed_work(hw, &sc->hw_pll_work, HZ/2);
+
 out:
        spin_unlock_bh(&sc->sc_pcu_lock);
 
@@ -923,6 +925,8 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw)
        int r;
 
        ath9k_ps_wakeup(sc);
+       cancel_delayed_work_sync(&sc->hw_pll_work);
+
        spin_lock_bh(&sc->sc_pcu_lock);
 
        ieee80211_stop_queues(hw);
@@ -1142,8 +1146,7 @@ mutex_unlock:
        return r;
 }
 
-static int ath9k_tx(struct ieee80211_hw *hw,
-                   struct sk_buff *skb)
+static void ath9k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
        struct ath_softc *sc = hw->priv;
        struct ath_common *common = ath9k_hw_common(sc->sc_ah);
@@ -1200,10 +1203,9 @@ static int ath9k_tx(struct ieee80211_hw *hw,
                goto exit;
        }
 
-       return 0;
+       return;
 exit:
        dev_kfree_skb_any(skb);
-       return 0;
 }
 
 static void ath9k_stop(struct ieee80211_hw *hw)
@@ -1214,9 +1216,6 @@ static void ath9k_stop(struct ieee80211_hw *hw)
 
        mutex_lock(&sc->mutex);
 
-       if (led_blink)
-               cancel_delayed_work_sync(&sc->ath_led_blink_work);
-
        cancel_delayed_work_sync(&sc->tx_complete_work);
        cancel_delayed_work_sync(&sc->hw_pll_work);
        cancel_work_sync(&sc->paprd_work);
@@ -2131,7 +2130,7 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop)
 {
 #define ATH_FLUSH_TIMEOUT      60 /* ms */
        struct ath_softc *sc = hw->priv;
-       struct ath_txq *txq;
+       struct ath_txq *txq = NULL;
        struct ath_hw *ah = sc->sc_ah;
        struct ath_common *common = ath9k_hw_common(ah);
        int i, j, npend = 0;
index daf171d..cb559e3 100644 (file)
@@ -983,7 +983,7 @@ static int ath9k_rx_skb_preprocess(struct ath_common *common,
        rx_status->freq = hw->conf.channel->center_freq;
        rx_status->signal = ATH_DEFAULT_NOISE_FLOOR + rx_stats->rs_rssi;
        rx_status->antenna = rx_stats->rs_antenna;
-       rx_status->flag |= RX_FLAG_TSFT;
+       rx_status->flag |= RX_FLAG_MACTIME_MPDU;
 
        return 0;
 }
index 64b226a..8fa8acf 100644 (file)
 enum ath_usb_dev {
        AR9280_USB = 1, /* AR7010 + AR9280, UB94 */
        AR9287_USB = 2, /* AR7010 + AR9287, UB95 */
+       STORAGE_DEVICE = 3,
 };
 
 #define AR_DEVID_7010(_ah) \
index dc862f5..d3d2490 100644 (file)
@@ -123,12 +123,8 @@ void ath9k_deinit_wmi(struct ath9k_htc_priv *priv)
 void ath9k_swba_tasklet(unsigned long data)
 {
        struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
-       struct ath_common *common = ath9k_hw_common(priv->ah);
-
-       ath_dbg(common, ATH_DBG_WMI, "SWBA Event received\n");
 
        ath9k_htc_swba(priv, priv->wmi->beacon_pending);
-
 }
 
 void ath9k_fatal_work(struct work_struct *work)
index 420d437..c6a5fae 100644 (file)
@@ -534,7 +534,7 @@ void carl9170_rx(struct ar9170 *ar, void *buf, unsigned int len);
 void carl9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len);
 
 /* TX */
-int carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
+void carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
 void carl9170_tx_janitor(struct work_struct *work);
 void carl9170_tx_process_status(struct ar9170 *ar,
                                const struct carl9170_rsp *cmd);
index 6f41e21..0ef70b6 100644 (file)
@@ -1339,7 +1339,7 @@ err_unlock_rcu:
        return false;
 }
 
-int carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+void carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
        struct ar9170 *ar = hw->priv;
        struct ieee80211_tx_info *info;
@@ -1373,12 +1373,11 @@ int carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
        }
 
        carl9170_tx(ar);
-       return NETDEV_TX_OK;
+       return;
 
 err_free:
        ar->tx_dropped++;
        dev_kfree_skb_any(skb);
-       return NETDEV_TX_OK;
 }
 
 void carl9170_tx_scheduler(struct ar9170 *ar)
index 22bc9f1..57eb5b6 100644 (file)
@@ -3203,7 +3203,7 @@ static void b43_tx_work(struct work_struct *work)
        mutex_unlock(&wl->mutex);
 }
 
-static int b43_op_tx(struct ieee80211_hw *hw,
+static void b43_op_tx(struct ieee80211_hw *hw,
                     struct sk_buff *skb)
 {
        struct b43_wl *wl = hw_to_b43_wl(hw);
@@ -3211,14 +3211,12 @@ static int b43_op_tx(struct ieee80211_hw *hw,
        if (unlikely(skb->len < 2 + 2 + 6)) {
                /* Too short, this can't be a valid frame. */
                dev_kfree_skb_any(skb);
-               return NETDEV_TX_OK;
+               return;
        }
        B43_WARN_ON(skb_shinfo(skb)->nr_frags);
 
        skb_queue_tail(&wl->tx_queue, skb);
        ieee80211_queue_work(wl->hw, &wl->tx_work);
-
-       return NETDEV_TX_OK;
 }
 
 static void b43_qos_params_upload(struct b43_wldev *dev,
index ab81ed8..9f5a3c9 100644 (file)
@@ -430,9 +430,9 @@ static void b43_radio_init2055_post(struct b43_wldev *dev)
        bool workaround = false;
 
        if (sprom->revision < 4)
-               workaround = (binfo->vendor != PCI_VENDOR_ID_BROADCOM ||
-                               binfo->type != 0x46D ||
-                               binfo->rev < 0x41);
+               workaround = (binfo->vendor != PCI_VENDOR_ID_BROADCOM &&
+                               binfo->type == 0x46D &&
+                               binfo->rev >= 0x41);
        else
                workaround =
                        !(sprom->boardflags2_lo & B43_BFL2_RXBB_INT_REG_DIS);
@@ -1281,17 +1281,17 @@ static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev)
                                                B43_NPHY_TABLE_DATALO, tmp);
                                }
                        }
+               }
 
-                       b43_nphy_set_rf_sequence(dev, 5,
-                                       rfseq_events, rfseq_delays, 3);
-                       b43_phy_maskset(dev, B43_NPHY_OVER_DGAIN1,
-                               ~B43_NPHY_OVER_DGAIN_CCKDGECV & 0xFFFF,
-                               0x5A << B43_NPHY_OVER_DGAIN_CCKDGECV_SHIFT);
+               b43_nphy_set_rf_sequence(dev, 5,
+                               rfseq_events, rfseq_delays, 3);
+               b43_phy_maskset(dev, B43_NPHY_OVER_DGAIN1,
+                       ~B43_NPHY_OVER_DGAIN_CCKDGECV & 0xFFFF,
+                       0x5A << B43_NPHY_OVER_DGAIN_CCKDGECV_SHIFT);
 
-                       if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
-                               b43_phy_maskset(dev, B43_PHY_N(0xC5D),
-                                               0xFF80, 4);
-               }
+               if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
+                       b43_phy_maskset(dev, B43_PHY_N(0xC5D),
+                                       0xFF80, 4);
        }
 }
 
@@ -2128,7 +2128,7 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf,
                save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
                save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B1S0);
                save_regs_phy[7] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B32S1);
-       } else if (dev->phy.rev == 2) {
+       } else {
                save_regs_phy[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1);
                save_regs_phy[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2);
                save_regs_phy[2] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
@@ -2179,7 +2179,7 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf,
                b43_phy_write(dev, B43_NPHY_AFECTL_OVER, save_regs_phy[5]);
                b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S0, save_regs_phy[6]);
                b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S1, save_regs_phy[7]);
-       } else if (dev->phy.rev == 2) {
+       } else {
                b43_phy_write(dev, B43_NPHY_AFECTL_C1, save_regs_phy[0]);
                b43_phy_write(dev, B43_NPHY_AFECTL_C2, save_regs_phy[1]);
                b43_phy_write(dev, B43_NPHY_AFECTL_OVER, save_regs_phy[2]);
index dc8ef09..c42b2ac 100644 (file)
@@ -1097,6 +1097,1080 @@ static const u32 b43_ntab_tmap[] = {
        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 };
 
+/* static tables, PHY revision >= 3 */
+static const u32 b43_ntab_framestruct_r3[] = {
+       0x08004a04, 0x00100000, 0x01000a05, 0x00100020,
+       0x09804506, 0x00100030, 0x09804507, 0x00100030,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x08004a0c, 0x00100004, 0x01000a0d, 0x00100024,
+       0x0980450e, 0x00100034, 0x0980450f, 0x00100034,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000a04, 0x00100000, 0x11008a05, 0x00100020,
+       0x1980c506, 0x00100030, 0x21810506, 0x00100030,
+       0x21810506, 0x00100030, 0x01800504, 0x00100030,
+       0x11808505, 0x00100030, 0x29814507, 0x01100030,
+       0x00000a04, 0x00100000, 0x11008a05, 0x00100020,
+       0x21810506, 0x00100030, 0x21810506, 0x00100030,
+       0x29814507, 0x01100030, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000a0c, 0x00100008, 0x11008a0d, 0x00100028,
+       0x1980c50e, 0x00100038, 0x2181050e, 0x00100038,
+       0x2181050e, 0x00100038, 0x0180050c, 0x00100038,
+       0x1180850d, 0x00100038, 0x2981450f, 0x01100038,
+       0x00000a0c, 0x00100008, 0x11008a0d, 0x00100028,
+       0x2181050e, 0x00100038, 0x2181050e, 0x00100038,
+       0x2981450f, 0x01100038, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x08004a04, 0x00100000, 0x01000a05, 0x00100020,
+       0x1980c506, 0x00100030, 0x1980c506, 0x00100030,
+       0x11808504, 0x00100030, 0x3981ca05, 0x00100030,
+       0x29814507, 0x01100030, 0x00000000, 0x00000000,
+       0x10008a04, 0x00100000, 0x3981ca05, 0x00100030,
+       0x1980c506, 0x00100030, 0x29814507, 0x01100030,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x08004a0c, 0x00100008, 0x01000a0d, 0x00100028,
+       0x1980c50e, 0x00100038, 0x1980c50e, 0x00100038,
+       0x1180850c, 0x00100038, 0x3981ca0d, 0x00100038,
+       0x2981450f, 0x01100038, 0x00000000, 0x00000000,
+       0x10008a0c, 0x00100008, 0x3981ca0d, 0x00100038,
+       0x1980c50e, 0x00100038, 0x2981450f, 0x01100038,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x40021404, 0x00100000, 0x02001405, 0x00100040,
+       0x0b004a06, 0x01900060, 0x13008a06, 0x01900060,
+       0x13008a06, 0x01900060, 0x43020a04, 0x00100060,
+       0x1b00ca05, 0x00100060, 0x23010a07, 0x01500060,
+       0x40021404, 0x00100000, 0x1a00d405, 0x00100040,
+       0x13008a06, 0x01900060, 0x13008a06, 0x01900060,
+       0x23010a07, 0x01500060, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x4002140c, 0x00100010, 0x0200140d, 0x00100050,
+       0x0b004a0e, 0x01900070, 0x13008a0e, 0x01900070,
+       0x13008a0e, 0x01900070, 0x43020a0c, 0x00100070,
+       0x1b00ca0d, 0x00100070, 0x23010a0f, 0x01500070,
+       0x4002140c, 0x00100010, 0x1a00d40d, 0x00100050,
+       0x13008a0e, 0x01900070, 0x13008a0e, 0x01900070,
+       0x23010a0f, 0x01500070, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x50029404, 0x00100000, 0x32019405, 0x00100040,
+       0x0b004a06, 0x01900060, 0x0b004a06, 0x01900060,
+       0x5b02ca04, 0x00100060, 0x3b01d405, 0x00100060,
+       0x23010a07, 0x01500060, 0x00000000, 0x00000000,
+       0x5802d404, 0x00100000, 0x3b01d405, 0x00100060,
+       0x0b004a06, 0x01900060, 0x23010a07, 0x01500060,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x5002940c, 0x00100010, 0x3201940d, 0x00100050,
+       0x0b004a0e, 0x01900070, 0x0b004a0e, 0x01900070,
+       0x5b02ca0c, 0x00100070, 0x3b01d40d, 0x00100070,
+       0x23010a0f, 0x01500070, 0x00000000, 0x00000000,
+       0x5802d40c, 0x00100010, 0x3b01d40d, 0x00100070,
+       0x0b004a0e, 0x01900070, 0x23010a0f, 0x01500070,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x40021404, 0x000f4800, 0x62031405, 0x00100040,
+       0x53028a06, 0x01900060, 0x53028a07, 0x01900060,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x4002140c, 0x000f4808, 0x6203140d, 0x00100048,
+       0x53028a0e, 0x01900068, 0x53028a0f, 0x01900068,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000a0c, 0x00100004, 0x11008a0d, 0x00100024,
+       0x1980c50e, 0x00100034, 0x2181050e, 0x00100034,
+       0x2181050e, 0x00100034, 0x0180050c, 0x00100038,
+       0x1180850d, 0x00100038, 0x1181850d, 0x00100038,
+       0x2981450f, 0x01100038, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000a0c, 0x00100008, 0x11008a0d, 0x00100028,
+       0x2181050e, 0x00100038, 0x2181050e, 0x00100038,
+       0x1181850d, 0x00100038, 0x2981450f, 0x01100038,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x08004a04, 0x00100000, 0x01000a05, 0x00100020,
+       0x0180c506, 0x00100030, 0x0180c506, 0x00100030,
+       0x2180c50c, 0x00100030, 0x49820a0d, 0x0016a130,
+       0x41824a0d, 0x0016a130, 0x2981450f, 0x01100030,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x2000ca0c, 0x00100000, 0x49820a0d, 0x0016a130,
+       0x1980c50e, 0x00100030, 0x41824a0d, 0x0016a130,
+       0x2981450f, 0x01100030, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x4002140c, 0x00100008, 0x0200140d, 0x00100048,
+       0x0b004a0e, 0x01900068, 0x13008a0e, 0x01900068,
+       0x13008a0e, 0x01900068, 0x43020a0c, 0x00100070,
+       0x1b00ca0d, 0x00100070, 0x1b014a0d, 0x00100070,
+       0x23010a0f, 0x01500070, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x4002140c, 0x00100010, 0x1a00d40d, 0x00100050,
+       0x13008a0e, 0x01900070, 0x13008a0e, 0x01900070,
+       0x1b014a0d, 0x00100070, 0x23010a0f, 0x01500070,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x50029404, 0x00100000, 0x32019405, 0x00100040,
+       0x03004a06, 0x01900060, 0x03004a06, 0x01900060,
+       0x6b030a0c, 0x00100060, 0x4b02140d, 0x0016a160,
+       0x4302540d, 0x0016a160, 0x23010a0f, 0x01500060,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x6b03140c, 0x00100060, 0x4b02140d, 0x0016a160,
+       0x0b004a0e, 0x01900060, 0x4302540d, 0x0016a160,
+       0x23010a0f, 0x01500060, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x40021404, 0x00100000, 0x1a00d405, 0x00100040,
+       0x53028a06, 0x01900060, 0x5b02ca06, 0x01900060,
+       0x5b02ca06, 0x01900060, 0x43020a04, 0x00100060,
+       0x1b00ca05, 0x00100060, 0x53028a07, 0x0190c060,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x4002140c, 0x00100010, 0x1a00d40d, 0x00100050,
+       0x53028a0e, 0x01900070, 0x5b02ca0e, 0x01900070,
+       0x5b02ca0e, 0x01900070, 0x43020a0c, 0x00100070,
+       0x1b00ca0d, 0x00100070, 0x53028a0f, 0x0190c070,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x40021404, 0x00100000, 0x1a00d405, 0x00100040,
+       0x5b02ca06, 0x01900060, 0x5b02ca06, 0x01900060,
+       0x53028a07, 0x0190c060, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x4002140c, 0x00100010, 0x1a00d40d, 0x00100050,
+       0x5b02ca0e, 0x01900070, 0x5b02ca0e, 0x01900070,
+       0x53028a0f, 0x0190c070, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+};
+
+static const u16 b43_ntab_pilot_r3[] = {
+       0xff08, 0xff08, 0xff08, 0xff08, 0xff08, 0xff08,
+       0xff08, 0xff08, 0x80d5, 0x80d5, 0x80d5, 0x80d5,
+       0x80d5, 0x80d5, 0x80d5, 0x80d5, 0xff0a, 0xff82,
+       0xffa0, 0xff28, 0xffff, 0xffff, 0xffff, 0xffff,
+       0xff82, 0xffa0, 0xff28, 0xff0a, 0xffff, 0xffff,
+       0xffff, 0xffff, 0xf83f, 0xfa1f, 0xfa97, 0xfab5,
+       0xf2bd, 0xf0bf, 0xffff, 0xffff, 0xf017, 0xf815,
+       0xf215, 0xf095, 0xf035, 0xf01d, 0xffff, 0xffff,
+       0xff08, 0xff02, 0xff80, 0xff20, 0xff08, 0xff02,
+       0xff80, 0xff20, 0xf01f, 0xf817, 0xfa15, 0xf295,
+       0xf0b5, 0xf03d, 0xffff, 0xffff, 0xf82a, 0xfa0a,
+       0xfa82, 0xfaa0, 0xf2a8, 0xf0aa, 0xffff, 0xffff,
+       0xf002, 0xf800, 0xf200, 0xf080, 0xf020, 0xf008,
+       0xffff, 0xffff, 0xf00a, 0xf802, 0xfa00, 0xf280,
+       0xf0a0, 0xf028, 0xffff, 0xffff,
+};
+
+static const u32 b43_ntab_tmap_r3[] = {
+       0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
+       0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
+       0xf1111110, 0x11111111, 0x11f11111, 0x00000111,
+       0x11000000, 0x1111f111, 0x11111111, 0x111111f1,
+       0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x000aa888,
+       0x88880000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
+       0xa1111110, 0x11111111, 0x11c11111, 0x00000111,
+       0x11000000, 0x1111a111, 0x11111111, 0x111111a1,
+       0xa2222220, 0x22222222, 0x22c22222, 0x00000222,
+       0x22000000, 0x2222a222, 0x22222222, 0x222222a2,
+       0xf1111110, 0x11111111, 0x11f11111, 0x00011111,
+       0x11110000, 0x1111f111, 0x11111111, 0x111111f1,
+       0xa8aa88a0, 0xa88888a8, 0xa8a8a88a, 0x00088aaa,
+       0xaaaa0000, 0xa8a8aa88, 0xa88aaaaa, 0xaaaa8a8a,
+       0xaaa8aaa0, 0x8aaa8aaa, 0xaa8a8a8a, 0x000aaa88,
+       0x8aaa0000, 0xaaa8a888, 0x8aa88a8a, 0x8a88a888,
+       0x08080a00, 0x0a08080a, 0x080a0a08, 0x00080808,
+       0x080a0000, 0x080a0808, 0x080a0808, 0x0a0a0a08,
+       0xa0a0a0a0, 0x80a0a080, 0x8080a0a0, 0x00008080,
+       0x80a00000, 0x80a080a0, 0xa080a0a0, 0x8080a0a0,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x99999000, 0x9b9b99bb, 0x9bb99999, 0x9999b9b9,
+       0x9b99bb90, 0x9bbbbb9b, 0x9b9b9bb9, 0x00000999,
+       0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
+       0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00aaa888,
+       0x22000000, 0x2222b222, 0x22222222, 0x222222b2,
+       0xb2222220, 0x22222222, 0x22d22222, 0x00000222,
+       0x11000000, 0x1111a111, 0x11111111, 0x111111a1,
+       0xa1111110, 0x11111111, 0x11c11111, 0x00000111,
+       0x33000000, 0x3333b333, 0x33333333, 0x333333b3,
+       0xb3333330, 0x33333333, 0x33d33333, 0x00000333,
+       0x22000000, 0x2222a222, 0x22222222, 0x222222a2,
+       0xa2222220, 0x22222222, 0x22c22222, 0x00000222,
+       0x99b99b00, 0x9b9b99bb, 0x9bb99999, 0x9999b9b9,
+       0x9b99bb99, 0x9bbbbb9b, 0x9b9b9bb9, 0x00000999,
+       0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
+       0x8a88aa88, 0x8aaaaa8a, 0x8a8a8aa8, 0x08aaa888,
+       0x22222200, 0x2222f222, 0x22222222, 0x222222f2,
+       0x22222222, 0x22222222, 0x22f22222, 0x00000222,
+       0x11000000, 0x1111f111, 0x11111111, 0x11111111,
+       0xf1111111, 0x11111111, 0x11f11111, 0x01111111,
+       0xbb9bb900, 0xb9b9bb99, 0xb99bbbbb, 0xbbbb9b9b,
+       0xb9bb99bb, 0xb99999b9, 0xb9b9b99b, 0x00000bbb,
+       0xaa000000, 0xa8a8aa88, 0xa88aaaaa, 0xaaaa8a8a,
+       0xa8aa88aa, 0xa88888a8, 0xa8a8a88a, 0x0a888aaa,
+       0xaa000000, 0xa8a8aa88, 0xa88aaaaa, 0xaaaa8a8a,
+       0xa8aa88a0, 0xa88888a8, 0xa8a8a88a, 0x00000aaa,
+       0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
+       0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
+       0xbbbbbb00, 0x999bbbbb, 0x9bb99b9b, 0xb9b9b9bb,
+       0xb9b99bbb, 0xb9b9b9bb, 0xb9bb9b99, 0x00000999,
+       0x8a000000, 0xaa88a888, 0xa88888aa, 0xa88a8a88,
+       0xa88aa88a, 0x88a8aaaa, 0xa8aa8aaa, 0x0888a88a,
+       0x0b0b0b00, 0x090b0b0b, 0x0b090b0b, 0x0909090b,
+       0x09090b0b, 0x09090b0b, 0x09090b09, 0x00000909,
+       0x0a000000, 0x0a080808, 0x080a080a, 0x080a0a08,
+       0x080a080a, 0x0808080a, 0x0a0a0a08, 0x0808080a,
+       0xb0b0b000, 0x9090b0b0, 0x90b09090, 0xb0b0b090,
+       0xb0b090b0, 0x90b0b0b0, 0xb0b09090, 0x00000090,
+       0x80000000, 0xa080a080, 0xa08080a0, 0xa0808080,
+       0xa080a080, 0x80a0a0a0, 0xa0a080a0, 0x00a0a0a0,
+       0x22000000, 0x2222f222, 0x22222222, 0x222222f2,
+       0xf2222220, 0x22222222, 0x22f22222, 0x00000222,
+       0x11000000, 0x1111f111, 0x11111111, 0x111111f1,
+       0xf1111110, 0x11111111, 0x11f11111, 0x00000111,
+       0x33000000, 0x3333f333, 0x33333333, 0x333333f3,
+       0xf3333330, 0x33333333, 0x33f33333, 0x00000333,
+       0x22000000, 0x2222f222, 0x22222222, 0x222222f2,
+       0xf2222220, 0x22222222, 0x22f22222, 0x00000222,
+       0x99000000, 0x9b9b99bb, 0x9bb99999, 0x9999b9b9,
+       0x9b99bb90, 0x9bbbbb9b, 0x9b9b9bb9, 0x00000999,
+       0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
+       0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
+       0x88888000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
+       0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
+       0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
+       0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00aaa888,
+       0x88a88a00, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
+       0x8a88aa88, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
+       0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
+       0x8a88aa88, 0x8aaaaa8a, 0x8a8a8aa8, 0x08aaa888,
+       0x11000000, 0x1111a111, 0x11111111, 0x111111a1,
+       0xa1111110, 0x11111111, 0x11c11111, 0x00000111,
+       0x11000000, 0x1111a111, 0x11111111, 0x111111a1,
+       0xa1111110, 0x11111111, 0x11c11111, 0x00000111,
+       0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
+       0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
+       0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
+       0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+};
+
+static const u32 b43_ntab_intlevel_r3[] = {
+       0x00802070, 0x0671188d, 0x0a60192c, 0x0a300e46,
+       0x00c1188d, 0x080024d2, 0x00000070,
+};
+
+static const u32 b43_ntab_tdtrn_r3[] = {
+       0x061c061c, 0x0050ee68, 0xf592fe36, 0xfe5212f6,
+       0x00000c38, 0xfe5212f6, 0xf592fe36, 0x0050ee68,
+       0x061c061c, 0xee680050, 0xfe36f592, 0x12f6fe52,
+       0x0c380000, 0x12f6fe52, 0xfe36f592, 0xee680050,
+       0x061c061c, 0x0050ee68, 0xf592fe36, 0xfe5212f6,
+       0x00000c38, 0xfe5212f6, 0xf592fe36, 0x0050ee68,
+       0x061c061c, 0xee680050, 0xfe36f592, 0x12f6fe52,
+       0x0c380000, 0x12f6fe52, 0xfe36f592, 0xee680050,
+       0x05e305e3, 0x004def0c, 0xf5f3fe47, 0xfe611246,
+       0x00000bc7, 0xfe611246, 0xf5f3fe47, 0x004def0c,
+       0x05e305e3, 0xef0c004d, 0xfe47f5f3, 0x1246fe61,
+       0x0bc70000, 0x1246fe61, 0xfe47f5f3, 0xef0c004d,
+       0x05e305e3, 0x004def0c, 0xf5f3fe47, 0xfe611246,
+       0x00000bc7, 0xfe611246, 0xf5f3fe47, 0x004def0c,
+       0x05e305e3, 0xef0c004d, 0xfe47f5f3, 0x1246fe61,
+       0x0bc70000, 0x1246fe61, 0xfe47f5f3, 0xef0c004d,
+       0xfa58fa58, 0xf895043b, 0xff4c09c0, 0xfbc6ffa8,
+       0xfb84f384, 0x0798f6f9, 0x05760122, 0x058409f6,
+       0x0b500000, 0x05b7f542, 0x08860432, 0x06ddfee7,
+       0xfb84f384, 0xf9d90664, 0xf7e8025c, 0x00fff7bd,
+       0x05a805a8, 0xf7bd00ff, 0x025cf7e8, 0x0664f9d9,
+       0xf384fb84, 0xfee706dd, 0x04320886, 0xf54205b7,
+       0x00000b50, 0x09f60584, 0x01220576, 0xf6f90798,
+       0xf384fb84, 0xffa8fbc6, 0x09c0ff4c, 0x043bf895,
+       0x02d402d4, 0x07de0270, 0xfc96079c, 0xf90afe94,
+       0xfe00ff2c, 0x02d4065d, 0x092a0096, 0x0014fbb8,
+       0xfd2cfd2c, 0x076afb3c, 0x0096f752, 0xf991fd87,
+       0xfb2c0200, 0xfeb8f960, 0x08e0fc96, 0x049802a8,
+       0xfd2cfd2c, 0x02a80498, 0xfc9608e0, 0xf960feb8,
+       0x0200fb2c, 0xfd87f991, 0xf7520096, 0xfb3c076a,
+       0xfd2cfd2c, 0xfbb80014, 0x0096092a, 0x065d02d4,
+       0xff2cfe00, 0xfe94f90a, 0x079cfc96, 0x027007de,
+       0x02d402d4, 0x027007de, 0x079cfc96, 0xfe94f90a,
+       0xff2cfe00, 0x065d02d4, 0x0096092a, 0xfbb80014,
+       0xfd2cfd2c, 0xfb3c076a, 0xf7520096, 0xfd87f991,
+       0x0200fb2c, 0xf960feb8, 0xfc9608e0, 0x02a80498,
+       0xfd2cfd2c, 0x049802a8, 0x08e0fc96, 0xfeb8f960,
+       0xfb2c0200, 0xf991fd87, 0x0096f752, 0x076afb3c,
+       0xfd2cfd2c, 0x0014fbb8, 0x092a0096, 0x02d4065d,
+       0xfe00ff2c, 0xf90afe94, 0xfc96079c, 0x07de0270,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x062a0000, 0xfefa0759, 0x08b80908, 0xf396fc2d,
+       0xf9d6045c, 0xfc4ef608, 0xf748f596, 0x07b207bf,
+       0x062a062a, 0xf84ef841, 0xf748f596, 0x03b209f8,
+       0xf9d6045c, 0x0c6a03d3, 0x08b80908, 0x0106f8a7,
+       0x062a0000, 0xfefaf8a7, 0x08b8f6f8, 0xf39603d3,
+       0xf9d6fba4, 0xfc4e09f8, 0xf7480a6a, 0x07b2f841,
+       0x062af9d6, 0xf84e07bf, 0xf7480a6a, 0x03b2f608,
+       0xf9d6fba4, 0x0c6afc2d, 0x08b8f6f8, 0x01060759,
+       0x062a0000, 0xfefa0759, 0x08b80908, 0xf396fc2d,
+       0xf9d6045c, 0xfc4ef608, 0xf748f596, 0x07b207bf,
+       0x062a062a, 0xf84ef841, 0xf748f596, 0x03b209f8,
+       0xf9d6045c, 0x0c6a03d3, 0x08b80908, 0x0106f8a7,
+       0x062a0000, 0xfefaf8a7, 0x08b8f6f8, 0xf39603d3,
+       0xf9d6fba4, 0xfc4e09f8, 0xf7480a6a, 0x07b2f841,
+       0x062af9d6, 0xf84e07bf, 0xf7480a6a, 0x03b2f608,
+       0xf9d6fba4, 0x0c6afc2d, 0x08b8f6f8, 0x01060759,
+       0x061c061c, 0xff30009d, 0xffb21141, 0xfd87fb54,
+       0xf65dfe59, 0x02eef99e, 0x0166f03c, 0xfff809b6,
+       0x000008a4, 0x000af42b, 0x00eff577, 0xfa840bf2,
+       0xfc02ff51, 0x08260f67, 0xfff0036f, 0x0842f9c3,
+       0x00000000, 0x063df7be, 0xfc910010, 0xf099f7da,
+       0x00af03fe, 0xf40e057c, 0x0a89ff11, 0x0bd5fff6,
+       0xf75c0000, 0xf64a0008, 0x0fc4fe9a, 0x0662fd12,
+       0x01a709a3, 0x04ac0279, 0xeebf004e, 0xff6300d0,
+       0xf9e4f9e4, 0x00d0ff63, 0x004eeebf, 0x027904ac,
+       0x09a301a7, 0xfd120662, 0xfe9a0fc4, 0x0008f64a,
+       0x0000f75c, 0xfff60bd5, 0xff110a89, 0x057cf40e,
+       0x03fe00af, 0xf7daf099, 0x0010fc91, 0xf7be063d,
+       0x00000000, 0xf9c30842, 0x036ffff0, 0x0f670826,
+       0xff51fc02, 0x0bf2fa84, 0xf57700ef, 0xf42b000a,
+       0x08a40000, 0x09b6fff8, 0xf03c0166, 0xf99e02ee,
+       0xfe59f65d, 0xfb54fd87, 0x1141ffb2, 0x009dff30,
+       0x05e30000, 0xff060705, 0x085408a0, 0xf425fc59,
+       0xfa1d042a, 0xfc78f67a, 0xf7acf60e, 0x075a0766,
+       0x05e305e3, 0xf8a6f89a, 0xf7acf60e, 0x03880986,
+       0xfa1d042a, 0x0bdb03a7, 0x085408a0, 0x00faf8fb,
+       0x05e30000, 0xff06f8fb, 0x0854f760, 0xf42503a7,
+       0xfa1dfbd6, 0xfc780986, 0xf7ac09f2, 0x075af89a,
+       0x05e3fa1d, 0xf8a60766, 0xf7ac09f2, 0x0388f67a,
+       0xfa1dfbd6, 0x0bdbfc59, 0x0854f760, 0x00fa0705,
+       0x05e30000, 0xff060705, 0x085408a0, 0xf425fc59,
+       0xfa1d042a, 0xfc78f67a, 0xf7acf60e, 0x075a0766,
+       0x05e305e3, 0xf8a6f89a, 0xf7acf60e, 0x03880986,
+       0xfa1d042a, 0x0bdb03a7, 0x085408a0, 0x00faf8fb,
+       0x05e30000, 0xff06f8fb, 0x0854f760, 0xf42503a7,
+       0xfa1dfbd6, 0xfc780986, 0xf7ac09f2, 0x075af89a,
+       0x05e3fa1d, 0xf8a60766, 0xf7ac09f2, 0x0388f67a,
+       0xfa1dfbd6, 0x0bdbfc59, 0x0854f760, 0x00fa0705,
+       0xfa58fa58, 0xf8f0fe00, 0x0448073d, 0xfdc9fe46,
+       0xf9910258, 0x089d0407, 0xfd5cf71a, 0x02affde0,
+       0x083e0496, 0xff5a0740, 0xff7afd97, 0x00fe01f1,
+       0x0009082e, 0xfa94ff75, 0xfecdf8ea, 0xffb0f693,
+       0xfd2cfa58, 0x0433ff16, 0xfba405dd, 0xfa610341,
+       0x06a606cb, 0x0039fd2d, 0x0677fa97, 0x01fa05e0,
+       0xf896003e, 0x075a068b, 0x012cfc3e, 0xfa23f98d,
+       0xfc7cfd43, 0xff90fc0d, 0x01c10982, 0x00c601d6,
+       0xfd2cfd2c, 0x01d600c6, 0x098201c1, 0xfc0dff90,
+       0xfd43fc7c, 0xf98dfa23, 0xfc3e012c, 0x068b075a,
+       0x003ef896, 0x05e001fa, 0xfa970677, 0xfd2d0039,
+       0x06cb06a6, 0x0341fa61, 0x05ddfba4, 0xff160433,
+       0xfa58fd2c, 0xf693ffb0, 0xf8eafecd, 0xff75fa94,
+       0x082e0009, 0x01f100fe, 0xfd97ff7a, 0x0740ff5a,
+       0x0496083e, 0xfde002af, 0xf71afd5c, 0x0407089d,
+       0x0258f991, 0xfe46fdc9, 0x073d0448, 0xfe00f8f0,
+       0xfd2cfd2c, 0xfce00500, 0xfc09fddc, 0xfe680157,
+       0x04c70571, 0xfc3aff21, 0xfcd70228, 0x056d0277,
+       0x0200fe00, 0x0022f927, 0xfe3c032b, 0xfc44ff3c,
+       0x03e9fbdb, 0x04570313, 0x04c9ff5c, 0x000d03b8,
+       0xfa580000, 0xfbe900d2, 0xf9d0fe0b, 0x0125fdf9,
+       0x042501bf, 0x0328fa2b, 0xffa902f0, 0xfa250157,
+       0x0200fe00, 0x03740438, 0xff0405fd, 0x030cfe52,
+       0x0037fb39, 0xff6904c5, 0x04f8fd23, 0xfd31fc1b,
+       0xfd2cfd2c, 0xfc1bfd31, 0xfd2304f8, 0x04c5ff69,
+       0xfb390037, 0xfe52030c, 0x05fdff04, 0x04380374,
+       0xfe000200, 0x0157fa25, 0x02f0ffa9, 0xfa2b0328,
+       0x01bf0425, 0xfdf90125, 0xfe0bf9d0, 0x00d2fbe9,
+       0x0000fa58, 0x03b8000d, 0xff5c04c9, 0x03130457,
+       0xfbdb03e9, 0xff3cfc44, 0x032bfe3c, 0xf9270022,
+       0xfe000200, 0x0277056d, 0x0228fcd7, 0xff21fc3a,
+       0x057104c7, 0x0157fe68, 0xfddcfc09, 0x0500fce0,
+       0xfd2cfd2c, 0x0500fce0, 0xfddcfc09, 0x0157fe68,
+       0x057104c7, 0xff21fc3a, 0x0228fcd7, 0x0277056d,
+       0xfe000200, 0xf9270022, 0x032bfe3c, 0xff3cfc44,
+       0xfbdb03e9, 0x03130457, 0xff5c04c9, 0x03b8000d,
+       0x0000fa58, 0x00d2fbe9, 0xfe0bf9d0, 0xfdf90125,
+       0x01bf0425, 0xfa2b0328, 0x02f0ffa9, 0x0157fa25,
+       0xfe000200, 0x04380374, 0x05fdff04, 0xfe52030c,
+       0xfb390037, 0x04c5ff69, 0xfd2304f8, 0xfc1bfd31,
+       0xfd2cfd2c, 0xfd31fc1b, 0x04f8fd23, 0xff6904c5,
+       0x0037fb39, 0x030cfe52, 0xff0405fd, 0x03740438,
+       0x0200fe00, 0xfa250157, 0xffa902f0, 0x0328fa2b,
+       0x042501bf, 0x0125fdf9, 0xf9d0fe0b, 0xfbe900d2,
+       0xfa580000, 0x000d03b8, 0x04c9ff5c, 0x04570313,
+       0x03e9fbdb, 0xfc44ff3c, 0xfe3c032b, 0x0022f927,
+       0x0200fe00, 0x056d0277, 0xfcd70228, 0xfc3aff21,
+       0x04c70571, 0xfe680157, 0xfc09fddc, 0xfce00500,
+       0x05a80000, 0xff1006be, 0x0800084a, 0xf49cfc7e,
+       0xfa580400, 0xfc9cf6da, 0xf800f672, 0x0710071c,
+       0x05a805a8, 0xf8f0f8e4, 0xf800f672, 0x03640926,
+       0xfa580400, 0x0b640382, 0x0800084a, 0x00f0f942,
+       0x05a80000, 0xff10f942, 0x0800f7b6, 0xf49c0382,
+       0xfa58fc00, 0xfc9c0926, 0xf800098e, 0x0710f8e4,
+       0x05a8fa58, 0xf8f0071c, 0xf800098e, 0x0364f6da,
+       0xfa58fc00, 0x0b64fc7e, 0x0800f7b6, 0x00f006be,
+       0x05a80000, 0xff1006be, 0x0800084a, 0xf49cfc7e,
+       0xfa580400, 0xfc9cf6da, 0xf800f672, 0x0710071c,
+       0x05a805a8, 0xf8f0f8e4, 0xf800f672, 0x03640926,
+       0xfa580400, 0x0b640382, 0x0800084a, 0x00f0f942,
+       0x05a80000, 0xff10f942, 0x0800f7b6, 0xf49c0382,
+       0xfa58fc00, 0xfc9c0926, 0xf800098e, 0x0710f8e4,
+       0x05a8fa58, 0xf8f0071c, 0xf800098e, 0x0364f6da,
+       0xfa58fc00, 0x0b64fc7e, 0x0800f7b6, 0x00f006be,
+};
+
+static const u32 b43_ntab_noisevar0_r3[] = {
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+};
+
+static const u32 b43_ntab_noisevar1_r3[] = {
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+       0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+};
+
+static const u16 b43_ntab_mcs_r3[] = {
+       0x0000, 0x0008, 0x000a, 0x0010, 0x0012, 0x0019,
+       0x001a, 0x001c, 0x0080, 0x0088, 0x008a, 0x0090,
+       0x0092, 0x0099, 0x009a, 0x009c, 0x0100, 0x0108,
+       0x010a, 0x0110, 0x0112, 0x0119, 0x011a, 0x011c,
+       0x0180, 0x0188, 0x018a, 0x0190, 0x0192, 0x0199,
+       0x019a, 0x019c, 0x0000, 0x0098, 0x00a0, 0x00a8,
+       0x009a, 0x00a2, 0x00aa, 0x0120, 0x0128, 0x0128,
+       0x0130, 0x0138, 0x0138, 0x0140, 0x0122, 0x012a,
+       0x012a, 0x0132, 0x013a, 0x013a, 0x0142, 0x01a8,
+       0x01b0, 0x01b8, 0x01b0, 0x01b8, 0x01c0, 0x01c8,
+       0x01c0, 0x01c8, 0x01d0, 0x01d0, 0x01d8, 0x01aa,
+       0x01b2, 0x01ba, 0x01b2, 0x01ba, 0x01c2, 0x01ca,
+       0x01c2, 0x01ca, 0x01d2, 0x01d2, 0x01da, 0x0001,
+       0x0002, 0x0004, 0x0009, 0x000c, 0x0011, 0x0014,
+       0x0018, 0x0020, 0x0021, 0x0022, 0x0024, 0x0081,
+       0x0082, 0x0084, 0x0089, 0x008c, 0x0091, 0x0094,
+       0x0098, 0x00a0, 0x00a1, 0x00a2, 0x00a4, 0x0007,
+       0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007,
+       0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007,
+       0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007,
+       0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007,
+       0x0007, 0x0007,
+};
+
+static const u32 b43_ntab_tdi20a0_r3[] = {
+       0x00091226, 0x000a1429, 0x000b56ad, 0x000c58b0,
+       0x000d5ab3, 0x000e9cb6, 0x000f9eba, 0x0000c13d,
+       0x00020301, 0x00030504, 0x00040708, 0x0005090b,
+       0x00064b8e, 0x00095291, 0x000a5494, 0x000b9718,
+       0x000c9927, 0x000d9b2a, 0x000edd2e, 0x000fdf31,
+       0x000101b4, 0x000243b7, 0x000345bb, 0x000447be,
+       0x00058982, 0x00068c05, 0x00099309, 0x000a950c,
+       0x000bd78f, 0x000cd992, 0x000ddb96, 0x000f1d99,
+       0x00005fa8, 0x0001422c, 0x0002842f, 0x00038632,
+       0x00048835, 0x0005ca38, 0x0006ccbc, 0x0009d3bf,
+       0x000b1603, 0x000c1806, 0x000d1a0a, 0x000e1c0d,
+       0x000f5e10, 0x00008093, 0x00018297, 0x0002c49a,
+       0x0003c680, 0x0004c880, 0x00060b00, 0x00070d00,
+       0x00000000, 0x00000000, 0x00000000,
+};
+
+static const u32 b43_ntab_tdi20a1_r3[] = {
+       0x00014b26, 0x00028d29, 0x000393ad, 0x00049630,
+       0x0005d833, 0x0006da36, 0x00099c3a, 0x000a9e3d,
+       0x000bc081, 0x000cc284, 0x000dc488, 0x000f068b,
+       0x0000488e, 0x00018b91, 0x0002d214, 0x0003d418,
+       0x0004d6a7, 0x000618aa, 0x00071aae, 0x0009dcb1,
+       0x000b1eb4, 0x000c0137, 0x000d033b, 0x000e053e,
+       0x000f4702, 0x00008905, 0x00020c09, 0x0003128c,
+       0x0004148f, 0x00051712, 0x00065916, 0x00091b19,
+       0x000a1d28, 0x000b5f2c, 0x000c41af, 0x000d43b2,
+       0x000e85b5, 0x000f87b8, 0x0000c9bc, 0x00024cbf,
+       0x00035303, 0x00045506, 0x0005978a, 0x0006998d,
+       0x00095b90, 0x000a5d93, 0x000b9f97, 0x000c821a,
+       0x000d8400, 0x000ec600, 0x000fc800, 0x00010a00,
+       0x00000000, 0x00000000, 0x00000000,
+};
+
+static const u32 b43_ntab_tdi40a0_r3[] = {
+       0x0011a346, 0x00136ccf, 0x0014f5d9, 0x001641e2,
+       0x0017cb6b, 0x00195475, 0x001b2383, 0x001cad0c,
+       0x001e7616, 0x0000821f, 0x00020ba8, 0x0003d4b2,
+       0x00056447, 0x00072dd0, 0x0008b6da, 0x000a02e3,
+       0x000b8c6c, 0x000d15f6, 0x0011e484, 0x0013ae0d,
+       0x00153717, 0x00168320, 0x00180ca9, 0x00199633,
+       0x001b6548, 0x001ceed1, 0x001eb7db, 0x0000c3e4,
+       0x00024d6d, 0x000416f7, 0x0005a585, 0x00076f0f,
+       0x0008f818, 0x000a4421, 0x000bcdab, 0x000d9734,
+       0x00122649, 0x0013efd2, 0x001578dc, 0x0016c4e5,
+       0x00184e6e, 0x001a17f8, 0x001ba686, 0x001d3010,
+       0x001ef999, 0x00010522, 0x00028eac, 0x00045835,
+       0x0005e74a, 0x0007b0d3, 0x00093a5d, 0x000a85e6,
+       0x000c0f6f, 0x000dd8f9, 0x00126787, 0x00143111,
+       0x0015ba9a, 0x00170623, 0x00188fad, 0x001a5936,
+       0x001be84b, 0x001db1d4, 0x001f3b5e, 0x000146e7,
+       0x00031070, 0x000499fa, 0x00062888, 0x0007f212,
+       0x00097b9b, 0x000ac7a4, 0x000c50ae, 0x000e1a37,
+       0x0012a94c, 0x001472d5, 0x0015fc5f, 0x00174868,
+       0x0018d171, 0x001a9afb, 0x001c2989, 0x001df313,
+       0x001f7c9c, 0x000188a5, 0x000351af, 0x0004db38,
+       0x0006aa4d, 0x000833d7, 0x0009bd60, 0x000b0969,
+       0x000c9273, 0x000e5bfc, 0x00132a8a, 0x0014b414,
+       0x00163d9d, 0x001789a6, 0x001912b0, 0x001adc39,
+       0x001c6bce, 0x001e34d8, 0x001fbe61, 0x0001ca6a,
+       0x00039374, 0x00051cfd, 0x0006ec0b, 0x00087515,
+       0x0009fe9e, 0x000b4aa7, 0x000cd3b1, 0x000e9d3a,
+       0x00000000, 0x00000000,
+};
+
+static const u32 b43_ntab_tdi40a1_r3[] = {
+       0x001edb36, 0x000129ca, 0x0002b353, 0x00047cdd,
+       0x0005c8e6, 0x000791ef, 0x00091bf9, 0x000aaa07,
+       0x000c3391, 0x000dfd1a, 0x00120923, 0x0013d22d,
+       0x00155c37, 0x0016eacb, 0x00187454, 0x001a3dde,
+       0x001b89e7, 0x001d12f0, 0x001f1cfa, 0x00016b88,
+       0x00033492, 0x0004be1b, 0x00060a24, 0x0007d32e,
+       0x00095d38, 0x000aec4c, 0x000c7555, 0x000e3edf,
+       0x00124ae8, 0x001413f1, 0x0015a37b, 0x00172c89,
+       0x0018b593, 0x001a419c, 0x001bcb25, 0x001d942f,
+       0x001f63b9, 0x0001ad4d, 0x00037657, 0x0004c260,
+       0x00068be9, 0x000814f3, 0x0009a47c, 0x000b2d8a,
+       0x000cb694, 0x000e429d, 0x00128c26, 0x001455b0,
+       0x0015e4ba, 0x00176e4e, 0x0018f758, 0x001a8361,
+       0x001c0cea, 0x001dd674, 0x001fa57d, 0x0001ee8b,
+       0x0003b795, 0x0005039e, 0x0006cd27, 0x000856b1,
+       0x0009e5c6, 0x000b6f4f, 0x000cf859, 0x000e8462,
+       0x00130deb, 0x00149775, 0x00162603, 0x0017af8c,
+       0x00193896, 0x001ac49f, 0x001c4e28, 0x001e17b2,
+       0x0000a6c7, 0x00023050, 0x0003f9da, 0x00054563,
+       0x00070eec, 0x00089876, 0x000a2704, 0x000bb08d,
+       0x000d3a17, 0x001185a0, 0x00134f29, 0x0014d8b3,
+       0x001667c8, 0x0017f151, 0x00197adb, 0x001b0664,
+       0x001c8fed, 0x001e5977, 0x0000e805, 0x0002718f,
+       0x00043b18, 0x000586a1, 0x0007502b, 0x0008d9b4,
+       0x000a68c9, 0x000bf252, 0x000dbbdc, 0x0011c7e5,
+       0x001390ee, 0x00151a78, 0x0016a906, 0x00183290,
+       0x0019bc19, 0x001b4822, 0x001cd12c, 0x001e9ab5,
+       0x00000000, 0x00000000,
+};
+
+static const u32 b43_ntab_pilotlt_r3[] = {
+       0x76540213, 0x62407351, 0x76543210, 0x76540213,
+       0x76540213, 0x76430521,
+};
+
+static const u32 b43_ntab_channelest_r3[] = {
+       0x44444444, 0x44444444, 0x44444444, 0x44444444,
+       0x44444444, 0x44444444, 0x44444444, 0x44444444,
+       0x10101010, 0x10101010, 0x10101010, 0x10101010,
+       0x10101010, 0x10101010, 0x10101010, 0x10101010,
+       0x44444444, 0x44444444, 0x44444444, 0x44444444,
+       0x44444444, 0x44444444, 0x44444444, 0x44444444,
+       0x10101010, 0x10101010, 0x10101010, 0x10101010,
+       0x10101010, 0x10101010, 0x10101010, 0x10101010,
+       0x44444444, 0x44444444, 0x44444444, 0x44444444,
+       0x44444444, 0x44444444, 0x44444444, 0x44444444,
+       0x44444444, 0x44444444, 0x44444444, 0x44444444,
+       0x44444444, 0x44444444, 0x44444444, 0x44444444,
+       0x10101010, 0x10101010, 0x10101010, 0x10101010,
+       0x10101010, 0x10101010, 0x10101010, 0x10101010,
+       0x10101010, 0x10101010, 0x10101010, 0x10101010,
+       0x10101010, 0x10101010, 0x10101010, 0x10101010,
+       0x44444444, 0x44444444, 0x44444444, 0x44444444,
+       0x44444444, 0x44444444, 0x44444444, 0x44444444,
+       0x44444444, 0x44444444, 0x44444444, 0x44444444,
+       0x44444444, 0x44444444, 0x44444444, 0x44444444,
+       0x10101010, 0x10101010, 0x10101010, 0x10101010,
+       0x10101010, 0x10101010, 0x10101010, 0x10101010,
+       0x10101010, 0x10101010, 0x10101010, 0x10101010,
+       0x10101010, 0x10101010, 0x10101010, 0x10101010,
+};
+
+static const u8 b43_ntab_framelookup_r3[] = {
+       0x02, 0x04, 0x14, 0x14, 0x03, 0x05, 0x16, 0x16,
+       0x0a, 0x0c, 0x1c, 0x1c, 0x0b, 0x0d, 0x1e, 0x1e,
+       0x06, 0x08, 0x18, 0x18, 0x07, 0x09, 0x1a, 0x1a,
+       0x0e, 0x10, 0x20, 0x28, 0x0f, 0x11, 0x22, 0x2a,
+};
+
+static const u8 b43_ntab_estimatepowerlt0_r3[] = {
+       0x55, 0x54, 0x54, 0x53, 0x52, 0x52, 0x51, 0x51,
+       0x50, 0x4f, 0x4f, 0x4e, 0x4e, 0x4d, 0x4c, 0x4c,
+       0x4b, 0x4a, 0x49, 0x49, 0x48, 0x47, 0x46, 0x46,
+       0x45, 0x44, 0x43, 0x42, 0x41, 0x40, 0x40, 0x3f,
+       0x3e, 0x3d, 0x3c, 0x3a, 0x39, 0x38, 0x37, 0x36,
+       0x35, 0x33, 0x32, 0x31, 0x2f, 0x2e, 0x2c, 0x2b,
+       0x29, 0x27, 0x25, 0x23, 0x21, 0x1f, 0x1d, 0x1a,
+       0x18, 0x15, 0x12, 0x0e, 0x0b, 0x07, 0x02, 0xfd,
+};
+
+static const u8 b43_ntab_estimatepowerlt1_r3[] = {
+       0x55, 0x54, 0x54, 0x53, 0x52, 0x52, 0x51, 0x51,
+       0x50, 0x4f, 0x4f, 0x4e, 0x4e, 0x4d, 0x4c, 0x4c,
+       0x4b, 0x4a, 0x49, 0x49, 0x48, 0x47, 0x46, 0x46,
+       0x45, 0x44, 0x43, 0x42, 0x41, 0x40, 0x40, 0x3f,
+       0x3e, 0x3d, 0x3c, 0x3a, 0x39, 0x38, 0x37, 0x36,
+       0x35, 0x33, 0x32, 0x31, 0x2f, 0x2e, 0x2c, 0x2b,
+       0x29, 0x27, 0x25, 0x23, 0x21, 0x1f, 0x1d, 0x1a,
+       0x18, 0x15, 0x12, 0x0e, 0x0b, 0x07, 0x02, 0xfd,
+};
+
+static const u8 b43_ntab_adjustpower0_r3[] = {
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+static const u8 b43_ntab_adjustpower1_r3[] = {
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+static const u32 b43_ntab_gainctl0_r3[] = {
+       0x5bf70044, 0x5bf70042, 0x5bf70040, 0x5bf7003e,
+       0x5bf7003c, 0x5bf7003b, 0x5bf70039, 0x5bf70037,
+       0x5bf70036, 0x5bf70034, 0x5bf70033, 0x5bf70031,
+       0x5bf70030, 0x5ba70044, 0x5ba70042, 0x5ba70040,
+       0x5ba7003e, 0x5ba7003c, 0x5ba7003b, 0x5ba70039,
+       0x5ba70037, 0x5ba70036, 0x5ba70034, 0x5ba70033,
+       0x5b770044, 0x5b770042, 0x5b770040, 0x5b77003e,
+       0x5b77003c, 0x5b77003b, 0x5b770039, 0x5b770037,
+       0x5b770036, 0x5b770034, 0x5b770033, 0x5b770031,
+       0x5b770030, 0x5b77002f, 0x5b77002d, 0x5b77002c,
+       0x5b470044, 0x5b470042, 0x5b470040, 0x5b47003e,
+       0x5b47003c, 0x5b47003b, 0x5b470039, 0x5b470037,
+       0x5b470036, 0x5b470034, 0x5b470033, 0x5b470031,
+       0x5b470030, 0x5b47002f, 0x5b47002d, 0x5b47002c,
+       0x5b47002b, 0x5b47002a, 0x5b270044, 0x5b270042,
+       0x5b270040, 0x5b27003e, 0x5b27003c, 0x5b27003b,
+       0x5b270039, 0x5b270037, 0x5b270036, 0x5b270034,
+       0x5b270033, 0x5b270031, 0x5b270030, 0x5b27002f,
+       0x5b170044, 0x5b170042, 0x5b170040, 0x5b17003e,
+       0x5b17003c, 0x5b17003b, 0x5b170039, 0x5b170037,
+       0x5b170036, 0x5b170034, 0x5b170033, 0x5b170031,
+       0x5b170030, 0x5b17002f, 0x5b17002d, 0x5b17002c,
+       0x5b17002b, 0x5b17002a, 0x5b170028, 0x5b170027,
+       0x5b170026, 0x5b170025, 0x5b170024, 0x5b170023,
+       0x5b070044, 0x5b070042, 0x5b070040, 0x5b07003e,
+       0x5b07003c, 0x5b07003b, 0x5b070039, 0x5b070037,
+       0x5b070036, 0x5b070034, 0x5b070033, 0x5b070031,
+       0x5b070030, 0x5b07002f, 0x5b07002d, 0x5b07002c,
+       0x5b07002b, 0x5b07002a, 0x5b070028, 0x5b070027,
+       0x5b070026, 0x5b070025, 0x5b070024, 0x5b070023,
+       0x5b070022, 0x5b070021, 0x5b070020, 0x5b07001f,
+       0x5b07001e, 0x5b07001d, 0x5b07001d, 0x5b07001c,
+};
+
+static const u32 b43_ntab_gainctl1_r3[] = {
+       0x5bf70044, 0x5bf70042, 0x5bf70040, 0x5bf7003e,
+       0x5bf7003c, 0x5bf7003b, 0x5bf70039, 0x5bf70037,
+       0x5bf70036, 0x5bf70034, 0x5bf70033, 0x5bf70031,
+       0x5bf70030, 0x5ba70044, 0x5ba70042, 0x5ba70040,
+       0x5ba7003e, 0x5ba7003c, 0x5ba7003b, 0x5ba70039,
+       0x5ba70037, 0x5ba70036, 0x5ba70034, 0x5ba70033,
+       0x5b770044, 0x5b770042, 0x5b770040, 0x5b77003e,
+       0x5b77003c, 0x5b77003b, 0x5b770039, 0x5b770037,
+       0x5b770036, 0x5b770034, 0x5b770033, 0x5b770031,
+       0x5b770030, 0x5b77002f, 0x5b77002d, 0x5b77002c,
+       0x5b470044, 0x5b470042, 0x5b470040, 0x5b47003e,
+       0x5b47003c, 0x5b47003b, 0x5b470039, 0x5b470037,
+       0x5b470036, 0x5b470034, 0x5b470033, 0x5b470031,
+       0x5b470030, 0x5b47002f, 0x5b47002d, 0x5b47002c,
+       0x5b47002b, 0x5b47002a, 0x5b270044, 0x5b270042,
+       0x5b270040, 0x5b27003e, 0x5b27003c, 0x5b27003b,
+       0x5b270039, 0x5b270037, 0x5b270036, 0x5b270034,
+       0x5b270033, 0x5b270031, 0x5b270030, 0x5b27002f,
+       0x5b170044, 0x5b170042, 0x5b170040, 0x5b17003e,
+       0x5b17003c, 0x5b17003b, 0x5b170039, 0x5b170037,
+       0x5b170036, 0x5b170034, 0x5b170033, 0x5b170031,
+       0x5b170030, 0x5b17002f, 0x5b17002d, 0x5b17002c,
+       0x5b17002b, 0x5b17002a, 0x5b170028, 0x5b170027,
+       0x5b170026, 0x5b170025, 0x5b170024, 0x5b170023,
+       0x5b070044, 0x5b070042, 0x5b070040, 0x5b07003e,
+       0x5b07003c, 0x5b07003b, 0x5b070039, 0x5b070037,
+       0x5b070036, 0x5b070034, 0x5b070033, 0x5b070031,
+       0x5b070030, 0x5b07002f, 0x5b07002d, 0x5b07002c,
+       0x5b07002b, 0x5b07002a, 0x5b070028, 0x5b070027,
+       0x5b070026, 0x5b070025, 0x5b070024, 0x5b070023,
+       0x5b070022, 0x5b070021, 0x5b070020, 0x5b07001f,
+       0x5b07001e, 0x5b07001d, 0x5b07001d, 0x5b07001c,
+};
+
+static const u32 b43_ntab_iqlt0_r3[] = {
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+};
+
+static const u32 b43_ntab_iqlt1_r3[] = {
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+};
+
+static const u16 b43_ntab_loftlt0_r3[] = {
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000,
+};
+
+static const u16 b43_ntab_loftlt1_r3[] = {
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000,
+};
+
+/* TX gain tables */
 const u32 b43_ntab_tx_gain_rev0_1_2[] = {
        0x03cc2b44, 0x03cc2b42, 0x03cc2a44, 0x03cc2a42,
        0x03cc2944, 0x03c82b44, 0x03c82b42, 0x03c82a44,
@@ -1813,7 +2887,6 @@ void b43_ntab_write_bulk(struct b43_wldev *dev, u32 offset,
 #define ntab_upload(dev, offset, data) do { \
                b43_ntab_write_bulk(dev, offset, offset##_SIZE, data);  \
        } while (0)
-
 void b43_nphy_rev0_1_2_tables_init(struct b43_wldev *dev)
 {
        /* Static tables */
@@ -1847,10 +2920,39 @@ void b43_nphy_rev0_1_2_tables_init(struct b43_wldev *dev)
        ntab_upload(dev, B43_NTAB_C1_LOFEEDTH, b43_ntab_loftlt1);
 }
 
+#define ntab_upload_r3(dev, offset, data) do { \
+               b43_ntab_write_bulk(dev, offset, ARRAY_SIZE(data), data); \
+       } while (0)
 void b43_nphy_rev3plus_tables_init(struct b43_wldev *dev)
 {
        /* Static tables */
-       /* TODO */
+       ntab_upload_r3(dev, B43_NTAB_FRAMESTRUCT_R3, b43_ntab_framestruct_r3);
+       ntab_upload_r3(dev, B43_NTAB_PILOT_R3, b43_ntab_pilot_r3);
+       ntab_upload_r3(dev, B43_NTAB_TMAP_R3, b43_ntab_tmap_r3);
+       ntab_upload_r3(dev, B43_NTAB_INTLEVEL_R3, b43_ntab_intlevel_r3);
+       ntab_upload_r3(dev, B43_NTAB_TDTRN_R3, b43_ntab_tdtrn_r3);
+       ntab_upload_r3(dev, B43_NTAB_NOISEVAR0_R3, b43_ntab_noisevar0_r3);
+       ntab_upload_r3(dev, B43_NTAB_NOISEVAR1_R3, b43_ntab_noisevar1_r3);
+       ntab_upload_r3(dev, B43_NTAB_MCS_R3, b43_ntab_mcs_r3);
+       ntab_upload_r3(dev, B43_NTAB_TDI20A0_R3, b43_ntab_tdi20a0_r3);
+       ntab_upload_r3(dev, B43_NTAB_TDI20A1_R3, b43_ntab_tdi20a1_r3);
+       ntab_upload_r3(dev, B43_NTAB_TDI40A0_R3, b43_ntab_tdi40a0_r3);
+       ntab_upload_r3(dev, B43_NTAB_TDI40A1_R3, b43_ntab_tdi40a1_r3);
+       ntab_upload_r3(dev, B43_NTAB_PILOTLT_R3, b43_ntab_pilotlt_r3);
+       ntab_upload_r3(dev, B43_NTAB_CHANEST_R3, b43_ntab_channelest_r3);
+       ntab_upload_r3(dev, B43_NTAB_FRAMELT_R3, b43_ntab_framelookup_r3);
+       ntab_upload_r3(dev, B43_NTAB_C0_ESTPLT_R3,
+                      b43_ntab_estimatepowerlt0_r3);
+       ntab_upload_r3(dev, B43_NTAB_C1_ESTPLT_R3,
+                      b43_ntab_estimatepowerlt1_r3);
+       ntab_upload_r3(dev, B43_NTAB_C0_ADJPLT_R3, b43_ntab_adjustpower0_r3);
+       ntab_upload_r3(dev, B43_NTAB_C1_ADJPLT_R3, b43_ntab_adjustpower1_r3);
+       ntab_upload_r3(dev, B43_NTAB_C0_GAINCTL_R3, b43_ntab_gainctl0_r3);
+       ntab_upload_r3(dev, B43_NTAB_C1_GAINCTL_R3, b43_ntab_gainctl1_r3);
+       ntab_upload_r3(dev, B43_NTAB_C0_IQLT_R3, b43_ntab_iqlt0_r3);
+       ntab_upload_r3(dev, B43_NTAB_C1_IQLT_R3, b43_ntab_iqlt1_r3);
+       ntab_upload_r3(dev, B43_NTAB_C0_LOFEEDTH_R3, b43_ntab_loftlt0_r3);
+       ntab_upload_r3(dev, B43_NTAB_C1_LOFEEDTH_R3, b43_ntab_loftlt1_r3);
 
        /* Volatile tables */
        /* TODO */
index 4ec593b..016a480 100644 (file)
@@ -109,6 +109,33 @@ b43_nphy_get_chantabent_rev3(struct b43_wldev *dev, u16 freq);
 #define B43_NTAB_C1_LOFEEDTH           B43_NTAB16(0x1B, 0x1C0) /* Local Oscillator Feed Through Lookup Table Core 1 */
 #define B43_NTAB_C1_LOFEEDTH_SIZE      128
 
+/* Static N-PHY tables, PHY revision >= 3 */
+#define B43_NTAB_FRAMESTRUCT_R3                B43_NTAB32(10, 000) /* frame struct  */
+#define B43_NTAB_PILOT_R3              B43_NTAB16(11, 000) /* pilot  */
+#define B43_NTAB_TMAP_R3               B43_NTAB32(12, 000) /* TM AP  */
+#define B43_NTAB_INTLEVEL_R3           B43_NTAB32(13, 000) /* INT LV  */
+#define B43_NTAB_TDTRN_R3              B43_NTAB32(14, 000) /* TD TRN  */
+#define B43_NTAB_NOISEVAR0_R3          B43_NTAB32(16, 000) /* noise variance 0  */
+#define B43_NTAB_NOISEVAR1_R3          B43_NTAB32(16, 128) /* noise variance 1  */
+#define B43_NTAB_MCS_R3                        B43_NTAB16(18, 000) /* MCS  */
+#define B43_NTAB_TDI20A0_R3            B43_NTAB32(19, 128) /* TDI 20/0  */
+#define B43_NTAB_TDI20A1_R3            B43_NTAB32(19, 256) /* TDI 20/1  */
+#define B43_NTAB_TDI40A0_R3            B43_NTAB32(19, 640) /* TDI 40/0  */
+#define B43_NTAB_TDI40A1_R3            B43_NTAB32(19, 768) /* TDI 40/1  */
+#define B43_NTAB_PILOTLT_R3            B43_NTAB32(20, 000) /* PLT lookup  */
+#define B43_NTAB_CHANEST_R3            B43_NTAB32(22, 000) /* channel estimate  */
+#define B43_NTAB_FRAMELT_R3            B43_NTAB8 (24, 000) /* frame lookup  */
+#define B43_NTAB_C0_ESTPLT_R3          B43_NTAB8 (26, 000) /* estimated power lookup 0  */
+#define B43_NTAB_C1_ESTPLT_R3          B43_NTAB8 (27, 000) /* estimated power lookup 1  */
+#define B43_NTAB_C0_ADJPLT_R3          B43_NTAB8 (26, 064) /* adjusted power lookup 0  */
+#define B43_NTAB_C1_ADJPLT_R3          B43_NTAB8 (27, 064) /* adjusted power lookup 1  */
+#define B43_NTAB_C0_GAINCTL_R3         B43_NTAB32(26, 192) /* gain control lookup 0  */
+#define B43_NTAB_C1_GAINCTL_R3         B43_NTAB32(27, 192) /* gain control lookup 1  */
+#define B43_NTAB_C0_IQLT_R3            B43_NTAB32(26, 320) /* I/Q lookup 0  */
+#define B43_NTAB_C1_IQLT_R3            B43_NTAB32(27, 320) /* I/Q lookup 1  */
+#define B43_NTAB_C0_LOFEEDTH_R3                B43_NTAB16(26, 448) /* Local Oscillator Feed Through lookup 0  */
+#define B43_NTAB_C1_LOFEEDTH_R3                B43_NTAB16(27, 448) /* Local Oscillator Feed Through lookup 1 */
+
 #define B43_NTAB_TX_IQLO_CAL_LOFT_LADDER_40_SIZE       18
 #define B43_NTAB_TX_IQLO_CAL_LOFT_LADDER_20_SIZE       18
 #define B43_NTAB_TX_IQLO_CAL_IQIMB_LADDER_40_SIZE      18
index e6b0528..e5be381 100644 (file)
 #include "dma.h"
 #include "pio.h"
 
+static const struct b43_tx_legacy_rate_phy_ctl_entry b43_tx_legacy_rate_phy_ctl[] = {
+       { B43_CCK_RATE_1MB,     0x0,                    0x0 },
+       { B43_CCK_RATE_2MB,     0x0,                    0x1 },
+       { B43_CCK_RATE_5MB,     0x0,                    0x2 },
+       { B43_CCK_RATE_11MB,    0x0,                    0x3 },
+       { B43_OFDM_RATE_6MB,    B43_TXH_PHY1_CRATE_1_2, B43_TXH_PHY1_MODUL_BPSK },
+       { B43_OFDM_RATE_9MB,    B43_TXH_PHY1_CRATE_3_4, B43_TXH_PHY1_MODUL_BPSK },
+       { B43_OFDM_RATE_12MB,   B43_TXH_PHY1_CRATE_1_2, B43_TXH_PHY1_MODUL_QPSK },
+       { B43_OFDM_RATE_18MB,   B43_TXH_PHY1_CRATE_3_4, B43_TXH_PHY1_MODUL_QPSK },
+       { B43_OFDM_RATE_24MB,   B43_TXH_PHY1_CRATE_1_2, B43_TXH_PHY1_MODUL_QAM16 },
+       { B43_OFDM_RATE_36MB,   B43_TXH_PHY1_CRATE_3_4, B43_TXH_PHY1_MODUL_QAM16 },
+       { B43_OFDM_RATE_48MB,   B43_TXH_PHY1_CRATE_2_3, B43_TXH_PHY1_MODUL_QAM64 },
+       { B43_OFDM_RATE_54MB,   B43_TXH_PHY1_CRATE_3_4, B43_TXH_PHY1_MODUL_QAM64 },
+};
+
+static const struct b43_tx_legacy_rate_phy_ctl_entry *
+b43_tx_legacy_rate_phy_ctl_ent(u8 bitrate)
+{
+       const struct b43_tx_legacy_rate_phy_ctl_entry *e;
+       unsigned int i;
+
+       for (i = 0; i < ARRAY_SIZE(b43_tx_legacy_rate_phy_ctl); i++) {
+               e = &(b43_tx_legacy_rate_phy_ctl[i]);
+               if (e->bitrate == bitrate)
+                       return e;
+       }
+
+       B43_WARN_ON(1);
+       return NULL;
+}
 
 /* Extract the bitrate index out of a CCK PLCP header. */
 static int b43_plcp_get_bitrate_idx_cck(struct b43_plcp_hdr6 *plcp)
@@ -145,6 +175,34 @@ void b43_generate_plcp_hdr(struct b43_plcp_hdr4 *plcp,
        }
 }
 
+static u16 b43_generate_tx_phy_ctl1(struct b43_wldev *dev, u8 bitrate)
+{
+       const struct b43_phy *phy = &dev->phy;
+       const struct b43_tx_legacy_rate_phy_ctl_entry *e;
+       u16 control = 0;
+       u16 bw;
+
+       if (phy->type == B43_PHYTYPE_LP)
+               bw = B43_TXH_PHY1_BW_20;
+       else /* FIXME */
+               bw = B43_TXH_PHY1_BW_20;
+
+       if (0) { /* FIXME: MIMO */
+       } else if (b43_is_cck_rate(bitrate) && phy->type != B43_PHYTYPE_LP) {
+               control = bw;
+       } else {
+               control = bw;
+               e = b43_tx_legacy_rate_phy_ctl_ent(bitrate);
+               if (e) {
+                       control |= e->coding_rate;
+                       control |= e->modulation;
+               }
+               control |= B43_TXH_PHY1_MODE_SISO;
+       }
+
+       return control;
+}
+
 static u8 b43_calc_fallback_rate(u8 bitrate)
 {
        switch (bitrate) {
@@ -437,6 +495,14 @@ int b43_generate_txhdr(struct b43_wldev *dev,
                        extra_ft |= B43_TXH_EFT_RTSFB_OFDM;
                else
                        extra_ft |= B43_TXH_EFT_RTSFB_CCK;
+
+               if (rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS &&
+                   phy->type == B43_PHYTYPE_N) {
+                       txhdr->phy_ctl1_rts = cpu_to_le16(
+                               b43_generate_tx_phy_ctl1(dev, rts_rate));
+                       txhdr->phy_ctl1_rts_fb = cpu_to_le16(
+                               b43_generate_tx_phy_ctl1(dev, rts_rate_fb));
+               }
        }
 
        /* Magic cookie */
@@ -445,6 +511,13 @@ int b43_generate_txhdr(struct b43_wldev *dev,
        else
                txhdr->new_format.cookie = cpu_to_le16(cookie);
 
+       if (phy->type == B43_PHYTYPE_N) {
+               txhdr->phy_ctl1 =
+                       cpu_to_le16(b43_generate_tx_phy_ctl1(dev, rate));
+               txhdr->phy_ctl1_fb =
+                       cpu_to_le16(b43_generate_tx_phy_ctl1(dev, rate_fb));
+       }
+
        /* Apply the bitfields */
        txhdr->mac_ctl = cpu_to_le32(mac_ctl);
        txhdr->phy_ctl = cpu_to_le16(phy_ctl);
@@ -652,7 +725,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
                status.mactime += mactime;
                if (low_mactime_now <= mactime)
                        status.mactime -= 0x10000;
-               status.flag |= RX_FLAG_TSFT;
+               status.flag |= RX_FLAG_MACTIME_MPDU;
        }
 
        chanid = (chanstat & B43_RX_CHAN_ID) >> B43_RX_CHAN_ID_SHIFT;
index d4cf9b3..42debb5 100644 (file)
@@ -73,6 +73,12 @@ struct b43_txhdr {
        } __packed;
 } __packed;
 
+struct b43_tx_legacy_rate_phy_ctl_entry {
+       u8 bitrate;
+       u16 coding_rate;
+       u16 modulation;
+};
+
 /* MAC TX control */
 #define B43_TXH_MAC_USEFBR             0x10000000 /* Use fallback rate for this AMPDU */
 #define B43_TXH_MAC_KEYIDX             0x0FF00000 /* Security key index */
index 1f11e16..c7fd73e 100644 (file)
@@ -2442,8 +2442,8 @@ static int b43legacy_rng_init(struct b43legacy_wl *wl)
        return err;
 }
 
-static int b43legacy_op_tx(struct ieee80211_hw *hw,
-                          struct sk_buff *skb)
+static void b43legacy_op_tx(struct ieee80211_hw *hw,
+                           struct sk_buff *skb)
 {
        struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
        struct b43legacy_wldev *dev = wl->current_dev;
@@ -2466,7 +2466,6 @@ out:
                /* Drop the packet. */
                dev_kfree_skb_any(skb);
        }
-       return NETDEV_TX_OK;
 }
 
 static int b43legacy_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
index 7d177d9..3a95541 100644 (file)
@@ -572,7 +572,7 @@ void b43legacy_rx(struct b43legacy_wldev *dev,
                status.mactime += mactime;
                if (low_mactime_now <= mactime)
                        status.mactime -= 0x10000;
-               status.flag |= RX_FLAG_TSFT;
+               status.flag |= RX_FLAG_MACTIME_MPDU;
        }
 
        chanid = (chanstat & B43legacy_RX_CHAN_ID) >>
diff --git a/drivers/net/wireless/iwlegacy/Kconfig b/drivers/net/wireless/iwlegacy/Kconfig
new file mode 100644 (file)
index 0000000..2a45dd4
--- /dev/null
@@ -0,0 +1,116 @@
+config IWLWIFI_LEGACY
+       tristate "Intel Wireless Wifi legacy devices"
+       depends on PCI && MAC80211
+       select FW_LOADER
+       select NEW_LEDS
+       select LEDS_CLASS
+       select LEDS_TRIGGERS
+       select MAC80211_LEDS
+
+menu "Debugging Options"
+       depends on IWLWIFI_LEGACY
+
+config IWLWIFI_LEGACY_DEBUG
+       bool "Enable full debugging output in 4965 and 3945 drivers"
+       depends on IWLWIFI_LEGACY
+       ---help---
+         This option will enable debug tracing output for the iwlwifilegacy
+         drivers.
+
+         This will result in the kernel module being ~100k larger.  You can
+         control which debug output is sent to the kernel log by setting the
+         value in
+
+               /sys/class/net/wlan0/device/debug_level
+
+         This entry will only exist if this option is enabled.
+
+         To set a value, simply echo an 8-byte hex value to the same file:
+
+                 % echo 0x43fff > /sys/class/net/wlan0/device/debug_level
+
+         You can find the list of debug mask values in:
+                 drivers/net/wireless/iwlwifilegacy/iwl-debug.h
+
+         If this is your first time using this driver, you should say Y here
+         as the debug information can assist others in helping you resolve
+         any problems you may encounter.
+
+config IWLWIFI_LEGACY_DEBUGFS
+        bool "4965 and 3945 debugfs support"
+        depends on IWLWIFI_LEGACY && MAC80211_DEBUGFS
+        ---help---
+         Enable creation of debugfs files for the iwlwifilegacy drivers. This
+         is a low-impact option that allows getting insight into the
+         driver's state at runtime.
+
+config IWLWIFI_LEGACY_DEVICE_TRACING
+       bool "iwlwifilegacy legacy device access tracing"
+       depends on IWLWIFI_LEGACY
+       depends on EVENT_TRACING
+       help
+         Say Y here to trace all commands, including TX frames and IO
+         accesses, sent to the device. If you say yes, iwlwifilegacy will
+         register with the ftrace framework for event tracing and dump
+         all this information to the ringbuffer, you may need to
+         increase the ringbuffer size. See the ftrace documentation
+         for more information.
+
+         When tracing is not enabled, this option still has some
+         (though rather small) overhead.
+
+         If unsure, say Y so we can help you better when problems
+         occur.
+endmenu
+
+config IWL4965
+       tristate "Intel Wireless WiFi 4965AGN (iwl4965)"
+       depends on IWLWIFI_LEGACY
+       ---help---
+         This option enables support for
+
+         Select to build the driver supporting the:
+
+         Intel Wireless WiFi Link 4965AGN
+
+         This driver uses the kernel's mac80211 subsystem.
+
+         In order to use this driver, you will need a microcode (uCode)
+         image for it. You can obtain the microcode from:
+
+                 <http://intellinuxwireless.org/>.
+
+         The microcode is typically installed in /lib/firmware. You can
+         look in the hotplug script /etc/hotplug/firmware.agent to
+         determine which directory FIRMWARE_DIR is set to when the script
+         runs.
+
+         If you want to compile the driver as a module ( = code which can be
+         inserted in and removed from the running kernel whenever you want),
+         say M here and read <file:Documentation/kbuild/modules.txt>.  The
+         module will be called iwl4965.
+
+config IWL3945
+       tristate "Intel PRO/Wireless 3945ABG/BG Network Connection (iwl3945)"
+       depends on IWLWIFI_LEGACY
+       ---help---
+         Select to build the driver supporting the:
+
+         Intel PRO/Wireless 3945ABG/BG Network Connection
+
+         This driver uses the kernel's mac80211 subsystem.
+
+         In order to use this driver, you will need a microcode (uCode)
+         image for it. You can obtain the microcode from:
+
+                 <http://intellinuxwireless.org/>.
+
+         The microcode is typically installed in /lib/firmware. You can
+         look in the hotplug script /etc/hotplug/firmware.agent to
+         determine which directory FIRMWARE_DIR is set to when the script
+         runs.
+
+         If you want to compile the driver as a module ( = code which can be
+         inserted in and removed from the running kernel whenever you want),
+         say M here and read <file:Documentation/kbuild/modules.txt>.  The
+         module will be called iwl3945.
diff --git a/drivers/net/wireless/iwlegacy/Makefile b/drivers/net/wireless/iwlegacy/Makefile
new file mode 100644 (file)
index 0000000..d56aeb3
--- /dev/null
@@ -0,0 +1,25 @@
+obj-$(CONFIG_IWLWIFI_LEGACY)   += iwl-legacy.o
+iwl-legacy-objs                := iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o
+iwl-legacy-objs                += iwl-rx.o iwl-tx.o iwl-sta.o
+iwl-legacy-objs                += iwl-scan.o iwl-led.o
+iwl-legacy-$(CONFIG_IWLWIFI_LEGACY_DEBUGFS) += iwl-debugfs.o
+iwl-legacy-$(CONFIG_IWLWIFI_LEGACY_DEVICE_TRACING) += iwl-devtrace.o
+
+iwl-legacy-objs += $(iwl-legacy-m)
+
+CFLAGS_iwl-devtrace.o := -I$(src)
+
+# 4965
+obj-$(CONFIG_IWL4965)  += iwl4965.o
+iwl4965-objs           := iwl-4965.o iwl4965-base.o iwl-4965-rs.o iwl-4965-led.o
+iwl4965-objs           += iwl-4965-ucode.o iwl-4965-tx.o
+iwl4965-objs           += iwl-4965-lib.o iwl-4965-rx.o iwl-4965-calib.o
+iwl4965-objs           += iwl-4965-sta.o iwl-4965-eeprom.o
+iwl4965-$(CONFIG_IWLWIFI_LEGACY_DEBUGFS) += iwl-4965-debugfs.o
+
+# 3945
+obj-$(CONFIG_IWL3945)  += iwl3945.o
+iwl3945-objs           := iwl3945-base.o iwl-3945.o iwl-3945-rs.o iwl-3945-led.o
+iwl3945-$(CONFIG_IWLWIFI_LEGACY_DEBUGFS) += iwl-3945-debugfs.o
+
+ccflags-y += -D__CHECK_ENDIAN__
@@ -2,7 +2,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -60,12 +60,13 @@ ssize_t iwl3945_ucode_rx_stats_read(struct file *file,
        int bufsz = sizeof(struct iwl39_statistics_rx_phy) * 40 +
                    sizeof(struct iwl39_statistics_rx_non_phy) * 40 + 400;
        ssize_t ret;
-       struct iwl39_statistics_rx_phy *ofdm, *accum_ofdm, *delta_ofdm, *max_ofdm;
+       struct iwl39_statistics_rx_phy *ofdm, *accum_ofdm, *delta_ofdm,
+                                       *max_ofdm;
        struct iwl39_statistics_rx_phy *cck, *accum_cck, *delta_cck, *max_cck;
        struct iwl39_statistics_rx_non_phy *general, *accum_general;
        struct iwl39_statistics_rx_non_phy *delta_general, *max_general;
 
-       if (!iwl_is_alive(priv))
+       if (!iwl_legacy_is_alive(priv))
                return -EAGAIN;
 
        buf = kzalloc(bufsz, GFP_KERNEL);
@@ -335,7 +336,7 @@ ssize_t iwl3945_ucode_tx_stats_read(struct file *file,
        ssize_t ret;
        struct iwl39_statistics_tx *tx, *accum_tx, *delta_tx, *max_tx;
 
-       if (!iwl_is_alive(priv))
+       if (!iwl_legacy_is_alive(priv))
                return -EAGAIN;
 
        buf = kzalloc(bufsz, GFP_KERNEL);
@@ -434,7 +435,7 @@ ssize_t iwl3945_ucode_general_stats_read(struct file *file,
        struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg;
        struct iwl39_statistics_div *div, *accum_div, *delta_div, *max_div;
 
-       if (!iwl_is_alive(priv))
+       if (!iwl_legacy_is_alive(priv))
                return -EAGAIN;
 
        buf = kzalloc(bufsz, GFP_KERNEL);
@@ -2,7 +2,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -30,7 +30,7 @@
 #include "iwl-core.h"
 #include "iwl-debug.h"
 
-#ifdef CONFIG_IWLWIFI_DEBUGFS
+#ifdef CONFIG_IWLWIFI_LEGACY_DEBUGFS
 ssize_t iwl3945_ucode_rx_stats_read(struct file *file, char __user *user_buf,
                                    size_t count, loff_t *ppos);
 ssize_t iwl3945_ucode_tx_stats_read(struct file *file, char __user *user_buf,
similarity index 98%
rename from drivers/net/wireless/iwlwifi/iwl-3945-fh.h
rename to drivers/net/wireless/iwlegacy/iwl-3945-fh.h
index 2c9ed2b..836c991 100644 (file)
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 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
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -185,4 +185,3 @@ struct iwl3945_tfd {
 
 
 #endif /* __iwl_3945_fh_h__ */
-
similarity index 96%
rename from drivers/net/wireless/iwlwifi/iwl-3945-hw.h
rename to drivers/net/wireless/iwlegacy/iwl-3945-hw.h
index 65b5834..779d3cb 100644 (file)
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 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
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -164,12 +164,11 @@ struct iwl3945_eeprom {
 /*
  * Per-channel regulatory data.
  *
- * Each channel that *might* be supported by 3945 or 4965 has a fixed location
+ * Each channel that *might* be supported by 3945 has a fixed location
  * in EEPROM containing EEPROM_CHANNEL_* usage flags (LSB) and max regulatory
  * txpower (MSB).
  *
- * Entries immediately below are for 20 MHz channel width.  HT40 (40 MHz)
- * channels (only for 4965, not supported by 3945) appear later in the EEPROM.
+ * Entries immediately below are for 20 MHz channel width.
  *
  * 2.4 GHz channels 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
  */
similarity index 94%
rename from drivers/net/wireless/iwlwifi/iwl-3945-led.c
rename to drivers/net/wireless/iwlegacy/iwl-3945-led.c
index dc7c3a4..abd9235 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 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
@@ -56,7 +56,7 @@ static int iwl3945_send_led_cmd(struct iwl_priv *priv,
                .callback = NULL,
        };
 
-       return iwl_send_cmd(priv, &cmd);
+       return iwl_legacy_send_cmd(priv, &cmd);
 }
 
 const struct iwl_led_ops iwl3945_led_ops = {
similarity index 95%
rename from drivers/net/wireless/iwlwifi/iwl-3945-led.h
rename to drivers/net/wireless/iwlegacy/iwl-3945-led.h
index ce990ad..9671627 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 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
similarity index 96%
rename from drivers/net/wireless/iwlwifi/iwl-3945-rs.c
rename to drivers/net/wireless/iwlegacy/iwl-3945-rs.c
index 1f3e7e3..977bd24 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 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
@@ -89,7 +89,7 @@ static struct iwl3945_tpt_entry iwl3945_tpt_table_g[] = {
 };
 
 #define IWL_RATE_MAX_WINDOW          62
-#define IWL_RATE_FLUSH          (3*HZ)
+#define IWL_RATE_FLUSH         (3*HZ)
 #define IWL_RATE_WIN_FLUSH       (HZ/2)
 #define IWL39_RATE_HIGH_TH          11520
 #define IWL_SUCCESS_UP_TH         8960
@@ -394,18 +394,18 @@ out:
        IWL_DEBUG_INFO(priv, "leave\n");
 }
 
-static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
+static void *iwl3945_rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
 {
        return hw->priv;
 }
 
 /* rate scale requires free function to be implemented */
-static void rs_free(void *priv)
+static void iwl3945_rs_free(void *priv)
 {
        return;
 }
 
-static void *rs_alloc_sta(void *iwl_priv, struct ieee80211_sta *sta, gfp_t gfp)
+static void *iwl3945_rs_alloc_sta(void *iwl_priv, struct ieee80211_sta *sta, gfp_t gfp)
 {
        struct iwl3945_rs_sta *rs_sta;
        struct iwl3945_sta_priv *psta = (void *) sta->drv_priv;
@@ -423,7 +423,7 @@ static void *rs_alloc_sta(void *iwl_priv, struct ieee80211_sta *sta, gfp_t gfp)
        return rs_sta;
 }
 
-static void rs_free_sta(void *iwl_priv, struct ieee80211_sta *sta,
+static void iwl3945_rs_free_sta(void *iwl_priv, struct ieee80211_sta *sta,
                        void *priv_sta)
 {
        struct iwl3945_rs_sta *rs_sta = priv_sta;
@@ -438,12 +438,12 @@ static void rs_free_sta(void *iwl_priv, struct ieee80211_sta *sta,
 
 
 /**
- * rs_tx_status - Update rate control values based on Tx results
+ * iwl3945_rs_tx_status - Update rate control values based on Tx results
  *
  * NOTE: Uses iwl_priv->retry_rate for the # of retries attempted by
  * the hardware for each rate.
  */
-static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband,
+static void iwl3945_rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband,
                         struct ieee80211_sta *sta, void *priv_sta,
                         struct sk_buff *skb)
 {
@@ -612,7 +612,7 @@ static u16 iwl3945_get_adjacent_rate(struct iwl3945_rs_sta *rs_sta,
 }
 
 /**
- * rs_get_rate - find the rate for the requested packet
+ * iwl3945_rs_get_rate - find the rate for the requested packet
  *
  * Returns the ieee80211_rate structure allocated by the driver.
  *
@@ -627,7 +627,7 @@ static u16 iwl3945_get_adjacent_rate(struct iwl3945_rs_sta *rs_sta,
  * rate table and must reference the driver allocated rate table
  *
  */
-static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
+static void iwl3945_rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
                        void *priv_sta, struct ieee80211_tx_rate_control *txrc)
 {
        struct ieee80211_supported_band *sband = txrc->sband;
@@ -644,7 +644,7 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
        u32 fail_count;
        s8 scale_action = 0;
        unsigned long flags;
-       u16 rate_mask = sta ? sta->supp_rates[sband->band] : 0;
+       u16 rate_mask;
        s8 max_rate_idx = -1;
        struct iwl_priv *priv __maybe_unused = (struct iwl_priv *)priv_r;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
@@ -899,7 +899,8 @@ static void iwl3945_remove_debugfs(void *priv, void *priv_sta)
  * the station is added. Since mac80211 calls this function before a
  * station is added we ignore it.
  */
-static void rs_rate_init_stub(void *priv_r, struct ieee80211_supported_band *sband,
+static void iwl3945_rs_rate_init_stub(void *priv_r,
+                               struct ieee80211_supported_band *sband,
                              struct ieee80211_sta *sta, void *priv_sta)
 {
 }
@@ -907,13 +908,13 @@ static void rs_rate_init_stub(void *priv_r, struct ieee80211_supported_band *sba
 static struct rate_control_ops rs_ops = {
        .module = NULL,
        .name = RS_NAME,
-       .tx_status = rs_tx_status,
-       .get_rate = rs_get_rate,
-       .rate_init = rs_rate_init_stub,
-       .alloc = rs_alloc,
-       .free = rs_free,
-       .alloc_sta = rs_alloc_sta,
-       .free_sta = rs_free_sta,
+       .tx_status = iwl3945_rs_tx_status,
+       .get_rate = iwl3945_rs_get_rate,
+       .rate_init = iwl3945_rs_rate_init_stub,
+       .alloc = iwl3945_rs_alloc,
+       .free = iwl3945_rs_free,
+       .alloc_sta = iwl3945_rs_alloc_sta,
+       .free_sta = iwl3945_rs_free_sta,
 #ifdef CONFIG_MAC80211_DEBUGFS
        .add_sta_debugfs = iwl3945_add_debugfs,
        .remove_sta_debugfs = iwl3945_remove_debugfs,
@@ -991,5 +992,3 @@ void iwl3945_rate_control_unregister(void)
 {
        ieee80211_rate_control_unregister(&rs_ops);
 }
-
-
similarity index 92%
rename from drivers/net/wireless/iwlwifi/iwl-3945.c
rename to drivers/net/wireless/iwlegacy/iwl-3945.c
index f4cd937..d096dc2 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 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
@@ -51,7 +51,6 @@
 #include "iwl-led.h"
 #include "iwl-3945-led.h"
 #include "iwl-3945-debugfs.h"
-#include "iwl-legacy.h"
 
 #define IWL_DECLARE_RATE_INFO(r, ip, in, rp, rn, pp, np)    \
        [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP,   \
@@ -172,14 +171,14 @@ void iwl3945_disable_events(struct iwl_priv *priv)
                return;
        }
 
-       disable_ptr = iwl_read_targ_mem(priv, base + (4 * sizeof(u32)));
-       array_size = iwl_read_targ_mem(priv, base + (5 * sizeof(u32)));
+       disable_ptr = iwl_legacy_read_targ_mem(priv, base + (4 * sizeof(u32)));
+       array_size = iwl_legacy_read_targ_mem(priv, base + (5 * sizeof(u32)));
 
        if (IWL_EVT_DISABLE && (array_size == IWL_EVT_DISABLE_SIZE)) {
                IWL_DEBUG_INFO(priv, "Disabling selected uCode log events at 0x%x\n",
                               disable_ptr);
                for (i = 0; i < IWL_EVT_DISABLE_SIZE; i++)
-                       iwl_write_targ_mem(priv,
+                       iwl_legacy_write_targ_mem(priv,
                                           disable_ptr + (i * sizeof(u32)),
                                           evt_disable[i]);
 
@@ -202,7 +201,7 @@ static int iwl3945_hwrate_to_plcp_idx(u8 plcp)
        return -1;
 }
 
-#ifdef CONFIG_IWLWIFI_DEBUG
+#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG
 #define TX_STATUS_ENTRY(x) case TX_3945_STATUS_FAIL_ ## x: return #x
 
 static const char *iwl3945_get_tx_fail_reason(u32 status)
@@ -255,7 +254,7 @@ int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate)
                break;
        case IEEE80211_BAND_2GHZ:
                if (!(priv->_3945.sta_supp_rates & IWL_OFDM_RATES_MASK) &&
-                   iwl_is_associated(priv, IWL_RXON_CTX_BSS)) {
+                   iwl_legacy_is_associated(priv, IWL_RXON_CTX_BSS)) {
                        if (rate == IWL_RATE_11M_INDEX)
                                next_rate = IWL_RATE_5M_INDEX;
                }
@@ -285,8 +284,9 @@ static void iwl3945_tx_queue_reclaim(struct iwl_priv *priv,
 
        BUG_ON(txq_id == IWL39_CMD_QUEUE_NUM);
 
-       for (index = iwl_queue_inc_wrap(index, q->n_bd); q->read_ptr != index;
-               q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
+       for (index = iwl_legacy_queue_inc_wrap(index, q->n_bd);
+               q->read_ptr != index;
+               q->read_ptr = iwl_legacy_queue_inc_wrap(q->read_ptr, q->n_bd)) {
 
                tx_info = &txq->txb[txq->q.read_ptr];
                ieee80211_tx_status_irqsafe(priv->hw, tx_info->skb);
@@ -294,10 +294,10 @@ static void iwl3945_tx_queue_reclaim(struct iwl_priv *priv,
                priv->cfg->ops->lib->txq_free_tfd(priv, txq);
        }
 
-       if (iwl_queue_space(q) > q->low_mark && (txq_id >= 0) &&
+       if (iwl_legacy_queue_space(q) > q->low_mark && (txq_id >= 0) &&
                        (txq_id != IWL39_CMD_QUEUE_NUM) &&
                        priv->mac80211_registered)
-               iwl_wake_queue(priv, txq);
+               iwl_legacy_wake_queue(priv, txq);
 }
 
 /**
@@ -317,7 +317,7 @@ static void iwl3945_rx_reply_tx(struct iwl_priv *priv,
        int rate_idx;
        int fail;
 
-       if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {
+       if ((index >= txq->q.n_bd) || (iwl_legacy_queue_used(&txq->q, index) == 0)) {
                IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d "
                          "is out of range [0-%d] %d %d\n", txq_id,
                          index, txq->q.n_bd, txq->q.write_ptr,
@@ -363,12 +363,7 @@ static void iwl3945_rx_reply_tx(struct iwl_priv *priv,
  *  RX handler implementations
  *
  *****************************************************************************/
-#ifdef CONFIG_IWLWIFI_DEBUGFS
-/*
- *  based on the assumption of all statistics counter are in DWORD
- *  FIXME: This function is for debugging, do not deal with
- *  the case of counters roll-over.
- */
+#ifdef CONFIG_IWLWIFI_LEGACY_DEBUGFS
 static void iwl3945_accumulative_statistics(struct iwl_priv *priv,
                                            __le32 *stats)
 {
@@ -410,10 +405,10 @@ void iwl3945_hw_rx_statistics(struct iwl_priv *priv,
        IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n",
                     (int)sizeof(struct iwl3945_notif_statistics),
                     le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK);
-#ifdef CONFIG_IWLWIFI_DEBUGFS
+#ifdef CONFIG_IWLWIFI_LEGACY_DEBUGFS
        iwl3945_accumulative_statistics(priv, (__le32 *)&pkt->u.raw);
 #endif
-       iwl_recover_from_statistics(priv, pkt);
+       iwl_legacy_recover_from_statistics(priv, pkt);
 
        memcpy(&priv->_3945.statistics, pkt->u.raw, sizeof(priv->_3945.statistics));
 }
@@ -425,7 +420,7 @@ void iwl3945_reply_statistics(struct iwl_priv *priv,
        __le32 *flag = (__le32 *)&pkt->u.raw;
 
        if (le32_to_cpu(*flag) & UCODE_STATISTICS_CLEAR_MSK) {
-#ifdef CONFIG_IWLWIFI_DEBUGFS
+#ifdef CONFIG_IWLWIFI_LEGACY_DEBUGFS
                memset(&priv->_3945.accum_statistics, 0,
                        sizeof(struct iwl3945_notif_statistics));
                memset(&priv->_3945.delta_statistics, 0,
@@ -496,14 +491,14 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv,
        }
 
        if (!iwl3945_mod_params.sw_crypto)
-               iwl_set_decrypted_flag(priv,
+               iwl_legacy_set_decrypted_flag(priv,
                                       (struct ieee80211_hdr *)rxb_addr(rxb),
                                       le32_to_cpu(rx_end->status), stats);
 
        skb_add_rx_frag(skb, 0, rxb->page,
                        (void *)rx_hdr->payload - (void *)pkt, len);
 
-       iwl_update_stats(priv, false, fc, len);
+       iwl_legacy_update_stats(priv, false, fc, len);
        memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats));
 
        ieee80211_rx(priv->hw, skb);
@@ -576,7 +571,8 @@ static void iwl3945_rx_reply_rx(struct iwl_priv *priv,
                              rx_status.signal, rx_status.signal,
                              rx_status.rate_idx);
 
-       iwl_dbg_log_rx_data_frame(priv, le16_to_cpu(rx_hdr->len), header);
+       iwl_legacy_dbg_log_rx_data_frame(priv, le16_to_cpu(rx_hdr->len),
+                                               header);
 
        if (network_packet) {
                priv->_3945.last_beacon_time =
@@ -744,7 +740,7 @@ static u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate)
        station->sta.sta.modify_mask = STA_MODIFY_TX_RATE_MSK;
        station->sta.rate_n_flags = cpu_to_le16(tx_rate);
        station->sta.mode = STA_CONTROL_MODIFY_MSK;
-       iwl_send_add_sta(priv, &station->sta, CMD_ASYNC);
+       iwl_legacy_send_add_sta(priv, &station->sta, CMD_ASYNC);
        spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
 
        IWL_DEBUG_RATE(priv, "SCALE sync station %d to rate %d\n",
@@ -759,7 +755,7 @@ static void iwl3945_set_pwr_vmain(struct iwl_priv *priv)
  * 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,
+                       iwl_legacy_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
                                        APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
                                        ~APMG_PS_CTRL_MSK_PWR_SRC);
 
@@ -769,7 +765,7 @@ static void iwl3945_set_pwr_vmain(struct iwl_priv *priv)
                }
  */
 
-       iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
+       iwl_legacy_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
                        APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
                        ~APMG_PS_CTRL_MSK_PWR_SRC);
 
@@ -779,10 +775,11 @@ static void iwl3945_set_pwr_vmain(struct iwl_priv *priv)
 
 static int iwl3945_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
 {
-       iwl_write_direct32(priv, FH39_RCSR_RBD_BASE(0), rxq->bd_dma);
-       iwl_write_direct32(priv, FH39_RCSR_RPTR_ADDR(0), rxq->rb_stts_dma);
-       iwl_write_direct32(priv, FH39_RCSR_WPTR(0), 0);
-       iwl_write_direct32(priv, FH39_RCSR_CONFIG(0),
+       iwl_legacy_write_direct32(priv, FH39_RCSR_RBD_BASE(0), rxq->bd_dma);
+       iwl_legacy_write_direct32(priv, FH39_RCSR_RPTR_ADDR(0),
+                                       rxq->rb_stts_dma);
+       iwl_legacy_write_direct32(priv, FH39_RCSR_WPTR(0), 0);
+       iwl_legacy_write_direct32(priv, FH39_RCSR_CONFIG(0),
                FH39_RCSR_RX_CONFIG_REG_VAL_DMA_CHNL_EN_ENABLE |
                FH39_RCSR_RX_CONFIG_REG_VAL_RDRBD_EN_ENABLE |
                FH39_RCSR_RX_CONFIG_REG_BIT_WR_STTS_EN |
@@ -793,7 +790,7 @@ static int iwl3945_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
                FH39_RCSR_RX_CONFIG_REG_VAL_MSG_MODE_FH);
 
        /* fake read to flush all prev I/O */
-       iwl_read_direct32(priv, FH39_RSSR_CTRL);
+       iwl_legacy_read_direct32(priv, FH39_RSSR_CTRL);
 
        return 0;
 }
@@ -802,23 +799,23 @@ static int iwl3945_tx_reset(struct iwl_priv *priv)
 {
 
        /* bypass mode */
-       iwl_write_prph(priv, ALM_SCD_MODE_REG, 0x2);
+       iwl_legacy_write_prph(priv, ALM_SCD_MODE_REG, 0x2);
 
        /* RA 0 is active */
-       iwl_write_prph(priv, ALM_SCD_ARASTAT_REG, 0x01);
+       iwl_legacy_write_prph(priv, ALM_SCD_ARASTAT_REG, 0x01);
 
        /* all 6 fifo are active */
-       iwl_write_prph(priv, ALM_SCD_TXFACT_REG, 0x3f);
+       iwl_legacy_write_prph(priv, ALM_SCD_TXFACT_REG, 0x3f);
 
-       iwl_write_prph(priv, ALM_SCD_SBYP_MODE_1_REG, 0x010000);
-       iwl_write_prph(priv, ALM_SCD_SBYP_MODE_2_REG, 0x030002);
-       iwl_write_prph(priv, ALM_SCD_TXF4MF_REG, 0x000004);
-       iwl_write_prph(priv, ALM_SCD_TXF5MF_REG, 0x000005);
+       iwl_legacy_write_prph(priv, ALM_SCD_SBYP_MODE_1_REG, 0x010000);
+       iwl_legacy_write_prph(priv, ALM_SCD_SBYP_MODE_2_REG, 0x030002);
+       iwl_legacy_write_prph(priv, ALM_SCD_TXF4MF_REG, 0x000004);
+       iwl_legacy_write_prph(priv, ALM_SCD_TXF5MF_REG, 0x000005);
 
-       iwl_write_direct32(priv, FH39_TSSR_CBB_BASE,
+       iwl_legacy_write_direct32(priv, FH39_TSSR_CBB_BASE,
                             priv->_3945.shared_phys);
 
-       iwl_write_direct32(priv, FH39_TSSR_MSG_CONFIG,
+       iwl_legacy_write_direct32(priv, FH39_TSSR_MSG_CONFIG,
                FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON |
                FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_TXPD_ON |
                FH39_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_128B |
@@ -844,7 +841,7 @@ static int iwl3945_txq_ctx_reset(struct iwl_priv *priv)
        iwl3945_hw_txq_ctx_free(priv);
 
        /* allocate tx queue structure */
-       rc = iwl_alloc_txq_mem(priv);
+       rc = iwl_legacy_alloc_txq_mem(priv);
        if (rc)
                return rc;
 
@@ -857,8 +854,8 @@ static int iwl3945_txq_ctx_reset(struct iwl_priv *priv)
        for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
                slots_num = (txq_id == IWL39_CMD_QUEUE_NUM) ?
                                TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
-               rc = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num,
-                                      txq_id);
+               rc = iwl_legacy_tx_queue_init(priv, &priv->txq[txq_id],
+                                               slots_num, txq_id);
                if (rc) {
                        IWL_ERR(priv, "Tx %d queue init failed\n", txq_id);
                        goto error;
@@ -875,21 +872,23 @@ static int iwl3945_txq_ctx_reset(struct iwl_priv *priv)
 
 /*
  * Start up 3945's basic functionality after it has been reset
- * (e.g. after platform boot, or shutdown via iwl_apm_stop())
+ * (e.g. after platform boot, or shutdown via iwl_legacy_apm_stop())
  * NOTE:  This does not load uCode nor start the embedded processor
  */
 static int iwl3945_apm_init(struct iwl_priv *priv)
 {
-       int ret = iwl_apm_init(priv);
+       int ret = iwl_legacy_apm_init(priv);
 
        /* Clear APMG (NIC's internal power management) interrupts */
-       iwl_write_prph(priv, APMG_RTC_INT_MSK_REG, 0x0);
-       iwl_write_prph(priv, APMG_RTC_INT_STT_REG, 0xFFFFFFFF);
+       iwl_legacy_write_prph(priv, APMG_RTC_INT_MSK_REG, 0x0);
+       iwl_legacy_write_prph(priv, APMG_RTC_INT_STT_REG, 0xFFFFFFFF);
 
        /* Reset radio chip */
-       iwl_set_bits_prph(priv, APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_RESET_REQ);
+       iwl_legacy_set_bits_prph(priv, APMG_PS_CTRL_REG,
+                               APMG_PS_CTRL_VAL_RESET_REQ);
        udelay(5);
-       iwl_clear_bits_prph(priv, APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_RESET_REQ);
+       iwl_legacy_clear_bits_prph(priv, APMG_PS_CTRL_REG,
+                               APMG_PS_CTRL_VAL_RESET_REQ);
 
        return ret;
 }
@@ -909,17 +908,17 @@ static void iwl3945_nic_config(struct iwl_priv *priv)
                IWL_DEBUG_INFO(priv, "RTP type\n");
        else if (rev_id & PCI_CFG_REV_ID_BIT_BASIC_SKU) {
                IWL_DEBUG_INFO(priv, "3945 RADIO-MB type\n");
-               iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+               iwl_legacy_set_bit(priv, CSR_HW_IF_CONFIG_REG,
                            CSR39_HW_IF_CONFIG_REG_BIT_3945_MB);
        } else {
                IWL_DEBUG_INFO(priv, "3945 RADIO-MM type\n");
-               iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+               iwl_legacy_set_bit(priv, CSR_HW_IF_CONFIG_REG,
                            CSR39_HW_IF_CONFIG_REG_BIT_3945_MM);
        }
 
        if (EEPROM_SKU_CAP_OP_MODE_MRC == eeprom->sku_cap) {
                IWL_DEBUG_INFO(priv, "SKU OP mode is mrc\n");
-               iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+               iwl_legacy_set_bit(priv, CSR_HW_IF_CONFIG_REG,
                            CSR39_HW_IF_CONFIG_REG_BIT_SKU_MRC);
        } else
                IWL_DEBUG_INFO(priv, "SKU OP mode is basic\n");
@@ -927,24 +926,24 @@ static void iwl3945_nic_config(struct iwl_priv *priv)
        if ((eeprom->board_revision & 0xF0) == 0xD0) {
                IWL_DEBUG_INFO(priv, "3945ABG revision is 0x%X\n",
                               eeprom->board_revision);
-               iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+               iwl_legacy_set_bit(priv, CSR_HW_IF_CONFIG_REG,
                            CSR39_HW_IF_CONFIG_REG_BIT_BOARD_TYPE);
        } else {
                IWL_DEBUG_INFO(priv, "3945ABG revision is 0x%X\n",
                               eeprom->board_revision);
-               iwl_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
+               iwl_legacy_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
                              CSR39_HW_IF_CONFIG_REG_BIT_BOARD_TYPE);
        }
 
        if (eeprom->almgor_m_version <= 1) {
-               iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+               iwl_legacy_set_bit(priv, CSR_HW_IF_CONFIG_REG,
                            CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_A);
                IWL_DEBUG_INFO(priv, "Card M type A version is 0x%X\n",
                               eeprom->almgor_m_version);
        } else {
                IWL_DEBUG_INFO(priv, "Card M type B version is 0x%X\n",
                               eeprom->almgor_m_version);
-               iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+               iwl_legacy_set_bit(priv, CSR_HW_IF_CONFIG_REG,
                            CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_B);
        }
        spin_unlock_irqrestore(&priv->lock, flags);
@@ -972,7 +971,7 @@ int iwl3945_hw_nic_init(struct iwl_priv *priv)
 
        /* Allocate the RX queue, or reset if it is already allocated */
        if (!rxq->bd) {
-               rc = iwl_rx_queue_alloc(priv);
+               rc = iwl_legacy_rx_queue_alloc(priv);
                if (rc) {
                        IWL_ERR(priv, "Unable to initialize Rx queue\n");
                        return -ENOMEM;
@@ -987,10 +986,10 @@ int iwl3945_hw_nic_init(struct iwl_priv *priv)
 
        /* Look at using this instead:
        rxq->need_update = 1;
-       iwl_rx_queue_update_write_ptr(priv, rxq);
+       iwl_legacy_rx_queue_update_write_ptr(priv, rxq);
        */
 
-       iwl_write_direct32(priv, FH39_RCSR_WPTR(0), rxq->write & ~7);
+       iwl_legacy_write_direct32(priv, FH39_RCSR_WPTR(0), rxq->write & ~7);
 
        rc = iwl3945_txq_ctx_reset(priv);
        if (rc)
@@ -1015,12 +1014,12 @@ void iwl3945_hw_txq_ctx_free(struct iwl_priv *priv)
                for (txq_id = 0; txq_id < priv->hw_params.max_txq_num;
                     txq_id++)
                        if (txq_id == IWL39_CMD_QUEUE_NUM)
-                               iwl_cmd_queue_free(priv);
+                               iwl_legacy_cmd_queue_free(priv);
                        else
-                               iwl_tx_queue_free(priv, txq_id);
+                               iwl_legacy_tx_queue_free(priv, txq_id);
 
        /* free tx queue structure */
-       iwl_free_txq_mem(priv);
+       iwl_legacy_txq_mem(priv);
 }
 
 void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv)
@@ -1028,12 +1027,12 @@ void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv)
        int txq_id;
 
        /* stop SCD */
-       iwl_write_prph(priv, ALM_SCD_MODE_REG, 0);
-       iwl_write_prph(priv, ALM_SCD_TXFACT_REG, 0);
+       iwl_legacy_write_prph(priv, ALM_SCD_MODE_REG, 0);
+       iwl_legacy_write_prph(priv, ALM_SCD_TXFACT_REG, 0);
 
        /* reset TFD queues */
        for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
-               iwl_write_direct32(priv, FH39_TCSR_CONFIG(txq_id), 0x0);
+               iwl_legacy_write_direct32(priv, FH39_TCSR_CONFIG(txq_id), 0x0);
                iwl_poll_direct_bit(priv, FH39_TSSR_TX_STATUS,
                                FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(txq_id),
                                1000);
@@ -1100,12 +1099,12 @@ static int iwl3945_hw_reg_txpower_get_temperature(struct iwl_priv *priv)
 #define IWL_TEMPERATURE_LIMIT_TIMER   6
 
 /**
- * is_temp_calib_needed - determines if new calibration is needed
+ * iwl3945_is_temp_calib_needed - determines if new calibration is needed
  *
  * records new temperature in tx_mgr->temperature.
  * replaces tx_mgr->last_temperature *only* if calib needed
  *    (assumes caller will actually do the calibration!). */
-static int is_temp_calib_needed(struct iwl_priv *priv)
+static int iwl3945_is_temp_calib_needed(struct iwl_priv *priv)
 {
        int temp_diff;
 
@@ -1336,9 +1335,6 @@ static void iwl3945_hw_reg_set_scan_power(struct iwl_priv *priv, u32 scan_tbl_in
         *   based on eeprom channel data) for this channel.  */
        power = min(ch_info->scan_power, clip_pwrs[IWL_RATE_6M_INDEX_TABLE]);
 
-       /* further limit to user's max power preference.
-        * FIXME:  Other spectrum management power limitations do not
-        *   seem to apply?? */
        power = min(power, priv->tx_power_user_lmt);
        scan_power_info->requested_power = power;
 
@@ -1392,7 +1388,7 @@ static int iwl3945_send_tx_power(struct iwl_priv *priv)
        chan = le16_to_cpu(priv->contexts[IWL_RXON_CTX_BSS].active.channel);
 
        txpower.band = (priv->band == IEEE80211_BAND_5GHZ) ? 0 : 1;
-       ch_info = iwl_get_channel_info(priv, priv->band, chan);
+       ch_info = iwl_legacy_get_channel_info(priv, priv->band, chan);
        if (!ch_info) {
                IWL_ERR(priv,
                        "Failed to get channel info for channel %d [%d]\n",
@@ -1400,7 +1396,7 @@ static int iwl3945_send_tx_power(struct iwl_priv *priv)
                return -EINVAL;
        }
 
-       if (!is_channel_valid(ch_info)) {
+       if (!iwl_legacy_is_channel_valid(ch_info)) {
                IWL_DEBUG_POWER(priv, "Not calling TX_PWR_TABLE_CMD on "
                                "non-Tx channel.\n");
                return 0;
@@ -1435,7 +1431,7 @@ static int iwl3945_send_tx_power(struct iwl_priv *priv)
                                txpower.power[i].rate);
        }
 
-       return iwl_send_cmd_pdu(priv, REPLY_TX_PWR_TABLE_CMD,
+       return iwl_legacy_send_cmd_pdu(priv, REPLY_TX_PWR_TABLE_CMD,
                                sizeof(struct iwl3945_txpowertable_cmd),
                                &txpower);
 
@@ -1569,7 +1565,7 @@ static int iwl3945_hw_reg_comp_txpower_temp(struct iwl_priv *priv)
        /* set up new Tx power info for each and every channel, 2.4 and 5.x */
        for (i = 0; i < priv->channel_count; i++) {
                ch_info = &priv->channel_info[i];
-               a_band = is_channel_a_band(ch_info);
+               a_band = iwl_legacy_is_channel_a_band(ch_info);
 
                /* Get this chnlgrp's factory calibration temperature */
                ref_temp = (s16)eeprom->groups[ch_info->group_index].
@@ -1635,7 +1631,7 @@ int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power)
 
        for (i = 0; i < priv->channel_count; i++) {
                ch_info = &priv->channel_info[i];
-               a_band = is_channel_a_band(ch_info);
+               a_band = iwl_legacy_is_channel_a_band(ch_info);
 
                /* find minimum power of all user and regulatory constraints
                 *    (does not consider h/w clipping limitations) */
@@ -1651,7 +1647,7 @@ int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power)
 
        /* update txpower settings for all channels,
         *   send to NIC if associated. */
-       is_temp_calib_needed(priv);
+       iwl3945_is_temp_calib_needed(priv);
        iwl3945_hw_reg_comp_txpower_temp(priv);
 
        return 0;
@@ -1669,8 +1665,8 @@ static int iwl3945_send_rxon_assoc(struct iwl_priv *priv,
                .flags = CMD_WANT_SKB,
                .data = &rxon_assoc,
        };
-       const struct iwl_rxon_cmd *rxon1 = &ctx->staging;
-       const struct iwl_rxon_cmd *rxon2 = &ctx->active;
+       const struct iwl_legacy_rxon_cmd *rxon1 = &ctx->staging;
+       const struct iwl_legacy_rxon_cmd *rxon2 = &ctx->active;
 
        if ((rxon1->flags == rxon2->flags) &&
            (rxon1->filter_flags == rxon2->filter_flags) &&
@@ -1686,7 +1682,7 @@ static int iwl3945_send_rxon_assoc(struct iwl_priv *priv,
        rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates;
        rxon_assoc.reserved = 0;
 
-       rc = iwl_send_cmd_sync(priv, &cmd);
+       rc = iwl_legacy_send_cmd_sync(priv, &cmd);
        if (rc)
                return rc;
 
@@ -1696,7 +1692,7 @@ static int iwl3945_send_rxon_assoc(struct iwl_priv *priv,
                rc = -EIO;
        }
 
-       iwl_free_pages(priv, cmd.reply_page);
+       iwl_legacy_free_pages(priv, cmd.reply_page);
 
        return rc;
 }
@@ -1720,7 +1716,7 @@ int iwl3945_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return -EINVAL;
 
-       if (!iwl_is_alive(priv))
+       if (!iwl_legacy_is_alive(priv))
                return -1;
 
        /* always get timestamp with Rx frame */
@@ -1731,7 +1727,7 @@ int iwl3945_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
            ~(RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_SEL_MSK);
        staging_rxon->flags |= iwl3945_get_antenna_flags(priv);
 
-       rc = iwl_check_rxon_cmd(priv, ctx);
+       rc = iwl_legacy_check_rxon_cmd(priv, ctx);
        if (rc) {
                IWL_ERR(priv, "Invalid RXON configuration.  Not committing.\n");
                return -EINVAL;
@@ -1740,8 +1736,9 @@ int iwl3945_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
        /* If we don't need to send a full RXON, we can use
         * iwl3945_rxon_assoc_cmd which is used to reconfigure filter
         * and other flags for the current radio configuration. */
-       if (!iwl_full_rxon_required(priv, &priv->contexts[IWL_RXON_CTX_BSS])) {
-               rc = iwl_send_rxon_assoc(priv,
+       if (!iwl_legacy_full_rxon_required(priv,
+                       &priv->contexts[IWL_RXON_CTX_BSS])) {
+               rc = iwl_legacy_send_rxon_assoc(priv,
                                         &priv->contexts[IWL_RXON_CTX_BSS]);
                if (rc) {
                        IWL_ERR(priv, "Error setting RXON_ASSOC "
@@ -1758,7 +1755,7 @@ int iwl3945_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
         * an RXON_ASSOC and the new config wants the associated mask enabled,
         * we must clear the associated from the active configuration
         * before we apply the new config */
-       if (iwl_is_associated(priv, IWL_RXON_CTX_BSS) && new_assoc) {
+       if (iwl_legacy_is_associated(priv, IWL_RXON_CTX_BSS) && new_assoc) {
                IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n");
                active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
 
@@ -1768,7 +1765,7 @@ int iwl3945_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
                 */
                active_rxon->reserved4 = 0;
                active_rxon->reserved5 = 0;
-               rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
+               rc = iwl_legacy_send_cmd_pdu(priv, REPLY_RXON,
                                      sizeof(struct iwl3945_rxon_cmd),
                                      &priv->contexts[IWL_RXON_CTX_BSS].active);
 
@@ -1780,9 +1777,10 @@ int iwl3945_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
                                  "configuration (%d).\n", rc);
                        return rc;
                }
-               iwl_clear_ucode_stations(priv,
+               iwl_legacy_clear_ucode_stations(priv,
+                                        &priv->contexts[IWL_RXON_CTX_BSS]);
+               iwl_legacy_restore_stations(priv,
                                         &priv->contexts[IWL_RXON_CTX_BSS]);
-               iwl_restore_stations(priv, &priv->contexts[IWL_RXON_CTX_BSS]);
        }
 
        IWL_DEBUG_INFO(priv, "Sending RXON\n"
@@ -1800,10 +1798,10 @@ int iwl3945_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
        staging_rxon->reserved4 = 0;
        staging_rxon->reserved5 = 0;
 
-       iwl_set_rxon_hwcrypto(priv, ctx, !iwl3945_mod_params.sw_crypto);
+       iwl_legacy_set_rxon_hwcrypto(priv, ctx, !iwl3945_mod_params.sw_crypto);
 
        /* Apply the new configuration */
-       rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
+       rc = iwl_legacy_send_cmd_pdu(priv, REPLY_RXON,
                              sizeof(struct iwl3945_rxon_cmd),
                              staging_rxon);
        if (rc) {
@@ -1814,14 +1812,15 @@ int iwl3945_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
        memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));
 
        if (!new_assoc) {
-               iwl_clear_ucode_stations(priv,
+               iwl_legacy_clear_ucode_stations(priv,
                                         &priv->contexts[IWL_RXON_CTX_BSS]);
-               iwl_restore_stations(priv, &priv->contexts[IWL_RXON_CTX_BSS]);
+               iwl_legacy_restore_stations(priv,
+                                       &priv->contexts[IWL_RXON_CTX_BSS]);
        }
 
        /* If we issue a new RXON command which required a tune then we must
         * send a new TXPOWER command or we won't be able to Tx any frames */
-       rc = iwl_set_tx_power(priv, priv->tx_power_next, true);
+       rc = iwl_legacy_set_tx_power(priv, priv->tx_power_next, true);
        if (rc) {
                IWL_ERR(priv, "Error setting Tx power (%d).\n", rc);
                return rc;
@@ -1851,7 +1850,7 @@ void iwl3945_reg_txpower_periodic(struct iwl_priv *priv)
 {
        /* This will kick in the "brute force"
         * iwl3945_hw_reg_comp_txpower_temp() below */
-       if (!is_temp_calib_needed(priv))
+       if (!iwl3945_is_temp_calib_needed(priv))
                goto reschedule;
 
        /* Set up a new set of temp-adjusted TxPowers, send to NIC.
@@ -1898,7 +1897,7 @@ static u16 iwl3945_hw_reg_get_ch_grp_index(struct iwl_priv *priv,
        u8 grp_channel;
 
        /* Find the group index for the channel ... don't use index 1(?) */
-       if (is_channel_a_band(ch_info)) {
+       if (iwl_legacy_is_channel_a_band(ch_info)) {
                for (group = 1; group < 5; group++) {
                        grp_channel = ch_grp[group].group_channel;
                        if (ch_info->channel <= grp_channel) {
@@ -2078,8 +2077,8 @@ int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv)
        /* initialize Tx power info for each and every channel, 2.4 and 5.x */
        for (i = 0, ch_info = priv->channel_info; i < priv->channel_count;
             i++, ch_info++) {
-               a_band = is_channel_a_band(ch_info);
-               if (!is_channel_valid(ch_info))
+               a_band = iwl_legacy_is_channel_a_band(ch_info);
+               if (!iwl_legacy_is_channel_valid(ch_info))
                        continue;
 
                /* find this channel's channel group (*not* "band") index */
@@ -2182,7 +2181,7 @@ int iwl3945_hw_rxq_stop(struct iwl_priv *priv)
 {
        int rc;
 
-       iwl_write_direct32(priv, FH39_RCSR_CONFIG(0), 0);
+       iwl_legacy_write_direct32(priv, FH39_RCSR_CONFIG(0), 0);
        rc = iwl_poll_direct_bit(priv, FH39_RSSR_STATUS,
                        FH39_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000);
        if (rc < 0)
@@ -2199,10 +2198,10 @@ int iwl3945_hw_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq)
 
        shared_data->tx_base_ptr[txq_id] = cpu_to_le32((u32)txq->q.dma_addr);
 
-       iwl_write_direct32(priv, FH39_CBCC_CTRL(txq_id), 0);
-       iwl_write_direct32(priv, FH39_CBCC_BASE(txq_id), 0);
+       iwl_legacy_write_direct32(priv, FH39_CBCC_CTRL(txq_id), 0);
+       iwl_legacy_write_direct32(priv, FH39_CBCC_BASE(txq_id), 0);
 
-       iwl_write_direct32(priv, FH39_TCSR_CONFIG(txq_id),
+       iwl_legacy_write_direct32(priv, FH39_TCSR_CONFIG(txq_id),
                FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_NOINT |
                FH39_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_TXF |
                FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD |
@@ -2231,7 +2230,8 @@ static u16 iwl3945_get_hcmd_size(u8 cmd_id, u16 len)
 }
 
 
-static u16 iwl3945_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
+static u16 iwl3945_build_addsta_hcmd(const struct iwl_legacy_addsta_cmd *cmd,
+                                                               u8 *data)
 {
        struct iwl3945_addsta_cmd *addsta = (struct iwl3945_addsta_cmd *)data;
        addsta->mode = cmd->mode;
@@ -2259,7 +2259,7 @@ static int iwl3945_add_bssid_station(struct iwl_priv *priv,
        if (sta_id_r)
                *sta_id_r = IWL_INVALID_STATION;
 
-       ret = iwl_add_station_common(priv, ctx, addr, 0, NULL, &sta_id);
+       ret = iwl_legacy_add_station_common(priv, ctx, addr, 0, NULL, &sta_id);
        if (ret) {
                IWL_ERR(priv, "Unable to add station %pM\n", addr);
                return ret;
@@ -2294,7 +2294,7 @@ static int iwl3945_manage_ibss_station(struct iwl_priv *priv,
                return 0;
        }
 
-       return iwl_remove_station(priv, vif_priv->ibss_bssid_sta_id,
+       return iwl_legacy_remove_station(priv, vif_priv->ibss_bssid_sta_id,
                                  vif->bss_conf.bssid);
 }
 
@@ -2345,7 +2345,7 @@ int iwl3945_init_hw_rate_table(struct iwl_priv *priv)
                 * 1M CCK rates */
 
                if (!(priv->_3945.sta_supp_rates & IWL_OFDM_RATES_MASK) &&
-                   iwl_is_associated(priv, IWL_RXON_CTX_BSS)) {
+                   iwl_legacy_is_associated(priv, IWL_RXON_CTX_BSS)) {
 
                        index = IWL_FIRST_CCK_RATE;
                        for (i = IWL_RATE_6M_INDEX_TABLE;
@@ -2366,14 +2366,14 @@ int iwl3945_init_hw_rate_table(struct iwl_priv *priv)
 
        /* Update the rate scaling for control frame Tx */
        rate_cmd.table_id = 0;
-       rc = iwl_send_cmd_pdu(priv, REPLY_RATE_SCALE, sizeof(rate_cmd),
+       rc = iwl_legacy_send_cmd_pdu(priv, REPLY_RATE_SCALE, sizeof(rate_cmd),
                              &rate_cmd);
        if (rc)
                return rc;
 
        /* Update the rate scaling for data frame Tx */
        rate_cmd.table_id = 1;
-       return iwl_send_cmd_pdu(priv, REPLY_RATE_SCALE, sizeof(rate_cmd),
+       return iwl_legacy_send_cmd_pdu(priv, REPLY_RATE_SCALE, sizeof(rate_cmd),
                                &rate_cmd);
 }
 
@@ -2473,11 +2473,11 @@ static int iwl3945_verify_bsm(struct iwl_priv *priv)
        IWL_DEBUG_INFO(priv, "Begin verify bsm\n");
 
        /* verify BSM SRAM contents */
-       val = iwl_read_prph(priv, BSM_WR_DWCOUNT_REG);
+       val = iwl_legacy_read_prph(priv, BSM_WR_DWCOUNT_REG);
        for (reg = BSM_SRAM_LOWER_BOUND;
             reg < BSM_SRAM_LOWER_BOUND + len;
             reg += sizeof(u32), image++) {
-               val = iwl_read_prph(priv, reg);
+               val = iwl_legacy_read_prph(priv, reg);
                if (val != le32_to_cpu(*image)) {
                        IWL_ERR(priv, "BSM uCode verification failed at "
                                  "addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n",
@@ -2510,7 +2510,7 @@ static int iwl3945_verify_bsm(struct iwl_priv *priv)
  */
 static int iwl3945_eeprom_acquire_semaphore(struct iwl_priv *priv)
 {
-       _iwl_clear_bit(priv, CSR_EEPROM_GP, CSR_EEPROM_GP_IF_OWNER_MSK);
+       _iwl_legacy_clear_bit(priv, CSR_EEPROM_GP, CSR_EEPROM_GP_IF_OWNER_MSK);
        return 0;
 }
 
@@ -2581,16 +2581,16 @@ static int iwl3945_load_bsm(struct iwl_priv *priv)
        inst_len = priv->ucode_init.len;
        data_len = priv->ucode_init_data.len;
 
-       iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst);
-       iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata);
-       iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len);
-       iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, data_len);
+       iwl_legacy_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst);
+       iwl_legacy_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata);
+       iwl_legacy_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len);
+       iwl_legacy_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, data_len);
 
        /* Fill BSM memory with bootstrap instructions */
        for (reg_offset = BSM_SRAM_LOWER_BOUND;
             reg_offset < BSM_SRAM_LOWER_BOUND + len;
             reg_offset += sizeof(u32), image++)
-               _iwl_write_prph(priv, reg_offset,
+               _iwl_legacy_write_prph(priv, reg_offset,
                                          le32_to_cpu(*image));
 
        rc = iwl3945_verify_bsm(priv);
@@ -2598,19 +2598,19 @@ static int iwl3945_load_bsm(struct iwl_priv *priv)
                return rc;
 
        /* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */
-       iwl_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0);
-       iwl_write_prph(priv, BSM_WR_MEM_DST_REG,
+       iwl_legacy_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0);
+       iwl_legacy_write_prph(priv, BSM_WR_MEM_DST_REG,
                                 IWL39_RTC_INST_LOWER_BOUND);
-       iwl_write_prph(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32));
+       iwl_legacy_write_prph(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32));
 
        /* Load bootstrap code into instruction SRAM now,
         *   to prepare to load "initialize" uCode */
-       iwl_write_prph(priv, BSM_WR_CTRL_REG,
+       iwl_legacy_write_prph(priv, BSM_WR_CTRL_REG,
                BSM_WR_CTRL_REG_BIT_START);
 
        /* Wait for load of bootstrap uCode to finish */
        for (i = 0; i < 100; i++) {
-               done = iwl_read_prph(priv, BSM_WR_CTRL_REG);
+               done = iwl_legacy_read_prph(priv, BSM_WR_CTRL_REG);
                if (!(done & BSM_WR_CTRL_REG_BIT_START))
                        break;
                udelay(10);
@@ -2624,7 +2624,7 @@ static int iwl3945_load_bsm(struct iwl_priv *priv)
 
        /* Enable future boot loads whenever power management unit triggers it
         *   (e.g. when powering back up after power-save shutdown) */
-       iwl_write_prph(priv, BSM_WR_CTRL_REG,
+       iwl_legacy_write_prph(priv, BSM_WR_CTRL_REG,
                BSM_WR_CTRL_REG_BIT_START_EN);
 
        return 0;
@@ -2633,7 +2633,6 @@ static int iwl3945_load_bsm(struct iwl_priv *priv)
 static struct iwl_hcmd_ops iwl3945_hcmd = {
        .rxon_assoc = iwl3945_send_rxon_assoc,
        .commit_rxon = iwl3945_commit_rxon,
-       .send_bt_config = iwl_send_bt_config,
 };
 
 static struct iwl_lib_ops iwl3945_lib = {
@@ -2659,13 +2658,9 @@ static struct iwl_lib_ops iwl3945_lib = {
                },
                .acquire_semaphore = iwl3945_eeprom_acquire_semaphore,
                .release_semaphore = iwl3945_eeprom_release_semaphore,
-               .query_addr = iwlcore_eeprom_query_addr,
        },
        .send_tx_power  = iwl3945_send_tx_power,
        .is_valid_rtc_data_addr = iwl3945_hw_valid_rtc_data_addr,
-       .isr_ops = {
-               .isr = iwl_isr_legacy,
-       },
 
        .debugfs_ops = {
                .rx_stats_read = iwl3945_ucode_rx_stats_read,
@@ -2683,7 +2678,6 @@ static const struct iwl_legacy_ops iwl3945_legacy_ops = {
 static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
        .get_hcmd_size = iwl3945_get_hcmd_size,
        .build_addsta_hcmd = iwl3945_build_addsta_hcmd,
-       .tx_cmd_protection = iwl_legacy_tx_cmd_protection,
        .request_scan = iwl3945_request_scan,
        .post_scan = iwl3945_post_scan,
 };
@@ -2703,13 +2697,10 @@ static struct iwl_base_params iwl3945_base_params = {
        .pll_cfg_val = CSR39_ANA_PLL_CFG_VAL,
        .set_l0s = false,
        .use_bsm = true,
-       .use_isr_legacy = true,
        .led_compensation = 64,
-       .broken_powersave = true,
        .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
        .wd_timeout = IWL_DEF_WD_TIMEOUT,
        .max_event_log_size = 512,
-       .tx_power_by_driver = true,
 };
 
 static struct iwl_cfg iwl3945_bg_cfg = {
similarity index 97%
rename from drivers/net/wireless/iwlwifi/iwl-3945.h
rename to drivers/net/wireless/iwlegacy/iwl-3945.h
index 3eef1eb..b118b59 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 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
@@ -108,7 +108,7 @@ struct iwl3945_rs_sta {
 
 /*
  * The common struct MUST be first because it is shared between
- * 3945 and agn!
+ * 3945 and 4965!
  */
 struct iwl3945_sta_priv {
        struct iwl_station_priv_common common;
@@ -201,7 +201,7 @@ struct iwl3945_ibss_seq {
 
 /******************************************************************************
  *
- * Functions implemented in iwl-base.c which are forward declared here
+ * Functions implemented in iwl3945-base.c which are forward declared here
  * for use by iwl-*.c
  *
  *****************************************************************************/
@@ -209,7 +209,7 @@ extern int iwl3945_calc_db_from_ratio(int sig_ratio);
 extern void iwl3945_rx_replenish(void *data);
 extern void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
 extern unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv,
-                                       struct ieee80211_hdr *hdr,int left);
+                                       struct ieee80211_hdr *hdr, int left);
 extern int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
                                       char **buf, bool display);
 extern void iwl3945_dump_nic_error_log(struct iwl_priv *priv);
@@ -217,7 +217,7 @@ extern void iwl3945_dump_nic_error_log(struct iwl_priv *priv);
 /******************************************************************************
  *
  * Functions implemented in iwl-[34]*.c which are forward declared here
- * for use by iwl-base.c
+ * for use by iwl3945-base.c
  *
  * NOTE:  The implementation of these functions are hardware specific
  * which is why they are in the hardware specific files (vs. iwl-base.c)
@@ -283,7 +283,7 @@ extern u8 iwl3945_hw_find_station(struct iwl_priv *priv, const u8 *bssid);
 extern struct ieee80211_ops iwl3945_hw_ops;
 
 /*
- * Forward declare iwl-3945.c functions for iwl-base.c
+ * Forward declare iwl-3945.c functions for iwl3945-base.c
  */
 extern __le32 iwl3945_get_antenna_flags(const struct iwl_priv *priv);
 extern int iwl3945_init_hw_rate_table(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-calib.c b/drivers/net/wireless/iwlegacy/iwl-4965-calib.c
new file mode 100644 (file)
index 0000000..81d6a25
--- /dev/null
@@ -0,0 +1,967 @@
+/******************************************************************************
+ *
+ * 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 - 2011 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 - 2011 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/slab.h>
+#include <net/mac80211.h>
+
+#include "iwl-dev.h"
+#include "iwl-core.h"
+#include "iwl-4965-calib.h"
+
+/*****************************************************************************
+ * INIT calibrations framework
+ *****************************************************************************/
+
+struct statistics_general_data {
+       u32 beacon_silence_rssi_a;
+       u32 beacon_silence_rssi_b;
+       u32 beacon_silence_rssi_c;
+       u32 beacon_energy_a;
+       u32 beacon_energy_b;
+       u32 beacon_energy_c;
+};
+
+void iwl4965_calib_free_results(struct iwl_priv *priv)
+{
+       int i;
+
+       for (i = 0; i < IWL_CALIB_MAX; i++) {
+               kfree(priv->calib_results[i].buf);
+               priv->calib_results[i].buf = NULL;
+               priv->calib_results[i].buf_len = 0;
+       }
+}
+
+/*****************************************************************************
+ * RUNTIME calibrations framework
+ *****************************************************************************/
+
+/* "false alarms" are signals that our DSP tries to lock onto,
+ *   but then determines that they are either noise, or transmissions
+ *   from a distant wireless network (also "noise", really) that get
+ *   "stepped on" by stronger transmissions within our own network.
+ * This algorithm attempts to set a sensitivity level that is high
+ *   enough to receive all of our own network traffic, but not so
+ *   high that our DSP gets too busy trying to lock onto non-network
+ *   activity/noise. */
+static int iwl4965_sens_energy_cck(struct iwl_priv *priv,
+                                  u32 norm_fa,
+                                  u32 rx_enable_time,
+                                  struct statistics_general_data *rx_info)
+{
+       u32 max_nrg_cck = 0;
+       int i = 0;
+       u8 max_silence_rssi = 0;
+       u32 silence_ref = 0;
+       u8 silence_rssi_a = 0;
+       u8 silence_rssi_b = 0;
+       u8 silence_rssi_c = 0;
+       u32 val;
+
+       /* "false_alarms" values below are cross-multiplications to assess the
+        *   numbers of false alarms within the measured period of actual Rx
+        *   (Rx is off when we're txing), vs the min/max expected false alarms
+        *   (some should be expected if rx is sensitive enough) in a
+        *   hypothetical listening period of 200 time units (TU), 204.8 msec:
+        *
+        * MIN_FA/fixed-time < false_alarms/actual-rx-time < MAX_FA/beacon-time
+        *
+        * */
+       u32 false_alarms = norm_fa * 200 * 1024;
+       u32 max_false_alarms = MAX_FA_CCK * rx_enable_time;
+       u32 min_false_alarms = MIN_FA_CCK * rx_enable_time;
+       struct iwl_sensitivity_data *data = NULL;
+       const struct iwl_sensitivity_ranges *ranges = priv->hw_params.sens;
+
+       data = &(priv->sensitivity_data);
+
+       data->nrg_auto_corr_silence_diff = 0;
+
+       /* Find max silence rssi among all 3 receivers.
+        * This is background noise, which may include transmissions from other
+        *    networks, measured during silence before our network's beacon */
+       silence_rssi_a = (u8)((rx_info->beacon_silence_rssi_a &
+                           ALL_BAND_FILTER) >> 8);
+       silence_rssi_b = (u8)((rx_info->beacon_silence_rssi_b &
+                           ALL_BAND_FILTER) >> 8);
+       silence_rssi_c = (u8)((rx_info->beacon_silence_rssi_c &
+                           ALL_BAND_FILTER) >> 8);
+
+       val = max(silence_rssi_b, silence_rssi_c);
+       max_silence_rssi = max(silence_rssi_a, (u8) val);
+
+       /* Store silence rssi in 20-beacon history table */
+       data->nrg_silence_rssi[data->nrg_silence_idx] = max_silence_rssi;
+       data->nrg_silence_idx++;
+       if (data->nrg_silence_idx >= NRG_NUM_PREV_STAT_L)
+               data->nrg_silence_idx = 0;
+
+       /* Find max silence rssi across 20 beacon history */
+       for (i = 0; i < NRG_NUM_PREV_STAT_L; i++) {
+               val = data->nrg_silence_rssi[i];
+               silence_ref = max(silence_ref, val);
+       }
+       IWL_DEBUG_CALIB(priv, "silence a %u, b %u, c %u, 20-bcn max %u\n",
+                       silence_rssi_a, silence_rssi_b, silence_rssi_c,
+                       silence_ref);
+
+       /* Find max rx energy (min value!) among all 3 receivers,
+        *   measured during beacon frame.
+        * Save it in 10-beacon history table. */
+       i = data->nrg_energy_idx;
+       val = min(rx_info->beacon_energy_b, rx_info->beacon_energy_c);
+       data->nrg_value[i] = min(rx_info->beacon_energy_a, val);
+
+       data->nrg_energy_idx++;
+       if (data->nrg_energy_idx >= 10)
+               data->nrg_energy_idx = 0;
+
+       /* Find min rx energy (max value) across 10 beacon history.
+        * This is the minimum signal level that we want to receive well.
+        * Add backoff (margin so we don't miss slightly lower energy frames).
+        * This establishes an upper bound (min value) for energy threshold. */
+       max_nrg_cck = data->nrg_value[0];
+       for (i = 1; i < 10; i++)
+               max_nrg_cck = (u32) max(max_nrg_cck, (data->nrg_value[i]));
+       max_nrg_cck += 6;
+
+       IWL_DEBUG_CALIB(priv, "rx energy a %u, b %u, c %u, 10-bcn max/min %u\n",
+                       rx_info->beacon_energy_a, rx_info->beacon_energy_b,
+                       rx_info->beacon_energy_c, max_nrg_cck - 6);
+
+       /* Count number of consecutive beacons with fewer-than-desired
+        *   false alarms. */
+       if (false_alarms < min_false_alarms)
+               data->num_in_cck_no_fa++;
+       else
+               data->num_in_cck_no_fa = 0;
+       IWL_DEBUG_CALIB(priv, "consecutive bcns with few false alarms = %u\n",
+                       data->num_in_cck_no_fa);
+
+       /* If we got too many false alarms this time, reduce sensitivity */
+       if ((false_alarms > max_false_alarms) &&
+               (data->auto_corr_cck > AUTO_CORR_MAX_TH_CCK)) {
+               IWL_DEBUG_CALIB(priv, "norm FA %u > max FA %u\n",
+                    false_alarms, max_false_alarms);
+               IWL_DEBUG_CALIB(priv, "... reducing sensitivity\n");
+               data->nrg_curr_state = IWL_FA_TOO_MANY;
+               /* Store for "fewer than desired" on later beacon */
+               data->nrg_silence_ref = silence_ref;
+
+               /* increase energy threshold (reduce nrg value)
+                *   to decrease sensitivity */
+               data->nrg_th_cck = data->nrg_th_cck - NRG_STEP_CCK;
+       /* Else if we got fewer than desired, increase sensitivity */
+       } else if (false_alarms < min_false_alarms) {
+               data->nrg_curr_state = IWL_FA_TOO_FEW;
+
+               /* Compare silence level with silence level for most recent
+                *   healthy number or too many false alarms */
+               data->nrg_auto_corr_silence_diff = (s32)data->nrg_silence_ref -
+                                                  (s32)silence_ref;
+
+               IWL_DEBUG_CALIB(priv,
+                        "norm FA %u < min FA %u, silence diff %d\n",
+                        false_alarms, min_false_alarms,
+                        data->nrg_auto_corr_silence_diff);
+
+               /* Increase value to increase sensitivity, but only if:
+                * 1a) previous beacon did *not* have *too many* false alarms
+                * 1b) AND there's a significant difference in Rx levels
+                *      from a previous beacon with too many, or healthy # FAs
+                * OR 2) We've seen a lot of beacons (100) with too few
+                *       false alarms */
+               if ((data->nrg_prev_state != IWL_FA_TOO_MANY) &&
+                       ((data->nrg_auto_corr_silence_diff > NRG_DIFF) ||
+                       (data->num_in_cck_no_fa > MAX_NUMBER_CCK_NO_FA))) {
+
+                       IWL_DEBUG_CALIB(priv, "... increasing sensitivity\n");
+                       /* Increase nrg value to increase sensitivity */
+                       val = data->nrg_th_cck + NRG_STEP_CCK;
+                       data->nrg_th_cck = min((u32)ranges->min_nrg_cck, val);
+               } else {
+                       IWL_DEBUG_CALIB(priv,
+                                        "... but not changing sensitivity\n");
+               }
+
+       /* Else we got a healthy number of false alarms, keep status quo */
+       } else {
+               IWL_DEBUG_CALIB(priv, " FA in safe zone\n");
+               data->nrg_curr_state = IWL_FA_GOOD_RANGE;
+
+               /* Store for use in "fewer than desired" with later beacon */
+               data->nrg_silence_ref = silence_ref;
+
+               /* If previous beacon had too many false alarms,
+                *   give it some extra margin by reducing sensitivity again
+                *   (but don't go below measured energy of desired Rx) */
+               if (IWL_FA_TOO_MANY == data->nrg_prev_state) {
+                       IWL_DEBUG_CALIB(priv, "... increasing margin\n");
+                       if (data->nrg_th_cck > (max_nrg_cck + NRG_MARGIN))
+                               data->nrg_th_cck -= NRG_MARGIN;
+                       else
+                               data->nrg_th_cck = max_nrg_cck;
+               }
+       }
+
+       /* Make sure the energy threshold does not go above the measured
+        * energy of the desired Rx signals (reduced by backoff margin),
+        * or else we might start missing Rx frames.
+        * Lower value is higher energy, so we use max()!
+        */
+       data->nrg_th_cck = max(max_nrg_cck, data->nrg_th_cck);
+       IWL_DEBUG_CALIB(priv, "new nrg_th_cck %u\n", data->nrg_th_cck);
+
+       data->nrg_prev_state = data->nrg_curr_state;
+
+       /* Auto-correlation CCK algorithm */
+       if (false_alarms > min_false_alarms) {
+
+               /* increase auto_corr values to decrease sensitivity
+                * so the DSP won't be disturbed by the noise
+                */
+               if (data->auto_corr_cck < AUTO_CORR_MAX_TH_CCK)
+                       data->auto_corr_cck = AUTO_CORR_MAX_TH_CCK + 1;
+               else {
+                       val = data->auto_corr_cck + AUTO_CORR_STEP_CCK;
+                       data->auto_corr_cck =
+                               min((u32)ranges->auto_corr_max_cck, val);
+               }
+               val = data->auto_corr_cck_mrc + AUTO_CORR_STEP_CCK;
+               data->auto_corr_cck_mrc =
+                       min((u32)ranges->auto_corr_max_cck_mrc, val);
+       } else if ((false_alarms < min_false_alarms) &&
+          ((data->nrg_auto_corr_silence_diff > NRG_DIFF) ||
+          (data->num_in_cck_no_fa > MAX_NUMBER_CCK_NO_FA))) {
+
+               /* Decrease auto_corr values to increase sensitivity */
+               val = data->auto_corr_cck - AUTO_CORR_STEP_CCK;
+               data->auto_corr_cck =
+                       max((u32)ranges->auto_corr_min_cck, val);
+               val = data->auto_corr_cck_mrc - AUTO_CORR_STEP_CCK;
+               data->auto_corr_cck_mrc =
+                       max((u32)ranges->auto_corr_min_cck_mrc, val);
+       }
+
+       return 0;
+}
+
+
+static int iwl4965_sens_auto_corr_ofdm(struct iwl_priv *priv,
+                                      u32 norm_fa,
+                                      u32 rx_enable_time)
+{
+       u32 val;
+       u32 false_alarms = norm_fa * 200 * 1024;
+       u32 max_false_alarms = MAX_FA_OFDM * rx_enable_time;
+       u32 min_false_alarms = MIN_FA_OFDM * rx_enable_time;
+       struct iwl_sensitivity_data *data = NULL;
+       const struct iwl_sensitivity_ranges *ranges = priv->hw_params.sens;
+
+       data = &(priv->sensitivity_data);
+
+       /* If we got too many false alarms this time, reduce sensitivity */
+       if (false_alarms > max_false_alarms) {
+
+               IWL_DEBUG_CALIB(priv, "norm FA %u > max FA %u)\n",
+                            false_alarms, max_false_alarms);
+
+               val = data->auto_corr_ofdm + AUTO_CORR_STEP_OFDM;
+               data->auto_corr_ofdm =
+                       min((u32)ranges->auto_corr_max_ofdm, val);
+
+               val = data->auto_corr_ofdm_mrc + AUTO_CORR_STEP_OFDM;
+               data->auto_corr_ofdm_mrc =
+                       min((u32)ranges->auto_corr_max_ofdm_mrc, val);
+
+               val = data->auto_corr_ofdm_x1 + AUTO_CORR_STEP_OFDM;
+               data->auto_corr_ofdm_x1 =
+                       min((u32)ranges->auto_corr_max_ofdm_x1, val);
+
+               val = data->auto_corr_ofdm_mrc_x1 + AUTO_CORR_STEP_OFDM;
+               data->auto_corr_ofdm_mrc_x1 =
+                       min((u32)ranges->auto_corr_max_ofdm_mrc_x1, val);
+       }
+
+       /* Else if we got fewer than desired, increase sensitivity */
+       else if (false_alarms < min_false_alarms) {
+
+               IWL_DEBUG_CALIB(priv, "norm FA %u < min FA %u\n",
+                            false_alarms, min_false_alarms);
+
+               val = data->auto_corr_ofdm - AUTO_CORR_STEP_OFDM;
+               data->auto_corr_ofdm =
+                       max((u32)ranges->auto_corr_min_ofdm, val);
+
+               val = data->auto_corr_ofdm_mrc - AUTO_CORR_STEP_OFDM;
+               data->auto_corr_ofdm_mrc =
+                       max((u32)ranges->auto_corr_min_ofdm_mrc, val);
+
+               val = data->auto_corr_ofdm_x1 - AUTO_CORR_STEP_OFDM;
+               data->auto_corr_ofdm_x1 =
+                       max((u32)ranges->auto_corr_min_ofdm_x1, val);
+
+               val = data->auto_corr_ofdm_mrc_x1 - AUTO_CORR_STEP_OFDM;
+               data->auto_corr_ofdm_mrc_x1 =
+                       max((u32)ranges->auto_corr_min_ofdm_mrc_x1, val);
+       } else {
+               IWL_DEBUG_CALIB(priv, "min FA %u < norm FA %u < max FA %u OK\n",
+                        min_false_alarms, false_alarms, max_false_alarms);
+       }
+       return 0;
+}
+
+static void iwl4965_prepare_legacy_sensitivity_tbl(struct iwl_priv *priv,
+                               struct iwl_sensitivity_data *data,
+                               __le16 *tbl)
+{
+       tbl[HD_AUTO_CORR32_X4_TH_ADD_MIN_INDEX] =
+                               cpu_to_le16((u16)data->auto_corr_ofdm);
+       tbl[HD_AUTO_CORR32_X4_TH_ADD_MIN_MRC_INDEX] =
+                               cpu_to_le16((u16)data->auto_corr_ofdm_mrc);
+       tbl[HD_AUTO_CORR32_X1_TH_ADD_MIN_INDEX] =
+                               cpu_to_le16((u16)data->auto_corr_ofdm_x1);
+       tbl[HD_AUTO_CORR32_X1_TH_ADD_MIN_MRC_INDEX] =
+                               cpu_to_le16((u16)data->auto_corr_ofdm_mrc_x1);
+
+       tbl[HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX] =
+                               cpu_to_le16((u16)data->auto_corr_cck);
+       tbl[HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX] =
+                               cpu_to_le16((u16)data->auto_corr_cck_mrc);
+
+       tbl[HD_MIN_ENERGY_CCK_DET_INDEX] =
+                               cpu_to_le16((u16)data->nrg_th_cck);
+       tbl[HD_MIN_ENERGY_OFDM_DET_INDEX] =
+                               cpu_to_le16((u16)data->nrg_th_ofdm);
+
+       tbl[HD_BARKER_CORR_TH_ADD_MIN_INDEX] =
+                               cpu_to_le16(data->barker_corr_th_min);
+       tbl[HD_BARKER_CORR_TH_ADD_MIN_MRC_INDEX] =
+                               cpu_to_le16(data->barker_corr_th_min_mrc);
+       tbl[HD_OFDM_ENERGY_TH_IN_INDEX] =
+                               cpu_to_le16(data->nrg_th_cca);
+
+       IWL_DEBUG_CALIB(priv, "ofdm: ac %u mrc %u x1 %u mrc_x1 %u thresh %u\n",
+                       data->auto_corr_ofdm, data->auto_corr_ofdm_mrc,
+                       data->auto_corr_ofdm_x1, data->auto_corr_ofdm_mrc_x1,
+                       data->nrg_th_ofdm);
+
+       IWL_DEBUG_CALIB(priv, "cck: ac %u mrc %u thresh %u\n",
+                       data->auto_corr_cck, data->auto_corr_cck_mrc,
+                       data->nrg_th_cck);
+}
+
+/* Prepare a SENSITIVITY_CMD, send to uCode if values have changed */
+static int iwl4965_sensitivity_write(struct iwl_priv *priv)
+{
+       struct iwl_sensitivity_cmd cmd;
+       struct iwl_sensitivity_data *data = NULL;
+       struct iwl_host_cmd cmd_out = {
+               .id = SENSITIVITY_CMD,
+               .len = sizeof(struct iwl_sensitivity_cmd),
+               .flags = CMD_ASYNC,
+               .data = &cmd,
+       };
+
+       data = &(priv->sensitivity_data);
+
+       memset(&cmd, 0, sizeof(cmd));
+
+       iwl4965_prepare_legacy_sensitivity_tbl(priv, data, &cmd.table[0]);
+
+       /* Update uCode's "work" table, and copy it to DSP */
+       cmd.control = SENSITIVITY_CMD_CONTROL_WORK_TABLE;
+
+       /* Don't send command to uCode if nothing has changed */
+       if (!memcmp(&cmd.table[0], &(priv->sensitivity_tbl[0]),
+                   sizeof(u16)*HD_TABLE_SIZE)) {
+               IWL_DEBUG_CALIB(priv, "No change in SENSITIVITY_CMD\n");
+               return 0;
+       }
+
+       /* Copy table for comparison next time */
+       memcpy(&(priv->sensitivity_tbl[0]), &(cmd.table[0]),
+              sizeof(u16)*HD_TABLE_SIZE);
+
+       return iwl_legacy_send_cmd(priv, &cmd_out);
+}
+
+void iwl4965_init_sensitivity(struct iwl_priv *priv)
+{
+       int ret = 0;
+       int i;
+       struct iwl_sensitivity_data *data = NULL;
+       const struct iwl_sensitivity_ranges *ranges = priv->hw_params.sens;
+
+       if (priv->disable_sens_cal)
+               return;
+
+       IWL_DEBUG_CALIB(priv, "Start iwl4965_init_sensitivity\n");
+
+       /* Clear driver's sensitivity algo data */
+       data = &(priv->sensitivity_data);
+
+       if (ranges == NULL)
+               return;
+
+       memset(data, 0, sizeof(struct iwl_sensitivity_data));
+
+       data->num_in_cck_no_fa = 0;
+       data->nrg_curr_state = IWL_FA_TOO_MANY;
+       data->nrg_prev_state = IWL_FA_TOO_MANY;
+       data->nrg_silence_ref = 0;
+       data->nrg_silence_idx = 0;
+       data->nrg_energy_idx = 0;
+
+       for (i = 0; i < 10; i++)
+               data->nrg_value[i] = 0;
+
+       for (i = 0; i < NRG_NUM_PREV_STAT_L; i++)
+               data->nrg_silence_rssi[i] = 0;
+
+       data->auto_corr_ofdm =  ranges->auto_corr_min_ofdm;
+       data->auto_corr_ofdm_mrc = ranges->auto_corr_min_ofdm_mrc;
+       data->auto_corr_ofdm_x1  = ranges->auto_corr_min_ofdm_x1;
+       data->auto_corr_ofdm_mrc_x1 = ranges->auto_corr_min_ofdm_mrc_x1;
+       data->auto_corr_cck = AUTO_CORR_CCK_MIN_VAL_DEF;
+       data->auto_corr_cck_mrc = ranges->auto_corr_min_cck_mrc;
+       data->nrg_th_cck = ranges->nrg_th_cck;
+       data->nrg_th_ofdm = ranges->nrg_th_ofdm;
+       data->barker_corr_th_min = ranges->barker_corr_th_min;
+       data->barker_corr_th_min_mrc = ranges->barker_corr_th_min_mrc;
+       data->nrg_th_cca = ranges->nrg_th_cca;
+
+       data->last_bad_plcp_cnt_ofdm = 0;
+       data->last_fa_cnt_ofdm = 0;
+       data->last_bad_plcp_cnt_cck = 0;
+       data->last_fa_cnt_cck = 0;
+
+       ret |= iwl4965_sensitivity_write(priv);
+       IWL_DEBUG_CALIB(priv, "<<return 0x%X\n", ret);
+}
+
+void iwl4965_sensitivity_calibration(struct iwl_priv *priv, void *resp)
+{
+       u32 rx_enable_time;
+       u32 fa_cck;
+       u32 fa_ofdm;
+       u32 bad_plcp_cck;
+       u32 bad_plcp_ofdm;
+       u32 norm_fa_ofdm;
+       u32 norm_fa_cck;
+       struct iwl_sensitivity_data *data = NULL;
+       struct statistics_rx_non_phy *rx_info;
+       struct statistics_rx_phy *ofdm, *cck;
+       unsigned long flags;
+       struct statistics_general_data statis;
+
+       if (priv->disable_sens_cal)
+               return;
+
+       data = &(priv->sensitivity_data);
+
+       if (!iwl_legacy_is_any_associated(priv)) {
+               IWL_DEBUG_CALIB(priv, "<< - not associated\n");
+               return;
+       }
+
+       spin_lock_irqsave(&priv->lock, flags);
+
+       rx_info = &(((struct iwl_notif_statistics *)resp)->rx.general);
+       ofdm = &(((struct iwl_notif_statistics *)resp)->rx.ofdm);
+       cck = &(((struct iwl_notif_statistics *)resp)->rx.cck);
+
+       if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) {
+               IWL_DEBUG_CALIB(priv, "<< invalid data.\n");
+               spin_unlock_irqrestore(&priv->lock, flags);
+               return;
+       }
+
+       /* Extract Statistics: */
+       rx_enable_time = le32_to_cpu(rx_info->channel_load);
+       fa_cck = le32_to_cpu(cck->false_alarm_cnt);
+       fa_ofdm = le32_to_cpu(ofdm->false_alarm_cnt);
+       bad_plcp_cck = le32_to_cpu(cck->plcp_err);
+       bad_plcp_ofdm = le32_to_cpu(ofdm->plcp_err);
+
+       statis.beacon_silence_rssi_a =
+                       le32_to_cpu(rx_info->beacon_silence_rssi_a);
+       statis.beacon_silence_rssi_b =
+                       le32_to_cpu(rx_info->beacon_silence_rssi_b);
+       statis.beacon_silence_rssi_c =
+                       le32_to_cpu(rx_info->beacon_silence_rssi_c);
+       statis.beacon_energy_a =
+                       le32_to_cpu(rx_info->beacon_energy_a);
+       statis.beacon_energy_b =
+                       le32_to_cpu(rx_info->beacon_energy_b);
+       statis.beacon_energy_c =
+                       le32_to_cpu(rx_info->beacon_energy_c);
+
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       IWL_DEBUG_CALIB(priv, "rx_enable_time = %u usecs\n", rx_enable_time);
+
+       if (!rx_enable_time) {
+               IWL_DEBUG_CALIB(priv, "<< RX Enable Time == 0!\n");
+               return;
+       }
+
+       /* These statistics increase monotonically, and do not reset
+        *   at each beacon.  Calculate difference from last value, or just
+        *   use the new statistics value if it has reset or wrapped around. */
+       if (data->last_bad_plcp_cnt_cck > bad_plcp_cck)
+               data->last_bad_plcp_cnt_cck = bad_plcp_cck;
+       else {
+               bad_plcp_cck -= data->last_bad_plcp_cnt_cck;
+               data->last_bad_plcp_cnt_cck += bad_plcp_cck;
+       }
+
+       if (data->last_bad_plcp_cnt_ofdm > bad_plcp_ofdm)
+               data->last_bad_plcp_cnt_ofdm = bad_plcp_ofdm;
+       else {
+               bad_plcp_ofdm -= data->last_bad_plcp_cnt_ofdm;
+               data->last_bad_plcp_cnt_ofdm += bad_plcp_ofdm;
+       }
+
+       if (data->last_fa_cnt_ofdm > fa_ofdm)
+               data->last_fa_cnt_ofdm = fa_ofdm;
+       else {
+               fa_ofdm -= data->last_fa_cnt_ofdm;
+               data->last_fa_cnt_ofdm += fa_ofdm;
+       }
+
+       if (data->last_fa_cnt_cck > fa_cck)
+               data->last_fa_cnt_cck = fa_cck;
+       else {
+               fa_cck -= data->last_fa_cnt_cck;
+               data->last_fa_cnt_cck += fa_cck;
+       }
+
+       /* Total aborted signal locks */
+       norm_fa_ofdm = fa_ofdm + bad_plcp_ofdm;
+       norm_fa_cck = fa_cck + bad_plcp_cck;
+
+       IWL_DEBUG_CALIB(priv,
+                        "cck: fa %u badp %u  ofdm: fa %u badp %u\n", fa_cck,
+                       bad_plcp_cck, fa_ofdm, bad_plcp_ofdm);
+
+       iwl4965_sens_auto_corr_ofdm(priv, norm_fa_ofdm, rx_enable_time);
+       iwl4965_sens_energy_cck(priv, norm_fa_cck, rx_enable_time, &statis);
+
+       iwl4965_sensitivity_write(priv);
+}
+
+static inline u8 iwl4965_find_first_chain(u8 mask)
+{
+       if (mask & ANT_A)
+               return CHAIN_A;
+       if (mask & ANT_B)
+               return CHAIN_B;
+       return CHAIN_C;
+}
+
+/**
+ * Run disconnected antenna algorithm to find out which antennas are
+ * disconnected.
+ */
+static void
+iwl4965_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig,
+                                    struct iwl_chain_noise_data *data)
+{
+       u32 active_chains = 0;
+       u32 max_average_sig;
+       u16 max_average_sig_antenna_i;
+       u8 num_tx_chains;
+       u8 first_chain;
+       u16 i = 0;
+
+       average_sig[0] = data->chain_signal_a /
+                        priv->cfg->base_params->chain_noise_num_beacons;
+       average_sig[1] = data->chain_signal_b /
+                        priv->cfg->base_params->chain_noise_num_beacons;
+       average_sig[2] = data->chain_signal_c /
+                        priv->cfg->base_params->chain_noise_num_beacons;
+
+       if (average_sig[0] >= average_sig[1]) {
+               max_average_sig = average_sig[0];
+               max_average_sig_antenna_i = 0;
+               active_chains = (1 << max_average_sig_antenna