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

          Line data    Source code
       1             : /*      $OpenBSD: ar5xxx.c,v 1.63 2018/01/31 11:27:03 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 Atheros Wireless LAN devices.
      21             :  * (Please have a look at ar5xxx.h for further information)
      22             :  */
      23             : 
      24             : #include <dev/pci/pcidevs.h>
      25             : #include <dev/ic/ar5xxx.h>
      26             : 
      27             : extern ar5k_attach_t ar5k_ar5210_attach;
      28             : extern ar5k_attach_t ar5k_ar5211_attach;
      29             : extern ar5k_attach_t ar5k_ar5212_attach;
      30             : 
      31             : static const struct {
      32             :         u_int16_t       vendor;
      33             :         u_int16_t       device;
      34             :         ar5k_attach_t   (*attach);
      35             : } ar5k_known_products[] = {
      36             :         /*
      37             :          * From pcidevs_data.h
      38             :          */
      39             :         { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5210,
      40             :             ar5k_ar5210_attach },
      41             :         { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5210_AP,
      42             :             ar5k_ar5210_attach },
      43             :         { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5210_DEFAULT,
      44             :             ar5k_ar5210_attach },
      45             :         { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5211,
      46             :             ar5k_ar5211_attach },
      47             :         { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5211_DEFAULT,
      48             :             ar5k_ar5211_attach },
      49             :         { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5311,
      50             :             ar5k_ar5211_attach },
      51             :         { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5211_FPGA11B,
      52             :             ar5k_ar5211_attach },
      53             :         { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5211_LEGACY,
      54             :             ar5k_ar5211_attach },
      55             :         { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5212,
      56             :             ar5k_ar5212_attach },
      57             :         { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5212_DEFAULT,
      58             :             ar5k_ar5212_attach },
      59             :         { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5212_FPGA,
      60             :             ar5k_ar5212_attach },
      61             :         { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5212_IBM,
      62             :             ar5k_ar5212_attach },
      63             :         { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR2413,
      64             :             ar5k_ar5212_attach },
      65             :         { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5413,
      66             :             ar5k_ar5212_attach },
      67             :         { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5424,
      68             :             ar5k_ar5212_attach },
      69             :         { PCI_VENDOR_3COM, PCI_PRODUCT_3COM_3CRDAG675,
      70             :             ar5k_ar5212_attach },
      71             :         { PCI_VENDOR_3COM2, PCI_PRODUCT_3COM2_3CRPAG175,
      72             :             ar5k_ar5212_attach }
      73             : };
      74             : 
      75             : static const HAL_RATE_TABLE ar5k_rt_11a = AR5K_RATES_11A;
      76             : static const HAL_RATE_TABLE ar5k_rt_11b = AR5K_RATES_11B;
      77             : static const HAL_RATE_TABLE ar5k_rt_11g = AR5K_RATES_11G;
      78             : static const HAL_RATE_TABLE ar5k_rt_xr = AR5K_RATES_XR;
      79             : 
      80             : int              ar5k_eeprom_read_ants(struct ath_hal *, u_int32_t *, u_int);
      81             : int              ar5k_eeprom_read_modes(struct ath_hal *, u_int32_t *, u_int);
      82             : u_int16_t        ar5k_eeprom_bin2freq(struct ath_hal *, u_int16_t, u_int);
      83             : 
      84             : HAL_BOOL         ar5k_ar5110_channel(struct ath_hal *, HAL_CHANNEL *);
      85             : u_int32_t        ar5k_ar5110_chan2athchan(HAL_CHANNEL *);
      86             : HAL_BOOL         ar5k_ar5111_channel(struct ath_hal *, HAL_CHANNEL *);
      87             : HAL_BOOL         ar5k_ar5111_chan2athchan(u_int, struct ar5k_athchan_2ghz *);
      88             : HAL_BOOL         ar5k_ar5112_channel(struct ath_hal *, HAL_CHANNEL *);
      89             : HAL_BOOL         ar5k_check_channel(struct ath_hal *, u_int16_t, u_int flags);
      90             : 
      91             : HAL_BOOL         ar5k_ar5111_rfregs(struct ath_hal *, HAL_CHANNEL *, u_int);
      92             : HAL_BOOL         ar5k_ar5112_rfregs(struct ath_hal *, HAL_CHANNEL *, u_int);
      93             : HAL_BOOL         ar5k_arxxxx_rfregs(struct ath_hal *, HAL_CHANNEL *, u_int);
      94             : u_int            ar5k_rfregs_op(u_int32_t *, u_int32_t, u_int32_t, u_int32_t,
      95             :     u_int32_t, u_int32_t, HAL_BOOL);
      96             : 
      97             : /*
      98             :  * Supported channels
      99             :  */
     100             : static const struct
     101             : ieee80211_regchannel ar5k_5ghz_channels[] = IEEE80211_CHANNELS_5GHZ;
     102             : static const struct
     103             : ieee80211_regchannel ar5k_2ghz_channels[] = IEEE80211_CHANNELS_2GHZ;
     104             : 
     105             : /*
     106             :  * Initial gain optimization values
     107             :  */
     108             : static const struct ar5k_gain_opt ar5111_gain_opt = AR5K_AR5111_GAIN_OPT;
     109             : static const struct ar5k_gain_opt ar5112_gain_opt = AR5K_AR5112_GAIN_OPT;
     110             : 
     111             : /*
     112             :  * Initial register for the radio chipsets
     113             :  */
     114             : static const struct ar5k_ini_rf ar5111_rf[] = AR5K_AR5111_INI_RF;
     115             : static const struct ar5k_ini_rf ar5112_rf[] = AR5K_AR5112_INI_RF;
     116             : static const struct ar5k_ini_rf ar5112a_rf[] = AR5K_AR5112A_INI_RF;
     117             : static const struct ar5k_ini_rf ar5413_rf[] = AR5K_AR5413_INI_RF;
     118             : static const struct ar5k_ini_rf ar2413_rf[] = AR5K_AR2413_INI_RF;
     119             : static const struct ar5k_ini_rf ar2425_rf[] = AR5K_AR2425_INI_RF;
     120             : static const struct ar5k_ini_rfgain ar5111_rfg[] = AR5K_AR5111_INI_RFGAIN;
     121             : static const struct ar5k_ini_rfgain ar5112_rfg[] = AR5K_AR5112_INI_RFGAIN;
     122             : static const struct ar5k_ini_rfgain ar5413_rfg[] = AR5K_AR5413_INI_RFGAIN;
     123             : static const struct ar5k_ini_rfgain ar2413_rfg[] = AR5K_AR2413_INI_RFGAIN;
     124             : 
     125             : /*
     126             :  * Enable to overwrite the country code (use "00" for debug)
     127             :  */
     128             : #if 0
     129             : #define COUNTRYCODE "00"
     130             : #endif
     131             : 
     132             : /*
     133             :  * Perform a lookup if the device is supported by the HAL
     134             :  */
     135             : const char *
     136           0 : ath_hal_probe(u_int16_t vendor, u_int16_t device)
     137             : {
     138             :         int i;
     139             : 
     140             :         /*
     141             :          * Perform a linear search on the table of supported devices
     142             :          */
     143           0 :         for (i = 0; i < nitems(ar5k_known_products); i++) {
     144           0 :                 if (vendor == ar5k_known_products[i].vendor &&
     145           0 :                     device == ar5k_known_products[i].device)
     146           0 :                         return ("");
     147             :         }
     148             : 
     149           0 :         return (NULL);
     150           0 : }
     151             : 
     152             : /*
     153             :  * Fills in the HAL structure and initialises the device
     154             :  */
     155             : struct ath_hal *
     156           0 : ath_hal_attach(u_int16_t device, void *arg, bus_space_tag_t st,
     157             :     bus_space_handle_t sh, u_int is_pcie, int *status)
     158             : {
     159           0 :         struct ath_softc *sc = (struct ath_softc *)arg;
     160             :         struct ath_hal *hal = NULL;
     161             :         ar5k_attach_t *attach = NULL;
     162           0 :         u_int8_t mac[IEEE80211_ADDR_LEN];
     163             :         int i;
     164             : 
     165           0 :         *status = EINVAL;
     166             : 
     167             :         /*
     168             :          * Call the chipset-dependent attach routine by device id
     169             :          */
     170           0 :         for (i = 0; i < nitems(ar5k_known_products); i++) {
     171           0 :                 if (device == ar5k_known_products[i].device &&
     172           0 :                     ar5k_known_products[i].attach != NULL)
     173           0 :                         attach = ar5k_known_products[i].attach;
     174             :         }
     175             : 
     176           0 :         if (attach == NULL) {
     177           0 :                 *status = ENXIO;
     178           0 :                 AR5K_PRINTF("device not supported: 0x%04x\n", device);
     179           0 :                 return (NULL);
     180             :         }
     181             : 
     182           0 :         if ((hal = malloc(sizeof(struct ath_hal),
     183           0 :                  M_DEVBUF, M_NOWAIT | M_ZERO)) == NULL) {
     184           0 :                 *status = ENOMEM;
     185           0 :                 AR5K_PRINT("out of memory\n");
     186           0 :                 return (NULL);
     187             :         }
     188             : 
     189           0 :         hal->ah_sc = sc;
     190           0 :         hal->ah_st = st;
     191           0 :         hal->ah_sh = sh;
     192           0 :         hal->ah_device = device;
     193           0 :         hal->ah_sub_vendor = 0; /* XXX unknown?! */
     194             : 
     195             :         /*
     196             :          * HAL information
     197             :          */
     198           0 :         hal->ah_abi = HAL_ABI_VERSION;
     199           0 :         hal->ah_op_mode = HAL_M_STA;
     200           0 :         hal->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT;
     201           0 :         hal->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
     202           0 :         hal->ah_imr = 0;
     203           0 :         hal->ah_atim_window = 0;
     204           0 :         hal->ah_aifs = AR5K_TUNE_AIFS;
     205           0 :         hal->ah_cw_min = AR5K_TUNE_CWMIN;
     206           0 :         hal->ah_limit_tx_retries = AR5K_INIT_TX_RETRY;
     207           0 :         hal->ah_software_retry = AH_FALSE;
     208           0 :         hal->ah_ant_diversity = AR5K_TUNE_ANT_DIVERSITY;
     209           0 :         hal->ah_pci_express = is_pcie ? AH_TRUE : AH_FALSE;
     210             : 
     211           0 :         switch (device) {
     212             :         case PCI_PRODUCT_ATHEROS_AR2413:
     213             :         case PCI_PRODUCT_ATHEROS_AR5413:
     214             :         case PCI_PRODUCT_ATHEROS_AR5424:
     215             :                 /*
     216             :                  * Known single chip solutions
     217             :                  */
     218           0 :                 hal->ah_single_chip = AH_TRUE;
     219           0 :                 break;
     220             :         default:
     221             :                 /*
     222             :                  * Multi chip solutions
     223             :                  */
     224           0 :                 hal->ah_single_chip = AH_FALSE;
     225           0 :                 break;
     226             :         }
     227             : 
     228           0 :         if ((attach)(device, hal, st, sh, status) == NULL)
     229             :                 goto failed;
     230             : 
     231             : #ifdef AR5K_DEBUG
     232             :         hal->ah_dump_state(hal);
     233             : #endif
     234             : 
     235             :         /*
     236             :          * Get card capabilities, values, ...
     237             :          */
     238             : 
     239           0 :         if (ar5k_eeprom_init(hal) != 0) {
     240           0 :                 AR5K_PRINT("unable to init EEPROM\n");
     241           0 :                 goto failed;
     242             :         }
     243             : 
     244             :         /* Get misc capabilities */
     245           0 :         if (hal->ah_get_capabilities(hal) != AH_TRUE) {
     246           0 :                 AR5K_PRINTF("unable to get device capabilities: 0x%04x\n",
     247             :                     device);
     248           0 :                 goto failed;
     249             :         }
     250             : 
     251             :         /* Get MAC address */
     252           0 :         if ((*status = ar5k_eeprom_read_mac(hal, mac)) != 0) {
     253           0 :                 AR5K_PRINTF("unable to read address from EEPROM: 0x%04x\n",
     254             :                     device);
     255           0 :                 goto failed;
     256             :         }
     257             : 
     258           0 :         hal->ah_set_lladdr(hal, mac);
     259             : 
     260             :         /* Get rate tables */
     261           0 :         if (hal->ah_capabilities.cap_mode & HAL_MODE_11A)
     262           0 :                 ar5k_rt_copy(&hal->ah_rt_11a, &ar5k_rt_11a);
     263           0 :         if (hal->ah_capabilities.cap_mode & HAL_MODE_11B)
     264           0 :                 ar5k_rt_copy(&hal->ah_rt_11b, &ar5k_rt_11b);
     265           0 :         if (hal->ah_capabilities.cap_mode & HAL_MODE_11G)
     266           0 :                 ar5k_rt_copy(&hal->ah_rt_11g, &ar5k_rt_11g);
     267           0 :         if (hal->ah_capabilities.cap_mode & HAL_MODE_XR)
     268           0 :                 ar5k_rt_copy(&hal->ah_rt_xr, &ar5k_rt_xr);
     269             : 
     270             :         /* Initialize the gain optimization values */
     271           0 :         if (hal->ah_radio == AR5K_AR5111) {
     272           0 :                 hal->ah_gain.g_step_idx = ar5111_gain_opt.go_default;
     273           0 :                 hal->ah_gain.g_step =
     274             :                     &ar5111_gain_opt.go_step[hal->ah_gain.g_step_idx];
     275           0 :                 hal->ah_gain.g_low = 20;
     276           0 :                 hal->ah_gain.g_high = 35;
     277           0 :                 hal->ah_gain.g_active = 1;
     278           0 :         } else if (hal->ah_radio == AR5K_AR5112) {
     279           0 :                 hal->ah_gain.g_step_idx = ar5112_gain_opt.go_default;
     280           0 :                 hal->ah_gain.g_step =
     281             :                     &ar5112_gain_opt.go_step[hal->ah_gain.g_step_idx];
     282           0 :                 hal->ah_gain.g_low = 20;
     283           0 :                 hal->ah_gain.g_high = 85;
     284           0 :                 hal->ah_gain.g_active = 1;
     285           0 :         } else {
     286             :                 /* XXX not needed for newer chipsets? */
     287             :         }
     288             : 
     289           0 :         *status = HAL_OK;
     290             : 
     291           0 :         return (hal);
     292             : 
     293             :  failed:
     294           0 :         free(hal, M_DEVBUF, 0);
     295           0 :         return (NULL);
     296           0 : }
     297             : 
     298             : u_int16_t
     299           0 : ath_hal_computetxtime(struct ath_hal *hal, const HAL_RATE_TABLE *rates,
     300             :     u_int32_t frame_length, u_int16_t rate_index, HAL_BOOL short_preamble)
     301             : {
     302             :         const HAL_RATE *rate;
     303             :         u_int32_t value;
     304             : 
     305           0 :         AR5K_ASSERT_ENTRY(rate_index, rates->rateCount);
     306             : 
     307             :         /*
     308             :          * Get rate by index
     309             :          */
     310           0 :         rate = &rates->info[rate_index];
     311             : 
     312             :         /*
     313             :          * Calculate the transmission time by operation (PHY) mode
     314             :          */
     315           0 :         switch (rate->phy) {
     316             :         case IEEE80211_T_CCK:
     317             :                 /*
     318             :                  * CCK / DS mode (802.11b)
     319             :                  */
     320           0 :                 value = AR5K_CCK_TX_TIME(rate->rateKbps, frame_length,
     321             :                     (short_preamble && rate->shortPreamble));
     322           0 :                 break;
     323             : 
     324             :         case IEEE80211_T_OFDM:
     325             :                 /*
     326             :                  * Orthogonal Frequency Division Multiplexing
     327             :                  */
     328           0 :                 if (AR5K_OFDM_NUM_BITS_PER_SYM(rate->rateKbps) == 0)
     329           0 :                         return (0);
     330           0 :                 value = AR5K_OFDM_TX_TIME(rate->rateKbps, frame_length);
     331           0 :                 break;
     332             : 
     333             :         case IEEE80211_T_XR:
     334             :                 /*
     335             :                  * Orthogonal Frequency Division Multiplexing
     336             :                  * Atheros "eXtended Range" (XR)
     337             :                  */
     338           0 :                 if (AR5K_XR_NUM_BITS_PER_SYM(rate->rateKbps) == 0)
     339           0 :                         return (0);
     340           0 :                 value = AR5K_XR_TX_TIME(rate->rateKbps, frame_length);
     341           0 :                 break;
     342             : 
     343             :         default:
     344           0 :                 return (0);
     345             :         }
     346             : 
     347           0 :         return (value);
     348           0 : }
     349             : 
     350             : HAL_BOOL
     351           0 : ar5k_check_channel(struct ath_hal *hal, u_int16_t freq, u_int flags)
     352             : {
     353             :         /* Check if the channel is in our supported range */
     354           0 :         if (flags & IEEE80211_CHAN_2GHZ) {
     355           0 :                 if ((freq >= hal->ah_capabilities.cap_range.range_2ghz_min) &&
     356           0 :                     (freq <= hal->ah_capabilities.cap_range.range_2ghz_max))
     357           0 :                         return (AH_TRUE);
     358           0 :         } else if (flags & IEEE80211_CHAN_5GHZ) {
     359           0 :                 if ((freq >= hal->ah_capabilities.cap_range.range_5ghz_min) &&
     360           0 :                     (freq <= hal->ah_capabilities.cap_range.range_5ghz_max))
     361           0 :                         return (AH_TRUE);
     362             :         }
     363             : 
     364           0 :         return (AH_FALSE);
     365           0 : }
     366             : 
     367             : HAL_BOOL
     368           0 : ath_hal_init_channels(struct ath_hal *hal, HAL_CHANNEL *channels,
     369             :     u_int max_channels, u_int *channels_size, u_int16_t mode,
     370             :     HAL_BOOL outdoor, HAL_BOOL extended)
     371             : {
     372             :         u_int i, c;
     373             :         u_int32_t domain_current;
     374             :         u_int domain_5ghz, domain_2ghz;
     375             :         HAL_CHANNEL *all_channels;
     376             : 
     377           0 :         if ((all_channels = mallocarray(max_channels, sizeof(HAL_CHANNEL),
     378           0 :             M_TEMP, M_NOWAIT | M_ZERO)) == NULL)
     379           0 :                 return (AH_FALSE);
     380             : 
     381             :         i = c = 0;
     382           0 :         domain_current = hal->ah_regdomain;
     383             : 
     384             :         /*
     385             :          * In debugging mode, enable all channels supported by the chipset
     386             :          */
     387           0 :         if (domain_current == DMN_DEFAULT) {
     388             :                 int min, max, freq;
     389             :                 u_int flags;
     390             : 
     391           0 :                 min = ieee80211_mhz2ieee(IEEE80211_CHANNELS_2GHZ_MIN,
     392             :                     IEEE80211_CHAN_2GHZ);
     393           0 :                 max = ieee80211_mhz2ieee(IEEE80211_CHANNELS_2GHZ_MAX,
     394             :                     IEEE80211_CHAN_2GHZ);
     395           0 :                 flags = CHANNEL_B |
     396           0 :                     (hal->ah_version == AR5K_AR5211 ?
     397             :                     CHANNEL_PUREG : CHANNEL_G);
     398             : 
     399             :  debugchan:
     400           0 :                 for (i = min; i <= max && c < max_channels; i++) {
     401           0 :                         freq = ieee80211_ieee2mhz(i, flags);
     402           0 :                         if (ar5k_check_channel(hal, freq, flags) == AH_FALSE)
     403             :                                 continue;
     404           0 :                         all_channels[c].c_channel = freq;
     405           0 :                         all_channels[c++].c_channel_flags = flags;
     406           0 :                 }
     407             : 
     408           0 :                 if (flags & IEEE80211_CHAN_2GHZ) {
     409           0 :                         min = ieee80211_mhz2ieee(IEEE80211_CHANNELS_5GHZ_MIN,
     410             :                             IEEE80211_CHAN_5GHZ);
     411           0 :                         max = ieee80211_mhz2ieee(IEEE80211_CHANNELS_5GHZ_MAX,
     412             :                             IEEE80211_CHAN_5GHZ);
     413             :                         flags = CHANNEL_A | CHANNEL_XR;
     414           0 :                         goto debugchan;
     415             :                 }
     416             : 
     417             :                 goto done;
     418             :         }
     419             : 
     420           0 :         domain_5ghz = ieee80211_regdomain2flag(domain_current,
     421             :             IEEE80211_CHANNELS_5GHZ_MIN);
     422           0 :         domain_2ghz = ieee80211_regdomain2flag(domain_current,
     423             :             IEEE80211_CHANNELS_2GHZ_MIN);
     424             : 
     425             :         /*
     426             :          * Create channel list based on chipset capabilities, regulation domain
     427             :          * and mode. 5GHz...
     428             :          */
     429           0 :         for (i = 0; (hal->ah_capabilities.cap_range.range_5ghz_max > 0) &&
     430           0 :                  (i < nitems(ar5k_5ghz_channels)) &&
     431           0 :                  (c < max_channels); i++) {
     432             :                 /* Check if channel is supported by the chipset */
     433           0 :                 if (ar5k_check_channel(hal,
     434           0 :                     ar5k_5ghz_channels[i].rc_channel,
     435           0 :                     IEEE80211_CHAN_5GHZ) == AH_FALSE)
     436             :                         continue;
     437             : 
     438             :                 /* Match regulation domain */
     439           0 :                 if ((IEEE80211_DMN(ar5k_5ghz_channels[i].rc_domain) &
     440           0 :                         IEEE80211_DMN(domain_5ghz)) == 0)
     441             :                         continue;
     442             : 
     443             :                 /* Match modes */
     444           0 :                 if (ar5k_5ghz_channels[i].rc_mode & IEEE80211_CHAN_OFDM)
     445           0 :                         all_channels[c].c_channel_flags = CHANNEL_A;
     446             :                 else
     447             :                         continue;
     448             : 
     449             :                 /* Write channel and increment counter */
     450           0 :                 all_channels[c++].channel = ar5k_5ghz_channels[i].rc_channel;
     451           0 :         }
     452             : 
     453             :         /*
     454             :          * ...and 2GHz.
     455             :          */
     456           0 :         for (i = 0; (hal->ah_capabilities.cap_range.range_2ghz_max > 0) &&
     457           0 :                  (i < nitems(ar5k_2ghz_channels)) &&
     458           0 :                  (c < max_channels); i++) {
     459             :                 /* Check if channel is supported by the chipset */
     460           0 :                 if (ar5k_check_channel(hal,
     461           0 :                     ar5k_2ghz_channels[i].rc_channel,
     462           0 :                     IEEE80211_CHAN_2GHZ) == AH_FALSE)
     463             :                         continue;
     464             : 
     465             :                 /* Match regulation domain */
     466           0 :                 if ((IEEE80211_DMN(ar5k_2ghz_channels[i].rc_domain) &
     467           0 :                         IEEE80211_DMN(domain_2ghz)) == 0)
     468             :                         continue;
     469             : 
     470             :                 /* Match modes */
     471           0 :                 if ((hal->ah_capabilities.cap_mode & HAL_MODE_11B) &&
     472           0 :                     (ar5k_2ghz_channels[i].rc_mode & IEEE80211_CHAN_CCK))
     473           0 :                         all_channels[c].c_channel_flags = CHANNEL_B;
     474             : 
     475           0 :                 if (hal->ah_capabilities.cap_mode & HAL_MODE_11G) {
     476           0 :                         if (ar5k_2ghz_channels[i].rc_mode & IEEE80211_CHAN_CCK)
     477           0 :                             all_channels[c].c_channel_flags = CHANNEL_B;
     478           0 :                         if (ar5k_2ghz_channels[i].rc_mode & IEEE80211_CHAN_OFDM)
     479           0 :                                 all_channels[c].c_channel_flags |= (CHANNEL_G | CHANNEL_PUREG);
     480             :                 }
     481             : 
     482             :                 /* Write channel and increment counter */
     483           0 :                 all_channels[c++].channel = ar5k_2ghz_channels[i].rc_channel;
     484           0 :         }
     485             : 
     486             :  done:
     487           0 :         bcopy(all_channels, channels, sizeof(HAL_CHANNEL) * max_channels);
     488           0 :         *channels_size = c;
     489           0 :         free(all_channels, M_TEMP, 0);
     490           0 :         return (AH_TRUE);
     491           0 : }
     492             : 
     493             : /*
     494             :  * Common internal functions
     495             :  */
     496             : 
     497             : const char *
     498           0 : ar5k_printver(enum ar5k_srev_type type, u_int32_t val)
     499             : {
     500           0 :         struct ar5k_srev_name names[] = AR5K_SREV_NAME;
     501             :         const char *name = "xxxx";
     502             :         int i;
     503             : 
     504           0 :         for (i = 0; i < nitems(names); i++) {
     505           0 :                 if (type == AR5K_VERSION_DEV) {
     506           0 :                         if (names[i].sr_type == type &&
     507           0 :                             names[i].sr_val == val) {
     508           0 :                                 name = names[i].sr_name;
     509           0 :                                 break;
     510             :                         }
     511             :                         continue;
     512             :                 }
     513           0 :                 if (names[i].sr_type != type ||
     514           0 :                     names[i].sr_val == AR5K_SREV_UNKNOWN)
     515             :                         continue;
     516             :                 /*
     517             :                  * The final iteration has names[i].sr_val == AR5K_SREV_UNKNOWN,
     518             :                  * so there is no out-of-bounds access with names[i + 1] below.
     519             :                  */
     520           0 :                 if ((val & 0xff) < names[i + 1].sr_val) {
     521           0 :                         name = names[i].sr_name;
     522           0 :                         break;
     523             :                 }
     524             :         }
     525             : 
     526           0 :         return (name);
     527           0 : }
     528             : 
     529             : void
     530           0 : ar5k_radar_alert(struct ath_hal *hal)
     531             : {
     532             :         /*
     533             :          * Limit ~1/s
     534             :          */
     535           0 :         if (hal->ah_radar.r_last_channel.channel ==
     536           0 :             hal->ah_current_channel.channel &&
     537           0 :             tick < (hal->ah_radar.r_last_alert + hz))
     538             :                 return;
     539             : 
     540           0 :         hal->ah_radar.r_last_channel.channel =
     541           0 :             hal->ah_current_channel.channel;
     542           0 :         hal->ah_radar.r_last_channel.c_channel_flags =
     543           0 :             hal->ah_current_channel.c_channel_flags;
     544           0 :         hal->ah_radar.r_last_alert = tick;
     545             : 
     546           0 :         AR5K_PRINTF("Possible radar activity detected at %u MHz (tick %u)\n",
     547             :             hal->ah_radar.r_last_alert, hal->ah_current_channel.channel);
     548           0 : }
     549             : 
     550             : u_int16_t
     551           0 : ar5k_regdomain_from_ieee(ieee80211_regdomain_t ieee)
     552             : {
     553             :         u_int32_t regdomain = (u_int32_t)ieee;
     554             : 
     555             :         /*
     556             :          * Use the default regulation domain if the value is empty
     557             :          * or not supported by the net80211 regulation code.
     558             :          */
     559           0 :         if (ieee80211_regdomain2flag(regdomain,
     560           0 :             IEEE80211_CHANNELS_5GHZ_MIN) == DMN_DEBUG)
     561           0 :                 return ((u_int16_t)AR5K_TUNE_REGDOMAIN);
     562             : 
     563             :         /* It is supported, just return the value */
     564           0 :         return (regdomain);
     565           0 : }
     566             : 
     567             : ieee80211_regdomain_t
     568           0 : ar5k_regdomain_to_ieee(u_int16_t regdomain)
     569             : {
     570           0 :         ieee80211_regdomain_t ieee = (ieee80211_regdomain_t)regdomain;
     571             : 
     572           0 :         return (ieee);
     573             : }
     574             : 
     575             : u_int16_t
     576           0 : ar5k_get_regdomain(struct ath_hal *hal)
     577             : {
     578             :         u_int16_t regdomain;
     579           0 :         ieee80211_regdomain_t ieee_regdomain;
     580             : #ifdef COUNTRYCODE
     581             :         u_int16_t code;
     582             : #endif
     583             : 
     584           0 :         ar5k_eeprom_regulation_domain(hal, AH_FALSE, &ieee_regdomain);
     585           0 :         hal->ah_capabilities.cap_regdomain.reg_hw = ieee_regdomain;
     586             : 
     587             : #ifdef COUNTRYCODE
     588             :         /*
     589             :          * Get the regulation domain by country code. This will ignore
     590             :          * the settings found in the EEPROM.
     591             :          */
     592             :         code = ieee80211_name2countrycode(COUNTRYCODE);
     593             :         ieee_regdomain = ieee80211_countrycode2regdomain(code);
     594             : #endif
     595             : 
     596           0 :         regdomain = ar5k_regdomain_from_ieee(ieee_regdomain);
     597           0 :         hal->ah_capabilities.cap_regdomain.reg_current = regdomain;
     598             : 
     599           0 :         return (regdomain);
     600           0 : }
     601             : 
     602             : u_int32_t
     603           0 : ar5k_bitswap(u_int32_t val, u_int bits)
     604             : {
     605           0 :         if (bits == 8) {
     606           0 :                 val = ((val & 0xF0) >>  4) | ((val & 0x0F) <<  4);
     607           0 :                 val = ((val & 0xCC) >>  2) | ((val & 0x33) <<  2);
     608           0 :                 val = ((val & 0xAA) >>  1) | ((val & 0x55) <<  1);
     609             : 
     610           0 :                 return val;
     611             :         } else {
     612             :                 u_int32_t retval = 0, bit, i;
     613             : 
     614           0 :                 for (i = 0; i < bits; i++) {
     615           0 :                         bit = (val >> i) & 1;
     616           0 :                         retval = (retval << 1) | bit;
     617             :                 }
     618             : 
     619             :                 return retval;
     620             :         }
     621           0 : }
     622             : 
     623             : u_int
     624           0 : ar5k_htoclock(u_int usec)
     625             : {
     626           0 :         return (usec * 40);
     627             : }
     628             : 
     629             : u_int
     630           0 : ar5k_clocktoh(u_int clock)
     631             : {
     632           0 :         return (clock / 40);
     633             : }
     634             : 
     635             : void
     636           0 : ar5k_rt_copy(HAL_RATE_TABLE *dst, const HAL_RATE_TABLE *src)
     637             : {
     638           0 :         bzero(dst, sizeof(HAL_RATE_TABLE));
     639           0 :         dst->rateCount = src->rateCount;
     640           0 :         bcopy(src->rateCodeToIndex, dst->rateCodeToIndex,
     641             :             sizeof(dst->rateCodeToIndex));
     642           0 :         bcopy(src->info, dst->info, sizeof(dst->info));
     643           0 : }
     644             : 
     645             : HAL_BOOL
     646           0 : ar5k_register_timeout(struct ath_hal *hal, u_int32_t reg, u_int32_t flag,
     647             :     u_int32_t val, HAL_BOOL is_set)
     648             : {
     649             :         int i;
     650             :         u_int32_t data;
     651             : 
     652           0 :         for (i = AR5K_TUNE_REGISTER_TIMEOUT; i > 0; i--) {
     653           0 :                 data = AR5K_REG_READ(reg);
     654           0 :                 if ((is_set == AH_TRUE) && (data & flag))
     655             :                         break;
     656           0 :                 else if ((data & flag) == val)
     657             :                         break;
     658           0 :                 AR5K_DELAY(15);
     659             :         }
     660             : 
     661           0 :         if (i <= 0)
     662           0 :                 return (AH_FALSE);
     663             : 
     664           0 :         return (AH_TRUE);
     665           0 : }
     666             : 
     667             : /*
     668             :  * Common ar5xx EEPROM access functions
     669             :  */
     670             : 
     671             : u_int16_t
     672           0 : ar5k_eeprom_bin2freq(struct ath_hal *hal, u_int16_t bin, u_int mode)
     673             : {
     674             :         u_int16_t val;
     675             : 
     676           0 :         if (bin == AR5K_EEPROM_CHANNEL_DIS)
     677           0 :                 return (bin);
     678             : 
     679           0 :         if (mode == AR5K_EEPROM_MODE_11A) {
     680           0 :                 if (hal->ah_ee_version > AR5K_EEPROM_VERSION_3_2)
     681           0 :                         val = (5 * bin) + 4800;
     682             :                 else
     683           0 :                         val = bin > 62 ?
     684           0 :                             (10 * 62) + (5 * (bin - 62)) + 5100 :
     685           0 :                             (bin * 10) + 5100;
     686             :         } else {
     687           0 :                 if (hal->ah_ee_version > AR5K_EEPROM_VERSION_3_2)
     688           0 :                         val = bin + 2300;
     689             :                 else
     690           0 :                         val = bin + 2400;
     691             :         }
     692             : 
     693           0 :         return (val);
     694           0 : }
     695             : 
     696             : int
     697           0 : ar5k_eeprom_read_ants(struct ath_hal *hal, u_int32_t *offset, u_int mode)
     698             : {
     699           0 :         struct ar5k_eeprom_info *ee = &hal->ah_capabilities.cap_eeprom;
     700           0 :         u_int32_t o = *offset;
     701           0 :         u_int16_t val;
     702             :         int ret, i = 0;
     703             : 
     704           0 :         AR5K_EEPROM_READ(o++, val);
     705           0 :         ee->ee_switch_settling[mode] = (val >> 8) & 0x7f;
     706           0 :         ee->ee_ant_tx_rx[mode]               = (val >> 2) & 0x3f;
     707           0 :         ee->ee_ant_control[mode][i]  = (val << 4) & 0x3f;
     708             : 
     709           0 :         AR5K_EEPROM_READ(o++, val);
     710           0 :         ee->ee_ant_control[mode][i++]        |= (val >> 12) & 0xf;
     711           0 :         ee->ee_ant_control[mode][i++]        = (val >> 6) & 0x3f;
     712           0 :         ee->ee_ant_control[mode][i++]        = val & 0x3f;
     713             : 
     714           0 :         AR5K_EEPROM_READ(o++, val);
     715           0 :         ee->ee_ant_control[mode][i++]        = (val >> 10) & 0x3f;
     716           0 :         ee->ee_ant_control[mode][i++]        = (val >> 4) & 0x3f;
     717           0 :         ee->ee_ant_control[mode][i]  = (val << 2) & 0x3f;
     718             : 
     719           0 :         AR5K_EEPROM_READ(o++, val);
     720           0 :         ee->ee_ant_control[mode][i++]        |= (val >> 14) & 0x3;
     721           0 :         ee->ee_ant_control[mode][i++]        = (val >> 8) & 0x3f;
     722           0 :         ee->ee_ant_control[mode][i++]        = (val >> 2) & 0x3f;
     723           0 :         ee->ee_ant_control[mode][i]  = (val << 4) & 0x3f;
     724             : 
     725           0 :         AR5K_EEPROM_READ(o++, val);
     726           0 :         ee->ee_ant_control[mode][i++]        |= (val >> 12) & 0xf;
     727           0 :         ee->ee_ant_control[mode][i++]        = (val >> 6) & 0x3f;
     728           0 :         ee->ee_ant_control[mode][i++]        = val & 0x3f;
     729             : 
     730             :         /* Get antenna modes */
     731           0 :         hal->ah_antenna[mode][0] =
     732           0 :             (ee->ee_ant_control[mode][0] << 4) | 0x1;
     733           0 :         hal->ah_antenna[mode][HAL_ANT_FIXED_A] =
     734           0 :             ee->ee_ant_control[mode][1] |
     735           0 :             (ee->ee_ant_control[mode][2] << 6) |
     736           0 :             (ee->ee_ant_control[mode][3] << 12) |
     737           0 :             (ee->ee_ant_control[mode][4] << 18) |
     738           0 :             (ee->ee_ant_control[mode][5] << 24);
     739           0 :         hal->ah_antenna[mode][HAL_ANT_FIXED_B] =
     740           0 :             ee->ee_ant_control[mode][6] |
     741           0 :             (ee->ee_ant_control[mode][7] << 6) |
     742           0 :             (ee->ee_ant_control[mode][8] << 12) |
     743           0 :             (ee->ee_ant_control[mode][9] << 18) |
     744           0 :             (ee->ee_ant_control[mode][10] << 24);
     745             : 
     746             :         /* return new offset */
     747           0 :         *offset = o;
     748             : 
     749           0 :         return (0);
     750           0 : }
     751             : 
     752             : int
     753           0 : ar5k_eeprom_read_modes(struct ath_hal *hal, u_int32_t *offset, u_int mode)
     754             : {
     755           0 :         struct ar5k_eeprom_info *ee = &hal->ah_capabilities.cap_eeprom;
     756           0 :         u_int32_t o = *offset;
     757           0 :         u_int16_t val;
     758             :         int ret;
     759             : 
     760           0 :         AR5K_EEPROM_READ(o++, val);
     761           0 :         ee->ee_tx_end2xlna_enable[mode]      = (val >> 8) & 0xff;
     762           0 :         ee->ee_thr_62[mode]          = val & 0xff;
     763             : 
     764           0 :         if (hal->ah_ee_version <= AR5K_EEPROM_VERSION_3_2)
     765           0 :                 ee->ee_thr_62[mode] =
     766           0 :                     mode == AR5K_EEPROM_MODE_11A ? 15 : 28;
     767             : 
     768           0 :         AR5K_EEPROM_READ(o++, val);
     769           0 :         ee->ee_tx_end2xpa_disable[mode]      = (val >> 8) & 0xff;
     770           0 :         ee->ee_tx_frm2xpa_enable[mode]       = val & 0xff;
     771             : 
     772           0 :         AR5K_EEPROM_READ(o++, val);
     773           0 :         ee->ee_pga_desired_size[mode]        = (val >> 8) & 0xff;
     774             : 
     775           0 :         if ((val & 0xff) & 0x80)
     776           0 :                 ee->ee_noise_floor_thr[mode] = -((((val & 0xff) ^ 0xff)) + 1);
     777             :         else
     778           0 :                 ee->ee_noise_floor_thr[mode] = val & 0xff;
     779             : 
     780           0 :         if (hal->ah_ee_version <= AR5K_EEPROM_VERSION_3_2)
     781           0 :                 ee->ee_noise_floor_thr[mode] =
     782           0 :                     mode == AR5K_EEPROM_MODE_11A ? -54 : -1;
     783             : 
     784           0 :         AR5K_EEPROM_READ(o++, val);
     785           0 :         ee->ee_xlna_gain[mode]               = (val >> 5) & 0xff;
     786           0 :         ee->ee_x_gain[mode]          = (val >> 1) & 0xf;
     787           0 :         ee->ee_xpd[mode]             = val & 0x1;
     788             : 
     789           0 :         if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_0)
     790           0 :                 ee->ee_fixed_bias[mode] = (val >> 13) & 0x1;
     791             : 
     792           0 :         if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_3_3) {
     793           0 :                 AR5K_EEPROM_READ(o++, val);
     794           0 :                 ee->ee_false_detect[mode] = (val >> 6) & 0x7f;
     795             : 
     796           0 :                 if (mode == AR5K_EEPROM_MODE_11A)
     797           0 :                         ee->ee_xr_power[mode] = val & 0x3f;
     798             :                 else {
     799           0 :                         ee->ee_ob[mode][0] = val & 0x7;
     800           0 :                         ee->ee_db[mode][0] = (val >> 3) & 0x7;
     801             :                 }
     802             :         }
     803             : 
     804           0 :         if (hal->ah_ee_version < AR5K_EEPROM_VERSION_3_4) {
     805           0 :                 ee->ee_i_gain[mode] = AR5K_EEPROM_I_GAIN;
     806           0 :                 ee->ee_cck_ofdm_power_delta = AR5K_EEPROM_CCK_OFDM_DELTA;
     807           0 :         } else {
     808           0 :                 ee->ee_i_gain[mode] = (val >> 13) & 0x7;
     809             : 
     810           0 :                 AR5K_EEPROM_READ(o++, val);
     811           0 :                 ee->ee_i_gain[mode] |= (val << 3) & 0x38;
     812             : 
     813           0 :                 if (mode == AR5K_EEPROM_MODE_11G)
     814           0 :                         ee->ee_cck_ofdm_power_delta = (val >> 3) & 0xff;
     815             :         }
     816             : 
     817           0 :         if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_0 &&
     818           0 :             mode == AR5K_EEPROM_MODE_11A) {
     819           0 :                 ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
     820           0 :                 ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
     821           0 :         }
     822             : 
     823           0 :         if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_6 &&
     824           0 :             mode == AR5K_EEPROM_MODE_11G)
     825           0 :                 ee->ee_scaled_cck_delta = (val >> 11) & 0x1f;
     826             : 
     827             :         /* return new offset */
     828           0 :         *offset = o;
     829             : 
     830           0 :         return (0);
     831           0 : }
     832             : 
     833             : int
     834           0 : ar5k_eeprom_init(struct ath_hal *hal)
     835             : {
     836           0 :         struct ar5k_eeprom_info *ee = &hal->ah_capabilities.cap_eeprom;
     837           0 :         u_int32_t offset;
     838           0 :         u_int16_t val;
     839             :         int ret, i;
     840             :         u_int mode;
     841             : 
     842             :         /* Initial TX thermal adjustment values */
     843           0 :         ee->ee_tx_clip = 4;
     844           0 :         ee->ee_pwd_84 = ee->ee_pwd_90 = 1;
     845           0 :         ee->ee_gain_select = 1;
     846             : 
     847             :         /*
     848             :          * Read values from EEPROM and store them in the capability structure
     849             :          */
     850           0 :         AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MAGIC, ee_magic);
     851           0 :         AR5K_EEPROM_READ_HDR(AR5K_EEPROM_PROTECT, ee_protect);
     852           0 :         AR5K_EEPROM_READ_HDR(AR5K_EEPROM_REG_DOMAIN, ee_regdomain);
     853           0 :         AR5K_EEPROM_READ_HDR(AR5K_EEPROM_VERSION, ee_version);
     854           0 :         AR5K_EEPROM_READ_HDR(AR5K_EEPROM_HDR, ee_header);
     855             : 
     856             :         /* Return if we have an old EEPROM */
     857           0 :         if (hal->ah_ee_version < AR5K_EEPROM_VERSION_3_0)
     858           0 :                 return (0);
     859             : 
     860             : #ifdef notyet
     861             :         /*
     862             :          * Validate the checksum of the EEPROM date. There are some
     863             :          * devices with invalid EEPROMs.
     864             :          */
     865             :         for (cksum = 0, offset = 0; offset < AR5K_EEPROM_INFO_MAX; offset++) {
     866             :                 AR5K_EEPROM_READ(AR5K_EEPROM_INFO(offset), val);
     867             :                 cksum ^= val;
     868             :         }
     869             :         if (cksum != AR5K_EEPROM_INFO_CKSUM) {
     870             :                 AR5K_PRINTF("Invalid EEPROM checksum 0x%04x\n", cksum);
     871             :                 return (EINVAL);
     872             :         }
     873             : #endif
     874             : 
     875           0 :         AR5K_EEPROM_READ_HDR(AR5K_EEPROM_ANT_GAIN(hal->ah_ee_version),
     876             :             ee_ant_gain);
     877             : 
     878           0 :         if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
     879           0 :                 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC0, ee_misc0);
     880           0 :                 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC1, ee_misc1);
     881             :         }
     882             : 
     883           0 :         if (hal->ah_ee_version < AR5K_EEPROM_VERSION_3_3) {
     884           0 :                 AR5K_EEPROM_READ(AR5K_EEPROM_OBDB0_2GHZ, val);
     885           0 :                 ee->ee_ob[AR5K_EEPROM_MODE_11B][0] = val & 0x7;
     886           0 :                 ee->ee_db[AR5K_EEPROM_MODE_11B][0] = (val >> 3) & 0x7;
     887             : 
     888           0 :                 AR5K_EEPROM_READ(AR5K_EEPROM_OBDB1_2GHZ, val);
     889           0 :                 ee->ee_ob[AR5K_EEPROM_MODE_11G][0] = val & 0x7;
     890           0 :                 ee->ee_db[AR5K_EEPROM_MODE_11G][0] = (val >> 3) & 0x7;
     891           0 :         }
     892             : 
     893             :         /*
     894             :          * Get conformance test limit values
     895             :          */
     896           0 :         offset = AR5K_EEPROM_CTL(hal->ah_ee_version);
     897           0 :         ee->ee_ctls = AR5K_EEPROM_N_CTLS(hal->ah_ee_version);
     898             : 
     899           0 :         for (i = 0; i < ee->ee_ctls - 1; i++) {
     900           0 :                 AR5K_EEPROM_READ(offset++, val);
     901           0 :                 ee->ee_ctl[i] = (val >> 8) & 0xff;
     902           0 :                 ee->ee_ctl[i + 1] = val & 0xff;
     903             :         }
     904             : 
     905             :         /*
     906             :          * Get values for 802.11a (5GHz)
     907             :          */
     908             :         mode = AR5K_EEPROM_MODE_11A;
     909             : 
     910           0 :         offset = AR5K_EEPROM_MODES_11A(hal->ah_ee_version);
     911             : 
     912           0 :         if ((ret = ar5k_eeprom_read_ants(hal, &offset, mode)) != 0)
     913           0 :                 return (ret);
     914             : 
     915           0 :         AR5K_EEPROM_READ(offset++, val);
     916           0 :         ee->ee_adc_desired_size[mode]        = (int8_t)((val >> 8) & 0xff);
     917           0 :         ee->ee_ob[mode][3]           = (val >> 5) & 0x7;
     918           0 :         ee->ee_db[mode][3]           = (val >> 2) & 0x7;
     919           0 :         ee->ee_ob[mode][2]           = (val << 1) & 0x7;
     920             : 
     921           0 :         AR5K_EEPROM_READ(offset++, val);
     922           0 :         ee->ee_ob[mode][2]           |= (val >> 15) & 0x1;
     923           0 :         ee->ee_db[mode][2]           = (val >> 12) & 0x7;
     924           0 :         ee->ee_ob[mode][1]           = (val >> 9) & 0x7;
     925           0 :         ee->ee_db[mode][1]           = (val >> 6) & 0x7;
     926           0 :         ee->ee_ob[mode][0]           = (val >> 3) & 0x7;
     927           0 :         ee->ee_db[mode][0]           = val & 0x7;
     928             : 
     929           0 :         if ((ret = ar5k_eeprom_read_modes(hal, &offset, mode)) != 0)
     930           0 :                 return (ret);
     931             : 
     932           0 :         if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) {
     933           0 :                 AR5K_EEPROM_READ(offset++, val);
     934           0 :                 ee->ee_margin_tx_rx[mode] = val & 0x3f;
     935           0 :         }
     936             : 
     937             :         /*
     938             :          * Get values for 802.11b (2.4GHz)
     939             :          */
     940             :         mode = AR5K_EEPROM_MODE_11B;
     941           0 :         offset = AR5K_EEPROM_MODES_11B(hal->ah_ee_version);
     942             : 
     943           0 :         if ((ret = ar5k_eeprom_read_ants(hal, &offset, mode)) != 0)
     944           0 :                 return (ret);
     945             : 
     946           0 :         AR5K_EEPROM_READ(offset++, val);
     947           0 :         ee->ee_adc_desired_size[mode]        = (int8_t)((val >> 8) & 0xff);
     948           0 :         ee->ee_ob[mode][1]           = (val >> 4) & 0x7;
     949           0 :         ee->ee_db[mode][1]           = val & 0x7;
     950             : 
     951           0 :         if ((ret = ar5k_eeprom_read_modes(hal, &offset, mode)) != 0)
     952           0 :                 return (ret);
     953             : 
     954           0 :         if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
     955           0 :                 AR5K_EEPROM_READ(offset++, val);
     956           0 :                 ee->ee_cal_pier[mode][0] =
     957           0 :                     ar5k_eeprom_bin2freq(hal, val & 0xff, mode);
     958           0 :                 ee->ee_cal_pier[mode][1] =
     959           0 :                     ar5k_eeprom_bin2freq(hal, (val >> 8) & 0xff, mode);
     960             : 
     961           0 :                 AR5K_EEPROM_READ(offset++, val);
     962           0 :                 ee->ee_cal_pier[mode][2] =
     963           0 :                     ar5k_eeprom_bin2freq(hal, val & 0xff, mode);
     964           0 :         }
     965             : 
     966           0 :         if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) {
     967           0 :                 ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
     968           0 :         }
     969             : 
     970             :         /*
     971             :          * Get values for 802.11g (2.4GHz)
     972             :          */
     973             :         mode = AR5K_EEPROM_MODE_11G;
     974           0 :         offset = AR5K_EEPROM_MODES_11G(hal->ah_ee_version);
     975             : 
     976           0 :         if ((ret = ar5k_eeprom_read_ants(hal, &offset, mode)) != 0)
     977           0 :                 return (ret);
     978             : 
     979           0 :         AR5K_EEPROM_READ(offset++, val);
     980           0 :         ee->ee_adc_desired_size[mode]        = (int8_t)((val >> 8) & 0xff);
     981           0 :         ee->ee_ob[mode][1]           = (val >> 4) & 0x7;
     982           0 :         ee->ee_db[mode][1]           = val & 0x7;
     983             : 
     984           0 :         if ((ret = ar5k_eeprom_read_modes(hal, &offset, mode)) != 0)
     985           0 :                 return (ret);
     986             : 
     987           0 :         if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
     988           0 :                 AR5K_EEPROM_READ(offset++, val);
     989           0 :                 ee->ee_cal_pier[mode][0] =
     990           0 :                     ar5k_eeprom_bin2freq(hal, val & 0xff, mode);
     991           0 :                 ee->ee_cal_pier[mode][1] =
     992           0 :                     ar5k_eeprom_bin2freq(hal, (val >> 8) & 0xff, mode);
     993             : 
     994           0 :                 AR5K_EEPROM_READ(offset++, val);
     995           0 :                 ee->ee_xr_power[mode] = (val >> 7) & 0x3f;
     996             : 
     997           0 :                 AR5K_EEPROM_READ(offset++, val);
     998           0 :                 ee->ee_cal_pier[mode][2] =
     999           0 :                     ar5k_eeprom_bin2freq(hal, val & 0xff, mode);
    1000             : 
    1001           0 :                 if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) {
    1002           0 :                         ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
    1003           0 :                 }
    1004             : 
    1005           0 :                 AR5K_EEPROM_READ(offset++, val);
    1006           0 :                 ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
    1007           0 :                 ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
    1008             : 
    1009           0 :                 if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_2) {
    1010           0 :                         AR5K_EEPROM_READ(offset++, val);
    1011           0 :                         ee->ee_cck_ofdm_gain_delta = val & 0xff;
    1012           0 :                 }
    1013             :         }
    1014             : 
    1015             :         /*
    1016             :          * Read 5GHz EEPROM channels
    1017             :          */
    1018             : 
    1019           0 :         return (0);
    1020           0 : }
    1021             : 
    1022             : int
    1023           0 : ar5k_eeprom_read_mac(struct ath_hal *hal, u_int8_t *mac)
    1024             : {
    1025             :         u_int32_t total, offset;
    1026           0 :         u_int16_t data;
    1027             :         int octet;
    1028           0 :         u_int8_t mac_d[IEEE80211_ADDR_LEN];
    1029             : 
    1030           0 :         bzero(mac, IEEE80211_ADDR_LEN);
    1031           0 :         bzero(&mac_d, IEEE80211_ADDR_LEN);
    1032             : 
    1033           0 :         if (hal->ah_eeprom_read(hal, 0x20, &data) != 0)
    1034           0 :                 return (EIO);
    1035             : 
    1036           0 :         for (offset = 0x1f, octet = 0, total = 0;
    1037           0 :              offset >= 0x1d; offset--) {
    1038           0 :                 if (hal->ah_eeprom_read(hal, offset, &data) != 0)
    1039           0 :                         return (EIO);
    1040             : 
    1041           0 :                 total += data;
    1042           0 :                 mac_d[octet + 1] = data & 0xff;
    1043           0 :                 mac_d[octet] = data >> 8;
    1044           0 :                 octet += 2;
    1045             :         }
    1046             : 
    1047           0 :         bcopy(mac_d, mac, IEEE80211_ADDR_LEN);
    1048             : 
    1049           0 :         if ((!total) || total == (3 * 0xffff))
    1050           0 :                 return (EINVAL);
    1051             : 
    1052           0 :         return (0);
    1053           0 : }
    1054             : 
    1055             : HAL_BOOL
    1056           0 : ar5k_eeprom_regulation_domain(struct ath_hal *hal, HAL_BOOL write,
    1057             :     ieee80211_regdomain_t *regdomain)
    1058             : {
    1059             :         u_int16_t ee_regdomain;
    1060             : 
    1061             :         /* Read current value */
    1062           0 :         if (write != AH_TRUE) {
    1063           0 :                 ee_regdomain = hal->ah_capabilities.cap_eeprom.ee_regdomain;
    1064           0 :                 *regdomain = ar5k_regdomain_to_ieee(ee_regdomain);
    1065           0 :                 return (AH_TRUE);
    1066             :         }
    1067             : 
    1068           0 :         ee_regdomain = ar5k_regdomain_from_ieee(*regdomain);
    1069             : 
    1070             :         /* Try to write a new value */
    1071           0 :         if (hal->ah_capabilities.cap_eeprom.ee_protect &
    1072             :             AR5K_EEPROM_PROTECT_WR_128_191)
    1073           0 :                 return (AH_FALSE);
    1074           0 :         if (hal->ah_eeprom_write(hal, AR5K_EEPROM_REG_DOMAIN,
    1075           0 :             ee_regdomain) != 0)
    1076           0 :                 return (AH_FALSE);
    1077             : 
    1078           0 :         hal->ah_capabilities.cap_eeprom.ee_regdomain = ee_regdomain;
    1079             : 
    1080           0 :         return (AH_TRUE);
    1081           0 : }
    1082             : 
    1083             : /*
    1084             :  * PHY/RF access functions
    1085             :  */
    1086             : 
    1087             : HAL_BOOL
    1088           0 : ar5k_channel(struct ath_hal *hal, HAL_CHANNEL *channel)
    1089             : {
    1090             :         HAL_BOOL ret;
    1091             : 
    1092             :         /*
    1093             :          * Check bounds supported by the PHY
    1094             :          * (don't care about regulation restrictions at this point)
    1095             :          */
    1096           0 :         if ((channel->channel < hal->ah_capabilities.cap_range.range_2ghz_min ||
    1097           0 :             channel->channel > hal->ah_capabilities.cap_range.range_2ghz_max) &&
    1098           0 :             (channel->channel < hal->ah_capabilities.cap_range.range_5ghz_min ||
    1099           0 :             channel->channel > hal->ah_capabilities.cap_range.range_5ghz_max)) {
    1100           0 :                 AR5K_PRINTF("channel out of supported range (%u MHz)\n",
    1101             :                     channel->channel);
    1102           0 :                 return (AH_FALSE);
    1103             :         }
    1104             : 
    1105             :         /*
    1106             :          * Set the channel and wait
    1107             :          */
    1108           0 :         if (hal->ah_radio == AR5K_AR5110)
    1109           0 :                 ret = ar5k_ar5110_channel(hal, channel);
    1110           0 :         else if (hal->ah_radio == AR5K_AR5111)
    1111           0 :                 ret = ar5k_ar5111_channel(hal, channel);
    1112             :         else
    1113           0 :                 ret = ar5k_ar5112_channel(hal, channel);
    1114             : 
    1115           0 :         if (ret == AH_FALSE)
    1116           0 :                 return (ret);
    1117             : 
    1118           0 :         hal->ah_current_channel.c_channel = channel->c_channel;
    1119           0 :         hal->ah_current_channel.c_channel_flags = channel->c_channel_flags;
    1120             : 
    1121           0 :         return (AH_TRUE);
    1122           0 : }
    1123             : 
    1124             : u_int32_t
    1125           0 : ar5k_ar5110_chan2athchan(HAL_CHANNEL *channel)
    1126             : {
    1127             :         u_int32_t athchan;
    1128             : 
    1129             :         /*
    1130             :          * Convert IEEE channel/MHz to an internal channel value used
    1131             :          * by the AR5210 chipset. This has not been verified with
    1132             :          * newer chipsets like the AR5212A who have a completely
    1133             :          * different RF/PHY part.
    1134             :          */
    1135           0 :         athchan = (ar5k_bitswap((ieee80211_mhz2ieee(channel->c_channel,
    1136           0 :             channel->c_channel_flags) - 24) / 2, 5) << 1) |
    1137           0 :             (1 << 6) | 0x1;
    1138             : 
    1139           0 :         return (athchan);
    1140             : }
    1141             : 
    1142             : HAL_BOOL
    1143           0 : ar5k_ar5110_channel(struct ath_hal *hal, HAL_CHANNEL *channel)
    1144             : {
    1145             :         u_int32_t data;
    1146             : 
    1147             :         /*
    1148             :          * Set the channel and wait
    1149             :          */
    1150           0 :         data = ar5k_ar5110_chan2athchan(channel);
    1151           0 :         AR5K_PHY_WRITE(0x27, data);
    1152           0 :         AR5K_PHY_WRITE(0x30, 0);
    1153           0 :         AR5K_DELAY(1000);
    1154             : 
    1155           0 :         return (AH_TRUE);
    1156             : }
    1157             : 
    1158             : HAL_BOOL
    1159           0 : ar5k_ar5111_chan2athchan(u_int ieee, struct ar5k_athchan_2ghz *athchan)
    1160             : {
    1161             :         int channel;
    1162             : 
    1163             :         /* Cast this value to catch negative channel numbers (>= -19) */ 
    1164             :         channel = (int)ieee;
    1165             : 
    1166             :         /*
    1167             :          * Map 2GHz IEEE channel to 5GHz Atheros channel
    1168             :          */
    1169           0 :         if (channel <= 13) {
    1170           0 :                 athchan->a2_athchan = 115 + channel;
    1171           0 :                 athchan->a2_flags = 0x46;
    1172           0 :         } else if (channel == 14) {
    1173           0 :                 athchan->a2_athchan = 124;
    1174           0 :                 athchan->a2_flags = 0x44;
    1175           0 :         } else if (channel >= 15 && channel <= 26) {
    1176           0 :                 athchan->a2_athchan = ((channel - 14) * 4) + 132;
    1177           0 :                 athchan->a2_flags = 0x46;
    1178             :         } else
    1179           0 :                 return (AH_FALSE);
    1180             : 
    1181           0 :         return (AH_TRUE);
    1182           0 : }
    1183             : 
    1184             : HAL_BOOL
    1185           0 : ar5k_ar5111_channel(struct ath_hal *hal, HAL_CHANNEL *channel)
    1186             : {
    1187             :         u_int ieee_channel, ath_channel;
    1188             :         u_int32_t data0, data1, clock;
    1189           0 :         struct ar5k_athchan_2ghz ath_channel_2ghz;
    1190             : 
    1191             :         /*
    1192             :          * Set the channel on the AR5111 radio
    1193             :          */
    1194             :         data0 = data1 = 0;
    1195           0 :         ath_channel = ieee_channel = ieee80211_mhz2ieee(channel->c_channel,
    1196           0 :             channel->c_channel_flags);
    1197             : 
    1198           0 :         if (channel->c_channel_flags & IEEE80211_CHAN_2GHZ) {
    1199             :                 /* Map 2GHz channel to 5GHz Atheros channel ID */
    1200           0 :                 if (ar5k_ar5111_chan2athchan(ieee_channel,
    1201           0 :                         &ath_channel_2ghz) == AH_FALSE)
    1202           0 :                         return (AH_FALSE);
    1203             : 
    1204           0 :                 ath_channel = ath_channel_2ghz.a2_athchan;
    1205           0 :                 data0 = ((ar5k_bitswap(ath_channel_2ghz.a2_flags, 8) & 0xff)
    1206           0 :                     << 5) | (1 << 4);
    1207           0 :         }
    1208             : 
    1209           0 :         if (ath_channel < 145 || !(ath_channel & 1)) {
    1210             :                 clock = 1;
    1211           0 :                 data1 = ((ar5k_bitswap(ath_channel - 24, 8) & 0xff) << 2)
    1212           0 :                     | (clock << 1) | (1 << 10) | 1;
    1213           0 :         } else {
    1214             :                 clock = 0;
    1215           0 :                 data1 = ((ar5k_bitswap((ath_channel - 24) / 2, 8) & 0xff) << 2)
    1216           0 :                     | (clock << 1) | (1 << 10) | 1;
    1217             :         }
    1218             : 
    1219           0 :         AR5K_PHY_WRITE(0x27, (data1 & 0xff) | ((data0 & 0xff) << 8));
    1220           0 :         AR5K_PHY_WRITE(0x34, ((data1 >> 8) & 0xff) | (data0 & 0xff00));
    1221             : 
    1222           0 :         return (AH_TRUE);
    1223           0 : }
    1224             : 
    1225             : HAL_BOOL
    1226           0 : ar5k_ar5112_channel(struct ath_hal *hal, HAL_CHANNEL *channel)
    1227             : {
    1228             :         u_int32_t data, data0, data1, data2;
    1229             :         u_int16_t c;
    1230             : 
    1231             :         data = data0 = data1 = data2 = 0;
    1232           0 :         c = channel->c_channel + hal->ah_chanoff;
    1233             : 
    1234             :         /*
    1235             :          * Set the channel on the AR5112 or newer
    1236             :          */
    1237           0 :         if (c < 4800) {
    1238           0 :                 if (!((c - 2224) % 5)) {
    1239           0 :                         data0 = ((2 * (c - 704)) - 3040) / 10;
    1240             :                         data1 = 1;
    1241           0 :                 } else if (!((c - 2192) % 5)) {
    1242           0 :                         data0 = ((2 * (c - 672)) - 3040) / 10;
    1243             :                         data1 = 0;
    1244             :                 } else
    1245           0 :                         return (AH_FALSE);
    1246             : 
    1247           0 :                 data0 = ar5k_bitswap((data0 << 2) & 0xff, 8);
    1248           0 :         } else {
    1249           0 :                 if (!(c % 20) && c >= 5120) {
    1250           0 :                         data0 = ar5k_bitswap(((c - 4800) / 20 << 2), 8);
    1251           0 :                         data2 = ar5k_bitswap(3, 2);
    1252           0 :                 } else if (!(c % 10)) {
    1253           0 :                         data0 = ar5k_bitswap(((c - 4800) / 10 << 1), 8);
    1254           0 :                         data2 = ar5k_bitswap(2, 2);
    1255           0 :                 } else if (!(c % 5)) {
    1256           0 :                         data0 = ar5k_bitswap((c - 4800) / 5, 8);
    1257           0 :                         data2 = ar5k_bitswap(1, 2);
    1258             :                 } else
    1259           0 :                         return (AH_FALSE);
    1260             :         }
    1261             : 
    1262           0 :         data = (data0 << 4) | (data1 << 1) | (data2 << 2) | 0x1001;
    1263             : 
    1264           0 :         AR5K_PHY_WRITE(0x27, data & 0xff);
    1265           0 :         AR5K_PHY_WRITE(0x36, (data >> 8) & 0x7f);
    1266             : 
    1267           0 :         return (AH_TRUE);
    1268           0 : }
    1269             : 
    1270             : u_int
    1271           0 : ar5k_rfregs_op(u_int32_t *rf, u_int32_t offset, u_int32_t reg, u_int32_t bits,
    1272             :     u_int32_t first, u_int32_t col, HAL_BOOL set)
    1273             : {
    1274             :         u_int32_t mask, entry, last, data, shift, position;
    1275             :         int32_t left;
    1276             :         int i;
    1277             : 
    1278           0 :         if (rf == NULL) {
    1279             :                 /* should not happen */
    1280           0 :                 return (0);
    1281             :         }
    1282             : 
    1283           0 :         if (!(col <= 3 && bits <= 32 && first + bits <= 319)) {
    1284           0 :                 AR5K_PRINTF("invalid values at offset %u\n", offset);
    1285           0 :                 return (0);
    1286             :         }
    1287             : 
    1288           0 :         entry = ((first - 1) / 8) + offset;
    1289           0 :         position = (first - 1) % 8;
    1290             : 
    1291           0 :         if (set == AH_TRUE)
    1292           0 :                 data = ar5k_bitswap(reg, bits);
    1293             : 
    1294           0 :         for (i = shift = 0, left = bits; left > 0; position = 0, entry++, i++) {
    1295           0 :                 last = (position + left > 8) ? 8 : position + left;
    1296           0 :                 mask = (((1 << last) - 1) ^ ((1 << position) - 1)) <<
    1297           0 :                     (col * 8);
    1298             : 
    1299           0 :                 if (set == AH_TRUE) {
    1300           0 :                         rf[entry] &= ~mask;
    1301           0 :                         rf[entry] |= ((data << position) << (col * 8)) & mask;
    1302           0 :                         data >>= (8 - position);
    1303           0 :                 } else {
    1304           0 :                         data = (((rf[entry] & mask) >> (col * 8)) >>
    1305           0 :                             position) << shift;
    1306           0 :                         shift += last - position;
    1307             :                 }
    1308             : 
    1309           0 :                 left -= 8 - position;
    1310             :         }
    1311             : 
    1312           0 :         data = set == AH_TRUE ? 1 : ar5k_bitswap(data, bits);
    1313             : 
    1314           0 :         return (data);
    1315           0 : }
    1316             : 
    1317             : u_int32_t
    1318           0 : ar5k_rfregs_gainf_corr(struct ath_hal *hal)
    1319             : {
    1320             :         u_int32_t mix, step;
    1321             :         u_int32_t *rf;
    1322             : 
    1323           0 :         if (hal->ah_rf_banks == NULL)
    1324           0 :                 return (0);
    1325             : 
    1326             :         rf = hal->ah_rf_banks;
    1327           0 :         hal->ah_gain.g_f_corr = 0;
    1328             : 
    1329           0 :         if (ar5k_rfregs_op(rf, hal->ah_offset[7], 0, 1, 36, 0, AH_FALSE) != 1)
    1330           0 :                 return (0);
    1331             : 
    1332           0 :         step = ar5k_rfregs_op(rf, hal->ah_offset[7], 0, 4, 32, 0, AH_FALSE);
    1333           0 :         mix = hal->ah_gain.g_step->gos_param[0];
    1334             : 
    1335           0 :         switch (mix) {
    1336             :         case 3:
    1337           0 :                 hal->ah_gain.g_f_corr = step * 2;
    1338           0 :                 break;
    1339             :         case 2:
    1340           0 :                 hal->ah_gain.g_f_corr = (step - 5) * 2;
    1341           0 :                 break;
    1342             :         case 1:
    1343           0 :                 hal->ah_gain.g_f_corr = step;
    1344           0 :                 break;
    1345             :         default:
    1346           0 :                 hal->ah_gain.g_f_corr = 0;
    1347           0 :                 break;
    1348             :         }
    1349             : 
    1350           0 :         return (hal->ah_gain.g_f_corr);
    1351           0 : }
    1352             : 
    1353             : HAL_BOOL
    1354           0 : ar5k_rfregs_gain_readback(struct ath_hal *hal)
    1355             : {
    1356             :         u_int32_t step, mix, level[4];
    1357             :         u_int32_t *rf;
    1358             : 
    1359           0 :         if (hal->ah_rf_banks == NULL)
    1360           0 :                 return (0);
    1361             : 
    1362             :         rf = hal->ah_rf_banks;
    1363             : 
    1364           0 :         if (hal->ah_radio == AR5K_AR5111) {
    1365           0 :                 step = ar5k_rfregs_op(rf, hal->ah_offset[7],
    1366             :                     0, 6, 37, 0, AH_FALSE);
    1367             :                 level[0] = 0;
    1368           0 :                 level[1] = (step == 0x3f) ? 0x32 : step + 4;
    1369           0 :                 level[2] = (step != 0x3f) ? 0x40 : level[0];
    1370           0 :                 level[3] = level[2] + 0x32;
    1371             : 
    1372           0 :                 hal->ah_gain.g_high = level[3] -
    1373           0 :                     (step == 0x3f ? AR5K_GAIN_DYN_ADJUST_HI_MARGIN : -5);
    1374           0 :                 hal->ah_gain.g_low = level[0] +
    1375           0 :                     (step == 0x3f ? AR5K_GAIN_DYN_ADJUST_LO_MARGIN : 0);
    1376           0 :         } else {
    1377           0 :                 mix = ar5k_rfregs_op(rf, hal->ah_offset[7],
    1378             :                     0, 1, 36, 0, AH_FALSE);
    1379             :                 level[0] = level[2] = 0;
    1380             : 
    1381           0 :                 if (mix == 1) {
    1382             :                         level[1] = level[3] = 83;
    1383           0 :                 } else {
    1384             :                         level[1] = level[3] = 107;
    1385           0 :                         hal->ah_gain.g_high = 55;
    1386             :                 }
    1387             :         }
    1388             : 
    1389           0 :         return ((hal->ah_gain.g_current >= level[0] &&
    1390           0 :             hal->ah_gain.g_current <= level[1]) ||
    1391           0 :             (hal->ah_gain.g_current >= level[2] &&
    1392           0 :             hal->ah_gain.g_current <= level[3]));
    1393           0 : }
    1394             : 
    1395             : int32_t
    1396           0 : ar5k_rfregs_gain_adjust(struct ath_hal *hal)
    1397             : {
    1398             :         int ret = 0;
    1399             :         const struct ar5k_gain_opt *go;
    1400             : 
    1401           0 :         go = hal->ah_radio == AR5K_AR5111 ?
    1402             :             &ar5111_gain_opt : &ar5112_gain_opt;
    1403             : 
    1404           0 :         hal->ah_gain.g_step = &go->go_step[hal->ah_gain.g_step_idx];
    1405             : 
    1406           0 :         if (hal->ah_gain.g_current >= hal->ah_gain.g_high) {
    1407           0 :                 if (hal->ah_gain.g_step_idx == 0)
    1408           0 :                         return (-1);
    1409           0 :                 for (hal->ah_gain.g_target = hal->ah_gain.g_current;
    1410           0 :                     hal->ah_gain.g_target >=  hal->ah_gain.g_high &&
    1411           0 :                     hal->ah_gain.g_step_idx > 0;
    1412           0 :                     hal->ah_gain.g_step =
    1413           0 :                     &go->go_step[hal->ah_gain.g_step_idx]) {
    1414           0 :                         hal->ah_gain.g_target -= 2 *
    1415           0 :                             (go->go_step[--(hal->ah_gain.g_step_idx)].gos_gain -
    1416           0 :                             hal->ah_gain.g_step->gos_gain);
    1417             :                 }
    1418             : 
    1419             :                 ret = 1;
    1420           0 :                 goto done;
    1421             :         }
    1422             : 
    1423           0 :         if (hal->ah_gain.g_current <= hal->ah_gain.g_low) {
    1424           0 :                 if (hal->ah_gain.g_step_idx == (go->go_steps_count - 1))
    1425           0 :                         return (-2);
    1426           0 :                 for (hal->ah_gain.g_target = hal->ah_gain.g_current;
    1427           0 :                     hal->ah_gain.g_target <=  hal->ah_gain.g_low &&
    1428           0 :                     hal->ah_gain.g_step_idx < (go->go_steps_count - 1);
    1429           0 :                     hal->ah_gain.g_step =
    1430           0 :                     &go->go_step[hal->ah_gain.g_step_idx]) {
    1431           0 :                         hal->ah_gain.g_target -= 2 *
    1432           0 :                             (go->go_step[++(hal->ah_gain.g_step_idx)].gos_gain -
    1433           0 :                             hal->ah_gain.g_step->gos_gain);
    1434             :                 }
    1435             : 
    1436             :                 ret = 2;
    1437           0 :                 goto done;
    1438             :         }
    1439             : 
    1440             :  done:
    1441             : #ifdef AR5K_DEBUG
    1442             :         AR5K_PRINTF("ret %d, gain step %u, current gain %u, target gain %u\n",
    1443             :             ret,
    1444             :             hal->ah_gain.g_step_idx,
    1445             :             hal->ah_gain.g_current,
    1446             :             hal->ah_gain.g_target);
    1447             : #endif
    1448             : 
    1449           0 :         return (ret);
    1450           0 : }
    1451             : 
    1452             : HAL_BOOL
    1453           0 : ar5k_rfregs(struct ath_hal *hal, HAL_CHANNEL *channel, u_int mode)
    1454             : {
    1455             :         ar5k_rfgain_t *func = NULL;
    1456             :         HAL_BOOL ret;
    1457             : 
    1458           0 :         switch (hal->ah_radio) {
    1459             :         case AR5K_AR5111:
    1460           0 :                 hal->ah_rf_banks_size = sizeof(ar5111_rf);
    1461             :                 func = ar5k_ar5111_rfregs;
    1462           0 :                 break;
    1463             :         case AR5K_AR5112:
    1464           0 :                 if (hal->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A)
    1465           0 :                         hal->ah_rf_banks_size = sizeof(ar5112a_rf);
    1466             :                 else
    1467           0 :                         hal->ah_rf_banks_size = sizeof(ar5112_rf);
    1468             :                 func = ar5k_ar5112_rfregs;
    1469           0 :                 break;
    1470             :         case AR5K_AR5413:
    1471           0 :                 hal->ah_rf_banks_size = sizeof(ar5413_rf);
    1472             :                 func = ar5k_arxxxx_rfregs;
    1473           0 :                 break;
    1474             :         case AR5K_AR2413:
    1475           0 :                 hal->ah_rf_banks_size = sizeof(ar2413_rf);
    1476             :                 func = ar5k_arxxxx_rfregs;
    1477           0 :                 break;
    1478             :         case AR5K_AR2425:
    1479           0 :                 hal->ah_rf_banks_size = sizeof(ar2425_rf);
    1480             :                 func = ar5k_arxxxx_rfregs;
    1481           0 :                 break;
    1482             :         default:
    1483           0 :                 return (AH_FALSE);
    1484             :         }
    1485             : 
    1486           0 :         if (hal->ah_rf_banks == NULL) {
    1487             :                 /* XXX do extra checks? */
    1488           0 :                 if ((hal->ah_rf_banks = malloc(hal->ah_rf_banks_size,
    1489           0 :                     M_DEVBUF, M_NOWAIT | M_ZERO)) == NULL) {
    1490           0 :                         AR5K_PRINT("out of memory\n");
    1491           0 :                         return (AH_FALSE);
    1492             :                 }
    1493             :         }
    1494             : 
    1495           0 :         ret = (func)(hal, channel, mode);
    1496             : 
    1497           0 :         if (ret == AH_TRUE)
    1498           0 :                 hal->ah_rf_gain = HAL_RFGAIN_INACTIVE;
    1499             : 
    1500           0 :         return (ret);
    1501           0 : }
    1502             : 
    1503             : HAL_BOOL
    1504           0 : ar5k_ar5111_rfregs(struct ath_hal *hal, HAL_CHANNEL *channel, u_int mode)
    1505             : {
    1506           0 :         struct ar5k_eeprom_info *ee = &hal->ah_capabilities.cap_eeprom;
    1507             :         const u_int rf_size = nitems(ar5111_rf);
    1508             :         u_int32_t *rf;
    1509             :         int i, obdb = -1, bank = -1;
    1510             :         u_int32_t ee_mode;
    1511             : 
    1512           0 :         AR5K_ASSERT_ENTRY(mode, AR5K_INI_VAL_MAX);
    1513             : 
    1514           0 :         rf = hal->ah_rf_banks;
    1515             : 
    1516             :         /* Copy values to modify them */
    1517           0 :         for (i = 0; i < rf_size; i++) {
    1518           0 :                 if (ar5111_rf[i].rf_bank >=
    1519             :                     AR5K_AR5111_INI_RF_MAX_BANKS) {
    1520           0 :                         AR5K_PRINT("invalid bank\n");
    1521           0 :                         return (AH_FALSE);
    1522             :                 }
    1523             : 
    1524           0 :                 if (bank != ar5111_rf[i].rf_bank) {
    1525             :                         bank = ar5111_rf[i].rf_bank;
    1526           0 :                         hal->ah_offset[bank] = i;
    1527           0 :                 }
    1528             : 
    1529           0 :                 rf[i] = ar5111_rf[i].rf_value[mode];
    1530             :         }
    1531             : 
    1532           0 :         if (channel->c_channel_flags & IEEE80211_CHAN_2GHZ) {
    1533           0 :                 if ((channel->c_channel_flags & IEEE80211_CHAN_G) ==
    1534             :                     IEEE80211_CHAN_G)
    1535           0 :                         ee_mode = AR5K_EEPROM_MODE_11G;
    1536             :                 else
    1537             :                         ee_mode = AR5K_EEPROM_MODE_11B;
    1538             :                 obdb = 0;
    1539             : 
    1540           0 :                 if (!ar5k_rfregs_op(rf, hal->ah_offset[0],
    1541           0 :                         ee->ee_ob[ee_mode][obdb], 3, 119, 0, AH_TRUE))
    1542           0 :                         return (AH_FALSE);
    1543             : 
    1544           0 :                 if (!ar5k_rfregs_op(rf, hal->ah_offset[0],
    1545           0 :                         ee->ee_ob[ee_mode][obdb], 3, 122, 0, AH_TRUE))
    1546           0 :                         return (AH_FALSE);
    1547             : 
    1548             :                 obdb = 1;
    1549           0 :         } else {
    1550             :                 /* For 11a, Turbo and XR */
    1551             :                 ee_mode = AR5K_EEPROM_MODE_11A;
    1552           0 :                 obdb = channel->c_channel >= 5725 ? 3 :
    1553           0 :                     (channel->c_channel >= 5500 ? 2 :
    1554           0 :                         (channel->c_channel >= 5260 ? 1 :
    1555           0 :                             (channel->c_channel > 4000 ? 0 : -1)));
    1556             : 
    1557           0 :                 if (!ar5k_rfregs_op(rf, hal->ah_offset[6],
    1558           0 :                         ee->ee_pwd_84, 1, 51, 3, AH_TRUE))
    1559           0 :                         return (AH_FALSE);
    1560             : 
    1561           0 :                 if (!ar5k_rfregs_op(rf, hal->ah_offset[6],
    1562           0 :                         ee->ee_pwd_90, 1, 45, 3, AH_TRUE))
    1563           0 :                         return (AH_FALSE);
    1564             :         }
    1565             : 
    1566           0 :         if (!ar5k_rfregs_op(rf, hal->ah_offset[6],
    1567           0 :                 !ee->ee_xpd[ee_mode], 1, 95, 0, AH_TRUE))
    1568           0 :                 return (AH_FALSE);
    1569             : 
    1570           0 :         if (!ar5k_rfregs_op(rf, hal->ah_offset[6],
    1571           0 :                 ee->ee_x_gain[ee_mode], 4, 96, 0, AH_TRUE))
    1572           0 :                 return (AH_FALSE);
    1573             : 
    1574           0 :         if (!ar5k_rfregs_op(rf, hal->ah_offset[6],
    1575           0 :                 obdb >= 0 ? ee->ee_ob[ee_mode][obdb] : 0, 3, 104, 0, AH_TRUE))
    1576           0 :                 return (AH_FALSE);
    1577             : 
    1578           0 :         if (!ar5k_rfregs_op(rf, hal->ah_offset[6],
    1579           0 :                 obdb >= 0 ? ee->ee_db[ee_mode][obdb] : 0, 3, 107, 0, AH_TRUE))
    1580           0 :                 return (AH_FALSE);
    1581             : 
    1582           0 :         if (!ar5k_rfregs_op(rf, hal->ah_offset[7],
    1583           0 :                 ee->ee_i_gain[ee_mode], 6, 29, 0, AH_TRUE))
    1584           0 :                 return (AH_FALSE);
    1585             : 
    1586           0 :         if (!ar5k_rfregs_op(rf, hal->ah_offset[7],
    1587           0 :                 ee->ee_xpd[ee_mode], 1, 4, 0, AH_TRUE))
    1588           0 :                 return (AH_FALSE);
    1589             : 
    1590             :         /* Write RF values */
    1591           0 :         for (i = 0; i < rf_size; i++) {
    1592           0 :                 AR5K_REG_WAIT(i);
    1593           0 :                 AR5K_REG_WRITE(ar5111_rf[i].rf_register, rf[i]);
    1594             :         }
    1595             : 
    1596           0 :         return (AH_TRUE);
    1597           0 : }
    1598             : 
    1599             : HAL_BOOL
    1600           0 : ar5k_ar5112_rfregs(struct ath_hal *hal, HAL_CHANNEL *channel, u_int mode)
    1601             : {
    1602           0 :         struct ar5k_eeprom_info *ee = &hal->ah_capabilities.cap_eeprom;
    1603             :         u_int rf_size;
    1604             :         u_int32_t *rf;
    1605             :         int i, obdb = -1, bank = -1;
    1606             :         u_int32_t ee_mode;
    1607             :         const struct ar5k_ini_rf *rf_ini;
    1608             : 
    1609           0 :         AR5K_ASSERT_ENTRY(mode, AR5K_INI_VAL_MAX);
    1610             : 
    1611           0 :         rf = hal->ah_rf_banks;
    1612             : 
    1613           0 :         if (hal->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) {
    1614             :                 rf_ini = ar5112a_rf;
    1615             :                 rf_size = nitems(ar5112a_rf);
    1616           0 :         } else {
    1617             :                 rf_ini = ar5112_rf;
    1618             :                 rf_size = nitems(ar5112_rf);
    1619             :         }
    1620             : 
    1621             :         /* Copy values to modify them */
    1622           0 :         for (i = 0; i < rf_size; i++) {
    1623           0 :                 if (rf_ini[i].rf_bank >=
    1624             :                     AR5K_AR5112_INI_RF_MAX_BANKS) {
    1625           0 :                         AR5K_PRINT("invalid bank\n");
    1626           0 :                         return (AH_FALSE);
    1627             :                 }
    1628             : 
    1629           0 :                 if (bank != rf_ini[i].rf_bank) {
    1630             :                         bank = rf_ini[i].rf_bank;
    1631           0 :                         hal->ah_offset[bank] = i;
    1632           0 :                 }
    1633             : 
    1634           0 :                 rf[i] = rf_ini[i].rf_value[mode];
    1635             :         }
    1636             : 
    1637           0 :         if (channel->c_channel_flags & IEEE80211_CHAN_2GHZ) {
    1638           0 :                 if ((channel->c_channel_flags & IEEE80211_CHAN_G) ==
    1639             :                     IEEE80211_CHAN_G)
    1640           0 :                         ee_mode = AR5K_EEPROM_MODE_11G;
    1641             :                 else
    1642             :                         ee_mode = AR5K_EEPROM_MODE_11B;
    1643             :                 obdb = 0;
    1644             : 
    1645           0 :                 if (!ar5k_rfregs_op(rf, hal->ah_offset[6],
    1646           0 :                         ee->ee_ob[ee_mode][obdb], 3, 287, 0, AH_TRUE))
    1647           0 :                         return (AH_FALSE);
    1648             : 
    1649           0 :                 if (!ar5k_rfregs_op(rf, hal->ah_offset[6],
    1650           0 :                         ee->ee_ob[ee_mode][obdb], 3, 290, 0, AH_TRUE))
    1651           0 :                         return (AH_FALSE);
    1652             :         } else {
    1653             :                 /* For 11a, Turbo and XR */
    1654             :                 ee_mode = AR5K_EEPROM_MODE_11A;
    1655           0 :                 obdb = channel->c_channel >= 5725 ? 3 :
    1656           0 :                     (channel->c_channel >= 5500 ? 2 :
    1657           0 :                         (channel->c_channel >= 5260 ? 1 :
    1658           0 :                             (channel->c_channel > 4000 ? 0 : -1)));
    1659             : 
    1660             :                 /* bogus channel: bad beacon? */
    1661           0 :                 if (obdb < 0)
    1662           0 :                         return (AH_FALSE);
    1663             : 
    1664           0 :                 if (!ar5k_rfregs_op(rf, hal->ah_offset[6],
    1665           0 :                         ee->ee_ob[ee_mode][obdb], 3, 279, 0, AH_TRUE))
    1666           0 :                         return (AH_FALSE);
    1667             : 
    1668           0 :                 if (!ar5k_rfregs_op(rf, hal->ah_offset[6],
    1669           0 :                         ee->ee_ob[ee_mode][obdb], 3, 282, 0, AH_TRUE))
    1670           0 :                         return (AH_FALSE);
    1671             :         }
    1672             : 
    1673             : #ifdef notyet
    1674             :         ar5k_rfregs_op(rf, hal->ah_offset[6],
    1675             :             ee->ee_x_gain[ee_mode], 2, 270, 0, AH_TRUE);
    1676             :         ar5k_rfregs_op(rf, hal->ah_offset[6],
    1677             :             ee->ee_x_gain[ee_mode], 2, 257, 0, AH_TRUE);
    1678             : #endif
    1679             : 
    1680           0 :         if (!ar5k_rfregs_op(rf, hal->ah_offset[6],
    1681           0 :                 ee->ee_xpd[ee_mode], 1, 302, 0, AH_TRUE))
    1682           0 :                 return (AH_FALSE);
    1683             : 
    1684           0 :         if (!ar5k_rfregs_op(rf, hal->ah_offset[7],
    1685           0 :                 ee->ee_i_gain[ee_mode], 6, 14, 0, AH_TRUE))
    1686           0 :                 return (AH_FALSE);
    1687             : 
    1688             :         /* Write RF values */
    1689           0 :         for (i = 0; i < rf_size; i++)
    1690           0 :                 AR5K_REG_WRITE(rf_ini[i].rf_register, rf[i]);
    1691             : 
    1692           0 :         return (AH_TRUE);
    1693           0 : }
    1694             : 
    1695             : HAL_BOOL
    1696           0 : ar5k_arxxxx_rfregs(struct ath_hal *hal, HAL_CHANNEL *channel, u_int mode)
    1697             : {
    1698             :         const struct ar5k_ini_rf        *rf_ini;
    1699             :         u_int                            rf_size;
    1700             :         u_int32_t                       *rf;
    1701             :         int                              i, bank = -1;
    1702             : 
    1703           0 :         AR5K_ASSERT_ENTRY(mode, AR5K_INI_VAL_MAX);
    1704             : 
    1705           0 :         rf = hal->ah_rf_banks;
    1706             : 
    1707           0 :         switch (hal->ah_radio) {
    1708             :         case AR5K_AR5413:
    1709             :                 rf_ini = ar5413_rf;
    1710             :                 rf_size = nitems(ar5413_rf);
    1711           0 :                 break;
    1712             :         case AR5K_AR2413:
    1713             :                 rf_ini = ar2413_rf;
    1714             :                 rf_size = nitems(ar2413_rf);
    1715           0 :                 break;
    1716             :         case AR5K_AR2425:
    1717           0 :                 if (mode == AR5K_INI_VAL_11B)
    1718           0 :                         mode = AR5K_INI_VAL_11G;
    1719             :                 rf_ini = ar2425_rf;
    1720             :                 rf_size = nitems(ar2425_rf);
    1721           0 :                 break;
    1722             :         default:
    1723           0 :                 return (AH_FALSE);
    1724             :         }
    1725             : 
    1726             :         /* Copy values to modify them */
    1727           0 :         for (i = 0; i < rf_size; i++) {
    1728           0 :                 if (rf_ini[i].rf_bank >= AR5K_MAX_RF_BANKS) {
    1729           0 :                         AR5K_PRINT("invalid bank\n");
    1730           0 :                         return (AH_FALSE);
    1731             :                 }
    1732             : 
    1733           0 :                 if (bank != rf_ini[i].rf_bank) {
    1734             :                         bank = rf_ini[i].rf_bank;
    1735           0 :                         hal->ah_offset[bank] = i;
    1736           0 :                 }
    1737             : 
    1738           0 :                 rf[i] = rf_ini[i].rf_value[mode];
    1739             :         }
    1740             : 
    1741             :         /* Write RF values */
    1742           0 :         for (i = 0; i < rf_size; i++)
    1743           0 :                 AR5K_REG_WRITE(rf_ini[i].rf_register, rf[i]);
    1744             : 
    1745           0 :         return (AH_TRUE);
    1746           0 : }
    1747             : 
    1748             : HAL_BOOL
    1749           0 : ar5k_rfgain(struct ath_hal *hal, u_int freq)
    1750             : {
    1751             :         const struct ar5k_ini_rfgain    *rfg;
    1752             :         size_t                           rfg_size;
    1753             :         int                              i;
    1754             : 
    1755           0 :         switch (hal->ah_radio) {
    1756             :         case AR5K_AR5111:
    1757             :                 rfg = ar5111_rfg;
    1758             :                 rfg_size = nitems(ar5111_rfg);
    1759           0 :                 break;
    1760             :         case AR5K_AR5112:
    1761             :                 rfg = ar5112_rfg;
    1762             :                 rfg_size = nitems(ar5112_rfg);
    1763           0 :                 break;
    1764             :         case AR5K_AR5413:
    1765             :                 rfg = ar5413_rfg;
    1766             :                 rfg_size = nitems(ar5413_rfg);
    1767           0 :                 break;
    1768             :         case AR5K_AR2413:
    1769             :         case AR5K_AR2425:
    1770           0 :                 if (freq == AR5K_INI_RFGAIN_5GHZ)
    1771           0 :                         return (AH_FALSE);
    1772             :                 rfg = ar2413_rfg;
    1773             :                 rfg_size = nitems(ar2413_rfg);
    1774           0 :                 break;
    1775             :         default:
    1776           0 :                 return (AH_FALSE);
    1777             :         }
    1778             : 
    1779           0 :         switch (freq) {
    1780             :         case AR5K_INI_RFGAIN_2GHZ:
    1781             :         case AR5K_INI_RFGAIN_5GHZ:
    1782             :                 break;
    1783             :         default:
    1784           0 :                 return (AH_FALSE);
    1785             :         }
    1786             : 
    1787           0 :         for (i = 0; i < rfg_size; i++) {
    1788           0 :                 AR5K_REG_WAIT(i);
    1789           0 :                 AR5K_REG_WRITE((u_int32_t)rfg[i].rfg_register,
    1790             :                     rfg[i].rfg_value[freq]);
    1791             :         }
    1792             : 
    1793           0 :         return (AH_TRUE);
    1794           0 : }
    1795             : 
    1796             : /*
    1797             :  * Common TX power setup
    1798             :  */
    1799             : void
    1800           0 : ar5k_txpower_table(struct ath_hal *hal, HAL_CHANNEL *channel, int16_t max_power)
    1801             : {
    1802             :         u_int16_t txpower, *rates;
    1803             :         int i, min, max, n;
    1804             : 
    1805           0 :         rates = hal->ah_txpower.txp_rates;
    1806             : 
    1807             :         txpower = AR5K_TUNE_DEFAULT_TXPOWER * 2;
    1808           0 :         if (max_power > txpower) {
    1809             :                 txpower = max_power > AR5K_TUNE_MAX_TXPOWER ?
    1810             :                     AR5K_TUNE_MAX_TXPOWER : max_power;
    1811           0 :         }
    1812             : 
    1813           0 :         for (i = 0; i < AR5K_MAX_RATES; i++)
    1814           0 :                 rates[i] = txpower;
    1815             : 
    1816             :         /* XXX setup target powers by rate */
    1817             : 
    1818           0 :         hal->ah_txpower.txp_min = rates[7];
    1819           0 :         hal->ah_txpower.txp_max = rates[0];
    1820           0 :         hal->ah_txpower.txp_ofdm = rates[0];
    1821             : 
    1822             :         /* Calculate the power table */
    1823             :         n = nitems(hal->ah_txpower.txp_pcdac);
    1824             :         min = AR5K_EEPROM_PCDAC_START;
    1825             :         max = AR5K_EEPROM_PCDAC_STOP;
    1826           0 :         for (i = 0; i < n; i += AR5K_EEPROM_PCDAC_STEP)
    1827           0 :                 hal->ah_txpower.txp_pcdac[i] =
    1828             : #ifdef notyet
    1829             :                     min + ((i * (max - min)) / n);
    1830             : #else
    1831             :                     min;
    1832             : #endif
    1833           0 : }
    1834             : 
    1835             : void
    1836           0 : ar5k_write_ini(struct ath_hal *hal, const struct ar5k_ini *ini,
    1837             :     size_t n, HAL_BOOL change_channel)
    1838             : {
    1839             :         u_int    i;
    1840             : 
    1841           0 :         for (i = 0; i < n; i++) {
    1842           0 :                 if (change_channel == AH_TRUE &&
    1843           0 :                     ini[i].ini_register >= AR5K_PCU_MIN &&
    1844           0 :                     ini[i].ini_register <= AR5K_PCU_MAX)
    1845             :                         continue;
    1846           0 :                 switch (ini[i].ini_mode) {
    1847             :                 case AR5K_INI_READ:
    1848             :                         /* cleared on read */
    1849           0 :                         AR5K_REG_READ((u_int32_t)ini[i].ini_register);
    1850           0 :                         break;
    1851             :                 case AR5K_INI_WRITE:
    1852           0 :                         AR5K_REG_WAIT(i);
    1853           0 :                         AR5K_REG_WRITE((u_int32_t)ini[i].ini_register,
    1854             :                             ini[i].ini_value);
    1855           0 :                         break;
    1856             :                 }
    1857             :         }
    1858           0 : }
    1859             : 
    1860             : void
    1861           0 : ar5k_write_mode(struct ath_hal *hal, const struct ar5k_mode *ini,
    1862             :     size_t n, u_int mode)
    1863             : {
    1864             :         u_int    i;
    1865             : 
    1866           0 :         for (i = 0; i < n; i++) {
    1867           0 :                 AR5K_REG_WAIT(i);
    1868           0 :                 AR5K_REG_WRITE((u_int32_t)ini[i].mode_register,
    1869             :                     ini[i].mode_value[mode]);
    1870             :         }
    1871           0 : }

Generated by: LCOV version 1.13