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