]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - sys/dev/ath/ath_hal/ar9002/ar9287_attach.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / sys / dev / ath / ath_hal / ar9002 / ar9287_attach.c
1 /*
2  * Copyright (c) 2008-2009 Sam Leffler, Errno Consulting
3  * Copyright (c) 2008 Atheros Communications, Inc.
4  *
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.
8  *
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.
16  *
17  * $FreeBSD$
18  */
19 #include "opt_ah.h"
20
21 #include "ah.h"
22 #include "ah_internal.h"
23 #include "ah_devid.h"
24
25 #include "ah_eeprom_v14.h"              /* XXX for tx/rx gain */
26 #include "ah_eeprom_9287.h"
27
28 #include "ar9002/ar9280.h"
29 #include "ar9002/ar9287.h"
30 #include "ar5416/ar5416reg.h"
31 #include "ar5416/ar5416phy.h"
32
33 #include "ar9002/ar9287_cal.h"
34 #include "ar9002/ar9287_reset.h"
35 #include "ar9002/ar9287_olc.h"
36
37 #include "ar9002/ar9287.ini"
38
39 static const HAL_PERCAL_DATA ar9287_iq_cal = {          /* single sample */
40         .calName = "IQ", .calType = IQ_MISMATCH_CAL,
41         .calNumSamples  = MIN_CAL_SAMPLES,
42         .calCountMax    = PER_MAX_LOG_COUNT,
43         .calCollect     = ar5416IQCalCollect,
44         .calPostProc    = ar5416IQCalibration
45 };
46 static const HAL_PERCAL_DATA ar9287_adc_gain_cal = {    /* single sample */
47         .calName = "ADC Gain", .calType = ADC_GAIN_CAL,
48         .calNumSamples  = MIN_CAL_SAMPLES,
49         .calCountMax    = PER_MIN_LOG_COUNT,
50         .calCollect     = ar5416AdcGainCalCollect,
51         .calPostProc    = ar5416AdcGainCalibration
52 };
53 static const HAL_PERCAL_DATA ar9287_adc_dc_cal = {      /* single sample */
54         .calName = "ADC DC", .calType = ADC_DC_CAL,
55         .calNumSamples  = MIN_CAL_SAMPLES,
56         .calCountMax    = PER_MIN_LOG_COUNT,
57         .calCollect     = ar5416AdcDcCalCollect,
58         .calPostProc    = ar5416AdcDcCalibration
59 };
60 static const HAL_PERCAL_DATA ar9287_adc_init_dc_cal = {
61         .calName = "ADC Init DC", .calType = ADC_DC_INIT_CAL,
62         .calNumSamples  = MIN_CAL_SAMPLES,
63         .calCountMax    = INIT_LOG_COUNT,
64         .calCollect     = ar5416AdcDcCalCollect,
65         .calPostProc    = ar5416AdcDcCalibration
66 };
67
68 static void ar9287ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore);
69 static HAL_BOOL ar9287FillCapabilityInfo(struct ath_hal *ah);
70 static void ar9287WriteIni(struct ath_hal *ah,
71         const struct ieee80211_channel *chan);
72
73 static void
74 ar9287AniSetup(struct ath_hal *ah)
75 {
76         /*
77          * These are the parameters from the AR5416 ANI code;
78          * they likely need quite a bit of adjustment for the
79          * AR9280.
80          */
81         static const struct ar5212AniParams aniparams = {
82                 .maxNoiseImmunityLevel  = 4,    /* levels 0..4 */
83                 .totalSizeDesired       = { -55, -55, -55, -55, -62 },
84                 .coarseHigh             = { -14, -14, -14, -14, -12 },
85                 .coarseLow              = { -64, -64, -64, -64, -70 },
86                 .firpwr                 = { -78, -78, -78, -78, -80 },
87                 .maxSpurImmunityLevel   = 2,
88                 .cycPwrThr1             = { 2, 4, 6 },
89                 .maxFirstepLevel        = 2,    /* levels 0..2 */
90                 .firstep                = { 0, 4, 8 },
91                 .ofdmTrigHigh           = 500,
92                 .ofdmTrigLow            = 200,
93                 .cckTrigHigh            = 200,
94                 .cckTrigLow             = 100,
95                 .rssiThrHigh            = 40,
96                 .rssiThrLow             = 7,
97                 .period                 = 100,
98         };
99         /* NB: disable ANI noise immmunity for reliable RIFS rx */
100         AH5416(ah)->ah_ani_function &= ~ HAL_ANI_NOISE_IMMUNITY_LEVEL;
101
102         /* NB: ANI is not enabled yet */
103         ar5416AniAttach(ah, &aniparams, &aniparams, AH_TRUE);
104 }
105
106 /*
107  * Attach for an AR9287 part.
108  */
109 static struct ath_hal *
110 ar9287Attach(uint16_t devid, HAL_SOFTC sc,
111         HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata,
112         HAL_STATUS *status)
113 {
114         struct ath_hal_9287 *ahp9287;
115         struct ath_hal_5212 *ahp;
116         struct ath_hal *ah;
117         uint32_t val;
118         HAL_STATUS ecode;
119         HAL_BOOL rfStatus;
120         int8_t pwr_table_offset;
121
122         HALDEBUG_G(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n",
123             __func__, sc, (void*) st, (void*) sh);
124
125         /* NB: memory is returned zero'd */
126         ahp9287 = ath_hal_malloc(sizeof (struct ath_hal_9287));
127         if (ahp9287 == AH_NULL) {
128                 HALDEBUG_G(AH_NULL, HAL_DEBUG_ANY,
129                     "%s: cannot allocate memory for state block\n", __func__);
130                 *status = HAL_ENOMEM;
131                 return AH_NULL;
132         }
133         ahp = AH5212(ahp9287);
134         ah = &ahp->ah_priv.h;
135
136         ar5416InitState(AH5416(ah), devid, sc, st, sh, status);
137
138         /* XXX override with 9280 specific state */
139         /* override 5416 methods for our needs */
140         AH5416(ah)->ah_initPLL = ar9280InitPLL;
141
142         ah->ah_setAntennaSwitch         = ar9287SetAntennaSwitch;
143         ah->ah_configPCIE               = ar9287ConfigPCIE;
144
145         AH5416(ah)->ah_cal.iqCalData.calData = &ar9287_iq_cal;
146         AH5416(ah)->ah_cal.adcGainCalData.calData = &ar9287_adc_gain_cal;
147         AH5416(ah)->ah_cal.adcDcCalData.calData = &ar9287_adc_dc_cal;
148         AH5416(ah)->ah_cal.adcDcCalInitData.calData = &ar9287_adc_init_dc_cal;
149         /* Better performance without ADC Gain Calibration */
150         AH5416(ah)->ah_cal.suppCals = ADC_DC_CAL | IQ_MISMATCH_CAL;
151
152         AH5416(ah)->ah_spurMitigate     = ar9280SpurMitigate;
153         AH5416(ah)->ah_writeIni         = ar9287WriteIni;
154
155         ah->ah_setTxPower               = ar9287SetTransmitPower;
156         ah->ah_setBoardValues           = ar9287SetBoardValues;
157
158         AH5416(ah)->ah_olcInit          = ar9287olcInit;
159         AH5416(ah)->ah_olcTempCompensation = ar9287olcTemperatureCompensation;
160         //AH5416(ah)->ah_setPowerCalTable       = ar9287SetPowerCalTable;
161         AH5416(ah)->ah_cal_initcal      = ar9287InitCalHardware;
162         AH5416(ah)->ah_cal_pacal        = ar9287PACal;
163
164         /* XXX NF calibration */
165         /* XXX Ini override? (IFS vars - since the kiwi mac clock is faster?) */
166         /* XXX what else is kiwi-specific in the radio/calibration pathway? */
167
168         AH5416(ah)->ah_rx_chainmask     = AR9287_DEFAULT_RXCHAINMASK;
169         AH5416(ah)->ah_tx_chainmask     = AR9287_DEFAULT_TXCHAINMASK;
170
171         if (!ar5416SetResetReg(ah, HAL_RESET_POWER_ON)) {
172                 /* reset chip */
173                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: couldn't reset chip\n",
174                     __func__);
175                 ecode = HAL_EIO;
176                 goto bad;
177         }
178
179         if (!ar5416SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) {
180                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: couldn't wakeup chip\n",
181                     __func__);
182                 ecode = HAL_EIO;
183                 goto bad;
184         }
185         /* Read Revisions from Chips before taking out of reset */
186         val = OS_REG_READ(ah, AR_SREV);
187         HALDEBUG(ah, HAL_DEBUG_ATTACH,
188             "%s: ID 0x%x VERSION 0x%x TYPE 0x%x REVISION 0x%x\n",
189             __func__, MS(val, AR_XSREV_ID), MS(val, AR_XSREV_VERSION),
190             MS(val, AR_XSREV_TYPE), MS(val, AR_XSREV_REVISION));
191         /* NB: include chip type to differentiate from pre-Sowl versions */
192         AH_PRIVATE(ah)->ah_macVersion =
193             (val & AR_XSREV_VERSION) >> AR_XSREV_TYPE_S;
194         AH_PRIVATE(ah)->ah_macRev = MS(val, AR_XSREV_REVISION);
195         AH_PRIVATE(ah)->ah_ispcie = (val & AR_XSREV_TYPE_HOST_MODE) == 0;
196
197         /* Don't support Kiwi < 1.2; those are pre-release chips */
198         if (! AR_SREV_KIWI_12_OR_LATER(ah)) {
199                 ath_hal_printf(ah, "[ath]: Kiwi < 1.2 is not supported\n");
200                 ecode = HAL_EIO;
201                 goto bad;
202         }
203
204         /* setup common ini data; rf backends handle remainder */
205         HAL_INI_INIT(&ahp->ah_ini_modes, ar9287Modes_9287_1_1, 6);
206         HAL_INI_INIT(&ahp->ah_ini_common, ar9287Common_9287_1_1, 2);
207
208         /* If pcie_clock_req */
209         HAL_INI_INIT(&AH5416(ah)->ah_ini_pcieserdes,
210             ar9287PciePhy_clkreq_always_on_L1_9287_1_1, 2);
211
212         /* XXX WoW ini values */
213
214         /* Else */
215 #if 0
216         HAL_INI_INIT(&AH5416(ah)->ah_ini_pcieserdes,
217             ar9287PciePhy_clkreq_off_L1_9287_1_1, 2);
218 #endif
219
220         /* Initialise Japan arrays */
221         HAL_INI_INIT(&ahp9287->ah_ini_cckFirNormal,
222             ar9287Common_normal_cck_fir_coeff_9287_1_1, 2);
223         HAL_INI_INIT(&ahp9287->ah_ini_cckFirJapan2484,
224             ar9287Common_japan_2484_cck_fir_coeff_9287_1_1, 2);
225
226         ar5416AttachPCIE(ah);
227
228         ecode = ath_hal_9287EepromAttach(ah);
229         if (ecode != HAL_OK)
230                 goto bad;
231
232         if (!ar5416ChipReset(ah, AH_NULL)) {    /* reset chip */
233                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", __func__);
234                 ecode = HAL_EIO;
235                 goto bad;
236         }
237
238         AH_PRIVATE(ah)->ah_phyRev = OS_REG_READ(ah, AR_PHY_CHIP_ID);
239
240         if (!ar5212ChipTest(ah)) {
241                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: hardware self-test failed\n",
242                     __func__);
243                 ecode = HAL_ESELFTEST;
244                 goto bad;
245         }
246
247         /*
248          * Set correct Baseband to analog shift
249          * setting to access analog chips.
250          */
251         OS_REG_WRITE(ah, AR_PHY(0), 0x00000007);
252
253         /* Read Radio Chip Rev Extract */
254         AH_PRIVATE(ah)->ah_analog5GhzRev = ar5416GetRadioRev(ah);
255         switch (AH_PRIVATE(ah)->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR) {
256         case AR_RAD2133_SREV_MAJOR:     /* Sowl: 2G/3x3 */
257         case AR_RAD5133_SREV_MAJOR:     /* Sowl: 2+5G/3x3 */
258                 break;
259         default:
260                 if (AH_PRIVATE(ah)->ah_analog5GhzRev == 0) {
261                         AH_PRIVATE(ah)->ah_analog5GhzRev =
262                                 AR_RAD5133_SREV_MAJOR;
263                         break;
264                 }
265 #ifdef AH_DEBUG
266                 HALDEBUG(ah, HAL_DEBUG_ANY,
267                     "%s: 5G Radio Chip Rev 0x%02X is not supported by "
268                     "this driver\n", __func__,
269                     AH_PRIVATE(ah)->ah_analog5GhzRev);
270                 ecode = HAL_ENOTSUPP;
271                 goto bad;
272 #endif
273         }
274         rfStatus = ar9287RfAttach(ah, &ecode);
275         if (!rfStatus) {
276                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: RF setup failed, status %u\n",
277                     __func__, ecode);
278                 goto bad;
279         }
280
281         /*
282          * We only implement open-loop TX power control
283          * for the AR9287 in this codebase.
284          */
285         if (! ath_hal_eepromGetFlag(ah, AR_EEP_OL_PWRCTRL)) {
286                 ath_hal_printf(ah, "[ath] AR9287 w/ closed-loop TX power control"
287                     " isn't supported.\n");
288                 ecode = HAL_ENOTSUPP;
289                 goto bad;
290         }
291
292         /*
293          * Check whether the power table offset isn't the default.
294          * This can occur with eeprom minor V21 or greater on Merlin.
295          */
296         (void) ath_hal_eepromGet(ah, AR_EEP_PWR_TABLE_OFFSET, &pwr_table_offset);
297         if (pwr_table_offset != AR5416_PWR_TABLE_OFFSET_DB)
298                 ath_hal_printf(ah, "[ath]: default pwr offset: %d dBm != EEPROM pwr offset: %d dBm; curves will be adjusted.\n",
299                     AR5416_PWR_TABLE_OFFSET_DB, (int) pwr_table_offset);
300
301         /* setup rxgain table */
302         HAL_INI_INIT(&ahp9287->ah_ini_rxgain, ar9287Modes_rx_gain_9287_1_1, 6);
303
304         /* setup txgain table */
305         HAL_INI_INIT(&ahp9287->ah_ini_txgain, ar9287Modes_tx_gain_9287_1_1, 6);
306
307         /*
308          * Got everything we need now to setup the capabilities.
309          */
310         if (!ar9287FillCapabilityInfo(ah)) {
311                 ecode = HAL_EEREAD;
312                 goto bad;
313         }
314
315         ecode = ath_hal_eepromGet(ah, AR_EEP_MACADDR, ahp->ah_macaddr);
316         if (ecode != HAL_OK) {
317                 HALDEBUG(ah, HAL_DEBUG_ANY,
318                     "%s: error getting mac address from EEPROM\n", __func__);
319                 goto bad;
320         }
321         /* XXX How about the serial number ? */
322         /* Read Reg Domain */
323         AH_PRIVATE(ah)->ah_currentRD =
324             ath_hal_eepromGet(ah, AR_EEP_REGDMN_0, AH_NULL);
325         AH_PRIVATE(ah)->ah_currentRDext = AR9287_RDEXT_DEFAULT;
326
327         /*
328          * ah_miscMode is populated by ar5416FillCapabilityInfo()
329          * starting from griffin. Set here to make sure that
330          * AR_MISC_MODE_MIC_NEW_LOC_ENABLE is set before a GTK is
331          * placed into hardware.
332          */
333         if (ahp->ah_miscMode != 0)
334                 OS_REG_WRITE(ah, AR_MISC_MODE, OS_REG_READ(ah, AR_MISC_MODE) | ahp->ah_miscMode);
335
336         ar9287AniSetup(ah);                     /* Anti Noise Immunity */
337
338         /* Setup noise floor min/max/nominal values */
339         AH5416(ah)->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9287_2GHZ;
340         AH5416(ah)->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9287_2GHZ;
341         AH5416(ah)->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9287_2GHZ;
342         AH5416(ah)->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_9287_5GHZ;
343         AH5416(ah)->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_9287_5GHZ;
344         AH5416(ah)->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_9287_5GHZ;
345
346         ar5416InitNfHistBuff(AH5416(ah)->ah_cal.nfCalHist);
347
348         HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: return\n", __func__);
349
350         return ah;
351 bad:
352         if (ah != AH_NULL)
353                 ah->ah_detach(ah);
354         if (status)
355                 *status = ecode;
356         return AH_NULL;
357 }
358
359 static void
360 ar9287ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore)
361 {
362         if (AH_PRIVATE(ah)->ah_ispcie && !restore) {
363                 ath_hal_ini_write(ah, &AH5416(ah)->ah_ini_pcieserdes, 1, 0);
364                 OS_DELAY(1000);
365                 OS_REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
366                 OS_REG_WRITE(ah, AR_WA, AR9285_WA_DEFAULT);     /* Yes, Kiwi uses the Kite PCIe PHY WA */
367         }
368 }
369
370 static void
371 ar9287WriteIni(struct ath_hal *ah, const struct ieee80211_channel *chan)
372 {
373         u_int modesIndex, freqIndex;
374         int regWrites = 0;
375
376         /* Setup the indices for the next set of register array writes */
377         /* XXX Ignore 11n dynamic mode on the AR5416 for the moment */
378         if (IEEE80211_IS_CHAN_2GHZ(chan)) {
379                 freqIndex = 2;
380                 if (IEEE80211_IS_CHAN_HT40(chan))
381                         modesIndex = 3;
382                 else if (IEEE80211_IS_CHAN_108G(chan))
383                         modesIndex = 5;
384                 else
385                         modesIndex = 4;
386         } else {
387                 freqIndex = 1;
388                 if (IEEE80211_IS_CHAN_HT40(chan) ||
389                     IEEE80211_IS_CHAN_TURBO(chan))
390                         modesIndex = 2;
391                 else
392                         modesIndex = 1;
393         }
394
395         /* Set correct Baseband to analog shift setting to access analog chips. */
396         OS_REG_WRITE(ah, AR_PHY(0), 0x00000007);
397         OS_REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);
398
399         regWrites = ath_hal_ini_write(ah, &AH5212(ah)->ah_ini_modes, modesIndex, regWrites);
400         regWrites = ath_hal_ini_write(ah, &AH9287(ah)->ah_ini_rxgain, modesIndex, regWrites);
401         regWrites = ath_hal_ini_write(ah, &AH9287(ah)->ah_ini_txgain, modesIndex, regWrites);
402         regWrites = ath_hal_ini_write(ah, &AH5212(ah)->ah_ini_common, 1, regWrites);
403 }
404
405 #define AR_BASE_FREQ_2GHZ       2300
406 #define AR_BASE_FREQ_5GHZ       4900
407 #define AR_SPUR_FEEQ_BOUND_HT40 19
408 #define AR_SPUR_FEEQ_BOUND_HT20 10
409
410
411
412 /*
413  * Fill all software cached or static hardware state information.
414  * Return failure if capabilities are to come from EEPROM and
415  * cannot be read.
416  */
417 static HAL_BOOL
418 ar9287FillCapabilityInfo(struct ath_hal *ah)
419 {
420         HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;
421
422         if (!ar5416FillCapabilityInfo(ah))
423                 return AH_FALSE;
424         pCap->halNumGpioPins = 10;
425         pCap->halWowSupport = AH_TRUE;
426         pCap->halWowMatchPatternExact = AH_TRUE;
427 #if 0
428         pCap->halWowMatchPatternDword = AH_TRUE;
429 #endif
430
431         pCap->halCSTSupport = AH_TRUE;
432         pCap->halRifsRxSupport = AH_TRUE;
433         pCap->halRifsTxSupport = AH_TRUE;
434         pCap->halRtsAggrLimit = 64*1024;        /* 802.11n max */
435         pCap->halExtChanDfsSupport = AH_TRUE;
436         pCap->halUseCombinedRadarRssi = AH_TRUE;
437 #if 0
438         /* XXX bluetooth */
439         pCap->halBtCoexSupport = AH_TRUE;
440 #endif
441         pCap->halAutoSleepSupport = AH_FALSE;   /* XXX? */
442         pCap->hal4kbSplitTransSupport = AH_FALSE;
443         /* Disable this so Block-ACK works correctly */
444         pCap->halHasRxSelfLinkedTail = AH_FALSE;
445         pCap->halPSPollBroken = AH_FALSE;
446
447         /* Hardware supports (at least) single-stream STBC TX/RX */
448         pCap->halRxStbcSupport = 1;
449         pCap->halTxStbcSupport = 1;
450
451         /* Hardware supports short-GI w/ 20MHz */
452         pCap->halHTSGI20Support = 1;
453
454         pCap->halEnhancedDfsSupport = AH_TRUE;
455
456         return AH_TRUE;
457 }
458
459 /*
460  * This has been disabled - having the HAL flip chainmasks on/off
461  * when attempting to implement 11n disrupts things. For now, just
462  * leave this flipped off and worry about implementing TX diversity
463  * for legacy and MCS0-7 when 11n is fully functioning.
464  */
465 HAL_BOOL
466 ar9287SetAntennaSwitch(struct ath_hal *ah, HAL_ANT_SETTING settings)
467 {
468         return AH_TRUE;
469 }
470
471 static const char*
472 ar9287Probe(uint16_t vendorid, uint16_t devid)
473 {
474         if (vendorid == ATHEROS_VENDOR_ID &&
475             (devid == AR9287_DEVID_PCI || devid == AR9287_DEVID_PCIE))
476                 return "Atheros 9287";
477         return AH_NULL;
478 }
479 AH_CHIP(AR9287, ar9287Probe, ar9287Attach);