Changeset 3867
- Timestamp:
- 09/23/08 20:21:56 (4 months ago)
- Files:
-
- madwifi/trunk/ath/if_ath.c (modified) (5 diffs)
- madwifi/trunk/ath/if_ath_hal_extensions.c (modified) (1 diff)
- madwifi/trunk/ath/if_ath_hal_extensions.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
madwifi/trunk/ath/if_ath.c
r3809 r3867 5389 5389 u_int32_t intval, nexttbtt = 0; 5390 5390 int reset_tsf = 0; 5391 unsigned long irqstate; 5391 5392 5392 5393 if (vap == NULL) … … 5394 5395 5395 5396 ni = vap->iv_bss; 5397 5398 /* TSF calculation is timing critical - we don't want to be interrupted here */ 5399 local_irq_save(irqstate); 5396 5400 5397 5401 hw_tsf = ath_hal_gettsf64(ah); … … 5570 5574 #endif 5571 5575 sc->sc_nexttbtt = nexttbtt; 5576 5577 /* stop beacons before reconfiguring the timers to avoid race 5578 * conditions. ath_hal_beaconinit will start them again */ 5579 ath_hw_beacon_stop(sc); 5580 5572 5581 ath_hal_beaconinit(ah, nexttbtt, intval); 5573 5582 if (intval & HAL_BEACON_RESET_TSF) { … … 5576 5585 sc->sc_bmisscount = 0; 5577 5586 ath_hal_intrset(ah, sc->sc_imask); 5587 5588 if (ath_hw_check_atim(sc, 1, intval & HAL_BEACON_PERIOD)) { 5589 DPRINTF(sc, ATH_DEBUG_BEACON, 5590 "fixed atim window after beacon init\n"); 5591 } 5578 5592 } 5579 5593 5580 5594 ath_beacon_config_debug: 5595 5596 local_irq_restore(irqstate); 5597 5581 5598 /* We print all debug messages here, in order to preserve the 5582 5599 * time critical aspect of this function. */ … … 6328 6345 "Updated beacon timers\n"); 6329 6346 } 6347 6348 if (IEEE80211_ADDR_EQ(ni->ni_bssid, vap->iv_bss->ni_bssid)) { 6349 if (ath_hw_check_atim(sc, 1, vap->iv_bss->ni_intval)) { 6350 DPRINTF(sc, ATH_DEBUG_BEACON, 6351 "fixed atim window after beacon recv\n"); 6352 } 6353 } 6354 6330 6355 /* NB: Fall Through */ 6331 6356 case IEEE80211_FC0_SUBTYPE_PROBE_RESP: madwifi/trunk/ath/if_ath_hal_extensions.c
r3658 r3867 162 162 return name; 163 163 } 164 165 166 void 167 ath_hw_beacon_stop(struct ath_softc *sc) { 168 HAL_BEACON_TIMERS btimers; 169 170 btimers.bt_intval = 0; 171 btimers.bt_nexttbtt = 0; 172 btimers.bt_nextdba = 0xffffffff; 173 btimers.bt_nextswba = 0xffffffff; 174 btimers.bt_nextatim = 0; 175 176 ath_hal_setbeacontimers(sc->sc_ah, &btimers); 177 } 178 179 180 /* 181 * IBSS mode: check the ATIM window size and fix it if necessary. 182 * 183 * the need for this function arises from the problem that due to unlucky timing 184 * of beacon timer configuration (which we try to avoid) and due to unlucky 185 * timing of local TSF updates (triggered by the reception of a beacon with the 186 * same BSSID - something we can't avoid) the beacon timers can be up updated 187 * seperately, leaving one of them in the past, not beeing updated until the 188 * timers wrap around. due to the fact that the beacon interval does not fit 189 * into the timer period (16 bit) a whole number of times the size of the ATIM 190 * window can get bigger than desired. 191 * 192 * usually we have an ATIM window size of 1 but this function is written to 193 * handle other window sizes as well. 194 */ 195 int 196 ath_hw_check_atim(struct ath_softc *sc, int window, int intval) 197 { 198 struct ath_hal *ah = sc->sc_ah; 199 unsigned int nbtt, atim, is5210 = 0; 200 201 if (ATH_SREV_FROM_AH(ah) >= AR5K_SREV_VER_AR5416) 202 return 0; /* AR5416+ doesn't do ATIM in HW */ 203 204 if (ATH_SREV_FROM_AH(ah) == AR5K_SREV_VER_AR5210) { 205 nbtt = OS_REG_READ(ah, AR5K_TIMER0_5210); 206 atim = OS_REG_READ(ah, AR5K_TIMER3_5210); 207 is5210 = 1; 208 } 209 else { 210 nbtt = OS_REG_READ(ah, AR5K_TIMER0_5211); 211 atim = OS_REG_READ(ah, AR5K_TIMER3_5211); 212 } 213 214 /* 215 * check if the ATIM window is still correct: 216 * 1.) usually ATIM should be NBTT + window 217 * 2.) nbtt already updated 218 * 3.) nbtt already updated and has wrapped around 219 * 4.) atim has wrapped around 220 */ 221 if ((atim - nbtt != window) && /* 1.) */ 222 (nbtt - atim != intval - window) && /* 2.) */ 223 ((nbtt | 0x10000) - atim != intval - window) && /* 3.) */ 224 ((atim | 0x10000) - nbtt != window)) { /* 4.) */ 225 if (is5210) 226 OS_REG_WRITE(ah, AR5K_TIMER3_5210, nbtt + window ); 227 else 228 OS_REG_WRITE(ah, AR5K_TIMER3_5211, nbtt + window ); 229 return atim - nbtt; 230 } 231 return 0; 232 } madwifi/trunk/ath/if_ath_hal_extensions.h
r3710 r3867 177 177 #define AR5K_STA_ID1_BASE_RATE_11B 0x02000000 /* Use 11b base rate (for ACK/CTS ?) [5211+] */ 178 178 179 /* 180 * PCU beacon control register 181 */ 182 #define AR5K_BEACON_5210 0x8024 183 #define AR5K_BEACON_5211 0x8020 184 185 /* 186 * Next beacon time register 187 */ 188 #define AR5K_TIMER0_5210 0x802c 189 #define AR5K_TIMER0_5211 0x8028 190 /* 191 * Next DMA beacon alert register 192 */ 193 #define AR5K_TIMER1_5210 0x8030 194 #define AR5K_TIMER1_5211 0x802c 195 196 /* 197 * Next software beacon alert register 198 */ 199 #define AR5K_TIMER2_5210 0x8034 200 #define AR5K_TIMER2_5211 0x8030 201 202 /* 203 * Next ATIM window time register 204 */ 205 #define AR5K_TIMER3_5210 0x8038 206 #define AR5K_TIMER3_5211 0x8034 207 179 208 180 209 enum ath5k_srev_type { … … 242 271 int ar_device(int devid); 243 272 const char * ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val); 273 void ath_hw_beacon_stop(struct ath_softc *sc); 274 int ath_hw_check_atim(struct ath_softc *sc, int window, int intval); 244 275 245 276 static inline unsigned long field_width(unsigned long mask, unsigned long shift)
