aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorNick Kossifidis <mick@madwifi-project.org>2009-04-30 15:55:47 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-05-06 15:14:55 -0400
commit428cbd4ff4d0f2423f49e499f499f04a636cb152 (patch)
tree1e30461090032e33a7e69abf0ced53ba3be63105 /drivers
parent1889ba0a48688b639c2b2e9e1b0fd8f84e2c37d1 (diff)
ath5k: Beaconing fixes
* Write next beacon timer even on AP mode since without this we get no beacons + ath9k does it too. Docs say that we must write 0 on this register on AP mode to start TSF increment, we do both to be on the safe side. * Fix num_tx_pending function, we never read the register :P that's why we got all those "beacon queue 7 didn't stop messages". * Put full prioriy on beacon queue, lock all queues with lower priority using the arblock and also bypass any arblock by seting the arblock ignore flag. * For the CAB queue (do we need this thing ?, it seems crap) since it's supposed to fire up after each beacon (we don't use it on driver part, ath9k/MadWiFi does), don't make it DBA gated but instead make it fire after each beacon by using the beacon sent gated flag. * Increase bmiss threshold to 10, that's what we used on MadWiFi for a long time. Also when we have pending frames on the beacon queue (we got a beacon that didn't make it on the air) it's more likely that the beacon queue never started, probably due to faulty DBA setting, so change that "beacon queue didn't stop" message. Tested this with AP mode and IBSS mode and seems to work fine ;-) Signed-off-by: Nick Kossifidis <mickflemm@gmail.com> Signed-off-by: Bob Copeland <me@bobcopeland.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-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 -