0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0025
0026 #include <linux/slab.h>
0027
0028 #include "ath5k.h"
0029 #include "reg.h"
0030 #include "debug.h"
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040 static u16 ath5k_eeprom_bin2freq(struct ath5k_eeprom_info *ee, u16 bin,
0041 unsigned int mode)
0042 {
0043 u16 val;
0044
0045 if (bin == AR5K_EEPROM_CHANNEL_DIS)
0046 return bin;
0047
0048 if (mode == AR5K_EEPROM_MODE_11A) {
0049 if (ee->ee_version > AR5K_EEPROM_VERSION_3_2)
0050 val = (5 * bin) + 4800;
0051 else
0052 val = bin > 62 ? (10 * 62) + (5 * (bin - 62)) + 5100 :
0053 (bin * 10) + 5100;
0054 } else {
0055 if (ee->ee_version > AR5K_EEPROM_VERSION_3_2)
0056 val = bin + 2300;
0057 else
0058 val = bin + 2400;
0059 }
0060
0061 return val;
0062 }
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072 static int
0073 ath5k_eeprom_init_header(struct ath5k_hw *ah)
0074 {
0075 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
0076 u16 val;
0077 u32 cksum, offset, eep_max = AR5K_EEPROM_INFO_MAX;
0078
0079
0080
0081
0082 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MAGIC, ee_magic);
0083 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_PROTECT, ee_protect);
0084 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_REG_DOMAIN, ee_regdomain);
0085 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_VERSION, ee_version);
0086 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_HDR, ee_header);
0087
0088
0089 if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_0)
0090 return 0;
0091
0092
0093
0094
0095
0096 AR5K_EEPROM_READ(AR5K_EEPROM_SIZE_UPPER, val);
0097 if (val) {
0098 eep_max = (val & AR5K_EEPROM_SIZE_UPPER_MASK) <<
0099 AR5K_EEPROM_SIZE_ENDLOC_SHIFT;
0100 AR5K_EEPROM_READ(AR5K_EEPROM_SIZE_LOWER, val);
0101 eep_max = (eep_max | val) - AR5K_EEPROM_INFO_BASE;
0102
0103
0104
0105
0106
0107
0108 if (eep_max > (3 * AR5K_EEPROM_INFO_MAX)) {
0109 ATH5K_ERR(ah, "Invalid max custom EEPROM size: "
0110 "%d (0x%04x) max expected: %d (0x%04x)\n",
0111 eep_max, eep_max,
0112 3 * AR5K_EEPROM_INFO_MAX,
0113 3 * AR5K_EEPROM_INFO_MAX);
0114 return -EIO;
0115 }
0116 }
0117
0118 for (cksum = 0, offset = 0; offset < eep_max; offset++) {
0119 AR5K_EEPROM_READ(AR5K_EEPROM_INFO(offset), val);
0120 cksum ^= val;
0121 }
0122 if (cksum != AR5K_EEPROM_INFO_CKSUM) {
0123 ATH5K_ERR(ah, "Invalid EEPROM "
0124 "checksum: 0x%04x eep_max: 0x%04x (%s)\n",
0125 cksum, eep_max,
0126 eep_max == AR5K_EEPROM_INFO_MAX ?
0127 "default size" : "custom size");
0128 return -EIO;
0129 }
0130
0131 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_ANT_GAIN(ah->ah_ee_version),
0132 ee_ant_gain);
0133
0134 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
0135 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC0, ee_misc0);
0136 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC1, ee_misc1);
0137
0138
0139 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC2, ee_misc2);
0140
0141 if (ee->ee_version >= AR5K_EEPROM_VERSION_4_3)
0142 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC3, ee_misc3);
0143
0144 if (ee->ee_version >= AR5K_EEPROM_VERSION_5_0) {
0145 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC4, ee_misc4);
0146 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC5, ee_misc5);
0147 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC6, ee_misc6);
0148 }
0149 }
0150
0151 if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_3) {
0152 AR5K_EEPROM_READ(AR5K_EEPROM_OBDB0_2GHZ, val);
0153 ee->ee_ob[AR5K_EEPROM_MODE_11B][0] = val & 0x7;
0154 ee->ee_db[AR5K_EEPROM_MODE_11B][0] = (val >> 3) & 0x7;
0155
0156 AR5K_EEPROM_READ(AR5K_EEPROM_OBDB1_2GHZ, val);
0157 ee->ee_ob[AR5K_EEPROM_MODE_11G][0] = val & 0x7;
0158 ee->ee_db[AR5K_EEPROM_MODE_11G][0] = (val >> 3) & 0x7;
0159 }
0160
0161 AR5K_EEPROM_READ(AR5K_EEPROM_IS_HB63, val);
0162
0163 if ((ah->ah_mac_version == (AR5K_SREV_AR2425 >> 4)) && val)
0164 ee->ee_is_hb63 = true;
0165 else
0166 ee->ee_is_hb63 = false;
0167
0168 AR5K_EEPROM_READ(AR5K_EEPROM_RFKILL, val);
0169 ee->ee_rfkill_pin = (u8) AR5K_REG_MS(val, AR5K_EEPROM_RFKILL_GPIO_SEL);
0170 ee->ee_rfkill_pol = val & AR5K_EEPROM_RFKILL_POLARITY ? true : false;
0171
0172
0173
0174
0175
0176
0177
0178 AR5K_EEPROM_READ(AR5K_EEPROM_PCIE_OFFSET, val);
0179 ee->ee_serdes = (val == AR5K_EEPROM_PCIE_SERDES_SECTION) ?
0180 true : false;
0181
0182 return 0;
0183 }
0184
0185
0186
0187
0188
0189 static int ath5k_eeprom_read_ants(struct ath5k_hw *ah, u32 *offset,
0190 unsigned int mode)
0191 {
0192 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
0193 u32 o = *offset;
0194 u16 val;
0195 int i = 0;
0196
0197 AR5K_EEPROM_READ(o++, val);
0198 ee->ee_switch_settling[mode] = (val >> 8) & 0x7f;
0199 ee->ee_atn_tx_rx[mode] = (val >> 2) & 0x3f;
0200 ee->ee_ant_control[mode][i] = (val << 4) & 0x3f;
0201
0202 AR5K_EEPROM_READ(o++, val);
0203 ee->ee_ant_control[mode][i++] |= (val >> 12) & 0xf;
0204 ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f;
0205 ee->ee_ant_control[mode][i++] = val & 0x3f;
0206
0207 AR5K_EEPROM_READ(o++, val);
0208 ee->ee_ant_control[mode][i++] = (val >> 10) & 0x3f;
0209 ee->ee_ant_control[mode][i++] = (val >> 4) & 0x3f;
0210 ee->ee_ant_control[mode][i] = (val << 2) & 0x3f;
0211
0212 AR5K_EEPROM_READ(o++, val);
0213 ee->ee_ant_control[mode][i++] |= (val >> 14) & 0x3;
0214 ee->ee_ant_control[mode][i++] = (val >> 8) & 0x3f;
0215 ee->ee_ant_control[mode][i++] = (val >> 2) & 0x3f;
0216 ee->ee_ant_control[mode][i] = (val << 4) & 0x3f;
0217
0218 AR5K_EEPROM_READ(o++, val);
0219 ee->ee_ant_control[mode][i++] |= (val >> 12) & 0xf;
0220 ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f;
0221 ee->ee_ant_control[mode][i++] = val & 0x3f;
0222
0223
0224 ah->ah_ant_ctl[mode][AR5K_ANT_CTL] =
0225 (ee->ee_ant_control[mode][0] << 4);
0226 ah->ah_ant_ctl[mode][AR5K_ANT_SWTABLE_A] =
0227 ee->ee_ant_control[mode][1] |
0228 (ee->ee_ant_control[mode][2] << 6) |
0229 (ee->ee_ant_control[mode][3] << 12) |
0230 (ee->ee_ant_control[mode][4] << 18) |
0231 (ee->ee_ant_control[mode][5] << 24);
0232 ah->ah_ant_ctl[mode][AR5K_ANT_SWTABLE_B] =
0233 ee->ee_ant_control[mode][6] |
0234 (ee->ee_ant_control[mode][7] << 6) |
0235 (ee->ee_ant_control[mode][8] << 12) |
0236 (ee->ee_ant_control[mode][9] << 18) |
0237 (ee->ee_ant_control[mode][10] << 24);
0238
0239
0240 *offset = o;
0241
0242 return 0;
0243 }
0244
0245
0246
0247
0248
0249 static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,
0250 unsigned int mode)
0251 {
0252 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
0253 u32 o = *offset;
0254 u16 val;
0255
0256 ee->ee_n_piers[mode] = 0;
0257 AR5K_EEPROM_READ(o++, val);
0258 ee->ee_adc_desired_size[mode] = (s8)((val >> 8) & 0xff);
0259 switch (mode) {
0260 case AR5K_EEPROM_MODE_11A:
0261 ee->ee_ob[mode][3] = (val >> 5) & 0x7;
0262 ee->ee_db[mode][3] = (val >> 2) & 0x7;
0263 ee->ee_ob[mode][2] = (val << 1) & 0x7;
0264
0265 AR5K_EEPROM_READ(o++, val);
0266 ee->ee_ob[mode][2] |= (val >> 15) & 0x1;
0267 ee->ee_db[mode][2] = (val >> 12) & 0x7;
0268 ee->ee_ob[mode][1] = (val >> 9) & 0x7;
0269 ee->ee_db[mode][1] = (val >> 6) & 0x7;
0270 ee->ee_ob[mode][0] = (val >> 3) & 0x7;
0271 ee->ee_db[mode][0] = val & 0x7;
0272 break;
0273 case AR5K_EEPROM_MODE_11G:
0274 case AR5K_EEPROM_MODE_11B:
0275 ee->ee_ob[mode][1] = (val >> 4) & 0x7;
0276 ee->ee_db[mode][1] = val & 0x7;
0277 break;
0278 }
0279
0280 AR5K_EEPROM_READ(o++, val);
0281 ee->ee_tx_end2xlna_enable[mode] = (val >> 8) & 0xff;
0282 ee->ee_thr_62[mode] = val & 0xff;
0283
0284 if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2)
0285 ee->ee_thr_62[mode] = mode == AR5K_EEPROM_MODE_11A ? 15 : 28;
0286
0287 AR5K_EEPROM_READ(o++, val);
0288 ee->ee_tx_end2xpa_disable[mode] = (val >> 8) & 0xff;
0289 ee->ee_tx_frm2xpa_enable[mode] = val & 0xff;
0290
0291 AR5K_EEPROM_READ(o++, val);
0292 ee->ee_pga_desired_size[mode] = (val >> 8) & 0xff;
0293
0294 if ((val & 0xff) & 0x80)
0295 ee->ee_noise_floor_thr[mode] = -((((val & 0xff) ^ 0xff)) + 1);
0296 else
0297 ee->ee_noise_floor_thr[mode] = val & 0xff;
0298
0299 if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2)
0300 ee->ee_noise_floor_thr[mode] =
0301 mode == AR5K_EEPROM_MODE_11A ? -54 : -1;
0302
0303 AR5K_EEPROM_READ(o++, val);
0304 ee->ee_xlna_gain[mode] = (val >> 5) & 0xff;
0305 ee->ee_x_gain[mode] = (val >> 1) & 0xf;
0306 ee->ee_xpd[mode] = val & 0x1;
0307
0308 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0 &&
0309 mode != AR5K_EEPROM_MODE_11B)
0310 ee->ee_fixed_bias[mode] = (val >> 13) & 0x1;
0311
0312 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_3) {
0313 AR5K_EEPROM_READ(o++, val);
0314 ee->ee_false_detect[mode] = (val >> 6) & 0x7f;
0315
0316 if (mode == AR5K_EEPROM_MODE_11A)
0317 ee->ee_xr_power[mode] = val & 0x3f;
0318 else {
0319
0320 ee->ee_ob[mode][0] = val & 0x7;
0321 ee->ee_db[mode][0] = (val >> 3) & 0x7;
0322 }
0323 }
0324
0325 if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_4) {
0326 ee->ee_i_gain[mode] = AR5K_EEPROM_I_GAIN;
0327 ee->ee_cck_ofdm_power_delta = AR5K_EEPROM_CCK_OFDM_DELTA;
0328 } else {
0329 ee->ee_i_gain[mode] = (val >> 13) & 0x7;
0330
0331 AR5K_EEPROM_READ(o++, val);
0332 ee->ee_i_gain[mode] |= (val << 3) & 0x38;
0333
0334 if (mode == AR5K_EEPROM_MODE_11G) {
0335 ee->ee_cck_ofdm_power_delta = (val >> 3) & 0xff;
0336 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_6)
0337 ee->ee_scaled_cck_delta = (val >> 11) & 0x1f;
0338 }
0339 }
0340
0341 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0 &&
0342 mode == AR5K_EEPROM_MODE_11A) {
0343 ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
0344 ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
0345 }
0346
0347 if (ah->ah_ee_version < AR5K_EEPROM_VERSION_4_0)
0348 goto done;
0349
0350
0351
0352
0353 switch (mode) {
0354 case AR5K_EEPROM_MODE_11A:
0355 if (ah->ah_ee_version < AR5K_EEPROM_VERSION_4_1)
0356 break;
0357
0358 AR5K_EEPROM_READ(o++, val);
0359 ee->ee_margin_tx_rx[mode] = val & 0x3f;
0360 break;
0361 case AR5K_EEPROM_MODE_11B:
0362 AR5K_EEPROM_READ(o++, val);
0363
0364 ee->ee_pwr_cal_b[0].freq =
0365 ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
0366 if (ee->ee_pwr_cal_b[0].freq != AR5K_EEPROM_CHANNEL_DIS)
0367 ee->ee_n_piers[mode]++;
0368
0369 ee->ee_pwr_cal_b[1].freq =
0370 ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode);
0371 if (ee->ee_pwr_cal_b[1].freq != AR5K_EEPROM_CHANNEL_DIS)
0372 ee->ee_n_piers[mode]++;
0373
0374 AR5K_EEPROM_READ(o++, val);
0375 ee->ee_pwr_cal_b[2].freq =
0376 ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
0377 if (ee->ee_pwr_cal_b[2].freq != AR5K_EEPROM_CHANNEL_DIS)
0378 ee->ee_n_piers[mode]++;
0379
0380 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
0381 ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
0382 break;
0383 case AR5K_EEPROM_MODE_11G:
0384 AR5K_EEPROM_READ(o++, val);
0385
0386 ee->ee_pwr_cal_g[0].freq =
0387 ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
0388 if (ee->ee_pwr_cal_g[0].freq != AR5K_EEPROM_CHANNEL_DIS)
0389 ee->ee_n_piers[mode]++;
0390
0391 ee->ee_pwr_cal_g[1].freq =
0392 ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode);
0393 if (ee->ee_pwr_cal_g[1].freq != AR5K_EEPROM_CHANNEL_DIS)
0394 ee->ee_n_piers[mode]++;
0395
0396 AR5K_EEPROM_READ(o++, val);
0397 ee->ee_turbo_max_power[mode] = val & 0x7f;
0398 ee->ee_xr_power[mode] = (val >> 7) & 0x3f;
0399
0400 AR5K_EEPROM_READ(o++, val);
0401 ee->ee_pwr_cal_g[2].freq =
0402 ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
0403 if (ee->ee_pwr_cal_g[2].freq != AR5K_EEPROM_CHANNEL_DIS)
0404 ee->ee_n_piers[mode]++;
0405
0406 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
0407 ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
0408
0409 AR5K_EEPROM_READ(o++, val);
0410 ee->ee_i_cal[mode] = (val >> 5) & 0x3f;
0411 ee->ee_q_cal[mode] = val & 0x1f;
0412
0413 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_2) {
0414 AR5K_EEPROM_READ(o++, val);
0415 ee->ee_cck_ofdm_gain_delta = val & 0xff;
0416 }
0417 break;
0418 }
0419
0420
0421
0422
0423 if (ee->ee_version < AR5K_EEPROM_VERSION_5_0)
0424 goto done;
0425
0426 switch (mode) {
0427 case AR5K_EEPROM_MODE_11A:
0428 ee->ee_switch_settling_turbo[mode] = (val >> 6) & 0x7f;
0429
0430 ee->ee_atn_tx_rx_turbo[mode] = (val >> 13) & 0x7;
0431 AR5K_EEPROM_READ(o++, val);
0432 ee->ee_atn_tx_rx_turbo[mode] |= (val & 0x7) << 3;
0433 ee->ee_margin_tx_rx_turbo[mode] = (val >> 3) & 0x3f;
0434
0435 ee->ee_adc_desired_size_turbo[mode] = (val >> 9) & 0x7f;
0436 AR5K_EEPROM_READ(o++, val);
0437 ee->ee_adc_desired_size_turbo[mode] |= (val & 0x1) << 7;
0438 ee->ee_pga_desired_size_turbo[mode] = (val >> 1) & 0xff;
0439
0440 if (AR5K_EEPROM_EEMAP(ee->ee_misc0) >= 2)
0441 ee->ee_pd_gain_overlap = (val >> 9) & 0xf;
0442 break;
0443 case AR5K_EEPROM_MODE_11G:
0444 ee->ee_switch_settling_turbo[mode] = (val >> 8) & 0x7f;
0445
0446 ee->ee_atn_tx_rx_turbo[mode] = (val >> 15) & 0x7;
0447 AR5K_EEPROM_READ(o++, val);
0448 ee->ee_atn_tx_rx_turbo[mode] |= (val & 0x1f) << 1;
0449 ee->ee_margin_tx_rx_turbo[mode] = (val >> 5) & 0x3f;
0450
0451 ee->ee_adc_desired_size_turbo[mode] = (val >> 11) & 0x7f;
0452 AR5K_EEPROM_READ(o++, val);
0453 ee->ee_adc_desired_size_turbo[mode] |= (val & 0x7) << 5;
0454 ee->ee_pga_desired_size_turbo[mode] = (val >> 3) & 0xff;
0455 break;
0456 }
0457
0458 done:
0459
0460 *offset = o;
0461
0462 return 0;
0463 }
0464
0465
0466 static int
0467 ath5k_eeprom_init_modes(struct ath5k_hw *ah)
0468 {
0469 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
0470 u32 mode_offset[3];
0471 unsigned int mode;
0472 u32 offset;
0473 int ret;
0474
0475
0476
0477
0478 mode_offset[AR5K_EEPROM_MODE_11A] = AR5K_EEPROM_MODES_11A(ah->ah_ee_version);
0479 mode_offset[AR5K_EEPROM_MODE_11B] = AR5K_EEPROM_MODES_11B(ah->ah_ee_version);
0480 mode_offset[AR5K_EEPROM_MODE_11G] = AR5K_EEPROM_MODES_11G(ah->ah_ee_version);
0481
0482 ee->ee_turbo_max_power[AR5K_EEPROM_MODE_11A] =
0483 AR5K_EEPROM_HDR_T_5GHZ_DBM(ee->ee_header);
0484
0485 for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++) {
0486 offset = mode_offset[mode];
0487
0488 ret = ath5k_eeprom_read_ants(ah, &offset, mode);
0489 if (ret)
0490 return ret;
0491
0492 ret = ath5k_eeprom_read_modes(ah, &offset, mode);
0493 if (ret)
0494 return ret;
0495 }
0496
0497
0498 if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2) {
0499 ee->ee_thr_62[AR5K_EEPROM_MODE_11A] = 15;
0500 ee->ee_thr_62[AR5K_EEPROM_MODE_11B] = 28;
0501 ee->ee_thr_62[AR5K_EEPROM_MODE_11G] = 28;
0502 }
0503
0504 return 0;
0505 }
0506
0507
0508
0509 static inline int
0510 ath5k_eeprom_read_freq_list(struct ath5k_hw *ah, int *offset, int max,
0511 struct ath5k_chan_pcal_info *pc, unsigned int mode)
0512 {
0513 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
0514 int o = *offset;
0515 int i = 0;
0516 u8 freq1, freq2;
0517 u16 val;
0518
0519 ee->ee_n_piers[mode] = 0;
0520 while (i < max) {
0521 AR5K_EEPROM_READ(o++, val);
0522
0523 freq1 = val & 0xff;
0524 if (!freq1)
0525 break;
0526
0527 pc[i++].freq = ath5k_eeprom_bin2freq(ee,
0528 freq1, mode);
0529 ee->ee_n_piers[mode]++;
0530
0531 freq2 = (val >> 8) & 0xff;
0532 if (!freq2)
0533 break;
0534
0535 pc[i++].freq = ath5k_eeprom_bin2freq(ee,
0536 freq2, mode);
0537 ee->ee_n_piers[mode]++;
0538 }
0539
0540
0541 *offset = o;
0542
0543 return 0;
0544 }
0545
0546
0547 static int
0548 ath5k_eeprom_init_11a_pcal_freq(struct ath5k_hw *ah, int offset)
0549 {
0550 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
0551 struct ath5k_chan_pcal_info *pcal = ee->ee_pwr_cal_a;
0552 int i;
0553 u16 val;
0554 u8 mask;
0555
0556 if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3) {
0557 ath5k_eeprom_read_freq_list(ah, &offset,
0558 AR5K_EEPROM_N_5GHZ_CHAN, pcal,
0559 AR5K_EEPROM_MODE_11A);
0560 } else {
0561 mask = AR5K_EEPROM_FREQ_M(ah->ah_ee_version);
0562
0563 AR5K_EEPROM_READ(offset++, val);
0564 pcal[0].freq = (val >> 9) & mask;
0565 pcal[1].freq = (val >> 2) & mask;
0566 pcal[2].freq = (val << 5) & mask;
0567
0568 AR5K_EEPROM_READ(offset++, val);
0569 pcal[2].freq |= (val >> 11) & 0x1f;
0570 pcal[3].freq = (val >> 4) & mask;
0571 pcal[4].freq = (val << 3) & mask;
0572
0573 AR5K_EEPROM_READ(offset++, val);
0574 pcal[4].freq |= (val >> 13) & 0x7;
0575 pcal[5].freq = (val >> 6) & mask;
0576 pcal[6].freq = (val << 1) & mask;
0577
0578 AR5K_EEPROM_READ(offset++, val);
0579 pcal[6].freq |= (val >> 15) & 0x1;
0580 pcal[7].freq = (val >> 8) & mask;
0581 pcal[8].freq = (val >> 1) & mask;
0582 pcal[9].freq = (val << 6) & mask;
0583
0584 AR5K_EEPROM_READ(offset++, val);
0585 pcal[9].freq |= (val >> 10) & 0x3f;
0586
0587
0588 ee->ee_n_piers[AR5K_EEPROM_MODE_11A] = 10;
0589
0590 for (i = 0; i < AR5K_EEPROM_N_5GHZ_CHAN; i++) {
0591 pcal[i].freq = ath5k_eeprom_bin2freq(ee,
0592 pcal[i].freq, AR5K_EEPROM_MODE_11A);
0593 }
0594 }
0595
0596 return 0;
0597 }
0598
0599
0600 static inline int
0601 ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset)
0602 {
0603 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
0604 struct ath5k_chan_pcal_info *pcal;
0605
0606 switch (mode) {
0607 case AR5K_EEPROM_MODE_11B:
0608 pcal = ee->ee_pwr_cal_b;
0609 break;
0610 case AR5K_EEPROM_MODE_11G:
0611 pcal = ee->ee_pwr_cal_g;
0612 break;
0613 default:
0614 return -EINVAL;
0615 }
0616
0617 ath5k_eeprom_read_freq_list(ah, &offset,
0618 AR5K_EEPROM_N_2GHZ_CHAN_2413, pcal,
0619 mode);
0620
0621 return 0;
0622 }
0623
0624
0625
0626
0627
0628
0629
0630
0631
0632
0633
0634
0635
0636
0637
0638
0639
0640
0641
0642
0643
0644
0645 static inline void
0646 ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp)
0647 {
0648 static const u16 intercepts3[] = {
0649 0, 5, 10, 20, 30, 50, 70, 85, 90, 95, 100
0650 };
0651 static const u16 intercepts3_2[] = {
0652 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100
0653 };
0654 const u16 *ip;
0655 int i;
0656
0657 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_2)
0658 ip = intercepts3_2;
0659 else
0660 ip = intercepts3;
0661
0662 for (i = 0; i < ARRAY_SIZE(intercepts3); i++)
0663 vp[i] = (ip[i] * max + (100 - ip[i]) * min) / 100;
0664 }
0665
0666 static int
0667 ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode)
0668 {
0669 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
0670 struct ath5k_chan_pcal_info *chinfo;
0671 u8 pier, pdg;
0672
0673 switch (mode) {
0674 case AR5K_EEPROM_MODE_11A:
0675 if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
0676 return 0;
0677 chinfo = ee->ee_pwr_cal_a;
0678 break;
0679 case AR5K_EEPROM_MODE_11B:
0680 if (!AR5K_EEPROM_HDR_11B(ee->ee_header))
0681 return 0;
0682 chinfo = ee->ee_pwr_cal_b;
0683 break;
0684 case AR5K_EEPROM_MODE_11G:
0685 if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
0686 return 0;
0687 chinfo = ee->ee_pwr_cal_g;
0688 break;
0689 default:
0690 return -EINVAL;
0691 }
0692
0693 for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
0694 if (!chinfo[pier].pd_curves)
0695 continue;
0696
0697 for (pdg = 0; pdg < AR5K_EEPROM_N_PD_CURVES; pdg++) {
0698 struct ath5k_pdgain_info *pd =
0699 &chinfo[pier].pd_curves[pdg];
0700
0701 kfree(pd->pd_step);
0702 kfree(pd->pd_pwr);
0703 }
0704
0705 kfree(chinfo[pier].pd_curves);
0706 }
0707
0708 return 0;
0709 }
0710
0711
0712
0713 static int
0714 ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode,
0715 struct ath5k_chan_pcal_info *chinfo)
0716 {
0717 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
0718 struct ath5k_chan_pcal_info_rf5111 *pcinfo;
0719 struct ath5k_pdgain_info *pd;
0720 u8 pier, point, idx;
0721 u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
0722
0723
0724 for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
0725
0726 pcinfo = &chinfo[pier].rf5111_info;
0727
0728
0729 chinfo[pier].pd_curves =
0730 kcalloc(AR5K_EEPROM_N_PD_CURVES,
0731 sizeof(struct ath5k_pdgain_info),
0732 GFP_KERNEL);
0733
0734 if (!chinfo[pier].pd_curves)
0735 goto err_out;
0736
0737
0738
0739
0740
0741 for (idx = 0; idx < AR5K_EEPROM_N_PD_CURVES; idx++) {
0742
0743 if (!((ee->ee_x_gain[mode] >> idx) & 0x1)) {
0744 pdgain_idx[0] = idx;
0745 break;
0746 }
0747 }
0748
0749 if (idx == AR5K_EEPROM_N_PD_CURVES)
0750 goto err_out;
0751
0752 ee->ee_pd_gains[mode] = 1;
0753
0754 pd = &chinfo[pier].pd_curves[idx];
0755
0756 pd->pd_points = AR5K_EEPROM_N_PWR_POINTS_5111;
0757
0758
0759 pd->pd_step = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111,
0760 sizeof(u8), GFP_KERNEL);
0761 if (!pd->pd_step)
0762 goto err_out;
0763
0764 pd->pd_pwr = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111,
0765 sizeof(s16), GFP_KERNEL);
0766 if (!pd->pd_pwr)
0767 goto err_out;
0768
0769
0770
0771
0772 for (point = 0; point < pd->pd_points; point++) {
0773
0774
0775 pd->pd_pwr[point] = 2 * pcinfo->pwr[point];
0776
0777
0778 pd->pd_step[point] = pcinfo->pcdac[point];
0779 }
0780
0781
0782 chinfo[pier].min_pwr = pd->pd_pwr[0];
0783 chinfo[pier].max_pwr = pd->pd_pwr[10];
0784
0785 }
0786
0787 return 0;
0788
0789 err_out:
0790 ath5k_eeprom_free_pcal_info(ah, mode);
0791 return -ENOMEM;
0792 }
0793
0794
0795 static int
0796 ath5k_eeprom_read_pcal_info_5111(struct ath5k_hw *ah, int mode)
0797 {
0798 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
0799 struct ath5k_chan_pcal_info *pcal;
0800 int offset, ret;
0801 int i;
0802 u16 val;
0803
0804 offset = AR5K_EEPROM_GROUPS_START(ee->ee_version);
0805 switch (mode) {
0806 case AR5K_EEPROM_MODE_11A:
0807 if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
0808 return 0;
0809
0810 ret = ath5k_eeprom_init_11a_pcal_freq(ah,
0811 offset + AR5K_EEPROM_GROUP1_OFFSET);
0812 if (ret < 0)
0813 return ret;
0814
0815 offset += AR5K_EEPROM_GROUP2_OFFSET;
0816 pcal = ee->ee_pwr_cal_a;
0817 break;
0818 case AR5K_EEPROM_MODE_11B:
0819 if (!AR5K_EEPROM_HDR_11B(ee->ee_header) &&
0820 !AR5K_EEPROM_HDR_11G(ee->ee_header))
0821 return 0;
0822
0823 pcal = ee->ee_pwr_cal_b;
0824 offset += AR5K_EEPROM_GROUP3_OFFSET;
0825
0826
0827 pcal[0].freq = 2412;
0828 pcal[1].freq = 2447;
0829 pcal[2].freq = 2484;
0830 ee->ee_n_piers[mode] = 3;
0831 break;
0832 case AR5K_EEPROM_MODE_11G:
0833 if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
0834 return 0;
0835
0836 pcal = ee->ee_pwr_cal_g;
0837 offset += AR5K_EEPROM_GROUP4_OFFSET;
0838
0839
0840 pcal[0].freq = 2312;
0841 pcal[1].freq = 2412;
0842 pcal[2].freq = 2484;
0843 ee->ee_n_piers[mode] = 3;
0844 break;
0845 default:
0846 return -EINVAL;
0847 }
0848
0849 for (i = 0; i < ee->ee_n_piers[mode]; i++) {
0850 struct ath5k_chan_pcal_info_rf5111 *cdata =
0851 &pcal[i].rf5111_info;
0852
0853 AR5K_EEPROM_READ(offset++, val);
0854 cdata->pcdac_max = ((val >> 10) & AR5K_EEPROM_PCDAC_M);
0855 cdata->pcdac_min = ((val >> 4) & AR5K_EEPROM_PCDAC_M);
0856 cdata->pwr[0] = ((val << 2) & AR5K_EEPROM_POWER_M);
0857
0858 AR5K_EEPROM_READ(offset++, val);
0859 cdata->pwr[0] |= ((val >> 14) & 0x3);
0860 cdata->pwr[1] = ((val >> 8) & AR5K_EEPROM_POWER_M);
0861 cdata->pwr[2] = ((val >> 2) & AR5K_EEPROM_POWER_M);
0862 cdata->pwr[3] = ((val << 4) & AR5K_EEPROM_POWER_M);
0863
0864 AR5K_EEPROM_READ(offset++, val);
0865 cdata->pwr[3] |= ((val >> 12) & 0xf);
0866 cdata->pwr[4] = ((val >> 6) & AR5K_EEPROM_POWER_M);
0867 cdata->pwr[5] = (val & AR5K_EEPROM_POWER_M);
0868
0869 AR5K_EEPROM_READ(offset++, val);
0870 cdata->pwr[6] = ((val >> 10) & AR5K_EEPROM_POWER_M);
0871 cdata->pwr[7] = ((val >> 4) & AR5K_EEPROM_POWER_M);
0872 cdata->pwr[8] = ((val << 2) & AR5K_EEPROM_POWER_M);
0873
0874 AR5K_EEPROM_READ(offset++, val);
0875 cdata->pwr[8] |= ((val >> 14) & 0x3);
0876 cdata->pwr[9] = ((val >> 8) & AR5K_EEPROM_POWER_M);
0877 cdata->pwr[10] = ((val >> 2) & AR5K_EEPROM_POWER_M);
0878
0879 ath5k_get_pcdac_intercepts(ah, cdata->pcdac_min,
0880 cdata->pcdac_max, cdata->pcdac);
0881 }
0882
0883 return ath5k_eeprom_convert_pcal_info_5111(ah, mode, pcal);
0884 }
0885
0886
0887
0888
0889
0890
0891
0892
0893
0894
0895
0896
0897
0898
0899
0900
0901
0902
0903
0904 static int
0905 ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode,
0906 struct ath5k_chan_pcal_info *chinfo)
0907 {
0908 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
0909 struct ath5k_chan_pcal_info_rf5112 *pcinfo;
0910 u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
0911 unsigned int pier, pdg, point;
0912
0913
0914 for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
0915
0916 pcinfo = &chinfo[pier].rf5112_info;
0917
0918
0919 chinfo[pier].pd_curves =
0920 kcalloc(AR5K_EEPROM_N_PD_CURVES,
0921 sizeof(struct ath5k_pdgain_info),
0922 GFP_KERNEL);
0923
0924 if (!chinfo[pier].pd_curves)
0925 goto err_out;
0926
0927
0928 for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
0929
0930 u8 idx = pdgain_idx[pdg];
0931 struct ath5k_pdgain_info *pd =
0932 &chinfo[pier].pd_curves[idx];
0933
0934
0935 if (pdg == 0) {
0936
0937 pd->pd_points = AR5K_EEPROM_N_XPD0_POINTS;
0938
0939
0940 pd->pd_step = kcalloc(pd->pd_points,
0941 sizeof(u8), GFP_KERNEL);
0942
0943 if (!pd->pd_step)
0944 goto err_out;
0945
0946 pd->pd_pwr = kcalloc(pd->pd_points,
0947 sizeof(s16), GFP_KERNEL);
0948
0949 if (!pd->pd_pwr)
0950 goto err_out;
0951
0952
0953
0954 pd->pd_step[0] = pcinfo->pcdac_x0[0];
0955 pd->pd_pwr[0] = pcinfo->pwr_x0[0];
0956
0957 for (point = 1; point < pd->pd_points;
0958 point++) {
0959
0960 pd->pd_pwr[point] =
0961 pcinfo->pwr_x0[point];
0962
0963
0964 pd->pd_step[point] =
0965 pd->pd_step[point - 1] +
0966 pcinfo->pcdac_x0[point];
0967 }
0968
0969
0970 chinfo[pier].min_pwr = pd->pd_pwr[0];
0971
0972
0973 } else if (pdg == 1) {
0974
0975 pd->pd_points = AR5K_EEPROM_N_XPD3_POINTS;
0976
0977
0978 pd->pd_step = kcalloc(pd->pd_points,
0979 sizeof(u8), GFP_KERNEL);
0980
0981 if (!pd->pd_step)
0982 goto err_out;
0983
0984 pd->pd_pwr = kcalloc(pd->pd_points,
0985 sizeof(s16), GFP_KERNEL);
0986
0987 if (!pd->pd_pwr)
0988 goto err_out;
0989
0990
0991
0992 for (point = 0; point < pd->pd_points;
0993 point++) {
0994
0995 pd->pd_pwr[point] =
0996 pcinfo->pwr_x3[point];
0997
0998
0999 pd->pd_step[point] =
1000 pcinfo->pcdac_x3[point];
1001 }
1002
1003
1004
1005 chinfo[pier].min_pwr = pd->pd_pwr[0];
1006 }
1007 }
1008 }
1009
1010 return 0;
1011
1012 err_out:
1013 ath5k_eeprom_free_pcal_info(ah, mode);
1014 return -ENOMEM;
1015 }
1016
1017
1018 static int
1019 ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw *ah, int mode)
1020 {
1021 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1022 struct ath5k_chan_pcal_info_rf5112 *chan_pcal_info;
1023 struct ath5k_chan_pcal_info *gen_chan_info;
1024 u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
1025 u32 offset;
1026 u8 i, c;
1027 u16 val;
1028 u8 pd_gains = 0;
1029
1030
1031
1032
1033
1034
1035 for (i = 0; i < AR5K_EEPROM_N_PD_CURVES; i++) {
1036
1037 if ((ee->ee_x_gain[mode] >> i) & 0x1)
1038 pdgain_idx[pd_gains++] = i;
1039 }
1040 ee->ee_pd_gains[mode] = pd_gains;
1041
1042 if (pd_gains == 0 || pd_gains > 2)
1043 return -EINVAL;
1044
1045 switch (mode) {
1046 case AR5K_EEPROM_MODE_11A:
1047
1048
1049
1050 offset = AR5K_EEPROM_GROUPS_START(ee->ee_version);
1051 ath5k_eeprom_init_11a_pcal_freq(ah, offset);
1052
1053 offset += AR5K_EEPROM_GROUP2_OFFSET;
1054 gen_chan_info = ee->ee_pwr_cal_a;
1055 break;
1056 case AR5K_EEPROM_MODE_11B:
1057 offset = AR5K_EEPROM_GROUPS_START(ee->ee_version);
1058 if (AR5K_EEPROM_HDR_11A(ee->ee_header))
1059 offset += AR5K_EEPROM_GROUP3_OFFSET;
1060
1061
1062 gen_chan_info = ee->ee_pwr_cal_b;
1063 break;
1064 case AR5K_EEPROM_MODE_11G:
1065 offset = AR5K_EEPROM_GROUPS_START(ee->ee_version);
1066 if (AR5K_EEPROM_HDR_11A(ee->ee_header))
1067 offset += AR5K_EEPROM_GROUP4_OFFSET;
1068 else if (AR5K_EEPROM_HDR_11B(ee->ee_header))
1069 offset += AR5K_EEPROM_GROUP2_OFFSET;
1070
1071
1072 gen_chan_info = ee->ee_pwr_cal_g;
1073 break;
1074 default:
1075 return -EINVAL;
1076 }
1077
1078 for (i = 0; i < ee->ee_n_piers[mode]; i++) {
1079 chan_pcal_info = &gen_chan_info[i].rf5112_info;
1080
1081
1082
1083
1084 for (c = 0; c < AR5K_EEPROM_N_XPD0_POINTS; c++) {
1085 AR5K_EEPROM_READ(offset++, val);
1086 chan_pcal_info->pwr_x0[c] = (s8) (val & 0xff);
1087 chan_pcal_info->pwr_x0[++c] = (s8) ((val >> 8) & 0xff);
1088 }
1089
1090
1091
1092
1093 AR5K_EEPROM_READ(offset++, val);
1094 chan_pcal_info->pcdac_x0[1] = (val & 0x1f);
1095 chan_pcal_info->pcdac_x0[2] = ((val >> 5) & 0x1f);
1096 chan_pcal_info->pcdac_x0[3] = ((val >> 10) & 0x1f);
1097
1098
1099
1100
1101 AR5K_EEPROM_READ(offset++, val);
1102 chan_pcal_info->pwr_x3[0] = (s8) (val & 0xff);
1103 chan_pcal_info->pwr_x3[1] = (s8) ((val >> 8) & 0xff);
1104
1105 AR5K_EEPROM_READ(offset++, val);
1106 chan_pcal_info->pwr_x3[2] = (val & 0xff);
1107
1108
1109
1110
1111 chan_pcal_info->pcdac_x3[0] = 20;
1112 chan_pcal_info->pcdac_x3[1] = 35;
1113 chan_pcal_info->pcdac_x3[2] = 63;
1114
1115 if (ee->ee_version >= AR5K_EEPROM_VERSION_4_3) {
1116 chan_pcal_info->pcdac_x0[0] = ((val >> 8) & 0x3f);
1117
1118
1119 gen_chan_info[i].max_pwr = chan_pcal_info->pwr_x0[3];
1120 } else {
1121 chan_pcal_info->pcdac_x0[0] = 1;
1122 gen_chan_info[i].max_pwr = (s8) ((val >> 8) & 0xff);
1123 }
1124
1125 }
1126
1127 return ath5k_eeprom_convert_pcal_info_5112(ah, mode, gen_chan_info);
1128 }
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153 static inline unsigned int
1154 ath5k_pdgains_size_2413(struct ath5k_eeprom_info *ee, unsigned int mode)
1155 {
1156 static const unsigned int pdgains_size[] = { 4, 6, 9, 12 };
1157 unsigned int sz;
1158
1159 sz = pdgains_size[ee->ee_pd_gains[mode] - 1];
1160 sz *= ee->ee_n_piers[mode];
1161
1162 return sz;
1163 }
1164
1165
1166
1167 static unsigned int
1168 ath5k_cal_data_offset_2413(struct ath5k_eeprom_info *ee, int mode)
1169 {
1170 u32 offset = AR5K_EEPROM_CAL_DATA_START(ee->ee_misc4);
1171
1172 switch (mode) {
1173 case AR5K_EEPROM_MODE_11G:
1174 if (AR5K_EEPROM_HDR_11B(ee->ee_header))
1175 offset += ath5k_pdgains_size_2413(ee,
1176 AR5K_EEPROM_MODE_11B) +
1177 AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2;
1178 fallthrough;
1179 case AR5K_EEPROM_MODE_11B:
1180 if (AR5K_EEPROM_HDR_11A(ee->ee_header))
1181 offset += ath5k_pdgains_size_2413(ee,
1182 AR5K_EEPROM_MODE_11A) +
1183 AR5K_EEPROM_N_5GHZ_CHAN / 2;
1184 fallthrough;
1185 case AR5K_EEPROM_MODE_11A:
1186 break;
1187 default:
1188 break;
1189 }
1190
1191 return offset;
1192 }
1193
1194
1195
1196 static int
1197 ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode,
1198 struct ath5k_chan_pcal_info *chinfo)
1199 {
1200 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1201 struct ath5k_chan_pcal_info_rf2413 *pcinfo;
1202 u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
1203 unsigned int pier, pdg, point;
1204
1205
1206 for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
1207
1208 pcinfo = &chinfo[pier].rf2413_info;
1209
1210
1211 chinfo[pier].pd_curves =
1212 kcalloc(AR5K_EEPROM_N_PD_CURVES,
1213 sizeof(struct ath5k_pdgain_info),
1214 GFP_KERNEL);
1215
1216 if (!chinfo[pier].pd_curves)
1217 goto err_out;
1218
1219
1220 for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
1221
1222 u8 idx = pdgain_idx[pdg];
1223 struct ath5k_pdgain_info *pd =
1224 &chinfo[pier].pd_curves[idx];
1225
1226
1227
1228 if (pdg == ee->ee_pd_gains[mode] - 1)
1229 pd->pd_points = AR5K_EEPROM_N_PD_POINTS;
1230 else
1231 pd->pd_points = AR5K_EEPROM_N_PD_POINTS - 1;
1232
1233
1234 pd->pd_step = kcalloc(pd->pd_points,
1235 sizeof(u8), GFP_KERNEL);
1236
1237 if (!pd->pd_step)
1238 goto err_out;
1239
1240 pd->pd_pwr = kcalloc(pd->pd_points,
1241 sizeof(s16), GFP_KERNEL);
1242
1243 if (!pd->pd_pwr)
1244 goto err_out;
1245
1246
1247
1248
1249 pd->pd_step[0] = pcinfo->pddac_i[pdg];
1250 pd->pd_pwr[0] = 4 * pcinfo->pwr_i[pdg];
1251
1252 for (point = 1; point < pd->pd_points; point++) {
1253
1254 pd->pd_pwr[point] = pd->pd_pwr[point - 1] +
1255 2 * pcinfo->pwr[pdg][point - 1];
1256
1257 pd->pd_step[point] = pd->pd_step[point - 1] +
1258 pcinfo->pddac[pdg][point - 1];
1259
1260 }
1261
1262
1263 if (pdg == 0)
1264 chinfo[pier].min_pwr = pd->pd_pwr[0];
1265
1266
1267 if (pdg == ee->ee_pd_gains[mode] - 1)
1268 chinfo[pier].max_pwr =
1269 pd->pd_pwr[pd->pd_points - 1];
1270 }
1271 }
1272
1273 return 0;
1274
1275 err_out:
1276 ath5k_eeprom_free_pcal_info(ah, mode);
1277 return -ENOMEM;
1278 }
1279
1280
1281 static int
1282 ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode)
1283 {
1284 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1285 struct ath5k_chan_pcal_info_rf2413 *pcinfo;
1286 struct ath5k_chan_pcal_info *chinfo;
1287 u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
1288 u32 offset;
1289 int idx, i;
1290 u16 val;
1291 u8 pd_gains = 0;
1292
1293
1294
1295
1296
1297
1298 for (idx = AR5K_EEPROM_N_PD_CURVES - 1; idx >= 0; idx--) {
1299
1300 if ((ee->ee_x_gain[mode] >> idx) & 0x1)
1301 pdgain_idx[pd_gains++] = idx;
1302
1303 }
1304 ee->ee_pd_gains[mode] = pd_gains;
1305
1306 if (pd_gains == 0)
1307 return -EINVAL;
1308
1309 offset = ath5k_cal_data_offset_2413(ee, mode);
1310 switch (mode) {
1311 case AR5K_EEPROM_MODE_11A:
1312 if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
1313 return 0;
1314
1315 ath5k_eeprom_init_11a_pcal_freq(ah, offset);
1316 offset += AR5K_EEPROM_N_5GHZ_CHAN / 2;
1317 chinfo = ee->ee_pwr_cal_a;
1318 break;
1319 case AR5K_EEPROM_MODE_11B:
1320 if (!AR5K_EEPROM_HDR_11B(ee->ee_header))
1321 return 0;
1322
1323 ath5k_eeprom_init_11bg_2413(ah, mode, offset);
1324 offset += AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2;
1325 chinfo = ee->ee_pwr_cal_b;
1326 break;
1327 case AR5K_EEPROM_MODE_11G:
1328 if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
1329 return 0;
1330
1331 ath5k_eeprom_init_11bg_2413(ah, mode, offset);
1332 offset += AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2;
1333 chinfo = ee->ee_pwr_cal_g;
1334 break;
1335 default:
1336 return -EINVAL;
1337 }
1338
1339 for (i = 0; i < ee->ee_n_piers[mode]; i++) {
1340 pcinfo = &chinfo[i].rf2413_info;
1341
1342
1343
1344
1345
1346 AR5K_EEPROM_READ(offset++, val);
1347 pcinfo->pwr_i[0] = val & 0x1f;
1348 pcinfo->pddac_i[0] = (val >> 5) & 0x7f;
1349 pcinfo->pwr[0][0] = (val >> 12) & 0xf;
1350
1351 AR5K_EEPROM_READ(offset++, val);
1352 pcinfo->pddac[0][0] = val & 0x3f;
1353 pcinfo->pwr[0][1] = (val >> 6) & 0xf;
1354 pcinfo->pddac[0][1] = (val >> 10) & 0x3f;
1355
1356 AR5K_EEPROM_READ(offset++, val);
1357 pcinfo->pwr[0][2] = val & 0xf;
1358 pcinfo->pddac[0][2] = (val >> 4) & 0x3f;
1359
1360 pcinfo->pwr[0][3] = 0;
1361 pcinfo->pddac[0][3] = 0;
1362
1363 if (pd_gains > 1) {
1364
1365
1366
1367
1368
1369 pcinfo->pwr_i[1] = (val >> 10) & 0x1f;
1370
1371 pcinfo->pddac_i[1] = (val >> 15) & 0x1;
1372 AR5K_EEPROM_READ(offset++, val);
1373 pcinfo->pddac_i[1] |= (val & 0x3F) << 1;
1374
1375 pcinfo->pwr[1][0] = (val >> 6) & 0xf;
1376 pcinfo->pddac[1][0] = (val >> 10) & 0x3f;
1377
1378 AR5K_EEPROM_READ(offset++, val);
1379 pcinfo->pwr[1][1] = val & 0xf;
1380 pcinfo->pddac[1][1] = (val >> 4) & 0x3f;
1381 pcinfo->pwr[1][2] = (val >> 10) & 0xf;
1382
1383 pcinfo->pddac[1][2] = (val >> 14) & 0x3;
1384 AR5K_EEPROM_READ(offset++, val);
1385 pcinfo->pddac[1][2] |= (val & 0xF) << 2;
1386
1387 pcinfo->pwr[1][3] = 0;
1388 pcinfo->pddac[1][3] = 0;
1389 } else if (pd_gains == 1) {
1390
1391
1392
1393
1394 pcinfo->pwr[0][3] = (val >> 10) & 0xf;
1395
1396 pcinfo->pddac[0][3] = (val >> 14) & 0x3;
1397 AR5K_EEPROM_READ(offset++, val);
1398 pcinfo->pddac[0][3] |= (val & 0xF) << 2;
1399 }
1400
1401
1402
1403
1404
1405 if (pd_gains > 2) {
1406 pcinfo->pwr_i[2] = (val >> 4) & 0x1f;
1407 pcinfo->pddac_i[2] = (val >> 9) & 0x7f;
1408
1409 AR5K_EEPROM_READ(offset++, val);
1410 pcinfo->pwr[2][0] = (val >> 0) & 0xf;
1411 pcinfo->pddac[2][0] = (val >> 4) & 0x3f;
1412 pcinfo->pwr[2][1] = (val >> 10) & 0xf;
1413
1414 pcinfo->pddac[2][1] = (val >> 14) & 0x3;
1415 AR5K_EEPROM_READ(offset++, val);
1416 pcinfo->pddac[2][1] |= (val & 0xF) << 2;
1417
1418 pcinfo->pwr[2][2] = (val >> 4) & 0xf;
1419 pcinfo->pddac[2][2] = (val >> 8) & 0x3f;
1420
1421 pcinfo->pwr[2][3] = 0;
1422 pcinfo->pddac[2][3] = 0;
1423 } else if (pd_gains == 2) {
1424 pcinfo->pwr[1][3] = (val >> 4) & 0xf;
1425 pcinfo->pddac[1][3] = (val >> 8) & 0x3f;
1426 }
1427
1428 if (pd_gains > 3) {
1429 pcinfo->pwr_i[3] = (val >> 14) & 0x3;
1430 AR5K_EEPROM_READ(offset++, val);
1431 pcinfo->pwr_i[3] |= ((val >> 0) & 0x7) << 2;
1432
1433 pcinfo->pddac_i[3] = (val >> 3) & 0x7f;
1434 pcinfo->pwr[3][0] = (val >> 10) & 0xf;
1435 pcinfo->pddac[3][0] = (val >> 14) & 0x3;
1436
1437 AR5K_EEPROM_READ(offset++, val);
1438 pcinfo->pddac[3][0] |= (val & 0xF) << 2;
1439 pcinfo->pwr[3][1] = (val >> 4) & 0xf;
1440 pcinfo->pddac[3][1] = (val >> 8) & 0x3f;
1441
1442 pcinfo->pwr[3][2] = (val >> 14) & 0x3;
1443 AR5K_EEPROM_READ(offset++, val);
1444 pcinfo->pwr[3][2] |= ((val >> 0) & 0x3) << 2;
1445
1446 pcinfo->pddac[3][2] = (val >> 2) & 0x3f;
1447 pcinfo->pwr[3][3] = (val >> 8) & 0xf;
1448
1449 pcinfo->pddac[3][3] = (val >> 12) & 0xF;
1450 AR5K_EEPROM_READ(offset++, val);
1451 pcinfo->pddac[3][3] |= ((val >> 0) & 0x3) << 4;
1452 } else if (pd_gains == 3) {
1453 pcinfo->pwr[2][3] = (val >> 14) & 0x3;
1454 AR5K_EEPROM_READ(offset++, val);
1455 pcinfo->pwr[2][3] |= ((val >> 0) & 0x3) << 2;
1456
1457 pcinfo->pddac[2][3] = (val >> 2) & 0x3f;
1458 }
1459 }
1460
1461 return ath5k_eeprom_convert_pcal_info_2413(ah, mode, chinfo);
1462 }
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472 static int
1473 ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned int mode)
1474 {
1475 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1476 struct ath5k_rate_pcal_info *rate_pcal_info;
1477 u8 *rate_target_pwr_num;
1478 u32 offset;
1479 u16 val;
1480 int i;
1481
1482 offset = AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1);
1483 rate_target_pwr_num = &ee->ee_rate_target_pwr_num[mode];
1484 switch (mode) {
1485 case AR5K_EEPROM_MODE_11A:
1486 offset += AR5K_EEPROM_TARGET_PWR_OFF_11A(ee->ee_version);
1487 rate_pcal_info = ee->ee_rate_tpwr_a;
1488 ee->ee_rate_target_pwr_num[mode] = AR5K_EEPROM_N_5GHZ_RATE_CHAN;
1489 break;
1490 case AR5K_EEPROM_MODE_11B:
1491 offset += AR5K_EEPROM_TARGET_PWR_OFF_11B(ee->ee_version);
1492 rate_pcal_info = ee->ee_rate_tpwr_b;
1493 ee->ee_rate_target_pwr_num[mode] = 2;
1494 break;
1495 case AR5K_EEPROM_MODE_11G:
1496 offset += AR5K_EEPROM_TARGET_PWR_OFF_11G(ee->ee_version);
1497 rate_pcal_info = ee->ee_rate_tpwr_g;
1498 ee->ee_rate_target_pwr_num[mode] = AR5K_EEPROM_N_2GHZ_CHAN;
1499 break;
1500 default:
1501 return -EINVAL;
1502 }
1503
1504
1505 if (ee->ee_version <= AR5K_EEPROM_VERSION_3_2) {
1506 for (i = 0; i < (*rate_target_pwr_num); i++) {
1507 AR5K_EEPROM_READ(offset++, val);
1508 rate_pcal_info[i].freq =
1509 ath5k_eeprom_bin2freq(ee, (val >> 9) & 0x7f, mode);
1510
1511 rate_pcal_info[i].target_power_6to24 = ((val >> 3) & 0x3f);
1512 rate_pcal_info[i].target_power_36 = (val << 3) & 0x3f;
1513
1514 AR5K_EEPROM_READ(offset++, val);
1515
1516 if (rate_pcal_info[i].freq == AR5K_EEPROM_CHANNEL_DIS ||
1517 val == 0) {
1518 (*rate_target_pwr_num) = i;
1519 break;
1520 }
1521
1522 rate_pcal_info[i].target_power_36 |= ((val >> 13) & 0x7);
1523 rate_pcal_info[i].target_power_48 = ((val >> 7) & 0x3f);
1524 rate_pcal_info[i].target_power_54 = ((val >> 1) & 0x3f);
1525 }
1526 } else {
1527 for (i = 0; i < (*rate_target_pwr_num); i++) {
1528 AR5K_EEPROM_READ(offset++, val);
1529 rate_pcal_info[i].freq =
1530 ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode);
1531
1532 rate_pcal_info[i].target_power_6to24 = ((val >> 2) & 0x3f);
1533 rate_pcal_info[i].target_power_36 = (val << 4) & 0x3f;
1534
1535 AR5K_EEPROM_READ(offset++, val);
1536
1537 if (rate_pcal_info[i].freq == AR5K_EEPROM_CHANNEL_DIS ||
1538 val == 0) {
1539 (*rate_target_pwr_num) = i;
1540 break;
1541 }
1542
1543 rate_pcal_info[i].target_power_36 |= (val >> 12) & 0xf;
1544 rate_pcal_info[i].target_power_48 = ((val >> 6) & 0x3f);
1545 rate_pcal_info[i].target_power_54 = (val & 0x3f);
1546 }
1547 }
1548
1549 return 0;
1550 }
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567 static int
1568 ath5k_eeprom_read_pcal_info(struct ath5k_hw *ah)
1569 {
1570 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1571 int (*read_pcal)(struct ath5k_hw *hw, int mode);
1572 int mode;
1573 int err;
1574
1575 if ((ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) &&
1576 (AR5K_EEPROM_EEMAP(ee->ee_misc0) == 1))
1577 read_pcal = ath5k_eeprom_read_pcal_info_5112;
1578 else if ((ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_0) &&
1579 (AR5K_EEPROM_EEMAP(ee->ee_misc0) == 2))
1580 read_pcal = ath5k_eeprom_read_pcal_info_2413;
1581 else
1582 read_pcal = ath5k_eeprom_read_pcal_info_5111;
1583
1584
1585 for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G;
1586 mode++) {
1587 err = read_pcal(ah, mode);
1588 if (err)
1589 return err;
1590
1591 err = ath5k_eeprom_read_target_rate_pwr_info(ah, mode);
1592 if (err < 0)
1593 return err;
1594 }
1595
1596 return 0;
1597 }
1598
1599
1600 static int
1601 ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah)
1602 {
1603 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1604 struct ath5k_edge_power *rep;
1605 unsigned int fmask, pmask;
1606 unsigned int ctl_mode;
1607 int i, j;
1608 u32 offset;
1609 u16 val;
1610
1611 pmask = AR5K_EEPROM_POWER_M;
1612 fmask = AR5K_EEPROM_FREQ_M(ee->ee_version);
1613 offset = AR5K_EEPROM_CTL(ee->ee_version);
1614 ee->ee_ctls = AR5K_EEPROM_N_CTLS(ee->ee_version);
1615 for (i = 0; i < ee->ee_ctls; i += 2) {
1616 AR5K_EEPROM_READ(offset++, val);
1617 ee->ee_ctl[i] = (val >> 8) & 0xff;
1618 ee->ee_ctl[i + 1] = val & 0xff;
1619 }
1620
1621 offset = AR5K_EEPROM_GROUP8_OFFSET;
1622 if (ee->ee_version >= AR5K_EEPROM_VERSION_4_0)
1623 offset += AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1) -
1624 AR5K_EEPROM_GROUP5_OFFSET;
1625 else
1626 offset += AR5K_EEPROM_GROUPS_START(ee->ee_version);
1627
1628 rep = ee->ee_ctl_pwr;
1629 for (i = 0; i < ee->ee_ctls; i++) {
1630 switch (ee->ee_ctl[i] & AR5K_CTL_MODE_M) {
1631 case AR5K_CTL_11A:
1632 case AR5K_CTL_TURBO:
1633 ctl_mode = AR5K_EEPROM_MODE_11A;
1634 break;
1635 default:
1636 ctl_mode = AR5K_EEPROM_MODE_11G;
1637 break;
1638 }
1639 if (ee->ee_ctl[i] == 0) {
1640 if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3)
1641 offset += 8;
1642 else
1643 offset += 7;
1644 rep += AR5K_EEPROM_N_EDGES;
1645 continue;
1646 }
1647 if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3) {
1648 for (j = 0; j < AR5K_EEPROM_N_EDGES; j += 2) {
1649 AR5K_EEPROM_READ(offset++, val);
1650 rep[j].freq = (val >> 8) & fmask;
1651 rep[j + 1].freq = val & fmask;
1652 }
1653 for (j = 0; j < AR5K_EEPROM_N_EDGES; j += 2) {
1654 AR5K_EEPROM_READ(offset++, val);
1655 rep[j].edge = (val >> 8) & pmask;
1656 rep[j].flag = (val >> 14) & 1;
1657 rep[j + 1].edge = val & pmask;
1658 rep[j + 1].flag = (val >> 6) & 1;
1659 }
1660 } else {
1661 AR5K_EEPROM_READ(offset++, val);
1662 rep[0].freq = (val >> 9) & fmask;
1663 rep[1].freq = (val >> 2) & fmask;
1664 rep[2].freq = (val << 5) & fmask;
1665
1666 AR5K_EEPROM_READ(offset++, val);
1667 rep[2].freq |= (val >> 11) & 0x1f;
1668 rep[3].freq = (val >> 4) & fmask;
1669 rep[4].freq = (val << 3) & fmask;
1670
1671 AR5K_EEPROM_READ(offset++, val);
1672 rep[4].freq |= (val >> 13) & 0x7;
1673 rep[5].freq = (val >> 6) & fmask;
1674 rep[6].freq = (val << 1) & fmask;
1675
1676 AR5K_EEPROM_READ(offset++, val);
1677 rep[6].freq |= (val >> 15) & 0x1;
1678 rep[7].freq = (val >> 8) & fmask;
1679
1680 rep[0].edge = (val >> 2) & pmask;
1681 rep[1].edge = (val << 4) & pmask;
1682
1683 AR5K_EEPROM_READ(offset++, val);
1684 rep[1].edge |= (val >> 12) & 0xf;
1685 rep[2].edge = (val >> 6) & pmask;
1686 rep[3].edge = val & pmask;
1687
1688 AR5K_EEPROM_READ(offset++, val);
1689 rep[4].edge = (val >> 10) & pmask;
1690 rep[5].edge = (val >> 4) & pmask;
1691 rep[6].edge = (val << 2) & pmask;
1692
1693 AR5K_EEPROM_READ(offset++, val);
1694 rep[6].edge |= (val >> 14) & 0x3;
1695 rep[7].edge = (val >> 8) & pmask;
1696 }
1697 for (j = 0; j < AR5K_EEPROM_N_EDGES; j++) {
1698 rep[j].freq = ath5k_eeprom_bin2freq(ee,
1699 rep[j].freq, ctl_mode);
1700 }
1701 rep += AR5K_EEPROM_N_EDGES;
1702 }
1703
1704 return 0;
1705 }
1706
1707 static int
1708 ath5k_eeprom_read_spur_chans(struct ath5k_hw *ah)
1709 {
1710 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1711 u32 offset;
1712 u16 val;
1713 int i;
1714
1715 offset = AR5K_EEPROM_CTL(ee->ee_version) +
1716 AR5K_EEPROM_N_CTLS(ee->ee_version);
1717
1718 if (ee->ee_version < AR5K_EEPROM_VERSION_5_3) {
1719
1720 ee->ee_spur_chans[0][0] = AR5K_EEPROM_NO_SPUR;
1721
1722 ee->ee_spur_chans[0][1] = AR5K_EEPROM_5413_SPUR_CHAN_1;
1723 ee->ee_spur_chans[1][1] = AR5K_EEPROM_5413_SPUR_CHAN_2;
1724 ee->ee_spur_chans[2][1] = AR5K_EEPROM_NO_SPUR;
1725 } else if (ee->ee_version >= AR5K_EEPROM_VERSION_5_3) {
1726 for (i = 0; i < AR5K_EEPROM_N_SPUR_CHANS; i++) {
1727 AR5K_EEPROM_READ(offset, val);
1728 ee->ee_spur_chans[i][0] = val;
1729 AR5K_EEPROM_READ(offset + AR5K_EEPROM_N_SPUR_CHANS,
1730 val);
1731 ee->ee_spur_chans[i][1] = val;
1732 offset++;
1733 }
1734 }
1735
1736 return 0;
1737 }
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747 int
1748 ath5k_eeprom_init(struct ath5k_hw *ah)
1749 {
1750 int err;
1751
1752 err = ath5k_eeprom_init_header(ah);
1753 if (err < 0)
1754 return err;
1755
1756 err = ath5k_eeprom_init_modes(ah);
1757 if (err < 0)
1758 return err;
1759
1760 err = ath5k_eeprom_read_pcal_info(ah);
1761 if (err < 0)
1762 return err;
1763
1764 err = ath5k_eeprom_read_ctl_info(ah);
1765 if (err < 0)
1766 return err;
1767
1768 err = ath5k_eeprom_read_spur_chans(ah);
1769 if (err < 0)
1770 return err;
1771
1772 return 0;
1773 }
1774
1775 void
1776 ath5k_eeprom_detach(struct ath5k_hw *ah)
1777 {
1778 u8 mode;
1779
1780 for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++)
1781 ath5k_eeprom_free_pcal_info(ah, mode);
1782 }
1783
1784 int
1785 ath5k_eeprom_mode_from_channel(struct ath5k_hw *ah,
1786 struct ieee80211_channel *channel)
1787 {
1788 switch (channel->hw_value) {
1789 case AR5K_MODE_11A:
1790 return AR5K_EEPROM_MODE_11A;
1791 case AR5K_MODE_11G:
1792 return AR5K_EEPROM_MODE_11G;
1793 case AR5K_MODE_11B:
1794 return AR5K_EEPROM_MODE_11B;
1795 default:
1796 ATH5K_WARN(ah, "channel is not A/B/G!");
1797 return AR5K_EEPROM_MODE_11A;
1798 }
1799 }