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 if (AR_SREV_POSEIDON(ah)) { 1647 xlan_gpio_cfg = ah->ah_config.ath_hal_ext_lna_ctl_gpio; 1648 if (xlan_gpio_cfg) { 1649 for (i = 0; i < 32; i++) { 1650 if (xlan_gpio_cfg & (1 << i)) { 1651 ath_hal_gpioCfgOutput(ah, i, 1652 HAL_GPIO_OUTPUT_MUX_PCIE_ATTENTION_LED); 1653 } 1654 } 1655 } 1656 } 1657 #define AR_SWITCH_TABLE_COM_ALL (0xffff) 1658 #define AR_SWITCH_TABLE_COM_ALL_S (0) 1659 #define AR_SWITCH_TABLE_COM_JUPITER_ALL (0xffffff) 1660 #define AR_SWITCH_TABLE_COM_JUPITER_ALL_S (0) 1661 #define AR_SWITCH_TABLE_COM_SCORPION_ALL (0xffffff) 1662 #define AR_SWITCH_TABLE_COM_SCORPION_ALL_S (0) 1663 #define AR_SWITCH_TABLE_COM_HONEYBEE_ALL (0xffffff) 1664 #define AR_SWITCH_TABLE_COM_HONEYBEE_ALL_S (0) 1665 #define AR_SWITCH_TABLE_COM_SPDT (0x00f00000) 1666 value = ar9300_ant_ctrl_common_get(ah, is_2ghz); 1667 if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) { 1668 if (AR_SREV_JUPITER_10(ah)) { 1669 /* Force SPDT setting for Jupiter 1.0 chips. */ 1670 value &= ~AR_SWITCH_TABLE_COM_SPDT; 1671 value |= 0x00100000; 1672 } 1673 OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, 1674 AR_SWITCH_TABLE_COM_JUPITER_ALL, value); 1675 } 1676 else if (AR_SREV_SCORPION(ah)) { 1677 OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, 1678 AR_SWITCH_TABLE_COM_SCORPION_ALL, value); 1679 } 1680 else if (AR_SREV_HONEYBEE(ah)) { 1681 OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, 1682 AR_SWITCH_TABLE_COM_HONEYBEE_ALL, value); 1683 } 1684 else { 1685 OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, 1686 AR_SWITCH_TABLE_COM_ALL, value); 1687 } 1688 /* 1689 * Jupiter2.0 defines new switch table for BT/WLAN, 1690 * here's new field name in WB222.ref for both 2G and 5G. 1691 * Register: [GLB_CONTROL] GLB_CONTROL (@0x20044) 1692 * 15:12 R/W SWITCH_TABLE_COM_SPDT_WLAN_RX SWITCH_TABLE_COM_SPDT_WLAN_RX 1693 * 11:8 R/W SWITCH_TABLE_COM_SPDT_WLAN_TX SWITCH_TABLE_COM_SPDT_WLAN_TX 1694 * 7:4 R/W SWITCH_TABLE_COM_SPDT_WLAN_IDLE SWITCH_TABLE_COM_SPDT_WLAN_IDLE 1695 */ 1696 #define AR_SWITCH_TABLE_COM_SPDT_ALL (0x0000fff0) 1697 #define AR_SWITCH_TABLE_COM_SPDT_ALL_S (4) 1698 if (AR_SREV_JUPITER_20_OR_LATER(ah) || AR_SREV_APHRODITE(ah)) { 1699 value = ar9300_switch_com_spdt_get(ah, is_2ghz); 1700 OS_REG_RMW_FIELD(ah, AR_GLB_CONTROL, 1701 AR_SWITCH_TABLE_COM_SPDT_ALL, value); 1702 1703 OS_REG_SET_BIT(ah, AR_GLB_CONTROL, 1704 AR_BTCOEX_CTRL_SPDT_ENABLE); 1705 //OS_REG_SET_BIT(ah, AR_GLB_CONTROL, 1706 // AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL); 1707 } 1708 1709 #define AR_SWITCH_TABLE_COM2_ALL (0xffffff) 1710 #define AR_SWITCH_TABLE_COM2_ALL_S (0) 1711 value = ar9300_ant_ctrl_common2_get(ah, is_2ghz); 1712 #if ATH_ANT_DIV_COMB 1713 if ( AR_SREV_POSEIDON(ah) && (ahp->ah_lna_div_use_bt_ant_enable == TRUE) ) { 1714 value &= ~AR_SWITCH_TABLE_COM2_ALL; 1715 value |= ah->ah_config.ath_hal_ant_ctrl_comm2g_switch_enable; 1716 HALDEBUG(ah, HAL_DEBUG_RESET, "%s: com2=0x%08x\n", __func__, value) 1717 } 1718 #endif /* ATH_ANT_DIV_COMB */ 1719 OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value); 1720 1721 #define AR_SWITCH_TABLE_ALL (0xfff) 1722 #define AR_SWITCH_TABLE_ALL_S (0) 1723 value = ar9300_ant_ctrl_chain_get(ah, 0, is_2ghz); 1724 OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_0, AR_SWITCH_TABLE_ALL, value); 1725 1726 if (!AR_SREV_HORNET(ah) && !AR_SREV_POSEIDON(ah) && !AR_SREV_APHRODITE(ah)) { 1727 value = ar9300_ant_ctrl_chain_get(ah, 1, is_2ghz); 1728 OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_1, AR_SWITCH_TABLE_ALL, value); 1729 1730 if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah) && !AR_SREV_HONEYBEE(ah)) { 1731 value = ar9300_ant_ctrl_chain_get(ah, 2, is_2ghz); 1732 OS_REG_RMW_FIELD(ah, 1733 AR_PHY_SWITCH_CHAIN_2, AR_SWITCH_TABLE_ALL, value); 1734 } 1735 } 1736 if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah)) { 1737 value = ar9300_eeprom_get(ahp, EEP_ANTDIV_control); 1738 /* main_lnaconf, alt_lnaconf, main_tb, alt_tb */ 1739 regval = OS_REG_READ(ah, AR_PHY_MC_GAIN_CTRL); 1740 regval &= (~ANT_DIV_CONTROL_ALL); /* clear bit 25~30 */ 1741 regval |= (value & 0x3f) << ANT_DIV_CONTROL_ALL_S; 1742 /* enable_lnadiv */ 1743 regval &= (~MULTICHAIN_GAIN_CTRL__ENABLE_ANT_DIV_LNADIV__MASK); 1744 regval |= ((value >> 6) & 0x1) << 1745 MULTICHAIN_GAIN_CTRL__ENABLE_ANT_DIV_LNADIV__SHIFT; 1746 #if ATH_ANT_DIV_COMB 1747 if ( AR_SREV_POSEIDON(ah) && (ahp->ah_lna_div_use_bt_ant_enable == TRUE) ) { 1748 regval |= ANT_DIV_ENABLE; 1749 } 1750 #endif /* ATH_ANT_DIV_COMB */ 1751 OS_REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval); 1752 1753 /* enable fast_div */ 1754 regval = OS_REG_READ(ah, AR_PHY_CCK_DETECT); 1755 regval &= (~BBB_SIG_DETECT__ENABLE_ANT_FAST_DIV__MASK); 1756 regval |= ((value >> 7) & 0x1) << 1757 BBB_SIG_DETECT__ENABLE_ANT_FAST_DIV__SHIFT; 1758 #if ATH_ANT_DIV_COMB 1759 if ( AR_SREV_POSEIDON(ah) && (ahp->ah_lna_div_use_bt_ant_enable == TRUE) ) { 1760 regval |= FAST_DIV_ENABLE; 1761 } 1762 #endif /* ATH_ANT_DIV_COMB */ 1763 OS_REG_WRITE(ah, AR_PHY_CCK_DETECT, regval); 1764 } 1765 1766 #if ATH_ANT_DIV_COMB 1767 if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON_11_OR_LATER(ah)) { 1768 if (pcap->halAntDivCombSupport) { 1769 /* If support DivComb, set MAIN to LNA1, ALT to LNA2 at beginning */ 1770 regval = OS_REG_READ(ah, AR_PHY_MC_GAIN_CTRL); 1771 /* clear bit 25~30 main_lnaconf, alt_lnaconf, main_tb, alt_tb */ 1772 regval &= (~(MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_LNACONF__MASK | 1773 MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_LNACONF__MASK | 1774 MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_GAINTB__MASK | 1775 MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_GAINTB__MASK)); 1776 regval |= (HAL_ANT_DIV_COMB_LNA1 << 1777 MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_LNACONF__SHIFT); 1778 regval |= (HAL_ANT_DIV_COMB_LNA2 << 1779 MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_LNACONF__SHIFT); 1780 OS_REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval); 1781 } 1782 1783 } 1784 #endif /* ATH_ANT_DIV_COMB */ 1785 if (AR_SREV_POSEIDON(ah) && ( ahp->ah_diversity_control == HAL_ANT_FIXED_A 1786 || ahp->ah_diversity_control == HAL_ANT_FIXED_B)) 1787 { 1788 u_int32_t reg_val = OS_REG_READ(ah, AR_PHY_MC_GAIN_CTRL); 1789 reg_val &= ~(MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_LNACONF__MASK | 1790 MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_LNACONF__MASK | 1791 MULTICHAIN_GAIN_CTRL__ANT_FAST_DIV_BIAS__MASK | 1792 MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_GAINTB__MASK | 1793 MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_GAINTB__MASK ); 1794 1795 switch (ahp->ah_diversity_control) { 1796 case HAL_ANT_FIXED_A: 1797 /* Enable first antenna only */ 1798 reg_val |= (HAL_ANT_DIV_COMB_LNA1 << 1799 MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_LNACONF__SHIFT); 1800 reg_val |= (HAL_ANT_DIV_COMB_LNA2 << 1801 MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_LNACONF__SHIFT); 1802 /* main/alt gain table and Fast Div Bias all set to 0 */ 1803 OS_REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, reg_val); 1804 regval = OS_REG_READ(ah, AR_PHY_CCK_DETECT); 1805 regval &= (~BBB_SIG_DETECT__ENABLE_ANT_FAST_DIV__MASK); 1806 OS_REG_WRITE(ah, AR_PHY_CCK_DETECT, regval); 1807 break; 1808 case HAL_ANT_FIXED_B: 1809 /* Enable second antenna only, after checking capability */ 1810 reg_val |= (HAL_ANT_DIV_COMB_LNA2 << 1811 MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_LNACONF__SHIFT); 1812 reg_val |= (HAL_ANT_DIV_COMB_LNA1 << 1813 MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_LNACONF__SHIFT); 1814 /* main/alt gain table and Fast Div all set to 0 */ 1815 OS_REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, reg_val); 1816 regval = OS_REG_READ(ah, AR_PHY_CCK_DETECT); 1817 regval &= (~BBB_SIG_DETECT__ENABLE_ANT_FAST_DIV__MASK); 1818 OS_REG_WRITE(ah, AR_PHY_CCK_DETECT, regval); 1819 /* For WB225, need to swith ANT2 from BT to Wifi 1820 * This will not affect HB125 LNA diversity feature. 1821 */ 1822 HALDEBUG(ah, HAL_DEBUG_RESET, "%s: com2=0x%08x\n", __func__, 1823 ah->ah_config.ath_hal_ant_ctrl_comm2g_switch_enable) 1824 OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, 1825 ah->ah_config.ath_hal_ant_ctrl_comm2g_switch_enable); 1826 break; 1827 default: 1828 break; 1829 } 1830 } 1831 return 0; 1832 } 1833 1834 static u_int16_t 1835 ar9300_attenuation_chain_get(struct ath_hal *ah, int chain, u_int16_t channel) 1836 { 1837 int32_t f[3], t[3]; 1838 u_int16_t value; 1839 ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom; 1840 if (chain >= 0 && chain < OSPREY_MAX_CHAINS) { 1841 if (channel < 4000) { 1842 return eep->modal_header_2g.xatten1_db[chain]; 1843 } else { 1844 if (eep->base_ext2.xatten1_db_low[chain] != 0) { 1845 t[0] = eep->base_ext2.xatten1_db_low[chain]; 1846 f[0] = 5180; 1847 t[1] = eep->modal_header_5g.xatten1_db[chain]; 1848 f[1] = 5500; 1849 t[2] = eep->base_ext2.xatten1_db_high[chain]; 1850 f[2] = 5785; 1851 value = interpolate(channel, f, t, 3); 1852 return value; 1853 } else { 1854 return eep->modal_header_5g.xatten1_db[chain]; 1855 } 1856 } 1857 } 1858 return 0; 1859 } 1860 1861 static u_int16_t 1862 ar9300_attenuation_margin_chain_get(struct ath_hal *ah, int chain, 1863 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_margin[chain]; 1871 } else { 1872 if (eep->base_ext2.xatten1_margin_low[chain] != 0) { 1873 t[0] = eep->base_ext2.xatten1_margin_low[chain]; 1874 f[0] = 5180; 1875 t[1] = eep->modal_header_5g.xatten1_margin[chain]; 1876 f[1] = 5500; 1877 t[2] = eep->base_ext2.xatten1_margin_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_margin[chain]; 1883 } 1884 } 1885 } 1886 return 0; 1887 } 1888 1889 #if 0 1890 HAL_BOOL ar9300_attenuation_apply(struct ath_hal *ah, u_int16_t channel) 1891 { 1892 u_int32_t value; 1893 // struct ath_hal_private *ahpriv = AH_PRIVATE(ah); 1894 1895 /* Test value. if 0 then attenuation is unused. Don't load anything. */ 1896 value = ar9300_attenuation_chain_get(ah, 0, channel); 1897 OS_REG_RMW_FIELD(ah, 1898 AR_PHY_EXT_ATTEN_CTL_0, AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value); 1899 value = ar9300_attenuation_margin_chain_get(ah, 0, channel); 1900 if (ar9300_rx_gain_index_get(ah) == 0 1901 && ah->ah_config.ath_hal_ext_atten_margin_cfg) 1902 { 1903 value = 5; 1904 } 1905 OS_REG_RMW_FIELD(ah, 1906 AR_PHY_EXT_ATTEN_CTL_0, AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN, value); 1907 1908 if (!AR_SREV_HORNET(ah) && !AR_SREV_POSEIDON(ah)) { 1909 value = ar9300_attenuation_chain_get(ah, 1, channel); 1910 OS_REG_RMW_FIELD(ah, 1911 AR_PHY_EXT_ATTEN_CTL_1, AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value); 1912 value = ar9300_attenuation_margin_chain_get(ah, 1, channel); 1913 OS_REG_RMW_FIELD(ah, 1914 AR_PHY_EXT_ATTEN_CTL_1, AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN, 1915 value); 1916 if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah)&& !AR_SREV_HONEYBEE(ah) ) { 1917 value = ar9300_attenuation_chain_get(ah, 2, channel); 1918 OS_REG_RMW_FIELD(ah, 1919 AR_PHY_EXT_ATTEN_CTL_2, AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value); 1920 value = ar9300_attenuation_margin_chain_get(ah, 2, channel); 1921 OS_REG_RMW_FIELD(ah, 1922 AR_PHY_EXT_ATTEN_CTL_2, AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN, 1923 value); 1924 } 1925 } 1926 return 0; 1927 } 1928 #endif 1929 HAL_BOOL 1930 ar9300_attenuation_apply(struct ath_hal *ah, u_int16_t channel) 1931 { 1932 int i; 1933 uint32_t value; 1934 uint32_t ext_atten_reg[3] = { 1935 AR_PHY_EXT_ATTEN_CTL_0, 1936 AR_PHY_EXT_ATTEN_CTL_1, 1937 AR_PHY_EXT_ATTEN_CTL_2 1938 }; 1939 1940 /* 1941 * If it's an AR9462 and we're receiving on the second 1942 * chain only, set the chain 0 details from chain 1 1943 * calibration. 1944 * 1945 * This is from ath9k. 1946 */ 1947 if (AR_SREV_JUPITER(ah) && (AH9300(ah)->ah_rx_chainmask == 0x2)) { 1948 value = ar9300_attenuation_chain_get(ah, 1, channel); 1949 OS_REG_RMW_FIELD(ah, ext_atten_reg[0], 1950 AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value); 1951 value = ar9300_attenuation_margin_chain_get(ah, 1, channel); 1952 OS_REG_RMW_FIELD(ah, ext_atten_reg[0], 1953 AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN, value); 1954 } 1955 1956 /* 1957 * Now, loop over the configured transmit chains and 1958 * load in the attenuation/margin settings as appropriate. 1959 */ 1960 for (i = 0; i < 3; i++) { 1961 if ((AH9300(ah)->ah_tx_chainmask & (1 << i)) == 0) 1962 continue; 1963 1964 value = ar9300_attenuation_chain_get(ah, i, channel); 1965 OS_REG_RMW_FIELD(ah, ext_atten_reg[i], 1966 AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, 1967 value); 1968 1969 if (AR_SREV_POSEIDON(ah) && 1970 (ar9300_rx_gain_index_get(ah) == 0) && 1971 ah->ah_config.ath_hal_ext_atten_margin_cfg) { 1972 value = 5; 1973 } else { 1974 value = ar9300_attenuation_margin_chain_get(ah, 0, 1975 channel); 1976 } 1977 1978 /* 1979 * I'm not sure why it's loading in this setting into 1980 * the chain 0 margin regardless of the current chain. 1981 */ 1982 if (ah->ah_config.ath_hal_min_gainidx) 1983 OS_REG_RMW_FIELD(ah, 1984 AR_PHY_EXT_ATTEN_CTL_0, 1985 AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN, 1986 value); 1987 1988 OS_REG_RMW_FIELD(ah, 1989 ext_atten_reg[i], 1990 AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN, 1991 value); 1992 } 1993 1994 return (0); 1995 } 1996 1997 1998 static u_int16_t ar9300_quick_drop_get(struct ath_hal *ah, 1999 int chain, u_int16_t channel) 2000 { 2001 int32_t f[3], t[3]; 2002 u_int16_t value; 2003 ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom; 2004 2005 if (channel < 4000) { 2006 return eep->modal_header_2g.quick_drop; 2007 } else { 2008 t[0] = eep->base_ext1.quick_drop_low; 2009 f[0] = 5180; 2010 t[1] = eep->modal_header_5g.quick_drop; 2011 f[1] = 5500; 2012 t[2] = eep->base_ext1.quick_drop_high; 2013 f[2] = 5785; 2014 value = interpolate(channel, f, t, 3); 2015 return value; 2016 } 2017 } 2018 2019 2020 static HAL_BOOL ar9300_quick_drop_apply(struct ath_hal *ah, u_int16_t channel) 2021 { 2022 ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom; 2023 u_int32_t value; 2024 // 2025 // Test value. if 0 then quickDrop is unused. Don't load anything. 2026 // 2027 if (eep->base_eep_header.misc_configuration & 0x10) 2028 { 2029 if (AR_SREV_OSPREY(ah) || AR_SREV_AR9580(ah) || AR_SREV_WASP(ah)) 2030 { 2031 value = ar9300_quick_drop_get(ah, 0, channel); 2032 OS_REG_RMW_FIELD(ah, AR_PHY_AGC, AR_PHY_AGC_QUICK_DROP, value); 2033 } 2034 } 2035 return 0; 2036 } 2037 2038 static u_int16_t ar9300_tx_end_to_xpa_off_get(struct ath_hal *ah, u_int16_t channel) 2039 { 2040 ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom; 2041 2042 if (channel < 4000) { 2043 return eep->modal_header_2g.tx_end_to_xpa_off; 2044 } else { 2045 return eep->modal_header_5g.tx_end_to_xpa_off; 2046 } 2047 } 2048 2049 static HAL_BOOL ar9300_tx_end_to_xpab_off_apply(struct ath_hal *ah, u_int16_t channel) 2050 { 2051 u_int32_t value; 2052 2053 value = ar9300_tx_end_to_xpa_off_get(ah, channel); 2054 /* Apply to both xpaa and xpab */ 2055 if (AR_SREV_OSPREY(ah) || AR_SREV_AR9580(ah) || AR_SREV_WASP(ah)) 2056 { 2057 OS_REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL, 2058 AR_PHY_XPA_TIMING_CTL_TX_END_XPAB_OFF, value); 2059 OS_REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL, 2060 AR_PHY_XPA_TIMING_CTL_TX_END_XPAA_OFF, value); 2061 } 2062 return 0; 2063 } 2064 2065 static int 2066 ar9300_eeprom_cal_pier_get(struct ath_hal *ah, int mode, int ipier, int ichain, 2067 int *pfrequency, int *pcorrection, int *ptemperature, int *pvoltage) 2068 { 2069 u_int8_t *p_cal_pier; 2070 OSP_CAL_DATA_PER_FREQ_OP_LOOP *p_cal_pier_struct; 2071 int is_2ghz; 2072 ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom; 2073 2074 if (ichain >= OSPREY_MAX_CHAINS) { 2075 HALDEBUG(ah, HAL_DEBUG_EEPROM, 2076 "%s: Invalid chain index, must be less than %d\n", 2077 __func__, OSPREY_MAX_CHAINS); 2078 return -1; 2079 } 2080 2081 if (mode) {/* 5GHz */ 2082 if (ipier >= OSPREY_NUM_5G_CAL_PIERS){ 2083 HALDEBUG(ah, HAL_DEBUG_EEPROM, 2084 "%s: Invalid 5GHz cal pier index, must be less than %d\n", 2085 __func__, OSPREY_NUM_5G_CAL_PIERS); 2086 return -1; 2087 } 2088 p_cal_pier = &(eep->cal_freq_pier_5g[ipier]); 2089 p_cal_pier_struct = &(eep->cal_pier_data_5g[ichain][ipier]); 2090 is_2ghz = 0; 2091 } else { 2092 if (ipier >= OSPREY_NUM_2G_CAL_PIERS){ 2093 HALDEBUG(ah, HAL_DEBUG_EEPROM, 2094 "%s: Invalid 2GHz cal pier index, must be less than %d\n", 2095 __func__, OSPREY_NUM_2G_CAL_PIERS); 2096 return -1; 2097 } 2098 2099 p_cal_pier = &(eep->cal_freq_pier_2g[ipier]); 2100 p_cal_pier_struct = &(eep->cal_pier_data_2g[ichain][ipier]); 2101 is_2ghz = 1; 2102 } 2103 *pfrequency = FBIN2FREQ(*p_cal_pier, is_2ghz); 2104 *pcorrection = p_cal_pier_struct->ref_power; 2105 *ptemperature = p_cal_pier_struct->temp_meas; 2106 *pvoltage = p_cal_pier_struct->volt_meas; 2107 return 0; 2108 } 2109 2110 /* 2111 * Apply the recorded correction values. 2112 */ 2113 static int 2114 ar9300_calibration_apply(struct ath_hal *ah, int frequency) 2115 { 2116 struct ath_hal_9300 *ahp = AH9300(ah); 2117 2118 int ichain, ipier, npier; 2119 int mode; 2120 int fdiff; 2121 int pfrequency, pcorrection, ptemperature, pvoltage; 2122 int bf, factor, plus; 2123 2124 int lfrequency[AR9300_MAX_CHAINS]; 2125 int hfrequency[AR9300_MAX_CHAINS]; 2126 2127 int lcorrection[AR9300_MAX_CHAINS]; 2128 int hcorrection[AR9300_MAX_CHAINS]; 2129 int correction[AR9300_MAX_CHAINS]; 2130 2131 int ltemperature[AR9300_MAX_CHAINS]; 2132 int htemperature[AR9300_MAX_CHAINS]; 2133 int temperature[AR9300_MAX_CHAINS]; 2134 2135 int lvoltage[AR9300_MAX_CHAINS]; 2136 int hvoltage[AR9300_MAX_CHAINS]; 2137 int voltage[AR9300_MAX_CHAINS]; 2138 2139 mode = (frequency >= 4000); 2140 npier = (mode) ? OSPREY_NUM_5G_CAL_PIERS : OSPREY_NUM_2G_CAL_PIERS; 2141 2142 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) { 2143 lfrequency[ichain] = 0; 2144 hfrequency[ichain] = 100000; 2145 } 2146 /* 2147 * identify best lower and higher frequency calibration measurement 2148 */ 2149 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) { 2150 for (ipier = 0; ipier < npier; ipier++) { 2151 if (ar9300_eeprom_cal_pier_get( 2152 ah, mode, ipier, ichain, 2153 &pfrequency, &pcorrection, &ptemperature, &pvoltage) == 0) 2154 { 2155 fdiff = frequency - pfrequency; 2156 /* 2157 * this measurement is higher than our desired frequency 2158 */ 2159 if (fdiff <= 0) { 2160 if (hfrequency[ichain] <= 0 || 2161 hfrequency[ichain] >= 100000 || 2162 fdiff > (frequency - hfrequency[ichain])) 2163 { 2164 /* 2165 * new best higher frequency measurement 2166 */ 2167 hfrequency[ichain] = pfrequency; 2168 hcorrection[ichain] = pcorrection; 2169 htemperature[ichain] = ptemperature; 2170 hvoltage[ichain] = pvoltage; 2171 } 2172 } 2173 if (fdiff >= 0) { 2174 if (lfrequency[ichain] <= 0 || 2175 fdiff < (frequency - lfrequency[ichain])) 2176 { 2177 /* 2178 * new best lower frequency measurement 2179 */ 2180 lfrequency[ichain] = pfrequency; 2181 lcorrection[ichain] = pcorrection; 2182 ltemperature[ichain] = ptemperature; 2183 lvoltage[ichain] = pvoltage; 2184 } 2185 } 2186 } 2187 } 2188 } 2189 /* interpolate */ 2190 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) { 2191 HALDEBUG(ah, HAL_DEBUG_EEPROM, 2192 "%s: ch=%d f=%d low=%d %d h=%d %d\n", 2193 __func__, ichain, frequency, 2194 lfrequency[ichain], lcorrection[ichain], 2195 hfrequency[ichain], hcorrection[ichain]); 2196 /* 2197 * they're the same, so just pick one 2198 */ 2199 if (hfrequency[ichain] == lfrequency[ichain]) { 2200 correction[ichain] = lcorrection[ichain]; 2201 voltage[ichain] = lvoltage[ichain]; 2202 temperature[ichain] = ltemperature[ichain]; 2203 } else if (frequency - lfrequency[ichain] < 1000) { 2204 /* the low frequency is good */ 2205 if (hfrequency[ichain] - frequency < 1000) { 2206 /* 2207 * The high frequency is good too - 2208 * interpolate with round off. 2209 */ 2210 int mult, div, diff; 2211 mult = frequency - lfrequency[ichain]; 2212 div = hfrequency[ichain] - lfrequency[ichain]; 2213 2214 diff = hcorrection[ichain] - lcorrection[ichain]; 2215 bf = 2 * diff * mult / div; 2216 plus = (bf % 2); 2217 factor = bf / 2; 2218 correction[ichain] = lcorrection[ichain] + factor + plus; 2219 2220 diff = htemperature[ichain] - ltemperature[ichain]; 2221 bf = 2 * diff * mult / div; 2222 plus = (bf % 2); 2223 factor = bf / 2; 2224 temperature[ichain] = ltemperature[ichain] + factor + plus; 2225 2226 diff = hvoltage[ichain] - lvoltage[ichain]; 2227 bf = 2 * diff * mult / div; 2228 plus = (bf % 2); 2229 factor = bf / 2; 2230 voltage[ichain] = lvoltage[ichain] + factor + plus; 2231 } else { 2232 /* only low is good, use it */ 2233 correction[ichain] = lcorrection[ichain]; 2234 temperature[ichain] = ltemperature[ichain]; 2235 voltage[ichain] = lvoltage[ichain]; 2236 } 2237 } else if (hfrequency[ichain] - frequency < 1000) { 2238 /* only high is good, use it */ 2239 correction[ichain] = hcorrection[ichain]; 2240 temperature[ichain] = htemperature[ichain]; 2241 voltage[ichain] = hvoltage[ichain]; 2242 } else { 2243 /* nothing is good, presume 0???? */ 2244 correction[ichain] = 0; 2245 temperature[ichain] = 0; 2246 voltage[ichain] = 0; 2247 } 2248 } 2249 2250 /* GreenTx isn't currently supported */ 2251 /* GreenTx */ 2252 if (ah->ah_config.ath_hal_sta_update_tx_pwr_enable) { 2253 if (AR_SREV_POSEIDON(ah)) { 2254 /* Get calibrated OLPC gain delta value for GreenTx */ 2255 ahp->ah_db2[POSEIDON_STORED_REG_G2_OLPC_OFFSET] = 2256 (u_int32_t) correction[0]; 2257 } 2258 } 2259 2260 ar9300_power_control_override( 2261 ah, frequency, correction, voltage, temperature); 2262 HALDEBUG(ah, HAL_DEBUG_EEPROM, 2263 "%s: for frequency=%d, calibration correction = %d %d %d\n", 2264 __func__, frequency, correction[0], correction[1], correction[2]); 2265 2266 return 0; 2267 } 2268 2269 int 2270 ar9300_power_control_override(struct ath_hal *ah, int frequency, 2271 int *correction, int *voltage, int *temperature) 2272 { 2273 int temp_slope = 0; 2274 int temp_slope_1 = 0; 2275 int temp_slope_2 = 0; 2276 ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom; 2277 int32_t f[8], t[8],t1[3], t2[3]; 2278 int i; 2279 2280 OS_REG_RMW(ah, AR_PHY_TPC_11_B0, 2281 (correction[0] << AR_PHY_TPC_OLPC_GAIN_DELTA_S), 2282 AR_PHY_TPC_OLPC_GAIN_DELTA); 2283 if (!AR_SREV_POSEIDON(ah)) { 2284 OS_REG_RMW(ah, AR_PHY_TPC_11_B1, 2285 (correction[1] << AR_PHY_TPC_OLPC_GAIN_DELTA_S), 2286 AR_PHY_TPC_OLPC_GAIN_DELTA); 2287 if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah) && !AR_SREV_HONEYBEE(ah) ) { 2288 OS_REG_RMW(ah, AR_PHY_TPC_11_B2, 2289 (correction[2] << AR_PHY_TPC_OLPC_GAIN_DELTA_S), 2290 AR_PHY_TPC_OLPC_GAIN_DELTA); 2291 } 2292 } 2293 /* 2294 * enable open loop power control on chip 2295 */ 2296 OS_REG_RMW(ah, AR_PHY_TPC_6_B0, 2297 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S), AR_PHY_TPC_6_ERROR_EST_MODE); 2298 if (!AR_SREV_POSEIDON(ah)) { 2299 OS_REG_RMW(ah, AR_PHY_TPC_6_B1, 2300 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S), AR_PHY_TPC_6_ERROR_EST_MODE); 2301 if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah) && !AR_SREV_HONEYBEE(ah) ) { 2302 OS_REG_RMW(ah, AR_PHY_TPC_6_B2, 2303 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S), 2304 AR_PHY_TPC_6_ERROR_EST_MODE); 2305 } 2306 } 2307 2308 /* 2309 * Enable temperature compensation 2310 * Need to use register names 2311 */ 2312 if (frequency < 4000) { 2313 temp_slope = eep->modal_header_2g.temp_slope; 2314 } else { 2315 if ((eep->base_eep_header.misc_configuration & 0x20) != 0) 2316 { 2317 for(i=0;i<8;i++) 2318 { 2319 t[i]=eep->base_ext1.tempslopextension[i]; 2320 f[i]=FBIN2FREQ(eep->cal_freq_pier_5g[i], 0); 2321 } 2322 temp_slope=interpolate(frequency,f,t,8); 2323 } 2324 else 2325 { 2326 if(!AR_SREV_SCORPION(ah)) { 2327 if (eep->base_ext2.temp_slope_low != 0) { 2328 t[0] = eep->base_ext2.temp_slope_low; 2329 f[0] = 5180; 2330 t[1] = eep->modal_header_5g.temp_slope; 2331 f[1] = 5500; 2332 t[2] = eep->base_ext2.temp_slope_high; 2333 f[2] = 5785; 2334 temp_slope = interpolate(frequency, f, t, 3); 2335 } else { 2336 temp_slope = eep->modal_header_5g.temp_slope; 2337 } 2338 } else { 2339 /* 2340 * Scorpion has individual chain tempslope values 2341 */ 2342 t[0] = eep->base_ext1.tempslopextension[2]; 2343 t1[0]= eep->base_ext1.tempslopextension[3]; 2344 t2[0]= eep->base_ext1.tempslopextension[4]; 2345 f[0] = 5180; 2346 t[1] = eep->modal_header_5g.temp_slope; 2347 t1[1]= eep->base_ext1.tempslopextension[0]; 2348 t2[1]= eep->base_ext1.tempslopextension[1]; 2349 f[1] = 5500; 2350 t[2] = eep->base_ext1.tempslopextension[5]; 2351 t1[2]= eep->base_ext1.tempslopextension[6]; 2352 t2[2]= eep->base_ext1.tempslopextension[7]; 2353 f[2] = 5785; 2354 temp_slope = interpolate(frequency, f, t, 3); 2355 temp_slope_1=interpolate(frequency, f, t1,3); 2356 temp_slope_2=interpolate(frequency, f, t2,3); 2357 } 2358 } 2359 } 2360 2361 if (!AR_SREV_SCORPION(ah) && !AR_SREV_HONEYBEE(ah)) { 2362 OS_REG_RMW_FIELD(ah, 2363 AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, temp_slope); 2364 } else { 2365 /*Scorpion and Honeybee has tempSlope register for each chain*/ 2366 /*Check whether temp_compensation feature is enabled or not*/ 2367 if (eep->base_eep_header.feature_enable & 0x1){ 2368 if(frequency < 4000) { 2369 if (((eep->base_eep_header.txrx_mask & 0xf0) >> 4) & 0x1) { 2370 OS_REG_RMW_FIELD(ah, 2371 AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, 2372 eep->base_ext2.temp_slope_low); 2373 } 2374 if (((eep->base_eep_header.txrx_mask & 0xf0) >> 4) & 0x2) { 2375 OS_REG_RMW_FIELD(ah, 2376 AR_SCORPION_PHY_TPC_19_B1, AR_PHY_TPC_19_ALPHA_THERM, 2377 temp_slope); 2378 } 2379 if (((eep->base_eep_header.txrx_mask & 0xf0) >> 4) & 0x4) { 2380 OS_REG_RMW_FIELD(ah, 2381 AR_SCORPION_PHY_TPC_19_B2, AR_PHY_TPC_19_ALPHA_THERM, 2382 eep->base_ext2.temp_slope_high); 2383 } 2384 } else { 2385 if (((eep->base_eep_header.txrx_mask & 0xf0) >> 4) & 0x1) { 2386 OS_REG_RMW_FIELD(ah, 2387 AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, 2388 temp_slope); 2389 } 2390 if (((eep->base_eep_header.txrx_mask & 0xf0) >> 4) & 0x2) { 2391 OS_REG_RMW_FIELD(ah, 2392 AR_SCORPION_PHY_TPC_19_B1, AR_PHY_TPC_19_ALPHA_THERM, 2393 temp_slope_1); 2394 } 2395 if (((eep->base_eep_header.txrx_mask & 0xf0) >> 4) & 0x4) { 2396 OS_REG_RMW_FIELD(ah, 2397 AR_SCORPION_PHY_TPC_19_B2, AR_PHY_TPC_19_ALPHA_THERM, 2398 temp_slope_2); 2399 } 2400 } 2401 }else { 2402 /* If temp compensation is not enabled, set all registers to 0*/ 2403 if (((eep->base_eep_header.txrx_mask & 0xf0) >> 4) & 0x1) { 2404 OS_REG_RMW_FIELD(ah, 2405 AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, 0); 2406 } 2407 if (((eep->base_eep_header.txrx_mask & 0xf0) >> 4) & 0x2) { 2408 OS_REG_RMW_FIELD(ah, 2409 AR_SCORPION_PHY_TPC_19_B1, AR_PHY_TPC_19_ALPHA_THERM, 0); 2410 } 2411 if (((eep->base_eep_header.txrx_mask & 0xf0) >> 4) & 0x4) { 2412 OS_REG_RMW_FIELD(ah, 2413 AR_SCORPION_PHY_TPC_19_B2, AR_PHY_TPC_19_ALPHA_THERM, 0); 2414 } 2415 } 2416 } 2417 OS_REG_RMW_FIELD(ah, 2418 AR_PHY_TPC_18, AR_PHY_TPC_18_THERM_CAL_VALUE, temperature[0]); 2419 2420 return 0; 2421 } 2422 2423 /************************************************************** 2424 * ar9300_eep_def_get_max_edge_power 2425 * 2426 * Find the maximum conformance test limit for the given channel and CTL info 2427 */ 2428 static inline u_int16_t 2429 ar9300_eep_def_get_max_edge_power(ar9300_eeprom_t *p_eep_data, u_int16_t freq, 2430 int idx, HAL_BOOL is_2ghz) 2431 { 2432 u_int16_t twice_max_edge_power = AR9300_MAX_RATE_POWER; 2433 u_int8_t *ctl_freqbin = is_2ghz ? 2434 &p_eep_data->ctl_freqbin_2G[idx][0] : 2435 &p_eep_data->ctl_freqbin_5G[idx][0]; 2436 u_int16_t num_edges = is_2ghz ? 2437 OSPREY_NUM_BAND_EDGES_2G : OSPREY_NUM_BAND_EDGES_5G; 2438 int i; 2439 2440 /* Get the edge power */ 2441 for (i = 0; (i < num_edges) && (ctl_freqbin[i] != AR9300_BCHAN_UNUSED); i++) 2442 { 2443 /* 2444 * If there's an exact channel match or an inband flag set 2445 * on the lower channel use the given rd_edge_power 2446 */ 2447 if (freq == fbin2freq(ctl_freqbin[i], is_2ghz)) { 2448 if (is_2ghz) { 2449 twice_max_edge_power = 2450 p_eep_data->ctl_power_data_2g[idx].ctl_edges[i].t_power; 2451 } else { 2452 twice_max_edge_power = 2453 p_eep_data->ctl_power_data_5g[idx].ctl_edges[i].t_power; 2454 } 2455 break; 2456 } else if ((i > 0) && (freq < fbin2freq(ctl_freqbin[i], is_2ghz))) { 2457 if (is_2ghz) { 2458 if (fbin2freq(ctl_freqbin[i - 1], 1) < freq && 2459 p_eep_data->ctl_power_data_2g[idx].ctl_edges[i - 1].flag) 2460 { 2461 twice_max_edge_power = 2462 p_eep_data->ctl_power_data_2g[idx]. 2463 ctl_edges[i - 1].t_power; 2464 } 2465 } else { 2466 if (fbin2freq(ctl_freqbin[i - 1], 0) < freq && 2467 p_eep_data->ctl_power_data_5g[idx].ctl_edges[i - 1].flag) 2468 { 2469 twice_max_edge_power = 2470 p_eep_data->ctl_power_data_5g[idx]. 2471 ctl_edges[i - 1].t_power; 2472 } 2473 } 2474 /* 2475 * Leave loop - no more affecting edges possible 2476 * in this monotonic increasing list 2477 */ 2478 break; 2479 } 2480 } 2481 /* 2482 * EV89475: EEPROM might contain 0 txpower in CTL table for certain 2483 * 2.4GHz channels. We workaround it by overwriting 60 (30 dBm) here. 2484 */ 2485 if (is_2ghz && (twice_max_edge_power == 0)) { 2486 twice_max_edge_power = 60; 2487 } 2488 2489 HALASSERT(twice_max_edge_power > 0); 2490 return twice_max_edge_power; 2491 } 2492 2493 HAL_BOOL 2494 ar9300_eeprom_set_power_per_rate_table( 2495 struct ath_hal *ah, 2496 ar9300_eeprom_t *p_eep_data, 2497 const struct ieee80211_channel *chan, 2498 u_int8_t *p_pwr_array, 2499 u_int16_t cfg_ctl, 2500 u_int16_t antenna_reduction, 2501 u_int16_t twice_max_regulatory_power, 2502 u_int16_t power_limit, 2503 u_int8_t chainmask) 2504 { 2505 /* Local defines to distinguish between extension and control CTL's */ 2506 #define EXT_ADDITIVE (0x8000) 2507 #define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE) 2508 #define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE) 2509 #define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE) 2510 #define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */ 2511 #define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10 /* 10*log10(3)*2 */ 2512 #define PWRINCR_3_TO_1_CHAIN 9 /* 10*log(3)*2 */ 2513 #define PWRINCR_3_TO_2_CHAIN 3 /* floor(10*log(3/2)*2) */ 2514 #define PWRINCR_2_TO_1_CHAIN 6 /* 10*log(2)*2 */ 2515 2516 static const u_int16_t tp_scale_reduction_table[5] = 2517 { 0, 3, 6, 9, AR9300_MAX_RATE_POWER }; 2518 int i; 2519 int16_t twice_largest_antenna; 2520 u_int16_t twice_antenna_reduction = 2*antenna_reduction ; 2521 int16_t scaled_power = 0, min_ctl_power, max_reg_allowed_power; 2522 #define SUB_NUM_CTL_MODES_AT_5G_40 2 /* excluding HT40, EXT-OFDM */ 2523 #define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */ 2524 u_int16_t ctl_modes_for11a[] = 2525 {CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40}; 2526 u_int16_t ctl_modes_for11g[] = 2527 {CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40}; 2528 u_int16_t num_ctl_modes, *p_ctl_mode, ctl_mode, freq; 2529 CHAN_CENTERS centers; 2530 int tx_chainmask; 2531 struct ath_hal_9300 *ahp = AH9300(ah); 2532 u_int8_t *ctl_index; 2533 u_int8_t ctl_num; 2534 u_int16_t twice_min_edge_power; 2535 u_int16_t twice_max_edge_power = AR9300_MAX_RATE_POWER; 2536 #ifdef AH_DEBUG 2537 HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan); 2538 #endif 2539 2540 if (chainmask) 2541 tx_chainmask = chainmask; 2542 else 2543 tx_chainmask = ahp->ah_tx_chainmaskopt ? 2544 ahp->ah_tx_chainmaskopt :ahp->ah_tx_chainmask; 2545 2546 ar9300_get_channel_centers(ah, chan, ¢ers); 2547 2548 #if 1 2549 if (IEEE80211_IS_CHAN_2GHZ(chan)) { 2550 ahp->twice_antenna_gain = p_eep_data->modal_header_2g.antenna_gain; 2551 } else { 2552 ahp->twice_antenna_gain = p_eep_data->modal_header_5g.antenna_gain; 2553 } 2554 2555 #else 2556 if (IEEE80211_IS_CHAN_2GHZ(chan)) { 2557 ahp->twice_antenna_gain = AH_MAX(p_eep_data->modal_header_2g.antenna_gain, 2558 AH_PRIVATE(ah)->ah_antenna_gain_2g); 2559 } else { 2560 ahp->twice_antenna_gain = AH_MAX(p_eep_data->modal_header_5g.antenna_gain, 2561 AH_PRIVATE(ah)->ah_antenna_gain_5g); 2562 } 2563 #endif 2564 2565 /* Save max allowed antenna gain to ease future lookups */ 2566 ahp->twice_antenna_reduction = twice_antenna_reduction; 2567 2568 /* Deduct antenna gain from EIRP to get the upper limit */ 2569 twice_largest_antenna = (int16_t)AH_MIN((twice_antenna_reduction - 2570 ahp->twice_antenna_gain), 0); 2571 max_reg_allowed_power = twice_max_regulatory_power + twice_largest_antenna; 2572 2573 /* Use ah_tp_scale - see bug 30070. */ 2574 if (AH_PRIVATE(ah)->ah_tpScale != HAL_TP_SCALE_MAX) { 2575 max_reg_allowed_power -= 2576 (tp_scale_reduction_table[(AH_PRIVATE(ah)->ah_tpScale)] * 2); 2577 } 2578 2579 scaled_power = AH_MIN(power_limit, max_reg_allowed_power); 2580 2581 /* 2582 * Reduce scaled Power by number of chains active to get to 2583 * per chain tx power level 2584 */ 2585 /* TODO: better value than these? */ 2586 switch (ar9300_get_ntxchains(tx_chainmask)) { 2587 case 1: 2588 ahp->upper_limit[0] = AH_MAX(0, scaled_power); 2589 break; 2590 case 2: 2591 scaled_power -= REDUCE_SCALED_POWER_BY_TWO_CHAIN; 2592 ahp->upper_limit[1] = AH_MAX(0, scaled_power); 2593 break; 2594 case 3: 2595 scaled_power -= REDUCE_SCALED_POWER_BY_THREE_CHAIN; 2596 ahp->upper_limit[2] = AH_MAX(0, scaled_power); 2597 break; 2598 default: 2599 HALASSERT(0); /* Unsupported number of chains */ 2600 } 2601 2602 scaled_power = AH_MAX(0, scaled_power); 2603 2604 /* Get target powers from EEPROM - our baseline for TX Power */ 2605 if (IEEE80211_IS_CHAN_2GHZ(chan)) { 2606 /* Setup for CTL modes */ 2607 /* CTL_11B, CTL_11G, CTL_2GHT20 */ 2608 num_ctl_modes = 2609 ARRAY_LENGTH(ctl_modes_for11g) - SUB_NUM_CTL_MODES_AT_2G_40; 2610 p_ctl_mode = ctl_modes_for11g; 2611 2612 if (IEEE80211_IS_CHAN_HT40(chan)) { 2613 num_ctl_modes = ARRAY_LENGTH(ctl_modes_for11g); /* All 2G CTL's */ 2614 } 2615 } else { 2616 /* Setup for CTL modes */ 2617 /* CTL_11A, CTL_5GHT20 */ 2618 num_ctl_modes = 2619 ARRAY_LENGTH(ctl_modes_for11a) - SUB_NUM_CTL_MODES_AT_5G_40; 2620 p_ctl_mode = ctl_modes_for11a; 2621 2622 if (IEEE80211_IS_CHAN_HT40(chan)) { 2623 num_ctl_modes = ARRAY_LENGTH(ctl_modes_for11a); /* All 5G CTL's */ 2624 } 2625 } 2626 2627 /* 2628 * For MIMO, need to apply regulatory caps individually across dynamically 2629 * running modes: CCK, OFDM, HT20, HT40 2630 * 2631 * The outer loop walks through each possible applicable runtime mode. 2632 * The inner loop walks through each ctl_index entry in EEPROM. 2633 * The ctl value is encoded as [7:4] == test group, [3:0] == test mode. 2634 * 2635 */ 2636 for (ctl_mode = 0; ctl_mode < num_ctl_modes; ctl_mode++) { 2637 HAL_BOOL is_ht40_ctl_mode = 2638 (p_ctl_mode[ctl_mode] == CTL_5GHT40) || 2639 (p_ctl_mode[ctl_mode] == CTL_2GHT40); 2640 if (is_ht40_ctl_mode) { 2641 freq = centers.synth_center; 2642 } else if (p_ctl_mode[ctl_mode] & EXT_ADDITIVE) { 2643 freq = centers.ext_center; 2644 } else { 2645 freq = centers.ctl_center; 2646 } 2647 2648 HALDEBUG(ah, HAL_DEBUG_POWER_MGMT, 2649 "LOOP-Mode ctl_mode %d < %d, " 2650 "is_ht40_ctl_mode %d, EXT_ADDITIVE %d\n", 2651 ctl_mode, num_ctl_modes, is_ht40_ctl_mode, 2652 (p_ctl_mode[ctl_mode] & EXT_ADDITIVE)); 2653 /* walk through each CTL index stored in EEPROM */ 2654 if (IEEE80211_IS_CHAN_2GHZ(chan)) { 2655 ctl_index = p_eep_data->ctl_index_2g; 2656 ctl_num = OSPREY_NUM_CTLS_2G; 2657 } else { 2658 ctl_index = p_eep_data->ctl_index_5g; 2659 ctl_num = OSPREY_NUM_CTLS_5G; 2660 } 2661 2662 for (i = 0; (i < ctl_num) && ctl_index[i]; i++) { 2663 HALDEBUG(ah, HAL_DEBUG_POWER_MGMT, 2664 " LOOP-Ctlidx %d: cfg_ctl 0x%2.2x p_ctl_mode 0x%2.2x " 2665 "ctl_index 0x%2.2x chan %d chanctl 0x%x\n", 2666 i, cfg_ctl, p_ctl_mode[ctl_mode], ctl_index[i], 2667 ichan->channel, ath_hal_getctl(ah, chan)); 2668 2669 2670 /* 2671 * compare test group from regulatory channel list 2672 * with test mode from p_ctl_mode list 2673 */ 2674 if ((((cfg_ctl & ~CTL_MODE_M) | 2675 (p_ctl_mode[ctl_mode] & CTL_MODE_M)) == ctl_index[i]) || 2676 (((cfg_ctl & ~CTL_MODE_M) | 2677 (p_ctl_mode[ctl_mode] & CTL_MODE_M)) == 2678 ((ctl_index[i] & CTL_MODE_M) | SD_NO_CTL))) 2679 { 2680 twice_min_edge_power = 2681 ar9300_eep_def_get_max_edge_power( 2682 p_eep_data, freq, i, IEEE80211_IS_CHAN_2GHZ(chan)); 2683 2684 HALDEBUG(ah, HAL_DEBUG_POWER_MGMT, 2685 " MATCH-EE_IDX %d: ch %d is2 %d " 2686 "2xMinEdge %d chainmask %d chains %d\n", 2687 i, freq, IEEE80211_IS_CHAN_2GHZ(chan), 2688 twice_min_edge_power, tx_chainmask, 2689 ar9300_get_ntxchains(tx_chainmask)); 2690 2691 if ((cfg_ctl & ~CTL_MODE_M) == SD_NO_CTL) { 2692 /* 2693 * Find the minimum of all CTL edge powers 2694 * that apply to this channel 2695 */ 2696 twice_max_edge_power = 2697 AH_MIN(twice_max_edge_power, twice_min_edge_power); 2698 } else { 2699 /* specific */ 2700 twice_max_edge_power = twice_min_edge_power; 2701 break; 2702 } 2703 } 2704 } 2705 2706 min_ctl_power = (u_int8_t)AH_MIN(twice_max_edge_power, scaled_power); 2707 2708 HALDEBUG(ah, HAL_DEBUG_POWER_MGMT, 2709 " SEL-Min ctl_mode %d p_ctl_mode %d " 2710 "2xMaxEdge %d sP %d min_ctl_pwr %d\n", 2711 ctl_mode, p_ctl_mode[ctl_mode], 2712 twice_max_edge_power, scaled_power, min_ctl_power); 2713 2714 /* Apply ctl mode to correct target power set */ 2715 switch (p_ctl_mode[ctl_mode]) { 2716 case CTL_11B: 2717 for (i = ALL_TARGET_LEGACY_1L_5L; i <= ALL_TARGET_LEGACY_11S; i++) { 2718 p_pwr_array[i] = 2719 (u_int8_t)AH_MIN(p_pwr_array[i], min_ctl_power); 2720 } 2721 break; 2722 case CTL_11A: 2723 case CTL_11G: 2724 for (i = ALL_TARGET_LEGACY_6_24; i <= ALL_TARGET_LEGACY_54; i++) { 2725 p_pwr_array[i] = 2726 (u_int8_t)AH_MIN(p_pwr_array[i], min_ctl_power); 2727 #ifdef ATH_BT_COEX 2728 if ((ahp->ah_bt_coex_config_type == HAL_BT_COEX_CFG_3WIRE) || 2729 (ahp->ah_bt_coex_config_type == HAL_BT_COEX_CFG_MCI)) 2730 { 2731 if ((ahp->ah_bt_coex_flag & HAL_BT_COEX_FLAG_LOWER_TX_PWR) 2732 && (ahp->ah_bt_wlan_isolation 2733 < HAL_BT_COEX_ISOLATION_FOR_NO_COEX)) 2734 { 2735 2736 u_int8_t reduce_pow; 2737 2738 reduce_pow = (HAL_BT_COEX_ISOLATION_FOR_NO_COEX 2739 - ahp->ah_bt_wlan_isolation) << 1; 2740 2741 if (reduce_pow <= p_pwr_array[i]) { 2742 p_pwr_array[i] -= reduce_pow; 2743 } 2744 } 2745 if ((ahp->ah_bt_coex_flag & 2746 HAL_BT_COEX_FLAG_LOW_ACK_PWR) && 2747 (i != ALL_TARGET_LEGACY_36) && 2748 (i != ALL_TARGET_LEGACY_48) && 2749 (i != ALL_TARGET_LEGACY_54) && 2750 (p_ctl_mode[ctl_mode] == CTL_11G)) 2751 { 2752 p_pwr_array[i] = 0; 2753 } 2754 } 2755 #endif 2756 } 2757 break; 2758 case CTL_5GHT20: 2759 case CTL_2GHT20: 2760 for (i = ALL_TARGET_HT20_0_8_16; i <= ALL_TARGET_HT20_23; i++) { 2761 p_pwr_array[i] = 2762 (u_int8_t)AH_MIN(p_pwr_array[i], min_ctl_power); 2763 #ifdef ATH_BT_COEX 2764 if (((ahp->ah_bt_coex_config_type == HAL_BT_COEX_CFG_3WIRE) || 2765 (ahp->ah_bt_coex_config_type == HAL_BT_COEX_CFG_MCI)) && 2766 (ahp->ah_bt_coex_flag & HAL_BT_COEX_FLAG_LOWER_TX_PWR) && 2767 (ahp->ah_bt_wlan_isolation 2768 < HAL_BT_COEX_ISOLATION_FOR_NO_COEX)) { 2769 2770 u_int8_t reduce_pow = (HAL_BT_COEX_ISOLATION_FOR_NO_COEX 2771 - ahp->ah_bt_wlan_isolation) << 1; 2772 2773 if (reduce_pow <= p_pwr_array[i]) { 2774 p_pwr_array[i] -= reduce_pow; 2775 } 2776 } 2777 #if ATH_SUPPORT_MCI 2778 else if ((ahp->ah_bt_coex_flag & 2779 HAL_BT_COEX_FLAG_MCI_MAX_TX_PWR) && 2780 (p_ctl_mode[ctl_mode] == CTL_2GHT20) && 2781 (ahp->ah_bt_coex_config_type == HAL_BT_COEX_CFG_MCI)) 2782 { 2783 u_int8_t max_pwr; 2784 2785 max_pwr = MS(mci_concur_tx_max_pwr[2][1], 2786 ATH_MCI_CONCUR_TX_LOWEST_PWR_MASK); 2787 if (p_pwr_array[i] > max_pwr) { 2788 p_pwr_array[i] = max_pwr; 2789 } 2790 } 2791 #endif 2792 #endif 2793 } 2794 break; 2795 case CTL_11B_EXT: 2796 #ifdef NOT_YET 2797 target_power_cck_ext.t_pow2x[0] = (u_int8_t) 2798 AH_MIN(target_power_cck_ext.t_pow2x[0], min_ctl_power); 2799 #endif /* NOT_YET */ 2800 break; 2801 case CTL_11A_EXT: 2802 case CTL_11G_EXT: 2803 #ifdef NOT_YET 2804 target_power_ofdm_ext.t_pow2x[0] = (u_int8_t) 2805 AH_MIN(target_power_ofdm_ext.t_pow2x[0], min_ctl_power); 2806 #endif /* NOT_YET */ 2807 break; 2808 case CTL_5GHT40: 2809 case CTL_2GHT40: 2810 for (i = ALL_TARGET_HT40_0_8_16; i <= ALL_TARGET_HT40_23; i++) { 2811 p_pwr_array[i] = (u_int8_t) 2812 AH_MIN(p_pwr_array[i], min_ctl_power); 2813 #ifdef ATH_BT_COEX 2814 if (((ahp->ah_bt_coex_config_type == HAL_BT_COEX_CFG_3WIRE) || 2815 (ahp->ah_bt_coex_config_type == HAL_BT_COEX_CFG_MCI)) && 2816 (ahp->ah_bt_coex_flag & HAL_BT_COEX_FLAG_LOWER_TX_PWR) && 2817 (ahp->ah_bt_wlan_isolation 2818 < HAL_BT_COEX_ISOLATION_FOR_NO_COEX)) { 2819 2820 u_int8_t reduce_pow = (HAL_BT_COEX_ISOLATION_FOR_NO_COEX 2821 - ahp->ah_bt_wlan_isolation) << 1; 2822 2823 if (reduce_pow <= p_pwr_array[i]) { 2824 p_pwr_array[i] -= reduce_pow; 2825 } 2826 } 2827 #if ATH_SUPPORT_MCI 2828 else if ((ahp->ah_bt_coex_flag & 2829 HAL_BT_COEX_FLAG_MCI_MAX_TX_PWR) && 2830 (p_ctl_mode[ctl_mode] == CTL_2GHT40) && 2831 (ahp->ah_bt_coex_config_type == HAL_BT_COEX_CFG_MCI)) 2832 { 2833 u_int8_t max_pwr; 2834 2835 max_pwr = MS(mci_concur_tx_max_pwr[3][1], 2836 ATH_MCI_CONCUR_TX_LOWEST_PWR_MASK); 2837 if (p_pwr_array[i] > max_pwr) { 2838 p_pwr_array[i] = max_pwr; 2839 } 2840 } 2841 #endif 2842 #endif 2843 } 2844 break; 2845 default: 2846 HALASSERT(0); 2847 break; 2848 } 2849 } /* end ctl mode checking */ 2850 2851 return AH_TRUE; 2852 #undef EXT_ADDITIVE 2853 #undef CTL_11A_EXT 2854 #undef CTL_11G_EXT 2855 #undef CTL_11B_EXT 2856 #undef REDUCE_SCALED_POWER_BY_TWO_CHAIN 2857 #undef REDUCE_SCALED_POWER_BY_THREE_CHAIN 2858 } 2859 2860 /************************************************************** 2861 * ar9300_eeprom_set_transmit_power 2862 * 2863 * Set the transmit power in the baseband for the given 2864 * operating channel and mode. 2865 */ 2866 HAL_STATUS 2867 ar9300_eeprom_set_transmit_power(struct ath_hal *ah, 2868 ar9300_eeprom_t *p_eep_data, const struct ieee80211_channel *chan, u_int16_t cfg_ctl, 2869 u_int16_t antenna_reduction, u_int16_t twice_max_regulatory_power, 2870 u_int16_t power_limit) 2871 { 2872 #define ABS(_x, _y) ((int)_x > (int)_y ? (int)_x - (int)_y : (int)_y - (int)_x) 2873 #define INCREASE_MAXPOW_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */ 2874 #define INCREASE_MAXPOW_BY_THREE_CHAIN 10 /* 10*log10(3)*2 */ 2875 u_int8_t target_power_val_t2[ar9300_rate_size]; 2876 u_int8_t target_power_val_t2_eep[ar9300_rate_size]; 2877 int16_t twice_array_gain = 0, max_power_level = 0; 2878 struct ath_hal_9300 *ahp = AH9300(ah); 2879 int i = 0; 2880 u_int32_t tmp_paprd_rate_mask = 0, *tmp_ptr = NULL; 2881 int paprd_scale_factor = 5; 2882 HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan); 2883 2884 u_int8_t *ptr_mcs_rate2power_table_index; 2885 u_int8_t mcs_rate2power_table_index_ht20[24] = 2886 { 2887 ALL_TARGET_HT20_0_8_16, 2888 ALL_TARGET_HT20_1_3_9_11_17_19, 2889 ALL_TARGET_HT20_1_3_9_11_17_19, 2890 ALL_TARGET_HT20_1_3_9_11_17_19, 2891 ALL_TARGET_HT20_4, 2892 ALL_TARGET_HT20_5, 2893 ALL_TARGET_HT20_6, 2894 ALL_TARGET_HT20_7, 2895 ALL_TARGET_HT20_0_8_16, 2896 ALL_TARGET_HT20_1_3_9_11_17_19, 2897 ALL_TARGET_HT20_1_3_9_11_17_19, 2898 ALL_TARGET_HT20_1_3_9_11_17_19, 2899 ALL_TARGET_HT20_12, 2900 ALL_TARGET_HT20_13, 2901 ALL_TARGET_HT20_14, 2902 ALL_TARGET_HT20_15, 2903 ALL_TARGET_HT20_0_8_16, 2904 ALL_TARGET_HT20_1_3_9_11_17_19, 2905 ALL_TARGET_HT20_1_3_9_11_17_19, 2906 ALL_TARGET_HT20_1_3_9_11_17_19, 2907 ALL_TARGET_HT20_20, 2908 ALL_TARGET_HT20_21, 2909 ALL_TARGET_HT20_22, 2910 ALL_TARGET_HT20_23 2911 }; 2912 2913 u_int8_t mcs_rate2power_table_index_ht40[24] = 2914 { 2915 ALL_TARGET_HT40_0_8_16, 2916 ALL_TARGET_HT40_1_3_9_11_17_19, 2917 ALL_TARGET_HT40_1_3_9_11_17_19, 2918 ALL_TARGET_HT40_1_3_9_11_17_19, 2919 ALL_TARGET_HT40_4, 2920 ALL_TARGET_HT40_5, 2921 ALL_TARGET_HT40_6, 2922 ALL_TARGET_HT40_7, 2923 ALL_TARGET_HT40_0_8_16, 2924 ALL_TARGET_HT40_1_3_9_11_17_19, 2925 ALL_TARGET_HT40_1_3_9_11_17_19, 2926 ALL_TARGET_HT40_1_3_9_11_17_19, 2927 ALL_TARGET_HT40_12, 2928 ALL_TARGET_HT40_13, 2929 ALL_TARGET_HT40_14, 2930 ALL_TARGET_HT40_15, 2931 ALL_TARGET_HT40_0_8_16, 2932 ALL_TARGET_HT40_1_3_9_11_17_19, 2933 ALL_TARGET_HT40_1_3_9_11_17_19, 2934 ALL_TARGET_HT40_1_3_9_11_17_19, 2935 ALL_TARGET_HT40_20, 2936 ALL_TARGET_HT40_21, 2937 ALL_TARGET_HT40_22, 2938 ALL_TARGET_HT40_23, 2939 }; 2940 2941 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 2942 "%s[%d] +++chan %d,cfgctl 0x%04x " 2943 "antenna_reduction 0x%04x, twice_max_regulatory_power 0x%04x " 2944 "power_limit 0x%04x\n", 2945 __func__, __LINE__, ichan->channel, cfg_ctl, 2946 antenna_reduction, twice_max_regulatory_power, power_limit); 2947 ar9300_set_target_power_from_eeprom(ah, ichan->channel, target_power_val_t2); 2948 2949 if (ar9300_eeprom_get(ahp, EEP_PAPRD_ENABLED)) { 2950 if (IEEE80211_IS_CHAN_2GHZ(chan)) { 2951 if (IEEE80211_IS_CHAN_HT40(chan)) { 2952 tmp_paprd_rate_mask = 2953 p_eep_data->modal_header_2g.paprd_rate_mask_ht40; 2954 tmp_ptr = &AH9300(ah)->ah_2g_paprd_rate_mask_ht40; 2955 } else { 2956 tmp_paprd_rate_mask = 2957 p_eep_data->modal_header_2g.paprd_rate_mask_ht20; 2958 tmp_ptr = &AH9300(ah)->ah_2g_paprd_rate_mask_ht20; 2959 } 2960 } else { 2961 if (IEEE80211_IS_CHAN_HT40(chan)) { 2962 tmp_paprd_rate_mask = 2963 p_eep_data->modal_header_5g.paprd_rate_mask_ht40; 2964 tmp_ptr = &AH9300(ah)->ah_5g_paprd_rate_mask_ht40; 2965 } else { 2966 tmp_paprd_rate_mask = 2967 p_eep_data->modal_header_5g.paprd_rate_mask_ht20; 2968 tmp_ptr = &AH9300(ah)->ah_5g_paprd_rate_mask_ht20; 2969 } 2970 } 2971 AH_PAPRD_GET_SCALE_FACTOR( 2972 paprd_scale_factor, p_eep_data, IEEE80211_IS_CHAN_2GHZ(chan), ichan->channel); 2973 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s[%d] paprd_scale_factor %d\n", 2974 __func__, __LINE__, paprd_scale_factor); 2975 /* PAPRD is not done yet, Scale down the EEP power */ 2976 if (IEEE80211_IS_CHAN_HT40(chan)) { 2977 ptr_mcs_rate2power_table_index = 2978 &mcs_rate2power_table_index_ht40[0]; 2979 } else { 2980 ptr_mcs_rate2power_table_index = 2981 &mcs_rate2power_table_index_ht20[0]; 2982 } 2983 if (! ichan->paprd_table_write_done) { 2984 for (i = 0; i < 24; i++) { 2985 /* PAPRD is done yet, so Scale down Power for PAPRD Rates*/ 2986 if (tmp_paprd_rate_mask & (1 << i)) { 2987 target_power_val_t2[ptr_mcs_rate2power_table_index[i]] -= 2988 paprd_scale_factor; 2989 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 2990 "%s[%d]: Chan %d " 2991 "Scale down target_power_val_t2[%d] = 0x%04x\n", 2992 __func__, __LINE__, 2993 ichan->channel, i, target_power_val_t2[i]); 2994 } 2995 } 2996 } else { 2997 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 2998 "%s[%d]: PAPRD Done No TGT PWR Scaling\n", __func__, __LINE__); 2999 } 3000 } 3001 3002 /* Save the Target power for future use */ 3003 OS_MEMCPY(target_power_val_t2_eep, target_power_val_t2, 3004 sizeof(target_power_val_t2)); 3005 ar9300_eeprom_set_power_per_rate_table(ah, p_eep_data, chan, 3006 target_power_val_t2, cfg_ctl, 3007 antenna_reduction, 3008 twice_max_regulatory_power, 3009 power_limit, 0); 3010 3011 /* Save this for quick lookup */ 3012 ahp->reg_dmn = ath_hal_getctl(ah, chan); 3013 3014 /* 3015 * Always use CDD/direct per rate power table for register based approach. 3016 * For FCC, CDD calculations should factor in the array gain, hence 3017 * this adjust call. ETSI and MKK does not have this requirement. 3018 */ 3019 if (is_reg_dmn_fcc(ahp->reg_dmn)) { 3020 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 3021 "%s: FCC regdomain, calling reg_txpower_cdd\n", 3022 __func__); 3023 ar9300_adjust_reg_txpower_cdd(ah, target_power_val_t2); 3024 } 3025 3026 if (ar9300_eeprom_get(ahp, EEP_PAPRD_ENABLED)) { 3027 for (i = 0; i < ar9300_rate_size; i++) { 3028 /* 3029 * EEPROM TGT PWR is not same as current TGT PWR, 3030 * so Disable PAPRD for this rate. 3031 * Some of APs might ask to reduce Target Power, 3032 * if target power drops significantly, 3033 * disable PAPRD for that rate. 3034 */ 3035 if (tmp_paprd_rate_mask & (1 << i)) { 3036 if (ABS(target_power_val_t2_eep[i], target_power_val_t2[i]) > 3037 paprd_scale_factor) 3038 { 3039 tmp_paprd_rate_mask &= ~(1 << i); 3040 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 3041 "%s: EEP TPC[%02d] 0x%08x " 3042 "Curr TPC[%02d] 0x%08x mask = 0x%08x\n", 3043 __func__, i, target_power_val_t2_eep[i], i, 3044 target_power_val_t2[i], tmp_paprd_rate_mask); 3045 } 3046 } 3047 3048 } 3049 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 3050 "%s: Chan %d After tmp_paprd_rate_mask = 0x%08x\n", 3051 __func__, ichan->channel, tmp_paprd_rate_mask); 3052 if (tmp_ptr) { 3053 *tmp_ptr = tmp_paprd_rate_mask; 3054 } 3055 } 3056 3057 /* Write target power array to registers */ 3058 ar9300_transmit_power_reg_write(ah, target_power_val_t2); 3059 3060 /* Write target power for self generated frames to the TPC register */ 3061 ar9300_selfgen_tpc_reg_write(ah, chan, target_power_val_t2); 3062 3063 /* GreenTx or Paprd */ 3064 if (ah->ah_config.ath_hal_sta_update_tx_pwr_enable || 3065 AH_PRIVATE(ah)->ah_caps.halPaprdEnabled) 3066 { 3067 if (AR_SREV_POSEIDON(ah)) { 3068 /*For HAL_RSSI_TX_POWER_NONE array*/ 3069 OS_MEMCPY(ahp->ah_default_tx_power, 3070 target_power_val_t2, 3071 sizeof(target_power_val_t2)); 3072 /* Get defautl tx related register setting for GreenTx */ 3073 /* Record OB/DB */ 3074 ahp->ah_ob_db1[POSEIDON_STORED_REG_OBDB] = 3075 OS_REG_READ(ah, AR_PHY_65NM_CH0_TXRF2); 3076 /* Record TPC settting */ 3077 ahp->ah_ob_db1[POSEIDON_STORED_REG_TPC] = 3078 OS_REG_READ(ah, AR_TPC); 3079 /* Record BB_powertx_rate9 setting */ 3080 ahp->ah_ob_db1[POSEIDON_STORED_REG_BB_PWRTX_RATE9] = 3081 OS_REG_READ(ah, AR_PHY_BB_POWERTX_RATE9); 3082 } 3083 } 3084 3085 /* 3086 * Return tx power used to iwconfig. 3087 * Since power is rate dependent, use one of the indices from the 3088 * AR9300_Rates enum to select an entry from target_power_val_t2[] 3089 * to report. 3090 * Currently returns the power for HT40 MCS 0, HT20 MCS 0, or OFDM 6 Mbps 3091 * as CCK power is less interesting (?). 3092 */ 3093 i = ALL_TARGET_LEGACY_6_24; /* legacy */ 3094 if (IEEE80211_IS_CHAN_HT40(chan)) { 3095 i = ALL_TARGET_HT40_0_8_16; /* ht40 */ 3096 } else if (IEEE80211_IS_CHAN_HT20(chan)) { 3097 i = ALL_TARGET_HT20_0_8_16; /* ht20 */ 3098 } 3099 max_power_level = target_power_val_t2[i]; 3100 /* Adjusting the ah_max_power_level based on chains and antennaGain*/ 3101 switch (ar9300_get_ntxchains(((ahp->ah_tx_chainmaskopt > 0) ? 3102 ahp->ah_tx_chainmaskopt : ahp->ah_tx_chainmask))) 3103 { 3104 case 1: 3105 break; 3106 case 2: 3107 twice_array_gain = (ahp->twice_antenna_gain >= ahp->twice_antenna_reduction)? 0: 3108 ((int16_t)AH_MIN((ahp->twice_antenna_reduction - 3109 (ahp->twice_antenna_gain + INCREASE_MAXPOW_BY_TWO_CHAIN)), 0)); 3110 /* Adjusting maxpower with antennaGain */ 3111 max_power_level -= twice_array_gain; 3112 /* Adjusting maxpower based on chain */ 3113 max_power_level += INCREASE_MAXPOW_BY_TWO_CHAIN; 3114 break; 3115 case 3: 3116 twice_array_gain = (ahp->twice_antenna_gain >= ahp->twice_antenna_reduction)? 0: 3117 ((int16_t)AH_MIN((ahp->twice_antenna_reduction - 3118 (ahp->twice_antenna_gain + INCREASE_MAXPOW_BY_THREE_CHAIN)), 0)); 3119 3120 /* Adjusting maxpower with antennaGain */ 3121 max_power_level -= twice_array_gain; 3122 /* Adjusting maxpower based on chain */ 3123 max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN; 3124 break; 3125 default: 3126 HALASSERT(0); /* Unsupported number of chains */ 3127 } 3128 AH_PRIVATE(ah)->ah_maxPowerLevel = (int8_t)max_power_level; 3129 3130 ar9300_calibration_apply(ah, ichan->channel); 3131 #undef ABS 3132 3133 /* Handle per packet TPC initializations */ 3134 if (ah->ah_config.ath_hal_desc_tpc) { 3135 /* Transmit Power per-rate per-chain are computed here. A separate 3136 * power table is maintained for different MIMO modes (i.e. TXBF ON, 3137 * STBC) to enable easy lookup during packet transmit. 3138 * The reason for maintaing each of these tables per chain is that 3139 * the transmit power used for different number of chains is different 3140 * depending on whether the power has been limited by the target power, 3141 * the regulatory domain or the CTL limits. 3142 */ 3143 u_int mode = ath_hal_get_curmode(ah, chan); 3144 u_int32_t val = 0; 3145 u_int8_t chainmasks[AR9300_MAX_CHAINS] = 3146 {OSPREY_1_CHAINMASK, OSPREY_2LOHI_CHAINMASK, OSPREY_3_CHAINMASK}; 3147 for (i = 0; i < AR9300_MAX_CHAINS; i++) { 3148 OS_MEMCPY(target_power_val_t2, target_power_val_t2_eep, 3149 sizeof(target_power_val_t2_eep)); 3150 ar9300_eeprom_set_power_per_rate_table(ah, p_eep_data, chan, 3151 target_power_val_t2, cfg_ctl, 3152 antenna_reduction, 3153 twice_max_regulatory_power, 3154 power_limit, chainmasks[i]); 3155 HALDEBUG(ah, HAL_DEBUG_POWER_MGMT, 3156 " Channel = %d Chainmask = %d, Upper Limit = [%2d.%1d dBm]\n", 3157 ichan->channel, i, ahp->upper_limit[i]/2, 3158 ahp->upper_limit[i]%2 * 5); 3159 ar9300_init_rate_txpower(ah, mode, chan, target_power_val_t2, 3160 chainmasks[i]); 3161 3162 } 3163 3164 /* Enable TPC */ 3165 OS_REG_WRITE(ah, AR_PHY_PWRTX_MAX, AR_PHY_PWRTX_MAX_TPC_ENABLE); 3166 /* 3167 * Disable per chain power reduction since we are already 3168 * accounting for this in our calculations 3169 */ 3170 val = OS_REG_READ(ah, AR_PHY_POWER_TX_SUB); 3171 if (AR_SREV_WASP(ah)) { 3172 OS_REG_WRITE(ah, AR_PHY_POWER_TX_SUB, 3173 val & AR_PHY_POWER_TX_SUB_2_DISABLE); 3174 } else { 3175 OS_REG_WRITE(ah, AR_PHY_POWER_TX_SUB, 3176 val & AR_PHY_POWER_TX_SUB_3_DISABLE); 3177 } 3178 } 3179 3180 return HAL_OK; 3181 } 3182 3183 /************************************************************** 3184 * ar9300_eeprom_set_addac 3185 * 3186 * Set the ADDAC from eeprom. 3187 */ 3188 void 3189 ar9300_eeprom_set_addac(struct ath_hal *ah, struct ieee80211_channel *chan) 3190 { 3191 3192 HALDEBUG(AH_NULL, HAL_DEBUG_UNMASKABLE, 3193 "FIXME: ar9300_eeprom_def_set_addac called\n"); 3194 #if 0 3195 MODAL_EEPDEF_HEADER *p_modal; 3196 struct ath_hal_9300 *ahp = AH9300(ah); 3197 ar9300_eeprom_t *eep = &ahp->ah_eeprom.def; 3198 u_int8_t biaslevel; 3199 3200 if (AH_PRIVATE(ah)->ah_macVersion != AR_SREV_VERSION_SOWL) { 3201 return; 3202 } 3203 3204 HALASSERT(owl_get_eepdef_ver(ahp) == AR9300_EEP_VER); 3205 3206 /* Xpa bias levels in eeprom are valid from rev 14.7 */ 3207 if (owl_get_eepdef_rev(ahp) < AR9300_EEP_MINOR_VER_7) { 3208 return; 3209 } 3210 3211 if (ahp->ah_emu_eeprom) { 3212 return; 3213 } 3214 3215 p_modal = &(eep->modal_header[IEEE80211_IS_CHAN_2GHZ(chan)]); 3216 3217 if (p_modal->xpa_bias_lvl != 0xff) { 3218 biaslevel = p_modal->xpa_bias_lvl; 3219 } else { 3220 /* Use freqeuncy specific xpa bias level */ 3221 u_int16_t reset_freq_bin, freq_bin, freq_count = 0; 3222 CHAN_CENTERS centers; 3223 3224 ar9300_get_channel_centers(ah, chan, ¢ers); 3225 3226 reset_freq_bin = FREQ2FBIN(centers.synth_center, IEEE80211_IS_CHAN_2GHZ(chan)); 3227 freq_bin = p_modal->xpa_bias_lvl_freq[0] & 0xff; 3228 biaslevel = (u_int8_t)(p_modal->xpa_bias_lvl_freq[0] >> 14); 3229 3230 freq_count++; 3231 3232 while (freq_count < 3) { 3233 if (p_modal->xpa_bias_lvl_freq[freq_count] == 0x0) { 3234 break; 3235 } 3236 3237 freq_bin = p_modal->xpa_bias_lvl_freq[freq_count] & 0xff; 3238 if (reset_freq_bin >= freq_bin) { 3239 biaslevel = 3240 (u_int8_t)(p_modal->xpa_bias_lvl_freq[freq_count] >> 14); 3241 } else { 3242 break; 3243 } 3244 freq_count++; 3245 } 3246 } 3247 3248 /* Apply bias level to the ADDAC values in the INI array */ 3249 if (IEEE80211_IS_CHAN_2GHZ(chan)) { 3250 INI_RA(&ahp->ah_ini_addac, 7, 1) = 3251 (INI_RA(&ahp->ah_ini_addac, 7, 1) & (~0x18)) | biaslevel << 3; 3252 } else { 3253 INI_RA(&ahp->ah_ini_addac, 6, 1) = 3254 (INI_RA(&ahp->ah_ini_addac, 6, 1) & (~0xc0)) | biaslevel << 6; 3255 } 3256 #endif 3257 } 3258 3259 u_int 3260 ar9300_eeprom_dump_support(struct ath_hal *ah, void **pp_e) 3261 { 3262 *pp_e = &(AH9300(ah)->ah_eeprom); 3263 return sizeof(ar9300_eeprom_t); 3264 } 3265 3266 u_int8_t 3267 ar9300_eeprom_get_num_ant_config(struct ath_hal_9300 *ahp, 3268 HAL_FREQ_BAND freq_band) 3269 { 3270 #if 0 3271 ar9300_eeprom_t *eep = &ahp->ah_eeprom.def; 3272 MODAL_EEPDEF_HEADER *p_modal = 3273 &(eep->modal_header[HAL_FREQ_BAND_2GHZ == freq_band]); 3274 BASE_EEPDEF_HEADER *p_base = &eep->base_eep_header; 3275 u_int8_t num_ant_config; 3276 3277 num_ant_config = 1; /* default antenna configuration */ 3278 3279 if (p_base->version >= 0x0E0D) { 3280 if (p_modal->use_ant1) { 3281 num_ant_config += 1; 3282 } 3283 } 3284 3285 return num_ant_config; 3286 #else 3287 return 1; 3288 #endif 3289 } 3290 3291 HAL_STATUS 3292 ar9300_eeprom_get_ant_cfg(struct ath_hal_9300 *ahp, 3293 const struct ieee80211_channel *chan, 3294 u_int8_t index, u_int16_t *config) 3295 { 3296 #if 0 3297 ar9300_eeprom_t *eep = &ahp->ah_eeprom.def; 3298 MODAL_EEPDEF_HEADER *p_modal = &(eep->modal_header[IEEE80211_IS_CHAN_2GHZ(chan)]); 3299 BASE_EEPDEF_HEADER *p_base = &eep->base_eep_header; 3300 3301 switch (index) { 3302 case 0: 3303 *config = p_modal->ant_ctrl_common & 0xFFFF; 3304 return HAL_OK; 3305 case 1: 3306 if (p_base->version >= 0x0E0D) { 3307 if (p_modal->use_ant1) { 3308 *config = ((p_modal->ant_ctrl_common & 0xFFFF0000) >> 16); 3309 return HAL_OK; 3310 } 3311 } 3312 break; 3313 default: 3314 break; 3315 } 3316 #endif 3317 return HAL_EINVAL; 3318 } 3319 3320 u_int8_t* 3321 ar9300_eeprom_get_cust_data(struct ath_hal_9300 *ahp) 3322 { 3323 return (u_int8_t *)ahp; 3324 } 3325 3326 #ifdef UNUSED 3327 static inline HAL_STATUS 3328 ar9300_check_eeprom(struct ath_hal *ah) 3329 { 3330 #if 0 3331 u_int32_t sum = 0, el; 3332 u_int16_t *eepdata; 3333 int i; 3334 struct ath_hal_9300 *ahp = AH9300(ah); 3335 HAL_BOOL need_swap = AH_FALSE; 3336 ar9300_eeprom_t *eep = (ar9300_eeprom_t *)&ahp->ah_eeprom.def; 3337 u_int16_t magic, magic2; 3338 int addr; 3339 u_int16_t temp; 3340 3341 /* 3342 ** We need to check the EEPROM data regardless of if it's in flash or 3343 ** in EEPROM. 3344 */ 3345 3346 if (!ahp->ah_priv.priv.ah_eeprom_read( 3347 ah, AR9300_EEPROM_MAGIC_OFFSET, &magic)) 3348 { 3349 HALDEBUG(ah, HAL_DEBUG_EEPROM, "%s: Reading Magic # failed\n", __func__); 3350 return AH_FALSE; 3351 } 3352 3353 HALDEBUG(ah, HAL_DEBUG_EEPROM, "%s: Read Magic = 0x%04X\n", __func__, magic); 3354 3355 if (!ar9300_eep_data_in_flash(ah)) { 3356 3357 if (magic != AR9300_EEPROM_MAGIC) { 3358 magic2 = SWAP16(magic); 3359 3360 if (magic2 == AR9300_EEPROM_MAGIC) { 3361 need_swap = AH_TRUE; 3362 eepdata = (u_int16_t *)(&ahp->ah_eeprom); 3363 3364 for (addr = 0; 3365 addr < sizeof(ar9300_eeprom_t) / sizeof(u_int16_t); 3366 addr++) 3367 { 3368 temp = SWAP16(*eepdata); 3369 *eepdata = temp; 3370 eepdata++; 3371 3372 HALDEBUG(ah, HAL_DEBUG_EEPROM_DUMP, "0x%04X ", *eepdata); 3373 if (((addr + 1) % 6) == 0) { 3374 HALDEBUG(ah, HAL_DEBUG_EEPROM_DUMP, "\n"); 3375 } 3376 } 3377 } else { 3378 HALDEBUG(ah, HAL_DEBUG_EEPROM, 3379 "Invalid EEPROM Magic. endianness missmatch.\n"); 3380 return HAL_EEBADSUM; 3381 } 3382 } 3383 } else { 3384 HALDEBUG(ah, HAL_DEBUG_EEPROM, 3385 "EEPROM being read from flash @0x%p\n", AH_PRIVATE(ah)->ah_st); 3386 } 3387 3388 HALDEBUG(ah, HAL_DEBUG_EEPROM, "need_swap = %s.\n", need_swap?"True":"False"); 3389 3390 if (need_swap) { 3391 el = SWAP16(ahp->ah_eeprom.def.base_eep_header.length); 3392 } else { 3393 el = ahp->ah_eeprom.def.base_eep_header.length; 3394 } 3395 3396 eepdata = (u_int16_t *)(&ahp->ah_eeprom.def); 3397 for (i = 0; 3398 i < AH_MIN(el, sizeof(ar9300_eeprom_t)) / sizeof(u_int16_t); 3399 i++) { 3400 sum ^= *eepdata++; 3401 } 3402 3403 if (need_swap) { 3404 /* 3405 * preddy: EEPROM endianness does not match. So change it 3406 * 8bit values in eeprom data structure does not need to be swapped 3407 * Only >8bits (16 & 32) values need to be swapped 3408 * If a new 16 or 32 bit field is added to the EEPROM contents, 3409 * please make sure to swap the field here 3410 */ 3411 u_int32_t integer, j; 3412 u_int16_t word; 3413 3414 HALDEBUG(ah, HAL_DEBUG_EEPROM, 3415 "EEPROM Endianness is not native.. Changing \n"); 3416 3417 /* convert Base Eep header */ 3418 word = SWAP16(eep->base_eep_header.length); 3419 eep->base_eep_header.length = word; 3420 3421 word = SWAP16(eep->base_eep_header.checksum); 3422 eep->base_eep_header.checksum = word; 3423 3424 word = SWAP16(eep->base_eep_header.version); 3425 eep->base_eep_header.version = word; 3426 3427 word = SWAP16(eep->base_eep_header.reg_dmn[0]); 3428 eep->base_eep_header.reg_dmn[0] = word; 3429 3430 word = SWAP16(eep->base_eep_header.reg_dmn[1]); 3431 eep->base_eep_header.reg_dmn[1] = word; 3432 3433 word = SWAP16(eep->base_eep_header.rf_silent); 3434 eep->base_eep_header.rf_silent = word; 3435 3436 word = SWAP16(eep->base_eep_header.blue_tooth_options); 3437 eep->base_eep_header.blue_tooth_options = word; 3438 3439 word = SWAP16(eep->base_eep_header.device_cap); 3440 eep->base_eep_header.device_cap = word; 3441 3442 /* convert Modal Eep header */ 3443 for (j = 0; j < ARRAY_LENGTH(eep->modal_header); j++) { 3444 MODAL_EEPDEF_HEADER *p_modal = &eep->modal_header[j]; 3445 integer = SWAP32(p_modal->ant_ctrl_common); 3446 p_modal->ant_ctrl_common = integer; 3447 3448 for (i = 0; i < AR9300_MAX_CHAINS; i++) { 3449 integer = SWAP32(p_modal->ant_ctrl_chain[i]); 3450 p_modal->ant_ctrl_chain[i] = integer; 3451 } 3452 3453 for (i = 0; i < AR9300_EEPROM_MODAL_SPURS; i++) { 3454 word = SWAP16(p_modal->spur_chans[i].spur_chan); 3455 p_modal->spur_chans[i].spur_chan = word; 3456 } 3457 } 3458 } 3459 3460 /* Check CRC - Attach should fail on a bad checksum */ 3461 if (sum != 0xffff || owl_get_eepdef_ver(ahp) != AR9300_EEP_VER || 3462 owl_get_eepdef_rev(ahp) < AR9300_EEP_NO_BACK_VER) { 3463 HALDEBUG(ah, HAL_DEBUG_EEPROM, 3464 "Bad EEPROM checksum 0x%x or revision 0x%04x\n", 3465 sum, owl_get_eepdef_ver(ahp)); 3466 return HAL_EEBADSUM; 3467 } 3468 #ifdef EEPROM_DUMP 3469 ar9300_eeprom_def_dump(ah, eep); 3470 #endif 3471 3472 #if 0 3473 #ifdef AH_AR9300_OVRD_TGT_PWR 3474 3475 /* 3476 * 14.4 EEPROM contains low target powers. 3477 * Hardcode until EEPROM > 14.4 3478 */ 3479 if (owl_get_eepdef_ver(ahp) == 14 && owl_get_eepdef_rev(ahp) <= 4) { 3480 MODAL_EEPDEF_HEADER *p_modal; 3481 3482 #ifdef EEPROM_DUMP 3483 HALDEBUG(ah, HAL_DEBUG_POWER_OVERRIDE, "Original Target Powers\n"); 3484 ar9300_eep_def_dump_tgt_power(ah, eep); 3485 #endif 3486 HALDEBUG(ah, HAL_DEBUG_POWER_OVERRIDE, 3487 "Override Target Powers. EEPROM Version is %d.%d, " 3488 "Device Type %d\n", 3489 owl_get_eepdef_ver(ahp), 3490 owl_get_eepdef_rev(ahp), 3491 eep->base_eep_header.device_type); 3492 3493 3494 ar9300_eep_def_override_tgt_power(ah, eep); 3495 3496 if (eep->base_eep_header.device_type == 5) { 3497 /* for xb72 only: improve transmit EVM for interop */ 3498 p_modal = &eep->modal_header[1]; 3499 p_modal->tx_frame_to_data_start = 0x23; 3500 p_modal->tx_frame_to_xpa_on = 0x23; 3501 p_modal->tx_frame_to_pa_on = 0x23; 3502 } 3503 3504 #ifdef EEPROM_DUMP 3505 HALDEBUG(ah, HAL_DEBUG_POWER_OVERRIDE, "Modified Target Powers\n"); 3506 ar9300_eep_def_dump_tgt_power(ah, eep); 3507 #endif 3508 } 3509 #endif /* AH_AR9300_OVRD_TGT_PWR */ 3510 #endif 3511 #endif 3512 return HAL_OK; 3513 } 3514 #endif 3515 3516 static u_int16_t 3517 ar9300_eeprom_get_spur_chan(struct ath_hal *ah, int i, HAL_BOOL is_2ghz) 3518 { 3519 u_int16_t spur_val = AR_NO_SPUR; 3520 #if 0 3521 struct ath_hal_9300 *ahp = AH9300(ah); 3522 ar9300_eeprom_t *eep = (ar9300_eeprom_t *)&ahp->ah_eeprom; 3523 3524 HALASSERT(i < AR_EEPROM_MODAL_SPURS ); 3525 3526 HALDEBUG(ah, HAL_DEBUG_ANI, 3527 "Getting spur idx %d is2Ghz. %d val %x\n", 3528 i, is_2ghz, 3529 AH_PRIVATE(ah)->ah_config.ath_hal_spur_chans[i][is_2ghz]); 3530 3531 switch (AH_PRIVATE(ah)->ah_config.ath_hal_spur_mode) { 3532 case SPUR_DISABLE: 3533 /* returns AR_NO_SPUR */ 3534 break; 3535 case SPUR_ENABLE_IOCTL: 3536 spur_val = AH_PRIVATE(ah)->ah_config.ath_hal_spur_chans[i][is_2ghz]; 3537 HALDEBUG(ah, HAL_DEBUG_ANI, 3538 "Getting spur val from new loc. %d\n", spur_val); 3539 break; 3540 case SPUR_ENABLE_EEPROM: 3541 spur_val = eep->modal_header[is_2ghz].spur_chans[i].spur_chan; 3542 break; 3543 3544 } 3545 #endif 3546 return spur_val; 3547 } 3548 3549 #ifdef UNUSED 3550 static inline HAL_BOOL 3551 ar9300_fill_eeprom(struct ath_hal *ah) 3552 { 3553 return ar9300_eeprom_restore(ah); 3554 } 3555 #endif 3556 3557 u_int16_t 3558 ar9300_eeprom_struct_size(void) 3559 { 3560 return sizeof(ar9300_eeprom_t); 3561 } 3562 3563 int ar9300_eeprom_struct_default_many(void) 3564 { 3565 return ARRAY_LENGTH(default9300); 3566 } 3567 3568 3569 ar9300_eeprom_t * 3570 ar9300_eeprom_struct_default(int default_index) 3571 { 3572 if (default_index >= 0 && 3573 default_index < ARRAY_LENGTH(default9300)) 3574 { 3575 return default9300[default_index]; 3576 } else { 3577 return 0; 3578 } 3579 } 3580 3581 ar9300_eeprom_t * 3582 ar9300_eeprom_struct_default_find_by_id(int id) 3583 { 3584 int it; 3585 3586 for (it = 0; it < ARRAY_LENGTH(default9300); it++) { 3587 if (default9300[it] != 0 && default9300[it]->template_version == id) { 3588 return default9300[it]; 3589 } 3590 } 3591 return 0; 3592 } 3593 3594 3595 HAL_BOOL 3596 ar9300_calibration_data_read_flash(struct ath_hal *ah, long address, 3597 u_int8_t *buffer, int many) 3598 { 3599 3600 if (((address) < 0) || ((address + many) > AR9300_EEPROM_SIZE - 1)) { 3601 return AH_FALSE; 3602 } 3603 return AH_FALSE; 3604 } 3605 3606 HAL_BOOL 3607 ar9300_calibration_data_read_eeprom(struct ath_hal *ah, long address, 3608 u_int8_t *buffer, int many) 3609 { 3610 int i; 3611 u_int8_t value[2]; 3612 unsigned long eep_addr; 3613 unsigned long byte_addr; 3614 u_int16_t *svalue; 3615 3616 if (((address) < 0) || ((address + many) > AR9300_EEPROM_SIZE)) { 3617 return AH_FALSE; 3618 } 3619 3620 for (i = 0; i < many; i++) { 3621 eep_addr = (u_int16_t) (address + i) / 2; 3622 byte_addr = (u_int16_t) (address + i) % 2; 3623 svalue = (u_int16_t *) value; 3624 if (! ath_hal_eepromRead(ah, eep_addr, svalue)) { 3625 HALDEBUG(ah, HAL_DEBUG_EEPROM, 3626 "%s: Unable to read eeprom region \n", __func__); 3627 return AH_FALSE; 3628 } 3629 buffer[i] = (*svalue >> (8 * byte_addr)) & 0xff; 3630 } 3631 return AH_TRUE; 3632 } 3633 3634 HAL_BOOL 3635 ar9300_calibration_data_read_otp(struct ath_hal *ah, long address, 3636 u_int8_t *buffer, int many, HAL_BOOL is_wifi) 3637 { 3638 int i; 3639 unsigned long eep_addr; 3640 unsigned long byte_addr; 3641 u_int32_t svalue; 3642 3643 if (((address) < 0) || ((address + many) > 0x400)) { 3644 return AH_FALSE; 3645 } 3646 3647 for (i = 0; i < many; i++) { 3648 eep_addr = (u_int16_t) (address + i) / 4; /* otp is 4 bytes long???? */ 3649 byte_addr = (u_int16_t) (address + i) % 4; 3650 if (!ar9300_otp_read(ah, eep_addr, &svalue, is_wifi)) { 3651 HALDEBUG(ah, HAL_DEBUG_EEPROM, 3652 "%s: Unable to read otp region \n", __func__); 3653 return AH_FALSE; 3654 } 3655 buffer[i] = (svalue >> (8 * byte_addr)) & 0xff; 3656 } 3657 return AH_TRUE; 3658 } 3659 3660 #ifdef ATH_CAL_NAND_FLASH 3661 HAL_BOOL 3662 ar9300_calibration_data_read_nand(struct ath_hal *ah, long address, 3663 u_int8_t *buffer, int many) 3664 { 3665 int ret_len; 3666 int ret_val = 1; 3667 3668 /* Calling OS based API to read NAND */ 3669 ret_val = OS_NAND_FLASH_READ(ATH_CAL_NAND_PARTITION, address, many, &ret_len, buffer); 3670 3671 return (ret_val ? AH_FALSE: AH_TRUE); 3672 } 3673 #endif 3674 3675 HAL_BOOL 3676 ar9300_calibration_data_read(struct ath_hal *ah, long address, 3677 u_int8_t *buffer, int many) 3678 { 3679 switch (AH9300(ah)->calibration_data_source) { 3680 case calibration_data_flash: 3681 return ar9300_calibration_data_read_flash(ah, address, buffer, many); 3682 case calibration_data_eeprom: 3683 return ar9300_calibration_data_read_eeprom(ah, address, buffer, many); 3684 case calibration_data_otp: 3685 return ar9300_calibration_data_read_otp(ah, address, buffer, many, 1); 3686 #ifdef ATH_CAL_NAND_FLASH 3687 case calibration_data_nand: 3688 return ar9300_calibration_data_read_nand(ah,address,buffer,many); 3689 #endif 3690 3691 } 3692 return AH_FALSE; 3693 } 3694 3695 3696 HAL_BOOL 3697 ar9300_calibration_data_read_array(struct ath_hal *ah, int address, 3698 u_int8_t *buffer, int many) 3699 { 3700 int it; 3701 3702 for (it = 0; it < many; it++) { 3703 (void)ar9300_calibration_data_read(ah, address - it, buffer + it, 1); 3704 } 3705 return AH_TRUE; 3706 } 3707 3708 3709 /* 3710 * the address where the first configuration block is written 3711 */ 3712 static const int base_address = 0x3ff; /* 1KB */ 3713 static const int base_address_512 = 0x1ff; /* 512Bytes */ 3714 3715 /* 3716 * the address where the NAND first configuration block is written 3717 */ 3718 #ifdef ATH_CAL_NAND_FLASH 3719 static const int base_address_nand = AR9300_FLASH_CAL_START_OFFSET; 3720 #endif 3721 3722 3723 /* 3724 * the lower limit on configuration data 3725 */ 3726 static const int low_limit = 0x040; 3727 3728 /* 3729 * returns size of the physical eeprom in bytes. 3730 * 1024 and 2048 are normal sizes. 3731 * 0 means there is no eeprom. 3732 */ 3733 int32_t 3734 ar9300_eeprom_size(struct ath_hal *ah) 3735 { 3736 u_int16_t data; 3737 /* 3738 * first we'll try for 4096 bytes eeprom 3739 */ 3740 if (ar9300_eeprom_read_word(ah, 2047, &data)) { 3741 if (data != 0) { 3742 return 4096; 3743 } 3744 } 3745 /* 3746 * then we'll try for 2048 bytes eeprom 3747 */ 3748 if (ar9300_eeprom_read_word(ah, 1023, &data)) { 3749 if (data != 0) { 3750 return 2048; 3751 } 3752 } 3753 /* 3754 * then we'll try for 1024 bytes eeprom 3755 */ 3756 if (ar9300_eeprom_read_word(ah, 511, &data)) { 3757 if (data != 0) { 3758 return 1024; 3759 } 3760 } 3761 return 0; 3762 } 3763 3764 /* 3765 * returns size of the physical otp in bytes. 3766 * 1024 and 2048 are normal sizes. 3767 * 0 means there is no eeprom. 3768 */ 3769 int32_t 3770 ar9300_otp_size(struct ath_hal *ah) 3771 { 3772 if (AR_SREV_POSEIDON(ah) || AR_SREV_HORNET(ah)) { 3773 return base_address_512+1; 3774 } else { 3775 return base_address+1; 3776 } 3777 } 3778 3779 3780 /* 3781 * find top of memory 3782 */ 3783 int 3784 ar9300_eeprom_base_address(struct ath_hal *ah) 3785 { 3786 int size; 3787 3788 if (AH9300(ah)->calibration_data_source == calibration_data_otp) { 3789 return ar9300_otp_size(ah)-1; 3790 } 3791 else 3792 { 3793 size = ar9300_eeprom_size(ah); 3794 if (size > 0) { 3795 return size - 1; 3796 } else { 3797 return ar9300_otp_size(ah)-1; 3798 } 3799 } 3800 } 3801 3802 int 3803 ar9300_eeprom_volatile(struct ath_hal *ah) 3804 { 3805 if (AH9300(ah)->calibration_data_source == calibration_data_otp) { 3806 return 0; /* no eeprom, use otp */ 3807 } else { 3808 return 1; /* board has eeprom or flash */ 3809 } 3810 } 3811 3812 /* 3813 * need to change this to look for the pcie data in the low parts of memory 3814 * cal data needs to stop a few locations above 3815 */ 3816 int 3817 ar9300_eeprom_low_limit(struct ath_hal *ah) 3818 { 3819 return low_limit; 3820 } 3821 3822 u_int16_t 3823 ar9300_compression_checksum(u_int8_t *data, int dsize) 3824 { 3825 int it; 3826 int checksum = 0; 3827 3828 for (it = 0; it < dsize; it++) { 3829 checksum += data[it]; 3830 checksum &= 0xffff; 3831 } 3832 3833 return checksum; 3834 } 3835 3836 int 3837 ar9300_compression_header_unpack(u_int8_t *best, int *code, int *reference, 3838 int *length, int *major, int *minor) 3839 { 3840 unsigned long value[4]; 3841 3842 value[0] = best[0]; 3843 value[1] = best[1]; 3844 value[2] = best[2]; 3845 value[3] = best[3]; 3846 *code = ((value[0] >> 5) & 0x0007); 3847 *reference = (value[0] & 0x001f) | ((value[1] >> 2) & 0x0020); 3848 *length = ((value[1] << 4) & 0x07f0) | ((value[2] >> 4) & 0x000f); 3849 *major = (value[2] & 0x000f); 3850 *minor = (value[3] & 0x00ff); 3851 3852 return 4; 3853 } 3854 3855 3856 static HAL_BOOL 3857 ar9300_uncompress_block(struct ath_hal *ah, u_int8_t *mptr, int mdata_size, 3858 u_int8_t *block, int size) 3859 { 3860 int it; 3861 int spot; 3862 int offset; 3863 int length; 3864 3865 spot = 0; 3866 for (it = 0; it < size; it += (length + 2)) { 3867 offset = block[it]; 3868 offset &= 0xff; 3869 spot += offset; 3870 length = block[it + 1]; 3871 length &= 0xff; 3872 if (length > 0 && spot >= 0 && spot + length <= mdata_size) { 3873 HALDEBUG(ah, HAL_DEBUG_EEPROM, 3874 "%s: Restore at %d: spot=%d offset=%d length=%d\n", 3875 __func__, it, spot, offset, length); 3876 OS_MEMCPY(&mptr[spot], &block[it + 2], length); 3877 spot += length; 3878 } else if (length > 0) { 3879 HALDEBUG(ah, HAL_DEBUG_EEPROM, 3880 "%s: Bad restore at %d: spot=%d offset=%d length=%d\n", 3881 __func__, it, spot, offset, length); 3882 return AH_FALSE; 3883 } 3884 } 3885 return AH_TRUE; 3886 } 3887 3888 static int 3889 ar9300_eeprom_restore_internal_address(struct ath_hal *ah, 3890 ar9300_eeprom_t *mptr, int mdata_size, int cptr, u_int8_t blank) 3891 { 3892 u_int8_t word[MOUTPUT]; 3893 ar9300_eeprom_t *dptr; /* was uint8 */ 3894 int code; 3895 int reference, length, major, minor; 3896 int osize; 3897 int it; 3898 int restored; 3899 u_int16_t checksum, mchecksum; 3900 3901 restored = 0; 3902 for (it = 0; it < MSTATE; it++) { 3903 (void) ar9300_calibration_data_read_array( 3904 ah, cptr, word, compression_header_length); 3905 if (word[0] == blank && word[1] == blank && word[2] == blank && word[3] == blank) 3906 { 3907 break; 3908 } 3909 ar9300_compression_header_unpack( 3910 word, &code, &reference, &length, &major, &minor); 3911 HALDEBUG(ah, HAL_DEBUG_EEPROM, 3912 "%s: Found block at %x: " 3913 "code=%d ref=%d length=%d major=%d minor=%d\n", 3914 __func__, cptr, code, reference, length, major, minor); 3915 #ifdef DONTUSE 3916 if (length >= 1024) { 3917 HALDEBUG(ah, HAL_DEBUG_EEPROM, "%s: Skipping bad header\n", __func__); 3918 cptr -= compression_header_length; 3919 continue; 3920 } 3921 #endif 3922 osize = length; 3923 (void) ar9300_calibration_data_read_array( 3924 ah, cptr, word, 3925 compression_header_length + osize + compression_checksum_length); 3926 checksum = ar9300_compression_checksum( 3927 &word[compression_header_length], length); 3928 mchecksum = 3929 word[compression_header_length + osize] | 3930 (word[compression_header_length + osize + 1] << 8); 3931 HALDEBUG(ah, HAL_DEBUG_EEPROM, 3932 "%s: checksum %x %x\n", __func__, checksum, mchecksum); 3933 if (checksum == mchecksum) { 3934 switch (code) { 3935 case _compress_none: 3936 if (length != mdata_size) { 3937 HALDEBUG(ah, HAL_DEBUG_EEPROM, 3938 "%s: EEPROM structure size mismatch " 3939 "memory=%d eeprom=%d\n", __func__, mdata_size, length); 3940 return -1; 3941 } 3942 OS_MEMCPY((u_int8_t *)mptr, 3943 (u_int8_t *)(word + compression_header_length), length); 3944 HALDEBUG(ah, HAL_DEBUG_EEPROM, 3945 "%s: restored eeprom %d: uncompressed, length %d\n", 3946 __func__, it, length); 3947 restored = 1; 3948 break; 3949 #ifdef UNUSED 3950 case _compress_lzma: 3951 if (reference == reference_current) { 3952 dptr = mptr; 3953 } else { 3954 dptr = (u_int8_t *)ar9300_eeprom_struct_default_find_by_id( 3955 reference); 3956 if (dptr == 0) { 3957 HALDEBUG(ah, HAL_DEBUG_EEPROM, 3958 "%s: Can't find reference eeprom struct %d\n", 3959 __func__, reference); 3960 goto done; 3961 } 3962 } 3963 usize = -1; 3964 if (usize != mdata_size) { 3965 HALDEBUG(ah, HAL_DEBUG_EEPROM, 3966 "%s: uncompressed data is wrong size %d %d\n", 3967 __func__, usize, mdata_size); 3968 goto done; 3969 } 3970 3971 for (ib = 0; ib < mdata_size; ib++) { 3972 mptr[ib] = dptr[ib] ^ word[ib + overhead]; 3973 } 3974 HALDEBUG(ah, HAL_DEBUG_EEPROM, 3975 "%s: restored eeprom %d: compressed, " 3976 "reference %d, length %d\n", 3977 __func__, it, reference, length); 3978 break; 3979 case _compress_pairs: 3980 if (reference == reference_current) { 3981 dptr = mptr; 3982 } else { 3983 dptr = (u_int8_t *)ar9300_eeprom_struct_default_find_by_id( 3984 reference); 3985 if (dptr == 0) { 3986 HALDEBUG(ah, HAL_DEBUG_EEPROM, 3987 "%s: Can't find the reference " 3988 "eeprom structure %d\n", 3989 __func__, reference); 3990 goto done; 3991 } 3992 } 3993 HALDEBUG(ah, HAL_DEBUG_EEPROM, 3994 "%s: restored eeprom %d: " 3995 "pairs, reference %d, length %d,\n", 3996 __func__, it, reference, length); 3997 break; 3998 #endif 3999 case _compress_block: 4000 if (reference == reference_current) { 4001 dptr = mptr; 4002 } else { 4003 dptr = ar9300_eeprom_struct_default_find_by_id(reference); 4004 if (dptr == 0) { 4005 HALDEBUG(ah, HAL_DEBUG_EEPROM, 4006 "%s: cant find reference eeprom struct %d\n", 4007 __func__, reference); 4008 break; 4009 } 4010 OS_MEMCPY(mptr, dptr, mdata_size); 4011 } 4012 4013 HALDEBUG(ah, HAL_DEBUG_EEPROM, 4014 "%s: restore eeprom %d: block, reference %d, length %d\n", 4015 __func__, it, reference, length); 4016 (void) ar9300_uncompress_block(ah, 4017 (u_int8_t *) mptr, mdata_size, 4018 (u_int8_t *) (word + compression_header_length), length); 4019 restored = 1; 4020 break; 4021 default: 4022 HALDEBUG(ah, HAL_DEBUG_EEPROM, 4023 "%s: unknown compression code %d\n", __func__, code); 4024 break; 4025 } 4026 } else { 4027 HALDEBUG(ah, HAL_DEBUG_EEPROM, 4028 "%s: skipping block with bad checksum\n", __func__); 4029 } 4030 cptr -= compression_header_length + osize + compression_checksum_length; 4031 } 4032 4033 if (!restored) { 4034 cptr = -1; 4035 } 4036 return cptr; 4037 } 4038 4039 static int 4040 ar9300_eeprom_restore_from_dram(struct ath_hal *ah, ar9300_eeprom_t *mptr, 4041 int mdata_size) 4042 { 4043 struct ath_hal_9300 *ahp = AH9300(ah); 4044 #if !defined(USE_PLATFORM_FRAMEWORK) 4045 char *cal_ptr; 4046 #endif 4047 4048 HALASSERT(mdata_size > 0); 4049 4050 /* if cal_in_flash is AH_TRUE, the address sent by LMAC to HAL 4051 (i.e. ah->ah_st) is corresponding to Flash. so return from 4052 here if ar9300_eep_data_in_flash(ah) returns AH_TRUE */ 4053 if(ar9300_eep_data_in_flash(ah)) 4054 return -1; 4055 4056 #if 0 4057 /* check if LMAC sent DRAM address is valid */ 4058 if (!(uintptr_t)(AH_PRIVATE(ah)->ah_st)) { 4059 return -1; 4060 } 4061 #endif 4062 4063 /* When calibration data is from host, Host will copy the 4064 compressed data to the predefined DRAM location saved at ah->ah_st */ 4065 #if 0 4066 ath_hal_printf(ah, "Restoring Cal data from DRAM\n"); 4067 ahp->ah_cal_mem = OS_REMAP((uintptr_t)(AH_PRIVATE(ah)->ah_st), 4068 HOST_CALDATA_SIZE); 4069 #endif 4070 if (!ahp->ah_cal_mem) 4071 { 4072 HALDEBUG(ah, HAL_DEBUG_EEPROM,"%s: can't remap dram region\n", __func__); 4073 return -1; 4074 } 4075 #if !defined(USE_PLATFORM_FRAMEWORK) 4076 cal_ptr = &((char *)(ahp->ah_cal_mem))[AR9300_FLASH_CAL_START_OFFSET]; 4077 OS_MEMCPY(mptr, cal_ptr, mdata_size); 4078 #else 4079 OS_MEMCPY(mptr, ahp->ah_cal_mem, mdata_size); 4080 #endif 4081 4082 if (mptr->eeprom_version == 0xff || 4083 mptr->template_version == 0xff || 4084 mptr->eeprom_version == 0 || 4085 mptr->template_version == 0) 4086 { 4087 /* The board is uncalibrated */ 4088 return -1; 4089 } 4090 if (mptr->eeprom_version != 0x2) 4091 { 4092 return -1; 4093 } 4094 4095 return mdata_size; 4096 4097 } 4098 4099 static int 4100 ar9300_eeprom_restore_from_flash(struct ath_hal *ah, ar9300_eeprom_t *mptr, 4101 int mdata_size) 4102 { 4103 struct ath_hal_9300 *ahp = AH9300(ah); 4104 char *cal_ptr; 4105 4106 HALASSERT(mdata_size > 0); 4107 4108 if (!ahp->ah_cal_mem) { 4109 return -1; 4110 } 4111 4112 ath_hal_printf(ah, "Restoring Cal data from Flash\n"); 4113 /* 4114 * When calibration data is saved in flash, read 4115 * uncompressed eeprom structure from flash and return 4116 */ 4117 cal_ptr = &((char *)(ahp->ah_cal_mem))[AR9300_FLASH_CAL_START_OFFSET]; 4118 OS_MEMCPY(mptr, cal_ptr, mdata_size); 4119 #if 0 4120 ar9300_swap_eeprom((ar9300_eeprom_t *)mptr); DONE IN ar9300_restore() 4121 #endif 4122 if (mptr->eeprom_version == 0xff || 4123 mptr->template_version == 0xff || 4124 mptr->eeprom_version == 0 || 4125 mptr->template_version == 0) 4126 { 4127 /* The board is uncalibrated */ 4128 return -1; 4129 } 4130 if (mptr->eeprom_version != 0x2) 4131 { 4132 return -1; 4133 } 4134 return mdata_size; 4135 } 4136 4137 /* 4138 * Read the configuration data from the storage. We try the order with: 4139 * EEPROM, Flash, OTP. If all of above failed, use the default template. 4140 * The data can be put in any specified memory buffer. 4141 * 4142 * Returns -1 on error. 4143 * Returns address of next memory location on success. 4144 */ 4145 int 4146 ar9300_eeprom_restore_internal(struct ath_hal *ah, ar9300_eeprom_t *mptr, 4147 int mdata_size) 4148 { 4149 int nptr; 4150 4151 nptr = -1; 4152 4153 if ((AH9300(ah)->calibration_data_try == calibration_data_none || 4154 AH9300(ah)->calibration_data_try == calibration_data_dram) && 4155 AH9300(ah)->try_dram && nptr < 0) 4156 { 4157 ath_hal_printf(ah, "Restoring Cal data from DRAM\n"); 4158 AH9300(ah)->calibration_data_source = calibration_data_dram; 4159 AH9300(ah)->calibration_data_source_address = 0; 4160 nptr = ar9300_eeprom_restore_from_dram(ah, mptr, mdata_size); 4161 if (nptr < 0) { 4162 AH9300(ah)->calibration_data_source = calibration_data_none; 4163 AH9300(ah)->calibration_data_source_address = 0; 4164 } 4165 } 4166 4167 if ((AH9300(ah)->calibration_data_try == calibration_data_none || 4168 AH9300(ah)->calibration_data_try == calibration_data_eeprom) && 4169 AH9300(ah)->try_eeprom && nptr < 0) 4170 { 4171 /* 4172 * need to look at highest eeprom address as well as at 4173 * base_address=0x3ff where we used to write the data 4174 */ 4175 ath_hal_printf(ah, "Restoring Cal data from EEPROM\n"); 4176 AH9300(ah)->calibration_data_source = calibration_data_eeprom; 4177 if (AH9300(ah)->calibration_data_try_address != 0) { 4178 AH9300(ah)->calibration_data_source_address = 4179 AH9300(ah)->calibration_data_try_address; 4180 nptr = ar9300_eeprom_restore_internal_address( 4181 ah, mptr, mdata_size, 4182 AH9300(ah)->calibration_data_source_address, 0xff); 4183 } else { 4184 AH9300(ah)->calibration_data_source_address = 4185 ar9300_eeprom_base_address(ah); 4186 nptr = ar9300_eeprom_restore_internal_address( 4187 ah, mptr, mdata_size, 4188 AH9300(ah)->calibration_data_source_address, 0xff); 4189 if (nptr < 0 && 4190 AH9300(ah)->calibration_data_source_address != base_address) 4191 { 4192 AH9300(ah)->calibration_data_source_address = base_address; 4193 nptr = ar9300_eeprom_restore_internal_address( 4194 ah, mptr, mdata_size, 4195 AH9300(ah)->calibration_data_source_address, 0xff); 4196 } 4197 } 4198 if (nptr < 0) { 4199 AH9300(ah)->calibration_data_source = calibration_data_none; 4200 AH9300(ah)->calibration_data_source_address = 0; 4201 } 4202 } 4203 4204 /* 4205 * ##### should be an ifdef test for any AP usage, 4206 * either in driver or in nart 4207 */ 4208 if ((AH9300(ah)->calibration_data_try == calibration_data_none || 4209 AH9300(ah)->calibration_data_try == calibration_data_flash) && 4210 AH9300(ah)->try_flash && nptr < 0) 4211 { 4212 ath_hal_printf(ah, "Restoring Cal data from Flash\n"); 4213 AH9300(ah)->calibration_data_source = calibration_data_flash; 4214 /* how are we supposed to set this for flash? */ 4215 AH9300(ah)->calibration_data_source_address = 0; 4216 nptr = ar9300_eeprom_restore_from_flash(ah, mptr, mdata_size); 4217 if (nptr < 0) { 4218 AH9300(ah)->calibration_data_source = calibration_data_none; 4219 AH9300(ah)->calibration_data_source_address = 0; 4220 } 4221 } 4222 4223 if ((AH9300(ah)->calibration_data_try == calibration_data_none || 4224 AH9300(ah)->calibration_data_try == calibration_data_otp) && 4225 AH9300(ah)->try_otp && nptr < 0) 4226 { 4227 ath_hal_printf(ah, "Restoring Cal data from OTP\n"); 4228 AH9300(ah)->calibration_data_source = calibration_data_otp; 4229 if (AH9300(ah)->calibration_data_try_address != 0) { 4230 AH9300(ah)->calibration_data_source_address = 4231 AH9300(ah)->calibration_data_try_address; 4232 } else { 4233 AH9300(ah)->calibration_data_source_address = 4234 ar9300_eeprom_base_address(ah); 4235 } 4236 nptr = ar9300_eeprom_restore_internal_address( 4237 ah, mptr, mdata_size, AH9300(ah)->calibration_data_source_address, 0); 4238 if (nptr < 0) { 4239 AH9300(ah)->calibration_data_source = calibration_data_none; 4240 AH9300(ah)->calibration_data_source_address = 0; 4241 } 4242 } 4243 4244 #ifdef ATH_CAL_NAND_FLASH 4245 if ((AH9300(ah)->calibration_data_try == calibration_data_none || 4246 AH9300(ah)->calibration_data_try == calibration_data_nand) && 4247 AH9300(ah)->try_nand && nptr < 0) 4248 { 4249 AH9300(ah)->calibration_data_source = calibration_data_nand; 4250 AH9300(ah)->calibration_data_source_address = ((unsigned int)(AH_PRIVATE(ah)->ah_st)) + base_address_nand; 4251 if(ar9300_calibration_data_read( 4252 ah, AH9300(ah)->calibration_data_source_address, 4253 (u_int8_t *)mptr, mdata_size) == AH_TRUE) 4254 { 4255 nptr = mdata_size; 4256 } 4257 /*nptr=ar9300EepromRestoreInternalAddress(ah, mptr, mdataSize, CalibrationDataSourceAddress);*/ 4258 if(nptr < 0) 4259 { 4260 AH9300(ah)->calibration_data_source = calibration_data_none; 4261 AH9300(ah)->calibration_data_source_address = 0; 4262 } 4263 } 4264 #endif 4265 if (nptr < 0) { 4266 ath_hal_printf(ah, "%s[%d] No vaid CAL, calling default template\n", 4267 __func__, __LINE__); 4268 nptr = ar9300_eeprom_restore_something(ah, mptr, mdata_size); 4269 } 4270 4271 return nptr; 4272 } 4273 4274 /******************************************************************************/ 4275 /*! 4276 ** \brief Eeprom Swapping Function 4277 ** 4278 ** This function will swap the contents of the "longer" EEPROM data items 4279 ** to ensure they are consistent with the endian requirements for the platform 4280 ** they are being compiled for 4281 ** 4282 ** \param eh Pointer to the EEPROM data structure 4283 ** \return N/A 4284 */ 4285 #if AH_BYTE_ORDER == AH_BIG_ENDIAN 4286 void 4287 ar9300_swap_eeprom(ar9300_eeprom_t *eep) 4288 { 4289 u_int32_t dword; 4290 u_int16_t word; 4291 int i; 4292 4293 word = __bswap16(eep->base_eep_header.reg_dmn[0]); 4294 eep->base_eep_header.reg_dmn[0] = word; 4295 4296 word = __bswap16(eep->base_eep_header.reg_dmn[1]); 4297 eep->base_eep_header.reg_dmn[1] = word; 4298 4299 dword = __bswap32(eep->base_eep_header.swreg); 4300 eep->base_eep_header.swreg = dword; 4301 4302 dword = __bswap32(eep->modal_header_2g.ant_ctrl_common); 4303 eep->modal_header_2g.ant_ctrl_common = dword; 4304 4305 dword = __bswap32(eep->modal_header_2g.ant_ctrl_common2); 4306 eep->modal_header_2g.ant_ctrl_common2 = dword; 4307 4308 dword = __bswap32(eep->modal_header_2g.paprd_rate_mask_ht20); 4309 eep->modal_header_2g.paprd_rate_mask_ht20 = dword; 4310 4311 dword = __bswap32(eep->modal_header_2g.paprd_rate_mask_ht40); 4312 eep->modal_header_2g.paprd_rate_mask_ht40 = dword; 4313 4314 dword = __bswap32(eep->modal_header_5g.ant_ctrl_common); 4315 eep->modal_header_5g.ant_ctrl_common = dword; 4316 4317 dword = __bswap32(eep->modal_header_5g.ant_ctrl_common2); 4318 eep->modal_header_5g.ant_ctrl_common2 = dword; 4319 4320 dword = __bswap32(eep->modal_header_5g.paprd_rate_mask_ht20); 4321 eep->modal_header_5g.paprd_rate_mask_ht20 = dword; 4322 4323 dword = __bswap32(eep->modal_header_5g.paprd_rate_mask_ht40); 4324 eep->modal_header_5g.paprd_rate_mask_ht40 = dword; 4325 4326 for (i = 0; i < OSPREY_MAX_CHAINS; i++) { 4327 word = __bswap16(eep->modal_header_2g.ant_ctrl_chain[i]); 4328 eep->modal_header_2g.ant_ctrl_chain[i] = word; 4329 4330 word = __bswap16(eep->modal_header_5g.ant_ctrl_chain[i]); 4331 eep->modal_header_5g.ant_ctrl_chain[i] = word; 4332 } 4333 } 4334 4335 void ar9300_eeprom_template_swap(void) 4336 { 4337 int it; 4338 ar9300_eeprom_t *dptr; 4339 4340 for (it = 0; it < ARRAY_LENGTH(default9300); it++) { 4341 dptr = ar9300_eeprom_struct_default(it); 4342 if (dptr != 0) { 4343 ar9300_swap_eeprom(dptr); 4344 } 4345 } 4346 } 4347 #endif 4348 4349 4350 /* 4351 * Restore the configuration structure by reading the eeprom. 4352 * This function destroys any existing in-memory structure content. 4353 */ 4354 HAL_BOOL 4355 ar9300_eeprom_restore(struct ath_hal *ah) 4356 { 4357 struct ath_hal_9300 *ahp = AH9300(ah); 4358 ar9300_eeprom_t *mptr; 4359 int mdata_size; 4360 HAL_BOOL status = AH_FALSE; 4361 4362 mptr = &ahp->ah_eeprom; 4363 mdata_size = ar9300_eeprom_struct_size(); 4364 4365 if (mptr != 0 && mdata_size > 0) { 4366 #if AH_BYTE_ORDER == AH_BIG_ENDIAN 4367 ar9300_eeprom_template_swap(); 4368 ar9300_swap_eeprom(mptr); 4369 #endif 4370 /* 4371 * At this point, mptr points to the eeprom data structure 4372 * in it's "default" state. If this is big endian, swap the 4373 * data structures back to "little endian" form. 4374 */ 4375 if (ar9300_eeprom_restore_internal(ah, mptr, mdata_size) >= 0) { 4376 status = AH_TRUE; 4377 } 4378 4379 #if AH_BYTE_ORDER == AH_BIG_ENDIAN 4380 /* Second Swap, back to Big Endian */ 4381 ar9300_eeprom_template_swap(); 4382 ar9300_swap_eeprom(mptr); 4383 #endif 4384 4385 } 4386 ahp->ah_2g_paprd_rate_mask_ht40 = 4387 mptr->modal_header_2g.paprd_rate_mask_ht40; 4388 ahp->ah_2g_paprd_rate_mask_ht20 = 4389 mptr->modal_header_2g.paprd_rate_mask_ht20; 4390 ahp->ah_5g_paprd_rate_mask_ht40 = 4391 mptr->modal_header_5g.paprd_rate_mask_ht40; 4392 ahp->ah_5g_paprd_rate_mask_ht20 = 4393 mptr->modal_header_5g.paprd_rate_mask_ht20; 4394 return status; 4395 } 4396 4397 int32_t ar9300_thermometer_get(struct ath_hal *ah) 4398 { 4399 struct ath_hal_9300 *ahp = AH9300(ah); 4400 int thermometer; 4401 thermometer = 4402 (ahp->ah_eeprom.base_eep_header.misc_configuration >> 1) & 0x3; 4403 thermometer--; 4404 return thermometer; 4405 } 4406 4407 HAL_BOOL ar9300_thermometer_apply(struct ath_hal *ah) 4408 { 4409 int thermometer = ar9300_thermometer_get(ah); 4410 4411 /* ch0_RXTX4 */ 4412 /*#define AR_PHY_65NM_CH0_RXTX4 AR_PHY_65NM(ch0_RXTX4)*/ 4413 #define AR_PHY_65NM_CH1_RXTX4 AR_PHY_65NM(ch1_RXTX4) 4414 #define AR_PHY_65NM_CH2_RXTX4 AR_PHY_65NM(ch2_RXTX4) 4415 /*#define AR_PHY_65NM_CH0_RXTX4_THERM_ON 0x10000000*/ 4416 /*#define AR_PHY_65NM_CH0_RXTX4_THERM_ON_S 28*/ 4417 #define AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR_S 29 4418 #define AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR \ 4419 (0x1<<AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR_S) 4420 4421 if (thermometer < 0) { 4422 OS_REG_RMW_FIELD(ah, 4423 AR_PHY_65NM_CH0_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, 0); 4424 if (!AR_SREV_HORNET(ah) && !AR_SREV_POSEIDON(ah)) { 4425 OS_REG_RMW_FIELD(ah, 4426 AR_PHY_65NM_CH1_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, 0); 4427 if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah) && !AR_SREV_HONEYBEE(ah) ) { 4428 OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4, 4429 AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, 0); 4430 } 4431 } 4432 OS_REG_RMW_FIELD(ah, 4433 AR_PHY_65NM_CH0_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON, 0); 4434 if (!AR_SREV_HORNET(ah) && !AR_SREV_POSEIDON(ah)) { 4435 OS_REG_RMW_FIELD(ah, 4436 AR_PHY_65NM_CH1_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON, 0); 4437 if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah) && !AR_SREV_HONEYBEE(ah) ) { 4438 OS_REG_RMW_FIELD(ah, 4439 AR_PHY_65NM_CH2_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON, 0); 4440 } 4441 } 4442 } else { 4443 OS_REG_RMW_FIELD(ah, 4444 AR_PHY_65NM_CH0_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, 1); 4445 if (!AR_SREV_HORNET(ah) && !AR_SREV_POSEIDON(ah)) { 4446 OS_REG_RMW_FIELD(ah, 4447 AR_PHY_65NM_CH1_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, 1); 4448 if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah) && !AR_SREV_HONEYBEE(ah) ) { 4449 OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4, 4450 AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, 1); 4451 } 4452 } 4453 if (thermometer == 0) { 4454 OS_REG_RMW_FIELD(ah, 4455 AR_PHY_65NM_CH0_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON, 1); 4456 if (!AR_SREV_HORNET(ah) && !AR_SREV_POSEIDON(ah)) { 4457 OS_REG_RMW_FIELD(ah, 4458 AR_PHY_65NM_CH1_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON, 0); 4459 if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah) && !AR_SREV_HONEYBEE(ah) ) { 4460 OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4, 4461 AR_PHY_65NM_CH0_RXTX4_THERM_ON, 0); 4462 } 4463 } 4464 } else if (thermometer == 1) { 4465 OS_REG_RMW_FIELD(ah, 4466 AR_PHY_65NM_CH0_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON, 0); 4467 if (!AR_SREV_HORNET(ah) && !AR_SREV_POSEIDON(ah)) { 4468 OS_REG_RMW_FIELD(ah, 4469 AR_PHY_65NM_CH1_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON, 1); 4470 if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah) && !AR_SREV_HONEYBEE(ah) ) { 4471 OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4, 4472 AR_PHY_65NM_CH0_RXTX4_THERM_ON, 0); 4473 } 4474 } 4475 } else if (thermometer == 2) { 4476 OS_REG_RMW_FIELD(ah, 4477 AR_PHY_65NM_CH0_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON, 0); 4478 if (!AR_SREV_HORNET(ah) && !AR_SREV_POSEIDON(ah)) { 4479 OS_REG_RMW_FIELD(ah, 4480 AR_PHY_65NM_CH1_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON, 0); 4481 if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah) && !AR_SREV_HONEYBEE(ah) ) { 4482 OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4, 4483 AR_PHY_65NM_CH0_RXTX4_THERM_ON, 1); 4484 } 4485 } 4486 } 4487 } 4488 return AH_TRUE; 4489 } 4490 4491 static int32_t ar9300_tuning_caps_params_get(struct ath_hal *ah) 4492 { 4493 int tuning_caps_params; 4494 ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom; 4495 tuning_caps_params = eep->base_eep_header.params_for_tuning_caps[0]; 4496 return tuning_caps_params; 4497 } 4498 4499 /* 4500 * Read the tuning caps params from eeprom and set to correct register. 4501 * To regulation the frequency accuracy. 4502 */ 4503 HAL_BOOL ar9300_tuning_caps_apply(struct ath_hal *ah) 4504 { 4505 int tuning_caps_params; 4506 ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom; 4507 tuning_caps_params = ar9300_tuning_caps_params_get(ah); 4508 if ((eep->base_eep_header.feature_enable & 0x40) >> 6) { 4509 tuning_caps_params &= 0x7f; 4510 4511 if (AR_SREV_POSEIDON(ah) || AR_SREV_WASP(ah) || AR_SREV_HONEYBEE(ah)) { 4512 return true; 4513 } else if (AR_SREV_HORNET(ah)) { 4514 OS_REG_RMW_FIELD(ah, 4515 AR_HORNET_CH0_XTAL, AR_OSPREY_CHO_XTAL_CAPINDAC, 4516 tuning_caps_params); 4517 OS_REG_RMW_FIELD(ah, 4518 AR_HORNET_CH0_XTAL, AR_OSPREY_CHO_XTAL_CAPOUTDAC, 4519 tuning_caps_params); 4520 } else if (AR_SREV_SCORPION(ah)) { 4521 OS_REG_RMW_FIELD(ah, 4522 AR_SCORPION_CH0_XTAL, AR_OSPREY_CHO_XTAL_CAPINDAC, 4523 tuning_caps_params); 4524 OS_REG_RMW_FIELD(ah, 4525 AR_SCORPION_CH0_XTAL, AR_OSPREY_CHO_XTAL_CAPOUTDAC, 4526 tuning_caps_params); 4527 } else { 4528 OS_REG_RMW_FIELD(ah, 4529 AR_OSPREY_CH0_XTAL, AR_OSPREY_CHO_XTAL_CAPINDAC, 4530 tuning_caps_params); 4531 OS_REG_RMW_FIELD(ah, 4532 AR_OSPREY_CH0_XTAL, AR_OSPREY_CHO_XTAL_CAPOUTDAC, 4533 tuning_caps_params); 4534 } 4535 4536 } 4537 return AH_TRUE; 4538 } 4539 4540 /* 4541 * Read the tx_frame_to_xpa_on param from eeprom and apply the value to 4542 * correct register. 4543 */ 4544 HAL_BOOL ar9300_xpa_timing_control_apply(struct ath_hal *ah, HAL_BOOL is_2ghz) 4545 { 4546 u_int8_t xpa_timing_control; 4547 ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom; 4548 if ((eep->base_eep_header.feature_enable & 0x80) >> 7) { 4549 if (AR_SREV_OSPREY(ah) || AR_SREV_AR9580(ah) || AR_SREV_WASP(ah) || AR_SREV_HONEYBEE(ah)) { 4550 if (is_2ghz) { 4551 xpa_timing_control = eep->modal_header_2g.tx_frame_to_xpa_on; 4552 OS_REG_RMW_FIELD(ah, 4553 AR_PHY_XPA_TIMING_CTL, AR_PHY_XPA_TIMING_CTL_FRAME_XPAB_ON, 4554 xpa_timing_control); 4555 } else { 4556 xpa_timing_control = eep->modal_header_5g.tx_frame_to_xpa_on; 4557 OS_REG_RMW_FIELD(ah, 4558 AR_PHY_XPA_TIMING_CTL, AR_PHY_XPA_TIMING_CTL_FRAME_XPAA_ON, 4559 xpa_timing_control); 4560 } 4561 } 4562 } 4563 return AH_TRUE; 4564 } 4565 4566 4567 /* 4568 * Read the xLNA_bias_strength param from eeprom and apply the value to 4569 * correct register. 4570 */ 4571 HAL_BOOL ar9300_x_lNA_bias_strength_apply(struct ath_hal *ah, HAL_BOOL is_2ghz) 4572 { 4573 u_int8_t x_lNABias; 4574 u_int32_t value = 0; 4575 ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom; 4576 4577 if ((eep->base_eep_header.misc_configuration & 0x40) >> 6) { 4578 if (AR_SREV_OSPREY(ah)) { 4579 if (is_2ghz) { 4580 x_lNABias = eep->modal_header_2g.xLNA_bias_strength; 4581 } else { 4582 x_lNABias = eep->modal_header_5g.xLNA_bias_strength; 4583 } 4584 value = x_lNABias & ( 0x03 ); // bit0,1 for chain0 4585 OS_REG_RMW_FIELD(ah, 4586 AR_PHY_65NM_CH0_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS, value); 4587 value = (x_lNABias >> 2) & ( 0x03 ); // bit2,3 for chain1 4588 OS_REG_RMW_FIELD(ah, 4589 AR_PHY_65NM_CH1_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS, value); 4590 value = (x_lNABias >> 4) & ( 0x03 ); // bit4,5 for chain2 4591 OS_REG_RMW_FIELD(ah, 4592 AR_PHY_65NM_CH2_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS, value); 4593 } 4594 } 4595 return AH_TRUE; 4596 } 4597 4598 4599 /* 4600 * Read EEPROM header info and program the device for correct operation 4601 * given the channel value. 4602 */ 4603 HAL_BOOL 4604 ar9300_eeprom_set_board_values(struct ath_hal *ah, const struct ieee80211_channel *chan) 4605 { 4606 HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan); 4607 4608 ar9300_xpa_bias_level_apply(ah, IEEE80211_IS_CHAN_2GHZ(chan)); 4609 4610 ar9300_xpa_timing_control_apply(ah, IEEE80211_IS_CHAN_2GHZ(chan)); 4611 4612 ar9300_ant_ctrl_apply(ah, IEEE80211_IS_CHAN_2GHZ(chan)); 4613 ar9300_drive_strength_apply(ah); 4614 4615 ar9300_x_lNA_bias_strength_apply(ah, IEEE80211_IS_CHAN_2GHZ(chan)); 4616 4617 /* wait for Poseidon internal regular turnning */ 4618 /* for Hornet we move it before initPLL to avoid an access issue */ 4619 /* Function not used when EMULATION. */ 4620 if (!AR_SREV_HORNET(ah) && !AR_SREV_WASP(ah) && !AR_SREV_HONEYBEE(ah)) { 4621 ar9300_internal_regulator_apply(ah); 4622 } 4623 4624 ar9300_attenuation_apply(ah, ichan->channel); 4625 ar9300_quick_drop_apply(ah, ichan->channel); 4626 ar9300_thermometer_apply(ah); 4627 if(!AR_SREV_WASP(ah)) 4628 { 4629 ar9300_tuning_caps_apply(ah); 4630 } 4631 4632 ar9300_tx_end_to_xpab_off_apply(ah, ichan->channel); 4633 4634 return AH_TRUE; 4635 } 4636 4637 u_int8_t * 4638 ar9300_eeprom_get_spur_chans_ptr(struct ath_hal *ah, HAL_BOOL is_2ghz) 4639 { 4640 ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom; 4641 4642 if (is_2ghz) { 4643 return &(eep->modal_header_2g.spur_chans[0]); 4644 } else { 4645 return &(eep->modal_header_5g.spur_chans[0]); 4646 } 4647 } 4648 4649 static u_int8_t ar9300_eeprom_get_tx_gain_table_number_max(struct ath_hal *ah) 4650 { 4651 unsigned long tx_gain_table_max; 4652 tx_gain_table_max = OS_REG_READ_FIELD(ah, 4653 AR_PHY_TPC_7, AR_PHY_TPC_7_TX_GAIN_TABLE_MAX); 4654 return tx_gain_table_max; 4655 } 4656 4657 u_int8_t ar9300_eeprom_tx_gain_table_index_max_apply(struct ath_hal *ah, u_int16_t channel) 4658 { 4659 unsigned int index; 4660 ar9300_eeprom_t *ahp_Eeprom; 4661 struct ath_hal_9300 *ahp = AH9300(ah); 4662 4663 ahp_Eeprom = &ahp->ah_eeprom; 4664 4665 if (ahp_Eeprom->base_ext1.misc_enable == 0) 4666 return AH_FALSE; 4667 4668 if (channel < 4000) 4669 { 4670 index = ahp_Eeprom->modal_header_2g.tx_gain_cap; 4671 } 4672 else 4673 { 4674 index = ahp_Eeprom->modal_header_5g.tx_gain_cap; 4675 } 4676 4677 OS_REG_RMW_FIELD(ah, 4678 AR_PHY_TPC_7, AR_PHY_TPC_7_TX_GAIN_TABLE_MAX, index); 4679 return AH_TRUE; 4680 } 4681 4682 static u_int8_t ar9300_eeprom_get_pcdac_tx_gain_table_i(struct ath_hal *ah, 4683 int i, u_int8_t *pcdac) 4684 { 4685 unsigned long tx_gain; 4686 u_int8_t tx_gain_table_max; 4687 tx_gain_table_max = ar9300_eeprom_get_tx_gain_table_number_max(ah); 4688 if (i <= 0 || i > tx_gain_table_max) { 4689 *pcdac = 0; 4690 return AH_FALSE; 4691 } 4692 4693 tx_gain = OS_REG_READ(ah, AR_PHY_TXGAIN_TAB(1) + i * 4); 4694 *pcdac = ((tx_gain >> 24) & 0xff); 4695 return AH_TRUE; 4696 } 4697 4698 u_int8_t ar9300_eeprom_set_tx_gain_cap(struct ath_hal *ah, 4699 int *tx_gain_max) 4700 // pcdac read back from reg, read back value depends on reset 2GHz/5GHz ini 4701 // tx_gain_table, this function will be called twice after each 4702 // band's calibration. 4703 // after 2GHz cal, tx_gain_max[0] has 2GHz, calibration max txgain, 4704 // tx_gain_max[1]=-100 4705 // after 5GHz cal, tx_gain_max[0],tx_gain_max[1] have calibration 4706 // value for both band 4707 // reset is on 5GHz, reg reading from tx_gain_table is for 5GHz, 4708 // so program can't recalculate 2g.tx_gain_cap at this point. 4709 { 4710 int i = 0, ig, im = 0; 4711 u_int8_t pcdac = 0; 4712 u_int8_t tx_gain_table_max; 4713 ar9300_eeprom_t *ahp_Eeprom; 4714 struct ath_hal_9300 *ahp = AH9300(ah); 4715 4716 ahp_Eeprom = &ahp->ah_eeprom; 4717 4718 if (ahp_Eeprom->base_ext1.misc_enable == 0) 4719 return AH_FALSE; 4720 4721 tx_gain_table_max = ar9300_eeprom_get_tx_gain_table_number_max(ah); 4722 4723 for (i = 0; i < 2; i++) { 4724 if (tx_gain_max[i]>-100) { // -100 didn't cal that band. 4725 if ( i== 0) { 4726 if (tx_gain_max[1]>-100) { 4727 continue; 4728 // both band are calibrated, skip 2GHz 2g.tx_gain_cap reset 4729 } 4730 } 4731 for (ig = 1; ig <= tx_gain_table_max; ig++) { 4732 if (ah != 0 && ah->ah_reset != 0) 4733 { 4734 ar9300_eeprom_get_pcdac_tx_gain_table_i(ah, ig, &pcdac); 4735 if (pcdac >= tx_gain_max[i]) 4736 break; 4737 } 4738 } 4739 if (ig+1 <= tx_gain_table_max) { 4740 if (pcdac == tx_gain_max[i]) 4741 im = ig; 4742 else 4743 im = ig + 1; 4744 if (i == 0) { 4745 ahp_Eeprom->modal_header_2g.tx_gain_cap = im; 4746 } else { 4747 ahp_Eeprom->modal_header_5g.tx_gain_cap = im; 4748 } 4749 } else { 4750 if (i == 0) { 4751 ahp_Eeprom->modal_header_2g.tx_gain_cap = ig; 4752 } else { 4753 ahp_Eeprom->modal_header_5g.tx_gain_cap = ig; 4754 } 4755 } 4756 } 4757 } 4758 return AH_TRUE; 4759 } 4760