The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/ic/ar5xxx.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 209259aa45ee71ae8234a438efe62837


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.