Rename malloc->kmalloc, free->kfree, and realloc->krealloc. Pass 1
[dragonfly.git] / sys / contrib / dev / ath / dragonfly / ah_osdep.c
1 /*-
2  * Copyright (c) 2002-2006 Sam Leffler, Errno Consulting, Atheros
3  * Communications, Inc.  All rights reserved.
4  *
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
8  *    unmodified.
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
12  *    modification.
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
20  *    permission.
21  *
22  * NO WARRANTY
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
34  * SUCH DAMAGES.
35  *
36  * $Id: //depot/sw/linuxsrc/src/802_11/madwifi/hal/main/freebsd/ah_osdep.c#39 $
37  */
38 #include "opt_ah.h"
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>
45 #include <sys/bus.h>
46 #include <sys/malloc.h>
47 #include <sys/proc.h>
48
49 #include <machine/stdarg.h>
50
51 #include <net/ethernet.h>               /* XXX for ether_sprintf */
52
53 #include <contrib/dev/ath/ah.h>
54
55 extern  void ath_hal_printf(struct ath_hal *, const char*, ...)
56                 __printflike(2,3);
57 extern  void ath_hal_vprintf(struct ath_hal *, const char*, __va_list)
58                 __printflike(2, 0);
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 *);
62 #ifdef AH_ASSERT
63 extern  void ath_hal_assert_failed(const char* filename,
64                 int lineno, const char* msg);
65 #endif
66 #ifdef AH_DEBUG
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, ...);
69 #endif /* AH_DEBUG */
70
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");
74
75 #ifdef AH_DEBUG
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);
80 #endif /* AH_DEBUG */
81
82 SYSCTL_STRING(_hw_ath_hal, OID_AUTO, version, CTLFLAG_RD, ath_hal_version, 0,
83         "Atheros HAL version");
84
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");
97
98 MALLOC_DEFINE(M_ATH_HAL, "ath_hal", "ath hal data");
99
100 void*
101 ath_hal_malloc(size_t size)
102 {
103         return kmalloc(size, M_ATH_HAL, M_NOWAIT | M_ZERO);
104 }
105
106 void
107 ath_hal_free(void* p)
108 {
109         return kfree(p, M_ATH_HAL);
110 }
111
112 void
113 ath_hal_vprintf(struct ath_hal *ah, const char* fmt, va_list ap)
114 {
115         vprintf(fmt, ap);
116 }
117
118 void
119 ath_hal_printf(struct ath_hal *ah, const char* fmt, ...)
120 {
121         va_list ap;
122         va_start(ap, fmt);
123         ath_hal_vprintf(ah, fmt, ap);
124         va_end(ap);
125 }
126
127 const char*
128 ath_hal_ether_sprintf(const u_int8_t *mac)
129 {
130         return ether_sprintf(mac);
131 }
132
133 #ifdef AH_DEBUG
134 void
135 HALDEBUG(struct ath_hal *ah, const char* fmt, ...)
136 {
137         if (ath_hal_debug) {
138                 __va_list ap;
139                 va_start(ap, fmt);
140                 ath_hal_vprintf(ah, fmt, ap);
141                 va_end(ap);
142         }
143 }
144
145 void
146 HALDEBUGn(struct ath_hal *ah, u_int level, const char* fmt, ...)
147 {
148         if (ath_hal_debug >= level) {
149                 __va_list ap;
150                 va_start(ap, fmt);
151                 ath_hal_vprintf(ah, fmt, ap);
152                 va_end(ap);
153         }
154 }
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 <contrib/dev/ath/ah_decode.h>
174
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;
180
181 static int
182 ath_hal_setlogging(int enable)
183 {
184         int error;
185
186         if (enable) {
187                 error = suser(curthread);
188                 if (error == 0) {
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",
195                                 ath_hal_logfile);
196                 }
197         } else {
198                 if (ath_hal_alq)
199                         alq_close(ath_hal_alq);
200                 ath_hal_alq = NULL;
201                 printf("ath_hal: logging disabled\n");
202                 error = 0;
203         }
204         return (error);
205 }
206
207 static int
208 sysctl_hw_ath_hal_log(SYSCTL_HANDLER_ARGS)
209 {
210         int error, enable;
211
212         enable = (ath_hal_alq != NULL);
213         error = sysctl_handle_int(oidp, &enable, 0, req);
214         if (error || !req->newptr)
215                 return (error);
216         else
217                 return (ath_hal_setlogging(enable));
218 }
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");
225
226 static struct ale *
227 ath_hal_alq_get(struct ath_hal *ah)
228 {
229         struct ale *ale;
230
231         if (ath_hal_alq_emitdev) {
232                 ale = alq_get(ath_hal_alq, ALQ_NOWAIT);
233                 if (ale) {
234                         struct athregrec *r =
235                                 (struct athregrec *) ale->ae_data;
236                         r->op = OP_DEVICE;
237                         r->reg = 0;
238                         r->val = ah->ah_devid;
239                         alq_post(ath_hal_alq, ale);
240                         ath_hal_alq_emitdev = 0;
241                 } else
242                         ath_hal_alq_lost++;
243         }
244         ale = alq_get(ath_hal_alq, ALQ_NOWAIT);
245         if (!ale)
246                 ath_hal_alq_lost++;
247         return ale;
248 }
249
250 void
251 ath_hal_reg_write(struct ath_hal *ah, u_int32_t reg, u_int32_t val)
252 {
253         if (ath_hal_alq) {
254                 struct ale *ale = ath_hal_alq_get(ah);
255                 if (ale) {
256                         struct athregrec *r = (struct athregrec *) ale->ae_data;
257                         r->op = OP_WRITE;
258                         r->reg = reg;
259                         r->val = val;
260                         alq_post(ath_hal_alq, ale);
261                 }
262         }
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));
266         else
267 #endif
268                 bus_space_write_4(ah->ah_st, ah->ah_sh, reg, val);
269 }
270
271 u_int32_t
272 ath_hal_reg_read(struct ath_hal *ah, u_int32_t reg)
273 {
274         u_int32_t val;
275
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)
279                 val = le32toh(val);
280 #endif
281         if (ath_hal_alq) {
282                 struct ale *ale = ath_hal_alq_get(ah);
283                 if (ale) {
284                         struct athregrec *r = (struct athregrec *) ale->ae_data;
285                         r->op = OP_READ;
286                         r->reg = reg;
287                         r->val = val;
288                         alq_post(ath_hal_alq, ale);
289                 }
290         }
291         return val;
292 }
293
294 void
295 OS_MARK(struct ath_hal *ah, u_int id, u_int32_t v)
296 {
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->op = OP_MARK;
302                         r->reg = id;
303                         r->val = v;
304                         alq_post(ath_hal_alq, ale);
305                 }
306         }
307 }
308 #elif defined(AH_DEBUG) || defined(AH_REGOPS_FUNC)
309 /*
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).
315  *
316  * NB: see the comments in ah_osdep.h about byte-swapping register
317  *     reads and writes to understand what's going on below.
318  */
319
320 void
321 ath_hal_reg_write(struct ath_hal *ah, u_int32_t reg, u_int32_t val)
322 {
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));
326         else
327 #endif
328                 bus_space_write_4(ah->ah_st, ah->ah_sh, reg, val);
329 }
330
331 u_int32_t
332 ath_hal_reg_read(struct ath_hal *ah, u_int32_t reg)
333 {
334         u_int32_t val;
335
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)
339                 val = le32toh(val);
340 #endif
341         return val;
342 }
343 #endif /* AH_DEBUG || AH_REGOPS_FUNC */
344
345 #ifdef AH_ASSERT
346 void
347 ath_hal_assert_failed(const char* filename, int lineno, const char *msg)
348 {
349         printf("Atheros HAL assertion failure: %s: line %u: %s\n",
350                 filename, lineno, msg);
351         panic("ath_hal_assert");
352 }
353 #endif /* AH_ASSERT */
354
355 /*
356  * Delay n microseconds.
357  */
358 void
359 ath_hal_delay(int n)
360 {
361         DELAY(n);
362 }
363
364 u_int32_t
365 ath_hal_getuptime(struct ath_hal *ah)
366 {
367         struct bintime bt;
368         getbinuptime(&bt);
369         return (bt.sec * 1000) +
370                 (((uint64_t)1000 * (uint32_t)(bt.frac >> 32)) >> 32);
371 }
372
373 void
374 ath_hal_memzero(void *dst, size_t n)
375 {
376         bzero(dst, n);
377 }
378
379 void *
380 ath_hal_memcpy(void *dst, const void *src, size_t n)
381 {
382         return memcpy(dst, src, n);
383 }
384
385 /*
386  * Module glue.
387  */
388
389 static int
390 ath_hal_modevent(module_t mod, int type, void *unused)
391 {
392         const char *sep;
393         int i;
394
395         switch (type) {
396         case MOD_LOAD:
397                 printf("ath_hal: %s (", ath_hal_version);
398                 sep = "";
399                 for (i = 0; ath_hal_buildopts[i] != NULL; i++) {
400                         printf("%s%s", sep, ath_hal_buildopts[i]);
401                         sep = ", ";
402                 }
403                 printf(")\n");
404                 return 0;
405         case MOD_UNLOAD:
406                 return 0;
407         }
408         return EINVAL;
409 }
410
411 static moduledata_t ath_hal_mod = {
412         "ath_hal",
413         ath_hal_modevent,
414         0
415 };
416 DECLARE_MODULE(ath_hal, ath_hal_mod, SI_SUB_DRIVERS, SI_ORDER_ANY);
417 MODULE_VERSION(ath_hal, 1);