LCOV - code coverage report
Current view: top level - dev/ic - ar5212.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 1248 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: ar5212.c,v 1.59 2018/02/03 17:17:31 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 AR5001 Wireless LAN chipset
      21             :  * (AR5212 + AR5111/AR5112).
      22             :  */
      23             : 
      24             : #include <dev/ic/ar5xxx.h>
      25             : #include <dev/ic/ar5212reg.h>
      26             : #include <dev/ic/ar5212var.h>
      27             : 
      28             : HAL_BOOL         ar5k_ar5212_nic_reset(struct ath_hal *, u_int32_t);
      29             : HAL_BOOL         ar5k_ar5212_nic_wakeup(struct ath_hal *, u_int16_t);
      30             : u_int16_t        ar5k_ar5212_radio_revision(struct ath_hal *, HAL_CHIP);
      31             : void             ar5k_ar5212_fill(struct ath_hal *);
      32             : HAL_BOOL         ar5k_ar5212_txpower(struct ath_hal *, HAL_CHANNEL *, u_int);
      33             : HAL_BOOL         ar5k_ar5212_warm_reset(struct ath_hal *);
      34             : 
      35             : /*
      36             :  * Initial register setting for the AR5212
      37             :  */
      38             : static const struct ar5k_ini ar5212_ini[] = AR5K_AR5212_INI;
      39             : static const struct ar5k_mode ar5212_mode[] = AR5K_AR5212_MODE;
      40             : static const struct ar5k_mode ar5212_ar5111_mode[] = AR5K_AR5212_AR5111_MODE;
      41             : static const struct ar5k_mode ar5212_ar5112_mode[] = AR5K_AR5212_AR5112_MODE;
      42             : static const struct ar5k_mode ar5413_mode[] = AR5K_AR5413_MODE;
      43             : static const struct ar5k_mode ar2413_mode[] = AR5K_AR2413_MODE;
      44             : static const struct ar5k_mode ar2425_mode[] = AR5K_AR2425_MODE;
      45             : static const struct ar5k_ini ar5111_bbgain[] = AR5K_AR5111_INI_BBGAIN;
      46             : static const struct ar5k_ini ar5112_bbgain[] = AR5K_AR5112_INI_BBGAIN;
      47             : static const struct ar5k_ini ar5212_pcie[] = AR5K_AR5212_PCIE;
      48             : 
      49             : AR5K_HAL_FUNCTIONS(extern, ar5k_ar5212,);
      50             : 
      51             : void
      52           0 : ar5k_ar5212_fill(struct ath_hal *hal)
      53             : {
      54           0 :         hal->ah_magic = AR5K_AR5212_MAGIC;
      55             : 
      56             :         /*
      57             :          * Init/Exit functions
      58             :          */
      59           0 :         AR5K_HAL_FUNCTION(hal, ar5212, get_rate_table);
      60           0 :         AR5K_HAL_FUNCTION(hal, ar5212, detach);
      61             : 
      62             :         /*
      63             :          * Reset functions
      64             :          */
      65           0 :         AR5K_HAL_FUNCTION(hal, ar5212, reset);
      66           0 :         AR5K_HAL_FUNCTION(hal, ar5212, set_opmode);
      67           0 :         AR5K_HAL_FUNCTION(hal, ar5212, calibrate);
      68             : 
      69             :         /*
      70             :          * TX functions
      71             :          */
      72           0 :         AR5K_HAL_FUNCTION(hal, ar5212, update_tx_triglevel);
      73           0 :         AR5K_HAL_FUNCTION(hal, ar5212, setup_tx_queue);
      74           0 :         AR5K_HAL_FUNCTION(hal, ar5212, setup_tx_queueprops);
      75           0 :         AR5K_HAL_FUNCTION(hal, ar5212, release_tx_queue);
      76           0 :         AR5K_HAL_FUNCTION(hal, ar5212, reset_tx_queue);
      77           0 :         AR5K_HAL_FUNCTION(hal, ar5212, get_tx_buf);
      78           0 :         AR5K_HAL_FUNCTION(hal, ar5212, put_tx_buf);
      79           0 :         AR5K_HAL_FUNCTION(hal, ar5212, tx_start);
      80           0 :         AR5K_HAL_FUNCTION(hal, ar5212, stop_tx_dma);
      81           0 :         AR5K_HAL_FUNCTION(hal, ar5212, setup_tx_desc);
      82           0 :         AR5K_HAL_FUNCTION(hal, ar5212, setup_xtx_desc);
      83           0 :         AR5K_HAL_FUNCTION(hal, ar5212, fill_tx_desc);
      84           0 :         AR5K_HAL_FUNCTION(hal, ar5212, proc_tx_desc);
      85           0 :         AR5K_HAL_FUNCTION(hal, ar5212, has_veol);
      86             : 
      87             :         /*
      88             :          * RX functions
      89             :          */
      90           0 :         AR5K_HAL_FUNCTION(hal, ar5212, get_rx_buf);
      91           0 :         AR5K_HAL_FUNCTION(hal, ar5212, put_rx_buf);
      92           0 :         AR5K_HAL_FUNCTION(hal, ar5212, start_rx);
      93           0 :         AR5K_HAL_FUNCTION(hal, ar5212, stop_rx_dma);
      94           0 :         AR5K_HAL_FUNCTION(hal, ar5212, start_rx_pcu);
      95           0 :         AR5K_HAL_FUNCTION(hal, ar5212, stop_pcu_recv);
      96           0 :         AR5K_HAL_FUNCTION(hal, ar5212, set_mcast_filter);
      97           0 :         AR5K_HAL_FUNCTION(hal, ar5212, set_mcast_filterindex);
      98           0 :         AR5K_HAL_FUNCTION(hal, ar5212, clear_mcast_filter_idx);
      99           0 :         AR5K_HAL_FUNCTION(hal, ar5212, get_rx_filter);
     100           0 :         AR5K_HAL_FUNCTION(hal, ar5212, set_rx_filter);
     101           0 :         AR5K_HAL_FUNCTION(hal, ar5212, setup_rx_desc);
     102           0 :         AR5K_HAL_FUNCTION(hal, ar5212, proc_rx_desc);
     103           0 :         AR5K_HAL_FUNCTION(hal, ar5212, set_rx_signal);
     104             : 
     105             :         /*
     106             :          * Misc functions
     107             :          */
     108           0 :         AR5K_HAL_FUNCTION(hal, ar5212, dump_state);
     109           0 :         AR5K_HAL_FUNCTION(hal, ar5212, get_diag_state);
     110           0 :         AR5K_HAL_FUNCTION(hal, ar5212, get_lladdr);
     111           0 :         AR5K_HAL_FUNCTION(hal, ar5212, set_lladdr);
     112           0 :         AR5K_HAL_FUNCTION(hal, ar5212, set_regdomain);
     113           0 :         AR5K_HAL_FUNCTION(hal, ar5212, set_ledstate);
     114           0 :         AR5K_HAL_FUNCTION(hal, ar5212, set_associd);
     115           0 :         AR5K_HAL_FUNCTION(hal, ar5212, set_gpio_input);
     116           0 :         AR5K_HAL_FUNCTION(hal, ar5212, set_gpio_output);
     117           0 :         AR5K_HAL_FUNCTION(hal, ar5212, get_gpio);
     118           0 :         AR5K_HAL_FUNCTION(hal, ar5212, set_gpio);
     119           0 :         AR5K_HAL_FUNCTION(hal, ar5212, set_gpio_intr);
     120           0 :         AR5K_HAL_FUNCTION(hal, ar5212, get_tsf32);
     121           0 :         AR5K_HAL_FUNCTION(hal, ar5212, get_tsf64);
     122           0 :         AR5K_HAL_FUNCTION(hal, ar5212, reset_tsf);
     123           0 :         AR5K_HAL_FUNCTION(hal, ar5212, get_regdomain);
     124           0 :         AR5K_HAL_FUNCTION(hal, ar5212, detect_card_present);
     125           0 :         AR5K_HAL_FUNCTION(hal, ar5212, update_mib_counters);
     126           0 :         AR5K_HAL_FUNCTION(hal, ar5212, get_rf_gain);
     127           0 :         AR5K_HAL_FUNCTION(hal, ar5212, set_slot_time);
     128           0 :         AR5K_HAL_FUNCTION(hal, ar5212, get_slot_time);
     129           0 :         AR5K_HAL_FUNCTION(hal, ar5212, set_ack_timeout);
     130           0 :         AR5K_HAL_FUNCTION(hal, ar5212, get_ack_timeout);
     131           0 :         AR5K_HAL_FUNCTION(hal, ar5212, set_cts_timeout);
     132           0 :         AR5K_HAL_FUNCTION(hal, ar5212, get_cts_timeout);
     133             : 
     134             :         /*
     135             :          * Key table (WEP) functions
     136             :          */
     137           0 :         AR5K_HAL_FUNCTION(hal, ar5212, is_cipher_supported);
     138           0 :         AR5K_HAL_FUNCTION(hal, ar5212, get_keycache_size);
     139           0 :         AR5K_HAL_FUNCTION(hal, ar5212, reset_key);
     140           0 :         AR5K_HAL_FUNCTION(hal, ar5212, is_key_valid);
     141           0 :         AR5K_HAL_FUNCTION(hal, ar5212, set_key);
     142           0 :         AR5K_HAL_FUNCTION(hal, ar5212, set_key_lladdr);
     143           0 :         AR5K_HAL_FUNCTION(hal, ar5212, softcrypto);
     144             : 
     145             :         /*
     146             :          * Power management functions
     147             :          */
     148           0 :         AR5K_HAL_FUNCTION(hal, ar5212, set_power);
     149           0 :         AR5K_HAL_FUNCTION(hal, ar5212, get_power_mode);
     150           0 :         AR5K_HAL_FUNCTION(hal, ar5212, query_pspoll_support);
     151           0 :         AR5K_HAL_FUNCTION(hal, ar5212, init_pspoll);
     152           0 :         AR5K_HAL_FUNCTION(hal, ar5212, enable_pspoll);
     153           0 :         AR5K_HAL_FUNCTION(hal, ar5212, disable_pspoll);
     154             : 
     155             :         /*
     156             :          * Beacon functions
     157             :          */
     158           0 :         AR5K_HAL_FUNCTION(hal, ar5212, init_beacon);
     159           0 :         AR5K_HAL_FUNCTION(hal, ar5212, set_beacon_timers);
     160           0 :         AR5K_HAL_FUNCTION(hal, ar5212, reset_beacon);
     161           0 :         AR5K_HAL_FUNCTION(hal, ar5212, wait_for_beacon);
     162             : 
     163             :         /*
     164             :          * Interrupt functions
     165             :          */
     166           0 :         AR5K_HAL_FUNCTION(hal, ar5212, is_intr_pending);
     167           0 :         AR5K_HAL_FUNCTION(hal, ar5212, get_isr);
     168           0 :         AR5K_HAL_FUNCTION(hal, ar5212, get_intr);
     169           0 :         AR5K_HAL_FUNCTION(hal, ar5212, set_intr);
     170             : 
     171             :         /*
     172             :          * Chipset functions (ar5k-specific, non-HAL)
     173             :          */
     174           0 :         AR5K_HAL_FUNCTION(hal, ar5212, get_capabilities);
     175           0 :         AR5K_HAL_FUNCTION(hal, ar5212, radar_alert);
     176             : 
     177             :         /*
     178             :          * EEPROM access
     179             :          */
     180           0 :         AR5K_HAL_FUNCTION(hal, ar5212, eeprom_is_busy);
     181           0 :         AR5K_HAL_FUNCTION(hal, ar5212, eeprom_read);
     182           0 :         AR5K_HAL_FUNCTION(hal, ar5212, eeprom_write);
     183             : 
     184             :         /*
     185             :          * Unused functions or functions not implemented
     186             :          */
     187           0 :         AR5K_HAL_FUNCTION(hal, ar5212, set_bssid_mask);
     188           0 :         AR5K_HAL_FUNCTION(hal, ar5212, get_tx_queueprops);
     189           0 :         AR5K_HAL_FUNCTION(hal, ar5212, num_tx_pending);
     190           0 :         AR5K_HAL_FUNCTION(hal, ar5212, phy_disable);
     191           0 :         AR5K_HAL_FUNCTION(hal, ar5212, set_txpower_limit);
     192           0 :         AR5K_HAL_FUNCTION(hal, ar5212, set_def_antenna);
     193           0 :         AR5K_HAL_FUNCTION(hal, ar5212, get_def_antenna);
     194             : #ifdef notyet
     195             :         AR5K_HAL_FUNCTION(hal, ar5212, set_capability);
     196             :         AR5K_HAL_FUNCTION(hal, ar5212, proc_mib_event);
     197             :         AR5K_HAL_FUNCTION(hal, ar5212, get_tx_inter_queue);
     198             : #endif
     199           0 : }
     200             : 
     201             : struct ath_hal *
     202           0 : ar5k_ar5212_attach(u_int16_t device, void *sc, bus_space_tag_t st,
     203             :     bus_space_handle_t sh, int *status)
     204             : {
     205           0 :         struct ath_hal *hal = (struct ath_hal*) sc;
     206           0 :         u_int8_t mac[IEEE80211_ADDR_LEN];
     207             :         u_int32_t srev;
     208             : 
     209           0 :         ar5k_ar5212_fill(hal);
     210             : 
     211             :         /* Bring device out of sleep and reset its units */
     212           0 :         if (ar5k_ar5212_nic_wakeup(hal, AR5K_INIT_MODE) != AH_TRUE)
     213           0 :                 return (NULL);
     214             : 
     215             :         /* Get MAC, PHY and RADIO revisions */
     216           0 :         srev = AR5K_REG_READ(AR5K_AR5212_SREV);
     217           0 :         hal->ah_mac_srev = srev;
     218           0 :         hal->ah_mac_version = AR5K_REG_MS(srev, AR5K_AR5212_SREV_VER);
     219           0 :         hal->ah_mac_revision = AR5K_REG_MS(srev, AR5K_AR5212_SREV_REV);
     220           0 :         hal->ah_phy_revision = AR5K_REG_READ(AR5K_AR5212_PHY_CHIP_ID) &
     221             :             0x00ffffffff;
     222           0 :         hal->ah_radio_5ghz_revision =
     223           0 :             ar5k_ar5212_radio_revision(hal, HAL_CHIP_5GHZ);
     224           0 :         hal->ah_radio_2ghz_revision =
     225           0 :             ar5k_ar5212_radio_revision(hal, HAL_CHIP_2GHZ);
     226             : 
     227             :         /* Single chip radio */
     228           0 :         if (hal->ah_radio_2ghz_revision == hal->ah_radio_5ghz_revision)
     229           0 :                 hal->ah_radio_2ghz_revision = 0;
     230             : 
     231             :         /* Identify the chipset (this has to be done in an early step) */
     232           0 :         hal->ah_version = AR5K_AR5212;
     233           0 :         if (device == AR5K_VERSION_DEV) {
     234           0 :                 hal->ah_radio = AR5K_AR5413;
     235           0 :                 hal->ah_phy_spending = AR5K_AR5212_PHY_SPENDING_AR5424;
     236           0 :                 hal->ah_radio_5ghz_revision = hal->ah_radio_2ghz_revision =
     237             :                     AR5K_SREV_VER_AR5413;
     238           0 :         } else if (srev == AR5K_SREV_VER_AR2425) {
     239           0 :                 hal->ah_radio = AR5K_AR2425;
     240           0 :                 hal->ah_phy_spending = AR5K_AR5212_PHY_SPENDING_AR5112;
     241           0 :                 hal->ah_radio_5ghz_revision = AR5K_SREV_RAD_SC2;
     242           0 :         } else if (hal->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112) {
     243           0 :                 hal->ah_radio = AR5K_AR5111;
     244           0 :                 hal->ah_phy_spending = AR5K_AR5212_PHY_SPENDING_AR5111;
     245           0 :         } else if (hal->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC0) {
     246           0 :                 hal->ah_radio = AR5K_AR5112;
     247           0 :                 if (hal->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112A)
     248           0 :                         hal->ah_phy_spending = AR5K_AR5212_PHY_SPENDING_AR5112;
     249             :                 else
     250           0 :                         hal->ah_phy_spending = AR5K_AR5212_PHY_SPENDING_AR5112A;
     251           0 :         } else if (hal->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC1) {
     252           0 :                 hal->ah_radio = AR5K_AR2413;
     253           0 :                 hal->ah_phy_spending = AR5K_AR5212_PHY_SPENDING_AR5112A;
     254           0 :         } else if (hal->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC2) {
     255           0 :                 hal->ah_radio = AR5K_AR5413;
     256           0 :                 hal->ah_phy_spending = AR5K_AR5212_PHY_SPENDING_AR5112A;
     257           0 :         } else if (hal->ah_radio_5ghz_revision < AR5K_SREV_RAD_5133 &&
     258           0 :             srev < AR5K_SREV_VER_AR5424) {
     259           0 :                 hal->ah_radio = AR5K_AR2413;
     260           0 :                 hal->ah_phy_spending = AR5K_AR5212_PHY_SPENDING_AR5112A;
     261           0 :         } else if (hal->ah_radio_5ghz_revision < AR5K_SREV_RAD_5133) {
     262           0 :                 hal->ah_radio = AR5K_AR5413;
     263           0 :                 hal->ah_phy_spending = AR5K_AR5212_PHY_SPENDING_AR5424;
     264           0 :         }
     265           0 :         hal->ah_phy = AR5K_AR5212_PHY(0);
     266             : 
     267           0 :         if (hal->ah_pci_express == AH_TRUE) {
     268             :                 /* PCI-Express based devices need some extra initialization */
     269           0 :                 ar5k_write_ini(hal, ar5212_pcie, nitems(ar5212_pcie), 0);
     270           0 :         }
     271             : 
     272           0 :         bcopy(etherbroadcastaddr, mac, IEEE80211_ADDR_LEN);
     273           0 :         ar5k_ar5212_set_associd(hal, mac, 0, 0);
     274           0 :         ar5k_ar5212_get_lladdr(hal, mac);
     275           0 :         ar5k_ar5212_set_opmode(hal);
     276             : 
     277           0 :         return (hal);
     278           0 : }
     279             : 
     280             : HAL_BOOL
     281           0 : ar5k_ar5212_nic_reset(struct ath_hal *hal, u_int32_t val)
     282             : {
     283             :         HAL_BOOL ret = AH_FALSE;
     284           0 :         u_int32_t mask = val ? val : ~0;
     285             : 
     286             :         /* Read-and-clear */
     287           0 :         AR5K_REG_READ(AR5K_AR5212_RXDP);
     288             : 
     289             :         /*
     290             :          * Reset the device and wait until success
     291             :          */
     292           0 :         AR5K_REG_WRITE(AR5K_AR5212_RC, val);
     293             : 
     294             :         /* Wait at least 128 PCI clocks */
     295           0 :         AR5K_DELAY(15);
     296             : 
     297           0 :         val &=
     298             :             AR5K_AR5212_RC_PCU | AR5K_AR5212_RC_BB;
     299             : 
     300           0 :         mask &=
     301             :             AR5K_AR5212_RC_PCU | AR5K_AR5212_RC_BB;
     302             : 
     303           0 :         ret = ar5k_register_timeout(hal, AR5K_AR5212_RC, mask, val, AH_FALSE);
     304             : 
     305             :         /*
     306             :          * Reset configuration register
     307             :          */
     308           0 :         if ((val & AR5K_AR5212_RC_PCU) == 0)
     309           0 :                 AR5K_REG_WRITE(AR5K_AR5212_CFG, AR5K_AR5212_INIT_CFG);
     310             : 
     311           0 :         return (ret);
     312             : }
     313             : 
     314             : HAL_BOOL
     315           0 : ar5k_ar5212_nic_wakeup(struct ath_hal *hal, u_int16_t flags)
     316             : {
     317             :         u_int32_t turbo, mode, clock;
     318             : 
     319             :         turbo = 0;
     320             :         mode = 0;
     321             :         clock = 0;
     322             : 
     323             :         /*
     324             :          * Get channel mode flags
     325             :          */
     326             : 
     327           0 :         if (hal->ah_radio >= AR5K_AR5112) {
     328             :                 mode = AR5K_AR5212_PHY_MODE_RAD_AR5112;
     329             :                 clock = AR5K_AR5212_PHY_PLL_AR5112;
     330           0 :         } else {
     331             :                 mode = AR5K_AR5212_PHY_MODE_RAD_AR5111;
     332             :                 clock = AR5K_AR5212_PHY_PLL_AR5111;
     333             :         }
     334             : 
     335           0 :         if (flags & IEEE80211_CHAN_2GHZ) {
     336           0 :                 mode |= AR5K_AR5212_PHY_MODE_FREQ_2GHZ;
     337           0 :                 clock |= AR5K_AR5212_PHY_PLL_44MHZ;
     338           0 :         } else if (flags & IEEE80211_CHAN_5GHZ) {
     339             :                 mode |= AR5K_AR5212_PHY_MODE_FREQ_5GHZ;
     340           0 :                 clock |= AR5K_AR5212_PHY_PLL_40MHZ;
     341             :         } else {
     342           0 :                 AR5K_PRINT("invalid radio frequency mode\n");
     343           0 :                 return (AH_FALSE);
     344             :         }
     345             : 
     346           0 :         if (flags & IEEE80211_CHAN_CCK) {
     347           0 :                 mode |= AR5K_AR5212_PHY_MODE_MOD_CCK;
     348           0 :         } else if (flags & IEEE80211_CHAN_OFDM) {
     349             :                 mode |= AR5K_AR5212_PHY_MODE_MOD_OFDM;
     350           0 :         } else if (flags & IEEE80211_CHAN_DYN) {
     351           0 :                 mode |= AR5K_AR5212_PHY_MODE_MOD_DYN;
     352             :         } else {
     353           0 :                 AR5K_PRINT("invalid radio frequency mode\n");
     354           0 :                 return (AH_FALSE);
     355             :         }
     356             : 
     357             :         /*
     358             :          * Reset and wakeup the device
     359             :          */
     360             : 
     361             :         /* ...reset chipset and PCI device (if not PCI-E) */
     362           0 :         if (hal->ah_pci_express == AH_FALSE &&
     363           0 :             ar5k_ar5212_nic_reset(hal, AR5K_AR5212_RC_CHIP) == AH_FALSE) {
     364           0 :                 AR5K_PRINT("failed to reset the AR5212 + PCI chipset\n");
     365           0 :                 return (AH_FALSE);
     366             :         }
     367             : 
     368             :         /* ...wakeup */
     369           0 :         if (ar5k_ar5212_set_power(hal,
     370           0 :                 HAL_PM_AWAKE, AH_TRUE, 0) == AH_FALSE) {
     371           0 :                 AR5K_PRINT("failed to resume the AR5212 (again)\n");
     372           0 :                 return (AH_FALSE);
     373             :         }
     374             : 
     375             :         /* ...final warm reset */
     376           0 :         if (ar5k_ar5212_nic_reset(hal, 0) == AH_FALSE) {
     377           0 :                 AR5K_PRINT("failed to warm reset the AR5212\n");
     378           0 :                 return (AH_FALSE);
     379             :         }
     380             : 
     381             :         /* ...set the PHY operating mode */
     382           0 :         AR5K_REG_WRITE(AR5K_AR5212_PHY_PLL, clock);
     383           0 :         AR5K_DELAY(300);
     384             : 
     385           0 :         AR5K_REG_WRITE(AR5K_AR5212_PHY_MODE, mode);
     386           0 :         AR5K_REG_WRITE(AR5K_AR5212_PHY_TURBO, turbo);
     387             : 
     388           0 :         return (AH_TRUE);
     389           0 : }
     390             : 
     391             : u_int16_t
     392           0 : ar5k_ar5212_radio_revision(struct ath_hal *hal, HAL_CHIP chip)
     393             : {
     394             :         int i;
     395             :         u_int32_t srev;
     396             :         u_int16_t ret;
     397             : 
     398             :         /*
     399             :          * Set the radio chip access register
     400             :          */
     401           0 :         switch (chip) {
     402             :         case HAL_CHIP_2GHZ:
     403           0 :                 AR5K_REG_WRITE(AR5K_AR5212_PHY(0), AR5K_AR5212_PHY_SHIFT_2GHZ);
     404           0 :                 break;
     405             :         case HAL_CHIP_5GHZ:
     406           0 :                 AR5K_REG_WRITE(AR5K_AR5212_PHY(0), AR5K_AR5212_PHY_SHIFT_5GHZ);
     407           0 :                 break;
     408             :         default:
     409           0 :                 return (0);
     410             :         }
     411             : 
     412           0 :         AR5K_DELAY(2000);
     413             : 
     414             :         /* ...wait until PHY is ready and read the selected radio revision */
     415           0 :         AR5K_REG_WRITE(AR5K_AR5212_PHY(0x34), 0x00001c16);
     416             : 
     417           0 :         for (i = 0; i < 8; i++)
     418           0 :                 AR5K_REG_WRITE(AR5K_AR5212_PHY(0x20), 0x00010000);
     419           0 :         srev = (AR5K_REG_READ(AR5K_AR5212_PHY(0x100)) >> 24) & 0xff;
     420             : 
     421           0 :         ret = ar5k_bitswap(((srev & 0xf0) >> 4) | ((srev & 0x0f) << 4), 8);
     422             : 
     423             :         /* Reset to the 5GHz mode */
     424           0 :         AR5K_REG_WRITE(AR5K_AR5212_PHY(0), AR5K_AR5212_PHY_SHIFT_5GHZ);
     425             : 
     426           0 :         return (ret);
     427           0 : }
     428             : 
     429             : const HAL_RATE_TABLE *
     430           0 : ar5k_ar5212_get_rate_table(struct ath_hal *hal, u_int mode)
     431             : {
     432           0 :         switch (mode) {
     433             :         case HAL_MODE_11A:
     434           0 :                 return (&hal->ah_rt_11a);
     435             :         case HAL_MODE_11B:
     436           0 :                 return (&hal->ah_rt_11b);
     437             :         case HAL_MODE_11G:
     438             :         case HAL_MODE_PUREG:
     439           0 :                 return (&hal->ah_rt_11g);
     440             :         case HAL_MODE_XR:
     441           0 :                 return (&hal->ah_rt_xr);
     442             :         default:
     443           0 :                 return (NULL);
     444             :         }
     445             : 
     446             :         return (NULL);
     447           0 : }
     448             : 
     449             : void
     450           0 : ar5k_ar5212_detach(struct ath_hal *hal)
     451             : {
     452           0 :         if (hal->ah_rf_banks != NULL)
     453           0 :                 free(hal->ah_rf_banks, M_DEVBUF, 0);
     454             : 
     455             :         /*
     456             :          * Free HAL structure, assume interrupts are down
     457             :          */
     458           0 :         free(hal, M_DEVBUF, 0);
     459           0 : }
     460             : 
     461             : HAL_BOOL
     462           0 : ar5k_ar5212_phy_disable(struct ath_hal *hal)
     463             : {
     464           0 :         AR5K_REG_WRITE(AR5K_AR5212_PHY_ACTIVE, AR5K_AR5212_PHY_DISABLE);
     465           0 :         return (AH_TRUE);
     466             : }
     467             : 
     468             : HAL_BOOL
     469           0 : ar5k_ar5212_reset(struct ath_hal *hal, HAL_OPMODE op_mode, HAL_CHANNEL *channel,
     470             :     HAL_BOOL chanchange, HAL_STATUS *status)
     471             : {
     472           0 :         struct ar5k_eeprom_info *ee = &hal->ah_capabilities.cap_eeprom;
     473           0 :         u_int8_t mac[IEEE80211_ADDR_LEN];
     474             :         u_int32_t data, s_seq, s_ant, s_led[3], dmasize;
     475             :         u_int i, mode, freq, ee_mode, ant[2];
     476             :         const HAL_RATE_TABLE *rt;
     477             : 
     478             :         /* Not used, keep for HAL compatibility */
     479           0 :         *status = HAL_OK;
     480             : 
     481             :         /*
     482             :          * Save some registers before a reset
     483             :          */
     484           0 :         if (chanchange == AH_TRUE) {
     485           0 :                 s_seq = AR5K_REG_READ(AR5K_AR5212_DCU_SEQNUM(0));
     486           0 :                 s_ant = AR5K_REG_READ(AR5K_AR5212_DEFAULT_ANTENNA);
     487           0 :         } else {
     488             :                 s_seq = 0;
     489             :                 s_ant = 1;
     490             :         }
     491             : 
     492           0 :         s_led[0] = AR5K_REG_READ(AR5K_AR5212_PCICFG) &
     493             :             AR5K_AR5212_PCICFG_LEDSTATE;
     494           0 :         s_led[1] = AR5K_REG_READ(AR5K_AR5212_GPIOCR);
     495           0 :         s_led[2] = AR5K_REG_READ(AR5K_AR5212_GPIODO);
     496             : 
     497           0 :         if (chanchange == AH_TRUE && hal->ah_rf_banks != NULL)
     498           0 :                 ar5k_ar5212_get_rf_gain(hal);
     499             : 
     500           0 :         if (ar5k_ar5212_nic_wakeup(hal, channel->c_channel_flags) == AH_FALSE)
     501           0 :                 return (AH_FALSE);
     502             : 
     503             :         /*
     504             :          * Initialize operating mode
     505             :          */
     506           0 :         hal->ah_op_mode = op_mode;
     507             : 
     508           0 :         if ((channel->c_channel_flags & CHANNEL_A) == CHANNEL_A) {
     509             :                 mode = AR5K_INI_VAL_11A;
     510             :                 freq = AR5K_INI_RFGAIN_5GHZ;
     511             :                 ee_mode = AR5K_EEPROM_MODE_11A;
     512           0 :         } else if ((channel->c_channel_flags & CHANNEL_B) == CHANNEL_B) {
     513           0 :                 if (hal->ah_capabilities.cap_mode & HAL_MODE_11B) {
     514             :                         mode = AR5K_INI_VAL_11B;
     515             :                         ee_mode = AR5K_EEPROM_MODE_11B;
     516           0 :                 } else {
     517             :                         mode = AR5K_INI_VAL_11G;
     518             :                         ee_mode = AR5K_EEPROM_MODE_11G;
     519             :                 }
     520             :                 freq = AR5K_INI_RFGAIN_2GHZ;
     521           0 :         } else if ((channel->c_channel_flags & (CHANNEL_G | CHANNEL_PUREG)) ==
     522             :             (CHANNEL_G | CHANNEL_PUREG)) {
     523             :                 mode = AR5K_INI_VAL_11G;
     524             :                 freq = AR5K_INI_RFGAIN_2GHZ;
     525             :                 ee_mode = AR5K_EEPROM_MODE_11G;
     526           0 :         } else if ((channel->c_channel_flags & CHANNEL_XR) == CHANNEL_XR) {
     527             :                 mode = AR5K_INI_VAL_XR;
     528             :                 freq = AR5K_INI_RFGAIN_5GHZ;
     529             :                 ee_mode = AR5K_EEPROM_MODE_11A;
     530             :         } else {
     531           0 :                 AR5K_PRINTF("invalid channel: %d\n", channel->c_channel);
     532           0 :                 return (AH_FALSE);
     533             :         }
     534             : 
     535             :         /* PHY access enable */
     536           0 :         AR5K_REG_WRITE(AR5K_AR5212_PHY(0), AR5K_AR5212_PHY_SHIFT_5GHZ);
     537             : 
     538             :         /*
     539             :          * Write initial mode and register settings
     540             :          */
     541           0 :         ar5k_write_mode(hal, ar5212_mode, nitems(ar5212_mode), mode);
     542           0 :         ar5k_write_ini(hal, ar5212_ini, nitems(ar5212_ini), chanchange);
     543             : 
     544           0 :         switch (hal->ah_radio) {
     545             :         case AR5K_AR5111:
     546           0 :                 ar5k_write_mode(hal, ar5212_ar5111_mode,
     547             :                     nitems(ar5212_ar5111_mode), mode);
     548           0 :                 break;
     549             :         case AR5K_AR5112:
     550           0 :                 ar5k_write_mode(hal, ar5212_ar5112_mode,
     551             :                     nitems(ar5212_ar5112_mode), mode);
     552           0 :                 break;
     553             :         case AR5K_AR5413:
     554           0 :                 ar5k_write_mode(hal, ar5413_mode,
     555             :                     nitems(ar5413_mode), mode);
     556           0 :                 break;
     557             :         case AR5K_AR2413:
     558           0 :                 AR5K_REG_WRITE(AR5K_AR5212_PHY(648), 0x018830c6);
     559           0 :                 ar5k_write_mode(hal, ar2413_mode,
     560             :                     nitems(ar2413_mode), mode);
     561           0 :                 break;
     562             :         case AR5K_AR2425:
     563           0 :                 AR5K_REG_WRITE(AR5K_AR5212_PHY(648), 0x018830c6);
     564           0 :                 if (mode == AR5K_INI_VAL_11B)
     565           0 :                         mode = AR5K_INI_VAL_11G;
     566           0 :                 ar5k_write_mode(hal, ar2425_mode,
     567             :                     nitems(ar2425_mode), mode);
     568           0 :                 break;
     569             :         default:
     570           0 :                 AR5K_PRINTF("invalid radio: %d\n", hal->ah_radio);
     571           0 :                 return (AH_FALSE);
     572             :         }
     573             : 
     574           0 :         if (hal->ah_radio == AR5K_AR5111)
     575           0 :                 ar5k_write_ini(hal, ar5111_bbgain,
     576             :                     nitems(ar5111_bbgain), chanchange);
     577             :         else
     578           0 :                 ar5k_write_ini(hal, ar5112_bbgain,
     579             :                     nitems(ar5112_bbgain), chanchange);
     580             : 
     581             :         /*
     582             :          * Write initial RF gain settings
     583             :          */
     584           0 :         if (ar5k_rfgain(hal, freq) == AH_FALSE)
     585           0 :                 return (AH_FALSE);
     586             : 
     587           0 :         AR5K_DELAY(1000);
     588             : 
     589             :         /*
     590             :          * Set rate duration table
     591             :          */
     592           0 :         rt = ar5k_ar5212_get_rate_table(hal, HAL_MODE_XR);
     593             : 
     594           0 :         for (i = 0; i < rt->rt_rate_count; i++) {
     595           0 :                 AR5K_REG_WRITE(AR5K_AR5212_RATE_DUR(rt->rt_info[i].r_rate_code),
     596             :                     ath_hal_computetxtime(hal, rt, 14,
     597             :                     rt->rt_info[i].r_control_rate, AH_FALSE));
     598             :         }
     599             : 
     600           0 :         rt = ar5k_ar5212_get_rate_table(hal, HAL_MODE_11B);
     601           0 :         for (i = 0; i < rt->rt_rate_count; i++) {
     602           0 :                 data = AR5K_AR5212_RATE_DUR(rt->rt_info[i].r_rate_code);
     603           0 :                 AR5K_REG_WRITE(data,
     604             :                     ath_hal_computetxtime(hal, rt, 14,
     605             :                     rt->rt_info[i].r_control_rate, AH_FALSE));
     606           0 :                 if (rt->rt_info[i].r_short_preamble) {
     607           0 :                         AR5K_REG_WRITE(data +
     608             :                             (rt->rt_info[i].r_short_preamble << 2),
     609             :                             ath_hal_computetxtime(hal, rt, 14,
     610             :                             rt->rt_info[i].r_control_rate, AH_FALSE));
     611           0 :                 }
     612             :         }
     613             : 
     614             :         /* Fix for first revision of the AR5112 RF chipset */
     615           0 :         if (hal->ah_radio >= AR5K_AR5112 &&
     616           0 :             hal->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112A) {
     617           0 :                 AR5K_REG_WRITE(AR5K_AR5212_PHY_CCKTXCTL,
     618             :                     AR5K_AR5212_PHY_CCKTXCTL_WORLD);
     619           0 :                 if (channel->c_channel_flags & IEEE80211_CHAN_OFDM)
     620           0 :                         data = 0xffb81020;
     621             :                 else
     622             :                         data = 0xffb80d20;
     623           0 :                 AR5K_REG_WRITE(AR5K_AR5212_PHY_FC, data);
     624           0 :         }
     625             : 
     626             :         /*
     627             :          * Set TX power (XXX use txpower from net80211)
     628             :          */
     629           0 :         if (ar5k_ar5212_txpower(hal, channel,
     630           0 :                 AR5K_TUNE_DEFAULT_TXPOWER) == AH_FALSE)
     631           0 :                 return (AH_FALSE);
     632             : 
     633             :         /*
     634             :          * Write RF registers
     635             :          */
     636           0 :         if (ar5k_rfregs(hal, channel, mode) == AH_FALSE)
     637           0 :                 return (AH_FALSE);
     638             : 
     639             :         /*
     640             :          * Configure additional registers
     641             :          */
     642             : 
     643             :         /* OFDM timings */
     644           0 :         if (channel->c_channel_flags & IEEE80211_CHAN_OFDM) {
     645             :                 u_int32_t coef_scaled, coef_exp, coef_man, ds_coef_exp,
     646             :                     ds_coef_man, clock;
     647             : 
     648             :                 clock = 40;
     649           0 :                 coef_scaled = ((5 * (clock << 24)) / 2) / channel->c_channel;
     650             : 
     651           0 :                 for (coef_exp = 31; coef_exp > 0; coef_exp--)
     652           0 :                         if ((coef_scaled >> coef_exp) & 0x1)
     653             :                                 break;
     654             : 
     655           0 :                 if (!coef_exp)
     656           0 :                         return (AH_FALSE);
     657             : 
     658           0 :                 coef_exp = 14 - (coef_exp - 24);
     659           0 :                 coef_man = coef_scaled + (1 << (24 - coef_exp - 1));
     660           0 :                 ds_coef_man = coef_man >> (24 - coef_exp);
     661           0 :                 ds_coef_exp = coef_exp - 16;
     662             : 
     663           0 :                 AR5K_REG_WRITE_BITS(AR5K_AR5212_PHY_TIMING_3,
     664             :                     AR5K_AR5212_PHY_TIMING_3_DSC_MAN, ds_coef_man);
     665           0 :                 AR5K_REG_WRITE_BITS(AR5K_AR5212_PHY_TIMING_3,
     666             :                     AR5K_AR5212_PHY_TIMING_3_DSC_EXP, ds_coef_exp);
     667           0 :         }
     668             : 
     669           0 :         if (hal->ah_radio == AR5K_AR5111) {
     670           0 :                 if (channel->c_channel_flags & IEEE80211_CHAN_B)
     671           0 :                         AR5K_REG_ENABLE_BITS(AR5K_AR5212_TXCFG,
     672             :                             AR5K_AR5212_TXCFG_B_MODE);
     673             :                 else
     674           0 :                         AR5K_REG_DISABLE_BITS(AR5K_AR5212_TXCFG,
     675             :                             AR5K_AR5212_TXCFG_B_MODE);
     676             :         }
     677             : 
     678             :         /* Set antenna mode */
     679           0 :         AR5K_REG_MASKED_BITS(AR5K_AR5212_PHY(0x44),
     680             :             hal->ah_antenna[ee_mode][0], 0xfffffc06);
     681             : 
     682           0 :         if (freq == AR5K_INI_RFGAIN_2GHZ)
     683           0 :                 ant[0] = ant[1] = HAL_ANT_FIXED_B;
     684             :         else
     685             :                 ant[0] = ant[1] = HAL_ANT_FIXED_A;
     686             : 
     687           0 :         AR5K_REG_WRITE(AR5K_AR5212_PHY_ANT_SWITCH_TABLE_0,
     688             :             hal->ah_antenna[ee_mode][ant[0]]);
     689           0 :         AR5K_REG_WRITE(AR5K_AR5212_PHY_ANT_SWITCH_TABLE_1,
     690             :             hal->ah_antenna[ee_mode][ant[1]]);
     691             : 
     692             :         /* Commit values from EEPROM */
     693           0 :         if (hal->ah_radio == AR5K_AR5111)
     694           0 :                 AR5K_REG_WRITE_BITS(AR5K_AR5212_PHY_FC,
     695             :                     AR5K_AR5212_PHY_FC_TX_CLIP, ee->ee_tx_clip);
     696             : 
     697           0 :         AR5K_REG_WRITE(AR5K_AR5212_PHY(0x5a),
     698             :             AR5K_AR5212_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]));
     699             : 
     700           0 :         AR5K_REG_MASKED_BITS(AR5K_AR5212_PHY(0x11),
     701             :             (ee->ee_switch_settling[ee_mode] << 7) & 0x3f80, 0xffffc07f);
     702           0 :         AR5K_REG_MASKED_BITS(AR5K_AR5212_PHY(0x12),
     703             :             (ee->ee_ant_tx_rx[ee_mode] << 12) & 0x3f000, 0xfffc0fff);
     704           0 :         AR5K_REG_MASKED_BITS(AR5K_AR5212_PHY(0x14),
     705             :             (ee->ee_adc_desired_size[ee_mode] & 0x00ff) |
     706             :             ((ee->ee_pga_desired_size[ee_mode] << 8) & 0xff00), 0xffff0000);
     707             : 
     708           0 :         AR5K_REG_WRITE(AR5K_AR5212_PHY(0x0d),
     709             :             (ee->ee_tx_end2xpa_disable[ee_mode] << 24) |
     710             :             (ee->ee_tx_end2xpa_disable[ee_mode] << 16) |
     711             :             (ee->ee_tx_frm2xpa_enable[ee_mode] << 8) |
     712             :             (ee->ee_tx_frm2xpa_enable[ee_mode]));
     713             : 
     714           0 :         AR5K_REG_MASKED_BITS(AR5K_AR5212_PHY(0x0a),
     715             :             ee->ee_tx_end2xlna_enable[ee_mode] << 8, 0xffff00ff);
     716           0 :         AR5K_REG_MASKED_BITS(AR5K_AR5212_PHY(0x19),
     717             :             (ee->ee_thr_62[ee_mode] << 12) & 0x7f000, 0xfff80fff);
     718           0 :         AR5K_REG_MASKED_BITS(AR5K_AR5212_PHY(0x49), 4, 0xffffff01);
     719             : 
     720           0 :         AR5K_REG_ENABLE_BITS(AR5K_AR5212_PHY_IQ,
     721             :             AR5K_AR5212_PHY_IQ_CORR_ENABLE |
     722             :             (ee->ee_i_cal[ee_mode] << AR5K_AR5212_PHY_IQ_CORR_Q_I_COFF_S) |
     723             :             ee->ee_q_cal[ee_mode]);
     724             : 
     725           0 :         if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) {
     726           0 :                 AR5K_REG_WRITE_BITS(AR5K_AR5212_PHY_GAIN_2GHZ,
     727             :                     AR5K_AR5212_PHY_GAIN_2GHZ_MARGIN_TXRX,
     728             :                     ee->ee_margin_tx_rx[ee_mode]);
     729           0 :         }
     730             : 
     731             :         /*
     732             :          * Restore saved values
     733             :          */
     734           0 :         AR5K_REG_WRITE(AR5K_AR5212_DCU_SEQNUM(0), s_seq);
     735           0 :         AR5K_REG_WRITE(AR5K_AR5212_DEFAULT_ANTENNA, s_ant);
     736           0 :         AR5K_REG_ENABLE_BITS(AR5K_AR5212_PCICFG, s_led[0]);
     737           0 :         AR5K_REG_WRITE(AR5K_AR5212_GPIOCR, s_led[1]);
     738           0 :         AR5K_REG_WRITE(AR5K_AR5212_GPIODO, s_led[2]);
     739             : 
     740             :         /*
     741             :          * Misc
     742             :          */
     743           0 :         bcopy(etherbroadcastaddr, mac, IEEE80211_ADDR_LEN);
     744           0 :         ar5k_ar5212_set_associd(hal, mac, 0, 0);
     745           0 :         ar5k_ar5212_set_opmode(hal);
     746           0 :         AR5K_REG_WRITE(AR5K_AR5212_PISR, 0xffffffff);
     747           0 :         AR5K_REG_WRITE(AR5K_AR5212_RSSI_THR, AR5K_TUNE_RSSI_THRES);
     748             : 
     749             :         /*
     750             :          * Set Rx/Tx DMA Configuration
     751             :          *
     752             :          * XXX Limit DMA size on PCI-E chipsets to 128 bytes because
     753             :          * XXX we saw RX overruns and TX errors with higher values.
     754             :          */
     755           0 :         dmasize = hal->ah_pci_express == AH_TRUE ?
     756             :             AR5K_AR5212_DMASIZE_128B : AR5K_AR5212_DMASIZE_512B;
     757           0 :         AR5K_REG_WRITE_BITS(AR5K_AR5212_TXCFG, AR5K_AR5212_TXCFG_SDMAMR,
     758             :             dmasize | AR5K_AR5212_TXCFG_DMASIZE);
     759           0 :         AR5K_REG_WRITE_BITS(AR5K_AR5212_RXCFG, AR5K_AR5212_RXCFG_SDMAMW,
     760             :             dmasize);
     761             : 
     762             :         /*
     763             :          * Set channel and calibrate the PHY
     764             :          */
     765           0 :         if (ar5k_channel(hal, channel) == AH_FALSE)
     766           0 :                 return (AH_FALSE);
     767             : 
     768             :         /*
     769             :          * Enable the PHY and wait until completion
     770             :          */
     771           0 :         AR5K_REG_WRITE(AR5K_AR5212_PHY_ACTIVE, AR5K_AR5212_PHY_ENABLE);
     772             : 
     773           0 :         data = AR5K_REG_READ(AR5K_AR5212_PHY_RX_DELAY) &
     774             :             AR5K_AR5212_PHY_RX_DELAY_M;
     775           0 :         data = (channel->c_channel_flags & IEEE80211_CHAN_CCK) ?
     776           0 :             ((data << 2) / 22) : (data / 10);
     777             : 
     778           0 :         AR5K_DELAY(100 + data);
     779             : 
     780             :         /*
     781             :          * Start calibration
     782             :          */
     783           0 :         AR5K_REG_ENABLE_BITS(AR5K_AR5212_PHY_AGCCTL,
     784             :             AR5K_AR5212_PHY_AGCCTL_NF |
     785             :             AR5K_AR5212_PHY_AGCCTL_CAL);
     786             : 
     787           0 :         hal->ah_calibration = AH_FALSE;
     788           0 :         if ((channel->c_channel_flags & IEEE80211_CHAN_B) == 0) {
     789           0 :                 hal->ah_calibration = AH_TRUE;
     790           0 :                 AR5K_REG_WRITE_BITS(AR5K_AR5212_PHY_IQ,
     791             :                     AR5K_AR5212_PHY_IQ_CAL_NUM_LOG_MAX, 15);
     792           0 :                 AR5K_REG_ENABLE_BITS(AR5K_AR5212_PHY_IQ,
     793             :                     AR5K_AR5212_PHY_IQ_RUN);
     794           0 :         }
     795             : 
     796             :         /*
     797             :          * Reset queues and start beacon timers at the end of the reset routine
     798             :          */
     799           0 :         for (i = 0; i < hal->ah_capabilities.cap_queues.q_tx_num; i++) {
     800           0 :                 AR5K_REG_WRITE_Q(AR5K_AR5212_DCU_QCUMASK(i), i);
     801           0 :                 if (ar5k_ar5212_reset_tx_queue(hal, i) == AH_FALSE) {
     802           0 :                         AR5K_PRINTF("failed to reset TX queue #%d\n", i);
     803           0 :                         return (AH_FALSE);
     804             :                 }
     805             :         }
     806             : 
     807             :         /* Pre-enable interrupts */
     808           0 :         ar5k_ar5212_set_intr(hal, HAL_INT_RX | HAL_INT_TX | HAL_INT_FATAL);
     809             : 
     810             :         /*
     811             :          * Set RF kill flags if supported by the device (read from the EEPROM)
     812             :          */
     813           0 :         if (AR5K_EEPROM_HDR_RFKILL(hal->ah_capabilities.cap_eeprom.ee_header)) {
     814           0 :                 ar5k_ar5212_set_gpio_input(hal, 0);
     815           0 :                 if ((hal->ah_gpio[0] = ar5k_ar5212_get_gpio(hal, 0)) == 0)
     816           0 :                         ar5k_ar5212_set_gpio_intr(hal, 0, 1);
     817             :                 else
     818           0 :                         ar5k_ar5212_set_gpio_intr(hal, 0, 0);
     819             :         }
     820             : 
     821             :         /*
     822             :          * Set the 32MHz reference clock
     823             :          */
     824           0 :         AR5K_REG_WRITE(AR5K_AR5212_PHY_SCR, AR5K_AR5212_PHY_SCR_32MHZ);
     825           0 :         AR5K_REG_WRITE(AR5K_AR5212_PHY_SLMT, AR5K_AR5212_PHY_SLMT_32MHZ);
     826           0 :         AR5K_REG_WRITE(AR5K_AR5212_PHY_SCAL, AR5K_AR5212_PHY_SCAL_32MHZ);
     827           0 :         AR5K_REG_WRITE(AR5K_AR5212_PHY_SCLOCK, AR5K_AR5212_PHY_SCLOCK_32MHZ);
     828           0 :         AR5K_REG_WRITE(AR5K_AR5212_PHY_SDELAY, AR5K_AR5212_PHY_SDELAY_32MHZ);
     829           0 :         AR5K_REG_WRITE(AR5K_AR5212_PHY_SPENDING, hal->ah_phy_spending);
     830             : 
     831             :         /* 
     832             :          * Disable beacons and reset the register
     833             :          */
     834           0 :         AR5K_REG_DISABLE_BITS(AR5K_AR5212_BEACON,
     835             :             AR5K_AR5212_BEACON_ENABLE | AR5K_AR5212_BEACON_RESET_TSF);
     836             : 
     837           0 :         return (AH_TRUE);
     838           0 : }
     839             : 
     840             : void
     841           0 : ar5k_ar5212_set_def_antenna(struct ath_hal *hal, u_int ant)
     842             : {
     843           0 :         AR5K_REG_WRITE(AR5K_AR5212_DEFAULT_ANTENNA, ant);
     844           0 : }
     845             : 
     846             : u_int
     847           0 : ar5k_ar5212_get_def_antenna(struct ath_hal *hal)
     848             : {
     849           0 :         return AR5K_REG_READ(AR5K_AR5212_DEFAULT_ANTENNA);
     850             : }
     851             : 
     852             : void
     853           0 : ar5k_ar5212_set_opmode(struct ath_hal *hal)
     854             : {
     855             :         u_int32_t pcu_reg, low_id, high_id;
     856             : 
     857             :         pcu_reg = 0;
     858             : 
     859           0 :         switch (hal->ah_op_mode) {
     860             : #ifndef IEEE80211_STA_ONLY
     861             :         case IEEE80211_M_IBSS:
     862             :                 pcu_reg |= AR5K_AR5212_STA_ID1_ADHOC |
     863             :                     AR5K_AR5212_STA_ID1_DESC_ANTENNA;
     864           0 :                 break;
     865             : 
     866             :         case IEEE80211_M_HOSTAP:
     867             :                 pcu_reg |= AR5K_AR5212_STA_ID1_AP |
     868             :                     AR5K_AR5212_STA_ID1_RTS_DEFAULT_ANTENNA;
     869           0 :                 break;
     870             : #endif
     871             : 
     872             :         case IEEE80211_M_STA:
     873             :         case IEEE80211_M_MONITOR:
     874             :                 pcu_reg |= AR5K_AR5212_STA_ID1_DEFAULT_ANTENNA;
     875           0 :                 break;
     876             : 
     877             :         default:
     878           0 :                 return;
     879             :         }
     880             : 
     881             :         /*
     882             :          * Set PCU registers
     883             :          */
     884           0 :         low_id = AR5K_LOW_ID(hal->ah_sta_id);
     885           0 :         high_id = AR5K_HIGH_ID(hal->ah_sta_id);
     886           0 :         AR5K_REG_WRITE(AR5K_AR5212_STA_ID0, low_id);
     887           0 :         AR5K_REG_WRITE(AR5K_AR5212_STA_ID1, pcu_reg | high_id);
     888             : 
     889           0 :         return;
     890           0 : }
     891             : 
     892             : HAL_BOOL
     893           0 : ar5k_ar5212_calibrate(struct ath_hal *hal, HAL_CHANNEL *channel)
     894             : {
     895             :         u_int32_t i_pwr, q_pwr;
     896             :         int32_t iq_corr, i_coff, i_coffd, q_coff, q_coffd;
     897             : 
     898           0 :         if (hal->ah_calibration == AH_FALSE ||
     899           0 :             AR5K_REG_READ(AR5K_AR5212_PHY_IQ) & AR5K_AR5212_PHY_IQ_RUN)
     900             :                 goto done;
     901             : 
     902           0 :         hal->ah_calibration = AH_FALSE;
     903             : 
     904           0 :         iq_corr = AR5K_REG_READ(AR5K_AR5212_PHY_IQRES_CAL_CORR);
     905           0 :         i_pwr = AR5K_REG_READ(AR5K_AR5212_PHY_IQRES_CAL_PWR_I);
     906           0 :         q_pwr = AR5K_REG_READ(AR5K_AR5212_PHY_IQRES_CAL_PWR_Q);
     907           0 :         i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7;
     908           0 :         q_coffd = q_pwr >> 6;
     909             : 
     910           0 :         if (i_coffd == 0 || q_coffd == 0)
     911             :                 goto done;
     912             : 
     913           0 :         i_coff = ((-iq_corr) / i_coffd) & 0x3f;
     914           0 :         q_coff = (((int32_t)i_pwr / q_coffd) - 64) & 0x1f;
     915             : 
     916             :         /* Commit new IQ value */
     917           0 :         AR5K_REG_ENABLE_BITS(AR5K_AR5212_PHY_IQ,
     918             :             AR5K_AR5212_PHY_IQ_CORR_ENABLE |
     919             :             ((u_int32_t)q_coff) |
     920             :             ((u_int32_t)i_coff << AR5K_AR5212_PHY_IQ_CORR_Q_I_COFF_S));
     921             : 
     922             :  done:
     923             :         /* Start noise floor calibration */
     924           0 :         AR5K_REG_ENABLE_BITS(AR5K_AR5212_PHY_AGCCTL,
     925             :             AR5K_AR5212_PHY_AGCCTL_NF);
     926             : 
     927             :         /* Request RF gain */
     928           0 :         if (channel->c_channel_flags & IEEE80211_CHAN_5GHZ) {
     929           0 :                 AR5K_REG_WRITE(AR5K_AR5212_PHY_PAPD_PROBE,
     930             :                     AR5K_REG_SM(hal->ah_txpower.txp_max,
     931             :                     AR5K_AR5212_PHY_PAPD_PROBE_TXPOWER) |
     932             :                     AR5K_AR5212_PHY_PAPD_PROBE_TX_NEXT);
     933           0 :                 hal->ah_rf_gain = HAL_RFGAIN_READ_REQUESTED;
     934           0 :         }
     935             : 
     936           0 :         return (AH_TRUE);
     937             : }
     938             : 
     939             : /*
     940             :  * Transmit functions
     941             :  */
     942             : 
     943             : HAL_BOOL
     944           0 : ar5k_ar5212_update_tx_triglevel(struct ath_hal *hal, HAL_BOOL increase)
     945             : {
     946             :         u_int32_t trigger_level, imr;
     947             :         HAL_BOOL status = AH_FALSE;
     948             : 
     949             :         /*
     950             :          * Disable interrupts by setting the mask
     951             :          */
     952           0 :         imr = ar5k_ar5212_set_intr(hal, hal->ah_imr & ~HAL_INT_GLOBAL);
     953             : 
     954           0 :         trigger_level = AR5K_REG_MS(AR5K_REG_READ(AR5K_AR5212_TXCFG),
     955             :             AR5K_AR5212_TXCFG_TXFULL);
     956             : 
     957           0 :         if (increase == AH_FALSE) {
     958           0 :                 if (--trigger_level < AR5K_TUNE_MIN_TX_FIFO_THRES)
     959             :                         goto done;
     960             :         } else
     961           0 :                 trigger_level +=
     962           0 :                     ((AR5K_TUNE_MAX_TX_FIFO_THRES - trigger_level) / 2);
     963             : 
     964             :         /*
     965             :          * Update trigger level on success
     966             :          */
     967           0 :         AR5K_REG_WRITE_BITS(AR5K_AR5212_TXCFG,
     968             :             AR5K_AR5212_TXCFG_TXFULL, trigger_level);
     969           0 :         status = AH_TRUE;
     970             : 
     971             :  done:
     972             :         /*
     973             :          * Restore interrupt mask
     974             :          */
     975           0 :         ar5k_ar5212_set_intr(hal, imr);
     976             : 
     977           0 :         return (status);
     978             : }
     979             : 
     980             : int
     981           0 : ar5k_ar5212_setup_tx_queue(struct ath_hal *hal, HAL_TX_QUEUE queue_type,
     982             :     const HAL_TXQ_INFO *queue_info)
     983             : {
     984             :         u_int queue;
     985             : 
     986             :         /*
     987             :          * Get queue by type
     988             :          */
     989           0 :         if (queue_type == HAL_TX_QUEUE_DATA) {
     990           0 :                 for (queue = HAL_TX_QUEUE_ID_DATA_MIN;
     991           0 :                      hal->ah_txq[queue].tqi_type != HAL_TX_QUEUE_INACTIVE;
     992           0 :                      queue++)
     993           0 :                         if (queue > HAL_TX_QUEUE_ID_DATA_MAX)
     994           0 :                                 return (-1);
     995           0 :         } else if (queue_type == HAL_TX_QUEUE_PSPOLL) {
     996             :                 queue = HAL_TX_QUEUE_ID_PSPOLL;
     997           0 :         } else if (queue_type == HAL_TX_QUEUE_BEACON) {
     998             :                 queue = HAL_TX_QUEUE_ID_BEACON;
     999           0 :         } else if (queue_type == HAL_TX_QUEUE_CAB) {
    1000             :                 queue = HAL_TX_QUEUE_ID_CAB;
    1001             :         } else
    1002           0 :                 return (-1);
    1003             : 
    1004             :         /*
    1005             :          * Setup internal queue structure
    1006             :          */
    1007           0 :         bzero(&hal->ah_txq[queue], sizeof(HAL_TXQ_INFO));
    1008           0 :         if (queue_info != NULL) {
    1009           0 :                 if (ar5k_ar5212_setup_tx_queueprops(hal, queue, queue_info)
    1010           0 :                     != AH_TRUE)
    1011           0 :                         return (-1);
    1012             :         }
    1013           0 :         hal->ah_txq[queue].tqi_type = queue_type;
    1014             : 
    1015           0 :         AR5K_Q_ENABLE_BITS(hal->ah_txq_interrupts, queue);
    1016             : 
    1017           0 :         return (queue);
    1018           0 : }
    1019             : 
    1020             : HAL_BOOL
    1021           0 : ar5k_ar5212_setup_tx_queueprops(struct ath_hal *hal, int queue,
    1022             :     const HAL_TXQ_INFO *queue_info)
    1023             : {
    1024           0 :         AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
    1025             : 
    1026           0 :         if (hal->ah_txq[queue].tqi_type != HAL_TX_QUEUE_INACTIVE)
    1027           0 :                 return (AH_FALSE);
    1028             : 
    1029           0 :         bcopy(queue_info, &hal->ah_txq[queue], sizeof(HAL_TXQ_INFO));
    1030             : 
    1031           0 :         if (queue_info->tqi_type == HAL_TX_QUEUE_DATA &&
    1032           0 :             (queue_info->tqi_subtype >= HAL_WME_AC_VI) &&
    1033           0 :             (queue_info->tqi_subtype <= HAL_WME_UPSD))
    1034           0 :                 hal->ah_txq[queue].tqi_flags |=
    1035             :                     AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS;
    1036             : 
    1037           0 :         return (AH_TRUE);
    1038           0 : }
    1039             : 
    1040             : HAL_BOOL
    1041           0 : ar5k_ar5212_get_tx_queueprops(struct ath_hal *hal, int queue,
    1042             :     HAL_TXQ_INFO *queue_info)
    1043             : {
    1044           0 :         AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
    1045           0 :         bcopy(&hal->ah_txq[queue], queue_info, sizeof(HAL_TXQ_INFO));
    1046           0 :         return (AH_TRUE);
    1047           0 : }
    1048             : 
    1049             : HAL_BOOL
    1050           0 : ar5k_ar5212_release_tx_queue(struct ath_hal *hal, u_int queue)
    1051             : {
    1052           0 :         AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
    1053             : 
    1054             :         /* This queue will be skipped in further operations */
    1055           0 :         hal->ah_txq[queue].tqi_type = HAL_TX_QUEUE_INACTIVE;
    1056           0 :         AR5K_Q_DISABLE_BITS(hal->ah_txq_interrupts, queue);
    1057             : 
    1058           0 :         return (AH_FALSE);
    1059           0 : }
    1060             : 
    1061             : HAL_BOOL
    1062           0 : ar5k_ar5212_reset_tx_queue(struct ath_hal *hal, u_int queue)
    1063             : {
    1064             :         u_int32_t cw_min, cw_max, retry_lg, retry_sh;
    1065           0 :         struct ieee80211_channel *channel = (struct ieee80211_channel*)
    1066           0 :             &hal->ah_current_channel;
    1067             :         HAL_TXQ_INFO *tq;
    1068             : 
    1069           0 :         AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
    1070             : 
    1071           0 :         tq = &hal->ah_txq[queue];
    1072             : 
    1073           0 :         if (tq->tqi_type == HAL_TX_QUEUE_INACTIVE)
    1074           0 :                 return (AH_TRUE);
    1075             : 
    1076             :         /*
    1077             :          * Set registers by channel mode
    1078             :          */
    1079           0 :         cw_min = hal->ah_cw_min = AR5K_TUNE_CWMIN;
    1080           0 :         cw_max = hal->ah_cw_max = AR5K_TUNE_CWMAX;
    1081           0 :         hal->ah_aifs = AR5K_TUNE_AIFS;
    1082           0 :         if (IEEE80211_IS_CHAN_XR(channel)) {
    1083           0 :                 cw_min = hal->ah_cw_min = AR5K_TUNE_CWMIN_XR;
    1084           0 :                 cw_max = hal->ah_cw_max = AR5K_TUNE_CWMAX_XR;
    1085           0 :                 hal->ah_aifs = AR5K_TUNE_AIFS_XR;
    1086           0 :         } else if (IEEE80211_IS_CHAN_B(channel)) {
    1087           0 :                 cw_min = hal->ah_cw_min = AR5K_TUNE_CWMIN_11B;
    1088           0 :                 cw_max = hal->ah_cw_max = AR5K_TUNE_CWMAX_11B;
    1089           0 :                 hal->ah_aifs = AR5K_TUNE_AIFS_11B;
    1090           0 :         }
    1091             : 
    1092             :         /*
    1093             :          * Set retry limits
    1094             :          */
    1095           0 :         if (hal->ah_software_retry == AH_TRUE) {
    1096             :                 /* XXX Need to test this */
    1097           0 :                 retry_lg = hal->ah_limit_tx_retries;
    1098             :                 retry_sh = retry_lg =
    1099           0 :                     retry_lg > AR5K_AR5212_DCU_RETRY_LMT_SH_RETRY ?
    1100             :                     AR5K_AR5212_DCU_RETRY_LMT_SH_RETRY : retry_lg;
    1101           0 :         } else {
    1102             :                 retry_lg = AR5K_INIT_LG_RETRY;
    1103             :                 retry_sh = AR5K_INIT_SH_RETRY;
    1104             :         }
    1105             : 
    1106           0 :         AR5K_REG_WRITE(AR5K_AR5212_DCU_RETRY_LMT(queue),
    1107             :             AR5K_REG_SM(AR5K_INIT_SLG_RETRY,
    1108             :             AR5K_AR5212_DCU_RETRY_LMT_SLG_RETRY) |
    1109             :             AR5K_REG_SM(AR5K_INIT_SSH_RETRY,
    1110             :             AR5K_AR5212_DCU_RETRY_LMT_SSH_RETRY) |
    1111             :             AR5K_REG_SM(retry_lg, AR5K_AR5212_DCU_RETRY_LMT_LG_RETRY) |
    1112             :             AR5K_REG_SM(retry_sh, AR5K_AR5212_DCU_RETRY_LMT_SH_RETRY));
    1113             : 
    1114             :         /*
    1115             :          * Set initial content window (cw_min/cw_max)
    1116             :          */
    1117             :         cw_min = 1;
    1118           0 :         while (cw_min < hal->ah_cw_min)
    1119           0 :                 cw_min = (cw_min << 1) | 1;
    1120             : 
    1121           0 :         cw_min = tq->tqi_cw_min < 0 ?
    1122           0 :             (cw_min >> (-tq->tqi_cw_min)) :
    1123           0 :             ((cw_min << tq->tqi_cw_min) + (1 << tq->tqi_cw_min) - 1);
    1124           0 :         cw_max = tq->tqi_cw_max < 0 ?
    1125           0 :             (cw_max >> (-tq->tqi_cw_max)) :
    1126           0 :             ((cw_max << tq->tqi_cw_max) + (1 << tq->tqi_cw_max) - 1);
    1127             : 
    1128           0 :         AR5K_REG_WRITE(AR5K_AR5212_DCU_LCL_IFS(queue),
    1129             :             AR5K_REG_SM(cw_min, AR5K_AR5212_DCU_LCL_IFS_CW_MIN) |
    1130             :             AR5K_REG_SM(cw_max, AR5K_AR5212_DCU_LCL_IFS_CW_MAX) |
    1131             :             AR5K_REG_SM(hal->ah_aifs + tq->tqi_aifs,
    1132             :             AR5K_AR5212_DCU_LCL_IFS_AIFS));
    1133             : 
    1134             :         /*
    1135             :          * Set misc registers
    1136             :          */
    1137           0 :         AR5K_REG_WRITE(AR5K_AR5212_QCU_MISC(queue),
    1138             :             AR5K_AR5212_QCU_MISC_DCU_EARLY);
    1139             : 
    1140           0 :         if (tq->tqi_cbr_period) {
    1141           0 :                 AR5K_REG_WRITE(AR5K_AR5212_QCU_CBRCFG(queue),
    1142             :                     AR5K_REG_SM(tq->tqi_cbr_period,
    1143             :                     AR5K_AR5212_QCU_CBRCFG_INTVAL) |
    1144             :                     AR5K_REG_SM(tq->tqi_cbr_overflow_limit,
    1145             :                     AR5K_AR5212_QCU_CBRCFG_ORN_THRES));
    1146           0 :                 AR5K_REG_ENABLE_BITS(AR5K_AR5212_QCU_MISC(queue),
    1147             :                     AR5K_AR5212_QCU_MISC_FRSHED_CBR);
    1148           0 :                 if (tq->tqi_cbr_overflow_limit)
    1149           0 :                         AR5K_REG_ENABLE_BITS(AR5K_AR5212_QCU_MISC(queue),
    1150             :                             AR5K_AR5212_QCU_MISC_CBR_THRES_ENABLE);
    1151             :         }
    1152             : 
    1153           0 :         if (tq->tqi_ready_time) {
    1154           0 :                 AR5K_REG_WRITE(AR5K_AR5212_QCU_RDYTIMECFG(queue),
    1155             :                     AR5K_REG_SM(tq->tqi_ready_time,
    1156             :                     AR5K_AR5212_QCU_RDYTIMECFG_INTVAL) |
    1157             :                     AR5K_AR5212_QCU_RDYTIMECFG_ENABLE);
    1158           0 :         }
    1159             : 
    1160           0 :         if (tq->tqi_burst_time) {
    1161           0 :                 AR5K_REG_WRITE(AR5K_AR5212_DCU_CHAN_TIME(queue),
    1162             :                     AR5K_REG_SM(tq->tqi_burst_time,
    1163             :                     AR5K_AR5212_DCU_CHAN_TIME_DUR) |
    1164             :                     AR5K_AR5212_DCU_CHAN_TIME_ENABLE);
    1165             : 
    1166           0 :                 if (tq->tqi_flags & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE) {
    1167           0 :                         AR5K_REG_ENABLE_BITS(AR5K_AR5212_QCU_MISC(queue),
    1168             :                             AR5K_AR5212_QCU_MISC_TXE);
    1169           0 :                 }
    1170             :         }
    1171             : 
    1172           0 :         if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE) {
    1173           0 :                 AR5K_REG_WRITE(AR5K_AR5212_DCU_MISC(queue),
    1174             :                     AR5K_AR5212_DCU_MISC_POST_FR_BKOFF_DIS);
    1175           0 :         }
    1176             : 
    1177           0 :         if (tq->tqi_flags & AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) {
    1178           0 :                 AR5K_REG_WRITE(AR5K_AR5212_DCU_MISC(queue),
    1179             :                     AR5K_AR5212_DCU_MISC_BACKOFF_FRAG);
    1180           0 :         }
    1181             : 
    1182             :         /*
    1183             :          * Set registers by queue type
    1184             :          */
    1185           0 :         switch (tq->tqi_type) {
    1186             :         case HAL_TX_QUEUE_BEACON:
    1187           0 :                 AR5K_REG_ENABLE_BITS(AR5K_AR5212_QCU_MISC(queue),
    1188             :                     AR5K_AR5212_QCU_MISC_FRSHED_DBA_GT |
    1189             :                     AR5K_AR5212_QCU_MISC_CBREXP_BCN |
    1190             :                     AR5K_AR5212_QCU_MISC_BCN_ENABLE);
    1191             : 
    1192           0 :                 AR5K_REG_ENABLE_BITS(AR5K_AR5212_DCU_MISC(queue),
    1193             :                     (AR5K_AR5212_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
    1194             :                     AR5K_AR5212_DCU_MISC_ARBLOCK_CTL_GLOBAL) |
    1195             :                     AR5K_AR5212_DCU_MISC_POST_FR_BKOFF_DIS |
    1196             :                     AR5K_AR5212_DCU_MISC_BCN_ENABLE);
    1197             : 
    1198           0 :                 AR5K_REG_WRITE(AR5K_AR5212_QCU_RDYTIMECFG(queue),
    1199             :                     ((AR5K_TUNE_BEACON_INTERVAL -
    1200             :                     (AR5K_TUNE_SW_BEACON_RESP - AR5K_TUNE_DMA_BEACON_RESP) -
    1201             :                     AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) |
    1202             :                     AR5K_AR5212_QCU_RDYTIMECFG_ENABLE);
    1203           0 :                 break;
    1204             : 
    1205             :         case HAL_TX_QUEUE_CAB:
    1206           0 :                 AR5K_REG_ENABLE_BITS(AR5K_AR5212_QCU_MISC(queue),
    1207             :                     AR5K_AR5212_QCU_MISC_FRSHED_DBA_GT |
    1208             :                     AR5K_AR5212_QCU_MISC_CBREXP |
    1209             :                     AR5K_AR5212_QCU_MISC_CBREXP_BCN);
    1210             : 
    1211           0 :                 AR5K_REG_ENABLE_BITS(AR5K_AR5212_DCU_MISC(queue),
    1212             :                     (AR5K_AR5212_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
    1213             :                     AR5K_AR5212_DCU_MISC_ARBLOCK_CTL_GLOBAL));
    1214           0 :                 break;
    1215             : 
    1216             :         case HAL_TX_QUEUE_PSPOLL:
    1217           0 :                 AR5K_REG_ENABLE_BITS(AR5K_AR5212_QCU_MISC(queue),
    1218             :                     AR5K_AR5212_QCU_MISC_CBREXP);
    1219           0 :                 break;
    1220             : 
    1221             :         case HAL_TX_QUEUE_DATA:
    1222             :         default:
    1223             :                 break;
    1224             :         }
    1225             : 
    1226             :         /*
    1227             :          * Enable tx queue in the secondary interrupt mask registers
    1228             :          */
    1229           0 :         AR5K_REG_WRITE(AR5K_AR5212_SIMR0,
    1230             :             AR5K_REG_SM(hal->ah_txq_interrupts, AR5K_AR5212_SIMR0_QCU_TXOK) |
    1231             :             AR5K_REG_SM(hal->ah_txq_interrupts, AR5K_AR5212_SIMR0_QCU_TXDESC));
    1232           0 :         AR5K_REG_WRITE(AR5K_AR5212_SIMR1,
    1233             :             AR5K_REG_SM(hal->ah_txq_interrupts, AR5K_AR5212_SIMR1_QCU_TXERR));
    1234           0 :         AR5K_REG_WRITE(AR5K_AR5212_SIMR2,
    1235             :             AR5K_REG_SM(hal->ah_txq_interrupts, AR5K_AR5212_SIMR2_QCU_TXURN));
    1236             : 
    1237           0 :         return (AH_TRUE);
    1238           0 : }
    1239             : 
    1240             : u_int32_t
    1241           0 : ar5k_ar5212_get_tx_buf(struct ath_hal *hal, u_int queue)
    1242             : {
    1243           0 :         AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
    1244             : 
    1245             :         /*
    1246             :          * Get the transmit queue descriptor pointer from the selected queue
    1247             :          */
    1248           0 :         return (AR5K_REG_READ(AR5K_AR5212_QCU_TXDP(queue)));
    1249           0 : }
    1250             : 
    1251             : HAL_BOOL
    1252           0 : ar5k_ar5212_put_tx_buf(struct ath_hal *hal, u_int queue, u_int32_t phys_addr)
    1253             : {
    1254           0 :         AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
    1255             : 
    1256             :         /*
    1257             :          * Set the transmit queue descriptor pointer for the selected queue
    1258             :          * (this won't work if the queue is still active)
    1259             :          */
    1260           0 :         if (AR5K_REG_READ_Q(AR5K_AR5212_QCU_TXE, queue))
    1261           0 :                 return (AH_FALSE);
    1262             : 
    1263           0 :         AR5K_REG_WRITE(AR5K_AR5212_QCU_TXDP(queue), phys_addr);
    1264             : 
    1265           0 :         return (AH_TRUE);
    1266           0 : }
    1267             : 
    1268             : u_int32_t
    1269           0 : ar5k_ar5212_num_tx_pending(struct ath_hal *hal, u_int queue)
    1270             : {
    1271           0 :         AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
    1272           0 :         return (AR5K_AR5212_QCU_STS(queue) & AR5K_AR5212_QCU_STS_FRMPENDCNT);
    1273           0 : }
    1274             : 
    1275             : HAL_BOOL
    1276           0 : ar5k_ar5212_tx_start(struct ath_hal *hal, u_int queue)
    1277             : {
    1278           0 :         AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
    1279             : 
    1280             :         /* Return if queue is disabled */
    1281           0 :         if (AR5K_REG_READ_Q(AR5K_AR5212_QCU_TXD, queue))
    1282           0 :                 return (AH_FALSE);
    1283             : 
    1284             :         /* Start queue */
    1285           0 :         AR5K_REG_WRITE_Q(AR5K_AR5212_QCU_TXE, queue);
    1286             : 
    1287           0 :         return (AH_TRUE);
    1288           0 : }
    1289             : 
    1290             : HAL_BOOL
    1291           0 : ar5k_ar5212_stop_tx_dma(struct ath_hal *hal, u_int queue)
    1292             : {
    1293             :         int i = 100, pending;
    1294             : 
    1295           0 :         AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
    1296             : 
    1297             :         /*
    1298             :          * Schedule TX disable and wait until queue is empty
    1299             :          */
    1300           0 :         AR5K_REG_WRITE_Q(AR5K_AR5212_QCU_TXD, queue);
    1301             : 
    1302           0 :         do {
    1303           0 :                 pending = AR5K_REG_READ(AR5K_AR5212_QCU_STS(queue)) &
    1304             :                      AR5K_AR5212_QCU_STS_FRMPENDCNT;
    1305           0 :                 delay(100);
    1306           0 :         } while (--i && pending);
    1307             : 
    1308             :         /* Clear register */
    1309           0 :         AR5K_REG_WRITE(AR5K_AR5212_QCU_TXD, 0);
    1310             : 
    1311           0 :         return (AH_TRUE);
    1312           0 : }
    1313             : 
    1314             : HAL_BOOL
    1315           0 : ar5k_ar5212_setup_tx_desc(struct ath_hal *hal, struct ath_desc *desc,
    1316             :     u_int packet_length, u_int header_length, HAL_PKT_TYPE type, u_int tx_power,
    1317             :     u_int tx_rate0, u_int tx_tries0, u_int key_index, u_int antenna_mode,
    1318             :     u_int flags, u_int rtscts_rate, u_int rtscts_duration)
    1319             : {
    1320             :         struct ar5k_ar5212_tx_desc *tx_desc;
    1321             : 
    1322           0 :         tx_desc = (struct ar5k_ar5212_tx_desc*)&desc->ds_ctl0;
    1323             : 
    1324             :         /*
    1325             :          * Validate input
    1326             :          */
    1327           0 :         if (tx_tries0 == 0)
    1328           0 :                 return (AH_FALSE);
    1329             : 
    1330           0 :         if ((tx_desc->tx_control_0 = (packet_length &
    1331           0 :             AR5K_AR5212_DESC_TX_CTL0_FRAME_LEN)) != packet_length)
    1332           0 :                 return (AH_FALSE);
    1333             : 
    1334           0 :         tx_desc->tx_control_0 |=
    1335           0 :             AR5K_REG_SM(tx_power, AR5K_AR5212_DESC_TX_CTL0_XMIT_POWER) |
    1336           0 :             AR5K_REG_SM(antenna_mode, AR5K_AR5212_DESC_TX_CTL0_ANT_MODE_XMIT);
    1337           0 :         tx_desc->tx_control_1 =
    1338           0 :             AR5K_REG_SM(type, AR5K_AR5212_DESC_TX_CTL1_FRAME_TYPE);
    1339           0 :         tx_desc->tx_control_2 =
    1340           0 :             AR5K_REG_SM(tx_tries0, AR5K_AR5212_DESC_TX_CTL2_XMIT_TRIES0);
    1341           0 :         tx_desc->tx_control_3 =
    1342           0 :             tx_rate0 & AR5K_AR5212_DESC_TX_CTL3_XMIT_RATE0;
    1343             : 
    1344             : #define _TX_FLAGS(_c, _flag)                                            \
    1345             :         if (flags & HAL_TXDESC_##_flag)                                     \
    1346             :                 tx_desc->tx_control_##_c |=                          \
    1347             :                         AR5K_AR5212_DESC_TX_CTL##_c##_##_flag
    1348             : 
    1349           0 :         _TX_FLAGS(0, CLRDMASK);
    1350           0 :         _TX_FLAGS(0, VEOL);
    1351           0 :         _TX_FLAGS(0, INTREQ);
    1352           0 :         _TX_FLAGS(0, RTSENA);
    1353           0 :         _TX_FLAGS(0, CTSENA);
    1354           0 :         _TX_FLAGS(1, NOACK);
    1355             : 
    1356             : #undef _TX_FLAGS
    1357             : 
    1358             :         /*
    1359             :          * WEP crap
    1360             :          */
    1361           0 :         if (key_index != HAL_TXKEYIX_INVALID) {
    1362           0 :                 tx_desc->tx_control_0 |=
    1363             :                     AR5K_AR5212_DESC_TX_CTL0_ENCRYPT_KEY_VALID;
    1364           0 :                 tx_desc->tx_control_1 |=
    1365           0 :                     AR5K_REG_SM(key_index,
    1366             :                     AR5K_AR5212_DESC_TX_CTL1_ENCRYPT_KEY_INDEX);
    1367           0 :         }
    1368             : 
    1369             :         /*
    1370             :          * RTS/CTS
    1371             :          */
    1372           0 :         if (flags & (HAL_TXDESC_RTSENA | HAL_TXDESC_CTSENA)) {
    1373           0 :                 if ((flags & HAL_TXDESC_RTSENA) &&
    1374             :                     (flags & HAL_TXDESC_CTSENA))
    1375           0 :                         return (AH_FALSE);
    1376           0 :                 tx_desc->tx_control_2 |=
    1377           0 :                     rtscts_duration & AR5K_AR5212_DESC_TX_CTL2_RTS_DURATION;
    1378           0 :                 tx_desc->tx_control_3 |=
    1379           0 :                     AR5K_REG_SM(rtscts_rate,
    1380             :                     AR5K_AR5212_DESC_TX_CTL3_RTS_CTS_RATE);
    1381           0 :         }
    1382             : 
    1383           0 :         return (AH_TRUE);
    1384           0 : }
    1385             : 
    1386             : HAL_BOOL
    1387           0 : ar5k_ar5212_fill_tx_desc(struct ath_hal *hal, struct ath_desc *desc,
    1388             :     u_int segment_length, HAL_BOOL first_segment, HAL_BOOL last_segment)
    1389             : {
    1390             :         struct ar5k_ar5212_tx_desc *tx_desc;
    1391             :         struct ar5k_ar5212_tx_status *tx_status;
    1392             : 
    1393           0 :         tx_desc = (struct ar5k_ar5212_tx_desc*)&desc->ds_ctl0;
    1394           0 :         tx_status = (struct ar5k_ar5212_tx_status*)&desc->ds_hw[2];
    1395             : 
    1396             :         /* Clear status descriptor */
    1397           0 :         bzero(tx_status, sizeof(struct ar5k_ar5212_tx_status));
    1398             : 
    1399             :         /* Validate segment length and initialize the descriptor */
    1400           0 :         if (segment_length & ~AR5K_AR5212_DESC_TX_CTL1_BUF_LEN)
    1401           0 :                 return (AH_FALSE);
    1402           0 :         tx_desc->tx_control_1 =
    1403             : #if 0
    1404             :             (tx_desc->tx_control_1 & ~AR5K_AR5212_DESC_TX_CTL1_BUF_LEN) |
    1405             : #endif
    1406             :             segment_length;
    1407             : 
    1408           0 :         if (first_segment != AH_TRUE)
    1409           0 :                 tx_desc->tx_control_0 &= ~AR5K_AR5212_DESC_TX_CTL0_FRAME_LEN;
    1410             : 
    1411           0 :         if (last_segment != AH_TRUE)
    1412           0 :                 tx_desc->tx_control_1 |= AR5K_AR5212_DESC_TX_CTL1_MORE;
    1413             : 
    1414           0 :         return (AH_TRUE);
    1415           0 : }
    1416             : 
    1417             : HAL_BOOL
    1418           0 : ar5k_ar5212_setup_xtx_desc(struct ath_hal *hal, struct ath_desc *desc,
    1419             :     u_int tx_rate1, u_int tx_tries1, u_int tx_rate2, u_int tx_tries2,
    1420             :     u_int tx_rate3, u_int tx_tries3)
    1421             : {
    1422             :         struct ar5k_ar5212_tx_desc *tx_desc;
    1423             : 
    1424           0 :         tx_desc = (struct ar5k_ar5212_tx_desc*)&desc->ds_ctl0;
    1425             : 
    1426             : #define _XTX_TRIES(_n)                                                  \
    1427             :         if (tx_tries##_n) {                                             \
    1428             :                 tx_desc->tx_control_2 |=                             \
    1429             :                     AR5K_REG_SM(tx_tries##_n,                           \
    1430             :                     AR5K_AR5212_DESC_TX_CTL2_XMIT_TRIES##_n);           \
    1431             :                 tx_desc->tx_control_3 |=                             \
    1432             :                     AR5K_REG_SM(tx_rate##_n,                            \
    1433             :                     AR5K_AR5212_DESC_TX_CTL3_XMIT_RATE##_n);            \
    1434             :         }
    1435             : 
    1436           0 :         _XTX_TRIES(1);
    1437           0 :         _XTX_TRIES(2);
    1438           0 :         _XTX_TRIES(3);
    1439             : 
    1440             : #undef _XTX_TRIES
    1441             : 
    1442           0 :         return (AH_TRUE);
    1443             : }
    1444             : 
    1445             : HAL_STATUS
    1446           0 : ar5k_ar5212_proc_tx_desc(struct ath_hal *hal, struct ath_desc *desc)
    1447             : {
    1448             :         struct ar5k_ar5212_tx_status *tx_status;
    1449             :         struct ar5k_ar5212_tx_desc *tx_desc;
    1450             : 
    1451           0 :         tx_desc = (struct ar5k_ar5212_tx_desc*)&desc->ds_ctl0;
    1452           0 :         tx_status = (struct ar5k_ar5212_tx_status*)&desc->ds_hw[2];
    1453             : 
    1454             :         /* No frame has been send or error */
    1455           0 :         if ((tx_status->tx_status_1 & AR5K_AR5212_DESC_TX_STATUS1_DONE) == 0)
    1456           0 :                 return (HAL_EINPROGRESS);
    1457             : 
    1458             :         /*
    1459             :          * Get descriptor status
    1460             :          */
    1461           0 :         desc->ds_us.tx.ts_tstamp =
    1462           0 :             AR5K_REG_MS(tx_status->tx_status_0,
    1463             :             AR5K_AR5212_DESC_TX_STATUS0_SEND_TIMESTAMP);
    1464           0 :         desc->ds_us.tx.ts_shortretry =
    1465           0 :             AR5K_REG_MS(tx_status->tx_status_0,
    1466             :             AR5K_AR5212_DESC_TX_STATUS0_RTS_FAIL_COUNT);
    1467           0 :         desc->ds_us.tx.ts_longretry =
    1468           0 :             AR5K_REG_MS(tx_status->tx_status_0,
    1469             :             AR5K_AR5212_DESC_TX_STATUS0_DATA_FAIL_COUNT);
    1470           0 :         desc->ds_us.tx.ts_seqnum =
    1471           0 :             AR5K_REG_MS(tx_status->tx_status_1,
    1472             :             AR5K_AR5212_DESC_TX_STATUS1_SEQ_NUM);
    1473           0 :         desc->ds_us.tx.ts_rssi =
    1474           0 :             AR5K_REG_MS(tx_status->tx_status_1,
    1475             :             AR5K_AR5212_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
    1476           0 :         desc->ds_us.tx.ts_antenna = (tx_status->tx_status_1 &
    1477             :             AR5K_AR5212_DESC_TX_STATUS1_XMIT_ANTENNA) ? 2 : 1;
    1478           0 :         desc->ds_us.tx.ts_status = 0;
    1479             : 
    1480           0 :         switch (AR5K_REG_MS(tx_status->tx_status_1,
    1481             :             AR5K_AR5212_DESC_TX_STATUS1_FINAL_TS_INDEX)) {
    1482             :         case 0:
    1483           0 :                 desc->ds_us.tx.ts_rate = tx_desc->tx_control_3 &
    1484             :                     AR5K_AR5212_DESC_TX_CTL3_XMIT_RATE0;
    1485           0 :                 break;
    1486             :         case 1:
    1487           0 :                 desc->ds_us.tx.ts_rate =
    1488           0 :                     AR5K_REG_MS(tx_desc->tx_control_3,
    1489             :                     AR5K_AR5212_DESC_TX_CTL3_XMIT_RATE1);
    1490           0 :                 desc->ds_us.tx.ts_longretry +=
    1491           0 :                     AR5K_REG_MS(tx_desc->tx_control_2,
    1492             :                     AR5K_AR5212_DESC_TX_CTL2_XMIT_TRIES1);
    1493           0 :                 break;
    1494             :         case 2:
    1495           0 :                 desc->ds_us.tx.ts_rate =
    1496           0 :                     AR5K_REG_MS(tx_desc->tx_control_3,
    1497             :                     AR5K_AR5212_DESC_TX_CTL3_XMIT_RATE2);
    1498           0 :                 desc->ds_us.tx.ts_longretry +=
    1499           0 :                     AR5K_REG_MS(tx_desc->tx_control_2,
    1500             :                     AR5K_AR5212_DESC_TX_CTL2_XMIT_TRIES2);
    1501           0 :                 break;
    1502             :         case 3:
    1503           0 :                 desc->ds_us.tx.ts_rate =
    1504           0 :                     AR5K_REG_MS(tx_desc->tx_control_3,
    1505             :                     AR5K_AR5212_DESC_TX_CTL3_XMIT_RATE3);
    1506           0 :                 desc->ds_us.tx.ts_longretry +=
    1507           0 :                     AR5K_REG_MS(tx_desc->tx_control_2,
    1508             :                     AR5K_AR5212_DESC_TX_CTL2_XMIT_TRIES3);
    1509           0 :                 break;
    1510             :         }
    1511             : 
    1512           0 :         if ((tx_status->tx_status_0 &
    1513           0 :             AR5K_AR5212_DESC_TX_STATUS0_FRAME_XMIT_OK) == 0) {
    1514           0 :                 if (tx_status->tx_status_0 &
    1515             :                     AR5K_AR5212_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
    1516           0 :                         desc->ds_us.tx.ts_status |= HAL_TXERR_XRETRY;
    1517             : 
    1518           0 :                 if (tx_status->tx_status_0 &
    1519             :                     AR5K_AR5212_DESC_TX_STATUS0_FIFO_UNDERRUN)
    1520           0 :                         desc->ds_us.tx.ts_status |= HAL_TXERR_FIFO;
    1521             : 
    1522           0 :                 if (tx_status->tx_status_0 &
    1523             :                     AR5K_AR5212_DESC_TX_STATUS0_FILTERED)
    1524           0 :                         desc->ds_us.tx.ts_status |= HAL_TXERR_FILT;
    1525             :         }
    1526             : 
    1527           0 :         return (HAL_OK);
    1528           0 : }
    1529             : 
    1530             : HAL_BOOL
    1531           0 : ar5k_ar5212_has_veol(struct ath_hal *hal)
    1532             : {
    1533           0 :         return (AH_TRUE);
    1534             : }
    1535             : 
    1536             : /*
    1537             :  * Receive functions
    1538             :  */
    1539             : 
    1540             : u_int32_t
    1541           0 : ar5k_ar5212_get_rx_buf(struct ath_hal *hal)
    1542             : {
    1543           0 :         return (AR5K_REG_READ(AR5K_AR5212_RXDP));
    1544             : }
    1545             : 
    1546             : void
    1547           0 : ar5k_ar5212_put_rx_buf(struct ath_hal *hal, u_int32_t phys_addr)
    1548             : {
    1549           0 :         AR5K_REG_WRITE(AR5K_AR5212_RXDP, phys_addr);
    1550           0 : }
    1551             : 
    1552             : void
    1553           0 : ar5k_ar5212_start_rx(struct ath_hal *hal)
    1554             : {
    1555           0 :         AR5K_REG_WRITE(AR5K_AR5212_CR, AR5K_AR5212_CR_RXE);
    1556           0 : }
    1557             : 
    1558             : HAL_BOOL
    1559           0 : ar5k_ar5212_stop_rx_dma(struct ath_hal *hal)
    1560             : {
    1561             :         int i;
    1562             : 
    1563           0 :         AR5K_REG_WRITE(AR5K_AR5212_CR, AR5K_AR5212_CR_RXD);
    1564             : 
    1565             :         /*
    1566             :          * It may take some time to disable the DMA receive unit
    1567             :          */
    1568           0 :         for (i = 2000;
    1569           0 :              i > 0 && (AR5K_REG_READ(AR5K_AR5212_CR) & AR5K_AR5212_CR_RXE) != 0;
    1570           0 :              i--)
    1571           0 :                 AR5K_DELAY(10);
    1572             : 
    1573           0 :         return (i > 0 ? AH_TRUE : AH_FALSE);
    1574             : }
    1575             : 
    1576             : void
    1577           0 : ar5k_ar5212_start_rx_pcu(struct ath_hal *hal)
    1578             : {
    1579           0 :         AR5K_REG_DISABLE_BITS(AR5K_AR5212_DIAG_SW, AR5K_AR5212_DIAG_SW_DIS_RX);
    1580           0 : }
    1581             : 
    1582             : void
    1583           0 : ar5k_ar5212_stop_pcu_recv(struct ath_hal *hal)
    1584             : {
    1585           0 :         AR5K_REG_ENABLE_BITS(AR5K_AR5212_DIAG_SW, AR5K_AR5212_DIAG_SW_DIS_RX);
    1586           0 : }
    1587             : 
    1588             : void
    1589           0 : ar5k_ar5212_set_mcast_filter(struct ath_hal *hal, u_int32_t filter0,
    1590             :     u_int32_t filter1)
    1591             : {
    1592             :         /* Set the multicat filter */
    1593           0 :         AR5K_REG_WRITE(AR5K_AR5212_MCAST_FIL0, filter0);
    1594           0 :         AR5K_REG_WRITE(AR5K_AR5212_MCAST_FIL1, filter1);
    1595           0 : }
    1596             : 
    1597             : HAL_BOOL
    1598           0 : ar5k_ar5212_set_mcast_filterindex(struct ath_hal *hal, u_int32_t index)
    1599             : {
    1600           0 :         if (index >= 64) {
    1601           0 :             return (AH_FALSE);
    1602           0 :         } else if (index >= 32) {
    1603           0 :             AR5K_REG_ENABLE_BITS(AR5K_AR5212_MCAST_FIL1,
    1604             :                 (1 << (index - 32)));
    1605           0 :         } else {
    1606           0 :             AR5K_REG_ENABLE_BITS(AR5K_AR5212_MCAST_FIL0,
    1607             :                 (1 << index));
    1608             :         }
    1609             : 
    1610           0 :         return (AH_TRUE);
    1611           0 : }
    1612             : 
    1613             : HAL_BOOL
    1614           0 : ar5k_ar5212_clear_mcast_filter_idx(struct ath_hal *hal, u_int32_t index)
    1615             : {
    1616             : 
    1617           0 :         if (index >= 64) {
    1618           0 :             return (AH_FALSE);
    1619           0 :         } else if (index >= 32) {
    1620           0 :             AR5K_REG_DISABLE_BITS(AR5K_AR5212_MCAST_FIL1,
    1621             :                 (1 << (index - 32)));
    1622           0 :         } else {
    1623           0 :             AR5K_REG_DISABLE_BITS(AR5K_AR5212_MCAST_FIL0,
    1624             :                 (1 << index));
    1625             :         }
    1626             : 
    1627           0 :         return (AH_TRUE);
    1628           0 : }
    1629             : 
    1630             : u_int32_t
    1631           0 : ar5k_ar5212_get_rx_filter(struct ath_hal *hal)
    1632             : {
    1633             :         u_int32_t data, filter = 0;
    1634             : 
    1635           0 :         filter = AR5K_REG_READ(AR5K_AR5212_RX_FILTER);
    1636           0 :         data = AR5K_REG_READ(AR5K_AR5212_PHY_ERR_FIL);
    1637             : 
    1638           0 :         if (data & AR5K_AR5212_PHY_ERR_FIL_RADAR)
    1639           0 :                 filter |= HAL_RX_FILTER_PHYRADAR;
    1640           0 :         if (data & (AR5K_AR5212_PHY_ERR_FIL_OFDM |
    1641             :             AR5K_AR5212_PHY_ERR_FIL_CCK))
    1642           0 :                 filter |= HAL_RX_FILTER_PHYERR;
    1643             : 
    1644           0 :         return (filter);
    1645             : }
    1646             : 
    1647             : void
    1648           0 : ar5k_ar5212_set_rx_filter(struct ath_hal *hal, u_int32_t filter)
    1649             : {
    1650             :         u_int32_t data = 0;
    1651             : 
    1652           0 :         if (filter & HAL_RX_FILTER_PHYRADAR)
    1653           0 :                 data |= AR5K_AR5212_PHY_ERR_FIL_RADAR;
    1654           0 :         if (filter & HAL_RX_FILTER_PHYERR)
    1655           0 :                 data |= AR5K_AR5212_PHY_ERR_FIL_OFDM |
    1656             :                     AR5K_AR5212_PHY_ERR_FIL_CCK;
    1657             : 
    1658           0 :         if (data) {
    1659           0 :                 AR5K_REG_ENABLE_BITS(AR5K_AR5212_RXCFG,
    1660             :                     AR5K_AR5212_RXCFG_ZLFDMA);
    1661           0 :         } else {
    1662           0 :                 AR5K_REG_DISABLE_BITS(AR5K_AR5212_RXCFG,
    1663             :                     AR5K_AR5212_RXCFG_ZLFDMA);
    1664             :         }
    1665             : 
    1666           0 :         AR5K_REG_WRITE(AR5K_AR5212_RX_FILTER, filter & 0xff);
    1667           0 :         AR5K_REG_WRITE(AR5K_AR5212_PHY_ERR_FIL, data);
    1668           0 : }
    1669             : 
    1670             : HAL_BOOL
    1671           0 : ar5k_ar5212_setup_rx_desc(struct ath_hal *hal, struct ath_desc *desc,
    1672             :     u_int32_t size, u_int flags)
    1673             : {
    1674             :         struct ar5k_ar5212_rx_desc *rx_desc;
    1675             : 
    1676           0 :         rx_desc = (struct ar5k_ar5212_rx_desc*)&desc->ds_ctl0;
    1677             : 
    1678           0 :         if ((rx_desc->rx_control_1 = (size &
    1679           0 :             AR5K_AR5212_DESC_RX_CTL1_BUF_LEN)) != size)
    1680           0 :                 return (AH_FALSE);
    1681             : 
    1682           0 :         if (flags & HAL_RXDESC_INTREQ)
    1683           0 :                 rx_desc->rx_control_1 |= AR5K_AR5212_DESC_RX_CTL1_INTREQ;
    1684             : 
    1685           0 :         return (AH_TRUE);
    1686           0 : }
    1687             : 
    1688             : HAL_STATUS
    1689           0 : ar5k_ar5212_proc_rx_desc(struct ath_hal *hal, struct ath_desc *desc,
    1690             :     u_int32_t phys_addr, struct ath_desc *next)
    1691             : {
    1692             :         struct ar5k_ar5212_rx_status *rx_status;
    1693             :         struct ar5k_ar5212_rx_error *rx_err;
    1694             : 
    1695           0 :         rx_status = (struct ar5k_ar5212_rx_status*)&desc->ds_hw[0];
    1696             : 
    1697             :         /* Overlay on error */
    1698           0 :         rx_err = (struct ar5k_ar5212_rx_error*)&desc->ds_hw[0];
    1699             : 
    1700             :         /* No frame received / not ready */
    1701           0 :         if ((rx_status->rx_status_1 & AR5K_AR5212_DESC_RX_STATUS1_DONE) == 0)
    1702           0 :                 return (HAL_EINPROGRESS);
    1703             : 
    1704             :         /*
    1705             :          * Frame receive status
    1706             :          */
    1707           0 :         desc->ds_us.rx.rs_datalen = rx_status->rx_status_0 &
    1708             :             AR5K_AR5212_DESC_RX_STATUS0_DATA_LEN;
    1709           0 :         desc->ds_us.rx.rs_rssi =
    1710           0 :             AR5K_REG_MS(rx_status->rx_status_0,
    1711             :             AR5K_AR5212_DESC_RX_STATUS0_RECEIVE_SIGNAL);
    1712           0 :         desc->ds_us.rx.rs_rate =
    1713           0 :             AR5K_REG_MS(rx_status->rx_status_0,
    1714             :             AR5K_AR5212_DESC_RX_STATUS0_RECEIVE_RATE);
    1715           0 :         desc->ds_us.rx.rs_antenna = rx_status->rx_status_0 &
    1716             :             AR5K_AR5212_DESC_RX_STATUS0_RECEIVE_ANTENNA;
    1717           0 :         desc->ds_us.rx.rs_more = rx_status->rx_status_0 &
    1718             :             AR5K_AR5212_DESC_RX_STATUS0_MORE;
    1719           0 :         desc->ds_us.rx.rs_tstamp =
    1720           0 :             AR5K_REG_MS(rx_status->rx_status_1,
    1721             :             AR5K_AR5212_DESC_RX_STATUS1_RECEIVE_TIMESTAMP);
    1722           0 :         desc->ds_us.rx.rs_status = 0;
    1723             : 
    1724             :         /*
    1725             :          * Key table status
    1726             :          */
    1727           0 :         if (rx_status->rx_status_1 &
    1728             :             AR5K_AR5212_DESC_RX_STATUS1_KEY_INDEX_VALID) {
    1729           0 :                 desc->ds_us.rx.rs_keyix =
    1730           0 :                     AR5K_REG_MS(rx_status->rx_status_1,
    1731             :                     AR5K_AR5212_DESC_RX_STATUS1_KEY_INDEX);
    1732           0 :         } else {
    1733           0 :                 desc->ds_us.rx.rs_keyix = HAL_RXKEYIX_INVALID;
    1734             :         }
    1735             : 
    1736             :         /*
    1737             :          * Receive/descriptor errors
    1738             :          */
    1739           0 :         if ((rx_status->rx_status_1 &
    1740           0 :             AR5K_AR5212_DESC_RX_STATUS1_FRAME_RECEIVE_OK) == 0) {
    1741           0 :                 if (rx_status->rx_status_1 &
    1742             :                     AR5K_AR5212_DESC_RX_STATUS1_CRC_ERROR)
    1743           0 :                         desc->ds_us.rx.rs_status |= HAL_RXERR_CRC;
    1744             : 
    1745           0 :                 if (rx_status->rx_status_1 &
    1746             :                     AR5K_AR5212_DESC_RX_STATUS1_PHY_ERROR) {
    1747           0 :                         desc->ds_us.rx.rs_status |= HAL_RXERR_PHY;
    1748           0 :                         desc->ds_us.rx.rs_phyerr =
    1749           0 :                             AR5K_REG_MS(rx_err->rx_error_1,
    1750             :                             AR5K_AR5212_DESC_RX_ERROR1_PHY_ERROR_CODE);
    1751           0 :                 }
    1752             : 
    1753           0 :                 if (rx_status->rx_status_1 &
    1754             :                     AR5K_AR5212_DESC_RX_STATUS1_DECRYPT_CRC_ERROR)
    1755           0 :                         desc->ds_us.rx.rs_status |= HAL_RXERR_DECRYPT;
    1756             : 
    1757           0 :                 if (rx_status->rx_status_1 &
    1758             :                     AR5K_AR5212_DESC_RX_STATUS1_MIC_ERROR)
    1759           0 :                         desc->ds_us.rx.rs_status |= HAL_RXERR_MIC;
    1760             :         }
    1761             : 
    1762           0 :         return (HAL_OK);
    1763           0 : }
    1764             : 
    1765             : void
    1766           0 : ar5k_ar5212_set_rx_signal(struct ath_hal *hal)
    1767             : {
    1768             :         /* Signal state monitoring is not yet supported */
    1769           0 : }
    1770             : 
    1771             : /*
    1772             :  * Misc functions
    1773             :  */
    1774             : 
    1775             : void
    1776           0 : ar5k_ar5212_dump_state(struct ath_hal *hal)
    1777             : {
    1778             : #ifdef AR5K_DEBUG
    1779             : #define AR5K_PRINT_REGISTER(_x)                                         \
    1780             :         printf("(%s: %08x) ", #_x, AR5K_REG_READ(AR5K_AR5212_##_x));
    1781             : 
    1782             :         printf("MAC registers:\n");
    1783             :         AR5K_PRINT_REGISTER(CR);
    1784             :         AR5K_PRINT_REGISTER(CFG);
    1785             :         AR5K_PRINT_REGISTER(IER);
    1786             :         AR5K_PRINT_REGISTER(TXCFG);
    1787             :         AR5K_PRINT_REGISTER(RXCFG);
    1788             :         AR5K_PRINT_REGISTER(MIBC);
    1789             :         AR5K_PRINT_REGISTER(TOPS);
    1790             :         AR5K_PRINT_REGISTER(RXNOFRM);
    1791             :         AR5K_PRINT_REGISTER(RPGTO);
    1792             :         AR5K_PRINT_REGISTER(RFCNT);
    1793             :         AR5K_PRINT_REGISTER(MISC);
    1794             :         AR5K_PRINT_REGISTER(PISR);
    1795             :         AR5K_PRINT_REGISTER(SISR0);
    1796             :         AR5K_PRINT_REGISTER(SISR1);
    1797             :         AR5K_PRINT_REGISTER(SISR3);
    1798             :         AR5K_PRINT_REGISTER(SISR4);
    1799             :         AR5K_PRINT_REGISTER(DCM_ADDR);
    1800             :         AR5K_PRINT_REGISTER(DCM_DATA);
    1801             :         AR5K_PRINT_REGISTER(DCCFG);
    1802             :         AR5K_PRINT_REGISTER(CCFG);
    1803             :         AR5K_PRINT_REGISTER(CCFG_CUP);
    1804             :         AR5K_PRINT_REGISTER(CPC0);
    1805             :         AR5K_PRINT_REGISTER(CPC1);
    1806             :         AR5K_PRINT_REGISTER(CPC2);
    1807             :         AR5K_PRINT_REGISTER(CPCORN);
    1808             :         AR5K_PRINT_REGISTER(QCU_TXE);
    1809             :         AR5K_PRINT_REGISTER(QCU_TXD);
    1810             :         AR5K_PRINT_REGISTER(DCU_GBL_IFS_SIFS);
    1811             :         AR5K_PRINT_REGISTER(DCU_GBL_IFS_SLOT);
    1812             :         AR5K_PRINT_REGISTER(DCU_FP);
    1813             :         AR5K_PRINT_REGISTER(DCU_TXP);
    1814             :         AR5K_PRINT_REGISTER(DCU_TX_FILTER);
    1815             :         AR5K_PRINT_REGISTER(RC);
    1816             :         AR5K_PRINT_REGISTER(SCR);
    1817             :         AR5K_PRINT_REGISTER(INTPEND);
    1818             :         AR5K_PRINT_REGISTER(PCICFG);
    1819             :         AR5K_PRINT_REGISTER(GPIOCR);
    1820             :         AR5K_PRINT_REGISTER(GPIODO);
    1821             :         AR5K_PRINT_REGISTER(SREV);
    1822             :         AR5K_PRINT_REGISTER(EEPROM_BASE);
    1823             :         AR5K_PRINT_REGISTER(EEPROM_DATA);
    1824             :         AR5K_PRINT_REGISTER(EEPROM_CMD);
    1825             :         AR5K_PRINT_REGISTER(EEPROM_CFG);
    1826             :         AR5K_PRINT_REGISTER(PCU_MIN);
    1827             :         AR5K_PRINT_REGISTER(STA_ID0);
    1828             :         AR5K_PRINT_REGISTER(STA_ID1);
    1829             :         AR5K_PRINT_REGISTER(BSS_ID0);
    1830             :         AR5K_PRINT_REGISTER(SLOT_TIME);
    1831             :         AR5K_PRINT_REGISTER(TIME_OUT);
    1832             :         AR5K_PRINT_REGISTER(RSSI_THR);
    1833             :         AR5K_PRINT_REGISTER(BEACON);
    1834             :         AR5K_PRINT_REGISTER(CFP_PERIOD);
    1835             :         AR5K_PRINT_REGISTER(TIMER0);
    1836             :         AR5K_PRINT_REGISTER(TIMER2);
    1837             :         AR5K_PRINT_REGISTER(TIMER3);
    1838             :         AR5K_PRINT_REGISTER(CFP_DUR);
    1839             :         AR5K_PRINT_REGISTER(MCAST_FIL0);
    1840             :         AR5K_PRINT_REGISTER(MCAST_FIL1);
    1841             :         AR5K_PRINT_REGISTER(DIAG_SW);
    1842             :         AR5K_PRINT_REGISTER(TSF_U32);
    1843             :         AR5K_PRINT_REGISTER(ADDAC_TEST);
    1844             :         AR5K_PRINT_REGISTER(DEFAULT_ANTENNA);
    1845             :         AR5K_PRINT_REGISTER(LAST_TSTP);
    1846             :         AR5K_PRINT_REGISTER(NAV);
    1847             :         AR5K_PRINT_REGISTER(RTS_OK);
    1848             :         AR5K_PRINT_REGISTER(ACK_FAIL);
    1849             :         AR5K_PRINT_REGISTER(FCS_FAIL);
    1850             :         AR5K_PRINT_REGISTER(BEACON_CNT);
    1851             :         AR5K_PRINT_REGISTER(TSF_PARM);
    1852             :         AR5K_PRINT_REGISTER(RATE_DUR_0);
    1853             :         AR5K_PRINT_REGISTER(KEYTABLE_0);
    1854             :         printf("\n");
    1855             : 
    1856             :         printf("PHY registers:\n");
    1857             :         AR5K_PRINT_REGISTER(PHY_TURBO);
    1858             :         AR5K_PRINT_REGISTER(PHY_AGC);
    1859             :         AR5K_PRINT_REGISTER(PHY_TIMING_3);
    1860             :         AR5K_PRINT_REGISTER(PHY_CHIP_ID);
    1861             :         AR5K_PRINT_REGISTER(PHY_AGCCTL);
    1862             :         AR5K_PRINT_REGISTER(PHY_NF);
    1863             :         AR5K_PRINT_REGISTER(PHY_SCR);
    1864             :         AR5K_PRINT_REGISTER(PHY_SLMT);
    1865             :         AR5K_PRINT_REGISTER(PHY_SCAL);
    1866             :         AR5K_PRINT_REGISTER(PHY_RX_DELAY);
    1867             :         AR5K_PRINT_REGISTER(PHY_IQ);
    1868             :         AR5K_PRINT_REGISTER(PHY_PAPD_PROBE);
    1869             :         AR5K_PRINT_REGISTER(PHY_TXPOWER_RATE1);
    1870             :         AR5K_PRINT_REGISTER(PHY_TXPOWER_RATE2);
    1871             :         AR5K_PRINT_REGISTER(PHY_FC);
    1872             :         AR5K_PRINT_REGISTER(PHY_RADAR);
    1873             :         AR5K_PRINT_REGISTER(PHY_ANT_SWITCH_TABLE_0);
    1874             :         AR5K_PRINT_REGISTER(PHY_ANT_SWITCH_TABLE_1);
    1875             :         printf("\n");
    1876             : #endif
    1877           0 : }
    1878             : 
    1879             : HAL_BOOL
    1880           0 : ar5k_ar5212_get_diag_state(struct ath_hal *hal, int id, void **device,
    1881             :     u_int *size)
    1882             : {
    1883             :         /*
    1884             :          * We'll ignore this right now. This seems to be some kind of an obscure
    1885             :          * debugging interface for the binary-only HAL.
    1886             :          */
    1887           0 :         return (AH_FALSE);
    1888             : }
    1889             : 
    1890             : void
    1891           0 : ar5k_ar5212_get_lladdr(struct ath_hal *hal, u_int8_t *mac)
    1892             : {
    1893           0 :         bcopy(hal->ah_sta_id, mac, IEEE80211_ADDR_LEN);
    1894           0 : }
    1895             : 
    1896             : HAL_BOOL
    1897           0 : ar5k_ar5212_set_lladdr(struct ath_hal *hal, const u_int8_t *mac)
    1898             : {
    1899             :         u_int32_t low_id, high_id;
    1900             : 
    1901             :         /* Set new station ID */
    1902           0 :         bcopy(mac, hal->ah_sta_id, IEEE80211_ADDR_LEN);
    1903             : 
    1904           0 :         low_id = AR5K_LOW_ID(mac);
    1905           0 :         high_id = 0x0000ffff & AR5K_HIGH_ID(mac);
    1906             : 
    1907           0 :         AR5K_REG_WRITE(AR5K_AR5212_STA_ID0, low_id);
    1908           0 :         AR5K_REG_WRITE(AR5K_AR5212_STA_ID1, high_id);
    1909             : 
    1910           0 :         return (AH_TRUE);
    1911             : }
    1912             : 
    1913             : HAL_BOOL
    1914           0 : ar5k_ar5212_set_regdomain(struct ath_hal *hal, u_int16_t regdomain,
    1915             :     HAL_STATUS *status)
    1916             : {
    1917           0 :         ieee80211_regdomain_t ieee_regdomain;
    1918             : 
    1919           0 :         ieee_regdomain = ar5k_regdomain_to_ieee(regdomain);
    1920             : 
    1921           0 :         if (ar5k_eeprom_regulation_domain(hal, AH_TRUE,
    1922           0 :                 &ieee_regdomain) == AH_TRUE) {
    1923           0 :                 *status = HAL_OK;
    1924           0 :                 return (AH_TRUE);
    1925             :         }
    1926             : 
    1927           0 :         *status = EIO;
    1928             : 
    1929           0 :         return (AH_FALSE);
    1930           0 : }
    1931             : 
    1932             : void
    1933           0 : ar5k_ar5212_set_ledstate(struct ath_hal *hal, HAL_LED_STATE state)
    1934             : {
    1935             :         u_int32_t led;
    1936             : 
    1937           0 :         AR5K_REG_DISABLE_BITS(AR5K_AR5212_PCICFG,
    1938             :             AR5K_AR5212_PCICFG_LEDMODE |  AR5K_AR5212_PCICFG_LED);
    1939             : 
    1940             :         /*
    1941             :          * Some blinking values, define at your wish
    1942             :          */
    1943           0 :         switch (state) {
    1944             :         case IEEE80211_S_SCAN:
    1945             :         case IEEE80211_S_AUTH:
    1946             :                 led = AR5K_AR5212_PCICFG_LEDMODE_PROP |
    1947             :                     AR5K_AR5212_PCICFG_LED_PEND;
    1948           0 :                 break;
    1949             : 
    1950             :         case IEEE80211_S_INIT:
    1951             :                 led = AR5K_AR5212_PCICFG_LEDMODE_PROP |
    1952             :                     AR5K_AR5212_PCICFG_LED_NONE;
    1953           0 :                 break;
    1954             : 
    1955             :         case IEEE80211_S_ASSOC:
    1956             :         case IEEE80211_S_RUN:
    1957             :                 led = AR5K_AR5212_PCICFG_LEDMODE_PROP |
    1958             :                     AR5K_AR5212_PCICFG_LED_ASSOC;
    1959           0 :                 break;
    1960             : 
    1961             :         default:
    1962             :                 led = AR5K_AR5212_PCICFG_LEDMODE_PROM |
    1963             :                     AR5K_AR5212_PCICFG_LED_NONE;
    1964           0 :                 break;
    1965             :         }
    1966             : 
    1967           0 :         AR5K_REG_ENABLE_BITS(AR5K_AR5212_PCICFG, led);
    1968           0 : }
    1969             : 
    1970             : void
    1971           0 : ar5k_ar5212_set_associd(struct ath_hal *hal, const u_int8_t *bssid,
    1972             :     u_int16_t assoc_id, u_int16_t tim_offset)
    1973             : {
    1974             :         u_int32_t low_id, high_id;
    1975             : 
    1976             :         /*
    1977             :          * Set simple BSSID mask
    1978             :          */
    1979           0 :         AR5K_REG_WRITE(AR5K_AR5212_BSS_IDM0, 0xfffffff);
    1980           0 :         AR5K_REG_WRITE(AR5K_AR5212_BSS_IDM1, 0xfffffff);
    1981             : 
    1982             :         /*
    1983             :          * Set BSSID which triggers the "SME Join" operation
    1984             :          */
    1985           0 :         low_id = AR5K_LOW_ID(bssid);
    1986           0 :         high_id = AR5K_HIGH_ID(bssid);
    1987           0 :         AR5K_REG_WRITE(AR5K_AR5212_BSS_ID0, low_id);
    1988           0 :         AR5K_REG_WRITE(AR5K_AR5212_BSS_ID1, high_id |
    1989             :             ((assoc_id & 0x3fff) << AR5K_AR5212_BSS_ID1_AID_S));
    1990           0 :         bcopy(bssid, &hal->ah_bssid, IEEE80211_ADDR_LEN);
    1991             : 
    1992           0 :         if (assoc_id == 0) {
    1993           0 :                 ar5k_ar5212_disable_pspoll(hal);
    1994           0 :                 return;
    1995             :         }
    1996             : 
    1997           0 :         AR5K_REG_WRITE(AR5K_AR5212_BEACON,
    1998             :             (AR5K_REG_READ(AR5K_AR5212_BEACON) &
    1999             :             ~AR5K_AR5212_BEACON_TIM) |
    2000             :             (((tim_offset ? tim_offset + 4 : 0) <<
    2001             :             AR5K_AR5212_BEACON_TIM_S) &
    2002             :             AR5K_AR5212_BEACON_TIM));
    2003             : 
    2004           0 :         ar5k_ar5212_enable_pspoll(hal, NULL, 0);
    2005           0 : }
    2006             : 
    2007             : HAL_BOOL
    2008           0 : ar5k_ar5212_set_bssid_mask(struct ath_hal *hal, const u_int8_t* mask)
    2009             : {
    2010             :         u_int32_t low_id, high_id;
    2011             : 
    2012           0 :         low_id = AR5K_LOW_ID(mask);
    2013           0 :         high_id = 0x0000ffff & AR5K_HIGH_ID(mask);
    2014             : 
    2015           0 :         AR5K_REG_WRITE(AR5K_AR5212_BSS_IDM0, low_id);
    2016           0 :         AR5K_REG_WRITE(AR5K_AR5212_BSS_IDM1, high_id);
    2017             : 
    2018           0 :         return (AH_TRUE);
    2019             : }
    2020             : 
    2021             : HAL_BOOL
    2022           0 : ar5k_ar5212_set_gpio_output(struct ath_hal *hal, u_int32_t gpio)
    2023             : {
    2024           0 :         if (gpio > AR5K_AR5212_NUM_GPIO)
    2025           0 :                 return (AH_FALSE);
    2026             : 
    2027           0 :         AR5K_REG_WRITE(AR5K_AR5212_GPIOCR,
    2028             :             (AR5K_REG_READ(AR5K_AR5212_GPIOCR) &~ AR5K_AR5212_GPIOCR_ALL(gpio))
    2029             :             | AR5K_AR5212_GPIOCR_ALL(gpio));
    2030             : 
    2031           0 :         return (AH_TRUE);
    2032           0 : }
    2033             : 
    2034             : HAL_BOOL
    2035           0 : ar5k_ar5212_set_gpio_input(struct ath_hal *hal, u_int32_t gpio)
    2036             : {
    2037           0 :         if (gpio > AR5K_AR5212_NUM_GPIO)
    2038           0 :                 return (AH_FALSE);
    2039             : 
    2040           0 :         AR5K_REG_WRITE(AR5K_AR5212_GPIOCR,
    2041             :             (AR5K_REG_READ(AR5K_AR5212_GPIOCR) &~ AR5K_AR5212_GPIOCR_ALL(gpio))
    2042             :             | AR5K_AR5212_GPIOCR_NONE(gpio));
    2043             : 
    2044           0 :         return (AH_TRUE);
    2045           0 : }
    2046             : 
    2047             : u_int32_t
    2048           0 : ar5k_ar5212_get_gpio(struct ath_hal *hal, u_int32_t gpio)
    2049             : {
    2050           0 :         if (gpio > AR5K_AR5212_NUM_GPIO)
    2051           0 :                 return (0xffffffff);
    2052             : 
    2053             :         /* GPIO input magic */
    2054           0 :         return (((AR5K_REG_READ(AR5K_AR5212_GPIODI) &
    2055           0 :             AR5K_AR5212_GPIODI_M) >> gpio) & 0x1);
    2056           0 : }
    2057             : 
    2058             : HAL_BOOL
    2059           0 : ar5k_ar5212_set_gpio(struct ath_hal *hal, u_int32_t gpio, u_int32_t val)
    2060             : {
    2061             :         u_int32_t data;
    2062             : 
    2063           0 :         if (gpio > AR5K_AR5212_NUM_GPIO)
    2064           0 :                 return (0xffffffff);
    2065             : 
    2066             :         /* GPIO output magic */
    2067           0 :         data =  AR5K_REG_READ(AR5K_AR5212_GPIODO);
    2068             : 
    2069           0 :         data &= ~(1 << gpio);
    2070           0 :         data |= (val&1) << gpio;
    2071             : 
    2072           0 :         AR5K_REG_WRITE(AR5K_AR5212_GPIODO, data);
    2073             : 
    2074           0 :         return (AH_TRUE);
    2075           0 : }
    2076             : 
    2077             : void
    2078           0 : ar5k_ar5212_set_gpio_intr(struct ath_hal *hal, u_int gpio,
    2079             :     u_int32_t interrupt_level)
    2080             : {
    2081             :         u_int32_t data;
    2082             : 
    2083           0 :         if (gpio > AR5K_AR5212_NUM_GPIO)
    2084           0 :                 return;
    2085             : 
    2086             :         /*
    2087             :          * Set the GPIO interrupt
    2088             :          */
    2089           0 :         data = (AR5K_REG_READ(AR5K_AR5212_GPIOCR) &
    2090           0 :             ~(AR5K_AR5212_GPIOCR_INT_SEL(gpio) | AR5K_AR5212_GPIOCR_INT_SELH |
    2091           0 :             AR5K_AR5212_GPIOCR_INT_ENA | AR5K_AR5212_GPIOCR_ALL(gpio))) |
    2092           0 :             (AR5K_AR5212_GPIOCR_INT_SEL(gpio) | AR5K_AR5212_GPIOCR_INT_ENA);
    2093             : 
    2094           0 :         AR5K_REG_WRITE(AR5K_AR5212_GPIOCR,
    2095             :             interrupt_level ? data : (data | AR5K_AR5212_GPIOCR_INT_SELH));
    2096             : 
    2097           0 :         hal->ah_imr |= AR5K_AR5212_PIMR_GPIO;
    2098             : 
    2099             :         /* Enable GPIO interrupts */
    2100           0 :         AR5K_REG_ENABLE_BITS(AR5K_AR5212_PIMR, AR5K_AR5212_PIMR_GPIO);
    2101           0 : }
    2102             : 
    2103             : u_int32_t
    2104           0 : ar5k_ar5212_get_tsf32(struct ath_hal *hal)
    2105             : {
    2106           0 :         return (AR5K_REG_READ(AR5K_AR5212_TSF_L32));
    2107             : }
    2108             : 
    2109             : u_int64_t
    2110           0 : ar5k_ar5212_get_tsf64(struct ath_hal *hal)
    2111             : {
    2112           0 :         u_int64_t tsf = AR5K_REG_READ(AR5K_AR5212_TSF_U32);
    2113             : 
    2114           0 :         return (AR5K_REG_READ(AR5K_AR5212_TSF_L32) | (tsf << 32));
    2115             : }
    2116             : 
    2117             : void
    2118           0 : ar5k_ar5212_reset_tsf(struct ath_hal *hal)
    2119             : {
    2120           0 :         AR5K_REG_ENABLE_BITS(AR5K_AR5212_BEACON,
    2121             :             AR5K_AR5212_BEACON_RESET_TSF);
    2122           0 : }
    2123             : 
    2124             : u_int16_t
    2125           0 : ar5k_ar5212_get_regdomain(struct ath_hal *hal)
    2126             : {
    2127           0 :         return (ar5k_get_regdomain(hal));
    2128             : }
    2129             : 
    2130             : HAL_BOOL
    2131           0 : ar5k_ar5212_detect_card_present(struct ath_hal *hal)
    2132             : {
    2133           0 :         u_int16_t magic;
    2134             : 
    2135             :         /*
    2136             :          * Checking the EEPROM's magic value could be an indication
    2137             :          * if the card is still present. I didn't find another suitable
    2138             :          * way to do this.
    2139             :          */
    2140           0 :         if (ar5k_ar5212_eeprom_read(hal, AR5K_EEPROM_MAGIC, &magic) != 0)
    2141           0 :                 return (AH_FALSE);
    2142             : 
    2143           0 :         return (magic == AR5K_EEPROM_MAGIC_VALUE ? AH_TRUE : AH_FALSE);
    2144           0 : }
    2145             : 
    2146             : void
    2147           0 : ar5k_ar5212_update_mib_counters(struct ath_hal *hal, HAL_MIB_STATS *statistics)
    2148             : {
    2149             :         /* Read-And-Clear */
    2150           0 :         statistics->ackrcv_bad += AR5K_REG_READ(AR5K_AR5212_ACK_FAIL);
    2151           0 :         statistics->rts_bad += AR5K_REG_READ(AR5K_AR5212_RTS_FAIL);
    2152           0 :         statistics->rts_good += AR5K_REG_READ(AR5K_AR5212_RTS_OK);
    2153           0 :         statistics->fcs_bad += AR5K_REG_READ(AR5K_AR5212_FCS_FAIL);
    2154           0 :         statistics->beacons += AR5K_REG_READ(AR5K_AR5212_BEACON_CNT);
    2155             : 
    2156             :         /* Reset profile count registers */
    2157           0 :         AR5K_REG_WRITE(AR5K_AR5212_PROFCNT_TX, 0);
    2158           0 :         AR5K_REG_WRITE(AR5K_AR5212_PROFCNT_RX, 0);
    2159           0 :         AR5K_REG_WRITE(AR5K_AR5212_PROFCNT_RXCLR, 0);
    2160           0 :         AR5K_REG_WRITE(AR5K_AR5212_PROFCNT_CYCLE, 0);
    2161           0 : }
    2162             : 
    2163             : HAL_RFGAIN
    2164           0 : ar5k_ar5212_get_rf_gain(struct ath_hal *hal)
    2165             : {
    2166             :         u_int32_t data, type;
    2167             : 
    2168           0 :         if ((hal->ah_rf_banks == NULL) || (!hal->ah_gain.g_active))
    2169           0 :                 return (HAL_RFGAIN_INACTIVE);
    2170             : 
    2171           0 :         if (hal->ah_rf_gain != HAL_RFGAIN_READ_REQUESTED)
    2172             :                 goto done;
    2173             : 
    2174           0 :         data = AR5K_REG_READ(AR5K_AR5212_PHY_PAPD_PROBE);
    2175             : 
    2176           0 :         if (!(data & AR5K_AR5212_PHY_PAPD_PROBE_TX_NEXT)) {
    2177           0 :                 hal->ah_gain.g_current =
    2178           0 :                     data >> AR5K_AR5212_PHY_PAPD_PROBE_GAINF_S;
    2179           0 :                 type = AR5K_REG_MS(data, AR5K_AR5212_PHY_PAPD_PROBE_TYPE);
    2180             : 
    2181           0 :                 if (type == AR5K_AR5212_PHY_PAPD_PROBE_TYPE_CCK)
    2182           0 :                         hal->ah_gain.g_current += AR5K_GAIN_CCK_PROBE_CORR;
    2183             : 
    2184           0 :                 if (hal->ah_radio >= AR5K_AR5112) {
    2185           0 :                         ar5k_rfregs_gainf_corr(hal);
    2186           0 :                         hal->ah_gain.g_current =
    2187           0 :                             hal->ah_gain.g_current >= hal->ah_gain.g_f_corr ?
    2188           0 :                             (hal->ah_gain.g_current - hal->ah_gain.g_f_corr) :
    2189             :                             0;
    2190           0 :                 }
    2191             : 
    2192           0 :                 if (ar5k_rfregs_gain_readback(hal) &&
    2193           0 :                     AR5K_GAIN_CHECK_ADJUST(&hal->ah_gain) &&
    2194           0 :                     ar5k_rfregs_gain_adjust(hal))
    2195           0 :                         hal->ah_rf_gain = HAL_RFGAIN_NEED_CHANGE;
    2196             :         }
    2197             : 
    2198             :  done:
    2199           0 :         return (hal->ah_rf_gain);
    2200           0 : }
    2201             : 
    2202             : HAL_BOOL
    2203           0 : ar5k_ar5212_set_slot_time(struct ath_hal *hal, u_int slot_time)
    2204             : {
    2205           0 :         if (slot_time < HAL_SLOT_TIME_9 || slot_time > HAL_SLOT_TIME_MAX)
    2206           0 :                 return (AH_FALSE);
    2207             : 
    2208           0 :         AR5K_REG_WRITE(AR5K_AR5212_DCU_GBL_IFS_SLOT, slot_time);
    2209             : 
    2210           0 :         return (AH_TRUE);
    2211           0 : }
    2212             : 
    2213             : u_int
    2214           0 : ar5k_ar5212_get_slot_time(struct ath_hal *hal)
    2215             : {
    2216           0 :         return (AR5K_REG_READ(AR5K_AR5212_DCU_GBL_IFS_SLOT) & 0xffff);
    2217             : }
    2218             : 
    2219             : HAL_BOOL
    2220           0 : ar5k_ar5212_set_ack_timeout(struct ath_hal *hal, u_int timeout)
    2221             : {
    2222           0 :         if (ar5k_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_AR5212_TIME_OUT_ACK))
    2223           0 :             <= timeout)
    2224           0 :                 return (AH_FALSE);
    2225             : 
    2226           0 :         AR5K_REG_WRITE_BITS(AR5K_AR5212_TIME_OUT, AR5K_AR5212_TIME_OUT_ACK,
    2227             :             ar5k_htoclock(timeout));
    2228             : 
    2229           0 :         return (AH_TRUE);
    2230           0 : }
    2231             : 
    2232             : u_int
    2233           0 : ar5k_ar5212_get_ack_timeout(struct ath_hal *hal)
    2234             : {
    2235           0 :         return (ar5k_clocktoh(AR5K_REG_MS(AR5K_REG_READ(AR5K_AR5212_TIME_OUT),
    2236             :             AR5K_AR5212_TIME_OUT_ACK)));
    2237             : }
    2238             : 
    2239             : HAL_BOOL
    2240           0 : ar5k_ar5212_set_cts_timeout(struct ath_hal *hal, u_int timeout)
    2241             : {
    2242           0 :         if (ar5k_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_AR5212_TIME_OUT_CTS))
    2243           0 :             <= timeout)
    2244           0 :                 return (AH_FALSE);
    2245             : 
    2246           0 :         AR5K_REG_WRITE_BITS(AR5K_AR5212_TIME_OUT, AR5K_AR5212_TIME_OUT_CTS,
    2247             :             ar5k_htoclock(timeout));
    2248             : 
    2249           0 :         return (AH_TRUE);
    2250           0 : }
    2251             : 
    2252             : u_int
    2253           0 : ar5k_ar5212_get_cts_timeout(struct ath_hal *hal)
    2254             : {
    2255           0 :         return (ar5k_clocktoh(AR5K_REG_MS(AR5K_REG_READ(AR5K_AR5212_TIME_OUT),
    2256             :             AR5K_AR5212_TIME_OUT_CTS)));
    2257             : }
    2258             : 
    2259             : /*
    2260             :  * Key table (WEP) functions
    2261             :  */
    2262             : 
    2263             : HAL_BOOL
    2264           0 : ar5k_ar5212_is_cipher_supported(struct ath_hal *hal, HAL_CIPHER cipher)
    2265             : {
    2266             :         /*
    2267             :          * The AR5212 only supports WEP
    2268             :          */
    2269           0 :         if (cipher == HAL_CIPHER_WEP)
    2270           0 :                 return (AH_TRUE);
    2271             : 
    2272           0 :         return (AH_FALSE);
    2273           0 : }
    2274             : 
    2275             : u_int32_t
    2276           0 : ar5k_ar5212_get_keycache_size(struct ath_hal *hal)
    2277             : {
    2278           0 :         return (AR5K_AR5212_KEYCACHE_SIZE);
    2279             : }
    2280             : 
    2281             : HAL_BOOL
    2282           0 : ar5k_ar5212_reset_key(struct ath_hal *hal, u_int16_t entry)
    2283             : {
    2284             :         int i;
    2285             : 
    2286           0 :         AR5K_ASSERT_ENTRY(entry, AR5K_AR5212_KEYTABLE_SIZE);
    2287             : 
    2288           0 :         for (i = 0; i < AR5K_AR5212_KEYCACHE_SIZE; i++)
    2289           0 :                 AR5K_REG_WRITE(AR5K_AR5212_KEYTABLE_OFF(entry, i), 0);
    2290             : 
    2291             :         /* Set NULL encryption */
    2292           0 :         AR5K_REG_WRITE(AR5K_AR5212_KEYTABLE_TYPE(entry),
    2293             :             AR5K_AR5212_KEYTABLE_TYPE_NULL);
    2294             : 
    2295           0 :         return (AH_FALSE);
    2296           0 : }
    2297             : 
    2298             : HAL_BOOL
    2299           0 : ar5k_ar5212_is_key_valid(struct ath_hal *hal, u_int16_t entry)
    2300             : {
    2301           0 :         AR5K_ASSERT_ENTRY(entry, AR5K_AR5212_KEYTABLE_SIZE);
    2302             : 
    2303             :         /*
    2304             :          * Check the validation flag at the end of the entry
    2305             :          */
    2306           0 :         if (AR5K_REG_READ(AR5K_AR5212_KEYTABLE_MAC1(entry)) &
    2307             :             AR5K_AR5212_KEYTABLE_VALID)
    2308           0 :                 return (AH_TRUE);
    2309             : 
    2310           0 :         return (AH_FALSE);
    2311           0 : }
    2312             : 
    2313             : HAL_BOOL
    2314           0 : ar5k_ar5212_set_key(struct ath_hal *hal, u_int16_t entry,
    2315             :     const HAL_KEYVAL *keyval, const u_int8_t *mac, int xor_notused)
    2316             : {
    2317             :         int i;
    2318           0 :         u_int32_t key_v[AR5K_AR5212_KEYCACHE_SIZE - 2];
    2319             : 
    2320           0 :         AR5K_ASSERT_ENTRY(entry, AR5K_AR5212_KEYTABLE_SIZE);
    2321             : 
    2322           0 :         bzero(&key_v, sizeof(key_v));
    2323             : 
    2324           0 :         switch (keyval->wk_len) {
    2325             :         case AR5K_KEYVAL_LENGTH_40:
    2326           0 :                 bcopy(keyval->wk_key, &key_v[0], 4);
    2327           0 :                 bcopy(keyval->wk_key + 4, &key_v[1], 1);
    2328           0 :                 key_v[5] = AR5K_AR5212_KEYTABLE_TYPE_40;
    2329           0 :                 break;
    2330             : 
    2331             :         case AR5K_KEYVAL_LENGTH_104:
    2332           0 :                 bcopy(keyval->wk_key, &key_v[0], 4);
    2333           0 :                 bcopy(keyval->wk_key + 4, &key_v[1], 2);
    2334           0 :                 bcopy(keyval->wk_key + 6, &key_v[2], 4);
    2335           0 :                 bcopy(keyval->wk_key + 10, &key_v[3], 2);
    2336           0 :                 bcopy(keyval->wk_key + 12, &key_v[4], 1);
    2337           0 :                 key_v[5] = AR5K_AR5212_KEYTABLE_TYPE_104;
    2338           0 :                 break;
    2339             : 
    2340             :         case AR5K_KEYVAL_LENGTH_128:
    2341           0 :                 bcopy(keyval->wk_key, &key_v[0], 4);
    2342           0 :                 bcopy(keyval->wk_key + 4, &key_v[1], 2);
    2343           0 :                 bcopy(keyval->wk_key + 6, &key_v[2], 4);
    2344           0 :                 bcopy(keyval->wk_key + 10, &key_v[3], 2);
    2345           0 :                 bcopy(keyval->wk_key + 12, &key_v[4], 4);
    2346           0 :                 key_v[5] = AR5K_AR5212_KEYTABLE_TYPE_128;
    2347           0 :                 break;
    2348             : 
    2349             :         default:
    2350             :                 /* Unsupported key length (not WEP40/104/128) */
    2351           0 :                 return (AH_FALSE);
    2352             :         }
    2353             : 
    2354           0 :         for (i = 0; i < nitems(key_v); i++)
    2355           0 :                 AR5K_REG_WRITE(AR5K_AR5212_KEYTABLE_OFF(entry, i), key_v[i]);
    2356             : 
    2357           0 :         return (ar5k_ar5212_set_key_lladdr(hal, entry, mac));
    2358           0 : }
    2359             : 
    2360             : HAL_BOOL
    2361           0 : ar5k_ar5212_set_key_lladdr(struct ath_hal *hal, u_int16_t entry,
    2362             :     const u_int8_t *mac)
    2363             : {
    2364             :         u_int32_t low_id, high_id;
    2365             :         const u_int8_t *mac_v;
    2366             : 
    2367             :         /*
    2368             :          * Invalid entry (key table overflow)
    2369             :          */
    2370           0 :         AR5K_ASSERT_ENTRY(entry, AR5K_AR5212_KEYTABLE_SIZE);
    2371             : 
    2372             :         /* MAC may be NULL if it's a broadcast key */
    2373           0 :         mac_v = mac == NULL ? etherbroadcastaddr : mac;
    2374             : 
    2375           0 :         low_id = AR5K_LOW_ID(mac_v);
    2376           0 :         high_id = AR5K_HIGH_ID(mac_v) | AR5K_AR5212_KEYTABLE_VALID;
    2377             : 
    2378           0 :         AR5K_REG_WRITE(AR5K_AR5212_KEYTABLE_MAC0(entry), low_id);
    2379           0 :         AR5K_REG_WRITE(AR5K_AR5212_KEYTABLE_MAC1(entry), high_id);
    2380             : 
    2381           0 :         return (AH_TRUE);
    2382           0 : }
    2383             : 
    2384             : HAL_BOOL
    2385           0 : ar5k_ar5212_softcrypto(struct ath_hal *hal, HAL_BOOL enable)
    2386             : {
    2387             :         u_int32_t bits;
    2388             :         int i;
    2389             : 
    2390             :         bits = AR5K_AR5212_DIAG_SW_DIS_ENC | AR5K_AR5212_DIAG_SW_DIS_DEC;
    2391           0 :         if (enable == AH_TRUE) {
    2392             :                 /* Disable the hardware crypto engine */
    2393           0 :                 AR5K_REG_ENABLE_BITS(AR5K_AR5212_DIAG_SW, bits);
    2394           0 :         } else {
    2395             :                 /* Enable the hardware crypto engine */
    2396           0 :                 AR5K_REG_DISABLE_BITS(AR5K_AR5212_DIAG_SW, bits);
    2397             :         }
    2398             : 
    2399             :         /* Reset the key cache */
    2400           0 :         for (i = 0; i < AR5K_AR5212_KEYTABLE_SIZE; i++)
    2401           0 :                 ar5k_ar5212_reset_key(hal, i);
    2402             : 
    2403           0 :         return (AH_TRUE);
    2404             : }
    2405             : 
    2406             : /*
    2407             :  * warm reset MAC and PHY
    2408             :  */
    2409             : 
    2410             : HAL_BOOL
    2411           0 : ar5k_ar5212_warm_reset(struct ath_hal *hal)
    2412             : {
    2413             :         u_int32_t flags;
    2414             : 
    2415             :         flags = AR5K_AR5212_RC_PCU | AR5K_AR5212_RC_BB;
    2416           0 :         if (hal->ah_pci_express == AH_FALSE)
    2417           0 :                 flags |= AR5K_AR5212_RC_PCI;
    2418             : 
    2419             :         /* reset chipset and PCI device */
    2420           0 :         if (ar5k_ar5212_nic_reset(hal, flags) == AH_FALSE)
    2421           0 :                 return (AH_FALSE);
    2422             : 
    2423             :         /* wakeup */
    2424           0 :         if (ar5k_ar5212_set_power(hal,
    2425           0 :             HAL_PM_AWAKE, AH_TRUE, 0) == AH_FALSE)
    2426           0 :                 return (AH_FALSE);
    2427             : 
    2428             :         /* reset chipset */
    2429           0 :         if (ar5k_ar5212_nic_reset(hal, 0) == AH_FALSE)
    2430           0 :                 return (AH_FALSE);
    2431             : 
    2432           0 :         return (AH_TRUE);
    2433           0 : }
    2434             : 
    2435             : /*
    2436             :  * Power management functions
    2437             :  */
    2438             : 
    2439             : HAL_BOOL
    2440           0 : ar5k_ar5212_set_power(struct ath_hal *hal, HAL_POWER_MODE mode,
    2441             :     HAL_BOOL set_chip, u_int16_t sleep_duration)
    2442             : {
    2443             :         u_int32_t staid;
    2444             :         int i;
    2445             : 
    2446           0 :         staid = AR5K_REG_READ(AR5K_AR5212_STA_ID1);
    2447             : 
    2448           0 :         switch (mode) {
    2449             :         case HAL_PM_AUTO:
    2450           0 :                 staid &= ~AR5K_AR5212_STA_ID1_DEFAULT_ANTENNA;
    2451             :                 /* FALLTHROUGH */
    2452             :         case HAL_PM_NETWORK_SLEEP:
    2453           0 :                 if (set_chip == AH_TRUE) {
    2454           0 :                         AR5K_REG_WRITE(AR5K_AR5212_SCR,
    2455             :                             AR5K_AR5212_SCR_SLE | sleep_duration);
    2456           0 :                 }
    2457           0 :                 staid |= AR5K_AR5212_STA_ID1_PWR_SV;
    2458           0 :                 break;
    2459             : 
    2460             :         case HAL_PM_FULL_SLEEP:
    2461           0 :                 if (set_chip == AH_TRUE)
    2462           0 :                         if (ar5k_ar5212_warm_reset(hal) == AH_FALSE)
    2463           0 :                                 return (AH_FALSE);
    2464           0 :                 staid |= AR5K_AR5212_STA_ID1_PWR_SV;
    2465           0 :                 break;
    2466             : 
    2467             :         case HAL_PM_AWAKE:
    2468           0 :                 if (set_chip == AH_FALSE)
    2469             :                         goto commit;
    2470             : 
    2471           0 :                 AR5K_REG_WRITE(AR5K_AR5212_SCR, AR5K_AR5212_SCR_SLE_WAKE);
    2472             : 
    2473           0 :                 for (i = 5000; i > 0; i--) {
    2474             :                         /* Check if the AR5212 did wake up */
    2475           0 :                         if ((AR5K_REG_READ(AR5K_AR5212_PCICFG) &
    2476           0 :                             AR5K_AR5212_PCICFG_SPWR_DN) == 0)
    2477             :                                 break;
    2478             : 
    2479             :                         /* Wait a bit and retry */
    2480           0 :                         AR5K_DELAY(200);
    2481           0 :                         AR5K_REG_WRITE(AR5K_AR5212_SCR,
    2482             :                             AR5K_AR5212_SCR_SLE_WAKE);
    2483             :                 }
    2484             : 
    2485             :                 /* Fail if the AR5212 didn't wake up */
    2486           0 :                 if (i <= 0)
    2487           0 :                         return (AH_FALSE);
    2488             : 
    2489           0 :                 staid &= ~AR5K_AR5212_STA_ID1_PWR_SV;
    2490           0 :                 break;
    2491             : 
    2492             :         default:
    2493           0 :                 return (AH_FALSE);
    2494             :         }
    2495             : 
    2496             :  commit:
    2497           0 :         hal->ah_power_mode = mode;
    2498             : 
    2499           0 :         AR5K_REG_WRITE(AR5K_AR5212_STA_ID1, staid);
    2500             : 
    2501           0 :         return (AH_TRUE);
    2502           0 : }
    2503             : 
    2504             : HAL_POWER_MODE
    2505           0 : ar5k_ar5212_get_power_mode(struct ath_hal *hal)
    2506             : {
    2507           0 :         return (hal->ah_power_mode);
    2508             : }
    2509             : 
    2510             : HAL_BOOL
    2511           0 : ar5k_ar5212_query_pspoll_support(struct ath_hal *hal)
    2512             : {
    2513             :         /* nope */
    2514           0 :         return (AH_FALSE);
    2515             : }
    2516             : 
    2517             : HAL_BOOL
    2518           0 : ar5k_ar5212_init_pspoll(struct ath_hal *hal)
    2519             : {
    2520             :         /*
    2521             :          * Not used on the AR5212
    2522             :          */
    2523           0 :         return (AH_FALSE);
    2524             : }
    2525             : 
    2526             : HAL_BOOL
    2527           0 : ar5k_ar5212_enable_pspoll(struct ath_hal *hal, u_int8_t *bssid,
    2528             :     u_int16_t assoc_id)
    2529             : {
    2530           0 :         return (AH_FALSE);
    2531             : }
    2532             : 
    2533             : HAL_BOOL
    2534           0 : ar5k_ar5212_disable_pspoll(struct ath_hal *hal)
    2535             : {
    2536           0 :         return (AH_FALSE);
    2537             : }
    2538             : 
    2539             : /*
    2540             :  * Beacon functions
    2541             :  */
    2542             : 
    2543             : void
    2544           0 : ar5k_ar5212_init_beacon(struct ath_hal *hal, u_int32_t next_beacon,
    2545             :     u_int32_t interval)
    2546             : {
    2547             :         u_int32_t timer1, timer2, timer3;
    2548             : 
    2549             :         /*
    2550             :          * Set the additional timers by mode
    2551             :          */
    2552           0 :         switch (hal->ah_op_mode) {
    2553             :         case HAL_M_STA:
    2554             :                 timer1 = 0x0000ffff;
    2555             :                 timer2 = 0x0007ffff;
    2556           0 :                 break;
    2557             : 
    2558             :         default:
    2559           0 :                 timer1 = (next_beacon - AR5K_TUNE_DMA_BEACON_RESP) <<
    2560             :                     0x00000003;
    2561           0 :                 timer2 = (next_beacon - AR5K_TUNE_SW_BEACON_RESP) <<
    2562             :                     0x00000003;
    2563           0 :         }
    2564             : 
    2565           0 :         timer3 = next_beacon +
    2566           0 :             (hal->ah_atim_window ? hal->ah_atim_window : 1);
    2567             : 
    2568             :         /*
    2569             :          * Enable all timers and set the beacon register
    2570             :          * (next beacon, DMA beacon, software beacon, ATIM window time)
    2571             :          */
    2572           0 :         AR5K_REG_WRITE(AR5K_AR5212_TIMER0, next_beacon);
    2573           0 :         AR5K_REG_WRITE(AR5K_AR5212_TIMER1, timer1);
    2574           0 :         AR5K_REG_WRITE(AR5K_AR5212_TIMER2, timer2);
    2575           0 :         AR5K_REG_WRITE(AR5K_AR5212_TIMER3, timer3);
    2576             : 
    2577           0 :         AR5K_REG_WRITE(AR5K_AR5212_BEACON, interval &
    2578             :             (AR5K_AR5212_BEACON_PERIOD | AR5K_AR5212_BEACON_RESET_TSF |
    2579             :             AR5K_AR5212_BEACON_ENABLE));
    2580           0 : }
    2581             : 
    2582             : void
    2583           0 : ar5k_ar5212_set_beacon_timers(struct ath_hal *hal,
    2584             :     const HAL_BEACON_STATE *state, u_int32_t tsf, u_int32_t dtim_count,
    2585             :     u_int32_t cfp_count)
    2586             : {
    2587             :         u_int32_t cfp_period, next_cfp, dtim, interval, next_beacon;
    2588             : 
    2589             :         /* Return on an invalid beacon state */
    2590           0 :         if (state->bs_interval < 1)
    2591           0 :                 return;
    2592             : 
    2593             :         interval = state->bs_intval;
    2594           0 :         dtim = state->bs_dtimperiod;
    2595             : 
    2596             :         /*
    2597             :          * PCF support?
    2598             :          */
    2599           0 :         if (state->bs_cfp_period > 0) {
    2600             :                 /* Enable CFP mode and set the CFP and timer registers */
    2601           0 :                 cfp_period = state->bs_cfp_period * state->bs_dtim_period *
    2602             :                     state->bs_interval;
    2603           0 :                 next_cfp = (cfp_count * state->bs_dtim_period + dtim_count) *
    2604             :                     state->bs_interval;
    2605             : 
    2606           0 :                 AR5K_REG_ENABLE_BITS(AR5K_AR5212_STA_ID1,
    2607             :                     AR5K_AR5212_STA_ID1_PCF);
    2608           0 :                 AR5K_REG_WRITE(AR5K_AR5212_CFP_PERIOD, cfp_period);
    2609           0 :                 AR5K_REG_WRITE(AR5K_AR5212_CFP_DUR, state->bs_cfp_max_duration);
    2610           0 :                 AR5K_REG_WRITE(AR5K_AR5212_TIMER2,
    2611             :                     (tsf + (next_cfp == 0 ? cfp_period : next_cfp)) << 3);
    2612           0 :         } else {
    2613             :                 /* Disable PCF mode */
    2614           0 :                 AR5K_REG_DISABLE_BITS(AR5K_AR5212_STA_ID1,
    2615             :                     AR5K_AR5212_STA_ID1_PCF);
    2616             :         }
    2617             : 
    2618             :         /*
    2619             :          * Enable the beacon timer register
    2620             :          */
    2621           0 :         AR5K_REG_WRITE(AR5K_AR5212_TIMER0, state->bs_next_beacon);
    2622             : 
    2623             :         /*
    2624             :          * Start the beacon timers
    2625             :          */
    2626           0 :         AR5K_REG_WRITE(AR5K_AR5212_BEACON,
    2627             :             (AR5K_REG_READ(AR5K_AR5212_BEACON) &~
    2628             :             (AR5K_AR5212_BEACON_PERIOD | AR5K_AR5212_BEACON_TIM)) |
    2629             :             AR5K_REG_SM(state->bs_tim_offset ? state->bs_tim_offset + 4 : 0,
    2630             :             AR5K_AR5212_BEACON_TIM) | AR5K_REG_SM(state->bs_interval,
    2631             :             AR5K_AR5212_BEACON_PERIOD));
    2632             : 
    2633             :         /*
    2634             :          * Write new beacon miss threshold, if it appears to be valid
    2635             :          */
    2636           0 :         if ((AR5K_AR5212_RSSI_THR_BMISS >> AR5K_AR5212_RSSI_THR_BMISS_S) <
    2637           0 :             state->bs_bmiss_threshold)
    2638           0 :                 return;
    2639             : 
    2640           0 :         AR5K_REG_WRITE_BITS(AR5K_AR5212_RSSI_THR_M,
    2641             :             AR5K_AR5212_RSSI_THR_BMISS, state->bs_bmiss_threshold);
    2642             : 
    2643             :         /*
    2644             :          * Set sleep registers
    2645             :          */
    2646           0 :         if ((state->bs_sleepduration > state->bs_interval) &&
    2647           0 :             (roundup(state->bs_sleepduration, interval) ==
    2648             :             state->bs_sleepduration))
    2649           0 :                 interval = state->bs_sleepduration;
    2650             : 
    2651           0 :         if (state->bs_sleepduration > dtim &&
    2652           0 :             (dtim == 0 || roundup(state->bs_sleepduration, dtim) ==
    2653             :             state->bs_sleepduration))
    2654           0 :                 dtim = state->bs_sleepduration;
    2655             : 
    2656           0 :         if (interval > dtim)
    2657           0 :                 return;
    2658             : 
    2659           0 :         next_beacon = interval == dtim ?
    2660           0 :             state->bs_nextdtim: state->bs_nexttbtt;
    2661             : 
    2662           0 :         AR5K_REG_WRITE(AR5K_AR5212_SLEEP0,
    2663             :             AR5K_REG_SM((state->bs_nextdtim - 3) << 3,
    2664             :             AR5K_AR5212_SLEEP0_NEXT_DTIM) |
    2665             :             AR5K_REG_SM(10, AR5K_AR5212_SLEEP0_CABTO) |
    2666             :             AR5K_AR5212_SLEEP0_ENH_SLEEP_EN |
    2667             :             AR5K_AR5212_SLEEP0_ASSUME_DTIM);
    2668           0 :         AR5K_REG_WRITE(AR5K_AR5212_SLEEP1,
    2669             :             AR5K_REG_SM((next_beacon - 3) << 3,
    2670             :             AR5K_AR5212_SLEEP1_NEXT_TIM) |
    2671             :             AR5K_REG_SM(10, AR5K_AR5212_SLEEP1_BEACON_TO));
    2672           0 :         AR5K_REG_WRITE(AR5K_AR5212_SLEEP2,
    2673             :             AR5K_REG_SM(interval, AR5K_AR5212_SLEEP2_TIM_PER) |
    2674             :             AR5K_REG_SM(dtim, AR5K_AR5212_SLEEP2_DTIM_PER));
    2675           0 : }
    2676             : 
    2677             : void
    2678           0 : ar5k_ar5212_reset_beacon(struct ath_hal *hal)
    2679             : {
    2680             :         /*
    2681             :          * Disable beacon timer
    2682             :          */
    2683           0 :         AR5K_REG_WRITE(AR5K_AR5212_TIMER0, 0);
    2684             : 
    2685             :         /*
    2686             :          * Disable some beacon register values
    2687             :          */
    2688           0 :         AR5K_REG_DISABLE_BITS(AR5K_AR5212_STA_ID1,
    2689             :             AR5K_AR5212_STA_ID1_DEFAULT_ANTENNA | AR5K_AR5212_STA_ID1_PCF);
    2690           0 :         AR5K_REG_WRITE(AR5K_AR5212_BEACON, AR5K_AR5212_BEACON_PERIOD);
    2691           0 : }
    2692             : 
    2693             : HAL_BOOL
    2694           0 : ar5k_ar5212_wait_for_beacon(struct ath_hal *hal, bus_addr_t phys_addr)
    2695             : {
    2696             :         HAL_BOOL ret;
    2697             : 
    2698             :         /*
    2699             :          * Wait for beaconn queue to be done
    2700             :          */
    2701           0 :         ret = ar5k_register_timeout(hal,
    2702             :             AR5K_AR5212_QCU_STS(HAL_TX_QUEUE_ID_BEACON),
    2703             :             AR5K_AR5212_QCU_STS_FRMPENDCNT, 0, AH_FALSE);
    2704             : 
    2705           0 :         if (AR5K_REG_READ_Q(AR5K_AR5212_QCU_TXE, HAL_TX_QUEUE_ID_BEACON))
    2706           0 :                 return (AH_FALSE);
    2707             : 
    2708           0 :         return (ret);
    2709           0 : }
    2710             : 
    2711             : /*
    2712             :  * Interrupt handling
    2713             :  */
    2714             : 
    2715             : HAL_BOOL
    2716           0 : ar5k_ar5212_is_intr_pending(struct ath_hal *hal)
    2717             : {
    2718           0 :         return (AR5K_REG_READ(AR5K_AR5212_INTPEND) == 0 ? AH_FALSE : AH_TRUE);
    2719             : }
    2720             : 
    2721             : HAL_BOOL
    2722           0 : ar5k_ar5212_get_isr(struct ath_hal *hal, u_int32_t *interrupt_mask)
    2723             : {
    2724             :         u_int32_t data;
    2725             : 
    2726             :         /*
    2727             :          * Read interrupt status from the Read-And-Clear shadow register
    2728             :          */
    2729           0 :         data = AR5K_REG_READ(AR5K_AR5212_RAC_PISR);
    2730             : 
    2731             :         /*
    2732             :          * Get abstract interrupt mask (HAL-compatible)
    2733             :          */
    2734           0 :         *interrupt_mask = (data & HAL_INT_COMMON) & hal->ah_imr;
    2735             : 
    2736           0 :         if (data == HAL_INT_NOCARD)
    2737           0 :                 return (AH_FALSE);
    2738             : 
    2739           0 :         if (data & (AR5K_AR5212_PISR_RXOK | AR5K_AR5212_PISR_RXERR))
    2740           0 :                 *interrupt_mask |= HAL_INT_RX;
    2741             : 
    2742           0 :         if (data & (AR5K_AR5212_PISR_TXOK | AR5K_AR5212_PISR_TXERR))
    2743           0 :                 *interrupt_mask |= HAL_INT_TX;
    2744             : 
    2745           0 :         if (data & (AR5K_AR5212_PISR_HIUERR))
    2746           0 :                 *interrupt_mask |= HAL_INT_FATAL;
    2747             : 
    2748             :         /*
    2749             :          * Special interrupt handling (not caught by the driver)
    2750             :          */
    2751           0 :         if (((*interrupt_mask) & AR5K_AR5212_PISR_RXPHY) &&
    2752           0 :             hal->ah_radar.r_enabled == AH_TRUE)
    2753           0 :                 ar5k_radar_alert(hal);
    2754             : 
    2755           0 :         if (*interrupt_mask == 0)
    2756           0 :                 AR5K_PRINTF("0x%08x\n", data);
    2757             : 
    2758           0 :         return (AH_TRUE);
    2759           0 : }
    2760             : 
    2761             : u_int32_t
    2762           0 : ar5k_ar5212_get_intr(struct ath_hal *hal)
    2763             : {
    2764             :         /* Return the interrupt mask stored previously */
    2765           0 :         return (hal->ah_imr);
    2766             : }
    2767             : 
    2768             : HAL_INT
    2769           0 : ar5k_ar5212_set_intr(struct ath_hal *hal, HAL_INT new_mask)
    2770             : {
    2771             :         HAL_INT old_mask, int_mask;
    2772             : 
    2773             :         /*
    2774             :          * Disable card interrupts to prevent any race conditions
    2775             :          * (they will be re-enabled afterwards).
    2776             :          */
    2777           0 :         AR5K_REG_WRITE(AR5K_AR5212_IER, AR5K_AR5212_IER_DISABLE);
    2778             : 
    2779           0 :         old_mask = hal->ah_imr;
    2780             : 
    2781             :         /*
    2782             :          * Add additional, chipset-dependent interrupt mask flags
    2783             :          * and write them to the IMR (interrupt mask register).
    2784             :          */
    2785           0 :         int_mask = new_mask & HAL_INT_COMMON;
    2786             : 
    2787           0 :         if (new_mask & HAL_INT_RX)
    2788           0 :                 int_mask |=
    2789             :                     AR5K_AR5212_PIMR_RXOK |
    2790             :                     AR5K_AR5212_PIMR_RXERR |
    2791             :                     AR5K_AR5212_PIMR_RXORN |
    2792             :                     AR5K_AR5212_PIMR_RXDESC;
    2793             : 
    2794           0 :         if (new_mask & HAL_INT_TX)
    2795           0 :                 int_mask |=
    2796             :                     AR5K_AR5212_PIMR_TXOK |
    2797             :                     AR5K_AR5212_PIMR_TXERR |
    2798             :                     AR5K_AR5212_PIMR_TXDESC |
    2799             :                     AR5K_AR5212_PIMR_TXURN;
    2800             : 
    2801           0 :         if (new_mask & HAL_INT_FATAL) {
    2802           0 :                 int_mask |= AR5K_AR5212_PIMR_HIUERR;
    2803           0 :                 AR5K_REG_ENABLE_BITS(AR5K_AR5212_SIMR2,
    2804             :                     AR5K_AR5212_SIMR2_MCABT |
    2805             :                     AR5K_AR5212_SIMR2_SSERR |
    2806             :                     AR5K_AR5212_SIMR2_DPERR);
    2807           0 :         }
    2808             : 
    2809           0 :         AR5K_REG_WRITE(AR5K_AR5212_PIMR, int_mask);
    2810             : 
    2811             :         /* Store new interrupt mask */
    2812           0 :         hal->ah_imr = new_mask;
    2813             : 
    2814             :         /* ..re-enable interrupts */
    2815           0 :         AR5K_REG_WRITE(AR5K_AR5212_IER, AR5K_AR5212_IER_ENABLE);
    2816             : 
    2817           0 :         return (old_mask);
    2818             : }
    2819             : 
    2820             : /*
    2821             :  * Misc internal functions
    2822             :  */
    2823             : 
    2824             : HAL_BOOL
    2825           0 : ar5k_ar5212_get_capabilities(struct ath_hal *hal)
    2826             : {
    2827             :         u_int16_t ee_header;
    2828             :         u_int a, b, g;
    2829             : 
    2830             :         /* Capabilities stored in the EEPROM */
    2831           0 :         ee_header = hal->ah_capabilities.cap_eeprom.ee_header;
    2832             : 
    2833           0 :         a = AR5K_EEPROM_HDR_11A(ee_header);
    2834           0 :         b = AR5K_EEPROM_HDR_11B(ee_header);
    2835           0 :         g = AR5K_EEPROM_HDR_11G(ee_header);
    2836             : 
    2837             :         /*
    2838             :          * If the EEPROM is not reporting any mode, we try 11b.
    2839             :          * This might fix a few broken devices with invalid EEPROM.
    2840             :          */
    2841           0 :         if (!a && !b && !g)
    2842           0 :                 b = 1;
    2843             : 
    2844             :         /*
    2845             :          * XXX The AR5212 tranceiver supports frequencies from 4920 to 6100GHz
    2846             :          * XXX and from 2312 to 2732GHz. There are problems with the current
    2847             :          * XXX ieee80211 implementation because the IEEE channel mapping
    2848             :          * XXX does not support negative channel numbers (2312MHz is channel
    2849             :          * XXX -19). Of course, this doesn't matter because these channels
    2850             :          * XXX are out of range but some regulation domains like MKK (Japan)
    2851             :          * XXX will support frequencies somewhere around 4.8GHz.
    2852             :          */
    2853             : 
    2854             :         /*
    2855             :          * Set radio capabilities
    2856             :          */
    2857             : 
    2858           0 :         if (a) {
    2859           0 :                 hal->ah_capabilities.cap_range.range_5ghz_min = 5005; /* 4920 */
    2860           0 :                 hal->ah_capabilities.cap_range.range_5ghz_max = 6100;
    2861             : 
    2862             :                 /* Set supported modes */
    2863           0 :                 hal->ah_capabilities.cap_mode =
    2864             :                     HAL_MODE_11A | HAL_MODE_TURBO | HAL_MODE_XR;
    2865           0 :         }
    2866             : 
    2867             :         /* This chip will support 802.11b if the 2GHz radio is connected */
    2868           0 :         if (b || g) {
    2869           0 :                 hal->ah_capabilities.cap_range.range_2ghz_min = 2412; /* 2312 */
    2870           0 :                 hal->ah_capabilities.cap_range.range_2ghz_max = 2732;
    2871             : 
    2872           0 :                 if (b)
    2873           0 :                         hal->ah_capabilities.cap_mode |= HAL_MODE_11B;
    2874             : #if 0
    2875             :                 if (g)
    2876             :                         hal->ah_capabilities.cap_mode |= HAL_MODE_11G;
    2877             : #endif
    2878             :         }
    2879             : 
    2880             :         /* GPIO */
    2881           0 :         hal->ah_gpio_npins = AR5K_AR5212_NUM_GPIO;
    2882             : 
    2883             :         /* Set number of supported TX queues */
    2884           0 :         hal->ah_capabilities.cap_queues.q_tx_num = AR5K_AR5212_TX_NUM_QUEUES;
    2885             : 
    2886           0 :         return (AH_TRUE);
    2887             : }
    2888             : 
    2889             : void
    2890           0 : ar5k_ar5212_radar_alert(struct ath_hal *hal, HAL_BOOL enable)
    2891             : {
    2892             :         /*
    2893             :          * Enable radar detection
    2894             :          */
    2895           0 :         AR5K_REG_WRITE(AR5K_AR5212_IER, AR5K_AR5212_IER_DISABLE);
    2896             : 
    2897           0 :         if (enable == AH_TRUE) {
    2898           0 :                 AR5K_REG_WRITE(AR5K_AR5212_PHY_RADAR,
    2899             :                     AR5K_AR5212_PHY_RADAR_ENABLE);
    2900           0 :                 AR5K_REG_ENABLE_BITS(AR5K_AR5212_PIMR,
    2901             :                     AR5K_AR5212_PIMR_RXPHY);
    2902           0 :         } else {
    2903           0 :                 AR5K_REG_WRITE(AR5K_AR5212_PHY_RADAR,
    2904             :                     AR5K_AR5212_PHY_RADAR_DISABLE);
    2905           0 :                 AR5K_REG_DISABLE_BITS(AR5K_AR5212_PIMR,
    2906             :                     AR5K_AR5212_PIMR_RXPHY);
    2907             :         }
    2908             : 
    2909           0 :         AR5K_REG_WRITE(AR5K_AR5212_IER, AR5K_AR5212_IER_ENABLE);
    2910           0 : }
    2911             : 
    2912             : /*
    2913             :  * EEPROM access functions
    2914             :  */
    2915             : 
    2916             : HAL_BOOL
    2917           0 : ar5k_ar5212_eeprom_is_busy(struct ath_hal *hal)
    2918             : {
    2919           0 :         return (AR5K_REG_READ(AR5K_AR5212_CFG) & AR5K_AR5212_CFG_EEBS ?
    2920             :             AH_TRUE : AH_FALSE);
    2921             : }
    2922             : 
    2923             : int
    2924           0 : ar5k_ar5212_eeprom_read(struct ath_hal *hal, u_int32_t offset, u_int16_t *data)
    2925             : {
    2926             :         u_int32_t status, i;
    2927             : 
    2928             :         /*
    2929             :          * Initialize EEPROM access
    2930             :          */
    2931           0 :         AR5K_REG_WRITE(AR5K_AR5212_EEPROM_BASE, (u_int8_t)offset);
    2932           0 :         AR5K_REG_ENABLE_BITS(AR5K_AR5212_EEPROM_CMD,
    2933             :             AR5K_AR5212_EEPROM_CMD_READ);
    2934             : 
    2935           0 :         for (i = AR5K_TUNE_REGISTER_TIMEOUT; i > 0; i--) {
    2936           0 :                 status = AR5K_REG_READ(AR5K_AR5212_EEPROM_STATUS);
    2937           0 :                 if (status & AR5K_AR5212_EEPROM_STAT_RDDONE) {
    2938           0 :                         if (status & AR5K_AR5212_EEPROM_STAT_RDERR)
    2939           0 :                                 return (EIO);
    2940           0 :                         *data = (u_int16_t)
    2941           0 :                             (AR5K_REG_READ(AR5K_AR5212_EEPROM_DATA) & 0xffff);
    2942           0 :                         return (0);
    2943             :                 }
    2944           0 :                 AR5K_DELAY(15);
    2945             :         }
    2946             : 
    2947           0 :         return (ETIMEDOUT);
    2948           0 : }
    2949             : 
    2950             : int
    2951           0 : ar5k_ar5212_eeprom_write(struct ath_hal *hal, u_int32_t offset, u_int16_t data)
    2952             : {
    2953             :         u_int32_t status, timeout;
    2954             : 
    2955             :         /* Enable eeprom access */
    2956           0 :         AR5K_REG_ENABLE_BITS(AR5K_AR5212_EEPROM_CMD,
    2957             :             AR5K_AR5212_EEPROM_CMD_RESET);
    2958           0 :         AR5K_REG_ENABLE_BITS(AR5K_AR5212_EEPROM_CMD,
    2959             :             AR5K_AR5212_EEPROM_CMD_WRITE);
    2960             : 
    2961             :         /*
    2962             :          * Prime write pump
    2963             :          */
    2964           0 :         AR5K_REG_WRITE(AR5K_AR5212_EEPROM_BASE, (u_int8_t)offset - 1);
    2965             : 
    2966           0 :         for (timeout = 10000; timeout > 0; timeout--) {
    2967           0 :                 AR5K_DELAY(1);
    2968           0 :                 status = AR5K_REG_READ(AR5K_AR5212_EEPROM_STATUS);
    2969           0 :                 if (status & AR5K_AR5212_EEPROM_STAT_WRDONE) {
    2970           0 :                         if (status & AR5K_AR5212_EEPROM_STAT_WRERR)
    2971           0 :                                 return (EIO);
    2972           0 :                         return (0);
    2973             :                 }
    2974             :         }
    2975             : 
    2976           0 :         return (ETIMEDOUT);
    2977           0 : }
    2978             : 
    2979             : /*
    2980             :  * TX power setup
    2981             :  */
    2982             : 
    2983             : HAL_BOOL
    2984           0 : ar5k_ar5212_txpower(struct ath_hal *hal, HAL_CHANNEL *channel, u_int txpower)
    2985             : {
    2986           0 :         HAL_BOOL tpc = hal->ah_txpower.txp_tpc;
    2987             :         int i;
    2988             : 
    2989           0 :         if (txpower > AR5K_TUNE_MAX_TXPOWER) {
    2990           0 :                 AR5K_PRINTF("invalid tx power: %u\n", txpower);
    2991           0 :                 return (AH_FALSE);
    2992             :         }
    2993             : 
    2994             :         /* Reset TX power values */
    2995           0 :         bzero(&hal->ah_txpower, sizeof(hal->ah_txpower));
    2996           0 :         hal->ah_txpower.txp_tpc = tpc;
    2997             : 
    2998             :         /* Initialize TX power table */
    2999           0 :         ar5k_txpower_table(hal, channel, txpower);
    3000             : 
    3001             :         /* 
    3002             :          * Write TX power values
    3003             :          */
    3004           0 :         for (i = 0; i < (AR5K_EEPROM_POWER_TABLE_SIZE / 2); i++) {
    3005           0 :                 AR5K_REG_WRITE(AR5K_AR5212_PHY_PCDAC_TXPOWER(i),
    3006             :                     ((((hal->ah_txpower.txp_pcdac[(i << 1) + 1] << 8) | 0xff) &
    3007             :                     0xffff) << 16) | (((hal->ah_txpower.txp_pcdac[i << 1] << 8)
    3008             :                     | 0xff) & 0xffff));
    3009             :         }
    3010             : 
    3011           0 :         AR5K_REG_WRITE(AR5K_AR5212_PHY_TXPOWER_RATE1,
    3012             :             AR5K_TXPOWER_OFDM(3, 24) | AR5K_TXPOWER_OFDM(2, 16)
    3013             :             | AR5K_TXPOWER_OFDM(1, 8) | AR5K_TXPOWER_OFDM(0, 0));
    3014             : 
    3015           0 :         AR5K_REG_WRITE(AR5K_AR5212_PHY_TXPOWER_RATE2,
    3016             :             AR5K_TXPOWER_OFDM(7, 24) | AR5K_TXPOWER_OFDM(6, 16)
    3017             :             | AR5K_TXPOWER_OFDM(5, 8) | AR5K_TXPOWER_OFDM(4, 0));
    3018             : 
    3019           0 :         AR5K_REG_WRITE(AR5K_AR5212_PHY_TXPOWER_RATE3,
    3020             :             AR5K_TXPOWER_CCK(10, 24) | AR5K_TXPOWER_CCK(9, 16)
    3021             :             | AR5K_TXPOWER_CCK(15, 8) | AR5K_TXPOWER_CCK(8, 0));
    3022             : 
    3023           0 :         AR5K_REG_WRITE(AR5K_AR5212_PHY_TXPOWER_RATE4,
    3024             :             AR5K_TXPOWER_CCK(14, 24) | AR5K_TXPOWER_CCK(13, 16)
    3025             :             | AR5K_TXPOWER_CCK(12, 8) | AR5K_TXPOWER_CCK(11, 0));
    3026             : 
    3027           0 :         if (hal->ah_txpower.txp_tpc == AH_TRUE) {
    3028           0 :                 AR5K_REG_WRITE(AR5K_AR5212_PHY_TXPOWER_RATE_MAX,
    3029             :                     AR5K_AR5212_PHY_TXPOWER_RATE_MAX_TPC_ENABLE |
    3030             :                     AR5K_TUNE_MAX_TXPOWER);
    3031           0 :         } else {
    3032           0 :                 AR5K_REG_WRITE(AR5K_AR5212_PHY_TXPOWER_RATE_MAX,
    3033             :                     AR5K_AR5212_PHY_TXPOWER_RATE_MAX |
    3034             :                     AR5K_TUNE_MAX_TXPOWER);
    3035             :         }
    3036             : 
    3037           0 :         return (AH_TRUE);
    3038           0 : }
    3039             : 
    3040             : HAL_BOOL
    3041           0 : ar5k_ar5212_set_txpower_limit(struct ath_hal *hal, u_int power)
    3042             : {
    3043           0 :         HAL_CHANNEL *channel = &hal->ah_current_channel;
    3044             : 
    3045           0 :         AR5K_PRINTF("changing txpower to %d\n", power);
    3046           0 :         return (ar5k_ar5212_txpower(hal, channel, power));
    3047             : }

Generated by: LCOV version 1.13