aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c64
-rw-r--r--drivers/net/wireless/ath/ath5k/pcu.c4
-rw-r--r--drivers/net/wireless/ath/ath5k/qcu.c7
3 files changed, 40 insertions, 35 deletions
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index d70856a9520e..b48ff7ded325 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -1738,35 +1738,6 @@ ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb,
1738 } 1738 }
1739} 1739}
1740 1740
1741static void ath5k_tasklet_beacon(unsigned long data)
1742{
1743 struct ath5k_softc *sc = (struct ath5k_softc *) data;
1744
1745 /*
1746 * Software beacon alert--time to send a beacon.
1747 *
1748 * In IBSS mode we use this interrupt just to
1749 * keep track of the next TBTT (target beacon
1750 * transmission time) in order to detect wether
1751 * automatic TSF updates happened.
1752 */
1753 if (sc->opmode == NL80211_IFTYPE_ADHOC) {
1754 /* XXX: only if VEOL suppported */
1755 u64 tsf = ath5k_hw_get_tsf64(sc->ah);
1756 sc->nexttbtt += sc->bintval;
1757 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
1758 "SWBA nexttbtt: %x hw_tu: %x "
1759 "TSF: %llx\n",
1760 sc->nexttbtt,
1761 TSF_TO_TU(tsf),
1762 (unsigned long long) tsf);
1763 } else {
1764 spin_lock(&sc->block);
1765 ath5k_beacon_send(sc);
1766 spin_unlock(&sc->block);
1767 }
1768}
1769
1770static void 1741static void
1771ath5k_tasklet_rx(unsigned long data) 1742ath5k_tasklet_rx(unsigned long data)
1772{ 1743{
@@ -2120,7 +2091,7 @@ ath5k_beacon_send(struct ath5k_softc *sc)
2120 sc->bmisscount++; 2091 sc->bmisscount++;
2121 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, 2092 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
2122 "missed %u consecutive beacons\n", sc->bmisscount); 2093 "missed %u consecutive beacons\n", sc->bmisscount);
2123 if (sc->bmisscount > 3) { /* NB: 3 is a guess */ 2094 if (sc->bmisscount > 10) { /* NB: 10 is a guess */
2124 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, 2095 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
2125 "stuck beacon time (%u missed)\n", 2096 "stuck beacon time (%u missed)\n",
2126 sc->bmisscount); 2097 sc->bmisscount);
@@ -2141,10 +2112,12 @@ ath5k_beacon_send(struct ath5k_softc *sc)
2141 * are still pending on the queue. 2112 * are still pending on the queue.
2142 */ 2113 */
2143 if (unlikely(ath5k_hw_stop_tx_dma(ah, sc->bhalq))) { 2114 if (unlikely(ath5k_hw_stop_tx_dma(ah, sc->bhalq))) {
2144 ATH5K_WARN(sc, "beacon queue %u didn't stop?\n", sc->bhalq); 2115 ATH5K_WARN(sc, "beacon queue %u didn't start/stop ?\n", sc->bhalq);
2145 /* NB: hw still stops DMA, so proceed */ 2116 /* NB: hw still stops DMA, so proceed */
2146 } 2117 }
2147 2118
2119 /* Note: Beacon buffer is updated on beacon_update when mac80211
2120 * calls config_interface */
2148 ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr); 2121 ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr);
2149 ath5k_hw_start_tx_dma(ah, sc->bhalq); 2122 ath5k_hw_start_tx_dma(ah, sc->bhalq);
2150 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n", 2123 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n",
@@ -2301,6 +2274,35 @@ ath5k_beacon_config(struct ath5k_softc *sc)
2301 ath5k_hw_set_imr(ah, sc->imask); 2274 ath5k_hw_set_imr(ah, sc->imask);
2302} 2275}
2303 2276
2277static void ath5k_tasklet_beacon(unsigned long data)
2278{
2279 struct ath5k_softc *sc = (struct ath5k_softc *) data;
2280
2281 /*
2282 * Software beacon alert--time to send a beacon.
2283 *
2284 * In IBSS mode we use this interrupt just to
2285 * keep track of the next TBTT (target beacon
2286 * transmission time) in order to detect wether
2287 * automatic TSF updates happened.
2288 */
2289 if (sc->opmode == NL80211_IFTYPE_ADHOC) {
2290 /* XXX: only if VEOL suppported */
2291 u64 tsf = ath5k_hw_get_tsf64(sc->ah);
2292 sc->nexttbtt += sc->bintval;
2293 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
2294 "SWBA nexttbtt: %x hw_tu: %x "
2295 "TSF: %llx\n",
2296 sc->nexttbtt,
2297 TSF_TO_TU(tsf),
2298 (unsigned long long) tsf);
2299 } else {
2300 spin_lock(&sc->block);
2301 ath5k_beacon_send(sc);
2302 spin_unlock(&sc->block);
2303 }
2304}
2305
2304 2306
2305/********************\ 2307/********************\
2306* Interrupt handling * 2308* Interrupt handling *
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c
index 5f07e876d4bd..579aa0a96ab8 100644
--- a/drivers/net/wireless/ath/ath5k/pcu.c
+++ b/drivers/net/wireless/ath/ath5k/pcu.c
@@ -736,8 +736,8 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval)
736 /* When in AP mode zero timer0 to start TSF */ 736 /* When in AP mode zero timer0 to start TSF */
737 if (ah->ah_op_mode == NL80211_IFTYPE_AP) 737 if (ah->ah_op_mode == NL80211_IFTYPE_AP)
738 ath5k_hw_reg_write(ah, 0, AR5K_TIMER0); 738 ath5k_hw_reg_write(ah, 0, AR5K_TIMER0);
739 else 739
740 ath5k_hw_reg_write(ah, next_beacon, AR5K_TIMER0); 740 ath5k_hw_reg_write(ah, next_beacon, AR5K_TIMER0);
741 ath5k_hw_reg_write(ah, timer1, AR5K_TIMER1); 741 ath5k_hw_reg_write(ah, timer1, AR5K_TIMER1);
742 ath5k_hw_reg_write(ah, timer2, AR5K_TIMER2); 742 ath5k_hw_reg_write(ah, timer2, AR5K_TIMER2);
743 ath5k_hw_reg_write(ah, timer3, AR5K_TIMER3); 743 ath5k_hw_reg_write(ah, timer3, AR5K_TIMER3);
diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c
index 5094c394a4b2..73407b3f53ef 100644
--- a/drivers/net/wireless/ath/ath5k/qcu.c
+++ b/drivers/net/wireless/ath/ath5k/qcu.c
@@ -160,7 +160,8 @@ u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue)
160 if (ah->ah_version == AR5K_AR5210) 160 if (ah->ah_version == AR5K_AR5210)
161 return false; 161 return false;
162 162
163 pending = (AR5K_QUEUE_STATUS(queue) & AR5K_QCU_STS_FRMPENDCNT); 163 pending = ath5k_hw_reg_read(ah, AR5K_QUEUE_STATUS(queue));
164 pending &= AR5K_QCU_STS_FRMPENDCNT;
164 165
165 /* It's possible to have no frames pending even if TXE 166 /* It's possible to have no frames pending even if TXE
166 * is set. To indicate that q has not stopped return 167 * is set. To indicate that q has not stopped return
@@ -401,14 +402,16 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
401 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue), 402 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
402 (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL << 403 (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
403 AR5K_DCU_MISC_ARBLOCK_CTL_S) | 404 AR5K_DCU_MISC_ARBLOCK_CTL_S) |
405 AR5K_DCU_MISC_ARBLOCK_IGNORE |
404 AR5K_DCU_MISC_POST_FR_BKOFF_DIS | 406 AR5K_DCU_MISC_POST_FR_BKOFF_DIS |
405 AR5K_DCU_MISC_BCN_ENABLE); 407 AR5K_DCU_MISC_BCN_ENABLE);
406 break; 408 break;
407 409
408 case AR5K_TX_QUEUE_CAB: 410 case AR5K_TX_QUEUE_CAB:
409 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), 411 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
410 AR5K_QCU_MISC_FRSHED_DBA_GT | 412 AR5K_QCU_MISC_FRSHED_BCN_SENT_GT |
411 AR5K_QCU_MISC_CBREXP_DIS | 413 AR5K_QCU_MISC_CBREXP_DIS |
414 AR5K_QCU_MISC_RDY_VEOL_POLICY |
412 AR5K_QCU_MISC_CBREXP_BCN_DIS); 415 AR5K_QCU_MISC_CBREXP_BCN_DIS);
413 416
414 ath5k_hw_reg_write(ah, ((AR5K_TUNE_BEACON_INTERVAL - 417 ath5k_hw_reg_write(ah, ((AR5K_TUNE_BEACON_INTERVAL -