aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath9k/eeprom.c
diff options
context:
space:
mode:
authorSujith <Sujith.Manoharan@atheros.com>2009-02-09 02:57:24 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-02-13 13:45:08 -0500
commitf74df6fbe31561091bf42be0ed30232be2b9d3ac (patch)
tree5cd6ed9f809e60d8ff6acd9363efa0475a95e20c /drivers/net/wireless/ath9k/eeprom.c
parente153789dc3846b35494435b4a8ae82a034c99dae (diff)
ath9k: Cleanup EEPROM operations
This patch removes the various function pointer assignments and unifies them in a single ops structure. Signed-off-by: Sujith <Sujith.Manoharan@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath9k/eeprom.c')
-rw-r--r--drivers/net/wireless/ath9k/eeprom.c2828
1 files changed, 1408 insertions, 1420 deletions
diff --git a/drivers/net/wireless/ath9k/eeprom.c b/drivers/net/wireless/ath9k/eeprom.c
index 94e79938b93a..2e604e1fb3e1 100644
--- a/drivers/net/wireless/ath9k/eeprom.c
+++ b/drivers/net/wireless/ath9k/eeprom.c
@@ -95,195 +95,216 @@ static inline bool ath9k_hw_nvram_read(struct ath_hw *ah, u32 off, u16 *data)
95 return sc->bus_ops->eeprom_read(ah, off, data); 95 return sc->bus_ops->eeprom_read(ah, off, data);
96} 96}
97 97
98static bool ath9k_hw_fill_4k_eeprom(struct ath_hw *ah) 98static inline bool ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList,
99 u8 *pVpdList, u16 numIntercepts,
100 u8 *pRetVpdList)
99{ 101{
100#define SIZE_EEPROM_4K (sizeof(struct ar5416_eeprom_4k) / sizeof(u16)) 102 u16 i, k;
101 struct ar5416_eeprom_4k *eep = &ah->ah_eeprom.map4k; 103 u8 currPwr = pwrMin;
102 u16 *eep_data; 104 u16 idxL = 0, idxR = 0;
103 int addr, eep_start_loc = 0;
104
105 eep_start_loc = 64;
106 105
107 if (!ath9k_hw_use_flash(ah)) { 106 for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) {
108 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 107 ath9k_hw_get_lower_upper_index(currPwr, pPwrList,
109 "Reading from EEPROM, not flash\n"); 108 numIntercepts, &(idxL),
109 &(idxR));
110 if (idxR < 1)
111 idxR = 1;
112 if (idxL == numIntercepts - 1)
113 idxL = (u16) (numIntercepts - 2);
114 if (pPwrList[idxL] == pPwrList[idxR])
115 k = pVpdList[idxL];
116 else
117 k = (u16)(((currPwr - pPwrList[idxL]) * pVpdList[idxR] +
118 (pPwrList[idxR] - currPwr) * pVpdList[idxL]) /
119 (pPwrList[idxR] - pPwrList[idxL]));
120 pRetVpdList[i] = (u8) k;
121 currPwr += 2;
110 } 122 }
111 123
112 eep_data = (u16 *)eep;
113
114 for (addr = 0; addr < SIZE_EEPROM_4K; addr++) {
115 if (!ath9k_hw_nvram_read(ah, addr + eep_start_loc, eep_data)) {
116 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
117 "Unable to read eeprom region \n");
118 return false;
119 }
120 eep_data++;
121 }
122 return true; 124 return true;
123#undef SIZE_EEPROM_4K
124} 125}
125 126
126static bool ath9k_hw_fill_def_eeprom(struct ath_hw *ah) 127static void ath9k_hw_get_legacy_target_powers(struct ath_hw *ah,
128 struct ath9k_channel *chan,
129 struct cal_target_power_leg *powInfo,
130 u16 numChannels,
131 struct cal_target_power_leg *pNewPower,
132 u16 numRates, bool isExtTarget)
127{ 133{
128#define SIZE_EEPROM_DEF (sizeof(struct ar5416_eeprom_def) / sizeof(u16)) 134 struct chan_centers centers;
129 struct ar5416_eeprom_def *eep = &ah->ah_eeprom.def; 135 u16 clo, chi;
130 u16 *eep_data; 136 int i;
131 int addr, ar5416_eep_start_loc = 0x100; 137 int matchIndex = -1, lowIndex = -1;
138 u16 freq;
132 139
133 eep_data = (u16 *)eep; 140 ath9k_hw_get_channel_centers(ah, chan, &centers);
141 freq = (isExtTarget) ? centers.ext_center : centers.ctl_center;
134 142
135 for (addr = 0; addr < SIZE_EEPROM_DEF; addr++) { 143 if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel,
136 if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc, 144 IS_CHAN_2GHZ(chan))) {
137 eep_data)) { 145 matchIndex = 0;
138 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 146 } else {
139 "Unable to read eeprom region\n"); 147 for (i = 0; (i < numChannels) &&
140 return false; 148 (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
149 if (freq == ath9k_hw_fbin2freq(powInfo[i].bChannel,
150 IS_CHAN_2GHZ(chan))) {
151 matchIndex = i;
152 break;
153 } else if ((freq < ath9k_hw_fbin2freq(powInfo[i].bChannel,
154 IS_CHAN_2GHZ(chan))) &&
155 (freq > ath9k_hw_fbin2freq(powInfo[i - 1].bChannel,
156 IS_CHAN_2GHZ(chan)))) {
157 lowIndex = i - 1;
158 break;
159 }
141 } 160 }
142 eep_data++; 161 if ((matchIndex == -1) && (lowIndex == -1))
162 matchIndex = i - 1;
143 } 163 }
144 return true;
145#undef SIZE_EEPROM_DEF
146}
147 164
148static bool (*ath9k_fill_eeprom[]) (struct ath_hw *) = { 165 if (matchIndex != -1) {
149 ath9k_hw_fill_def_eeprom, 166 *pNewPower = powInfo[matchIndex];
150 ath9k_hw_fill_4k_eeprom 167 } else {
151}; 168 clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
169 IS_CHAN_2GHZ(chan));
170 chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
171 IS_CHAN_2GHZ(chan));
152 172
153static inline bool ath9k_hw_fill_eeprom(struct ath_hw *ah) 173 for (i = 0; i < numRates; i++) {
154{ 174 pNewPower->tPow2x[i] =
155 return ath9k_fill_eeprom[ah->ah_eep_map](ah); 175 (u8)ath9k_hw_interpolate(freq, clo, chi,
176 powInfo[lowIndex].tPow2x[i],
177 powInfo[lowIndex + 1].tPow2x[i]);
178 }
179 }
156} 180}
157 181
158static int ath9k_hw_check_def_eeprom(struct ath_hw *ah) 182static void ath9k_hw_get_target_powers(struct ath_hw *ah,
183 struct ath9k_channel *chan,
184 struct cal_target_power_ht *powInfo,
185 u16 numChannels,
186 struct cal_target_power_ht *pNewPower,
187 u16 numRates, bool isHt40Target)
159{ 188{
160 struct ar5416_eeprom_def *eep = 189 struct chan_centers centers;
161 (struct ar5416_eeprom_def *) &ah->ah_eeprom.def; 190 u16 clo, chi;
162 u16 *eepdata, temp, magic, magic2; 191 int i;
163 u32 sum = 0, el; 192 int matchIndex = -1, lowIndex = -1;
164 bool need_swap = false; 193 u16 freq;
165 int i, addr, size;
166
167 if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET,
168 &magic)) {
169 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
170 "Reading Magic # failed\n");
171 return false;
172 }
173
174 if (!ath9k_hw_use_flash(ah)) {
175 194
176 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 195 ath9k_hw_get_channel_centers(ah, chan, &centers);
177 "Read Magic = 0x%04X\n", magic); 196 freq = isHt40Target ? centers.synth_center : centers.ctl_center;
178 197
179 if (magic != AR5416_EEPROM_MAGIC) { 198 if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel, IS_CHAN_2GHZ(chan))) {
180 magic2 = swab16(magic); 199 matchIndex = 0;
200 } else {
201 for (i = 0; (i < numChannels) &&
202 (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
203 if (freq == ath9k_hw_fbin2freq(powInfo[i].bChannel,
204 IS_CHAN_2GHZ(chan))) {
205 matchIndex = i;
206 break;
207 } else
208 if ((freq < ath9k_hw_fbin2freq(powInfo[i].bChannel,
209 IS_CHAN_2GHZ(chan))) &&
210 (freq > ath9k_hw_fbin2freq(powInfo[i - 1].bChannel,
211 IS_CHAN_2GHZ(chan)))) {
212 lowIndex = i - 1;
213 break;
214 }
215 }
216 if ((matchIndex == -1) && (lowIndex == -1))
217 matchIndex = i - 1;
218 }
181 219
182 if (magic2 == AR5416_EEPROM_MAGIC) { 220 if (matchIndex != -1) {
183 size = sizeof(struct ar5416_eeprom_def); 221 *pNewPower = powInfo[matchIndex];
184 need_swap = true; 222 } else {
185 eepdata = (u16 *) (&ah->ah_eeprom); 223 clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
224 IS_CHAN_2GHZ(chan));
225 chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
226 IS_CHAN_2GHZ(chan));
186 227
187 for (addr = 0; addr < size / sizeof(u16); addr++) { 228 for (i = 0; i < numRates; i++) {
188 temp = swab16(*eepdata); 229 pNewPower->tPow2x[i] = (u8)ath9k_hw_interpolate(freq,
189 *eepdata = temp; 230 clo, chi,
190 eepdata++; 231 powInfo[lowIndex].tPow2x[i],
232 powInfo[lowIndex + 1].tPow2x[i]);
233 }
234 }
235}
191 236
192 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 237static u16 ath9k_hw_get_max_edge_power(u16 freq,
193 "0x%04X ", *eepdata); 238 struct cal_ctl_edges *pRdEdgesPower,
239 bool is2GHz, int num_band_edges)
240{
241 u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
242 int i;
194 243
195 if (((addr + 1) % 6) == 0) 244 for (i = 0; (i < num_band_edges) &&
196 DPRINTF(ah->ah_sc, 245 (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
197 ATH_DBG_EEPROM, "\n"); 246 if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel, is2GHz)) {
198 } 247 twiceMaxEdgePower = pRdEdgesPower[i].tPower;
199 } else { 248 break;
200 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 249 } else if ((i > 0) &&
201 "Invalid EEPROM Magic. " 250 (freq < ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel,
202 "endianness mismatch.\n"); 251 is2GHz))) {
203 return -EINVAL; 252 if (ath9k_hw_fbin2freq(pRdEdgesPower[i - 1].bChannel,
253 is2GHz) < freq &&
254 pRdEdgesPower[i - 1].flag) {
255 twiceMaxEdgePower =
256 pRdEdgesPower[i - 1].tPower;
204 } 257 }
258 break;
205 } 259 }
206 } 260 }
207 261
208 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n", 262 return twiceMaxEdgePower;
209 need_swap ? "True" : "False"); 263}
210 264
211 if (need_swap) 265/****************************************/
212 el = swab16(ah->ah_eeprom.def.baseEepHeader.length); 266/* EEPROM Operations for 4K sized cards */
213 else 267/****************************************/
214 el = ah->ah_eeprom.def.baseEepHeader.length;
215 268
216 if (el > sizeof(struct ar5416_eeprom_def)) 269static int ath9k_hw_4k_get_eeprom_ver(struct ath_hw *ah)
217 el = sizeof(struct ar5416_eeprom_def) / sizeof(u16); 270{
218 else 271 return ((ah->ah_eeprom.map4k.baseEepHeader.version >> 12) & 0xF);
219 el = el / sizeof(u16); 272}
220 273
221 eepdata = (u16 *)(&ah->ah_eeprom); 274static int ath9k_hw_4k_get_eeprom_rev(struct ath_hw *ah)
275{
276 return ((ah->ah_eeprom.map4k.baseEepHeader.version) & 0xFFF);
277}
222 278
223 for (i = 0; i < el; i++) 279static bool ath9k_hw_4k_fill_eeprom(struct ath_hw *ah)
224 sum ^= *eepdata++; 280{
281#define SIZE_EEPROM_4K (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
282 struct ar5416_eeprom_4k *eep = &ah->ah_eeprom.map4k;
283 u16 *eep_data;
284 int addr, eep_start_loc = 0;
225 285
226 if (need_swap) { 286 eep_start_loc = 64;
227 u32 integer, j;
228 u16 word;
229 287
288 if (!ath9k_hw_use_flash(ah)) {
230 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 289 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
231 "EEPROM Endianness is not native.. Changing \n"); 290 "Reading from EEPROM, not flash\n");
232 291 }
233 word = swab16(eep->baseEepHeader.length);
234 eep->baseEepHeader.length = word;
235
236 word = swab16(eep->baseEepHeader.checksum);
237 eep->baseEepHeader.checksum = word;
238
239 word = swab16(eep->baseEepHeader.version);
240 eep->baseEepHeader.version = word;
241
242 word = swab16(eep->baseEepHeader.regDmn[0]);
243 eep->baseEepHeader.regDmn[0] = word;
244
245 word = swab16(eep->baseEepHeader.regDmn[1]);
246 eep->baseEepHeader.regDmn[1] = word;
247
248 word = swab16(eep->baseEepHeader.rfSilent);
249 eep->baseEepHeader.rfSilent = word;
250
251 word = swab16(eep->baseEepHeader.blueToothOptions);
252 eep->baseEepHeader.blueToothOptions = word;
253
254 word = swab16(eep->baseEepHeader.deviceCap);
255 eep->baseEepHeader.deviceCap = word;
256
257 for (j = 0; j < ARRAY_SIZE(eep->modalHeader); j++) {
258 struct modal_eep_header *pModal =
259 &eep->modalHeader[j];
260 integer = swab32(pModal->antCtrlCommon);
261 pModal->antCtrlCommon = integer;
262 292
263 for (i = 0; i < AR5416_MAX_CHAINS; i++) { 293 eep_data = (u16 *)eep;
264 integer = swab32(pModal->antCtrlChain[i]);
265 pModal->antCtrlChain[i] = integer;
266 }
267 294
268 for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) { 295 for (addr = 0; addr < SIZE_EEPROM_4K; addr++) {
269 word = swab16(pModal->spurChans[i].spurChan); 296 if (!ath9k_hw_nvram_read(ah, addr + eep_start_loc, eep_data)) {
270 pModal->spurChans[i].spurChan = word; 297 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
271 } 298 "Unable to read eeprom region \n");
299 return false;
272 } 300 }
301 eep_data++;
273 } 302 }
274 303 return true;
275 if (sum != 0xffff || ar5416_get_eep_ver(ah) != AR5416_EEP_VER || 304#undef SIZE_EEPROM_4K
276 ar5416_get_eep_rev(ah) < AR5416_EEP_NO_BACK_VER) {
277 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
278 "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
279 sum, ar5416_get_eep_ver(ah));
280 return -EINVAL;
281 }
282
283 return 0;
284} 305}
285 306
286static int ath9k_hw_check_4k_eeprom(struct ath_hw *ah) 307static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah)
287{ 308{
288#define EEPROM_4K_SIZE (sizeof(struct ar5416_eeprom_4k) / sizeof(u16)) 309#define EEPROM_4K_SIZE (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
289 struct ar5416_eeprom_4k *eep = 310 struct ar5416_eeprom_4k *eep =
@@ -397,11 +418,11 @@ static int ath9k_hw_check_4k_eeprom(struct ath_hw *ah)
397 } 418 }
398 } 419 }
399 420
400 if (sum != 0xffff || ar5416_get_eep4k_ver(ah) != AR5416_EEP_VER || 421 if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER ||
401 ar5416_get_eep4k_rev(ah) < AR5416_EEP_NO_BACK_VER) { 422 ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
402 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 423 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
403 "Bad EEPROM checksum 0x%x or revision 0x%04x\n", 424 "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
404 sum, ar5416_get_eep4k_ver(ah)); 425 sum, ah->eep_ops->get_eeprom_ver(ah));
405 return -EINVAL; 426 return -EINVAL;
406 } 427 }
407 428
@@ -409,43 +430,45 @@ static int ath9k_hw_check_4k_eeprom(struct ath_hw *ah)
409#undef EEPROM_4K_SIZE 430#undef EEPROM_4K_SIZE
410} 431}
411 432
412static int (*ath9k_check_eeprom[]) (struct ath_hw *) = { 433static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
413 ath9k_hw_check_def_eeprom, 434 enum eeprom_param param)
414 ath9k_hw_check_4k_eeprom
415};
416
417static inline int ath9k_hw_check_eeprom(struct ath_hw *ah)
418{
419 return ath9k_check_eeprom[ah->ah_eep_map](ah);
420}
421
422static inline bool ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList,
423 u8 *pVpdList, u16 numIntercepts,
424 u8 *pRetVpdList)
425{ 435{
426 u16 i, k; 436 struct ar5416_eeprom_4k *eep = &ah->ah_eeprom.map4k;
427 u8 currPwr = pwrMin; 437 struct modal_eep_4k_header *pModal = &eep->modalHeader;
428 u16 idxL = 0, idxR = 0; 438 struct base_eep_header_4k *pBase = &eep->baseEepHeader;
429 439
430 for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) { 440 switch (param) {
431 ath9k_hw_get_lower_upper_index(currPwr, pPwrList, 441 case EEP_NFTHRESH_2:
432 numIntercepts, &(idxL), 442 return pModal[1].noiseFloorThreshCh[0];
433 &(idxR)); 443 case AR_EEPROM_MAC(0):
434 if (idxR < 1) 444 return pBase->macAddr[0] << 8 | pBase->macAddr[1];
435 idxR = 1; 445 case AR_EEPROM_MAC(1):
436 if (idxL == numIntercepts - 1) 446 return pBase->macAddr[2] << 8 | pBase->macAddr[3];
437 idxL = (u16) (numIntercepts - 2); 447 case AR_EEPROM_MAC(2):
438 if (pPwrList[idxL] == pPwrList[idxR]) 448 return pBase->macAddr[4] << 8 | pBase->macAddr[5];
439 k = pVpdList[idxL]; 449 case EEP_REG_0:
440 else 450 return pBase->regDmn[0];
441 k = (u16)(((currPwr - pPwrList[idxL]) * pVpdList[idxR] + 451 case EEP_REG_1:
442 (pPwrList[idxR] - currPwr) * pVpdList[idxL]) / 452 return pBase->regDmn[1];
443 (pPwrList[idxR] - pPwrList[idxL])); 453 case EEP_OP_CAP:
444 pRetVpdList[i] = (u8) k; 454 return pBase->deviceCap;
445 currPwr += 2; 455 case EEP_OP_MODE:
456 return pBase->opCapFlags;
457 case EEP_RF_SILENT:
458 return pBase->rfSilent;
459 case EEP_OB_2:
460 return pModal->ob_01;
461 case EEP_DB_2:
462 return pModal->db1_01;
463 case EEP_MINOR_REV:
464 return pBase->version & AR5416_EEP_VER_MINOR_MASK;
465 case EEP_TX_MASK:
466 return pBase->txMask;
467 case EEP_RX_MASK:
468 return pBase->rxMask;
469 default:
470 return 0;
446 } 471 }
447
448 return true;
449} 472}
450 473
451static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw *ah, 474static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw *ah,
@@ -616,435 +639,6 @@ static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw *ah,
616#undef TMP_VAL_VPD_TABLE 639#undef TMP_VAL_VPD_TABLE
617} 640}
618 641
619static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw *ah,
620 struct ath9k_channel *chan,
621 struct cal_data_per_freq *pRawDataSet,
622 u8 *bChans, u16 availPiers,
623 u16 tPdGainOverlap, int16_t *pMinCalPower,
624 u16 *pPdGainBoundaries, u8 *pPDADCValues,
625 u16 numXpdGains)
626{
627 int i, j, k;
628 int16_t ss;
629 u16 idxL = 0, idxR = 0, numPiers;
630 static u8 vpdTableL[AR5416_NUM_PD_GAINS]
631 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
632 static u8 vpdTableR[AR5416_NUM_PD_GAINS]
633 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
634 static u8 vpdTableI[AR5416_NUM_PD_GAINS]
635 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
636
637 u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
638 u8 minPwrT4[AR5416_NUM_PD_GAINS];
639 u8 maxPwrT4[AR5416_NUM_PD_GAINS];
640 int16_t vpdStep;
641 int16_t tmpVal;
642 u16 sizeCurrVpdTable, maxIndex, tgtIndex;
643 bool match;
644 int16_t minDelta = 0;
645 struct chan_centers centers;
646
647 ath9k_hw_get_channel_centers(ah, chan, &centers);
648
649 for (numPiers = 0; numPiers < availPiers; numPiers++) {
650 if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
651 break;
652 }
653
654 match = ath9k_hw_get_lower_upper_index((u8)FREQ2FBIN(centers.synth_center,
655 IS_CHAN_2GHZ(chan)),
656 bChans, numPiers, &idxL, &idxR);
657
658 if (match) {
659 for (i = 0; i < numXpdGains; i++) {
660 minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
661 maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
662 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
663 pRawDataSet[idxL].pwrPdg[i],
664 pRawDataSet[idxL].vpdPdg[i],
665 AR5416_PD_GAIN_ICEPTS,
666 vpdTableI[i]);
667 }
668 } else {
669 for (i = 0; i < numXpdGains; i++) {
670 pVpdL = pRawDataSet[idxL].vpdPdg[i];
671 pPwrL = pRawDataSet[idxL].pwrPdg[i];
672 pVpdR = pRawDataSet[idxR].vpdPdg[i];
673 pPwrR = pRawDataSet[idxR].pwrPdg[i];
674
675 minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
676
677 maxPwrT4[i] =
678 min(pPwrL[AR5416_PD_GAIN_ICEPTS - 1],
679 pPwrR[AR5416_PD_GAIN_ICEPTS - 1]);
680
681
682 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
683 pPwrL, pVpdL,
684 AR5416_PD_GAIN_ICEPTS,
685 vpdTableL[i]);
686 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
687 pPwrR, pVpdR,
688 AR5416_PD_GAIN_ICEPTS,
689 vpdTableR[i]);
690
691 for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
692 vpdTableI[i][j] =
693 (u8)(ath9k_hw_interpolate((u16)
694 FREQ2FBIN(centers.
695 synth_center,
696 IS_CHAN_2GHZ
697 (chan)),
698 bChans[idxL], bChans[idxR],
699 vpdTableL[i][j], vpdTableR[i][j]));
700 }
701 }
702 }
703
704 *pMinCalPower = (int16_t)(minPwrT4[0] / 2);
705
706 k = 0;
707
708 for (i = 0; i < numXpdGains; i++) {
709 if (i == (numXpdGains - 1))
710 pPdGainBoundaries[i] =
711 (u16)(maxPwrT4[i] / 2);
712 else
713 pPdGainBoundaries[i] =
714 (u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
715
716 pPdGainBoundaries[i] =
717 min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
718
719 if ((i == 0) && !AR_SREV_5416_V20_OR_LATER(ah)) {
720 minDelta = pPdGainBoundaries[0] - 23;
721 pPdGainBoundaries[0] = 23;
722 } else {
723 minDelta = 0;
724 }
725
726 if (i == 0) {
727 if (AR_SREV_9280_10_OR_LATER(ah))
728 ss = (int16_t)(0 - (minPwrT4[i] / 2));
729 else
730 ss = 0;
731 } else {
732 ss = (int16_t)((pPdGainBoundaries[i - 1] -
733 (minPwrT4[i] / 2)) -
734 tPdGainOverlap + 1 + minDelta);
735 }
736 vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
737 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
738
739 while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
740 tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
741 pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
742 ss++;
743 }
744
745 sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
746 tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap -
747 (minPwrT4[i] / 2));
748 maxIndex = (tgtIndex < sizeCurrVpdTable) ?
749 tgtIndex : sizeCurrVpdTable;
750
751 while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
752 pPDADCValues[k++] = vpdTableI[i][ss++];
753 }
754
755 vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
756 vpdTableI[i][sizeCurrVpdTable - 2]);
757 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
758
759 if (tgtIndex > maxIndex) {
760 while ((ss <= tgtIndex) &&
761 (k < (AR5416_NUM_PDADC_VALUES - 1))) {
762 tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] +
763 (ss - maxIndex + 1) * vpdStep));
764 pPDADCValues[k++] = (u8)((tmpVal > 255) ?
765 255 : tmpVal);
766 ss++;
767 }
768 }
769 }
770
771 while (i < AR5416_PD_GAINS_IN_MASK) {
772 pPdGainBoundaries[i] = pPdGainBoundaries[i - 1];
773 i++;
774 }
775
776 while (k < AR5416_NUM_PDADC_VALUES) {
777 pPDADCValues[k] = pPDADCValues[k - 1];
778 k++;
779 }
780
781 return;
782}
783
784static void ath9k_hw_get_legacy_target_powers(struct ath_hw *ah,
785 struct ath9k_channel *chan,
786 struct cal_target_power_leg *powInfo,
787 u16 numChannels,
788 struct cal_target_power_leg *pNewPower,
789 u16 numRates, bool isExtTarget)
790{
791 struct chan_centers centers;
792 u16 clo, chi;
793 int i;
794 int matchIndex = -1, lowIndex = -1;
795 u16 freq;
796
797 ath9k_hw_get_channel_centers(ah, chan, &centers);
798 freq = (isExtTarget) ? centers.ext_center : centers.ctl_center;
799
800 if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel,
801 IS_CHAN_2GHZ(chan))) {
802 matchIndex = 0;
803 } else {
804 for (i = 0; (i < numChannels) &&
805 (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
806 if (freq == ath9k_hw_fbin2freq(powInfo[i].bChannel,
807 IS_CHAN_2GHZ(chan))) {
808 matchIndex = i;
809 break;
810 } else if ((freq < ath9k_hw_fbin2freq(powInfo[i].bChannel,
811 IS_CHAN_2GHZ(chan))) &&
812 (freq > ath9k_hw_fbin2freq(powInfo[i - 1].bChannel,
813 IS_CHAN_2GHZ(chan)))) {
814 lowIndex = i - 1;
815 break;
816 }
817 }
818 if ((matchIndex == -1) && (lowIndex == -1))
819 matchIndex = i - 1;
820 }
821
822 if (matchIndex != -1) {
823 *pNewPower = powInfo[matchIndex];
824 } else {
825 clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
826 IS_CHAN_2GHZ(chan));
827 chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
828 IS_CHAN_2GHZ(chan));
829
830 for (i = 0; i < numRates; i++) {
831 pNewPower->tPow2x[i] =
832 (u8)ath9k_hw_interpolate(freq, clo, chi,
833 powInfo[lowIndex].tPow2x[i],
834 powInfo[lowIndex + 1].tPow2x[i]);
835 }
836 }
837}
838
839static void ath9k_hw_get_target_powers(struct ath_hw *ah,
840 struct ath9k_channel *chan,
841 struct cal_target_power_ht *powInfo,
842 u16 numChannels,
843 struct cal_target_power_ht *pNewPower,
844 u16 numRates, bool isHt40Target)
845{
846 struct chan_centers centers;
847 u16 clo, chi;
848 int i;
849 int matchIndex = -1, lowIndex = -1;
850 u16 freq;
851
852 ath9k_hw_get_channel_centers(ah, chan, &centers);
853 freq = isHt40Target ? centers.synth_center : centers.ctl_center;
854
855 if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel, IS_CHAN_2GHZ(chan))) {
856 matchIndex = 0;
857 } else {
858 for (i = 0; (i < numChannels) &&
859 (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
860 if (freq == ath9k_hw_fbin2freq(powInfo[i].bChannel,
861 IS_CHAN_2GHZ(chan))) {
862 matchIndex = i;
863 break;
864 } else
865 if ((freq < ath9k_hw_fbin2freq(powInfo[i].bChannel,
866 IS_CHAN_2GHZ(chan))) &&
867 (freq > ath9k_hw_fbin2freq(powInfo[i - 1].bChannel,
868 IS_CHAN_2GHZ(chan)))) {
869 lowIndex = i - 1;
870 break;
871 }
872 }
873 if ((matchIndex == -1) && (lowIndex == -1))
874 matchIndex = i - 1;
875 }
876
877 if (matchIndex != -1) {
878 *pNewPower = powInfo[matchIndex];
879 } else {
880 clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
881 IS_CHAN_2GHZ(chan));
882 chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
883 IS_CHAN_2GHZ(chan));
884
885 for (i = 0; i < numRates; i++) {
886 pNewPower->tPow2x[i] = (u8)ath9k_hw_interpolate(freq,
887 clo, chi,
888 powInfo[lowIndex].tPow2x[i],
889 powInfo[lowIndex + 1].tPow2x[i]);
890 }
891 }
892}
893
894static u16 ath9k_hw_get_max_edge_power(u16 freq,
895 struct cal_ctl_edges *pRdEdgesPower,
896 bool is2GHz, int num_band_edges)
897{
898 u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
899 int i;
900
901 for (i = 0; (i < num_band_edges) &&
902 (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
903 if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel, is2GHz)) {
904 twiceMaxEdgePower = pRdEdgesPower[i].tPower;
905 break;
906 } else if ((i > 0) &&
907 (freq < ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel,
908 is2GHz))) {
909 if (ath9k_hw_fbin2freq(pRdEdgesPower[i - 1].bChannel,
910 is2GHz) < freq &&
911 pRdEdgesPower[i - 1].flag) {
912 twiceMaxEdgePower =
913 pRdEdgesPower[i - 1].tPower;
914 }
915 break;
916 }
917 }
918
919 return twiceMaxEdgePower;
920}
921
922static bool ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
923 struct ath9k_channel *chan,
924 int16_t *pTxPowerIndexOffset)
925{
926 struct ar5416_eeprom_def *pEepData = &ah->ah_eeprom.def;
927 struct cal_data_per_freq *pRawDataset;
928 u8 *pCalBChans = NULL;
929 u16 pdGainOverlap_t2;
930 static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
931 u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
932 u16 numPiers, i, j;
933 int16_t tMinCalPower;
934 u16 numXpdGain, xpdMask;
935 u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
936 u32 reg32, regOffset, regChainOffset;
937 int16_t modalIdx;
938
939 modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
940 xpdMask = pEepData->modalHeader[modalIdx].xpdGain;
941
942 if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
943 AR5416_EEP_MINOR_VER_2) {
944 pdGainOverlap_t2 =
945 pEepData->modalHeader[modalIdx].pdGainOverlap;
946 } else {
947 pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),
948 AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
949 }
950
951 if (IS_CHAN_2GHZ(chan)) {
952 pCalBChans = pEepData->calFreqPier2G;
953 numPiers = AR5416_NUM_2G_CAL_PIERS;
954 } else {
955 pCalBChans = pEepData->calFreqPier5G;
956 numPiers = AR5416_NUM_5G_CAL_PIERS;
957 }
958
959 numXpdGain = 0;
960
961 for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
962 if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
963 if (numXpdGain >= AR5416_NUM_PD_GAINS)
964 break;
965 xpdGainValues[numXpdGain] =
966 (u16)(AR5416_PD_GAINS_IN_MASK - i);
967 numXpdGain++;
968 }
969 }
970
971 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
972 (numXpdGain - 1) & 0x3);
973 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
974 xpdGainValues[0]);
975 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
976 xpdGainValues[1]);
977 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
978 xpdGainValues[2]);
979
980 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
981 if (AR_SREV_5416_V20_OR_LATER(ah) &&
982 (ah->ah_rxchainmask == 5 || ah->ah_txchainmask == 5) &&
983 (i != 0)) {
984 regChainOffset = (i == 1) ? 0x2000 : 0x1000;
985 } else
986 regChainOffset = i * 0x1000;
987
988 if (pEepData->baseEepHeader.txMask & (1 << i)) {
989 if (IS_CHAN_2GHZ(chan))
990 pRawDataset = pEepData->calPierData2G[i];
991 else
992 pRawDataset = pEepData->calPierData5G[i];
993
994 ath9k_hw_get_def_gain_boundaries_pdadcs(ah, chan,
995 pRawDataset, pCalBChans,
996 numPiers, pdGainOverlap_t2,
997 &tMinCalPower, gainBoundaries,
998 pdadcValues, numXpdGain);
999
1000 if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
1001 REG_WRITE(ah,
1002 AR_PHY_TPCRG5 + regChainOffset,
1003 SM(pdGainOverlap_t2,
1004 AR_PHY_TPCRG5_PD_GAIN_OVERLAP)
1005 | SM(gainBoundaries[0],
1006 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1)
1007 | SM(gainBoundaries[1],
1008 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2)
1009 | SM(gainBoundaries[2],
1010 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3)
1011 | SM(gainBoundaries[3],
1012 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
1013 }
1014
1015 regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
1016 for (j = 0; j < 32; j++) {
1017 reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) |
1018 ((pdadcValues[4 * j + 1] & 0xFF) << 8) |
1019 ((pdadcValues[4 * j + 2] & 0xFF) << 16)|
1020 ((pdadcValues[4 * j + 3] & 0xFF) << 24);
1021 REG_WRITE(ah, regOffset, reg32);
1022
1023 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1024 "PDADC (%d,%4x): %4.4x %8.8x\n",
1025 i, regChainOffset, regOffset,
1026 reg32);
1027 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1028 "PDADC: Chain %d | PDADC %3d "
1029 "Value %3d | PDADC %3d Value %3d | "
1030 "PDADC %3d Value %3d | PDADC %3d "
1031 "Value %3d |\n",
1032 i, 4 * j, pdadcValues[4 * j],
1033 4 * j + 1, pdadcValues[4 * j + 1],
1034 4 * j + 2, pdadcValues[4 * j + 2],
1035 4 * j + 3,
1036 pdadcValues[4 * j + 3]);
1037
1038 regOffset += 4;
1039 }
1040 }
1041 }
1042
1043 *pTxPowerIndexOffset = 0;
1044
1045 return true;
1046}
1047
1048static bool ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah, 642static bool ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
1049 struct ath9k_channel *chan, 643 struct ath9k_channel *chan,
1050 int16_t *pTxPowerIndexOffset) 644 int16_t *pTxPowerIndexOffset)
@@ -1161,296 +755,6 @@ static bool ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
1161 return true; 755 return true;
1162} 756}
1163 757
1164static bool ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
1165 struct ath9k_channel *chan,
1166 int16_t *ratesArray,
1167 u16 cfgCtl,
1168 u16 AntennaReduction,
1169 u16 twiceMaxRegulatoryPower,
1170 u16 powerLimit)
1171{
1172#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */
1173#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10 /* 10*log10(3)*2 */
1174
1175 struct ar5416_eeprom_def *pEepData = &ah->ah_eeprom.def;
1176 u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
1177 static const u16 tpScaleReductionTable[5] =
1178 { 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
1179
1180 int i;
1181 int16_t twiceLargestAntenna;
1182 struct cal_ctl_data *rep;
1183 struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
1184 0, { 0, 0, 0, 0}
1185 };
1186 struct cal_target_power_leg targetPowerOfdmExt = {
1187 0, { 0, 0, 0, 0} }, targetPowerCckExt = {
1188 0, { 0, 0, 0, 0 }
1189 };
1190 struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
1191 0, {0, 0, 0, 0}
1192 };
1193 u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
1194 u16 ctlModesFor11a[] =
1195 { CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 };
1196 u16 ctlModesFor11g[] =
1197 { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
1198 CTL_2GHT40
1199 };
1200 u16 numCtlModes, *pCtlMode, ctlMode, freq;
1201 struct chan_centers centers;
1202 int tx_chainmask;
1203 u16 twiceMinEdgePower;
1204
1205 tx_chainmask = ah->ah_txchainmask;
1206
1207 ath9k_hw_get_channel_centers(ah, chan, &centers);
1208
1209 twiceLargestAntenna = max(
1210 pEepData->modalHeader
1211 [IS_CHAN_2GHZ(chan)].antennaGainCh[0],
1212 pEepData->modalHeader
1213 [IS_CHAN_2GHZ(chan)].antennaGainCh[1]);
1214
1215 twiceLargestAntenna = max((u8)twiceLargestAntenna,
1216 pEepData->modalHeader
1217 [IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
1218
1219 twiceLargestAntenna = (int16_t)min(AntennaReduction -
1220 twiceLargestAntenna, 0);
1221
1222 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
1223
1224 if (ah->regulatory.tp_scale != ATH9K_TP_SCALE_MAX) {
1225 maxRegAllowedPower -=
1226 (tpScaleReductionTable[(ah->regulatory.tp_scale)] * 2);
1227 }
1228
1229 scaledPower = min(powerLimit, maxRegAllowedPower);
1230
1231 switch (ar5416_get_ntxchains(tx_chainmask)) {
1232 case 1:
1233 break;
1234 case 2:
1235 scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
1236 break;
1237 case 3:
1238 scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
1239 break;
1240 }
1241
1242 scaledPower = max((u16)0, scaledPower);
1243
1244 if (IS_CHAN_2GHZ(chan)) {
1245 numCtlModes = ARRAY_SIZE(ctlModesFor11g) -
1246 SUB_NUM_CTL_MODES_AT_2G_40;
1247 pCtlMode = ctlModesFor11g;
1248
1249 ath9k_hw_get_legacy_target_powers(ah, chan,
1250 pEepData->calTargetPowerCck,
1251 AR5416_NUM_2G_CCK_TARGET_POWERS,
1252 &targetPowerCck, 4, false);
1253 ath9k_hw_get_legacy_target_powers(ah, chan,
1254 pEepData->calTargetPower2G,
1255 AR5416_NUM_2G_20_TARGET_POWERS,
1256 &targetPowerOfdm, 4, false);
1257 ath9k_hw_get_target_powers(ah, chan,
1258 pEepData->calTargetPower2GHT20,
1259 AR5416_NUM_2G_20_TARGET_POWERS,
1260 &targetPowerHt20, 8, false);
1261
1262 if (IS_CHAN_HT40(chan)) {
1263 numCtlModes = ARRAY_SIZE(ctlModesFor11g);
1264 ath9k_hw_get_target_powers(ah, chan,
1265 pEepData->calTargetPower2GHT40,
1266 AR5416_NUM_2G_40_TARGET_POWERS,
1267 &targetPowerHt40, 8, true);
1268 ath9k_hw_get_legacy_target_powers(ah, chan,
1269 pEepData->calTargetPowerCck,
1270 AR5416_NUM_2G_CCK_TARGET_POWERS,
1271 &targetPowerCckExt, 4, true);
1272 ath9k_hw_get_legacy_target_powers(ah, chan,
1273 pEepData->calTargetPower2G,
1274 AR5416_NUM_2G_20_TARGET_POWERS,
1275 &targetPowerOfdmExt, 4, true);
1276 }
1277 } else {
1278 numCtlModes = ARRAY_SIZE(ctlModesFor11a) -
1279 SUB_NUM_CTL_MODES_AT_5G_40;
1280 pCtlMode = ctlModesFor11a;
1281
1282 ath9k_hw_get_legacy_target_powers(ah, chan,
1283 pEepData->calTargetPower5G,
1284 AR5416_NUM_5G_20_TARGET_POWERS,
1285 &targetPowerOfdm, 4, false);
1286 ath9k_hw_get_target_powers(ah, chan,
1287 pEepData->calTargetPower5GHT20,
1288 AR5416_NUM_5G_20_TARGET_POWERS,
1289 &targetPowerHt20, 8, false);
1290
1291 if (IS_CHAN_HT40(chan)) {
1292 numCtlModes = ARRAY_SIZE(ctlModesFor11a);
1293 ath9k_hw_get_target_powers(ah, chan,
1294 pEepData->calTargetPower5GHT40,
1295 AR5416_NUM_5G_40_TARGET_POWERS,
1296 &targetPowerHt40, 8, true);
1297 ath9k_hw_get_legacy_target_powers(ah, chan,
1298 pEepData->calTargetPower5G,
1299 AR5416_NUM_5G_20_TARGET_POWERS,
1300 &targetPowerOfdmExt, 4, true);
1301 }
1302 }
1303
1304 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
1305 bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
1306 (pCtlMode[ctlMode] == CTL_2GHT40);
1307 if (isHt40CtlMode)
1308 freq = centers.synth_center;
1309 else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
1310 freq = centers.ext_center;
1311 else
1312 freq = centers.ctl_center;
1313
1314 if (ar5416_get_eep_ver(ah) == 14 && ar5416_get_eep_rev(ah) <= 2)
1315 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
1316
1317 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
1318 "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
1319 "EXT_ADDITIVE %d\n",
1320 ctlMode, numCtlModes, isHt40CtlMode,
1321 (pCtlMode[ctlMode] & EXT_ADDITIVE));
1322
1323 for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i]; i++) {
1324 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
1325 " LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
1326 "pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
1327 "chan %d\n",
1328 i, cfgCtl, pCtlMode[ctlMode],
1329 pEepData->ctlIndex[i], chan->channel);
1330
1331 if ((((cfgCtl & ~CTL_MODE_M) |
1332 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
1333 pEepData->ctlIndex[i]) ||
1334 (((cfgCtl & ~CTL_MODE_M) |
1335 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
1336 ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) {
1337 rep = &(pEepData->ctlData[i]);
1338
1339 twiceMinEdgePower = ath9k_hw_get_max_edge_power(freq,
1340 rep->ctlEdges[ar5416_get_ntxchains(tx_chainmask) - 1],
1341 IS_CHAN_2GHZ(chan), AR5416_NUM_BAND_EDGES);
1342
1343 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
1344 " MATCH-EE_IDX %d: ch %d is2 %d "
1345 "2xMinEdge %d chainmask %d chains %d\n",
1346 i, freq, IS_CHAN_2GHZ(chan),
1347 twiceMinEdgePower, tx_chainmask,
1348 ar5416_get_ntxchains
1349 (tx_chainmask));
1350 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
1351 twiceMaxEdgePower = min(twiceMaxEdgePower,
1352 twiceMinEdgePower);
1353 } else {
1354 twiceMaxEdgePower = twiceMinEdgePower;
1355 break;
1356 }
1357 }
1358 }
1359
1360 minCtlPower = min(twiceMaxEdgePower, scaledPower);
1361
1362 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
1363 " SEL-Min ctlMode %d pCtlMode %d "
1364 "2xMaxEdge %d sP %d minCtlPwr %d\n",
1365 ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
1366 scaledPower, minCtlPower);
1367
1368 switch (pCtlMode[ctlMode]) {
1369 case CTL_11B:
1370 for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); i++) {
1371 targetPowerCck.tPow2x[i] =
1372 min((u16)targetPowerCck.tPow2x[i],
1373 minCtlPower);
1374 }
1375 break;
1376 case CTL_11A:
1377 case CTL_11G:
1378 for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) {
1379 targetPowerOfdm.tPow2x[i] =
1380 min((u16)targetPowerOfdm.tPow2x[i],
1381 minCtlPower);
1382 }
1383 break;
1384 case CTL_5GHT20:
1385 case CTL_2GHT20:
1386 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) {
1387 targetPowerHt20.tPow2x[i] =
1388 min((u16)targetPowerHt20.tPow2x[i],
1389 minCtlPower);
1390 }
1391 break;
1392 case CTL_11B_EXT:
1393 targetPowerCckExt.tPow2x[0] = min((u16)
1394 targetPowerCckExt.tPow2x[0],
1395 minCtlPower);
1396 break;
1397 case CTL_11A_EXT:
1398 case CTL_11G_EXT:
1399 targetPowerOfdmExt.tPow2x[0] = min((u16)
1400 targetPowerOfdmExt.tPow2x[0],
1401 minCtlPower);
1402 break;
1403 case CTL_5GHT40:
1404 case CTL_2GHT40:
1405 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
1406 targetPowerHt40.tPow2x[i] =
1407 min((u16)targetPowerHt40.tPow2x[i],
1408 minCtlPower);
1409 }
1410 break;
1411 default:
1412 break;
1413 }
1414 }
1415
1416 ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
1417 ratesArray[rate18mb] = ratesArray[rate24mb] =
1418 targetPowerOfdm.tPow2x[0];
1419 ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
1420 ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
1421 ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
1422 ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
1423
1424 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
1425 ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
1426
1427 if (IS_CHAN_2GHZ(chan)) {
1428 ratesArray[rate1l] = targetPowerCck.tPow2x[0];
1429 ratesArray[rate2s] = ratesArray[rate2l] =
1430 targetPowerCck.tPow2x[1];
1431 ratesArray[rate5_5s] = ratesArray[rate5_5l] =
1432 targetPowerCck.tPow2x[2];
1433 ;
1434 ratesArray[rate11s] = ratesArray[rate11l] =
1435 targetPowerCck.tPow2x[3];
1436 ;
1437 }
1438 if (IS_CHAN_HT40(chan)) {
1439 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
1440 ratesArray[rateHt40_0 + i] =
1441 targetPowerHt40.tPow2x[i];
1442 }
1443 ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
1444 ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
1445 ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
1446 if (IS_CHAN_2GHZ(chan)) {
1447 ratesArray[rateExtCck] =
1448 targetPowerCckExt.tPow2x[0];
1449 }
1450 }
1451 return true;
1452}
1453
1454static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah, 758static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
1455 struct ath9k_channel *chan, 759 struct ath9k_channel *chan,
1456 int16_t *ratesArray, 760 int16_t *ratesArray,
@@ -1548,8 +852,8 @@ static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
1548 else 852 else
1549 freq = centers.ctl_center; 853 freq = centers.ctl_center;
1550 854
1551 if (ar5416_get_eep_ver(ah) == 14 && 855 if (ah->eep_ops->get_eeprom_ver(ah) == 14 &&
1552 ar5416_get_eep_rev(ah) <= 2) 856 ah->eep_ops->get_eeprom_rev(ah) <= 2)
1553 twiceMaxEdgePower = AR5416_MAX_RATE_POWER; 857 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
1554 858
1555 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, 859 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
@@ -1686,16 +990,15 @@ static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
1686 return true; 990 return true;
1687} 991}
1688 992
1689static int ath9k_hw_def_set_txpower(struct ath_hw *ah, 993static int ath9k_hw_4k_set_txpower(struct ath_hw *ah,
1690 struct ath9k_channel *chan, 994 struct ath9k_channel *chan,
1691 u16 cfgCtl, 995 u16 cfgCtl,
1692 u8 twiceAntennaReduction, 996 u8 twiceAntennaReduction,
1693 u8 twiceMaxRegulatoryPower, 997 u8 twiceMaxRegulatoryPower,
1694 u8 powerLimit) 998 u8 powerLimit)
1695{ 999{
1696 struct ar5416_eeprom_def *pEepData = &ah->ah_eeprom.def; 1000 struct ar5416_eeprom_4k *pEepData = &ah->ah_eeprom.map4k;
1697 struct modal_eep_header *pModal = 1001 struct modal_eep_4k_header *pModal = &pEepData->modalHeader;
1698 &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]);
1699 int16_t ratesArray[Ar5416RateSize]; 1002 int16_t ratesArray[Ar5416RateSize];
1700 int16_t txPowerIndexOffset = 0; 1003 int16_t txPowerIndexOffset = 0;
1701 u8 ht40PowerIncForPdadc = 2; 1004 u8 ht40PowerIncForPdadc = 2;
@@ -1708,7 +1011,7 @@ static int ath9k_hw_def_set_txpower(struct ath_hw *ah,
1708 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc; 1011 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
1709 } 1012 }
1710 1013
1711 if (!ath9k_hw_set_def_power_per_rate_table(ah, chan, 1014 if (!ath9k_hw_set_4k_power_per_rate_table(ah, chan,
1712 &ratesArray[0], cfgCtl, 1015 &ratesArray[0], cfgCtl,
1713 twiceAntennaReduction, 1016 twiceAntennaReduction,
1714 twiceMaxRegulatoryPower, 1017 twiceMaxRegulatoryPower,
@@ -1719,7 +1022,7 @@ static int ath9k_hw_def_set_txpower(struct ath_hw *ah,
1719 return -EIO; 1022 return -EIO;
1720 } 1023 }
1721 1024
1722 if (!ath9k_hw_set_def_power_cal_table(ah, chan, &txPowerIndexOffset)) { 1025 if (!ath9k_hw_set_4k_power_cal_table(ah, chan, &txPowerIndexOffset)) {
1723 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 1026 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
1724 "ath9k_hw_set_txpower: unable to set power table\n"); 1027 "ath9k_hw_set_txpower: unable to set power table\n");
1725 return -EIO; 1028 return -EIO;
@@ -1798,10 +1101,6 @@ static int ath9k_hw_def_set_txpower(struct ath_hw *ah,
1798 | ATH9K_POW_SM(ratesArray[rateDupCck], 0)); 1101 | ATH9K_POW_SM(ratesArray[rateDupCck], 0));
1799 } 1102 }
1800 1103
1801 REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
1802 ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
1803 | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0));
1804
1805 i = rate6mb; 1104 i = rate6mb;
1806 1105
1807 if (IS_CHAN_HT40(chan)) 1106 if (IS_CHAN_HT40(chan))
@@ -1818,241 +1117,497 @@ static int ath9k_hw_def_set_txpower(struct ath_hw *ah,
1818 return 0; 1117 return 0;
1819} 1118}
1820 1119
1821static int ath9k_hw_4k_set_txpower(struct ath_hw *ah, 1120static void ath9k_hw_4k_set_addac(struct ath_hw *ah,
1822 struct ath9k_channel *chan, 1121 struct ath9k_channel *chan)
1823 u16 cfgCtl,
1824 u8 twiceAntennaReduction,
1825 u8 twiceMaxRegulatoryPower,
1826 u8 powerLimit)
1827{ 1122{
1828 struct ar5416_eeprom_4k *pEepData = &ah->ah_eeprom.map4k; 1123 struct modal_eep_4k_header *pModal;
1829 struct modal_eep_4k_header *pModal = &pEepData->modalHeader; 1124 struct ar5416_eeprom_4k *eep = &ah->ah_eeprom.map4k;
1830 int16_t ratesArray[Ar5416RateSize]; 1125 u8 biaslevel;
1831 int16_t txPowerIndexOffset = 0;
1832 u8 ht40PowerIncForPdadc = 2;
1833 int i;
1834 1126
1835 memset(ratesArray, 0, sizeof(ratesArray)); 1127 if (ah->hw_version.macVersion != AR_SREV_VERSION_9160)
1128 return;
1836 1129
1837 if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= 1130 if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7)
1838 AR5416_EEP_MINOR_VER_2) { 1131 return;
1839 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc; 1132
1133 pModal = &eep->modalHeader;
1134
1135 if (pModal->xpaBiasLvl != 0xff) {
1136 biaslevel = pModal->xpaBiasLvl;
1137 INI_RA(&ah->ah_iniAddac, 7, 1) =
1138 (INI_RA(&ah->ah_iniAddac, 7, 1) & (~0x18)) | biaslevel << 3;
1840 } 1139 }
1140}
1841 1141
1842 if (!ath9k_hw_set_4k_power_per_rate_table(ah, chan, 1142static bool ath9k_hw_4k_set_board_values(struct ath_hw *ah,
1843 &ratesArray[0], cfgCtl, 1143 struct ath9k_channel *chan)
1844 twiceAntennaReduction, 1144{
1845 twiceMaxRegulatoryPower, 1145 struct modal_eep_4k_header *pModal;
1846 powerLimit)) { 1146 struct ar5416_eeprom_4k *eep = &ah->ah_eeprom.map4k;
1847 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 1147 int regChainOffset;
1848 "ath9k_hw_set_txpower: unable to set " 1148 u8 txRxAttenLocal;
1849 "tx power per rate table\n"); 1149 u8 ob[5], db1[5], db2[5];
1850 return -EIO; 1150 u8 ant_div_control1, ant_div_control2;
1151 u32 regVal;
1152
1153
1154 pModal = &eep->modalHeader;
1155
1156 txRxAttenLocal = 23;
1157
1158 REG_WRITE(ah, AR_PHY_SWITCH_COM,
1159 ah->eep_ops->get_eeprom_antenna_cfg(ah, chan));
1160
1161 regChainOffset = 0;
1162 REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
1163 pModal->antCtrlChain[0]);
1164
1165 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
1166 (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) &
1167 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
1168 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
1169 SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
1170 SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
1171
1172 if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
1173 AR5416_EEP_MINOR_VER_3) {
1174 txRxAttenLocal = pModal->txRxAttenCh[0];
1175 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
1176 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, pModal->bswMargin[0]);
1177 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
1178 AR_PHY_GAIN_2GHZ_XATTEN1_DB, pModal->bswAtten[0]);
1179 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
1180 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
1181 pModal->xatten2Margin[0]);
1182 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
1183 AR_PHY_GAIN_2GHZ_XATTEN2_DB, pModal->xatten2Db[0]);
1851 } 1184 }
1852 1185
1853 if (!ath9k_hw_set_4k_power_cal_table(ah, chan, &txPowerIndexOffset)) { 1186 REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
1187 AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
1188 REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
1189 AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]);
1190
1191 if (AR_SREV_9285_11(ah))
1192 REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14));
1193
1194 /* Initialize Ant Diversity settings from EEPROM */
1195 if (pModal->version == 3) {
1196 ant_div_control1 = ((pModal->ob_234 >> 12) & 0xf);
1197 ant_div_control2 = ((pModal->db1_234 >> 12) & 0xf);
1198 regVal = REG_READ(ah, 0x99ac);
1199 regVal &= (~(0x7f000000));
1200 regVal |= ((ant_div_control1 & 0x1) << 24);
1201 regVal |= (((ant_div_control1 >> 1) & 0x1) << 29);
1202 regVal |= (((ant_div_control1 >> 2) & 0x1) << 30);
1203 regVal |= ((ant_div_control2 & 0x3) << 25);
1204 regVal |= (((ant_div_control2 >> 2) & 0x3) << 27);
1205 REG_WRITE(ah, 0x99ac, regVal);
1206 regVal = REG_READ(ah, 0x99ac);
1207 regVal = REG_READ(ah, 0xa208);
1208 regVal &= (~(0x1 << 13));
1209 regVal |= (((ant_div_control1 >> 3) & 0x1) << 13);
1210 REG_WRITE(ah, 0xa208, regVal);
1211 regVal = REG_READ(ah, 0xa208);
1212 }
1213
1214 if (pModal->version >= 2) {
1215 ob[0] = (pModal->ob_01 & 0xf);
1216 ob[1] = (pModal->ob_01 >> 4) & 0xf;
1217 ob[2] = (pModal->ob_234 & 0xf);
1218 ob[3] = ((pModal->ob_234 >> 4) & 0xf);
1219 ob[4] = ((pModal->ob_234 >> 8) & 0xf);
1220
1221 db1[0] = (pModal->db1_01 & 0xf);
1222 db1[1] = ((pModal->db1_01 >> 4) & 0xf);
1223 db1[2] = (pModal->db1_234 & 0xf);
1224 db1[3] = ((pModal->db1_234 >> 4) & 0xf);
1225 db1[4] = ((pModal->db1_234 >> 8) & 0xf);
1226
1227 db2[0] = (pModal->db2_01 & 0xf);
1228 db2[1] = ((pModal->db2_01 >> 4) & 0xf);
1229 db2[2] = (pModal->db2_234 & 0xf);
1230 db2[3] = ((pModal->db2_234 >> 4) & 0xf);
1231 db2[4] = ((pModal->db2_234 >> 8) & 0xf);
1232
1233 } else if (pModal->version == 1) {
1234
1854 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 1235 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
1855 "ath9k_hw_set_txpower: unable to set power table\n"); 1236 "EEPROM Model version is set to 1 \n");
1856 return -EIO; 1237 ob[0] = (pModal->ob_01 & 0xf);
1238 ob[1] = ob[2] = ob[3] = ob[4] = (pModal->ob_01 >> 4) & 0xf;
1239 db1[0] = (pModal->db1_01 & 0xf);
1240 db1[1] = db1[2] = db1[3] =
1241 db1[4] = ((pModal->db1_01 >> 4) & 0xf);
1242 db2[0] = (pModal->db2_01 & 0xf);
1243 db2[1] = db2[2] = db2[3] =
1244 db2[4] = ((pModal->db2_01 >> 4) & 0xf);
1245 } else {
1246 int i;
1247 for (i = 0; i < 5; i++) {
1248 ob[i] = pModal->ob_01;
1249 db1[i] = pModal->db1_01;
1250 db2[i] = pModal->db1_01;
1251 }
1857 } 1252 }
1858 1253
1859 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) { 1254 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
1860 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]); 1255 AR9285_AN_RF2G3_OB_0, AR9285_AN_RF2G3_OB_0_S, ob[0]);
1861 if (ratesArray[i] > AR5416_MAX_RATE_POWER) 1256 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
1862 ratesArray[i] = AR5416_MAX_RATE_POWER; 1257 AR9285_AN_RF2G3_OB_1, AR9285_AN_RF2G3_OB_1_S, ob[1]);
1258 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
1259 AR9285_AN_RF2G3_OB_2, AR9285_AN_RF2G3_OB_2_S, ob[2]);
1260 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
1261 AR9285_AN_RF2G3_OB_3, AR9285_AN_RF2G3_OB_3_S, ob[3]);
1262 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
1263 AR9285_AN_RF2G3_OB_4, AR9285_AN_RF2G3_OB_4_S, ob[4]);
1264
1265 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
1266 AR9285_AN_RF2G3_DB1_0, AR9285_AN_RF2G3_DB1_0_S, db1[0]);
1267 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
1268 AR9285_AN_RF2G3_DB1_1, AR9285_AN_RF2G3_DB1_1_S, db1[1]);
1269 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
1270 AR9285_AN_RF2G3_DB1_2, AR9285_AN_RF2G3_DB1_2_S, db1[2]);
1271 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
1272 AR9285_AN_RF2G4_DB1_3, AR9285_AN_RF2G4_DB1_3_S, db1[3]);
1273 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
1274 AR9285_AN_RF2G4_DB1_4, AR9285_AN_RF2G4_DB1_4_S, db1[4]);
1275
1276 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
1277 AR9285_AN_RF2G4_DB2_0, AR9285_AN_RF2G4_DB2_0_S, db2[0]);
1278 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
1279 AR9285_AN_RF2G4_DB2_1, AR9285_AN_RF2G4_DB2_1_S, db2[1]);
1280 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
1281 AR9285_AN_RF2G4_DB2_2, AR9285_AN_RF2G4_DB2_2_S, db2[2]);
1282 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
1283 AR9285_AN_RF2G4_DB2_3, AR9285_AN_RF2G4_DB2_3_S, db2[3]);
1284 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
1285 AR9285_AN_RF2G4_DB2_4, AR9285_AN_RF2G4_DB2_4_S, db2[4]);
1286
1287
1288 if (AR_SREV_9285_11(ah))
1289 REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT);
1290
1291 REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
1292 pModal->switchSettling);
1293 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
1294 pModal->adcDesiredSize);
1295
1296 REG_WRITE(ah, AR_PHY_RF_CTL4,
1297 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) |
1298 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) |
1299 SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON) |
1300 SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON));
1301
1302 REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
1303 pModal->txEndToRxOn);
1304 REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
1305 pModal->thresh62);
1306 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62,
1307 pModal->thresh62);
1308
1309 if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
1310 AR5416_EEP_MINOR_VER_2) {
1311 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_DATA_START,
1312 pModal->txFrameToDataStart);
1313 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON,
1314 pModal->txFrameToPaOn);
1863 } 1315 }
1864 1316
1865 if (AR_SREV_9280_10_OR_LATER(ah)) { 1317 if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
1866 for (i = 0; i < Ar5416RateSize; i++) 1318 AR5416_EEP_MINOR_VER_3) {
1867 ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2; 1319 if (IS_CHAN_HT40(chan))
1320 REG_RMW_FIELD(ah, AR_PHY_SETTLING,
1321 AR_PHY_SETTLING_SWITCH,
1322 pModal->swSettleHt40);
1868 } 1323 }
1869 1324
1870 REG_WRITE(ah, AR_PHY_POWER_TX_RATE1, 1325 return true;
1871 ATH9K_POW_SM(ratesArray[rate18mb], 24) 1326}
1872 | ATH9K_POW_SM(ratesArray[rate12mb], 16)
1873 | ATH9K_POW_SM(ratesArray[rate9mb], 8)
1874 | ATH9K_POW_SM(ratesArray[rate6mb], 0));
1875 REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
1876 ATH9K_POW_SM(ratesArray[rate54mb], 24)
1877 | ATH9K_POW_SM(ratesArray[rate48mb], 16)
1878 | ATH9K_POW_SM(ratesArray[rate36mb], 8)
1879 | ATH9K_POW_SM(ratesArray[rate24mb], 0));
1880 1327
1881 if (IS_CHAN_2GHZ(chan)) { 1328static u16 ath9k_hw_4k_get_eeprom_antenna_cfg(struct ath_hw *ah,
1882 REG_WRITE(ah, AR_PHY_POWER_TX_RATE3, 1329 struct ath9k_channel *chan)
1883 ATH9K_POW_SM(ratesArray[rate2s], 24) 1330{
1884 | ATH9K_POW_SM(ratesArray[rate2l], 16) 1331 struct ar5416_eeprom_4k *eep = &ah->ah_eeprom.map4k;
1885 | ATH9K_POW_SM(ratesArray[rateXr], 8) 1332 struct modal_eep_4k_header *pModal = &eep->modalHeader;
1886 | ATH9K_POW_SM(ratesArray[rate1l], 0));
1887 REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
1888 ATH9K_POW_SM(ratesArray[rate11s], 24)
1889 | ATH9K_POW_SM(ratesArray[rate11l], 16)
1890 | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
1891 | ATH9K_POW_SM(ratesArray[rate5_5l], 0));
1892 }
1893 1333
1894 REG_WRITE(ah, AR_PHY_POWER_TX_RATE5, 1334 return pModal->antCtrlCommon & 0xFFFF;
1895 ATH9K_POW_SM(ratesArray[rateHt20_3], 24) 1335}
1896 | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
1897 | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
1898 | ATH9K_POW_SM(ratesArray[rateHt20_0], 0));
1899 REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
1900 ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
1901 | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
1902 | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
1903 | ATH9K_POW_SM(ratesArray[rateHt20_4], 0));
1904 1336
1905 if (IS_CHAN_HT40(chan)) { 1337static u8 ath9k_hw_4k_get_num_ant_config(struct ath_hw *ah,
1906 REG_WRITE(ah, AR_PHY_POWER_TX_RATE7, 1338 enum ieee80211_band freq_band)
1907 ATH9K_POW_SM(ratesArray[rateHt40_3] + 1339{
1908 ht40PowerIncForPdadc, 24) 1340 return 1;
1909 | ATH9K_POW_SM(ratesArray[rateHt40_2] + 1341}
1910 ht40PowerIncForPdadc, 16)
1911 | ATH9K_POW_SM(ratesArray[rateHt40_1] +
1912 ht40PowerIncForPdadc, 8)
1913 | ATH9K_POW_SM(ratesArray[rateHt40_0] +
1914 ht40PowerIncForPdadc, 0));
1915 REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
1916 ATH9K_POW_SM(ratesArray[rateHt40_7] +
1917 ht40PowerIncForPdadc, 24)
1918 | ATH9K_POW_SM(ratesArray[rateHt40_6] +
1919 ht40PowerIncForPdadc, 16)
1920 | ATH9K_POW_SM(ratesArray[rateHt40_5] +
1921 ht40PowerIncForPdadc, 8)
1922 | ATH9K_POW_SM(ratesArray[rateHt40_4] +
1923 ht40PowerIncForPdadc, 0));
1924 1342
1925 REG_WRITE(ah, AR_PHY_POWER_TX_RATE9, 1343u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
1926 ATH9K_POW_SM(ratesArray[rateExtOfdm], 24) 1344{
1927 | ATH9K_POW_SM(ratesArray[rateExtCck], 16) 1345#define EEP_MAP4K_SPURCHAN \
1928 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8) 1346 (ah->ah_eeprom.map4k.modalHeader.spurChans[i].spurChan)
1929 | ATH9K_POW_SM(ratesArray[rateDupCck], 0));
1930 }
1931 1347
1932 i = rate6mb; 1348 u16 spur_val = AR_NO_SPUR;
1933 1349
1934 if (IS_CHAN_HT40(chan)) 1350 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
1935 i = rateHt40_0; 1351 "Getting spur idx %d is2Ghz. %d val %x\n",
1936 else if (IS_CHAN_HT20(chan)) 1352 i, is2GHz, ah->ah_config.spurchans[i][is2GHz]);
1937 i = rateHt20_0;
1938 1353
1939 if (AR_SREV_9280_10_OR_LATER(ah)) 1354 switch (ah->ah_config.spurmode) {
1940 ah->regulatory.max_power_level = 1355 case SPUR_DISABLE:
1941 ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2; 1356 break;
1942 else 1357 case SPUR_ENABLE_IOCTL:
1943 ah->regulatory.max_power_level = ratesArray[i]; 1358 spur_val = ah->ah_config.spurchans[i][is2GHz];
1359 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
1360 "Getting spur val from new loc. %d\n", spur_val);
1361 break;
1362 case SPUR_ENABLE_EEPROM:
1363 spur_val = EEP_MAP4K_SPURCHAN;
1364 break;
1365 }
1944 1366
1945 return 0; 1367 return spur_val;
1368
1369#undef EEP_MAP4K_SPURCHAN
1946} 1370}
1947 1371
1948static int (*ath9k_set_txpower[]) (struct ath_hw *, 1372struct eeprom_ops eep_4k_ops = {
1949 struct ath9k_channel *, 1373 .check_eeprom = ath9k_hw_4k_check_eeprom,
1950 u16, u8, u8, u8) = { 1374 .get_eeprom = ath9k_hw_4k_get_eeprom,
1951 ath9k_hw_def_set_txpower, 1375 .fill_eeprom = ath9k_hw_4k_fill_eeprom,
1952 ath9k_hw_4k_set_txpower 1376 .get_eeprom_ver = ath9k_hw_4k_get_eeprom_ver,
1377 .get_eeprom_rev = ath9k_hw_4k_get_eeprom_rev,
1378 .get_num_ant_config = ath9k_hw_4k_get_num_ant_config,
1379 .get_eeprom_antenna_cfg = ath9k_hw_4k_get_eeprom_antenna_cfg,
1380 .set_board_values = ath9k_hw_4k_set_board_values,
1381 .set_addac = ath9k_hw_4k_set_addac,
1382 .set_txpower = ath9k_hw_4k_set_txpower,
1383 .get_spur_channel = ath9k_hw_4k_get_spur_channel
1953}; 1384};
1954 1385
1955int ath9k_hw_set_txpower(struct ath_hw *ah, 1386/************************************************/
1956 struct ath9k_channel *chan, 1387/* EEPROM Operations for non-4K (Default) cards */
1957 u16 cfgCtl, 1388/************************************************/
1958 u8 twiceAntennaReduction, 1389
1959 u8 twiceMaxRegulatoryPower, 1390static int ath9k_hw_def_get_eeprom_ver(struct ath_hw *ah)
1960 u8 powerLimit)
1961{ 1391{
1962 return ath9k_set_txpower[ah->ah_eep_map](ah, chan, cfgCtl, 1392 return ((ah->ah_eeprom.def.baseEepHeader.version >> 12) & 0xF);
1963 twiceAntennaReduction, twiceMaxRegulatoryPower,
1964 powerLimit);
1965} 1393}
1966 1394
1967static void ath9k_hw_set_def_addac(struct ath_hw *ah, 1395static int ath9k_hw_def_get_eeprom_rev(struct ath_hw *ah)
1968 struct ath9k_channel *chan)
1969{ 1396{
1970#define XPA_LVL_FREQ(cnt) (pModal->xpaBiasLvlFreq[cnt]) 1397 return ((ah->ah_eeprom.def.baseEepHeader.version) & 0xFFF);
1971 struct modal_eep_header *pModal; 1398}
1399
1400static bool ath9k_hw_def_fill_eeprom(struct ath_hw *ah)
1401{
1402#define SIZE_EEPROM_DEF (sizeof(struct ar5416_eeprom_def) / sizeof(u16))
1972 struct ar5416_eeprom_def *eep = &ah->ah_eeprom.def; 1403 struct ar5416_eeprom_def *eep = &ah->ah_eeprom.def;
1973 u8 biaslevel; 1404 u16 *eep_data;
1405 int addr, ar5416_eep_start_loc = 0x100;
1974 1406
1975 if (ah->hw_version.macVersion != AR_SREV_VERSION_9160) 1407 eep_data = (u16 *)eep;
1976 return;
1977 1408
1978 if (ar5416_get_eep_rev(ah) < AR5416_EEP_MINOR_VER_7) 1409 for (addr = 0; addr < SIZE_EEPROM_DEF; addr++) {
1979 return; 1410 if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc,
1411 eep_data)) {
1412 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
1413 "Unable to read eeprom region\n");
1414 return false;
1415 }
1416 eep_data++;
1417 }
1418 return true;
1419#undef SIZE_EEPROM_DEF
1420}
1980 1421
1981 pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]); 1422static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
1423{
1424 struct ar5416_eeprom_def *eep =
1425 (struct ar5416_eeprom_def *) &ah->ah_eeprom.def;
1426 u16 *eepdata, temp, magic, magic2;
1427 u32 sum = 0, el;
1428 bool need_swap = false;
1429 int i, addr, size;
1982 1430
1983 if (pModal->xpaBiasLvl != 0xff) { 1431 if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET,
1984 biaslevel = pModal->xpaBiasLvl; 1432 &magic)) {
1985 } else { 1433 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
1986 u16 resetFreqBin, freqBin, freqCount = 0; 1434 "Reading Magic # failed\n");
1987 struct chan_centers centers; 1435 return false;
1436 }
1988 1437
1989 ath9k_hw_get_channel_centers(ah, chan, &centers); 1438 if (!ath9k_hw_use_flash(ah)) {
1990 1439
1991 resetFreqBin = FREQ2FBIN(centers.synth_center, 1440 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
1992 IS_CHAN_2GHZ(chan)); 1441 "Read Magic = 0x%04X\n", magic);
1993 freqBin = XPA_LVL_FREQ(0) & 0xff;
1994 biaslevel = (u8) (XPA_LVL_FREQ(0) >> 14);
1995 1442
1996 freqCount++; 1443 if (magic != AR5416_EEPROM_MAGIC) {
1444 magic2 = swab16(magic);
1997 1445
1998 while (freqCount < 3) { 1446 if (magic2 == AR5416_EEPROM_MAGIC) {
1999 if (XPA_LVL_FREQ(freqCount) == 0x0) 1447 size = sizeof(struct ar5416_eeprom_def);
2000 break; 1448 need_swap = true;
1449 eepdata = (u16 *) (&ah->ah_eeprom);
2001 1450
2002 freqBin = XPA_LVL_FREQ(freqCount) & 0xff; 1451 for (addr = 0; addr < size / sizeof(u16); addr++) {
2003 if (resetFreqBin >= freqBin) 1452 temp = swab16(*eepdata);
2004 biaslevel = (u8)(XPA_LVL_FREQ(freqCount) >> 14); 1453 *eepdata = temp;
2005 else 1454 eepdata++;
2006 break; 1455
2007 freqCount++; 1456 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
1457 "0x%04X ", *eepdata);
1458
1459 if (((addr + 1) % 6) == 0)
1460 DPRINTF(ah->ah_sc,
1461 ATH_DBG_EEPROM, "\n");
1462 }
1463 } else {
1464 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
1465 "Invalid EEPROM Magic. "
1466 "endianness mismatch.\n");
1467 return -EINVAL;
1468 }
2008 } 1469 }
2009 } 1470 }
2010 1471
2011 if (IS_CHAN_2GHZ(chan)) { 1472 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n",
2012 INI_RA(&ah->ah_iniAddac, 7, 1) = (INI_RA(&ah->ah_iniAddac, 1473 need_swap ? "True" : "False");
2013 7, 1) & (~0x18)) | biaslevel << 3;
2014 } else {
2015 INI_RA(&ah->ah_iniAddac, 6, 1) = (INI_RA(&ah->ah_iniAddac,
2016 6, 1) & (~0xc0)) | biaslevel << 6;
2017 }
2018#undef XPA_LVL_FREQ
2019}
2020 1474
2021static void ath9k_hw_set_4k_addac(struct ath_hw *ah, 1475 if (need_swap)
2022 struct ath9k_channel *chan) 1476 el = swab16(ah->ah_eeprom.def.baseEepHeader.length);
2023{ 1477 else
2024 struct modal_eep_4k_header *pModal; 1478 el = ah->ah_eeprom.def.baseEepHeader.length;
2025 struct ar5416_eeprom_4k *eep = &ah->ah_eeprom.map4k;
2026 u8 biaslevel;
2027 1479
2028 if (ah->hw_version.macVersion != AR_SREV_VERSION_9160) 1480 if (el > sizeof(struct ar5416_eeprom_def))
2029 return; 1481 el = sizeof(struct ar5416_eeprom_def) / sizeof(u16);
1482 else
1483 el = el / sizeof(u16);
2030 1484
2031 if (ar5416_get_eep_rev(ah) < AR5416_EEP_MINOR_VER_7) 1485 eepdata = (u16 *)(&ah->ah_eeprom);
2032 return;
2033 1486
2034 pModal = &eep->modalHeader; 1487 for (i = 0; i < el; i++)
1488 sum ^= *eepdata++;
2035 1489
2036 if (pModal->xpaBiasLvl != 0xff) { 1490 if (need_swap) {
2037 biaslevel = pModal->xpaBiasLvl; 1491 u32 integer, j;
2038 INI_RA(&ah->ah_iniAddac, 7, 1) = 1492 u16 word;
2039 (INI_RA(&ah->ah_iniAddac, 7, 1) & (~0x18)) | biaslevel << 3; 1493
1494 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
1495 "EEPROM Endianness is not native.. Changing \n");
1496
1497 word = swab16(eep->baseEepHeader.length);
1498 eep->baseEepHeader.length = word;
1499
1500 word = swab16(eep->baseEepHeader.checksum);
1501 eep->baseEepHeader.checksum = word;
1502
1503 word = swab16(eep->baseEepHeader.version);
1504 eep->baseEepHeader.version = word;
1505
1506 word = swab16(eep->baseEepHeader.regDmn[0]);
1507 eep->baseEepHeader.regDmn[0] = word;
1508
1509 word = swab16(eep->baseEepHeader.regDmn[1]);
1510 eep->baseEepHeader.regDmn[1] = word;
1511
1512 word = swab16(eep->baseEepHeader.rfSilent);
1513 eep->baseEepHeader.rfSilent = word;
1514
1515 word = swab16(eep->baseEepHeader.blueToothOptions);
1516 eep->baseEepHeader.blueToothOptions = word;
1517
1518 word = swab16(eep->baseEepHeader.deviceCap);
1519 eep->baseEepHeader.deviceCap = word;
1520
1521 for (j = 0; j < ARRAY_SIZE(eep->modalHeader); j++) {
1522 struct modal_eep_header *pModal =
1523 &eep->modalHeader[j];
1524 integer = swab32(pModal->antCtrlCommon);
1525 pModal->antCtrlCommon = integer;
1526
1527 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
1528 integer = swab32(pModal->antCtrlChain[i]);
1529 pModal->antCtrlChain[i] = integer;
1530 }
1531
1532 for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
1533 word = swab16(pModal->spurChans[i].spurChan);
1534 pModal->spurChans[i].spurChan = word;
1535 }
1536 }
2040 } 1537 }
2041}
2042 1538
2043static void (*ath9k_set_addac[]) (struct ath_hw *, struct ath9k_channel *) = { 1539 if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER ||
2044 ath9k_hw_set_def_addac, 1540 ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
2045 ath9k_hw_set_4k_addac 1541 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
2046}; 1542 "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
1543 sum, ah->eep_ops->get_eeprom_ver(ah));
1544 return -EINVAL;
1545 }
2047 1546
2048void ath9k_hw_set_addac(struct ath_hw *ah, struct ath9k_channel *chan) 1547 return 0;
1548}
1549
1550static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah,
1551 enum eeprom_param param)
2049{ 1552{
2050 ath9k_set_addac[ah->ah_eep_map](ah, chan); 1553#define AR5416_VER_MASK (pBase->version & AR5416_EEP_VER_MINOR_MASK)
1554 struct ar5416_eeprom_def *eep = &ah->ah_eeprom.def;
1555 struct modal_eep_header *pModal = eep->modalHeader;
1556 struct base_eep_header *pBase = &eep->baseEepHeader;
1557
1558 switch (param) {
1559 case EEP_NFTHRESH_5:
1560 return pModal[0].noiseFloorThreshCh[0];
1561 case EEP_NFTHRESH_2:
1562 return pModal[1].noiseFloorThreshCh[0];
1563 case AR_EEPROM_MAC(0):
1564 return pBase->macAddr[0] << 8 | pBase->macAddr[1];
1565 case AR_EEPROM_MAC(1):
1566 return pBase->macAddr[2] << 8 | pBase->macAddr[3];
1567 case AR_EEPROM_MAC(2):
1568 return pBase->macAddr[4] << 8 | pBase->macAddr[5];
1569 case EEP_REG_0:
1570 return pBase->regDmn[0];
1571 case EEP_REG_1:
1572 return pBase->regDmn[1];
1573 case EEP_OP_CAP:
1574 return pBase->deviceCap;
1575 case EEP_OP_MODE:
1576 return pBase->opCapFlags;
1577 case EEP_RF_SILENT:
1578 return pBase->rfSilent;
1579 case EEP_OB_5:
1580 return pModal[0].ob;
1581 case EEP_DB_5:
1582 return pModal[0].db;
1583 case EEP_OB_2:
1584 return pModal[1].ob;
1585 case EEP_DB_2:
1586 return pModal[1].db;
1587 case EEP_MINOR_REV:
1588 return AR5416_VER_MASK;
1589 case EEP_TX_MASK:
1590 return pBase->txMask;
1591 case EEP_RX_MASK:
1592 return pBase->rxMask;
1593 case EEP_RXGAIN_TYPE:
1594 return pBase->rxGainType;
1595 case EEP_TXGAIN_TYPE:
1596 return pBase->txGainType;
1597 case EEP_DAC_HPWR_5G:
1598 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20)
1599 return pBase->dacHiPwrMode_5G;
1600 else
1601 return 0;
1602 default:
1603 return 0;
1604 }
1605#undef AR5416_VER_MASK
2051} 1606}
2052 1607
2053/* XXX: Clean me up, make me more legible */ 1608/* XXX: Clean me up, make me more legible */
2054static bool ath9k_hw_eeprom_set_def_board_values(struct ath_hw *ah, 1609static bool ath9k_hw_def_set_board_values(struct ath_hw *ah,
2055 struct ath9k_channel *chan) 1610 struct ath9k_channel *chan)
2056{ 1611{
2057#define AR5416_VER_MASK (eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) 1612#define AR5416_VER_MASK (eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK)
2058 struct modal_eep_header *pModal; 1613 struct modal_eep_header *pModal;
@@ -2065,7 +1620,7 @@ static bool ath9k_hw_eeprom_set_def_board_values(struct ath_hw *ah,
2065 txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44; 1620 txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44;
2066 1621
2067 REG_WRITE(ah, AR_PHY_SWITCH_COM, 1622 REG_WRITE(ah, AR_PHY_SWITCH_COM,
2068 ath9k_hw_get_eeprom_antenna_cfg(ah, chan)); 1623 ah->eep_ops->get_eeprom_antenna_cfg(ah, chan));
2069 1624
2070 for (i = 0; i < AR5416_MAX_CHAINS; i++) { 1625 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
2071 if (AR_SREV_9280(ah)) { 1626 if (AR_SREV_9280(ah)) {
@@ -2295,242 +1850,775 @@ static bool ath9k_hw_eeprom_set_def_board_values(struct ath_hw *ah,
2295#undef AR5416_VER_MASK 1850#undef AR5416_VER_MASK
2296} 1851}
2297 1852
2298static bool ath9k_hw_eeprom_set_4k_board_values(struct ath_hw *ah, 1853static void ath9k_hw_def_set_addac(struct ath_hw *ah,
2299 struct ath9k_channel *chan) 1854 struct ath9k_channel *chan)
2300{ 1855{
2301 struct modal_eep_4k_header *pModal; 1856#define XPA_LVL_FREQ(cnt) (pModal->xpaBiasLvlFreq[cnt])
2302 struct ar5416_eeprom_4k *eep = &ah->ah_eeprom.map4k; 1857 struct modal_eep_header *pModal;
2303 int regChainOffset; 1858 struct ar5416_eeprom_def *eep = &ah->ah_eeprom.def;
2304 u8 txRxAttenLocal; 1859 u8 biaslevel;
2305 u8 ob[5], db1[5], db2[5];
2306 u8 ant_div_control1, ant_div_control2;
2307 u32 regVal;
2308 1860
1861 if (ah->hw_version.macVersion != AR_SREV_VERSION_9160)
1862 return;
2309 1863
2310 pModal = &eep->modalHeader; 1864 if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7)
1865 return;
2311 1866
2312 txRxAttenLocal = 23; 1867 pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
2313 1868
2314 REG_WRITE(ah, AR_PHY_SWITCH_COM, 1869 if (pModal->xpaBiasLvl != 0xff) {
2315 ath9k_hw_get_eeprom_antenna_cfg(ah, chan)); 1870 biaslevel = pModal->xpaBiasLvl;
1871 } else {
1872 u16 resetFreqBin, freqBin, freqCount = 0;
1873 struct chan_centers centers;
2316 1874
2317 regChainOffset = 0; 1875 ath9k_hw_get_channel_centers(ah, chan, &centers);
2318 REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
2319 pModal->antCtrlChain[0]);
2320 1876
2321 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset, 1877 resetFreqBin = FREQ2FBIN(centers.synth_center,
2322 (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) & 1878 IS_CHAN_2GHZ(chan));
2323 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF | 1879 freqBin = XPA_LVL_FREQ(0) & 0xff;
2324 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) | 1880 biaslevel = (u8) (XPA_LVL_FREQ(0) >> 14);
2325 SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
2326 SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
2327 1881
2328 if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= 1882 freqCount++;
2329 AR5416_EEP_MINOR_VER_3) {
2330 txRxAttenLocal = pModal->txRxAttenCh[0];
2331 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
2332 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, pModal->bswMargin[0]);
2333 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
2334 AR_PHY_GAIN_2GHZ_XATTEN1_DB, pModal->bswAtten[0]);
2335 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
2336 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
2337 pModal->xatten2Margin[0]);
2338 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
2339 AR_PHY_GAIN_2GHZ_XATTEN2_DB, pModal->xatten2Db[0]);
2340 }
2341 1883
2342 REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset, 1884 while (freqCount < 3) {
2343 AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal); 1885 if (XPA_LVL_FREQ(freqCount) == 0x0)
2344 REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset, 1886 break;
2345 AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]);
2346 1887
2347 if (AR_SREV_9285_11(ah)) 1888 freqBin = XPA_LVL_FREQ(freqCount) & 0xff;
2348 REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14)); 1889 if (resetFreqBin >= freqBin)
1890 biaslevel = (u8)(XPA_LVL_FREQ(freqCount) >> 14);
1891 else
1892 break;
1893 freqCount++;
1894 }
1895 }
2349 1896
2350 /* Initialize Ant Diversity settings from EEPROM */ 1897 if (IS_CHAN_2GHZ(chan)) {
2351 if (pModal->version == 3) { 1898 INI_RA(&ah->ah_iniAddac, 7, 1) = (INI_RA(&ah->ah_iniAddac,
2352 ant_div_control1 = ((pModal->ob_234 >> 12) & 0xf); 1899 7, 1) & (~0x18)) | biaslevel << 3;
2353 ant_div_control2 = ((pModal->db1_234 >> 12) & 0xf); 1900 } else {
2354 regVal = REG_READ(ah, 0x99ac); 1901 INI_RA(&ah->ah_iniAddac, 6, 1) = (INI_RA(&ah->ah_iniAddac,
2355 regVal &= (~(0x7f000000)); 1902 6, 1) & (~0xc0)) | biaslevel << 6;
2356 regVal |= ((ant_div_control1 & 0x1) << 24);
2357 regVal |= (((ant_div_control1 >> 1) & 0x1) << 29);
2358 regVal |= (((ant_div_control1 >> 2) & 0x1) << 30);
2359 regVal |= ((ant_div_control2 & 0x3) << 25);
2360 regVal |= (((ant_div_control2 >> 2) & 0x3) << 27);
2361 REG_WRITE(ah, 0x99ac, regVal);
2362 regVal = REG_READ(ah, 0x99ac);
2363 regVal = REG_READ(ah, 0xa208);
2364 regVal &= (~(0x1 << 13));
2365 regVal |= (((ant_div_control1 >> 3) & 0x1) << 13);
2366 REG_WRITE(ah, 0xa208, regVal);
2367 regVal = REG_READ(ah, 0xa208);
2368 } 1903 }
1904#undef XPA_LVL_FREQ
1905}
2369 1906
2370 if (pModal->version >= 2) { 1907static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw *ah,
2371 ob[0] = (pModal->ob_01 & 0xf); 1908 struct ath9k_channel *chan,
2372 ob[1] = (pModal->ob_01 >> 4) & 0xf; 1909 struct cal_data_per_freq *pRawDataSet,
2373 ob[2] = (pModal->ob_234 & 0xf); 1910 u8 *bChans, u16 availPiers,
2374 ob[3] = ((pModal->ob_234 >> 4) & 0xf); 1911 u16 tPdGainOverlap, int16_t *pMinCalPower,
2375 ob[4] = ((pModal->ob_234 >> 8) & 0xf); 1912 u16 *pPdGainBoundaries, u8 *pPDADCValues,
1913 u16 numXpdGains)
1914{
1915 int i, j, k;
1916 int16_t ss;
1917 u16 idxL = 0, idxR = 0, numPiers;
1918 static u8 vpdTableL[AR5416_NUM_PD_GAINS]
1919 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
1920 static u8 vpdTableR[AR5416_NUM_PD_GAINS]
1921 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
1922 static u8 vpdTableI[AR5416_NUM_PD_GAINS]
1923 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
2376 1924
2377 db1[0] = (pModal->db1_01 & 0xf); 1925 u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
2378 db1[1] = ((pModal->db1_01 >> 4) & 0xf); 1926 u8 minPwrT4[AR5416_NUM_PD_GAINS];
2379 db1[2] = (pModal->db1_234 & 0xf); 1927 u8 maxPwrT4[AR5416_NUM_PD_GAINS];
2380 db1[3] = ((pModal->db1_234 >> 4) & 0xf); 1928 int16_t vpdStep;
2381 db1[4] = ((pModal->db1_234 >> 8) & 0xf); 1929 int16_t tmpVal;
1930 u16 sizeCurrVpdTable, maxIndex, tgtIndex;
1931 bool match;
1932 int16_t minDelta = 0;
1933 struct chan_centers centers;
2382 1934
2383 db2[0] = (pModal->db2_01 & 0xf); 1935 ath9k_hw_get_channel_centers(ah, chan, &centers);
2384 db2[1] = ((pModal->db2_01 >> 4) & 0xf);
2385 db2[2] = (pModal->db2_234 & 0xf);
2386 db2[3] = ((pModal->db2_234 >> 4) & 0xf);
2387 db2[4] = ((pModal->db2_234 >> 8) & 0xf);
2388 1936
2389 } else if (pModal->version == 1) { 1937 for (numPiers = 0; numPiers < availPiers; numPiers++) {
1938 if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
1939 break;
1940 }
2390 1941
2391 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 1942 match = ath9k_hw_get_lower_upper_index((u8)FREQ2FBIN(centers.synth_center,
2392 "EEPROM Model version is set to 1 \n"); 1943 IS_CHAN_2GHZ(chan)),
2393 ob[0] = (pModal->ob_01 & 0xf); 1944 bChans, numPiers, &idxL, &idxR);
2394 ob[1] = ob[2] = ob[3] = ob[4] = (pModal->ob_01 >> 4) & 0xf; 1945
2395 db1[0] = (pModal->db1_01 & 0xf); 1946 if (match) {
2396 db1[1] = db1[2] = db1[3] = 1947 for (i = 0; i < numXpdGains; i++) {
2397 db1[4] = ((pModal->db1_01 >> 4) & 0xf); 1948 minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
2398 db2[0] = (pModal->db2_01 & 0xf); 1949 maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
2399 db2[1] = db2[2] = db2[3] = 1950 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
2400 db2[4] = ((pModal->db2_01 >> 4) & 0xf); 1951 pRawDataSet[idxL].pwrPdg[i],
1952 pRawDataSet[idxL].vpdPdg[i],
1953 AR5416_PD_GAIN_ICEPTS,
1954 vpdTableI[i]);
1955 }
2401 } else { 1956 } else {
2402 int i; 1957 for (i = 0; i < numXpdGains; i++) {
2403 for (i = 0; i < 5; i++) { 1958 pVpdL = pRawDataSet[idxL].vpdPdg[i];
2404 ob[i] = pModal->ob_01; 1959 pPwrL = pRawDataSet[idxL].pwrPdg[i];
2405 db1[i] = pModal->db1_01; 1960 pVpdR = pRawDataSet[idxR].vpdPdg[i];
2406 db2[i] = pModal->db1_01; 1961 pPwrR = pRawDataSet[idxR].pwrPdg[i];
1962
1963 minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
1964
1965 maxPwrT4[i] =
1966 min(pPwrL[AR5416_PD_GAIN_ICEPTS - 1],
1967 pPwrR[AR5416_PD_GAIN_ICEPTS - 1]);
1968
1969
1970 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
1971 pPwrL, pVpdL,
1972 AR5416_PD_GAIN_ICEPTS,
1973 vpdTableL[i]);
1974 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
1975 pPwrR, pVpdR,
1976 AR5416_PD_GAIN_ICEPTS,
1977 vpdTableR[i]);
1978
1979 for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
1980 vpdTableI[i][j] =
1981 (u8)(ath9k_hw_interpolate((u16)
1982 FREQ2FBIN(centers.
1983 synth_center,
1984 IS_CHAN_2GHZ
1985 (chan)),
1986 bChans[idxL], bChans[idxR],
1987 vpdTableL[i][j], vpdTableR[i][j]));
1988 }
2407 } 1989 }
2408 } 1990 }
2409 1991
2410 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, 1992 *pMinCalPower = (int16_t)(minPwrT4[0] / 2);
2411 AR9285_AN_RF2G3_OB_0, AR9285_AN_RF2G3_OB_0_S, ob[0]);
2412 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
2413 AR9285_AN_RF2G3_OB_1, AR9285_AN_RF2G3_OB_1_S, ob[1]);
2414 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
2415 AR9285_AN_RF2G3_OB_2, AR9285_AN_RF2G3_OB_2_S, ob[2]);
2416 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
2417 AR9285_AN_RF2G3_OB_3, AR9285_AN_RF2G3_OB_3_S, ob[3]);
2418 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
2419 AR9285_AN_RF2G3_OB_4, AR9285_AN_RF2G3_OB_4_S, ob[4]);
2420 1993
2421 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, 1994 k = 0;
2422 AR9285_AN_RF2G3_DB1_0, AR9285_AN_RF2G3_DB1_0_S, db1[0]);
2423 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
2424 AR9285_AN_RF2G3_DB1_1, AR9285_AN_RF2G3_DB1_1_S, db1[1]);
2425 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
2426 AR9285_AN_RF2G3_DB1_2, AR9285_AN_RF2G3_DB1_2_S, db1[2]);
2427 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
2428 AR9285_AN_RF2G4_DB1_3, AR9285_AN_RF2G4_DB1_3_S, db1[3]);
2429 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
2430 AR9285_AN_RF2G4_DB1_4, AR9285_AN_RF2G4_DB1_4_S, db1[4]);
2431 1995
2432 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, 1996 for (i = 0; i < numXpdGains; i++) {
2433 AR9285_AN_RF2G4_DB2_0, AR9285_AN_RF2G4_DB2_0_S, db2[0]); 1997 if (i == (numXpdGains - 1))
2434 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, 1998 pPdGainBoundaries[i] =
2435 AR9285_AN_RF2G4_DB2_1, AR9285_AN_RF2G4_DB2_1_S, db2[1]); 1999 (u16)(maxPwrT4[i] / 2);
2436 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, 2000 else
2437 AR9285_AN_RF2G4_DB2_2, AR9285_AN_RF2G4_DB2_2_S, db2[2]); 2001 pPdGainBoundaries[i] =
2438 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, 2002 (u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
2439 AR9285_AN_RF2G4_DB2_3, AR9285_AN_RF2G4_DB2_3_S, db2[3]);
2440 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
2441 AR9285_AN_RF2G4_DB2_4, AR9285_AN_RF2G4_DB2_4_S, db2[4]);
2442 2003
2004 pPdGainBoundaries[i] =
2005 min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
2443 2006
2444 if (AR_SREV_9285_11(ah)) 2007 if ((i == 0) && !AR_SREV_5416_V20_OR_LATER(ah)) {
2445 REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT); 2008 minDelta = pPdGainBoundaries[0] - 23;
2009 pPdGainBoundaries[0] = 23;
2010 } else {
2011 minDelta = 0;
2012 }
2446 2013
2447 REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH, 2014 if (i == 0) {
2448 pModal->switchSettling); 2015 if (AR_SREV_9280_10_OR_LATER(ah))
2449 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC, 2016 ss = (int16_t)(0 - (minPwrT4[i] / 2));
2450 pModal->adcDesiredSize); 2017 else
2018 ss = 0;
2019 } else {
2020 ss = (int16_t)((pPdGainBoundaries[i - 1] -
2021 (minPwrT4[i] / 2)) -
2022 tPdGainOverlap + 1 + minDelta);
2023 }
2024 vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
2025 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
2451 2026
2452 REG_WRITE(ah, AR_PHY_RF_CTL4, 2027 while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
2453 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) | 2028 tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
2454 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) | 2029 pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
2455 SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON) | 2030 ss++;
2456 SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON)); 2031 }
2457 2032
2458 REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON, 2033 sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
2459 pModal->txEndToRxOn); 2034 tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap -
2460 REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62, 2035 (minPwrT4[i] / 2));
2461 pModal->thresh62); 2036 maxIndex = (tgtIndex < sizeCurrVpdTable) ?
2462 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62, 2037 tgtIndex : sizeCurrVpdTable;
2463 pModal->thresh62);
2464 2038
2465 if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= 2039 while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
2466 AR5416_EEP_MINOR_VER_2) { 2040 pPDADCValues[k++] = vpdTableI[i][ss++];
2467 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_DATA_START, 2041 }
2468 pModal->txFrameToDataStart);
2469 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON,
2470 pModal->txFrameToPaOn);
2471 }
2472 2042
2473 if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= 2043 vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
2474 AR5416_EEP_MINOR_VER_3) { 2044 vpdTableI[i][sizeCurrVpdTable - 2]);
2475 if (IS_CHAN_HT40(chan)) 2045 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
2476 REG_RMW_FIELD(ah, AR_PHY_SETTLING, 2046
2477 AR_PHY_SETTLING_SWITCH, 2047 if (tgtIndex > maxIndex) {
2478 pModal->swSettleHt40); 2048 while ((ss <= tgtIndex) &&
2049 (k < (AR5416_NUM_PDADC_VALUES - 1))) {
2050 tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] +
2051 (ss - maxIndex + 1) * vpdStep));
2052 pPDADCValues[k++] = (u8)((tmpVal > 255) ?
2053 255 : tmpVal);
2054 ss++;
2055 }
2056 }
2479 } 2057 }
2480 2058
2481 return true; 2059 while (i < AR5416_PD_GAINS_IN_MASK) {
2482} 2060 pPdGainBoundaries[i] = pPdGainBoundaries[i - 1];
2061 i++;
2062 }
2483 2063
2484static bool (*ath9k_eeprom_set_board_values[])(struct ath_hw *, 2064 while (k < AR5416_NUM_PDADC_VALUES) {
2485 struct ath9k_channel *) = { 2065 pPDADCValues[k] = pPDADCValues[k - 1];
2486 ath9k_hw_eeprom_set_def_board_values, 2066 k++;
2487 ath9k_hw_eeprom_set_4k_board_values 2067 }
2488};
2489 2068
2490bool ath9k_hw_eeprom_set_board_values(struct ath_hw *ah, 2069 return;
2491 struct ath9k_channel *chan)
2492{
2493 return ath9k_eeprom_set_board_values[ah->ah_eep_map](ah, chan);
2494} 2070}
2495 2071
2496static u16 ath9k_hw_get_def_eeprom_antenna_cfg(struct ath_hw *ah, 2072static bool ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
2497 struct ath9k_channel *chan) 2073 struct ath9k_channel *chan,
2074 int16_t *pTxPowerIndexOffset)
2498{ 2075{
2499 struct ar5416_eeprom_def *eep = &ah->ah_eeprom.def; 2076 struct ar5416_eeprom_def *pEepData = &ah->ah_eeprom.def;
2500 struct modal_eep_header *pModal = 2077 struct cal_data_per_freq *pRawDataset;
2501 &(eep->modalHeader[IS_CHAN_2GHZ(chan)]); 2078 u8 *pCalBChans = NULL;
2079 u16 pdGainOverlap_t2;
2080 static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
2081 u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
2082 u16 numPiers, i, j;
2083 int16_t tMinCalPower;
2084 u16 numXpdGain, xpdMask;
2085 u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
2086 u32 reg32, regOffset, regChainOffset;
2087 int16_t modalIdx;
2502 2088
2503 return pModal->antCtrlCommon & 0xFFFF; 2089 modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
2090 xpdMask = pEepData->modalHeader[modalIdx].xpdGain;
2091
2092 if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
2093 AR5416_EEP_MINOR_VER_2) {
2094 pdGainOverlap_t2 =
2095 pEepData->modalHeader[modalIdx].pdGainOverlap;
2096 } else {
2097 pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),
2098 AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
2099 }
2100
2101 if (IS_CHAN_2GHZ(chan)) {
2102 pCalBChans = pEepData->calFreqPier2G;
2103 numPiers = AR5416_NUM_2G_CAL_PIERS;
2104 } else {
2105 pCalBChans = pEepData->calFreqPier5G;
2106 numPiers = AR5416_NUM_5G_CAL_PIERS;
2107 }
2108
2109 numXpdGain = 0;
2110
2111 for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
2112 if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
2113 if (numXpdGain >= AR5416_NUM_PD_GAINS)
2114 break;
2115 xpdGainValues[numXpdGain] =
2116 (u16)(AR5416_PD_GAINS_IN_MASK - i);
2117 numXpdGain++;
2118 }
2119 }
2120
2121 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
2122 (numXpdGain - 1) & 0x3);
2123 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
2124 xpdGainValues[0]);
2125 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
2126 xpdGainValues[1]);
2127 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
2128 xpdGainValues[2]);
2129
2130 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
2131 if (AR_SREV_5416_V20_OR_LATER(ah) &&
2132 (ah->ah_rxchainmask == 5 || ah->ah_txchainmask == 5) &&
2133 (i != 0)) {
2134 regChainOffset = (i == 1) ? 0x2000 : 0x1000;
2135 } else
2136 regChainOffset = i * 0x1000;
2137
2138 if (pEepData->baseEepHeader.txMask & (1 << i)) {
2139 if (IS_CHAN_2GHZ(chan))
2140 pRawDataset = pEepData->calPierData2G[i];
2141 else
2142 pRawDataset = pEepData->calPierData5G[i];
2143
2144 ath9k_hw_get_def_gain_boundaries_pdadcs(ah, chan,
2145 pRawDataset, pCalBChans,
2146 numPiers, pdGainOverlap_t2,
2147 &tMinCalPower, gainBoundaries,
2148 pdadcValues, numXpdGain);
2149
2150 if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
2151 REG_WRITE(ah,
2152 AR_PHY_TPCRG5 + regChainOffset,
2153 SM(pdGainOverlap_t2,
2154 AR_PHY_TPCRG5_PD_GAIN_OVERLAP)
2155 | SM(gainBoundaries[0],
2156 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1)
2157 | SM(gainBoundaries[1],
2158 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2)
2159 | SM(gainBoundaries[2],
2160 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3)
2161 | SM(gainBoundaries[3],
2162 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
2163 }
2164
2165 regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
2166 for (j = 0; j < 32; j++) {
2167 reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) |
2168 ((pdadcValues[4 * j + 1] & 0xFF) << 8) |
2169 ((pdadcValues[4 * j + 2] & 0xFF) << 16)|
2170 ((pdadcValues[4 * j + 3] & 0xFF) << 24);
2171 REG_WRITE(ah, regOffset, reg32);
2172
2173 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
2174 "PDADC (%d,%4x): %4.4x %8.8x\n",
2175 i, regChainOffset, regOffset,
2176 reg32);
2177 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
2178 "PDADC: Chain %d | PDADC %3d "
2179 "Value %3d | PDADC %3d Value %3d | "
2180 "PDADC %3d Value %3d | PDADC %3d "
2181 "Value %3d |\n",
2182 i, 4 * j, pdadcValues[4 * j],
2183 4 * j + 1, pdadcValues[4 * j + 1],
2184 4 * j + 2, pdadcValues[4 * j + 2],
2185 4 * j + 3,
2186 pdadcValues[4 * j + 3]);
2187
2188 regOffset += 4;
2189 }
2190 }
2191 }
2192
2193 *pTxPowerIndexOffset = 0;
2194
2195 return true;
2504} 2196}
2505 2197
2506static u16 ath9k_hw_get_4k_eeprom_antenna_cfg(struct ath_hw *ah, 2198static bool ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
2507 struct ath9k_channel *chan) 2199 struct ath9k_channel *chan,
2200 int16_t *ratesArray,
2201 u16 cfgCtl,
2202 u16 AntennaReduction,
2203 u16 twiceMaxRegulatoryPower,
2204 u16 powerLimit)
2508{ 2205{
2509 struct ar5416_eeprom_4k *eep = &ah->ah_eeprom.map4k; 2206#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */
2510 struct modal_eep_4k_header *pModal = &eep->modalHeader; 2207#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10 /* 10*log10(3)*2 */
2511 2208
2512 return pModal->antCtrlCommon & 0xFFFF; 2209 struct ar5416_eeprom_def *pEepData = &ah->ah_eeprom.def;
2513} 2210 u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
2211 static const u16 tpScaleReductionTable[5] =
2212 { 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
2514 2213
2515static u16 (*ath9k_get_eeprom_antenna_cfg[])(struct ath_hw *, 2214 int i;
2516 struct ath9k_channel *) = { 2215 int16_t twiceLargestAntenna;
2517 ath9k_hw_get_def_eeprom_antenna_cfg, 2216 struct cal_ctl_data *rep;
2518 ath9k_hw_get_4k_eeprom_antenna_cfg 2217 struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
2519}; 2218 0, { 0, 0, 0, 0}
2219 };
2220 struct cal_target_power_leg targetPowerOfdmExt = {
2221 0, { 0, 0, 0, 0} }, targetPowerCckExt = {
2222 0, { 0, 0, 0, 0 }
2223 };
2224 struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
2225 0, {0, 0, 0, 0}
2226 };
2227 u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
2228 u16 ctlModesFor11a[] =
2229 { CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 };
2230 u16 ctlModesFor11g[] =
2231 { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
2232 CTL_2GHT40
2233 };
2234 u16 numCtlModes, *pCtlMode, ctlMode, freq;
2235 struct chan_centers centers;
2236 int tx_chainmask;
2237 u16 twiceMinEdgePower;
2520 2238
2521u16 ath9k_hw_get_eeprom_antenna_cfg(struct ath_hw *ah, 2239 tx_chainmask = ah->ah_txchainmask;
2522 struct ath9k_channel *chan) 2240
2523{ 2241 ath9k_hw_get_channel_centers(ah, chan, &centers);
2524 return ath9k_get_eeprom_antenna_cfg[ah->ah_eep_map](ah, chan); 2242
2243 twiceLargestAntenna = max(
2244 pEepData->modalHeader
2245 [IS_CHAN_2GHZ(chan)].antennaGainCh[0],
2246 pEepData->modalHeader
2247 [IS_CHAN_2GHZ(chan)].antennaGainCh[1]);
2248
2249 twiceLargestAntenna = max((u8)twiceLargestAntenna,
2250 pEepData->modalHeader
2251 [IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
2252
2253 twiceLargestAntenna = (int16_t)min(AntennaReduction -
2254 twiceLargestAntenna, 0);
2255
2256 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
2257
2258 if (ah->regulatory.tp_scale != ATH9K_TP_SCALE_MAX) {
2259 maxRegAllowedPower -=
2260 (tpScaleReductionTable[(ah->regulatory.tp_scale)] * 2);
2261 }
2262
2263 scaledPower = min(powerLimit, maxRegAllowedPower);
2264
2265 switch (ar5416_get_ntxchains(tx_chainmask)) {
2266 case 1:
2267 break;
2268 case 2:
2269 scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
2270 break;
2271 case 3:
2272 scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
2273 break;
2274 }
2275
2276 scaledPower = max((u16)0, scaledPower);
2277
2278 if (IS_CHAN_2GHZ(chan)) {
2279 numCtlModes = ARRAY_SIZE(ctlModesFor11g) -
2280 SUB_NUM_CTL_MODES_AT_2G_40;
2281 pCtlMode = ctlModesFor11g;
2282
2283 ath9k_hw_get_legacy_target_powers(ah, chan,
2284 pEepData->calTargetPowerCck,
2285 AR5416_NUM_2G_CCK_TARGET_POWERS,
2286 &targetPowerCck, 4, false);
2287 ath9k_hw_get_legacy_target_powers(ah, chan,
2288 pEepData->calTargetPower2G,
2289 AR5416_NUM_2G_20_TARGET_POWERS,
2290 &targetPowerOfdm, 4, false);
2291 ath9k_hw_get_target_powers(ah, chan,
2292 pEepData->calTargetPower2GHT20,
2293 AR5416_NUM_2G_20_TARGET_POWERS,
2294 &targetPowerHt20, 8, false);
2295
2296 if (IS_CHAN_HT40(chan)) {
2297 numCtlModes = ARRAY_SIZE(ctlModesFor11g);
2298 ath9k_hw_get_target_powers(ah, chan,
2299 pEepData->calTargetPower2GHT40,
2300 AR5416_NUM_2G_40_TARGET_POWERS,
2301 &targetPowerHt40, 8, true);
2302 ath9k_hw_get_legacy_target_powers(ah, chan,
2303 pEepData->calTargetPowerCck,
2304 AR5416_NUM_2G_CCK_TARGET_POWERS,
2305 &targetPowerCckExt, 4, true);
2306 ath9k_hw_get_legacy_target_powers(ah, chan,
2307 pEepData->calTargetPower2G,
2308 AR5416_NUM_2G_20_TARGET_POWERS,
2309 &targetPowerOfdmExt, 4, true);
2310 }
2311 } else {
2312 numCtlModes = ARRAY_SIZE(ctlModesFor11a) -
2313 SUB_NUM_CTL_MODES_AT_5G_40;
2314 pCtlMode = ctlModesFor11a;
2315
2316 ath9k_hw_get_legacy_target_powers(ah, chan,
2317 pEepData->calTargetPower5G,
2318 AR5416_NUM_5G_20_TARGET_POWERS,
2319 &targetPowerOfdm, 4, false);
2320 ath9k_hw_get_target_powers(ah, chan,
2321 pEepData->calTargetPower5GHT20,
2322 AR5416_NUM_5G_20_TARGET_POWERS,
2323 &targetPowerHt20, 8, false);
2324
2325 if (IS_CHAN_HT40(chan)) {
2326 numCtlModes = ARRAY_SIZE(ctlModesFor11a);
2327 ath9k_hw_get_target_powers(ah, chan,
2328 pEepData->calTargetPower5GHT40,
2329 AR5416_NUM_5G_40_TARGET_POWERS,
2330 &targetPowerHt40, 8, true);
2331 ath9k_hw_get_legacy_target_powers(ah, chan,
2332 pEepData->calTargetPower5G,
2333 AR5416_NUM_5G_20_TARGET_POWERS,
2334 &targetPowerOfdmExt, 4, true);
2335 }
2336 }
2337
2338 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
2339 bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
2340 (pCtlMode[ctlMode] == CTL_2GHT40);
2341 if (isHt40CtlMode)
2342 freq = centers.synth_center;
2343 else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
2344 freq = centers.ext_center;
2345 else
2346 freq = centers.ctl_center;
2347
2348 if (ah->eep_ops->get_eeprom_ver(ah) == 14 &&
2349 ah->eep_ops->get_eeprom_rev(ah) <= 2)
2350 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
2351
2352 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
2353 "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
2354 "EXT_ADDITIVE %d\n",
2355 ctlMode, numCtlModes, isHt40CtlMode,
2356 (pCtlMode[ctlMode] & EXT_ADDITIVE));
2357
2358 for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i]; i++) {
2359 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
2360 " LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
2361 "pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
2362 "chan %d\n",
2363 i, cfgCtl, pCtlMode[ctlMode],
2364 pEepData->ctlIndex[i], chan->channel);
2365
2366 if ((((cfgCtl & ~CTL_MODE_M) |
2367 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
2368 pEepData->ctlIndex[i]) ||
2369 (((cfgCtl & ~CTL_MODE_M) |
2370 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
2371 ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) {
2372 rep = &(pEepData->ctlData[i]);
2373
2374 twiceMinEdgePower = ath9k_hw_get_max_edge_power(freq,
2375 rep->ctlEdges[ar5416_get_ntxchains(tx_chainmask) - 1],
2376 IS_CHAN_2GHZ(chan), AR5416_NUM_BAND_EDGES);
2377
2378 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
2379 " MATCH-EE_IDX %d: ch %d is2 %d "
2380 "2xMinEdge %d chainmask %d chains %d\n",
2381 i, freq, IS_CHAN_2GHZ(chan),
2382 twiceMinEdgePower, tx_chainmask,
2383 ar5416_get_ntxchains
2384 (tx_chainmask));
2385 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
2386 twiceMaxEdgePower = min(twiceMaxEdgePower,
2387 twiceMinEdgePower);
2388 } else {
2389 twiceMaxEdgePower = twiceMinEdgePower;
2390 break;
2391 }
2392 }
2393 }
2394
2395 minCtlPower = min(twiceMaxEdgePower, scaledPower);
2396
2397 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
2398 " SEL-Min ctlMode %d pCtlMode %d "
2399 "2xMaxEdge %d sP %d minCtlPwr %d\n",
2400 ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
2401 scaledPower, minCtlPower);
2402
2403 switch (pCtlMode[ctlMode]) {
2404 case CTL_11B:
2405 for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); i++) {
2406 targetPowerCck.tPow2x[i] =
2407 min((u16)targetPowerCck.tPow2x[i],
2408 minCtlPower);
2409 }
2410 break;
2411 case CTL_11A:
2412 case CTL_11G:
2413 for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) {
2414 targetPowerOfdm.tPow2x[i] =
2415 min((u16)targetPowerOfdm.tPow2x[i],
2416 minCtlPower);
2417 }
2418 break;
2419 case CTL_5GHT20:
2420 case CTL_2GHT20:
2421 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) {
2422 targetPowerHt20.tPow2x[i] =
2423 min((u16)targetPowerHt20.tPow2x[i],
2424 minCtlPower);
2425 }
2426 break;
2427 case CTL_11B_EXT:
2428 targetPowerCckExt.tPow2x[0] = min((u16)
2429 targetPowerCckExt.tPow2x[0],
2430 minCtlPower);
2431 break;
2432 case CTL_11A_EXT:
2433 case CTL_11G_EXT:
2434 targetPowerOfdmExt.tPow2x[0] = min((u16)
2435 targetPowerOfdmExt.tPow2x[0],
2436 minCtlPower);
2437 break;
2438 case CTL_5GHT40:
2439 case CTL_2GHT40:
2440 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
2441 targetPowerHt40.tPow2x[i] =
2442 min((u16)targetPowerHt40.tPow2x[i],
2443 minCtlPower);
2444 }
2445 break;
2446 default:
2447 break;
2448 }
2449 }
2450
2451 ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
2452 ratesArray[rate18mb] = ratesArray[rate24mb] =
2453 targetPowerOfdm.tPow2x[0];
2454 ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
2455 ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
2456 ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
2457 ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
2458
2459 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
2460 ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
2461
2462 if (IS_CHAN_2GHZ(chan)) {
2463 ratesArray[rate1l] = targetPowerCck.tPow2x[0];
2464 ratesArray[rate2s] = ratesArray[rate2l] =
2465 targetPowerCck.tPow2x[1];
2466 ratesArray[rate5_5s] = ratesArray[rate5_5l] =
2467 targetPowerCck.tPow2x[2];
2468 ;
2469 ratesArray[rate11s] = ratesArray[rate11l] =
2470 targetPowerCck.tPow2x[3];
2471 ;
2472 }
2473 if (IS_CHAN_HT40(chan)) {
2474 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
2475 ratesArray[rateHt40_0 + i] =
2476 targetPowerHt40.tPow2x[i];
2477 }
2478 ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
2479 ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
2480 ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
2481 if (IS_CHAN_2GHZ(chan)) {
2482 ratesArray[rateExtCck] =
2483 targetPowerCckExt.tPow2x[0];
2484 }
2485 }
2486 return true;
2525} 2487}
2526 2488
2527static u8 ath9k_hw_get_4k_num_ant_config(struct ath_hw *ah, 2489static int ath9k_hw_def_set_txpower(struct ath_hw *ah,
2528 enum ieee80211_band freq_band) 2490 struct ath9k_channel *chan,
2491 u16 cfgCtl,
2492 u8 twiceAntennaReduction,
2493 u8 twiceMaxRegulatoryPower,
2494 u8 powerLimit)
2529{ 2495{
2530 return 1; 2496 struct ar5416_eeprom_def *pEepData = &ah->ah_eeprom.def;
2497 struct modal_eep_header *pModal =
2498 &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]);
2499 int16_t ratesArray[Ar5416RateSize];
2500 int16_t txPowerIndexOffset = 0;
2501 u8 ht40PowerIncForPdadc = 2;
2502 int i;
2503
2504 memset(ratesArray, 0, sizeof(ratesArray));
2505
2506 if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
2507 AR5416_EEP_MINOR_VER_2) {
2508 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
2509 }
2510
2511 if (!ath9k_hw_set_def_power_per_rate_table(ah, chan,
2512 &ratesArray[0], cfgCtl,
2513 twiceAntennaReduction,
2514 twiceMaxRegulatoryPower,
2515 powerLimit)) {
2516 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
2517 "ath9k_hw_set_txpower: unable to set "
2518 "tx power per rate table\n");
2519 return -EIO;
2520 }
2521
2522 if (!ath9k_hw_set_def_power_cal_table(ah, chan, &txPowerIndexOffset)) {
2523 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
2524 "ath9k_hw_set_txpower: unable to set power table\n");
2525 return -EIO;
2526 }
2527
2528 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
2529 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
2530 if (ratesArray[i] > AR5416_MAX_RATE_POWER)
2531 ratesArray[i] = AR5416_MAX_RATE_POWER;
2532 }
2533
2534 if (AR_SREV_9280_10_OR_LATER(ah)) {
2535 for (i = 0; i < Ar5416RateSize; i++)
2536 ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2;
2537 }
2538
2539 REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
2540 ATH9K_POW_SM(ratesArray[rate18mb], 24)
2541 | ATH9K_POW_SM(ratesArray[rate12mb], 16)
2542 | ATH9K_POW_SM(ratesArray[rate9mb], 8)
2543 | ATH9K_POW_SM(ratesArray[rate6mb], 0));
2544 REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
2545 ATH9K_POW_SM(ratesArray[rate54mb], 24)
2546 | ATH9K_POW_SM(ratesArray[rate48mb], 16)
2547 | ATH9K_POW_SM(ratesArray[rate36mb], 8)
2548 | ATH9K_POW_SM(ratesArray[rate24mb], 0));
2549
2550 if (IS_CHAN_2GHZ(chan)) {
2551 REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
2552 ATH9K_POW_SM(ratesArray[rate2s], 24)
2553 | ATH9K_POW_SM(ratesArray[rate2l], 16)
2554 | ATH9K_POW_SM(ratesArray[rateXr], 8)
2555 | ATH9K_POW_SM(ratesArray[rate1l], 0));
2556 REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
2557 ATH9K_POW_SM(ratesArray[rate11s], 24)
2558 | ATH9K_POW_SM(ratesArray[rate11l], 16)
2559 | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
2560 | ATH9K_POW_SM(ratesArray[rate5_5l], 0));
2561 }
2562
2563 REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
2564 ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
2565 | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
2566 | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
2567 | ATH9K_POW_SM(ratesArray[rateHt20_0], 0));
2568 REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
2569 ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
2570 | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
2571 | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
2572 | ATH9K_POW_SM(ratesArray[rateHt20_4], 0));
2573
2574 if (IS_CHAN_HT40(chan)) {
2575 REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
2576 ATH9K_POW_SM(ratesArray[rateHt40_3] +
2577 ht40PowerIncForPdadc, 24)
2578 | ATH9K_POW_SM(ratesArray[rateHt40_2] +
2579 ht40PowerIncForPdadc, 16)
2580 | ATH9K_POW_SM(ratesArray[rateHt40_1] +
2581 ht40PowerIncForPdadc, 8)
2582 | ATH9K_POW_SM(ratesArray[rateHt40_0] +
2583 ht40PowerIncForPdadc, 0));
2584 REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
2585 ATH9K_POW_SM(ratesArray[rateHt40_7] +
2586 ht40PowerIncForPdadc, 24)
2587 | ATH9K_POW_SM(ratesArray[rateHt40_6] +
2588 ht40PowerIncForPdadc, 16)
2589 | ATH9K_POW_SM(ratesArray[rateHt40_5] +
2590 ht40PowerIncForPdadc, 8)
2591 | ATH9K_POW_SM(ratesArray[rateHt40_4] +
2592 ht40PowerIncForPdadc, 0));
2593
2594 REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
2595 ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
2596 | ATH9K_POW_SM(ratesArray[rateExtCck], 16)
2597 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
2598 | ATH9K_POW_SM(ratesArray[rateDupCck], 0));
2599 }
2600
2601 REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
2602 ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
2603 | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0));
2604
2605 i = rate6mb;
2606
2607 if (IS_CHAN_HT40(chan))
2608 i = rateHt40_0;
2609 else if (IS_CHAN_HT20(chan))
2610 i = rateHt20_0;
2611
2612 if (AR_SREV_9280_10_OR_LATER(ah))
2613 ah->regulatory.max_power_level =
2614 ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
2615 else
2616 ah->regulatory.max_power_level = ratesArray[i];
2617
2618 return 0;
2531} 2619}
2532 2620
2533static u8 ath9k_hw_get_def_num_ant_config(struct ath_hw *ah, 2621static u8 ath9k_hw_def_get_num_ant_config(struct ath_hw *ah,
2534 enum ieee80211_band freq_band) 2622 enum ieee80211_band freq_band)
2535{ 2623{
2536 struct ar5416_eeprom_def *eep = &ah->ah_eeprom.def; 2624 struct ar5416_eeprom_def *eep = &ah->ah_eeprom.def;
@@ -2548,24 +2636,21 @@ static u8 ath9k_hw_get_def_num_ant_config(struct ath_hw *ah,
2548 return num_ant_config; 2636 return num_ant_config;
2549} 2637}
2550 2638
2551static u8 (*ath9k_get_num_ant_config[])(struct ath_hw *, 2639static u16 ath9k_hw_def_get_eeprom_antenna_cfg(struct ath_hw *ah,
2552 enum ieee80211_band) = { 2640 struct ath9k_channel *chan)
2553 ath9k_hw_get_def_num_ant_config,
2554 ath9k_hw_get_4k_num_ant_config
2555};
2556
2557u8 ath9k_hw_get_num_ant_config(struct ath_hw *ah,
2558 enum ieee80211_band freq_band)
2559{ 2641{
2560 return ath9k_get_num_ant_config[ah->ah_eep_map](ah, freq_band); 2642 struct ar5416_eeprom_def *eep = &ah->ah_eeprom.def;
2643 struct modal_eep_header *pModal =
2644 &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
2645
2646 return pModal->antCtrlCommon & 0xFFFF;
2561} 2647}
2562 2648
2563u16 ath9k_hw_eeprom_get_spur_chan(struct ath_hw *ah, u16 i, bool is2GHz) 2649u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
2564{ 2650{
2565#define EEP_MAP4K_SPURCHAN \
2566 (ah->ah_eeprom.map4k.modalHeader.spurChans[i].spurChan)
2567#define EEP_DEF_SPURCHAN \ 2651#define EEP_DEF_SPURCHAN \
2568 (ah->ah_eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan) 2652 (ah->ah_eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan)
2653
2569 u16 spur_val = AR_NO_SPUR; 2654 u16 spur_val = AR_NO_SPUR;
2570 2655
2571 DPRINTF(ah->ah_sc, ATH_DBG_ANI, 2656 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
@@ -2581,142 +2666,45 @@ u16 ath9k_hw_eeprom_get_spur_chan(struct ath_hw *ah, u16 i, bool is2GHz)
2581 "Getting spur val from new loc. %d\n", spur_val); 2666 "Getting spur val from new loc. %d\n", spur_val);
2582 break; 2667 break;
2583 case SPUR_ENABLE_EEPROM: 2668 case SPUR_ENABLE_EEPROM:
2584 if (ah->ah_eep_map == EEP_MAP_4KBITS) 2669 spur_val = EEP_DEF_SPURCHAN;
2585 spur_val = EEP_MAP4K_SPURCHAN;
2586 else
2587 spur_val = EEP_DEF_SPURCHAN;
2588 break; 2670 break;
2589
2590 } 2671 }
2591 2672
2592 return spur_val; 2673 return spur_val;
2593#undef EEP_DEF_SPURCHAN
2594#undef EEP_MAP4K_SPURCHAN
2595}
2596
2597static u32 ath9k_hw_get_eeprom_4k(struct ath_hw *ah,
2598 enum eeprom_param param)
2599{
2600 struct ar5416_eeprom_4k *eep = &ah->ah_eeprom.map4k;
2601 struct modal_eep_4k_header *pModal = &eep->modalHeader;
2602 struct base_eep_header_4k *pBase = &eep->baseEepHeader;
2603
2604 switch (param) {
2605 case EEP_NFTHRESH_2:
2606 return pModal[1].noiseFloorThreshCh[0];
2607 case AR_EEPROM_MAC(0):
2608 return pBase->macAddr[0] << 8 | pBase->macAddr[1];
2609 case AR_EEPROM_MAC(1):
2610 return pBase->macAddr[2] << 8 | pBase->macAddr[3];
2611 case AR_EEPROM_MAC(2):
2612 return pBase->macAddr[4] << 8 | pBase->macAddr[5];
2613 case EEP_REG_0:
2614 return pBase->regDmn[0];
2615 case EEP_REG_1:
2616 return pBase->regDmn[1];
2617 case EEP_OP_CAP:
2618 return pBase->deviceCap;
2619 case EEP_OP_MODE:
2620 return pBase->opCapFlags;
2621 case EEP_RF_SILENT:
2622 return pBase->rfSilent;
2623 case EEP_OB_2:
2624 return pModal->ob_01;
2625 case EEP_DB_2:
2626 return pModal->db1_01;
2627 case EEP_MINOR_REV:
2628 return pBase->version & AR5416_EEP_VER_MINOR_MASK;
2629 case EEP_TX_MASK:
2630 return pBase->txMask;
2631 case EEP_RX_MASK:
2632 return pBase->rxMask;
2633 default:
2634 return 0;
2635 }
2636}
2637 2674
2638static u32 ath9k_hw_get_eeprom_def(struct ath_hw *ah, 2675#undef EEP_DEF_SPURCHAN
2639 enum eeprom_param param)
2640{
2641#define AR5416_VER_MASK (pBase->version & AR5416_EEP_VER_MINOR_MASK)
2642 struct ar5416_eeprom_def *eep = &ah->ah_eeprom.def;
2643 struct modal_eep_header *pModal = eep->modalHeader;
2644 struct base_eep_header *pBase = &eep->baseEepHeader;
2645
2646 switch (param) {
2647 case EEP_NFTHRESH_5:
2648 return pModal[0].noiseFloorThreshCh[0];
2649 case EEP_NFTHRESH_2:
2650 return pModal[1].noiseFloorThreshCh[0];
2651 case AR_EEPROM_MAC(0):
2652 return pBase->macAddr[0] << 8 | pBase->macAddr[1];
2653 case AR_EEPROM_MAC(1):
2654 return pBase->macAddr[2] << 8 | pBase->macAddr[3];
2655 case AR_EEPROM_MAC(2):
2656 return pBase->macAddr[4] << 8 | pBase->macAddr[5];
2657 case EEP_REG_0:
2658 return pBase->regDmn[0];
2659 case EEP_REG_1:
2660 return pBase->regDmn[1];
2661 case EEP_OP_CAP:
2662 return pBase->deviceCap;
2663 case EEP_OP_MODE:
2664 return pBase->opCapFlags;
2665 case EEP_RF_SILENT:
2666 return pBase->rfSilent;
2667 case EEP_OB_5:
2668 return pModal[0].ob;
2669 case EEP_DB_5:
2670 return pModal[0].db;
2671 case EEP_OB_2:
2672 return pModal[1].ob;
2673 case EEP_DB_2:
2674 return pModal[1].db;
2675 case EEP_MINOR_REV:
2676 return AR5416_VER_MASK;
2677 case EEP_TX_MASK:
2678 return pBase->txMask;
2679 case EEP_RX_MASK:
2680 return pBase->rxMask;
2681 case EEP_RXGAIN_TYPE:
2682 return pBase->rxGainType;
2683 case EEP_TXGAIN_TYPE:
2684 return pBase->txGainType;
2685 case EEP_DAC_HPWR_5G:
2686 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20)
2687 return pBase->dacHiPwrMode_5G;
2688 else
2689 return 0;
2690 default:
2691 return 0;
2692 }
2693#undef AR5416_VER_MASK
2694} 2676}
2695 2677
2696static u32 (*ath9k_get_eeprom[])(struct ath_hw *, enum eeprom_param) = { 2678struct eeprom_ops eep_def_ops = {
2697 ath9k_hw_get_eeprom_def, 2679 .check_eeprom = ath9k_hw_def_check_eeprom,
2698 ath9k_hw_get_eeprom_4k 2680 .get_eeprom = ath9k_hw_def_get_eeprom,
2681 .fill_eeprom = ath9k_hw_def_fill_eeprom,
2682 .get_eeprom_ver = ath9k_hw_def_get_eeprom_ver,
2683 .get_eeprom_rev = ath9k_hw_def_get_eeprom_rev,
2684 .get_num_ant_config = ath9k_hw_def_get_num_ant_config,
2685 .get_eeprom_antenna_cfg = ath9k_hw_def_get_eeprom_antenna_cfg,
2686 .set_board_values = ath9k_hw_def_set_board_values,
2687 .set_addac = ath9k_hw_def_set_addac,
2688 .set_txpower = ath9k_hw_def_set_txpower,
2689 .get_spur_channel = ath9k_hw_def_get_spur_channel
2699}; 2690};
2700 2691
2701u32 ath9k_hw_get_eeprom(struct ath_hw *ah,
2702 enum eeprom_param param)
2703{
2704 return ath9k_get_eeprom[ah->ah_eep_map](ah, param);
2705}
2706
2707int ath9k_hw_eeprom_attach(struct ath_hw *ah) 2692int ath9k_hw_eeprom_attach(struct ath_hw *ah)
2708{ 2693{
2709 int status; 2694 int status;
2710 2695
2711 if (AR_SREV_9285(ah)) 2696 if (AR_SREV_9285(ah)) {
2712 ah->ah_eep_map = EEP_MAP_4KBITS; 2697 ah->ah_eep_map = EEP_MAP_4KBITS;
2713 else 2698 ah->eep_ops = &eep_4k_ops;
2699 } else {
2714 ah->ah_eep_map = EEP_MAP_DEFAULT; 2700 ah->ah_eep_map = EEP_MAP_DEFAULT;
2701 ah->eep_ops = &eep_def_ops;
2702 }
2715 2703
2716 if (!ath9k_hw_fill_eeprom(ah)) 2704 if (!ah->eep_ops->fill_eeprom(ah))
2717 return -EIO; 2705 return -EIO;
2718 2706
2719 status = ath9k_hw_check_eeprom(ah); 2707 status = ah->eep_ops->check_eeprom(ah);
2720 2708
2721 return status; 2709 return status;
2722} 2710}