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