Line data Source code
1 : /* $OpenBSD: ar5212.c,v 1.59 2018/02/03 17:17:31 stsp Exp $ */
2 :
3 : /*
4 : * Copyright (c) 2004, 2005, 2006, 2007 Reyk Floeter <reyk@openbsd.org>
5 : *
6 : * Permission to use, copy, modify, and distribute this software for any
7 : * purpose with or without fee is hereby granted, provided that the above
8 : * copyright notice and this permission notice appear in all copies.
9 : *
10 : * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 : * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 : * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 : * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 : * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 : * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 : * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 : */
18 :
19 : /*
20 : * HAL interface for the Atheros AR5001 Wireless LAN chipset
21 : * (AR5212 + AR5111/AR5112).
22 : */
23 :
24 : #include <dev/ic/ar5xxx.h>
25 : #include <dev/ic/ar5212reg.h>
26 : #include <dev/ic/ar5212var.h>
27 :
28 : HAL_BOOL ar5k_ar5212_nic_reset(struct ath_hal *, u_int32_t);
29 : HAL_BOOL ar5k_ar5212_nic_wakeup(struct ath_hal *, u_int16_t);
30 : u_int16_t ar5k_ar5212_radio_revision(struct ath_hal *, HAL_CHIP);
31 : void ar5k_ar5212_fill(struct ath_hal *);
32 : HAL_BOOL ar5k_ar5212_txpower(struct ath_hal *, HAL_CHANNEL *, u_int);
33 : HAL_BOOL ar5k_ar5212_warm_reset(struct ath_hal *);
34 :
35 : /*
36 : * Initial register setting for the AR5212
37 : */
38 : static const struct ar5k_ini ar5212_ini[] = AR5K_AR5212_INI;
39 : static const struct ar5k_mode ar5212_mode[] = AR5K_AR5212_MODE;
40 : static const struct ar5k_mode ar5212_ar5111_mode[] = AR5K_AR5212_AR5111_MODE;
41 : static const struct ar5k_mode ar5212_ar5112_mode[] = AR5K_AR5212_AR5112_MODE;
42 : static const struct ar5k_mode ar5413_mode[] = AR5K_AR5413_MODE;
43 : static const struct ar5k_mode ar2413_mode[] = AR5K_AR2413_MODE;
44 : static const struct ar5k_mode ar2425_mode[] = AR5K_AR2425_MODE;
45 : static const struct ar5k_ini ar5111_bbgain[] = AR5K_AR5111_INI_BBGAIN;
46 : static const struct ar5k_ini ar5112_bbgain[] = AR5K_AR5112_INI_BBGAIN;
47 : static const struct ar5k_ini ar5212_pcie[] = AR5K_AR5212_PCIE;
48 :
49 : AR5K_HAL_FUNCTIONS(extern, ar5k_ar5212,);
50 :
51 : void
52 0 : ar5k_ar5212_fill(struct ath_hal *hal)
53 : {
54 0 : hal->ah_magic = AR5K_AR5212_MAGIC;
55 :
56 : /*
57 : * Init/Exit functions
58 : */
59 0 : AR5K_HAL_FUNCTION(hal, ar5212, get_rate_table);
60 0 : AR5K_HAL_FUNCTION(hal, ar5212, detach);
61 :
62 : /*
63 : * Reset functions
64 : */
65 0 : AR5K_HAL_FUNCTION(hal, ar5212, reset);
66 0 : AR5K_HAL_FUNCTION(hal, ar5212, set_opmode);
67 0 : AR5K_HAL_FUNCTION(hal, ar5212, calibrate);
68 :
69 : /*
70 : * TX functions
71 : */
72 0 : AR5K_HAL_FUNCTION(hal, ar5212, update_tx_triglevel);
73 0 : AR5K_HAL_FUNCTION(hal, ar5212, setup_tx_queue);
74 0 : AR5K_HAL_FUNCTION(hal, ar5212, setup_tx_queueprops);
75 0 : AR5K_HAL_FUNCTION(hal, ar5212, release_tx_queue);
76 0 : AR5K_HAL_FUNCTION(hal, ar5212, reset_tx_queue);
77 0 : AR5K_HAL_FUNCTION(hal, ar5212, get_tx_buf);
78 0 : AR5K_HAL_FUNCTION(hal, ar5212, put_tx_buf);
79 0 : AR5K_HAL_FUNCTION(hal, ar5212, tx_start);
80 0 : AR5K_HAL_FUNCTION(hal, ar5212, stop_tx_dma);
81 0 : AR5K_HAL_FUNCTION(hal, ar5212, setup_tx_desc);
82 0 : AR5K_HAL_FUNCTION(hal, ar5212, setup_xtx_desc);
83 0 : AR5K_HAL_FUNCTION(hal, ar5212, fill_tx_desc);
84 0 : AR5K_HAL_FUNCTION(hal, ar5212, proc_tx_desc);
85 0 : AR5K_HAL_FUNCTION(hal, ar5212, has_veol);
86 :
87 : /*
88 : * RX functions
89 : */
90 0 : AR5K_HAL_FUNCTION(hal, ar5212, get_rx_buf);
91 0 : AR5K_HAL_FUNCTION(hal, ar5212, put_rx_buf);
92 0 : AR5K_HAL_FUNCTION(hal, ar5212, start_rx);
93 0 : AR5K_HAL_FUNCTION(hal, ar5212, stop_rx_dma);
94 0 : AR5K_HAL_FUNCTION(hal, ar5212, start_rx_pcu);
95 0 : AR5K_HAL_FUNCTION(hal, ar5212, stop_pcu_recv);
96 0 : AR5K_HAL_FUNCTION(hal, ar5212, set_mcast_filter);
97 0 : AR5K_HAL_FUNCTION(hal, ar5212, set_mcast_filterindex);
98 0 : AR5K_HAL_FUNCTION(hal, ar5212, clear_mcast_filter_idx);
99 0 : AR5K_HAL_FUNCTION(hal, ar5212, get_rx_filter);
100 0 : AR5K_HAL_FUNCTION(hal, ar5212, set_rx_filter);
101 0 : AR5K_HAL_FUNCTION(hal, ar5212, setup_rx_desc);
102 0 : AR5K_HAL_FUNCTION(hal, ar5212, proc_rx_desc);
103 0 : AR5K_HAL_FUNCTION(hal, ar5212, set_rx_signal);
104 :
105 : /*
106 : * Misc functions
107 : */
108 0 : AR5K_HAL_FUNCTION(hal, ar5212, dump_state);
109 0 : AR5K_HAL_FUNCTION(hal, ar5212, get_diag_state);
110 0 : AR5K_HAL_FUNCTION(hal, ar5212, get_lladdr);
111 0 : AR5K_HAL_FUNCTION(hal, ar5212, set_lladdr);
112 0 : AR5K_HAL_FUNCTION(hal, ar5212, set_regdomain);
113 0 : AR5K_HAL_FUNCTION(hal, ar5212, set_ledstate);
114 0 : AR5K_HAL_FUNCTION(hal, ar5212, set_associd);
115 0 : AR5K_HAL_FUNCTION(hal, ar5212, set_gpio_input);
116 0 : AR5K_HAL_FUNCTION(hal, ar5212, set_gpio_output);
117 0 : AR5K_HAL_FUNCTION(hal, ar5212, get_gpio);
118 0 : AR5K_HAL_FUNCTION(hal, ar5212, set_gpio);
119 0 : AR5K_HAL_FUNCTION(hal, ar5212, set_gpio_intr);
120 0 : AR5K_HAL_FUNCTION(hal, ar5212, get_tsf32);
121 0 : AR5K_HAL_FUNCTION(hal, ar5212, get_tsf64);
122 0 : AR5K_HAL_FUNCTION(hal, ar5212, reset_tsf);
123 0 : AR5K_HAL_FUNCTION(hal, ar5212, get_regdomain);
124 0 : AR5K_HAL_FUNCTION(hal, ar5212, detect_card_present);
125 0 : AR5K_HAL_FUNCTION(hal, ar5212, update_mib_counters);
126 0 : AR5K_HAL_FUNCTION(hal, ar5212, get_rf_gain);
127 0 : AR5K_HAL_FUNCTION(hal, ar5212, set_slot_time);
128 0 : AR5K_HAL_FUNCTION(hal, ar5212, get_slot_time);
129 0 : AR5K_HAL_FUNCTION(hal, ar5212, set_ack_timeout);
130 0 : AR5K_HAL_FUNCTION(hal, ar5212, get_ack_timeout);
131 0 : AR5K_HAL_FUNCTION(hal, ar5212, set_cts_timeout);
132 0 : AR5K_HAL_FUNCTION(hal, ar5212, get_cts_timeout);
133 :
134 : /*
135 : * Key table (WEP) functions
136 : */
137 0 : AR5K_HAL_FUNCTION(hal, ar5212, is_cipher_supported);
138 0 : AR5K_HAL_FUNCTION(hal, ar5212, get_keycache_size);
139 0 : AR5K_HAL_FUNCTION(hal, ar5212, reset_key);
140 0 : AR5K_HAL_FUNCTION(hal, ar5212, is_key_valid);
141 0 : AR5K_HAL_FUNCTION(hal, ar5212, set_key);
142 0 : AR5K_HAL_FUNCTION(hal, ar5212, set_key_lladdr);
143 0 : AR5K_HAL_FUNCTION(hal, ar5212, softcrypto);
144 :
145 : /*
146 : * Power management functions
147 : */
148 0 : AR5K_HAL_FUNCTION(hal, ar5212, set_power);
149 0 : AR5K_HAL_FUNCTION(hal, ar5212, get_power_mode);
150 0 : AR5K_HAL_FUNCTION(hal, ar5212, query_pspoll_support);
151 0 : AR5K_HAL_FUNCTION(hal, ar5212, init_pspoll);
152 0 : AR5K_HAL_FUNCTION(hal, ar5212, enable_pspoll);
153 0 : AR5K_HAL_FUNCTION(hal, ar5212, disable_pspoll);
154 :
155 : /*
156 : * Beacon functions
157 : */
158 0 : AR5K_HAL_FUNCTION(hal, ar5212, init_beacon);
159 0 : AR5K_HAL_FUNCTION(hal, ar5212, set_beacon_timers);
160 0 : AR5K_HAL_FUNCTION(hal, ar5212, reset_beacon);
161 0 : AR5K_HAL_FUNCTION(hal, ar5212, wait_for_beacon);
162 :
163 : /*
164 : * Interrupt functions
165 : */
166 0 : AR5K_HAL_FUNCTION(hal, ar5212, is_intr_pending);
167 0 : AR5K_HAL_FUNCTION(hal, ar5212, get_isr);
168 0 : AR5K_HAL_FUNCTION(hal, ar5212, get_intr);
169 0 : AR5K_HAL_FUNCTION(hal, ar5212, set_intr);
170 :
171 : /*
172 : * Chipset functions (ar5k-specific, non-HAL)
173 : */
174 0 : AR5K_HAL_FUNCTION(hal, ar5212, get_capabilities);
175 0 : AR5K_HAL_FUNCTION(hal, ar5212, radar_alert);
176 :
177 : /*
178 : * EEPROM access
179 : */
180 0 : AR5K_HAL_FUNCTION(hal, ar5212, eeprom_is_busy);
181 0 : AR5K_HAL_FUNCTION(hal, ar5212, eeprom_read);
182 0 : AR5K_HAL_FUNCTION(hal, ar5212, eeprom_write);
183 :
184 : /*
185 : * Unused functions or functions not implemented
186 : */
187 0 : AR5K_HAL_FUNCTION(hal, ar5212, set_bssid_mask);
188 0 : AR5K_HAL_FUNCTION(hal, ar5212, get_tx_queueprops);
189 0 : AR5K_HAL_FUNCTION(hal, ar5212, num_tx_pending);
190 0 : AR5K_HAL_FUNCTION(hal, ar5212, phy_disable);
191 0 : AR5K_HAL_FUNCTION(hal, ar5212, set_txpower_limit);
192 0 : AR5K_HAL_FUNCTION(hal, ar5212, set_def_antenna);
193 0 : AR5K_HAL_FUNCTION(hal, ar5212, get_def_antenna);
194 : #ifdef notyet
195 : AR5K_HAL_FUNCTION(hal, ar5212, set_capability);
196 : AR5K_HAL_FUNCTION(hal, ar5212, proc_mib_event);
197 : AR5K_HAL_FUNCTION(hal, ar5212, get_tx_inter_queue);
198 : #endif
199 0 : }
200 :
201 : struct ath_hal *
202 0 : ar5k_ar5212_attach(u_int16_t device, void *sc, bus_space_tag_t st,
203 : bus_space_handle_t sh, int *status)
204 : {
205 0 : struct ath_hal *hal = (struct ath_hal*) sc;
206 0 : u_int8_t mac[IEEE80211_ADDR_LEN];
207 : u_int32_t srev;
208 :
209 0 : ar5k_ar5212_fill(hal);
210 :
211 : /* Bring device out of sleep and reset its units */
212 0 : if (ar5k_ar5212_nic_wakeup(hal, AR5K_INIT_MODE) != AH_TRUE)
213 0 : return (NULL);
214 :
215 : /* Get MAC, PHY and RADIO revisions */
216 0 : srev = AR5K_REG_READ(AR5K_AR5212_SREV);
217 0 : hal->ah_mac_srev = srev;
218 0 : hal->ah_mac_version = AR5K_REG_MS(srev, AR5K_AR5212_SREV_VER);
219 0 : hal->ah_mac_revision = AR5K_REG_MS(srev, AR5K_AR5212_SREV_REV);
220 0 : hal->ah_phy_revision = AR5K_REG_READ(AR5K_AR5212_PHY_CHIP_ID) &
221 : 0x00ffffffff;
222 0 : hal->ah_radio_5ghz_revision =
223 0 : ar5k_ar5212_radio_revision(hal, HAL_CHIP_5GHZ);
224 0 : hal->ah_radio_2ghz_revision =
225 0 : ar5k_ar5212_radio_revision(hal, HAL_CHIP_2GHZ);
226 :
227 : /* Single chip radio */
228 0 : if (hal->ah_radio_2ghz_revision == hal->ah_radio_5ghz_revision)
229 0 : hal->ah_radio_2ghz_revision = 0;
230 :
231 : /* Identify the chipset (this has to be done in an early step) */
232 0 : hal->ah_version = AR5K_AR5212;
233 0 : if (device == AR5K_VERSION_DEV) {
234 0 : hal->ah_radio = AR5K_AR5413;
235 0 : hal->ah_phy_spending = AR5K_AR5212_PHY_SPENDING_AR5424;
236 0 : hal->ah_radio_5ghz_revision = hal->ah_radio_2ghz_revision =
237 : AR5K_SREV_VER_AR5413;
238 0 : } else if (srev == AR5K_SREV_VER_AR2425) {
239 0 : hal->ah_radio = AR5K_AR2425;
240 0 : hal->ah_phy_spending = AR5K_AR5212_PHY_SPENDING_AR5112;
241 0 : hal->ah_radio_5ghz_revision = AR5K_SREV_RAD_SC2;
242 0 : } else if (hal->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112) {
243 0 : hal->ah_radio = AR5K_AR5111;
244 0 : hal->ah_phy_spending = AR5K_AR5212_PHY_SPENDING_AR5111;
245 0 : } else if (hal->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC0) {
246 0 : hal->ah_radio = AR5K_AR5112;
247 0 : if (hal->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112A)
248 0 : hal->ah_phy_spending = AR5K_AR5212_PHY_SPENDING_AR5112;
249 : else
250 0 : hal->ah_phy_spending = AR5K_AR5212_PHY_SPENDING_AR5112A;
251 0 : } else if (hal->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC1) {
252 0 : hal->ah_radio = AR5K_AR2413;
253 0 : hal->ah_phy_spending = AR5K_AR5212_PHY_SPENDING_AR5112A;
254 0 : } else if (hal->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC2) {
255 0 : hal->ah_radio = AR5K_AR5413;
256 0 : hal->ah_phy_spending = AR5K_AR5212_PHY_SPENDING_AR5112A;
257 0 : } else if (hal->ah_radio_5ghz_revision < AR5K_SREV_RAD_5133 &&
258 0 : srev < AR5K_SREV_VER_AR5424) {
259 0 : hal->ah_radio = AR5K_AR2413;
260 0 : hal->ah_phy_spending = AR5K_AR5212_PHY_SPENDING_AR5112A;
261 0 : } else if (hal->ah_radio_5ghz_revision < AR5K_SREV_RAD_5133) {
262 0 : hal->ah_radio = AR5K_AR5413;
263 0 : hal->ah_phy_spending = AR5K_AR5212_PHY_SPENDING_AR5424;
264 0 : }
265 0 : hal->ah_phy = AR5K_AR5212_PHY(0);
266 :
267 0 : if (hal->ah_pci_express == AH_TRUE) {
268 : /* PCI-Express based devices need some extra initialization */
269 0 : ar5k_write_ini(hal, ar5212_pcie, nitems(ar5212_pcie), 0);
270 0 : }
271 :
272 0 : bcopy(etherbroadcastaddr, mac, IEEE80211_ADDR_LEN);
273 0 : ar5k_ar5212_set_associd(hal, mac, 0, 0);
274 0 : ar5k_ar5212_get_lladdr(hal, mac);
275 0 : ar5k_ar5212_set_opmode(hal);
276 :
277 0 : return (hal);
278 0 : }
279 :
280 : HAL_BOOL
281 0 : ar5k_ar5212_nic_reset(struct ath_hal *hal, u_int32_t val)
282 : {
283 : HAL_BOOL ret = AH_FALSE;
284 0 : u_int32_t mask = val ? val : ~0;
285 :
286 : /* Read-and-clear */
287 0 : AR5K_REG_READ(AR5K_AR5212_RXDP);
288 :
289 : /*
290 : * Reset the device and wait until success
291 : */
292 0 : AR5K_REG_WRITE(AR5K_AR5212_RC, val);
293 :
294 : /* Wait at least 128 PCI clocks */
295 0 : AR5K_DELAY(15);
296 :
297 0 : val &=
298 : AR5K_AR5212_RC_PCU | AR5K_AR5212_RC_BB;
299 :
300 0 : mask &=
301 : AR5K_AR5212_RC_PCU | AR5K_AR5212_RC_BB;
302 :
303 0 : ret = ar5k_register_timeout(hal, AR5K_AR5212_RC, mask, val, AH_FALSE);
304 :
305 : /*
306 : * Reset configuration register
307 : */
308 0 : if ((val & AR5K_AR5212_RC_PCU) == 0)
309 0 : AR5K_REG_WRITE(AR5K_AR5212_CFG, AR5K_AR5212_INIT_CFG);
310 :
311 0 : return (ret);
312 : }
313 :
314 : HAL_BOOL
315 0 : ar5k_ar5212_nic_wakeup(struct ath_hal *hal, u_int16_t flags)
316 : {
317 : u_int32_t turbo, mode, clock;
318 :
319 : turbo = 0;
320 : mode = 0;
321 : clock = 0;
322 :
323 : /*
324 : * Get channel mode flags
325 : */
326 :
327 0 : if (hal->ah_radio >= AR5K_AR5112) {
328 : mode = AR5K_AR5212_PHY_MODE_RAD_AR5112;
329 : clock = AR5K_AR5212_PHY_PLL_AR5112;
330 0 : } else {
331 : mode = AR5K_AR5212_PHY_MODE_RAD_AR5111;
332 : clock = AR5K_AR5212_PHY_PLL_AR5111;
333 : }
334 :
335 0 : if (flags & IEEE80211_CHAN_2GHZ) {
336 0 : mode |= AR5K_AR5212_PHY_MODE_FREQ_2GHZ;
337 0 : clock |= AR5K_AR5212_PHY_PLL_44MHZ;
338 0 : } else if (flags & IEEE80211_CHAN_5GHZ) {
339 : mode |= AR5K_AR5212_PHY_MODE_FREQ_5GHZ;
340 0 : clock |= AR5K_AR5212_PHY_PLL_40MHZ;
341 : } else {
342 0 : AR5K_PRINT("invalid radio frequency mode\n");
343 0 : return (AH_FALSE);
344 : }
345 :
346 0 : if (flags & IEEE80211_CHAN_CCK) {
347 0 : mode |= AR5K_AR5212_PHY_MODE_MOD_CCK;
348 0 : } else if (flags & IEEE80211_CHAN_OFDM) {
349 : mode |= AR5K_AR5212_PHY_MODE_MOD_OFDM;
350 0 : } else if (flags & IEEE80211_CHAN_DYN) {
351 0 : mode |= AR5K_AR5212_PHY_MODE_MOD_DYN;
352 : } else {
353 0 : AR5K_PRINT("invalid radio frequency mode\n");
354 0 : return (AH_FALSE);
355 : }
356 :
357 : /*
358 : * Reset and wakeup the device
359 : */
360 :
361 : /* ...reset chipset and PCI device (if not PCI-E) */
362 0 : if (hal->ah_pci_express == AH_FALSE &&
363 0 : ar5k_ar5212_nic_reset(hal, AR5K_AR5212_RC_CHIP) == AH_FALSE) {
364 0 : AR5K_PRINT("failed to reset the AR5212 + PCI chipset\n");
365 0 : return (AH_FALSE);
366 : }
367 :
368 : /* ...wakeup */
369 0 : if (ar5k_ar5212_set_power(hal,
370 0 : HAL_PM_AWAKE, AH_TRUE, 0) == AH_FALSE) {
371 0 : AR5K_PRINT("failed to resume the AR5212 (again)\n");
372 0 : return (AH_FALSE);
373 : }
374 :
375 : /* ...final warm reset */
376 0 : if (ar5k_ar5212_nic_reset(hal, 0) == AH_FALSE) {
377 0 : AR5K_PRINT("failed to warm reset the AR5212\n");
378 0 : return (AH_FALSE);
379 : }
380 :
381 : /* ...set the PHY operating mode */
382 0 : AR5K_REG_WRITE(AR5K_AR5212_PHY_PLL, clock);
383 0 : AR5K_DELAY(300);
384 :
385 0 : AR5K_REG_WRITE(AR5K_AR5212_PHY_MODE, mode);
386 0 : AR5K_REG_WRITE(AR5K_AR5212_PHY_TURBO, turbo);
387 :
388 0 : return (AH_TRUE);
389 0 : }
390 :
391 : u_int16_t
392 0 : ar5k_ar5212_radio_revision(struct ath_hal *hal, HAL_CHIP chip)
393 : {
394 : int i;
395 : u_int32_t srev;
396 : u_int16_t ret;
397 :
398 : /*
399 : * Set the radio chip access register
400 : */
401 0 : switch (chip) {
402 : case HAL_CHIP_2GHZ:
403 0 : AR5K_REG_WRITE(AR5K_AR5212_PHY(0), AR5K_AR5212_PHY_SHIFT_2GHZ);
404 0 : break;
405 : case HAL_CHIP_5GHZ:
406 0 : AR5K_REG_WRITE(AR5K_AR5212_PHY(0), AR5K_AR5212_PHY_SHIFT_5GHZ);
407 0 : break;
408 : default:
409 0 : return (0);
410 : }
411 :
412 0 : AR5K_DELAY(2000);
413 :
414 : /* ...wait until PHY is ready and read the selected radio revision */
415 0 : AR5K_REG_WRITE(AR5K_AR5212_PHY(0x34), 0x00001c16);
416 :
417 0 : for (i = 0; i < 8; i++)
418 0 : AR5K_REG_WRITE(AR5K_AR5212_PHY(0x20), 0x00010000);
419 0 : srev = (AR5K_REG_READ(AR5K_AR5212_PHY(0x100)) >> 24) & 0xff;
420 :
421 0 : ret = ar5k_bitswap(((srev & 0xf0) >> 4) | ((srev & 0x0f) << 4), 8);
422 :
423 : /* Reset to the 5GHz mode */
424 0 : AR5K_REG_WRITE(AR5K_AR5212_PHY(0), AR5K_AR5212_PHY_SHIFT_5GHZ);
425 :
426 0 : return (ret);
427 0 : }
428 :
429 : const HAL_RATE_TABLE *
430 0 : ar5k_ar5212_get_rate_table(struct ath_hal *hal, u_int mode)
431 : {
432 0 : switch (mode) {
433 : case HAL_MODE_11A:
434 0 : return (&hal->ah_rt_11a);
435 : case HAL_MODE_11B:
436 0 : return (&hal->ah_rt_11b);
437 : case HAL_MODE_11G:
438 : case HAL_MODE_PUREG:
439 0 : return (&hal->ah_rt_11g);
440 : case HAL_MODE_XR:
441 0 : return (&hal->ah_rt_xr);
442 : default:
443 0 : return (NULL);
444 : }
445 :
446 : return (NULL);
447 0 : }
448 :
449 : void
450 0 : ar5k_ar5212_detach(struct ath_hal *hal)
451 : {
452 0 : if (hal->ah_rf_banks != NULL)
453 0 : free(hal->ah_rf_banks, M_DEVBUF, 0);
454 :
455 : /*
456 : * Free HAL structure, assume interrupts are down
457 : */
458 0 : free(hal, M_DEVBUF, 0);
459 0 : }
460 :
461 : HAL_BOOL
462 0 : ar5k_ar5212_phy_disable(struct ath_hal *hal)
463 : {
464 0 : AR5K_REG_WRITE(AR5K_AR5212_PHY_ACTIVE, AR5K_AR5212_PHY_DISABLE);
465 0 : return (AH_TRUE);
466 : }
467 :
468 : HAL_BOOL
469 0 : ar5k_ar5212_reset(struct ath_hal *hal, HAL_OPMODE op_mode, HAL_CHANNEL *channel,
470 : HAL_BOOL chanchange, HAL_STATUS *status)
471 : {
472 0 : struct ar5k_eeprom_info *ee = &hal->ah_capabilities.cap_eeprom;
473 0 : u_int8_t mac[IEEE80211_ADDR_LEN];
474 : u_int32_t data, s_seq, s_ant, s_led[3], dmasize;
475 : u_int i, mode, freq, ee_mode, ant[2];
476 : const HAL_RATE_TABLE *rt;
477 :
478 : /* Not used, keep for HAL compatibility */
479 0 : *status = HAL_OK;
480 :
481 : /*
482 : * Save some registers before a reset
483 : */
484 0 : if (chanchange == AH_TRUE) {
485 0 : s_seq = AR5K_REG_READ(AR5K_AR5212_DCU_SEQNUM(0));
486 0 : s_ant = AR5K_REG_READ(AR5K_AR5212_DEFAULT_ANTENNA);
487 0 : } else {
488 : s_seq = 0;
489 : s_ant = 1;
490 : }
491 :
492 0 : s_led[0] = AR5K_REG_READ(AR5K_AR5212_PCICFG) &
493 : AR5K_AR5212_PCICFG_LEDSTATE;
494 0 : s_led[1] = AR5K_REG_READ(AR5K_AR5212_GPIOCR);
495 0 : s_led[2] = AR5K_REG_READ(AR5K_AR5212_GPIODO);
496 :
497 0 : if (chanchange == AH_TRUE && hal->ah_rf_banks != NULL)
498 0 : ar5k_ar5212_get_rf_gain(hal);
499 :
500 0 : if (ar5k_ar5212_nic_wakeup(hal, channel->c_channel_flags) == AH_FALSE)
501 0 : return (AH_FALSE);
502 :
503 : /*
504 : * Initialize operating mode
505 : */
506 0 : hal->ah_op_mode = op_mode;
507 :
508 0 : if ((channel->c_channel_flags & CHANNEL_A) == CHANNEL_A) {
509 : mode = AR5K_INI_VAL_11A;
510 : freq = AR5K_INI_RFGAIN_5GHZ;
511 : ee_mode = AR5K_EEPROM_MODE_11A;
512 0 : } else if ((channel->c_channel_flags & CHANNEL_B) == CHANNEL_B) {
513 0 : if (hal->ah_capabilities.cap_mode & HAL_MODE_11B) {
514 : mode = AR5K_INI_VAL_11B;
515 : ee_mode = AR5K_EEPROM_MODE_11B;
516 0 : } else {
517 : mode = AR5K_INI_VAL_11G;
518 : ee_mode = AR5K_EEPROM_MODE_11G;
519 : }
520 : freq = AR5K_INI_RFGAIN_2GHZ;
521 0 : } else if ((channel->c_channel_flags & (CHANNEL_G | CHANNEL_PUREG)) ==
522 : (CHANNEL_G | CHANNEL_PUREG)) {
523 : mode = AR5K_INI_VAL_11G;
524 : freq = AR5K_INI_RFGAIN_2GHZ;
525 : ee_mode = AR5K_EEPROM_MODE_11G;
526 0 : } else if ((channel->c_channel_flags & CHANNEL_XR) == CHANNEL_XR) {
527 : mode = AR5K_INI_VAL_XR;
528 : freq = AR5K_INI_RFGAIN_5GHZ;
529 : ee_mode = AR5K_EEPROM_MODE_11A;
530 : } else {
531 0 : AR5K_PRINTF("invalid channel: %d\n", channel->c_channel);
532 0 : return (AH_FALSE);
533 : }
534 :
535 : /* PHY access enable */
536 0 : AR5K_REG_WRITE(AR5K_AR5212_PHY(0), AR5K_AR5212_PHY_SHIFT_5GHZ);
537 :
538 : /*
539 : * Write initial mode and register settings
540 : */
541 0 : ar5k_write_mode(hal, ar5212_mode, nitems(ar5212_mode), mode);
542 0 : ar5k_write_ini(hal, ar5212_ini, nitems(ar5212_ini), chanchange);
543 :
544 0 : switch (hal->ah_radio) {
545 : case AR5K_AR5111:
546 0 : ar5k_write_mode(hal, ar5212_ar5111_mode,
547 : nitems(ar5212_ar5111_mode), mode);
548 0 : break;
549 : case AR5K_AR5112:
550 0 : ar5k_write_mode(hal, ar5212_ar5112_mode,
551 : nitems(ar5212_ar5112_mode), mode);
552 0 : break;
553 : case AR5K_AR5413:
554 0 : ar5k_write_mode(hal, ar5413_mode,
555 : nitems(ar5413_mode), mode);
556 0 : break;
557 : case AR5K_AR2413:
558 0 : AR5K_REG_WRITE(AR5K_AR5212_PHY(648), 0x018830c6);
559 0 : ar5k_write_mode(hal, ar2413_mode,
560 : nitems(ar2413_mode), mode);
561 0 : break;
562 : case AR5K_AR2425:
563 0 : AR5K_REG_WRITE(AR5K_AR5212_PHY(648), 0x018830c6);
564 0 : if (mode == AR5K_INI_VAL_11B)
565 0 : mode = AR5K_INI_VAL_11G;
566 0 : ar5k_write_mode(hal, ar2425_mode,
567 : nitems(ar2425_mode), mode);
568 0 : break;
569 : default:
570 0 : AR5K_PRINTF("invalid radio: %d\n", hal->ah_radio);
571 0 : return (AH_FALSE);
572 : }
573 :
574 0 : if (hal->ah_radio == AR5K_AR5111)
575 0 : ar5k_write_ini(hal, ar5111_bbgain,
576 : nitems(ar5111_bbgain), chanchange);
577 : else
578 0 : ar5k_write_ini(hal, ar5112_bbgain,
579 : nitems(ar5112_bbgain), chanchange);
580 :
581 : /*
582 : * Write initial RF gain settings
583 : */
584 0 : if (ar5k_rfgain(hal, freq) == AH_FALSE)
585 0 : return (AH_FALSE);
586 :
587 0 : AR5K_DELAY(1000);
588 :
589 : /*
590 : * Set rate duration table
591 : */
592 0 : rt = ar5k_ar5212_get_rate_table(hal, HAL_MODE_XR);
593 :
594 0 : for (i = 0; i < rt->rt_rate_count; i++) {
595 0 : AR5K_REG_WRITE(AR5K_AR5212_RATE_DUR(rt->rt_info[i].r_rate_code),
596 : ath_hal_computetxtime(hal, rt, 14,
597 : rt->rt_info[i].r_control_rate, AH_FALSE));
598 : }
599 :
600 0 : rt = ar5k_ar5212_get_rate_table(hal, HAL_MODE_11B);
601 0 : for (i = 0; i < rt->rt_rate_count; i++) {
602 0 : data = AR5K_AR5212_RATE_DUR(rt->rt_info[i].r_rate_code);
603 0 : AR5K_REG_WRITE(data,
604 : ath_hal_computetxtime(hal, rt, 14,
605 : rt->rt_info[i].r_control_rate, AH_FALSE));
606 0 : if (rt->rt_info[i].r_short_preamble) {
607 0 : AR5K_REG_WRITE(data +
608 : (rt->rt_info[i].r_short_preamble << 2),
609 : ath_hal_computetxtime(hal, rt, 14,
610 : rt->rt_info[i].r_control_rate, AH_FALSE));
611 0 : }
612 : }
613 :
614 : /* Fix for first revision of the AR5112 RF chipset */
615 0 : if (hal->ah_radio >= AR5K_AR5112 &&
616 0 : hal->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112A) {
617 0 : AR5K_REG_WRITE(AR5K_AR5212_PHY_CCKTXCTL,
618 : AR5K_AR5212_PHY_CCKTXCTL_WORLD);
619 0 : if (channel->c_channel_flags & IEEE80211_CHAN_OFDM)
620 0 : data = 0xffb81020;
621 : else
622 : data = 0xffb80d20;
623 0 : AR5K_REG_WRITE(AR5K_AR5212_PHY_FC, data);
624 0 : }
625 :
626 : /*
627 : * Set TX power (XXX use txpower from net80211)
628 : */
629 0 : if (ar5k_ar5212_txpower(hal, channel,
630 0 : AR5K_TUNE_DEFAULT_TXPOWER) == AH_FALSE)
631 0 : return (AH_FALSE);
632 :
633 : /*
634 : * Write RF registers
635 : */
636 0 : if (ar5k_rfregs(hal, channel, mode) == AH_FALSE)
637 0 : return (AH_FALSE);
638 :
639 : /*
640 : * Configure additional registers
641 : */
642 :
643 : /* OFDM timings */
644 0 : if (channel->c_channel_flags & IEEE80211_CHAN_OFDM) {
645 : u_int32_t coef_scaled, coef_exp, coef_man, ds_coef_exp,
646 : ds_coef_man, clock;
647 :
648 : clock = 40;
649 0 : coef_scaled = ((5 * (clock << 24)) / 2) / channel->c_channel;
650 :
651 0 : for (coef_exp = 31; coef_exp > 0; coef_exp--)
652 0 : if ((coef_scaled >> coef_exp) & 0x1)
653 : break;
654 :
655 0 : if (!coef_exp)
656 0 : return (AH_FALSE);
657 :
658 0 : coef_exp = 14 - (coef_exp - 24);
659 0 : coef_man = coef_scaled + (1 << (24 - coef_exp - 1));
660 0 : ds_coef_man = coef_man >> (24 - coef_exp);
661 0 : ds_coef_exp = coef_exp - 16;
662 :
663 0 : AR5K_REG_WRITE_BITS(AR5K_AR5212_PHY_TIMING_3,
664 : AR5K_AR5212_PHY_TIMING_3_DSC_MAN, ds_coef_man);
665 0 : AR5K_REG_WRITE_BITS(AR5K_AR5212_PHY_TIMING_3,
666 : AR5K_AR5212_PHY_TIMING_3_DSC_EXP, ds_coef_exp);
667 0 : }
668 :
669 0 : if (hal->ah_radio == AR5K_AR5111) {
670 0 : if (channel->c_channel_flags & IEEE80211_CHAN_B)
671 0 : AR5K_REG_ENABLE_BITS(AR5K_AR5212_TXCFG,
672 : AR5K_AR5212_TXCFG_B_MODE);
673 : else
674 0 : AR5K_REG_DISABLE_BITS(AR5K_AR5212_TXCFG,
675 : AR5K_AR5212_TXCFG_B_MODE);
676 : }
677 :
678 : /* Set antenna mode */
679 0 : AR5K_REG_MASKED_BITS(AR5K_AR5212_PHY(0x44),
680 : hal->ah_antenna[ee_mode][0], 0xfffffc06);
681 :
682 0 : if (freq == AR5K_INI_RFGAIN_2GHZ)
683 0 : ant[0] = ant[1] = HAL_ANT_FIXED_B;
684 : else
685 : ant[0] = ant[1] = HAL_ANT_FIXED_A;
686 :
687 0 : AR5K_REG_WRITE(AR5K_AR5212_PHY_ANT_SWITCH_TABLE_0,
688 : hal->ah_antenna[ee_mode][ant[0]]);
689 0 : AR5K_REG_WRITE(AR5K_AR5212_PHY_ANT_SWITCH_TABLE_1,
690 : hal->ah_antenna[ee_mode][ant[1]]);
691 :
692 : /* Commit values from EEPROM */
693 0 : if (hal->ah_radio == AR5K_AR5111)
694 0 : AR5K_REG_WRITE_BITS(AR5K_AR5212_PHY_FC,
695 : AR5K_AR5212_PHY_FC_TX_CLIP, ee->ee_tx_clip);
696 :
697 0 : AR5K_REG_WRITE(AR5K_AR5212_PHY(0x5a),
698 : AR5K_AR5212_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]));
699 :
700 0 : AR5K_REG_MASKED_BITS(AR5K_AR5212_PHY(0x11),
701 : (ee->ee_switch_settling[ee_mode] << 7) & 0x3f80, 0xffffc07f);
702 0 : AR5K_REG_MASKED_BITS(AR5K_AR5212_PHY(0x12),
703 : (ee->ee_ant_tx_rx[ee_mode] << 12) & 0x3f000, 0xfffc0fff);
704 0 : AR5K_REG_MASKED_BITS(AR5K_AR5212_PHY(0x14),
705 : (ee->ee_adc_desired_size[ee_mode] & 0x00ff) |
706 : ((ee->ee_pga_desired_size[ee_mode] << 8) & 0xff00), 0xffff0000);
707 :
708 0 : AR5K_REG_WRITE(AR5K_AR5212_PHY(0x0d),
709 : (ee->ee_tx_end2xpa_disable[ee_mode] << 24) |
710 : (ee->ee_tx_end2xpa_disable[ee_mode] << 16) |
711 : (ee->ee_tx_frm2xpa_enable[ee_mode] << 8) |
712 : (ee->ee_tx_frm2xpa_enable[ee_mode]));
713 :
714 0 : AR5K_REG_MASKED_BITS(AR5K_AR5212_PHY(0x0a),
715 : ee->ee_tx_end2xlna_enable[ee_mode] << 8, 0xffff00ff);
716 0 : AR5K_REG_MASKED_BITS(AR5K_AR5212_PHY(0x19),
717 : (ee->ee_thr_62[ee_mode] << 12) & 0x7f000, 0xfff80fff);
718 0 : AR5K_REG_MASKED_BITS(AR5K_AR5212_PHY(0x49), 4, 0xffffff01);
719 :
720 0 : AR5K_REG_ENABLE_BITS(AR5K_AR5212_PHY_IQ,
721 : AR5K_AR5212_PHY_IQ_CORR_ENABLE |
722 : (ee->ee_i_cal[ee_mode] << AR5K_AR5212_PHY_IQ_CORR_Q_I_COFF_S) |
723 : ee->ee_q_cal[ee_mode]);
724 :
725 0 : if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) {
726 0 : AR5K_REG_WRITE_BITS(AR5K_AR5212_PHY_GAIN_2GHZ,
727 : AR5K_AR5212_PHY_GAIN_2GHZ_MARGIN_TXRX,
728 : ee->ee_margin_tx_rx[ee_mode]);
729 0 : }
730 :
731 : /*
732 : * Restore saved values
733 : */
734 0 : AR5K_REG_WRITE(AR5K_AR5212_DCU_SEQNUM(0), s_seq);
735 0 : AR5K_REG_WRITE(AR5K_AR5212_DEFAULT_ANTENNA, s_ant);
736 0 : AR5K_REG_ENABLE_BITS(AR5K_AR5212_PCICFG, s_led[0]);
737 0 : AR5K_REG_WRITE(AR5K_AR5212_GPIOCR, s_led[1]);
738 0 : AR5K_REG_WRITE(AR5K_AR5212_GPIODO, s_led[2]);
739 :
740 : /*
741 : * Misc
742 : */
743 0 : bcopy(etherbroadcastaddr, mac, IEEE80211_ADDR_LEN);
744 0 : ar5k_ar5212_set_associd(hal, mac, 0, 0);
745 0 : ar5k_ar5212_set_opmode(hal);
746 0 : AR5K_REG_WRITE(AR5K_AR5212_PISR, 0xffffffff);
747 0 : AR5K_REG_WRITE(AR5K_AR5212_RSSI_THR, AR5K_TUNE_RSSI_THRES);
748 :
749 : /*
750 : * Set Rx/Tx DMA Configuration
751 : *
752 : * XXX Limit DMA size on PCI-E chipsets to 128 bytes because
753 : * XXX we saw RX overruns and TX errors with higher values.
754 : */
755 0 : dmasize = hal->ah_pci_express == AH_TRUE ?
756 : AR5K_AR5212_DMASIZE_128B : AR5K_AR5212_DMASIZE_512B;
757 0 : AR5K_REG_WRITE_BITS(AR5K_AR5212_TXCFG, AR5K_AR5212_TXCFG_SDMAMR,
758 : dmasize | AR5K_AR5212_TXCFG_DMASIZE);
759 0 : AR5K_REG_WRITE_BITS(AR5K_AR5212_RXCFG, AR5K_AR5212_RXCFG_SDMAMW,
760 : dmasize);
761 :
762 : /*
763 : * Set channel and calibrate the PHY
764 : */
765 0 : if (ar5k_channel(hal, channel) == AH_FALSE)
766 0 : return (AH_FALSE);
767 :
768 : /*
769 : * Enable the PHY and wait until completion
770 : */
771 0 : AR5K_REG_WRITE(AR5K_AR5212_PHY_ACTIVE, AR5K_AR5212_PHY_ENABLE);
772 :
773 0 : data = AR5K_REG_READ(AR5K_AR5212_PHY_RX_DELAY) &
774 : AR5K_AR5212_PHY_RX_DELAY_M;
775 0 : data = (channel->c_channel_flags & IEEE80211_CHAN_CCK) ?
776 0 : ((data << 2) / 22) : (data / 10);
777 :
778 0 : AR5K_DELAY(100 + data);
779 :
780 : /*
781 : * Start calibration
782 : */
783 0 : AR5K_REG_ENABLE_BITS(AR5K_AR5212_PHY_AGCCTL,
784 : AR5K_AR5212_PHY_AGCCTL_NF |
785 : AR5K_AR5212_PHY_AGCCTL_CAL);
786 :
787 0 : hal->ah_calibration = AH_FALSE;
788 0 : if ((channel->c_channel_flags & IEEE80211_CHAN_B) == 0) {
789 0 : hal->ah_calibration = AH_TRUE;
790 0 : AR5K_REG_WRITE_BITS(AR5K_AR5212_PHY_IQ,
791 : AR5K_AR5212_PHY_IQ_CAL_NUM_LOG_MAX, 15);
792 0 : AR5K_REG_ENABLE_BITS(AR5K_AR5212_PHY_IQ,
793 : AR5K_AR5212_PHY_IQ_RUN);
794 0 : }
795 :
796 : /*
797 : * Reset queues and start beacon timers at the end of the reset routine
798 : */
799 0 : for (i = 0; i < hal->ah_capabilities.cap_queues.q_tx_num; i++) {
800 0 : AR5K_REG_WRITE_Q(AR5K_AR5212_DCU_QCUMASK(i), i);
801 0 : if (ar5k_ar5212_reset_tx_queue(hal, i) == AH_FALSE) {
802 0 : AR5K_PRINTF("failed to reset TX queue #%d\n", i);
803 0 : return (AH_FALSE);
804 : }
805 : }
806 :
807 : /* Pre-enable interrupts */
808 0 : ar5k_ar5212_set_intr(hal, HAL_INT_RX | HAL_INT_TX | HAL_INT_FATAL);
809 :
810 : /*
811 : * Set RF kill flags if supported by the device (read from the EEPROM)
812 : */
813 0 : if (AR5K_EEPROM_HDR_RFKILL(hal->ah_capabilities.cap_eeprom.ee_header)) {
814 0 : ar5k_ar5212_set_gpio_input(hal, 0);
815 0 : if ((hal->ah_gpio[0] = ar5k_ar5212_get_gpio(hal, 0)) == 0)
816 0 : ar5k_ar5212_set_gpio_intr(hal, 0, 1);
817 : else
818 0 : ar5k_ar5212_set_gpio_intr(hal, 0, 0);
819 : }
820 :
821 : /*
822 : * Set the 32MHz reference clock
823 : */
824 0 : AR5K_REG_WRITE(AR5K_AR5212_PHY_SCR, AR5K_AR5212_PHY_SCR_32MHZ);
825 0 : AR5K_REG_WRITE(AR5K_AR5212_PHY_SLMT, AR5K_AR5212_PHY_SLMT_32MHZ);
826 0 : AR5K_REG_WRITE(AR5K_AR5212_PHY_SCAL, AR5K_AR5212_PHY_SCAL_32MHZ);
827 0 : AR5K_REG_WRITE(AR5K_AR5212_PHY_SCLOCK, AR5K_AR5212_PHY_SCLOCK_32MHZ);
828 0 : AR5K_REG_WRITE(AR5K_AR5212_PHY_SDELAY, AR5K_AR5212_PHY_SDELAY_32MHZ);
829 0 : AR5K_REG_WRITE(AR5K_AR5212_PHY_SPENDING, hal->ah_phy_spending);
830 :
831 : /*
832 : * Disable beacons and reset the register
833 : */
834 0 : AR5K_REG_DISABLE_BITS(AR5K_AR5212_BEACON,
835 : AR5K_AR5212_BEACON_ENABLE | AR5K_AR5212_BEACON_RESET_TSF);
836 :
837 0 : return (AH_TRUE);
838 0 : }
839 :
840 : void
841 0 : ar5k_ar5212_set_def_antenna(struct ath_hal *hal, u_int ant)
842 : {
843 0 : AR5K_REG_WRITE(AR5K_AR5212_DEFAULT_ANTENNA, ant);
844 0 : }
845 :
846 : u_int
847 0 : ar5k_ar5212_get_def_antenna(struct ath_hal *hal)
848 : {
849 0 : return AR5K_REG_READ(AR5K_AR5212_DEFAULT_ANTENNA);
850 : }
851 :
852 : void
853 0 : ar5k_ar5212_set_opmode(struct ath_hal *hal)
854 : {
855 : u_int32_t pcu_reg, low_id, high_id;
856 :
857 : pcu_reg = 0;
858 :
859 0 : switch (hal->ah_op_mode) {
860 : #ifndef IEEE80211_STA_ONLY
861 : case IEEE80211_M_IBSS:
862 : pcu_reg |= AR5K_AR5212_STA_ID1_ADHOC |
863 : AR5K_AR5212_STA_ID1_DESC_ANTENNA;
864 0 : break;
865 :
866 : case IEEE80211_M_HOSTAP:
867 : pcu_reg |= AR5K_AR5212_STA_ID1_AP |
868 : AR5K_AR5212_STA_ID1_RTS_DEFAULT_ANTENNA;
869 0 : break;
870 : #endif
871 :
872 : case IEEE80211_M_STA:
873 : case IEEE80211_M_MONITOR:
874 : pcu_reg |= AR5K_AR5212_STA_ID1_DEFAULT_ANTENNA;
875 0 : break;
876 :
877 : default:
878 0 : return;
879 : }
880 :
881 : /*
882 : * Set PCU registers
883 : */
884 0 : low_id = AR5K_LOW_ID(hal->ah_sta_id);
885 0 : high_id = AR5K_HIGH_ID(hal->ah_sta_id);
886 0 : AR5K_REG_WRITE(AR5K_AR5212_STA_ID0, low_id);
887 0 : AR5K_REG_WRITE(AR5K_AR5212_STA_ID1, pcu_reg | high_id);
888 :
889 0 : return;
890 0 : }
891 :
892 : HAL_BOOL
893 0 : ar5k_ar5212_calibrate(struct ath_hal *hal, HAL_CHANNEL *channel)
894 : {
895 : u_int32_t i_pwr, q_pwr;
896 : int32_t iq_corr, i_coff, i_coffd, q_coff, q_coffd;
897 :
898 0 : if (hal->ah_calibration == AH_FALSE ||
899 0 : AR5K_REG_READ(AR5K_AR5212_PHY_IQ) & AR5K_AR5212_PHY_IQ_RUN)
900 : goto done;
901 :
902 0 : hal->ah_calibration = AH_FALSE;
903 :
904 0 : iq_corr = AR5K_REG_READ(AR5K_AR5212_PHY_IQRES_CAL_CORR);
905 0 : i_pwr = AR5K_REG_READ(AR5K_AR5212_PHY_IQRES_CAL_PWR_I);
906 0 : q_pwr = AR5K_REG_READ(AR5K_AR5212_PHY_IQRES_CAL_PWR_Q);
907 0 : i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7;
908 0 : q_coffd = q_pwr >> 6;
909 :
910 0 : if (i_coffd == 0 || q_coffd == 0)
911 : goto done;
912 :
913 0 : i_coff = ((-iq_corr) / i_coffd) & 0x3f;
914 0 : q_coff = (((int32_t)i_pwr / q_coffd) - 64) & 0x1f;
915 :
916 : /* Commit new IQ value */
917 0 : AR5K_REG_ENABLE_BITS(AR5K_AR5212_PHY_IQ,
918 : AR5K_AR5212_PHY_IQ_CORR_ENABLE |
919 : ((u_int32_t)q_coff) |
920 : ((u_int32_t)i_coff << AR5K_AR5212_PHY_IQ_CORR_Q_I_COFF_S));
921 :
922 : done:
923 : /* Start noise floor calibration */
924 0 : AR5K_REG_ENABLE_BITS(AR5K_AR5212_PHY_AGCCTL,
925 : AR5K_AR5212_PHY_AGCCTL_NF);
926 :
927 : /* Request RF gain */
928 0 : if (channel->c_channel_flags & IEEE80211_CHAN_5GHZ) {
929 0 : AR5K_REG_WRITE(AR5K_AR5212_PHY_PAPD_PROBE,
930 : AR5K_REG_SM(hal->ah_txpower.txp_max,
931 : AR5K_AR5212_PHY_PAPD_PROBE_TXPOWER) |
932 : AR5K_AR5212_PHY_PAPD_PROBE_TX_NEXT);
933 0 : hal->ah_rf_gain = HAL_RFGAIN_READ_REQUESTED;
934 0 : }
935 :
936 0 : return (AH_TRUE);
937 : }
938 :
939 : /*
940 : * Transmit functions
941 : */
942 :
943 : HAL_BOOL
944 0 : ar5k_ar5212_update_tx_triglevel(struct ath_hal *hal, HAL_BOOL increase)
945 : {
946 : u_int32_t trigger_level, imr;
947 : HAL_BOOL status = AH_FALSE;
948 :
949 : /*
950 : * Disable interrupts by setting the mask
951 : */
952 0 : imr = ar5k_ar5212_set_intr(hal, hal->ah_imr & ~HAL_INT_GLOBAL);
953 :
954 0 : trigger_level = AR5K_REG_MS(AR5K_REG_READ(AR5K_AR5212_TXCFG),
955 : AR5K_AR5212_TXCFG_TXFULL);
956 :
957 0 : if (increase == AH_FALSE) {
958 0 : if (--trigger_level < AR5K_TUNE_MIN_TX_FIFO_THRES)
959 : goto done;
960 : } else
961 0 : trigger_level +=
962 0 : ((AR5K_TUNE_MAX_TX_FIFO_THRES - trigger_level) / 2);
963 :
964 : /*
965 : * Update trigger level on success
966 : */
967 0 : AR5K_REG_WRITE_BITS(AR5K_AR5212_TXCFG,
968 : AR5K_AR5212_TXCFG_TXFULL, trigger_level);
969 0 : status = AH_TRUE;
970 :
971 : done:
972 : /*
973 : * Restore interrupt mask
974 : */
975 0 : ar5k_ar5212_set_intr(hal, imr);
976 :
977 0 : return (status);
978 : }
979 :
980 : int
981 0 : ar5k_ar5212_setup_tx_queue(struct ath_hal *hal, HAL_TX_QUEUE queue_type,
982 : const HAL_TXQ_INFO *queue_info)
983 : {
984 : u_int queue;
985 :
986 : /*
987 : * Get queue by type
988 : */
989 0 : if (queue_type == HAL_TX_QUEUE_DATA) {
990 0 : for (queue = HAL_TX_QUEUE_ID_DATA_MIN;
991 0 : hal->ah_txq[queue].tqi_type != HAL_TX_QUEUE_INACTIVE;
992 0 : queue++)
993 0 : if (queue > HAL_TX_QUEUE_ID_DATA_MAX)
994 0 : return (-1);
995 0 : } else if (queue_type == HAL_TX_QUEUE_PSPOLL) {
996 : queue = HAL_TX_QUEUE_ID_PSPOLL;
997 0 : } else if (queue_type == HAL_TX_QUEUE_BEACON) {
998 : queue = HAL_TX_QUEUE_ID_BEACON;
999 0 : } else if (queue_type == HAL_TX_QUEUE_CAB) {
1000 : queue = HAL_TX_QUEUE_ID_CAB;
1001 : } else
1002 0 : return (-1);
1003 :
1004 : /*
1005 : * Setup internal queue structure
1006 : */
1007 0 : bzero(&hal->ah_txq[queue], sizeof(HAL_TXQ_INFO));
1008 0 : if (queue_info != NULL) {
1009 0 : if (ar5k_ar5212_setup_tx_queueprops(hal, queue, queue_info)
1010 0 : != AH_TRUE)
1011 0 : return (-1);
1012 : }
1013 0 : hal->ah_txq[queue].tqi_type = queue_type;
1014 :
1015 0 : AR5K_Q_ENABLE_BITS(hal->ah_txq_interrupts, queue);
1016 :
1017 0 : return (queue);
1018 0 : }
1019 :
1020 : HAL_BOOL
1021 0 : ar5k_ar5212_setup_tx_queueprops(struct ath_hal *hal, int queue,
1022 : const HAL_TXQ_INFO *queue_info)
1023 : {
1024 0 : AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
1025 :
1026 0 : if (hal->ah_txq[queue].tqi_type != HAL_TX_QUEUE_INACTIVE)
1027 0 : return (AH_FALSE);
1028 :
1029 0 : bcopy(queue_info, &hal->ah_txq[queue], sizeof(HAL_TXQ_INFO));
1030 :
1031 0 : if (queue_info->tqi_type == HAL_TX_QUEUE_DATA &&
1032 0 : (queue_info->tqi_subtype >= HAL_WME_AC_VI) &&
1033 0 : (queue_info->tqi_subtype <= HAL_WME_UPSD))
1034 0 : hal->ah_txq[queue].tqi_flags |=
1035 : AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS;
1036 :
1037 0 : return (AH_TRUE);
1038 0 : }
1039 :
1040 : HAL_BOOL
1041 0 : ar5k_ar5212_get_tx_queueprops(struct ath_hal *hal, int queue,
1042 : HAL_TXQ_INFO *queue_info)
1043 : {
1044 0 : AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
1045 0 : bcopy(&hal->ah_txq[queue], queue_info, sizeof(HAL_TXQ_INFO));
1046 0 : return (AH_TRUE);
1047 0 : }
1048 :
1049 : HAL_BOOL
1050 0 : ar5k_ar5212_release_tx_queue(struct ath_hal *hal, u_int queue)
1051 : {
1052 0 : AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
1053 :
1054 : /* This queue will be skipped in further operations */
1055 0 : hal->ah_txq[queue].tqi_type = HAL_TX_QUEUE_INACTIVE;
1056 0 : AR5K_Q_DISABLE_BITS(hal->ah_txq_interrupts, queue);
1057 :
1058 0 : return (AH_FALSE);
1059 0 : }
1060 :
1061 : HAL_BOOL
1062 0 : ar5k_ar5212_reset_tx_queue(struct ath_hal *hal, u_int queue)
1063 : {
1064 : u_int32_t cw_min, cw_max, retry_lg, retry_sh;
1065 0 : struct ieee80211_channel *channel = (struct ieee80211_channel*)
1066 0 : &hal->ah_current_channel;
1067 : HAL_TXQ_INFO *tq;
1068 :
1069 0 : AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
1070 :
1071 0 : tq = &hal->ah_txq[queue];
1072 :
1073 0 : if (tq->tqi_type == HAL_TX_QUEUE_INACTIVE)
1074 0 : return (AH_TRUE);
1075 :
1076 : /*
1077 : * Set registers by channel mode
1078 : */
1079 0 : cw_min = hal->ah_cw_min = AR5K_TUNE_CWMIN;
1080 0 : cw_max = hal->ah_cw_max = AR5K_TUNE_CWMAX;
1081 0 : hal->ah_aifs = AR5K_TUNE_AIFS;
1082 0 : if (IEEE80211_IS_CHAN_XR(channel)) {
1083 0 : cw_min = hal->ah_cw_min = AR5K_TUNE_CWMIN_XR;
1084 0 : cw_max = hal->ah_cw_max = AR5K_TUNE_CWMAX_XR;
1085 0 : hal->ah_aifs = AR5K_TUNE_AIFS_XR;
1086 0 : } else if (IEEE80211_IS_CHAN_B(channel)) {
1087 0 : cw_min = hal->ah_cw_min = AR5K_TUNE_CWMIN_11B;
1088 0 : cw_max = hal->ah_cw_max = AR5K_TUNE_CWMAX_11B;
1089 0 : hal->ah_aifs = AR5K_TUNE_AIFS_11B;
1090 0 : }
1091 :
1092 : /*
1093 : * Set retry limits
1094 : */
1095 0 : if (hal->ah_software_retry == AH_TRUE) {
1096 : /* XXX Need to test this */
1097 0 : retry_lg = hal->ah_limit_tx_retries;
1098 : retry_sh = retry_lg =
1099 0 : retry_lg > AR5K_AR5212_DCU_RETRY_LMT_SH_RETRY ?
1100 : AR5K_AR5212_DCU_RETRY_LMT_SH_RETRY : retry_lg;
1101 0 : } else {
1102 : retry_lg = AR5K_INIT_LG_RETRY;
1103 : retry_sh = AR5K_INIT_SH_RETRY;
1104 : }
1105 :
1106 0 : AR5K_REG_WRITE(AR5K_AR5212_DCU_RETRY_LMT(queue),
1107 : AR5K_REG_SM(AR5K_INIT_SLG_RETRY,
1108 : AR5K_AR5212_DCU_RETRY_LMT_SLG_RETRY) |
1109 : AR5K_REG_SM(AR5K_INIT_SSH_RETRY,
1110 : AR5K_AR5212_DCU_RETRY_LMT_SSH_RETRY) |
1111 : AR5K_REG_SM(retry_lg, AR5K_AR5212_DCU_RETRY_LMT_LG_RETRY) |
1112 : AR5K_REG_SM(retry_sh, AR5K_AR5212_DCU_RETRY_LMT_SH_RETRY));
1113 :
1114 : /*
1115 : * Set initial content window (cw_min/cw_max)
1116 : */
1117 : cw_min = 1;
1118 0 : while (cw_min < hal->ah_cw_min)
1119 0 : cw_min = (cw_min << 1) | 1;
1120 :
1121 0 : cw_min = tq->tqi_cw_min < 0 ?
1122 0 : (cw_min >> (-tq->tqi_cw_min)) :
1123 0 : ((cw_min << tq->tqi_cw_min) + (1 << tq->tqi_cw_min) - 1);
1124 0 : cw_max = tq->tqi_cw_max < 0 ?
1125 0 : (cw_max >> (-tq->tqi_cw_max)) :
1126 0 : ((cw_max << tq->tqi_cw_max) + (1 << tq->tqi_cw_max) - 1);
1127 :
1128 0 : AR5K_REG_WRITE(AR5K_AR5212_DCU_LCL_IFS(queue),
1129 : AR5K_REG_SM(cw_min, AR5K_AR5212_DCU_LCL_IFS_CW_MIN) |
1130 : AR5K_REG_SM(cw_max, AR5K_AR5212_DCU_LCL_IFS_CW_MAX) |
1131 : AR5K_REG_SM(hal->ah_aifs + tq->tqi_aifs,
1132 : AR5K_AR5212_DCU_LCL_IFS_AIFS));
1133 :
1134 : /*
1135 : * Set misc registers
1136 : */
1137 0 : AR5K_REG_WRITE(AR5K_AR5212_QCU_MISC(queue),
1138 : AR5K_AR5212_QCU_MISC_DCU_EARLY);
1139 :
1140 0 : if (tq->tqi_cbr_period) {
1141 0 : AR5K_REG_WRITE(AR5K_AR5212_QCU_CBRCFG(queue),
1142 : AR5K_REG_SM(tq->tqi_cbr_period,
1143 : AR5K_AR5212_QCU_CBRCFG_INTVAL) |
1144 : AR5K_REG_SM(tq->tqi_cbr_overflow_limit,
1145 : AR5K_AR5212_QCU_CBRCFG_ORN_THRES));
1146 0 : AR5K_REG_ENABLE_BITS(AR5K_AR5212_QCU_MISC(queue),
1147 : AR5K_AR5212_QCU_MISC_FRSHED_CBR);
1148 0 : if (tq->tqi_cbr_overflow_limit)
1149 0 : AR5K_REG_ENABLE_BITS(AR5K_AR5212_QCU_MISC(queue),
1150 : AR5K_AR5212_QCU_MISC_CBR_THRES_ENABLE);
1151 : }
1152 :
1153 0 : if (tq->tqi_ready_time) {
1154 0 : AR5K_REG_WRITE(AR5K_AR5212_QCU_RDYTIMECFG(queue),
1155 : AR5K_REG_SM(tq->tqi_ready_time,
1156 : AR5K_AR5212_QCU_RDYTIMECFG_INTVAL) |
1157 : AR5K_AR5212_QCU_RDYTIMECFG_ENABLE);
1158 0 : }
1159 :
1160 0 : if (tq->tqi_burst_time) {
1161 0 : AR5K_REG_WRITE(AR5K_AR5212_DCU_CHAN_TIME(queue),
1162 : AR5K_REG_SM(tq->tqi_burst_time,
1163 : AR5K_AR5212_DCU_CHAN_TIME_DUR) |
1164 : AR5K_AR5212_DCU_CHAN_TIME_ENABLE);
1165 :
1166 0 : if (tq->tqi_flags & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE) {
1167 0 : AR5K_REG_ENABLE_BITS(AR5K_AR5212_QCU_MISC(queue),
1168 : AR5K_AR5212_QCU_MISC_TXE);
1169 0 : }
1170 : }
1171 :
1172 0 : if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE) {
1173 0 : AR5K_REG_WRITE(AR5K_AR5212_DCU_MISC(queue),
1174 : AR5K_AR5212_DCU_MISC_POST_FR_BKOFF_DIS);
1175 0 : }
1176 :
1177 0 : if (tq->tqi_flags & AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) {
1178 0 : AR5K_REG_WRITE(AR5K_AR5212_DCU_MISC(queue),
1179 : AR5K_AR5212_DCU_MISC_BACKOFF_FRAG);
1180 0 : }
1181 :
1182 : /*
1183 : * Set registers by queue type
1184 : */
1185 0 : switch (tq->tqi_type) {
1186 : case HAL_TX_QUEUE_BEACON:
1187 0 : AR5K_REG_ENABLE_BITS(AR5K_AR5212_QCU_MISC(queue),
1188 : AR5K_AR5212_QCU_MISC_FRSHED_DBA_GT |
1189 : AR5K_AR5212_QCU_MISC_CBREXP_BCN |
1190 : AR5K_AR5212_QCU_MISC_BCN_ENABLE);
1191 :
1192 0 : AR5K_REG_ENABLE_BITS(AR5K_AR5212_DCU_MISC(queue),
1193 : (AR5K_AR5212_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
1194 : AR5K_AR5212_DCU_MISC_ARBLOCK_CTL_GLOBAL) |
1195 : AR5K_AR5212_DCU_MISC_POST_FR_BKOFF_DIS |
1196 : AR5K_AR5212_DCU_MISC_BCN_ENABLE);
1197 :
1198 0 : AR5K_REG_WRITE(AR5K_AR5212_QCU_RDYTIMECFG(queue),
1199 : ((AR5K_TUNE_BEACON_INTERVAL -
1200 : (AR5K_TUNE_SW_BEACON_RESP - AR5K_TUNE_DMA_BEACON_RESP) -
1201 : AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) |
1202 : AR5K_AR5212_QCU_RDYTIMECFG_ENABLE);
1203 0 : break;
1204 :
1205 : case HAL_TX_QUEUE_CAB:
1206 0 : AR5K_REG_ENABLE_BITS(AR5K_AR5212_QCU_MISC(queue),
1207 : AR5K_AR5212_QCU_MISC_FRSHED_DBA_GT |
1208 : AR5K_AR5212_QCU_MISC_CBREXP |
1209 : AR5K_AR5212_QCU_MISC_CBREXP_BCN);
1210 :
1211 0 : AR5K_REG_ENABLE_BITS(AR5K_AR5212_DCU_MISC(queue),
1212 : (AR5K_AR5212_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
1213 : AR5K_AR5212_DCU_MISC_ARBLOCK_CTL_GLOBAL));
1214 0 : break;
1215 :
1216 : case HAL_TX_QUEUE_PSPOLL:
1217 0 : AR5K_REG_ENABLE_BITS(AR5K_AR5212_QCU_MISC(queue),
1218 : AR5K_AR5212_QCU_MISC_CBREXP);
1219 0 : break;
1220 :
1221 : case HAL_TX_QUEUE_DATA:
1222 : default:
1223 : break;
1224 : }
1225 :
1226 : /*
1227 : * Enable tx queue in the secondary interrupt mask registers
1228 : */
1229 0 : AR5K_REG_WRITE(AR5K_AR5212_SIMR0,
1230 : AR5K_REG_SM(hal->ah_txq_interrupts, AR5K_AR5212_SIMR0_QCU_TXOK) |
1231 : AR5K_REG_SM(hal->ah_txq_interrupts, AR5K_AR5212_SIMR0_QCU_TXDESC));
1232 0 : AR5K_REG_WRITE(AR5K_AR5212_SIMR1,
1233 : AR5K_REG_SM(hal->ah_txq_interrupts, AR5K_AR5212_SIMR1_QCU_TXERR));
1234 0 : AR5K_REG_WRITE(AR5K_AR5212_SIMR2,
1235 : AR5K_REG_SM(hal->ah_txq_interrupts, AR5K_AR5212_SIMR2_QCU_TXURN));
1236 :
1237 0 : return (AH_TRUE);
1238 0 : }
1239 :
1240 : u_int32_t
1241 0 : ar5k_ar5212_get_tx_buf(struct ath_hal *hal, u_int queue)
1242 : {
1243 0 : AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
1244 :
1245 : /*
1246 : * Get the transmit queue descriptor pointer from the selected queue
1247 : */
1248 0 : return (AR5K_REG_READ(AR5K_AR5212_QCU_TXDP(queue)));
1249 0 : }
1250 :
1251 : HAL_BOOL
1252 0 : ar5k_ar5212_put_tx_buf(struct ath_hal *hal, u_int queue, u_int32_t phys_addr)
1253 : {
1254 0 : AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
1255 :
1256 : /*
1257 : * Set the transmit queue descriptor pointer for the selected queue
1258 : * (this won't work if the queue is still active)
1259 : */
1260 0 : if (AR5K_REG_READ_Q(AR5K_AR5212_QCU_TXE, queue))
1261 0 : return (AH_FALSE);
1262 :
1263 0 : AR5K_REG_WRITE(AR5K_AR5212_QCU_TXDP(queue), phys_addr);
1264 :
1265 0 : return (AH_TRUE);
1266 0 : }
1267 :
1268 : u_int32_t
1269 0 : ar5k_ar5212_num_tx_pending(struct ath_hal *hal, u_int queue)
1270 : {
1271 0 : AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
1272 0 : return (AR5K_AR5212_QCU_STS(queue) & AR5K_AR5212_QCU_STS_FRMPENDCNT);
1273 0 : }
1274 :
1275 : HAL_BOOL
1276 0 : ar5k_ar5212_tx_start(struct ath_hal *hal, u_int queue)
1277 : {
1278 0 : AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
1279 :
1280 : /* Return if queue is disabled */
1281 0 : if (AR5K_REG_READ_Q(AR5K_AR5212_QCU_TXD, queue))
1282 0 : return (AH_FALSE);
1283 :
1284 : /* Start queue */
1285 0 : AR5K_REG_WRITE_Q(AR5K_AR5212_QCU_TXE, queue);
1286 :
1287 0 : return (AH_TRUE);
1288 0 : }
1289 :
1290 : HAL_BOOL
1291 0 : ar5k_ar5212_stop_tx_dma(struct ath_hal *hal, u_int queue)
1292 : {
1293 : int i = 100, pending;
1294 :
1295 0 : AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
1296 :
1297 : /*
1298 : * Schedule TX disable and wait until queue is empty
1299 : */
1300 0 : AR5K_REG_WRITE_Q(AR5K_AR5212_QCU_TXD, queue);
1301 :
1302 0 : do {
1303 0 : pending = AR5K_REG_READ(AR5K_AR5212_QCU_STS(queue)) &
1304 : AR5K_AR5212_QCU_STS_FRMPENDCNT;
1305 0 : delay(100);
1306 0 : } while (--i && pending);
1307 :
1308 : /* Clear register */
1309 0 : AR5K_REG_WRITE(AR5K_AR5212_QCU_TXD, 0);
1310 :
1311 0 : return (AH_TRUE);
1312 0 : }
1313 :
1314 : HAL_BOOL
1315 0 : ar5k_ar5212_setup_tx_desc(struct ath_hal *hal, struct ath_desc *desc,
1316 : u_int packet_length, u_int header_length, HAL_PKT_TYPE type, u_int tx_power,
1317 : u_int tx_rate0, u_int tx_tries0, u_int key_index, u_int antenna_mode,
1318 : u_int flags, u_int rtscts_rate, u_int rtscts_duration)
1319 : {
1320 : struct ar5k_ar5212_tx_desc *tx_desc;
1321 :
1322 0 : tx_desc = (struct ar5k_ar5212_tx_desc*)&desc->ds_ctl0;
1323 :
1324 : /*
1325 : * Validate input
1326 : */
1327 0 : if (tx_tries0 == 0)
1328 0 : return (AH_FALSE);
1329 :
1330 0 : if ((tx_desc->tx_control_0 = (packet_length &
1331 0 : AR5K_AR5212_DESC_TX_CTL0_FRAME_LEN)) != packet_length)
1332 0 : return (AH_FALSE);
1333 :
1334 0 : tx_desc->tx_control_0 |=
1335 0 : AR5K_REG_SM(tx_power, AR5K_AR5212_DESC_TX_CTL0_XMIT_POWER) |
1336 0 : AR5K_REG_SM(antenna_mode, AR5K_AR5212_DESC_TX_CTL0_ANT_MODE_XMIT);
1337 0 : tx_desc->tx_control_1 =
1338 0 : AR5K_REG_SM(type, AR5K_AR5212_DESC_TX_CTL1_FRAME_TYPE);
1339 0 : tx_desc->tx_control_2 =
1340 0 : AR5K_REG_SM(tx_tries0, AR5K_AR5212_DESC_TX_CTL2_XMIT_TRIES0);
1341 0 : tx_desc->tx_control_3 =
1342 0 : tx_rate0 & AR5K_AR5212_DESC_TX_CTL3_XMIT_RATE0;
1343 :
1344 : #define _TX_FLAGS(_c, _flag) \
1345 : if (flags & HAL_TXDESC_##_flag) \
1346 : tx_desc->tx_control_##_c |= \
1347 : AR5K_AR5212_DESC_TX_CTL##_c##_##_flag
1348 :
1349 0 : _TX_FLAGS(0, CLRDMASK);
1350 0 : _TX_FLAGS(0, VEOL);
1351 0 : _TX_FLAGS(0, INTREQ);
1352 0 : _TX_FLAGS(0, RTSENA);
1353 0 : _TX_FLAGS(0, CTSENA);
1354 0 : _TX_FLAGS(1, NOACK);
1355 :
1356 : #undef _TX_FLAGS
1357 :
1358 : /*
1359 : * WEP crap
1360 : */
1361 0 : if (key_index != HAL_TXKEYIX_INVALID) {
1362 0 : tx_desc->tx_control_0 |=
1363 : AR5K_AR5212_DESC_TX_CTL0_ENCRYPT_KEY_VALID;
1364 0 : tx_desc->tx_control_1 |=
1365 0 : AR5K_REG_SM(key_index,
1366 : AR5K_AR5212_DESC_TX_CTL1_ENCRYPT_KEY_INDEX);
1367 0 : }
1368 :
1369 : /*
1370 : * RTS/CTS
1371 : */
1372 0 : if (flags & (HAL_TXDESC_RTSENA | HAL_TXDESC_CTSENA)) {
1373 0 : if ((flags & HAL_TXDESC_RTSENA) &&
1374 : (flags & HAL_TXDESC_CTSENA))
1375 0 : return (AH_FALSE);
1376 0 : tx_desc->tx_control_2 |=
1377 0 : rtscts_duration & AR5K_AR5212_DESC_TX_CTL2_RTS_DURATION;
1378 0 : tx_desc->tx_control_3 |=
1379 0 : AR5K_REG_SM(rtscts_rate,
1380 : AR5K_AR5212_DESC_TX_CTL3_RTS_CTS_RATE);
1381 0 : }
1382 :
1383 0 : return (AH_TRUE);
1384 0 : }
1385 :
1386 : HAL_BOOL
1387 0 : ar5k_ar5212_fill_tx_desc(struct ath_hal *hal, struct ath_desc *desc,
1388 : u_int segment_length, HAL_BOOL first_segment, HAL_BOOL last_segment)
1389 : {
1390 : struct ar5k_ar5212_tx_desc *tx_desc;
1391 : struct ar5k_ar5212_tx_status *tx_status;
1392 :
1393 0 : tx_desc = (struct ar5k_ar5212_tx_desc*)&desc->ds_ctl0;
1394 0 : tx_status = (struct ar5k_ar5212_tx_status*)&desc->ds_hw[2];
1395 :
1396 : /* Clear status descriptor */
1397 0 : bzero(tx_status, sizeof(struct ar5k_ar5212_tx_status));
1398 :
1399 : /* Validate segment length and initialize the descriptor */
1400 0 : if (segment_length & ~AR5K_AR5212_DESC_TX_CTL1_BUF_LEN)
1401 0 : return (AH_FALSE);
1402 0 : tx_desc->tx_control_1 =
1403 : #if 0
1404 : (tx_desc->tx_control_1 & ~AR5K_AR5212_DESC_TX_CTL1_BUF_LEN) |
1405 : #endif
1406 : segment_length;
1407 :
1408 0 : if (first_segment != AH_TRUE)
1409 0 : tx_desc->tx_control_0 &= ~AR5K_AR5212_DESC_TX_CTL0_FRAME_LEN;
1410 :
1411 0 : if (last_segment != AH_TRUE)
1412 0 : tx_desc->tx_control_1 |= AR5K_AR5212_DESC_TX_CTL1_MORE;
1413 :
1414 0 : return (AH_TRUE);
1415 0 : }
1416 :
1417 : HAL_BOOL
1418 0 : ar5k_ar5212_setup_xtx_desc(struct ath_hal *hal, struct ath_desc *desc,
1419 : u_int tx_rate1, u_int tx_tries1, u_int tx_rate2, u_int tx_tries2,
1420 : u_int tx_rate3, u_int tx_tries3)
1421 : {
1422 : struct ar5k_ar5212_tx_desc *tx_desc;
1423 :
1424 0 : tx_desc = (struct ar5k_ar5212_tx_desc*)&desc->ds_ctl0;
1425 :
1426 : #define _XTX_TRIES(_n) \
1427 : if (tx_tries##_n) { \
1428 : tx_desc->tx_control_2 |= \
1429 : AR5K_REG_SM(tx_tries##_n, \
1430 : AR5K_AR5212_DESC_TX_CTL2_XMIT_TRIES##_n); \
1431 : tx_desc->tx_control_3 |= \
1432 : AR5K_REG_SM(tx_rate##_n, \
1433 : AR5K_AR5212_DESC_TX_CTL3_XMIT_RATE##_n); \
1434 : }
1435 :
1436 0 : _XTX_TRIES(1);
1437 0 : _XTX_TRIES(2);
1438 0 : _XTX_TRIES(3);
1439 :
1440 : #undef _XTX_TRIES
1441 :
1442 0 : return (AH_TRUE);
1443 : }
1444 :
1445 : HAL_STATUS
1446 0 : ar5k_ar5212_proc_tx_desc(struct ath_hal *hal, struct ath_desc *desc)
1447 : {
1448 : struct ar5k_ar5212_tx_status *tx_status;
1449 : struct ar5k_ar5212_tx_desc *tx_desc;
1450 :
1451 0 : tx_desc = (struct ar5k_ar5212_tx_desc*)&desc->ds_ctl0;
1452 0 : tx_status = (struct ar5k_ar5212_tx_status*)&desc->ds_hw[2];
1453 :
1454 : /* No frame has been send or error */
1455 0 : if ((tx_status->tx_status_1 & AR5K_AR5212_DESC_TX_STATUS1_DONE) == 0)
1456 0 : return (HAL_EINPROGRESS);
1457 :
1458 : /*
1459 : * Get descriptor status
1460 : */
1461 0 : desc->ds_us.tx.ts_tstamp =
1462 0 : AR5K_REG_MS(tx_status->tx_status_0,
1463 : AR5K_AR5212_DESC_TX_STATUS0_SEND_TIMESTAMP);
1464 0 : desc->ds_us.tx.ts_shortretry =
1465 0 : AR5K_REG_MS(tx_status->tx_status_0,
1466 : AR5K_AR5212_DESC_TX_STATUS0_RTS_FAIL_COUNT);
1467 0 : desc->ds_us.tx.ts_longretry =
1468 0 : AR5K_REG_MS(tx_status->tx_status_0,
1469 : AR5K_AR5212_DESC_TX_STATUS0_DATA_FAIL_COUNT);
1470 0 : desc->ds_us.tx.ts_seqnum =
1471 0 : AR5K_REG_MS(tx_status->tx_status_1,
1472 : AR5K_AR5212_DESC_TX_STATUS1_SEQ_NUM);
1473 0 : desc->ds_us.tx.ts_rssi =
1474 0 : AR5K_REG_MS(tx_status->tx_status_1,
1475 : AR5K_AR5212_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
1476 0 : desc->ds_us.tx.ts_antenna = (tx_status->tx_status_1 &
1477 : AR5K_AR5212_DESC_TX_STATUS1_XMIT_ANTENNA) ? 2 : 1;
1478 0 : desc->ds_us.tx.ts_status = 0;
1479 :
1480 0 : switch (AR5K_REG_MS(tx_status->tx_status_1,
1481 : AR5K_AR5212_DESC_TX_STATUS1_FINAL_TS_INDEX)) {
1482 : case 0:
1483 0 : desc->ds_us.tx.ts_rate = tx_desc->tx_control_3 &
1484 : AR5K_AR5212_DESC_TX_CTL3_XMIT_RATE0;
1485 0 : break;
1486 : case 1:
1487 0 : desc->ds_us.tx.ts_rate =
1488 0 : AR5K_REG_MS(tx_desc->tx_control_3,
1489 : AR5K_AR5212_DESC_TX_CTL3_XMIT_RATE1);
1490 0 : desc->ds_us.tx.ts_longretry +=
1491 0 : AR5K_REG_MS(tx_desc->tx_control_2,
1492 : AR5K_AR5212_DESC_TX_CTL2_XMIT_TRIES1);
1493 0 : break;
1494 : case 2:
1495 0 : desc->ds_us.tx.ts_rate =
1496 0 : AR5K_REG_MS(tx_desc->tx_control_3,
1497 : AR5K_AR5212_DESC_TX_CTL3_XMIT_RATE2);
1498 0 : desc->ds_us.tx.ts_longretry +=
1499 0 : AR5K_REG_MS(tx_desc->tx_control_2,
1500 : AR5K_AR5212_DESC_TX_CTL2_XMIT_TRIES2);
1501 0 : break;
1502 : case 3:
1503 0 : desc->ds_us.tx.ts_rate =
1504 0 : AR5K_REG_MS(tx_desc->tx_control_3,
1505 : AR5K_AR5212_DESC_TX_CTL3_XMIT_RATE3);
1506 0 : desc->ds_us.tx.ts_longretry +=
1507 0 : AR5K_REG_MS(tx_desc->tx_control_2,
1508 : AR5K_AR5212_DESC_TX_CTL2_XMIT_TRIES3);
1509 0 : break;
1510 : }
1511 :
1512 0 : if ((tx_status->tx_status_0 &
1513 0 : AR5K_AR5212_DESC_TX_STATUS0_FRAME_XMIT_OK) == 0) {
1514 0 : if (tx_status->tx_status_0 &
1515 : AR5K_AR5212_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
1516 0 : desc->ds_us.tx.ts_status |= HAL_TXERR_XRETRY;
1517 :
1518 0 : if (tx_status->tx_status_0 &
1519 : AR5K_AR5212_DESC_TX_STATUS0_FIFO_UNDERRUN)
1520 0 : desc->ds_us.tx.ts_status |= HAL_TXERR_FIFO;
1521 :
1522 0 : if (tx_status->tx_status_0 &
1523 : AR5K_AR5212_DESC_TX_STATUS0_FILTERED)
1524 0 : desc->ds_us.tx.ts_status |= HAL_TXERR_FILT;
1525 : }
1526 :
1527 0 : return (HAL_OK);
1528 0 : }
1529 :
1530 : HAL_BOOL
1531 0 : ar5k_ar5212_has_veol(struct ath_hal *hal)
1532 : {
1533 0 : return (AH_TRUE);
1534 : }
1535 :
1536 : /*
1537 : * Receive functions
1538 : */
1539 :
1540 : u_int32_t
1541 0 : ar5k_ar5212_get_rx_buf(struct ath_hal *hal)
1542 : {
1543 0 : return (AR5K_REG_READ(AR5K_AR5212_RXDP));
1544 : }
1545 :
1546 : void
1547 0 : ar5k_ar5212_put_rx_buf(struct ath_hal *hal, u_int32_t phys_addr)
1548 : {
1549 0 : AR5K_REG_WRITE(AR5K_AR5212_RXDP, phys_addr);
1550 0 : }
1551 :
1552 : void
1553 0 : ar5k_ar5212_start_rx(struct ath_hal *hal)
1554 : {
1555 0 : AR5K_REG_WRITE(AR5K_AR5212_CR, AR5K_AR5212_CR_RXE);
1556 0 : }
1557 :
1558 : HAL_BOOL
1559 0 : ar5k_ar5212_stop_rx_dma(struct ath_hal *hal)
1560 : {
1561 : int i;
1562 :
1563 0 : AR5K_REG_WRITE(AR5K_AR5212_CR, AR5K_AR5212_CR_RXD);
1564 :
1565 : /*
1566 : * It may take some time to disable the DMA receive unit
1567 : */
1568 0 : for (i = 2000;
1569 0 : i > 0 && (AR5K_REG_READ(AR5K_AR5212_CR) & AR5K_AR5212_CR_RXE) != 0;
1570 0 : i--)
1571 0 : AR5K_DELAY(10);
1572 :
1573 0 : return (i > 0 ? AH_TRUE : AH_FALSE);
1574 : }
1575 :
1576 : void
1577 0 : ar5k_ar5212_start_rx_pcu(struct ath_hal *hal)
1578 : {
1579 0 : AR5K_REG_DISABLE_BITS(AR5K_AR5212_DIAG_SW, AR5K_AR5212_DIAG_SW_DIS_RX);
1580 0 : }
1581 :
1582 : void
1583 0 : ar5k_ar5212_stop_pcu_recv(struct ath_hal *hal)
1584 : {
1585 0 : AR5K_REG_ENABLE_BITS(AR5K_AR5212_DIAG_SW, AR5K_AR5212_DIAG_SW_DIS_RX);
1586 0 : }
1587 :
1588 : void
1589 0 : ar5k_ar5212_set_mcast_filter(struct ath_hal *hal, u_int32_t filter0,
1590 : u_int32_t filter1)
1591 : {
1592 : /* Set the multicat filter */
1593 0 : AR5K_REG_WRITE(AR5K_AR5212_MCAST_FIL0, filter0);
1594 0 : AR5K_REG_WRITE(AR5K_AR5212_MCAST_FIL1, filter1);
1595 0 : }
1596 :
1597 : HAL_BOOL
1598 0 : ar5k_ar5212_set_mcast_filterindex(struct ath_hal *hal, u_int32_t index)
1599 : {
1600 0 : if (index >= 64) {
1601 0 : return (AH_FALSE);
1602 0 : } else if (index >= 32) {
1603 0 : AR5K_REG_ENABLE_BITS(AR5K_AR5212_MCAST_FIL1,
1604 : (1 << (index - 32)));
1605 0 : } else {
1606 0 : AR5K_REG_ENABLE_BITS(AR5K_AR5212_MCAST_FIL0,
1607 : (1 << index));
1608 : }
1609 :
1610 0 : return (AH_TRUE);
1611 0 : }
1612 :
1613 : HAL_BOOL
1614 0 : ar5k_ar5212_clear_mcast_filter_idx(struct ath_hal *hal, u_int32_t index)
1615 : {
1616 :
1617 0 : if (index >= 64) {
1618 0 : return (AH_FALSE);
1619 0 : } else if (index >= 32) {
1620 0 : AR5K_REG_DISABLE_BITS(AR5K_AR5212_MCAST_FIL1,
1621 : (1 << (index - 32)));
1622 0 : } else {
1623 0 : AR5K_REG_DISABLE_BITS(AR5K_AR5212_MCAST_FIL0,
1624 : (1 << index));
1625 : }
1626 :
1627 0 : return (AH_TRUE);
1628 0 : }
1629 :
1630 : u_int32_t
1631 0 : ar5k_ar5212_get_rx_filter(struct ath_hal *hal)
1632 : {
1633 : u_int32_t data, filter = 0;
1634 :
1635 0 : filter = AR5K_REG_READ(AR5K_AR5212_RX_FILTER);
1636 0 : data = AR5K_REG_READ(AR5K_AR5212_PHY_ERR_FIL);
1637 :
1638 0 : if (data & AR5K_AR5212_PHY_ERR_FIL_RADAR)
1639 0 : filter |= HAL_RX_FILTER_PHYRADAR;
1640 0 : if (data & (AR5K_AR5212_PHY_ERR_FIL_OFDM |
1641 : AR5K_AR5212_PHY_ERR_FIL_CCK))
1642 0 : filter |= HAL_RX_FILTER_PHYERR;
1643 :
1644 0 : return (filter);
1645 : }
1646 :
1647 : void
1648 0 : ar5k_ar5212_set_rx_filter(struct ath_hal *hal, u_int32_t filter)
1649 : {
1650 : u_int32_t data = 0;
1651 :
1652 0 : if (filter & HAL_RX_FILTER_PHYRADAR)
1653 0 : data |= AR5K_AR5212_PHY_ERR_FIL_RADAR;
1654 0 : if (filter & HAL_RX_FILTER_PHYERR)
1655 0 : data |= AR5K_AR5212_PHY_ERR_FIL_OFDM |
1656 : AR5K_AR5212_PHY_ERR_FIL_CCK;
1657 :
1658 0 : if (data) {
1659 0 : AR5K_REG_ENABLE_BITS(AR5K_AR5212_RXCFG,
1660 : AR5K_AR5212_RXCFG_ZLFDMA);
1661 0 : } else {
1662 0 : AR5K_REG_DISABLE_BITS(AR5K_AR5212_RXCFG,
1663 : AR5K_AR5212_RXCFG_ZLFDMA);
1664 : }
1665 :
1666 0 : AR5K_REG_WRITE(AR5K_AR5212_RX_FILTER, filter & 0xff);
1667 0 : AR5K_REG_WRITE(AR5K_AR5212_PHY_ERR_FIL, data);
1668 0 : }
1669 :
1670 : HAL_BOOL
1671 0 : ar5k_ar5212_setup_rx_desc(struct ath_hal *hal, struct ath_desc *desc,
1672 : u_int32_t size, u_int flags)
1673 : {
1674 : struct ar5k_ar5212_rx_desc *rx_desc;
1675 :
1676 0 : rx_desc = (struct ar5k_ar5212_rx_desc*)&desc->ds_ctl0;
1677 :
1678 0 : if ((rx_desc->rx_control_1 = (size &
1679 0 : AR5K_AR5212_DESC_RX_CTL1_BUF_LEN)) != size)
1680 0 : return (AH_FALSE);
1681 :
1682 0 : if (flags & HAL_RXDESC_INTREQ)
1683 0 : rx_desc->rx_control_1 |= AR5K_AR5212_DESC_RX_CTL1_INTREQ;
1684 :
1685 0 : return (AH_TRUE);
1686 0 : }
1687 :
1688 : HAL_STATUS
1689 0 : ar5k_ar5212_proc_rx_desc(struct ath_hal *hal, struct ath_desc *desc,
1690 : u_int32_t phys_addr, struct ath_desc *next)
1691 : {
1692 : struct ar5k_ar5212_rx_status *rx_status;
1693 : struct ar5k_ar5212_rx_error *rx_err;
1694 :
1695 0 : rx_status = (struct ar5k_ar5212_rx_status*)&desc->ds_hw[0];
1696 :
1697 : /* Overlay on error */
1698 0 : rx_err = (struct ar5k_ar5212_rx_error*)&desc->ds_hw[0];
1699 :
1700 : /* No frame received / not ready */
1701 0 : if ((rx_status->rx_status_1 & AR5K_AR5212_DESC_RX_STATUS1_DONE) == 0)
1702 0 : return (HAL_EINPROGRESS);
1703 :
1704 : /*
1705 : * Frame receive status
1706 : */
1707 0 : desc->ds_us.rx.rs_datalen = rx_status->rx_status_0 &
1708 : AR5K_AR5212_DESC_RX_STATUS0_DATA_LEN;
1709 0 : desc->ds_us.rx.rs_rssi =
1710 0 : AR5K_REG_MS(rx_status->rx_status_0,
1711 : AR5K_AR5212_DESC_RX_STATUS0_RECEIVE_SIGNAL);
1712 0 : desc->ds_us.rx.rs_rate =
1713 0 : AR5K_REG_MS(rx_status->rx_status_0,
1714 : AR5K_AR5212_DESC_RX_STATUS0_RECEIVE_RATE);
1715 0 : desc->ds_us.rx.rs_antenna = rx_status->rx_status_0 &
1716 : AR5K_AR5212_DESC_RX_STATUS0_RECEIVE_ANTENNA;
1717 0 : desc->ds_us.rx.rs_more = rx_status->rx_status_0 &
1718 : AR5K_AR5212_DESC_RX_STATUS0_MORE;
1719 0 : desc->ds_us.rx.rs_tstamp =
1720 0 : AR5K_REG_MS(rx_status->rx_status_1,
1721 : AR5K_AR5212_DESC_RX_STATUS1_RECEIVE_TIMESTAMP);
1722 0 : desc->ds_us.rx.rs_status = 0;
1723 :
1724 : /*
1725 : * Key table status
1726 : */
1727 0 : if (rx_status->rx_status_1 &
1728 : AR5K_AR5212_DESC_RX_STATUS1_KEY_INDEX_VALID) {
1729 0 : desc->ds_us.rx.rs_keyix =
1730 0 : AR5K_REG_MS(rx_status->rx_status_1,
1731 : AR5K_AR5212_DESC_RX_STATUS1_KEY_INDEX);
1732 0 : } else {
1733 0 : desc->ds_us.rx.rs_keyix = HAL_RXKEYIX_INVALID;
1734 : }
1735 :
1736 : /*
1737 : * Receive/descriptor errors
1738 : */
1739 0 : if ((rx_status->rx_status_1 &
1740 0 : AR5K_AR5212_DESC_RX_STATUS1_FRAME_RECEIVE_OK) == 0) {
1741 0 : if (rx_status->rx_status_1 &
1742 : AR5K_AR5212_DESC_RX_STATUS1_CRC_ERROR)
1743 0 : desc->ds_us.rx.rs_status |= HAL_RXERR_CRC;
1744 :
1745 0 : if (rx_status->rx_status_1 &
1746 : AR5K_AR5212_DESC_RX_STATUS1_PHY_ERROR) {
1747 0 : desc->ds_us.rx.rs_status |= HAL_RXERR_PHY;
1748 0 : desc->ds_us.rx.rs_phyerr =
1749 0 : AR5K_REG_MS(rx_err->rx_error_1,
1750 : AR5K_AR5212_DESC_RX_ERROR1_PHY_ERROR_CODE);
1751 0 : }
1752 :
1753 0 : if (rx_status->rx_status_1 &
1754 : AR5K_AR5212_DESC_RX_STATUS1_DECRYPT_CRC_ERROR)
1755 0 : desc->ds_us.rx.rs_status |= HAL_RXERR_DECRYPT;
1756 :
1757 0 : if (rx_status->rx_status_1 &
1758 : AR5K_AR5212_DESC_RX_STATUS1_MIC_ERROR)
1759 0 : desc->ds_us.rx.rs_status |= HAL_RXERR_MIC;
1760 : }
1761 :
1762 0 : return (HAL_OK);
1763 0 : }
1764 :
1765 : void
1766 0 : ar5k_ar5212_set_rx_signal(struct ath_hal *hal)
1767 : {
1768 : /* Signal state monitoring is not yet supported */
1769 0 : }
1770 :
1771 : /*
1772 : * Misc functions
1773 : */
1774 :
1775 : void
1776 0 : ar5k_ar5212_dump_state(struct ath_hal *hal)
1777 : {
1778 : #ifdef AR5K_DEBUG
1779 : #define AR5K_PRINT_REGISTER(_x) \
1780 : printf("(%s: %08x) ", #_x, AR5K_REG_READ(AR5K_AR5212_##_x));
1781 :
1782 : printf("MAC registers:\n");
1783 : AR5K_PRINT_REGISTER(CR);
1784 : AR5K_PRINT_REGISTER(CFG);
1785 : AR5K_PRINT_REGISTER(IER);
1786 : AR5K_PRINT_REGISTER(TXCFG);
1787 : AR5K_PRINT_REGISTER(RXCFG);
1788 : AR5K_PRINT_REGISTER(MIBC);
1789 : AR5K_PRINT_REGISTER(TOPS);
1790 : AR5K_PRINT_REGISTER(RXNOFRM);
1791 : AR5K_PRINT_REGISTER(RPGTO);
1792 : AR5K_PRINT_REGISTER(RFCNT);
1793 : AR5K_PRINT_REGISTER(MISC);
1794 : AR5K_PRINT_REGISTER(PISR);
1795 : AR5K_PRINT_REGISTER(SISR0);
1796 : AR5K_PRINT_REGISTER(SISR1);
1797 : AR5K_PRINT_REGISTER(SISR3);
1798 : AR5K_PRINT_REGISTER(SISR4);
1799 : AR5K_PRINT_REGISTER(DCM_ADDR);
1800 : AR5K_PRINT_REGISTER(DCM_DATA);
1801 : AR5K_PRINT_REGISTER(DCCFG);
1802 : AR5K_PRINT_REGISTER(CCFG);
1803 : AR5K_PRINT_REGISTER(CCFG_CUP);
1804 : AR5K_PRINT_REGISTER(CPC0);
1805 : AR5K_PRINT_REGISTER(CPC1);
1806 : AR5K_PRINT_REGISTER(CPC2);
1807 : AR5K_PRINT_REGISTER(CPCORN);
1808 : AR5K_PRINT_REGISTER(QCU_TXE);
1809 : AR5K_PRINT_REGISTER(QCU_TXD);
1810 : AR5K_PRINT_REGISTER(DCU_GBL_IFS_SIFS);
1811 : AR5K_PRINT_REGISTER(DCU_GBL_IFS_SLOT);
1812 : AR5K_PRINT_REGISTER(DCU_FP);
1813 : AR5K_PRINT_REGISTER(DCU_TXP);
1814 : AR5K_PRINT_REGISTER(DCU_TX_FILTER);
1815 : AR5K_PRINT_REGISTER(RC);
1816 : AR5K_PRINT_REGISTER(SCR);
1817 : AR5K_PRINT_REGISTER(INTPEND);
1818 : AR5K_PRINT_REGISTER(PCICFG);
1819 : AR5K_PRINT_REGISTER(GPIOCR);
1820 : AR5K_PRINT_REGISTER(GPIODO);
1821 : AR5K_PRINT_REGISTER(SREV);
1822 : AR5K_PRINT_REGISTER(EEPROM_BASE);
1823 : AR5K_PRINT_REGISTER(EEPROM_DATA);
1824 : AR5K_PRINT_REGISTER(EEPROM_CMD);
1825 : AR5K_PRINT_REGISTER(EEPROM_CFG);
1826 : AR5K_PRINT_REGISTER(PCU_MIN);
1827 : AR5K_PRINT_REGISTER(STA_ID0);
1828 : AR5K_PRINT_REGISTER(STA_ID1);
1829 : AR5K_PRINT_REGISTER(BSS_ID0);
1830 : AR5K_PRINT_REGISTER(SLOT_TIME);
1831 : AR5K_PRINT_REGISTER(TIME_OUT);
1832 : AR5K_PRINT_REGISTER(RSSI_THR);
1833 : AR5K_PRINT_REGISTER(BEACON);
1834 : AR5K_PRINT_REGISTER(CFP_PERIOD);
1835 : AR5K_PRINT_REGISTER(TIMER0);
1836 : AR5K_PRINT_REGISTER(TIMER2);
1837 : AR5K_PRINT_REGISTER(TIMER3);
1838 : AR5K_PRINT_REGISTER(CFP_DUR);
1839 : AR5K_PRINT_REGISTER(MCAST_FIL0);
1840 : AR5K_PRINT_REGISTER(MCAST_FIL1);
1841 : AR5K_PRINT_REGISTER(DIAG_SW);
1842 : AR5K_PRINT_REGISTER(TSF_U32);
1843 : AR5K_PRINT_REGISTER(ADDAC_TEST);
1844 : AR5K_PRINT_REGISTER(DEFAULT_ANTENNA);
1845 : AR5K_PRINT_REGISTER(LAST_TSTP);
1846 : AR5K_PRINT_REGISTER(NAV);
1847 : AR5K_PRINT_REGISTER(RTS_OK);
1848 : AR5K_PRINT_REGISTER(ACK_FAIL);
1849 : AR5K_PRINT_REGISTER(FCS_FAIL);
1850 : AR5K_PRINT_REGISTER(BEACON_CNT);
1851 : AR5K_PRINT_REGISTER(TSF_PARM);
1852 : AR5K_PRINT_REGISTER(RATE_DUR_0);
1853 : AR5K_PRINT_REGISTER(KEYTABLE_0);
1854 : printf("\n");
1855 :
1856 : printf("PHY registers:\n");
1857 : AR5K_PRINT_REGISTER(PHY_TURBO);
1858 : AR5K_PRINT_REGISTER(PHY_AGC);
1859 : AR5K_PRINT_REGISTER(PHY_TIMING_3);
1860 : AR5K_PRINT_REGISTER(PHY_CHIP_ID);
1861 : AR5K_PRINT_REGISTER(PHY_AGCCTL);
1862 : AR5K_PRINT_REGISTER(PHY_NF);
1863 : AR5K_PRINT_REGISTER(PHY_SCR);
1864 : AR5K_PRINT_REGISTER(PHY_SLMT);
1865 : AR5K_PRINT_REGISTER(PHY_SCAL);
1866 : AR5K_PRINT_REGISTER(PHY_RX_DELAY);
1867 : AR5K_PRINT_REGISTER(PHY_IQ);
1868 : AR5K_PRINT_REGISTER(PHY_PAPD_PROBE);
1869 : AR5K_PRINT_REGISTER(PHY_TXPOWER_RATE1);
1870 : AR5K_PRINT_REGISTER(PHY_TXPOWER_RATE2);
1871 : AR5K_PRINT_REGISTER(PHY_FC);
1872 : AR5K_PRINT_REGISTER(PHY_RADAR);
1873 : AR5K_PRINT_REGISTER(PHY_ANT_SWITCH_TABLE_0);
1874 : AR5K_PRINT_REGISTER(PHY_ANT_SWITCH_TABLE_1);
1875 : printf("\n");
1876 : #endif
1877 0 : }
1878 :
1879 : HAL_BOOL
1880 0 : ar5k_ar5212_get_diag_state(struct ath_hal *hal, int id, void **device,
1881 : u_int *size)
1882 : {
1883 : /*
1884 : * We'll ignore this right now. This seems to be some kind of an obscure
1885 : * debugging interface for the binary-only HAL.
1886 : */
1887 0 : return (AH_FALSE);
1888 : }
1889 :
1890 : void
1891 0 : ar5k_ar5212_get_lladdr(struct ath_hal *hal, u_int8_t *mac)
1892 : {
1893 0 : bcopy(hal->ah_sta_id, mac, IEEE80211_ADDR_LEN);
1894 0 : }
1895 :
1896 : HAL_BOOL
1897 0 : ar5k_ar5212_set_lladdr(struct ath_hal *hal, const u_int8_t *mac)
1898 : {
1899 : u_int32_t low_id, high_id;
1900 :
1901 : /* Set new station ID */
1902 0 : bcopy(mac, hal->ah_sta_id, IEEE80211_ADDR_LEN);
1903 :
1904 0 : low_id = AR5K_LOW_ID(mac);
1905 0 : high_id = 0x0000ffff & AR5K_HIGH_ID(mac);
1906 :
1907 0 : AR5K_REG_WRITE(AR5K_AR5212_STA_ID0, low_id);
1908 0 : AR5K_REG_WRITE(AR5K_AR5212_STA_ID1, high_id);
1909 :
1910 0 : return (AH_TRUE);
1911 : }
1912 :
1913 : HAL_BOOL
1914 0 : ar5k_ar5212_set_regdomain(struct ath_hal *hal, u_int16_t regdomain,
1915 : HAL_STATUS *status)
1916 : {
1917 0 : ieee80211_regdomain_t ieee_regdomain;
1918 :
1919 0 : ieee_regdomain = ar5k_regdomain_to_ieee(regdomain);
1920 :
1921 0 : if (ar5k_eeprom_regulation_domain(hal, AH_TRUE,
1922 0 : &ieee_regdomain) == AH_TRUE) {
1923 0 : *status = HAL_OK;
1924 0 : return (AH_TRUE);
1925 : }
1926 :
1927 0 : *status = EIO;
1928 :
1929 0 : return (AH_FALSE);
1930 0 : }
1931 :
1932 : void
1933 0 : ar5k_ar5212_set_ledstate(struct ath_hal *hal, HAL_LED_STATE state)
1934 : {
1935 : u_int32_t led;
1936 :
1937 0 : AR5K_REG_DISABLE_BITS(AR5K_AR5212_PCICFG,
1938 : AR5K_AR5212_PCICFG_LEDMODE | AR5K_AR5212_PCICFG_LED);
1939 :
1940 : /*
1941 : * Some blinking values, define at your wish
1942 : */
1943 0 : switch (state) {
1944 : case IEEE80211_S_SCAN:
1945 : case IEEE80211_S_AUTH:
1946 : led = AR5K_AR5212_PCICFG_LEDMODE_PROP |
1947 : AR5K_AR5212_PCICFG_LED_PEND;
1948 0 : break;
1949 :
1950 : case IEEE80211_S_INIT:
1951 : led = AR5K_AR5212_PCICFG_LEDMODE_PROP |
1952 : AR5K_AR5212_PCICFG_LED_NONE;
1953 0 : break;
1954 :
1955 : case IEEE80211_S_ASSOC:
1956 : case IEEE80211_S_RUN:
1957 : led = AR5K_AR5212_PCICFG_LEDMODE_PROP |
1958 : AR5K_AR5212_PCICFG_LED_ASSOC;
1959 0 : break;
1960 :
1961 : default:
1962 : led = AR5K_AR5212_PCICFG_LEDMODE_PROM |
1963 : AR5K_AR5212_PCICFG_LED_NONE;
1964 0 : break;
1965 : }
1966 :
1967 0 : AR5K_REG_ENABLE_BITS(AR5K_AR5212_PCICFG, led);
1968 0 : }
1969 :
1970 : void
1971 0 : ar5k_ar5212_set_associd(struct ath_hal *hal, const u_int8_t *bssid,
1972 : u_int16_t assoc_id, u_int16_t tim_offset)
1973 : {
1974 : u_int32_t low_id, high_id;
1975 :
1976 : /*
1977 : * Set simple BSSID mask
1978 : */
1979 0 : AR5K_REG_WRITE(AR5K_AR5212_BSS_IDM0, 0xfffffff);
1980 0 : AR5K_REG_WRITE(AR5K_AR5212_BSS_IDM1, 0xfffffff);
1981 :
1982 : /*
1983 : * Set BSSID which triggers the "SME Join" operation
1984 : */
1985 0 : low_id = AR5K_LOW_ID(bssid);
1986 0 : high_id = AR5K_HIGH_ID(bssid);
1987 0 : AR5K_REG_WRITE(AR5K_AR5212_BSS_ID0, low_id);
1988 0 : AR5K_REG_WRITE(AR5K_AR5212_BSS_ID1, high_id |
1989 : ((assoc_id & 0x3fff) << AR5K_AR5212_BSS_ID1_AID_S));
1990 0 : bcopy(bssid, &hal->ah_bssid, IEEE80211_ADDR_LEN);
1991 :
1992 0 : if (assoc_id == 0) {
1993 0 : ar5k_ar5212_disable_pspoll(hal);
1994 0 : return;
1995 : }
1996 :
1997 0 : AR5K_REG_WRITE(AR5K_AR5212_BEACON,
1998 : (AR5K_REG_READ(AR5K_AR5212_BEACON) &
1999 : ~AR5K_AR5212_BEACON_TIM) |
2000 : (((tim_offset ? tim_offset + 4 : 0) <<
2001 : AR5K_AR5212_BEACON_TIM_S) &
2002 : AR5K_AR5212_BEACON_TIM));
2003 :
2004 0 : ar5k_ar5212_enable_pspoll(hal, NULL, 0);
2005 0 : }
2006 :
2007 : HAL_BOOL
2008 0 : ar5k_ar5212_set_bssid_mask(struct ath_hal *hal, const u_int8_t* mask)
2009 : {
2010 : u_int32_t low_id, high_id;
2011 :
2012 0 : low_id = AR5K_LOW_ID(mask);
2013 0 : high_id = 0x0000ffff & AR5K_HIGH_ID(mask);
2014 :
2015 0 : AR5K_REG_WRITE(AR5K_AR5212_BSS_IDM0, low_id);
2016 0 : AR5K_REG_WRITE(AR5K_AR5212_BSS_IDM1, high_id);
2017 :
2018 0 : return (AH_TRUE);
2019 : }
2020 :
2021 : HAL_BOOL
2022 0 : ar5k_ar5212_set_gpio_output(struct ath_hal *hal, u_int32_t gpio)
2023 : {
2024 0 : if (gpio > AR5K_AR5212_NUM_GPIO)
2025 0 : return (AH_FALSE);
2026 :
2027 0 : AR5K_REG_WRITE(AR5K_AR5212_GPIOCR,
2028 : (AR5K_REG_READ(AR5K_AR5212_GPIOCR) &~ AR5K_AR5212_GPIOCR_ALL(gpio))
2029 : | AR5K_AR5212_GPIOCR_ALL(gpio));
2030 :
2031 0 : return (AH_TRUE);
2032 0 : }
2033 :
2034 : HAL_BOOL
2035 0 : ar5k_ar5212_set_gpio_input(struct ath_hal *hal, u_int32_t gpio)
2036 : {
2037 0 : if (gpio > AR5K_AR5212_NUM_GPIO)
2038 0 : return (AH_FALSE);
2039 :
2040 0 : AR5K_REG_WRITE(AR5K_AR5212_GPIOCR,
2041 : (AR5K_REG_READ(AR5K_AR5212_GPIOCR) &~ AR5K_AR5212_GPIOCR_ALL(gpio))
2042 : | AR5K_AR5212_GPIOCR_NONE(gpio));
2043 :
2044 0 : return (AH_TRUE);
2045 0 : }
2046 :
2047 : u_int32_t
2048 0 : ar5k_ar5212_get_gpio(struct ath_hal *hal, u_int32_t gpio)
2049 : {
2050 0 : if (gpio > AR5K_AR5212_NUM_GPIO)
2051 0 : return (0xffffffff);
2052 :
2053 : /* GPIO input magic */
2054 0 : return (((AR5K_REG_READ(AR5K_AR5212_GPIODI) &
2055 0 : AR5K_AR5212_GPIODI_M) >> gpio) & 0x1);
2056 0 : }
2057 :
2058 : HAL_BOOL
2059 0 : ar5k_ar5212_set_gpio(struct ath_hal *hal, u_int32_t gpio, u_int32_t val)
2060 : {
2061 : u_int32_t data;
2062 :
2063 0 : if (gpio > AR5K_AR5212_NUM_GPIO)
2064 0 : return (0xffffffff);
2065 :
2066 : /* GPIO output magic */
2067 0 : data = AR5K_REG_READ(AR5K_AR5212_GPIODO);
2068 :
2069 0 : data &= ~(1 << gpio);
2070 0 : data |= (val&1) << gpio;
2071 :
2072 0 : AR5K_REG_WRITE(AR5K_AR5212_GPIODO, data);
2073 :
2074 0 : return (AH_TRUE);
2075 0 : }
2076 :
2077 : void
2078 0 : ar5k_ar5212_set_gpio_intr(struct ath_hal *hal, u_int gpio,
2079 : u_int32_t interrupt_level)
2080 : {
2081 : u_int32_t data;
2082 :
2083 0 : if (gpio > AR5K_AR5212_NUM_GPIO)
2084 0 : return;
2085 :
2086 : /*
2087 : * Set the GPIO interrupt
2088 : */
2089 0 : data = (AR5K_REG_READ(AR5K_AR5212_GPIOCR) &
2090 0 : ~(AR5K_AR5212_GPIOCR_INT_SEL(gpio) | AR5K_AR5212_GPIOCR_INT_SELH |
2091 0 : AR5K_AR5212_GPIOCR_INT_ENA | AR5K_AR5212_GPIOCR_ALL(gpio))) |
2092 0 : (AR5K_AR5212_GPIOCR_INT_SEL(gpio) | AR5K_AR5212_GPIOCR_INT_ENA);
2093 :
2094 0 : AR5K_REG_WRITE(AR5K_AR5212_GPIOCR,
2095 : interrupt_level ? data : (data | AR5K_AR5212_GPIOCR_INT_SELH));
2096 :
2097 0 : hal->ah_imr |= AR5K_AR5212_PIMR_GPIO;
2098 :
2099 : /* Enable GPIO interrupts */
2100 0 : AR5K_REG_ENABLE_BITS(AR5K_AR5212_PIMR, AR5K_AR5212_PIMR_GPIO);
2101 0 : }
2102 :
2103 : u_int32_t
2104 0 : ar5k_ar5212_get_tsf32(struct ath_hal *hal)
2105 : {
2106 0 : return (AR5K_REG_READ(AR5K_AR5212_TSF_L32));
2107 : }
2108 :
2109 : u_int64_t
2110 0 : ar5k_ar5212_get_tsf64(struct ath_hal *hal)
2111 : {
2112 0 : u_int64_t tsf = AR5K_REG_READ(AR5K_AR5212_TSF_U32);
2113 :
2114 0 : return (AR5K_REG_READ(AR5K_AR5212_TSF_L32) | (tsf << 32));
2115 : }
2116 :
2117 : void
2118 0 : ar5k_ar5212_reset_tsf(struct ath_hal *hal)
2119 : {
2120 0 : AR5K_REG_ENABLE_BITS(AR5K_AR5212_BEACON,
2121 : AR5K_AR5212_BEACON_RESET_TSF);
2122 0 : }
2123 :
2124 : u_int16_t
2125 0 : ar5k_ar5212_get_regdomain(struct ath_hal *hal)
2126 : {
2127 0 : return (ar5k_get_regdomain(hal));
2128 : }
2129 :
2130 : HAL_BOOL
2131 0 : ar5k_ar5212_detect_card_present(struct ath_hal *hal)
2132 : {
2133 0 : u_int16_t magic;
2134 :
2135 : /*
2136 : * Checking the EEPROM's magic value could be an indication
2137 : * if the card is still present. I didn't find another suitable
2138 : * way to do this.
2139 : */
2140 0 : if (ar5k_ar5212_eeprom_read(hal, AR5K_EEPROM_MAGIC, &magic) != 0)
2141 0 : return (AH_FALSE);
2142 :
2143 0 : return (magic == AR5K_EEPROM_MAGIC_VALUE ? AH_TRUE : AH_FALSE);
2144 0 : }
2145 :
2146 : void
2147 0 : ar5k_ar5212_update_mib_counters(struct ath_hal *hal, HAL_MIB_STATS *statistics)
2148 : {
2149 : /* Read-And-Clear */
2150 0 : statistics->ackrcv_bad += AR5K_REG_READ(AR5K_AR5212_ACK_FAIL);
2151 0 : statistics->rts_bad += AR5K_REG_READ(AR5K_AR5212_RTS_FAIL);
2152 0 : statistics->rts_good += AR5K_REG_READ(AR5K_AR5212_RTS_OK);
2153 0 : statistics->fcs_bad += AR5K_REG_READ(AR5K_AR5212_FCS_FAIL);
2154 0 : statistics->beacons += AR5K_REG_READ(AR5K_AR5212_BEACON_CNT);
2155 :
2156 : /* Reset profile count registers */
2157 0 : AR5K_REG_WRITE(AR5K_AR5212_PROFCNT_TX, 0);
2158 0 : AR5K_REG_WRITE(AR5K_AR5212_PROFCNT_RX, 0);
2159 0 : AR5K_REG_WRITE(AR5K_AR5212_PROFCNT_RXCLR, 0);
2160 0 : AR5K_REG_WRITE(AR5K_AR5212_PROFCNT_CYCLE, 0);
2161 0 : }
2162 :
2163 : HAL_RFGAIN
2164 0 : ar5k_ar5212_get_rf_gain(struct ath_hal *hal)
2165 : {
2166 : u_int32_t data, type;
2167 :
2168 0 : if ((hal->ah_rf_banks == NULL) || (!hal->ah_gain.g_active))
2169 0 : return (HAL_RFGAIN_INACTIVE);
2170 :
2171 0 : if (hal->ah_rf_gain != HAL_RFGAIN_READ_REQUESTED)
2172 : goto done;
2173 :
2174 0 : data = AR5K_REG_READ(AR5K_AR5212_PHY_PAPD_PROBE);
2175 :
2176 0 : if (!(data & AR5K_AR5212_PHY_PAPD_PROBE_TX_NEXT)) {
2177 0 : hal->ah_gain.g_current =
2178 0 : data >> AR5K_AR5212_PHY_PAPD_PROBE_GAINF_S;
2179 0 : type = AR5K_REG_MS(data, AR5K_AR5212_PHY_PAPD_PROBE_TYPE);
2180 :
2181 0 : if (type == AR5K_AR5212_PHY_PAPD_PROBE_TYPE_CCK)
2182 0 : hal->ah_gain.g_current += AR5K_GAIN_CCK_PROBE_CORR;
2183 :
2184 0 : if (hal->ah_radio >= AR5K_AR5112) {
2185 0 : ar5k_rfregs_gainf_corr(hal);
2186 0 : hal->ah_gain.g_current =
2187 0 : hal->ah_gain.g_current >= hal->ah_gain.g_f_corr ?
2188 0 : (hal->ah_gain.g_current - hal->ah_gain.g_f_corr) :
2189 : 0;
2190 0 : }
2191 :
2192 0 : if (ar5k_rfregs_gain_readback(hal) &&
2193 0 : AR5K_GAIN_CHECK_ADJUST(&hal->ah_gain) &&
2194 0 : ar5k_rfregs_gain_adjust(hal))
2195 0 : hal->ah_rf_gain = HAL_RFGAIN_NEED_CHANGE;
2196 : }
2197 :
2198 : done:
2199 0 : return (hal->ah_rf_gain);
2200 0 : }
2201 :
2202 : HAL_BOOL
2203 0 : ar5k_ar5212_set_slot_time(struct ath_hal *hal, u_int slot_time)
2204 : {
2205 0 : if (slot_time < HAL_SLOT_TIME_9 || slot_time > HAL_SLOT_TIME_MAX)
2206 0 : return (AH_FALSE);
2207 :
2208 0 : AR5K_REG_WRITE(AR5K_AR5212_DCU_GBL_IFS_SLOT, slot_time);
2209 :
2210 0 : return (AH_TRUE);
2211 0 : }
2212 :
2213 : u_int
2214 0 : ar5k_ar5212_get_slot_time(struct ath_hal *hal)
2215 : {
2216 0 : return (AR5K_REG_READ(AR5K_AR5212_DCU_GBL_IFS_SLOT) & 0xffff);
2217 : }
2218 :
2219 : HAL_BOOL
2220 0 : ar5k_ar5212_set_ack_timeout(struct ath_hal *hal, u_int timeout)
2221 : {
2222 0 : if (ar5k_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_AR5212_TIME_OUT_ACK))
2223 0 : <= timeout)
2224 0 : return (AH_FALSE);
2225 :
2226 0 : AR5K_REG_WRITE_BITS(AR5K_AR5212_TIME_OUT, AR5K_AR5212_TIME_OUT_ACK,
2227 : ar5k_htoclock(timeout));
2228 :
2229 0 : return (AH_TRUE);
2230 0 : }
2231 :
2232 : u_int
2233 0 : ar5k_ar5212_get_ack_timeout(struct ath_hal *hal)
2234 : {
2235 0 : return (ar5k_clocktoh(AR5K_REG_MS(AR5K_REG_READ(AR5K_AR5212_TIME_OUT),
2236 : AR5K_AR5212_TIME_OUT_ACK)));
2237 : }
2238 :
2239 : HAL_BOOL
2240 0 : ar5k_ar5212_set_cts_timeout(struct ath_hal *hal, u_int timeout)
2241 : {
2242 0 : if (ar5k_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_AR5212_TIME_OUT_CTS))
2243 0 : <= timeout)
2244 0 : return (AH_FALSE);
2245 :
2246 0 : AR5K_REG_WRITE_BITS(AR5K_AR5212_TIME_OUT, AR5K_AR5212_TIME_OUT_CTS,
2247 : ar5k_htoclock(timeout));
2248 :
2249 0 : return (AH_TRUE);
2250 0 : }
2251 :
2252 : u_int
2253 0 : ar5k_ar5212_get_cts_timeout(struct ath_hal *hal)
2254 : {
2255 0 : return (ar5k_clocktoh(AR5K_REG_MS(AR5K_REG_READ(AR5K_AR5212_TIME_OUT),
2256 : AR5K_AR5212_TIME_OUT_CTS)));
2257 : }
2258 :
2259 : /*
2260 : * Key table (WEP) functions
2261 : */
2262 :
2263 : HAL_BOOL
2264 0 : ar5k_ar5212_is_cipher_supported(struct ath_hal *hal, HAL_CIPHER cipher)
2265 : {
2266 : /*
2267 : * The AR5212 only supports WEP
2268 : */
2269 0 : if (cipher == HAL_CIPHER_WEP)
2270 0 : return (AH_TRUE);
2271 :
2272 0 : return (AH_FALSE);
2273 0 : }
2274 :
2275 : u_int32_t
2276 0 : ar5k_ar5212_get_keycache_size(struct ath_hal *hal)
2277 : {
2278 0 : return (AR5K_AR5212_KEYCACHE_SIZE);
2279 : }
2280 :
2281 : HAL_BOOL
2282 0 : ar5k_ar5212_reset_key(struct ath_hal *hal, u_int16_t entry)
2283 : {
2284 : int i;
2285 :
2286 0 : AR5K_ASSERT_ENTRY(entry, AR5K_AR5212_KEYTABLE_SIZE);
2287 :
2288 0 : for (i = 0; i < AR5K_AR5212_KEYCACHE_SIZE; i++)
2289 0 : AR5K_REG_WRITE(AR5K_AR5212_KEYTABLE_OFF(entry, i), 0);
2290 :
2291 : /* Set NULL encryption */
2292 0 : AR5K_REG_WRITE(AR5K_AR5212_KEYTABLE_TYPE(entry),
2293 : AR5K_AR5212_KEYTABLE_TYPE_NULL);
2294 :
2295 0 : return (AH_FALSE);
2296 0 : }
2297 :
2298 : HAL_BOOL
2299 0 : ar5k_ar5212_is_key_valid(struct ath_hal *hal, u_int16_t entry)
2300 : {
2301 0 : AR5K_ASSERT_ENTRY(entry, AR5K_AR5212_KEYTABLE_SIZE);
2302 :
2303 : /*
2304 : * Check the validation flag at the end of the entry
2305 : */
2306 0 : if (AR5K_REG_READ(AR5K_AR5212_KEYTABLE_MAC1(entry)) &
2307 : AR5K_AR5212_KEYTABLE_VALID)
2308 0 : return (AH_TRUE);
2309 :
2310 0 : return (AH_FALSE);
2311 0 : }
2312 :
2313 : HAL_BOOL
2314 0 : ar5k_ar5212_set_key(struct ath_hal *hal, u_int16_t entry,
2315 : const HAL_KEYVAL *keyval, const u_int8_t *mac, int xor_notused)
2316 : {
2317 : int i;
2318 0 : u_int32_t key_v[AR5K_AR5212_KEYCACHE_SIZE - 2];
2319 :
2320 0 : AR5K_ASSERT_ENTRY(entry, AR5K_AR5212_KEYTABLE_SIZE);
2321 :
2322 0 : bzero(&key_v, sizeof(key_v));
2323 :
2324 0 : switch (keyval->wk_len) {
2325 : case AR5K_KEYVAL_LENGTH_40:
2326 0 : bcopy(keyval->wk_key, &key_v[0], 4);
2327 0 : bcopy(keyval->wk_key + 4, &key_v[1], 1);
2328 0 : key_v[5] = AR5K_AR5212_KEYTABLE_TYPE_40;
2329 0 : break;
2330 :
2331 : case AR5K_KEYVAL_LENGTH_104:
2332 0 : bcopy(keyval->wk_key, &key_v[0], 4);
2333 0 : bcopy(keyval->wk_key + 4, &key_v[1], 2);
2334 0 : bcopy(keyval->wk_key + 6, &key_v[2], 4);
2335 0 : bcopy(keyval->wk_key + 10, &key_v[3], 2);
2336 0 : bcopy(keyval->wk_key + 12, &key_v[4], 1);
2337 0 : key_v[5] = AR5K_AR5212_KEYTABLE_TYPE_104;
2338 0 : break;
2339 :
2340 : case AR5K_KEYVAL_LENGTH_128:
2341 0 : bcopy(keyval->wk_key, &key_v[0], 4);
2342 0 : bcopy(keyval->wk_key + 4, &key_v[1], 2);
2343 0 : bcopy(keyval->wk_key + 6, &key_v[2], 4);
2344 0 : bcopy(keyval->wk_key + 10, &key_v[3], 2);
2345 0 : bcopy(keyval->wk_key + 12, &key_v[4], 4);
2346 0 : key_v[5] = AR5K_AR5212_KEYTABLE_TYPE_128;
2347 0 : break;
2348 :
2349 : default:
2350 : /* Unsupported key length (not WEP40/104/128) */
2351 0 : return (AH_FALSE);
2352 : }
2353 :
2354 0 : for (i = 0; i < nitems(key_v); i++)
2355 0 : AR5K_REG_WRITE(AR5K_AR5212_KEYTABLE_OFF(entry, i), key_v[i]);
2356 :
2357 0 : return (ar5k_ar5212_set_key_lladdr(hal, entry, mac));
2358 0 : }
2359 :
2360 : HAL_BOOL
2361 0 : ar5k_ar5212_set_key_lladdr(struct ath_hal *hal, u_int16_t entry,
2362 : const u_int8_t *mac)
2363 : {
2364 : u_int32_t low_id, high_id;
2365 : const u_int8_t *mac_v;
2366 :
2367 : /*
2368 : * Invalid entry (key table overflow)
2369 : */
2370 0 : AR5K_ASSERT_ENTRY(entry, AR5K_AR5212_KEYTABLE_SIZE);
2371 :
2372 : /* MAC may be NULL if it's a broadcast key */
2373 0 : mac_v = mac == NULL ? etherbroadcastaddr : mac;
2374 :
2375 0 : low_id = AR5K_LOW_ID(mac_v);
2376 0 : high_id = AR5K_HIGH_ID(mac_v) | AR5K_AR5212_KEYTABLE_VALID;
2377 :
2378 0 : AR5K_REG_WRITE(AR5K_AR5212_KEYTABLE_MAC0(entry), low_id);
2379 0 : AR5K_REG_WRITE(AR5K_AR5212_KEYTABLE_MAC1(entry), high_id);
2380 :
2381 0 : return (AH_TRUE);
2382 0 : }
2383 :
2384 : HAL_BOOL
2385 0 : ar5k_ar5212_softcrypto(struct ath_hal *hal, HAL_BOOL enable)
2386 : {
2387 : u_int32_t bits;
2388 : int i;
2389 :
2390 : bits = AR5K_AR5212_DIAG_SW_DIS_ENC | AR5K_AR5212_DIAG_SW_DIS_DEC;
2391 0 : if (enable == AH_TRUE) {
2392 : /* Disable the hardware crypto engine */
2393 0 : AR5K_REG_ENABLE_BITS(AR5K_AR5212_DIAG_SW, bits);
2394 0 : } else {
2395 : /* Enable the hardware crypto engine */
2396 0 : AR5K_REG_DISABLE_BITS(AR5K_AR5212_DIAG_SW, bits);
2397 : }
2398 :
2399 : /* Reset the key cache */
2400 0 : for (i = 0; i < AR5K_AR5212_KEYTABLE_SIZE; i++)
2401 0 : ar5k_ar5212_reset_key(hal, i);
2402 :
2403 0 : return (AH_TRUE);
2404 : }
2405 :
2406 : /*
2407 : * warm reset MAC and PHY
2408 : */
2409 :
2410 : HAL_BOOL
2411 0 : ar5k_ar5212_warm_reset(struct ath_hal *hal)
2412 : {
2413 : u_int32_t flags;
2414 :
2415 : flags = AR5K_AR5212_RC_PCU | AR5K_AR5212_RC_BB;
2416 0 : if (hal->ah_pci_express == AH_FALSE)
2417 0 : flags |= AR5K_AR5212_RC_PCI;
2418 :
2419 : /* reset chipset and PCI device */
2420 0 : if (ar5k_ar5212_nic_reset(hal, flags) == AH_FALSE)
2421 0 : return (AH_FALSE);
2422 :
2423 : /* wakeup */
2424 0 : if (ar5k_ar5212_set_power(hal,
2425 0 : HAL_PM_AWAKE, AH_TRUE, 0) == AH_FALSE)
2426 0 : return (AH_FALSE);
2427 :
2428 : /* reset chipset */
2429 0 : if (ar5k_ar5212_nic_reset(hal, 0) == AH_FALSE)
2430 0 : return (AH_FALSE);
2431 :
2432 0 : return (AH_TRUE);
2433 0 : }
2434 :
2435 : /*
2436 : * Power management functions
2437 : */
2438 :
2439 : HAL_BOOL
2440 0 : ar5k_ar5212_set_power(struct ath_hal *hal, HAL_POWER_MODE mode,
2441 : HAL_BOOL set_chip, u_int16_t sleep_duration)
2442 : {
2443 : u_int32_t staid;
2444 : int i;
2445 :
2446 0 : staid = AR5K_REG_READ(AR5K_AR5212_STA_ID1);
2447 :
2448 0 : switch (mode) {
2449 : case HAL_PM_AUTO:
2450 0 : staid &= ~AR5K_AR5212_STA_ID1_DEFAULT_ANTENNA;
2451 : /* FALLTHROUGH */
2452 : case HAL_PM_NETWORK_SLEEP:
2453 0 : if (set_chip == AH_TRUE) {
2454 0 : AR5K_REG_WRITE(AR5K_AR5212_SCR,
2455 : AR5K_AR5212_SCR_SLE | sleep_duration);
2456 0 : }
2457 0 : staid |= AR5K_AR5212_STA_ID1_PWR_SV;
2458 0 : break;
2459 :
2460 : case HAL_PM_FULL_SLEEP:
2461 0 : if (set_chip == AH_TRUE)
2462 0 : if (ar5k_ar5212_warm_reset(hal) == AH_FALSE)
2463 0 : return (AH_FALSE);
2464 0 : staid |= AR5K_AR5212_STA_ID1_PWR_SV;
2465 0 : break;
2466 :
2467 : case HAL_PM_AWAKE:
2468 0 : if (set_chip == AH_FALSE)
2469 : goto commit;
2470 :
2471 0 : AR5K_REG_WRITE(AR5K_AR5212_SCR, AR5K_AR5212_SCR_SLE_WAKE);
2472 :
2473 0 : for (i = 5000; i > 0; i--) {
2474 : /* Check if the AR5212 did wake up */
2475 0 : if ((AR5K_REG_READ(AR5K_AR5212_PCICFG) &
2476 0 : AR5K_AR5212_PCICFG_SPWR_DN) == 0)
2477 : break;
2478 :
2479 : /* Wait a bit and retry */
2480 0 : AR5K_DELAY(200);
2481 0 : AR5K_REG_WRITE(AR5K_AR5212_SCR,
2482 : AR5K_AR5212_SCR_SLE_WAKE);
2483 : }
2484 :
2485 : /* Fail if the AR5212 didn't wake up */
2486 0 : if (i <= 0)
2487 0 : return (AH_FALSE);
2488 :
2489 0 : staid &= ~AR5K_AR5212_STA_ID1_PWR_SV;
2490 0 : break;
2491 :
2492 : default:
2493 0 : return (AH_FALSE);
2494 : }
2495 :
2496 : commit:
2497 0 : hal->ah_power_mode = mode;
2498 :
2499 0 : AR5K_REG_WRITE(AR5K_AR5212_STA_ID1, staid);
2500 :
2501 0 : return (AH_TRUE);
2502 0 : }
2503 :
2504 : HAL_POWER_MODE
2505 0 : ar5k_ar5212_get_power_mode(struct ath_hal *hal)
2506 : {
2507 0 : return (hal->ah_power_mode);
2508 : }
2509 :
2510 : HAL_BOOL
2511 0 : ar5k_ar5212_query_pspoll_support(struct ath_hal *hal)
2512 : {
2513 : /* nope */
2514 0 : return (AH_FALSE);
2515 : }
2516 :
2517 : HAL_BOOL
2518 0 : ar5k_ar5212_init_pspoll(struct ath_hal *hal)
2519 : {
2520 : /*
2521 : * Not used on the AR5212
2522 : */
2523 0 : return (AH_FALSE);
2524 : }
2525 :
2526 : HAL_BOOL
2527 0 : ar5k_ar5212_enable_pspoll(struct ath_hal *hal, u_int8_t *bssid,
2528 : u_int16_t assoc_id)
2529 : {
2530 0 : return (AH_FALSE);
2531 : }
2532 :
2533 : HAL_BOOL
2534 0 : ar5k_ar5212_disable_pspoll(struct ath_hal *hal)
2535 : {
2536 0 : return (AH_FALSE);
2537 : }
2538 :
2539 : /*
2540 : * Beacon functions
2541 : */
2542 :
2543 : void
2544 0 : ar5k_ar5212_init_beacon(struct ath_hal *hal, u_int32_t next_beacon,
2545 : u_int32_t interval)
2546 : {
2547 : u_int32_t timer1, timer2, timer3;
2548 :
2549 : /*
2550 : * Set the additional timers by mode
2551 : */
2552 0 : switch (hal->ah_op_mode) {
2553 : case HAL_M_STA:
2554 : timer1 = 0x0000ffff;
2555 : timer2 = 0x0007ffff;
2556 0 : break;
2557 :
2558 : default:
2559 0 : timer1 = (next_beacon - AR5K_TUNE_DMA_BEACON_RESP) <<
2560 : 0x00000003;
2561 0 : timer2 = (next_beacon - AR5K_TUNE_SW_BEACON_RESP) <<
2562 : 0x00000003;
2563 0 : }
2564 :
2565 0 : timer3 = next_beacon +
2566 0 : (hal->ah_atim_window ? hal->ah_atim_window : 1);
2567 :
2568 : /*
2569 : * Enable all timers and set the beacon register
2570 : * (next beacon, DMA beacon, software beacon, ATIM window time)
2571 : */
2572 0 : AR5K_REG_WRITE(AR5K_AR5212_TIMER0, next_beacon);
2573 0 : AR5K_REG_WRITE(AR5K_AR5212_TIMER1, timer1);
2574 0 : AR5K_REG_WRITE(AR5K_AR5212_TIMER2, timer2);
2575 0 : AR5K_REG_WRITE(AR5K_AR5212_TIMER3, timer3);
2576 :
2577 0 : AR5K_REG_WRITE(AR5K_AR5212_BEACON, interval &
2578 : (AR5K_AR5212_BEACON_PERIOD | AR5K_AR5212_BEACON_RESET_TSF |
2579 : AR5K_AR5212_BEACON_ENABLE));
2580 0 : }
2581 :
2582 : void
2583 0 : ar5k_ar5212_set_beacon_timers(struct ath_hal *hal,
2584 : const HAL_BEACON_STATE *state, u_int32_t tsf, u_int32_t dtim_count,
2585 : u_int32_t cfp_count)
2586 : {
2587 : u_int32_t cfp_period, next_cfp, dtim, interval, next_beacon;
2588 :
2589 : /* Return on an invalid beacon state */
2590 0 : if (state->bs_interval < 1)
2591 0 : return;
2592 :
2593 : interval = state->bs_intval;
2594 0 : dtim = state->bs_dtimperiod;
2595 :
2596 : /*
2597 : * PCF support?
2598 : */
2599 0 : if (state->bs_cfp_period > 0) {
2600 : /* Enable CFP mode and set the CFP and timer registers */
2601 0 : cfp_period = state->bs_cfp_period * state->bs_dtim_period *
2602 : state->bs_interval;
2603 0 : next_cfp = (cfp_count * state->bs_dtim_period + dtim_count) *
2604 : state->bs_interval;
2605 :
2606 0 : AR5K_REG_ENABLE_BITS(AR5K_AR5212_STA_ID1,
2607 : AR5K_AR5212_STA_ID1_PCF);
2608 0 : AR5K_REG_WRITE(AR5K_AR5212_CFP_PERIOD, cfp_period);
2609 0 : AR5K_REG_WRITE(AR5K_AR5212_CFP_DUR, state->bs_cfp_max_duration);
2610 0 : AR5K_REG_WRITE(AR5K_AR5212_TIMER2,
2611 : (tsf + (next_cfp == 0 ? cfp_period : next_cfp)) << 3);
2612 0 : } else {
2613 : /* Disable PCF mode */
2614 0 : AR5K_REG_DISABLE_BITS(AR5K_AR5212_STA_ID1,
2615 : AR5K_AR5212_STA_ID1_PCF);
2616 : }
2617 :
2618 : /*
2619 : * Enable the beacon timer register
2620 : */
2621 0 : AR5K_REG_WRITE(AR5K_AR5212_TIMER0, state->bs_next_beacon);
2622 :
2623 : /*
2624 : * Start the beacon timers
2625 : */
2626 0 : AR5K_REG_WRITE(AR5K_AR5212_BEACON,
2627 : (AR5K_REG_READ(AR5K_AR5212_BEACON) &~
2628 : (AR5K_AR5212_BEACON_PERIOD | AR5K_AR5212_BEACON_TIM)) |
2629 : AR5K_REG_SM(state->bs_tim_offset ? state->bs_tim_offset + 4 : 0,
2630 : AR5K_AR5212_BEACON_TIM) | AR5K_REG_SM(state->bs_interval,
2631 : AR5K_AR5212_BEACON_PERIOD));
2632 :
2633 : /*
2634 : * Write new beacon miss threshold, if it appears to be valid
2635 : */
2636 0 : if ((AR5K_AR5212_RSSI_THR_BMISS >> AR5K_AR5212_RSSI_THR_BMISS_S) <
2637 0 : state->bs_bmiss_threshold)
2638 0 : return;
2639 :
2640 0 : AR5K_REG_WRITE_BITS(AR5K_AR5212_RSSI_THR_M,
2641 : AR5K_AR5212_RSSI_THR_BMISS, state->bs_bmiss_threshold);
2642 :
2643 : /*
2644 : * Set sleep registers
2645 : */
2646 0 : if ((state->bs_sleepduration > state->bs_interval) &&
2647 0 : (roundup(state->bs_sleepduration, interval) ==
2648 : state->bs_sleepduration))
2649 0 : interval = state->bs_sleepduration;
2650 :
2651 0 : if (state->bs_sleepduration > dtim &&
2652 0 : (dtim == 0 || roundup(state->bs_sleepduration, dtim) ==
2653 : state->bs_sleepduration))
2654 0 : dtim = state->bs_sleepduration;
2655 :
2656 0 : if (interval > dtim)
2657 0 : return;
2658 :
2659 0 : next_beacon = interval == dtim ?
2660 0 : state->bs_nextdtim: state->bs_nexttbtt;
2661 :
2662 0 : AR5K_REG_WRITE(AR5K_AR5212_SLEEP0,
2663 : AR5K_REG_SM((state->bs_nextdtim - 3) << 3,
2664 : AR5K_AR5212_SLEEP0_NEXT_DTIM) |
2665 : AR5K_REG_SM(10, AR5K_AR5212_SLEEP0_CABTO) |
2666 : AR5K_AR5212_SLEEP0_ENH_SLEEP_EN |
2667 : AR5K_AR5212_SLEEP0_ASSUME_DTIM);
2668 0 : AR5K_REG_WRITE(AR5K_AR5212_SLEEP1,
2669 : AR5K_REG_SM((next_beacon - 3) << 3,
2670 : AR5K_AR5212_SLEEP1_NEXT_TIM) |
2671 : AR5K_REG_SM(10, AR5K_AR5212_SLEEP1_BEACON_TO));
2672 0 : AR5K_REG_WRITE(AR5K_AR5212_SLEEP2,
2673 : AR5K_REG_SM(interval, AR5K_AR5212_SLEEP2_TIM_PER) |
2674 : AR5K_REG_SM(dtim, AR5K_AR5212_SLEEP2_DTIM_PER));
2675 0 : }
2676 :
2677 : void
2678 0 : ar5k_ar5212_reset_beacon(struct ath_hal *hal)
2679 : {
2680 : /*
2681 : * Disable beacon timer
2682 : */
2683 0 : AR5K_REG_WRITE(AR5K_AR5212_TIMER0, 0);
2684 :
2685 : /*
2686 : * Disable some beacon register values
2687 : */
2688 0 : AR5K_REG_DISABLE_BITS(AR5K_AR5212_STA_ID1,
2689 : AR5K_AR5212_STA_ID1_DEFAULT_ANTENNA | AR5K_AR5212_STA_ID1_PCF);
2690 0 : AR5K_REG_WRITE(AR5K_AR5212_BEACON, AR5K_AR5212_BEACON_PERIOD);
2691 0 : }
2692 :
2693 : HAL_BOOL
2694 0 : ar5k_ar5212_wait_for_beacon(struct ath_hal *hal, bus_addr_t phys_addr)
2695 : {
2696 : HAL_BOOL ret;
2697 :
2698 : /*
2699 : * Wait for beaconn queue to be done
2700 : */
2701 0 : ret = ar5k_register_timeout(hal,
2702 : AR5K_AR5212_QCU_STS(HAL_TX_QUEUE_ID_BEACON),
2703 : AR5K_AR5212_QCU_STS_FRMPENDCNT, 0, AH_FALSE);
2704 :
2705 0 : if (AR5K_REG_READ_Q(AR5K_AR5212_QCU_TXE, HAL_TX_QUEUE_ID_BEACON))
2706 0 : return (AH_FALSE);
2707 :
2708 0 : return (ret);
2709 0 : }
2710 :
2711 : /*
2712 : * Interrupt handling
2713 : */
2714 :
2715 : HAL_BOOL
2716 0 : ar5k_ar5212_is_intr_pending(struct ath_hal *hal)
2717 : {
2718 0 : return (AR5K_REG_READ(AR5K_AR5212_INTPEND) == 0 ? AH_FALSE : AH_TRUE);
2719 : }
2720 :
2721 : HAL_BOOL
2722 0 : ar5k_ar5212_get_isr(struct ath_hal *hal, u_int32_t *interrupt_mask)
2723 : {
2724 : u_int32_t data;
2725 :
2726 : /*
2727 : * Read interrupt status from the Read-And-Clear shadow register
2728 : */
2729 0 : data = AR5K_REG_READ(AR5K_AR5212_RAC_PISR);
2730 :
2731 : /*
2732 : * Get abstract interrupt mask (HAL-compatible)
2733 : */
2734 0 : *interrupt_mask = (data & HAL_INT_COMMON) & hal->ah_imr;
2735 :
2736 0 : if (data == HAL_INT_NOCARD)
2737 0 : return (AH_FALSE);
2738 :
2739 0 : if (data & (AR5K_AR5212_PISR_RXOK | AR5K_AR5212_PISR_RXERR))
2740 0 : *interrupt_mask |= HAL_INT_RX;
2741 :
2742 0 : if (data & (AR5K_AR5212_PISR_TXOK | AR5K_AR5212_PISR_TXERR))
2743 0 : *interrupt_mask |= HAL_INT_TX;
2744 :
2745 0 : if (data & (AR5K_AR5212_PISR_HIUERR))
2746 0 : *interrupt_mask |= HAL_INT_FATAL;
2747 :
2748 : /*
2749 : * Special interrupt handling (not caught by the driver)
2750 : */
2751 0 : if (((*interrupt_mask) & AR5K_AR5212_PISR_RXPHY) &&
2752 0 : hal->ah_radar.r_enabled == AH_TRUE)
2753 0 : ar5k_radar_alert(hal);
2754 :
2755 0 : if (*interrupt_mask == 0)
2756 0 : AR5K_PRINTF("0x%08x\n", data);
2757 :
2758 0 : return (AH_TRUE);
2759 0 : }
2760 :
2761 : u_int32_t
2762 0 : ar5k_ar5212_get_intr(struct ath_hal *hal)
2763 : {
2764 : /* Return the interrupt mask stored previously */
2765 0 : return (hal->ah_imr);
2766 : }
2767 :
2768 : HAL_INT
2769 0 : ar5k_ar5212_set_intr(struct ath_hal *hal, HAL_INT new_mask)
2770 : {
2771 : HAL_INT old_mask, int_mask;
2772 :
2773 : /*
2774 : * Disable card interrupts to prevent any race conditions
2775 : * (they will be re-enabled afterwards).
2776 : */
2777 0 : AR5K_REG_WRITE(AR5K_AR5212_IER, AR5K_AR5212_IER_DISABLE);
2778 :
2779 0 : old_mask = hal->ah_imr;
2780 :
2781 : /*
2782 : * Add additional, chipset-dependent interrupt mask flags
2783 : * and write them to the IMR (interrupt mask register).
2784 : */
2785 0 : int_mask = new_mask & HAL_INT_COMMON;
2786 :
2787 0 : if (new_mask & HAL_INT_RX)
2788 0 : int_mask |=
2789 : AR5K_AR5212_PIMR_RXOK |
2790 : AR5K_AR5212_PIMR_RXERR |
2791 : AR5K_AR5212_PIMR_RXORN |
2792 : AR5K_AR5212_PIMR_RXDESC;
2793 :
2794 0 : if (new_mask & HAL_INT_TX)
2795 0 : int_mask |=
2796 : AR5K_AR5212_PIMR_TXOK |
2797 : AR5K_AR5212_PIMR_TXERR |
2798 : AR5K_AR5212_PIMR_TXDESC |
2799 : AR5K_AR5212_PIMR_TXURN;
2800 :
2801 0 : if (new_mask & HAL_INT_FATAL) {
2802 0 : int_mask |= AR5K_AR5212_PIMR_HIUERR;
2803 0 : AR5K_REG_ENABLE_BITS(AR5K_AR5212_SIMR2,
2804 : AR5K_AR5212_SIMR2_MCABT |
2805 : AR5K_AR5212_SIMR2_SSERR |
2806 : AR5K_AR5212_SIMR2_DPERR);
2807 0 : }
2808 :
2809 0 : AR5K_REG_WRITE(AR5K_AR5212_PIMR, int_mask);
2810 :
2811 : /* Store new interrupt mask */
2812 0 : hal->ah_imr = new_mask;
2813 :
2814 : /* ..re-enable interrupts */
2815 0 : AR5K_REG_WRITE(AR5K_AR5212_IER, AR5K_AR5212_IER_ENABLE);
2816 :
2817 0 : return (old_mask);
2818 : }
2819 :
2820 : /*
2821 : * Misc internal functions
2822 : */
2823 :
2824 : HAL_BOOL
2825 0 : ar5k_ar5212_get_capabilities(struct ath_hal *hal)
2826 : {
2827 : u_int16_t ee_header;
2828 : u_int a, b, g;
2829 :
2830 : /* Capabilities stored in the EEPROM */
2831 0 : ee_header = hal->ah_capabilities.cap_eeprom.ee_header;
2832 :
2833 0 : a = AR5K_EEPROM_HDR_11A(ee_header);
2834 0 : b = AR5K_EEPROM_HDR_11B(ee_header);
2835 0 : g = AR5K_EEPROM_HDR_11G(ee_header);
2836 :
2837 : /*
2838 : * If the EEPROM is not reporting any mode, we try 11b.
2839 : * This might fix a few broken devices with invalid EEPROM.
2840 : */
2841 0 : if (!a && !b && !g)
2842 0 : b = 1;
2843 :
2844 : /*
2845 : * XXX The AR5212 tranceiver supports frequencies from 4920 to 6100GHz
2846 : * XXX and from 2312 to 2732GHz. There are problems with the current
2847 : * XXX ieee80211 implementation because the IEEE channel mapping
2848 : * XXX does not support negative channel numbers (2312MHz is channel
2849 : * XXX -19). Of course, this doesn't matter because these channels
2850 : * XXX are out of range but some regulation domains like MKK (Japan)
2851 : * XXX will support frequencies somewhere around 4.8GHz.
2852 : */
2853 :
2854 : /*
2855 : * Set radio capabilities
2856 : */
2857 :
2858 0 : if (a) {
2859 0 : hal->ah_capabilities.cap_range.range_5ghz_min = 5005; /* 4920 */
2860 0 : hal->ah_capabilities.cap_range.range_5ghz_max = 6100;
2861 :
2862 : /* Set supported modes */
2863 0 : hal->ah_capabilities.cap_mode =
2864 : HAL_MODE_11A | HAL_MODE_TURBO | HAL_MODE_XR;
2865 0 : }
2866 :
2867 : /* This chip will support 802.11b if the 2GHz radio is connected */
2868 0 : if (b || g) {
2869 0 : hal->ah_capabilities.cap_range.range_2ghz_min = 2412; /* 2312 */
2870 0 : hal->ah_capabilities.cap_range.range_2ghz_max = 2732;
2871 :
2872 0 : if (b)
2873 0 : hal->ah_capabilities.cap_mode |= HAL_MODE_11B;
2874 : #if 0
2875 : if (g)
2876 : hal->ah_capabilities.cap_mode |= HAL_MODE_11G;
2877 : #endif
2878 : }
2879 :
2880 : /* GPIO */
2881 0 : hal->ah_gpio_npins = AR5K_AR5212_NUM_GPIO;
2882 :
2883 : /* Set number of supported TX queues */
2884 0 : hal->ah_capabilities.cap_queues.q_tx_num = AR5K_AR5212_TX_NUM_QUEUES;
2885 :
2886 0 : return (AH_TRUE);
2887 : }
2888 :
2889 : void
2890 0 : ar5k_ar5212_radar_alert(struct ath_hal *hal, HAL_BOOL enable)
2891 : {
2892 : /*
2893 : * Enable radar detection
2894 : */
2895 0 : AR5K_REG_WRITE(AR5K_AR5212_IER, AR5K_AR5212_IER_DISABLE);
2896 :
2897 0 : if (enable == AH_TRUE) {
2898 0 : AR5K_REG_WRITE(AR5K_AR5212_PHY_RADAR,
2899 : AR5K_AR5212_PHY_RADAR_ENABLE);
2900 0 : AR5K_REG_ENABLE_BITS(AR5K_AR5212_PIMR,
2901 : AR5K_AR5212_PIMR_RXPHY);
2902 0 : } else {
2903 0 : AR5K_REG_WRITE(AR5K_AR5212_PHY_RADAR,
2904 : AR5K_AR5212_PHY_RADAR_DISABLE);
2905 0 : AR5K_REG_DISABLE_BITS(AR5K_AR5212_PIMR,
2906 : AR5K_AR5212_PIMR_RXPHY);
2907 : }
2908 :
2909 0 : AR5K_REG_WRITE(AR5K_AR5212_IER, AR5K_AR5212_IER_ENABLE);
2910 0 : }
2911 :
2912 : /*
2913 : * EEPROM access functions
2914 : */
2915 :
2916 : HAL_BOOL
2917 0 : ar5k_ar5212_eeprom_is_busy(struct ath_hal *hal)
2918 : {
2919 0 : return (AR5K_REG_READ(AR5K_AR5212_CFG) & AR5K_AR5212_CFG_EEBS ?
2920 : AH_TRUE : AH_FALSE);
2921 : }
2922 :
2923 : int
2924 0 : ar5k_ar5212_eeprom_read(struct ath_hal *hal, u_int32_t offset, u_int16_t *data)
2925 : {
2926 : u_int32_t status, i;
2927 :
2928 : /*
2929 : * Initialize EEPROM access
2930 : */
2931 0 : AR5K_REG_WRITE(AR5K_AR5212_EEPROM_BASE, (u_int8_t)offset);
2932 0 : AR5K_REG_ENABLE_BITS(AR5K_AR5212_EEPROM_CMD,
2933 : AR5K_AR5212_EEPROM_CMD_READ);
2934 :
2935 0 : for (i = AR5K_TUNE_REGISTER_TIMEOUT; i > 0; i--) {
2936 0 : status = AR5K_REG_READ(AR5K_AR5212_EEPROM_STATUS);
2937 0 : if (status & AR5K_AR5212_EEPROM_STAT_RDDONE) {
2938 0 : if (status & AR5K_AR5212_EEPROM_STAT_RDERR)
2939 0 : return (EIO);
2940 0 : *data = (u_int16_t)
2941 0 : (AR5K_REG_READ(AR5K_AR5212_EEPROM_DATA) & 0xffff);
2942 0 : return (0);
2943 : }
2944 0 : AR5K_DELAY(15);
2945 : }
2946 :
2947 0 : return (ETIMEDOUT);
2948 0 : }
2949 :
2950 : int
2951 0 : ar5k_ar5212_eeprom_write(struct ath_hal *hal, u_int32_t offset, u_int16_t data)
2952 : {
2953 : u_int32_t status, timeout;
2954 :
2955 : /* Enable eeprom access */
2956 0 : AR5K_REG_ENABLE_BITS(AR5K_AR5212_EEPROM_CMD,
2957 : AR5K_AR5212_EEPROM_CMD_RESET);
2958 0 : AR5K_REG_ENABLE_BITS(AR5K_AR5212_EEPROM_CMD,
2959 : AR5K_AR5212_EEPROM_CMD_WRITE);
2960 :
2961 : /*
2962 : * Prime write pump
2963 : */
2964 0 : AR5K_REG_WRITE(AR5K_AR5212_EEPROM_BASE, (u_int8_t)offset - 1);
2965 :
2966 0 : for (timeout = 10000; timeout > 0; timeout--) {
2967 0 : AR5K_DELAY(1);
2968 0 : status = AR5K_REG_READ(AR5K_AR5212_EEPROM_STATUS);
2969 0 : if (status & AR5K_AR5212_EEPROM_STAT_WRDONE) {
2970 0 : if (status & AR5K_AR5212_EEPROM_STAT_WRERR)
2971 0 : return (EIO);
2972 0 : return (0);
2973 : }
2974 : }
2975 :
2976 0 : return (ETIMEDOUT);
2977 0 : }
2978 :
2979 : /*
2980 : * TX power setup
2981 : */
2982 :
2983 : HAL_BOOL
2984 0 : ar5k_ar5212_txpower(struct ath_hal *hal, HAL_CHANNEL *channel, u_int txpower)
2985 : {
2986 0 : HAL_BOOL tpc = hal->ah_txpower.txp_tpc;
2987 : int i;
2988 :
2989 0 : if (txpower > AR5K_TUNE_MAX_TXPOWER) {
2990 0 : AR5K_PRINTF("invalid tx power: %u\n", txpower);
2991 0 : return (AH_FALSE);
2992 : }
2993 :
2994 : /* Reset TX power values */
2995 0 : bzero(&hal->ah_txpower, sizeof(hal->ah_txpower));
2996 0 : hal->ah_txpower.txp_tpc = tpc;
2997 :
2998 : /* Initialize TX power table */
2999 0 : ar5k_txpower_table(hal, channel, txpower);
3000 :
3001 : /*
3002 : * Write TX power values
3003 : */
3004 0 : for (i = 0; i < (AR5K_EEPROM_POWER_TABLE_SIZE / 2); i++) {
3005 0 : AR5K_REG_WRITE(AR5K_AR5212_PHY_PCDAC_TXPOWER(i),
3006 : ((((hal->ah_txpower.txp_pcdac[(i << 1) + 1] << 8) | 0xff) &
3007 : 0xffff) << 16) | (((hal->ah_txpower.txp_pcdac[i << 1] << 8)
3008 : | 0xff) & 0xffff));
3009 : }
3010 :
3011 0 : AR5K_REG_WRITE(AR5K_AR5212_PHY_TXPOWER_RATE1,
3012 : AR5K_TXPOWER_OFDM(3, 24) | AR5K_TXPOWER_OFDM(2, 16)
3013 : | AR5K_TXPOWER_OFDM(1, 8) | AR5K_TXPOWER_OFDM(0, 0));
3014 :
3015 0 : AR5K_REG_WRITE(AR5K_AR5212_PHY_TXPOWER_RATE2,
3016 : AR5K_TXPOWER_OFDM(7, 24) | AR5K_TXPOWER_OFDM(6, 16)
3017 : | AR5K_TXPOWER_OFDM(5, 8) | AR5K_TXPOWER_OFDM(4, 0));
3018 :
3019 0 : AR5K_REG_WRITE(AR5K_AR5212_PHY_TXPOWER_RATE3,
3020 : AR5K_TXPOWER_CCK(10, 24) | AR5K_TXPOWER_CCK(9, 16)
3021 : | AR5K_TXPOWER_CCK(15, 8) | AR5K_TXPOWER_CCK(8, 0));
3022 :
3023 0 : AR5K_REG_WRITE(AR5K_AR5212_PHY_TXPOWER_RATE4,
3024 : AR5K_TXPOWER_CCK(14, 24) | AR5K_TXPOWER_CCK(13, 16)
3025 : | AR5K_TXPOWER_CCK(12, 8) | AR5K_TXPOWER_CCK(11, 0));
3026 :
3027 0 : if (hal->ah_txpower.txp_tpc == AH_TRUE) {
3028 0 : AR5K_REG_WRITE(AR5K_AR5212_PHY_TXPOWER_RATE_MAX,
3029 : AR5K_AR5212_PHY_TXPOWER_RATE_MAX_TPC_ENABLE |
3030 : AR5K_TUNE_MAX_TXPOWER);
3031 0 : } else {
3032 0 : AR5K_REG_WRITE(AR5K_AR5212_PHY_TXPOWER_RATE_MAX,
3033 : AR5K_AR5212_PHY_TXPOWER_RATE_MAX |
3034 : AR5K_TUNE_MAX_TXPOWER);
3035 : }
3036 :
3037 0 : return (AH_TRUE);
3038 0 : }
3039 :
3040 : HAL_BOOL
3041 0 : ar5k_ar5212_set_txpower_limit(struct ath_hal *hal, u_int power)
3042 : {
3043 0 : HAL_CHANNEL *channel = &hal->ah_current_channel;
3044 :
3045 0 : AR5K_PRINTF("changing txpower to %d\n", power);
3046 0 : return (ar5k_ar5212_txpower(hal, channel, power));
3047 : }
|