Line data Source code
1 : /* $OpenBSD: ar5xxx.c,v 1.63 2018/01/31 11:27:03 stsp Exp $ */
2 :
3 : /*
4 : * Copyright (c) 2004, 2005, 2006, 2007 Reyk Floeter <reyk@openbsd.org>
5 : *
6 : * Permission to use, copy, modify, and distribute this software for any
7 : * purpose with or without fee is hereby granted, provided that the above
8 : * copyright notice and this permission notice appear in all copies.
9 : *
10 : * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 : * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 : * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 : * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 : * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 : * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 : * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 : */
18 :
19 : /*
20 : * HAL interface for Atheros Wireless LAN devices.
21 : * (Please have a look at ar5xxx.h for further information)
22 : */
23 :
24 : #include <dev/pci/pcidevs.h>
25 : #include <dev/ic/ar5xxx.h>
26 :
27 : extern ar5k_attach_t ar5k_ar5210_attach;
28 : extern ar5k_attach_t ar5k_ar5211_attach;
29 : extern ar5k_attach_t ar5k_ar5212_attach;
30 :
31 : static const struct {
32 : u_int16_t vendor;
33 : u_int16_t device;
34 : ar5k_attach_t (*attach);
35 : } ar5k_known_products[] = {
36 : /*
37 : * From pcidevs_data.h
38 : */
39 : { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5210,
40 : ar5k_ar5210_attach },
41 : { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5210_AP,
42 : ar5k_ar5210_attach },
43 : { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5210_DEFAULT,
44 : ar5k_ar5210_attach },
45 : { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5211,
46 : ar5k_ar5211_attach },
47 : { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5211_DEFAULT,
48 : ar5k_ar5211_attach },
49 : { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5311,
50 : ar5k_ar5211_attach },
51 : { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5211_FPGA11B,
52 : ar5k_ar5211_attach },
53 : { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5211_LEGACY,
54 : ar5k_ar5211_attach },
55 : { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5212,
56 : ar5k_ar5212_attach },
57 : { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5212_DEFAULT,
58 : ar5k_ar5212_attach },
59 : { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5212_FPGA,
60 : ar5k_ar5212_attach },
61 : { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5212_IBM,
62 : ar5k_ar5212_attach },
63 : { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR2413,
64 : ar5k_ar5212_attach },
65 : { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5413,
66 : ar5k_ar5212_attach },
67 : { PCI_VENDOR_ATHEROS, PCI_PRODUCT_ATHEROS_AR5424,
68 : ar5k_ar5212_attach },
69 : { PCI_VENDOR_3COM, PCI_PRODUCT_3COM_3CRDAG675,
70 : ar5k_ar5212_attach },
71 : { PCI_VENDOR_3COM2, PCI_PRODUCT_3COM2_3CRPAG175,
72 : ar5k_ar5212_attach }
73 : };
74 :
75 : static const HAL_RATE_TABLE ar5k_rt_11a = AR5K_RATES_11A;
76 : static const HAL_RATE_TABLE ar5k_rt_11b = AR5K_RATES_11B;
77 : static const HAL_RATE_TABLE ar5k_rt_11g = AR5K_RATES_11G;
78 : static const HAL_RATE_TABLE ar5k_rt_xr = AR5K_RATES_XR;
79 :
80 : int ar5k_eeprom_read_ants(struct ath_hal *, u_int32_t *, u_int);
81 : int ar5k_eeprom_read_modes(struct ath_hal *, u_int32_t *, u_int);
82 : u_int16_t ar5k_eeprom_bin2freq(struct ath_hal *, u_int16_t, u_int);
83 :
84 : HAL_BOOL ar5k_ar5110_channel(struct ath_hal *, HAL_CHANNEL *);
85 : u_int32_t ar5k_ar5110_chan2athchan(HAL_CHANNEL *);
86 : HAL_BOOL ar5k_ar5111_channel(struct ath_hal *, HAL_CHANNEL *);
87 : HAL_BOOL ar5k_ar5111_chan2athchan(u_int, struct ar5k_athchan_2ghz *);
88 : HAL_BOOL ar5k_ar5112_channel(struct ath_hal *, HAL_CHANNEL *);
89 : HAL_BOOL ar5k_check_channel(struct ath_hal *, u_int16_t, u_int flags);
90 :
91 : HAL_BOOL ar5k_ar5111_rfregs(struct ath_hal *, HAL_CHANNEL *, u_int);
92 : HAL_BOOL ar5k_ar5112_rfregs(struct ath_hal *, HAL_CHANNEL *, u_int);
93 : HAL_BOOL ar5k_arxxxx_rfregs(struct ath_hal *, HAL_CHANNEL *, u_int);
94 : u_int ar5k_rfregs_op(u_int32_t *, u_int32_t, u_int32_t, u_int32_t,
95 : u_int32_t, u_int32_t, HAL_BOOL);
96 :
97 : /*
98 : * Supported channels
99 : */
100 : static const struct
101 : ieee80211_regchannel ar5k_5ghz_channels[] = IEEE80211_CHANNELS_5GHZ;
102 : static const struct
103 : ieee80211_regchannel ar5k_2ghz_channels[] = IEEE80211_CHANNELS_2GHZ;
104 :
105 : /*
106 : * Initial gain optimization values
107 : */
108 : static const struct ar5k_gain_opt ar5111_gain_opt = AR5K_AR5111_GAIN_OPT;
109 : static const struct ar5k_gain_opt ar5112_gain_opt = AR5K_AR5112_GAIN_OPT;
110 :
111 : /*
112 : * Initial register for the radio chipsets
113 : */
114 : static const struct ar5k_ini_rf ar5111_rf[] = AR5K_AR5111_INI_RF;
115 : static const struct ar5k_ini_rf ar5112_rf[] = AR5K_AR5112_INI_RF;
116 : static const struct ar5k_ini_rf ar5112a_rf[] = AR5K_AR5112A_INI_RF;
117 : static const struct ar5k_ini_rf ar5413_rf[] = AR5K_AR5413_INI_RF;
118 : static const struct ar5k_ini_rf ar2413_rf[] = AR5K_AR2413_INI_RF;
119 : static const struct ar5k_ini_rf ar2425_rf[] = AR5K_AR2425_INI_RF;
120 : static const struct ar5k_ini_rfgain ar5111_rfg[] = AR5K_AR5111_INI_RFGAIN;
121 : static const struct ar5k_ini_rfgain ar5112_rfg[] = AR5K_AR5112_INI_RFGAIN;
122 : static const struct ar5k_ini_rfgain ar5413_rfg[] = AR5K_AR5413_INI_RFGAIN;
123 : static const struct ar5k_ini_rfgain ar2413_rfg[] = AR5K_AR2413_INI_RFGAIN;
124 :
125 : /*
126 : * Enable to overwrite the country code (use "00" for debug)
127 : */
128 : #if 0
129 : #define COUNTRYCODE "00"
130 : #endif
131 :
132 : /*
133 : * Perform a lookup if the device is supported by the HAL
134 : */
135 : const char *
136 0 : ath_hal_probe(u_int16_t vendor, u_int16_t device)
137 : {
138 : int i;
139 :
140 : /*
141 : * Perform a linear search on the table of supported devices
142 : */
143 0 : for (i = 0; i < nitems(ar5k_known_products); i++) {
144 0 : if (vendor == ar5k_known_products[i].vendor &&
145 0 : device == ar5k_known_products[i].device)
146 0 : return ("");
147 : }
148 :
149 0 : return (NULL);
150 0 : }
151 :
152 : /*
153 : * Fills in the HAL structure and initialises the device
154 : */
155 : struct ath_hal *
156 0 : ath_hal_attach(u_int16_t device, void *arg, bus_space_tag_t st,
157 : bus_space_handle_t sh, u_int is_pcie, int *status)
158 : {
159 0 : struct ath_softc *sc = (struct ath_softc *)arg;
160 : struct ath_hal *hal = NULL;
161 : ar5k_attach_t *attach = NULL;
162 0 : u_int8_t mac[IEEE80211_ADDR_LEN];
163 : int i;
164 :
165 0 : *status = EINVAL;
166 :
167 : /*
168 : * Call the chipset-dependent attach routine by device id
169 : */
170 0 : for (i = 0; i < nitems(ar5k_known_products); i++) {
171 0 : if (device == ar5k_known_products[i].device &&
172 0 : ar5k_known_products[i].attach != NULL)
173 0 : attach = ar5k_known_products[i].attach;
174 : }
175 :
176 0 : if (attach == NULL) {
177 0 : *status = ENXIO;
178 0 : AR5K_PRINTF("device not supported: 0x%04x\n", device);
179 0 : return (NULL);
180 : }
181 :
182 0 : if ((hal = malloc(sizeof(struct ath_hal),
183 0 : M_DEVBUF, M_NOWAIT | M_ZERO)) == NULL) {
184 0 : *status = ENOMEM;
185 0 : AR5K_PRINT("out of memory\n");
186 0 : return (NULL);
187 : }
188 :
189 0 : hal->ah_sc = sc;
190 0 : hal->ah_st = st;
191 0 : hal->ah_sh = sh;
192 0 : hal->ah_device = device;
193 0 : hal->ah_sub_vendor = 0; /* XXX unknown?! */
194 :
195 : /*
196 : * HAL information
197 : */
198 0 : hal->ah_abi = HAL_ABI_VERSION;
199 0 : hal->ah_op_mode = HAL_M_STA;
200 0 : hal->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT;
201 0 : hal->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
202 0 : hal->ah_imr = 0;
203 0 : hal->ah_atim_window = 0;
204 0 : hal->ah_aifs = AR5K_TUNE_AIFS;
205 0 : hal->ah_cw_min = AR5K_TUNE_CWMIN;
206 0 : hal->ah_limit_tx_retries = AR5K_INIT_TX_RETRY;
207 0 : hal->ah_software_retry = AH_FALSE;
208 0 : hal->ah_ant_diversity = AR5K_TUNE_ANT_DIVERSITY;
209 0 : hal->ah_pci_express = is_pcie ? AH_TRUE : AH_FALSE;
210 :
211 0 : switch (device) {
212 : case PCI_PRODUCT_ATHEROS_AR2413:
213 : case PCI_PRODUCT_ATHEROS_AR5413:
214 : case PCI_PRODUCT_ATHEROS_AR5424:
215 : /*
216 : * Known single chip solutions
217 : */
218 0 : hal->ah_single_chip = AH_TRUE;
219 0 : break;
220 : default:
221 : /*
222 : * Multi chip solutions
223 : */
224 0 : hal->ah_single_chip = AH_FALSE;
225 0 : break;
226 : }
227 :
228 0 : if ((attach)(device, hal, st, sh, status) == NULL)
229 : goto failed;
230 :
231 : #ifdef AR5K_DEBUG
232 : hal->ah_dump_state(hal);
233 : #endif
234 :
235 : /*
236 : * Get card capabilities, values, ...
237 : */
238 :
239 0 : if (ar5k_eeprom_init(hal) != 0) {
240 0 : AR5K_PRINT("unable to init EEPROM\n");
241 0 : goto failed;
242 : }
243 :
244 : /* Get misc capabilities */
245 0 : if (hal->ah_get_capabilities(hal) != AH_TRUE) {
246 0 : AR5K_PRINTF("unable to get device capabilities: 0x%04x\n",
247 : device);
248 0 : goto failed;
249 : }
250 :
251 : /* Get MAC address */
252 0 : if ((*status = ar5k_eeprom_read_mac(hal, mac)) != 0) {
253 0 : AR5K_PRINTF("unable to read address from EEPROM: 0x%04x\n",
254 : device);
255 0 : goto failed;
256 : }
257 :
258 0 : hal->ah_set_lladdr(hal, mac);
259 :
260 : /* Get rate tables */
261 0 : if (hal->ah_capabilities.cap_mode & HAL_MODE_11A)
262 0 : ar5k_rt_copy(&hal->ah_rt_11a, &ar5k_rt_11a);
263 0 : if (hal->ah_capabilities.cap_mode & HAL_MODE_11B)
264 0 : ar5k_rt_copy(&hal->ah_rt_11b, &ar5k_rt_11b);
265 0 : if (hal->ah_capabilities.cap_mode & HAL_MODE_11G)
266 0 : ar5k_rt_copy(&hal->ah_rt_11g, &ar5k_rt_11g);
267 0 : if (hal->ah_capabilities.cap_mode & HAL_MODE_XR)
268 0 : ar5k_rt_copy(&hal->ah_rt_xr, &ar5k_rt_xr);
269 :
270 : /* Initialize the gain optimization values */
271 0 : if (hal->ah_radio == AR5K_AR5111) {
272 0 : hal->ah_gain.g_step_idx = ar5111_gain_opt.go_default;
273 0 : hal->ah_gain.g_step =
274 : &ar5111_gain_opt.go_step[hal->ah_gain.g_step_idx];
275 0 : hal->ah_gain.g_low = 20;
276 0 : hal->ah_gain.g_high = 35;
277 0 : hal->ah_gain.g_active = 1;
278 0 : } else if (hal->ah_radio == AR5K_AR5112) {
279 0 : hal->ah_gain.g_step_idx = ar5112_gain_opt.go_default;
280 0 : hal->ah_gain.g_step =
281 : &ar5112_gain_opt.go_step[hal->ah_gain.g_step_idx];
282 0 : hal->ah_gain.g_low = 20;
283 0 : hal->ah_gain.g_high = 85;
284 0 : hal->ah_gain.g_active = 1;
285 0 : } else {
286 : /* XXX not needed for newer chipsets? */
287 : }
288 :
289 0 : *status = HAL_OK;
290 :
291 0 : return (hal);
292 :
293 : failed:
294 0 : free(hal, M_DEVBUF, 0);
295 0 : return (NULL);
296 0 : }
297 :
298 : u_int16_t
299 0 : ath_hal_computetxtime(struct ath_hal *hal, const HAL_RATE_TABLE *rates,
300 : u_int32_t frame_length, u_int16_t rate_index, HAL_BOOL short_preamble)
301 : {
302 : const HAL_RATE *rate;
303 : u_int32_t value;
304 :
305 0 : AR5K_ASSERT_ENTRY(rate_index, rates->rateCount);
306 :
307 : /*
308 : * Get rate by index
309 : */
310 0 : rate = &rates->info[rate_index];
311 :
312 : /*
313 : * Calculate the transmission time by operation (PHY) mode
314 : */
315 0 : switch (rate->phy) {
316 : case IEEE80211_T_CCK:
317 : /*
318 : * CCK / DS mode (802.11b)
319 : */
320 0 : value = AR5K_CCK_TX_TIME(rate->rateKbps, frame_length,
321 : (short_preamble && rate->shortPreamble));
322 0 : break;
323 :
324 : case IEEE80211_T_OFDM:
325 : /*
326 : * Orthogonal Frequency Division Multiplexing
327 : */
328 0 : if (AR5K_OFDM_NUM_BITS_PER_SYM(rate->rateKbps) == 0)
329 0 : return (0);
330 0 : value = AR5K_OFDM_TX_TIME(rate->rateKbps, frame_length);
331 0 : break;
332 :
333 : case IEEE80211_T_XR:
334 : /*
335 : * Orthogonal Frequency Division Multiplexing
336 : * Atheros "eXtended Range" (XR)
337 : */
338 0 : if (AR5K_XR_NUM_BITS_PER_SYM(rate->rateKbps) == 0)
339 0 : return (0);
340 0 : value = AR5K_XR_TX_TIME(rate->rateKbps, frame_length);
341 0 : break;
342 :
343 : default:
344 0 : return (0);
345 : }
346 :
347 0 : return (value);
348 0 : }
349 :
350 : HAL_BOOL
351 0 : ar5k_check_channel(struct ath_hal *hal, u_int16_t freq, u_int flags)
352 : {
353 : /* Check if the channel is in our supported range */
354 0 : if (flags & IEEE80211_CHAN_2GHZ) {
355 0 : if ((freq >= hal->ah_capabilities.cap_range.range_2ghz_min) &&
356 0 : (freq <= hal->ah_capabilities.cap_range.range_2ghz_max))
357 0 : return (AH_TRUE);
358 0 : } else if (flags & IEEE80211_CHAN_5GHZ) {
359 0 : if ((freq >= hal->ah_capabilities.cap_range.range_5ghz_min) &&
360 0 : (freq <= hal->ah_capabilities.cap_range.range_5ghz_max))
361 0 : return (AH_TRUE);
362 : }
363 :
364 0 : return (AH_FALSE);
365 0 : }
366 :
367 : HAL_BOOL
368 0 : ath_hal_init_channels(struct ath_hal *hal, HAL_CHANNEL *channels,
369 : u_int max_channels, u_int *channels_size, u_int16_t mode,
370 : HAL_BOOL outdoor, HAL_BOOL extended)
371 : {
372 : u_int i, c;
373 : u_int32_t domain_current;
374 : u_int domain_5ghz, domain_2ghz;
375 : HAL_CHANNEL *all_channels;
376 :
377 0 : if ((all_channels = mallocarray(max_channels, sizeof(HAL_CHANNEL),
378 0 : M_TEMP, M_NOWAIT | M_ZERO)) == NULL)
379 0 : return (AH_FALSE);
380 :
381 : i = c = 0;
382 0 : domain_current = hal->ah_regdomain;
383 :
384 : /*
385 : * In debugging mode, enable all channels supported by the chipset
386 : */
387 0 : if (domain_current == DMN_DEFAULT) {
388 : int min, max, freq;
389 : u_int flags;
390 :
391 0 : min = ieee80211_mhz2ieee(IEEE80211_CHANNELS_2GHZ_MIN,
392 : IEEE80211_CHAN_2GHZ);
393 0 : max = ieee80211_mhz2ieee(IEEE80211_CHANNELS_2GHZ_MAX,
394 : IEEE80211_CHAN_2GHZ);
395 0 : flags = CHANNEL_B |
396 0 : (hal->ah_version == AR5K_AR5211 ?
397 : CHANNEL_PUREG : CHANNEL_G);
398 :
399 : debugchan:
400 0 : for (i = min; i <= max && c < max_channels; i++) {
401 0 : freq = ieee80211_ieee2mhz(i, flags);
402 0 : if (ar5k_check_channel(hal, freq, flags) == AH_FALSE)
403 : continue;
404 0 : all_channels[c].c_channel = freq;
405 0 : all_channels[c++].c_channel_flags = flags;
406 0 : }
407 :
408 0 : if (flags & IEEE80211_CHAN_2GHZ) {
409 0 : min = ieee80211_mhz2ieee(IEEE80211_CHANNELS_5GHZ_MIN,
410 : IEEE80211_CHAN_5GHZ);
411 0 : max = ieee80211_mhz2ieee(IEEE80211_CHANNELS_5GHZ_MAX,
412 : IEEE80211_CHAN_5GHZ);
413 : flags = CHANNEL_A | CHANNEL_XR;
414 0 : goto debugchan;
415 : }
416 :
417 : goto done;
418 : }
419 :
420 0 : domain_5ghz = ieee80211_regdomain2flag(domain_current,
421 : IEEE80211_CHANNELS_5GHZ_MIN);
422 0 : domain_2ghz = ieee80211_regdomain2flag(domain_current,
423 : IEEE80211_CHANNELS_2GHZ_MIN);
424 :
425 : /*
426 : * Create channel list based on chipset capabilities, regulation domain
427 : * and mode. 5GHz...
428 : */
429 0 : for (i = 0; (hal->ah_capabilities.cap_range.range_5ghz_max > 0) &&
430 0 : (i < nitems(ar5k_5ghz_channels)) &&
431 0 : (c < max_channels); i++) {
432 : /* Check if channel is supported by the chipset */
433 0 : if (ar5k_check_channel(hal,
434 0 : ar5k_5ghz_channels[i].rc_channel,
435 0 : IEEE80211_CHAN_5GHZ) == AH_FALSE)
436 : continue;
437 :
438 : /* Match regulation domain */
439 0 : if ((IEEE80211_DMN(ar5k_5ghz_channels[i].rc_domain) &
440 0 : IEEE80211_DMN(domain_5ghz)) == 0)
441 : continue;
442 :
443 : /* Match modes */
444 0 : if (ar5k_5ghz_channels[i].rc_mode & IEEE80211_CHAN_OFDM)
445 0 : all_channels[c].c_channel_flags = CHANNEL_A;
446 : else
447 : continue;
448 :
449 : /* Write channel and increment counter */
450 0 : all_channels[c++].channel = ar5k_5ghz_channels[i].rc_channel;
451 0 : }
452 :
453 : /*
454 : * ...and 2GHz.
455 : */
456 0 : for (i = 0; (hal->ah_capabilities.cap_range.range_2ghz_max > 0) &&
457 0 : (i < nitems(ar5k_2ghz_channels)) &&
458 0 : (c < max_channels); i++) {
459 : /* Check if channel is supported by the chipset */
460 0 : if (ar5k_check_channel(hal,
461 0 : ar5k_2ghz_channels[i].rc_channel,
462 0 : IEEE80211_CHAN_2GHZ) == AH_FALSE)
463 : continue;
464 :
465 : /* Match regulation domain */
466 0 : if ((IEEE80211_DMN(ar5k_2ghz_channels[i].rc_domain) &
467 0 : IEEE80211_DMN(domain_2ghz)) == 0)
468 : continue;
469 :
470 : /* Match modes */
471 0 : if ((hal->ah_capabilities.cap_mode & HAL_MODE_11B) &&
472 0 : (ar5k_2ghz_channels[i].rc_mode & IEEE80211_CHAN_CCK))
473 0 : all_channels[c].c_channel_flags = CHANNEL_B;
474 :
475 0 : if (hal->ah_capabilities.cap_mode & HAL_MODE_11G) {
476 0 : if (ar5k_2ghz_channels[i].rc_mode & IEEE80211_CHAN_CCK)
477 0 : all_channels[c].c_channel_flags = CHANNEL_B;
478 0 : if (ar5k_2ghz_channels[i].rc_mode & IEEE80211_CHAN_OFDM)
479 0 : all_channels[c].c_channel_flags |= (CHANNEL_G | CHANNEL_PUREG);
480 : }
481 :
482 : /* Write channel and increment counter */
483 0 : all_channels[c++].channel = ar5k_2ghz_channels[i].rc_channel;
484 0 : }
485 :
486 : done:
487 0 : bcopy(all_channels, channels, sizeof(HAL_CHANNEL) * max_channels);
488 0 : *channels_size = c;
489 0 : free(all_channels, M_TEMP, 0);
490 0 : return (AH_TRUE);
491 0 : }
492 :
493 : /*
494 : * Common internal functions
495 : */
496 :
497 : const char *
498 0 : ar5k_printver(enum ar5k_srev_type type, u_int32_t val)
499 : {
500 0 : struct ar5k_srev_name names[] = AR5K_SREV_NAME;
501 : const char *name = "xxxx";
502 : int i;
503 :
504 0 : for (i = 0; i < nitems(names); i++) {
505 0 : if (type == AR5K_VERSION_DEV) {
506 0 : if (names[i].sr_type == type &&
507 0 : names[i].sr_val == val) {
508 0 : name = names[i].sr_name;
509 0 : break;
510 : }
511 : continue;
512 : }
513 0 : if (names[i].sr_type != type ||
514 0 : names[i].sr_val == AR5K_SREV_UNKNOWN)
515 : continue;
516 : /*
517 : * The final iteration has names[i].sr_val == AR5K_SREV_UNKNOWN,
518 : * so there is no out-of-bounds access with names[i + 1] below.
519 : */
520 0 : if ((val & 0xff) < names[i + 1].sr_val) {
521 0 : name = names[i].sr_name;
522 0 : break;
523 : }
524 : }
525 :
526 0 : return (name);
527 0 : }
528 :
529 : void
530 0 : ar5k_radar_alert(struct ath_hal *hal)
531 : {
532 : /*
533 : * Limit ~1/s
534 : */
535 0 : if (hal->ah_radar.r_last_channel.channel ==
536 0 : hal->ah_current_channel.channel &&
537 0 : tick < (hal->ah_radar.r_last_alert + hz))
538 : return;
539 :
540 0 : hal->ah_radar.r_last_channel.channel =
541 0 : hal->ah_current_channel.channel;
542 0 : hal->ah_radar.r_last_channel.c_channel_flags =
543 0 : hal->ah_current_channel.c_channel_flags;
544 0 : hal->ah_radar.r_last_alert = tick;
545 :
546 0 : AR5K_PRINTF("Possible radar activity detected at %u MHz (tick %u)\n",
547 : hal->ah_radar.r_last_alert, hal->ah_current_channel.channel);
548 0 : }
549 :
550 : u_int16_t
551 0 : ar5k_regdomain_from_ieee(ieee80211_regdomain_t ieee)
552 : {
553 : u_int32_t regdomain = (u_int32_t)ieee;
554 :
555 : /*
556 : * Use the default regulation domain if the value is empty
557 : * or not supported by the net80211 regulation code.
558 : */
559 0 : if (ieee80211_regdomain2flag(regdomain,
560 0 : IEEE80211_CHANNELS_5GHZ_MIN) == DMN_DEBUG)
561 0 : return ((u_int16_t)AR5K_TUNE_REGDOMAIN);
562 :
563 : /* It is supported, just return the value */
564 0 : return (regdomain);
565 0 : }
566 :
567 : ieee80211_regdomain_t
568 0 : ar5k_regdomain_to_ieee(u_int16_t regdomain)
569 : {
570 0 : ieee80211_regdomain_t ieee = (ieee80211_regdomain_t)regdomain;
571 :
572 0 : return (ieee);
573 : }
574 :
575 : u_int16_t
576 0 : ar5k_get_regdomain(struct ath_hal *hal)
577 : {
578 : u_int16_t regdomain;
579 0 : ieee80211_regdomain_t ieee_regdomain;
580 : #ifdef COUNTRYCODE
581 : u_int16_t code;
582 : #endif
583 :
584 0 : ar5k_eeprom_regulation_domain(hal, AH_FALSE, &ieee_regdomain);
585 0 : hal->ah_capabilities.cap_regdomain.reg_hw = ieee_regdomain;
586 :
587 : #ifdef COUNTRYCODE
588 : /*
589 : * Get the regulation domain by country code. This will ignore
590 : * the settings found in the EEPROM.
591 : */
592 : code = ieee80211_name2countrycode(COUNTRYCODE);
593 : ieee_regdomain = ieee80211_countrycode2regdomain(code);
594 : #endif
595 :
596 0 : regdomain = ar5k_regdomain_from_ieee(ieee_regdomain);
597 0 : hal->ah_capabilities.cap_regdomain.reg_current = regdomain;
598 :
599 0 : return (regdomain);
600 0 : }
601 :
602 : u_int32_t
603 0 : ar5k_bitswap(u_int32_t val, u_int bits)
604 : {
605 0 : if (bits == 8) {
606 0 : val = ((val & 0xF0) >> 4) | ((val & 0x0F) << 4);
607 0 : val = ((val & 0xCC) >> 2) | ((val & 0x33) << 2);
608 0 : val = ((val & 0xAA) >> 1) | ((val & 0x55) << 1);
609 :
610 0 : return val;
611 : } else {
612 : u_int32_t retval = 0, bit, i;
613 :
614 0 : for (i = 0; i < bits; i++) {
615 0 : bit = (val >> i) & 1;
616 0 : retval = (retval << 1) | bit;
617 : }
618 :
619 : return retval;
620 : }
621 0 : }
622 :
623 : u_int
624 0 : ar5k_htoclock(u_int usec)
625 : {
626 0 : return (usec * 40);
627 : }
628 :
629 : u_int
630 0 : ar5k_clocktoh(u_int clock)
631 : {
632 0 : return (clock / 40);
633 : }
634 :
635 : void
636 0 : ar5k_rt_copy(HAL_RATE_TABLE *dst, const HAL_RATE_TABLE *src)
637 : {
638 0 : bzero(dst, sizeof(HAL_RATE_TABLE));
639 0 : dst->rateCount = src->rateCount;
640 0 : bcopy(src->rateCodeToIndex, dst->rateCodeToIndex,
641 : sizeof(dst->rateCodeToIndex));
642 0 : bcopy(src->info, dst->info, sizeof(dst->info));
643 0 : }
644 :
645 : HAL_BOOL
646 0 : ar5k_register_timeout(struct ath_hal *hal, u_int32_t reg, u_int32_t flag,
647 : u_int32_t val, HAL_BOOL is_set)
648 : {
649 : int i;
650 : u_int32_t data;
651 :
652 0 : for (i = AR5K_TUNE_REGISTER_TIMEOUT; i > 0; i--) {
653 0 : data = AR5K_REG_READ(reg);
654 0 : if ((is_set == AH_TRUE) && (data & flag))
655 : break;
656 0 : else if ((data & flag) == val)
657 : break;
658 0 : AR5K_DELAY(15);
659 : }
660 :
661 0 : if (i <= 0)
662 0 : return (AH_FALSE);
663 :
664 0 : return (AH_TRUE);
665 0 : }
666 :
667 : /*
668 : * Common ar5xx EEPROM access functions
669 : */
670 :
671 : u_int16_t
672 0 : ar5k_eeprom_bin2freq(struct ath_hal *hal, u_int16_t bin, u_int mode)
673 : {
674 : u_int16_t val;
675 :
676 0 : if (bin == AR5K_EEPROM_CHANNEL_DIS)
677 0 : return (bin);
678 :
679 0 : if (mode == AR5K_EEPROM_MODE_11A) {
680 0 : if (hal->ah_ee_version > AR5K_EEPROM_VERSION_3_2)
681 0 : val = (5 * bin) + 4800;
682 : else
683 0 : val = bin > 62 ?
684 0 : (10 * 62) + (5 * (bin - 62)) + 5100 :
685 0 : (bin * 10) + 5100;
686 : } else {
687 0 : if (hal->ah_ee_version > AR5K_EEPROM_VERSION_3_2)
688 0 : val = bin + 2300;
689 : else
690 0 : val = bin + 2400;
691 : }
692 :
693 0 : return (val);
694 0 : }
695 :
696 : int
697 0 : ar5k_eeprom_read_ants(struct ath_hal *hal, u_int32_t *offset, u_int mode)
698 : {
699 0 : struct ar5k_eeprom_info *ee = &hal->ah_capabilities.cap_eeprom;
700 0 : u_int32_t o = *offset;
701 0 : u_int16_t val;
702 : int ret, i = 0;
703 :
704 0 : AR5K_EEPROM_READ(o++, val);
705 0 : ee->ee_switch_settling[mode] = (val >> 8) & 0x7f;
706 0 : ee->ee_ant_tx_rx[mode] = (val >> 2) & 0x3f;
707 0 : ee->ee_ant_control[mode][i] = (val << 4) & 0x3f;
708 :
709 0 : AR5K_EEPROM_READ(o++, val);
710 0 : ee->ee_ant_control[mode][i++] |= (val >> 12) & 0xf;
711 0 : ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f;
712 0 : ee->ee_ant_control[mode][i++] = val & 0x3f;
713 :
714 0 : AR5K_EEPROM_READ(o++, val);
715 0 : ee->ee_ant_control[mode][i++] = (val >> 10) & 0x3f;
716 0 : ee->ee_ant_control[mode][i++] = (val >> 4) & 0x3f;
717 0 : ee->ee_ant_control[mode][i] = (val << 2) & 0x3f;
718 :
719 0 : AR5K_EEPROM_READ(o++, val);
720 0 : ee->ee_ant_control[mode][i++] |= (val >> 14) & 0x3;
721 0 : ee->ee_ant_control[mode][i++] = (val >> 8) & 0x3f;
722 0 : ee->ee_ant_control[mode][i++] = (val >> 2) & 0x3f;
723 0 : ee->ee_ant_control[mode][i] = (val << 4) & 0x3f;
724 :
725 0 : AR5K_EEPROM_READ(o++, val);
726 0 : ee->ee_ant_control[mode][i++] |= (val >> 12) & 0xf;
727 0 : ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f;
728 0 : ee->ee_ant_control[mode][i++] = val & 0x3f;
729 :
730 : /* Get antenna modes */
731 0 : hal->ah_antenna[mode][0] =
732 0 : (ee->ee_ant_control[mode][0] << 4) | 0x1;
733 0 : hal->ah_antenna[mode][HAL_ANT_FIXED_A] =
734 0 : ee->ee_ant_control[mode][1] |
735 0 : (ee->ee_ant_control[mode][2] << 6) |
736 0 : (ee->ee_ant_control[mode][3] << 12) |
737 0 : (ee->ee_ant_control[mode][4] << 18) |
738 0 : (ee->ee_ant_control[mode][5] << 24);
739 0 : hal->ah_antenna[mode][HAL_ANT_FIXED_B] =
740 0 : ee->ee_ant_control[mode][6] |
741 0 : (ee->ee_ant_control[mode][7] << 6) |
742 0 : (ee->ee_ant_control[mode][8] << 12) |
743 0 : (ee->ee_ant_control[mode][9] << 18) |
744 0 : (ee->ee_ant_control[mode][10] << 24);
745 :
746 : /* return new offset */
747 0 : *offset = o;
748 :
749 0 : return (0);
750 0 : }
751 :
752 : int
753 0 : ar5k_eeprom_read_modes(struct ath_hal *hal, u_int32_t *offset, u_int mode)
754 : {
755 0 : struct ar5k_eeprom_info *ee = &hal->ah_capabilities.cap_eeprom;
756 0 : u_int32_t o = *offset;
757 0 : u_int16_t val;
758 : int ret;
759 :
760 0 : AR5K_EEPROM_READ(o++, val);
761 0 : ee->ee_tx_end2xlna_enable[mode] = (val >> 8) & 0xff;
762 0 : ee->ee_thr_62[mode] = val & 0xff;
763 :
764 0 : if (hal->ah_ee_version <= AR5K_EEPROM_VERSION_3_2)
765 0 : ee->ee_thr_62[mode] =
766 0 : mode == AR5K_EEPROM_MODE_11A ? 15 : 28;
767 :
768 0 : AR5K_EEPROM_READ(o++, val);
769 0 : ee->ee_tx_end2xpa_disable[mode] = (val >> 8) & 0xff;
770 0 : ee->ee_tx_frm2xpa_enable[mode] = val & 0xff;
771 :
772 0 : AR5K_EEPROM_READ(o++, val);
773 0 : ee->ee_pga_desired_size[mode] = (val >> 8) & 0xff;
774 :
775 0 : if ((val & 0xff) & 0x80)
776 0 : ee->ee_noise_floor_thr[mode] = -((((val & 0xff) ^ 0xff)) + 1);
777 : else
778 0 : ee->ee_noise_floor_thr[mode] = val & 0xff;
779 :
780 0 : if (hal->ah_ee_version <= AR5K_EEPROM_VERSION_3_2)
781 0 : ee->ee_noise_floor_thr[mode] =
782 0 : mode == AR5K_EEPROM_MODE_11A ? -54 : -1;
783 :
784 0 : AR5K_EEPROM_READ(o++, val);
785 0 : ee->ee_xlna_gain[mode] = (val >> 5) & 0xff;
786 0 : ee->ee_x_gain[mode] = (val >> 1) & 0xf;
787 0 : ee->ee_xpd[mode] = val & 0x1;
788 :
789 0 : if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_0)
790 0 : ee->ee_fixed_bias[mode] = (val >> 13) & 0x1;
791 :
792 0 : if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_3_3) {
793 0 : AR5K_EEPROM_READ(o++, val);
794 0 : ee->ee_false_detect[mode] = (val >> 6) & 0x7f;
795 :
796 0 : if (mode == AR5K_EEPROM_MODE_11A)
797 0 : ee->ee_xr_power[mode] = val & 0x3f;
798 : else {
799 0 : ee->ee_ob[mode][0] = val & 0x7;
800 0 : ee->ee_db[mode][0] = (val >> 3) & 0x7;
801 : }
802 : }
803 :
804 0 : if (hal->ah_ee_version < AR5K_EEPROM_VERSION_3_4) {
805 0 : ee->ee_i_gain[mode] = AR5K_EEPROM_I_GAIN;
806 0 : ee->ee_cck_ofdm_power_delta = AR5K_EEPROM_CCK_OFDM_DELTA;
807 0 : } else {
808 0 : ee->ee_i_gain[mode] = (val >> 13) & 0x7;
809 :
810 0 : AR5K_EEPROM_READ(o++, val);
811 0 : ee->ee_i_gain[mode] |= (val << 3) & 0x38;
812 :
813 0 : if (mode == AR5K_EEPROM_MODE_11G)
814 0 : ee->ee_cck_ofdm_power_delta = (val >> 3) & 0xff;
815 : }
816 :
817 0 : if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_0 &&
818 0 : mode == AR5K_EEPROM_MODE_11A) {
819 0 : ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
820 0 : ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
821 0 : }
822 :
823 0 : if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_6 &&
824 0 : mode == AR5K_EEPROM_MODE_11G)
825 0 : ee->ee_scaled_cck_delta = (val >> 11) & 0x1f;
826 :
827 : /* return new offset */
828 0 : *offset = o;
829 :
830 0 : return (0);
831 0 : }
832 :
833 : int
834 0 : ar5k_eeprom_init(struct ath_hal *hal)
835 : {
836 0 : struct ar5k_eeprom_info *ee = &hal->ah_capabilities.cap_eeprom;
837 0 : u_int32_t offset;
838 0 : u_int16_t val;
839 : int ret, i;
840 : u_int mode;
841 :
842 : /* Initial TX thermal adjustment values */
843 0 : ee->ee_tx_clip = 4;
844 0 : ee->ee_pwd_84 = ee->ee_pwd_90 = 1;
845 0 : ee->ee_gain_select = 1;
846 :
847 : /*
848 : * Read values from EEPROM and store them in the capability structure
849 : */
850 0 : AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MAGIC, ee_magic);
851 0 : AR5K_EEPROM_READ_HDR(AR5K_EEPROM_PROTECT, ee_protect);
852 0 : AR5K_EEPROM_READ_HDR(AR5K_EEPROM_REG_DOMAIN, ee_regdomain);
853 0 : AR5K_EEPROM_READ_HDR(AR5K_EEPROM_VERSION, ee_version);
854 0 : AR5K_EEPROM_READ_HDR(AR5K_EEPROM_HDR, ee_header);
855 :
856 : /* Return if we have an old EEPROM */
857 0 : if (hal->ah_ee_version < AR5K_EEPROM_VERSION_3_0)
858 0 : return (0);
859 :
860 : #ifdef notyet
861 : /*
862 : * Validate the checksum of the EEPROM date. There are some
863 : * devices with invalid EEPROMs.
864 : */
865 : for (cksum = 0, offset = 0; offset < AR5K_EEPROM_INFO_MAX; offset++) {
866 : AR5K_EEPROM_READ(AR5K_EEPROM_INFO(offset), val);
867 : cksum ^= val;
868 : }
869 : if (cksum != AR5K_EEPROM_INFO_CKSUM) {
870 : AR5K_PRINTF("Invalid EEPROM checksum 0x%04x\n", cksum);
871 : return (EINVAL);
872 : }
873 : #endif
874 :
875 0 : AR5K_EEPROM_READ_HDR(AR5K_EEPROM_ANT_GAIN(hal->ah_ee_version),
876 : ee_ant_gain);
877 :
878 0 : if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
879 0 : AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC0, ee_misc0);
880 0 : AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC1, ee_misc1);
881 : }
882 :
883 0 : if (hal->ah_ee_version < AR5K_EEPROM_VERSION_3_3) {
884 0 : AR5K_EEPROM_READ(AR5K_EEPROM_OBDB0_2GHZ, val);
885 0 : ee->ee_ob[AR5K_EEPROM_MODE_11B][0] = val & 0x7;
886 0 : ee->ee_db[AR5K_EEPROM_MODE_11B][0] = (val >> 3) & 0x7;
887 :
888 0 : AR5K_EEPROM_READ(AR5K_EEPROM_OBDB1_2GHZ, val);
889 0 : ee->ee_ob[AR5K_EEPROM_MODE_11G][0] = val & 0x7;
890 0 : ee->ee_db[AR5K_EEPROM_MODE_11G][0] = (val >> 3) & 0x7;
891 0 : }
892 :
893 : /*
894 : * Get conformance test limit values
895 : */
896 0 : offset = AR5K_EEPROM_CTL(hal->ah_ee_version);
897 0 : ee->ee_ctls = AR5K_EEPROM_N_CTLS(hal->ah_ee_version);
898 :
899 0 : for (i = 0; i < ee->ee_ctls - 1; i++) {
900 0 : AR5K_EEPROM_READ(offset++, val);
901 0 : ee->ee_ctl[i] = (val >> 8) & 0xff;
902 0 : ee->ee_ctl[i + 1] = val & 0xff;
903 : }
904 :
905 : /*
906 : * Get values for 802.11a (5GHz)
907 : */
908 : mode = AR5K_EEPROM_MODE_11A;
909 :
910 0 : offset = AR5K_EEPROM_MODES_11A(hal->ah_ee_version);
911 :
912 0 : if ((ret = ar5k_eeprom_read_ants(hal, &offset, mode)) != 0)
913 0 : return (ret);
914 :
915 0 : AR5K_EEPROM_READ(offset++, val);
916 0 : ee->ee_adc_desired_size[mode] = (int8_t)((val >> 8) & 0xff);
917 0 : ee->ee_ob[mode][3] = (val >> 5) & 0x7;
918 0 : ee->ee_db[mode][3] = (val >> 2) & 0x7;
919 0 : ee->ee_ob[mode][2] = (val << 1) & 0x7;
920 :
921 0 : AR5K_EEPROM_READ(offset++, val);
922 0 : ee->ee_ob[mode][2] |= (val >> 15) & 0x1;
923 0 : ee->ee_db[mode][2] = (val >> 12) & 0x7;
924 0 : ee->ee_ob[mode][1] = (val >> 9) & 0x7;
925 0 : ee->ee_db[mode][1] = (val >> 6) & 0x7;
926 0 : ee->ee_ob[mode][0] = (val >> 3) & 0x7;
927 0 : ee->ee_db[mode][0] = val & 0x7;
928 :
929 0 : if ((ret = ar5k_eeprom_read_modes(hal, &offset, mode)) != 0)
930 0 : return (ret);
931 :
932 0 : if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) {
933 0 : AR5K_EEPROM_READ(offset++, val);
934 0 : ee->ee_margin_tx_rx[mode] = val & 0x3f;
935 0 : }
936 :
937 : /*
938 : * Get values for 802.11b (2.4GHz)
939 : */
940 : mode = AR5K_EEPROM_MODE_11B;
941 0 : offset = AR5K_EEPROM_MODES_11B(hal->ah_ee_version);
942 :
943 0 : if ((ret = ar5k_eeprom_read_ants(hal, &offset, mode)) != 0)
944 0 : return (ret);
945 :
946 0 : AR5K_EEPROM_READ(offset++, val);
947 0 : ee->ee_adc_desired_size[mode] = (int8_t)((val >> 8) & 0xff);
948 0 : ee->ee_ob[mode][1] = (val >> 4) & 0x7;
949 0 : ee->ee_db[mode][1] = val & 0x7;
950 :
951 0 : if ((ret = ar5k_eeprom_read_modes(hal, &offset, mode)) != 0)
952 0 : return (ret);
953 :
954 0 : if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
955 0 : AR5K_EEPROM_READ(offset++, val);
956 0 : ee->ee_cal_pier[mode][0] =
957 0 : ar5k_eeprom_bin2freq(hal, val & 0xff, mode);
958 0 : ee->ee_cal_pier[mode][1] =
959 0 : ar5k_eeprom_bin2freq(hal, (val >> 8) & 0xff, mode);
960 :
961 0 : AR5K_EEPROM_READ(offset++, val);
962 0 : ee->ee_cal_pier[mode][2] =
963 0 : ar5k_eeprom_bin2freq(hal, val & 0xff, mode);
964 0 : }
965 :
966 0 : if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) {
967 0 : ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
968 0 : }
969 :
970 : /*
971 : * Get values for 802.11g (2.4GHz)
972 : */
973 : mode = AR5K_EEPROM_MODE_11G;
974 0 : offset = AR5K_EEPROM_MODES_11G(hal->ah_ee_version);
975 :
976 0 : if ((ret = ar5k_eeprom_read_ants(hal, &offset, mode)) != 0)
977 0 : return (ret);
978 :
979 0 : AR5K_EEPROM_READ(offset++, val);
980 0 : ee->ee_adc_desired_size[mode] = (int8_t)((val >> 8) & 0xff);
981 0 : ee->ee_ob[mode][1] = (val >> 4) & 0x7;
982 0 : ee->ee_db[mode][1] = val & 0x7;
983 :
984 0 : if ((ret = ar5k_eeprom_read_modes(hal, &offset, mode)) != 0)
985 0 : return (ret);
986 :
987 0 : if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
988 0 : AR5K_EEPROM_READ(offset++, val);
989 0 : ee->ee_cal_pier[mode][0] =
990 0 : ar5k_eeprom_bin2freq(hal, val & 0xff, mode);
991 0 : ee->ee_cal_pier[mode][1] =
992 0 : ar5k_eeprom_bin2freq(hal, (val >> 8) & 0xff, mode);
993 :
994 0 : AR5K_EEPROM_READ(offset++, val);
995 0 : ee->ee_xr_power[mode] = (val >> 7) & 0x3f;
996 :
997 0 : AR5K_EEPROM_READ(offset++, val);
998 0 : ee->ee_cal_pier[mode][2] =
999 0 : ar5k_eeprom_bin2freq(hal, val & 0xff, mode);
1000 :
1001 0 : if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) {
1002 0 : ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
1003 0 : }
1004 :
1005 0 : AR5K_EEPROM_READ(offset++, val);
1006 0 : ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
1007 0 : ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
1008 :
1009 0 : if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_2) {
1010 0 : AR5K_EEPROM_READ(offset++, val);
1011 0 : ee->ee_cck_ofdm_gain_delta = val & 0xff;
1012 0 : }
1013 : }
1014 :
1015 : /*
1016 : * Read 5GHz EEPROM channels
1017 : */
1018 :
1019 0 : return (0);
1020 0 : }
1021 :
1022 : int
1023 0 : ar5k_eeprom_read_mac(struct ath_hal *hal, u_int8_t *mac)
1024 : {
1025 : u_int32_t total, offset;
1026 0 : u_int16_t data;
1027 : int octet;
1028 0 : u_int8_t mac_d[IEEE80211_ADDR_LEN];
1029 :
1030 0 : bzero(mac, IEEE80211_ADDR_LEN);
1031 0 : bzero(&mac_d, IEEE80211_ADDR_LEN);
1032 :
1033 0 : if (hal->ah_eeprom_read(hal, 0x20, &data) != 0)
1034 0 : return (EIO);
1035 :
1036 0 : for (offset = 0x1f, octet = 0, total = 0;
1037 0 : offset >= 0x1d; offset--) {
1038 0 : if (hal->ah_eeprom_read(hal, offset, &data) != 0)
1039 0 : return (EIO);
1040 :
1041 0 : total += data;
1042 0 : mac_d[octet + 1] = data & 0xff;
1043 0 : mac_d[octet] = data >> 8;
1044 0 : octet += 2;
1045 : }
1046 :
1047 0 : bcopy(mac_d, mac, IEEE80211_ADDR_LEN);
1048 :
1049 0 : if ((!total) || total == (3 * 0xffff))
1050 0 : return (EINVAL);
1051 :
1052 0 : return (0);
1053 0 : }
1054 :
1055 : HAL_BOOL
1056 0 : ar5k_eeprom_regulation_domain(struct ath_hal *hal, HAL_BOOL write,
1057 : ieee80211_regdomain_t *regdomain)
1058 : {
1059 : u_int16_t ee_regdomain;
1060 :
1061 : /* Read current value */
1062 0 : if (write != AH_TRUE) {
1063 0 : ee_regdomain = hal->ah_capabilities.cap_eeprom.ee_regdomain;
1064 0 : *regdomain = ar5k_regdomain_to_ieee(ee_regdomain);
1065 0 : return (AH_TRUE);
1066 : }
1067 :
1068 0 : ee_regdomain = ar5k_regdomain_from_ieee(*regdomain);
1069 :
1070 : /* Try to write a new value */
1071 0 : if (hal->ah_capabilities.cap_eeprom.ee_protect &
1072 : AR5K_EEPROM_PROTECT_WR_128_191)
1073 0 : return (AH_FALSE);
1074 0 : if (hal->ah_eeprom_write(hal, AR5K_EEPROM_REG_DOMAIN,
1075 0 : ee_regdomain) != 0)
1076 0 : return (AH_FALSE);
1077 :
1078 0 : hal->ah_capabilities.cap_eeprom.ee_regdomain = ee_regdomain;
1079 :
1080 0 : return (AH_TRUE);
1081 0 : }
1082 :
1083 : /*
1084 : * PHY/RF access functions
1085 : */
1086 :
1087 : HAL_BOOL
1088 0 : ar5k_channel(struct ath_hal *hal, HAL_CHANNEL *channel)
1089 : {
1090 : HAL_BOOL ret;
1091 :
1092 : /*
1093 : * Check bounds supported by the PHY
1094 : * (don't care about regulation restrictions at this point)
1095 : */
1096 0 : if ((channel->channel < hal->ah_capabilities.cap_range.range_2ghz_min ||
1097 0 : channel->channel > hal->ah_capabilities.cap_range.range_2ghz_max) &&
1098 0 : (channel->channel < hal->ah_capabilities.cap_range.range_5ghz_min ||
1099 0 : channel->channel > hal->ah_capabilities.cap_range.range_5ghz_max)) {
1100 0 : AR5K_PRINTF("channel out of supported range (%u MHz)\n",
1101 : channel->channel);
1102 0 : return (AH_FALSE);
1103 : }
1104 :
1105 : /*
1106 : * Set the channel and wait
1107 : */
1108 0 : if (hal->ah_radio == AR5K_AR5110)
1109 0 : ret = ar5k_ar5110_channel(hal, channel);
1110 0 : else if (hal->ah_radio == AR5K_AR5111)
1111 0 : ret = ar5k_ar5111_channel(hal, channel);
1112 : else
1113 0 : ret = ar5k_ar5112_channel(hal, channel);
1114 :
1115 0 : if (ret == AH_FALSE)
1116 0 : return (ret);
1117 :
1118 0 : hal->ah_current_channel.c_channel = channel->c_channel;
1119 0 : hal->ah_current_channel.c_channel_flags = channel->c_channel_flags;
1120 :
1121 0 : return (AH_TRUE);
1122 0 : }
1123 :
1124 : u_int32_t
1125 0 : ar5k_ar5110_chan2athchan(HAL_CHANNEL *channel)
1126 : {
1127 : u_int32_t athchan;
1128 :
1129 : /*
1130 : * Convert IEEE channel/MHz to an internal channel value used
1131 : * by the AR5210 chipset. This has not been verified with
1132 : * newer chipsets like the AR5212A who have a completely
1133 : * different RF/PHY part.
1134 : */
1135 0 : athchan = (ar5k_bitswap((ieee80211_mhz2ieee(channel->c_channel,
1136 0 : channel->c_channel_flags) - 24) / 2, 5) << 1) |
1137 0 : (1 << 6) | 0x1;
1138 :
1139 0 : return (athchan);
1140 : }
1141 :
1142 : HAL_BOOL
1143 0 : ar5k_ar5110_channel(struct ath_hal *hal, HAL_CHANNEL *channel)
1144 : {
1145 : u_int32_t data;
1146 :
1147 : /*
1148 : * Set the channel and wait
1149 : */
1150 0 : data = ar5k_ar5110_chan2athchan(channel);
1151 0 : AR5K_PHY_WRITE(0x27, data);
1152 0 : AR5K_PHY_WRITE(0x30, 0);
1153 0 : AR5K_DELAY(1000);
1154 :
1155 0 : return (AH_TRUE);
1156 : }
1157 :
1158 : HAL_BOOL
1159 0 : ar5k_ar5111_chan2athchan(u_int ieee, struct ar5k_athchan_2ghz *athchan)
1160 : {
1161 : int channel;
1162 :
1163 : /* Cast this value to catch negative channel numbers (>= -19) */
1164 : channel = (int)ieee;
1165 :
1166 : /*
1167 : * Map 2GHz IEEE channel to 5GHz Atheros channel
1168 : */
1169 0 : if (channel <= 13) {
1170 0 : athchan->a2_athchan = 115 + channel;
1171 0 : athchan->a2_flags = 0x46;
1172 0 : } else if (channel == 14) {
1173 0 : athchan->a2_athchan = 124;
1174 0 : athchan->a2_flags = 0x44;
1175 0 : } else if (channel >= 15 && channel <= 26) {
1176 0 : athchan->a2_athchan = ((channel - 14) * 4) + 132;
1177 0 : athchan->a2_flags = 0x46;
1178 : } else
1179 0 : return (AH_FALSE);
1180 :
1181 0 : return (AH_TRUE);
1182 0 : }
1183 :
1184 : HAL_BOOL
1185 0 : ar5k_ar5111_channel(struct ath_hal *hal, HAL_CHANNEL *channel)
1186 : {
1187 : u_int ieee_channel, ath_channel;
1188 : u_int32_t data0, data1, clock;
1189 0 : struct ar5k_athchan_2ghz ath_channel_2ghz;
1190 :
1191 : /*
1192 : * Set the channel on the AR5111 radio
1193 : */
1194 : data0 = data1 = 0;
1195 0 : ath_channel = ieee_channel = ieee80211_mhz2ieee(channel->c_channel,
1196 0 : channel->c_channel_flags);
1197 :
1198 0 : if (channel->c_channel_flags & IEEE80211_CHAN_2GHZ) {
1199 : /* Map 2GHz channel to 5GHz Atheros channel ID */
1200 0 : if (ar5k_ar5111_chan2athchan(ieee_channel,
1201 0 : &ath_channel_2ghz) == AH_FALSE)
1202 0 : return (AH_FALSE);
1203 :
1204 0 : ath_channel = ath_channel_2ghz.a2_athchan;
1205 0 : data0 = ((ar5k_bitswap(ath_channel_2ghz.a2_flags, 8) & 0xff)
1206 0 : << 5) | (1 << 4);
1207 0 : }
1208 :
1209 0 : if (ath_channel < 145 || !(ath_channel & 1)) {
1210 : clock = 1;
1211 0 : data1 = ((ar5k_bitswap(ath_channel - 24, 8) & 0xff) << 2)
1212 0 : | (clock << 1) | (1 << 10) | 1;
1213 0 : } else {
1214 : clock = 0;
1215 0 : data1 = ((ar5k_bitswap((ath_channel - 24) / 2, 8) & 0xff) << 2)
1216 0 : | (clock << 1) | (1 << 10) | 1;
1217 : }
1218 :
1219 0 : AR5K_PHY_WRITE(0x27, (data1 & 0xff) | ((data0 & 0xff) << 8));
1220 0 : AR5K_PHY_WRITE(0x34, ((data1 >> 8) & 0xff) | (data0 & 0xff00));
1221 :
1222 0 : return (AH_TRUE);
1223 0 : }
1224 :
1225 : HAL_BOOL
1226 0 : ar5k_ar5112_channel(struct ath_hal *hal, HAL_CHANNEL *channel)
1227 : {
1228 : u_int32_t data, data0, data1, data2;
1229 : u_int16_t c;
1230 :
1231 : data = data0 = data1 = data2 = 0;
1232 0 : c = channel->c_channel + hal->ah_chanoff;
1233 :
1234 : /*
1235 : * Set the channel on the AR5112 or newer
1236 : */
1237 0 : if (c < 4800) {
1238 0 : if (!((c - 2224) % 5)) {
1239 0 : data0 = ((2 * (c - 704)) - 3040) / 10;
1240 : data1 = 1;
1241 0 : } else if (!((c - 2192) % 5)) {
1242 0 : data0 = ((2 * (c - 672)) - 3040) / 10;
1243 : data1 = 0;
1244 : } else
1245 0 : return (AH_FALSE);
1246 :
1247 0 : data0 = ar5k_bitswap((data0 << 2) & 0xff, 8);
1248 0 : } else {
1249 0 : if (!(c % 20) && c >= 5120) {
1250 0 : data0 = ar5k_bitswap(((c - 4800) / 20 << 2), 8);
1251 0 : data2 = ar5k_bitswap(3, 2);
1252 0 : } else if (!(c % 10)) {
1253 0 : data0 = ar5k_bitswap(((c - 4800) / 10 << 1), 8);
1254 0 : data2 = ar5k_bitswap(2, 2);
1255 0 : } else if (!(c % 5)) {
1256 0 : data0 = ar5k_bitswap((c - 4800) / 5, 8);
1257 0 : data2 = ar5k_bitswap(1, 2);
1258 : } else
1259 0 : return (AH_FALSE);
1260 : }
1261 :
1262 0 : data = (data0 << 4) | (data1 << 1) | (data2 << 2) | 0x1001;
1263 :
1264 0 : AR5K_PHY_WRITE(0x27, data & 0xff);
1265 0 : AR5K_PHY_WRITE(0x36, (data >> 8) & 0x7f);
1266 :
1267 0 : return (AH_TRUE);
1268 0 : }
1269 :
1270 : u_int
1271 0 : ar5k_rfregs_op(u_int32_t *rf, u_int32_t offset, u_int32_t reg, u_int32_t bits,
1272 : u_int32_t first, u_int32_t col, HAL_BOOL set)
1273 : {
1274 : u_int32_t mask, entry, last, data, shift, position;
1275 : int32_t left;
1276 : int i;
1277 :
1278 0 : if (rf == NULL) {
1279 : /* should not happen */
1280 0 : return (0);
1281 : }
1282 :
1283 0 : if (!(col <= 3 && bits <= 32 && first + bits <= 319)) {
1284 0 : AR5K_PRINTF("invalid values at offset %u\n", offset);
1285 0 : return (0);
1286 : }
1287 :
1288 0 : entry = ((first - 1) / 8) + offset;
1289 0 : position = (first - 1) % 8;
1290 :
1291 0 : if (set == AH_TRUE)
1292 0 : data = ar5k_bitswap(reg, bits);
1293 :
1294 0 : for (i = shift = 0, left = bits; left > 0; position = 0, entry++, i++) {
1295 0 : last = (position + left > 8) ? 8 : position + left;
1296 0 : mask = (((1 << last) - 1) ^ ((1 << position) - 1)) <<
1297 0 : (col * 8);
1298 :
1299 0 : if (set == AH_TRUE) {
1300 0 : rf[entry] &= ~mask;
1301 0 : rf[entry] |= ((data << position) << (col * 8)) & mask;
1302 0 : data >>= (8 - position);
1303 0 : } else {
1304 0 : data = (((rf[entry] & mask) >> (col * 8)) >>
1305 0 : position) << shift;
1306 0 : shift += last - position;
1307 : }
1308 :
1309 0 : left -= 8 - position;
1310 : }
1311 :
1312 0 : data = set == AH_TRUE ? 1 : ar5k_bitswap(data, bits);
1313 :
1314 0 : return (data);
1315 0 : }
1316 :
1317 : u_int32_t
1318 0 : ar5k_rfregs_gainf_corr(struct ath_hal *hal)
1319 : {
1320 : u_int32_t mix, step;
1321 : u_int32_t *rf;
1322 :
1323 0 : if (hal->ah_rf_banks == NULL)
1324 0 : return (0);
1325 :
1326 : rf = hal->ah_rf_banks;
1327 0 : hal->ah_gain.g_f_corr = 0;
1328 :
1329 0 : if (ar5k_rfregs_op(rf, hal->ah_offset[7], 0, 1, 36, 0, AH_FALSE) != 1)
1330 0 : return (0);
1331 :
1332 0 : step = ar5k_rfregs_op(rf, hal->ah_offset[7], 0, 4, 32, 0, AH_FALSE);
1333 0 : mix = hal->ah_gain.g_step->gos_param[0];
1334 :
1335 0 : switch (mix) {
1336 : case 3:
1337 0 : hal->ah_gain.g_f_corr = step * 2;
1338 0 : break;
1339 : case 2:
1340 0 : hal->ah_gain.g_f_corr = (step - 5) * 2;
1341 0 : break;
1342 : case 1:
1343 0 : hal->ah_gain.g_f_corr = step;
1344 0 : break;
1345 : default:
1346 0 : hal->ah_gain.g_f_corr = 0;
1347 0 : break;
1348 : }
1349 :
1350 0 : return (hal->ah_gain.g_f_corr);
1351 0 : }
1352 :
1353 : HAL_BOOL
1354 0 : ar5k_rfregs_gain_readback(struct ath_hal *hal)
1355 : {
1356 : u_int32_t step, mix, level[4];
1357 : u_int32_t *rf;
1358 :
1359 0 : if (hal->ah_rf_banks == NULL)
1360 0 : return (0);
1361 :
1362 : rf = hal->ah_rf_banks;
1363 :
1364 0 : if (hal->ah_radio == AR5K_AR5111) {
1365 0 : step = ar5k_rfregs_op(rf, hal->ah_offset[7],
1366 : 0, 6, 37, 0, AH_FALSE);
1367 : level[0] = 0;
1368 0 : level[1] = (step == 0x3f) ? 0x32 : step + 4;
1369 0 : level[2] = (step != 0x3f) ? 0x40 : level[0];
1370 0 : level[3] = level[2] + 0x32;
1371 :
1372 0 : hal->ah_gain.g_high = level[3] -
1373 0 : (step == 0x3f ? AR5K_GAIN_DYN_ADJUST_HI_MARGIN : -5);
1374 0 : hal->ah_gain.g_low = level[0] +
1375 0 : (step == 0x3f ? AR5K_GAIN_DYN_ADJUST_LO_MARGIN : 0);
1376 0 : } else {
1377 0 : mix = ar5k_rfregs_op(rf, hal->ah_offset[7],
1378 : 0, 1, 36, 0, AH_FALSE);
1379 : level[0] = level[2] = 0;
1380 :
1381 0 : if (mix == 1) {
1382 : level[1] = level[3] = 83;
1383 0 : } else {
1384 : level[1] = level[3] = 107;
1385 0 : hal->ah_gain.g_high = 55;
1386 : }
1387 : }
1388 :
1389 0 : return ((hal->ah_gain.g_current >= level[0] &&
1390 0 : hal->ah_gain.g_current <= level[1]) ||
1391 0 : (hal->ah_gain.g_current >= level[2] &&
1392 0 : hal->ah_gain.g_current <= level[3]));
1393 0 : }
1394 :
1395 : int32_t
1396 0 : ar5k_rfregs_gain_adjust(struct ath_hal *hal)
1397 : {
1398 : int ret = 0;
1399 : const struct ar5k_gain_opt *go;
1400 :
1401 0 : go = hal->ah_radio == AR5K_AR5111 ?
1402 : &ar5111_gain_opt : &ar5112_gain_opt;
1403 :
1404 0 : hal->ah_gain.g_step = &go->go_step[hal->ah_gain.g_step_idx];
1405 :
1406 0 : if (hal->ah_gain.g_current >= hal->ah_gain.g_high) {
1407 0 : if (hal->ah_gain.g_step_idx == 0)
1408 0 : return (-1);
1409 0 : for (hal->ah_gain.g_target = hal->ah_gain.g_current;
1410 0 : hal->ah_gain.g_target >= hal->ah_gain.g_high &&
1411 0 : hal->ah_gain.g_step_idx > 0;
1412 0 : hal->ah_gain.g_step =
1413 0 : &go->go_step[hal->ah_gain.g_step_idx]) {
1414 0 : hal->ah_gain.g_target -= 2 *
1415 0 : (go->go_step[--(hal->ah_gain.g_step_idx)].gos_gain -
1416 0 : hal->ah_gain.g_step->gos_gain);
1417 : }
1418 :
1419 : ret = 1;
1420 0 : goto done;
1421 : }
1422 :
1423 0 : if (hal->ah_gain.g_current <= hal->ah_gain.g_low) {
1424 0 : if (hal->ah_gain.g_step_idx == (go->go_steps_count - 1))
1425 0 : return (-2);
1426 0 : for (hal->ah_gain.g_target = hal->ah_gain.g_current;
1427 0 : hal->ah_gain.g_target <= hal->ah_gain.g_low &&
1428 0 : hal->ah_gain.g_step_idx < (go->go_steps_count - 1);
1429 0 : hal->ah_gain.g_step =
1430 0 : &go->go_step[hal->ah_gain.g_step_idx]) {
1431 0 : hal->ah_gain.g_target -= 2 *
1432 0 : (go->go_step[++(hal->ah_gain.g_step_idx)].gos_gain -
1433 0 : hal->ah_gain.g_step->gos_gain);
1434 : }
1435 :
1436 : ret = 2;
1437 0 : goto done;
1438 : }
1439 :
1440 : done:
1441 : #ifdef AR5K_DEBUG
1442 : AR5K_PRINTF("ret %d, gain step %u, current gain %u, target gain %u\n",
1443 : ret,
1444 : hal->ah_gain.g_step_idx,
1445 : hal->ah_gain.g_current,
1446 : hal->ah_gain.g_target);
1447 : #endif
1448 :
1449 0 : return (ret);
1450 0 : }
1451 :
1452 : HAL_BOOL
1453 0 : ar5k_rfregs(struct ath_hal *hal, HAL_CHANNEL *channel, u_int mode)
1454 : {
1455 : ar5k_rfgain_t *func = NULL;
1456 : HAL_BOOL ret;
1457 :
1458 0 : switch (hal->ah_radio) {
1459 : case AR5K_AR5111:
1460 0 : hal->ah_rf_banks_size = sizeof(ar5111_rf);
1461 : func = ar5k_ar5111_rfregs;
1462 0 : break;
1463 : case AR5K_AR5112:
1464 0 : if (hal->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A)
1465 0 : hal->ah_rf_banks_size = sizeof(ar5112a_rf);
1466 : else
1467 0 : hal->ah_rf_banks_size = sizeof(ar5112_rf);
1468 : func = ar5k_ar5112_rfregs;
1469 0 : break;
1470 : case AR5K_AR5413:
1471 0 : hal->ah_rf_banks_size = sizeof(ar5413_rf);
1472 : func = ar5k_arxxxx_rfregs;
1473 0 : break;
1474 : case AR5K_AR2413:
1475 0 : hal->ah_rf_banks_size = sizeof(ar2413_rf);
1476 : func = ar5k_arxxxx_rfregs;
1477 0 : break;
1478 : case AR5K_AR2425:
1479 0 : hal->ah_rf_banks_size = sizeof(ar2425_rf);
1480 : func = ar5k_arxxxx_rfregs;
1481 0 : break;
1482 : default:
1483 0 : return (AH_FALSE);
1484 : }
1485 :
1486 0 : if (hal->ah_rf_banks == NULL) {
1487 : /* XXX do extra checks? */
1488 0 : if ((hal->ah_rf_banks = malloc(hal->ah_rf_banks_size,
1489 0 : M_DEVBUF, M_NOWAIT | M_ZERO)) == NULL) {
1490 0 : AR5K_PRINT("out of memory\n");
1491 0 : return (AH_FALSE);
1492 : }
1493 : }
1494 :
1495 0 : ret = (func)(hal, channel, mode);
1496 :
1497 0 : if (ret == AH_TRUE)
1498 0 : hal->ah_rf_gain = HAL_RFGAIN_INACTIVE;
1499 :
1500 0 : return (ret);
1501 0 : }
1502 :
1503 : HAL_BOOL
1504 0 : ar5k_ar5111_rfregs(struct ath_hal *hal, HAL_CHANNEL *channel, u_int mode)
1505 : {
1506 0 : struct ar5k_eeprom_info *ee = &hal->ah_capabilities.cap_eeprom;
1507 : const u_int rf_size = nitems(ar5111_rf);
1508 : u_int32_t *rf;
1509 : int i, obdb = -1, bank = -1;
1510 : u_int32_t ee_mode;
1511 :
1512 0 : AR5K_ASSERT_ENTRY(mode, AR5K_INI_VAL_MAX);
1513 :
1514 0 : rf = hal->ah_rf_banks;
1515 :
1516 : /* Copy values to modify them */
1517 0 : for (i = 0; i < rf_size; i++) {
1518 0 : if (ar5111_rf[i].rf_bank >=
1519 : AR5K_AR5111_INI_RF_MAX_BANKS) {
1520 0 : AR5K_PRINT("invalid bank\n");
1521 0 : return (AH_FALSE);
1522 : }
1523 :
1524 0 : if (bank != ar5111_rf[i].rf_bank) {
1525 : bank = ar5111_rf[i].rf_bank;
1526 0 : hal->ah_offset[bank] = i;
1527 0 : }
1528 :
1529 0 : rf[i] = ar5111_rf[i].rf_value[mode];
1530 : }
1531 :
1532 0 : if (channel->c_channel_flags & IEEE80211_CHAN_2GHZ) {
1533 0 : if ((channel->c_channel_flags & IEEE80211_CHAN_G) ==
1534 : IEEE80211_CHAN_G)
1535 0 : ee_mode = AR5K_EEPROM_MODE_11G;
1536 : else
1537 : ee_mode = AR5K_EEPROM_MODE_11B;
1538 : obdb = 0;
1539 :
1540 0 : if (!ar5k_rfregs_op(rf, hal->ah_offset[0],
1541 0 : ee->ee_ob[ee_mode][obdb], 3, 119, 0, AH_TRUE))
1542 0 : return (AH_FALSE);
1543 :
1544 0 : if (!ar5k_rfregs_op(rf, hal->ah_offset[0],
1545 0 : ee->ee_ob[ee_mode][obdb], 3, 122, 0, AH_TRUE))
1546 0 : return (AH_FALSE);
1547 :
1548 : obdb = 1;
1549 0 : } else {
1550 : /* For 11a, Turbo and XR */
1551 : ee_mode = AR5K_EEPROM_MODE_11A;
1552 0 : obdb = channel->c_channel >= 5725 ? 3 :
1553 0 : (channel->c_channel >= 5500 ? 2 :
1554 0 : (channel->c_channel >= 5260 ? 1 :
1555 0 : (channel->c_channel > 4000 ? 0 : -1)));
1556 :
1557 0 : if (!ar5k_rfregs_op(rf, hal->ah_offset[6],
1558 0 : ee->ee_pwd_84, 1, 51, 3, AH_TRUE))
1559 0 : return (AH_FALSE);
1560 :
1561 0 : if (!ar5k_rfregs_op(rf, hal->ah_offset[6],
1562 0 : ee->ee_pwd_90, 1, 45, 3, AH_TRUE))
1563 0 : return (AH_FALSE);
1564 : }
1565 :
1566 0 : if (!ar5k_rfregs_op(rf, hal->ah_offset[6],
1567 0 : !ee->ee_xpd[ee_mode], 1, 95, 0, AH_TRUE))
1568 0 : return (AH_FALSE);
1569 :
1570 0 : if (!ar5k_rfregs_op(rf, hal->ah_offset[6],
1571 0 : ee->ee_x_gain[ee_mode], 4, 96, 0, AH_TRUE))
1572 0 : return (AH_FALSE);
1573 :
1574 0 : if (!ar5k_rfregs_op(rf, hal->ah_offset[6],
1575 0 : obdb >= 0 ? ee->ee_ob[ee_mode][obdb] : 0, 3, 104, 0, AH_TRUE))
1576 0 : return (AH_FALSE);
1577 :
1578 0 : if (!ar5k_rfregs_op(rf, hal->ah_offset[6],
1579 0 : obdb >= 0 ? ee->ee_db[ee_mode][obdb] : 0, 3, 107, 0, AH_TRUE))
1580 0 : return (AH_FALSE);
1581 :
1582 0 : if (!ar5k_rfregs_op(rf, hal->ah_offset[7],
1583 0 : ee->ee_i_gain[ee_mode], 6, 29, 0, AH_TRUE))
1584 0 : return (AH_FALSE);
1585 :
1586 0 : if (!ar5k_rfregs_op(rf, hal->ah_offset[7],
1587 0 : ee->ee_xpd[ee_mode], 1, 4, 0, AH_TRUE))
1588 0 : return (AH_FALSE);
1589 :
1590 : /* Write RF values */
1591 0 : for (i = 0; i < rf_size; i++) {
1592 0 : AR5K_REG_WAIT(i);
1593 0 : AR5K_REG_WRITE(ar5111_rf[i].rf_register, rf[i]);
1594 : }
1595 :
1596 0 : return (AH_TRUE);
1597 0 : }
1598 :
1599 : HAL_BOOL
1600 0 : ar5k_ar5112_rfregs(struct ath_hal *hal, HAL_CHANNEL *channel, u_int mode)
1601 : {
1602 0 : struct ar5k_eeprom_info *ee = &hal->ah_capabilities.cap_eeprom;
1603 : u_int rf_size;
1604 : u_int32_t *rf;
1605 : int i, obdb = -1, bank = -1;
1606 : u_int32_t ee_mode;
1607 : const struct ar5k_ini_rf *rf_ini;
1608 :
1609 0 : AR5K_ASSERT_ENTRY(mode, AR5K_INI_VAL_MAX);
1610 :
1611 0 : rf = hal->ah_rf_banks;
1612 :
1613 0 : if (hal->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) {
1614 : rf_ini = ar5112a_rf;
1615 : rf_size = nitems(ar5112a_rf);
1616 0 : } else {
1617 : rf_ini = ar5112_rf;
1618 : rf_size = nitems(ar5112_rf);
1619 : }
1620 :
1621 : /* Copy values to modify them */
1622 0 : for (i = 0; i < rf_size; i++) {
1623 0 : if (rf_ini[i].rf_bank >=
1624 : AR5K_AR5112_INI_RF_MAX_BANKS) {
1625 0 : AR5K_PRINT("invalid bank\n");
1626 0 : return (AH_FALSE);
1627 : }
1628 :
1629 0 : if (bank != rf_ini[i].rf_bank) {
1630 : bank = rf_ini[i].rf_bank;
1631 0 : hal->ah_offset[bank] = i;
1632 0 : }
1633 :
1634 0 : rf[i] = rf_ini[i].rf_value[mode];
1635 : }
1636 :
1637 0 : if (channel->c_channel_flags & IEEE80211_CHAN_2GHZ) {
1638 0 : if ((channel->c_channel_flags & IEEE80211_CHAN_G) ==
1639 : IEEE80211_CHAN_G)
1640 0 : ee_mode = AR5K_EEPROM_MODE_11G;
1641 : else
1642 : ee_mode = AR5K_EEPROM_MODE_11B;
1643 : obdb = 0;
1644 :
1645 0 : if (!ar5k_rfregs_op(rf, hal->ah_offset[6],
1646 0 : ee->ee_ob[ee_mode][obdb], 3, 287, 0, AH_TRUE))
1647 0 : return (AH_FALSE);
1648 :
1649 0 : if (!ar5k_rfregs_op(rf, hal->ah_offset[6],
1650 0 : ee->ee_ob[ee_mode][obdb], 3, 290, 0, AH_TRUE))
1651 0 : return (AH_FALSE);
1652 : } else {
1653 : /* For 11a, Turbo and XR */
1654 : ee_mode = AR5K_EEPROM_MODE_11A;
1655 0 : obdb = channel->c_channel >= 5725 ? 3 :
1656 0 : (channel->c_channel >= 5500 ? 2 :
1657 0 : (channel->c_channel >= 5260 ? 1 :
1658 0 : (channel->c_channel > 4000 ? 0 : -1)));
1659 :
1660 : /* bogus channel: bad beacon? */
1661 0 : if (obdb < 0)
1662 0 : return (AH_FALSE);
1663 :
1664 0 : if (!ar5k_rfregs_op(rf, hal->ah_offset[6],
1665 0 : ee->ee_ob[ee_mode][obdb], 3, 279, 0, AH_TRUE))
1666 0 : return (AH_FALSE);
1667 :
1668 0 : if (!ar5k_rfregs_op(rf, hal->ah_offset[6],
1669 0 : ee->ee_ob[ee_mode][obdb], 3, 282, 0, AH_TRUE))
1670 0 : return (AH_FALSE);
1671 : }
1672 :
1673 : #ifdef notyet
1674 : ar5k_rfregs_op(rf, hal->ah_offset[6],
1675 : ee->ee_x_gain[ee_mode], 2, 270, 0, AH_TRUE);
1676 : ar5k_rfregs_op(rf, hal->ah_offset[6],
1677 : ee->ee_x_gain[ee_mode], 2, 257, 0, AH_TRUE);
1678 : #endif
1679 :
1680 0 : if (!ar5k_rfregs_op(rf, hal->ah_offset[6],
1681 0 : ee->ee_xpd[ee_mode], 1, 302, 0, AH_TRUE))
1682 0 : return (AH_FALSE);
1683 :
1684 0 : if (!ar5k_rfregs_op(rf, hal->ah_offset[7],
1685 0 : ee->ee_i_gain[ee_mode], 6, 14, 0, AH_TRUE))
1686 0 : return (AH_FALSE);
1687 :
1688 : /* Write RF values */
1689 0 : for (i = 0; i < rf_size; i++)
1690 0 : AR5K_REG_WRITE(rf_ini[i].rf_register, rf[i]);
1691 :
1692 0 : return (AH_TRUE);
1693 0 : }
1694 :
1695 : HAL_BOOL
1696 0 : ar5k_arxxxx_rfregs(struct ath_hal *hal, HAL_CHANNEL *channel, u_int mode)
1697 : {
1698 : const struct ar5k_ini_rf *rf_ini;
1699 : u_int rf_size;
1700 : u_int32_t *rf;
1701 : int i, bank = -1;
1702 :
1703 0 : AR5K_ASSERT_ENTRY(mode, AR5K_INI_VAL_MAX);
1704 :
1705 0 : rf = hal->ah_rf_banks;
1706 :
1707 0 : switch (hal->ah_radio) {
1708 : case AR5K_AR5413:
1709 : rf_ini = ar5413_rf;
1710 : rf_size = nitems(ar5413_rf);
1711 0 : break;
1712 : case AR5K_AR2413:
1713 : rf_ini = ar2413_rf;
1714 : rf_size = nitems(ar2413_rf);
1715 0 : break;
1716 : case AR5K_AR2425:
1717 0 : if (mode == AR5K_INI_VAL_11B)
1718 0 : mode = AR5K_INI_VAL_11G;
1719 : rf_ini = ar2425_rf;
1720 : rf_size = nitems(ar2425_rf);
1721 0 : break;
1722 : default:
1723 0 : return (AH_FALSE);
1724 : }
1725 :
1726 : /* Copy values to modify them */
1727 0 : for (i = 0; i < rf_size; i++) {
1728 0 : if (rf_ini[i].rf_bank >= AR5K_MAX_RF_BANKS) {
1729 0 : AR5K_PRINT("invalid bank\n");
1730 0 : return (AH_FALSE);
1731 : }
1732 :
1733 0 : if (bank != rf_ini[i].rf_bank) {
1734 : bank = rf_ini[i].rf_bank;
1735 0 : hal->ah_offset[bank] = i;
1736 0 : }
1737 :
1738 0 : rf[i] = rf_ini[i].rf_value[mode];
1739 : }
1740 :
1741 : /* Write RF values */
1742 0 : for (i = 0; i < rf_size; i++)
1743 0 : AR5K_REG_WRITE(rf_ini[i].rf_register, rf[i]);
1744 :
1745 0 : return (AH_TRUE);
1746 0 : }
1747 :
1748 : HAL_BOOL
1749 0 : ar5k_rfgain(struct ath_hal *hal, u_int freq)
1750 : {
1751 : const struct ar5k_ini_rfgain *rfg;
1752 : size_t rfg_size;
1753 : int i;
1754 :
1755 0 : switch (hal->ah_radio) {
1756 : case AR5K_AR5111:
1757 : rfg = ar5111_rfg;
1758 : rfg_size = nitems(ar5111_rfg);
1759 0 : break;
1760 : case AR5K_AR5112:
1761 : rfg = ar5112_rfg;
1762 : rfg_size = nitems(ar5112_rfg);
1763 0 : break;
1764 : case AR5K_AR5413:
1765 : rfg = ar5413_rfg;
1766 : rfg_size = nitems(ar5413_rfg);
1767 0 : break;
1768 : case AR5K_AR2413:
1769 : case AR5K_AR2425:
1770 0 : if (freq == AR5K_INI_RFGAIN_5GHZ)
1771 0 : return (AH_FALSE);
1772 : rfg = ar2413_rfg;
1773 : rfg_size = nitems(ar2413_rfg);
1774 0 : break;
1775 : default:
1776 0 : return (AH_FALSE);
1777 : }
1778 :
1779 0 : switch (freq) {
1780 : case AR5K_INI_RFGAIN_2GHZ:
1781 : case AR5K_INI_RFGAIN_5GHZ:
1782 : break;
1783 : default:
1784 0 : return (AH_FALSE);
1785 : }
1786 :
1787 0 : for (i = 0; i < rfg_size; i++) {
1788 0 : AR5K_REG_WAIT(i);
1789 0 : AR5K_REG_WRITE((u_int32_t)rfg[i].rfg_register,
1790 : rfg[i].rfg_value[freq]);
1791 : }
1792 :
1793 0 : return (AH_TRUE);
1794 0 : }
1795 :
1796 : /*
1797 : * Common TX power setup
1798 : */
1799 : void
1800 0 : ar5k_txpower_table(struct ath_hal *hal, HAL_CHANNEL *channel, int16_t max_power)
1801 : {
1802 : u_int16_t txpower, *rates;
1803 : int i, min, max, n;
1804 :
1805 0 : rates = hal->ah_txpower.txp_rates;
1806 :
1807 : txpower = AR5K_TUNE_DEFAULT_TXPOWER * 2;
1808 0 : if (max_power > txpower) {
1809 : txpower = max_power > AR5K_TUNE_MAX_TXPOWER ?
1810 : AR5K_TUNE_MAX_TXPOWER : max_power;
1811 0 : }
1812 :
1813 0 : for (i = 0; i < AR5K_MAX_RATES; i++)
1814 0 : rates[i] = txpower;
1815 :
1816 : /* XXX setup target powers by rate */
1817 :
1818 0 : hal->ah_txpower.txp_min = rates[7];
1819 0 : hal->ah_txpower.txp_max = rates[0];
1820 0 : hal->ah_txpower.txp_ofdm = rates[0];
1821 :
1822 : /* Calculate the power table */
1823 : n = nitems(hal->ah_txpower.txp_pcdac);
1824 : min = AR5K_EEPROM_PCDAC_START;
1825 : max = AR5K_EEPROM_PCDAC_STOP;
1826 0 : for (i = 0; i < n; i += AR5K_EEPROM_PCDAC_STEP)
1827 0 : hal->ah_txpower.txp_pcdac[i] =
1828 : #ifdef notyet
1829 : min + ((i * (max - min)) / n);
1830 : #else
1831 : min;
1832 : #endif
1833 0 : }
1834 :
1835 : void
1836 0 : ar5k_write_ini(struct ath_hal *hal, const struct ar5k_ini *ini,
1837 : size_t n, HAL_BOOL change_channel)
1838 : {
1839 : u_int i;
1840 :
1841 0 : for (i = 0; i < n; i++) {
1842 0 : if (change_channel == AH_TRUE &&
1843 0 : ini[i].ini_register >= AR5K_PCU_MIN &&
1844 0 : ini[i].ini_register <= AR5K_PCU_MAX)
1845 : continue;
1846 0 : switch (ini[i].ini_mode) {
1847 : case AR5K_INI_READ:
1848 : /* cleared on read */
1849 0 : AR5K_REG_READ((u_int32_t)ini[i].ini_register);
1850 0 : break;
1851 : case AR5K_INI_WRITE:
1852 0 : AR5K_REG_WAIT(i);
1853 0 : AR5K_REG_WRITE((u_int32_t)ini[i].ini_register,
1854 : ini[i].ini_value);
1855 0 : break;
1856 : }
1857 : }
1858 0 : }
1859 :
1860 : void
1861 0 : ar5k_write_mode(struct ath_hal *hal, const struct ar5k_mode *ini,
1862 : size_t n, u_int mode)
1863 : {
1864 : u_int i;
1865 :
1866 0 : for (i = 0; i < n; i++) {
1867 0 : AR5K_REG_WAIT(i);
1868 0 : AR5K_REG_WRITE((u_int32_t)ini[i].mode_register,
1869 : ini[i].mode_value[mode]);
1870 : }
1871 0 : }
|