aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2010-12-11 18:51:10 -0500
committerJohn W. Linville <linville@tuxdriver.com>2010-12-13 15:23:31 -0500
commit940cd2c12ebff688cfdc14f21c4b0e5b845ad47f (patch)
treefb5d8a4da3975d76c27e46848a1135d25015e939
parent115277a3bc0683d04da797268ddafdc3bf67ca33 (diff)
ath9k_hw: merge the ar9287 version of ath9k_hw_get_gain_boundaries_pdadcs
Also add a comment about a potential array overrun that needs to be reviewed. Signed-off-by: Felix Fietkau <nbd@openwrt.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.c39
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_9287.c159
2 files changed, 32 insertions, 166 deletions
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c
index d54cfa4e8057..d05163159572 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom.c
@@ -309,7 +309,14 @@ void ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hw *ah,
309 int pdgain_boundary_default; 309 int pdgain_boundary_default;
310 struct cal_data_per_freq *data_def = pRawDataSet; 310 struct cal_data_per_freq *data_def = pRawDataSet;
311 struct cal_data_per_freq_4k *data_4k = pRawDataSet; 311 struct cal_data_per_freq_4k *data_4k = pRawDataSet;
312 struct cal_data_per_freq_ar9287 *data_9287 = pRawDataSet;
312 bool eeprom_4k = AR_SREV_9285(ah) || AR_SREV_9271(ah); 313 bool eeprom_4k = AR_SREV_9285(ah) || AR_SREV_9271(ah);
314 int intercepts;
315
316 if (AR_SREV_9287(ah))
317 intercepts = AR9287_PD_GAIN_ICEPTS;
318 else
319 intercepts = AR5416_PD_GAIN_ICEPTS;
313 320
314 memset(&minPwrT4, 0, AR5416_NUM_PD_GAINS); 321 memset(&minPwrT4, 0, AR5416_NUM_PD_GAINS);
315 ath9k_hw_get_channel_centers(ah, chan, &centers); 322 ath9k_hw_get_channel_centers(ah, chan, &centers);
@@ -324,14 +331,25 @@ void ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hw *ah,
324 bChans, numPiers, &idxL, &idxR); 331 bChans, numPiers, &idxL, &idxR);
325 332
326 if (match) { 333 if (match) {
327 if (eeprom_4k) { 334 if (AR_SREV_9287(ah)) {
335 /* FIXME: array overrun? */
336 for (i = 0; i < numXpdGains; i++) {
337 minPwrT4[i] = data_9287[idxL].pwrPdg[i][0];
338 maxPwrT4[i] = data_9287[idxL].pwrPdg[i][4];
339 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
340 data_9287[idxL].pwrPdg[i],
341 data_9287[idxL].vpdPdg[i],
342 intercepts,
343 vpdTableI[i]);
344 }
345 } else if (eeprom_4k) {
328 for (i = 0; i < numXpdGains; i++) { 346 for (i = 0; i < numXpdGains; i++) {
329 minPwrT4[i] = data_4k[idxL].pwrPdg[i][0]; 347 minPwrT4[i] = data_4k[idxL].pwrPdg[i][0];
330 maxPwrT4[i] = data_4k[idxL].pwrPdg[i][4]; 348 maxPwrT4[i] = data_4k[idxL].pwrPdg[i][4];
331 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], 349 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
332 data_4k[idxL].pwrPdg[i], 350 data_4k[idxL].pwrPdg[i],
333 data_4k[idxL].vpdPdg[i], 351 data_4k[idxL].vpdPdg[i],
334 AR5416_PD_GAIN_ICEPTS, 352 intercepts,
335 vpdTableI[i]); 353 vpdTableI[i]);
336 } 354 }
337 } else { 355 } else {
@@ -341,13 +359,18 @@ void ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hw *ah,
341 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], 359 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
342 data_def[idxL].pwrPdg[i], 360 data_def[idxL].pwrPdg[i],
343 data_def[idxL].vpdPdg[i], 361 data_def[idxL].vpdPdg[i],
344 AR5416_PD_GAIN_ICEPTS, 362 intercepts,
345 vpdTableI[i]); 363 vpdTableI[i]);
346 } 364 }
347 } 365 }
348 } else { 366 } else {
349 for (i = 0; i < numXpdGains; i++) { 367 for (i = 0; i < numXpdGains; i++) {
350 if (eeprom_4k) { 368 if (AR_SREV_9287(ah)) {
369 pVpdL = data_9287[idxL].vpdPdg[i];
370 pPwrL = data_9287[idxL].pwrPdg[i];
371 pVpdR = data_9287[idxR].vpdPdg[i];
372 pPwrR = data_9287[idxR].pwrPdg[i];
373 } else if (eeprom_4k) {
351 pVpdL = data_4k[idxL].vpdPdg[i]; 374 pVpdL = data_4k[idxL].vpdPdg[i];
352 pPwrL = data_4k[idxL].pwrPdg[i]; 375 pPwrL = data_4k[idxL].pwrPdg[i];
353 pVpdR = data_4k[idxR].vpdPdg[i]; 376 pVpdR = data_4k[idxR].vpdPdg[i];
@@ -362,17 +385,17 @@ void ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hw *ah,
362 minPwrT4[i] = max(pPwrL[0], pPwrR[0]); 385 minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
363 386
364 maxPwrT4[i] = 387 maxPwrT4[i] =
365 min(pPwrL[AR5416_PD_GAIN_ICEPTS - 1], 388 min(pPwrL[intercepts - 1],
366 pPwrR[AR5416_PD_GAIN_ICEPTS - 1]); 389 pPwrR[intercepts - 1]);
367 390
368 391
369 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], 392 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
370 pPwrL, pVpdL, 393 pPwrL, pVpdL,
371 AR5416_PD_GAIN_ICEPTS, 394 intercepts,
372 vpdTableL[i]); 395 vpdTableL[i]);
373 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], 396 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
374 pPwrR, pVpdR, 397 pPwrR, pVpdR,
375 AR5416_PD_GAIN_ICEPTS, 398 intercepts,
376 vpdTableR[i]); 399 vpdTableR[i]);
377 400
378 for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) { 401 for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
index 4ba07da37457..868faf95ad2c 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
@@ -220,163 +220,6 @@ static u32 ath9k_hw_ar9287_get_eeprom(struct ath_hw *ah,
220 } 220 }
221} 221}
222 222
223static void ath9k_hw_get_ar9287_gain_boundaries_pdadcs(struct ath_hw *ah,
224 struct ath9k_channel *chan,
225 struct cal_data_per_freq_ar9287 *pRawDataSet,
226 u8 *bChans, u16 availPiers,
227 u16 tPdGainOverlap,
228 u16 *pPdGainBoundaries,
229 u8 *pPDADCValues,
230 u16 numXpdGains)
231{
232#define TMP_VAL_VPD_TABLE \
233 ((vpdTableI[i][sizeCurrVpdTable - 1] + (ss - maxIndex + 1) * vpdStep));
234
235 int i, j, k;
236 int16_t ss;
237 u16 idxL = 0, idxR = 0, numPiers;
238 u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
239 u8 minPwrT4[AR5416_NUM_PD_GAINS];
240 u8 maxPwrT4[AR5416_NUM_PD_GAINS];
241 int16_t vpdStep;
242 int16_t tmpVal;
243 u16 sizeCurrVpdTable, maxIndex, tgtIndex;
244 bool match;
245 int16_t minDelta = 0;
246 struct chan_centers centers;
247 static u8 vpdTableL[AR5416_EEP4K_NUM_PD_GAINS]
248 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
249 static u8 vpdTableR[AR5416_EEP4K_NUM_PD_GAINS]
250 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
251 static u8 vpdTableI[AR5416_EEP4K_NUM_PD_GAINS]
252 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
253
254 memset(&minPwrT4, 0, AR5416_NUM_PD_GAINS);
255 ath9k_hw_get_channel_centers(ah, chan, &centers);
256
257 for (numPiers = 0; numPiers < availPiers; numPiers++) {
258 if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
259 break;
260 }
261
262 match = ath9k_hw_get_lower_upper_index(
263 (u8)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)),
264 bChans, numPiers, &idxL, &idxR);
265
266 if (match) {
267 for (i = 0; i < numXpdGains; i++) {
268 minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
269 maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
270 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
271 pRawDataSet[idxL].pwrPdg[i],
272 pRawDataSet[idxL].vpdPdg[i],
273 AR9287_PD_GAIN_ICEPTS,
274 vpdTableI[i]);
275 }
276 } else {
277 for (i = 0; i < numXpdGains; i++) {
278 pVpdL = pRawDataSet[idxL].vpdPdg[i];
279 pPwrL = pRawDataSet[idxL].pwrPdg[i];
280 pVpdR = pRawDataSet[idxR].vpdPdg[i];
281 pPwrR = pRawDataSet[idxR].pwrPdg[i];
282
283 minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
284
285 maxPwrT4[i] = min(pPwrL[AR9287_PD_GAIN_ICEPTS - 1],
286 pPwrR[AR9287_PD_GAIN_ICEPTS - 1]);
287
288 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
289 pPwrL, pVpdL,
290 AR9287_PD_GAIN_ICEPTS,
291 vpdTableL[i]);
292 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
293 pPwrR, pVpdR,
294 AR9287_PD_GAIN_ICEPTS,
295 vpdTableR[i]);
296
297 for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
298 vpdTableI[i][j] = (u8)(ath9k_hw_interpolate(
299 (u16)FREQ2FBIN(centers. synth_center,
300 IS_CHAN_2GHZ(chan)),
301 bChans[idxL], bChans[idxR],
302 vpdTableL[i][j], vpdTableR[i][j]));
303 }
304 }
305 }
306
307 k = 0;
308
309 for (i = 0; i < numXpdGains; i++) {
310 if (i == (numXpdGains - 1))
311 pPdGainBoundaries[i] =
312 (u16)(maxPwrT4[i] / 2);
313 else
314 pPdGainBoundaries[i] =
315 (u16)((maxPwrT4[i] + minPwrT4[i+1]) / 4);
316
317 pPdGainBoundaries[i] = min((u16)MAX_RATE_POWER,
318 pPdGainBoundaries[i]);
319
320
321 minDelta = 0;
322
323 if (i == 0) {
324 if (AR_SREV_9280_20_OR_LATER(ah))
325 ss = (int16_t)(0 - (minPwrT4[i] / 2));
326 else
327 ss = 0;
328 } else {
329 ss = (int16_t)((pPdGainBoundaries[i-1] -
330 (minPwrT4[i] / 2)) -
331 tPdGainOverlap + 1 + minDelta);
332 }
333
334 vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
335 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
336
337 while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
338 tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
339 pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
340 ss++;
341 }
342
343 sizeCurrVpdTable = (u8)((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
344 tgtIndex = (u8)(pPdGainBoundaries[i] +
345 tPdGainOverlap - (minPwrT4[i] / 2));
346 maxIndex = (tgtIndex < sizeCurrVpdTable) ?
347 tgtIndex : sizeCurrVpdTable;
348
349 while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1)))
350 pPDADCValues[k++] = vpdTableI[i][ss++];
351
352 vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
353 vpdTableI[i][sizeCurrVpdTable - 2]);
354 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
355
356 if (tgtIndex > maxIndex) {
357 while ((ss <= tgtIndex) &&
358 (k < (AR5416_NUM_PDADC_VALUES - 1))) {
359 tmpVal = (int16_t) TMP_VAL_VPD_TABLE;
360 pPDADCValues[k++] =
361 (u8)((tmpVal > 255) ? 255 : tmpVal);
362 ss++;
363 }
364 }
365 }
366
367 while (i < AR5416_PD_GAINS_IN_MASK) {
368 pPdGainBoundaries[i] = pPdGainBoundaries[i-1];
369 i++;
370 }
371
372 while (k < AR5416_NUM_PDADC_VALUES) {
373 pPDADCValues[k] = pPDADCValues[k-1];
374 k++;
375 }
376
377#undef TMP_VAL_VPD_TABLE
378}
379
380static void ar9287_eeprom_get_tx_gain_index(struct ath_hw *ah, 223static void ar9287_eeprom_get_tx_gain_index(struct ath_hw *ah,
381 struct ath9k_channel *chan, 224 struct ath9k_channel *chan,
382 struct cal_data_op_loop_ar9287 *pRawDatasetOpLoop, 225 struct cal_data_op_loop_ar9287 *pRawDatasetOpLoop,
@@ -525,7 +368,7 @@ static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah,
525 (struct cal_data_per_freq_ar9287 *) 368 (struct cal_data_per_freq_ar9287 *)
526 pEepData->calPierData2G[i]; 369 pEepData->calPierData2G[i];
527 370
528 ath9k_hw_get_ar9287_gain_boundaries_pdadcs(ah, chan, 371 ath9k_hw_get_gain_boundaries_pdadcs(ah, chan,
529 pRawDataset, 372 pRawDataset,
530 pCalBChans, numPiers, 373 pCalBChans, numPiers,
531 pdGainOverlap_t2, 374 pdGainOverlap_t2,