K2.6 patches and update.
[tomato.git] / release / src-rt / include / linux_osl.h
blobb4ec0742a8b5188da29608eb44da564e7cd5cad8
1 /*
2 * Linux OS Independent Layer
4 * Copyright (C) 2010, Broadcom Corporation. All Rights Reserved.
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
13 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
15 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
16 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 * $Id: linux_osl.h,v 13.160.2.9 2010-12-08 07:33:07 Exp $
21 #ifndef _linux_osl_h_
22 #define _linux_osl_h_
24 #include <typedefs.h>
26 /* Linux Kernel: File Operations: start */
27 extern void * osl_os_open_image(char * filename);
28 extern int osl_os_get_image_block(char * buf, int len, void * image);
29 extern void osl_os_close_image(void * image);
30 extern int osl_os_image_size(void *image);
31 /* Linux Kernel: File Operations: end */
33 #ifdef BCMDRIVER
35 /* OSL initialization */
36 extern osl_t *osl_attach(void *pdev, uint bustype, bool pkttag);
37 extern void osl_detach(osl_t *osh);
39 /* Global ASSERT type */
40 extern uint32 g_assert_type;
42 /* ASSERT */
43 #if defined(BCMDBG_ASSERT)
44 #define ASSERT(exp) \
45 do { if (!(exp)) osl_assert(#exp, __FILE__, __LINE__); } while (0)
46 extern void osl_assert(const char *exp, const char *file, int line);
47 #else
48 #ifdef __GNUC__
49 #define GCC_VERSION \
50 (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
51 #if GCC_VERSION > 30100
52 #define ASSERT(exp) do {} while (0)
53 #else
54 /* ASSERT could cause segmentation fault on GCC3.1, use empty instead */
55 #define ASSERT(exp)
56 #endif /* GCC_VERSION > 30100 */
57 #endif /* __GNUC__ */
58 #endif
60 /* microsecond delay */
61 #define OSL_DELAY(usec) osl_delay(usec)
62 extern void osl_delay(uint usec);
64 #define OSL_PCMCIA_READ_ATTR(osh, offset, buf, size) \
65 osl_pcmcia_read_attr((osh), (offset), (buf), (size))
66 #define OSL_PCMCIA_WRITE_ATTR(osh, offset, buf, size) \
67 osl_pcmcia_write_attr((osh), (offset), (buf), (size))
68 extern void osl_pcmcia_read_attr(osl_t *osh, uint offset, void *buf, int size);
69 extern void osl_pcmcia_write_attr(osl_t *osh, uint offset, void *buf, int size);
71 /* PCI configuration space access macros */
72 #define OSL_PCI_READ_CONFIG(osh, offset, size) \
73 osl_pci_read_config((osh), (offset), (size))
74 #define OSL_PCI_WRITE_CONFIG(osh, offset, size, val) \
75 osl_pci_write_config((osh), (offset), (size), (val))
76 extern uint32 osl_pci_read_config(osl_t *osh, uint offset, uint size);
77 extern void osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val);
79 /* PCI device bus # and slot # */
80 #define OSL_PCI_BUS(osh) osl_pci_bus(osh)
81 #define OSL_PCI_SLOT(osh) osl_pci_slot(osh)
82 extern uint osl_pci_bus(osl_t *osh);
83 extern uint osl_pci_slot(osl_t *osh);
85 /* Pkttag flag should be part of public information */
86 typedef struct {
87 bool pkttag;
88 uint pktalloced; /* Number of allocated packet buffers */
89 bool mmbus; /* Bus supports memory-mapped register accesses */
90 pktfree_cb_fn_t tx_fn; /* Callback function for PKTFREE */
91 void *tx_ctx; /* Context to the callback function */
92 #if defined(OSLREGOPS) || (defined(WLC_HIGH) && !defined(WLC_LOW))
93 osl_rreg_fn_t rreg_fn; /* Read Register function */
94 osl_wreg_fn_t wreg_fn; /* Write Register function */
95 void *reg_ctx; /* Context to the reg callback functions */
96 #else
97 void *unused[3];
98 #endif
99 } osl_pubinfo_t;
101 #define PKTFREESETCB(osh, _tx_fn, _tx_ctx) \
102 do { \
103 ((osl_pubinfo_t*)osh)->tx_fn = _tx_fn; \
104 ((osl_pubinfo_t*)osh)->tx_ctx = _tx_ctx; \
105 } while (0)
107 #ifdef OSLREGOPS
108 #define REGOPSSET(osh, rreg, wreg, ctx) \
109 do { \
110 ((osl_pubinfo_t*)osh)->rreg_fn = rreg; \
111 ((osl_pubinfo_t*)osh)->wreg_fn = wreg; \
112 ((osl_pubinfo_t*)osh)->reg_ctx = ctx; \
113 } while (0)
114 #endif /* OSLREGOPS */
116 /* host/bus architecture-specific byte swap */
117 #define BUS_SWAP32(v) (v)
119 #ifdef BCMDBG_MEM
120 #define MALLOC(osh, size) osl_debug_malloc((osh), (size), __LINE__, __FILE__)
121 #define MFREE(osh, addr, size) osl_debug_mfree((osh), (addr), (size), __LINE__, __FILE__)
122 #define MALLOCED(osh) osl_malloced((osh))
123 #define MALLOC_DUMP(osh, b) osl_debug_memdump((osh), (b))
124 extern void *osl_debug_malloc(osl_t *osh, uint size, int line, char* file);
125 extern void osl_debug_mfree(osl_t *osh, void *addr, uint size, int line, char* file);
126 extern uint osl_malloced(osl_t *osh);
127 struct bcmstrbuf;
128 extern int osl_debug_memdump(osl_t *osh, struct bcmstrbuf *b);
129 #else
130 #define MALLOC(osh, size) osl_malloc((osh), (size))
131 #define MFREE(osh, addr, size) osl_mfree((osh), (addr), (size))
132 #define MALLOCED(osh) osl_malloced((osh))
133 extern void *osl_malloc(osl_t *osh, uint size);
134 extern void osl_mfree(osl_t *osh, void *addr, uint size);
135 extern uint osl_malloced(osl_t *osh);
136 #endif /* BCMDBG_MEM */
138 #define NATIVE_MALLOC(osh, size) kmalloc(size, GFP_ATOMIC)
139 #define NATIVE_MFREE(osh, addr, size) kfree(addr)
141 #if defined(USBAP) || defined(WL_VMEM_NVRAM_DECOMP)
142 #include <linuxver.h> /* use current 2.4.x calling conventions */
143 #include <linux/vmalloc.h>
144 #define VMALLOC(osh, size) vmalloc(size)
145 #define VFREE(osh, addr, size) vfree(addr)
146 #endif
148 #define MALLOC_FAILED(osh) osl_malloc_failed((osh))
149 extern uint osl_malloc_failed(osl_t *osh);
151 /* allocate/free shared (dma-able) consistent memory */
152 #define DMA_CONSISTENT_ALIGN osl_dma_consistent_align()
153 #define DMA_ALLOC_CONSISTENT(osh, size, align, tot, pap, dmah) \
154 osl_dma_alloc_consistent((osh), (size), (align), (tot), (pap))
155 #define DMA_FREE_CONSISTENT(osh, va, size, pa, dmah) \
156 osl_dma_free_consistent((osh), (void*)(va), (size), (pa))
157 extern uint osl_dma_consistent_align(void);
158 extern void *osl_dma_alloc_consistent(osl_t *osh, uint size, uint16 align, uint *tot, ulong *pap);
159 extern void osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa);
161 /* map/unmap direction */
162 #define DMA_TX 1 /* TX direction for DMA */
163 #define DMA_RX 2 /* RX direction for DMA */
165 /* map/unmap shared (dma-able) memory */
166 #define DMA_UNMAP(osh, pa, size, direction, p, dmah) \
167 osl_dma_unmap((osh), (pa), (size), (direction))
168 extern uint osl_dma_map(osl_t *osh, void *va, uint size, int direction);
169 extern void osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction);
171 /* API for DMA addressing capability */
172 #define OSL_DMADDRWIDTH(osh, addrwidth) do {} while (0)
174 /* register access macros */
175 #if defined(BCMJTAG)
176 #include <bcmjtag.h>
177 #define OSL_WRITE_REG(osh, r, v) (bcmjtag_write(NULL, (uintptr)(r), (v), sizeof(*(r))))
178 #define OSL_READ_REG(osh, r) (bcmjtag_read(NULL, (uintptr)(r), sizeof(*(r))))
179 #endif
181 #if defined(BCMJTAG)
182 #define SELECT_BUS_WRITE(osh, mmap_op, bus_op) if (((osl_pubinfo_t*)(osh))->mmbus) \
183 mmap_op else bus_op
184 #define SELECT_BUS_READ(osh, mmap_op, bus_op) (((osl_pubinfo_t*)(osh))->mmbus) ? \
185 mmap_op : bus_op
186 #else
187 #define SELECT_BUS_WRITE(osh, mmap_op, bus_op) mmap_op
188 #define SELECT_BUS_READ(osh, mmap_op, bus_op) mmap_op
189 #endif
191 #define OSL_ERROR(bcmerror) osl_error(bcmerror)
192 extern int osl_error(int bcmerror);
194 /* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */
195 #define PKTBUFSZ 2048 /* largest reasonable packet buffer, driver uses for ethernet MTU */
198 * BINOSL selects the slightly slower function-call-based binary compatible osl.
199 * Macros expand to calls to functions defined in linux_osl.c .
201 #ifndef BINOSL
203 #include <linuxver.h> /* use current 2.4.x calling conventions */
204 #include <linux/kernel.h> /* for vsn/printf's */
205 #include <linux/string.h> /* for mem*, str* */
207 #define OSL_SYSUPTIME() ((uint32)jiffies * (1000 / HZ))
208 #define printf(fmt, args...) printk(fmt , ## args)
210 /* bcopy's: Linux kernel doesn't provide these (anymore) */
211 #define bcopy(src, dst, len) memcpy((dst), (src), (len))
212 #define bcmp(b1, b2, len) memcmp((b1), (b2), (len))
213 #define bzero(b, len) memset((b), '\0', (len))
215 extern uint8 osl_readb(osl_t *osh, volatile uint8 *r);
216 extern uint16 osl_readw(osl_t *osh, volatile uint16 *r);
217 extern uint32 osl_readl(osl_t *osh, volatile uint32 *r);
218 extern void osl_writeb(osl_t *osh, volatile uint8 *r, uint8 v);
219 extern void osl_writew(osl_t *osh, volatile uint16 *r, uint16 v);
220 extern void osl_writel(osl_t *osh, volatile uint32 *r, uint32 v);
221 /* register access macros */
222 #if defined(OSLREGOPS)
223 #define R_REG(osh, r) (\
224 sizeof(*(r)) == sizeof(uint8) ? osl_readb((osh), (volatile uint8*)(r)) : \
225 sizeof(*(r)) == sizeof(uint16) ? osl_readw((osh), (volatile uint16*)(r)) : \
226 osl_readl((osh), (volatile uint32*)(r)) \
228 #define W_REG(osh, r, v) do { \
229 switch (sizeof(*(r))) { \
230 case sizeof(uint8): osl_writeb((osh), (volatile uint8*)(r), (uint8)(v)); break; \
231 case sizeof(uint16): osl_writew((osh), (volatile uint16*)(r), (uint16)(v)); break; \
232 case sizeof(uint32): osl_writel((osh), (volatile uint32*)(r), (uint32)(v)); break; \
234 } while (0)
237 #else /* OSLREGOPS */
239 #ifndef IL_BIGENDIAN
240 #ifndef __mips__
241 #define R_REG(osh, r) (\
242 SELECT_BUS_READ(osh, sizeof(*(r)) == sizeof(uint8) ? readb((volatile uint8*)(r)) : \
243 sizeof(*(r)) == sizeof(uint16) ? readw((volatile uint16*)(r)) : \
244 readl((volatile uint32*)(r)), OSL_READ_REG(osh, r)) \
246 #else /* __mips__ */
247 #define R_REG(osh, r) (\
248 SELECT_BUS_READ(osh, \
249 ({ \
250 __typeof(*(r)) __osl_v; \
251 __asm__ __volatile__("sync"); \
252 switch (sizeof(*(r))) { \
253 case sizeof(uint8): __osl_v = \
254 readb((volatile uint8*)(r)); break; \
255 case sizeof(uint16): __osl_v = \
256 readw((volatile uint16*)(r)); break; \
257 case sizeof(uint32): __osl_v = \
258 readl((volatile uint32*)(r)); break; \
260 __asm__ __volatile__("sync"); \
261 __osl_v; \
262 }), \
263 ({ \
264 __typeof(*(r)) __osl_v; \
265 __asm__ __volatile__("sync"); \
266 __osl_v = OSL_READ_REG(osh, r); \
267 __asm__ __volatile__("sync"); \
268 __osl_v; \
269 })) \
271 #endif /* __mips__ */
273 #define W_REG(osh, r, v) do { \
274 SELECT_BUS_WRITE(osh, \
275 switch (sizeof(*(r))) { \
276 case sizeof(uint8): writeb((uint8)(v), (volatile uint8*)(r)); break; \
277 case sizeof(uint16): writew((uint16)(v), (volatile uint16*)(r)); break; \
278 case sizeof(uint32): writel((uint32)(v), (volatile uint32*)(r)); break; \
279 }, \
280 (OSL_WRITE_REG(osh, r, v))); \
281 } while (0)
282 #else /* IL_BIGENDIAN */
283 #define R_REG(osh, r) (\
284 SELECT_BUS_READ(osh, \
285 ({ \
286 __typeof(*(r)) __osl_v; \
287 switch (sizeof(*(r))) { \
288 case sizeof(uint8): __osl_v = \
289 readb((volatile uint8*)((uintptr)(r)^3)); break; \
290 case sizeof(uint16): __osl_v = \
291 readw((volatile uint16*)((uintptr)(r)^2)); break; \
292 case sizeof(uint32): __osl_v = \
293 readl((volatile uint32*)(r)); break; \
295 __osl_v; \
296 }), \
297 OSL_READ_REG(osh, r)) \
299 #define W_REG(osh, r, v) do { \
300 SELECT_BUS_WRITE(osh, \
301 switch (sizeof(*(r))) { \
302 case sizeof(uint8): writeb((uint8)(v), \
303 (volatile uint8*)((uintptr)(r)^3)); break; \
304 case sizeof(uint16): writew((uint16)(v), \
305 (volatile uint16*)((uintptr)(r)^2)); break; \
306 case sizeof(uint32): writel((uint32)(v), \
307 (volatile uint32*)(r)); break; \
308 }, \
309 (OSL_WRITE_REG(osh, r, v))); \
310 } while (0)
311 #endif /* IL_BIGENDIAN */
313 #endif /* OSLREGOPS */
315 #define AND_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) & (v))
316 #define OR_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) | (v))
318 /* bcopy, bcmp, and bzero functions */
319 #define bcopy(src, dst, len) memcpy((dst), (src), (len))
320 #define bcmp(b1, b2, len) memcmp((b1), (b2), (len))
321 #define bzero(b, len) memset((b), '\0', (len))
323 /* uncached/cached virtual address */
324 #ifdef __mips__
325 #include <asm/addrspace.h>
326 #define OSL_UNCACHED(va) ((void *)KSEG1ADDR((va)))
327 #define OSL_CACHED(va) ((void *)KSEG0ADDR((va)))
328 #else
329 #define OSL_UNCACHED(va) ((void *)va)
330 #define OSL_CACHED(va) ((void *)va)
331 #endif /* mips */
333 #ifdef __mips__
334 #define OSL_PREF_RANGE_LD(va, sz) prefetch_range_PREF_LOAD_RETAINED(va, sz)
335 #define OSL_PREF_RANGE_ST(va, sz) prefetch_range_PREF_STORE_RETAINED(va, sz)
336 #else /* __mips__ */
337 #define OSL_PREF_RANGE_LD(va, sz)
338 #define OSL_PREF_RANGE_ST(va, sz)
339 #endif /* __mips__ */
341 /* get processor cycle count */
342 #if defined(mips)
343 #if defined DSLCPE_DELAY
344 #define OSL_GETCYCLES(x) ((x) = read_c0_count())
345 #define TICKDIFF(_x2_, _x1_) \
346 ((_x2_ >= _x1_) ? (_x2_ - _x1_) : ((unsigned long)(-1) - _x2_ + _x1_))
347 #else
348 #define OSL_GETCYCLES(x) ((x) = read_c0_count() * 2)
349 #endif
350 #elif defined(__i386__)
351 #define OSL_GETCYCLES(x) rdtscl((x))
352 #else
353 #define OSL_GETCYCLES(x) ((x) = 0)
354 #endif /* defined(mips) */
356 /* dereference an address that may cause a bus exception */
357 #ifdef mips
358 #if defined(MODULE) && (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 17))
359 #define BUSPROBE(val, addr) panic("get_dbe() will not fixup a bus exception when compiled into"\
360 " a module")
361 #else
362 #define BUSPROBE(val, addr) get_dbe((val), (addr))
363 #include <asm/paccess.h>
364 #endif /* defined(MODULE) && (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 17)) */
365 #else
366 #define BUSPROBE(val, addr) ({ (val) = R_REG(NULL, (addr)); 0; })
367 #endif /* mips */
369 /* map/unmap physical to virtual I/O */
370 #if !defined(CONFIG_MMC_MSM7X00A)
371 #define REG_MAP(pa, size) ioremap_nocache((unsigned long)(pa), (unsigned long)(size))
372 #else
373 #define REG_MAP(pa, size) (void *)(0)
374 #endif /* !defined(CONFIG_MMC_MSM7X00A */
375 #define REG_UNMAP(va) iounmap((va))
377 /* shared (dma-able) memory access macros */
378 #define R_SM(r) *(r)
379 #define W_SM(r, v) (*(r) = (v))
380 #define BZERO_SM(r, len) memset((r), '\0', (len))
382 /* packet primitives */
383 #ifndef BCMDBG_PKT
384 #define PKTGET(osh, len, send) osl_pktget((osh), (len))
385 #define PKTDUP(osh, skb) osl_pktdup((osh), (skb))
386 #define PKTLIST_DUMP(osh, buf)
387 #define PKTDBG_TRACE(osh, pkt, bit)
388 #else /* BCMDBG_PKT pkt logging for debugging */
389 #define PKTGET(osh, len, send) osl_pktget((osh), (len), __LINE__, __FILE__)
390 #define PKTDUP(osh, skb) osl_pktdup((osh), (skb), __LINE__, __FILE__)
391 #define PKTLIST_DUMP(osh, buf) osl_pktlist_dump(osh, buf)
392 #define BCMDBG_PTRACE
393 #define PKTLIST_IDX(skb) ((uint16 *)((char *)PKTTAG(skb) + \
394 sizeof(((struct sk_buff*)(skb))->cb) - sizeof(uint16)))
395 #define PKTDBG_TRACE(osh, pkt, bit) osl_pkttrace(osh, pkt, bit)
396 #endif /* BCMDBG_PKT */
397 #define PKTFREE(osh, skb, send) osl_pktfree((osh), (skb), (send))
398 #define PKTDATA(osh, skb) (((struct sk_buff*)(skb))->data)
399 #define PKTLEN(osh, skb) (((struct sk_buff*)(skb))->len)
400 #define PKTHEADROOM(osh, skb) (PKTDATA(osh, skb)-(((struct sk_buff*)(skb))->head))
401 #define PKTTAILROOM(osh, skb) ((((struct sk_buff*)(skb))->end)-(((struct sk_buff*)(skb))->tail))
402 #define PKTNEXT(osh, skb) (((struct sk_buff*)(skb))->next)
403 #define PKTSETNEXT(osh, skb, x) (((struct sk_buff*)(skb))->next = (struct sk_buff*)(x))
404 #define PKTSETLEN(osh, skb, len) __skb_trim((struct sk_buff*)(skb), (len))
405 #define PKTPUSH(osh, skb, bytes) skb_push((struct sk_buff*)(skb), (bytes))
406 #define PKTPULL(osh, skb, bytes) skb_pull((struct sk_buff*)(skb), (bytes))
407 #define PKTTAG(skb) ((void*)(((struct sk_buff*)(skb))->cb))
408 #define PKTALLOCED(osh) ((osl_pubinfo_t *)(osh))->pktalloced
409 #define PKTSETPOOL(osh, skb, x, y) do {} while (0)
410 #define PKTPOOL(osh, skb) FALSE
412 #ifdef CTFPOOL
413 #define CTFPOOL_REFILL_THRESH 3
414 typedef struct ctfpool {
415 void *head;
416 spinlock_t lock;
417 uint max_obj;
418 uint curr_obj;
419 uint obj_size;
420 uint refills;
421 uint fast_allocs;
422 uint fast_frees;
423 uint slow_allocs;
424 } ctfpool_t;
425 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22)
426 #define FASTBUF (1 << 4)
427 #define CTFBUF (1 << 5)
428 #define PKTSETFAST(osh, skb) ((((struct sk_buff*)(skb))->ctf_mac_len) |= FASTBUF)
429 #define PKTCLRFAST(osh, skb) ((((struct sk_buff*)(skb))->ctf_mac_len) &= (~FASTBUF))
430 #define PKTSETCTF(osh, skb) ((((struct sk_buff*)(skb))->ctf_mac_len) |= CTFBUF)
431 #define PKTCLRCTF(osh, skb) ((((struct sk_buff*)(skb))->ctf_mac_len) &= (~CTFBUF))
432 #define PKTISFAST(osh, skb) ((((struct sk_buff*)(skb))->ctf_mac_len) & FASTBUF)
433 #define PKTISCTF(osh, skb) ((((struct sk_buff*)(skb))->ctf_mac_len) & CTFBUF)
434 #define PKTFAST(osh, skb) (((struct sk_buff*)(skb))->ctf_mac_len)
435 #else
436 #define FASTBUF (1 << 0)
437 #define CTFBUF (1 << 1)
438 #define PKTSETFAST(osh, skb) ((((struct sk_buff*)(skb))->__unused) |= FASTBUF)
439 #define PKTCLRFAST(osh, skb) ((((struct sk_buff*)(skb))->__unused) &= (~FASTBUF))
440 #define PKTSETCTF(osh, skb) ((((struct sk_buff*)(skb))->__unused) |= CTFBUF)
441 #define PKTCLRCTF(osh, skb) ((((struct sk_buff*)(skb))->__unused) &= (~CTFBUF))
442 #define PKTISFAST(osh, skb) ((((struct sk_buff*)(skb))->__unused) & FASTBUF)
443 #define PKTISCTF(osh, skb) ((((struct sk_buff*)(skb))->__unused) & CTFBUF)
444 #define PKTFAST(osh, skb) (((struct sk_buff*)(skb))->__unused)
445 #endif /* 2.6.22 */
447 #define CTFPOOLPTR(osh, skb) (((struct sk_buff*)(skb))->sk)
448 #define CTFPOOLHEAD(osh, skb) (((ctfpool_t *)((struct sk_buff*)(skb))->sk)->head)
450 extern void *osl_ctfpool_add(osl_t *osh);
451 extern void osl_ctfpool_replenish(osl_t *osh, uint thresh);
452 extern int32 osl_ctfpool_init(osl_t *osh, uint numobj, uint size);
453 extern void osl_ctfpool_cleanup(osl_t *osh);
454 extern void osl_ctfpool_stats(osl_t *osh, void *b);
455 #endif /* CTFPOOL */
457 #ifdef CTFMAP
458 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14)
459 #define CTFMAPPTR(osh, skb) (((struct sk_buff*)(skb))->sp)
460 #else /* 2.6.14 */
461 #define CTFMAPPTR(osh, skb) (((struct sk_buff*)(skb))->list)
462 #endif /* 2.6.14 */
464 #define PKTCTFMAP(osh, p) \
465 do { \
466 if (PKTISCTF(osh, p)) { \
467 int32 sz; \
468 sz = (uint32)(((struct sk_buff *)p)->end) - \
469 (uint32)CTFMAPPTR(osh, p); \
470 /* map the remaining unmapped area */ \
471 if (sz > 0) { \
472 _DMA_MAP(osh, (void *)CTFMAPPTR(osh, p), \
473 sz, DMA_RX, p, NULL); \
475 /* clear ctf buf flag */ \
476 PKTCLRCTF(osh, p); \
477 CTFMAPPTR(osh, p) = NULL; \
479 } while (0)
480 #endif /* CTFMAP */
482 #ifdef HNDCTF
483 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22)
484 #define SKIPCT (1 << 6)
485 #define PKTSETSKIPCT(osh, skb) (((struct sk_buff*)(skb))->ctf_mac_len |= SKIPCT)
486 #define PKTCLRSKIPCT(osh, skb) (((struct sk_buff*)(skb))->ctf_mac_len &= (~SKIPCT))
487 #define PKTSKIPCT(osh, skb) (((struct sk_buff*)(skb))->ctf_mac_len & SKIPCT)
488 #else /* 2.6.22 */
489 #define SKIPCT (1 << 2)
490 #define PKTSETSKIPCT(osh, skb) (((struct sk_buff*)(skb))->__unused |= SKIPCT)
491 #define PKTCLRSKIPCT(osh, skb) (((struct sk_buff*)(skb))->__unused &= (~SKIPCT))
492 #define PKTSKIPCT(osh, skb) (((struct sk_buff*)(skb))->__unused & SKIPCT)
493 #endif /* 2.6.22 */
494 #else /* HNDCTF */
495 #define PKTSETSKIPCT(osh, skb)
496 #define PKTCLRSKIPCT(osh, skb)
497 #define PKTSKIPCT(osh, skb)
498 #endif /* HNDCTF */
500 extern void osl_pktfree(osl_t *osh, void *skb, bool send);
502 #ifdef BCMDBG_PKT /* pkt logging for debugging */
503 extern void *osl_pktget(osl_t *osh, uint len, int line, char *file);
504 extern void *osl_pkt_frmnative(osl_t *osh, void *skb, int line, char *file);
505 extern void *osl_pktdup(osl_t *osh, void *skb, int line, char *file);
506 extern void osl_pktlist_add(osl_t *osh, void *p, int line, char *file);
507 extern void osl_pktlist_remove(osl_t *osh, void *p);
508 extern char *osl_pktlist_dump(osl_t *osh, char *buf);
509 #ifdef BCMDBG_PTRACE
510 extern void osl_pkttrace(osl_t *osh, void *pkt, uint16 bit);
511 #endif /* BCMDBG_PTRACE */
512 #else /* BCMDBG_PKT */
513 extern void *osl_pkt_frmnative(osl_t *osh, void *skb);
514 extern void *osl_pktget(osl_t *osh, uint len);
515 extern void *osl_pktdup(osl_t *osh, void *skb);
516 #endif /* BCMDBG_PKT */
517 extern struct sk_buff *osl_pkt_tonative(osl_t *osh, void *pkt);
518 #ifdef BCMDBG_PKT
519 #define PKTFRMNATIVE(osh, skb) osl_pkt_frmnative(((osl_t *)osh), \
520 (struct sk_buff*)(skb), __LINE__, __FILE__)
521 #else /* BCMDBG_PKT */
522 #define PKTFRMNATIVE(osh, skb) osl_pkt_frmnative(((osl_t *)osh), (struct sk_buff*)(skb))
523 #endif /* BCMDBG_PKT */
524 #define PKTTONATIVE(osh, pkt) osl_pkt_tonative((osl_t *)(osh), (pkt))
526 #define PKTLINK(skb) (((struct sk_buff*)(skb))->prev)
527 #define PKTSETLINK(skb, x) (((struct sk_buff*)(skb))->prev = (struct sk_buff*)(x))
528 #define PKTPRIO(skb) (((struct sk_buff*)(skb))->priority)
529 #define PKTSETPRIO(skb, x) (((struct sk_buff*)(skb))->priority = (x))
530 #define PKTSUMNEEDED(skb) (((struct sk_buff*)(skb))->ip_summed == CHECKSUM_HW)
531 #define PKTSETSUMGOOD(skb, x) (((struct sk_buff*)(skb))->ip_summed = \
532 ((x) ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE))
533 /* PKTSETSUMNEEDED and PKTSUMGOOD are not possible because skb->ip_summed is overloaded */
534 #define PKTSHARED(skb) (((struct sk_buff*)(skb))->cloned)
536 #if defined(DSLCPE_DELAY)
537 #include <linux/spinlock.h> /* for spinlock_t */
538 struct shared_osl {
539 int long_delay;
540 spinlock_t *lock;
541 void *wl;
542 unsigned long MIPS;
544 typedef struct shared_osl shared_osl_t;
546 #define OSL_LONG_DELAY(osh, usec) osl_long_delay(osh, usec, 0)
547 #define OSL_YIELD_EXEC(osh, usec) osl_long_delay(osh, usec, 1)
548 extern void osl_long_delay(osl_t *osh, uint usec, bool yield);
549 extern int in_long_delay(osl_t *osh);
550 extern void osl_oshsh_init(osl_t *osh, shared_osl_t *oshsh);
551 #define IN_LONG_DELAY(osh) in_long_delay(osh)
552 #endif /* DSLCPE_DELAY */
554 #else /* BINOSL */
556 /* Where to get the declarations for mem, str, printf, bcopy's? Two basic approaches.
558 * First, use the Linux header files and the C standard library replacmenent versions
559 * built-in to the kernel. Use this approach when compiling non hybrid code or compling
560 * the OS port files. The second approach is to use our own defines/prototypes and
561 * functions we have provided in the Linux OSL, i.e. linux_osl.c. Use this approach when
562 * compiling the files that make up the hybrid binary. We are ensuring we
563 * don't directly link to the kernel replacement routines from the hybrid binary.
565 * NOTE: The issue we are trying to avoid is any questioning of whether the
566 * hybrid binary is derived from Linux. The wireless common code (wlc) is designed
567 * to be OS independent through the use of the OSL API and thus the hybrid binary doesn't
568 * derive from the Linux kernel at all. But since we defined our OSL API to include
569 * a small collection of standard C library routines and these routines are provided in
570 * the kernel we want to avoid even the appearance of deriving at all even though clearly
571 * usage of a C standard library API doesn't represent a derivation from Linux. Lastly
572 * note at the time of this checkin 4 references to memcpy/memset could not be eliminated
573 * from the binary because they are created internally by GCC as part of things like
574 * structure assignment. I don't think the compiler should be doing this but there is
575 * no options to disable it on Intel architectures (there is for MIPS so somebody must
576 * agree with me). I may be able to even remove these references eventually with
577 * a GNU binutil such as objcopy via a symbol rename (i.e. memcpy to osl_memcpy).
579 #if !defined(LINUX_HYBRID) || defined(LINUX_PORT)
580 #define printf(fmt, args...) printk(fmt , ## args)
581 #include <linux/kernel.h> /* for vsn/printf's */
582 #include <linux/string.h> /* for mem*, str* */
583 /* bcopy's: Linux kernel doesn't provide these (anymore) */
584 #define bcopy(src, dst, len) memcpy((dst), (src), (len))
585 #define bcmp(b1, b2, len) memcmp((b1), (b2), (len))
586 #define bzero(b, len) memset((b), '\0', (len))
588 /* These are provided only because when compiling linux_osl.c there
589 * must be an explicit prototype (separate from the definition) because
590 * we are compiling with GCC option -Wstrict-prototypes. Conversely
591 * these could be placed directly in linux_osl.c.
593 extern int osl_printf(const char *format, ...);
594 extern int osl_sprintf(char *buf, const char *format, ...);
595 extern int osl_snprintf(char *buf, size_t n, const char *format, ...);
596 extern int osl_vsprintf(char *buf, const char *format, va_list ap);
597 extern int osl_vsnprintf(char *buf, size_t n, const char *format, va_list ap);
598 extern int osl_strcmp(const char *s1, const char *s2);
599 extern int osl_strncmp(const char *s1, const char *s2, uint n);
600 extern int osl_strlen(const char *s);
601 extern char* osl_strcpy(char *d, const char *s);
602 extern char* osl_strncpy(char *d, const char *s, uint n);
603 extern char* osl_strchr(const char *s, int c);
604 extern char* osl_strrchr(const char *s, int c);
605 extern void *osl_memset(void *d, int c, size_t n);
606 extern void *osl_memcpy(void *d, const void *s, size_t n);
607 extern void *osl_memmove(void *d, const void *s, size_t n);
608 extern int osl_memcmp(const void *s1, const void *s2, size_t n);
609 #else
611 /* In the below defines we undefine the macro first in case it is
612 * defined. This shouldn't happen because we are not using Linux
613 * header files but because our Linux 2.4 make includes modversions.h
614 * through a GCC -include compile option, they get defined to point
615 * at the appropriate versioned symbol name. Note this doesn't
616 * happen with our Linux 2.6 makes.
619 /* *printf functions */
620 #include <stdarg.h> /* va_list needed for v*printf */
621 #include <stddef.h> /* size_t needed for *nprintf */
622 #undef printf
623 #undef sprintf
624 #undef snprintf
625 #undef vsprintf
626 #undef vsnprintf
627 #define printf(fmt, args...) osl_printf((fmt) , ## args)
628 #define sprintf(buf, fmt, args...) osl_sprintf((buf), (fmt) , ## args)
629 #define snprintf(buf, n, fmt, args...) osl_snprintf((buf), (n), (fmt) , ## args)
630 #define vsprintf(buf, fmt, ap) osl_vsprintf((buf), (fmt), (ap))
631 #define vsnprintf(buf, n, fmt, ap) osl_vsnprintf((buf), (n), (fmt), (ap))
632 extern int osl_printf(const char *format, ...);
633 extern int osl_sprintf(char *buf, const char *format, ...);
634 extern int osl_snprintf(char *buf, size_t n, const char *format, ...);
635 extern int osl_vsprintf(char *buf, const char *format, va_list ap);
636 extern int osl_vsnprintf(char *buf, size_t n, const char *format, va_list ap);
638 /* str* functions */
639 #undef strcmp
640 #undef strncmp
641 #undef strlen
642 #undef strcpy
643 #undef strncpy
644 #undef strchr
645 #undef strrchr
646 #define strcmp(s1, s2) osl_strcmp((s1), (s2))
647 #define strncmp(s1, s2, n) osl_strncmp((s1), (s2), (n))
648 #define strlen(s) osl_strlen((s))
649 #define strcpy(d, s) osl_strcpy((d), (s))
650 #define strncpy(d, s, n) osl_strncpy((d), (s), (n))
651 #define strchr(s, c) osl_strchr((s), (c))
652 #define strrchr(s, c) osl_strrchr((s), (c))
653 extern int osl_strcmp(const char *s1, const char *s2);
654 extern int osl_strncmp(const char *s1, const char *s2, uint n);
655 extern int osl_strlen(const char *s);
656 extern char* osl_strcpy(char *d, const char *s);
657 extern char* osl_strncpy(char *d, const char *s, uint n);
658 extern char* osl_strchr(const char *s, int c);
659 extern char* osl_strrchr(const char *s, int c);
661 /* mem* functions */
662 #undef memset
663 #undef memcpy
664 #undef memcmp
665 #define memset(d, c, n) osl_memset((d), (c), (n))
666 #define memcpy(d, s, n) osl_memcpy((d), (s), (n))
667 #define memmove(d, s, n) osl_memmove((d), (s), (n))
668 #define memcmp(s1, s2, n) osl_memcmp((s1), (s2), (n))
669 extern void *osl_memset(void *d, int c, size_t n);
670 extern void *osl_memcpy(void *d, const void *s, size_t n);
671 extern void *osl_memmove(void *d, const void *s, size_t n);
672 extern int osl_memcmp(const void *s1, const void *s2, size_t n);
674 /* bcopy, bcmp, and bzero functions */
675 #undef bcopy
676 #undef bcmp
677 #undef bzero
678 #define bcopy(src, dst, len) osl_memcpy((dst), (src), (len))
679 #define bcmp(b1, b2, len) osl_memcmp((b1), (b2), (len))
680 #define bzero(b, len) osl_memset((b), '\0', (len))
681 #endif /* !defined(LINUX_HYBRID) || defined(LINUX_PORT) */
683 /* register access macros */
684 #if !defined(BCMJTAG)
685 #define R_REG(osh, r) (\
686 sizeof(*(r)) == sizeof(uint8) ? osl_readb((volatile uint8*)(r)) : \
687 sizeof(*(r)) == sizeof(uint16) ? osl_readw((volatile uint16*)(r)) : \
688 osl_readl((volatile uint32*)(r)) \
690 #define W_REG(osh, r, v) do { \
691 switch (sizeof(*(r))) { \
692 case sizeof(uint8): osl_writeb((uint8)(v), (volatile uint8*)(r)); break; \
693 case sizeof(uint16): osl_writew((uint16)(v), (volatile uint16*)(r)); break; \
694 case sizeof(uint32): osl_writel((uint32)(v), (volatile uint32*)(r)); break; \
696 } while (0)
698 /* else added by johnvb to make sdio and jtag work with BINOSL, at least compile ... UNTESTED */
699 #else
700 #define R_REG(osh, r) OSL_READ_REG(osh, r)
701 #define W_REG(osh, r, v) do { OSL_WRITE_REG(osh, r, v); } while (0)
702 #endif
704 #define AND_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) & (v))
705 #define OR_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) | (v))
706 extern uint8 osl_readb(volatile uint8 *r);
707 extern uint16 osl_readw(volatile uint16 *r);
708 extern uint32 osl_readl(volatile uint32 *r);
709 extern void osl_writeb(uint8 v, volatile uint8 *r);
710 extern void osl_writew(uint16 v, volatile uint16 *r);
711 extern void osl_writel(uint32 v, volatile uint32 *r);
713 /* system up time in ms */
714 #define OSL_SYSUPTIME() osl_sysuptime()
715 extern uint32 osl_sysuptime(void);
717 /* uncached/cached virtual address */
718 #define OSL_UNCACHED(va) osl_uncached((va))
719 extern void *osl_uncached(void *va);
720 #define OSL_CACHED(va) osl_cached((va))
721 extern void *osl_cached(void *va);
723 #define OSL_PREF_RANGE_LD(va, sz)
724 #define OSL_PREF_RANGE_ST(va, sz)
726 /* get processor cycle count */
727 #define OSL_GETCYCLES(x) ((x) = osl_getcycles())
728 extern uint osl_getcycles(void);
730 /* dereference an address that may target abort */
731 #define BUSPROBE(val, addr) osl_busprobe(&(val), (addr))
732 extern int osl_busprobe(uint32 *val, uint32 addr);
734 /* map/unmap physical to virtual */
735 #define REG_MAP(pa, size) osl_reg_map((pa), (size))
736 #define REG_UNMAP(va) osl_reg_unmap((va))
737 extern void *osl_reg_map(uint32 pa, uint size);
738 extern void osl_reg_unmap(void *va);
740 /* shared (dma-able) memory access macros */
741 #define R_SM(r) *(r)
742 #define W_SM(r, v) (*(r) = (v))
743 #define BZERO_SM(r, len) bzero((r), (len))
745 /* packet primitives */
746 #ifdef BCMDBG_PKT
747 #define PKTGET(osh, len, send) osl_pktget((osh), (len), __LINE__, __FILE__)
748 #define PKTDUP(osh, skb) osl_pktdup((osh), (skb), __LINE__, __FILE__)
749 #define PKTFRMNATIVE(osh, skb) osl_pkt_frmnative((osh), (skb), __LINE__, __FILE__)
750 #define PKTLIST_DUMP(osh, buf) osl_pktlist_dump(osh, buf)
751 #define PKTDBG_TRACE(osh, pkt, bit)
752 #else /* BCMDBG_PKT */
753 #define PKTGET(osh, len, send) osl_pktget((osh), (len))
754 #define PKTDUP(osh, skb) osl_pktdup((osh), (skb))
755 #define PKTFRMNATIVE(osh, skb) osl_pkt_frmnative((osh), (skb))
756 #define PKTLIST_DUMP(osh, buf)
757 #define PKTDBG_TRACE(osh, pkt, bit)
758 #endif /* BCMDBG_PKT */
759 #define PKTFREE(osh, skb, send) osl_pktfree((osh), (skb), (send))
760 #define PKTDATA(osh, skb) osl_pktdata((osh), (skb))
761 #define PKTLEN(osh, skb) osl_pktlen((osh), (skb))
762 #define PKTHEADROOM(osh, skb) osl_pktheadroom((osh), (skb))
763 #define PKTTAILROOM(osh, skb) osl_pkttailroom((osh), (skb))
764 #define PKTNEXT(osh, skb) osl_pktnext((osh), (skb))
765 #define PKTSETNEXT(osh, skb, x) osl_pktsetnext((skb), (x))
766 #define PKTSETLEN(osh, skb, len) osl_pktsetlen((osh), (skb), (len))
767 #define PKTPUSH(osh, skb, bytes) osl_pktpush((osh), (skb), (bytes))
768 #define PKTPULL(osh, skb, bytes) osl_pktpull((osh), (skb), (bytes))
769 #define PKTTAG(skb) osl_pkttag((skb))
770 #define PKTTONATIVE(osh, pkt) osl_pkt_tonative((osh), (pkt))
771 #define PKTLINK(skb) osl_pktlink((skb))
772 #define PKTSETLINK(skb, x) osl_pktsetlink((skb), (x))
773 #define PKTPRIO(skb) osl_pktprio((skb))
774 #define PKTSETPRIO(skb, x) osl_pktsetprio((skb), (x))
775 #define PKTSHARED(skb) osl_pktshared((skb))
776 #define PKTALLOCED(osh) osl_pktalloced((osh))
777 #define PKTSETPOOL(osh, skb, x, y) do {} while (0)
778 #define PKTPOOL(osh, skb) FALSE
780 #ifdef BCMDBG_PKT /* pkt logging for debugging */
781 extern void *osl_pktget(osl_t *osh, uint len, int line, char *file);
782 extern void *osl_pktdup(osl_t *osh, void *skb, int line, char *file);
783 extern void *osl_pkt_frmnative(osl_t *osh, void *skb, int line, char *file);
784 #else /* BCMDBG_PKT */
785 extern void *osl_pktget(osl_t *osh, uint len);
786 extern void *osl_pktdup(osl_t *osh, void *skb);
787 extern void *osl_pkt_frmnative(osl_t *osh, void *skb);
788 #endif /* BCMDBG_PKT */
789 extern void osl_pktfree(osl_t *osh, void *skb, bool send);
790 extern uchar *osl_pktdata(osl_t *osh, void *skb);
791 extern uint osl_pktlen(osl_t *osh, void *skb);
792 extern uint osl_pktheadroom(osl_t *osh, void *skb);
793 extern uint osl_pkttailroom(osl_t *osh, void *skb);
794 extern void *osl_pktnext(osl_t *osh, void *skb);
795 extern void osl_pktsetnext(void *skb, void *x);
796 extern void osl_pktsetlen(osl_t *osh, void *skb, uint len);
797 extern uchar *osl_pktpush(osl_t *osh, void *skb, int bytes);
798 extern uchar *osl_pktpull(osl_t *osh, void *skb, int bytes);
799 extern void *osl_pkttag(void *skb);
800 extern void *osl_pktlink(void *skb);
801 extern void osl_pktsetlink(void *skb, void *x);
802 extern uint osl_pktprio(void *skb);
803 extern void osl_pktsetprio(void *skb, uint x);
804 extern struct sk_buff *osl_pkt_tonative(osl_t *osh, void *pkt);
805 extern bool osl_pktshared(void *skb);
806 extern uint osl_pktalloced(osl_t *osh);
808 #ifdef BCMDBG_PKT /* pkt logging for debugging */
809 extern char *osl_pktlist_dump(osl_t *osh, char *buf);
810 extern void osl_pktlist_add(osl_t *osh, void *p, int line, char *file);
811 extern void osl_pktlist_remove(osl_t *osh, void *p);
812 #endif /* BCMDBG_PKT */
814 #endif /* BINOSL */
816 #ifdef CTFMAP
817 #include <ctf/hndctf.h>
818 #define CTFMAPSZ 320
819 #define DMA_MAP(osh, va, size, direction, p, dmah) \
820 ({ \
821 typeof(size) sz = (size); \
822 if (PKTISCTF((osh), (p))) { \
823 sz = CTFMAPSZ; \
824 CTFMAPPTR((osh), (p)) = (void *)(((uint8 *)(va)) + CTFMAPSZ); \
826 osl_dma_map((osh), (va), sz, (direction)); \
828 #define _DMA_MAP(osh, va, size, direction, p, dmah) \
829 dma_cache_inv((uint)(va), (size))
830 #else /* CTFMAP */
831 #define DMA_MAP(osh, va, size, direction, p, dmah) \
832 osl_dma_map((osh), (va), (size), (direction))
833 #endif /* CTFMAP */
835 #else /* ! BCMDRIVER */
838 /* ASSERT */
839 #ifdef BCMDBG_ASSERT
840 #include <assert.h>
841 #define ASSERT assert
842 #else /* BCMDBG_ASSERT */
843 #define ASSERT(exp) do {} while (0)
844 #endif /* BCMDBG_ASSERT */
846 /* MALLOC and MFREE */
847 #define MALLOC(o, l) malloc(l)
848 #define MFREE(o, p, l) free(p)
849 #include <stdlib.h>
851 /* str* and mem* functions */
852 #include <string.h>
854 /* *printf functions */
855 #include <stdio.h>
857 /* bcopy, bcmp, and bzero */
858 extern void bcopy(const void *src, void *dst, size_t len);
859 extern int bcmp(const void *b1, const void *b2, size_t len);
860 extern void bzero(void *b, size_t len);
861 #endif /* ! BCMDRIVER */
863 #endif /* _linux_osl_h_ */