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