xref: /openbsd-src/sys/dev/ic/ar5212.c (revision d13be5d47e4149db2549a9828e244d59dbc43f15)
1 /*	$OpenBSD: ar5212.c,v 1.51 2009/06/02 12:39:02 reyk 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 the Atheros AR5001 Wireless LAN chipset
21  * (AR5212 + AR5111/AR5112).
22  */
23 
24 #include <dev/ic/ar5xxx.h>
25 #include <dev/ic/ar5212reg.h>
26 #include <dev/ic/ar5212var.h>
27 
28 HAL_BOOL	 ar5k_ar5212_nic_reset(struct ath_hal *, u_int32_t);
29 HAL_BOOL	 ar5k_ar5212_nic_wakeup(struct ath_hal *, u_int16_t);
30 u_int16_t	 ar5k_ar5212_radio_revision(struct ath_hal *, HAL_CHIP);
31 void		 ar5k_ar5212_fill(struct ath_hal *);
32 HAL_BOOL	 ar5k_ar5212_txpower(struct ath_hal *, HAL_CHANNEL *, u_int);
33 
34 /*
35  * Initial register setting for the AR5212
36  */
37 static const struct ar5k_ini ar5212_ini[] = AR5K_AR5212_INI;
38 static const struct ar5k_mode ar5212_mode[] = AR5K_AR5212_MODE;
39 static const struct ar5k_mode ar5212_ar5111_mode[] = AR5K_AR5212_AR5111_MODE;
40 static const struct ar5k_mode ar5212_ar5112_mode[] = AR5K_AR5212_AR5112_MODE;
41 static const struct ar5k_mode ar5413_mode[] = AR5K_AR5413_MODE;
42 static const struct ar5k_mode ar2413_mode[] = AR5K_AR2413_MODE;
43 static const struct ar5k_mode ar2425_mode[] = AR5K_AR2425_MODE;
44 static const struct ar5k_ini ar5111_bbgain[] = AR5K_AR5111_INI_BBGAIN;
45 static const struct ar5k_ini ar5112_bbgain[] = AR5K_AR5112_INI_BBGAIN;
46 static const struct ar5k_ini ar5212_pcie[] = AR5K_AR5212_PCIE;
47 
48 AR5K_HAL_FUNCTIONS(extern, ar5k_ar5212,);
49 
50 void
51 ar5k_ar5212_fill(struct ath_hal *hal)
52 {
53 	hal->ah_magic = AR5K_AR5212_MAGIC;
54 
55 	/*
56 	 * Init/Exit functions
57 	 */
58 	AR5K_HAL_FUNCTION(hal, ar5212, get_rate_table);
59 	AR5K_HAL_FUNCTION(hal, ar5212, detach);
60 
61 	/*
62 	 * Reset functions
63 	 */
64 	AR5K_HAL_FUNCTION(hal, ar5212, reset);
65 	AR5K_HAL_FUNCTION(hal, ar5212, set_opmode);
66 	AR5K_HAL_FUNCTION(hal, ar5212, calibrate);
67 
68 	/*
69 	 * TX functions
70 	 */
71 	AR5K_HAL_FUNCTION(hal, ar5212, update_tx_triglevel);
72 	AR5K_HAL_FUNCTION(hal, ar5212, setup_tx_queue);
73 	AR5K_HAL_FUNCTION(hal, ar5212, setup_tx_queueprops);
74 	AR5K_HAL_FUNCTION(hal, ar5212, release_tx_queue);
75 	AR5K_HAL_FUNCTION(hal, ar5212, reset_tx_queue);
76 	AR5K_HAL_FUNCTION(hal, ar5212, get_tx_buf);
77 	AR5K_HAL_FUNCTION(hal, ar5212, put_tx_buf);
78 	AR5K_HAL_FUNCTION(hal, ar5212, tx_start);
79 	AR5K_HAL_FUNCTION(hal, ar5212, stop_tx_dma);
80 	AR5K_HAL_FUNCTION(hal, ar5212, setup_tx_desc);
81 	AR5K_HAL_FUNCTION(hal, ar5212, setup_xtx_desc);
82 	AR5K_HAL_FUNCTION(hal, ar5212, fill_tx_desc);
83 	AR5K_HAL_FUNCTION(hal, ar5212, proc_tx_desc);
84 	AR5K_HAL_FUNCTION(hal, ar5212, has_veol);
85 
86 	/*
87 	 * RX functions
88 	 */
89 	AR5K_HAL_FUNCTION(hal, ar5212, get_rx_buf);
90 	AR5K_HAL_FUNCTION(hal, ar5212, put_rx_buf);
91 	AR5K_HAL_FUNCTION(hal, ar5212, start_rx);
92 	AR5K_HAL_FUNCTION(hal, ar5212, stop_rx_dma);
93 	AR5K_HAL_FUNCTION(hal, ar5212, start_rx_pcu);
94 	AR5K_HAL_FUNCTION(hal, ar5212, stop_pcu_recv);
95 	AR5K_HAL_FUNCTION(hal, ar5212, set_mcast_filter);
96 	AR5K_HAL_FUNCTION(hal, ar5212, set_mcast_filterindex);
97 	AR5K_HAL_FUNCTION(hal, ar5212, clear_mcast_filter_idx);
98 	AR5K_HAL_FUNCTION(hal, ar5212, get_rx_filter);
99 	AR5K_HAL_FUNCTION(hal, ar5212, set_rx_filter);
100 	AR5K_HAL_FUNCTION(hal, ar5212, setup_rx_desc);
101 	AR5K_HAL_FUNCTION(hal, ar5212, proc_rx_desc);
102 	AR5K_HAL_FUNCTION(hal, ar5212, set_rx_signal);
103 
104 	/*
105 	 * Misc functions
106 	 */
107 	AR5K_HAL_FUNCTION(hal, ar5212, dump_state);
108 	AR5K_HAL_FUNCTION(hal, ar5212, get_diag_state);
109 	AR5K_HAL_FUNCTION(hal, ar5212, get_lladdr);
110 	AR5K_HAL_FUNCTION(hal, ar5212, set_lladdr);
111 	AR5K_HAL_FUNCTION(hal, ar5212, set_regdomain);
112 	AR5K_HAL_FUNCTION(hal, ar5212, set_ledstate);
113 	AR5K_HAL_FUNCTION(hal, ar5212, set_associd);
114 	AR5K_HAL_FUNCTION(hal, ar5212, set_gpio_input);
115 	AR5K_HAL_FUNCTION(hal, ar5212, set_gpio_output);
116 	AR5K_HAL_FUNCTION(hal, ar5212, get_gpio);
117 	AR5K_HAL_FUNCTION(hal, ar5212, set_gpio);
118 	AR5K_HAL_FUNCTION(hal, ar5212, set_gpio_intr);
119 	AR5K_HAL_FUNCTION(hal, ar5212, get_tsf32);
120 	AR5K_HAL_FUNCTION(hal, ar5212, get_tsf64);
121 	AR5K_HAL_FUNCTION(hal, ar5212, reset_tsf);
122 	AR5K_HAL_FUNCTION(hal, ar5212, get_regdomain);
123 	AR5K_HAL_FUNCTION(hal, ar5212, detect_card_present);
124 	AR5K_HAL_FUNCTION(hal, ar5212, update_mib_counters);
125 	AR5K_HAL_FUNCTION(hal, ar5212, get_rf_gain);
126 	AR5K_HAL_FUNCTION(hal, ar5212, set_slot_time);
127 	AR5K_HAL_FUNCTION(hal, ar5212, get_slot_time);
128 	AR5K_HAL_FUNCTION(hal, ar5212, set_ack_timeout);
129 	AR5K_HAL_FUNCTION(hal, ar5212, get_ack_timeout);
130 	AR5K_HAL_FUNCTION(hal, ar5212, set_cts_timeout);
131 	AR5K_HAL_FUNCTION(hal, ar5212, get_cts_timeout);
132 
133 	/*
134 	 * Key table (WEP) functions
135 	 */
136 	AR5K_HAL_FUNCTION(hal, ar5212, is_cipher_supported);
137 	AR5K_HAL_FUNCTION(hal, ar5212, get_keycache_size);
138 	AR5K_HAL_FUNCTION(hal, ar5212, reset_key);
139 	AR5K_HAL_FUNCTION(hal, ar5212, is_key_valid);
140 	AR5K_HAL_FUNCTION(hal, ar5212, set_key);
141 	AR5K_HAL_FUNCTION(hal, ar5212, set_key_lladdr);
142 	AR5K_HAL_FUNCTION(hal, ar5212, softcrypto);
143 
144 	/*
145 	 * Power management functions
146 	 */
147 	AR5K_HAL_FUNCTION(hal, ar5212, set_power);
148 	AR5K_HAL_FUNCTION(hal, ar5212, get_power_mode);
149 	AR5K_HAL_FUNCTION(hal, ar5212, query_pspoll_support);
150 	AR5K_HAL_FUNCTION(hal, ar5212, init_pspoll);
151 	AR5K_HAL_FUNCTION(hal, ar5212, enable_pspoll);
152 	AR5K_HAL_FUNCTION(hal, ar5212, disable_pspoll);
153 
154 	/*
155 	 * Beacon functions
156 	 */
157 	AR5K_HAL_FUNCTION(hal, ar5212, init_beacon);
158 	AR5K_HAL_FUNCTION(hal, ar5212, set_beacon_timers);
159 	AR5K_HAL_FUNCTION(hal, ar5212, reset_beacon);
160 	AR5K_HAL_FUNCTION(hal, ar5212, wait_for_beacon);
161 
162 	/*
163 	 * Interrupt functions
164 	 */
165 	AR5K_HAL_FUNCTION(hal, ar5212, is_intr_pending);
166 	AR5K_HAL_FUNCTION(hal, ar5212, get_isr);
167 	AR5K_HAL_FUNCTION(hal, ar5212, get_intr);
168 	AR5K_HAL_FUNCTION(hal, ar5212, set_intr);
169 
170 	/*
171 	 * Chipset functions (ar5k-specific, non-HAL)
172 	 */
173 	AR5K_HAL_FUNCTION(hal, ar5212, get_capabilities);
174 	AR5K_HAL_FUNCTION(hal, ar5212, radar_alert);
175 
176 	/*
177 	 * EEPROM access
178 	 */
179 	AR5K_HAL_FUNCTION(hal, ar5212, eeprom_is_busy);
180 	AR5K_HAL_FUNCTION(hal, ar5212, eeprom_read);
181 	AR5K_HAL_FUNCTION(hal, ar5212, eeprom_write);
182 
183 	/*
184 	 * Unused functions or functions not implemented
185 	 */
186 	AR5K_HAL_FUNCTION(hal, ar5212, set_bssid_mask);
187 	AR5K_HAL_FUNCTION(hal, ar5212, get_tx_queueprops);
188 	AR5K_HAL_FUNCTION(hal, ar5212, num_tx_pending);
189 	AR5K_HAL_FUNCTION(hal, ar5212, phy_disable);
190 	AR5K_HAL_FUNCTION(hal, ar5212, set_txpower_limit);
191 	AR5K_HAL_FUNCTION(hal, ar5212, set_def_antenna);
192 	AR5K_HAL_FUNCTION(hal, ar5212, get_def_antenna);
193 #ifdef notyet
194 	AR5K_HAL_FUNCTION(hal, ar5212, set_capability);
195 	AR5K_HAL_FUNCTION(hal, ar5212, proc_mib_event);
196 	AR5K_HAL_FUNCTION(hal, ar5212, get_tx_inter_queue);
197 #endif
198 }
199 
200 struct ath_hal *
201 ar5k_ar5212_attach(u_int16_t device, void *sc, bus_space_tag_t st,
202     bus_space_handle_t sh, int *status)
203 {
204 	struct ath_hal *hal = (struct ath_hal*) sc;
205 	u_int8_t mac[IEEE80211_ADDR_LEN];
206 	u_int32_t srev;
207 
208 	ar5k_ar5212_fill(hal);
209 
210 	/* Bring device out of sleep and reset its units */
211 	if (ar5k_ar5212_nic_wakeup(hal, AR5K_INIT_MODE) != AH_TRUE)
212 		return (NULL);
213 
214 	/* Get MAC, PHY and RADIO revisions */
215 	srev = AR5K_REG_READ(AR5K_AR5212_SREV);
216 	hal->ah_mac_srev = srev;
217 	hal->ah_mac_version = AR5K_REG_MS(srev, AR5K_AR5212_SREV_VER);
218 	hal->ah_mac_revision = AR5K_REG_MS(srev, AR5K_AR5212_SREV_REV);
219 	hal->ah_phy_revision = AR5K_REG_READ(AR5K_AR5212_PHY_CHIP_ID) &
220 	    0x00ffffffff;
221 	hal->ah_radio_5ghz_revision =
222 	    ar5k_ar5212_radio_revision(hal, HAL_CHIP_5GHZ);
223 	hal->ah_radio_2ghz_revision =
224 	    ar5k_ar5212_radio_revision(hal, HAL_CHIP_2GHZ);
225 
226 	/* Single chip radio */
227 	if (hal->ah_radio_2ghz_revision == hal->ah_radio_5ghz_revision)
228 		hal->ah_radio_2ghz_revision = 0;
229 
230 	/* Identify the chipset (this has to be done in an early step) */
231 	hal->ah_version = AR5K_AR5212;
232 	if (device == AR5K_VERSION_DEV) {
233 		hal->ah_radio = AR5K_AR5413;
234 		hal->ah_phy_spending = AR5K_AR5212_PHY_SPENDING_AR5424;
235 		hal->ah_radio_5ghz_revision = hal->ah_radio_2ghz_revision =
236 		    AR5K_SREV_VER_AR5413;
237 	} else if (srev == AR5K_SREV_VER_AR2425) {
238 		hal->ah_radio = AR5K_AR2425;
239 		hal->ah_phy_spending = AR5K_AR5212_PHY_SPENDING_AR5112;
240 	} else if (hal->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112) {
241 		hal->ah_radio = AR5K_AR5111;
242 		hal->ah_phy_spending = AR5K_AR5212_PHY_SPENDING_AR5111;
243 	} else if (hal->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC0) {
244 		hal->ah_radio = AR5K_AR5112;
245 		if (hal->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112A)
246 			hal->ah_phy_spending = AR5K_AR5212_PHY_SPENDING_AR5112;
247 		else
248 			hal->ah_phy_spending = AR5K_AR5212_PHY_SPENDING_AR5112A;
249 	} else if (hal->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC1) {
250 		hal->ah_radio = AR5K_AR2413;
251 		hal->ah_phy_spending = AR5K_AR5212_PHY_SPENDING_AR5112A;
252 	} else if (hal->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC2) {
253 		hal->ah_radio = AR5K_AR5413;
254 		hal->ah_phy_spending = AR5K_AR5212_PHY_SPENDING_AR5112A;
255 	} else if (hal->ah_radio_5ghz_revision < AR5K_SREV_RAD_5133 &&
256 	    srev < AR5K_SREV_VER_AR5424) {
257 		hal->ah_radio = AR5K_AR2413;
258 		hal->ah_phy_spending = AR5K_AR5212_PHY_SPENDING_AR5112A;
259 	} else if (hal->ah_radio_5ghz_revision < AR5K_SREV_RAD_5133) {
260 		hal->ah_radio = AR5K_AR5413;
261 		hal->ah_phy_spending = AR5K_AR5212_PHY_SPENDING_AR5424;
262 	}
263 	hal->ah_phy = AR5K_AR5212_PHY(0);
264 
265 	if (hal->ah_pci_express == AH_TRUE) {
266 		/* PCI-Express based devices need some extra initialization */
267 		ar5k_write_ini(hal, ar5212_pcie, nitems(ar5212_pcie), 0);
268 	}
269 
270 	bcopy(etherbroadcastaddr, mac, IEEE80211_ADDR_LEN);
271 	ar5k_ar5212_set_associd(hal, mac, 0, 0);
272 	ar5k_ar5212_get_lladdr(hal, mac);
273 	ar5k_ar5212_set_opmode(hal);
274 
275 	return (hal);
276 }
277 
278 HAL_BOOL
279 ar5k_ar5212_nic_reset(struct ath_hal *hal, u_int32_t val)
280 {
281 	HAL_BOOL ret = AH_FALSE;
282 	u_int32_t mask = val ? val : ~0;
283 
284 	/* Read-and-clear */
285 	AR5K_REG_READ(AR5K_AR5212_RXDP);
286 
287 	/*
288 	 * Reset the device and wait until success
289 	 */
290 	AR5K_REG_WRITE(AR5K_AR5212_RC, val);
291 
292 	/* Wait at least 128 PCI clocks */
293 	AR5K_DELAY(15);
294 
295 	val &=
296 	    AR5K_AR5212_RC_PCU | AR5K_AR5212_RC_BB;
297 
298 	mask &=
299 	    AR5K_AR5212_RC_PCU | AR5K_AR5212_RC_BB;
300 
301 	ret = ar5k_register_timeout(hal, AR5K_AR5212_RC, mask, val, AH_FALSE);
302 
303 	/*
304 	 * Reset configuration register
305 	 */
306 	if ((val & AR5K_AR5212_RC_PCU) == 0)
307 		AR5K_REG_WRITE(AR5K_AR5212_CFG, AR5K_AR5212_INIT_CFG);
308 
309 	return (ret);
310 }
311 
312 HAL_BOOL
313 ar5k_ar5212_nic_wakeup(struct ath_hal *hal, u_int16_t flags)
314 {
315 	u_int32_t turbo, mode, clock;
316 
317 	turbo = 0;
318 	mode = 0;
319 	clock = 0;
320 
321 	/*
322 	 * Get channel mode flags
323 	 */
324 
325 	if (hal->ah_radio >= AR5K_AR5112) {
326 		mode = AR5K_AR5212_PHY_MODE_RAD_AR5112;
327 		clock = AR5K_AR5212_PHY_PLL_AR5112;
328 	} else {
329 		mode = AR5K_AR5212_PHY_MODE_RAD_AR5111;
330 		clock = AR5K_AR5212_PHY_PLL_AR5111;
331 	}
332 
333 	if (flags & IEEE80211_CHAN_2GHZ) {
334 		mode |= AR5K_AR5212_PHY_MODE_FREQ_2GHZ;
335 		clock |= AR5K_AR5212_PHY_PLL_44MHZ;
336 	} else if (flags & IEEE80211_CHAN_5GHZ) {
337 		mode |= AR5K_AR5212_PHY_MODE_FREQ_5GHZ;
338 		clock |= AR5K_AR5212_PHY_PLL_40MHZ;
339 	} else {
340 		AR5K_PRINT("invalid radio frequency mode\n");
341 		return (AH_FALSE);
342 	}
343 
344 	if (flags & IEEE80211_CHAN_CCK) {
345 		mode |= AR5K_AR5212_PHY_MODE_MOD_CCK;
346 	} else if (flags & IEEE80211_CHAN_OFDM) {
347 		mode |= AR5K_AR5212_PHY_MODE_MOD_OFDM;
348 	} else if (flags & IEEE80211_CHAN_DYN) {
349 		mode |= AR5K_AR5212_PHY_MODE_MOD_DYN;
350 	} else {
351 		AR5K_PRINT("invalid radio frequency mode\n");
352 		return (AH_FALSE);
353 	}
354 
355 	if (flags & IEEE80211_CHAN_TURBO) {
356 		turbo = AR5K_AR5212_PHY_TURBO_MODE |
357 		    AR5K_AR5212_PHY_TURBO_SHORT;
358 	}
359 
360 	/*
361 	 * Reset and wakeup the device
362 	 */
363 
364 	/* ...reset chipset and PCI device (if not PCI-E) */
365 	if (hal->ah_pci_express == AH_FALSE &&
366 	    ar5k_ar5212_nic_reset(hal, AR5K_AR5212_RC_CHIP) == AH_FALSE) {
367 		AR5K_PRINT("failed to reset the AR5212 + PCI chipset\n");
368 		return (AH_FALSE);
369 	}
370 
371 	/* ...wakeup */
372 	if (ar5k_ar5212_set_power(hal,
373 		HAL_PM_AWAKE, AH_TRUE, 0) == AH_FALSE) {
374 		AR5K_PRINT("failed to resume the AR5212 (again)\n");
375 		return (AH_FALSE);
376 	}
377 
378 	/* ...final warm reset */
379 	if (ar5k_ar5212_nic_reset(hal, 0) == AH_FALSE) {
380 		AR5K_PRINT("failed to warm reset the AR5212\n");
381 		return (AH_FALSE);
382 	}
383 
384 	/* ...set the PHY operating mode */
385 	AR5K_REG_WRITE(AR5K_AR5212_PHY_PLL, clock);
386 	AR5K_DELAY(300);
387 
388 	AR5K_REG_WRITE(AR5K_AR5212_PHY_MODE, mode);
389 	AR5K_REG_WRITE(AR5K_AR5212_PHY_TURBO, turbo);
390 
391 	return (AH_TRUE);
392 }
393 
394 u_int16_t
395 ar5k_ar5212_radio_revision(struct ath_hal *hal, HAL_CHIP chip)
396 {
397 	int i;
398 	u_int32_t srev;
399 	u_int16_t ret;
400 
401 	/*
402 	 * Set the radio chip access register
403 	 */
404 	switch (chip) {
405 	case HAL_CHIP_2GHZ:
406 		AR5K_REG_WRITE(AR5K_AR5212_PHY(0), AR5K_AR5212_PHY_SHIFT_2GHZ);
407 		break;
408 	case HAL_CHIP_5GHZ:
409 		AR5K_REG_WRITE(AR5K_AR5212_PHY(0), AR5K_AR5212_PHY_SHIFT_5GHZ);
410 		break;
411 	default:
412 		return (0);
413 	}
414 
415 	AR5K_DELAY(2000);
416 
417 	/* ...wait until PHY is ready and read the selected radio revision */
418 	AR5K_REG_WRITE(AR5K_AR5212_PHY(0x34), 0x00001c16);
419 
420 	for (i = 0; i < 8; i++)
421 		AR5K_REG_WRITE(AR5K_AR5212_PHY(0x20), 0x00010000);
422 	srev = (AR5K_REG_READ(AR5K_AR5212_PHY(0x100)) >> 24) & 0xff;
423 
424 	ret = ar5k_bitswap(((srev & 0xf0) >> 4) | ((srev & 0x0f) << 4), 8);
425 
426 	/* Reset to the 5GHz mode */
427 	AR5K_REG_WRITE(AR5K_AR5212_PHY(0), AR5K_AR5212_PHY_SHIFT_5GHZ);
428 
429 	return (ret);
430 }
431 
432 const HAL_RATE_TABLE *
433 ar5k_ar5212_get_rate_table(struct ath_hal *hal, u_int mode)
434 {
435 	switch (mode) {
436 	case HAL_MODE_11A:
437 		return (&hal->ah_rt_11a);
438 	case HAL_MODE_TURBO:
439 		return (&hal->ah_rt_turbo);
440 	case HAL_MODE_11B:
441 		return (&hal->ah_rt_11b);
442 	case HAL_MODE_11G:
443 	case HAL_MODE_PUREG:
444 		return (&hal->ah_rt_11g);
445 	case HAL_MODE_XR:
446 		return (&hal->ah_rt_xr);
447 	default:
448 		return (NULL);
449 	}
450 
451 	return (NULL);
452 }
453 
454 void
455 ar5k_ar5212_detach(struct ath_hal *hal)
456 {
457 	if (hal->ah_rf_banks != NULL)
458 		free(hal->ah_rf_banks, M_DEVBUF);
459 
460 	/*
461 	 * Free HAL structure, assume interrupts are down
462 	 */
463 	free(hal, M_DEVBUF);
464 }
465 
466 HAL_BOOL
467 ar5k_ar5212_phy_disable(struct ath_hal *hal)
468 {
469 	AR5K_REG_WRITE(AR5K_AR5212_PHY_ACTIVE, AR5K_AR5212_PHY_DISABLE);
470 	return (AH_TRUE);
471 }
472 
473 HAL_BOOL
474 ar5k_ar5212_reset(struct ath_hal *hal, HAL_OPMODE op_mode, HAL_CHANNEL *channel,
475     HAL_BOOL chanchange, HAL_STATUS *status)
476 {
477 	struct ar5k_eeprom_info *ee = &hal->ah_capabilities.cap_eeprom;
478 	u_int8_t mac[IEEE80211_ADDR_LEN];
479 	u_int32_t data, s_seq, s_ant, s_led[3], dmasize;
480 	u_int i, mode, freq, ee_mode, ant[2];
481 	const HAL_RATE_TABLE *rt;
482 
483 	/*
484 	 * Save some registers before a reset
485 	 */
486 	if (chanchange == AH_TRUE) {
487 		s_seq = AR5K_REG_READ(AR5K_AR5212_DCU_SEQNUM(0));
488 		s_ant = AR5K_REG_READ(AR5K_AR5212_DEFAULT_ANTENNA);
489 	} else {
490 		s_seq = 0;
491 		s_ant = 1;
492 	}
493 
494 	s_led[0] = AR5K_REG_READ(AR5K_AR5212_PCICFG) &
495 	    AR5K_AR5212_PCICFG_LEDSTATE;
496 	s_led[1] = AR5K_REG_READ(AR5K_AR5212_GPIOCR);
497 	s_led[2] = AR5K_REG_READ(AR5K_AR5212_GPIODO);
498 
499 	if (chanchange == AH_TRUE && hal->ah_rf_banks != NULL)
500 		ar5k_ar5212_get_rf_gain(hal);
501 
502 	if (ar5k_ar5212_nic_wakeup(hal, channel->c_channel_flags) == AH_FALSE)
503 		return (AH_FALSE);
504 
505 	/*
506 	 * Initialize operating mode
507 	 */
508 	hal->ah_op_mode = op_mode;
509 
510 	switch (channel->c_channel_flags & CHANNEL_MODES) {
511 	case CHANNEL_A:
512 		mode = AR5K_INI_VAL_11A;
513 		freq = AR5K_INI_RFGAIN_5GHZ;
514 		ee_mode = AR5K_EEPROM_MODE_11A;
515 		break;
516 	case CHANNEL_B:
517 		mode = AR5K_INI_VAL_11B;
518 		freq = AR5K_INI_RFGAIN_2GHZ;
519 		ee_mode = AR5K_EEPROM_MODE_11B;
520 		break;
521 	case CHANNEL_G:
522 	case CHANNEL_PUREG:
523 		mode = AR5K_INI_VAL_11G;
524 		freq = AR5K_INI_RFGAIN_2GHZ;
525 		ee_mode = AR5K_EEPROM_MODE_11G;
526 		break;
527 	case CHANNEL_T:
528 		mode = AR5K_INI_VAL_11A_TURBO;
529 		freq = AR5K_INI_RFGAIN_5GHZ;
530 		ee_mode = AR5K_EEPROM_MODE_11A;
531 		break;
532 	case CHANNEL_TG:
533 		mode = AR5K_INI_VAL_11G_TURBO;
534 		freq = AR5K_INI_RFGAIN_2GHZ;
535 		ee_mode = AR5K_EEPROM_MODE_11G;
536 		break;
537 	case CHANNEL_XR:
538 		mode = AR5K_INI_VAL_XR;
539 		freq = AR5K_INI_RFGAIN_5GHZ;
540 		ee_mode = AR5K_EEPROM_MODE_11A;
541 		break;
542 	default:
543 		AR5K_PRINTF("invalid channel: %d\n", channel->c_channel);
544 		return (AH_FALSE);
545 	}
546 
547 	/* PHY access enable */
548 	AR5K_REG_WRITE(AR5K_AR5212_PHY(0), AR5K_AR5212_PHY_SHIFT_5GHZ);
549 
550 	/*
551 	 * Write initial mode and register settings
552 	 */
553 	ar5k_write_mode(hal, ar5212_mode, nitems(ar5212_mode), mode);
554 	ar5k_write_ini(hal, ar5212_ini, nitems(ar5212_ini), chanchange);
555 
556 	switch (hal->ah_radio) {
557 	case AR5K_AR5111:
558 		ar5k_write_mode(hal, ar5212_ar5111_mode,
559 		    nitems(ar5212_ar5111_mode), mode);
560 		break;
561 	case AR5K_AR5112:
562 		ar5k_write_mode(hal, ar5212_ar5112_mode,
563 		    nitems(ar5212_ar5112_mode), mode);
564 		break;
565 	case AR5K_AR5413:
566 		ar5k_write_mode(hal, ar5413_mode,
567 		    nitems(ar5413_mode), mode);
568 		break;
569 	case AR5K_AR2413:
570 		AR5K_REG_WRITE(AR5K_AR5212_PHY(648), 0x018830c6);
571 		ar5k_write_mode(hal, ar2413_mode,
572 		    nitems(ar2413_mode), mode);
573 		break;
574 	case AR5K_AR2425:
575 		AR5K_REG_WRITE(AR5K_AR5212_PHY(648), 0x018830c6);
576 		if (mode == AR5K_INI_VAL_11B)
577 			mode = AR5K_INI_VAL_11G;
578 		ar5k_write_mode(hal, ar2425_mode,
579 		    nitems(ar2425_mode), mode);
580 		break;
581 	default:
582 		AR5K_PRINTF("invalid radio: %d\n", hal->ah_radio);
583 		return (AH_FALSE);
584 	}
585 
586 	if (hal->ah_radio == AR5K_AR5111)
587 		ar5k_write_ini(hal, ar5111_bbgain,
588 		    nitems(ar5111_bbgain), chanchange);
589 	else
590 		ar5k_write_ini(hal, ar5112_bbgain,
591 		    nitems(ar5112_bbgain), chanchange);
592 
593 	/*
594 	 * Write initial RF gain settings
595 	 */
596 	if (ar5k_rfgain(hal, freq) == AH_FALSE)
597 		return (AH_FALSE);
598 
599 	AR5K_DELAY(1000);
600 
601 	/*
602 	 * Set rate duration table
603 	 */
604 	rt = ar5k_ar5212_get_rate_table(hal,
605 	    channel->c_channel_flags & IEEE80211_CHAN_TURBO ?
606 	    HAL_MODE_TURBO : HAL_MODE_XR);
607 
608 	for (i = 0; i < rt->rt_rate_count; i++) {
609 		AR5K_REG_WRITE(AR5K_AR5212_RATE_DUR(rt->rt_info[i].r_rate_code),
610 		    ath_hal_computetxtime(hal, rt, 14,
611 		    rt->rt_info[i].r_control_rate, AH_FALSE));
612 	}
613 
614 	if ((channel->c_channel_flags & IEEE80211_CHAN_TURBO) == 0) {
615 		rt = ar5k_ar5212_get_rate_table(hal, HAL_MODE_11B);
616 		for (i = 0; i < rt->rt_rate_count; i++) {
617 			data = AR5K_AR5212_RATE_DUR(rt->rt_info[i].r_rate_code);
618 			AR5K_REG_WRITE(data,
619 			    ath_hal_computetxtime(hal, rt, 14,
620 			    rt->rt_info[i].r_control_rate, AH_FALSE));
621 			if (rt->rt_info[i].r_short_preamble) {
622 				AR5K_REG_WRITE(data +
623 				    (rt->rt_info[i].r_short_preamble << 2),
624 				    ath_hal_computetxtime(hal, rt, 14,
625 				    rt->rt_info[i].r_control_rate, AH_FALSE));
626 			}
627 		}
628 	}
629 
630 	/* Fix for first revision of the AR5112 RF chipset */
631 	if (hal->ah_radio >= AR5K_AR5112 &&
632 	    hal->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112A) {
633 		AR5K_REG_WRITE(AR5K_AR5212_PHY_CCKTXCTL,
634 		    AR5K_AR5212_PHY_CCKTXCTL_WORLD);
635 		if (channel->c_channel_flags & IEEE80211_CHAN_OFDM)
636 			data = 0xffb81020;
637 		else
638 			data = 0xffb80d20;
639 		AR5K_REG_WRITE(AR5K_AR5212_PHY_FC, data);
640 	}
641 
642 	/*
643 	 * Set TX power (XXX use txpower from net80211)
644 	 */
645 	if (ar5k_ar5212_txpower(hal, channel,
646 		AR5K_TUNE_DEFAULT_TXPOWER) == AH_FALSE)
647 		return (AH_FALSE);
648 
649 	/*
650 	 * Write RF registers
651 	 */
652 	if (ar5k_rfregs(hal, channel, mode) == AH_FALSE)
653 		return (AH_FALSE);
654 
655 	/*
656 	 * Configure additional registers
657 	 */
658 
659 	/* OFDM timings */
660 	if (channel->c_channel_flags & IEEE80211_CHAN_OFDM) {
661 		u_int32_t coef_scaled, coef_exp, coef_man, ds_coef_exp,
662 		    ds_coef_man, clock;
663 
664 		clock = channel->c_channel_flags & IEEE80211_CHAN_T ? 80 : 40;
665 		coef_scaled = ((5 * (clock << 24)) / 2) / channel->c_channel;
666 
667 		for (coef_exp = 31; coef_exp > 0; coef_exp--)
668 			if ((coef_scaled >> coef_exp) & 0x1)
669 				break;
670 
671 		if (!coef_exp)
672 			return (AH_FALSE);
673 
674 		coef_exp = 14 - (coef_exp - 24);
675 		coef_man = coef_scaled + (1 << (24 - coef_exp - 1));
676 		ds_coef_man = coef_man >> (24 - coef_exp);
677 		ds_coef_exp = coef_exp - 16;
678 
679 		AR5K_REG_WRITE_BITS(AR5K_AR5212_PHY_TIMING_3,
680 		    AR5K_AR5212_PHY_TIMING_3_DSC_MAN, ds_coef_man);
681 		AR5K_REG_WRITE_BITS(AR5K_AR5212_PHY_TIMING_3,
682 		    AR5K_AR5212_PHY_TIMING_3_DSC_EXP, ds_coef_exp);
683 	}
684 
685 	if (hal->ah_radio == AR5K_AR5111) {
686 		if (channel->c_channel_flags & IEEE80211_CHAN_B)
687 			AR5K_REG_ENABLE_BITS(AR5K_AR5212_TXCFG,
688 			    AR5K_AR5212_TXCFG_B_MODE);
689 		else
690 			AR5K_REG_DISABLE_BITS(AR5K_AR5212_TXCFG,
691 			    AR5K_AR5212_TXCFG_B_MODE);
692 	}
693 
694 	/* Set antenna mode */
695 	AR5K_REG_MASKED_BITS(AR5K_AR5212_PHY(0x44),
696 	    hal->ah_antenna[ee_mode][0], 0xfffffc06);
697 
698 	if (freq == AR5K_INI_RFGAIN_2GHZ)
699 		ant[0] = ant[1] = HAL_ANT_FIXED_B;
700 	else
701 		ant[0] = ant[1] = HAL_ANT_FIXED_A;
702 
703 	AR5K_REG_WRITE(AR5K_AR5212_PHY_ANT_SWITCH_TABLE_0,
704 	    hal->ah_antenna[ee_mode][ant[0]]);
705 	AR5K_REG_WRITE(AR5K_AR5212_PHY_ANT_SWITCH_TABLE_1,
706 	    hal->ah_antenna[ee_mode][ant[1]]);
707 
708 	/* Commit values from EEPROM */
709 	if (hal->ah_radio == AR5K_AR5111)
710 		AR5K_REG_WRITE_BITS(AR5K_AR5212_PHY_FC,
711 		    AR5K_AR5212_PHY_FC_TX_CLIP, ee->ee_tx_clip);
712 
713 	AR5K_REG_WRITE(AR5K_AR5212_PHY(0x5a),
714 	    AR5K_AR5212_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]));
715 
716 	AR5K_REG_MASKED_BITS(AR5K_AR5212_PHY(0x11),
717 	    (ee->ee_switch_settling[ee_mode] << 7) & 0x3f80, 0xffffc07f);
718 	AR5K_REG_MASKED_BITS(AR5K_AR5212_PHY(0x12),
719 	    (ee->ee_ant_tx_rx[ee_mode] << 12) & 0x3f000, 0xfffc0fff);
720 	AR5K_REG_MASKED_BITS(AR5K_AR5212_PHY(0x14),
721 	    (ee->ee_adc_desired_size[ee_mode] & 0x00ff) |
722 	    ((ee->ee_pga_desired_size[ee_mode] << 8) & 0xff00), 0xffff0000);
723 
724 	AR5K_REG_WRITE(AR5K_AR5212_PHY(0x0d),
725 	    (ee->ee_tx_end2xpa_disable[ee_mode] << 24) |
726 	    (ee->ee_tx_end2xpa_disable[ee_mode] << 16) |
727 	    (ee->ee_tx_frm2xpa_enable[ee_mode] << 8) |
728 	    (ee->ee_tx_frm2xpa_enable[ee_mode]));
729 
730 	AR5K_REG_MASKED_BITS(AR5K_AR5212_PHY(0x0a),
731 	    ee->ee_tx_end2xlna_enable[ee_mode] << 8, 0xffff00ff);
732 	AR5K_REG_MASKED_BITS(AR5K_AR5212_PHY(0x19),
733 	    (ee->ee_thr_62[ee_mode] << 12) & 0x7f000, 0xfff80fff);
734 	AR5K_REG_MASKED_BITS(AR5K_AR5212_PHY(0x49), 4, 0xffffff01);
735 
736 	AR5K_REG_ENABLE_BITS(AR5K_AR5212_PHY_IQ,
737 	    AR5K_AR5212_PHY_IQ_CORR_ENABLE |
738 	    (ee->ee_i_cal[ee_mode] << AR5K_AR5212_PHY_IQ_CORR_Q_I_COFF_S) |
739 	    ee->ee_q_cal[ee_mode]);
740 
741 	if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) {
742 		AR5K_REG_WRITE_BITS(AR5K_AR5212_PHY_GAIN_2GHZ,
743 		    AR5K_AR5212_PHY_GAIN_2GHZ_MARGIN_TXRX,
744 		    ee->ee_margin_tx_rx[ee_mode]);
745 	}
746 
747 	/*
748 	 * Restore saved values
749 	 */
750 	AR5K_REG_WRITE(AR5K_AR5212_DCU_SEQNUM(0), s_seq);
751 	AR5K_REG_WRITE(AR5K_AR5212_DEFAULT_ANTENNA, s_ant);
752 	AR5K_REG_ENABLE_BITS(AR5K_AR5212_PCICFG, s_led[0]);
753 	AR5K_REG_WRITE(AR5K_AR5212_GPIOCR, s_led[1]);
754 	AR5K_REG_WRITE(AR5K_AR5212_GPIODO, s_led[2]);
755 
756 	/*
757 	 * Misc
758 	 */
759 	bcopy(etherbroadcastaddr, mac, IEEE80211_ADDR_LEN);
760 	ar5k_ar5212_set_associd(hal, mac, 0, 0);
761 	ar5k_ar5212_set_opmode(hal);
762 	AR5K_REG_WRITE(AR5K_AR5212_PISR, 0xffffffff);
763 	AR5K_REG_WRITE(AR5K_AR5212_RSSI_THR, AR5K_TUNE_RSSI_THRES);
764 
765 	/*
766 	 * Set Rx/Tx DMA Configuration
767 	 *
768 	 * XXX Limit DMA size on PCI-E chipsets to 128 bytes because
769 	 * XXX we saw RX overruns and TX errors with higher values.
770 	 */
771 	dmasize = hal->ah_pci_express == AH_TRUE ?
772 	    AR5K_AR5212_DMASIZE_128B : AR5K_AR5212_DMASIZE_512B;
773 	AR5K_REG_WRITE_BITS(AR5K_AR5212_TXCFG, AR5K_AR5212_TXCFG_SDMAMR,
774 	    dmasize | AR5K_AR5212_TXCFG_DMASIZE);
775 	AR5K_REG_WRITE_BITS(AR5K_AR5212_RXCFG, AR5K_AR5212_RXCFG_SDMAMW,
776 	    dmasize);
777 
778 	/*
779 	 * Set channel and calibrate the PHY
780 	 */
781 	if (ar5k_channel(hal, channel) == AH_FALSE)
782 		return (AH_FALSE);
783 
784 	/*
785 	 * Enable the PHY and wait until completion
786 	 */
787 	AR5K_REG_WRITE(AR5K_AR5212_PHY_ACTIVE, AR5K_AR5212_PHY_ENABLE);
788 
789 	data = AR5K_REG_READ(AR5K_AR5212_PHY_RX_DELAY) &
790 	    AR5K_AR5212_PHY_RX_DELAY_M;
791 	data = (channel->c_channel_flags & IEEE80211_CHAN_CCK) ?
792 	    ((data << 2) / 22) : (data / 10);
793 
794 	AR5K_DELAY(100 + data);
795 
796 	/*
797 	 * Start calibration
798 	 */
799 	AR5K_REG_ENABLE_BITS(AR5K_AR5212_PHY_AGCCTL,
800 	    AR5K_AR5212_PHY_AGCCTL_NF |
801 	    AR5K_AR5212_PHY_AGCCTL_CAL);
802 
803 	hal->ah_calibration = AH_FALSE;
804 	if ((channel->c_channel_flags & IEEE80211_CHAN_B) == 0) {
805 		hal->ah_calibration = AH_TRUE;
806 		AR5K_REG_WRITE_BITS(AR5K_AR5212_PHY_IQ,
807 		    AR5K_AR5212_PHY_IQ_CAL_NUM_LOG_MAX, 15);
808 		AR5K_REG_ENABLE_BITS(AR5K_AR5212_PHY_IQ,
809 		    AR5K_AR5212_PHY_IQ_RUN);
810 	}
811 
812 	/*
813 	 * Reset queues and start beacon timers at the end of the reset routine
814 	 */
815 	for (i = 0; i < hal->ah_capabilities.cap_queues.q_tx_num; i++) {
816 		AR5K_REG_WRITE_Q(AR5K_AR5212_DCU_QCUMASK(i), i);
817 		if (ar5k_ar5212_reset_tx_queue(hal, i) == AH_FALSE) {
818 			AR5K_PRINTF("failed to reset TX queue #%d\n", i);
819 			return (AH_FALSE);
820 		}
821 	}
822 
823 	/* Pre-enable interrupts */
824 	ar5k_ar5212_set_intr(hal, HAL_INT_RX | HAL_INT_TX | HAL_INT_FATAL);
825 
826 	/*
827 	 * Set RF kill flags if supported by the device (read from the EEPROM)
828 	 */
829 	if (AR5K_EEPROM_HDR_RFKILL(hal->ah_capabilities.cap_eeprom.ee_header)) {
830 		ar5k_ar5212_set_gpio_input(hal, 0);
831 		if ((hal->ah_gpio[0] = ar5k_ar5212_get_gpio(hal, 0)) == 0)
832 			ar5k_ar5212_set_gpio_intr(hal, 0, 1);
833 		else
834 			ar5k_ar5212_set_gpio_intr(hal, 0, 0);
835 	}
836 
837 	/*
838 	 * Set the 32MHz reference clock
839 	 */
840 	AR5K_REG_WRITE(AR5K_AR5212_PHY_SCR, AR5K_AR5212_PHY_SCR_32MHZ);
841 	AR5K_REG_WRITE(AR5K_AR5212_PHY_SLMT, AR5K_AR5212_PHY_SLMT_32MHZ);
842 	AR5K_REG_WRITE(AR5K_AR5212_PHY_SCAL, AR5K_AR5212_PHY_SCAL_32MHZ);
843 	AR5K_REG_WRITE(AR5K_AR5212_PHY_SCLOCK, AR5K_AR5212_PHY_SCLOCK_32MHZ);
844 	AR5K_REG_WRITE(AR5K_AR5212_PHY_SDELAY, AR5K_AR5212_PHY_SDELAY_32MHZ);
845 	AR5K_REG_WRITE(AR5K_AR5212_PHY_SPENDING, hal->ah_phy_spending);
846 
847 	/*
848 	 * Disable beacons and reset the register
849 	 */
850 	AR5K_REG_DISABLE_BITS(AR5K_AR5212_BEACON,
851 	    AR5K_AR5212_BEACON_ENABLE | AR5K_AR5212_BEACON_RESET_TSF);
852 
853 	return (AH_TRUE);
854 }
855 
856 void
857 ar5k_ar5212_set_def_antenna(struct ath_hal *hal, u_int ant)
858 {
859 	AR5K_REG_WRITE(AR5K_AR5212_DEFAULT_ANTENNA, ant);
860 }
861 
862 u_int
863 ar5k_ar5212_get_def_antenna(struct ath_hal *hal)
864 {
865 	return AR5K_REG_READ(AR5K_AR5212_DEFAULT_ANTENNA);
866 }
867 
868 void
869 ar5k_ar5212_set_opmode(struct ath_hal *hal)
870 {
871 	u_int32_t pcu_reg, low_id, high_id;
872 
873 	pcu_reg = 0;
874 
875 	switch (hal->ah_op_mode) {
876 #ifndef IEEE80211_STA_ONLY
877 	case IEEE80211_M_IBSS:
878 		pcu_reg |= AR5K_AR5212_STA_ID1_ADHOC |
879 		    AR5K_AR5212_STA_ID1_DESC_ANTENNA;
880 		break;
881 
882 	case IEEE80211_M_HOSTAP:
883 		pcu_reg |= AR5K_AR5212_STA_ID1_AP |
884 		    AR5K_AR5212_STA_ID1_RTS_DEFAULT_ANTENNA;
885 		break;
886 #endif
887 
888 	case IEEE80211_M_STA:
889 	case IEEE80211_M_MONITOR:
890 		pcu_reg |= AR5K_AR5212_STA_ID1_DEFAULT_ANTENNA;
891 		break;
892 
893 	default:
894 		return;
895 	}
896 
897 	/*
898 	 * Set PCU registers
899 	 */
900 	low_id = AR5K_LOW_ID(hal->ah_sta_id);
901 	high_id = AR5K_HIGH_ID(hal->ah_sta_id);
902 	AR5K_REG_WRITE(AR5K_AR5212_STA_ID0, low_id);
903 	AR5K_REG_WRITE(AR5K_AR5212_STA_ID1, pcu_reg | high_id);
904 
905 	return;
906 }
907 
908 HAL_BOOL
909 ar5k_ar5212_calibrate(struct ath_hal *hal, HAL_CHANNEL *channel)
910 {
911 	u_int32_t i_pwr, q_pwr;
912 	int32_t iq_corr, i_coff, i_coffd, q_coff, q_coffd;
913 
914 	if (hal->ah_calibration == AH_FALSE ||
915 	    AR5K_REG_READ(AR5K_AR5212_PHY_IQ) & AR5K_AR5212_PHY_IQ_RUN)
916 		goto done;
917 
918 	hal->ah_calibration = AH_FALSE;
919 
920 	iq_corr = AR5K_REG_READ(AR5K_AR5212_PHY_IQRES_CAL_CORR);
921 	i_pwr = AR5K_REG_READ(AR5K_AR5212_PHY_IQRES_CAL_PWR_I);
922 	q_pwr = AR5K_REG_READ(AR5K_AR5212_PHY_IQRES_CAL_PWR_Q);
923 	i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7;
924 	q_coffd = q_pwr >> 6;
925 
926 	if (i_coffd == 0 || q_coffd == 0)
927 		goto done;
928 
929 	i_coff = ((-iq_corr) / i_coffd) & 0x3f;
930 	q_coff = (((int32_t)i_pwr / q_coffd) - 64) & 0x1f;
931 
932 	/* Commit new IQ value */
933 	AR5K_REG_ENABLE_BITS(AR5K_AR5212_PHY_IQ,
934 	    AR5K_AR5212_PHY_IQ_CORR_ENABLE |
935 	    ((u_int32_t)q_coff) |
936 	    ((u_int32_t)i_coff << AR5K_AR5212_PHY_IQ_CORR_Q_I_COFF_S));
937 
938  done:
939 	/* Start noise floor calibration */
940 	AR5K_REG_ENABLE_BITS(AR5K_AR5212_PHY_AGCCTL,
941 	    AR5K_AR5212_PHY_AGCCTL_NF);
942 
943 	/* Request RF gain */
944 	if (channel->c_channel_flags & IEEE80211_CHAN_5GHZ) {
945 		AR5K_REG_WRITE(AR5K_AR5212_PHY_PAPD_PROBE,
946 		    AR5K_REG_SM(hal->ah_txpower.txp_max,
947 		    AR5K_AR5212_PHY_PAPD_PROBE_TXPOWER) |
948 		    AR5K_AR5212_PHY_PAPD_PROBE_TX_NEXT);
949 		hal->ah_rf_gain = HAL_RFGAIN_READ_REQUESTED;
950 	}
951 
952 	return (AH_TRUE);
953 }
954 
955 /*
956  * Transmit functions
957  */
958 
959 HAL_BOOL
960 ar5k_ar5212_update_tx_triglevel(struct ath_hal *hal, HAL_BOOL increase)
961 {
962 	u_int32_t trigger_level, imr;
963 	HAL_BOOL status = AH_FALSE;
964 
965 	/*
966 	 * Disable interrupts by setting the mask
967 	 */
968 	imr = ar5k_ar5212_set_intr(hal, hal->ah_imr & ~HAL_INT_GLOBAL);
969 
970 	trigger_level = AR5K_REG_MS(AR5K_REG_READ(AR5K_AR5212_TXCFG),
971 	    AR5K_AR5212_TXCFG_TXFULL);
972 
973 	if (increase == AH_FALSE) {
974 		if (--trigger_level < AR5K_TUNE_MIN_TX_FIFO_THRES)
975 			goto done;
976 	} else
977 		trigger_level +=
978 		    ((AR5K_TUNE_MAX_TX_FIFO_THRES - trigger_level) / 2);
979 
980 	/*
981 	 * Update trigger level on success
982 	 */
983 	AR5K_REG_WRITE_BITS(AR5K_AR5212_TXCFG,
984 	    AR5K_AR5212_TXCFG_TXFULL, trigger_level);
985 	status = AH_TRUE;
986 
987  done:
988 	/*
989 	 * Restore interrupt mask
990 	 */
991 	ar5k_ar5212_set_intr(hal, imr);
992 
993 	return (status);
994 }
995 
996 int
997 ar5k_ar5212_setup_tx_queue(struct ath_hal *hal, HAL_TX_QUEUE queue_type,
998     const HAL_TXQ_INFO *queue_info)
999 {
1000 	u_int queue;
1001 
1002 	/*
1003 	 * Get queue by type
1004 	 */
1005 	if (queue_type == HAL_TX_QUEUE_DATA) {
1006 		for (queue = HAL_TX_QUEUE_ID_DATA_MIN;
1007 		     hal->ah_txq[queue].tqi_type != HAL_TX_QUEUE_INACTIVE;
1008 		     queue++)
1009 			if (queue > HAL_TX_QUEUE_ID_DATA_MAX)
1010 				return (-1);
1011 	} else if (queue_type == HAL_TX_QUEUE_PSPOLL) {
1012 		queue = HAL_TX_QUEUE_ID_PSPOLL;
1013 	} else if (queue_type == HAL_TX_QUEUE_BEACON) {
1014 		queue = HAL_TX_QUEUE_ID_BEACON;
1015 	} else if (queue_type == HAL_TX_QUEUE_CAB) {
1016 		queue = HAL_TX_QUEUE_ID_CAB;
1017 	} else
1018 		return (-1);
1019 
1020 	/*
1021 	 * Setup internal queue structure
1022 	 */
1023 	bzero(&hal->ah_txq[queue], sizeof(HAL_TXQ_INFO));
1024 	if (queue_info != NULL) {
1025 		if (ar5k_ar5212_setup_tx_queueprops(hal, queue, queue_info)
1026 		    != AH_TRUE)
1027 			return (-1);
1028 	}
1029 	hal->ah_txq[queue].tqi_type = queue_type;
1030 
1031 	AR5K_Q_ENABLE_BITS(hal->ah_txq_interrupts, queue);
1032 
1033 	return (queue);
1034 }
1035 
1036 HAL_BOOL
1037 ar5k_ar5212_setup_tx_queueprops(struct ath_hal *hal, int queue,
1038     const HAL_TXQ_INFO *queue_info)
1039 {
1040 	AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
1041 
1042 	if (hal->ah_txq[queue].tqi_type != HAL_TX_QUEUE_INACTIVE)
1043 		return (AH_FALSE);
1044 
1045 	bcopy(queue_info, &hal->ah_txq[queue], sizeof(HAL_TXQ_INFO));
1046 
1047 	if (queue_info->tqi_type == HAL_TX_QUEUE_DATA &&
1048 	    (queue_info->tqi_subtype >= HAL_WME_AC_VI) &&
1049 	    (queue_info->tqi_subtype <= HAL_WME_UPSD))
1050 		hal->ah_txq[queue].tqi_flags |=
1051 		    AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS;
1052 
1053 	return (AH_TRUE);
1054 }
1055 
1056 HAL_BOOL
1057 ar5k_ar5212_get_tx_queueprops(struct ath_hal *hal, int queue,
1058     HAL_TXQ_INFO *queue_info)
1059 {
1060 	AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
1061 	bcopy(&hal->ah_txq[queue], queue_info, sizeof(HAL_TXQ_INFO));
1062 	return (AH_TRUE);
1063 }
1064 
1065 HAL_BOOL
1066 ar5k_ar5212_release_tx_queue(struct ath_hal *hal, u_int queue)
1067 {
1068 	AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
1069 
1070 	/* This queue will be skipped in further operations */
1071 	hal->ah_txq[queue].tqi_type = HAL_TX_QUEUE_INACTIVE;
1072 	AR5K_Q_DISABLE_BITS(hal->ah_txq_interrupts, queue);
1073 
1074 	return (AH_FALSE);
1075 }
1076 
1077 HAL_BOOL
1078 ar5k_ar5212_reset_tx_queue(struct ath_hal *hal, u_int queue)
1079 {
1080 	u_int32_t cw_min, cw_max, retry_lg, retry_sh;
1081 	struct ieee80211_channel *channel = (struct ieee80211_channel*)
1082 	    &hal->ah_current_channel;
1083 	HAL_TXQ_INFO *tq;
1084 
1085 	AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
1086 
1087 	tq = &hal->ah_txq[queue];
1088 
1089 	if (tq->tqi_type == HAL_TX_QUEUE_INACTIVE)
1090 		return (AH_TRUE);
1091 
1092 	/*
1093 	 * Set registers by channel mode
1094 	 */
1095 	cw_min = hal->ah_cw_min = AR5K_TUNE_CWMIN;
1096 	cw_max = hal->ah_cw_max = AR5K_TUNE_CWMAX;
1097 	hal->ah_aifs = AR5K_TUNE_AIFS;
1098 	if (IEEE80211_IS_CHAN_XR(channel)) {
1099 		cw_min = hal->ah_cw_min = AR5K_TUNE_CWMIN_XR;
1100 		cw_max = hal->ah_cw_max = AR5K_TUNE_CWMAX_XR;
1101 		hal->ah_aifs = AR5K_TUNE_AIFS_XR;
1102 	} else if (IEEE80211_IS_CHAN_B(channel)) {
1103 		cw_min = hal->ah_cw_min = AR5K_TUNE_CWMIN_11B;
1104 		cw_max = hal->ah_cw_max = AR5K_TUNE_CWMAX_11B;
1105 		hal->ah_aifs = AR5K_TUNE_AIFS_11B;
1106 	}
1107 
1108 	/*
1109 	 * Set retry limits
1110 	 */
1111 	if (hal->ah_software_retry == AH_TRUE) {
1112 		/* XXX Need to test this */
1113 		retry_lg = hal->ah_limit_tx_retries;
1114 		retry_sh = retry_lg =
1115 		    retry_lg > AR5K_AR5212_DCU_RETRY_LMT_SH_RETRY ?
1116 		    AR5K_AR5212_DCU_RETRY_LMT_SH_RETRY : retry_lg;
1117 	} else {
1118 		retry_lg = AR5K_INIT_LG_RETRY;
1119 		retry_sh = AR5K_INIT_SH_RETRY;
1120 	}
1121 
1122 	AR5K_REG_WRITE(AR5K_AR5212_DCU_RETRY_LMT(queue),
1123 	    AR5K_REG_SM(AR5K_INIT_SLG_RETRY,
1124 	    AR5K_AR5212_DCU_RETRY_LMT_SLG_RETRY) |
1125 	    AR5K_REG_SM(AR5K_INIT_SSH_RETRY,
1126 	    AR5K_AR5212_DCU_RETRY_LMT_SSH_RETRY) |
1127 	    AR5K_REG_SM(retry_lg, AR5K_AR5212_DCU_RETRY_LMT_LG_RETRY) |
1128 	    AR5K_REG_SM(retry_sh, AR5K_AR5212_DCU_RETRY_LMT_SH_RETRY));
1129 
1130 	/*
1131 	 * Set initial content window (cw_min/cw_max)
1132 	 */
1133 	cw_min = 1;
1134 	while (cw_min < hal->ah_cw_min)
1135 		cw_min = (cw_min << 1) | 1;
1136 
1137 	cw_min = tq->tqi_cw_min < 0 ?
1138 	    (cw_min >> (-tq->tqi_cw_min)) :
1139 	    ((cw_min << tq->tqi_cw_min) + (1 << tq->tqi_cw_min) - 1);
1140 	cw_max = tq->tqi_cw_max < 0 ?
1141 	    (cw_max >> (-tq->tqi_cw_max)) :
1142 	    ((cw_max << tq->tqi_cw_max) + (1 << tq->tqi_cw_max) - 1);
1143 
1144 	AR5K_REG_WRITE(AR5K_AR5212_DCU_LCL_IFS(queue),
1145 	    AR5K_REG_SM(cw_min, AR5K_AR5212_DCU_LCL_IFS_CW_MIN) |
1146 	    AR5K_REG_SM(cw_max, AR5K_AR5212_DCU_LCL_IFS_CW_MAX) |
1147 	    AR5K_REG_SM(hal->ah_aifs + tq->tqi_aifs,
1148 	    AR5K_AR5212_DCU_LCL_IFS_AIFS));
1149 
1150 	/*
1151 	 * Set misc registers
1152 	 */
1153 	AR5K_REG_WRITE(AR5K_AR5212_QCU_MISC(queue),
1154 	    AR5K_AR5212_QCU_MISC_DCU_EARLY);
1155 
1156 	if (tq->tqi_cbr_period) {
1157 		AR5K_REG_WRITE(AR5K_AR5212_QCU_CBRCFG(queue),
1158 		    AR5K_REG_SM(tq->tqi_cbr_period,
1159 		    AR5K_AR5212_QCU_CBRCFG_INTVAL) |
1160 		    AR5K_REG_SM(tq->tqi_cbr_overflow_limit,
1161 		    AR5K_AR5212_QCU_CBRCFG_ORN_THRES));
1162 		AR5K_REG_ENABLE_BITS(AR5K_AR5212_QCU_MISC(queue),
1163 		    AR5K_AR5212_QCU_MISC_FRSHED_CBR);
1164 		if (tq->tqi_cbr_overflow_limit)
1165 			AR5K_REG_ENABLE_BITS(AR5K_AR5212_QCU_MISC(queue),
1166 			    AR5K_AR5212_QCU_MISC_CBR_THRES_ENABLE);
1167 	}
1168 
1169 	if (tq->tqi_ready_time) {
1170 		AR5K_REG_WRITE(AR5K_AR5212_QCU_RDYTIMECFG(queue),
1171 		    AR5K_REG_SM(tq->tqi_ready_time,
1172 		    AR5K_AR5212_QCU_RDYTIMECFG_INTVAL) |
1173 		    AR5K_AR5212_QCU_RDYTIMECFG_ENABLE);
1174 	}
1175 
1176 	if (tq->tqi_burst_time) {
1177 		AR5K_REG_WRITE(AR5K_AR5212_DCU_CHAN_TIME(queue),
1178 		    AR5K_REG_SM(tq->tqi_burst_time,
1179 		    AR5K_AR5212_DCU_CHAN_TIME_DUR) |
1180 		    AR5K_AR5212_DCU_CHAN_TIME_ENABLE);
1181 
1182 		if (tq->tqi_flags & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE) {
1183 			AR5K_REG_ENABLE_BITS(AR5K_AR5212_QCU_MISC(queue),
1184 			    AR5K_AR5212_QCU_MISC_TXE);
1185 		}
1186 	}
1187 
1188 	if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE) {
1189 		AR5K_REG_WRITE(AR5K_AR5212_DCU_MISC(queue),
1190 		    AR5K_AR5212_DCU_MISC_POST_FR_BKOFF_DIS);
1191 	}
1192 
1193 	if (tq->tqi_flags & AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) {
1194 		AR5K_REG_WRITE(AR5K_AR5212_DCU_MISC(queue),
1195 		    AR5K_AR5212_DCU_MISC_BACKOFF_FRAG);
1196 	}
1197 
1198 	/*
1199 	 * Set registers by queue type
1200 	 */
1201 	switch (tq->tqi_type) {
1202 	case HAL_TX_QUEUE_BEACON:
1203 		AR5K_REG_ENABLE_BITS(AR5K_AR5212_QCU_MISC(queue),
1204 		    AR5K_AR5212_QCU_MISC_FRSHED_DBA_GT |
1205 		    AR5K_AR5212_QCU_MISC_CBREXP_BCN |
1206 		    AR5K_AR5212_QCU_MISC_BCN_ENABLE);
1207 
1208 		AR5K_REG_ENABLE_BITS(AR5K_AR5212_DCU_MISC(queue),
1209 		    (AR5K_AR5212_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
1210 		    AR5K_AR5212_DCU_MISC_ARBLOCK_CTL_GLOBAL) |
1211 		    AR5K_AR5212_DCU_MISC_POST_FR_BKOFF_DIS |
1212 		    AR5K_AR5212_DCU_MISC_BCN_ENABLE);
1213 
1214 		AR5K_REG_WRITE(AR5K_AR5212_QCU_RDYTIMECFG(queue),
1215 		    ((AR5K_TUNE_BEACON_INTERVAL -
1216 		    (AR5K_TUNE_SW_BEACON_RESP - AR5K_TUNE_DMA_BEACON_RESP) -
1217 		    AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) |
1218 		    AR5K_AR5212_QCU_RDYTIMECFG_ENABLE);
1219 		break;
1220 
1221 	case HAL_TX_QUEUE_CAB:
1222 		AR5K_REG_ENABLE_BITS(AR5K_AR5212_QCU_MISC(queue),
1223 		    AR5K_AR5212_QCU_MISC_FRSHED_DBA_GT |
1224 		    AR5K_AR5212_QCU_MISC_CBREXP |
1225 		    AR5K_AR5212_QCU_MISC_CBREXP_BCN);
1226 
1227 		AR5K_REG_ENABLE_BITS(AR5K_AR5212_DCU_MISC(queue),
1228 		    (AR5K_AR5212_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
1229 		    AR5K_AR5212_DCU_MISC_ARBLOCK_CTL_GLOBAL));
1230 		break;
1231 
1232 	case HAL_TX_QUEUE_PSPOLL:
1233 		AR5K_REG_ENABLE_BITS(AR5K_AR5212_QCU_MISC(queue),
1234 		    AR5K_AR5212_QCU_MISC_CBREXP);
1235 		break;
1236 
1237 	case HAL_TX_QUEUE_DATA:
1238 	default:
1239 		break;
1240 	}
1241 
1242 	/*
1243 	 * Enable tx queue in the secondary interrupt mask registers
1244 	 */
1245 	AR5K_REG_WRITE(AR5K_AR5212_SIMR0,
1246 	    AR5K_REG_SM(hal->ah_txq_interrupts, AR5K_AR5212_SIMR0_QCU_TXOK) |
1247 	    AR5K_REG_SM(hal->ah_txq_interrupts, AR5K_AR5212_SIMR0_QCU_TXDESC));
1248 	AR5K_REG_WRITE(AR5K_AR5212_SIMR1,
1249 	    AR5K_REG_SM(hal->ah_txq_interrupts, AR5K_AR5212_SIMR1_QCU_TXERR));
1250 	AR5K_REG_WRITE(AR5K_AR5212_SIMR2,
1251 	    AR5K_REG_SM(hal->ah_txq_interrupts, AR5K_AR5212_SIMR2_QCU_TXURN));
1252 
1253 	return (AH_TRUE);
1254 }
1255 
1256 u_int32_t
1257 ar5k_ar5212_get_tx_buf(struct ath_hal *hal, u_int queue)
1258 {
1259 	AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
1260 
1261 	/*
1262 	 * Get the transmit queue descriptor pointer from the selected queue
1263 	 */
1264 	return (AR5K_REG_READ(AR5K_AR5212_QCU_TXDP(queue)));
1265 }
1266 
1267 HAL_BOOL
1268 ar5k_ar5212_put_tx_buf(struct ath_hal *hal, u_int queue, u_int32_t phys_addr)
1269 {
1270 	AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
1271 
1272 	/*
1273 	 * Set the transmit queue descriptor pointer for the selected queue
1274 	 * (this won't work if the queue is still active)
1275 	 */
1276 	if (AR5K_REG_READ_Q(AR5K_AR5212_QCU_TXE, queue))
1277 		return (AH_FALSE);
1278 
1279 	AR5K_REG_WRITE(AR5K_AR5212_QCU_TXDP(queue), phys_addr);
1280 
1281 	return (AH_TRUE);
1282 }
1283 
1284 u_int32_t
1285 ar5k_ar5212_num_tx_pending(struct ath_hal *hal, u_int queue)
1286 {
1287 	AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
1288 	return (AR5K_AR5212_QCU_STS(queue) & AR5K_AR5212_QCU_STS_FRMPENDCNT);
1289 }
1290 
1291 HAL_BOOL
1292 ar5k_ar5212_tx_start(struct ath_hal *hal, u_int queue)
1293 {
1294 	AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
1295 
1296 	/* Return if queue is disabled */
1297 	if (AR5K_REG_READ_Q(AR5K_AR5212_QCU_TXD, queue))
1298 		return (AH_FALSE);
1299 
1300 	/* Start queue */
1301 	AR5K_REG_WRITE_Q(AR5K_AR5212_QCU_TXE, queue);
1302 
1303 	return (AH_TRUE);
1304 }
1305 
1306 HAL_BOOL
1307 ar5k_ar5212_stop_tx_dma(struct ath_hal *hal, u_int queue)
1308 {
1309 	int i = 100, pending;
1310 
1311 	AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);
1312 
1313 	/*
1314 	 * Schedule TX disable and wait until queue is empty
1315 	 */
1316 	AR5K_REG_WRITE_Q(AR5K_AR5212_QCU_TXD, queue);
1317 
1318 	do {
1319 		pending = AR5K_REG_READ(AR5K_AR5212_QCU_STS(queue)) &
1320 		     AR5K_AR5212_QCU_STS_FRMPENDCNT;
1321 		delay(100);
1322 	} while (--i && pending);
1323 
1324 	/* Clear register */
1325 	AR5K_REG_WRITE(AR5K_AR5212_QCU_TXD, 0);
1326 
1327 	return (AH_TRUE);
1328 }
1329 
1330 HAL_BOOL
1331 ar5k_ar5212_setup_tx_desc(struct ath_hal *hal, struct ath_desc *desc,
1332     u_int packet_length, u_int header_length, HAL_PKT_TYPE type, u_int tx_power,
1333     u_int tx_rate0, u_int tx_tries0, u_int key_index, u_int antenna_mode,
1334     u_int flags, u_int rtscts_rate, u_int rtscts_duration)
1335 {
1336 	struct ar5k_ar5212_tx_desc *tx_desc;
1337 
1338 	tx_desc = (struct ar5k_ar5212_tx_desc*)&desc->ds_ctl0;
1339 
1340 	/*
1341 	 * Validate input
1342 	 */
1343 	if (tx_tries0 == 0)
1344 		return (AH_FALSE);
1345 
1346 	if ((tx_desc->tx_control_0 = (packet_length &
1347 	    AR5K_AR5212_DESC_TX_CTL0_FRAME_LEN)) != packet_length)
1348 		return (AH_FALSE);
1349 
1350 	tx_desc->tx_control_0 |=
1351 	    AR5K_REG_SM(tx_power, AR5K_AR5212_DESC_TX_CTL0_XMIT_POWER) |
1352 	    AR5K_REG_SM(antenna_mode, AR5K_AR5212_DESC_TX_CTL0_ANT_MODE_XMIT);
1353 	tx_desc->tx_control_1 =
1354 	    AR5K_REG_SM(type, AR5K_AR5212_DESC_TX_CTL1_FRAME_TYPE);
1355 	tx_desc->tx_control_2 =
1356 	    AR5K_REG_SM(tx_tries0 + AR5K_TUNE_HWTXTRIES,
1357 	    AR5K_AR5212_DESC_TX_CTL2_XMIT_TRIES0);
1358 	tx_desc->tx_control_3 =
1359 	    tx_rate0 & AR5K_AR5212_DESC_TX_CTL3_XMIT_RATE0;
1360 
1361 #define _TX_FLAGS(_c, _flag)						\
1362 	if (flags & HAL_TXDESC_##_flag)					\
1363 		tx_desc->tx_control_##_c |=				\
1364 			AR5K_AR5212_DESC_TX_CTL##_c##_##_flag
1365 
1366 	_TX_FLAGS(0, CLRDMASK);
1367 	_TX_FLAGS(0, VEOL);
1368 	_TX_FLAGS(0, INTREQ);
1369 	_TX_FLAGS(0, RTSENA);
1370 	_TX_FLAGS(0, CTSENA);
1371 	_TX_FLAGS(1, NOACK);
1372 
1373 #undef _TX_FLAGS
1374 
1375 	/*
1376 	 * WEP crap
1377 	 */
1378 	if (key_index != HAL_TXKEYIX_INVALID) {
1379 		tx_desc->tx_control_0 |=
1380 		    AR5K_AR5212_DESC_TX_CTL0_ENCRYPT_KEY_VALID;
1381 		tx_desc->tx_control_1 |=
1382 		    AR5K_REG_SM(key_index,
1383 		    AR5K_AR5212_DESC_TX_CTL1_ENCRYPT_KEY_INDEX);
1384 	}
1385 
1386 	/*
1387 	 * RTS/CTS
1388 	 */
1389 	if (flags & (HAL_TXDESC_RTSENA | HAL_TXDESC_CTSENA)) {
1390 		if ((flags & HAL_TXDESC_RTSENA) &&
1391 		    (flags & HAL_TXDESC_CTSENA))
1392 			return (AH_FALSE);
1393 		tx_desc->tx_control_2 |=
1394 		    rtscts_duration & AR5K_AR5212_DESC_TX_CTL2_RTS_DURATION;
1395 		tx_desc->tx_control_3 |=
1396 		    AR5K_REG_SM(rtscts_rate,
1397 		    AR5K_AR5212_DESC_TX_CTL3_RTS_CTS_RATE);
1398 	}
1399 
1400 	return (AH_TRUE);
1401 }
1402 
1403 HAL_BOOL
1404 ar5k_ar5212_fill_tx_desc(struct ath_hal *hal, struct ath_desc *desc,
1405     u_int segment_length, HAL_BOOL first_segment, HAL_BOOL last_segment)
1406 {
1407 	struct ar5k_ar5212_tx_desc *tx_desc;
1408 	struct ar5k_ar5212_tx_status *tx_status;
1409 
1410 	tx_desc = (struct ar5k_ar5212_tx_desc*)&desc->ds_ctl0;
1411 	tx_status = (struct ar5k_ar5212_tx_status*)&desc->ds_hw[2];
1412 
1413 	/* Clear status descriptor */
1414 	bzero(tx_status, sizeof(struct ar5k_ar5212_tx_status));
1415 
1416 	/* Validate segment length and initialize the descriptor */
1417 	if (segment_length & ~AR5K_AR5212_DESC_TX_CTL1_BUF_LEN)
1418 		return (AH_FALSE);
1419 	tx_desc->tx_control_1 =
1420 #if 0
1421 	    (tx_desc->tx_control_1 & ~AR5K_AR5212_DESC_TX_CTL1_BUF_LEN) |
1422 #endif
1423 	    segment_length;
1424 
1425 	if (first_segment != AH_TRUE)
1426 		tx_desc->tx_control_0 &= ~AR5K_AR5212_DESC_TX_CTL0_FRAME_LEN;
1427 
1428 	if (last_segment != AH_TRUE)
1429 		tx_desc->tx_control_1 |= AR5K_AR5212_DESC_TX_CTL1_MORE;
1430 
1431 	return (AH_TRUE);
1432 }
1433 
1434 HAL_BOOL
1435 ar5k_ar5212_setup_xtx_desc(struct ath_hal *hal, struct ath_desc *desc,
1436     u_int tx_rate1, u_int tx_tries1, u_int tx_rate2, u_int tx_tries2,
1437     u_int tx_rate3, u_int tx_tries3)
1438 {
1439 	struct ar5k_ar5212_tx_desc *tx_desc;
1440 
1441 	tx_desc = (struct ar5k_ar5212_tx_desc*)&desc->ds_ctl0;
1442 
1443 #define _XTX_TRIES(_n)							\
1444 	if (tx_tries##_n) {						\
1445 		tx_desc->tx_control_2 |=				\
1446 		    AR5K_REG_SM(tx_tries##_n,				\
1447 		    AR5K_AR5212_DESC_TX_CTL2_XMIT_TRIES##_n);		\
1448 		tx_desc->tx_control_3 |=				\
1449 		    AR5K_REG_SM(tx_rate##_n,				\
1450 		    AR5K_AR5212_DESC_TX_CTL3_XMIT_RATE##_n);		\
1451 	}
1452 
1453 	_XTX_TRIES(1);
1454 	_XTX_TRIES(2);
1455 	_XTX_TRIES(3);
1456 
1457 #undef _XTX_TRIES
1458 
1459 	return (AH_TRUE);
1460 }
1461 
1462 HAL_STATUS
1463 ar5k_ar5212_proc_tx_desc(struct ath_hal *hal, struct ath_desc *desc)
1464 {
1465 	struct ar5k_ar5212_tx_status *tx_status;
1466 	struct ar5k_ar5212_tx_desc *tx_desc;
1467 
1468 	tx_desc = (struct ar5k_ar5212_tx_desc*)&desc->ds_ctl0;
1469 	tx_status = (struct ar5k_ar5212_tx_status*)&desc->ds_hw[2];
1470 
1471 	/* No frame has been send or error */
1472 	if ((tx_status->tx_status_1 & AR5K_AR5212_DESC_TX_STATUS1_DONE) == 0)
1473 		return (HAL_EINPROGRESS);
1474 
1475 	/*
1476 	 * Get descriptor status
1477 	 */
1478 	desc->ds_us.tx.ts_tstamp =
1479 	    AR5K_REG_MS(tx_status->tx_status_0,
1480 	    AR5K_AR5212_DESC_TX_STATUS0_SEND_TIMESTAMP);
1481 	desc->ds_us.tx.ts_shortretry =
1482 	    AR5K_REG_MS(tx_status->tx_status_0,
1483 	    AR5K_AR5212_DESC_TX_STATUS0_RTS_FAIL_COUNT);
1484 	desc->ds_us.tx.ts_longretry =
1485 	    AR5K_REG_MS(tx_status->tx_status_0,
1486 	    AR5K_AR5212_DESC_TX_STATUS0_DATA_FAIL_COUNT);
1487 	desc->ds_us.tx.ts_seqnum =
1488 	    AR5K_REG_MS(tx_status->tx_status_1,
1489 	    AR5K_AR5212_DESC_TX_STATUS1_SEQ_NUM);
1490 	desc->ds_us.tx.ts_rssi =
1491 	    AR5K_REG_MS(tx_status->tx_status_1,
1492 	    AR5K_AR5212_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
1493 	desc->ds_us.tx.ts_antenna = (tx_status->tx_status_1 &
1494 	    AR5K_AR5212_DESC_TX_STATUS1_XMIT_ANTENNA) ? 2 : 1;
1495 	desc->ds_us.tx.ts_status = 0;
1496 
1497 	switch (AR5K_REG_MS(tx_status->tx_status_1,
1498 	    AR5K_AR5212_DESC_TX_STATUS1_FINAL_TS_INDEX)) {
1499 	case 0:
1500 		desc->ds_us.tx.ts_rate = tx_desc->tx_control_3 &
1501 		    AR5K_AR5212_DESC_TX_CTL3_XMIT_RATE0;
1502 		break;
1503 	case 1:
1504 		desc->ds_us.tx.ts_rate =
1505 		    AR5K_REG_MS(tx_desc->tx_control_3,
1506 		    AR5K_AR5212_DESC_TX_CTL3_XMIT_RATE1);
1507 		desc->ds_us.tx.ts_longretry +=
1508 		    AR5K_REG_MS(tx_desc->tx_control_2,
1509 		    AR5K_AR5212_DESC_TX_CTL2_XMIT_TRIES1);
1510 		break;
1511 	case 2:
1512 		desc->ds_us.tx.ts_rate =
1513 		    AR5K_REG_MS(tx_desc->tx_control_3,
1514 		    AR5K_AR5212_DESC_TX_CTL3_XMIT_RATE2);
1515 		desc->ds_us.tx.ts_longretry +=
1516 		    AR5K_REG_MS(tx_desc->tx_control_2,
1517 		    AR5K_AR5212_DESC_TX_CTL2_XMIT_TRIES2);
1518 		break;
1519 	case 3:
1520 		desc->ds_us.tx.ts_rate =
1521 		    AR5K_REG_MS(tx_desc->tx_control_3,
1522 		    AR5K_AR5212_DESC_TX_CTL3_XMIT_RATE3);
1523 		desc->ds_us.tx.ts_longretry +=
1524 		    AR5K_REG_MS(tx_desc->tx_control_2,
1525 		    AR5K_AR5212_DESC_TX_CTL2_XMIT_TRIES3);
1526 		break;
1527 	}
1528 
1529 	if ((tx_status->tx_status_0 &
1530 	    AR5K_AR5212_DESC_TX_STATUS0_FRAME_XMIT_OK) == 0) {
1531 		if (tx_status->tx_status_0 &
1532 		    AR5K_AR5212_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
1533 			desc->ds_us.tx.ts_status |= HAL_TXERR_XRETRY;
1534 
1535 		if (tx_status->tx_status_0 &
1536 		    AR5K_AR5212_DESC_TX_STATUS0_FIFO_UNDERRUN)
1537 			desc->ds_us.tx.ts_status |= HAL_TXERR_FIFO;
1538 
1539 		if (tx_status->tx_status_0 &
1540 		    AR5K_AR5212_DESC_TX_STATUS0_FILTERED)
1541 			desc->ds_us.tx.ts_status |= HAL_TXERR_FILT;
1542 	}
1543 
1544 	return (HAL_OK);
1545 }
1546 
1547 HAL_BOOL
1548 ar5k_ar5212_has_veol(struct ath_hal *hal)
1549 {
1550 	return (AH_TRUE);
1551 }
1552 
1553 /*
1554  * Receive functions
1555  */
1556 
1557 u_int32_t
1558 ar5k_ar5212_get_rx_buf(struct ath_hal *hal)
1559 {
1560 	return (AR5K_REG_READ(AR5K_AR5212_RXDP));
1561 }
1562 
1563 void
1564 ar5k_ar5212_put_rx_buf(struct ath_hal *hal, u_int32_t phys_addr)
1565 {
1566 	AR5K_REG_WRITE(AR5K_AR5212_RXDP, phys_addr);
1567 }
1568 
1569 void
1570 ar5k_ar5212_start_rx(struct ath_hal *hal)
1571 {
1572 	AR5K_REG_WRITE(AR5K_AR5212_CR, AR5K_AR5212_CR_RXE);
1573 }
1574 
1575 HAL_BOOL
1576 ar5k_ar5212_stop_rx_dma(struct ath_hal *hal)
1577 {
1578 	int i;
1579 
1580 	AR5K_REG_WRITE(AR5K_AR5212_CR, AR5K_AR5212_CR_RXD);
1581 
1582 	/*
1583 	 * It may take some time to disable the DMA receive unit
1584 	 */
1585 	for (i = 2000;
1586 	     i > 0 && (AR5K_REG_READ(AR5K_AR5212_CR) & AR5K_AR5212_CR_RXE) != 0;
1587 	     i--)
1588 		AR5K_DELAY(10);
1589 
1590 	return (i > 0 ? AH_TRUE : AH_FALSE);
1591 }
1592 
1593 void
1594 ar5k_ar5212_start_rx_pcu(struct ath_hal *hal)
1595 {
1596 	AR5K_REG_DISABLE_BITS(AR5K_AR5212_DIAG_SW, AR5K_AR5212_DIAG_SW_DIS_RX);
1597 }
1598 
1599 void
1600 ar5k_ar5212_stop_pcu_recv(struct ath_hal *hal)
1601 {
1602 	AR5K_REG_ENABLE_BITS(AR5K_AR5212_DIAG_SW, AR5K_AR5212_DIAG_SW_DIS_RX);
1603 }
1604 
1605 void
1606 ar5k_ar5212_set_mcast_filter(struct ath_hal *hal, u_int32_t filter0,
1607     u_int32_t filter1)
1608 {
1609 	/* Set the multicat filter */
1610 	AR5K_REG_WRITE(AR5K_AR5212_MCAST_FIL0, filter0);
1611 	AR5K_REG_WRITE(AR5K_AR5212_MCAST_FIL1, filter1);
1612 }
1613 
1614 HAL_BOOL
1615 ar5k_ar5212_set_mcast_filterindex(struct ath_hal *hal, u_int32_t index)
1616 {
1617 	if (index >= 64) {
1618 	    return (AH_FALSE);
1619 	} else if (index >= 32) {
1620 	    AR5K_REG_ENABLE_BITS(AR5K_AR5212_MCAST_FIL1,
1621 		(1 << (index - 32)));
1622 	} else {
1623 	    AR5K_REG_ENABLE_BITS(AR5K_AR5212_MCAST_FIL0,
1624 		(1 << index));
1625 	}
1626 
1627 	return (AH_TRUE);
1628 }
1629 
1630 HAL_BOOL
1631 ar5k_ar5212_clear_mcast_filter_idx(struct ath_hal *hal, u_int32_t index)
1632 {
1633 
1634 	if (index >= 64) {
1635 	    return (AH_FALSE);
1636 	} else if (index >= 32) {
1637 	    AR5K_REG_DISABLE_BITS(AR5K_AR5212_MCAST_FIL1,
1638 		(1 << (index - 32)));
1639 	} else {
1640 	    AR5K_REG_DISABLE_BITS(AR5K_AR5212_MCAST_FIL0,
1641 		(1 << index));
1642 	}
1643 
1644 	return (AH_TRUE);
1645 }
1646 
1647 u_int32_t
1648 ar5k_ar5212_get_rx_filter(struct ath_hal *hal)
1649 {
1650 	u_int32_t data, filter = 0;
1651 
1652 	filter = AR5K_REG_READ(AR5K_AR5212_RX_FILTER);
1653 	data = AR5K_REG_READ(AR5K_AR5212_PHY_ERR_FIL);
1654 
1655 	if (data & AR5K_AR5212_PHY_ERR_FIL_RADAR)
1656 		filter |= HAL_RX_FILTER_PHYRADAR;
1657 	if (data & (AR5K_AR5212_PHY_ERR_FIL_OFDM |
1658 	    AR5K_AR5212_PHY_ERR_FIL_CCK))
1659 		filter |= HAL_RX_FILTER_PHYERR;
1660 
1661 	return (filter);
1662 }
1663 
1664 void
1665 ar5k_ar5212_set_rx_filter(struct ath_hal *hal, u_int32_t filter)
1666 {
1667 	u_int32_t data = 0;
1668 
1669 	if (filter & HAL_RX_FILTER_PHYRADAR)
1670 		data |= AR5K_AR5212_PHY_ERR_FIL_RADAR;
1671 	if (filter & HAL_RX_FILTER_PHYERR)
1672 		data |= AR5K_AR5212_PHY_ERR_FIL_OFDM |
1673 		    AR5K_AR5212_PHY_ERR_FIL_CCK;
1674 
1675 	if (data) {
1676 		AR5K_REG_ENABLE_BITS(AR5K_AR5212_RXCFG,
1677 		    AR5K_AR5212_RXCFG_ZLFDMA);
1678 	} else {
1679 		AR5K_REG_DISABLE_BITS(AR5K_AR5212_RXCFG,
1680 		    AR5K_AR5212_RXCFG_ZLFDMA);
1681 	}
1682 
1683 	AR5K_REG_WRITE(AR5K_AR5212_RX_FILTER, filter & 0xff);
1684 	AR5K_REG_WRITE(AR5K_AR5212_PHY_ERR_FIL, data);
1685 }
1686 
1687 HAL_BOOL
1688 ar5k_ar5212_setup_rx_desc(struct ath_hal *hal, struct ath_desc *desc,
1689     u_int32_t size, u_int flags)
1690 {
1691 	struct ar5k_ar5212_rx_desc *rx_desc;
1692 
1693 	rx_desc = (struct ar5k_ar5212_rx_desc*)&desc->ds_ctl0;
1694 
1695 	if ((rx_desc->rx_control_1 = (size &
1696 	    AR5K_AR5212_DESC_RX_CTL1_BUF_LEN)) != size)
1697 		return (AH_FALSE);
1698 
1699 	if (flags & HAL_RXDESC_INTREQ)
1700 		rx_desc->rx_control_1 |= AR5K_AR5212_DESC_RX_CTL1_INTREQ;
1701 
1702 	return (AH_TRUE);
1703 }
1704 
1705 HAL_STATUS
1706 ar5k_ar5212_proc_rx_desc(struct ath_hal *hal, struct ath_desc *desc,
1707     u_int32_t phys_addr, struct ath_desc *next)
1708 {
1709 	struct ar5k_ar5212_rx_status *rx_status;
1710 	struct ar5k_ar5212_rx_error *rx_err;
1711 
1712 	rx_status = (struct ar5k_ar5212_rx_status*)&desc->ds_hw[0];
1713 
1714 	/* Overlay on error */
1715 	rx_err = (struct ar5k_ar5212_rx_error*)&desc->ds_hw[0];
1716 
1717 	/* No frame received / not ready */
1718 	if ((rx_status->rx_status_1 & AR5K_AR5212_DESC_RX_STATUS1_DONE) == 0)
1719 		return (HAL_EINPROGRESS);
1720 
1721 	/*
1722 	 * Frame receive status
1723 	 */
1724 	desc->ds_us.rx.rs_datalen = rx_status->rx_status_0 &
1725 	    AR5K_AR5212_DESC_RX_STATUS0_DATA_LEN;
1726 	desc->ds_us.rx.rs_rssi =
1727 	    AR5K_REG_MS(rx_status->rx_status_0,
1728 	    AR5K_AR5212_DESC_RX_STATUS0_RECEIVE_SIGNAL);
1729 	desc->ds_us.rx.rs_rate =
1730 	    AR5K_REG_MS(rx_status->rx_status_0,
1731 	    AR5K_AR5212_DESC_RX_STATUS0_RECEIVE_RATE);
1732 	desc->ds_us.rx.rs_antenna = rx_status->rx_status_0 &
1733 	    AR5K_AR5212_DESC_RX_STATUS0_RECEIVE_ANTENNA;
1734 	desc->ds_us.rx.rs_more = rx_status->rx_status_0 &
1735 	    AR5K_AR5212_DESC_RX_STATUS0_MORE;
1736 	desc->ds_us.rx.rs_tstamp =
1737 	    AR5K_REG_MS(rx_status->rx_status_1,
1738 	    AR5K_AR5212_DESC_RX_STATUS1_RECEIVE_TIMESTAMP);
1739 	desc->ds_us.rx.rs_status = 0;
1740 
1741 	/*
1742 	 * Key table status
1743 	 */
1744 	if (rx_status->rx_status_1 &
1745 	    AR5K_AR5212_DESC_RX_STATUS1_KEY_INDEX_VALID) {
1746 		desc->ds_us.rx.rs_keyix =
1747 		    AR5K_REG_MS(rx_status->rx_status_1,
1748 		    AR5K_AR5212_DESC_RX_STATUS1_KEY_INDEX);
1749 	} else {
1750 		desc->ds_us.rx.rs_keyix = HAL_RXKEYIX_INVALID;
1751 	}
1752 
1753 	/*
1754 	 * Receive/descriptor errors
1755 	 */
1756 	if ((rx_status->rx_status_1 &
1757 	    AR5K_AR5212_DESC_RX_STATUS1_FRAME_RECEIVE_OK) == 0) {
1758 		if (rx_status->rx_status_1 &
1759 		    AR5K_AR5212_DESC_RX_STATUS1_CRC_ERROR)
1760 			desc->ds_us.rx.rs_status |= HAL_RXERR_CRC;
1761 
1762 		if (rx_status->rx_status_1 &
1763 		    AR5K_AR5212_DESC_RX_STATUS1_PHY_ERROR) {
1764 			desc->ds_us.rx.rs_status |= HAL_RXERR_PHY;
1765 			desc->ds_us.rx.rs_phyerr =
1766 			    AR5K_REG_MS(rx_err->rx_error_1,
1767 			    AR5K_AR5212_DESC_RX_ERROR1_PHY_ERROR_CODE);
1768 		}
1769 
1770 		if (rx_status->rx_status_1 &
1771 		    AR5K_AR5212_DESC_RX_STATUS1_DECRYPT_CRC_ERROR)
1772 			desc->ds_us.rx.rs_status |= HAL_RXERR_DECRYPT;
1773 
1774 		if (rx_status->rx_status_1 &
1775 		    AR5K_AR5212_DESC_RX_STATUS1_MIC_ERROR)
1776 			desc->ds_us.rx.rs_status |= HAL_RXERR_MIC;
1777 	}
1778 
1779 	return (HAL_OK);
1780 }
1781 
1782 void
1783 ar5k_ar5212_set_rx_signal(struct ath_hal *hal)
1784 {
1785 	/* Signal state monitoring is not yet supported */
1786 }
1787 
1788 /*
1789  * Misc functions
1790  */
1791 
1792 void
1793 ar5k_ar5212_dump_state(struct ath_hal *hal)
1794 {
1795 #ifdef AR5K_DEBUG
1796 #define AR5K_PRINT_REGISTER(_x)						\
1797 	printf("(%s: %08x) ", #_x, AR5K_REG_READ(AR5K_AR5212_##_x));
1798 
1799 	printf("MAC registers:\n");
1800 	AR5K_PRINT_REGISTER(CR);
1801 	AR5K_PRINT_REGISTER(CFG);
1802 	AR5K_PRINT_REGISTER(IER);
1803 	AR5K_PRINT_REGISTER(TXCFG);
1804 	AR5K_PRINT_REGISTER(RXCFG);
1805 	AR5K_PRINT_REGISTER(MIBC);
1806 	AR5K_PRINT_REGISTER(TOPS);
1807 	AR5K_PRINT_REGISTER(RXNOFRM);
1808 	AR5K_PRINT_REGISTER(RPGTO);
1809 	AR5K_PRINT_REGISTER(RFCNT);
1810 	AR5K_PRINT_REGISTER(MISC);
1811 	AR5K_PRINT_REGISTER(PISR);
1812 	AR5K_PRINT_REGISTER(SISR0);
1813 	AR5K_PRINT_REGISTER(SISR1);
1814 	AR5K_PRINT_REGISTER(SISR3);
1815 	AR5K_PRINT_REGISTER(SISR4);
1816 	AR5K_PRINT_REGISTER(DCM_ADDR);
1817 	AR5K_PRINT_REGISTER(DCM_DATA);
1818 	AR5K_PRINT_REGISTER(DCCFG);
1819 	AR5K_PRINT_REGISTER(CCFG);
1820 	AR5K_PRINT_REGISTER(CCFG_CUP);
1821 	AR5K_PRINT_REGISTER(CPC0);
1822 	AR5K_PRINT_REGISTER(CPC1);
1823 	AR5K_PRINT_REGISTER(CPC2);
1824 	AR5K_PRINT_REGISTER(CPCORN);
1825 	AR5K_PRINT_REGISTER(QCU_TXE);
1826 	AR5K_PRINT_REGISTER(QCU_TXD);
1827 	AR5K_PRINT_REGISTER(DCU_GBL_IFS_SIFS);
1828 	AR5K_PRINT_REGISTER(DCU_GBL_IFS_SLOT);
1829 	AR5K_PRINT_REGISTER(DCU_FP);
1830 	AR5K_PRINT_REGISTER(DCU_TXP);
1831 	AR5K_PRINT_REGISTER(DCU_TX_FILTER);
1832 	AR5K_PRINT_REGISTER(RC);
1833 	AR5K_PRINT_REGISTER(SCR);
1834 	AR5K_PRINT_REGISTER(INTPEND);
1835 	AR5K_PRINT_REGISTER(PCICFG);
1836 	AR5K_PRINT_REGISTER(GPIOCR);
1837 	AR5K_PRINT_REGISTER(GPIODO);
1838 	AR5K_PRINT_REGISTER(SREV);
1839 	AR5K_PRINT_REGISTER(EEPROM_BASE);
1840 	AR5K_PRINT_REGISTER(EEPROM_DATA);
1841 	AR5K_PRINT_REGISTER(EEPROM_CMD);
1842 	AR5K_PRINT_REGISTER(EEPROM_CFG);
1843 	AR5K_PRINT_REGISTER(PCU_MIN);
1844 	AR5K_PRINT_REGISTER(STA_ID0);
1845 	AR5K_PRINT_REGISTER(STA_ID1);
1846 	AR5K_PRINT_REGISTER(BSS_ID0);
1847 	AR5K_PRINT_REGISTER(SLOT_TIME);
1848 	AR5K_PRINT_REGISTER(TIME_OUT);
1849 	AR5K_PRINT_REGISTER(RSSI_THR);
1850 	AR5K_PRINT_REGISTER(BEACON);
1851 	AR5K_PRINT_REGISTER(CFP_PERIOD);
1852 	AR5K_PRINT_REGISTER(TIMER0);
1853 	AR5K_PRINT_REGISTER(TIMER2);
1854 	AR5K_PRINT_REGISTER(TIMER3);
1855 	AR5K_PRINT_REGISTER(CFP_DUR);
1856 	AR5K_PRINT_REGISTER(MCAST_FIL0);
1857 	AR5K_PRINT_REGISTER(MCAST_FIL1);
1858 	AR5K_PRINT_REGISTER(DIAG_SW);
1859 	AR5K_PRINT_REGISTER(TSF_U32);
1860 	AR5K_PRINT_REGISTER(ADDAC_TEST);
1861 	AR5K_PRINT_REGISTER(DEFAULT_ANTENNA);
1862 	AR5K_PRINT_REGISTER(LAST_TSTP);
1863 	AR5K_PRINT_REGISTER(NAV);
1864 	AR5K_PRINT_REGISTER(RTS_OK);
1865 	AR5K_PRINT_REGISTER(ACK_FAIL);
1866 	AR5K_PRINT_REGISTER(FCS_FAIL);
1867 	AR5K_PRINT_REGISTER(BEACON_CNT);
1868 	AR5K_PRINT_REGISTER(TSF_PARM);
1869 	AR5K_PRINT_REGISTER(RATE_DUR_0);
1870 	AR5K_PRINT_REGISTER(KEYTABLE_0);
1871 	printf("\n");
1872 
1873 	printf("PHY registers:\n");
1874 	AR5K_PRINT_REGISTER(PHY_TURBO);
1875 	AR5K_PRINT_REGISTER(PHY_AGC);
1876 	AR5K_PRINT_REGISTER(PHY_TIMING_3);
1877 	AR5K_PRINT_REGISTER(PHY_CHIP_ID);
1878 	AR5K_PRINT_REGISTER(PHY_AGCCTL);
1879 	AR5K_PRINT_REGISTER(PHY_NF);
1880 	AR5K_PRINT_REGISTER(PHY_SCR);
1881 	AR5K_PRINT_REGISTER(PHY_SLMT);
1882 	AR5K_PRINT_REGISTER(PHY_SCAL);
1883 	AR5K_PRINT_REGISTER(PHY_RX_DELAY);
1884 	AR5K_PRINT_REGISTER(PHY_IQ);
1885 	AR5K_PRINT_REGISTER(PHY_PAPD_PROBE);
1886 	AR5K_PRINT_REGISTER(PHY_TXPOWER_RATE1);
1887 	AR5K_PRINT_REGISTER(PHY_TXPOWER_RATE2);
1888 	AR5K_PRINT_REGISTER(PHY_FC);
1889 	AR5K_PRINT_REGISTER(PHY_RADAR);
1890 	AR5K_PRINT_REGISTER(PHY_ANT_SWITCH_TABLE_0);
1891 	AR5K_PRINT_REGISTER(PHY_ANT_SWITCH_TABLE_1);
1892 	printf("\n");
1893 #endif
1894 }
1895 
1896 HAL_BOOL
1897 ar5k_ar5212_get_diag_state(struct ath_hal *hal, int id, void **device,
1898     u_int *size)
1899 {
1900 	/*
1901 	 * We'll ignore this right now. This seems to be some kind of an obscure
1902 	 * debugging interface for the binary-only HAL.
1903 	 */
1904 	return (AH_FALSE);
1905 }
1906 
1907 void
1908 ar5k_ar5212_get_lladdr(struct ath_hal *hal, u_int8_t *mac)
1909 {
1910 	bcopy(hal->ah_sta_id, mac, IEEE80211_ADDR_LEN);
1911 }
1912 
1913 HAL_BOOL
1914 ar5k_ar5212_set_lladdr(struct ath_hal *hal, const u_int8_t *mac)
1915 {
1916 	u_int32_t low_id, high_id;
1917 
1918 	/* Set new station ID */
1919 	bcopy(mac, hal->ah_sta_id, IEEE80211_ADDR_LEN);
1920 
1921 	low_id = AR5K_LOW_ID(mac);
1922 	high_id = 0x0000ffff & AR5K_HIGH_ID(mac);
1923 
1924 	AR5K_REG_WRITE(AR5K_AR5212_STA_ID0, low_id);
1925 	AR5K_REG_WRITE(AR5K_AR5212_STA_ID1, high_id);
1926 
1927 	return (AH_TRUE);
1928 }
1929 
1930 HAL_BOOL
1931 ar5k_ar5212_set_regdomain(struct ath_hal *hal, u_int16_t regdomain,
1932     HAL_STATUS *status)
1933 {
1934 	ieee80211_regdomain_t ieee_regdomain;
1935 
1936 	ieee_regdomain = ar5k_regdomain_to_ieee(regdomain);
1937 
1938 	if (ar5k_eeprom_regulation_domain(hal, AH_TRUE,
1939 		&ieee_regdomain) == AH_TRUE) {
1940 		*status = HAL_OK;
1941 		return (AH_TRUE);
1942 	}
1943 
1944 	*status = EIO;
1945 
1946 	return (AH_FALSE);
1947 }
1948 
1949 void
1950 ar5k_ar5212_set_ledstate(struct ath_hal *hal, HAL_LED_STATE state)
1951 {
1952 	u_int32_t led;
1953 
1954 	AR5K_REG_DISABLE_BITS(AR5K_AR5212_PCICFG,
1955 	    AR5K_AR5212_PCICFG_LEDMODE |  AR5K_AR5212_PCICFG_LED);
1956 
1957 	/*
1958 	 * Some blinking values, define at your wish
1959 	 */
1960 	switch (state) {
1961 	case IEEE80211_S_SCAN:
1962 	case IEEE80211_S_AUTH:
1963 		led = AR5K_AR5212_PCICFG_LEDMODE_PROP |
1964 		    AR5K_AR5212_PCICFG_LED_PEND;
1965 		break;
1966 
1967 	case IEEE80211_S_INIT:
1968 		led = AR5K_AR5212_PCICFG_LEDMODE_PROP |
1969 		    AR5K_AR5212_PCICFG_LED_NONE;
1970 		break;
1971 
1972 	case IEEE80211_S_ASSOC:
1973 	case IEEE80211_S_RUN:
1974 		led = AR5K_AR5212_PCICFG_LEDMODE_PROP |
1975 		    AR5K_AR5212_PCICFG_LED_ASSOC;
1976 		break;
1977 
1978 	default:
1979 		led = AR5K_AR5212_PCICFG_LEDMODE_PROM |
1980 		    AR5K_AR5212_PCICFG_LED_NONE;
1981 		break;
1982 	}
1983 
1984 	AR5K_REG_ENABLE_BITS(AR5K_AR5212_PCICFG, led);
1985 }
1986 
1987 void
1988 ar5k_ar5212_set_associd(struct ath_hal *hal, const u_int8_t *bssid,
1989     u_int16_t assoc_id, u_int16_t tim_offset)
1990 {
1991 	u_int32_t low_id, high_id;
1992 
1993 	/*
1994 	 * Set simple BSSID mask
1995 	 */
1996 	AR5K_REG_WRITE(AR5K_AR5212_BSS_IDM0, 0xfffffff);
1997 	AR5K_REG_WRITE(AR5K_AR5212_BSS_IDM1, 0xfffffff);
1998 
1999 	/*
2000 	 * Set BSSID which triggers the "SME Join" operation
2001 	 */
2002 	low_id = AR5K_LOW_ID(bssid);
2003 	high_id = AR5K_HIGH_ID(bssid);
2004 	AR5K_REG_WRITE(AR5K_AR5212_BSS_ID0, low_id);
2005 	AR5K_REG_WRITE(AR5K_AR5212_BSS_ID1, high_id |
2006 	    ((assoc_id & 0x3fff) << AR5K_AR5212_BSS_ID1_AID_S));
2007 	bcopy(bssid, &hal->ah_bssid, IEEE80211_ADDR_LEN);
2008 
2009 	if (assoc_id == 0) {
2010 		ar5k_ar5212_disable_pspoll(hal);
2011 		return;
2012 	}
2013 
2014 	AR5K_REG_WRITE(AR5K_AR5212_BEACON,
2015 	    (AR5K_REG_READ(AR5K_AR5212_BEACON) &
2016 	    ~AR5K_AR5212_BEACON_TIM) |
2017 	    (((tim_offset ? tim_offset + 4 : 0) <<
2018 	    AR5K_AR5212_BEACON_TIM_S) &
2019 	    AR5K_AR5212_BEACON_TIM));
2020 
2021 	ar5k_ar5212_enable_pspoll(hal, NULL, 0);
2022 }
2023 
2024 HAL_BOOL
2025 ar5k_ar5212_set_bssid_mask(struct ath_hal *hal, const u_int8_t* mask)
2026 {
2027 	u_int32_t low_id, high_id;
2028 
2029 	low_id = AR5K_LOW_ID(mask);
2030 	high_id = 0x0000ffff & AR5K_HIGH_ID(mask);
2031 
2032 	AR5K_REG_WRITE(AR5K_AR5212_BSS_IDM0, low_id);
2033 	AR5K_REG_WRITE(AR5K_AR5212_BSS_IDM1, high_id);
2034 
2035 	return (AH_TRUE);
2036 }
2037 
2038 HAL_BOOL
2039 ar5k_ar5212_set_gpio_output(struct ath_hal *hal, u_int32_t gpio)
2040 {
2041 	if (gpio > AR5K_AR5212_NUM_GPIO)
2042 		return (AH_FALSE);
2043 
2044 	AR5K_REG_WRITE(AR5K_AR5212_GPIOCR,
2045 	    (AR5K_REG_READ(AR5K_AR5212_GPIOCR) &~ AR5K_AR5212_GPIOCR_ALL(gpio))
2046 	    | AR5K_AR5212_GPIOCR_ALL(gpio));
2047 
2048 	return (AH_TRUE);
2049 }
2050 
2051 HAL_BOOL
2052 ar5k_ar5212_set_gpio_input(struct ath_hal *hal, u_int32_t gpio)
2053 {
2054 	if (gpio > AR5K_AR5212_NUM_GPIO)
2055 		return (AH_FALSE);
2056 
2057 	AR5K_REG_WRITE(AR5K_AR5212_GPIOCR,
2058 	    (AR5K_REG_READ(AR5K_AR5212_GPIOCR) &~ AR5K_AR5212_GPIOCR_ALL(gpio))
2059 	    | AR5K_AR5212_GPIOCR_NONE(gpio));
2060 
2061 	return (AH_TRUE);
2062 }
2063 
2064 u_int32_t
2065 ar5k_ar5212_get_gpio(struct ath_hal *hal, u_int32_t gpio)
2066 {
2067 	if (gpio > AR5K_AR5212_NUM_GPIO)
2068 		return (0xffffffff);
2069 
2070 	/* GPIO input magic */
2071 	return (((AR5K_REG_READ(AR5K_AR5212_GPIODI) &
2072 	    AR5K_AR5212_GPIODI_M) >> gpio) & 0x1);
2073 }
2074 
2075 HAL_BOOL
2076 ar5k_ar5212_set_gpio(struct ath_hal *hal, u_int32_t gpio, u_int32_t val)
2077 {
2078 	u_int32_t data;
2079 
2080 	if (gpio > AR5K_AR5212_NUM_GPIO)
2081 		return (0xffffffff);
2082 
2083 	/* GPIO output magic */
2084 	data =  AR5K_REG_READ(AR5K_AR5212_GPIODO);
2085 
2086 	data &= ~(1 << gpio);
2087 	data |= (val&1) << gpio;
2088 
2089 	AR5K_REG_WRITE(AR5K_AR5212_GPIODO, data);
2090 
2091 	return (AH_TRUE);
2092 }
2093 
2094 void
2095 ar5k_ar5212_set_gpio_intr(struct ath_hal *hal, u_int gpio,
2096     u_int32_t interrupt_level)
2097 {
2098 	u_int32_t data;
2099 
2100 	if (gpio > AR5K_AR5212_NUM_GPIO)
2101 		return;
2102 
2103 	/*
2104 	 * Set the GPIO interrupt
2105 	 */
2106 	data = (AR5K_REG_READ(AR5K_AR5212_GPIOCR) &
2107 	    ~(AR5K_AR5212_GPIOCR_INT_SEL(gpio) | AR5K_AR5212_GPIOCR_INT_SELH |
2108 	    AR5K_AR5212_GPIOCR_INT_ENA | AR5K_AR5212_GPIOCR_ALL(gpio))) |
2109 	    (AR5K_AR5212_GPIOCR_INT_SEL(gpio) | AR5K_AR5212_GPIOCR_INT_ENA);
2110 
2111 	AR5K_REG_WRITE(AR5K_AR5212_GPIOCR,
2112 	    interrupt_level ? data : (data | AR5K_AR5212_GPIOCR_INT_SELH));
2113 
2114 	hal->ah_imr |= AR5K_AR5212_PIMR_GPIO;
2115 
2116 	/* Enable GPIO interrupts */
2117 	AR5K_REG_ENABLE_BITS(AR5K_AR5212_PIMR, AR5K_AR5212_PIMR_GPIO);
2118 }
2119 
2120 u_int32_t
2121 ar5k_ar5212_get_tsf32(struct ath_hal *hal)
2122 {
2123 	return (AR5K_REG_READ(AR5K_AR5212_TSF_L32));
2124 }
2125 
2126 u_int64_t
2127 ar5k_ar5212_get_tsf64(struct ath_hal *hal)
2128 {
2129 	u_int64_t tsf = AR5K_REG_READ(AR5K_AR5212_TSF_U32);
2130 
2131 	return (AR5K_REG_READ(AR5K_AR5212_TSF_L32) | (tsf << 32));
2132 }
2133 
2134 void
2135 ar5k_ar5212_reset_tsf(struct ath_hal *hal)
2136 {
2137 	AR5K_REG_ENABLE_BITS(AR5K_AR5212_BEACON,
2138 	    AR5K_AR5212_BEACON_RESET_TSF);
2139 }
2140 
2141 u_int16_t
2142 ar5k_ar5212_get_regdomain(struct ath_hal *hal)
2143 {
2144 	return (ar5k_get_regdomain(hal));
2145 }
2146 
2147 HAL_BOOL
2148 ar5k_ar5212_detect_card_present(struct ath_hal *hal)
2149 {
2150 	u_int16_t magic;
2151 
2152 	/*
2153 	 * Checking the EEPROM's magic value could be an indication
2154 	 * if the card is still present. I didn't find another suitable
2155 	 * way to do this.
2156 	 */
2157 	if (ar5k_ar5212_eeprom_read(hal, AR5K_EEPROM_MAGIC, &magic) != 0)
2158 		return (AH_FALSE);
2159 
2160 	return (magic == AR5K_EEPROM_MAGIC_VALUE ? AH_TRUE : AH_FALSE);
2161 }
2162 
2163 void
2164 ar5k_ar5212_update_mib_counters(struct ath_hal *hal, HAL_MIB_STATS *statistics)
2165 {
2166 	/* Read-And-Clear */
2167 	statistics->ackrcv_bad += AR5K_REG_READ(AR5K_AR5212_ACK_FAIL);
2168 	statistics->rts_bad += AR5K_REG_READ(AR5K_AR5212_RTS_FAIL);
2169 	statistics->rts_good += AR5K_REG_READ(AR5K_AR5212_RTS_OK);
2170 	statistics->fcs_bad += AR5K_REG_READ(AR5K_AR5212_FCS_FAIL);
2171 	statistics->beacons += AR5K_REG_READ(AR5K_AR5212_BEACON_CNT);
2172 
2173 	/* Reset profile count registers */
2174 	AR5K_REG_WRITE(AR5K_AR5212_PROFCNT_TX, 0);
2175 	AR5K_REG_WRITE(AR5K_AR5212_PROFCNT_RX, 0);
2176 	AR5K_REG_WRITE(AR5K_AR5212_PROFCNT_RXCLR, 0);
2177 	AR5K_REG_WRITE(AR5K_AR5212_PROFCNT_CYCLE, 0);
2178 }
2179 
2180 HAL_RFGAIN
2181 ar5k_ar5212_get_rf_gain(struct ath_hal *hal)
2182 {
2183 	u_int32_t data, type;
2184 
2185 	if ((hal->ah_rf_banks == NULL) || (!hal->ah_gain.g_active))
2186 		return (HAL_RFGAIN_INACTIVE);
2187 
2188 	if (hal->ah_rf_gain != HAL_RFGAIN_READ_REQUESTED)
2189 		goto done;
2190 
2191 	data = AR5K_REG_READ(AR5K_AR5212_PHY_PAPD_PROBE);
2192 
2193 	if (!(data & AR5K_AR5212_PHY_PAPD_PROBE_TX_NEXT)) {
2194 		hal->ah_gain.g_current =
2195 		    data >> AR5K_AR5212_PHY_PAPD_PROBE_GAINF_S;
2196 		type = AR5K_REG_MS(data, AR5K_AR5212_PHY_PAPD_PROBE_TYPE);
2197 
2198 		if (type == AR5K_AR5212_PHY_PAPD_PROBE_TYPE_CCK)
2199 			hal->ah_gain.g_current += AR5K_GAIN_CCK_PROBE_CORR;
2200 
2201 		if (hal->ah_radio >= AR5K_AR5112) {
2202 			ar5k_rfregs_gainf_corr(hal);
2203 			hal->ah_gain.g_current =
2204 			    hal->ah_gain.g_current >= hal->ah_gain.g_f_corr ?
2205 			    (hal->ah_gain.g_current - hal->ah_gain.g_f_corr) :
2206 			    0;
2207 		}
2208 
2209 		if (ar5k_rfregs_gain_readback(hal) &&
2210 		    AR5K_GAIN_CHECK_ADJUST(&hal->ah_gain) &&
2211 		    ar5k_rfregs_gain_adjust(hal))
2212 			hal->ah_rf_gain = HAL_RFGAIN_NEED_CHANGE;
2213 	}
2214 
2215  done:
2216 	return (hal->ah_rf_gain);
2217 }
2218 
2219 HAL_BOOL
2220 ar5k_ar5212_set_slot_time(struct ath_hal *hal, u_int slot_time)
2221 {
2222 	if (slot_time < HAL_SLOT_TIME_9 || slot_time > HAL_SLOT_TIME_MAX)
2223 		return (AH_FALSE);
2224 
2225 	AR5K_REG_WRITE(AR5K_AR5212_DCU_GBL_IFS_SLOT, slot_time);
2226 
2227 	return (AH_TRUE);
2228 }
2229 
2230 u_int
2231 ar5k_ar5212_get_slot_time(struct ath_hal *hal)
2232 {
2233 	return (AR5K_REG_READ(AR5K_AR5212_DCU_GBL_IFS_SLOT) & 0xffff);
2234 }
2235 
2236 HAL_BOOL
2237 ar5k_ar5212_set_ack_timeout(struct ath_hal *hal, u_int timeout)
2238 {
2239 	if (ar5k_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_AR5212_TIME_OUT_ACK),
2240 	    hal->ah_turbo) <= timeout)
2241 		return (AH_FALSE);
2242 
2243 	AR5K_REG_WRITE_BITS(AR5K_AR5212_TIME_OUT, AR5K_AR5212_TIME_OUT_ACK,
2244 	    ar5k_htoclock(timeout, hal->ah_turbo));
2245 
2246 	return (AH_TRUE);
2247 }
2248 
2249 u_int
2250 ar5k_ar5212_get_ack_timeout(struct ath_hal *hal)
2251 {
2252 	return (ar5k_clocktoh(AR5K_REG_MS(AR5K_REG_READ(AR5K_AR5212_TIME_OUT),
2253 	    AR5K_AR5212_TIME_OUT_ACK), hal->ah_turbo));
2254 }
2255 
2256 HAL_BOOL
2257 ar5k_ar5212_set_cts_timeout(struct ath_hal *hal, u_int timeout)
2258 {
2259 	if (ar5k_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_AR5212_TIME_OUT_CTS),
2260 	    hal->ah_turbo) <= timeout)
2261 		return (AH_FALSE);
2262 
2263 	AR5K_REG_WRITE_BITS(AR5K_AR5212_TIME_OUT, AR5K_AR5212_TIME_OUT_CTS,
2264 	    ar5k_htoclock(timeout, hal->ah_turbo));
2265 
2266 	return (AH_TRUE);
2267 }
2268 
2269 u_int
2270 ar5k_ar5212_get_cts_timeout(struct ath_hal *hal)
2271 {
2272 	return (ar5k_clocktoh(AR5K_REG_MS(AR5K_REG_READ(AR5K_AR5212_TIME_OUT),
2273 	    AR5K_AR5212_TIME_OUT_CTS), hal->ah_turbo));
2274 }
2275 
2276 /*
2277  * Key table (WEP) functions
2278  */
2279 
2280 HAL_BOOL
2281 ar5k_ar5212_is_cipher_supported(struct ath_hal *hal, HAL_CIPHER cipher)
2282 {
2283 	/*
2284 	 * The AR5212 only supports WEP
2285 	 */
2286 	if (cipher == HAL_CIPHER_WEP)
2287 		return (AH_TRUE);
2288 
2289 	return (AH_FALSE);
2290 }
2291 
2292 u_int32_t
2293 ar5k_ar5212_get_keycache_size(struct ath_hal *hal)
2294 {
2295 	return (AR5K_AR5212_KEYCACHE_SIZE);
2296 }
2297 
2298 HAL_BOOL
2299 ar5k_ar5212_reset_key(struct ath_hal *hal, u_int16_t entry)
2300 {
2301 	int i;
2302 
2303 	AR5K_ASSERT_ENTRY(entry, AR5K_AR5212_KEYTABLE_SIZE);
2304 
2305 	for (i = 0; i < AR5K_AR5212_KEYCACHE_SIZE; i++)
2306 		AR5K_REG_WRITE(AR5K_AR5212_KEYTABLE_OFF(entry, i), 0);
2307 
2308 	/* Set NULL encryption */
2309 	AR5K_REG_WRITE(AR5K_AR5212_KEYTABLE_TYPE(entry),
2310 	    AR5K_AR5212_KEYTABLE_TYPE_NULL);
2311 
2312 	return (AH_FALSE);
2313 }
2314 
2315 HAL_BOOL
2316 ar5k_ar5212_is_key_valid(struct ath_hal *hal, u_int16_t entry)
2317 {
2318 	AR5K_ASSERT_ENTRY(entry, AR5K_AR5212_KEYTABLE_SIZE);
2319 
2320 	/*
2321 	 * Check the validation flag at the end of the entry
2322 	 */
2323 	if (AR5K_REG_READ(AR5K_AR5212_KEYTABLE_MAC1(entry)) &
2324 	    AR5K_AR5212_KEYTABLE_VALID)
2325 		return (AH_TRUE);
2326 
2327 	return (AH_FALSE);
2328 }
2329 
2330 HAL_BOOL
2331 ar5k_ar5212_set_key(struct ath_hal *hal, u_int16_t entry,
2332     const HAL_KEYVAL *keyval, const u_int8_t *mac, int xor_notused)
2333 {
2334 	int i;
2335 	u_int32_t key_v[AR5K_AR5212_KEYCACHE_SIZE - 2];
2336 
2337 	AR5K_ASSERT_ENTRY(entry, AR5K_AR5212_KEYTABLE_SIZE);
2338 
2339 	bzero(&key_v, sizeof(key_v));
2340 
2341 	switch (keyval->wk_len) {
2342 	case AR5K_KEYVAL_LENGTH_40:
2343 		bcopy(keyval->wk_key, &key_v[0], 4);
2344 		bcopy(keyval->wk_key + 4, &key_v[1], 1);
2345 		key_v[5] = AR5K_AR5212_KEYTABLE_TYPE_40;
2346 		break;
2347 
2348 	case AR5K_KEYVAL_LENGTH_104:
2349 		bcopy(keyval->wk_key, &key_v[0], 4);
2350 		bcopy(keyval->wk_key + 4, &key_v[1], 2);
2351 		bcopy(keyval->wk_key + 6, &key_v[2], 4);
2352 		bcopy(keyval->wk_key + 10, &key_v[3], 2);
2353 		bcopy(keyval->wk_key + 12, &key_v[4], 1);
2354 		key_v[5] = AR5K_AR5212_KEYTABLE_TYPE_104;
2355 		break;
2356 
2357 	case AR5K_KEYVAL_LENGTH_128:
2358 		bcopy(keyval->wk_key, &key_v[0], 4);
2359 		bcopy(keyval->wk_key + 4, &key_v[1], 2);
2360 		bcopy(keyval->wk_key + 6, &key_v[2], 4);
2361 		bcopy(keyval->wk_key + 10, &key_v[3], 2);
2362 		bcopy(keyval->wk_key + 12, &key_v[4], 4);
2363 		key_v[5] = AR5K_AR5212_KEYTABLE_TYPE_128;
2364 		break;
2365 
2366 	default:
2367 		/* Unsupported key length (not WEP40/104/128) */
2368 		return (AH_FALSE);
2369 	}
2370 
2371 	for (i = 0; i < nitems(key_v); i++)
2372 		AR5K_REG_WRITE(AR5K_AR5212_KEYTABLE_OFF(entry, i), key_v[i]);
2373 
2374 	return (ar5k_ar5212_set_key_lladdr(hal, entry, mac));
2375 }
2376 
2377 HAL_BOOL
2378 ar5k_ar5212_set_key_lladdr(struct ath_hal *hal, u_int16_t entry,
2379     const u_int8_t *mac)
2380 {
2381 	u_int32_t low_id, high_id;
2382 	const u_int8_t *mac_v;
2383 
2384 	/*
2385 	 * Invalid entry (key table overflow)
2386 	 */
2387 	AR5K_ASSERT_ENTRY(entry, AR5K_AR5212_KEYTABLE_SIZE);
2388 
2389 	/* MAC may be NULL if it's a broadcast key */
2390 	mac_v = mac == NULL ? etherbroadcastaddr : mac;
2391 
2392 	low_id = AR5K_LOW_ID(mac_v);
2393 	high_id = AR5K_HIGH_ID(mac_v) | AR5K_AR5212_KEYTABLE_VALID;
2394 
2395 	AR5K_REG_WRITE(AR5K_AR5212_KEYTABLE_MAC0(entry), low_id);
2396 	AR5K_REG_WRITE(AR5K_AR5212_KEYTABLE_MAC1(entry), high_id);
2397 
2398 	return (AH_TRUE);
2399 }
2400 
2401 HAL_BOOL
2402 ar5k_ar5212_softcrypto(struct ath_hal *hal, HAL_BOOL enable)
2403 {
2404 	u_int32_t bits;
2405 	int i;
2406 
2407 	bits = AR5K_AR5212_DIAG_SW_DIS_ENC | AR5K_AR5212_DIAG_SW_DIS_DEC;
2408 	if (enable == AH_TRUE) {
2409 		/* Disable the hardware crypto engine */
2410 		AR5K_REG_ENABLE_BITS(AR5K_AR5212_DIAG_SW, bits);
2411 	} else {
2412 		/* Enable the hardware crypto engine */
2413 		AR5K_REG_DISABLE_BITS(AR5K_AR5212_DIAG_SW, bits);
2414 	}
2415 
2416 	/* Reset the key cache */
2417 	for (i = 0; i < AR5K_AR5212_KEYTABLE_SIZE; i++)
2418 		ar5k_ar5212_reset_key(hal, i);
2419 
2420 	return (AH_TRUE);
2421 }
2422 
2423 /*
2424  * Power management functions
2425  */
2426 
2427 HAL_BOOL
2428 ar5k_ar5212_set_power(struct ath_hal *hal, HAL_POWER_MODE mode,
2429     HAL_BOOL set_chip, u_int16_t sleep_duration)
2430 {
2431 	u_int32_t staid;
2432 	int i;
2433 
2434 	staid = AR5K_REG_READ(AR5K_AR5212_STA_ID1);
2435 
2436 	switch (mode) {
2437 	case HAL_PM_AUTO:
2438 		staid &= ~AR5K_AR5212_STA_ID1_DEFAULT_ANTENNA;
2439 		/* FALLTHROUGH */
2440 	case HAL_PM_NETWORK_SLEEP:
2441 		if (set_chip == AH_TRUE) {
2442 			AR5K_REG_WRITE(AR5K_AR5212_SCR,
2443 			    AR5K_AR5212_SCR_SLE | sleep_duration);
2444 		}
2445 		staid |= AR5K_AR5212_STA_ID1_PWR_SV;
2446 		break;
2447 
2448 	case HAL_PM_FULL_SLEEP:
2449 		if (set_chip == AH_TRUE) {
2450 			AR5K_REG_WRITE(AR5K_AR5212_SCR,
2451 			    AR5K_AR5212_SCR_SLE_SLP);
2452 		}
2453 		staid |= AR5K_AR5212_STA_ID1_PWR_SV;
2454 		break;
2455 
2456 	case HAL_PM_AWAKE:
2457 		if (set_chip == AH_FALSE)
2458 			goto commit;
2459 
2460 		AR5K_REG_WRITE(AR5K_AR5212_SCR, AR5K_AR5212_SCR_SLE_WAKE);
2461 
2462 		for (i = 5000; i > 0; i--) {
2463 			/* Check if the AR5212 did wake up */
2464 			if ((AR5K_REG_READ(AR5K_AR5212_PCICFG) &
2465 			    AR5K_AR5212_PCICFG_SPWR_DN) == 0)
2466 				break;
2467 
2468 			/* Wait a bit and retry */
2469 			AR5K_DELAY(200);
2470 			AR5K_REG_WRITE(AR5K_AR5212_SCR,
2471 			    AR5K_AR5212_SCR_SLE_WAKE);
2472 		}
2473 
2474 		/* Fail if the AR5212 didn't wake up */
2475 		if (i <= 0)
2476 			return (AH_FALSE);
2477 
2478 		staid &= ~AR5K_AR5212_STA_ID1_PWR_SV;
2479 		break;
2480 
2481 	default:
2482 		return (AH_FALSE);
2483 	}
2484 
2485  commit:
2486 	hal->ah_power_mode = mode;
2487 
2488 	AR5K_REG_WRITE(AR5K_AR5212_STA_ID1, staid);
2489 
2490 	return (AH_TRUE);
2491 }
2492 
2493 HAL_POWER_MODE
2494 ar5k_ar5212_get_power_mode(struct ath_hal *hal)
2495 {
2496 	return (hal->ah_power_mode);
2497 }
2498 
2499 HAL_BOOL
2500 ar5k_ar5212_query_pspoll_support(struct ath_hal *hal)
2501 {
2502 	/* nope */
2503 	return (AH_FALSE);
2504 }
2505 
2506 HAL_BOOL
2507 ar5k_ar5212_init_pspoll(struct ath_hal *hal)
2508 {
2509 	/*
2510 	 * Not used on the AR5212
2511 	 */
2512 	return (AH_FALSE);
2513 }
2514 
2515 HAL_BOOL
2516 ar5k_ar5212_enable_pspoll(struct ath_hal *hal, u_int8_t *bssid,
2517     u_int16_t assoc_id)
2518 {
2519 	return (AH_FALSE);
2520 }
2521 
2522 HAL_BOOL
2523 ar5k_ar5212_disable_pspoll(struct ath_hal *hal)
2524 {
2525 	return (AH_FALSE);
2526 }
2527 
2528 /*
2529  * Beacon functions
2530  */
2531 
2532 void
2533 ar5k_ar5212_init_beacon(struct ath_hal *hal, u_int32_t next_beacon,
2534     u_int32_t interval)
2535 {
2536 	u_int32_t timer1, timer2, timer3;
2537 
2538 	/*
2539 	 * Set the additional timers by mode
2540 	 */
2541 	switch (hal->ah_op_mode) {
2542 	case HAL_M_STA:
2543 		timer1 = 0x0000ffff;
2544 		timer2 = 0x0007ffff;
2545 		break;
2546 
2547 	default:
2548 		timer1 = (next_beacon - AR5K_TUNE_DMA_BEACON_RESP) <<
2549 		    0x00000003;
2550 		timer2 = (next_beacon - AR5K_TUNE_SW_BEACON_RESP) <<
2551 		    0x00000003;
2552 	}
2553 
2554 	timer3 = next_beacon +
2555 	    (hal->ah_atim_window ? hal->ah_atim_window : 1);
2556 
2557 	/*
2558 	 * Enable all timers and set the beacon register
2559 	 * (next beacon, DMA beacon, software beacon, ATIM window time)
2560 	 */
2561 	AR5K_REG_WRITE(AR5K_AR5212_TIMER0, next_beacon);
2562 	AR5K_REG_WRITE(AR5K_AR5212_TIMER1, timer1);
2563 	AR5K_REG_WRITE(AR5K_AR5212_TIMER2, timer2);
2564 	AR5K_REG_WRITE(AR5K_AR5212_TIMER3, timer3);
2565 
2566 	AR5K_REG_WRITE(AR5K_AR5212_BEACON, interval &
2567 	    (AR5K_AR5212_BEACON_PERIOD | AR5K_AR5212_BEACON_RESET_TSF |
2568 	    AR5K_AR5212_BEACON_ENABLE));
2569 }
2570 
2571 void
2572 ar5k_ar5212_set_beacon_timers(struct ath_hal *hal,
2573     const HAL_BEACON_STATE *state, u_int32_t tsf, u_int32_t dtim_count,
2574     u_int32_t cfp_count)
2575 {
2576 	u_int32_t cfp_period, next_cfp, dtim, interval, next_beacon;
2577 
2578 	/* Return on an invalid beacon state */
2579 	if (state->bs_interval < 1)
2580 		return;
2581 
2582 	interval = state->bs_intval;
2583 	dtim = state->bs_dtimperiod;
2584 
2585 	/*
2586 	 * PCF support?
2587 	 */
2588 	if (state->bs_cfp_period > 0) {
2589 		/* Enable CFP mode and set the CFP and timer registers */
2590 		cfp_period = state->bs_cfp_period * state->bs_dtim_period *
2591 		    state->bs_interval;
2592 		next_cfp = (cfp_count * state->bs_dtim_period + dtim_count) *
2593 		    state->bs_interval;
2594 
2595 		AR5K_REG_ENABLE_BITS(AR5K_AR5212_STA_ID1,
2596 		    AR5K_AR5212_STA_ID1_PCF);
2597 		AR5K_REG_WRITE(AR5K_AR5212_CFP_PERIOD, cfp_period);
2598 		AR5K_REG_WRITE(AR5K_AR5212_CFP_DUR, state->bs_cfp_max_duration);
2599 		AR5K_REG_WRITE(AR5K_AR5212_TIMER2,
2600 		    (tsf + (next_cfp == 0 ? cfp_period : next_cfp)) << 3);
2601 	} else {
2602 		/* Disable PCF mode */
2603 		AR5K_REG_DISABLE_BITS(AR5K_AR5212_STA_ID1,
2604 		    AR5K_AR5212_STA_ID1_PCF);
2605 	}
2606 
2607 	/*
2608 	 * Enable the beacon timer register
2609 	 */
2610 	AR5K_REG_WRITE(AR5K_AR5212_TIMER0, state->bs_next_beacon);
2611 
2612 	/*
2613 	 * Start the beacon timers
2614 	 */
2615 	AR5K_REG_WRITE(AR5K_AR5212_BEACON,
2616 	    (AR5K_REG_READ(AR5K_AR5212_BEACON) &~
2617 	    (AR5K_AR5212_BEACON_PERIOD | AR5K_AR5212_BEACON_TIM)) |
2618 	    AR5K_REG_SM(state->bs_tim_offset ? state->bs_tim_offset + 4 : 0,
2619 	    AR5K_AR5212_BEACON_TIM) | AR5K_REG_SM(state->bs_interval,
2620 	    AR5K_AR5212_BEACON_PERIOD));
2621 
2622 	/*
2623 	 * Write new beacon miss threshold, if it appears to be valid
2624 	 */
2625 	if ((AR5K_AR5212_RSSI_THR_BMISS >> AR5K_AR5212_RSSI_THR_BMISS_S) <
2626 	    state->bs_bmiss_threshold)
2627 		return;
2628 
2629 	AR5K_REG_WRITE_BITS(AR5K_AR5212_RSSI_THR_M,
2630 	    AR5K_AR5212_RSSI_THR_BMISS, state->bs_bmiss_threshold);
2631 
2632 	/*
2633 	 * Set sleep registers
2634 	 */
2635 	if ((state->bs_sleepduration > state->bs_interval) &&
2636 	    (roundup(state->bs_sleepduration, interval) ==
2637 	    state->bs_sleepduration))
2638 		interval = state->bs_sleepduration;
2639 
2640 	if (state->bs_sleepduration > dtim &&
2641 	    (dtim == 0 || roundup(state->bs_sleepduration, dtim) ==
2642 	    state->bs_sleepduration))
2643 		dtim = state->bs_sleepduration;
2644 
2645 	if (interval > dtim)
2646 		return;
2647 
2648 	next_beacon = interval == dtim ?
2649 	    state->bs_nextdtim: state->bs_nexttbtt;
2650 
2651 	AR5K_REG_WRITE(AR5K_AR5212_SLEEP0,
2652 	    AR5K_REG_SM((state->bs_nextdtim - 3) << 3,
2653 	    AR5K_AR5212_SLEEP0_NEXT_DTIM) |
2654 	    AR5K_REG_SM(10, AR5K_AR5212_SLEEP0_CABTO) |
2655 	    AR5K_AR5212_SLEEP0_ENH_SLEEP_EN |
2656 	    AR5K_AR5212_SLEEP0_ASSUME_DTIM);
2657 	AR5K_REG_WRITE(AR5K_AR5212_SLEEP1,
2658 	    AR5K_REG_SM((next_beacon - 3) << 3,
2659 	    AR5K_AR5212_SLEEP1_NEXT_TIM) |
2660 	    AR5K_REG_SM(10, AR5K_AR5212_SLEEP1_BEACON_TO));
2661 	AR5K_REG_WRITE(AR5K_AR5212_SLEEP2,
2662 	    AR5K_REG_SM(interval, AR5K_AR5212_SLEEP2_TIM_PER) |
2663 	    AR5K_REG_SM(dtim, AR5K_AR5212_SLEEP2_DTIM_PER));
2664 }
2665 
2666 void
2667 ar5k_ar5212_reset_beacon(struct ath_hal *hal)
2668 {
2669 	/*
2670 	 * Disable beacon timer
2671 	 */
2672 	AR5K_REG_WRITE(AR5K_AR5212_TIMER0, 0);
2673 
2674 	/*
2675 	 * Disable some beacon register values
2676 	 */
2677 	AR5K_REG_DISABLE_BITS(AR5K_AR5212_STA_ID1,
2678 	    AR5K_AR5212_STA_ID1_DEFAULT_ANTENNA | AR5K_AR5212_STA_ID1_PCF);
2679 	AR5K_REG_WRITE(AR5K_AR5212_BEACON, AR5K_AR5212_BEACON_PERIOD);
2680 }
2681 
2682 HAL_BOOL
2683 ar5k_ar5212_wait_for_beacon(struct ath_hal *hal, bus_addr_t phys_addr)
2684 {
2685 	HAL_BOOL ret;
2686 
2687 	/*
2688 	 * Wait for beaconn queue to be done
2689 	 */
2690 	ret = ar5k_register_timeout(hal,
2691 	    AR5K_AR5212_QCU_STS(HAL_TX_QUEUE_ID_BEACON),
2692 	    AR5K_AR5212_QCU_STS_FRMPENDCNT, 0, AH_FALSE);
2693 
2694 	if (AR5K_REG_READ_Q(AR5K_AR5212_QCU_TXE, HAL_TX_QUEUE_ID_BEACON))
2695 		return (AH_FALSE);
2696 
2697 	return (ret);
2698 }
2699 
2700 /*
2701  * Interrupt handling
2702  */
2703 
2704 HAL_BOOL
2705 ar5k_ar5212_is_intr_pending(struct ath_hal *hal)
2706 {
2707 	return (AR5K_REG_READ(AR5K_AR5212_INTPEND) == 0 ? AH_FALSE : AH_TRUE);
2708 }
2709 
2710 HAL_BOOL
2711 ar5k_ar5212_get_isr(struct ath_hal *hal, u_int32_t *interrupt_mask)
2712 {
2713 	u_int32_t data;
2714 
2715 	/*
2716 	 * Read interrupt status from the Read-And-Clear shadow register
2717 	 */
2718 	data = AR5K_REG_READ(AR5K_AR5212_RAC_PISR);
2719 
2720 	/*
2721 	 * Get abstract interrupt mask (HAL-compatible)
2722 	 */
2723 	*interrupt_mask = (data & HAL_INT_COMMON) & hal->ah_imr;
2724 
2725 	if (data == HAL_INT_NOCARD)
2726 		return (AH_FALSE);
2727 
2728 	if (data & (AR5K_AR5212_PISR_RXOK | AR5K_AR5212_PISR_RXERR))
2729 		*interrupt_mask |= HAL_INT_RX;
2730 
2731 	if (data & (AR5K_AR5212_PISR_TXOK | AR5K_AR5212_PISR_TXERR))
2732 		*interrupt_mask |= HAL_INT_TX;
2733 
2734 	if (data & (AR5K_AR5212_PISR_HIUERR))
2735 		*interrupt_mask |= HAL_INT_FATAL;
2736 
2737 	/*
2738 	 * Special interrupt handling (not caught by the driver)
2739 	 */
2740 	if (((*interrupt_mask) & AR5K_AR5212_PISR_RXPHY) &&
2741 	    hal->ah_radar.r_enabled == AH_TRUE)
2742 		ar5k_radar_alert(hal);
2743 
2744 	if (*interrupt_mask == 0)
2745 		AR5K_PRINTF("0x%08x\n", data);
2746 
2747 	return (AH_TRUE);
2748 }
2749 
2750 u_int32_t
2751 ar5k_ar5212_get_intr(struct ath_hal *hal)
2752 {
2753 	/* Return the interrupt mask stored previously */
2754 	return (hal->ah_imr);
2755 }
2756 
2757 HAL_INT
2758 ar5k_ar5212_set_intr(struct ath_hal *hal, HAL_INT new_mask)
2759 {
2760 	HAL_INT old_mask, int_mask;
2761 
2762 	/*
2763 	 * Disable card interrupts to prevent any race conditions
2764 	 * (they will be re-enabled afterwards).
2765 	 */
2766 	AR5K_REG_WRITE(AR5K_AR5212_IER, AR5K_AR5212_IER_DISABLE);
2767 
2768 	old_mask = hal->ah_imr;
2769 
2770 	/*
2771 	 * Add additional, chipset-dependent interrupt mask flags
2772 	 * and write them to the IMR (interrupt mask register).
2773 	 */
2774 	int_mask = new_mask & HAL_INT_COMMON;
2775 
2776 	if (new_mask & HAL_INT_RX)
2777 		int_mask |=
2778 		    AR5K_AR5212_PIMR_RXOK |
2779 		    AR5K_AR5212_PIMR_RXERR |
2780 		    AR5K_AR5212_PIMR_RXORN |
2781 		    AR5K_AR5212_PIMR_RXDESC;
2782 
2783 	if (new_mask & HAL_INT_TX)
2784 		int_mask |=
2785 		    AR5K_AR5212_PIMR_TXOK |
2786 		    AR5K_AR5212_PIMR_TXERR |
2787 		    AR5K_AR5212_PIMR_TXDESC |
2788 		    AR5K_AR5212_PIMR_TXURN;
2789 
2790 	if (new_mask & HAL_INT_FATAL) {
2791 		int_mask |= AR5K_AR5212_PIMR_HIUERR;
2792 		AR5K_REG_ENABLE_BITS(AR5K_AR5212_SIMR2,
2793 		    AR5K_AR5212_SIMR2_MCABT |
2794 		    AR5K_AR5212_SIMR2_SSERR |
2795 		    AR5K_AR5212_SIMR2_DPERR);
2796 	}
2797 
2798 	AR5K_REG_WRITE(AR5K_AR5212_PIMR, int_mask);
2799 
2800 	/* Store new interrupt mask */
2801 	hal->ah_imr = new_mask;
2802 
2803 	/* ..re-enable interrupts */
2804 	AR5K_REG_WRITE(AR5K_AR5212_IER, AR5K_AR5212_IER_ENABLE);
2805 
2806 	return (old_mask);
2807 }
2808 
2809 /*
2810  * Misc internal functions
2811  */
2812 
2813 HAL_BOOL
2814 ar5k_ar5212_get_capabilities(struct ath_hal *hal)
2815 {
2816 	u_int16_t ee_header;
2817 	u_int a, b, g;
2818 
2819 	/* Capabilities stored in the EEPROM */
2820 	ee_header = hal->ah_capabilities.cap_eeprom.ee_header;
2821 
2822 	a = AR5K_EEPROM_HDR_11A(ee_header);
2823 	b = AR5K_EEPROM_HDR_11B(ee_header);
2824 	g = AR5K_EEPROM_HDR_11G(ee_header);
2825 
2826 	/*
2827 	 * If the EEPROM is not reporting any mode, we try 11b.
2828 	 * This might fix a few broken devices with invalid EEPROM.
2829 	 */
2830 	if (!a && !b && !g)
2831 		b = 1;
2832 
2833 	/*
2834 	 * XXX The AR5212 tranceiver supports frequencies from 4920 to 6100GHz
2835 	 * XXX and from 2312 to 2732GHz. There are problems with the current
2836 	 * XXX ieee80211 implementation because the IEEE channel mapping
2837 	 * XXX does not support negative channel numbers (2312MHz is channel
2838 	 * XXX -19). Of course, this doesn't matter because these channels
2839 	 * XXX are out of range but some regulation domains like MKK (Japan)
2840 	 * XXX will support frequencies somewhere around 4.8GHz.
2841 	 */
2842 
2843 	/*
2844 	 * Set radio capabilities
2845 	 */
2846 
2847 	if (a) {
2848 		hal->ah_capabilities.cap_range.range_5ghz_min = 5005; /* 4920 */
2849 		hal->ah_capabilities.cap_range.range_5ghz_max = 6100;
2850 
2851 		/* Set supported modes */
2852 		hal->ah_capabilities.cap_mode =
2853 		    HAL_MODE_11A | HAL_MODE_TURBO | HAL_MODE_XR;
2854 	}
2855 
2856 	/* This chip will support 802.11b if the 2GHz radio is connected */
2857 	if (b || g) {
2858 		hal->ah_capabilities.cap_range.range_2ghz_min = 2412; /* 2312 */
2859 		hal->ah_capabilities.cap_range.range_2ghz_max = 2732;
2860 
2861 		if (b)
2862 			hal->ah_capabilities.cap_mode |= HAL_MODE_11B;
2863 #if 0
2864 		if (g)
2865 			hal->ah_capabilities.cap_mode |= HAL_MODE_11G;
2866 #endif
2867 	}
2868 
2869 	/* GPIO */
2870 	hal->ah_gpio_npins = AR5K_AR5212_NUM_GPIO;
2871 
2872 	/* Set number of supported TX queues */
2873 	hal->ah_capabilities.cap_queues.q_tx_num = AR5K_AR5212_TX_NUM_QUEUES;
2874 
2875 	return (AH_TRUE);
2876 }
2877 
2878 void
2879 ar5k_ar5212_radar_alert(struct ath_hal *hal, HAL_BOOL enable)
2880 {
2881 	/*
2882 	 * Enable radar detection
2883 	 */
2884 	AR5K_REG_WRITE(AR5K_AR5212_IER, AR5K_AR5212_IER_DISABLE);
2885 
2886 	if (enable == AH_TRUE) {
2887 		AR5K_REG_WRITE(AR5K_AR5212_PHY_RADAR,
2888 		    AR5K_AR5212_PHY_RADAR_ENABLE);
2889 		AR5K_REG_ENABLE_BITS(AR5K_AR5212_PIMR,
2890 		    AR5K_AR5212_PIMR_RXPHY);
2891 	} else {
2892 		AR5K_REG_WRITE(AR5K_AR5212_PHY_RADAR,
2893 		    AR5K_AR5212_PHY_RADAR_DISABLE);
2894 		AR5K_REG_DISABLE_BITS(AR5K_AR5212_PIMR,
2895 		    AR5K_AR5212_PIMR_RXPHY);
2896 	}
2897 
2898 	AR5K_REG_WRITE(AR5K_AR5212_IER, AR5K_AR5212_IER_ENABLE);
2899 }
2900 
2901 /*
2902  * EEPROM access functions
2903  */
2904 
2905 HAL_BOOL
2906 ar5k_ar5212_eeprom_is_busy(struct ath_hal *hal)
2907 {
2908 	return (AR5K_REG_READ(AR5K_AR5212_CFG) & AR5K_AR5212_CFG_EEBS ?
2909 	    AH_TRUE : AH_FALSE);
2910 }
2911 
2912 int
2913 ar5k_ar5212_eeprom_read(struct ath_hal *hal, u_int32_t offset, u_int16_t *data)
2914 {
2915 	u_int32_t status, i;
2916 
2917 	/*
2918 	 * Initialize EEPROM access
2919 	 */
2920 	AR5K_REG_WRITE(AR5K_AR5212_EEPROM_BASE, (u_int8_t)offset);
2921 	AR5K_REG_ENABLE_BITS(AR5K_AR5212_EEPROM_CMD,
2922 	    AR5K_AR5212_EEPROM_CMD_READ);
2923 
2924 	for (i = AR5K_TUNE_REGISTER_TIMEOUT; i > 0; i--) {
2925 		status = AR5K_REG_READ(AR5K_AR5212_EEPROM_STATUS);
2926 		if (status & AR5K_AR5212_EEPROM_STAT_RDDONE) {
2927 			if (status & AR5K_AR5212_EEPROM_STAT_RDERR)
2928 				return (EIO);
2929 			*data = (u_int16_t)
2930 			    (AR5K_REG_READ(AR5K_AR5212_EEPROM_DATA) & 0xffff);
2931 			return (0);
2932 		}
2933 		AR5K_DELAY(15);
2934 	}
2935 
2936 	return (ETIMEDOUT);
2937 }
2938 
2939 int
2940 ar5k_ar5212_eeprom_write(struct ath_hal *hal, u_int32_t offset, u_int16_t data)
2941 {
2942 	u_int32_t status, timeout;
2943 
2944 	/* Enable eeprom access */
2945 	AR5K_REG_ENABLE_BITS(AR5K_AR5212_EEPROM_CMD,
2946 	    AR5K_AR5212_EEPROM_CMD_RESET);
2947 	AR5K_REG_ENABLE_BITS(AR5K_AR5212_EEPROM_CMD,
2948 	    AR5K_AR5212_EEPROM_CMD_WRITE);
2949 
2950 	/*
2951 	 * Prime write pump
2952 	 */
2953 	AR5K_REG_WRITE(AR5K_AR5212_EEPROM_BASE, (u_int8_t)offset - 1);
2954 
2955 	for (timeout = 10000; timeout > 0; timeout--) {
2956 		AR5K_DELAY(1);
2957 		status = AR5K_REG_READ(AR5K_AR5212_EEPROM_STATUS);
2958 		if (status & AR5K_AR5212_EEPROM_STAT_WRDONE) {
2959 			if (status & AR5K_AR5212_EEPROM_STAT_WRERR)
2960 				return (EIO);
2961 			return (0);
2962 		}
2963 	}
2964 
2965 	return (ETIMEDOUT);
2966 }
2967 
2968 /*
2969  * TX power setup
2970  */
2971 
2972 HAL_BOOL
2973 ar5k_ar5212_txpower(struct ath_hal *hal, HAL_CHANNEL *channel, u_int txpower)
2974 {
2975 	HAL_BOOL tpc = hal->ah_txpower.txp_tpc;
2976 	int i;
2977 
2978 	if (txpower > AR5K_TUNE_MAX_TXPOWER) {
2979 		AR5K_PRINTF("invalid tx power: %u\n", txpower);
2980 		return (AH_FALSE);
2981 	}
2982 
2983 	/* Reset TX power values */
2984 	bzero(&hal->ah_txpower, sizeof(hal->ah_txpower));
2985 	hal->ah_txpower.txp_tpc = tpc;
2986 
2987 	/* Initialize TX power table */
2988 	ar5k_txpower_table(hal, channel, txpower);
2989 
2990 	/*
2991 	 * Write TX power values
2992 	 */
2993 	for (i = 0; i < (AR5K_EEPROM_POWER_TABLE_SIZE / 2); i++) {
2994 		AR5K_REG_WRITE(AR5K_AR5212_PHY_PCDAC_TXPOWER(i),
2995 		    ((((hal->ah_txpower.txp_pcdac[(i << 1) + 1] << 8) | 0xff) &
2996 		    0xffff) << 16) | (((hal->ah_txpower.txp_pcdac[i << 1] << 8)
2997 		    | 0xff) & 0xffff));
2998 	}
2999 
3000 	AR5K_REG_WRITE(AR5K_AR5212_PHY_TXPOWER_RATE1,
3001 	    AR5K_TXPOWER_OFDM(3, 24) | AR5K_TXPOWER_OFDM(2, 16)
3002 	    | AR5K_TXPOWER_OFDM(1, 8) | AR5K_TXPOWER_OFDM(0, 0));
3003 
3004 	AR5K_REG_WRITE(AR5K_AR5212_PHY_TXPOWER_RATE2,
3005 	    AR5K_TXPOWER_OFDM(7, 24) | AR5K_TXPOWER_OFDM(6, 16)
3006 	    | AR5K_TXPOWER_OFDM(5, 8) | AR5K_TXPOWER_OFDM(4, 0));
3007 
3008 	AR5K_REG_WRITE(AR5K_AR5212_PHY_TXPOWER_RATE3,
3009 	    AR5K_TXPOWER_CCK(10, 24) | AR5K_TXPOWER_CCK(9, 16)
3010 	    | AR5K_TXPOWER_CCK(15, 8) | AR5K_TXPOWER_CCK(8, 0));
3011 
3012 	AR5K_REG_WRITE(AR5K_AR5212_PHY_TXPOWER_RATE4,
3013 	    AR5K_TXPOWER_CCK(14, 24) | AR5K_TXPOWER_CCK(13, 16)
3014 	    | AR5K_TXPOWER_CCK(12, 8) | AR5K_TXPOWER_CCK(11, 0));
3015 
3016 	if (hal->ah_txpower.txp_tpc == AH_TRUE) {
3017 		AR5K_REG_WRITE(AR5K_AR5212_PHY_TXPOWER_RATE_MAX,
3018 		    AR5K_AR5212_PHY_TXPOWER_RATE_MAX_TPC_ENABLE |
3019 		    AR5K_TUNE_MAX_TXPOWER);
3020 	} else {
3021 		AR5K_REG_WRITE(AR5K_AR5212_PHY_TXPOWER_RATE_MAX,
3022 		    AR5K_AR5212_PHY_TXPOWER_RATE_MAX |
3023 		    AR5K_TUNE_MAX_TXPOWER);
3024 	}
3025 
3026 	return (AH_TRUE);
3027 }
3028 
3029 HAL_BOOL
3030 ar5k_ar5212_set_txpower_limit(struct ath_hal *hal, u_int power)
3031 {
3032 	HAL_CHANNEL *channel = &hal->ah_current_channel;
3033 
3034 	AR5K_PRINTF("changing txpower to %d\n", power);
3035 	return (ar5k_ar5212_txpower(hal, channel, power));
3036 }
3037