mac80211: update to wireless-testing 2010-07-16

SVN-Revision: 22301
v19.07.3_mercusys_ac12_duma
Felix Fietkau 14 years ago
parent f813a693fd
commit 41872e8765

@ -10,12 +10,12 @@ include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=mac80211
PKG_VERSION:=2010-07-06
PKG_RELEASE:=2
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)

@ -1,6 +1,6 @@
--- 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);

@ -1,68 +0,0 @@
--- 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);
}
}

@ -11,7 +11,7 @@
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
@@ -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;

@ -1,21 +0,0 @@
--- 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;
}

@ -1,77 +0,0 @@
--- 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;

@ -1,11 +0,0 @@
--- 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",

@ -1,11 +0,0 @@
--- 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] +

@ -1,15 +0,0 @@
--- 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))

@ -1,51 +0,0 @@
--- 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);

@ -1,399 +0,0 @@
--- 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;

@ -1,35 +0,0 @@
--- 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;
}

@ -1,6 +1,6 @@
--- 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);
@ -8,7 +8,7 @@
/*
* 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 */

@ -1,29 +0,0 @@
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, &reg);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
+ rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
rt2800_register_read(rt2x00dev, WPDMA_RST_IDX, &reg);
rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX0, (qid == QID_AC_BE));

@ -1,6 +1,6 @@
--- 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_
@@ -270,8 +270,10 @@ int rt2x00pci_probe(struct pci_dev *pci_
pci_set_master(pci_dev);
Loading…
Cancel
Save