2 * Copyright (c) 2008-2009 Sam Leffler, Errno Consulting
3 * Copyright (c) 2008 Atheros Communications, Inc.
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 * $FreeBSD: head/sys/dev/ath/ath_hal/ar5416/ar9280_attach.c 203930 2010-02-15 17:49:49Z rpaulo $
22 #include "ah_internal.h"
25 #include "ah_eeprom_v14.h" /* XXX for tx/rx gain */
27 #include "ar5416/ar9280.h"
28 #include "ar5416/ar5416reg.h"
29 #include "ar5416/ar5416phy.h"
31 #include "ar5416/ar9280v1.ini"
32 #include "ar5416/ar9280v2.ini"
34 static const HAL_PERCAL_DATA ar9280_iq_cal
= { /* single sample */
35 .calName
= "IQ", .calType
= IQ_MISMATCH_CAL
,
36 .calNumSamples
= MIN_CAL_SAMPLES
,
37 .calCountMax
= PER_MAX_LOG_COUNT
,
38 .calCollect
= ar5416IQCalCollect
,
39 .calPostProc
= ar5416IQCalibration
41 static const HAL_PERCAL_DATA ar9280_adc_gain_cal
= { /* single sample */
42 .calName
= "ADC Gain", .calType
= ADC_GAIN_CAL
,
43 .calNumSamples
= MIN_CAL_SAMPLES
,
44 .calCountMax
= PER_MIN_LOG_COUNT
,
45 .calCollect
= ar5416AdcGainCalCollect
,
46 .calPostProc
= ar5416AdcGainCalibration
48 static const HAL_PERCAL_DATA ar9280_adc_dc_cal
= { /* single sample */
49 .calName
= "ADC DC", .calType
= ADC_DC_CAL
,
50 .calNumSamples
= MIN_CAL_SAMPLES
,
51 .calCountMax
= PER_MIN_LOG_COUNT
,
52 .calCollect
= ar5416AdcDcCalCollect
,
53 .calPostProc
= ar5416AdcDcCalibration
55 static const HAL_PERCAL_DATA ar9280_adc_init_dc_cal
= {
56 .calName
= "ADC Init DC", .calType
= ADC_DC_INIT_CAL
,
57 .calNumSamples
= MIN_CAL_SAMPLES
,
58 .calCountMax
= INIT_LOG_COUNT
,
59 .calCollect
= ar5416AdcDcCalCollect
,
60 .calPostProc
= ar5416AdcDcCalibration
63 static void ar9280ConfigPCIE(struct ath_hal
*ah
, HAL_BOOL restore
);
64 static HAL_BOOL
ar9280FillCapabilityInfo(struct ath_hal
*ah
);
65 static void ar9280WriteIni(struct ath_hal
*ah
,
66 const struct ieee80211_channel
*chan
);
69 ar9280AniSetup(struct ath_hal
*ah
)
71 /* NB: disable ANI for reliable RIFS rx */
72 ar5212AniAttach(ah
, AH_NULL
, AH_NULL
, AH_FALSE
);
76 * Attach for an AR9280 part.
78 static struct ath_hal
*
79 ar9280Attach(uint16_t devid
, HAL_SOFTC sc
,
80 HAL_BUS_TAG st
, HAL_BUS_HANDLE sh
, HAL_STATUS
*status
)
82 struct ath_hal_9280
*ahp9280
;
83 struct ath_hal_5212
*ahp
;
89 HALDEBUG(AH_NULL
, HAL_DEBUG_ATTACH
, "%s: sc %p st %p sh %p\n",
90 __func__
, sc
, (void*) st
, (void*) sh
);
92 /* NB: memory is returned zero'd */
93 ahp9280
= ath_hal_malloc(sizeof (struct ath_hal_9280
));
94 if (ahp9280
== AH_NULL
) {
95 HALDEBUG(AH_NULL
, HAL_DEBUG_ANY
,
96 "%s: cannot allocate memory for state block\n", __func__
);
100 ahp
= AH5212(ahp9280
);
101 ah
= &ahp
->ah_priv
.h
;
103 ar5416InitState(AH5416(ah
), devid
, sc
, st
, sh
, status
);
105 /* XXX override with 9280 specific state */
106 /* override 5416 methods for our needs */
107 ah
->ah_setAntennaSwitch
= ar9280SetAntennaSwitch
;
108 ah
->ah_configPCIE
= ar9280ConfigPCIE
;
110 AH5416(ah
)->ah_cal
.iqCalData
.calData
= &ar9280_iq_cal
;
111 AH5416(ah
)->ah_cal
.adcGainCalData
.calData
= &ar9280_adc_gain_cal
;
112 AH5416(ah
)->ah_cal
.adcDcCalData
.calData
= &ar9280_adc_dc_cal
;
113 AH5416(ah
)->ah_cal
.adcDcCalInitData
.calData
= &ar9280_adc_init_dc_cal
;
114 AH5416(ah
)->ah_cal
.suppCals
= ADC_GAIN_CAL
| ADC_DC_CAL
| IQ_MISMATCH_CAL
;
116 AH5416(ah
)->ah_spurMitigate
= ar9280SpurMitigate
;
117 AH5416(ah
)->ah_writeIni
= ar9280WriteIni
;
118 AH5416(ah
)->ah_rx_chainmask
= AR9280_DEFAULT_RXCHAINMASK
;
119 AH5416(ah
)->ah_tx_chainmask
= AR9280_DEFAULT_TXCHAINMASK
;
121 if (!ar5416SetResetReg(ah
, HAL_RESET_POWER_ON
)) {
123 HALDEBUG(ah
, HAL_DEBUG_ANY
, "%s: couldn't reset chip\n",
129 if (!ar5416SetPowerMode(ah
, HAL_PM_AWAKE
, AH_TRUE
)) {
130 HALDEBUG(ah
, HAL_DEBUG_ANY
, "%s: couldn't wakeup chip\n",
135 /* Read Revisions from Chips before taking out of reset */
136 val
= OS_REG_READ(ah
, AR_SREV
);
137 HALDEBUG(ah
, HAL_DEBUG_ATTACH
,
138 "%s: ID 0x%x VERSION 0x%x TYPE 0x%x REVISION 0x%x\n",
139 __func__
, MS(val
, AR_XSREV_ID
), MS(val
, AR_XSREV_VERSION
),
140 MS(val
, AR_XSREV_TYPE
), MS(val
, AR_XSREV_REVISION
));
141 /* NB: include chip type to differentiate from pre-Sowl versions */
142 AH_PRIVATE(ah
)->ah_macVersion
=
143 (val
& AR_XSREV_VERSION
) >> AR_XSREV_TYPE_S
;
144 AH_PRIVATE(ah
)->ah_macRev
= MS(val
, AR_XSREV_REVISION
);
145 AH_PRIVATE(ah
)->ah_ispcie
= (val
& AR_XSREV_TYPE_HOST_MODE
) == 0;
147 /* setup common ini data; rf backends handle remainder */
148 if (AR_SREV_MERLIN_20_OR_LATER(ah
)) {
149 HAL_INI_INIT(&ahp
->ah_ini_modes
, ar9280Modes_v2
, 6);
150 HAL_INI_INIT(&ahp
->ah_ini_common
, ar9280Common_v2
, 2);
151 HAL_INI_INIT(&AH5416(ah
)->ah_ini_pcieserdes
,
152 ar9280PciePhy_clkreq_always_on_L1_v2
, 2);
153 HAL_INI_INIT(&ahp9280
->ah_ini_xmodes
,
154 ar9280Modes_fast_clock_v2
, 3);
156 HAL_INI_INIT(&ahp
->ah_ini_modes
, ar9280Modes_v1
, 6);
157 HAL_INI_INIT(&ahp
->ah_ini_common
, ar9280Common_v1
, 2);
158 HAL_INI_INIT(&AH5416(ah
)->ah_ini_pcieserdes
,
159 ar9280PciePhy_v1
, 2);
161 ar5416AttachPCIE(ah
);
163 ecode
= ath_hal_v14EepromAttach(ah
);
167 if (!ar5416ChipReset(ah
, AH_NULL
)) { /* reset chip */
168 HALDEBUG(ah
, HAL_DEBUG_ANY
, "%s: chip reset failed\n", __func__
);
173 AH_PRIVATE(ah
)->ah_phyRev
= OS_REG_READ(ah
, AR_PHY_CHIP_ID
);
175 if (!ar5212ChipTest(ah
)) {
176 HALDEBUG(ah
, HAL_DEBUG_ANY
, "%s: hardware self-test failed\n",
178 ecode
= HAL_ESELFTEST
;
183 * Set correct Baseband to analog shift
184 * setting to access analog chips.
186 OS_REG_WRITE(ah
, AR_PHY(0), 0x00000007);
188 /* Read Radio Chip Rev Extract */
189 AH_PRIVATE(ah
)->ah_analog5GhzRev
= ar5416GetRadioRev(ah
);
190 switch (AH_PRIVATE(ah
)->ah_analog5GhzRev
& AR_RADIO_SREV_MAJOR
) {
191 case AR_RAD2133_SREV_MAJOR
: /* Sowl: 2G/3x3 */
192 case AR_RAD5133_SREV_MAJOR
: /* Sowl: 2+5G/3x3 */
195 if (AH_PRIVATE(ah
)->ah_analog5GhzRev
== 0) {
196 AH_PRIVATE(ah
)->ah_analog5GhzRev
=
197 AR_RAD5133_SREV_MAJOR
;
201 HALDEBUG(ah
, HAL_DEBUG_ANY
,
202 "%s: 5G Radio Chip Rev 0x%02X is not supported by "
203 "this driver\n", __func__
,
204 AH_PRIVATE(ah
)->ah_analog5GhzRev
);
205 ecode
= HAL_ENOTSUPP
;
209 rfStatus
= ar9280RfAttach(ah
, &ecode
);
211 HALDEBUG(ah
, HAL_DEBUG_ANY
, "%s: RF setup failed, status %u\n",
216 if (AR_SREV_MERLIN_20_OR_LATER(ah
)) {
217 /* setup rxgain table */
218 switch (ath_hal_eepromGet(ah
, AR_EEP_RXGAIN_TYPE
, AH_NULL
)) {
219 case AR5416_EEP_RXGAIN_13dB_BACKOFF
:
220 HAL_INI_INIT(&ahp9280
->ah_ini_rxgain
,
221 ar9280Modes_backoff_13db_rxgain_v2
, 6);
223 case AR5416_EEP_RXGAIN_23dB_BACKOFF
:
224 HAL_INI_INIT(&ahp9280
->ah_ini_rxgain
,
225 ar9280Modes_backoff_23db_rxgain_v2
, 6);
227 case AR5416_EEP_RXGAIN_ORIG
:
228 HAL_INI_INIT(&ahp9280
->ah_ini_rxgain
,
229 ar9280Modes_original_rxgain_v2
, 6);
233 goto bad
; /* XXX ? try to continue */
236 if (AR_SREV_MERLIN_20_OR_LATER(ah
)) {
237 /* setp txgain table */
238 switch (ath_hal_eepromGet(ah
, AR_EEP_TXGAIN_TYPE
, AH_NULL
)) {
239 case AR5416_EEP_TXGAIN_HIGH_POWER
:
240 HAL_INI_INIT(&ahp9280
->ah_ini_txgain
,
241 ar9280Modes_high_power_tx_gain_v2
, 6);
243 case AR5416_EEP_TXGAIN_ORIG
:
244 HAL_INI_INIT(&ahp9280
->ah_ini_txgain
,
245 ar9280Modes_original_tx_gain_v2
, 6);
249 goto bad
; /* XXX ? try to continue */
254 * Got everything we need now to setup the capabilities.
256 if (!ar9280FillCapabilityInfo(ah
)) {
261 ecode
= ath_hal_eepromGet(ah
, AR_EEP_MACADDR
, ahp
->ah_macaddr
);
262 if (ecode
!= HAL_OK
) {
263 HALDEBUG(ah
, HAL_DEBUG_ANY
,
264 "%s: error getting mac address from EEPROM\n", __func__
);
267 /* XXX How about the serial number ? */
268 /* Read Reg Domain */
269 AH_PRIVATE(ah
)->ah_currentRD
=
270 ath_hal_eepromGet(ah
, AR_EEP_REGDMN_0
, AH_NULL
);
273 * ah_miscMode is populated by ar5416FillCapabilityInfo()
274 * starting from griffin. Set here to make sure that
275 * AR_MISC_MODE_MIC_NEW_LOC_ENABLE is set before a GTK is
276 * placed into hardware.
278 if (ahp
->ah_miscMode
!= 0)
279 OS_REG_WRITE(ah
, AR_MISC_MODE
, ahp
->ah_miscMode
);
281 ar9280AniSetup(ah
); /* Anti Noise Immunity */
282 ar5416InitNfHistBuff(AH5416(ah
)->ah_cal
.nfCalHist
);
284 HALDEBUG(ah
, HAL_DEBUG_ATTACH
, "%s: return\n", __func__
);
296 ar9280ConfigPCIE(struct ath_hal
*ah
, HAL_BOOL restore
)
298 if (AH_PRIVATE(ah
)->ah_ispcie
&& !restore
) {
299 ath_hal_ini_write(ah
, &AH5416(ah
)->ah_ini_pcieserdes
, 1, 0);
301 OS_REG_SET_BIT(ah
, AR_PCIE_PM_CTRL
, AR_PCIE_PM_CTRL_ENA
);
302 OS_REG_WRITE(ah
, AR_WA
, AR9280_WA_DEFAULT
);
307 ar9280WriteIni(struct ath_hal
*ah
, const struct ieee80211_channel
*chan
)
309 u_int modesIndex
, freqIndex
;
312 /* Setup the indices for the next set of register array writes */
313 /* XXX Ignore 11n dynamic mode on the AR5416 for the moment */
314 if (IEEE80211_IS_CHAN_2GHZ(chan
)) {
316 if (IEEE80211_IS_CHAN_HT40(chan
))
318 else if (IEEE80211_IS_CHAN_108G(chan
))
324 if (IEEE80211_IS_CHAN_HT40(chan
) ||
325 IEEE80211_IS_CHAN_TURBO(chan
))
331 /* Set correct Baseband to analog shift setting to access analog chips. */
332 OS_REG_WRITE(ah
, AR_PHY(0), 0x00000007);
333 OS_REG_WRITE(ah
, AR_PHY_ADC_SERIAL_CTL
, AR_PHY_SEL_INTERNAL_ADDAC
);
335 /* XXX Merlin ini fixups */
336 /* XXX Merlin 100us delay for shift registers */
337 regWrites
= ath_hal_ini_write(ah
, &AH5212(ah
)->ah_ini_modes
,
338 modesIndex
, regWrites
);
339 if (AR_SREV_MERLIN_20_OR_LATER(ah
)) {
340 regWrites
= ath_hal_ini_write(ah
, &AH9280(ah
)->ah_ini_rxgain
,
341 modesIndex
, regWrites
);
342 regWrites
= ath_hal_ini_write(ah
, &AH9280(ah
)->ah_ini_txgain
,
343 modesIndex
, regWrites
);
345 /* XXX Merlin 100us delay for shift registers */
346 regWrites
= ath_hal_ini_write(ah
, &AH5212(ah
)->ah_ini_common
,
349 if (AR_SREV_MERLIN_20(ah
) && IS_5GHZ_FAST_CLOCK_EN(ah
, chan
)) {
350 /* 5GHz channels w/ Fast Clock use different modal values */
351 regWrites
= ath_hal_ini_write(ah
, &AH9280(ah
)->ah_ini_xmodes
,
352 modesIndex
, regWrites
);
356 #define AR_BASE_FREQ_2GHZ 2300
357 #define AR_BASE_FREQ_5GHZ 4900
358 #define AR_SPUR_FEEQ_BOUND_HT40 19
359 #define AR_SPUR_FEEQ_BOUND_HT20 10
362 ar9280SpurMitigate(struct ath_hal
*ah
, const struct ieee80211_channel
*chan
)
364 static const int pilot_mask_reg
[4] = { AR_PHY_TIMING7
, AR_PHY_TIMING8
,
365 AR_PHY_PILOT_MASK_01_30
, AR_PHY_PILOT_MASK_31_60
};
366 static const int chan_mask_reg
[4] = { AR_PHY_TIMING9
, AR_PHY_TIMING10
,
367 AR_PHY_CHANNEL_MASK_01_30
, AR_PHY_CHANNEL_MASK_31_60
};
368 static int inc
[4] = { 0, 100, 0, 0 };
370 int bb_spur
= AR_NO_SPUR
;
373 int bb_spur_off
, spur_subchannel_sd
;
375 int spur_delta_phase
;
377 int upper
, lower
, cur_vit_mask
;
380 CHAN_CENTERS centers
;
387 HAL_BOOL is2GHz
= IEEE80211_IS_CHAN_2GHZ(chan
);
389 OS_MEMZERO(&mask_m
, sizeof(int8_t) * 123);
390 OS_MEMZERO(&mask_p
, sizeof(int8_t) * 123);
392 ar5416GetChannelCenters(ah
, chan
, ¢ers
);
393 freq
= centers
.synth_center
;
396 * Need to verify range +/- 9.38 for static ht20 and +/- 18.75 for ht40,
397 * otherwise spur is out-of-band and can be ignored.
399 for (i
= 0; i
< AR5416_EEPROM_MODAL_SPURS
; i
++) {
400 cur_bb_spur
= ath_hal_getSpurChan(ah
, i
, is2GHz
);
401 /* Get actual spur freq in MHz from EEPROM read value */
403 cur_bb_spur
= (cur_bb_spur
/ 10) + AR_BASE_FREQ_2GHZ
;
405 cur_bb_spur
= (cur_bb_spur
/ 10) + AR_BASE_FREQ_5GHZ
;
408 if (AR_NO_SPUR
== cur_bb_spur
)
410 cur_bb_spur
= cur_bb_spur
- freq
;
412 if (IEEE80211_IS_CHAN_HT40(chan
)) {
413 if ((cur_bb_spur
> -AR_SPUR_FEEQ_BOUND_HT40
) &&
414 (cur_bb_spur
< AR_SPUR_FEEQ_BOUND_HT40
)) {
415 bb_spur
= cur_bb_spur
;
418 } else if ((cur_bb_spur
> -AR_SPUR_FEEQ_BOUND_HT20
) &&
419 (cur_bb_spur
< AR_SPUR_FEEQ_BOUND_HT20
)) {
420 bb_spur
= cur_bb_spur
;
425 if (AR_NO_SPUR
== bb_spur
) {
428 * MRC CCK can interfere with beacon detection and cause deaf/mute.
429 * Disable MRC CCK for now.
431 OS_REG_CLR_BIT(ah
, AR_PHY_FORCE_CLKEN_CCK
, AR_PHY_FORCE_CLKEN_CCK_MRC_MUX
);
433 /* Enable MRC CCK if no spur is found in this channel. */
434 OS_REG_SET_BIT(ah
, AR_PHY_FORCE_CLKEN_CCK
, AR_PHY_FORCE_CLKEN_CCK_MRC_MUX
);
439 * For Merlin, spur can break CCK MRC algorithm. Disable CCK MRC if spur
440 * is found in this channel.
442 OS_REG_CLR_BIT(ah
, AR_PHY_FORCE_CLKEN_CCK
, AR_PHY_FORCE_CLKEN_CCK_MRC_MUX
);
447 tmp
= OS_REG_READ(ah
, AR_PHY_TIMING_CTRL4_CHAIN(0));
449 newVal
= tmp
| (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI
|
450 AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER
|
451 AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK
|
452 AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK
);
453 OS_REG_WRITE(ah
, AR_PHY_TIMING_CTRL4_CHAIN(0), newVal
);
455 newVal
= (AR_PHY_SPUR_REG_MASK_RATE_CNTL
|
456 AR_PHY_SPUR_REG_ENABLE_MASK_PPM
|
457 AR_PHY_SPUR_REG_MASK_RATE_SELECT
|
458 AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI
|
459 SM(AR5416_SPUR_RSSI_THRESH
, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH
));
460 OS_REG_WRITE(ah
, AR_PHY_SPUR_REG
, newVal
);
462 /* Pick control or extn channel to cancel the spur */
463 if (IEEE80211_IS_CHAN_HT40(chan
)) {
465 spur_subchannel_sd
= 1;
466 bb_spur_off
= bb_spur
+ 10;
468 spur_subchannel_sd
= 0;
469 bb_spur_off
= bb_spur
- 10;
472 spur_subchannel_sd
= 0;
473 bb_spur_off
= bb_spur
;
477 * spur_delta_phase = bb_spur/40 * 2**21 for static ht20,
480 if (IEEE80211_IS_CHAN_HT40(chan
))
481 spur_delta_phase
= ((bb_spur
* 262144) / 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE
;
483 spur_delta_phase
= ((bb_spur
* 524288) / 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE
;
486 * in 11A mode the denominator of spur_freq_sd should be 40 and
487 * it should be 44 in 11G
489 denominator
= IEEE80211_IS_CHAN_2GHZ(chan
) ? 44 : 40;
490 spur_freq_sd
= ((bb_spur_off
* 2048) / denominator
) & 0x3ff;
492 newVal
= (AR_PHY_TIMING11_USE_SPUR_IN_AGC
|
493 SM(spur_freq_sd
, AR_PHY_TIMING11_SPUR_FREQ_SD
) |
494 SM(spur_delta_phase
, AR_PHY_TIMING11_SPUR_DELTA_PHASE
));
495 OS_REG_WRITE(ah
, AR_PHY_TIMING11
, newVal
);
497 /* Choose to cancel between control and extension channels */
498 newVal
= spur_subchannel_sd
<< AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S
;
499 OS_REG_WRITE(ah
, AR_PHY_SFCORR_EXT
, newVal
);
502 * ============================================
503 * Set Pilot and Channel Masks
505 * pilot mask 1 [31:0] = +6..-26, no 0 bin
506 * pilot mask 2 [19:0] = +26..+7
508 * channel mask 1 [31:0] = +6..-26, no 0 bin
509 * channel mask 2 [19:0] = +26..+7
515 for (i
= 0; i
< 4; i
++) {
519 for (bp
= 0; bp
< 30; bp
++) {
520 if ((cur_bin
> lower
) && (cur_bin
< upper
)) {
521 pilot_mask
= pilot_mask
| 0x1 << bp
;
522 chan_mask
= chan_mask
| 0x1 << bp
;
527 OS_REG_WRITE(ah
, pilot_mask_reg
[i
], pilot_mask
);
528 OS_REG_WRITE(ah
, chan_mask_reg
[i
], chan_mask
);
531 /* =================================================
532 * viterbi mask 1 based on channel magnitude
534 * - mask (-27 to 27) (reg 64,0x9900 to 67,0x990c)
535 * [1 2 2 1] for -9.6 or [1 2 1] for +16
536 * - enable_mask_ppm, all bins move with freq
538 * - mask_select, 8 bits for rates (reg 67,0x990c)
539 * - mask_rate_cntl, 8 bits for rates (reg 67,0x990c)
540 * choose which mask to use mask or mask2
544 * viterbi mask 2 2nd set for per data rate puncturing
546 * - mask_select, 8 bits for rates (reg 67)
547 * - mask (-27 to 27) (reg 98,0x9988 to 101,0x9994)
548 * [1 2 2 1] for -9.6 or [1 2 1] for +16
554 for (i
= 0; i
< 123; i
++) {
555 if ((cur_vit_mask
> lower
) && (cur_vit_mask
< upper
)) {
556 if ((abs(cur_vit_mask
- bin
)) < 75) {
561 if (cur_vit_mask
< 0) {
562 mask_m
[abs(cur_vit_mask
/ 100)] = mask_amt
;
564 mask_p
[cur_vit_mask
/ 100] = mask_amt
;
570 tmp_mask
= (mask_m
[46] << 30) | (mask_m
[47] << 28)
571 | (mask_m
[48] << 26) | (mask_m
[49] << 24)
572 | (mask_m
[50] << 22) | (mask_m
[51] << 20)
573 | (mask_m
[52] << 18) | (mask_m
[53] << 16)
574 | (mask_m
[54] << 14) | (mask_m
[55] << 12)
575 | (mask_m
[56] << 10) | (mask_m
[57] << 8)
576 | (mask_m
[58] << 6) | (mask_m
[59] << 4)
577 | (mask_m
[60] << 2) | (mask_m
[61] << 0);
578 OS_REG_WRITE(ah
, AR_PHY_BIN_MASK_1
, tmp_mask
);
579 OS_REG_WRITE(ah
, AR_PHY_VIT_MASK2_M_46_61
, tmp_mask
);
581 tmp_mask
= (mask_m
[31] << 28)
582 | (mask_m
[32] << 26) | (mask_m
[33] << 24)
583 | (mask_m
[34] << 22) | (mask_m
[35] << 20)
584 | (mask_m
[36] << 18) | (mask_m
[37] << 16)
585 | (mask_m
[48] << 14) | (mask_m
[39] << 12)
586 | (mask_m
[40] << 10) | (mask_m
[41] << 8)
587 | (mask_m
[42] << 6) | (mask_m
[43] << 4)
588 | (mask_m
[44] << 2) | (mask_m
[45] << 0);
589 OS_REG_WRITE(ah
, AR_PHY_BIN_MASK_2
, tmp_mask
);
590 OS_REG_WRITE(ah
, AR_PHY_MASK2_M_31_45
, tmp_mask
);
592 tmp_mask
= (mask_m
[16] << 30) | (mask_m
[16] << 28)
593 | (mask_m
[18] << 26) | (mask_m
[18] << 24)
594 | (mask_m
[20] << 22) | (mask_m
[20] << 20)
595 | (mask_m
[22] << 18) | (mask_m
[22] << 16)
596 | (mask_m
[24] << 14) | (mask_m
[24] << 12)
597 | (mask_m
[25] << 10) | (mask_m
[26] << 8)
598 | (mask_m
[27] << 6) | (mask_m
[28] << 4)
599 | (mask_m
[29] << 2) | (mask_m
[30] << 0);
600 OS_REG_WRITE(ah
, AR_PHY_BIN_MASK_3
, tmp_mask
);
601 OS_REG_WRITE(ah
, AR_PHY_MASK2_M_16_30
, tmp_mask
);
603 tmp_mask
= (mask_m
[ 0] << 30) | (mask_m
[ 1] << 28)
604 | (mask_m
[ 2] << 26) | (mask_m
[ 3] << 24)
605 | (mask_m
[ 4] << 22) | (mask_m
[ 5] << 20)
606 | (mask_m
[ 6] << 18) | (mask_m
[ 7] << 16)
607 | (mask_m
[ 8] << 14) | (mask_m
[ 9] << 12)
608 | (mask_m
[10] << 10) | (mask_m
[11] << 8)
609 | (mask_m
[12] << 6) | (mask_m
[13] << 4)
610 | (mask_m
[14] << 2) | (mask_m
[15] << 0);
611 OS_REG_WRITE(ah
, AR_PHY_MASK_CTL
, tmp_mask
);
612 OS_REG_WRITE(ah
, AR_PHY_MASK2_M_00_15
, tmp_mask
);
614 tmp_mask
= (mask_p
[15] << 28)
615 | (mask_p
[14] << 26) | (mask_p
[13] << 24)
616 | (mask_p
[12] << 22) | (mask_p
[11] << 20)
617 | (mask_p
[10] << 18) | (mask_p
[ 9] << 16)
618 | (mask_p
[ 8] << 14) | (mask_p
[ 7] << 12)
619 | (mask_p
[ 6] << 10) | (mask_p
[ 5] << 8)
620 | (mask_p
[ 4] << 6) | (mask_p
[ 3] << 4)
621 | (mask_p
[ 2] << 2) | (mask_p
[ 1] << 0);
622 OS_REG_WRITE(ah
, AR_PHY_BIN_MASK2_1
, tmp_mask
);
623 OS_REG_WRITE(ah
, AR_PHY_MASK2_P_15_01
, tmp_mask
);
625 tmp_mask
= (mask_p
[30] << 28)
626 | (mask_p
[29] << 26) | (mask_p
[28] << 24)
627 | (mask_p
[27] << 22) | (mask_p
[26] << 20)
628 | (mask_p
[25] << 18) | (mask_p
[24] << 16)
629 | (mask_p
[23] << 14) | (mask_p
[22] << 12)
630 | (mask_p
[21] << 10) | (mask_p
[20] << 8)
631 | (mask_p
[19] << 6) | (mask_p
[18] << 4)
632 | (mask_p
[17] << 2) | (mask_p
[16] << 0);
633 OS_REG_WRITE(ah
, AR_PHY_BIN_MASK2_2
, tmp_mask
);
634 OS_REG_WRITE(ah
, AR_PHY_MASK2_P_30_16
, tmp_mask
);
636 tmp_mask
= (mask_p
[45] << 28)
637 | (mask_p
[44] << 26) | (mask_p
[43] << 24)
638 | (mask_p
[42] << 22) | (mask_p
[41] << 20)
639 | (mask_p
[40] << 18) | (mask_p
[39] << 16)
640 | (mask_p
[38] << 14) | (mask_p
[37] << 12)
641 | (mask_p
[36] << 10) | (mask_p
[35] << 8)
642 | (mask_p
[34] << 6) | (mask_p
[33] << 4)
643 | (mask_p
[32] << 2) | (mask_p
[31] << 0);
644 OS_REG_WRITE(ah
, AR_PHY_BIN_MASK2_3
, tmp_mask
);
645 OS_REG_WRITE(ah
, AR_PHY_MASK2_P_45_31
, tmp_mask
);
647 tmp_mask
= (mask_p
[61] << 30) | (mask_p
[60] << 28)
648 | (mask_p
[59] << 26) | (mask_p
[58] << 24)
649 | (mask_p
[57] << 22) | (mask_p
[56] << 20)
650 | (mask_p
[55] << 18) | (mask_p
[54] << 16)
651 | (mask_p
[53] << 14) | (mask_p
[52] << 12)
652 | (mask_p
[51] << 10) | (mask_p
[50] << 8)
653 | (mask_p
[49] << 6) | (mask_p
[48] << 4)
654 | (mask_p
[47] << 2) | (mask_p
[46] << 0);
655 OS_REG_WRITE(ah
, AR_PHY_BIN_MASK2_4
, tmp_mask
);
656 OS_REG_WRITE(ah
, AR_PHY_MASK2_P_61_45
, tmp_mask
);
660 * Fill all software cached or static hardware state information.
661 * Return failure if capabilities are to come from EEPROM and
665 ar9280FillCapabilityInfo(struct ath_hal
*ah
)
667 HAL_CAPABILITIES
*pCap
= &AH_PRIVATE(ah
)->ah_caps
;
669 if (!ar5416FillCapabilityInfo(ah
))
671 pCap
->halNumGpioPins
= 10;
672 pCap
->halWowSupport
= AH_TRUE
;
673 pCap
->halWowMatchPatternExact
= AH_TRUE
;
675 pCap
->halWowMatchPatternDword
= AH_TRUE
;
677 pCap
->halCSTSupport
= AH_TRUE
;
678 pCap
->halRifsRxSupport
= AH_TRUE
;
679 pCap
->halRifsTxSupport
= AH_TRUE
;
680 pCap
->halRtsAggrLimit
= 64*1024; /* 802.11n max */
681 pCap
->halExtChanDfsSupport
= AH_TRUE
;
684 pCap
->halBtCoexSupport
= AH_TRUE
;
686 pCap
->halAutoSleepSupport
= AH_FALSE
; /* XXX? */
688 pCap
->hal4kbSplitTransSupport
= AH_FALSE
;
690 pCap
->halRxStbcSupport
= 1;
691 pCap
->halTxStbcSupport
= 1;
697 ar9280SetAntennaSwitch(struct ath_hal
*ah
, HAL_ANT_SETTING settings
)
699 #define ANTENNA0_CHAINMASK 0x1
700 #define ANTENNA1_CHAINMASK 0x2
701 struct ath_hal_5416
*ahp
= AH5416(ah
);
703 /* Antenna selection is done by setting the tx/rx chainmasks approp. */
705 case HAL_ANT_FIXED_A
:
706 /* Enable first antenna only */
707 ahp
->ah_tx_chainmask
= ANTENNA0_CHAINMASK
;
708 ahp
->ah_rx_chainmask
= ANTENNA0_CHAINMASK
;
710 case HAL_ANT_FIXED_B
:
711 /* Enable second antenna only, after checking capability */
712 if (AH_PRIVATE(ah
)->ah_caps
.halTxChainMask
> ANTENNA1_CHAINMASK
)
713 ahp
->ah_tx_chainmask
= ANTENNA1_CHAINMASK
;
714 ahp
->ah_rx_chainmask
= ANTENNA1_CHAINMASK
;
716 case HAL_ANT_VARIABLE
:
717 /* Restore original chainmask settings */
719 ahp
->ah_tx_chainmask
= AR5416_DEFAULT_TXCHAINMASK
;
720 ahp
->ah_rx_chainmask
= AR5416_DEFAULT_RXCHAINMASK
;
724 #undef ANTENNA0_CHAINMASK
725 #undef ANTENNA1_CHAINMASK
729 ar9280Probe(uint16_t vendorid
, uint16_t devid
)
731 if (vendorid
== ATHEROS_VENDOR_ID
&&
732 (devid
== AR9280_DEVID_PCI
|| devid
== AR9280_DEVID_PCIE
))
733 return "Atheros 9280";
736 AH_CHIP(AR9280
, ar9280Probe
, ar9280Attach
);