2 * Linux OS Independent Layer
4 * Copyright 2007, Broadcom Corporation
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.
22 #define OSL_PKTTAG_SZ 32 /* Size of PktTag */
24 /* microsecond delay */
25 extern void osl_delay(uint usec
);
27 /* OSL initialization */
28 extern osl_t
*osl_attach(void *pdev
, uint bustype
, bool pkttag
);
29 extern void osl_detach(osl_t
*osh
);
31 #define PKTFREESETCB(osh, _tx_fn, _tx_ctx) \
33 ((osl_pubinfo_t*)osh)->tx_fn = _tx_fn; \
34 ((osl_pubinfo_t*)osh)->tx_ctx = _tx_ctx; \
37 /* host/bus architecture-specific byte swap */
38 #define BUS_SWAP32(v) (v)
41 #define MALLOC_FAILED(osh) osl_malloc_failed((osh))
43 extern void *osl_malloc(osl_t
*osh
, uint size
);
44 extern void osl_mfree(osl_t
*osh
, void *addr
, uint size
);
45 extern uint
osl_malloced(osl_t
*osh
);
46 extern uint
osl_malloc_failed(osl_t
*osh
);
48 /* allocate/free shared (dma-able) consistent memory */
49 #define DMA_CONSISTENT_ALIGN PAGE_SIZE
50 #define DMA_ALLOC_CONSISTENT(osh, size, pap, dmah) \
51 osl_dma_alloc_consistent((osh), (size), (pap))
52 #define DMA_FREE_CONSISTENT(osh, va, size, pa, dmah) \
53 osl_dma_free_consistent((osh), (void*)(va), (size), (pa))
54 extern void *osl_dma_alloc_consistent(osl_t
*osh
, uint size
, ulong
*pap
);
55 extern void osl_dma_free_consistent(osl_t
*osh
, void *va
, uint size
, ulong pa
);
57 /* map/unmap direction */
58 #define DMA_TX 1 /* TX direction for DMA */
59 #define DMA_RX 2 /* RX direction for DMA */
61 /* map/unmap shared (dma-able) memory */
62 #define DMA_MAP(osh, va, size, direction, p, dmah) \
63 osl_dma_map((osh), (va), (size), (direction))
64 #define DMA_UNMAP(osh, pa, size, direction, p, dmah) \
65 osl_dma_unmap((osh), (pa), (size), (direction))
66 extern uint
osl_dma_map(osl_t
*osh
, void *va
, uint size
, int direction
);
67 extern void osl_dma_unmap(osl_t
*osh
, uint pa
, uint size
, int direction
);
69 /* API for DMA addressing capability */
70 #define OSL_DMADDRWIDTH(osh, addrwidth) do {} while (0)
72 /* register access macros */
75 #define OSL_WRITE_REG(osh, r, v) (bcmjtag_write(NULL, (uintptr)(r), (v), sizeof(*(r))))
76 #define OSL_READ_REG(osh, r) (bcmjtag_read(NULL, (uintptr)(r), sizeof(*(r))))
80 #define SELECT_BUS_WRITE(osh, mmap_op, bus_op) if (((osl_pubinfo_t*)(osh))->mmbus) \
82 #define SELECT_BUS_READ(osh, mmap_op, bus_op) (((osl_pubinfo_t*)(osh))->mmbus) ? \
85 #define SELECT_BUS_WRITE(osh, mmap_op, bus_op) mmap_op
86 #define SELECT_BUS_READ(osh, mmap_op, bus_op) mmap_op
90 * BINOSL selects the slightly slower function-call-based binary compatible osl.
91 * Macros expand to calls to functions defined in linux_osl.c .
95 /* string library, kernel mode */
97 #define printf(fmt, args...) printk(fmt, ## args)
99 #include <linux/kernel.h>
100 #include <linux/string.h>
102 /* register access macros */
103 #define AND_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) & (v))
104 #define OR_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) | (v))
106 /* bcopy, bcmp, and bzero */
107 #define bcopy(src, dst, len) memcpy((dst), (src), (len))
108 #define bcmp(b1, b2, len) memcmp((b1), (b2), (len))
109 #define bzero(b, len) memset((b), '\0', (len))
111 /* uncached virtual address */
113 #define OSL_UNCACHED(va) KSEG1ADDR((va))
114 #include <asm/addrspace.h>
116 #define OSL_UNCACHED(va) (va)
119 /* get processor cycle count */
121 #define OSL_GETCYCLES(x) ((x) = read_c0_count() * 2)
122 #elif defined(__i386__)
123 #define OSL_GETCYCLES(x) rdtscl((x))
125 #define OSL_GETCYCLES(x) ((x) = 0)
126 #endif /* defined(mips) */
128 /* dereference an address that may cause a bus exception */
130 #if defined(MODULE) && (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 17))
131 #define BUSPROBE(val, addr) panic("get_dbe() will not fixup a bus exception when compiled into"\
134 #define BUSPROBE(val, addr) get_dbe((val), (addr))
135 #include <asm/paccess.h>
136 #endif /* defined(MODULE) && (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 17)) */
138 #define BUSPROBE(val, addr) ({ (val) = R_REG(NULL, (addr)); 0; })
141 /* map/unmap physical to virtual I/O */
142 #define REG_MAP(pa, size) ioremap_nocache((unsigned long)(pa), (unsigned long)(size))
143 #define REG_UNMAP(va) iounmap((void *)(va))
145 /* shared (dma-able) memory access macros */
147 #define W_SM(r, v) (*(r) = (v))
148 #define BZERO_SM(r, len) memset((r), '\0', (len))
150 /* packet primitives */
151 #define PKTGET(osh, len, send) osl_pktget((osh), (len))
152 #define PKTFREE(osh, skb, send) osl_pktfree((osh), (skb), (send))
153 #define PKTDATA(osh, skb) (((struct sk_buff*)(skb))->data)
154 #define PKTLEN(osh, skb) (((struct sk_buff*)(skb))->len)
155 #define PKTHEADROOM(osh, skb) (PKTDATA(osh, skb)-(((struct sk_buff*)(skb))->head))
156 #define PKTTAILROOM(osh, skb) ((((struct sk_buff*)(skb))->end)-(((struct sk_buff*)(skb))->tail))
157 #define PKTNEXT(osh, skb) (((struct sk_buff*)(skb))->next)
158 #define PKTSETNEXT(osh, skb, x) (((struct sk_buff*)(skb))->next = (struct sk_buff*)(x))
159 #define PKTSETLEN(osh, skb, len) __skb_trim((struct sk_buff*)(skb), (len))
160 #define PKTPUSH(osh, skb, bytes) skb_push((struct sk_buff*)(skb), (bytes))
161 #define PKTPULL(osh, skb, bytes) skb_pull((struct sk_buff*)(skb), (bytes))
162 #define PKTDUP(osh, skb) osl_pktdup((osh), (skb))
163 #define PKTTAG(skb) ((void*)(((struct sk_buff*)(skb))->cb))
164 #define PKTALLOCED(osh) ((osl_pubinfo_t *)(osh))->pktalloced
165 #ifdef BCMDBG_PKT /* pkt logging for debugging */
166 #define PKTLIST_DUMP(osh, buf) osl_pktlist_dump(osh, buf)
167 #else /* BCMDBG_PKT */
168 #define PKTLIST_DUMP(osh, buf)
169 #endif /* BCMDBG_PKT */
171 #ifdef BCMDBG_PKT /* pkt logging for debugging */
172 extern void osl_pktlist_add(osl_t
*osh
, void *p
);
173 extern void osl_pktlist_remove(osl_t
*osh
, void *p
);
174 extern char *osl_pktlist_dump(osl_t
*osh
, char *buf
);
175 #endif /* BCMDBG_PKT */
177 /* Convert a native(OS) packet to driver packet.
178 * In the process, native packet is destroyed, there is no copying
179 * Also, a packettag is zeroed out
182 osl_pkt_frmnative(osl_pubinfo_t
*osh
, struct sk_buff
*skb
)
184 struct sk_buff
*nskb
;
187 bzero((void*)skb
->cb
, OSL_PKTTAG_SZ
);
189 /* Increment the packet counter */
190 for (nskb
= skb
; nskb
; nskb
= nskb
->next
) {
192 osl_pktlist_add((osl_t
*)osh
, (void *) nskb
);
193 #endif /* BCMDBG_PKT */
199 #define PKTFRMNATIVE(osh, skb) osl_pkt_frmnative(((osl_pubinfo_t *)osh), (struct sk_buff*)(skb))
201 /* Convert a driver packet to native(OS) packet
202 * In the process, packettag is zeroed out before sending up
203 * IP code depends on skb->cb to be setup correctly with various options
204 * In our case, that means it should be 0
206 static INLINE
struct sk_buff
*
207 osl_pkt_tonative(osl_pubinfo_t
*osh
, void *pkt
)
209 struct sk_buff
*nskb
;
212 bzero(((struct sk_buff
*)pkt
)->cb
, OSL_PKTTAG_SZ
);
214 /* Decrement the packet counter */
215 for (nskb
= (struct sk_buff
*)pkt
; nskb
; nskb
= nskb
->next
) {
217 osl_pktlist_remove((osl_t
*)osh
, (void *) nskb
);
218 #endif /* BCMDBG_PKT */
222 return (struct sk_buff
*)pkt
;
224 #define PKTTONATIVE(osh, pkt) osl_pkt_tonative((osl_pubinfo_t *)(osh), (pkt))
226 #define PKTLINK(skb) (((struct sk_buff*)(skb))->prev)
227 #define PKTSETLINK(skb, x) (((struct sk_buff*)(skb))->prev = (struct sk_buff*)(x))
228 #define PKTPRIO(skb) (((struct sk_buff*)(skb))->priority)
229 #define PKTSETPRIO(skb, x) (((struct sk_buff*)(skb))->priority = (x))
230 #define PKTSUMNEEDED(skb) (((struct sk_buff*)(skb))->ip_summed == CHECKSUM_HW)
231 #define PKTSETSUMGOOD(skb, x) (((struct sk_buff*)(skb))->ip_summed = \
232 ((x) ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE))
233 /* PKTSETSUMNEEDED and PKTSUMGOOD are not possible because skb->ip_summed is overloaded */
234 #define PKTSHARED(skb) (((struct sk_buff*)(skb))->cloned)
236 extern void *osl_pktget(osl_t
*osh
, uint len
);
237 extern void osl_pktfree(osl_t
*osh
, void *skb
, bool send
);
238 extern void *osl_pktdup(osl_t
*osh
, void *skb
);
244 #define printf(fmt, args...) osl_printf((fmt), ## args)
246 #define sprintf(buf, fmt, args...) osl_sprintf((buf), (fmt), ## args)
248 #define strcmp(s1, s2) osl_strcmp((s1), (s2))
250 #define strncmp(s1, s2, n) osl_strncmp((s1), (s2), (n))
252 #define strlen(s) osl_strlen((s))
254 #define strcpy(d, s) osl_strcpy((d), (s))
256 #define strncpy(d, s, n) osl_strncpy((d), (s), (n))
257 #endif /* LINUX_OSL */
258 extern int osl_printf(const char *format
, ...);
259 extern int osl_sprintf(char *buf
, const char *format
, ...);
260 extern int osl_strcmp(const char *s1
, const char *s2
);
261 extern int osl_strncmp(const char *s1
, const char *s2
, uint n
);
262 extern int osl_strlen(const char *s
);
263 extern char* osl_strcpy(char *d
, const char *s
);
264 extern char* osl_strncpy(char *d
, const char *s
, uint n
);
266 /* register access macros */
267 #if !defined(BCMJTAG)
268 #define R_REG(osh, r) (\
269 sizeof(*(r)) == sizeof(uint8) ? osl_readb((volatile uint8*)(r)) : \
270 sizeof(*(r)) == sizeof(uint16) ? osl_readw((volatile uint16*)(r)) : \
271 osl_readl((volatile uint32*)(r)) \
273 #define W_REG(osh, r, v) do { \
274 switch (sizeof(*(r))) { \
275 case sizeof(uint8): osl_writeb((uint8)(v), (volatile uint8*)(r)); break; \
276 case sizeof(uint16): osl_writew((uint16)(v), (volatile uint16*)(r)); break; \
277 case sizeof(uint32): osl_writel((uint32)(v), (volatile uint32*)(r)); break; \
282 #define AND_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) & (v))
283 #define OR_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) | (v))
284 extern uint8
osl_readb(volatile uint8
*r
);
285 extern uint16
osl_readw(volatile uint16
*r
);
286 extern uint32
osl_readl(volatile uint32
*r
);
287 extern void osl_writeb(uint8 v
, volatile uint8
*r
);
288 extern void osl_writew(uint16 v
, volatile uint16
*r
);
289 extern void osl_writel(uint32 v
, volatile uint32
*r
);
291 /* bcopy, bcmp, and bzero */
292 extern void bcopy(const void *src
, void *dst
, int len
);
293 extern int bcmp(const void *b1
, const void *b2
, int len
);
294 extern void bzero(void *b
, int len
);
296 /* uncached virtual address */
297 #define OSL_UNCACHED(va) osl_uncached((va))
298 extern void *osl_uncached(void *va
);
300 /* get processor cycle count */
301 #define OSL_GETCYCLES(x) ((x) = osl_getcycles())
302 extern uint
osl_getcycles(void);
304 /* dereference an address that may target abort */
305 #define BUSPROBE(val, addr) osl_busprobe(&(val), (addr))
306 extern int osl_busprobe(uint32
*val
, uint32 addr
);
308 /* map/unmap physical to virtual */
309 #define REG_MAP(pa, size) osl_reg_map((pa), (size))
310 #define REG_UNMAP(va) osl_reg_unmap((va))
311 extern void *osl_reg_map(uint32 pa
, uint size
);
312 extern void osl_reg_unmap(void *va
);
314 /* shared (dma-able) memory access macros */
316 #define W_SM(r, v) (*(r) = (v))
317 #define BZERO_SM(r, len) bzero((r), (len))
319 /* packet primitives */
320 #define PKTGET(osh, len, send) osl_pktget((osh), (len))
321 #define PKTFREE(osh, skb, send) osl_pktfree((osh), (skb), (send))
322 #define PKTDATA(osh, skb) osl_pktdata((osh), (skb))
323 #define PKTLEN(osh, skb) osl_pktlen((osh), (skb))
324 #define PKTHEADROOM(osh, skb) osl_pktheadroom((osh), (skb))
325 #define PKTTAILROOM(osh, skb) osl_pkttailroom((osh), (skb))
326 #define PKTNEXT(osh, skb) osl_pktnext((osh), (skb))
327 #define PKTSETNEXT(osh, skb, x) osl_pktsetnext((skb), (x))
328 #define PKTSETLEN(osh, skb, len) osl_pktsetlen((osh), (skb), (len))
329 #define PKTPUSH(osh, skb, bytes) osl_pktpush((osh), (skb), (bytes))
330 #define PKTPULL(osh, skb, bytes) osl_pktpull((osh), (skb), (bytes))
331 #define PKTDUP(osh, skb) osl_pktdup((osh), (skb))
332 #define PKTTAG(skb) osl_pkttag((skb))
333 #define PKTFRMNATIVE(osh, skb) osl_pkt_frmnative((osh), (struct sk_buff*)(skb))
334 #define PKTTONATIVE(osh, pkt) osl_pkt_tonative((osh), (pkt))
335 #define PKTLINK(skb) osl_pktlink((skb))
336 #define PKTSETLINK(skb, x) osl_pktsetlink((skb), (x))
337 #define PKTPRIO(skb) osl_pktprio((skb))
338 #define PKTSETPRIO(skb, x) osl_pktsetprio((skb), (x))
339 #define PKTSHARED(skb) osl_pktshared((skb))
340 #define PKTALLOCED(osh) osl_pktalloced((osh))
342 #define PKTLIST_DUMP(osh, buf) osl_pktlist_dump(osh, buf)
343 #else /* BCMDBG_PKT */
344 #define PKTLIST_DUMP(osh, buf)
345 #endif /* BCMDBG_PKT */
347 extern void *osl_pktget(osl_t
*osh
, uint len
);
348 extern void osl_pktfree(osl_t
*osh
, void *skb
, bool send
);
349 extern uchar
*osl_pktdata(osl_t
*osh
, void *skb
);
350 extern uint
osl_pktlen(osl_t
*osh
, void *skb
);
351 extern uint
osl_pktheadroom(osl_t
*osh
, void *skb
);
352 extern uint
osl_pkttailroom(osl_t
*osh
, void *skb
);
353 extern void *osl_pktnext(osl_t
*osh
, void *skb
);
354 extern void osl_pktsetnext(void *skb
, void *x
);
355 extern void osl_pktsetlen(osl_t
*osh
, void *skb
, uint len
);
356 extern uchar
*osl_pktpush(osl_t
*osh
, void *skb
, int bytes
);
357 extern uchar
*osl_pktpull(osl_t
*osh
, void *skb
, int bytes
);
358 extern void *osl_pktdup(osl_t
*osh
, void *skb
);
359 extern void *osl_pkttag(void *skb
);
360 extern void *osl_pktlink(void *skb
);
361 extern void osl_pktsetlink(void *skb
, void *x
);
362 extern uint
osl_pktprio(void *skb
);
363 extern void osl_pktsetprio(void *skb
, uint x
);
364 extern void *osl_pkt_frmnative(osl_t
*osh
, struct sk_buff
*skb
);
365 extern struct sk_buff
*osl_pkt_tonative(osl_t
*osh
, void *pkt
);
366 extern bool osl_pktshared(void *skb
);
367 extern uint
osl_pktalloced(osl_t
*osh
);
369 #ifdef BCMDBG_PKT /* pkt logging for debugging */
370 extern char *osl_pktlist_dump(osl_t
*osh
, char *buf
);
371 extern void osl_pktlist_add(osl_t
*osh
, void *p
);
372 extern void osl_pktlist_remove(osl_t
*osh
, void *p
);
373 #endif /* BCMDBG_PKT */
377 #define OSL_ERROR(bcmerror) osl_error(bcmerror)
378 extern int osl_error(int bcmerror
);
380 /* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */
381 #define PKTBUFSZ 2048 /* largest reasonable packet buffer, driver uses for ethernet MTU */
383 #endif /* _linux_osl_h_ */