]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/ath/ath_hal/ar9001/ar9130_attach.c
[ath] [ath_hal] Propagate the HAL_RESET_TYPE through to the chip reset; set it during...
[FreeBSD/FreeBSD.git] / sys / dev / ath / ath_hal / ar9001 / ar9130_attach.c
1 /*-
2  * SPDX-License-Identifier: ISC
3  *
4  * Copyright (c) 2011 Adrian Chadd, Xenion Pty Ltd
5  * Copyright (c) 2008 Sam Leffler, Errno Consulting
6  * Copyright (c) 2008 Atheros Communications, Inc.
7  *
8  * Permission to use, copy, modify, and/or distribute this software for any
9  * purpose with or without fee is hereby granted, provided that the above
10  * copyright notice and this permission notice appear in all copies.
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19  *
20  * $FreeBSD$
21  */
22 #include "opt_ah.h"
23
24 #include "ah.h"
25 #include "ah_internal.h"
26 #include "ah_devid.h"
27
28 #include "ar5416/ar5416.h"
29 #include "ar5416/ar5416reg.h"
30 #include "ar5416/ar5416phy.h"
31
32 #include "ar9001/ar9130reg.h"
33 #include "ar9001/ar9130_phy.h"
34 #include "ar9001/ar9130_eeprom.h"
35
36 #include "ar9001/ar9130.ini"
37
38 static const HAL_PERCAL_DATA ar9130_iq_cal = {          /* multi sample */
39         .calName = "IQ", .calType = IQ_MISMATCH_CAL,
40         .calNumSamples  = MAX_CAL_SAMPLES,
41         .calCountMax    = PER_MIN_LOG_COUNT,
42         .calCollect     = ar5416IQCalCollect,
43         .calPostProc    = ar5416IQCalibration
44 };
45 static const HAL_PERCAL_DATA ar9130_adc_gain_cal = {    /* multi sample */
46         .calName = "ADC Gain", .calType = ADC_GAIN_CAL,
47         .calNumSamples  = MAX_CAL_SAMPLES,
48         .calCountMax    = PER_MIN_LOG_COUNT,
49         .calCollect     = ar5416AdcGainCalCollect,
50         .calPostProc    = ar5416AdcGainCalibration
51 };
52 static const HAL_PERCAL_DATA ar9130_adc_dc_cal = {      /* multi sample */
53         .calName = "ADC DC", .calType = ADC_DC_CAL,
54         .calNumSamples  = MAX_CAL_SAMPLES,
55         .calCountMax    = PER_MIN_LOG_COUNT,
56         .calCollect     = ar5416AdcDcCalCollect,
57         .calPostProc    = ar5416AdcDcCalibration
58 };
59 static const HAL_PERCAL_DATA ar9130_adc_init_dc_cal = {
60         .calName = "ADC Init DC", .calType = ADC_DC_INIT_CAL,
61         .calNumSamples  = MIN_CAL_SAMPLES,
62         .calCountMax    = INIT_LOG_COUNT,
63         .calCollect     = ar5416AdcDcCalCollect,
64         .calPostProc    = ar5416AdcDcCalibration
65 };
66
67 static HAL_BOOL ar9130FillCapabilityInfo(struct ath_hal *ah);
68
69 /*
70  * Attach for an AR9130 part.
71  */
72 static struct ath_hal *
73 ar9130Attach(uint16_t devid, HAL_SOFTC sc,
74         HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata,
75         HAL_OPS_CONFIG *ah_config,
76         HAL_STATUS *status)
77 {
78         struct ath_hal_5416 *ahp5416;
79         struct ath_hal_5212 *ahp;
80         struct ath_hal *ah;
81         uint32_t val;
82         HAL_STATUS ecode;
83         HAL_BOOL rfStatus;
84
85         HALDEBUG(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n",
86             __func__, sc, (void*) st, (void*) sh);
87
88         /* NB: memory is returned zero'd */
89         ahp5416 = ath_hal_malloc(sizeof (struct ath_hal_5416));
90         if (ahp5416 == AH_NULL) {
91                 HALDEBUG(AH_NULL, HAL_DEBUG_ANY,
92                     "%s: cannot allocate memory for state block\n", __func__);
93                 *status = HAL_ENOMEM;
94                 return AH_NULL;
95         }
96         ar5416InitState(ahp5416, devid, sc, st, sh, status);
97         ahp = &ahp5416->ah_5212;
98         ah = &ahp->ah_priv.h;
99
100         /* XXX override with 9100 specific state */
101         AH5416(ah)->ah_initPLL = ar9130InitPLL;
102         /* XXX should force chainmasks to 0x7, as per ath9k calibration bugs */
103
104         /* override 5416 methods for our needs */
105
106         AH5416(ah)->ah_cal.iqCalData.calData = &ar9130_iq_cal;
107         AH5416(ah)->ah_cal.adcGainCalData.calData = &ar9130_adc_gain_cal;
108         AH5416(ah)->ah_cal.adcDcCalData.calData = &ar9130_adc_dc_cal;
109         AH5416(ah)->ah_cal.adcDcCalInitData.calData = &ar9130_adc_init_dc_cal;
110         AH5416(ah)->ah_cal.suppCals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
111
112         /*
113          * This was hard-set because the initial ath9k port of this
114          * code kept their runtime conditional register #defines.
115          * AR_SREV and the RTC registers have shifted for Howl;
116          * they detected this and changed the values at runtime.
117          * The current port doesn't yet do this; it may do at a
118          * later stage, so this is set early so any routines which
119          * manipulate the registers have ah_macVersion set to base
120          * the above decision upon.
121          */
122         AH_PRIVATE((ah))->ah_macVersion = AR_XSREV_VERSION_HOWL;
123
124         /*
125          * Use the "local" EEPROM data given to us by the higher layers.
126          * This is a private copy out of system flash.
127          * By this stage the SoC SPI flash may have disabled the memory-
128          * mapping and rely purely on port-based SPI IO.
129          */
130         AH_PRIVATE((ah))->ah_eepromRead = ath_hal_EepromDataRead;
131         AH_PRIVATE((ah))->ah_eepromWrite = NULL;
132         ah->ah_eepromdata = eepromdata;
133
134         if (!ar5416SetResetReg(ah, HAL_RESET_POWER_ON)) {
135                 /* reset chip */
136                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: couldn't reset chip\n",
137                     __func__);
138                 ecode = HAL_EIO;
139                 goto bad;
140         }
141
142         if (!ar5416SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) {
143                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: couldn't wakeup chip\n",
144                     __func__);
145                 ecode = HAL_EIO;
146                 goto bad;
147         }
148         /* Read Revisions from Chips before taking out of reset */
149         val = OS_REG_READ(ah, AR_SREV_CHIP_HOWL) & AR_SREV_CHIP_HOWL_ID;
150
151         /* XXX are these values even valid for the mac/radio revision? -adrian */
152         HALDEBUG(ah, HAL_DEBUG_ATTACH,
153             "%s: ID 0x%x VERSION 0x%x TYPE 0x%x REVISION 0x%x\n",
154             __func__, MS(val, AR_XSREV_ID), MS(val, AR_XSREV_VERSION),
155             MS(val, AR_XSREV_TYPE), MS(val, AR_XSREV_REVISION));
156         AH_PRIVATE(ah)->ah_macRev = MS(val, AR_XSREV_REVISION);
157         AH_PRIVATE(ah)->ah_ispcie = 0;
158
159         /* setup common ini data; rf backends handle remainder */
160         HAL_INI_INIT(&ahp->ah_ini_modes, ar5416Modes_9100, 6);
161         HAL_INI_INIT(&ahp->ah_ini_common, ar5416Common_9100, 2);
162
163         HAL_INI_INIT(&AH5416(ah)->ah_ini_bb_rfgain, ar5416BB_RfGain_9100, 3);
164         HAL_INI_INIT(&AH5416(ah)->ah_ini_bank0, ar5416Bank0_9100, 2);
165         HAL_INI_INIT(&AH5416(ah)->ah_ini_bank1, ar5416Bank1_9100, 2);
166         HAL_INI_INIT(&AH5416(ah)->ah_ini_bank2, ar5416Bank2_9100, 2);
167         HAL_INI_INIT(&AH5416(ah)->ah_ini_bank3, ar5416Bank3_9100, 3);
168         HAL_INI_INIT(&AH5416(ah)->ah_ini_bank6, ar5416Bank6TPC_9100, 3);
169         HAL_INI_INIT(&AH5416(ah)->ah_ini_bank7, ar5416Bank7_9100, 2);
170         HAL_INI_INIT(&AH5416(ah)->ah_ini_addac, ar5416Addac_9100, 2);
171
172         ecode = ath_hal_v14EepromAttach(ah);
173         if (ecode != HAL_OK)
174                 goto bad;
175
176         if (!ar5416ChipReset(ah, AH_NULL, HAL_RESET_NORMAL)) {  /* reset chip */
177                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", __func__);
178                 ecode = HAL_EIO;
179                 goto bad;
180         }
181
182         AH_PRIVATE(ah)->ah_phyRev = OS_REG_READ(ah, AR_PHY_CHIP_ID);
183
184         if (!ar5212ChipTest(ah)) {
185                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: hardware self-test failed\n",
186                     __func__);
187                 ecode = HAL_ESELFTEST;
188                 goto bad;
189         }
190
191         /*
192          * Set correct Baseband to analog shift
193          * setting to access analog chips.
194          */
195         OS_REG_WRITE(ah, AR_PHY(0), 0x00000007);
196
197         /* Read Radio Chip Rev Extract */
198         AH_PRIVATE(ah)->ah_analog5GhzRev = ar5416GetRadioRev(ah);
199         switch (AH_PRIVATE(ah)->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR) {
200         case AR_RAD2133_SREV_MAJOR:     /* Sowl: 2G/3x3 */
201         case AR_RAD5133_SREV_MAJOR:     /* Sowl: 2+5G/3x3 */
202                 break;
203         default:
204                 if (AH_PRIVATE(ah)->ah_analog5GhzRev == 0) {
205                         AH_PRIVATE(ah)->ah_analog5GhzRev =
206                                 AR_RAD5133_SREV_MAJOR;
207                         break;
208                 }
209 #ifdef AH_DEBUG
210                 HALDEBUG(ah, HAL_DEBUG_ANY,
211                     "%s: 5G Radio Chip Rev 0x%02X is not supported by "
212                     "this driver\n", __func__,
213                     AH_PRIVATE(ah)->ah_analog5GhzRev);
214                 ecode = HAL_ENOTSUPP;
215                 goto bad;
216 #endif
217         }
218         rfStatus = ar2133RfAttach(ah, &ecode);
219         if (!rfStatus) {
220                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: RF setup failed, status %u\n",
221                     __func__, ecode);
222                 goto bad;
223         }
224
225         /*
226          * Got everything we need now to setup the capabilities.
227          */
228         if (!ar9130FillCapabilityInfo(ah)) {
229                 ecode = HAL_EEREAD;
230                 goto bad;
231         }
232
233         ecode = ath_hal_eepromGet(ah, AR_EEP_MACADDR, ahp->ah_macaddr);
234         if (ecode != HAL_OK) {
235                 HALDEBUG(ah, HAL_DEBUG_ANY,
236                     "%s: error getting mac address from EEPROM\n", __func__);
237                 goto bad;
238         }
239         /* XXX How about the serial number ? */
240         /* Read Reg Domain */
241         AH_PRIVATE(ah)->ah_currentRD =
242             ath_hal_eepromGet(ah, AR_EEP_REGDMN_0, AH_NULL);
243         AH_PRIVATE(ah)->ah_currentRDext =
244             ath_hal_eepromGet(ah, AR_EEP_REGDMN_1, AH_NULL);
245
246
247         /*
248          * ah_miscMode is populated by ar5416FillCapabilityInfo()
249          * starting from griffin. Set here to make sure that
250          * AR_MISC_MODE_MIC_NEW_LOC_ENABLE is set before a GTK is
251          * placed into hardware.
252          */
253         if (ahp->ah_miscMode != 0)
254                 OS_REG_WRITE(ah, AR_MISC_MODE, ahp->ah_miscMode);
255
256         /* XXX no ANI for AR9130 */
257         AH5416(ah)->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_5416_2GHZ;
258         AH5416(ah)->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_5416_2GHZ;
259         AH5416(ah)->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_5416_2GHZ;
260         AH5416(ah)->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_5416_5GHZ;
261         AH5416(ah)->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_5416_5GHZ;
262         AH5416(ah)->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_5416_5GHZ;
263
264         ar5416InitNfHistBuff(AH5416(ah)->ah_cal.nfCalHist);
265
266         HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: return\n", __func__);
267
268         return ah;
269 bad:
270         if (ahp)
271                 ar5416Detach((struct ath_hal *) ahp);
272         if (status)
273                 *status = ecode;
274         return AH_NULL;
275 }
276
277 /*
278  * Fill all software cached or static hardware state information.
279  * Return failure if capabilities are to come from EEPROM and
280  * cannot be read.
281  */
282 static HAL_BOOL
283 ar9130FillCapabilityInfo(struct ath_hal *ah)
284 {
285         HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;
286
287         HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: begin\n", __func__);
288         if (!ar5416FillCapabilityInfo(ah))
289                 return AH_FALSE;
290         HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: fill'ed; now setting\n", __func__);
291         pCap->halCSTSupport = AH_TRUE;
292         pCap->halRifsRxSupport = AH_TRUE;
293         pCap->halRifsTxSupport = AH_TRUE;
294         pCap->halRtsAggrLimit = 64*1024;        /* 802.11n max */
295         pCap->halExtChanDfsSupport = AH_TRUE;
296         pCap->halUseCombinedRadarRssi = AH_TRUE;
297         pCap->halAutoSleepSupport = AH_FALSE;   /* XXX? */
298         /*
299          * MBSSID aggregation is broken in Howl v1.1, v1.2, v1.3
300          * and works fine in v1.4.
301          * XXX todo, enable it for v1.4.
302          */
303         pCap->halMbssidAggrSupport = AH_FALSE;
304         pCap->hal4AddrAggrSupport = AH_TRUE;
305         /* BB Read WAR */
306         pCap->halHasBBReadWar = AH_TRUE;
307
308         /*
309          * Implement the PLL/config changes needed for half/quarter
310          * rates before re-enabling them here.
311          */
312         pCap->halChanHalfRate = AH_FALSE;
313         pCap->halChanQuarterRate = AH_FALSE;
314
315         return AH_TRUE;
316 }
317
318 static const char*
319 ar9130Probe(uint16_t vendorid, uint16_t devid)
320 {
321         if (vendorid == ATHEROS_VENDOR_ID && devid == AR5416_AR9130_DEVID)
322                 return "Atheros 9130";
323         return AH_NULL;
324 }
325 AH_CHIP(AR9130, ar9130Probe, ar9130Attach);