1 /* 2 * Copyright (c) 2013 Qualcomm Atheros, Inc. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 * PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 #include "opt_ah.h" 18 19 #include "ah.h" 20 #include "ah_internal.h" 21 22 #include "ar9300/ar9300.h" 23 #include "ar9300/ar9300reg.h" 24 25 #define TU_TO_USEC(_tu) ((_tu) << 10) 26 #define ONE_EIGHTH_TU_TO_USEC(_tu8) ((_tu8) << 7) 27 28 extern u_int32_t ar9300_num_tx_pending(struct ath_hal *ah, u_int q); 29 30 /* 31 * Initializes all of the hardware registers used to 32 * send beacons. Note that for station operation the 33 * driver calls ar9300_set_sta_beacon_timers instead. 34 */ 35 void 36 ar9300_beacon_init(struct ath_hal *ah, 37 u_int32_t next_beacon, u_int32_t beacon_period, 38 u_int32_t beacon_period_fraction, HAL_OPMODE opmode) 39 { 40 u_int32_t beacon_period_usec; 41 42 HALASSERT(opmode == HAL_M_IBSS || opmode == HAL_M_HOSTAP); 43 if (opmode == HAL_M_IBSS) { 44 OS_REG_SET_BIT(ah, AR_TXCFG, AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY); 45 } 46 OS_REG_WRITE(ah, AR_NEXT_TBTT_TIMER, ONE_EIGHTH_TU_TO_USEC(next_beacon)); 47 OS_REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 48 (ONE_EIGHTH_TU_TO_USEC(next_beacon) - 49 ah->ah_config.ah_dma_beacon_response_time)); 50 OS_REG_WRITE(ah, AR_NEXT_SWBA, 51 (ONE_EIGHTH_TU_TO_USEC(next_beacon) - 52 ah->ah_config.ah_sw_beacon_response_time)); 53 54 beacon_period_usec = 55 ONE_EIGHTH_TU_TO_USEC(beacon_period & HAL_BEACON_PERIOD_TU8); 56 57 /* Add the fraction adjustment lost due to unit conversions. */ 58 beacon_period_usec += beacon_period_fraction; 59 60 HALDEBUG(ah, HAL_DEBUG_BEACON, 61 "%s: next_beacon=0x%08x, beacon_period=%d, opmode=%d, beacon_period_usec=%d\n", 62 __func__, next_beacon, beacon_period, opmode, beacon_period_usec); 63 64 OS_REG_WRITE(ah, AR_BEACON_PERIOD, beacon_period_usec); 65 OS_REG_WRITE(ah, AR_DMA_BEACON_PERIOD, beacon_period_usec); 66 OS_REG_WRITE(ah, AR_SWBA_PERIOD, beacon_period_usec); 67 68 /* reset TSF if required */ 69 if (beacon_period & HAL_BEACON_RESET_TSF) { 70 ar9300_reset_tsf(ah); 71 } 72 73 /* enable timers */ 74 OS_REG_SET_BIT(ah, AR_TIMER_MODE, 75 AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN); 76 } 77 78 /* 79 * Set all the beacon related bits on the h/w for stations 80 * i.e. initializes the corresponding h/w timers; 81 */ 82 void 83 ar9300_set_sta_beacon_timers(struct ath_hal *ah, const HAL_BEACON_STATE *bs) 84 { 85 u_int32_t next_tbtt, beaconintval, dtimperiod, beacontimeout; 86 HAL_CAPABILITIES *p_cap = &AH_PRIVATE(ah)->ah_caps; 87 88 HALASSERT(bs->bs_intval != 0); 89 90 /* no cfp setting since h/w automatically takes care */ 91 OS_REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bs->bs_nexttbtt)); 92 93 /* 94 * Start the beacon timers by setting the BEACON register 95 * to the beacon interval; no need to write tim offset since 96 * h/w parses IEs. 97 */ 98 OS_REG_WRITE(ah, AR_BEACON_PERIOD, 99 TU_TO_USEC(bs->bs_intval & HAL_BEACON_PERIOD)); 100 OS_REG_WRITE(ah, AR_DMA_BEACON_PERIOD, 101 TU_TO_USEC(bs->bs_intval & HAL_BEACON_PERIOD)); 102 /* 103 * Configure the BMISS interrupt. Note that we 104 * assume the caller blocks interrupts while enabling 105 * the threshold. 106 */ 107 HALASSERT(bs->bs_bmissthreshold <= 108 (AR_RSSI_THR_BM_THR >> AR_RSSI_THR_BM_THR_S)); 109 OS_REG_RMW_FIELD(ah, AR_RSSI_THR, 110 AR_RSSI_THR_BM_THR, bs->bs_bmissthreshold); 111 112 /* 113 * Program the sleep registers to correlate with the beacon setup. 114 */ 115 116 /* 117 * Current implementation assumes sw processing of beacons - 118 * assuming an interrupt is generated every beacon which 119 * causes the hardware to become awake until the sw tells 120 * it to go to sleep again; beacon timeout is to allow for 121 * beacon jitter; cab timeout is max time to wait for cab 122 * after seeing the last DTIM or MORE CAB bit 123 */ 124 #define CAB_TIMEOUT_VAL 10 /* in TU */ 125 #define BEACON_TIMEOUT_VAL 10 /* in TU */ 126 #define MIN_BEACON_TIMEOUT_VAL 1 /* in 1/8 TU */ 127 #define SLEEP_SLOP 3 /* in TU */ 128 129 /* 130 * For max powersave mode we may want to sleep for longer than a 131 * beacon period and not want to receive all beacons; modify the 132 * timers accordingly; make sure to align the next TIM to the 133 * next DTIM if we decide to wake for DTIMs only 134 */ 135 beaconintval = bs->bs_intval & HAL_BEACON_PERIOD; 136 HALASSERT(beaconintval != 0); 137 if (bs->bs_sleepduration > beaconintval) { 138 HALASSERT(roundup(bs->bs_sleepduration, beaconintval) == 139 bs->bs_sleepduration); 140 beaconintval = bs->bs_sleepduration; 141 } 142 dtimperiod = bs->bs_dtimperiod; 143 if (bs->bs_sleepduration > dtimperiod) { 144 HALASSERT(dtimperiod == 0 || 145 roundup(bs->bs_sleepduration, dtimperiod) == 146 bs->bs_sleepduration); 147 dtimperiod = bs->bs_sleepduration; 148 } 149 HALASSERT(beaconintval <= dtimperiod); 150 if (beaconintval == dtimperiod) { 151 next_tbtt = bs->bs_nextdtim; 152 } else { 153 next_tbtt = bs->bs_nexttbtt; 154 } 155 156 HALDEBUG(ah, HAL_DEBUG_BEACON, 157 "%s: next DTIM %d\n", __func__, bs->bs_nextdtim); 158 HALDEBUG(ah, HAL_DEBUG_BEACON, 159 "%s: next beacon %d\n", __func__, next_tbtt); 160 HALDEBUG(ah, HAL_DEBUG_BEACON, 161 "%s: beacon period %d\n", __func__, beaconintval); 162 HALDEBUG(ah, HAL_DEBUG_BEACON, 163 "%s: DTIM period %d\n", __func__, dtimperiod); 164 165 OS_REG_WRITE(ah, AR_NEXT_DTIM, TU_TO_USEC(bs->bs_nextdtim - SLEEP_SLOP)); 166 OS_REG_WRITE(ah, AR_NEXT_TIM, TU_TO_USEC(next_tbtt - SLEEP_SLOP)); 167 168 /* cab timeout is now in 1/8 TU */ 169 OS_REG_WRITE(ah, AR_SLEEP1, 170 SM((CAB_TIMEOUT_VAL << 3), AR_SLEEP1_CAB_TIMEOUT) 171 | AR_SLEEP1_ASSUME_DTIM); 172 173 /* beacon timeout is now in 1/8 TU */ 174 if (p_cap->halAutoSleepSupport) { 175 beacontimeout = (BEACON_TIMEOUT_VAL << 3); 176 } else { 177 /* 178 * Use a very small value to make sure the timeout occurs before 179 * the TBTT. In this case the chip will not go back to sleep 180 * automatically, instead it will wait for the SW to explicitly 181 * set it to that mode. 182 */ 183 beacontimeout = MIN_BEACON_TIMEOUT_VAL; 184 } 185 186 OS_REG_WRITE(ah, AR_SLEEP2, 187 SM(beacontimeout, AR_SLEEP2_BEACON_TIMEOUT)); 188 189 OS_REG_WRITE(ah, AR_TIM_PERIOD, TU_TO_USEC(beaconintval)); 190 OS_REG_WRITE(ah, AR_DTIM_PERIOD, TU_TO_USEC(dtimperiod)); 191 192 /* clear HOST AP related timers first */ 193 OS_REG_CLR_BIT(ah, AR_TIMER_MODE, (AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN)); 194 195 OS_REG_SET_BIT(ah, AR_TIMER_MODE, AR_TBTT_TIMER_EN | AR_TIM_TIMER_EN 196 | AR_DTIM_TIMER_EN); 197 198 /* TSF out of range threshold */ 199 OS_REG_WRITE(ah, AR_TSFOOR_THRESHOLD, bs->bs_tsfoor_threshold); 200 201 #undef CAB_TIMEOUT_VAL 202 #undef BEACON_TIMEOUT_VAL 203 #undef SLEEP_SLOP 204 } 205