Main Page | Data Structures | Directories | File List | Data Fields | Globals

ar5210.c

Go to the documentation of this file.
00001 /*     $OpenBSD: ar5210.c,v 1.27 2005/08/02 12:55:11 reyk Exp $        */
00002 
00003 /*
00004  * Copyright (c) 2004, 2005 Reyk Floeter <reyk@vantronix.net>
00005  *
00006  * Permission to use, copy, modify, and distribute this software for any
00007  * purpose with or without fee is hereby granted, provided that the above
00008  * copyright notice and this permission notice appear in all copies.
00009  *
00010  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
00011  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
00012  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
00013  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
00014  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
00015  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
00016  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
00017  */
00018 
00019 /*
00020  * HAL interface for the Atheros AR5000 Wireless LAN chipset
00021  * (AR5210 + AR5110).
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  * Initial register setting for the AR5210
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          * Init/Exit functions
00051          */
00052         AR5K_HAL_FUNCTION(hal, ar5210, get_rate_table);
00053         AR5K_HAL_FUNCTION(hal, ar5210, detach);
00054 
00055         /*
00056          * Reset functions
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          * TX functions
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          * RX functions
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          * Misc functions
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          * Key table (WEP) functions
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          * Power management functions
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          * Beacon functions
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          * Interrupt functions
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          * Chipset functions (ar5k-specific, non-HAL)
00165          */
00166         AR5K_HAL_FUNCTION(hal, ar5210, get_capabilities);
00167         AR5K_HAL_FUNCTION(hal, ar5210, radar_alert);
00168 
00169         /*
00170          * EEPROM access
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         /* Bring device out of sleep and reset it's units */
00193         if (ar5k_ar5210_nic_wakeup(hal, AH_FALSE, AH_TRUE) != AH_TRUE)
00194                 return (NULL);
00195 
00196         /* Get MAC, PHY and RADIO revisions */
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         /* ...wait until PHY is ready and read RADIO revision */
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         /* Identify the chipset */
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          * Reset the device and wait until success
00235          */
00236         AR5K_REG_WRITE(AR5K_AR5210_RC, val);
00237 
00238         /* Wait at least 128 PCI clocks */
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          * Reset configuration register
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          * Reset and wakeup the device
00269          */
00270 
00271         if (initial == AH_TRUE) {
00272                 /* ...reset hardware */
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         /* ...wakeup the device */
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         /* ...enable Atheros turbo mode if requested */
00290         AR5K_REG_WRITE(AR5K_AR5210_PHY_FC,
00291             turbo == AH_TRUE ? AR5K_AR5210_PHY_FC_TURBO_MODE : 0);
00292 
00293         /* ...reset chipset */
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         /* ...reset chipset and PCI device */
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         /* ...wakeup (again) */
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         /* ...final warm reset */
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          * Free HAL structure, assume interrupts are down
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         /* Not used, keep for HAL compatibility */
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          * Initialize operating mode
00375          */
00376         hal->ah_op_mode = op_mode;
00377         ar5k_ar5210_set_opmode(hal);
00378 
00379         /*
00380          * Write initial mode register settings
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                         /* Cleared on read */
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          * Set channel and calibrate the PHY
00405          */
00406 
00407         /* Disable phy and wait */
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          * Activate phy and wait
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          * Set RF kill flags if supported by the device (read from the EEPROM)
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          * Reset queues and start beacon timers at the end of the reset routine
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          * Set PCU and BCR registers
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          * Disable beacons and RX/TX queues, wait
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          * Set the channel (with AGC turned off)
00533          */
00534         AGC_DISABLE;
00535         ret = ar5k_channel(hal, channel);
00536 
00537         /*
00538          * Activate PHY and wait
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          * Calibrate the radio chip
00550          */
00551 
00552         /* Remember normal state */
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         /* Update radio registers */
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         /* Reset to normal state */
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          * Re-enable RX/TX and beacons
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          * Enable calibration and wait until completion
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          * Enable noise floor calibration and wait until completion
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         /* wait until the noise floor is calibrated */
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  * Transmit functions
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          * Disable interrupts by setting the mask
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          * Update trigger level on success
00699          */
00700         AR5K_REG_WRITE(AR5K_AR5210_TRIG_LVL, trigger_level);
00701         status = AH_TRUE;
00702 
00703  done:
00704         /*
00705          * Restore interrupt mask
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          * Get queue by type
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          * Setup internal queue structure
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         /* This queue will be skipped in further operations */
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          * Write initial mode register settings
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         /* Only handle data queues, others will be ignored */
00816         if (tq->tqi_type != HAL_TX_QUEUE_DATA)
00817                 return (AH_TRUE);
00818 
00819         /* Set turbo/base mode parameters */
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          * Set retry limits
00825          */
00826         if (hal->ah_software_retry == AH_TRUE) {
00827                 /* XXX Need to test this */
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          * Set initial content window (cw_min/cw_max)
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         /* Commit values */
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          * Get the transmit queue descriptor pointer register by type
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          * Get the transmit queue descriptor pointer register by type
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         /* Set descriptor pointer */
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          * Set the queue type
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         /* Start queue */
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          * Set by queue type
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                 /* XXX Fix me... */
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         /* Stop queue */
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          * Validate input
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          * WEP crap
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          * RTS/CTS
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         /* Clear status descriptor */
01090         bzero(desc->ds_hw, sizeof(desc->ds_hw));
01091 
01092         /* Validate segment length and initialize the descriptor */
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          * Does this function is for setting up XR? Not sure...
01120          * Nevertheless, I didn't find any information about XR support
01121          * by the AR5210. This seems to be a slightly new feature.
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         /* No frame has been send or error */
01138         if ((tx_status->tx_status_1 & AR5K_AR5210_DESC_TX_STATUS1_DONE) == 0)
01139                 return (HAL_EINPROGRESS);
01140 
01141         /*
01142          * Get descriptor status
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  * Receive functions
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          * It may take some time to disable the DMA receive unit
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         /* Set the multicat filter */
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          * The AR5210 uses promiscous mode to detect radar activity
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         /* No frame received / not ready */
01352         if ((rx_status->rx_status_1 & AR5K_AR5210_DESC_RX_STATUS1_DONE) == 0)
01353                 return (HAL_EINPROGRESS);
01354 
01355         /*
01356          * Frame receive status
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          * Key table status
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          * Receive/descriptor errors
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         /* Signal state monitoring is not yet supported */
01421 }
01422 
01423 /*
01424  * Misc functions
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          * We'll ignore this right now. This seems to be some kind of an obscure
01528          * debugging interface for the binary-only HAL.
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         /* Set new station ID */
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          * Some blinking values, define at your wish
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          * Set BSSID which triggers the "SME Join" operation
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         /* GPIO input magic */
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         /* GPIO output magic */
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          * Set the GPIO interrupt
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         /* Enable GPIO interrupts */
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          * Checking the EEPROM's magic value could be an indication
01777          * if the card is still present. I didn't find another suitable
01778          * way to do this.
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  * Key table (WEP) functions
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          * The AR5210 only supports WEP
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          * Check the validation flag at the end of the entry
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                 /* Unsupported key length (not WEP40/104/128) */
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          * Invalid entry (key table overflow)
01993          */
01994         AR5K_ASSERT_ENTRY(entry, AR5K_AR5210_KEYTABLE_SIZE);
01995 
01996         /* MAC may be NULL if it's a broadcast key */
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  * Power management functions
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                 /* fallthrough */
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                         /* Check if the AR5210 did wake up */
02053                         if ((AR5K_REG_READ(AR5K_AR5210_PCICFG) &
02054                             AR5K_AR5210_PCICFG_SPWR_DN) == 0)
02055                                 break;
02056 
02057                         /* Wait a bit and retry */
02058                         AR5K_DELAY(200);
02059                         AR5K_REG_WRITE(AR5K_AR5210_SCR,
02060                             AR5K_AR5210_SCR_SLE_WAKE);
02061                 }
02062 
02063                 /* Fail if the AR5210 didn't wake up */
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         /* I think so, why not? */
02094         return (AH_TRUE);
02095 }
02096 
02097 HAL_BOOL
02098 ar5k_ar5210_init_pspoll(hal)
02099         struct ath_hal *hal;
02100 {
02101         /*
02102          * Not used on the AR5210
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  * Beacon functions
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          * Set the additional timers by mode
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          * Enable all timers and set the beacon register
02162          * (next beacon, DMA beacon, software beacon, ATIM window time)
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         /* Return on an invalid beacon state */
02186         if (state->bs_interval < 1)
02187                 return;
02188 
02189         /*
02190          * PCF support?
02191          */
02192         if (state->bs_cfp_period > 0) {
02193                 /* Enable CFP mode and set the CFP and timer registers */
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                 /* Disable PCF mode */
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          * Enable the beacon timer register
02215          */
02216         AR5K_REG_WRITE(AR5K_AR5210_TIMER0, state->bs_next_beacon);
02217 
02218         /*
02219          * Start the beacon timers
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          * Write new beacon miss threshold, if it appears to be valid
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          * Disable beacon timer
02244          */
02245         AR5K_REG_WRITE(AR5K_AR5210_TIMER0, 0);
02246 
02247         /*
02248          * Disable some beacon register values
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          * Wait for beaconn queue to be done
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         /* Timeout... */
02272         if (i <= 0) {
02273                 /*
02274                  * Re-schedule the beacon queue
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  * Interrupt handling
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          * Get abstract interrupt mask (HAL-compatible)
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          * Special interrupt handling (not catched by the driver)
02323          */
02324         if (((*interrupt_mask) & AR5K_AR5210_ISR_RXPHY) &&
02325             hal->ah_radar.r_enabled == AH_TRUE)
02326                 ar5k_radar_alert(hal);
02327 
02328         /* XXX BMISS interrupts may occur after association */
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         /* Return the interrupt mask stored previously */
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          * Disable card interrupts to prevent any race conditions
02351          * (they will be re-enabled afterwards).
02352          */
02353         AR5K_REG_WRITE(AR5K_AR5210_IER, AR5K_AR5210_IER_DISABLE);
02354 
02355         old_mask = hal->ah_imr;
02356 
02357         /*
02358          * Add additional, chipset-dependent interrupt mask flags
02359          * and write them to the IMR (interrupt mask register).
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         /* Store new interrupt mask */
02378         hal->ah_imr = new_mask;
02379 
02380         /* ..re-enable interrupts */
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  * Misc internal functions
02390  */
02391 
02392 HAL_BOOL
02393 ar5k_ar5210_get_capabilities(hal)
02394         struct ath_hal *hal;
02395 {
02396         /* Set number of supported TX queues */
02397         hal->ah_capabilities.cap_queues.q_tx_num = AR5K_AR5210_TX_NUM_QUEUES;
02398 
02399         /*
02400          * Set radio capabilities
02401          * (The AR5210 only supports the middle 5GHz band)
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         /* Set supported modes */
02409         hal->ah_capabilities.cap_mode = HAL_MODE_11A | HAL_MODE_TURBO;
02410 
02411         /* Set number of GPIO pins */
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          * Set the RXPHY interrupt to be able to detect
02424          * possible radar activity.
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  * EEPROM access functions
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         /* Enable eeprom access */
02460         AR5K_REG_ENABLE_BITS(AR5K_AR5210_PCICFG, AR5K_AR5210_PCICFG_EEAE);
02461 
02462         /*
02463          * Prime read pump
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         /* Enable eeprom access */
02491         AR5K_REG_ENABLE_BITS(AR5K_AR5210_PCICFG, AR5K_AR5210_PCICFG_EEAE);
02492 
02493         /*
02494          * Prime write pump
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 

Generated on Mon Nov 21 15:58:10 2005 for openwifi by  doxygen 1.4.1