PKG_NAME:=mac80211
-PKG_VERSION:=2010-07-06
+PKG_VERSION:=2010-07-16
PKG_RELEASE:=1
PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources
# http://www.orbit-lab.org/kernel/compat-wireless-2.6/2010/11 \
# http://wireless.kernel.org/download/compat-wireless-2.6
-PKG_MD5SUM:=e669e4c2ed4f0cc9a6a28e941d766eac
+PKG_MD5SUM:=f0eb07a207d1f3675787a466c838b777
PKG_SOURCE:=compat-wireless-$(PKG_VERSION).tar.bz2
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/compat-wireless-$(PKG_VERSION)
--- /dev/null
+--- a/drivers/net/wireless/ipw2x00/ipw2100.c
++++ b/drivers/net/wireless/ipw2x00/ipw2100.c
+@@ -174,7 +174,9 @@ that only one external action is invoked
+ #define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2100 Network Driver"
+ #define DRV_COPYRIGHT "Copyright(c) 2003-2006 Intel Corporation"
+
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
+ struct pm_qos_request_list *ipw2100_pm_qos_req;
++#endif
+
+ /* Debugging stuff */
+ #ifdef CONFIG_IPW2100_DEBUG
+@@ -1741,7 +1743,11 @@ static int ipw2100_up(struct ipw2100_pri
+ /* the ipw2100 hardware really doesn't want power management delays
+ * longer than 175usec
+ */
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
+ pm_qos_update_request(ipw2100_pm_qos_req, 175);
++#else
++ pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY, "ipw2100", 175);
++#endif
+
+ /* If the interrupt is enabled, turn it off... */
+ spin_lock_irqsave(&priv->low_lock, flags);
+@@ -1889,7 +1895,12 @@ static void ipw2100_down(struct ipw2100_
+ ipw2100_disable_interrupts(priv);
+ spin_unlock_irqrestore(&priv->low_lock, flags);
+
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
+ pm_qos_update_request(ipw2100_pm_qos_req, PM_QOS_DEFAULT_VALUE);
++#else
++ pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY, "ipw2100",
++ PM_QOS_DEFAULT_VALUE);
++#endif
+
+ /* We have to signal any supplicant if we are disassociating */
+ if (associated)
+@@ -6669,7 +6680,11 @@ static int __init ipw2100_init(void)
+ if (ret)
+ goto out;
+
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
+ ipw2100_pm_qos_req = pm_qos_add_request(PM_QOS_CPU_DMA_LATENCY,
++#else
++ pm_qos_add_requirement(PM_QOS_CPU_DMA_LATENCY, "ipw2100",
++#endif
+ PM_QOS_DEFAULT_VALUE);
+ #ifdef CONFIG_IPW2100_DEBUG
+ ipw2100_debug_level = debug;
+@@ -6692,7 +6707,11 @@ static void __exit ipw2100_exit(void)
+ &driver_attr_debug_level);
+ #endif
+ pci_unregister_driver(&ipw2100_pci_driver);
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
+ pm_qos_remove_request(ipw2100_pm_qos_req);
++#else
++ pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY, "ipw2100");
++#endif
+ }
+
+ module_init(ipw2100_init);
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
-@@ -1416,7 +1416,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st
+@@ -1418,7 +1418,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st
if (ah->config.rx_intr_mitigation) {
REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500);
--- /dev/null
+diff -Nur a/include/linux/ath5k_platform.h b/include/linux/ath5k_platform.h
+--- a/include/linux/ath5k_platform.h 1970-01-01 01:00:00.000000000 +0100
++++ b/include/linux/ath5k_platform.h 2010-06-21 00:19:52.000000000 +0200
+@@ -0,0 +1,30 @@
++/*
++ * Copyright (c) 2008 Atheros Communications Inc.
++ * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org>
++ * Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org>
++ * Copyright (c) 2010 Daniel Golle <daniel.golle@gmail.com>
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _LINUX_ATH5K_PLATFORM_H
++#define _LINUX_ATH5K_PLATFORM_H
++
++#define ATH5K_PLAT_EEP_MAX_WORDS 2048
++
++struct ath5k_platform_data {
++ u16 *eeprom_data;
++ u8 *macaddr;
++};
++
++#endif /* _LINUX_ATH5K_PLATFORM_H */
+
--- /dev/null
+--- a/drivers/net/wireless/ath/ath5k/eeprom.c 2010-06-23 03:08:32.000000000 +0200
++++ b/drivers/net/wireless/ath/ath5k/eeprom.c 2010-06-23 05:59:30.000000000 +0200
+@@ -22,6 +23,8 @@
+ \*************************************/
+
+ #include <linux/slab.h>
++#include <linux/ath5k_platform.h>
++#include <linux/pci.h>
+
+ #include "ath5k.h"
+ #include "reg.h"
+@@ -34,6 +37,18 @@
+ static int ath5k_hw_eeprom_read(struct ath5k_hw *ah, u32 offset, u16 *data)
+ {
+ u32 status, timeout;
++ struct ath5k_platform_data *pdata = NULL;
++
++ if (ah->ah_sc->pdev)
++ pdata = ah->ah_sc->pdev->dev.platform_data;
++
++ if (pdata && pdata->eeprom_data && pdata->eeprom_data[0] == AR5K_EEPROM_MAGIC_VALUE)
++ {
++ ATH5K_INFO(ah->ah_sc, "using eeprom-content from platform_data\n");
++ if (offset >= ATH5K_PLAT_EEP_MAX_WORDS) return -EIO;
++ *data = pdata->eeprom_data[offset];
++ return 0;
++ }
+
+ /*
+ * Initialize EEPROM access
+@@ -1788,7 +1802,7 @@
+ }
+
+ /*
+- * Read the MAC address from eeprom
++ * Read the MAC address from eeprom or platform_data
+ */
+ int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
+ {
+@@ -1796,6 +1810,16 @@
+ u32 total, offset;
+ u16 data;
+ int octet, ret;
++ struct ath5k_platform_data *pdata = NULL;
++
++ if (ah->ah_sc->pdev)
++ pdata = ah->ah_sc->pdev->dev.platform_data;
++
++ if (pdata && pdata->macaddr)
++ {
++ memcpy(mac, pdata->macaddr, ETH_ALEN);
++ return 0;
++ }
+
+ ret = ath5k_hw_eeprom_read(ah, 0x20, &data);
+ if (ret)
+
+++ /dev/null
---- a/drivers/net/wireless/ath/ath9k/xmit.c
-+++ b/drivers/net/wireless/ath/ath9k/xmit.c
-@@ -2430,37 +2430,37 @@ void ath_tx_node_init(struct ath_softc *
-
- void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
- {
-- int i;
-- struct ath_atx_ac *ac, *ac_tmp;
-- struct ath_atx_tid *tid, *tid_tmp;
-+ struct ath_atx_ac *ac;
-+ struct ath_atx_tid *tid;
- struct ath_txq *txq;
-+ int i, tidno;
-
-- for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
-- if (ATH_TXQ_SETUP(sc, i)) {
-- txq = &sc->tx.txq[i];
--
-- spin_lock_bh(&txq->axq_lock);
--
-- list_for_each_entry_safe(ac,
-- ac_tmp, &txq->axq_acq, list) {
-- tid = list_first_entry(&ac->tid_q,
-- struct ath_atx_tid, list);
-- if (tid && tid->an != an)
-- continue;
-- list_del(&ac->list);
-- ac->sched = false;
--
-- list_for_each_entry_safe(tid,
-- tid_tmp, &ac->tid_q, list) {
-- list_del(&tid->list);
-- tid->sched = false;
-- ath_tid_drain(sc, txq, tid);
-- tid->state &= ~AGGR_ADDBA_COMPLETE;
-- tid->state &= ~AGGR_CLEANUP;
-- }
-- }
-+ for (tidno = 0, tid = &an->tid[tidno];
-+ tidno < WME_NUM_TID; tidno++, tid++) {
-+ i = tid->ac->qnum;
-
-- spin_unlock_bh(&txq->axq_lock);
-+ if (!ATH_TXQ_SETUP(sc, i))
-+ continue;
-+
-+ txq = &sc->tx.txq[i];
-+ ac = tid->ac;
-+
-+ spin_lock_bh(&txq->axq_lock);
-+
-+ if (tid->sched) {
-+ list_del(&tid->list);
-+ tid->sched = false;
- }
-+
-+ if (ac->sched) {
-+ list_del(&ac->list);
-+ tid->ac->sched = false;
-+ }
-+
-+ ath_tid_drain(sc, txq, tid);
-+ tid->state &= ~AGGR_ADDBA_COMPLETE;
-+ tid->state &= ~AGGR_CLEANUP;
-+
-+ spin_unlock_bh(&txq->axq_lock);
- }
- }
--- /dev/null
+--- a/drivers/net/wireless/ath/ath9k/mac.c
++++ b/drivers/net/wireless/ath/ath9k/mac.c
+@@ -713,6 +713,8 @@ int ath9k_hw_rxprocdesc(struct ath_hw *a
+ rs->rs_status |= ATH9K_RXERR_DECRYPT;
+ else if (ads.ds_rxstatus8 & AR_MichaelErr)
+ rs->rs_status |= ATH9K_RXERR_MIC;
++ else if (ads.ds_rxstatus8 & AR_KeyMiss)
++ rs->rs_status |= ATH9K_RXERR_DECRYPT;
+ }
+
+ return 0;
+--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
++++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+@@ -616,7 +616,8 @@ int ath9k_hw_process_rxdesc_edma(struct
+ rxs->rs_status |= ATH9K_RXERR_DECRYPT;
+ } else if (rxsp->status11 & AR_MichaelErr) {
+ rxs->rs_status |= ATH9K_RXERR_MIC;
+- }
++ } else if (rxsp->status11 & AR_KeyMiss)
++ rxs->rs_status |= ATH9K_RXERR_DECRYPT;
+ }
+
+ return 0;
+++ /dev/null
---- a/drivers/net/wireless/ath/ath9k/xmit.c
-+++ b/drivers/net/wireless/ath/ath9k/xmit.c
-@@ -329,6 +329,7 @@ static void ath_tx_complete_aggr(struct
- int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0;
- bool rc_update = true;
- struct ieee80211_tx_rate rates[4];
-+ unsigned long flags;
-
- skb = bf->bf_mpdu;
- hdr = (struct ieee80211_hdr *)skb->data;
-@@ -344,6 +345,10 @@ static void ath_tx_complete_aggr(struct
- sta = ieee80211_find_sta_by_hw(hw, hdr->addr1);
- if (!sta) {
- rcu_read_unlock();
-+
-+ spin_lock_irqsave(&sc->tx.txbuflock, flags);
-+ list_splice_tail_init(bf_q, &sc->tx.txbuf);
-+ spin_unlock_irqrestore(&sc->tx.txbuflock, flags);
- return;
- }
-
+++ /dev/null
---- a/drivers/net/wireless/ath/ath9k/eeprom.h
-+++ b/drivers/net/wireless/ath/ath9k/eeprom.h
-@@ -670,7 +670,7 @@ struct eeprom_ops {
- int (*get_eeprom_ver)(struct ath_hw *hw);
- int (*get_eeprom_rev)(struct ath_hw *hw);
- u8 (*get_num_ant_config)(struct ath_hw *hw, enum ieee80211_band band);
-- u16 (*get_eeprom_antenna_cfg)(struct ath_hw *hw,
-+ u32 (*get_eeprom_antenna_cfg)(struct ath_hw *hw,
- struct ath9k_channel *chan);
- void (*set_board_values)(struct ath_hw *hw, struct ath9k_channel *chan);
- void (*set_addac)(struct ath_hw *hw, struct ath9k_channel *chan);
---- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c
-+++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
-@@ -1130,13 +1130,13 @@ static u8 ath9k_hw_ar9287_get_num_ant_co
- return 1;
- }
-
--static u16 ath9k_hw_ar9287_get_eeprom_antenna_cfg(struct ath_hw *ah,
-+static u32 ath9k_hw_ar9287_get_eeprom_antenna_cfg(struct ath_hw *ah,
- struct ath9k_channel *chan)
- {
- struct ar9287_eeprom *eep = &ah->eeprom.map9287;
- struct modal_eep_ar9287_header *pModal = &eep->modalHeader;
-
-- return pModal->antCtrlCommon & 0xFFFF;
-+ return pModal->antCtrlCommon;
- }
-
- static u16 ath9k_hw_ar9287_get_spur_channel(struct ath_hw *ah,
---- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
-+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
-@@ -1438,14 +1438,14 @@ static u8 ath9k_hw_def_get_num_ant_confi
- return num_ant_config;
- }
-
--static u16 ath9k_hw_def_get_eeprom_antenna_cfg(struct ath_hw *ah,
-+static u32 ath9k_hw_def_get_eeprom_antenna_cfg(struct ath_hw *ah,
- struct ath9k_channel *chan)
- {
- struct ar5416_eeprom_def *eep = &ah->eeprom.def;
- struct modal_eep_header *pModal =
- &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
-
-- return pModal->antCtrlCommon & 0xFFFF;
-+ return pModal->antCtrlCommon;
- }
-
- static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
---- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
-+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
-@@ -1150,13 +1150,13 @@ static void ath9k_hw_4k_set_board_values
- }
- }
-
--static u16 ath9k_hw_4k_get_eeprom_antenna_cfg(struct ath_hw *ah,
-+static u32 ath9k_hw_4k_get_eeprom_antenna_cfg(struct ath_hw *ah,
- struct ath9k_channel *chan)
- {
- struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
- struct modal_eep_4k_header *pModal = &eep->modalHeader;
-
-- return pModal->antCtrlCommon & 0xFFFF;
-+ return pModal->antCtrlCommon;
- }
-
- static u8 ath9k_hw_4k_get_num_ant_config(struct ath_hw *ah,
---- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
-+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
-@@ -951,7 +951,7 @@ static u8 ath9k_hw_ar9300_get_num_ant_co
- return 1;
- }
-
--static u16 ath9k_hw_ar9300_get_eeprom_antenna_cfg(struct ath_hw *ah,
-+static u32 ath9k_hw_ar9300_get_eeprom_antenna_cfg(struct ath_hw *ah,
- struct ath9k_channel *chan)
- {
- return -EINVAL;
--- /dev/null
+--- a/drivers/net/wireless/ath/ath9k/xmit.c
++++ b/drivers/net/wireless/ath/ath9k/xmit.c
+@@ -518,6 +518,14 @@ static void ath_tx_complete_aggr(struct
+ bf = bf_next;
+ }
+
++ /* prepend un-acked frames to the beginning of the pending frame queue */
++ if (!list_empty(&bf_pending)) {
++ spin_lock_bh(&txq->axq_lock);
++ list_splice(&bf_pending, &tid->buf_q);
++ ath_tx_queue_tid(txq, tid);
++ spin_unlock_bh(&txq->axq_lock);
++ }
++
+ if (tid->state & AGGR_CLEANUP) {
+ if (tid->baw_head == tid->baw_tail) {
+ tid->state &= ~AGGR_ADDBA_COMPLETE;
+@@ -530,14 +538,6 @@ static void ath_tx_complete_aggr(struct
+ return;
+ }
+
+- /* prepend un-acked frames to the beginning of the pending frame queue */
+- if (!list_empty(&bf_pending)) {
+- spin_lock_bh(&txq->axq_lock);
+- list_splice(&bf_pending, &tid->buf_q);
+- ath_tx_queue_tid(txq, tid);
+- spin_unlock_bh(&txq->axq_lock);
+- }
+-
+ rcu_read_unlock();
+
+ if (needreset)
+++ /dev/null
---- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
-+++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
-@@ -239,7 +239,7 @@ static void ar9002_hw_iqcalibrate(struct
- if (qCoff > 15)
- qCoff = 15;
- else if (qCoff <= -16)
-- qCoff = 16;
-+ qCoff = -16;
-
- ath_print(common, ATH_DBG_CALIBRATE,
- "Chn %d : iCoff = 0x%x qCoff = 0x%x\n",
+++ /dev/null
---- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
-+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
-@@ -730,7 +730,7 @@ static void ath9k_hw_get_def_gain_bounda
- vpdTableI[i][sizeCurrVpdTable - 2]);
- vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
-
-- if (tgtIndex > maxIndex) {
-+ if (tgtIndex >= maxIndex) {
- while ((ss <= tgtIndex) &&
- (k < (AR5416_NUM_PDADC_VALUES - 1))) {
- tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] +
+++ /dev/null
---- a/drivers/net/wireless/ath/ath9k/hw.c
-+++ b/drivers/net/wireless/ath/ath9k/hw.c
-@@ -1244,9 +1244,11 @@ int ath9k_hw_reset(struct ath_hw *ah, st
-
- if (!ah->chip_fullsleep) {
- ath9k_hw_abortpcurecv(ah);
-- if (!ath9k_hw_stopdmarecv(ah))
-+ if (!ath9k_hw_stopdmarecv(ah)) {
- ath_print(common, ATH_DBG_XMIT,
- "Failed to stop receive dma\n");
-+ bChannelChange = false;
-+ }
- }
-
- if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
+++ /dev/null
---- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c
-+++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
-@@ -287,6 +287,7 @@ static int ar9002_hw_proc_txdesc(struct
- ts->ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt);
- ts->ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt);
- ts->ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt);
-+ ts->tid = MS(ads->ds_txstatus9, AR_TxTid);
- ts->ts_antenna = 0;
-
- return 0;
---- a/drivers/net/wireless/ath/ath9k/ar9003_mac.h
-+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.h
-@@ -33,9 +33,6 @@
- #define AR_TxDescId_S 16
- #define AR_TxPtrChkSum 0x0000ffff
-
--#define AR_TxTid 0xf0000000
--#define AR_TxTid_S 28
--
- #define AR_LowRxChain 0x00004000
-
- #define AR_Not_Sounding 0x20000000
---- a/drivers/net/wireless/ath/ath9k/mac.h
-+++ b/drivers/net/wireless/ath/ath9k/mac.h
-@@ -485,6 +485,9 @@ struct ar5416_desc {
- #define AR_TxRSSICombined 0xff000000
- #define AR_TxRSSICombined_S 24
-
-+#define AR_TxTid 0xf0000000
-+#define AR_TxTid_S 28
-+
- #define AR_TxEVM0 ds_txstatus5
- #define AR_TxEVM1 ds_txstatus6
- #define AR_TxEVM2 ds_txstatus7
---- a/drivers/net/wireless/ath/ath9k/xmit.c
-+++ b/drivers/net/wireless/ath/ath9k/xmit.c
-@@ -355,6 +355,14 @@ static void ath_tx_complete_aggr(struct
- an = (struct ath_node *)sta->drv_priv;
- tid = ATH_AN_2_TID(an, bf->bf_tidno);
-
-+ /*
-+ * The hardware occasionally sends a tx status for the wrong TID.
-+ * In this case, the BA status cannot be considered valid and all
-+ * subframes need to be retransmitted
-+ */
-+ if (bf->bf_tidno != ts->tid)
-+ txok = false;
-+
- isaggr = bf_isaggr(bf);
- memset(ba, 0, WME_BA_BMP_SIZE >> 3);
-
+++ /dev/null
---- a/drivers/net/wireless/ath/ath9k/mac.c
-+++ b/drivers/net/wireless/ath/ath9k/mac.c
-@@ -713,6 +713,8 @@ int ath9k_hw_rxprocdesc(struct ath_hw *a
- rs->rs_status |= ATH9K_RXERR_DECRYPT;
- else if (ads.ds_rxstatus8 & AR_MichaelErr)
- rs->rs_status |= ATH9K_RXERR_MIC;
-+ else if (ads.ds_rxstatus8 & AR_KeyMiss)
-+ rs->rs_status |= ATH9K_RXERR_DECRYPT;
- }
-
- return 0;
---- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
-+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
-@@ -589,7 +589,8 @@ int ath9k_hw_process_rxdesc_edma(struct
- rxs->rs_status |= ATH9K_RXERR_DECRYPT;
- } else if (rxsp->status11 & AR_MichaelErr) {
- rxs->rs_status |= ATH9K_RXERR_MIC;
-- }
-+ } else if (rxsp->status11 & AR_KeyMiss)
-+ rxs->rs_status |= ATH9K_RXERR_DECRYPT;
- }
-
- return 0;
+++ /dev/null
---- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
-+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
-@@ -1518,77 +1518,6 @@ static void ar5008_hw_do_getnf(struct at
- nfarray[5] = sign_extend(nf, 9);
- }
-
--static void ar5008_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
--{
-- struct ath9k_nfcal_hist *h;
-- int i, j;
-- int32_t val;
-- const u32 ar5416_cca_regs[6] = {
-- AR_PHY_CCA,
-- AR_PHY_CH1_CCA,
-- AR_PHY_CH2_CCA,
-- AR_PHY_EXT_CCA,
-- AR_PHY_CH1_EXT_CCA,
-- AR_PHY_CH2_EXT_CCA
-- };
-- u8 chainmask, rx_chain_status;
--
-- rx_chain_status = REG_READ(ah, AR_PHY_RX_CHAINMASK);
-- if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
-- chainmask = 0x9;
-- else if (AR_SREV_9280(ah) || AR_SREV_9287(ah)) {
-- if ((rx_chain_status & 0x2) || (rx_chain_status & 0x4))
-- chainmask = 0x1B;
-- else
-- chainmask = 0x09;
-- } else {
-- if (rx_chain_status & 0x4)
-- chainmask = 0x3F;
-- else if (rx_chain_status & 0x2)
-- chainmask = 0x1B;
-- else
-- chainmask = 0x09;
-- }
--
-- h = ah->nfCalHist;
--
-- for (i = 0; i < NUM_NF_READINGS; i++) {
-- if (chainmask & (1 << i)) {
-- val = REG_READ(ah, ar5416_cca_regs[i]);
-- val &= 0xFFFFFE00;
-- val |= (((u32) (h[i].privNF) << 1) & 0x1ff);
-- REG_WRITE(ah, ar5416_cca_regs[i], val);
-- }
-- }
--
-- REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
-- AR_PHY_AGC_CONTROL_ENABLE_NF);
-- REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
-- AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
-- REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
--
-- for (j = 0; j < 5; j++) {
-- if ((REG_READ(ah, AR_PHY_AGC_CONTROL) &
-- AR_PHY_AGC_CONTROL_NF) == 0)
-- break;
-- udelay(50);
-- }
--
-- ENABLE_REGWRITE_BUFFER(ah);
--
-- for (i = 0; i < NUM_NF_READINGS; i++) {
-- if (chainmask & (1 << i)) {
-- val = REG_READ(ah, ar5416_cca_regs[i]);
-- val &= 0xFFFFFE00;
-- val |= (((u32) (-50) << 1) & 0x1ff);
-- REG_WRITE(ah, ar5416_cca_regs[i], val);
-- }
-- }
--
-- REGWRITE_BUFFER_FLUSH(ah);
-- DISABLE_REGWRITE_BUFFER(ah);
--}
--
- /*
- * Initialize the ANI register values with default (ini) values.
- * This routine is called during a (full) hardware reset after
-@@ -1666,6 +1595,14 @@ static void ar5008_hw_set_nf_limits(stru
- void ar5008_hw_attach_phy_ops(struct ath_hw *ah)
- {
- struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
-+ const u32 ar5416_cca_regs[6] = {
-+ AR_PHY_CCA,
-+ AR_PHY_CH1_CCA,
-+ AR_PHY_CH2_CCA,
-+ AR_PHY_EXT_CCA,
-+ AR_PHY_CH1_EXT_CCA,
-+ AR_PHY_CH2_EXT_CCA
-+ };
-
- priv_ops->rf_set_freq = ar5008_hw_set_channel;
- priv_ops->spur_mitigate_freq = ar5008_hw_spur_mitigate;
-@@ -1685,7 +1622,6 @@ void ar5008_hw_attach_phy_ops(struct ath
- priv_ops->restore_chainmask = ar5008_restore_chainmask;
- priv_ops->set_diversity = ar5008_set_diversity;
- priv_ops->do_getnf = ar5008_hw_do_getnf;
-- priv_ops->loadnf = ar5008_hw_loadnf;
-
- if (modparam_force_new_ani) {
- priv_ops->ani_control = ar5008_hw_ani_control_new;
-@@ -1701,4 +1637,5 @@ void ar5008_hw_attach_phy_ops(struct ath
- priv_ops->compute_pll_control = ar5008_hw_compute_pll_control;
-
- ar5008_hw_set_nf_limits(ah);
-+ memcpy(ah->nf_regs, ar5416_cca_regs, sizeof(ah->nf_regs));
- }
---- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
-+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
-@@ -1050,106 +1050,6 @@ static void ar9003_hw_set_nf_limits(stru
- }
-
- /*
-- * Find out which of the RX chains are enabled
-- */
--static u32 ar9003_hw_get_rx_chainmask(struct ath_hw *ah)
--{
-- u32 chain = REG_READ(ah, AR_PHY_RX_CHAINMASK);
-- /*
-- * The bits [2:0] indicate the rx chain mask and are to be
-- * interpreted as follows:
-- * 00x => Only chain 0 is enabled
-- * 01x => Chain 1 and 0 enabled
-- * 1xx => Chain 2,1 and 0 enabled
-- */
-- return chain & 0x7;
--}
--
--static void ar9003_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
--{
-- struct ath9k_nfcal_hist *h;
-- unsigned i, j;
-- int32_t val;
-- const u32 ar9300_cca_regs[6] = {
-- AR_PHY_CCA_0,
-- AR_PHY_CCA_1,
-- AR_PHY_CCA_2,
-- AR_PHY_EXT_CCA,
-- AR_PHY_EXT_CCA_1,
-- AR_PHY_EXT_CCA_2,
-- };
-- u8 chainmask, rx_chain_status;
-- struct ath_common *common = ath9k_hw_common(ah);
--
-- rx_chain_status = ar9003_hw_get_rx_chainmask(ah);
--
-- chainmask = 0x3F;
-- h = ah->nfCalHist;
--
-- for (i = 0; i < NUM_NF_READINGS; i++) {
-- if (chainmask & (1 << i)) {
-- val = REG_READ(ah, ar9300_cca_regs[i]);
-- val &= 0xFFFFFE00;
-- val |= (((u32) (h[i].privNF) << 1) & 0x1ff);
-- REG_WRITE(ah, ar9300_cca_regs[i], val);
-- }
-- }
--
-- /*
-- * Load software filtered NF value into baseband internal minCCApwr
-- * variable.
-- */
-- REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
-- AR_PHY_AGC_CONTROL_ENABLE_NF);
-- REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
-- AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
-- REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
--
-- /*
-- * Wait for load to complete, should be fast, a few 10s of us.
-- * The max delay was changed from an original 250us to 10000us
-- * since 250us often results in NF load timeout and causes deaf
-- * condition during stress testing 12/12/2009
-- */
-- for (j = 0; j < 1000; j++) {
-- if ((REG_READ(ah, AR_PHY_AGC_CONTROL) &
-- AR_PHY_AGC_CONTROL_NF) == 0)
-- break;
-- udelay(10);
-- }
--
-- /*
-- * We timed out waiting for the noisefloor to load, probably due to an
-- * in-progress rx. Simply return here and allow the load plenty of time
-- * to complete before the next calibration interval. We need to avoid
-- * trying to load -50 (which happens below) while the previous load is
-- * still in progress as this can cause rx deafness. Instead by returning
-- * here, the baseband nf cal will just be capped by our present
-- * noisefloor until the next calibration timer.
-- */
-- if (j == 1000) {
-- ath_print(common, ATH_DBG_ANY, "Timeout while waiting for nf "
-- "to load: AR_PHY_AGC_CONTROL=0x%x\n",
-- REG_READ(ah, AR_PHY_AGC_CONTROL));
-- return;
-- }
--
-- /*
-- * Restore maxCCAPower register parameter again so that we're not capped
-- * by the median we just loaded. This will be initial (and max) value
-- * of next noise floor calibration the baseband does.
-- */
-- for (i = 0; i < NUM_NF_READINGS; i++) {
-- if (chainmask & (1 << i)) {
-- val = REG_READ(ah, ar9300_cca_regs[i]);
-- val &= 0xFFFFFE00;
-- val |= (((u32) (-50) << 1) & 0x1ff);
-- REG_WRITE(ah, ar9300_cca_regs[i], val);
-- }
-- }
--}
--
--/*
- * Initialize the ANI register values with default (ini) values.
- * This routine is called during a (full) hardware reset after
- * all the registers are initialised from the INI.
-@@ -1216,6 +1116,14 @@ static void ar9003_hw_ani_cache_ini_regs
- void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
- {
- struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
-+ const u32 ar9300_cca_regs[6] = {
-+ AR_PHY_CCA_0,
-+ AR_PHY_CCA_1,
-+ AR_PHY_CCA_2,
-+ AR_PHY_EXT_CCA,
-+ AR_PHY_EXT_CCA_1,
-+ AR_PHY_EXT_CCA_2,
-+ };
-
- priv_ops->rf_set_freq = ar9003_hw_set_channel;
- priv_ops->spur_mitigate_freq = ar9003_hw_spur_mitigate;
-@@ -1232,10 +1140,10 @@ void ar9003_hw_attach_phy_ops(struct ath
- priv_ops->set_diversity = ar9003_hw_set_diversity;
- priv_ops->ani_control = ar9003_hw_ani_control;
- priv_ops->do_getnf = ar9003_hw_do_getnf;
-- priv_ops->loadnf = ar9003_hw_loadnf;
- priv_ops->ani_cache_ini_regs = ar9003_hw_ani_cache_ini_regs;
-
- ar9003_hw_set_nf_limits(ah);
-+ memcpy(ah->nf_regs, ar9300_cca_regs, sizeof(ah->nf_regs));
- }
-
- void ar9003_hw_bb_watchdog_config(struct ath_hw *ah)
---- a/drivers/net/wireless/ath/ath9k/calib.c
-+++ b/drivers/net/wireless/ath/ath9k/calib.c
-@@ -167,6 +167,100 @@ void ath9k_hw_start_nfcal(struct ath_hw
- REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
- }
-
-+void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
-+{
-+ struct ath9k_nfcal_hist *h;
-+ unsigned i, j;
-+ int32_t val;
-+ u8 chainmask;
-+ struct ath_common *common = ath9k_hw_common(ah);
-+
-+ if (AR_SREV_9300_20_OR_LATER(ah))
-+ chainmask = 0x3F;
-+ else if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
-+ chainmask = 0x9;
-+ else if (AR_SREV_9280(ah) || AR_SREV_9287(ah)) {
-+ if ((ah->rxchainmask & 0x2) || (ah->rxchainmask & 0x4))
-+ chainmask = 0x1B;
-+ else
-+ chainmask = 0x09;
-+ } else {
-+ if (ah->rxchainmask & 0x4)
-+ chainmask = 0x3F;
-+ else if (ah->rxchainmask & 0x2)
-+ chainmask = 0x1B;
-+ else
-+ chainmask = 0x09;
-+ }
-+ h = ah->nfCalHist;
-+
-+ for (i = 0; i < NUM_NF_READINGS; i++) {
-+ if (chainmask & (1 << i)) {
-+ val = REG_READ(ah, ah->nf_regs[i]);
-+ val &= 0xFFFFFE00;
-+ val |= (((u32) (h[i].privNF) << 1) & 0x1ff);
-+ REG_WRITE(ah, ah->nf_regs[i], val);
-+ }
-+ }
-+
-+ /*
-+ * Load software filtered NF value into baseband internal minCCApwr
-+ * variable.
-+ */
-+ REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
-+ AR_PHY_AGC_CONTROL_ENABLE_NF);
-+ REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
-+ AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
-+ REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
-+
-+ /*
-+ * Wait for load to complete, should be fast, a few 10s of us.
-+ * The max delay was changed from an original 250us to 10000us
-+ * since 250us often results in NF load timeout and causes deaf
-+ * condition during stress testing 12/12/2009
-+ */
-+ for (j = 0; j < 1000; j++) {
-+ if ((REG_READ(ah, AR_PHY_AGC_CONTROL) &
-+ AR_PHY_AGC_CONTROL_NF) == 0)
-+ break;
-+ udelay(10);
-+ }
-+
-+ /*
-+ * We timed out waiting for the noisefloor to load, probably due to an
-+ * in-progress rx. Simply return here and allow the load plenty of time
-+ * to complete before the next calibration interval. We need to avoid
-+ * trying to load -50 (which happens below) while the previous load is
-+ * still in progress as this can cause rx deafness. Instead by returning
-+ * here, the baseband nf cal will just be capped by our present
-+ * noisefloor until the next calibration timer.
-+ */
-+ if (j == 1000) {
-+ ath_print(common, ATH_DBG_ANY, "Timeout while waiting for nf "
-+ "to load: AR_PHY_AGC_CONTROL=0x%x\n",
-+ REG_READ(ah, AR_PHY_AGC_CONTROL));
-+ return;
-+ }
-+
-+ /*
-+ * Restore maxCCAPower register parameter again so that we're not capped
-+ * by the median we just loaded. This will be initial (and max) value
-+ * of next noise floor calibration the baseband does.
-+ */
-+ ENABLE_REGWRITE_BUFFER(ah);
-+ for (i = 0; i < NUM_NF_READINGS; i++) {
-+ if (chainmask & (1 << i)) {
-+ val = REG_READ(ah, ah->nf_regs[i]);
-+ val &= 0xFFFFFE00;
-+ val |= (((u32) (-50) << 1) & 0x1ff);
-+ REG_WRITE(ah, ah->nf_regs[i], val);
-+ }
-+ }
-+ REGWRITE_BUFFER_FLUSH(ah);
-+ DISABLE_REGWRITE_BUFFER(ah);
-+}
-+
-+
- static void ath9k_hw_nf_sanitize(struct ath_hw *ah, s16 *nf)
- {
- struct ath_common *common = ath9k_hw_common(ah);
---- a/drivers/net/wireless/ath/ath9k/calib.h
-+++ b/drivers/net/wireless/ath/ath9k/calib.h
-@@ -109,6 +109,7 @@ struct ath9k_pacal_info{
-
- bool ath9k_hw_reset_calvalid(struct ath_hw *ah);
- void ath9k_hw_start_nfcal(struct ath_hw *ah);
-+void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan);
- int16_t ath9k_hw_getnf(struct ath_hw *ah,
- struct ath9k_channel *chan);
- void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah);
---- a/drivers/net/wireless/ath/ath9k/hw-ops.h
-+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
-@@ -264,12 +264,6 @@ static inline void ath9k_hw_do_getnf(str
- ath9k_hw_private_ops(ah)->do_getnf(ah, nfarray);
- }
-
--static inline void ath9k_hw_loadnf(struct ath_hw *ah,
-- struct ath9k_channel *chan)
--{
-- ath9k_hw_private_ops(ah)->loadnf(ah, chan);
--}
--
- static inline bool ath9k_hw_init_cal(struct ath_hw *ah,
- struct ath9k_channel *chan)
- {
---- a/drivers/net/wireless/ath/ath9k/hw.h
-+++ b/drivers/net/wireless/ath/ath9k/hw.h
-@@ -510,7 +510,6 @@ struct ath_gen_timer_table {
- * AR_RTC_PLL_CONTROL for a given channel
- * @setup_calibration: set up calibration
- * @iscal_supported: used to query if a type of calibration is supported
-- * @loadnf: load noise floor read from each chain on the CCA registers
- *
- * @ani_reset: reset ANI parameters to default values
- * @ani_lower_immunity: lower the noise immunity level. The level controls
-@@ -564,7 +563,6 @@ struct ath_hw_private_ops {
- bool (*ani_control)(struct ath_hw *ah, enum ath9k_ani_cmd cmd,
- int param);
- void (*do_getnf)(struct ath_hw *ah, int16_t nfarray[NUM_NF_READINGS]);
-- void (*loadnf)(struct ath_hw *ah, struct ath9k_channel *chan);
-
- /* ANI */
- void (*ani_reset)(struct ath_hw *ah, bool is_scanning);
-@@ -658,6 +656,7 @@ struct ath_hw {
- bool need_an_top2_fixup;
- u16 tx_trig_level;
-
-+ u32 nf_regs[6];
- struct ath_nf_limits nf_2g;
- struct ath_nf_limits nf_5g;
- u16 rfsilent;
+++ /dev/null
---- a/drivers/net/wireless/ath/ath9k/xmit.c
-+++ b/drivers/net/wireless/ath/ath9k/xmit.c
-@@ -329,7 +329,6 @@ static void ath_tx_complete_aggr(struct
- int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0;
- bool rc_update = true;
- struct ieee80211_tx_rate rates[4];
-- unsigned long flags;
-
- skb = bf->bf_mpdu;
- hdr = (struct ieee80211_hdr *)skb->data;
-@@ -346,9 +345,21 @@ static void ath_tx_complete_aggr(struct
- if (!sta) {
- rcu_read_unlock();
-
-- spin_lock_irqsave(&sc->tx.txbuflock, flags);
-- list_splice_tail_init(bf_q, &sc->tx.txbuf);
-- spin_unlock_irqrestore(&sc->tx.txbuflock, flags);
-+ INIT_LIST_HEAD(&bf_head);
-+ while (bf) {
-+ bf_next = bf->bf_next;
-+
-+ bf->bf_state.bf_type |= BUF_XRETRY;
-+ if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) ||
-+ !bf->bf_stale || bf_next != NULL)
-+ list_move_tail(&bf->list, &bf_head);
-+
-+ ath_tx_rc_status(bf, ts, 0, 0, false);
-+ ath_tx_complete_buf(sc, bf, txq, &bf_head, ts,
-+ 0, 0);
-+
-+ bf = bf_next;
-+ }
- return;
- }
-
--- /dev/null
+--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
++++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+@@ -1508,6 +1508,9 @@ static void ar5008_hw_do_getnf(struct at
+ nf = MS(REG_READ(ah, AR_PHY_CH2_CCA), AR_PHY_CH2_MINCCA_PWR);
+ nfarray[2] = sign_extend(nf, 9);
+
++ if (!IS_CHAN_HT40(ah->curchan))
++ return;
++
+ nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR);
+ nfarray[3] = sign_extend(nf, 9);
+
+--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c
++++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
+@@ -477,7 +477,8 @@ static void ar9002_hw_do_getnf(struct at
+ nfarray[0] = sign_extend(nf, 9);
+
+ nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR9280_PHY_EXT_MINCCA_PWR);
+- nfarray[3] = sign_extend(nf, 9);
++ if (IS_CHAN_HT40(ah->curchan))
++ nfarray[3] = sign_extend(nf, 9);
+
+ if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
+ return;
+@@ -486,7 +487,8 @@ static void ar9002_hw_do_getnf(struct at
+ nfarray[1] = sign_extend(nf, 9);
+
+ nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), AR9280_PHY_CH1_EXT_MINCCA_PWR);
+- nfarray[4] = sign_extend(nf, 9);
++ if (IS_CHAN_HT40(ah->curchan))
++ nfarray[4] = sign_extend(nf, 9);
+ }
+
+ static void ar9002_hw_set_nf_limits(struct ath_hw *ah)
+--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
++++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+@@ -1029,6 +1029,9 @@ static void ar9003_hw_do_getnf(struct at
+ nf = MS(REG_READ(ah, AR_PHY_CCA_2), AR_PHY_CH2_MINCCA_PWR);
+ nfarray[2] = sign_extend(nf, 9);
+
++ if (!IS_CHAN_HT40(ah->curchan))
++ return;
++
+ nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR);
+ nfarray[3] = sign_extend(nf, 9);
+
--- /dev/null
+--- a/drivers/net/wireless/ath/ath9k/calib.c
++++ b/drivers/net/wireless/ath/ath9k/calib.c
+@@ -172,26 +172,9 @@ void ath9k_hw_loadnf(struct ath_hw *ah,
+ struct ath9k_nfcal_hist *h;
+ unsigned i, j;
+ int32_t val;
+- u8 chainmask;
++ u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask;
+ struct ath_common *common = ath9k_hw_common(ah);
+
+- if (AR_SREV_9300_20_OR_LATER(ah))
+- chainmask = 0x3F;
+- else if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
+- chainmask = 0x9;
+- else if (AR_SREV_9280(ah) || AR_SREV_9287(ah)) {
+- if ((ah->rxchainmask & 0x2) || (ah->rxchainmask & 0x4))
+- chainmask = 0x1B;
+- else
+- chainmask = 0x09;
+- } else {
+- if (ah->rxchainmask & 0x4)
+- chainmask = 0x3F;
+- else if (ah->rxchainmask & 0x2)
+- chainmask = 0x1B;
+- else
+- chainmask = 0x09;
+- }
+ h = ah->nfCalHist;
+
+ for (i = 0; i < NUM_NF_READINGS; i++) {
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
-@@ -188,6 +188,7 @@ void rt2x00pci_uninitialize(struct rt2x0
+@@ -202,6 +202,7 @@ void rt2x00pci_uninitialize(struct rt2x0
}
EXPORT_SYMBOL_GPL(rt2x00pci_uninitialize);
/*
* PCI driver handlers.
*/
-@@ -365,6 +366,7 @@ int rt2x00pci_resume(struct pci_dev *pci
+@@ -382,6 +383,7 @@ int rt2x00pci_resume(struct pci_dev *pci
}
EXPORT_SYMBOL_GPL(rt2x00pci_resume);
#endif /* CONFIG_PM */
+++ /dev/null
-From 27ed5ec6924c17b76d65b697a162bafee7bd8e4e Mon Sep 17 00:00:00 2001
-From: Helmut Schaa <helmut.schaa@googlemail.com>
-Date: Mon, 21 Jun 2010 10:03:05 +0200
-Subject: [PATCH] rt2x00: fix rt2800pci hang on ifdown
-
-rt2800pci hangs the system on rt305x SoC devices on ifdown. Work around
-this issue by disabling TX DMA prior to restting the TX queue indices.
-
-This patch is not suitable for upstream inclusion but is just meant as
-a workaround until a proper solution is implemented.
-
-Signed-off-by: Helmut Schaa <helmut.schaa@googlemail.com>
----
- drivers/net/wireless/rt2x00/rt2800pci.c | 4 ++++
- 1 files changed, 4 insertions(+), 0 deletions(-)
-
---- a/drivers/net/wireless/rt2x00/rt2800pci.c
-+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
-@@ -749,6 +749,10 @@ static void rt2800pci_kill_tx_queue(stru
- rt2800_register_write(rt2x00dev, BCN_TIME_CFG, 0);
- return;
- }
-+
-+ rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®);
-+ rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
-+ rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
-
- rt2800_register_read(rt2x00dev, WPDMA_RST_IDX, ®);
- rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX0, (qid == QID_AC_BE));
--- /dev/null
+--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
++++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
+@@ -270,8 +270,10 @@ int rt2x00pci_probe(struct pci_dev *pci_
+
+ pci_set_master(pci_dev);
+
++#ifdef CONFIG_PCI_SET_MWI
+ if (pci_set_mwi(pci_dev))
+ ERROR_PROBE("MWI not available.\n");
++#endif
+
+ if (dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(32))) {
+ ERROR_PROBE("PCI DMA not supported.\n");
+++ /dev/null
---- a/drivers/net/wireless/rt2x00/rt2x00pci.c
-+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
-@@ -253,8 +253,10 @@ int rt2x00pci_probe(struct pci_dev *pci_
-
- pci_set_master(pci_dev);
-
-+#ifdef CONFIG_PCI_SET_MWI
- if (pci_set_mwi(pci_dev))
- ERROR_PROBE("MWI not available.\n");
-+#endif
-
- if (dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(32))) {
- ERROR_PROBE("PCI DMA not supported.\n");
--- /dev/null
+--- a/net/mac80211/iface.c
++++ b/net/mac80211/iface.c
+@@ -756,7 +756,7 @@ static void ieee80211_iface_work(struct
+ int len = skb->len;
+
+ mutex_lock(&local->sta_mtx);
+- sta = sta_info_get(sdata, mgmt->sa);
++ sta = sta_info_get_bss(sdata, mgmt->sa);
+ if (sta) {
+ switch (mgmt->u.action.u.addba_req.action_code) {
+ case WLAN_ACTION_ADDBA_REQ:
+@@ -797,7 +797,7 @@ static void ieee80211_iface_work(struct
+ * right, so terminate the session.
+ */
+ mutex_lock(&local->sta_mtx);
+- sta = sta_info_get(sdata, mgmt->sa);
++ sta = sta_info_get_bss(sdata, mgmt->sa);
+ if (sta) {
+ u16 tid = *ieee80211_get_qos_ctl(hdr) &
+ IEEE80211_QOS_CTL_TID_MASK;