diff options
author | John W. Linville <linville@tuxdriver.com> | 2011-06-30 13:34:06 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-06-30 13:34:06 -0400 |
commit | df2cbe40753dc36af294c30209ed909869aca6cf (patch) | |
tree | 39eb7e8e06737b295007126f4e16c1b688427163 /drivers/net/wireless/ath/ath9k | |
parent | 1049f6413f6e52572a768ca1590fa479ef0a48e8 (diff) | |
parent | 9a4ba833a2d0016cf836827e136f0c219834bd41 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Diffstat (limited to 'drivers/net/wireless/ath/ath9k')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ar9003_mac.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ar9003_paprd.c | 38 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ar9003_phy.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ath9k.h | 5 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/beacon.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/hif_usb.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/init.c | 7 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 13 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/xmit.c | 7 |
9 files changed, 62 insertions, 29 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c index 04e6be04acf..575e185f454 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c @@ -229,6 +229,7 @@ static void ar9003_hw_fill_txdesc(struct ath_hw *ah, void *ds, u32 seglen, static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_status *ts) { + struct ar9003_txc *txc = (struct ar9003_txc *) ds; struct ar9003_txs *ads; u32 status; @@ -238,7 +239,11 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds, if ((status & AR_TxDone) == 0) return -EINPROGRESS; - ah->ts_tail = (ah->ts_tail + 1) % ah->ts_size; + ts->qid = MS(ads->ds_info, AR_TxQcuNum); + if (!txc || (MS(txc->info, AR_TxQcuNum) == ts->qid)) + ah->ts_tail = (ah->ts_tail + 1) % ah->ts_size; + else + return -ENOENT; if ((MS(ads->ds_info, AR_DescId) != ATHEROS_VENDOR_ID) || (MS(ads->ds_info, AR_TxRxDesc) != 1)) { @@ -254,7 +259,6 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds, ts->ts_seqnum = MS(status, AR_SeqNum); ts->tid = MS(status, AR_TxTid); - ts->qid = MS(ads->ds_info, AR_TxQcuNum); ts->desc_id = MS(ads->status1, AR_TxDescId); ts->ts_tstamp = ads->status4; ts->ts_status = 0; diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c index 8f6d11dfa37..de1972307b0 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c @@ -236,7 +236,7 @@ static void ar9003_paprd_get_gain_table(struct ath_hw *ah) memset(entry, 0, sizeof(ah->paprd_gain_table_entries)); memset(index, 0, sizeof(ah->paprd_gain_table_index)); - for (i = 0; i < 32; i++) { + for (i = 0; i < PAPRD_GAIN_TABLE_ENTRIES; i++) { entry[i] = REG_READ(ah, reg); index[i] = (entry[i] >> 24) & 0xff; reg += 4; @@ -246,13 +246,13 @@ static void ar9003_paprd_get_gain_table(struct ath_hw *ah) static unsigned int ar9003_get_desired_gain(struct ath_hw *ah, int chain, int target_power) { - int olpc_gain_delta = 0; + int olpc_gain_delta = 0, cl_gain_mod; int alpha_therm, alpha_volt; int therm_cal_value, volt_cal_value; int therm_value, volt_value; int thermal_gain_corr, voltage_gain_corr; int desired_scale, desired_gain = 0; - u32 reg; + u32 reg_olpc = 0, reg_cl_gain = 0; REG_CLR_BIT(ah, AR_PHY_PAPRD_TRAINER_STAT1, AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE); @@ -271,15 +271,29 @@ static unsigned int ar9003_get_desired_gain(struct ath_hw *ah, int chain, volt_value = REG_READ_FIELD(ah, AR_PHY_BB_THERM_ADC_4, AR_PHY_BB_THERM_ADC_4_LATEST_VOLT_VALUE); - if (chain == 0) - reg = AR_PHY_TPC_11_B0; - else if (chain == 1) - reg = AR_PHY_TPC_11_B1; - else - reg = AR_PHY_TPC_11_B2; + switch (chain) { + case 0: + reg_olpc = AR_PHY_TPC_11_B0; + reg_cl_gain = AR_PHY_CL_TAB_0; + break; + case 1: + reg_olpc = AR_PHY_TPC_11_B1; + reg_cl_gain = AR_PHY_CL_TAB_1; + break; + case 2: + reg_olpc = AR_PHY_TPC_11_B2; + reg_cl_gain = AR_PHY_CL_TAB_2; + break; + default: + ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, + "Invalid chainmask: %d\n", chain); + break; + } - olpc_gain_delta = REG_READ_FIELD(ah, reg, + olpc_gain_delta = REG_READ_FIELD(ah, reg_olpc, AR_PHY_TPC_11_OLPC_GAIN_DELTA); + cl_gain_mod = REG_READ_FIELD(ah, reg_cl_gain, + AR_PHY_CL_TAB_CL_GAIN_MOD); if (olpc_gain_delta >= 128) olpc_gain_delta = olpc_gain_delta - 256; @@ -289,7 +303,7 @@ static unsigned int ar9003_get_desired_gain(struct ath_hw *ah, int chain, voltage_gain_corr = (alpha_volt * (volt_value - volt_cal_value) + (128 / 2)) / 128; desired_gain = target_power - olpc_gain_delta - thermal_gain_corr - - voltage_gain_corr + desired_scale; + voltage_gain_corr + desired_scale + cl_gain_mod; return desired_gain; } @@ -727,7 +741,7 @@ int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain) desired_gain = ar9003_get_desired_gain(ah, chain, train_power); gain_index = 0; - for (i = 0; i < 32; i++) { + for (i = 0; i < PAPRD_GAIN_TABLE_ENTRIES; i++) { if (ah->paprd_gain_table_index[i] >= desired_gain) break; gain_index++; diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index 9eb3aa21168..6de3f0bc18e 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h @@ -1121,6 +1121,9 @@ #define AR_PHY_POWERTX_RATE8_POWERTXHT40_5 0x3F00 #define AR_PHY_POWERTX_RATE8_POWERTXHT40_5_S 8 +#define AR_PHY_CL_TAB_CL_GAIN_MOD 0x1f +#define AR_PHY_CL_TAB_CL_GAIN_MOD_S 0 + void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx); #endif /* AR9003_PHY_H */ diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 359576ff86d..46393f90f16 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -101,6 +101,11 @@ enum buffer_type { #define ATH_TXSTATUS_RING_SIZE 64 +#define DS2PHYS(_dd, _ds) \ + ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc)) +#define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0) +#define ATH_DESC_4KB_BOUND_NUM_SKIPPED(_len) ((_len) / 4096) + struct ath_descdma { void *dd_desc; dma_addr_t dd_desc_paddr; diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 4c790b5f793..0d13ff74a68 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -361,6 +361,7 @@ void ath_beacon_tasklet(unsigned long data) struct ath_common *common = ath9k_hw_common(ah); struct ath_buf *bf = NULL; struct ieee80211_vif *vif; + struct ath_tx_status ts; int slot; u32 bfaddr, bc = 0; @@ -385,7 +386,9 @@ void ath_beacon_tasklet(unsigned long data) ath_dbg(common, ATH_DBG_BSTUCK, "beacon is officially stuck\n"); sc->sc_flags |= SC_OP_TSF_RESET; + spin_lock(&sc->sc_pcu_lock); ath_reset(sc, true); + spin_unlock(&sc->sc_pcu_lock); } return; @@ -465,6 +468,11 @@ void ath_beacon_tasklet(unsigned long data) ath9k_hw_txstart(ah, sc->beacon.beaconq); sc->beacon.ast_be_xmit += bc; /* XXX per-vif? */ + if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { + spin_lock_bh(&sc->sc_pcu_lock); + ath9k_hw_txprocdesc(ah, bf->bf_desc, (void *)&ts); + spin_unlock_bh(&sc->sc_pcu_lock); + } } } diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 260f1f37a60..8028fe90f66 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -49,6 +49,8 @@ static struct usb_device_id ath9k_hif_usb_ids[] = { .driver_info = AR9280_USB }, /* Netgear WNDA3200 */ { USB_DEVICE(0x083A, 0xA704), .driver_info = AR9280_USB }, /* SMC Networks */ + { USB_DEVICE(0x0411, 0x017f), + .driver_info = AR9280_USB }, /* Sony UWA-BR100 */ { USB_DEVICE(0x0cf3, 0x20ff), .driver_info = STORAGE_DEVICE }, diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 616e30b2001..b855fe1adc3 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -299,10 +299,6 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, struct list_head *head, const char *name, int nbuf, int ndesc, bool is_tx) { -#define DS2PHYS(_dd, _ds) \ - ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc)) -#define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0) -#define ATH_DESC_4KB_BOUND_NUM_SKIPPED(_len) ((_len) / 4096) struct ath_common *common = ath9k_hw_common(sc->sc_ah); u8 *ds; struct ath_buf *bf; @@ -397,9 +393,6 @@ fail2: fail: memset(dd, 0, sizeof(*dd)); return error; -#undef ATH_DESC_4KB_BOUND_CHECK -#undef ATH_DESC_4KB_BOUND_NUM_SKIPPED -#undef DS2PHYS } void ath9k_init_crypto(struct ath_softc *sc) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 5ae303b11e6..9098aaad97a 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -617,8 +617,11 @@ void ath_hw_check(struct work_struct *work) ath_dbg(common, ATH_DBG_RESET, "Possible baseband hang, " "busy=%d (try %d)\n", busy, sc->hw_busy_count + 1); if (busy >= 99) { - if (++sc->hw_busy_count >= 3) + if (++sc->hw_busy_count >= 3) { + spin_lock_bh(&sc->sc_pcu_lock); ath_reset(sc, true); + spin_unlock_bh(&sc->sc_pcu_lock); + } } else if (busy >= 0) sc->hw_busy_count = 0; @@ -637,7 +640,9 @@ static void ath_hw_pll_rx_hang_check(struct ath_softc *sc, u32 pll_sqsum) /* Rx is hung for more than 500ms. Reset it */ ath_dbg(common, ATH_DBG_RESET, "Possible RX hang, resetting"); + spin_lock_bh(&sc->sc_pcu_lock); ath_reset(sc, true); + spin_unlock_bh(&sc->sc_pcu_lock); count = 0; } } else @@ -674,7 +679,9 @@ void ath9k_tasklet(unsigned long data) if ((status & ATH9K_INT_FATAL) || (status & ATH9K_INT_BB_WATCHDOG)) { + spin_lock(&sc->sc_pcu_lock); ath_reset(sc, true); + spin_unlock(&sc->sc_pcu_lock); return; } @@ -980,7 +987,6 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) del_timer_sync(&common->ani.timer); ath9k_ps_wakeup(sc); - spin_lock_bh(&sc->sc_pcu_lock); ieee80211_stop_queues(hw); @@ -1023,7 +1029,6 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) } ieee80211_wake_queues(hw); - spin_unlock_bh(&sc->sc_pcu_lock); /* Start ANI */ if (!common->disable_ani) @@ -2326,9 +2331,9 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop) ath9k_ps_wakeup(sc); spin_lock_bh(&sc->sc_pcu_lock); drain_txq = ath_drain_all_txq(sc, false); - spin_unlock_bh(&sc->sc_pcu_lock); if (!drain_txq) ath_reset(sc, false); + spin_unlock_bh(&sc->sc_pcu_lock); ath9k_ps_restore(sc); ieee80211_wake_queues(hw); diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 7e79bbaf2ba..52dadfc3884 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -566,11 +566,8 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, rcu_read_unlock(); - if (needreset) { - spin_unlock_bh(&sc->sc_pcu_lock); + if (needreset) ath_reset(sc, false); - spin_lock_bh(&sc->sc_pcu_lock); - } } static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf, @@ -2170,7 +2167,9 @@ static void ath_tx_complete_poll_work(struct work_struct *work) if (needreset) { ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_RESET, "tx hung, resetting the chip\n"); + spin_lock_bh(&sc->sc_pcu_lock); ath_reset(sc, true); + spin_unlock_bh(&sc->sc_pcu_lock); } ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, |