1 /* 2 * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org> 3 * Copyright (c) 2006-2009 Nick Kossifidis <mickflemm@gmail.com> 4 * Copyright (c) 2008-2009 Felix Fietkau <nbd@openwrt.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 * 18 */ 19 20 /*************************************\ 21 * EEPROM access functions and helpers * 22 \*************************************/ 23 24 #include "ath5k.h" 25 #include "reg.h" 26 #include "debug.h" 27 #include "base.h" 28 29 /* 30 * Read from eeprom 31 */ 32 static int ath5k_hw_eeprom_read(struct ath5k_hw *ah, u32 offset, u16 *data) 33 { 34 u32 status, timeout; 35 36 ATH5K_TRACE(ah->ah_sc); 37 /* 38 * Initialize EEPROM access 39 */ 40 if (ah->ah_version == AR5K_AR5210) { 41 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_EEAE); 42 (void)ath5k_hw_reg_read(ah, AR5K_EEPROM_BASE + (4 * offset)); 43 } else { 44 ath5k_hw_reg_write(ah, offset, AR5K_EEPROM_BASE); 45 AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD, 46 AR5K_EEPROM_CMD_READ); 47 } 48 49 for (timeout = AR5K_TUNE_REGISTER_TIMEOUT; timeout > 0; timeout--) { 50 status = ath5k_hw_reg_read(ah, AR5K_EEPROM_STATUS); 51 if (status & AR5K_EEPROM_STAT_RDDONE) { 52 if (status & AR5K_EEPROM_STAT_RDERR) 53 return -EIO; 54 *data = (u16)(ath5k_hw_reg_read(ah, AR5K_EEPROM_DATA) & 55 0xffff); 56 return 0; 57 } 58 udelay(15); 59 } 60 61 return -ETIMEDOUT; 62 } 63 64 /* 65 * Translate binary channel representation in EEPROM to frequency 66 */ 67 static u16 ath5k_eeprom_bin2freq(struct ath5k_eeprom_info *ee, u16 bin, 68 unsigned int mode) 69 { 70 u16 val; 71 72 if (bin == AR5K_EEPROM_CHANNEL_DIS) 73 return bin; 74 75 if (mode == AR5K_EEPROM_MODE_11A) { 76 if (ee->ee_version > AR5K_EEPROM_VERSION_3_2) 77 val = (5 * bin) + 4800; 78 else 79 val = bin > 62 ? (10 * 62) + (5 * (bin - 62)) + 5100 : 80 (bin * 10) + 5100; 81 } else { 82 if (ee->ee_version > AR5K_EEPROM_VERSION_3_2) 83 val = bin + 2300; 84 else 85 val = bin + 2400; 86 } 87 88 return val; 89 } 90 91 /* 92 * Initialize eeprom & capabilities structs 93 */ 94 static int 95 ath5k_eeprom_init_header(struct ath5k_hw *ah) 96 { 97 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 98 int ret; 99 u16 val; 100 u32 cksum, offset, eep_max = AR5K_EEPROM_INFO_MAX; 101 102 /* 103 * Read values from EEPROM and store them in the capability structure 104 */ 105 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MAGIC, ee_magic); 106 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_PROTECT, ee_protect); 107 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_REG_DOMAIN, ee_regdomain); 108 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_VERSION, ee_version); 109 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_HDR, ee_header); 110 111 /* Return if we have an old EEPROM */ 112 if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_0) 113 return 0; 114 115 /* 116 * Validate the checksum of the EEPROM date. There are some 117 * devices with invalid EEPROMs. 118 */ 119 AR5K_EEPROM_READ(AR5K_EEPROM_SIZE_UPPER, val); 120 if (val) { 121 eep_max = (val & AR5K_EEPROM_SIZE_UPPER_MASK) << 122 AR5K_EEPROM_SIZE_ENDLOC_SHIFT; 123 AR5K_EEPROM_READ(AR5K_EEPROM_SIZE_LOWER, val); 124 eep_max = (eep_max | val) - AR5K_EEPROM_INFO_BASE; 125 126 /* 127 * Fail safe check to prevent stupid loops due 128 * to busted EEPROMs. XXX: This value is likely too 129 * big still, waiting on a better value. 130 */ 131 if (eep_max > (3 * AR5K_EEPROM_INFO_MAX)) { 132 ATH5K_ERR(ah->ah_sc, "Invalid max custom EEPROM size: " 133 "%d (0x%04x) max expected: %d (0x%04x)\n", 134 eep_max, eep_max, 135 3 * AR5K_EEPROM_INFO_MAX, 136 3 * AR5K_EEPROM_INFO_MAX); 137 return -EIO; 138 } 139 } 140 141 for (cksum = 0, offset = 0; offset < eep_max; offset++) { 142 AR5K_EEPROM_READ(AR5K_EEPROM_INFO(offset), val); 143 cksum ^= val; 144 } 145 if (cksum != AR5K_EEPROM_INFO_CKSUM) { 146 ATH5K_ERR(ah->ah_sc, "Invalid EEPROM " 147 "checksum: 0x%04x eep_max: 0x%04x (%s)\n", 148 cksum, eep_max, 149 eep_max == AR5K_EEPROM_INFO_MAX ? 150 "default size" : "custom size"); 151 return -EIO; 152 } 153 154 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_ANT_GAIN(ah->ah_ee_version), 155 ee_ant_gain); 156 157 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) { 158 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC0, ee_misc0); 159 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC1, ee_misc1); 160 161 /* XXX: Don't know which versions include these two */ 162 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC2, ee_misc2); 163 164 if (ee->ee_version >= AR5K_EEPROM_VERSION_4_3) 165 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC3, ee_misc3); 166 167 if (ee->ee_version >= AR5K_EEPROM_VERSION_5_0) { 168 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC4, ee_misc4); 169 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC5, ee_misc5); 170 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC6, ee_misc6); 171 } 172 } 173 174 if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_3) { 175 AR5K_EEPROM_READ(AR5K_EEPROM_OBDB0_2GHZ, val); 176 ee->ee_ob[AR5K_EEPROM_MODE_11B][0] = val & 0x7; 177 ee->ee_db[AR5K_EEPROM_MODE_11B][0] = (val >> 3) & 0x7; 178 179 AR5K_EEPROM_READ(AR5K_EEPROM_OBDB1_2GHZ, val); 180 ee->ee_ob[AR5K_EEPROM_MODE_11G][0] = val & 0x7; 181 ee->ee_db[AR5K_EEPROM_MODE_11G][0] = (val >> 3) & 0x7; 182 } 183 184 AR5K_EEPROM_READ(AR5K_EEPROM_IS_HB63, val); 185 186 if ((ah->ah_mac_version == (AR5K_SREV_AR2425 >> 4)) && val) 187 ee->ee_is_hb63 = true; 188 else 189 ee->ee_is_hb63 = false; 190 191 AR5K_EEPROM_READ(AR5K_EEPROM_RFKILL, val); 192 ee->ee_rfkill_pin = (u8) AR5K_REG_MS(val, AR5K_EEPROM_RFKILL_GPIO_SEL); 193 ee->ee_rfkill_pol = val & AR5K_EEPROM_RFKILL_POLARITY ? true : false; 194 195 /* Check if PCIE_OFFSET points to PCIE_SERDES_SECTION 196 * and enable serdes programming if needed. 197 * 198 * XXX: Serdes values seem to be fixed so 199 * no need to read them here, we write them 200 * during ath5k_hw_attach */ 201 AR5K_EEPROM_READ(AR5K_EEPROM_PCIE_OFFSET, val); 202 ee->ee_serdes = (val == AR5K_EEPROM_PCIE_SERDES_SECTION) ? 203 true : false; 204 205 return 0; 206 } 207 208 209 /* 210 * Read antenna infos from eeprom 211 */ 212 static int ath5k_eeprom_read_ants(struct ath5k_hw *ah, u32 *offset, 213 unsigned int mode) 214 { 215 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 216 u32 o = *offset; 217 u16 val; 218 int ret, i = 0; 219 220 AR5K_EEPROM_READ(o++, val); 221 ee->ee_switch_settling[mode] = (val >> 8) & 0x7f; 222 ee->ee_atn_tx_rx[mode] = (val >> 2) & 0x3f; 223 ee->ee_ant_control[mode][i] = (val << 4) & 0x3f; 224 225 AR5K_EEPROM_READ(o++, val); 226 ee->ee_ant_control[mode][i++] |= (val >> 12) & 0xf; 227 ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f; 228 ee->ee_ant_control[mode][i++] = val & 0x3f; 229 230 AR5K_EEPROM_READ(o++, val); 231 ee->ee_ant_control[mode][i++] = (val >> 10) & 0x3f; 232 ee->ee_ant_control[mode][i++] = (val >> 4) & 0x3f; 233 ee->ee_ant_control[mode][i] = (val << 2) & 0x3f; 234 235 AR5K_EEPROM_READ(o++, val); 236 ee->ee_ant_control[mode][i++] |= (val >> 14) & 0x3; 237 ee->ee_ant_control[mode][i++] = (val >> 8) & 0x3f; 238 ee->ee_ant_control[mode][i++] = (val >> 2) & 0x3f; 239 ee->ee_ant_control[mode][i] = (val << 4) & 0x3f; 240 241 AR5K_EEPROM_READ(o++, val); 242 ee->ee_ant_control[mode][i++] |= (val >> 12) & 0xf; 243 ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f; 244 ee->ee_ant_control[mode][i++] = val & 0x3f; 245 246 /* Get antenna switch tables */ 247 ah->ah_ant_ctl[mode][AR5K_ANT_CTL] = 248 (ee->ee_ant_control[mode][0] << 4); 249 ah->ah_ant_ctl[mode][AR5K_ANT_SWTABLE_A] = 250 ee->ee_ant_control[mode][1] | 251 (ee->ee_ant_control[mode][2] << 6) | 252 (ee->ee_ant_control[mode][3] << 12) | 253 (ee->ee_ant_control[mode][4] << 18) | 254 (ee->ee_ant_control[mode][5] << 24); 255 ah->ah_ant_ctl[mode][AR5K_ANT_SWTABLE_B] = 256 ee->ee_ant_control[mode][6] | 257 (ee->ee_ant_control[mode][7] << 6) | 258 (ee->ee_ant_control[mode][8] << 12) | 259 (ee->ee_ant_control[mode][9] << 18) | 260 (ee->ee_ant_control[mode][10] << 24); 261 262 /* return new offset */ 263 *offset = o; 264 265 return 0; 266 } 267 268 /* 269 * Read supported modes and some mode-specific calibration data 270 * from eeprom 271 */ 272 static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset, 273 unsigned int mode) 274 { 275 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 276 u32 o = *offset; 277 u16 val; 278 int ret; 279 280 ee->ee_n_piers[mode] = 0; 281 AR5K_EEPROM_READ(o++, val); 282 ee->ee_adc_desired_size[mode] = (s8)((val >> 8) & 0xff); 283 switch(mode) { 284 case AR5K_EEPROM_MODE_11A: 285 ee->ee_ob[mode][3] = (val >> 5) & 0x7; 286 ee->ee_db[mode][3] = (val >> 2) & 0x7; 287 ee->ee_ob[mode][2] = (val << 1) & 0x7; 288 289 AR5K_EEPROM_READ(o++, val); 290 ee->ee_ob[mode][2] |= (val >> 15) & 0x1; 291 ee->ee_db[mode][2] = (val >> 12) & 0x7; 292 ee->ee_ob[mode][1] = (val >> 9) & 0x7; 293 ee->ee_db[mode][1] = (val >> 6) & 0x7; 294 ee->ee_ob[mode][0] = (val >> 3) & 0x7; 295 ee->ee_db[mode][0] = val & 0x7; 296 break; 297 case AR5K_EEPROM_MODE_11G: 298 case AR5K_EEPROM_MODE_11B: 299 ee->ee_ob[mode][1] = (val >> 4) & 0x7; 300 ee->ee_db[mode][1] = val & 0x7; 301 break; 302 } 303 304 AR5K_EEPROM_READ(o++, val); 305 ee->ee_tx_end2xlna_enable[mode] = (val >> 8) & 0xff; 306 ee->ee_thr_62[mode] = val & 0xff; 307 308 if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2) 309 ee->ee_thr_62[mode] = mode == AR5K_EEPROM_MODE_11A ? 15 : 28; 310 311 AR5K_EEPROM_READ(o++, val); 312 ee->ee_tx_end2xpa_disable[mode] = (val >> 8) & 0xff; 313 ee->ee_tx_frm2xpa_enable[mode] = val & 0xff; 314 315 AR5K_EEPROM_READ(o++, val); 316 ee->ee_pga_desired_size[mode] = (val >> 8) & 0xff; 317 318 if ((val & 0xff) & 0x80) 319 ee->ee_noise_floor_thr[mode] = -((((val & 0xff) ^ 0xff)) + 1); 320 else 321 ee->ee_noise_floor_thr[mode] = val & 0xff; 322 323 if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2) 324 ee->ee_noise_floor_thr[mode] = 325 mode == AR5K_EEPROM_MODE_11A ? -54 : -1; 326 327 AR5K_EEPROM_READ(o++, val); 328 ee->ee_xlna_gain[mode] = (val >> 5) & 0xff; 329 ee->ee_x_gain[mode] = (val >> 1) & 0xf; 330 ee->ee_xpd[mode] = val & 0x1; 331 332 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) 333 ee->ee_fixed_bias[mode] = (val >> 13) & 0x1; 334 335 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_3) { 336 AR5K_EEPROM_READ(o++, val); 337 ee->ee_false_detect[mode] = (val >> 6) & 0x7f; 338 339 if (mode == AR5K_EEPROM_MODE_11A) 340 ee->ee_xr_power[mode] = val & 0x3f; 341 else { 342 ee->ee_ob[mode][0] = val & 0x7; 343 ee->ee_db[mode][0] = (val >> 3) & 0x7; 344 } 345 } 346 347 if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_4) { 348 ee->ee_i_gain[mode] = AR5K_EEPROM_I_GAIN; 349 ee->ee_cck_ofdm_power_delta = AR5K_EEPROM_CCK_OFDM_DELTA; 350 } else { 351 ee->ee_i_gain[mode] = (val >> 13) & 0x7; 352 353 AR5K_EEPROM_READ(o++, val); 354 ee->ee_i_gain[mode] |= (val << 3) & 0x38; 355 356 if (mode == AR5K_EEPROM_MODE_11G) { 357 ee->ee_cck_ofdm_power_delta = (val >> 3) & 0xff; 358 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_6) 359 ee->ee_scaled_cck_delta = (val >> 11) & 0x1f; 360 } 361 } 362 363 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0 && 364 mode == AR5K_EEPROM_MODE_11A) { 365 ee->ee_i_cal[mode] = (val >> 8) & 0x3f; 366 ee->ee_q_cal[mode] = (val >> 3) & 0x1f; 367 } 368 369 if (ah->ah_ee_version < AR5K_EEPROM_VERSION_4_0) 370 goto done; 371 372 /* Note: >= v5 have bg freq piers on another location 373 * so these freq piers are ignored for >= v5 (should be 0xff 374 * anyway) */ 375 switch(mode) { 376 case AR5K_EEPROM_MODE_11A: 377 if (ah->ah_ee_version < AR5K_EEPROM_VERSION_4_1) 378 break; 379 380 AR5K_EEPROM_READ(o++, val); 381 ee->ee_margin_tx_rx[mode] = val & 0x3f; 382 break; 383 case AR5K_EEPROM_MODE_11B: 384 AR5K_EEPROM_READ(o++, val); 385 386 ee->ee_pwr_cal_b[0].freq = 387 ath5k_eeprom_bin2freq(ee, val & 0xff, mode); 388 if (ee->ee_pwr_cal_b[0].freq != AR5K_EEPROM_CHANNEL_DIS) 389 ee->ee_n_piers[mode]++; 390 391 ee->ee_pwr_cal_b[1].freq = 392 ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode); 393 if (ee->ee_pwr_cal_b[1].freq != AR5K_EEPROM_CHANNEL_DIS) 394 ee->ee_n_piers[mode]++; 395 396 AR5K_EEPROM_READ(o++, val); 397 ee->ee_pwr_cal_b[2].freq = 398 ath5k_eeprom_bin2freq(ee, val & 0xff, mode); 399 if (ee->ee_pwr_cal_b[2].freq != AR5K_EEPROM_CHANNEL_DIS) 400 ee->ee_n_piers[mode]++; 401 402 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) 403 ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f; 404 break; 405 case AR5K_EEPROM_MODE_11G: 406 AR5K_EEPROM_READ(o++, val); 407 408 ee->ee_pwr_cal_g[0].freq = 409 ath5k_eeprom_bin2freq(ee, val & 0xff, mode); 410 if (ee->ee_pwr_cal_g[0].freq != AR5K_EEPROM_CHANNEL_DIS) 411 ee->ee_n_piers[mode]++; 412 413 ee->ee_pwr_cal_g[1].freq = 414 ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode); 415 if (ee->ee_pwr_cal_g[1].freq != AR5K_EEPROM_CHANNEL_DIS) 416 ee->ee_n_piers[mode]++; 417 418 AR5K_EEPROM_READ(o++, val); 419 ee->ee_turbo_max_power[mode] = val & 0x7f; 420 ee->ee_xr_power[mode] = (val >> 7) & 0x3f; 421 422 AR5K_EEPROM_READ(o++, val); 423 ee->ee_pwr_cal_g[2].freq = 424 ath5k_eeprom_bin2freq(ee, val & 0xff, mode); 425 if (ee->ee_pwr_cal_g[2].freq != AR5K_EEPROM_CHANNEL_DIS) 426 ee->ee_n_piers[mode]++; 427 428 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) 429 ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f; 430 431 AR5K_EEPROM_READ(o++, val); 432 ee->ee_i_cal[mode] = (val >> 8) & 0x3f; 433 ee->ee_q_cal[mode] = (val >> 3) & 0x1f; 434 435 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_2) { 436 AR5K_EEPROM_READ(o++, val); 437 ee->ee_cck_ofdm_gain_delta = val & 0xff; 438 } 439 break; 440 } 441 442 /* 443 * Read turbo mode information on newer EEPROM versions 444 */ 445 if (ee->ee_version < AR5K_EEPROM_VERSION_5_0) 446 goto done; 447 448 switch (mode){ 449 case AR5K_EEPROM_MODE_11A: 450 ee->ee_switch_settling_turbo[mode] = (val >> 6) & 0x7f; 451 452 ee->ee_atn_tx_rx_turbo[mode] = (val >> 13) & 0x7; 453 AR5K_EEPROM_READ(o++, val); 454 ee->ee_atn_tx_rx_turbo[mode] |= (val & 0x7) << 3; 455 ee->ee_margin_tx_rx_turbo[mode] = (val >> 3) & 0x3f; 456 457 ee->ee_adc_desired_size_turbo[mode] = (val >> 9) & 0x7f; 458 AR5K_EEPROM_READ(o++, val); 459 ee->ee_adc_desired_size_turbo[mode] |= (val & 0x1) << 7; 460 ee->ee_pga_desired_size_turbo[mode] = (val >> 1) & 0xff; 461 462 if (AR5K_EEPROM_EEMAP(ee->ee_misc0) >=2) 463 ee->ee_pd_gain_overlap = (val >> 9) & 0xf; 464 break; 465 case AR5K_EEPROM_MODE_11G: 466 ee->ee_switch_settling_turbo[mode] = (val >> 8) & 0x7f; 467 468 ee->ee_atn_tx_rx_turbo[mode] = (val >> 15) & 0x7; 469 AR5K_EEPROM_READ(o++, val); 470 ee->ee_atn_tx_rx_turbo[mode] |= (val & 0x1f) << 1; 471 ee->ee_margin_tx_rx_turbo[mode] = (val >> 5) & 0x3f; 472 473 ee->ee_adc_desired_size_turbo[mode] = (val >> 11) & 0x7f; 474 AR5K_EEPROM_READ(o++, val); 475 ee->ee_adc_desired_size_turbo[mode] |= (val & 0x7) << 5; 476 ee->ee_pga_desired_size_turbo[mode] = (val >> 3) & 0xff; 477 break; 478 } 479 480 done: 481 /* return new offset */ 482 *offset = o; 483 484 return 0; 485 } 486 487 /* Read mode-specific data (except power calibration data) */ 488 static int 489 ath5k_eeprom_init_modes(struct ath5k_hw *ah) 490 { 491 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 492 u32 mode_offset[3]; 493 unsigned int mode; 494 u32 offset; 495 int ret; 496 497 /* 498 * Get values for all modes 499 */ 500 mode_offset[AR5K_EEPROM_MODE_11A] = AR5K_EEPROM_MODES_11A(ah->ah_ee_version); 501 mode_offset[AR5K_EEPROM_MODE_11B] = AR5K_EEPROM_MODES_11B(ah->ah_ee_version); 502 mode_offset[AR5K_EEPROM_MODE_11G] = AR5K_EEPROM_MODES_11G(ah->ah_ee_version); 503 504 ee->ee_turbo_max_power[AR5K_EEPROM_MODE_11A] = 505 AR5K_EEPROM_HDR_T_5GHZ_DBM(ee->ee_header); 506 507 for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++) { 508 offset = mode_offset[mode]; 509 510 ret = ath5k_eeprom_read_ants(ah, &offset, mode); 511 if (ret) 512 return ret; 513 514 ret = ath5k_eeprom_read_modes(ah, &offset, mode); 515 if (ret) 516 return ret; 517 } 518 519 /* override for older eeprom versions for better performance */ 520 if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2) { 521 ee->ee_thr_62[AR5K_EEPROM_MODE_11A] = 15; 522 ee->ee_thr_62[AR5K_EEPROM_MODE_11B] = 28; 523 ee->ee_thr_62[AR5K_EEPROM_MODE_11G] = 28; 524 } 525 526 return 0; 527 } 528 529 /* Read the frequency piers for each mode (mostly used on newer eeproms with 0xff 530 * frequency mask) */ 531 static inline int 532 ath5k_eeprom_read_freq_list(struct ath5k_hw *ah, int *offset, int max, 533 struct ath5k_chan_pcal_info *pc, unsigned int mode) 534 { 535 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 536 int o = *offset; 537 int i = 0; 538 u8 freq1, freq2; 539 int ret; 540 u16 val; 541 542 ee->ee_n_piers[mode] = 0; 543 while(i < max) { 544 AR5K_EEPROM_READ(o++, val); 545 546 freq1 = val & 0xff; 547 if (!freq1) 548 break; 549 550 pc[i++].freq = ath5k_eeprom_bin2freq(ee, 551 freq1, mode); 552 ee->ee_n_piers[mode]++; 553 554 freq2 = (val >> 8) & 0xff; 555 if (!freq2) 556 break; 557 558 pc[i++].freq = ath5k_eeprom_bin2freq(ee, 559 freq2, mode); 560 ee->ee_n_piers[mode]++; 561 } 562 563 /* return new offset */ 564 *offset = o; 565 566 return 0; 567 } 568 569 /* Read frequency piers for 802.11a */ 570 static int 571 ath5k_eeprom_init_11a_pcal_freq(struct ath5k_hw *ah, int offset) 572 { 573 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 574 struct ath5k_chan_pcal_info *pcal = ee->ee_pwr_cal_a; 575 int i, ret; 576 u16 val; 577 u8 mask; 578 579 if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3) { 580 ath5k_eeprom_read_freq_list(ah, &offset, 581 AR5K_EEPROM_N_5GHZ_CHAN, pcal, 582 AR5K_EEPROM_MODE_11A); 583 } else { 584 mask = AR5K_EEPROM_FREQ_M(ah->ah_ee_version); 585 586 AR5K_EEPROM_READ(offset++, val); 587 pcal[0].freq = (val >> 9) & mask; 588 pcal[1].freq = (val >> 2) & mask; 589 pcal[2].freq = (val << 5) & mask; 590 591 AR5K_EEPROM_READ(offset++, val); 592 pcal[2].freq |= (val >> 11) & 0x1f; 593 pcal[3].freq = (val >> 4) & mask; 594 pcal[4].freq = (val << 3) & mask; 595 596 AR5K_EEPROM_READ(offset++, val); 597 pcal[4].freq |= (val >> 13) & 0x7; 598 pcal[5].freq = (val >> 6) & mask; 599 pcal[6].freq = (val << 1) & mask; 600 601 AR5K_EEPROM_READ(offset++, val); 602 pcal[6].freq |= (val >> 15) & 0x1; 603 pcal[7].freq = (val >> 8) & mask; 604 pcal[8].freq = (val >> 1) & mask; 605 pcal[9].freq = (val << 6) & mask; 606 607 AR5K_EEPROM_READ(offset++, val); 608 pcal[9].freq |= (val >> 10) & 0x3f; 609 610 /* Fixed number of piers */ 611 ee->ee_n_piers[AR5K_EEPROM_MODE_11A] = 10; 612 613 for (i = 0; i < AR5K_EEPROM_N_5GHZ_CHAN; i++) { 614 pcal[i].freq = ath5k_eeprom_bin2freq(ee, 615 pcal[i].freq, AR5K_EEPROM_MODE_11A); 616 } 617 } 618 619 return 0; 620 } 621 622 /* Read frequency piers for 802.11bg on eeprom versions >= 5 and eemap >= 2 */ 623 static inline int 624 ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset) 625 { 626 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 627 struct ath5k_chan_pcal_info *pcal; 628 629 switch(mode) { 630 case AR5K_EEPROM_MODE_11B: 631 pcal = ee->ee_pwr_cal_b; 632 break; 633 case AR5K_EEPROM_MODE_11G: 634 pcal = ee->ee_pwr_cal_g; 635 break; 636 default: 637 return -EINVAL; 638 } 639 640 ath5k_eeprom_read_freq_list(ah, &offset, 641 AR5K_EEPROM_N_2GHZ_CHAN_2413, pcal, 642 mode); 643 644 return 0; 645 } 646 647 /* 648 * Read power calibration for RF5111 chips 649 * 650 * For RF5111 we have an XPD -eXternal Power Detector- curve 651 * for each calibrated channel. Each curve has 0,5dB Power steps 652 * on x axis and PCDAC steps (offsets) on y axis and looks like an 653 * exponential function. To recreate the curve we read 11 points 654 * here and interpolate later. 655 */ 656 657 /* Used to match PCDAC steps with power values on RF5111 chips 658 * (eeprom versions < 4). For RF5111 we have 11 pre-defined PCDAC 659 * steps that match with the power values we read from eeprom. On 660 * older eeprom versions (< 3.2) these steps are equaly spaced at 661 * 10% of the pcdac curve -until the curve reaches it's maximum- 662 * (11 steps from 0 to 100%) but on newer eeprom versions (>= 3.2) 663 * these 11 steps are spaced in a different way. This function returns 664 * the pcdac steps based on eeprom version and curve min/max so that we 665 * can have pcdac/pwr points. 666 */ 667 static inline void 668 ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp) 669 { 670 static const u16 intercepts3[] = 671 { 0, 5, 10, 20, 30, 50, 70, 85, 90, 95, 100 }; 672 static const u16 intercepts3_2[] = 673 { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 }; 674 const u16 *ip; 675 int i; 676 677 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_2) 678 ip = intercepts3_2; 679 else 680 ip = intercepts3; 681 682 for (i = 0; i < ARRAY_SIZE(intercepts3); i++) 683 vp[i] = (ip[i] * max + (100 - ip[i]) * min) / 100; 684 } 685 686 /* Convert RF5111 specific data to generic raw data 687 * used by interpolation code */ 688 static int 689 ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode, 690 struct ath5k_chan_pcal_info *chinfo) 691 { 692 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 693 struct ath5k_chan_pcal_info_rf5111 *pcinfo; 694 struct ath5k_pdgain_info *pd; 695 u8 pier, point, idx; 696 u8 *pdgain_idx = ee->ee_pdc_to_idx[mode]; 697 698 /* Fill raw data for each calibration pier */ 699 for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) { 700 701 pcinfo = &chinfo[pier].rf5111_info; 702 703 /* Allocate pd_curves for this cal pier */ 704 chinfo[pier].pd_curves = 705 kcalloc(AR5K_EEPROM_N_PD_CURVES, 706 sizeof(struct ath5k_pdgain_info), 707 GFP_KERNEL); 708 709 if (!chinfo[pier].pd_curves) 710 return -ENOMEM; 711 712 /* Only one curve for RF5111 713 * find out which one and place 714 * in in pd_curves. 715 * Note: ee_x_gain is reversed here */ 716 for (idx = 0; idx < AR5K_EEPROM_N_PD_CURVES; idx++) { 717 718 if (!((ee->ee_x_gain[mode] >> idx) & 0x1)) { 719 pdgain_idx[0] = idx; 720 break; 721 } 722 } 723 724 ee->ee_pd_gains[mode] = 1; 725 726 pd = &chinfo[pier].pd_curves[idx]; 727 728 pd->pd_points = AR5K_EEPROM_N_PWR_POINTS_5111; 729 730 /* Allocate pd points for this curve */ 731 pd->pd_step = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111, 732 sizeof(u8), GFP_KERNEL); 733 if (!pd->pd_step) 734 return -ENOMEM; 735 736 pd->pd_pwr = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111, 737 sizeof(s16), GFP_KERNEL); 738 if (!pd->pd_pwr) 739 return -ENOMEM; 740 741 /* Fill raw dataset 742 * (convert power to 0.25dB units 743 * for RF5112 combatibility) */ 744 for (point = 0; point < pd->pd_points; point++) { 745 746 /* Absolute values */ 747 pd->pd_pwr[point] = 2 * pcinfo->pwr[point]; 748 749 /* Already sorted */ 750 pd->pd_step[point] = pcinfo->pcdac[point]; 751 } 752 753 /* Set min/max pwr */ 754 chinfo[pier].min_pwr = pd->pd_pwr[0]; 755 chinfo[pier].max_pwr = pd->pd_pwr[10]; 756 757 } 758 759 return 0; 760 } 761 762 /* Parse EEPROM data */ 763 static int 764 ath5k_eeprom_read_pcal_info_5111(struct ath5k_hw *ah, int mode) 765 { 766 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 767 struct ath5k_chan_pcal_info *pcal; 768 int offset, ret; 769 int i; 770 u16 val; 771 772 offset = AR5K_EEPROM_GROUPS_START(ee->ee_version); 773 switch(mode) { 774 case AR5K_EEPROM_MODE_11A: 775 if (!AR5K_EEPROM_HDR_11A(ee->ee_header)) 776 return 0; 777 778 ret = ath5k_eeprom_init_11a_pcal_freq(ah, 779 offset + AR5K_EEPROM_GROUP1_OFFSET); 780 if (ret < 0) 781 return ret; 782 783 offset += AR5K_EEPROM_GROUP2_OFFSET; 784 pcal = ee->ee_pwr_cal_a; 785 break; 786 case AR5K_EEPROM_MODE_11B: 787 if (!AR5K_EEPROM_HDR_11B(ee->ee_header) && 788 !AR5K_EEPROM_HDR_11G(ee->ee_header)) 789 return 0; 790 791 pcal = ee->ee_pwr_cal_b; 792 offset += AR5K_EEPROM_GROUP3_OFFSET; 793 794 /* fixed piers */ 795 pcal[0].freq = 2412; 796 pcal[1].freq = 2447; 797 pcal[2].freq = 2484; 798 ee->ee_n_piers[mode] = 3; 799 break; 800 case AR5K_EEPROM_MODE_11G: 801 if (!AR5K_EEPROM_HDR_11G(ee->ee_header)) 802 return 0; 803 804 pcal = ee->ee_pwr_cal_g; 805 offset += AR5K_EEPROM_GROUP4_OFFSET; 806 807 /* fixed piers */ 808 pcal[0].freq = 2312; 809 pcal[1].freq = 2412; 810 pcal[2].freq = 2484; 811 ee->ee_n_piers[mode] = 3; 812 break; 813 default: 814 return -EINVAL; 815 } 816 817 for (i = 0; i < ee->ee_n_piers[mode]; i++) { 818 struct ath5k_chan_pcal_info_rf5111 *cdata = 819 &pcal[i].rf5111_info; 820 821 AR5K_EEPROM_READ(offset++, val); 822 cdata->pcdac_max = ((val >> 10) & AR5K_EEPROM_PCDAC_M); 823 cdata->pcdac_min = ((val >> 4) & AR5K_EEPROM_PCDAC_M); 824 cdata->pwr[0] = ((val << 2) & AR5K_EEPROM_POWER_M); 825 826 AR5K_EEPROM_READ(offset++, val); 827 cdata->pwr[0] |= ((val >> 14) & 0x3); 828 cdata->pwr[1] = ((val >> 8) & AR5K_EEPROM_POWER_M); 829 cdata->pwr[2] = ((val >> 2) & AR5K_EEPROM_POWER_M); 830 cdata->pwr[3] = ((val << 4) & AR5K_EEPROM_POWER_M); 831 832 AR5K_EEPROM_READ(offset++, val); 833 cdata->pwr[3] |= ((val >> 12) & 0xf); 834 cdata->pwr[4] = ((val >> 6) & AR5K_EEPROM_POWER_M); 835 cdata->pwr[5] = (val & AR5K_EEPROM_POWER_M); 836 837 AR5K_EEPROM_READ(offset++, val); 838 cdata->pwr[6] = ((val >> 10) & AR5K_EEPROM_POWER_M); 839 cdata->pwr[7] = ((val >> 4) & AR5K_EEPROM_POWER_M); 840 cdata->pwr[8] = ((val << 2) & AR5K_EEPROM_POWER_M); 841 842 AR5K_EEPROM_READ(offset++, val); 843 cdata->pwr[8] |= ((val >> 14) & 0x3); 844 cdata->pwr[9] = ((val >> 8) & AR5K_EEPROM_POWER_M); 845 cdata->pwr[10] = ((val >> 2) & AR5K_EEPROM_POWER_M); 846 847 ath5k_get_pcdac_intercepts(ah, cdata->pcdac_min, 848 cdata->pcdac_max, cdata->pcdac); 849 } 850 851 return ath5k_eeprom_convert_pcal_info_5111(ah, mode, pcal); 852 } 853 854 855 /* 856 * Read power calibration for RF5112 chips 857 * 858 * For RF5112 we have 4 XPD -eXternal Power Detector- curves 859 * for each calibrated channel on 0, -6, -12 and -18dbm but we only 860 * use the higher (3) and the lower (0) curves. Each curve has 0.5dB 861 * power steps on x axis and PCDAC steps on y axis and looks like a 862 * linear function. To recreate the curve and pass the power values 863 * on hw, we read 4 points for xpd 0 (lower gain -> max power) 864 * and 3 points for xpd 3 (higher gain -> lower power) here and 865 * interpolate later. 866 * 867 * Note: Many vendors just use xpd 0 so xpd 3 is zeroed. 868 */ 869 870 /* Convert RF5112 specific data to generic raw data 871 * used by interpolation code */ 872 static int 873 ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode, 874 struct ath5k_chan_pcal_info *chinfo) 875 { 876 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 877 struct ath5k_chan_pcal_info_rf5112 *pcinfo; 878 u8 *pdgain_idx = ee->ee_pdc_to_idx[mode]; 879 unsigned int pier, pdg, point; 880 881 /* Fill raw data for each calibration pier */ 882 for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) { 883 884 pcinfo = &chinfo[pier].rf5112_info; 885 886 /* Allocate pd_curves for this cal pier */ 887 chinfo[pier].pd_curves = 888 kcalloc(AR5K_EEPROM_N_PD_CURVES, 889 sizeof(struct ath5k_pdgain_info), 890 GFP_KERNEL); 891 892 if (!chinfo[pier].pd_curves) 893 return -ENOMEM; 894 895 /* Fill pd_curves */ 896 for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { 897 898 u8 idx = pdgain_idx[pdg]; 899 struct ath5k_pdgain_info *pd = 900 &chinfo[pier].pd_curves[idx]; 901 902 /* Lowest gain curve (max power) */ 903 if (pdg == 0) { 904 /* One more point for better accuracy */ 905 pd->pd_points = AR5K_EEPROM_N_XPD0_POINTS; 906 907 /* Allocate pd points for this curve */ 908 pd->pd_step = kcalloc(pd->pd_points, 909 sizeof(u8), GFP_KERNEL); 910 911 if (!pd->pd_step) 912 return -ENOMEM; 913 914 pd->pd_pwr = kcalloc(pd->pd_points, 915 sizeof(s16), GFP_KERNEL); 916 917 if (!pd->pd_pwr) 918 return -ENOMEM; 919 920 921 /* Fill raw dataset 922 * (all power levels are in 0.25dB units) */ 923 pd->pd_step[0] = pcinfo->pcdac_x0[0]; 924 pd->pd_pwr[0] = pcinfo->pwr_x0[0]; 925 926 for (point = 1; point < pd->pd_points; 927 point++) { 928 /* Absolute values */ 929 pd->pd_pwr[point] = 930 pcinfo->pwr_x0[point]; 931 932 /* Deltas */ 933 pd->pd_step[point] = 934 pd->pd_step[point - 1] + 935 pcinfo->pcdac_x0[point]; 936 } 937 938 /* Set min power for this frequency */ 939 chinfo[pier].min_pwr = pd->pd_pwr[0]; 940 941 /* Highest gain curve (min power) */ 942 } else if (pdg == 1) { 943 944 pd->pd_points = AR5K_EEPROM_N_XPD3_POINTS; 945 946 /* Allocate pd points for this curve */ 947 pd->pd_step = kcalloc(pd->pd_points, 948 sizeof(u8), GFP_KERNEL); 949 950 if (!pd->pd_step) 951 return -ENOMEM; 952 953 pd->pd_pwr = kcalloc(pd->pd_points, 954 sizeof(s16), GFP_KERNEL); 955 956 if (!pd->pd_pwr) 957 return -ENOMEM; 958 959 /* Fill raw dataset 960 * (all power levels are in 0.25dB units) */ 961 for (point = 0; point < pd->pd_points; 962 point++) { 963 /* Absolute values */ 964 pd->pd_pwr[point] = 965 pcinfo->pwr_x3[point]; 966 967 /* Fixed points */ 968 pd->pd_step[point] = 969 pcinfo->pcdac_x3[point]; 970 } 971 972 /* Since we have a higher gain curve 973 * override min power */ 974 chinfo[pier].min_pwr = pd->pd_pwr[0]; 975 } 976 } 977 } 978 979 return 0; 980 } 981 982 /* Parse EEPROM data */ 983 static int 984 ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw *ah, int mode) 985 { 986 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 987 struct ath5k_chan_pcal_info_rf5112 *chan_pcal_info; 988 struct ath5k_chan_pcal_info *gen_chan_info; 989 u8 *pdgain_idx = ee->ee_pdc_to_idx[mode]; 990 u32 offset; 991 u8 i, c; 992 u16 val; 993 int ret; 994 u8 pd_gains = 0; 995 996 /* Count how many curves we have and 997 * identify them (which one of the 4 998 * available curves we have on each count). 999 * Curves are stored from lower (x0) to 1000 * higher (x3) gain */ 1001 for (i = 0; i < AR5K_EEPROM_N_PD_CURVES; i++) { 1002 /* ee_x_gain[mode] is x gain mask */ 1003 if ((ee->ee_x_gain[mode] >> i) & 0x1) 1004 pdgain_idx[pd_gains++] = i; 1005 } 1006 ee->ee_pd_gains[mode] = pd_gains; 1007 1008 if (pd_gains == 0 || pd_gains > 2) 1009 return -EINVAL; 1010 1011 switch (mode) { 1012 case AR5K_EEPROM_MODE_11A: 1013 /* 1014 * Read 5GHz EEPROM channels 1015 */ 1016 offset = AR5K_EEPROM_GROUPS_START(ee->ee_version); 1017 ath5k_eeprom_init_11a_pcal_freq(ah, offset); 1018 1019 offset += AR5K_EEPROM_GROUP2_OFFSET; 1020 gen_chan_info = ee->ee_pwr_cal_a; 1021 break; 1022 case AR5K_EEPROM_MODE_11B: 1023 offset = AR5K_EEPROM_GROUPS_START(ee->ee_version); 1024 if (AR5K_EEPROM_HDR_11A(ee->ee_header)) 1025 offset += AR5K_EEPROM_GROUP3_OFFSET; 1026 1027 /* NB: frequency piers parsed during mode init */ 1028 gen_chan_info = ee->ee_pwr_cal_b; 1029 break; 1030 case AR5K_EEPROM_MODE_11G: 1031 offset = AR5K_EEPROM_GROUPS_START(ee->ee_version); 1032 if (AR5K_EEPROM_HDR_11A(ee->ee_header)) 1033 offset += AR5K_EEPROM_GROUP4_OFFSET; 1034 else if (AR5K_EEPROM_HDR_11B(ee->ee_header)) 1035 offset += AR5K_EEPROM_GROUP2_OFFSET; 1036 1037 /* NB: frequency piers parsed during mode init */ 1038 gen_chan_info = ee->ee_pwr_cal_g; 1039 break; 1040 default: 1041 return -EINVAL; 1042 } 1043 1044 for (i = 0; i < ee->ee_n_piers[mode]; i++) { 1045 chan_pcal_info = &gen_chan_info[i].rf5112_info; 1046 1047 /* Power values in quarter dB 1048 * for the lower xpd gain curve 1049 * (0 dBm -> higher output power) */ 1050 for (c = 0; c < AR5K_EEPROM_N_XPD0_POINTS; c++) { 1051 AR5K_EEPROM_READ(offset++, val); 1052 chan_pcal_info->pwr_x0[c] = (s8) (val & 0xff); 1053 chan_pcal_info->pwr_x0[++c] = (s8) ((val >> 8) & 0xff); 1054 } 1055 1056 /* PCDAC steps 1057 * corresponding to the above power 1058 * measurements */ 1059 AR5K_EEPROM_READ(offset++, val); 1060 chan_pcal_info->pcdac_x0[1] = (val & 0x1f); 1061 chan_pcal_info->pcdac_x0[2] = ((val >> 5) & 0x1f); 1062 chan_pcal_info->pcdac_x0[3] = ((val >> 10) & 0x1f); 1063 1064 /* Power values in quarter dB 1065 * for the higher xpd gain curve 1066 * (18 dBm -> lower output power) */ 1067 AR5K_EEPROM_READ(offset++, val); 1068 chan_pcal_info->pwr_x3[0] = (s8) (val & 0xff); 1069 chan_pcal_info->pwr_x3[1] = (s8) ((val >> 8) & 0xff); 1070 1071 AR5K_EEPROM_READ(offset++, val); 1072 chan_pcal_info->pwr_x3[2] = (val & 0xff); 1073 1074 /* PCDAC steps 1075 * corresponding to the above power 1076 * measurements (fixed) */ 1077 chan_pcal_info->pcdac_x3[0] = 20; 1078 chan_pcal_info->pcdac_x3[1] = 35; 1079 chan_pcal_info->pcdac_x3[2] = 63; 1080 1081 if (ee->ee_version >= AR5K_EEPROM_VERSION_4_3) { 1082 chan_pcal_info->pcdac_x0[0] = ((val >> 8) & 0x3f); 1083 1084 /* Last xpd0 power level is also channel maximum */ 1085 gen_chan_info[i].max_pwr = chan_pcal_info->pwr_x0[3]; 1086 } else { 1087 chan_pcal_info->pcdac_x0[0] = 1; 1088 gen_chan_info[i].max_pwr = (s8) ((val >> 8) & 0xff); 1089 } 1090 1091 } 1092 1093 return ath5k_eeprom_convert_pcal_info_5112(ah, mode, gen_chan_info); 1094 } 1095 1096 1097 /* 1098 * Read power calibration for RF2413 chips 1099 * 1100 * For RF2413 we have a Power to PDDAC table (Power Detector) 1101 * instead of a PCDAC and 4 pd gain curves for each calibrated channel. 1102 * Each curve has power on x axis in 0.5 db steps and PDDADC steps on y 1103 * axis and looks like an exponential function like the RF5111 curve. 1104 * 1105 * To recreate the curves we read here the points and interpolate 1106 * later. Note that in most cases only 2 (higher and lower) curves are 1107 * used (like RF5112) but vendors have the oportunity to include all 1108 * 4 curves on eeprom. The final curve (higher power) has an extra 1109 * point for better accuracy like RF5112. 1110 */ 1111 1112 /* For RF2413 power calibration data doesn't start on a fixed location and 1113 * if a mode is not supported, it's section is missing -not zeroed-. 1114 * So we need to calculate the starting offset for each section by using 1115 * these two functions */ 1116 1117 /* Return the size of each section based on the mode and the number of pd 1118 * gains available (maximum 4). */ 1119 static inline unsigned int 1120 ath5k_pdgains_size_2413(struct ath5k_eeprom_info *ee, unsigned int mode) 1121 { 1122 static const unsigned int pdgains_size[] = { 4, 6, 9, 12 }; 1123 unsigned int sz; 1124 1125 sz = pdgains_size[ee->ee_pd_gains[mode] - 1]; 1126 sz *= ee->ee_n_piers[mode]; 1127 1128 return sz; 1129 } 1130 1131 /* Return the starting offset for a section based on the modes supported 1132 * and each section's size. */ 1133 static unsigned int 1134 ath5k_cal_data_offset_2413(struct ath5k_eeprom_info *ee, int mode) 1135 { 1136 u32 offset = AR5K_EEPROM_CAL_DATA_START(ee->ee_misc4); 1137 1138 switch(mode) { 1139 case AR5K_EEPROM_MODE_11G: 1140 if (AR5K_EEPROM_HDR_11B(ee->ee_header)) 1141 offset += ath5k_pdgains_size_2413(ee, 1142 AR5K_EEPROM_MODE_11B) + 1143 AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2; 1144 /* fall through */ 1145 case AR5K_EEPROM_MODE_11B: 1146 if (AR5K_EEPROM_HDR_11A(ee->ee_header)) 1147 offset += ath5k_pdgains_size_2413(ee, 1148 AR5K_EEPROM_MODE_11A) + 1149 AR5K_EEPROM_N_5GHZ_CHAN / 2; 1150 /* fall through */ 1151 case AR5K_EEPROM_MODE_11A: 1152 break; 1153 default: 1154 break; 1155 } 1156 1157 return offset; 1158 } 1159 1160 /* Convert RF2413 specific data to generic raw data 1161 * used by interpolation code */ 1162 static int 1163 ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode, 1164 struct ath5k_chan_pcal_info *chinfo) 1165 { 1166 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 1167 struct ath5k_chan_pcal_info_rf2413 *pcinfo; 1168 u8 *pdgain_idx = ee->ee_pdc_to_idx[mode]; 1169 unsigned int pier, pdg, point; 1170 1171 /* Fill raw data for each calibration pier */ 1172 for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) { 1173 1174 pcinfo = &chinfo[pier].rf2413_info; 1175 1176 /* Allocate pd_curves for this cal pier */ 1177 chinfo[pier].pd_curves = 1178 kcalloc(AR5K_EEPROM_N_PD_CURVES, 1179 sizeof(struct ath5k_pdgain_info), 1180 GFP_KERNEL); 1181 1182 if (!chinfo[pier].pd_curves) 1183 return -ENOMEM; 1184 1185 /* Fill pd_curves */ 1186 for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { 1187 1188 u8 idx = pdgain_idx[pdg]; 1189 struct ath5k_pdgain_info *pd = 1190 &chinfo[pier].pd_curves[idx]; 1191 1192 /* One more point for the highest power 1193 * curve (lowest gain) */ 1194 if (pdg == ee->ee_pd_gains[mode] - 1) 1195 pd->pd_points = AR5K_EEPROM_N_PD_POINTS; 1196 else 1197 pd->pd_points = AR5K_EEPROM_N_PD_POINTS - 1; 1198 1199 /* Allocate pd points for this curve */ 1200 pd->pd_step = kcalloc(pd->pd_points, 1201 sizeof(u8), GFP_KERNEL); 1202 1203 if (!pd->pd_step) 1204 return -ENOMEM; 1205 1206 pd->pd_pwr = kcalloc(pd->pd_points, 1207 sizeof(s16), GFP_KERNEL); 1208 1209 if (!pd->pd_pwr) 1210 return -ENOMEM; 1211 1212 /* Fill raw dataset 1213 * convert all pwr levels to 1214 * quarter dB for RF5112 combatibility */ 1215 pd->pd_step[0] = pcinfo->pddac_i[pdg]; 1216 pd->pd_pwr[0] = 4 * pcinfo->pwr_i[pdg]; 1217 1218 for (point = 1; point < pd->pd_points; point++) { 1219 1220 pd->pd_pwr[point] = pd->pd_pwr[point - 1] + 1221 2 * pcinfo->pwr[pdg][point - 1]; 1222 1223 pd->pd_step[point] = pd->pd_step[point - 1] + 1224 pcinfo->pddac[pdg][point - 1]; 1225 1226 } 1227 1228 /* Highest gain curve -> min power */ 1229 if (pdg == 0) 1230 chinfo[pier].min_pwr = pd->pd_pwr[0]; 1231 1232 /* Lowest gain curve -> max power */ 1233 if (pdg == ee->ee_pd_gains[mode] - 1) 1234 chinfo[pier].max_pwr = 1235 pd->pd_pwr[pd->pd_points - 1]; 1236 } 1237 } 1238 1239 return 0; 1240 } 1241 1242 /* Parse EEPROM data */ 1243 static int 1244 ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode) 1245 { 1246 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 1247 struct ath5k_chan_pcal_info_rf2413 *pcinfo; 1248 struct ath5k_chan_pcal_info *chinfo; 1249 u8 *pdgain_idx = ee->ee_pdc_to_idx[mode]; 1250 u32 offset; 1251 int idx, i, ret; 1252 u16 val; 1253 u8 pd_gains = 0; 1254 1255 /* Count how many curves we have and 1256 * identify them (which one of the 4 1257 * available curves we have on each count). 1258 * Curves are stored from higher to 1259 * lower gain so we go backwards */ 1260 for (idx = AR5K_EEPROM_N_PD_CURVES - 1; idx >= 0; idx--) { 1261 /* ee_x_gain[mode] is x gain mask */ 1262 if ((ee->ee_x_gain[mode] >> idx) & 0x1) 1263 pdgain_idx[pd_gains++] = idx; 1264 1265 } 1266 ee->ee_pd_gains[mode] = pd_gains; 1267 1268 if (pd_gains == 0) 1269 return -EINVAL; 1270 1271 offset = ath5k_cal_data_offset_2413(ee, mode); 1272 switch (mode) { 1273 case AR5K_EEPROM_MODE_11A: 1274 if (!AR5K_EEPROM_HDR_11A(ee->ee_header)) 1275 return 0; 1276 1277 ath5k_eeprom_init_11a_pcal_freq(ah, offset); 1278 offset += AR5K_EEPROM_N_5GHZ_CHAN / 2; 1279 chinfo = ee->ee_pwr_cal_a; 1280 break; 1281 case AR5K_EEPROM_MODE_11B: 1282 if (!AR5K_EEPROM_HDR_11B(ee->ee_header)) 1283 return 0; 1284 1285 ath5k_eeprom_init_11bg_2413(ah, mode, offset); 1286 offset += AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2; 1287 chinfo = ee->ee_pwr_cal_b; 1288 break; 1289 case AR5K_EEPROM_MODE_11G: 1290 if (!AR5K_EEPROM_HDR_11G(ee->ee_header)) 1291 return 0; 1292 1293 ath5k_eeprom_init_11bg_2413(ah, mode, offset); 1294 offset += AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2; 1295 chinfo = ee->ee_pwr_cal_g; 1296 break; 1297 default: 1298 return -EINVAL; 1299 } 1300 1301 for (i = 0; i < ee->ee_n_piers[mode]; i++) { 1302 pcinfo = &chinfo[i].rf2413_info; 1303 1304 /* 1305 * Read pwr_i, pddac_i and the first 1306 * 2 pd points (pwr, pddac) 1307 */ 1308 AR5K_EEPROM_READ(offset++, val); 1309 pcinfo->pwr_i[0] = val & 0x1f; 1310 pcinfo->pddac_i[0] = (val >> 5) & 0x7f; 1311 pcinfo->pwr[0][0] = (val >> 12) & 0xf; 1312 1313 AR5K_EEPROM_READ(offset++, val); 1314 pcinfo->pddac[0][0] = val & 0x3f; 1315 pcinfo->pwr[0][1] = (val >> 6) & 0xf; 1316 pcinfo->pddac[0][1] = (val >> 10) & 0x3f; 1317 1318 AR5K_EEPROM_READ(offset++, val); 1319 pcinfo->pwr[0][2] = val & 0xf; 1320 pcinfo->pddac[0][2] = (val >> 4) & 0x3f; 1321 1322 pcinfo->pwr[0][3] = 0; 1323 pcinfo->pddac[0][3] = 0; 1324 1325 if (pd_gains > 1) { 1326 /* 1327 * Pd gain 0 is not the last pd gain 1328 * so it only has 2 pd points. 1329 * Continue wih pd gain 1. 1330 */ 1331 pcinfo->pwr_i[1] = (val >> 10) & 0x1f; 1332 1333 pcinfo->pddac_i[1] = (val >> 15) & 0x1; 1334 AR5K_EEPROM_READ(offset++, val); 1335 pcinfo->pddac_i[1] |= (val & 0x3F) << 1; 1336 1337 pcinfo->pwr[1][0] = (val >> 6) & 0xf; 1338 pcinfo->pddac[1][0] = (val >> 10) & 0x3f; 1339 1340 AR5K_EEPROM_READ(offset++, val); 1341 pcinfo->pwr[1][1] = val & 0xf; 1342 pcinfo->pddac[1][1] = (val >> 4) & 0x3f; 1343 pcinfo->pwr[1][2] = (val >> 10) & 0xf; 1344 1345 pcinfo->pddac[1][2] = (val >> 14) & 0x3; 1346 AR5K_EEPROM_READ(offset++, val); 1347 pcinfo->pddac[1][2] |= (val & 0xF) << 2; 1348 1349 pcinfo->pwr[1][3] = 0; 1350 pcinfo->pddac[1][3] = 0; 1351 } else if (pd_gains == 1) { 1352 /* 1353 * Pd gain 0 is the last one so 1354 * read the extra point. 1355 */ 1356 pcinfo->pwr[0][3] = (val >> 10) & 0xf; 1357 1358 pcinfo->pddac[0][3] = (val >> 14) & 0x3; 1359 AR5K_EEPROM_READ(offset++, val); 1360 pcinfo->pddac[0][3] |= (val & 0xF) << 2; 1361 } 1362 1363 /* 1364 * Proceed with the other pd_gains 1365 * as above. 1366 */ 1367 if (pd_gains > 2) { 1368 pcinfo->pwr_i[2] = (val >> 4) & 0x1f; 1369 pcinfo->pddac_i[2] = (val >> 9) & 0x7f; 1370 1371 AR5K_EEPROM_READ(offset++, val); 1372 pcinfo->pwr[2][0] = (val >> 0) & 0xf; 1373 pcinfo->pddac[2][0] = (val >> 4) & 0x3f; 1374 pcinfo->pwr[2][1] = (val >> 10) & 0xf; 1375 1376 pcinfo->pddac[2][1] = (val >> 14) & 0x3; 1377 AR5K_EEPROM_READ(offset++, val); 1378 pcinfo->pddac[2][1] |= (val & 0xF) << 2; 1379 1380 pcinfo->pwr[2][2] = (val >> 4) & 0xf; 1381 pcinfo->pddac[2][2] = (val >> 8) & 0x3f; 1382 1383 pcinfo->pwr[2][3] = 0; 1384 pcinfo->pddac[2][3] = 0; 1385 } else if (pd_gains == 2) { 1386 pcinfo->pwr[1][3] = (val >> 4) & 0xf; 1387 pcinfo->pddac[1][3] = (val >> 8) & 0x3f; 1388 } 1389 1390 if (pd_gains > 3) { 1391 pcinfo->pwr_i[3] = (val >> 14) & 0x3; 1392 AR5K_EEPROM_READ(offset++, val); 1393 pcinfo->pwr_i[3] |= ((val >> 0) & 0x7) << 2; 1394 1395 pcinfo->pddac_i[3] = (val >> 3) & 0x7f; 1396 pcinfo->pwr[3][0] = (val >> 10) & 0xf; 1397 pcinfo->pddac[3][0] = (val >> 14) & 0x3; 1398 1399 AR5K_EEPROM_READ(offset++, val); 1400 pcinfo->pddac[3][0] |= (val & 0xF) << 2; 1401 pcinfo->pwr[3][1] = (val >> 4) & 0xf; 1402 pcinfo->pddac[3][1] = (val >> 8) & 0x3f; 1403 1404 pcinfo->pwr[3][2] = (val >> 14) & 0x3; 1405 AR5K_EEPROM_READ(offset++, val); 1406 pcinfo->pwr[3][2] |= ((val >> 0) & 0x3) << 2; 1407 1408 pcinfo->pddac[3][2] = (val >> 2) & 0x3f; 1409 pcinfo->pwr[3][3] = (val >> 8) & 0xf; 1410 1411 pcinfo->pddac[3][3] = (val >> 12) & 0xF; 1412 AR5K_EEPROM_READ(offset++, val); 1413 pcinfo->pddac[3][3] |= ((val >> 0) & 0x3) << 4; 1414 } else if (pd_gains == 3) { 1415 pcinfo->pwr[2][3] = (val >> 14) & 0x3; 1416 AR5K_EEPROM_READ(offset++, val); 1417 pcinfo->pwr[2][3] |= ((val >> 0) & 0x3) << 2; 1418 1419 pcinfo->pddac[2][3] = (val >> 2) & 0x3f; 1420 } 1421 } 1422 1423 return ath5k_eeprom_convert_pcal_info_2413(ah, mode, chinfo); 1424 } 1425 1426 1427 /* 1428 * Read per rate target power (this is the maximum tx power 1429 * supported by the card). This info is used when setting 1430 * tx power, no matter the channel. 1431 * 1432 * This also works for v5 EEPROMs. 1433 */ 1434 static int 1435 ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned int mode) 1436 { 1437 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 1438 struct ath5k_rate_pcal_info *rate_pcal_info; 1439 u8 *rate_target_pwr_num; 1440 u32 offset; 1441 u16 val; 1442 int ret, i; 1443 1444 offset = AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1); 1445 rate_target_pwr_num = &ee->ee_rate_target_pwr_num[mode]; 1446 switch (mode) { 1447 case AR5K_EEPROM_MODE_11A: 1448 offset += AR5K_EEPROM_TARGET_PWR_OFF_11A(ee->ee_version); 1449 rate_pcal_info = ee->ee_rate_tpwr_a; 1450 ee->ee_rate_target_pwr_num[mode] = AR5K_EEPROM_N_5GHZ_CHAN; 1451 break; 1452 case AR5K_EEPROM_MODE_11B: 1453 offset += AR5K_EEPROM_TARGET_PWR_OFF_11B(ee->ee_version); 1454 rate_pcal_info = ee->ee_rate_tpwr_b; 1455 ee->ee_rate_target_pwr_num[mode] = 2; /* 3rd is g mode's 1st */ 1456 break; 1457 case AR5K_EEPROM_MODE_11G: 1458 offset += AR5K_EEPROM_TARGET_PWR_OFF_11G(ee->ee_version); 1459 rate_pcal_info = ee->ee_rate_tpwr_g; 1460 ee->ee_rate_target_pwr_num[mode] = AR5K_EEPROM_N_2GHZ_CHAN; 1461 break; 1462 default: 1463 return -EINVAL; 1464 } 1465 1466 /* Different freq mask for older eeproms (<= v3.2) */ 1467 if (ee->ee_version <= AR5K_EEPROM_VERSION_3_2) { 1468 for (i = 0; i < (*rate_target_pwr_num); i++) { 1469 AR5K_EEPROM_READ(offset++, val); 1470 rate_pcal_info[i].freq = 1471 ath5k_eeprom_bin2freq(ee, (val >> 9) & 0x7f, mode); 1472 1473 rate_pcal_info[i].target_power_6to24 = ((val >> 3) & 0x3f); 1474 rate_pcal_info[i].target_power_36 = (val << 3) & 0x3f; 1475 1476 AR5K_EEPROM_READ(offset++, val); 1477 1478 if (rate_pcal_info[i].freq == AR5K_EEPROM_CHANNEL_DIS || 1479 val == 0) { 1480 (*rate_target_pwr_num) = i; 1481 break; 1482 } 1483 1484 rate_pcal_info[i].target_power_36 |= ((val >> 13) & 0x7); 1485 rate_pcal_info[i].target_power_48 = ((val >> 7) & 0x3f); 1486 rate_pcal_info[i].target_power_54 = ((val >> 1) & 0x3f); 1487 } 1488 } else { 1489 for (i = 0; i < (*rate_target_pwr_num); i++) { 1490 AR5K_EEPROM_READ(offset++, val); 1491 rate_pcal_info[i].freq = 1492 ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode); 1493 1494 rate_pcal_info[i].target_power_6to24 = ((val >> 2) & 0x3f); 1495 rate_pcal_info[i].target_power_36 = (val << 4) & 0x3f; 1496 1497 AR5K_EEPROM_READ(offset++, val); 1498 1499 if (rate_pcal_info[i].freq == AR5K_EEPROM_CHANNEL_DIS || 1500 val == 0) { 1501 (*rate_target_pwr_num) = i; 1502 break; 1503 } 1504 1505 rate_pcal_info[i].target_power_36 |= (val >> 12) & 0xf; 1506 rate_pcal_info[i].target_power_48 = ((val >> 6) & 0x3f); 1507 rate_pcal_info[i].target_power_54 = (val & 0x3f); 1508 } 1509 } 1510 1511 return 0; 1512 } 1513 1514 /* 1515 * Read per channel calibration info from EEPROM 1516 * 1517 * This info is used to calibrate the baseband power table. Imagine 1518 * that for each channel there is a power curve that's hw specific 1519 * (depends on amplifier etc) and we try to "correct" this curve using 1520 * offsets we pass on to phy chip (baseband -> before amplifier) so that 1521 * it can use accurate power values when setting tx power (takes amplifier's 1522 * performance on each channel into account). 1523 * 1524 * EEPROM provides us with the offsets for some pre-calibrated channels 1525 * and we have to interpolate to create the full table for these channels and 1526 * also the table for any channel. 1527 */ 1528 static int 1529 ath5k_eeprom_read_pcal_info(struct ath5k_hw *ah) 1530 { 1531 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 1532 int (*read_pcal)(struct ath5k_hw *hw, int mode); 1533 int mode; 1534 int err; 1535 1536 if ((ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) && 1537 (AR5K_EEPROM_EEMAP(ee->ee_misc0) == 1)) 1538 read_pcal = ath5k_eeprom_read_pcal_info_5112; 1539 else if ((ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_0) && 1540 (AR5K_EEPROM_EEMAP(ee->ee_misc0) == 2)) 1541 read_pcal = ath5k_eeprom_read_pcal_info_2413; 1542 else 1543 read_pcal = ath5k_eeprom_read_pcal_info_5111; 1544 1545 1546 for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; 1547 mode++) { 1548 err = read_pcal(ah, mode); 1549 if (err) 1550 return err; 1551 1552 err = ath5k_eeprom_read_target_rate_pwr_info(ah, mode); 1553 if (err < 0) 1554 return err; 1555 } 1556 1557 return 0; 1558 } 1559 1560 static int 1561 ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode) 1562 { 1563 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 1564 struct ath5k_chan_pcal_info *chinfo; 1565 u8 pier, pdg; 1566 1567 switch (mode) { 1568 case AR5K_EEPROM_MODE_11A: 1569 if (!AR5K_EEPROM_HDR_11A(ee->ee_header)) 1570 return 0; 1571 chinfo = ee->ee_pwr_cal_a; 1572 break; 1573 case AR5K_EEPROM_MODE_11B: 1574 if (!AR5K_EEPROM_HDR_11B(ee->ee_header)) 1575 return 0; 1576 chinfo = ee->ee_pwr_cal_b; 1577 break; 1578 case AR5K_EEPROM_MODE_11G: 1579 if (!AR5K_EEPROM_HDR_11G(ee->ee_header)) 1580 return 0; 1581 chinfo = ee->ee_pwr_cal_g; 1582 break; 1583 default: 1584 return -EINVAL; 1585 } 1586 1587 for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) { 1588 if (!chinfo[pier].pd_curves) 1589 continue; 1590 1591 for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { 1592 struct ath5k_pdgain_info *pd = 1593 &chinfo[pier].pd_curves[pdg]; 1594 1595 if (pd != NULL) { 1596 kfree(pd->pd_step); 1597 kfree(pd->pd_pwr); 1598 } 1599 } 1600 1601 kfree(chinfo[pier].pd_curves); 1602 } 1603 1604 return 0; 1605 } 1606 1607 void 1608 ath5k_eeprom_detach(struct ath5k_hw *ah) 1609 { 1610 u8 mode; 1611 1612 for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++) 1613 ath5k_eeprom_free_pcal_info(ah, mode); 1614 } 1615 1616 /* Read conformance test limits used for regulatory control */ 1617 static int 1618 ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah) 1619 { 1620 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 1621 struct ath5k_edge_power *rep; 1622 unsigned int fmask, pmask; 1623 unsigned int ctl_mode; 1624 int ret, i, j; 1625 u32 offset; 1626 u16 val; 1627 1628 pmask = AR5K_EEPROM_POWER_M; 1629 fmask = AR5K_EEPROM_FREQ_M(ee->ee_version); 1630 offset = AR5K_EEPROM_CTL(ee->ee_version); 1631 ee->ee_ctls = AR5K_EEPROM_N_CTLS(ee->ee_version); 1632 for (i = 0; i < ee->ee_ctls; i += 2) { 1633 AR5K_EEPROM_READ(offset++, val); 1634 ee->ee_ctl[i] = (val >> 8) & 0xff; 1635 ee->ee_ctl[i + 1] = val & 0xff; 1636 } 1637 1638 offset = AR5K_EEPROM_GROUP8_OFFSET; 1639 if (ee->ee_version >= AR5K_EEPROM_VERSION_4_0) 1640 offset += AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1) - 1641 AR5K_EEPROM_GROUP5_OFFSET; 1642 else 1643 offset += AR5K_EEPROM_GROUPS_START(ee->ee_version); 1644 1645 rep = ee->ee_ctl_pwr; 1646 for(i = 0; i < ee->ee_ctls; i++) { 1647 switch(ee->ee_ctl[i] & AR5K_CTL_MODE_M) { 1648 case AR5K_CTL_11A: 1649 case AR5K_CTL_TURBO: 1650 ctl_mode = AR5K_EEPROM_MODE_11A; 1651 break; 1652 default: 1653 ctl_mode = AR5K_EEPROM_MODE_11G; 1654 break; 1655 } 1656 if (ee->ee_ctl[i] == 0) { 1657 if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3) 1658 offset += 8; 1659 else 1660 offset += 7; 1661 rep += AR5K_EEPROM_N_EDGES; 1662 continue; 1663 } 1664 if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3) { 1665 for (j = 0; j < AR5K_EEPROM_N_EDGES; j += 2) { 1666 AR5K_EEPROM_READ(offset++, val); 1667 rep[j].freq = (val >> 8) & fmask; 1668 rep[j + 1].freq = val & fmask; 1669 } 1670 for (j = 0; j < AR5K_EEPROM_N_EDGES; j += 2) { 1671 AR5K_EEPROM_READ(offset++, val); 1672 rep[j].edge = (val >> 8) & pmask; 1673 rep[j].flag = (val >> 14) & 1; 1674 rep[j + 1].edge = val & pmask; 1675 rep[j + 1].flag = (val >> 6) & 1; 1676 } 1677 } else { 1678 AR5K_EEPROM_READ(offset++, val); 1679 rep[0].freq = (val >> 9) & fmask; 1680 rep[1].freq = (val >> 2) & fmask; 1681 rep[2].freq = (val << 5) & fmask; 1682 1683 AR5K_EEPROM_READ(offset++, val); 1684 rep[2].freq |= (val >> 11) & 0x1f; 1685 rep[3].freq = (val >> 4) & fmask; 1686 rep[4].freq = (val << 3) & fmask; 1687 1688 AR5K_EEPROM_READ(offset++, val); 1689 rep[4].freq |= (val >> 13) & 0x7; 1690 rep[5].freq = (val >> 6) & fmask; 1691 rep[6].freq = (val << 1) & fmask; 1692 1693 AR5K_EEPROM_READ(offset++, val); 1694 rep[6].freq |= (val >> 15) & 0x1; 1695 rep[7].freq = (val >> 8) & fmask; 1696 1697 rep[0].edge = (val >> 2) & pmask; 1698 rep[1].edge = (val << 4) & pmask; 1699 1700 AR5K_EEPROM_READ(offset++, val); 1701 rep[1].edge |= (val >> 12) & 0xf; 1702 rep[2].edge = (val >> 6) & pmask; 1703 rep[3].edge = val & pmask; 1704 1705 AR5K_EEPROM_READ(offset++, val); 1706 rep[4].edge = (val >> 10) & pmask; 1707 rep[5].edge = (val >> 4) & pmask; 1708 rep[6].edge = (val << 2) & pmask; 1709 1710 AR5K_EEPROM_READ(offset++, val); 1711 rep[6].edge |= (val >> 14) & 0x3; 1712 rep[7].edge = (val >> 8) & pmask; 1713 } 1714 for (j = 0; j < AR5K_EEPROM_N_EDGES; j++) { 1715 rep[j].freq = ath5k_eeprom_bin2freq(ee, 1716 rep[j].freq, ctl_mode); 1717 } 1718 rep += AR5K_EEPROM_N_EDGES; 1719 } 1720 1721 return 0; 1722 } 1723 1724 static int 1725 ath5k_eeprom_read_spur_chans(struct ath5k_hw *ah) 1726 { 1727 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 1728 u32 offset; 1729 u16 val; 1730 int ret = 0, i; 1731 1732 offset = AR5K_EEPROM_CTL(ee->ee_version) + 1733 AR5K_EEPROM_N_CTLS(ee->ee_version); 1734 1735 if (ee->ee_version < AR5K_EEPROM_VERSION_5_3) { 1736 /* No spur info for 5GHz */ 1737 ee->ee_spur_chans[0][0] = AR5K_EEPROM_NO_SPUR; 1738 /* 2 channels for 2GHz (2464/2420) */ 1739 ee->ee_spur_chans[0][1] = AR5K_EEPROM_5413_SPUR_CHAN_1; 1740 ee->ee_spur_chans[1][1] = AR5K_EEPROM_5413_SPUR_CHAN_2; 1741 ee->ee_spur_chans[2][1] = AR5K_EEPROM_NO_SPUR; 1742 } else if (ee->ee_version >= AR5K_EEPROM_VERSION_5_3) { 1743 for (i = 0; i < AR5K_EEPROM_N_SPUR_CHANS; i++) { 1744 AR5K_EEPROM_READ(offset, val); 1745 ee->ee_spur_chans[i][0] = val; 1746 AR5K_EEPROM_READ(offset + AR5K_EEPROM_N_SPUR_CHANS, 1747 val); 1748 ee->ee_spur_chans[i][1] = val; 1749 offset++; 1750 } 1751 } 1752 1753 return ret; 1754 } 1755 1756 /* 1757 * Initialize eeprom data structure 1758 */ 1759 int 1760 ath5k_eeprom_init(struct ath5k_hw *ah) 1761 { 1762 int err; 1763 1764 err = ath5k_eeprom_init_header(ah); 1765 if (err < 0) 1766 return err; 1767 1768 err = ath5k_eeprom_init_modes(ah); 1769 if (err < 0) 1770 return err; 1771 1772 err = ath5k_eeprom_read_pcal_info(ah); 1773 if (err < 0) 1774 return err; 1775 1776 err = ath5k_eeprom_read_ctl_info(ah); 1777 if (err < 0) 1778 return err; 1779 1780 err = ath5k_eeprom_read_spur_chans(ah); 1781 if (err < 0) 1782 return err; 1783 1784 return 0; 1785 } 1786 1787 /* 1788 * Read the MAC address from eeprom 1789 */ 1790 int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac) 1791 { 1792 u8 mac_d[ETH_ALEN] = {}; 1793 u32 total, offset; 1794 u16 data; 1795 int octet, ret; 1796 1797 ret = ath5k_hw_eeprom_read(ah, 0x20, &data); 1798 if (ret) 1799 return ret; 1800 1801 for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) { 1802 ret = ath5k_hw_eeprom_read(ah, offset, &data); 1803 if (ret) 1804 return ret; 1805 1806 total += data; 1807 mac_d[octet + 1] = data & 0xff; 1808 mac_d[octet] = data >> 8; 1809 octet += 2; 1810 } 1811 1812 if (!total || total == 3 * 0xffff) 1813 return -EINVAL; 1814 1815 memcpy(mac, mac_d, ETH_ALEN); 1816 1817 return 0; 1818 } 1819