2 * Copyright (c) 2002-2006 Sam Leffler, Errno Consulting, Atheros
3 * Communications, Inc. All rights reserved.
5 * Redistribution and use in source and binary forms are permitted
6 * provided that the following conditions are met:
7 * 1. The materials contained herein are unmodified and are used
9 * 2. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following NO
11 * ''WARRANTY'' disclaimer below (''Disclaimer''), without
13 * 3. Redistributions in binary form must reproduce at minimum a
14 * disclaimer similar to the Disclaimer below and any redistribution
15 * must be conditioned upon including a substantially similar
16 * Disclaimer requirement for further binary redistribution.
17 * 4. Neither the names of the above-listed copyright holders nor the
18 * names of any contributors may be used to endorse or promote
19 * product derived from this software without specific prior written
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT,
26 * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27 * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE
28 * FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
30 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
33 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * $Id: //depot/sw/linuxsrc/src/802_11/madwifi/hal/main/freebsd/ah_osdep.c#39 $
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/kernel.h>
43 #include <sys/module.h>
44 #include <sys/sysctl.h>
46 #include <sys/malloc.h>
49 #include <machine/stdarg.h>
51 #include <net/ethernet.h> /* XXX for ether_sprintf */
53 #include <contrib/dev/ath/ah.h>
55 extern void ath_hal_printf(struct ath_hal *, const char*, ...)
57 extern void ath_hal_vprintf(struct ath_hal *, const char*, __va_list)
59 extern const char* ath_hal_ether_sprintf(const u_int8_t *mac);
60 extern void *ath_hal_malloc(size_t);
61 extern void ath_hal_free(void *);
63 extern void ath_hal_assert_failed(const char* filename,
64 int lineno, const char* msg);
67 extern void HALDEBUG(struct ath_hal *ah, const char* fmt, ...);
68 extern void HALDEBUGn(struct ath_hal *ah, u_int level, const char* fmt, ...);
71 /* NB: put this here instead of the driver to avoid circular references */
72 SYSCTL_NODE(_hw, OID_AUTO, ath, CTLFLAG_RD, 0, "Atheros driver parameters");
73 SYSCTL_NODE(_hw_ath, OID_AUTO, hal, CTLFLAG_RD, 0, "Atheros HAL parameters");
76 static int ath_hal_debug = 0;
77 SYSCTL_INT(_hw_ath_hal, OID_AUTO, debug, CTLFLAG_RW, &ath_hal_debug,
78 0, "Atheros HAL debugging printfs");
79 TUNABLE_INT("hw.ath.hal.debug", &ath_hal_debug);
82 SYSCTL_STRING(_hw_ath_hal, OID_AUTO, version, CTLFLAG_RD, ath_hal_version, 0,
83 "Atheros HAL version");
85 int ath_hal_dma_beacon_response_time = 2; /* in TU's */
86 SYSCTL_INT(_hw_ath_hal, OID_AUTO, dma_brt, CTLFLAG_RW,
87 &ath_hal_dma_beacon_response_time, 0,
88 "Atheros HAL DMA beacon response time");
89 int ath_hal_sw_beacon_response_time = 10; /* in TU's */
90 SYSCTL_INT(_hw_ath_hal, OID_AUTO, sw_brt, CTLFLAG_RW,
91 &ath_hal_sw_beacon_response_time, 0,
92 "Atheros HAL software beacon response time");
93 int ath_hal_additional_swba_backoff = 0; /* in TU's */
94 SYSCTL_INT(_hw_ath_hal, OID_AUTO, swba_backoff, CTLFLAG_RW,
95 &ath_hal_additional_swba_backoff, 0,
96 "Atheros HAL additional SWBA backoff time");
98 MALLOC_DEFINE(M_ATH_HAL, "ath_hal", "ath hal data");
101 ath_hal_malloc(size_t size)
103 return kmalloc(size, M_ATH_HAL, M_NOWAIT | M_ZERO);
107 ath_hal_free(void* p)
109 return kfree(p, M_ATH_HAL);
113 ath_hal_vprintf(struct ath_hal *ah, const char* fmt, va_list ap)
119 ath_hal_printf(struct ath_hal *ah, const char* fmt, ...)
123 ath_hal_vprintf(ah, fmt, ap);
128 ath_hal_ether_sprintf(const u_int8_t *mac)
130 return ether_sprintf(mac);
135 HALDEBUG(struct ath_hal *ah, const char* fmt, ...)
140 ath_hal_vprintf(ah, fmt, ap);
146 HALDEBUGn(struct ath_hal *ah, u_int level, const char* fmt, ...)
148 if (ath_hal_debug >= level) {
151 ath_hal_vprintf(ah, fmt, ap);
155 #endif /* AH_DEBUG */
159 * ALQ register tracing support.
161 * Setting hw.ath.hal.alq=1 enables tracing of all register reads and
162 * writes to the file /tmp/ath_hal.log. The file format is a simple
163 * fixed-size array of records. When done logging set hw.ath.hal.alq=0
164 * and then decode the file with the arcode program (that is part of the
165 * HAL). If you start+stop tracing the data will be appended to an
168 * NB: doesn't handle multiple devices properly; only one DEVICE record
169 * is emitted and the different devices are not identified.
172 #include <sys/pcpu.h>
173 #include <contrib/dev/ath/ah_decode.h>
175 static struct alq *ath_hal_alq;
176 static int ath_hal_alq_emitdev; /* need to emit DEVICE record */
177 static u_int ath_hal_alq_lost; /* count of lost records */
178 static const char *ath_hal_logfile = "/tmp/ath_hal.log";
179 static u_int ath_hal_alq_qsize = 64*1024;
182 ath_hal_setlogging(int enable)
187 error = suser(curthread);
189 error = alq_open(&ath_hal_alq, ath_hal_logfile,
190 curthread->td_ucred, ALQ_DEFAULT_CMODE,
191 sizeof (struct athregrec), ath_hal_alq_qsize);
192 ath_hal_alq_lost = 0;
193 ath_hal_alq_emitdev = 1;
194 printf("ath_hal: logging to %s enabled\n",
199 alq_close(ath_hal_alq);
201 printf("ath_hal: logging disabled\n");
208 sysctl_hw_ath_hal_log(SYSCTL_HANDLER_ARGS)
212 enable = (ath_hal_alq != NULL);
213 error = sysctl_handle_int(oidp, &enable, 0, req);
214 if (error || !req->newptr)
217 return (ath_hal_setlogging(enable));
219 SYSCTL_PROC(_hw_ath_hal, OID_AUTO, alq, CTLTYPE_INT|CTLFLAG_RW,
220 0, 0, sysctl_hw_ath_hal_log, "I", "Enable HAL register logging");
221 SYSCTL_INT(_hw_ath_hal, OID_AUTO, alq_size, CTLFLAG_RW,
222 &ath_hal_alq_qsize, 0, "In-memory log size (#records)");
223 SYSCTL_INT(_hw_ath_hal, OID_AUTO, alq_lost, CTLFLAG_RW,
224 &ath_hal_alq_lost, 0, "Register operations not logged");
227 ath_hal_alq_get(struct ath_hal *ah)
231 if (ath_hal_alq_emitdev) {
232 ale = alq_get(ath_hal_alq, ALQ_NOWAIT);
234 struct athregrec *r =
235 (struct athregrec *) ale->ae_data;
238 r->val = ah->ah_devid;
239 alq_post(ath_hal_alq, ale);
240 ath_hal_alq_emitdev = 0;
244 ale = alq_get(ath_hal_alq, ALQ_NOWAIT);
251 ath_hal_reg_write(struct ath_hal *ah, u_int32_t reg, u_int32_t val)
254 struct ale *ale = ath_hal_alq_get(ah);
256 struct athregrec *r = (struct athregrec *) ale->ae_data;
260 alq_post(ath_hal_alq, ale);
263 #if _BYTE_ORDER == _BIG_ENDIAN
264 if (reg >= 0x4000 && reg < 0x5000)
265 bus_space_write_4(ah->ah_st, ah->ah_sh, reg, htole32(val));
268 bus_space_write_4(ah->ah_st, ah->ah_sh, reg, val);
272 ath_hal_reg_read(struct ath_hal *ah, u_int32_t reg)
276 val = bus_space_read_4(ah->ah_st, ah->ah_sh, reg);
277 #if _BYTE_ORDER == _BIG_ENDIAN
278 if (reg >= 0x4000 && reg < 0x5000)
282 struct ale *ale = ath_hal_alq_get(ah);
284 struct athregrec *r = (struct athregrec *) ale->ae_data;
288 alq_post(ath_hal_alq, ale);
295 OS_MARK(struct ath_hal *ah, u_int id, u_int32_t v)
298 struct ale *ale = ath_hal_alq_get(ah);
300 struct athregrec *r = (struct athregrec *) ale->ae_data;
304 alq_post(ath_hal_alq, ale);
308 #elif defined(AH_DEBUG) || defined(AH_REGOPS_FUNC)
310 * Memory-mapped device register read/write. These are here
311 * as routines when debugging support is enabled and/or when
312 * explicitly configured to use function calls. The latter is
313 * for architectures that might need to do something before
314 * referencing memory (e.g. remap an i/o window).
316 * NB: see the comments in ah_osdep.h about byte-swapping register
317 * reads and writes to understand what's going on below.
321 ath_hal_reg_write(struct ath_hal *ah, u_int32_t reg, u_int32_t val)
323 #if _BYTE_ORDER == _BIG_ENDIAN
324 if (reg >= 0x4000 && reg < 0x5000)
325 bus_space_write_4(ah->ah_st, ah->ah_sh, reg, htole32(val));
328 bus_space_write_4(ah->ah_st, ah->ah_sh, reg, val);
332 ath_hal_reg_read(struct ath_hal *ah, u_int32_t reg)
336 val = bus_space_read_4(ah->ah_st, ah->ah_sh, reg);
337 #if _BYTE_ORDER == _BIG_ENDIAN
338 if (reg >= 0x4000 && reg < 0x5000)
343 #endif /* AH_DEBUG || AH_REGOPS_FUNC */
347 ath_hal_assert_failed(const char* filename, int lineno, const char *msg)
349 printf("Atheros HAL assertion failure: %s: line %u: %s\n",
350 filename, lineno, msg);
351 panic("ath_hal_assert");
353 #endif /* AH_ASSERT */
356 * Delay n microseconds.
365 ath_hal_getuptime(struct ath_hal *ah)
369 return (bt.sec * 1000) +
370 (((uint64_t)1000 * (uint32_t)(bt.frac >> 32)) >> 32);
374 ath_hal_memzero(void *dst, size_t n)
380 ath_hal_memcpy(void *dst, const void *src, size_t n)
382 return memcpy(dst, src, n);
390 ath_hal_modevent(module_t mod, int type, void *unused)
397 printf("ath_hal: %s (", ath_hal_version);
399 for (i = 0; ath_hal_buildopts[i] != NULL; i++) {
400 printf("%s%s", sep, ath_hal_buildopts[i]);
411 static moduledata_t ath_hal_mod = {
416 DECLARE_MODULE(ath_hal, ath_hal_mod, SI_SUB_DRIVERS, SI_ORDER_ANY);
417 MODULE_VERSION(ath_hal, 1);