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