diff options
author | John W. Linville <linville@tuxdriver.com> | 2010-04-23 14:43:45 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-04-23 14:43:45 -0400 |
commit | 3b51cc996e81d8a113416d8094fa4a88f8360a51 (patch) | |
tree | e75b98b228bb4e456c30673fcc4b56ffa1d09cf5 /drivers/net/wireless/ath/ath9k/phy.c | |
parent | c68ed255265968c3948fa2678bf59d15c471b055 (diff) | |
parent | 672724403b42da1d276c6cf811e8e34d15efd964 (diff) |
Merge branch 'master' into for-davem
Conflicts:
drivers/net/wireless/ath/ath9k/phy.c
drivers/net/wireless/iwlwifi/iwl-6000.c
drivers/net/wireless/iwlwifi/iwl-debugfs.c
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/phy.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/phy.c | 978 |
1 files changed, 0 insertions, 978 deletions
diff --git a/drivers/net/wireless/ath/ath9k/phy.c b/drivers/net/wireless/ath/ath9k/phy.c deleted file mode 100644 index 2547b3c4a26c..000000000000 --- a/drivers/net/wireless/ath/ath9k/phy.c +++ /dev/null | |||
@@ -1,978 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2009 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | /** | ||
18 | * DOC: Programming Atheros 802.11n analog front end radios | ||
19 | * | ||
20 | * AR5416 MAC based PCI devices and AR518 MAC based PCI-Express | ||
21 | * devices have either an external AR2133 analog front end radio for single | ||
22 | * band 2.4 GHz communication or an AR5133 analog front end radio for dual | ||
23 | * band 2.4 GHz / 5 GHz communication. | ||
24 | * | ||
25 | * All devices after the AR5416 and AR5418 family starting with the AR9280 | ||
26 | * have their analog front radios, MAC/BB and host PCIe/USB interface embedded | ||
27 | * into a single-chip and require less programming. | ||
28 | * | ||
29 | * The following single-chips exist with a respective embedded radio: | ||
30 | * | ||
31 | * AR9280 - 11n dual-band 2x2 MIMO for PCIe | ||
32 | * AR9281 - 11n single-band 1x2 MIMO for PCIe | ||
33 | * AR9285 - 11n single-band 1x1 for PCIe | ||
34 | * AR9287 - 11n single-band 2x2 MIMO for PCIe | ||
35 | * | ||
36 | * AR9220 - 11n dual-band 2x2 MIMO for PCI | ||
37 | * AR9223 - 11n single-band 2x2 MIMO for PCI | ||
38 | * | ||
39 | * AR9287 - 11n single-band 1x1 MIMO for USB | ||
40 | */ | ||
41 | |||
42 | #include <linux/slab.h> | ||
43 | |||
44 | #include "hw.h" | ||
45 | |||
46 | /** | ||
47 | * ath9k_hw_write_regs - ?? | ||
48 | * | ||
49 | * @ah: atheros hardware structure | ||
50 | * @freqIndex: | ||
51 | * @regWrites: | ||
52 | * | ||
53 | * Used for both the chipsets with an external AR2133/AR5133 radios and | ||
54 | * single-chip devices. | ||
55 | */ | ||
56 | void ath9k_hw_write_regs(struct ath_hw *ah, u32 freqIndex, int regWrites) | ||
57 | { | ||
58 | REG_WRITE_ARRAY(&ah->iniBB_RfGain, freqIndex, regWrites); | ||
59 | } | ||
60 | |||
61 | /** | ||
62 | * ath9k_hw_ar9280_set_channel - set channel on single-chip device | ||
63 | * @ah: atheros hardware structure | ||
64 | * @chan: | ||
65 | * | ||
66 | * This is the function to change channel on single-chip devices, that is | ||
67 | * all devices after ar9280. | ||
68 | * | ||
69 | * This function takes the channel value in MHz and sets | ||
70 | * hardware channel value. Assumes writes have been enabled to analog bus. | ||
71 | * | ||
72 | * Actual Expression, | ||
73 | * | ||
74 | * For 2GHz channel, | ||
75 | * Channel Frequency = (3/4) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17) | ||
76 | * (freq_ref = 40MHz) | ||
77 | * | ||
78 | * For 5GHz channel, | ||
79 | * Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^10) | ||
80 | * (freq_ref = 40MHz/(24>>amodeRefSel)) | ||
81 | */ | ||
82 | int ath9k_hw_ar9280_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) | ||
83 | { | ||
84 | u16 bMode, fracMode, aModeRefSel = 0; | ||
85 | u32 freq, ndiv, channelSel = 0, channelFrac = 0, reg32 = 0; | ||
86 | struct chan_centers centers; | ||
87 | u32 refDivA = 24; | ||
88 | |||
89 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); | ||
90 | freq = centers.synth_center; | ||
91 | |||
92 | reg32 = REG_READ(ah, AR_PHY_SYNTH_CONTROL); | ||
93 | reg32 &= 0xc0000000; | ||
94 | |||
95 | if (freq < 4800) { /* 2 GHz, fractional mode */ | ||
96 | u32 txctl; | ||
97 | int regWrites = 0; | ||
98 | |||
99 | bMode = 1; | ||
100 | fracMode = 1; | ||
101 | aModeRefSel = 0; | ||
102 | channelSel = (freq * 0x10000) / 15; | ||
103 | |||
104 | if (AR_SREV_9287_11_OR_LATER(ah)) { | ||
105 | if (freq == 2484) { | ||
106 | /* Enable channel spreading for channel 14 */ | ||
107 | REG_WRITE_ARRAY(&ah->iniCckfirJapan2484, | ||
108 | 1, regWrites); | ||
109 | } else { | ||
110 | REG_WRITE_ARRAY(&ah->iniCckfirNormal, | ||
111 | 1, regWrites); | ||
112 | } | ||
113 | } else { | ||
114 | txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL); | ||
115 | if (freq == 2484) { | ||
116 | /* Enable channel spreading for channel 14 */ | ||
117 | REG_WRITE(ah, AR_PHY_CCK_TX_CTRL, | ||
118 | txctl | AR_PHY_CCK_TX_CTRL_JAPAN); | ||
119 | } else { | ||
120 | REG_WRITE(ah, AR_PHY_CCK_TX_CTRL, | ||
121 | txctl &~ AR_PHY_CCK_TX_CTRL_JAPAN); | ||
122 | } | ||
123 | } | ||
124 | } else { | ||
125 | bMode = 0; | ||
126 | fracMode = 0; | ||
127 | |||
128 | switch(ah->eep_ops->get_eeprom(ah, EEP_FRAC_N_5G)) { | ||
129 | case 0: | ||
130 | if ((freq % 20) == 0) { | ||
131 | aModeRefSel = 3; | ||
132 | } else if ((freq % 10) == 0) { | ||
133 | aModeRefSel = 2; | ||
134 | } | ||
135 | if (aModeRefSel) | ||
136 | break; | ||
137 | case 1: | ||
138 | default: | ||
139 | aModeRefSel = 0; | ||
140 | /* | ||
141 | * Enable 2G (fractional) mode for channels | ||
142 | * which are 5MHz spaced. | ||
143 | */ | ||
144 | fracMode = 1; | ||
145 | refDivA = 1; | ||
146 | channelSel = (freq * 0x8000) / 15; | ||
147 | |||
148 | /* RefDivA setting */ | ||
149 | REG_RMW_FIELD(ah, AR_AN_SYNTH9, | ||
150 | AR_AN_SYNTH9_REFDIVA, refDivA); | ||
151 | |||
152 | } | ||
153 | |||
154 | if (!fracMode) { | ||
155 | ndiv = (freq * (refDivA >> aModeRefSel)) / 60; | ||
156 | channelSel = ndiv & 0x1ff; | ||
157 | channelFrac = (ndiv & 0xfffffe00) * 2; | ||
158 | channelSel = (channelSel << 17) | channelFrac; | ||
159 | } | ||
160 | } | ||
161 | |||
162 | reg32 = reg32 | | ||
163 | (bMode << 29) | | ||
164 | (fracMode << 28) | (aModeRefSel << 26) | (channelSel); | ||
165 | |||
166 | REG_WRITE(ah, AR_PHY_SYNTH_CONTROL, reg32); | ||
167 | |||
168 | ah->curchan = chan; | ||
169 | ah->curchan_rad_index = -1; | ||
170 | |||
171 | return 0; | ||
172 | } | ||
173 | |||
174 | /** | ||
175 | * ath9k_hw_9280_spur_mitigate - convert baseband spur frequency | ||
176 | * @ah: atheros hardware structure | ||
177 | * @chan: | ||
178 | * | ||
179 | * For single-chip solutions. Converts to baseband spur frequency given the | ||
180 | * input channel frequency and compute register settings below. | ||
181 | */ | ||
182 | void ath9k_hw_9280_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan) | ||
183 | { | ||
184 | int bb_spur = AR_NO_SPUR; | ||
185 | int freq; | ||
186 | int bin, cur_bin; | ||
187 | int bb_spur_off, spur_subchannel_sd; | ||
188 | int spur_freq_sd; | ||
189 | int spur_delta_phase; | ||
190 | int denominator; | ||
191 | int upper, lower, cur_vit_mask; | ||
192 | int tmp, newVal; | ||
193 | int i; | ||
194 | int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8, | ||
195 | AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60 | ||
196 | }; | ||
197 | int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10, | ||
198 | AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60 | ||
199 | }; | ||
200 | int inc[4] = { 0, 100, 0, 0 }; | ||
201 | struct chan_centers centers; | ||
202 | |||
203 | int8_t mask_m[123]; | ||
204 | int8_t mask_p[123]; | ||
205 | int8_t mask_amt; | ||
206 | int tmp_mask; | ||
207 | int cur_bb_spur; | ||
208 | bool is2GHz = IS_CHAN_2GHZ(chan); | ||
209 | |||
210 | memset(&mask_m, 0, sizeof(int8_t) * 123); | ||
211 | memset(&mask_p, 0, sizeof(int8_t) * 123); | ||
212 | |||
213 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); | ||
214 | freq = centers.synth_center; | ||
215 | |||
216 | ah->config.spurmode = SPUR_ENABLE_EEPROM; | ||
217 | for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { | ||
218 | cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz); | ||
219 | |||
220 | if (is2GHz) | ||
221 | cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ; | ||
222 | else | ||
223 | cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_5GHZ; | ||
224 | |||
225 | if (AR_NO_SPUR == cur_bb_spur) | ||
226 | break; | ||
227 | cur_bb_spur = cur_bb_spur - freq; | ||
228 | |||
229 | if (IS_CHAN_HT40(chan)) { | ||
230 | if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT40) && | ||
231 | (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT40)) { | ||
232 | bb_spur = cur_bb_spur; | ||
233 | break; | ||
234 | } | ||
235 | } else if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT20) && | ||
236 | (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT20)) { | ||
237 | bb_spur = cur_bb_spur; | ||
238 | break; | ||
239 | } | ||
240 | } | ||
241 | |||
242 | if (AR_NO_SPUR == bb_spur) { | ||
243 | REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK, | ||
244 | AR_PHY_FORCE_CLKEN_CCK_MRC_MUX); | ||
245 | return; | ||
246 | } else { | ||
247 | REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK, | ||
248 | AR_PHY_FORCE_CLKEN_CCK_MRC_MUX); | ||
249 | } | ||
250 | |||
251 | bin = bb_spur * 320; | ||
252 | |||
253 | tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0)); | ||
254 | |||
255 | newVal = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI | | ||
256 | AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER | | ||
257 | AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK | | ||
258 | AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK); | ||
259 | REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), newVal); | ||
260 | |||
261 | newVal = (AR_PHY_SPUR_REG_MASK_RATE_CNTL | | ||
262 | AR_PHY_SPUR_REG_ENABLE_MASK_PPM | | ||
263 | AR_PHY_SPUR_REG_MASK_RATE_SELECT | | ||
264 | AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI | | ||
265 | SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH)); | ||
266 | REG_WRITE(ah, AR_PHY_SPUR_REG, newVal); | ||
267 | |||
268 | if (IS_CHAN_HT40(chan)) { | ||
269 | if (bb_spur < 0) { | ||
270 | spur_subchannel_sd = 1; | ||
271 | bb_spur_off = bb_spur + 10; | ||
272 | } else { | ||
273 | spur_subchannel_sd = 0; | ||
274 | bb_spur_off = bb_spur - 10; | ||
275 | } | ||
276 | } else { | ||
277 | spur_subchannel_sd = 0; | ||
278 | bb_spur_off = bb_spur; | ||
279 | } | ||
280 | |||
281 | if (IS_CHAN_HT40(chan)) | ||
282 | spur_delta_phase = | ||
283 | ((bb_spur * 262144) / | ||
284 | 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE; | ||
285 | else | ||
286 | spur_delta_phase = | ||
287 | ((bb_spur * 524288) / | ||
288 | 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE; | ||
289 | |||
290 | denominator = IS_CHAN_2GHZ(chan) ? 44 : 40; | ||
291 | spur_freq_sd = ((bb_spur_off * 2048) / denominator) & 0x3ff; | ||
292 | |||
293 | newVal = (AR_PHY_TIMING11_USE_SPUR_IN_AGC | | ||
294 | SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) | | ||
295 | SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE)); | ||
296 | REG_WRITE(ah, AR_PHY_TIMING11, newVal); | ||
297 | |||
298 | newVal = spur_subchannel_sd << AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S; | ||
299 | REG_WRITE(ah, AR_PHY_SFCORR_EXT, newVal); | ||
300 | |||
301 | cur_bin = -6000; | ||
302 | upper = bin + 100; | ||
303 | lower = bin - 100; | ||
304 | |||
305 | for (i = 0; i < 4; i++) { | ||
306 | int pilot_mask = 0; | ||
307 | int chan_mask = 0; | ||
308 | int bp = 0; | ||
309 | for (bp = 0; bp < 30; bp++) { | ||
310 | if ((cur_bin > lower) && (cur_bin < upper)) { | ||
311 | pilot_mask = pilot_mask | 0x1 << bp; | ||
312 | chan_mask = chan_mask | 0x1 << bp; | ||
313 | } | ||
314 | cur_bin += 100; | ||
315 | } | ||
316 | cur_bin += inc[i]; | ||
317 | REG_WRITE(ah, pilot_mask_reg[i], pilot_mask); | ||
318 | REG_WRITE(ah, chan_mask_reg[i], chan_mask); | ||
319 | } | ||
320 | |||
321 | cur_vit_mask = 6100; | ||
322 | upper = bin + 120; | ||
323 | lower = bin - 120; | ||
324 | |||
325 | for (i = 0; i < 123; i++) { | ||
326 | if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) { | ||
327 | |||
328 | /* workaround for gcc bug #37014 */ | ||
329 | volatile int tmp_v = abs(cur_vit_mask - bin); | ||
330 | |||
331 | if (tmp_v < 75) | ||
332 | mask_amt = 1; | ||
333 | else | ||
334 | mask_amt = 0; | ||
335 | if (cur_vit_mask < 0) | ||
336 | mask_m[abs(cur_vit_mask / 100)] = mask_amt; | ||
337 | else | ||
338 | mask_p[cur_vit_mask / 100] = mask_amt; | ||
339 | } | ||
340 | cur_vit_mask -= 100; | ||
341 | } | ||
342 | |||
343 | tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28) | ||
344 | | (mask_m[48] << 26) | (mask_m[49] << 24) | ||
345 | | (mask_m[50] << 22) | (mask_m[51] << 20) | ||
346 | | (mask_m[52] << 18) | (mask_m[53] << 16) | ||
347 | | (mask_m[54] << 14) | (mask_m[55] << 12) | ||
348 | | (mask_m[56] << 10) | (mask_m[57] << 8) | ||
349 | | (mask_m[58] << 6) | (mask_m[59] << 4) | ||
350 | | (mask_m[60] << 2) | (mask_m[61] << 0); | ||
351 | REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask); | ||
352 | REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask); | ||
353 | |||
354 | tmp_mask = (mask_m[31] << 28) | ||
355 | | (mask_m[32] << 26) | (mask_m[33] << 24) | ||
356 | | (mask_m[34] << 22) | (mask_m[35] << 20) | ||
357 | | (mask_m[36] << 18) | (mask_m[37] << 16) | ||
358 | | (mask_m[48] << 14) | (mask_m[39] << 12) | ||
359 | | (mask_m[40] << 10) | (mask_m[41] << 8) | ||
360 | | (mask_m[42] << 6) | (mask_m[43] << 4) | ||
361 | | (mask_m[44] << 2) | (mask_m[45] << 0); | ||
362 | REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask); | ||
363 | REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask); | ||
364 | |||
365 | tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28) | ||
366 | | (mask_m[18] << 26) | (mask_m[18] << 24) | ||
367 | | (mask_m[20] << 22) | (mask_m[20] << 20) | ||
368 | | (mask_m[22] << 18) | (mask_m[22] << 16) | ||
369 | | (mask_m[24] << 14) | (mask_m[24] << 12) | ||
370 | | (mask_m[25] << 10) | (mask_m[26] << 8) | ||
371 | | (mask_m[27] << 6) | (mask_m[28] << 4) | ||
372 | | (mask_m[29] << 2) | (mask_m[30] << 0); | ||
373 | REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask); | ||
374 | REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask); | ||
375 | |||
376 | tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28) | ||
377 | | (mask_m[2] << 26) | (mask_m[3] << 24) | ||
378 | | (mask_m[4] << 22) | (mask_m[5] << 20) | ||
379 | | (mask_m[6] << 18) | (mask_m[7] << 16) | ||
380 | | (mask_m[8] << 14) | (mask_m[9] << 12) | ||
381 | | (mask_m[10] << 10) | (mask_m[11] << 8) | ||
382 | | (mask_m[12] << 6) | (mask_m[13] << 4) | ||
383 | | (mask_m[14] << 2) | (mask_m[15] << 0); | ||
384 | REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask); | ||
385 | REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask); | ||
386 | |||
387 | tmp_mask = (mask_p[15] << 28) | ||
388 | | (mask_p[14] << 26) | (mask_p[13] << 24) | ||
389 | | (mask_p[12] << 22) | (mask_p[11] << 20) | ||
390 | | (mask_p[10] << 18) | (mask_p[9] << 16) | ||
391 | | (mask_p[8] << 14) | (mask_p[7] << 12) | ||
392 | | (mask_p[6] << 10) | (mask_p[5] << 8) | ||
393 | | (mask_p[4] << 6) | (mask_p[3] << 4) | ||
394 | | (mask_p[2] << 2) | (mask_p[1] << 0); | ||
395 | REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask); | ||
396 | REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask); | ||
397 | |||
398 | tmp_mask = (mask_p[30] << 28) | ||
399 | | (mask_p[29] << 26) | (mask_p[28] << 24) | ||
400 | | (mask_p[27] << 22) | (mask_p[26] << 20) | ||
401 | | (mask_p[25] << 18) | (mask_p[24] << 16) | ||
402 | | (mask_p[23] << 14) | (mask_p[22] << 12) | ||
403 | | (mask_p[21] << 10) | (mask_p[20] << 8) | ||
404 | | (mask_p[19] << 6) | (mask_p[18] << 4) | ||
405 | | (mask_p[17] << 2) | (mask_p[16] << 0); | ||
406 | REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask); | ||
407 | REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask); | ||
408 | |||
409 | tmp_mask = (mask_p[45] << 28) | ||
410 | | (mask_p[44] << 26) | (mask_p[43] << 24) | ||
411 | | (mask_p[42] << 22) | (mask_p[41] << 20) | ||
412 | | (mask_p[40] << 18) | (mask_p[39] << 16) | ||
413 | | (mask_p[38] << 14) | (mask_p[37] << 12) | ||
414 | | (mask_p[36] << 10) | (mask_p[35] << 8) | ||
415 | | (mask_p[34] << 6) | (mask_p[33] << 4) | ||
416 | | (mask_p[32] << 2) | (mask_p[31] << 0); | ||
417 | REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask); | ||
418 | REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask); | ||
419 | |||
420 | tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28) | ||
421 | | (mask_p[59] << 26) | (mask_p[58] << 24) | ||
422 | | (mask_p[57] << 22) | (mask_p[56] << 20) | ||
423 | | (mask_p[55] << 18) | (mask_p[54] << 16) | ||
424 | | (mask_p[53] << 14) | (mask_p[52] << 12) | ||
425 | | (mask_p[51] << 10) | (mask_p[50] << 8) | ||
426 | | (mask_p[49] << 6) | (mask_p[48] << 4) | ||
427 | | (mask_p[47] << 2) | (mask_p[46] << 0); | ||
428 | REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask); | ||
429 | REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask); | ||
430 | } | ||
431 | |||
432 | /* All code below is for non single-chip solutions */ | ||
433 | |||
434 | /** | ||
435 | * ath9k_phy_modify_rx_buffer() - perform analog swizzling of parameters | ||
436 | * @rfbuf: | ||
437 | * @reg32: | ||
438 | * @numBits: | ||
439 | * @firstBit: | ||
440 | * @column: | ||
441 | * | ||
442 | * Performs analog "swizzling" of parameters into their location. | ||
443 | * Used on external AR2133/AR5133 radios. | ||
444 | */ | ||
445 | static void ath9k_phy_modify_rx_buffer(u32 *rfBuf, u32 reg32, | ||
446 | u32 numBits, u32 firstBit, | ||
447 | u32 column) | ||
448 | { | ||
449 | u32 tmp32, mask, arrayEntry, lastBit; | ||
450 | int32_t bitPosition, bitsLeft; | ||
451 | |||
452 | tmp32 = ath9k_hw_reverse_bits(reg32, numBits); | ||
453 | arrayEntry = (firstBit - 1) / 8; | ||
454 | bitPosition = (firstBit - 1) % 8; | ||
455 | bitsLeft = numBits; | ||
456 | while (bitsLeft > 0) { | ||
457 | lastBit = (bitPosition + bitsLeft > 8) ? | ||
458 | 8 : bitPosition + bitsLeft; | ||
459 | mask = (((1 << lastBit) - 1) ^ ((1 << bitPosition) - 1)) << | ||
460 | (column * 8); | ||
461 | rfBuf[arrayEntry] &= ~mask; | ||
462 | rfBuf[arrayEntry] |= ((tmp32 << bitPosition) << | ||
463 | (column * 8)) & mask; | ||
464 | bitsLeft -= 8 - bitPosition; | ||
465 | tmp32 = tmp32 >> (8 - bitPosition); | ||
466 | bitPosition = 0; | ||
467 | arrayEntry++; | ||
468 | } | ||
469 | } | ||
470 | |||
471 | /* | ||
472 | * Fix on 2.4 GHz band for orientation sensitivity issue by increasing | ||
473 | * rf_pwd_icsyndiv. | ||
474 | * | ||
475 | * Theoretical Rules: | ||
476 | * if 2 GHz band | ||
477 | * if forceBiasAuto | ||
478 | * if synth_freq < 2412 | ||
479 | * bias = 0 | ||
480 | * else if 2412 <= synth_freq <= 2422 | ||
481 | * bias = 1 | ||
482 | * else // synth_freq > 2422 | ||
483 | * bias = 2 | ||
484 | * else if forceBias > 0 | ||
485 | * bias = forceBias & 7 | ||
486 | * else | ||
487 | * no change, use value from ini file | ||
488 | * else | ||
489 | * no change, invalid band | ||
490 | * | ||
491 | * 1st Mod: | ||
492 | * 2422 also uses value of 2 | ||
493 | * <approved> | ||
494 | * | ||
495 | * 2nd Mod: | ||
496 | * Less than 2412 uses value of 0, 2412 and above uses value of 2 | ||
497 | */ | ||
498 | static void ath9k_hw_force_bias(struct ath_hw *ah, u16 synth_freq) | ||
499 | { | ||
500 | struct ath_common *common = ath9k_hw_common(ah); | ||
501 | u32 tmp_reg; | ||
502 | int reg_writes = 0; | ||
503 | u32 new_bias = 0; | ||
504 | |||
505 | if (!AR_SREV_5416(ah) || synth_freq >= 3000) { | ||
506 | return; | ||
507 | } | ||
508 | |||
509 | BUG_ON(AR_SREV_9280_10_OR_LATER(ah)); | ||
510 | |||
511 | if (synth_freq < 2412) | ||
512 | new_bias = 0; | ||
513 | else if (synth_freq < 2422) | ||
514 | new_bias = 1; | ||
515 | else | ||
516 | new_bias = 2; | ||
517 | |||
518 | /* pre-reverse this field */ | ||
519 | tmp_reg = ath9k_hw_reverse_bits(new_bias, 3); | ||
520 | |||
521 | ath_print(common, ATH_DBG_CONFIG, | ||
522 | "Force rf_pwd_icsyndiv to %1d on %4d\n", | ||
523 | new_bias, synth_freq); | ||
524 | |||
525 | /* swizzle rf_pwd_icsyndiv */ | ||
526 | ath9k_phy_modify_rx_buffer(ah->analogBank6Data, tmp_reg, 3, 181, 3); | ||
527 | |||
528 | /* write Bank 6 with new params */ | ||
529 | REG_WRITE_RF_ARRAY(&ah->iniBank6, ah->analogBank6Data, reg_writes); | ||
530 | } | ||
531 | |||
532 | /** | ||
533 | * ath9k_hw_set_channel - tune to a channel on the external AR2133/AR5133 radios | ||
534 | * @ah: atheros hardware stucture | ||
535 | * @chan: | ||
536 | * | ||
537 | * For the external AR2133/AR5133 radios, takes the MHz channel value and set | ||
538 | * the channel value. Assumes writes enabled to analog bus and bank6 register | ||
539 | * cache in ah->analogBank6Data. | ||
540 | */ | ||
541 | int ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) | ||
542 | { | ||
543 | struct ath_common *common = ath9k_hw_common(ah); | ||
544 | u32 channelSel = 0; | ||
545 | u32 bModeSynth = 0; | ||
546 | u32 aModeRefSel = 0; | ||
547 | u32 reg32 = 0; | ||
548 | u16 freq; | ||
549 | struct chan_centers centers; | ||
550 | |||
551 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); | ||
552 | freq = centers.synth_center; | ||
553 | |||
554 | if (freq < 4800) { | ||
555 | u32 txctl; | ||
556 | |||
557 | if (((freq - 2192) % 5) == 0) { | ||
558 | channelSel = ((freq - 672) * 2 - 3040) / 10; | ||
559 | bModeSynth = 0; | ||
560 | } else if (((freq - 2224) % 5) == 0) { | ||
561 | channelSel = ((freq - 704) * 2 - 3040) / 10; | ||
562 | bModeSynth = 1; | ||
563 | } else { | ||
564 | ath_print(common, ATH_DBG_FATAL, | ||
565 | "Invalid channel %u MHz\n", freq); | ||
566 | return -EINVAL; | ||
567 | } | ||
568 | |||
569 | channelSel = (channelSel << 2) & 0xff; | ||
570 | channelSel = ath9k_hw_reverse_bits(channelSel, 8); | ||
571 | |||
572 | txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL); | ||
573 | if (freq == 2484) { | ||
574 | |||
575 | REG_WRITE(ah, AR_PHY_CCK_TX_CTRL, | ||
576 | txctl | AR_PHY_CCK_TX_CTRL_JAPAN); | ||
577 | } else { | ||
578 | REG_WRITE(ah, AR_PHY_CCK_TX_CTRL, | ||
579 | txctl & ~AR_PHY_CCK_TX_CTRL_JAPAN); | ||
580 | } | ||
581 | |||
582 | } else if ((freq % 20) == 0 && freq >= 5120) { | ||
583 | channelSel = | ||
584 | ath9k_hw_reverse_bits(((freq - 4800) / 20 << 2), 8); | ||
585 | aModeRefSel = ath9k_hw_reverse_bits(1, 2); | ||
586 | } else if ((freq % 10) == 0) { | ||
587 | channelSel = | ||
588 | ath9k_hw_reverse_bits(((freq - 4800) / 10 << 1), 8); | ||
589 | if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) | ||
590 | aModeRefSel = ath9k_hw_reverse_bits(2, 2); | ||
591 | else | ||
592 | aModeRefSel = ath9k_hw_reverse_bits(1, 2); | ||
593 | } else if ((freq % 5) == 0) { | ||
594 | channelSel = ath9k_hw_reverse_bits((freq - 4800) / 5, 8); | ||
595 | aModeRefSel = ath9k_hw_reverse_bits(1, 2); | ||
596 | } else { | ||
597 | ath_print(common, ATH_DBG_FATAL, | ||
598 | "Invalid channel %u MHz\n", freq); | ||
599 | return -EINVAL; | ||
600 | } | ||
601 | |||
602 | ath9k_hw_force_bias(ah, freq); | ||
603 | |||
604 | reg32 = | ||
605 | (channelSel << 8) | (aModeRefSel << 2) | (bModeSynth << 1) | | ||
606 | (1 << 5) | 0x1; | ||
607 | |||
608 | REG_WRITE(ah, AR_PHY(0x37), reg32); | ||
609 | |||
610 | ah->curchan = chan; | ||
611 | ah->curchan_rad_index = -1; | ||
612 | |||
613 | return 0; | ||
614 | } | ||
615 | |||
616 | /** | ||
617 | * ath9k_hw_spur_mitigate - convert baseband spur frequency for external radios | ||
618 | * @ah: atheros hardware structure | ||
619 | * @chan: | ||
620 | * | ||
621 | * For non single-chip solutions. Converts to baseband spur frequency given the | ||
622 | * input channel frequency and compute register settings below. | ||
623 | */ | ||
624 | void ath9k_hw_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan) | ||
625 | { | ||
626 | int bb_spur = AR_NO_SPUR; | ||
627 | int bin, cur_bin; | ||
628 | int spur_freq_sd; | ||
629 | int spur_delta_phase; | ||
630 | int denominator; | ||
631 | int upper, lower, cur_vit_mask; | ||
632 | int tmp, new; | ||
633 | int i; | ||
634 | int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8, | ||
635 | AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60 | ||
636 | }; | ||
637 | int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10, | ||
638 | AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60 | ||
639 | }; | ||
640 | int inc[4] = { 0, 100, 0, 0 }; | ||
641 | |||
642 | int8_t mask_m[123]; | ||
643 | int8_t mask_p[123]; | ||
644 | int8_t mask_amt; | ||
645 | int tmp_mask; | ||
646 | int cur_bb_spur; | ||
647 | bool is2GHz = IS_CHAN_2GHZ(chan); | ||
648 | |||
649 | memset(&mask_m, 0, sizeof(int8_t) * 123); | ||
650 | memset(&mask_p, 0, sizeof(int8_t) * 123); | ||
651 | |||
652 | for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { | ||
653 | cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz); | ||
654 | if (AR_NO_SPUR == cur_bb_spur) | ||
655 | break; | ||
656 | cur_bb_spur = cur_bb_spur - (chan->channel * 10); | ||
657 | if ((cur_bb_spur > -95) && (cur_bb_spur < 95)) { | ||
658 | bb_spur = cur_bb_spur; | ||
659 | break; | ||
660 | } | ||
661 | } | ||
662 | |||
663 | if (AR_NO_SPUR == bb_spur) | ||
664 | return; | ||
665 | |||
666 | bin = bb_spur * 32; | ||
667 | |||
668 | tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0)); | ||
669 | new = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI | | ||
670 | AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER | | ||
671 | AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK | | ||
672 | AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK); | ||
673 | |||
674 | REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), new); | ||
675 | |||
676 | new = (AR_PHY_SPUR_REG_MASK_RATE_CNTL | | ||
677 | AR_PHY_SPUR_REG_ENABLE_MASK_PPM | | ||
678 | AR_PHY_SPUR_REG_MASK_RATE_SELECT | | ||
679 | AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI | | ||
680 | SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH)); | ||
681 | REG_WRITE(ah, AR_PHY_SPUR_REG, new); | ||
682 | |||
683 | spur_delta_phase = ((bb_spur * 524288) / 100) & | ||
684 | AR_PHY_TIMING11_SPUR_DELTA_PHASE; | ||
685 | |||
686 | denominator = IS_CHAN_2GHZ(chan) ? 440 : 400; | ||
687 | spur_freq_sd = ((bb_spur * 2048) / denominator) & 0x3ff; | ||
688 | |||
689 | new = (AR_PHY_TIMING11_USE_SPUR_IN_AGC | | ||
690 | SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) | | ||
691 | SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE)); | ||
692 | REG_WRITE(ah, AR_PHY_TIMING11, new); | ||
693 | |||
694 | cur_bin = -6000; | ||
695 | upper = bin + 100; | ||
696 | lower = bin - 100; | ||
697 | |||
698 | for (i = 0; i < 4; i++) { | ||
699 | int pilot_mask = 0; | ||
700 | int chan_mask = 0; | ||
701 | int bp = 0; | ||
702 | for (bp = 0; bp < 30; bp++) { | ||
703 | if ((cur_bin > lower) && (cur_bin < upper)) { | ||
704 | pilot_mask = pilot_mask | 0x1 << bp; | ||
705 | chan_mask = chan_mask | 0x1 << bp; | ||
706 | } | ||
707 | cur_bin += 100; | ||
708 | } | ||
709 | cur_bin += inc[i]; | ||
710 | REG_WRITE(ah, pilot_mask_reg[i], pilot_mask); | ||
711 | REG_WRITE(ah, chan_mask_reg[i], chan_mask); | ||
712 | } | ||
713 | |||
714 | cur_vit_mask = 6100; | ||
715 | upper = bin + 120; | ||
716 | lower = bin - 120; | ||
717 | |||
718 | for (i = 0; i < 123; i++) { | ||
719 | if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) { | ||
720 | |||
721 | /* workaround for gcc bug #37014 */ | ||
722 | volatile int tmp_v = abs(cur_vit_mask - bin); | ||
723 | |||
724 | if (tmp_v < 75) | ||
725 | mask_amt = 1; | ||
726 | else | ||
727 | mask_amt = 0; | ||
728 | if (cur_vit_mask < 0) | ||
729 | mask_m[abs(cur_vit_mask / 100)] = mask_amt; | ||
730 | else | ||
731 | mask_p[cur_vit_mask / 100] = mask_amt; | ||
732 | } | ||
733 | cur_vit_mask -= 100; | ||
734 | } | ||
735 | |||
736 | tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28) | ||
737 | | (mask_m[48] << 26) | (mask_m[49] << 24) | ||
738 | | (mask_m[50] << 22) | (mask_m[51] << 20) | ||
739 | | (mask_m[52] << 18) | (mask_m[53] << 16) | ||
740 | | (mask_m[54] << 14) | (mask_m[55] << 12) | ||
741 | | (mask_m[56] << 10) | (mask_m[57] << 8) | ||
742 | | (mask_m[58] << 6) | (mask_m[59] << 4) | ||
743 | | (mask_m[60] << 2) | (mask_m[61] << 0); | ||
744 | REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask); | ||
745 | REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask); | ||
746 | |||
747 | tmp_mask = (mask_m[31] << 28) | ||
748 | | (mask_m[32] << 26) | (mask_m[33] << 24) | ||
749 | | (mask_m[34] << 22) | (mask_m[35] << 20) | ||
750 | | (mask_m[36] << 18) | (mask_m[37] << 16) | ||
751 | | (mask_m[48] << 14) | (mask_m[39] << 12) | ||
752 | | (mask_m[40] << 10) | (mask_m[41] << 8) | ||
753 | | (mask_m[42] << 6) | (mask_m[43] << 4) | ||
754 | | (mask_m[44] << 2) | (mask_m[45] << 0); | ||
755 | REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask); | ||
756 | REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask); | ||
757 | |||
758 | tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28) | ||
759 | | (mask_m[18] << 26) | (mask_m[18] << 24) | ||
760 | | (mask_m[20] << 22) | (mask_m[20] << 20) | ||
761 | | (mask_m[22] << 18) | (mask_m[22] << 16) | ||
762 | | (mask_m[24] << 14) | (mask_m[24] << 12) | ||
763 | | (mask_m[25] << 10) | (mask_m[26] << 8) | ||
764 | | (mask_m[27] << 6) | (mask_m[28] << 4) | ||
765 | | (mask_m[29] << 2) | (mask_m[30] << 0); | ||
766 | REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask); | ||
767 | REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask); | ||
768 | |||
769 | tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28) | ||
770 | | (mask_m[2] << 26) | (mask_m[3] << 24) | ||
771 | | (mask_m[4] << 22) | (mask_m[5] << 20) | ||
772 | | (mask_m[6] << 18) | (mask_m[7] << 16) | ||
773 | | (mask_m[8] << 14) | (mask_m[9] << 12) | ||
774 | | (mask_m[10] << 10) | (mask_m[11] << 8) | ||
775 | | (mask_m[12] << 6) | (mask_m[13] << 4) | ||
776 | | (mask_m[14] << 2) | (mask_m[15] << 0); | ||
777 | REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask); | ||
778 | REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask); | ||
779 | |||
780 | tmp_mask = (mask_p[15] << 28) | ||
781 | | (mask_p[14] << 26) | (mask_p[13] << 24) | ||
782 | | (mask_p[12] << 22) | (mask_p[11] << 20) | ||
783 | | (mask_p[10] << 18) | (mask_p[9] << 16) | ||
784 | | (mask_p[8] << 14) | (mask_p[7] << 12) | ||
785 | | (mask_p[6] << 10) | (mask_p[5] << 8) | ||
786 | | (mask_p[4] << 6) | (mask_p[3] << 4) | ||
787 | | (mask_p[2] << 2) | (mask_p[1] << 0); | ||
788 | REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask); | ||
789 | REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask); | ||
790 | |||
791 | tmp_mask = (mask_p[30] << 28) | ||
792 | | (mask_p[29] << 26) | (mask_p[28] << 24) | ||
793 | | (mask_p[27] << 22) | (mask_p[26] << 20) | ||
794 | | (mask_p[25] << 18) | (mask_p[24] << 16) | ||
795 | | (mask_p[23] << 14) | (mask_p[22] << 12) | ||
796 | | (mask_p[21] << 10) | (mask_p[20] << 8) | ||
797 | | (mask_p[19] << 6) | (mask_p[18] << 4) | ||
798 | | (mask_p[17] << 2) | (mask_p[16] << 0); | ||
799 | REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask); | ||
800 | REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask); | ||
801 | |||
802 | tmp_mask = (mask_p[45] << 28) | ||
803 | | (mask_p[44] << 26) | (mask_p[43] << 24) | ||
804 | | (mask_p[42] << 22) | (mask_p[41] << 20) | ||
805 | | (mask_p[40] << 18) | (mask_p[39] << 16) | ||
806 | | (mask_p[38] << 14) | (mask_p[37] << 12) | ||
807 | | (mask_p[36] << 10) | (mask_p[35] << 8) | ||
808 | | (mask_p[34] << 6) | (mask_p[33] << 4) | ||
809 | | (mask_p[32] << 2) | (mask_p[31] << 0); | ||
810 | REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask); | ||
811 | REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask); | ||
812 | |||
813 | tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28) | ||
814 | | (mask_p[59] << 26) | (mask_p[58] << 24) | ||
815 | | (mask_p[57] << 22) | (mask_p[56] << 20) | ||
816 | | (mask_p[55] << 18) | (mask_p[54] << 16) | ||
817 | | (mask_p[53] << 14) | (mask_p[52] << 12) | ||
818 | | (mask_p[51] << 10) | (mask_p[50] << 8) | ||
819 | | (mask_p[49] << 6) | (mask_p[48] << 4) | ||
820 | | (mask_p[47] << 2) | (mask_p[46] << 0); | ||
821 | REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask); | ||
822 | REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask); | ||
823 | } | ||
824 | |||
825 | /** | ||
826 | * ath9k_hw_rf_alloc_ext_banks - allocates banks for external radio programming | ||
827 | * @ah: atheros hardware structure | ||
828 | * | ||
829 | * Only required for older devices with external AR2133/AR5133 radios. | ||
830 | */ | ||
831 | int ath9k_hw_rf_alloc_ext_banks(struct ath_hw *ah) | ||
832 | { | ||
833 | #define ATH_ALLOC_BANK(bank, size) do { \ | ||
834 | bank = kzalloc((sizeof(u32) * size), GFP_KERNEL); \ | ||
835 | if (!bank) { \ | ||
836 | ath_print(common, ATH_DBG_FATAL, \ | ||
837 | "Cannot allocate RF banks\n"); \ | ||
838 | return -ENOMEM; \ | ||
839 | } \ | ||
840 | } while (0); | ||
841 | |||
842 | struct ath_common *common = ath9k_hw_common(ah); | ||
843 | |||
844 | BUG_ON(AR_SREV_9280_10_OR_LATER(ah)); | ||
845 | |||
846 | ATH_ALLOC_BANK(ah->analogBank0Data, ah->iniBank0.ia_rows); | ||
847 | ATH_ALLOC_BANK(ah->analogBank1Data, ah->iniBank1.ia_rows); | ||
848 | ATH_ALLOC_BANK(ah->analogBank2Data, ah->iniBank2.ia_rows); | ||
849 | ATH_ALLOC_BANK(ah->analogBank3Data, ah->iniBank3.ia_rows); | ||
850 | ATH_ALLOC_BANK(ah->analogBank6Data, ah->iniBank6.ia_rows); | ||
851 | ATH_ALLOC_BANK(ah->analogBank6TPCData, ah->iniBank6TPC.ia_rows); | ||
852 | ATH_ALLOC_BANK(ah->analogBank7Data, ah->iniBank7.ia_rows); | ||
853 | ATH_ALLOC_BANK(ah->addac5416_21, | ||
854 | ah->iniAddac.ia_rows * ah->iniAddac.ia_columns); | ||
855 | ATH_ALLOC_BANK(ah->bank6Temp, ah->iniBank6.ia_rows); | ||
856 | |||
857 | return 0; | ||
858 | #undef ATH_ALLOC_BANK | ||
859 | } | ||
860 | |||
861 | |||
862 | /** | ||
863 | * ath9k_hw_rf_free_ext_banks - Free memory for analog bank scratch buffers | ||
864 | * @ah: atheros hardware struture | ||
865 | * For the external AR2133/AR5133 radios banks. | ||
866 | */ | ||
867 | void | ||
868 | ath9k_hw_rf_free_ext_banks(struct ath_hw *ah) | ||
869 | { | ||
870 | #define ATH_FREE_BANK(bank) do { \ | ||
871 | kfree(bank); \ | ||
872 | bank = NULL; \ | ||
873 | } while (0); | ||
874 | |||
875 | BUG_ON(AR_SREV_9280_10_OR_LATER(ah)); | ||
876 | |||
877 | ATH_FREE_BANK(ah->analogBank0Data); | ||
878 | ATH_FREE_BANK(ah->analogBank1Data); | ||
879 | ATH_FREE_BANK(ah->analogBank2Data); | ||
880 | ATH_FREE_BANK(ah->analogBank3Data); | ||
881 | ATH_FREE_BANK(ah->analogBank6Data); | ||
882 | ATH_FREE_BANK(ah->analogBank6TPCData); | ||
883 | ATH_FREE_BANK(ah->analogBank7Data); | ||
884 | ATH_FREE_BANK(ah->addac5416_21); | ||
885 | ATH_FREE_BANK(ah->bank6Temp); | ||
886 | |||
887 | #undef ATH_FREE_BANK | ||
888 | } | ||
889 | |||
890 | /* * | ||
891 | * ath9k_hw_set_rf_regs - programs rf registers based on EEPROM | ||
892 | * @ah: atheros hardware structure | ||
893 | * @chan: | ||
894 | * @modesIndex: | ||
895 | * | ||
896 | * Used for the external AR2133/AR5133 radios. | ||
897 | * | ||
898 | * Reads the EEPROM header info from the device structure and programs | ||
899 | * all rf registers. This routine requires access to the analog | ||
900 | * rf device. This is not required for single-chip devices. | ||
901 | */ | ||
902 | bool ath9k_hw_set_rf_regs(struct ath_hw *ah, struct ath9k_channel *chan, | ||
903 | u16 modesIndex) | ||
904 | { | ||
905 | u32 eepMinorRev; | ||
906 | u32 ob5GHz = 0, db5GHz = 0; | ||
907 | u32 ob2GHz = 0, db2GHz = 0; | ||
908 | int regWrites = 0; | ||
909 | |||
910 | /* | ||
911 | * Software does not need to program bank data | ||
912 | * for single chip devices, that is AR9280 or anything | ||
913 | * after that. | ||
914 | */ | ||
915 | if (AR_SREV_9280_10_OR_LATER(ah)) | ||
916 | return true; | ||
917 | |||
918 | /* Setup rf parameters */ | ||
919 | eepMinorRev = ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV); | ||
920 | |||
921 | /* Setup Bank 0 Write */ | ||
922 | RF_BANK_SETUP(ah->analogBank0Data, &ah->iniBank0, 1); | ||
923 | |||
924 | /* Setup Bank 1 Write */ | ||
925 | RF_BANK_SETUP(ah->analogBank1Data, &ah->iniBank1, 1); | ||
926 | |||
927 | /* Setup Bank 2 Write */ | ||
928 | RF_BANK_SETUP(ah->analogBank2Data, &ah->iniBank2, 1); | ||
929 | |||
930 | /* Setup Bank 6 Write */ | ||
931 | RF_BANK_SETUP(ah->analogBank3Data, &ah->iniBank3, | ||
932 | modesIndex); | ||
933 | { | ||
934 | int i; | ||
935 | for (i = 0; i < ah->iniBank6TPC.ia_rows; i++) { | ||
936 | ah->analogBank6Data[i] = | ||
937 | INI_RA(&ah->iniBank6TPC, i, modesIndex); | ||
938 | } | ||
939 | } | ||
940 | |||
941 | /* Only the 5 or 2 GHz OB/DB need to be set for a mode */ | ||
942 | if (eepMinorRev >= 2) { | ||
943 | if (IS_CHAN_2GHZ(chan)) { | ||
944 | ob2GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_2); | ||
945 | db2GHz = ah->eep_ops->get_eeprom(ah, EEP_DB_2); | ||
946 | ath9k_phy_modify_rx_buffer(ah->analogBank6Data, | ||
947 | ob2GHz, 3, 197, 0); | ||
948 | ath9k_phy_modify_rx_buffer(ah->analogBank6Data, | ||
949 | db2GHz, 3, 194, 0); | ||
950 | } else { | ||
951 | ob5GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_5); | ||
952 | db5GHz = ah->eep_ops->get_eeprom(ah, EEP_DB_5); | ||
953 | ath9k_phy_modify_rx_buffer(ah->analogBank6Data, | ||
954 | ob5GHz, 3, 203, 0); | ||
955 | ath9k_phy_modify_rx_buffer(ah->analogBank6Data, | ||
956 | db5GHz, 3, 200, 0); | ||
957 | } | ||
958 | } | ||
959 | |||
960 | /* Setup Bank 7 Setup */ | ||
961 | RF_BANK_SETUP(ah->analogBank7Data, &ah->iniBank7, 1); | ||
962 | |||
963 | /* Write Analog registers */ | ||
964 | REG_WRITE_RF_ARRAY(&ah->iniBank0, ah->analogBank0Data, | ||
965 | regWrites); | ||
966 | REG_WRITE_RF_ARRAY(&ah->iniBank1, ah->analogBank1Data, | ||
967 | regWrites); | ||
968 | REG_WRITE_RF_ARRAY(&ah->iniBank2, ah->analogBank2Data, | ||
969 | regWrites); | ||
970 | REG_WRITE_RF_ARRAY(&ah->iniBank3, ah->analogBank3Data, | ||
971 | regWrites); | ||
972 | REG_WRITE_RF_ARRAY(&ah->iniBank6TPC, ah->analogBank6Data, | ||
973 | regWrites); | ||
974 | REG_WRITE_RF_ARRAY(&ah->iniBank7, ah->analogBank7Data, | ||
975 | regWrites); | ||
976 | |||
977 | return true; | ||
978 | } | ||