Merge branch 'vendor/ZLIB'
[dragonfly.git] / sys / dev / netif / ath / hal / ath_hal / ar5416 / ar9285_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: head/sys/dev/ath/ath_hal/ar5416/ar9285_attach.c 203930 2010-02-15 17:49:49Z rpaulo $
18  * $DragonFly$
19  */
20 #include "opt_ah.h"
21
22 #include "ah.h"
23 #include "ah_internal.h"
24 #include "ah_devid.h"
25
26 #include "ah_eeprom_v4k.h"              /* XXX for tx/rx gain */
27
28 #include "ar5416/ar9280.h"
29 #include "ar5416/ar9285.h"
30 #include "ar5416/ar5416reg.h"
31 #include "ar5416/ar5416phy.h"
32
33 #include "ar5416/ar9285.ini"
34 #include "ar5416/ar9285v2.ini"
35 #include "ar5416/ar9280v2.ini"          /* XXX ini for tx/rx gain */
36
37 static const HAL_PERCAL_DATA ar9280_iq_cal = {          /* single sample */
38         .calName = "IQ", .calType = IQ_MISMATCH_CAL,
39         .calNumSamples  = MIN_CAL_SAMPLES,
40         .calCountMax    = PER_MAX_LOG_COUNT,
41         .calCollect     = ar5416IQCalCollect,
42         .calPostProc    = ar5416IQCalibration
43 };
44 static const HAL_PERCAL_DATA ar9280_adc_gain_cal = {    /* single sample */
45         .calName = "ADC Gain", .calType = ADC_GAIN_CAL,
46         .calNumSamples  = MIN_CAL_SAMPLES,
47         .calCountMax    = PER_MIN_LOG_COUNT,
48         .calCollect     = ar5416AdcGainCalCollect,
49         .calPostProc    = ar5416AdcGainCalibration
50 };
51 static const HAL_PERCAL_DATA ar9280_adc_dc_cal = {      /* single sample */
52         .calName = "ADC DC", .calType = ADC_DC_CAL,
53         .calNumSamples  = MIN_CAL_SAMPLES,
54         .calCountMax    = PER_MIN_LOG_COUNT,
55         .calCollect     = ar5416AdcDcCalCollect,
56         .calPostProc    = ar5416AdcDcCalibration
57 };
58 static const HAL_PERCAL_DATA ar9280_adc_init_dc_cal = {
59         .calName = "ADC Init DC", .calType = ADC_DC_INIT_CAL,
60         .calNumSamples  = MIN_CAL_SAMPLES,
61         .calCountMax    = INIT_LOG_COUNT,
62         .calCollect     = ar5416AdcDcCalCollect,
63         .calPostProc    = ar5416AdcDcCalibration
64 };
65
66 static void ar9285ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore);
67 static HAL_BOOL ar9285FillCapabilityInfo(struct ath_hal *ah);
68 static void ar9285WriteIni(struct ath_hal *ah,
69         const struct ieee80211_channel *chan);
70
71 static void
72 ar9285AniSetup(struct ath_hal *ah)
73 {
74         /* NB: disable ANI for reliable RIFS rx */
75         ar5212AniAttach(ah, AH_NULL, AH_NULL, AH_FALSE);
76 }
77
78 /*
79  * Attach for an AR9285 part.
80  */
81 static struct ath_hal *
82 ar9285Attach(uint16_t devid, HAL_SOFTC sc,
83         HAL_BUS_TAG st, HAL_BUS_HANDLE sh, HAL_STATUS *status)
84 {
85         struct ath_hal_9285 *ahp9285;
86         struct ath_hal_5212 *ahp;
87         struct ath_hal *ah;
88         uint32_t val;
89         HAL_STATUS ecode;
90         HAL_BOOL rfStatus;
91
92         HALDEBUG(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n",
93             __func__, sc, (void*) st, (void*) sh);
94
95         /* NB: memory is returned zero'd */
96         ahp9285 = ath_hal_malloc(sizeof (struct ath_hal_9285));
97         if (ahp9285 == AH_NULL) {
98                 HALDEBUG(AH_NULL, HAL_DEBUG_ANY,
99                     "%s: cannot allocate memory for state block\n", __func__);
100                 *status = HAL_ENOMEM;
101                 return AH_NULL;
102         }
103         ahp = AH5212(ahp9285);
104         ah = &ahp->ah_priv.h;
105
106         ar5416InitState(AH5416(ah), devid, sc, st, sh, status);
107
108         /* XXX override with 9285 specific state */
109         /* override 5416 methods for our needs */
110         ah->ah_setAntennaSwitch         = ar9285SetAntennaSwitch;
111         ah->ah_configPCIE               = ar9285ConfigPCIE;
112         ah->ah_setTxPower               = ar9285SetTransmitPower;
113         ah->ah_setBoardValues           = ar9285SetBoardValues;
114
115         AH5416(ah)->ah_cal.iqCalData.calData = &ar9280_iq_cal;
116         AH5416(ah)->ah_cal.adcGainCalData.calData = &ar9280_adc_gain_cal;
117         AH5416(ah)->ah_cal.adcDcCalData.calData = &ar9280_adc_dc_cal;
118         AH5416(ah)->ah_cal.adcDcCalInitData.calData = &ar9280_adc_init_dc_cal;
119         AH5416(ah)->ah_cal.suppCals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
120
121         AH5416(ah)->ah_spurMitigate     = ar9280SpurMitigate;
122         AH5416(ah)->ah_writeIni         = ar9285WriteIni;
123         AH5416(ah)->ah_rx_chainmask     = AR9285_DEFAULT_RXCHAINMASK;
124         AH5416(ah)->ah_tx_chainmask     = AR9285_DEFAULT_TXCHAINMASK;
125         
126         ahp->ah_maxTxTrigLev            = MAX_TX_FIFO_THRESHOLD >> 1;
127
128         if (!ar5416SetResetReg(ah, HAL_RESET_POWER_ON)) {
129                 /* reset chip */
130                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: couldn't reset chip\n",
131                     __func__);
132                 ecode = HAL_EIO;
133                 goto bad;
134         }
135
136         if (!ar5416SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) {
137                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: couldn't wakeup chip\n",
138                     __func__);
139                 ecode = HAL_EIO;
140                 goto bad;
141         }
142         /* Read Revisions from Chips before taking out of reset */
143         val = OS_REG_READ(ah, AR_SREV);
144         HALDEBUG(ah, HAL_DEBUG_ATTACH,
145             "%s: ID 0x%x VERSION 0x%x TYPE 0x%x REVISION 0x%x\n",
146             __func__, MS(val, AR_XSREV_ID), MS(val, AR_XSREV_VERSION),
147             MS(val, AR_XSREV_TYPE), MS(val, AR_XSREV_REVISION));
148         /* NB: include chip type to differentiate from pre-Sowl versions */
149         AH_PRIVATE(ah)->ah_macVersion =
150             (val & AR_XSREV_VERSION) >> AR_XSREV_TYPE_S;
151         AH_PRIVATE(ah)->ah_macRev = MS(val, AR_XSREV_REVISION);
152         AH_PRIVATE(ah)->ah_ispcie = (val & AR_XSREV_TYPE_HOST_MODE) == 0;
153
154         /* setup common ini data; rf backends handle remainder */
155         if (AR_SREV_KITE_12_OR_LATER(ah)) {
156                 HAL_INI_INIT(&ahp->ah_ini_modes, ar9285Modes_v2, 6);
157                 HAL_INI_INIT(&ahp->ah_ini_common, ar9285Common_v2, 2);
158                 HAL_INI_INIT(&AH5416(ah)->ah_ini_pcieserdes,
159                     ar9285PciePhy_clkreq_always_on_L1_v2, 2);
160         } else {
161                 HAL_INI_INIT(&ahp->ah_ini_modes, ar9285Modes, 6);
162                 HAL_INI_INIT(&ahp->ah_ini_common, ar9285Common, 2);
163                 HAL_INI_INIT(&AH5416(ah)->ah_ini_pcieserdes,
164                     ar9285PciePhy_clkreq_always_on_L1, 2);
165         }
166         ar5416AttachPCIE(ah);
167
168         ecode = ath_hal_v4kEepromAttach(ah);
169         if (ecode != HAL_OK)
170                 goto bad;
171
172         if (!ar5416ChipReset(ah, AH_NULL)) {    /* reset chip */
173                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n",
174                     __func__);
175                 ecode = HAL_EIO;
176                 goto bad;
177         }
178
179         AH_PRIVATE(ah)->ah_phyRev = OS_REG_READ(ah, AR_PHY_CHIP_ID);
180
181         if (!ar5212ChipTest(ah)) {
182                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: hardware self-test failed\n",
183                     __func__);
184                 ecode = HAL_ESELFTEST;
185                 goto bad;
186         }
187
188         /*
189          * Set correct Baseband to analog shift
190          * setting to access analog chips.
191          */
192         OS_REG_WRITE(ah, AR_PHY(0), 0x00000007);
193
194         /* Read Radio Chip Rev Extract */
195         AH_PRIVATE(ah)->ah_analog5GhzRev = ar5416GetRadioRev(ah);
196         switch (AH_PRIVATE(ah)->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR) {
197         case AR_RAD2133_SREV_MAJOR:     /* Sowl: 2G/3x3 */
198         case AR_RAD5133_SREV_MAJOR:     /* Sowl: 2+5G/3x3 */
199                 break;
200         default:
201                 if (AH_PRIVATE(ah)->ah_analog5GhzRev == 0) {
202                         AH_PRIVATE(ah)->ah_analog5GhzRev =
203                                 AR_RAD5133_SREV_MAJOR;
204                         break;
205                 }
206 #ifdef AH_DEBUG
207                 HALDEBUG(ah, HAL_DEBUG_ANY,
208                     "%s: 5G Radio Chip Rev 0x%02X is not supported by "
209                     "this driver\n", __func__,
210                     AH_PRIVATE(ah)->ah_analog5GhzRev);
211                 ecode = HAL_ENOTSUPP;
212                 goto bad;
213 #endif
214         }
215         rfStatus = ar9285RfAttach(ah, &ecode);
216         if (!rfStatus) {
217                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: RF setup failed, status %u\n",
218                     __func__, ecode);
219                 goto bad;
220         }
221
222         HAL_INI_INIT(&ahp9285->ah_ini_rxgain, ar9280Modes_original_rxgain_v2,
223             6);
224         /* setup txgain table */
225         switch (ath_hal_eepromGet(ah, AR_EEP_TXGAIN_TYPE, AH_NULL)) {
226         case AR5416_EEP_TXGAIN_HIGH_POWER:
227                 HAL_INI_INIT(&ahp9285->ah_ini_txgain,
228                     ar9285Modes_high_power_tx_gain_v2, 6);
229                 break;
230         case AR5416_EEP_TXGAIN_ORIG:
231                 HAL_INI_INIT(&ahp9285->ah_ini_txgain,
232                     ar9285Modes_original_tx_gain_v2, 6);
233                 break;
234         default:
235                 HALASSERT(AH_FALSE);
236                 goto bad;               /* XXX ? try to continue */
237         }
238
239         /*
240          * Got everything we need now to setup the capabilities.
241          */
242         if (!ar9285FillCapabilityInfo(ah)) {
243                 ecode = HAL_EEREAD;
244                 goto bad;
245         }
246
247         ecode = ath_hal_eepromGet(ah, AR_EEP_MACADDR, ahp->ah_macaddr);
248         if (ecode != HAL_OK) {
249                 HALDEBUG(ah, HAL_DEBUG_ANY,
250                     "%s: error getting mac address from EEPROM\n", __func__);
251                 goto bad;
252         }
253         /* XXX How about the serial number ? */
254         /* Read Reg Domain */
255         AH_PRIVATE(ah)->ah_currentRD =
256             ath_hal_eepromGet(ah, AR_EEP_REGDMN_0, AH_NULL);
257
258         /*
259          * ah_miscMode is populated by ar5416FillCapabilityInfo()
260          * starting from griffin. Set here to make sure that
261          * AR_MISC_MODE_MIC_NEW_LOC_ENABLE is set before a GTK is
262          * placed into hardware.
263          */
264         if (ahp->ah_miscMode != 0)
265                 OS_REG_WRITE(ah, AR_MISC_MODE, ahp->ah_miscMode);
266
267         ar9285AniSetup(ah);                     /* Anti Noise Immunity */
268         ar5416InitNfHistBuff(AH5416(ah)->ah_cal.nfCalHist);
269
270         HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: return\n", __func__);
271
272         return ah;
273 bad:
274         if (ah != AH_NULL)
275                 ah->ah_detach(ah);
276         if (status)
277                 *status = ecode;
278         return AH_NULL;
279 }
280
281 static void
282 ar9285ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore)
283 {
284         if (AH_PRIVATE(ah)->ah_ispcie && !restore) {
285                 ath_hal_ini_write(ah, &AH5416(ah)->ah_ini_pcieserdes, 1, 0);
286                 OS_DELAY(1000);
287                 OS_REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
288                 OS_REG_WRITE(ah, AR_WA, AR9285_WA_DEFAULT);
289         }
290 }
291
292 static void
293 ar9285WriteIni(struct ath_hal *ah, const struct ieee80211_channel *chan)
294 {
295         u_int modesIndex, freqIndex;
296         int regWrites = 0;
297
298         /* Setup the indices for the next set of register array writes */
299         /* XXX Ignore 11n dynamic mode on the AR5416 for the moment */
300         freqIndex = 2;
301         if (IEEE80211_IS_CHAN_HT40(chan))
302                 modesIndex = 3;
303         else if (IEEE80211_IS_CHAN_108G(chan))
304                 modesIndex = 5;
305         else
306                 modesIndex = 4;
307
308         /* Set correct Baseband to analog shift setting to access analog chips. */
309         OS_REG_WRITE(ah, AR_PHY(0), 0x00000007);
310         OS_REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);
311         regWrites = ath_hal_ini_write(ah, &AH5212(ah)->ah_ini_modes,
312             modesIndex, regWrites);
313         if (AR_SREV_KITE_12_OR_LATER(ah)) {
314                 regWrites = ath_hal_ini_write(ah, &AH9285(ah)->ah_ini_txgain,
315                     modesIndex, regWrites);
316         }
317         regWrites = ath_hal_ini_write(ah, &AH5212(ah)->ah_ini_common,
318             1, regWrites);
319
320         OS_REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
321
322         if (AR_SREV_MERLIN_10_OR_LATER(ah)) {
323                 uint32_t val;
324                 val = OS_REG_READ(ah, AR_PCU_MISC_MODE2) &
325                         (~AR_PCU_MISC_MODE2_HWWAR1);
326                 OS_REG_WRITE(ah, AR_PCU_MISC_MODE2, val);
327                 OS_REG_WRITE(ah, 0x9800 + (651 << 2), 0x11);
328         }
329
330 }
331
332 /*
333  * Fill all software cached or static hardware state information.
334  * Return failure if capabilities are to come from EEPROM and
335  * cannot be read.
336  */
337 static HAL_BOOL
338 ar9285FillCapabilityInfo(struct ath_hal *ah)
339 {
340         HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;
341
342         if (!ar5416FillCapabilityInfo(ah))
343                 return AH_FALSE;
344         pCap->halNumGpioPins = 12;
345         pCap->halWowSupport = AH_TRUE;
346         pCap->halWowMatchPatternExact = AH_TRUE;
347 #if 0
348         pCap->halWowMatchPatternDword = AH_TRUE;
349 #endif
350         pCap->halCSTSupport = AH_TRUE;
351         pCap->halRifsRxSupport = AH_TRUE;
352         pCap->halRifsTxSupport = AH_TRUE;
353         pCap->halRtsAggrLimit = 64*1024;        /* 802.11n max */
354         pCap->halExtChanDfsSupport = AH_TRUE;
355 #if 0
356         /* XXX bluetooth */
357         pCap->halBtCoexSupport = AH_TRUE;
358 #endif
359         pCap->halAutoSleepSupport = AH_FALSE;   /* XXX? */
360 #if 0
361         pCap->hal4kbSplitTransSupport = AH_FALSE;
362 #endif
363         pCap->halRxStbcSupport = 1;
364         pCap->halTxStbcSupport = 1;
365
366         return AH_TRUE;
367 }
368
369 HAL_BOOL
370 ar9285SetAntennaSwitch(struct ath_hal *ah, HAL_ANT_SETTING settings)
371 {
372 #define ANTENNA0_CHAINMASK    0x1
373 #define ANTENNA1_CHAINMASK    0x2
374         struct ath_hal_5416 *ahp = AH5416(ah);
375
376         /* Antenna selection is done by setting the tx/rx chainmasks approp. */
377         switch (settings) {
378         case HAL_ANT_FIXED_A:
379                 /* Enable first antenna only */
380                 ahp->ah_tx_chainmask = ANTENNA0_CHAINMASK;
381                 ahp->ah_rx_chainmask = ANTENNA0_CHAINMASK;
382                 break;
383         case HAL_ANT_FIXED_B:
384                 /* Enable second antenna only, after checking capability */
385                 if (AH_PRIVATE(ah)->ah_caps.halTxChainMask > ANTENNA1_CHAINMASK)
386                         ahp->ah_tx_chainmask = ANTENNA1_CHAINMASK;
387                 ahp->ah_rx_chainmask = ANTENNA1_CHAINMASK;
388                 break;
389         case HAL_ANT_VARIABLE:
390                 /* Restore original chainmask settings */
391                 /* XXX */
392                 ahp->ah_tx_chainmask = AR9285_DEFAULT_TXCHAINMASK;
393                 ahp->ah_rx_chainmask = AR9285_DEFAULT_RXCHAINMASK;
394                 break;
395         }
396         return AH_TRUE;
397 #undef ANTENNA0_CHAINMASK
398 #undef ANTENNA1_CHAINMASK
399 }
400
401 static const char*
402 ar9285Probe(uint16_t vendorid, uint16_t devid)
403 {
404         if (vendorid == ATHEROS_VENDOR_ID && devid == AR9285_DEVID_PCIE)
405                 return "Atheros 9285";
406         return AH_NULL;
407 }
408 AH_CHIP(AR9285, ar9285Probe, ar9285Attach);