diff options
author | Felix Fietkau <nbd@openwrt.org> | 2010-12-11 18:51:10 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-12-13 15:23:31 -0500 |
commit | 940cd2c12ebff688cfdc14f21c4b0e5b845ad47f (patch) | |
tree | fb5d8a4da3975d76c27e46848a1135d25015e939 | |
parent | 115277a3bc0683d04da797268ddafdc3bf67ca33 (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.c | 39 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/eeprom_9287.c | 159 |
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, ¢ers); | 322 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); |
@@ -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 | ||
223 | static 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, ¢ers); | ||
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 | |||
380 | static void ar9287_eeprom_get_tx_gain_index(struct ath_hw *ah, | 223 | static 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, |