1e113789bSAdrian Chadd /*
2e113789bSAdrian Chadd * Copyright (c) 2012, 2013 Adrian Chadd <adrian@FreeBSD.org>.
3e113789bSAdrian Chadd *
4e113789bSAdrian Chadd * Permission to use, copy, modify, and/or distribute this software for any
5e113789bSAdrian Chadd * purpose with or without fee is hereby granted, provided that the above
6e113789bSAdrian Chadd * copyright notice and this permission notice appear in all copies.
7e113789bSAdrian Chadd *
8e113789bSAdrian Chadd * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9e113789bSAdrian Chadd * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10e113789bSAdrian Chadd * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11e113789bSAdrian Chadd * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12e113789bSAdrian Chadd * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13e113789bSAdrian Chadd * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14e113789bSAdrian Chadd * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15e113789bSAdrian Chadd */
16e113789bSAdrian Chadd
17e113789bSAdrian Chadd #include "opt_ah.h"
18e113789bSAdrian Chadd
19e113789bSAdrian Chadd #include "ah.h"
20e113789bSAdrian Chadd #include "ah_internal.h"
21e113789bSAdrian Chadd #include "ah_devid.h"
22e113789bSAdrian Chadd #include "ah_desc.h"
23e113789bSAdrian Chadd
24e113789bSAdrian Chadd #include "ar9300.h"
25e113789bSAdrian Chadd #include "ar9300reg.h"
26e113789bSAdrian Chadd #include "ar9300phy.h"
27e113789bSAdrian Chadd #include "ar9300desc.h"
28e113789bSAdrian Chadd
29e113789bSAdrian Chadd #include "ar9300_freebsd.h"
30e113789bSAdrian Chadd
31e113789bSAdrian Chadd #include "ar9300_stub.h"
32e113789bSAdrian Chadd #include "ar9300_stub_funcs.h"
33e113789bSAdrian Chadd
34e113789bSAdrian Chadd #define FIX_NOISE_FLOOR 1
35e113789bSAdrian Chadd #define NEXT_TBTT_NOW 5
36e113789bSAdrian Chadd static HAL_BOOL ar9300ClrMulticastFilterIndex(struct ath_hal *ah, uint32_t ix);
37e113789bSAdrian Chadd static HAL_BOOL ar9300SetMulticastFilterIndex(struct ath_hal *ah, uint32_t ix);
38e113789bSAdrian Chadd
39caa918bdSAdrian Chadd static void ar9300_beacon_set_beacon_timers(struct ath_hal *ah,
40caa918bdSAdrian Chadd const HAL_BEACON_TIMERS *bt);
41caa918bdSAdrian Chadd
42e113789bSAdrian Chadd static void
ar9300SetChainMasks(struct ath_hal * ah,uint32_t tx_chainmask,uint32_t rx_chainmask)43e113789bSAdrian Chadd ar9300SetChainMasks(struct ath_hal *ah, uint32_t tx_chainmask,
44e113789bSAdrian Chadd uint32_t rx_chainmask)
45e113789bSAdrian Chadd {
46e113789bSAdrian Chadd
47e113789bSAdrian Chadd AH9300(ah)->ah_tx_chainmask =
48e113789bSAdrian Chadd tx_chainmask & AH_PRIVATE(ah)->ah_caps.halTxChainMask;
49e113789bSAdrian Chadd AH9300(ah)->ah_rx_chainmask =
50e113789bSAdrian Chadd rx_chainmask & AH_PRIVATE(ah)->ah_caps.halRxChainMask;
51e113789bSAdrian Chadd }
52e113789bSAdrian Chadd
53e113789bSAdrian Chadd static u_int
ar9300GetSlotTime(struct ath_hal * ah)54e113789bSAdrian Chadd ar9300GetSlotTime(struct ath_hal *ah)
55e113789bSAdrian Chadd {
56e113789bSAdrian Chadd u_int clks = OS_REG_READ(ah, AR_D_GBL_IFS_SLOT) & 0xffff;
57e113789bSAdrian Chadd return (ath_hal_mac_usec(ah, clks)); /* convert from system clocks */
58e113789bSAdrian Chadd }
59e113789bSAdrian Chadd
60e113789bSAdrian Chadd static HAL_BOOL
ar9300_freebsd_set_tx_power_limit(struct ath_hal * ah,uint32_t limit)61e113789bSAdrian Chadd ar9300_freebsd_set_tx_power_limit(struct ath_hal *ah, uint32_t limit)
62e113789bSAdrian Chadd {
63e113789bSAdrian Chadd return (ar9300_set_tx_power_limit(ah, limit, 0, 0));
64e113789bSAdrian Chadd }
65e113789bSAdrian Chadd
660694aa79SAdrian Chadd static uint64_t
ar9300_get_next_tbtt(struct ath_hal * ah)670694aa79SAdrian Chadd ar9300_get_next_tbtt(struct ath_hal *ah)
680694aa79SAdrian Chadd {
690694aa79SAdrian Chadd return (OS_REG_READ(ah, AR_NEXT_TBTT_TIMER));
700694aa79SAdrian Chadd }
71e113789bSAdrian Chadd
72*bed90bf8SAdrian Chadd static u_int
ar9300_get_nav(struct ath_hal * ah)73*bed90bf8SAdrian Chadd ar9300_get_nav(struct ath_hal *ah)
74*bed90bf8SAdrian Chadd {
75*bed90bf8SAdrian Chadd uint32_t reg;
76*bed90bf8SAdrian Chadd
77*bed90bf8SAdrian Chadd reg = OS_REG_READ(ah, AR_NAV);
78*bed90bf8SAdrian Chadd if (reg == 0xdeadbeef)
79*bed90bf8SAdrian Chadd return 0;
80*bed90bf8SAdrian Chadd return reg;
81*bed90bf8SAdrian Chadd }
82*bed90bf8SAdrian Chadd
83*bed90bf8SAdrian Chadd static void
ar9300_set_nav(struct ath_hal * ah,u_int nav)84*bed90bf8SAdrian Chadd ar9300_set_nav(struct ath_hal *ah, u_int nav)
85*bed90bf8SAdrian Chadd {
86*bed90bf8SAdrian Chadd
87*bed90bf8SAdrian Chadd OS_REG_WRITE(ah, AR_NAV, nav);
88*bed90bf8SAdrian Chadd }
89f5ab408eSAdrian Chadd
90f5ab408eSAdrian Chadd /*
91f5ab408eSAdrian Chadd * TODO: implement the antenna diversity control for AR9485 and
92f5ab408eSAdrian Chadd * other LNA mixing based NICs.
93f5ab408eSAdrian Chadd *
94f5ab408eSAdrian Chadd * For now we'll just go with the HAL default and make these no-ops.
95f5ab408eSAdrian Chadd */
96f5ab408eSAdrian Chadd static HAL_ANT_SETTING
ar9300_freebsd_get_antenna_switch(struct ath_hal * ah)97f5ab408eSAdrian Chadd ar9300_freebsd_get_antenna_switch(struct ath_hal *ah)
98f5ab408eSAdrian Chadd {
99f5ab408eSAdrian Chadd
100f5ab408eSAdrian Chadd return (HAL_ANT_VARIABLE);
101f5ab408eSAdrian Chadd }
102f5ab408eSAdrian Chadd
103f5ab408eSAdrian Chadd static HAL_BOOL
ar9300_freebsd_set_antenna_switch(struct ath_hal * ah,HAL_ANT_SETTING setting)104f5ab408eSAdrian Chadd ar9300_freebsd_set_antenna_switch(struct ath_hal *ah, HAL_ANT_SETTING setting)
105f5ab408eSAdrian Chadd {
106f5ab408eSAdrian Chadd
107f5ab408eSAdrian Chadd return (AH_TRUE);
108f5ab408eSAdrian Chadd }
109f5ab408eSAdrian Chadd
110f5ab408eSAdrian Chadd static u_int
ar9300_freebsd_get_cts_timeout(struct ath_hal * ah)111f5ab408eSAdrian Chadd ar9300_freebsd_get_cts_timeout(struct ath_hal *ah)
112f5ab408eSAdrian Chadd {
113f5ab408eSAdrian Chadd u_int clks = MS(OS_REG_READ(ah, AR_TIME_OUT), AR_TIME_OUT_CTS);
114f5ab408eSAdrian Chadd return ath_hal_mac_usec(ah, clks); /* convert from system clocks */
115f5ab408eSAdrian Chadd }
116f5ab408eSAdrian Chadd
11766b870f3SAdrian Chadd static void
ar9300_freebsd_set_tsf64(struct ath_hal * ah,uint64_t tsf64)11866b870f3SAdrian Chadd ar9300_freebsd_set_tsf64(struct ath_hal *ah, uint64_t tsf64)
11966b870f3SAdrian Chadd {
12066b870f3SAdrian Chadd
12166b870f3SAdrian Chadd /*
12266b870f3SAdrian Chadd * XXX TODO: read ar5416SetTsf64() - we should wait before we do
12366b870f3SAdrian Chadd * this.
12466b870f3SAdrian Chadd */
12566b870f3SAdrian Chadd OS_REG_WRITE(ah, AR_TSF_L32, tsf64 & 0xffffffff);
12666b870f3SAdrian Chadd OS_REG_WRITE(ah, AR_TSF_U32, (tsf64 >> 32) & 0xffffffff);
12766b870f3SAdrian Chadd }
12866b870f3SAdrian Chadd
129c15fdc23SAdrian Chadd /* Flags for pulse_bw_info */
130c15fdc23SAdrian Chadd #define PRI_CH_RADAR_FOUND 0x01
131c15fdc23SAdrian Chadd #define EXT_CH_RADAR_FOUND 0x02
132c15fdc23SAdrian Chadd #define EXT_CH_RADAR_EARLY_FOUND 0x04
133c15fdc23SAdrian Chadd
134c15fdc23SAdrian Chadd static HAL_BOOL
ar9300_freebsd_proc_radar_event(struct ath_hal * ah,struct ath_rx_status * rxs,uint64_t fulltsf,const char * buf,HAL_DFS_EVENT * event)135c15fdc23SAdrian Chadd ar9300_freebsd_proc_radar_event(struct ath_hal *ah, struct ath_rx_status *rxs,
136c15fdc23SAdrian Chadd uint64_t fulltsf, const char *buf, HAL_DFS_EVENT *event)
137c15fdc23SAdrian Chadd {
138c15fdc23SAdrian Chadd HAL_BOOL doDfsExtCh;
139c15fdc23SAdrian Chadd HAL_BOOL doDfsEnhanced;
140c15fdc23SAdrian Chadd HAL_BOOL doDfsCombinedRssi;
141c15fdc23SAdrian Chadd
142c15fdc23SAdrian Chadd uint8_t rssi = 0, ext_rssi = 0;
143c15fdc23SAdrian Chadd uint8_t pulse_bw_info = 0, pulse_length_ext = 0, pulse_length_pri = 0;
144c15fdc23SAdrian Chadd uint32_t dur = 0;
145c15fdc23SAdrian Chadd int pri_found = 1, ext_found = 0;
146c15fdc23SAdrian Chadd int early_ext = 0;
147c15fdc23SAdrian Chadd int is_dc = 0;
148c15fdc23SAdrian Chadd uint16_t datalen; /* length from the RX status field */
149c15fdc23SAdrian Chadd
150c15fdc23SAdrian Chadd /* Check whether the given phy error is a radar event */
151c15fdc23SAdrian Chadd if ((rxs->rs_phyerr != HAL_PHYERR_RADAR) &&
152c15fdc23SAdrian Chadd (rxs->rs_phyerr != HAL_PHYERR_FALSE_RADAR_EXT)) {
153c15fdc23SAdrian Chadd return AH_FALSE;
154c15fdc23SAdrian Chadd }
155c15fdc23SAdrian Chadd
156c15fdc23SAdrian Chadd /* Grab copies of the capabilities; just to make the code clearer */
157c15fdc23SAdrian Chadd doDfsExtCh = AH_PRIVATE(ah)->ah_caps.halExtChanDfsSupport;
158c15fdc23SAdrian Chadd doDfsEnhanced = AH_PRIVATE(ah)->ah_caps.halEnhancedDfsSupport;
159c15fdc23SAdrian Chadd doDfsCombinedRssi = AH_PRIVATE(ah)->ah_caps.halUseCombinedRadarRssi;
160c15fdc23SAdrian Chadd
161c15fdc23SAdrian Chadd datalen = rxs->rs_datalen;
162c15fdc23SAdrian Chadd
163c15fdc23SAdrian Chadd /* If hardware supports it, use combined RSSI, else use chain 0 RSSI */
164c15fdc23SAdrian Chadd if (doDfsCombinedRssi)
165c15fdc23SAdrian Chadd rssi = (uint8_t) rxs->rs_rssi;
166c15fdc23SAdrian Chadd else
167c15fdc23SAdrian Chadd rssi = (uint8_t) rxs->rs_rssi_ctl[0];
168c15fdc23SAdrian Chadd
169c15fdc23SAdrian Chadd /* Set this; but only use it if doDfsExtCh is set */
170c15fdc23SAdrian Chadd ext_rssi = (uint8_t) rxs->rs_rssi_ext[0];
171c15fdc23SAdrian Chadd
172c15fdc23SAdrian Chadd /* Cap it at 0 if the RSSI is a negative number */
173c15fdc23SAdrian Chadd if (rssi & 0x80)
174c15fdc23SAdrian Chadd rssi = 0;
175c15fdc23SAdrian Chadd
176c15fdc23SAdrian Chadd if (ext_rssi & 0x80)
177c15fdc23SAdrian Chadd ext_rssi = 0;
178c15fdc23SAdrian Chadd
179c15fdc23SAdrian Chadd /*
180c15fdc23SAdrian Chadd * Fetch the relevant data from the frame
181c15fdc23SAdrian Chadd */
182c15fdc23SAdrian Chadd if (doDfsExtCh) {
183c15fdc23SAdrian Chadd if (datalen < 3)
184c15fdc23SAdrian Chadd return AH_FALSE;
185c15fdc23SAdrian Chadd
186c15fdc23SAdrian Chadd /* Last three bytes of the frame are of interest */
187c15fdc23SAdrian Chadd pulse_length_pri = *(buf + datalen - 3);
188c15fdc23SAdrian Chadd pulse_length_ext = *(buf + datalen - 2);
189c15fdc23SAdrian Chadd pulse_bw_info = *(buf + datalen - 1);
190c15fdc23SAdrian Chadd HALDEBUG(ah, HAL_DEBUG_DFS, "%s: rssi=%d, ext_rssi=%d, pulse_length_pri=%d,"
191c15fdc23SAdrian Chadd " pulse_length_ext=%d, pulse_bw_info=%x\n",
192c15fdc23SAdrian Chadd __func__, rssi, ext_rssi, pulse_length_pri, pulse_length_ext,
193c15fdc23SAdrian Chadd pulse_bw_info);
194c15fdc23SAdrian Chadd } else {
195c15fdc23SAdrian Chadd /* The pulse width is byte 0 of the data */
196c15fdc23SAdrian Chadd if (datalen >= 1)
197c15fdc23SAdrian Chadd dur = ((uint8_t) buf[0]) & 0xff;
198c15fdc23SAdrian Chadd else
199c15fdc23SAdrian Chadd dur = 0;
200c15fdc23SAdrian Chadd
201c15fdc23SAdrian Chadd if (dur == 0 && rssi == 0) {
202c15fdc23SAdrian Chadd HALDEBUG(ah, HAL_DEBUG_DFS, "%s: dur and rssi are 0\n", __func__);
203c15fdc23SAdrian Chadd return AH_FALSE;
204c15fdc23SAdrian Chadd }
205c15fdc23SAdrian Chadd
206c15fdc23SAdrian Chadd HALDEBUG(ah, HAL_DEBUG_DFS, "%s: rssi=%d, dur=%d\n", __func__, rssi, dur);
207c15fdc23SAdrian Chadd
208c15fdc23SAdrian Chadd /* Single-channel only */
209c15fdc23SAdrian Chadd pri_found = 1;
210c15fdc23SAdrian Chadd ext_found = 0;
211c15fdc23SAdrian Chadd }
212c15fdc23SAdrian Chadd
213c15fdc23SAdrian Chadd /*
214c15fdc23SAdrian Chadd * If doing extended channel data, pulse_bw_info must
215c15fdc23SAdrian Chadd * have one of the flags set.
216c15fdc23SAdrian Chadd */
217c15fdc23SAdrian Chadd if (doDfsExtCh && pulse_bw_info == 0x0)
218c15fdc23SAdrian Chadd return AH_FALSE;
219c15fdc23SAdrian Chadd
220c15fdc23SAdrian Chadd /*
221c15fdc23SAdrian Chadd * If the extended channel data is available, calculate
222c15fdc23SAdrian Chadd * which to pay attention to.
223c15fdc23SAdrian Chadd */
224c15fdc23SAdrian Chadd if (doDfsExtCh) {
225c15fdc23SAdrian Chadd /* If pulse is on DC, take the larger duration of the two */
226c15fdc23SAdrian Chadd if ((pulse_bw_info & EXT_CH_RADAR_FOUND) &&
227c15fdc23SAdrian Chadd (pulse_bw_info & PRI_CH_RADAR_FOUND)) {
228c15fdc23SAdrian Chadd is_dc = 1;
229c15fdc23SAdrian Chadd if (pulse_length_ext > pulse_length_pri) {
230c15fdc23SAdrian Chadd dur = pulse_length_ext;
231c15fdc23SAdrian Chadd pri_found = 0;
232c15fdc23SAdrian Chadd ext_found = 1;
233c15fdc23SAdrian Chadd } else {
234c15fdc23SAdrian Chadd dur = pulse_length_pri;
235c15fdc23SAdrian Chadd pri_found = 1;
236c15fdc23SAdrian Chadd ext_found = 0;
237c15fdc23SAdrian Chadd }
238c15fdc23SAdrian Chadd } else if (pulse_bw_info & EXT_CH_RADAR_EARLY_FOUND) {
239c15fdc23SAdrian Chadd dur = pulse_length_ext;
240c15fdc23SAdrian Chadd pri_found = 0;
241c15fdc23SAdrian Chadd ext_found = 1;
242c15fdc23SAdrian Chadd early_ext = 1;
243c15fdc23SAdrian Chadd } else if (pulse_bw_info & PRI_CH_RADAR_FOUND) {
244c15fdc23SAdrian Chadd dur = pulse_length_pri;
245c15fdc23SAdrian Chadd pri_found = 1;
246c15fdc23SAdrian Chadd ext_found = 0;
247c15fdc23SAdrian Chadd } else if (pulse_bw_info & EXT_CH_RADAR_FOUND) {
248c15fdc23SAdrian Chadd dur = pulse_length_ext;
249c15fdc23SAdrian Chadd pri_found = 0;
250c15fdc23SAdrian Chadd ext_found = 1;
251c15fdc23SAdrian Chadd }
252c15fdc23SAdrian Chadd
253c15fdc23SAdrian Chadd }
254c15fdc23SAdrian Chadd
255c15fdc23SAdrian Chadd /*
256c15fdc23SAdrian Chadd * For enhanced DFS (Merlin and later), pulse_bw_info has
257c15fdc23SAdrian Chadd * implications for selecting the correct RSSI value.
258c15fdc23SAdrian Chadd */
259c15fdc23SAdrian Chadd if (doDfsEnhanced) {
260c15fdc23SAdrian Chadd switch (pulse_bw_info & 0x03) {
261c15fdc23SAdrian Chadd case 0:
262c15fdc23SAdrian Chadd /* No radar? */
263c15fdc23SAdrian Chadd rssi = 0;
264c15fdc23SAdrian Chadd break;
265c15fdc23SAdrian Chadd case PRI_CH_RADAR_FOUND:
266c15fdc23SAdrian Chadd /* Radar in primary channel */
267c15fdc23SAdrian Chadd /* Cannot use ctrl channel RSSI if ext channel is stronger */
268c15fdc23SAdrian Chadd if (ext_rssi >= (rssi + 3)) {
269c15fdc23SAdrian Chadd rssi = 0;
270c15fdc23SAdrian Chadd }
271c15fdc23SAdrian Chadd break;
272c15fdc23SAdrian Chadd case EXT_CH_RADAR_FOUND:
273c15fdc23SAdrian Chadd /* Radar in extended channel */
274c15fdc23SAdrian Chadd /* Cannot use ext channel RSSI if ctrl channel is stronger */
275c15fdc23SAdrian Chadd if (rssi >= (ext_rssi + 12)) {
276c15fdc23SAdrian Chadd rssi = 0;
277c15fdc23SAdrian Chadd } else {
278c15fdc23SAdrian Chadd rssi = ext_rssi;
279c15fdc23SAdrian Chadd }
280c15fdc23SAdrian Chadd break;
281c15fdc23SAdrian Chadd case (PRI_CH_RADAR_FOUND | EXT_CH_RADAR_FOUND):
282c15fdc23SAdrian Chadd /* When both are present, use stronger one */
283c15fdc23SAdrian Chadd if (rssi < ext_rssi)
284c15fdc23SAdrian Chadd rssi = ext_rssi;
285c15fdc23SAdrian Chadd break;
286c15fdc23SAdrian Chadd }
287c15fdc23SAdrian Chadd }
288c15fdc23SAdrian Chadd
289c15fdc23SAdrian Chadd /*
290c15fdc23SAdrian Chadd * If not doing enhanced DFS, choose the ext channel if
291c15fdc23SAdrian Chadd * it is stronger than the main channel
292c15fdc23SAdrian Chadd */
293c15fdc23SAdrian Chadd if (doDfsExtCh && !doDfsEnhanced) {
294c15fdc23SAdrian Chadd if ((ext_rssi > rssi) && (ext_rssi < 128))
295c15fdc23SAdrian Chadd rssi = ext_rssi;
296c15fdc23SAdrian Chadd }
297c15fdc23SAdrian Chadd
298c15fdc23SAdrian Chadd /*
299c15fdc23SAdrian Chadd * XXX what happens if the above code decides the RSSI
300c15fdc23SAdrian Chadd * XXX wasn't valid, an sets it to 0?
301c15fdc23SAdrian Chadd */
302c15fdc23SAdrian Chadd
303c15fdc23SAdrian Chadd /*
304c15fdc23SAdrian Chadd * Fill out dfs_event structure.
305c15fdc23SAdrian Chadd */
306c15fdc23SAdrian Chadd event->re_full_ts = fulltsf;
307c15fdc23SAdrian Chadd event->re_ts = rxs->rs_tstamp;
308c15fdc23SAdrian Chadd event->re_rssi = rssi;
309c15fdc23SAdrian Chadd event->re_dur = dur;
310c15fdc23SAdrian Chadd
311c15fdc23SAdrian Chadd event->re_flags = 0;
312c15fdc23SAdrian Chadd if (pri_found)
313c15fdc23SAdrian Chadd event->re_flags |= HAL_DFS_EVENT_PRICH;
314c15fdc23SAdrian Chadd if (ext_found)
315c15fdc23SAdrian Chadd event->re_flags |= HAL_DFS_EVENT_EXTCH;
316c15fdc23SAdrian Chadd if (early_ext)
317c15fdc23SAdrian Chadd event->re_flags |= HAL_DFS_EVENT_EXTEARLY;
318c15fdc23SAdrian Chadd if (is_dc)
319c15fdc23SAdrian Chadd event->re_flags |= HAL_DFS_EVENT_ISDC;
320c15fdc23SAdrian Chadd
321c15fdc23SAdrian Chadd return AH_TRUE;
322c15fdc23SAdrian Chadd }
323c15fdc23SAdrian Chadd
324e113789bSAdrian Chadd void
ar9300_attach_freebsd_ops(struct ath_hal * ah)325e113789bSAdrian Chadd ar9300_attach_freebsd_ops(struct ath_hal *ah)
326e113789bSAdrian Chadd {
327e113789bSAdrian Chadd
328e113789bSAdrian Chadd /* Global functions */
329e113789bSAdrian Chadd ah->ah_detach = ar9300_detach;
330e113789bSAdrian Chadd ah->ah_getRateTable = ar9300_get_rate_table;
331e113789bSAdrian Chadd
332e113789bSAdrian Chadd /* Reset functions */
333e113789bSAdrian Chadd ah->ah_reset = ar9300_reset_freebsd;
334e113789bSAdrian Chadd ah->ah_phyDisable = ar9300_phy_disable;
335e113789bSAdrian Chadd ah->ah_disable = ar9300_disable;
336e113789bSAdrian Chadd ah->ah_configPCIE = ar9300_config_pcie_freebsd;
337e113789bSAdrian Chadd // ah->ah_disablePCIE = ar9300_disable_pcie_phy;
338e113789bSAdrian Chadd ah->ah_setPCUConfig = ar9300_set_pcu_config;
339e113789bSAdrian Chadd // perCalibration
340e113789bSAdrian Chadd ah->ah_perCalibrationN = ar9300_per_calibration_freebsd;
341e113789bSAdrian Chadd ah->ah_resetCalValid = ar9300_reset_cal_valid_freebsd;
342e113789bSAdrian Chadd ah->ah_setTxPowerLimit = ar9300_freebsd_set_tx_power_limit;
343e113789bSAdrian Chadd ah->ah_getChanNoise = ath_hal_getChanNoise;
344e113789bSAdrian Chadd
345e113789bSAdrian Chadd /* Transmit functions */
346e113789bSAdrian Chadd ah->ah_setupTxQueue = ar9300_setup_tx_queue;
347e113789bSAdrian Chadd ah->ah_setTxQueueProps = ar9300_set_tx_queue_props;
348e113789bSAdrian Chadd ah->ah_getTxQueueProps = ar9300_get_tx_queue_props;
349e113789bSAdrian Chadd ah->ah_releaseTxQueue = ar9300_release_tx_queue;
350e113789bSAdrian Chadd ah->ah_resetTxQueue = ar9300_reset_tx_queue;
351e113789bSAdrian Chadd ah->ah_getTxDP = ar9300_get_tx_dp;
352e113789bSAdrian Chadd ah->ah_setTxDP = ar9300_set_tx_dp;
353e113789bSAdrian Chadd ah->ah_numTxPending = ar9300_num_tx_pending;
354e113789bSAdrian Chadd ah->ah_startTxDma = ar9300_start_tx_dma;
355e113789bSAdrian Chadd ah->ah_stopTxDma = ar9300_stop_tx_dma_freebsd;
356e113789bSAdrian Chadd ah->ah_setupTxDesc = ar9300_freebsd_setup_tx_desc;
357e113789bSAdrian Chadd ah->ah_setupXTxDesc = ar9300_freebsd_setup_x_tx_desc;
358e113789bSAdrian Chadd ah->ah_fillTxDesc = ar9300_freebsd_fill_tx_desc;
359e113789bSAdrian Chadd ah->ah_procTxDesc = ar9300_freebsd_proc_tx_desc;
360e113789bSAdrian Chadd ah->ah_getTxIntrQueue = ar9300_get_tx_intr_queue;
361e113789bSAdrian Chadd // reqTxIntrDesc
362e113789bSAdrian Chadd ah->ah_getTxCompletionRates = ar9300_freebsd_get_tx_completion_rates;
363e113789bSAdrian Chadd ah->ah_setTxDescLink = ar9300_set_desc_link;
364e113789bSAdrian Chadd ah->ah_getTxDescLink = ar9300_freebsd_get_desc_link;
365e113789bSAdrian Chadd ah->ah_getTxDescLinkPtr = ar9300_get_desc_link_ptr;
366e113789bSAdrian Chadd ah->ah_setupTxStatusRing = ar9300_setup_tx_status_ring;
367e113789bSAdrian Chadd ah->ah_getTxRawTxDesc = ar9300_get_raw_tx_desc;
368e113789bSAdrian Chadd ah->ah_updateTxTrigLevel = ar9300_update_tx_trig_level;
369e113789bSAdrian Chadd
370e113789bSAdrian Chadd /* RX functions */
371e113789bSAdrian Chadd ah->ah_getRxDP = ar9300_get_rx_dp;
372e113789bSAdrian Chadd ah->ah_setRxDP = ar9300_set_rx_dp;
373e113789bSAdrian Chadd ah->ah_enableReceive = ar9300_enable_receive;
374e113789bSAdrian Chadd ah->ah_stopDmaReceive = ar9300_stop_dma_receive_freebsd;
375a8083b9cSAdrian Chadd ah->ah_startPcuReceive = ar9300_start_pcu_receive;
376e113789bSAdrian Chadd ah->ah_stopPcuReceive = ar9300_stop_pcu_receive;
377e113789bSAdrian Chadd ah->ah_setMulticastFilter = ar9300_set_multicast_filter;
378e113789bSAdrian Chadd ah->ah_setMulticastFilterIndex = ar9300SetMulticastFilterIndex;
379e113789bSAdrian Chadd ah->ah_clrMulticastFilterIndex = ar9300ClrMulticastFilterIndex;
380e113789bSAdrian Chadd ah->ah_getRxFilter = ar9300_get_rx_filter;
381e113789bSAdrian Chadd ah->ah_setRxFilter = ar9300_set_rx_filter;
382e113789bSAdrian Chadd /* setupRxDesc */
383e113789bSAdrian Chadd ah->ah_procRxDesc = ar9300_proc_rx_desc_freebsd;
384e113789bSAdrian Chadd ah->ah_rxMonitor = ar9300_ani_rxmonitor_freebsd;
385e113789bSAdrian Chadd ah->ah_aniPoll = ar9300_ani_poll_freebsd;
386e113789bSAdrian Chadd ah->ah_procMibEvent = ar9300_process_mib_intr;
387e113789bSAdrian Chadd
388e113789bSAdrian Chadd /* Misc functions */
389e113789bSAdrian Chadd ah->ah_getCapability = ar9300_get_capability;
390e113789bSAdrian Chadd ah->ah_setCapability = ar9300_set_capability;
391e113789bSAdrian Chadd ah->ah_getDiagState = ar9300_get_diag_state;
392e113789bSAdrian Chadd ah->ah_getMacAddress = ar9300_get_mac_address;
393e113789bSAdrian Chadd ah->ah_setMacAddress = ar9300_set_mac_address;
394e113789bSAdrian Chadd ah->ah_getBssIdMask = ar9300_get_bss_id_mask;
395e113789bSAdrian Chadd ah->ah_setBssIdMask = ar9300_set_bss_id_mask;
396e113789bSAdrian Chadd ah->ah_setRegulatoryDomain = ar9300_set_regulatory_domain;
397e113789bSAdrian Chadd ah->ah_setLedState = ar9300_set_led_state;
398e113789bSAdrian Chadd ah->ah_writeAssocid = ar9300_write_associd;
399e113789bSAdrian Chadd ah->ah_gpioCfgInput = ar9300_gpio_cfg_input;
400e113789bSAdrian Chadd ah->ah_gpioCfgOutput = ar9300_gpio_cfg_output;
401e113789bSAdrian Chadd ah->ah_gpioGet = ar9300_gpio_get;
402e113789bSAdrian Chadd ah->ah_gpioSet = ar9300_gpio_set;
403e113789bSAdrian Chadd ah->ah_gpioSetIntr = ar9300_gpio_set_intr;
404e113789bSAdrian Chadd /* polarity */
405e113789bSAdrian Chadd /* mask */
406e113789bSAdrian Chadd ah->ah_getTsf32 = ar9300_get_tsf32;
407e113789bSAdrian Chadd ah->ah_getTsf64 = ar9300_get_tsf64;
408e113789bSAdrian Chadd ah->ah_resetTsf = ar9300_reset_tsf;
40966b870f3SAdrian Chadd ah->ah_setTsf64 = ar9300_freebsd_set_tsf64;
410e113789bSAdrian Chadd ah->ah_detectCardPresent = ar9300_detect_card_present;
411e113789bSAdrian Chadd // ah->ah_updateMibCounters = ar9300_update_mib_counters;
412e113789bSAdrian Chadd ah->ah_getRfGain = ar9300_get_rfgain;
413e113789bSAdrian Chadd ah->ah_getDefAntenna = ar9300_get_def_antenna;
414e113789bSAdrian Chadd ah->ah_setDefAntenna = ar9300_set_def_antenna;
415f5ab408eSAdrian Chadd ah->ah_getAntennaSwitch = ar9300_freebsd_get_antenna_switch;
416f5ab408eSAdrian Chadd ah->ah_setAntennaSwitch = ar9300_freebsd_set_antenna_switch;
417e113789bSAdrian Chadd // ah->ah_setSifsTime = ar9300_set_sifs_time;
418e113789bSAdrian Chadd // ah->ah_getSifsTime = ar9300_get_sifs_time;
419e113789bSAdrian Chadd ah->ah_setSlotTime = ar9300_set_slot_time;
420e113789bSAdrian Chadd ah->ah_getSlotTime = ar9300GetSlotTime;
421e113789bSAdrian Chadd ah->ah_getAckTimeout = ar9300_get_ack_timeout;
422e113789bSAdrian Chadd ah->ah_setAckTimeout = ar9300_set_ack_timeout;
423e113789bSAdrian Chadd // XXX ack/ctsrate
424e113789bSAdrian Chadd // XXX CTS timeout
425f5ab408eSAdrian Chadd ah->ah_getCTSTimeout = ar9300_freebsd_get_cts_timeout;
426e113789bSAdrian Chadd // XXX decompmask
427e113789bSAdrian Chadd // coverageclass
428e113789bSAdrian Chadd ah->ah_setQuiet = ar9300_set_quiet;
429e113789bSAdrian Chadd ah->ah_getMibCycleCounts = ar9300_freebsd_get_mib_cycle_counts;
430e113789bSAdrian Chadd
431e113789bSAdrian Chadd /* DFS functions */
432e113789bSAdrian Chadd ah->ah_enableDfs = ar9300_enable_dfs;
433e113789bSAdrian Chadd ah->ah_getDfsThresh = ar9300_get_dfs_thresh;
43466c73f1dSAdrian Chadd ah->ah_getDfsDefaultThresh = ar9300_get_default_dfs_thresh;
435c15fdc23SAdrian Chadd ah->ah_procRadarEvent = ar9300_freebsd_proc_radar_event;
436e113789bSAdrian Chadd ah->ah_isFastClockEnabled = ar9300_is_fast_clock_enabled;
437e113789bSAdrian Chadd ah->ah_get11nExtBusy = ar9300_get_11n_ext_busy;
438ea319c83SAdrian Chadd ah->ah_setDfsCacTxQuiet = ar9300_cac_tx_quiet;
439e113789bSAdrian Chadd
440204c8e00SAdrian Chadd /* Spectral Scan Functions */
441204c8e00SAdrian Chadd ah->ah_spectralConfigure = ar9300_configure_spectral_scan;
442204c8e00SAdrian Chadd ah->ah_spectralGetConfig = ar9300_get_spectral_params;
443204c8e00SAdrian Chadd ah->ah_spectralStart = ar9300_start_spectral_scan;
444204c8e00SAdrian Chadd ah->ah_spectralStop = ar9300_stop_spectral_scan;
445204c8e00SAdrian Chadd ah->ah_spectralIsEnabled = ar9300_is_spectral_enabled;
446204c8e00SAdrian Chadd ah->ah_spectralIsActive = ar9300_is_spectral_active;
447204c8e00SAdrian Chadd
448e113789bSAdrian Chadd /* Key cache functions */
449e113789bSAdrian Chadd ah->ah_getKeyCacheSize = ar9300_get_key_cache_size;
450e113789bSAdrian Chadd ah->ah_resetKeyCacheEntry = ar9300_reset_key_cache_entry;
451e113789bSAdrian Chadd ah->ah_isKeyCacheEntryValid = ar9300_is_key_cache_entry_valid;
452e113789bSAdrian Chadd ah->ah_setKeyCacheEntry = ar9300_set_key_cache_entry;
453e113789bSAdrian Chadd ah->ah_setKeyCacheEntryMac = ar9300_set_key_cache_entry_mac;
454e113789bSAdrian Chadd
455e113789bSAdrian Chadd /* Power management functions */
456e113789bSAdrian Chadd ah->ah_setPowerMode = ar9300_set_power_mode;
457e113789bSAdrian Chadd ah->ah_getPowerMode = ar9300_get_power_mode;
458e113789bSAdrian Chadd
459e113789bSAdrian Chadd /* Beacon functions */
460e113789bSAdrian Chadd /* ah_setBeaconTimers */
461e113789bSAdrian Chadd ah->ah_beaconInit = ar9300_freebsd_beacon_init;
462caa918bdSAdrian Chadd ah->ah_setBeaconTimers = ar9300_beacon_set_beacon_timers;
463e113789bSAdrian Chadd ah->ah_setStationBeaconTimers = ar9300_set_sta_beacon_timers;
464e113789bSAdrian Chadd /* ah_resetStationBeaconTimers */
4650694aa79SAdrian Chadd ah->ah_getNextTBTT = ar9300_get_next_tbtt;
466e113789bSAdrian Chadd
467e113789bSAdrian Chadd /* Interrupt functions */
468e113789bSAdrian Chadd ah->ah_isInterruptPending = ar9300_is_interrupt_pending;
469e113789bSAdrian Chadd ah->ah_getPendingInterrupts = ar9300_get_pending_interrupts_freebsd;
470e113789bSAdrian Chadd ah->ah_getInterrupts = ar9300_get_interrupts;
471e113789bSAdrian Chadd ah->ah_setInterrupts = ar9300_set_interrupts_freebsd;
472e113789bSAdrian Chadd
473e113789bSAdrian Chadd /* Regulatory/internal functions */
474e113789bSAdrian Chadd // AH_PRIVATE(ah)->ah_getNfAdjust = ar9300_get_nf_adjust;
475e113789bSAdrian Chadd AH_PRIVATE(ah)->ah_eepromRead = ar9300_eeprom_read_word;
476e113789bSAdrian Chadd // AH_PRIVATE(ah)->ah_getChipPowerLimits = ar9300_get_chip_power_limits;
477e113789bSAdrian Chadd AH_PRIVATE(ah)->ah_getWirelessModes = ar9300_get_wireless_modes;
478e113789bSAdrian Chadd AH_PRIVATE(ah)->ah_getChannelEdges = ar9300_get_channel_edges;
479e113789bSAdrian Chadd
480e113789bSAdrian Chadd AH_PRIVATE(ah)->ah_eepromRead = ar9300_eeprom_read_word;
481e113789bSAdrian Chadd /* XXX ah_eeprom */
482e113789bSAdrian Chadd /* XXX ah_eeversion */
483e113789bSAdrian Chadd /* XXX ah_eepromDetach */
484e113789bSAdrian Chadd /* XXX ah_eepromGet */
485e113789bSAdrian Chadd AH_PRIVATE(ah)->ah_eepromGet = ar9300_eeprom_get_freebsd;
486e113789bSAdrian Chadd /* XXX ah_eepromSet */
487e113789bSAdrian Chadd /* XXX ah_getSpurChan */
488e113789bSAdrian Chadd /* XXX ah_eepromDiag */
489e113789bSAdrian Chadd
490e113789bSAdrian Chadd /* 802.11n functions */
491e113789bSAdrian Chadd ah->ah_chainTxDesc = ar9300_freebsd_chain_tx_desc;
492e113789bSAdrian Chadd ah->ah_setupFirstTxDesc= ar9300_freebsd_setup_first_tx_desc;
493e113789bSAdrian Chadd ah->ah_setupLastTxDesc = ar9300_freebsd_setup_last_tx_desc;
494e113789bSAdrian Chadd ah->ah_set11nRateScenario = ar9300_freebsd_set_11n_rate_scenario;
495e113789bSAdrian Chadd ah->ah_set11nTxDesc = ar9300_freebsd_setup_11n_desc;
496e113789bSAdrian Chadd ah->ah_set11nAggrFirst = ar9300_set_11n_aggr_first;
497e113789bSAdrian Chadd ah->ah_set11nAggrMiddle = ar9300_set_11n_aggr_middle;
498e113789bSAdrian Chadd ah->ah_set11nAggrLast = ar9300_set_11n_aggr_last;
499e113789bSAdrian Chadd ah->ah_clr11nAggr = ar9300_clr_11n_aggr;
500e113789bSAdrian Chadd ah->ah_set11nBurstDuration = ar9300_set_11n_burst_duration;
501e113789bSAdrian Chadd /* ah_get11nExtBusy */
502e113789bSAdrian Chadd ah->ah_set11nMac2040 = ar9300_set_11n_mac2040;
503e113789bSAdrian Chadd ah->ah_setChainMasks = ar9300SetChainMasks;
504*bed90bf8SAdrian Chadd ah->ah_getNav = ar9300_get_nav;
505*bed90bf8SAdrian Chadd ah->ah_setNav = ar9300_set_nav;
506e113789bSAdrian Chadd /* ah_get11nRxClear */
507e113789bSAdrian Chadd /* ah_set11nRxClear */
508a987ae07SAdrian Chadd
509a987ae07SAdrian Chadd /* bluetooth coexistence functions */
510b5ddd800SAdrian Chadd ah->ah_btCoexSetInfo = ar9300_set_bt_coex_info;
511b5ddd800SAdrian Chadd ah->ah_btCoexSetConfig = ar9300_bt_coex_config;
512b5ddd800SAdrian Chadd ah->ah_btCoexSetQcuThresh = ar9300_bt_coex_set_qcu_thresh;
513b5ddd800SAdrian Chadd ah->ah_btCoexSetWeights = ar9300_bt_coex_set_weights;
514b5ddd800SAdrian Chadd ah->ah_btCoexSetBmissThresh = ar9300_bt_coex_setup_bmiss_thresh;
515b5ddd800SAdrian Chadd ah->ah_btCoexSetParameter = ar9300_bt_coex_set_parameter;
516b5ddd800SAdrian Chadd ah->ah_btCoexDisable = ar9300_bt_coex_disable;
517b5ddd800SAdrian Chadd ah->ah_btCoexEnable = ar9300_bt_coex_enable;
518a987ae07SAdrian Chadd
51938878c63SAdrian Chadd /* MCI bluetooth functions */
520e5acc52dSAdrian Chadd if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) {
521d24161cbSAdrian Chadd /*
522d24161cbSAdrian Chadd * Note: these are done in attach too for now, because
523d24161cbSAdrian Chadd * at this point we haven't yet setup the mac/bb revision
524d24161cbSAdrian Chadd * values, so this code is effectively NULL.
525d24161cbSAdrian Chadd * However, I'm leaving this here so people digging
526d24161cbSAdrian Chadd * into the code (a) see the MCI bits here, and (b)
527d24161cbSAdrian Chadd * are now told they should look elsewhere for
528d24161cbSAdrian Chadd * these methods.
529d24161cbSAdrian Chadd */
530e5acc52dSAdrian Chadd ah->ah_btCoexSetWeights = ar9300_mci_bt_coex_set_weights;
531e5acc52dSAdrian Chadd ah->ah_btCoexDisable = ar9300_mci_bt_coex_disable;
532e5acc52dSAdrian Chadd ah->ah_btCoexEnable = ar9300_mci_bt_coex_enable;
533e5acc52dSAdrian Chadd }
53438878c63SAdrian Chadd ah->ah_btMciSetup = ar9300_mci_setup;
53538878c63SAdrian Chadd ah->ah_btMciSendMessage = ar9300_mci_send_message;
53638878c63SAdrian Chadd ah->ah_btMciGetInterrupt = ar9300_mci_get_interrupt;
537d24161cbSAdrian Chadd ah->ah_btMciState = ar9300_mci_state;
53838878c63SAdrian Chadd ah->ah_btMciDetach = ar9300_mci_detach;
53938878c63SAdrian Chadd
540a987ae07SAdrian Chadd /* LNA diversity functions */
541a987ae07SAdrian Chadd ah->ah_divLnaConfGet = ar9300_ant_div_comb_get_config;
542a987ae07SAdrian Chadd ah->ah_divLnaConfSet = ar9300_ant_div_comb_set_config;
543e113789bSAdrian Chadd }
544e113789bSAdrian Chadd
545e113789bSAdrian Chadd HAL_BOOL
ar9300_reset_freebsd(struct ath_hal * ah,HAL_OPMODE opmode,struct ieee80211_channel * chan,HAL_BOOL bChannelChange,HAL_RESET_TYPE resetType,HAL_STATUS * status)546e113789bSAdrian Chadd ar9300_reset_freebsd(struct ath_hal *ah, HAL_OPMODE opmode,
547e113789bSAdrian Chadd struct ieee80211_channel *chan, HAL_BOOL bChannelChange,
548f50e4ebfSAdrian Chadd HAL_RESET_TYPE resetType,
549e113789bSAdrian Chadd HAL_STATUS *status)
550e113789bSAdrian Chadd {
551e113789bSAdrian Chadd HAL_BOOL r;
552e113789bSAdrian Chadd HAL_HT_MACMODE macmode;
553e113789bSAdrian Chadd struct ath_hal_private *ap = AH_PRIVATE(ah);
554e113789bSAdrian Chadd
555e113789bSAdrian Chadd macmode =
556e113789bSAdrian Chadd IEEE80211_IS_CHAN_HT40(chan) ?
557e113789bSAdrian Chadd HAL_HT_MACMODE_2040 : HAL_HT_MACMODE_20;
558e113789bSAdrian Chadd
559e113789bSAdrian Chadd r = ar9300_reset(ah, opmode, chan, macmode,
560e113789bSAdrian Chadd ap->ah_caps.halTxChainMask,
561e113789bSAdrian Chadd ap->ah_caps.halRxChainMask,
562e113789bSAdrian Chadd HAL_HT_EXTPROTSPACING_20, /* always 20Mhz channel spacing */
563e113789bSAdrian Chadd bChannelChange,
564e113789bSAdrian Chadd status,
5658c01c3dcSAdrian Chadd resetType,
566e113789bSAdrian Chadd AH_FALSE); /* XXX should really extend ath_hal_reset() */
567e113789bSAdrian Chadd
568e113789bSAdrian Chadd return (r);
569e113789bSAdrian Chadd }
570e113789bSAdrian Chadd
571e113789bSAdrian Chadd void
ar9300_config_pcie_freebsd(struct ath_hal * ah,HAL_BOOL restore,HAL_BOOL powerOff)572e113789bSAdrian Chadd ar9300_config_pcie_freebsd(struct ath_hal *ah, HAL_BOOL restore,
573e113789bSAdrian Chadd HAL_BOOL powerOff)
574e113789bSAdrian Chadd {
575e113789bSAdrian Chadd
576e113789bSAdrian Chadd ar9300_config_pci_power_save(ah, restore ? 1 : 0, powerOff ? 1 : 0);
577e113789bSAdrian Chadd }
578e113789bSAdrian Chadd
579e113789bSAdrian Chadd /*
580e113789bSAdrian Chadd * This is a copy from ar9300_eeprom_get(), purely because the FreeBSD
581e113789bSAdrian Chadd * API is very silly and inconsistent.
582e113789bSAdrian Chadd *
583e113789bSAdrian Chadd * The AR93xx HAL doesn't call the eepromGetFlag() function, so this
584e113789bSAdrian Chadd * only occurs for FreeBSD code.
585e113789bSAdrian Chadd *
586e113789bSAdrian Chadd * When I fix this particular API, I'll undo this.
587e113789bSAdrian Chadd */
588e113789bSAdrian Chadd HAL_STATUS
ar9300_eeprom_get_freebsd(struct ath_hal * ah,int param,void * val)589e113789bSAdrian Chadd ar9300_eeprom_get_freebsd(struct ath_hal *ah, int param, void *val)
590e113789bSAdrian Chadd {
591e113789bSAdrian Chadd
592e113789bSAdrian Chadd switch (param) {
593e113789bSAdrian Chadd case AR_EEP_FSTCLK_5G:
594e113789bSAdrian Chadd return HAL_OK;
595e113789bSAdrian Chadd default:
596e113789bSAdrian Chadd ath_hal_printf(ah, "%s: called, param=%d\n",
597e113789bSAdrian Chadd __func__, param);
598e113789bSAdrian Chadd return HAL_EIO;
599e113789bSAdrian Chadd }
600e113789bSAdrian Chadd }
601e113789bSAdrian Chadd
602e113789bSAdrian Chadd HAL_BOOL
ar9300_stop_tx_dma_freebsd(struct ath_hal * ah,u_int q)603e113789bSAdrian Chadd ar9300_stop_tx_dma_freebsd(struct ath_hal *ah, u_int q)
604e113789bSAdrian Chadd {
605e113789bSAdrian Chadd
606e113789bSAdrian Chadd return ar9300_stop_tx_dma(ah, q, 1000);
607e113789bSAdrian Chadd }
608e113789bSAdrian Chadd
609e113789bSAdrian Chadd void
ar9300_ani_poll_freebsd(struct ath_hal * ah,const struct ieee80211_channel * chan)610e113789bSAdrian Chadd ar9300_ani_poll_freebsd(struct ath_hal *ah,
611e113789bSAdrian Chadd const struct ieee80211_channel *chan)
612e113789bSAdrian Chadd {
613e113789bSAdrian Chadd
614e113789bSAdrian Chadd HAL_NODE_STATS stats;
615e113789bSAdrian Chadd HAL_ANISTATS anistats;
6169778bf37SAdrian Chadd HAL_SURVEY_SAMPLE survey;
617e113789bSAdrian Chadd
618e113789bSAdrian Chadd OS_MEMZERO(&stats, sizeof(stats));
619e113789bSAdrian Chadd OS_MEMZERO(&anistats, sizeof(anistats));
6209778bf37SAdrian Chadd OS_MEMZERO(&survey, sizeof(survey));
621e113789bSAdrian Chadd
622e113789bSAdrian Chadd ar9300_ani_ar_poll(ah, &stats, chan, &anistats);
6239778bf37SAdrian Chadd
6249778bf37SAdrian Chadd /*
6259778bf37SAdrian Chadd * If ANI stats are valid, use them to update the
6269778bf37SAdrian Chadd * channel survey.
6279778bf37SAdrian Chadd */
6289778bf37SAdrian Chadd if (anistats.valid) {
6299778bf37SAdrian Chadd survey.cycle_count = anistats.cyclecnt_diff;
6309778bf37SAdrian Chadd survey.chan_busy = anistats.rxclr_cnt;
6319778bf37SAdrian Chadd survey.ext_chan_busy = anistats.extrxclr_cnt;
6329778bf37SAdrian Chadd survey.tx_busy = anistats.txframecnt_diff;
6339778bf37SAdrian Chadd survey.rx_busy = anistats.rxframecnt_diff;
6349778bf37SAdrian Chadd ath_hal_survey_add_sample(ah, &survey);
6359778bf37SAdrian Chadd }
636e113789bSAdrian Chadd }
637e113789bSAdrian Chadd
638e113789bSAdrian Chadd /*
639e113789bSAdrian Chadd * Setup the configuration parameters in the style the AR9300 HAL
640e113789bSAdrian Chadd * wants.
641e113789bSAdrian Chadd */
642e113789bSAdrian Chadd void
ar9300_config_defaults_freebsd(struct ath_hal * ah,HAL_OPS_CONFIG * ah_config)6439389d5a9SAdrian Chadd ar9300_config_defaults_freebsd(struct ath_hal *ah, HAL_OPS_CONFIG *ah_config)
644e113789bSAdrian Chadd {
645e113789bSAdrian Chadd
6469389d5a9SAdrian Chadd /* Until FreeBSD's HAL does this by default - just copy */
6479389d5a9SAdrian Chadd OS_MEMCPY(&ah->ah_config, ah_config, sizeof(HAL_OPS_CONFIG));
648e113789bSAdrian Chadd ah->ah_config.ath_hal_enable_ani = AH_TRUE;
649e113789bSAdrian Chadd }
650e113789bSAdrian Chadd
651e113789bSAdrian Chadd HAL_BOOL
ar9300_stop_dma_receive_freebsd(struct ath_hal * ah)652e113789bSAdrian Chadd ar9300_stop_dma_receive_freebsd(struct ath_hal *ah)
653e113789bSAdrian Chadd {
654e113789bSAdrian Chadd
655e113789bSAdrian Chadd return ar9300_stop_dma_receive(ah, 1000);
656e113789bSAdrian Chadd }
657e113789bSAdrian Chadd
658e113789bSAdrian Chadd HAL_BOOL
ar9300_get_pending_interrupts_freebsd(struct ath_hal * ah,HAL_INT * masked)659e113789bSAdrian Chadd ar9300_get_pending_interrupts_freebsd(struct ath_hal *ah, HAL_INT *masked)
660e113789bSAdrian Chadd {
661e113789bSAdrian Chadd
662e113789bSAdrian Chadd /* Non-MSI, so no MSI vector; and 'nortc' = 0 */
663e113789bSAdrian Chadd return ar9300_get_pending_interrupts(ah, masked, HAL_INT_LINE, 0, 0);
664e113789bSAdrian Chadd }
665e113789bSAdrian Chadd
666e113789bSAdrian Chadd HAL_INT
ar9300_set_interrupts_freebsd(struct ath_hal * ah,HAL_INT ints)667e113789bSAdrian Chadd ar9300_set_interrupts_freebsd(struct ath_hal *ah, HAL_INT ints)
668e113789bSAdrian Chadd {
669e113789bSAdrian Chadd
670e113789bSAdrian Chadd /* nortc = 0 */
671e113789bSAdrian Chadd return ar9300_set_interrupts(ah, ints, 0);
672e113789bSAdrian Chadd }
673e113789bSAdrian Chadd
674e113789bSAdrian Chadd HAL_BOOL
ar9300_per_calibration_freebsd(struct ath_hal * ah,struct ieee80211_channel * chan,u_int rxchainmask,HAL_BOOL long_cal,HAL_BOOL * isCalDone)675e113789bSAdrian Chadd ar9300_per_calibration_freebsd(struct ath_hal *ah,
676e113789bSAdrian Chadd struct ieee80211_channel *chan, u_int rxchainmask, HAL_BOOL long_cal,
677e113789bSAdrian Chadd HAL_BOOL *isCalDone)
678e113789bSAdrian Chadd {
679e113789bSAdrian Chadd /* XXX fake scheduled calibrations for now */
680e113789bSAdrian Chadd u_int32_t sched_cals = 0xfffffff;
681e113789bSAdrian Chadd
682e113789bSAdrian Chadd return ar9300_calibration(ah, chan,
683e113789bSAdrian Chadd AH_PRIVATE(ah)->ah_caps.halRxChainMask,
684e113789bSAdrian Chadd long_cal,
685e113789bSAdrian Chadd isCalDone,
686e113789bSAdrian Chadd 0, /* is_scan */
687e113789bSAdrian Chadd &sched_cals);
688e113789bSAdrian Chadd }
689e113789bSAdrian Chadd
690e113789bSAdrian Chadd HAL_BOOL
ar9300_reset_cal_valid_freebsd(struct ath_hal * ah,const struct ieee80211_channel * chan)691e113789bSAdrian Chadd ar9300_reset_cal_valid_freebsd(struct ath_hal *ah,
692e113789bSAdrian Chadd const struct ieee80211_channel *chan)
693e113789bSAdrian Chadd {
694e113789bSAdrian Chadd
695e113789bSAdrian Chadd HAL_BOOL is_cal_done = AH_TRUE;
696e113789bSAdrian Chadd
697e113789bSAdrian Chadd ar9300_reset_cal_valid(ah, chan, &is_cal_done, 0xffffffff);
698e113789bSAdrian Chadd return (is_cal_done);
699e113789bSAdrian Chadd }
700e113789bSAdrian Chadd
701e113789bSAdrian Chadd
702e113789bSAdrian Chadd /*
703e113789bSAdrian Chadd * FreeBSD will just pass in the descriptor value as 'pa'.
704e113789bSAdrian Chadd * The Atheros HAL treats 'pa' as the physical address of the RX
705e113789bSAdrian Chadd * descriptor and 'bufaddr' as the physical address of the RX buffer.
706e113789bSAdrian Chadd * I'm not sure why they didn't collapse them - the AR9300 RX descriptor
707e113789bSAdrian Chadd * routine doesn't check 'pa'.
708e113789bSAdrian Chadd */
709e113789bSAdrian Chadd HAL_STATUS
ar9300_proc_rx_desc_freebsd(struct ath_hal * ah,struct ath_desc * ds,uint32_t pa,struct ath_desc * ds_next,uint64_t tsf,struct ath_rx_status * rxs)710e113789bSAdrian Chadd ar9300_proc_rx_desc_freebsd(struct ath_hal *ah, struct ath_desc *ds,
711e113789bSAdrian Chadd uint32_t pa, struct ath_desc *ds_next, uint64_t tsf,
712e113789bSAdrian Chadd struct ath_rx_status *rxs)
713e113789bSAdrian Chadd {
714e113789bSAdrian Chadd
715e113789bSAdrian Chadd return (ar9300_proc_rx_desc_fast(ah, ds, 0, ds_next, rxs,
716e113789bSAdrian Chadd (void *) ds));
717e113789bSAdrian Chadd }
718e113789bSAdrian Chadd
7198a97beffSAdrian Chadd /*
7208a97beffSAdrian Chadd * This is the primary way the ANI code gets the node statistics per packet.
7218a97beffSAdrian Chadd */
722e113789bSAdrian Chadd void
ar9300_ani_rxmonitor_freebsd(struct ath_hal * ah,const HAL_NODE_STATS * stats,const struct ieee80211_channel * chan)723e113789bSAdrian Chadd ar9300_ani_rxmonitor_freebsd(struct ath_hal *ah, const HAL_NODE_STATS *stats,
724e113789bSAdrian Chadd const struct ieee80211_channel *chan)
725e113789bSAdrian Chadd {
7268a97beffSAdrian Chadd struct ath_hal_9300 *ahp = AH9300(ah);
727e113789bSAdrian Chadd
7288a97beffSAdrian Chadd ahp->ah_stats.ast_nodestats.ns_avgbrssi = stats->ns_avgbrssi;
729e113789bSAdrian Chadd }
730e113789bSAdrian Chadd
731e113789bSAdrian Chadd void
ar9300_freebsd_get_desc_link(struct ath_hal * ah,void * ds,uint32_t * link)732e113789bSAdrian Chadd ar9300_freebsd_get_desc_link(struct ath_hal *ah, void *ds, uint32_t *link)
733e113789bSAdrian Chadd {
734e113789bSAdrian Chadd struct ar9300_txc *ads = AR9300TXC(ds);
735e113789bSAdrian Chadd
736e113789bSAdrian Chadd (*link) = ads->ds_link;
737e113789bSAdrian Chadd }
738e113789bSAdrian Chadd
739e113789bSAdrian Chadd /*
740e113789bSAdrian Chadd * TX descriptor field setting wrappers - eek.
741e113789bSAdrian Chadd */
742e113789bSAdrian Chadd
743e113789bSAdrian Chadd
744e113789bSAdrian Chadd HAL_BOOL
ar9300_freebsd_setup_tx_desc(struct ath_hal * ah,struct ath_desc * ds,u_int pktLen,u_int hdrLen,HAL_PKT_TYPE type,u_int txPower,u_int txRate0,u_int txTries0,u_int keyIx,u_int antMode,u_int flags,u_int rtsctsRate,u_int rtsCtsDuration,u_int compicvLen,u_int compivLen,u_int comp)745e113789bSAdrian Chadd ar9300_freebsd_setup_tx_desc(struct ath_hal *ah, struct ath_desc *ds,
746e113789bSAdrian Chadd u_int pktLen, u_int hdrLen, HAL_PKT_TYPE type, u_int txPower,
747e113789bSAdrian Chadd u_int txRate0, u_int txTries0, u_int keyIx, u_int antMode, u_int flags,
748e113789bSAdrian Chadd u_int rtsctsRate, u_int rtsCtsDuration, u_int compicvLen,
749e113789bSAdrian Chadd u_int compivLen, u_int comp)
750e113789bSAdrian Chadd {
751e113789bSAdrian Chadd struct ath_hal_9300 *ahp = AH9300(ah);
752e113789bSAdrian Chadd
753e113789bSAdrian Chadd HAL_KEY_TYPE keyType = 0; /* XXX No padding */
754e113789bSAdrian Chadd
755e113789bSAdrian Chadd if (keyIx != HAL_TXKEYIX_INVALID)
756e113789bSAdrian Chadd keyType = ahp->ah_keytype[keyIx];
757e113789bSAdrian Chadd
758e113789bSAdrian Chadd /* XXX bounds check keyix */
759e113789bSAdrian Chadd ar9300_set_11n_tx_desc(ah, ds, pktLen, type, txPower, keyIx,
760e113789bSAdrian Chadd keyType, flags);
761e113789bSAdrian Chadd
762e113789bSAdrian Chadd return AH_TRUE;
763e113789bSAdrian Chadd }
764e113789bSAdrian Chadd
765e113789bSAdrian Chadd HAL_BOOL
ar9300_freebsd_setup_x_tx_desc(struct ath_hal * ah,struct ath_desc * ds,u_int txRate1,u_int txTries1,u_int txRate2,u_int txTries2,u_int txRate3,u_int txTries3)766e113789bSAdrian Chadd ar9300_freebsd_setup_x_tx_desc(struct ath_hal *ah, struct ath_desc *ds,
767e113789bSAdrian Chadd u_int txRate1, u_int txTries1,
768e113789bSAdrian Chadd u_int txRate2, u_int txTries2,
769e113789bSAdrian Chadd u_int txRate3, u_int txTries3)
770e113789bSAdrian Chadd {
771e113789bSAdrian Chadd
77288c0971aSAdrian Chadd #if 0
773e113789bSAdrian Chadd ath_hal_printf(ah, "%s: called, 0x%x/%d, 0x%x/%d, 0x%x/%d\n",
774e113789bSAdrian Chadd __func__,
775e113789bSAdrian Chadd txRate1, txTries1,
776e113789bSAdrian Chadd txRate2, txTries2,
777e113789bSAdrian Chadd txRate3, txTries3);
77888c0971aSAdrian Chadd #endif
779e113789bSAdrian Chadd
780e113789bSAdrian Chadd /* XXX should only be called during probe */
781e113789bSAdrian Chadd return (AH_TRUE);
782e113789bSAdrian Chadd }
783e113789bSAdrian Chadd
784e113789bSAdrian Chadd HAL_BOOL
ar9300_freebsd_fill_tx_desc(struct ath_hal * ah,struct ath_desc * ds,HAL_DMA_ADDR * bufListPtr,uint32_t * segLenPtr,u_int descId,u_int qid,HAL_BOOL firstSeg,HAL_BOOL lastSeg,const struct ath_desc * ds0)785e113789bSAdrian Chadd ar9300_freebsd_fill_tx_desc(struct ath_hal *ah, struct ath_desc *ds,
786e113789bSAdrian Chadd HAL_DMA_ADDR *bufListPtr, uint32_t *segLenPtr, u_int descId, u_int qid,
787e113789bSAdrian Chadd HAL_BOOL firstSeg, HAL_BOOL lastSeg,
788e113789bSAdrian Chadd const struct ath_desc *ds0)
789e113789bSAdrian Chadd {
790e113789bSAdrian Chadd HAL_KEY_TYPE keyType = 0;
791e113789bSAdrian Chadd const struct ar9300_txc *ads = AR9300TXC_CONST(ds0);
792e113789bSAdrian Chadd
793e113789bSAdrian Chadd /*
794e113789bSAdrian Chadd * FreeBSD's HAL doesn't pass the keytype to fill_tx_desc();
795e113789bSAdrian Chadd * it's copied as part of the descriptor chaining.
796e113789bSAdrian Chadd *
797e113789bSAdrian Chadd * So, extract it from ds0.
798e113789bSAdrian Chadd */
799e113789bSAdrian Chadd keyType = MS(ads->ds_ctl17, AR_encr_type);
800e113789bSAdrian Chadd
801e113789bSAdrian Chadd return ar9300_fill_tx_desc(ah, ds, bufListPtr, segLenPtr, descId,
802e113789bSAdrian Chadd qid, keyType, firstSeg, lastSeg, ds0);
803e113789bSAdrian Chadd }
804e113789bSAdrian Chadd
805e113789bSAdrian Chadd HAL_BOOL
ar9300_freebsd_get_tx_completion_rates(struct ath_hal * ah,const struct ath_desc * ds0,int * rates,int * tries)806e113789bSAdrian Chadd ar9300_freebsd_get_tx_completion_rates(struct ath_hal *ah,
807e113789bSAdrian Chadd const struct ath_desc *ds0, int *rates, int *tries)
808e113789bSAdrian Chadd {
809e113789bSAdrian Chadd
810e113789bSAdrian Chadd ath_hal_printf(ah, "%s: called\n", __func__);
811e113789bSAdrian Chadd return AH_FALSE; /* XXX for now */
812e113789bSAdrian Chadd }
813e113789bSAdrian Chadd
814e113789bSAdrian Chadd
815e113789bSAdrian Chadd /*
816e113789bSAdrian Chadd * 802.11n TX descriptor wrappers
817e113789bSAdrian Chadd */
818e113789bSAdrian Chadd void
ar9300_freebsd_set_11n_rate_scenario(struct ath_hal * ah,struct ath_desc * ds,u_int durUpdateEn,u_int rtsctsRate,HAL_11N_RATE_SERIES series[],u_int nseries,u_int flags)819e113789bSAdrian Chadd ar9300_freebsd_set_11n_rate_scenario(struct ath_hal *ah, struct ath_desc *ds,
820e113789bSAdrian Chadd u_int durUpdateEn, u_int rtsctsRate, HAL_11N_RATE_SERIES series[],
821e113789bSAdrian Chadd u_int nseries, u_int flags)
822e113789bSAdrian Chadd {
823e113789bSAdrian Chadd
824e113789bSAdrian Chadd /* lastds=NULL, rtscts_duration is 0, smart antenna is 0 */
825e113789bSAdrian Chadd ar9300_set_11n_rate_scenario(ah, (void *) ds, (void *)ds, durUpdateEn,
826e113789bSAdrian Chadd rtsctsRate, 0, series, nseries, flags, 0);
827e113789bSAdrian Chadd }
828e113789bSAdrian Chadd
829e113789bSAdrian Chadd /* chaintxdesc */
830e113789bSAdrian Chadd HAL_BOOL
ar9300_freebsd_chain_tx_desc(struct ath_hal * ah,struct ath_desc * ds,HAL_DMA_ADDR * bufLenList,uint32_t * segLenList,u_int pktLen,u_int hdrLen,HAL_PKT_TYPE type,u_int keyIx,HAL_CIPHER cipher,uint8_t numDelims,HAL_BOOL firstSeg,HAL_BOOL lastSeg,HAL_BOOL lastAggr)831e113789bSAdrian Chadd ar9300_freebsd_chain_tx_desc(struct ath_hal *ah, struct ath_desc *ds,
832e113789bSAdrian Chadd HAL_DMA_ADDR *bufLenList, uint32_t *segLenList,
833e113789bSAdrian Chadd u_int pktLen, u_int hdrLen, HAL_PKT_TYPE type, u_int keyIx,
834e113789bSAdrian Chadd HAL_CIPHER cipher, uint8_t numDelims,
835e113789bSAdrian Chadd HAL_BOOL firstSeg, HAL_BOOL lastSeg, HAL_BOOL lastAggr)
836e113789bSAdrian Chadd {
837e113789bSAdrian Chadd
838e113789bSAdrian Chadd ath_hal_printf(ah, "%s: called\n", __func__);
839e113789bSAdrian Chadd return AH_FALSE;
840e113789bSAdrian Chadd }
841e113789bSAdrian Chadd
842e113789bSAdrian Chadd /* setupfirsttxdesc */
843e113789bSAdrian Chadd HAL_BOOL
ar9300_freebsd_setup_first_tx_desc(struct ath_hal * ah,struct ath_desc * ds,u_int aggrLen,u_int flags,u_int txPower,u_int txRate0,u_int txTries0,u_int antMode,u_int rtsctsRate,u_int rtsctsDuration)844e113789bSAdrian Chadd ar9300_freebsd_setup_first_tx_desc(struct ath_hal *ah, struct ath_desc *ds,
845e113789bSAdrian Chadd u_int aggrLen, u_int flags, u_int txPower, u_int txRate0,
846e113789bSAdrian Chadd u_int txTries0, u_int antMode, u_int rtsctsRate, u_int rtsctsDuration)
847e113789bSAdrian Chadd {
848e113789bSAdrian Chadd
849e113789bSAdrian Chadd ath_hal_printf(ah, "%s: called\n", __func__);
850e113789bSAdrian Chadd return AH_FALSE;
851e113789bSAdrian Chadd }
852e113789bSAdrian Chadd
853e113789bSAdrian Chadd /* setuplasttxdesc */
854e113789bSAdrian Chadd /*
855e113789bSAdrian Chadd * This gets called but for now let's not log anything;
856e113789bSAdrian Chadd * it's only used to update the rate control information.
857e113789bSAdrian Chadd */
858e113789bSAdrian Chadd HAL_BOOL
ar9300_freebsd_setup_last_tx_desc(struct ath_hal * ah,struct ath_desc * ds,const struct ath_desc * ds0)859e113789bSAdrian Chadd ar9300_freebsd_setup_last_tx_desc(struct ath_hal *ah, struct ath_desc *ds,
860e113789bSAdrian Chadd const struct ath_desc *ds0)
861e113789bSAdrian Chadd {
862e113789bSAdrian Chadd
863e113789bSAdrian Chadd // ath_hal_printf(ah, "%s: called\n", __func__);
864e113789bSAdrian Chadd return AH_FALSE;
865e113789bSAdrian Chadd }
866e113789bSAdrian Chadd
867e113789bSAdrian Chadd void
ar9300_freebsd_setup_11n_desc(struct ath_hal * ah,void * ds,u_int pktLen,HAL_PKT_TYPE type,u_int txPower,u_int keyIx,u_int flags)868e113789bSAdrian Chadd ar9300_freebsd_setup_11n_desc(struct ath_hal *ah, void *ds, u_int pktLen,
869e113789bSAdrian Chadd HAL_PKT_TYPE type, u_int txPower, u_int keyIx, u_int flags)
870e113789bSAdrian Chadd {
871e113789bSAdrian Chadd ath_hal_printf(ah, "%s: called\n", __func__);
872e113789bSAdrian Chadd #if 0
873e113789bSAdrian Chadd struct ath_hal_9300 *ahp = AH9300(ah);
874e113789bSAdrian Chadd
875e113789bSAdrian Chadd HAL_KEY_TYPE keyType = 0; /* XXX No padding */
876e113789bSAdrian Chadd
877e113789bSAdrian Chadd if (keyIx != HAL_TXKEYIX_INVALID)
878e113789bSAdrian Chadd keyType = ahp->ah_keytype[keyIx];
879e113789bSAdrian Chadd
880e113789bSAdrian Chadd /* XXX bounds check keyix */
881e113789bSAdrian Chadd ar9300_set_11n_tx_desc(ah, ds, pktLen, type, txPower, keyIx,
882e113789bSAdrian Chadd keyType, flags);
883e113789bSAdrian Chadd #endif
884e113789bSAdrian Chadd }
885e113789bSAdrian Chadd
886e113789bSAdrian Chadd HAL_STATUS
ar9300_freebsd_proc_tx_desc(struct ath_hal * ah,struct ath_desc * ds,struct ath_tx_status * ts)887e113789bSAdrian Chadd ar9300_freebsd_proc_tx_desc(struct ath_hal *ah, struct ath_desc *ds,
888e113789bSAdrian Chadd struct ath_tx_status *ts)
889e113789bSAdrian Chadd {
890e113789bSAdrian Chadd
891e113789bSAdrian Chadd return ar9300_proc_tx_desc(ah, ts);
892e113789bSAdrian Chadd }
893e113789bSAdrian Chadd
894e113789bSAdrian Chadd void
ar9300_freebsd_beacon_init(struct ath_hal * ah,uint32_t next_beacon,uint32_t beacon_period)895e113789bSAdrian Chadd ar9300_freebsd_beacon_init(struct ath_hal *ah, uint32_t next_beacon,
896e113789bSAdrian Chadd uint32_t beacon_period)
897e113789bSAdrian Chadd {
898e113789bSAdrian Chadd
899899d1cacSAdrian Chadd ar9300_beacon_init(ah, next_beacon, beacon_period, 0,
9006ae52b27SAdrian Chadd AH_PRIVATE(ah)->ah_opmode);
901e113789bSAdrian Chadd }
902e113789bSAdrian Chadd
903e113789bSAdrian Chadd HAL_BOOL
ar9300_freebsd_get_mib_cycle_counts(struct ath_hal * ah,HAL_SURVEY_SAMPLE * hs)904e113789bSAdrian Chadd ar9300_freebsd_get_mib_cycle_counts(struct ath_hal *ah,
905e113789bSAdrian Chadd HAL_SURVEY_SAMPLE *hs)
906e113789bSAdrian Chadd
907e113789bSAdrian Chadd {
908e113789bSAdrian Chadd
909e113789bSAdrian Chadd return (AH_FALSE);
910e113789bSAdrian Chadd }
911e113789bSAdrian Chadd
912e113789bSAdrian Chadd /*
913e113789bSAdrian Chadd * Clear multicast filter by index - from FreeBSD ar5212_recv.c
914e113789bSAdrian Chadd */
915e113789bSAdrian Chadd static HAL_BOOL
ar9300ClrMulticastFilterIndex(struct ath_hal * ah,uint32_t ix)916e113789bSAdrian Chadd ar9300ClrMulticastFilterIndex(struct ath_hal *ah, uint32_t ix)
917e113789bSAdrian Chadd {
918e113789bSAdrian Chadd uint32_t val;
919e113789bSAdrian Chadd
920e113789bSAdrian Chadd if (ix >= 64)
921e113789bSAdrian Chadd return (AH_FALSE);
922e113789bSAdrian Chadd if (ix >= 32) {
923e113789bSAdrian Chadd val = OS_REG_READ(ah, AR_MCAST_FIL1);
924e113789bSAdrian Chadd OS_REG_WRITE(ah, AR_MCAST_FIL1, (val &~ (1<<(ix-32))));
925e113789bSAdrian Chadd } else {
926e113789bSAdrian Chadd val = OS_REG_READ(ah, AR_MCAST_FIL0);
927e113789bSAdrian Chadd OS_REG_WRITE(ah, AR_MCAST_FIL0, (val &~ (1<<ix)));
928e113789bSAdrian Chadd }
929e113789bSAdrian Chadd return AH_TRUE;
930e113789bSAdrian Chadd }
931e113789bSAdrian Chadd
932e113789bSAdrian Chadd /*
933e113789bSAdrian Chadd * Set multicast filter by index - from FreeBSD ar5212_recv.c
934e113789bSAdrian Chadd */
935e113789bSAdrian Chadd static HAL_BOOL
ar9300SetMulticastFilterIndex(struct ath_hal * ah,uint32_t ix)936e113789bSAdrian Chadd ar9300SetMulticastFilterIndex(struct ath_hal *ah, uint32_t ix)
937e113789bSAdrian Chadd {
938e113789bSAdrian Chadd uint32_t val;
939e113789bSAdrian Chadd
940e113789bSAdrian Chadd if (ix >= 64)
941e113789bSAdrian Chadd return (AH_FALSE);
942e113789bSAdrian Chadd if (ix >= 32) {
943e113789bSAdrian Chadd val = OS_REG_READ(ah, AR_MCAST_FIL1);
944e113789bSAdrian Chadd OS_REG_WRITE(ah, AR_MCAST_FIL1, (val | (1<<(ix-32))));
945e113789bSAdrian Chadd } else {
946e113789bSAdrian Chadd val = OS_REG_READ(ah, AR_MCAST_FIL0);
947e113789bSAdrian Chadd OS_REG_WRITE(ah, AR_MCAST_FIL0, (val | (1<<ix)));
948e113789bSAdrian Chadd }
949e113789bSAdrian Chadd return (AH_TRUE);
950e113789bSAdrian Chadd }
951a778f8a1SAdrian Chadd
952caa918bdSAdrian Chadd #define TU_TO_USEC(_tu) ((_tu) << 10)
953caa918bdSAdrian Chadd #define ONE_EIGHTH_TU_TO_USEC(_tu8) ((_tu8) << 7)
954caa918bdSAdrian Chadd
955caa918bdSAdrian Chadd /*
956caa918bdSAdrian Chadd * Initializes all of the hardware registers used to
957caa918bdSAdrian Chadd * send beacons. Note that for station operation the
958caa918bdSAdrian Chadd * driver calls ar9300_set_sta_beacon_timers instead.
959caa918bdSAdrian Chadd */
960caa918bdSAdrian Chadd static void
ar9300_beacon_set_beacon_timers(struct ath_hal * ah,const HAL_BEACON_TIMERS * bt)961caa918bdSAdrian Chadd ar9300_beacon_set_beacon_timers(struct ath_hal *ah,
962caa918bdSAdrian Chadd const HAL_BEACON_TIMERS *bt)
963caa918bdSAdrian Chadd {
964caa918bdSAdrian Chadd uint32_t bperiod;
965caa918bdSAdrian Chadd
966caa918bdSAdrian Chadd #if 0
967caa918bdSAdrian Chadd HALASSERT(opmode == HAL_M_IBSS || opmode == HAL_M_HOSTAP);
968caa918bdSAdrian Chadd if (opmode == HAL_M_IBSS) {
969caa918bdSAdrian Chadd OS_REG_SET_BIT(ah, AR_TXCFG, AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY);
970caa918bdSAdrian Chadd }
971caa918bdSAdrian Chadd #endif
972caa918bdSAdrian Chadd
973caa918bdSAdrian Chadd /* XXX TODO: should migrate the HAL code to always use ONE_EIGHTH_TU */
974caa918bdSAdrian Chadd OS_REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bt->bt_nexttbtt));
975caa918bdSAdrian Chadd OS_REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, ONE_EIGHTH_TU_TO_USEC(bt->bt_nextdba));
976caa918bdSAdrian Chadd OS_REG_WRITE(ah, AR_NEXT_SWBA, ONE_EIGHTH_TU_TO_USEC(bt->bt_nextswba));
977caa918bdSAdrian Chadd OS_REG_WRITE(ah, AR_NEXT_NDP_TIMER, TU_TO_USEC(bt->bt_nextatim));
978caa918bdSAdrian Chadd
979caa918bdSAdrian Chadd bperiod = TU_TO_USEC(bt->bt_intval & HAL_BEACON_PERIOD);
98078b812deSAdrian Chadd AH9300(ah)->ah_beaconInterval = bt->bt_intval & HAL_BEACON_PERIOD;
981caa918bdSAdrian Chadd OS_REG_WRITE(ah, AR_BEACON_PERIOD, bperiod);
982caa918bdSAdrian Chadd OS_REG_WRITE(ah, AR_DMA_BEACON_PERIOD, bperiod);
983caa918bdSAdrian Chadd OS_REG_WRITE(ah, AR_SWBA_PERIOD, bperiod);
984caa918bdSAdrian Chadd OS_REG_WRITE(ah, AR_NDP_PERIOD, bperiod);
985caa918bdSAdrian Chadd
986caa918bdSAdrian Chadd /*
987caa918bdSAdrian Chadd * Reset TSF if required.
988caa918bdSAdrian Chadd */
989caa918bdSAdrian Chadd if (bt->bt_intval & HAL_BEACON_RESET_TSF)
990caa918bdSAdrian Chadd ar9300_reset_tsf(ah);
991caa918bdSAdrian Chadd
992caa918bdSAdrian Chadd /* enable timers */
993caa918bdSAdrian Chadd /* NB: flags == 0 handled specially for backwards compatibility */
994caa918bdSAdrian Chadd OS_REG_SET_BIT(ah, AR_TIMER_MODE,
995caa918bdSAdrian Chadd bt->bt_flags != 0 ? bt->bt_flags :
996caa918bdSAdrian Chadd AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN);
997caa918bdSAdrian Chadd }
998caa918bdSAdrian Chadd
999caa918bdSAdrian Chadd
1000a778f8a1SAdrian Chadd /*
1001a778f8a1SAdrian Chadd * RF attach stubs
1002a778f8a1SAdrian Chadd */
1003a778f8a1SAdrian Chadd
1004a778f8a1SAdrian Chadd static HAL_BOOL
rf9330_attach(struct ath_hal * ah,HAL_STATUS * status)1005a778f8a1SAdrian Chadd rf9330_attach(struct ath_hal *ah, HAL_STATUS *status)
1006a778f8a1SAdrian Chadd {
1007a778f8a1SAdrian Chadd
1008a778f8a1SAdrian Chadd (*status) = HAL_EINVAL;
1009a778f8a1SAdrian Chadd return (AH_FALSE);
1010a778f8a1SAdrian Chadd }
1011a778f8a1SAdrian Chadd
1012a778f8a1SAdrian Chadd static HAL_BOOL
rf9330_probe(struct ath_hal * ah)1013a778f8a1SAdrian Chadd rf9330_probe(struct ath_hal *ah)
1014a778f8a1SAdrian Chadd {
1015a778f8a1SAdrian Chadd return (AH_FALSE);
1016a778f8a1SAdrian Chadd }
1017a778f8a1SAdrian Chadd
1018a778f8a1SAdrian Chadd AH_RF(RF9330, rf9330_probe, rf9330_attach);
1019a778f8a1SAdrian Chadd
1020