This source file includes following definitions.
- ath5k_eeprom_bin2freq
- ath5k_eeprom_init_header
- ath5k_eeprom_read_ants
- ath5k_eeprom_read_modes
- ath5k_eeprom_init_modes
- ath5k_eeprom_read_freq_list
- ath5k_eeprom_init_11a_pcal_freq
- ath5k_eeprom_init_11bg_2413
- ath5k_get_pcdac_intercepts
- ath5k_eeprom_free_pcal_info
- ath5k_eeprom_convert_pcal_info_5111
- ath5k_eeprom_read_pcal_info_5111
- ath5k_eeprom_convert_pcal_info_5112
- ath5k_eeprom_read_pcal_info_5112
- ath5k_pdgains_size_2413
- ath5k_cal_data_offset_2413
- ath5k_eeprom_convert_pcal_info_2413
- ath5k_eeprom_read_pcal_info_2413
- ath5k_eeprom_read_target_rate_pwr_info
- ath5k_eeprom_read_pcal_info
- ath5k_eeprom_read_ctl_info
- ath5k_eeprom_read_spur_chans
- ath5k_eeprom_init
- ath5k_eeprom_detach
- ath5k_eeprom_mode_from_channel
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
25
26 #include <linux/slab.h>
27
28 #include "ath5k.h"
29 #include "reg.h"
30 #include "debug.h"
31
32
33
34
35
36
37
38
39
40 static u16 ath5k_eeprom_bin2freq(struct ath5k_eeprom_info *ee, u16 bin,
41 unsigned int mode)
42 {
43 u16 val;
44
45 if (bin == AR5K_EEPROM_CHANNEL_DIS)
46 return bin;
47
48 if (mode == AR5K_EEPROM_MODE_11A) {
49 if (ee->ee_version > AR5K_EEPROM_VERSION_3_2)
50 val = (5 * bin) + 4800;
51 else
52 val = bin > 62 ? (10 * 62) + (5 * (bin - 62)) + 5100 :
53 (bin * 10) + 5100;
54 } else {
55 if (ee->ee_version > AR5K_EEPROM_VERSION_3_2)
56 val = bin + 2300;
57 else
58 val = bin + 2400;
59 }
60
61 return val;
62 }
63
64
65
66
67
68
69
70
71
72 static int
73 ath5k_eeprom_init_header(struct ath5k_hw *ah)
74 {
75 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
76 u16 val;
77 u32 cksum, offset, eep_max = AR5K_EEPROM_INFO_MAX;
78
79
80
81
82 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MAGIC, ee_magic);
83 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_PROTECT, ee_protect);
84 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_REG_DOMAIN, ee_regdomain);
85 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_VERSION, ee_version);
86 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_HDR, ee_header);
87
88
89 if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_0)
90 return 0;
91
92
93
94
95
96 AR5K_EEPROM_READ(AR5K_EEPROM_SIZE_UPPER, val);
97 if (val) {
98 eep_max = (val & AR5K_EEPROM_SIZE_UPPER_MASK) <<
99 AR5K_EEPROM_SIZE_ENDLOC_SHIFT;
100 AR5K_EEPROM_READ(AR5K_EEPROM_SIZE_LOWER, val);
101 eep_max = (eep_max | val) - AR5K_EEPROM_INFO_BASE;
102
103
104
105
106
107
108 if (eep_max > (3 * AR5K_EEPROM_INFO_MAX)) {
109 ATH5K_ERR(ah, "Invalid max custom EEPROM size: "
110 "%d (0x%04x) max expected: %d (0x%04x)\n",
111 eep_max, eep_max,
112 3 * AR5K_EEPROM_INFO_MAX,
113 3 * AR5K_EEPROM_INFO_MAX);
114 return -EIO;
115 }
116 }
117
118 for (cksum = 0, offset = 0; offset < eep_max; offset++) {
119 AR5K_EEPROM_READ(AR5K_EEPROM_INFO(offset), val);
120 cksum ^= val;
121 }
122 if (cksum != AR5K_EEPROM_INFO_CKSUM) {
123 ATH5K_ERR(ah, "Invalid EEPROM "
124 "checksum: 0x%04x eep_max: 0x%04x (%s)\n",
125 cksum, eep_max,
126 eep_max == AR5K_EEPROM_INFO_MAX ?
127 "default size" : "custom size");
128 return -EIO;
129 }
130
131 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_ANT_GAIN(ah->ah_ee_version),
132 ee_ant_gain);
133
134 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
135 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC0, ee_misc0);
136 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC1, ee_misc1);
137
138
139 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC2, ee_misc2);
140
141 if (ee->ee_version >= AR5K_EEPROM_VERSION_4_3)
142 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC3, ee_misc3);
143
144 if (ee->ee_version >= AR5K_EEPROM_VERSION_5_0) {
145 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC4, ee_misc4);
146 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC5, ee_misc5);
147 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC6, ee_misc6);
148 }
149 }
150
151 if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_3) {
152 AR5K_EEPROM_READ(AR5K_EEPROM_OBDB0_2GHZ, val);
153 ee->ee_ob[AR5K_EEPROM_MODE_11B][0] = val & 0x7;
154 ee->ee_db[AR5K_EEPROM_MODE_11B][0] = (val >> 3) & 0x7;
155
156 AR5K_EEPROM_READ(AR5K_EEPROM_OBDB1_2GHZ, val);
157 ee->ee_ob[AR5K_EEPROM_MODE_11G][0] = val & 0x7;
158 ee->ee_db[AR5K_EEPROM_MODE_11G][0] = (val >> 3) & 0x7;
159 }
160
161 AR5K_EEPROM_READ(AR5K_EEPROM_IS_HB63, val);
162
163 if ((ah->ah_mac_version == (AR5K_SREV_AR2425 >> 4)) && val)
164 ee->ee_is_hb63 = true;
165 else
166 ee->ee_is_hb63 = false;
167
168 AR5K_EEPROM_READ(AR5K_EEPROM_RFKILL, val);
169 ee->ee_rfkill_pin = (u8) AR5K_REG_MS(val, AR5K_EEPROM_RFKILL_GPIO_SEL);
170 ee->ee_rfkill_pol = val & AR5K_EEPROM_RFKILL_POLARITY ? true : false;
171
172
173
174
175
176
177
178 AR5K_EEPROM_READ(AR5K_EEPROM_PCIE_OFFSET, val);
179 ee->ee_serdes = (val == AR5K_EEPROM_PCIE_SERDES_SECTION) ?
180 true : false;
181
182 return 0;
183 }
184
185
186
187
188
189 static int ath5k_eeprom_read_ants(struct ath5k_hw *ah, u32 *offset,
190 unsigned int mode)
191 {
192 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
193 u32 o = *offset;
194 u16 val;
195 int i = 0;
196
197 AR5K_EEPROM_READ(o++, val);
198 ee->ee_switch_settling[mode] = (val >> 8) & 0x7f;
199 ee->ee_atn_tx_rx[mode] = (val >> 2) & 0x3f;
200 ee->ee_ant_control[mode][i] = (val << 4) & 0x3f;
201
202 AR5K_EEPROM_READ(o++, val);
203 ee->ee_ant_control[mode][i++] |= (val >> 12) & 0xf;
204 ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f;
205 ee->ee_ant_control[mode][i++] = val & 0x3f;
206
207 AR5K_EEPROM_READ(o++, val);
208 ee->ee_ant_control[mode][i++] = (val >> 10) & 0x3f;
209 ee->ee_ant_control[mode][i++] = (val >> 4) & 0x3f;
210 ee->ee_ant_control[mode][i] = (val << 2) & 0x3f;
211
212 AR5K_EEPROM_READ(o++, val);
213 ee->ee_ant_control[mode][i++] |= (val >> 14) & 0x3;
214 ee->ee_ant_control[mode][i++] = (val >> 8) & 0x3f;
215 ee->ee_ant_control[mode][i++] = (val >> 2) & 0x3f;
216 ee->ee_ant_control[mode][i] = (val << 4) & 0x3f;
217
218 AR5K_EEPROM_READ(o++, val);
219 ee->ee_ant_control[mode][i++] |= (val >> 12) & 0xf;
220 ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f;
221 ee->ee_ant_control[mode][i++] = val & 0x3f;
222
223
224 ah->ah_ant_ctl[mode][AR5K_ANT_CTL] =
225 (ee->ee_ant_control[mode][0] << 4);
226 ah->ah_ant_ctl[mode][AR5K_ANT_SWTABLE_A] =
227 ee->ee_ant_control[mode][1] |
228 (ee->ee_ant_control[mode][2] << 6) |
229 (ee->ee_ant_control[mode][3] << 12) |
230 (ee->ee_ant_control[mode][4] << 18) |
231 (ee->ee_ant_control[mode][5] << 24);
232 ah->ah_ant_ctl[mode][AR5K_ANT_SWTABLE_B] =
233 ee->ee_ant_control[mode][6] |
234 (ee->ee_ant_control[mode][7] << 6) |
235 (ee->ee_ant_control[mode][8] << 12) |
236 (ee->ee_ant_control[mode][9] << 18) |
237 (ee->ee_ant_control[mode][10] << 24);
238
239
240 *offset = o;
241
242 return 0;
243 }
244
245
246
247
248
249 static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,
250 unsigned int mode)
251 {
252 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
253 u32 o = *offset;
254 u16 val;
255
256 ee->ee_n_piers[mode] = 0;
257 AR5K_EEPROM_READ(o++, val);
258 ee->ee_adc_desired_size[mode] = (s8)((val >> 8) & 0xff);
259 switch (mode) {
260 case AR5K_EEPROM_MODE_11A:
261 ee->ee_ob[mode][3] = (val >> 5) & 0x7;
262 ee->ee_db[mode][3] = (val >> 2) & 0x7;
263 ee->ee_ob[mode][2] = (val << 1) & 0x7;
264
265 AR5K_EEPROM_READ(o++, val);
266 ee->ee_ob[mode][2] |= (val >> 15) & 0x1;
267 ee->ee_db[mode][2] = (val >> 12) & 0x7;
268 ee->ee_ob[mode][1] = (val >> 9) & 0x7;
269 ee->ee_db[mode][1] = (val >> 6) & 0x7;
270 ee->ee_ob[mode][0] = (val >> 3) & 0x7;
271 ee->ee_db[mode][0] = val & 0x7;
272 break;
273 case AR5K_EEPROM_MODE_11G:
274 case AR5K_EEPROM_MODE_11B:
275 ee->ee_ob[mode][1] = (val >> 4) & 0x7;
276 ee->ee_db[mode][1] = val & 0x7;
277 break;
278 }
279
280 AR5K_EEPROM_READ(o++, val);
281 ee->ee_tx_end2xlna_enable[mode] = (val >> 8) & 0xff;
282 ee->ee_thr_62[mode] = val & 0xff;
283
284 if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2)
285 ee->ee_thr_62[mode] = mode == AR5K_EEPROM_MODE_11A ? 15 : 28;
286
287 AR5K_EEPROM_READ(o++, val);
288 ee->ee_tx_end2xpa_disable[mode] = (val >> 8) & 0xff;
289 ee->ee_tx_frm2xpa_enable[mode] = val & 0xff;
290
291 AR5K_EEPROM_READ(o++, val);
292 ee->ee_pga_desired_size[mode] = (val >> 8) & 0xff;
293
294 if ((val & 0xff) & 0x80)
295 ee->ee_noise_floor_thr[mode] = -((((val & 0xff) ^ 0xff)) + 1);
296 else
297 ee->ee_noise_floor_thr[mode] = val & 0xff;
298
299 if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2)
300 ee->ee_noise_floor_thr[mode] =
301 mode == AR5K_EEPROM_MODE_11A ? -54 : -1;
302
303 AR5K_EEPROM_READ(o++, val);
304 ee->ee_xlna_gain[mode] = (val >> 5) & 0xff;
305 ee->ee_x_gain[mode] = (val >> 1) & 0xf;
306 ee->ee_xpd[mode] = val & 0x1;
307
308 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0 &&
309 mode != AR5K_EEPROM_MODE_11B)
310 ee->ee_fixed_bias[mode] = (val >> 13) & 0x1;
311
312 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_3) {
313 AR5K_EEPROM_READ(o++, val);
314 ee->ee_false_detect[mode] = (val >> 6) & 0x7f;
315
316 if (mode == AR5K_EEPROM_MODE_11A)
317 ee->ee_xr_power[mode] = val & 0x3f;
318 else {
319
320 ee->ee_ob[mode][0] = val & 0x7;
321 ee->ee_db[mode][0] = (val >> 3) & 0x7;
322 }
323 }
324
325 if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_4) {
326 ee->ee_i_gain[mode] = AR5K_EEPROM_I_GAIN;
327 ee->ee_cck_ofdm_power_delta = AR5K_EEPROM_CCK_OFDM_DELTA;
328 } else {
329 ee->ee_i_gain[mode] = (val >> 13) & 0x7;
330
331 AR5K_EEPROM_READ(o++, val);
332 ee->ee_i_gain[mode] |= (val << 3) & 0x38;
333
334 if (mode == AR5K_EEPROM_MODE_11G) {
335 ee->ee_cck_ofdm_power_delta = (val >> 3) & 0xff;
336 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_6)
337 ee->ee_scaled_cck_delta = (val >> 11) & 0x1f;
338 }
339 }
340
341 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0 &&
342 mode == AR5K_EEPROM_MODE_11A) {
343 ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
344 ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
345 }
346
347 if (ah->ah_ee_version < AR5K_EEPROM_VERSION_4_0)
348 goto done;
349
350
351
352
353 switch (mode) {
354 case AR5K_EEPROM_MODE_11A:
355 if (ah->ah_ee_version < AR5K_EEPROM_VERSION_4_1)
356 break;
357
358 AR5K_EEPROM_READ(o++, val);
359 ee->ee_margin_tx_rx[mode] = val & 0x3f;
360 break;
361 case AR5K_EEPROM_MODE_11B:
362 AR5K_EEPROM_READ(o++, val);
363
364 ee->ee_pwr_cal_b[0].freq =
365 ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
366 if (ee->ee_pwr_cal_b[0].freq != AR5K_EEPROM_CHANNEL_DIS)
367 ee->ee_n_piers[mode]++;
368
369 ee->ee_pwr_cal_b[1].freq =
370 ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode);
371 if (ee->ee_pwr_cal_b[1].freq != AR5K_EEPROM_CHANNEL_DIS)
372 ee->ee_n_piers[mode]++;
373
374 AR5K_EEPROM_READ(o++, val);
375 ee->ee_pwr_cal_b[2].freq =
376 ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
377 if (ee->ee_pwr_cal_b[2].freq != AR5K_EEPROM_CHANNEL_DIS)
378 ee->ee_n_piers[mode]++;
379
380 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
381 ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
382 break;
383 case AR5K_EEPROM_MODE_11G:
384 AR5K_EEPROM_READ(o++, val);
385
386 ee->ee_pwr_cal_g[0].freq =
387 ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
388 if (ee->ee_pwr_cal_g[0].freq != AR5K_EEPROM_CHANNEL_DIS)
389 ee->ee_n_piers[mode]++;
390
391 ee->ee_pwr_cal_g[1].freq =
392 ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode);
393 if (ee->ee_pwr_cal_g[1].freq != AR5K_EEPROM_CHANNEL_DIS)
394 ee->ee_n_piers[mode]++;
395
396 AR5K_EEPROM_READ(o++, val);
397 ee->ee_turbo_max_power[mode] = val & 0x7f;
398 ee->ee_xr_power[mode] = (val >> 7) & 0x3f;
399
400 AR5K_EEPROM_READ(o++, val);
401 ee->ee_pwr_cal_g[2].freq =
402 ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
403 if (ee->ee_pwr_cal_g[2].freq != AR5K_EEPROM_CHANNEL_DIS)
404 ee->ee_n_piers[mode]++;
405
406 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
407 ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
408
409 AR5K_EEPROM_READ(o++, val);
410 ee->ee_i_cal[mode] = (val >> 5) & 0x3f;
411 ee->ee_q_cal[mode] = val & 0x1f;
412
413 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_2) {
414 AR5K_EEPROM_READ(o++, val);
415 ee->ee_cck_ofdm_gain_delta = val & 0xff;
416 }
417 break;
418 }
419
420
421
422
423 if (ee->ee_version < AR5K_EEPROM_VERSION_5_0)
424 goto done;
425
426 switch (mode) {
427 case AR5K_EEPROM_MODE_11A:
428 ee->ee_switch_settling_turbo[mode] = (val >> 6) & 0x7f;
429
430 ee->ee_atn_tx_rx_turbo[mode] = (val >> 13) & 0x7;
431 AR5K_EEPROM_READ(o++, val);
432 ee->ee_atn_tx_rx_turbo[mode] |= (val & 0x7) << 3;
433 ee->ee_margin_tx_rx_turbo[mode] = (val >> 3) & 0x3f;
434
435 ee->ee_adc_desired_size_turbo[mode] = (val >> 9) & 0x7f;
436 AR5K_EEPROM_READ(o++, val);
437 ee->ee_adc_desired_size_turbo[mode] |= (val & 0x1) << 7;
438 ee->ee_pga_desired_size_turbo[mode] = (val >> 1) & 0xff;
439
440 if (AR5K_EEPROM_EEMAP(ee->ee_misc0) >= 2)
441 ee->ee_pd_gain_overlap = (val >> 9) & 0xf;
442 break;
443 case AR5K_EEPROM_MODE_11G:
444 ee->ee_switch_settling_turbo[mode] = (val >> 8) & 0x7f;
445
446 ee->ee_atn_tx_rx_turbo[mode] = (val >> 15) & 0x7;
447 AR5K_EEPROM_READ(o++, val);
448 ee->ee_atn_tx_rx_turbo[mode] |= (val & 0x1f) << 1;
449 ee->ee_margin_tx_rx_turbo[mode] = (val >> 5) & 0x3f;
450
451 ee->ee_adc_desired_size_turbo[mode] = (val >> 11) & 0x7f;
452 AR5K_EEPROM_READ(o++, val);
453 ee->ee_adc_desired_size_turbo[mode] |= (val & 0x7) << 5;
454 ee->ee_pga_desired_size_turbo[mode] = (val >> 3) & 0xff;
455 break;
456 }
457
458 done:
459
460 *offset = o;
461
462 return 0;
463 }
464
465
466 static int
467 ath5k_eeprom_init_modes(struct ath5k_hw *ah)
468 {
469 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
470 u32 mode_offset[3];
471 unsigned int mode;
472 u32 offset;
473 int ret;
474
475
476
477
478 mode_offset[AR5K_EEPROM_MODE_11A] = AR5K_EEPROM_MODES_11A(ah->ah_ee_version);
479 mode_offset[AR5K_EEPROM_MODE_11B] = AR5K_EEPROM_MODES_11B(ah->ah_ee_version);
480 mode_offset[AR5K_EEPROM_MODE_11G] = AR5K_EEPROM_MODES_11G(ah->ah_ee_version);
481
482 ee->ee_turbo_max_power[AR5K_EEPROM_MODE_11A] =
483 AR5K_EEPROM_HDR_T_5GHZ_DBM(ee->ee_header);
484
485 for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++) {
486 offset = mode_offset[mode];
487
488 ret = ath5k_eeprom_read_ants(ah, &offset, mode);
489 if (ret)
490 return ret;
491
492 ret = ath5k_eeprom_read_modes(ah, &offset, mode);
493 if (ret)
494 return ret;
495 }
496
497
498 if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2) {
499 ee->ee_thr_62[AR5K_EEPROM_MODE_11A] = 15;
500 ee->ee_thr_62[AR5K_EEPROM_MODE_11B] = 28;
501 ee->ee_thr_62[AR5K_EEPROM_MODE_11G] = 28;
502 }
503
504 return 0;
505 }
506
507
508
509 static inline int
510 ath5k_eeprom_read_freq_list(struct ath5k_hw *ah, int *offset, int max,
511 struct ath5k_chan_pcal_info *pc, unsigned int mode)
512 {
513 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
514 int o = *offset;
515 int i = 0;
516 u8 freq1, freq2;
517 u16 val;
518
519 ee->ee_n_piers[mode] = 0;
520 while (i < max) {
521 AR5K_EEPROM_READ(o++, val);
522
523 freq1 = val & 0xff;
524 if (!freq1)
525 break;
526
527 pc[i++].freq = ath5k_eeprom_bin2freq(ee,
528 freq1, mode);
529 ee->ee_n_piers[mode]++;
530
531 freq2 = (val >> 8) & 0xff;
532 if (!freq2)
533 break;
534
535 pc[i++].freq = ath5k_eeprom_bin2freq(ee,
536 freq2, mode);
537 ee->ee_n_piers[mode]++;
538 }
539
540
541 *offset = o;
542
543 return 0;
544 }
545
546
547 static int
548 ath5k_eeprom_init_11a_pcal_freq(struct ath5k_hw *ah, int offset)
549 {
550 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
551 struct ath5k_chan_pcal_info *pcal = ee->ee_pwr_cal_a;
552 int i;
553 u16 val;
554 u8 mask;
555
556 if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3) {
557 ath5k_eeprom_read_freq_list(ah, &offset,
558 AR5K_EEPROM_N_5GHZ_CHAN, pcal,
559 AR5K_EEPROM_MODE_11A);
560 } else {
561 mask = AR5K_EEPROM_FREQ_M(ah->ah_ee_version);
562
563 AR5K_EEPROM_READ(offset++, val);
564 pcal[0].freq = (val >> 9) & mask;
565 pcal[1].freq = (val >> 2) & mask;
566 pcal[2].freq = (val << 5) & mask;
567
568 AR5K_EEPROM_READ(offset++, val);
569 pcal[2].freq |= (val >> 11) & 0x1f;
570 pcal[3].freq = (val >> 4) & mask;
571 pcal[4].freq = (val << 3) & mask;
572
573 AR5K_EEPROM_READ(offset++, val);
574 pcal[4].freq |= (val >> 13) & 0x7;
575 pcal[5].freq = (val >> 6) & mask;
576 pcal[6].freq = (val << 1) & mask;
577
578 AR5K_EEPROM_READ(offset++, val);
579 pcal[6].freq |= (val >> 15) & 0x1;
580 pcal[7].freq = (val >> 8) & mask;
581 pcal[8].freq = (val >> 1) & mask;
582 pcal[9].freq = (val << 6) & mask;
583
584 AR5K_EEPROM_READ(offset++, val);
585 pcal[9].freq |= (val >> 10) & 0x3f;
586
587
588 ee->ee_n_piers[AR5K_EEPROM_MODE_11A] = 10;
589
590 for (i = 0; i < AR5K_EEPROM_N_5GHZ_CHAN; i++) {
591 pcal[i].freq = ath5k_eeprom_bin2freq(ee,
592 pcal[i].freq, AR5K_EEPROM_MODE_11A);
593 }
594 }
595
596 return 0;
597 }
598
599
600 static inline int
601 ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset)
602 {
603 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
604 struct ath5k_chan_pcal_info *pcal;
605
606 switch (mode) {
607 case AR5K_EEPROM_MODE_11B:
608 pcal = ee->ee_pwr_cal_b;
609 break;
610 case AR5K_EEPROM_MODE_11G:
611 pcal = ee->ee_pwr_cal_g;
612 break;
613 default:
614 return -EINVAL;
615 }
616
617 ath5k_eeprom_read_freq_list(ah, &offset,
618 AR5K_EEPROM_N_2GHZ_CHAN_2413, pcal,
619 mode);
620
621 return 0;
622 }
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645 static inline void
646 ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp)
647 {
648 static const u16 intercepts3[] = {
649 0, 5, 10, 20, 30, 50, 70, 85, 90, 95, 100
650 };
651 static const u16 intercepts3_2[] = {
652 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100
653 };
654 const u16 *ip;
655 int i;
656
657 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_2)
658 ip = intercepts3_2;
659 else
660 ip = intercepts3;
661
662 for (i = 0; i < ARRAY_SIZE(intercepts3); i++)
663 vp[i] = (ip[i] * max + (100 - ip[i]) * min) / 100;
664 }
665
666 static int
667 ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode)
668 {
669 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
670 struct ath5k_chan_pcal_info *chinfo;
671 u8 pier, pdg;
672
673 switch (mode) {
674 case AR5K_EEPROM_MODE_11A:
675 if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
676 return 0;
677 chinfo = ee->ee_pwr_cal_a;
678 break;
679 case AR5K_EEPROM_MODE_11B:
680 if (!AR5K_EEPROM_HDR_11B(ee->ee_header))
681 return 0;
682 chinfo = ee->ee_pwr_cal_b;
683 break;
684 case AR5K_EEPROM_MODE_11G:
685 if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
686 return 0;
687 chinfo = ee->ee_pwr_cal_g;
688 break;
689 default:
690 return -EINVAL;
691 }
692
693 for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
694 if (!chinfo[pier].pd_curves)
695 continue;
696
697 for (pdg = 0; pdg < AR5K_EEPROM_N_PD_CURVES; pdg++) {
698 struct ath5k_pdgain_info *pd =
699 &chinfo[pier].pd_curves[pdg];
700
701 kfree(pd->pd_step);
702 kfree(pd->pd_pwr);
703 }
704
705 kfree(chinfo[pier].pd_curves);
706 }
707
708 return 0;
709 }
710
711
712
713 static int
714 ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode,
715 struct ath5k_chan_pcal_info *chinfo)
716 {
717 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
718 struct ath5k_chan_pcal_info_rf5111 *pcinfo;
719 struct ath5k_pdgain_info *pd;
720 u8 pier, point, idx;
721 u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
722
723
724 for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
725
726 pcinfo = &chinfo[pier].rf5111_info;
727
728
729 chinfo[pier].pd_curves =
730 kcalloc(AR5K_EEPROM_N_PD_CURVES,
731 sizeof(struct ath5k_pdgain_info),
732 GFP_KERNEL);
733
734 if (!chinfo[pier].pd_curves)
735 goto err_out;
736
737
738
739
740
741 for (idx = 0; idx < AR5K_EEPROM_N_PD_CURVES; idx++) {
742
743 if (!((ee->ee_x_gain[mode] >> idx) & 0x1)) {
744 pdgain_idx[0] = idx;
745 break;
746 }
747 }
748
749 ee->ee_pd_gains[mode] = 1;
750
751 pd = &chinfo[pier].pd_curves[idx];
752
753 pd->pd_points = AR5K_EEPROM_N_PWR_POINTS_5111;
754
755
756 pd->pd_step = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111,
757 sizeof(u8), GFP_KERNEL);
758 if (!pd->pd_step)
759 goto err_out;
760
761 pd->pd_pwr = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111,
762 sizeof(s16), GFP_KERNEL);
763 if (!pd->pd_pwr)
764 goto err_out;
765
766
767
768
769 for (point = 0; point < pd->pd_points; point++) {
770
771
772 pd->pd_pwr[point] = 2 * pcinfo->pwr[point];
773
774
775 pd->pd_step[point] = pcinfo->pcdac[point];
776 }
777
778
779 chinfo[pier].min_pwr = pd->pd_pwr[0];
780 chinfo[pier].max_pwr = pd->pd_pwr[10];
781
782 }
783
784 return 0;
785
786 err_out:
787 ath5k_eeprom_free_pcal_info(ah, mode);
788 return -ENOMEM;
789 }
790
791
792 static int
793 ath5k_eeprom_read_pcal_info_5111(struct ath5k_hw *ah, int mode)
794 {
795 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
796 struct ath5k_chan_pcal_info *pcal;
797 int offset, ret;
798 int i;
799 u16 val;
800
801 offset = AR5K_EEPROM_GROUPS_START(ee->ee_version);
802 switch (mode) {
803 case AR5K_EEPROM_MODE_11A:
804 if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
805 return 0;
806
807 ret = ath5k_eeprom_init_11a_pcal_freq(ah,
808 offset + AR5K_EEPROM_GROUP1_OFFSET);
809 if (ret < 0)
810 return ret;
811
812 offset += AR5K_EEPROM_GROUP2_OFFSET;
813 pcal = ee->ee_pwr_cal_a;
814 break;
815 case AR5K_EEPROM_MODE_11B:
816 if (!AR5K_EEPROM_HDR_11B(ee->ee_header) &&
817 !AR5K_EEPROM_HDR_11G(ee->ee_header))
818 return 0;
819
820 pcal = ee->ee_pwr_cal_b;
821 offset += AR5K_EEPROM_GROUP3_OFFSET;
822
823
824 pcal[0].freq = 2412;
825 pcal[1].freq = 2447;
826 pcal[2].freq = 2484;
827 ee->ee_n_piers[mode] = 3;
828 break;
829 case AR5K_EEPROM_MODE_11G:
830 if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
831 return 0;
832
833 pcal = ee->ee_pwr_cal_g;
834 offset += AR5K_EEPROM_GROUP4_OFFSET;
835
836
837 pcal[0].freq = 2312;
838 pcal[1].freq = 2412;
839 pcal[2].freq = 2484;
840 ee->ee_n_piers[mode] = 3;
841 break;
842 default:
843 return -EINVAL;
844 }
845
846 for (i = 0; i < ee->ee_n_piers[mode]; i++) {
847 struct ath5k_chan_pcal_info_rf5111 *cdata =
848 &pcal[i].rf5111_info;
849
850 AR5K_EEPROM_READ(offset++, val);
851 cdata->pcdac_max = ((val >> 10) & AR5K_EEPROM_PCDAC_M);
852 cdata->pcdac_min = ((val >> 4) & AR5K_EEPROM_PCDAC_M);
853 cdata->pwr[0] = ((val << 2) & AR5K_EEPROM_POWER_M);
854
855 AR5K_EEPROM_READ(offset++, val);
856 cdata->pwr[0] |= ((val >> 14) & 0x3);
857 cdata->pwr[1] = ((val >> 8) & AR5K_EEPROM_POWER_M);
858 cdata->pwr[2] = ((val >> 2) & AR5K_EEPROM_POWER_M);
859 cdata->pwr[3] = ((val << 4) & AR5K_EEPROM_POWER_M);
860
861 AR5K_EEPROM_READ(offset++, val);
862 cdata->pwr[3] |= ((val >> 12) & 0xf);
863 cdata->pwr[4] = ((val >> 6) & AR5K_EEPROM_POWER_M);
864 cdata->pwr[5] = (val & AR5K_EEPROM_POWER_M);
865
866 AR5K_EEPROM_READ(offset++, val);
867 cdata->pwr[6] = ((val >> 10) & AR5K_EEPROM_POWER_M);
868 cdata->pwr[7] = ((val >> 4) & AR5K_EEPROM_POWER_M);
869 cdata->pwr[8] = ((val << 2) & AR5K_EEPROM_POWER_M);
870
871 AR5K_EEPROM_READ(offset++, val);
872 cdata->pwr[8] |= ((val >> 14) & 0x3);
873 cdata->pwr[9] = ((val >> 8) & AR5K_EEPROM_POWER_M);
874 cdata->pwr[10] = ((val >> 2) & AR5K_EEPROM_POWER_M);
875
876 ath5k_get_pcdac_intercepts(ah, cdata->pcdac_min,
877 cdata->pcdac_max, cdata->pcdac);
878 }
879
880 return ath5k_eeprom_convert_pcal_info_5111(ah, mode, pcal);
881 }
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901 static int
902 ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode,
903 struct ath5k_chan_pcal_info *chinfo)
904 {
905 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
906 struct ath5k_chan_pcal_info_rf5112 *pcinfo;
907 u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
908 unsigned int pier, pdg, point;
909
910
911 for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
912
913 pcinfo = &chinfo[pier].rf5112_info;
914
915
916 chinfo[pier].pd_curves =
917 kcalloc(AR5K_EEPROM_N_PD_CURVES,
918 sizeof(struct ath5k_pdgain_info),
919 GFP_KERNEL);
920
921 if (!chinfo[pier].pd_curves)
922 goto err_out;
923
924
925 for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
926
927 u8 idx = pdgain_idx[pdg];
928 struct ath5k_pdgain_info *pd =
929 &chinfo[pier].pd_curves[idx];
930
931
932 if (pdg == 0) {
933
934 pd->pd_points = AR5K_EEPROM_N_XPD0_POINTS;
935
936
937 pd->pd_step = kcalloc(pd->pd_points,
938 sizeof(u8), GFP_KERNEL);
939
940 if (!pd->pd_step)
941 goto err_out;
942
943 pd->pd_pwr = kcalloc(pd->pd_points,
944 sizeof(s16), GFP_KERNEL);
945
946 if (!pd->pd_pwr)
947 goto err_out;
948
949
950
951 pd->pd_step[0] = pcinfo->pcdac_x0[0];
952 pd->pd_pwr[0] = pcinfo->pwr_x0[0];
953
954 for (point = 1; point < pd->pd_points;
955 point++) {
956
957 pd->pd_pwr[point] =
958 pcinfo->pwr_x0[point];
959
960
961 pd->pd_step[point] =
962 pd->pd_step[point - 1] +
963 pcinfo->pcdac_x0[point];
964 }
965
966
967 chinfo[pier].min_pwr = pd->pd_pwr[0];
968
969
970 } else if (pdg == 1) {
971
972 pd->pd_points = AR5K_EEPROM_N_XPD3_POINTS;
973
974
975 pd->pd_step = kcalloc(pd->pd_points,
976 sizeof(u8), GFP_KERNEL);
977
978 if (!pd->pd_step)
979 goto err_out;
980
981 pd->pd_pwr = kcalloc(pd->pd_points,
982 sizeof(s16), GFP_KERNEL);
983
984 if (!pd->pd_pwr)
985 goto err_out;
986
987
988
989 for (point = 0; point < pd->pd_points;
990 point++) {
991
992 pd->pd_pwr[point] =
993 pcinfo->pwr_x3[point];
994
995
996 pd->pd_step[point] =
997 pcinfo->pcdac_x3[point];
998 }
999
1000
1001
1002 chinfo[pier].min_pwr = pd->pd_pwr[0];
1003 }
1004 }
1005 }
1006
1007 return 0;
1008
1009 err_out:
1010 ath5k_eeprom_free_pcal_info(ah, mode);
1011 return -ENOMEM;
1012 }
1013
1014
1015 static int
1016 ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw *ah, int mode)
1017 {
1018 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1019 struct ath5k_chan_pcal_info_rf5112 *chan_pcal_info;
1020 struct ath5k_chan_pcal_info *gen_chan_info;
1021 u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
1022 u32 offset;
1023 u8 i, c;
1024 u16 val;
1025 u8 pd_gains = 0;
1026
1027
1028
1029
1030
1031
1032 for (i = 0; i < AR5K_EEPROM_N_PD_CURVES; i++) {
1033
1034 if ((ee->ee_x_gain[mode] >> i) & 0x1)
1035 pdgain_idx[pd_gains++] = i;
1036 }
1037 ee->ee_pd_gains[mode] = pd_gains;
1038
1039 if (pd_gains == 0 || pd_gains > 2)
1040 return -EINVAL;
1041
1042 switch (mode) {
1043 case AR5K_EEPROM_MODE_11A:
1044
1045
1046
1047 offset = AR5K_EEPROM_GROUPS_START(ee->ee_version);
1048 ath5k_eeprom_init_11a_pcal_freq(ah, offset);
1049
1050 offset += AR5K_EEPROM_GROUP2_OFFSET;
1051 gen_chan_info = ee->ee_pwr_cal_a;
1052 break;
1053 case AR5K_EEPROM_MODE_11B:
1054 offset = AR5K_EEPROM_GROUPS_START(ee->ee_version);
1055 if (AR5K_EEPROM_HDR_11A(ee->ee_header))
1056 offset += AR5K_EEPROM_GROUP3_OFFSET;
1057
1058
1059 gen_chan_info = ee->ee_pwr_cal_b;
1060 break;
1061 case AR5K_EEPROM_MODE_11G:
1062 offset = AR5K_EEPROM_GROUPS_START(ee->ee_version);
1063 if (AR5K_EEPROM_HDR_11A(ee->ee_header))
1064 offset += AR5K_EEPROM_GROUP4_OFFSET;
1065 else if (AR5K_EEPROM_HDR_11B(ee->ee_header))
1066 offset += AR5K_EEPROM_GROUP2_OFFSET;
1067
1068
1069 gen_chan_info = ee->ee_pwr_cal_g;
1070 break;
1071 default:
1072 return -EINVAL;
1073 }
1074
1075 for (i = 0; i < ee->ee_n_piers[mode]; i++) {
1076 chan_pcal_info = &gen_chan_info[i].rf5112_info;
1077
1078
1079
1080
1081 for (c = 0; c < AR5K_EEPROM_N_XPD0_POINTS; c++) {
1082 AR5K_EEPROM_READ(offset++, val);
1083 chan_pcal_info->pwr_x0[c] = (s8) (val & 0xff);
1084 chan_pcal_info->pwr_x0[++c] = (s8) ((val >> 8) & 0xff);
1085 }
1086
1087
1088
1089
1090 AR5K_EEPROM_READ(offset++, val);
1091 chan_pcal_info->pcdac_x0[1] = (val & 0x1f);
1092 chan_pcal_info->pcdac_x0[2] = ((val >> 5) & 0x1f);
1093 chan_pcal_info->pcdac_x0[3] = ((val >> 10) & 0x1f);
1094
1095
1096
1097
1098 AR5K_EEPROM_READ(offset++, val);
1099 chan_pcal_info->pwr_x3[0] = (s8) (val & 0xff);
1100 chan_pcal_info->pwr_x3[1] = (s8) ((val >> 8) & 0xff);
1101
1102 AR5K_EEPROM_READ(offset++, val);
1103 chan_pcal_info->pwr_x3[2] = (val & 0xff);
1104
1105
1106
1107
1108 chan_pcal_info->pcdac_x3[0] = 20;
1109 chan_pcal_info->pcdac_x3[1] = 35;
1110 chan_pcal_info->pcdac_x3[2] = 63;
1111
1112 if (ee->ee_version >= AR5K_EEPROM_VERSION_4_3) {
1113 chan_pcal_info->pcdac_x0[0] = ((val >> 8) & 0x3f);
1114
1115
1116 gen_chan_info[i].max_pwr = chan_pcal_info->pwr_x0[3];
1117 } else {
1118 chan_pcal_info->pcdac_x0[0] = 1;
1119 gen_chan_info[i].max_pwr = (s8) ((val >> 8) & 0xff);
1120 }
1121
1122 }
1123
1124 return ath5k_eeprom_convert_pcal_info_5112(ah, mode, gen_chan_info);
1125 }
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150 static inline unsigned int
1151 ath5k_pdgains_size_2413(struct ath5k_eeprom_info *ee, unsigned int mode)
1152 {
1153 static const unsigned int pdgains_size[] = { 4, 6, 9, 12 };
1154 unsigned int sz;
1155
1156 sz = pdgains_size[ee->ee_pd_gains[mode] - 1];
1157 sz *= ee->ee_n_piers[mode];
1158
1159 return sz;
1160 }
1161
1162
1163
1164 static unsigned int
1165 ath5k_cal_data_offset_2413(struct ath5k_eeprom_info *ee, int mode)
1166 {
1167 u32 offset = AR5K_EEPROM_CAL_DATA_START(ee->ee_misc4);
1168
1169 switch (mode) {
1170 case AR5K_EEPROM_MODE_11G:
1171 if (AR5K_EEPROM_HDR_11B(ee->ee_header))
1172 offset += ath5k_pdgains_size_2413(ee,
1173 AR5K_EEPROM_MODE_11B) +
1174 AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2;
1175
1176 case AR5K_EEPROM_MODE_11B:
1177 if (AR5K_EEPROM_HDR_11A(ee->ee_header))
1178 offset += ath5k_pdgains_size_2413(ee,
1179 AR5K_EEPROM_MODE_11A) +
1180 AR5K_EEPROM_N_5GHZ_CHAN / 2;
1181
1182 case AR5K_EEPROM_MODE_11A:
1183 break;
1184 default:
1185 break;
1186 }
1187
1188 return offset;
1189 }
1190
1191
1192
1193 static int
1194 ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode,
1195 struct ath5k_chan_pcal_info *chinfo)
1196 {
1197 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1198 struct ath5k_chan_pcal_info_rf2413 *pcinfo;
1199 u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
1200 unsigned int pier, pdg, point;
1201
1202
1203 for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
1204
1205 pcinfo = &chinfo[pier].rf2413_info;
1206
1207
1208 chinfo[pier].pd_curves =
1209 kcalloc(AR5K_EEPROM_N_PD_CURVES,
1210 sizeof(struct ath5k_pdgain_info),
1211 GFP_KERNEL);
1212
1213 if (!chinfo[pier].pd_curves)
1214 goto err_out;
1215
1216
1217 for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
1218
1219 u8 idx = pdgain_idx[pdg];
1220 struct ath5k_pdgain_info *pd =
1221 &chinfo[pier].pd_curves[idx];
1222
1223
1224
1225 if (pdg == ee->ee_pd_gains[mode] - 1)
1226 pd->pd_points = AR5K_EEPROM_N_PD_POINTS;
1227 else
1228 pd->pd_points = AR5K_EEPROM_N_PD_POINTS - 1;
1229
1230
1231 pd->pd_step = kcalloc(pd->pd_points,
1232 sizeof(u8), GFP_KERNEL);
1233
1234 if (!pd->pd_step)
1235 goto err_out;
1236
1237 pd->pd_pwr = kcalloc(pd->pd_points,
1238 sizeof(s16), GFP_KERNEL);
1239
1240 if (!pd->pd_pwr)
1241 goto err_out;
1242
1243
1244
1245
1246 pd->pd_step[0] = pcinfo->pddac_i[pdg];
1247 pd->pd_pwr[0] = 4 * pcinfo->pwr_i[pdg];
1248
1249 for (point = 1; point < pd->pd_points; point++) {
1250
1251 pd->pd_pwr[point] = pd->pd_pwr[point - 1] +
1252 2 * pcinfo->pwr[pdg][point - 1];
1253
1254 pd->pd_step[point] = pd->pd_step[point - 1] +
1255 pcinfo->pddac[pdg][point - 1];
1256
1257 }
1258
1259
1260 if (pdg == 0)
1261 chinfo[pier].min_pwr = pd->pd_pwr[0];
1262
1263
1264 if (pdg == ee->ee_pd_gains[mode] - 1)
1265 chinfo[pier].max_pwr =
1266 pd->pd_pwr[pd->pd_points - 1];
1267 }
1268 }
1269
1270 return 0;
1271
1272 err_out:
1273 ath5k_eeprom_free_pcal_info(ah, mode);
1274 return -ENOMEM;
1275 }
1276
1277
1278 static int
1279 ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode)
1280 {
1281 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1282 struct ath5k_chan_pcal_info_rf2413 *pcinfo;
1283 struct ath5k_chan_pcal_info *chinfo;
1284 u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
1285 u32 offset;
1286 int idx, i;
1287 u16 val;
1288 u8 pd_gains = 0;
1289
1290
1291
1292
1293
1294
1295 for (idx = AR5K_EEPROM_N_PD_CURVES - 1; idx >= 0; idx--) {
1296
1297 if ((ee->ee_x_gain[mode] >> idx) & 0x1)
1298 pdgain_idx[pd_gains++] = idx;
1299
1300 }
1301 ee->ee_pd_gains[mode] = pd_gains;
1302
1303 if (pd_gains == 0)
1304 return -EINVAL;
1305
1306 offset = ath5k_cal_data_offset_2413(ee, mode);
1307 switch (mode) {
1308 case AR5K_EEPROM_MODE_11A:
1309 if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
1310 return 0;
1311
1312 ath5k_eeprom_init_11a_pcal_freq(ah, offset);
1313 offset += AR5K_EEPROM_N_5GHZ_CHAN / 2;
1314 chinfo = ee->ee_pwr_cal_a;
1315 break;
1316 case AR5K_EEPROM_MODE_11B:
1317 if (!AR5K_EEPROM_HDR_11B(ee->ee_header))
1318 return 0;
1319
1320 ath5k_eeprom_init_11bg_2413(ah, mode, offset);
1321 offset += AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2;
1322 chinfo = ee->ee_pwr_cal_b;
1323 break;
1324 case AR5K_EEPROM_MODE_11G:
1325 if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
1326 return 0;
1327
1328 ath5k_eeprom_init_11bg_2413(ah, mode, offset);
1329 offset += AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2;
1330 chinfo = ee->ee_pwr_cal_g;
1331 break;
1332 default:
1333 return -EINVAL;
1334 }
1335
1336 for (i = 0; i < ee->ee_n_piers[mode]; i++) {
1337 pcinfo = &chinfo[i].rf2413_info;
1338
1339
1340
1341
1342
1343 AR5K_EEPROM_READ(offset++, val);
1344 pcinfo->pwr_i[0] = val & 0x1f;
1345 pcinfo->pddac_i[0] = (val >> 5) & 0x7f;
1346 pcinfo->pwr[0][0] = (val >> 12) & 0xf;
1347
1348 AR5K_EEPROM_READ(offset++, val);
1349 pcinfo->pddac[0][0] = val & 0x3f;
1350 pcinfo->pwr[0][1] = (val >> 6) & 0xf;
1351 pcinfo->pddac[0][1] = (val >> 10) & 0x3f;
1352
1353 AR5K_EEPROM_READ(offset++, val);
1354 pcinfo->pwr[0][2] = val & 0xf;
1355 pcinfo->pddac[0][2] = (val >> 4) & 0x3f;
1356
1357 pcinfo->pwr[0][3] = 0;
1358 pcinfo->pddac[0][3] = 0;
1359
1360 if (pd_gains > 1) {
1361
1362
1363
1364
1365
1366 pcinfo->pwr_i[1] = (val >> 10) & 0x1f;
1367
1368 pcinfo->pddac_i[1] = (val >> 15) & 0x1;
1369 AR5K_EEPROM_READ(offset++, val);
1370 pcinfo->pddac_i[1] |= (val & 0x3F) << 1;
1371
1372 pcinfo->pwr[1][0] = (val >> 6) & 0xf;
1373 pcinfo->pddac[1][0] = (val >> 10) & 0x3f;
1374
1375 AR5K_EEPROM_READ(offset++, val);
1376 pcinfo->pwr[1][1] = val & 0xf;
1377 pcinfo->pddac[1][1] = (val >> 4) & 0x3f;
1378 pcinfo->pwr[1][2] = (val >> 10) & 0xf;
1379
1380 pcinfo->pddac[1][2] = (val >> 14) & 0x3;
1381 AR5K_EEPROM_READ(offset++, val);
1382 pcinfo->pddac[1][2] |= (val & 0xF) << 2;
1383
1384 pcinfo->pwr[1][3] = 0;
1385 pcinfo->pddac[1][3] = 0;
1386 } else if (pd_gains == 1) {
1387
1388
1389
1390
1391 pcinfo->pwr[0][3] = (val >> 10) & 0xf;
1392
1393 pcinfo->pddac[0][3] = (val >> 14) & 0x3;
1394 AR5K_EEPROM_READ(offset++, val);
1395 pcinfo->pddac[0][3] |= (val & 0xF) << 2;
1396 }
1397
1398
1399
1400
1401
1402 if (pd_gains > 2) {
1403 pcinfo->pwr_i[2] = (val >> 4) & 0x1f;
1404 pcinfo->pddac_i[2] = (val >> 9) & 0x7f;
1405
1406 AR5K_EEPROM_READ(offset++, val);
1407 pcinfo->pwr[2][0] = (val >> 0) & 0xf;
1408 pcinfo->pddac[2][0] = (val >> 4) & 0x3f;
1409 pcinfo->pwr[2][1] = (val >> 10) & 0xf;
1410
1411 pcinfo->pddac[2][1] = (val >> 14) & 0x3;
1412 AR5K_EEPROM_READ(offset++, val);
1413 pcinfo->pddac[2][1] |= (val & 0xF) << 2;
1414
1415 pcinfo->pwr[2][2] = (val >> 4) & 0xf;
1416 pcinfo->pddac[2][2] = (val >> 8) & 0x3f;
1417
1418 pcinfo->pwr[2][3] = 0;
1419 pcinfo->pddac[2][3] = 0;
1420 } else if (pd_gains == 2) {
1421 pcinfo->pwr[1][3] = (val >> 4) & 0xf;
1422 pcinfo->pddac[1][3] = (val >> 8) & 0x3f;
1423 }
1424
1425 if (pd_gains > 3) {
1426 pcinfo->pwr_i[3] = (val >> 14) & 0x3;
1427 AR5K_EEPROM_READ(offset++, val);
1428 pcinfo->pwr_i[3] |= ((val >> 0) & 0x7) << 2;
1429
1430 pcinfo->pddac_i[3] = (val >> 3) & 0x7f;
1431 pcinfo->pwr[3][0] = (val >> 10) & 0xf;
1432 pcinfo->pddac[3][0] = (val >> 14) & 0x3;
1433
1434 AR5K_EEPROM_READ(offset++, val);
1435 pcinfo->pddac[3][0] |= (val & 0xF) << 2;
1436 pcinfo->pwr[3][1] = (val >> 4) & 0xf;
1437 pcinfo->pddac[3][1] = (val >> 8) & 0x3f;
1438
1439 pcinfo->pwr[3][2] = (val >> 14) & 0x3;
1440 AR5K_EEPROM_READ(offset++, val);
1441 pcinfo->pwr[3][2] |= ((val >> 0) & 0x3) << 2;
1442
1443 pcinfo->pddac[3][2] = (val >> 2) & 0x3f;
1444 pcinfo->pwr[3][3] = (val >> 8) & 0xf;
1445
1446 pcinfo->pddac[3][3] = (val >> 12) & 0xF;
1447 AR5K_EEPROM_READ(offset++, val);
1448 pcinfo->pddac[3][3] |= ((val >> 0) & 0x3) << 4;
1449 } else if (pd_gains == 3) {
1450 pcinfo->pwr[2][3] = (val >> 14) & 0x3;
1451 AR5K_EEPROM_READ(offset++, val);
1452 pcinfo->pwr[2][3] |= ((val >> 0) & 0x3) << 2;
1453
1454 pcinfo->pddac[2][3] = (val >> 2) & 0x3f;
1455 }
1456 }
1457
1458 return ath5k_eeprom_convert_pcal_info_2413(ah, mode, chinfo);
1459 }
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469 static int
1470 ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned int mode)
1471 {
1472 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1473 struct ath5k_rate_pcal_info *rate_pcal_info;
1474 u8 *rate_target_pwr_num;
1475 u32 offset;
1476 u16 val;
1477 int i;
1478
1479 offset = AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1);
1480 rate_target_pwr_num = &ee->ee_rate_target_pwr_num[mode];
1481 switch (mode) {
1482 case AR5K_EEPROM_MODE_11A:
1483 offset += AR5K_EEPROM_TARGET_PWR_OFF_11A(ee->ee_version);
1484 rate_pcal_info = ee->ee_rate_tpwr_a;
1485 ee->ee_rate_target_pwr_num[mode] = AR5K_EEPROM_N_5GHZ_RATE_CHAN;
1486 break;
1487 case AR5K_EEPROM_MODE_11B:
1488 offset += AR5K_EEPROM_TARGET_PWR_OFF_11B(ee->ee_version);
1489 rate_pcal_info = ee->ee_rate_tpwr_b;
1490 ee->ee_rate_target_pwr_num[mode] = 2;
1491 break;
1492 case AR5K_EEPROM_MODE_11G:
1493 offset += AR5K_EEPROM_TARGET_PWR_OFF_11G(ee->ee_version);
1494 rate_pcal_info = ee->ee_rate_tpwr_g;
1495 ee->ee_rate_target_pwr_num[mode] = AR5K_EEPROM_N_2GHZ_CHAN;
1496 break;
1497 default:
1498 return -EINVAL;
1499 }
1500
1501
1502 if (ee->ee_version <= AR5K_EEPROM_VERSION_3_2) {
1503 for (i = 0; i < (*rate_target_pwr_num); i++) {
1504 AR5K_EEPROM_READ(offset++, val);
1505 rate_pcal_info[i].freq =
1506 ath5k_eeprom_bin2freq(ee, (val >> 9) & 0x7f, mode);
1507
1508 rate_pcal_info[i].target_power_6to24 = ((val >> 3) & 0x3f);
1509 rate_pcal_info[i].target_power_36 = (val << 3) & 0x3f;
1510
1511 AR5K_EEPROM_READ(offset++, val);
1512
1513 if (rate_pcal_info[i].freq == AR5K_EEPROM_CHANNEL_DIS ||
1514 val == 0) {
1515 (*rate_target_pwr_num) = i;
1516 break;
1517 }
1518
1519 rate_pcal_info[i].target_power_36 |= ((val >> 13) & 0x7);
1520 rate_pcal_info[i].target_power_48 = ((val >> 7) & 0x3f);
1521 rate_pcal_info[i].target_power_54 = ((val >> 1) & 0x3f);
1522 }
1523 } else {
1524 for (i = 0; i < (*rate_target_pwr_num); i++) {
1525 AR5K_EEPROM_READ(offset++, val);
1526 rate_pcal_info[i].freq =
1527 ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode);
1528
1529 rate_pcal_info[i].target_power_6to24 = ((val >> 2) & 0x3f);
1530 rate_pcal_info[i].target_power_36 = (val << 4) & 0x3f;
1531
1532 AR5K_EEPROM_READ(offset++, val);
1533
1534 if (rate_pcal_info[i].freq == AR5K_EEPROM_CHANNEL_DIS ||
1535 val == 0) {
1536 (*rate_target_pwr_num) = i;
1537 break;
1538 }
1539
1540 rate_pcal_info[i].target_power_36 |= (val >> 12) & 0xf;
1541 rate_pcal_info[i].target_power_48 = ((val >> 6) & 0x3f);
1542 rate_pcal_info[i].target_power_54 = (val & 0x3f);
1543 }
1544 }
1545
1546 return 0;
1547 }
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564 static int
1565 ath5k_eeprom_read_pcal_info(struct ath5k_hw *ah)
1566 {
1567 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1568 int (*read_pcal)(struct ath5k_hw *hw, int mode);
1569 int mode;
1570 int err;
1571
1572 if ((ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) &&
1573 (AR5K_EEPROM_EEMAP(ee->ee_misc0) == 1))
1574 read_pcal = ath5k_eeprom_read_pcal_info_5112;
1575 else if ((ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_0) &&
1576 (AR5K_EEPROM_EEMAP(ee->ee_misc0) == 2))
1577 read_pcal = ath5k_eeprom_read_pcal_info_2413;
1578 else
1579 read_pcal = ath5k_eeprom_read_pcal_info_5111;
1580
1581
1582 for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G;
1583 mode++) {
1584 err = read_pcal(ah, mode);
1585 if (err)
1586 return err;
1587
1588 err = ath5k_eeprom_read_target_rate_pwr_info(ah, mode);
1589 if (err < 0)
1590 return err;
1591 }
1592
1593 return 0;
1594 }
1595
1596
1597 static int
1598 ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah)
1599 {
1600 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1601 struct ath5k_edge_power *rep;
1602 unsigned int fmask, pmask;
1603 unsigned int ctl_mode;
1604 int i, j;
1605 u32 offset;
1606 u16 val;
1607
1608 pmask = AR5K_EEPROM_POWER_M;
1609 fmask = AR5K_EEPROM_FREQ_M(ee->ee_version);
1610 offset = AR5K_EEPROM_CTL(ee->ee_version);
1611 ee->ee_ctls = AR5K_EEPROM_N_CTLS(ee->ee_version);
1612 for (i = 0; i < ee->ee_ctls; i += 2) {
1613 AR5K_EEPROM_READ(offset++, val);
1614 ee->ee_ctl[i] = (val >> 8) & 0xff;
1615 ee->ee_ctl[i + 1] = val & 0xff;
1616 }
1617
1618 offset = AR5K_EEPROM_GROUP8_OFFSET;
1619 if (ee->ee_version >= AR5K_EEPROM_VERSION_4_0)
1620 offset += AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1) -
1621 AR5K_EEPROM_GROUP5_OFFSET;
1622 else
1623 offset += AR5K_EEPROM_GROUPS_START(ee->ee_version);
1624
1625 rep = ee->ee_ctl_pwr;
1626 for (i = 0; i < ee->ee_ctls; i++) {
1627 switch (ee->ee_ctl[i] & AR5K_CTL_MODE_M) {
1628 case AR5K_CTL_11A:
1629 case AR5K_CTL_TURBO:
1630 ctl_mode = AR5K_EEPROM_MODE_11A;
1631 break;
1632 default:
1633 ctl_mode = AR5K_EEPROM_MODE_11G;
1634 break;
1635 }
1636 if (ee->ee_ctl[i] == 0) {
1637 if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3)
1638 offset += 8;
1639 else
1640 offset += 7;
1641 rep += AR5K_EEPROM_N_EDGES;
1642 continue;
1643 }
1644 if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3) {
1645 for (j = 0; j < AR5K_EEPROM_N_EDGES; j += 2) {
1646 AR5K_EEPROM_READ(offset++, val);
1647 rep[j].freq = (val >> 8) & fmask;
1648 rep[j + 1].freq = val & fmask;
1649 }
1650 for (j = 0; j < AR5K_EEPROM_N_EDGES; j += 2) {
1651 AR5K_EEPROM_READ(offset++, val);
1652 rep[j].edge = (val >> 8) & pmask;
1653 rep[j].flag = (val >> 14) & 1;
1654 rep[j + 1].edge = val & pmask;
1655 rep[j + 1].flag = (val >> 6) & 1;
1656 }
1657 } else {
1658 AR5K_EEPROM_READ(offset++, val);
1659 rep[0].freq = (val >> 9) & fmask;
1660 rep[1].freq = (val >> 2) & fmask;
1661 rep[2].freq = (val << 5) & fmask;
1662
1663 AR5K_EEPROM_READ(offset++, val);
1664 rep[2].freq |= (val >> 11) & 0x1f;
1665 rep[3].freq = (val >> 4) & fmask;
1666 rep[4].freq = (val << 3) & fmask;
1667
1668 AR5K_EEPROM_READ(offset++, val);
1669 rep[4].freq |= (val >> 13) & 0x7;
1670 rep[5].freq = (val >> 6) & fmask;
1671 rep[6].freq = (val << 1) & fmask;
1672
1673 AR5K_EEPROM_READ(offset++, val);
1674 rep[6].freq |= (val >> 15) & 0x1;
1675 rep[7].freq = (val >> 8) & fmask;
1676
1677 rep[0].edge = (val >> 2) & pmask;
1678 rep[1].edge = (val << 4) & pmask;
1679
1680 AR5K_EEPROM_READ(offset++, val);
1681 rep[1].edge |= (val >> 12) & 0xf;
1682 rep[2].edge = (val >> 6) & pmask;
1683 rep[3].edge = val & pmask;
1684
1685 AR5K_EEPROM_READ(offset++, val);
1686 rep[4].edge = (val >> 10) & pmask;
1687 rep[5].edge = (val >> 4) & pmask;
1688 rep[6].edge = (val << 2) & pmask;
1689
1690 AR5K_EEPROM_READ(offset++, val);
1691 rep[6].edge |= (val >> 14) & 0x3;
1692 rep[7].edge = (val >> 8) & pmask;
1693 }
1694 for (j = 0; j < AR5K_EEPROM_N_EDGES; j++) {
1695 rep[j].freq = ath5k_eeprom_bin2freq(ee,
1696 rep[j].freq, ctl_mode);
1697 }
1698 rep += AR5K_EEPROM_N_EDGES;
1699 }
1700
1701 return 0;
1702 }
1703
1704 static int
1705 ath5k_eeprom_read_spur_chans(struct ath5k_hw *ah)
1706 {
1707 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1708 u32 offset;
1709 u16 val;
1710 int ret = 0, i;
1711
1712 offset = AR5K_EEPROM_CTL(ee->ee_version) +
1713 AR5K_EEPROM_N_CTLS(ee->ee_version);
1714
1715 if (ee->ee_version < AR5K_EEPROM_VERSION_5_3) {
1716
1717 ee->ee_spur_chans[0][0] = AR5K_EEPROM_NO_SPUR;
1718
1719 ee->ee_spur_chans[0][1] = AR5K_EEPROM_5413_SPUR_CHAN_1;
1720 ee->ee_spur_chans[1][1] = AR5K_EEPROM_5413_SPUR_CHAN_2;
1721 ee->ee_spur_chans[2][1] = AR5K_EEPROM_NO_SPUR;
1722 } else if (ee->ee_version >= AR5K_EEPROM_VERSION_5_3) {
1723 for (i = 0; i < AR5K_EEPROM_N_SPUR_CHANS; i++) {
1724 AR5K_EEPROM_READ(offset, val);
1725 ee->ee_spur_chans[i][0] = val;
1726 AR5K_EEPROM_READ(offset + AR5K_EEPROM_N_SPUR_CHANS,
1727 val);
1728 ee->ee_spur_chans[i][1] = val;
1729 offset++;
1730 }
1731 }
1732
1733 return ret;
1734 }
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744 int
1745 ath5k_eeprom_init(struct ath5k_hw *ah)
1746 {
1747 int err;
1748
1749 err = ath5k_eeprom_init_header(ah);
1750 if (err < 0)
1751 return err;
1752
1753 err = ath5k_eeprom_init_modes(ah);
1754 if (err < 0)
1755 return err;
1756
1757 err = ath5k_eeprom_read_pcal_info(ah);
1758 if (err < 0)
1759 return err;
1760
1761 err = ath5k_eeprom_read_ctl_info(ah);
1762 if (err < 0)
1763 return err;
1764
1765 err = ath5k_eeprom_read_spur_chans(ah);
1766 if (err < 0)
1767 return err;
1768
1769 return 0;
1770 }
1771
1772 void
1773 ath5k_eeprom_detach(struct ath5k_hw *ah)
1774 {
1775 u8 mode;
1776
1777 for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++)
1778 ath5k_eeprom_free_pcal_info(ah, mode);
1779 }
1780
1781 int
1782 ath5k_eeprom_mode_from_channel(struct ath5k_hw *ah,
1783 struct ieee80211_channel *channel)
1784 {
1785 switch (channel->hw_value) {
1786 case AR5K_MODE_11A:
1787 return AR5K_EEPROM_MODE_11A;
1788 case AR5K_MODE_11G:
1789 return AR5K_EEPROM_MODE_11G;
1790 case AR5K_MODE_11B:
1791 return AR5K_EEPROM_MODE_11B;
1792 default:
1793 ATH5K_WARN(ah, "channel is not A/B/G!");
1794 return AR5K_EEPROM_MODE_11A;
1795 }
1796 }