Deleted Added
full compact
ah_osdep.c (233887) ah_osdep.c (234450)
1/*-
2 * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer,
10 * without modification.
11 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13 * redistribution must be conditioned upon including a substantially
14 * similar Disclaimer requirement for further binary redistribution.
15 *
16 * NO WARRANTY
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
20 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
22 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27 * THE POSSIBILITY OF SUCH DAMAGES.
28 *
1/*-
2 * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer,
10 * without modification.
11 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13 * redistribution must be conditioned upon including a substantially
14 * similar Disclaimer requirement for further binary redistribution.
15 *
16 * NO WARRANTY
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
20 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
22 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27 * THE POSSIBILITY OF SUCH DAMAGES.
28 *
29 * $FreeBSD: head/sys/dev/ath/ah_osdep.c 233887 2012-04-04 20:46:20Z adrian $
29 * $FreeBSD: head/sys/dev/ath/ah_osdep.c 234450 2012-04-19 03:26:21Z adrian $
30 */
31#include "opt_ah.h"
32
33#include <sys/param.h>
34#include <sys/systm.h>
35#include <sys/kernel.h>
36#include <sys/module.h>
37#include <sys/sysctl.h>
38#include <sys/bus.h>
39#include <sys/malloc.h>
40#include <sys/proc.h>
41#include <sys/pcpu.h>
42#include <sys/lock.h>
43#include <sys/mutex.h>
44
45#include <machine/stdarg.h>
46
47#include <net/ethernet.h> /* XXX for ether_sprintf */
48
49#include <dev/ath/ath_hal/ah.h>
50
51/*
52 * WiSoC boards overload the bus tag with information about the
53 * board layout. We must extract the bus space tag from that
54 * indirect structure. For everyone else the tag is passed in
55 * directly.
56 * XXX cache indirect ref privately
57 */
58#ifdef AH_SUPPORT_AR5312
59#define BUSTAG(ah) \
60 ((bus_space_tag_t) ((struct ar531x_config *)((ah)->ah_st))->tag)
61#else
62#define BUSTAG(ah) ((ah)->ah_st)
63#endif
64
65/*
66 * This lock is used to seralise register access for chips which have
67 * problems w/ SMP CPUs issuing concurrent PCI transactions.
68 *
69 * XXX This is a global lock for now; it should be pushed to
70 * a per-device lock in some platform-independent fashion.
71 */
72struct mtx ah_regser_mtx;
73MTX_SYSINIT(ah_regser, &ah_regser_mtx, "Atheros register access mutex",
74 MTX_SPIN);
75
76extern void ath_hal_printf(struct ath_hal *, const char*, ...)
77 __printflike(2,3);
78extern void ath_hal_vprintf(struct ath_hal *, const char*, __va_list)
79 __printflike(2, 0);
80extern const char* ath_hal_ether_sprintf(const u_int8_t *mac);
81extern void *ath_hal_malloc(size_t);
82extern void ath_hal_free(void *);
83#ifdef AH_ASSERT
84extern void ath_hal_assert_failed(const char* filename,
85 int lineno, const char* msg);
86#endif
87#ifdef AH_DEBUG
88extern void DO_HALDEBUG(struct ath_hal *ah, u_int mask, const char* fmt, ...);
89#endif /* AH_DEBUG */
90
91/* NB: put this here instead of the driver to avoid circular references */
92SYSCTL_NODE(_hw, OID_AUTO, ath, CTLFLAG_RD, 0, "Atheros driver parameters");
93static SYSCTL_NODE(_hw_ath, OID_AUTO, hal, CTLFLAG_RD, 0,
94 "Atheros HAL parameters");
95
96#ifdef AH_DEBUG
97int ath_hal_debug = 0;
98SYSCTL_INT(_hw_ath_hal, OID_AUTO, debug, CTLFLAG_RW, &ath_hal_debug,
99 0, "Atheros HAL debugging printfs");
100TUNABLE_INT("hw.ath.hal.debug", &ath_hal_debug);
101#endif /* AH_DEBUG */
102
103static MALLOC_DEFINE(M_ATH_HAL, "ath_hal", "ath hal data");
104
105void*
106ath_hal_malloc(size_t size)
107{
108 return malloc(size, M_ATH_HAL, M_NOWAIT | M_ZERO);
109}
110
111void
112ath_hal_free(void* p)
113{
114 free(p, M_ATH_HAL);
115}
116
117void
118ath_hal_vprintf(struct ath_hal *ah, const char* fmt, va_list ap)
119{
120 vprintf(fmt, ap);
121}
122
123void
124ath_hal_printf(struct ath_hal *ah, const char* fmt, ...)
125{
126 va_list ap;
127 va_start(ap, fmt);
128 ath_hal_vprintf(ah, fmt, ap);
129 va_end(ap);
130}
131
132const char*
133ath_hal_ether_sprintf(const u_int8_t *mac)
134{
135 return ether_sprintf(mac);
136}
137
138#ifdef AH_DEBUG
139
140/* This must match the definition in ath_hal/ah_debug.h */
141#define HAL_DEBUG_UNMASKABLE 0xf0000000
142void
143DO_HALDEBUG(struct ath_hal *ah, u_int mask, const char* fmt, ...)
144{
145 if ((mask == HAL_DEBUG_UNMASKABLE) ||
146 (ah != NULL && ah->ah_config.ah_debug & mask) ||
147 (ath_hal_debug & mask)) {
148 __va_list ap;
149 va_start(ap, fmt);
150 ath_hal_vprintf(ah, fmt, ap);
151 va_end(ap);
152 }
153}
154#undef HAL_DEBUG_UNMASKABLE
155#endif /* AH_DEBUG */
156
157#ifdef AH_DEBUG_ALQ
158/*
159 * ALQ register tracing support.
160 *
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
166 * existing file.
167 *
168 * NB: doesn't handle multiple devices properly; only one DEVICE record
169 * is emitted and the different devices are not identified.
170 */
171#include <sys/alq.h>
172#include <sys/pcpu.h>
173#include <dev/ath/ath_hal/ah_decode.h>
174
175static struct alq *ath_hal_alq;
176static int ath_hal_alq_emitdev; /* need to emit DEVICE record */
177static u_int ath_hal_alq_lost; /* count of lost records */
178static char ath_hal_logfile[MAXPATHLEN] = "/tmp/ath_hal.log";
179
180SYSCTL_STRING(_hw_ath_hal, OID_AUTO, alq_logfile, CTLFLAG_RW,
181 &ath_hal_logfile, sizeof(kernelname), "Name of ALQ logfile");
182
183static u_int ath_hal_alq_qsize = 64*1024;
184
185static int
186ath_hal_setlogging(int enable)
187{
188 int error;
189
190 if (enable) {
191 error = alq_open(&ath_hal_alq, ath_hal_logfile,
192 curthread->td_ucred, ALQ_DEFAULT_CMODE,
193 sizeof (struct athregrec), ath_hal_alq_qsize);
194 ath_hal_alq_lost = 0;
195 ath_hal_alq_emitdev = 1;
196 printf("ath_hal: logging to %s enabled\n",
197 ath_hal_logfile);
198 } else {
199 if (ath_hal_alq)
200 alq_close(ath_hal_alq);
201 ath_hal_alq = NULL;
202 printf("ath_hal: logging disabled\n");
203 error = 0;
204 }
205 return (error);
206}
207
208static int
209sysctl_hw_ath_hal_log(SYSCTL_HANDLER_ARGS)
210{
211 int error, enable;
212
213 enable = (ath_hal_alq != NULL);
214 error = sysctl_handle_int(oidp, &enable, 0, req);
215 if (error || !req->newptr)
216 return (error);
217 else
218 return (ath_hal_setlogging(enable));
219}
220SYSCTL_PROC(_hw_ath_hal, OID_AUTO, alq, CTLTYPE_INT|CTLFLAG_RW,
221 0, 0, sysctl_hw_ath_hal_log, "I", "Enable HAL register logging");
222SYSCTL_INT(_hw_ath_hal, OID_AUTO, alq_size, CTLFLAG_RW,
223 &ath_hal_alq_qsize, 0, "In-memory log size (#records)");
224SYSCTL_INT(_hw_ath_hal, OID_AUTO, alq_lost, CTLFLAG_RW,
225 &ath_hal_alq_lost, 0, "Register operations not logged");
226
227static struct ale *
228ath_hal_alq_get(struct ath_hal *ah)
229{
230 struct ale *ale;
231
232 if (ath_hal_alq_emitdev) {
233 ale = alq_get(ath_hal_alq, ALQ_NOWAIT);
234 if (ale) {
235 struct athregrec *r =
236 (struct athregrec *) ale->ae_data;
237 r->op = OP_DEVICE;
238 r->reg = 0;
239 r->val = ah->ah_devid;
240 alq_post(ath_hal_alq, ale);
241 ath_hal_alq_emitdev = 0;
242 } else
243 ath_hal_alq_lost++;
244 }
245 ale = alq_get(ath_hal_alq, ALQ_NOWAIT);
246 if (!ale)
247 ath_hal_alq_lost++;
248 return ale;
249}
250
251void
252ath_hal_reg_write(struct ath_hal *ah, u_int32_t reg, u_int32_t val)
253{
254 bus_space_tag_t tag = BUSTAG(ah);
255 bus_space_handle_t h = ah->ah_sh;
256
257 if (ath_hal_alq) {
258 struct ale *ale = ath_hal_alq_get(ah);
259 if (ale) {
260 struct athregrec *r = (struct athregrec *) ale->ae_data;
261 r->threadid = curthread->td_tid;
262 r->op = OP_WRITE;
263 r->reg = reg;
264 r->val = val;
265 alq_post(ath_hal_alq, ale);
266 }
267 }
268 if (ah->ah_config.ah_serialise_reg_war)
269 mtx_lock_spin(&ah_regser_mtx);
30 */
31#include "opt_ah.h"
32
33#include <sys/param.h>
34#include <sys/systm.h>
35#include <sys/kernel.h>
36#include <sys/module.h>
37#include <sys/sysctl.h>
38#include <sys/bus.h>
39#include <sys/malloc.h>
40#include <sys/proc.h>
41#include <sys/pcpu.h>
42#include <sys/lock.h>
43#include <sys/mutex.h>
44
45#include <machine/stdarg.h>
46
47#include <net/ethernet.h> /* XXX for ether_sprintf */
48
49#include <dev/ath/ath_hal/ah.h>
50
51/*
52 * WiSoC boards overload the bus tag with information about the
53 * board layout. We must extract the bus space tag from that
54 * indirect structure. For everyone else the tag is passed in
55 * directly.
56 * XXX cache indirect ref privately
57 */
58#ifdef AH_SUPPORT_AR5312
59#define BUSTAG(ah) \
60 ((bus_space_tag_t) ((struct ar531x_config *)((ah)->ah_st))->tag)
61#else
62#define BUSTAG(ah) ((ah)->ah_st)
63#endif
64
65/*
66 * This lock is used to seralise register access for chips which have
67 * problems w/ SMP CPUs issuing concurrent PCI transactions.
68 *
69 * XXX This is a global lock for now; it should be pushed to
70 * a per-device lock in some platform-independent fashion.
71 */
72struct mtx ah_regser_mtx;
73MTX_SYSINIT(ah_regser, &ah_regser_mtx, "Atheros register access mutex",
74 MTX_SPIN);
75
76extern void ath_hal_printf(struct ath_hal *, const char*, ...)
77 __printflike(2,3);
78extern void ath_hal_vprintf(struct ath_hal *, const char*, __va_list)
79 __printflike(2, 0);
80extern const char* ath_hal_ether_sprintf(const u_int8_t *mac);
81extern void *ath_hal_malloc(size_t);
82extern void ath_hal_free(void *);
83#ifdef AH_ASSERT
84extern void ath_hal_assert_failed(const char* filename,
85 int lineno, const char* msg);
86#endif
87#ifdef AH_DEBUG
88extern void DO_HALDEBUG(struct ath_hal *ah, u_int mask, const char* fmt, ...);
89#endif /* AH_DEBUG */
90
91/* NB: put this here instead of the driver to avoid circular references */
92SYSCTL_NODE(_hw, OID_AUTO, ath, CTLFLAG_RD, 0, "Atheros driver parameters");
93static SYSCTL_NODE(_hw_ath, OID_AUTO, hal, CTLFLAG_RD, 0,
94 "Atheros HAL parameters");
95
96#ifdef AH_DEBUG
97int ath_hal_debug = 0;
98SYSCTL_INT(_hw_ath_hal, OID_AUTO, debug, CTLFLAG_RW, &ath_hal_debug,
99 0, "Atheros HAL debugging printfs");
100TUNABLE_INT("hw.ath.hal.debug", &ath_hal_debug);
101#endif /* AH_DEBUG */
102
103static MALLOC_DEFINE(M_ATH_HAL, "ath_hal", "ath hal data");
104
105void*
106ath_hal_malloc(size_t size)
107{
108 return malloc(size, M_ATH_HAL, M_NOWAIT | M_ZERO);
109}
110
111void
112ath_hal_free(void* p)
113{
114 free(p, M_ATH_HAL);
115}
116
117void
118ath_hal_vprintf(struct ath_hal *ah, const char* fmt, va_list ap)
119{
120 vprintf(fmt, ap);
121}
122
123void
124ath_hal_printf(struct ath_hal *ah, const char* fmt, ...)
125{
126 va_list ap;
127 va_start(ap, fmt);
128 ath_hal_vprintf(ah, fmt, ap);
129 va_end(ap);
130}
131
132const char*
133ath_hal_ether_sprintf(const u_int8_t *mac)
134{
135 return ether_sprintf(mac);
136}
137
138#ifdef AH_DEBUG
139
140/* This must match the definition in ath_hal/ah_debug.h */
141#define HAL_DEBUG_UNMASKABLE 0xf0000000
142void
143DO_HALDEBUG(struct ath_hal *ah, u_int mask, const char* fmt, ...)
144{
145 if ((mask == HAL_DEBUG_UNMASKABLE) ||
146 (ah != NULL && ah->ah_config.ah_debug & mask) ||
147 (ath_hal_debug & mask)) {
148 __va_list ap;
149 va_start(ap, fmt);
150 ath_hal_vprintf(ah, fmt, ap);
151 va_end(ap);
152 }
153}
154#undef HAL_DEBUG_UNMASKABLE
155#endif /* AH_DEBUG */
156
157#ifdef AH_DEBUG_ALQ
158/*
159 * ALQ register tracing support.
160 *
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
166 * existing file.
167 *
168 * NB: doesn't handle multiple devices properly; only one DEVICE record
169 * is emitted and the different devices are not identified.
170 */
171#include <sys/alq.h>
172#include <sys/pcpu.h>
173#include <dev/ath/ath_hal/ah_decode.h>
174
175static struct alq *ath_hal_alq;
176static int ath_hal_alq_emitdev; /* need to emit DEVICE record */
177static u_int ath_hal_alq_lost; /* count of lost records */
178static char ath_hal_logfile[MAXPATHLEN] = "/tmp/ath_hal.log";
179
180SYSCTL_STRING(_hw_ath_hal, OID_AUTO, alq_logfile, CTLFLAG_RW,
181 &ath_hal_logfile, sizeof(kernelname), "Name of ALQ logfile");
182
183static u_int ath_hal_alq_qsize = 64*1024;
184
185static int
186ath_hal_setlogging(int enable)
187{
188 int error;
189
190 if (enable) {
191 error = alq_open(&ath_hal_alq, ath_hal_logfile,
192 curthread->td_ucred, ALQ_DEFAULT_CMODE,
193 sizeof (struct athregrec), ath_hal_alq_qsize);
194 ath_hal_alq_lost = 0;
195 ath_hal_alq_emitdev = 1;
196 printf("ath_hal: logging to %s enabled\n",
197 ath_hal_logfile);
198 } else {
199 if (ath_hal_alq)
200 alq_close(ath_hal_alq);
201 ath_hal_alq = NULL;
202 printf("ath_hal: logging disabled\n");
203 error = 0;
204 }
205 return (error);
206}
207
208static int
209sysctl_hw_ath_hal_log(SYSCTL_HANDLER_ARGS)
210{
211 int error, enable;
212
213 enable = (ath_hal_alq != NULL);
214 error = sysctl_handle_int(oidp, &enable, 0, req);
215 if (error || !req->newptr)
216 return (error);
217 else
218 return (ath_hal_setlogging(enable));
219}
220SYSCTL_PROC(_hw_ath_hal, OID_AUTO, alq, CTLTYPE_INT|CTLFLAG_RW,
221 0, 0, sysctl_hw_ath_hal_log, "I", "Enable HAL register logging");
222SYSCTL_INT(_hw_ath_hal, OID_AUTO, alq_size, CTLFLAG_RW,
223 &ath_hal_alq_qsize, 0, "In-memory log size (#records)");
224SYSCTL_INT(_hw_ath_hal, OID_AUTO, alq_lost, CTLFLAG_RW,
225 &ath_hal_alq_lost, 0, "Register operations not logged");
226
227static struct ale *
228ath_hal_alq_get(struct ath_hal *ah)
229{
230 struct ale *ale;
231
232 if (ath_hal_alq_emitdev) {
233 ale = alq_get(ath_hal_alq, ALQ_NOWAIT);
234 if (ale) {
235 struct athregrec *r =
236 (struct athregrec *) ale->ae_data;
237 r->op = OP_DEVICE;
238 r->reg = 0;
239 r->val = ah->ah_devid;
240 alq_post(ath_hal_alq, ale);
241 ath_hal_alq_emitdev = 0;
242 } else
243 ath_hal_alq_lost++;
244 }
245 ale = alq_get(ath_hal_alq, ALQ_NOWAIT);
246 if (!ale)
247 ath_hal_alq_lost++;
248 return ale;
249}
250
251void
252ath_hal_reg_write(struct ath_hal *ah, u_int32_t reg, u_int32_t val)
253{
254 bus_space_tag_t tag = BUSTAG(ah);
255 bus_space_handle_t h = ah->ah_sh;
256
257 if (ath_hal_alq) {
258 struct ale *ale = ath_hal_alq_get(ah);
259 if (ale) {
260 struct athregrec *r = (struct athregrec *) ale->ae_data;
261 r->threadid = curthread->td_tid;
262 r->op = OP_WRITE;
263 r->reg = reg;
264 r->val = val;
265 alq_post(ath_hal_alq, ale);
266 }
267 }
268 if (ah->ah_config.ah_serialise_reg_war)
269 mtx_lock_spin(&ah_regser_mtx);
270#if _BYTE_ORDER == _BIG_ENDIAN
271 if (OS_REG_UNSWAPPED(reg))
272 bus_space_write_4(tag, h, reg, val);
273 else
274#endif
275 bus_space_write_stream_4(tag, h, reg, val);
270 bus_space_write_4(tag, h, reg, val);
276 if (ah->ah_config.ah_serialise_reg_war)
277 mtx_unlock_spin(&ah_regser_mtx);
278}
279
280u_int32_t
281ath_hal_reg_read(struct ath_hal *ah, u_int32_t reg)
282{
283 bus_space_tag_t tag = BUSTAG(ah);
284 bus_space_handle_t h = ah->ah_sh;
285 u_int32_t val;
286
287 if (ah->ah_config.ah_serialise_reg_war)
288 mtx_lock_spin(&ah_regser_mtx);
271 if (ah->ah_config.ah_serialise_reg_war)
272 mtx_unlock_spin(&ah_regser_mtx);
273}
274
275u_int32_t
276ath_hal_reg_read(struct ath_hal *ah, u_int32_t reg)
277{
278 bus_space_tag_t tag = BUSTAG(ah);
279 bus_space_handle_t h = ah->ah_sh;
280 u_int32_t val;
281
282 if (ah->ah_config.ah_serialise_reg_war)
283 mtx_lock_spin(&ah_regser_mtx);
289#if _BYTE_ORDER == _BIG_ENDIAN
290 if (OS_REG_UNSWAPPED(reg))
291 val = bus_space_read_4(tag, h, reg);
292 else
293#endif
294 val = bus_space_read_stream_4(tag, h, reg);
284 val = bus_space_read_4(tag, h, reg);
295 if (ah->ah_config.ah_serialise_reg_war)
296 mtx_unlock_spin(&ah_regser_mtx);
297 if (ath_hal_alq) {
298 struct ale *ale = ath_hal_alq_get(ah);
299 if (ale) {
300 struct athregrec *r = (struct athregrec *) ale->ae_data;
301 r->threadid = curthread->td_tid;
302 r->op = OP_READ;
303 r->reg = reg;
304 r->val = val;
305 alq_post(ath_hal_alq, ale);
306 }
307 }
308 return val;
309}
310
311void
312OS_MARK(struct ath_hal *ah, u_int id, u_int32_t v)
313{
314 if (ath_hal_alq) {
315 struct ale *ale = ath_hal_alq_get(ah);
316 if (ale) {
317 struct athregrec *r = (struct athregrec *) ale->ae_data;
318 r->threadid = curthread->td_tid;
319 r->op = OP_MARK;
320 r->reg = id;
321 r->val = v;
322 alq_post(ath_hal_alq, ale);
323 }
324 }
325}
326#elif defined(AH_DEBUG) || defined(AH_REGOPS_FUNC)
327/*
328 * Memory-mapped device register read/write. These are here
329 * as routines when debugging support is enabled and/or when
330 * explicitly configured to use function calls. The latter is
331 * for architectures that might need to do something before
332 * referencing memory (e.g. remap an i/o window).
333 *
334 * NB: see the comments in ah_osdep.h about byte-swapping register
335 * reads and writes to understand what's going on below.
336 */
337
338void
339ath_hal_reg_write(struct ath_hal *ah, u_int32_t reg, u_int32_t val)
340{
341 bus_space_tag_t tag = BUSTAG(ah);
342 bus_space_handle_t h = ah->ah_sh;
343
344 if (ah->ah_config.ah_serialise_reg_war)
345 mtx_lock_spin(&ah_regser_mtx);
285 if (ah->ah_config.ah_serialise_reg_war)
286 mtx_unlock_spin(&ah_regser_mtx);
287 if (ath_hal_alq) {
288 struct ale *ale = ath_hal_alq_get(ah);
289 if (ale) {
290 struct athregrec *r = (struct athregrec *) ale->ae_data;
291 r->threadid = curthread->td_tid;
292 r->op = OP_READ;
293 r->reg = reg;
294 r->val = val;
295 alq_post(ath_hal_alq, ale);
296 }
297 }
298 return val;
299}
300
301void
302OS_MARK(struct ath_hal *ah, u_int id, u_int32_t v)
303{
304 if (ath_hal_alq) {
305 struct ale *ale = ath_hal_alq_get(ah);
306 if (ale) {
307 struct athregrec *r = (struct athregrec *) ale->ae_data;
308 r->threadid = curthread->td_tid;
309 r->op = OP_MARK;
310 r->reg = id;
311 r->val = v;
312 alq_post(ath_hal_alq, ale);
313 }
314 }
315}
316#elif defined(AH_DEBUG) || defined(AH_REGOPS_FUNC)
317/*
318 * Memory-mapped device register read/write. These are here
319 * as routines when debugging support is enabled and/or when
320 * explicitly configured to use function calls. The latter is
321 * for architectures that might need to do something before
322 * referencing memory (e.g. remap an i/o window).
323 *
324 * NB: see the comments in ah_osdep.h about byte-swapping register
325 * reads and writes to understand what's going on below.
326 */
327
328void
329ath_hal_reg_write(struct ath_hal *ah, u_int32_t reg, u_int32_t val)
330{
331 bus_space_tag_t tag = BUSTAG(ah);
332 bus_space_handle_t h = ah->ah_sh;
333
334 if (ah->ah_config.ah_serialise_reg_war)
335 mtx_lock_spin(&ah_regser_mtx);
346#if _BYTE_ORDER == _BIG_ENDIAN
347 if (OS_REG_UNSWAPPED(reg))
348 bus_space_write_4(tag, h, reg, val);
349 else
350#endif
351 bus_space_write_stream_4(tag, h, reg, val);
336 bus_space_write_4(tag, h, reg, val);
352 if (ah->ah_config.ah_serialise_reg_war)
353 mtx_unlock_spin(&ah_regser_mtx);
354}
355
356u_int32_t
357ath_hal_reg_read(struct ath_hal *ah, u_int32_t reg)
358{
359 bus_space_tag_t tag = BUSTAG(ah);
360 bus_space_handle_t h = ah->ah_sh;
361 u_int32_t val;
362
363 if (ah->ah_config.ah_serialise_reg_war)
364 mtx_lock_spin(&ah_regser_mtx);
337 if (ah->ah_config.ah_serialise_reg_war)
338 mtx_unlock_spin(&ah_regser_mtx);
339}
340
341u_int32_t
342ath_hal_reg_read(struct ath_hal *ah, u_int32_t reg)
343{
344 bus_space_tag_t tag = BUSTAG(ah);
345 bus_space_handle_t h = ah->ah_sh;
346 u_int32_t val;
347
348 if (ah->ah_config.ah_serialise_reg_war)
349 mtx_lock_spin(&ah_regser_mtx);
365#if _BYTE_ORDER == _BIG_ENDIAN
366 if (OS_REG_UNSWAPPED(reg))
367 val = bus_space_read_4(tag, h, reg);
368 else
369#endif
370 val = bus_space_read_stream_4(tag, h, reg);
350 val = bus_space_read_4(tag, h, reg);
371 if (ah->ah_config.ah_serialise_reg_war)
372 mtx_unlock_spin(&ah_regser_mtx);
373 return val;
374}
375#endif /* AH_DEBUG || AH_REGOPS_FUNC */
376
377#ifdef AH_ASSERT
378void
379ath_hal_assert_failed(const char* filename, int lineno, const char *msg)
380{
381 printf("Atheros HAL assertion failure: %s: line %u: %s\n",
382 filename, lineno, msg);
383 panic("ath_hal_assert");
384}
385#endif /* AH_ASSERT */
351 if (ah->ah_config.ah_serialise_reg_war)
352 mtx_unlock_spin(&ah_regser_mtx);
353 return val;
354}
355#endif /* AH_DEBUG || AH_REGOPS_FUNC */
356
357#ifdef AH_ASSERT
358void
359ath_hal_assert_failed(const char* filename, int lineno, const char *msg)
360{
361 printf("Atheros HAL assertion failure: %s: line %u: %s\n",
362 filename, lineno, msg);
363 panic("ath_hal_assert");
364}
365#endif /* AH_ASSERT */