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

ar5xxx.c

Go to the documentation of this file.
00001 /*      $OpenBSD: ar5xxx.c,v 1.27 2005/08/02 12:55:11 reyk Exp $        */
00002 
00003 /*
00004  * Copyright (c) 2004, 2005 Reyk Floeter <reyk@vantronix.net>
00005  *
00006  * Permission to use, copy, modify, and distribute this software for any
00007  * purpose with or without fee is hereby granted, provided that the above
00008  * copyright notice and this permission notice appear in all copies.
00009  *
00010  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
00011  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
00012  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
00013  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
00014  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
00015  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
00016  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
00017  */
00018 
00019 /*
00020  * HAL interface for Atheros Wireless LAN devices.
00021  * (Please have a look at ar5xxx.h for further information)
00022  */
00023 
00024 
00025 #include <linux/config.h>
00026 #include <linux/version.h>
00027 #include <linux/module.h>
00028 #include <linux/init.h>
00029 #include <linux/kernel.h>
00030 #include <linux/slab.h>
00031 #include <linux/delay.h>
00032 #include <asm/io.h>
00033 #include <linux/netdevice.h>
00034 #include <linux/random.h>
00035 #include <linux/cache.h>
00036 #include <linux/sysctl.h>
00037 #include <linux/if_arp.h>
00038 
00039 
00040 #include "_ieee80211.h"
00041 #include "ieee80211_regdomain.h"
00042 #include "ah.h"
00043 
00044 
00045 #define PCI_VENDOR_ATHEROS 0x168c
00046 #define PCI_VENDOR_3COM 0x10b7 /* 3Com */
00047 #define PCI_VENDOR_3COM2 0xa727 /* 3Com */
00048 #define PCI_PRODUCT_3COM_3CRDAG675 0x0013 /* 3CRDAG675 (Atheros AR5212) */
00049 #define PCI_PRODUCT_3COM2_3CRPAG175 0x0013 /* 3CRPAG175 (Atheros AR5212) */
00050 #define PCI_PRODUCT_ATHEROS_AR5210 0x0007 /* AR5210 */
00051 #define PCI_PRODUCT_ATHEROS_AR5311 0x0011 /* AR5211 */
00052 #define PCI_PRODUCT_ATHEROS_AR5211 0x0012 /* AR5211 */
00053 #define PCI_PRODUCT_ATHEROS_AR5212 0x0013 /* AR5212 */
00054 #define PCI_PRODUCT_ATHEROS_AR5210_AP 0x0207 /* AR5210 (Early) */
00055 #define PCI_PRODUCT_ATHEROS_AR5212_IBM 0x1014 /* AR5212 (IBM MiniPCI) */
00056 #define PCI_PRODUCT_ATHEROS_AR5210_DEFAULT 0x1107 /* AR5210 (no eeprom) */
00057 #define PCI_PRODUCT_ATHEROS_AR5212_DEFAULT 0x1113 /* AR5212 (no eeprom) */
00058 #define PCI_PRODUCT_ATHEROS_AR5211_DEFAULT 0x1112 /* AR5211 (no eeprom) */
00059 #define PCI_PRODUCT_ATHEROS_AR5212_FPGA 0xf013 /* AR5212 (emulation board) */
00060 #define PCI_PRODUCT_ATHEROS_AR5211_FPGA11B 0xf11b /* AR5211Ref */
00061 #define PCI_PRODUCT_ATHEROS_AR5211_LEGACY 0xff12 /* AR5211Ref */
00062 
00063 
00064 
00065 extern ar5k_attach_t ar5k_ar5212_attach;
00066 
00067 static const struct {
00068         u_int16_t       vendor;
00069         u_int16_t       device;
00070         ar5k_attach_t   (*attach);
00071 } ar5k_known_products[] = {
00072         /*
00073          * From pcidevs_data.h
00074          */
00075         { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5212,
00076             ar5k_ar5212_attach },
00077         { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5212_DEFAULT,
00078             ar5k_ar5212_attach },
00079         { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5212_FPGA,
00080             ar5k_ar5212_attach },
00081         { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5212_IBM,
00082             ar5k_ar5212_attach },
00083         { PCI_VENDOR_3COM, PCI_PRODUCT_3COM_3CRDAG675,
00084             ar5k_ar5212_attach },
00085         { PCI_VENDOR_3COM2, PCI_PRODUCT_3COM2_3CRPAG175,
00086             ar5k_ar5212_attach }
00087 };
00088 
00089 static const HAL_RATE_TABLE ar5k_rt_11a = AR5K_RATES_11A;
00090 static const HAL_RATE_TABLE ar5k_rt_11b = AR5K_RATES_11B;
00091 static const HAL_RATE_TABLE ar5k_rt_11g = AR5K_RATES_11G;
00092 static const HAL_RATE_TABLE ar5k_rt_turbo = AR5K_RATES_TURBO;
00093 //static const HAL_RATE_TABLE ar5k_rt_xr = AR5K_RATES_XR;
00094 
00095 int              ar5k_eeprom_read_ants(struct ath_hal *, u_int32_t *, u_int);
00096 int              ar5k_eeprom_read_modes(struct ath_hal *, u_int32_t *, u_int);
00097 u_int16_t        ar5k_eeprom_bin2freq(struct ath_hal *, u_int16_t, u_int);
00098 
00099 HAL_BOOL         ar5k_ar5110_channel(struct ath_hal *, HAL_CHANNEL *);
00100 u_int32_t        ar5k_ar5110_chan2athchan(HAL_CHANNEL *);
00101 HAL_BOOL         ar5k_ar5111_channel(struct ath_hal *, HAL_CHANNEL *);
00102 HAL_BOOL         ar5k_ar5111_chan2athchan(u_int, struct ar5k_athchan_2ghz *);
00103 HAL_BOOL         ar5k_ar5112_channel(struct ath_hal *, HAL_CHANNEL *);
00104 HAL_BOOL         ar5k_check_channel(struct ath_hal *, u_int16_t, u_int flags);
00105 
00106 HAL_BOOL         ar5k_ar5111_rfregs(struct ath_hal *, HAL_CHANNEL *, u_int);
00107 HAL_BOOL         ar5k_ar5112_rfregs(struct ath_hal *, HAL_CHANNEL *, u_int);
00108 u_int            ar5k_rfregs_op(u_int32_t *, u_int32_t, u_int32_t, u_int32_t,
00109     u_int32_t, u_int32_t, HAL_BOOL);
00110 
00111 
00112 /*
00113  * Supported channels
00114  */
00115 static const struct
00116 ieee80211_regchannel ar5k_5ghz_channels[] = IEEE80211_CHANNELS_5GHZ;
00117 static const struct
00118 ieee80211_regchannel ar5k_2ghz_channels[] = IEEE80211_CHANNELS_2GHZ;
00119 
00120 /*
00121  * Initial gain optimization values
00122  */
00123 static const struct ar5k_gain_opt ar5111_gain_opt = AR5K_AR5111_GAIN_OPT;
00124 static const struct ar5k_gain_opt ar5112_gain_opt = AR5K_AR5112_GAIN_OPT;
00125 
00126 /*
00127  * Initial register for the radio chipsets
00128  */
00129 static const struct ar5k_ini_rf ar5111_rf[] = AR5K_AR5111_INI_RF;
00130 static const struct ar5k_ini_rf ar5112_rf[] = AR5K_AR5112_INI_RF;
00131 static const struct ar5k_ini_rfgain ar5k_rfg[] = AR5K_INI_RFGAIN;
00132 
00133 /*
00134  * Enable to overwrite the country code (use "00" for debug)
00135  */
00136 #if 0
00137 #define COUNTRYCODE "00"
00138 #endif
00139 
00140 /*
00141  * Perform a lookup if the device is supported by the HAL
00142  */
00143 const char *
00144 ath_hal_probe(vendor, device)
00145         u_int16_t vendor;
00146         u_int16_t device;
00147 {
00148         int i;
00149 
00150         /*
00151          * Perform a linear search on the table of supported devices
00152          */
00153         for (i = 0; i < AR5K_ELEMENTS(ar5k_known_products); i++) {
00154                 if (vendor == ar5k_known_products[i].vendor &&
00155                     device == ar5k_known_products[i].device)
00156                         return ("");
00157         }
00158 
00159         return (0);
00160 }
00161 
00162 
00163 struct ath_hal *
00164 _ath_hal_attach(u_int16_t devid, HAL_SOFTC sc,
00165                 HAL_BUS_TAG t, HAL_BUS_HANDLE h, void* s)
00166 {
00167         HAL_STATUS status;
00168         struct ath_hal *ah = ath_hal_attach(devid, sc, t, h, &status);
00169 
00170         *(HAL_STATUS *)s = status;
00171 //      if (ah)
00172 //              MOD_INC_USE_COUNT;
00173         return ah;
00174 }
00175 
00176 void
00177 ath_hal_detach(struct ath_hal *ah)
00178 {
00179         (*ah->ah_detach)(ah);
00180 //      MOD_DEC_USE_COUNT;
00181 }
00182 /*
00183  * Fills in the HAL structure and initialises the device
00184  */
00185 struct ath_hal *
00186 ath_hal_attach(u_int16_t device,
00187                HAL_SOFTC sc,
00188                HAL_BUS_TAG st,
00189                HAL_BUS_HANDLE sh,
00190                HAL_STATUS *status)
00191 {
00192         u_int32_t ieee_regdomain;
00193         u_int16_t regdomain;
00194         struct ath_hal *hal = NULL;
00195         ar5k_attach_t *attach = NULL;
00196         u_int8_t mac[IEEE80211_ADDR_LEN];
00197         int i;
00198 
00199         *status = EINVAL;
00200 
00201         /*
00202          * Call the chipset-dependent attach routine by device id
00203          */
00204         for (i = 0; i < AR5K_ELEMENTS(ar5k_known_products); i++) {
00205                 if (device == ar5k_known_products[i].device &&
00206                     ar5k_known_products[i].attach != NULL) {
00207                         attach = ar5k_known_products[i].attach;
00208                 }
00209         }
00210 
00211         if (attach == NULL) {
00212                 *status = ENXIO;
00213                 AR5K_PRINTF("device not supported: 0x%04x\n", device);
00214                 return (NULL);
00215         }
00216 
00217         if ((hal = (struct ath_hal *) kmalloc(sizeof(struct ath_hal), GFP_KERNEL)) == NULL) {
00218                 *status = ENOMEM;
00219                 AR5K_PRINT("out of memory\n");
00220                 return (NULL);
00221         }
00222 
00223         bzero(hal, sizeof(struct ath_hal));
00224 
00225         hal->ah_sc = sc;
00226         hal->ah_st = st;
00227         hal->ah_sh = sh;
00228         hal->ah_device = device;
00229         hal->ah_sub_vendor = 0; /* XXX unknown?! */
00230 
00231         /*
00232          * HAL information
00233          */
00234         hal->ah_abi = HAL_ABI_VERSION;
00235         hal->ah_country_code = CTRY_DEFAULT;
00236         hal->ah_capabilities.reg_current = 0x10;
00237         hal->ah_op_mode = HAL_M_STA;
00238         hal->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT;
00239         hal->ah_turbo = AH_FALSE;
00240         hal->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
00241         hal->ah_imr = 0;
00242         hal->ah_atim_window = 0;
00243         hal->ah_aifs = AR5K_TUNE_AIFS;
00244         hal->ah_cw_min = AR5K_TUNE_CWMIN;
00245         hal->ah_limit_tx_retries = AR5K_INIT_TX_RETRY;
00246         hal->ah_software_retry = AH_FALSE;
00247         hal->ah_ant_diversity = AR5K_TUNE_ANT_DIVERSITY;
00248 
00249         if ((attach)(device, hal, st, sh, status) == NULL)
00250                 goto failed;
00251 
00252 
00253         /*
00254          * Get card capabilities, values, ...
00255          */
00256 
00257         if (ar5k_eeprom_init(hal) != 0) {
00258                 AR5K_PRINT("unable to init EEPROM\n");
00259                 goto failed;
00260         }
00261 
00262         /* Set regulation domain */
00263         if ((regdomain =
00264                 hal->ah_capabilities.cap_eeprom.ee_regdomain) != 0) {
00265                 hal->ah_capabilities.reg_current =
00266                     ieee_regdomain = ar5k_regdomain_to_ieee(regdomain);
00267         } else {
00268                 ieee_regdomain =
00269                     hal->ah_capabilities.reg_current;
00270 
00271                 /* Try to write default regulation domain to EEPROM */
00272                 ar5k_eeprom_regulation_domain(hal, AH_TRUE, &ieee_regdomain);
00273         }
00274 
00275         hal->ah_capabilities.reg_hw = ieee_regdomain;
00276 
00277         /* Get misc capabilities */
00278         if (hal->ah_get_capabilities(hal) != AH_TRUE) {
00279                 AR5K_PRINTF("unable to get device capabilities: 0x%04x\n",
00280                             device);
00281                 goto failed;
00282         }
00283 
00284         /* Get MAC address */
00285         if ((*status = ar5k_eeprom_read_mac(hal, mac)) != 0) {
00286                 AR5K_PRINTF("unable to read address from EEPROM: 0x%04x\n",
00287                     device);
00288                 goto failed;
00289         }
00290 
00291         hal->ah_setMacAddress(hal, mac);
00292 
00293         /* Get rate tables */
00294         if (hal->ah_capabilities.cap_mode & HAL_MODE_11A)
00295                 ar5k_rt_copy(&hal->ah_rt_11a, &ar5k_rt_11a);
00296         if (hal->ah_capabilities.cap_mode & HAL_MODE_11B)
00297                 ar5k_rt_copy(&hal->ah_rt_11b, &ar5k_rt_11b);
00298         if (hal->ah_capabilities.cap_mode & HAL_MODE_11G)
00299                 ar5k_rt_copy(&hal->ah_rt_11g, &ar5k_rt_11g);
00300         if (hal->ah_capabilities.cap_mode & HAL_MODE_TURBO)
00301                 ar5k_rt_copy(&hal->ah_rt_turbo, &ar5k_rt_turbo);
00302         //if (hal->ah_capabilities.cap_mode & HAL_MODE_XR)
00303                 //ar5k_rt_copy(&hal->ah_rt_xr, &ar5k_rt_xr);
00304 
00305         /* Initialize the gain optimization values */
00306         if (hal->ah_radio == AR5K_AR5111) {
00307                 hal->ah_gain.g_step_idx = ar5111_gain_opt.go_default;
00308                 hal->ah_gain.g_step =
00309                     &ar5111_gain_opt.go_step[hal->ah_gain.g_step_idx];
00310                 hal->ah_gain.g_low = 20;
00311                 hal->ah_gain.g_high = 35;
00312                 hal->ah_gain.g_active = 1;
00313         } else if (hal->ah_radio == AR5K_AR5112) {
00314                 hal->ah_gain.g_step_idx = ar5112_gain_opt.go_default;
00315                 hal->ah_gain.g_step =
00316                     &ar5111_gain_opt.go_step[hal->ah_gain.g_step_idx];
00317                 hal->ah_gain.g_low = 20;
00318                 hal->ah_gain.g_high = 85;
00319                 hal->ah_gain.g_active = 1;
00320         }
00321 
00322         *status = HAL_OK;
00323 
00324         return (hal);
00325 
00326  failed:
00327         kfree(hal);
00328         return (NULL);
00329 }
00330 
00331 u_int16_t
00332 ath_hal_computetxtime(hal, rates, frame_length, rate_index, short_preamble)
00333         struct ath_hal *hal;
00334         const HAL_RATE_TABLE *rates;
00335         u_int32_t frame_length;
00336         u_int16_t rate_index;
00337         HAL_BOOL short_preamble;
00338 {
00339         const HAL_RATE *rate;
00340         u_int32_t value;
00341 
00342         AR5K_ASSERT_ENTRY(rate_index, rates->rateCount);
00343 
00344         /*
00345          * Get rate by index
00346          */
00347         rate = &rates->info[rate_index];
00348 
00349         /*
00350          * Calculate the transmission time by operation (PHY) mode
00351          */
00352         switch (rate->phy) {
00353         case IEEE80211_T_CCK:
00354                 /*
00355                  * CCK / DS mode (802.11b)
00356                  */
00357                 value = AR5K_CCK_TX_TIME(rate->rateKbps, frame_length,
00358                     (short_preamble && rate->shortPreamble));
00359                 break;
00360 
00361         case IEEE80211_T_OFDM:
00362                 /*
00363                  * Orthogonal Frequency Division Multiplexing
00364                  */
00365                 if (AR5K_OFDM_NUM_BITS_PER_SYM(rate->rateKbps) == 0)
00366                         return (0);
00367                 value = AR5K_OFDM_TX_TIME(rate->rateKbps, frame_length);
00368                 break;
00369 
00370         case IEEE80211_T_TURBO:
00371                 /*
00372                  * Orthogonal Frequency Division Multiplexing
00373                  * Atheros "Turbo Mode" (doubled rates)
00374                  */
00375                 if (AR5K_TURBO_NUM_BITS_PER_SYM(rate->rateKbps) == 0)
00376                         return (0);
00377                 value = AR5K_TURBO_TX_TIME(rate->rateKbps, frame_length);
00378                 break;
00379 
00380                 /* case IEEE80211_T_XR: */
00381                 /*
00382                  * Orthogonal Frequency Division Multiplexing
00383                  * Atheros "eXtended Range" (XR)
00384                  */
00385                 /*
00386                 if (AR5K_XR_NUM_BITS_PER_SYM(rate->rateKbps) == 0)
00387                         return (0);
00388                 value = AR5K_XR_TX_TIME(rate->rateKbps, frame_length);
00389                 break;
00390                 */
00391         default:
00392                 return (0);
00393         }
00394 
00395         return (value);
00396 }
00397 
00398 
00399 u_int
00400 ath_hal_mhz2ieee(mhz, flags)
00401         u_int mhz;
00402         u_int flags;
00403 {
00404         if (flags & IEEE80211_CHAN_2GHZ) {      /* 2GHz band */
00405                 if (mhz == 2484)
00406                         return 14;
00407                 if (mhz < 2484)
00408                         return (mhz - 2407) / 5;
00409                 else
00410                         return 15 + ((mhz - 2512) / 20);
00411         } else if (flags & IEEE80211_CHAN_5GHZ) {       /* 5Ghz band */
00412                 return (mhz - 5000) / 5;
00413         } else {                                /* either, guess */
00414                 if (mhz == 2484)
00415                         return 14;
00416                 if (mhz < 2484)
00417                         return (mhz - 2407) / 5;
00418                 if (mhz < 5000)
00419                         return 15 + ((mhz - 2512) / 20);
00420                 return (mhz - 5000) / 5;
00421         }
00422 }
00423 
00424 u_int
00425 ath_hal_ieee2mhz(ieee, flags)
00426         u_int ieee;
00427         u_int flags;
00428 {       if (flags & IEEE80211_CHAN_2GHZ) {      /* 2GHz band */
00429                 if (ieee == 14)
00430                         return 2484;
00431                 if (ieee < 14)
00432                         return 2407 + ieee*5;
00433                 else
00434                         return 2512 + ((ieee-15)*20);
00435         } else if (flags & IEEE80211_CHAN_5GHZ) {/* 5Ghz band */
00436                 return 5000 + (ieee*5);
00437         } else {                                /* either, guess */
00438                 if (ieee == 14)
00439                         return 2484;
00440                 if (ieee < 14)                  /* 0-13 */
00441                         return 2407 + ieee*5;
00442                 if (ieee < 27)                  /* 15-26 */
00443                         return 2512 + ((ieee-15)*20);
00444                 return 5000 + (ieee*5);
00445         }
00446 }
00447 
00448 HAL_BOOL
00449 ar5k_check_channel(hal, freq, flags)
00450         struct ath_hal *hal;
00451         u_int16_t freq;
00452         u_int flags;
00453 {
00454         /* Check if the channel is in our supported range */
00455         if (flags & IEEE80211_CHAN_2GHZ) {
00456                 if ((freq >= hal->ah_capabilities.cap_range.range_2ghz_min) &&
00457                     (freq <= hal->ah_capabilities.cap_range.range_2ghz_max))
00458                         return (AH_TRUE);
00459         } else if (flags & IEEE80211_CHAN_5GHZ) {
00460                 if ((freq >= hal->ah_capabilities.cap_range.range_5ghz_min) &&
00461                     (freq <= hal->ah_capabilities.cap_range.range_5ghz_max))
00462                         return (AH_TRUE);
00463         }
00464 
00465         return (AH_FALSE);
00466 }
00467 
00468 HAL_BOOL
00469 ath_hal_init_channels(hal, channels, max_channels, channels_size, country, mode,
00470     outdoor, extended)
00471         struct ath_hal *hal;
00472         HAL_CHANNEL *channels;
00473         u_int max_channels;
00474         u_int *channels_size;
00475         HAL_CTRY_CODE country;
00476         u_int16_t mode;
00477         HAL_BOOL outdoor;
00478         HAL_BOOL extended;
00479 {
00480         u_int i, c;
00481         u_int32_t domain_current;
00482         HAL_CHANNEL *all_channels;
00483 
00484         AR5K_TRACE;
00485 
00486         if ((all_channels = (HAL_CHANNEL *) kmalloc(sizeof(HAL_CHANNEL) * max_channels, GFP_KERNEL)) == 0)
00487                 return (AH_FALSE);
00488 
00489         i = c = 0;
00490         domain_current = hal->ah_regdomain;
00491 
00492         /*
00493          * In debugging mode, enable all channels supported by the chipset
00494          */
00495         for (i = 0; i < sizeof(ar5k_2ghz_channels)/sizeof(struct ieee80211_regchannel); i++) {
00496                 all_channels[c].channel = ar5k_2ghz_channels[i].rc_channel;
00497                 all_channels[c].channelFlags = ar5k_2ghz_channels[i].rc_mode;
00498                 c++;
00499         }
00500         for (i = 0; i < sizeof(ar5k_5ghz_channels)/sizeof(struct ieee80211_regchannel); i++) {
00501                 all_channels[c].channel = ar5k_5ghz_channels[i].rc_channel;
00502                 all_channels[c].channelFlags = ar5k_5ghz_channels[i].rc_mode;
00503                 c++;
00504         }
00505 
00506         bcopy(all_channels, channels, sizeof(HAL_CHANNEL) * max_channels);
00507         *channels_size = c;
00508         kfree(all_channels);
00509         return (AH_TRUE);
00510 }
00511 
00512 /*
00513  * Common internal functions
00514  */
00515 
00516 const char *
00517 ar5k_printver(type, val)
00518         enum ar5k_srev_type type;
00519         u_int32_t val;
00520 {
00521         struct ar5k_srev_name names[] = AR5K_SREV_NAME;
00522         const char *name = "xxxx";
00523         int i;
00524 
00525         for (i = 0; i < AR5K_ELEMENTS(names); i++) {
00526                 if (names[i].sr_type != type ||
00527                     names[i].sr_val == AR5K_SREV_UNKNOWN)
00528                         continue;
00529                 if (val < names[i + 1].sr_val) {
00530                         name = names[i].sr_name;
00531                         break;
00532                 }
00533         }
00534 
00535         return (name);
00536 }
00537 
00538 void
00539 ar5k_radar_alert(hal)
00540         struct ath_hal *hal;
00541 {
00542         /*
00543          * Limit ~1/s
00544          */
00545         /*
00546         if (hal->ah_radar.r_last_channel.channel ==
00547             hal->ah_current_channel.channel &&
00548             tick < (hal->ah_radar.r_last_alert + hz))
00549         */              return;
00550 
00551         hal->ah_radar.r_last_channel.channel =
00552             hal->ah_current_channel.channel;
00553         hal->ah_radar.r_last_channel.channelFlags =
00554             hal->ah_current_channel.channelFlags;
00555         //hal->ah_radar.r_last_alert = tick;
00556 
00557         AR5K_PRINTF("Possible radar activity detected at %u MHz (tick %u)\n",
00558             hal->ah_radar.r_last_alert, hal->ah_current_channel.channel);
00559 }
00560 
00561 u_int16_t
00562 ar5k_regdomain_from_ieee(ieee)
00563         ieee80211_regdomain_t ieee;
00564 {
00565         u_int32_t regdomain = (u_int32_t)ieee;
00566 
00567         if (regdomain & 0xf0000000)
00568                 return ((u_int16_t)AR5K_TUNE_REGDOMAIN);
00569 
00570         return (regdomain & 0xff);
00571 }
00572 
00573 ieee80211_regdomain_t
00574 ar5k_regdomain_to_ieee(regdomain)
00575         u_int16_t regdomain;
00576 {
00577         ieee80211_regdomain_t ieee = (ieee80211_regdomain_t)regdomain & 0xff;
00578 
00579         return (ieee);
00580 }
00581 
00582 u_int16_t
00583 ar5k_get_regdomain(hal)
00584         struct ath_hal *hal;
00585 {
00586         AR5K_TRACE;
00587         
00588         return DMN_FCC1;
00589 
00590 #ifndef COUNTRYCODE
00591         /*
00592          * Use the regulation domain found in the EEPROM, if not
00593          * forced by a static country code.
00594          */
00595         u_int16_t regdomain;
00596         ieee80211_regdomain_t ieee_regdomain;
00597 
00598         if (ar5k_eeprom_regulation_domain(hal,
00599             AH_FALSE, &ieee_regdomain) == AH_TRUE) {
00600                 if ((regdomain = ar5k_regdomain_from_ieee(ieee_regdomain)))
00601                         return (regdomain);
00602         }
00603 
00604         return (hal->ah_regdomain);
00605 #else
00606         /*
00607          * Get the regulation domain by country code. This will ignore
00608          * the settings found in the EEPROM.
00609          */
00610         u_int16_t code;
00611 
00612         code = ieee80211_name2countrycode(COUNTRYCODE);
00613         return (ieee80211_countrycode2regdomain(code));
00614 #endif
00615 }
00616 
00617 u_int32_t
00618 ar5k_bitswap(val, bits)
00619         u_int32_t val;
00620         u_int bits;
00621 {
00622         u_int32_t retval = 0, bit, i;
00623 
00624         for (i = 0; i < bits; i++) {
00625                 bit = (val >> i) & 1;
00626                 retval = (retval << 1) | bit;
00627         }
00628 
00629         return (retval);
00630 }
00631 
00632 u_int
00633 ar5k_htoclock(usec, turbo)
00634         u_int usec;
00635         HAL_BOOL turbo;
00636 {
00637         return (turbo == AH_TRUE ? (usec * 80) : (usec * 40));
00638 }
00639 
00640 u_int
00641 ar5k_clocktoh(clock, turbo)
00642         u_int clock;
00643         HAL_BOOL turbo;
00644 {
00645         return (turbo == AH_TRUE ? (clock / 80) : (clock / 40));
00646 }
00647 
00648 void
00649 ar5k_rt_copy(dst, src)
00650         HAL_RATE_TABLE *dst;
00651         const HAL_RATE_TABLE *src;
00652 {
00653         bzero(dst, sizeof(HAL_RATE_TABLE));
00654         dst->rateCount = src->rateCount;
00655         bcopy(src->info, dst->info, sizeof(dst->info));
00656 }
00657 
00658 HAL_BOOL
00659 ar5k_register_timeout(hal, reg, flag, val, is_set)
00660         struct ath_hal *hal;
00661         u_int32_t reg;
00662         u_int32_t flag;
00663         u_int32_t val;
00664         HAL_BOOL is_set;
00665 {
00666         int i;
00667         u_int32_t data;
00668 
00669         for (i = AR5K_TUNE_REGISTER_TIMEOUT; i > 0; i--) {
00670                 data = AR5K_REG_READ(reg);
00671                 if ((is_set == AH_TRUE) && (data & flag))
00672                         break;
00673                 else if ((data & flag) == val)
00674                         break;
00675                 AR5K_DELAY(15);
00676         }
00677 
00678         if (i <= 0)
00679                 return (AH_FALSE);
00680 
00681         return (AH_TRUE);
00682 }
00683 
00684 /*
00685  * Common ar5xx EEPROM access functions
00686  */
00687 
00688 u_int16_t
00689 ar5k_eeprom_bin2freq(hal, bin, mode)
00690         struct ath_hal *hal;
00691         u_int16_t bin;
00692         u_int mode;
00693 {
00694         u_int16_t val;
00695 
00696         if (bin == AR5K_EEPROM_CHANNEL_DIS)
00697                 return (bin);
00698 
00699         if (mode == AR5K_EEPROM_MODE_11A) {
00700                 if (hal->ah_ee_version > AR5K_EEPROM_VERSION_3_2)
00701                         val = (5 * bin) + 4800;
00702                 else
00703                         val = bin > 62 ?
00704                             (10 * 62) + (5 * (bin - 62)) + 5100 :
00705                             (bin * 10) + 5100;
00706         } else {
00707                 if (hal->ah_ee_version > AR5K_EEPROM_VERSION_3_2)
00708                         val = bin + 2300;
00709                 else
00710                         val = bin + 2400;
00711         }
00712 
00713         return (val);
00714 }
00715 
00716 int
00717 ar5k_eeprom_read_ants(hal, offset, mode)
00718         struct ath_hal *hal;
00719         u_int32_t *offset;
00720         u_int mode;
00721 {
00722         struct ar5k_eeprom_info *ee = &hal->ah_capabilities.cap_eeprom;
00723         u_int32_t o = *offset;
00724         u_int16_t val;
00725         int ret, i = 0;
00726 
00727         AR5K_EEPROM_READ(o++, val);
00728         ee->ee_switch_settling[mode]    = (val >> 8) & 0x7f;
00729         ee->ee_ant_tx_rx[mode]          = (val >> 2) & 0x3f;
00730         ee->ee_ant_control[mode][i]     = (val << 4) & 0x3f;
00731 
00732         AR5K_EEPROM_READ(o++, val);
00733         ee->ee_ant_control[mode][i++]   |= (val >> 12) & 0xf;
00734         ee->ee_ant_control[mode][i++]   = (val >> 6) & 0x3f;
00735         ee->ee_ant_control[mode][i++]   = val & 0x3f;
00736 
00737         AR5K_EEPROM_READ(o++, val);
00738         ee->ee_ant_control[mode][i++]   = (val >> 10) & 0x3f;
00739         ee->ee_ant_control[mode][i++]   = (val >> 4) & 0x3f;
00740         ee->ee_ant_control[mode][i]     = (val << 2) & 0x3f;
00741 
00742         AR5K_EEPROM_READ(o++, val);
00743         ee->ee_ant_control[mode][i++]   |= (val >> 14) & 0x3;
00744         ee->ee_ant_control[mode][i++]   = (val >> 8) & 0x3f;
00745         ee->ee_ant_control[mode][i++]   = (val >> 2) & 0x3f;
00746         ee->ee_ant_control[mode][i]     = (val << 4) & 0x3f;
00747 
00748         AR5K_EEPROM_READ(o++, val);
00749         ee->ee_ant_control[mode][i++]   |= (val >> 12) & 0xf;
00750         ee->ee_ant_control[mode][i++]   = (val >> 6) & 0x3f;
00751         ee->ee_ant_control[mode][i++]   = val & 0x3f;
00752 
00753         /* Get antenna modes */
00754         hal->ah_antenna[mode][0] =
00755             (ee->ee_ant_control[mode][0] << 4) | 0x1;
00756         hal->ah_antenna[mode][HAL_ANT_FIXED_A] =
00757             ee->ee_ant_control[mode][1] |
00758             (ee->ee_ant_control[mode][2] << 6) |
00759             (ee->ee_ant_control[mode][3] << 12) |
00760             (ee->ee_ant_control[mode][4] << 18) |
00761             (ee->ee_ant_control[mode][5] << 24);
00762         hal->ah_antenna[mode][HAL_ANT_FIXED_B] =
00763             ee->ee_ant_control[mode][6] |
00764             (ee->ee_ant_control[mode][7] << 6) |
00765             (ee->ee_ant_control[mode][8] << 12) |
00766             (ee->ee_ant_control[mode][9] << 18) |
00767             (ee->ee_ant_control[mode][10] << 24);
00768 
00769         /* return new offset */
00770         *offset = o;
00771 
00772         return (0);
00773 }
00774 
00775 int
00776 ar5k_eeprom_read_modes(hal, offset, mode)
00777         struct ath_hal *hal;
00778         u_int32_t *offset;
00779         u_int mode;
00780 {
00781         struct ar5k_eeprom_info *ee = &hal->ah_capabilities.cap_eeprom;
00782         u_int32_t o = *offset;
00783         u_int16_t val;
00784         int ret;
00785 
00786         AR5K_EEPROM_READ(o++, val);
00787         ee->ee_tx_end2xlna_enable[mode] = (val >> 8) & 0xff;
00788         ee->ee_thr_62[mode]             = val & 0xff;
00789 
00790         if (hal->ah_ee_version <= AR5K_EEPROM_VERSION_3_2)
00791                 ee->ee_thr_62[mode] =
00792                     mode == AR5K_EEPROM_MODE_11A ? 15 : 28;
00793 
00794         AR5K_EEPROM_READ(o++, val);
00795         ee->ee_tx_end2xpa_disable[mode] = (val >> 8) & 0xff;
00796         ee->ee_tx_frm2xpa_enable[mode]  = val & 0xff;
00797 
00798         AR5K_EEPROM_READ(o++, val);
00799         ee->ee_pga_desired_size[mode]   = (val >> 8) & 0xff;
00800 
00801         if ((val & 0xff) & 0x80)
00802                 ee->ee_noise_floor_thr[mode] = -((((val & 0xff) ^ 0xff)) + 1);
00803         else
00804                 ee->ee_noise_floor_thr[mode] = val & 0xff;
00805 
00806         if (hal->ah_ee_version <= AR5K_EEPROM_VERSION_3_2)
00807                 ee->ee_noise_floor_thr[mode] =
00808                     mode == AR5K_EEPROM_MODE_11A ? -54 : -1;
00809 
00810         AR5K_EEPROM_READ(o++, val);
00811         ee->ee_xlna_gain[mode]          = (val >> 5) & 0xff;
00812         ee->ee_x_gain[mode]             = (val >> 1) & 0xf;
00813         ee->ee_xpd[mode]                = val & 0x1;
00814 
00815         if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_0)
00816                 ee->ee_fixed_bias[mode] = (val >> 13) & 0x1;
00817 
00818         if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_3_3) {
00819                 AR5K_EEPROM_READ(o++, val);
00820                 ee->ee_false_detect[mode] = (val >> 6) & 0x7f;
00821 
00822                 if (mode == AR5K_EEPROM_MODE_11A)
00823                         ee->ee_xr_power[mode] = val & 0x3f;
00824                 else {
00825                         ee->ee_ob[mode][0] = val & 0x7;
00826                         ee->ee_db[mode][0] = (val >> 3) & 0x7;
00827                 }
00828         }
00829 
00830         if (hal->ah_ee_version < AR5K_EEPROM_VERSION_3_4) {
00831                 ee->ee_i_gain[mode] = AR5K_EEPROM_I_GAIN;
00832                 ee->ee_cck_ofdm_power_delta = AR5K_EEPROM_CCK_OFDM_DELTA;
00833         } else {
00834                 ee->ee_i_gain[mode] = (val >> 13) & 0x7;
00835 
00836                 AR5K_EEPROM_READ(o++, val);
00837                 ee->ee_i_gain[mode] |= (val << 3) & 0x38;
00838 
00839                 if (mode == AR5K_EEPROM_MODE_11G)
00840                         ee->ee_cck_ofdm_power_delta = (val >> 3) & 0xff;
00841         }
00842 
00843         if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_0 &&
00844             mode == AR5K_EEPROM_MODE_11A) {
00845                 ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
00846                 ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
00847         }
00848 
00849         if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_6 &&
00850             mode == AR5K_EEPROM_MODE_11G)
00851                 ee->ee_scaled_cck_delta = (val >> 11) & 0x1f;
00852 
00853         /* return new offset */
00854         *offset = o;
00855 
00856         return (0);
00857 }
00858 
00859 
00860 u_int 
00861 ath_hal_getwirelessmodes(struct ath_hal *hal, HAL_CTRY_CODE country) 
00862 {
00863         /* XXX */
00864         return (HAL_MODE_11A | HAL_MODE_11B | HAL_MODE_11G);
00865 
00866 }
00867 int
00868 ar5k_eeprom_init(hal)
00869         struct ath_hal *hal;
00870 {
00871         struct ar5k_eeprom_info *ee = &hal->ah_capabilities.cap_eeprom;
00872         u_int32_t offset;
00873         u_int16_t val;
00874         int ret, i;
00875         u_int mode;
00876 
00877         AR5K_TRACE;
00878 
00879 
00880         /* Initial TX thermal adjustment values */
00881         ee->ee_tx_clip = 4;
00882         ee->ee_pwd_84 = ee->ee_pwd_90 = 1;
00883         ee->ee_gain_select = 1;
00884 
00885         /*
00886          * Read values from EEPROM and store them in the capability structure
00887          */
00888         AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MAGIC, ee_magic);
00889         AR5K_EEPROM_READ_HDR(AR5K_EEPROM_PROTECT, ee_protect);
00890         AR5K_EEPROM_READ_HDR(AR5K_EEPROM_REG_DOMAIN, ee_regdomain);
00891         AR5K_EEPROM_READ_HDR(AR5K_EEPROM_VERSION, ee_version);
00892         AR5K_EEPROM_READ_HDR(AR5K_EEPROM_HDR, ee_header);
00893 
00894         /* Return if we have an old EEPROM */
00895         if (hal->ah_ee_version < AR5K_EEPROM_VERSION_3_0)
00896                 return (0);
00897 
00898         AR5K_EEPROM_READ_HDR(AR5K_EEPROM_ANT_GAIN(hal->ah_ee_version),
00899             ee_ant_gain);
00900 
00901         if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
00902                 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC0, ee_misc0);
00903                 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC1, ee_misc1);
00904         }
00905 
00906         if (hal->ah_ee_version < AR5K_EEPROM_VERSION_3_3) {
00907                 AR5K_EEPROM_READ(AR5K_EEPROM_OBDB0_2GHZ, val);
00908                 ee->ee_ob[AR5K_EEPROM_MODE_11B][0] = val & 0x7;
00909                 ee->ee_db[AR5K_EEPROM_MODE_11B][0] = (val >> 3) & 0x7;
00910 
00911                 AR5K_EEPROM_READ(AR5K_EEPROM_OBDB1_2GHZ, val);
00912                 ee->ee_ob[AR5K_EEPROM_MODE_11G][0] = val & 0x7;
00913                 ee->ee_db[AR5K_EEPROM_MODE_11G][0] = (val >> 3) & 0x7;
00914         }
00915 
00916         /*
00917          * Get conformance test limit values
00918          */
00919         offset = AR5K_EEPROM_CTL(hal->ah_ee_version);
00920         ee->ee_ctls = AR5K_EEPROM_N_CTLS(hal->ah_ee_version);
00921 
00922         for (i = 0; i < ee->ee_ctls; i++) {
00923                 AR5K_EEPROM_READ(offset++, val);
00924                 ee->ee_ctl[i] = (val >> 8) & 0xff;
00925                 ee->ee_ctl[i + 1] = val & 0xff;
00926         }
00927 
00928         /*
00929          * Get values for 802.11a (5GHz)
00930          */
00931         mode = AR5K_EEPROM_MODE_11A;
00932 
00933         ee->ee_turbo_max_power[mode] =
00934             AR5K_EEPROM_HDR_T_5GHZ_DBM(ee->ee_header);
00935 
00936         offset = AR5K_EEPROM_MODES_11A(hal->ah_ee_version);
00937 
00938         if ((ret = ar5k_eeprom_read_ants(hal, &offset, mode)) != 0)
00939                 return (ret);
00940 
00941         AR5K_EEPROM_READ(offset++, val);
00942         ee->ee_adc_desired_size[mode]   = (int8_t)((val >> 8) & 0xff);
00943         ee->ee_ob[mode][3]              = (val >> 5) & 0x7;
00944         ee->ee_db[mode][3]              = (val >> 2) & 0x7;
00945         ee->ee_ob[mode][2]              = (val << 1) & 0x7;
00946 
00947         AR5K_EEPROM_READ(offset++, val);
00948         ee->ee_ob[mode][2]              |= (val >> 15) & 0x1;
00949         ee->ee_db[mode][2]              = (val >> 12) & 0x7;
00950         ee->ee_ob[mode][1]              = (val >> 9) & 0x7;
00951         ee->ee_db[mode][1]              = (val >> 6) & 0x7;
00952         ee->ee_ob[mode][0]              = (val >> 3) & 0x7;
00953         ee->ee_db[mode][0]              = val & 0x7;
00954 
00955         if ((ret = ar5k_eeprom_read_modes(hal, &offset, mode)) != 0)
00956                 return (ret);
00957 
00958         if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) {
00959                 AR5K_EEPROM_READ(offset++, val);
00960                 ee->ee_margin_tx_rx[mode] = val & 0x3f;
00961         }
00962 
00963         /*
00964          * Get values for 802.11b (2.4GHz)
00965          */
00966         mode = AR5K_EEPROM_MODE_11B;
00967         offset = AR5K_EEPROM_MODES_11B(hal->ah_ee_version);
00968 
00969         if ((ret = ar5k_eeprom_read_ants(hal, &offset, mode)) != 0)
00970                 return (ret);
00971 
00972         AR5K_EEPROM_READ(offset++, val);
00973         ee->ee_adc_desired_size[mode]   = (int8_t)((val >> 8) & 0xff);
00974         ee->ee_ob[mode][1]              = (val >> 4) & 0x7;
00975         ee->ee_db[mode][1]              = val & 0x7;
00976 
00977         if ((ret = ar5k_eeprom_read_modes(hal, &offset, mode)) != 0)
00978                 return (ret);
00979 
00980         if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
00981                 AR5K_EEPROM_READ(offset++, val);
00982                 ee->ee_cal_pier[mode][0] =
00983                     ar5k_eeprom_bin2freq(hal, val & 0xff, mode);
00984                 ee->ee_cal_pier[mode][1] =
00985                     ar5k_eeprom_bin2freq(hal, (val >> 8) & 0xff, mode);
00986 
00987                 AR5K_EEPROM_READ(offset++, val);
00988                 ee->ee_cal_pier[mode][2] =
00989                     ar5k_eeprom_bin2freq(hal, val & 0xff, mode);
00990         }
00991 
00992         if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) {
00993                 ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
00994         }
00995 
00996         /*
00997          * Get values for 802.11g (2.4GHz)
00998          */
00999         mode = AR5K_EEPROM_MODE_11G;
01000         offset = AR5K_EEPROM_MODES_11G(hal->ah_ee_version);
01001 
01002         if ((ret = ar5k_eeprom_read_ants(hal, &offset, mode)) != 0)
01003                 return (ret);
01004 
01005         AR5K_EEPROM_READ(offset++, val);
01006         ee->ee_adc_desired_size[mode]   = (int8_t)((val >> 8) & 0xff);
01007         ee->ee_ob[mode][1]              = (val >> 4) & 0x7;
01008         ee->ee_db[mode][1]              = val & 0x7;
01009 
01010         if ((ret = ar5k_eeprom_read_modes(hal, &offset, mode)) != 0)
01011                 return (ret);
01012 
01013         if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
01014                 AR5K_EEPROM_READ(offset++, val);
01015                 ee->ee_cal_pier[mode][0] =
01016                     ar5k_eeprom_bin2freq(hal, val & 0xff, mode);
01017                 ee->ee_cal_pier[mode][1] =
01018                     ar5k_eeprom_bin2freq(hal, (val >> 8) & 0xff, mode);
01019 
01020                 AR5K_EEPROM_READ(offset++, val);
01021                 ee->ee_turbo_max_power[mode] = val & 0x7f;
01022                 ee->ee_xr_power[mode] = (val >> 7) & 0x3f;
01023 
01024                 AR5K_EEPROM_READ(offset++, val);
01025                 ee->ee_cal_pier[mode][2] =
01026                     ar5k_eeprom_bin2freq(hal, val & 0xff, mode);
01027 
01028                 if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) {
01029                         ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
01030                 }
01031 
01032                 AR5K_EEPROM_READ(offset++, val);
01033                 ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
01034                 ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
01035 
01036                 if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_2) {
01037                         AR5K_EEPROM_READ(offset++, val);
01038                         ee->ee_cck_ofdm_gain_delta = val & 0xff;
01039                 }
01040         }
01041 
01042         /*
01043          * Read 5GHz EEPROM channels
01044          */
01045 
01046         return (0);
01047 }
01048 
01049 int
01050 ar5k_eeprom_read_mac(hal, mac)
01051         struct ath_hal *hal;
01052         u_int8_t *mac;
01053 {
01054 
01055         AR5K_TRACE;
01056 
01057 
01058         u_int32_t total, offset;
01059         u_int16_t data;
01060         int octet;
01061         u_int8_t mac_d[IEEE80211_ADDR_LEN];
01062         
01063         bzero(mac, IEEE80211_ADDR_LEN);
01064         bzero(&mac_d, IEEE80211_ADDR_LEN);
01065 
01066         if (hal->ah_eeprom_read(hal, 0x20, &data) != 0)
01067                 return (EIO);
01068 
01069         for (offset = 0x1f, octet = 0, total = 0;
01070              offset >= 0x1d; offset--) {
01071                 if (hal->ah_eeprom_read(hal, offset, &data) != 0)
01072                         return (EIO);
01073 
01074                 total += data;
01075                 mac_d[octet + 1] = data & 0xff;
01076                 mac_d[octet] = data >> 8;
01077                 octet += 2;
01078         }
01079 
01080         bcopy(mac_d, mac, IEEE80211_ADDR_LEN);
01081 
01082         if ((!total) || total == (3 * 0xffff))
01083                 return (EINVAL);
01084 
01085         return (0);
01086 }
01087 
01088 HAL_BOOL
01089 ar5k_eeprom_regulation_domain(hal, write, regdomain)
01090         struct ath_hal *hal;
01091         HAL_BOOL write;
01092         ieee80211_regdomain_t *regdomain;
01093 {
01094 
01095         AR5K_TRACE;
01096 
01097 
01098         /* Read current value */
01099         if (write != AH_TRUE) {
01100                 *regdomain = hal->ah_capabilities.reg_current;
01101                 return (AH_TRUE);
01102         }
01103 
01104         /* Try to write a new value */
01105         hal->ah_capabilities.reg_current = *regdomain;
01106 
01107         if (hal->ah_capabilities.cap_eeprom.ee_protect &
01108             AR5K_EEPROM_PROTECT_WR_128_191)
01109                 return (AH_FALSE);
01110 
01111         if (hal->ah_eeprom_write(hal, AR5K_EEPROM_REG_DOMAIN,
01112             hal->ah_capabilities.cap_eeprom.ee_regdomain) != 0)
01113                 return (AH_FALSE);
01114 
01115         hal->ah_capabilities.cap_eeprom.ee_regdomain =
01116             ar5k_regdomain_from_ieee(*regdomain);
01117 
01118         return (AH_TRUE);
01119 }
01120 
01121 /*
01122  * PHY/RF access functions
01123  */
01124 
01125 HAL_BOOL
01126 ar5k_channel(hal, channel)
01127         struct ath_hal *hal;
01128         HAL_CHANNEL *channel;
01129 {
01130         HAL_BOOL ret;
01131 
01132         /*
01133          * Check bounds supported by the PHY
01134          * (don't care about regulation restrictions at this point)
01135          */
01136         if ((channel->channel < hal->ah_capabilities.cap_range.range_2ghz_min ||
01137             channel->channel > hal->ah_capabilities.cap_range.range_2ghz_max) &&
01138             (channel->channel < hal->ah_capabilities.cap_range.range_5ghz_min ||
01139             channel->channel > hal->ah_capabilities.cap_range.range_5ghz_max)) {
01140                 AR5K_PRINTF("channel out of supported range (%u MHz)\n",
01141                     channel->channel);
01142                 return (AH_FALSE);
01143         }
01144 
01145         /*
01146          * Set the channel and wait
01147          */
01148         if (hal->ah_radio == AR5K_AR5110)
01149                 ret = ar5k_ar5110_channel(hal, channel);
01150         else if (hal->ah_radio == AR5K_AR5111)
01151                 ret = ar5k_ar5111_channel(hal, channel);
01152         else
01153                 ret = ar5k_ar5112_channel(hal, channel);
01154 
01155         if (ret == AH_FALSE)
01156                 return (ret);
01157 
01158         hal->ah_current_channel.channel = channel->channel;
01159         hal->ah_current_channel.channelFlags = channel->channelFlags;
01160         hal->ah_turbo = channel->channelFlags == CHANNEL_T ?
01161             AH_TRUE : AH_FALSE;
01162 
01163         return (AH_TRUE);
01164 }
01165 
01166 u_int32_t
01167 ar5k_ar5110_chan2athchan(channel)
01168         HAL_CHANNEL *channel;
01169 {
01170         u_int32_t athchan;
01171 
01172         /*
01173          * Convert IEEE channel/MHz to an internal channel value used
01174          * by the AR5210 chipset. This has not been verified with
01175          * newer chipsets like the AR5212A who have a completely
01176          * different RF/PHY part.
01177          */
01178         athchan = (ar5k_bitswap((ath_hal_mhz2ieee(channel->channel,
01179             channel->channelFlags) - 24) / 2, 5) << 1) |
01180             (1 << 6) | 0x1;
01181 
01182         return (athchan);
01183 }
01184 
01185 HAL_BOOL
01186 ar5k_ar5110_channel(hal, channel)
01187         struct ath_hal *hal;
01188         HAL_CHANNEL *channel;
01189 {
01190         u_int32_t data;
01191 
01192         /*
01193          * Set the channel and wait
01194          */
01195         data = ar5k_ar5110_chan2athchan(channel);
01196         AR5K_PHY_WRITE(0x27, data);
01197         AR5K_PHY_WRITE(0x30, 0);
01198         AR5K_DELAY(1000);
01199 
01200         return (AH_TRUE);
01201 }
01202 
01203 HAL_BOOL
01204 ar5k_ar5111_chan2athchan(ieee, athchan)
01205         u_int ieee;
01206         struct ar5k_athchan_2ghz *athchan;
01207 {
01208         int channel;
01209 
01210         /* Cast this value to catch negative channel numbers (>= -19) */ 
01211         channel = (int)ieee;
01212 
01213         /*
01214          * Map 2GHz IEEE channel to 5GHz Atheros channel
01215          */
01216         if (channel <= 13) {
01217                 athchan->a2_athchan = 115 + channel;
01218                 athchan->a2_flags = 0x46;
01219         } else if (channel == 14) {
01220                 athchan->a2_athchan = 124;
01221                 athchan->a2_flags = 0x44;
01222         } else if (channel >= 15 && channel <= 26) {
01223                 athchan->a2_athchan = ((channel - 14) * 4) + 132;
01224                 athchan->a2_flags = 0x46;
01225         } else
01226                 return (AH_FALSE);
01227 
01228         return (AH_TRUE);
01229 }
01230 
01231 HAL_BOOL
01232 ar5k_ar5111_channel(hal, channel)
01233         struct ath_hal *hal;
01234         HAL_CHANNEL *channel;
01235 {
01236         u_int ieee_channel, ath_channel;
01237         u_int32_t data0, data1, clock;
01238         struct ar5k_athchan_2ghz ath_channel_2ghz;
01239 
01240         /*
01241          * Set the channel on the AR5111 radio
01242          */
01243         data0 = data1 = 0;
01244         ath_channel = ieee_channel = ath_hal_mhz2ieee(channel->channel,
01245             channel->channelFlags);
01246 
01247         if (channel->channelFlags & IEEE80211_CHAN_2GHZ) {
01248                 /* Map 2GHz channel to 5GHz Atheros channel ID */
01249                 if (ar5k_ar5111_chan2athchan(ieee_channel,
01250                         &ath_channel_2ghz) == AH_FALSE)
01251                         return (AH_FALSE);
01252 
01253                 ath_channel = ath_channel_2ghz.a2_athchan;
01254                 data0 = ((ar5k_bitswap(ath_channel_2ghz.a2_flags, 8) & 0xff)
01255                     << 5) | (1 << 4);
01256         }
01257 
01258         if (ath_channel < 145 || !(ath_channel & 1)) {
01259                 clock = 1;
01260                 data1 = ((ar5k_bitswap(ath_channel - 24, 8) & 0xff) << 2)
01261                     | (clock << 1) | (1 << 10) | 1;
01262         } else {
01263                 clock = 0;
01264                 data1 = ((ar5k_bitswap((ath_channel - 24) / 2, 8) & 0xff) << 2)
01265                     | (clock << 1) | (1 << 10) | 1;
01266         }
01267 
01268         AR5K_PHY_WRITE(0x27, (data1 & 0xff) | ((data0 & 0xff) << 8));
01269         AR5K_PHY_WRITE(0x34, ((data1 >> 8) & 0xff) | (data0 & 0xff00));
01270 
01271         return (AH_TRUE);
01272 }
01273 
01274 HAL_BOOL
01275 ar5k_ar5112_channel(hal, channel)
01276         struct ath_hal *hal;
01277         HAL_CHANNEL *channel;
01278 {
01279         u_int32_t data, data0, data1, data2;
01280         u_int16_t c;
01281 
01282         data = data0 = data1 = data2 = 0;
01283         c = channel->channel;
01284 
01285         /*
01286          * Set the channel on the AR5112 or newer
01287          */
01288         if (c < 4800) {
01289                 if (!((c - 2224) % 5)) {
01290                         data0 = ((2 * (c - 704)) - 3040) / 10;
01291                         data1 = 1;
01292                 } else if (!((c - 2192) % 5)) {
01293                         data0 = ((2 * (c - 672)) - 3040) / 10;
01294                         data1 = 0;
01295                 } else
01296                         return (AH_FALSE);
01297 
01298                 data0 = ar5k_bitswap((data0 << 2) & 0xff, 8);
01299         } else {
01300                 if (!(c % 20) && c >= 5120) {
01301                         data0 = ar5k_bitswap(((c - 4800) / 20 << 2), 8);
01302                         data2 = ar5k_bitswap(3, 2);
01303                 } else if (!(c % 10)) {
01304                         data0 = ar5k_bitswap(((c - 4800) / 10 << 1), 8);
01305                         data2 = ar5k_bitswap(2, 2);
01306                 } else if (!(c % 5)) {
01307                         data0 = ar5k_bitswap((c - 4800) / 5, 8);
01308                         data2 = ar5k_bitswap(1, 2);
01309                 } else
01310                         return (AH_FALSE);
01311         }
01312 
01313         data = (data0 << 4) | (data1 << 1) | (data2 << 2) | 0x1001;
01314 
01315         AR5K_PHY_WRITE(0x27, data & 0xff);
01316         AR5K_PHY_WRITE(0x36, (data >> 8) & 0x7f);
01317 
01318         return (AH_TRUE);
01319 }
01320 
01321 u_int
01322 ar5k_rfregs_op(rf, offset, reg, bits, first, col, set)
01323         u_int32_t *rf;
01324         u_int32_t offset, reg, bits, first, col;
01325         HAL_BOOL set;
01326 {
01327         u_int32_t mask, entry, last, data = 0, shift, position;
01328         int32_t left;
01329         int i;
01330 
01331         if (rf == NULL) {
01332                 /* should not happen */
01333                 return (0);
01334         }
01335 
01336         if (!(col <= 3 && bits <= 32 && first + bits <= 319)) {
01337                 AR5K_PRINTF("invalid values at offset %u\n", offset);
01338                 return (0);
01339         }
01340 
01341         entry = ((first - 1) / 8) + offset;
01342         position = (first - 1) % 8;
01343 
01344         if (set == AH_TRUE)
01345                 data = ar5k_bitswap(reg, bits);
01346 
01347         for (i = shift = 0, left = bits; left > 0; position = 0, entry++, i++) {
01348                 last = (position + left > 8) ? 8 : position + left;
01349                 mask = (((1 << last) - 1) ^ ((1 << position) - 1)) <<
01350                     (col * 8);
01351 
01352                 if (set == AH_TRUE) {
01353                         rf[entry] &= ~mask;
01354                         rf[entry] |= ((data << position) << (col * 8)) & mask;
01355                         data >>= (8 - position);
01356                 } else {
01357                         data = (((rf[entry] & mask) >> (col * 8)) >>
01358                             position) << shift;
01359                         shift += last - position;
01360                 }
01361 
01362                 left -= 8 - position;
01363         }
01364 
01365         data = set == AH_TRUE ? 1 : ar5k_bitswap(data, bits);
01366 
01367         return (data);
01368 }
01369 
01370 u_int32_t
01371 ar5k_rfregs_gainf_corr(hal)
01372         struct ath_hal *hal;
01373 {
01374         u_int32_t mix, step;
01375         u_int32_t *rf;
01376 
01377         if (hal->ah_rf_banks == NULL)
01378                 return (0);
01379 
01380         rf = hal->ah_rf_banks;
01381         hal->ah_gain.g_f_corr = 0;
01382 
01383         if (ar5k_rfregs_op(rf, hal->ah_offset[7], 0, 1, 36, 0, AH_FALSE) != 1)
01384                 return (0);
01385 
01386         step = ar5k_rfregs_op(rf, hal->ah_offset[7], 0, 4, 32, 0, AH_FALSE);
01387         mix = hal->ah_gain.g_step->gos_param[0];
01388 
01389         switch (mix) {
01390         case 3:
01391                 hal->ah_gain.g_f_corr = step * 2;
01392                 break;
01393         case 2:
01394                 hal->ah_gain.g_f_corr = (step - 5) * 2;
01395                 break;
01396         case 1:
01397                 hal->ah_gain.g_f_corr = step;
01398                 break;
01399         default:
01400                 hal->ah_gain.g_f_corr = 0;
01401                 break;
01402         }
01403 
01404         return (hal->ah_gain.g_f_corr);
01405 }
01406 
01407 HAL_BOOL
01408 ar5k_rfregs_gain_readback(hal)
01409         struct ath_hal *hal;
01410 {
01411         u_int32_t step, mix, level[4];
01412         u_int32_t *rf;
01413 
01414         if (hal->ah_rf_banks == NULL)
01415                 return (0);
01416 
01417         rf = hal->ah_rf_banks;
01418 
01419         if (hal->ah_radio == AR5K_AR5111) {
01420                 step = ar5k_rfregs_op(rf, hal->ah_offset[7],
01421                     0, 6, 37, 0, AH_FALSE);
01422                 level[0] = 0;
01423                 level[1] = (step == 0x3f) ? 0x32 : step + 4;
01424                 level[2] = (step != 0x3f) ? 0x40 : level[0];
01425                 level[3] = level[2] + 0x32;
01426 
01427                 hal->ah_gain.g_high = level[3] -
01428                     (step == 0x3f ? AR5K_GAIN_DYN_ADJUST_HI_MARGIN : -5);
01429                 hal->ah_gain.g_low = level[0] +
01430                     (step == 0x3f ? AR5K_GAIN_DYN_ADJUST_LO_MARGIN : 0);
01431         } else {
01432                 mix = ar5k_rfregs_op(rf, hal->ah_offset[7],
01433                     0, 1, 36, 0, AH_FALSE);
01434                 level[0] = level[2] = 0;
01435 
01436                 if (mix == 1) {
01437                         level[1] = level[3] = 83;
01438                 } else {
01439                         level[1] = level[3] = 107;
01440                         hal->ah_gain.g_high = 55;
01441                 }
01442         }
01443 
01444         return ((hal->ah_gain.g_current >= level[0] &&
01445             hal->ah_gain.g_current <= level[1]) ||
01446             (hal->ah_gain.g_current >= level[2] &&
01447             hal->ah_gain.g_current <= level[3]));
01448 }
01449 
01450 int32_t
01451 ar5k_rfregs_gain_adjust(hal)
01452         struct ath_hal *hal;
01453 {
01454         int ret = 0;
01455         const struct ar5k_gain_opt *go;
01456 
01457         go = hal->ah_radio == AR5K_AR5111 ?
01458             &ar5111_gain_opt : &ar5112_gain_opt;
01459 
01460         hal->ah_gain.g_step = &go->go_step[hal->ah_gain.g_step_idx];
01461 
01462         if (hal->ah_gain.g_current >= hal->ah_gain.g_high) {
01463                 if (hal->ah_gain.g_step_idx == 0)
01464                         return (-1);
01465                 for (hal->ah_gain.g_target = hal->ah_gain.g_current;
01466                     hal->ah_gain.g_target >=  hal->ah_gain.g_high &&
01467                     hal->ah_gain.g_step_idx > 0;
01468                     hal->ah_gain.g_step =
01469                     &go->go_step[hal->ah_gain.g_step_idx]) {
01470                         hal->ah_gain.g_target -= 2 *
01471                             (go->go_step[--(hal->ah_gain.g_step_idx)].gos_gain -
01472                             hal->ah_gain.g_step->gos_gain);
01473                 }
01474 
01475                 ret = 1;
01476                 goto done;
01477         }
01478 
01479         if (hal->ah_gain.g_current <= hal->ah_gain.g_low) {
01480                 if (hal->ah_gain.g_step_idx == (go->go_steps_count - 1))
01481                         return (-2);
01482                 for (hal->ah_gain.g_target = hal->ah_gain.g_current;
01483                     hal->ah_gain.g_target <=  hal->ah_gain.g_low &&
01484                     hal->ah_gain.g_step_idx < (go->go_steps_count - 1);
01485                     hal->ah_gain.g_step =
01486                     &go->go_step[hal->ah_gain.g_step_idx]) {
01487                         hal->ah_gain.g_target -= 2 *
01488                             (go->go_step[++(hal->ah_gain.g_step_idx)].gos_gain -
01489                             hal->ah_gain.g_step->gos_gain);
01490                 }
01491 
01492                 ret = 2;
01493                 goto done;
01494         }
01495 
01496  done:
01497 #ifdef AR5K_DEBUG
01498         AR5K_PRINTF("ret %d, gain step %u, current gain %u, target gain %u\n",
01499                     ret,
01500                     hal->ah_gain.g_step_idx,
01501                     hal->ah_gain.g_current,
01502                     hal->ah_gain.g_target);
01503 #endif
01504 
01505         return (ret);
01506 }
01507 
01508 HAL_BOOL
01509 ar5k_rfregs(hal, channel, mode)
01510         struct ath_hal *hal;
01511         HAL_CHANNEL *channel;
01512         u_int mode;
01513 {
01514         ar5k_rfgain_t *func = 0;
01515         HAL_BOOL ret;
01516 
01517         if (hal->ah_radio == AR5K_AR5111) {
01518                 hal->ah_rf_banks_size = sizeof(ar5111_rf);
01519                 func = ar5k_ar5111_rfregs;
01520         } else if (hal->ah_radio == AR5K_AR5112) {
01521                 hal->ah_rf_banks_size = sizeof(ar5112_rf);
01522                 func = ar5k_ar5112_rfregs;
01523         } else
01524                 return (AH_FALSE);
01525 
01526         if (hal->ah_rf_banks == 0) {
01527                 /* XXX do extra checks? */
01528                 if ((hal->ah_rf_banks = (u_int32_t *)kmalloc(hal->ah_rf_banks_size, GFP_KERNEL)) == 0) {
01529                         AR5K_PRINT("out of memory\n");
01530                         return (AH_FALSE);
01531                 }
01532         }
01533 
01534         ret = (func)(hal, channel, mode);
01535 
01536         if (ret == AH_TRUE)
01537                 hal->ah_rf_gain = HAL_RFGAIN_INACTIVE;
01538 
01539         return (ret);
01540 }
01541 
01542 HAL_BOOL
01543 ar5k_ar5111_rfregs(hal, channel, mode)
01544         struct ath_hal *hal;
01545         HAL_CHANNEL *channel;
01546         u_int mode;
01547 {
01548         struct ar5k_eeprom_info *ee = &hal->ah_capabilities.cap_eeprom;
01549         const u_int rf_size = AR5K_ELEMENTS(ar5111_rf);
01550         u_int32_t *rf;
01551         int i, obdb = -1, bank = -1;
01552         u_int32_t ee_mode;
01553 
01554         AR5K_ASSERT_ENTRY(mode, AR5K_INI_VAL_MAX);
01555 
01556         rf = hal->ah_rf_banks;
01557 
01558         /* Copy values to modify them */
01559         for (i = 0; i < rf_size; i++) {
01560                 if (ar5111_rf[i].rf_bank >=
01561                     AR5K_AR5111_INI_RF_MAX_BANKS) {
01562                         AR5K_PRINT("invalid bank\n");
01563                         return (AH_FALSE);
01564                 }
01565 
01566                 if (bank != ar5111_rf[i].rf_bank) {
01567                         bank = ar5111_rf[i].rf_bank;
01568                         hal->ah_offset[bank] = i;
01569                 }
01570 
01571                 rf[i] = ar5111_rf[i].rf_value[mode];
01572         }
01573 
01574         if (channel->channelFlags & IEEE80211_CHAN_2GHZ) {
01575                 if (channel->channelFlags & IEEE80211_CHAN_B)
01576                         ee_mode = AR5K_EEPROM_MODE_11B;
01577                 else
01578                         ee_mode = AR5K_EEPROM_MODE_11G;
01579                 obdb = 0;
01580 
01581                 if (!ar5k_rfregs_op(rf, hal->ah_offset[0],
01582                         ee->ee_ob[ee_mode][obdb], 3, 119, 0, AH_TRUE))
01583                         return (AH_FALSE);
01584 
01585                 if (!ar5k_rfregs_op(rf, hal->ah_offset[0],
01586                         ee->ee_ob[ee_mode][obdb], 3, 122, 0, AH_TRUE))
01587                         return (AH_FALSE);
01588 
01589                 obdb = 1;
01590         } else {
01591                 /* For 11a, Turbo and XR */
01592                 ee_mode = AR5K_EEPROM_MODE_11A;
01593                 obdb = channel->channel >= 5725 ? 3 :
01594                     (channel->channel >= 5500 ? 2 :
01595                         (channel->channel >= 5260 ? 1 :
01596                             (channel->channel > 4000 ? 0 : -1)));
01597 
01598                 if (!ar5k_rfregs_op(rf, hal->ah_offset[6],
01599                         ee->ee_pwd_84, 1, 51, 3, AH_TRUE))
01600                         return (AH_FALSE);
01601 
01602                 if (!ar5k_rfregs_op(rf, hal->ah_offset[6],
01603                         ee->ee_pwd_90, 1, 45, 3, AH_TRUE))
01604                         return (AH_FALSE);
01605         }
01606 
01607         if (!ar5k_rfregs_op(rf, hal->ah_offset[6],
01608                 !ee->ee_xpd[ee_mode], 1, 95, 0, AH_TRUE))
01609                 return (AH_FALSE);
01610 
01611         if (!ar5k_rfregs_op(rf, hal->ah_offset[6],
01612                 ee->ee_x_gain[ee_mode], 4, 96, 0, AH_TRUE))
01613                 return (AH_FALSE);
01614 
01615         if (!ar5k_rfregs_op(rf, hal->ah_offset[6],
01616                 obdb >= 0 ? ee->ee_ob[ee_mode][obdb] : 0, 3, 104, 0, AH_TRUE))
01617                 return (AH_FALSE);
01618 
01619         if (!ar5k_rfregs_op(rf, hal->ah_offset[6],
01620                 obdb >= 0 ? ee->ee_db[ee_mode][obdb] : 0, 3, 107, 0, AH_TRUE))
01621                 return (AH_FALSE);
01622         
01623         if (!ar5k_rfregs_op(rf, hal->ah_offset[7],
01624                 ee->ee_i_gain[ee_mode], 6, 29, 0, AH_TRUE))
01625                 return (AH_FALSE);
01626 
01627         if (!ar5k_rfregs_op(rf, hal->ah_offset[7],
01628                 ee->ee_xpd[ee_mode], 1, 4, 0, AH_TRUE))
01629                 return (AH_FALSE);
01630 
01631         /* Write RF values */
01632         for (i = 0; i < rf_size; i++) {
01633                 AR5K_REG_WAIT(i);
01634                 AR5K_REG_WRITE(ar5111_rf[i].rf_register, rf[i]);
01635         }
01636 
01637         return (AH_TRUE);
01638 }
01639 
01640 HAL_BOOL
01641 ar5k_ar5112_rfregs(hal, channel, mode)
01642         struct ath_hal *hal;
01643         HAL_CHANNEL *channel;
01644         u_int mode;
01645 {
01646         struct ar5k_eeprom_info *ee = &hal->ah_capabilities.cap_eeprom;
01647         const u_int rf_size = AR5K_ELEMENTS(ar5112_rf);
01648         u_int32_t *rf;
01649         int i, obdb = -1, bank = -1;
01650         u_int32_t ee_mode;
01651 
01652         AR5K_ASSERT_ENTRY(mode, AR5K_INI_VAL_MAX);
01653 
01654         rf = hal->ah_rf_banks;
01655 
01656         /* Copy values to modify them */
01657         for (i = 0; i < rf_size; i++) {
01658                 if (ar5112_rf[i].rf_bank >=
01659                     AR5K_AR5112_INI_RF_MAX_BANKS) {
01660                         AR5K_PRINT("invalid bank\n");
01661                         return (AH_FALSE);
01662                 }
01663 
01664                 if (bank != ar5112_rf[i].rf_bank) {
01665                         bank = ar5112_rf[i].rf_bank;
01666                         hal->ah_offset[bank] = i;
01667                 }
01668 
01669                 rf[i] = ar5112_rf[i].rf_value[mode];
01670         }
01671 
01672         if (channel->channelFlags & IEEE80211_CHAN_2GHZ) {
01673                 if (channel->channelFlags & IEEE80211_CHAN_B)
01674                         ee_mode = AR5K_EEPROM_MODE_11B;
01675                 else
01676                         ee_mode = AR5K_EEPROM_MODE_11G;
01677                 obdb = 0;
01678 
01679                 if (!ar5k_rfregs_op(rf, hal->ah_offset[6],
01680                         ee->ee_ob[ee_mode][obdb], 3, 287, 0, AH_TRUE))
01681                         return (AH_FALSE);
01682 
01683                 if (!ar5k_rfregs_op(rf, hal->ah_offset[6],
01684                         ee->ee_ob[ee_mode][obdb], 3, 290, 0, AH_TRUE))
01685                         return (AH_FALSE);
01686         } else {
01687                 /* For 11a, Turbo and XR */
01688                 ee_mode = AR5K_EEPROM_MODE_11A;
01689                 obdb = channel->channel >= 5725 ? 3 :
01690                     (channel->channel >= 5500 ? 2 :
01691                         (channel->channel >= 5260 ? 1 :
01692                             (channel->channel > 4000 ? 0 : -1)));
01693 
01694                 if (!ar5k_rfregs_op(rf, hal->ah_offset[6],
01695                         ee->ee_ob[ee_mode][obdb], 3, 279, 0, AH_TRUE))
01696                         return (AH_FALSE);
01697 
01698                 if (!ar5k_rfregs_op(rf, hal->ah_offset[6],
01699                         ee->ee_ob[ee_mode][obdb], 3, 282, 0, AH_TRUE))
01700                         return (AH_FALSE);
01701         }
01702 
01703 #ifdef notyet
01704         ar5k_rfregs_op(rf, hal->ah_offset[6],
01705             ee->ee_x_gain[ee_mode], 2, 270, 0, AH_TRUE);
01706         ar5k_rfregs_op(rf, hal->ah_offset[6],
01707             ee->ee_x_gain[ee_mode], 2, 257, 0, AH_TRUE);
01708 #endif
01709 
01710         if (!ar5k_rfregs_op(rf, hal->ah_offset[6],
01711                 ee->ee_xpd[ee_mode], 1, 302, 0, AH_TRUE))
01712                 return (AH_FALSE);
01713 
01714         if (!ar5k_rfregs_op(rf, hal->ah_offset[7],
01715                 ee->ee_i_gain[ee_mode], 6, 14, 0, AH_TRUE))
01716                 return (AH_FALSE);
01717 
01718         /* Write RF values */
01719         for (i = 0; i < rf_size; i++)
01720                 AR5K_REG_WRITE(ar5112_rf[i].rf_register, rf[i]);
01721 
01722         return (AH_TRUE);
01723 }
01724 
01725 HAL_BOOL
01726 ar5k_rfgain(hal, phy, freq)
01727         struct ath_hal *hal;
01728         u_int phy, freq;
01729 {
01730         int i;
01731 
01732         switch (phy) {
01733         case AR5K_INI_PHY_5111:
01734         case AR5K_INI_PHY_5112:
01735                 break;
01736         default:
01737                 return (AH_FALSE);
01738         }
01739 
01740         switch (freq) {
01741         case AR5K_INI_RFGAIN_2GHZ:
01742         case AR5K_INI_RFGAIN_5GHZ:
01743                 break;
01744         default:
01745                 return (AH_FALSE);
01746         }
01747 
01748         for (i = 0; i < AR5K_ELEMENTS(ar5k_rfg); i++) {
01749                 AR5K_REG_WAIT(i);
01750                 AR5K_REG_WRITE((u_int32_t)ar5k_rfg[i].rfg_register,
01751                     ar5k_rfg[i].rfg_value[phy][freq]);
01752         }
01753 
01754         return (AH_TRUE);
01755 }
01756 
01757 /*
01758  * Common TX power setup
01759  */
01760 void
01761 ar5k_txpower_table(hal, channel, max_power)
01762         struct ath_hal *hal;
01763         HAL_CHANNEL *channel;
01764         int16_t max_power;
01765 {
01766         u_int16_t txpower, *rates;
01767         int i;
01768 
01769         rates = hal->ah_txpower.txp_rates;
01770 
01771         txpower = AR5K_TUNE_DEFAULT_TXPOWER * 2;
01772         if (max_power > txpower) {
01773                 txpower = max_power > AR5K_TUNE_MAX_TXPOWER ?
01774                     AR5K_TUNE_MAX_TXPOWER : max_power;
01775         }
01776 
01777         for (i = 0; i < AR5K_MAX_RATES; i++)
01778                 rates[i] = txpower;
01779 
01780         /* XXX setup target powers by rate */
01781 
01782         hal->ah_txpower.txp_min = rates[7];
01783         hal->ah_txpower.txp_max = rates[0];
01784         hal->ah_txpower.txp_ofdm = rates[0];
01785 
01786         for (i = 0; i < AR5K_ELEMENTS(hal->ah_txpower.txp_pcdac); i++) {
01787                 int min = 4;
01788                 int max = 127;
01789                 int val = min + ((i * (max - min)) / (AR5K_ELEMENTS(hal->ah_txpower.txp_pcdac)));
01790                 hal->ah_txpower.txp_pcdac[i] = val;
01791         }
01792 }

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