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