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