1*9999SWang.Lin@Sun.COM /*
2*9999SWang.Lin@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
3*9999SWang.Lin@Sun.COM * Use is subject to license terms.
4*9999SWang.Lin@Sun.COM */
5*9999SWang.Lin@Sun.COM
6*9999SWang.Lin@Sun.COM /*
7*9999SWang.Lin@Sun.COM * Copyright (c) 2008 Atheros Communications Inc.
8*9999SWang.Lin@Sun.COM *
9*9999SWang.Lin@Sun.COM * Permission to use, copy, modify, and/or distribute this software for any
10*9999SWang.Lin@Sun.COM * purpose with or without fee is hereby granted, provided that the above
11*9999SWang.Lin@Sun.COM * copyright notice and this permission notice appear in all copies.
12*9999SWang.Lin@Sun.COM *
13*9999SWang.Lin@Sun.COM * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14*9999SWang.Lin@Sun.COM * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15*9999SWang.Lin@Sun.COM * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16*9999SWang.Lin@Sun.COM * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17*9999SWang.Lin@Sun.COM * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18*9999SWang.Lin@Sun.COM * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19*9999SWang.Lin@Sun.COM * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20*9999SWang.Lin@Sun.COM */
21*9999SWang.Lin@Sun.COM
22*9999SWang.Lin@Sun.COM #include "arn_core.h"
23*9999SWang.Lin@Sun.COM #include "arn_hw.h"
24*9999SWang.Lin@Sun.COM #include "arn_reg.h"
25*9999SWang.Lin@Sun.COM #include "arn_phy.h"
26*9999SWang.Lin@Sun.COM
27*9999SWang.Lin@Sun.COM /* ARGSUSED */
28*9999SWang.Lin@Sun.COM void
ath9k_hw_write_regs(struct ath_hal * ah,uint32_t modesIndex,uint32_t freqIndex,int regWrites)29*9999SWang.Lin@Sun.COM ath9k_hw_write_regs(struct ath_hal *ah, uint32_t modesIndex, uint32_t freqIndex,
30*9999SWang.Lin@Sun.COM int regWrites)
31*9999SWang.Lin@Sun.COM {
32*9999SWang.Lin@Sun.COM struct ath_hal_5416 *ahp = AH5416(ah);
33*9999SWang.Lin@Sun.COM
34*9999SWang.Lin@Sun.COM /* LINTED: E_CONSTANT_CONDITION */
35*9999SWang.Lin@Sun.COM REG_WRITE_ARRAY(&ahp->ah_iniBB_RfGain, freqIndex, regWrites);
36*9999SWang.Lin@Sun.COM }
37*9999SWang.Lin@Sun.COM
38*9999SWang.Lin@Sun.COM boolean_t
ath9k_hw_set_channel(struct ath_hal * ah,struct ath9k_channel * chan)39*9999SWang.Lin@Sun.COM ath9k_hw_set_channel(struct ath_hal *ah, struct ath9k_channel *chan)
40*9999SWang.Lin@Sun.COM {
41*9999SWang.Lin@Sun.COM uint32_t channelSel = 0;
42*9999SWang.Lin@Sun.COM uint32_t bModeSynth = 0;
43*9999SWang.Lin@Sun.COM uint32_t aModeRefSel = 0;
44*9999SWang.Lin@Sun.COM uint32_t reg32 = 0;
45*9999SWang.Lin@Sun.COM uint16_t freq;
46*9999SWang.Lin@Sun.COM struct chan_centers centers;
47*9999SWang.Lin@Sun.COM
48*9999SWang.Lin@Sun.COM ath9k_hw_get_channel_centers(ah, chan, ¢ers);
49*9999SWang.Lin@Sun.COM freq = centers.synth_center;
50*9999SWang.Lin@Sun.COM
51*9999SWang.Lin@Sun.COM if (freq < 4800) {
52*9999SWang.Lin@Sun.COM uint32_t txctl;
53*9999SWang.Lin@Sun.COM
54*9999SWang.Lin@Sun.COM if (((freq - 2192) % 5) == 0) {
55*9999SWang.Lin@Sun.COM channelSel = ((freq - 672) * 2 - 3040) / 10;
56*9999SWang.Lin@Sun.COM bModeSynth = 0;
57*9999SWang.Lin@Sun.COM } else if (((freq - 2224) % 5) == 0) {
58*9999SWang.Lin@Sun.COM channelSel = ((freq - 704) * 2 - 3040) / 10;
59*9999SWang.Lin@Sun.COM bModeSynth = 1;
60*9999SWang.Lin@Sun.COM } else {
61*9999SWang.Lin@Sun.COM arn_problem("%s: invalid channel %u MHz\n",
62*9999SWang.Lin@Sun.COM __func__, freq);
63*9999SWang.Lin@Sun.COM return (B_FALSE);
64*9999SWang.Lin@Sun.COM }
65*9999SWang.Lin@Sun.COM
66*9999SWang.Lin@Sun.COM channelSel = (channelSel << 2) & 0xff;
67*9999SWang.Lin@Sun.COM channelSel = ath9k_hw_reverse_bits(channelSel, 8);
68*9999SWang.Lin@Sun.COM
69*9999SWang.Lin@Sun.COM txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL);
70*9999SWang.Lin@Sun.COM if (freq == 2484) {
71*9999SWang.Lin@Sun.COM
72*9999SWang.Lin@Sun.COM REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
73*9999SWang.Lin@Sun.COM txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
74*9999SWang.Lin@Sun.COM } else {
75*9999SWang.Lin@Sun.COM REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
76*9999SWang.Lin@Sun.COM txctl & ~AR_PHY_CCK_TX_CTRL_JAPAN);
77*9999SWang.Lin@Sun.COM }
78*9999SWang.Lin@Sun.COM
79*9999SWang.Lin@Sun.COM } else if ((freq % 20) == 0 && freq >= 5120) {
80*9999SWang.Lin@Sun.COM channelSel =
81*9999SWang.Lin@Sun.COM ath9k_hw_reverse_bits(((freq - 4800) / 20 << 2), 8);
82*9999SWang.Lin@Sun.COM aModeRefSel = ath9k_hw_reverse_bits(1, 2);
83*9999SWang.Lin@Sun.COM } else if ((freq % 10) == 0) {
84*9999SWang.Lin@Sun.COM channelSel =
85*9999SWang.Lin@Sun.COM ath9k_hw_reverse_bits(((freq - 4800) / 10 << 1), 8);
86*9999SWang.Lin@Sun.COM if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah))
87*9999SWang.Lin@Sun.COM aModeRefSel = ath9k_hw_reverse_bits(2, 2);
88*9999SWang.Lin@Sun.COM else
89*9999SWang.Lin@Sun.COM aModeRefSel = ath9k_hw_reverse_bits(1, 2);
90*9999SWang.Lin@Sun.COM } else if ((freq % 5) == 0) {
91*9999SWang.Lin@Sun.COM channelSel = ath9k_hw_reverse_bits((freq - 4800) / 5, 8);
92*9999SWang.Lin@Sun.COM aModeRefSel = ath9k_hw_reverse_bits(1, 2);
93*9999SWang.Lin@Sun.COM } else {
94*9999SWang.Lin@Sun.COM arn_problem("%s: invalid channel %u MHz\n", __func__, freq);
95*9999SWang.Lin@Sun.COM return (B_FALSE);
96*9999SWang.Lin@Sun.COM }
97*9999SWang.Lin@Sun.COM
98*9999SWang.Lin@Sun.COM reg32 =
99*9999SWang.Lin@Sun.COM (channelSel << 8) | (aModeRefSel << 2) | (bModeSynth << 1) |
100*9999SWang.Lin@Sun.COM (1 << 5) | 0x1;
101*9999SWang.Lin@Sun.COM
102*9999SWang.Lin@Sun.COM REG_WRITE(ah, AR_PHY(0x37), reg32);
103*9999SWang.Lin@Sun.COM
104*9999SWang.Lin@Sun.COM ah->ah_curchan = chan;
105*9999SWang.Lin@Sun.COM
106*9999SWang.Lin@Sun.COM AH5416(ah)->ah_curchanRadIndex = -1;
107*9999SWang.Lin@Sun.COM
108*9999SWang.Lin@Sun.COM return (B_TRUE);
109*9999SWang.Lin@Sun.COM }
110*9999SWang.Lin@Sun.COM
111*9999SWang.Lin@Sun.COM boolean_t
ath9k_hw_ar9280_set_channel(struct ath_hal * ah,struct ath9k_channel * chan)112*9999SWang.Lin@Sun.COM ath9k_hw_ar9280_set_channel(struct ath_hal *ah,
113*9999SWang.Lin@Sun.COM struct ath9k_channel *chan)
114*9999SWang.Lin@Sun.COM {
115*9999SWang.Lin@Sun.COM uint16_t bMode, fracMode, aModeRefSel = 0;
116*9999SWang.Lin@Sun.COM uint32_t freq, ndiv, channelSel = 0, channelFrac = 0, reg32 = 0;
117*9999SWang.Lin@Sun.COM struct chan_centers centers;
118*9999SWang.Lin@Sun.COM uint32_t refDivA = 24;
119*9999SWang.Lin@Sun.COM
120*9999SWang.Lin@Sun.COM ath9k_hw_get_channel_centers(ah, chan, ¢ers);
121*9999SWang.Lin@Sun.COM freq = centers.synth_center;
122*9999SWang.Lin@Sun.COM
123*9999SWang.Lin@Sun.COM reg32 = REG_READ(ah, AR_PHY_SYNTH_CONTROL);
124*9999SWang.Lin@Sun.COM reg32 &= 0xc0000000;
125*9999SWang.Lin@Sun.COM
126*9999SWang.Lin@Sun.COM if (freq < 4800) {
127*9999SWang.Lin@Sun.COM uint32_t txctl;
128*9999SWang.Lin@Sun.COM
129*9999SWang.Lin@Sun.COM bMode = 1;
130*9999SWang.Lin@Sun.COM fracMode = 1;
131*9999SWang.Lin@Sun.COM aModeRefSel = 0;
132*9999SWang.Lin@Sun.COM channelSel = (freq * 0x10000) / 15;
133*9999SWang.Lin@Sun.COM
134*9999SWang.Lin@Sun.COM txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL);
135*9999SWang.Lin@Sun.COM if (freq == 2484) {
136*9999SWang.Lin@Sun.COM
137*9999SWang.Lin@Sun.COM REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
138*9999SWang.Lin@Sun.COM txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
139*9999SWang.Lin@Sun.COM } else {
140*9999SWang.Lin@Sun.COM REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
141*9999SWang.Lin@Sun.COM txctl & ~AR_PHY_CCK_TX_CTRL_JAPAN);
142*9999SWang.Lin@Sun.COM }
143*9999SWang.Lin@Sun.COM } else {
144*9999SWang.Lin@Sun.COM bMode = 0;
145*9999SWang.Lin@Sun.COM fracMode = 0;
146*9999SWang.Lin@Sun.COM
147*9999SWang.Lin@Sun.COM if ((freq % 20) == 0) {
148*9999SWang.Lin@Sun.COM aModeRefSel = 3;
149*9999SWang.Lin@Sun.COM } else if ((freq % 10) == 0) {
150*9999SWang.Lin@Sun.COM aModeRefSel = 2;
151*9999SWang.Lin@Sun.COM } else {
152*9999SWang.Lin@Sun.COM aModeRefSel = 0;
153*9999SWang.Lin@Sun.COM
154*9999SWang.Lin@Sun.COM fracMode = 1;
155*9999SWang.Lin@Sun.COM refDivA = 1;
156*9999SWang.Lin@Sun.COM channelSel = (freq * 0x8000) / 15;
157*9999SWang.Lin@Sun.COM
158*9999SWang.Lin@Sun.COM REG_RMW_FIELD(ah, AR_AN_SYNTH9,
159*9999SWang.Lin@Sun.COM AR_AN_SYNTH9_REFDIVA, refDivA);
160*9999SWang.Lin@Sun.COM }
161*9999SWang.Lin@Sun.COM if (!fracMode) {
162*9999SWang.Lin@Sun.COM ndiv = (freq * (refDivA >> aModeRefSel)) / 60;
163*9999SWang.Lin@Sun.COM channelSel = ndiv & 0x1ff;
164*9999SWang.Lin@Sun.COM channelFrac = (ndiv & 0xfffffe00) * 2;
165*9999SWang.Lin@Sun.COM channelSel = (channelSel << 17) | channelFrac;
166*9999SWang.Lin@Sun.COM }
167*9999SWang.Lin@Sun.COM }
168*9999SWang.Lin@Sun.COM
169*9999SWang.Lin@Sun.COM reg32 = reg32 |
170*9999SWang.Lin@Sun.COM (bMode << 29) |
171*9999SWang.Lin@Sun.COM (fracMode << 28) | (aModeRefSel << 26) | (channelSel);
172*9999SWang.Lin@Sun.COM
173*9999SWang.Lin@Sun.COM REG_WRITE(ah, AR_PHY_SYNTH_CONTROL, reg32);
174*9999SWang.Lin@Sun.COM
175*9999SWang.Lin@Sun.COM ah->ah_curchan = chan;
176*9999SWang.Lin@Sun.COM
177*9999SWang.Lin@Sun.COM AH5416(ah)->ah_curchanRadIndex = -1;
178*9999SWang.Lin@Sun.COM
179*9999SWang.Lin@Sun.COM return (B_TRUE);
180*9999SWang.Lin@Sun.COM }
181*9999SWang.Lin@Sun.COM
182*9999SWang.Lin@Sun.COM static void
ath9k_phy_modify_rx_buffer(uint32_t * rfBuf,uint32_t reg32,uint32_t numBits,uint32_t firstBit,uint32_t column)183*9999SWang.Lin@Sun.COM ath9k_phy_modify_rx_buffer(uint32_t *rfBuf, uint32_t reg32,
184*9999SWang.Lin@Sun.COM uint32_t numBits, uint32_t firstBit, uint32_t column)
185*9999SWang.Lin@Sun.COM {
186*9999SWang.Lin@Sun.COM uint32_t tmp32, mask, arrayEntry, lastBit;
187*9999SWang.Lin@Sun.COM int32_t bitPosition, bitsLeft;
188*9999SWang.Lin@Sun.COM
189*9999SWang.Lin@Sun.COM tmp32 = ath9k_hw_reverse_bits(reg32, numBits);
190*9999SWang.Lin@Sun.COM arrayEntry = (firstBit - 1) / 8;
191*9999SWang.Lin@Sun.COM bitPosition = (firstBit - 1) % 8;
192*9999SWang.Lin@Sun.COM bitsLeft = numBits;
193*9999SWang.Lin@Sun.COM while (bitsLeft > 0) {
194*9999SWang.Lin@Sun.COM lastBit = (bitPosition + bitsLeft > 8) ?
195*9999SWang.Lin@Sun.COM 8 : bitPosition + bitsLeft;
196*9999SWang.Lin@Sun.COM mask = (((1 << lastBit) - 1) ^ ((1 << bitPosition) - 1)) <<
197*9999SWang.Lin@Sun.COM (column * 8);
198*9999SWang.Lin@Sun.COM rfBuf[arrayEntry] &= ~mask;
199*9999SWang.Lin@Sun.COM rfBuf[arrayEntry] |= ((tmp32 << bitPosition) <<
200*9999SWang.Lin@Sun.COM (column * 8)) & mask;
201*9999SWang.Lin@Sun.COM bitsLeft -= 8 - bitPosition;
202*9999SWang.Lin@Sun.COM tmp32 = tmp32 >> (8 - bitPosition);
203*9999SWang.Lin@Sun.COM bitPosition = 0;
204*9999SWang.Lin@Sun.COM arrayEntry++;
205*9999SWang.Lin@Sun.COM }
206*9999SWang.Lin@Sun.COM }
207*9999SWang.Lin@Sun.COM
208*9999SWang.Lin@Sun.COM boolean_t
ath9k_hw_set_rf_regs(struct ath_hal * ah,struct ath9k_channel * chan,uint16_t modesIndex)209*9999SWang.Lin@Sun.COM ath9k_hw_set_rf_regs(struct ath_hal *ah, struct ath9k_channel *chan,
210*9999SWang.Lin@Sun.COM uint16_t modesIndex)
211*9999SWang.Lin@Sun.COM {
212*9999SWang.Lin@Sun.COM struct ath_hal_5416 *ahp = AH5416(ah);
213*9999SWang.Lin@Sun.COM
214*9999SWang.Lin@Sun.COM uint32_t eepMinorRev;
215*9999SWang.Lin@Sun.COM uint32_t ob5GHz = 0, db5GHz = 0;
216*9999SWang.Lin@Sun.COM uint32_t ob2GHz = 0, db2GHz = 0;
217*9999SWang.Lin@Sun.COM /* LINTED E_FUNC_SET_NOT_USED */
218*9999SWang.Lin@Sun.COM int regWrites = 0;
219*9999SWang.Lin@Sun.COM
220*9999SWang.Lin@Sun.COM if (AR_SREV_9280_10_OR_LATER(ah))
221*9999SWang.Lin@Sun.COM return (B_TRUE);
222*9999SWang.Lin@Sun.COM
223*9999SWang.Lin@Sun.COM eepMinorRev = ath9k_hw_get_eeprom(ah, EEP_MINOR_REV);
224*9999SWang.Lin@Sun.COM
225*9999SWang.Lin@Sun.COM RF_BANK_SETUP(ahp->ah_analogBank0Data, &ahp->ah_iniBank0, 1);
226*9999SWang.Lin@Sun.COM
227*9999SWang.Lin@Sun.COM RF_BANK_SETUP(ahp->ah_analogBank1Data, &ahp->ah_iniBank1, 1);
228*9999SWang.Lin@Sun.COM
229*9999SWang.Lin@Sun.COM RF_BANK_SETUP(ahp->ah_analogBank2Data, &ahp->ah_iniBank2, 1);
230*9999SWang.Lin@Sun.COM
231*9999SWang.Lin@Sun.COM RF_BANK_SETUP(ahp->ah_analogBank3Data, &ahp->ah_iniBank3,
232*9999SWang.Lin@Sun.COM modesIndex);
233*9999SWang.Lin@Sun.COM {
234*9999SWang.Lin@Sun.COM int i;
235*9999SWang.Lin@Sun.COM for (i = 0; i < ahp->ah_iniBank6TPC.ia_rows; i++) {
236*9999SWang.Lin@Sun.COM ahp->ah_analogBank6Data[i] =
237*9999SWang.Lin@Sun.COM INI_RA(&ahp->ah_iniBank6TPC, i, modesIndex);
238*9999SWang.Lin@Sun.COM }
239*9999SWang.Lin@Sun.COM }
240*9999SWang.Lin@Sun.COM
241*9999SWang.Lin@Sun.COM if (eepMinorRev >= 2) {
242*9999SWang.Lin@Sun.COM if (IS_CHAN_2GHZ(chan)) {
243*9999SWang.Lin@Sun.COM ob2GHz = ath9k_hw_get_eeprom(ah, EEP_OB_2);
244*9999SWang.Lin@Sun.COM db2GHz = ath9k_hw_get_eeprom(ah, EEP_DB_2);
245*9999SWang.Lin@Sun.COM ath9k_phy_modify_rx_buffer(ahp->ah_analogBank6Data,
246*9999SWang.Lin@Sun.COM ob2GHz, 3, 197, 0);
247*9999SWang.Lin@Sun.COM ath9k_phy_modify_rx_buffer(ahp->ah_analogBank6Data,
248*9999SWang.Lin@Sun.COM db2GHz, 3, 194, 0);
249*9999SWang.Lin@Sun.COM } else {
250*9999SWang.Lin@Sun.COM ob5GHz = ath9k_hw_get_eeprom(ah, EEP_OB_5);
251*9999SWang.Lin@Sun.COM db5GHz = ath9k_hw_get_eeprom(ah, EEP_DB_5);
252*9999SWang.Lin@Sun.COM ath9k_phy_modify_rx_buffer(ahp->ah_analogBank6Data,
253*9999SWang.Lin@Sun.COM ob5GHz, 3, 203, 0);
254*9999SWang.Lin@Sun.COM ath9k_phy_modify_rx_buffer(ahp->ah_analogBank6Data,
255*9999SWang.Lin@Sun.COM db5GHz, 3, 200, 0);
256*9999SWang.Lin@Sun.COM }
257*9999SWang.Lin@Sun.COM }
258*9999SWang.Lin@Sun.COM
259*9999SWang.Lin@Sun.COM RF_BANK_SETUP(ahp->ah_analogBank7Data, &ahp->ah_iniBank7, 1);
260*9999SWang.Lin@Sun.COM
261*9999SWang.Lin@Sun.COM REG_WRITE_RF_ARRAY(&ahp->ah_iniBank0, ahp->ah_analogBank0Data,
262*9999SWang.Lin@Sun.COM regWrites);
263*9999SWang.Lin@Sun.COM
264*9999SWang.Lin@Sun.COM REG_WRITE_RF_ARRAY(&ahp->ah_iniBank1, ahp->ah_analogBank1Data,
265*9999SWang.Lin@Sun.COM regWrites);
266*9999SWang.Lin@Sun.COM
267*9999SWang.Lin@Sun.COM REG_WRITE_RF_ARRAY(&ahp->ah_iniBank2, ahp->ah_analogBank2Data,
268*9999SWang.Lin@Sun.COM regWrites);
269*9999SWang.Lin@Sun.COM
270*9999SWang.Lin@Sun.COM REG_WRITE_RF_ARRAY(&ahp->ah_iniBank3, ahp->ah_analogBank3Data,
271*9999SWang.Lin@Sun.COM regWrites);
272*9999SWang.Lin@Sun.COM
273*9999SWang.Lin@Sun.COM REG_WRITE_RF_ARRAY(&ahp->ah_iniBank6TPC, ahp->ah_analogBank6Data,
274*9999SWang.Lin@Sun.COM regWrites);
275*9999SWang.Lin@Sun.COM
276*9999SWang.Lin@Sun.COM REG_WRITE_RF_ARRAY(&ahp->ah_iniBank7, ahp->ah_analogBank7Data,
277*9999SWang.Lin@Sun.COM regWrites);
278*9999SWang.Lin@Sun.COM
279*9999SWang.Lin@Sun.COM return (B_TRUE);
280*9999SWang.Lin@Sun.COM }
281*9999SWang.Lin@Sun.COM
282*9999SWang.Lin@Sun.COM void
ath9k_hw_rfdetach(struct ath_hal * ah)283*9999SWang.Lin@Sun.COM ath9k_hw_rfdetach(struct ath_hal *ah)
284*9999SWang.Lin@Sun.COM {
285*9999SWang.Lin@Sun.COM struct ath_hal_5416 *ahp = AH5416(ah);
286*9999SWang.Lin@Sun.COM
287*9999SWang.Lin@Sun.COM if (ahp->ah_analogBank0Data != NULL) {
288*9999SWang.Lin@Sun.COM kmem_free(ahp->ah_analogBank0Data,
289*9999SWang.Lin@Sun.COM (sizeof (uint32_t) * ahp->ah_iniBank0.ia_rows));
290*9999SWang.Lin@Sun.COM ahp->ah_analogBank0Data = NULL;
291*9999SWang.Lin@Sun.COM }
292*9999SWang.Lin@Sun.COM if (ahp->ah_analogBank1Data != NULL) {
293*9999SWang.Lin@Sun.COM kmem_free(ahp->ah_analogBank1Data,
294*9999SWang.Lin@Sun.COM (sizeof (uint32_t) * ahp->ah_iniBank1.ia_rows));
295*9999SWang.Lin@Sun.COM ahp->ah_analogBank1Data = NULL;
296*9999SWang.Lin@Sun.COM }
297*9999SWang.Lin@Sun.COM if (ahp->ah_analogBank2Data != NULL) {
298*9999SWang.Lin@Sun.COM kmem_free(ahp->ah_analogBank2Data,
299*9999SWang.Lin@Sun.COM (sizeof (uint32_t) * ahp->ah_iniBank2.ia_rows));
300*9999SWang.Lin@Sun.COM ahp->ah_analogBank2Data = NULL;
301*9999SWang.Lin@Sun.COM }
302*9999SWang.Lin@Sun.COM if (ahp->ah_analogBank3Data != NULL) {
303*9999SWang.Lin@Sun.COM kmem_free(ahp->ah_analogBank3Data,
304*9999SWang.Lin@Sun.COM (sizeof (uint32_t) * ahp->ah_iniBank3.ia_rows));
305*9999SWang.Lin@Sun.COM ahp->ah_analogBank3Data = NULL;
306*9999SWang.Lin@Sun.COM }
307*9999SWang.Lin@Sun.COM if (ahp->ah_analogBank6Data != NULL) {
308*9999SWang.Lin@Sun.COM kmem_free(ahp->ah_analogBank6Data,
309*9999SWang.Lin@Sun.COM (sizeof (uint32_t) * ahp->ah_iniBank6.ia_rows));
310*9999SWang.Lin@Sun.COM ahp->ah_analogBank6Data = NULL;
311*9999SWang.Lin@Sun.COM }
312*9999SWang.Lin@Sun.COM if (ahp->ah_analogBank6TPCData != NULL) {
313*9999SWang.Lin@Sun.COM kmem_free(ahp->ah_analogBank6TPCData,
314*9999SWang.Lin@Sun.COM (sizeof (uint32_t) * ahp->ah_iniBank6TPC.ia_rows));
315*9999SWang.Lin@Sun.COM ahp->ah_analogBank6TPCData = NULL;
316*9999SWang.Lin@Sun.COM }
317*9999SWang.Lin@Sun.COM if (ahp->ah_analogBank7Data != NULL) {
318*9999SWang.Lin@Sun.COM kmem_free(ahp->ah_analogBank7Data,
319*9999SWang.Lin@Sun.COM (sizeof (uint32_t) * ahp->ah_iniBank7.ia_rows));
320*9999SWang.Lin@Sun.COM ahp->ah_analogBank7Data = NULL;
321*9999SWang.Lin@Sun.COM }
322*9999SWang.Lin@Sun.COM if (ahp->ah_addac5416_21 != NULL) {
323*9999SWang.Lin@Sun.COM kmem_free(ahp->ah_addac5416_21,
324*9999SWang.Lin@Sun.COM (sizeof (uint32_t) * ahp->ah_iniAddac.ia_rows *
325*9999SWang.Lin@Sun.COM ahp->ah_iniAddac.ia_columns));
326*9999SWang.Lin@Sun.COM ahp->ah_addac5416_21 = NULL;
327*9999SWang.Lin@Sun.COM }
328*9999SWang.Lin@Sun.COM if (ahp->ah_bank6Temp != NULL) {
329*9999SWang.Lin@Sun.COM kmem_free(ahp->ah_bank6Temp,
330*9999SWang.Lin@Sun.COM (sizeof (uint32_t) * ahp->ah_iniBank6.ia_rows));
331*9999SWang.Lin@Sun.COM ahp->ah_bank6Temp = NULL;
332*9999SWang.Lin@Sun.COM }
333*9999SWang.Lin@Sun.COM }
334*9999SWang.Lin@Sun.COM
335*9999SWang.Lin@Sun.COM boolean_t
ath9k_hw_init_rf(struct ath_hal * ah,int * status)336*9999SWang.Lin@Sun.COM ath9k_hw_init_rf(struct ath_hal *ah, int *status)
337*9999SWang.Lin@Sun.COM {
338*9999SWang.Lin@Sun.COM struct ath_hal_5416 *ahp = AH5416(ah);
339*9999SWang.Lin@Sun.COM
340*9999SWang.Lin@Sun.COM if (!AR_SREV_9280_10_OR_LATER(ah)) {
341*9999SWang.Lin@Sun.COM
342*9999SWang.Lin@Sun.COM ahp->ah_analogBank0Data =
343*9999SWang.Lin@Sun.COM kmem_zalloc((sizeof (uint32_t) *
344*9999SWang.Lin@Sun.COM ahp->ah_iniBank0.ia_rows), KM_SLEEP);
345*9999SWang.Lin@Sun.COM ahp->ah_analogBank1Data =
346*9999SWang.Lin@Sun.COM kmem_zalloc((sizeof (uint32_t) *
347*9999SWang.Lin@Sun.COM ahp->ah_iniBank1.ia_rows), KM_SLEEP);
348*9999SWang.Lin@Sun.COM ahp->ah_analogBank2Data =
349*9999SWang.Lin@Sun.COM kmem_zalloc((sizeof (uint32_t) *
350*9999SWang.Lin@Sun.COM ahp->ah_iniBank2.ia_rows), KM_SLEEP);
351*9999SWang.Lin@Sun.COM ahp->ah_analogBank3Data =
352*9999SWang.Lin@Sun.COM kmem_zalloc((sizeof (uint32_t) *
353*9999SWang.Lin@Sun.COM ahp->ah_iniBank3.ia_rows), KM_SLEEP);
354*9999SWang.Lin@Sun.COM ahp->ah_analogBank6Data =
355*9999SWang.Lin@Sun.COM kmem_zalloc((sizeof (uint32_t) *
356*9999SWang.Lin@Sun.COM ahp->ah_iniBank6.ia_rows), KM_SLEEP);
357*9999SWang.Lin@Sun.COM ahp->ah_analogBank6TPCData =
358*9999SWang.Lin@Sun.COM kmem_zalloc((sizeof (uint32_t) *
359*9999SWang.Lin@Sun.COM ahp->ah_iniBank6TPC.ia_rows), KM_SLEEP);
360*9999SWang.Lin@Sun.COM ahp->ah_analogBank7Data =
361*9999SWang.Lin@Sun.COM kmem_zalloc((sizeof (uint32_t) *
362*9999SWang.Lin@Sun.COM ahp->ah_iniBank7.ia_rows), KM_SLEEP);
363*9999SWang.Lin@Sun.COM
364*9999SWang.Lin@Sun.COM if (ahp->ah_analogBank0Data == NULL ||
365*9999SWang.Lin@Sun.COM ahp->ah_analogBank1Data == NULL ||
366*9999SWang.Lin@Sun.COM ahp->ah_analogBank2Data == NULL ||
367*9999SWang.Lin@Sun.COM ahp->ah_analogBank3Data == NULL ||
368*9999SWang.Lin@Sun.COM ahp->ah_analogBank6Data == NULL ||
369*9999SWang.Lin@Sun.COM ahp->ah_analogBank6TPCData == NULL ||
370*9999SWang.Lin@Sun.COM ahp->ah_analogBank7Data == NULL) {
371*9999SWang.Lin@Sun.COM ARN_DBG((ARN_DBG_FATAL, "arn: ath9k_hw_init_rf(): "
372*9999SWang.Lin@Sun.COM "cannot allocate RF banks\n"));
373*9999SWang.Lin@Sun.COM *status = ENOMEM;
374*9999SWang.Lin@Sun.COM return (B_FALSE);
375*9999SWang.Lin@Sun.COM }
376*9999SWang.Lin@Sun.COM
377*9999SWang.Lin@Sun.COM ahp->ah_addac5416_21 =
378*9999SWang.Lin@Sun.COM kmem_zalloc((sizeof (uint32_t) *
379*9999SWang.Lin@Sun.COM ahp->ah_iniAddac.ia_rows *
380*9999SWang.Lin@Sun.COM ahp->ah_iniAddac.ia_columns), KM_SLEEP);
381*9999SWang.Lin@Sun.COM if (ahp->ah_addac5416_21 == NULL) {
382*9999SWang.Lin@Sun.COM ARN_DBG((ARN_DBG_FATAL, "arn: ath9k_hw_init_rf(): "
383*9999SWang.Lin@Sun.COM "cannot allocate ah_addac5416_21\n"));
384*9999SWang.Lin@Sun.COM *status = ENOMEM;
385*9999SWang.Lin@Sun.COM return (B_FALSE);
386*9999SWang.Lin@Sun.COM }
387*9999SWang.Lin@Sun.COM
388*9999SWang.Lin@Sun.COM ahp->ah_bank6Temp =
389*9999SWang.Lin@Sun.COM kmem_zalloc((sizeof (uint32_t) *
390*9999SWang.Lin@Sun.COM ahp->ah_iniBank6.ia_rows), KM_SLEEP);
391*9999SWang.Lin@Sun.COM if (ahp->ah_bank6Temp == NULL) {
392*9999SWang.Lin@Sun.COM ARN_DBG((ARN_DBG_FATAL, "arn: ath9k_hw_init_rf(): "
393*9999SWang.Lin@Sun.COM "cannot allocate ah_bank6Temp\n"));
394*9999SWang.Lin@Sun.COM *status = ENOMEM;
395*9999SWang.Lin@Sun.COM return (B_FALSE);
396*9999SWang.Lin@Sun.COM }
397*9999SWang.Lin@Sun.COM }
398*9999SWang.Lin@Sun.COM
399*9999SWang.Lin@Sun.COM return (B_TRUE);
400*9999SWang.Lin@Sun.COM }
401*9999SWang.Lin@Sun.COM
402*9999SWang.Lin@Sun.COM /* ARGSUSED */
403*9999SWang.Lin@Sun.COM void
ath9k_hw_decrease_chain_power(struct ath_hal * ah,struct ath9k_channel * chan)404*9999SWang.Lin@Sun.COM ath9k_hw_decrease_chain_power(struct ath_hal *ah, struct ath9k_channel *chan)
405*9999SWang.Lin@Sun.COM {
406*9999SWang.Lin@Sun.COM /* LINTED E_FUNC_SET_NOT_USED */
407*9999SWang.Lin@Sun.COM int i, regWrites = 0;
408*9999SWang.Lin@Sun.COM struct ath_hal_5416 *ahp = AH5416(ah);
409*9999SWang.Lin@Sun.COM uint32_t bank6SelMask;
410*9999SWang.Lin@Sun.COM uint32_t *bank6Temp = ahp->ah_bank6Temp;
411*9999SWang.Lin@Sun.COM
412*9999SWang.Lin@Sun.COM switch (ahp->ah_diversityControl) {
413*9999SWang.Lin@Sun.COM case ATH9K_ANT_FIXED_A:
414*9999SWang.Lin@Sun.COM bank6SelMask =
415*9999SWang.Lin@Sun.COM (ahp-> ah_antennaSwitchSwap & ANTSWAP_AB) ? REDUCE_CHAIN_0 :
416*9999SWang.Lin@Sun.COM REDUCE_CHAIN_1;
417*9999SWang.Lin@Sun.COM break;
418*9999SWang.Lin@Sun.COM case ATH9K_ANT_FIXED_B:
419*9999SWang.Lin@Sun.COM bank6SelMask =
420*9999SWang.Lin@Sun.COM (ahp-> ah_antennaSwitchSwap & ANTSWAP_AB) ? REDUCE_CHAIN_1 :
421*9999SWang.Lin@Sun.COM REDUCE_CHAIN_0;
422*9999SWang.Lin@Sun.COM break;
423*9999SWang.Lin@Sun.COM case ATH9K_ANT_VARIABLE:
424*9999SWang.Lin@Sun.COM default:
425*9999SWang.Lin@Sun.COM return;
426*9999SWang.Lin@Sun.COM }
427*9999SWang.Lin@Sun.COM
428*9999SWang.Lin@Sun.COM for (i = 0; i < ahp->ah_iniBank6.ia_rows; i++)
429*9999SWang.Lin@Sun.COM bank6Temp[i] = ahp->ah_analogBank6Data[i];
430*9999SWang.Lin@Sun.COM
431*9999SWang.Lin@Sun.COM REG_WRITE(ah, AR_PHY_BASE + 0xD8, bank6SelMask);
432*9999SWang.Lin@Sun.COM
433*9999SWang.Lin@Sun.COM ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 189, 0);
434*9999SWang.Lin@Sun.COM ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 190, 0);
435*9999SWang.Lin@Sun.COM ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 191, 0);
436*9999SWang.Lin@Sun.COM ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 192, 0);
437*9999SWang.Lin@Sun.COM ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 193, 0);
438*9999SWang.Lin@Sun.COM ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 222, 0);
439*9999SWang.Lin@Sun.COM ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 245, 0);
440*9999SWang.Lin@Sun.COM ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 246, 0);
441*9999SWang.Lin@Sun.COM ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 247, 0);
442*9999SWang.Lin@Sun.COM
443*9999SWang.Lin@Sun.COM REG_WRITE_RF_ARRAY(&ahp->ah_iniBank6, bank6Temp, regWrites);
444*9999SWang.Lin@Sun.COM
445*9999SWang.Lin@Sun.COM REG_WRITE(ah, AR_PHY_BASE + 0xD8, 0x00000053);
446*9999SWang.Lin@Sun.COM #ifdef ALTER_SWITCH
447*9999SWang.Lin@Sun.COM REG_WRITE(ah, PHY_SWITCH_CHAIN_0,
448*9999SWang.Lin@Sun.COM (REG_READ(ah, PHY_SWITCH_CHAIN_0) & ~0x38)
449*9999SWang.Lin@Sun.COM | ((REG_READ(ah, PHY_SWITCH_CHAIN_0) >> 3) & 0x38));
450*9999SWang.Lin@Sun.COM #endif
451*9999SWang.Lin@Sun.COM }
452