00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "ath5k.h"
00025 #include "reg.h"
00026 #include "debug.h"
00027 #include "base.h"
00028
00029
00030
00031
00032 static int ath5k_hw_eeprom_read(struct ath5k_hw *ah, u32 offset, u16 *data)
00033 {
00034 u32 status, timeout;
00035
00036 ATH5K_TRACE(ah->ah_sc);
00037
00038
00039
00040 if (ah->ah_version == AR5K_AR5210) {
00041 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_EEAE);
00042 (void)ath5k_hw_reg_read(ah, AR5K_EEPROM_BASE + (4 * offset));
00043 } else {
00044 ath5k_hw_reg_write(ah, offset, AR5K_EEPROM_BASE);
00045 AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD,
00046 AR5K_EEPROM_CMD_READ);
00047 }
00048
00049 for (timeout = AR5K_TUNE_REGISTER_TIMEOUT; timeout > 0; timeout--) {
00050 status = ath5k_hw_reg_read(ah, AR5K_EEPROM_STATUS);
00051 if (status & AR5K_EEPROM_STAT_RDDONE) {
00052 if (status & AR5K_EEPROM_STAT_RDERR)
00053 return -EIO;
00054 *data = (u16)(ath5k_hw_reg_read(ah, AR5K_EEPROM_DATA) &
00055 0xffff);
00056 return 0;
00057 }
00058 udelay(15);
00059 }
00060
00061 return -ETIMEDOUT;
00062 }
00063
00064
00065
00066
00067 static u16 ath5k_eeprom_bin2freq(struct ath5k_eeprom_info *ee, u16 bin,
00068 unsigned int mode)
00069 {
00070 u16 val;
00071
00072 if (bin == AR5K_EEPROM_CHANNEL_DIS)
00073 return bin;
00074
00075 if (mode == AR5K_EEPROM_MODE_11A) {
00076 if (ee->ee_version > AR5K_EEPROM_VERSION_3_2)
00077 val = (5 * bin) + 4800;
00078 else
00079 val = bin > 62 ? (10 * 62) + (5 * (bin - 62)) + 5100 :
00080 (bin * 10) + 5100;
00081 } else {
00082 if (ee->ee_version > AR5K_EEPROM_VERSION_3_2)
00083 val = bin + 2300;
00084 else
00085 val = bin + 2400;
00086 }
00087
00088 return val;
00089 }
00090
00091
00092
00093
00094 static int
00095 ath5k_eeprom_init_header(struct ath5k_hw *ah)
00096 {
00097 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
00098 int ret;
00099 u16 val;
00100
00101
00102
00103
00104 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MAGIC, ee_magic);
00105 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_PROTECT, ee_protect);
00106 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_REG_DOMAIN, ee_regdomain);
00107 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_VERSION, ee_version);
00108 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_HDR, ee_header);
00109
00110
00111 if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_0)
00112 return 0;
00113
00114 #ifdef notyet
00115
00116
00117
00118
00119 for (cksum = 0, offset = 0; offset < AR5K_EEPROM_INFO_MAX; offset++) {
00120 AR5K_EEPROM_READ(AR5K_EEPROM_INFO(offset), val);
00121 cksum ^= val;
00122 }
00123 if (cksum != AR5K_EEPROM_INFO_CKSUM) {
00124 ATH5K_ERR(ah->ah_sc, "Invalid EEPROM checksum 0x%04x\n", cksum);
00125 return -EIO;
00126 }
00127 #endif
00128
00129 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_ANT_GAIN(ah->ah_ee_version),
00130 ee_ant_gain);
00131
00132 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
00133 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC0, ee_misc0);
00134 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC1, ee_misc1);
00135
00136
00137 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC2, ee_misc2);
00138
00139 if (ee->ee_version >= AR5K_EEPROM_VERSION_4_3)
00140 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC3, ee_misc3);
00141
00142 if (ee->ee_version >= AR5K_EEPROM_VERSION_5_0) {
00143 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC4, ee_misc4);
00144 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC5, ee_misc5);
00145 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC6, ee_misc6);
00146 }
00147 }
00148
00149 if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_3) {
00150 AR5K_EEPROM_READ(AR5K_EEPROM_OBDB0_2GHZ, val);
00151 ee->ee_ob[AR5K_EEPROM_MODE_11B][0] = val & 0x7;
00152 ee->ee_db[AR5K_EEPROM_MODE_11B][0] = (val >> 3) & 0x7;
00153
00154 AR5K_EEPROM_READ(AR5K_EEPROM_OBDB1_2GHZ, val);
00155 ee->ee_ob[AR5K_EEPROM_MODE_11G][0] = val & 0x7;
00156 ee->ee_db[AR5K_EEPROM_MODE_11G][0] = (val >> 3) & 0x7;
00157 }
00158
00159 AR5K_EEPROM_READ(AR5K_EEPROM_IS_HB63, val);
00160
00161 if ((ah->ah_mac_version == (AR5K_SREV_AR2425 >> 4)) && val)
00162 ee->ee_is_hb63 = true;
00163 else
00164 ee->ee_is_hb63 = false;
00165
00166 AR5K_EEPROM_READ(AR5K_EEPROM_RFKILL, val);
00167 ee->ee_rfkill_pin = (u8) AR5K_REG_MS(val, AR5K_EEPROM_RFKILL_GPIO_SEL);
00168 ee->ee_rfkill_pol = val & AR5K_EEPROM_RFKILL_POLARITY ? true : false;
00169
00170
00171
00172
00173
00174
00175
00176 AR5K_EEPROM_READ(AR5K_EEPROM_PCIE_OFFSET, val);
00177 ee->ee_serdes = (val == AR5K_EEPROM_PCIE_SERDES_SECTION) ?
00178 true : false;
00179
00180 return 0;
00181 }
00182
00183
00184
00185
00186
00187 static int ath5k_eeprom_read_ants(struct ath5k_hw *ah, u32 *offset,
00188 unsigned int mode)
00189 {
00190 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
00191 u32 o = *offset;
00192 u16 val;
00193 int ret, i = 0;
00194
00195 AR5K_EEPROM_READ(o++, val);
00196 ee->ee_switch_settling[mode] = (val >> 8) & 0x7f;
00197 ee->ee_atn_tx_rx[mode] = (val >> 2) & 0x3f;
00198 ee->ee_ant_control[mode][i] = (val << 4) & 0x3f;
00199
00200 AR5K_EEPROM_READ(o++, val);
00201 ee->ee_ant_control[mode][i++] |= (val >> 12) & 0xf;
00202 ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f;
00203 ee->ee_ant_control[mode][i++] = val & 0x3f;
00204
00205 AR5K_EEPROM_READ(o++, val);
00206 ee->ee_ant_control[mode][i++] = (val >> 10) & 0x3f;
00207 ee->ee_ant_control[mode][i++] = (val >> 4) & 0x3f;
00208 ee->ee_ant_control[mode][i] = (val << 2) & 0x3f;
00209
00210 AR5K_EEPROM_READ(o++, val);
00211 ee->ee_ant_control[mode][i++] |= (val >> 14) & 0x3;
00212 ee->ee_ant_control[mode][i++] = (val >> 8) & 0x3f;
00213 ee->ee_ant_control[mode][i++] = (val >> 2) & 0x3f;
00214 ee->ee_ant_control[mode][i] = (val << 4) & 0x3f;
00215
00216 AR5K_EEPROM_READ(o++, val);
00217 ee->ee_ant_control[mode][i++] |= (val >> 12) & 0xf;
00218 ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f;
00219 ee->ee_ant_control[mode][i++] = val & 0x3f;
00220
00221
00222 ah->ah_ant_ctl[mode][AR5K_ANT_CTL] =
00223 (ee->ee_ant_control[mode][0] << 4);
00224 ah->ah_ant_ctl[mode][AR5K_ANT_SWTABLE_A] =
00225 ee->ee_ant_control[mode][1] |
00226 (ee->ee_ant_control[mode][2] << 6) |
00227 (ee->ee_ant_control[mode][3] << 12) |
00228 (ee->ee_ant_control[mode][4] << 18) |
00229 (ee->ee_ant_control[mode][5] << 24);
00230 ah->ah_ant_ctl[mode][AR5K_ANT_SWTABLE_B] =
00231 ee->ee_ant_control[mode][6] |
00232 (ee->ee_ant_control[mode][7] << 6) |
00233 (ee->ee_ant_control[mode][8] << 12) |
00234 (ee->ee_ant_control[mode][9] << 18) |
00235 (ee->ee_ant_control[mode][10] << 24);
00236
00237
00238 *offset = o;
00239
00240 return 0;
00241 }
00242
00243
00244
00245
00246
00247 static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,
00248 unsigned int mode)
00249 {
00250 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
00251 u32 o = *offset;
00252 u16 val;
00253 int ret;
00254
00255 ee->ee_n_piers[mode] = 0;
00256 AR5K_EEPROM_READ(o++, val);
00257 ee->ee_adc_desired_size[mode] = (s8)((val >> 8) & 0xff);
00258 switch(mode) {
00259 case AR5K_EEPROM_MODE_11A:
00260 ee->ee_ob[mode][3] = (val >> 5) & 0x7;
00261 ee->ee_db[mode][3] = (val >> 2) & 0x7;
00262 ee->ee_ob[mode][2] = (val << 1) & 0x7;
00263
00264 AR5K_EEPROM_READ(o++, val);
00265 ee->ee_ob[mode][2] |= (val >> 15) & 0x1;
00266 ee->ee_db[mode][2] = (val >> 12) & 0x7;
00267 ee->ee_ob[mode][1] = (val >> 9) & 0x7;
00268 ee->ee_db[mode][1] = (val >> 6) & 0x7;
00269 ee->ee_ob[mode][0] = (val >> 3) & 0x7;
00270 ee->ee_db[mode][0] = val & 0x7;
00271 break;
00272 case AR5K_EEPROM_MODE_11G:
00273 case AR5K_EEPROM_MODE_11B:
00274 ee->ee_ob[mode][1] = (val >> 4) & 0x7;
00275 ee->ee_db[mode][1] = val & 0x7;
00276 break;
00277 }
00278
00279 AR5K_EEPROM_READ(o++, val);
00280 ee->ee_tx_end2xlna_enable[mode] = (val >> 8) & 0xff;
00281 ee->ee_thr_62[mode] = val & 0xff;
00282
00283 if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2)
00284 ee->ee_thr_62[mode] = mode == AR5K_EEPROM_MODE_11A ? 15 : 28;
00285
00286 AR5K_EEPROM_READ(o++, val);
00287 ee->ee_tx_end2xpa_disable[mode] = (val >> 8) & 0xff;
00288 ee->ee_tx_frm2xpa_enable[mode] = val & 0xff;
00289
00290 AR5K_EEPROM_READ(o++, val);
00291 ee->ee_pga_desired_size[mode] = (val >> 8) & 0xff;
00292
00293 if ((val & 0xff) & 0x80)
00294 ee->ee_noise_floor_thr[mode] = -((((val & 0xff) ^ 0xff)) + 1);
00295 else
00296 ee->ee_noise_floor_thr[mode] = val & 0xff;
00297
00298 if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2)
00299 ee->ee_noise_floor_thr[mode] =
00300 mode == AR5K_EEPROM_MODE_11A ? -54 : -1;
00301
00302 AR5K_EEPROM_READ(o++, val);
00303 ee->ee_xlna_gain[mode] = (val >> 5) & 0xff;
00304 ee->ee_x_gain[mode] = (val >> 1) & 0xf;
00305 ee->ee_xpd[mode] = val & 0x1;
00306
00307 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0)
00308 ee->ee_fixed_bias[mode] = (val >> 13) & 0x1;
00309
00310 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_3) {
00311 AR5K_EEPROM_READ(o++, val);
00312 ee->ee_false_detect[mode] = (val >> 6) & 0x7f;
00313
00314 if (mode == AR5K_EEPROM_MODE_11A)
00315 ee->ee_xr_power[mode] = val & 0x3f;
00316 else {
00317 ee->ee_ob[mode][0] = val & 0x7;
00318 ee->ee_db[mode][0] = (val >> 3) & 0x7;
00319 }
00320 }
00321
00322 if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_4) {
00323 ee->ee_i_gain[mode] = AR5K_EEPROM_I_GAIN;
00324 ee->ee_cck_ofdm_power_delta = AR5K_EEPROM_CCK_OFDM_DELTA;
00325 } else {
00326 ee->ee_i_gain[mode] = (val >> 13) & 0x7;
00327
00328 AR5K_EEPROM_READ(o++, val);
00329 ee->ee_i_gain[mode] |= (val << 3) & 0x38;
00330
00331 if (mode == AR5K_EEPROM_MODE_11G) {
00332 ee->ee_cck_ofdm_power_delta = (val >> 3) & 0xff;
00333 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_6)
00334 ee->ee_scaled_cck_delta = (val >> 11) & 0x1f;
00335 }
00336 }
00337
00338 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0 &&
00339 mode == AR5K_EEPROM_MODE_11A) {
00340 ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
00341 ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
00342 }
00343
00344 if (ah->ah_ee_version < AR5K_EEPROM_VERSION_4_0)
00345 goto done;
00346
00347
00348
00349
00350 switch(mode) {
00351 case AR5K_EEPROM_MODE_11A:
00352 if (ah->ah_ee_version < AR5K_EEPROM_VERSION_4_1)
00353 break;
00354
00355 AR5K_EEPROM_READ(o++, val);
00356 ee->ee_margin_tx_rx[mode] = val & 0x3f;
00357 break;
00358 case AR5K_EEPROM_MODE_11B:
00359 AR5K_EEPROM_READ(o++, val);
00360
00361 ee->ee_pwr_cal_b[0].freq =
00362 ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
00363 if (ee->ee_pwr_cal_b[0].freq != AR5K_EEPROM_CHANNEL_DIS)
00364 ee->ee_n_piers[mode]++;
00365
00366 ee->ee_pwr_cal_b[1].freq =
00367 ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode);
00368 if (ee->ee_pwr_cal_b[1].freq != AR5K_EEPROM_CHANNEL_DIS)
00369 ee->ee_n_piers[mode]++;
00370
00371 AR5K_EEPROM_READ(o++, val);
00372 ee->ee_pwr_cal_b[2].freq =
00373 ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
00374 if (ee->ee_pwr_cal_b[2].freq != AR5K_EEPROM_CHANNEL_DIS)
00375 ee->ee_n_piers[mode]++;
00376
00377 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
00378 ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
00379 break;
00380 case AR5K_EEPROM_MODE_11G:
00381 AR5K_EEPROM_READ(o++, val);
00382
00383 ee->ee_pwr_cal_g[0].freq =
00384 ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
00385 if (ee->ee_pwr_cal_g[0].freq != AR5K_EEPROM_CHANNEL_DIS)
00386 ee->ee_n_piers[mode]++;
00387
00388 ee->ee_pwr_cal_g[1].freq =
00389 ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode);
00390 if (ee->ee_pwr_cal_g[1].freq != AR5K_EEPROM_CHANNEL_DIS)
00391 ee->ee_n_piers[mode]++;
00392
00393 AR5K_EEPROM_READ(o++, val);
00394 ee->ee_turbo_max_power[mode] = val & 0x7f;
00395 ee->ee_xr_power[mode] = (val >> 7) & 0x3f;
00396
00397 AR5K_EEPROM_READ(o++, val);
00398 ee->ee_pwr_cal_g[2].freq =
00399 ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
00400 if (ee->ee_pwr_cal_g[2].freq != AR5K_EEPROM_CHANNEL_DIS)
00401 ee->ee_n_piers[mode]++;
00402
00403 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
00404 ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
00405
00406 AR5K_EEPROM_READ(o++, val);
00407 ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
00408 ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
00409
00410 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_2) {
00411 AR5K_EEPROM_READ(o++, val);
00412 ee->ee_cck_ofdm_gain_delta = val & 0xff;
00413 }
00414 break;
00415 }
00416
00417
00418
00419
00420 if (ee->ee_version < AR5K_EEPROM_VERSION_5_0)
00421 goto done;
00422
00423 switch (mode){
00424 case AR5K_EEPROM_MODE_11A:
00425 ee->ee_switch_settling_turbo[mode] = (val >> 6) & 0x7f;
00426
00427 ee->ee_atn_tx_rx_turbo[mode] = (val >> 13) & 0x7;
00428 AR5K_EEPROM_READ(o++, val);
00429 ee->ee_atn_tx_rx_turbo[mode] |= (val & 0x7) << 3;
00430 ee->ee_margin_tx_rx_turbo[mode] = (val >> 3) & 0x3f;
00431
00432 ee->ee_adc_desired_size_turbo[mode] = (val >> 9) & 0x7f;
00433 AR5K_EEPROM_READ(o++, val);
00434 ee->ee_adc_desired_size_turbo[mode] |= (val & 0x1) << 7;
00435 ee->ee_pga_desired_size_turbo[mode] = (val >> 1) & 0xff;
00436
00437 if (AR5K_EEPROM_EEMAP(ee->ee_misc0) >=2)
00438 ee->ee_pd_gain_overlap = (val >> 9) & 0xf;
00439 break;
00440 case AR5K_EEPROM_MODE_11G:
00441 ee->ee_switch_settling_turbo[mode] = (val >> 8) & 0x7f;
00442
00443 ee->ee_atn_tx_rx_turbo[mode] = (val >> 15) & 0x7;
00444 AR5K_EEPROM_READ(o++, val);
00445 ee->ee_atn_tx_rx_turbo[mode] |= (val & 0x1f) << 1;
00446 ee->ee_margin_tx_rx_turbo[mode] = (val >> 5) & 0x3f;
00447
00448 ee->ee_adc_desired_size_turbo[mode] = (val >> 11) & 0x7f;
00449 AR5K_EEPROM_READ(o++, val);
00450 ee->ee_adc_desired_size_turbo[mode] |= (val & 0x7) << 5;
00451 ee->ee_pga_desired_size_turbo[mode] = (val >> 3) & 0xff;
00452 break;
00453 }
00454
00455 done:
00456
00457 *offset = o;
00458
00459 return 0;
00460 }
00461
00462
00463 static int
00464 ath5k_eeprom_init_modes(struct ath5k_hw *ah)
00465 {
00466 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
00467 u32 mode_offset[3];
00468 unsigned int mode;
00469 u32 offset;
00470 int ret;
00471
00472
00473
00474
00475 mode_offset[AR5K_EEPROM_MODE_11A] = AR5K_EEPROM_MODES_11A(ah->ah_ee_version);
00476 mode_offset[AR5K_EEPROM_MODE_11B] = AR5K_EEPROM_MODES_11B(ah->ah_ee_version);
00477 mode_offset[AR5K_EEPROM_MODE_11G] = AR5K_EEPROM_MODES_11G(ah->ah_ee_version);
00478
00479 ee->ee_turbo_max_power[AR5K_EEPROM_MODE_11A] =
00480 AR5K_EEPROM_HDR_T_5GHZ_DBM(ee->ee_header);
00481
00482 for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++) {
00483 offset = mode_offset[mode];
00484
00485 ret = ath5k_eeprom_read_ants(ah, &offset, mode);
00486 if (ret)
00487 return ret;
00488
00489 ret = ath5k_eeprom_read_modes(ah, &offset, mode);
00490 if (ret)
00491 return ret;
00492 }
00493
00494
00495 if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2) {
00496 ee->ee_thr_62[AR5K_EEPROM_MODE_11A] = 15;
00497 ee->ee_thr_62[AR5K_EEPROM_MODE_11B] = 28;
00498 ee->ee_thr_62[AR5K_EEPROM_MODE_11G] = 28;
00499 }
00500
00501 return 0;
00502 }
00503
00504
00505
00506 static inline int
00507 ath5k_eeprom_read_freq_list(struct ath5k_hw *ah, int *offset, int max,
00508 struct ath5k_chan_pcal_info *pc, unsigned int mode)
00509 {
00510 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
00511 int o = *offset;
00512 int i = 0;
00513 u8 freq1, freq2;
00514 int ret;
00515 u16 val;
00516
00517 ee->ee_n_piers[mode] = 0;
00518 while(i < max) {
00519 AR5K_EEPROM_READ(o++, val);
00520
00521 freq1 = val & 0xff;
00522 if (!freq1)
00523 break;
00524
00525 pc[i++].freq = ath5k_eeprom_bin2freq(ee,
00526 freq1, mode);
00527 ee->ee_n_piers[mode]++;
00528
00529 freq2 = (val >> 8) & 0xff;
00530 if (!freq2)
00531 break;
00532
00533 pc[i++].freq = ath5k_eeprom_bin2freq(ee,
00534 freq2, mode);
00535 ee->ee_n_piers[mode]++;
00536 }
00537
00538
00539 *offset = o;
00540
00541 return 0;
00542 }
00543
00544
00545 static int
00546 ath5k_eeprom_init_11a_pcal_freq(struct ath5k_hw *ah, int offset)
00547 {
00548 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
00549 struct ath5k_chan_pcal_info *pcal = ee->ee_pwr_cal_a;
00550 int i, ret;
00551 u16 val;
00552 u8 mask;
00553
00554 if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3) {
00555 ath5k_eeprom_read_freq_list(ah, &offset,
00556 AR5K_EEPROM_N_5GHZ_CHAN, pcal,
00557 AR5K_EEPROM_MODE_11A);
00558 } else {
00559 mask = AR5K_EEPROM_FREQ_M(ah->ah_ee_version);
00560
00561 AR5K_EEPROM_READ(offset++, val);
00562 pcal[0].freq = (val >> 9) & mask;
00563 pcal[1].freq = (val >> 2) & mask;
00564 pcal[2].freq = (val << 5) & mask;
00565
00566 AR5K_EEPROM_READ(offset++, val);
00567 pcal[2].freq |= (val >> 11) & 0x1f;
00568 pcal[3].freq = (val >> 4) & mask;
00569 pcal[4].freq = (val << 3) & mask;
00570
00571 AR5K_EEPROM_READ(offset++, val);
00572 pcal[4].freq |= (val >> 13) & 0x7;
00573 pcal[5].freq = (val >> 6) & mask;
00574 pcal[6].freq = (val << 1) & mask;
00575
00576 AR5K_EEPROM_READ(offset++, val);
00577 pcal[6].freq |= (val >> 15) & 0x1;
00578 pcal[7].freq = (val >> 8) & mask;
00579 pcal[8].freq = (val >> 1) & mask;
00580 pcal[9].freq = (val << 6) & mask;
00581
00582 AR5K_EEPROM_READ(offset++, val);
00583 pcal[9].freq |= (val >> 10) & 0x3f;
00584
00585
00586 ee->ee_n_piers[AR5K_EEPROM_MODE_11A] = 10;
00587
00588 for (i = 0; i < AR5K_EEPROM_N_5GHZ_CHAN; i++) {
00589 pcal[i].freq = ath5k_eeprom_bin2freq(ee,
00590 pcal[i].freq, AR5K_EEPROM_MODE_11A);
00591 }
00592 }
00593
00594 return 0;
00595 }
00596
00597
00598 static inline int
00599 ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset)
00600 {
00601 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
00602 struct ath5k_chan_pcal_info *pcal;
00603
00604 switch(mode) {
00605 case AR5K_EEPROM_MODE_11B:
00606 pcal = ee->ee_pwr_cal_b;
00607 break;
00608 case AR5K_EEPROM_MODE_11G:
00609 pcal = ee->ee_pwr_cal_g;
00610 break;
00611 default:
00612 return -EINVAL;
00613 }
00614
00615 ath5k_eeprom_read_freq_list(ah, &offset,
00616 AR5K_EEPROM_N_2GHZ_CHAN_2413, pcal,
00617 mode);
00618
00619 return 0;
00620 }
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642 static inline void
00643 ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp)
00644 {
00645 static const u16 intercepts3[] =
00646 { 0, 5, 10, 20, 30, 50, 70, 85, 90, 95, 100 };
00647 static const u16 intercepts3_2[] =
00648 { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 };
00649 const u16 *ip;
00650 int i;
00651
00652 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_2)
00653 ip = intercepts3_2;
00654 else
00655 ip = intercepts3;
00656
00657 for (i = 0; i < ARRAY_SIZE(intercepts3); i++)
00658 vp[i] = (ip[i] * max + (100 - ip[i]) * min) / 100;
00659 }
00660
00661
00662
00663 static int
00664 ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode,
00665 struct ath5k_chan_pcal_info *chinfo)
00666 {
00667 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
00668 struct ath5k_chan_pcal_info_rf5111 *pcinfo;
00669 struct ath5k_pdgain_info *pd;
00670 u8 pier, point, idx;
00671 u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
00672
00673
00674 for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
00675
00676 pcinfo = &chinfo[pier].rf5111_info;
00677
00678
00679 chinfo[pier].pd_curves =
00680 kcalloc(AR5K_EEPROM_N_PD_CURVES,
00681 sizeof(struct ath5k_pdgain_info),
00682 GFP_KERNEL);
00683
00684 if (!chinfo[pier].pd_curves)
00685 return -ENOMEM;
00686
00687
00688
00689
00690
00691 for (idx = 0; idx < AR5K_EEPROM_N_PD_CURVES; idx++) {
00692
00693 if (!((ee->ee_x_gain[mode] >> idx) & 0x1)) {
00694 pdgain_idx[0] = idx;
00695 break;
00696 }
00697 }
00698
00699 ee->ee_pd_gains[mode] = 1;
00700
00701 pd = &chinfo[pier].pd_curves[idx];
00702
00703 pd->pd_points = AR5K_EEPROM_N_PWR_POINTS_5111;
00704
00705
00706 pd->pd_step = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111,
00707 sizeof(u8), GFP_KERNEL);
00708 if (!pd->pd_step)
00709 return -ENOMEM;
00710
00711 pd->pd_pwr = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111,
00712 sizeof(s16), GFP_KERNEL);
00713 if (!pd->pd_pwr)
00714 return -ENOMEM;
00715
00716
00717
00718
00719 for (point = 0; point < pd->pd_points; point++) {
00720
00721
00722 pd->pd_pwr[point] = 2 * pcinfo->pwr[point];
00723
00724
00725 pd->pd_step[point] = pcinfo->pcdac[point];
00726 }
00727
00728
00729 chinfo[pier].min_pwr = pd->pd_pwr[0];
00730 chinfo[pier].max_pwr = pd->pd_pwr[10];
00731
00732 }
00733
00734 return 0;
00735 }
00736
00737
00738 static int
00739 ath5k_eeprom_read_pcal_info_5111(struct ath5k_hw *ah, int mode)
00740 {
00741 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
00742 struct ath5k_chan_pcal_info *pcal;
00743 int offset, ret;
00744 int i;
00745 u16 val;
00746
00747 offset = AR5K_EEPROM_GROUPS_START(ee->ee_version);
00748 switch(mode) {
00749 case AR5K_EEPROM_MODE_11A:
00750 if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
00751 return 0;
00752
00753 ret = ath5k_eeprom_init_11a_pcal_freq(ah,
00754 offset + AR5K_EEPROM_GROUP1_OFFSET);
00755 if (ret < 0)
00756 return ret;
00757
00758 offset += AR5K_EEPROM_GROUP2_OFFSET;
00759 pcal = ee->ee_pwr_cal_a;
00760 break;
00761 case AR5K_EEPROM_MODE_11B:
00762 if (!AR5K_EEPROM_HDR_11B(ee->ee_header) &&
00763 !AR5K_EEPROM_HDR_11G(ee->ee_header))
00764 return 0;
00765
00766 pcal = ee->ee_pwr_cal_b;
00767 offset += AR5K_EEPROM_GROUP3_OFFSET;
00768
00769
00770 pcal[0].freq = 2412;
00771 pcal[1].freq = 2447;
00772 pcal[2].freq = 2484;
00773 ee->ee_n_piers[mode] = 3;
00774 break;
00775 case AR5K_EEPROM_MODE_11G:
00776 if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
00777 return 0;
00778
00779 pcal = ee->ee_pwr_cal_g;
00780 offset += AR5K_EEPROM_GROUP4_OFFSET;
00781
00782
00783 pcal[0].freq = 2312;
00784 pcal[1].freq = 2412;
00785 pcal[2].freq = 2484;
00786 ee->ee_n_piers[mode] = 3;
00787 break;
00788 default:
00789 return -EINVAL;
00790 }
00791
00792 for (i = 0; i < ee->ee_n_piers[mode]; i++) {
00793 struct ath5k_chan_pcal_info_rf5111 *cdata =
00794 &pcal[i].rf5111_info;
00795
00796 AR5K_EEPROM_READ(offset++, val);
00797 cdata->pcdac_max = ((val >> 10) & AR5K_EEPROM_PCDAC_M);
00798 cdata->pcdac_min = ((val >> 4) & AR5K_EEPROM_PCDAC_M);
00799 cdata->pwr[0] = ((val << 2) & AR5K_EEPROM_POWER_M);
00800
00801 AR5K_EEPROM_READ(offset++, val);
00802 cdata->pwr[0] |= ((val >> 14) & 0x3);
00803 cdata->pwr[1] = ((val >> 8) & AR5K_EEPROM_POWER_M);
00804 cdata->pwr[2] = ((val >> 2) & AR5K_EEPROM_POWER_M);
00805 cdata->pwr[3] = ((val << 4) & AR5K_EEPROM_POWER_M);
00806
00807 AR5K_EEPROM_READ(offset++, val);
00808 cdata->pwr[3] |= ((val >> 12) & 0xf);
00809 cdata->pwr[4] = ((val >> 6) & AR5K_EEPROM_POWER_M);
00810 cdata->pwr[5] = (val & AR5K_EEPROM_POWER_M);
00811
00812 AR5K_EEPROM_READ(offset++, val);
00813 cdata->pwr[6] = ((val >> 10) & AR5K_EEPROM_POWER_M);
00814 cdata->pwr[7] = ((val >> 4) & AR5K_EEPROM_POWER_M);
00815 cdata->pwr[8] = ((val << 2) & AR5K_EEPROM_POWER_M);
00816
00817 AR5K_EEPROM_READ(offset++, val);
00818 cdata->pwr[8] |= ((val >> 14) & 0x3);
00819 cdata->pwr[9] = ((val >> 8) & AR5K_EEPROM_POWER_M);
00820 cdata->pwr[10] = ((val >> 2) & AR5K_EEPROM_POWER_M);
00821
00822 ath5k_get_pcdac_intercepts(ah, cdata->pcdac_min,
00823 cdata->pcdac_max, cdata->pcdac);
00824 }
00825
00826 return ath5k_eeprom_convert_pcal_info_5111(ah, mode, pcal);
00827 }
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847 static int
00848 ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode,
00849 struct ath5k_chan_pcal_info *chinfo)
00850 {
00851 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
00852 struct ath5k_chan_pcal_info_rf5112 *pcinfo;
00853 u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
00854 unsigned int pier, pdg, point;
00855
00856
00857 for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
00858
00859 pcinfo = &chinfo[pier].rf5112_info;
00860
00861
00862 chinfo[pier].pd_curves =
00863 kcalloc(AR5K_EEPROM_N_PD_CURVES,
00864 sizeof(struct ath5k_pdgain_info),
00865 GFP_KERNEL);
00866
00867 if (!chinfo[pier].pd_curves)
00868 return -ENOMEM;
00869
00870
00871 for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
00872
00873 u8 idx = pdgain_idx[pdg];
00874 struct ath5k_pdgain_info *pd =
00875 &chinfo[pier].pd_curves[idx];
00876
00877
00878 if (pdg == 0) {
00879
00880 pd->pd_points = AR5K_EEPROM_N_XPD0_POINTS;
00881
00882
00883 pd->pd_step = kcalloc(pd->pd_points,
00884 sizeof(u8), GFP_KERNEL);
00885
00886 if (!pd->pd_step)
00887 return -ENOMEM;
00888
00889 pd->pd_pwr = kcalloc(pd->pd_points,
00890 sizeof(s16), GFP_KERNEL);
00891
00892 if (!pd->pd_pwr)
00893 return -ENOMEM;
00894
00895
00896
00897
00898 pd->pd_step[0] = pcinfo->pcdac_x0[0];
00899 pd->pd_pwr[0] = pcinfo->pwr_x0[0];
00900
00901 for (point = 1; point < pd->pd_points;
00902 point++) {
00903
00904 pd->pd_pwr[point] =
00905 pcinfo->pwr_x0[point];
00906
00907
00908 pd->pd_step[point] =
00909 pd->pd_step[point - 1] +
00910 pcinfo->pcdac_x0[point];
00911 }
00912
00913
00914 chinfo[pier].min_pwr = pd->pd_pwr[0];
00915
00916
00917 } else if (pdg == 1) {
00918
00919 pd->pd_points = AR5K_EEPROM_N_XPD3_POINTS;
00920
00921
00922 pd->pd_step = kcalloc(pd->pd_points,
00923 sizeof(u8), GFP_KERNEL);
00924
00925 if (!pd->pd_step)
00926 return -ENOMEM;
00927
00928 pd->pd_pwr = kcalloc(pd->pd_points,
00929 sizeof(s16), GFP_KERNEL);
00930
00931 if (!pd->pd_pwr)
00932 return -ENOMEM;
00933
00934
00935
00936 for (point = 0; point < pd->pd_points;
00937 point++) {
00938
00939 pd->pd_pwr[point] =
00940 pcinfo->pwr_x3[point];
00941
00942
00943 pd->pd_step[point] =
00944 pcinfo->pcdac_x3[point];
00945 }
00946
00947
00948
00949 chinfo[pier].min_pwr = pd->pd_pwr[0];
00950 }
00951 }
00952 }
00953
00954 return 0;
00955 }
00956
00957
00958 static int
00959 ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw *ah, int mode)
00960 {
00961 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
00962 struct ath5k_chan_pcal_info_rf5112 *chan_pcal_info;
00963 struct ath5k_chan_pcal_info *gen_chan_info;
00964 u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
00965 u32 offset;
00966 u8 i, c;
00967 u16 val;
00968 int ret;
00969 u8 pd_gains = 0;
00970
00971
00972
00973
00974
00975
00976 for (i = 0; i < AR5K_EEPROM_N_PD_CURVES; i++) {
00977
00978 if ((ee->ee_x_gain[mode] >> i) & 0x1)
00979 pdgain_idx[pd_gains++] = i;
00980 }
00981 ee->ee_pd_gains[mode] = pd_gains;
00982
00983 if (pd_gains == 0 || pd_gains > 2)
00984 return -EINVAL;
00985
00986 switch (mode) {
00987 case AR5K_EEPROM_MODE_11A:
00988
00989
00990
00991 offset = AR5K_EEPROM_GROUPS_START(ee->ee_version);
00992 ath5k_eeprom_init_11a_pcal_freq(ah, offset);
00993
00994 offset += AR5K_EEPROM_GROUP2_OFFSET;
00995 gen_chan_info = ee->ee_pwr_cal_a;
00996 break;
00997 case AR5K_EEPROM_MODE_11B:
00998 offset = AR5K_EEPROM_GROUPS_START(ee->ee_version);
00999 if (AR5K_EEPROM_HDR_11A(ee->ee_header))
01000 offset += AR5K_EEPROM_GROUP3_OFFSET;
01001
01002
01003 gen_chan_info = ee->ee_pwr_cal_b;
01004 break;
01005 case AR5K_EEPROM_MODE_11G:
01006 offset = AR5K_EEPROM_GROUPS_START(ee->ee_version);
01007 if (AR5K_EEPROM_HDR_11A(ee->ee_header))
01008 offset += AR5K_EEPROM_GROUP4_OFFSET;
01009 else if (AR5K_EEPROM_HDR_11B(ee->ee_header))
01010 offset += AR5K_EEPROM_GROUP2_OFFSET;
01011
01012
01013 gen_chan_info = ee->ee_pwr_cal_g;
01014 break;
01015 default:
01016 return -EINVAL;
01017 }
01018
01019 for (i = 0; i < ee->ee_n_piers[mode]; i++) {
01020 chan_pcal_info = &gen_chan_info[i].rf5112_info;
01021
01022
01023
01024
01025 for (c = 0; c < AR5K_EEPROM_N_XPD0_POINTS; c++) {
01026 AR5K_EEPROM_READ(offset++, val);
01027 chan_pcal_info->pwr_x0[c] = (s8) (val & 0xff);
01028 chan_pcal_info->pwr_x0[++c] = (s8) ((val >> 8) & 0xff);
01029 }
01030
01031
01032
01033
01034 AR5K_EEPROM_READ(offset++, val);
01035 chan_pcal_info->pcdac_x0[1] = (val & 0x1f);
01036 chan_pcal_info->pcdac_x0[2] = ((val >> 5) & 0x1f);
01037 chan_pcal_info->pcdac_x0[3] = ((val >> 10) & 0x1f);
01038
01039
01040
01041
01042 AR5K_EEPROM_READ(offset++, val);
01043 chan_pcal_info->pwr_x3[0] = (s8) (val & 0xff);
01044 chan_pcal_info->pwr_x3[1] = (s8) ((val >> 8) & 0xff);
01045
01046 AR5K_EEPROM_READ(offset++, val);
01047 chan_pcal_info->pwr_x3[2] = (val & 0xff);
01048
01049
01050
01051
01052 chan_pcal_info->pcdac_x3[0] = 20;
01053 chan_pcal_info->pcdac_x3[1] = 35;
01054 chan_pcal_info->pcdac_x3[2] = 63;
01055
01056 if (ee->ee_version >= AR5K_EEPROM_VERSION_4_3) {
01057 chan_pcal_info->pcdac_x0[0] = ((val >> 8) & 0x3f);
01058
01059
01060 gen_chan_info[i].max_pwr = chan_pcal_info->pwr_x0[3];
01061 } else {
01062 chan_pcal_info->pcdac_x0[0] = 1;
01063 gen_chan_info[i].max_pwr = (s8) ((val >> 8) & 0xff);
01064 }
01065
01066 }
01067
01068 return ath5k_eeprom_convert_pcal_info_5112(ah, mode, gen_chan_info);
01069 }
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094 static inline unsigned int
01095 ath5k_pdgains_size_2413(struct ath5k_eeprom_info *ee, unsigned int mode)
01096 {
01097 static const unsigned int pdgains_size[] = { 4, 6, 9, 12 };
01098 unsigned int sz;
01099
01100 sz = pdgains_size[ee->ee_pd_gains[mode] - 1];
01101 sz *= ee->ee_n_piers[mode];
01102
01103 return sz;
01104 }
01105
01106
01107
01108 static unsigned int
01109 ath5k_cal_data_offset_2413(struct ath5k_eeprom_info *ee, int mode)
01110 {
01111 u32 offset = AR5K_EEPROM_CAL_DATA_START(ee->ee_misc4);
01112
01113 switch(mode) {
01114 case AR5K_EEPROM_MODE_11G:
01115 if (AR5K_EEPROM_HDR_11B(ee->ee_header))
01116 offset += ath5k_pdgains_size_2413(ee,
01117 AR5K_EEPROM_MODE_11B) +
01118 AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2;
01119
01120 case AR5K_EEPROM_MODE_11B:
01121 if (AR5K_EEPROM_HDR_11A(ee->ee_header))
01122 offset += ath5k_pdgains_size_2413(ee,
01123 AR5K_EEPROM_MODE_11A) +
01124 AR5K_EEPROM_N_5GHZ_CHAN / 2;
01125
01126 case AR5K_EEPROM_MODE_11A:
01127 break;
01128 default:
01129 break;
01130 }
01131
01132 return offset;
01133 }
01134
01135
01136
01137 static int
01138 ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode,
01139 struct ath5k_chan_pcal_info *chinfo)
01140 {
01141 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
01142 struct ath5k_chan_pcal_info_rf2413 *pcinfo;
01143 u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
01144 unsigned int pier, pdg, point;
01145
01146
01147 for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
01148
01149 pcinfo = &chinfo[pier].rf2413_info;
01150
01151
01152 chinfo[pier].pd_curves =
01153 kcalloc(AR5K_EEPROM_N_PD_CURVES,
01154 sizeof(struct ath5k_pdgain_info),
01155 GFP_KERNEL);
01156
01157 if (!chinfo[pier].pd_curves)
01158 return -ENOMEM;
01159
01160
01161 for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
01162
01163 u8 idx = pdgain_idx[pdg];
01164 struct ath5k_pdgain_info *pd =
01165 &chinfo[pier].pd_curves[idx];
01166
01167
01168
01169 if (pdg == ee->ee_pd_gains[mode] - 1)
01170 pd->pd_points = AR5K_EEPROM_N_PD_POINTS;
01171 else
01172 pd->pd_points = AR5K_EEPROM_N_PD_POINTS - 1;
01173
01174
01175 pd->pd_step = kcalloc(pd->pd_points,
01176 sizeof(u8), GFP_KERNEL);
01177
01178 if (!pd->pd_step)
01179 return -ENOMEM;
01180
01181 pd->pd_pwr = kcalloc(pd->pd_points,
01182 sizeof(s16), GFP_KERNEL);
01183
01184 if (!pd->pd_pwr)
01185 return -ENOMEM;
01186
01187
01188
01189
01190 pd->pd_step[0] = pcinfo->pddac_i[pdg];
01191 pd->pd_pwr[0] = 4 * pcinfo->pwr_i[pdg];
01192
01193 for (point = 1; point < pd->pd_points; point++) {
01194
01195 pd->pd_pwr[point] = pd->pd_pwr[point - 1] +
01196 2 * pcinfo->pwr[pdg][point - 1];
01197
01198 pd->pd_step[point] = pd->pd_step[point - 1] +
01199 pcinfo->pddac[pdg][point - 1];
01200
01201 }
01202
01203
01204 if (pdg == 0)
01205 chinfo[pier].min_pwr = pd->pd_pwr[0];
01206
01207
01208 if (pdg == ee->ee_pd_gains[mode] - 1)
01209 chinfo[pier].max_pwr =
01210 pd->pd_pwr[pd->pd_points - 1];
01211 }
01212 }
01213
01214 return 0;
01215 }
01216
01217
01218 static int
01219 ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode)
01220 {
01221 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
01222 struct ath5k_chan_pcal_info_rf2413 *pcinfo;
01223 struct ath5k_chan_pcal_info *chinfo;
01224 u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
01225 u32 offset;
01226 int idx, i, ret;
01227 u16 val;
01228 u8 pd_gains = 0;
01229
01230
01231
01232
01233
01234
01235 for (idx = AR5K_EEPROM_N_PD_CURVES - 1; idx >= 0; idx--) {
01236
01237 if ((ee->ee_x_gain[mode] >> idx) & 0x1)
01238 pdgain_idx[pd_gains++] = idx;
01239
01240 }
01241 ee->ee_pd_gains[mode] = pd_gains;
01242
01243 if (pd_gains == 0)
01244 return -EINVAL;
01245
01246 offset = ath5k_cal_data_offset_2413(ee, mode);
01247 switch (mode) {
01248 case AR5K_EEPROM_MODE_11A:
01249 if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
01250 return 0;
01251
01252 ath5k_eeprom_init_11a_pcal_freq(ah, offset);
01253 offset += AR5K_EEPROM_N_5GHZ_CHAN / 2;
01254 chinfo = ee->ee_pwr_cal_a;
01255 break;
01256 case AR5K_EEPROM_MODE_11B:
01257 if (!AR5K_EEPROM_HDR_11B(ee->ee_header))
01258 return 0;
01259
01260 ath5k_eeprom_init_11bg_2413(ah, mode, offset);
01261 offset += AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2;
01262 chinfo = ee->ee_pwr_cal_b;
01263 break;
01264 case AR5K_EEPROM_MODE_11G:
01265 if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
01266 return 0;
01267
01268 ath5k_eeprom_init_11bg_2413(ah, mode, offset);
01269 offset += AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2;
01270 chinfo = ee->ee_pwr_cal_g;
01271 break;
01272 default:
01273 return -EINVAL;
01274 }
01275
01276 for (i = 0; i < ee->ee_n_piers[mode]; i++) {
01277 pcinfo = &chinfo[i].rf2413_info;
01278
01279
01280
01281
01282
01283 AR5K_EEPROM_READ(offset++, val);
01284 pcinfo->pwr_i[0] = val & 0x1f;
01285 pcinfo->pddac_i[0] = (val >> 5) & 0x7f;
01286 pcinfo->pwr[0][0] = (val >> 12) & 0xf;
01287
01288 AR5K_EEPROM_READ(offset++, val);
01289 pcinfo->pddac[0][0] = val & 0x3f;
01290 pcinfo->pwr[0][1] = (val >> 6) & 0xf;
01291 pcinfo->pddac[0][1] = (val >> 10) & 0x3f;
01292
01293 AR5K_EEPROM_READ(offset++, val);
01294 pcinfo->pwr[0][2] = val & 0xf;
01295 pcinfo->pddac[0][2] = (val >> 4) & 0x3f;
01296
01297 pcinfo->pwr[0][3] = 0;
01298 pcinfo->pddac[0][3] = 0;
01299
01300 if (pd_gains > 1) {
01301
01302
01303
01304
01305
01306 pcinfo->pwr_i[1] = (val >> 10) & 0x1f;
01307
01308 pcinfo->pddac_i[1] = (val >> 15) & 0x1;
01309 AR5K_EEPROM_READ(offset++, val);
01310 pcinfo->pddac_i[1] |= (val & 0x3F) << 1;
01311
01312 pcinfo->pwr[1][0] = (val >> 6) & 0xf;
01313 pcinfo->pddac[1][0] = (val >> 10) & 0x3f;
01314
01315 AR5K_EEPROM_READ(offset++, val);
01316 pcinfo->pwr[1][1] = val & 0xf;
01317 pcinfo->pddac[1][1] = (val >> 4) & 0x3f;
01318 pcinfo->pwr[1][2] = (val >> 10) & 0xf;
01319
01320 pcinfo->pddac[1][2] = (val >> 14) & 0x3;
01321 AR5K_EEPROM_READ(offset++, val);
01322 pcinfo->pddac[1][2] |= (val & 0xF) << 2;
01323
01324 pcinfo->pwr[1][3] = 0;
01325 pcinfo->pddac[1][3] = 0;
01326 } else if (pd_gains == 1) {
01327
01328
01329
01330
01331 pcinfo->pwr[0][3] = (val >> 10) & 0xf;
01332
01333 pcinfo->pddac[0][3] = (val >> 14) & 0x3;
01334 AR5K_EEPROM_READ(offset++, val);
01335 pcinfo->pddac[0][3] |= (val & 0xF) << 2;
01336 }
01337
01338
01339
01340
01341
01342 if (pd_gains > 2) {
01343 pcinfo->pwr_i[2] = (val >> 4) & 0x1f;
01344 pcinfo->pddac_i[2] = (val >> 9) & 0x7f;
01345
01346 AR5K_EEPROM_READ(offset++, val);
01347 pcinfo->pwr[2][0] = (val >> 0) & 0xf;
01348 pcinfo->pddac[2][0] = (val >> 4) & 0x3f;
01349 pcinfo->pwr[2][1] = (val >> 10) & 0xf;
01350
01351 pcinfo->pddac[2][1] = (val >> 14) & 0x3;
01352 AR5K_EEPROM_READ(offset++, val);
01353 pcinfo->pddac[2][1] |= (val & 0xF) << 2;
01354
01355 pcinfo->pwr[2][2] = (val >> 4) & 0xf;
01356 pcinfo->pddac[2][2] = (val >> 8) & 0x3f;
01357
01358 pcinfo->pwr[2][3] = 0;
01359 pcinfo->pddac[2][3] = 0;
01360 } else if (pd_gains == 2) {
01361 pcinfo->pwr[1][3] = (val >> 4) & 0xf;
01362 pcinfo->pddac[1][3] = (val >> 8) & 0x3f;
01363 }
01364
01365 if (pd_gains > 3) {
01366 pcinfo->pwr_i[3] = (val >> 14) & 0x3;
01367 AR5K_EEPROM_READ(offset++, val);
01368 pcinfo->pwr_i[3] |= ((val >> 0) & 0x7) << 2;
01369
01370 pcinfo->pddac_i[3] = (val >> 3) & 0x7f;
01371 pcinfo->pwr[3][0] = (val >> 10) & 0xf;
01372 pcinfo->pddac[3][0] = (val >> 14) & 0x3;
01373
01374 AR5K_EEPROM_READ(offset++, val);
01375 pcinfo->pddac[3][0] |= (val & 0xF) << 2;
01376 pcinfo->pwr[3][1] = (val >> 4) & 0xf;
01377 pcinfo->pddac[3][1] = (val >> 8) & 0x3f;
01378
01379 pcinfo->pwr[3][2] = (val >> 14) & 0x3;
01380 AR5K_EEPROM_READ(offset++, val);
01381 pcinfo->pwr[3][2] |= ((val >> 0) & 0x3) << 2;
01382
01383 pcinfo->pddac[3][2] = (val >> 2) & 0x3f;
01384 pcinfo->pwr[3][3] = (val >> 8) & 0xf;
01385
01386 pcinfo->pddac[3][3] = (val >> 12) & 0xF;
01387 AR5K_EEPROM_READ(offset++, val);
01388 pcinfo->pddac[3][3] |= ((val >> 0) & 0x3) << 4;
01389 } else if (pd_gains == 3) {
01390 pcinfo->pwr[2][3] = (val >> 14) & 0x3;
01391 AR5K_EEPROM_READ(offset++, val);
01392 pcinfo->pwr[2][3] |= ((val >> 0) & 0x3) << 2;
01393
01394 pcinfo->pddac[2][3] = (val >> 2) & 0x3f;
01395 }
01396 }
01397
01398 return ath5k_eeprom_convert_pcal_info_2413(ah, mode, chinfo);
01399 }
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409 static int
01410 ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned int mode)
01411 {
01412 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
01413 struct ath5k_rate_pcal_info *rate_pcal_info;
01414 u8 *rate_target_pwr_num;
01415 u32 offset;
01416 u16 val;
01417 int ret, i;
01418
01419 offset = AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1);
01420 rate_target_pwr_num = &ee->ee_rate_target_pwr_num[mode];
01421 switch (mode) {
01422 case AR5K_EEPROM_MODE_11A:
01423 offset += AR5K_EEPROM_TARGET_PWR_OFF_11A(ee->ee_version);
01424 rate_pcal_info = ee->ee_rate_tpwr_a;
01425 ee->ee_rate_target_pwr_num[mode] = AR5K_EEPROM_N_5GHZ_CHAN;
01426 break;
01427 case AR5K_EEPROM_MODE_11B:
01428 offset += AR5K_EEPROM_TARGET_PWR_OFF_11B(ee->ee_version);
01429 rate_pcal_info = ee->ee_rate_tpwr_b;
01430 ee->ee_rate_target_pwr_num[mode] = 2;
01431 break;
01432 case AR5K_EEPROM_MODE_11G:
01433 offset += AR5K_EEPROM_TARGET_PWR_OFF_11G(ee->ee_version);
01434 rate_pcal_info = ee->ee_rate_tpwr_g;
01435 ee->ee_rate_target_pwr_num[mode] = AR5K_EEPROM_N_2GHZ_CHAN;
01436 break;
01437 default:
01438 return -EINVAL;
01439 }
01440
01441
01442 if (ee->ee_version <= AR5K_EEPROM_VERSION_3_2) {
01443 for (i = 0; i < (*rate_target_pwr_num); i++) {
01444 AR5K_EEPROM_READ(offset++, val);
01445 rate_pcal_info[i].freq =
01446 ath5k_eeprom_bin2freq(ee, (val >> 9) & 0x7f, mode);
01447
01448 rate_pcal_info[i].target_power_6to24 = ((val >> 3) & 0x3f);
01449 rate_pcal_info[i].target_power_36 = (val << 3) & 0x3f;
01450
01451 AR5K_EEPROM_READ(offset++, val);
01452
01453 if (rate_pcal_info[i].freq == AR5K_EEPROM_CHANNEL_DIS ||
01454 val == 0) {
01455 (*rate_target_pwr_num) = i;
01456 break;
01457 }
01458
01459 rate_pcal_info[i].target_power_36 |= ((val >> 13) & 0x7);
01460 rate_pcal_info[i].target_power_48 = ((val >> 7) & 0x3f);
01461 rate_pcal_info[i].target_power_54 = ((val >> 1) & 0x3f);
01462 }
01463 } else {
01464 for (i = 0; i < (*rate_target_pwr_num); i++) {
01465 AR5K_EEPROM_READ(offset++, val);
01466 rate_pcal_info[i].freq =
01467 ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode);
01468
01469 rate_pcal_info[i].target_power_6to24 = ((val >> 2) & 0x3f);
01470 rate_pcal_info[i].target_power_36 = (val << 4) & 0x3f;
01471
01472 AR5K_EEPROM_READ(offset++, val);
01473
01474 if (rate_pcal_info[i].freq == AR5K_EEPROM_CHANNEL_DIS ||
01475 val == 0) {
01476 (*rate_target_pwr_num) = i;
01477 break;
01478 }
01479
01480 rate_pcal_info[i].target_power_36 |= (val >> 12) & 0xf;
01481 rate_pcal_info[i].target_power_48 = ((val >> 6) & 0x3f);
01482 rate_pcal_info[i].target_power_54 = (val & 0x3f);
01483 }
01484 }
01485
01486 return 0;
01487 }
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503 static int
01504 ath5k_eeprom_read_pcal_info(struct ath5k_hw *ah)
01505 {
01506 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
01507 int (*read_pcal)(struct ath5k_hw *hw, int mode);
01508 int mode;
01509 int err;
01510
01511 if ((ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) &&
01512 (AR5K_EEPROM_EEMAP(ee->ee_misc0) == 1))
01513 read_pcal = ath5k_eeprom_read_pcal_info_5112;
01514 else if ((ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_0) &&
01515 (AR5K_EEPROM_EEMAP(ee->ee_misc0) == 2))
01516 read_pcal = ath5k_eeprom_read_pcal_info_2413;
01517 else
01518 read_pcal = ath5k_eeprom_read_pcal_info_5111;
01519
01520
01521 for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G;
01522 mode++) {
01523 err = read_pcal(ah, mode);
01524 if (err)
01525 return err;
01526
01527 err = ath5k_eeprom_read_target_rate_pwr_info(ah, mode);
01528 if (err < 0)
01529 return err;
01530 }
01531
01532 return 0;
01533 }
01534
01535 static int
01536 ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode)
01537 {
01538 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
01539 struct ath5k_chan_pcal_info *chinfo;
01540 u8 pier, pdg;
01541
01542 switch (mode) {
01543 case AR5K_EEPROM_MODE_11A:
01544 if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
01545 return 0;
01546 chinfo = ee->ee_pwr_cal_a;
01547 break;
01548 case AR5K_EEPROM_MODE_11B:
01549 if (!AR5K_EEPROM_HDR_11B(ee->ee_header))
01550 return 0;
01551 chinfo = ee->ee_pwr_cal_b;
01552 break;
01553 case AR5K_EEPROM_MODE_11G:
01554 if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
01555 return 0;
01556 chinfo = ee->ee_pwr_cal_g;
01557 break;
01558 default:
01559 return -EINVAL;
01560 }
01561
01562 for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
01563 if (!chinfo[pier].pd_curves)
01564 continue;
01565
01566 for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
01567 struct ath5k_pdgain_info *pd =
01568 &chinfo[pier].pd_curves[pdg];
01569
01570 if (pd != NULL) {
01571 kfree(pd->pd_step);
01572 kfree(pd->pd_pwr);
01573 }
01574 }
01575
01576 kfree(chinfo[pier].pd_curves);
01577 }
01578
01579 return 0;
01580 }
01581
01582 void
01583 ath5k_eeprom_detach(struct ath5k_hw *ah)
01584 {
01585 u8 mode;
01586
01587 for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++)
01588 ath5k_eeprom_free_pcal_info(ah, mode);
01589 }
01590
01591
01592 static int
01593 ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah)
01594 {
01595 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
01596 struct ath5k_edge_power *rep;
01597 unsigned int fmask, pmask;
01598 unsigned int ctl_mode;
01599 int ret, i, j;
01600 u32 offset;
01601 u16 val;
01602
01603 pmask = AR5K_EEPROM_POWER_M;
01604 fmask = AR5K_EEPROM_FREQ_M(ee->ee_version);
01605 offset = AR5K_EEPROM_CTL(ee->ee_version);
01606 ee->ee_ctls = AR5K_EEPROM_N_CTLS(ee->ee_version);
01607 for (i = 0; i < ee->ee_ctls; i += 2) {
01608 AR5K_EEPROM_READ(offset++, val);
01609 ee->ee_ctl[i] = (val >> 8) & 0xff;
01610 ee->ee_ctl[i + 1] = val & 0xff;
01611 }
01612
01613 offset = AR5K_EEPROM_GROUP8_OFFSET;
01614 if (ee->ee_version >= AR5K_EEPROM_VERSION_4_0)
01615 offset += AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1) -
01616 AR5K_EEPROM_GROUP5_OFFSET;
01617 else
01618 offset += AR5K_EEPROM_GROUPS_START(ee->ee_version);
01619
01620 rep = ee->ee_ctl_pwr;
01621 for(i = 0; i < ee->ee_ctls; i++) {
01622 switch(ee->ee_ctl[i] & AR5K_CTL_MODE_M) {
01623 case AR5K_CTL_11A:
01624 case AR5K_CTL_TURBO:
01625 ctl_mode = AR5K_EEPROM_MODE_11A;
01626 break;
01627 default:
01628 ctl_mode = AR5K_EEPROM_MODE_11G;
01629 break;
01630 }
01631 if (ee->ee_ctl[i] == 0) {
01632 if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3)
01633 offset += 8;
01634 else
01635 offset += 7;
01636 rep += AR5K_EEPROM_N_EDGES;
01637 continue;
01638 }
01639 if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3) {
01640 for (j = 0; j < AR5K_EEPROM_N_EDGES; j += 2) {
01641 AR5K_EEPROM_READ(offset++, val);
01642 rep[j].freq = (val >> 8) & fmask;
01643 rep[j + 1].freq = val & fmask;
01644 }
01645 for (j = 0; j < AR5K_EEPROM_N_EDGES; j += 2) {
01646 AR5K_EEPROM_READ(offset++, val);
01647 rep[j].edge = (val >> 8) & pmask;
01648 rep[j].flag = (val >> 14) & 1;
01649 rep[j + 1].edge = val & pmask;
01650 rep[j + 1].flag = (val >> 6) & 1;
01651 }
01652 } else {
01653 AR5K_EEPROM_READ(offset++, val);
01654 rep[0].freq = (val >> 9) & fmask;
01655 rep[1].freq = (val >> 2) & fmask;
01656 rep[2].freq = (val << 5) & fmask;
01657
01658 AR5K_EEPROM_READ(offset++, val);
01659 rep[2].freq |= (val >> 11) & 0x1f;
01660 rep[3].freq = (val >> 4) & fmask;
01661 rep[4].freq = (val << 3) & fmask;
01662
01663 AR5K_EEPROM_READ(offset++, val);
01664 rep[4].freq |= (val >> 13) & 0x7;
01665 rep[5].freq = (val >> 6) & fmask;
01666 rep[6].freq = (val << 1) & fmask;
01667
01668 AR5K_EEPROM_READ(offset++, val);
01669 rep[6].freq |= (val >> 15) & 0x1;
01670 rep[7].freq = (val >> 8) & fmask;
01671
01672 rep[0].edge = (val >> 2) & pmask;
01673 rep[1].edge = (val << 4) & pmask;
01674
01675 AR5K_EEPROM_READ(offset++, val);
01676 rep[1].edge |= (val >> 12) & 0xf;
01677 rep[2].edge = (val >> 6) & pmask;
01678 rep[3].edge = val & pmask;
01679
01680 AR5K_EEPROM_READ(offset++, val);
01681 rep[4].edge = (val >> 10) & pmask;
01682 rep[5].edge = (val >> 4) & pmask;
01683 rep[6].edge = (val << 2) & pmask;
01684
01685 AR5K_EEPROM_READ(offset++, val);
01686 rep[6].edge |= (val >> 14) & 0x3;
01687 rep[7].edge = (val >> 8) & pmask;
01688 }
01689 for (j = 0; j < AR5K_EEPROM_N_EDGES; j++) {
01690 rep[j].freq = ath5k_eeprom_bin2freq(ee,
01691 rep[j].freq, ctl_mode);
01692 }
01693 rep += AR5K_EEPROM_N_EDGES;
01694 }
01695
01696 return 0;
01697 }
01698
01699 static int
01700 ath5k_eeprom_read_spur_chans(struct ath5k_hw *ah)
01701 {
01702 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
01703 u32 offset;
01704 u16 val;
01705 int ret = 0, i;
01706
01707 offset = AR5K_EEPROM_CTL(ee->ee_version) +
01708 AR5K_EEPROM_N_CTLS(ee->ee_version);
01709
01710 if (ee->ee_version < AR5K_EEPROM_VERSION_5_3) {
01711
01712 ee->ee_spur_chans[0][0] = AR5K_EEPROM_NO_SPUR;
01713
01714 ee->ee_spur_chans[0][1] = AR5K_EEPROM_5413_SPUR_CHAN_1;
01715 ee->ee_spur_chans[1][1] = AR5K_EEPROM_5413_SPUR_CHAN_2;
01716 ee->ee_spur_chans[2][1] = AR5K_EEPROM_NO_SPUR;
01717 } else if (ee->ee_version >= AR5K_EEPROM_VERSION_5_3) {
01718 for (i = 0; i < AR5K_EEPROM_N_SPUR_CHANS; i++) {
01719 AR5K_EEPROM_READ(offset, val);
01720 ee->ee_spur_chans[i][0] = val;
01721 AR5K_EEPROM_READ(offset + AR5K_EEPROM_N_SPUR_CHANS,
01722 val);
01723 ee->ee_spur_chans[i][1] = val;
01724 offset++;
01725 }
01726 }
01727
01728 return ret;
01729 }
01730
01731
01732
01733
01734 int
01735 ath5k_eeprom_init(struct ath5k_hw *ah)
01736 {
01737 int err;
01738
01739 err = ath5k_eeprom_init_header(ah);
01740 if (err < 0)
01741 return err;
01742
01743 err = ath5k_eeprom_init_modes(ah);
01744 if (err < 0)
01745 return err;
01746
01747 err = ath5k_eeprom_read_pcal_info(ah);
01748 if (err < 0)
01749 return err;
01750
01751 err = ath5k_eeprom_read_ctl_info(ah);
01752 if (err < 0)
01753 return err;
01754
01755 err = ath5k_eeprom_read_spur_chans(ah);
01756 if (err < 0)
01757 return err;
01758
01759 return 0;
01760 }
01761
01762
01763
01764
01765 int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
01766 {
01767 u8 mac_d[ETH_ALEN] = {};
01768 u32 total, offset;
01769 u16 data;
01770 int octet, ret;
01771
01772 ret = ath5k_hw_eeprom_read(ah, 0x20, &data);
01773 if (ret)
01774 return ret;
01775
01776 for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) {
01777 ret = ath5k_hw_eeprom_read(ah, offset, &data);
01778 if (ret)
01779 return ret;
01780
01781 total += data;
01782 mac_d[octet + 1] = data & 0xff;
01783 mac_d[octet] = data >> 8;
01784 octet += 2;
01785 }
01786
01787 if (!total || total == 3 * 0xffff)
01788 return -EINVAL;
01789
01790 memcpy(mac, mac_d, ETH_ALEN);
01791
01792 return 0;
01793 }