Annotation of sys/dev/ic/ar5210.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: ar5210.c,v 1.39 2007/04/10 17:47:55 miod 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 AR5000 Wireless LAN chipset
21: * (AR5210 + AR5110).
22: */
23:
24: #include <dev/ic/ar5xxx.h>
25: #include <dev/ic/ar5210reg.h>
26: #include <dev/ic/ar5210var.h>
27:
28: HAL_BOOL ar5k_ar5210_nic_reset(struct ath_hal *, u_int32_t);
29: HAL_BOOL ar5k_ar5210_nic_wakeup(struct ath_hal *, HAL_BOOL, HAL_BOOL);
30: void ar5k_ar5210_init_tx_queue(struct ath_hal *, u_int, HAL_BOOL);
31: const void ar5k_ar5210_fill(struct ath_hal *);
32: HAL_BOOL ar5k_ar5210_do_calibrate(struct ath_hal *, HAL_CHANNEL *);
33: HAL_BOOL ar5k_ar5210_noise_floor(struct ath_hal *, HAL_CHANNEL *);
34:
35: /*
36: * Initial register setting for the AR5210
37: */
38: static const struct ar5k_ini ar5210_ini[] =
39: AR5K_AR5210_INI;
40:
41: AR5K_HAL_FUNCTIONS(extern, ar5k_ar5210,);
42:
43: const void
44: ar5k_ar5210_fill(struct ath_hal *hal)
45: {
46: hal->ah_magic = AR5K_AR5210_MAGIC;
47:
48: /*
49: * Init/Exit functions
50: */
51: AR5K_HAL_FUNCTION(hal, ar5210, get_rate_table);
52: AR5K_HAL_FUNCTION(hal, ar5210, detach);
53:
54: /*
55: * Reset functions
56: */
57: AR5K_HAL_FUNCTION(hal, ar5210, reset);
58: AR5K_HAL_FUNCTION(hal, ar5210, set_opmode);
59: AR5K_HAL_FUNCTION(hal, ar5210, calibrate);
60:
61: /*
62: * TX functions
63: */
64: AR5K_HAL_FUNCTION(hal, ar5210, update_tx_triglevel);
65: AR5K_HAL_FUNCTION(hal, ar5210, setup_tx_queue);
66: AR5K_HAL_FUNCTION(hal, ar5210, setup_tx_queueprops);
67: AR5K_HAL_FUNCTION(hal, ar5210, release_tx_queue);
68: AR5K_HAL_FUNCTION(hal, ar5210, reset_tx_queue);
69: AR5K_HAL_FUNCTION(hal, ar5210, get_tx_buf);
70: AR5K_HAL_FUNCTION(hal, ar5210, put_tx_buf);
71: AR5K_HAL_FUNCTION(hal, ar5210, tx_start);
72: AR5K_HAL_FUNCTION(hal, ar5210, stop_tx_dma);
73: AR5K_HAL_FUNCTION(hal, ar5210, setup_tx_desc);
74: AR5K_HAL_FUNCTION(hal, ar5210, setup_xtx_desc);
75: AR5K_HAL_FUNCTION(hal, ar5210, fill_tx_desc);
76: AR5K_HAL_FUNCTION(hal, ar5210, proc_tx_desc);
77: AR5K_HAL_FUNCTION(hal, ar5210, has_veol);
78:
79: /*
80: * RX functions
81: */
82: AR5K_HAL_FUNCTION(hal, ar5210, get_rx_buf);
83: AR5K_HAL_FUNCTION(hal, ar5210, put_rx_buf);
84: AR5K_HAL_FUNCTION(hal, ar5210, start_rx);
85: AR5K_HAL_FUNCTION(hal, ar5210, stop_rx_dma);
86: AR5K_HAL_FUNCTION(hal, ar5210, start_rx_pcu);
87: AR5K_HAL_FUNCTION(hal, ar5210, stop_pcu_recv);
88: AR5K_HAL_FUNCTION(hal, ar5210, set_mcast_filter);
89: AR5K_HAL_FUNCTION(hal, ar5210, set_mcast_filterindex);
90: AR5K_HAL_FUNCTION(hal, ar5210, clear_mcast_filter_idx);
91: AR5K_HAL_FUNCTION(hal, ar5210, get_rx_filter);
92: AR5K_HAL_FUNCTION(hal, ar5210, set_rx_filter);
93: AR5K_HAL_FUNCTION(hal, ar5210, setup_rx_desc);
94: AR5K_HAL_FUNCTION(hal, ar5210, proc_rx_desc);
95: AR5K_HAL_FUNCTION(hal, ar5210, set_rx_signal);
96:
97: /*
98: * Misc functions
99: */
100: AR5K_HAL_FUNCTION(hal, ar5210, dump_state);
101: AR5K_HAL_FUNCTION(hal, ar5210, get_diag_state);
102: AR5K_HAL_FUNCTION(hal, ar5210, get_lladdr);
103: AR5K_HAL_FUNCTION(hal, ar5210, set_lladdr);
104: AR5K_HAL_FUNCTION(hal, ar5210, set_regdomain);
105: AR5K_HAL_FUNCTION(hal, ar5210, set_ledstate);
106: AR5K_HAL_FUNCTION(hal, ar5210, set_associd);
107: AR5K_HAL_FUNCTION(hal, ar5210, set_gpio_input);
108: AR5K_HAL_FUNCTION(hal, ar5210, set_gpio_output);
109: AR5K_HAL_FUNCTION(hal, ar5210, get_gpio);
110: AR5K_HAL_FUNCTION(hal, ar5210, set_gpio);
111: AR5K_HAL_FUNCTION(hal, ar5210, set_gpio_intr);
112: AR5K_HAL_FUNCTION(hal, ar5210, get_tsf32);
113: AR5K_HAL_FUNCTION(hal, ar5210, get_tsf64);
114: AR5K_HAL_FUNCTION(hal, ar5210, reset_tsf);
115: AR5K_HAL_FUNCTION(hal, ar5210, get_regdomain);
116: AR5K_HAL_FUNCTION(hal, ar5210, detect_card_present);
117: AR5K_HAL_FUNCTION(hal, ar5210, update_mib_counters);
118: AR5K_HAL_FUNCTION(hal, ar5210, get_rf_gain);
119: AR5K_HAL_FUNCTION(hal, ar5210, set_slot_time);
120: AR5K_HAL_FUNCTION(hal, ar5210, get_slot_time);
121: AR5K_HAL_FUNCTION(hal, ar5210, set_ack_timeout);
122: AR5K_HAL_FUNCTION(hal, ar5210, get_ack_timeout);
123: AR5K_HAL_FUNCTION(hal, ar5210, set_cts_timeout);
124: AR5K_HAL_FUNCTION(hal, ar5210, get_cts_timeout);
125:
126: /*
127: * Key table (WEP) functions
128: */
129: AR5K_HAL_FUNCTION(hal, ar5210, is_cipher_supported);
130: AR5K_HAL_FUNCTION(hal, ar5210, get_keycache_size);
131: AR5K_HAL_FUNCTION(hal, ar5210, reset_key);
132: AR5K_HAL_FUNCTION(hal, ar5210, is_key_valid);
133: AR5K_HAL_FUNCTION(hal, ar5210, set_key);
134: AR5K_HAL_FUNCTION(hal, ar5210, set_key_lladdr);
135:
136: /*
137: * Power management functions
138: */
139: AR5K_HAL_FUNCTION(hal, ar5210, set_power);
140: AR5K_HAL_FUNCTION(hal, ar5210, get_power_mode);
141: AR5K_HAL_FUNCTION(hal, ar5210, query_pspoll_support);
142: AR5K_HAL_FUNCTION(hal, ar5210, init_pspoll);
143: AR5K_HAL_FUNCTION(hal, ar5210, enable_pspoll);
144: AR5K_HAL_FUNCTION(hal, ar5210, disable_pspoll);
145:
146: /*
147: * Beacon functions
148: */
149: AR5K_HAL_FUNCTION(hal, ar5210, init_beacon);
150: AR5K_HAL_FUNCTION(hal, ar5210, set_beacon_timers);
151: AR5K_HAL_FUNCTION(hal, ar5210, reset_beacon);
152: AR5K_HAL_FUNCTION(hal, ar5210, wait_for_beacon);
153:
154: /*
155: * Interrupt functions
156: */
157: AR5K_HAL_FUNCTION(hal, ar5210, is_intr_pending);
158: AR5K_HAL_FUNCTION(hal, ar5210, get_isr);
159: AR5K_HAL_FUNCTION(hal, ar5210, get_intr);
160: AR5K_HAL_FUNCTION(hal, ar5210, set_intr);
161:
162: /*
163: * Chipset functions (ar5k-specific, non-HAL)
164: */
165: AR5K_HAL_FUNCTION(hal, ar5210, get_capabilities);
166: AR5K_HAL_FUNCTION(hal, ar5210, radar_alert);
167:
168: /*
169: * EEPROM access
170: */
171: AR5K_HAL_FUNCTION(hal, ar5210, eeprom_is_busy);
172: AR5K_HAL_FUNCTION(hal, ar5210, eeprom_read);
173: AR5K_HAL_FUNCTION(hal, ar5210, eeprom_write);
174:
175: /*
176: * Unused functions or functions not implemented
177: */
178: AR5K_HAL_FUNCTION(hal, ar5210, set_bssid_mask);
179: AR5K_HAL_FUNCTION(hal, ar5210, get_tx_queueprops);
180: AR5K_HAL_FUNCTION(hal, ar5210, num_tx_pending);
181: AR5K_HAL_FUNCTION(hal, ar5210, phy_disable);
182: AR5K_HAL_FUNCTION(hal, ar5210, set_txpower_limit);
183: AR5K_HAL_FUNCTION(hal, ar5210, set_def_antenna);
184: AR5K_HAL_FUNCTION(hal, ar5210, get_def_antenna);
185: #ifdef notyet
186: AR5K_HAL_FUNCTION(hal, ar5210, set_capability);
187: AR5K_HAL_FUNCTION(hal, ar5210, proc_mib_event);
188: AR5K_HAL_FUNCTION(hal, ar5210, get_tx_inter_queue);
189: #endif
190: }
191:
192: struct ath_hal *
193: ar5k_ar5210_attach(u_int16_t device, void *sc, bus_space_tag_t st,
194: bus_space_handle_t sh, int *status)
195: {
196: int i;
197: struct ath_hal *hal = (struct ath_hal*) sc;
198: u_int8_t mac[IEEE80211_ADDR_LEN];
199: u_int32_t srev;
200:
201: ar5k_ar5210_fill(hal);
202:
203: /* Bring device out of sleep and reset its units */
204: if (ar5k_ar5210_nic_wakeup(hal, AH_FALSE, AH_TRUE) != AH_TRUE)
205: return (NULL);
206:
207: /* Get MAC, PHY and RADIO revisions */
208: srev = AR5K_REG_READ(AR5K_AR5210_SREV);
209: hal->ah_mac_srev = srev;
210: hal->ah_mac_version = AR5K_REG_MS(srev, AR5K_AR5210_SREV_VER);
211: hal->ah_mac_revision = AR5K_REG_MS(srev, AR5K_AR5210_SREV_REV);
212: hal->ah_phy_revision = AR5K_REG_READ(AR5K_AR5210_PHY_CHIP_ID) &
213: 0x00ffffffff;
214:
215: /* ...wait until PHY is ready and read RADIO revision */
216: AR5K_REG_WRITE(AR5K_AR5210_PHY(0x34), 0x00001c16);
217: for (i = 0; i < 4; i++)
218: AR5K_REG_WRITE(AR5K_AR5210_PHY(0x20), 0x00010000);
219: hal->ah_radio_5ghz_revision = (u_int16_t)
220: (ar5k_bitswap((AR5K_REG_READ(AR5K_AR5210_PHY(256) >> 28) & 0xf), 4)
221: + 1);
222: hal->ah_radio_2ghz_revision = 0;
223:
224: /* Identify the chipset */
225: hal->ah_version = AR5K_AR5210;
226: hal->ah_radio = AR5K_AR5110;
227: hal->ah_phy = AR5K_AR5210_PHY(0);
228:
229: bcopy(etherbroadcastaddr, mac, IEEE80211_ADDR_LEN);
230: ar5k_ar5210_set_associd(hal, mac, 0, 0);
231: ar5k_ar5210_get_lladdr(hal, mac);
232: ar5k_ar5210_set_opmode(hal);
233:
234: return (hal);
235: }
236:
237: HAL_BOOL
238: ar5k_ar5210_nic_reset(struct ath_hal *hal, u_int32_t val)
239: {
240: HAL_BOOL ret = AH_FALSE;
241: u_int32_t mask = val ? val : ~0;
242:
243: /*
244: * Reset the device and wait until success
245: */
246: AR5K_REG_WRITE(AR5K_AR5210_RC, val);
247:
248: /* Wait at least 128 PCI clocks */
249: AR5K_DELAY(15);
250:
251: val &=
252: AR5K_AR5210_RC_PCU | AR5K_AR5210_RC_MAC |
253: AR5K_AR5210_RC_PHY | AR5K_AR5210_RC_DMA;
254:
255: mask &=
256: AR5K_AR5210_RC_PCU | AR5K_AR5210_RC_MAC |
257: AR5K_AR5210_RC_PHY | AR5K_AR5210_RC_DMA;
258:
259: ret = ar5k_register_timeout(hal, AR5K_AR5210_RC, mask, val, AH_FALSE);
260:
261: /*
262: * Reset configuration register
263: */
264: if ((val & AR5K_AR5210_RC_MAC) == 0) {
265: AR5K_REG_WRITE(AR5K_AR5210_CFG, AR5K_AR5210_INIT_CFG);
266: }
267:
268: return (ret);
269: }
270:
271: HAL_BOOL
272: ar5k_ar5210_nic_wakeup(struct ath_hal *hal, HAL_BOOL turbo, HAL_BOOL initial)
273: {
274: /*
275: * Reset and wakeup the device
276: */
277:
278: if (initial == AH_TRUE) {
279: /* ...reset hardware */
280: if (ar5k_ar5210_nic_reset(hal,
281: AR5K_AR5210_RC_PCI) == AH_FALSE) {
282: AR5K_PRINT("failed to reset the PCI chipset\n");
283: return (AH_FALSE);
284: }
285:
286: AR5K_DELAY(1000);
287: }
288:
289: /* ...wakeup the device */
290: if (ar5k_ar5210_set_power(hal,
291: HAL_PM_AWAKE, AH_TRUE, 0) == AH_FALSE) {
292: AR5K_PRINT("failed to resume the AR5210 chipset\n");
293: return (AH_FALSE);
294: }
295:
296: /* ...enable Atheros turbo mode if requested */
297: AR5K_REG_WRITE(AR5K_AR5210_PHY_FC,
298: turbo == AH_TRUE ? AR5K_AR5210_PHY_FC_TURBO_MODE : 0);
299:
300: /* ...reset chipset */
301: if (ar5k_ar5210_nic_reset(hal, AR5K_AR5210_RC_CHIP) == AH_FALSE) {
302: AR5K_PRINT("failed to reset the AR5210 chipset\n");
303: return (AH_FALSE);
304: }
305:
306: AR5K_DELAY(1000);
307:
308: /* ...reset chipset and PCI device */
309: if (ar5k_ar5210_nic_reset(hal,
310: AR5K_AR5210_RC_CHIP | AR5K_AR5210_RC_PCI) == AH_FALSE) {
311: AR5K_PRINT("failed to reset the AR5210 + PCI chipset\n");
312: return (AH_FALSE);
313: }
314:
315: AR5K_DELAY(2300);
316:
317: /* ...wakeup (again) */
318: if (ar5k_ar5210_set_power(hal,
319: HAL_PM_AWAKE, AH_TRUE, 0) == AH_FALSE) {
320: AR5K_PRINT("failed to resume the AR5210 (again)\n");
321: return (AH_FALSE);
322: }
323:
324: /* ...final warm reset */
325: if (ar5k_ar5210_nic_reset(hal, 0) == AH_FALSE) {
326: AR5K_PRINT("failed to warm reset the AR5210\n");
327: return (AH_FALSE);
328: }
329:
330: return (AH_TRUE);
331: }
332:
333: const HAL_RATE_TABLE *
334: ar5k_ar5210_get_rate_table(struct ath_hal *hal, u_int mode)
335: {
336: switch (mode) {
337: case HAL_MODE_11A:
338: return (&hal->ah_rt_11a);
339: case HAL_MODE_TURBO:
340: return (&hal->ah_rt_turbo);
341: case HAL_MODE_11B:
342: case HAL_MODE_11G:
343: default:
344: return (NULL);
345: }
346:
347: return (NULL);
348: }
349:
350: void
351: ar5k_ar5210_detach(struct ath_hal *hal)
352: {
353: /*
354: * Free HAL structure, assume interrupts are down
355: */
356: free(hal, M_DEVBUF);
357: }
358:
359: HAL_BOOL
360: ar5k_ar5210_phy_disable(struct ath_hal *hal)
361: {
362: AR5K_REG_WRITE(AR5K_AR5210_PHY_ACTIVE, AR5K_AR5210_PHY_DISABLE);
363: return (AH_TRUE);
364: }
365:
366: HAL_BOOL
367: ar5k_ar5210_reset(struct ath_hal *hal, HAL_OPMODE op_mode, HAL_CHANNEL *channel,
368: HAL_BOOL change_channel, HAL_STATUS *status)
369: {
370: int i;
371:
372: /* Not used, keep for HAL compatibility */
373: *status = HAL_OK;
374:
375: if (ar5k_ar5210_nic_wakeup(hal,
376: channel->c_channel_flags & IEEE80211_CHAN_T ?
377: AH_TRUE : AH_FALSE, AH_FALSE) == AH_FALSE)
378: return (AH_FALSE);
379:
380: /*
381: * Initialize operating mode
382: */
383: hal->ah_op_mode = op_mode;
384: ar5k_ar5210_set_opmode(hal);
385:
386: /*
387: * Write initial mode register settings
388: */
389: for (i = 0; i < AR5K_ELEMENTS(ar5210_ini); i++) {
390: if (change_channel == AH_TRUE &&
391: ar5210_ini[i].ini_register >= AR5K_AR5210_PCU_MIN &&
392: ar5210_ini[i].ini_register <= AR5K_AR5210_PCU_MAX)
393: continue;
394:
395: switch (ar5210_ini[i].ini_mode) {
396: case AR5K_INI_READ:
397: /* Cleared on read */
398: AR5K_REG_READ(ar5210_ini[i].ini_register);
399: break;
400:
401: case AR5K_INI_WRITE:
402: default:
403: AR5K_REG_WRITE(ar5210_ini[i].ini_register,
404: ar5210_ini[i].ini_value);
405: }
406: }
407:
408: AR5K_DELAY(1000);
409:
410: /*
411: * Set channel and calibrate the PHY
412: */
413:
414: /* Disable phy and wait */
415: AR5K_REG_WRITE(AR5K_AR5210_PHY_ACTIVE, AR5K_AR5210_PHY_DISABLE);
416: AR5K_DELAY(1000);
417:
418: if (ar5k_channel(hal, channel) == AH_FALSE)
419: return (AH_FALSE);
420:
421: /*
422: * Activate phy and wait
423: */
424: AR5K_REG_WRITE(AR5K_AR5210_PHY_ACTIVE, AR5K_AR5210_PHY_ENABLE);
425: AR5K_DELAY(1000);
426:
427: ar5k_ar5210_do_calibrate(hal, channel);
428: if (ar5k_ar5210_noise_floor(hal, channel) == AH_FALSE)
429: return (AH_FALSE);
430:
431: /*
432: * Set RF kill flags if supported by the device (read from the EEPROM)
433: */
434: if (AR5K_EEPROM_HDR_RFKILL(hal->ah_capabilities.cap_eeprom.ee_header)) {
435: ar5k_ar5210_set_gpio_input(hal, 0);
436: if ((hal->ah_gpio[0] = ar5k_ar5210_get_gpio(hal, 0)) == 0) {
437: ar5k_ar5210_set_gpio_intr(hal, 0, 1);
438: } else {
439: ar5k_ar5210_set_gpio_intr(hal, 0, 0);
440: }
441: }
442:
443: /*
444: * Reset queues and start beacon timers at the end of the reset routine
445: */
446: for (i = 0; i < hal->ah_capabilities.cap_queues.q_tx_num; i++) {
447: if (ar5k_ar5210_reset_tx_queue(hal, i) == AH_FALSE) {
448: AR5K_PRINTF("failed to reset TX queue #%d\n", i);
449: return (AH_FALSE);
450: }
451: }
452:
453: AR5K_REG_DISABLE_BITS(AR5K_AR5210_BEACON,
454: AR5K_AR5210_BEACON_EN | AR5K_AR5210_BEACON_RESET_TSF);
455:
456: return (AH_TRUE);
457: }
458:
459: void
460: ar5k_ar5210_set_def_antenna(struct ath_hal *hal, u_int ant)
461: {
462: /* Not available */
463: return;
464: }
465:
466: u_int
467: ar5k_ar5210_get_def_antenna(struct ath_hal *hal)
468: {
469: return (0);
470: }
471:
472: void
473: ar5k_ar5210_set_opmode(struct ath_hal *hal)
474: {
475: u_int32_t pcu_reg, beacon_reg, low_id, high_id;
476:
477: beacon_reg = 0;
478: pcu_reg = 0;
479:
480: switch (hal->ah_op_mode) {
481: case IEEE80211_M_STA:
482: pcu_reg |= AR5K_AR5210_STA_ID1_NO_PSPOLL |
483: AR5K_AR5210_STA_ID1_DESC_ANTENNA |
484: AR5K_AR5210_STA_ID1_PWR_SV;
485: break;
486:
487: case IEEE80211_M_IBSS:
488: pcu_reg |= AR5K_AR5210_STA_ID1_ADHOC |
489: AR5K_AR5210_STA_ID1_NO_PSPOLL |
490: AR5K_AR5210_STA_ID1_DESC_ANTENNA;
491: beacon_reg |= AR5K_AR5210_BCR_ADHOC;
492: break;
493:
494: case IEEE80211_M_HOSTAP:
495: pcu_reg |= AR5K_AR5210_STA_ID1_AP |
496: AR5K_AR5210_STA_ID1_NO_PSPOLL |
497: AR5K_AR5210_STA_ID1_DESC_ANTENNA;
498: beacon_reg |= AR5K_AR5210_BCR_AP;
499: break;
500:
501: case IEEE80211_M_MONITOR:
502: pcu_reg |= AR5K_AR5210_STA_ID1_NO_PSPOLL;
503: break;
504:
505: default:
506: return;
507: }
508:
509: /*
510: * Set PCU and BCR registers
511: */
512: low_id = AR5K_LOW_ID(hal->ah_sta_id);
513: high_id = AR5K_HIGH_ID(hal->ah_sta_id);
514: AR5K_REG_WRITE(AR5K_AR5210_STA_ID0, low_id);
515: AR5K_REG_WRITE(AR5K_AR5210_STA_ID1, pcu_reg | high_id);
516: AR5K_REG_WRITE(AR5K_AR5210_BCR, beacon_reg);
517:
518: return;
519: }
520:
521: HAL_BOOL
522: ar5k_ar5210_calibrate(struct ath_hal *hal, HAL_CHANNEL *channel)
523: {
524: HAL_BOOL ret = AH_TRUE;
525: u_int32_t phy_sig, phy_agc, phy_sat, beacon;
526:
527: #define AGC_DISABLE { \
528: AR5K_REG_ENABLE_BITS(AR5K_AR5210_PHY_AGC, \
529: AR5K_AR5210_PHY_AGC_DISABLE); \
530: AR5K_DELAY(10); \
531: }
532:
533: #define AGC_ENABLE { \
534: AR5K_REG_DISABLE_BITS(AR5K_AR5210_PHY_AGC, \
535: AR5K_AR5210_PHY_AGC_DISABLE); \
536: }
537:
538: /*
539: * Disable beacons and RX/TX queues, wait
540: */
541: AR5K_REG_ENABLE_BITS(AR5K_AR5210_DIAG_SW,
542: AR5K_AR5210_DIAG_SW_DIS_TX | AR5K_AR5210_DIAG_SW_DIS_RX);
543: beacon = AR5K_REG_READ(AR5K_AR5210_BEACON);
544: AR5K_REG_WRITE(AR5K_AR5210_BEACON, beacon & ~AR5K_AR5210_BEACON_EN);
545:
546: AR5K_DELAY(2300);
547:
548: /*
549: * Set the channel (with AGC turned off)
550: */
551: AGC_DISABLE;
552: ret = ar5k_channel(hal, channel);
553:
554: /*
555: * Activate PHY and wait
556: */
557: AR5K_REG_WRITE(AR5K_AR5210_PHY_ACTIVE, AR5K_AR5210_PHY_ENABLE);
558: AR5K_DELAY(1000);
559:
560: AGC_ENABLE;
561:
562: if (ret == AH_FALSE)
563: return (ret);
564:
565: /*
566: * Calibrate the radio chip
567: */
568:
569: /* Remember normal state */
570: phy_sig = AR5K_REG_READ(AR5K_AR5210_PHY_SIG);
571: phy_agc = AR5K_REG_READ(AR5K_AR5210_PHY_AGCCOARSE);
572: phy_sat = AR5K_REG_READ(AR5K_AR5210_PHY_ADCSAT);
573:
574: /* Update radio registers */
575: AR5K_REG_WRITE(AR5K_AR5210_PHY_SIG,
576: (phy_sig & ~(AR5K_AR5210_PHY_SIG_FIRPWR)) |
577: AR5K_REG_SM(-1, AR5K_AR5210_PHY_SIG_FIRPWR));
578:
579: AR5K_REG_WRITE(AR5K_AR5210_PHY_AGCCOARSE,
580: (phy_agc & ~(AR5K_AR5210_PHY_AGCCOARSE_HI |
581: AR5K_AR5210_PHY_AGCCOARSE_LO)) |
582: AR5K_REG_SM(-1, AR5K_AR5210_PHY_AGCCOARSE_HI) |
583: AR5K_REG_SM(-127, AR5K_AR5210_PHY_AGCCOARSE_LO));
584:
585: AR5K_REG_WRITE(AR5K_AR5210_PHY_ADCSAT,
586: (phy_sat & ~(AR5K_AR5210_PHY_ADCSAT_ICNT |
587: AR5K_AR5210_PHY_ADCSAT_THR)) |
588: AR5K_REG_SM(2, AR5K_AR5210_PHY_ADCSAT_ICNT) |
589: AR5K_REG_SM(12, AR5K_AR5210_PHY_ADCSAT_THR));
590:
591: AR5K_DELAY(20);
592:
593: AGC_DISABLE;
594: AR5K_REG_WRITE(AR5K_AR5210_PHY_RFSTG, AR5K_AR5210_PHY_RFSTG_DISABLE);
595: AGC_ENABLE;
596:
597: AR5K_DELAY(1000);
598:
599: ret = ar5k_ar5210_do_calibrate(hal, channel);
600:
601: /* Reset to normal state */
602: AR5K_REG_WRITE(AR5K_AR5210_PHY_SIG, phy_sig);
603: AR5K_REG_WRITE(AR5K_AR5210_PHY_AGCCOARSE, phy_agc);
604: AR5K_REG_WRITE(AR5K_AR5210_PHY_ADCSAT, phy_sat);
605:
606: if (ret == AH_FALSE)
607: return (AH_FALSE);
608:
609: if (ar5k_ar5210_noise_floor(hal, channel) == AH_FALSE)
610: return (AH_FALSE);
611:
612: /*
613: * Re-enable RX/TX and beacons
614: */
615: AR5K_REG_DISABLE_BITS(AR5K_AR5210_DIAG_SW,
616: AR5K_AR5210_DIAG_SW_DIS_TX | AR5K_AR5210_DIAG_SW_DIS_RX);
617: AR5K_REG_WRITE(AR5K_AR5210_BEACON, beacon);
618:
619: #undef AGC_ENABLE
620: #undef AGC_DISABLE
621:
622: return (AH_TRUE);
623: }
624:
625: HAL_BOOL
626: ar5k_ar5210_do_calibrate(struct ath_hal *hal, HAL_CHANNEL *channel)
627: {
628: /*
629: * Enable calibration and wait until completion
630: */
631: AR5K_REG_ENABLE_BITS(AR5K_AR5210_PHY_AGCCTL,
632: AR5K_AR5210_PHY_AGCCTL_CAL);
633:
634: if (ar5k_register_timeout(hal, AR5K_AR5210_PHY_AGCCTL,
635: AR5K_AR5210_PHY_AGCCTL_CAL, 0, AH_FALSE) == AH_FALSE) {
636: AR5K_PRINTF("calibration timeout (%uMHz)\n",
637: channel->c_channel);
638: return (AH_FALSE);
639: }
640:
641: return (AH_TRUE);
642: }
643:
644: HAL_BOOL
645: ar5k_ar5210_noise_floor(struct ath_hal *hal, HAL_CHANNEL *channel)
646: {
647: int i;
648: u_int32_t noise_floor;
649:
650: /*
651: * Enable noise floor calibration and wait until completion
652: */
653: AR5K_REG_ENABLE_BITS(AR5K_AR5210_PHY_AGCCTL,
654: AR5K_AR5210_PHY_AGCCTL_NF);
655:
656: if (ar5k_register_timeout(hal, AR5K_AR5210_PHY_AGCCTL,
657: AR5K_AR5210_PHY_AGCCTL_NF, 0, AH_FALSE) == AH_FALSE) {
658: AR5K_PRINTF("noise floor calibration timeout (%uMHz)\n",
659: channel->c_channel);
660: return (AH_FALSE);
661: }
662:
663: /* wait until the noise floor is calibrated */
664: for (i = 20; i > 0; i--) {
665: AR5K_DELAY(1000);
666: noise_floor = AR5K_REG_READ(AR5K_AR5210_PHY_NF);
667: if (AR5K_AR5210_PHY_NF_RVAL(noise_floor) &
668: AR5K_AR5210_PHY_NF_ACTIVE)
669: noise_floor = AR5K_AR5210_PHY_NF_AVAL(noise_floor);
670: if (noise_floor <= AR5K_TUNE_NOISE_FLOOR)
671: break;
672: }
673:
674: if (noise_floor > AR5K_TUNE_NOISE_FLOOR) {
675: AR5K_PRINTF("noise floor calibration failed (%uMHz)\n",
676: channel->c_channel);
677: return (AH_FALSE);
678: }
679:
680: return (AH_TRUE);
681: }
682:
683: /*
684: * Transmit functions
685: */
686:
687: HAL_BOOL
688: ar5k_ar5210_update_tx_triglevel(struct ath_hal *hal, HAL_BOOL increase)
689: {
690: u_int32_t trigger_level;
691: HAL_BOOL status = AH_FALSE;
692:
693: /*
694: * Disable interrupts by setting the mask
695: */
696: AR5K_REG_DISABLE_BITS(AR5K_AR5210_IMR, HAL_INT_GLOBAL);
697:
698: trigger_level = AR5K_REG_READ(AR5K_AR5210_TRIG_LVL);
699:
700: if (increase == AH_FALSE) {
701: if (--trigger_level < AR5K_TUNE_MIN_TX_FIFO_THRES)
702: goto done;
703: } else {
704: trigger_level +=
705: ((AR5K_TUNE_MAX_TX_FIFO_THRES - trigger_level) / 2);
706: }
707:
708: /*
709: * Update trigger level on success
710: */
711: AR5K_REG_WRITE(AR5K_AR5210_TRIG_LVL, trigger_level);
712: status = AH_TRUE;
713:
714: done:
715: /*
716: * Restore interrupt mask
717: */
718: AR5K_REG_ENABLE_BITS(AR5K_AR5210_IMR, HAL_INT_GLOBAL);
719:
720: return (status);
721: }
722:
723: int
724: ar5k_ar5210_setup_tx_queue(struct ath_hal *hal, HAL_TX_QUEUE queue_type,
725: const HAL_TXQ_INFO *queue_info)
726: {
727: u_int queue;
728:
729: /*
730: * Get queue by type
731: */
732: switch (queue_type) {
733: case HAL_TX_QUEUE_DATA:
734: queue = 0;
735: break;
736: case HAL_TX_QUEUE_BEACON:
737: case HAL_TX_QUEUE_CAB:
738: queue = 1;
739: break;
740: default:
741: return (-1);
742: }
743:
744: /*
745: * Setup internal queue structure
746: */
747: bzero(&hal->ah_txq[queue], sizeof(HAL_TXQ_INFO));
748: hal->ah_txq[queue].tqi_type = queue_type;
749:
750: if (queue_info != NULL) {
751: if (ar5k_ar5210_setup_tx_queueprops(hal,
752: queue, queue_info) != AH_TRUE)
753: return (-1);
754: }
755:
756: return (queue);
757: }
758:
759: HAL_BOOL
760: ar5k_ar5210_setup_tx_queueprops(struct ath_hal *hal, int queue,
761: const HAL_TXQ_INFO *queue_info)
762: {
763: AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
764:
765: if (hal->ah_txq[queue].tqi_type == HAL_TX_QUEUE_INACTIVE)
766: return (AH_FALSE);
767:
768: hal->ah_txq[queue].tqi_aifs = queue_info->tqi_aifs;
769: hal->ah_txq[queue].tqi_cw_max = queue_info->tqi_cw_max;
770: hal->ah_txq[queue].tqi_cw_min = queue_info->tqi_cw_min;
771: hal->ah_txq[queue].tqi_flags = queue_info->tqi_flags;
772:
773: return (AH_TRUE);
774: }
775:
776: HAL_BOOL
777: ar5k_ar5210_get_tx_queueprops(struct ath_hal *hal, int queue,
778: HAL_TXQ_INFO *queue_info)
779: {
780: AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
781: bcopy(&hal->ah_txq[queue], queue_info, sizeof(HAL_TXQ_INFO));
782: return (AH_TRUE);
783: }
784:
785: HAL_BOOL
786: ar5k_ar5210_release_tx_queue(struct ath_hal *hal, u_int queue)
787: {
788: AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
789:
790: /* This queue will be skipped in further operations */
791: hal->ah_txq[queue].tqi_type = HAL_TX_QUEUE_INACTIVE;
792:
793: return (AH_FALSE);
794: }
795:
796: void
797: ar5k_ar5210_init_tx_queue(struct ath_hal *hal, u_int aifs, HAL_BOOL turbo)
798: {
799: int i;
800: struct {
801: u_int16_t mode_register;
802: u_int32_t mode_base, mode_turbo;
803: } initial[] = AR5K_AR5210_INI_MODE(aifs);
804:
805: /*
806: * Write initial mode register settings
807: */
808: for (i = 0; i < AR5K_ELEMENTS(initial); i++)
809: AR5K_REG_WRITE((u_int32_t)initial[i].mode_register,
810: turbo == AH_TRUE ?
811: initial[i].mode_turbo : initial[i].mode_base);
812: }
813:
814: HAL_BOOL
815: ar5k_ar5210_reset_tx_queue(struct ath_hal *hal, u_int queue)
816: {
817: u_int32_t cw_min, retry_lg, retry_sh;
818: HAL_TXQ_INFO *tq;
819:
820: AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
821:
822: tq = &hal->ah_txq[queue];
823:
824: /* Only handle data queues, others will be ignored */
825: if (tq->tqi_type != HAL_TX_QUEUE_DATA)
826: return (AH_TRUE);
827:
828: /* Set turbo/base mode parameters */
829: ar5k_ar5210_init_tx_queue(hal, hal->ah_aifs + tq->tqi_aifs,
830: hal->ah_turbo == AH_TRUE ? AH_TRUE : AH_FALSE);
831:
832: /*
833: * Set retry limits
834: */
835: if (hal->ah_software_retry == AH_TRUE) {
836: /* XXX Need to test this */
837: retry_lg = hal->ah_limit_tx_retries;
838: retry_sh = retry_lg =
839: retry_lg > AR5K_AR5210_RETRY_LMT_SH_RETRY ?
840: AR5K_AR5210_RETRY_LMT_SH_RETRY : retry_lg;
841: } else {
842: retry_lg = AR5K_INIT_LG_RETRY;
843: retry_sh = AR5K_INIT_SH_RETRY;
844: }
845:
846: /*
847: * Set initial content window (cw_min/cw_max)
848: */
849: cw_min = 1;
850: while (cw_min < hal->ah_cw_min)
851: cw_min = (cw_min << 1) | 1;
852:
853: cw_min = tq->tqi_cw_min < 0 ?
854: (cw_min >> (-tq->tqi_cw_min)) :
855: ((cw_min << tq->tqi_cw_min) + (1 << tq->tqi_cw_min) - 1);
856:
857: /* Commit values */
858: AR5K_REG_WRITE(AR5K_AR5210_RETRY_LMT,
859: (cw_min << AR5K_AR5210_RETRY_LMT_CW_MIN_S)
860: | AR5K_REG_SM(AR5K_INIT_SLG_RETRY, AR5K_AR5210_RETRY_LMT_SLG_RETRY)
861: | AR5K_REG_SM(AR5K_INIT_SSH_RETRY, AR5K_AR5210_RETRY_LMT_SSH_RETRY)
862: | AR5K_REG_SM(retry_lg, AR5K_AR5210_RETRY_LMT_LG_RETRY)
863: | AR5K_REG_SM(retry_sh, AR5K_AR5210_RETRY_LMT_SH_RETRY));
864:
865: return (AH_TRUE);
866: }
867:
868: u_int32_t
869: ar5k_ar5210_get_tx_buf(struct ath_hal *hal, u_int queue)
870: {
871: u_int16_t tx_reg;
872:
873: AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
874:
875: /*
876: * Get the transmit queue descriptor pointer register by type
877: */
878: switch (hal->ah_txq[queue].tqi_type) {
879: case HAL_TX_QUEUE_DATA:
880: tx_reg = AR5K_AR5210_TXDP0;
881: break;
882: case HAL_TX_QUEUE_BEACON:
883: case HAL_TX_QUEUE_CAB:
884: tx_reg = AR5K_AR5210_TXDP1;
885: break;
886: default:
887: return (0xffffffff);
888: }
889:
890: return (AR5K_REG_READ(tx_reg));
891: }
892:
893: HAL_BOOL
894: ar5k_ar5210_put_tx_buf(struct ath_hal *hal, u_int queue, u_int32_t phys_addr)
895: {
896: u_int16_t tx_reg;
897:
898: AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
899:
900: /*
901: * Get the transmit queue descriptor pointer register by type
902: */
903: switch (hal->ah_txq[queue].tqi_type) {
904: case HAL_TX_QUEUE_DATA:
905: tx_reg = AR5K_AR5210_TXDP0;
906: break;
907: case HAL_TX_QUEUE_BEACON:
908: case HAL_TX_QUEUE_CAB:
909: tx_reg = AR5K_AR5210_TXDP1;
910: break;
911: default:
912: return (AH_FALSE);
913: }
914:
915: /* Set descriptor pointer */
916: AR5K_REG_WRITE(tx_reg, phys_addr);
917:
918: return (AH_TRUE);
919: }
920:
921: u_int32_t
922: ar5k_ar5210_num_tx_pending(struct ath_hal *hal, u_int queue)
923: {
924: return (AH_FALSE);
925: }
926:
927: HAL_BOOL
928: ar5k_ar5210_tx_start(struct ath_hal *hal, u_int queue)
929: {
930: u_int32_t tx_queue;
931:
932: AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
933:
934: tx_queue = AR5K_REG_READ(AR5K_AR5210_CR);
935:
936: /*
937: * Set the queue type
938: */
939: switch (hal->ah_txq[queue].tqi_type) {
940: case HAL_TX_QUEUE_DATA:
941: tx_queue |= AR5K_AR5210_CR_TXE0 & ~AR5K_AR5210_CR_TXD0;
942: break;
943:
944: case HAL_TX_QUEUE_BEACON:
945: tx_queue |= AR5K_AR5210_CR_TXE1 & ~AR5K_AR5210_CR_TXD1;
946: AR5K_REG_WRITE(AR5K_AR5210_BSR,
947: AR5K_AR5210_BCR_TQ1V | AR5K_AR5210_BCR_BDMAE);
948: break;
949:
950: case HAL_TX_QUEUE_CAB:
951: tx_queue |= AR5K_AR5210_CR_TXE1 & ~AR5K_AR5210_CR_TXD1;
952: AR5K_REG_WRITE(AR5K_AR5210_BSR,
953: AR5K_AR5210_BCR_TQ1FV | AR5K_AR5210_BCR_TQ1V |
954: AR5K_AR5210_BCR_BDMAE);
955: break;
956:
957: default:
958: return (AH_FALSE);
959: }
960:
961: /* Start queue */
962: AR5K_REG_WRITE(AR5K_AR5210_CR, tx_queue);
963:
964: return (AH_TRUE);
965: }
966:
967: HAL_BOOL
968: ar5k_ar5210_stop_tx_dma(struct ath_hal *hal, u_int queue)
969: {
970: u_int32_t tx_queue;
971:
972: AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
973:
974: tx_queue = AR5K_REG_READ(AR5K_AR5210_CR);
975:
976: /*
977: * Set by queue type
978: */
979: switch (hal->ah_txq[queue].tqi_type) {
980: case HAL_TX_QUEUE_DATA:
981: tx_queue |= AR5K_AR5210_CR_TXD0 & ~AR5K_AR5210_CR_TXE0;
982: break;
983:
984: case HAL_TX_QUEUE_BEACON:
985: case HAL_TX_QUEUE_CAB:
986: /* XXX Fix me... */
987: tx_queue |= AR5K_AR5210_CR_TXD1 & ~AR5K_AR5210_CR_TXD1;
988: AR5K_REG_WRITE(AR5K_AR5210_BSR, 0);
989: break;
990:
991: default:
992: return (AH_FALSE);
993: }
994:
995: /* Stop queue */
996: AR5K_REG_WRITE(AR5K_AR5210_CR, tx_queue);
997:
998: return (AH_TRUE);
999: }
1000:
1001: HAL_BOOL
1002: ar5k_ar5210_setup_tx_desc(struct ath_hal *hal, struct ath_desc *desc,
1003: u_int packet_length, u_int header_length, HAL_PKT_TYPE type, u_int tx_power,
1004: u_int tx_rate0, u_int tx_tries0, u_int key_index, u_int antenna_mode,
1005: u_int flags, u_int rtscts_rate, u_int rtscts_duration)
1006: {
1007: u_int32_t frame_type;
1008: struct ar5k_ar5210_tx_desc *tx_desc;
1009:
1010: tx_desc = (struct ar5k_ar5210_tx_desc*)&desc->ds_ctl0;
1011:
1012: /*
1013: * Validate input
1014: */
1015: if (tx_tries0 == 0)
1016: return (AH_FALSE);
1017:
1018: if ((tx_desc->tx_control_0 = (packet_length &
1019: AR5K_AR5210_DESC_TX_CTL0_FRAME_LEN)) != packet_length)
1020: return (AH_FALSE);
1021:
1022: if ((tx_desc->tx_control_0 = (header_length &
1023: AR5K_AR5210_DESC_TX_CTL0_HEADER_LEN)) != header_length)
1024: return (AH_FALSE);
1025:
1026: if (type == HAL_PKT_TYPE_BEACON || type == HAL_PKT_TYPE_PROBE_RESP)
1027: frame_type = AR5K_AR5210_DESC_TX_FRAME_TYPE_NO_DELAY;
1028: else if (type == HAL_PKT_TYPE_PIFS)
1029: frame_type = AR5K_AR5210_DESC_TX_FRAME_TYPE_PIFS;
1030: else
1031: frame_type = type;
1032:
1033: tx_desc->tx_control_0 =
1034: AR5K_REG_SM(frame_type, AR5K_AR5210_DESC_TX_CTL0_FRAME_TYPE);
1035: tx_desc->tx_control_0 |=
1036: AR5K_REG_SM(tx_rate0, AR5K_AR5210_DESC_TX_CTL0_XMIT_RATE);
1037:
1038: #define _TX_FLAGS(_c, _flag) \
1039: if (flags & HAL_TXDESC_##_flag) \
1040: tx_desc->tx_control_##_c |= \
1041: AR5K_AR5210_DESC_TX_CTL##_c##_##_flag
1042:
1043: _TX_FLAGS(0, CLRDMASK);
1044: _TX_FLAGS(0, INTREQ);
1045: _TX_FLAGS(0, RTSENA);
1046:
1047: #undef _TX_FLAGS
1048:
1049: /*
1050: * WEP crap
1051: */
1052: if (key_index != HAL_TXKEYIX_INVALID) {
1053: tx_desc->tx_control_0 |=
1054: AR5K_AR5210_DESC_TX_CTL0_ENCRYPT_KEY_VALID;
1055: tx_desc->tx_control_1 |=
1056: AR5K_REG_SM(key_index,
1057: AR5K_AR5210_DESC_TX_CTL1_ENCRYPT_KEY_INDEX);
1058: }
1059:
1060: /*
1061: * RTS/CTS
1062: */
1063: if (flags & (HAL_TXDESC_RTSENA | HAL_TXDESC_CTSENA)) {
1064: tx_desc->tx_control_1 |=
1065: rtscts_duration & AR5K_AR5210_DESC_TX_CTL1_RTS_DURATION;
1066: }
1067:
1068: return (AH_TRUE);
1069: }
1070:
1071: HAL_BOOL
1072: ar5k_ar5210_fill_tx_desc(struct ath_hal *hal, struct ath_desc *desc,
1073: u_int segment_length, HAL_BOOL first_segment, HAL_BOOL last_segment)
1074: {
1075: struct ar5k_ar5210_tx_desc *tx_desc;
1076:
1077: tx_desc = (struct ar5k_ar5210_tx_desc*)&desc->ds_ctl0;
1078:
1079: /* Clear status descriptor */
1080: bzero(desc->ds_hw, sizeof(desc->ds_hw));
1081:
1082: /* Validate segment length and initialize the descriptor */
1083: if ((tx_desc->tx_control_1 = (segment_length &
1084: AR5K_AR5210_DESC_TX_CTL1_BUF_LEN)) != segment_length)
1085: return (AH_FALSE);
1086:
1087: if (first_segment != AH_TRUE)
1088: tx_desc->tx_control_0 &= ~AR5K_AR5210_DESC_TX_CTL0_FRAME_LEN;
1089:
1090: if (last_segment != AH_TRUE)
1091: tx_desc->tx_control_1 |= AR5K_AR5210_DESC_TX_CTL1_MORE;
1092:
1093: return (AH_TRUE);
1094: }
1095:
1096: HAL_BOOL
1097: ar5k_ar5210_setup_xtx_desc(struct ath_hal *hal, struct ath_desc *desc,
1098: u_int tx_rate1, u_int tx_tries1, u_int tx_rate2, u_int tx_tries2,
1099: u_int tx_rate3, u_int tx_tries3)
1100: {
1101: /*
1102: * Does this function is for setting up XR? Not sure...
1103: * Nevertheless, I didn't find any information about XR support
1104: * by the AR5210. This seems to be a slightly new feature.
1105: */
1106: return (AH_FALSE);
1107: }
1108:
1109: HAL_STATUS
1110: ar5k_ar5210_proc_tx_desc(struct ath_hal *hal, struct ath_desc *desc)
1111: {
1112: struct ar5k_ar5210_tx_status *tx_status;
1113: struct ar5k_ar5210_tx_desc *tx_desc;
1114:
1115: tx_desc = (struct ar5k_ar5210_tx_desc*)&desc->ds_ctl0;
1116: tx_status = (struct ar5k_ar5210_tx_status*)&desc->ds_hw[0];
1117:
1118: /* No frame has been send or error */
1119: if ((tx_status->tx_status_1 & AR5K_AR5210_DESC_TX_STATUS1_DONE) == 0)
1120: return (HAL_EINPROGRESS);
1121:
1122: /*
1123: * Get descriptor status
1124: */
1125: desc->ds_us.tx.ts_tstamp =
1126: AR5K_REG_MS(tx_status->tx_status_0,
1127: AR5K_AR5210_DESC_TX_STATUS0_SEND_TIMESTAMP);
1128: desc->ds_us.tx.ts_shortretry =
1129: AR5K_REG_MS(tx_status->tx_status_0,
1130: AR5K_AR5210_DESC_TX_STATUS0_SHORT_RETRY_COUNT);
1131: desc->ds_us.tx.ts_longretry =
1132: AR5K_REG_MS(tx_status->tx_status_0,
1133: AR5K_AR5210_DESC_TX_STATUS0_LONG_RETRY_COUNT);
1134: desc->ds_us.tx.ts_seqnum =
1135: AR5K_REG_MS(tx_status->tx_status_1,
1136: AR5K_AR5210_DESC_TX_STATUS1_SEQ_NUM);
1137: desc->ds_us.tx.ts_rssi =
1138: AR5K_REG_MS(tx_status->tx_status_1,
1139: AR5K_AR5210_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
1140: desc->ds_us.tx.ts_antenna = 1;
1141: desc->ds_us.tx.ts_status = 0;
1142: desc->ds_us.tx.ts_rate =
1143: AR5K_REG_MS(tx_desc->tx_control_0,
1144: AR5K_AR5210_DESC_TX_CTL0_XMIT_RATE);
1145:
1146: if ((tx_status->tx_status_0 &
1147: AR5K_AR5210_DESC_TX_STATUS0_FRAME_XMIT_OK) == 0) {
1148: if (tx_status->tx_status_0 &
1149: AR5K_AR5210_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
1150: desc->ds_us.tx.ts_status |= HAL_TXERR_XRETRY;
1151:
1152: if (tx_status->tx_status_0 &
1153: AR5K_AR5210_DESC_TX_STATUS0_FIFO_UNDERRUN)
1154: desc->ds_us.tx.ts_status |= HAL_TXERR_FIFO;
1155:
1156: if (tx_status->tx_status_0 &
1157: AR5K_AR5210_DESC_TX_STATUS0_FILTERED)
1158: desc->ds_us.tx.ts_status |= HAL_TXERR_FILT;
1159: }
1160:
1161: return (HAL_OK);
1162: }
1163:
1164: HAL_BOOL
1165: ar5k_ar5210_has_veol(struct ath_hal *hal)
1166: {
1167: return (AH_FALSE);
1168: }
1169:
1170: /*
1171: * Receive functions
1172: */
1173:
1174: u_int32_t
1175: ar5k_ar5210_get_rx_buf(struct ath_hal *hal)
1176: {
1177: return (AR5K_REG_READ(AR5K_AR5210_RXDP));
1178: }
1179:
1180: void
1181: ar5k_ar5210_put_rx_buf(struct ath_hal *hal, u_int32_t phys_addr)
1182: {
1183: AR5K_REG_WRITE(AR5K_AR5210_RXDP, phys_addr);
1184: }
1185:
1186: void
1187: ar5k_ar5210_start_rx(struct ath_hal *hal)
1188: {
1189: AR5K_REG_WRITE(AR5K_AR5210_CR, AR5K_AR5210_CR_RXE);
1190: }
1191:
1192: HAL_BOOL
1193: ar5k_ar5210_stop_rx_dma(struct ath_hal *hal)
1194: {
1195: int i;
1196:
1197: AR5K_REG_WRITE(AR5K_AR5210_CR, AR5K_AR5210_CR_RXD);
1198:
1199: /*
1200: * It may take some time to disable the DMA receive unit
1201: */
1202: for (i = 2000;
1203: i > 0 && (AR5K_REG_READ(AR5K_AR5210_CR) & AR5K_AR5210_CR_RXE) != 0;
1204: i--)
1205: AR5K_DELAY(10);
1206:
1207: return (i > 0 ? AH_TRUE : AH_FALSE);
1208: }
1209:
1210: void
1211: ar5k_ar5210_start_rx_pcu(struct ath_hal *hal)
1212: {
1213: AR5K_REG_DISABLE_BITS(AR5K_AR5210_DIAG_SW, AR5K_AR5210_DIAG_SW_DIS_RX);
1214: }
1215:
1216: void
1217: ar5k_ar5210_stop_pcu_recv(struct ath_hal *hal)
1218: {
1219: AR5K_REG_ENABLE_BITS(AR5K_AR5210_DIAG_SW, AR5K_AR5210_DIAG_SW_DIS_RX);
1220: }
1221:
1222: void
1223: ar5k_ar5210_set_mcast_filter(struct ath_hal *hal, u_int32_t filter0,
1224: u_int32_t filter1)
1225: {
1226: /* Set the multicat filter */
1227: AR5K_REG_WRITE(AR5K_AR5210_MCAST_FIL0, filter0);
1228: AR5K_REG_WRITE(AR5K_AR5210_MCAST_FIL1, filter1);
1229: }
1230:
1231: HAL_BOOL
1232: ar5k_ar5210_set_mcast_filterindex(struct ath_hal *hal, u_int32_t index)
1233: {
1234: if (index >= 64) {
1235: return (AH_FALSE);
1236: } else if (index >= 32) {
1237: AR5K_REG_ENABLE_BITS(AR5K_AR5210_MCAST_FIL1,
1238: (1 << (index - 32)));
1239: } else {
1240: AR5K_REG_ENABLE_BITS(AR5K_AR5210_MCAST_FIL0,
1241: (1 << index));
1242: }
1243:
1244: return (AH_TRUE);
1245: }
1246:
1247: HAL_BOOL
1248: ar5k_ar5210_clear_mcast_filter_idx(struct ath_hal *hal, u_int32_t index)
1249: {
1250: if (index >= 64) {
1251: return (AH_FALSE);
1252: } else if (index >= 32) {
1253: AR5K_REG_DISABLE_BITS(AR5K_AR5210_MCAST_FIL1,
1254: (1 << (index - 32)));
1255: } else {
1256: AR5K_REG_DISABLE_BITS(AR5K_AR5210_MCAST_FIL0,
1257: (1 << index));
1258: }
1259:
1260: return (AH_TRUE);
1261: }
1262:
1263: u_int32_t
1264: ar5k_ar5210_get_rx_filter(struct ath_hal *hal)
1265: {
1266: return (AR5K_REG_READ(AR5K_AR5210_RX_FILTER));
1267: }
1268:
1269: void
1270: ar5k_ar5210_set_rx_filter(struct ath_hal *hal, u_int32_t filter)
1271: {
1272: /*
1273: * The AR5210 uses promiscous mode to detect radar activity
1274: */
1275: if (filter & HAL_RX_FILTER_PHYRADAR) {
1276: filter &= ~HAL_RX_FILTER_PHYRADAR;
1277: filter |= AR5K_AR5210_RX_FILTER_PROMISC;
1278: }
1279:
1280: AR5K_REG_WRITE(AR5K_AR5210_RX_FILTER, filter);
1281: }
1282:
1283: HAL_BOOL
1284: ar5k_ar5210_setup_rx_desc(struct ath_hal *hal, struct ath_desc *desc,
1285: u_int32_t size, u_int flags)
1286: {
1287: struct ar5k_ar5210_rx_desc *rx_desc;
1288:
1289: rx_desc = (struct ar5k_ar5210_rx_desc*)&desc->ds_ctl0;
1290:
1291: if ((rx_desc->rx_control_1 = (size &
1292: AR5K_AR5210_DESC_RX_CTL1_BUF_LEN)) != size)
1293: return (AH_FALSE);
1294:
1295: if (flags & HAL_RXDESC_INTREQ)
1296: rx_desc->rx_control_1 |= AR5K_AR5210_DESC_RX_CTL1_INTREQ;
1297:
1298: return (AH_TRUE);
1299: }
1300:
1301: HAL_STATUS
1302: ar5k_ar5210_proc_rx_desc(struct ath_hal *hal, struct ath_desc *desc,
1303: u_int32_t phys_addr, struct ath_desc *next)
1304: {
1305: struct ar5k_ar5210_rx_status *rx_status;
1306:
1307: rx_status = (struct ar5k_ar5210_rx_status*)&desc->ds_hw[0];
1308:
1309: /* No frame received / not ready */
1310: if ((rx_status->rx_status_1 & AR5K_AR5210_DESC_RX_STATUS1_DONE) == 0)
1311: return (HAL_EINPROGRESS);
1312:
1313: /*
1314: * Frame receive status
1315: */
1316: desc->ds_us.rx.rs_datalen = rx_status->rx_status_0 &
1317: AR5K_AR5210_DESC_RX_STATUS0_DATA_LEN;
1318: desc->ds_us.rx.rs_rssi =
1319: AR5K_REG_MS(rx_status->rx_status_0,
1320: AR5K_AR5210_DESC_RX_STATUS0_RECEIVE_SIGNAL);
1321: desc->ds_us.rx.rs_rate =
1322: AR5K_REG_MS(rx_status->rx_status_0,
1323: AR5K_AR5210_DESC_RX_STATUS0_RECEIVE_RATE);
1324: desc->ds_us.rx.rs_antenna = rx_status->rx_status_0 &
1325: AR5K_AR5210_DESC_RX_STATUS0_RECEIVE_ANTENNA;
1326: desc->ds_us.rx.rs_more = rx_status->rx_status_0 &
1327: AR5K_AR5210_DESC_RX_STATUS0_MORE;
1328: desc->ds_us.rx.rs_tstamp =
1329: AR5K_REG_MS(rx_status->rx_status_1,
1330: AR5K_AR5210_DESC_RX_STATUS1_RECEIVE_TIMESTAMP);
1331: desc->ds_us.rx.rs_status = 0;
1332:
1333: /*
1334: * Key table status
1335: */
1336: if (rx_status->rx_status_1 &
1337: AR5K_AR5210_DESC_RX_STATUS1_KEY_INDEX_VALID) {
1338: desc->ds_us.rx.rs_keyix =
1339: AR5K_REG_MS(rx_status->rx_status_1,
1340: AR5K_AR5210_DESC_RX_STATUS1_KEY_INDEX);
1341: } else {
1342: desc->ds_us.rx.rs_keyix = HAL_RXKEYIX_INVALID;
1343: }
1344:
1345: /*
1346: * Receive/descriptor errors
1347: */
1348: if ((rx_status->rx_status_1 &
1349: AR5K_AR5210_DESC_RX_STATUS1_FRAME_RECEIVE_OK) == 0) {
1350: if (rx_status->rx_status_1 &
1351: AR5K_AR5210_DESC_RX_STATUS1_CRC_ERROR)
1352: desc->ds_us.rx.rs_status |= HAL_RXERR_CRC;
1353:
1354: if (rx_status->rx_status_1 &
1355: AR5K_AR5210_DESC_RX_STATUS1_FIFO_OVERRUN)
1356: desc->ds_us.rx.rs_status |= HAL_RXERR_FIFO;
1357:
1358: if (rx_status->rx_status_1 &
1359: AR5K_AR5210_DESC_RX_STATUS1_PHY_ERROR) {
1360: desc->ds_us.rx.rs_status |= HAL_RXERR_PHY;
1361: desc->ds_us.rx.rs_phyerr =
1362: AR5K_REG_MS(rx_status->rx_status_1,
1363: AR5K_AR5210_DESC_RX_STATUS1_PHY_ERROR);
1364: }
1365:
1366: if (rx_status->rx_status_1 &
1367: AR5K_AR5210_DESC_RX_STATUS1_DECRYPT_CRC_ERROR)
1368: desc->ds_us.rx.rs_status |= HAL_RXERR_DECRYPT;
1369: }
1370:
1371: return (HAL_OK);
1372: }
1373:
1374: void
1375: ar5k_ar5210_set_rx_signal(struct ath_hal *hal)
1376: {
1377: /* Signal state monitoring is not yet supported */
1378: }
1379:
1380: /*
1381: * Misc functions
1382: */
1383:
1384: void
1385: ar5k_ar5210_dump_state(struct ath_hal *hal)
1386: {
1387: #ifdef AR5K_DEBUG
1388: #define AR5K_PRINT_REGISTER(_x) \
1389: printf("(%s: %08x) ", #_x, AR5K_REG_READ(AR5K_AR5210_##_x));
1390:
1391: printf("DMA registers:\n");
1392: AR5K_PRINT_REGISTER(TXDP0);
1393: AR5K_PRINT_REGISTER(TXDP1);
1394: AR5K_PRINT_REGISTER(CR);
1395: AR5K_PRINT_REGISTER(RXDP);
1396: AR5K_PRINT_REGISTER(CFG);
1397: AR5K_PRINT_REGISTER(ISR);
1398: AR5K_PRINT_REGISTER(IMR);
1399: AR5K_PRINT_REGISTER(IER);
1400: AR5K_PRINT_REGISTER(BCR);
1401: AR5K_PRINT_REGISTER(BSR);
1402: AR5K_PRINT_REGISTER(TXCFG);
1403: AR5K_PRINT_REGISTER(RXCFG);
1404: AR5K_PRINT_REGISTER(MIBC);
1405: AR5K_PRINT_REGISTER(TOPS);
1406: AR5K_PRINT_REGISTER(RXNOFRM);
1407: AR5K_PRINT_REGISTER(TXNOFRM);
1408: AR5K_PRINT_REGISTER(RPGTO);
1409: AR5K_PRINT_REGISTER(RFCNT);
1410: AR5K_PRINT_REGISTER(MISC);
1411: AR5K_PRINT_REGISTER(RC);
1412: AR5K_PRINT_REGISTER(SCR);
1413: AR5K_PRINT_REGISTER(INTPEND);
1414: AR5K_PRINT_REGISTER(SFR);
1415: AR5K_PRINT_REGISTER(PCICFG);
1416: AR5K_PRINT_REGISTER(GPIOCR);
1417: AR5K_PRINT_REGISTER(GPIODO);
1418: AR5K_PRINT_REGISTER(GPIODI);
1419: AR5K_PRINT_REGISTER(SREV);
1420: printf("\n");
1421:
1422: printf("PCU registers:\n");
1423: AR5K_PRINT_REGISTER(STA_ID0);
1424: AR5K_PRINT_REGISTER(STA_ID1);
1425: AR5K_PRINT_REGISTER(BSS_ID0);
1426: AR5K_PRINT_REGISTER(BSS_ID1);
1427: AR5K_PRINT_REGISTER(SLOT_TIME);
1428: AR5K_PRINT_REGISTER(TIME_OUT);
1429: AR5K_PRINT_REGISTER(RSSI_THR);
1430: AR5K_PRINT_REGISTER(RETRY_LMT);
1431: AR5K_PRINT_REGISTER(USEC);
1432: AR5K_PRINT_REGISTER(BEACON);
1433: AR5K_PRINT_REGISTER(CFP_PERIOD);
1434: AR5K_PRINT_REGISTER(TIMER0);
1435: AR5K_PRINT_REGISTER(TIMER1);
1436: AR5K_PRINT_REGISTER(TIMER2);
1437: AR5K_PRINT_REGISTER(TIMER3);
1438: AR5K_PRINT_REGISTER(IFS0);
1439: AR5K_PRINT_REGISTER(IFS1);
1440: AR5K_PRINT_REGISTER(CFP_DUR);
1441: AR5K_PRINT_REGISTER(RX_FILTER);
1442: AR5K_PRINT_REGISTER(MCAST_FIL0);
1443: AR5K_PRINT_REGISTER(MCAST_FIL1);
1444: AR5K_PRINT_REGISTER(TX_MASK0);
1445: AR5K_PRINT_REGISTER(TX_MASK1);
1446: AR5K_PRINT_REGISTER(CLR_TMASK);
1447: AR5K_PRINT_REGISTER(TRIG_LVL);
1448: AR5K_PRINT_REGISTER(DIAG_SW);
1449: AR5K_PRINT_REGISTER(TSF_L32);
1450: AR5K_PRINT_REGISTER(TSF_U32);
1451: AR5K_PRINT_REGISTER(LAST_TSTP);
1452: AR5K_PRINT_REGISTER(RETRY_CNT);
1453: AR5K_PRINT_REGISTER(BACKOFF);
1454: AR5K_PRINT_REGISTER(NAV);
1455: AR5K_PRINT_REGISTER(RTS_OK);
1456: AR5K_PRINT_REGISTER(RTS_FAIL);
1457: AR5K_PRINT_REGISTER(ACK_FAIL);
1458: AR5K_PRINT_REGISTER(FCS_FAIL);
1459: AR5K_PRINT_REGISTER(BEACON_CNT);
1460: AR5K_PRINT_REGISTER(KEYTABLE_0);
1461: printf("\n");
1462:
1463: printf("PHY registers:\n");
1464: AR5K_PRINT_REGISTER(PHY(0));
1465: AR5K_PRINT_REGISTER(PHY_FC);
1466: AR5K_PRINT_REGISTER(PHY_AGC);
1467: AR5K_PRINT_REGISTER(PHY_CHIP_ID);
1468: AR5K_PRINT_REGISTER(PHY_ACTIVE);
1469: AR5K_PRINT_REGISTER(PHY_AGCCTL);
1470: printf("\n");
1471: #endif
1472: }
1473:
1474: HAL_BOOL
1475: ar5k_ar5210_get_diag_state(struct ath_hal *hal, int id, void **device,
1476: u_int *size)
1477: {
1478: /*
1479: * We'll ignore this right now. This seems to be some kind of an obscure
1480: * debugging interface for the binary-only HAL.
1481: */
1482: return (AH_FALSE);
1483: }
1484:
1485: void
1486: ar5k_ar5210_get_lladdr(struct ath_hal *hal, u_int8_t *mac)
1487: {
1488: bcopy(hal->ah_sta_id, mac, IEEE80211_ADDR_LEN);
1489: }
1490:
1491: HAL_BOOL
1492: ar5k_ar5210_set_lladdr(struct ath_hal *hal, const u_int8_t *mac)
1493: {
1494: u_int32_t low_id, high_id;
1495:
1496: /* Set new station ID */
1497: bcopy(mac, hal->ah_sta_id, IEEE80211_ADDR_LEN);
1498:
1499: low_id = AR5K_LOW_ID(mac);
1500: high_id = 0x0000ffff & AR5K_HIGH_ID(mac);
1501:
1502: AR5K_REG_WRITE(AR5K_AR5210_STA_ID0, low_id);
1503: AR5K_REG_WRITE(AR5K_AR5210_STA_ID1, high_id);
1504:
1505: return (AH_TRUE);
1506: }
1507:
1508: HAL_BOOL
1509: ar5k_ar5210_set_regdomain(struct ath_hal *hal, u_int16_t regdomain,
1510: HAL_STATUS *status)
1511: {
1512: ieee80211_regdomain_t ieee_regdomain;
1513:
1514: ieee_regdomain = ar5k_regdomain_to_ieee(regdomain);
1515:
1516: if (ar5k_eeprom_regulation_domain(hal, AH_TRUE,
1517: &ieee_regdomain) == AH_TRUE) {
1518: *status = HAL_OK;
1519: return (AH_TRUE);
1520: }
1521:
1522: *status = EIO;
1523:
1524: return (AH_FALSE);
1525: }
1526:
1527: void
1528: ar5k_ar5210_set_ledstate(struct ath_hal *hal, HAL_LED_STATE state)
1529: {
1530: u_int32_t led;
1531:
1532: led = AR5K_REG_READ(AR5K_AR5210_PCICFG);
1533:
1534: /*
1535: * Some blinking values, define at your wish
1536: */
1537: switch (state) {
1538: case IEEE80211_S_SCAN:
1539: case IEEE80211_S_INIT:
1540: led |=
1541: AR5K_AR5210_PCICFG_LED_PEND |
1542: AR5K_AR5210_PCICFG_LED_BCTL;
1543: break;
1544: case IEEE80211_S_RUN:
1545: led |=
1546: AR5K_AR5210_PCICFG_LED_ACT;
1547: break;
1548: default:
1549: led |=
1550: AR5K_AR5210_PCICFG_LED_ACT |
1551: AR5K_AR5210_PCICFG_LED_BCTL;
1552: break;
1553: }
1554:
1555: AR5K_REG_WRITE(AR5K_AR5210_PCICFG, led);
1556: }
1557:
1558: void
1559: ar5k_ar5210_set_associd(struct ath_hal *hal, const u_int8_t *bssid,
1560: u_int16_t assoc_id, u_int16_t tim_offset)
1561: {
1562: u_int32_t low_id, high_id;
1563:
1564: /*
1565: * Set BSSID which triggers the "SME Join" operation
1566: */
1567: low_id = AR5K_LOW_ID(bssid);
1568: high_id = AR5K_HIGH_ID(bssid);
1569: AR5K_REG_WRITE(AR5K_AR5210_BSS_ID0, low_id);
1570: AR5K_REG_WRITE(AR5K_AR5210_BSS_ID1, high_id |
1571: ((assoc_id & 0x3fff) << AR5K_AR5210_BSS_ID1_AID_S));
1572: bcopy(bssid, &hal->ah_bssid, IEEE80211_ADDR_LEN);
1573:
1574: if (assoc_id == 0) {
1575: ar5k_ar5210_disable_pspoll(hal);
1576: return;
1577: }
1578:
1579: AR5K_REG_WRITE_BITS(AR5K_AR5210_BEACON, AR5K_AR5210_BEACON_TIM,
1580: tim_offset ? tim_offset + 4 : 0);
1581:
1582: ar5k_ar5210_enable_pspoll(hal, NULL, 0);
1583: }
1584:
1585: HAL_BOOL
1586: ar5k_ar5210_set_bssid_mask(struct ath_hal *hal, const u_int8_t* mask)
1587: {
1588: /* Not supported in 5210 */
1589: return (AH_FALSE);
1590: }
1591:
1592: HAL_BOOL
1593: ar5k_ar5210_set_gpio_output(struct ath_hal *hal, u_int32_t gpio)
1594: {
1595: if (gpio > AR5K_AR5210_NUM_GPIO)
1596: return (AH_FALSE);
1597:
1598: AR5K_REG_WRITE(AR5K_AR5210_GPIOCR,
1599: (AR5K_REG_READ(AR5K_AR5210_GPIOCR) &~ AR5K_AR5210_GPIOCR_ALL(gpio))
1600: | AR5K_AR5210_GPIOCR_OUT1(gpio));
1601:
1602: return (AH_TRUE);
1603: }
1604:
1605: HAL_BOOL
1606: ar5k_ar5210_set_gpio_input(struct ath_hal *hal, u_int32_t gpio)
1607: {
1608: if (gpio > AR5K_AR5210_NUM_GPIO)
1609: return (AH_FALSE);
1610:
1611: AR5K_REG_WRITE(AR5K_AR5210_GPIOCR,
1612: (AR5K_REG_READ(AR5K_AR5210_GPIOCR) &~ AR5K_AR5210_GPIOCR_ALL(gpio))
1613: | AR5K_AR5210_GPIOCR_IN(gpio));
1614:
1615: return (AH_TRUE);
1616: }
1617:
1618: u_int32_t
1619: ar5k_ar5210_get_gpio(struct ath_hal *hal, u_int32_t gpio)
1620: {
1621: if (gpio > AR5K_AR5210_NUM_GPIO)
1622: return (0xffffffff);
1623:
1624: /* GPIO input magic */
1625: return (((AR5K_REG_READ(AR5K_AR5210_GPIODI) &
1626: AR5K_AR5210_GPIOD_MASK) >> gpio) & 0x1);
1627: }
1628:
1629: HAL_BOOL
1630: ar5k_ar5210_set_gpio(struct ath_hal *hal, u_int32_t gpio, u_int32_t val)
1631: {
1632: u_int32_t data;
1633:
1634: if (gpio > AR5K_AR5210_NUM_GPIO)
1635: return (0xffffffff);
1636:
1637: /* GPIO output magic */
1638: data = AR5K_REG_READ(AR5K_AR5210_GPIODO);
1639:
1640: data &= ~(1 << gpio);
1641: data |= (val&1) << gpio;
1642:
1643: AR5K_REG_WRITE(AR5K_AR5210_GPIODO, data);
1644:
1645: return (AH_TRUE);
1646: }
1647:
1648: void
1649: ar5k_ar5210_set_gpio_intr(struct ath_hal *hal, u_int gpio,
1650: u_int32_t interrupt_level)
1651: {
1652: u_int32_t data;
1653:
1654: if (gpio > AR5K_AR5210_NUM_GPIO)
1655: return;
1656:
1657: /*
1658: * Set the GPIO interrupt
1659: */
1660: data = (AR5K_REG_READ(AR5K_AR5210_GPIOCR) &
1661: ~(AR5K_AR5210_GPIOCR_INT_SEL(gpio) | AR5K_AR5210_GPIOCR_INT_SELH |
1662: AR5K_AR5210_GPIOCR_INT_ENA | AR5K_AR5210_GPIOCR_ALL(gpio))) |
1663: (AR5K_AR5210_GPIOCR_INT_SEL(gpio) | AR5K_AR5210_GPIOCR_INT_ENA);
1664:
1665: AR5K_REG_WRITE(AR5K_AR5210_GPIOCR,
1666: interrupt_level ? data : (data | AR5K_AR5210_GPIOCR_INT_SELH));
1667:
1668: hal->ah_imr |= AR5K_AR5210_IMR_GPIO;
1669:
1670: /* Enable GPIO interrupts */
1671: AR5K_REG_ENABLE_BITS(AR5K_AR5210_IMR, AR5K_AR5210_IMR_GPIO);
1672: }
1673:
1674: u_int32_t
1675: ar5k_ar5210_get_tsf32(struct ath_hal *hal)
1676: {
1677: return (AR5K_REG_READ(AR5K_AR5210_TSF_L32));
1678: }
1679:
1680: u_int64_t
1681: ar5k_ar5210_get_tsf64(struct ath_hal *hal)
1682: {
1683: u_int64_t tsf = AR5K_REG_READ(AR5K_AR5210_TSF_U32);
1684: return (AR5K_REG_READ(AR5K_AR5210_TSF_L32) | (tsf << 32));
1685: }
1686:
1687: void
1688: ar5k_ar5210_reset_tsf(struct ath_hal *hal)
1689: {
1690: AR5K_REG_ENABLE_BITS(AR5K_AR5210_BEACON,
1691: AR5K_AR5210_BEACON_RESET_TSF);
1692: }
1693:
1694: u_int16_t
1695: ar5k_ar5210_get_regdomain(struct ath_hal *hal)
1696: {
1697: return (ar5k_get_regdomain(hal));
1698: }
1699:
1700: HAL_BOOL
1701: ar5k_ar5210_detect_card_present(struct ath_hal *hal)
1702: {
1703: u_int16_t magic;
1704:
1705: /*
1706: * Checking the EEPROM's magic value could be an indication
1707: * if the card is still present. I didn't find another suitable
1708: * way to do this.
1709: */
1710: if (ar5k_ar5210_eeprom_read(hal, AR5K_EEPROM_MAGIC, &magic) != 0)
1711: return (AH_FALSE);
1712:
1713: return (magic == AR5K_EEPROM_MAGIC_VALUE ? AH_TRUE : AH_FALSE);
1714: }
1715:
1716: void
1717: ar5k_ar5210_update_mib_counters(struct ath_hal *hal, HAL_MIB_STATS *statistics)
1718: {
1719: statistics->ackrcv_bad += AR5K_REG_READ(AR5K_AR5210_ACK_FAIL);
1720: statistics->rts_bad += AR5K_REG_READ(AR5K_AR5210_RTS_FAIL);
1721: statistics->rts_good += AR5K_REG_READ(AR5K_AR5210_RTS_OK);
1722: statistics->fcs_bad += AR5K_REG_READ(AR5K_AR5210_FCS_FAIL);
1723: statistics->beacons += AR5K_REG_READ(AR5K_AR5210_BEACON_CNT);
1724: }
1725:
1726: HAL_RFGAIN
1727: ar5k_ar5210_get_rf_gain(struct ath_hal *hal)
1728: {
1729: return (HAL_RFGAIN_INACTIVE);
1730: }
1731:
1732: HAL_BOOL
1733: ar5k_ar5210_set_slot_time(struct ath_hal *hal, u_int slot_time)
1734: {
1735: if (slot_time < HAL_SLOT_TIME_9 || slot_time > HAL_SLOT_TIME_MAX)
1736: return (AH_FALSE);
1737:
1738: AR5K_REG_WRITE(AR5K_AR5210_SLOT_TIME,
1739: ar5k_htoclock(slot_time, hal->ah_turbo));
1740:
1741: return (AH_TRUE);
1742: }
1743:
1744: u_int
1745: ar5k_ar5210_get_slot_time(struct ath_hal *hal)
1746: {
1747: return (ar5k_clocktoh(AR5K_REG_READ(AR5K_AR5210_SLOT_TIME) &
1748: 0xffff, hal->ah_turbo));
1749: }
1750:
1751: HAL_BOOL
1752: ar5k_ar5210_set_ack_timeout(struct ath_hal *hal, u_int timeout)
1753: {
1754: if (ar5k_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_AR5210_TIME_OUT_ACK),
1755: hal->ah_turbo) <= timeout)
1756: return (AH_FALSE);
1757:
1758: AR5K_REG_WRITE_BITS(AR5K_AR5210_TIME_OUT, AR5K_AR5210_TIME_OUT_ACK,
1759: ar5k_htoclock(timeout, hal->ah_turbo));
1760:
1761: return (AH_TRUE);
1762: }
1763:
1764: u_int
1765: ar5k_ar5210_get_ack_timeout(struct ath_hal *hal)
1766: {
1767: return (ar5k_clocktoh(AR5K_REG_MS(AR5K_REG_READ(AR5K_AR5210_TIME_OUT),
1768: AR5K_AR5210_TIME_OUT_ACK), hal->ah_turbo));
1769: }
1770:
1771: HAL_BOOL
1772: ar5k_ar5210_set_cts_timeout(struct ath_hal *hal, u_int timeout)
1773: {
1774: if (ar5k_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_AR5210_TIME_OUT_CTS),
1775: hal->ah_turbo) <= timeout)
1776: return (AH_FALSE);
1777:
1778: AR5K_REG_WRITE_BITS(AR5K_AR5210_TIME_OUT, AR5K_AR5210_TIME_OUT_CTS,
1779: ar5k_htoclock(timeout, hal->ah_turbo));
1780:
1781: return (AH_TRUE);
1782: }
1783:
1784: u_int
1785: ar5k_ar5210_get_cts_timeout(struct ath_hal *hal)
1786: {
1787: return (ar5k_clocktoh(AR5K_REG_MS(AR5K_REG_READ(AR5K_AR5210_TIME_OUT),
1788: AR5K_AR5210_TIME_OUT_CTS), hal->ah_turbo));
1789: }
1790:
1791: /*
1792: * Key table (WEP) functions
1793: */
1794:
1795: HAL_BOOL
1796: ar5k_ar5210_is_cipher_supported(struct ath_hal *hal, HAL_CIPHER cipher)
1797: {
1798: /*
1799: * The AR5210 only supports WEP
1800: */
1801: if (cipher == HAL_CIPHER_WEP)
1802: return (AH_TRUE);
1803:
1804: return (AH_FALSE);
1805: }
1806:
1807: u_int32_t
1808: ar5k_ar5210_get_keycache_size(struct ath_hal *hal)
1809: {
1810: return (AR5K_AR5210_KEYCACHE_SIZE);
1811: }
1812:
1813: HAL_BOOL
1814: ar5k_ar5210_reset_key(struct ath_hal *hal, u_int16_t entry)
1815: {
1816: int i;
1817:
1818: AR5K_ASSERT_ENTRY(entry, AR5K_AR5210_KEYTABLE_SIZE);
1819:
1820: for (i = 0; i < AR5K_AR5210_KEYCACHE_SIZE; i++)
1821: AR5K_REG_WRITE(AR5K_AR5210_KEYTABLE_OFF(entry, i), 0);
1822:
1823: return (AH_FALSE);
1824: }
1825:
1826: HAL_BOOL
1827: ar5k_ar5210_is_key_valid(struct ath_hal *hal, u_int16_t entry)
1828: {
1829: AR5K_ASSERT_ENTRY(entry, AR5K_AR5210_KEYTABLE_SIZE);
1830:
1831: /*
1832: * Check the validation flag at the end of the entry
1833: */
1834: if (AR5K_REG_READ(AR5K_AR5210_KEYTABLE_MAC1(entry)) &
1835: AR5K_AR5210_KEYTABLE_VALID)
1836: return (AH_TRUE);
1837:
1838: return (AH_FALSE);
1839: }
1840:
1841: HAL_BOOL
1842: ar5k_ar5210_set_key(struct ath_hal *hal, u_int16_t entry,
1843: const HAL_KEYVAL *keyval, const u_int8_t *mac, int xor_notused)
1844: {
1845: int i;
1846: u_int32_t key_v[AR5K_AR5210_KEYCACHE_SIZE - 2];
1847:
1848: AR5K_ASSERT_ENTRY(entry, AR5K_AR5210_KEYTABLE_SIZE);
1849:
1850: bzero(&key_v, sizeof(key_v));
1851:
1852: switch (keyval->wk_len) {
1853: case AR5K_KEYVAL_LENGTH_40:
1854: bcopy(keyval->wk_key, &key_v[0], 4);
1855: bcopy(keyval->wk_key + 4, &key_v[1], 1);
1856: key_v[5] = AR5K_AR5210_KEYTABLE_TYPE_40;
1857: break;
1858:
1859: case AR5K_KEYVAL_LENGTH_104:
1860: bcopy(keyval->wk_key, &key_v[0], 4);
1861: bcopy(keyval->wk_key + 4, &key_v[1], 2);
1862: bcopy(keyval->wk_key + 6, &key_v[2], 4);
1863: bcopy(keyval->wk_key + 10, &key_v[3], 2);
1864: bcopy(keyval->wk_key + 12, &key_v[4], 1);
1865: key_v[5] = AR5K_AR5210_KEYTABLE_TYPE_104;
1866: break;
1867:
1868: case AR5K_KEYVAL_LENGTH_128:
1869: bcopy(keyval->wk_key, &key_v[0], 4);
1870: bcopy(keyval->wk_key + 4, &key_v[1], 2);
1871: bcopy(keyval->wk_key + 6, &key_v[2], 4);
1872: bcopy(keyval->wk_key + 10, &key_v[3], 2);
1873: bcopy(keyval->wk_key + 12, &key_v[4], 4);
1874: key_v[5] = AR5K_AR5210_KEYTABLE_TYPE_128;
1875: break;
1876:
1877: default:
1878: /* Unsupported key length (not WEP40/104/128) */
1879: return (AH_FALSE);
1880: }
1881:
1882: for (i = 0; i < AR5K_ELEMENTS(key_v); i++)
1883: AR5K_REG_WRITE(AR5K_AR5210_KEYTABLE_OFF(entry, i), key_v[i]);
1884:
1885: return (ar5k_ar5210_set_key_lladdr(hal, entry, mac));
1886: }
1887:
1888: HAL_BOOL
1889: ar5k_ar5210_set_key_lladdr(struct ath_hal *hal, u_int16_t entry,
1890: const u_int8_t *mac)
1891: {
1892: u_int32_t low_id, high_id;
1893: const u_int8_t *mac_v;
1894:
1895: /*
1896: * Invalid entry (key table overflow)
1897: */
1898: AR5K_ASSERT_ENTRY(entry, AR5K_AR5210_KEYTABLE_SIZE);
1899:
1900: /* MAC may be NULL if it's a broadcast key */
1901: mac_v = mac == NULL ? etherbroadcastaddr : mac;
1902:
1903: low_id = AR5K_LOW_ID(mac_v);
1904: high_id = AR5K_HIGH_ID(mac_v) | AR5K_AR5210_KEYTABLE_VALID;
1905:
1906: AR5K_REG_WRITE(AR5K_AR5210_KEYTABLE_MAC0(entry), low_id);
1907: AR5K_REG_WRITE(AR5K_AR5210_KEYTABLE_MAC1(entry), high_id);
1908:
1909: return (AH_TRUE);
1910: }
1911:
1912: /*
1913: * Power management functions
1914: */
1915:
1916: HAL_BOOL
1917: ar5k_ar5210_set_power(struct ath_hal *hal, HAL_POWER_MODE mode,
1918: HAL_BOOL set_chip, u_int16_t sleep_duration)
1919: {
1920: u_int32_t staid;
1921: int i;
1922:
1923: staid = AR5K_REG_READ(AR5K_AR5210_STA_ID1);
1924:
1925: switch (mode) {
1926: case HAL_PM_AUTO:
1927: staid &= ~AR5K_AR5210_STA_ID1_DEFAULT_ANTENNA;
1928: /* FALLTHROUGH */
1929: case HAL_PM_NETWORK_SLEEP:
1930: if (set_chip == AH_TRUE) {
1931: AR5K_REG_WRITE(AR5K_AR5210_SCR,
1932: AR5K_AR5210_SCR_SLE | sleep_duration);
1933: }
1934: staid |= AR5K_AR5210_STA_ID1_PWR_SV;
1935: break;
1936:
1937: case HAL_PM_FULL_SLEEP:
1938: if (set_chip == AH_TRUE) {
1939: AR5K_REG_WRITE(AR5K_AR5210_SCR,
1940: AR5K_AR5210_SCR_SLE_SLP);
1941: }
1942: staid |= AR5K_AR5210_STA_ID1_PWR_SV;
1943: break;
1944:
1945: case HAL_PM_AWAKE:
1946: if (set_chip == AH_FALSE)
1947: goto commit;
1948:
1949: AR5K_REG_WRITE(AR5K_AR5210_SCR, AR5K_AR5210_SCR_SLE_WAKE);
1950:
1951: for (i = 5000; i > 0; i--) {
1952: /* Check if the AR5210 did wake up */
1953: if ((AR5K_REG_READ(AR5K_AR5210_PCICFG) &
1954: AR5K_AR5210_PCICFG_SPWR_DN) == 0)
1955: break;
1956:
1957: /* Wait a bit and retry */
1958: AR5K_DELAY(200);
1959: AR5K_REG_WRITE(AR5K_AR5210_SCR,
1960: AR5K_AR5210_SCR_SLE_WAKE);
1961: }
1962:
1963: /* Fail if the AR5210 didn't wake up */
1964: if (i <= 0)
1965: return (AH_FALSE);
1966:
1967: staid &= ~AR5K_AR5210_STA_ID1_PWR_SV;
1968: break;
1969:
1970: default:
1971: return (AH_FALSE);
1972: }
1973:
1974: commit:
1975: hal->ah_power_mode = mode;
1976:
1977: AR5K_REG_WRITE(AR5K_AR5210_STA_ID1, staid);
1978:
1979: return (AH_TRUE);
1980: }
1981:
1982: HAL_POWER_MODE
1983: ar5k_ar5210_get_power_mode(struct ath_hal *hal)
1984: {
1985: return (hal->ah_power_mode);
1986: }
1987:
1988: HAL_BOOL
1989: ar5k_ar5210_query_pspoll_support(struct ath_hal *hal)
1990: {
1991: /* I think so, why not? */
1992: return (AH_TRUE);
1993: }
1994:
1995: HAL_BOOL
1996: ar5k_ar5210_init_pspoll(struct ath_hal *hal)
1997: {
1998: /*
1999: * Not used on the AR5210
2000: */
2001: return (AH_FALSE);
2002: }
2003:
2004: HAL_BOOL
2005: ar5k_ar5210_enable_pspoll(struct ath_hal *hal, u_int8_t *bssid,
2006: u_int16_t assoc_id)
2007: {
2008: AR5K_REG_DISABLE_BITS(AR5K_AR5210_STA_ID1,
2009: AR5K_AR5210_STA_ID1_NO_PSPOLL |
2010: AR5K_AR5210_STA_ID1_DEFAULT_ANTENNA);
2011:
2012: return (AH_TRUE);
2013: }
2014:
2015: HAL_BOOL
2016: ar5k_ar5210_disable_pspoll(struct ath_hal *hal)
2017: {
2018: AR5K_REG_ENABLE_BITS(AR5K_AR5210_STA_ID1,
2019: AR5K_AR5210_STA_ID1_NO_PSPOLL |
2020: AR5K_AR5210_STA_ID1_DEFAULT_ANTENNA);
2021:
2022: return (AH_TRUE);
2023: }
2024:
2025: /*
2026: * Beacon functions
2027: */
2028:
2029: void
2030: ar5k_ar5210_init_beacon(struct ath_hal *hal, u_int32_t next_beacon,
2031: u_int32_t interval)
2032: {
2033: u_int32_t timer1, timer2, timer3;
2034:
2035: /*
2036: * Set the additional timers by mode
2037: */
2038: switch (hal->ah_op_mode) {
2039: case HAL_M_STA:
2040: timer1 = 0xffffffff;
2041: timer2 = 0xffffffff;
2042: timer3 = 1;
2043: break;
2044:
2045: default:
2046: timer1 = (next_beacon - AR5K_TUNE_DMA_BEACON_RESP) << 3;
2047: timer2 = (next_beacon - AR5K_TUNE_SW_BEACON_RESP) << 3;
2048: timer3 = next_beacon + hal->ah_atim_window;
2049: break;
2050: }
2051:
2052: /*
2053: * Enable all timers and set the beacon register
2054: * (next beacon, DMA beacon, software beacon, ATIM window time)
2055: */
2056: AR5K_REG_WRITE(AR5K_AR5210_TIMER0, next_beacon);
2057: AR5K_REG_WRITE(AR5K_AR5210_TIMER1, timer1);
2058: AR5K_REG_WRITE(AR5K_AR5210_TIMER2, timer2);
2059: AR5K_REG_WRITE(AR5K_AR5210_TIMER3, timer3);
2060:
2061: AR5K_REG_WRITE(AR5K_AR5210_BEACON, interval &
2062: (AR5K_AR5210_BEACON_PERIOD | AR5K_AR5210_BEACON_RESET_TSF |
2063: AR5K_AR5210_BEACON_EN));
2064: }
2065:
2066: void
2067: ar5k_ar5210_set_beacon_timers(struct ath_hal *hal,
2068: const HAL_BEACON_STATE *state, u_int32_t tsf, u_int32_t dtim_count,
2069: u_int32_t cfp_count)
2070: {
2071: u_int32_t cfp_period, next_cfp;
2072:
2073: /* Return on an invalid beacon state */
2074: if (state->bs_interval < 1)
2075: return;
2076:
2077: /*
2078: * PCF support?
2079: */
2080: if (state->bs_cfp_period > 0) {
2081: /* Enable CFP mode and set the CFP and timer registers */
2082: cfp_period = state->bs_cfp_period * state->bs_dtim_period *
2083: state->bs_interval;
2084: next_cfp = (cfp_count * state->bs_dtim_period + dtim_count) *
2085: state->bs_interval;
2086:
2087: AR5K_REG_DISABLE_BITS(AR5K_AR5210_STA_ID1,
2088: AR5K_AR5210_STA_ID1_DEFAULT_ANTENNA |
2089: AR5K_AR5210_STA_ID1_PCF);
2090: AR5K_REG_WRITE(AR5K_AR5210_CFP_PERIOD, cfp_period);
2091: AR5K_REG_WRITE(AR5K_AR5210_CFP_DUR, state->bs_cfp_max_duration);
2092: AR5K_REG_WRITE(AR5K_AR5210_TIMER2,
2093: (tsf + (next_cfp == 0 ? cfp_period : next_cfp)) << 3);
2094: } else {
2095: /* Disable PCF mode */
2096: AR5K_REG_DISABLE_BITS(AR5K_AR5210_STA_ID1,
2097: AR5K_AR5210_STA_ID1_DEFAULT_ANTENNA |
2098: AR5K_AR5210_STA_ID1_PCF);
2099: }
2100:
2101: /*
2102: * Enable the beacon timer register
2103: */
2104: AR5K_REG_WRITE(AR5K_AR5210_TIMER0, state->bs_next_beacon);
2105:
2106: /*
2107: * Start the beacon timers
2108: */
2109: AR5K_REG_WRITE(AR5K_AR5210_BEACON,
2110: (AR5K_REG_READ(AR5K_AR5210_BEACON) &~
2111: (AR5K_AR5210_BEACON_PERIOD | AR5K_AR5210_BEACON_TIM)) |
2112: AR5K_REG_SM(state->bs_tim_offset ? state->bs_tim_offset + 4 : 0,
2113: AR5K_AR5210_BEACON_TIM) |
2114: AR5K_REG_SM(state->bs_interval, AR5K_AR5210_BEACON_PERIOD));
2115:
2116: /*
2117: * Write new beacon miss threshold, if it appears to be valid
2118: */
2119: if (state->bs_bmiss_threshold <=
2120: (AR5K_AR5210_RSSI_THR_BM_THR >> AR5K_AR5210_RSSI_THR_BM_THR_S)) {
2121: AR5K_REG_WRITE_BITS(AR5K_AR5210_RSSI_THR,
2122: AR5K_AR5210_RSSI_THR_BM_THR, state->bs_bmiss_threshold);
2123: }
2124: }
2125:
2126: void
2127: ar5k_ar5210_reset_beacon(struct ath_hal *hal)
2128: {
2129: /*
2130: * Disable beacon timer
2131: */
2132: AR5K_REG_WRITE(AR5K_AR5210_TIMER0, 0);
2133:
2134: /*
2135: * Disable some beacon register values
2136: */
2137: AR5K_REG_DISABLE_BITS(AR5K_AR5210_STA_ID1,
2138: AR5K_AR5210_STA_ID1_DEFAULT_ANTENNA | AR5K_AR5210_STA_ID1_PCF);
2139: AR5K_REG_WRITE(AR5K_AR5210_BEACON, AR5K_AR5210_BEACON_PERIOD);
2140: }
2141:
2142: HAL_BOOL
2143: ar5k_ar5210_wait_for_beacon(struct ath_hal *hal, bus_addr_t phys_addr)
2144: {
2145: int i;
2146:
2147: /*
2148: * Wait for beaconn queue to be done
2149: */
2150: for (i = (AR5K_TUNE_BEACON_INTERVAL / 2); i > 0 &&
2151: (AR5K_REG_READ(AR5K_AR5210_BSR) &
2152: AR5K_AR5210_BSR_TXQ1F) != 0 &&
2153: (AR5K_REG_READ(AR5K_AR5210_CR) &
2154: AR5K_AR5210_CR_TXE1) != 0; i--);
2155:
2156: /* Timeout... */
2157: if (i <= 0) {
2158: /*
2159: * Re-schedule the beacon queue
2160: */
2161: AR5K_REG_WRITE(AR5K_AR5210_TXDP1, (u_int32_t)phys_addr);
2162: AR5K_REG_WRITE(AR5K_AR5210_BCR,
2163: AR5K_AR5210_BCR_TQ1V | AR5K_AR5210_BCR_BDMAE);
2164:
2165: return (AH_FALSE);
2166: }
2167:
2168: return (AH_TRUE);
2169: }
2170:
2171: /*
2172: * Interrupt handling
2173: */
2174:
2175: HAL_BOOL
2176: ar5k_ar5210_is_intr_pending(struct ath_hal *hal)
2177: {
2178: return (AR5K_REG_READ(AR5K_AR5210_INTPEND) == 0 ? AH_FALSE : AH_TRUE);
2179: }
2180:
2181: HAL_BOOL
2182: ar5k_ar5210_get_isr(struct ath_hal *hal, u_int32_t *interrupt_mask)
2183: {
2184: u_int32_t data;
2185:
2186: if ((data = AR5K_REG_READ(AR5K_AR5210_ISR)) == HAL_INT_NOCARD) {
2187: *interrupt_mask = data;
2188: return (AH_FALSE);
2189: }
2190:
2191: /*
2192: * Get abstract interrupt mask (HAL-compatible)
2193: */
2194: *interrupt_mask = (data & HAL_INT_COMMON) & hal->ah_imr;
2195:
2196: if (data & (AR5K_AR5210_ISR_RXOK | AR5K_AR5210_ISR_RXERR))
2197: *interrupt_mask |= HAL_INT_RX;
2198: if (data & (AR5K_AR5210_ISR_TXOK | AR5K_AR5210_ISR_TXERR))
2199: *interrupt_mask |= HAL_INT_TX;
2200: if (data & AR5K_AR5210_ISR_FATAL)
2201: *interrupt_mask |= HAL_INT_FATAL;
2202:
2203: /*
2204: * Special interrupt handling (not caught by the driver)
2205: */
2206: if (((*interrupt_mask) & AR5K_AR5210_ISR_RXPHY) &&
2207: hal->ah_radar.r_enabled == AH_TRUE)
2208: ar5k_radar_alert(hal);
2209:
2210: /* XXX BMISS interrupts may occur after association */
2211: *interrupt_mask &= ~HAL_INT_BMISS;
2212:
2213: return (AH_TRUE);
2214: }
2215:
2216: u_int32_t
2217: ar5k_ar5210_get_intr(struct ath_hal *hal)
2218: {
2219: /* Return the interrupt mask stored previously */
2220: return (hal->ah_imr);
2221: }
2222:
2223: HAL_INT
2224: ar5k_ar5210_set_intr(struct ath_hal *hal, HAL_INT new_mask)
2225: {
2226: HAL_INT old_mask, int_mask;
2227:
2228: /*
2229: * Disable card interrupts to prevent any race conditions
2230: * (they will be re-enabled afterwards).
2231: */
2232: AR5K_REG_WRITE(AR5K_AR5210_IER, AR5K_AR5210_IER_DISABLE);
2233:
2234: old_mask = hal->ah_imr;
2235:
2236: /*
2237: * Add additional, chipset-dependent interrupt mask flags
2238: * and write them to the IMR (interrupt mask register).
2239: */
2240: int_mask = new_mask & HAL_INT_COMMON;
2241:
2242: if (new_mask & HAL_INT_RX)
2243: int_mask |=
2244: AR5K_AR5210_IMR_RXOK |
2245: AR5K_AR5210_IMR_RXERR |
2246: AR5K_AR5210_IMR_RXORN;
2247:
2248: if (new_mask & HAL_INT_TX)
2249: int_mask |=
2250: AR5K_AR5210_IMR_TXOK |
2251: AR5K_AR5210_IMR_TXERR |
2252: AR5K_AR5210_IMR_TXURN;
2253:
2254: AR5K_REG_WRITE(AR5K_AR5210_IMR, int_mask);
2255:
2256: /* Store new interrupt mask */
2257: hal->ah_imr = new_mask;
2258:
2259: /* ..re-enable interrupts */
2260: if (int_mask) {
2261: AR5K_REG_WRITE(AR5K_AR5210_IER, AR5K_AR5210_IER_ENABLE);
2262: }
2263:
2264: return (old_mask);
2265: }
2266:
2267: /*
2268: * Misc internal functions
2269: */
2270:
2271: HAL_BOOL
2272: ar5k_ar5210_get_capabilities(struct ath_hal *hal)
2273: {
2274: /* Set number of supported TX queues */
2275: hal->ah_capabilities.cap_queues.q_tx_num = AR5K_AR5210_TX_NUM_QUEUES;
2276:
2277: /*
2278: * Set radio capabilities
2279: * (The AR5210 only supports the middle 5GHz band)
2280: */
2281: hal->ah_capabilities.cap_range.range_5ghz_min = 5120;
2282: hal->ah_capabilities.cap_range.range_5ghz_max = 5430;
2283: hal->ah_capabilities.cap_range.range_2ghz_min = 0;
2284: hal->ah_capabilities.cap_range.range_2ghz_max = 0;
2285:
2286: /* Set supported modes */
2287: hal->ah_capabilities.cap_mode = HAL_MODE_11A | HAL_MODE_TURBO;
2288:
2289: /* Set number of GPIO pins */
2290: hal->ah_gpio_npins = AR5K_AR5210_NUM_GPIO;
2291:
2292: return (AH_TRUE);
2293: }
2294:
2295: void
2296: ar5k_ar5210_radar_alert(struct ath_hal *hal, HAL_BOOL enable)
2297: {
2298: /*
2299: * Set the RXPHY interrupt to be able to detect
2300: * possible radar activity.
2301: */
2302: AR5K_REG_WRITE(AR5K_AR5210_IER, AR5K_AR5210_IER_DISABLE);
2303:
2304: if (enable == AH_TRUE) {
2305: AR5K_REG_ENABLE_BITS(AR5K_AR5210_IMR,
2306: AR5K_AR5210_IMR_RXPHY);
2307: } else {
2308: AR5K_REG_DISABLE_BITS(AR5K_AR5210_IMR,
2309: AR5K_AR5210_IMR_RXPHY);
2310: }
2311:
2312: AR5K_REG_WRITE(AR5K_AR5210_IER, AR5K_AR5210_IER_ENABLE);
2313: }
2314:
2315: /*
2316: * EEPROM access functions
2317: */
2318:
2319: HAL_BOOL
2320: ar5k_ar5210_eeprom_is_busy(struct ath_hal *hal)
2321: {
2322: return (AR5K_REG_READ(AR5K_AR5210_CFG) & AR5K_AR5210_CFG_EEBS ?
2323: AH_TRUE : AH_FALSE);
2324: }
2325:
2326: int
2327: ar5k_ar5210_eeprom_read(struct ath_hal *hal, u_int32_t offset, u_int16_t *data)
2328: {
2329: u_int32_t status, timeout;
2330:
2331: /* Enable eeprom access */
2332: AR5K_REG_ENABLE_BITS(AR5K_AR5210_PCICFG, AR5K_AR5210_PCICFG_EEAE);
2333:
2334: /*
2335: * Prime read pump
2336: */
2337: (void)AR5K_REG_READ(AR5K_AR5210_EEPROM_BASE + (4 * offset));
2338:
2339: for (timeout = 10000; timeout > 0; timeout--) {
2340: AR5K_DELAY(1);
2341: status = AR5K_REG_READ(AR5K_AR5210_EEPROM_STATUS);
2342: if (status & AR5K_AR5210_EEPROM_STAT_RDDONE) {
2343: if (status & AR5K_AR5210_EEPROM_STAT_RDERR)
2344: return (EIO);
2345: *data = (u_int16_t)
2346: (AR5K_REG_READ(AR5K_AR5210_EEPROM_RDATA) & 0xffff);
2347: return (0);
2348: }
2349: }
2350:
2351: return (ETIMEDOUT);
2352: }
2353:
2354: int
2355: ar5k_ar5210_eeprom_write(struct ath_hal *hal, u_int32_t offset, u_int16_t data)
2356: {
2357: u_int32_t status, timeout;
2358:
2359: /* Enable eeprom access */
2360: AR5K_REG_ENABLE_BITS(AR5K_AR5210_PCICFG, AR5K_AR5210_PCICFG_EEAE);
2361:
2362: /*
2363: * Prime write pump
2364: */
2365: AR5K_REG_WRITE(AR5K_AR5210_EEPROM_BASE + (4 * offset), data);
2366:
2367: for (timeout = 10000; timeout > 0; timeout--) {
2368: AR5K_DELAY(1);
2369: status = AR5K_REG_READ(AR5K_AR5210_EEPROM_STATUS);
2370: if (status & AR5K_AR5210_EEPROM_STAT_WRDONE) {
2371: if (status & AR5K_AR5210_EEPROM_STAT_WRERR)
2372: return (EIO);
2373: return (0);
2374: }
2375: }
2376:
2377: return (ETIMEDOUT);
2378: }
2379:
2380: HAL_BOOL
2381: ar5k_ar5210_set_txpower_limit(struct ath_hal *hal, u_int power)
2382: {
2383: /* Not implemented */
2384: return (AH_FALSE);
2385: }
CVSweb