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