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