Annotation of sys/dev/ic/ar5211.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: ar5211.c,v 1.34 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 AR5001 Wireless LAN chipset
! 21: * (AR5211 + AR5111).
! 22: */
! 23:
! 24: #include <dev/ic/ar5xxx.h>
! 25: #include <dev/ic/ar5211reg.h>
! 26: #include <dev/ic/ar5211var.h>
! 27:
! 28: HAL_BOOL ar5k_ar5211_nic_reset(struct ath_hal *, u_int32_t);
! 29: HAL_BOOL ar5k_ar5211_nic_wakeup(struct ath_hal *, u_int16_t);
! 30: u_int16_t ar5k_ar5211_radio_revision(struct ath_hal *, HAL_CHIP);
! 31: const void ar5k_ar5211_fill(struct ath_hal *);
! 32: void ar5k_ar5211_rfregs(struct ath_hal *, HAL_CHANNEL *, u_int,
! 33: u_int);
! 34:
! 35: /*
! 36: * Initial register setting for the AR5211
! 37: */
! 38: static const struct ar5k_ini ar5211_ini[] =
! 39: AR5K_AR5211_INI;
! 40: static const struct ar5k_ar5211_ini_mode ar5211_mode[] =
! 41: AR5K_AR5211_INI_MODE;
! 42: static const struct ar5k_ar5211_ini_rf ar5211_rf[] =
! 43: AR5K_AR5211_INI_RF;
! 44:
! 45: AR5K_HAL_FUNCTIONS(extern, ar5k_ar5211,);
! 46:
! 47: const void
! 48: ar5k_ar5211_fill(struct ath_hal *hal)
! 49: {
! 50: hal->ah_magic = AR5K_AR5211_MAGIC;
! 51:
! 52: /*
! 53: * Init/Exit functions
! 54: */
! 55: AR5K_HAL_FUNCTION(hal, ar5211, get_rate_table);
! 56: AR5K_HAL_FUNCTION(hal, ar5211, detach);
! 57:
! 58: /*
! 59: * Reset functions
! 60: */
! 61: AR5K_HAL_FUNCTION(hal, ar5211, reset);
! 62: AR5K_HAL_FUNCTION(hal, ar5211, set_opmode);
! 63: AR5K_HAL_FUNCTION(hal, ar5211, calibrate);
! 64:
! 65: /*
! 66: * TX functions
! 67: */
! 68: AR5K_HAL_FUNCTION(hal, ar5211, update_tx_triglevel);
! 69: AR5K_HAL_FUNCTION(hal, ar5211, setup_tx_queue);
! 70: AR5K_HAL_FUNCTION(hal, ar5211, setup_tx_queueprops);
! 71: AR5K_HAL_FUNCTION(hal, ar5211, release_tx_queue);
! 72: AR5K_HAL_FUNCTION(hal, ar5211, reset_tx_queue);
! 73: AR5K_HAL_FUNCTION(hal, ar5211, get_tx_buf);
! 74: AR5K_HAL_FUNCTION(hal, ar5211, put_tx_buf);
! 75: AR5K_HAL_FUNCTION(hal, ar5211, tx_start);
! 76: AR5K_HAL_FUNCTION(hal, ar5211, stop_tx_dma);
! 77: AR5K_HAL_FUNCTION(hal, ar5211, setup_tx_desc);
! 78: AR5K_HAL_FUNCTION(hal, ar5211, setup_xtx_desc);
! 79: AR5K_HAL_FUNCTION(hal, ar5211, fill_tx_desc);
! 80: AR5K_HAL_FUNCTION(hal, ar5211, proc_tx_desc);
! 81: AR5K_HAL_FUNCTION(hal, ar5211, has_veol);
! 82:
! 83: /*
! 84: * RX functions
! 85: */
! 86: AR5K_HAL_FUNCTION(hal, ar5211, get_rx_buf);
! 87: AR5K_HAL_FUNCTION(hal, ar5211, put_rx_buf);
! 88: AR5K_HAL_FUNCTION(hal, ar5211, start_rx);
! 89: AR5K_HAL_FUNCTION(hal, ar5211, stop_rx_dma);
! 90: AR5K_HAL_FUNCTION(hal, ar5211, start_rx_pcu);
! 91: AR5K_HAL_FUNCTION(hal, ar5211, stop_pcu_recv);
! 92: AR5K_HAL_FUNCTION(hal, ar5211, set_mcast_filter);
! 93: AR5K_HAL_FUNCTION(hal, ar5211, set_mcast_filterindex);
! 94: AR5K_HAL_FUNCTION(hal, ar5211, clear_mcast_filter_idx);
! 95: AR5K_HAL_FUNCTION(hal, ar5211, get_rx_filter);
! 96: AR5K_HAL_FUNCTION(hal, ar5211, set_rx_filter);
! 97: AR5K_HAL_FUNCTION(hal, ar5211, setup_rx_desc);
! 98: AR5K_HAL_FUNCTION(hal, ar5211, proc_rx_desc);
! 99: AR5K_HAL_FUNCTION(hal, ar5211, set_rx_signal);
! 100:
! 101: /*
! 102: * Misc functions
! 103: */
! 104: AR5K_HAL_FUNCTION(hal, ar5211, dump_state);
! 105: AR5K_HAL_FUNCTION(hal, ar5211, get_diag_state);
! 106: AR5K_HAL_FUNCTION(hal, ar5211, get_lladdr);
! 107: AR5K_HAL_FUNCTION(hal, ar5211, set_lladdr);
! 108: AR5K_HAL_FUNCTION(hal, ar5211, set_regdomain);
! 109: AR5K_HAL_FUNCTION(hal, ar5211, set_ledstate);
! 110: AR5K_HAL_FUNCTION(hal, ar5211, set_associd);
! 111: AR5K_HAL_FUNCTION(hal, ar5211, set_gpio_input);
! 112: AR5K_HAL_FUNCTION(hal, ar5211, set_gpio_output);
! 113: AR5K_HAL_FUNCTION(hal, ar5211, get_gpio);
! 114: AR5K_HAL_FUNCTION(hal, ar5211, set_gpio);
! 115: AR5K_HAL_FUNCTION(hal, ar5211, set_gpio_intr);
! 116: AR5K_HAL_FUNCTION(hal, ar5211, get_tsf32);
! 117: AR5K_HAL_FUNCTION(hal, ar5211, get_tsf64);
! 118: AR5K_HAL_FUNCTION(hal, ar5211, reset_tsf);
! 119: AR5K_HAL_FUNCTION(hal, ar5211, get_regdomain);
! 120: AR5K_HAL_FUNCTION(hal, ar5211, detect_card_present);
! 121: AR5K_HAL_FUNCTION(hal, ar5211, update_mib_counters);
! 122: AR5K_HAL_FUNCTION(hal, ar5211, get_rf_gain);
! 123: AR5K_HAL_FUNCTION(hal, ar5211, set_slot_time);
! 124: AR5K_HAL_FUNCTION(hal, ar5211, get_slot_time);
! 125: AR5K_HAL_FUNCTION(hal, ar5211, set_ack_timeout);
! 126: AR5K_HAL_FUNCTION(hal, ar5211, get_ack_timeout);
! 127: AR5K_HAL_FUNCTION(hal, ar5211, set_cts_timeout);
! 128: AR5K_HAL_FUNCTION(hal, ar5211, get_cts_timeout);
! 129:
! 130: /*
! 131: * Key table (WEP) functions
! 132: */
! 133: AR5K_HAL_FUNCTION(hal, ar5211, is_cipher_supported);
! 134: AR5K_HAL_FUNCTION(hal, ar5211, get_keycache_size);
! 135: AR5K_HAL_FUNCTION(hal, ar5211, reset_key);
! 136: AR5K_HAL_FUNCTION(hal, ar5211, is_key_valid);
! 137: AR5K_HAL_FUNCTION(hal, ar5211, set_key);
! 138: AR5K_HAL_FUNCTION(hal, ar5211, set_key_lladdr);
! 139:
! 140: /*
! 141: * Power management functions
! 142: */
! 143: AR5K_HAL_FUNCTION(hal, ar5211, set_power);
! 144: AR5K_HAL_FUNCTION(hal, ar5211, get_power_mode);
! 145: AR5K_HAL_FUNCTION(hal, ar5211, query_pspoll_support);
! 146: AR5K_HAL_FUNCTION(hal, ar5211, init_pspoll);
! 147: AR5K_HAL_FUNCTION(hal, ar5211, enable_pspoll);
! 148: AR5K_HAL_FUNCTION(hal, ar5211, disable_pspoll);
! 149:
! 150: /*
! 151: * Beacon functions
! 152: */
! 153: AR5K_HAL_FUNCTION(hal, ar5211, init_beacon);
! 154: AR5K_HAL_FUNCTION(hal, ar5211, set_beacon_timers);
! 155: AR5K_HAL_FUNCTION(hal, ar5211, reset_beacon);
! 156: AR5K_HAL_FUNCTION(hal, ar5211, wait_for_beacon);
! 157:
! 158: /*
! 159: * Interrupt functions
! 160: */
! 161: AR5K_HAL_FUNCTION(hal, ar5211, is_intr_pending);
! 162: AR5K_HAL_FUNCTION(hal, ar5211, get_isr);
! 163: AR5K_HAL_FUNCTION(hal, ar5211, get_intr);
! 164: AR5K_HAL_FUNCTION(hal, ar5211, set_intr);
! 165:
! 166: /*
! 167: * Chipset functions (ar5k-specific, non-HAL)
! 168: */
! 169: AR5K_HAL_FUNCTION(hal, ar5211, get_capabilities);
! 170: AR5K_HAL_FUNCTION(hal, ar5211, radar_alert);
! 171:
! 172: /*
! 173: * EEPROM access
! 174: */
! 175: AR5K_HAL_FUNCTION(hal, ar5211, eeprom_is_busy);
! 176: AR5K_HAL_FUNCTION(hal, ar5211, eeprom_read);
! 177: AR5K_HAL_FUNCTION(hal, ar5211, eeprom_write);
! 178:
! 179: /*
! 180: * Unused functions or functions not implemented
! 181: */
! 182: AR5K_HAL_FUNCTION(hal, ar5211, get_tx_queueprops);
! 183: AR5K_HAL_FUNCTION(hal, ar5211, num_tx_pending);
! 184: AR5K_HAL_FUNCTION(hal, ar5211, phy_disable);
! 185: AR5K_HAL_FUNCTION(hal, ar5211, set_txpower_limit);
! 186: AR5K_HAL_FUNCTION(hal, ar5211, set_def_antenna);
! 187: AR5K_HAL_FUNCTION(hal, ar5211, get_def_antenna);
! 188: AR5K_HAL_FUNCTION(hal, ar5211, set_bssid_mask);
! 189: #ifdef notyet
! 190: AR5K_HAL_FUNCTION(hal, ar5211, set_capability);
! 191: AR5K_HAL_FUNCTION(hal, ar5211, proc_mib_event);
! 192: AR5K_HAL_FUNCTION(hal, ar5211, get_tx_inter_queue);
! 193: #endif
! 194: }
! 195:
! 196: struct ath_hal *
! 197: ar5k_ar5211_attach(u_int16_t device, void *sc, bus_space_tag_t st,
! 198: bus_space_handle_t sh, int *status)
! 199: {
! 200: struct ath_hal *hal = (struct ath_hal*) sc;
! 201: u_int8_t mac[IEEE80211_ADDR_LEN];
! 202: u_int32_t srev;
! 203:
! 204: ar5k_ar5211_fill(hal);
! 205:
! 206: /* Bring device out of sleep and reset its units */
! 207: if (ar5k_ar5211_nic_wakeup(hal, AR5K_INIT_MODE) != AH_TRUE)
! 208: return (NULL);
! 209:
! 210: /* Get MAC, PHY and RADIO revisions */
! 211: srev = AR5K_REG_READ(AR5K_AR5211_SREV);
! 212: hal->ah_mac_srev = srev;
! 213: hal->ah_mac_version = AR5K_REG_MS(srev, AR5K_AR5211_SREV_VER);
! 214: hal->ah_mac_revision = AR5K_REG_MS(srev, AR5K_AR5211_SREV_REV);
! 215: hal->ah_phy_revision = AR5K_REG_READ(AR5K_AR5211_PHY_CHIP_ID) &
! 216: 0x00ffffffff;
! 217: hal->ah_radio_5ghz_revision =
! 218: ar5k_ar5211_radio_revision(hal, HAL_CHIP_5GHZ);
! 219: hal->ah_radio_2ghz_revision = 0;
! 220:
! 221: /* Identify the chipset (this has to be done in an early step) */
! 222: hal->ah_version = AR5K_AR5211;
! 223: hal->ah_radio = AR5K_AR5111;
! 224: hal->ah_phy = AR5K_AR5211_PHY(0);
! 225:
! 226: bcopy(etherbroadcastaddr, mac, IEEE80211_ADDR_LEN);
! 227: ar5k_ar5211_set_associd(hal, mac, 0, 0);
! 228: ar5k_ar5211_get_lladdr(hal, mac);
! 229: ar5k_ar5211_set_opmode(hal);
! 230:
! 231: return (hal);
! 232: }
! 233:
! 234: HAL_BOOL
! 235: ar5k_ar5211_nic_reset(struct ath_hal *hal, u_int32_t val)
! 236: {
! 237: HAL_BOOL ret = AH_FALSE;
! 238: u_int32_t mask = val ? val : ~0;
! 239:
! 240: /* Read-and-clear */
! 241: AR5K_REG_READ(AR5K_AR5211_RXDP);
! 242:
! 243: /*
! 244: * Reset the device and wait until success
! 245: */
! 246: AR5K_REG_WRITE(AR5K_AR5211_RC, val);
! 247:
! 248: /* Wait at least 128 PCI clocks */
! 249: AR5K_DELAY(15);
! 250:
! 251: val &=
! 252: AR5K_AR5211_RC_PCU | AR5K_AR5211_RC_BB;
! 253:
! 254: mask &=
! 255: AR5K_AR5211_RC_PCU | AR5K_AR5211_RC_BB;
! 256:
! 257: ret = ar5k_register_timeout(hal, AR5K_AR5211_RC, mask, val, AH_FALSE);
! 258:
! 259: /*
! 260: * Reset configuration register
! 261: */
! 262: if ((val & AR5K_AR5211_RC_PCU) == 0)
! 263: AR5K_REG_WRITE(AR5K_AR5211_CFG, AR5K_AR5211_INIT_CFG);
! 264:
! 265: return (ret);
! 266: }
! 267:
! 268: HAL_BOOL
! 269: ar5k_ar5211_nic_wakeup(struct ath_hal *hal, u_int16_t flags)
! 270: {
! 271: u_int32_t turbo, mode, clock;
! 272:
! 273: turbo = 0;
! 274: mode = 0;
! 275: clock = 0;
! 276:
! 277: /*
! 278: * Get channel mode flags
! 279: */
! 280:
! 281: if (flags & IEEE80211_CHAN_2GHZ) {
! 282: mode |= AR5K_AR5211_PHY_MODE_FREQ_2GHZ;
! 283: clock |= AR5K_AR5211_PHY_PLL_44MHZ;
! 284: } else if (flags & IEEE80211_CHAN_5GHZ) {
! 285: mode |= AR5K_AR5211_PHY_MODE_FREQ_5GHZ;
! 286: clock |= AR5K_AR5211_PHY_PLL_40MHZ;
! 287: } else {
! 288: AR5K_PRINT("invalid radio frequency mode\n");
! 289: return (AH_FALSE);
! 290: }
! 291:
! 292: if ((flags & IEEE80211_CHAN_CCK) ||
! 293: (flags & IEEE80211_CHAN_DYN)) {
! 294: /* Dynamic OFDM/CCK is not supported by the AR5211 */
! 295: mode |= AR5K_AR5211_PHY_MODE_MOD_CCK;
! 296: } else if (flags & IEEE80211_CHAN_OFDM) {
! 297: mode |= AR5K_AR5211_PHY_MODE_MOD_OFDM;
! 298: } else {
! 299: AR5K_PRINT("invalid radio frequency mode\n");
! 300: return (AH_FALSE);
! 301: }
! 302:
! 303: if (flags & IEEE80211_CHAN_TURBO) {
! 304: turbo = AR5K_AR5211_PHY_TURBO_MODE |
! 305: AR5K_AR5211_PHY_TURBO_SHORT;
! 306: }
! 307:
! 308: /*
! 309: * Reset and wakeup the device
! 310: */
! 311:
! 312: /* ...reset chipset and PCI device */
! 313: if (ar5k_ar5211_nic_reset(hal,
! 314: AR5K_AR5211_RC_CHIP | AR5K_AR5211_RC_PCI) == AH_FALSE) {
! 315: AR5K_PRINT("failed to reset the AR5211 + PCI chipset\n");
! 316: return (AH_FALSE);
! 317: }
! 318:
! 319: /* ...wakeup */
! 320: if (ar5k_ar5211_set_power(hal,
! 321: HAL_PM_AWAKE, AH_TRUE, 0) == AH_FALSE) {
! 322: AR5K_PRINT("failed to resume the AR5211 (again)\n");
! 323: return (AH_FALSE);
! 324: }
! 325:
! 326: /* ...final warm reset */
! 327: if (ar5k_ar5211_nic_reset(hal, 0) == AH_FALSE) {
! 328: AR5K_PRINT("failed to warm reset the AR5211\n");
! 329: return (AH_FALSE);
! 330: }
! 331:
! 332: /* ...set the PHY operating mode */
! 333: AR5K_REG_WRITE(AR5K_AR5211_PHY_PLL, clock);
! 334: AR5K_DELAY(300);
! 335:
! 336: AR5K_REG_WRITE(AR5K_AR5211_PHY_MODE, mode);
! 337: AR5K_REG_WRITE(AR5K_AR5211_PHY_TURBO, turbo);
! 338:
! 339: return (AH_TRUE);
! 340: }
! 341:
! 342: u_int16_t
! 343: ar5k_ar5211_radio_revision(struct ath_hal *hal, HAL_CHIP chip)
! 344: {
! 345: int i;
! 346: u_int32_t srev;
! 347: u_int16_t ret;
! 348:
! 349: /*
! 350: * Set the radio chip access register
! 351: */
! 352: switch (chip) {
! 353: case HAL_CHIP_2GHZ:
! 354: AR5K_REG_WRITE(AR5K_AR5211_PHY(0), AR5K_AR5211_PHY_SHIFT_2GHZ);
! 355: break;
! 356: case HAL_CHIP_5GHZ:
! 357: AR5K_REG_WRITE(AR5K_AR5211_PHY(0), AR5K_AR5211_PHY_SHIFT_5GHZ);
! 358: break;
! 359: default:
! 360: return (0);
! 361: }
! 362:
! 363: AR5K_DELAY(2000);
! 364:
! 365: /* ...wait until PHY is ready and read the selected radio revision */
! 366: AR5K_REG_WRITE(AR5K_AR5211_PHY(0x34), 0x00001c16);
! 367:
! 368: for (i = 0; i < 8; i++)
! 369: AR5K_REG_WRITE(AR5K_AR5211_PHY(0x20), 0x00010000);
! 370: srev = (AR5K_REG_READ(AR5K_AR5211_PHY(0x100)) >> 24) & 0xff;
! 371:
! 372: ret = ar5k_bitswap(((srev & 0xf0) >> 4) | ((srev & 0x0f) << 4), 8);
! 373:
! 374: /* Reset to the 5GHz mode */
! 375: AR5K_REG_WRITE(AR5K_AR5211_PHY(0), AR5K_AR5211_PHY_SHIFT_5GHZ);
! 376:
! 377: return (ret);
! 378: }
! 379:
! 380: const HAL_RATE_TABLE *
! 381: ar5k_ar5211_get_rate_table(struct ath_hal *hal, u_int mode)
! 382: {
! 383: switch (mode) {
! 384: case HAL_MODE_11A:
! 385: return (&hal->ah_rt_11a);
! 386: case HAL_MODE_TURBO:
! 387: return (&hal->ah_rt_turbo);
! 388: case HAL_MODE_11B:
! 389: return (&hal->ah_rt_11b);
! 390: case HAL_MODE_11G:
! 391: case HAL_MODE_PUREG:
! 392: return (&hal->ah_rt_11g);
! 393: default:
! 394: return (NULL);
! 395: }
! 396:
! 397: return (NULL);
! 398: }
! 399:
! 400: void
! 401: ar5k_ar5211_detach(struct ath_hal *hal)
! 402: {
! 403: /*
! 404: * Free HAL structure, assume interrupts are down
! 405: */
! 406: free(hal, M_DEVBUF);
! 407: }
! 408:
! 409: HAL_BOOL
! 410: ar5k_ar5211_phy_disable(struct ath_hal *hal)
! 411: {
! 412: AR5K_REG_WRITE(AR5K_AR5211_PHY_ACTIVE, AR5K_AR5211_PHY_DISABLE);
! 413: return (AH_TRUE);
! 414: }
! 415:
! 416: HAL_BOOL
! 417: ar5k_ar5211_reset(struct ath_hal *hal, HAL_OPMODE op_mode, HAL_CHANNEL *channel,
! 418: HAL_BOOL change_channel, HAL_STATUS *status)
! 419: {
! 420: struct ar5k_eeprom_info *ee = &hal->ah_capabilities.cap_eeprom;
! 421: u_int8_t mac[IEEE80211_ADDR_LEN];
! 422: u_int32_t data, s_seq, s_ant, s_led[3];
! 423: u_int i, mode, freq, ee_mode, ant[2];
! 424:
! 425: /*
! 426: * Save some registers before a reset
! 427: */
! 428: if (change_channel == AH_TRUE) {
! 429: s_seq = AR5K_REG_READ(AR5K_AR5211_DCU_SEQNUM(0));
! 430: s_ant = AR5K_REG_READ(AR5K_AR5211_DEFAULT_ANTENNA);
! 431: } else {
! 432: s_seq = 0;
! 433: s_ant = 1;
! 434: }
! 435:
! 436: s_led[0] = AR5K_REG_READ(AR5K_AR5211_PCICFG) &
! 437: AR5K_AR5211_PCICFG_LEDSTATE;
! 438: s_led[1] = AR5K_REG_READ(AR5K_AR5211_GPIOCR);
! 439: s_led[2] = AR5K_REG_READ(AR5K_AR5211_GPIODO);
! 440:
! 441: if (ar5k_ar5211_nic_wakeup(hal, channel->c_channel_flags) == AH_FALSE)
! 442: return (AH_FALSE);
! 443:
! 444: /*
! 445: * Initialize operating mode
! 446: */
! 447: hal->ah_op_mode = op_mode;
! 448:
! 449: switch (channel->c_channel_flags & CHANNEL_MODES) {
! 450: case CHANNEL_A:
! 451: mode = AR5K_INI_VAL_11A;
! 452: freq = AR5K_INI_RFGAIN_5GHZ;
! 453: ee_mode = AR5K_EEPROM_MODE_11A;
! 454: break;
! 455: case CHANNEL_T:
! 456: mode = AR5K_INI_VAL_11A_TURBO;
! 457: freq = AR5K_INI_RFGAIN_5GHZ;
! 458: ee_mode = AR5K_EEPROM_MODE_11A;
! 459: break;
! 460: case CHANNEL_B:
! 461: mode = AR5K_INI_VAL_11B;
! 462: freq = AR5K_INI_RFGAIN_2GHZ;
! 463: ee_mode = AR5K_EEPROM_MODE_11B;
! 464: break;
! 465: case CHANNEL_G:
! 466: case CHANNEL_PUREG:
! 467: mode = AR5K_INI_VAL_11G;
! 468: freq = AR5K_INI_RFGAIN_2GHZ;
! 469: ee_mode = AR5K_EEPROM_MODE_11G;
! 470: break;
! 471: default:
! 472: AR5K_PRINTF("invalid channel: %d\n", channel->c_channel);
! 473: return (AH_FALSE);
! 474: }
! 475:
! 476: /* PHY access enable */
! 477: AR5K_REG_WRITE(AR5K_AR5211_PHY(0), AR5K_AR5211_PHY_SHIFT_5GHZ);
! 478:
! 479: /*
! 480: * Write initial RF registers
! 481: */
! 482: ar5k_ar5211_rfregs(hal, channel, freq, ee_mode);
! 483:
! 484: /*
! 485: * Write initial mode settings
! 486: */
! 487: for (i = 0; i < AR5K_ELEMENTS(ar5211_mode); i++) {
! 488: AR5K_REG_WAIT(i);
! 489: AR5K_REG_WRITE((u_int32_t)ar5211_mode[i].mode_register,
! 490: ar5211_mode[i].mode_value[mode]);
! 491: }
! 492:
! 493: /*
! 494: * Write initial register settings
! 495: */
! 496: for (i = 0; i < AR5K_ELEMENTS(ar5211_ini); i++) {
! 497: if (change_channel == AH_TRUE &&
! 498: ar5211_ini[i].ini_register >= AR5K_AR5211_PCU_MIN &&
! 499: ar5211_ini[i].ini_register <= AR5K_AR5211_PCU_MAX)
! 500: continue;
! 501:
! 502: AR5K_REG_WAIT(i);
! 503: AR5K_REG_WRITE((u_int32_t)ar5211_ini[i].ini_register,
! 504: ar5211_ini[i].ini_value);
! 505: }
! 506:
! 507: /*
! 508: * Write initial RF gain settings
! 509: */
! 510: if (ar5k_rfgain(hal, AR5K_INI_PHY_5111, freq) == AH_FALSE)
! 511: return (AH_FALSE);
! 512:
! 513: AR5K_DELAY(1000);
! 514:
! 515: /*
! 516: * Configure additional registers
! 517: */
! 518:
! 519: if (hal->ah_radio == AR5K_AR5111) {
! 520: if (channel->c_channel_flags & IEEE80211_CHAN_B)
! 521: AR5K_REG_ENABLE_BITS(AR5K_AR5211_TXCFG,
! 522: AR5K_AR5211_TXCFG_B_MODE);
! 523: else
! 524: AR5K_REG_DISABLE_BITS(AR5K_AR5211_TXCFG,
! 525: AR5K_AR5211_TXCFG_B_MODE);
! 526: }
! 527:
! 528: /* Set antenna mode */
! 529: AR5K_REG_MASKED_BITS(AR5K_AR5211_PHY(0x44),
! 530: hal->ah_antenna[ee_mode][0], 0xfffffc06);
! 531:
! 532: if (freq == AR5K_INI_RFGAIN_2GHZ)
! 533: ant[0] = ant[1] = HAL_ANT_FIXED_B;
! 534: else
! 535: ant[0] = ant[1] = HAL_ANT_FIXED_A;
! 536:
! 537: AR5K_REG_WRITE(AR5K_AR5211_PHY_ANT_SWITCH_TABLE_0,
! 538: hal->ah_antenna[ee_mode][ant[0]]);
! 539: AR5K_REG_WRITE(AR5K_AR5211_PHY_ANT_SWITCH_TABLE_1,
! 540: hal->ah_antenna[ee_mode][ant[1]]);
! 541:
! 542: /* Commit values from EEPROM */
! 543: AR5K_REG_WRITE_BITS(AR5K_AR5211_PHY_FC,
! 544: AR5K_AR5211_PHY_FC_TX_CLIP, ee->ee_tx_clip);
! 545:
! 546: AR5K_REG_WRITE(AR5K_AR5211_PHY(0x5a),
! 547: AR5K_AR5211_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]));
! 548:
! 549: AR5K_REG_MASKED_BITS(AR5K_AR5211_PHY(0x11),
! 550: (ee->ee_switch_settling[ee_mode] << 7) & 0x3f80, 0xffffc07f);
! 551: AR5K_REG_MASKED_BITS(AR5K_AR5211_PHY(0x12),
! 552: (ee->ee_ant_tx_rx[ee_mode] << 12) & 0x3f000, 0xfffc0fff);
! 553: AR5K_REG_MASKED_BITS(AR5K_AR5211_PHY(0x14),
! 554: (ee->ee_adc_desired_size[ee_mode] & 0x00ff) |
! 555: ((ee->ee_pga_desired_size[ee_mode] << 8) & 0xff00), 0xffff0000);
! 556:
! 557: AR5K_REG_WRITE(AR5K_AR5211_PHY(0x0d),
! 558: (ee->ee_tx_end2xpa_disable[ee_mode] << 24) |
! 559: (ee->ee_tx_end2xpa_disable[ee_mode] << 16) |
! 560: (ee->ee_tx_frm2xpa_enable[ee_mode] << 8) |
! 561: (ee->ee_tx_frm2xpa_enable[ee_mode]));
! 562:
! 563: AR5K_REG_MASKED_BITS(AR5K_AR5211_PHY(0x0a),
! 564: ee->ee_tx_end2xlna_enable[ee_mode] << 8, 0xffff00ff);
! 565: AR5K_REG_MASKED_BITS(AR5K_AR5211_PHY(0x19),
! 566: (ee->ee_thr_62[ee_mode] << 12) & 0x7f000, 0xfff80fff);
! 567: AR5K_REG_MASKED_BITS(AR5K_AR5211_PHY(0x49), 4, 0xffffff01);
! 568:
! 569: AR5K_REG_ENABLE_BITS(AR5K_AR5211_PHY_IQ,
! 570: AR5K_AR5211_PHY_IQ_CORR_ENABLE |
! 571: (ee->ee_i_cal[ee_mode] << AR5K_AR5211_PHY_IQ_CORR_Q_I_COFF_S) |
! 572: ee->ee_q_cal[ee_mode]);
! 573:
! 574: /*
! 575: * Restore saved values
! 576: */
! 577: AR5K_REG_WRITE(AR5K_AR5211_DCU_SEQNUM(0), s_seq);
! 578: AR5K_REG_WRITE(AR5K_AR5211_DEFAULT_ANTENNA, s_ant);
! 579: AR5K_REG_ENABLE_BITS(AR5K_AR5211_PCICFG, s_led[0]);
! 580: AR5K_REG_WRITE(AR5K_AR5211_GPIOCR, s_led[1]);
! 581: AR5K_REG_WRITE(AR5K_AR5211_GPIODO, s_led[2]);
! 582:
! 583: /*
! 584: * Misc
! 585: */
! 586: bcopy(etherbroadcastaddr, mac, IEEE80211_ADDR_LEN);
! 587: ar5k_ar5211_set_associd(hal, mac, 0, 0);
! 588: ar5k_ar5211_set_opmode(hal);
! 589: AR5K_REG_WRITE(AR5K_AR5211_PISR, 0xffffffff);
! 590: AR5K_REG_WRITE(AR5K_AR5211_RSSI_THR, AR5K_TUNE_RSSI_THRES);
! 591:
! 592: /*
! 593: * Set Rx/Tx DMA Configuration
! 594: */
! 595: AR5K_REG_WRITE_BITS(AR5K_AR5211_TXCFG, AR5K_AR5211_TXCFG_SDMAMR,
! 596: AR5K_AR5211_DMASIZE_512B | AR5K_AR5211_TXCFG_DMASIZE);
! 597: AR5K_REG_WRITE_BITS(AR5K_AR5211_RXCFG, AR5K_AR5211_RXCFG_SDMAMW,
! 598: AR5K_AR5211_DMASIZE_512B);
! 599:
! 600: /*
! 601: * Set channel and calibrate the PHY
! 602: */
! 603: if (ar5k_channel(hal, channel) == AH_FALSE)
! 604: return (AH_FALSE);
! 605:
! 606: /*
! 607: * Enable the PHY and wait until completion
! 608: */
! 609: AR5K_REG_WRITE(AR5K_AR5211_PHY_ACTIVE, AR5K_AR5211_PHY_ENABLE);
! 610:
! 611: data = AR5K_REG_READ(AR5K_AR5211_PHY_RX_DELAY) &
! 612: AR5K_AR5211_PHY_RX_DELAY_M;
! 613: data = (channel->c_channel_flags & IEEE80211_CHAN_CCK) ?
! 614: ((data << 2) / 22) : (data / 10);
! 615:
! 616: AR5K_DELAY(100 + data);
! 617:
! 618: /*
! 619: * Start calibration
! 620: */
! 621: AR5K_REG_ENABLE_BITS(AR5K_AR5211_PHY_AGCCTL,
! 622: AR5K_AR5211_PHY_AGCCTL_NF |
! 623: AR5K_AR5211_PHY_AGCCTL_CAL);
! 624:
! 625: if (channel->c_channel_flags & IEEE80211_CHAN_B) {
! 626: hal->ah_calibration = AH_FALSE;
! 627: } else {
! 628: hal->ah_calibration = AH_TRUE;
! 629: AR5K_REG_WRITE_BITS(AR5K_AR5211_PHY_IQ,
! 630: AR5K_AR5211_PHY_IQ_CAL_NUM_LOG_MAX, 15);
! 631: AR5K_REG_ENABLE_BITS(AR5K_AR5211_PHY_IQ,
! 632: AR5K_AR5211_PHY_IQ_RUN);
! 633: }
! 634:
! 635: /*
! 636: * Reset queues and start beacon timers at the end of the reset routine
! 637: */
! 638: for (i = 0; i < hal->ah_capabilities.cap_queues.q_tx_num; i++) {
! 639: AR5K_REG_WRITE_Q(AR5K_AR5211_DCU_QCUMASK(i), i);
! 640: if (ar5k_ar5211_reset_tx_queue(hal, i) == AH_FALSE) {
! 641: AR5K_PRINTF("failed to reset TX queue #%d\n", i);
! 642: return (AH_FALSE);
! 643: }
! 644: }
! 645:
! 646: /* Pre-enable interrupts */
! 647: ar5k_ar5211_set_intr(hal, HAL_INT_RX | HAL_INT_TX | HAL_INT_FATAL);
! 648:
! 649: /*
! 650: * Set RF kill flags if supported by the device (read from the EEPROM)
! 651: */
! 652: if (AR5K_EEPROM_HDR_RFKILL(hal->ah_capabilities.cap_eeprom.ee_header)) {
! 653: ar5k_ar5211_set_gpio_input(hal, 0);
! 654: if ((hal->ah_gpio[0] = ar5k_ar5211_get_gpio(hal, 0)) == 0)
! 655: ar5k_ar5211_set_gpio_intr(hal, 0, 1);
! 656: else
! 657: ar5k_ar5211_set_gpio_intr(hal, 0, 0);
! 658: }
! 659:
! 660: /*
! 661: * Disable beacons and reset the register
! 662: */
! 663: AR5K_REG_DISABLE_BITS(AR5K_AR5211_BEACON,
! 664: AR5K_AR5211_BEACON_ENABLE | AR5K_AR5211_BEACON_RESET_TSF);
! 665:
! 666: return (AH_TRUE);
! 667: }
! 668:
! 669: void
! 670: ar5k_ar5211_set_def_antenna(struct ath_hal *hal, u_int ant)
! 671: {
! 672: AR5K_REG_WRITE(AR5K_AR5211_DEFAULT_ANTENNA, ant);
! 673: }
! 674:
! 675: u_int
! 676: ar5k_ar5211_get_def_antenna(struct ath_hal *hal)
! 677: {
! 678: return AR5K_REG_READ(AR5K_AR5211_DEFAULT_ANTENNA);
! 679: }
! 680:
! 681: void
! 682: ar5k_ar5211_set_opmode(struct ath_hal *hal)
! 683: {
! 684: u_int32_t pcu_reg, low_id, high_id;
! 685:
! 686: pcu_reg = 0;
! 687:
! 688: switch (hal->ah_op_mode) {
! 689: case IEEE80211_M_IBSS:
! 690: pcu_reg |= AR5K_AR5211_STA_ID1_ADHOC |
! 691: AR5K_AR5211_STA_ID1_DESC_ANTENNA;
! 692: break;
! 693:
! 694: case IEEE80211_M_HOSTAP:
! 695: pcu_reg |= AR5K_AR5211_STA_ID1_AP |
! 696: AR5K_AR5211_STA_ID1_RTS_DEFAULT_ANTENNA;
! 697: break;
! 698:
! 699: case IEEE80211_M_STA:
! 700: case IEEE80211_M_MONITOR:
! 701: pcu_reg |= AR5K_AR5211_STA_ID1_DEFAULT_ANTENNA;
! 702: break;
! 703:
! 704: default:
! 705: return;
! 706: }
! 707:
! 708: /*
! 709: * Set PCU registers
! 710: */
! 711: low_id = AR5K_LOW_ID(hal->ah_sta_id);
! 712: high_id = AR5K_HIGH_ID(hal->ah_sta_id);
! 713: AR5K_REG_WRITE(AR5K_AR5211_STA_ID0, low_id);
! 714: AR5K_REG_WRITE(AR5K_AR5211_STA_ID1, pcu_reg | high_id);
! 715:
! 716: return;
! 717: }
! 718:
! 719: HAL_BOOL
! 720: ar5k_ar5211_calibrate(struct ath_hal *hal, HAL_CHANNEL *channel)
! 721: {
! 722: u_int32_t i_pwr, q_pwr;
! 723: int32_t iq_corr, i_coff, i_coffd, q_coff, q_coffd;
! 724:
! 725: if (hal->ah_calibration == AH_FALSE ||
! 726: AR5K_REG_READ(AR5K_AR5211_PHY_IQ) & AR5K_AR5211_PHY_IQ_RUN)
! 727: goto done;
! 728:
! 729: hal->ah_calibration = AH_FALSE;
! 730:
! 731: iq_corr = AR5K_REG_READ(AR5K_AR5211_PHY_IQRES_CAL_CORR);
! 732: i_pwr = AR5K_REG_READ(AR5K_AR5211_PHY_IQRES_CAL_PWR_I);
! 733: q_pwr = AR5K_REG_READ(AR5K_AR5211_PHY_IQRES_CAL_PWR_Q);
! 734: i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7;
! 735: q_coffd = q_pwr >> 6;
! 736:
! 737: if (i_coffd == 0 || q_coffd == 0)
! 738: goto done;
! 739:
! 740: i_coff = ((-iq_corr) / i_coffd) & 0x3f;
! 741: q_coff = (((int32_t)i_pwr / q_coffd) - 64) & 0x1f;
! 742:
! 743: /* Commit new IQ value */
! 744: AR5K_REG_ENABLE_BITS(AR5K_AR5211_PHY_IQ,
! 745: AR5K_AR5211_PHY_IQ_CORR_ENABLE |
! 746: ((u_int32_t)q_coff) |
! 747: ((u_int32_t)i_coff << AR5K_AR5211_PHY_IQ_CORR_Q_I_COFF_S));
! 748:
! 749: done:
! 750: /* Start noise floor calibration */
! 751: AR5K_REG_ENABLE_BITS(AR5K_AR5211_PHY_AGCCTL,
! 752: AR5K_AR5211_PHY_AGCCTL_NF);
! 753:
! 754: return (AH_TRUE);
! 755: }
! 756:
! 757: /*
! 758: * Transmit functions
! 759: */
! 760:
! 761: HAL_BOOL
! 762: ar5k_ar5211_update_tx_triglevel(struct ath_hal *hal, HAL_BOOL increase)
! 763: {
! 764: u_int32_t trigger_level, imr;
! 765: HAL_BOOL status = AH_FALSE;
! 766:
! 767: /*
! 768: * Disable interrupts by setting the mask
! 769: */
! 770: imr = ar5k_ar5211_set_intr(hal, hal->ah_imr & ~HAL_INT_GLOBAL);
! 771:
! 772: trigger_level = AR5K_REG_MS(AR5K_REG_READ(AR5K_AR5211_TXCFG),
! 773: AR5K_AR5211_TXCFG_TXFULL);
! 774:
! 775: if (increase == AH_FALSE) {
! 776: if (--trigger_level < AR5K_TUNE_MIN_TX_FIFO_THRES)
! 777: goto done;
! 778: } else
! 779: trigger_level +=
! 780: ((AR5K_TUNE_MAX_TX_FIFO_THRES - trigger_level) / 2);
! 781:
! 782: /*
! 783: * Update trigger level on success
! 784: */
! 785: AR5K_REG_WRITE_BITS(AR5K_AR5211_TXCFG,
! 786: AR5K_AR5211_TXCFG_TXFULL, trigger_level);
! 787: status = AH_TRUE;
! 788:
! 789: done:
! 790: /*
! 791: * Restore interrupt mask
! 792: */
! 793: ar5k_ar5211_set_intr(hal, imr);
! 794:
! 795: return (status);
! 796: }
! 797:
! 798: int
! 799: ar5k_ar5211_setup_tx_queue(struct ath_hal *hal, HAL_TX_QUEUE queue_type,
! 800: const HAL_TXQ_INFO *queue_info)
! 801: {
! 802: u_int queue;
! 803:
! 804: /*
! 805: * Get queue by type
! 806: */
! 807: if (queue_type == HAL_TX_QUEUE_DATA) {
! 808: for (queue = HAL_TX_QUEUE_ID_DATA_MIN;
! 809: hal->ah_txq[queue].tqi_type != HAL_TX_QUEUE_INACTIVE;
! 810: queue++)
! 811: if (queue > HAL_TX_QUEUE_ID_DATA_MAX)
! 812: return (-1);
! 813: } else if (queue_type == HAL_TX_QUEUE_PSPOLL) {
! 814: queue = HAL_TX_QUEUE_ID_PSPOLL;
! 815: } else if (queue_type == HAL_TX_QUEUE_BEACON) {
! 816: queue = HAL_TX_QUEUE_ID_BEACON;
! 817: } else if (queue_type == HAL_TX_QUEUE_CAB) {
! 818: queue = HAL_TX_QUEUE_ID_CAB;
! 819: } else
! 820: return (-1);
! 821:
! 822: /*
! 823: * Setup internal queue structure
! 824: */
! 825: bzero(&hal->ah_txq[queue], sizeof(HAL_TXQ_INFO));
! 826: hal->ah_txq[queue].tqi_type = queue_type;
! 827:
! 828: if (queue_info != NULL) {
! 829: if (ar5k_ar5211_setup_tx_queueprops(hal, queue, queue_info)
! 830: != AH_TRUE)
! 831: return (-1);
! 832: }
! 833:
! 834: AR5K_Q_ENABLE_BITS(hal->ah_txq_interrupts, queue);
! 835:
! 836: return (queue);
! 837: }
! 838:
! 839: HAL_BOOL
! 840: ar5k_ar5211_setup_tx_queueprops(struct ath_hal *hal, int queue,
! 841: const HAL_TXQ_INFO *queue_info)
! 842: {
! 843: AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
! 844:
! 845: if (hal->ah_txq[queue].tqi_type == HAL_TX_QUEUE_INACTIVE)
! 846: return (AH_FALSE);
! 847:
! 848: bcopy(queue_info, &hal->ah_txq[queue], sizeof(HAL_TXQ_INFO));
! 849:
! 850: if (queue_info->tqi_type == HAL_TX_QUEUE_DATA &&
! 851: (queue_info->tqi_subtype >= HAL_WME_AC_VI) &&
! 852: (queue_info->tqi_subtype <= HAL_WME_UPSD))
! 853: hal->ah_txq[queue].tqi_flags |=
! 854: AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS;
! 855:
! 856: return (AH_TRUE);
! 857: }
! 858:
! 859: HAL_BOOL
! 860: ar5k_ar5211_get_tx_queueprops(struct ath_hal *hal, int queue,
! 861: HAL_TXQ_INFO *queue_info)
! 862: {
! 863: AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
! 864: bcopy(&hal->ah_txq[queue], queue_info, sizeof(HAL_TXQ_INFO));
! 865: return (AH_TRUE);
! 866: }
! 867:
! 868: HAL_BOOL
! 869: ar5k_ar5211_release_tx_queue(struct ath_hal *hal, u_int queue)
! 870: {
! 871: AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
! 872:
! 873: /* This queue will be skipped in further operations */
! 874: hal->ah_txq[queue].tqi_type = HAL_TX_QUEUE_INACTIVE;
! 875: AR5K_Q_DISABLE_BITS(hal->ah_txq_interrupts, queue);
! 876:
! 877: return (AH_FALSE);
! 878: }
! 879:
! 880: HAL_BOOL
! 881: ar5k_ar5211_reset_tx_queue(struct ath_hal *hal, u_int queue)
! 882: {
! 883: u_int32_t cw_min, cw_max, retry_lg, retry_sh;
! 884: struct ieee80211_channel *channel = (struct ieee80211_channel*)
! 885: &hal->ah_current_channel;
! 886: HAL_TXQ_INFO *tq;
! 887:
! 888: AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
! 889:
! 890: tq = &hal->ah_txq[queue];
! 891:
! 892: if (tq->tqi_type == HAL_TX_QUEUE_INACTIVE)
! 893: return (AH_TRUE);
! 894:
! 895: /*
! 896: * Set registers by channel mode
! 897: */
! 898: if (IEEE80211_IS_CHAN_B(channel)) {
! 899: hal->ah_cw_min = AR5K_TUNE_CWMIN_11B;
! 900: cw_max = hal->ah_cw_max = AR5K_TUNE_CWMAX_11B;
! 901: hal->ah_aifs = AR5K_TUNE_AIFS_11B;
! 902: } else {
! 903: hal->ah_cw_min = AR5K_TUNE_CWMIN;
! 904: cw_max = hal->ah_cw_max = AR5K_TUNE_CWMAX;
! 905: hal->ah_aifs = AR5K_TUNE_AIFS;
! 906: }
! 907:
! 908: /*
! 909: * Set retry limits
! 910: */
! 911: if (hal->ah_software_retry == AH_TRUE) {
! 912: /* XXX Need to test this */
! 913: retry_lg = hal->ah_limit_tx_retries;
! 914: retry_sh = retry_lg =
! 915: retry_lg > AR5K_AR5211_DCU_RETRY_LMT_SH_RETRY ?
! 916: AR5K_AR5211_DCU_RETRY_LMT_SH_RETRY : retry_lg;
! 917: } else {
! 918: retry_lg = AR5K_INIT_LG_RETRY;
! 919: retry_sh = AR5K_INIT_SH_RETRY;
! 920: }
! 921:
! 922: AR5K_REG_WRITE(AR5K_AR5211_DCU_RETRY_LMT(queue),
! 923: AR5K_REG_SM(AR5K_INIT_SLG_RETRY,
! 924: AR5K_AR5211_DCU_RETRY_LMT_SLG_RETRY) |
! 925: AR5K_REG_SM(AR5K_INIT_SSH_RETRY,
! 926: AR5K_AR5211_DCU_RETRY_LMT_SSH_RETRY) |
! 927: AR5K_REG_SM(retry_lg, AR5K_AR5211_DCU_RETRY_LMT_LG_RETRY) |
! 928: AR5K_REG_SM(retry_sh, AR5K_AR5211_DCU_RETRY_LMT_SH_RETRY));
! 929:
! 930: /*
! 931: * Set initial content window (cw_min/cw_max)
! 932: */
! 933: cw_min = 1;
! 934: while (cw_min < hal->ah_cw_min)
! 935: cw_min = (cw_min << 1) | 1;
! 936:
! 937: cw_min = tq->tqi_cw_min < 0 ?
! 938: (cw_min >> (-tq->tqi_cw_min)) :
! 939: ((cw_min << tq->tqi_cw_min) + (1 << tq->tqi_cw_min) - 1);
! 940: cw_max = tq->tqi_cw_max < 0 ?
! 941: (cw_max >> (-tq->tqi_cw_max)) :
! 942: ((cw_max << tq->tqi_cw_max) + (1 << tq->tqi_cw_max) - 1);
! 943:
! 944: AR5K_REG_WRITE(AR5K_AR5211_DCU_LCL_IFS(queue),
! 945: AR5K_REG_SM(cw_min, AR5K_AR5211_DCU_LCL_IFS_CW_MIN) |
! 946: AR5K_REG_SM(cw_max, AR5K_AR5211_DCU_LCL_IFS_CW_MAX) |
! 947: AR5K_REG_SM(hal->ah_aifs + tq->tqi_aifs,
! 948: AR5K_AR5211_DCU_LCL_IFS_AIFS));
! 949:
! 950: /*
! 951: * Set misc registers
! 952: */
! 953: AR5K_REG_WRITE(AR5K_AR5211_QCU_MISC(queue),
! 954: AR5K_AR5211_QCU_MISC_DCU_EARLY);
! 955:
! 956: if (tq->tqi_cbr_period) {
! 957: AR5K_REG_WRITE(AR5K_AR5211_QCU_CBRCFG(queue),
! 958: AR5K_REG_SM(tq->tqi_cbr_period,
! 959: AR5K_AR5211_QCU_CBRCFG_INTVAL) |
! 960: AR5K_REG_SM(tq->tqi_cbr_overflow_limit,
! 961: AR5K_AR5211_QCU_CBRCFG_ORN_THRES));
! 962: AR5K_REG_ENABLE_BITS(AR5K_AR5211_QCU_MISC(queue),
! 963: AR5K_AR5211_QCU_MISC_FRSHED_CBR);
! 964: if (tq->tqi_cbr_overflow_limit)
! 965: AR5K_REG_ENABLE_BITS(AR5K_AR5211_QCU_MISC(queue),
! 966: AR5K_AR5211_QCU_MISC_CBR_THRES_ENABLE);
! 967: }
! 968:
! 969: if (tq->tqi_ready_time) {
! 970: AR5K_REG_WRITE(AR5K_AR5211_QCU_RDYTIMECFG(queue),
! 971: AR5K_REG_SM(tq->tqi_ready_time,
! 972: AR5K_AR5211_QCU_RDYTIMECFG_INTVAL) |
! 973: AR5K_AR5211_QCU_RDYTIMECFG_ENABLE);
! 974: }
! 975:
! 976: if (tq->tqi_burst_time) {
! 977: AR5K_REG_WRITE(AR5K_AR5211_DCU_CHAN_TIME(queue),
! 978: AR5K_REG_SM(tq->tqi_burst_time,
! 979: AR5K_AR5211_DCU_CHAN_TIME_DUR) |
! 980: AR5K_AR5211_DCU_CHAN_TIME_ENABLE);
! 981:
! 982: if (tq->tqi_flags & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE) {
! 983: AR5K_REG_ENABLE_BITS(AR5K_AR5211_QCU_MISC(queue),
! 984: AR5K_AR5211_QCU_MISC_TXE);
! 985: }
! 986: }
! 987:
! 988: if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE) {
! 989: AR5K_REG_WRITE(AR5K_AR5211_DCU_MISC(queue),
! 990: AR5K_AR5211_DCU_MISC_POST_FR_BKOFF_DIS);
! 991: }
! 992:
! 993: if (tq->tqi_flags & AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) {
! 994: AR5K_REG_WRITE(AR5K_AR5211_DCU_MISC(queue),
! 995: AR5K_AR5211_DCU_MISC_BACKOFF_FRAG);
! 996: }
! 997:
! 998: /*
! 999: * Set registers by queue type
! 1000: */
! 1001: switch (tq->tqi_type) {
! 1002: case HAL_TX_QUEUE_BEACON:
! 1003: AR5K_REG_ENABLE_BITS(AR5K_AR5211_QCU_MISC(queue),
! 1004: AR5K_AR5211_QCU_MISC_FRSHED_DBA_GT |
! 1005: AR5K_AR5211_QCU_MISC_CBREXP_BCN |
! 1006: AR5K_AR5211_QCU_MISC_BCN_ENABLE);
! 1007:
! 1008: AR5K_REG_ENABLE_BITS(AR5K_AR5211_DCU_MISC(queue),
! 1009: (AR5K_AR5211_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
! 1010: AR5K_AR5211_DCU_MISC_ARBLOCK_CTL_GLOBAL) |
! 1011: AR5K_AR5211_DCU_MISC_POST_FR_BKOFF_DIS |
! 1012: AR5K_AR5211_DCU_MISC_BCN_ENABLE);
! 1013:
! 1014: AR5K_REG_WRITE(AR5K_AR5211_QCU_RDYTIMECFG(queue),
! 1015: ((AR5K_TUNE_BEACON_INTERVAL -
! 1016: (AR5K_TUNE_SW_BEACON_RESP - AR5K_TUNE_DMA_BEACON_RESP) -
! 1017: AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) |
! 1018: AR5K_AR5211_QCU_RDYTIMECFG_ENABLE);
! 1019: break;
! 1020:
! 1021: case HAL_TX_QUEUE_CAB:
! 1022: AR5K_REG_ENABLE_BITS(AR5K_AR5211_QCU_MISC(queue),
! 1023: AR5K_AR5211_QCU_MISC_FRSHED_DBA_GT |
! 1024: AR5K_AR5211_QCU_MISC_CBREXP |
! 1025: AR5K_AR5211_QCU_MISC_CBREXP_BCN);
! 1026:
! 1027: AR5K_REG_ENABLE_BITS(AR5K_AR5211_DCU_MISC(queue),
! 1028: (AR5K_AR5211_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
! 1029: AR5K_AR5211_DCU_MISC_ARBLOCK_CTL_GLOBAL));
! 1030: break;
! 1031:
! 1032: case HAL_TX_QUEUE_PSPOLL:
! 1033: AR5K_REG_ENABLE_BITS(AR5K_AR5211_QCU_MISC(queue),
! 1034: AR5K_AR5211_QCU_MISC_CBREXP);
! 1035: break;
! 1036:
! 1037: case HAL_TX_QUEUE_DATA:
! 1038: default:
! 1039: break;
! 1040: }
! 1041:
! 1042: /*
! 1043: * Enable tx queue in the secondary interrupt mask registers
! 1044: */
! 1045: AR5K_REG_WRITE(AR5K_AR5211_SIMR0,
! 1046: AR5K_REG_SM(hal->ah_txq_interrupts, AR5K_AR5211_SIMR0_QCU_TXOK) |
! 1047: AR5K_REG_SM(hal->ah_txq_interrupts, AR5K_AR5211_SIMR0_QCU_TXDESC));
! 1048: AR5K_REG_WRITE(AR5K_AR5211_SIMR1,
! 1049: AR5K_REG_SM(hal->ah_txq_interrupts, AR5K_AR5211_SIMR1_QCU_TXERR));
! 1050: AR5K_REG_WRITE(AR5K_AR5211_SIMR2,
! 1051: AR5K_REG_SM(hal->ah_txq_interrupts, AR5K_AR5211_SIMR2_QCU_TXURN));
! 1052:
! 1053: return (AH_TRUE);
! 1054: }
! 1055:
! 1056: u_int32_t
! 1057: ar5k_ar5211_get_tx_buf(struct ath_hal *hal, u_int queue)
! 1058: {
! 1059: AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
! 1060:
! 1061: /*
! 1062: * Get the transmit queue descriptor pointer from the selected queue
! 1063: */
! 1064: return (AR5K_REG_READ(AR5K_AR5211_QCU_TXDP(queue)));
! 1065: }
! 1066:
! 1067: HAL_BOOL
! 1068: ar5k_ar5211_put_tx_buf(struct ath_hal *hal, u_int queue, u_int32_t phys_addr)
! 1069: {
! 1070: AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
! 1071:
! 1072: /*
! 1073: * Set the transmit queue descriptor pointer for the selected queue
! 1074: * (this won't work if the queue is still active)
! 1075: */
! 1076: if (AR5K_REG_READ_Q(AR5K_AR5211_QCU_TXE, queue))
! 1077: return (AH_FALSE);
! 1078:
! 1079: AR5K_REG_WRITE(AR5K_AR5211_QCU_TXDP(queue), phys_addr);
! 1080:
! 1081: return (AH_TRUE);
! 1082: }
! 1083:
! 1084: u_int32_t
! 1085: ar5k_ar5211_num_tx_pending(struct ath_hal *hal, u_int queue)
! 1086: {
! 1087: AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
! 1088: return (AR5K_AR5211_QCU_STS(queue) & AR5K_AR5211_QCU_STS_FRMPENDCNT);
! 1089: }
! 1090:
! 1091: HAL_BOOL
! 1092: ar5k_ar5211_tx_start(struct ath_hal *hal, u_int queue)
! 1093: {
! 1094: AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
! 1095:
! 1096: /* Return if queue is disabled */
! 1097: if (AR5K_REG_READ_Q(AR5K_AR5211_QCU_TXD, queue))
! 1098: return (AH_FALSE);
! 1099:
! 1100: /* Start queue */
! 1101: AR5K_REG_WRITE_Q(AR5K_AR5211_QCU_TXE, queue);
! 1102:
! 1103: return (AH_TRUE);
! 1104: }
! 1105:
! 1106: HAL_BOOL
! 1107: ar5k_ar5211_stop_tx_dma(struct ath_hal *hal, u_int queue)
! 1108: {
! 1109: int i = 100, pending;
! 1110:
! 1111: AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
! 1112:
! 1113: /*
! 1114: * Schedule TX disable and wait until queue is empty
! 1115: */
! 1116: AR5K_REG_WRITE_Q(AR5K_AR5211_QCU_TXD, queue);
! 1117:
! 1118: do {
! 1119: pending = AR5K_REG_READ(AR5K_AR5211_QCU_STS(queue)) &
! 1120: AR5K_AR5211_QCU_STS_FRMPENDCNT;
! 1121: delay(100);
! 1122: } while (--i && pending);
! 1123:
! 1124: /* Clear register */
! 1125: AR5K_REG_WRITE(AR5K_AR5211_QCU_TXD, 0);
! 1126:
! 1127: return (AH_TRUE);
! 1128: }
! 1129:
! 1130: HAL_BOOL
! 1131: ar5k_ar5211_setup_tx_desc(struct ath_hal *hal, struct ath_desc *desc,
! 1132: u_int packet_length, u_int header_length, HAL_PKT_TYPE type, u_int tx_power,
! 1133: u_int tx_rate0, u_int tx_tries0, u_int key_index, u_int antenna_mode,
! 1134: u_int flags, u_int rtscts_rate, u_int rtscts_duration)
! 1135: {
! 1136: struct ar5k_ar5211_tx_desc *tx_desc;
! 1137:
! 1138: tx_desc = (struct ar5k_ar5211_tx_desc*)&desc->ds_ctl0;
! 1139:
! 1140: /*
! 1141: * Validate input
! 1142: */
! 1143: if (tx_tries0 == 0)
! 1144: return (AH_FALSE);
! 1145:
! 1146: if ((tx_desc->tx_control_0 = (packet_length &
! 1147: AR5K_AR5211_DESC_TX_CTL0_FRAME_LEN)) != packet_length)
! 1148: return (AH_FALSE);
! 1149:
! 1150: tx_desc->tx_control_0 |=
! 1151: AR5K_REG_SM(tx_rate0, AR5K_AR5211_DESC_TX_CTL0_XMIT_RATE) |
! 1152: AR5K_REG_SM(antenna_mode, AR5K_AR5211_DESC_TX_CTL0_ANT_MODE_XMIT);
! 1153: tx_desc->tx_control_1 =
! 1154: AR5K_REG_SM(type, AR5K_AR5211_DESC_TX_CTL1_FRAME_TYPE);
! 1155:
! 1156: #define _TX_FLAGS(_c, _flag) \
! 1157: if (flags & HAL_TXDESC_##_flag) \
! 1158: tx_desc->tx_control_##_c |= \
! 1159: AR5K_AR5211_DESC_TX_CTL##_c##_##_flag
! 1160:
! 1161: _TX_FLAGS(0, CLRDMASK);
! 1162: _TX_FLAGS(0, VEOL);
! 1163: _TX_FLAGS(0, INTREQ);
! 1164: _TX_FLAGS(0, RTSENA);
! 1165: _TX_FLAGS(1, NOACK);
! 1166:
! 1167: #undef _TX_FLAGS
! 1168:
! 1169: /*
! 1170: * WEP crap
! 1171: */
! 1172: if (key_index != HAL_TXKEYIX_INVALID) {
! 1173: tx_desc->tx_control_0 |=
! 1174: AR5K_AR5211_DESC_TX_CTL0_ENCRYPT_KEY_VALID;
! 1175: tx_desc->tx_control_1 |=
! 1176: AR5K_REG_SM(key_index,
! 1177: AR5K_AR5211_DESC_TX_CTL1_ENCRYPT_KEY_INDEX);
! 1178: }
! 1179:
! 1180: return (AH_TRUE);
! 1181: }
! 1182:
! 1183: HAL_BOOL
! 1184: ar5k_ar5211_fill_tx_desc(struct ath_hal *hal, struct ath_desc *desc,
! 1185: u_int segment_length, HAL_BOOL first_segment, HAL_BOOL last_segment)
! 1186: {
! 1187: struct ar5k_ar5211_tx_desc *tx_desc;
! 1188:
! 1189: tx_desc = (struct ar5k_ar5211_tx_desc*)&desc->ds_ctl0;
! 1190:
! 1191: /* Clear status descriptor */
! 1192: bzero(desc->ds_hw, sizeof(desc->ds_hw));
! 1193:
! 1194: /* Validate segment length and initialize the descriptor */
! 1195: if ((tx_desc->tx_control_1 = (segment_length &
! 1196: AR5K_AR5211_DESC_TX_CTL1_BUF_LEN)) != segment_length)
! 1197: return (AH_FALSE);
! 1198:
! 1199: if (first_segment != AH_TRUE)
! 1200: tx_desc->tx_control_0 &= ~AR5K_AR5211_DESC_TX_CTL0_FRAME_LEN;
! 1201:
! 1202: if (last_segment != AH_TRUE)
! 1203: tx_desc->tx_control_1 |= AR5K_AR5211_DESC_TX_CTL1_MORE;
! 1204:
! 1205: return (AH_TRUE);
! 1206: }
! 1207:
! 1208: HAL_BOOL
! 1209: ar5k_ar5211_setup_xtx_desc(struct ath_hal *hal, struct ath_desc *desc,
! 1210: u_int tx_rate1, u_int tx_tries1, u_int tx_rate2, u_int tx_tries2,
! 1211: u_int tx_rate3, u_int tx_tries3)
! 1212: {
! 1213: return (AH_FALSE);
! 1214: }
! 1215:
! 1216: HAL_STATUS
! 1217: ar5k_ar5211_proc_tx_desc(struct ath_hal *hal, struct ath_desc *desc)
! 1218: {
! 1219: struct ar5k_ar5211_tx_status *tx_status;
! 1220: struct ar5k_ar5211_tx_desc *tx_desc;
! 1221:
! 1222: tx_desc = (struct ar5k_ar5211_tx_desc*)&desc->ds_ctl0;
! 1223: tx_status = (struct ar5k_ar5211_tx_status*)&desc->ds_hw[0];
! 1224:
! 1225: /* No frame has been send or error */
! 1226: if ((tx_status->tx_status_1 & AR5K_AR5211_DESC_TX_STATUS1_DONE) == 0)
! 1227: return (HAL_EINPROGRESS);
! 1228:
! 1229: /*
! 1230: * Get descriptor status
! 1231: */
! 1232: desc->ds_us.tx.ts_tstamp =
! 1233: AR5K_REG_MS(tx_status->tx_status_0,
! 1234: AR5K_AR5211_DESC_TX_STATUS0_SEND_TIMESTAMP);
! 1235: desc->ds_us.tx.ts_shortretry =
! 1236: AR5K_REG_MS(tx_status->tx_status_0,
! 1237: AR5K_AR5211_DESC_TX_STATUS0_RTS_FAIL_COUNT);
! 1238: desc->ds_us.tx.ts_longretry =
! 1239: AR5K_REG_MS(tx_status->tx_status_0,
! 1240: AR5K_AR5211_DESC_TX_STATUS0_DATA_FAIL_COUNT);
! 1241: desc->ds_us.tx.ts_seqnum =
! 1242: AR5K_REG_MS(tx_status->tx_status_1,
! 1243: AR5K_AR5211_DESC_TX_STATUS1_SEQ_NUM);
! 1244: desc->ds_us.tx.ts_rssi =
! 1245: AR5K_REG_MS(tx_status->tx_status_1,
! 1246: AR5K_AR5211_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
! 1247: desc->ds_us.tx.ts_antenna = 1;
! 1248: desc->ds_us.tx.ts_status = 0;
! 1249: desc->ds_us.tx.ts_rate =
! 1250: AR5K_REG_MS(tx_desc->tx_control_0,
! 1251: AR5K_AR5211_DESC_TX_CTL0_XMIT_RATE);
! 1252:
! 1253: if ((tx_status->tx_status_0 &
! 1254: AR5K_AR5211_DESC_TX_STATUS0_FRAME_XMIT_OK) == 0) {
! 1255: if (tx_status->tx_status_0 &
! 1256: AR5K_AR5211_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
! 1257: desc->ds_us.tx.ts_status |= HAL_TXERR_XRETRY;
! 1258:
! 1259: if (tx_status->tx_status_0 &
! 1260: AR5K_AR5211_DESC_TX_STATUS0_FIFO_UNDERRUN)
! 1261: desc->ds_us.tx.ts_status |= HAL_TXERR_FIFO;
! 1262:
! 1263: if (tx_status->tx_status_0 &
! 1264: AR5K_AR5211_DESC_TX_STATUS0_FILTERED)
! 1265: desc->ds_us.tx.ts_status |= HAL_TXERR_FILT;
! 1266: }
! 1267:
! 1268: return (HAL_OK);
! 1269: }
! 1270:
! 1271: HAL_BOOL
! 1272: ar5k_ar5211_has_veol(struct ath_hal *hal)
! 1273: {
! 1274: return (AH_TRUE);
! 1275: }
! 1276:
! 1277: /*
! 1278: * Receive functions
! 1279: */
! 1280:
! 1281: u_int32_t
! 1282: ar5k_ar5211_get_rx_buf(struct ath_hal *hal)
! 1283: {
! 1284: return (AR5K_REG_READ(AR5K_AR5211_RXDP));
! 1285: }
! 1286:
! 1287: void
! 1288: ar5k_ar5211_put_rx_buf(struct ath_hal *hal, u_int32_t phys_addr)
! 1289: {
! 1290: AR5K_REG_WRITE(AR5K_AR5211_RXDP, phys_addr);
! 1291: }
! 1292:
! 1293: void
! 1294: ar5k_ar5211_start_rx(struct ath_hal *hal)
! 1295: {
! 1296: AR5K_REG_WRITE(AR5K_AR5211_CR, AR5K_AR5211_CR_RXE);
! 1297: }
! 1298:
! 1299: HAL_BOOL
! 1300: ar5k_ar5211_stop_rx_dma(struct ath_hal *hal)
! 1301: {
! 1302: int i;
! 1303:
! 1304: AR5K_REG_WRITE(AR5K_AR5211_CR, AR5K_AR5211_CR_RXD);
! 1305:
! 1306: /*
! 1307: * It may take some time to disable the DMA receive unit
! 1308: */
! 1309: for (i = 2000;
! 1310: i > 0 && (AR5K_REG_READ(AR5K_AR5211_CR) & AR5K_AR5211_CR_RXE) != 0;
! 1311: i--)
! 1312: AR5K_DELAY(10);
! 1313:
! 1314: return (i > 0 ? AH_TRUE : AH_FALSE);
! 1315: }
! 1316:
! 1317: void
! 1318: ar5k_ar5211_start_rx_pcu(struct ath_hal *hal)
! 1319: {
! 1320: AR5K_REG_DISABLE_BITS(AR5K_AR5211_DIAG_SW, AR5K_AR5211_DIAG_SW_DIS_RX);
! 1321: }
! 1322:
! 1323: void
! 1324: ar5k_ar5211_stop_pcu_recv(struct ath_hal *hal)
! 1325: {
! 1326: AR5K_REG_ENABLE_BITS(AR5K_AR5211_DIAG_SW, AR5K_AR5211_DIAG_SW_DIS_RX);
! 1327: }
! 1328:
! 1329: void
! 1330: ar5k_ar5211_set_mcast_filter(struct ath_hal *hal, u_int32_t filter0,
! 1331: u_int32_t filter1)
! 1332: {
! 1333: /* Set the multicat filter */
! 1334: AR5K_REG_WRITE(AR5K_AR5211_MCAST_FIL0, filter0);
! 1335: AR5K_REG_WRITE(AR5K_AR5211_MCAST_FIL1, filter1);
! 1336: }
! 1337:
! 1338: HAL_BOOL
! 1339: ar5k_ar5211_set_mcast_filterindex(struct ath_hal *hal, u_int32_t index)
! 1340: {
! 1341: if (index >= 64) {
! 1342: return (AH_FALSE);
! 1343: } else if (index >= 32) {
! 1344: AR5K_REG_ENABLE_BITS(AR5K_AR5211_MCAST_FIL1,
! 1345: (1 << (index - 32)));
! 1346: } else {
! 1347: AR5K_REG_ENABLE_BITS(AR5K_AR5211_MCAST_FIL0,
! 1348: (1 << index));
! 1349: }
! 1350:
! 1351: return (AH_TRUE);
! 1352: }
! 1353:
! 1354: HAL_BOOL
! 1355: ar5k_ar5211_clear_mcast_filter_idx(struct ath_hal *hal, u_int32_t index)
! 1356: {
! 1357:
! 1358: if (index >= 64) {
! 1359: return (AH_FALSE);
! 1360: } else if (index >= 32) {
! 1361: AR5K_REG_DISABLE_BITS(AR5K_AR5211_MCAST_FIL1,
! 1362: (1 << (index - 32)));
! 1363: } else {
! 1364: AR5K_REG_DISABLE_BITS(AR5K_AR5211_MCAST_FIL0,
! 1365: (1 << index));
! 1366: }
! 1367:
! 1368: return (AH_TRUE);
! 1369: }
! 1370:
! 1371: u_int32_t
! 1372: ar5k_ar5211_get_rx_filter(struct ath_hal *hal)
! 1373: {
! 1374: return (AR5K_REG_READ(AR5K_AR5211_RX_FILTER));
! 1375: }
! 1376:
! 1377: void
! 1378: ar5k_ar5211_set_rx_filter(struct ath_hal *hal, u_int32_t filter)
! 1379: {
! 1380: AR5K_REG_WRITE(AR5K_AR5211_RX_FILTER, filter);
! 1381: }
! 1382:
! 1383: HAL_BOOL
! 1384: ar5k_ar5211_setup_rx_desc(struct ath_hal *hal, struct ath_desc *desc,
! 1385: u_int32_t size, u_int flags)
! 1386: {
! 1387: struct ar5k_ar5211_rx_desc *rx_desc;
! 1388:
! 1389: rx_desc = (struct ar5k_ar5211_rx_desc*)&desc->ds_ctl0;
! 1390:
! 1391: if ((rx_desc->rx_control_1 = (size &
! 1392: AR5K_AR5211_DESC_RX_CTL1_BUF_LEN)) != size)
! 1393: return (AH_FALSE);
! 1394:
! 1395: if (flags & HAL_RXDESC_INTREQ)
! 1396: rx_desc->rx_control_1 |= AR5K_AR5211_DESC_RX_CTL1_INTREQ;
! 1397:
! 1398: return (AH_TRUE);
! 1399: }
! 1400:
! 1401: HAL_STATUS
! 1402: ar5k_ar5211_proc_rx_desc(struct ath_hal *hal, struct ath_desc *desc,
! 1403: u_int32_t phys_addr, struct ath_desc *next)
! 1404: {
! 1405: struct ar5k_ar5211_rx_status *rx_status;
! 1406:
! 1407: rx_status = (struct ar5k_ar5211_rx_status*)&desc->ds_hw[0];
! 1408:
! 1409: /* No frame received / not ready */
! 1410: if ((rx_status->rx_status_1 & AR5K_AR5211_DESC_RX_STATUS1_DONE) == 0)
! 1411: return (HAL_EINPROGRESS);
! 1412:
! 1413: /*
! 1414: * Frame receive status
! 1415: */
! 1416: desc->ds_us.rx.rs_datalen = rx_status->rx_status_0 &
! 1417: AR5K_AR5211_DESC_RX_STATUS0_DATA_LEN;
! 1418: desc->ds_us.rx.rs_rssi =
! 1419: AR5K_REG_MS(rx_status->rx_status_0,
! 1420: AR5K_AR5211_DESC_RX_STATUS0_RECEIVE_SIGNAL);
! 1421: desc->ds_us.rx.rs_rate =
! 1422: AR5K_REG_MS(rx_status->rx_status_0,
! 1423: AR5K_AR5211_DESC_RX_STATUS0_RECEIVE_RATE);
! 1424: desc->ds_us.rx.rs_antenna = rx_status->rx_status_0 &
! 1425: AR5K_AR5211_DESC_RX_STATUS0_RECEIVE_ANTENNA;
! 1426: desc->ds_us.rx.rs_more = rx_status->rx_status_0 &
! 1427: AR5K_AR5211_DESC_RX_STATUS0_MORE;
! 1428: desc->ds_us.rx.rs_tstamp =
! 1429: AR5K_REG_MS(rx_status->rx_status_1,
! 1430: AR5K_AR5211_DESC_RX_STATUS1_RECEIVE_TIMESTAMP);
! 1431: desc->ds_us.rx.rs_status = 0;
! 1432:
! 1433: /*
! 1434: * Key table status
! 1435: */
! 1436: if (rx_status->rx_status_1 &
! 1437: AR5K_AR5211_DESC_RX_STATUS1_KEY_INDEX_VALID) {
! 1438: desc->ds_us.rx.rs_keyix =
! 1439: AR5K_REG_MS(rx_status->rx_status_1,
! 1440: AR5K_AR5211_DESC_RX_STATUS1_KEY_INDEX);
! 1441: } else {
! 1442: desc->ds_us.rx.rs_keyix = HAL_RXKEYIX_INVALID;
! 1443: }
! 1444:
! 1445: /*
! 1446: * Receive/descriptor errors
! 1447: */
! 1448: if ((rx_status->rx_status_1 &
! 1449: AR5K_AR5211_DESC_RX_STATUS1_FRAME_RECEIVE_OK) == 0) {
! 1450: if (rx_status->rx_status_1 &
! 1451: AR5K_AR5211_DESC_RX_STATUS1_CRC_ERROR)
! 1452: desc->ds_us.rx.rs_status |= HAL_RXERR_CRC;
! 1453:
! 1454: if (rx_status->rx_status_1 &
! 1455: AR5K_AR5211_DESC_RX_STATUS1_PHY_ERROR) {
! 1456: desc->ds_us.rx.rs_status |= HAL_RXERR_PHY;
! 1457: desc->ds_us.rx.rs_phyerr =
! 1458: AR5K_REG_MS(rx_status->rx_status_1,
! 1459: AR5K_AR5211_DESC_RX_STATUS1_PHY_ERROR);
! 1460: }
! 1461:
! 1462: if (rx_status->rx_status_1 &
! 1463: AR5K_AR5211_DESC_RX_STATUS1_DECRYPT_CRC_ERROR)
! 1464: desc->ds_us.rx.rs_status |= HAL_RXERR_DECRYPT;
! 1465: }
! 1466:
! 1467: return (HAL_OK);
! 1468: }
! 1469:
! 1470: void
! 1471: ar5k_ar5211_set_rx_signal(struct ath_hal *hal)
! 1472: {
! 1473: /* Signal state monitoring is not yet supported */
! 1474: }
! 1475:
! 1476: /*
! 1477: * Misc functions
! 1478: */
! 1479:
! 1480: void
! 1481: ar5k_ar5211_dump_state(struct ath_hal *hal)
! 1482: {
! 1483: #ifdef AR5K_DEBUG
! 1484: #define AR5K_PRINT_REGISTER(_x) \
! 1485: printf("(%s: %08x) ", #_x, AR5K_REG_READ(AR5K_AR5211_##_x));
! 1486:
! 1487: printf("MAC registers:\n");
! 1488: AR5K_PRINT_REGISTER(CR);
! 1489: AR5K_PRINT_REGISTER(CFG);
! 1490: AR5K_PRINT_REGISTER(IER);
! 1491: AR5K_PRINT_REGISTER(RTSD0);
! 1492: AR5K_PRINT_REGISTER(TXCFG);
! 1493: AR5K_PRINT_REGISTER(RXCFG);
! 1494: AR5K_PRINT_REGISTER(RXJLA);
! 1495: AR5K_PRINT_REGISTER(MIBC);
! 1496: AR5K_PRINT_REGISTER(TOPS);
! 1497: AR5K_PRINT_REGISTER(RXNOFRM);
! 1498: AR5K_PRINT_REGISTER(RPGTO);
! 1499: AR5K_PRINT_REGISTER(RFCNT);
! 1500: AR5K_PRINT_REGISTER(MISC);
! 1501: AR5K_PRINT_REGISTER(PISR);
! 1502: AR5K_PRINT_REGISTER(SISR0);
! 1503: AR5K_PRINT_REGISTER(SISR1);
! 1504: AR5K_PRINT_REGISTER(SISR3);
! 1505: AR5K_PRINT_REGISTER(SISR4);
! 1506: AR5K_PRINT_REGISTER(QCU_TXE);
! 1507: AR5K_PRINT_REGISTER(QCU_TXD);
! 1508: AR5K_PRINT_REGISTER(DCU_GBL_IFS_SIFS);
! 1509: AR5K_PRINT_REGISTER(DCU_GBL_IFS_SLOT);
! 1510: AR5K_PRINT_REGISTER(DCU_FP);
! 1511: AR5K_PRINT_REGISTER(DCU_TXP);
! 1512: AR5K_PRINT_REGISTER(DCU_TX_FILTER);
! 1513: AR5K_PRINT_REGISTER(RC);
! 1514: AR5K_PRINT_REGISTER(SCR);
! 1515: AR5K_PRINT_REGISTER(INTPEND);
! 1516: AR5K_PRINT_REGISTER(PCICFG);
! 1517: AR5K_PRINT_REGISTER(GPIOCR);
! 1518: AR5K_PRINT_REGISTER(GPIODO);
! 1519: AR5K_PRINT_REGISTER(SREV);
! 1520: AR5K_PRINT_REGISTER(EEPROM_BASE);
! 1521: AR5K_PRINT_REGISTER(EEPROM_DATA);
! 1522: AR5K_PRINT_REGISTER(EEPROM_CMD);
! 1523: AR5K_PRINT_REGISTER(EEPROM_CFG);
! 1524: AR5K_PRINT_REGISTER(PCU_MIN);
! 1525: AR5K_PRINT_REGISTER(STA_ID0);
! 1526: AR5K_PRINT_REGISTER(STA_ID1);
! 1527: AR5K_PRINT_REGISTER(BSS_ID0);
! 1528: AR5K_PRINT_REGISTER(SLOT_TIME);
! 1529: AR5K_PRINT_REGISTER(TIME_OUT);
! 1530: AR5K_PRINT_REGISTER(RSSI_THR);
! 1531: AR5K_PRINT_REGISTER(BEACON);
! 1532: AR5K_PRINT_REGISTER(CFP_PERIOD);
! 1533: AR5K_PRINT_REGISTER(TIMER0);
! 1534: AR5K_PRINT_REGISTER(TIMER2);
! 1535: AR5K_PRINT_REGISTER(TIMER3);
! 1536: AR5K_PRINT_REGISTER(CFP_DUR);
! 1537: AR5K_PRINT_REGISTER(MCAST_FIL0);
! 1538: AR5K_PRINT_REGISTER(MCAST_FIL1);
! 1539: AR5K_PRINT_REGISTER(DIAG_SW);
! 1540: AR5K_PRINT_REGISTER(TSF_U32);
! 1541: AR5K_PRINT_REGISTER(ADDAC_TEST);
! 1542: AR5K_PRINT_REGISTER(DEFAULT_ANTENNA);
! 1543: AR5K_PRINT_REGISTER(LAST_TSTP);
! 1544: AR5K_PRINT_REGISTER(NAV);
! 1545: AR5K_PRINT_REGISTER(RTS_OK);
! 1546: AR5K_PRINT_REGISTER(ACK_FAIL);
! 1547: AR5K_PRINT_REGISTER(FCS_FAIL);
! 1548: AR5K_PRINT_REGISTER(BEACON_CNT);
! 1549: AR5K_PRINT_REGISTER(KEYTABLE_0);
! 1550: printf("\n");
! 1551:
! 1552: printf("PHY registers:\n");
! 1553: AR5K_PRINT_REGISTER(PHY_TURBO);
! 1554: AR5K_PRINT_REGISTER(PHY_AGC);
! 1555: AR5K_PRINT_REGISTER(PHY_CHIP_ID);
! 1556: AR5K_PRINT_REGISTER(PHY_AGCCTL);
! 1557: AR5K_PRINT_REGISTER(PHY_NF);
! 1558: AR5K_PRINT_REGISTER(PHY_RX_DELAY);
! 1559: AR5K_PRINT_REGISTER(PHY_IQ);
! 1560: AR5K_PRINT_REGISTER(PHY_PAPD_PROBE);
! 1561: AR5K_PRINT_REGISTER(PHY_FC);
! 1562: AR5K_PRINT_REGISTER(PHY_RADAR);
! 1563: AR5K_PRINT_REGISTER(PHY_ANT_SWITCH_TABLE_0);
! 1564: AR5K_PRINT_REGISTER(PHY_ANT_SWITCH_TABLE_1);
! 1565: printf("\n");
! 1566: #endif
! 1567: }
! 1568:
! 1569: HAL_BOOL
! 1570: ar5k_ar5211_get_diag_state(struct ath_hal *hal, int id, void **device,
! 1571: u_int *size)
! 1572: {
! 1573: /*
! 1574: * We'll ignore this right now. This seems to be some kind of an obscure
! 1575: * debugging interface for the binary-only HAL.
! 1576: */
! 1577: return (AH_FALSE);
! 1578: }
! 1579:
! 1580: void
! 1581: ar5k_ar5211_get_lladdr(struct ath_hal *hal, u_int8_t *mac)
! 1582: {
! 1583: bcopy(hal->ah_sta_id, mac, IEEE80211_ADDR_LEN);
! 1584: }
! 1585:
! 1586: HAL_BOOL
! 1587: ar5k_ar5211_set_lladdr(struct ath_hal *hal, const u_int8_t *mac)
! 1588: {
! 1589: u_int32_t low_id, high_id;
! 1590:
! 1591: /* Set new station ID */
! 1592: bcopy(mac, hal->ah_sta_id, IEEE80211_ADDR_LEN);
! 1593:
! 1594: low_id = AR5K_LOW_ID(mac);
! 1595: high_id = 0x0000ffff & AR5K_HIGH_ID(mac);
! 1596:
! 1597: AR5K_REG_WRITE(AR5K_AR5211_STA_ID0, low_id);
! 1598: AR5K_REG_WRITE(AR5K_AR5211_STA_ID1, high_id);
! 1599:
! 1600: return (AH_TRUE);
! 1601: }
! 1602:
! 1603: HAL_BOOL
! 1604: ar5k_ar5211_set_regdomain(struct ath_hal *hal, u_int16_t regdomain,
! 1605: HAL_STATUS *status)
! 1606: {
! 1607: ieee80211_regdomain_t ieee_regdomain;
! 1608:
! 1609: ieee_regdomain = ar5k_regdomain_to_ieee(regdomain);
! 1610:
! 1611: if (ar5k_eeprom_regulation_domain(hal, AH_TRUE,
! 1612: &ieee_regdomain) == AH_TRUE) {
! 1613: *status = HAL_OK;
! 1614: return (AH_TRUE);
! 1615: }
! 1616:
! 1617: *status = EIO;
! 1618:
! 1619: return (AH_FALSE);
! 1620: }
! 1621:
! 1622: void
! 1623: ar5k_ar5211_set_ledstate(struct ath_hal *hal, HAL_LED_STATE state)
! 1624: {
! 1625: u_int32_t led;
! 1626:
! 1627: AR5K_REG_DISABLE_BITS(AR5K_AR5211_PCICFG,
! 1628: AR5K_AR5211_PCICFG_LEDMODE | AR5K_AR5211_PCICFG_LED);
! 1629:
! 1630: /*
! 1631: * Some blinking values, define at your wish
! 1632: */
! 1633: switch (state) {
! 1634: case IEEE80211_S_SCAN:
! 1635: case IEEE80211_S_AUTH:
! 1636: led = AR5K_AR5211_PCICFG_LEDMODE_PROP |
! 1637: AR5K_AR5211_PCICFG_LED_PEND;
! 1638: break;
! 1639:
! 1640: case IEEE80211_S_INIT:
! 1641: led = AR5K_AR5211_PCICFG_LEDMODE_PROP |
! 1642: AR5K_AR5211_PCICFG_LED_NONE;
! 1643: break;
! 1644:
! 1645: case IEEE80211_S_ASSOC:
! 1646: case IEEE80211_S_RUN:
! 1647: led = AR5K_AR5211_PCICFG_LEDMODE_PROP |
! 1648: AR5K_AR5211_PCICFG_LED_ASSOC;
! 1649: break;
! 1650:
! 1651: default:
! 1652: led = AR5K_AR5211_PCICFG_LEDMODE_PROM |
! 1653: AR5K_AR5211_PCICFG_LED_NONE;
! 1654: break;
! 1655: }
! 1656:
! 1657: AR5K_REG_ENABLE_BITS(AR5K_AR5211_PCICFG, led);
! 1658: }
! 1659:
! 1660: void
! 1661: ar5k_ar5211_set_associd(struct ath_hal *hal, const u_int8_t *bssid,
! 1662: u_int16_t assoc_id, u_int16_t tim_offset)
! 1663: {
! 1664: u_int32_t low_id, high_id;
! 1665:
! 1666: /*
! 1667: * Set BSSID which triggers the "SME Join" operation
! 1668: */
! 1669: low_id = AR5K_LOW_ID(bssid);
! 1670: high_id = AR5K_HIGH_ID(bssid);
! 1671: AR5K_REG_WRITE(AR5K_AR5211_BSS_ID0, low_id);
! 1672: AR5K_REG_WRITE(AR5K_AR5211_BSS_ID1, high_id |
! 1673: ((assoc_id & 0x3fff) << AR5K_AR5211_BSS_ID1_AID_S));
! 1674: bcopy(bssid, hal->ah_bssid, IEEE80211_ADDR_LEN);
! 1675:
! 1676: if (assoc_id == 0) {
! 1677: ar5k_ar5211_disable_pspoll(hal);
! 1678: return;
! 1679: }
! 1680:
! 1681: AR5K_REG_WRITE(AR5K_AR5211_BEACON,
! 1682: (AR5K_REG_READ(AR5K_AR5211_BEACON) &
! 1683: ~AR5K_AR5211_BEACON_TIM) |
! 1684: (((tim_offset ? tim_offset + 4 : 0) <<
! 1685: AR5K_AR5211_BEACON_TIM_S) &
! 1686: AR5K_AR5211_BEACON_TIM));
! 1687:
! 1688: ar5k_ar5211_enable_pspoll(hal, NULL, 0);
! 1689: }
! 1690:
! 1691: HAL_BOOL
! 1692: ar5k_ar5211_set_bssid_mask(struct ath_hal *hal, const u_int8_t* mask)
! 1693: {
! 1694: /* Not supported in 5211 */
! 1695: return (AH_FALSE);
! 1696: }
! 1697:
! 1698: HAL_BOOL
! 1699: ar5k_ar5211_set_gpio_output(struct ath_hal *hal, u_int32_t gpio)
! 1700: {
! 1701: if (gpio > AR5K_AR5211_NUM_GPIO)
! 1702: return (AH_FALSE);
! 1703:
! 1704: AR5K_REG_WRITE(AR5K_AR5211_GPIOCR,
! 1705: (AR5K_REG_READ(AR5K_AR5211_GPIOCR) &~ AR5K_AR5211_GPIOCR_ALL(gpio))
! 1706: | AR5K_AR5211_GPIOCR_ALL(gpio));
! 1707:
! 1708: return (AH_TRUE);
! 1709: }
! 1710:
! 1711: HAL_BOOL
! 1712: ar5k_ar5211_set_gpio_input(struct ath_hal *hal, u_int32_t gpio)
! 1713: {
! 1714: if (gpio > AR5K_AR5211_NUM_GPIO)
! 1715: return (AH_FALSE);
! 1716:
! 1717: AR5K_REG_WRITE(AR5K_AR5211_GPIOCR,
! 1718: (AR5K_REG_READ(AR5K_AR5211_GPIOCR) &~ AR5K_AR5211_GPIOCR_ALL(gpio))
! 1719: | AR5K_AR5211_GPIOCR_NONE(gpio));
! 1720:
! 1721: return (AH_TRUE);
! 1722: }
! 1723:
! 1724: u_int32_t
! 1725: ar5k_ar5211_get_gpio(struct ath_hal *hal, u_int32_t gpio)
! 1726: {
! 1727: if (gpio > AR5K_AR5211_NUM_GPIO)
! 1728: return (0xffffffff);
! 1729:
! 1730: /* GPIO input magic */
! 1731: return (((AR5K_REG_READ(AR5K_AR5211_GPIODI) &
! 1732: AR5K_AR5211_GPIODI_M) >> gpio) & 0x1);
! 1733: }
! 1734:
! 1735: HAL_BOOL
! 1736: ar5k_ar5211_set_gpio(struct ath_hal *hal, u_int32_t gpio, u_int32_t val)
! 1737: {
! 1738: u_int32_t data;
! 1739:
! 1740: if (gpio > AR5K_AR5211_NUM_GPIO)
! 1741: return (0xffffffff);
! 1742:
! 1743: /* GPIO output magic */
! 1744: data = AR5K_REG_READ(AR5K_AR5211_GPIODO);
! 1745:
! 1746: data &= ~(1 << gpio);
! 1747: data |= (val&1) << gpio;
! 1748:
! 1749: AR5K_REG_WRITE(AR5K_AR5211_GPIODO, data);
! 1750:
! 1751: return (AH_TRUE);
! 1752: }
! 1753:
! 1754: void
! 1755: ar5k_ar5211_set_gpio_intr(struct ath_hal *hal, u_int gpio,
! 1756: u_int32_t interrupt_level)
! 1757: {
! 1758: u_int32_t data;
! 1759:
! 1760: if (gpio > AR5K_AR5211_NUM_GPIO)
! 1761: return;
! 1762:
! 1763: /*
! 1764: * Set the GPIO interrupt
! 1765: */
! 1766: data = (AR5K_REG_READ(AR5K_AR5211_GPIOCR) &
! 1767: ~(AR5K_AR5211_GPIOCR_INT_SEL(gpio) | AR5K_AR5211_GPIOCR_INT_SELH |
! 1768: AR5K_AR5211_GPIOCR_INT_ENA | AR5K_AR5211_GPIOCR_ALL(gpio))) |
! 1769: (AR5K_AR5211_GPIOCR_INT_SEL(gpio) | AR5K_AR5211_GPIOCR_INT_ENA);
! 1770:
! 1771: AR5K_REG_WRITE(AR5K_AR5211_GPIOCR,
! 1772: interrupt_level ? data : (data | AR5K_AR5211_GPIOCR_INT_SELH));
! 1773:
! 1774: hal->ah_imr |= AR5K_AR5211_PIMR_GPIO;
! 1775:
! 1776: /* Enable GPIO interrupts */
! 1777: AR5K_REG_ENABLE_BITS(AR5K_AR5211_PIMR, AR5K_AR5211_PIMR_GPIO);
! 1778: }
! 1779:
! 1780: u_int32_t
! 1781: ar5k_ar5211_get_tsf32(struct ath_hal *hal)
! 1782: {
! 1783: return (AR5K_REG_READ(AR5K_AR5211_TSF_L32));
! 1784: }
! 1785:
! 1786: u_int64_t
! 1787: ar5k_ar5211_get_tsf64(struct ath_hal *hal)
! 1788: {
! 1789: u_int64_t tsf = AR5K_REG_READ(AR5K_AR5211_TSF_U32);
! 1790:
! 1791: return (AR5K_REG_READ(AR5K_AR5211_TSF_L32) | (tsf << 32));
! 1792: }
! 1793:
! 1794: void
! 1795: ar5k_ar5211_reset_tsf(struct ath_hal *hal)
! 1796: {
! 1797: AR5K_REG_ENABLE_BITS(AR5K_AR5211_BEACON,
! 1798: AR5K_AR5211_BEACON_RESET_TSF);
! 1799: }
! 1800:
! 1801: u_int16_t
! 1802: ar5k_ar5211_get_regdomain(struct ath_hal *hal)
! 1803: {
! 1804: return (ar5k_get_regdomain(hal));
! 1805: }
! 1806:
! 1807: HAL_BOOL
! 1808: ar5k_ar5211_detect_card_present(struct ath_hal *hal)
! 1809: {
! 1810: u_int16_t magic;
! 1811:
! 1812: /*
! 1813: * Checking the EEPROM's magic value could be an indication
! 1814: * if the card is still present. I didn't find another suitable
! 1815: * way to do this.
! 1816: */
! 1817: if (ar5k_ar5211_eeprom_read(hal, AR5K_EEPROM_MAGIC, &magic) != 0)
! 1818: return (AH_FALSE);
! 1819:
! 1820: return (magic == AR5K_EEPROM_MAGIC_VALUE ? AH_TRUE : AH_FALSE);
! 1821: }
! 1822:
! 1823: void
! 1824: ar5k_ar5211_update_mib_counters(struct ath_hal *hal, HAL_MIB_STATS *statistics)
! 1825: {
! 1826: statistics->ackrcv_bad += AR5K_REG_READ(AR5K_AR5211_ACK_FAIL);
! 1827: statistics->rts_bad += AR5K_REG_READ(AR5K_AR5211_RTS_FAIL);
! 1828: statistics->rts_good += AR5K_REG_READ(AR5K_AR5211_RTS_OK);
! 1829: statistics->fcs_bad += AR5K_REG_READ(AR5K_AR5211_FCS_FAIL);
! 1830: statistics->beacons += AR5K_REG_READ(AR5K_AR5211_BEACON_CNT);
! 1831: }
! 1832:
! 1833: HAL_RFGAIN
! 1834: ar5k_ar5211_get_rf_gain(struct ath_hal *hal)
! 1835: {
! 1836: return (HAL_RFGAIN_INACTIVE);
! 1837: }
! 1838:
! 1839: HAL_BOOL
! 1840: ar5k_ar5211_set_slot_time(struct ath_hal *hal, u_int slot_time)
! 1841: {
! 1842: if (slot_time < HAL_SLOT_TIME_9 || slot_time > HAL_SLOT_TIME_MAX)
! 1843: return (AH_FALSE);
! 1844:
! 1845: AR5K_REG_WRITE(AR5K_AR5211_DCU_GBL_IFS_SLOT, slot_time);
! 1846:
! 1847: return (AH_TRUE);
! 1848: }
! 1849:
! 1850: u_int
! 1851: ar5k_ar5211_get_slot_time(struct ath_hal *hal)
! 1852: {
! 1853: return (AR5K_REG_READ(AR5K_AR5211_DCU_GBL_IFS_SLOT) & 0xffff);
! 1854: }
! 1855:
! 1856: HAL_BOOL
! 1857: ar5k_ar5211_set_ack_timeout(struct ath_hal *hal, u_int timeout)
! 1858: {
! 1859: if (ar5k_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_AR5211_TIME_OUT_ACK),
! 1860: hal->ah_turbo) <= timeout)
! 1861: return (AH_FALSE);
! 1862:
! 1863: AR5K_REG_WRITE_BITS(AR5K_AR5211_TIME_OUT, AR5K_AR5211_TIME_OUT_ACK,
! 1864: ar5k_htoclock(timeout, hal->ah_turbo));
! 1865:
! 1866: return (AH_TRUE);
! 1867: }
! 1868:
! 1869: u_int
! 1870: ar5k_ar5211_get_ack_timeout(struct ath_hal *hal)
! 1871: {
! 1872: return (ar5k_clocktoh(AR5K_REG_MS(AR5K_REG_READ(AR5K_AR5211_TIME_OUT),
! 1873: AR5K_AR5211_TIME_OUT_ACK), hal->ah_turbo));
! 1874: }
! 1875:
! 1876: HAL_BOOL
! 1877: ar5k_ar5211_set_cts_timeout(struct ath_hal *hal, u_int timeout)
! 1878: {
! 1879: if (ar5k_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_AR5211_TIME_OUT_CTS),
! 1880: hal->ah_turbo) <= timeout)
! 1881: return (AH_FALSE);
! 1882:
! 1883: AR5K_REG_WRITE_BITS(AR5K_AR5211_TIME_OUT, AR5K_AR5211_TIME_OUT_CTS,
! 1884: ar5k_htoclock(timeout, hal->ah_turbo));
! 1885:
! 1886: return (AH_TRUE);
! 1887: }
! 1888:
! 1889: u_int
! 1890: ar5k_ar5211_get_cts_timeout(struct ath_hal *hal)
! 1891: {
! 1892: return (ar5k_clocktoh(AR5K_REG_MS(AR5K_REG_READ(AR5K_AR5211_TIME_OUT),
! 1893: AR5K_AR5211_TIME_OUT_CTS), hal->ah_turbo));
! 1894: }
! 1895:
! 1896: /*
! 1897: * Key table (WEP) functions
! 1898: */
! 1899:
! 1900: HAL_BOOL
! 1901: ar5k_ar5211_is_cipher_supported(struct ath_hal *hal, HAL_CIPHER cipher)
! 1902: {
! 1903: /*
! 1904: * The AR5211 only supports WEP
! 1905: */
! 1906: if (cipher == HAL_CIPHER_WEP)
! 1907: return (AH_TRUE);
! 1908:
! 1909: return (AH_FALSE);
! 1910: }
! 1911:
! 1912: u_int32_t
! 1913: ar5k_ar5211_get_keycache_size(struct ath_hal *hal)
! 1914: {
! 1915: return (AR5K_AR5211_KEYCACHE_SIZE);
! 1916: }
! 1917:
! 1918: HAL_BOOL
! 1919: ar5k_ar5211_reset_key(struct ath_hal *hal, u_int16_t entry)
! 1920: {
! 1921: int i;
! 1922:
! 1923: AR5K_ASSERT_ENTRY(entry, AR5K_AR5211_KEYTABLE_SIZE);
! 1924:
! 1925: for (i = 0; i < AR5K_AR5211_KEYCACHE_SIZE; i++)
! 1926: AR5K_REG_WRITE(AR5K_AR5211_KEYTABLE_OFF(entry, i), 0);
! 1927:
! 1928: return (AH_FALSE);
! 1929: }
! 1930:
! 1931: HAL_BOOL
! 1932: ar5k_ar5211_is_key_valid(struct ath_hal *hal, u_int16_t entry)
! 1933: {
! 1934: AR5K_ASSERT_ENTRY(entry, AR5K_AR5211_KEYTABLE_SIZE);
! 1935:
! 1936: /*
! 1937: * Check the validation flag at the end of the entry
! 1938: */
! 1939: if (AR5K_REG_READ(AR5K_AR5211_KEYTABLE_MAC1(entry)) &
! 1940: AR5K_AR5211_KEYTABLE_VALID)
! 1941: return (AH_TRUE);
! 1942:
! 1943: return (AH_FALSE);
! 1944: }
! 1945:
! 1946: HAL_BOOL
! 1947: ar5k_ar5211_set_key(struct ath_hal *hal, u_int16_t entry,
! 1948: const HAL_KEYVAL *keyval, const u_int8_t *mac, int xor_notused)
! 1949: {
! 1950: int i;
! 1951: u_int32_t key_v[AR5K_AR5211_KEYCACHE_SIZE - 2];
! 1952:
! 1953: AR5K_ASSERT_ENTRY(entry, AR5K_AR5211_KEYTABLE_SIZE);
! 1954:
! 1955: bzero(&key_v, sizeof(key_v));
! 1956:
! 1957: switch (keyval->wk_len) {
! 1958: case AR5K_KEYVAL_LENGTH_40:
! 1959: bcopy(keyval->wk_key, &key_v[0], 4);
! 1960: bcopy(keyval->wk_key + 4, &key_v[1], 1);
! 1961: key_v[5] = AR5K_AR5211_KEYTABLE_TYPE_40;
! 1962: break;
! 1963:
! 1964: case AR5K_KEYVAL_LENGTH_104:
! 1965: bcopy(keyval->wk_key, &key_v[0], 4);
! 1966: bcopy(keyval->wk_key + 4, &key_v[1], 2);
! 1967: bcopy(keyval->wk_key + 6, &key_v[2], 4);
! 1968: bcopy(keyval->wk_key + 10, &key_v[3], 2);
! 1969: bcopy(keyval->wk_key + 12, &key_v[4], 1);
! 1970: key_v[5] = AR5K_AR5211_KEYTABLE_TYPE_104;
! 1971: break;
! 1972:
! 1973: case AR5K_KEYVAL_LENGTH_128:
! 1974: bcopy(keyval->wk_key, &key_v[0], 4);
! 1975: bcopy(keyval->wk_key + 4, &key_v[1], 2);
! 1976: bcopy(keyval->wk_key + 6, &key_v[2], 4);
! 1977: bcopy(keyval->wk_key + 10, &key_v[3], 2);
! 1978: bcopy(keyval->wk_key + 12, &key_v[4], 4);
! 1979: key_v[5] = AR5K_AR5211_KEYTABLE_TYPE_128;
! 1980: break;
! 1981:
! 1982: default:
! 1983: /* Unsupported key length (not WEP40/104/128) */
! 1984: return (AH_FALSE);
! 1985: }
! 1986:
! 1987: for (i = 0; i < AR5K_ELEMENTS(key_v); i++)
! 1988: AR5K_REG_WRITE(AR5K_AR5211_KEYTABLE_OFF(entry, i), key_v[i]);
! 1989:
! 1990: return (ar5k_ar5211_set_key_lladdr(hal, entry, mac));
! 1991: }
! 1992:
! 1993: HAL_BOOL
! 1994: ar5k_ar5211_set_key_lladdr(struct ath_hal *hal, u_int16_t entry,
! 1995: const u_int8_t *mac)
! 1996: {
! 1997: u_int32_t low_id, high_id;
! 1998: const u_int8_t *mac_v;
! 1999:
! 2000: /*
! 2001: * Invalid entry (key table overflow)
! 2002: */
! 2003: AR5K_ASSERT_ENTRY(entry, AR5K_AR5211_KEYTABLE_SIZE);
! 2004:
! 2005: /* MAC may be NULL if it's a broadcast key */
! 2006: mac_v = mac == NULL ? etherbroadcastaddr : mac;
! 2007:
! 2008: low_id = AR5K_LOW_ID(mac_v);
! 2009: high_id = AR5K_HIGH_ID(mac_v) | AR5K_AR5211_KEYTABLE_VALID;
! 2010:
! 2011: AR5K_REG_WRITE(AR5K_AR5211_KEYTABLE_MAC0(entry), low_id);
! 2012: AR5K_REG_WRITE(AR5K_AR5211_KEYTABLE_MAC1(entry), high_id);
! 2013:
! 2014: return (AH_TRUE);
! 2015: }
! 2016:
! 2017: /*
! 2018: * Power management functions
! 2019: */
! 2020:
! 2021: HAL_BOOL
! 2022: ar5k_ar5211_set_power(struct ath_hal *hal, HAL_POWER_MODE mode,
! 2023: HAL_BOOL set_chip, u_int16_t sleep_duration)
! 2024: {
! 2025: u_int32_t staid;
! 2026: int i;
! 2027:
! 2028: staid = AR5K_REG_READ(AR5K_AR5211_STA_ID1);
! 2029:
! 2030: switch (mode) {
! 2031: case HAL_PM_AUTO:
! 2032: staid &= ~AR5K_AR5211_STA_ID1_DEFAULT_ANTENNA;
! 2033: /* FALLTHROUGH */
! 2034: case HAL_PM_NETWORK_SLEEP:
! 2035: if (set_chip == AH_TRUE) {
! 2036: AR5K_REG_WRITE(AR5K_AR5211_SCR,
! 2037: AR5K_AR5211_SCR_SLE | sleep_duration);
! 2038: }
! 2039: staid |= AR5K_AR5211_STA_ID1_PWR_SV;
! 2040: break;
! 2041:
! 2042: case HAL_PM_FULL_SLEEP:
! 2043: if (set_chip == AH_TRUE) {
! 2044: AR5K_REG_WRITE(AR5K_AR5211_SCR,
! 2045: AR5K_AR5211_SCR_SLE_SLP);
! 2046: }
! 2047: staid |= AR5K_AR5211_STA_ID1_PWR_SV;
! 2048: break;
! 2049:
! 2050: case HAL_PM_AWAKE:
! 2051: if (set_chip == AH_FALSE)
! 2052: goto commit;
! 2053:
! 2054: AR5K_REG_WRITE(AR5K_AR5211_SCR, AR5K_AR5211_SCR_SLE_WAKE);
! 2055:
! 2056: for (i = 5000; i > 0; i--) {
! 2057: /* Check if the AR5211 did wake up */
! 2058: if ((AR5K_REG_READ(AR5K_AR5211_PCICFG) &
! 2059: AR5K_AR5211_PCICFG_SPWR_DN) == 0)
! 2060: break;
! 2061:
! 2062: /* Wait a bit and retry */
! 2063: AR5K_DELAY(200);
! 2064: AR5K_REG_WRITE(AR5K_AR5211_SCR,
! 2065: AR5K_AR5211_SCR_SLE_WAKE);
! 2066: }
! 2067:
! 2068: /* Fail if the AR5211 didn't wake up */
! 2069: if (i <= 0)
! 2070: return (AH_FALSE);
! 2071:
! 2072: staid &= ~AR5K_AR5211_STA_ID1_PWR_SV;
! 2073: break;
! 2074:
! 2075: default:
! 2076: return (AH_FALSE);
! 2077: }
! 2078:
! 2079: commit:
! 2080: hal->ah_power_mode = mode;
! 2081:
! 2082: AR5K_REG_WRITE(AR5K_AR5211_STA_ID1, staid);
! 2083:
! 2084: return (AH_TRUE);
! 2085: }
! 2086:
! 2087: HAL_POWER_MODE
! 2088: ar5k_ar5211_get_power_mode(struct ath_hal *hal)
! 2089: {
! 2090: return (hal->ah_power_mode);
! 2091: }
! 2092:
! 2093: HAL_BOOL
! 2094: ar5k_ar5211_query_pspoll_support(struct ath_hal *hal)
! 2095: {
! 2096: /* nope */
! 2097: return (AH_FALSE);
! 2098: }
! 2099:
! 2100: HAL_BOOL
! 2101: ar5k_ar5211_init_pspoll(struct ath_hal *hal)
! 2102: {
! 2103: /*
! 2104: * Not used on the AR5211
! 2105: */
! 2106: return (AH_FALSE);
! 2107: }
! 2108:
! 2109: HAL_BOOL
! 2110: ar5k_ar5211_enable_pspoll(struct ath_hal *hal, u_int8_t *bssid,
! 2111: u_int16_t assoc_id)
! 2112: {
! 2113: return (AH_FALSE);
! 2114: }
! 2115:
! 2116: HAL_BOOL
! 2117: ar5k_ar5211_disable_pspoll(struct ath_hal *hal)
! 2118: {
! 2119: return (AH_FALSE);
! 2120: }
! 2121:
! 2122: /*
! 2123: * Beacon functions
! 2124: */
! 2125:
! 2126: void
! 2127: ar5k_ar5211_init_beacon(struct ath_hal *hal, u_int32_t next_beacon,
! 2128: u_int32_t interval)
! 2129: {
! 2130: u_int32_t timer1, timer2, timer3;
! 2131:
! 2132: /*
! 2133: * Set the additional timers by mode
! 2134: */
! 2135: switch (hal->ah_op_mode) {
! 2136: case HAL_M_STA:
! 2137: timer1 = 0x0000ffff;
! 2138: timer2 = 0x0007ffff;
! 2139: break;
! 2140:
! 2141: default:
! 2142: timer1 = (next_beacon - AR5K_TUNE_DMA_BEACON_RESP) <<
! 2143: 0x00000003;
! 2144: timer2 = (next_beacon - AR5K_TUNE_SW_BEACON_RESP) <<
! 2145: 0x00000003;
! 2146: }
! 2147:
! 2148: timer3 = next_beacon +
! 2149: (hal->ah_atim_window ? hal->ah_atim_window : 1);
! 2150:
! 2151: /*
! 2152: * Enable all timers and set the beacon register
! 2153: * (next beacon, DMA beacon, software beacon, ATIM window time)
! 2154: */
! 2155: AR5K_REG_WRITE(AR5K_AR5211_TIMER0, next_beacon);
! 2156: AR5K_REG_WRITE(AR5K_AR5211_TIMER1, timer1);
! 2157: AR5K_REG_WRITE(AR5K_AR5211_TIMER2, timer2);
! 2158: AR5K_REG_WRITE(AR5K_AR5211_TIMER3, timer3);
! 2159:
! 2160: AR5K_REG_WRITE(AR5K_AR5211_BEACON, interval &
! 2161: (AR5K_AR5211_BEACON_PERIOD | AR5K_AR5211_BEACON_RESET_TSF |
! 2162: AR5K_AR5211_BEACON_ENABLE));
! 2163: }
! 2164:
! 2165: void
! 2166: ar5k_ar5211_set_beacon_timers(struct ath_hal *hal,
! 2167: const HAL_BEACON_STATE *state, u_int32_t tsf, u_int32_t dtim_count,
! 2168: u_int32_t cfp_count)
! 2169: {
! 2170: u_int32_t cfp_period, next_cfp;
! 2171:
! 2172: /* Return on an invalid beacon state */
! 2173: if (state->bs_interval < 1)
! 2174: return;
! 2175:
! 2176: /*
! 2177: * PCF support?
! 2178: */
! 2179: if (state->bs_cfp_period > 0) {
! 2180: /* Enable CFP mode and set the CFP and timer registers */
! 2181: cfp_period = state->bs_cfp_period * state->bs_dtim_period *
! 2182: state->bs_interval;
! 2183: next_cfp = (cfp_count * state->bs_dtim_period + dtim_count) *
! 2184: state->bs_interval;
! 2185:
! 2186: AR5K_REG_DISABLE_BITS(AR5K_AR5211_STA_ID1,
! 2187: AR5K_AR5211_STA_ID1_DEFAULT_ANTENNA |
! 2188: AR5K_AR5211_STA_ID1_PCF);
! 2189: AR5K_REG_WRITE(AR5K_AR5211_CFP_PERIOD, cfp_period);
! 2190: AR5K_REG_WRITE(AR5K_AR5211_CFP_DUR, state->bs_cfp_max_duration);
! 2191: AR5K_REG_WRITE(AR5K_AR5211_TIMER2,
! 2192: (tsf + (next_cfp == 0 ? cfp_period : next_cfp)) << 3);
! 2193: } else {
! 2194: /* Disable PCF mode */
! 2195: AR5K_REG_DISABLE_BITS(AR5K_AR5211_STA_ID1,
! 2196: AR5K_AR5211_STA_ID1_DEFAULT_ANTENNA |
! 2197: AR5K_AR5211_STA_ID1_PCF);
! 2198: }
! 2199:
! 2200: /*
! 2201: * Enable the beacon timer register
! 2202: */
! 2203: AR5K_REG_WRITE(AR5K_AR5211_TIMER0, state->bs_next_beacon);
! 2204:
! 2205: /*
! 2206: * Start the beacon timers
! 2207: */
! 2208: AR5K_REG_WRITE(AR5K_AR5211_BEACON,
! 2209: (AR5K_REG_READ(AR5K_AR5211_BEACON) &~
! 2210: (AR5K_AR5211_BEACON_PERIOD | AR5K_AR5211_BEACON_TIM)) |
! 2211: AR5K_REG_SM(state->bs_tim_offset ? state->bs_tim_offset + 4 : 0,
! 2212: AR5K_AR5211_BEACON_TIM) | AR5K_REG_SM(state->bs_interval,
! 2213: AR5K_AR5211_BEACON_PERIOD));
! 2214:
! 2215: /*
! 2216: * Write new beacon miss threshold, if it appears to be valid
! 2217: */
! 2218: if ((AR5K_AR5211_RSSI_THR_BMISS >> AR5K_AR5211_RSSI_THR_BMISS_S) <
! 2219: state->bs_bmiss_threshold)
! 2220: return;
! 2221:
! 2222: AR5K_REG_WRITE_BITS(AR5K_AR5211_RSSI_THR_M,
! 2223: AR5K_AR5211_RSSI_THR_BMISS, state->bs_bmiss_threshold);
! 2224: AR5K_REG_WRITE_BITS(AR5K_AR5211_SCR, AR5K_AR5211_SCR_SLDUR,
! 2225: (state->bs_sleepduration - 3) << 3);
! 2226: }
! 2227:
! 2228: void
! 2229: ar5k_ar5211_reset_beacon(struct ath_hal *hal)
! 2230: {
! 2231: /*
! 2232: * Disable beacon timer
! 2233: */
! 2234: AR5K_REG_WRITE(AR5K_AR5211_TIMER0, 0);
! 2235:
! 2236: /*
! 2237: * Disable some beacon register values
! 2238: */
! 2239: AR5K_REG_DISABLE_BITS(AR5K_AR5211_STA_ID1,
! 2240: AR5K_AR5211_STA_ID1_DEFAULT_ANTENNA | AR5K_AR5211_STA_ID1_PCF);
! 2241: AR5K_REG_WRITE(AR5K_AR5211_BEACON, AR5K_AR5211_BEACON_PERIOD);
! 2242: }
! 2243:
! 2244: HAL_BOOL
! 2245: ar5k_ar5211_wait_for_beacon(struct ath_hal *hal, bus_addr_t phys_addr)
! 2246: {
! 2247: HAL_BOOL ret;
! 2248:
! 2249: /*
! 2250: * Wait for beaconn queue to be done
! 2251: */
! 2252: ret = ar5k_register_timeout(hal,
! 2253: AR5K_AR5211_QCU_STS(HAL_TX_QUEUE_ID_BEACON),
! 2254: AR5K_AR5211_QCU_STS_FRMPENDCNT, 0, AH_FALSE);
! 2255:
! 2256: if (AR5K_REG_READ_Q(AR5K_AR5211_QCU_TXE, HAL_TX_QUEUE_ID_BEACON))
! 2257: return (AH_FALSE);
! 2258:
! 2259: return (ret);
! 2260: }
! 2261:
! 2262: /*
! 2263: * Interrupt handling
! 2264: */
! 2265:
! 2266: HAL_BOOL
! 2267: ar5k_ar5211_is_intr_pending(struct ath_hal *hal)
! 2268: {
! 2269: return (AR5K_REG_READ(AR5K_AR5211_INTPEND) == 0 ? AH_FALSE : AH_TRUE);
! 2270: }
! 2271:
! 2272: HAL_BOOL
! 2273: ar5k_ar5211_get_isr(struct ath_hal *hal, u_int32_t *interrupt_mask)
! 2274: {
! 2275: u_int32_t data;
! 2276:
! 2277: /*
! 2278: * Read interrupt status from the Read-And-Clear shadow register
! 2279: */
! 2280: data = AR5K_REG_READ(AR5K_AR5211_RAC_PISR);
! 2281:
! 2282: /*
! 2283: * Get abstract interrupt mask (HAL-compatible)
! 2284: */
! 2285: *interrupt_mask = (data & HAL_INT_COMMON) & hal->ah_imr;
! 2286:
! 2287: if (data == HAL_INT_NOCARD)
! 2288: return (AH_FALSE);
! 2289:
! 2290: if (data & (AR5K_AR5211_PISR_RXOK | AR5K_AR5211_PISR_RXERR))
! 2291: *interrupt_mask |= HAL_INT_RX;
! 2292:
! 2293: if (data & (AR5K_AR5211_PISR_TXOK | AR5K_AR5211_PISR_TXERR))
! 2294: *interrupt_mask |= HAL_INT_TX;
! 2295:
! 2296: if (data & (AR5K_AR5211_PISR_HIUERR))
! 2297: *interrupt_mask |= HAL_INT_FATAL;
! 2298:
! 2299: /*
! 2300: * Special interrupt handling (not caught by the driver)
! 2301: */
! 2302: if (((*interrupt_mask) & AR5K_AR5211_PISR_RXPHY) &&
! 2303: hal->ah_radar.r_enabled == AH_TRUE)
! 2304: ar5k_radar_alert(hal);
! 2305:
! 2306: return (AH_TRUE);
! 2307: }
! 2308:
! 2309: u_int32_t
! 2310: ar5k_ar5211_get_intr(struct ath_hal *hal)
! 2311: {
! 2312: /* Return the interrupt mask stored previously */
! 2313: return (hal->ah_imr);
! 2314: }
! 2315:
! 2316: HAL_INT
! 2317: ar5k_ar5211_set_intr(struct ath_hal *hal, HAL_INT new_mask)
! 2318: {
! 2319: HAL_INT old_mask, int_mask;
! 2320:
! 2321: /*
! 2322: * Disable card interrupts to prevent any race conditions
! 2323: * (they will be re-enabled afterwards).
! 2324: */
! 2325: AR5K_REG_WRITE(AR5K_AR5211_IER, AR5K_AR5211_IER_DISABLE);
! 2326:
! 2327: old_mask = hal->ah_imr;
! 2328:
! 2329: /*
! 2330: * Add additional, chipset-dependent interrupt mask flags
! 2331: * and write them to the IMR (interrupt mask register).
! 2332: */
! 2333: int_mask = new_mask & HAL_INT_COMMON;
! 2334:
! 2335: if (new_mask & HAL_INT_RX)
! 2336: int_mask |=
! 2337: AR5K_AR5211_PIMR_RXOK |
! 2338: AR5K_AR5211_PIMR_RXERR |
! 2339: AR5K_AR5211_PIMR_RXORN |
! 2340: AR5K_AR5211_PIMR_RXDESC;
! 2341:
! 2342: if (new_mask & HAL_INT_TX)
! 2343: int_mask |=
! 2344: AR5K_AR5211_PIMR_TXOK |
! 2345: AR5K_AR5211_PIMR_TXERR |
! 2346: AR5K_AR5211_PIMR_TXDESC |
! 2347: AR5K_AR5211_PIMR_TXURN;
! 2348:
! 2349: if (new_mask & HAL_INT_FATAL) {
! 2350: int_mask |= AR5K_AR5211_PIMR_HIUERR;
! 2351: AR5K_REG_ENABLE_BITS(AR5K_AR5211_SIMR2,
! 2352: AR5K_AR5211_SIMR2_MCABT |
! 2353: AR5K_AR5211_SIMR2_SSERR |
! 2354: AR5K_AR5211_SIMR2_DPERR);
! 2355: }
! 2356:
! 2357: AR5K_REG_WRITE(AR5K_AR5211_PIMR, int_mask);
! 2358:
! 2359: /* Store new interrupt mask */
! 2360: hal->ah_imr = new_mask;
! 2361:
! 2362: /* ..re-enable interrupts */
! 2363: AR5K_REG_WRITE(AR5K_AR5211_IER, AR5K_AR5211_IER_ENABLE);
! 2364:
! 2365: return (old_mask);
! 2366: }
! 2367:
! 2368: /*
! 2369: * Misc internal functions
! 2370: */
! 2371:
! 2372: HAL_BOOL
! 2373: ar5k_ar5211_get_capabilities(struct ath_hal *hal)
! 2374: {
! 2375: u_int16_t ee_header;
! 2376:
! 2377: /* Capabilities stored in the EEPROM */
! 2378: ee_header = hal->ah_capabilities.cap_eeprom.ee_header;
! 2379:
! 2380: /*
! 2381: * XXX The AR5211 tranceiver supports frequencies from 4920 to 6100GHz
! 2382: * XXX and from 2312 to 2732GHz. There are problems with the current
! 2383: * XXX ieee80211 implementation because the IEEE channel mapping
! 2384: * XXX does not support negative channel numbers (2312MHz is channel
! 2385: * XXX -19). Of course, this doesn't matter because these channels
! 2386: * XXX are out of range but some regulation domains like MKK (Japan)
! 2387: * XXX will support frequencies somewhere around 4.8GHz.
! 2388: */
! 2389:
! 2390: /*
! 2391: * Set radio capabilities
! 2392: */
! 2393:
! 2394: if (AR5K_EEPROM_HDR_11A(ee_header)) {
! 2395: hal->ah_capabilities.cap_range.range_5ghz_min = 5005; /* 4920 */
! 2396: hal->ah_capabilities.cap_range.range_5ghz_max = 6100;
! 2397:
! 2398: /* Set supported modes */
! 2399: hal->ah_capabilities.cap_mode = HAL_MODE_11A | HAL_MODE_TURBO;
! 2400: }
! 2401:
! 2402: /* This chip will support 802.11b if the 2GHz radio is connected */
! 2403: if (AR5K_EEPROM_HDR_11B(ee_header) || AR5K_EEPROM_HDR_11G(ee_header)) {
! 2404: hal->ah_capabilities.cap_range.range_2ghz_min = 2412; /* 2312 */
! 2405: hal->ah_capabilities.cap_range.range_2ghz_max = 2732;
! 2406:
! 2407: if (AR5K_EEPROM_HDR_11B(ee_header))
! 2408: hal->ah_capabilities.cap_mode |= HAL_MODE_11B;
! 2409: #if 0
! 2410: if (AR5K_EEPROM_HDR_11G(ee_header))
! 2411: hal->ah_capabilities.cap_mode |= HAL_MODE_11G;
! 2412: #endif
! 2413: }
! 2414:
! 2415: /* GPIO */
! 2416: hal->ah_gpio_npins = AR5K_AR5211_NUM_GPIO;
! 2417:
! 2418: /* Set number of supported TX queues */
! 2419: hal->ah_capabilities.cap_queues.q_tx_num = AR5K_AR5211_TX_NUM_QUEUES;
! 2420:
! 2421: return (AH_TRUE);
! 2422: }
! 2423:
! 2424: void
! 2425: ar5k_ar5211_radar_alert(struct ath_hal *hal, HAL_BOOL enable)
! 2426: {
! 2427: /*
! 2428: * Enable radar detection
! 2429: */
! 2430: AR5K_REG_WRITE(AR5K_AR5211_IER, AR5K_AR5211_IER_DISABLE);
! 2431:
! 2432: if (enable == AH_TRUE) {
! 2433: AR5K_REG_WRITE(AR5K_AR5211_PHY_RADAR,
! 2434: AR5K_AR5211_PHY_RADAR_ENABLE);
! 2435: AR5K_REG_ENABLE_BITS(AR5K_AR5211_PIMR,
! 2436: AR5K_AR5211_PIMR_RXPHY);
! 2437: } else {
! 2438: AR5K_REG_WRITE(AR5K_AR5211_PHY_RADAR,
! 2439: AR5K_AR5211_PHY_RADAR_DISABLE);
! 2440: AR5K_REG_DISABLE_BITS(AR5K_AR5211_PIMR,
! 2441: AR5K_AR5211_PIMR_RXPHY);
! 2442: }
! 2443:
! 2444: AR5K_REG_WRITE(AR5K_AR5211_IER, AR5K_AR5211_IER_ENABLE);
! 2445: }
! 2446:
! 2447: /*
! 2448: * EEPROM access functions
! 2449: */
! 2450:
! 2451: HAL_BOOL
! 2452: ar5k_ar5211_eeprom_is_busy(struct ath_hal *hal)
! 2453: {
! 2454: return (AR5K_REG_READ(AR5K_AR5211_CFG) & AR5K_AR5211_CFG_EEBS ?
! 2455: AH_TRUE : AH_FALSE);
! 2456: }
! 2457:
! 2458: int
! 2459: ar5k_ar5211_eeprom_read(struct ath_hal *hal, u_int32_t offset, u_int16_t *data)
! 2460: {
! 2461: u_int32_t status, i;
! 2462:
! 2463: /*
! 2464: * Initialize EEPROM access
! 2465: */
! 2466: AR5K_REG_WRITE(AR5K_AR5211_EEPROM_BASE, (u_int8_t)offset);
! 2467: AR5K_REG_ENABLE_BITS(AR5K_AR5211_EEPROM_CMD,
! 2468: AR5K_AR5211_EEPROM_CMD_READ);
! 2469:
! 2470: for (i = AR5K_TUNE_REGISTER_TIMEOUT; i > 0; i--) {
! 2471: status = AR5K_REG_READ(AR5K_AR5211_EEPROM_STATUS);
! 2472: if (status & AR5K_AR5211_EEPROM_STAT_RDDONE) {
! 2473: if (status & AR5K_AR5211_EEPROM_STAT_RDERR)
! 2474: return (EIO);
! 2475: *data = (u_int16_t)
! 2476: (AR5K_REG_READ(AR5K_AR5211_EEPROM_DATA) & 0xffff);
! 2477: return (0);
! 2478: }
! 2479: AR5K_DELAY(15);
! 2480: }
! 2481:
! 2482: return (ETIMEDOUT);
! 2483: }
! 2484:
! 2485: int
! 2486: ar5k_ar5211_eeprom_write(struct ath_hal *hal, u_int32_t offset, u_int16_t data)
! 2487: {
! 2488: u_int32_t status, timeout;
! 2489:
! 2490: /* Enable eeprom access */
! 2491: AR5K_REG_ENABLE_BITS(AR5K_AR5211_EEPROM_CMD,
! 2492: AR5K_AR5211_EEPROM_CMD_RESET);
! 2493: AR5K_REG_ENABLE_BITS(AR5K_AR5211_EEPROM_CMD,
! 2494: AR5K_AR5211_EEPROM_CMD_WRITE);
! 2495:
! 2496: /*
! 2497: * Prime write pump
! 2498: */
! 2499: AR5K_REG_WRITE(AR5K_AR5211_EEPROM_BASE, (u_int8_t)offset - 1);
! 2500:
! 2501: for (timeout = 10000; timeout > 0; timeout--) {
! 2502: AR5K_DELAY(1);
! 2503: status = AR5K_REG_READ(AR5K_AR5211_EEPROM_STATUS);
! 2504: if (status & AR5K_AR5211_EEPROM_STAT_WRDONE) {
! 2505: if (status & AR5K_AR5211_EEPROM_STAT_WRERR)
! 2506: return (EIO);
! 2507: return (0);
! 2508: }
! 2509: }
! 2510:
! 2511: return (ETIMEDOUT);
! 2512: }
! 2513:
! 2514: /*
! 2515: * RF register settings
! 2516: */
! 2517:
! 2518: void
! 2519: ar5k_ar5211_rfregs(struct ath_hal *hal, HAL_CHANNEL *channel, u_int freq,
! 2520: u_int ee_mode)
! 2521: {
! 2522: struct ar5k_eeprom_info *ee = &hal->ah_capabilities.cap_eeprom;
! 2523: struct ar5k_ar5211_ini_rf rf[AR5K_ELEMENTS(ar5211_rf)];
! 2524: u_int32_t ob, db, obdb, xpds, xpdp, x_gain;
! 2525: u_int i;
! 2526:
! 2527: bcopy(ar5211_rf, rf, sizeof(rf));
! 2528: obdb = 0;
! 2529:
! 2530: if (freq == AR5K_INI_RFGAIN_2GHZ &&
! 2531: hal->ah_ee_version >= AR5K_EEPROM_VERSION_3_1) {
! 2532: ob = ar5k_bitswap(ee->ee_ob[ee_mode][0], 3);
! 2533: db = ar5k_bitswap(ee->ee_db[ee_mode][0], 3);
! 2534: rf[25].rf_value[freq] =
! 2535: ((ob << 6) & 0xc0) | (rf[25].rf_value[freq] & ~0xc0);
! 2536: rf[26].rf_value[freq] =
! 2537: (((ob >> 2) & 0x1) | ((db << 1) & 0xe)) |
! 2538: (rf[26].rf_value[freq] & ~0xf);
! 2539: }
! 2540:
! 2541: if (freq == AR5K_INI_RFGAIN_5GHZ) {
! 2542: /* For 11a and Turbo */
! 2543: obdb = channel->c_channel >= 5725 ? 3 :
! 2544: (channel->c_channel >= 5500 ? 2 :
! 2545: (channel->c_channel >= 5260 ? 1 :
! 2546: (channel->c_channel > 4000 ? 0 : -1)));
! 2547: }
! 2548:
! 2549: ob = ee->ee_ob[ee_mode][obdb];
! 2550: db = ee->ee_db[ee_mode][obdb];
! 2551: x_gain = ee->ee_x_gain[ee_mode];
! 2552: xpds = ee->ee_xpd[ee_mode];
! 2553: xpdp = !xpds;
! 2554:
! 2555: rf[11].rf_value[freq] = (rf[11].rf_value[freq] & ~0xc0) |
! 2556: (((ar5k_bitswap(x_gain, 4) << 7) | (xpdp << 6)) & 0xc0);
! 2557: rf[12].rf_value[freq] = (rf[12].rf_value[freq] & ~0x7) |
! 2558: ((ar5k_bitswap(x_gain, 4) >> 1) & 0x7);
! 2559: rf[12].rf_value[freq] = (rf[12].rf_value[freq] & ~0x80) |
! 2560: ((ar5k_bitswap(ob, 3) << 7) & 0x80);
! 2561: rf[13].rf_value[freq] = (rf[13].rf_value[freq] & ~0x3) |
! 2562: ((ar5k_bitswap(ob, 3) >> 1) & 0x3);
! 2563: rf[13].rf_value[freq] = (rf[13].rf_value[freq] & ~0x1c) |
! 2564: ((ar5k_bitswap(db, 3) << 2) & 0x1c);
! 2565: rf[17].rf_value[freq] = (rf[17].rf_value[freq] & ~0x8) |
! 2566: ((xpds << 3) & 0x8);
! 2567:
! 2568: for (i = 0; i < AR5K_ELEMENTS(rf); i++) {
! 2569: AR5K_REG_WAIT(i);
! 2570: AR5K_REG_WRITE((u_int32_t)rf[i].rf_register,
! 2571: rf[i].rf_value[freq]);
! 2572: }
! 2573:
! 2574: hal->ah_rf_gain = HAL_RFGAIN_INACTIVE;
! 2575: }
! 2576:
! 2577: HAL_BOOL
! 2578: ar5k_ar5211_set_txpower_limit(struct ath_hal *hal, u_int power)
! 2579: {
! 2580: /* Not implemented */
! 2581: return (AH_FALSE);
! 2582: }
CVSweb