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 ee->ee_pd_gains[mode] = 1; 750 751 pd = &chinfo[pier].pd_curves[idx]; 752 753 pd->pd_points = AR5K_EEPROM_N_PWR_POINTS_5111; 754 755 /* Allocate pd points for this curve */ 756 pd->pd_step = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111, 757 sizeof(u8), GFP_KERNEL); 758 if (!pd->pd_step) 759 goto err_out; 760 761 pd->pd_pwr = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111, 762 sizeof(s16), GFP_KERNEL); 763 if (!pd->pd_pwr) 764 goto err_out; 765 766 /* Fill raw dataset 767 * (convert power to 0.25dB units 768 * for RF5112 compatibility) */ 769 for (point = 0; point < pd->pd_points; point++) { 770 771 /* Absolute values */ 772 pd->pd_pwr[point] = 2 * pcinfo->pwr[point]; 773 774 /* Already sorted */ 775 pd->pd_step[point] = pcinfo->pcdac[point]; 776 } 777 778 /* Set min/max pwr */ 779 chinfo[pier].min_pwr = pd->pd_pwr[0]; 780 chinfo[pier].max_pwr = pd->pd_pwr[10]; 781 782 } 783 784 return 0; 785 786err_out: 787 ath5k_eeprom_free_pcal_info(ah, mode); 788 return -ENOMEM; 789} 790 791/* Parse EEPROM data */ 792static int 793ath5k_eeprom_read_pcal_info_5111(struct ath5k_hw *ah, int mode) 794{ 795 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 796 struct ath5k_chan_pcal_info *pcal; 797 int offset, ret; 798 int i; 799 u16 val; 800 801 offset = AR5K_EEPROM_GROUPS_START(ee->ee_version); 802 switch (mode) { 803 case AR5K_EEPROM_MODE_11A: 804 if (!AR5K_EEPROM_HDR_11A(ee->ee_header)) 805 return 0; 806 807 ret = ath5k_eeprom_init_11a_pcal_freq(ah, 808 offset + AR5K_EEPROM_GROUP1_OFFSET); 809 if (ret < 0) 810 return ret; 811 812 offset += AR5K_EEPROM_GROUP2_OFFSET; 813 pcal = ee->ee_pwr_cal_a; 814 break; 815 case AR5K_EEPROM_MODE_11B: 816 if (!AR5K_EEPROM_HDR_11B(ee->ee_header) && 817 !AR5K_EEPROM_HDR_11G(ee->ee_header)) 818 return 0; 819 820 pcal = ee->ee_pwr_cal_b; 821 offset += AR5K_EEPROM_GROUP3_OFFSET; 822 823 /* fixed piers */ 824 pcal[0].freq = 2412; 825 pcal[1].freq = 2447; 826 pcal[2].freq = 2484; 827 ee->ee_n_piers[mode] = 3; 828 break; 829 case AR5K_EEPROM_MODE_11G: 830 if (!AR5K_EEPROM_HDR_11G(ee->ee_header)) 831 return 0; 832 833 pcal = ee->ee_pwr_cal_g; 834 offset += AR5K_EEPROM_GROUP4_OFFSET; 835 836 /* fixed piers */ 837 pcal[0].freq = 2312; 838 pcal[1].freq = 2412; 839 pcal[2].freq = 2484; 840 ee->ee_n_piers[mode] = 3; 841 break; 842 default: 843 return -EINVAL; 844 } 845 846 for (i = 0; i < ee->ee_n_piers[mode]; i++) { 847 struct ath5k_chan_pcal_info_rf5111 *cdata = 848 &pcal[i].rf5111_info; 849 850 AR5K_EEPROM_READ(offset++, val); 851 cdata->pcdac_max = ((val >> 10) & AR5K_EEPROM_PCDAC_M); 852 cdata->pcdac_min = ((val >> 4) & AR5K_EEPROM_PCDAC_M); 853 cdata->pwr[0] = ((val << 2) & AR5K_EEPROM_POWER_M); 854 855 AR5K_EEPROM_READ(offset++, val); 856 cdata->pwr[0] |= ((val >> 14) & 0x3); 857 cdata->pwr[1] = ((val >> 8) & AR5K_EEPROM_POWER_M); 858 cdata->pwr[2] = ((val >> 2) & AR5K_EEPROM_POWER_M); 859 cdata->pwr[3] = ((val << 4) & AR5K_EEPROM_POWER_M); 860 861 AR5K_EEPROM_READ(offset++, val); 862 cdata->pwr[3] |= ((val >> 12) & 0xf); 863 cdata->pwr[4] = ((val >> 6) & AR5K_EEPROM_POWER_M); 864 cdata->pwr[5] = (val & AR5K_EEPROM_POWER_M); 865 866 AR5K_EEPROM_READ(offset++, val); 867 cdata->pwr[6] = ((val >> 10) & AR5K_EEPROM_POWER_M); 868 cdata->pwr[7] = ((val >> 4) & AR5K_EEPROM_POWER_M); 869 cdata->pwr[8] = ((val << 2) & AR5K_EEPROM_POWER_M); 870 871 AR5K_EEPROM_READ(offset++, val); 872 cdata->pwr[8] |= ((val >> 14) & 0x3); 873 cdata->pwr[9] = ((val >> 8) & AR5K_EEPROM_POWER_M); 874 cdata->pwr[10] = ((val >> 2) & AR5K_EEPROM_POWER_M); 875 876 ath5k_get_pcdac_intercepts(ah, cdata->pcdac_min, 877 cdata->pcdac_max, cdata->pcdac); 878 } 879 880 return ath5k_eeprom_convert_pcal_info_5111(ah, mode, pcal); 881} 882 883 884/* 885 * Read power calibration for RF5112 chips 886 * 887 * For RF5112 we have 4 XPD -eXternal Power Detector- curves 888 * for each calibrated channel on 0, -6, -12 and -18dBm but we only 889 * use the higher (3) and the lower (0) curves. Each curve has 0.5dB 890 * power steps on x axis and PCDAC steps on y axis and looks like a 891 * linear function. To recreate the curve and pass the power values 892 * on hw, we read 4 points for xpd 0 (lower gain -> max power) 893 * and 3 points for xpd 3 (higher gain -> lower power) here and 894 * interpolate later. 895 * 896 * Note: Many vendors just use xpd 0 so xpd 3 is zeroed. 897 */ 898 899/* Convert RF5112 specific data to generic raw data 900 * used by interpolation code */ 901static int 902ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode, 903 struct ath5k_chan_pcal_info *chinfo) 904{ 905 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 906 struct ath5k_chan_pcal_info_rf5112 *pcinfo; 907 u8 *pdgain_idx = ee->ee_pdc_to_idx[mode]; 908 unsigned int pier, pdg, point; 909 910 /* Fill raw data for each calibration pier */ 911 for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) { 912 913 pcinfo = &chinfo[pier].rf5112_info; 914 915 /* Allocate pd_curves for this cal pier */ 916 chinfo[pier].pd_curves = 917 kcalloc(AR5K_EEPROM_N_PD_CURVES, 918 sizeof(struct ath5k_pdgain_info), 919 GFP_KERNEL); 920 921 if (!chinfo[pier].pd_curves) 922 goto err_out; 923 924 /* Fill pd_curves */ 925 for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { 926 927 u8 idx = pdgain_idx[pdg]; 928 struct ath5k_pdgain_info *pd = 929 &chinfo[pier].pd_curves[idx]; 930 931 /* Lowest gain curve (max power) */ 932 if (pdg == 0) { 933 /* One more point for better accuracy */ 934 pd->pd_points = AR5K_EEPROM_N_XPD0_POINTS; 935 936 /* Allocate pd points for this curve */ 937 pd->pd_step = kcalloc(pd->pd_points, 938 sizeof(u8), GFP_KERNEL); 939 940 if (!pd->pd_step) 941 goto err_out; 942 943 pd->pd_pwr = kcalloc(pd->pd_points, 944 sizeof(s16), GFP_KERNEL); 945 946 if (!pd->pd_pwr) 947 goto err_out; 948 949 /* Fill raw dataset 950 * (all power levels are in 0.25dB units) */ 951 pd->pd_step[0] = pcinfo->pcdac_x0[0]; 952 pd->pd_pwr[0] = pcinfo->pwr_x0[0]; 953 954 for (point = 1; point < pd->pd_points; 955 point++) { 956 /* Absolute values */ 957 pd->pd_pwr[point] = 958 pcinfo->pwr_x0[point]; 959 960 /* Deltas */ 961 pd->pd_step[point] = 962 pd->pd_step[point - 1] + 963 pcinfo->pcdac_x0[point]; 964 } 965 966 /* Set min power for this frequency */ 967 chinfo[pier].min_pwr = pd->pd_pwr[0]; 968 969 /* Highest gain curve (min power) */ 970 } else if (pdg == 1) { 971 972 pd->pd_points = AR5K_EEPROM_N_XPD3_POINTS; 973 974 /* Allocate pd points for this curve */ 975 pd->pd_step = kcalloc(pd->pd_points, 976 sizeof(u8), GFP_KERNEL); 977 978 if (!pd->pd_step) 979 goto err_out; 980 981 pd->pd_pwr = kcalloc(pd->pd_points, 982 sizeof(s16), GFP_KERNEL); 983 984 if (!pd->pd_pwr) 985 goto err_out; 986 987 /* Fill raw dataset 988 * (all power levels are in 0.25dB units) */ 989 for (point = 0; point < pd->pd_points; 990 point++) { 991 /* Absolute values */ 992 pd->pd_pwr[point] = 993 pcinfo->pwr_x3[point]; 994 995 /* Fixed points */ 996 pd->pd_step[point] = 997 pcinfo->pcdac_x3[point]; 998 } 999 1000 /* Since we have a higher gain curve 1001 * override min power */ 1002 chinfo[pier].min_pwr = pd->pd_pwr[0]; 1003 } 1004 } 1005 } 1006 1007 return 0; 1008 1009err_out: 1010 ath5k_eeprom_free_pcal_info(ah, mode); 1011 return -ENOMEM; 1012} 1013 1014/* Parse EEPROM data */ 1015static int 1016ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw *ah, int mode) 1017{ 1018 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 1019 struct ath5k_chan_pcal_info_rf5112 *chan_pcal_info; 1020 struct ath5k_chan_pcal_info *gen_chan_info; 1021 u8 *pdgain_idx = ee->ee_pdc_to_idx[mode]; 1022 u32 offset; 1023 u8 i, c; 1024 u16 val; 1025 u8 pd_gains = 0; 1026 1027 /* Count how many curves we have and 1028 * identify them (which one of the 4 1029 * available curves we have on each count). 1030 * Curves are stored from lower (x0) to 1031 * higher (x3) gain */ 1032 for (i = 0; i < AR5K_EEPROM_N_PD_CURVES; i++) { 1033 /* ee_x_gain[mode] is x gain mask */ 1034 if ((ee->ee_x_gain[mode] >> i) & 0x1) 1035 pdgain_idx[pd_gains++] = i; 1036 } 1037 ee->ee_pd_gains[mode] = pd_gains; 1038 1039 if (pd_gains == 0 || pd_gains > 2) 1040 return -EINVAL; 1041 1042 switch (mode) { 1043 case AR5K_EEPROM_MODE_11A: 1044 /* 1045 * Read 5GHz EEPROM channels 1046 */ 1047 offset = AR5K_EEPROM_GROUPS_START(ee->ee_version); 1048 ath5k_eeprom_init_11a_pcal_freq(ah, offset); 1049 1050 offset += AR5K_EEPROM_GROUP2_OFFSET; 1051 gen_chan_info = ee->ee_pwr_cal_a; 1052 break; 1053 case AR5K_EEPROM_MODE_11B: 1054 offset = AR5K_EEPROM_GROUPS_START(ee->ee_version); 1055 if (AR5K_EEPROM_HDR_11A(ee->ee_header)) 1056 offset += AR5K_EEPROM_GROUP3_OFFSET; 1057 1058 /* NB: frequency piers parsed during mode init */ 1059 gen_chan_info = ee->ee_pwr_cal_b; 1060 break; 1061 case AR5K_EEPROM_MODE_11G: 1062 offset = AR5K_EEPROM_GROUPS_START(ee->ee_version); 1063 if (AR5K_EEPROM_HDR_11A(ee->ee_header)) 1064 offset += AR5K_EEPROM_GROUP4_OFFSET; 1065 else if (AR5K_EEPROM_HDR_11B(ee->ee_header)) 1066 offset += AR5K_EEPROM_GROUP2_OFFSET; 1067 1068 /* NB: frequency piers parsed during mode init */ 1069 gen_chan_info = ee->ee_pwr_cal_g; 1070 break; 1071 default: 1072 return -EINVAL; 1073 } 1074 1075 for (i = 0; i < ee->ee_n_piers[mode]; i++) { 1076 chan_pcal_info = &gen_chan_info[i].rf5112_info; 1077 1078 /* Power values in quarter dB 1079 * for the lower xpd gain curve 1080 * (0 dBm -> higher output power) */ 1081 for (c = 0; c < AR5K_EEPROM_N_XPD0_POINTS; c++) { 1082 AR5K_EEPROM_READ(offset++, val); 1083 chan_pcal_info->pwr_x0[c] = (s8) (val & 0xff); 1084 chan_pcal_info->pwr_x0[++c] = (s8) ((val >> 8) & 0xff); 1085 } 1086 1087 /* PCDAC steps 1088 * corresponding to the above power 1089 * measurements */ 1090 AR5K_EEPROM_READ(offset++, val); 1091 chan_pcal_info->pcdac_x0[1] = (val & 0x1f); 1092 chan_pcal_info->pcdac_x0[2] = ((val >> 5) & 0x1f); 1093 chan_pcal_info->pcdac_x0[3] = ((val >> 10) & 0x1f); 1094 1095 /* Power values in quarter dB 1096 * for the higher xpd gain curve 1097 * (18 dBm -> lower output power) */ 1098 AR5K_EEPROM_READ(offset++, val); 1099 chan_pcal_info->pwr_x3[0] = (s8) (val & 0xff); 1100 chan_pcal_info->pwr_x3[1] = (s8) ((val >> 8) & 0xff); 1101 1102 AR5K_EEPROM_READ(offset++, val); 1103 chan_pcal_info->pwr_x3[2] = (val & 0xff); 1104 1105 /* PCDAC steps 1106 * corresponding to the above power 1107 * measurements (fixed) */ 1108 chan_pcal_info->pcdac_x3[0] = 20; 1109 chan_pcal_info->pcdac_x3[1] = 35; 1110 chan_pcal_info->pcdac_x3[2] = 63; 1111 1112 if (ee->ee_version >= AR5K_EEPROM_VERSION_4_3) { 1113 chan_pcal_info->pcdac_x0[0] = ((val >> 8) & 0x3f); 1114 1115 /* Last xpd0 power level is also channel maximum */ 1116 gen_chan_info[i].max_pwr = chan_pcal_info->pwr_x0[3]; 1117 } else { 1118 chan_pcal_info->pcdac_x0[0] = 1; 1119 gen_chan_info[i].max_pwr = (s8) ((val >> 8) & 0xff); 1120 } 1121 1122 } 1123 1124 return ath5k_eeprom_convert_pcal_info_5112(ah, mode, gen_chan_info); 1125} 1126 1127 1128/* 1129 * Read power calibration for RF2413 chips 1130 * 1131 * For RF2413 we have a Power to PDDAC table (Power Detector) 1132 * instead of a PCDAC and 4 pd gain curves for each calibrated channel. 1133 * Each curve has power on x axis in 0.5 db steps and PDDADC steps on y 1134 * axis and looks like an exponential function like the RF5111 curve. 1135 * 1136 * To recreate the curves we read here the points and interpolate 1137 * later. Note that in most cases only 2 (higher and lower) curves are 1138 * used (like RF5112) but vendors have the opportunity to include all 1139 * 4 curves on eeprom. The final curve (higher power) has an extra 1140 * point for better accuracy like RF5112. 1141 */ 1142 1143/* For RF2413 power calibration data doesn't start on a fixed location and 1144 * if a mode is not supported, its section is missing -not zeroed-. 1145 * So we need to calculate the starting offset for each section by using 1146 * these two functions */ 1147 1148/* Return the size of each section based on the mode and the number of pd 1149 * gains available (maximum 4). */ 1150static inline unsigned int 1151ath5k_pdgains_size_2413(struct ath5k_eeprom_info *ee, unsigned int mode) 1152{ 1153 static const unsigned int pdgains_size[] = { 4, 6, 9, 12 }; 1154 unsigned int sz; 1155 1156 sz = pdgains_size[ee->ee_pd_gains[mode] - 1]; 1157 sz *= ee->ee_n_piers[mode]; 1158 1159 return sz; 1160} 1161 1162/* Return the starting offset for a section based on the modes supported 1163 * and each section's size. */ 1164static unsigned int 1165ath5k_cal_data_offset_2413(struct ath5k_eeprom_info *ee, int mode) 1166{ 1167 u32 offset = AR5K_EEPROM_CAL_DATA_START(ee->ee_misc4); 1168 1169 switch (mode) { 1170 case AR5K_EEPROM_MODE_11G: 1171 if (AR5K_EEPROM_HDR_11B(ee->ee_header)) 1172 offset += ath5k_pdgains_size_2413(ee, 1173 AR5K_EEPROM_MODE_11B) + 1174 AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2; 1175 /* fall through */ 1176 case AR5K_EEPROM_MODE_11B: 1177 if (AR5K_EEPROM_HDR_11A(ee->ee_header)) 1178 offset += ath5k_pdgains_size_2413(ee, 1179 AR5K_EEPROM_MODE_11A) + 1180 AR5K_EEPROM_N_5GHZ_CHAN / 2; 1181 /* fall through */ 1182 case AR5K_EEPROM_MODE_11A: 1183 break; 1184 default: 1185 break; 1186 } 1187 1188 return offset; 1189} 1190 1191/* Convert RF2413 specific data to generic raw data 1192 * used by interpolation code */ 1193static int 1194ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode, 1195 struct ath5k_chan_pcal_info *chinfo) 1196{ 1197 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 1198 struct ath5k_chan_pcal_info_rf2413 *pcinfo; 1199 u8 *pdgain_idx = ee->ee_pdc_to_idx[mode]; 1200 unsigned int pier, pdg, point; 1201 1202 /* Fill raw data for each calibration pier */ 1203 for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) { 1204 1205 pcinfo = &chinfo[pier].rf2413_info; 1206 1207 /* Allocate pd_curves for this cal pier */ 1208 chinfo[pier].pd_curves = 1209 kcalloc(AR5K_EEPROM_N_PD_CURVES, 1210 sizeof(struct ath5k_pdgain_info), 1211 GFP_KERNEL); 1212 1213 if (!chinfo[pier].pd_curves) 1214 goto err_out; 1215 1216 /* Fill pd_curves */ 1217 for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { 1218 1219 u8 idx = pdgain_idx[pdg]; 1220 struct ath5k_pdgain_info *pd = 1221 &chinfo[pier].pd_curves[idx]; 1222 1223 /* One more point for the highest power 1224 * curve (lowest gain) */ 1225 if (pdg == ee->ee_pd_gains[mode] - 1) 1226 pd->pd_points = AR5K_EEPROM_N_PD_POINTS; 1227 else 1228 pd->pd_points = AR5K_EEPROM_N_PD_POINTS - 1; 1229 1230 /* Allocate pd points for this curve */ 1231 pd->pd_step = kcalloc(pd->pd_points, 1232 sizeof(u8), GFP_KERNEL); 1233 1234 if (!pd->pd_step) 1235 goto err_out; 1236 1237 pd->pd_pwr = kcalloc(pd->pd_points, 1238 sizeof(s16), GFP_KERNEL); 1239 1240 if (!pd->pd_pwr) 1241 goto err_out; 1242 1243 /* Fill raw dataset 1244 * convert all pwr levels to 1245 * quarter dB for RF5112 compatibility */ 1246 pd->pd_step[0] = pcinfo->pddac_i[pdg]; 1247 pd->pd_pwr[0] = 4 * pcinfo->pwr_i[pdg]; 1248 1249 for (point = 1; point < pd->pd_points; point++) { 1250 1251 pd->pd_pwr[point] = pd->pd_pwr[point - 1] + 1252 2 * pcinfo->pwr[pdg][point - 1]; 1253 1254 pd->pd_step[point] = pd->pd_step[point - 1] + 1255 pcinfo->pddac[pdg][point - 1]; 1256 1257 } 1258 1259 /* Highest gain curve -> min power */ 1260 if (pdg == 0) 1261 chinfo[pier].min_pwr = pd->pd_pwr[0]; 1262 1263 /* Lowest gain curve -> max power */ 1264 if (pdg == ee->ee_pd_gains[mode] - 1) 1265 chinfo[pier].max_pwr = 1266 pd->pd_pwr[pd->pd_points - 1]; 1267 } 1268 } 1269 1270 return 0; 1271 1272err_out: 1273 ath5k_eeprom_free_pcal_info(ah, mode); 1274 return -ENOMEM; 1275} 1276 1277/* Parse EEPROM data */ 1278static int 1279ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode) 1280{ 1281 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 1282 struct ath5k_chan_pcal_info_rf2413 *pcinfo; 1283 struct ath5k_chan_pcal_info *chinfo; 1284 u8 *pdgain_idx = ee->ee_pdc_to_idx[mode]; 1285 u32 offset; 1286 int idx, i; 1287 u16 val; 1288 u8 pd_gains = 0; 1289 1290 /* Count how many curves we have and 1291 * identify them (which one of the 4 1292 * available curves we have on each count). 1293 * Curves are stored from higher to 1294 * lower gain so we go backwards */ 1295 for (idx = AR5K_EEPROM_N_PD_CURVES - 1; idx >= 0; idx--) { 1296 /* ee_x_gain[mode] is x gain mask */ 1297 if ((ee->ee_x_gain[mode] >> idx) & 0x1) 1298 pdgain_idx[pd_gains++] = idx; 1299 1300 } 1301 ee->ee_pd_gains[mode] = pd_gains; 1302 1303 if (pd_gains == 0) 1304 return -EINVAL; 1305 1306 offset = ath5k_cal_data_offset_2413(ee, mode); 1307 switch (mode) { 1308 case AR5K_EEPROM_MODE_11A: 1309 if (!AR5K_EEPROM_HDR_11A(ee->ee_header)) 1310 return 0; 1311 1312 ath5k_eeprom_init_11a_pcal_freq(ah, offset); 1313 offset += AR5K_EEPROM_N_5GHZ_CHAN / 2; 1314 chinfo = ee->ee_pwr_cal_a; 1315 break; 1316 case AR5K_EEPROM_MODE_11B: 1317 if (!AR5K_EEPROM_HDR_11B(ee->ee_header)) 1318 return 0; 1319 1320 ath5k_eeprom_init_11bg_2413(ah, mode, offset); 1321 offset += AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2; 1322 chinfo = ee->ee_pwr_cal_b; 1323 break; 1324 case AR5K_EEPROM_MODE_11G: 1325 if (!AR5K_EEPROM_HDR_11G(ee->ee_header)) 1326 return 0; 1327 1328 ath5k_eeprom_init_11bg_2413(ah, mode, offset); 1329 offset += AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2; 1330 chinfo = ee->ee_pwr_cal_g; 1331 break; 1332 default: 1333 return -EINVAL; 1334 } 1335 1336 for (i = 0; i < ee->ee_n_piers[mode]; i++) { 1337 pcinfo = &chinfo[i].rf2413_info; 1338 1339 /* 1340 * Read pwr_i, pddac_i and the first 1341 * 2 pd points (pwr, pddac) 1342 */ 1343 AR5K_EEPROM_READ(offset++, val); 1344 pcinfo->pwr_i[0] = val & 0x1f; 1345 pcinfo->pddac_i[0] = (val >> 5) & 0x7f; 1346 pcinfo->pwr[0][0] = (val >> 12) & 0xf; 1347 1348 AR5K_EEPROM_READ(offset++, val); 1349 pcinfo->pddac[0][0] = val & 0x3f; 1350 pcinfo->pwr[0][1] = (val >> 6) & 0xf; 1351 pcinfo->pddac[0][1] = (val >> 10) & 0x3f; 1352 1353 AR5K_EEPROM_READ(offset++, val); 1354 pcinfo->pwr[0][2] = val & 0xf; 1355 pcinfo->pddac[0][2] = (val >> 4) & 0x3f; 1356 1357 pcinfo->pwr[0][3] = 0; 1358 pcinfo->pddac[0][3] = 0; 1359 1360 if (pd_gains > 1) { 1361 /* 1362 * Pd gain 0 is not the last pd gain 1363 * so it only has 2 pd points. 1364 * Continue with pd gain 1. 1365 */ 1366 pcinfo->pwr_i[1] = (val >> 10) & 0x1f; 1367 1368 pcinfo->pddac_i[1] = (val >> 15) & 0x1; 1369 AR5K_EEPROM_READ(offset++, val); 1370 pcinfo->pddac_i[1] |= (val & 0x3F) << 1; 1371 1372 pcinfo->pwr[1][0] = (val >> 6) & 0xf; 1373 pcinfo->pddac[1][0] = (val >> 10) & 0x3f; 1374 1375 AR5K_EEPROM_READ(offset++, val); 1376 pcinfo->pwr[1][1] = val & 0xf; 1377 pcinfo->pddac[1][1] = (val >> 4) & 0x3f; 1378 pcinfo->pwr[1][2] = (val >> 10) & 0xf; 1379 1380 pcinfo->pddac[1][2] = (val >> 14) & 0x3; 1381 AR5K_EEPROM_READ(offset++, val); 1382 pcinfo->pddac[1][2] |= (val & 0xF) << 2; 1383 1384 pcinfo->pwr[1][3] = 0; 1385 pcinfo->pddac[1][3] = 0; 1386 } else if (pd_gains == 1) { 1387 /* 1388 * Pd gain 0 is the last one so 1389 * read the extra point. 1390 */ 1391 pcinfo->pwr[0][3] = (val >> 10) & 0xf; 1392 1393 pcinfo->pddac[0][3] = (val >> 14) & 0x3; 1394 AR5K_EEPROM_READ(offset++, val); 1395 pcinfo->pddac[0][3] |= (val & 0xF) << 2; 1396 } 1397 1398 /* 1399 * Proceed with the other pd_gains 1400 * as above. 1401 */ 1402 if (pd_gains > 2) { 1403 pcinfo->pwr_i[2] = (val >> 4) & 0x1f; 1404 pcinfo->pddac_i[2] = (val >> 9) & 0x7f; 1405 1406 AR5K_EEPROM_READ(offset++, val); 1407 pcinfo->pwr[2][0] = (val >> 0) & 0xf; 1408 pcinfo->pddac[2][0] = (val >> 4) & 0x3f; 1409 pcinfo->pwr[2][1] = (val >> 10) & 0xf; 1410 1411 pcinfo->pddac[2][1] = (val >> 14) & 0x3; 1412 AR5K_EEPROM_READ(offset++, val); 1413 pcinfo->pddac[2][1] |= (val & 0xF) << 2; 1414 1415 pcinfo->pwr[2][2] = (val >> 4) & 0xf; 1416 pcinfo->pddac[2][2] = (val >> 8) & 0x3f; 1417 1418 pcinfo->pwr[2][3] = 0; 1419 pcinfo->pddac[2][3] = 0; 1420 } else if (pd_gains == 2) { 1421 pcinfo->pwr[1][3] = (val >> 4) & 0xf; 1422 pcinfo->pddac[1][3] = (val >> 8) & 0x3f; 1423 } 1424 1425 if (pd_gains > 3) { 1426 pcinfo->pwr_i[3] = (val >> 14) & 0x3; 1427 AR5K_EEPROM_READ(offset++, val); 1428 pcinfo->pwr_i[3] |= ((val >> 0) & 0x7) << 2; 1429 1430 pcinfo->pddac_i[3] = (val >> 3) & 0x7f; 1431 pcinfo->pwr[3][0] = (val >> 10) & 0xf; 1432 pcinfo->pddac[3][0] = (val >> 14) & 0x3; 1433 1434 AR5K_EEPROM_READ(offset++, val); 1435 pcinfo->pddac[3][0] |= (val & 0xF) << 2; 1436 pcinfo->pwr[3][1] = (val >> 4) & 0xf; 1437 pcinfo->pddac[3][1] = (val >> 8) & 0x3f; 1438 1439 pcinfo->pwr[3][2] = (val >> 14) & 0x3; 1440 AR5K_EEPROM_READ(offset++, val); 1441 pcinfo->pwr[3][2] |= ((val >> 0) & 0x3) << 2; 1442 1443 pcinfo->pddac[3][2] = (val >> 2) & 0x3f; 1444 pcinfo->pwr[3][3] = (val >> 8) & 0xf; 1445 1446 pcinfo->pddac[3][3] = (val >> 12) & 0xF; 1447 AR5K_EEPROM_READ(offset++, val); 1448 pcinfo->pddac[3][3] |= ((val >> 0) & 0x3) << 4; 1449 } else if (pd_gains == 3) { 1450 pcinfo->pwr[2][3] = (val >> 14) & 0x3; 1451 AR5K_EEPROM_READ(offset++, val); 1452 pcinfo->pwr[2][3] |= ((val >> 0) & 0x3) << 2; 1453 1454 pcinfo->pddac[2][3] = (val >> 2) & 0x3f; 1455 } 1456 } 1457 1458 return ath5k_eeprom_convert_pcal_info_2413(ah, mode, chinfo); 1459} 1460 1461 1462/* 1463 * Read per rate target power (this is the maximum tx power 1464 * supported by the card). This info is used when setting 1465 * tx power, no matter the channel. 1466 * 1467 * This also works for v5 EEPROMs. 1468 */ 1469static int 1470ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned int mode) 1471{ 1472 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 1473 struct ath5k_rate_pcal_info *rate_pcal_info; 1474 u8 *rate_target_pwr_num; 1475 u32 offset; 1476 u16 val; 1477 int i; 1478 1479 offset = AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1); 1480 rate_target_pwr_num = &ee->ee_rate_target_pwr_num[mode]; 1481 switch (mode) { 1482 case AR5K_EEPROM_MODE_11A: 1483 offset += AR5K_EEPROM_TARGET_PWR_OFF_11A(ee->ee_version); 1484 rate_pcal_info = ee->ee_rate_tpwr_a; 1485 ee->ee_rate_target_pwr_num[mode] = AR5K_EEPROM_N_5GHZ_RATE_CHAN; 1486 break; 1487 case AR5K_EEPROM_MODE_11B: 1488 offset += AR5K_EEPROM_TARGET_PWR_OFF_11B(ee->ee_version); 1489 rate_pcal_info = ee->ee_rate_tpwr_b; 1490 ee->ee_rate_target_pwr_num[mode] = 2; /* 3rd is g mode's 1st */ 1491 break; 1492 case AR5K_EEPROM_MODE_11G: 1493 offset += AR5K_EEPROM_TARGET_PWR_OFF_11G(ee->ee_version); 1494 rate_pcal_info = ee->ee_rate_tpwr_g; 1495 ee->ee_rate_target_pwr_num[mode] = AR5K_EEPROM_N_2GHZ_CHAN; 1496 break; 1497 default: 1498 return -EINVAL; 1499 } 1500 1501 /* Different freq mask for older eeproms (<= v3.2) */ 1502 if (ee->ee_version <= AR5K_EEPROM_VERSION_3_2) { 1503 for (i = 0; i < (*rate_target_pwr_num); i++) { 1504 AR5K_EEPROM_READ(offset++, val); 1505 rate_pcal_info[i].freq = 1506 ath5k_eeprom_bin2freq(ee, (val >> 9) & 0x7f, mode); 1507 1508 rate_pcal_info[i].target_power_6to24 = ((val >> 3) & 0x3f); 1509 rate_pcal_info[i].target_power_36 = (val << 3) & 0x3f; 1510 1511 AR5K_EEPROM_READ(offset++, val); 1512 1513 if (rate_pcal_info[i].freq == AR5K_EEPROM_CHANNEL_DIS || 1514 val == 0) { 1515 (*rate_target_pwr_num) = i; 1516 break; 1517 } 1518 1519 rate_pcal_info[i].target_power_36 |= ((val >> 13) & 0x7); 1520 rate_pcal_info[i].target_power_48 = ((val >> 7) & 0x3f); 1521 rate_pcal_info[i].target_power_54 = ((val >> 1) & 0x3f); 1522 } 1523 } else { 1524 for (i = 0; i < (*rate_target_pwr_num); i++) { 1525 AR5K_EEPROM_READ(offset++, val); 1526 rate_pcal_info[i].freq = 1527 ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode); 1528 1529 rate_pcal_info[i].target_power_6to24 = ((val >> 2) & 0x3f); 1530 rate_pcal_info[i].target_power_36 = (val << 4) & 0x3f; 1531 1532 AR5K_EEPROM_READ(offset++, val); 1533 1534 if (rate_pcal_info[i].freq == AR5K_EEPROM_CHANNEL_DIS || 1535 val == 0) { 1536 (*rate_target_pwr_num) = i; 1537 break; 1538 } 1539 1540 rate_pcal_info[i].target_power_36 |= (val >> 12) & 0xf; 1541 rate_pcal_info[i].target_power_48 = ((val >> 6) & 0x3f); 1542 rate_pcal_info[i].target_power_54 = (val & 0x3f); 1543 } 1544 } 1545 1546 return 0; 1547} 1548 1549 1550/* 1551 * Read per channel calibration info from EEPROM 1552 * 1553 * This info is used to calibrate the baseband power table. Imagine 1554 * that for each channel there is a power curve that's hw specific 1555 * (depends on amplifier etc) and we try to "correct" this curve using 1556 * offsets we pass on to phy chip (baseband -> before amplifier) so that 1557 * it can use accurate power values when setting tx power (takes amplifier's 1558 * performance on each channel into account). 1559 * 1560 * EEPROM provides us with the offsets for some pre-calibrated channels 1561 * and we have to interpolate to create the full table for these channels and 1562 * also the table for any channel. 1563 */ 1564static int 1565ath5k_eeprom_read_pcal_info(struct ath5k_hw *ah) 1566{ 1567 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 1568 int (*read_pcal)(struct ath5k_hw *hw, int mode); 1569 int mode; 1570 int err; 1571 1572 if ((ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) && 1573 (AR5K_EEPROM_EEMAP(ee->ee_misc0) == 1)) 1574 read_pcal = ath5k_eeprom_read_pcal_info_5112; 1575 else if ((ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_0) && 1576 (AR5K_EEPROM_EEMAP(ee->ee_misc0) == 2)) 1577 read_pcal = ath5k_eeprom_read_pcal_info_2413; 1578 else 1579 read_pcal = ath5k_eeprom_read_pcal_info_5111; 1580 1581 1582 for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; 1583 mode++) { 1584 err = read_pcal(ah, mode); 1585 if (err) 1586 return err; 1587 1588 err = ath5k_eeprom_read_target_rate_pwr_info(ah, mode); 1589 if (err < 0) 1590 return err; 1591 } 1592 1593 return 0; 1594} 1595 1596/* Read conformance test limits used for regulatory control */ 1597static int 1598ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah) 1599{ 1600 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 1601 struct ath5k_edge_power *rep; 1602 unsigned int fmask, pmask; 1603 unsigned int ctl_mode; 1604 int i, j; 1605 u32 offset; 1606 u16 val; 1607 1608 pmask = AR5K_EEPROM_POWER_M; 1609 fmask = AR5K_EEPROM_FREQ_M(ee->ee_version); 1610 offset = AR5K_EEPROM_CTL(ee->ee_version); 1611 ee->ee_ctls = AR5K_EEPROM_N_CTLS(ee->ee_version); 1612 for (i = 0; i < ee->ee_ctls; i += 2) { 1613 AR5K_EEPROM_READ(offset++, val); 1614 ee->ee_ctl[i] = (val >> 8) & 0xff; 1615 ee->ee_ctl[i + 1] = val & 0xff; 1616 } 1617 1618 offset = AR5K_EEPROM_GROUP8_OFFSET; 1619 if (ee->ee_version >= AR5K_EEPROM_VERSION_4_0) 1620 offset += AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1) - 1621 AR5K_EEPROM_GROUP5_OFFSET; 1622 else 1623 offset += AR5K_EEPROM_GROUPS_START(ee->ee_version); 1624 1625 rep = ee->ee_ctl_pwr; 1626 for (i = 0; i < ee->ee_ctls; i++) { 1627 switch (ee->ee_ctl[i] & AR5K_CTL_MODE_M) { 1628 case AR5K_CTL_11A: 1629 case AR5K_CTL_TURBO: 1630 ctl_mode = AR5K_EEPROM_MODE_11A; 1631 break; 1632 default: 1633 ctl_mode = AR5K_EEPROM_MODE_11G; 1634 break; 1635 } 1636 if (ee->ee_ctl[i] == 0) { 1637 if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3) 1638 offset += 8; 1639 else 1640 offset += 7; 1641 rep += AR5K_EEPROM_N_EDGES; 1642 continue; 1643 } 1644 if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3) { 1645 for (j = 0; j < AR5K_EEPROM_N_EDGES; j += 2) { 1646 AR5K_EEPROM_READ(offset++, val); 1647 rep[j].freq = (val >> 8) & fmask; 1648 rep[j + 1].freq = val & fmask; 1649 } 1650 for (j = 0; j < AR5K_EEPROM_N_EDGES; j += 2) { 1651 AR5K_EEPROM_READ(offset++, val); 1652 rep[j].edge = (val >> 8) & pmask; 1653 rep[j].flag = (val >> 14) & 1; 1654 rep[j + 1].edge = val & pmask; 1655 rep[j + 1].flag = (val >> 6) & 1; 1656 } 1657 } else { 1658 AR5K_EEPROM_READ(offset++, val); 1659 rep[0].freq = (val >> 9) & fmask; 1660 rep[1].freq = (val >> 2) & fmask; 1661 rep[2].freq = (val << 5) & fmask; 1662 1663 AR5K_EEPROM_READ(offset++, val); 1664 rep[2].freq |= (val >> 11) & 0x1f; 1665 rep[3].freq = (val >> 4) & fmask; 1666 rep[4].freq = (val << 3) & fmask; 1667 1668 AR5K_EEPROM_READ(offset++, val); 1669 rep[4].freq |= (val >> 13) & 0x7; 1670 rep[5].freq = (val >> 6) & fmask; 1671 rep[6].freq = (val << 1) & fmask; 1672 1673 AR5K_EEPROM_READ(offset++, val); 1674 rep[6].freq |= (val >> 15) & 0x1; 1675 rep[7].freq = (val >> 8) & fmask; 1676 1677 rep[0].edge = (val >> 2) & pmask; 1678 rep[1].edge = (val << 4) & pmask; 1679 1680 AR5K_EEPROM_READ(offset++, val); 1681 rep[1].edge |= (val >> 12) & 0xf; 1682 rep[2].edge = (val >> 6) & pmask; 1683 rep[3].edge = val & pmask; 1684 1685 AR5K_EEPROM_READ(offset++, val); 1686 rep[4].edge = (val >> 10) & pmask; 1687 rep[5].edge = (val >> 4) & pmask; 1688 rep[6].edge = (val << 2) & pmask; 1689 1690 AR5K_EEPROM_READ(offset++, val); 1691 rep[6].edge |= (val >> 14) & 0x3; 1692 rep[7].edge = (val >> 8) & pmask; 1693 } 1694 for (j = 0; j < AR5K_EEPROM_N_EDGES; j++) { 1695 rep[j].freq = ath5k_eeprom_bin2freq(ee, 1696 rep[j].freq, ctl_mode); 1697 } 1698 rep += AR5K_EEPROM_N_EDGES; 1699 } 1700 1701 return 0; 1702} 1703 1704static int 1705ath5k_eeprom_read_spur_chans(struct ath5k_hw *ah) 1706{ 1707 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 1708 u32 offset; 1709 u16 val; 1710 int ret = 0, i; 1711 1712 offset = AR5K_EEPROM_CTL(ee->ee_version) + 1713 AR5K_EEPROM_N_CTLS(ee->ee_version); 1714 1715 if (ee->ee_version < AR5K_EEPROM_VERSION_5_3) { 1716 /* No spur info for 5GHz */ 1717 ee->ee_spur_chans[0][0] = AR5K_EEPROM_NO_SPUR; 1718 /* 2 channels for 2GHz (2464/2420) */ 1719 ee->ee_spur_chans[0][1] = AR5K_EEPROM_5413_SPUR_CHAN_1; 1720 ee->ee_spur_chans[1][1] = AR5K_EEPROM_5413_SPUR_CHAN_2; 1721 ee->ee_spur_chans[2][1] = AR5K_EEPROM_NO_SPUR; 1722 } else if (ee->ee_version >= AR5K_EEPROM_VERSION_5_3) { 1723 for (i = 0; i < AR5K_EEPROM_N_SPUR_CHANS; i++) { 1724 AR5K_EEPROM_READ(offset, val); 1725 ee->ee_spur_chans[i][0] = val; 1726 AR5K_EEPROM_READ(offset + AR5K_EEPROM_N_SPUR_CHANS, 1727 val); 1728 ee->ee_spur_chans[i][1] = val; 1729 offset++; 1730 } 1731 } 1732 1733 return ret; 1734} 1735 1736 1737/***********************\ 1738* Init/Detach functions * 1739\***********************/ 1740 1741/* 1742 * Initialize eeprom data structure 1743 */ 1744int 1745ath5k_eeprom_init(struct ath5k_hw *ah) 1746{ 1747 int err; 1748 1749 err = ath5k_eeprom_init_header(ah); 1750 if (err < 0) 1751 return err; 1752 1753 err = ath5k_eeprom_init_modes(ah); 1754 if (err < 0) 1755 return err; 1756 1757 err = ath5k_eeprom_read_pcal_info(ah); 1758 if (err < 0) 1759 return err; 1760 1761 err = ath5k_eeprom_read_ctl_info(ah); 1762 if (err < 0) 1763 return err; 1764 1765 err = ath5k_eeprom_read_spur_chans(ah); 1766 if (err < 0) 1767 return err; 1768 1769 return 0; 1770} 1771 1772void 1773ath5k_eeprom_detach(struct ath5k_hw *ah) 1774{ 1775 u8 mode; 1776 1777 for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++) 1778 ath5k_eeprom_free_pcal_info(ah, mode); 1779} 1780 1781int 1782ath5k_eeprom_mode_from_channel(struct ath5k_hw *ah, 1783 struct ieee80211_channel *channel) 1784{ 1785 switch (channel->hw_value) { 1786 case AR5K_MODE_11A: 1787 return AR5K_EEPROM_MODE_11A; 1788 case AR5K_MODE_11G: 1789 return AR5K_EEPROM_MODE_11G; 1790 case AR5K_MODE_11B: 1791 return AR5K_EEPROM_MODE_11B; 1792 default: 1793 ATH5K_WARN(ah, "channel is not A/B/G!"); 1794 return AR5K_EEPROM_MODE_11A; 1795 } 1796} 1797