f65c85966b7a23c1f069e825024bff0cde38f9cd
[openwrt/openwrt.git] / package / broadcom-wl / src / driver / linux_osl.h
1 /*
2 * Linux OS Independent Layer
3 *
4 * Copyright 2007, 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.
11 *
12 * $Id$
13 */
14
15 #ifndef _linux_osl_h_
16 #define _linux_osl_h_
17
18 #include <typedefs.h>
19 #include <linuxver.h>
20 #include <osl.h>
21
22 #define OSL_PKTTAG_SZ 32 /* Size of PktTag */
23
24 /* microsecond delay */
25 extern void osl_delay(uint usec);
26
27 /* OSL initialization */
28 extern osl_t *osl_attach(void *pdev, uint bustype, bool pkttag);
29 extern void osl_detach(osl_t *osh);
30
31 #define PKTFREESETCB(osh, _tx_fn, _tx_ctx) \
32 do { \
33 ((osl_pubinfo_t*)osh)->tx_fn = _tx_fn; \
34 ((osl_pubinfo_t*)osh)->tx_ctx = _tx_ctx; \
35 } while (0)
36
37 /* host/bus architecture-specific byte swap */
38 #define BUS_SWAP32(v) (v)
39
40
41 #define MALLOC_FAILED(osh) osl_malloc_failed((osh))
42
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);
47
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);
56
57 /* map/unmap direction */
58 #define DMA_TX 1 /* TX direction for DMA */
59 #define DMA_RX 2 /* RX direction for DMA */
60
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);
68
69 /* API for DMA addressing capability */
70 #define OSL_DMADDRWIDTH(osh, addrwidth) do {} while (0)
71
72 /* register access macros */
73 #if defined(BCMJTAG)
74 #include <bcmjtag.h>
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))))
77 #endif
78
79 #if defined(BCMJTAG)
80 #define SELECT_BUS_WRITE(osh, mmap_op, bus_op) if (((osl_pubinfo_t*)(osh))->mmbus) \
81 mmap_op else bus_op
82 #define SELECT_BUS_READ(osh, mmap_op, bus_op) (((osl_pubinfo_t*)(osh))->mmbus) ? \
83 mmap_op : bus_op
84 #else
85 #define SELECT_BUS_WRITE(osh, mmap_op, bus_op) mmap_op
86 #define SELECT_BUS_READ(osh, mmap_op, bus_op) mmap_op
87 #endif
88
89 /*
90 * BINOSL selects the slightly slower function-call-based binary compatible osl.
91 * Macros expand to calls to functions defined in linux_osl.c .
92 */
93 #ifndef BINOSL
94
95 /* string library, kernel mode */
96 #ifndef printf
97 #define printf(fmt, args...) printk(fmt, ## args)
98 #endif /* printf */
99 #include <linux/kernel.h>
100 #include <linux/string.h>
101
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))
105
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))
110
111 /* uncached virtual address */
112 #ifdef mips
113 #define OSL_UNCACHED(va) KSEG1ADDR((va))
114 #include <asm/addrspace.h>
115 #else
116 #define OSL_UNCACHED(va) (va)
117 #endif /* mips */
118
119 /* get processor cycle count */
120 #if defined(mips)
121 #define OSL_GETCYCLES(x) ((x) = read_c0_count() * 2)
122 #elif defined(__i386__)
123 #define OSL_GETCYCLES(x) rdtscl((x))
124 #else
125 #define OSL_GETCYCLES(x) ((x) = 0)
126 #endif /* defined(mips) */
127
128 /* dereference an address that may cause a bus exception */
129 #ifdef mips
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"\
132 " a module")
133 #else
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)) */
137 #else
138 #define BUSPROBE(val, addr) ({ (val) = R_REG(NULL, (addr)); 0; })
139 #endif /* mips */
140
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))
144
145 /* shared (dma-able) memory access macros */
146 #define R_SM(r) *(r)
147 #define W_SM(r, v) (*(r) = (v))
148 #define BZERO_SM(r, len) memset((r), '\0', (len))
149
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 */
170
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 */
176
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
180 */
181 static INLINE void *
182 osl_pkt_frmnative(osl_pubinfo_t *osh, struct sk_buff *skb)
183 {
184 struct sk_buff *nskb;
185
186 if (osh->pkttag)
187 bzero((void*)skb->cb, OSL_PKTTAG_SZ);
188
189 /* Increment the packet counter */
190 for (nskb = skb; nskb; nskb = nskb->next) {
191 #ifdef BCMDBG_PKT
192 osl_pktlist_add((osl_t *)osh, (void *) nskb);
193 #endif /* BCMDBG_PKT */
194 osh->pktalloced++;
195 }
196
197 return (void *)skb;
198 }
199 #define PKTFRMNATIVE(osh, skb) osl_pkt_frmnative(((osl_pubinfo_t *)osh), (struct sk_buff*)(skb))
200
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
205 */
206 static INLINE struct sk_buff *
207 osl_pkt_tonative(osl_pubinfo_t *osh, void *pkt)
208 {
209 struct sk_buff *nskb;
210
211 if (osh->pkttag)
212 bzero(((struct sk_buff*)pkt)->cb, OSL_PKTTAG_SZ);
213
214 /* Decrement the packet counter */
215 for (nskb = (struct sk_buff *)pkt; nskb; nskb = nskb->next) {
216 #ifdef BCMDBG_PKT
217 osl_pktlist_remove((osl_t *)osh, (void *) nskb);
218 #endif /* BCMDBG_PKT */
219 osh->pktalloced--;
220 }
221
222 return (struct sk_buff *)pkt;
223 }
224 #define PKTTONATIVE(osh, pkt) osl_pkt_tonative((osl_pubinfo_t *)(osh), (pkt))
225
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)
235
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);
239 #else /* BINOSL */
240
241 /* string library */
242 #ifndef LINUX_OSL
243 #undef printf
244 #define printf(fmt, args...) osl_printf((fmt), ## args)
245 #undef sprintf
246 #define sprintf(buf, fmt, args...) osl_sprintf((buf), (fmt), ## args)
247 #undef strcmp
248 #define strcmp(s1, s2) osl_strcmp((s1), (s2))
249 #undef strncmp
250 #define strncmp(s1, s2, n) osl_strncmp((s1), (s2), (n))
251 #undef strlen
252 #define strlen(s) osl_strlen((s))
253 #undef strcpy
254 #define strcpy(d, s) osl_strcpy((d), (s))
255 #undef strncpy
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);
265
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)) \
272 )
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; \
278 } \
279 } while (0)
280 #endif
281
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);
290
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);
295
296 /* uncached virtual address */
297 #define OSL_UNCACHED(va) osl_uncached((va))
298 extern void *osl_uncached(void *va);
299
300 /* get processor cycle count */
301 #define OSL_GETCYCLES(x) ((x) = osl_getcycles())
302 extern uint osl_getcycles(void);
303
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);
307
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);
313
314 /* shared (dma-able) memory access macros */
315 #define R_SM(r) *(r)
316 #define W_SM(r, v) (*(r) = (v))
317 #define BZERO_SM(r, len) bzero((r), (len))
318
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))
341 #ifdef BCMDBG_PKT
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 */
346
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);
368
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 */
374
375 #endif /* BINOSL */
376
377 #define OSL_ERROR(bcmerror) osl_error(bcmerror)
378 extern int osl_error(int bcmerror);
379
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 */
382
383 #endif /* _linux_osl_h_ */