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