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