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