3f62eefb92914120a268ba4bf5adf5a8c0811a25
[openwrt/svn-archive/archive.git] / package / mac80211 / patches / 330-ath5k_eeprom.patch
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
4 the eyes.
5
6 Signed-off-by: Felix Fietkau <nbd@openwrt.org>
7
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
11 {
12 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
13 int o = *offset;
14 - int i = 0;
15 + int i;
16 u8 freq1, freq2;
17 int ret;
18 u16 val;
19
20 + ee->ee_n_piers[mode] = 0;
21 while(i < max) {
22 AR5K_EEPROM_READ(o++, val);
23
24 - freq1 = (val >> 8) & 0xff;
25 - freq2 = val & 0xff;
26 -
27 - if (freq1) {
28 - pc[i++].freq = ath5k_eeprom_bin2freq(ee,
29 - freq1, mode);
30 - ee->ee_n_piers[mode]++;
31 - }
32 + freq1 = val & 0xff;
33 + if (!freq1)
34 + break;
35
36 - if (freq2) {
37 - pc[i++].freq = ath5k_eeprom_bin2freq(ee,
38 - freq2, mode);
39 - ee->ee_n_piers[mode]++;
40 - }
41 + pc[i++].freq = ath5k_eeprom_bin2freq(ee,
42 + freq1, mode);
43 + ee->ee_n_piers[mode]++;
44
45 - if (!freq1 || !freq2)
46 + freq2 = (val >> 8) & 0xff;
47 + if (!freq2)
48 break;
49 +
50 + pc[i++].freq = ath5k_eeprom_bin2freq(ee,
51 + freq2, mode);
52 + ee->ee_n_piers[mode]++;
53 }
54
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.
59 */
60 +
61 static int
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)
65 {
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;
69 - unsigned int i, c;
70 - u32 offset;
71 + struct ath5k_chan_pcal_info_rf2413 *pcinfo;
72 + unsigned int i;
73 int ret;
74 u16 val;
75 - u8 pd_gains = 0;
76 -
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;
82 + u8 pd_gains;
83
84 - offset = ath5k_cal_data_offset_2413(ee, mode);
85 - ee->ee_n_piers[mode] = 0;
86 - switch (mode) {
87 - case AR5K_EEPROM_MODE_11A:
88 - if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
89 - return 0;
90 -
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;
94 - break;
95 - case AR5K_EEPROM_MODE_11B:
96 - if (!AR5K_EEPROM_HDR_11B(ee->ee_header))
97 - return 0;
98 -
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;
102 - break;
103 - case AR5K_EEPROM_MODE_11G:
104 - if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
105 - return 0;
106 -
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;
110 - break;
111 - default:
112 - return -EINVAL;
113 - }
114 + pd_gains = ee->ee_pd_gains[mode];
115
116 if (pd_gains == 0)
117 return 0;
118
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;
122
123 /*
124 * Read pwr_i, pddac_i and the first
125 * 2 pd points (pwr, pddac)
126 */
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] =
131 - (val >> 12) & 0xf;
132 + pcinfo->pwr_i[0] = val & 0x1f;
133 + pcinfo->pddac_i[0] = (val >> 5) & 0x7f;
134 + pcinfo->pwr[0][0] = (val >> 12) & 0xf;
135
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;
144
145 AR5K_EEPROM_READ(offset++, val);
146 - chan_pcal_info->pwr[0][2] = val & 0xf;
147 - chan_pcal_info->pddac[0][2] =
148 - (val >> 4) & 0x3f;
149 + pcinfo->pwr[0][2] = val & 0xf;
150 + pcinfo->pddac[0][2] = (val >> 4) & 0x3f;
151
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;
156
157 if (pd_gains > 1) {
158 /*
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.
162 */
163 - chan_pcal_info->pwr_i[1] = (val >> 10) & 0x1f;
164 + pcinfo->pwr_i[1] = (val >> 10) & 0x1f;
165
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;
171
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;
177
178 AR5K_EEPROM_READ(offset++, val);
179 - chan_pcal_info->pwr[1][1] = val & 0xf;
180 - chan_pcal_info->pddac[1][1] =
181 - (val >> 4) & 0x3f;
182 - chan_pcal_info->pwr[1][2] =
183 - (val >> 10) & 0xf;
184 + pcinfo->pwr[1][1] = val & 0xf;
185 + pcinfo->pddac[1][1] = (val >> 4) & 0x3f;
186 + pcinfo->pwr[1][2] = (val >> 10) & 0xf;
187
188 - chan_pcal_info->pddac[1][2] =
189 - (val >> 14) & 0x3;
190 + pcinfo->pddac[1][2] = (val >> 14) & 0x3;
191 AR5K_EEPROM_READ(offset++, val);
192 - chan_pcal_info->pddac[1][2] |=
193 - (val & 0xF) << 2;
194 + pcinfo->pddac[1][2] |= (val & 0xF) << 2;
195
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) {
201 /*
202 * Pd gain 0 is the last one so
203 * read the extra point.
204 */
205 - chan_pcal_info->pwr[0][3] =
206 - (val >> 10) & 0xf;
207 + pcinfo->pwr[0][3] = (val >> 10) & 0xf;
208
209 - chan_pcal_info->pddac[0][3] =
210 - (val >> 14) & 0x3;
211 + pcinfo->pddac[0][3] = (val >> 14) & 0x3;
212 AR5K_EEPROM_READ(offset++, val);
213 - chan_pcal_info->pddac[0][3] |=
214 - (val & 0xF) << 2;
215 + pcinfo->pddac[0][3] |= (val & 0xF) << 2;
216 }
217
218 /*
219 @@ -1048,105 +1001,159 @@ ath5k_eeprom_read_pcal_info_2413(struct
220 * as above.
221 */
222 if (pd_gains > 2) {
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;
227
228 AR5K_EEPROM_READ(offset++, val);
229 - chan_pcal_info->pwr[2][0] =
230 - (val >> 0) & 0xf;
231 - chan_pcal_info->pddac[2][0] =
232 - (val >> 4) & 0x3f;
233 - chan_pcal_info->pwr[2][1] =
234 - (val >> 10) & 0xf;
235 -
236 - chan_pcal_info->pddac[2][1] =
237 - (val >> 14) & 0x3;
238 - AR5K_EEPROM_READ(offset++, val);
239 - chan_pcal_info->pddac[2][1] |=
240 - (val & 0xF) << 2;
241 -
242 - chan_pcal_info->pwr[2][2] =
243 - (val >> 4) & 0xf;
244 - chan_pcal_info->pddac[2][2] =
245 - (val >> 8) & 0x3f;
246 + pcinfo->pwr[2][0] = (val >> 0) & 0xf;
247 + pcinfo->pddac[2][0] = (val >> 4) & 0x3f;
248 + pcinfo->pwr[2][1] = (val >> 10) & 0xf;
249
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;
255 +
256 + pcinfo->pwr[2][2] = (val >> 4) & 0xf;
257 + pcinfo->pddac[2][2] = (val >> 8) & 0x3f;
258 +
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] =
263 - (val >> 4) & 0xf;
264 - chan_pcal_info->pddac[1][3] =
265 - (val >> 8) & 0x3f;
266 + pcinfo->pwr[1][3] = (val >> 4) & 0xf;
267 + pcinfo->pddac[1][3] = (val >> 8) & 0x3f;
268 }
269
270 if (pd_gains > 3) {
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;
276
277 - chan_pcal_info->pddac_i[3] = (val >> 3) & 0x7f;
278 - chan_pcal_info->pwr[3][0] =
279 - (val >> 10) & 0xf;
280 - chan_pcal_info->pddac[3][0] =
281 - (val >> 14) & 0x3;
282 + pcinfo->pddac_i[3] = (val >> 3) & 0x7f;
283 + pcinfo->pwr[3][0] = (val >> 10) & 0xf;
284 + pcinfo->pddac[3][0] = (val >> 14) & 0x3;
285
286 AR5K_EEPROM_READ(offset++, val);
287 - chan_pcal_info->pddac[3][0] |=
288 - (val & 0xF) << 2;
289 - chan_pcal_info->pwr[3][1] =
290 - (val >> 4) & 0xf;
291 - chan_pcal_info->pddac[3][1] =
292 - (val >> 8) & 0x3f;
293 + pcinfo->pddac[3][0] |= (val & 0xF) << 2;
294 + pcinfo->pwr[3][1] = (val >> 4) & 0xf;
295 + pcinfo->pddac[3][1] = (val >> 8) & 0x3f;
296
297 - chan_pcal_info->pwr[3][2] =
298 - (val >> 14) & 0x3;
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;
304
305 - chan_pcal_info->pddac[3][2] =
306 - (val >> 2) & 0x3f;
307 - chan_pcal_info->pwr[3][3] =
308 - (val >> 8) & 0xf;
309 + pcinfo->pddac[3][2] = (val >> 2) & 0x3f;
310 + pcinfo->pwr[3][3] = (val >> 8) & 0xf;
311
312 - chan_pcal_info->pddac[3][3] =
313 - (val >> 12) & 0xF;
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] =
321 - (val >> 14) & 0x3;
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;
327
328 - chan_pcal_info->pddac[2][3] =
329 - (val >> 2) & 0x3f;
330 + pcinfo->pddac[2][3] = (val >> 2) & 0x3f;
331 }
332 + }
333 + return 0;
334 +}
335 +
336 +static int
337 +ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode,
338 + struct ath5k_chan_pcal_info *chinfo,
339 + unsigned int *xgains)
340 +{
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;
344
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;
353 -
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];
367 +
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;
371 + } else {
372 + pd->n_vpd = AR5K_EEPROM_N_PD_POINTS - 1;
373 + }
374 +
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];
380 + }
381 }
382 }
383
384 return 0;
385 }
386
387 +static int
388 +ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode)
389 +{
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];
393 + u32 offset;
394 + u8 pd_gains = 0;
395 + int i, ret;
396 +
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;
400 +
401 + if ((ee->ee_x_gain[mode] >> idx) & 0x1)
402 + xgains[pd_gains++] = idx;
403 + }
404 + ee->ee_pd_gains[mode] = pd_gains;
405 +
406 + offset = ath5k_cal_data_offset_2413(ee, mode);
407 + switch (mode) {
408 + case AR5K_EEPROM_MODE_11A:
409 + if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
410 + return 0;
411 +
412 + ath5k_eeprom_init_11a_pcal_freq(ah, offset);
413 + offset += AR5K_EEPROM_N_5GHZ_CHAN / 2;
414 + chinfo = ee->ee_pwr_cal_a;
415 + break;
416 + case AR5K_EEPROM_MODE_11B:
417 + if (!AR5K_EEPROM_HDR_11B(ee->ee_header))
418 + return 0;
419 +
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;
423 + break;
424 + case AR5K_EEPROM_MODE_11G:
425 + if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
426 + return 0;
427 +
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;
431 + break;
432 + default:
433 + return -EINVAL;
434 + }
435 +
436 +
437 + ret = ath5k_eeprom_parse_pcal_info_2413(ah, mode, offset, chinfo);
438 + if (ret)
439 + return ret;
440 +
441 + ret = ath5k_eeprom_convert_pcal_info_2413(ah, mode, chinfo, xgains);
442 + if (ret)
443 + return ret;
444 +
445 + return 0;
446 +}
447 +
448 /*
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
452 else
453 read_pcal = ath5k_eeprom_read_pcal_info_5111;
454
455 +
456 for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++) {
457 err = read_pcal(ah, mode);
458 if (err)
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];
463 };
464
465 +
466 +struct ath5k_pdgain_info {
467 + u16 n_vpd;
468 + u16 vpd[AR5K_EEPROM_N_PD_POINTS];
469 + s16 pwr_t4[AR5K_EEPROM_N_PD_POINTS];
470 +};
471 +
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];
488 +
489 + /* --- RAW VALUES --- */
490 + struct ath5k_pdgain_info pdgains
491 + [AR5K_EEPROM_N_PD_GAINS];
492 };
493
494 struct ath5k_chan_pcal_info {