diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/eeprom_9287.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/eeprom_9287.c | 618 |
1 files changed, 309 insertions, 309 deletions
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c index b471db5fb82d..39a41053705f 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c | |||
@@ -17,17 +17,19 @@ | |||
17 | #include "hw.h" | 17 | #include "hw.h" |
18 | #include "ar9002_phy.h" | 18 | #include "ar9002_phy.h" |
19 | 19 | ||
20 | static int ath9k_hw_AR9287_get_eeprom_ver(struct ath_hw *ah) | 20 | #define NUM_EEP_WORDS (sizeof(struct ar9287_eeprom) / sizeof(u16)) |
21 | |||
22 | static int ath9k_hw_ar9287_get_eeprom_ver(struct ath_hw *ah) | ||
21 | { | 23 | { |
22 | return (ah->eeprom.map9287.baseEepHeader.version >> 12) & 0xF; | 24 | return (ah->eeprom.map9287.baseEepHeader.version >> 12) & 0xF; |
23 | } | 25 | } |
24 | 26 | ||
25 | static int ath9k_hw_AR9287_get_eeprom_rev(struct ath_hw *ah) | 27 | static int ath9k_hw_ar9287_get_eeprom_rev(struct ath_hw *ah) |
26 | { | 28 | { |
27 | return (ah->eeprom.map9287.baseEepHeader.version) & 0xFFF; | 29 | return (ah->eeprom.map9287.baseEepHeader.version) & 0xFFF; |
28 | } | 30 | } |
29 | 31 | ||
30 | static bool ath9k_hw_AR9287_fill_eeprom(struct ath_hw *ah) | 32 | static bool ath9k_hw_ar9287_fill_eeprom(struct ath_hw *ah) |
31 | { | 33 | { |
32 | struct ar9287_eeprom *eep = &ah->eeprom.map9287; | 34 | struct ar9287_eeprom *eep = &ah->eeprom.map9287; |
33 | struct ath_common *common = ath9k_hw_common(ah); | 35 | struct ath_common *common = ath9k_hw_common(ah); |
@@ -40,20 +42,20 @@ static bool ath9k_hw_AR9287_fill_eeprom(struct ath_hw *ah) | |||
40 | "Reading from EEPROM, not flash\n"); | 42 | "Reading from EEPROM, not flash\n"); |
41 | } | 43 | } |
42 | 44 | ||
43 | for (addr = 0; addr < sizeof(struct ar9287_eeprom) / sizeof(u16); | 45 | for (addr = 0; addr < NUM_EEP_WORDS; addr++) { |
44 | addr++) { | 46 | if (!ath9k_hw_nvram_read(common, addr + eep_start_loc, |
45 | if (!ath9k_hw_nvram_read(common, | 47 | eep_data)) { |
46 | addr + eep_start_loc, eep_data)) { | ||
47 | ath_print(common, ATH_DBG_EEPROM, | 48 | ath_print(common, ATH_DBG_EEPROM, |
48 | "Unable to read eeprom region\n"); | 49 | "Unable to read eeprom region\n"); |
49 | return false; | 50 | return false; |
50 | } | 51 | } |
51 | eep_data++; | 52 | eep_data++; |
52 | } | 53 | } |
54 | |||
53 | return true; | 55 | return true; |
54 | } | 56 | } |
55 | 57 | ||
56 | static int ath9k_hw_AR9287_check_eeprom(struct ath_hw *ah) | 58 | static int ath9k_hw_ar9287_check_eeprom(struct ath_hw *ah) |
57 | { | 59 | { |
58 | u32 sum = 0, el, integer; | 60 | u32 sum = 0, el, integer; |
59 | u16 temp, word, magic, magic2, *eepdata; | 61 | u16 temp, word, magic, magic2, *eepdata; |
@@ -63,8 +65,8 @@ static int ath9k_hw_AR9287_check_eeprom(struct ath_hw *ah) | |||
63 | struct ath_common *common = ath9k_hw_common(ah); | 65 | struct ath_common *common = ath9k_hw_common(ah); |
64 | 66 | ||
65 | if (!ath9k_hw_use_flash(ah)) { | 67 | if (!ath9k_hw_use_flash(ah)) { |
66 | if (!ath9k_hw_nvram_read(common, | 68 | if (!ath9k_hw_nvram_read(common, AR5416_EEPROM_MAGIC_OFFSET, |
67 | AR5416_EEPROM_MAGIC_OFFSET, &magic)) { | 69 | &magic)) { |
68 | ath_print(common, ATH_DBG_FATAL, | 70 | ath_print(common, ATH_DBG_FATAL, |
69 | "Reading Magic # failed\n"); | 71 | "Reading Magic # failed\n"); |
70 | return false; | 72 | return false; |
@@ -72,6 +74,7 @@ static int ath9k_hw_AR9287_check_eeprom(struct ath_hw *ah) | |||
72 | 74 | ||
73 | ath_print(common, ATH_DBG_EEPROM, | 75 | ath_print(common, ATH_DBG_EEPROM, |
74 | "Read Magic = 0x%04X\n", magic); | 76 | "Read Magic = 0x%04X\n", magic); |
77 | |||
75 | if (magic != AR5416_EEPROM_MAGIC) { | 78 | if (magic != AR5416_EEPROM_MAGIC) { |
76 | magic2 = swab16(magic); | 79 | magic2 = swab16(magic); |
77 | 80 | ||
@@ -79,9 +82,7 @@ static int ath9k_hw_AR9287_check_eeprom(struct ath_hw *ah) | |||
79 | need_swap = true; | 82 | need_swap = true; |
80 | eepdata = (u16 *)(&ah->eeprom); | 83 | eepdata = (u16 *)(&ah->eeprom); |
81 | 84 | ||
82 | for (addr = 0; | 85 | for (addr = 0; addr < NUM_EEP_WORDS; addr++) { |
83 | addr < sizeof(struct ar9287_eeprom) / sizeof(u16); | ||
84 | addr++) { | ||
85 | temp = swab16(*eepdata); | 86 | temp = swab16(*eepdata); |
86 | *eepdata = temp; | 87 | *eepdata = temp; |
87 | eepdata++; | 88 | eepdata++; |
@@ -89,13 +90,14 @@ static int ath9k_hw_AR9287_check_eeprom(struct ath_hw *ah) | |||
89 | } else { | 90 | } else { |
90 | ath_print(common, ATH_DBG_FATAL, | 91 | ath_print(common, ATH_DBG_FATAL, |
91 | "Invalid EEPROM Magic. " | 92 | "Invalid EEPROM Magic. " |
92 | "endianness mismatch.\n"); | 93 | "Endianness mismatch.\n"); |
93 | return -EINVAL; | 94 | return -EINVAL; |
94 | } | 95 | } |
95 | } | 96 | } |
96 | } | 97 | } |
97 | ath_print(common, ATH_DBG_EEPROM, "need_swap = %s.\n", need_swap ? | 98 | |
98 | "True" : "False"); | 99 | ath_print(common, ATH_DBG_EEPROM, "need_swap = %s.\n", |
100 | need_swap ? "True" : "False"); | ||
99 | 101 | ||
100 | if (need_swap) | 102 | if (need_swap) |
101 | el = swab16(ah->eeprom.map9287.baseEepHeader.length); | 103 | el = swab16(ah->eeprom.map9287.baseEepHeader.length); |
@@ -108,6 +110,7 @@ static int ath9k_hw_AR9287_check_eeprom(struct ath_hw *ah) | |||
108 | el = el / sizeof(u16); | 110 | el = el / sizeof(u16); |
109 | 111 | ||
110 | eepdata = (u16 *)(&ah->eeprom); | 112 | eepdata = (u16 *)(&ah->eeprom); |
113 | |||
111 | for (i = 0; i < el; i++) | 114 | for (i = 0; i < el; i++) |
112 | sum ^= *eepdata++; | 115 | sum ^= *eepdata++; |
113 | 116 | ||
@@ -161,7 +164,7 @@ static int ath9k_hw_AR9287_check_eeprom(struct ath_hw *ah) | |||
161 | return 0; | 164 | return 0; |
162 | } | 165 | } |
163 | 166 | ||
164 | static u32 ath9k_hw_AR9287_get_eeprom(struct ath_hw *ah, | 167 | static u32 ath9k_hw_ar9287_get_eeprom(struct ath_hw *ah, |
165 | enum eeprom_param param) | 168 | enum eeprom_param param) |
166 | { | 169 | { |
167 | struct ar9287_eeprom *eep = &ah->eeprom.map9287; | 170 | struct ar9287_eeprom *eep = &ah->eeprom.map9287; |
@@ -170,6 +173,7 @@ static u32 ath9k_hw_AR9287_get_eeprom(struct ath_hw *ah, | |||
170 | u16 ver_minor; | 173 | u16 ver_minor; |
171 | 174 | ||
172 | ver_minor = pBase->version & AR9287_EEP_VER_MINOR_MASK; | 175 | ver_minor = pBase->version & AR9287_EEP_VER_MINOR_MASK; |
176 | |||
173 | switch (param) { | 177 | switch (param) { |
174 | case EEP_NFTHRESH_2: | 178 | case EEP_NFTHRESH_2: |
175 | return pModal->noiseFloorThreshCh[0]; | 179 | return pModal->noiseFloorThreshCh[0]; |
@@ -214,29 +218,30 @@ static u32 ath9k_hw_AR9287_get_eeprom(struct ath_hw *ah, | |||
214 | } | 218 | } |
215 | } | 219 | } |
216 | 220 | ||
217 | 221 | static void ath9k_hw_get_ar9287_gain_boundaries_pdadcs(struct ath_hw *ah, | |
218 | static void ath9k_hw_get_AR9287_gain_boundaries_pdadcs(struct ath_hw *ah, | 222 | struct ath9k_channel *chan, |
219 | struct ath9k_channel *chan, | 223 | struct cal_data_per_freq_ar9287 *pRawDataSet, |
220 | struct cal_data_per_freq_ar9287 *pRawDataSet, | 224 | u8 *bChans, u16 availPiers, |
221 | u8 *bChans, u16 availPiers, | 225 | u16 tPdGainOverlap, |
222 | u16 tPdGainOverlap, int16_t *pMinCalPower, | 226 | int16_t *pMinCalPower, |
223 | u16 *pPdGainBoundaries, u8 *pPDADCValues, | 227 | u16 *pPdGainBoundaries, |
224 | u16 numXpdGains) | 228 | u8 *pPDADCValues, |
229 | u16 numXpdGains) | ||
225 | { | 230 | { |
226 | #define TMP_VAL_VPD_TABLE \ | 231 | #define TMP_VAL_VPD_TABLE \ |
227 | ((vpdTableI[i][sizeCurrVpdTable - 1] + (ss - maxIndex + 1) * vpdStep)); | 232 | ((vpdTableI[i][sizeCurrVpdTable - 1] + (ss - maxIndex + 1) * vpdStep)); |
228 | 233 | ||
229 | int i, j, k; | 234 | int i, j, k; |
230 | int16_t ss; | 235 | int16_t ss; |
231 | u16 idxL = 0, idxR = 0, numPiers; | 236 | u16 idxL = 0, idxR = 0, numPiers; |
232 | u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR; | 237 | u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR; |
233 | u8 minPwrT4[AR9287_NUM_PD_GAINS]; | 238 | u8 minPwrT4[AR9287_NUM_PD_GAINS]; |
234 | u8 maxPwrT4[AR9287_NUM_PD_GAINS]; | 239 | u8 maxPwrT4[AR9287_NUM_PD_GAINS]; |
235 | int16_t vpdStep; | 240 | int16_t vpdStep; |
236 | int16_t tmpVal; | 241 | int16_t tmpVal; |
237 | u16 sizeCurrVpdTable, maxIndex, tgtIndex; | 242 | u16 sizeCurrVpdTable, maxIndex, tgtIndex; |
238 | bool match; | 243 | bool match; |
239 | int16_t minDelta = 0; | 244 | int16_t minDelta = 0; |
240 | struct chan_centers centers; | 245 | struct chan_centers centers; |
241 | static u8 vpdTableL[AR5416_EEP4K_NUM_PD_GAINS] | 246 | static u8 vpdTableL[AR5416_EEP4K_NUM_PD_GAINS] |
242 | [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; | 247 | [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; |
@@ -245,6 +250,7 @@ static void ath9k_hw_get_AR9287_gain_boundaries_pdadcs(struct ath_hw *ah, | |||
245 | static u8 vpdTableI[AR5416_EEP4K_NUM_PD_GAINS] | 250 | static u8 vpdTableI[AR5416_EEP4K_NUM_PD_GAINS] |
246 | [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; | 251 | [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; |
247 | 252 | ||
253 | memset(&minPwrT4, 0, AR9287_NUM_PD_GAINS); | ||
248 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); | 254 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); |
249 | 255 | ||
250 | for (numPiers = 0; numPiers < availPiers; numPiers++) { | 256 | for (numPiers = 0; numPiers < availPiers; numPiers++) { |
@@ -253,18 +259,18 @@ static void ath9k_hw_get_AR9287_gain_boundaries_pdadcs(struct ath_hw *ah, | |||
253 | } | 259 | } |
254 | 260 | ||
255 | match = ath9k_hw_get_lower_upper_index( | 261 | match = ath9k_hw_get_lower_upper_index( |
256 | (u8)FREQ2FBIN(centers.synth_center, | 262 | (u8)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)), |
257 | IS_CHAN_2GHZ(chan)), bChans, numPiers, | 263 | bChans, numPiers, &idxL, &idxR); |
258 | &idxL, &idxR); | ||
259 | 264 | ||
260 | if (match) { | 265 | if (match) { |
261 | for (i = 0; i < numXpdGains; i++) { | 266 | for (i = 0; i < numXpdGains; i++) { |
262 | minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0]; | 267 | minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0]; |
263 | maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4]; | 268 | maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4]; |
264 | ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], | 269 | ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], |
265 | pRawDataSet[idxL].pwrPdg[i], | 270 | pRawDataSet[idxL].pwrPdg[i], |
266 | pRawDataSet[idxL].vpdPdg[i], | 271 | pRawDataSet[idxL].vpdPdg[i], |
267 | AR9287_PD_GAIN_ICEPTS, vpdTableI[i]); | 272 | AR9287_PD_GAIN_ICEPTS, |
273 | vpdTableI[i]); | ||
268 | } | 274 | } |
269 | } else { | 275 | } else { |
270 | for (i = 0; i < numXpdGains; i++) { | 276 | for (i = 0; i < numXpdGains; i++) { |
@@ -275,61 +281,59 @@ static void ath9k_hw_get_AR9287_gain_boundaries_pdadcs(struct ath_hw *ah, | |||
275 | 281 | ||
276 | minPwrT4[i] = max(pPwrL[0], pPwrR[0]); | 282 | minPwrT4[i] = max(pPwrL[0], pPwrR[0]); |
277 | 283 | ||
278 | maxPwrT4[i] = | 284 | maxPwrT4[i] = min(pPwrL[AR9287_PD_GAIN_ICEPTS - 1], |
279 | min(pPwrL[AR9287_PD_GAIN_ICEPTS - 1], | 285 | pPwrR[AR9287_PD_GAIN_ICEPTS - 1]); |
280 | pPwrR[AR9287_PD_GAIN_ICEPTS - 1]); | ||
281 | 286 | ||
282 | ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], | 287 | ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], |
283 | pPwrL, pVpdL, | 288 | pPwrL, pVpdL, |
284 | AR9287_PD_GAIN_ICEPTS, | 289 | AR9287_PD_GAIN_ICEPTS, |
285 | vpdTableL[i]); | 290 | vpdTableL[i]); |
286 | ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], | 291 | ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], |
287 | pPwrR, pVpdR, | 292 | pPwrR, pVpdR, |
288 | AR9287_PD_GAIN_ICEPTS, | 293 | AR9287_PD_GAIN_ICEPTS, |
289 | vpdTableR[i]); | 294 | vpdTableR[i]); |
290 | 295 | ||
291 | for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) { | 296 | for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) { |
292 | vpdTableI[i][j] = | 297 | vpdTableI[i][j] = (u8)(ath9k_hw_interpolate( |
293 | (u8)(ath9k_hw_interpolate((u16) | 298 | (u16)FREQ2FBIN(centers. synth_center, |
294 | FREQ2FBIN(centers. synth_center, | 299 | IS_CHAN_2GHZ(chan)), |
295 | IS_CHAN_2GHZ(chan)), | 300 | bChans[idxL], bChans[idxR], |
296 | bChans[idxL], bChans[idxR], | 301 | vpdTableL[i][j], vpdTableR[i][j])); |
297 | vpdTableL[i][j], vpdTableR[i][j])); | ||
298 | } | 302 | } |
299 | } | 303 | } |
300 | } | 304 | } |
301 | *pMinCalPower = (int16_t)(minPwrT4[0] / 2); | ||
302 | 305 | ||
306 | *pMinCalPower = (int16_t)(minPwrT4[0] / 2); | ||
303 | k = 0; | 307 | k = 0; |
308 | |||
304 | for (i = 0; i < numXpdGains; i++) { | 309 | for (i = 0; i < numXpdGains; i++) { |
305 | if (i == (numXpdGains - 1)) | 310 | if (i == (numXpdGains - 1)) |
306 | pPdGainBoundaries[i] = (u16)(maxPwrT4[i] / 2); | 311 | pPdGainBoundaries[i] = |
312 | (u16)(maxPwrT4[i] / 2); | ||
307 | else | 313 | else |
308 | pPdGainBoundaries[i] = (u16)((maxPwrT4[i] + | 314 | pPdGainBoundaries[i] = |
309 | minPwrT4[i+1]) / 4); | 315 | (u16)((maxPwrT4[i] + minPwrT4[i+1]) / 4); |
310 | 316 | ||
311 | pPdGainBoundaries[i] = min((u16)AR5416_MAX_RATE_POWER, | 317 | pPdGainBoundaries[i] = min((u16)AR5416_MAX_RATE_POWER, |
312 | pPdGainBoundaries[i]); | 318 | pPdGainBoundaries[i]); |
313 | 319 | ||
314 | 320 | ||
315 | if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) { | 321 | minDelta = 0; |
316 | minDelta = pPdGainBoundaries[0] - 23; | ||
317 | pPdGainBoundaries[0] = 23; | ||
318 | } else | ||
319 | minDelta = 0; | ||
320 | 322 | ||
321 | if (i == 0) { | 323 | if (i == 0) { |
322 | if (AR_SREV_9280_10_OR_LATER(ah)) | 324 | if (AR_SREV_9280_10_OR_LATER(ah)) |
323 | ss = (int16_t)(0 - (minPwrT4[i] / 2)); | 325 | ss = (int16_t)(0 - (minPwrT4[i] / 2)); |
324 | else | 326 | else |
325 | ss = 0; | 327 | ss = 0; |
326 | } else | 328 | } else { |
327 | ss = (int16_t)((pPdGainBoundaries[i-1] - | 329 | ss = (int16_t)((pPdGainBoundaries[i-1] - |
328 | (minPwrT4[i] / 2)) - | 330 | (minPwrT4[i] / 2)) - |
329 | tPdGainOverlap + 1 + minDelta); | 331 | tPdGainOverlap + 1 + minDelta); |
332 | } | ||
330 | 333 | ||
331 | vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]); | 334 | vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]); |
332 | vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); | 335 | vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); |
336 | |||
333 | while ((ss < 0) && (k < (AR9287_NUM_PDADC_VALUES - 1))) { | 337 | while ((ss < 0) && (k < (AR9287_NUM_PDADC_VALUES - 1))) { |
334 | tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep); | 338 | tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep); |
335 | pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal); | 339 | pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal); |
@@ -348,12 +352,13 @@ static void ath9k_hw_get_AR9287_gain_boundaries_pdadcs(struct ath_hw *ah, | |||
348 | vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] - | 352 | vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] - |
349 | vpdTableI[i][sizeCurrVpdTable - 2]); | 353 | vpdTableI[i][sizeCurrVpdTable - 2]); |
350 | vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); | 354 | vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); |
355 | |||
351 | if (tgtIndex > maxIndex) { | 356 | if (tgtIndex > maxIndex) { |
352 | while ((ss <= tgtIndex) && | 357 | while ((ss <= tgtIndex) && |
353 | (k < (AR9287_NUM_PDADC_VALUES - 1))) { | 358 | (k < (AR9287_NUM_PDADC_VALUES - 1))) { |
354 | tmpVal = (int16_t) TMP_VAL_VPD_TABLE; | 359 | tmpVal = (int16_t) TMP_VAL_VPD_TABLE; |
355 | pPDADCValues[k++] = (u8)((tmpVal > 255) ? | 360 | pPDADCValues[k++] = |
356 | 255 : tmpVal); | 361 | (u8)((tmpVal > 255) ? 255 : tmpVal); |
357 | ss++; | 362 | ss++; |
358 | } | 363 | } |
359 | } | 364 | } |
@@ -375,10 +380,9 @@ static void ath9k_hw_get_AR9287_gain_boundaries_pdadcs(struct ath_hw *ah, | |||
375 | static void ar9287_eeprom_get_tx_gain_index(struct ath_hw *ah, | 380 | static void ar9287_eeprom_get_tx_gain_index(struct ath_hw *ah, |
376 | struct ath9k_channel *chan, | 381 | struct ath9k_channel *chan, |
377 | struct cal_data_op_loop_ar9287 *pRawDatasetOpLoop, | 382 | struct cal_data_op_loop_ar9287 *pRawDatasetOpLoop, |
378 | u8 *pCalChans, u16 availPiers, | 383 | u8 *pCalChans, u16 availPiers, int8_t *pPwr) |
379 | int8_t *pPwr) | ||
380 | { | 384 | { |
381 | u16 idxL = 0, idxR = 0, numPiers; | 385 | u16 idxL = 0, idxR = 0, numPiers; |
382 | bool match; | 386 | bool match; |
383 | struct chan_centers centers; | 387 | struct chan_centers centers; |
384 | 388 | ||
@@ -390,15 +394,14 @@ static void ar9287_eeprom_get_tx_gain_index(struct ath_hw *ah, | |||
390 | } | 394 | } |
391 | 395 | ||
392 | match = ath9k_hw_get_lower_upper_index( | 396 | match = ath9k_hw_get_lower_upper_index( |
393 | (u8)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)), | 397 | (u8)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)), |
394 | pCalChans, numPiers, | 398 | pCalChans, numPiers, &idxL, &idxR); |
395 | &idxL, &idxR); | ||
396 | 399 | ||
397 | if (match) { | 400 | if (match) { |
398 | *pPwr = (int8_t) pRawDatasetOpLoop[idxL].pwrPdg[0][0]; | 401 | *pPwr = (int8_t) pRawDatasetOpLoop[idxL].pwrPdg[0][0]; |
399 | } else { | 402 | } else { |
400 | *pPwr = ((int8_t) pRawDatasetOpLoop[idxL].pwrPdg[0][0] + | 403 | *pPwr = ((int8_t) pRawDatasetOpLoop[idxL].pwrPdg[0][0] + |
401 | (int8_t) pRawDatasetOpLoop[idxR].pwrPdg[0][0])/2; | 404 | (int8_t) pRawDatasetOpLoop[idxR].pwrPdg[0][0])/2; |
402 | } | 405 | } |
403 | 406 | ||
404 | } | 407 | } |
@@ -409,16 +412,22 @@ static void ar9287_eeprom_olpc_set_pdadcs(struct ath_hw *ah, | |||
409 | u32 tmpVal; | 412 | u32 tmpVal; |
410 | u32 a; | 413 | u32 a; |
411 | 414 | ||
415 | /* Enable OLPC for chain 0 */ | ||
416 | |||
412 | tmpVal = REG_READ(ah, 0xa270); | 417 | tmpVal = REG_READ(ah, 0xa270); |
413 | tmpVal = tmpVal & 0xFCFFFFFF; | 418 | tmpVal = tmpVal & 0xFCFFFFFF; |
414 | tmpVal = tmpVal | (0x3 << 24); | 419 | tmpVal = tmpVal | (0x3 << 24); |
415 | REG_WRITE(ah, 0xa270, tmpVal); | 420 | REG_WRITE(ah, 0xa270, tmpVal); |
416 | 421 | ||
422 | /* Enable OLPC for chain 1 */ | ||
423 | |||
417 | tmpVal = REG_READ(ah, 0xb270); | 424 | tmpVal = REG_READ(ah, 0xb270); |
418 | tmpVal = tmpVal & 0xFCFFFFFF; | 425 | tmpVal = tmpVal & 0xFCFFFFFF; |
419 | tmpVal = tmpVal | (0x3 << 24); | 426 | tmpVal = tmpVal | (0x3 << 24); |
420 | REG_WRITE(ah, 0xb270, tmpVal); | 427 | REG_WRITE(ah, 0xb270, tmpVal); |
421 | 428 | ||
429 | /* Write the OLPC ref power for chain 0 */ | ||
430 | |||
422 | if (chain == 0) { | 431 | if (chain == 0) { |
423 | tmpVal = REG_READ(ah, 0xa398); | 432 | tmpVal = REG_READ(ah, 0xa398); |
424 | tmpVal = tmpVal & 0xff00ffff; | 433 | tmpVal = tmpVal & 0xff00ffff; |
@@ -427,6 +436,8 @@ static void ar9287_eeprom_olpc_set_pdadcs(struct ath_hw *ah, | |||
427 | REG_WRITE(ah, 0xa398, tmpVal); | 436 | REG_WRITE(ah, 0xa398, tmpVal); |
428 | } | 437 | } |
429 | 438 | ||
439 | /* Write the OLPC ref power for chain 1 */ | ||
440 | |||
430 | if (chain == 1) { | 441 | if (chain == 1) { |
431 | tmpVal = REG_READ(ah, 0xb398); | 442 | tmpVal = REG_READ(ah, 0xb398); |
432 | tmpVal = tmpVal & 0xff00ffff; | 443 | tmpVal = tmpVal & 0xff00ffff; |
@@ -436,28 +447,29 @@ static void ar9287_eeprom_olpc_set_pdadcs(struct ath_hw *ah, | |||
436 | } | 447 | } |
437 | } | 448 | } |
438 | 449 | ||
439 | static void ath9k_hw_set_AR9287_power_cal_table(struct ath_hw *ah, | 450 | static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah, |
440 | struct ath9k_channel *chan, | 451 | struct ath9k_channel *chan, |
441 | int16_t *pTxPowerIndexOffset) | 452 | int16_t *pTxPowerIndexOffset) |
442 | { | 453 | { |
443 | struct ath_common *common = ath9k_hw_common(ah); | ||
444 | struct cal_data_per_freq_ar9287 *pRawDataset; | 454 | struct cal_data_per_freq_ar9287 *pRawDataset; |
445 | struct cal_data_op_loop_ar9287 *pRawDatasetOpenLoop; | 455 | struct cal_data_op_loop_ar9287 *pRawDatasetOpenLoop; |
446 | u8 *pCalBChans = NULL; | 456 | u8 *pCalBChans = NULL; |
447 | u16 pdGainOverlap_t2; | 457 | u16 pdGainOverlap_t2; |
448 | u8 pdadcValues[AR9287_NUM_PDADC_VALUES]; | 458 | u8 pdadcValues[AR9287_NUM_PDADC_VALUES]; |
449 | u16 gainBoundaries[AR9287_PD_GAINS_IN_MASK]; | 459 | u16 gainBoundaries[AR9287_PD_GAINS_IN_MASK]; |
450 | u16 numPiers = 0, i, j; | 460 | u16 numPiers = 0, i, j; |
451 | int16_t tMinCalPower; | 461 | int16_t tMinCalPower; |
452 | u16 numXpdGain, xpdMask; | 462 | u16 numXpdGain, xpdMask; |
453 | u16 xpdGainValues[AR9287_NUM_PD_GAINS] = {0, 0, 0, 0}; | 463 | u16 xpdGainValues[AR9287_NUM_PD_GAINS] = {0, 0, 0, 0}; |
454 | u32 reg32, regOffset, regChainOffset; | 464 | u32 reg32, regOffset, regChainOffset, regval; |
455 | int16_t modalIdx, diff = 0; | 465 | int16_t modalIdx, diff = 0; |
456 | struct ar9287_eeprom *pEepData = &ah->eeprom.map9287; | 466 | struct ar9287_eeprom *pEepData = &ah->eeprom.map9287; |
467 | |||
457 | modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0; | 468 | modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0; |
458 | xpdMask = pEepData->modalHeader.xpdGain; | 469 | xpdMask = pEepData->modalHeader.xpdGain; |
470 | |||
459 | if ((pEepData->baseEepHeader.version & AR9287_EEP_VER_MINOR_MASK) >= | 471 | if ((pEepData->baseEepHeader.version & AR9287_EEP_VER_MINOR_MASK) >= |
460 | AR9287_EEP_MINOR_VER_2) | 472 | AR9287_EEP_MINOR_VER_2) |
461 | pdGainOverlap_t2 = pEepData->modalHeader.pdGainOverlap; | 473 | pdGainOverlap_t2 = pEepData->modalHeader.pdGainOverlap; |
462 | else | 474 | else |
463 | pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5), | 475 | pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5), |
@@ -466,15 +478,16 @@ static void ath9k_hw_set_AR9287_power_cal_table(struct ath_hw *ah, | |||
466 | if (IS_CHAN_2GHZ(chan)) { | 478 | if (IS_CHAN_2GHZ(chan)) { |
467 | pCalBChans = pEepData->calFreqPier2G; | 479 | pCalBChans = pEepData->calFreqPier2G; |
468 | numPiers = AR9287_NUM_2G_CAL_PIERS; | 480 | numPiers = AR9287_NUM_2G_CAL_PIERS; |
469 | if (ath9k_hw_AR9287_get_eeprom(ah, EEP_OL_PWRCTRL)) { | 481 | if (ath9k_hw_ar9287_get_eeprom(ah, EEP_OL_PWRCTRL)) { |
470 | pRawDatasetOpenLoop = | 482 | pRawDatasetOpenLoop = |
471 | (struct cal_data_op_loop_ar9287 *) | 483 | (struct cal_data_op_loop_ar9287 *)pEepData->calPierData2G[0]; |
472 | pEepData->calPierData2G[0]; | ||
473 | ah->initPDADC = pRawDatasetOpenLoop->vpdPdg[0][0]; | 484 | ah->initPDADC = pRawDatasetOpenLoop->vpdPdg[0][0]; |
474 | } | 485 | } |
475 | } | 486 | } |
476 | 487 | ||
477 | numXpdGain = 0; | 488 | numXpdGain = 0; |
489 | |||
490 | /* Calculate the value of xpdgains from the xpdGain Mask */ | ||
478 | for (i = 1; i <= AR9287_PD_GAINS_IN_MASK; i++) { | 491 | for (i = 1; i <= AR9287_PD_GAINS_IN_MASK; i++) { |
479 | if ((xpdMask >> (AR9287_PD_GAINS_IN_MASK - i)) & 1) { | 492 | if ((xpdMask >> (AR9287_PD_GAINS_IN_MASK - i)) & 1) { |
480 | if (numXpdGain >= AR9287_NUM_PD_GAINS) | 493 | if (numXpdGain >= AR9287_NUM_PD_GAINS) |
@@ -496,99 +509,80 @@ static void ath9k_hw_set_AR9287_power_cal_table(struct ath_hw *ah, | |||
496 | 509 | ||
497 | for (i = 0; i < AR9287_MAX_CHAINS; i++) { | 510 | for (i = 0; i < AR9287_MAX_CHAINS; i++) { |
498 | regChainOffset = i * 0x1000; | 511 | regChainOffset = i * 0x1000; |
512 | |||
499 | if (pEepData->baseEepHeader.txMask & (1 << i)) { | 513 | if (pEepData->baseEepHeader.txMask & (1 << i)) { |
500 | pRawDatasetOpenLoop = (struct cal_data_op_loop_ar9287 *) | 514 | pRawDatasetOpenLoop = |
501 | pEepData->calPierData2G[i]; | 515 | (struct cal_data_op_loop_ar9287 *)pEepData->calPierData2G[i]; |
502 | if (ath9k_hw_AR9287_get_eeprom(ah, EEP_OL_PWRCTRL)) { | 516 | |
517 | if (ath9k_hw_ar9287_get_eeprom(ah, EEP_OL_PWRCTRL)) { | ||
503 | int8_t txPower; | 518 | int8_t txPower; |
504 | ar9287_eeprom_get_tx_gain_index(ah, chan, | 519 | ar9287_eeprom_get_tx_gain_index(ah, chan, |
505 | pRawDatasetOpenLoop, | 520 | pRawDatasetOpenLoop, |
506 | pCalBChans, numPiers, | 521 | pCalBChans, numPiers, |
507 | &txPower); | 522 | &txPower); |
508 | ar9287_eeprom_olpc_set_pdadcs(ah, txPower, i); | 523 | ar9287_eeprom_olpc_set_pdadcs(ah, txPower, i); |
509 | } else { | 524 | } else { |
510 | pRawDataset = | 525 | pRawDataset = |
511 | (struct cal_data_per_freq_ar9287 *) | 526 | (struct cal_data_per_freq_ar9287 *) |
512 | pEepData->calPierData2G[i]; | 527 | pEepData->calPierData2G[i]; |
513 | ath9k_hw_get_AR9287_gain_boundaries_pdadcs( | 528 | |
514 | ah, chan, pRawDataset, | 529 | ath9k_hw_get_ar9287_gain_boundaries_pdadcs(ah, chan, |
515 | pCalBChans, numPiers, | 530 | pRawDataset, |
516 | pdGainOverlap_t2, | 531 | pCalBChans, numPiers, |
517 | &tMinCalPower, gainBoundaries, | 532 | pdGainOverlap_t2, |
518 | pdadcValues, numXpdGain); | 533 | &tMinCalPower, |
534 | gainBoundaries, | ||
535 | pdadcValues, | ||
536 | numXpdGain); | ||
519 | } | 537 | } |
520 | 538 | ||
521 | if (i == 0) { | 539 | if (i == 0) { |
522 | if (!ath9k_hw_AR9287_get_eeprom( | 540 | if (!ath9k_hw_ar9287_get_eeprom(ah, |
523 | ah, EEP_OL_PWRCTRL)) { | 541 | EEP_OL_PWRCTRL)) { |
524 | REG_WRITE(ah, AR_PHY_TPCRG5 + | 542 | |
525 | regChainOffset, | 543 | regval = SM(pdGainOverlap_t2, |
526 | SM(pdGainOverlap_t2, | 544 | AR_PHY_TPCRG5_PD_GAIN_OVERLAP) |
527 | AR_PHY_TPCRG5_PD_GAIN_OVERLAP) | | 545 | | SM(gainBoundaries[0], |
528 | SM(gainBoundaries[0], | 546 | AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1) |
529 | AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1) | 547 | | SM(gainBoundaries[1], |
530 | | SM(gainBoundaries[1], | 548 | AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2) |
531 | AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2) | 549 | | SM(gainBoundaries[2], |
532 | | SM(gainBoundaries[2], | 550 | AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3) |
533 | AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3) | 551 | | SM(gainBoundaries[3], |
534 | | SM(gainBoundaries[3], | 552 | AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4); |
535 | AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4)); | 553 | |
554 | REG_WRITE(ah, | ||
555 | AR_PHY_TPCRG5 + regChainOffset, | ||
556 | regval); | ||
536 | } | 557 | } |
537 | } | 558 | } |
538 | 559 | ||
539 | if ((int32_t)AR9287_PWR_TABLE_OFFSET_DB != | 560 | if ((int32_t)AR9287_PWR_TABLE_OFFSET_DB != |
540 | pEepData->baseEepHeader.pwrTableOffset) { | 561 | pEepData->baseEepHeader.pwrTableOffset) { |
541 | diff = (u16) | 562 | diff = (u16)(pEepData->baseEepHeader.pwrTableOffset - |
542 | (pEepData->baseEepHeader.pwrTableOffset | 563 | (int32_t)AR9287_PWR_TABLE_OFFSET_DB); |
543 | - (int32_t)AR9287_PWR_TABLE_OFFSET_DB); | ||
544 | diff *= 2; | 564 | diff *= 2; |
545 | 565 | ||
546 | for (j = 0; | 566 | for (j = 0; j < ((u16)AR9287_NUM_PDADC_VALUES-diff); j++) |
547 | j < ((u16)AR9287_NUM_PDADC_VALUES-diff); | ||
548 | j++) | ||
549 | pdadcValues[j] = pdadcValues[j+diff]; | 567 | pdadcValues[j] = pdadcValues[j+diff]; |
550 | 568 | ||
551 | for (j = (u16)(AR9287_NUM_PDADC_VALUES-diff); | 569 | for (j = (u16)(AR9287_NUM_PDADC_VALUES-diff); |
552 | j < AR9287_NUM_PDADC_VALUES; j++) | 570 | j < AR9287_NUM_PDADC_VALUES; j++) |
553 | pdadcValues[j] = | 571 | pdadcValues[j] = |
554 | pdadcValues[ | 572 | pdadcValues[AR9287_NUM_PDADC_VALUES-diff]; |
555 | AR9287_NUM_PDADC_VALUES-diff]; | ||
556 | } | 573 | } |
557 | 574 | ||
558 | if (!ath9k_hw_AR9287_get_eeprom(ah, EEP_OL_PWRCTRL)) { | 575 | if (!ath9k_hw_ar9287_get_eeprom(ah, EEP_OL_PWRCTRL)) { |
559 | regOffset = AR_PHY_BASE + (672 << 2) + | 576 | regOffset = AR_PHY_BASE + |
560 | regChainOffset; | 577 | (672 << 2) + regChainOffset; |
561 | for (j = 0; j < 32; j++) { | ||
562 | reg32 = ((pdadcValues[4*j + 0] | ||
563 | & 0xFF) << 0) | | ||
564 | ((pdadcValues[4*j + 1] | ||
565 | & 0xFF) << 8) | | ||
566 | ((pdadcValues[4*j + 2] | ||
567 | & 0xFF) << 16) | | ||
568 | ((pdadcValues[4*j + 3] | ||
569 | & 0xFF) << 24) ; | ||
570 | REG_WRITE(ah, regOffset, reg32); | ||
571 | 578 | ||
572 | ath_print(common, ATH_DBG_EEPROM, | 579 | for (j = 0; j < 32; j++) { |
573 | "PDADC (%d,%4x): %4.4x " | 580 | reg32 = ((pdadcValues[4*j + 0] & 0xFF) << 0) |
574 | "%8.8x\n", | 581 | | ((pdadcValues[4*j + 1] & 0xFF) << 8) |
575 | i, regChainOffset, regOffset, | 582 | | ((pdadcValues[4*j + 2] & 0xFF) << 16) |
576 | reg32); | 583 | | ((pdadcValues[4*j + 3] & 0xFF) << 24); |
577 | |||
578 | ath_print(common, ATH_DBG_EEPROM, | ||
579 | "PDADC: Chain %d | " | ||
580 | "PDADC %3d Value %3d | " | ||
581 | "PDADC %3d Value %3d | " | ||
582 | "PDADC %3d Value %3d | " | ||
583 | "PDADC %3d Value %3d |\n", | ||
584 | i, 4 * j, pdadcValues[4 * j], | ||
585 | 4 * j + 1, | ||
586 | pdadcValues[4 * j + 1], | ||
587 | 4 * j + 2, | ||
588 | pdadcValues[4 * j + 2], | ||
589 | 4 * j + 3, | ||
590 | pdadcValues[4 * j + 3]); | ||
591 | 584 | ||
585 | REG_WRITE(ah, regOffset, reg32); | ||
592 | regOffset += 4; | 586 | regOffset += 4; |
593 | } | 587 | } |
594 | } | 588 | } |
@@ -598,30 +592,45 @@ static void ath9k_hw_set_AR9287_power_cal_table(struct ath_hw *ah, | |||
598 | *pTxPowerIndexOffset = 0; | 592 | *pTxPowerIndexOffset = 0; |
599 | } | 593 | } |
600 | 594 | ||
601 | static void ath9k_hw_set_AR9287_power_per_rate_table(struct ath_hw *ah, | 595 | static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah, |
602 | struct ath9k_channel *chan, int16_t *ratesArray, u16 cfgCtl, | 596 | struct ath9k_channel *chan, |
603 | u16 AntennaReduction, u16 twiceMaxRegulatoryPower, | 597 | int16_t *ratesArray, |
604 | u16 powerLimit) | 598 | u16 cfgCtl, |
599 | u16 AntennaReduction, | ||
600 | u16 twiceMaxRegulatoryPower, | ||
601 | u16 powerLimit) | ||
605 | { | 602 | { |
603 | #define CMP_CTL \ | ||
604 | (((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == \ | ||
605 | pEepData->ctlIndex[i]) | ||
606 | |||
607 | #define CMP_NO_CTL \ | ||
608 | (((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == \ | ||
609 | ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL)) | ||
610 | |||
606 | #define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 | 611 | #define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 |
607 | #define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10 | 612 | #define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10 |
613 | |||
608 | struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); | 614 | struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); |
609 | u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER; | 615 | u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER; |
610 | static const u16 tpScaleReductionTable[5] = | 616 | static const u16 tpScaleReductionTable[5] = |
611 | { 0, 3, 6, 9, AR5416_MAX_RATE_POWER }; | 617 | { 0, 3, 6, 9, AR5416_MAX_RATE_POWER }; |
612 | int i; | 618 | int i; |
613 | int16_t twiceLargestAntenna; | 619 | int16_t twiceLargestAntenna; |
614 | struct cal_ctl_data_ar9287 *rep; | 620 | struct cal_ctl_data_ar9287 *rep; |
615 | struct cal_target_power_leg targetPowerOfdm = {0, {0, 0, 0, 0} }, | 621 | struct cal_target_power_leg targetPowerOfdm = {0, {0, 0, 0, 0} }, |
616 | targetPowerCck = {0, {0, 0, 0, 0} }; | 622 | targetPowerCck = {0, {0, 0, 0, 0} }; |
617 | struct cal_target_power_leg targetPowerOfdmExt = {0, {0, 0, 0, 0} }, | 623 | struct cal_target_power_leg targetPowerOfdmExt = {0, {0, 0, 0, 0} }, |
618 | targetPowerCckExt = {0, {0, 0, 0, 0} }; | 624 | targetPowerCckExt = {0, {0, 0, 0, 0} }; |
619 | struct cal_target_power_ht targetPowerHt20, | 625 | struct cal_target_power_ht targetPowerHt20, |
620 | targetPowerHt40 = {0, {0, 0, 0, 0} }; | 626 | targetPowerHt40 = {0, {0, 0, 0, 0} }; |
621 | u16 scaledPower = 0, minCtlPower, maxRegAllowedPower; | 627 | u16 scaledPower = 0, minCtlPower, maxRegAllowedPower; |
622 | u16 ctlModesFor11g[] = | 628 | u16 ctlModesFor11g[] = {CTL_11B, |
623 | {CTL_11B, CTL_11G, CTL_2GHT20, | 629 | CTL_11G, |
624 | CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40}; | 630 | CTL_2GHT20, |
631 | CTL_11B_EXT, | ||
632 | CTL_11G_EXT, | ||
633 | CTL_2GHT40}; | ||
625 | u16 numCtlModes = 0, *pCtlMode = NULL, ctlMode, freq; | 634 | u16 numCtlModes = 0, *pCtlMode = NULL, ctlMode, freq; |
626 | struct chan_centers centers; | 635 | struct chan_centers centers; |
627 | int tx_chainmask; | 636 | int tx_chainmask; |
@@ -631,19 +640,28 @@ static void ath9k_hw_set_AR9287_power_per_rate_table(struct ath_hw *ah, | |||
631 | 640 | ||
632 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); | 641 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); |
633 | 642 | ||
643 | /* Compute TxPower reduction due to Antenna Gain */ | ||
634 | twiceLargestAntenna = max(pEepData->modalHeader.antennaGainCh[0], | 644 | twiceLargestAntenna = max(pEepData->modalHeader.antennaGainCh[0], |
635 | pEepData->modalHeader.antennaGainCh[1]); | 645 | pEepData->modalHeader.antennaGainCh[1]); |
646 | twiceLargestAntenna = (int16_t)min((AntennaReduction) - | ||
647 | twiceLargestAntenna, 0); | ||
636 | 648 | ||
637 | twiceLargestAntenna = (int16_t)min((AntennaReduction) - | 649 | /* |
638 | twiceLargestAntenna, 0); | 650 | * scaledPower is the minimum of the user input power level |
639 | 651 | * and the regulatory allowed power level. | |
652 | */ | ||
640 | maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna; | 653 | maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna; |
654 | |||
641 | if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) | 655 | if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) |
642 | maxRegAllowedPower -= | 656 | maxRegAllowedPower -= |
643 | (tpScaleReductionTable[(regulatory->tp_scale)] * 2); | 657 | (tpScaleReductionTable[(regulatory->tp_scale)] * 2); |
644 | 658 | ||
645 | scaledPower = min(powerLimit, maxRegAllowedPower); | 659 | scaledPower = min(powerLimit, maxRegAllowedPower); |
646 | 660 | ||
661 | /* | ||
662 | * Reduce scaled Power by number of chains active | ||
663 | * to get the per chain tx power level. | ||
664 | */ | ||
647 | switch (ar5416_get_ntxchains(tx_chainmask)) { | 665 | switch (ar5416_get_ntxchains(tx_chainmask)) { |
648 | case 1: | 666 | case 1: |
649 | break; | 667 | break; |
@@ -656,9 +674,14 @@ static void ath9k_hw_set_AR9287_power_per_rate_table(struct ath_hw *ah, | |||
656 | } | 674 | } |
657 | scaledPower = max((u16)0, scaledPower); | 675 | scaledPower = max((u16)0, scaledPower); |
658 | 676 | ||
677 | /* | ||
678 | * Get TX power from EEPROM. | ||
679 | */ | ||
659 | if (IS_CHAN_2GHZ(chan)) { | 680 | if (IS_CHAN_2GHZ(chan)) { |
681 | /* CTL_11B, CTL_11G, CTL_2GHT20 */ | ||
660 | numCtlModes = | 682 | numCtlModes = |
661 | ARRAY_SIZE(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40; | 683 | ARRAY_SIZE(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40; |
684 | |||
662 | pCtlMode = ctlModesFor11g; | 685 | pCtlMode = ctlModesFor11g; |
663 | 686 | ||
664 | ath9k_hw_get_legacy_target_powers(ah, chan, | 687 | ath9k_hw_get_legacy_target_powers(ah, chan, |
@@ -675,6 +698,7 @@ static void ath9k_hw_set_AR9287_power_per_rate_table(struct ath_hw *ah, | |||
675 | &targetPowerHt20, 8, false); | 698 | &targetPowerHt20, 8, false); |
676 | 699 | ||
677 | if (IS_CHAN_HT40(chan)) { | 700 | if (IS_CHAN_HT40(chan)) { |
701 | /* All 2G CTLs */ | ||
678 | numCtlModes = ARRAY_SIZE(ctlModesFor11g); | 702 | numCtlModes = ARRAY_SIZE(ctlModesFor11g); |
679 | ath9k_hw_get_target_powers(ah, chan, | 703 | ath9k_hw_get_target_powers(ah, chan, |
680 | pEepData->calTargetPower2GHT40, | 704 | pEepData->calTargetPower2GHT40, |
@@ -692,8 +716,9 @@ static void ath9k_hw_set_AR9287_power_per_rate_table(struct ath_hw *ah, | |||
692 | } | 716 | } |
693 | 717 | ||
694 | for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) { | 718 | for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) { |
695 | bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) || | 719 | bool isHt40CtlMode = |
696 | (pCtlMode[ctlMode] == CTL_2GHT40); | 720 | (pCtlMode[ctlMode] == CTL_2GHT40) ? true : false; |
721 | |||
697 | if (isHt40CtlMode) | 722 | if (isHt40CtlMode) |
698 | freq = centers.synth_center; | 723 | freq = centers.synth_center; |
699 | else if (pCtlMode[ctlMode] & EXT_ADDITIVE) | 724 | else if (pCtlMode[ctlMode] & EXT_ADDITIVE) |
@@ -701,31 +726,28 @@ static void ath9k_hw_set_AR9287_power_per_rate_table(struct ath_hw *ah, | |||
701 | else | 726 | else |
702 | freq = centers.ctl_center; | 727 | freq = centers.ctl_center; |
703 | 728 | ||
704 | if (ah->eep_ops->get_eeprom_ver(ah) == 14 && | 729 | /* Walk through the CTL indices stored in EEPROM */ |
705 | ah->eep_ops->get_eeprom_rev(ah) <= 2) | ||
706 | twiceMaxEdgePower = AR5416_MAX_RATE_POWER; | ||
707 | |||
708 | for (i = 0; (i < AR9287_NUM_CTLS) && pEepData->ctlIndex[i]; i++) { | 730 | for (i = 0; (i < AR9287_NUM_CTLS) && pEepData->ctlIndex[i]; i++) { |
709 | if ((((cfgCtl & ~CTL_MODE_M) | | 731 | struct cal_ctl_edges *pRdEdgesPower; |
710 | (pCtlMode[ctlMode] & CTL_MODE_M)) == | ||
711 | pEepData->ctlIndex[i]) || | ||
712 | (((cfgCtl & ~CTL_MODE_M) | | ||
713 | (pCtlMode[ctlMode] & CTL_MODE_M)) == | ||
714 | ((pEepData->ctlIndex[i] & | ||
715 | CTL_MODE_M) | SD_NO_CTL))) { | ||
716 | 732 | ||
733 | /* | ||
734 | * Compare test group from regulatory channel list | ||
735 | * with test mode from pCtlMode list | ||
736 | */ | ||
737 | if (CMP_CTL || CMP_NO_CTL) { | ||
717 | rep = &(pEepData->ctlData[i]); | 738 | rep = &(pEepData->ctlData[i]); |
718 | twiceMinEdgePower = ath9k_hw_get_max_edge_power( | 739 | pRdEdgesPower = |
719 | freq, | 740 | rep->ctlEdges[ar5416_get_ntxchains(tx_chainmask) - 1]; |
720 | rep->ctlEdges[ar5416_get_ntxchains( | 741 | |
721 | tx_chainmask) - 1], | 742 | twiceMinEdgePower = ath9k_hw_get_max_edge_power(freq, |
722 | IS_CHAN_2GHZ(chan), AR5416_NUM_BAND_EDGES); | 743 | pRdEdgesPower, |
723 | 744 | IS_CHAN_2GHZ(chan), | |
724 | if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) | 745 | AR5416_NUM_BAND_EDGES); |
725 | twiceMaxEdgePower = min( | 746 | |
726 | twiceMaxEdgePower, | 747 | if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) { |
727 | twiceMinEdgePower); | 748 | twiceMaxEdgePower = min(twiceMaxEdgePower, |
728 | else { | 749 | twiceMinEdgePower); |
750 | } else { | ||
729 | twiceMaxEdgePower = twiceMinEdgePower; | 751 | twiceMaxEdgePower = twiceMinEdgePower; |
730 | break; | 752 | break; |
731 | } | 753 | } |
@@ -734,55 +756,48 @@ static void ath9k_hw_set_AR9287_power_per_rate_table(struct ath_hw *ah, | |||
734 | 756 | ||
735 | minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower); | 757 | minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower); |
736 | 758 | ||
759 | /* Apply ctl mode to correct target power set */ | ||
737 | switch (pCtlMode[ctlMode]) { | 760 | switch (pCtlMode[ctlMode]) { |
738 | case CTL_11B: | 761 | case CTL_11B: |
739 | for (i = 0; | 762 | for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); i++) { |
740 | i < ARRAY_SIZE(targetPowerCck.tPow2x); | 763 | targetPowerCck.tPow2x[i] = |
741 | i++) { | 764 | (u8)min((u16)targetPowerCck.tPow2x[i], |
742 | targetPowerCck.tPow2x[i] = (u8)min( | 765 | minCtlPower); |
743 | (u16)targetPowerCck.tPow2x[i], | ||
744 | minCtlPower); | ||
745 | } | 766 | } |
746 | break; | 767 | break; |
747 | case CTL_11A: | 768 | case CTL_11A: |
748 | case CTL_11G: | 769 | case CTL_11G: |
749 | for (i = 0; | 770 | for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) { |
750 | i < ARRAY_SIZE(targetPowerOfdm.tPow2x); | 771 | targetPowerOfdm.tPow2x[i] = |
751 | i++) { | 772 | (u8)min((u16)targetPowerOfdm.tPow2x[i], |
752 | targetPowerOfdm.tPow2x[i] = (u8)min( | 773 | minCtlPower); |
753 | (u16)targetPowerOfdm.tPow2x[i], | ||
754 | minCtlPower); | ||
755 | } | 774 | } |
756 | break; | 775 | break; |
757 | case CTL_5GHT20: | 776 | case CTL_5GHT20: |
758 | case CTL_2GHT20: | 777 | case CTL_2GHT20: |
759 | for (i = 0; | 778 | for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) { |
760 | i < ARRAY_SIZE(targetPowerHt20.tPow2x); | 779 | targetPowerHt20.tPow2x[i] = |
761 | i++) { | 780 | (u8)min((u16)targetPowerHt20.tPow2x[i], |
762 | targetPowerHt20.tPow2x[i] = (u8)min( | 781 | minCtlPower); |
763 | (u16)targetPowerHt20.tPow2x[i], | ||
764 | minCtlPower); | ||
765 | } | 782 | } |
766 | break; | 783 | break; |
767 | case CTL_11B_EXT: | 784 | case CTL_11B_EXT: |
768 | targetPowerCckExt.tPow2x[0] = (u8)min( | 785 | targetPowerCckExt.tPow2x[0] = |
769 | (u16)targetPowerCckExt.tPow2x[0], | 786 | (u8)min((u16)targetPowerCckExt.tPow2x[0], |
770 | minCtlPower); | 787 | minCtlPower); |
771 | break; | 788 | break; |
772 | case CTL_11A_EXT: | 789 | case CTL_11A_EXT: |
773 | case CTL_11G_EXT: | 790 | case CTL_11G_EXT: |
774 | targetPowerOfdmExt.tPow2x[0] = (u8)min( | 791 | targetPowerOfdmExt.tPow2x[0] = |
775 | (u16)targetPowerOfdmExt.tPow2x[0], | 792 | (u8)min((u16)targetPowerOfdmExt.tPow2x[0], |
776 | minCtlPower); | 793 | minCtlPower); |
777 | break; | 794 | break; |
778 | case CTL_5GHT40: | 795 | case CTL_5GHT40: |
779 | case CTL_2GHT40: | 796 | case CTL_2GHT40: |
780 | for (i = 0; | 797 | for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) { |
781 | i < ARRAY_SIZE(targetPowerHt40.tPow2x); | 798 | targetPowerHt40.tPow2x[i] = |
782 | i++) { | 799 | (u8)min((u16)targetPowerHt40.tPow2x[i], |
783 | targetPowerHt40.tPow2x[i] = (u8)min( | 800 | minCtlPower); |
784 | (u16)targetPowerHt40.tPow2x[i], | ||
785 | minCtlPower); | ||
786 | } | 801 | } |
787 | break; | 802 | break; |
788 | default: | 803 | default: |
@@ -790,12 +805,13 @@ static void ath9k_hw_set_AR9287_power_per_rate_table(struct ath_hw *ah, | |||
790 | } | 805 | } |
791 | } | 806 | } |
792 | 807 | ||
808 | /* Now set the rates array */ | ||
809 | |||
793 | ratesArray[rate6mb] = | 810 | ratesArray[rate6mb] = |
794 | ratesArray[rate9mb] = | 811 | ratesArray[rate9mb] = |
795 | ratesArray[rate12mb] = | 812 | ratesArray[rate12mb] = |
796 | ratesArray[rate18mb] = | 813 | ratesArray[rate18mb] = |
797 | ratesArray[rate24mb] = | 814 | ratesArray[rate24mb] = targetPowerOfdm.tPow2x[0]; |
798 | targetPowerOfdm.tPow2x[0]; | ||
799 | 815 | ||
800 | ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1]; | 816 | ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1]; |
801 | ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2]; | 817 | ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2]; |
@@ -807,12 +823,12 @@ static void ath9k_hw_set_AR9287_power_per_rate_table(struct ath_hw *ah, | |||
807 | 823 | ||
808 | if (IS_CHAN_2GHZ(chan)) { | 824 | if (IS_CHAN_2GHZ(chan)) { |
809 | ratesArray[rate1l] = targetPowerCck.tPow2x[0]; | 825 | ratesArray[rate1l] = targetPowerCck.tPow2x[0]; |
810 | ratesArray[rate2s] = ratesArray[rate2l] = | 826 | ratesArray[rate2s] = |
811 | targetPowerCck.tPow2x[1]; | 827 | ratesArray[rate2l] = targetPowerCck.tPow2x[1]; |
812 | ratesArray[rate5_5s] = ratesArray[rate5_5l] = | 828 | ratesArray[rate5_5s] = |
813 | targetPowerCck.tPow2x[2]; | 829 | ratesArray[rate5_5l] = targetPowerCck.tPow2x[2]; |
814 | ratesArray[rate11s] = ratesArray[rate11l] = | 830 | ratesArray[rate11s] = |
815 | targetPowerCck.tPow2x[3]; | 831 | ratesArray[rate11l] = targetPowerCck.tPow2x[3]; |
816 | } | 832 | } |
817 | if (IS_CHAN_HT40(chan)) { | 833 | if (IS_CHAN_HT40(chan)) { |
818 | for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) | 834 | for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) |
@@ -821,28 +837,28 @@ static void ath9k_hw_set_AR9287_power_per_rate_table(struct ath_hw *ah, | |||
821 | ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0]; | 837 | ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0]; |
822 | ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0]; | 838 | ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0]; |
823 | ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0]; | 839 | ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0]; |
840 | |||
824 | if (IS_CHAN_2GHZ(chan)) | 841 | if (IS_CHAN_2GHZ(chan)) |
825 | ratesArray[rateExtCck] = targetPowerCckExt.tPow2x[0]; | 842 | ratesArray[rateExtCck] = targetPowerCckExt.tPow2x[0]; |
826 | } | 843 | } |
827 | 844 | ||
845 | #undef CMP_CTL | ||
846 | #undef CMP_NO_CTL | ||
828 | #undef REDUCE_SCALED_POWER_BY_TWO_CHAIN | 847 | #undef REDUCE_SCALED_POWER_BY_TWO_CHAIN |
829 | #undef REDUCE_SCALED_POWER_BY_THREE_CHAIN | 848 | #undef REDUCE_SCALED_POWER_BY_THREE_CHAIN |
830 | } | 849 | } |
831 | 850 | ||
832 | static void ath9k_hw_AR9287_set_txpower(struct ath_hw *ah, | 851 | static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah, |
833 | struct ath9k_channel *chan, u16 cfgCtl, | 852 | struct ath9k_channel *chan, u16 cfgCtl, |
834 | u8 twiceAntennaReduction, | 853 | u8 twiceAntennaReduction, |
835 | u8 twiceMaxRegulatoryPower, | 854 | u8 twiceMaxRegulatoryPower, |
836 | u8 powerLimit) | 855 | u8 powerLimit) |
837 | { | 856 | { |
838 | #define INCREASE_MAXPOW_BY_TWO_CHAIN 6 | ||
839 | #define INCREASE_MAXPOW_BY_THREE_CHAIN 10 | ||
840 | struct ath_common *common = ath9k_hw_common(ah); | ||
841 | struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); | 857 | struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); |
842 | struct ar9287_eeprom *pEepData = &ah->eeprom.map9287; | 858 | struct ar9287_eeprom *pEepData = &ah->eeprom.map9287; |
843 | struct modal_eep_ar9287_header *pModal = &pEepData->modalHeader; | 859 | struct modal_eep_ar9287_header *pModal = &pEepData->modalHeader; |
844 | int16_t ratesArray[Ar5416RateSize]; | 860 | int16_t ratesArray[Ar5416RateSize]; |
845 | int16_t txPowerIndexOffset = 0; | 861 | int16_t txPowerIndexOffset = 0; |
846 | u8 ht40PowerIncForPdadc = 2; | 862 | u8 ht40PowerIncForPdadc = 2; |
847 | int i; | 863 | int i; |
848 | 864 | ||
@@ -852,13 +868,13 @@ static void ath9k_hw_AR9287_set_txpower(struct ath_hw *ah, | |||
852 | AR9287_EEP_MINOR_VER_2) | 868 | AR9287_EEP_MINOR_VER_2) |
853 | ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc; | 869 | ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc; |
854 | 870 | ||
855 | ath9k_hw_set_AR9287_power_per_rate_table(ah, chan, | 871 | ath9k_hw_set_ar9287_power_per_rate_table(ah, chan, |
856 | &ratesArray[0], cfgCtl, | 872 | &ratesArray[0], cfgCtl, |
857 | twiceAntennaReduction, | 873 | twiceAntennaReduction, |
858 | twiceMaxRegulatoryPower, | 874 | twiceMaxRegulatoryPower, |
859 | powerLimit); | 875 | powerLimit); |
860 | 876 | ||
861 | ath9k_hw_set_AR9287_power_cal_table(ah, chan, &txPowerIndexOffset); | 877 | ath9k_hw_set_ar9287_power_cal_table(ah, chan, &txPowerIndexOffset); |
862 | 878 | ||
863 | for (i = 0; i < ARRAY_SIZE(ratesArray); i++) { | 879 | for (i = 0; i < ARRAY_SIZE(ratesArray); i++) { |
864 | ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]); | 880 | ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]); |
@@ -871,6 +887,7 @@ static void ath9k_hw_AR9287_set_txpower(struct ath_hw *ah, | |||
871 | ratesArray[i] -= AR9287_PWR_TABLE_OFFSET_DB * 2; | 887 | ratesArray[i] -= AR9287_PWR_TABLE_OFFSET_DB * 2; |
872 | } | 888 | } |
873 | 889 | ||
890 | /* OFDM power per rate */ | ||
874 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE1, | 891 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE1, |
875 | ATH9K_POW_SM(ratesArray[rate18mb], 24) | 892 | ATH9K_POW_SM(ratesArray[rate18mb], 24) |
876 | | ATH9K_POW_SM(ratesArray[rate12mb], 16) | 893 | | ATH9K_POW_SM(ratesArray[rate12mb], 16) |
@@ -883,6 +900,7 @@ static void ath9k_hw_AR9287_set_txpower(struct ath_hw *ah, | |||
883 | | ATH9K_POW_SM(ratesArray[rate36mb], 8) | 900 | | ATH9K_POW_SM(ratesArray[rate36mb], 8) |
884 | | ATH9K_POW_SM(ratesArray[rate24mb], 0)); | 901 | | ATH9K_POW_SM(ratesArray[rate24mb], 0)); |
885 | 902 | ||
903 | /* CCK power per rate */ | ||
886 | if (IS_CHAN_2GHZ(chan)) { | 904 | if (IS_CHAN_2GHZ(chan)) { |
887 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE3, | 905 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE3, |
888 | ATH9K_POW_SM(ratesArray[rate2s], 24) | 906 | ATH9K_POW_SM(ratesArray[rate2s], 24) |
@@ -896,6 +914,7 @@ static void ath9k_hw_AR9287_set_txpower(struct ath_hw *ah, | |||
896 | | ATH9K_POW_SM(ratesArray[rate5_5l], 0)); | 914 | | ATH9K_POW_SM(ratesArray[rate5_5l], 0)); |
897 | } | 915 | } |
898 | 916 | ||
917 | /* HT20 power per rate */ | ||
899 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE5, | 918 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE5, |
900 | ATH9K_POW_SM(ratesArray[rateHt20_3], 24) | 919 | ATH9K_POW_SM(ratesArray[rateHt20_3], 24) |
901 | | ATH9K_POW_SM(ratesArray[rateHt20_2], 16) | 920 | | ATH9K_POW_SM(ratesArray[rateHt20_2], 16) |
@@ -908,8 +927,9 @@ static void ath9k_hw_AR9287_set_txpower(struct ath_hw *ah, | |||
908 | | ATH9K_POW_SM(ratesArray[rateHt20_5], 8) | 927 | | ATH9K_POW_SM(ratesArray[rateHt20_5], 8) |
909 | | ATH9K_POW_SM(ratesArray[rateHt20_4], 0)); | 928 | | ATH9K_POW_SM(ratesArray[rateHt20_4], 0)); |
910 | 929 | ||
930 | /* HT40 power per rate */ | ||
911 | if (IS_CHAN_HT40(chan)) { | 931 | if (IS_CHAN_HT40(chan)) { |
912 | if (ath9k_hw_AR9287_get_eeprom(ah, EEP_OL_PWRCTRL)) { | 932 | if (ath9k_hw_ar9287_get_eeprom(ah, EEP_OL_PWRCTRL)) { |
913 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE7, | 933 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE7, |
914 | ATH9K_POW_SM(ratesArray[rateHt40_3], 24) | 934 | ATH9K_POW_SM(ratesArray[rateHt40_3], 24) |
915 | | ATH9K_POW_SM(ratesArray[rateHt40_2], 16) | 935 | | ATH9K_POW_SM(ratesArray[rateHt40_2], 16) |
@@ -943,6 +963,7 @@ static void ath9k_hw_AR9287_set_txpower(struct ath_hw *ah, | |||
943 | ht40PowerIncForPdadc, 0)); | 963 | ht40PowerIncForPdadc, 0)); |
944 | } | 964 | } |
945 | 965 | ||
966 | /* Dup/Ext power per rate */ | ||
946 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE9, | 967 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE9, |
947 | ATH9K_POW_SM(ratesArray[rateExtOfdm], 24) | 968 | ATH9K_POW_SM(ratesArray[rateExtOfdm], 24) |
948 | | ATH9K_POW_SM(ratesArray[rateExtCck], 16) | 969 | | ATH9K_POW_SM(ratesArray[rateExtCck], 16) |
@@ -960,37 +981,20 @@ static void ath9k_hw_AR9287_set_txpower(struct ath_hw *ah, | |||
960 | ratesArray[i] + AR9287_PWR_TABLE_OFFSET_DB * 2; | 981 | ratesArray[i] + AR9287_PWR_TABLE_OFFSET_DB * 2; |
961 | else | 982 | else |
962 | regulatory->max_power_level = ratesArray[i]; | 983 | regulatory->max_power_level = ratesArray[i]; |
963 | |||
964 | switch (ar5416_get_ntxchains(ah->txchainmask)) { | ||
965 | case 1: | ||
966 | break; | ||
967 | case 2: | ||
968 | regulatory->max_power_level += | ||
969 | INCREASE_MAXPOW_BY_TWO_CHAIN; | ||
970 | break; | ||
971 | case 3: | ||
972 | regulatory->max_power_level += | ||
973 | INCREASE_MAXPOW_BY_THREE_CHAIN; | ||
974 | break; | ||
975 | default: | ||
976 | ath_print(common, ATH_DBG_EEPROM, | ||
977 | "Invalid chainmask configuration\n"); | ||
978 | break; | ||
979 | } | ||
980 | } | 984 | } |
981 | 985 | ||
982 | static void ath9k_hw_AR9287_set_addac(struct ath_hw *ah, | 986 | static void ath9k_hw_ar9287_set_addac(struct ath_hw *ah, |
983 | struct ath9k_channel *chan) | 987 | struct ath9k_channel *chan) |
984 | { | 988 | { |
985 | } | 989 | } |
986 | 990 | ||
987 | static void ath9k_hw_AR9287_set_board_values(struct ath_hw *ah, | 991 | static void ath9k_hw_ar9287_set_board_values(struct ath_hw *ah, |
988 | struct ath9k_channel *chan) | 992 | struct ath9k_channel *chan) |
989 | { | 993 | { |
990 | struct ar9287_eeprom *eep = &ah->eeprom.map9287; | 994 | struct ar9287_eeprom *eep = &ah->eeprom.map9287; |
991 | struct modal_eep_ar9287_header *pModal = &eep->modalHeader; | 995 | struct modal_eep_ar9287_header *pModal = &eep->modalHeader; |
992 | u16 antWrites[AR9287_ANT_16S]; | 996 | u16 antWrites[AR9287_ANT_16S]; |
993 | u32 regChainOffset; | 997 | u32 regChainOffset, regval; |
994 | u8 txRxAttenLocal; | 998 | u8 txRxAttenLocal; |
995 | int i, j, offset_num; | 999 | int i, j, offset_num; |
996 | 1000 | ||
@@ -1077,42 +1081,37 @@ static void ath9k_hw_AR9287_set_board_values(struct ath_hw *ah, | |||
1077 | REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, | 1081 | REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, |
1078 | AR_PHY_EXT_CCA0_THRESH62, pModal->thresh62); | 1082 | AR_PHY_EXT_CCA0_THRESH62, pModal->thresh62); |
1079 | 1083 | ||
1080 | ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0, AR9287_AN_RF2G3_DB1, | 1084 | regval = REG_READ(ah, AR9287_AN_RF2G3_CH0); |
1081 | AR9287_AN_RF2G3_DB1_S, pModal->db1); | 1085 | regval &= ~(AR9287_AN_RF2G3_DB1 | |
1082 | ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0, AR9287_AN_RF2G3_DB2, | 1086 | AR9287_AN_RF2G3_DB2 | |
1083 | AR9287_AN_RF2G3_DB2_S, pModal->db2); | 1087 | AR9287_AN_RF2G3_OB_CCK | |
1084 | ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0, | 1088 | AR9287_AN_RF2G3_OB_PSK | |
1085 | AR9287_AN_RF2G3_OB_CCK, | 1089 | AR9287_AN_RF2G3_OB_QAM | |
1086 | AR9287_AN_RF2G3_OB_CCK_S, pModal->ob_cck); | 1090 | AR9287_AN_RF2G3_OB_PAL_OFF); |
1087 | ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0, | 1091 | regval |= (SM(pModal->db1, AR9287_AN_RF2G3_DB1) | |
1088 | AR9287_AN_RF2G3_OB_PSK, | 1092 | SM(pModal->db2, AR9287_AN_RF2G3_DB2) | |
1089 | AR9287_AN_RF2G3_OB_PSK_S, pModal->ob_psk); | 1093 | SM(pModal->ob_cck, AR9287_AN_RF2G3_OB_CCK) | |
1090 | ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0, | 1094 | SM(pModal->ob_psk, AR9287_AN_RF2G3_OB_PSK) | |
1091 | AR9287_AN_RF2G3_OB_QAM, | 1095 | SM(pModal->ob_qam, AR9287_AN_RF2G3_OB_QAM) | |
1092 | AR9287_AN_RF2G3_OB_QAM_S, pModal->ob_qam); | 1096 | SM(pModal->ob_pal_off, AR9287_AN_RF2G3_OB_PAL_OFF)); |
1093 | ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0, | 1097 | |
1094 | AR9287_AN_RF2G3_OB_PAL_OFF, | 1098 | ath9k_hw_analog_shift_regwrite(ah, AR9287_AN_RF2G3_CH0, regval); |
1095 | AR9287_AN_RF2G3_OB_PAL_OFF_S, | 1099 | |
1096 | pModal->ob_pal_off); | 1100 | regval = REG_READ(ah, AR9287_AN_RF2G3_CH1); |
1097 | 1101 | regval &= ~(AR9287_AN_RF2G3_DB1 | | |
1098 | ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1, | 1102 | AR9287_AN_RF2G3_DB2 | |
1099 | AR9287_AN_RF2G3_DB1, AR9287_AN_RF2G3_DB1_S, | 1103 | AR9287_AN_RF2G3_OB_CCK | |
1100 | pModal->db1); | 1104 | AR9287_AN_RF2G3_OB_PSK | |
1101 | ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1, AR9287_AN_RF2G3_DB2, | 1105 | AR9287_AN_RF2G3_OB_QAM | |
1102 | AR9287_AN_RF2G3_DB2_S, pModal->db2); | 1106 | AR9287_AN_RF2G3_OB_PAL_OFF); |
1103 | ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1, | 1107 | regval |= (SM(pModal->db1, AR9287_AN_RF2G3_DB1) | |
1104 | AR9287_AN_RF2G3_OB_CCK, | 1108 | SM(pModal->db2, AR9287_AN_RF2G3_DB2) | |
1105 | AR9287_AN_RF2G3_OB_CCK_S, pModal->ob_cck); | 1109 | SM(pModal->ob_cck, AR9287_AN_RF2G3_OB_CCK) | |
1106 | ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1, | 1110 | SM(pModal->ob_psk, AR9287_AN_RF2G3_OB_PSK) | |
1107 | AR9287_AN_RF2G3_OB_PSK, | 1111 | SM(pModal->ob_qam, AR9287_AN_RF2G3_OB_QAM) | |
1108 | AR9287_AN_RF2G3_OB_PSK_S, pModal->ob_psk); | 1112 | SM(pModal->ob_pal_off, AR9287_AN_RF2G3_OB_PAL_OFF)); |
1109 | ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1, | 1113 | |
1110 | AR9287_AN_RF2G3_OB_QAM, | 1114 | ath9k_hw_analog_shift_regwrite(ah, AR9287_AN_RF2G3_CH1, regval); |
1111 | AR9287_AN_RF2G3_OB_QAM_S, pModal->ob_qam); | ||
1112 | ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1, | ||
1113 | AR9287_AN_RF2G3_OB_PAL_OFF, | ||
1114 | AR9287_AN_RF2G3_OB_PAL_OFF_S, | ||
1115 | pModal->ob_pal_off); | ||
1116 | 1115 | ||
1117 | REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, | 1116 | REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, |
1118 | AR_PHY_TX_END_DATA_START, pModal->txFrameToDataStart); | 1117 | AR_PHY_TX_END_DATA_START, pModal->txFrameToDataStart); |
@@ -1125,13 +1124,13 @@ static void ath9k_hw_AR9287_set_board_values(struct ath_hw *ah, | |||
1125 | pModal->xpaBiasLvl); | 1124 | pModal->xpaBiasLvl); |
1126 | } | 1125 | } |
1127 | 1126 | ||
1128 | static u8 ath9k_hw_AR9287_get_num_ant_config(struct ath_hw *ah, | 1127 | static u8 ath9k_hw_ar9287_get_num_ant_config(struct ath_hw *ah, |
1129 | enum ieee80211_band freq_band) | 1128 | enum ieee80211_band freq_band) |
1130 | { | 1129 | { |
1131 | return 1; | 1130 | return 1; |
1132 | } | 1131 | } |
1133 | 1132 | ||
1134 | static u16 ath9k_hw_AR9287_get_eeprom_antenna_cfg(struct ath_hw *ah, | 1133 | static u16 ath9k_hw_ar9287_get_eeprom_antenna_cfg(struct ath_hw *ah, |
1135 | struct ath9k_channel *chan) | 1134 | struct ath9k_channel *chan) |
1136 | { | 1135 | { |
1137 | struct ar9287_eeprom *eep = &ah->eeprom.map9287; | 1136 | struct ar9287_eeprom *eep = &ah->eeprom.map9287; |
@@ -1140,11 +1139,12 @@ static u16 ath9k_hw_AR9287_get_eeprom_antenna_cfg(struct ath_hw *ah, | |||
1140 | return pModal->antCtrlCommon & 0xFFFF; | 1139 | return pModal->antCtrlCommon & 0xFFFF; |
1141 | } | 1140 | } |
1142 | 1141 | ||
1143 | static u16 ath9k_hw_AR9287_get_spur_channel(struct ath_hw *ah, | 1142 | static u16 ath9k_hw_ar9287_get_spur_channel(struct ath_hw *ah, |
1144 | u16 i, bool is2GHz) | 1143 | u16 i, bool is2GHz) |
1145 | { | 1144 | { |
1146 | #define EEP_MAP9287_SPURCHAN \ | 1145 | #define EEP_MAP9287_SPURCHAN \ |
1147 | (ah->eeprom.map9287.modalHeader.spurChans[i].spurChan) | 1146 | (ah->eeprom.map9287.modalHeader.spurChans[i].spurChan) |
1147 | |||
1148 | struct ath_common *common = ath9k_hw_common(ah); | 1148 | struct ath_common *common = ath9k_hw_common(ah); |
1149 | u16 spur_val = AR_NO_SPUR; | 1149 | u16 spur_val = AR_NO_SPUR; |
1150 | 1150 | ||
@@ -1171,15 +1171,15 @@ static u16 ath9k_hw_AR9287_get_spur_channel(struct ath_hw *ah, | |||
1171 | } | 1171 | } |
1172 | 1172 | ||
1173 | const struct eeprom_ops eep_ar9287_ops = { | 1173 | const struct eeprom_ops eep_ar9287_ops = { |
1174 | .check_eeprom = ath9k_hw_AR9287_check_eeprom, | 1174 | .check_eeprom = ath9k_hw_ar9287_check_eeprom, |
1175 | .get_eeprom = ath9k_hw_AR9287_get_eeprom, | 1175 | .get_eeprom = ath9k_hw_ar9287_get_eeprom, |
1176 | .fill_eeprom = ath9k_hw_AR9287_fill_eeprom, | 1176 | .fill_eeprom = ath9k_hw_ar9287_fill_eeprom, |
1177 | .get_eeprom_ver = ath9k_hw_AR9287_get_eeprom_ver, | 1177 | .get_eeprom_ver = ath9k_hw_ar9287_get_eeprom_ver, |
1178 | .get_eeprom_rev = ath9k_hw_AR9287_get_eeprom_rev, | 1178 | .get_eeprom_rev = ath9k_hw_ar9287_get_eeprom_rev, |
1179 | .get_num_ant_config = ath9k_hw_AR9287_get_num_ant_config, | 1179 | .get_num_ant_config = ath9k_hw_ar9287_get_num_ant_config, |
1180 | .get_eeprom_antenna_cfg = ath9k_hw_AR9287_get_eeprom_antenna_cfg, | 1180 | .get_eeprom_antenna_cfg = ath9k_hw_ar9287_get_eeprom_antenna_cfg, |
1181 | .set_board_values = ath9k_hw_AR9287_set_board_values, | 1181 | .set_board_values = ath9k_hw_ar9287_set_board_values, |
1182 | .set_addac = ath9k_hw_AR9287_set_addac, | 1182 | .set_addac = ath9k_hw_ar9287_set_addac, |
1183 | .set_txpower = ath9k_hw_AR9287_set_txpower, | 1183 | .set_txpower = ath9k_hw_ar9287_set_txpower, |
1184 | .get_spur_channel = ath9k_hw_AR9287_get_spur_channel | 1184 | .get_spur_channel = ath9k_hw_ar9287_get_spur_channel |
1185 | }; | 1185 | }; |