1
0
mirror of git://projects.qi-hardware.com/openwrt-xburst.git synced 2024-11-23 21:00:37 +02:00

mac80211: backport latest version from trunk into backfire

git-svn-id: svn://svn.openwrt.org/openwrt/branches/backfire@22391 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
nbd 2010-07-26 21:59:27 +00:00
parent 2f1f0c0e5b
commit 250cb956cb
22 changed files with 288 additions and 724 deletions

View File

@ -10,12 +10,12 @@ include $(INCLUDE_DIR)/kernel.mk
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)

View File

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

View File

@ -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);

View File

@ -0,0 +1,35 @@
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 */

View File

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

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

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

View File

@ -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",

View File

@ -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] +

View File

@ -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))

View File

@ -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);

View File

@ -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;

View File

@ -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;
}

View File

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

View File

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

View File

@ -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 */

View File

@ -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));

View File

@ -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);

View File

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