00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
00047 #define PCI_VENDOR_3COM2 0xa727
00048 #define PCI_PRODUCT_3COM_3CRDAG675 0x0013
00049 #define PCI_PRODUCT_3COM2_3CRPAG175 0x0013
00050 #define PCI_PRODUCT_ATHEROS_AR5210 0x0007
00051 #define PCI_PRODUCT_ATHEROS_AR5311 0x0011
00052 #define PCI_PRODUCT_ATHEROS_AR5211 0x0012
00053 #define PCI_PRODUCT_ATHEROS_AR5212 0x0013
00054 #define PCI_PRODUCT_ATHEROS_AR5210_AP 0x0207
00055 #define PCI_PRODUCT_ATHEROS_AR5212_IBM 0x1014
00056 #define PCI_PRODUCT_ATHEROS_AR5210_DEFAULT 0x1107
00057 #define PCI_PRODUCT_ATHEROS_AR5212_DEFAULT 0x1113
00058 #define PCI_PRODUCT_ATHEROS_AR5211_DEFAULT 0x1112
00059 #define PCI_PRODUCT_ATHEROS_AR5212_FPGA 0xf013
00060 #define PCI_PRODUCT_ATHEROS_AR5211_FPGA11B 0xf11b
00061 #define PCI_PRODUCT_ATHEROS_AR5211_LEGACY 0xff12
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
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
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
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
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
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
00135
00136 #if 0
00137 #define COUNTRYCODE "00"
00138 #endif
00139
00140
00141
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
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
00172
00173 return ah;
00174 }
00175
00176 void
00177 ath_hal_detach(struct ath_hal *ah)
00178 {
00179 (*ah->ah_detach)(ah);
00180
00181 }
00182
00183
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
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;
00230
00231
00232
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
00255
00256
00257 if (ar5k_eeprom_init(hal) != 0) {
00258 AR5K_PRINT("unable to init EEPROM\n");
00259 goto failed;
00260 }
00261
00262
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
00272 ar5k_eeprom_regulation_domain(hal, AH_TRUE, &ieee_regdomain);
00273 }
00274
00275 hal->ah_capabilities.reg_hw = ieee_regdomain;
00276
00277
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
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
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
00303
00304
00305
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
00346
00347 rate = &rates->info[rate_index];
00348
00349
00350
00351
00352 switch (rate->phy) {
00353 case IEEE80211_T_CCK:
00354
00355
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
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
00373
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
00381
00382
00383
00384
00385
00386
00387
00388
00389
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) {
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) {
00412 return (mhz - 5000) / 5;
00413 } else {
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) {
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) {
00436 return 5000 + (ieee*5);
00437 } else {
00438 if (ieee == 14)
00439 return 2484;
00440 if (ieee < 14)
00441 return 2407 + ieee*5;
00442 if (ieee < 27)
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
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
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
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
00544
00545
00546
00547
00548
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
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
00593
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
00608
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
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
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
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
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
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
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
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
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
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
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
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
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
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
01099 if (write != AH_TRUE) {
01100 *regdomain = hal->ah_capabilities.reg_current;
01101 return (AH_TRUE);
01102 }
01103
01104
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
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
01134
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
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
01174
01175
01176
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
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
01211 channel = (int)ieee;
01212
01213
01214
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }