00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <dev/ic/ar5xxx.h>
00025 #include <dev/ic/ar5210reg.h>
00026 #include <dev/ic/ar5210var.h>
00027
00028 HAL_BOOL ar5k_ar5210_nic_reset(struct ath_hal *, u_int32_t);
00029 HAL_BOOL ar5k_ar5210_nic_wakeup(struct ath_hal *, HAL_BOOL, HAL_BOOL);
00030 void ar5k_ar5210_init_tx_queue(struct ath_hal *, u_int, HAL_BOOL);
00031 const void ar5k_ar5210_fill(struct ath_hal *);
00032 HAL_BOOL ar5k_ar5210_do_calibrate(struct ath_hal *, HAL_CHANNEL *);
00033 HAL_BOOL ar5k_ar5210_noise_floor(struct ath_hal *, HAL_CHANNEL *);
00034
00035
00036
00037
00038 static const struct ar5k_ini ar5210_ini[] =
00039 AR5K_AR5210_INI;
00040
00041 AR5K_HAL_FUNCTIONS(extern, ar5k_ar5210,);
00042
00043 const void
00044 ar5k_ar5210_fill(hal)
00045 struct ath_hal *hal;
00046 {
00047 hal->ah_magic = AR5K_AR5210_MAGIC;
00048
00049
00050
00051
00052 AR5K_HAL_FUNCTION(hal, ar5210, get_rate_table);
00053 AR5K_HAL_FUNCTION(hal, ar5210, detach);
00054
00055
00056
00057
00058 AR5K_HAL_FUNCTION(hal, ar5210, reset);
00059 AR5K_HAL_FUNCTION(hal, ar5210, set_opmode);
00060 AR5K_HAL_FUNCTION(hal, ar5210, calibrate);
00061
00062
00063
00064
00065 AR5K_HAL_FUNCTION(hal, ar5210, update_tx_triglevel);
00066 AR5K_HAL_FUNCTION(hal, ar5210, setup_tx_queue);
00067 AR5K_HAL_FUNCTION(hal, ar5210, setup_tx_queueprops);
00068 AR5K_HAL_FUNCTION(hal, ar5210, release_tx_queue);
00069 AR5K_HAL_FUNCTION(hal, ar5210, reset_tx_queue);
00070 AR5K_HAL_FUNCTION(hal, ar5210, get_tx_buf);
00071 AR5K_HAL_FUNCTION(hal, ar5210, put_tx_buf);
00072 AR5K_HAL_FUNCTION(hal, ar5210, tx_start);
00073 AR5K_HAL_FUNCTION(hal, ar5210, stop_tx_dma);
00074 AR5K_HAL_FUNCTION(hal, ar5210, setup_tx_desc);
00075 AR5K_HAL_FUNCTION(hal, ar5210, setup_xtx_desc);
00076 AR5K_HAL_FUNCTION(hal, ar5210, fill_tx_desc);
00077 AR5K_HAL_FUNCTION(hal, ar5210, proc_tx_desc);
00078 AR5K_HAL_FUNCTION(hal, ar5210, has_veol);
00079
00080
00081
00082
00083 AR5K_HAL_FUNCTION(hal, ar5210, get_rx_buf);
00084 AR5K_HAL_FUNCTION(hal, ar5210, put_rx_buf);
00085 AR5K_HAL_FUNCTION(hal, ar5210, start_rx);
00086 AR5K_HAL_FUNCTION(hal, ar5210, stop_rx_dma);
00087 AR5K_HAL_FUNCTION(hal, ar5210, start_rx_pcu);
00088 AR5K_HAL_FUNCTION(hal, ar5210, stop_pcu_recv);
00089 AR5K_HAL_FUNCTION(hal, ar5210, set_mcast_filter);
00090 AR5K_HAL_FUNCTION(hal, ar5210, set_mcast_filterindex);
00091 AR5K_HAL_FUNCTION(hal, ar5210, clear_mcast_filter_idx);
00092 AR5K_HAL_FUNCTION(hal, ar5210, get_rx_filter);
00093 AR5K_HAL_FUNCTION(hal, ar5210, set_rx_filter);
00094 AR5K_HAL_FUNCTION(hal, ar5210, setup_rx_desc);
00095 AR5K_HAL_FUNCTION(hal, ar5210, proc_rx_desc);
00096 AR5K_HAL_FUNCTION(hal, ar5210, set_rx_signal);
00097
00098
00099
00100
00101 AR5K_HAL_FUNCTION(hal, ar5210, dump_state);
00102 AR5K_HAL_FUNCTION(hal, ar5210, get_diag_state);
00103 AR5K_HAL_FUNCTION(hal, ar5210, get_lladdr);
00104 AR5K_HAL_FUNCTION(hal, ar5210, set_lladdr);
00105 AR5K_HAL_FUNCTION(hal, ar5210, set_regdomain);
00106 AR5K_HAL_FUNCTION(hal, ar5210, set_ledstate);
00107 AR5K_HAL_FUNCTION(hal, ar5210, set_associd);
00108 AR5K_HAL_FUNCTION(hal, ar5210, set_gpio_input);
00109 AR5K_HAL_FUNCTION(hal, ar5210, set_gpio_output);
00110 AR5K_HAL_FUNCTION(hal, ar5210, get_gpio);
00111 AR5K_HAL_FUNCTION(hal, ar5210, set_gpio);
00112 AR5K_HAL_FUNCTION(hal, ar5210, set_gpio_intr);
00113 AR5K_HAL_FUNCTION(hal, ar5210, get_tsf32);
00114 AR5K_HAL_FUNCTION(hal, ar5210, get_tsf64);
00115 AR5K_HAL_FUNCTION(hal, ar5210, reset_tsf);
00116 AR5K_HAL_FUNCTION(hal, ar5210, get_regdomain);
00117 AR5K_HAL_FUNCTION(hal, ar5210, detect_card_present);
00118 AR5K_HAL_FUNCTION(hal, ar5210, update_mib_counters);
00119 AR5K_HAL_FUNCTION(hal, ar5210, get_rf_gain);
00120 AR5K_HAL_FUNCTION(hal, ar5210, set_slot_time);
00121 AR5K_HAL_FUNCTION(hal, ar5210, get_slot_time);
00122 AR5K_HAL_FUNCTION(hal, ar5210, set_ack_timeout);
00123 AR5K_HAL_FUNCTION(hal, ar5210, get_ack_timeout);
00124 AR5K_HAL_FUNCTION(hal, ar5210, set_cts_timeout);
00125 AR5K_HAL_FUNCTION(hal, ar5210, get_cts_timeout);
00126
00127
00128
00129
00130 AR5K_HAL_FUNCTION(hal, ar5210, is_cipher_supported);
00131 AR5K_HAL_FUNCTION(hal, ar5210, get_keycache_size);
00132 AR5K_HAL_FUNCTION(hal, ar5210, reset_key);
00133 AR5K_HAL_FUNCTION(hal, ar5210, is_key_valid);
00134 AR5K_HAL_FUNCTION(hal, ar5210, set_key);
00135 AR5K_HAL_FUNCTION(hal, ar5210, set_key_lladdr);
00136
00137
00138
00139
00140 AR5K_HAL_FUNCTION(hal, ar5210, set_power);
00141 AR5K_HAL_FUNCTION(hal, ar5210, get_power_mode);
00142 AR5K_HAL_FUNCTION(hal, ar5210, query_pspoll_support);
00143 AR5K_HAL_FUNCTION(hal, ar5210, init_pspoll);
00144 AR5K_HAL_FUNCTION(hal, ar5210, enable_pspoll);
00145 AR5K_HAL_FUNCTION(hal, ar5210, disable_pspoll);
00146
00147
00148
00149
00150 AR5K_HAL_FUNCTION(hal, ar5210, init_beacon);
00151 AR5K_HAL_FUNCTION(hal, ar5210, set_beacon_timers);
00152 AR5K_HAL_FUNCTION(hal, ar5210, reset_beacon);
00153 AR5K_HAL_FUNCTION(hal, ar5210, wait_for_beacon);
00154
00155
00156
00157
00158 AR5K_HAL_FUNCTION(hal, ar5210, is_intr_pending);
00159 AR5K_HAL_FUNCTION(hal, ar5210, get_isr);
00160 AR5K_HAL_FUNCTION(hal, ar5210, get_intr);
00161 AR5K_HAL_FUNCTION(hal, ar5210, set_intr);
00162
00163
00164
00165
00166 AR5K_HAL_FUNCTION(hal, ar5210, get_capabilities);
00167 AR5K_HAL_FUNCTION(hal, ar5210, radar_alert);
00168
00169
00170
00171
00172 AR5K_HAL_FUNCTION(hal, ar5210, eeprom_is_busy);
00173 AR5K_HAL_FUNCTION(hal, ar5210, eeprom_read);
00174 AR5K_HAL_FUNCTION(hal, ar5210, eeprom_write);
00175 }
00176
00177 struct ath_hal *
00178 ar5k_ar5210_attach(device, sc, st, sh, status)
00179 u_int16_t device;
00180 void *sc;
00181 bus_space_tag_t st;
00182 bus_space_handle_t sh;
00183 int *status;
00184 {
00185 int i;
00186 struct ath_hal *hal = (struct ath_hal*) sc;
00187 u_int8_t mac[IEEE80211_ADDR_LEN];
00188 u_int32_t srev;
00189
00190 ar5k_ar5210_fill(hal);
00191
00192
00193 if (ar5k_ar5210_nic_wakeup(hal, AH_FALSE, AH_TRUE) != AH_TRUE)
00194 return (NULL);
00195
00196
00197 srev = AR5K_REG_READ(AR5K_AR5210_SREV);
00198 hal->ah_mac_version = AR5K_REG_MS(srev, AR5K_AR5210_SREV_VER);
00199 hal->ah_mac_revision = AR5K_REG_MS(srev, AR5K_AR5210_SREV_REV);
00200 hal->ah_phy_revision = AR5K_REG_READ(AR5K_AR5210_PHY_CHIP_ID) &
00201 0x00ffffffff;
00202
00203
00204 AR5K_REG_WRITE(AR5K_AR5210_PHY(0x34), 0x00001c16);
00205 for (i = 0; i < 4; i++)
00206 AR5K_REG_WRITE(AR5K_AR5210_PHY(0x20), 0x00010000);
00207 hal->ah_radio_5ghz_revision = (u_int16_t)
00208 (ar5k_bitswap((AR5K_REG_READ(AR5K_AR5210_PHY(256) >> 28) & 0xf), 4)
00209 + 1);
00210 hal->ah_radio_2ghz_revision = 0;
00211
00212
00213 hal->ah_version = AR5K_AR5210;
00214 hal->ah_radio = AR5K_AR5110;
00215 hal->ah_phy = AR5K_AR5210_PHY(0);
00216
00217 bcopy(etherbroadcastaddr, mac, IEEE80211_ADDR_LEN);
00218 ar5k_ar5210_set_associd(hal, mac, 0, 0);
00219 ar5k_ar5210_get_lladdr(hal, mac);
00220 ar5k_ar5210_set_opmode(hal);
00221
00222 return (hal);
00223 }
00224
00225 HAL_BOOL
00226 ar5k_ar5210_nic_reset(hal, val)
00227 struct ath_hal *hal;
00228 u_int32_t val;
00229 {
00230 HAL_BOOL ret = AH_FALSE;
00231 u_int32_t mask = val ? val : ~0;
00232
00233
00234
00235
00236 AR5K_REG_WRITE(AR5K_AR5210_RC, val);
00237
00238
00239 AR5K_DELAY(15);
00240
00241 val &=
00242 AR5K_AR5210_RC_PCU | AR5K_AR5210_RC_MAC |
00243 AR5K_AR5210_RC_PHY | AR5K_AR5210_RC_DMA;
00244
00245 mask &=
00246 AR5K_AR5210_RC_PCU | AR5K_AR5210_RC_MAC |
00247 AR5K_AR5210_RC_PHY | AR5K_AR5210_RC_DMA;
00248
00249 ret = ar5k_register_timeout(hal, AR5K_AR5210_RC, mask, val, AH_FALSE);
00250
00251
00252
00253
00254 if ((val & AR5K_AR5210_RC_MAC) == 0) {
00255 AR5K_REG_WRITE(AR5K_AR5210_CFG, AR5K_AR5210_INIT_CFG);
00256 }
00257
00258 return (ret);
00259 }
00260
00261 HAL_BOOL
00262 ar5k_ar5210_nic_wakeup(hal, turbo, initial)
00263 struct ath_hal *hal;
00264 HAL_BOOL turbo;
00265 HAL_BOOL initial;
00266 {
00267
00268
00269
00270
00271 if (initial == AH_TRUE) {
00272
00273 if (ar5k_ar5210_nic_reset(hal,
00274 AR5K_AR5210_RC_PCI) == AH_FALSE) {
00275 AR5K_PRINT("failed to reset the PCI chipset\n");
00276 return (AH_FALSE);
00277 }
00278
00279 AR5K_DELAY(1000);
00280 }
00281
00282
00283 if (ar5k_ar5210_set_power(hal,
00284 HAL_PM_AWAKE, AH_TRUE, 0) == AH_FALSE) {
00285 AR5K_PRINT("failed to resume the AR5210 chipset\n");
00286 return (AH_FALSE);
00287 }
00288
00289
00290 AR5K_REG_WRITE(AR5K_AR5210_PHY_FC,
00291 turbo == AH_TRUE ? AR5K_AR5210_PHY_FC_TURBO_MODE : 0);
00292
00293
00294 if (ar5k_ar5210_nic_reset(hal, AR5K_AR5210_RC_CHIP) == AH_FALSE) {
00295 AR5K_PRINT("failed to reset the AR5210 chipset\n");
00296 return (AH_FALSE);
00297 }
00298
00299 AR5K_DELAY(1000);
00300
00301
00302 if (ar5k_ar5210_nic_reset(hal,
00303 AR5K_AR5210_RC_CHIP | AR5K_AR5210_RC_PCI) == AH_FALSE) {
00304 AR5K_PRINT("failed to reset the AR5210 + PCI chipset\n");
00305 return (AH_FALSE);
00306 }
00307
00308 AR5K_DELAY(2300);
00309
00310
00311 if (ar5k_ar5210_set_power(hal,
00312 HAL_PM_AWAKE, AH_TRUE, 0) == AH_FALSE) {
00313 AR5K_PRINT("failed to resume the AR5210 (again)\n");
00314 return (AH_FALSE);
00315 }
00316
00317
00318 if (ar5k_ar5210_nic_reset(hal, 0) == AH_FALSE) {
00319 AR5K_PRINT("failed to warm reset the AR5210\n");
00320 return (AH_FALSE);
00321 }
00322
00323 return (AH_TRUE);
00324 }
00325
00326 const HAL_RATE_TABLE *
00327 ar5k_ar5210_get_rate_table(hal, mode)
00328 struct ath_hal *hal;
00329 u_int mode;
00330 {
00331 switch (mode) {
00332 case HAL_MODE_11A:
00333 return (&hal->ah_rt_11a);
00334 case HAL_MODE_TURBO:
00335 return (&hal->ah_rt_turbo);
00336 case HAL_MODE_11B:
00337 case HAL_MODE_11G:
00338 default:
00339 return (NULL);
00340 }
00341
00342 return (NULL);
00343 }
00344
00345 void
00346 ar5k_ar5210_detach(hal)
00347 struct ath_hal *hal;
00348 {
00349
00350
00351
00352 free(hal, M_DEVBUF);
00353 }
00354
00355 HAL_BOOL
00356 ar5k_ar5210_reset(hal, op_mode, channel, change_channel, status)
00357 struct ath_hal *hal;
00358 HAL_OPMODE op_mode;
00359 HAL_CHANNEL *channel;
00360 HAL_BOOL change_channel;
00361 HAL_STATUS *status;
00362 {
00363 int i;
00364
00365
00366 *status = HAL_OK;
00367
00368 if (ar5k_ar5210_nic_wakeup(hal,
00369 channel->c_channel_flags & IEEE80211_CHAN_T ?
00370 AH_TRUE : AH_FALSE, AH_FALSE) == AH_FALSE)
00371 return (AH_FALSE);
00372
00373
00374
00375
00376 hal->ah_op_mode = op_mode;
00377 ar5k_ar5210_set_opmode(hal);
00378
00379
00380
00381
00382 for (i = 0; i < AR5K_ELEMENTS(ar5210_ini); i++) {
00383 if (change_channel == AH_TRUE &&
00384 ar5210_ini[i].ini_register >= AR5K_AR5210_PCU_MIN &&
00385 ar5210_ini[i].ini_register <= AR5K_AR5210_PCU_MAX)
00386 continue;
00387
00388 switch (ar5210_ini[i].ini_mode) {
00389 case AR5K_INI_READ:
00390
00391 AR5K_REG_READ(ar5210_ini[i].ini_register);
00392 break;
00393
00394 case AR5K_INI_WRITE:
00395 default:
00396 AR5K_REG_WRITE(ar5210_ini[i].ini_register,
00397 ar5210_ini[i].ini_value);
00398 }
00399 }
00400
00401 AR5K_DELAY(1000);
00402
00403
00404
00405
00406
00407
00408 AR5K_REG_WRITE(AR5K_AR5210_PHY_ACTIVE, AR5K_AR5210_PHY_DISABLE);
00409 AR5K_DELAY(1000);
00410
00411 if (ar5k_channel(hal, channel) == AH_FALSE)
00412 return (AH_FALSE);
00413
00414
00415
00416
00417 AR5K_REG_WRITE(AR5K_AR5210_PHY_ACTIVE, AR5K_AR5210_PHY_ENABLE);
00418 AR5K_DELAY(1000);
00419
00420 ar5k_ar5210_do_calibrate(hal, channel);
00421 if (ar5k_ar5210_noise_floor(hal, channel) == AH_FALSE)
00422 return (AH_FALSE);
00423
00424
00425
00426
00427 if (AR5K_EEPROM_HDR_RFKILL(hal->ah_capabilities.cap_eeprom.ee_header)) {
00428 ar5k_ar5210_set_gpio_input(hal, 0);
00429 if ((hal->ah_gpio[0] = ar5k_ar5210_get_gpio(hal, 0)) == 0) {
00430 ar5k_ar5210_set_gpio_intr(hal, 0, 1);
00431 } else {
00432 ar5k_ar5210_set_gpio_intr(hal, 0, 0);
00433 }
00434 }
00435
00436
00437
00438
00439 for (i = 0; i < hal->ah_capabilities.cap_queues.q_tx_num; i++) {
00440 if (ar5k_ar5210_reset_tx_queue(hal, i) == AH_FALSE) {
00441 AR5K_PRINTF("failed to reset TX queue #%d\n", i);
00442 return (AH_FALSE);
00443 }
00444 }
00445
00446 AR5K_REG_DISABLE_BITS(AR5K_AR5210_BEACON,
00447 AR5K_AR5210_BEACON_EN | AR5K_AR5210_BEACON_RESET_TSF);
00448
00449 return (AH_TRUE);
00450 }
00451
00452 void
00453 ar5k_ar5210_set_opmode(hal)
00454 struct ath_hal *hal;
00455 {
00456 u_int32_t pcu_reg, beacon_reg, low_id, high_id;
00457
00458 beacon_reg = 0;
00459 pcu_reg = 0;
00460
00461 switch (hal->ah_op_mode) {
00462 case IEEE80211_M_STA:
00463 pcu_reg |= AR5K_AR5210_STA_ID1_NO_PSPOLL |
00464 AR5K_AR5210_STA_ID1_DESC_ANTENNA |
00465 AR5K_AR5210_STA_ID1_PWR_SV;
00466 break;
00467
00468 case IEEE80211_M_IBSS:
00469 pcu_reg |= AR5K_AR5210_STA_ID1_ADHOC |
00470 AR5K_AR5210_STA_ID1_NO_PSPOLL |
00471 AR5K_AR5210_STA_ID1_DESC_ANTENNA;
00472 beacon_reg |= AR5K_AR5210_BCR_ADHOC;
00473 break;
00474
00475 case IEEE80211_M_HOSTAP:
00476 pcu_reg |= AR5K_AR5210_STA_ID1_AP |
00477 AR5K_AR5210_STA_ID1_NO_PSPOLL |
00478 AR5K_AR5210_STA_ID1_DESC_ANTENNA;
00479 beacon_reg |= AR5K_AR5210_BCR_AP;
00480 break;
00481
00482 case IEEE80211_M_MONITOR:
00483 pcu_reg |= AR5K_AR5210_STA_ID1_NO_PSPOLL;
00484 break;
00485
00486 default:
00487 return;
00488 }
00489
00490
00491
00492
00493 bcopy(&(hal->ah_sta_id[0]), &low_id, 4);
00494 bcopy(&(hal->ah_sta_id[4]), &high_id, 2);
00495 AR5K_REG_WRITE(AR5K_AR5210_STA_ID0, low_id);
00496 AR5K_REG_WRITE(AR5K_AR5210_STA_ID1, pcu_reg | high_id);
00497 AR5K_REG_WRITE(AR5K_AR5210_BCR, beacon_reg);
00498
00499 return;
00500 }
00501
00502 HAL_BOOL
00503 ar5k_ar5210_calibrate(hal, channel)
00504 struct ath_hal *hal;
00505 HAL_CHANNEL *channel;
00506 {
00507 HAL_BOOL ret = AH_TRUE;
00508 u_int32_t phy_sig, phy_agc, phy_sat, beacon;
00509
00510 #define AGC_DISABLE { \
00511 AR5K_REG_ENABLE_BITS(AR5K_AR5210_PHY_AGC, \
00512 AR5K_AR5210_PHY_AGC_DISABLE); \
00513 AR5K_DELAY(10); \
00514 }
00515
00516 #define AGC_ENABLE { \
00517 AR5K_REG_DISABLE_BITS(AR5K_AR5210_PHY_AGC, \
00518 AR5K_AR5210_PHY_AGC_DISABLE); \
00519 }
00520
00521
00522
00523
00524 AR5K_REG_ENABLE_BITS(AR5K_AR5210_DIAG_SW,
00525 AR5K_AR5210_DIAG_SW_DIS_TX | AR5K_AR5210_DIAG_SW_DIS_RX);
00526 beacon = AR5K_REG_READ(AR5K_AR5210_BEACON);
00527 AR5K_REG_WRITE(AR5K_AR5210_BEACON, beacon & ~AR5K_AR5210_BEACON_EN);
00528
00529 AR5K_DELAY(2300);
00530
00531
00532
00533
00534 AGC_DISABLE;
00535 ret = ar5k_channel(hal, channel);
00536
00537
00538
00539
00540 AR5K_REG_WRITE(AR5K_AR5210_PHY_ACTIVE, AR5K_AR5210_PHY_ENABLE);
00541 AR5K_DELAY(1000);
00542
00543 AGC_ENABLE;
00544
00545 if (ret == AH_FALSE)
00546 return (ret);
00547
00548
00549
00550
00551
00552
00553 phy_sig = AR5K_REG_READ(AR5K_AR5210_PHY_SIG);
00554 phy_agc = AR5K_REG_READ(AR5K_AR5210_PHY_AGCCOARSE);
00555 phy_sat = AR5K_REG_READ(AR5K_AR5210_PHY_ADCSAT);
00556
00557
00558 AR5K_REG_WRITE(AR5K_AR5210_PHY_SIG,
00559 (phy_sig & ~(AR5K_AR5210_PHY_SIG_FIRPWR)) |
00560 AR5K_REG_SM(-1, AR5K_AR5210_PHY_SIG_FIRPWR));
00561
00562 AR5K_REG_WRITE(AR5K_AR5210_PHY_AGCCOARSE,
00563 (phy_agc & ~(AR5K_AR5210_PHY_AGCCOARSE_HI |
00564 AR5K_AR5210_PHY_AGCCOARSE_LO)) |
00565 AR5K_REG_SM(-1, AR5K_AR5210_PHY_AGCCOARSE_HI) |
00566 AR5K_REG_SM(-127, AR5K_AR5210_PHY_AGCCOARSE_LO));
00567
00568 AR5K_REG_WRITE(AR5K_AR5210_PHY_ADCSAT,
00569 (phy_sat & ~(AR5K_AR5210_PHY_ADCSAT_ICNT |
00570 AR5K_AR5210_PHY_ADCSAT_THR)) |
00571 AR5K_REG_SM(2, AR5K_AR5210_PHY_ADCSAT_ICNT) |
00572 AR5K_REG_SM(12, AR5K_AR5210_PHY_ADCSAT_THR));
00573
00574 AR5K_DELAY(20);
00575
00576 AGC_DISABLE;
00577 AR5K_REG_WRITE(AR5K_AR5210_PHY_RFSTG, AR5K_AR5210_PHY_RFSTG_DISABLE);
00578 AGC_ENABLE;
00579
00580 AR5K_DELAY(1000);
00581
00582 ret = ar5k_ar5210_do_calibrate(hal, channel);
00583
00584
00585 AR5K_REG_WRITE(AR5K_AR5210_PHY_SIG, phy_sig);
00586 AR5K_REG_WRITE(AR5K_AR5210_PHY_AGCCOARSE, phy_agc);
00587 AR5K_REG_WRITE(AR5K_AR5210_PHY_ADCSAT, phy_sat);
00588
00589 if (ret == AH_FALSE)
00590 return (AH_FALSE);
00591
00592 if (ar5k_ar5210_noise_floor(hal, channel) == AH_FALSE)
00593 return (AH_FALSE);
00594
00595
00596
00597
00598 AR5K_REG_DISABLE_BITS(AR5K_AR5210_DIAG_SW,
00599 AR5K_AR5210_DIAG_SW_DIS_TX | AR5K_AR5210_DIAG_SW_DIS_RX);
00600 AR5K_REG_WRITE(AR5K_AR5210_BEACON, beacon);
00601
00602 #undef AGC_ENABLE
00603 #undef AGC_DISABLE
00604
00605 return (AH_TRUE);
00606 }
00607
00608 HAL_BOOL
00609 ar5k_ar5210_do_calibrate(hal, channel)
00610 struct ath_hal *hal;
00611 HAL_CHANNEL *channel;
00612 {
00613
00614
00615
00616 AR5K_REG_ENABLE_BITS(AR5K_AR5210_PHY_AGCCTL,
00617 AR5K_AR5210_PHY_AGCCTL_CAL);
00618
00619 if (ar5k_register_timeout(hal, AR5K_AR5210_PHY_AGCCTL,
00620 AR5K_AR5210_PHY_AGCCTL_CAL, 0, AH_FALSE) == AH_FALSE) {
00621 AR5K_PRINTF("calibration timeout (%uMHz)\n",
00622 channel->c_channel);
00623 return (AH_FALSE);
00624 }
00625
00626 return (AH_TRUE);
00627 }
00628
00629 HAL_BOOL
00630 ar5k_ar5210_noise_floor(hal, channel)
00631 struct ath_hal *hal;
00632 HAL_CHANNEL *channel;
00633 {
00634 int i;
00635 u_int32_t noise_floor;
00636
00637
00638
00639
00640 AR5K_REG_ENABLE_BITS(AR5K_AR5210_PHY_AGCCTL,
00641 AR5K_AR5210_PHY_AGCCTL_NF);
00642
00643 if (ar5k_register_timeout(hal, AR5K_AR5210_PHY_AGCCTL,
00644 AR5K_AR5210_PHY_AGCCTL_NF, 0, AH_FALSE) == AH_FALSE) {
00645 AR5K_PRINTF("noise floor calibration timeout (%uMHz)\n",
00646 channel->c_channel);
00647 return (AH_FALSE);
00648 }
00649
00650
00651 for (i = 20; i > 0; i--) {
00652 AR5K_DELAY(1000);
00653 noise_floor = AR5K_REG_READ(AR5K_AR5210_PHY_NF);
00654 if (AR5K_AR5210_PHY_NF_RVAL(noise_floor) &
00655 AR5K_AR5210_PHY_NF_ACTIVE)
00656 noise_floor = AR5K_AR5210_PHY_NF_AVAL(noise_floor);
00657 if (noise_floor <= AR5K_TUNE_NOISE_FLOOR)
00658 break;
00659 }
00660
00661 if (noise_floor > AR5K_TUNE_NOISE_FLOOR) {
00662 AR5K_PRINTF("noise floor calibration failed (%uMHz)\n",
00663 channel->c_channel);
00664 return (AH_FALSE);
00665 }
00666
00667 return (AH_TRUE);
00668 }
00669
00670
00671
00672
00673
00674 HAL_BOOL
00675 ar5k_ar5210_update_tx_triglevel(hal, increase)
00676 struct ath_hal *hal;
00677 HAL_BOOL increase;
00678 {
00679 u_int32_t trigger_level;
00680 HAL_BOOL status = AH_FALSE;
00681
00682
00683
00684
00685 AR5K_REG_DISABLE_BITS(AR5K_AR5210_IMR, HAL_INT_GLOBAL);
00686
00687 trigger_level = AR5K_REG_READ(AR5K_AR5210_TRIG_LVL);
00688
00689 if (increase == AH_FALSE) {
00690 if (--trigger_level < AR5K_TUNE_MIN_TX_FIFO_THRES)
00691 goto done;
00692 } else {
00693 trigger_level +=
00694 ((AR5K_TUNE_MAX_TX_FIFO_THRES - trigger_level) / 2);
00695 }
00696
00697
00698
00699
00700 AR5K_REG_WRITE(AR5K_AR5210_TRIG_LVL, trigger_level);
00701 status = AH_TRUE;
00702
00703 done:
00704
00705
00706
00707 AR5K_REG_ENABLE_BITS(AR5K_AR5210_IMR, HAL_INT_GLOBAL);
00708
00709 return (status);
00710 }
00711
00712 int
00713 ar5k_ar5210_setup_tx_queue(hal, queue_type, queue_info)
00714 struct ath_hal *hal;
00715 HAL_TX_QUEUE queue_type;
00716 const HAL_TXQ_INFO *queue_info;
00717 {
00718 u_int queue;
00719
00720
00721
00722
00723 switch (queue_type) {
00724 case HAL_TX_QUEUE_DATA:
00725 queue = 0;
00726 break;
00727 case HAL_TX_QUEUE_BEACON:
00728 case HAL_TX_QUEUE_CAB:
00729 queue = 1;
00730 break;
00731 default:
00732 return (-1);
00733 }
00734
00735
00736
00737
00738 bzero(&hal->ah_txq[queue], sizeof(HAL_TXQ_INFO));
00739 hal->ah_txq[queue].tqi_type = queue_type;
00740
00741 if (queue_info != NULL) {
00742 if (ar5k_ar5210_setup_tx_queueprops(hal,
00743 queue, queue_info) != AH_TRUE)
00744 return (-1);
00745 }
00746
00747 return (queue);
00748 }
00749
00750 HAL_BOOL
00751 ar5k_ar5210_setup_tx_queueprops(hal, queue, queue_info)
00752 struct ath_hal *hal;
00753 int queue;
00754 const HAL_TXQ_INFO *queue_info;
00755 {
00756 AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
00757
00758 if (hal->ah_txq[queue].tqi_type == HAL_TX_QUEUE_INACTIVE)
00759 return (AH_FALSE);
00760
00761 hal->ah_txq[queue].tqi_aifs = queue_info->tqi_aifs;
00762 hal->ah_txq[queue].tqi_cw_max = queue_info->tqi_cw_max;
00763 hal->ah_txq[queue].tqi_cw_min = queue_info->tqi_cw_min;
00764 hal->ah_txq[queue].tqi_flags = queue_info->tqi_flags;
00765
00766 return (AH_TRUE);
00767 }
00768
00769 HAL_BOOL
00770 ar5k_ar5210_release_tx_queue(hal, queue)
00771 struct ath_hal *hal;
00772 u_int queue;
00773 {
00774 AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
00775
00776
00777 hal->ah_txq[queue].tqi_type = HAL_TX_QUEUE_INACTIVE;
00778
00779 return (AH_FALSE);
00780 }
00781
00782 void
00783 ar5k_ar5210_init_tx_queue(hal, aifs, turbo)
00784 struct ath_hal *hal;
00785 u_int aifs;
00786 HAL_BOOL turbo;
00787 {
00788 int i;
00789 struct {
00790 u_int16_t mode_register;
00791 u_int32_t mode_base, mode_turbo;
00792 } initial[] = AR5K_AR5210_INI_MODE(aifs);
00793
00794
00795
00796
00797 for (i = 0; i < AR5K_ELEMENTS(initial); i++)
00798 AR5K_REG_WRITE((u_int32_t)initial[i].mode_register,
00799 turbo == AH_TRUE ?
00800 initial[i].mode_turbo : initial[i].mode_base);
00801 }
00802
00803 HAL_BOOL
00804 ar5k_ar5210_reset_tx_queue(hal, queue)
00805 struct ath_hal *hal;
00806 u_int queue;
00807 {
00808 u_int32_t cw_min, retry_lg, retry_sh;
00809 HAL_TXQ_INFO *tq;
00810
00811 AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
00812
00813 tq = &hal->ah_txq[queue];
00814
00815
00816 if (tq->tqi_type != HAL_TX_QUEUE_DATA)
00817 return (AH_TRUE);
00818
00819
00820 ar5k_ar5210_init_tx_queue(hal, hal->ah_aifs + tq->tqi_aifs,
00821 hal->ah_turbo == AH_TRUE ? AH_TRUE : AH_FALSE);
00822
00823
00824
00825
00826 if (hal->ah_software_retry == AH_TRUE) {
00827
00828 retry_lg = hal->ah_limit_tx_retries;
00829 retry_sh = retry_lg =
00830 retry_lg > AR5K_AR5210_RETRY_LMT_SH_RETRY ?
00831 AR5K_AR5210_RETRY_LMT_SH_RETRY : retry_lg;
00832 } else {
00833 retry_lg = AR5K_INIT_LG_RETRY;
00834 retry_sh = AR5K_INIT_SH_RETRY;
00835 }
00836
00837
00838
00839
00840 cw_min = 1;
00841 while (cw_min < hal->ah_cw_min)
00842 cw_min = (cw_min << 1) | 1;
00843
00844 cw_min = tq->tqi_cw_min < 0 ?
00845 (cw_min >> (-tq->tqi_cw_min)) :
00846 ((cw_min << tq->tqi_cw_min) + (1 << tq->tqi_cw_min) - 1);
00847
00848
00849 AR5K_REG_WRITE(AR5K_AR5210_RETRY_LMT,
00850 (cw_min << AR5K_AR5210_RETRY_LMT_CW_MIN_S)
00851 | AR5K_REG_SM(AR5K_INIT_SLG_RETRY, AR5K_AR5210_RETRY_LMT_SLG_RETRY)
00852 | AR5K_REG_SM(AR5K_INIT_SSH_RETRY, AR5K_AR5210_RETRY_LMT_SSH_RETRY)
00853 | AR5K_REG_SM(retry_lg, AR5K_AR5210_RETRY_LMT_LG_RETRY)
00854 | AR5K_REG_SM(retry_sh, AR5K_AR5210_RETRY_LMT_SH_RETRY));
00855
00856 return (AH_TRUE);
00857 }
00858
00859 u_int32_t
00860 ar5k_ar5210_get_tx_buf(hal, queue)
00861 struct ath_hal *hal;
00862 u_int queue;
00863 {
00864 u_int16_t tx_reg;
00865
00866 AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
00867
00868
00869
00870
00871 switch (hal->ah_txq[queue].tqi_type) {
00872 case HAL_TX_QUEUE_DATA:
00873 tx_reg = AR5K_AR5210_TXDP0;
00874 break;
00875 case HAL_TX_QUEUE_BEACON:
00876 case HAL_TX_QUEUE_CAB:
00877 tx_reg = AR5K_AR5210_TXDP1;
00878 break;
00879 default:
00880 return (0xffffffff);
00881 }
00882
00883 return (AR5K_REG_READ(tx_reg));
00884 }
00885
00886 HAL_BOOL
00887 ar5k_ar5210_put_tx_buf(hal, queue, phys_addr)
00888 struct ath_hal *hal;
00889 u_int queue;
00890 u_int32_t phys_addr;
00891 {
00892 u_int16_t tx_reg;
00893
00894 AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
00895
00896
00897
00898
00899 switch (hal->ah_txq[queue].tqi_type) {
00900 case HAL_TX_QUEUE_DATA:
00901 tx_reg = AR5K_AR5210_TXDP0;
00902 break;
00903 case HAL_TX_QUEUE_BEACON:
00904 case HAL_TX_QUEUE_CAB:
00905 tx_reg = AR5K_AR5210_TXDP1;
00906 break;
00907 default:
00908 return (AH_FALSE);
00909 }
00910
00911
00912 AR5K_REG_WRITE(tx_reg, phys_addr);
00913
00914 return (AH_TRUE);
00915 }
00916
00917 HAL_BOOL
00918 ar5k_ar5210_tx_start(hal, queue)
00919 struct ath_hal *hal;
00920 u_int queue;
00921 {
00922 u_int32_t tx_queue;
00923
00924 AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
00925
00926 tx_queue = AR5K_REG_READ(AR5K_AR5210_CR);
00927
00928
00929
00930
00931 switch (hal->ah_txq[queue].tqi_type) {
00932 case HAL_TX_QUEUE_DATA:
00933 tx_queue |= AR5K_AR5210_CR_TXE0 & ~AR5K_AR5210_CR_TXD0;
00934 break;
00935
00936 case HAL_TX_QUEUE_BEACON:
00937 tx_queue |= AR5K_AR5210_CR_TXE1 & ~AR5K_AR5210_CR_TXD1;
00938 AR5K_REG_WRITE(AR5K_AR5210_BSR,
00939 AR5K_AR5210_BCR_TQ1V | AR5K_AR5210_BCR_BDMAE);
00940 break;
00941
00942 case HAL_TX_QUEUE_CAB:
00943 tx_queue |= AR5K_AR5210_CR_TXE1 & ~AR5K_AR5210_CR_TXD1;
00944 AR5K_REG_WRITE(AR5K_AR5210_BSR,
00945 AR5K_AR5210_BCR_TQ1FV | AR5K_AR5210_BCR_TQ1V |
00946 AR5K_AR5210_BCR_BDMAE);
00947 break;
00948
00949 default:
00950 return (AH_FALSE);
00951 }
00952
00953
00954 AR5K_REG_WRITE(AR5K_AR5210_CR, tx_queue);
00955
00956 return (AH_TRUE);
00957 }
00958
00959 HAL_BOOL
00960 ar5k_ar5210_stop_tx_dma(hal, queue)
00961 struct ath_hal *hal;
00962 u_int queue;
00963 {
00964 u_int32_t tx_queue;
00965
00966 AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
00967
00968 tx_queue = AR5K_REG_READ(AR5K_AR5210_CR);
00969
00970
00971
00972
00973 switch (hal->ah_txq[queue].tqi_type) {
00974 case HAL_TX_QUEUE_DATA:
00975 tx_queue |= AR5K_AR5210_CR_TXD0 & ~AR5K_AR5210_CR_TXE0;
00976 break;
00977
00978 case HAL_TX_QUEUE_BEACON:
00979 case HAL_TX_QUEUE_CAB:
00980
00981 tx_queue |= AR5K_AR5210_CR_TXD1 & ~AR5K_AR5210_CR_TXD1;
00982 AR5K_REG_WRITE(AR5K_AR5210_BSR, 0);
00983 break;
00984
00985 default:
00986 return (AH_FALSE);
00987 }
00988
00989
00990 AR5K_REG_WRITE(AR5K_AR5210_CR, tx_queue);
00991
00992 return (AH_TRUE);
00993 }
00994
00995 HAL_BOOL
00996 ar5k_ar5210_setup_tx_desc(hal, desc, packet_length, header_length, type,
00997 tx_power, tx_rate0, tx_tries0, key_index, antenna_mode, flags, rtscts_rate,
00998 rtscts_duration)
00999 struct ath_hal *hal;
01000 struct ath_desc *desc;
01001 u_int packet_length;
01002 u_int header_length;
01003 HAL_PKT_TYPE type;
01004 u_int tx_power;
01005 u_int tx_rate0;
01006 u_int tx_tries0;
01007 u_int key_index;
01008 u_int antenna_mode;
01009 u_int flags;
01010 u_int rtscts_rate;
01011 u_int rtscts_duration;
01012 {
01013 u_int32_t frame_type;
01014 struct ar5k_ar5210_tx_desc *tx_desc;
01015
01016 tx_desc = (struct ar5k_ar5210_tx_desc*)&desc->ds_ctl0;
01017
01018
01019
01020
01021 if (tx_tries0 == 0)
01022 return (AH_FALSE);
01023
01024 if ((tx_desc->tx_control_0 = (packet_length &
01025 AR5K_AR5210_DESC_TX_CTL0_FRAME_LEN)) != packet_length)
01026 return (AH_FALSE);
01027
01028 if ((tx_desc->tx_control_0 = (header_length &
01029 AR5K_AR5210_DESC_TX_CTL0_HEADER_LEN)) != header_length)
01030 return (AH_FALSE);
01031
01032 if (type == HAL_PKT_TYPE_BEACON || type == HAL_PKT_TYPE_PROBE_RESP)
01033 frame_type = AR5K_AR5210_DESC_TX_FRAME_TYPE_NO_DELAY;
01034 else if (type == HAL_PKT_TYPE_PIFS)
01035 frame_type = AR5K_AR5210_DESC_TX_FRAME_TYPE_PIFS;
01036 else
01037 frame_type = type;
01038
01039 tx_desc->tx_control_0 =
01040 AR5K_REG_SM(frame_type, AR5K_AR5210_DESC_TX_CTL0_FRAME_TYPE);
01041 tx_desc->tx_control_0 |=
01042 AR5K_REG_SM(tx_rate0, AR5K_AR5210_DESC_TX_CTL0_XMIT_RATE);
01043
01044 #define _TX_FLAGS(_c, _flag) \
01045 if (flags & HAL_TXDESC_##_flag) \
01046 tx_desc->tx_control_##_c |= \
01047 AR5K_AR5210_DESC_TX_CTL##_c##_##_flag
01048
01049 _TX_FLAGS(0, CLRDMASK);
01050 _TX_FLAGS(0, INTREQ);
01051 _TX_FLAGS(0, RTSENA);
01052
01053 #undef _TX_FLAGS
01054
01055
01056
01057
01058 if (key_index != HAL_TXKEYIX_INVALID) {
01059 tx_desc->tx_control_0 |=
01060 AR5K_AR5210_DESC_TX_CTL0_ENCRYPT_KEY_VALID;
01061 tx_desc->tx_control_1 |=
01062 AR5K_REG_SM(key_index,
01063 AR5K_AR5210_DESC_TX_CTL1_ENCRYPT_KEY_INDEX);
01064 }
01065
01066
01067
01068
01069 if (flags & (HAL_TXDESC_RTSENA | HAL_TXDESC_CTSENA)) {
01070 tx_desc->tx_control_1 |=
01071 rtscts_duration & AR5K_AR5210_DESC_TX_CTL1_RTS_DURATION;
01072 }
01073
01074 return (AH_TRUE);
01075 }
01076
01077 HAL_BOOL
01078 ar5k_ar5210_fill_tx_desc(hal, desc, segment_length, first_segment, last_segment)
01079 struct ath_hal *hal;
01080 struct ath_desc *desc;
01081 u_int segment_length;
01082 HAL_BOOL first_segment;
01083 HAL_BOOL last_segment;
01084 {
01085 struct ar5k_ar5210_tx_desc *tx_desc;
01086
01087 tx_desc = (struct ar5k_ar5210_tx_desc*)&desc->ds_ctl0;
01088
01089
01090 bzero(desc->ds_hw, sizeof(desc->ds_hw));
01091
01092
01093 if ((tx_desc->tx_control_1 = (segment_length &
01094 AR5K_AR5210_DESC_TX_CTL1_BUF_LEN)) != segment_length)
01095 return (AH_FALSE);
01096
01097 if (first_segment != AH_TRUE)
01098 tx_desc->tx_control_0 &= ~AR5K_AR5210_DESC_TX_CTL0_FRAME_LEN;
01099
01100 if (last_segment != AH_TRUE)
01101 tx_desc->tx_control_1 |= AR5K_AR5210_DESC_TX_CTL1_MORE;
01102
01103 return (AH_TRUE);
01104 }
01105
01106 HAL_BOOL
01107 ar5k_ar5210_setup_xtx_desc(hal, desc, tx_rate1, tx_tries1, tx_rate2, tx_tries2,
01108 tx_rate3, tx_tries3)
01109 struct ath_hal *hal;
01110 struct ath_desc *desc;
01111 u_int tx_rate1;
01112 u_int tx_tries1;
01113 u_int tx_rate2;
01114 u_int tx_tries2;
01115 u_int tx_rate3;
01116 u_int tx_tries3;
01117 {
01118
01119
01120
01121
01122
01123 return (AH_FALSE);
01124 }
01125
01126 HAL_STATUS
01127 ar5k_ar5210_proc_tx_desc(hal, desc)
01128 struct ath_hal *hal;
01129 struct ath_desc *desc;
01130 {
01131 struct ar5k_ar5210_tx_status *tx_status;
01132 struct ar5k_ar5210_tx_desc *tx_desc;
01133
01134 tx_desc = (struct ar5k_ar5210_tx_desc*)&desc->ds_ctl0;
01135 tx_status = (struct ar5k_ar5210_tx_status*)&desc->ds_hw[0];
01136
01137
01138 if ((tx_status->tx_status_1 & AR5K_AR5210_DESC_TX_STATUS1_DONE) == 0)
01139 return (HAL_EINPROGRESS);
01140
01141
01142
01143
01144 desc->ds_us.tx.ts_tstamp =
01145 AR5K_REG_MS(tx_status->tx_status_0,
01146 AR5K_AR5210_DESC_TX_STATUS0_SEND_TIMESTAMP);
01147 desc->ds_us.tx.ts_shortretry =
01148 AR5K_REG_MS(tx_status->tx_status_0,
01149 AR5K_AR5210_DESC_TX_STATUS0_SHORT_RETRY_COUNT);
01150 desc->ds_us.tx.ts_longretry =
01151 AR5K_REG_MS(tx_status->tx_status_0,
01152 AR5K_AR5210_DESC_TX_STATUS0_LONG_RETRY_COUNT);
01153 desc->ds_us.tx.ts_seqnum =
01154 AR5K_REG_MS(tx_status->tx_status_1,
01155 AR5K_AR5210_DESC_TX_STATUS1_SEQ_NUM);
01156 desc->ds_us.tx.ts_rssi =
01157 AR5K_REG_MS(tx_status->tx_status_1,
01158 AR5K_AR5210_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
01159 desc->ds_us.tx.ts_antenna = 1;
01160 desc->ds_us.tx.ts_status = 0;
01161 desc->ds_us.tx.ts_tstamp =
01162 AR5K_REG_MS(tx_desc->tx_control_0,
01163 AR5K_AR5210_DESC_TX_CTL0_XMIT_RATE);
01164
01165 if ((tx_status->tx_status_0 &
01166 AR5K_AR5210_DESC_TX_STATUS0_FRAME_XMIT_OK) == 0) {
01167 if (tx_status->tx_status_0 &
01168 AR5K_AR5210_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
01169 desc->ds_us.tx.ts_status |= HAL_TXERR_XRETRY;
01170
01171 if (tx_status->tx_status_0 &
01172 AR5K_AR5210_DESC_TX_STATUS0_FIFO_UNDERRUN)
01173 desc->ds_us.tx.ts_status |= HAL_TXERR_FIFO;
01174
01175 if (tx_status->tx_status_0 &
01176 AR5K_AR5210_DESC_TX_STATUS0_FILTERED)
01177 desc->ds_us.tx.ts_status |= HAL_TXERR_FILT;
01178 }
01179
01180 return (HAL_OK);
01181 }
01182
01183 HAL_BOOL
01184 ar5k_ar5210_has_veol(hal)
01185 struct ath_hal *hal;
01186 {
01187 return (AH_FALSE);
01188 }
01189
01190
01191
01192
01193
01194 u_int32_t
01195 ar5k_ar5210_get_rx_buf(hal)
01196 struct ath_hal *hal;
01197 {
01198 return (AR5K_REG_READ(AR5K_AR5210_RXDP));
01199 }
01200
01201 void
01202 ar5k_ar5210_put_rx_buf(hal, phys_addr)
01203 struct ath_hal *hal;
01204 u_int32_t phys_addr;
01205 {
01206 AR5K_REG_WRITE(AR5K_AR5210_RXDP, phys_addr);
01207 }
01208
01209 void
01210 ar5k_ar5210_start_rx(hal)
01211 struct ath_hal *hal;
01212 {
01213 AR5K_REG_WRITE(AR5K_AR5210_CR, AR5K_AR5210_CR_RXE);
01214 }
01215
01216 HAL_BOOL
01217 ar5k_ar5210_stop_rx_dma(hal)
01218 struct ath_hal *hal;
01219 {
01220 int i;
01221
01222 AR5K_REG_WRITE(AR5K_AR5210_CR, AR5K_AR5210_CR_RXD);
01223
01224
01225
01226
01227 for (i = 2000;
01228 i > 0 && (AR5K_REG_READ(AR5K_AR5210_CR) & AR5K_AR5210_CR_RXE) != 0;
01229 i--)
01230 AR5K_DELAY(10);
01231
01232 return (i > 0 ? AH_TRUE : AH_FALSE);
01233 }
01234
01235 void
01236 ar5k_ar5210_start_rx_pcu(hal)
01237 struct ath_hal *hal;
01238 {
01239 AR5K_REG_DISABLE_BITS(AR5K_AR5210_DIAG_SW, AR5K_AR5210_DIAG_SW_DIS_RX);
01240 }
01241
01242 void
01243 ar5k_ar5210_stop_pcu_recv(hal)
01244 struct ath_hal *hal;
01245 {
01246 AR5K_REG_ENABLE_BITS(AR5K_AR5210_DIAG_SW, AR5K_AR5210_DIAG_SW_DIS_RX);
01247 }
01248
01249 void
01250 ar5k_ar5210_set_mcast_filter(hal, filter0, filter1)
01251 struct ath_hal *hal;
01252 u_int32_t filter0;
01253 u_int32_t filter1;
01254 {
01255
01256 AR5K_REG_WRITE(AR5K_AR5210_MCAST_FIL0, filter0);
01257 AR5K_REG_WRITE(AR5K_AR5210_MCAST_FIL1, filter1);
01258 }
01259
01260 HAL_BOOL
01261 ar5k_ar5210_set_mcast_filterindex(hal, index)
01262 struct ath_hal *hal;
01263 u_int32_t index;
01264 {
01265 if (index >= 64) {
01266 return (AH_FALSE);
01267 } else if (index >= 32) {
01268 AR5K_REG_ENABLE_BITS(AR5K_AR5210_MCAST_FIL1,
01269 (1 << (index - 32)));
01270 } else {
01271 AR5K_REG_ENABLE_BITS(AR5K_AR5210_MCAST_FIL0,
01272 (1 << index));
01273 }
01274
01275 return (AH_TRUE);
01276 }
01277
01278 HAL_BOOL
01279 ar5k_ar5210_clear_mcast_filter_idx(hal, index)
01280 struct ath_hal *hal;
01281 u_int32_t index;
01282 {
01283 if (index >= 64) {
01284 return (AH_FALSE);
01285 } else if (index >= 32) {
01286 AR5K_REG_DISABLE_BITS(AR5K_AR5210_MCAST_FIL1,
01287 (1 << (index - 32)));
01288 } else {
01289 AR5K_REG_DISABLE_BITS(AR5K_AR5210_MCAST_FIL0,
01290 (1 << index));
01291 }
01292
01293 return (AH_TRUE);
01294 }
01295
01296 u_int32_t
01297 ar5k_ar5210_get_rx_filter(hal)
01298 struct ath_hal *hal;
01299 {
01300 return (AR5K_REG_READ(AR5K_AR5210_RX_FILTER));
01301 }
01302
01303 void
01304 ar5k_ar5210_set_rx_filter(hal, filter)
01305 struct ath_hal *hal;
01306 u_int32_t filter;
01307 {
01308
01309
01310
01311 if (filter & HAL_RX_FILTER_PHYRADAR) {
01312 filter &= ~HAL_RX_FILTER_PHYRADAR;
01313 filter |= AR5K_AR5210_RX_FILTER_PROMISC;
01314 }
01315
01316 AR5K_REG_WRITE(AR5K_AR5210_RX_FILTER, filter);
01317 }
01318
01319 HAL_BOOL
01320 ar5k_ar5210_setup_rx_desc(hal, desc, size, flags)
01321 struct ath_hal *hal;
01322 struct ath_desc *desc;
01323 u_int32_t size;
01324 u_int flags;
01325 {
01326 struct ar5k_ar5210_rx_desc *rx_desc;
01327
01328 rx_desc = (struct ar5k_ar5210_rx_desc*)&desc->ds_ctl0;
01329
01330 if ((rx_desc->rx_control_1 = (size &
01331 AR5K_AR5210_DESC_RX_CTL1_BUF_LEN)) != size)
01332 return (AH_FALSE);
01333
01334 if (flags & HAL_RXDESC_INTREQ)
01335 rx_desc->rx_control_1 |= AR5K_AR5210_DESC_RX_CTL1_INTREQ;
01336
01337 return (AH_TRUE);
01338 }
01339
01340 HAL_STATUS
01341 ar5k_ar5210_proc_rx_desc(hal, desc, phys_addr, next)
01342 struct ath_hal *hal;
01343 struct ath_desc *desc;
01344 u_int32_t phys_addr;
01345 struct ath_desc *next;
01346 {
01347 struct ar5k_ar5210_rx_status *rx_status;
01348
01349 rx_status = (struct ar5k_ar5210_rx_status*)&desc->ds_hw[0];
01350
01351
01352 if ((rx_status->rx_status_1 & AR5K_AR5210_DESC_RX_STATUS1_DONE) == 0)
01353 return (HAL_EINPROGRESS);
01354
01355
01356
01357
01358 desc->ds_us.rx.rs_datalen = rx_status->rx_status_0 &
01359 AR5K_AR5210_DESC_RX_STATUS0_DATA_LEN;
01360 desc->ds_us.rx.rs_rssi =
01361 AR5K_REG_MS(rx_status->rx_status_0,
01362 AR5K_AR5210_DESC_RX_STATUS0_RECEIVE_SIGNAL);
01363 desc->ds_us.rx.rs_rate =
01364 AR5K_REG_MS(rx_status->rx_status_0,
01365 AR5K_AR5210_DESC_RX_STATUS0_RECEIVE_RATE);
01366 desc->ds_us.rx.rs_antenna = rx_status->rx_status_0 &
01367 AR5K_AR5210_DESC_RX_STATUS0_RECEIVE_ANTENNA;
01368 desc->ds_us.rx.rs_more = rx_status->rx_status_0 &
01369 AR5K_AR5210_DESC_RX_STATUS0_MORE;
01370 desc->ds_us.rx.rs_tstamp =
01371 AR5K_REG_MS(rx_status->rx_status_1,
01372 AR5K_AR5210_DESC_RX_STATUS1_RECEIVE_TIMESTAMP);
01373 desc->ds_us.rx.rs_status = 0;
01374
01375
01376
01377
01378 if (rx_status->rx_status_1 &
01379 AR5K_AR5210_DESC_RX_STATUS1_KEY_INDEX_VALID) {
01380 desc->ds_us.rx.rs_keyix =
01381 AR5K_REG_MS(rx_status->rx_status_1,
01382 AR5K_AR5210_DESC_RX_STATUS1_KEY_INDEX);
01383 } else {
01384 desc->ds_us.rx.rs_keyix = HAL_RXKEYIX_INVALID;
01385 }
01386
01387
01388
01389
01390 if ((rx_status->rx_status_1 &
01391 AR5K_AR5210_DESC_RX_STATUS1_FRAME_RECEIVE_OK) == 0) {
01392 if (rx_status->rx_status_1 &
01393 AR5K_AR5210_DESC_RX_STATUS1_CRC_ERROR)
01394 desc->ds_us.rx.rs_status |= HAL_RXERR_CRC;
01395
01396 if (rx_status->rx_status_1 &
01397 AR5K_AR5210_DESC_RX_STATUS1_FIFO_OVERRUN)
01398 desc->ds_us.rx.rs_status |= HAL_RXERR_FIFO;
01399
01400 if (rx_status->rx_status_1 &
01401 AR5K_AR5210_DESC_RX_STATUS1_PHY_ERROR) {
01402 desc->ds_us.rx.rs_status |= HAL_RXERR_PHY;
01403 desc->ds_us.rx.rs_phyerr =
01404 AR5K_REG_MS(rx_status->rx_status_1,
01405 AR5K_AR5210_DESC_RX_STATUS1_PHY_ERROR);
01406 }
01407
01408 if (rx_status->rx_status_1 &
01409 AR5K_AR5210_DESC_RX_STATUS1_DECRYPT_CRC_ERROR)
01410 desc->ds_us.rx.rs_status |= HAL_RXERR_DECRYPT;
01411 }
01412
01413 return (HAL_OK);
01414 }
01415
01416 void
01417 ar5k_ar5210_set_rx_signal(hal)
01418 struct ath_hal *hal;
01419 {
01420
01421 }
01422
01423
01424
01425
01426
01427 void
01428 ar5k_ar5210_dump_state(hal)
01429 struct ath_hal *hal;
01430 {
01431 #ifdef AR5K_DEBUG
01432 #define AR5K_PRINT_REGISTER(_x) \
01433 printf("(%s: %08x) ", #_x, AR5K_REG_READ(AR5K_AR5210_##_x));
01434
01435 printf("DMA registers:\n");
01436 AR5K_PRINT_REGISTER(TXDP0);
01437 AR5K_PRINT_REGISTER(TXDP1);
01438 AR5K_PRINT_REGISTER(CR);
01439 AR5K_PRINT_REGISTER(RXDP);
01440 AR5K_PRINT_REGISTER(CFG);
01441 AR5K_PRINT_REGISTER(ISR);
01442 AR5K_PRINT_REGISTER(IMR);
01443 AR5K_PRINT_REGISTER(IER);
01444 AR5K_PRINT_REGISTER(BCR);
01445 AR5K_PRINT_REGISTER(BSR);
01446 AR5K_PRINT_REGISTER(TXCFG);
01447 AR5K_PRINT_REGISTER(RXCFG);
01448 AR5K_PRINT_REGISTER(MIBC);
01449 AR5K_PRINT_REGISTER(TOPS);
01450 AR5K_PRINT_REGISTER(RXNOFRM);
01451 AR5K_PRINT_REGISTER(TXNOFRM);
01452 AR5K_PRINT_REGISTER(RPGTO);
01453 AR5K_PRINT_REGISTER(RFCNT);
01454 AR5K_PRINT_REGISTER(MISC);
01455 AR5K_PRINT_REGISTER(RC);
01456 AR5K_PRINT_REGISTER(SCR);
01457 AR5K_PRINT_REGISTER(INTPEND);
01458 AR5K_PRINT_REGISTER(SFR);
01459 AR5K_PRINT_REGISTER(PCICFG);
01460 AR5K_PRINT_REGISTER(GPIOCR);
01461 AR5K_PRINT_REGISTER(GPIODO);
01462 AR5K_PRINT_REGISTER(GPIODI);
01463 AR5K_PRINT_REGISTER(SREV);
01464 printf("\n");
01465
01466 printf("PCU registers:\n");
01467 AR5K_PRINT_REGISTER(STA_ID0);
01468 AR5K_PRINT_REGISTER(STA_ID1);
01469 AR5K_PRINT_REGISTER(BSS_ID0);
01470 AR5K_PRINT_REGISTER(BSS_ID1);
01471 AR5K_PRINT_REGISTER(SLOT_TIME);
01472 AR5K_PRINT_REGISTER(TIME_OUT);
01473 AR5K_PRINT_REGISTER(RSSI_THR);
01474 AR5K_PRINT_REGISTER(RETRY_LMT);
01475 AR5K_PRINT_REGISTER(USEC);
01476 AR5K_PRINT_REGISTER(BEACON);
01477 AR5K_PRINT_REGISTER(CFP_PERIOD);
01478 AR5K_PRINT_REGISTER(TIMER0);
01479 AR5K_PRINT_REGISTER(TIMER1);
01480 AR5K_PRINT_REGISTER(TIMER2);
01481 AR5K_PRINT_REGISTER(TIMER3);
01482 AR5K_PRINT_REGISTER(IFS0);
01483 AR5K_PRINT_REGISTER(IFS1);
01484 AR5K_PRINT_REGISTER(CFP_DUR);
01485 AR5K_PRINT_REGISTER(RX_FILTER);
01486 AR5K_PRINT_REGISTER(MCAST_FIL0);
01487 AR5K_PRINT_REGISTER(MCAST_FIL1);
01488 AR5K_PRINT_REGISTER(TX_MASK0);
01489 AR5K_PRINT_REGISTER(TX_MASK1);
01490 AR5K_PRINT_REGISTER(CLR_TMASK);
01491 AR5K_PRINT_REGISTER(TRIG_LVL);
01492 AR5K_PRINT_REGISTER(DIAG_SW);
01493 AR5K_PRINT_REGISTER(TSF_L32);
01494 AR5K_PRINT_REGISTER(TSF_U32);
01495 AR5K_PRINT_REGISTER(LAST_TSTP);
01496 AR5K_PRINT_REGISTER(RETRY_CNT);
01497 AR5K_PRINT_REGISTER(BACKOFF);
01498 AR5K_PRINT_REGISTER(NAV);
01499 AR5K_PRINT_REGISTER(RTS_OK);
01500 AR5K_PRINT_REGISTER(RTS_FAIL);
01501 AR5K_PRINT_REGISTER(ACK_FAIL);
01502 AR5K_PRINT_REGISTER(FCS_FAIL);
01503 AR5K_PRINT_REGISTER(BEACON_CNT);
01504 AR5K_PRINT_REGISTER(KEYTABLE_0);
01505 printf("\n");
01506
01507 printf("PHY registers:\n");
01508 AR5K_PRINT_REGISTER(PHY(0));
01509 AR5K_PRINT_REGISTER(PHY_FC);
01510 AR5K_PRINT_REGISTER(PHY_AGC);
01511 AR5K_PRINT_REGISTER(PHY_CHIP_ID);
01512 AR5K_PRINT_REGISTER(PHY_ACTIVE);
01513 AR5K_PRINT_REGISTER(PHY_AGCCTL);
01514 printf("\n");
01515 #endif
01516 }
01517
01518 HAL_BOOL
01519 ar5k_ar5210_get_diag_state(hal, id, device, size)
01520 struct ath_hal *hal;
01521 int id;
01522 void **device;
01523 u_int *size;
01524
01525 {
01526
01527
01528
01529
01530 return (AH_FALSE);
01531 }
01532
01533 void
01534 ar5k_ar5210_get_lladdr(hal, mac)
01535 struct ath_hal *hal;
01536 u_int8_t *mac;
01537 {
01538 bcopy(hal->ah_sta_id, mac, IEEE80211_ADDR_LEN);
01539 }
01540
01541 HAL_BOOL
01542 ar5k_ar5210_set_lladdr(hal, mac)
01543 struct ath_hal *hal;
01544 const u_int8_t *mac;
01545 {
01546 u_int32_t low_id, high_id;
01547
01548
01549 bcopy(mac, hal->ah_sta_id, IEEE80211_ADDR_LEN);
01550
01551 bcopy(mac, &low_id, 4);
01552 bcopy(mac + 4, &high_id, 2);
01553 high_id = 0x0000ffff & high_id;
01554
01555 AR5K_REG_WRITE(AR5K_AR5210_STA_ID0, low_id);
01556 AR5K_REG_WRITE(AR5K_AR5210_STA_ID1, high_id);
01557
01558 return (AH_TRUE);
01559 }
01560
01561 HAL_BOOL
01562 ar5k_ar5210_set_regdomain(hal, regdomain, status)
01563 struct ath_hal *hal;
01564 u_int16_t regdomain;
01565 HAL_STATUS *status;
01566
01567 {
01568 ieee80211_regdomain_t ieee_regdomain;
01569
01570 ieee_regdomain = ar5k_regdomain_to_ieee(regdomain);
01571
01572 if (ar5k_eeprom_regulation_domain(hal, AH_TRUE,
01573 &ieee_regdomain) == AH_TRUE) {
01574 *status = HAL_OK;
01575 return (AH_TRUE);
01576 }
01577
01578 *status = EIO;
01579
01580 return (AH_FALSE);
01581 }
01582
01583 void
01584 ar5k_ar5210_set_ledstate(hal, state)
01585 struct ath_hal *hal;
01586 HAL_LED_STATE state;
01587 {
01588 u_int32_t led;
01589
01590 led = AR5K_REG_READ(AR5K_AR5210_PCICFG);
01591
01592
01593
01594
01595 switch (state) {
01596 case IEEE80211_S_SCAN:
01597 case IEEE80211_S_INIT:
01598 led |=
01599 AR5K_AR5210_PCICFG_LED_PEND |
01600 AR5K_AR5210_PCICFG_LED_BCTL;
01601 break;
01602 case IEEE80211_S_RUN:
01603 led |=
01604 AR5K_AR5210_PCICFG_LED_ACT;
01605 break;
01606 default:
01607 led |=
01608 AR5K_AR5210_PCICFG_LED_ACT |
01609 AR5K_AR5210_PCICFG_LED_BCTL;
01610 break;
01611 }
01612
01613 AR5K_REG_WRITE(AR5K_AR5210_PCICFG, led);
01614 }
01615
01616 void
01617 ar5k_ar5210_set_associd(hal, bssid, assoc_id, tim_offset)
01618 struct ath_hal *hal;
01619 const u_int8_t *bssid;
01620 u_int16_t assoc_id;
01621 u_int16_t tim_offset;
01622 {
01623 u_int32_t low_id, high_id;
01624
01625
01626
01627
01628 bcopy(bssid, &low_id, 4);
01629 bcopy(bssid + 4, &high_id, 2);
01630 AR5K_REG_WRITE(AR5K_AR5210_BSS_ID0, low_id);
01631 AR5K_REG_WRITE(AR5K_AR5210_BSS_ID1, high_id |
01632 ((assoc_id & 0x3fff) << AR5K_AR5210_BSS_ID1_AID_S));
01633 bcopy(bssid, &hal->ah_bssid, IEEE80211_ADDR_LEN);
01634
01635 if (assoc_id == 0) {
01636 ar5k_ar5210_disable_pspoll(hal);
01637 return;
01638 }
01639
01640 AR5K_REG_WRITE_BITS(AR5K_AR5210_BEACON, AR5K_AR5210_BEACON_TIM,
01641 tim_offset ? tim_offset + 4 : 0);
01642
01643 ar5k_ar5210_enable_pspoll(hal, NULL, 0);
01644 }
01645
01646 HAL_BOOL
01647 ar5k_ar5210_set_gpio_output(hal, gpio)
01648 struct ath_hal *hal;
01649 u_int32_t gpio;
01650 {
01651 if (gpio > AR5K_AR5210_NUM_GPIO)
01652 return (AH_FALSE);
01653
01654 AR5K_REG_WRITE(AR5K_AR5210_GPIOCR,
01655 (AR5K_REG_READ(AR5K_AR5210_GPIOCR) &~ AR5K_AR5210_GPIOCR_ALL(gpio))
01656 | AR5K_AR5210_GPIOCR_OUT1(gpio));
01657
01658 return (AH_TRUE);
01659 }
01660
01661 HAL_BOOL
01662 ar5k_ar5210_set_gpio_input(hal, gpio)
01663 struct ath_hal *hal;
01664 u_int32_t gpio;
01665 {
01666 if (gpio > AR5K_AR5210_NUM_GPIO)
01667 return (AH_FALSE);
01668
01669 AR5K_REG_WRITE(AR5K_AR5210_GPIOCR,
01670 (AR5K_REG_READ(AR5K_AR5210_GPIOCR) &~ AR5K_AR5210_GPIOCR_ALL(gpio))
01671 | AR5K_AR5210_GPIOCR_IN(gpio));
01672
01673 return (AH_TRUE);
01674 }
01675
01676 u_int32_t
01677 ar5k_ar5210_get_gpio(hal, gpio)
01678 struct ath_hal *hal;
01679 u_int32_t gpio;
01680 {
01681 if (gpio > AR5K_AR5210_NUM_GPIO)
01682 return (0xffffffff);
01683
01684
01685 return (((AR5K_REG_READ(AR5K_AR5210_GPIODI) &
01686 AR5K_AR5210_GPIOD_MASK) >> gpio) & 0x1);
01687 }
01688
01689 HAL_BOOL
01690 ar5k_ar5210_set_gpio(hal, gpio, val)
01691 struct ath_hal *hal;
01692 u_int32_t gpio;
01693 u_int32_t val;
01694 {
01695 u_int32_t data;
01696
01697 if (gpio > AR5K_AR5210_NUM_GPIO)
01698 return (0xffffffff);
01699
01700
01701 data = AR5K_REG_READ(AR5K_AR5210_GPIODO);
01702
01703 data &= ~(1 << gpio);
01704 data |= (val&1) << gpio;
01705
01706 AR5K_REG_WRITE(AR5K_AR5210_GPIODO, data);
01707
01708 return (AH_TRUE);
01709 }
01710
01711 void
01712 ar5k_ar5210_set_gpio_intr(hal, gpio, interrupt_level)
01713 struct ath_hal *hal;
01714 u_int gpio;
01715 u_int32_t interrupt_level;
01716 {
01717 u_int32_t data;
01718
01719 if (gpio > AR5K_AR5210_NUM_GPIO)
01720 return;
01721
01722
01723
01724
01725 data = (AR5K_REG_READ(AR5K_AR5210_GPIOCR) &
01726 ~(AR5K_AR5210_GPIOCR_INT_SEL(gpio) | AR5K_AR5210_GPIOCR_INT_SELH |
01727 AR5K_AR5210_GPIOCR_INT_ENA | AR5K_AR5210_GPIOCR_ALL(gpio))) |
01728 (AR5K_AR5210_GPIOCR_INT_SEL(gpio) | AR5K_AR5210_GPIOCR_INT_ENA);
01729
01730 AR5K_REG_WRITE(AR5K_AR5210_GPIOCR,
01731 interrupt_level ? data : (data | AR5K_AR5210_GPIOCR_INT_SELH));
01732
01733 hal->ah_imr |= AR5K_AR5210_IMR_GPIO;
01734
01735
01736 AR5K_REG_ENABLE_BITS(AR5K_AR5210_IMR, AR5K_AR5210_IMR_GPIO);
01737 }
01738
01739 u_int32_t
01740 ar5k_ar5210_get_tsf32(hal)
01741 struct ath_hal *hal;
01742 {
01743 return (AR5K_REG_READ(AR5K_AR5210_TSF_L32));
01744 }
01745
01746 u_int64_t
01747 ar5k_ar5210_get_tsf64(hal)
01748 struct ath_hal *hal;
01749 {
01750 u_int64_t tsf = AR5K_REG_READ(AR5K_AR5210_TSF_U32);
01751 return (AR5K_REG_READ(AR5K_AR5210_TSF_L32) | (tsf << 32));
01752 }
01753
01754 void
01755 ar5k_ar5210_reset_tsf(hal)
01756 struct ath_hal *hal;
01757 {
01758 AR5K_REG_ENABLE_BITS(AR5K_AR5210_BEACON,
01759 AR5K_AR5210_BEACON_RESET_TSF);
01760 }
01761
01762 u_int16_t
01763 ar5k_ar5210_get_regdomain(hal)
01764 struct ath_hal *hal;
01765 {
01766 return (ar5k_get_regdomain(hal));
01767 }
01768
01769 HAL_BOOL
01770 ar5k_ar5210_detect_card_present(hal)
01771 struct ath_hal *hal;
01772 {
01773 u_int16_t magic;
01774
01775
01776
01777
01778
01779
01780 if (ar5k_ar5210_eeprom_read(hal, AR5K_EEPROM_MAGIC, &magic) != 0)
01781 return (AH_FALSE);
01782
01783 return (magic == AR5K_EEPROM_MAGIC_VALUE ? AH_TRUE : AH_FALSE);
01784 }
01785
01786 void
01787 ar5k_ar5210_update_mib_counters(hal, statistics)
01788 struct ath_hal *hal;
01789 HAL_MIB_STATS *statistics;
01790 {
01791 statistics->ackrcv_bad += AR5K_REG_READ(AR5K_AR5210_ACK_FAIL);
01792 statistics->rts_bad += AR5K_REG_READ(AR5K_AR5210_RTS_FAIL);
01793 statistics->rts_good += AR5K_REG_READ(AR5K_AR5210_RTS_OK);
01794 statistics->fcs_bad += AR5K_REG_READ(AR5K_AR5210_FCS_FAIL);
01795 statistics->beacons += AR5K_REG_READ(AR5K_AR5210_BEACON_CNT);
01796 }
01797
01798 HAL_RFGAIN
01799 ar5k_ar5210_get_rf_gain(hal)
01800 struct ath_hal *hal;
01801 {
01802 return (HAL_RFGAIN_INACTIVE);
01803 }
01804
01805 HAL_BOOL
01806 ar5k_ar5210_set_slot_time(hal, slot_time)
01807 struct ath_hal *hal;
01808 u_int slot_time;
01809
01810 {
01811 if (slot_time < HAL_SLOT_TIME_9 || slot_time > HAL_SLOT_TIME_MAX)
01812 return (AH_FALSE);
01813
01814 AR5K_REG_WRITE(AR5K_AR5210_SLOT_TIME,
01815 ar5k_htoclock(slot_time, hal->ah_turbo));
01816
01817 return (AH_TRUE);
01818 }
01819
01820 u_int
01821 ar5k_ar5210_get_slot_time(hal)
01822 struct ath_hal *hal;
01823 {
01824 return (ar5k_clocktoh(AR5K_REG_READ(AR5K_AR5210_SLOT_TIME) &
01825 0xffff, hal->ah_turbo));
01826 }
01827
01828 HAL_BOOL
01829 ar5k_ar5210_set_ack_timeout(hal, timeout)
01830 struct ath_hal *hal;
01831 u_int timeout;
01832 {
01833 if (ar5k_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_AR5210_TIME_OUT_ACK),
01834 hal->ah_turbo) <= timeout)
01835 return (AH_FALSE);
01836
01837 AR5K_REG_WRITE_BITS(AR5K_AR5210_TIME_OUT, AR5K_AR5210_TIME_OUT_ACK,
01838 ar5k_htoclock(timeout, hal->ah_turbo));
01839
01840 return (AH_TRUE);
01841 }
01842
01843 u_int
01844 ar5k_ar5210_get_ack_timeout(hal)
01845 struct ath_hal *hal;
01846 {
01847 return (ar5k_clocktoh(AR5K_REG_MS(AR5K_REG_READ(AR5K_AR5210_TIME_OUT),
01848 AR5K_AR5210_TIME_OUT_ACK), hal->ah_turbo));
01849 }
01850
01851 HAL_BOOL
01852 ar5k_ar5210_set_cts_timeout(hal, timeout)
01853 struct ath_hal *hal;
01854 u_int timeout;
01855 {
01856 if (ar5k_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_AR5210_TIME_OUT_CTS),
01857 hal->ah_turbo) <= timeout)
01858 return (AH_FALSE);
01859
01860 AR5K_REG_WRITE_BITS(AR5K_AR5210_TIME_OUT, AR5K_AR5210_TIME_OUT_CTS,
01861 ar5k_htoclock(timeout, hal->ah_turbo));
01862
01863 return (AH_TRUE);
01864 }
01865
01866 u_int
01867 ar5k_ar5210_get_cts_timeout(hal)
01868 struct ath_hal *hal;
01869 {
01870 return (ar5k_clocktoh(AR5K_REG_MS(AR5K_REG_READ(AR5K_AR5210_TIME_OUT),
01871 AR5K_AR5210_TIME_OUT_CTS), hal->ah_turbo));
01872 }
01873
01874
01875
01876
01877
01878 HAL_BOOL
01879 ar5k_ar5210_is_cipher_supported(hal, cipher)
01880 struct ath_hal *hal;
01881 HAL_CIPHER cipher;
01882 {
01883
01884
01885
01886 if (cipher == HAL_CIPHER_WEP)
01887 return (AH_TRUE);
01888
01889 return (AH_FALSE);
01890 }
01891
01892 u_int32_t
01893 ar5k_ar5210_get_keycache_size(hal)
01894 struct ath_hal *hal;
01895 {
01896 return (AR5K_AR5210_KEYCACHE_SIZE);
01897 }
01898
01899 HAL_BOOL
01900 ar5k_ar5210_reset_key(hal, entry)
01901 struct ath_hal *hal;
01902 u_int16_t entry;
01903 {
01904 int i;
01905
01906 AR5K_ASSERT_ENTRY(entry, AR5K_AR5210_KEYTABLE_SIZE);
01907
01908 for (i = 0; i < AR5K_AR5210_KEYCACHE_SIZE; i++)
01909 AR5K_REG_WRITE(AR5K_AR5210_KEYTABLE_OFF(entry, i), 0);
01910
01911 return (AH_FALSE);
01912 }
01913
01914 HAL_BOOL
01915 ar5k_ar5210_is_key_valid(hal, entry)
01916 struct ath_hal *hal;
01917 u_int16_t entry;
01918 {
01919 AR5K_ASSERT_ENTRY(entry, AR5K_AR5210_KEYTABLE_SIZE);
01920
01921
01922
01923
01924 if (AR5K_REG_READ(AR5K_AR5210_KEYTABLE_MAC1(entry)) &
01925 AR5K_AR5210_KEYTABLE_VALID)
01926 return (AH_TRUE);
01927
01928 return (AH_FALSE);
01929 }
01930
01931 HAL_BOOL
01932 ar5k_ar5210_set_key(hal, entry, keyval, mac, xor_notused)
01933 struct ath_hal *hal;
01934 u_int16_t entry;
01935 const HAL_KEYVAL *keyval;
01936 const u_int8_t *mac;
01937 int xor_notused;
01938 {
01939 int i;
01940 u_int32_t key_v[AR5K_AR5210_KEYCACHE_SIZE - 2];
01941
01942 AR5K_ASSERT_ENTRY(entry, AR5K_AR5210_KEYTABLE_SIZE);
01943
01944 bzero(&key_v, sizeof(key_v));
01945
01946 switch (keyval->wk_len) {
01947 case AR5K_KEYVAL_LENGTH_40:
01948 bcopy(keyval->wk_key, &key_v[0], 4);
01949 bcopy(keyval->wk_key + 4, &key_v[1], 1);
01950 key_v[5] = AR5K_AR5210_KEYTABLE_TYPE_40;
01951 break;
01952
01953 case AR5K_KEYVAL_LENGTH_104:
01954 bcopy(keyval->wk_key, &key_v[0], 4);
01955 bcopy(keyval->wk_key + 4, &key_v[1], 2);
01956 bcopy(keyval->wk_key + 6, &key_v[2], 4);
01957 bcopy(keyval->wk_key + 10, &key_v[3], 2);
01958 bcopy(keyval->wk_key + 12, &key_v[4], 1);
01959 key_v[5] = AR5K_AR5210_KEYTABLE_TYPE_104;
01960 break;
01961
01962 case AR5K_KEYVAL_LENGTH_128:
01963 bcopy(keyval->wk_key, &key_v[0], 4);
01964 bcopy(keyval->wk_key + 4, &key_v[1], 2);
01965 bcopy(keyval->wk_key + 6, &key_v[2], 4);
01966 bcopy(keyval->wk_key + 10, &key_v[3], 2);
01967 bcopy(keyval->wk_key + 12, &key_v[4], 4);
01968 key_v[5] = AR5K_AR5210_KEYTABLE_TYPE_128;
01969 break;
01970
01971 default:
01972
01973 return (AH_FALSE);
01974 }
01975
01976 for (i = 0; i < AR5K_ELEMENTS(key_v); i++)
01977 AR5K_REG_WRITE(AR5K_AR5210_KEYTABLE_OFF(entry, i), key_v[i]);
01978
01979 return (ar5k_ar5210_set_key_lladdr(hal, entry, mac));
01980 }
01981
01982 HAL_BOOL
01983 ar5k_ar5210_set_key_lladdr(hal, entry, mac)
01984 struct ath_hal *hal;
01985 u_int16_t entry;
01986 const u_int8_t *mac;
01987 {
01988 u_int32_t low_id, high_id;
01989 const u_int8_t *mac_v;
01990
01991
01992
01993
01994 AR5K_ASSERT_ENTRY(entry, AR5K_AR5210_KEYTABLE_SIZE);
01995
01996
01997 mac_v = mac == NULL ? etherbroadcastaddr : mac;
01998
01999 bcopy(mac_v, &low_id, 4);
02000 bcopy(mac_v + 4, &high_id, 2);
02001 high_id |= AR5K_AR5210_KEYTABLE_VALID;
02002
02003 AR5K_REG_WRITE(AR5K_AR5210_KEYTABLE_MAC0(entry), low_id);
02004 AR5K_REG_WRITE(AR5K_AR5210_KEYTABLE_MAC1(entry), high_id);
02005
02006 return (AH_TRUE);
02007 }
02008
02009
02010
02011
02012
02013 HAL_BOOL
02014 ar5k_ar5210_set_power(hal, mode, set_chip, sleep_duration)
02015 struct ath_hal *hal;
02016 HAL_POWER_MODE mode;
02017 HAL_BOOL set_chip;
02018 u_int16_t sleep_duration;
02019 {
02020 u_int32_t staid;
02021 int i;
02022
02023 staid = AR5K_REG_READ(AR5K_AR5210_STA_ID1);
02024
02025 switch (mode) {
02026 case HAL_PM_AUTO:
02027 staid &= ~AR5K_AR5210_STA_ID1_DEFAULT_ANTENNA;
02028
02029 case HAL_PM_NETWORK_SLEEP:
02030 if (set_chip == AH_TRUE) {
02031 AR5K_REG_WRITE(AR5K_AR5210_SCR,
02032 AR5K_AR5210_SCR_SLE | sleep_duration);
02033 }
02034 staid |= AR5K_AR5210_STA_ID1_PWR_SV;
02035 break;
02036
02037 case HAL_PM_FULL_SLEEP:
02038 if (set_chip == AH_TRUE) {
02039 AR5K_REG_WRITE(AR5K_AR5210_SCR,
02040 AR5K_AR5210_SCR_SLE_SLP);
02041 }
02042 staid |= AR5K_AR5210_STA_ID1_PWR_SV;
02043 break;
02044
02045 case HAL_PM_AWAKE:
02046 if (set_chip == AH_FALSE)
02047 goto commit;
02048
02049 AR5K_REG_WRITE(AR5K_AR5210_SCR, AR5K_AR5210_SCR_SLE_WAKE);
02050
02051 for (i = 5000; i > 0; i--) {
02052
02053 if ((AR5K_REG_READ(AR5K_AR5210_PCICFG) &
02054 AR5K_AR5210_PCICFG_SPWR_DN) == 0)
02055 break;
02056
02057
02058 AR5K_DELAY(200);
02059 AR5K_REG_WRITE(AR5K_AR5210_SCR,
02060 AR5K_AR5210_SCR_SLE_WAKE);
02061 }
02062
02063
02064 if (i <= 0)
02065 return (AH_FALSE);
02066
02067 staid &= ~AR5K_AR5210_STA_ID1_PWR_SV;
02068 break;
02069
02070 default:
02071 return (AH_FALSE);
02072 }
02073
02074 commit:
02075 hal->ah_power_mode = mode;
02076
02077 AR5K_REG_WRITE(AR5K_AR5210_STA_ID1, staid);
02078
02079 return (AH_TRUE);
02080 }
02081
02082 HAL_POWER_MODE
02083 ar5k_ar5210_get_power_mode(hal)
02084 struct ath_hal *hal;
02085 {
02086 return (hal->ah_power_mode);
02087 }
02088
02089 HAL_BOOL
02090 ar5k_ar5210_query_pspoll_support(hal)
02091 struct ath_hal *hal;
02092 {
02093
02094 return (AH_TRUE);
02095 }
02096
02097 HAL_BOOL
02098 ar5k_ar5210_init_pspoll(hal)
02099 struct ath_hal *hal;
02100 {
02101
02102
02103
02104 return (AH_FALSE);
02105 }
02106
02107 HAL_BOOL
02108 ar5k_ar5210_enable_pspoll(hal, bssid, assoc_id)
02109 struct ath_hal *hal;
02110 u_int8_t *bssid;
02111 u_int16_t assoc_id;
02112 {
02113 AR5K_REG_DISABLE_BITS(AR5K_AR5210_STA_ID1,
02114 AR5K_AR5210_STA_ID1_NO_PSPOLL |
02115 AR5K_AR5210_STA_ID1_DEFAULT_ANTENNA);
02116
02117 return (AH_TRUE);
02118 }
02119
02120 HAL_BOOL
02121 ar5k_ar5210_disable_pspoll(hal)
02122 struct ath_hal *hal;
02123 {
02124 AR5K_REG_ENABLE_BITS(AR5K_AR5210_STA_ID1,
02125 AR5K_AR5210_STA_ID1_NO_PSPOLL |
02126 AR5K_AR5210_STA_ID1_DEFAULT_ANTENNA);
02127
02128 return (AH_TRUE);
02129 }
02130
02131
02132
02133
02134
02135 void
02136 ar5k_ar5210_init_beacon(hal, next_beacon, interval)
02137 struct ath_hal *hal;
02138 u_int32_t next_beacon;
02139 u_int32_t interval;
02140 {
02141 u_int32_t timer1, timer2, timer3;
02142
02143
02144
02145
02146 switch (hal->ah_op_mode) {
02147 case HAL_M_STA:
02148 timer1 = 0xffffffff;
02149 timer2 = 0xffffffff;
02150 timer3 = 1;
02151 break;
02152
02153 default:
02154 timer1 = (next_beacon - AR5K_TUNE_DMA_BEACON_RESP) << 3;
02155 timer2 = (next_beacon - AR5K_TUNE_SW_BEACON_RESP) << 3;
02156 timer3 = next_beacon + hal->ah_atim_window;
02157 break;
02158 }
02159
02160
02161
02162
02163
02164 AR5K_REG_WRITE(AR5K_AR5210_TIMER0, next_beacon);
02165 AR5K_REG_WRITE(AR5K_AR5210_TIMER1, timer1);
02166 AR5K_REG_WRITE(AR5K_AR5210_TIMER2, timer2);
02167 AR5K_REG_WRITE(AR5K_AR5210_TIMER3, timer3);
02168
02169 AR5K_REG_WRITE(AR5K_AR5210_BEACON, interval &
02170 (AR5K_AR5210_BEACON_PERIOD | AR5K_AR5210_BEACON_RESET_TSF |
02171 AR5K_AR5210_BEACON_EN));
02172 }
02173
02174 void
02175 ar5k_ar5210_set_beacon_timers(hal, state, tsf, dtim_count, cfp_count)
02176 struct ath_hal *hal;
02177 const HAL_BEACON_STATE *state;
02178 u_int32_t tsf;
02179 u_int32_t dtim_count;
02180 u_int32_t cfp_count;
02181
02182 {
02183 u_int32_t cfp_period, next_cfp;
02184
02185
02186 if (state->bs_interval < 1)
02187 return;
02188
02189
02190
02191
02192 if (state->bs_cfp_period > 0) {
02193
02194 cfp_period = state->bs_cfp_period * state->bs_dtim_period *
02195 state->bs_interval;
02196 next_cfp = (cfp_count * state->bs_dtim_period + dtim_count) *
02197 state->bs_interval;
02198
02199 AR5K_REG_DISABLE_BITS(AR5K_AR5210_STA_ID1,
02200 AR5K_AR5210_STA_ID1_DEFAULT_ANTENNA |
02201 AR5K_AR5210_STA_ID1_PCF);
02202 AR5K_REG_WRITE(AR5K_AR5210_CFP_PERIOD, cfp_period);
02203 AR5K_REG_WRITE(AR5K_AR5210_CFP_DUR, state->bs_cfp_max_duration);
02204 AR5K_REG_WRITE(AR5K_AR5210_TIMER2,
02205 (tsf + (next_cfp == 0 ? cfp_period : next_cfp)) << 3);
02206 } else {
02207
02208 AR5K_REG_DISABLE_BITS(AR5K_AR5210_STA_ID1,
02209 AR5K_AR5210_STA_ID1_DEFAULT_ANTENNA |
02210 AR5K_AR5210_STA_ID1_PCF);
02211 }
02212
02213
02214
02215
02216 AR5K_REG_WRITE(AR5K_AR5210_TIMER0, state->bs_next_beacon);
02217
02218
02219
02220
02221 AR5K_REG_WRITE(AR5K_AR5210_BEACON,
02222 (AR5K_REG_READ(AR5K_AR5210_BEACON) &~
02223 (AR5K_AR5210_BEACON_PERIOD | AR5K_AR5210_BEACON_TIM)) |
02224 AR5K_REG_SM(state->bs_tim_offset ? state->bs_tim_offset + 4 : 0,
02225 AR5K_AR5210_BEACON_TIM) |
02226 AR5K_REG_SM(state->bs_interval, AR5K_AR5210_BEACON_PERIOD));
02227
02228
02229
02230
02231 if (state->bs_bmiss_threshold <=
02232 (AR5K_AR5210_RSSI_THR_BM_THR >> AR5K_AR5210_RSSI_THR_BM_THR_S)) {
02233 AR5K_REG_WRITE_BITS(AR5K_AR5210_RSSI_THR,
02234 AR5K_AR5210_RSSI_THR_BM_THR, state->bs_bmiss_threshold);
02235 }
02236 }
02237
02238 void
02239 ar5k_ar5210_reset_beacon(hal)
02240 struct ath_hal *hal;
02241 {
02242
02243
02244
02245 AR5K_REG_WRITE(AR5K_AR5210_TIMER0, 0);
02246
02247
02248
02249
02250 AR5K_REG_DISABLE_BITS(AR5K_AR5210_STA_ID1,
02251 AR5K_AR5210_STA_ID1_DEFAULT_ANTENNA | AR5K_AR5210_STA_ID1_PCF);
02252 AR5K_REG_WRITE(AR5K_AR5210_BEACON, AR5K_AR5210_BEACON_PERIOD);
02253 }
02254
02255 HAL_BOOL
02256 ar5k_ar5210_wait_for_beacon(hal, phys_addr)
02257 struct ath_hal *hal;
02258 bus_addr_t phys_addr;
02259 {
02260 int i;
02261
02262
02263
02264
02265 for (i = (AR5K_TUNE_BEACON_INTERVAL / 2); i > 0 &&
02266 (AR5K_REG_READ(AR5K_AR5210_BSR) &
02267 AR5K_AR5210_BSR_TXQ1F) != 0 &&
02268 (AR5K_REG_READ(AR5K_AR5210_CR) &
02269 AR5K_AR5210_CR_TXE1) != 0; i--);
02270
02271
02272 if (i <= 0) {
02273
02274
02275
02276 AR5K_REG_WRITE(AR5K_AR5210_TXDP1, (u_int32_t)phys_addr);
02277 AR5K_REG_WRITE(AR5K_AR5210_BCR,
02278 AR5K_AR5210_BCR_TQ1V | AR5K_AR5210_BCR_BDMAE);
02279
02280 return (AH_FALSE);
02281 }
02282
02283 return (AH_TRUE);
02284 }
02285
02286
02287
02288
02289
02290 HAL_BOOL
02291 ar5k_ar5210_is_intr_pending(hal)
02292 struct ath_hal *hal;
02293 {
02294 return (AR5K_REG_READ(AR5K_AR5210_INTPEND) == 0 ? AH_FALSE : AH_TRUE);
02295 }
02296
02297 HAL_BOOL
02298 ar5k_ar5210_get_isr(hal, interrupt_mask)
02299 struct ath_hal *hal;
02300 u_int32_t *interrupt_mask;
02301 {
02302 u_int32_t data;
02303
02304 if ((data = AR5K_REG_READ(AR5K_AR5210_ISR)) == HAL_INT_NOCARD) {
02305 *interrupt_mask = data;
02306 return (AH_FALSE);
02307 }
02308
02309
02310
02311
02312 *interrupt_mask = (data & HAL_INT_COMMON) & hal->ah_imr;
02313
02314 if (data & (AR5K_AR5210_ISR_RXOK | AR5K_AR5210_ISR_RXERR))
02315 *interrupt_mask |= HAL_INT_RX;
02316 if (data & (AR5K_AR5210_ISR_TXOK | AR5K_AR5210_ISR_TXERR))
02317 *interrupt_mask |= HAL_INT_TX;
02318 if (data & AR5K_AR5210_ISR_FATAL)
02319 *interrupt_mask |= HAL_INT_FATAL;
02320
02321
02322
02323
02324 if (((*interrupt_mask) & AR5K_AR5210_ISR_RXPHY) &&
02325 hal->ah_radar.r_enabled == AH_TRUE)
02326 ar5k_radar_alert(hal);
02327
02328
02329 *interrupt_mask &= ~HAL_INT_BMISS;
02330
02331 return (AH_TRUE);
02332 }
02333
02334 u_int32_t
02335 ar5k_ar5210_get_intr(hal)
02336 struct ath_hal *hal;
02337 {
02338
02339 return (hal->ah_imr);
02340 }
02341
02342 HAL_INT
02343 ar5k_ar5210_set_intr(hal, new_mask)
02344 struct ath_hal *hal;
02345 HAL_INT new_mask;
02346 {
02347 HAL_INT old_mask, int_mask;
02348
02349
02350
02351
02352
02353 AR5K_REG_WRITE(AR5K_AR5210_IER, AR5K_AR5210_IER_DISABLE);
02354
02355 old_mask = hal->ah_imr;
02356
02357
02358
02359
02360
02361 int_mask = new_mask & HAL_INT_COMMON;
02362
02363 if (new_mask & HAL_INT_RX)
02364 int_mask |=
02365 AR5K_AR5210_IMR_RXOK |
02366 AR5K_AR5210_IMR_RXERR |
02367 AR5K_AR5210_IMR_RXORN;
02368
02369 if (new_mask & HAL_INT_TX)
02370 int_mask |=
02371 AR5K_AR5210_IMR_TXOK |
02372 AR5K_AR5210_IMR_TXERR |
02373 AR5K_AR5210_IMR_TXURN;
02374
02375 AR5K_REG_WRITE(AR5K_AR5210_IMR, int_mask);
02376
02377
02378 hal->ah_imr = new_mask;
02379
02380
02381 if (int_mask) {
02382 AR5K_REG_WRITE(AR5K_AR5210_IER, AR5K_AR5210_IER_ENABLE);
02383 }
02384
02385 return (old_mask);
02386 }
02387
02388
02389
02390
02391
02392 HAL_BOOL
02393 ar5k_ar5210_get_capabilities(hal)
02394 struct ath_hal *hal;
02395 {
02396
02397 hal->ah_capabilities.cap_queues.q_tx_num = AR5K_AR5210_TX_NUM_QUEUES;
02398
02399
02400
02401
02402
02403 hal->ah_capabilities.cap_range.range_5ghz_min = 5120;
02404 hal->ah_capabilities.cap_range.range_5ghz_max = 5430;
02405 hal->ah_capabilities.cap_range.range_2ghz_min = 0;
02406 hal->ah_capabilities.cap_range.range_2ghz_max = 0;
02407
02408
02409 hal->ah_capabilities.cap_mode = HAL_MODE_11A | HAL_MODE_TURBO;
02410
02411
02412 hal->ah_gpio_npins = AR5K_AR5210_NUM_GPIO;
02413
02414 return (AH_TRUE);
02415 }
02416
02417 void
02418 ar5k_ar5210_radar_alert(hal, enable)
02419 struct ath_hal *hal;
02420 HAL_BOOL enable;
02421 {
02422
02423
02424
02425
02426 AR5K_REG_WRITE(AR5K_AR5210_IER, AR5K_AR5210_IER_DISABLE);
02427
02428 if (enable == AH_TRUE) {
02429 AR5K_REG_ENABLE_BITS(AR5K_AR5210_IMR,
02430 AR5K_AR5210_IMR_RXPHY);
02431 } else {
02432 AR5K_REG_DISABLE_BITS(AR5K_AR5210_IMR,
02433 AR5K_AR5210_IMR_RXPHY);
02434 }
02435
02436 AR5K_REG_WRITE(AR5K_AR5210_IER, AR5K_AR5210_IER_ENABLE);
02437 }
02438
02439
02440
02441
02442
02443 HAL_BOOL
02444 ar5k_ar5210_eeprom_is_busy(hal)
02445 struct ath_hal *hal;
02446 {
02447 return (AR5K_REG_READ(AR5K_AR5210_CFG) & AR5K_AR5210_CFG_EEBS ?
02448 AH_TRUE : AH_FALSE);
02449 }
02450
02451 int
02452 ar5k_ar5210_eeprom_read(hal, offset, data)
02453 struct ath_hal *hal;
02454 u_int32_t offset;
02455 u_int16_t *data;
02456 {
02457 u_int32_t status, timeout;
02458
02459
02460 AR5K_REG_ENABLE_BITS(AR5K_AR5210_PCICFG, AR5K_AR5210_PCICFG_EEAE);
02461
02462
02463
02464
02465 (void)AR5K_REG_READ(AR5K_AR5210_EEPROM_BASE + (4 * offset));
02466
02467 for (timeout = 10000; timeout > 0; timeout--) {
02468 AR5K_DELAY(1);
02469 status = AR5K_REG_READ(AR5K_AR5210_EEPROM_STATUS);
02470 if (status & AR5K_AR5210_EEPROM_STAT_RDDONE) {
02471 if (status & AR5K_AR5210_EEPROM_STAT_RDERR)
02472 return (EIO);
02473 *data = (u_int16_t)
02474 (AR5K_REG_READ(AR5K_AR5210_EEPROM_RDATA) & 0xffff);
02475 return (0);
02476 }
02477 }
02478
02479 return (ETIMEDOUT);
02480 }
02481
02482 int
02483 ar5k_ar5210_eeprom_write(hal, offset, data)
02484 struct ath_hal *hal;
02485 u_int32_t offset;
02486 u_int16_t data;
02487 {
02488 u_int32_t status, timeout;
02489
02490
02491 AR5K_REG_ENABLE_BITS(AR5K_AR5210_PCICFG, AR5K_AR5210_PCICFG_EEAE);
02492
02493
02494
02495
02496 AR5K_REG_WRITE(AR5K_AR5210_EEPROM_BASE + (4 * offset), data);
02497
02498 for (timeout = 10000; timeout > 0; timeout--) {
02499 AR5K_DELAY(1);
02500 status = AR5K_REG_READ(AR5K_AR5210_EEPROM_STATUS);
02501 if (status & AR5K_AR5210_EEPROM_STAT_WRDONE) {
02502 if (status & AR5K_AR5210_EEPROM_STAT_WRERR)
02503 return (EIO);
02504 return (0);
02505 }
02506 }
02507
02508 return (ETIMEDOUT);
02509 }
02510