iPXE
ath5k_eeprom.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
3  * Copyright (c) 2006-2009 Nick Kossifidis <mickflemm@gmail.com>
4  * Copyright (c) 2008-2009 Felix Fietkau <nbd@openwrt.org>
5  *
6  * Lightly modified for iPXE, July 2009, by Joshua Oreman <oremanj@rwcr.net>.
7  *
8  * Permission to use, copy, modify, and distribute this software for any
9  * purpose with or without fee is hereby granted, provided that the above
10  * copyright notice and this permission notice appear in all copies.
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19  *
20  */
21 
22 FILE_LICENCE ( MIT );
23 
24 /*************************************\
25 * EEPROM access functions and helpers *
26 \*************************************/
27 
28 #include <unistd.h>
29 #include <stdlib.h>
30 
31 #include "ath5k.h"
32 #include "reg.h"
33 #include "base.h"
34 
35 /*
36  * Read from eeprom
37  */
39 {
41 
42  /* Avoid returning uninitialised data on error */
43  *data = 0xffff;
44 
45  /*
46  * Initialize EEPROM access
47  */
48  if (ah->ah_version == AR5K_AR5210) {
51  } else {
55  }
56 
61  return -EIO;
63  0xffff);
64  return 0;
65  }
66  udelay(15);
67  }
68 
69  return -ETIMEDOUT;
70 }
71 
72 /*
73  * Translate binary channel representation in EEPROM to frequency
74  */
76  unsigned int mode)
77 {
78  u16 val;
79 
80  if (bin == AR5K_EEPROM_CHANNEL_DIS)
81  return bin;
82 
83  if (mode == AR5K_EEPROM_MODE_11A) {
85  val = (5 * bin) + 4800;
86  else
87  val = bin > 62 ? (10 * 62) + (5 * (bin - 62)) + 5100 :
88  (bin * 10) + 5100;
89  } else {
91  val = bin + 2300;
92  else
93  val = bin + 2400;
94  }
95 
96  return val;
97 }
98 
99 /*
100  * Initialize eeprom & capabilities structs
101  */
102 static int
104 {
105  struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
106  int ret;
107  u16 val;
108 
109  /*
110  * Read values from EEPROM and store them in the capability structure
111  */
117 
118  /* Return if we have an old EEPROM */
119  if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_0)
120  return 0;
121 
123  ee_ant_gain);
124 
125  if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
128 
129  /* XXX: Don't know which versions include these two */
131 
134 
135  if (ee->ee_version >= AR5K_EEPROM_VERSION_5_0) {
139  }
140  }
141 
142  if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_3) {
144  ee->ee_ob[AR5K_EEPROM_MODE_11B][0] = val & 0x7;
145  ee->ee_db[AR5K_EEPROM_MODE_11B][0] = (val >> 3) & 0x7;
146 
148  ee->ee_ob[AR5K_EEPROM_MODE_11G][0] = val & 0x7;
149  ee->ee_db[AR5K_EEPROM_MODE_11G][0] = (val >> 3) & 0x7;
150  }
151 
153 
154  if ((ah->ah_mac_version == (AR5K_SREV_AR2425 >> 4)) && val)
155  ee->ee_is_hb63 = 1;
156  else
157  ee->ee_is_hb63 = 0;
158 
162 
163  return 0;
164 }
165 
166 
167 /*
168  * Read antenna infos from eeprom
169  */
171  unsigned int mode)
172 {
173  struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
174  u32 o = *offset;
175  u16 val;
176  int ret, i = 0;
177 
178  AR5K_EEPROM_READ(o++, val);
179  ee->ee_switch_settling[mode] = (val >> 8) & 0x7f;
180  ee->ee_atn_tx_rx[mode] = (val >> 2) & 0x3f;
181  ee->ee_ant_control[mode][i] = (val << 4) & 0x3f;
182 
183  AR5K_EEPROM_READ(o++, val);
184  ee->ee_ant_control[mode][i++] |= (val >> 12) & 0xf;
185  ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f;
186  ee->ee_ant_control[mode][i++] = val & 0x3f;
187 
188  AR5K_EEPROM_READ(o++, val);
189  ee->ee_ant_control[mode][i++] = (val >> 10) & 0x3f;
190  ee->ee_ant_control[mode][i++] = (val >> 4) & 0x3f;
191  ee->ee_ant_control[mode][i] = (val << 2) & 0x3f;
192 
193  AR5K_EEPROM_READ(o++, val);
194  ee->ee_ant_control[mode][i++] |= (val >> 14) & 0x3;
195  ee->ee_ant_control[mode][i++] = (val >> 8) & 0x3f;
196  ee->ee_ant_control[mode][i++] = (val >> 2) & 0x3f;
197  ee->ee_ant_control[mode][i] = (val << 4) & 0x3f;
198 
199  AR5K_EEPROM_READ(o++, val);
200  ee->ee_ant_control[mode][i++] |= (val >> 12) & 0xf;
201  ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f;
202  ee->ee_ant_control[mode][i++] = val & 0x3f;
203 
204  /* Get antenna modes */
205  ah->ah_antenna[mode][0] =
206  (ee->ee_ant_control[mode][0] << 4);
207  ah->ah_antenna[mode][AR5K_ANT_FIXED_A] =
208  ee->ee_ant_control[mode][1] |
209  (ee->ee_ant_control[mode][2] << 6) |
210  (ee->ee_ant_control[mode][3] << 12) |
211  (ee->ee_ant_control[mode][4] << 18) |
212  (ee->ee_ant_control[mode][5] << 24);
213  ah->ah_antenna[mode][AR5K_ANT_FIXED_B] =
214  ee->ee_ant_control[mode][6] |
215  (ee->ee_ant_control[mode][7] << 6) |
216  (ee->ee_ant_control[mode][8] << 12) |
217  (ee->ee_ant_control[mode][9] << 18) |
218  (ee->ee_ant_control[mode][10] << 24);
219 
220  /* return new offset */
221  *offset = o;
222 
223  return 0;
224 }
225 
226 /*
227  * Read supported modes and some mode-specific calibration data
228  * from eeprom
229  */
231  unsigned int mode)
232 {
233  struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
234  u32 o = *offset;
235  u16 val;
236  int ret;
237 
238  ee->ee_n_piers[mode] = 0;
239  AR5K_EEPROM_READ(o++, val);
240  ee->ee_adc_desired_size[mode] = (s8)((val >> 8) & 0xff);
241  switch(mode) {
243  ee->ee_ob[mode][3] = (val >> 5) & 0x7;
244  ee->ee_db[mode][3] = (val >> 2) & 0x7;
245  ee->ee_ob[mode][2] = (val << 1) & 0x7;
246 
247  AR5K_EEPROM_READ(o++, val);
248  ee->ee_ob[mode][2] |= (val >> 15) & 0x1;
249  ee->ee_db[mode][2] = (val >> 12) & 0x7;
250  ee->ee_ob[mode][1] = (val >> 9) & 0x7;
251  ee->ee_db[mode][1] = (val >> 6) & 0x7;
252  ee->ee_ob[mode][0] = (val >> 3) & 0x7;
253  ee->ee_db[mode][0] = val & 0x7;
254  break;
257  ee->ee_ob[mode][1] = (val >> 4) & 0x7;
258  ee->ee_db[mode][1] = val & 0x7;
259  break;
260  }
261 
262  AR5K_EEPROM_READ(o++, val);
263  ee->ee_tx_end2xlna_enable[mode] = (val >> 8) & 0xff;
264  ee->ee_thr_62[mode] = val & 0xff;
265 
266  if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2)
267  ee->ee_thr_62[mode] = mode == AR5K_EEPROM_MODE_11A ? 15 : 28;
268 
269  AR5K_EEPROM_READ(o++, val);
270  ee->ee_tx_end2xpa_disable[mode] = (val >> 8) & 0xff;
271  ee->ee_tx_frm2xpa_enable[mode] = val & 0xff;
272 
273  AR5K_EEPROM_READ(o++, val);
274  ee->ee_pga_desired_size[mode] = (val >> 8) & 0xff;
275 
276  if ((val & 0xff) & 0x80)
277  ee->ee_noise_floor_thr[mode] = -((((val & 0xff) ^ 0xff)) + 1);
278  else
279  ee->ee_noise_floor_thr[mode] = val & 0xff;
280 
281  if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2)
282  ee->ee_noise_floor_thr[mode] =
283  mode == AR5K_EEPROM_MODE_11A ? -54 : -1;
284 
285  AR5K_EEPROM_READ(o++, val);
286  ee->ee_xlna_gain[mode] = (val >> 5) & 0xff;
287  ee->ee_x_gain[mode] = (val >> 1) & 0xf;
288  ee->ee_xpd[mode] = val & 0x1;
289 
290  if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0)
291  ee->ee_fixed_bias[mode] = (val >> 13) & 0x1;
292 
293  if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_3) {
294  AR5K_EEPROM_READ(o++, val);
295  ee->ee_false_detect[mode] = (val >> 6) & 0x7f;
296 
297  if (mode == AR5K_EEPROM_MODE_11A)
298  ee->ee_xr_power[mode] = val & 0x3f;
299  else {
300  ee->ee_ob[mode][0] = val & 0x7;
301  ee->ee_db[mode][0] = (val >> 3) & 0x7;
302  }
303  }
304 
305  if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_4) {
306  ee->ee_i_gain[mode] = AR5K_EEPROM_I_GAIN;
308  } else {
309  ee->ee_i_gain[mode] = (val >> 13) & 0x7;
310 
311  AR5K_EEPROM_READ(o++, val);
312  ee->ee_i_gain[mode] |= (val << 3) & 0x38;
313 
314  if (mode == AR5K_EEPROM_MODE_11G) {
315  ee->ee_cck_ofdm_power_delta = (val >> 3) & 0xff;
316  if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_6)
317  ee->ee_scaled_cck_delta = (val >> 11) & 0x1f;
318  }
319  }
320 
321  if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0 &&
322  mode == AR5K_EEPROM_MODE_11A) {
323  ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
324  ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
325  }
326 
327  if (ah->ah_ee_version < AR5K_EEPROM_VERSION_4_0)
328  goto done;
329 
330  /* Note: >= v5 have bg freq piers on another location
331  * so these freq piers are ignored for >= v5 (should be 0xff
332  * anyway) */
333  switch(mode) {
335  if (ah->ah_ee_version < AR5K_EEPROM_VERSION_4_1)
336  break;
337 
338  AR5K_EEPROM_READ(o++, val);
339  ee->ee_margin_tx_rx[mode] = val & 0x3f;
340  break;
342  AR5K_EEPROM_READ(o++, val);
343 
344  ee->ee_pwr_cal_b[0].freq =
345  ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
347  ee->ee_n_piers[mode]++;
348 
349  ee->ee_pwr_cal_b[1].freq =
350  ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode);
352  ee->ee_n_piers[mode]++;
353 
354  AR5K_EEPROM_READ(o++, val);
355  ee->ee_pwr_cal_b[2].freq =
356  ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
358  ee->ee_n_piers[mode]++;
359 
360  if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
361  ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
362  break;
364  AR5K_EEPROM_READ(o++, val);
365 
366  ee->ee_pwr_cal_g[0].freq =
367  ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
369  ee->ee_n_piers[mode]++;
370 
371  ee->ee_pwr_cal_g[1].freq =
372  ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode);
374  ee->ee_n_piers[mode]++;
375 
376  AR5K_EEPROM_READ(o++, val);
377  ee->ee_turbo_max_power[mode] = val & 0x7f;
378  ee->ee_xr_power[mode] = (val >> 7) & 0x3f;
379 
380  AR5K_EEPROM_READ(o++, val);
381  ee->ee_pwr_cal_g[2].freq =
382  ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
384  ee->ee_n_piers[mode]++;
385 
386  if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
387  ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
388 
389  AR5K_EEPROM_READ(o++, val);
390  ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
391  ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
392 
393  if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_2) {
394  AR5K_EEPROM_READ(o++, val);
395  ee->ee_cck_ofdm_gain_delta = val & 0xff;
396  }
397  break;
398  }
399 
400 done:
401  /* return new offset */
402  *offset = o;
403 
404  return 0;
405 }
406 
407 /*
408  * Read turbo mode information on newer EEPROM versions
409  */
410 static int
412  u32 *offset, unsigned int mode)
413 {
414  struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
415  u32 o = *offset;
416  u16 val;
417  int ret;
418 
420  return 0;
421 
422  AR5K_EEPROM_READ(o++, val);
423  switch (mode){
425  ee->ee_switch_settling_turbo[mode] = (val >> 6) & 0x7f;
426 
427  ee->ee_atn_tx_rx_turbo[mode] = (val >> 13) & 0x7;
428  AR5K_EEPROM_READ(o++, val);
429  ee->ee_atn_tx_rx_turbo[mode] |= (val & 0x7) << 3;
430  ee->ee_margin_tx_rx_turbo[mode] = (val >> 3) & 0x3f;
431 
432  ee->ee_adc_desired_size_turbo[mode] = (val >> 9) & 0x7f;
433  AR5K_EEPROM_READ(o++, val);
434  ee->ee_adc_desired_size_turbo[mode] |= (val & 0x1) << 7;
435  ee->ee_pga_desired_size_turbo[mode] = (val >> 1) & 0xff;
436 
437  if (AR5K_EEPROM_EEMAP(ee->ee_misc0) >=2)
438  ee->ee_pd_gain_overlap = (val >> 9) & 0xf;
439  break;
441  ee->ee_switch_settling_turbo[mode] = (val >> 8) & 0x7f;
442 
443  ee->ee_atn_tx_rx_turbo[mode] = (val >> 15) & 0x7;
444  AR5K_EEPROM_READ(o++, val);
445  ee->ee_atn_tx_rx_turbo[mode] |= (val & 0x1f) << 1;
446  ee->ee_margin_tx_rx_turbo[mode] = (val >> 5) & 0x3f;
447 
448  ee->ee_adc_desired_size_turbo[mode] = (val >> 11) & 0x7f;
449  AR5K_EEPROM_READ(o++, val);
450  ee->ee_adc_desired_size_turbo[mode] |= (val & 0x7) << 5;
451  ee->ee_pga_desired_size_turbo[mode] = (val >> 3) & 0xff;
452  break;
453  }
454 
455  /* return new offset */
456  *offset = o;
457 
458  return 0;
459 }
460 
461 /* Read mode-specific data (except power calibration data) */
462 static int
464 {
465  struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
466  u32 mode_offset[3];
467  unsigned int mode;
468  u32 offset;
469  int ret;
470 
471  /*
472  * Get values for all modes
473  */
474  mode_offset[AR5K_EEPROM_MODE_11A] = AR5K_EEPROM_MODES_11A(ah->ah_ee_version);
475  mode_offset[AR5K_EEPROM_MODE_11B] = AR5K_EEPROM_MODES_11B(ah->ah_ee_version);
476  mode_offset[AR5K_EEPROM_MODE_11G] = AR5K_EEPROM_MODES_11G(ah->ah_ee_version);
477 
480 
481  for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++) {
482  offset = mode_offset[mode];
483 
484  ret = ath5k_eeprom_read_ants(ah, &offset, mode);
485  if (ret)
486  return ret;
487 
488  ret = ath5k_eeprom_read_modes(ah, &offset, mode);
489  if (ret)
490  return ret;
491 
492  ret = ath5k_eeprom_read_turbo_modes(ah, &offset, mode);
493  if (ret)
494  return ret;
495  }
496 
497  /* override for older eeprom versions for better performance */
498  if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2) {
502  }
503 
504  return 0;
505 }
506 
507 /* Read the frequency piers for each mode (mostly used on newer eeproms with 0xff
508  * frequency mask) */
509 static inline int
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  int ret;
518  u16 val;
519 
520  ee->ee_n_piers[mode] = 0;
521  while(i < max) {
522  AR5K_EEPROM_READ(o++, val);
523 
524  freq1 = val & 0xff;
525  if (!freq1)
526  break;
527 
528  pc[i++].freq = ath5k_eeprom_bin2freq(ee,
529  freq1, mode);
530  ee->ee_n_piers[mode]++;
531 
532  freq2 = (val >> 8) & 0xff;
533  if (!freq2)
534  break;
535 
536  pc[i++].freq = ath5k_eeprom_bin2freq(ee,
537  freq2, mode);
538  ee->ee_n_piers[mode]++;
539  }
540 
541  /* return new offset */
542  *offset = o;
543 
544  return 0;
545 }
546 
547 /* Read frequency piers for 802.11a */
548 static int
550 {
551  struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
552  struct ath5k_chan_pcal_info *pcal = ee->ee_pwr_cal_a;
553  int i, ret;
554  u16 val;
555  u8 mask;
556 
557  if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3) {
561  } else {
562  mask = AR5K_EEPROM_FREQ_M(ah->ah_ee_version);
563 
565  pcal[0].freq = (val >> 9) & mask;
566  pcal[1].freq = (val >> 2) & mask;
567  pcal[2].freq = (val << 5) & mask;
568 
570  pcal[2].freq |= (val >> 11) & 0x1f;
571  pcal[3].freq = (val >> 4) & mask;
572  pcal[4].freq = (val << 3) & mask;
573 
575  pcal[4].freq |= (val >> 13) & 0x7;
576  pcal[5].freq = (val >> 6) & mask;
577  pcal[6].freq = (val << 1) & mask;
578 
580  pcal[6].freq |= (val >> 15) & 0x1;
581  pcal[7].freq = (val >> 8) & mask;
582  pcal[8].freq = (val >> 1) & mask;
583  pcal[9].freq = (val << 6) & mask;
584 
586  pcal[9].freq |= (val >> 10) & 0x3f;
587 
588  /* Fixed number of piers */
590 
591  for (i = 0; i < AR5K_EEPROM_N_5GHZ_CHAN; i++) {
592  pcal[i].freq = ath5k_eeprom_bin2freq(ee,
593  pcal[i].freq, AR5K_EEPROM_MODE_11A);
594  }
595  }
596 
597  return 0;
598 }
599 
600 /* Read frequency piers for 802.11bg on eeprom versions >= 5 and eemap >= 2 */
601 static inline int
602 ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset)
603 {
604  struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
605  struct ath5k_chan_pcal_info *pcal;
606 
607  switch(mode) {
609  pcal = ee->ee_pwr_cal_b;
610  break;
612  pcal = ee->ee_pwr_cal_g;
613  break;
614  default:
615  return -EINVAL;
616  }
617 
620  mode);
621 
622  return 0;
623 }
624 
625 /*
626  * Read power calibration for RF5111 chips
627  *
628  * For RF5111 we have an XPD -eXternal Power Detector- curve
629  * for each calibrated channel. Each curve has 0,5dB Power steps
630  * on x axis and PCDAC steps (offsets) on y axis and looks like an
631  * exponential function. To recreate the curve we read 11 points
632  * here and interpolate later.
633  */
634 
635 /* Used to match PCDAC steps with power values on RF5111 chips
636  * (eeprom versions < 4). For RF5111 we have 11 pre-defined PCDAC
637  * steps that match with the power values we read from eeprom. On
638  * older eeprom versions (< 3.2) these steps are equaly spaced at
639  * 10% of the pcdac curve -until the curve reaches it's maximum-
640  * (11 steps from 0 to 100%) but on newer eeprom versions (>= 3.2)
641  * these 11 steps are spaced in a different way. This function returns
642  * the pcdac steps based on eeprom version and curve min/max so that we
643  * can have pcdac/pwr points.
644  */
645 static inline void
647 {
648  static const u16 intercepts3[] =
649  { 0, 5, 10, 20, 30, 50, 70, 85, 90, 95, 100 };
650  static const u16 intercepts3_2[] =
651  { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 };
652  const u16 *ip;
653  unsigned i;
654 
655  if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_2)
656  ip = intercepts3_2;
657  else
658  ip = intercepts3;
659 
660  for (i = 0; i < ARRAY_SIZE(intercepts3); i++)
661  vp[i] = (ip[i] * max + (100 - ip[i]) * min) / 100;
662 }
663 
664 /* Convert RF5111 specific data to generic raw data
665  * used by interpolation code */
666 static int
668  struct ath5k_chan_pcal_info *chinfo)
669 {
670  struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
671  struct ath5k_chan_pcal_info_rf5111 *pcinfo;
672  struct ath5k_pdgain_info *pd;
673  u8 pier, point, idx;
674  u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
675 
676  /* Fill raw data for each calibration pier */
677  for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
678 
679  pcinfo = &chinfo[pier].rf5111_info;
680 
681  /* Allocate pd_curves for this cal pier */
682  chinfo[pier].pd_curves =
684  sizeof(struct ath5k_pdgain_info));
685 
686  if (!chinfo[pier].pd_curves)
687  return -ENOMEM;
688 
689  /* Only one curve for RF5111
690  * find out which one and place
691  * in in pd_curves.
692  * Note: ee_x_gain is reversed here */
693  for (idx = 0; idx < AR5K_EEPROM_N_PD_CURVES; idx++) {
694 
695  if (!((ee->ee_x_gain[mode] >> idx) & 0x1)) {
696  pdgain_idx[0] = idx;
697  break;
698  }
699  }
700 
701  ee->ee_pd_gains[mode] = 1;
702 
703  pd = &chinfo[pier].pd_curves[idx];
704 
706 
707  /* Allocate pd points for this curve */
709  if (!pd->pd_step)
710  return -ENOMEM;
711 
713  if (!pd->pd_pwr)
714  return -ENOMEM;
715 
716  /* Fill raw dataset
717  * (convert power to 0.25dB units
718  * for RF5112 combatibility) */
719  for (point = 0; point < pd->pd_points; point++) {
720 
721  /* Absolute values */
722  pd->pd_pwr[point] = 2 * pcinfo->pwr[point];
723 
724  /* Already sorted */
725  pd->pd_step[point] = pcinfo->pcdac[point];
726  }
727 
728  /* Set min/max pwr */
729  chinfo[pier].min_pwr = pd->pd_pwr[0];
730  chinfo[pier].max_pwr = pd->pd_pwr[10];
731 
732  }
733 
734  return 0;
735 }
736 
737 /* Parse EEPROM data */
738 static int
740 {
741  struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
742  struct ath5k_chan_pcal_info *pcal;
743  int offset, ret;
744  int i;
745  u16 val;
746 
748  switch(mode) {
750  if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
751  return 0;
752 
755  if (ret < 0)
756  return ret;
757 
759  pcal = ee->ee_pwr_cal_a;
760  break;
762  if (!AR5K_EEPROM_HDR_11B(ee->ee_header) &&
764  return 0;
765 
766  pcal = ee->ee_pwr_cal_b;
768 
769  /* fixed piers */
770  pcal[0].freq = 2412;
771  pcal[1].freq = 2447;
772  pcal[2].freq = 2484;
773  ee->ee_n_piers[mode] = 3;
774  break;
776  if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
777  return 0;
778 
779  pcal = ee->ee_pwr_cal_g;
781 
782  /* fixed piers */
783  pcal[0].freq = 2312;
784  pcal[1].freq = 2412;
785  pcal[2].freq = 2484;
786  ee->ee_n_piers[mode] = 3;
787  break;
788  default:
789  return -EINVAL;
790  }
791 
792  for (i = 0; i < ee->ee_n_piers[mode]; i++) {
793  struct ath5k_chan_pcal_info_rf5111 *cdata =
794  &pcal[i].rf5111_info;
795 
797  cdata->pcdac_max = ((val >> 10) & AR5K_EEPROM_PCDAC_M);
798  cdata->pcdac_min = ((val >> 4) & AR5K_EEPROM_PCDAC_M);
799  cdata->pwr[0] = ((val << 2) & AR5K_EEPROM_POWER_M);
800 
802  cdata->pwr[0] |= ((val >> 14) & 0x3);
803  cdata->pwr[1] = ((val >> 8) & AR5K_EEPROM_POWER_M);
804  cdata->pwr[2] = ((val >> 2) & AR5K_EEPROM_POWER_M);
805  cdata->pwr[3] = ((val << 4) & AR5K_EEPROM_POWER_M);
806 
808  cdata->pwr[3] |= ((val >> 12) & 0xf);
809  cdata->pwr[4] = ((val >> 6) & AR5K_EEPROM_POWER_M);
810  cdata->pwr[5] = (val & AR5K_EEPROM_POWER_M);
811 
813  cdata->pwr[6] = ((val >> 10) & AR5K_EEPROM_POWER_M);
814  cdata->pwr[7] = ((val >> 4) & AR5K_EEPROM_POWER_M);
815  cdata->pwr[8] = ((val << 2) & AR5K_EEPROM_POWER_M);
816 
818  cdata->pwr[8] |= ((val >> 14) & 0x3);
819  cdata->pwr[9] = ((val >> 8) & AR5K_EEPROM_POWER_M);
820  cdata->pwr[10] = ((val >> 2) & AR5K_EEPROM_POWER_M);
821 
823  cdata->pcdac_max, cdata->pcdac);
824  }
825 
826  return ath5k_eeprom_convert_pcal_info_5111(ah, mode, pcal);
827 }
828 
829 
830 /*
831  * Read power calibration for RF5112 chips
832  *
833  * For RF5112 we have 4 XPD -eXternal Power Detector- curves
834  * for each calibrated channel on 0, -6, -12 and -18dbm but we only
835  * use the higher (3) and the lower (0) curves. Each curve has 0.5dB
836  * power steps on x axis and PCDAC steps on y axis and looks like a
837  * linear function. To recreate the curve and pass the power values
838  * on hw, we read 4 points for xpd 0 (lower gain -> max power)
839  * and 3 points for xpd 3 (higher gain -> lower power) here and
840  * interpolate later.
841  *
842  * Note: Many vendors just use xpd 0 so xpd 3 is zeroed.
843  */
844 
845 /* Convert RF5112 specific data to generic raw data
846  * used by interpolation code */
847 static int
849  struct ath5k_chan_pcal_info *chinfo)
850 {
851  struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
852  struct ath5k_chan_pcal_info_rf5112 *pcinfo;
853  u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
854  unsigned int pier, pdg, point;
855 
856  /* Fill raw data for each calibration pier */
857  for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
858 
859  pcinfo = &chinfo[pier].rf5112_info;
860 
861  /* Allocate pd_curves for this cal pier */
862  chinfo[pier].pd_curves =
864  sizeof(struct ath5k_pdgain_info));
865 
866  if (!chinfo[pier].pd_curves)
867  return -ENOMEM;
868 
869  /* Fill pd_curves */
870  for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
871 
872  u8 idx = pdgain_idx[pdg];
873  struct ath5k_pdgain_info *pd =
874  &chinfo[pier].pd_curves[idx];
875 
876  /* Lowest gain curve (max power) */
877  if (pdg == 0) {
878  /* One more point for better accuracy */
880 
881  /* Allocate pd points for this curve */
882  pd->pd_step = calloc(pd->pd_points, sizeof(u8));
883 
884  if (!pd->pd_step)
885  return -ENOMEM;
886 
887  pd->pd_pwr = calloc(pd->pd_points, sizeof(s16));
888 
889  if (!pd->pd_pwr)
890  return -ENOMEM;
891 
892 
893  /* Fill raw dataset
894  * (all power levels are in 0.25dB units) */
895  pd->pd_step[0] = pcinfo->pcdac_x0[0];
896  pd->pd_pwr[0] = pcinfo->pwr_x0[0];
897 
898  for (point = 1; point < pd->pd_points;
899  point++) {
900  /* Absolute values */
901  pd->pd_pwr[point] =
902  pcinfo->pwr_x0[point];
903 
904  /* Deltas */
905  pd->pd_step[point] =
906  pd->pd_step[point - 1] +
907  pcinfo->pcdac_x0[point];
908  }
909 
910  /* Set min power for this frequency */
911  chinfo[pier].min_pwr = pd->pd_pwr[0];
912 
913  /* Highest gain curve (min power) */
914  } else if (pdg == 1) {
915 
917 
918  /* Allocate pd points for this curve */
919  pd->pd_step = calloc(pd->pd_points, sizeof(u8));
920 
921  if (!pd->pd_step)
922  return -ENOMEM;
923 
924  pd->pd_pwr = calloc(pd->pd_points, sizeof(s16));
925 
926  if (!pd->pd_pwr)
927  return -ENOMEM;
928 
929  /* Fill raw dataset
930  * (all power levels are in 0.25dB units) */
931  for (point = 0; point < pd->pd_points;
932  point++) {
933  /* Absolute values */
934  pd->pd_pwr[point] =
935  pcinfo->pwr_x3[point];
936 
937  /* Fixed points */
938  pd->pd_step[point] =
939  pcinfo->pcdac_x3[point];
940  }
941 
942  /* Since we have a higher gain curve
943  * override min power */
944  chinfo[pier].min_pwr = pd->pd_pwr[0];
945  }
946  }
947  }
948 
949  return 0;
950 }
951 
952 /* Parse EEPROM data */
953 static int
955 {
956  struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
957  struct ath5k_chan_pcal_info_rf5112 *chan_pcal_info;
958  struct ath5k_chan_pcal_info *gen_chan_info;
959  u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
960  u32 offset;
961  u8 i, c;
962  u16 val;
963  int ret;
964  u8 pd_gains = 0;
965 
966  /* Count how many curves we have and
967  * identify them (which one of the 4
968  * available curves we have on each count).
969  * Curves are stored from lower (x0) to
970  * higher (x3) gain */
971  for (i = 0; i < AR5K_EEPROM_N_PD_CURVES; i++) {
972  /* ee_x_gain[mode] is x gain mask */
973  if ((ee->ee_x_gain[mode] >> i) & 0x1)
974  pdgain_idx[pd_gains++] = i;
975  }
976  ee->ee_pd_gains[mode] = pd_gains;
977 
978  if (pd_gains == 0 || pd_gains > 2)
979  return -EINVAL;
980 
981  switch (mode) {
983  /*
984  * Read 5GHz EEPROM channels
985  */
988 
990  gen_chan_info = ee->ee_pwr_cal_a;
991  break;
996 
997  /* NB: frequency piers parsed during mode init */
998  gen_chan_info = ee->ee_pwr_cal_b;
999  break;
1000  case AR5K_EEPROM_MODE_11G:
1002  if (AR5K_EEPROM_HDR_11A(ee->ee_header))
1004  else if (AR5K_EEPROM_HDR_11B(ee->ee_header))
1006 
1007  /* NB: frequency piers parsed during mode init */
1008  gen_chan_info = ee->ee_pwr_cal_g;
1009  break;
1010  default:
1011  return -EINVAL;
1012  }
1013 
1014  for (i = 0; i < ee->ee_n_piers[mode]; i++) {
1015  chan_pcal_info = &gen_chan_info[i].rf5112_info;
1016 
1017  /* Power values in quarter dB
1018  * for the lower xpd gain curve
1019  * (0 dBm -> higher output power) */
1020  for (c = 0; c < AR5K_EEPROM_N_XPD0_POINTS; c++) {
1022  chan_pcal_info->pwr_x0[c] = (s8) (val & 0xff);
1023  chan_pcal_info->pwr_x0[++c] = (s8) ((val >> 8) & 0xff);
1024  }
1025 
1026  /* PCDAC steps
1027  * corresponding to the above power
1028  * measurements */
1030  chan_pcal_info->pcdac_x0[1] = (val & 0x1f);
1031  chan_pcal_info->pcdac_x0[2] = ((val >> 5) & 0x1f);
1032  chan_pcal_info->pcdac_x0[3] = ((val >> 10) & 0x1f);
1033 
1034  /* Power values in quarter dB
1035  * for the higher xpd gain curve
1036  * (18 dBm -> lower output power) */
1038  chan_pcal_info->pwr_x3[0] = (s8) (val & 0xff);
1039  chan_pcal_info->pwr_x3[1] = (s8) ((val >> 8) & 0xff);
1040 
1042  chan_pcal_info->pwr_x3[2] = (val & 0xff);
1043 
1044  /* PCDAC steps
1045  * corresponding to the above power
1046  * measurements (fixed) */
1047  chan_pcal_info->pcdac_x3[0] = 20;
1048  chan_pcal_info->pcdac_x3[1] = 35;
1049  chan_pcal_info->pcdac_x3[2] = 63;
1050 
1051  if (ee->ee_version >= AR5K_EEPROM_VERSION_4_3) {
1052  chan_pcal_info->pcdac_x0[0] = ((val >> 8) & 0x3f);
1053 
1054  /* Last xpd0 power level is also channel maximum */
1055  gen_chan_info[i].max_pwr = chan_pcal_info->pwr_x0[3];
1056  } else {
1057  chan_pcal_info->pcdac_x0[0] = 1;
1058  gen_chan_info[i].max_pwr = (s8) ((val >> 8) & 0xff);
1059  }
1060 
1061  }
1062 
1063  return ath5k_eeprom_convert_pcal_info_5112(ah, mode, gen_chan_info);
1064 }
1065 
1066 
1067 /*
1068  * Read power calibration for RF2413 chips
1069  *
1070  * For RF2413 we have a Power to PDDAC table (Power Detector)
1071  * instead of a PCDAC and 4 pd gain curves for each calibrated channel.
1072  * Each curve has power on x axis in 0.5 db steps and PDDADC steps on y
1073  * axis and looks like an exponential function like the RF5111 curve.
1074  *
1075  * To recreate the curves we read here the points and interpolate
1076  * later. Note that in most cases only 2 (higher and lower) curves are
1077  * used (like RF5112) but vendors have the oportunity to include all
1078  * 4 curves on eeprom. The final curve (higher power) has an extra
1079  * point for better accuracy like RF5112.
1080  */
1081 
1082 /* For RF2413 power calibration data doesn't start on a fixed location and
1083  * if a mode is not supported, it's section is missing -not zeroed-.
1084  * So we need to calculate the starting offset for each section by using
1085  * these two functions */
1086 
1087 /* Return the size of each section based on the mode and the number of pd
1088  * gains available (maximum 4). */
1089 static inline unsigned int
1090 ath5k_pdgains_size_2413(struct ath5k_eeprom_info *ee, unsigned int mode)
1091 {
1092  static const unsigned int pdgains_size[] = { 4, 6, 9, 12 };
1093  unsigned int sz;
1094 
1095  sz = pdgains_size[ee->ee_pd_gains[mode] - 1];
1096  sz *= ee->ee_n_piers[mode];
1097 
1098  return sz;
1099 }
1100 
1101 /* Return the starting offset for a section based on the modes supported
1102  * and each section's size. */
1103 static unsigned int
1105 {
1107 
1108  switch(mode) {
1109  case AR5K_EEPROM_MODE_11G:
1110  if (AR5K_EEPROM_HDR_11B(ee->ee_header))
1114  /* fall through */
1115  case AR5K_EEPROM_MODE_11B:
1116  if (AR5K_EEPROM_HDR_11A(ee->ee_header))
1120  /* fall through */
1121  case AR5K_EEPROM_MODE_11A:
1122  break;
1123  default:
1124  break;
1125  }
1126 
1127  return offset;
1128 }
1129 
1130 /* Convert RF2413 specific data to generic raw data
1131  * used by interpolation code */
1132 static int
1134  struct ath5k_chan_pcal_info *chinfo)
1135 {
1136  struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1137  struct ath5k_chan_pcal_info_rf2413 *pcinfo;
1138  u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
1139  unsigned int pier, point;
1140  int pdg;
1141 
1142  /* Fill raw data for each calibration pier */
1143  for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
1144 
1145  pcinfo = &chinfo[pier].rf2413_info;
1146 
1147  /* Allocate pd_curves for this cal pier */
1148  chinfo[pier].pd_curves =
1150  sizeof(struct ath5k_pdgain_info));
1151 
1152  if (!chinfo[pier].pd_curves)
1153  return -ENOMEM;
1154 
1155  /* Fill pd_curves */
1156  for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
1157 
1158  u8 idx = pdgain_idx[pdg];
1159  struct ath5k_pdgain_info *pd =
1160  &chinfo[pier].pd_curves[idx];
1161 
1162  /* One more point for the highest power
1163  * curve (lowest gain) */
1164  if (pdg == ee->ee_pd_gains[mode] - 1)
1166  else
1168 
1169  /* Allocate pd points for this curve */
1170  pd->pd_step = calloc(pd->pd_points, sizeof(u8));
1171 
1172  if (!pd->pd_step)
1173  return -ENOMEM;
1174 
1175  pd->pd_pwr = calloc(pd->pd_points, sizeof(s16));
1176 
1177  if (!pd->pd_pwr)
1178  return -ENOMEM;
1179 
1180  /* Fill raw dataset
1181  * convert all pwr levels to
1182  * quarter dB for RF5112 combatibility */
1183  pd->pd_step[0] = pcinfo->pddac_i[pdg];
1184  pd->pd_pwr[0] = 4 * pcinfo->pwr_i[pdg];
1185 
1186  for (point = 1; point < pd->pd_points; point++) {
1187 
1188  pd->pd_pwr[point] = pd->pd_pwr[point - 1] +
1189  2 * pcinfo->pwr[pdg][point - 1];
1190 
1191  pd->pd_step[point] = pd->pd_step[point - 1] +
1192  pcinfo->pddac[pdg][point - 1];
1193 
1194  }
1195 
1196  /* Highest gain curve -> min power */
1197  if (pdg == 0)
1198  chinfo[pier].min_pwr = pd->pd_pwr[0];
1199 
1200  /* Lowest gain curve -> max power */
1201  if (pdg == ee->ee_pd_gains[mode] - 1)
1202  chinfo[pier].max_pwr =
1203  pd->pd_pwr[pd->pd_points - 1];
1204  }
1205  }
1206 
1207  return 0;
1208 }
1209 
1210 /* Parse EEPROM data */
1211 static int
1213 {
1214  struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1215  struct ath5k_chan_pcal_info_rf2413 *pcinfo;
1216  struct ath5k_chan_pcal_info *chinfo;
1217  u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
1218  u32 offset;
1219  int idx, i, ret;
1220  u16 val;
1221  u8 pd_gains = 0;
1222 
1223  /* Count how many curves we have and
1224  * identify them (which one of the 4
1225  * available curves we have on each count).
1226  * Curves are stored from higher to
1227  * lower gain so we go backwards */
1228  for (idx = AR5K_EEPROM_N_PD_CURVES - 1; idx >= 0; idx--) {
1229  /* ee_x_gain[mode] is x gain mask */
1230  if ((ee->ee_x_gain[mode] >> idx) & 0x1)
1231  pdgain_idx[pd_gains++] = idx;
1232 
1233  }
1234  ee->ee_pd_gains[mode] = pd_gains;
1235 
1236  if (pd_gains == 0)
1237  return -EINVAL;
1238 
1239  offset = ath5k_cal_data_offset_2413(ee, mode);
1240  switch (mode) {
1241  case AR5K_EEPROM_MODE_11A:
1242  if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
1243  return 0;
1244 
1247  chinfo = ee->ee_pwr_cal_a;
1248  break;
1249  case AR5K_EEPROM_MODE_11B:
1250  if (!AR5K_EEPROM_HDR_11B(ee->ee_header))
1251  return 0;
1252 
1255  chinfo = ee->ee_pwr_cal_b;
1256  break;
1257  case AR5K_EEPROM_MODE_11G:
1258  if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
1259  return 0;
1260 
1263  chinfo = ee->ee_pwr_cal_g;
1264  break;
1265  default:
1266  return -EINVAL;
1267  }
1268 
1269  for (i = 0; i < ee->ee_n_piers[mode]; i++) {
1270  pcinfo = &chinfo[i].rf2413_info;
1271 
1272  /*
1273  * Read pwr_i, pddac_i and the first
1274  * 2 pd points (pwr, pddac)
1275  */
1277  pcinfo->pwr_i[0] = val & 0x1f;
1278  pcinfo->pddac_i[0] = (val >> 5) & 0x7f;
1279  pcinfo->pwr[0][0] = (val >> 12) & 0xf;
1280 
1282  pcinfo->pddac[0][0] = val & 0x3f;
1283  pcinfo->pwr[0][1] = (val >> 6) & 0xf;
1284  pcinfo->pddac[0][1] = (val >> 10) & 0x3f;
1285 
1287  pcinfo->pwr[0][2] = val & 0xf;
1288  pcinfo->pddac[0][2] = (val >> 4) & 0x3f;
1289 
1290  pcinfo->pwr[0][3] = 0;
1291  pcinfo->pddac[0][3] = 0;
1292 
1293  if (pd_gains > 1) {
1294  /*
1295  * Pd gain 0 is not the last pd gain
1296  * so it only has 2 pd points.
1297  * Continue wih pd gain 1.
1298  */
1299  pcinfo->pwr_i[1] = (val >> 10) & 0x1f;
1300 
1301  pcinfo->pddac_i[1] = (val >> 15) & 0x1;
1303  pcinfo->pddac_i[1] |= (val & 0x3F) << 1;
1304 
1305  pcinfo->pwr[1][0] = (val >> 6) & 0xf;
1306  pcinfo->pddac[1][0] = (val >> 10) & 0x3f;
1307 
1309  pcinfo->pwr[1][1] = val & 0xf;
1310  pcinfo->pddac[1][1] = (val >> 4) & 0x3f;
1311  pcinfo->pwr[1][2] = (val >> 10) & 0xf;
1312 
1313  pcinfo->pddac[1][2] = (val >> 14) & 0x3;
1315  pcinfo->pddac[1][2] |= (val & 0xF) << 2;
1316 
1317  pcinfo->pwr[1][3] = 0;
1318  pcinfo->pddac[1][3] = 0;
1319  } else if (pd_gains == 1) {
1320  /*
1321  * Pd gain 0 is the last one so
1322  * read the extra point.
1323  */
1324  pcinfo->pwr[0][3] = (val >> 10) & 0xf;
1325 
1326  pcinfo->pddac[0][3] = (val >> 14) & 0x3;
1328  pcinfo->pddac[0][3] |= (val & 0xF) << 2;
1329  }
1330 
1331  /*
1332  * Proceed with the other pd_gains
1333  * as above.
1334  */
1335  if (pd_gains > 2) {
1336  pcinfo->pwr_i[2] = (val >> 4) & 0x1f;
1337  pcinfo->pddac_i[2] = (val >> 9) & 0x7f;
1338 
1340  pcinfo->pwr[2][0] = (val >> 0) & 0xf;
1341  pcinfo->pddac[2][0] = (val >> 4) & 0x3f;
1342  pcinfo->pwr[2][1] = (val >> 10) & 0xf;
1343 
1344  pcinfo->pddac[2][1] = (val >> 14) & 0x3;
1346  pcinfo->pddac[2][1] |= (val & 0xF) << 2;
1347 
1348  pcinfo->pwr[2][2] = (val >> 4) & 0xf;
1349  pcinfo->pddac[2][2] = (val >> 8) & 0x3f;
1350 
1351  pcinfo->pwr[2][3] = 0;
1352  pcinfo->pddac[2][3] = 0;
1353  } else if (pd_gains == 2) {
1354  pcinfo->pwr[1][3] = (val >> 4) & 0xf;
1355  pcinfo->pddac[1][3] = (val >> 8) & 0x3f;
1356  }
1357 
1358  if (pd_gains > 3) {
1359  pcinfo->pwr_i[3] = (val >> 14) & 0x3;
1361  pcinfo->pwr_i[3] |= ((val >> 0) & 0x7) << 2;
1362 
1363  pcinfo->pddac_i[3] = (val >> 3) & 0x7f;
1364  pcinfo->pwr[3][0] = (val >> 10) & 0xf;
1365  pcinfo->pddac[3][0] = (val >> 14) & 0x3;
1366 
1368  pcinfo->pddac[3][0] |= (val & 0xF) << 2;
1369  pcinfo->pwr[3][1] = (val >> 4) & 0xf;
1370  pcinfo->pddac[3][1] = (val >> 8) & 0x3f;
1371 
1372  pcinfo->pwr[3][2] = (val >> 14) & 0x3;
1374  pcinfo->pwr[3][2] |= ((val >> 0) & 0x3) << 2;
1375 
1376  pcinfo->pddac[3][2] = (val >> 2) & 0x3f;
1377  pcinfo->pwr[3][3] = (val >> 8) & 0xf;
1378 
1379  pcinfo->pddac[3][3] = (val >> 12) & 0xF;
1381  pcinfo->pddac[3][3] |= ((val >> 0) & 0x3) << 4;
1382  } else if (pd_gains == 3) {
1383  pcinfo->pwr[2][3] = (val >> 14) & 0x3;
1385  pcinfo->pwr[2][3] |= ((val >> 0) & 0x3) << 2;
1386 
1387  pcinfo->pddac[2][3] = (val >> 2) & 0x3f;
1388  }
1389  }
1390 
1391  return ath5k_eeprom_convert_pcal_info_2413(ah, mode, chinfo);
1392 }
1393 
1394 
1395 /*
1396  * Read per rate target power (this is the maximum tx power
1397  * supported by the card). This info is used when setting
1398  * tx power, no matter the channel.
1399  *
1400  * This also works for v5 EEPROMs.
1401  */
1402 static int
1404 {
1405  struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1406  struct ath5k_rate_pcal_info *rate_pcal_info;
1407  u8 *rate_target_pwr_num;
1408  u32 offset;
1409  u16 val;
1410  int ret, i;
1411 
1413  rate_target_pwr_num = &ee->ee_rate_target_pwr_num[mode];
1414  switch (mode) {
1415  case AR5K_EEPROM_MODE_11A:
1417  rate_pcal_info = ee->ee_rate_tpwr_a;
1419  break;
1420  case AR5K_EEPROM_MODE_11B:
1422  rate_pcal_info = ee->ee_rate_tpwr_b;
1423  ee->ee_rate_target_pwr_num[mode] = 2; /* 3rd is g mode's 1st */
1424  break;
1425  case AR5K_EEPROM_MODE_11G:
1427  rate_pcal_info = ee->ee_rate_tpwr_g;
1429  break;
1430  default:
1431  return -EINVAL;
1432  }
1433 
1434  /* Different freq mask for older eeproms (<= v3.2) */
1435  if (ee->ee_version <= AR5K_EEPROM_VERSION_3_2) {
1436  for (i = 0; i < (*rate_target_pwr_num); i++) {
1438  rate_pcal_info[i].freq =
1439  ath5k_eeprom_bin2freq(ee, (val >> 9) & 0x7f, mode);
1440 
1441  rate_pcal_info[i].target_power_6to24 = ((val >> 3) & 0x3f);
1442  rate_pcal_info[i].target_power_36 = (val << 3) & 0x3f;
1443 
1445 
1446  if (rate_pcal_info[i].freq == AR5K_EEPROM_CHANNEL_DIS ||
1447  val == 0) {
1448  (*rate_target_pwr_num) = i;
1449  break;
1450  }
1451 
1452  rate_pcal_info[i].target_power_36 |= ((val >> 13) & 0x7);
1453  rate_pcal_info[i].target_power_48 = ((val >> 7) & 0x3f);
1454  rate_pcal_info[i].target_power_54 = ((val >> 1) & 0x3f);
1455  }
1456  } else {
1457  for (i = 0; i < (*rate_target_pwr_num); i++) {
1459  rate_pcal_info[i].freq =
1460  ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode);
1461 
1462  rate_pcal_info[i].target_power_6to24 = ((val >> 2) & 0x3f);
1463  rate_pcal_info[i].target_power_36 = (val << 4) & 0x3f;
1464 
1466 
1467  if (rate_pcal_info[i].freq == AR5K_EEPROM_CHANNEL_DIS ||
1468  val == 0) {
1469  (*rate_target_pwr_num) = i;
1470  break;
1471  }
1472 
1473  rate_pcal_info[i].target_power_36 |= (val >> 12) & 0xf;
1474  rate_pcal_info[i].target_power_48 = ((val >> 6) & 0x3f);
1475  rate_pcal_info[i].target_power_54 = (val & 0x3f);
1476  }
1477  }
1478 
1479  return 0;
1480 }
1481 
1482 /*
1483  * Read per channel calibration info from EEPROM
1484  *
1485  * This info is used to calibrate the baseband power table. Imagine
1486  * that for each channel there is a power curve that's hw specific
1487  * (depends on amplifier etc) and we try to "correct" this curve using
1488  * offests we pass on to phy chip (baseband -> before amplifier) so that
1489  * it can use accurate power values when setting tx power (takes amplifier's
1490  * performance on each channel into account).
1491  *
1492  * EEPROM provides us with the offsets for some pre-calibrated channels
1493  * and we have to interpolate to create the full table for these channels and
1494  * also the table for any channel.
1495  */
1496 static int
1498 {
1499  struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1500  int (*read_pcal)(struct ath5k_hw *hw, int mode);
1501  int mode;
1502  int err;
1503 
1504  if ((ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) &&
1505  (AR5K_EEPROM_EEMAP(ee->ee_misc0) == 1))
1507  else if ((ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_0) &&
1508  (AR5K_EEPROM_EEMAP(ee->ee_misc0) == 2))
1510  else
1512 
1513 
1514  for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G;
1515  mode++) {
1516  err = read_pcal(ah, mode);
1517  if (err)
1518  return err;
1519 
1521  if (err < 0)
1522  return err;
1523  }
1524 
1525  return 0;
1526 }
1527 
1528 static int
1530 {
1531  struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1532  struct ath5k_chan_pcal_info *chinfo;
1533  u8 pier, pdg;
1534 
1535  switch (mode) {
1536  case AR5K_EEPROM_MODE_11A:
1537  if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
1538  return 0;
1539  chinfo = ee->ee_pwr_cal_a;
1540  break;
1541  case AR5K_EEPROM_MODE_11B:
1542  if (!AR5K_EEPROM_HDR_11B(ee->ee_header))
1543  return 0;
1544  chinfo = ee->ee_pwr_cal_b;
1545  break;
1546  case AR5K_EEPROM_MODE_11G:
1547  if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
1548  return 0;
1549  chinfo = ee->ee_pwr_cal_g;
1550  break;
1551  default:
1552  return -EINVAL;
1553  }
1554 
1555  for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
1556  if (!chinfo[pier].pd_curves)
1557  continue;
1558 
1559  for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
1560  struct ath5k_pdgain_info *pd =
1561  &chinfo[pier].pd_curves[pdg];
1562 
1563  if (pd != NULL) {
1564  free(pd->pd_step);
1565  free(pd->pd_pwr);
1566  }
1567  }
1568 
1569  free(chinfo[pier].pd_curves);
1570  }
1571 
1572  return 0;
1573 }
1574 
1575 void
1577 {
1578  u8 mode;
1579 
1580  for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++)
1582 }
1583 
1584 /* Read conformance test limits used for regulatory control */
1585 static int
1587 {
1588  struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1589  struct ath5k_edge_power *rep;
1590  unsigned int fmask, pmask;
1591  unsigned int ctl_mode;
1592  int ret, i, j;
1593  u32 offset;
1594  u16 val;
1595 
1596  pmask = AR5K_EEPROM_POWER_M;
1597  fmask = AR5K_EEPROM_FREQ_M(ee->ee_version);
1600  for (i = 0; i < ee->ee_ctls; i += 2) {
1602  ee->ee_ctl[i] = (val >> 8) & 0xff;
1603  ee->ee_ctl[i + 1] = val & 0xff;
1604  }
1605 
1610  else
1612 
1613  rep = ee->ee_ctl_pwr;
1614  for(i = 0; i < ee->ee_ctls; i++) {
1615  switch(ee->ee_ctl[i] & AR5K_CTL_MODE_M) {
1616  case AR5K_CTL_11A:
1617  case AR5K_CTL_TURBO:
1618  ctl_mode = AR5K_EEPROM_MODE_11A;
1619  break;
1620  default:
1621  ctl_mode = AR5K_EEPROM_MODE_11G;
1622  break;
1623  }
1624  if (ee->ee_ctl[i] == 0) {
1626  offset += 8;
1627  else
1628  offset += 7;
1629  rep += AR5K_EEPROM_N_EDGES;
1630  continue;
1631  }
1632  if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3) {
1633  for (j = 0; j < AR5K_EEPROM_N_EDGES; j += 2) {
1635  rep[j].freq = (val >> 8) & fmask;
1636  rep[j + 1].freq = val & fmask;
1637  }
1638  for (j = 0; j < AR5K_EEPROM_N_EDGES; j += 2) {
1640  rep[j].edge = (val >> 8) & pmask;
1641  rep[j].flag = (val >> 14) & 1;
1642  rep[j + 1].edge = val & pmask;
1643  rep[j + 1].flag = (val >> 6) & 1;
1644  }
1645  } else {
1647  rep[0].freq = (val >> 9) & fmask;
1648  rep[1].freq = (val >> 2) & fmask;
1649  rep[2].freq = (val << 5) & fmask;
1650 
1652  rep[2].freq |= (val >> 11) & 0x1f;
1653  rep[3].freq = (val >> 4) & fmask;
1654  rep[4].freq = (val << 3) & fmask;
1655 
1657  rep[4].freq |= (val >> 13) & 0x7;
1658  rep[5].freq = (val >> 6) & fmask;
1659  rep[6].freq = (val << 1) & fmask;
1660 
1662  rep[6].freq |= (val >> 15) & 0x1;
1663  rep[7].freq = (val >> 8) & fmask;
1664 
1665  rep[0].edge = (val >> 2) & pmask;
1666  rep[1].edge = (val << 4) & pmask;
1667 
1669  rep[1].edge |= (val >> 12) & 0xf;
1670  rep[2].edge = (val >> 6) & pmask;
1671  rep[3].edge = val & pmask;
1672 
1674  rep[4].edge = (val >> 10) & pmask;
1675  rep[5].edge = (val >> 4) & pmask;
1676  rep[6].edge = (val << 2) & pmask;
1677 
1679  rep[6].edge |= (val >> 14) & 0x3;
1680  rep[7].edge = (val >> 8) & pmask;
1681  }
1682  for (j = 0; j < AR5K_EEPROM_N_EDGES; j++) {
1683  rep[j].freq = ath5k_eeprom_bin2freq(ee,
1684  rep[j].freq, ctl_mode);
1685  }
1686  rep += AR5K_EEPROM_N_EDGES;
1687  }
1688 
1689  return 0;
1690 }
1691 
1692 
1693 /*
1694  * Initialize eeprom power tables
1695  */
1696 int
1698 {
1699  int err;
1700 
1702  if (err < 0)
1703  return err;
1704 
1705  err = ath5k_eeprom_init_modes(ah);
1706  if (err < 0)
1707  return err;
1708 
1710  if (err < 0)
1711  return err;
1712 
1714  if (err < 0)
1715  return err;
1716 
1717  return 0;
1718 }
1719 
1720 /*
1721  * Read the MAC address from eeprom
1722  */
1724 {
1725  u8 mac_d[ETH_ALEN] = {};
1726  u32 total, offset;
1727  u16 data;
1728  int octet, ret;
1729 
1730  ret = ath5k_hw_eeprom_read(ah, 0x20, &data);
1731  if (ret)
1732  return ret;
1733 
1734  for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) {
1735  ret = ath5k_hw_eeprom_read(ah, offset, &data);
1736  if (ret)
1737  return ret;
1738 
1739  total += data;
1740  mac_d[octet + 1] = data & 0xff;
1741  mac_d[octet] = data >> 8;
1742  octet += 2;
1743  }
1744 
1745  if (!total || total == 3 * 0xffff)
1746  return -EINVAL;
1747 
1748  memcpy(mac, mac_d, ETH_ALEN);
1749 
1750  return 0;
1751 }
1752 
1754 {
1755  u16 data;
1756 
1758 
1759  if ((ah->ah_mac_version == (AR5K_SREV_AR2425 >> 4)) && data)
1760  return 1;
1761  else
1762  return 0;
1763 }
1764 
u16 ee_xr_power[AR5K_EEPROM_N_MODES]
Definition: eeprom.h:398
#define u16
Definition: vga.h:20
uint16_t u16
Definition: stdint.h:21
int8_t s8
Definition: stdint.h:18
uint32_t c
Definition: md4.c:30
#define EINVAL
Invalid argument.
Definition: errno.h:428
u8 ee_pd_gains[AR5K_EEPROM_N_MODES]
Definition: eeprom.h:421
#define AR5K_EEPROM_HDR_11B(_v)
Definition: eeprom.h:68
static int ath5k_eeprom_read_turbo_modes(struct ath5k_hw *ah, u32 *offset, unsigned int mode)
Definition: ath5k_eeprom.c:411
int16_t s16
Definition: stdint.h:20
#define AR5K_EEPROM_N_5GHZ_CHAN
Definition: eeprom.h:180
#define AR5K_EEPROM_MISC5
Definition: eeprom.h:114
#define AR5K_EEPROM_GROUP4_OFFSET
Definition: eeprom.h:141
#define AR5K_EEPROM_VERSION_4_2
Definition: eeprom.h:51
#define AR5K_EEPROM_IS_HB63
Definition: eeprom.h:28
#define max(x, y)
Definition: ath.h:39
struct ath5k_pdgain_info * pd_curves
Definition: eeprom.h:340
#define AR5K_EEPROM_MODE_11G
Definition: eeprom.h:64
u16 ee_thr_62[AR5K_EEPROM_N_MODES]
Definition: eeprom.h:407
#define AR5K_EEPROM_N_PD_CURVES
Definition: eeprom.h:204
s8 ee_adc_desired_size_turbo[AR5K_EEPROM_N_MODES]
Definition: eeprom.h:445
u8 ee_ctl[AR5K_EEPROM_MAX_CTLS]
Definition: eeprom.h:438
#define AR5K_EEPROM_MODE_11A
Definition: eeprom.h:62
#define AR5K_EEPROM_CAL_DATA_START(_v)
Definition: eeprom.h:110
u8 ee_pdc_to_idx[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_PD_GAINS]
Definition: eeprom.h:423
#define AR5K_EEPROM_TARGET_PWRSTART(_v)
Definition: eeprom.h:97
s8 pwr_x0[AR5K_EEPROM_N_XPD0_POINTS]
Definition: eeprom.h:292
#define AR5K_EEPROM_N_2GHZ_CHAN
Definition: eeprom.h:181
#define AR5K_EEPROM_POWER_M
Definition: eeprom.h:211
#define AR5K_EEPROM_N_XPD3_POINTS
Definition: eeprom.h:206
u16 ee_false_detect[AR5K_EEPROM_N_MODES]
Definition: eeprom.h:418
#define min(x, y)
Definition: ath.h:34
static int ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned int mode)
#define AR5K_EEPROM_PROTECT
Definition: eeprom.h:158
u8 ee_rate_target_pwr_num[AR5K_EEPROM_N_MODES]
Definition: eeprom.h:431
u16 ee_x_gain[AR5K_EEPROM_N_MODES]
Definition: eeprom.h:410
#define AR5K_EEPROM_OBDB1_2GHZ
Definition: eeprom.h:156
#define AR5K_PCICFG
Definition: reg.h:880
#define AR5K_REG_MS(_val, _flags)
Definition: ath5k.h:88
#define AR5K_EEPROM_BASE
Definition: reg.h:1054
uint8_t mac[ETH_ALEN]
MAC address.
Definition: ena.h:24
#define AR5K_EEPROM_N_PWR_POINTS_5111
Definition: eeprom.h:185
#define AR5K_EEPROM_CMD_READ
Definition: reg.h:1068
s16 ee_noise_floor_thr[AR5K_EEPROM_N_MODES]
Definition: eeprom.h:442
u8 pwr[AR5K_EEPROM_N_PWR_POINTS_5111]
Definition: eeprom.h:278
#define AR5K_EEPROM_MISC6
Definition: eeprom.h:123
static unsigned int ath5k_pdgains_size_2413(struct ath5k_eeprom_info *ee, unsigned int mode)
u16 ee_tx_end2xlna_enable[AR5K_EEPROM_N_MODES]
Definition: eeprom.h:404
Definition: hw.c:16
s8 ee_pd_gain_overlap
Definition: eeprom.h:447
ath5k_hw_get_isr - Get interrupt status
Definition: ath5k.h:953
static unsigned int ath5k_cal_data_offset_2413(struct ath5k_eeprom_info *ee, int mode)
u16 ee_ant_control[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_PCDAC]
Definition: eeprom.h:401
#define AR5K_EEPROM_STAT_RDDONE
Definition: reg.h:1080
#define AR5K_EEPROM_TARGET_PWR_OFF_11G(_v)
Definition: eeprom.h:151
u16 ee_db[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_OBDB]
Definition: eeprom.h:403
s8 pwr_x3[AR5K_EEPROM_N_XPD3_POINTS]
Definition: eeprom.h:293
uint8_t status
Status.
Definition: ena.h:16
static int ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode, struct ath5k_chan_pcal_info *chinfo)
struct ath5k_chan_pcal_info ee_pwr_cal_b[AR5K_EEPROM_N_2GHZ_CHAN_MAX]
Definition: eeprom.h:427
#define ENOMEM
Not enough space.
Definition: errno.h:534
void * memcpy(void *dest, const void *src, size_t len) __nonnull
s8 ee_adc_desired_size[AR5K_EEPROM_N_MODES]
Definition: eeprom.h:443
#define AR5K_EEPROM_MAGIC
Definition: eeprom.h:22
#define AR5K_EEPROM_HDR_T_5GHZ_DBM(_v)
Definition: eeprom.h:71
static int ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode)
#define AR5K_EEPROM_GROUP5_OFFSET
Definition: eeprom.h:142
static int ath5k_hw_eeprom_read(struct ath5k_hw *ah, u32 offset, u16 *data)
Definition: ath5k_eeprom.c:38
struct ath5k_chan_pcal_info_rf5111 rf5111_info
Definition: eeprom.h:333
struct ath5k_chan_pcal_info ee_pwr_cal_g[AR5K_EEPROM_N_2GHZ_CHAN_MAX]
Definition: eeprom.h:428
static int ath5k_eeprom_read_pcal_info(struct ath5k_hw *ah)
static int ath5k_eeprom_init_11a_pcal_freq(struct ath5k_hw *ah, int offset)
Definition: ath5k_eeprom.c:549
#define AR5K_EEPROM_GROUP1_OFFSET
Definition: eeprom.h:138
static int ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode, struct ath5k_chan_pcal_info *chinfo)
Definition: ath5k_eeprom.c:848
#define AR5K_EEPROM_REG_DOMAIN
Definition: eeprom.h:36
void udelay(unsigned long usecs)
Delay for a fixed number of microseconds.
Definition: timer.c:60
#define AR5K_EEPROM_VERSION_3_3
Definition: eeprom.h:47
static void *__malloc calloc(size_t nmemb, size_t size)
Allocate cleared memory.
Definition: stdlib.h:45
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
#define AR5K_EEPROM_CTL(_v)
Definition: eeprom.h:136
#define u8
Definition: igbvf_osdep.h:38
int ath5k_eeprom_is_hb63(struct ath5k_hw *ah)
#define AR5K_EEPROM_ANT_GAIN(_v)
Definition: eeprom.h:85
s8 pwr[AR5K_EEPROM_N_PD_GAINS][AR5K_EEPROM_N_PD_POINTS]
Definition: eeprom.h:307
#define AR5K_EEPROM_RFKILL_GPIO_SEL
Definition: eeprom.h:76
#define AR5K_EEPROM_HDR_11A(_v)
Definition: eeprom.h:67
#define AR5K_EEPROM_MISC4
Definition: eeprom.h:109
#define AR5K_EEPROM_GROUPS_START(_v)
Definition: eeprom.h:137
#define AR5K_EEPROM_N_CTLS(_v)
Definition: eeprom.h:202
#define AR5K_EEPROM_TARGET_PWR_OFF_11B(_v)
Definition: eeprom.h:149
static int ath5k_eeprom_read_freq_list(struct ath5k_hw *ah, int *offset, int max, struct ath5k_chan_pcal_info *pc, unsigned int mode)
Definition: ath5k_eeprom.c:510
u16 ee_xlna_gain[AR5K_EEPROM_N_MODES]
Definition: eeprom.h:408
u8 ee_n_piers[AR5K_EEPROM_N_MODES]
Definition: eeprom.h:425
int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
#define AR5K_EEPROM_VERSION_5_0
Definition: eeprom.h:58
#define AR5K_TUNE_REGISTER_TIMEOUT
Definition: ath5k.h:169
#define AR5K_EEPROM_HDR
Definition: eeprom.h:66
#define AR5K_EEPROM_VERSION_4_3
Definition: eeprom.h:52
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
u16 ee_tx_end2xpa_disable[AR5K_EEPROM_N_MODES]
Definition: eeprom.h:405
void ath5k_eeprom_detach(struct ath5k_hw *ah)
#define AR5K_EEPROM_EEMAP(_v)
Definition: eeprom.h:94
int ath5k_eeprom_init(struct ath5k_hw *ah)
u16 ee_margin_tx_rx_turbo[AR5K_EEPROM_N_MODES]
Definition: eeprom.h:414
static int ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah)
#define AR5K_EEPROM_N_PD_POINTS
Definition: eeprom.h:208
#define AR5K_EEPROM_MODES_11G(_v)
Definition: eeprom.h:135
#define AR5K_EEPROM_STATUS
Definition: reg.h:1077
#define AR5K_EEPROM_VERSION_4_1
Definition: eeprom.h:50
u16 ee_scaled_cck_delta
Definition: eeprom.h:391
#define AR5K_EEPROM_N_EDGES
Definition: eeprom.h:189
IP4_t ip
Destination IP address.
Definition: pxe_api.h:58
#define AR5K_EEPROM_MODE_11B
Definition: eeprom.h:63
#define ARRAY_SIZE(x)
Definition: efx_common.h:43
static void ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp)
Definition: ath5k_eeprom.c:646
struct ath5k_rate_pcal_info ee_rate_tpwr_b[AR5K_EEPROM_N_2GHZ_CHAN_MAX]
Definition: eeprom.h:433
u16 ee_i_gain[AR5K_EEPROM_N_MODES]
Definition: eeprom.h:411
#define AR5K_EEPROM_STAT_RDERR
Definition: reg.h:1079
#define AR5K_EEPROM_GROUP8_OFFSET
Definition: eeprom.h:145
static void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
Definition: ath5k.h:1222
u8 pddac_i[AR5K_EEPROM_N_PD_GAINS]
Definition: eeprom.h:303
#define AR5K_EEPROM_MODES_11B(_v)
Definition: eeprom.h:134
static int ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode)
u8 pcdac_x3[AR5K_EEPROM_N_XPD3_POINTS]
Definition: eeprom.h:297
#define ETH_ALEN
Definition: if_ether.h:8
static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset, unsigned int mode)
Definition: ath5k_eeprom.c:230
#define AR5K_EEPROM_CHANNEL_DIS
Definition: eeprom.h:200
u16 ee_i_cal[AR5K_EEPROM_N_MODES]
Definition: eeprom.h:394
u16 ee_tx_frm2xpa_enable[AR5K_EEPROM_N_MODES]
Definition: eeprom.h:406
void __asmcall int val
Definition: setjmp.h:28
s8 ee_pga_desired_size[AR5K_EEPROM_N_MODES]
Definition: eeprom.h:444
#define AR5K_SREV_AR2425
Definition: ath5k.h:304
static struct corkscrew_private * vp
Definition: 3c515.c:67
struct ath5k_rate_pcal_info ee_rate_tpwr_a[AR5K_EEPROM_N_5GHZ_CHAN]
Definition: eeprom.h:432
struct ath5k_chan_pcal_info_rf5112 rf5112_info
Definition: eeprom.h:334
u16 ee_switch_settling_turbo[AR5K_EEPROM_N_MODES]
Definition: eeprom.h:413
u16 ee_xpd[AR5K_EEPROM_N_MODES]
Definition: eeprom.h:409
#define AR5K_PCICFG_EEAE
Definition: reg.h:881
#define AR5K_EEPROM_PCDAC_M
Definition: eeprom.h:192
#define AR5K_EEPROM_MISC3
Definition: eeprom.h:105
struct ath5k_chan_pcal_info ee_pwr_cal_a[AR5K_EEPROM_N_5GHZ_CHAN]
Definition: eeprom.h:426
static int ath5k_eeprom_read_pcal_info_5111(struct ath5k_hw *ah, int mode)
Definition: ath5k_eeprom.c:739
static int ath5k_eeprom_read_ants(struct ath5k_hw *ah, u32 *offset, unsigned int mode)
Definition: ath5k_eeprom.c:170
#define AR5K_EEPROM_VERSION_3_2
Definition: eeprom.h:46
#define AR5K_EEPROM_VERSION
Definition: eeprom.h:43
#define AR5K_EEPROM_MISC2
Definition: eeprom.h:101
#define AR5K_EEPROM_N_XPD0_POINTS
Definition: eeprom.h:205
#define AR5K_EEPROM_MISC1
Definition: eeprom.h:96
u8 pcdac_x0[AR5K_EEPROM_N_XPD0_POINTS]
Definition: eeprom.h:296
u16 ee_margin_tx_rx[AR5K_EEPROM_N_MODES]
Definition: eeprom.h:412
u16 ee_cck_ofdm_power_delta
Definition: eeprom.h:390
#define AR5K_EEPROM_OBDB0_2GHZ
Definition: eeprom.h:155
#define EIO
Input/output error.
Definition: errno.h:433
static int ath5k_eeprom_init_header(struct ath5k_hw *ah)
Definition: ath5k_eeprom.c:103
struct ath5k_rate_pcal_info ee_rate_tpwr_g[AR5K_EEPROM_N_2GHZ_CHAN_MAX]
Definition: eeprom.h:434
#define AR5K_EEPROM_N_2GHZ_CHAN_2413
Definition: eeprom.h:182
#define AR5K_EEPROM_GROUP2_OFFSET
Definition: eeprom.h:139
u16 ee_atn_tx_rx[AR5K_EEPROM_N_MODES]
Definition: eeprom.h:400
u16 ee_atn_tx_rx_turbo[AR5K_EEPROM_N_MODES]
Definition: eeprom.h:415
uint8_t data[48]
Additional event data.
Definition: ena.h:22
FILE_LICENCE(MIT)
#define AR5K_EEPROM_DATA
Definition: reg.h:1061
#define AR5K_EEPROM_RFKILL
Definition: eeprom.h:30
uint8_t ah
Definition: registers.h:85
void timeout(int)
#define AR5K_EEPROM_VERSION_4_6
Definition: eeprom.h:55
u16 ee_ob[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_OBDB]
Definition: eeprom.h:402
u8 pcdac[AR5K_EEPROM_N_PWR_POINTS_5111]
Definition: eeprom.h:281
s8 pwr_i[AR5K_EEPROM_N_PD_GAINS]
Definition: eeprom.h:302
static u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
Definition: ath5k.h:1214
struct ath5k_chan_pcal_info_rf2413 rf2413_info
Definition: eeprom.h:335
#define AR5K_EEPROM_TARGET_PWR_OFF_11A(_v)
Definition: eeprom.h:147
#define AR5K_EEPROM_GROUP3_OFFSET
Definition: eeprom.h:140
struct ath5k_edge_power ee_ctl_pwr[AR5K_EEPROM_N_EDGES *AR5K_EEPROM_MAX_CTLS]
Definition: eeprom.h:439
static int ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw *ah, int mode)
Definition: ath5k_eeprom.c:954
#define AR5K_EEPROM_VERSION_3_0
Definition: eeprom.h:44
#define AR5K_EEPROM_MODES_11A(_v)
Definition: eeprom.h:133
static u16 ath5k_eeprom_bin2freq(struct ath5k_eeprom_info *ee, u16 bin, unsigned int mode)
Definition: ath5k_eeprom.c:75
static int ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset)
Definition: ath5k_eeprom.c:602
u16 ee_turbo_max_power[AR5K_EEPROM_N_MODES]
Definition: eeprom.h:397
#define AR5K_EEPROM_READ(_o, _v)
Definition: eeprom.h:222
#define AR5K_EEPROM_MISC0
Definition: eeprom.h:90
#define AR5K_EEPROM_FREQ_M(_v)
Definition: eeprom.h:191
u16 ee_cck_ofdm_gain_delta
Definition: eeprom.h:389
u8 pddac[AR5K_EEPROM_N_PD_GAINS][AR5K_EEPROM_N_PD_POINTS]
Definition: eeprom.h:309
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
u16 ee_switch_settling[AR5K_EEPROM_N_MODES]
Definition: eeprom.h:399
#define ETIMEDOUT
Connection timed out.
Definition: errno.h:669
u16 ee_fixed_bias[AR5K_EEPROM_N_MODES]
Definition: eeprom.h:396
#define AR5K_EEPROM_HDR_11G(_v)
Definition: eeprom.h:69
#define AR5K_EEPROM_RFKILL_POLARITY
Definition: eeprom.h:78
static int ath5k_eeprom_init_modes(struct ath5k_hw *ah)
Definition: ath5k_eeprom.c:463
struct bofm_section_header done
Definition: bofm_test.c:46
uint8_t u8
Definition: stdint.h:19
#define AR5K_EEPROM_CCK_OFDM_DELTA
Definition: eeprom.h:219
uint32_t u32
Definition: stdint.h:23
u16 ee_q_cal[AR5K_EEPROM_N_MODES]
Definition: eeprom.h:395
#define AR5K_EEPROM_READ_HDR(_o, _v)
Definition: eeprom.h:228
s8 ee_pga_desired_size_turbo[AR5K_EEPROM_N_MODES]
Definition: eeprom.h:446
#define AR5K_REG_ENABLE_BITS(ah, _reg, _flags)
Definition: ath5k.h:104
#define AR5K_EEPROM_I_GAIN
Definition: eeprom.h:218
#define AR5K_EEPROM_VERSION_3_4
Definition: eeprom.h:48
static int ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode, struct ath5k_chan_pcal_info *chinfo)
Definition: ath5k_eeprom.c:667
#define AR5K_EEPROM_CMD
Definition: reg.h:1067
#define AR5K_EEPROM_VERSION_4_0
Definition: eeprom.h:49