Broadcom SDK and wireless driver: another attempt to update to ver. 5.10.147.0
[tomato.git] / release / src-rt / include / linux_osl.h
blob39053b55c345e993a29a5ddf7b607ce4375273c7
1 /*
2 * Linux OS Independent Layer
4 * Copyright (C) 2009, Broadcom Corporation
5 * All Rights Reserved.
6 *
7 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
8 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
9 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
10 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
12 * $Id: linux_osl.h,v 13.133.2.18 2009/11/04 16:51:58 Exp $
15 #ifndef _linux_osl_h_
16 #define _linux_osl_h_
18 #include <typedefs.h>
20 #ifdef BCMDRIVER
22 /* OSL initialization */
23 extern osl_t *osl_attach(void *pdev, uint bustype, bool pkttag);
24 extern void osl_detach(osl_t *osh);
26 /* Global ASSERT type */
27 extern uint32 g_assert_type;
29 /* ASSERT */
30 #if defined(BCMDBG_ASSERT) || defined(BCMASSERT_LOG)
31 #define ASSERT(exp) \
32 do { if (!(exp)) osl_assert(#exp, __FILE__, __LINE__); } while (0)
33 extern void osl_assert(char *exp, char *file, int line);
34 #else
35 #ifdef __GNUC__
36 #define GCC_VERSION \
37 (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
38 #if GCC_VERSION > 30100
39 #define ASSERT(exp) do {} while (0)
40 #else
41 /* ASSERT could cause segmentation fault on GCC3.1, use empty instead */
42 #define ASSERT(exp)
43 #endif /* GCC_VERSION > 30100 */
44 #endif /* __GNUC__ */
45 #endif /* BCMDBG_ASSERT || BCMASSERT_LOG */
47 /* microsecond delay */
48 #define OSL_DELAY(usec) osl_delay(usec)
49 extern void osl_delay(uint usec);
51 #define OSL_PCMCIA_READ_ATTR(osh, offset, buf, size) \
52 osl_pcmcia_read_attr((osh), (offset), (buf), (size))
53 #define OSL_PCMCIA_WRITE_ATTR(osh, offset, buf, size) \
54 osl_pcmcia_write_attr((osh), (offset), (buf), (size))
55 extern void osl_pcmcia_read_attr(osl_t *osh, uint offset, void *buf, int size);
56 extern void osl_pcmcia_write_attr(osl_t *osh, uint offset, void *buf, int size);
58 /* PCI configuration space access macros */
59 #define OSL_PCI_READ_CONFIG(osh, offset, size) \
60 osl_pci_read_config((osh), (offset), (size))
61 #define OSL_PCI_WRITE_CONFIG(osh, offset, size, val) \
62 osl_pci_write_config((osh), (offset), (size), (val))
63 extern uint32 osl_pci_read_config(osl_t *osh, uint offset, uint size);
64 extern void osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val);
66 /* PCI device bus # and slot # */
67 #define OSL_PCI_BUS(osh) osl_pci_bus(osh)
68 #define OSL_PCI_SLOT(osh) osl_pci_slot(osh)
69 extern uint osl_pci_bus(osl_t *osh);
70 extern uint osl_pci_slot(osl_t *osh);
72 /* Pkttag flag should be part of public information */
73 typedef struct {
74 bool pkttag;
75 uint pktalloced; /* Number of allocated packet buffers */
76 bool mmbus; /* Bus supports memory-mapped register accesses */
77 pktfree_cb_fn_t tx_fn; /* Callback function for PKTFREE */
78 void *tx_ctx; /* Context to the callback function */
79 #ifdef OSLREGOPS
80 osl_rreg_fn_t rreg_fn; /* Read Register function */
81 osl_wreg_fn_t wreg_fn; /* Write Register function */
82 void *reg_ctx; /* Context to the reg callback functions */
83 #endif
84 } osl_pubinfo_t;
86 #define PKTFREESETCB(osh, _tx_fn, _tx_ctx) \
87 do { \
88 ((osl_pubinfo_t*)osh)->tx_fn = _tx_fn; \
89 ((osl_pubinfo_t*)osh)->tx_ctx = _tx_ctx; \
90 } while (0)
92 #ifdef OSLREGOPS
93 #define REGOPSSET(osh, rreg, wreg, ctx) \
94 do { \
95 ((osl_pubinfo_t*)osh)->rreg_fn = rreg; \
96 ((osl_pubinfo_t*)osh)->wreg_fn = wreg; \
97 ((osl_pubinfo_t*)osh)->reg_ctx = ctx; \
98 } while (0)
99 #endif /* OSLREGOPS */
101 /* host/bus architecture-specific byte swap */
102 #define BUS_SWAP32(v) (v)
104 #ifdef BCMDBG_MEM
105 #define MALLOC(osh, size) osl_debug_malloc((osh), (size), __LINE__, __FILE__)
106 #define MFREE(osh, addr, size) osl_debug_mfree((osh), (addr), (size), __LINE__, __FILE__)
107 #define MALLOCED(osh) osl_malloced((osh))
108 #define MALLOC_DUMP(osh, b) osl_debug_memdump((osh), (b))
109 extern void *osl_debug_malloc(osl_t *osh, uint size, int line, char* file);
110 extern void osl_debug_mfree(osl_t *osh, void *addr, uint size, int line, char* file);
111 extern uint osl_malloced(osl_t *osh);
112 struct bcmstrbuf;
113 extern int osl_debug_memdump(osl_t *osh, struct bcmstrbuf *b);
114 #else
115 #define MALLOC(osh, size) osl_malloc((osh), (size))
116 #define MFREE(osh, addr, size) osl_mfree((osh), (addr), (size))
117 #define MALLOCED(osh) osl_malloced((osh))
118 extern void *osl_malloc(osl_t *osh, uint size);
119 extern void osl_mfree(osl_t *osh, void *addr, uint size);
120 extern uint osl_malloced(osl_t *osh);
121 #endif /* BCMDBG_MEM */
123 #define NATIVE_MALLOC(osh, size) kmalloc(size, GFP_ATOMIC)
124 #define NATIVE_MFREE(osh, addr, size) kfree(addr)
126 #define NATIVE_MALLOC(osh, size) kmalloc(size, GFP_ATOMIC)
127 #define NATIVE_MFREE(osh, addr, size) kfree(addr)
129 #define MALLOC_FAILED(osh) osl_malloc_failed((osh))
130 extern uint osl_malloc_failed(osl_t *osh);
132 /* allocate/free shared (dma-able) consistent memory */
133 #define DMA_CONSISTENT_ALIGN osl_dma_consistent_align()
134 #define DMA_ALLOC_CONSISTENT(osh, size, pap, dmah) \
135 osl_dma_alloc_consistent((osh), (size), (pap))
136 #define DMA_FREE_CONSISTENT(osh, va, size, pa, dmah) \
137 osl_dma_free_consistent((osh), (void*)(va), (size), (pa))
138 extern uint osl_dma_consistent_align(void);
139 extern void *osl_dma_alloc_consistent(osl_t *osh, uint size, ulong *pap);
140 extern void osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa);
142 /* map/unmap direction */
143 #define DMA_TX 1 /* TX direction for DMA */
144 #define DMA_RX 2 /* RX direction for DMA */
146 /* map/unmap shared (dma-able) memory */
147 #define DMA_MAP(osh, va, size, direction, p, dmah) \
148 osl_dma_map((osh), (va), (size), (direction))
149 #define DMA_UNMAP(osh, pa, size, direction, p, dmah) \
150 osl_dma_unmap((osh), (pa), (size), (direction))
151 extern uint osl_dma_map(osl_t *osh, void *va, uint size, int direction);
152 extern void osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction);
154 /* API for DMA addressing capability */
155 #define OSL_DMADDRWIDTH(osh, addrwidth) do {} while (0)
157 /* register access macros */
158 #if defined(BCMJTAG)
159 #include <bcmjtag.h>
160 #define OSL_WRITE_REG(osh, r, v) (bcmjtag_write(NULL, (uintptr)(r), (v), sizeof(*(r))))
161 #define OSL_READ_REG(osh, r) (bcmjtag_read(NULL, (uintptr)(r), sizeof(*(r))))
162 #endif
164 #if defined(BCMJTAG)
165 #define SELECT_BUS_WRITE(osh, mmap_op, bus_op) if (((osl_pubinfo_t*)(osh))->mmbus) \
166 mmap_op else bus_op
167 #define SELECT_BUS_READ(osh, mmap_op, bus_op) (((osl_pubinfo_t*)(osh))->mmbus) ? \
168 mmap_op : bus_op
169 #else
170 #define SELECT_BUS_WRITE(osh, mmap_op, bus_op) mmap_op
171 #define SELECT_BUS_READ(osh, mmap_op, bus_op) mmap_op
172 #endif
174 #define OSL_ERROR(bcmerror) osl_error(bcmerror)
175 extern int osl_error(int bcmerror);
177 /* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */
178 #define PKTBUFSZ 2048 /* largest reasonable packet buffer, driver uses for ethernet MTU */
181 * BINOSL selects the slightly slower function-call-based binary compatible osl.
182 * Macros expand to calls to functions defined in linux_osl.c .
184 #ifndef BINOSL
186 #define OSL_SYSUPTIME() ((uint32)jiffies * (1000 / HZ))
188 #ifndef printf
189 #define printf(fmt, args...) printk(fmt , ## args)
190 #endif
192 #include <linux/kernel.h> /* for vsn/printf's */
193 #include <linux/string.h> /* for mem*, str* */
194 /* bcopy's: Linux kernel doesn't provide these (anymore) */
195 #define bcopy(src, dst, len) memcpy((dst), (src), (len))
196 #define bcmp(b1, b2, len) memcmp((b1), (b2), (len))
197 #define bzero(b, len) memset((b), '\0', (len))
199 /* register access macros */
200 #if defined(OSLREGOPS)
201 #define R_REG(osh, r) (\
202 sizeof(*(r)) == sizeof(uint8) ? osl_readb((osh), (volatile uint8*)(r)) : \
203 sizeof(*(r)) == sizeof(uint16) ? osl_readw((osh), (volatile uint16*)(r)) : \
204 osl_readl((osh), (volatile uint32*)(r)) \
206 #define W_REG(osh, r, v) do { \
207 switch (sizeof(*(r))) { \
208 case sizeof(uint8): osl_writeb((osh), (volatile uint8*)(r), (uint8)(v)); break; \
209 case sizeof(uint16): osl_writew((osh), (volatile uint16*)(r), (uint16)(v)); break; \
210 case sizeof(uint32): osl_writel((osh), (volatile uint32*)(r), (uint32)(v)); break; \
212 } while (0)
214 extern uint8 osl_readb(osl_t *osh, volatile uint8 *r);
215 extern uint16 osl_readw(osl_t *osh, volatile uint16 *r);
216 extern uint32 osl_readl(osl_t *osh, volatile uint32 *r);
217 extern void osl_writeb(osl_t *osh, volatile uint8 *r, uint8 v);
218 extern void osl_writew(osl_t *osh, volatile uint16 *r, uint16 v);
219 extern void osl_writel(osl_t *osh, volatile uint32 *r, uint32 v);
221 #else /* OSLREGOPS */
223 #ifndef IL_BIGENDIAN
224 #ifndef __mips__
225 #define R_REG(osh, r) (\
226 SELECT_BUS_READ(osh, sizeof(*(r)) == sizeof(uint8) ? readb((volatile uint8*)(r)) : \
227 sizeof(*(r)) == sizeof(uint16) ? readw((volatile uint16*)(r)) : \
228 readl((volatile uint32*)(r)), OSL_READ_REG(osh, r)) \
230 #else /* __mips__ */
231 #define R_REG(osh, r) (\
232 SELECT_BUS_READ(osh, \
233 ({ \
234 __typeof(*(r)) __osl_v; \
235 __asm__ __volatile__("sync"); \
236 switch (sizeof(*(r))) { \
237 case sizeof(uint8): __osl_v = \
238 readb((volatile uint8*)(r)); break; \
239 case sizeof(uint16): __osl_v = \
240 readw((volatile uint16*)(r)); break; \
241 case sizeof(uint32): __osl_v = \
242 readl((volatile uint32*)(r)); break; \
244 __asm__ __volatile__("sync"); \
245 __osl_v; \
246 }), \
247 ({ \
248 __typeof(*(r)) __osl_v; \
249 __asm__ __volatile__("sync"); \
250 __osl_v = OSL_READ_REG(osh, r); \
251 __asm__ __volatile__("sync"); \
252 __osl_v; \
253 })) \
255 #endif /* __mips__ */
257 #define W_REG(osh, r, v) do { \
258 SELECT_BUS_WRITE(osh, \
259 switch (sizeof(*(r))) { \
260 case sizeof(uint8): writeb((uint8)(v), (volatile uint8*)(r)); break; \
261 case sizeof(uint16): writew((uint16)(v), (volatile uint16*)(r)); break; \
262 case sizeof(uint32): writel((uint32)(v), (volatile uint32*)(r)); break; \
263 }, \
264 (OSL_WRITE_REG(osh, r, v))); \
265 } while (0)
266 #else /* IL_BIGENDIAN */
267 #define R_REG(osh, r) (\
268 SELECT_BUS_READ(osh, \
269 ({ \
270 __typeof(*(r)) __osl_v; \
271 switch (sizeof(*(r))) { \
272 case sizeof(uint8): __osl_v = \
273 readb((volatile uint8*)((uintptr)(r)^3)); break; \
274 case sizeof(uint16): __osl_v = \
275 readw((volatile uint16*)((uintptr)(r)^2)); break; \
276 case sizeof(uint32): __osl_v = \
277 readl((volatile uint32*)(r)); break; \
279 __osl_v; \
280 }), \
281 OSL_READ_REG(osh, r)) \
283 #define W_REG(osh, r, v) do { \
284 SELECT_BUS_WRITE(osh, \
285 switch (sizeof(*(r))) { \
286 case sizeof(uint8): writeb((uint8)(v), \
287 (volatile uint8*)((uintptr)(r)^3)); break; \
288 case sizeof(uint16): writew((uint16)(v), \
289 (volatile uint16*)((uintptr)(r)^2)); break; \
290 case sizeof(uint32): writel((uint32)(v), \
291 (volatile uint32*)(r)); break; \
292 }, \
293 (OSL_WRITE_REG(osh, r, v))); \
294 } while (0)
295 #endif /* IL_BIGENDIAN */
297 #endif /* OSLREGOPS */
299 #define AND_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) & (v))
300 #define OR_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) | (v))
302 /* bcopy, bcmp, and bzero functions */
303 #define bcopy(src, dst, len) memcpy((dst), (src), (len))
304 #define bcmp(b1, b2, len) memcmp((b1), (b2), (len))
305 #define bzero(b, len) memset((b), '\0', (len))
307 /* uncached/cached virtual address */
308 #ifdef __mips__
309 #include <asm/addrspace.h>
310 #define OSL_UNCACHED(va) ((void *)KSEG1ADDR((va)))
311 #define OSL_CACHED(va) ((void *)KSEG0ADDR((va)))
312 #define OSL_CACHE_FLUSH(va, len) dma_cache_wback_inv((va), (len))
313 #else
314 #define OSL_UNCACHED(va) ((void *)va)
315 #define OSL_CACHED(va) ((void *)va)
316 #endif /* mips */
318 #ifdef __mips__
319 #define OSL_PREF_RANGE_LD(va, sz) prefetch_range_PREF_LOAD_RETAINED(va, sz)
320 #define OSL_PREF_RANGE_ST(va, sz) prefetch_range_PREF_STORE_RETAINED(va, sz)
321 #else /* __mips__ */
322 #define OSL_PREF_RANGE_LD(va, sz)
323 #define OSL_PREF_RANGE_ST(va, sz)
324 #endif /* __mips__ */
326 /* get processor cycle count */
327 #if defined(mips)
328 #if defined DSLCPE_DELAY
329 #define OSL_GETCYCLES(x) ((x) = read_c0_count())
330 #define TICKDIFF(_x2_, _x1_) \
331 ((_x2_ >= _x1_) ? (_x2_ - _x1_) : ((unsigned long)(-1) - _x2_ + _x1_))
332 #else
333 #define OSL_GETCYCLES(x) ((x) = read_c0_count() * 2)
334 #endif
335 #elif defined(__i386__)
336 #define OSL_GETCYCLES(x) rdtscl((x))
337 #else
338 #define OSL_GETCYCLES(x) ((x) = 0)
339 #endif /* defined(mips) */
341 /* dereference an address that may cause a bus exception */
342 #ifdef mips
343 #if defined(MODULE) && (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 17))
344 #define BUSPROBE(val, addr) panic("get_dbe() will not fixup a bus exception when compiled into"\
345 " a module")
346 #else
347 #define BUSPROBE(val, addr) get_dbe((val), (addr))
348 #include <asm/paccess.h>
349 #endif /* defined(MODULE) && (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 17)) */
350 #else
351 #define BUSPROBE(val, addr) ({ (val) = R_REG(NULL, (addr)); 0; })
352 #endif /* mips */
354 /* map/unmap physical to virtual I/O */
355 #define REG_MAP(pa, size) ioremap_nocache((unsigned long)(pa), (unsigned long)(size))
356 #define REG_UNMAP(va) iounmap((va))
358 /* shared (dma-able) memory access macros */
359 #define R_SM(r) *(r)
360 #define W_SM(r, v) (*(r) = (v))
361 #define BZERO_SM(r, len) memset((r), '\0', (len))
363 /* Because the non BINOSL implemenation of the PKT OSL routines are macros (for
364 * performance reasons), we need the Linux headers.
366 #include <linuxver.h> /* use current 2.4.x calling conventions */
368 /* packet primitives */
369 #define PKTGET(osh, len, send) osl_pktget((osh), (len))
370 #define PKTFREE(osh, skb, send) osl_pktfree((osh), (skb), (send))
371 #define PKTDATA(osh, skb) (((struct sk_buff*)(skb))->data)
372 #define PKTLEN(osh, skb) (((struct sk_buff*)(skb))->len)
373 #define PKTHEADROOM(osh, skb) (PKTDATA(osh, skb)-(((struct sk_buff*)(skb))->head))
374 #define PKTTAILROOM(osh, skb) ((((struct sk_buff*)(skb))->end)-(((struct sk_buff*)(skb))->tail))
375 #define PKTNEXT(osh, skb) (((struct sk_buff*)(skb))->next)
376 #define PKTSETNEXT(osh, skb, x) (((struct sk_buff*)(skb))->next = (struct sk_buff*)(x))
377 #define PKTSETLEN(osh, skb, len) __skb_trim((struct sk_buff*)(skb), (len))
378 #define PKTPUSH(osh, skb, bytes) skb_push((struct sk_buff*)(skb), (bytes))
379 #define PKTPULL(osh, skb, bytes) skb_pull((struct sk_buff*)(skb), (bytes))
380 #define PKTDUP(osh, skb) osl_pktdup((osh), (skb))
381 #define PKTTAG(skb) ((void*)(((struct sk_buff*)(skb))->cb))
382 #define PKTALLOCED(osh) ((osl_pubinfo_t *)(osh))->pktalloced
383 #ifdef BCMDBG_PKT /* pkt logging for debugging */
384 #define PKTLIST_DUMP(osh, buf) osl_pktlist_dump(osh, buf)
385 #else /* BCMDBG_PKT */
386 #define PKTLIST_DUMP(osh, buf)
387 #endif /* BCMDBG_PKT */
389 #ifdef CTFPOOL
390 #define CTFPOOL_REFILL_THRESH 3
391 typedef struct ctfpool {
392 void *head;
393 spinlock_t lock;
394 uint max_obj;
395 uint curr_obj;
396 uint obj_size;
397 uint refills;
398 uint fast_allocs;
399 uint fast_frees;
400 uint slow_allocs;
401 } ctfpool_t;
402 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22)
403 #define FASTBUF (1 << 4)
404 #define CTFBUF (1 << 5)
405 #define PKTSETFAST(osh, skb) ((((struct sk_buff*)(skb))->mac_len) |= FASTBUF)
406 #define PKTCLRFAST(osh, skb) ((((struct sk_buff*)(skb))->mac_len) &= (~FASTBUF))
407 #define PKTSETCTF(osh, skb) ((((struct sk_buff*)(skb))->mac_len) |= CTFBUF)
408 #define PKTCLRCTF(osh, skb) ((((struct sk_buff*)(skb))->mac_len) &= (~CTFBUF))
409 #define PKTISFAST(osh, skb) ((((struct sk_buff*)(skb))->mac_len) & FASTBUF)
410 #define PKTISCTF(osh, skb) ((((struct sk_buff*)(skb))->mac_len) & CTFBUF)
411 #define PKTFAST(osh, skb) (((struct sk_buff*)(skb))->mac_len)
412 #else
413 #define FASTBUF (1 << 0)
414 #define CTFBUF (1 << 1)
415 #define PKTSETFAST(osh, skb) ((((struct sk_buff*)(skb))->__unused) |= FASTBUF)
416 #define PKTCLRFAST(osh, skb) ((((struct sk_buff*)(skb))->__unused) &= (~FASTBUF))
417 #define PKTSETCTF(osh, skb) ((((struct sk_buff*)(skb))->__unused) |= CTFBUF)
418 #define PKTCLRCTF(osh, skb) ((((struct sk_buff*)(skb))->__unused) &= (~CTFBUF))
419 #define PKTISFAST(osh, skb) ((((struct sk_buff*)(skb))->__unused) & FASTBUF)
420 #define PKTISCTF(osh, skb) ((((struct sk_buff*)(skb))->__unused) & CTFBUF)
421 #define PKTFAST(osh, skb) (((struct sk_buff*)(skb))->__unused)
422 #endif /* 2.6.22 */
424 #define CTFPOOLPTR(osh, skb) (((struct sk_buff*)(skb))->sk)
425 #define CTFPOOLHEAD(osh, skb) (((ctfpool_t *)((struct sk_buff*)(skb))->sk)->head)
427 extern void *osl_ctfpool_add(osl_t *osh);
428 extern void osl_ctfpool_replenish(osl_t *osh, uint thresh);
429 extern int32 osl_ctfpool_init(osl_t *osh, uint numobj, uint size);
430 extern void osl_ctfpool_cleanup(osl_t *osh);
431 extern void osl_ctfpool_stats(osl_t *osh, void *b);
432 #endif /* CTFPOOL */
434 #ifdef HNDCTF
435 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22)
436 #define SKIPCT (1 << 6)
437 #define PKTSETSKIPCT(osh, skb) (((struct sk_buff*)(skb))->mac_len |= SKIPCT)
438 #define PKTCLRSKIPCT(osh, skb) (((struct sk_buff*)(skb))->mac_len &= (~SKIPCT))
439 #define PKTSKIPCT(osh, skb) (((struct sk_buff*)(skb))->mac_len & SKIPCT)
440 #else /* 2.6.22 */
441 #define SKIPCT (1 << 2)
442 #define PKTSETSKIPCT(osh, skb) (((struct sk_buff*)(skb))->__unused |= SKIPCT)
443 #define PKTCLRSKIPCT(osh, skb) (((struct sk_buff*)(skb))->__unused &= (~SKIPCT))
444 #define PKTSKIPCT(osh, skb) (((struct sk_buff*)(skb))->__unused & SKIPCT)
445 #endif /* 2.6.22 */
446 #else /* HNDCTF */
447 #define PKTSETSKIPCT(osh, skb)
448 #define PKTCLRSKIPCT(osh, skb)
449 #define PKTSKIPCT(osh, skb)
450 #endif /* HNDCTF */
452 extern void *osl_pktget(osl_t *osh, uint len);
453 extern void osl_pktfree(osl_t *osh, void *skb, bool send);
454 extern void *osl_pktdup(osl_t *osh, void *skb);
456 #ifdef BCMDBG_PKT /* pkt logging for debugging */
457 extern void osl_pktlist_add(osl_t *osh, void *p);
458 extern void osl_pktlist_remove(osl_t *osh, void *p);
459 extern char *osl_pktlist_dump(osl_t *osh, char *buf);
460 #endif /* BCMDBG_PKT */
462 /* Convert a native(OS) packet to driver packet.
463 * In the process, native packet is destroyed, there is no copying
464 * Also, a packettag is zeroed out
466 static INLINE void *
467 osl_pkt_frmnative(osl_pubinfo_t *osh, void *pkt)
469 struct sk_buff *nskb;
471 if (osh->pkttag)
472 bzero((void*)((struct sk_buff*)pkt)->cb, OSL_PKTTAG_SZ);
474 /* Increment the packet counter */
475 for (nskb = (struct sk_buff *)pkt; nskb; nskb = nskb->next) {
476 #ifdef BCMDBG_PKT
477 osl_pktlist_add((osl_t *)osh, (void *) nskb);
478 #endif /* BCMDBG_PKT */
479 osh->pktalloced++;
482 return (void *)pkt;
484 #define PKTFRMNATIVE(osh, skb) osl_pkt_frmnative(((osl_pubinfo_t *)osh), (struct sk_buff*)(skb))
486 /* Convert a driver packet to native(OS) packet
487 * In the process, packettag is zeroed out before sending up
488 * IP code depends on skb->cb to be setup correctly with various options
489 * In our case, that means it should be 0
491 static INLINE struct sk_buff *
492 osl_pkt_tonative(osl_pubinfo_t *osh, void *pkt)
494 struct sk_buff *nskb;
496 if (osh->pkttag)
497 bzero(((struct sk_buff*)pkt)->cb, OSL_PKTTAG_SZ);
499 /* Decrement the packet counter */
500 for (nskb = (struct sk_buff *)pkt; nskb; nskb = nskb->next) {
501 #ifdef BCMDBG_PKT
502 osl_pktlist_remove((osl_t *)osh, (void *) nskb);
503 #endif /* BCMDBG_PKT */
504 osh->pktalloced--;
507 return (struct sk_buff *)pkt;
509 #define PKTTONATIVE(osh, pkt) osl_pkt_tonative((osl_pubinfo_t *)(osh), (pkt))
511 #define PKTLINK(skb) (((struct sk_buff*)(skb))->prev)
512 #define PKTSETLINK(skb, x) (((struct sk_buff*)(skb))->prev = (struct sk_buff*)(x))
513 #define PKTPRIO(skb) (((struct sk_buff*)(skb))->priority)
514 #define PKTSETPRIO(skb, x) (((struct sk_buff*)(skb))->priority = (x))
515 #define PKTSUMNEEDED(skb) (((struct sk_buff*)(skb))->ip_summed == CHECKSUM_HW)
516 #define PKTSETSUMGOOD(skb, x) (((struct sk_buff*)(skb))->ip_summed = \
517 ((x) ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE))
518 /* PKTSETSUMNEEDED and PKTSUMGOOD are not possible because skb->ip_summed is overloaded */
519 #define PKTSHARED(skb) (((struct sk_buff*)(skb))->cloned)
521 #if defined(DSLCPE_DELAY)
522 #include <linux/spinlock.h> /* for spinlock_t */
523 struct shared_osl {
524 int long_delay;
525 spinlock_t *lock;
526 void *wl;
527 unsigned long MIPS;
529 typedef struct shared_osl shared_osl_t;
531 #define OSL_LONG_DELAY(osh, usec) osl_long_delay(osh, usec, 0)
532 #define OSL_YIELD_EXEC(osh, usec) osl_long_delay(osh, usec, 1)
533 extern void osl_long_delay(osl_t *osh, uint usec, bool yield);
534 extern int in_long_delay(osl_t *osh);
535 extern void osl_oshsh_init(osl_t *osh, shared_osl_t *oshsh);
536 #define IN_LONG_DELAY(osh) in_long_delay(osh)
537 #endif /* DSLCPE_DELAY */
539 #else /* BINOSL */
541 /* Where to get the declarations for mem, str, printf, bcopy's? Two basic approaches.
543 * First, use the Linux header files and the C standard library replacmenent versions
544 * built-in to the kernel. Use this approach when compiling non hybrid code or compling
545 * the OS port files. The second approach is to use our own defines/prototypes and
546 * functions we have provided in the Linux OSL, i.e. linux_osl.c. Use this approach when
547 * compiling the files that make up the hybrid binary. We are ensuring we
548 * don't directly link to the kernel replacement routines from the hybrid binary.
550 * NOTE: The issue we are trying to avoid is any questioning of whether the
551 * hybrid binary is derived from Linux. The wireless common code (wlc) is designed
552 * to be OS independent through the use of the OSL API and thus the hybrid binary doesn't
553 * derive from the Linux kernel at all. But since we defined our OSL API to include
554 * a small collection of standard C library routines and these routines are provided in
555 * the kernel we want to avoid even the appearance of deriving at all even though clearly
556 * usage of a C standard library API doesn't represent a derivation from Linux. Lastly
557 * note at the time of this checkin 4 references to memcpy/memset could not be eliminated
558 * from the binary because they are created internally by GCC as part of things like
559 * structure assignment. I don't think the compiler should be doing this but there is
560 * no options to disable it on Intel architectures (there is for MIPS so somebody must
561 * agree with me). I may be able to even remove these references eventually with
562 * a GNU binutil such as objcopy via a symbol rename (i.e. memcpy to osl_memcpy).
564 #if !defined(LINUX_HYBRID) || defined(LINUX_PORT)
565 #define printf(fmt, args...) printk(fmt , ## args)
566 #include <linux/kernel.h> /* for vsn/printf's */
567 #include <linux/string.h> /* for mem*, str* */
568 /* bcopy's: Linux kernel doesn't provide these (anymore) */
569 #define bcopy(src, dst, len) memcpy((dst), (src), (len))
570 #define bcmp(b1, b2, len) memcmp((b1), (b2), (len))
571 #define bzero(b, len) memset((b), '\0', (len))
573 /* These are provided only because when compiling linux_osl.c there
574 * must be an explicit prototype (separate from the definition) because
575 * we are compiling with GCC option -Wstrict-prototypes. Conversely
576 * these could be placed directly in linux_osl.c.
578 extern int osl_printf(const char *format, ...);
579 extern int osl_sprintf(char *buf, const char *format, ...);
580 extern int osl_snprintf(char *buf, size_t n, const char *format, ...);
581 extern int osl_vsprintf(char *buf, const char *format, va_list ap);
582 extern int osl_vsnprintf(char *buf, size_t n, const char *format, va_list ap);
583 extern int osl_strcmp(const char *s1, const char *s2);
584 extern int osl_strncmp(const char *s1, const char *s2, uint n);
585 extern int osl_strlen(const char *s);
586 extern char* osl_strcpy(char *d, const char *s);
587 extern char* osl_strncpy(char *d, const char *s, uint n);
588 extern char* osl_strchr(const char *s, int c);
589 extern char* osl_strrchr(const char *s, int c);
590 extern void *osl_memset(void *d, int c, size_t n);
591 extern void *osl_memcpy(void *d, const void *s, size_t n);
592 extern void *osl_memmove(void *d, const void *s, size_t n);
593 extern int osl_memcmp(const void *s1, const void *s2, size_t n);
594 #else
596 /* In the below defines we undefine the macro first in case it is
597 * defined. This shouldn't happen because we are not using Linux
598 * header files but because our Linux 2.4 make includes modversions.h
599 * through a GCC -include compile option, they get defined to point
600 * at the appropriate versioned symbol name. Note this doesn't
601 * happen with our Linux 2.6 makes.
604 /* *printf functions */
605 #include <stdarg.h> /* va_list needed for v*printf */
606 #include <stddef.h> /* size_t needed for *nprintf */
607 #undef printf
608 #undef sprintf
609 #undef snprintf
610 #undef vsprintf
611 #undef vsnprintf
612 #define printf(fmt, args...) osl_printf((fmt) , ## args)
613 #define sprintf(buf, fmt, args...) osl_sprintf((buf), (fmt) , ## args)
614 #define snprintf(buf, n, fmt, args...) osl_snprintf((buf), (n), (fmt) , ## args)
615 #define vsprintf(buf, fmt, ap) osl_vsprintf((buf), (fmt), (ap))
616 #define vsnprintf(buf, n, fmt, ap) osl_vsnprintf((buf), (n), (fmt), (ap))
617 extern int osl_printf(const char *format, ...);
618 extern int osl_sprintf(char *buf, const char *format, ...);
619 extern int osl_snprintf(char *buf, size_t n, const char *format, ...);
620 extern int osl_vsprintf(char *buf, const char *format, va_list ap);
621 extern int osl_vsnprintf(char *buf, size_t n, const char *format, va_list ap);
623 /* str* functions */
624 #undef strcmp
625 #undef strncmp
626 #undef strlen
627 #undef strcpy
628 #undef strncpy
629 #undef strchr
630 #undef strrchr
631 #define strcmp(s1, s2) osl_strcmp((s1), (s2))
632 #define strncmp(s1, s2, n) osl_strncmp((s1), (s2), (n))
633 #define strlen(s) osl_strlen((s))
634 #define strcpy(d, s) osl_strcpy((d), (s))
635 #define strncpy(d, s, n) osl_strncpy((d), (s), (n))
636 #define strchr(s, c) osl_strchr((s), (c))
637 #define strrchr(s, c) osl_strrchr((s), (c))
638 extern int osl_strcmp(const char *s1, const char *s2);
639 extern int osl_strncmp(const char *s1, const char *s2, uint n);
640 extern int osl_strlen(const char *s);
641 extern char* osl_strcpy(char *d, const char *s);
642 extern char* osl_strncpy(char *d, const char *s, uint n);
643 extern char* osl_strchr(const char *s, int c);
644 extern char* osl_strrchr(const char *s, int c);
646 /* mem* functions */
647 #undef memset
648 #undef memcpy
649 #undef memcmp
650 #define memset(d, c, n) osl_memset((d), (c), (n))
651 #define memcpy(d, s, n) osl_memcpy((d), (s), (n))
652 #define memmove(d, s, n) osl_memmove((d), (s), (n))
653 #define memcmp(s1, s2, n) osl_memcmp((s1), (s2), (n))
654 extern void *osl_memset(void *d, int c, size_t n);
655 extern void *osl_memcpy(void *d, const void *s, size_t n);
656 extern void *osl_memmove(void *d, const void *s, size_t n);
657 extern int osl_memcmp(const void *s1, const void *s2, size_t n);
659 /* bcopy, bcmp, and bzero functions */
660 #undef bcopy
661 #undef bcmp
662 #undef bzero
663 #define bcopy(src, dst, len) osl_memcpy((dst), (src), (len))
664 #define bcmp(b1, b2, len) osl_memcmp((b1), (b2), (len))
665 #define bzero(b, len) osl_memset((b), '\0', (len))
666 #endif /* !defined(LINUX_HYBRID) || defined(LINUX_PORT) */
668 /* register access macros */
669 #if !defined(BCMJTAG)
670 #define R_REG(osh, r) (\
671 sizeof(*(r)) == sizeof(uint8) ? osl_readb((volatile uint8*)(r)) : \
672 sizeof(*(r)) == sizeof(uint16) ? osl_readw((volatile uint16*)(r)) : \
673 osl_readl((volatile uint32*)(r)) \
675 #define W_REG(osh, r, v) do { \
676 switch (sizeof(*(r))) { \
677 case sizeof(uint8): osl_writeb((uint8)(v), (volatile uint8*)(r)); break; \
678 case sizeof(uint16): osl_writew((uint16)(v), (volatile uint16*)(r)); break; \
679 case sizeof(uint32): osl_writel((uint32)(v), (volatile uint32*)(r)); break; \
681 } while (0)
683 /* else added by johnvb to make sdio and jtag work with BINOSL, at least compile ... UNTESTED */
684 #else
685 #define R_REG(osh, r) OSL_READ_REG(osh, r)
686 #define W_REG(osh, r, v) do { OSL_WRITE_REG(osh, r, v); } while (0)
687 #endif
689 #define AND_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) & (v))
690 #define OR_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) | (v))
691 extern uint8 osl_readb(volatile uint8 *r);
692 extern uint16 osl_readw(volatile uint16 *r);
693 extern uint32 osl_readl(volatile uint32 *r);
694 extern void osl_writeb(uint8 v, volatile uint8 *r);
695 extern void osl_writew(uint16 v, volatile uint16 *r);
696 extern void osl_writel(uint32 v, volatile uint32 *r);
698 /* system up time in ms */
699 #define OSL_SYSUPTIME() osl_sysuptime()
700 extern uint32 osl_sysuptime(void);
702 /* uncached/cached virtual address */
703 #define OSL_UNCACHED(va) osl_uncached((va))
704 extern void *osl_uncached(void *va);
705 #define OSL_CACHED(va) osl_cached((va))
706 extern void *osl_cached(void *va);
708 #ifdef __mips__
709 #define OSL_PREF_RANGE_LD(va, sz) prefetch_range_PREF_LOAD_RETAINED(va, sz)
710 #define OSL_PREF_RANGE_ST(va, sz) prefetch_range_PREF_STORE_RETAINED(va, sz)
711 #else /* __mips__ */
712 #define OSL_PREF_RANGE_LD(va, sz)
713 #define OSL_PREF_RANGE_ST(va, sz)
714 #endif /* __mips__ */
716 /* get processor cycle count */
717 #define OSL_GETCYCLES(x) ((x) = osl_getcycles())
718 extern uint osl_getcycles(void);
720 /* dereference an address that may target abort */
721 #define BUSPROBE(val, addr) osl_busprobe(&(val), (addr))
722 extern int osl_busprobe(uint32 *val, uint32 addr);
724 /* map/unmap physical to virtual */
725 #define REG_MAP(pa, size) osl_reg_map((pa), (size))
726 #define REG_UNMAP(va) osl_reg_unmap((va))
727 extern void *osl_reg_map(uint32 pa, uint size);
728 extern void osl_reg_unmap(void *va);
730 /* shared (dma-able) memory access macros */
731 #define R_SM(r) *(r)
732 #define W_SM(r, v) (*(r) = (v))
733 #define BZERO_SM(r, len) bzero((r), (len))
735 /* packet primitives */
736 #define PKTGET(osh, len, send) osl_pktget((osh), (len))
737 #define PKTFREE(osh, skb, send) osl_pktfree((osh), (skb), (send))
738 #define PKTDATA(osh, skb) osl_pktdata((osh), (skb))
739 #define PKTLEN(osh, skb) osl_pktlen((osh), (skb))
740 #define PKTHEADROOM(osh, skb) osl_pktheadroom((osh), (skb))
741 #define PKTTAILROOM(osh, skb) osl_pkttailroom((osh), (skb))
742 #define PKTNEXT(osh, skb) osl_pktnext((osh), (skb))
743 #define PKTSETNEXT(osh, skb, x) osl_pktsetnext((skb), (x))
744 #define PKTSETLEN(osh, skb, len) osl_pktsetlen((osh), (skb), (len))
745 #define PKTPUSH(osh, skb, bytes) osl_pktpush((osh), (skb), (bytes))
746 #define PKTPULL(osh, skb, bytes) osl_pktpull((osh), (skb), (bytes))
747 #define PKTDUP(osh, skb) osl_pktdup((osh), (skb))
748 #define PKTTAG(skb) osl_pkttag((skb))
749 #define PKTFRMNATIVE(osh, skb) osl_pkt_frmnative((osh), (skb))
750 #define PKTTONATIVE(osh, pkt) osl_pkt_tonative((osh), (pkt))
751 #define PKTLINK(skb) osl_pktlink((skb))
752 #define PKTSETLINK(skb, x) osl_pktsetlink((skb), (x))
753 #define PKTPRIO(skb) osl_pktprio((skb))
754 #define PKTSETPRIO(skb, x) osl_pktsetprio((skb), (x))
755 #define PKTSHARED(skb) osl_pktshared((skb))
756 #define PKTALLOCED(osh) osl_pktalloced((osh))
757 #ifdef BCMDBG_PKT
758 #define PKTLIST_DUMP(osh, buf) osl_pktlist_dump(osh, buf)
759 #else /* BCMDBG_PKT */
760 #define PKTLIST_DUMP(osh, buf)
761 #endif /* BCMDBG_PKT */
763 extern void *osl_pktget(osl_t *osh, uint len);
764 extern void osl_pktfree(osl_t *osh, void *skb, bool send);
765 extern uchar *osl_pktdata(osl_t *osh, void *skb);
766 extern uint osl_pktlen(osl_t *osh, void *skb);
767 extern uint osl_pktheadroom(osl_t *osh, void *skb);
768 extern uint osl_pkttailroom(osl_t *osh, void *skb);
769 extern void *osl_pktnext(osl_t *osh, void *skb);
770 extern void osl_pktsetnext(void *skb, void *x);
771 extern void osl_pktsetlen(osl_t *osh, void *skb, uint len);
772 extern uchar *osl_pktpush(osl_t *osh, void *skb, int bytes);
773 extern uchar *osl_pktpull(osl_t *osh, void *skb, int bytes);
774 extern void *osl_pktdup(osl_t *osh, void *skb);
775 extern void *osl_pkttag(void *skb);
776 extern void *osl_pktlink(void *skb);
777 extern void osl_pktsetlink(void *skb, void *x);
778 extern uint osl_pktprio(void *skb);
779 extern void osl_pktsetprio(void *skb, uint x);
780 extern void *osl_pkt_frmnative(osl_t *osh, void *skb);
781 extern struct sk_buff *osl_pkt_tonative(osl_t *osh, void *pkt);
782 extern bool osl_pktshared(void *skb);
783 extern uint osl_pktalloced(osl_t *osh);
785 #ifdef BCMDBG_PKT /* pkt logging for debugging */
786 extern char *osl_pktlist_dump(osl_t *osh, char *buf);
787 extern void osl_pktlist_add(osl_t *osh, void *p);
788 extern void osl_pktlist_remove(osl_t *osh, void *p);
789 #endif /* BCMDBG_PKT */
791 #endif /* BINOSL */
793 #else /* ! BCMDRIVER */
796 /* ASSERT */
797 #ifdef BCMDBG_ASSERT
798 #include <assert.h>
799 #define ASSERT assert
800 #else /* BCMDBG_ASSERT */
801 #define ASSERT(exp) do {} while (0)
802 #endif /* BCMDBG_ASSERT */
804 /* MALLOC and MFREE */
805 #define MALLOC(o, l) malloc(l)
806 #define MFREE(o, p, l) free(p)
807 #include <stdlib.h>
809 /* str* and mem* functions */
810 #include <string.h>
812 /* *printf functions */
813 #include <stdio.h>
815 /* bcopy, bcmp, and bzero */
816 extern void bcopy(const void *src, void *dst, size_t len);
817 extern int bcmp(const void *b1, const void *b2, size_t len);
818 extern void bzero(void *b, size_t len);
820 #endif /* ! BCMDRIVER */
822 #endif /* _linux_osl_h_ */