add all source code from linksys/broadcom which is free, to cvs for better maintainen...
[openwrt/svn-archive/archive.git] / openwrt / package / linux / kernel-source / drivers / net / hnd / linux_osl.c
1 /*
2 * Linux OS Independent Layer
3 *
4 * Copyright 2004, 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 #define LINUX_OSL
16
17 #include <typedefs.h>
18 #include <bcmendian.h>
19 #include <linuxver.h>
20 #include <linux_osl.h>
21 #include <bcmutils.h>
22 #include <linux/delay.h>
23 #ifdef mips
24 #include <asm/paccess.h>
25 #endif
26 #include <pcicfg.h>
27
28 #define PCI_CFG_RETRY 10
29
30 void*
31 osl_pktget(void *drv, uint len, bool send)
32 {
33 struct sk_buff *skb;
34
35 if ((skb = dev_alloc_skb(len)) == NULL)
36 return (NULL);
37
38 skb_put(skb, len);
39
40 /* ensure the cookie field is cleared */
41 PKTSETCOOKIE(skb, NULL);
42
43 return ((void*) skb);
44 }
45
46 void
47 osl_pktfree(void *p)
48 {
49 struct sk_buff *skb, *nskb;
50
51 skb = (struct sk_buff*) p;
52
53 /* perversion: we use skb->next to chain multi-skb packets */
54 while (skb) {
55 nskb = skb->next;
56 skb->next = NULL;
57 if (skb->destructor) {
58 /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if destructor exists */
59 dev_kfree_skb_any(skb);
60 } else {
61 /* can free immediately (even in_irq()) if destructor does not exist */
62 dev_kfree_skb(skb);
63 }
64 skb = nskb;
65 }
66 }
67
68 uint32
69 osl_pci_read_config(void *loc, uint offset, uint size)
70 {
71 struct pci_dev *pdev;
72 uint val;
73 uint retry=PCI_CFG_RETRY;
74
75 /* only 4byte access supported */
76 ASSERT(size == 4);
77
78 pdev = (struct pci_dev*)loc;
79 do {
80 pci_read_config_dword(pdev, offset, &val);
81 if (val != 0xffffffff)
82 break;
83 } while (retry--);
84
85
86 return (val);
87 }
88
89 void
90 osl_pci_write_config(void *loc, uint offset, uint size, uint val)
91 {
92 struct pci_dev *pdev;
93 uint retry=PCI_CFG_RETRY;
94
95 /* only 4byte access supported */
96 ASSERT(size == 4);
97
98 pdev = (struct pci_dev*)loc;
99
100 do {
101 pci_write_config_dword(pdev, offset, val);
102 if (offset!=PCI_BAR0_WIN)
103 break;
104 if (osl_pci_read_config(loc,offset,size) == val)
105 break;
106 } while (retry--);
107
108 }
109
110 static void
111 osl_pcmcia_attr(void *osh, uint offset, char *buf, int size, bool write)
112 {
113 }
114
115 void
116 osl_pcmcia_read_attr(void *osh, uint offset, void *buf, int size)
117 {
118 osl_pcmcia_attr(osh, offset, (char *) buf, size, FALSE);
119 }
120
121 void
122 osl_pcmcia_write_attr(void *osh, uint offset, void *buf, int size)
123 {
124 osl_pcmcia_attr(osh, offset, (char *) buf, size, TRUE);
125 }
126
127 #if defined(BINOSL)
128
129 void
130 osl_assert(char *exp, char *file, int line)
131 {
132 char tempbuf[255];
133
134 sprintf(tempbuf, "assertion \"%s\" failed: file \"%s\", line %d\n", exp, file, line);
135 panic(tempbuf);
136 }
137
138
139
140 void*
141 osl_malloc(uint size)
142 {
143 return (kmalloc(size, GFP_ATOMIC));
144 }
145
146 void
147 osl_mfree(void *addr, uint size)
148 {
149 kfree(addr);
150 }
151
152 uint
153 osl_malloced(void)
154 {
155 #ifdef MODULE
156 return malloced;
157 #else
158 return 0;
159 #endif
160 }
161
162 #endif /* defined(BCMDBG) || defined(BINOSL) */
163
164 /*
165 * BINOSL selects the slightly slower function-call-based binary compatible osl.
166 */
167 #ifdef BINOSL
168
169 int
170 osl_printf(const char *format, ...)
171 {
172 va_list args;
173 char buf[1024];
174 int len;
175
176 /* sprintf into a local buffer because there *is* no "vprintk()".. */
177 va_start(args, format);
178 len = vsprintf(buf, format, args);
179 va_end(args);
180
181 if (len > sizeof (buf)) {
182 printk("osl_printf: buffer overrun\n");
183 return (0);
184 }
185
186 return (printk(buf));
187 }
188
189 int
190 osl_sprintf(char *buf, const char *format, ...)
191 {
192 va_list args;
193 int rc;
194
195 va_start(args, format);
196 rc = vsprintf(buf, format, args);
197 va_end(args);
198 return (rc);
199 }
200
201 int
202 osl_strcmp(const char *s1, const char *s2)
203 {
204 return (strcmp(s1, s2));
205 }
206
207 int
208 osl_strncmp(const char *s1, const char *s2, uint n)
209 {
210 return (strncmp(s1, s2, n));
211 }
212
213 int
214 osl_strlen(char *s)
215 {
216 return (strlen(s));
217 }
218
219 char*
220 osl_strcpy(char *d, const char *s)
221 {
222 return (strcpy(d, s));
223 }
224
225 char*
226 osl_strncpy(char *d, const char *s, uint n)
227 {
228 return (strncpy(d, s, n));
229 }
230
231 void
232 bcopy(const void *src, void *dst, int len)
233 {
234 memcpy(dst, src, len);
235 }
236
237 int
238 bcmp(const void *b1, const void *b2, int len)
239 {
240 return (memcmp(b1, b2, len));
241 }
242
243 void
244 bzero(void *b, int len)
245 {
246 memset(b, '\0', len);
247 }
248
249 uint32
250 osl_readl(volatile uint32 *r)
251 {
252 return (readl(r));
253 }
254
255 uint16
256 osl_readw(volatile uint16 *r)
257 {
258 return (readw(r));
259 }
260
261 uint8
262 osl_readb(volatile uint8 *r)
263 {
264 return (readb(r));
265 }
266
267 void
268 osl_writel(uint32 v, volatile uint32 *r)
269 {
270 writel(v, r);
271 }
272
273 void
274 osl_writew(uint16 v, volatile uint16 *r)
275 {
276 writew(v, r);
277 }
278
279 void
280 osl_writeb(uint8 v, volatile uint8 *r)
281 {
282 writeb(v, r);
283 }
284
285 void *
286 osl_uncached(void *va)
287 {
288 #ifdef mips
289 return ((void*)KSEG1ADDR(va));
290 #else
291 return ((void*)va);
292 #endif
293 }
294
295 uint
296 osl_getcycles(void)
297 {
298 uint cycles;
299
300 #if defined(mips)
301 cycles = read_c0_count() * 2;
302 #elif defined(__i386__)
303 rdtscl(cycles);
304 #else
305 cycles = 0;
306 #endif
307 return cycles;
308 }
309
310 void *
311 osl_reg_map(uint32 pa, uint size)
312 {
313 return (ioremap_nocache((unsigned long)pa, (unsigned long)size));
314 }
315
316 void
317 osl_reg_unmap(void *va)
318 {
319 iounmap(va);
320 }
321
322 int
323 osl_busprobe(uint32 *val, uint32 addr)
324 {
325 #ifdef mips
326 return get_dbe(*val, (uint32*)addr);
327 #else
328 *val = readl(addr);
329 return 0;
330 #endif
331 }
332
333 void*
334 osl_dma_alloc_consistent(void *dev, uint size, ulong *pap)
335 {
336 return (pci_alloc_consistent((struct pci_dev*)dev, size, (dma_addr_t*)pap));
337 }
338
339 void
340 osl_dma_free_consistent(void *dev, void *va, uint size, ulong pa)
341 {
342 pci_free_consistent((struct pci_dev*)dev, size, va, (dma_addr_t)pa);
343 }
344
345 uint
346 osl_dma_map(void *dev, void *va, uint size, int direction)
347 {
348 int dir;
349
350 dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE;
351 return (pci_map_single(dev, va, size, dir));
352 }
353
354 void
355 osl_dma_unmap(void *dev, uint pa, uint size, int direction)
356 {
357 int dir;
358
359 dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE;
360 pci_unmap_single(dev, (uint32)pa, size, dir);
361 }
362
363 void
364 osl_delay(uint usec)
365 {
366 udelay(usec);
367 }
368
369 uchar*
370 osl_pktdata(void *drv, void *skb)
371 {
372 return (((struct sk_buff*)skb)->data);
373 }
374
375 uint
376 osl_pktlen(void *drv, void *skb)
377 {
378 return (((struct sk_buff*)skb)->len);
379 }
380
381 uint
382 osl_pktheadroom(void *drv, void *skb)
383 {
384 return (uint) skb_headroom((struct sk_buff *) skb);
385 }
386
387 uint
388 osl_pkttailroom(void *drv, void *skb)
389 {
390 return (uint) skb_tailroom((struct sk_buff *) skb);
391 }
392
393 void*
394 osl_pktnext(void *drv, void *skb)
395 {
396 return (((struct sk_buff*)skb)->next);
397 }
398
399 void
400 osl_pktsetnext(void *skb, void *x)
401 {
402 ((struct sk_buff*)skb)->next = (struct sk_buff*)x;
403 }
404
405 void
406 osl_pktsetlen(void *drv, void *skb, uint len)
407 {
408 __skb_trim((struct sk_buff*)skb, len);
409 }
410
411 uchar*
412 osl_pktpush(void *drv, void *skb, int bytes)
413 {
414 return (skb_push((struct sk_buff*)skb, bytes));
415 }
416
417 uchar*
418 osl_pktpull(void *drv, void *skb, int bytes)
419 {
420 return (skb_pull((struct sk_buff*)skb, bytes));
421 }
422
423 void*
424 osl_pktdup(void *drv, void *skb)
425 {
426 return (skb_clone((struct sk_buff*)skb, GFP_ATOMIC));
427 }
428
429 void*
430 osl_pktcookie(void *skb)
431 {
432 return ((void*)((struct sk_buff*)skb)->csum);
433 }
434
435 void
436 osl_pktsetcookie(void *skb, void *x)
437 {
438 ((struct sk_buff*)skb)->csum = (uint)x;
439 }
440
441 void*
442 osl_pktlink(void *skb)
443 {
444 return (((struct sk_buff*)skb)->prev);
445 }
446
447 void
448 osl_pktsetlink(void *skb, void *x)
449 {
450 ((struct sk_buff*)skb)->prev = (struct sk_buff*)x;
451 }
452
453 uint
454 osl_pktprio(void *skb)
455 {
456 return (((struct sk_buff*)skb)->priority);
457 }
458
459 void
460 osl_pktsetprio(void *skb, uint x)
461 {
462 ((struct sk_buff*)skb)->priority = x;
463 }
464
465 #endif /* BINOSL */