1 /* 2 * Copyright (c) 2013 Qualcomm Atheros, Inc. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 * PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 #include "opt_ah.h" 18 19 #include "ah.h" 20 #include "ah_internal.h" 21 #include "ah_devid.h" 22 #ifdef AH_DEBUG 23 #include "ah_desc.h" /* NB: for HAL_PHYERR* */ 24 #endif 25 #include "ar9300/ar9300.h" 26 #include "ar9300/ar9300eep.h" 27 #include "ar9300/ar9300template_generic.h" 28 #include "ar9300/ar9300template_xb112.h" 29 #include "ar9300/ar9300template_hb116.h" 30 #include "ar9300/ar9300template_xb113.h" 31 #include "ar9300/ar9300template_hb112.h" 32 #include "ar9300/ar9300template_ap121.h" 33 #include "ar9300/ar9300template_osprey_k31.h" 34 #include "ar9300/ar9300template_wasp_2.h" 35 #include "ar9300/ar9300template_wasp_k31.h" 36 #include "ar9300/ar9300template_aphrodite.h" 37 #include "ar9300/ar9300reg.h" 38 #include "ar9300/ar9300phy.h" 39 40 41 42 #if AH_BYTE_ORDER == AH_BIG_ENDIAN 43 void ar9300_swap_eeprom(ar9300_eeprom_t *eep); 44 void ar9300_eeprom_template_swap(void); 45 #endif 46 47 static u_int16_t ar9300_eeprom_get_spur_chan(struct ath_hal *ah, 48 int spur_chan, HAL_BOOL is_2ghz); 49 #ifdef UNUSED 50 static inline HAL_BOOL ar9300_fill_eeprom(struct ath_hal *ah); 51 static inline HAL_STATUS ar9300_check_eeprom(struct ath_hal *ah); 52 #endif 53 54 static ar9300_eeprom_t *default9300[] = 55 { 56 &ar9300_template_generic, 57 &ar9300_template_xb112, 58 &ar9300_template_hb116, 59 &ar9300_template_hb112, 60 &ar9300_template_xb113, 61 &ar9300_template_ap121, 62 &ar9300_template_wasp_2, 63 &ar9300_template_wasp_k31, 64 &ar9300_template_osprey_k31, 65 &ar9300_template_aphrodite, 66 }; 67 68 /* 69 * Different types of memory where the calibration data might be stored. 70 * All types are searched in ar9300_eeprom_restore() 71 * in the order flash, eeprom, otp. 72 * To disable searching a type, set its parameter to 0. 73 */ 74 75 /* 76 * This is where we look for the calibration data. 77 * must be set before ath_attach() is called 78 */ 79 static int calibration_data_try = calibration_data_none; 80 static int calibration_data_try_address = 0; 81 82 /* 83 * Set the type of memory used to store calibration data. 84 * Used by nart to force reading/writing of a specific type. 85 * The driver can normally allow autodetection 86 * by setting source to calibration_data_none=0. 87 */ 88 void ar9300_calibration_data_set(struct ath_hal *ah, int32_t source) 89 { 90 if (ah != 0) { 91 AH9300(ah)->calibration_data_source = source; 92 } else { 93 calibration_data_try = source; 94 } 95 } 96 97 int32_t ar9300_calibration_data_get(struct ath_hal *ah) 98 { 99 if (ah != 0) { 100 return AH9300(ah)->calibration_data_source; 101 } else { 102 return calibration_data_try; 103 } 104 } 105 106 /* 107 * Set the address of first byte used to store calibration data. 108 * Used by nart to force reading/writing at a specific address. 109 * The driver can normally allow autodetection by setting size=0. 110 */ 111 void ar9300_calibration_data_address_set(struct ath_hal *ah, int32_t size) 112 { 113 if (ah != 0) { 114 AH9300(ah)->calibration_data_source_address = size; 115 } else { 116 calibration_data_try_address = size; 117 } 118 } 119 120 int32_t ar9300_calibration_data_address_get(struct ath_hal *ah) 121 { 122 if (ah != 0) { 123 return AH9300(ah)->calibration_data_source_address; 124 } else { 125 return calibration_data_try_address; 126 } 127 } 128 129 /* 130 * This is the template that is loaded if ar9300_eeprom_restore() 131 * can't find valid data in the memory. 132 */ 133 static int Ar9300_eeprom_template_preference = ar9300_eeprom_template_generic; 134 135 void ar9300_eeprom_template_preference(int32_t value) 136 { 137 Ar9300_eeprom_template_preference = value; 138 } 139 140 /* 141 * Install the specified default template. 142 * Overwrites any existing calibration and configuration information in memory. 143 */ 144 int32_t ar9300_eeprom_template_install(struct ath_hal *ah, int32_t value) 145 { 146 struct ath_hal_9300 *ahp = AH9300(ah); 147 ar9300_eeprom_t *mptr, *dptr; 148 int mdata_size; 149 150 mptr = &ahp->ah_eeprom; 151 mdata_size = ar9300_eeprom_struct_size(); 152 if (mptr != 0) { 153 #if 0 154 calibration_data_source = calibration_data_none; 155 calibration_data_source_address = 0; 156 #endif 157 dptr = ar9300_eeprom_struct_default_find_by_id(value); 158 if (dptr != 0) { 159 OS_MEMCPY(mptr, dptr, mdata_size); 160 return 0; 161 } 162 } 163 return -1; 164 } 165 166 static int 167 ar9300_eeprom_restore_something(struct ath_hal *ah, ar9300_eeprom_t *mptr, 168 int mdata_size) 169 { 170 int it; 171 ar9300_eeprom_t *dptr; 172 int nptr; 173 174 nptr = -1; 175 /* 176 * if we didn't find any blocks in the memory, 177 * put the prefered template in place 178 */ 179 if (nptr < 0) { 180 AH9300(ah)->calibration_data_source = calibration_data_none; 181 AH9300(ah)->calibration_data_source_address = 0; 182 dptr = ar9300_eeprom_struct_default_find_by_id( 183 Ar9300_eeprom_template_preference); 184 if (dptr != 0) { 185 OS_MEMCPY(mptr, dptr, mdata_size); 186 nptr = 0; 187 } 188 } 189 /* 190 * if we didn't find the prefered one, 191 * put the normal default template in place 192 */ 193 if (nptr < 0) { 194 AH9300(ah)->calibration_data_source = calibration_data_none; 195 AH9300(ah)->calibration_data_source_address = 0; 196 dptr = ar9300_eeprom_struct_default_find_by_id( 197 ar9300_eeprom_template_default); 198 if (dptr != 0) { 199 OS_MEMCPY(mptr, dptr, mdata_size); 200 nptr = 0; 201 } 202 } 203 /* 204 * if we can't find the best template, put any old template in place 205 * presume that newer ones are better, so search backwards 206 */ 207 if (nptr < 0) { 208 AH9300(ah)->calibration_data_source = calibration_data_none; 209 AH9300(ah)->calibration_data_source_address = 0; 210 for (it = ar9300_eeprom_struct_default_many() - 1; it >= 0; it--) { 211 dptr = ar9300_eeprom_struct_default(it); 212 if (dptr != 0) { 213 OS_MEMCPY(mptr, dptr, mdata_size); 214 nptr = 0; 215 break; 216 } 217 } 218 } 219 return nptr; 220 } 221 222 /* 223 * Read 16 bits of data from offset into *data 224 */ 225 HAL_BOOL 226 ar9300_eeprom_read_word(struct ath_hal *ah, u_int off, u_int16_t *data) 227 { 228 if (AR_SREV_OSPREY(ah) || AR_SREV_POSEIDON(ah)) 229 { 230 (void) OS_REG_READ(ah, AR9300_EEPROM_OFFSET + (off << AR9300_EEPROM_S)); 231 if (!ath_hal_wait(ah, 232 AR_HOSTIF_REG(ah, AR_EEPROM_STATUS_DATA), 233 AR_EEPROM_STATUS_DATA_BUSY | AR_EEPROM_STATUS_DATA_PROT_ACCESS, 234 0)) 235 { 236 return AH_FALSE; 237 } 238 *data = MS(OS_REG_READ(ah, 239 AR_HOSTIF_REG(ah, AR_EEPROM_STATUS_DATA)), AR_EEPROM_STATUS_DATA_VAL); 240 return AH_TRUE; 241 } 242 else 243 { 244 *data = 0; 245 return AH_FALSE; 246 } 247 } 248 249 250 HAL_BOOL 251 ar9300_otp_read(struct ath_hal *ah, u_int off, u_int32_t *data, HAL_BOOL is_wifi) 252 { 253 int time_out = 1000; 254 int status = 0; 255 u_int32_t addr; 256 257 if (AR_SREV_HONEYBEE(ah)){ /* no OTP for Honeybee */ 258 return false; 259 } 260 addr = (AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah))? 261 OTP_MEM_START_ADDRESS_WASP : OTP_MEM_START_ADDRESS; 262 if (!is_wifi) { 263 addr = BTOTP_MEM_START_ADDRESS; 264 } 265 addr += off * 4; /* OTP is 32 bit addressable */ 266 (void) OS_REG_READ(ah, addr); 267 268 addr = (AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) ? 269 OTP_STATUS0_OTP_SM_BUSY_WASP : OTP_STATUS0_OTP_SM_BUSY; 270 if (!is_wifi) { 271 addr = BTOTP_STATUS0_OTP_SM_BUSY; 272 } 273 while ((time_out > 0) && (!status)) { /* wait for access complete */ 274 /* Read data valid, access not busy, sm not busy */ 275 status = ((OS_REG_READ(ah, addr) & 0x7) == 0x4) ? 1 : 0; 276 time_out--; 277 } 278 if (time_out == 0) { 279 HALDEBUG(ah, HAL_DEBUG_EEPROM, 280 "%s: Timed out during OTP Status0 validation\n", __func__); 281 return AH_FALSE; 282 } 283 284 addr = (AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) ? 285 OTP_STATUS1_EFUSE_READ_DATA_WASP : OTP_STATUS1_EFUSE_READ_DATA; 286 if (!is_wifi) { 287 addr = BTOTP_STATUS1_EFUSE_READ_DATA; 288 } 289 *data = OS_REG_READ(ah, addr); 290 return AH_TRUE; 291 } 292 293 294 295 296 static HAL_STATUS 297 ar9300_flash_map(struct ath_hal *ah) 298 { 299 /* XXX disable flash remapping for now (ie, SoC support) */ 300 ath_hal_printf(ah, "%s: unimplemented for now\n", __func__); 301 #if 0 302 struct ath_hal_9300 *ahp = AH9300(ah); 303 #if defined(AR9100) || defined(__NetBSD__) 304 ahp->ah_cal_mem = OS_REMAP(ah, AR9300_EEPROM_START_ADDR, AR9300_EEPROM_MAX); 305 #else 306 ahp->ah_cal_mem = OS_REMAP((uintptr_t)(AH_PRIVATE(ah)->ah_st), 307 (AR9300_EEPROM_MAX + AR9300_FLASH_CAL_START_OFFSET)); 308 #endif 309 if (!ahp->ah_cal_mem) { 310 HALDEBUG(ah, HAL_DEBUG_EEPROM, 311 "%s: cannot remap eeprom region \n", __func__); 312 return HAL_EIO; 313 } 314 #endif 315 return HAL_OK; 316 } 317 318 HAL_BOOL 319 ar9300_flash_read(struct ath_hal *ah, u_int off, u_int16_t *data) 320 { 321 struct ath_hal_9300 *ahp = AH9300(ah); 322 323 *data = ((u_int16_t *)ahp->ah_cal_mem)[off]; 324 return AH_TRUE; 325 } 326 327 HAL_BOOL 328 ar9300_flash_write(struct ath_hal *ah, u_int off, u_int16_t data) 329 { 330 struct ath_hal_9300 *ahp = AH9300(ah); 331 332 ((u_int16_t *)ahp->ah_cal_mem)[off] = data; 333 return AH_TRUE; 334 } 335 336 HAL_STATUS 337 ar9300_eeprom_attach(struct ath_hal *ah) 338 { 339 struct ath_hal_9300 *ahp = AH9300(ah); 340 ahp->try_dram = 1; 341 ahp->try_eeprom = 1; 342 ahp->try_otp = 1; 343 #ifdef ATH_CAL_NAND_FLASH 344 ahp->try_nand = 1; 345 #else 346 ahp->try_flash = 1; 347 #endif 348 ahp->calibration_data_source = calibration_data_none; 349 ahp->calibration_data_source_address = 0; 350 ahp->calibration_data_try = calibration_data_try; 351 ahp->calibration_data_try_address = 0; 352 353 /* 354 * In case flash will be used for EEPROM. Otherwise ahp->ah_cal_mem 355 * must be set to NULL or the real EEPROM address. 356 */ 357 ar9300_flash_map(ah); 358 /* 359 * ###### This function always return NO SPUR. 360 * This is not true for many board designs. 361 * Does anyone use this? 362 */ 363 AH_PRIVATE(ah)->ah_getSpurChan = ar9300_eeprom_get_spur_chan; 364 365 #ifdef OLDCODE 366 /* XXX Needs to be moved for dynamic selection */ 367 ahp->ah_eeprom = *(default9300[ar9300_eeprom_template_default]); 368 369 370 if (AR_SREV_HORNET(ah)) { 371 /* Set default values for Hornet. */ 372 ahp->ah_eeprom.base_eep_header.op_cap_flags.op_flags = 373 AR9300_OPFLAGS_11G; 374 ahp->ah_eeprom.base_eep_header.txrx_mask = 0x11; 375 } else if (AR_SREV_POSEIDON(ah)) { 376 /* Set default values for Poseidon. */ 377 ahp->ah_eeprom.base_eep_header.op_cap_flags.op_flags = 378 AR9300_OPFLAGS_11G; 379 ahp->ah_eeprom.base_eep_header.txrx_mask = 0x11; 380 } 381 382 if (AH_PRIVATE(ah)->ah_config.ath_hal_skip_eeprom_read) { 383 ahp->ah_emu_eeprom = 1; 384 return HAL_OK; 385 } 386 387 ahp->ah_emu_eeprom = 1; 388 389 #ifdef UNUSED 390 #endif 391 392 if (!ar9300_fill_eeprom(ah)) { 393 return HAL_EIO; 394 } 395 396 return HAL_OK; 397 /* return ar9300_check_eeprom(ah); */ 398 #else 399 ahp->ah_emu_eeprom = 1; 400 401 #if 0 402 /*#ifdef MDK_AP*/ /* MDK_AP is defined only in NART AP build */ 403 u_int8_t buffer[10]; 404 int caldata_check = 0; 405 406 ar9300_calibration_data_read_flash( 407 ah, FLASH_BASE_CALDATA_OFFSET, buffer, 4); 408 printf("flash caldata:: %x\n", buffer[0]); 409 if (buffer[0] != 0xff) { 410 caldata_check = 1; 411 } 412 if (!caldata_check) { 413 ar9300_eeprom_t *mptr; 414 int mdata_size; 415 if (AR_SREV_HORNET(ah)) { 416 /* XXX: For initial testing */ 417 mptr = &ahp->ah_eeprom; 418 mdata_size = ar9300_eeprom_struct_size(); 419 ahp->ah_eeprom = ar9300_template_ap121; 420 ahp->ah_emu_eeprom = 1; 421 /* need it to let art save in to flash ????? */ 422 calibration_data_source = calibration_data_flash; 423 } else if (AR_SREV_WASP(ah)) { 424 /* XXX: For initial testing */ 425 ath_hal_printf(ah, " wasp eep attach\n"); 426 mptr = &ahp->ah_eeprom; 427 mdata_size = ar9300_eeprom_struct_size(); 428 ahp->ah_eeprom = ar9300_template_generic; 429 ahp->ah_eeprom.mac_addr[0] = 0x00; 430 ahp->ah_eeprom.mac_addr[1] = 0x03; 431 ahp->ah_eeprom.mac_addr[2] = 0x7F; 432 ahp->ah_eeprom.mac_addr[3] = 0xBA; 433 ahp->ah_eeprom.mac_addr[4] = 0xD0; 434 ahp->ah_eeprom.mac_addr[5] = 0x00; 435 ahp->ah_emu_eeprom = 1; 436 ahp->ah_eeprom.base_eep_header.txrx_mask = 0x33; 437 ahp->ah_eeprom.base_eep_header.txrxgain = 0x10; 438 /* need it to let art save in to flash ????? */ 439 calibration_data_source = calibration_data_flash; 440 } 441 return HAL_OK; 442 } 443 #endif 444 if (AR_SREV_HORNET(ah) || AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah) 445 || AR_SREV_HONEYBEE(ah)) { 446 ahp->try_eeprom = 0; 447 } 448 449 if (AR_SREV_HONEYBEE(ah)) { 450 ahp->try_otp = 0; 451 } 452 453 if (!ar9300_eeprom_restore(ah)) { 454 return HAL_EIO; 455 } 456 return HAL_OK; 457 #endif 458 } 459 460 u_int32_t 461 ar9300_eeprom_get(struct ath_hal_9300 *ahp, EEPROM_PARAM param) 462 { 463 ar9300_eeprom_t *eep = &ahp->ah_eeprom; 464 OSPREY_BASE_EEP_HEADER *p_base = &eep->base_eep_header; 465 OSPREY_BASE_EXTENSION_1 *base_ext1 = &eep->base_ext1; 466 467 switch (param) { 468 #ifdef NOTYET 469 case EEP_NFTHRESH_5: 470 return p_modal[0].noise_floor_thresh_ch[0]; 471 case EEP_NFTHRESH_2: 472 return p_modal[1].noise_floor_thresh_ch[0]; 473 #endif 474 case EEP_MAC_LSW: 475 return eep->mac_addr[0] << 8 | eep->mac_addr[1]; 476 case EEP_MAC_MID: 477 return eep->mac_addr[2] << 8 | eep->mac_addr[3]; 478 case EEP_MAC_MSW: 479 return eep->mac_addr[4] << 8 | eep->mac_addr[5]; 480 case EEP_REG_0: 481 return p_base->reg_dmn[0]; 482 case EEP_REG_1: 483 return p_base->reg_dmn[1]; 484 case EEP_OP_CAP: 485 return p_base->device_cap; 486 case EEP_OP_MODE: 487 return p_base->op_cap_flags.op_flags; 488 case EEP_RF_SILENT: 489 return p_base->rf_silent; 490 #ifdef NOTYET 491 case EEP_OB_5: 492 return p_modal[0].ob; 493 case EEP_DB_5: 494 return p_modal[0].db; 495 case EEP_OB_2: 496 return p_modal[1].ob; 497 case EEP_DB_2: 498 return p_modal[1].db; 499 case EEP_MINOR_REV: 500 return p_base->eeprom_version & AR9300_EEP_VER_MINOR_MASK; 501 #endif 502 case EEP_TX_MASK: 503 return (p_base->txrx_mask >> 4) & 0xf; 504 case EEP_RX_MASK: 505 return p_base->txrx_mask & 0xf; 506 #ifdef NOTYET 507 case EEP_FSTCLK_5G: 508 return p_base->fast_clk5g; 509 case EEP_RXGAIN_TYPE: 510 return p_base->rx_gain_type; 511 #endif 512 case EEP_DRIVE_STRENGTH: 513 #define AR9300_EEP_BASE_DRIVE_STRENGTH 0x1 514 return p_base->misc_configuration & AR9300_EEP_BASE_DRIVE_STRENGTH; 515 case EEP_INTERNAL_REGULATOR: 516 /* Bit 4 is internal regulator flag */ 517 return ((p_base->feature_enable & 0x10) >> 4); 518 case EEP_SWREG: 519 return (p_base->swreg); 520 case EEP_PAPRD_ENABLED: 521 /* Bit 5 is paprd flag */ 522 return ((p_base->feature_enable & 0x20) >> 5); 523 case EEP_ANTDIV_control: 524 return (u_int32_t)(base_ext1->ant_div_control); 525 case EEP_CHAIN_MASK_REDUCE: 526 return ((p_base->misc_configuration >> 3) & 0x1); 527 case EEP_OL_PWRCTRL: 528 return 0; 529 case EEP_DEV_TYPE: 530 return p_base->device_type; 531 default: 532 HALASSERT(0); 533 return 0; 534 } 535 } 536 537 538 539 /******************************************************************************/ 540 /*! 541 ** \brief EEPROM fixup code for INI values 542 ** 543 ** This routine provides a place to insert "fixup" code for specific devices 544 ** that need to modify INI values based on EEPROM values, BEFORE the INI values 545 ** are written. 546 ** Certain registers in the INI file can only be written once without 547 ** undesired side effects, and this provides a place for EEPROM overrides 548 ** in these cases. 549 ** 550 ** This is called at attach time once. It should not affect run time 551 ** performance at all 552 ** 553 ** \param ah Pointer to HAL object (this) 554 ** \param p_eep_data Pointer to (filled in) eeprom data structure 555 ** \param reg register being inspected on this call 556 ** \param value value in INI file 557 ** 558 ** \return Updated value for INI file. 559 */ 560 u_int32_t 561 ar9300_ini_fixup(struct ath_hal *ah, ar9300_eeprom_t *p_eep_data, 562 u_int32_t reg, u_int32_t value) 563 { 564 HALDEBUG(AH_NULL, HAL_DEBUG_UNMASKABLE, 565 "ar9300_eeprom_def_ini_fixup: FIXME\n"); 566 #if 0 567 BASE_EEPDEF_HEADER *p_base = &(p_eep_data->base_eep_header); 568 569 switch (AH_PRIVATE(ah)->ah_devid) 570 { 571 case AR9300_DEVID_AR9300_PCI: 572 /* 573 ** Need to set the external/internal regulator bit to the proper value. 574 ** Can only write this ONCE. 575 */ 576 577 if ( reg == 0x7894 ) 578 { 579 /* 580 ** Check for an EEPROM data structure of "0x0b" or better 581 */ 582 583 HALDEBUG(ah, HAL_DEBUG_EEPROM, "ini VAL: %x EEPROM: %x\n", 584 value, (p_base->version & 0xff)); 585 586 if ( (p_base->version & 0xff) > 0x0a) { 587 HALDEBUG(ah, HAL_DEBUG_EEPROM, 588 "PWDCLKIND: %d\n", p_base->pwdclkind); 589 value &= ~AR_AN_TOP2_PWDCLKIND; 590 value |= 591 AR_AN_TOP2_PWDCLKIND & 592 (p_base->pwdclkind << AR_AN_TOP2_PWDCLKIND_S); 593 } else { 594 HALDEBUG(ah, HAL_DEBUG_EEPROM, "PWDCLKIND Earlier Rev\n"); 595 } 596 597 HALDEBUG(ah, HAL_DEBUG_EEPROM, "final ini VAL: %x\n", value); 598 } 599 break; 600 601 } 602 603 return (value); 604 #else 605 return 0; 606 #endif 607 } 608 609 /* 610 * Returns the interpolated y value corresponding to the specified x value 611 * from the np ordered pairs of data (px,py). 612 * The pairs do not have to be in any order. 613 * If the specified x value is less than any of the px, 614 * the returned y value is equal to the py for the lowest px. 615 * If the specified x value is greater than any of the px, 616 * the returned y value is equal to the py for the highest px. 617 */ 618 static int 619 interpolate(int32_t x, int32_t *px, int32_t *py, u_int16_t np) 620 { 621 int ip = 0; 622 int lx = 0, ly = 0, lhave = 0; 623 int hx = 0, hy = 0, hhave = 0; 624 int dx = 0; 625 int y = 0; 626 int bf, factor, plus; 627 628 lhave = 0; 629 hhave = 0; 630 /* 631 * identify best lower and higher x calibration measurement 632 */ 633 for (ip = 0; ip < np; ip++) { 634 dx = x - px[ip]; 635 /* this measurement is higher than our desired x */ 636 if (dx <= 0) { 637 if (!hhave || dx > (x - hx)) { 638 /* new best higher x measurement */ 639 hx = px[ip]; 640 hy = py[ip]; 641 hhave = 1; 642 } 643 } 644 /* this measurement is lower than our desired x */ 645 if (dx >= 0) { 646 if (!lhave || dx < (x - lx)) { 647 /* new best lower x measurement */ 648 lx = px[ip]; 649 ly = py[ip]; 650 lhave = 1; 651 } 652 } 653 } 654 /* the low x is good */ 655 if (lhave) { 656 /* so is the high x */ 657 if (hhave) { 658 /* they're the same, so just pick one */ 659 if (hx == lx) { 660 y = ly; 661 } else { 662 /* interpolate with round off */ 663 bf = (2 * (hy - ly) * (x - lx)) / (hx - lx); 664 plus = (bf % 2); 665 factor = bf / 2; 666 y = ly + factor + plus; 667 } 668 } else { 669 /* only low is good, use it */ 670 y = ly; 671 } 672 } else if (hhave) { 673 /* only high is good, use it */ 674 y = hy; 675 } else { 676 /* nothing is good,this should never happen unless np=0, ???? */ 677 y = -(1 << 30); 678 } 679 680 return y; 681 } 682 683 u_int8_t 684 ar9300_eeprom_get_legacy_trgt_pwr(struct ath_hal *ah, u_int16_t rate_index, 685 u_int16_t freq, HAL_BOOL is_2ghz) 686 { 687 u_int16_t num_piers, i; 688 int32_t target_power_array[OSPREY_NUM_5G_20_TARGET_POWERS]; 689 int32_t freq_array[OSPREY_NUM_5G_20_TARGET_POWERS]; 690 u_int8_t *p_freq_bin; 691 ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom; 692 CAL_TARGET_POWER_LEG *p_eeprom_target_pwr; 693 694 if (is_2ghz) { 695 num_piers = OSPREY_NUM_2G_20_TARGET_POWERS; 696 p_eeprom_target_pwr = eep->cal_target_power_2g; 697 p_freq_bin = eep->cal_target_freqbin_2g; 698 } else { 699 num_piers = OSPREY_NUM_5G_20_TARGET_POWERS; 700 p_eeprom_target_pwr = eep->cal_target_power_5g; 701 p_freq_bin = eep->cal_target_freqbin_5g; 702 } 703 704 /* 705 * create array of channels and targetpower from 706 * targetpower piers stored on eeprom 707 */ 708 for (i = 0; i < num_piers; i++) { 709 freq_array[i] = FBIN2FREQ(p_freq_bin[i], is_2ghz); 710 target_power_array[i] = p_eeprom_target_pwr[i].t_pow2x[rate_index]; 711 } 712 713 /* interpolate to get target power for given frequency */ 714 return 715 ((u_int8_t)interpolate( 716 (int32_t)freq, freq_array, target_power_array, num_piers)); 717 } 718 719 u_int8_t 720 ar9300_eeprom_get_ht20_trgt_pwr(struct ath_hal *ah, u_int16_t rate_index, 721 u_int16_t freq, HAL_BOOL is_2ghz) 722 { 723 u_int16_t num_piers, i; 724 int32_t target_power_array[OSPREY_NUM_5G_20_TARGET_POWERS]; 725 int32_t freq_array[OSPREY_NUM_5G_20_TARGET_POWERS]; 726 u_int8_t *p_freq_bin; 727 ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom; 728 OSP_CAL_TARGET_POWER_HT *p_eeprom_target_pwr; 729 730 if (is_2ghz) { 731 num_piers = OSPREY_NUM_2G_20_TARGET_POWERS; 732 p_eeprom_target_pwr = eep->cal_target_power_2g_ht20; 733 p_freq_bin = eep->cal_target_freqbin_2g_ht20; 734 } else { 735 num_piers = OSPREY_NUM_5G_20_TARGET_POWERS; 736 p_eeprom_target_pwr = eep->cal_target_power_5g_ht20; 737 p_freq_bin = eep->cal_target_freqbin_5g_ht20; 738 } 739 740 /* 741 * create array of channels and targetpower from 742 * targetpower piers stored on eeprom 743 */ 744 for (i = 0; i < num_piers; i++) { 745 freq_array[i] = FBIN2FREQ(p_freq_bin[i], is_2ghz); 746 target_power_array[i] = p_eeprom_target_pwr[i].t_pow2x[rate_index]; 747 } 748 749 /* interpolate to get target power for given frequency */ 750 return 751 ((u_int8_t)interpolate( 752 (int32_t)freq, freq_array, target_power_array, num_piers)); 753 } 754 755 u_int8_t 756 ar9300_eeprom_get_ht40_trgt_pwr(struct ath_hal *ah, u_int16_t rate_index, 757 u_int16_t freq, HAL_BOOL is_2ghz) 758 { 759 u_int16_t num_piers, i; 760 int32_t target_power_array[OSPREY_NUM_5G_40_TARGET_POWERS]; 761 int32_t freq_array[OSPREY_NUM_5G_40_TARGET_POWERS]; 762 u_int8_t *p_freq_bin; 763 ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom; 764 OSP_CAL_TARGET_POWER_HT *p_eeprom_target_pwr; 765 766 if (is_2ghz) { 767 num_piers = OSPREY_NUM_2G_40_TARGET_POWERS; 768 p_eeprom_target_pwr = eep->cal_target_power_2g_ht40; 769 p_freq_bin = eep->cal_target_freqbin_2g_ht40; 770 } else { 771 num_piers = OSPREY_NUM_5G_40_TARGET_POWERS; 772 p_eeprom_target_pwr = eep->cal_target_power_5g_ht40; 773 p_freq_bin = eep->cal_target_freqbin_5g_ht40; 774 } 775 776 /* 777 * create array of channels and targetpower from 778 * targetpower piers stored on eeprom 779 */ 780 for (i = 0; i < num_piers; i++) { 781 freq_array[i] = FBIN2FREQ(p_freq_bin[i], is_2ghz); 782 target_power_array[i] = p_eeprom_target_pwr[i].t_pow2x[rate_index]; 783 } 784 785 /* interpolate to get target power for given frequency */ 786 return 787 ((u_int8_t)interpolate( 788 (int32_t)freq, freq_array, target_power_array, num_piers)); 789 } 790 791 u_int8_t 792 ar9300_eeprom_get_cck_trgt_pwr(struct ath_hal *ah, u_int16_t rate_index, 793 u_int16_t freq) 794 { 795 u_int16_t num_piers = OSPREY_NUM_2G_CCK_TARGET_POWERS, i; 796 int32_t target_power_array[OSPREY_NUM_2G_CCK_TARGET_POWERS]; 797 int32_t freq_array[OSPREY_NUM_2G_CCK_TARGET_POWERS]; 798 ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom; 799 u_int8_t *p_freq_bin = eep->cal_target_freqbin_cck; 800 CAL_TARGET_POWER_LEG *p_eeprom_target_pwr = eep->cal_target_power_cck; 801 802 /* 803 * create array of channels and targetpower from 804 * targetpower piers stored on eeprom 805 */ 806 for (i = 0; i < num_piers; i++) { 807 freq_array[i] = FBIN2FREQ(p_freq_bin[i], 1); 808 target_power_array[i] = p_eeprom_target_pwr[i].t_pow2x[rate_index]; 809 } 810 811 /* interpolate to get target power for given frequency */ 812 return 813 ((u_int8_t)interpolate( 814 (int32_t)freq, freq_array, target_power_array, num_piers)); 815 } 816 817 /* 818 * Set tx power registers to array of values passed in 819 */ 820 int 821 ar9300_transmit_power_reg_write(struct ath_hal *ah, u_int8_t *p_pwr_array) 822 { 823 #define POW_SM(_r, _s) (((_r) & 0x3f) << (_s)) 824 /* make sure forced gain is not set */ 825 #if 0 826 field_write("force_dac_gain", 0); 827 OS_REG_WRITE(ah, 0xa3f8, 0); 828 field_write("force_tx_gain", 0); 829 #endif 830 831 OS_REG_WRITE(ah, 0xa458, 0); 832 833 /* Write the OFDM power per rate set */ 834 /* 6 (LSB), 9, 12, 18 (MSB) */ 835 OS_REG_WRITE(ah, 0xa3c0, 836 POW_SM(p_pwr_array[ALL_TARGET_LEGACY_6_24], 24) 837 | POW_SM(p_pwr_array[ALL_TARGET_LEGACY_6_24], 16) 838 | POW_SM(p_pwr_array[ALL_TARGET_LEGACY_6_24], 8) 839 | POW_SM(p_pwr_array[ALL_TARGET_LEGACY_6_24], 0) 840 ); 841 /* 24 (LSB), 36, 48, 54 (MSB) */ 842 OS_REG_WRITE(ah, 0xa3c4, 843 POW_SM(p_pwr_array[ALL_TARGET_LEGACY_54], 24) 844 | POW_SM(p_pwr_array[ALL_TARGET_LEGACY_48], 16) 845 | POW_SM(p_pwr_array[ALL_TARGET_LEGACY_36], 8) 846 | POW_SM(p_pwr_array[ALL_TARGET_LEGACY_6_24], 0) 847 ); 848 849 /* Write the CCK power per rate set */ 850 /* 1L (LSB), reserved, 2L, 2S (MSB) */ 851 OS_REG_WRITE(ah, 0xa3c8, 852 POW_SM(p_pwr_array[ALL_TARGET_LEGACY_1L_5L], 24) 853 | POW_SM(p_pwr_array[ALL_TARGET_LEGACY_1L_5L], 16) 854 /* | POW_SM(tx_power_times2, 8)*/ /* this is reserved for Osprey */ 855 | POW_SM(p_pwr_array[ALL_TARGET_LEGACY_1L_5L], 0) 856 ); 857 /* 5.5L (LSB), 5.5S, 11L, 11S (MSB) */ 858 OS_REG_WRITE(ah, 0xa3cc, 859 POW_SM(p_pwr_array[ALL_TARGET_LEGACY_11S], 24) 860 | POW_SM(p_pwr_array[ALL_TARGET_LEGACY_11L], 16) 861 | POW_SM(p_pwr_array[ALL_TARGET_LEGACY_5S], 8) 862 | POW_SM(p_pwr_array[ALL_TARGET_LEGACY_1L_5L], 0) 863 ); 864 865 /* write the power for duplicated frames - HT40 */ 866 /* dup40_cck (LSB), dup40_ofdm, ext20_cck, ext20_ofdm (MSB) */ 867 OS_REG_WRITE(ah, 0xa3e0, 868 POW_SM(p_pwr_array[ALL_TARGET_LEGACY_6_24], 24) 869 | POW_SM(p_pwr_array[ALL_TARGET_LEGACY_1L_5L], 16) 870 | POW_SM(p_pwr_array[ALL_TARGET_LEGACY_6_24], 8) 871 | POW_SM(p_pwr_array[ALL_TARGET_LEGACY_1L_5L], 0) 872 ); 873 874 /* Write the HT20 power per rate set */ 875 /* 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) */ 876 OS_REG_WRITE(ah, 0xa3d0, 877 POW_SM(p_pwr_array[ALL_TARGET_HT20_5], 24) 878 | POW_SM(p_pwr_array[ALL_TARGET_HT20_4], 16) 879 | POW_SM(p_pwr_array[ALL_TARGET_HT20_1_3_9_11_17_19], 8) 880 | POW_SM(p_pwr_array[ALL_TARGET_HT20_0_8_16], 0) 881 ); 882 883 /* 6 (LSB), 7, 12, 13 (MSB) */ 884 OS_REG_WRITE(ah, 0xa3d4, 885 POW_SM(p_pwr_array[ALL_TARGET_HT20_13], 24) 886 | POW_SM(p_pwr_array[ALL_TARGET_HT20_12], 16) 887 | POW_SM(p_pwr_array[ALL_TARGET_HT20_7], 8) 888 | POW_SM(p_pwr_array[ALL_TARGET_HT20_6], 0) 889 ); 890 891 /* 14 (LSB), 15, 20, 21 */ 892 OS_REG_WRITE(ah, 0xa3e4, 893 POW_SM(p_pwr_array[ALL_TARGET_HT20_21], 24) 894 | POW_SM(p_pwr_array[ALL_TARGET_HT20_20], 16) 895 | POW_SM(p_pwr_array[ALL_TARGET_HT20_15], 8) 896 | POW_SM(p_pwr_array[ALL_TARGET_HT20_14], 0) 897 ); 898 899 /* Mixed HT20 and HT40 rates */ 900 /* HT20 22 (LSB), HT20 23, HT40 22, HT40 23 (MSB) */ 901 OS_REG_WRITE(ah, 0xa3e8, 902 POW_SM(p_pwr_array[ALL_TARGET_HT40_23], 24) 903 | POW_SM(p_pwr_array[ALL_TARGET_HT40_22], 16) 904 | POW_SM(p_pwr_array[ALL_TARGET_HT20_23], 8) 905 | POW_SM(p_pwr_array[ALL_TARGET_HT20_22], 0) 906 ); 907 908 /* Write the HT40 power per rate set */ 909 /* correct PAR difference between HT40 and HT20/LEGACY */ 910 /* 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) */ 911 OS_REG_WRITE(ah, 0xa3d8, 912 POW_SM(p_pwr_array[ALL_TARGET_HT40_5], 24) 913 | POW_SM(p_pwr_array[ALL_TARGET_HT40_4], 16) 914 | POW_SM(p_pwr_array[ALL_TARGET_HT40_1_3_9_11_17_19], 8) 915 | POW_SM(p_pwr_array[ALL_TARGET_HT40_0_8_16], 0) 916 ); 917 918 /* 6 (LSB), 7, 12, 13 (MSB) */ 919 OS_REG_WRITE(ah, 0xa3dc, 920 POW_SM(p_pwr_array[ALL_TARGET_HT40_13], 24) 921 | POW_SM(p_pwr_array[ALL_TARGET_HT40_12], 16) 922 | POW_SM(p_pwr_array[ALL_TARGET_HT40_7], 8) 923 | POW_SM(p_pwr_array[ALL_TARGET_HT40_6], 0) 924 ); 925 926 /* 14 (LSB), 15, 20, 21 */ 927 OS_REG_WRITE(ah, 0xa3ec, 928 POW_SM(p_pwr_array[ALL_TARGET_HT40_21], 24) 929 | POW_SM(p_pwr_array[ALL_TARGET_HT40_20], 16) 930 | POW_SM(p_pwr_array[ALL_TARGET_HT40_15], 8) 931 | POW_SM(p_pwr_array[ALL_TARGET_HT40_14], 0) 932 ); 933 934 return 0; 935 #undef POW_SM 936 } 937 938 static void 939 ar9300_selfgen_tpc_reg_write(struct ath_hal *ah, const struct ieee80211_channel *chan, 940 u_int8_t *p_pwr_array) 941 { 942 u_int32_t tpc_reg_val; 943 944 /* Set the target power values for self generated frames (ACK,RTS/CTS) to 945 * be within limits. This is just a safety measure.With per packet TPC mode 946 * enabled the target power value used with self generated frames will be 947 * MIN( TPC reg, BB_powertx_rate register) 948 */ 949 950 if (IEEE80211_IS_CHAN_2GHZ(chan)) { 951 tpc_reg_val = (SM(p_pwr_array[ALL_TARGET_LEGACY_1L_5L], AR_TPC_ACK) | 952 SM(p_pwr_array[ALL_TARGET_LEGACY_1L_5L], AR_TPC_CTS) | 953 SM(0x3f, AR_TPC_CHIRP) | 954 SM(0x3f, AR_TPC_RPT)); 955 } else { 956 tpc_reg_val = (SM(p_pwr_array[ALL_TARGET_LEGACY_6_24], AR_TPC_ACK) | 957 SM(p_pwr_array[ALL_TARGET_LEGACY_6_24], AR_TPC_CTS) | 958 SM(0x3f, AR_TPC_CHIRP) | 959 SM(0x3f, AR_TPC_RPT)); 960 } 961 OS_REG_WRITE(ah, AR_TPC, tpc_reg_val); 962 } 963 964 void 965 ar9300_set_target_power_from_eeprom(struct ath_hal *ah, u_int16_t freq, 966 u_int8_t *target_power_val_t2) 967 { 968 /* hard code for now, need to get from eeprom struct */ 969 u_int8_t ht40_power_inc_for_pdadc = 0; 970 HAL_BOOL is_2ghz = 0; 971 972 if (freq < 4000) { 973 is_2ghz = 1; 974 } 975 976 target_power_val_t2[ALL_TARGET_LEGACY_6_24] = 977 ar9300_eeprom_get_legacy_trgt_pwr( 978 ah, LEGACY_TARGET_RATE_6_24, freq, is_2ghz); 979 target_power_val_t2[ALL_TARGET_LEGACY_36] = 980 ar9300_eeprom_get_legacy_trgt_pwr( 981 ah, LEGACY_TARGET_RATE_36, freq, is_2ghz); 982 target_power_val_t2[ALL_TARGET_LEGACY_48] = 983 ar9300_eeprom_get_legacy_trgt_pwr( 984 ah, LEGACY_TARGET_RATE_48, freq, is_2ghz); 985 target_power_val_t2[ALL_TARGET_LEGACY_54] = 986 ar9300_eeprom_get_legacy_trgt_pwr( 987 ah, LEGACY_TARGET_RATE_54, freq, is_2ghz); 988 target_power_val_t2[ALL_TARGET_LEGACY_1L_5L] = 989 ar9300_eeprom_get_cck_trgt_pwr( 990 ah, LEGACY_TARGET_RATE_1L_5L, freq); 991 target_power_val_t2[ALL_TARGET_LEGACY_5S] = 992 ar9300_eeprom_get_cck_trgt_pwr( 993 ah, LEGACY_TARGET_RATE_5S, freq); 994 target_power_val_t2[ALL_TARGET_LEGACY_11L] = 995 ar9300_eeprom_get_cck_trgt_pwr( 996 ah, LEGACY_TARGET_RATE_11L, freq); 997 target_power_val_t2[ALL_TARGET_LEGACY_11S] = 998 ar9300_eeprom_get_cck_trgt_pwr( 999 ah, LEGACY_TARGET_RATE_11S, freq); 1000 target_power_val_t2[ALL_TARGET_HT20_0_8_16] = 1001 ar9300_eeprom_get_ht20_trgt_pwr( 1002 ah, HT_TARGET_RATE_0_8_16, freq, is_2ghz); 1003 target_power_val_t2[ALL_TARGET_HT20_1_3_9_11_17_19] = 1004 ar9300_eeprom_get_ht20_trgt_pwr( 1005 ah, HT_TARGET_RATE_1_3_9_11_17_19, freq, is_2ghz); 1006 target_power_val_t2[ALL_TARGET_HT20_4] = 1007 ar9300_eeprom_get_ht20_trgt_pwr( 1008 ah, HT_TARGET_RATE_4, freq, is_2ghz); 1009 target_power_val_t2[ALL_TARGET_HT20_5] = 1010 ar9300_eeprom_get_ht20_trgt_pwr( 1011 ah, HT_TARGET_RATE_5, freq, is_2ghz); 1012 target_power_val_t2[ALL_TARGET_HT20_6] = 1013 ar9300_eeprom_get_ht20_trgt_pwr( 1014 ah, HT_TARGET_RATE_6, freq, is_2ghz); 1015 target_power_val_t2[ALL_TARGET_HT20_7] = 1016 ar9300_eeprom_get_ht20_trgt_pwr( 1017 ah, HT_TARGET_RATE_7, freq, is_2ghz); 1018 target_power_val_t2[ALL_TARGET_HT20_12] = 1019 ar9300_eeprom_get_ht20_trgt_pwr( 1020 ah, HT_TARGET_RATE_12, freq, is_2ghz); 1021 target_power_val_t2[ALL_TARGET_HT20_13] = 1022 ar9300_eeprom_get_ht20_trgt_pwr( 1023 ah, HT_TARGET_RATE_13, freq, is_2ghz); 1024 target_power_val_t2[ALL_TARGET_HT20_14] = 1025 ar9300_eeprom_get_ht20_trgt_pwr( 1026 ah, HT_TARGET_RATE_14, freq, is_2ghz); 1027 target_power_val_t2[ALL_TARGET_HT20_15] = 1028 ar9300_eeprom_get_ht20_trgt_pwr( 1029 ah, HT_TARGET_RATE_15, freq, is_2ghz); 1030 target_power_val_t2[ALL_TARGET_HT20_20] = 1031 ar9300_eeprom_get_ht20_trgt_pwr( 1032 ah, HT_TARGET_RATE_20, freq, is_2ghz); 1033 target_power_val_t2[ALL_TARGET_HT20_21] = 1034 ar9300_eeprom_get_ht20_trgt_pwr( 1035 ah, HT_TARGET_RATE_21, freq, is_2ghz); 1036 target_power_val_t2[ALL_TARGET_HT20_22] = 1037 ar9300_eeprom_get_ht20_trgt_pwr( 1038 ah, HT_TARGET_RATE_22, freq, is_2ghz); 1039 target_power_val_t2[ALL_TARGET_HT20_23] = 1040 ar9300_eeprom_get_ht20_trgt_pwr( 1041 ah, HT_TARGET_RATE_23, freq, is_2ghz); 1042 target_power_val_t2[ALL_TARGET_HT40_0_8_16] = 1043 ar9300_eeprom_get_ht40_trgt_pwr( 1044 ah, HT_TARGET_RATE_0_8_16, freq, is_2ghz) + 1045 ht40_power_inc_for_pdadc; 1046 target_power_val_t2[ALL_TARGET_HT40_1_3_9_11_17_19] = 1047 ar9300_eeprom_get_ht40_trgt_pwr( 1048 ah, HT_TARGET_RATE_1_3_9_11_17_19, freq, is_2ghz) + 1049 ht40_power_inc_for_pdadc; 1050 target_power_val_t2[ALL_TARGET_HT40_4] = 1051 ar9300_eeprom_get_ht40_trgt_pwr( 1052 ah, HT_TARGET_RATE_4, freq, is_2ghz) + ht40_power_inc_for_pdadc; 1053 target_power_val_t2[ALL_TARGET_HT40_5] = 1054 ar9300_eeprom_get_ht40_trgt_pwr( 1055 ah, HT_TARGET_RATE_5, freq, is_2ghz) + ht40_power_inc_for_pdadc; 1056 target_power_val_t2[ALL_TARGET_HT40_6] = 1057 ar9300_eeprom_get_ht40_trgt_pwr( 1058 ah, HT_TARGET_RATE_6, freq, is_2ghz) + ht40_power_inc_for_pdadc; 1059 target_power_val_t2[ALL_TARGET_HT40_7] = 1060 ar9300_eeprom_get_ht40_trgt_pwr( 1061 ah, HT_TARGET_RATE_7, freq, is_2ghz) + ht40_power_inc_for_pdadc; 1062 target_power_val_t2[ALL_TARGET_HT40_12] = 1063 ar9300_eeprom_get_ht40_trgt_pwr( 1064 ah, HT_TARGET_RATE_12, freq, is_2ghz) + ht40_power_inc_for_pdadc; 1065 target_power_val_t2[ALL_TARGET_HT40_13] = 1066 ar9300_eeprom_get_ht40_trgt_pwr( 1067 ah, HT_TARGET_RATE_13, freq, is_2ghz) + ht40_power_inc_for_pdadc; 1068 target_power_val_t2[ALL_TARGET_HT40_14] = 1069 ar9300_eeprom_get_ht40_trgt_pwr( 1070 ah, HT_TARGET_RATE_14, freq, is_2ghz) + ht40_power_inc_for_pdadc; 1071 target_power_val_t2[ALL_TARGET_HT40_15] = 1072 ar9300_eeprom_get_ht40_trgt_pwr( 1073 ah, HT_TARGET_RATE_15, freq, is_2ghz) + ht40_power_inc_for_pdadc; 1074 target_power_val_t2[ALL_TARGET_HT40_20] = 1075 ar9300_eeprom_get_ht40_trgt_pwr( 1076 ah, HT_TARGET_RATE_20, freq, is_2ghz) + ht40_power_inc_for_pdadc; 1077 target_power_val_t2[ALL_TARGET_HT40_21] = 1078 ar9300_eeprom_get_ht40_trgt_pwr( 1079 ah, HT_TARGET_RATE_21, freq, is_2ghz) + ht40_power_inc_for_pdadc; 1080 target_power_val_t2[ALL_TARGET_HT40_22] = 1081 ar9300_eeprom_get_ht40_trgt_pwr( 1082 ah, HT_TARGET_RATE_22, freq, is_2ghz) + ht40_power_inc_for_pdadc; 1083 target_power_val_t2[ALL_TARGET_HT40_23] = 1084 ar9300_eeprom_get_ht40_trgt_pwr( 1085 ah, HT_TARGET_RATE_23, freq, is_2ghz) + ht40_power_inc_for_pdadc; 1086 1087 #ifdef AH_DEBUG 1088 { 1089 int i = 0; 1090 1091 HALDEBUG(ah, HAL_DEBUG_EEPROM, "%s: APPLYING TARGET POWERS\n", __func__); 1092 while (i < ar9300_rate_size) { 1093 HALDEBUG(ah, HAL_DEBUG_EEPROM, "%s: TPC[%02d] 0x%08x ", 1094 __func__, i, target_power_val_t2[i]); 1095 i++; 1096 if (i == ar9300_rate_size) { 1097 break; 1098 } 1099 HALDEBUG(ah, HAL_DEBUG_EEPROM, "%s: TPC[%02d] 0x%08x ", 1100 __func__, i, target_power_val_t2[i]); 1101 i++; 1102 if (i == ar9300_rate_size) { 1103 break; 1104 } 1105 HALDEBUG(ah, HAL_DEBUG_EEPROM, "%s: TPC[%02d] 0x%08x ", 1106 __func__, i, target_power_val_t2[i]); 1107 i++; 1108 if (i == ar9300_rate_size) { 1109 break; 1110 } 1111 HALDEBUG(ah, HAL_DEBUG_EEPROM, "%s: TPC[%02d] 0x%08x \n", 1112 __func__, i, target_power_val_t2[i]); 1113 i++; 1114 } 1115 } 1116 #endif 1117 } 1118 1119 u_int16_t *ar9300_regulatory_domain_get(struct ath_hal *ah) 1120 { 1121 ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom; 1122 return eep->base_eep_header.reg_dmn; 1123 } 1124 1125 1126 int32_t 1127 ar9300_eeprom_write_enable_gpio_get(struct ath_hal *ah) 1128 { 1129 ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom; 1130 return eep->base_eep_header.eeprom_write_enable_gpio; 1131 } 1132 1133 int32_t 1134 ar9300_wlan_disable_gpio_get(struct ath_hal *ah) 1135 { 1136 ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom; 1137 return eep->base_eep_header.wlan_disable_gpio; 1138 } 1139 1140 int32_t 1141 ar9300_wlan_led_gpio_get(struct ath_hal *ah) 1142 { 1143 ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom; 1144 return eep->base_eep_header.wlan_led_gpio; 1145 } 1146 1147 int32_t 1148 ar9300_rx_band_select_gpio_get(struct ath_hal *ah) 1149 { 1150 ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom; 1151 return eep->base_eep_header.rx_band_select_gpio; 1152 } 1153 1154 /* 1155 * since valid noise floor values are negative, returns 1 on error 1156 */ 1157 int32_t 1158 ar9300_noise_floor_cal_or_power_get(struct ath_hal *ah, int32_t frequency, 1159 int32_t ichain, HAL_BOOL use_cal) 1160 { 1161 int nf_use = 1; /* start with an error return value */ 1162 int32_t fx[OSPREY_NUM_5G_CAL_PIERS + OSPREY_NUM_2G_CAL_PIERS]; 1163 int32_t nf[OSPREY_NUM_5G_CAL_PIERS + OSPREY_NUM_2G_CAL_PIERS]; 1164 int nnf; 1165 int is_2ghz; 1166 int ipier, npier; 1167 ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom; 1168 u_int8_t *p_cal_pier; 1169 OSP_CAL_DATA_PER_FREQ_OP_LOOP *p_cal_pier_struct; 1170 1171 /* 1172 * check chain value 1173 */ 1174 if (ichain < 0 || ichain >= OSPREY_MAX_CHAINS) { 1175 return 1; 1176 } 1177 1178 /* figure out which band we're using */ 1179 is_2ghz = (frequency < 4000); 1180 if (is_2ghz) { 1181 npier = OSPREY_NUM_2G_CAL_PIERS; 1182 p_cal_pier = eep->cal_freq_pier_2g; 1183 p_cal_pier_struct = eep->cal_pier_data_2g[ichain]; 1184 } else { 1185 npier = OSPREY_NUM_5G_CAL_PIERS; 1186 p_cal_pier = eep->cal_freq_pier_5g; 1187 p_cal_pier_struct = eep->cal_pier_data_5g[ichain]; 1188 } 1189 /* look for valid noise floor values */ 1190 nnf = 0; 1191 for (ipier = 0; ipier < npier; ipier++) { 1192 fx[nnf] = FBIN2FREQ(p_cal_pier[ipier], is_2ghz); 1193 nf[nnf] = use_cal ? 1194 p_cal_pier_struct[ipier].rx_noisefloor_cal : 1195 p_cal_pier_struct[ipier].rx_noisefloor_power; 1196 if (nf[nnf] < 0) { 1197 nnf++; 1198 } 1199 } 1200 /* 1201 * If we have some valid values, interpolate to find the value 1202 * at the desired frequency. 1203 */ 1204 if (nnf > 0) { 1205 nf_use = interpolate(frequency, fx, nf, nnf); 1206 } 1207 1208 return nf_use; 1209 } 1210 1211 /* 1212 * Return the Rx NF offset for specific channel. 1213 * The values saved in EEPROM/OTP/Flash is converted through the following way: 1214 * ((_p) - NOISE_PWR_DATA_OFFSET) << 2 1215 * So we need to convert back to the original values. 1216 */ 1217 int ar9300_get_rx_nf_offset(struct ath_hal *ah, struct ieee80211_channel *chan, int8_t *nf_pwr, int8_t *nf_cal) { 1218 HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan); 1219 int8_t rx_nf_pwr, rx_nf_cal; 1220 int i; 1221 //HALASSERT(ichan); 1222 1223 /* Fill 0 if valid internal channel is not found */ 1224 if (ichan == AH_NULL) { 1225 OS_MEMZERO(nf_pwr, sizeof(nf_pwr[0])*OSPREY_MAX_CHAINS); 1226 OS_MEMZERO(nf_cal, sizeof(nf_cal[0])*OSPREY_MAX_CHAINS); 1227 return -1; 1228 } 1229 1230 for (i = 0; i < OSPREY_MAX_CHAINS; i++) { 1231 if ((rx_nf_pwr = ar9300_noise_floor_cal_or_power_get(ah, ichan->channel, i, 0)) == 1) { 1232 nf_pwr[i] = 0; 1233 } else { 1234 //printk("%s: raw nf_pwr[%d] = %d\n", __func__, i, rx_nf_pwr); 1235 nf_pwr[i] = NOISE_PWR_DBM_2_INT(rx_nf_pwr); 1236 } 1237 1238 if ((rx_nf_cal = ar9300_noise_floor_cal_or_power_get(ah, ichan->channel, i, 1)) == 1) { 1239 nf_cal[i] = 0; 1240 } else { 1241 //printk("%s: raw nf_cal[%d] = %d\n", __func__, i, rx_nf_cal); 1242 nf_cal[i] = NOISE_PWR_DBM_2_INT(rx_nf_cal); 1243 } 1244 } 1245 1246 return 0; 1247 } 1248 1249 int32_t ar9300_rx_gain_index_get(struct ath_hal *ah) 1250 { 1251 ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom; 1252 1253 return (eep->base_eep_header.txrxgain) & 0xf; /* bits 3:0 */ 1254 } 1255 1256 1257 int32_t ar9300_tx_gain_index_get(struct ath_hal *ah) 1258 { 1259 ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom; 1260 1261 return (eep->base_eep_header.txrxgain >> 4) & 0xf; /* bits 7:4 */ 1262 } 1263 1264 HAL_BOOL ar9300_internal_regulator_apply(struct ath_hal *ah) 1265 { 1266 struct ath_hal_9300 *ahp = AH9300(ah); 1267 int internal_regulator = ar9300_eeprom_get(ahp, EEP_INTERNAL_REGULATOR); 1268 int reg_pmu1, reg_pmu2, reg_pmu1_set, reg_pmu2_set; 1269 u_int32_t reg_PMU1, reg_PMU2; 1270 unsigned long eep_addr; 1271 u_int32_t reg_val, reg_usb = 0, reg_pmu = 0; 1272 int usb_valid = 0, pmu_valid = 0; 1273 unsigned char pmu_refv; 1274 1275 if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) { 1276 reg_PMU1 = AR_PHY_PMU1_JUPITER; 1277 reg_PMU2 = AR_PHY_PMU2_JUPITER; 1278 } 1279 else { 1280 reg_PMU1 = AR_PHY_PMU1; 1281 reg_PMU2 = AR_PHY_PMU2; 1282 } 1283 1284 if (internal_regulator) { 1285 if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah)) { 1286 if (AR_SREV_HORNET(ah)) { 1287 /* Read OTP first */ 1288 for (eep_addr = 0x14; ; eep_addr -= 0x10) { 1289 1290 ar9300_otp_read(ah, eep_addr / 4, ®_val, 1); 1291 1292 if ((reg_val & 0x80) == 0x80){ 1293 usb_valid = 1; 1294 reg_usb = reg_val & 0x000000ff; 1295 } 1296 1297 if ((reg_val & 0x80000000) == 0x80000000){ 1298 pmu_valid = 1; 1299 reg_pmu = (reg_val & 0xff000000) >> 24; 1300 } 1301 1302 if (eep_addr == 0x4) { 1303 break; 1304 } 1305 } 1306 1307 if (pmu_valid) { 1308 pmu_refv = reg_pmu & 0xf; 1309 } else { 1310 pmu_refv = 0x8; 1311 } 1312 1313 /* 1314 * If (valid) { 1315 * Usb_phy_ctrl2_tx_cal_en -> 0 1316 * Usb_phy_ctrl2_tx_cal_sel -> 0 1317 * Usb_phy_ctrl2_tx_man_cal -> 0, 1, 3, 7 or 15 from OTP 1318 * } 1319 */ 1320 if (usb_valid) { 1321 OS_REG_RMW_FIELD(ah, 0x16c88, AR_PHY_CTRL2_TX_CAL_EN, 0x0); 1322 OS_REG_RMW_FIELD(ah, 0x16c88, AR_PHY_CTRL2_TX_CAL_SEL, 0x0); 1323 OS_REG_RMW_FIELD(ah, 0x16c88, 1324 AR_PHY_CTRL2_TX_MAN_CAL, (reg_usb & 0xf)); 1325 } 1326 1327 } else { 1328 pmu_refv = 0x8; 1329 } 1330 /*#ifndef USE_HIF*/ 1331 /* Follow the MDK settings for Hornet PMU. 1332 * my $pwd = 0x0; 1333 * my $Nfdiv = 0x3; # xtal_freq = 25MHz 1334 * my $Nfdiv = 0x4; # xtal_freq = 40MHz 1335 * my $Refv = 0x7; # 0x5:1.22V; 0x8:1.29V 1336 * my $Gm1 = 0x3; #Poseidon $Gm1=1 1337 * my $classb = 0x0; 1338 * my $Cc = 0x1; #Poseidon $Cc=7 1339 * my $Rc = 0x6; 1340 * my $ramp_slope = 0x1; 1341 * my $Segm = 0x3; 1342 * my $use_local_osc = 0x0; 1343 * my $force_xosc_stable = 0x0; 1344 * my $Selfb = 0x0; #Poseidon $Selfb=1 1345 * my $Filterfb = 0x3; #Poseidon $Filterfb=0 1346 * my $Filtervc = 0x0; 1347 * my $disc = 0x0; 1348 * my $discdel = 0x4; 1349 * my $spare = 0x0; 1350 * $reg_PMU1 = 1351 * $pwd | ($Nfdiv<<1) | ($Refv<<4) | ($Gm1<<8) | 1352 * ($classb<<11) | ($Cc<<14) | ($Rc<<17) | ($ramp_slope<<20) | 1353 * ($Segm<<24) | ($use_local_osc<<26) | 1354 * ($force_xosc_stable<<27) | ($Selfb<<28) | ($Filterfb<<29); 1355 * $reg_PMU2 = $handle->reg_rd("ch0_PMU2"); 1356 * $reg_PMU2 = ($reg_PMU2 & 0xfe3fffff) | ($Filtervc<<22); 1357 * $reg_PMU2 = ($reg_PMU2 & 0xe3ffffff) | ($discdel<<26); 1358 * $reg_PMU2 = ($reg_PMU2 & 0x1fffffff) | ($spare<<29); 1359 */ 1360 if (ahp->clk_25mhz) { 1361 reg_pmu1_set = 0 | 1362 (3 << 1) | (pmu_refv << 4) | (3 << 8) | (0 << 11) | 1363 (1 << 14) | (6 << 17) | (1 << 20) | (3 << 24) | 1364 (0 << 26) | (0 << 27) | (0 << 28) | (0 << 29); 1365 } else { 1366 if (AR_SREV_POSEIDON(ah)) { 1367 reg_pmu1_set = 0 | 1368 (5 << 1) | (7 << 4) | (2 << 8) | (0 << 11) | 1369 (2 << 14) | (6 << 17) | (1 << 20) | (3 << 24) | 1370 (0 << 26) | (0 << 27) | (1 << 28) | (0 << 29) ; 1371 } else { 1372 reg_pmu1_set = 0 | 1373 (4 << 1) | (7 << 4) | (3 << 8) | (0 << 11) | 1374 (1 << 14) | (6 << 17) | (1 << 20) | (3 << 24) | 1375 (0 << 26) | (0 << 27) | (0 << 28) | (0 << 29) ; 1376 } 1377 } 1378 OS_REG_RMW_FIELD(ah, reg_PMU2, AR_PHY_PMU2_PGM, 0x0); 1379 1380 OS_REG_WRITE(ah, reg_PMU1, reg_pmu1_set); /* 0x638c8376 */ 1381 reg_pmu1 = OS_REG_READ(ah, reg_PMU1); 1382 while (reg_pmu1 != reg_pmu1_set) { 1383 OS_REG_WRITE(ah, reg_PMU1, reg_pmu1_set); /* 0x638c8376 */ 1384 OS_DELAY(10); 1385 reg_pmu1 = OS_REG_READ(ah, reg_PMU1); 1386 } 1387 1388 reg_pmu2_set = 1389 (OS_REG_READ(ah, reg_PMU2) & (~0xFFC00000)) | (4 << 26); 1390 OS_REG_WRITE(ah, reg_PMU2, reg_pmu2_set); 1391 reg_pmu2 = OS_REG_READ(ah, reg_PMU2); 1392 while (reg_pmu2 != reg_pmu2_set) { 1393 OS_REG_WRITE(ah, reg_PMU2, reg_pmu2_set); 1394 OS_DELAY(10); 1395 reg_pmu2 = OS_REG_READ(ah, reg_PMU2); 1396 } 1397 reg_pmu2_set = 1398 (OS_REG_READ(ah, reg_PMU2) & (~0x00200000)) | (1 << 21); 1399 OS_REG_WRITE(ah, reg_PMU2, reg_pmu2_set); 1400 reg_pmu2 = OS_REG_READ(ah, reg_PMU2); 1401 while (reg_pmu2 != reg_pmu2_set) { 1402 OS_REG_WRITE(ah, reg_PMU2, reg_pmu2_set); 1403 OS_DELAY(10); 1404 reg_pmu2 = OS_REG_READ(ah, reg_PMU2); 1405 } 1406 /*#endif*/ 1407 } else if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) { 1408 /* Internal regulator is ON. Write swreg register. */ 1409 int swreg = ar9300_eeprom_get(ahp, EEP_SWREG); 1410 OS_REG_WRITE(ah, reg_PMU1, swreg); 1411 } else { 1412 /* Internal regulator is ON. Write swreg register. */ 1413 int swreg = ar9300_eeprom_get(ahp, EEP_SWREG); 1414 OS_REG_WRITE(ah, AR_RTC_REG_CONTROL1, 1415 OS_REG_READ(ah, AR_RTC_REG_CONTROL1) & 1416 (~AR_RTC_REG_CONTROL1_SWREG_PROGRAM)); 1417 OS_REG_WRITE(ah, AR_RTC_REG_CONTROL0, swreg); 1418 /* Set REG_CONTROL1.SWREG_PROGRAM */ 1419 OS_REG_WRITE(ah, AR_RTC_REG_CONTROL1, 1420 OS_REG_READ(ah, AR_RTC_REG_CONTROL1) | 1421 AR_RTC_REG_CONTROL1_SWREG_PROGRAM); 1422 } 1423 } else { 1424 if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah)) { 1425 OS_REG_RMW_FIELD(ah, reg_PMU2, AR_PHY_PMU2_PGM, 0x0); 1426 reg_pmu2 = OS_REG_READ_FIELD(ah, reg_PMU2, AR_PHY_PMU2_PGM); 1427 while (reg_pmu2) { 1428 OS_DELAY(10); 1429 reg_pmu2 = OS_REG_READ_FIELD(ah, reg_PMU2, AR_PHY_PMU2_PGM); 1430 } 1431 OS_REG_RMW_FIELD(ah, reg_PMU1, AR_PHY_PMU1_PWD, 0x1); 1432 reg_pmu1 = OS_REG_READ_FIELD(ah, reg_PMU1, AR_PHY_PMU1_PWD); 1433 while (!reg_pmu1) { 1434 OS_DELAY(10); 1435 reg_pmu1 = OS_REG_READ_FIELD(ah, reg_PMU1, AR_PHY_PMU1_PWD); 1436 } 1437 OS_REG_RMW_FIELD(ah, reg_PMU2, AR_PHY_PMU2_PGM, 0x1); 1438 reg_pmu2 = OS_REG_READ_FIELD(ah, reg_PMU2, AR_PHY_PMU2_PGM); 1439 while (!reg_pmu2) { 1440 OS_DELAY(10); 1441 reg_pmu2 = OS_REG_READ_FIELD(ah, reg_PMU2, AR_PHY_PMU2_PGM); 1442 } 1443 } else if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) { 1444 OS_REG_RMW_FIELD(ah, reg_PMU1, AR_PHY_PMU1_PWD, 0x1); 1445 } else { 1446 OS_REG_WRITE(ah, AR_RTC_SLEEP_CLK, 1447 (OS_REG_READ(ah, AR_RTC_SLEEP_CLK) | 1448 AR_RTC_FORCE_SWREG_PRD | AR_RTC_PCIE_RST_PWDN_EN)); 1449 } 1450 } 1451 1452 return 0; 1453 } 1454 1455 HAL_BOOL ar9300_drive_strength_apply(struct ath_hal *ah) 1456 { 1457 struct ath_hal_9300 *ahp = AH9300(ah); 1458 int drive_strength; 1459 unsigned long reg; 1460 1461 drive_strength = ar9300_eeprom_get(ahp, EEP_DRIVE_STRENGTH); 1462 if (drive_strength) { 1463 reg = OS_REG_READ(ah, AR_PHY_65NM_CH0_BIAS1); 1464 reg &= ~0x00ffffc0; 1465 reg |= 0x5 << 21; 1466 reg |= 0x5 << 18; 1467 reg |= 0x5 << 15; 1468 reg |= 0x5 << 12; 1469 reg |= 0x5 << 9; 1470 reg |= 0x5 << 6; 1471 OS_REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS1, reg); 1472 1473 reg = OS_REG_READ(ah, AR_PHY_65NM_CH0_BIAS2); 1474 reg &= ~0xffffffe0; 1475 reg |= 0x5 << 29; 1476 reg |= 0x5 << 26; 1477 reg |= 0x5 << 23; 1478 reg |= 0x5 << 20; 1479 reg |= 0x5 << 17; 1480 reg |= 0x5 << 14; 1481 reg |= 0x5 << 11; 1482 reg |= 0x5 << 8; 1483 reg |= 0x5 << 5; 1484 OS_REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS2, reg); 1485 1486 reg = OS_REG_READ(ah, AR_PHY_65NM_CH0_BIAS4); 1487 reg &= ~0xff800000; 1488 reg |= 0x5 << 29; 1489 reg |= 0x5 << 26; 1490 reg |= 0x5 << 23; 1491 OS_REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS4, reg); 1492 } 1493 return 0; 1494 } 1495 1496 int32_t ar9300_xpa_bias_level_get(struct ath_hal *ah, HAL_BOOL is_2ghz) 1497 { 1498 ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom; 1499 if (is_2ghz) { 1500 return eep->modal_header_2g.xpa_bias_lvl; 1501 } else { 1502 return eep->modal_header_5g.xpa_bias_lvl; 1503 } 1504 } 1505 1506 HAL_BOOL ar9300_xpa_bias_level_apply(struct ath_hal *ah, HAL_BOOL is_2ghz) 1507 { 1508 /* 1509 * In ar9330 emu, we can't access radio registers, 1510 * merlin is used for radio part. 1511 */ 1512 int bias; 1513 bias = ar9300_xpa_bias_level_get(ah, is_2ghz); 1514 1515 if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah) || AR_SREV_WASP(ah)) { 1516 OS_REG_RMW_FIELD(ah, 1517 AR_HORNET_CH0_TOP2, AR_HORNET_CH0_TOP2_XPABIASLVL, bias); 1518 } else if (AR_SREV_SCORPION(ah)) { 1519 OS_REG_RMW_FIELD(ah, 1520 AR_SCORPION_CH0_TOP, AR_SCORPION_CH0_TOP_XPABIASLVL, bias); 1521 } else if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) { 1522 OS_REG_RMW_FIELD(ah, 1523 AR_PHY_65NM_CH0_TOP_JUPITER, AR_PHY_65NM_CH0_TOP_XPABIASLVL, bias); 1524 } else { 1525 OS_REG_RMW_FIELD(ah, 1526 AR_PHY_65NM_CH0_TOP, AR_PHY_65NM_CH0_TOP_XPABIASLVL, bias); 1527 OS_REG_RMW_FIELD(ah, 1528 AR_PHY_65NM_CH0_THERM, AR_PHY_65NM_CH0_THERM_XPABIASLVL_MSB, 1529 bias >> 2); 1530 OS_REG_RMW_FIELD(ah, 1531 AR_PHY_65NM_CH0_THERM, AR_PHY_65NM_CH0_THERM_XPASHORT2GND, 1); 1532 } 1533 return 0; 1534 } 1535 1536 u_int32_t ar9300_ant_ctrl_common_get(struct ath_hal *ah, HAL_BOOL is_2ghz) 1537 { 1538 ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom; 1539 if (is_2ghz) { 1540 return eep->modal_header_2g.ant_ctrl_common; 1541 } else { 1542 return eep->modal_header_5g.ant_ctrl_common; 1543 } 1544 } 1545 static u_int16_t 1546 ar9300_switch_com_spdt_get(struct ath_hal *ah, HAL_BOOL is_2ghz) 1547 { 1548 ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom; 1549 if (is_2ghz) { 1550 return eep->modal_header_2g.switchcomspdt; 1551 } else { 1552 return eep->modal_header_5g.switchcomspdt; 1553 } 1554 } 1555 u_int32_t ar9300_ant_ctrl_common2_get(struct ath_hal *ah, HAL_BOOL is_2ghz) 1556 { 1557 ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom; 1558 if (is_2ghz) { 1559 return eep->modal_header_2g.ant_ctrl_common2; 1560 } else { 1561 return eep->modal_header_5g.ant_ctrl_common2; 1562 } 1563 } 1564 1565 u_int16_t ar9300_ant_ctrl_chain_get(struct ath_hal *ah, int chain, 1566 HAL_BOOL is_2ghz) 1567 { 1568 ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom; 1569 if (chain >= 0 && chain < OSPREY_MAX_CHAINS) { 1570 if (is_2ghz) { 1571 return eep->modal_header_2g.ant_ctrl_chain[chain]; 1572 } else { 1573 return eep->modal_header_5g.ant_ctrl_chain[chain]; 1574 } 1575 } 1576 return 0; 1577 } 1578 1579 /* 1580 * Select the usage of antenna via the RF switch. 1581 * Default values are loaded from eeprom. 1582 */ 1583 HAL_BOOL ar9300_ant_swcom_sel(struct ath_hal *ah, u_int8_t ops, 1584 u_int32_t *common_tbl1, u_int32_t *common_tbl2) 1585 { 1586 ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom; 1587 struct ath_hal_private *ap = AH_PRIVATE(ah); 1588 const struct ieee80211_channel *curchan = ap->ah_curchan; 1589 enum { 1590 ANT_SELECT_OPS_GET, 1591 ANT_SELECT_OPS_SET, 1592 }; 1593 1594 if (AR_SREV_JUPITER(ah) || AR_SREV_SCORPION(ah)) 1595 return AH_FALSE; 1596 1597 if (!curchan) 1598 return AH_FALSE; 1599 1600 #define AR_SWITCH_TABLE_COM_ALL (0xffff) 1601 #define AR_SWITCH_TABLE_COM_ALL_S (0) 1602 #define AR_SWITCH_TABLE_COM2_ALL (0xffffff) 1603 #define AR_SWITCH_TABLE_COM2_ALL_S (0) 1604 switch (ops) { 1605 case ANT_SELECT_OPS_GET: 1606 *common_tbl1 = OS_REG_READ_FIELD(ah, AR_PHY_SWITCH_COM, 1607 AR_SWITCH_TABLE_COM_ALL); 1608 *common_tbl2 = OS_REG_READ_FIELD(ah, AR_PHY_SWITCH_COM_2, 1609 AR_SWITCH_TABLE_COM2_ALL); 1610 break; 1611 case ANT_SELECT_OPS_SET: 1612 OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, 1613 AR_SWITCH_TABLE_COM_ALL, *common_tbl1); 1614 OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, 1615 AR_SWITCH_TABLE_COM2_ALL, *common_tbl2); 1616 1617 /* write back to eeprom */ 1618 if (IEEE80211_IS_CHAN_2GHZ(curchan)) { 1619 eep->modal_header_2g.ant_ctrl_common = *common_tbl1; 1620 eep->modal_header_2g.ant_ctrl_common2 = *common_tbl2; 1621 } else { 1622 eep->modal_header_5g.ant_ctrl_common = *common_tbl1; 1623 eep->modal_header_5g.ant_ctrl_common2 = *common_tbl2; 1624 } 1625 1626 break; 1627 default: 1628 break; 1629 } 1630 1631 return AH_TRUE; 1632 } 1633 1634 HAL_BOOL ar9300_ant_ctrl_apply(struct ath_hal *ah, HAL_BOOL is_2ghz) 1635 { 1636 u_int32_t value; 1637 struct ath_hal_9300 *ahp = AH9300(ah); 1638 u_int32_t regval; 1639 struct ath_hal_private *ahpriv = AH_PRIVATE(ah); 1640 #if ATH_ANT_DIV_COMB 1641 HAL_CAPABILITIES *pcap = &ahpriv->ah_caps; 1642 #endif /* ATH_ANT_DIV_COMB */ 1643 u_int32_t xlan_gpio_cfg; 1644 u_int8_t i; 1645 1646 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "%s: use_bt_ant_enable=%d\n", 1647 __func__, ahp->ah_lna_div_use_bt_ant_enable); 1648 1649 /* XXX TODO: only if rx_gain_idx == 0 */ 1650 if (AR_SREV_POSEIDON(ah)) { 1651 xlan_gpio_cfg = ah->ah_config.ath_hal_ext_lna_ctl_gpio; 1652 if (xlan_gpio_cfg) { 1653 for (i = 0; i < 32; i++) { 1654 if (xlan_gpio_cfg & (1 << i)) { 1655 ath_hal_gpioCfgOutput(ah, i, 1656 HAL_GPIO_OUTPUT_MUX_PCIE_ATTENTION_LED); 1657 } 1658 } 1659 } 1660 } 1661 #define AR_SWITCH_TABLE_COM_ALL (0xffff) 1662 #define AR_SWITCH_TABLE_COM_ALL_S (0) 1663 #define AR_SWITCH_TABLE_COM_JUPITER_ALL (0xffffff) 1664 #define AR_SWITCH_TABLE_COM_JUPITER_ALL_S (0) 1665 #define AR_SWITCH_TABLE_COM_SCORPION_ALL (0xffffff) 1666 #define AR_SWITCH_TABLE_COM_SCORPION_ALL_S (0) 1667 #define AR_SWITCH_TABLE_COM_HONEYBEE_ALL (0xffffff) 1668 #define AR_SWITCH_TABLE_COM_HONEYBEE_ALL_S (0) 1669 #define AR_SWITCH_TABLE_COM_SPDT (0x00f00000) 1670 value = ar9300_ant_ctrl_common_get(ah, is_2ghz); 1671 if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) { 1672 if (AR_SREV_JUPITER_10(ah)) { 1673 /* Force SPDT setting for Jupiter 1.0 chips. */ 1674 value &= ~AR_SWITCH_TABLE_COM_SPDT; 1675 value |= 0x00100000; 1676 } 1677 OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, 1678 AR_SWITCH_TABLE_COM_JUPITER_ALL, value); 1679 } 1680 else if (AR_SREV_SCORPION(ah)) { 1681 OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, 1682 AR_SWITCH_TABLE_COM_SCORPION_ALL, value); 1683 } 1684 else if (AR_SREV_HONEYBEE(ah)) { 1685 OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, 1686 AR_SWITCH_TABLE_COM_HONEYBEE_ALL, value); 1687 } 1688 else { 1689 OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, 1690 AR_SWITCH_TABLE_COM_ALL, value); 1691 } 1692 /* 1693 * Jupiter2.0 defines new switch table for BT/WLAN, 1694 * here's new field name in WB222.ref for both 2G and 5G. 1695 * Register: [GLB_CONTROL] GLB_CONTROL (@0x20044) 1696 * 15:12 R/W SWITCH_TABLE_COM_SPDT_WLAN_RX SWITCH_TABLE_COM_SPDT_WLAN_RX 1697 * 11:8 R/W SWITCH_TABLE_COM_SPDT_WLAN_TX SWITCH_TABLE_COM_SPDT_WLAN_TX 1698 * 7:4 R/W SWITCH_TABLE_COM_SPDT_WLAN_IDLE SWITCH_TABLE_COM_SPDT_WLAN_IDLE 1699 */ 1700 #define AR_SWITCH_TABLE_COM_SPDT_ALL (0x0000fff0) 1701 #define AR_SWITCH_TABLE_COM_SPDT_ALL_S (4) 1702 if (AR_SREV_JUPITER_20_OR_LATER(ah) || AR_SREV_APHRODITE(ah)) { 1703 value = ar9300_switch_com_spdt_get(ah, is_2ghz); 1704 OS_REG_RMW_FIELD(ah, AR_GLB_CONTROL, 1705 AR_SWITCH_TABLE_COM_SPDT_ALL, value); 1706 1707 OS_REG_SET_BIT(ah, AR_GLB_CONTROL, 1708 AR_BTCOEX_CTRL_SPDT_ENABLE); 1709 //OS_REG_SET_BIT(ah, AR_GLB_CONTROL, 1710 // AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL); 1711 } 1712 1713 #define AR_SWITCH_TABLE_COM2_ALL (0xffffff) 1714 #define AR_SWITCH_TABLE_COM2_ALL_S (0) 1715 value = ar9300_ant_ctrl_common2_get(ah, is_2ghz); 1716 #if ATH_ANT_DIV_COMB 1717 if ( AR_SREV_POSEIDON(ah) && (ahp->ah_lna_div_use_bt_ant_enable == TRUE) ) { 1718 value &= ~AR_SWITCH_TABLE_COM2_ALL; 1719 value |= ah->ah_config.ath_hal_ant_ctrl_comm2g_switch_enable; 1720 HALDEBUG(ah, HAL_DEBUG_RESET, "%s: com2=0x%08x\n", __func__, value) 1721 } 1722 #endif /* ATH_ANT_DIV_COMB */ 1723 OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value); 1724 1725 #define AR_SWITCH_TABLE_ALL (0xfff) 1726 #define AR_SWITCH_TABLE_ALL_S (0) 1727 value = ar9300_ant_ctrl_chain_get(ah, 0, is_2ghz); 1728 OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_0, AR_SWITCH_TABLE_ALL, value); 1729 1730 if (!AR_SREV_HORNET(ah) && !AR_SREV_POSEIDON(ah) && !AR_SREV_APHRODITE(ah)) { 1731 value = ar9300_ant_ctrl_chain_get(ah, 1, is_2ghz); 1732 OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_1, AR_SWITCH_TABLE_ALL, value); 1733 1734 if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah) && !AR_SREV_HONEYBEE(ah)) { 1735 value = ar9300_ant_ctrl_chain_get(ah, 2, is_2ghz); 1736 OS_REG_RMW_FIELD(ah, 1737 AR_PHY_SWITCH_CHAIN_2, AR_SWITCH_TABLE_ALL, value); 1738 } 1739 } 1740 if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah) || AR_SREV_APHRODITE(ah)) { 1741 value = ar9300_eeprom_get(ahp, EEP_ANTDIV_control); 1742 /* main_lnaconf, alt_lnaconf, main_tb, alt_tb */ 1743 regval = OS_REG_READ(ah, AR_PHY_MC_GAIN_CTRL); 1744 regval &= (~ANT_DIV_CONTROL_ALL); /* clear bit 25~30 */ 1745 regval |= (value & 0x3f) << ANT_DIV_CONTROL_ALL_S; 1746 /* enable_lnadiv */ 1747 regval &= (~MULTICHAIN_GAIN_CTRL__ENABLE_ANT_DIV_LNADIV__MASK); 1748 regval |= ((value >> 6) & 0x1) << 1749 MULTICHAIN_GAIN_CTRL__ENABLE_ANT_DIV_LNADIV__SHIFT; 1750 #if ATH_ANT_DIV_COMB 1751 if ( AR_SREV_POSEIDON(ah) && (ahp->ah_lna_div_use_bt_ant_enable == TRUE) ) { 1752 regval |= ANT_DIV_ENABLE; 1753 } 1754 if (AR_SREV_APHRODITE(ah)) { 1755 if (ahp->ah_lna_div_use_bt_ant_enable) { 1756 regval |= (1 << MULTICHAIN_GAIN_CTRL__ENABLE_ANT_SW_RX_PROT__SHIFT); 1757 1758 OS_REG_SET_BIT(ah, AR_PHY_RESTART, 1759 RESTART__ENABLE_ANT_FAST_DIV_M2FLAG__MASK); 1760 1761 /* Force WLAN LNA diversity ON */ 1762 OS_REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, 1763 AR_BTCOEX_WL_LNADIV_FORCE_ON); 1764 } else { 1765 regval &= ~(1 << MULTICHAIN_GAIN_CTRL__ENABLE_ANT_DIV_LNADIV__SHIFT); 1766 regval &= ~(1 << MULTICHAIN_GAIN_CTRL__ENABLE_ANT_SW_RX_PROT__SHIFT); 1767 1768 OS_REG_CLR_BIT(ah, AR_PHY_MC_GAIN_CTRL, 1769 (1 << MULTICHAIN_GAIN_CTRL__ENABLE_ANT_SW_RX_PROT__SHIFT)); 1770 1771 /* Force WLAN LNA diversity OFF */ 1772 OS_REG_CLR_BIT(ah, AR_BTCOEX_WL_LNADIV, 1773 AR_BTCOEX_WL_LNADIV_FORCE_ON); 1774 } 1775 } 1776 1777 #endif /* ATH_ANT_DIV_COMB */ 1778 OS_REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval); 1779 1780 /* enable fast_div */ 1781 regval = OS_REG_READ(ah, AR_PHY_CCK_DETECT); 1782 regval &= (~BBB_SIG_DETECT__ENABLE_ANT_FAST_DIV__MASK); 1783 regval |= ((value >> 7) & 0x1) << 1784 BBB_SIG_DETECT__ENABLE_ANT_FAST_DIV__SHIFT; 1785 #if ATH_ANT_DIV_COMB 1786 if ((AR_SREV_POSEIDON(ah) || AR_SREV_APHRODITE(ah)) 1787 && (ahp->ah_lna_div_use_bt_ant_enable == TRUE) ) { 1788 regval |= FAST_DIV_ENABLE; 1789 } 1790 #endif /* ATH_ANT_DIV_COMB */ 1791 OS_REG_WRITE(ah, AR_PHY_CCK_DETECT, regval); 1792 } 1793 1794 #if ATH_ANT_DIV_COMB 1795 if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON_11_OR_LATER(ah)) { 1796 if (pcap->halAntDivCombSupport) { 1797 /* If support DivComb, set MAIN to LNA1, ALT to LNA2 at beginning */ 1798 regval = OS_REG_READ(ah, AR_PHY_MC_GAIN_CTRL); 1799 /* clear bit 25~30 main_lnaconf, alt_lnaconf, main_tb, alt_tb */ 1800 regval &= (~(MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_LNACONF__MASK | 1801 MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_LNACONF__MASK | 1802 MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_GAINTB__MASK | 1803 MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_GAINTB__MASK)); 1804 regval |= (HAL_ANT_DIV_COMB_LNA1 << 1805 MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_LNACONF__SHIFT); 1806 regval |= (HAL_ANT_DIV_COMB_LNA2 << 1807 MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_LNACONF__SHIFT); 1808 OS_REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval); 1809 } 1810 1811 } 1812 #endif /* ATH_ANT_DIV_COMB */ 1813 if (AR_SREV_POSEIDON(ah) && ( ahp->ah_diversity_control == HAL_ANT_FIXED_A 1814 || ahp->ah_diversity_control == HAL_ANT_FIXED_B)) 1815 { 1816 u_int32_t reg_val = OS_REG_READ(ah, AR_PHY_MC_GAIN_CTRL); 1817 reg_val &= ~(MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_LNACONF__MASK | 1818 MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_LNACONF__MASK | 1819 MULTICHAIN_GAIN_CTRL__ANT_FAST_DIV_BIAS__MASK | 1820 MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_GAINTB__MASK | 1821 MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_GAINTB__MASK ); 1822 1823 switch (ahp->ah_diversity_control) { 1824 case HAL_ANT_FIXED_A: 1825 /* Enable first antenna only */ 1826 reg_val |= (HAL_ANT_DIV_COMB_LNA1 << 1827 MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_LNACONF__SHIFT); 1828 reg_val |= (HAL_ANT_DIV_COMB_LNA2 << 1829 MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_LNACONF__SHIFT); 1830 /* main/alt gain table and Fast Div Bias all set to 0 */ 1831 OS_REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, reg_val); 1832 regval = OS_REG_READ(ah, AR_PHY_CCK_DETECT); 1833 regval &= (~BBB_SIG_DETECT__ENABLE_ANT_FAST_DIV__MASK); 1834 OS_REG_WRITE(ah, AR_PHY_CCK_DETECT, regval); 1835 break; 1836 case HAL_ANT_FIXED_B: 1837 /* Enable second antenna only, after checking capability */ 1838 reg_val |= (HAL_ANT_DIV_COMB_LNA2 << 1839 MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_LNACONF__SHIFT); 1840 reg_val |= (HAL_ANT_DIV_COMB_LNA1 << 1841 MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_LNACONF__SHIFT); 1842 /* main/alt gain table and Fast Div all set to 0 */ 1843 OS_REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, reg_val); 1844 regval = OS_REG_READ(ah, AR_PHY_CCK_DETECT); 1845 regval &= (~BBB_SIG_DETECT__ENABLE_ANT_FAST_DIV__MASK); 1846 OS_REG_WRITE(ah, AR_PHY_CCK_DETECT, regval); 1847 /* For WB225, need to swith ANT2 from BT to Wifi 1848 * This will not affect HB125 LNA diversity feature. 1849 */ 1850 HALDEBUG(ah, HAL_DEBUG_RESET, "%s: com2=0x%08x\n", __func__, 1851 ah->ah_config.ath_hal_ant_ctrl_comm2g_switch_enable) 1852 OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, 1853 ah->ah_config.ath_hal_ant_ctrl_comm2g_switch_enable); 1854 break; 1855 default: 1856 break; 1857 } 1858 } 1859 return 0; 1860 } 1861 1862 static u_int16_t 1863 ar9300_attenuation_chain_get(struct ath_hal *ah, int chain, u_int16_t channel) 1864 { 1865 int32_t f[3], t[3]; 1866 u_int16_t value; 1867 ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom; 1868 if (chain >= 0 && chain < OSPREY_MAX_CHAINS) { 1869 if (channel < 4000) { 1870 return eep->modal_header_2g.xatten1_db[chain]; 1871 } else { 1872 if (eep->base_ext2.xatten1_db_low[chain] != 0) { 1873 t[0] = eep->base_ext2.xatten1_db_low[chain]; 1874 f[0] = 5180; 1875 t[1] = eep->modal_header_5g.xatten1_db[chain]; 1876 f[1] = 5500; 1877 t[2] = eep->base_ext2.xatten1_db_high[chain]; 1878 f[2] = 5785; 1879 value = interpolate(channel, f, t, 3); 1880 return value; 1881 } else { 1882 return eep->modal_header_5g.xatten1_db[chain]; 1883 } 1884 } 1885 } 1886 return 0; 1887 } 1888 1889 static u_int16_t 1890 ar9300_attenuation_margin_chain_get(struct ath_hal *ah, int chain, 1891 u_int16_t channel) 1892 { 1893 int32_t f[3], t[3]; 1894 u_int16_t value; 1895 ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom; 1896 if (chain >= 0 && chain < OSPREY_MAX_CHAINS) { 1897 if (channel < 4000) { 1898 return eep->modal_header_2g.xatten1_margin[chain]; 1899 } else { 1900 if (eep->base_ext2.xatten1_margin_low[chain] != 0) { 1901 t[0] = eep->base_ext2.xatten1_margin_low[chain]; 1902 f[0] = 5180; 1903 t[1] = eep->modal_header_5g.xatten1_margin[chain]; 1904 f[1] = 5500; 1905 t[2] = eep->base_ext2.xatten1_margin_high[chain]; 1906 f[2] = 5785; 1907 value = interpolate(channel, f, t, 3); 1908 return value; 1909 } else { 1910 return eep->modal_header_5g.xatten1_margin[chain]; 1911 } 1912 } 1913 } 1914 return 0; 1915 } 1916 1917 #if 0 1918 HAL_BOOL ar9300_attenuation_apply(struct ath_hal *ah, u_int16_t channel) 1919 { 1920 u_int32_t value; 1921 // struct ath_hal_private *ahpriv = AH_PRIVATE(ah); 1922 1923 /* Test value. if 0 then attenuation is unused. Don't load anything. */ 1924 value = ar9300_attenuation_chain_get(ah, 0, channel); 1925 OS_REG_RMW_FIELD(ah, 1926 AR_PHY_EXT_ATTEN_CTL_0, AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value); 1927 value = ar9300_attenuation_margin_chain_get(ah, 0, channel); 1928 if (ar9300_rx_gain_index_get(ah) == 0 1929 && ah->ah_config.ath_hal_ext_atten_margin_cfg) 1930 { 1931 value = 5; 1932 } 1933 OS_REG_RMW_FIELD(ah, 1934 AR_PHY_EXT_ATTEN_CTL_0, AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN, value); 1935 1936 if (!AR_SREV_HORNET(ah) && !AR_SREV_POSEIDON(ah)) { 1937 value = ar9300_attenuation_chain_get(ah, 1, channel); 1938 OS_REG_RMW_FIELD(ah, 1939 AR_PHY_EXT_ATTEN_CTL_1, AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value); 1940 value = ar9300_attenuation_margin_chain_get(ah, 1, channel); 1941 OS_REG_RMW_FIELD(ah, 1942 AR_PHY_EXT_ATTEN_CTL_1, AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN, 1943 value); 1944 if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah)&& !AR_SREV_HONEYBEE(ah) ) { 1945 value = ar9300_attenuation_chain_get(ah, 2, channel); 1946 OS_REG_RMW_FIELD(ah, 1947 AR_PHY_EXT_ATTEN_CTL_2, AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value); 1948 value = ar9300_attenuation_margin_chain_get(ah, 2, channel); 1949 OS_REG_RMW_FIELD(ah, 1950 AR_PHY_EXT_ATTEN_CTL_2, AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN, 1951 value); 1952 } 1953 } 1954 return 0; 1955 } 1956 #endif 1957 HAL_BOOL 1958 ar9300_attenuation_apply(struct ath_hal *ah, u_int16_t channel) 1959 { 1960 int i; 1961 uint32_t value; 1962 uint32_t ext_atten_reg[3] = { 1963 AR_PHY_EXT_ATTEN_CTL_0, 1964 AR_PHY_EXT_ATTEN_CTL_1, 1965 AR_PHY_EXT_ATTEN_CTL_2 1966 }; 1967 1968 /* 1969 * If it's an AR9462 and we're receiving on the second 1970 * chain only, set the chain 0 details from chain 1 1971 * calibration. 1972 * 1973 * This is from ath9k. 1974 */ 1975 if (AR_SREV_JUPITER(ah) && (AH9300(ah)->ah_rx_chainmask == 0x2)) { 1976 value = ar9300_attenuation_chain_get(ah, 1, channel); 1977 OS_REG_RMW_FIELD(ah, ext_atten_reg[0], 1978 AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value); 1979 value = ar9300_attenuation_margin_chain_get(ah, 1, channel); 1980 OS_REG_RMW_FIELD(ah, ext_atten_reg[0], 1981 AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN, value); 1982 } 1983 1984 /* 1985 * Now, loop over the configured transmit chains and 1986 * load in the attenuation/margin settings as appropriate. 1987 */ 1988 for (i = 0; i < 3; i++) { 1989 if ((AH9300(ah)->ah_tx_chainmask & (1 << i)) == 0) 1990 continue; 1991 1992 value = ar9300_attenuation_chain_get(ah, i, channel); 1993 OS_REG_RMW_FIELD(ah, ext_atten_reg[i], 1994 AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, 1995 value); 1996 1997 if (AR_SREV_POSEIDON(ah) && 1998 (ar9300_rx_gain_index_get(ah) == 0) && 1999 ah->ah_config.ath_hal_ext_atten_margin_cfg) { 2000 value = 5; 2001 } else { 2002 value = ar9300_attenuation_margin_chain_get(ah, 0, 2003 channel); 2004 } 2005 2006 /* 2007 * I'm not sure why it's loading in this setting into 2008 * the chain 0 margin regardless of the current chain. 2009 */ 2010 if (ah->ah_config.ath_hal_min_gainidx) 2011 OS_REG_RMW_FIELD(ah, 2012 AR_PHY_EXT_ATTEN_CTL_0, 2013 AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN, 2014 value); 2015 2016 OS_REG_RMW_FIELD(ah, 2017 ext_atten_reg[i], 2018 AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN, 2019 value); 2020 } 2021 2022 return (0); 2023 } 2024 2025 2026 static u_int16_t ar9300_quick_drop_get(struct ath_hal *ah, 2027 int chain, u_int16_t channel) 2028 { 2029 int32_t f[3], t[3]; 2030 u_int16_t value; 2031 ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom; 2032 2033 if (channel < 4000) { 2034 return eep->modal_header_2g.quick_drop; 2035 } else { 2036 t[0] = eep->base_ext1.quick_drop_low; 2037 f[0] = 5180; 2038 t[1] = eep->modal_header_5g.quick_drop; 2039 f[1] = 5500; 2040 t[2] = eep->base_ext1.quick_drop_high; 2041 f[2] = 5785; 2042 value = interpolate(channel, f, t, 3); 2043 return value; 2044 } 2045 } 2046 2047 2048 static HAL_BOOL ar9300_quick_drop_apply(struct ath_hal *ah, u_int16_t channel) 2049 { 2050 ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom; 2051 u_int32_t value; 2052 // 2053 // Test value. if 0 then quickDrop is unused. Don't load anything. 2054 // 2055 if (eep->base_eep_header.misc_configuration & 0x10) 2056 { 2057 if (AR_SREV_OSPREY(ah) || AR_SREV_AR9580(ah) || AR_SREV_WASP(ah)) 2058 { 2059 value = ar9300_quick_drop_get(ah, 0, channel); 2060 OS_REG_RMW_FIELD(ah, AR_PHY_AGC, AR_PHY_AGC_QUICK_DROP, value); 2061 } 2062 } 2063 return 0; 2064 } 2065 2066 static u_int16_t ar9300_tx_end_to_xpa_off_get(struct ath_hal *ah, u_int16_t channel) 2067 { 2068 ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom; 2069 2070 if (channel < 4000) { 2071 return eep->modal_header_2g.tx_end_to_xpa_off; 2072 } else { 2073 return eep->modal_header_5g.tx_end_to_xpa_off; 2074 } 2075 } 2076 2077 static HAL_BOOL ar9300_tx_end_to_xpab_off_apply(struct ath_hal *ah, u_int16_t channel) 2078 { 2079 u_int32_t value; 2080 2081 value = ar9300_tx_end_to_xpa_off_get(ah, channel); 2082 /* Apply to both xpaa and xpab */ 2083 if (AR_SREV_OSPREY(ah) || AR_SREV_AR9580(ah) || AR_SREV_WASP(ah)) 2084 { 2085 OS_REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL, 2086 AR_PHY_XPA_TIMING_CTL_TX_END_XPAB_OFF, value); 2087 OS_REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL, 2088 AR_PHY_XPA_TIMING_CTL_TX_END_XPAA_OFF, value); 2089 } 2090 return 0; 2091 } 2092 2093 static int 2094 ar9300_eeprom_cal_pier_get(struct ath_hal *ah, int mode, int ipier, int ichain, 2095 int *pfrequency, int *pcorrection, int *ptemperature, int *pvoltage) 2096 { 2097 u_int8_t *p_cal_pier; 2098 OSP_CAL_DATA_PER_FREQ_OP_LOOP *p_cal_pier_struct; 2099 int is_2ghz; 2100 ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom; 2101 2102 if (ichain >= OSPREY_MAX_CHAINS) { 2103 HALDEBUG(ah, HAL_DEBUG_EEPROM, 2104 "%s: Invalid chain index, must be less than %d\n", 2105 __func__, OSPREY_MAX_CHAINS); 2106 return -1; 2107 } 2108 2109 if (mode) {/* 5GHz */ 2110 if (ipier >= OSPREY_NUM_5G_CAL_PIERS){ 2111 HALDEBUG(ah, HAL_DEBUG_EEPROM, 2112 "%s: Invalid 5GHz cal pier index, must be less than %d\n", 2113 __func__, OSPREY_NUM_5G_CAL_PIERS); 2114 return -1; 2115 } 2116 p_cal_pier = &(eep->cal_freq_pier_5g[ipier]); 2117 p_cal_pier_struct = &(eep->cal_pier_data_5g[ichain][ipier]); 2118 is_2ghz = 0; 2119 } else { 2120 if (ipier >= OSPREY_NUM_2G_CAL_PIERS){ 2121 HALDEBUG(ah, HAL_DEBUG_EEPROM, 2122 "%s: Invalid 2GHz cal pier index, must be less than %d\n", 2123 __func__, OSPREY_NUM_2G_CAL_PIERS); 2124 return -1; 2125 } 2126 2127 p_cal_pier = &(eep->cal_freq_pier_2g[ipier]); 2128 p_cal_pier_struct = &(eep->cal_pier_data_2g[ichain][ipier]); 2129 is_2ghz = 1; 2130 } 2131 *pfrequency = FBIN2FREQ(*p_cal_pier, is_2ghz); 2132 *pcorrection = p_cal_pier_struct->ref_power; 2133 *ptemperature = p_cal_pier_struct->temp_meas; 2134 *pvoltage = p_cal_pier_struct->volt_meas; 2135 return 0; 2136 } 2137 2138 /* 2139 * Apply the recorded correction values. 2140 */ 2141 static int 2142 ar9300_calibration_apply(struct ath_hal *ah, int frequency) 2143 { 2144 struct ath_hal_9300 *ahp = AH9300(ah); 2145 2146 int ichain, ipier, npier; 2147 int mode; 2148 int fdiff; 2149 int pfrequency, pcorrection, ptemperature, pvoltage; 2150 int bf, factor, plus; 2151 2152 int lfrequency[AR9300_MAX_CHAINS]; 2153 int hfrequency[AR9300_MAX_CHAINS]; 2154 2155 int lcorrection[AR9300_MAX_CHAINS]; 2156 int hcorrection[AR9300_MAX_CHAINS]; 2157 int correction[AR9300_MAX_CHAINS]; 2158 2159 int ltemperature[AR9300_MAX_CHAINS]; 2160 int htemperature[AR9300_MAX_CHAINS]; 2161 int temperature[AR9300_MAX_CHAINS]; 2162 2163 int lvoltage[AR9300_MAX_CHAINS]; 2164 int hvoltage[AR9300_MAX_CHAINS]; 2165 int voltage[AR9300_MAX_CHAINS]; 2166 2167 mode = (frequency >= 4000); 2168 npier = (mode) ? OSPREY_NUM_5G_CAL_PIERS : OSPREY_NUM_2G_CAL_PIERS; 2169 2170 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) { 2171 lfrequency[ichain] = 0; 2172 hfrequency[ichain] = 100000; 2173 } 2174 /* 2175 * identify best lower and higher frequency calibration measurement 2176 */ 2177 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) { 2178 for (ipier = 0; ipier < npier; ipier++) { 2179 if (ar9300_eeprom_cal_pier_get( 2180 ah, mode, ipier, ichain, 2181 &pfrequency, &pcorrection, &ptemperature, &pvoltage) == 0) 2182 { 2183 fdiff = frequency - pfrequency; 2184 /* 2185 * this measurement is higher than our desired frequency 2186 */ 2187 if (fdiff <= 0) { 2188 if (hfrequency[ichain] <= 0 || 2189 hfrequency[ichain] >= 100000 || 2190 fdiff > (frequency - hfrequency[ichain])) 2191 { 2192 /* 2193 * new best higher frequency measurement 2194 */ 2195 hfrequency[ichain] = pfrequency; 2196 hcorrection[ichain] = pcorrection; 2197 htemperature[ichain] = ptemperature; 2198 hvoltage[ichain] = pvoltage; 2199 } 2200 } 2201 if (fdiff >= 0) { 2202 if (lfrequency[ichain] <= 0 || 2203 fdiff < (frequency - lfrequency[ichain])) 2204 { 2205 /* 2206 * new best lower frequency measurement 2207 */ 2208 lfrequency[ichain] = pfrequency; 2209 lcorrection[ichain] = pcorrection; 2210 ltemperature[ichain] = ptemperature; 2211 lvoltage[ichain] = pvoltage; 2212 } 2213 } 2214 } 2215 } 2216 } 2217 /* interpolate */ 2218 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) { 2219 HALDEBUG(ah, HAL_DEBUG_EEPROM, 2220 "%s: ch=%d f=%d low=%d %d h=%d %d\n", 2221 __func__, ichain, frequency, 2222 lfrequency[ichain], lcorrection[ichain], 2223 hfrequency[ichain], hcorrection[ichain]); 2224 /* 2225 * they're the same, so just pick one 2226 */ 2227 if (hfrequency[ichain] == lfrequency[ichain]) { 2228 correction[ichain] = lcorrection[ichain]; 2229 voltage[ichain] = lvoltage[ichain]; 2230 temperature[ichain] = ltemperature[ichain]; 2231 } else if (frequency - lfrequency[ichain] < 1000) { 2232 /* the low frequency is good */ 2233 if (hfrequency[ichain] - frequency < 1000) { 2234 /* 2235 * The high frequency is good too - 2236 * interpolate with round off. 2237 */ 2238 int mult, div, diff; 2239 mult = frequency - lfrequency[ichain]; 2240 div = hfrequency[ichain] - lfrequency[ichain]; 2241 2242 diff = hcorrection[ichain] - lcorrection[ichain]; 2243 bf = 2 * diff * mult / div; 2244 plus = (bf % 2); 2245 factor = bf / 2; 2246 correction[ichain] = lcorrection[ichain] + factor + plus; 2247 2248 diff = htemperature[ichain] - ltemperature[ichain]; 2249 bf = 2 * diff * mult / div; 2250 plus = (bf % 2); 2251 factor = bf / 2; 2252 temperature[ichain] = ltemperature[ichain] + factor + plus; 2253 2254 diff = hvoltage[ichain] - lvoltage[ichain]; 2255 bf = 2 * diff * mult / div; 2256 plus = (bf % 2); 2257 factor = bf / 2; 2258 voltage[ichain] = lvoltage[ichain] + factor + plus; 2259 } else { 2260 /* only low is good, use it */ 2261 correction[ichain] = lcorrection[ichain]; 2262 temperature[ichain] = ltemperature[ichain]; 2263 voltage[ichain] = lvoltage[ichain]; 2264 } 2265 } else if (hfrequency[ichain] - frequency < 1000) { 2266 /* only high is good, use it */ 2267 correction[ichain] = hcorrection[ichain]; 2268 temperature[ichain] = htemperature[ichain]; 2269 voltage[ichain] = hvoltage[ichain]; 2270 } else { 2271 /* nothing is good, presume 0???? */ 2272 correction[ichain] = 0; 2273 temperature[ichain] = 0; 2274 voltage[ichain] = 0; 2275 } 2276 } 2277 2278 /* GreenTx isn't currently supported */ 2279 /* GreenTx */ 2280 if (ah->ah_config.ath_hal_sta_update_tx_pwr_enable) { 2281 if (AR_SREV_POSEIDON(ah)) { 2282 /* Get calibrated OLPC gain delta value for GreenTx */ 2283 ahp->ah_db2[POSEIDON_STORED_REG_G2_OLPC_OFFSET] = 2284 (u_int32_t) correction[0]; 2285 } 2286 } 2287 2288 ar9300_power_control_override( 2289 ah, frequency, correction, voltage, temperature); 2290 HALDEBUG(ah, HAL_DEBUG_EEPROM, 2291 "%s: for frequency=%d, calibration correction = %d %d %d\n", 2292 __func__, frequency, correction[0], correction[1], correction[2]); 2293 2294 return 0; 2295 } 2296 2297 int 2298 ar9300_power_control_override(struct ath_hal *ah, int frequency, 2299 int *correction, int *voltage, int *temperature) 2300 { 2301 int temp_slope = 0; 2302 int temp_slope_1 = 0; 2303 int temp_slope_2 = 0; 2304 ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom; 2305 int32_t f[8], t[8],t1[3], t2[3]; 2306 int i; 2307 2308 OS_REG_RMW(ah, AR_PHY_TPC_11_B0, 2309 (correction[0] << AR_PHY_TPC_OLPC_GAIN_DELTA_S), 2310 AR_PHY_TPC_OLPC_GAIN_DELTA); 2311 if (!AR_SREV_POSEIDON(ah)) { 2312 OS_REG_RMW(ah, AR_PHY_TPC_11_B1, 2313 (correction[1] << AR_PHY_TPC_OLPC_GAIN_DELTA_S), 2314 AR_PHY_TPC_OLPC_GAIN_DELTA); 2315 if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah) && !AR_SREV_HONEYBEE(ah) ) { 2316 OS_REG_RMW(ah, AR_PHY_TPC_11_B2, 2317 (correction[2] << AR_PHY_TPC_OLPC_GAIN_DELTA_S), 2318 AR_PHY_TPC_OLPC_GAIN_DELTA); 2319 } 2320 } 2321 /* 2322 * enable open loop power control on chip 2323 */ 2324 OS_REG_RMW(ah, AR_PHY_TPC_6_B0, 2325 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S), AR_PHY_TPC_6_ERROR_EST_MODE); 2326 if (!AR_SREV_POSEIDON(ah)) { 2327 OS_REG_RMW(ah, AR_PHY_TPC_6_B1, 2328 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S), AR_PHY_TPC_6_ERROR_EST_MODE); 2329 if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah) && !AR_SREV_HONEYBEE(ah) ) { 2330 OS_REG_RMW(ah, AR_PHY_TPC_6_B2, 2331 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S), 2332 AR_PHY_TPC_6_ERROR_EST_MODE); 2333 } 2334 } 2335 2336 /* 2337 * Enable temperature compensation 2338 * Need to use register names 2339 */ 2340 if (frequency < 4000) { 2341 temp_slope = eep->modal_header_2g.temp_slope; 2342 } else { 2343 if ((eep->base_eep_header.misc_configuration & 0x20) != 0) 2344 { 2345 for(i=0;i<8;i++) 2346 { 2347 t[i]=eep->base_ext1.tempslopextension[i]; 2348 f[i]=FBIN2FREQ(eep->cal_freq_pier_5g[i], 0); 2349 } 2350 temp_slope=interpolate(frequency,f,t,8); 2351 } 2352 else 2353 { 2354 if(!AR_SREV_SCORPION(ah)) { 2355 if (eep->base_ext2.temp_slope_low != 0) { 2356 t[0] = eep->base_ext2.temp_slope_low; 2357 f[0] = 5180; 2358 t[1] = eep->modal_header_5g.temp_slope; 2359 f[1] = 5500; 2360 t[2] = eep->base_ext2.temp_slope_high; 2361 f[2] = 5785; 2362 temp_slope = interpolate(frequency, f, t, 3); 2363 } else { 2364 temp_slope = eep->modal_header_5g.temp_slope; 2365 } 2366 } else { 2367 /* 2368 * Scorpion has individual chain tempslope values 2369 */ 2370 t[0] = eep->base_ext1.tempslopextension[2]; 2371 t1[0]= eep->base_ext1.tempslopextension[3]; 2372 t2[0]= eep->base_ext1.tempslopextension[4]; 2373 f[0] = 5180; 2374 t[1] = eep->modal_header_5g.temp_slope; 2375 t1[1]= eep->base_ext1.tempslopextension[0]; 2376 t2[1]= eep->base_ext1.tempslopextension[1]; 2377 f[1] = 5500; 2378 t[2] = eep->base_ext1.tempslopextension[5]; 2379 t1[2]= eep->base_ext1.tempslopextension[6]; 2380 t2[2]= eep->base_ext1.tempslopextension[7]; 2381 f[2] = 5785; 2382 temp_slope = interpolate(frequency, f, t, 3); 2383 temp_slope_1=interpolate(frequency, f, t1,3); 2384 temp_slope_2=interpolate(frequency, f, t2,3); 2385 } 2386 } 2387 } 2388 2389 if (!AR_SREV_SCORPION(ah) && !AR_SREV_HONEYBEE(ah)) { 2390 OS_REG_RMW_FIELD(ah, 2391 AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, temp_slope); 2392 } else { 2393 /*Scorpion and Honeybee has tempSlope register for each chain*/ 2394 /*Check whether temp_compensation feature is enabled or not*/ 2395 if (eep->base_eep_header.feature_enable & 0x1){ 2396 if(frequency < 4000) { 2397 if (((eep->base_eep_header.txrx_mask & 0xf0) >> 4) & 0x1) { 2398 OS_REG_RMW_FIELD(ah, 2399 AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, 2400 eep->base_ext2.temp_slope_low); 2401 } 2402 if (((eep->base_eep_header.txrx_mask & 0xf0) >> 4) & 0x2) { 2403 OS_REG_RMW_FIELD(ah, 2404 AR_SCORPION_PHY_TPC_19_B1, AR_PHY_TPC_19_ALPHA_THERM, 2405 temp_slope); 2406 } 2407 if (((eep->base_eep_header.txrx_mask & 0xf0) >> 4) & 0x4) { 2408 OS_REG_RMW_FIELD(ah, 2409 AR_SCORPION_PHY_TPC_19_B2, AR_PHY_TPC_19_ALPHA_THERM, 2410 eep->base_ext2.temp_slope_high); 2411 } 2412 } else { 2413 if (((eep->base_eep_header.txrx_mask & 0xf0) >> 4) & 0x1) { 2414 OS_REG_RMW_FIELD(ah, 2415 AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, 2416 temp_slope); 2417 } 2418 if (((eep->base_eep_header.txrx_mask & 0xf0) >> 4) & 0x2) { 2419 OS_REG_RMW_FIELD(ah, 2420 AR_SCORPION_PHY_TPC_19_B1, AR_PHY_TPC_19_ALPHA_THERM, 2421 temp_slope_1); 2422 } 2423 if (((eep->base_eep_header.txrx_mask & 0xf0) >> 4) & 0x4) { 2424 OS_REG_RMW_FIELD(ah, 2425 AR_SCORPION_PHY_TPC_19_B2, AR_PHY_TPC_19_ALPHA_THERM, 2426 temp_slope_2); 2427 } 2428 } 2429 }else { 2430 /* If temp compensation is not enabled, set all registers to 0*/ 2431 if (((eep->base_eep_header.txrx_mask & 0xf0) >> 4) & 0x1) { 2432 OS_REG_RMW_FIELD(ah, 2433 AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, 0); 2434 } 2435 if (((eep->base_eep_header.txrx_mask & 0xf0) >> 4) & 0x2) { 2436 OS_REG_RMW_FIELD(ah, 2437 AR_SCORPION_PHY_TPC_19_B1, AR_PHY_TPC_19_ALPHA_THERM, 0); 2438 } 2439 if (((eep->base_eep_header.txrx_mask & 0xf0) >> 4) & 0x4) { 2440 OS_REG_RMW_FIELD(ah, 2441 AR_SCORPION_PHY_TPC_19_B2, AR_PHY_TPC_19_ALPHA_THERM, 0); 2442 } 2443 } 2444 } 2445 OS_REG_RMW_FIELD(ah, 2446 AR_PHY_TPC_18, AR_PHY_TPC_18_THERM_CAL_VALUE, temperature[0]); 2447 2448 return 0; 2449 } 2450 2451 /************************************************************** 2452 * ar9300_eep_def_get_max_edge_power 2453 * 2454 * Find the maximum conformance test limit for the given channel and CTL info 2455 */ 2456 static inline u_int16_t 2457 ar9300_eep_def_get_max_edge_power(ar9300_eeprom_t *p_eep_data, u_int16_t freq, 2458 int idx, HAL_BOOL is_2ghz) 2459 { 2460 u_int16_t twice_max_edge_power = AR9300_MAX_RATE_POWER; 2461 u_int8_t *ctl_freqbin = is_2ghz ? 2462 &p_eep_data->ctl_freqbin_2G[idx][0] : 2463 &p_eep_data->ctl_freqbin_5G[idx][0]; 2464 u_int16_t num_edges = is_2ghz ? 2465 OSPREY_NUM_BAND_EDGES_2G : OSPREY_NUM_BAND_EDGES_5G; 2466 int i; 2467 2468 /* Get the edge power */ 2469 for (i = 0; (i < num_edges) && (ctl_freqbin[i] != AR9300_BCHAN_UNUSED); i++) 2470 { 2471 /* 2472 * If there's an exact channel match or an inband flag set 2473 * on the lower channel use the given rd_edge_power 2474 */ 2475 if (freq == fbin2freq(ctl_freqbin[i], is_2ghz)) { 2476 if (is_2ghz) { 2477 twice_max_edge_power = 2478 p_eep_data->ctl_power_data_2g[idx].ctl_edges[i].t_power; 2479 } else { 2480 twice_max_edge_power = 2481 p_eep_data->ctl_power_data_5g[idx].ctl_edges[i].t_power; 2482 } 2483 break; 2484 } else if ((i > 0) && (freq < fbin2freq(ctl_freqbin[i], is_2ghz))) { 2485 if (is_2ghz) { 2486 if (fbin2freq(ctl_freqbin[i - 1], 1) < freq && 2487 p_eep_data->ctl_power_data_2g[idx].ctl_edges[i - 1].flag) 2488 { 2489 twice_max_edge_power = 2490 p_eep_data->ctl_power_data_2g[idx]. 2491 ctl_edges[i - 1].t_power; 2492 } 2493 } else { 2494 if (fbin2freq(ctl_freqbin[i - 1], 0) < freq && 2495 p_eep_data->ctl_power_data_5g[idx].ctl_edges[i - 1].flag) 2496 { 2497 twice_max_edge_power = 2498 p_eep_data->ctl_power_data_5g[idx]. 2499 ctl_edges[i - 1].t_power; 2500 } 2501 } 2502 /* 2503 * Leave loop - no more affecting edges possible 2504 * in this monotonic increasing list 2505 */ 2506 break; 2507 } 2508 } 2509 /* 2510 * EV89475: EEPROM might contain 0 txpower in CTL table for certain 2511 * 2.4GHz channels. We workaround it by overwriting 60 (30 dBm) here. 2512 */ 2513 if (is_2ghz && (twice_max_edge_power == 0)) { 2514 twice_max_edge_power = 60; 2515 } 2516 2517 HALASSERT(twice_max_edge_power > 0); 2518 return twice_max_edge_power; 2519 } 2520 2521 HAL_BOOL 2522 ar9300_eeprom_set_power_per_rate_table( 2523 struct ath_hal *ah, 2524 ar9300_eeprom_t *p_eep_data, 2525 const struct ieee80211_channel *chan, 2526 u_int8_t *p_pwr_array, 2527 u_int16_t cfg_ctl, 2528 u_int16_t antenna_reduction, 2529 u_int16_t twice_max_regulatory_power, 2530 u_int16_t power_limit, 2531 u_int8_t chainmask) 2532 { 2533 /* Local defines to distinguish between extension and control CTL's */ 2534 #define EXT_ADDITIVE (0x8000) 2535 #define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE) 2536 #define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE) 2537 #define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE) 2538 #define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */ 2539 #define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10 /* 10*log10(3)*2 */ 2540 #define PWRINCR_3_TO_1_CHAIN 9 /* 10*log(3)*2 */ 2541 #define PWRINCR_3_TO_2_CHAIN 3 /* floor(10*log(3/2)*2) */ 2542 #define PWRINCR_2_TO_1_CHAIN 6 /* 10*log(2)*2 */ 2543 2544 static const u_int16_t tp_scale_reduction_table[5] = 2545 { 0, 3, 6, 9, AR9300_MAX_RATE_POWER }; 2546 int i; 2547 int16_t twice_largest_antenna; 2548 u_int16_t twice_antenna_reduction = 2*antenna_reduction ; 2549 int16_t scaled_power = 0, min_ctl_power, max_reg_allowed_power; 2550 #define SUB_NUM_CTL_MODES_AT_5G_40 2 /* excluding HT40, EXT-OFDM */ 2551 #define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */ 2552 u_int16_t ctl_modes_for11a[] = 2553 {CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40}; 2554 u_int16_t ctl_modes_for11g[] = 2555 {CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40}; 2556 u_int16_t num_ctl_modes, *p_ctl_mode, ctl_mode, freq; 2557 CHAN_CENTERS centers; 2558 int tx_chainmask; 2559 struct ath_hal_9300 *ahp = AH9300(ah); 2560 u_int8_t *ctl_index; 2561 u_int8_t ctl_num; 2562 u_int16_t twice_min_edge_power; 2563 u_int16_t twice_max_edge_power = AR9300_MAX_RATE_POWER; 2564 #ifdef AH_DEBUG 2565 HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan); 2566 #endif 2567 2568 if (chainmask) 2569 tx_chainmask = chainmask; 2570 else 2571 tx_chainmask = ahp->ah_tx_chainmaskopt ? 2572 ahp->ah_tx_chainmaskopt :ahp->ah_tx_chainmask; 2573 2574 ar9300_get_channel_centers(ah, chan, ¢ers); 2575 2576 #if 1 2577 if (IEEE80211_IS_CHAN_2GHZ(chan)) { 2578 ahp->twice_antenna_gain = p_eep_data->modal_header_2g.antenna_gain; 2579 } else { 2580 ahp->twice_antenna_gain = p_eep_data->modal_header_5g.antenna_gain; 2581 } 2582 2583 #else 2584 if (IEEE80211_IS_CHAN_2GHZ(chan)) { 2585 ahp->twice_antenna_gain = AH_MAX(p_eep_data->modal_header_2g.antenna_gain, 2586 AH_PRIVATE(ah)->ah_antenna_gain_2g); 2587 } else { 2588 ahp->twice_antenna_gain = AH_MAX(p_eep_data->modal_header_5g.antenna_gain, 2589 AH_PRIVATE(ah)->ah_antenna_gain_5g); 2590 } 2591 #endif 2592 2593 /* Save max allowed antenna gain to ease future lookups */ 2594 ahp->twice_antenna_reduction = twice_antenna_reduction; 2595 2596 /* Deduct antenna gain from EIRP to get the upper limit */ 2597 twice_largest_antenna = (int16_t)AH_MIN((twice_antenna_reduction - 2598 ahp->twice_antenna_gain), 0); 2599 max_reg_allowed_power = twice_max_regulatory_power + twice_largest_antenna; 2600 2601 /* Use ah_tp_scale - see bug 30070. */ 2602 if (AH_PRIVATE(ah)->ah_tpScale != HAL_TP_SCALE_MAX) { 2603 max_reg_allowed_power -= 2604 (tp_scale_reduction_table[(AH_PRIVATE(ah)->ah_tpScale)] * 2); 2605 } 2606 2607 scaled_power = AH_MIN(power_limit, max_reg_allowed_power); 2608 2609 /* 2610 * Reduce scaled Power by number of chains active to get to 2611 * per chain tx power level 2612 */ 2613 /* TODO: better value than these? */ 2614 switch (ar9300_get_ntxchains(tx_chainmask)) { 2615 case 1: 2616 ahp->upper_limit[0] = AH_MAX(0, scaled_power); 2617 break; 2618 case 2: 2619 scaled_power -= REDUCE_SCALED_POWER_BY_TWO_CHAIN; 2620 ahp->upper_limit[1] = AH_MAX(0, scaled_power); 2621 break; 2622 case 3: 2623 scaled_power -= REDUCE_SCALED_POWER_BY_THREE_CHAIN; 2624 ahp->upper_limit[2] = AH_MAX(0, scaled_power); 2625 break; 2626 default: 2627 HALASSERT(0); /* Unsupported number of chains */ 2628 } 2629 2630 scaled_power = AH_MAX(0, scaled_power); 2631 2632 /* Get target powers from EEPROM - our baseline for TX Power */ 2633 if (IEEE80211_IS_CHAN_2GHZ(chan)) { 2634 /* Setup for CTL modes */ 2635 /* CTL_11B, CTL_11G, CTL_2GHT20 */ 2636 num_ctl_modes = 2637 ARRAY_LENGTH(ctl_modes_for11g) - SUB_NUM_CTL_MODES_AT_2G_40; 2638 p_ctl_mode = ctl_modes_for11g; 2639 2640 if (IEEE80211_IS_CHAN_HT40(chan)) { 2641 num_ctl_modes = ARRAY_LENGTH(ctl_modes_for11g); /* All 2G CTL's */ 2642 } 2643 } else { 2644 /* Setup for CTL modes */ 2645 /* CTL_11A, CTL_5GHT20 */ 2646 num_ctl_modes = 2647 ARRAY_LENGTH(ctl_modes_for11a) - SUB_NUM_CTL_MODES_AT_5G_40; 2648 p_ctl_mode = ctl_modes_for11a; 2649 2650 if (IEEE80211_IS_CHAN_HT40(chan)) { 2651 num_ctl_modes = ARRAY_LENGTH(ctl_modes_for11a); /* All 5G CTL's */ 2652 } 2653 } 2654 2655 /* 2656 * For MIMO, need to apply regulatory caps individually across dynamically 2657 * running modes: CCK, OFDM, HT20, HT40 2658 * 2659 * The outer loop walks through each possible applicable runtime mode. 2660 * The inner loop walks through each ctl_index entry in EEPROM. 2661 * The ctl value is encoded as [7:4] == test group, [3:0] == test mode. 2662 * 2663 */ 2664 for (ctl_mode = 0; ctl_mode < num_ctl_modes; ctl_mode++) { 2665 HAL_BOOL is_ht40_ctl_mode = 2666 (p_ctl_mode[ctl_mode] == CTL_5GHT40) || 2667 (p_ctl_mode[ctl_mode] == CTL_2GHT40); 2668 if (is_ht40_ctl_mode) { 2669 freq = centers.synth_center; 2670 } else if (p_ctl_mode[ctl_mode] & EXT_ADDITIVE) { 2671 freq = centers.ext_center; 2672 } else { 2673 freq = centers.ctl_center; 2674 } 2675 2676 HALDEBUG(ah, HAL_DEBUG_POWER_MGMT, 2677 "LOOP-Mode ctl_mode %d < %d, " 2678 "is_ht40_ctl_mode %d, EXT_ADDITIVE %d\n", 2679 ctl_mode, num_ctl_modes, is_ht40_ctl_mode, 2680 (p_ctl_mode[ctl_mode] & EXT_ADDITIVE)); 2681 /* walk through each CTL index stored in EEPROM */ 2682 if (IEEE80211_IS_CHAN_2GHZ(chan)) { 2683 ctl_index = p_eep_data->ctl_index_2g; 2684 ctl_num = OSPREY_NUM_CTLS_2G; 2685 } else { 2686 ctl_index = p_eep_data->ctl_index_5g; 2687 ctl_num = OSPREY_NUM_CTLS_5G; 2688 } 2689 2690 for (i = 0; (i < ctl_num) && ctl_index[i]; i++) { 2691 HALDEBUG(ah, HAL_DEBUG_POWER_MGMT, 2692 " LOOP-Ctlidx %d: cfg_ctl 0x%2.2x p_ctl_mode 0x%2.2x " 2693 "ctl_index 0x%2.2x chan %d chanctl 0x%x\n", 2694 i, cfg_ctl, p_ctl_mode[ctl_mode], ctl_index[i], 2695 ichan->channel, ath_hal_getctl(ah, chan)); 2696 2697 2698 /* 2699 * compare test group from regulatory channel list 2700 * with test mode from p_ctl_mode list 2701 */ 2702 if ((((cfg_ctl & ~CTL_MODE_M) | 2703 (p_ctl_mode[ctl_mode] & CTL_MODE_M)) == ctl_index[i]) || 2704 (((cfg_ctl & ~CTL_MODE_M) | 2705 (p_ctl_mode[ctl_mode] & CTL_MODE_M)) == 2706 ((ctl_index[i] & CTL_MODE_M) | SD_NO_CTL))) 2707 { 2708 twice_min_edge_power = 2709 ar9300_eep_def_get_max_edge_power( 2710 p_eep_data, freq, i, IEEE80211_IS_CHAN_2GHZ(chan)); 2711 2712 HALDEBUG(ah, HAL_DEBUG_POWER_MGMT, 2713 " MATCH-EE_IDX %d: ch %d is2 %d " 2714 "2xMinEdge %d chainmask %d chains %d\n", 2715 i, freq, IEEE80211_IS_CHAN_2GHZ(chan), 2716 twice_min_edge_power, tx_chainmask, 2717 ar9300_get_ntxchains(tx_chainmask)); 2718 2719 if ((cfg_ctl & ~CTL_MODE_M) == SD_NO_CTL) { 2720 /* 2721 * Find the minimum of all CTL edge powers 2722 * that apply to this channel 2723 */ 2724 twice_max_edge_power = 2725 AH_MIN(twice_max_edge_power, twice_min_edge_power); 2726 } else { 2727 /* specific */ 2728 twice_max_edge_power = twice_min_edge_power; 2729 break; 2730 } 2731 } 2732 } 2733 2734 min_ctl_power = (u_int8_t)AH_MIN(twice_max_edge_power, scaled_power); 2735 2736 HALDEBUG(ah, HAL_DEBUG_POWER_MGMT, 2737 " SEL-Min ctl_mode %d p_ctl_mode %d " 2738 "2xMaxEdge %d sP %d min_ctl_pwr %d\n", 2739 ctl_mode, p_ctl_mode[ctl_mode], 2740 twice_max_edge_power, scaled_power, min_ctl_power); 2741 2742 /* Apply ctl mode to correct target power set */ 2743 switch (p_ctl_mode[ctl_mode]) { 2744 case CTL_11B: 2745 for (i = ALL_TARGET_LEGACY_1L_5L; i <= ALL_TARGET_LEGACY_11S; i++) { 2746 p_pwr_array[i] = 2747 (u_int8_t)AH_MIN(p_pwr_array[i], min_ctl_power); 2748 } 2749 break; 2750 case CTL_11A: 2751 case CTL_11G: 2752 for (i = ALL_TARGET_LEGACY_6_24; i <= ALL_TARGET_LEGACY_54; i++) { 2753 p_pwr_array[i] = 2754 (u_int8_t)AH_MIN(p_pwr_array[i], min_ctl_power); 2755 #ifdef ATH_BT_COEX 2756 if ((ahp->ah_bt_coex_config_type == HAL_BT_COEX_CFG_3WIRE) || 2757 (ahp->ah_bt_coex_config_type == HAL_BT_COEX_CFG_MCI)) 2758 { 2759 if ((ahp->ah_bt_coex_flag & HAL_BT_COEX_FLAG_LOWER_TX_PWR) 2760 && (ahp->ah_bt_wlan_isolation 2761 < HAL_BT_COEX_ISOLATION_FOR_NO_COEX)) 2762 { 2763 2764 u_int8_t reduce_pow; 2765 2766 reduce_pow = (HAL_BT_COEX_ISOLATION_FOR_NO_COEX 2767 - ahp->ah_bt_wlan_isolation) << 1; 2768 2769 if (reduce_pow <= p_pwr_array[i]) { 2770 p_pwr_array[i] -= reduce_pow; 2771 } 2772 } 2773 if ((ahp->ah_bt_coex_flag & 2774 HAL_BT_COEX_FLAG_LOW_ACK_PWR) && 2775 (i != ALL_TARGET_LEGACY_36) && 2776 (i != ALL_TARGET_LEGACY_48) && 2777 (i != ALL_TARGET_LEGACY_54) && 2778 (p_ctl_mode[ctl_mode] == CTL_11G)) 2779 { 2780 p_pwr_array[i] = 0; 2781 } 2782 } 2783 #endif 2784 } 2785 break; 2786 case CTL_5GHT20: 2787 case CTL_2GHT20: 2788 for (i = ALL_TARGET_HT20_0_8_16; i <= ALL_TARGET_HT20_23; i++) { 2789 p_pwr_array[i] = 2790 (u_int8_t)AH_MIN(p_pwr_array[i], min_ctl_power); 2791 #ifdef ATH_BT_COEX 2792 if (((ahp->ah_bt_coex_config_type == HAL_BT_COEX_CFG_3WIRE) || 2793 (ahp->ah_bt_coex_config_type == HAL_BT_COEX_CFG_MCI)) && 2794 (ahp->ah_bt_coex_flag & HAL_BT_COEX_FLAG_LOWER_TX_PWR) && 2795 (ahp->ah_bt_wlan_isolation 2796 < HAL_BT_COEX_ISOLATION_FOR_NO_COEX)) { 2797 2798 u_int8_t reduce_pow = (HAL_BT_COEX_ISOLATION_FOR_NO_COEX 2799 - ahp->ah_bt_wlan_isolation) << 1; 2800 2801 if (reduce_pow <= p_pwr_array[i]) { 2802 p_pwr_array[i] -= reduce_pow; 2803 } 2804 } 2805 #if ATH_SUPPORT_MCI 2806 else if ((ahp->ah_bt_coex_flag & 2807 HAL_BT_COEX_FLAG_MCI_MAX_TX_PWR) && 2808 (p_ctl_mode[ctl_mode] == CTL_2GHT20) && 2809 (ahp->ah_bt_coex_config_type == HAL_BT_COEX_CFG_MCI)) 2810 { 2811 u_int8_t max_pwr; 2812 2813 max_pwr = MS(mci_concur_tx_max_pwr[2][1], 2814 ATH_MCI_CONCUR_TX_LOWEST_PWR_MASK); 2815 if (p_pwr_array[i] > max_pwr) { 2816 p_pwr_array[i] = max_pwr; 2817 } 2818 } 2819 #endif 2820 #endif 2821 } 2822 break; 2823 case CTL_11B_EXT: 2824 #ifdef NOT_YET 2825 target_power_cck_ext.t_pow2x[0] = (u_int8_t) 2826 AH_MIN(target_power_cck_ext.t_pow2x[0], min_ctl_power); 2827 #endif /* NOT_YET */ 2828 break; 2829 case CTL_11A_EXT: 2830 case CTL_11G_EXT: 2831 #ifdef NOT_YET 2832 target_power_ofdm_ext.t_pow2x[0] = (u_int8_t) 2833 AH_MIN(target_power_ofdm_ext.t_pow2x[0], min_ctl_power); 2834 #endif /* NOT_YET */ 2835 break; 2836 case CTL_5GHT40: 2837 case CTL_2GHT40: 2838 for (i = ALL_TARGET_HT40_0_8_16; i <= ALL_TARGET_HT40_23; i++) { 2839 p_pwr_array[i] = (u_int8_t) 2840 AH_MIN(p_pwr_array[i], min_ctl_power); 2841 #ifdef ATH_BT_COEX 2842 if (((ahp->ah_bt_coex_config_type == HAL_BT_COEX_CFG_3WIRE) || 2843 (ahp->ah_bt_coex_config_type == HAL_BT_COEX_CFG_MCI)) && 2844 (ahp->ah_bt_coex_flag & HAL_BT_COEX_FLAG_LOWER_TX_PWR) && 2845 (ahp->ah_bt_wlan_isolation 2846 < HAL_BT_COEX_ISOLATION_FOR_NO_COEX)) { 2847 2848 u_int8_t reduce_pow = (HAL_BT_COEX_ISOLATION_FOR_NO_COEX 2849 - ahp->ah_bt_wlan_isolation) << 1; 2850 2851 if (reduce_pow <= p_pwr_array[i]) { 2852 p_pwr_array[i] -= reduce_pow; 2853 } 2854 } 2855 #if ATH_SUPPORT_MCI 2856 else if ((ahp->ah_bt_coex_flag & 2857 HAL_BT_COEX_FLAG_MCI_MAX_TX_PWR) && 2858 (p_ctl_mode[ctl_mode] == CTL_2GHT40) && 2859 (ahp->ah_bt_coex_config_type == HAL_BT_COEX_CFG_MCI)) 2860 { 2861 u_int8_t max_pwr; 2862 2863 max_pwr = MS(mci_concur_tx_max_pwr[3][1], 2864 ATH_MCI_CONCUR_TX_LOWEST_PWR_MASK); 2865 if (p_pwr_array[i] > max_pwr) { 2866 p_pwr_array[i] = max_pwr; 2867 } 2868 } 2869 #endif 2870 #endif 2871 } 2872 break; 2873 default: 2874 HALASSERT(0); 2875 break; 2876 } 2877 } /* end ctl mode checking */ 2878 2879 return AH_TRUE; 2880 #undef EXT_ADDITIVE 2881 #undef CTL_11A_EXT 2882 #undef CTL_11G_EXT 2883 #undef CTL_11B_EXT 2884 #undef REDUCE_SCALED_POWER_BY_TWO_CHAIN 2885 #undef REDUCE_SCALED_POWER_BY_THREE_CHAIN 2886 } 2887 2888 /************************************************************** 2889 * ar9300_eeprom_set_transmit_power 2890 * 2891 * Set the transmit power in the baseband for the given 2892 * operating channel and mode. 2893 */ 2894 HAL_STATUS 2895 ar9300_eeprom_set_transmit_power(struct ath_hal *ah, 2896 ar9300_eeprom_t *p_eep_data, const struct ieee80211_channel *chan, u_int16_t cfg_ctl, 2897 u_int16_t antenna_reduction, u_int16_t twice_max_regulatory_power, 2898 u_int16_t power_limit) 2899 { 2900 #define ABS(_x, _y) ((int)_x > (int)_y ? (int)_x - (int)_y : (int)_y - (int)_x) 2901 #define INCREASE_MAXPOW_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */ 2902 #define INCREASE_MAXPOW_BY_THREE_CHAIN 10 /* 10*log10(3)*2 */ 2903 u_int8_t target_power_val_t2[ar9300_rate_size]; 2904 u_int8_t target_power_val_t2_eep[ar9300_rate_size]; 2905 int16_t twice_array_gain = 0, max_power_level = 0; 2906 struct ath_hal_9300 *ahp = AH9300(ah); 2907 int i = 0; 2908 u_int32_t tmp_paprd_rate_mask = 0, *tmp_ptr = NULL; 2909 int paprd_scale_factor = 5; 2910 HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan); 2911 2912 u_int8_t *ptr_mcs_rate2power_table_index; 2913 u_int8_t mcs_rate2power_table_index_ht20[24] = 2914 { 2915 ALL_TARGET_HT20_0_8_16, 2916 ALL_TARGET_HT20_1_3_9_11_17_19, 2917 ALL_TARGET_HT20_1_3_9_11_17_19, 2918 ALL_TARGET_HT20_1_3_9_11_17_19, 2919 ALL_TARGET_HT20_4, 2920 ALL_TARGET_HT20_5, 2921 ALL_TARGET_HT20_6, 2922 ALL_TARGET_HT20_7, 2923 ALL_TARGET_HT20_0_8_16, 2924 ALL_TARGET_HT20_1_3_9_11_17_19, 2925 ALL_TARGET_HT20_1_3_9_11_17_19, 2926 ALL_TARGET_HT20_1_3_9_11_17_19, 2927 ALL_TARGET_HT20_12, 2928 ALL_TARGET_HT20_13, 2929 ALL_TARGET_HT20_14, 2930 ALL_TARGET_HT20_15, 2931 ALL_TARGET_HT20_0_8_16, 2932 ALL_TARGET_HT20_1_3_9_11_17_19, 2933 ALL_TARGET_HT20_1_3_9_11_17_19, 2934 ALL_TARGET_HT20_1_3_9_11_17_19, 2935 ALL_TARGET_HT20_20, 2936 ALL_TARGET_HT20_21, 2937 ALL_TARGET_HT20_22, 2938 ALL_TARGET_HT20_23 2939 }; 2940 2941 u_int8_t mcs_rate2power_table_index_ht40[24] = 2942 { 2943 ALL_TARGET_HT40_0_8_16, 2944 ALL_TARGET_HT40_1_3_9_11_17_19, 2945 ALL_TARGET_HT40_1_3_9_11_17_19, 2946 ALL_TARGET_HT40_1_3_9_11_17_19, 2947 ALL_TARGET_HT40_4, 2948 ALL_TARGET_HT40_5, 2949 ALL_TARGET_HT40_6, 2950 ALL_TARGET_HT40_7, 2951 ALL_TARGET_HT40_0_8_16, 2952 ALL_TARGET_HT40_1_3_9_11_17_19, 2953 ALL_TARGET_HT40_1_3_9_11_17_19, 2954 ALL_TARGET_HT40_1_3_9_11_17_19, 2955 ALL_TARGET_HT40_12, 2956 ALL_TARGET_HT40_13, 2957 ALL_TARGET_HT40_14, 2958 ALL_TARGET_HT40_15, 2959 ALL_TARGET_HT40_0_8_16, 2960 ALL_TARGET_HT40_1_3_9_11_17_19, 2961 ALL_TARGET_HT40_1_3_9_11_17_19, 2962 ALL_TARGET_HT40_1_3_9_11_17_19, 2963 ALL_TARGET_HT40_20, 2964 ALL_TARGET_HT40_21, 2965 ALL_TARGET_HT40_22, 2966 ALL_TARGET_HT40_23, 2967 }; 2968 2969 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 2970 "%s[%d] +++chan %d,cfgctl 0x%04x " 2971 "antenna_reduction 0x%04x, twice_max_regulatory_power 0x%04x " 2972 "power_limit 0x%04x\n", 2973 __func__, __LINE__, ichan->channel, cfg_ctl, 2974 antenna_reduction, twice_max_regulatory_power, power_limit); 2975 ar9300_set_target_power_from_eeprom(ah, ichan->channel, target_power_val_t2); 2976 2977 if (ar9300_eeprom_get(ahp, EEP_PAPRD_ENABLED)) { 2978 if (IEEE80211_IS_CHAN_2GHZ(chan)) { 2979 if (IEEE80211_IS_CHAN_HT40(chan)) { 2980 tmp_paprd_rate_mask = 2981 p_eep_data->modal_header_2g.paprd_rate_mask_ht40; 2982 tmp_ptr = &AH9300(ah)->ah_2g_paprd_rate_mask_ht40; 2983 } else { 2984 tmp_paprd_rate_mask = 2985 p_eep_data->modal_header_2g.paprd_rate_mask_ht20; 2986 tmp_ptr = &AH9300(ah)->ah_2g_paprd_rate_mask_ht20; 2987 } 2988 } else { 2989 if (IEEE80211_IS_CHAN_HT40(chan)) { 2990 tmp_paprd_rate_mask = 2991 p_eep_data->modal_header_5g.paprd_rate_mask_ht40; 2992 tmp_ptr = &AH9300(ah)->ah_5g_paprd_rate_mask_ht40; 2993 } else { 2994 tmp_paprd_rate_mask = 2995 p_eep_data->modal_header_5g.paprd_rate_mask_ht20; 2996 tmp_ptr = &AH9300(ah)->ah_5g_paprd_rate_mask_ht20; 2997 } 2998 } 2999 AH_PAPRD_GET_SCALE_FACTOR( 3000 paprd_scale_factor, p_eep_data, IEEE80211_IS_CHAN_2GHZ(chan), ichan->channel); 3001 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s[%d] paprd_scale_factor %d\n", 3002 __func__, __LINE__, paprd_scale_factor); 3003 /* PAPRD is not done yet, Scale down the EEP power */ 3004 if (IEEE80211_IS_CHAN_HT40(chan)) { 3005 ptr_mcs_rate2power_table_index = 3006 &mcs_rate2power_table_index_ht40[0]; 3007 } else { 3008 ptr_mcs_rate2power_table_index = 3009 &mcs_rate2power_table_index_ht20[0]; 3010 } 3011 if (! ichan->paprd_table_write_done) { 3012 for (i = 0; i < 24; i++) { 3013 /* PAPRD is done yet, so Scale down Power for PAPRD Rates*/ 3014 if (tmp_paprd_rate_mask & (1 << i)) { 3015 target_power_val_t2[ptr_mcs_rate2power_table_index[i]] -= 3016 paprd_scale_factor; 3017 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 3018 "%s[%d]: Chan %d " 3019 "Scale down target_power_val_t2[%d] = 0x%04x\n", 3020 __func__, __LINE__, 3021 ichan->channel, i, target_power_val_t2[i]); 3022 } 3023 } 3024 } else { 3025 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 3026 "%s[%d]: PAPRD Done No TGT PWR Scaling\n", __func__, __LINE__); 3027 } 3028 } 3029 3030 /* Save the Target power for future use */ 3031 OS_MEMCPY(target_power_val_t2_eep, target_power_val_t2, 3032 sizeof(target_power_val_t2)); 3033 ar9300_eeprom_set_power_per_rate_table(ah, p_eep_data, chan, 3034 target_power_val_t2, cfg_ctl, 3035 antenna_reduction, 3036 twice_max_regulatory_power, 3037 power_limit, 0); 3038 3039 /* Save this for quick lookup */ 3040 ahp->reg_dmn = ath_hal_getctl(ah, chan); 3041 3042 /* 3043 * Always use CDD/direct per rate power table for register based approach. 3044 * For FCC, CDD calculations should factor in the array gain, hence 3045 * this adjust call. ETSI and MKK does not have this requirement. 3046 */ 3047 if (is_reg_dmn_fcc(ahp->reg_dmn)) { 3048 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 3049 "%s: FCC regdomain, calling reg_txpower_cdd\n", 3050 __func__); 3051 ar9300_adjust_reg_txpower_cdd(ah, target_power_val_t2); 3052 } 3053 3054 if (ar9300_eeprom_get(ahp, EEP_PAPRD_ENABLED)) { 3055 for (i = 0; i < ar9300_rate_size; i++) { 3056 /* 3057 * EEPROM TGT PWR is not same as current TGT PWR, 3058 * so Disable PAPRD for this rate. 3059 * Some of APs might ask to reduce Target Power, 3060 * if target power drops significantly, 3061 * disable PAPRD for that rate. 3062 */ 3063 if (tmp_paprd_rate_mask & (1 << i)) { 3064 if (ABS(target_power_val_t2_eep[i], target_power_val_t2[i]) > 3065 paprd_scale_factor) 3066 { 3067 tmp_paprd_rate_mask &= ~(1 << i); 3068 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 3069 "%s: EEP TPC[%02d] 0x%08x " 3070 "Curr TPC[%02d] 0x%08x mask = 0x%08x\n", 3071 __func__, i, target_power_val_t2_eep[i], i, 3072 target_power_val_t2[i], tmp_paprd_rate_mask); 3073 } 3074 } 3075 3076 } 3077 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 3078 "%s: Chan %d After tmp_paprd_rate_mask = 0x%08x\n", 3079 __func__, ichan->channel, tmp_paprd_rate_mask); 3080 if (tmp_ptr) { 3081 *tmp_ptr = tmp_paprd_rate_mask; 3082 } 3083 } 3084 3085 /* Write target power array to registers */ 3086 ar9300_transmit_power_reg_write(ah, target_power_val_t2); 3087 3088 /* Write target power for self generated frames to the TPC register */ 3089 ar9300_selfgen_tpc_reg_write(ah, chan, target_power_val_t2); 3090 3091 /* GreenTx or Paprd */ 3092 if (ah->ah_config.ath_hal_sta_update_tx_pwr_enable || 3093 AH_PRIVATE(ah)->ah_caps.halPaprdEnabled) 3094 { 3095 if (AR_SREV_POSEIDON(ah)) { 3096 /*For HAL_RSSI_TX_POWER_NONE array*/ 3097 OS_MEMCPY(ahp->ah_default_tx_power, 3098 target_power_val_t2, 3099 sizeof(target_power_val_t2)); 3100 /* Get defautl tx related register setting for GreenTx */ 3101 /* Record OB/DB */ 3102 ahp->ah_ob_db1[POSEIDON_STORED_REG_OBDB] = 3103 OS_REG_READ(ah, AR_PHY_65NM_CH0_TXRF2); 3104 /* Record TPC settting */ 3105 ahp->ah_ob_db1[POSEIDON_STORED_REG_TPC] = 3106 OS_REG_READ(ah, AR_TPC); 3107 /* Record BB_powertx_rate9 setting */ 3108 ahp->ah_ob_db1[POSEIDON_STORED_REG_BB_PWRTX_RATE9] = 3109 OS_REG_READ(ah, AR_PHY_BB_POWERTX_RATE9); 3110 } 3111 } 3112 3113 /* 3114 * Return tx power used to iwconfig. 3115 * Since power is rate dependent, use one of the indices from the 3116 * AR9300_Rates enum to select an entry from target_power_val_t2[] 3117 * to report. 3118 * Currently returns the power for HT40 MCS 0, HT20 MCS 0, or OFDM 6 Mbps 3119 * as CCK power is less interesting (?). 3120 */ 3121 i = ALL_TARGET_LEGACY_6_24; /* legacy */ 3122 if (IEEE80211_IS_CHAN_HT40(chan)) { 3123 i = ALL_TARGET_HT40_0_8_16; /* ht40 */ 3124 } else if (IEEE80211_IS_CHAN_HT20(chan)) { 3125 i = ALL_TARGET_HT20_0_8_16; /* ht20 */ 3126 } 3127 max_power_level = target_power_val_t2[i]; 3128 /* Adjusting the ah_max_power_level based on chains and antennaGain*/ 3129 switch (ar9300_get_ntxchains(((ahp->ah_tx_chainmaskopt > 0) ? 3130 ahp->ah_tx_chainmaskopt : ahp->ah_tx_chainmask))) 3131 { 3132 case 1: 3133 break; 3134 case 2: 3135 twice_array_gain = (ahp->twice_antenna_gain >= ahp->twice_antenna_reduction)? 0: 3136 ((int16_t)AH_MIN((ahp->twice_antenna_reduction - 3137 (ahp->twice_antenna_gain + INCREASE_MAXPOW_BY_TWO_CHAIN)), 0)); 3138 /* Adjusting maxpower with antennaGain */ 3139 max_power_level -= twice_array_gain; 3140 /* Adjusting maxpower based on chain */ 3141 max_power_level += INCREASE_MAXPOW_BY_TWO_CHAIN; 3142 break; 3143 case 3: 3144 twice_array_gain = (ahp->twice_antenna_gain >= ahp->twice_antenna_reduction)? 0: 3145 ((int16_t)AH_MIN((ahp->twice_antenna_reduction - 3146 (ahp->twice_antenna_gain + INCREASE_MAXPOW_BY_THREE_CHAIN)), 0)); 3147 3148 /* Adjusting maxpower with antennaGain */ 3149 max_power_level -= twice_array_gain; 3150 /* Adjusting maxpower based on chain */ 3151 max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN; 3152 break; 3153 default: 3154 HALASSERT(0); /* Unsupported number of chains */ 3155 } 3156 AH_PRIVATE(ah)->ah_maxPowerLevel = (int8_t)max_power_level; 3157 3158 ar9300_calibration_apply(ah, ichan->channel); 3159 #undef ABS 3160 3161 /* Handle per packet TPC initializations */ 3162 if (ah->ah_config.ath_hal_desc_tpc) { 3163 /* Transmit Power per-rate per-chain are computed here. A separate 3164 * power table is maintained for different MIMO modes (i.e. TXBF ON, 3165 * STBC) to enable easy lookup during packet transmit. 3166 * The reason for maintaing each of these tables per chain is that 3167 * the transmit power used for different number of chains is different 3168 * depending on whether the power has been limited by the target power, 3169 * the regulatory domain or the CTL limits. 3170 */ 3171 u_int mode = ath_hal_get_curmode(ah, chan); 3172 u_int32_t val = 0; 3173 u_int8_t chainmasks[AR9300_MAX_CHAINS] = 3174 {OSPREY_1_CHAINMASK, OSPREY_2LOHI_CHAINMASK, OSPREY_3_CHAINMASK}; 3175 for (i = 0; i < AR9300_MAX_CHAINS; i++) { 3176 OS_MEMCPY(target_power_val_t2, target_power_val_t2_eep, 3177 sizeof(target_power_val_t2_eep)); 3178 ar9300_eeprom_set_power_per_rate_table(ah, p_eep_data, chan, 3179 target_power_val_t2, cfg_ctl, 3180 antenna_reduction, 3181 twice_max_regulatory_power, 3182 power_limit, chainmasks[i]); 3183 HALDEBUG(ah, HAL_DEBUG_POWER_MGMT, 3184 " Channel = %d Chainmask = %d, Upper Limit = [%2d.%1d dBm]\n", 3185 ichan->channel, i, ahp->upper_limit[i]/2, 3186 ahp->upper_limit[i]%2 * 5); 3187 ar9300_init_rate_txpower(ah, mode, chan, target_power_val_t2, 3188 chainmasks[i]); 3189 3190 } 3191 3192 /* Enable TPC */ 3193 OS_REG_WRITE(ah, AR_PHY_PWRTX_MAX, AR_PHY_PWRTX_MAX_TPC_ENABLE); 3194 /* 3195 * Disable per chain power reduction since we are already 3196 * accounting for this in our calculations 3197 */ 3198 val = OS_REG_READ(ah, AR_PHY_POWER_TX_SUB); 3199 if (AR_SREV_WASP(ah)) { 3200 OS_REG_WRITE(ah, AR_PHY_POWER_TX_SUB, 3201 val & AR_PHY_POWER_TX_SUB_2_DISABLE); 3202 } else { 3203 OS_REG_WRITE(ah, AR_PHY_POWER_TX_SUB, 3204 val & AR_PHY_POWER_TX_SUB_3_DISABLE); 3205 } 3206 } 3207 3208 return HAL_OK; 3209 } 3210 3211 /************************************************************** 3212 * ar9300_eeprom_set_addac 3213 * 3214 * Set the ADDAC from eeprom. 3215 */ 3216 void 3217 ar9300_eeprom_set_addac(struct ath_hal *ah, struct ieee80211_channel *chan) 3218 { 3219 3220 HALDEBUG(AH_NULL, HAL_DEBUG_UNMASKABLE, 3221 "FIXME: ar9300_eeprom_def_set_addac called\n"); 3222 #if 0 3223 MODAL_EEPDEF_HEADER *p_modal; 3224 struct ath_hal_9300 *ahp = AH9300(ah); 3225 ar9300_eeprom_t *eep = &ahp->ah_eeprom.def; 3226 u_int8_t biaslevel; 3227 3228 if (AH_PRIVATE(ah)->ah_macVersion != AR_SREV_VERSION_SOWL) { 3229 return; 3230 } 3231 3232 HALASSERT(owl_get_eepdef_ver(ahp) == AR9300_EEP_VER); 3233 3234 /* Xpa bias levels in eeprom are valid from rev 14.7 */ 3235 if (owl_get_eepdef_rev(ahp) < AR9300_EEP_MINOR_VER_7) { 3236 return; 3237 } 3238 3239 if (ahp->ah_emu_eeprom) { 3240 return; 3241 } 3242 3243 p_modal = &(eep->modal_header[IEEE80211_IS_CHAN_2GHZ(chan)]); 3244 3245 if (p_modal->xpa_bias_lvl != 0xff) { 3246 biaslevel = p_modal->xpa_bias_lvl; 3247 } else { 3248 /* Use freqeuncy specific xpa bias level */ 3249 u_int16_t reset_freq_bin, freq_bin, freq_count = 0; 3250 CHAN_CENTERS centers; 3251 3252 ar9300_get_channel_centers(ah, chan, ¢ers); 3253 3254 reset_freq_bin = FREQ2FBIN(centers.synth_center, IEEE80211_IS_CHAN_2GHZ(chan)); 3255 freq_bin = p_modal->xpa_bias_lvl_freq[0] & 0xff; 3256 biaslevel = (u_int8_t)(p_modal->xpa_bias_lvl_freq[0] >> 14); 3257 3258 freq_count++; 3259 3260 while (freq_count < 3) { 3261 if (p_modal->xpa_bias_lvl_freq[freq_count] == 0x0) { 3262 break; 3263 } 3264 3265 freq_bin = p_modal->xpa_bias_lvl_freq[freq_count] & 0xff; 3266 if (reset_freq_bin >= freq_bin) { 3267 biaslevel = 3268 (u_int8_t)(p_modal->xpa_bias_lvl_freq[freq_count] >> 14); 3269 } else { 3270 break; 3271 } 3272 freq_count++; 3273 } 3274 } 3275 3276 /* Apply bias level to the ADDAC values in the INI array */ 3277 if (IEEE80211_IS_CHAN_2GHZ(chan)) { 3278 INI_RA(&ahp->ah_ini_addac, 7, 1) = 3279 (INI_RA(&ahp->ah_ini_addac, 7, 1) & (~0x18)) | biaslevel << 3; 3280 } else { 3281 INI_RA(&ahp->ah_ini_addac, 6, 1) = 3282 (INI_RA(&ahp->ah_ini_addac, 6, 1) & (~0xc0)) | biaslevel << 6; 3283 } 3284 #endif 3285 } 3286 3287 u_int 3288 ar9300_eeprom_dump_support(struct ath_hal *ah, void **pp_e) 3289 { 3290 *pp_e = &(AH9300(ah)->ah_eeprom); 3291 return sizeof(ar9300_eeprom_t); 3292 } 3293 3294 u_int8_t 3295 ar9300_eeprom_get_num_ant_config(struct ath_hal_9300 *ahp, 3296 HAL_FREQ_BAND freq_band) 3297 { 3298 #if 0 3299 ar9300_eeprom_t *eep = &ahp->ah_eeprom.def; 3300 MODAL_EEPDEF_HEADER *p_modal = 3301 &(eep->modal_header[HAL_FREQ_BAND_2GHZ == freq_band]); 3302 BASE_EEPDEF_HEADER *p_base = &eep->base_eep_header; 3303 u_int8_t num_ant_config; 3304 3305 num_ant_config = 1; /* default antenna configuration */ 3306 3307 if (p_base->version >= 0x0E0D) { 3308 if (p_modal->use_ant1) { 3309 num_ant_config += 1; 3310 } 3311 } 3312 3313 return num_ant_config; 3314 #else 3315 return 1; 3316 #endif 3317 } 3318 3319 HAL_STATUS 3320 ar9300_eeprom_get_ant_cfg(struct ath_hal_9300 *ahp, 3321 const struct ieee80211_channel *chan, 3322 u_int8_t index, u_int16_t *config) 3323 { 3324 #if 0 3325 ar9300_eeprom_t *eep = &ahp->ah_eeprom.def; 3326 MODAL_EEPDEF_HEADER *p_modal = &(eep->modal_header[IEEE80211_IS_CHAN_2GHZ(chan)]); 3327 BASE_EEPDEF_HEADER *p_base = &eep->base_eep_header; 3328 3329 switch (index) { 3330 case 0: 3331 *config = p_modal->ant_ctrl_common & 0xFFFF; 3332 return HAL_OK; 3333 case 1: 3334 if (p_base->version >= 0x0E0D) { 3335 if (p_modal->use_ant1) { 3336 *config = ((p_modal->ant_ctrl_common & 0xFFFF0000) >> 16); 3337 return HAL_OK; 3338 } 3339 } 3340 break; 3341 default: 3342 break; 3343 } 3344 #endif 3345 return HAL_EINVAL; 3346 } 3347 3348 u_int8_t* 3349 ar9300_eeprom_get_cust_data(struct ath_hal_9300 *ahp) 3350 { 3351 return (u_int8_t *)ahp; 3352 } 3353 3354 #ifdef UNUSED 3355 static inline HAL_STATUS 3356 ar9300_check_eeprom(struct ath_hal *ah) 3357 { 3358 #if 0 3359 u_int32_t sum = 0, el; 3360 u_int16_t *eepdata; 3361 int i; 3362 struct ath_hal_9300 *ahp = AH9300(ah); 3363 HAL_BOOL need_swap = AH_FALSE; 3364 ar9300_eeprom_t *eep = (ar9300_eeprom_t *)&ahp->ah_eeprom.def; 3365 u_int16_t magic, magic2; 3366 int addr; 3367 u_int16_t temp; 3368 3369 /* 3370 ** We need to check the EEPROM data regardless of if it's in flash or 3371 ** in EEPROM. 3372 */ 3373 3374 if (!ahp->ah_priv.priv.ah_eeprom_read( 3375 ah, AR9300_EEPROM_MAGIC_OFFSET, &magic)) 3376 { 3377 HALDEBUG(ah, HAL_DEBUG_EEPROM, "%s: Reading Magic # failed\n", __func__); 3378 return AH_FALSE; 3379 } 3380 3381 HALDEBUG(ah, HAL_DEBUG_EEPROM, "%s: Read Magic = 0x%04X\n", __func__, magic); 3382 3383 if (!ar9300_eep_data_in_flash(ah)) { 3384 3385 if (magic != AR9300_EEPROM_MAGIC) { 3386 magic2 = SWAP16(magic); 3387 3388 if (magic2 == AR9300_EEPROM_MAGIC) { 3389 need_swap = AH_TRUE; 3390 eepdata = (u_int16_t *)(&ahp->ah_eeprom); 3391 3392 for (addr = 0; 3393 addr < sizeof(ar9300_eeprom_t) / sizeof(u_int16_t); 3394 addr++) 3395 { 3396 temp = SWAP16(*eepdata); 3397 *eepdata = temp; 3398 eepdata++; 3399 3400 HALDEBUG(ah, HAL_DEBUG_EEPROM_DUMP, "0x%04X ", *eepdata); 3401 if (((addr + 1) % 6) == 0) { 3402 HALDEBUG(ah, HAL_DEBUG_EEPROM_DUMP, "\n"); 3403 } 3404 } 3405 } else { 3406 HALDEBUG(ah, HAL_DEBUG_EEPROM, 3407 "Invalid EEPROM Magic. endianness missmatch.\n"); 3408 return HAL_EEBADSUM; 3409 } 3410 } 3411 } else { 3412 HALDEBUG(ah, HAL_DEBUG_EEPROM, 3413 "EEPROM being read from flash @0x%p\n", AH_PRIVATE(ah)->ah_st); 3414 } 3415 3416 HALDEBUG(ah, HAL_DEBUG_EEPROM, "need_swap = %s.\n", need_swap?"True":"False"); 3417 3418 if (need_swap) { 3419 el = SWAP16(ahp->ah_eeprom.def.base_eep_header.length); 3420 } else { 3421 el = ahp->ah_eeprom.def.base_eep_header.length; 3422 } 3423 3424 eepdata = (u_int16_t *)(&ahp->ah_eeprom.def); 3425 for (i = 0; 3426 i < AH_MIN(el, sizeof(ar9300_eeprom_t)) / sizeof(u_int16_t); 3427 i++) { 3428 sum ^= *eepdata++; 3429 } 3430 3431 if (need_swap) { 3432 /* 3433 * preddy: EEPROM endianness does not match. So change it 3434 * 8bit values in eeprom data structure does not need to be swapped 3435 * Only >8bits (16 & 32) values need to be swapped 3436 * If a new 16 or 32 bit field is added to the EEPROM contents, 3437 * please make sure to swap the field here 3438 */ 3439 u_int32_t integer, j; 3440 u_int16_t word; 3441 3442 HALDEBUG(ah, HAL_DEBUG_EEPROM, 3443 "EEPROM Endianness is not native.. Changing \n"); 3444 3445 /* convert Base Eep header */ 3446 word = SWAP16(eep->base_eep_header.length); 3447 eep->base_eep_header.length = word; 3448 3449 word = SWAP16(eep->base_eep_header.checksum); 3450 eep->base_eep_header.checksum = word; 3451 3452 word = SWAP16(eep->base_eep_header.version); 3453 eep->base_eep_header.version = word; 3454 3455 word = SWAP16(eep->base_eep_header.reg_dmn[0]); 3456 eep->base_eep_header.reg_dmn[0] = word; 3457 3458 word = SWAP16(eep->base_eep_header.reg_dmn[1]); 3459 eep->base_eep_header.reg_dmn[1] = word; 3460 3461 word = SWAP16(eep->base_eep_header.rf_silent); 3462 eep->base_eep_header.rf_silent = word; 3463 3464 word = SWAP16(eep->base_eep_header.blue_tooth_options); 3465 eep->base_eep_header.blue_tooth_options = word; 3466 3467 word = SWAP16(eep->base_eep_header.device_cap); 3468 eep->base_eep_header.device_cap = word; 3469 3470 /* convert Modal Eep header */ 3471 for (j = 0; j < ARRAY_LENGTH(eep->modal_header); j++) { 3472 MODAL_EEPDEF_HEADER *p_modal = &eep->modal_header[j]; 3473 integer = SWAP32(p_modal->ant_ctrl_common); 3474 p_modal->ant_ctrl_common = integer; 3475 3476 for (i = 0; i < AR9300_MAX_CHAINS; i++) { 3477 integer = SWAP32(p_modal->ant_ctrl_chain[i]); 3478 p_modal->ant_ctrl_chain[i] = integer; 3479 } 3480 3481 for (i = 0; i < AR9300_EEPROM_MODAL_SPURS; i++) { 3482 word = SWAP16(p_modal->spur_chans[i].spur_chan); 3483 p_modal->spur_chans[i].spur_chan = word; 3484 } 3485 } 3486 } 3487 3488 /* Check CRC - Attach should fail on a bad checksum */ 3489 if (sum != 0xffff || owl_get_eepdef_ver(ahp) != AR9300_EEP_VER || 3490 owl_get_eepdef_rev(ahp) < AR9300_EEP_NO_BACK_VER) { 3491 HALDEBUG(ah, HAL_DEBUG_EEPROM, 3492 "Bad EEPROM checksum 0x%x or revision 0x%04x\n", 3493 sum, owl_get_eepdef_ver(ahp)); 3494 return HAL_EEBADSUM; 3495 } 3496 #ifdef EEPROM_DUMP 3497 ar9300_eeprom_def_dump(ah, eep); 3498 #endif 3499 3500 #if 0 3501 #ifdef AH_AR9300_OVRD_TGT_PWR 3502 3503 /* 3504 * 14.4 EEPROM contains low target powers. 3505 * Hardcode until EEPROM > 14.4 3506 */ 3507 if (owl_get_eepdef_ver(ahp) == 14 && owl_get_eepdef_rev(ahp) <= 4) { 3508 MODAL_EEPDEF_HEADER *p_modal; 3509 3510 #ifdef EEPROM_DUMP 3511 HALDEBUG(ah, HAL_DEBUG_POWER_OVERRIDE, "Original Target Powers\n"); 3512 ar9300_eep_def_dump_tgt_power(ah, eep); 3513 #endif 3514 HALDEBUG(ah, HAL_DEBUG_POWER_OVERRIDE, 3515 "Override Target Powers. EEPROM Version is %d.%d, " 3516 "Device Type %d\n", 3517 owl_get_eepdef_ver(ahp), 3518 owl_get_eepdef_rev(ahp), 3519 eep->base_eep_header.device_type); 3520 3521 3522 ar9300_eep_def_override_tgt_power(ah, eep); 3523 3524 if (eep->base_eep_header.device_type == 5) { 3525 /* for xb72 only: improve transmit EVM for interop */ 3526 p_modal = &eep->modal_header[1]; 3527 p_modal->tx_frame_to_data_start = 0x23; 3528 p_modal->tx_frame_to_xpa_on = 0x23; 3529 p_modal->tx_frame_to_pa_on = 0x23; 3530 } 3531 3532 #ifdef EEPROM_DUMP 3533 HALDEBUG(ah, HAL_DEBUG_POWER_OVERRIDE, "Modified Target Powers\n"); 3534 ar9300_eep_def_dump_tgt_power(ah, eep); 3535 #endif 3536 } 3537 #endif /* AH_AR9300_OVRD_TGT_PWR */ 3538 #endif 3539 #endif 3540 return HAL_OK; 3541 } 3542 #endif 3543 3544 static u_int16_t 3545 ar9300_eeprom_get_spur_chan(struct ath_hal *ah, int i, HAL_BOOL is_2ghz) 3546 { 3547 u_int16_t spur_val = AR_NO_SPUR; 3548 #if 0 3549 struct ath_hal_9300 *ahp = AH9300(ah); 3550 ar9300_eeprom_t *eep = (ar9300_eeprom_t *)&ahp->ah_eeprom; 3551 3552 HALASSERT(i < AR_EEPROM_MODAL_SPURS ); 3553 3554 HALDEBUG(ah, HAL_DEBUG_ANI, 3555 "Getting spur idx %d is2Ghz. %d val %x\n", 3556 i, is_2ghz, 3557 AH_PRIVATE(ah)->ah_config.ath_hal_spur_chans[i][is_2ghz]); 3558 3559 switch (AH_PRIVATE(ah)->ah_config.ath_hal_spur_mode) { 3560 case SPUR_DISABLE: 3561 /* returns AR_NO_SPUR */ 3562 break; 3563 case SPUR_ENABLE_IOCTL: 3564 spur_val = AH_PRIVATE(ah)->ah_config.ath_hal_spur_chans[i][is_2ghz]; 3565 HALDEBUG(ah, HAL_DEBUG_ANI, 3566 "Getting spur val from new loc. %d\n", spur_val); 3567 break; 3568 case SPUR_ENABLE_EEPROM: 3569 spur_val = eep->modal_header[is_2ghz].spur_chans[i].spur_chan; 3570 break; 3571 3572 } 3573 #endif 3574 return spur_val; 3575 } 3576 3577 #ifdef UNUSED 3578 static inline HAL_BOOL 3579 ar9300_fill_eeprom(struct ath_hal *ah) 3580 { 3581 return ar9300_eeprom_restore(ah); 3582 } 3583 #endif 3584 3585 u_int16_t 3586 ar9300_eeprom_struct_size(void) 3587 { 3588 return sizeof(ar9300_eeprom_t); 3589 } 3590 3591 int ar9300_eeprom_struct_default_many(void) 3592 { 3593 return ARRAY_LENGTH(default9300); 3594 } 3595 3596 3597 ar9300_eeprom_t * 3598 ar9300_eeprom_struct_default(int default_index) 3599 { 3600 if (default_index >= 0 && 3601 default_index < ARRAY_LENGTH(default9300)) 3602 { 3603 return default9300[default_index]; 3604 } else { 3605 return 0; 3606 } 3607 } 3608 3609 ar9300_eeprom_t * 3610 ar9300_eeprom_struct_default_find_by_id(int id) 3611 { 3612 int it; 3613 3614 for (it = 0; it < ARRAY_LENGTH(default9300); it++) { 3615 if (default9300[it] != 0 && default9300[it]->template_version == id) { 3616 return default9300[it]; 3617 } 3618 } 3619 return 0; 3620 } 3621 3622 3623 HAL_BOOL 3624 ar9300_calibration_data_read_flash(struct ath_hal *ah, long address, 3625 u_int8_t *buffer, int many) 3626 { 3627 3628 if (((address) < 0) || ((address + many) > AR9300_EEPROM_SIZE - 1)) { 3629 return AH_FALSE; 3630 } 3631 return AH_FALSE; 3632 } 3633 3634 HAL_BOOL 3635 ar9300_calibration_data_read_eeprom(struct ath_hal *ah, long address, 3636 u_int8_t *buffer, int many) 3637 { 3638 int i; 3639 u_int8_t value[2]; 3640 unsigned long eep_addr; 3641 unsigned long byte_addr; 3642 u_int16_t *svalue; 3643 3644 if (((address) < 0) || ((address + many) > AR9300_EEPROM_SIZE)) { 3645 return AH_FALSE; 3646 } 3647 3648 for (i = 0; i < many; i++) { 3649 eep_addr = (u_int16_t) (address + i) / 2; 3650 byte_addr = (u_int16_t) (address + i) % 2; 3651 svalue = (u_int16_t *) value; 3652 if (! ath_hal_eepromRead(ah, eep_addr, svalue)) { 3653 HALDEBUG(ah, HAL_DEBUG_EEPROM, 3654 "%s: Unable to read eeprom region \n", __func__); 3655 return AH_FALSE; 3656 } 3657 buffer[i] = (*svalue >> (8 * byte_addr)) & 0xff; 3658 } 3659 return AH_TRUE; 3660 } 3661 3662 HAL_BOOL 3663 ar9300_calibration_data_read_otp(struct ath_hal *ah, long address, 3664 u_int8_t *buffer, int many, HAL_BOOL is_wifi) 3665 { 3666 int i; 3667 unsigned long eep_addr; 3668 unsigned long byte_addr; 3669 u_int32_t svalue; 3670 3671 if (((address) < 0) || ((address + many) > 0x400)) { 3672 return AH_FALSE; 3673 } 3674 3675 for (i = 0; i < many; i++) { 3676 eep_addr = (u_int16_t) (address + i) / 4; /* otp is 4 bytes long???? */ 3677 byte_addr = (u_int16_t) (address + i) % 4; 3678 if (!ar9300_otp_read(ah, eep_addr, &svalue, is_wifi)) { 3679 HALDEBUG(ah, HAL_DEBUG_EEPROM, 3680 "%s: Unable to read otp region \n", __func__); 3681 return AH_FALSE; 3682 } 3683 buffer[i] = (svalue >> (8 * byte_addr)) & 0xff; 3684 } 3685 return AH_TRUE; 3686 } 3687 3688 #ifdef ATH_CAL_NAND_FLASH 3689 HAL_BOOL 3690 ar9300_calibration_data_read_nand(struct ath_hal *ah, long address, 3691 u_int8_t *buffer, int many) 3692 { 3693 int ret_len; 3694 int ret_val = 1; 3695 3696 /* Calling OS based API to read NAND */ 3697 ret_val = OS_NAND_FLASH_READ(ATH_CAL_NAND_PARTITION, address, many, &ret_len, buffer); 3698 3699 return (ret_val ? AH_FALSE: AH_TRUE); 3700 } 3701 #endif 3702 3703 HAL_BOOL 3704 ar9300_calibration_data_read(struct ath_hal *ah, long address, 3705 u_int8_t *buffer, int many) 3706 { 3707 switch (AH9300(ah)->calibration_data_source) { 3708 case calibration_data_flash: 3709 return ar9300_calibration_data_read_flash(ah, address, buffer, many); 3710 case calibration_data_eeprom: 3711 return ar9300_calibration_data_read_eeprom(ah, address, buffer, many); 3712 case calibration_data_otp: 3713 return ar9300_calibration_data_read_otp(ah, address, buffer, many, 1); 3714 #ifdef ATH_CAL_NAND_FLASH 3715 case calibration_data_nand: 3716 return ar9300_calibration_data_read_nand(ah,address,buffer,many); 3717 #endif 3718 3719 } 3720 return AH_FALSE; 3721 } 3722 3723 3724 HAL_BOOL 3725 ar9300_calibration_data_read_array(struct ath_hal *ah, int address, 3726 u_int8_t *buffer, int many) 3727 { 3728 int it; 3729 3730 for (it = 0; it < many; it++) { 3731 (void)ar9300_calibration_data_read(ah, address - it, buffer + it, 1); 3732 } 3733 return AH_TRUE; 3734 } 3735 3736 3737 /* 3738 * the address where the first configuration block is written 3739 */ 3740 static const int base_address = 0x3ff; /* 1KB */ 3741 static const int base_address_512 = 0x1ff; /* 512Bytes */ 3742 3743 /* 3744 * the address where the NAND first configuration block is written 3745 */ 3746 #ifdef ATH_CAL_NAND_FLASH 3747 static const int base_address_nand = AR9300_FLASH_CAL_START_OFFSET; 3748 #endif 3749 3750 3751 /* 3752 * the lower limit on configuration data 3753 */ 3754 static const int low_limit = 0x040; 3755 3756 /* 3757 * returns size of the physical eeprom in bytes. 3758 * 1024 and 2048 are normal sizes. 3759 * 0 means there is no eeprom. 3760 */ 3761 int32_t 3762 ar9300_eeprom_size(struct ath_hal *ah) 3763 { 3764 u_int16_t data; 3765 /* 3766 * first we'll try for 4096 bytes eeprom 3767 */ 3768 if (ar9300_eeprom_read_word(ah, 2047, &data)) { 3769 if (data != 0) { 3770 return 4096; 3771 } 3772 } 3773 /* 3774 * then we'll try for 2048 bytes eeprom 3775 */ 3776 if (ar9300_eeprom_read_word(ah, 1023, &data)) { 3777 if (data != 0) { 3778 return 2048; 3779 } 3780 } 3781 /* 3782 * then we'll try for 1024 bytes eeprom 3783 */ 3784 if (ar9300_eeprom_read_word(ah, 511, &data)) { 3785 if (data != 0) { 3786 return 1024; 3787 } 3788 } 3789 return 0; 3790 } 3791 3792 /* 3793 * returns size of the physical otp in bytes. 3794 * 1024 and 2048 are normal sizes. 3795 * 0 means there is no eeprom. 3796 */ 3797 int32_t 3798 ar9300_otp_size(struct ath_hal *ah) 3799 { 3800 if (AR_SREV_POSEIDON(ah) || AR_SREV_HORNET(ah)) { 3801 return base_address_512+1; 3802 } else { 3803 return base_address+1; 3804 } 3805 } 3806 3807 3808 /* 3809 * find top of memory 3810 */ 3811 int 3812 ar9300_eeprom_base_address(struct ath_hal *ah) 3813 { 3814 int size; 3815 3816 if (AH9300(ah)->calibration_data_source == calibration_data_otp) { 3817 return ar9300_otp_size(ah)-1; 3818 } 3819 else 3820 { 3821 size = ar9300_eeprom_size(ah); 3822 if (size > 0) { 3823 return size - 1; 3824 } else { 3825 return ar9300_otp_size(ah)-1; 3826 } 3827 } 3828 } 3829 3830 int 3831 ar9300_eeprom_volatile(struct ath_hal *ah) 3832 { 3833 if (AH9300(ah)->calibration_data_source == calibration_data_otp) { 3834 return 0; /* no eeprom, use otp */ 3835 } else { 3836 return 1; /* board has eeprom or flash */ 3837 } 3838 } 3839 3840 /* 3841 * need to change this to look for the pcie data in the low parts of memory 3842 * cal data needs to stop a few locations above 3843 */ 3844 int 3845 ar9300_eeprom_low_limit(struct ath_hal *ah) 3846 { 3847 return low_limit; 3848 } 3849 3850 u_int16_t 3851 ar9300_compression_checksum(u_int8_t *data, int dsize) 3852 { 3853 int it; 3854 int checksum = 0; 3855 3856 for (it = 0; it < dsize; it++) { 3857 checksum += data[it]; 3858 checksum &= 0xffff; 3859 } 3860 3861 return checksum; 3862 } 3863 3864 int 3865 ar9300_compression_header_unpack(u_int8_t *best, int *code, int *reference, 3866 int *length, int *major, int *minor) 3867 { 3868 unsigned long value[4]; 3869 3870 value[0] = best[0]; 3871 value[1] = best[1]; 3872 value[2] = best[2]; 3873 value[3] = best[3]; 3874 *code = ((value[0] >> 5) & 0x0007); 3875 *reference = (value[0] & 0x001f) | ((value[1] >> 2) & 0x0020); 3876 *length = ((value[1] << 4) & 0x07f0) | ((value[2] >> 4) & 0x000f); 3877 *major = (value[2] & 0x000f); 3878 *minor = (value[3] & 0x00ff); 3879 3880 return 4; 3881 } 3882 3883 3884 static HAL_BOOL 3885 ar9300_uncompress_block(struct ath_hal *ah, u_int8_t *mptr, int mdata_size, 3886 u_int8_t *block, int size) 3887 { 3888 int it; 3889 int spot; 3890 int offset; 3891 int length; 3892 3893 spot = 0; 3894 for (it = 0; it < size; it += (length + 2)) { 3895 offset = block[it]; 3896 offset &= 0xff; 3897 spot += offset; 3898 length = block[it + 1]; 3899 length &= 0xff; 3900 if (length > 0 && spot >= 0 && spot + length <= mdata_size) { 3901 HALDEBUG(ah, HAL_DEBUG_EEPROM, 3902 "%s: Restore at %d: spot=%d offset=%d length=%d\n", 3903 __func__, it, spot, offset, length); 3904 OS_MEMCPY(&mptr[spot], &block[it + 2], length); 3905 spot += length; 3906 } else if (length > 0) { 3907 HALDEBUG(ah, HAL_DEBUG_EEPROM, 3908 "%s: Bad restore at %d: spot=%d offset=%d length=%d\n", 3909 __func__, it, spot, offset, length); 3910 return AH_FALSE; 3911 } 3912 } 3913 return AH_TRUE; 3914 } 3915 3916 static int 3917 ar9300_eeprom_restore_internal_address(struct ath_hal *ah, 3918 ar9300_eeprom_t *mptr, int mdata_size, int cptr, u_int8_t blank) 3919 { 3920 u_int8_t word[MOUTPUT]; 3921 ar9300_eeprom_t *dptr; /* was uint8 */ 3922 int code; 3923 int reference, length, major, minor; 3924 int osize; 3925 int it; 3926 int restored; 3927 u_int16_t checksum, mchecksum; 3928 3929 restored = 0; 3930 for (it = 0; it < MSTATE; it++) { 3931 (void) ar9300_calibration_data_read_array( 3932 ah, cptr, word, compression_header_length); 3933 if (word[0] == blank && word[1] == blank && word[2] == blank && word[3] == blank) 3934 { 3935 break; 3936 } 3937 ar9300_compression_header_unpack( 3938 word, &code, &reference, &length, &major, &minor); 3939 HALDEBUG(ah, HAL_DEBUG_EEPROM, 3940 "%s: Found block at %x: " 3941 "code=%d ref=%d length=%d major=%d minor=%d\n", 3942 __func__, cptr, code, reference, length, major, minor); 3943 #ifdef DONTUSE 3944 if (length >= 1024) { 3945 HALDEBUG(ah, HAL_DEBUG_EEPROM, "%s: Skipping bad header\n", __func__); 3946 cptr -= compression_header_length; 3947 continue; 3948 } 3949 #endif 3950 osize = length; 3951 (void) ar9300_calibration_data_read_array( 3952 ah, cptr, word, 3953 compression_header_length + osize + compression_checksum_length); 3954 checksum = ar9300_compression_checksum( 3955 &word[compression_header_length], length); 3956 mchecksum = 3957 word[compression_header_length + osize] | 3958 (word[compression_header_length + osize + 1] << 8); 3959 HALDEBUG(ah, HAL_DEBUG_EEPROM, 3960 "%s: checksum %x %x\n", __func__, checksum, mchecksum); 3961 if (checksum == mchecksum) { 3962 switch (code) { 3963 case _compress_none: 3964 if (length != mdata_size) { 3965 HALDEBUG(ah, HAL_DEBUG_EEPROM, 3966 "%s: EEPROM structure size mismatch " 3967 "memory=%d eeprom=%d\n", __func__, mdata_size, length); 3968 return -1; 3969 } 3970 OS_MEMCPY((u_int8_t *)mptr, 3971 (u_int8_t *)(word + compression_header_length), length); 3972 HALDEBUG(ah, HAL_DEBUG_EEPROM, 3973 "%s: restored eeprom %d: uncompressed, length %d\n", 3974 __func__, it, length); 3975 restored = 1; 3976 break; 3977 #ifdef UNUSED 3978 case _compress_lzma: 3979 if (reference == reference_current) { 3980 dptr = mptr; 3981 } else { 3982 dptr = (u_int8_t *)ar9300_eeprom_struct_default_find_by_id( 3983 reference); 3984 if (dptr == 0) { 3985 HALDEBUG(ah, HAL_DEBUG_EEPROM, 3986 "%s: Can't find reference eeprom struct %d\n", 3987 __func__, reference); 3988 goto done; 3989 } 3990 } 3991 usize = -1; 3992 if (usize != mdata_size) { 3993 HALDEBUG(ah, HAL_DEBUG_EEPROM, 3994 "%s: uncompressed data is wrong size %d %d\n", 3995 __func__, usize, mdata_size); 3996 goto done; 3997 } 3998 3999 for (ib = 0; ib < mdata_size; ib++) { 4000 mptr[ib] = dptr[ib] ^ word[ib + overhead]; 4001 } 4002 HALDEBUG(ah, HAL_DEBUG_EEPROM, 4003 "%s: restored eeprom %d: compressed, " 4004 "reference %d, length %d\n", 4005 __func__, it, reference, length); 4006 break; 4007 case _compress_pairs: 4008 if (reference == reference_current) { 4009 dptr = mptr; 4010 } else { 4011 dptr = (u_int8_t *)ar9300_eeprom_struct_default_find_by_id( 4012 reference); 4013 if (dptr == 0) { 4014 HALDEBUG(ah, HAL_DEBUG_EEPROM, 4015 "%s: Can't find the reference " 4016 "eeprom structure %d\n", 4017 __func__, reference); 4018 goto done; 4019 } 4020 } 4021 HALDEBUG(ah, HAL_DEBUG_EEPROM, 4022 "%s: restored eeprom %d: " 4023 "pairs, reference %d, length %d,\n", 4024 __func__, it, reference, length); 4025 break; 4026 #endif 4027 case _compress_block: 4028 if (reference == reference_current) { 4029 dptr = mptr; 4030 } else { 4031 dptr = ar9300_eeprom_struct_default_find_by_id(reference); 4032 if (dptr == 0) { 4033 HALDEBUG(ah, HAL_DEBUG_EEPROM, 4034 "%s: cant find reference eeprom struct %d\n", 4035 __func__, reference); 4036 break; 4037 } 4038 OS_MEMCPY(mptr, dptr, mdata_size); 4039 } 4040 4041 HALDEBUG(ah, HAL_DEBUG_EEPROM, 4042 "%s: restore eeprom %d: block, reference %d, length %d\n", 4043 __func__, it, reference, length); 4044 (void) ar9300_uncompress_block(ah, 4045 (u_int8_t *) mptr, mdata_size, 4046 (u_int8_t *) (word + compression_header_length), length); 4047 restored = 1; 4048 break; 4049 default: 4050 HALDEBUG(ah, HAL_DEBUG_EEPROM, 4051 "%s: unknown compression code %d\n", __func__, code); 4052 break; 4053 } 4054 } else { 4055 HALDEBUG(ah, HAL_DEBUG_EEPROM, 4056 "%s: skipping block with bad checksum\n", __func__); 4057 } 4058 cptr -= compression_header_length + osize + compression_checksum_length; 4059 } 4060 4061 if (!restored) { 4062 cptr = -1; 4063 } 4064 return cptr; 4065 } 4066 4067 static int 4068 ar9300_eeprom_restore_from_dram(struct ath_hal *ah, ar9300_eeprom_t *mptr, 4069 int mdata_size) 4070 { 4071 struct ath_hal_9300 *ahp = AH9300(ah); 4072 #if !defined(USE_PLATFORM_FRAMEWORK) 4073 char *cal_ptr; 4074 #endif 4075 4076 HALASSERT(mdata_size > 0); 4077 4078 /* if cal_in_flash is AH_TRUE, the address sent by LMAC to HAL 4079 (i.e. ah->ah_st) is corresponding to Flash. so return from 4080 here if ar9300_eep_data_in_flash(ah) returns AH_TRUE */ 4081 if(ar9300_eep_data_in_flash(ah)) 4082 return -1; 4083 4084 #if 0 4085 /* check if LMAC sent DRAM address is valid */ 4086 if (!(uintptr_t)(AH_PRIVATE(ah)->ah_st)) { 4087 return -1; 4088 } 4089 #endif 4090 4091 /* When calibration data is from host, Host will copy the 4092 compressed data to the predefined DRAM location saved at ah->ah_st */ 4093 #if 0 4094 ath_hal_printf(ah, "Restoring Cal data from DRAM\n"); 4095 ahp->ah_cal_mem = OS_REMAP((uintptr_t)(AH_PRIVATE(ah)->ah_st), 4096 HOST_CALDATA_SIZE); 4097 #endif 4098 if (!ahp->ah_cal_mem) 4099 { 4100 HALDEBUG(ah, HAL_DEBUG_EEPROM,"%s: can't remap dram region\n", __func__); 4101 return -1; 4102 } 4103 #if !defined(USE_PLATFORM_FRAMEWORK) 4104 cal_ptr = &((char *)(ahp->ah_cal_mem))[AR9300_FLASH_CAL_START_OFFSET]; 4105 OS_MEMCPY(mptr, cal_ptr, mdata_size); 4106 #else 4107 OS_MEMCPY(mptr, ahp->ah_cal_mem, mdata_size); 4108 #endif 4109 4110 if (mptr->eeprom_version == 0xff || 4111 mptr->template_version == 0xff || 4112 mptr->eeprom_version == 0 || 4113 mptr->template_version == 0) 4114 { 4115 /* The board is uncalibrated */ 4116 return -1; 4117 } 4118 if (mptr->eeprom_version != 0x2) 4119 { 4120 return -1; 4121 } 4122 4123 return mdata_size; 4124 4125 } 4126 4127 static int 4128 ar9300_eeprom_restore_from_flash(struct ath_hal *ah, ar9300_eeprom_t *mptr, 4129 int mdata_size) 4130 { 4131 struct ath_hal_9300 *ahp = AH9300(ah); 4132 char *cal_ptr; 4133 4134 HALASSERT(mdata_size > 0); 4135 4136 if (!ahp->ah_cal_mem) { 4137 return -1; 4138 } 4139 4140 ath_hal_printf(ah, "Restoring Cal data from Flash\n"); 4141 /* 4142 * When calibration data is saved in flash, read 4143 * uncompressed eeprom structure from flash and return 4144 */ 4145 cal_ptr = &((char *)(ahp->ah_cal_mem))[AR9300_FLASH_CAL_START_OFFSET]; 4146 OS_MEMCPY(mptr, cal_ptr, mdata_size); 4147 #if 0 4148 ar9300_swap_eeprom((ar9300_eeprom_t *)mptr); DONE IN ar9300_restore() 4149 #endif 4150 if (mptr->eeprom_version == 0xff || 4151 mptr->template_version == 0xff || 4152 mptr->eeprom_version == 0 || 4153 mptr->template_version == 0) 4154 { 4155 /* The board is uncalibrated */ 4156 return -1; 4157 } 4158 if (mptr->eeprom_version != 0x2) 4159 { 4160 return -1; 4161 } 4162 return mdata_size; 4163 } 4164 4165 /* 4166 * Read the configuration data from the storage. We try the order with: 4167 * EEPROM, Flash, OTP. If all of above failed, use the default template. 4168 * The data can be put in any specified memory buffer. 4169 * 4170 * Returns -1 on error. 4171 * Returns address of next memory location on success. 4172 */ 4173 int 4174 ar9300_eeprom_restore_internal(struct ath_hal *ah, ar9300_eeprom_t *mptr, 4175 int mdata_size) 4176 { 4177 int nptr; 4178 4179 nptr = -1; 4180 4181 if ((AH9300(ah)->calibration_data_try == calibration_data_none || 4182 AH9300(ah)->calibration_data_try == calibration_data_dram) && 4183 AH9300(ah)->try_dram && nptr < 0) 4184 { 4185 ath_hal_printf(ah, "Restoring Cal data from DRAM\n"); 4186 AH9300(ah)->calibration_data_source = calibration_data_dram; 4187 AH9300(ah)->calibration_data_source_address = 0; 4188 nptr = ar9300_eeprom_restore_from_dram(ah, mptr, mdata_size); 4189 if (nptr < 0) { 4190 AH9300(ah)->calibration_data_source = calibration_data_none; 4191 AH9300(ah)->calibration_data_source_address = 0; 4192 } 4193 } 4194 4195 if ((AH9300(ah)->calibration_data_try == calibration_data_none || 4196 AH9300(ah)->calibration_data_try == calibration_data_eeprom) && 4197 AH9300(ah)->try_eeprom && nptr < 0) 4198 { 4199 /* 4200 * need to look at highest eeprom address as well as at 4201 * base_address=0x3ff where we used to write the data 4202 */ 4203 ath_hal_printf(ah, "Restoring Cal data from EEPROM\n"); 4204 AH9300(ah)->calibration_data_source = calibration_data_eeprom; 4205 if (AH9300(ah)->calibration_data_try_address != 0) { 4206 AH9300(ah)->calibration_data_source_address = 4207 AH9300(ah)->calibration_data_try_address; 4208 nptr = ar9300_eeprom_restore_internal_address( 4209 ah, mptr, mdata_size, 4210 AH9300(ah)->calibration_data_source_address, 0xff); 4211 } else { 4212 AH9300(ah)->calibration_data_source_address = 4213 ar9300_eeprom_base_address(ah); 4214 nptr = ar9300_eeprom_restore_internal_address( 4215 ah, mptr, mdata_size, 4216 AH9300(ah)->calibration_data_source_address, 0xff); 4217 if (nptr < 0 && 4218 AH9300(ah)->calibration_data_source_address != base_address) 4219 { 4220 AH9300(ah)->calibration_data_source_address = base_address; 4221 nptr = ar9300_eeprom_restore_internal_address( 4222 ah, mptr, mdata_size, 4223 AH9300(ah)->calibration_data_source_address, 0xff); 4224 } 4225 } 4226 if (nptr < 0) { 4227 AH9300(ah)->calibration_data_source = calibration_data_none; 4228 AH9300(ah)->calibration_data_source_address = 0; 4229 } 4230 } 4231 4232 /* 4233 * ##### should be an ifdef test for any AP usage, 4234 * either in driver or in nart 4235 */ 4236 if ((AH9300(ah)->calibration_data_try == calibration_data_none || 4237 AH9300(ah)->calibration_data_try == calibration_data_flash) && 4238 AH9300(ah)->try_flash && nptr < 0) 4239 { 4240 ath_hal_printf(ah, "Restoring Cal data from Flash\n"); 4241 AH9300(ah)->calibration_data_source = calibration_data_flash; 4242 /* how are we supposed to set this for flash? */ 4243 AH9300(ah)->calibration_data_source_address = 0; 4244 nptr = ar9300_eeprom_restore_from_flash(ah, mptr, mdata_size); 4245 if (nptr < 0) { 4246 AH9300(ah)->calibration_data_source = calibration_data_none; 4247 AH9300(ah)->calibration_data_source_address = 0; 4248 } 4249 } 4250 4251 if ((AH9300(ah)->calibration_data_try == calibration_data_none || 4252 AH9300(ah)->calibration_data_try == calibration_data_otp) && 4253 AH9300(ah)->try_otp && nptr < 0) 4254 { 4255 ath_hal_printf(ah, "Restoring Cal data from OTP\n"); 4256 AH9300(ah)->calibration_data_source = calibration_data_otp; 4257 if (AH9300(ah)->calibration_data_try_address != 0) { 4258 AH9300(ah)->calibration_data_source_address = 4259 AH9300(ah)->calibration_data_try_address; 4260 } else { 4261 AH9300(ah)->calibration_data_source_address = 4262 ar9300_eeprom_base_address(ah); 4263 } 4264 nptr = ar9300_eeprom_restore_internal_address( 4265 ah, mptr, mdata_size, AH9300(ah)->calibration_data_source_address, 0); 4266 if (nptr < 0) { 4267 AH9300(ah)->calibration_data_source = calibration_data_none; 4268 AH9300(ah)->calibration_data_source_address = 0; 4269 } 4270 } 4271 4272 #ifdef ATH_CAL_NAND_FLASH 4273 if ((AH9300(ah)->calibration_data_try == calibration_data_none || 4274 AH9300(ah)->calibration_data_try == calibration_data_nand) && 4275 AH9300(ah)->try_nand && nptr < 0) 4276 { 4277 AH9300(ah)->calibration_data_source = calibration_data_nand; 4278 AH9300(ah)->calibration_data_source_address = ((unsigned int)(AH_PRIVATE(ah)->ah_st)) + base_address_nand; 4279 if(ar9300_calibration_data_read( 4280 ah, AH9300(ah)->calibration_data_source_address, 4281 (u_int8_t *)mptr, mdata_size) == AH_TRUE) 4282 { 4283 nptr = mdata_size; 4284 } 4285 /*nptr=ar9300EepromRestoreInternalAddress(ah, mptr, mdataSize, CalibrationDataSourceAddress);*/ 4286 if(nptr < 0) 4287 { 4288 AH9300(ah)->calibration_data_source = calibration_data_none; 4289 AH9300(ah)->calibration_data_source_address = 0; 4290 } 4291 } 4292 #endif 4293 if (nptr < 0) { 4294 ath_hal_printf(ah, "%s[%d] No vaid CAL, calling default template\n", 4295 __func__, __LINE__); 4296 nptr = ar9300_eeprom_restore_something(ah, mptr, mdata_size); 4297 } 4298 4299 return nptr; 4300 } 4301 4302 /******************************************************************************/ 4303 /*! 4304 ** \brief Eeprom Swapping Function 4305 ** 4306 ** This function will swap the contents of the "longer" EEPROM data items 4307 ** to ensure they are consistent with the endian requirements for the platform 4308 ** they are being compiled for 4309 ** 4310 ** \param eh Pointer to the EEPROM data structure 4311 ** \return N/A 4312 */ 4313 #if AH_BYTE_ORDER == AH_BIG_ENDIAN 4314 void 4315 ar9300_swap_eeprom(ar9300_eeprom_t *eep) 4316 { 4317 u_int32_t dword; 4318 u_int16_t word; 4319 int i; 4320 4321 word = __bswap16(eep->base_eep_header.reg_dmn[0]); 4322 eep->base_eep_header.reg_dmn[0] = word; 4323 4324 word = __bswap16(eep->base_eep_header.reg_dmn[1]); 4325 eep->base_eep_header.reg_dmn[1] = word; 4326 4327 dword = __bswap32(eep->base_eep_header.swreg); 4328 eep->base_eep_header.swreg = dword; 4329 4330 dword = __bswap32(eep->modal_header_2g.ant_ctrl_common); 4331 eep->modal_header_2g.ant_ctrl_common = dword; 4332 4333 dword = __bswap32(eep->modal_header_2g.ant_ctrl_common2); 4334 eep->modal_header_2g.ant_ctrl_common2 = dword; 4335 4336 dword = __bswap32(eep->modal_header_2g.paprd_rate_mask_ht20); 4337 eep->modal_header_2g.paprd_rate_mask_ht20 = dword; 4338 4339 dword = __bswap32(eep->modal_header_2g.paprd_rate_mask_ht40); 4340 eep->modal_header_2g.paprd_rate_mask_ht40 = dword; 4341 4342 dword = __bswap32(eep->modal_header_5g.ant_ctrl_common); 4343 eep->modal_header_5g.ant_ctrl_common = dword; 4344 4345 dword = __bswap32(eep->modal_header_5g.ant_ctrl_common2); 4346 eep->modal_header_5g.ant_ctrl_common2 = dword; 4347 4348 dword = __bswap32(eep->modal_header_5g.paprd_rate_mask_ht20); 4349 eep->modal_header_5g.paprd_rate_mask_ht20 = dword; 4350 4351 dword = __bswap32(eep->modal_header_5g.paprd_rate_mask_ht40); 4352 eep->modal_header_5g.paprd_rate_mask_ht40 = dword; 4353 4354 for (i = 0; i < OSPREY_MAX_CHAINS; i++) { 4355 word = __bswap16(eep->modal_header_2g.ant_ctrl_chain[i]); 4356 eep->modal_header_2g.ant_ctrl_chain[i] = word; 4357 4358 word = __bswap16(eep->modal_header_5g.ant_ctrl_chain[i]); 4359 eep->modal_header_5g.ant_ctrl_chain[i] = word; 4360 } 4361 } 4362 4363 void ar9300_eeprom_template_swap(void) 4364 { 4365 int it; 4366 ar9300_eeprom_t *dptr; 4367 4368 for (it = 0; it < ARRAY_LENGTH(default9300); it++) { 4369 dptr = ar9300_eeprom_struct_default(it); 4370 if (dptr != 0) { 4371 ar9300_swap_eeprom(dptr); 4372 } 4373 } 4374 } 4375 #endif 4376 4377 4378 /* 4379 * Restore the configuration structure by reading the eeprom. 4380 * This function destroys any existing in-memory structure content. 4381 */ 4382 HAL_BOOL 4383 ar9300_eeprom_restore(struct ath_hal *ah) 4384 { 4385 struct ath_hal_9300 *ahp = AH9300(ah); 4386 ar9300_eeprom_t *mptr; 4387 int mdata_size; 4388 HAL_BOOL status = AH_FALSE; 4389 4390 mptr = &ahp->ah_eeprom; 4391 mdata_size = ar9300_eeprom_struct_size(); 4392 4393 if (mptr != 0 && mdata_size > 0) { 4394 #if AH_BYTE_ORDER == AH_BIG_ENDIAN 4395 ar9300_eeprom_template_swap(); 4396 ar9300_swap_eeprom(mptr); 4397 #endif 4398 /* 4399 * At this point, mptr points to the eeprom data structure 4400 * in its "default" state. If this is big endian, swap the 4401 * data structures back to "little endian" form. 4402 */ 4403 if (ar9300_eeprom_restore_internal(ah, mptr, mdata_size) >= 0) { 4404 status = AH_TRUE; 4405 } 4406 4407 #if AH_BYTE_ORDER == AH_BIG_ENDIAN 4408 /* Second Swap, back to Big Endian */ 4409 ar9300_eeprom_template_swap(); 4410 ar9300_swap_eeprom(mptr); 4411 #endif 4412 4413 } 4414 ahp->ah_2g_paprd_rate_mask_ht40 = 4415 mptr->modal_header_2g.paprd_rate_mask_ht40; 4416 ahp->ah_2g_paprd_rate_mask_ht20 = 4417 mptr->modal_header_2g.paprd_rate_mask_ht20; 4418 ahp->ah_5g_paprd_rate_mask_ht40 = 4419 mptr->modal_header_5g.paprd_rate_mask_ht40; 4420 ahp->ah_5g_paprd_rate_mask_ht20 = 4421 mptr->modal_header_5g.paprd_rate_mask_ht20; 4422 return status; 4423 } 4424 4425 int32_t ar9300_thermometer_get(struct ath_hal *ah) 4426 { 4427 struct ath_hal_9300 *ahp = AH9300(ah); 4428 int thermometer; 4429 thermometer = 4430 (ahp->ah_eeprom.base_eep_header.misc_configuration >> 1) & 0x3; 4431 thermometer--; 4432 return thermometer; 4433 } 4434 4435 HAL_BOOL ar9300_thermometer_apply(struct ath_hal *ah) 4436 { 4437 int thermometer = ar9300_thermometer_get(ah); 4438 4439 /* ch0_RXTX4 */ 4440 /*#define AR_PHY_65NM_CH0_RXTX4 AR_PHY_65NM(ch0_RXTX4)*/ 4441 #define AR_PHY_65NM_CH1_RXTX4 AR_PHY_65NM(ch1_RXTX4) 4442 #define AR_PHY_65NM_CH2_RXTX4 AR_PHY_65NM(ch2_RXTX4) 4443 /*#define AR_PHY_65NM_CH0_RXTX4_THERM_ON 0x10000000*/ 4444 /*#define AR_PHY_65NM_CH0_RXTX4_THERM_ON_S 28*/ 4445 #define AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR_S 29 4446 #define AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR \ 4447 (0x1<<AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR_S) 4448 4449 if (thermometer < 0) { 4450 OS_REG_RMW_FIELD(ah, 4451 AR_PHY_65NM_CH0_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, 0); 4452 if (!AR_SREV_HORNET(ah) && !AR_SREV_POSEIDON(ah)) { 4453 OS_REG_RMW_FIELD(ah, 4454 AR_PHY_65NM_CH1_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, 0); 4455 if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah) && !AR_SREV_HONEYBEE(ah) ) { 4456 OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4, 4457 AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, 0); 4458 } 4459 } 4460 OS_REG_RMW_FIELD(ah, 4461 AR_PHY_65NM_CH0_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON, 0); 4462 if (!AR_SREV_HORNET(ah) && !AR_SREV_POSEIDON(ah)) { 4463 OS_REG_RMW_FIELD(ah, 4464 AR_PHY_65NM_CH1_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON, 0); 4465 if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah) && !AR_SREV_HONEYBEE(ah) ) { 4466 OS_REG_RMW_FIELD(ah, 4467 AR_PHY_65NM_CH2_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON, 0); 4468 } 4469 } 4470 } else { 4471 OS_REG_RMW_FIELD(ah, 4472 AR_PHY_65NM_CH0_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, 1); 4473 if (!AR_SREV_HORNET(ah) && !AR_SREV_POSEIDON(ah)) { 4474 OS_REG_RMW_FIELD(ah, 4475 AR_PHY_65NM_CH1_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, 1); 4476 if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah) && !AR_SREV_HONEYBEE(ah) ) { 4477 OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4, 4478 AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, 1); 4479 } 4480 } 4481 if (thermometer == 0) { 4482 OS_REG_RMW_FIELD(ah, 4483 AR_PHY_65NM_CH0_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON, 1); 4484 if (!AR_SREV_HORNET(ah) && !AR_SREV_POSEIDON(ah)) { 4485 OS_REG_RMW_FIELD(ah, 4486 AR_PHY_65NM_CH1_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON, 0); 4487 if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah) && !AR_SREV_HONEYBEE(ah) ) { 4488 OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4, 4489 AR_PHY_65NM_CH0_RXTX4_THERM_ON, 0); 4490 } 4491 } 4492 } else if (thermometer == 1) { 4493 OS_REG_RMW_FIELD(ah, 4494 AR_PHY_65NM_CH0_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON, 0); 4495 if (!AR_SREV_HORNET(ah) && !AR_SREV_POSEIDON(ah)) { 4496 OS_REG_RMW_FIELD(ah, 4497 AR_PHY_65NM_CH1_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON, 1); 4498 if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah) && !AR_SREV_HONEYBEE(ah) ) { 4499 OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4, 4500 AR_PHY_65NM_CH0_RXTX4_THERM_ON, 0); 4501 } 4502 } 4503 } else if (thermometer == 2) { 4504 OS_REG_RMW_FIELD(ah, 4505 AR_PHY_65NM_CH0_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON, 0); 4506 if (!AR_SREV_HORNET(ah) && !AR_SREV_POSEIDON(ah)) { 4507 OS_REG_RMW_FIELD(ah, 4508 AR_PHY_65NM_CH1_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON, 0); 4509 if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah) && !AR_SREV_HONEYBEE(ah) ) { 4510 OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4, 4511 AR_PHY_65NM_CH0_RXTX4_THERM_ON, 1); 4512 } 4513 } 4514 } 4515 } 4516 return AH_TRUE; 4517 } 4518 4519 static int32_t ar9300_tuning_caps_params_get(struct ath_hal *ah) 4520 { 4521 int tuning_caps_params; 4522 ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom; 4523 tuning_caps_params = eep->base_eep_header.params_for_tuning_caps[0]; 4524 return tuning_caps_params; 4525 } 4526 4527 /* 4528 * Read the tuning caps params from eeprom and set to correct register. 4529 * To regulation the frequency accuracy. 4530 */ 4531 HAL_BOOL ar9300_tuning_caps_apply(struct ath_hal *ah) 4532 { 4533 int tuning_caps_params; 4534 ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom; 4535 tuning_caps_params = ar9300_tuning_caps_params_get(ah); 4536 if ((eep->base_eep_header.feature_enable & 0x40) >> 6) { 4537 tuning_caps_params &= 0x7f; 4538 4539 if (AR_SREV_POSEIDON(ah) || AR_SREV_WASP(ah) || AR_SREV_HONEYBEE(ah)) { 4540 return true; 4541 } else if (AR_SREV_HORNET(ah)) { 4542 OS_REG_RMW_FIELD(ah, 4543 AR_HORNET_CH0_XTAL, AR_OSPREY_CHO_XTAL_CAPINDAC, 4544 tuning_caps_params); 4545 OS_REG_RMW_FIELD(ah, 4546 AR_HORNET_CH0_XTAL, AR_OSPREY_CHO_XTAL_CAPOUTDAC, 4547 tuning_caps_params); 4548 } else if (AR_SREV_SCORPION(ah)) { 4549 OS_REG_RMW_FIELD(ah, 4550 AR_SCORPION_CH0_XTAL, AR_OSPREY_CHO_XTAL_CAPINDAC, 4551 tuning_caps_params); 4552 OS_REG_RMW_FIELD(ah, 4553 AR_SCORPION_CH0_XTAL, AR_OSPREY_CHO_XTAL_CAPOUTDAC, 4554 tuning_caps_params); 4555 } else { 4556 OS_REG_RMW_FIELD(ah, 4557 AR_OSPREY_CH0_XTAL, AR_OSPREY_CHO_XTAL_CAPINDAC, 4558 tuning_caps_params); 4559 OS_REG_RMW_FIELD(ah, 4560 AR_OSPREY_CH0_XTAL, AR_OSPREY_CHO_XTAL_CAPOUTDAC, 4561 tuning_caps_params); 4562 } 4563 4564 } 4565 return AH_TRUE; 4566 } 4567 4568 /* 4569 * Read the tx_frame_to_xpa_on param from eeprom and apply the value to 4570 * correct register. 4571 */ 4572 HAL_BOOL ar9300_xpa_timing_control_apply(struct ath_hal *ah, HAL_BOOL is_2ghz) 4573 { 4574 u_int8_t xpa_timing_control; 4575 ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom; 4576 if ((eep->base_eep_header.feature_enable & 0x80) >> 7) { 4577 if (AR_SREV_OSPREY(ah) || AR_SREV_AR9580(ah) || AR_SREV_WASP(ah) || AR_SREV_HONEYBEE(ah)) { 4578 if (is_2ghz) { 4579 xpa_timing_control = eep->modal_header_2g.tx_frame_to_xpa_on; 4580 OS_REG_RMW_FIELD(ah, 4581 AR_PHY_XPA_TIMING_CTL, AR_PHY_XPA_TIMING_CTL_FRAME_XPAB_ON, 4582 xpa_timing_control); 4583 } else { 4584 xpa_timing_control = eep->modal_header_5g.tx_frame_to_xpa_on; 4585 OS_REG_RMW_FIELD(ah, 4586 AR_PHY_XPA_TIMING_CTL, AR_PHY_XPA_TIMING_CTL_FRAME_XPAA_ON, 4587 xpa_timing_control); 4588 } 4589 } 4590 } 4591 return AH_TRUE; 4592 } 4593 4594 4595 /* 4596 * Read the xLNA_bias_strength param from eeprom and apply the value to 4597 * correct register. 4598 */ 4599 HAL_BOOL ar9300_x_lNA_bias_strength_apply(struct ath_hal *ah, HAL_BOOL is_2ghz) 4600 { 4601 u_int8_t x_lNABias; 4602 u_int32_t value = 0; 4603 ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom; 4604 4605 if ((eep->base_eep_header.misc_configuration & 0x40) >> 6) { 4606 if (AR_SREV_OSPREY(ah)) { 4607 if (is_2ghz) { 4608 x_lNABias = eep->modal_header_2g.xLNA_bias_strength; 4609 } else { 4610 x_lNABias = eep->modal_header_5g.xLNA_bias_strength; 4611 } 4612 value = x_lNABias & ( 0x03 ); // bit0,1 for chain0 4613 OS_REG_RMW_FIELD(ah, 4614 AR_PHY_65NM_CH0_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS, value); 4615 value = (x_lNABias >> 2) & ( 0x03 ); // bit2,3 for chain1 4616 OS_REG_RMW_FIELD(ah, 4617 AR_PHY_65NM_CH1_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS, value); 4618 value = (x_lNABias >> 4) & ( 0x03 ); // bit4,5 for chain2 4619 OS_REG_RMW_FIELD(ah, 4620 AR_PHY_65NM_CH2_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS, value); 4621 } 4622 } 4623 return AH_TRUE; 4624 } 4625 4626 4627 /* 4628 * Read EEPROM header info and program the device for correct operation 4629 * given the channel value. 4630 */ 4631 HAL_BOOL 4632 ar9300_eeprom_set_board_values(struct ath_hal *ah, const struct ieee80211_channel *chan) 4633 { 4634 HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan); 4635 4636 ar9300_xpa_bias_level_apply(ah, IEEE80211_IS_CHAN_2GHZ(chan)); 4637 4638 ar9300_xpa_timing_control_apply(ah, IEEE80211_IS_CHAN_2GHZ(chan)); 4639 4640 ar9300_ant_ctrl_apply(ah, IEEE80211_IS_CHAN_2GHZ(chan)); 4641 ar9300_drive_strength_apply(ah); 4642 4643 ar9300_x_lNA_bias_strength_apply(ah, IEEE80211_IS_CHAN_2GHZ(chan)); 4644 4645 /* wait for Poseidon internal regular turnning */ 4646 /* for Hornet we move it before initPLL to avoid an access issue */ 4647 /* Function not used when EMULATION. */ 4648 if (!AR_SREV_HORNET(ah) && !AR_SREV_WASP(ah) && !AR_SREV_HONEYBEE(ah)) { 4649 ar9300_internal_regulator_apply(ah); 4650 } 4651 4652 ar9300_attenuation_apply(ah, ichan->channel); 4653 ar9300_quick_drop_apply(ah, ichan->channel); 4654 ar9300_thermometer_apply(ah); 4655 if(!AR_SREV_WASP(ah)) 4656 { 4657 ar9300_tuning_caps_apply(ah); 4658 } 4659 4660 ar9300_tx_end_to_xpab_off_apply(ah, ichan->channel); 4661 4662 return AH_TRUE; 4663 } 4664 4665 u_int8_t * 4666 ar9300_eeprom_get_spur_chans_ptr(struct ath_hal *ah, HAL_BOOL is_2ghz) 4667 { 4668 ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom; 4669 4670 if (is_2ghz) { 4671 return &(eep->modal_header_2g.spur_chans[0]); 4672 } else { 4673 return &(eep->modal_header_5g.spur_chans[0]); 4674 } 4675 } 4676 4677 static u_int8_t ar9300_eeprom_get_tx_gain_table_number_max(struct ath_hal *ah) 4678 { 4679 unsigned long tx_gain_table_max; 4680 tx_gain_table_max = OS_REG_READ_FIELD(ah, 4681 AR_PHY_TPC_7, AR_PHY_TPC_7_TX_GAIN_TABLE_MAX); 4682 return tx_gain_table_max; 4683 } 4684 4685 u_int8_t ar9300_eeprom_tx_gain_table_index_max_apply(struct ath_hal *ah, u_int16_t channel) 4686 { 4687 unsigned int index; 4688 ar9300_eeprom_t *ahp_Eeprom; 4689 struct ath_hal_9300 *ahp = AH9300(ah); 4690 4691 ahp_Eeprom = &ahp->ah_eeprom; 4692 4693 if (ahp_Eeprom->base_ext1.misc_enable == 0) 4694 return AH_FALSE; 4695 4696 if (channel < 4000) 4697 { 4698 index = ahp_Eeprom->modal_header_2g.tx_gain_cap; 4699 } 4700 else 4701 { 4702 index = ahp_Eeprom->modal_header_5g.tx_gain_cap; 4703 } 4704 4705 OS_REG_RMW_FIELD(ah, 4706 AR_PHY_TPC_7, AR_PHY_TPC_7_TX_GAIN_TABLE_MAX, index); 4707 return AH_TRUE; 4708 } 4709 4710 static u_int8_t ar9300_eeprom_get_pcdac_tx_gain_table_i(struct ath_hal *ah, 4711 int i, u_int8_t *pcdac) 4712 { 4713 unsigned long tx_gain; 4714 u_int8_t tx_gain_table_max; 4715 tx_gain_table_max = ar9300_eeprom_get_tx_gain_table_number_max(ah); 4716 if (i <= 0 || i > tx_gain_table_max) { 4717 *pcdac = 0; 4718 return AH_FALSE; 4719 } 4720 4721 tx_gain = OS_REG_READ(ah, AR_PHY_TXGAIN_TAB(1) + i * 4); 4722 *pcdac = ((tx_gain >> 24) & 0xff); 4723 return AH_TRUE; 4724 } 4725 4726 u_int8_t ar9300_eeprom_set_tx_gain_cap(struct ath_hal *ah, 4727 int *tx_gain_max) 4728 // pcdac read back from reg, read back value depends on reset 2GHz/5GHz ini 4729 // tx_gain_table, this function will be called twice after each 4730 // band's calibration. 4731 // after 2GHz cal, tx_gain_max[0] has 2GHz, calibration max txgain, 4732 // tx_gain_max[1]=-100 4733 // after 5GHz cal, tx_gain_max[0],tx_gain_max[1] have calibration 4734 // value for both band 4735 // reset is on 5GHz, reg reading from tx_gain_table is for 5GHz, 4736 // so program can't recalculate 2g.tx_gain_cap at this point. 4737 { 4738 int i = 0, ig, im = 0; 4739 u_int8_t pcdac = 0; 4740 u_int8_t tx_gain_table_max; 4741 ar9300_eeprom_t *ahp_Eeprom; 4742 struct ath_hal_9300 *ahp = AH9300(ah); 4743 4744 ahp_Eeprom = &ahp->ah_eeprom; 4745 4746 if (ahp_Eeprom->base_ext1.misc_enable == 0) 4747 return AH_FALSE; 4748 4749 tx_gain_table_max = ar9300_eeprom_get_tx_gain_table_number_max(ah); 4750 4751 for (i = 0; i < 2; i++) { 4752 if (tx_gain_max[i]>-100) { // -100 didn't cal that band. 4753 if ( i== 0) { 4754 if (tx_gain_max[1]>-100) { 4755 continue; 4756 // both band are calibrated, skip 2GHz 2g.tx_gain_cap reset 4757 } 4758 } 4759 for (ig = 1; ig <= tx_gain_table_max; ig++) { 4760 if (ah != 0 && ah->ah_reset != 0) 4761 { 4762 ar9300_eeprom_get_pcdac_tx_gain_table_i(ah, ig, &pcdac); 4763 if (pcdac >= tx_gain_max[i]) 4764 break; 4765 } 4766 } 4767 if (ig+1 <= tx_gain_table_max) { 4768 if (pcdac == tx_gain_max[i]) 4769 im = ig; 4770 else 4771 im = ig + 1; 4772 if (i == 0) { 4773 ahp_Eeprom->modal_header_2g.tx_gain_cap = im; 4774 } else { 4775 ahp_Eeprom->modal_header_5g.tx_gain_cap = im; 4776 } 4777 } else { 4778 if (i == 0) { 4779 ahp_Eeprom->modal_header_2g.tx_gain_cap = ig; 4780 } else { 4781 ahp_Eeprom->modal_header_5g.tx_gain_cap = ig; 4782 } 4783 } 4784 } 4785 } 4786 return AH_TRUE; 4787 } 4788