2 * Copyright (c) 2008 Atheros Communications Inc.
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 static void ath9k_hw_analog_shift_rmw(struct ath_hal
*ah
,
28 regVal
= REG_READ(ah
, reg
) & ~mask
;
29 regVal
|= (val
<< shift
) & mask
;
31 REG_WRITE(ah
, reg
, regVal
);
33 if (ah
->ah_config
.analog_shiftreg
)
39 static inline u16
ath9k_hw_fbin2freq(u8 fbin
, bool is2GHz
)
42 if (fbin
== AR5416_BCHAN_UNUSED
)
45 return (u16
) ((is2GHz
) ? (2300 + fbin
) : (4800 + 5 * fbin
));
48 static inline int16_t ath9k_hw_interpolate(u16 target
,
49 u16 srcLeft
, u16 srcRight
,
55 if (srcRight
== srcLeft
) {
58 rv
= (int16_t) (((target
- srcLeft
) * targetRight
+
59 (srcRight
- target
) * targetLeft
) /
60 (srcRight
- srcLeft
));
65 static inline bool ath9k_hw_get_lower_upper_index(u8 target
, u8
*pList
,
66 u16 listSize
, u16
*indexL
,
71 if (target
<= pList
[0]) {
72 *indexL
= *indexR
= 0;
75 if (target
>= pList
[listSize
- 1]) {
76 *indexL
= *indexR
= (u16
) (listSize
- 1);
80 for (i
= 0; i
< listSize
- 1; i
++) {
81 if (pList
[i
] == target
) {
82 *indexL
= *indexR
= i
;
85 if (target
< pList
[i
+ 1]) {
87 *indexR
= (u16
) (i
+ 1);
94 static bool ath9k_hw_eeprom_read(struct ath_hal
*ah
, u32 off
, u16
*data
)
96 (void)REG_READ(ah
, AR5416_EEPROM_OFFSET
+ (off
<< AR5416_EEPROM_S
));
98 if (!ath9k_hw_wait(ah
,
99 AR_EEPROM_STATUS_DATA
,
100 AR_EEPROM_STATUS_DATA_BUSY
|
101 AR_EEPROM_STATUS_DATA_PROT_ACCESS
, 0)) {
105 *data
= MS(REG_READ(ah
, AR_EEPROM_STATUS_DATA
),
106 AR_EEPROM_STATUS_DATA_VAL
);
111 static int ath9k_hw_flash_map(struct ath_hal
*ah
)
113 struct ath_hal_5416
*ahp
= AH5416(ah
);
115 ahp
->ah_cal_mem
= ioremap(AR5416_EEPROM_START_ADDR
, AR5416_EEPROM_MAX
);
117 if (!ahp
->ah_cal_mem
) {
118 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
119 "cannot remap eeprom region \n");
126 static bool ath9k_hw_flash_read(struct ath_hal
*ah
, u32 off
, u16
*data
)
128 struct ath_hal_5416
*ahp
= AH5416(ah
);
130 *data
= ioread16(ahp
->ah_cal_mem
+ off
);
135 static inline bool ath9k_hw_nvram_read(struct ath_hal
*ah
, u32 off
, u16
*data
)
137 if (ath9k_hw_use_flash(ah
))
138 return ath9k_hw_flash_read(ah
, off
, data
);
140 return ath9k_hw_eeprom_read(ah
, off
, data
);
143 static bool ath9k_hw_fill_4k_eeprom(struct ath_hal
*ah
)
145 #define SIZE_EEPROM_4K (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
146 struct ath_hal_5416
*ahp
= AH5416(ah
);
147 struct ar5416_eeprom_4k
*eep
= &ahp
->ah_eeprom
.map4k
;
149 int addr
, eep_start_loc
= 0;
153 if (!ath9k_hw_use_flash(ah
)) {
154 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
155 "Reading from EEPROM, not flash\n");
158 eep_data
= (u16
*)eep
;
160 for (addr
= 0; addr
< SIZE_EEPROM_4K
; addr
++) {
161 if (!ath9k_hw_nvram_read(ah
, addr
+ eep_start_loc
, eep_data
)) {
162 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
163 "Unable to read eeprom region \n");
169 #undef SIZE_EEPROM_4K
172 static bool ath9k_hw_fill_def_eeprom(struct ath_hal
*ah
)
174 #define SIZE_EEPROM_DEF (sizeof(struct ar5416_eeprom_def) / sizeof(u16))
175 struct ath_hal_5416
*ahp
= AH5416(ah
);
176 struct ar5416_eeprom_def
*eep
= &ahp
->ah_eeprom
.def
;
178 int addr
, ar5416_eep_start_loc
= 0x100;
180 eep_data
= (u16
*)eep
;
182 for (addr
= 0; addr
< SIZE_EEPROM_DEF
; addr
++) {
183 if (!ath9k_hw_nvram_read(ah
, addr
+ ar5416_eep_start_loc
,
185 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
186 "Unable to read eeprom region\n");
192 #undef SIZE_EEPROM_DEF
195 static bool (*ath9k_fill_eeprom
[]) (struct ath_hal
*) = {
196 ath9k_hw_fill_def_eeprom
,
197 ath9k_hw_fill_4k_eeprom
200 static inline bool ath9k_hw_fill_eeprom(struct ath_hal
*ah
)
202 struct ath_hal_5416
*ahp
= AH5416(ah
);
204 return ath9k_fill_eeprom
[ahp
->ah_eep_map
](ah
);
207 static int ath9k_hw_check_def_eeprom(struct ath_hal
*ah
)
209 struct ath_hal_5416
*ahp
= AH5416(ah
);
210 struct ar5416_eeprom_def
*eep
=
211 (struct ar5416_eeprom_def
*) &ahp
->ah_eeprom
.def
;
212 u16
*eepdata
, temp
, magic
, magic2
;
214 bool need_swap
= false;
217 if (!ath9k_hw_nvram_read(ah
, AR5416_EEPROM_MAGIC_OFFSET
,
219 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
220 "Reading Magic # failed\n");
224 if (!ath9k_hw_use_flash(ah
)) {
226 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
227 "Read Magic = 0x%04X\n", magic
);
229 if (magic
!= AR5416_EEPROM_MAGIC
) {
230 magic2
= swab16(magic
);
232 if (magic2
== AR5416_EEPROM_MAGIC
) {
233 size
= sizeof(struct ar5416_eeprom_def
);
235 eepdata
= (u16
*) (&ahp
->ah_eeprom
);
237 for (addr
= 0; addr
< size
/ sizeof(u16
); addr
++) {
238 temp
= swab16(*eepdata
);
242 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
243 "0x%04X ", *eepdata
);
245 if (((addr
+ 1) % 6) == 0)
247 ATH_DBG_EEPROM
, "\n");
250 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
251 "Invalid EEPROM Magic. "
252 "endianness mismatch.\n");
258 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
, "need_swap = %s.\n",
259 need_swap
? "True" : "False");
262 el
= swab16(ahp
->ah_eeprom
.def
.baseEepHeader
.length
);
264 el
= ahp
->ah_eeprom
.def
.baseEepHeader
.length
;
266 if (el
> sizeof(struct ar5416_eeprom_def
))
267 el
= sizeof(struct ar5416_eeprom_def
) / sizeof(u16
);
269 el
= el
/ sizeof(u16
);
271 eepdata
= (u16
*)(&ahp
->ah_eeprom
);
273 for (i
= 0; i
< el
; i
++)
280 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
281 "EEPROM Endianness is not native.. Changing \n");
283 word
= swab16(eep
->baseEepHeader
.length
);
284 eep
->baseEepHeader
.length
= word
;
286 word
= swab16(eep
->baseEepHeader
.checksum
);
287 eep
->baseEepHeader
.checksum
= word
;
289 word
= swab16(eep
->baseEepHeader
.version
);
290 eep
->baseEepHeader
.version
= word
;
292 word
= swab16(eep
->baseEepHeader
.regDmn
[0]);
293 eep
->baseEepHeader
.regDmn
[0] = word
;
295 word
= swab16(eep
->baseEepHeader
.regDmn
[1]);
296 eep
->baseEepHeader
.regDmn
[1] = word
;
298 word
= swab16(eep
->baseEepHeader
.rfSilent
);
299 eep
->baseEepHeader
.rfSilent
= word
;
301 word
= swab16(eep
->baseEepHeader
.blueToothOptions
);
302 eep
->baseEepHeader
.blueToothOptions
= word
;
304 word
= swab16(eep
->baseEepHeader
.deviceCap
);
305 eep
->baseEepHeader
.deviceCap
= word
;
307 for (j
= 0; j
< ARRAY_SIZE(eep
->modalHeader
); j
++) {
308 struct modal_eep_header
*pModal
=
309 &eep
->modalHeader
[j
];
310 integer
= swab32(pModal
->antCtrlCommon
);
311 pModal
->antCtrlCommon
= integer
;
313 for (i
= 0; i
< AR5416_MAX_CHAINS
; i
++) {
314 integer
= swab32(pModal
->antCtrlChain
[i
]);
315 pModal
->antCtrlChain
[i
] = integer
;
318 for (i
= 0; i
< AR5416_EEPROM_MODAL_SPURS
; i
++) {
319 word
= swab16(pModal
->spurChans
[i
].spurChan
);
320 pModal
->spurChans
[i
].spurChan
= word
;
325 if (sum
!= 0xffff || ar5416_get_eep_ver(ahp
) != AR5416_EEP_VER
||
326 ar5416_get_eep_rev(ahp
) < AR5416_EEP_NO_BACK_VER
) {
327 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
328 "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
329 sum
, ar5416_get_eep_ver(ahp
));
336 static int ath9k_hw_check_4k_eeprom(struct ath_hal
*ah
)
338 #define EEPROM_4K_SIZE (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
339 struct ath_hal_5416
*ahp
= AH5416(ah
);
340 struct ar5416_eeprom_4k
*eep
=
341 (struct ar5416_eeprom_4k
*) &ahp
->ah_eeprom
.map4k
;
342 u16
*eepdata
, temp
, magic
, magic2
;
344 bool need_swap
= false;
348 if (!ath9k_hw_use_flash(ah
)) {
350 if (!ath9k_hw_nvram_read(ah
, AR5416_EEPROM_MAGIC_OFFSET
,
352 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
353 "Reading Magic # failed\n");
357 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
358 "Read Magic = 0x%04X\n", magic
);
360 if (magic
!= AR5416_EEPROM_MAGIC
) {
361 magic2
= swab16(magic
);
363 if (magic2
== AR5416_EEPROM_MAGIC
) {
365 eepdata
= (u16
*) (&ahp
->ah_eeprom
);
367 for (addr
= 0; addr
< EEPROM_4K_SIZE
; addr
++) {
368 temp
= swab16(*eepdata
);
372 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
373 "0x%04X ", *eepdata
);
375 if (((addr
+ 1) % 6) == 0)
377 ATH_DBG_EEPROM
, "\n");
380 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
381 "Invalid EEPROM Magic. "
382 "endianness mismatch.\n");
388 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
, "need_swap = %s.\n",
389 need_swap
? "True" : "False");
392 el
= swab16(ahp
->ah_eeprom
.map4k
.baseEepHeader
.length
);
394 el
= ahp
->ah_eeprom
.map4k
.baseEepHeader
.length
;
396 if (el
> sizeof(struct ar5416_eeprom_def
))
397 el
= sizeof(struct ar5416_eeprom_4k
) / sizeof(u16
);
399 el
= el
/ sizeof(u16
);
401 eepdata
= (u16
*)(&ahp
->ah_eeprom
);
403 for (i
= 0; i
< el
; i
++)
410 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
411 "EEPROM Endianness is not native.. Changing \n");
413 word
= swab16(eep
->baseEepHeader
.length
);
414 eep
->baseEepHeader
.length
= word
;
416 word
= swab16(eep
->baseEepHeader
.checksum
);
417 eep
->baseEepHeader
.checksum
= word
;
419 word
= swab16(eep
->baseEepHeader
.version
);
420 eep
->baseEepHeader
.version
= word
;
422 word
= swab16(eep
->baseEepHeader
.regDmn
[0]);
423 eep
->baseEepHeader
.regDmn
[0] = word
;
425 word
= swab16(eep
->baseEepHeader
.regDmn
[1]);
426 eep
->baseEepHeader
.regDmn
[1] = word
;
428 word
= swab16(eep
->baseEepHeader
.rfSilent
);
429 eep
->baseEepHeader
.rfSilent
= word
;
431 word
= swab16(eep
->baseEepHeader
.blueToothOptions
);
432 eep
->baseEepHeader
.blueToothOptions
= word
;
434 word
= swab16(eep
->baseEepHeader
.deviceCap
);
435 eep
->baseEepHeader
.deviceCap
= word
;
437 integer
= swab32(eep
->modalHeader
.antCtrlCommon
);
438 eep
->modalHeader
.antCtrlCommon
= integer
;
440 for (i
= 0; i
< AR5416_MAX_CHAINS
; i
++) {
441 integer
= swab32(eep
->modalHeader
.antCtrlChain
[i
]);
442 eep
->modalHeader
.antCtrlChain
[i
] = integer
;
445 for (i
= 0; i
< AR5416_EEPROM_MODAL_SPURS
; i
++) {
446 word
= swab16(eep
->modalHeader
.spurChans
[i
].spurChan
);
447 eep
->modalHeader
.spurChans
[i
].spurChan
= word
;
451 if (sum
!= 0xffff || ar5416_get_eep4k_ver(ahp
) != AR5416_EEP_VER
||
452 ar5416_get_eep4k_rev(ahp
) < AR5416_EEP_NO_BACK_VER
) {
453 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
454 "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
455 sum
, ar5416_get_eep4k_ver(ahp
));
460 #undef EEPROM_4K_SIZE
463 static int (*ath9k_check_eeprom
[]) (struct ath_hal
*) = {
464 ath9k_hw_check_def_eeprom
,
465 ath9k_hw_check_4k_eeprom
468 static inline int ath9k_hw_check_eeprom(struct ath_hal
*ah
)
470 struct ath_hal_5416
*ahp
= AH5416(ah
);
472 return ath9k_check_eeprom
[ahp
->ah_eep_map
](ah
);
475 static inline bool ath9k_hw_fill_vpd_table(u8 pwrMin
, u8 pwrMax
, u8
*pPwrList
,
476 u8
*pVpdList
, u16 numIntercepts
,
481 u16 idxL
= 0, idxR
= 0;
483 for (i
= 0; i
<= (pwrMax
- pwrMin
) / 2; i
++) {
484 ath9k_hw_get_lower_upper_index(currPwr
, pPwrList
,
485 numIntercepts
, &(idxL
),
489 if (idxL
== numIntercepts
- 1)
490 idxL
= (u16
) (numIntercepts
- 2);
491 if (pPwrList
[idxL
] == pPwrList
[idxR
])
494 k
= (u16
)(((currPwr
- pPwrList
[idxL
]) * pVpdList
[idxR
] +
495 (pPwrList
[idxR
] - currPwr
) * pVpdList
[idxL
]) /
496 (pPwrList
[idxR
] - pPwrList
[idxL
]));
497 pRetVpdList
[i
] = (u8
) k
;
504 static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hal
*ah
,
505 struct ath9k_channel
*chan
,
506 struct cal_data_per_freq_4k
*pRawDataSet
,
507 u8
*bChans
, u16 availPiers
,
508 u16 tPdGainOverlap
, int16_t *pMinCalPower
,
509 u16
*pPdGainBoundaries
, u8
*pPDADCValues
,
512 #define TMP_VAL_VPD_TABLE \
513 ((vpdTableI[i][sizeCurrVpdTable - 1] + (ss - maxIndex + 1) * vpdStep));
516 u16 idxL
= 0, idxR
= 0, numPiers
;
517 static u8 vpdTableL
[AR5416_EEP4K_NUM_PD_GAINS
]
518 [AR5416_MAX_PWR_RANGE_IN_HALF_DB
];
519 static u8 vpdTableR
[AR5416_EEP4K_NUM_PD_GAINS
]
520 [AR5416_MAX_PWR_RANGE_IN_HALF_DB
];
521 static u8 vpdTableI
[AR5416_EEP4K_NUM_PD_GAINS
]
522 [AR5416_MAX_PWR_RANGE_IN_HALF_DB
];
524 u8
*pVpdL
, *pVpdR
, *pPwrL
, *pPwrR
;
525 u8 minPwrT4
[AR5416_EEP4K_NUM_PD_GAINS
];
526 u8 maxPwrT4
[AR5416_EEP4K_NUM_PD_GAINS
];
529 u16 sizeCurrVpdTable
, maxIndex
, tgtIndex
;
531 int16_t minDelta
= 0;
532 struct chan_centers centers
;
533 #define PD_GAIN_BOUNDARY_DEFAULT 58;
535 ath9k_hw_get_channel_centers(ah
, chan
, ¢ers
);
537 for (numPiers
= 0; numPiers
< availPiers
; numPiers
++) {
538 if (bChans
[numPiers
] == AR5416_BCHAN_UNUSED
)
542 match
= ath9k_hw_get_lower_upper_index(
543 (u8
)FREQ2FBIN(centers
.synth_center
,
544 IS_CHAN_2GHZ(chan
)), bChans
, numPiers
,
548 for (i
= 0; i
< numXpdGains
; i
++) {
549 minPwrT4
[i
] = pRawDataSet
[idxL
].pwrPdg
[i
][0];
550 maxPwrT4
[i
] = pRawDataSet
[idxL
].pwrPdg
[i
][4];
551 ath9k_hw_fill_vpd_table(minPwrT4
[i
], maxPwrT4
[i
],
552 pRawDataSet
[idxL
].pwrPdg
[i
],
553 pRawDataSet
[idxL
].vpdPdg
[i
],
554 AR5416_EEP4K_PD_GAIN_ICEPTS
,
558 for (i
= 0; i
< numXpdGains
; i
++) {
559 pVpdL
= pRawDataSet
[idxL
].vpdPdg
[i
];
560 pPwrL
= pRawDataSet
[idxL
].pwrPdg
[i
];
561 pVpdR
= pRawDataSet
[idxR
].vpdPdg
[i
];
562 pPwrR
= pRawDataSet
[idxR
].pwrPdg
[i
];
564 minPwrT4
[i
] = max(pPwrL
[0], pPwrR
[0]);
567 min(pPwrL
[AR5416_EEP4K_PD_GAIN_ICEPTS
- 1],
568 pPwrR
[AR5416_EEP4K_PD_GAIN_ICEPTS
- 1]);
571 ath9k_hw_fill_vpd_table(minPwrT4
[i
], maxPwrT4
[i
],
573 AR5416_EEP4K_PD_GAIN_ICEPTS
,
575 ath9k_hw_fill_vpd_table(minPwrT4
[i
], maxPwrT4
[i
],
577 AR5416_EEP4K_PD_GAIN_ICEPTS
,
580 for (j
= 0; j
<= (maxPwrT4
[i
] - minPwrT4
[i
]) / 2; j
++) {
582 (u8
)(ath9k_hw_interpolate((u16
)
587 bChans
[idxL
], bChans
[idxR
],
588 vpdTableL
[i
][j
], vpdTableR
[i
][j
]));
593 *pMinCalPower
= (int16_t)(minPwrT4
[0] / 2);
597 for (i
= 0; i
< numXpdGains
; i
++) {
598 if (i
== (numXpdGains
- 1))
599 pPdGainBoundaries
[i
] =
600 (u16
)(maxPwrT4
[i
] / 2);
602 pPdGainBoundaries
[i
] =
603 (u16
)((maxPwrT4
[i
] + minPwrT4
[i
+ 1]) / 4);
605 pPdGainBoundaries
[i
] =
606 min((u16
)AR5416_MAX_RATE_POWER
, pPdGainBoundaries
[i
]);
608 if ((i
== 0) && !AR_SREV_5416_V20_OR_LATER(ah
)) {
609 minDelta
= pPdGainBoundaries
[0] - 23;
610 pPdGainBoundaries
[0] = 23;
616 if (AR_SREV_9280_10_OR_LATER(ah
))
617 ss
= (int16_t)(0 - (minPwrT4
[i
] / 2));
621 ss
= (int16_t)((pPdGainBoundaries
[i
- 1] -
623 tPdGainOverlap
+ 1 + minDelta
);
625 vpdStep
= (int16_t)(vpdTableI
[i
][1] - vpdTableI
[i
][0]);
626 vpdStep
= (int16_t)((vpdStep
< 1) ? 1 : vpdStep
);
628 while ((ss
< 0) && (k
< (AR5416_NUM_PDADC_VALUES
- 1))) {
629 tmpVal
= (int16_t)(vpdTableI
[i
][0] + ss
* vpdStep
);
630 pPDADCValues
[k
++] = (u8
)((tmpVal
< 0) ? 0 : tmpVal
);
634 sizeCurrVpdTable
= (u8
) ((maxPwrT4
[i
] - minPwrT4
[i
]) / 2 + 1);
635 tgtIndex
= (u8
)(pPdGainBoundaries
[i
] + tPdGainOverlap
-
637 maxIndex
= (tgtIndex
< sizeCurrVpdTable
) ?
638 tgtIndex
: sizeCurrVpdTable
;
640 while ((ss
< maxIndex
) && (k
< (AR5416_NUM_PDADC_VALUES
- 1)))
641 pPDADCValues
[k
++] = vpdTableI
[i
][ss
++];
643 vpdStep
= (int16_t)(vpdTableI
[i
][sizeCurrVpdTable
- 1] -
644 vpdTableI
[i
][sizeCurrVpdTable
- 2]);
645 vpdStep
= (int16_t)((vpdStep
< 1) ? 1 : vpdStep
);
647 if (tgtIndex
> maxIndex
) {
648 while ((ss
<= tgtIndex
) &&
649 (k
< (AR5416_NUM_PDADC_VALUES
- 1))) {
650 tmpVal
= (int16_t) TMP_VAL_VPD_TABLE
;
651 pPDADCValues
[k
++] = (u8
)((tmpVal
> 255) ?
658 while (i
< AR5416_EEP4K_PD_GAINS_IN_MASK
) {
659 pPdGainBoundaries
[i
] = PD_GAIN_BOUNDARY_DEFAULT
;
663 while (k
< AR5416_NUM_PDADC_VALUES
) {
664 pPDADCValues
[k
] = pPDADCValues
[k
- 1];
669 #undef TMP_VAL_VPD_TABLE
672 static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hal
*ah
,
673 struct ath9k_channel
*chan
,
674 struct cal_data_per_freq
*pRawDataSet
,
675 u8
*bChans
, u16 availPiers
,
676 u16 tPdGainOverlap
, int16_t *pMinCalPower
,
677 u16
*pPdGainBoundaries
, u8
*pPDADCValues
,
682 u16 idxL
= 0, idxR
= 0, numPiers
;
683 static u8 vpdTableL
[AR5416_NUM_PD_GAINS
]
684 [AR5416_MAX_PWR_RANGE_IN_HALF_DB
];
685 static u8 vpdTableR
[AR5416_NUM_PD_GAINS
]
686 [AR5416_MAX_PWR_RANGE_IN_HALF_DB
];
687 static u8 vpdTableI
[AR5416_NUM_PD_GAINS
]
688 [AR5416_MAX_PWR_RANGE_IN_HALF_DB
];
690 u8
*pVpdL
, *pVpdR
, *pPwrL
, *pPwrR
;
691 u8 minPwrT4
[AR5416_NUM_PD_GAINS
];
692 u8 maxPwrT4
[AR5416_NUM_PD_GAINS
];
695 u16 sizeCurrVpdTable
, maxIndex
, tgtIndex
;
697 int16_t minDelta
= 0;
698 struct chan_centers centers
;
700 ath9k_hw_get_channel_centers(ah
, chan
, ¢ers
);
702 for (numPiers
= 0; numPiers
< availPiers
; numPiers
++) {
703 if (bChans
[numPiers
] == AR5416_BCHAN_UNUSED
)
707 match
= ath9k_hw_get_lower_upper_index((u8
)FREQ2FBIN(centers
.synth_center
,
709 bChans
, numPiers
, &idxL
, &idxR
);
712 for (i
= 0; i
< numXpdGains
; i
++) {
713 minPwrT4
[i
] = pRawDataSet
[idxL
].pwrPdg
[i
][0];
714 maxPwrT4
[i
] = pRawDataSet
[idxL
].pwrPdg
[i
][4];
715 ath9k_hw_fill_vpd_table(minPwrT4
[i
], maxPwrT4
[i
],
716 pRawDataSet
[idxL
].pwrPdg
[i
],
717 pRawDataSet
[idxL
].vpdPdg
[i
],
718 AR5416_PD_GAIN_ICEPTS
,
722 for (i
= 0; i
< numXpdGains
; i
++) {
723 pVpdL
= pRawDataSet
[idxL
].vpdPdg
[i
];
724 pPwrL
= pRawDataSet
[idxL
].pwrPdg
[i
];
725 pVpdR
= pRawDataSet
[idxR
].vpdPdg
[i
];
726 pPwrR
= pRawDataSet
[idxR
].pwrPdg
[i
];
728 minPwrT4
[i
] = max(pPwrL
[0], pPwrR
[0]);
731 min(pPwrL
[AR5416_PD_GAIN_ICEPTS
- 1],
732 pPwrR
[AR5416_PD_GAIN_ICEPTS
- 1]);
735 ath9k_hw_fill_vpd_table(minPwrT4
[i
], maxPwrT4
[i
],
737 AR5416_PD_GAIN_ICEPTS
,
739 ath9k_hw_fill_vpd_table(minPwrT4
[i
], maxPwrT4
[i
],
741 AR5416_PD_GAIN_ICEPTS
,
744 for (j
= 0; j
<= (maxPwrT4
[i
] - minPwrT4
[i
]) / 2; j
++) {
746 (u8
)(ath9k_hw_interpolate((u16
)
751 bChans
[idxL
], bChans
[idxR
],
752 vpdTableL
[i
][j
], vpdTableR
[i
][j
]));
757 *pMinCalPower
= (int16_t)(minPwrT4
[0] / 2);
761 for (i
= 0; i
< numXpdGains
; i
++) {
762 if (i
== (numXpdGains
- 1))
763 pPdGainBoundaries
[i
] =
764 (u16
)(maxPwrT4
[i
] / 2);
766 pPdGainBoundaries
[i
] =
767 (u16
)((maxPwrT4
[i
] + minPwrT4
[i
+ 1]) / 4);
769 pPdGainBoundaries
[i
] =
770 min((u16
)AR5416_MAX_RATE_POWER
, pPdGainBoundaries
[i
]);
772 if ((i
== 0) && !AR_SREV_5416_V20_OR_LATER(ah
)) {
773 minDelta
= pPdGainBoundaries
[0] - 23;
774 pPdGainBoundaries
[0] = 23;
780 if (AR_SREV_9280_10_OR_LATER(ah
))
781 ss
= (int16_t)(0 - (minPwrT4
[i
] / 2));
785 ss
= (int16_t)((pPdGainBoundaries
[i
- 1] -
787 tPdGainOverlap
+ 1 + minDelta
);
789 vpdStep
= (int16_t)(vpdTableI
[i
][1] - vpdTableI
[i
][0]);
790 vpdStep
= (int16_t)((vpdStep
< 1) ? 1 : vpdStep
);
792 while ((ss
< 0) && (k
< (AR5416_NUM_PDADC_VALUES
- 1))) {
793 tmpVal
= (int16_t)(vpdTableI
[i
][0] + ss
* vpdStep
);
794 pPDADCValues
[k
++] = (u8
)((tmpVal
< 0) ? 0 : tmpVal
);
798 sizeCurrVpdTable
= (u8
) ((maxPwrT4
[i
] - minPwrT4
[i
]) / 2 + 1);
799 tgtIndex
= (u8
)(pPdGainBoundaries
[i
] + tPdGainOverlap
-
801 maxIndex
= (tgtIndex
< sizeCurrVpdTable
) ?
802 tgtIndex
: sizeCurrVpdTable
;
804 while ((ss
< maxIndex
) && (k
< (AR5416_NUM_PDADC_VALUES
- 1))) {
805 pPDADCValues
[k
++] = vpdTableI
[i
][ss
++];
808 vpdStep
= (int16_t)(vpdTableI
[i
][sizeCurrVpdTable
- 1] -
809 vpdTableI
[i
][sizeCurrVpdTable
- 2]);
810 vpdStep
= (int16_t)((vpdStep
< 1) ? 1 : vpdStep
);
812 if (tgtIndex
> maxIndex
) {
813 while ((ss
<= tgtIndex
) &&
814 (k
< (AR5416_NUM_PDADC_VALUES
- 1))) {
815 tmpVal
= (int16_t)((vpdTableI
[i
][sizeCurrVpdTable
- 1] +
816 (ss
- maxIndex
+ 1) * vpdStep
));
817 pPDADCValues
[k
++] = (u8
)((tmpVal
> 255) ?
824 while (i
< AR5416_PD_GAINS_IN_MASK
) {
825 pPdGainBoundaries
[i
] = pPdGainBoundaries
[i
- 1];
829 while (k
< AR5416_NUM_PDADC_VALUES
) {
830 pPDADCValues
[k
] = pPDADCValues
[k
- 1];
837 static void ath9k_hw_get_legacy_target_powers(struct ath_hal
*ah
,
838 struct ath9k_channel
*chan
,
839 struct cal_target_power_leg
*powInfo
,
841 struct cal_target_power_leg
*pNewPower
,
842 u16 numRates
, bool isExtTarget
)
844 struct chan_centers centers
;
847 int matchIndex
= -1, lowIndex
= -1;
850 ath9k_hw_get_channel_centers(ah
, chan
, ¢ers
);
851 freq
= (isExtTarget
) ? centers
.ext_center
: centers
.ctl_center
;
853 if (freq
<= ath9k_hw_fbin2freq(powInfo
[0].bChannel
,
854 IS_CHAN_2GHZ(chan
))) {
857 for (i
= 0; (i
< numChannels
) &&
858 (powInfo
[i
].bChannel
!= AR5416_BCHAN_UNUSED
); i
++) {
859 if (freq
== ath9k_hw_fbin2freq(powInfo
[i
].bChannel
,
860 IS_CHAN_2GHZ(chan
))) {
863 } else if ((freq
< ath9k_hw_fbin2freq(powInfo
[i
].bChannel
,
864 IS_CHAN_2GHZ(chan
))) &&
865 (freq
> ath9k_hw_fbin2freq(powInfo
[i
- 1].bChannel
,
866 IS_CHAN_2GHZ(chan
)))) {
871 if ((matchIndex
== -1) && (lowIndex
== -1))
875 if (matchIndex
!= -1) {
876 *pNewPower
= powInfo
[matchIndex
];
878 clo
= ath9k_hw_fbin2freq(powInfo
[lowIndex
].bChannel
,
880 chi
= ath9k_hw_fbin2freq(powInfo
[lowIndex
+ 1].bChannel
,
883 for (i
= 0; i
< numRates
; i
++) {
884 pNewPower
->tPow2x
[i
] =
885 (u8
)ath9k_hw_interpolate(freq
, clo
, chi
,
886 powInfo
[lowIndex
].tPow2x
[i
],
887 powInfo
[lowIndex
+ 1].tPow2x
[i
]);
892 static void ath9k_hw_get_target_powers(struct ath_hal
*ah
,
893 struct ath9k_channel
*chan
,
894 struct cal_target_power_ht
*powInfo
,
896 struct cal_target_power_ht
*pNewPower
,
897 u16 numRates
, bool isHt40Target
)
899 struct chan_centers centers
;
902 int matchIndex
= -1, lowIndex
= -1;
905 ath9k_hw_get_channel_centers(ah
, chan
, ¢ers
);
906 freq
= isHt40Target
? centers
.synth_center
: centers
.ctl_center
;
908 if (freq
<= ath9k_hw_fbin2freq(powInfo
[0].bChannel
, IS_CHAN_2GHZ(chan
))) {
911 for (i
= 0; (i
< numChannels
) &&
912 (powInfo
[i
].bChannel
!= AR5416_BCHAN_UNUSED
); i
++) {
913 if (freq
== ath9k_hw_fbin2freq(powInfo
[i
].bChannel
,
914 IS_CHAN_2GHZ(chan
))) {
918 if ((freq
< ath9k_hw_fbin2freq(powInfo
[i
].bChannel
,
919 IS_CHAN_2GHZ(chan
))) &&
920 (freq
> ath9k_hw_fbin2freq(powInfo
[i
- 1].bChannel
,
921 IS_CHAN_2GHZ(chan
)))) {
926 if ((matchIndex
== -1) && (lowIndex
== -1))
930 if (matchIndex
!= -1) {
931 *pNewPower
= powInfo
[matchIndex
];
933 clo
= ath9k_hw_fbin2freq(powInfo
[lowIndex
].bChannel
,
935 chi
= ath9k_hw_fbin2freq(powInfo
[lowIndex
+ 1].bChannel
,
938 for (i
= 0; i
< numRates
; i
++) {
939 pNewPower
->tPow2x
[i
] = (u8
)ath9k_hw_interpolate(freq
,
941 powInfo
[lowIndex
].tPow2x
[i
],
942 powInfo
[lowIndex
+ 1].tPow2x
[i
]);
947 static u16
ath9k_hw_get_max_edge_power(u16 freq
,
948 struct cal_ctl_edges
*pRdEdgesPower
,
949 bool is2GHz
, int num_band_edges
)
951 u16 twiceMaxEdgePower
= AR5416_MAX_RATE_POWER
;
954 for (i
= 0; (i
< num_band_edges
) &&
955 (pRdEdgesPower
[i
].bChannel
!= AR5416_BCHAN_UNUSED
); i
++) {
956 if (freq
== ath9k_hw_fbin2freq(pRdEdgesPower
[i
].bChannel
, is2GHz
)) {
957 twiceMaxEdgePower
= pRdEdgesPower
[i
].tPower
;
959 } else if ((i
> 0) &&
960 (freq
< ath9k_hw_fbin2freq(pRdEdgesPower
[i
].bChannel
,
962 if (ath9k_hw_fbin2freq(pRdEdgesPower
[i
- 1].bChannel
,
964 pRdEdgesPower
[i
- 1].flag
) {
966 pRdEdgesPower
[i
- 1].tPower
;
972 return twiceMaxEdgePower
;
975 static bool ath9k_hw_set_def_power_cal_table(struct ath_hal
*ah
,
976 struct ath9k_channel
*chan
,
977 int16_t *pTxPowerIndexOffset
)
979 struct ath_hal_5416
*ahp
= AH5416(ah
);
980 struct ar5416_eeprom_def
*pEepData
= &ahp
->ah_eeprom
.def
;
981 struct cal_data_per_freq
*pRawDataset
;
982 u8
*pCalBChans
= NULL
;
983 u16 pdGainOverlap_t2
;
984 static u8 pdadcValues
[AR5416_NUM_PDADC_VALUES
];
985 u16 gainBoundaries
[AR5416_PD_GAINS_IN_MASK
];
987 int16_t tMinCalPower
;
988 u16 numXpdGain
, xpdMask
;
989 u16 xpdGainValues
[AR5416_NUM_PD_GAINS
] = { 0, 0, 0, 0 };
990 u32 reg32
, regOffset
, regChainOffset
;
993 modalIdx
= IS_CHAN_2GHZ(chan
) ? 1 : 0;
994 xpdMask
= pEepData
->modalHeader
[modalIdx
].xpdGain
;
996 if ((pEepData
->baseEepHeader
.version
& AR5416_EEP_VER_MINOR_MASK
) >=
997 AR5416_EEP_MINOR_VER_2
) {
999 pEepData
->modalHeader
[modalIdx
].pdGainOverlap
;
1001 pdGainOverlap_t2
= (u16
)(MS(REG_READ(ah
, AR_PHY_TPCRG5
),
1002 AR_PHY_TPCRG5_PD_GAIN_OVERLAP
));
1005 if (IS_CHAN_2GHZ(chan
)) {
1006 pCalBChans
= pEepData
->calFreqPier2G
;
1007 numPiers
= AR5416_NUM_2G_CAL_PIERS
;
1009 pCalBChans
= pEepData
->calFreqPier5G
;
1010 numPiers
= AR5416_NUM_5G_CAL_PIERS
;
1015 for (i
= 1; i
<= AR5416_PD_GAINS_IN_MASK
; i
++) {
1016 if ((xpdMask
>> (AR5416_PD_GAINS_IN_MASK
- i
)) & 1) {
1017 if (numXpdGain
>= AR5416_NUM_PD_GAINS
)
1019 xpdGainValues
[numXpdGain
] =
1020 (u16
)(AR5416_PD_GAINS_IN_MASK
- i
);
1025 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_NUM_PD_GAIN
,
1026 (numXpdGain
- 1) & 0x3);
1027 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_PD_GAIN_1
,
1029 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_PD_GAIN_2
,
1031 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_PD_GAIN_3
,
1034 for (i
= 0; i
< AR5416_MAX_CHAINS
; i
++) {
1035 if (AR_SREV_5416_V20_OR_LATER(ah
) &&
1036 (ahp
->ah_rxchainmask
== 5 || ahp
->ah_txchainmask
== 5) &&
1038 regChainOffset
= (i
== 1) ? 0x2000 : 0x1000;
1040 regChainOffset
= i
* 0x1000;
1042 if (pEepData
->baseEepHeader
.txMask
& (1 << i
)) {
1043 if (IS_CHAN_2GHZ(chan
))
1044 pRawDataset
= pEepData
->calPierData2G
[i
];
1046 pRawDataset
= pEepData
->calPierData5G
[i
];
1048 ath9k_hw_get_def_gain_boundaries_pdadcs(ah
, chan
,
1049 pRawDataset
, pCalBChans
,
1050 numPiers
, pdGainOverlap_t2
,
1051 &tMinCalPower
, gainBoundaries
,
1052 pdadcValues
, numXpdGain
);
1054 if ((i
== 0) || AR_SREV_5416_V20_OR_LATER(ah
)) {
1056 AR_PHY_TPCRG5
+ regChainOffset
,
1057 SM(pdGainOverlap_t2
,
1058 AR_PHY_TPCRG5_PD_GAIN_OVERLAP
)
1059 | SM(gainBoundaries
[0],
1060 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1
)
1061 | SM(gainBoundaries
[1],
1062 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2
)
1063 | SM(gainBoundaries
[2],
1064 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3
)
1065 | SM(gainBoundaries
[3],
1066 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4
));
1069 regOffset
= AR_PHY_BASE
+ (672 << 2) + regChainOffset
;
1070 for (j
= 0; j
< 32; j
++) {
1071 reg32
= ((pdadcValues
[4 * j
+ 0] & 0xFF) << 0) |
1072 ((pdadcValues
[4 * j
+ 1] & 0xFF) << 8) |
1073 ((pdadcValues
[4 * j
+ 2] & 0xFF) << 16)|
1074 ((pdadcValues
[4 * j
+ 3] & 0xFF) << 24);
1075 REG_WRITE(ah
, regOffset
, reg32
);
1077 DPRINTF(ah
->ah_sc
, ATH_DBG_REG_IO
,
1078 "PDADC (%d,%4x): %4.4x %8.8x\n",
1079 i
, regChainOffset
, regOffset
,
1081 DPRINTF(ah
->ah_sc
, ATH_DBG_REG_IO
,
1082 "PDADC: Chain %d | PDADC %3d "
1083 "Value %3d | PDADC %3d Value %3d | "
1084 "PDADC %3d Value %3d | PDADC %3d "
1086 i
, 4 * j
, pdadcValues
[4 * j
],
1087 4 * j
+ 1, pdadcValues
[4 * j
+ 1],
1088 4 * j
+ 2, pdadcValues
[4 * j
+ 2],
1090 pdadcValues
[4 * j
+ 3]);
1097 *pTxPowerIndexOffset
= 0;
1102 static bool ath9k_hw_set_4k_power_cal_table(struct ath_hal
*ah
,
1103 struct ath9k_channel
*chan
,
1104 int16_t *pTxPowerIndexOffset
)
1106 struct ath_hal_5416
*ahp
= AH5416(ah
);
1107 struct ar5416_eeprom_4k
*pEepData
= &ahp
->ah_eeprom
.map4k
;
1108 struct cal_data_per_freq_4k
*pRawDataset
;
1109 u8
*pCalBChans
= NULL
;
1110 u16 pdGainOverlap_t2
;
1111 static u8 pdadcValues
[AR5416_NUM_PDADC_VALUES
];
1112 u16 gainBoundaries
[AR5416_PD_GAINS_IN_MASK
];
1114 int16_t tMinCalPower
;
1115 u16 numXpdGain
, xpdMask
;
1116 u16 xpdGainValues
[AR5416_NUM_PD_GAINS
] = { 0, 0, 0, 0 };
1117 u32 reg32
, regOffset
, regChainOffset
;
1119 xpdMask
= pEepData
->modalHeader
.xpdGain
;
1121 if ((pEepData
->baseEepHeader
.version
& AR5416_EEP_VER_MINOR_MASK
) >=
1122 AR5416_EEP_MINOR_VER_2
) {
1124 pEepData
->modalHeader
.pdGainOverlap
;
1126 pdGainOverlap_t2
= (u16
)(MS(REG_READ(ah
, AR_PHY_TPCRG5
),
1127 AR_PHY_TPCRG5_PD_GAIN_OVERLAP
));
1130 pCalBChans
= pEepData
->calFreqPier2G
;
1131 numPiers
= AR5416_NUM_2G_CAL_PIERS
;
1135 for (i
= 1; i
<= AR5416_PD_GAINS_IN_MASK
; i
++) {
1136 if ((xpdMask
>> (AR5416_PD_GAINS_IN_MASK
- i
)) & 1) {
1137 if (numXpdGain
>= AR5416_NUM_PD_GAINS
)
1139 xpdGainValues
[numXpdGain
] =
1140 (u16
)(AR5416_PD_GAINS_IN_MASK
- i
);
1145 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_NUM_PD_GAIN
,
1146 (numXpdGain
- 1) & 0x3);
1147 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_PD_GAIN_1
,
1149 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_PD_GAIN_2
,
1151 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_PD_GAIN_3
,
1154 for (i
= 0; i
< AR5416_MAX_CHAINS
; i
++) {
1155 if (AR_SREV_5416_V20_OR_LATER(ah
) &&
1156 (ahp
->ah_rxchainmask
== 5 || ahp
->ah_txchainmask
== 5) &&
1158 regChainOffset
= (i
== 1) ? 0x2000 : 0x1000;
1160 regChainOffset
= i
* 0x1000;
1162 if (pEepData
->baseEepHeader
.txMask
& (1 << i
)) {
1163 pRawDataset
= pEepData
->calPierData2G
[i
];
1165 ath9k_hw_get_4k_gain_boundaries_pdadcs(ah
, chan
,
1166 pRawDataset
, pCalBChans
,
1167 numPiers
, pdGainOverlap_t2
,
1168 &tMinCalPower
, gainBoundaries
,
1169 pdadcValues
, numXpdGain
);
1171 if ((i
== 0) || AR_SREV_5416_V20_OR_LATER(ah
)) {
1172 REG_WRITE(ah
, AR_PHY_TPCRG5
+ regChainOffset
,
1173 SM(pdGainOverlap_t2
,
1174 AR_PHY_TPCRG5_PD_GAIN_OVERLAP
)
1175 | SM(gainBoundaries
[0],
1176 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1
)
1177 | SM(gainBoundaries
[1],
1178 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2
)
1179 | SM(gainBoundaries
[2],
1180 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3
)
1181 | SM(gainBoundaries
[3],
1182 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4
));
1185 regOffset
= AR_PHY_BASE
+ (672 << 2) + regChainOffset
;
1186 for (j
= 0; j
< 32; j
++) {
1187 reg32
= ((pdadcValues
[4 * j
+ 0] & 0xFF) << 0) |
1188 ((pdadcValues
[4 * j
+ 1] & 0xFF) << 8) |
1189 ((pdadcValues
[4 * j
+ 2] & 0xFF) << 16)|
1190 ((pdadcValues
[4 * j
+ 3] & 0xFF) << 24);
1191 REG_WRITE(ah
, regOffset
, reg32
);
1193 DPRINTF(ah
->ah_sc
, ATH_DBG_REG_IO
,
1194 "PDADC (%d,%4x): %4.4x %8.8x\n",
1195 i
, regChainOffset
, regOffset
,
1197 DPRINTF(ah
->ah_sc
, ATH_DBG_REG_IO
,
1198 "PDADC: Chain %d | "
1199 "PDADC %3d Value %3d | "
1200 "PDADC %3d Value %3d | "
1201 "PDADC %3d Value %3d | "
1202 "PDADC %3d Value %3d |\n",
1203 i
, 4 * j
, pdadcValues
[4 * j
],
1204 4 * j
+ 1, pdadcValues
[4 * j
+ 1],
1205 4 * j
+ 2, pdadcValues
[4 * j
+ 2],
1207 pdadcValues
[4 * j
+ 3]);
1214 *pTxPowerIndexOffset
= 0;
1219 static bool ath9k_hw_set_def_power_per_rate_table(struct ath_hal
*ah
,
1220 struct ath9k_channel
*chan
,
1221 int16_t *ratesArray
,
1223 u16 AntennaReduction
,
1224 u16 twiceMaxRegulatoryPower
,
1227 #define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */
1228 #define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10 /* 10*log10(3)*2 */
1230 struct ath_hal_5416
*ahp
= AH5416(ah
);
1231 struct ar5416_eeprom_def
*pEepData
= &ahp
->ah_eeprom
.def
;
1232 u16 twiceMaxEdgePower
= AR5416_MAX_RATE_POWER
;
1233 static const u16 tpScaleReductionTable
[5] =
1234 { 0, 3, 6, 9, AR5416_MAX_RATE_POWER
};
1237 int16_t twiceLargestAntenna
;
1238 struct cal_ctl_data
*rep
;
1239 struct cal_target_power_leg targetPowerOfdm
, targetPowerCck
= {
1242 struct cal_target_power_leg targetPowerOfdmExt
= {
1243 0, { 0, 0, 0, 0} }, targetPowerCckExt
= {
1246 struct cal_target_power_ht targetPowerHt20
, targetPowerHt40
= {
1249 u16 scaledPower
= 0, minCtlPower
, maxRegAllowedPower
;
1250 u16 ctlModesFor11a
[] =
1251 { CTL_11A
, CTL_5GHT20
, CTL_11A_EXT
, CTL_5GHT40
};
1252 u16 ctlModesFor11g
[] =
1253 { CTL_11B
, CTL_11G
, CTL_2GHT20
, CTL_11B_EXT
, CTL_11G_EXT
,
1256 u16 numCtlModes
, *pCtlMode
, ctlMode
, freq
;
1257 struct chan_centers centers
;
1259 u16 twiceMinEdgePower
;
1261 tx_chainmask
= ahp
->ah_txchainmask
;
1263 ath9k_hw_get_channel_centers(ah
, chan
, ¢ers
);
1265 twiceLargestAntenna
= max(
1266 pEepData
->modalHeader
1267 [IS_CHAN_2GHZ(chan
)].antennaGainCh
[0],
1268 pEepData
->modalHeader
1269 [IS_CHAN_2GHZ(chan
)].antennaGainCh
[1]);
1271 twiceLargestAntenna
= max((u8
)twiceLargestAntenna
,
1272 pEepData
->modalHeader
1273 [IS_CHAN_2GHZ(chan
)].antennaGainCh
[2]);
1275 twiceLargestAntenna
= (int16_t)min(AntennaReduction
-
1276 twiceLargestAntenna
, 0);
1278 maxRegAllowedPower
= twiceMaxRegulatoryPower
+ twiceLargestAntenna
;
1280 if (ah
->ah_tpScale
!= ATH9K_TP_SCALE_MAX
) {
1281 maxRegAllowedPower
-=
1282 (tpScaleReductionTable
[(ah
->ah_tpScale
)] * 2);
1285 scaledPower
= min(powerLimit
, maxRegAllowedPower
);
1287 switch (ar5416_get_ntxchains(tx_chainmask
)) {
1291 scaledPower
-= REDUCE_SCALED_POWER_BY_TWO_CHAIN
;
1294 scaledPower
-= REDUCE_SCALED_POWER_BY_THREE_CHAIN
;
1298 scaledPower
= max((u16
)0, scaledPower
);
1300 if (IS_CHAN_2GHZ(chan
)) {
1301 numCtlModes
= ARRAY_SIZE(ctlModesFor11g
) -
1302 SUB_NUM_CTL_MODES_AT_2G_40
;
1303 pCtlMode
= ctlModesFor11g
;
1305 ath9k_hw_get_legacy_target_powers(ah
, chan
,
1306 pEepData
->calTargetPowerCck
,
1307 AR5416_NUM_2G_CCK_TARGET_POWERS
,
1308 &targetPowerCck
, 4, false);
1309 ath9k_hw_get_legacy_target_powers(ah
, chan
,
1310 pEepData
->calTargetPower2G
,
1311 AR5416_NUM_2G_20_TARGET_POWERS
,
1312 &targetPowerOfdm
, 4, false);
1313 ath9k_hw_get_target_powers(ah
, chan
,
1314 pEepData
->calTargetPower2GHT20
,
1315 AR5416_NUM_2G_20_TARGET_POWERS
,
1316 &targetPowerHt20
, 8, false);
1318 if (IS_CHAN_HT40(chan
)) {
1319 numCtlModes
= ARRAY_SIZE(ctlModesFor11g
);
1320 ath9k_hw_get_target_powers(ah
, chan
,
1321 pEepData
->calTargetPower2GHT40
,
1322 AR5416_NUM_2G_40_TARGET_POWERS
,
1323 &targetPowerHt40
, 8, true);
1324 ath9k_hw_get_legacy_target_powers(ah
, chan
,
1325 pEepData
->calTargetPowerCck
,
1326 AR5416_NUM_2G_CCK_TARGET_POWERS
,
1327 &targetPowerCckExt
, 4, true);
1328 ath9k_hw_get_legacy_target_powers(ah
, chan
,
1329 pEepData
->calTargetPower2G
,
1330 AR5416_NUM_2G_20_TARGET_POWERS
,
1331 &targetPowerOfdmExt
, 4, true);
1334 numCtlModes
= ARRAY_SIZE(ctlModesFor11a
) -
1335 SUB_NUM_CTL_MODES_AT_5G_40
;
1336 pCtlMode
= ctlModesFor11a
;
1338 ath9k_hw_get_legacy_target_powers(ah
, chan
,
1339 pEepData
->calTargetPower5G
,
1340 AR5416_NUM_5G_20_TARGET_POWERS
,
1341 &targetPowerOfdm
, 4, false);
1342 ath9k_hw_get_target_powers(ah
, chan
,
1343 pEepData
->calTargetPower5GHT20
,
1344 AR5416_NUM_5G_20_TARGET_POWERS
,
1345 &targetPowerHt20
, 8, false);
1347 if (IS_CHAN_HT40(chan
)) {
1348 numCtlModes
= ARRAY_SIZE(ctlModesFor11a
);
1349 ath9k_hw_get_target_powers(ah
, chan
,
1350 pEepData
->calTargetPower5GHT40
,
1351 AR5416_NUM_5G_40_TARGET_POWERS
,
1352 &targetPowerHt40
, 8, true);
1353 ath9k_hw_get_legacy_target_powers(ah
, chan
,
1354 pEepData
->calTargetPower5G
,
1355 AR5416_NUM_5G_20_TARGET_POWERS
,
1356 &targetPowerOfdmExt
, 4, true);
1360 for (ctlMode
= 0; ctlMode
< numCtlModes
; ctlMode
++) {
1361 bool isHt40CtlMode
= (pCtlMode
[ctlMode
] == CTL_5GHT40
) ||
1362 (pCtlMode
[ctlMode
] == CTL_2GHT40
);
1364 freq
= centers
.synth_center
;
1365 else if (pCtlMode
[ctlMode
] & EXT_ADDITIVE
)
1366 freq
= centers
.ext_center
;
1368 freq
= centers
.ctl_center
;
1370 if (ar5416_get_eep_ver(ahp
) == 14 && ar5416_get_eep_rev(ahp
) <= 2)
1371 twiceMaxEdgePower
= AR5416_MAX_RATE_POWER
;
1373 DPRINTF(ah
->ah_sc
, ATH_DBG_POWER_MGMT
,
1374 "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
1375 "EXT_ADDITIVE %d\n",
1376 ctlMode
, numCtlModes
, isHt40CtlMode
,
1377 (pCtlMode
[ctlMode
] & EXT_ADDITIVE
));
1379 for (i
= 0; (i
< AR5416_NUM_CTLS
) && pEepData
->ctlIndex
[i
]; i
++) {
1380 DPRINTF(ah
->ah_sc
, ATH_DBG_POWER_MGMT
,
1381 " LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
1382 "pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
1384 i
, cfgCtl
, pCtlMode
[ctlMode
],
1385 pEepData
->ctlIndex
[i
], chan
->channel
);
1387 if ((((cfgCtl
& ~CTL_MODE_M
) |
1388 (pCtlMode
[ctlMode
] & CTL_MODE_M
)) ==
1389 pEepData
->ctlIndex
[i
]) ||
1390 (((cfgCtl
& ~CTL_MODE_M
) |
1391 (pCtlMode
[ctlMode
] & CTL_MODE_M
)) ==
1392 ((pEepData
->ctlIndex
[i
] & CTL_MODE_M
) | SD_NO_CTL
))) {
1393 rep
= &(pEepData
->ctlData
[i
]);
1395 twiceMinEdgePower
= ath9k_hw_get_max_edge_power(freq
,
1396 rep
->ctlEdges
[ar5416_get_ntxchains(tx_chainmask
) - 1],
1397 IS_CHAN_2GHZ(chan
), AR5416_NUM_BAND_EDGES
);
1399 DPRINTF(ah
->ah_sc
, ATH_DBG_POWER_MGMT
,
1400 " MATCH-EE_IDX %d: ch %d is2 %d "
1401 "2xMinEdge %d chainmask %d chains %d\n",
1402 i
, freq
, IS_CHAN_2GHZ(chan
),
1403 twiceMinEdgePower
, tx_chainmask
,
1404 ar5416_get_ntxchains
1406 if ((cfgCtl
& ~CTL_MODE_M
) == SD_NO_CTL
) {
1407 twiceMaxEdgePower
= min(twiceMaxEdgePower
,
1410 twiceMaxEdgePower
= twiceMinEdgePower
;
1416 minCtlPower
= min(twiceMaxEdgePower
, scaledPower
);
1418 DPRINTF(ah
->ah_sc
, ATH_DBG_POWER_MGMT
,
1419 " SEL-Min ctlMode %d pCtlMode %d "
1420 "2xMaxEdge %d sP %d minCtlPwr %d\n",
1421 ctlMode
, pCtlMode
[ctlMode
], twiceMaxEdgePower
,
1422 scaledPower
, minCtlPower
);
1424 switch (pCtlMode
[ctlMode
]) {
1426 for (i
= 0; i
< ARRAY_SIZE(targetPowerCck
.tPow2x
); i
++) {
1427 targetPowerCck
.tPow2x
[i
] =
1428 min((u16
)targetPowerCck
.tPow2x
[i
],
1434 for (i
= 0; i
< ARRAY_SIZE(targetPowerOfdm
.tPow2x
); i
++) {
1435 targetPowerOfdm
.tPow2x
[i
] =
1436 min((u16
)targetPowerOfdm
.tPow2x
[i
],
1442 for (i
= 0; i
< ARRAY_SIZE(targetPowerHt20
.tPow2x
); i
++) {
1443 targetPowerHt20
.tPow2x
[i
] =
1444 min((u16
)targetPowerHt20
.tPow2x
[i
],
1449 targetPowerCckExt
.tPow2x
[0] = min((u16
)
1450 targetPowerCckExt
.tPow2x
[0],
1455 targetPowerOfdmExt
.tPow2x
[0] = min((u16
)
1456 targetPowerOfdmExt
.tPow2x
[0],
1461 for (i
= 0; i
< ARRAY_SIZE(targetPowerHt40
.tPow2x
); i
++) {
1462 targetPowerHt40
.tPow2x
[i
] =
1463 min((u16
)targetPowerHt40
.tPow2x
[i
],
1472 ratesArray
[rate6mb
] = ratesArray
[rate9mb
] = ratesArray
[rate12mb
] =
1473 ratesArray
[rate18mb
] = ratesArray
[rate24mb
] =
1474 targetPowerOfdm
.tPow2x
[0];
1475 ratesArray
[rate36mb
] = targetPowerOfdm
.tPow2x
[1];
1476 ratesArray
[rate48mb
] = targetPowerOfdm
.tPow2x
[2];
1477 ratesArray
[rate54mb
] = targetPowerOfdm
.tPow2x
[3];
1478 ratesArray
[rateXr
] = targetPowerOfdm
.tPow2x
[0];
1480 for (i
= 0; i
< ARRAY_SIZE(targetPowerHt20
.tPow2x
); i
++)
1481 ratesArray
[rateHt20_0
+ i
] = targetPowerHt20
.tPow2x
[i
];
1483 if (IS_CHAN_2GHZ(chan
)) {
1484 ratesArray
[rate1l
] = targetPowerCck
.tPow2x
[0];
1485 ratesArray
[rate2s
] = ratesArray
[rate2l
] =
1486 targetPowerCck
.tPow2x
[1];
1487 ratesArray
[rate5_5s
] = ratesArray
[rate5_5l
] =
1488 targetPowerCck
.tPow2x
[2];
1490 ratesArray
[rate11s
] = ratesArray
[rate11l
] =
1491 targetPowerCck
.tPow2x
[3];
1494 if (IS_CHAN_HT40(chan
)) {
1495 for (i
= 0; i
< ARRAY_SIZE(targetPowerHt40
.tPow2x
); i
++) {
1496 ratesArray
[rateHt40_0
+ i
] =
1497 targetPowerHt40
.tPow2x
[i
];
1499 ratesArray
[rateDupOfdm
] = targetPowerHt40
.tPow2x
[0];
1500 ratesArray
[rateDupCck
] = targetPowerHt40
.tPow2x
[0];
1501 ratesArray
[rateExtOfdm
] = targetPowerOfdmExt
.tPow2x
[0];
1502 if (IS_CHAN_2GHZ(chan
)) {
1503 ratesArray
[rateExtCck
] =
1504 targetPowerCckExt
.tPow2x
[0];
1510 static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hal
*ah
,
1511 struct ath9k_channel
*chan
,
1512 int16_t *ratesArray
,
1514 u16 AntennaReduction
,
1515 u16 twiceMaxRegulatoryPower
,
1518 struct ath_hal_5416
*ahp
= AH5416(ah
);
1519 struct ar5416_eeprom_4k
*pEepData
= &ahp
->ah_eeprom
.map4k
;
1520 u16 twiceMaxEdgePower
= AR5416_MAX_RATE_POWER
;
1521 static const u16 tpScaleReductionTable
[5] =
1522 { 0, 3, 6, 9, AR5416_MAX_RATE_POWER
};
1525 int16_t twiceLargestAntenna
;
1526 struct cal_ctl_data_4k
*rep
;
1527 struct cal_target_power_leg targetPowerOfdm
, targetPowerCck
= {
1530 struct cal_target_power_leg targetPowerOfdmExt
= {
1531 0, { 0, 0, 0, 0} }, targetPowerCckExt
= {
1534 struct cal_target_power_ht targetPowerHt20
, targetPowerHt40
= {
1537 u16 scaledPower
= 0, minCtlPower
, maxRegAllowedPower
;
1538 u16 ctlModesFor11g
[] =
1539 { CTL_11B
, CTL_11G
, CTL_2GHT20
, CTL_11B_EXT
, CTL_11G_EXT
,
1542 u16 numCtlModes
, *pCtlMode
, ctlMode
, freq
;
1543 struct chan_centers centers
;
1545 u16 twiceMinEdgePower
;
1547 tx_chainmask
= ahp
->ah_txchainmask
;
1549 ath9k_hw_get_channel_centers(ah
, chan
, ¢ers
);
1551 twiceLargestAntenna
= pEepData
->modalHeader
.antennaGainCh
[0];
1553 twiceLargestAntenna
= (int16_t)min(AntennaReduction
-
1554 twiceLargestAntenna
, 0);
1556 maxRegAllowedPower
= twiceMaxRegulatoryPower
+ twiceLargestAntenna
;
1558 if (ah
->ah_tpScale
!= ATH9K_TP_SCALE_MAX
) {
1559 maxRegAllowedPower
-=
1560 (tpScaleReductionTable
[(ah
->ah_tpScale
)] * 2);
1563 scaledPower
= min(powerLimit
, maxRegAllowedPower
);
1564 scaledPower
= max((u16
)0, scaledPower
);
1566 numCtlModes
= ARRAY_SIZE(ctlModesFor11g
) - SUB_NUM_CTL_MODES_AT_2G_40
;
1567 pCtlMode
= ctlModesFor11g
;
1569 ath9k_hw_get_legacy_target_powers(ah
, chan
,
1570 pEepData
->calTargetPowerCck
,
1571 AR5416_NUM_2G_CCK_TARGET_POWERS
,
1572 &targetPowerCck
, 4, false);
1573 ath9k_hw_get_legacy_target_powers(ah
, chan
,
1574 pEepData
->calTargetPower2G
,
1575 AR5416_NUM_2G_20_TARGET_POWERS
,
1576 &targetPowerOfdm
, 4, false);
1577 ath9k_hw_get_target_powers(ah
, chan
,
1578 pEepData
->calTargetPower2GHT20
,
1579 AR5416_NUM_2G_20_TARGET_POWERS
,
1580 &targetPowerHt20
, 8, false);
1582 if (IS_CHAN_HT40(chan
)) {
1583 numCtlModes
= ARRAY_SIZE(ctlModesFor11g
);
1584 ath9k_hw_get_target_powers(ah
, chan
,
1585 pEepData
->calTargetPower2GHT40
,
1586 AR5416_NUM_2G_40_TARGET_POWERS
,
1587 &targetPowerHt40
, 8, true);
1588 ath9k_hw_get_legacy_target_powers(ah
, chan
,
1589 pEepData
->calTargetPowerCck
,
1590 AR5416_NUM_2G_CCK_TARGET_POWERS
,
1591 &targetPowerCckExt
, 4, true);
1592 ath9k_hw_get_legacy_target_powers(ah
, chan
,
1593 pEepData
->calTargetPower2G
,
1594 AR5416_NUM_2G_20_TARGET_POWERS
,
1595 &targetPowerOfdmExt
, 4, true);
1598 for (ctlMode
= 0; ctlMode
< numCtlModes
; ctlMode
++) {
1599 bool isHt40CtlMode
= (pCtlMode
[ctlMode
] == CTL_5GHT40
) ||
1600 (pCtlMode
[ctlMode
] == CTL_2GHT40
);
1602 freq
= centers
.synth_center
;
1603 else if (pCtlMode
[ctlMode
] & EXT_ADDITIVE
)
1604 freq
= centers
.ext_center
;
1606 freq
= centers
.ctl_center
;
1608 if (ar5416_get_eep_ver(ahp
) == 14 &&
1609 ar5416_get_eep_rev(ahp
) <= 2)
1610 twiceMaxEdgePower
= AR5416_MAX_RATE_POWER
;
1612 DPRINTF(ah
->ah_sc
, ATH_DBG_POWER_MGMT
,
1613 "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
1614 "EXT_ADDITIVE %d\n",
1615 ctlMode
, numCtlModes
, isHt40CtlMode
,
1616 (pCtlMode
[ctlMode
] & EXT_ADDITIVE
));
1618 for (i
= 0; (i
< AR5416_NUM_CTLS
) &&
1619 pEepData
->ctlIndex
[i
]; i
++) {
1620 DPRINTF(ah
->ah_sc
, ATH_DBG_POWER_MGMT
,
1621 " LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
1622 "pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
1624 i
, cfgCtl
, pCtlMode
[ctlMode
],
1625 pEepData
->ctlIndex
[i
], chan
->channel
);
1627 if ((((cfgCtl
& ~CTL_MODE_M
) |
1628 (pCtlMode
[ctlMode
] & CTL_MODE_M
)) ==
1629 pEepData
->ctlIndex
[i
]) ||
1630 (((cfgCtl
& ~CTL_MODE_M
) |
1631 (pCtlMode
[ctlMode
] & CTL_MODE_M
)) ==
1632 ((pEepData
->ctlIndex
[i
] & CTL_MODE_M
) |
1634 rep
= &(pEepData
->ctlData
[i
]);
1637 ath9k_hw_get_max_edge_power(freq
,
1638 rep
->ctlEdges
[ar5416_get_ntxchains
1639 (tx_chainmask
) - 1],
1641 AR5416_EEP4K_NUM_BAND_EDGES
);
1643 DPRINTF(ah
->ah_sc
, ATH_DBG_POWER_MGMT
,
1644 " MATCH-EE_IDX %d: ch %d is2 %d "
1645 "2xMinEdge %d chainmask %d chains %d\n",
1646 i
, freq
, IS_CHAN_2GHZ(chan
),
1647 twiceMinEdgePower
, tx_chainmask
,
1648 ar5416_get_ntxchains
1650 if ((cfgCtl
& ~CTL_MODE_M
) == SD_NO_CTL
) {
1652 min(twiceMaxEdgePower
,
1655 twiceMaxEdgePower
= twiceMinEdgePower
;
1661 minCtlPower
= (u8
)min(twiceMaxEdgePower
, scaledPower
);
1663 DPRINTF(ah
->ah_sc
, ATH_DBG_POWER_MGMT
,
1664 " SEL-Min ctlMode %d pCtlMode %d "
1665 "2xMaxEdge %d sP %d minCtlPwr %d\n",
1666 ctlMode
, pCtlMode
[ctlMode
], twiceMaxEdgePower
,
1667 scaledPower
, minCtlPower
);
1669 switch (pCtlMode
[ctlMode
]) {
1671 for (i
= 0; i
< ARRAY_SIZE(targetPowerCck
.tPow2x
);
1673 targetPowerCck
.tPow2x
[i
] =
1674 min((u16
)targetPowerCck
.tPow2x
[i
],
1679 for (i
= 0; i
< ARRAY_SIZE(targetPowerOfdm
.tPow2x
);
1681 targetPowerOfdm
.tPow2x
[i
] =
1682 min((u16
)targetPowerOfdm
.tPow2x
[i
],
1687 for (i
= 0; i
< ARRAY_SIZE(targetPowerHt20
.tPow2x
);
1689 targetPowerHt20
.tPow2x
[i
] =
1690 min((u16
)targetPowerHt20
.tPow2x
[i
],
1695 targetPowerCckExt
.tPow2x
[0] = min((u16
)
1696 targetPowerCckExt
.tPow2x
[0],
1700 targetPowerOfdmExt
.tPow2x
[0] = min((u16
)
1701 targetPowerOfdmExt
.tPow2x
[0],
1705 for (i
= 0; i
< ARRAY_SIZE(targetPowerHt40
.tPow2x
);
1707 targetPowerHt40
.tPow2x
[i
] =
1708 min((u16
)targetPowerHt40
.tPow2x
[i
],
1717 ratesArray
[rate6mb
] = ratesArray
[rate9mb
] = ratesArray
[rate12mb
] =
1718 ratesArray
[rate18mb
] = ratesArray
[rate24mb
] =
1719 targetPowerOfdm
.tPow2x
[0];
1720 ratesArray
[rate36mb
] = targetPowerOfdm
.tPow2x
[1];
1721 ratesArray
[rate48mb
] = targetPowerOfdm
.tPow2x
[2];
1722 ratesArray
[rate54mb
] = targetPowerOfdm
.tPow2x
[3];
1723 ratesArray
[rateXr
] = targetPowerOfdm
.tPow2x
[0];
1725 for (i
= 0; i
< ARRAY_SIZE(targetPowerHt20
.tPow2x
); i
++)
1726 ratesArray
[rateHt20_0
+ i
] = targetPowerHt20
.tPow2x
[i
];
1728 ratesArray
[rate1l
] = targetPowerCck
.tPow2x
[0];
1729 ratesArray
[rate2s
] = ratesArray
[rate2l
] = targetPowerCck
.tPow2x
[1];
1730 ratesArray
[rate5_5s
] = ratesArray
[rate5_5l
] = targetPowerCck
.tPow2x
[2];
1731 ratesArray
[rate11s
] = ratesArray
[rate11l
] = targetPowerCck
.tPow2x
[3];
1733 if (IS_CHAN_HT40(chan
)) {
1734 for (i
= 0; i
< ARRAY_SIZE(targetPowerHt40
.tPow2x
); i
++) {
1735 ratesArray
[rateHt40_0
+ i
] =
1736 targetPowerHt40
.tPow2x
[i
];
1738 ratesArray
[rateDupOfdm
] = targetPowerHt40
.tPow2x
[0];
1739 ratesArray
[rateDupCck
] = targetPowerHt40
.tPow2x
[0];
1740 ratesArray
[rateExtOfdm
] = targetPowerOfdmExt
.tPow2x
[0];
1741 ratesArray
[rateExtCck
] = targetPowerCckExt
.tPow2x
[0];
1746 static int ath9k_hw_def_set_txpower(struct ath_hal
*ah
,
1747 struct ath9k_channel
*chan
,
1749 u8 twiceAntennaReduction
,
1750 u8 twiceMaxRegulatoryPower
,
1753 struct ath_hal_5416
*ahp
= AH5416(ah
);
1754 struct ar5416_eeprom_def
*pEepData
= &ahp
->ah_eeprom
.def
;
1755 struct modal_eep_header
*pModal
=
1756 &(pEepData
->modalHeader
[IS_CHAN_2GHZ(chan
)]);
1757 int16_t ratesArray
[Ar5416RateSize
];
1758 int16_t txPowerIndexOffset
= 0;
1759 u8 ht40PowerIncForPdadc
= 2;
1762 memset(ratesArray
, 0, sizeof(ratesArray
));
1764 if ((pEepData
->baseEepHeader
.version
& AR5416_EEP_VER_MINOR_MASK
) >=
1765 AR5416_EEP_MINOR_VER_2
) {
1766 ht40PowerIncForPdadc
= pModal
->ht40PowerIncForPdadc
;
1769 if (!ath9k_hw_set_def_power_per_rate_table(ah
, chan
,
1770 &ratesArray
[0], cfgCtl
,
1771 twiceAntennaReduction
,
1772 twiceMaxRegulatoryPower
,
1774 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
1775 "ath9k_hw_set_txpower: unable to set "
1776 "tx power per rate table\n");
1780 if (!ath9k_hw_set_def_power_cal_table(ah
, chan
, &txPowerIndexOffset
)) {
1781 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
1782 "ath9k_hw_set_txpower: unable to set power table\n");
1786 for (i
= 0; i
< ARRAY_SIZE(ratesArray
); i
++) {
1787 ratesArray
[i
] = (int16_t)(txPowerIndexOffset
+ ratesArray
[i
]);
1788 if (ratesArray
[i
] > AR5416_MAX_RATE_POWER
)
1789 ratesArray
[i
] = AR5416_MAX_RATE_POWER
;
1792 if (AR_SREV_9280_10_OR_LATER(ah
)) {
1793 for (i
= 0; i
< Ar5416RateSize
; i
++)
1794 ratesArray
[i
] -= AR5416_PWR_TABLE_OFFSET
* 2;
1797 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE1
,
1798 ATH9K_POW_SM(ratesArray
[rate18mb
], 24)
1799 | ATH9K_POW_SM(ratesArray
[rate12mb
], 16)
1800 | ATH9K_POW_SM(ratesArray
[rate9mb
], 8)
1801 | ATH9K_POW_SM(ratesArray
[rate6mb
], 0));
1802 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE2
,
1803 ATH9K_POW_SM(ratesArray
[rate54mb
], 24)
1804 | ATH9K_POW_SM(ratesArray
[rate48mb
], 16)
1805 | ATH9K_POW_SM(ratesArray
[rate36mb
], 8)
1806 | ATH9K_POW_SM(ratesArray
[rate24mb
], 0));
1808 if (IS_CHAN_2GHZ(chan
)) {
1809 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE3
,
1810 ATH9K_POW_SM(ratesArray
[rate2s
], 24)
1811 | ATH9K_POW_SM(ratesArray
[rate2l
], 16)
1812 | ATH9K_POW_SM(ratesArray
[rateXr
], 8)
1813 | ATH9K_POW_SM(ratesArray
[rate1l
], 0));
1814 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE4
,
1815 ATH9K_POW_SM(ratesArray
[rate11s
], 24)
1816 | ATH9K_POW_SM(ratesArray
[rate11l
], 16)
1817 | ATH9K_POW_SM(ratesArray
[rate5_5s
], 8)
1818 | ATH9K_POW_SM(ratesArray
[rate5_5l
], 0));
1821 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE5
,
1822 ATH9K_POW_SM(ratesArray
[rateHt20_3
], 24)
1823 | ATH9K_POW_SM(ratesArray
[rateHt20_2
], 16)
1824 | ATH9K_POW_SM(ratesArray
[rateHt20_1
], 8)
1825 | ATH9K_POW_SM(ratesArray
[rateHt20_0
], 0));
1826 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE6
,
1827 ATH9K_POW_SM(ratesArray
[rateHt20_7
], 24)
1828 | ATH9K_POW_SM(ratesArray
[rateHt20_6
], 16)
1829 | ATH9K_POW_SM(ratesArray
[rateHt20_5
], 8)
1830 | ATH9K_POW_SM(ratesArray
[rateHt20_4
], 0));
1832 if (IS_CHAN_HT40(chan
)) {
1833 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE7
,
1834 ATH9K_POW_SM(ratesArray
[rateHt40_3
] +
1835 ht40PowerIncForPdadc
, 24)
1836 | ATH9K_POW_SM(ratesArray
[rateHt40_2
] +
1837 ht40PowerIncForPdadc
, 16)
1838 | ATH9K_POW_SM(ratesArray
[rateHt40_1
] +
1839 ht40PowerIncForPdadc
, 8)
1840 | ATH9K_POW_SM(ratesArray
[rateHt40_0
] +
1841 ht40PowerIncForPdadc
, 0));
1842 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE8
,
1843 ATH9K_POW_SM(ratesArray
[rateHt40_7
] +
1844 ht40PowerIncForPdadc
, 24)
1845 | ATH9K_POW_SM(ratesArray
[rateHt40_6
] +
1846 ht40PowerIncForPdadc
, 16)
1847 | ATH9K_POW_SM(ratesArray
[rateHt40_5
] +
1848 ht40PowerIncForPdadc
, 8)
1849 | ATH9K_POW_SM(ratesArray
[rateHt40_4
] +
1850 ht40PowerIncForPdadc
, 0));
1852 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE9
,
1853 ATH9K_POW_SM(ratesArray
[rateExtOfdm
], 24)
1854 | ATH9K_POW_SM(ratesArray
[rateExtCck
], 16)
1855 | ATH9K_POW_SM(ratesArray
[rateDupOfdm
], 8)
1856 | ATH9K_POW_SM(ratesArray
[rateDupCck
], 0));
1859 REG_WRITE(ah
, AR_PHY_POWER_TX_SUB
,
1860 ATH9K_POW_SM(pModal
->pwrDecreaseFor3Chain
, 6)
1861 | ATH9K_POW_SM(pModal
->pwrDecreaseFor2Chain
, 0));
1865 if (IS_CHAN_HT40(chan
))
1867 else if (IS_CHAN_HT20(chan
))
1870 if (AR_SREV_9280_10_OR_LATER(ah
))
1871 ah
->ah_maxPowerLevel
=
1872 ratesArray
[i
] + AR5416_PWR_TABLE_OFFSET
* 2;
1874 ah
->ah_maxPowerLevel
= ratesArray
[i
];
1879 static int ath9k_hw_4k_set_txpower(struct ath_hal
*ah
,
1880 struct ath9k_channel
*chan
,
1882 u8 twiceAntennaReduction
,
1883 u8 twiceMaxRegulatoryPower
,
1886 struct ath_hal_5416
*ahp
= AH5416(ah
);
1887 struct ar5416_eeprom_4k
*pEepData
= &ahp
->ah_eeprom
.map4k
;
1888 struct modal_eep_4k_header
*pModal
= &pEepData
->modalHeader
;
1889 int16_t ratesArray
[Ar5416RateSize
];
1890 int16_t txPowerIndexOffset
= 0;
1891 u8 ht40PowerIncForPdadc
= 2;
1894 memset(ratesArray
, 0, sizeof(ratesArray
));
1896 if ((pEepData
->baseEepHeader
.version
& AR5416_EEP_VER_MINOR_MASK
) >=
1897 AR5416_EEP_MINOR_VER_2
) {
1898 ht40PowerIncForPdadc
= pModal
->ht40PowerIncForPdadc
;
1901 if (!ath9k_hw_set_4k_power_per_rate_table(ah
, chan
,
1902 &ratesArray
[0], cfgCtl
,
1903 twiceAntennaReduction
,
1904 twiceMaxRegulatoryPower
,
1906 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
1907 "ath9k_hw_set_txpower: unable to set "
1908 "tx power per rate table\n");
1912 if (!ath9k_hw_set_4k_power_cal_table(ah
, chan
, &txPowerIndexOffset
)) {
1913 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
1914 "ath9k_hw_set_txpower: unable to set power table\n");
1918 for (i
= 0; i
< ARRAY_SIZE(ratesArray
); i
++) {
1919 ratesArray
[i
] = (int16_t)(txPowerIndexOffset
+ ratesArray
[i
]);
1920 if (ratesArray
[i
] > AR5416_MAX_RATE_POWER
)
1921 ratesArray
[i
] = AR5416_MAX_RATE_POWER
;
1924 if (AR_SREV_9280_10_OR_LATER(ah
)) {
1925 for (i
= 0; i
< Ar5416RateSize
; i
++)
1926 ratesArray
[i
] -= AR5416_PWR_TABLE_OFFSET
* 2;
1929 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE1
,
1930 ATH9K_POW_SM(ratesArray
[rate18mb
], 24)
1931 | ATH9K_POW_SM(ratesArray
[rate12mb
], 16)
1932 | ATH9K_POW_SM(ratesArray
[rate9mb
], 8)
1933 | ATH9K_POW_SM(ratesArray
[rate6mb
], 0));
1934 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE2
,
1935 ATH9K_POW_SM(ratesArray
[rate54mb
], 24)
1936 | ATH9K_POW_SM(ratesArray
[rate48mb
], 16)
1937 | ATH9K_POW_SM(ratesArray
[rate36mb
], 8)
1938 | ATH9K_POW_SM(ratesArray
[rate24mb
], 0));
1940 if (IS_CHAN_2GHZ(chan
)) {
1941 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE3
,
1942 ATH9K_POW_SM(ratesArray
[rate2s
], 24)
1943 | ATH9K_POW_SM(ratesArray
[rate2l
], 16)
1944 | ATH9K_POW_SM(ratesArray
[rateXr
], 8)
1945 | ATH9K_POW_SM(ratesArray
[rate1l
], 0));
1946 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE4
,
1947 ATH9K_POW_SM(ratesArray
[rate11s
], 24)
1948 | ATH9K_POW_SM(ratesArray
[rate11l
], 16)
1949 | ATH9K_POW_SM(ratesArray
[rate5_5s
], 8)
1950 | ATH9K_POW_SM(ratesArray
[rate5_5l
], 0));
1953 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE5
,
1954 ATH9K_POW_SM(ratesArray
[rateHt20_3
], 24)
1955 | ATH9K_POW_SM(ratesArray
[rateHt20_2
], 16)
1956 | ATH9K_POW_SM(ratesArray
[rateHt20_1
], 8)
1957 | ATH9K_POW_SM(ratesArray
[rateHt20_0
], 0));
1958 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE6
,
1959 ATH9K_POW_SM(ratesArray
[rateHt20_7
], 24)
1960 | ATH9K_POW_SM(ratesArray
[rateHt20_6
], 16)
1961 | ATH9K_POW_SM(ratesArray
[rateHt20_5
], 8)
1962 | ATH9K_POW_SM(ratesArray
[rateHt20_4
], 0));
1964 if (IS_CHAN_HT40(chan
)) {
1965 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE7
,
1966 ATH9K_POW_SM(ratesArray
[rateHt40_3
] +
1967 ht40PowerIncForPdadc
, 24)
1968 | ATH9K_POW_SM(ratesArray
[rateHt40_2
] +
1969 ht40PowerIncForPdadc
, 16)
1970 | ATH9K_POW_SM(ratesArray
[rateHt40_1
] +
1971 ht40PowerIncForPdadc
, 8)
1972 | ATH9K_POW_SM(ratesArray
[rateHt40_0
] +
1973 ht40PowerIncForPdadc
, 0));
1974 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE8
,
1975 ATH9K_POW_SM(ratesArray
[rateHt40_7
] +
1976 ht40PowerIncForPdadc
, 24)
1977 | ATH9K_POW_SM(ratesArray
[rateHt40_6
] +
1978 ht40PowerIncForPdadc
, 16)
1979 | ATH9K_POW_SM(ratesArray
[rateHt40_5
] +
1980 ht40PowerIncForPdadc
, 8)
1981 | ATH9K_POW_SM(ratesArray
[rateHt40_4
] +
1982 ht40PowerIncForPdadc
, 0));
1984 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE9
,
1985 ATH9K_POW_SM(ratesArray
[rateExtOfdm
], 24)
1986 | ATH9K_POW_SM(ratesArray
[rateExtCck
], 16)
1987 | ATH9K_POW_SM(ratesArray
[rateDupOfdm
], 8)
1988 | ATH9K_POW_SM(ratesArray
[rateDupCck
], 0));
1993 if (IS_CHAN_HT40(chan
))
1995 else if (IS_CHAN_HT20(chan
))
1998 if (AR_SREV_9280_10_OR_LATER(ah
))
1999 ah
->ah_maxPowerLevel
=
2000 ratesArray
[i
] + AR5416_PWR_TABLE_OFFSET
* 2;
2002 ah
->ah_maxPowerLevel
= ratesArray
[i
];
2007 static int (*ath9k_set_txpower
[]) (struct ath_hal
*,
2008 struct ath9k_channel
*,
2009 u16
, u8
, u8
, u8
) = {
2010 ath9k_hw_def_set_txpower
,
2011 ath9k_hw_4k_set_txpower
2014 int ath9k_hw_set_txpower(struct ath_hal
*ah
,
2015 struct ath9k_channel
*chan
,
2017 u8 twiceAntennaReduction
,
2018 u8 twiceMaxRegulatoryPower
,
2021 struct ath_hal_5416
*ahp
= AH5416(ah
);
2023 return ath9k_set_txpower
[ahp
->ah_eep_map
](ah
, chan
, cfgCtl
,
2024 twiceAntennaReduction
, twiceMaxRegulatoryPower
,
2028 static void ath9k_hw_set_def_addac(struct ath_hal
*ah
,
2029 struct ath9k_channel
*chan
)
2031 #define XPA_LVL_FREQ(cnt) (pModal->xpaBiasLvlFreq[cnt])
2032 struct modal_eep_header
*pModal
;
2033 struct ath_hal_5416
*ahp
= AH5416(ah
);
2034 struct ar5416_eeprom_def
*eep
= &ahp
->ah_eeprom
.def
;
2037 if (ah
->ah_macVersion
!= AR_SREV_VERSION_9160
)
2040 if (ar5416_get_eep_rev(ahp
) < AR5416_EEP_MINOR_VER_7
)
2043 pModal
= &(eep
->modalHeader
[IS_CHAN_2GHZ(chan
)]);
2045 if (pModal
->xpaBiasLvl
!= 0xff) {
2046 biaslevel
= pModal
->xpaBiasLvl
;
2048 u16 resetFreqBin
, freqBin
, freqCount
= 0;
2049 struct chan_centers centers
;
2051 ath9k_hw_get_channel_centers(ah
, chan
, ¢ers
);
2053 resetFreqBin
= FREQ2FBIN(centers
.synth_center
,
2054 IS_CHAN_2GHZ(chan
));
2055 freqBin
= XPA_LVL_FREQ(0) & 0xff;
2056 biaslevel
= (u8
) (XPA_LVL_FREQ(0) >> 14);
2060 while (freqCount
< 3) {
2061 if (XPA_LVL_FREQ(freqCount
) == 0x0)
2064 freqBin
= XPA_LVL_FREQ(freqCount
) & 0xff;
2065 if (resetFreqBin
>= freqBin
)
2066 biaslevel
= (u8
)(XPA_LVL_FREQ(freqCount
) >> 14);
2073 if (IS_CHAN_2GHZ(chan
)) {
2074 INI_RA(&ahp
->ah_iniAddac
, 7, 1) = (INI_RA(&ahp
->ah_iniAddac
,
2075 7, 1) & (~0x18)) | biaslevel
<< 3;
2077 INI_RA(&ahp
->ah_iniAddac
, 6, 1) = (INI_RA(&ahp
->ah_iniAddac
,
2078 6, 1) & (~0xc0)) | biaslevel
<< 6;
2083 static void ath9k_hw_set_4k_addac(struct ath_hal
*ah
,
2084 struct ath9k_channel
*chan
)
2086 struct modal_eep_4k_header
*pModal
;
2087 struct ath_hal_5416
*ahp
= AH5416(ah
);
2088 struct ar5416_eeprom_4k
*eep
= &ahp
->ah_eeprom
.map4k
;
2091 if (ah
->ah_macVersion
!= AR_SREV_VERSION_9160
)
2094 if (ar5416_get_eep_rev(ahp
) < AR5416_EEP_MINOR_VER_7
)
2097 pModal
= &eep
->modalHeader
;
2099 if (pModal
->xpaBiasLvl
!= 0xff) {
2100 biaslevel
= pModal
->xpaBiasLvl
;
2101 INI_RA(&ahp
->ah_iniAddac
, 7, 1) =
2102 (INI_RA(&ahp
->ah_iniAddac
, 7, 1) & (~0x18)) | biaslevel
<< 3;
2106 static void (*ath9k_set_addac
[]) (struct ath_hal
*, struct ath9k_channel
*) = {
2107 ath9k_hw_set_def_addac
,
2108 ath9k_hw_set_4k_addac
2111 void ath9k_hw_set_addac(struct ath_hal
*ah
, struct ath9k_channel
*chan
)
2113 struct ath_hal_5416
*ahp
= AH5416(ah
);
2115 ath9k_set_addac
[ahp
->ah_eep_map
](ah
, chan
);
2120 /* XXX: Clean me up, make me more legible */
2121 static bool ath9k_hw_eeprom_set_def_board_values(struct ath_hal
*ah
,
2122 struct ath9k_channel
*chan
)
2124 struct modal_eep_header
*pModal
;
2125 struct ath_hal_5416
*ahp
= AH5416(ah
);
2126 struct ar5416_eeprom_def
*eep
= &ahp
->ah_eeprom
.def
;
2127 int i
, regChainOffset
;
2131 pModal
= &(eep
->modalHeader
[IS_CHAN_2GHZ(chan
)]);
2133 txRxAttenLocal
= IS_CHAN_2GHZ(chan
) ? 23 : 44;
2135 ath9k_hw_get_eeprom_antenna_cfg(ah
, chan
, 0, &ant_config
);
2136 REG_WRITE(ah
, AR_PHY_SWITCH_COM
, ant_config
);
2138 for (i
= 0; i
< AR5416_MAX_CHAINS
; i
++) {
2139 if (AR_SREV_9280(ah
)) {
2144 if (AR_SREV_5416_V20_OR_LATER(ah
) &&
2145 (ahp
->ah_rxchainmask
== 5 || ahp
->ah_txchainmask
== 5)
2147 regChainOffset
= (i
== 1) ? 0x2000 : 0x1000;
2149 regChainOffset
= i
* 0x1000;
2151 REG_WRITE(ah
, AR_PHY_SWITCH_CHAIN_0
+ regChainOffset
,
2152 pModal
->antCtrlChain
[i
]);
2154 REG_WRITE(ah
, AR_PHY_TIMING_CTRL4(0) + regChainOffset
,
2156 AR_PHY_TIMING_CTRL4(0) +
2158 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF
|
2159 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF
)) |
2160 SM(pModal
->iqCalICh
[i
],
2161 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF
) |
2162 SM(pModal
->iqCalQCh
[i
],
2163 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF
));
2165 if ((i
== 0) || AR_SREV_5416_V20_OR_LATER(ah
)) {
2166 if ((eep
->baseEepHeader
.version
&
2167 AR5416_EEP_VER_MINOR_MASK
) >=
2168 AR5416_EEP_MINOR_VER_3
) {
2169 txRxAttenLocal
= pModal
->txRxAttenCh
[i
];
2170 if (AR_SREV_9280_10_OR_LATER(ah
)) {
2174 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN
,
2180 AR_PHY_GAIN_2GHZ_XATTEN1_DB
,
2186 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN
,
2192 AR_PHY_GAIN_2GHZ_XATTEN2_DB
,
2202 ~AR_PHY_GAIN_2GHZ_BSW_MARGIN
)
2205 AR_PHY_GAIN_2GHZ_BSW_MARGIN
));
2212 ~AR_PHY_GAIN_2GHZ_BSW_ATTEN
)
2213 | SM(pModal
->bswAtten
[i
],
2214 AR_PHY_GAIN_2GHZ_BSW_ATTEN
));
2217 if (AR_SREV_9280_10_OR_LATER(ah
)) {
2221 AR9280_PHY_RXGAIN_TXRX_ATTEN
,
2226 AR9280_PHY_RXGAIN_TXRX_MARGIN
,
2227 pModal
->rxTxMarginCh
[i
]);
2230 AR_PHY_RXGAIN
+ regChainOffset
,
2234 ~AR_PHY_RXGAIN_TXRX_ATTEN
) |
2236 AR_PHY_RXGAIN_TXRX_ATTEN
));
2243 ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN
) |
2244 SM(pModal
->rxTxMarginCh
[i
],
2245 AR_PHY_GAIN_2GHZ_RXTX_MARGIN
));
2250 if (AR_SREV_9280_10_OR_LATER(ah
)) {
2251 if (IS_CHAN_2GHZ(chan
)) {
2252 ath9k_hw_analog_shift_rmw(ah
, AR_AN_RF2G1_CH0
,
2254 AR_AN_RF2G1_CH0_OB_S
,
2256 ath9k_hw_analog_shift_rmw(ah
, AR_AN_RF2G1_CH0
,
2258 AR_AN_RF2G1_CH0_DB_S
,
2260 ath9k_hw_analog_shift_rmw(ah
, AR_AN_RF2G1_CH1
,
2262 AR_AN_RF2G1_CH1_OB_S
,
2264 ath9k_hw_analog_shift_rmw(ah
, AR_AN_RF2G1_CH1
,
2266 AR_AN_RF2G1_CH1_DB_S
,
2269 ath9k_hw_analog_shift_rmw(ah
, AR_AN_RF5G1_CH0
,
2270 AR_AN_RF5G1_CH0_OB5
,
2271 AR_AN_RF5G1_CH0_OB5_S
,
2273 ath9k_hw_analog_shift_rmw(ah
, AR_AN_RF5G1_CH0
,
2274 AR_AN_RF5G1_CH0_DB5
,
2275 AR_AN_RF5G1_CH0_DB5_S
,
2277 ath9k_hw_analog_shift_rmw(ah
, AR_AN_RF5G1_CH1
,
2278 AR_AN_RF5G1_CH1_OB5
,
2279 AR_AN_RF5G1_CH1_OB5_S
,
2281 ath9k_hw_analog_shift_rmw(ah
, AR_AN_RF5G1_CH1
,
2282 AR_AN_RF5G1_CH1_DB5
,
2283 AR_AN_RF5G1_CH1_DB5_S
,
2286 ath9k_hw_analog_shift_rmw(ah
, AR_AN_TOP2
,
2287 AR_AN_TOP2_XPABIAS_LVL
,
2288 AR_AN_TOP2_XPABIAS_LVL_S
,
2289 pModal
->xpaBiasLvl
);
2290 ath9k_hw_analog_shift_rmw(ah
, AR_AN_TOP2
,
2291 AR_AN_TOP2_LOCALBIAS
,
2292 AR_AN_TOP2_LOCALBIAS_S
,
2293 pModal
->local_bias
);
2294 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
, "ForceXPAon: %d\n",
2295 pModal
->force_xpaon
);
2296 REG_RMW_FIELD(ah
, AR_PHY_XPA_CFG
, AR_PHY_FORCE_XPA_CFG
,
2297 pModal
->force_xpaon
);
2300 REG_RMW_FIELD(ah
, AR_PHY_SETTLING
, AR_PHY_SETTLING_SWITCH
,
2301 pModal
->switchSettling
);
2302 REG_RMW_FIELD(ah
, AR_PHY_DESIRED_SZ
, AR_PHY_DESIRED_SZ_ADC
,
2303 pModal
->adcDesiredSize
);
2305 if (!AR_SREV_9280_10_OR_LATER(ah
))
2306 REG_RMW_FIELD(ah
, AR_PHY_DESIRED_SZ
,
2307 AR_PHY_DESIRED_SZ_PGA
,
2308 pModal
->pgaDesiredSize
);
2310 REG_WRITE(ah
, AR_PHY_RF_CTL4
,
2311 SM(pModal
->txEndToXpaOff
, AR_PHY_RF_CTL4_TX_END_XPAA_OFF
)
2312 | SM(pModal
->txEndToXpaOff
,
2313 AR_PHY_RF_CTL4_TX_END_XPAB_OFF
)
2314 | SM(pModal
->txFrameToXpaOn
,
2315 AR_PHY_RF_CTL4_FRAME_XPAA_ON
)
2316 | SM(pModal
->txFrameToXpaOn
,
2317 AR_PHY_RF_CTL4_FRAME_XPAB_ON
));
2319 REG_RMW_FIELD(ah
, AR_PHY_RF_CTL3
, AR_PHY_TX_END_TO_A2_RX_ON
,
2320 pModal
->txEndToRxOn
);
2321 if (AR_SREV_9280_10_OR_LATER(ah
)) {
2322 REG_RMW_FIELD(ah
, AR_PHY_CCA
, AR9280_PHY_CCA_THRESH62
,
2324 REG_RMW_FIELD(ah
, AR_PHY_EXT_CCA0
,
2325 AR_PHY_EXT_CCA0_THRESH62
,
2328 REG_RMW_FIELD(ah
, AR_PHY_CCA
, AR_PHY_CCA_THRESH62
,
2330 REG_RMW_FIELD(ah
, AR_PHY_EXT_CCA
,
2331 AR_PHY_EXT_CCA_THRESH62
,
2335 if ((eep
->baseEepHeader
.version
& AR5416_EEP_VER_MINOR_MASK
) >=
2336 AR5416_EEP_MINOR_VER_2
) {
2337 REG_RMW_FIELD(ah
, AR_PHY_RF_CTL2
,
2338 AR_PHY_TX_END_DATA_START
,
2339 pModal
->txFrameToDataStart
);
2340 REG_RMW_FIELD(ah
, AR_PHY_RF_CTL2
, AR_PHY_TX_END_PA_ON
,
2341 pModal
->txFrameToPaOn
);
2344 if ((eep
->baseEepHeader
.version
& AR5416_EEP_VER_MINOR_MASK
) >=
2345 AR5416_EEP_MINOR_VER_3
) {
2346 if (IS_CHAN_HT40(chan
))
2347 REG_RMW_FIELD(ah
, AR_PHY_SETTLING
,
2348 AR_PHY_SETTLING_SWITCH
,
2349 pModal
->swSettleHt40
);
2355 static bool ath9k_hw_eeprom_set_4k_board_values(struct ath_hal
*ah
,
2356 struct ath9k_channel
*chan
)
2358 struct modal_eep_4k_header
*pModal
;
2359 struct ath_hal_5416
*ahp
= AH5416(ah
);
2360 struct ar5416_eeprom_4k
*eep
= &ahp
->ah_eeprom
.map4k
;
2364 u8 ob
[5], db1
[5], db2
[5];
2365 u8 ant_div_control1
, ant_div_control2
;
2369 pModal
= &eep
->modalHeader
;
2371 txRxAttenLocal
= 23;
2373 ath9k_hw_get_eeprom_antenna_cfg(ah
, chan
, 0, &ant_config
);
2374 REG_WRITE(ah
, AR_PHY_SWITCH_COM
, ant_config
);
2377 REG_WRITE(ah
, AR_PHY_SWITCH_CHAIN_0
+ regChainOffset
,
2378 pModal
->antCtrlChain
[0]);
2380 REG_WRITE(ah
, AR_PHY_TIMING_CTRL4(0) + regChainOffset
,
2381 (REG_READ(ah
, AR_PHY_TIMING_CTRL4(0) + regChainOffset
) &
2382 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF
|
2383 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF
)) |
2384 SM(pModal
->iqCalICh
[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF
) |
2385 SM(pModal
->iqCalQCh
[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF
));
2387 if ((eep
->baseEepHeader
.version
& AR5416_EEP_VER_MINOR_MASK
) >=
2388 AR5416_EEP_MINOR_VER_3
) {
2389 txRxAttenLocal
= pModal
->txRxAttenCh
[0];
2390 REG_RMW_FIELD(ah
, AR_PHY_GAIN_2GHZ
+ regChainOffset
,
2391 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN
, pModal
->bswMargin
[0]);
2392 REG_RMW_FIELD(ah
, AR_PHY_GAIN_2GHZ
+ regChainOffset
,
2393 AR_PHY_GAIN_2GHZ_XATTEN1_DB
, pModal
->bswAtten
[0]);
2394 REG_RMW_FIELD(ah
, AR_PHY_GAIN_2GHZ
+ regChainOffset
,
2395 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN
,
2396 pModal
->xatten2Margin
[0]);
2397 REG_RMW_FIELD(ah
, AR_PHY_GAIN_2GHZ
+ regChainOffset
,
2398 AR_PHY_GAIN_2GHZ_XATTEN2_DB
, pModal
->xatten2Db
[0]);
2401 REG_RMW_FIELD(ah
, AR_PHY_RXGAIN
+ regChainOffset
,
2402 AR9280_PHY_RXGAIN_TXRX_ATTEN
, txRxAttenLocal
);
2403 REG_RMW_FIELD(ah
, AR_PHY_RXGAIN
+ regChainOffset
,
2404 AR9280_PHY_RXGAIN_TXRX_MARGIN
, pModal
->rxTxMarginCh
[0]);
2406 if (AR_SREV_9285_11(ah
))
2407 REG_WRITE(ah
, AR9285_AN_TOP4
, (AR9285_AN_TOP4_DEFAULT
| 0x14));
2409 /* Initialize Ant Diversity settings from EEPROM */
2410 if (pModal
->version
== 3) {
2411 ant_div_control1
= ((pModal
->ob_234
>> 12) & 0xf);
2412 ant_div_control2
= ((pModal
->db1_234
>> 12) & 0xf);
2413 regVal
= REG_READ(ah
, 0x99ac);
2414 regVal
&= (~(0x7f000000));
2415 regVal
|= ((ant_div_control1
& 0x1) << 24);
2416 regVal
|= (((ant_div_control1
>> 1) & 0x1) << 29);
2417 regVal
|= (((ant_div_control1
>> 2) & 0x1) << 30);
2418 regVal
|= ((ant_div_control2
& 0x3) << 25);
2419 regVal
|= (((ant_div_control2
>> 2) & 0x3) << 27);
2420 REG_WRITE(ah
, 0x99ac, regVal
);
2421 regVal
= REG_READ(ah
, 0x99ac);
2422 regVal
= REG_READ(ah
, 0xa208);
2423 regVal
&= (~(0x1 << 13));
2424 regVal
|= (((ant_div_control1
>> 3) & 0x1) << 13);
2425 REG_WRITE(ah
, 0xa208, regVal
);
2426 regVal
= REG_READ(ah
, 0xa208);
2429 if (pModal
->version
>= 2) {
2430 ob
[0] = (pModal
->ob_01
& 0xf);
2431 ob
[1] = (pModal
->ob_01
>> 4) & 0xf;
2432 ob
[2] = (pModal
->ob_234
& 0xf);
2433 ob
[3] = ((pModal
->ob_234
>> 4) & 0xf);
2434 ob
[4] = ((pModal
->ob_234
>> 8) & 0xf);
2436 db1
[0] = (pModal
->db1_01
& 0xf);
2437 db1
[1] = ((pModal
->db1_01
>> 4) & 0xf);
2438 db1
[2] = (pModal
->db1_234
& 0xf);
2439 db1
[3] = ((pModal
->db1_234
>> 4) & 0xf);
2440 db1
[4] = ((pModal
->db1_234
>> 8) & 0xf);
2442 db2
[0] = (pModal
->db2_01
& 0xf);
2443 db2
[1] = ((pModal
->db2_01
>> 4) & 0xf);
2444 db2
[2] = (pModal
->db2_234
& 0xf);
2445 db2
[3] = ((pModal
->db2_234
>> 4) & 0xf);
2446 db2
[4] = ((pModal
->db2_234
>> 8) & 0xf);
2448 } else if (pModal
->version
== 1) {
2450 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
2451 "EEPROM Model version is set to 1 \n");
2452 ob
[0] = (pModal
->ob_01
& 0xf);
2453 ob
[1] = ob
[2] = ob
[3] = ob
[4] = (pModal
->ob_01
>> 4) & 0xf;
2454 db1
[0] = (pModal
->db1_01
& 0xf);
2455 db1
[1] = db1
[2] = db1
[3] =
2456 db1
[4] = ((pModal
->db1_01
>> 4) & 0xf);
2457 db2
[0] = (pModal
->db2_01
& 0xf);
2458 db2
[1] = db2
[2] = db2
[3] =
2459 db2
[4] = ((pModal
->db2_01
>> 4) & 0xf);
2462 for (i
= 0; i
< 5; i
++) {
2463 ob
[i
] = pModal
->ob_01
;
2464 db1
[i
] = pModal
->db1_01
;
2465 db2
[i
] = pModal
->db1_01
;
2469 ath9k_hw_analog_shift_rmw(ah
, AR9285_AN_RF2G3
,
2470 AR9285_AN_RF2G3_OB_0
, AR9285_AN_RF2G3_OB_0_S
, ob
[0]);
2471 ath9k_hw_analog_shift_rmw(ah
, AR9285_AN_RF2G3
,
2472 AR9285_AN_RF2G3_OB_1
, AR9285_AN_RF2G3_OB_1_S
, ob
[1]);
2473 ath9k_hw_analog_shift_rmw(ah
, AR9285_AN_RF2G3
,
2474 AR9285_AN_RF2G3_OB_2
, AR9285_AN_RF2G3_OB_2_S
, ob
[2]);
2475 ath9k_hw_analog_shift_rmw(ah
, AR9285_AN_RF2G3
,
2476 AR9285_AN_RF2G3_OB_3
, AR9285_AN_RF2G3_OB_3_S
, ob
[3]);
2477 ath9k_hw_analog_shift_rmw(ah
, AR9285_AN_RF2G3
,
2478 AR9285_AN_RF2G3_OB_4
, AR9285_AN_RF2G3_OB_4_S
, ob
[4]);
2480 ath9k_hw_analog_shift_rmw(ah
, AR9285_AN_RF2G3
,
2481 AR9285_AN_RF2G3_DB1_0
, AR9285_AN_RF2G3_DB1_0_S
, db1
[0]);
2482 ath9k_hw_analog_shift_rmw(ah
, AR9285_AN_RF2G3
,
2483 AR9285_AN_RF2G3_DB1_1
, AR9285_AN_RF2G3_DB1_1_S
, db1
[1]);
2484 ath9k_hw_analog_shift_rmw(ah
, AR9285_AN_RF2G3
,
2485 AR9285_AN_RF2G3_DB1_2
, AR9285_AN_RF2G3_DB1_2_S
, db1
[2]);
2486 ath9k_hw_analog_shift_rmw(ah
, AR9285_AN_RF2G4
,
2487 AR9285_AN_RF2G4_DB1_3
, AR9285_AN_RF2G4_DB1_3_S
, db1
[3]);
2488 ath9k_hw_analog_shift_rmw(ah
, AR9285_AN_RF2G4
,
2489 AR9285_AN_RF2G4_DB1_4
, AR9285_AN_RF2G4_DB1_4_S
, db1
[4]);
2491 ath9k_hw_analog_shift_rmw(ah
, AR9285_AN_RF2G4
,
2492 AR9285_AN_RF2G4_DB2_0
, AR9285_AN_RF2G4_DB2_0_S
, db2
[0]);
2493 ath9k_hw_analog_shift_rmw(ah
, AR9285_AN_RF2G4
,
2494 AR9285_AN_RF2G4_DB2_1
, AR9285_AN_RF2G4_DB2_1_S
, db2
[1]);
2495 ath9k_hw_analog_shift_rmw(ah
, AR9285_AN_RF2G4
,
2496 AR9285_AN_RF2G4_DB2_2
, AR9285_AN_RF2G4_DB2_2_S
, db2
[2]);
2497 ath9k_hw_analog_shift_rmw(ah
, AR9285_AN_RF2G4
,
2498 AR9285_AN_RF2G4_DB2_3
, AR9285_AN_RF2G4_DB2_3_S
, db2
[3]);
2499 ath9k_hw_analog_shift_rmw(ah
, AR9285_AN_RF2G4
,
2500 AR9285_AN_RF2G4_DB2_4
, AR9285_AN_RF2G4_DB2_4_S
, db2
[4]);
2503 if (AR_SREV_9285_11(ah
))
2504 REG_WRITE(ah
, AR9285_AN_TOP4
, AR9285_AN_TOP4_DEFAULT
);
2506 REG_RMW_FIELD(ah
, AR_PHY_SETTLING
, AR_PHY_SETTLING_SWITCH
,
2507 pModal
->switchSettling
);
2508 REG_RMW_FIELD(ah
, AR_PHY_DESIRED_SZ
, AR_PHY_DESIRED_SZ_ADC
,
2509 pModal
->adcDesiredSize
);
2511 REG_WRITE(ah
, AR_PHY_RF_CTL4
,
2512 SM(pModal
->txEndToXpaOff
, AR_PHY_RF_CTL4_TX_END_XPAA_OFF
) |
2513 SM(pModal
->txEndToXpaOff
, AR_PHY_RF_CTL4_TX_END_XPAB_OFF
) |
2514 SM(pModal
->txFrameToXpaOn
, AR_PHY_RF_CTL4_FRAME_XPAA_ON
) |
2515 SM(pModal
->txFrameToXpaOn
, AR_PHY_RF_CTL4_FRAME_XPAB_ON
));
2517 REG_RMW_FIELD(ah
, AR_PHY_RF_CTL3
, AR_PHY_TX_END_TO_A2_RX_ON
,
2518 pModal
->txEndToRxOn
);
2519 REG_RMW_FIELD(ah
, AR_PHY_CCA
, AR9280_PHY_CCA_THRESH62
,
2521 REG_RMW_FIELD(ah
, AR_PHY_EXT_CCA0
, AR_PHY_EXT_CCA0_THRESH62
,
2524 if ((eep
->baseEepHeader
.version
& AR5416_EEP_VER_MINOR_MASK
) >=
2525 AR5416_EEP_MINOR_VER_2
) {
2526 REG_RMW_FIELD(ah
, AR_PHY_RF_CTL2
, AR_PHY_TX_END_DATA_START
,
2527 pModal
->txFrameToDataStart
);
2528 REG_RMW_FIELD(ah
, AR_PHY_RF_CTL2
, AR_PHY_TX_END_PA_ON
,
2529 pModal
->txFrameToPaOn
);
2532 if ((eep
->baseEepHeader
.version
& AR5416_EEP_VER_MINOR_MASK
) >=
2533 AR5416_EEP_MINOR_VER_3
) {
2534 if (IS_CHAN_HT40(chan
))
2535 REG_RMW_FIELD(ah
, AR_PHY_SETTLING
,
2536 AR_PHY_SETTLING_SWITCH
,
2537 pModal
->swSettleHt40
);
2543 static bool (*ath9k_eeprom_set_board_values
[])(struct ath_hal
*,
2544 struct ath9k_channel
*) = {
2545 ath9k_hw_eeprom_set_def_board_values
,
2546 ath9k_hw_eeprom_set_4k_board_values
2549 bool ath9k_hw_eeprom_set_board_values(struct ath_hal
*ah
,
2550 struct ath9k_channel
*chan
)
2552 struct ath_hal_5416
*ahp
= AH5416(ah
);
2554 return ath9k_eeprom_set_board_values
[ahp
->ah_eep_map
](ah
, chan
);
2557 static int ath9k_hw_get_def_eeprom_antenna_cfg(struct ath_hal
*ah
,
2558 struct ath9k_channel
*chan
,
2559 u8 index
, u16
*config
)
2561 struct ath_hal_5416
*ahp
= AH5416(ah
);
2562 struct ar5416_eeprom_def
*eep
= &ahp
->ah_eeprom
.def
;
2563 struct modal_eep_header
*pModal
=
2564 &(eep
->modalHeader
[IS_CHAN_2GHZ(chan
)]);
2565 struct base_eep_header
*pBase
= &eep
->baseEepHeader
;
2569 *config
= pModal
->antCtrlCommon
& 0xFFFF;
2572 if (pBase
->version
>= 0x0E0D) {
2573 if (pModal
->useAnt1
) {
2575 ((pModal
->antCtrlCommon
& 0xFFFF0000) >> 16);
2587 static int ath9k_hw_get_4k_eeprom_antenna_cfg(struct ath_hal
*ah
,
2588 struct ath9k_channel
*chan
,
2589 u8 index
, u16
*config
)
2591 struct ath_hal_5416
*ahp
= AH5416(ah
);
2592 struct ar5416_eeprom_4k
*eep
= &ahp
->ah_eeprom
.map4k
;
2593 struct modal_eep_4k_header
*pModal
= &eep
->modalHeader
;
2597 *config
= pModal
->antCtrlCommon
& 0xFFFF;
2606 static int (*ath9k_get_eeprom_antenna_cfg
[])(struct ath_hal
*,
2607 struct ath9k_channel
*,
2609 ath9k_hw_get_def_eeprom_antenna_cfg
,
2610 ath9k_hw_get_4k_eeprom_antenna_cfg
2613 int ath9k_hw_get_eeprom_antenna_cfg(struct ath_hal
*ah
,
2614 struct ath9k_channel
*chan
,
2615 u8 index
, u16
*config
)
2617 struct ath_hal_5416
*ahp
= AH5416(ah
);
2619 return ath9k_get_eeprom_antenna_cfg
[ahp
->ah_eep_map
](ah
, chan
,
2623 static u8
ath9k_hw_get_4k_num_ant_config(struct ath_hal
*ah
,
2624 enum ieee80211_band freq_band
)
2629 static u8
ath9k_hw_get_def_num_ant_config(struct ath_hal
*ah
,
2630 enum ieee80211_band freq_band
)
2632 struct ath_hal_5416
*ahp
= AH5416(ah
);
2633 struct ar5416_eeprom_def
*eep
= &ahp
->ah_eeprom
.def
;
2634 struct modal_eep_header
*pModal
=
2635 &(eep
->modalHeader
[ATH9K_HAL_FREQ_BAND_2GHZ
== freq_band
]);
2636 struct base_eep_header
*pBase
= &eep
->baseEepHeader
;
2641 if (pBase
->version
>= 0x0E0D)
2642 if (pModal
->useAnt1
)
2643 num_ant_config
+= 1;
2645 return num_ant_config
;
2648 static u8 (*ath9k_get_num_ant_config
[])(struct ath_hal
*,
2649 enum ieee80211_band
) = {
2650 ath9k_hw_get_def_num_ant_config
,
2651 ath9k_hw_get_4k_num_ant_config
2654 u8
ath9k_hw_get_num_ant_config(struct ath_hal
*ah
,
2655 enum ieee80211_band freq_band
)
2657 struct ath_hal_5416
*ahp
= AH5416(ah
);
2659 return ath9k_get_num_ant_config
[ahp
->ah_eep_map
](ah
, freq_band
);
2662 u16
ath9k_hw_eeprom_get_spur_chan(struct ath_hal
*ah
, u16 i
, bool is2GHz
)
2664 #define EEP_MAP4K_SPURCHAN \
2665 (ahp->ah_eeprom.map4k.modalHeader.spurChans[i].spurChan)
2666 #define EEP_DEF_SPURCHAN \
2667 (ahp->ah_eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan)
2668 struct ath_hal_5416
*ahp
= AH5416(ah
);
2669 u16 spur_val
= AR_NO_SPUR
;
2671 DPRINTF(ah
->ah_sc
, ATH_DBG_ANI
,
2672 "Getting spur idx %d is2Ghz. %d val %x\n",
2673 i
, is2GHz
, ah
->ah_config
.spurchans
[i
][is2GHz
]);
2675 switch (ah
->ah_config
.spurmode
) {
2678 case SPUR_ENABLE_IOCTL
:
2679 spur_val
= ah
->ah_config
.spurchans
[i
][is2GHz
];
2680 DPRINTF(ah
->ah_sc
, ATH_DBG_ANI
,
2681 "Getting spur val from new loc. %d\n", spur_val
);
2683 case SPUR_ENABLE_EEPROM
:
2684 if (ahp
->ah_eep_map
== EEP_MAP_4KBITS
)
2685 spur_val
= EEP_MAP4K_SPURCHAN
;
2687 spur_val
= EEP_DEF_SPURCHAN
;
2693 #undef EEP_DEF_SPURCHAN
2694 #undef EEP_MAP4K_SPURCHAN
2697 static u32
ath9k_hw_get_eeprom_4k(struct ath_hal
*ah
,
2698 enum eeprom_param param
)
2700 struct ath_hal_5416
*ahp
= AH5416(ah
);
2701 struct ar5416_eeprom_4k
*eep
= &ahp
->ah_eeprom
.map4k
;
2702 struct modal_eep_4k_header
*pModal
= &eep
->modalHeader
;
2703 struct base_eep_header_4k
*pBase
= &eep
->baseEepHeader
;
2706 case EEP_NFTHRESH_2
:
2707 return pModal
[1].noiseFloorThreshCh
[0];
2708 case AR_EEPROM_MAC(0):
2709 return pBase
->macAddr
[0] << 8 | pBase
->macAddr
[1];
2710 case AR_EEPROM_MAC(1):
2711 return pBase
->macAddr
[2] << 8 | pBase
->macAddr
[3];
2712 case AR_EEPROM_MAC(2):
2713 return pBase
->macAddr
[4] << 8 | pBase
->macAddr
[5];
2715 return pBase
->regDmn
[0];
2717 return pBase
->regDmn
[1];
2719 return pBase
->deviceCap
;
2721 return pBase
->opCapFlags
;
2723 return pBase
->rfSilent
;
2725 return pModal
->ob_01
;
2727 return pModal
->db1_01
;
2729 return pBase
->version
& AR5416_EEP_VER_MINOR_MASK
;
2731 return pBase
->txMask
;
2733 return pBase
->rxMask
;
2739 static u32
ath9k_hw_get_eeprom_def(struct ath_hal
*ah
,
2740 enum eeprom_param param
)
2742 struct ath_hal_5416
*ahp
= AH5416(ah
);
2743 struct ar5416_eeprom_def
*eep
= &ahp
->ah_eeprom
.def
;
2744 struct modal_eep_header
*pModal
= eep
->modalHeader
;
2745 struct base_eep_header
*pBase
= &eep
->baseEepHeader
;
2748 case EEP_NFTHRESH_5
:
2749 return pModal
[0].noiseFloorThreshCh
[0];
2750 case EEP_NFTHRESH_2
:
2751 return pModal
[1].noiseFloorThreshCh
[0];
2752 case AR_EEPROM_MAC(0):
2753 return pBase
->macAddr
[0] << 8 | pBase
->macAddr
[1];
2754 case AR_EEPROM_MAC(1):
2755 return pBase
->macAddr
[2] << 8 | pBase
->macAddr
[3];
2756 case AR_EEPROM_MAC(2):
2757 return pBase
->macAddr
[4] << 8 | pBase
->macAddr
[5];
2759 return pBase
->regDmn
[0];
2761 return pBase
->regDmn
[1];
2763 return pBase
->deviceCap
;
2765 return pBase
->opCapFlags
;
2767 return pBase
->rfSilent
;
2769 return pModal
[0].ob
;
2771 return pModal
[0].db
;
2773 return pModal
[1].ob
;
2775 return pModal
[1].db
;
2777 return pBase
->version
& AR5416_EEP_VER_MINOR_MASK
;
2779 return pBase
->txMask
;
2781 return pBase
->rxMask
;
2782 case EEP_RXGAIN_TYPE
:
2783 return pBase
->rxGainType
;
2784 case EEP_TXGAIN_TYPE
:
2785 return pBase
->txGainType
;
2792 static u32 (*ath9k_get_eeprom
[])(struct ath_hal
*, enum eeprom_param
) = {
2793 ath9k_hw_get_eeprom_def
,
2794 ath9k_hw_get_eeprom_4k
2797 u32
ath9k_hw_get_eeprom(struct ath_hal
*ah
,
2798 enum eeprom_param param
)
2800 struct ath_hal_5416
*ahp
= AH5416(ah
);
2802 return ath9k_get_eeprom
[ahp
->ah_eep_map
](ah
, param
);
2805 int ath9k_hw_eeprom_attach(struct ath_hal
*ah
)
2808 struct ath_hal_5416
*ahp
= AH5416(ah
);
2810 if (ath9k_hw_use_flash(ah
))
2811 ath9k_hw_flash_map(ah
);
2813 if (AR_SREV_9285(ah
))
2814 ahp
->ah_eep_map
= EEP_MAP_4KBITS
;
2816 ahp
->ah_eep_map
= EEP_MAP_DEFAULT
;
2818 if (!ath9k_hw_fill_eeprom(ah
))
2821 status
= ath9k_hw_check_eeprom(ah
);