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
ar9300_beacon_init(struct ath_hal * ah,u_int32_t next_beacon,u_int32_t beacon_period,HAL_OPMODE opmode)36 ar9300_beacon_init(struct ath_hal *ah,
37 u_int32_t next_beacon, u_int32_t beacon_period, HAL_OPMODE opmode)
38 {
39 u_int32_t beacon_period_usec;
40
41 HALASSERT(opmode == HAL_M_IBSS || opmode == HAL_M_HOSTAP);
42 if (opmode == HAL_M_IBSS) {
43 OS_REG_SET_BIT(ah, AR_TXCFG, AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY);
44 }
45 OS_REG_WRITE(ah, AR_NEXT_TBTT_TIMER, ONE_EIGHTH_TU_TO_USEC(next_beacon));
46 OS_REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT,
47 (ONE_EIGHTH_TU_TO_USEC(next_beacon) -
48 ah->ah_config.ah_dma_beacon_response_time));
49 OS_REG_WRITE(ah, AR_NEXT_SWBA,
50 (ONE_EIGHTH_TU_TO_USEC(next_beacon) -
51 ah->ah_config.ah_sw_beacon_response_time));
52
53 beacon_period_usec =
54 ONE_EIGHTH_TU_TO_USEC(beacon_period & HAL_BEACON_PERIOD_TU8);
55 OS_REG_WRITE(ah, AR_BEACON_PERIOD, beacon_period_usec);
56 OS_REG_WRITE(ah, AR_DMA_BEACON_PERIOD, beacon_period_usec);
57 OS_REG_WRITE(ah, AR_SWBA_PERIOD, beacon_period_usec);
58
59 /* reset TSF if required */
60 if (beacon_period & HAL_BEACON_RESET_TSF) {
61 ar9300_reset_tsf(ah);
62 }
63
64 /* enable timers */
65 OS_REG_SET_BIT(ah, AR_TIMER_MODE,
66 AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN);
67 }
68
69 /*
70 * Set all the beacon related bits on the h/w for stations
71 * i.e. initializes the corresponding h/w timers;
72 */
73 void
ar9300_set_sta_beacon_timers(struct ath_hal * ah,const HAL_BEACON_STATE * bs)74 ar9300_set_sta_beacon_timers(struct ath_hal *ah, const HAL_BEACON_STATE *bs)
75 {
76 u_int32_t next_tbtt, beaconintval, dtimperiod, beacontimeout;
77 HAL_CAPABILITIES *p_cap = &AH_PRIVATE(ah)->ah_caps;
78
79 HALASSERT(bs->bs_intval != 0);
80
81 /* no cfp setting since h/w automatically takes care */
82 OS_REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bs->bs_nexttbtt));
83
84 /*
85 * Start the beacon timers by setting the BEACON register
86 * to the beacon interval; no need to write tim offset since
87 * h/w parses IEs.
88 */
89 OS_REG_WRITE(ah, AR_BEACON_PERIOD,
90 TU_TO_USEC(bs->bs_intval & HAL_BEACON_PERIOD));
91 OS_REG_WRITE(ah, AR_DMA_BEACON_PERIOD,
92 TU_TO_USEC(bs->bs_intval & HAL_BEACON_PERIOD));
93 /*
94 * Configure the BMISS interrupt. Note that we
95 * assume the caller blocks interrupts while enabling
96 * the threshold.
97 */
98 HALASSERT(bs->bs_bmissthreshold <=
99 (AR_RSSI_THR_BM_THR >> AR_RSSI_THR_BM_THR_S));
100 OS_REG_RMW_FIELD(ah, AR_RSSI_THR,
101 AR_RSSI_THR_BM_THR, bs->bs_bmissthreshold);
102
103 /*
104 * Program the sleep registers to correlate with the beacon setup.
105 */
106
107 /*
108 * Current implementation assumes sw processing of beacons -
109 * assuming an interrupt is generated every beacon which
110 * causes the hardware to become awake until the sw tells
111 * it to go to sleep again; beacon timeout is to allow for
112 * beacon jitter; cab timeout is max time to wait for cab
113 * after seeing the last DTIM or MORE CAB bit
114 */
115 #define CAB_TIMEOUT_VAL 10 /* in TU */
116 #define BEACON_TIMEOUT_VAL 10 /* in TU */
117 #define MIN_BEACON_TIMEOUT_VAL 1 /* in 1/8 TU */
118 #define SLEEP_SLOP 3 /* in TU */
119
120 /*
121 * For max powersave mode we may want to sleep for longer than a
122 * beacon period and not want to receive all beacons; modify the
123 * timers accordingly; make sure to align the next TIM to the
124 * next DTIM if we decide to wake for DTIMs only
125 */
126 beaconintval = bs->bs_intval & HAL_BEACON_PERIOD;
127 HALASSERT(beaconintval != 0);
128 if (bs->bs_sleepduration > beaconintval) {
129 HALASSERT(roundup(bs->bs_sleepduration, beaconintval) ==
130 bs->bs_sleepduration);
131 beaconintval = bs->bs_sleepduration;
132 }
133 dtimperiod = bs->bs_dtimperiod;
134 if (bs->bs_sleepduration > dtimperiod) {
135 HALASSERT(dtimperiod == 0 ||
136 roundup(bs->bs_sleepduration, dtimperiod) ==
137 bs->bs_sleepduration);
138 dtimperiod = bs->bs_sleepduration;
139 }
140 HALASSERT(beaconintval <= dtimperiod);
141 if (beaconintval == dtimperiod) {
142 next_tbtt = bs->bs_nextdtim;
143 } else {
144 next_tbtt = bs->bs_nexttbtt;
145 }
146
147 HALDEBUG(ah, HAL_DEBUG_BEACON,
148 "%s: next DTIM %d\n", __func__, bs->bs_nextdtim);
149 HALDEBUG(ah, HAL_DEBUG_BEACON,
150 "%s: next beacon %d\n", __func__, next_tbtt);
151 HALDEBUG(ah, HAL_DEBUG_BEACON,
152 "%s: beacon period %d\n", __func__, beaconintval);
153 HALDEBUG(ah, HAL_DEBUG_BEACON,
154 "%s: DTIM period %d\n", __func__, dtimperiod);
155
156 OS_REG_WRITE(ah, AR_NEXT_DTIM, TU_TO_USEC(bs->bs_nextdtim - SLEEP_SLOP));
157 OS_REG_WRITE(ah, AR_NEXT_TIM, TU_TO_USEC(next_tbtt - SLEEP_SLOP));
158
159 /* cab timeout is now in 1/8 TU */
160 OS_REG_WRITE(ah, AR_SLEEP1,
161 SM((CAB_TIMEOUT_VAL << 3), AR_SLEEP1_CAB_TIMEOUT)
162 | AR_SLEEP1_ASSUME_DTIM);
163
164 /* beacon timeout is now in 1/8 TU */
165 if (p_cap->halAutoSleepSupport) {
166 beacontimeout = (BEACON_TIMEOUT_VAL << 3);
167 } else {
168 /*
169 * Use a very small value to make sure the timeout occurs before
170 * the TBTT. In this case the chip will not go back to sleep
171 * automatically, instead it will wait for the SW to explicitly
172 * set it to that mode.
173 */
174 beacontimeout = MIN_BEACON_TIMEOUT_VAL;
175 }
176
177 OS_REG_WRITE(ah, AR_SLEEP2,
178 SM(beacontimeout, AR_SLEEP2_BEACON_TIMEOUT));
179
180 OS_REG_WRITE(ah, AR_TIM_PERIOD, TU_TO_USEC(beaconintval));
181 OS_REG_WRITE(ah, AR_DTIM_PERIOD, TU_TO_USEC(dtimperiod));
182
183 /* clear HOST AP related timers first */
184 OS_REG_CLR_BIT(ah, AR_TIMER_MODE, (AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN));
185
186 OS_REG_SET_BIT(ah, AR_TIMER_MODE, AR_TBTT_TIMER_EN | AR_TIM_TIMER_EN
187 | AR_DTIM_TIMER_EN);
188
189 /* TSF out of range threshold */
190 OS_REG_WRITE(ah, AR_TSFOOR_THRESHOLD, bs->bs_tsfoor_threshold);
191
192 #undef CAB_TIMEOUT_VAL
193 #undef BEACON_TIMEOUT_VAL
194 #undef SLEEP_SLOP
195 }
196