1 Clean up the eeprom parsing code and prepare the pdgain
2 data for 2413, which will be required for power calibration code.
3 Also clean up some ugly line wrapping to make the code easier on
6 Signed-off-by: Felix Fietkau <nbd@openwrt.org>
8 --- a/drivers/net/wireless/ath5k/eeprom.c
9 +++ b/drivers/net/wireless/ath5k/eeprom.c
10 @@ -541,31 +541,30 @@ ath5k_eeprom_read_freq_list(struct ath5k
12 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
20 + ee->ee_n_piers[mode] = 0;
22 AR5K_EEPROM_READ(o++, val);
24 - freq1 = (val >> 8) & 0xff;
28 - pc[i++].freq = ath5k_eeprom_bin2freq(ee,
30 - ee->ee_n_piers[mode]++;
37 - pc[i++].freq = ath5k_eeprom_bin2freq(ee,
39 - ee->ee_n_piers[mode]++;
41 + pc[i++].freq = ath5k_eeprom_bin2freq(ee,
43 + ee->ee_n_piers[mode]++;
45 - if (!freq1 || !freq2)
46 + freq2 = (val >> 8) & 0xff;
50 + pc[i++].freq = ath5k_eeprom_bin2freq(ee,
52 + ee->ee_n_piers[mode]++;
55 /* return new offset */
56 @@ -918,84 +917,46 @@ ath5k_cal_data_offset_2413(struct ath5k_
57 * curves on eeprom. The final curve (higher power) has an extra
58 * point for better accuracy like RF5112.
62 -ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode)
63 +ath5k_eeprom_parse_pcal_info_2413(struct ath5k_hw *ah, int mode, u32 offset,
64 + struct ath5k_chan_pcal_info *chinfo)
66 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
67 - struct ath5k_chan_pcal_info_rf2413 *chan_pcal_info;
68 - struct ath5k_chan_pcal_info *gen_chan_info;
71 + struct ath5k_chan_pcal_info_rf2413 *pcinfo;
77 - if (ee->ee_x_gain[mode] & 0x1) pd_gains++;
78 - if ((ee->ee_x_gain[mode] >> 1) & 0x1) pd_gains++;
79 - if ((ee->ee_x_gain[mode] >> 2) & 0x1) pd_gains++;
80 - if ((ee->ee_x_gain[mode] >> 3) & 0x1) pd_gains++;
81 - ee->ee_pd_gains[mode] = pd_gains;
84 - offset = ath5k_cal_data_offset_2413(ee, mode);
85 - ee->ee_n_piers[mode] = 0;
87 - case AR5K_EEPROM_MODE_11A:
88 - if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
91 - ath5k_eeprom_init_11a_pcal_freq(ah, offset);
92 - offset += AR5K_EEPROM_N_5GHZ_CHAN / 2;
93 - gen_chan_info = ee->ee_pwr_cal_a;
95 - case AR5K_EEPROM_MODE_11B:
96 - if (!AR5K_EEPROM_HDR_11B(ee->ee_header))
99 - ath5k_eeprom_init_11bg_2413(ah, mode, offset);
100 - offset += AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2;
101 - gen_chan_info = ee->ee_pwr_cal_b;
103 - case AR5K_EEPROM_MODE_11G:
104 - if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
107 - ath5k_eeprom_init_11bg_2413(ah, mode, offset);
108 - offset += AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2;
109 - gen_chan_info = ee->ee_pwr_cal_g;
114 + pd_gains = ee->ee_pd_gains[mode];
119 for (i = 0; i < ee->ee_n_piers[mode]; i++) {
120 - chan_pcal_info = &gen_chan_info[i].rf2413_info;
121 + pcinfo = &chinfo[i].rf2413_info;
124 * Read pwr_i, pddac_i and the first
125 * 2 pd points (pwr, pddac)
127 AR5K_EEPROM_READ(offset++, val);
128 - chan_pcal_info->pwr_i[0] = val & 0x1f;
129 - chan_pcal_info->pddac_i[0] = (val >> 5) & 0x7f;
130 - chan_pcal_info->pwr[0][0] =
132 + pcinfo->pwr_i[0] = val & 0x1f;
133 + pcinfo->pddac_i[0] = (val >> 5) & 0x7f;
134 + pcinfo->pwr[0][0] = (val >> 12) & 0xf;
136 AR5K_EEPROM_READ(offset++, val);
137 - chan_pcal_info->pddac[0][0] = val & 0x3f;
138 - chan_pcal_info->pwr[0][1] = (val >> 6) & 0xf;
139 - chan_pcal_info->pddac[0][1] =
140 - (val >> 10) & 0x3f;
141 + pcinfo->pddac[0][0] = val & 0x3f;
142 + pcinfo->pwr[0][1] = (val >> 6) & 0xf;
143 + pcinfo->pddac[0][1] = (val >> 10) & 0x3f;
145 AR5K_EEPROM_READ(offset++, val);
146 - chan_pcal_info->pwr[0][2] = val & 0xf;
147 - chan_pcal_info->pddac[0][2] =
149 + pcinfo->pwr[0][2] = val & 0xf;
150 + pcinfo->pddac[0][2] = (val >> 4) & 0x3f;
152 - chan_pcal_info->pwr[0][3] = 0;
153 - chan_pcal_info->pddac[0][3] = 0;
154 + pcinfo->pwr[0][3] = 0;
155 + pcinfo->pddac[0][3] = 0;
159 @@ -1003,44 +964,36 @@ ath5k_eeprom_read_pcal_info_2413(struct
160 * so it only has 2 pd points.
161 * Continue wih pd gain 1.
163 - chan_pcal_info->pwr_i[1] = (val >> 10) & 0x1f;
164 + pcinfo->pwr_i[1] = (val >> 10) & 0x1f;
166 - chan_pcal_info->pddac_i[1] = (val >> 15) & 0x1;
167 + pcinfo->pddac_i[1] = (val >> 15) & 0x1;
168 AR5K_EEPROM_READ(offset++, val);
169 - chan_pcal_info->pddac_i[1] |= (val & 0x3F) << 1;
170 + pcinfo->pddac_i[1] |= (val & 0x3F) << 1;
172 - chan_pcal_info->pwr[1][0] = (val >> 6) & 0xf;
173 - chan_pcal_info->pddac[1][0] =
174 - (val >> 10) & 0x3f;
175 + pcinfo->pwr[1][0] = (val >> 6) & 0xf;
176 + pcinfo->pddac[1][0] = (val >> 10) & 0x3f;
178 AR5K_EEPROM_READ(offset++, val);
179 - chan_pcal_info->pwr[1][1] = val & 0xf;
180 - chan_pcal_info->pddac[1][1] =
182 - chan_pcal_info->pwr[1][2] =
184 + pcinfo->pwr[1][1] = val & 0xf;
185 + pcinfo->pddac[1][1] = (val >> 4) & 0x3f;
186 + pcinfo->pwr[1][2] = (val >> 10) & 0xf;
188 - chan_pcal_info->pddac[1][2] =
190 + pcinfo->pddac[1][2] = (val >> 14) & 0x3;
191 AR5K_EEPROM_READ(offset++, val);
192 - chan_pcal_info->pddac[1][2] |=
194 + pcinfo->pddac[1][2] |= (val & 0xF) << 2;
196 - chan_pcal_info->pwr[1][3] = 0;
197 - chan_pcal_info->pddac[1][3] = 0;
198 + pcinfo->pwr[1][3] = 0;
199 + pcinfo->pddac[1][3] = 0;
200 } else if (pd_gains == 1) {
202 * Pd gain 0 is the last one so
203 * read the extra point.
205 - chan_pcal_info->pwr[0][3] =
207 + pcinfo->pwr[0][3] = (val >> 10) & 0xf;
209 - chan_pcal_info->pddac[0][3] =
211 + pcinfo->pddac[0][3] = (val >> 14) & 0x3;
212 AR5K_EEPROM_READ(offset++, val);
213 - chan_pcal_info->pddac[0][3] |=
215 + pcinfo->pddac[0][3] |= (val & 0xF) << 2;
219 @@ -1048,105 +1001,159 @@ ath5k_eeprom_read_pcal_info_2413(struct
223 - chan_pcal_info->pwr_i[2] = (val >> 4) & 0x1f;
224 - chan_pcal_info->pddac_i[2] = (val >> 9) & 0x7f;
225 + pcinfo->pwr_i[2] = (val >> 4) & 0x1f;
226 + pcinfo->pddac_i[2] = (val >> 9) & 0x7f;
228 AR5K_EEPROM_READ(offset++, val);
229 - chan_pcal_info->pwr[2][0] =
231 - chan_pcal_info->pddac[2][0] =
233 - chan_pcal_info->pwr[2][1] =
236 - chan_pcal_info->pddac[2][1] =
238 - AR5K_EEPROM_READ(offset++, val);
239 - chan_pcal_info->pddac[2][1] |=
242 - chan_pcal_info->pwr[2][2] =
244 - chan_pcal_info->pddac[2][2] =
246 + pcinfo->pwr[2][0] = (val >> 0) & 0xf;
247 + pcinfo->pddac[2][0] = (val >> 4) & 0x3f;
248 + pcinfo->pwr[2][1] = (val >> 10) & 0xf;
250 - chan_pcal_info->pwr[2][3] = 0;
251 - chan_pcal_info->pddac[2][3] = 0;
252 + pcinfo->pddac[2][1] = (val >> 14) & 0x3;
253 + AR5K_EEPROM_READ(offset++, val);
254 + pcinfo->pddac[2][1] |= (val & 0xF) << 2;
256 + pcinfo->pwr[2][2] = (val >> 4) & 0xf;
257 + pcinfo->pddac[2][2] = (val >> 8) & 0x3f;
259 + pcinfo->pwr[2][3] = 0;
260 + pcinfo->pddac[2][3] = 0;
261 } else if (pd_gains == 2) {
262 - chan_pcal_info->pwr[1][3] =
264 - chan_pcal_info->pddac[1][3] =
266 + pcinfo->pwr[1][3] = (val >> 4) & 0xf;
267 + pcinfo->pddac[1][3] = (val >> 8) & 0x3f;
271 - chan_pcal_info->pwr_i[3] = (val >> 14) & 0x3;
272 + pcinfo->pwr_i[3] = (val >> 14) & 0x3;
273 AR5K_EEPROM_READ(offset++, val);
274 - chan_pcal_info->pwr_i[3] |= ((val >> 0) & 0x7) << 2;
275 + pcinfo->pwr_i[3] |= ((val >> 0) & 0x7) << 2;
277 - chan_pcal_info->pddac_i[3] = (val >> 3) & 0x7f;
278 - chan_pcal_info->pwr[3][0] =
280 - chan_pcal_info->pddac[3][0] =
282 + pcinfo->pddac_i[3] = (val >> 3) & 0x7f;
283 + pcinfo->pwr[3][0] = (val >> 10) & 0xf;
284 + pcinfo->pddac[3][0] = (val >> 14) & 0x3;
286 AR5K_EEPROM_READ(offset++, val);
287 - chan_pcal_info->pddac[3][0] |=
289 - chan_pcal_info->pwr[3][1] =
291 - chan_pcal_info->pddac[3][1] =
293 + pcinfo->pddac[3][0] |= (val & 0xF) << 2;
294 + pcinfo->pwr[3][1] = (val >> 4) & 0xf;
295 + pcinfo->pddac[3][1] = (val >> 8) & 0x3f;
297 - chan_pcal_info->pwr[3][2] =
299 + pcinfo->pwr[3][2] = (val >> 14) & 0x3;
300 AR5K_EEPROM_READ(offset++, val);
301 - chan_pcal_info->pwr[3][2] |=
302 - ((val >> 0) & 0x3) << 2;
303 + pcinfo->pwr[3][2] |= ((val >> 0) & 0x3) << 2;
305 - chan_pcal_info->pddac[3][2] =
307 - chan_pcal_info->pwr[3][3] =
309 + pcinfo->pddac[3][2] = (val >> 2) & 0x3f;
310 + pcinfo->pwr[3][3] = (val >> 8) & 0xf;
312 - chan_pcal_info->pddac[3][3] =
314 + pcinfo->pddac[3][3] = (val >> 12) & 0xF;
315 AR5K_EEPROM_READ(offset++, val);
316 - chan_pcal_info->pddac[3][3] |=
317 - ((val >> 0) & 0x3) << 4;
318 + pcinfo->pddac[3][3] |= ((val >> 0) & 0x3) << 4;
319 } else if (pd_gains == 3) {
320 - chan_pcal_info->pwr[2][3] =
322 + pcinfo->pwr[2][3] = (val >> 14) & 0x3;
323 AR5K_EEPROM_READ(offset++, val);
324 - chan_pcal_info->pwr[2][3] |=
325 - ((val >> 0) & 0x3) << 2;
326 + pcinfo->pwr[2][3] |= ((val >> 0) & 0x3) << 2;
328 - chan_pcal_info->pddac[2][3] =
330 + pcinfo->pddac[2][3] = (val >> 2) & 0x3f;
337 +ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode,
338 + struct ath5k_chan_pcal_info *chinfo,
339 + unsigned int *xgains)
341 + struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
342 + struct ath5k_chan_pcal_info_rf2413 *pcinfo;
343 + unsigned int i, j, k;
345 - for (c = 0; c < pd_gains; c++) {
346 - /* Recreate pwr table for this channel using pwr steps */
347 - chan_pcal_info->pwr[c][0] += chan_pcal_info->pwr_i[c] * 2;
348 - chan_pcal_info->pwr[c][1] += chan_pcal_info->pwr[c][0];
349 - chan_pcal_info->pwr[c][2] += chan_pcal_info->pwr[c][1];
350 - chan_pcal_info->pwr[c][3] += chan_pcal_info->pwr[c][2];
351 - if (chan_pcal_info->pwr[c][3] == chan_pcal_info->pwr[c][2])
352 - chan_pcal_info->pwr[c][3] = 0;
354 - /* Recreate pddac table for this channel using pddac steps */
355 - chan_pcal_info->pddac[c][0] += chan_pcal_info->pddac_i[c];
356 - chan_pcal_info->pddac[c][1] += chan_pcal_info->pddac[c][0];
357 - chan_pcal_info->pddac[c][2] += chan_pcal_info->pddac[c][1];
358 - chan_pcal_info->pddac[c][3] += chan_pcal_info->pddac[c][2];
359 - if (chan_pcal_info->pddac[c][3] == chan_pcal_info->pddac[c][2])
360 - chan_pcal_info->pddac[c][3] = 0;
361 + /* prepare the raw values */
362 + for (i = 0; i < ee->ee_n_piers[mode]; i++) {
363 + pcinfo = &chinfo[i].rf2413_info;
364 + for (j = 0; j < ee->ee_pd_gains[mode]; j++) {
365 + unsigned int idx = xgains[j];
366 + struct ath5k_pdgain_info *pd = &pcinfo->pdgains[idx];
368 + /* one more point for the highest power (lowest gain) */
369 + if (j == ee->ee_pd_gains[mode] - 1) {
370 + pd->n_vpd = AR5K_EEPROM_N_PD_POINTS;
372 + pd->n_vpd = AR5K_EEPROM_N_PD_POINTS - 1;
375 + pd->vpd[0] = pcinfo->pddac_i[j];
376 + pd->pwr_t4[0] = 4 * pcinfo->pwr_i[j];
377 + for (k = 1; k < pd->n_vpd; k++) {
378 + pd->pwr_t4[k] = pd->pwr_t4[k - 1] + 2 * pcinfo->pwr[j][k - 1];
379 + pd->vpd[k] = pd->vpd[k - 1] + pcinfo->pddac[j][k - 1];
388 +ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode)
390 + struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
391 + struct ath5k_chan_pcal_info *chinfo;
392 + unsigned int xgains[AR5K_EEPROM_N_PD_GAINS];
397 + memset(xgains, 0, sizeof(xgains));
398 + for (i = 0; i < AR5K_EEPROM_N_PD_GAINS; i++) {
399 + int idx = AR5K_EEPROM_N_PD_GAINS - i - 1;
401 + if ((ee->ee_x_gain[mode] >> idx) & 0x1)
402 + xgains[pd_gains++] = idx;
404 + ee->ee_pd_gains[mode] = pd_gains;
406 + offset = ath5k_cal_data_offset_2413(ee, mode);
408 + case AR5K_EEPROM_MODE_11A:
409 + if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
412 + ath5k_eeprom_init_11a_pcal_freq(ah, offset);
413 + offset += AR5K_EEPROM_N_5GHZ_CHAN / 2;
414 + chinfo = ee->ee_pwr_cal_a;
416 + case AR5K_EEPROM_MODE_11B:
417 + if (!AR5K_EEPROM_HDR_11B(ee->ee_header))
420 + ath5k_eeprom_init_11bg_2413(ah, mode, offset);
421 + offset += AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2;
422 + chinfo = ee->ee_pwr_cal_b;
424 + case AR5K_EEPROM_MODE_11G:
425 + if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
428 + ath5k_eeprom_init_11bg_2413(ah, mode, offset);
429 + offset += AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2;
430 + chinfo = ee->ee_pwr_cal_g;
437 + ret = ath5k_eeprom_parse_pcal_info_2413(ah, mode, offset, chinfo);
441 + ret = ath5k_eeprom_convert_pcal_info_2413(ah, mode, chinfo, xgains);
449 * Read per rate target power (this is the maximum tx power
450 * supported by the card). This info is used when setting
451 @@ -1264,6 +1271,7 @@ ath5k_eeprom_read_pcal_info(struct ath5k
453 read_pcal = ath5k_eeprom_read_pcal_info_5111;
456 for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++) {
457 err = read_pcal(ah, mode);
459 --- a/drivers/net/wireless/ath5k/eeprom.h
460 +++ b/drivers/net/wireless/ath5k/eeprom.h
461 @@ -266,15 +266,27 @@ struct ath5k_chan_pcal_info_rf5112 {
462 u8 pcdac_x3[AR5K_EEPROM_N_XPD3_POINTS];
466 +struct ath5k_pdgain_info {
468 + u16 vpd[AR5K_EEPROM_N_PD_POINTS];
469 + s16 pwr_t4[AR5K_EEPROM_N_PD_POINTS];
472 struct ath5k_chan_pcal_info_rf2413 {
473 + /* --- EEPROM VALUES --- */
474 /* Starting pwr/pddac values */
475 - s8 pwr_i[AR5K_EEPROM_N_PD_GAINS];
476 - u8 pddac_i[AR5K_EEPROM_N_PD_GAINS];
477 + s8 pwr_i[AR5K_EEPROM_N_PD_GAINS];
478 + u8 pddac_i[AR5K_EEPROM_N_PD_GAINS];
479 /* (pwr,pddac) points */
480 - s8 pwr[AR5K_EEPROM_N_PD_GAINS]
481 - [AR5K_EEPROM_N_PD_POINTS];
482 - u8 pddac[AR5K_EEPROM_N_PD_GAINS]
483 - [AR5K_EEPROM_N_PD_POINTS];
484 + s8 pwr[AR5K_EEPROM_N_PD_GAINS]
485 + [AR5K_EEPROM_N_PD_POINTS];
486 + u8 pddac[AR5K_EEPROM_N_PD_GAINS]
487 + [AR5K_EEPROM_N_PD_POINTS];
489 + /* --- RAW VALUES --- */
490 + struct ath5k_pdgain_info pdgains
491 + [AR5K_EEPROM_N_PD_GAINS];
494 struct ath5k_chan_pcal_info {