LCOV - code coverage report
Current view: top level - dev/ic - ar5210.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 952 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 98 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13