get rid of $Id$ - it has never helped us and it has broken too many patches ;)
[openwrt.git] / package / broadcom-wl / src / driver / linux_osl.c
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  */
13
14 #define LINUX_OSL
15
16 #include <typedefs.h>
17 #include <bcmendian.h>
18 #include <linuxver.h>
19 #include <bcmdefs.h>
20 #include <osl.h>
21 #include "linux_osl.h"
22 #include "bcmutils.h"
23 #include <linux/delay.h>
24 #ifdef mips
25 #include <asm/paccess.h>
26 #endif /* mips */
27 #include <pcicfg.h>
28
29 #define PCI_CFG_RETRY           10
30
31 #define OS_HANDLE_MAGIC         0x1234abcd      /* Magic # to recognise osh */
32 #define BCM_MEM_FILENAME_LEN    24      /* Mem. filename length */
33
34 typedef struct bcm_mem_link
35 {
36   struct bcm_mem_link *prev;
37   struct bcm_mem_link *next;
38   uint size;
39   int line;
40   char file[BCM_MEM_FILENAME_LEN];
41 } bcm_mem_link_t;
42
43 #if 0
44 struct osl_info
45 {
46   osl_pubinfo_t pub;
47   uint magic;
48   void *pdev;
49   uint malloced;
50   uint failed;
51   uint bustype;
52   bcm_mem_link_t *dbgmem_list;
53 #ifdef BCMDBG_PKT               /* pkt logging for debugging */
54   pktlist_info_t pktlist;
55 #endif                          /* BCMDBG_PKT */
56 };
57 #endif
58
59 static int16 linuxbcmerrormap[] = { 0,  /* 0 */
60   -EINVAL,                      /* BCME_ERROR */
61   -EINVAL,                      /* BCME_BADARG */
62   -EINVAL,                      /* BCME_BADOPTION */
63   -EINVAL,                      /* BCME_NOTUP */
64   -EINVAL,                      /* BCME_NOTDOWN */
65   -EINVAL,                      /* BCME_NOTAP */
66   -EINVAL,                      /* BCME_NOTSTA */
67   -EINVAL,                      /* BCME_BADKEYIDX */
68   -EINVAL,                      /* BCME_RADIOOFF */
69   -EINVAL,                      /* BCME_NOTBANDLOCKED */
70   -EINVAL,                      /* BCME_NOCLK */
71   -EINVAL,                      /* BCME_BADRATESET */
72   -EINVAL,                      /* BCME_BADBAND */
73   -E2BIG,                       /* BCME_BUFTOOSHORT */
74   -E2BIG,                       /* BCME_BUFTOOLONG */
75   -EBUSY,                       /* BCME_BUSY */
76   -EINVAL,                      /* BCME_NOTASSOCIATED */
77   -EINVAL,                      /* BCME_BADSSIDLEN */
78   -EINVAL,                      /* BCME_OUTOFRANGECHAN */
79   -EINVAL,                      /* BCME_BADCHAN */
80   -EFAULT,                      /* BCME_BADADDR */
81   -ENOMEM,                      /* BCME_NORESOURCE */
82   -EOPNOTSUPP,                  /* BCME_UNSUPPORTED */
83   -EMSGSIZE,                    /* BCME_BADLENGTH */
84   -EINVAL,                      /* BCME_NOTREADY */
85   -EPERM,                       /* BCME_NOTPERMITTED */
86   -ENOMEM,                      /* BCME_NOMEM */
87   -EINVAL,                      /* BCME_ASSOCIATED */
88   -ERANGE,                      /* BCME_RANGE */
89   -EINVAL,                      /* BCME_NOTFOUND */
90   -EINVAL,                      /* BCME_WME_NOT_ENABLED */
91   -EINVAL,                      /* BCME_TSPEC_NOTFOUND */
92   -EINVAL,                      /* BCME_ACM_NOTSUPPORTED */
93   -EINVAL,                      /* BCME_NOT_WME_ASSOCIATION */
94   -EIO,                         /* BCME_SDIO_ERROR */
95   -ENODEV,                      /* BCME_DONGLE_DOWN */
96   -EINVAL                       /* BCME_VERSION */
97 /* When an new error code is added to bcmutils.h, add os 
98  * spcecific error translation here as well
99  */
100 /* check if BCME_LAST changed since the last time this function was updated */
101 #if BCME_LAST != -37
102 #error "You need to add a OS error translation in the linuxbcmerrormap \
103         for new error code defined in bcmuitls.h"
104 #endif /* BCME_LAST != -37 */
105 };
106
107 /* translate bcmerrors into linux errors */
108 int
109 osl_error (int bcmerror)
110 {
111   if (bcmerror > 0)
112     bcmerror = 0;
113   else if (bcmerror < BCME_LAST)
114     bcmerror = BCME_ERROR;
115
116   /* Array bounds covered by ASSERT in osl_attach */
117   return linuxbcmerrormap[-bcmerror];
118 }
119
120 osl_t *
121 osl_attach (void *pdev, uint bustype, bool pkttag)
122 {
123   osl_t *osh;
124
125   osh = kmalloc (sizeof (osl_t), GFP_ATOMIC);
126   ASSERT (osh);
127
128   bzero (osh, sizeof (osl_t));
129
130   /* Check that error map has the right number of entries in it */
131   ASSERT (ABS (BCME_LAST) == (ARRAYSIZE (linuxbcmerrormap) - 1));
132
133   osh->magic = OS_HANDLE_MAGIC;
134   osh->malloced = 0;
135   osh->failed = 0;
136   osh->dbgmem_list = NULL;
137   osh->pdev = pdev;
138   osh->pub.pkttag = pkttag;
139   osh->bustype = bustype;
140
141   switch (bustype)
142     {
143     case PCI_BUS:
144     case SB_BUS:
145     case PCMCIA_BUS:
146       osh->pub.mmbus = TRUE;
147       break;
148     case JTAG_BUS:
149     case SDIO_BUS:
150       break;
151     default:
152       ASSERT (FALSE);
153       break;
154     }
155
156 #ifdef BCMDBG
157   if (pkttag)
158     {
159       struct sk_buff *skb;
160       ASSERT (OSL_PKTTAG_SZ <= sizeof (skb->cb));
161     }
162 #endif
163   return osh;
164 }
165
166 void
167 osl_detach (osl_t * osh)
168 {
169   if (osh == NULL)
170     return;
171
172   ASSERT (osh->magic == OS_HANDLE_MAGIC);
173   kfree (osh);
174 }
175
176 /* Return a new packet. zero out pkttag */
177 void *
178 osl_pktget (osl_t * osh, uint len)
179 {
180   struct sk_buff *skb;
181
182   if ((skb = dev_alloc_skb (len)))
183     {
184       skb_put (skb, len);
185       skb->priority = 0;
186
187 #ifdef BCMDBG_PKT
188       pktlist_add (&(osh->pktlist), (void *) skb);
189 #endif /* BCMDBG_PKT */
190
191       osh->pub.pktalloced++;
192     }
193
194   return ((void *) skb);
195 }
196
197 /* Free the driver packet. Free the tag if present */
198 void
199 osl_pktfree (osl_t * osh, void *p, bool send)
200 {
201   struct sk_buff *skb, *nskb;
202
203   skb = (struct sk_buff *) p;
204
205   if (send && osh->pub.tx_fn)
206     osh->pub.tx_fn (osh->pub.tx_ctx, p, 0);
207
208   /* perversion: we use skb->next to chain multi-skb packets */
209   while (skb)
210     {
211       nskb = skb->next;
212       skb->next = NULL;
213
214 #ifdef BCMDBG_PKT
215       pktlist_remove (&(osh->pktlist), (void *) skb);
216 #endif /* BCMDBG_PKT */
217
218       if (skb->destructor)
219         {
220           /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if destructor exists
221            */
222           dev_kfree_skb_any (skb);
223         }
224       else
225         {
226           /* can free immediately (even in_irq()) if destructor does not exist */
227           dev_kfree_skb (skb);
228         }
229
230       osh->pub.pktalloced--;
231
232       skb = nskb;
233     }
234 }
235
236 uint32
237 osl_pci_read_config (osl_t * osh, uint offset, uint size)
238 {
239   uint val;
240   uint retry = PCI_CFG_RETRY;
241
242   ASSERT ((osh && (osh->magic == OS_HANDLE_MAGIC)));
243
244   /* only 4byte access supported */
245   ASSERT (size == 4);
246
247   do
248     {
249       pci_read_config_dword (osh->pdev, offset, &val);
250       if (val != 0xffffffff)
251         break;
252     }
253   while (retry--);
254
255 #ifdef BCMDBG
256   if (retry < PCI_CFG_RETRY)
257     printk ("PCI CONFIG READ access to %d required %d retries\n", offset,
258             (PCI_CFG_RETRY - retry));
259 #endif /* BCMDBG */
260
261   return (val);
262 }
263
264 void
265 osl_pci_write_config (osl_t * osh, uint offset, uint size, uint val)
266 {
267   uint retry = PCI_CFG_RETRY;
268
269   ASSERT ((osh && (osh->magic == OS_HANDLE_MAGIC)));
270
271   /* only 4byte access supported */
272   ASSERT (size == 4);
273
274   do
275     {
276       pci_write_config_dword (osh->pdev, offset, val);
277       if (offset != PCI_BAR0_WIN)
278         break;
279       if (osl_pci_read_config (osh, offset, size) == val)
280         break;
281     }
282   while (retry--);
283
284 #ifdef BCMDBG
285   if (retry < PCI_CFG_RETRY)
286     printk ("PCI CONFIG WRITE access to %d required %d retries\n", offset,
287             (PCI_CFG_RETRY - retry));
288 #endif /* BCMDBG */
289 }
290
291 /* return bus # for the pci device pointed by osh->pdev */
292 uint
293 osl_pci_bus (osl_t * osh)
294 {
295   ASSERT (osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev);
296
297   return ((struct pci_dev *) osh->pdev)->bus->number;
298 }
299
300 /* return slot # for the pci device pointed by osh->pdev */
301 uint
302 osl_pci_slot (osl_t * osh)
303 {
304   ASSERT (osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev);
305
306   return PCI_SLOT (((struct pci_dev *) osh->pdev)->devfn);
307 }
308
309 static void
310 osl_pcmcia_attr (osl_t * osh, uint offset, char *buf, int size, bool write)
311 {
312 }
313
314 void
315 osl_pcmcia_read_attr (osl_t * osh, uint offset, void *buf, int size)
316 {
317   osl_pcmcia_attr (osh, offset, (char *) buf, size, FALSE);
318 }
319
320 void
321 osl_pcmcia_write_attr (osl_t * osh, uint offset, void *buf, int size)
322 {
323   osl_pcmcia_attr (osh, offset, (char *) buf, size, TRUE);
324 }
325
326
327 #ifdef BCMDBG_MEM
328
329 void *
330 osl_debug_malloc (osl_t * osh, uint size, int line, char *file)
331 {
332   bcm_mem_link_t *p;
333   char *basename;
334
335   ASSERT (size);
336
337   if ((p =
338        (bcm_mem_link_t *) osl_malloc (osh,
339                                       sizeof (bcm_mem_link_t) + size)) ==
340       NULL)
341     return (NULL);
342
343   p->size = size;
344   p->line = line;
345
346   basename = strrchr (file, '/');
347   /* skip the '/' */
348   if (basename)
349     basename++;
350
351   if (!basename)
352     basename = file;
353
354   strncpy (p->file, basename, BCM_MEM_FILENAME_LEN);
355   p->file[BCM_MEM_FILENAME_LEN - 1] = '\0';
356
357   /* link this block */
358   p->prev = NULL;
359   p->next = osh->dbgmem_list;
360   if (p->next)
361     p->next->prev = p;
362   osh->dbgmem_list = p;
363
364   return p + 1;
365 }
366
367 void
368 osl_debug_mfree (osl_t * osh, void *addr, uint size, int line, char *file)
369 {
370   bcm_mem_link_t *p =
371     (bcm_mem_link_t *) ((int8 *) addr - sizeof (bcm_mem_link_t));
372
373   ASSERT ((osh && (osh->magic == OS_HANDLE_MAGIC)));
374
375   if (p->size == 0)
376     {
377       printk
378         ("osl_debug_mfree: double free on addr %p size %d at line %d file %s\n",
379          addr, size, line, file);
380       ASSERT (p->size);
381       return;
382     }
383
384   if (p->size != size)
385     {
386       printk
387         ("osl_debug_mfree: dealloc size %d does not match alloc size %d on addr %p"
388          " at line %d file %s\n", size, p->size, addr, line, file);
389       ASSERT (p->size == size);
390       return;
391     }
392
393   /* unlink this block */
394   if (p->prev)
395     p->prev->next = p->next;
396   if (p->next)
397     p->next->prev = p->prev;
398   if (osh->dbgmem_list == p)
399     osh->dbgmem_list = p->next;
400   p->next = p->prev = NULL;
401
402   osl_mfree (osh, p, size + sizeof (bcm_mem_link_t));
403 }
404
405 int
406 osl_debug_memdump (osl_t * osh, struct bcmstrbuf *b)
407 {
408   bcm_mem_link_t *p;
409
410   ASSERT ((osh && (osh->magic == OS_HANDLE_MAGIC)));
411
412   bcm_bprintf (b, "   Address\tSize\tFile:line\n");
413   for (p = osh->dbgmem_list; p; p = p->next)
414     bcm_bprintf (b, "0x%08x\t%5d\t%s:%d\n",
415                  (uintptr) p + sizeof (bcm_mem_link_t), p->size, p->file,
416                  p->line);
417
418   return 0;
419 }
420
421 #endif /* BCMDBG_MEM */
422
423 void *
424 osl_malloc (osl_t * osh, uint size)
425 {
426   void *addr;
427
428   /* only ASSERT if osh is defined */
429   if (osh)
430     ASSERT (osh->magic == OS_HANDLE_MAGIC);
431
432   if ((addr = kmalloc (size, GFP_ATOMIC)) == NULL)
433     {
434       if (osh)
435         osh->failed++;
436       return (NULL);
437     }
438   if (osh)
439     osh->malloced += size;
440
441   return (addr);
442 }
443
444 void
445 osl_mfree (osl_t * osh, void *addr, uint size)
446 {
447   if (osh)
448     {
449       ASSERT (osh->magic == OS_HANDLE_MAGIC);
450       osh->malloced -= size;
451     }
452   kfree (addr);
453 }
454
455 uint
456 osl_malloced (osl_t * osh)
457 {
458   ASSERT ((osh && (osh->magic == OS_HANDLE_MAGIC)));
459   return (osh->malloced);
460 }
461
462 uint
463 osl_malloc_failed (osl_t * osh)
464 {
465   ASSERT ((osh && (osh->magic == OS_HANDLE_MAGIC)));
466   return (osh->failed);
467 }
468
469 void *
470 osl_dma_alloc_consistent (osl_t * osh, uint size, ulong * pap)
471 {
472   ASSERT ((osh && (osh->magic == OS_HANDLE_MAGIC)));
473
474   return (pci_alloc_consistent (osh->pdev, size, (dma_addr_t *) pap));
475 }
476
477 void
478 osl_dma_free_consistent (osl_t * osh, void *va, uint size, ulong pa)
479 {
480   ASSERT ((osh && (osh->magic == OS_HANDLE_MAGIC)));
481
482   pci_free_consistent (osh->pdev, size, va, (dma_addr_t) pa);
483 }
484
485 uint
486 osl_dma_map (osl_t * osh, void *va, uint size, int direction)
487 {
488   int dir;
489
490   ASSERT ((osh && (osh->magic == OS_HANDLE_MAGIC)));
491   dir = (direction == DMA_TX) ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE;
492   return (pci_map_single (osh->pdev, va, size, dir));
493 }
494
495 void
496 osl_dma_unmap (osl_t * osh, uint pa, uint size, int direction)
497 {
498   int dir;
499
500   ASSERT ((osh && (osh->magic == OS_HANDLE_MAGIC)));
501   dir = (direction == DMA_TX) ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE;
502   pci_unmap_single (osh->pdev, (uint32) pa, size, dir);
503 }
504
505 #if defined(BINOSL) || defined(BCMDBG_ASSERT)
506 void
507 osl_assert (char *exp, char *file, int line)
508 {
509   char tempbuf[255];
510
511   sprintf (tempbuf, "assertion \"%s\" failed: file \"%s\", line %d\n", exp,
512            file, line);
513   panic (tempbuf);
514 }
515 #endif /* BCMDBG_ASSERT || BINOSL */
516
517 void
518 osl_delay (uint usec)
519 {
520   uint d;
521
522   while (usec > 0)
523     {
524       d = MIN (usec, 1000);
525       udelay (d);
526       usec -= d;
527     }
528 }
529
530 /* Clone a packet.
531  * The pkttag contents are NOT cloned.
532  */
533 void *
534 osl_pktdup (osl_t * osh, void *skb)
535 {
536   void *p;
537
538   if ((p = skb_clone ((struct sk_buff *) skb, GFP_ATOMIC)) == NULL)
539     return NULL;
540
541   /* skb_clone copies skb->cb.. we don't want that */
542   if (osh->pub.pkttag)
543     bzero ((void *) ((struct sk_buff *) p)->cb, OSL_PKTTAG_SZ);
544
545   /* Increment the packet counter */
546   osh->pub.pktalloced++;
547 #ifdef BCMDBG_PKT
548   pktlist_add (&(osh->pktlist), (void *) p);
549 #endif /* BCMDBG_PKT */
550   return (p);
551 }
552
553 uint
554 osl_pktalloced (osl_t * osh)
555 {
556   return (osh->pub.pktalloced);
557 }
558
559 #ifdef BCMDBG_PKT
560 char *
561 osl_pktlist_dump (osl_t * osh, char *buf)
562 {
563   pktlist_dump (&(osh->pktlist), buf);
564   return buf;
565 }
566
567 void
568 osl_pktlist_add (osl_t * osh, void *p)
569 {
570   pktlist_add (&(osh->pktlist), p);
571 }
572
573 void
574 osl_pktlist_remove (osl_t * osh, void *p)
575 {
576   pktlist_remove (&(osh->pktlist), p);
577 }
578 #endif /* BCMDBG_PKT */
579
580 /*
581  * BINOSL selects the slightly slower function-call-based binary compatible osl.
582  */
583 #ifdef BINOSL
584
585 int
586 osl_printf (const char *format, ...)
587 {
588   va_list args;
589   char buf[1024];
590   int len;
591
592   /* sprintf into a local buffer because there *is* no "vprintk()".. */
593   va_start (args, format);
594   len = vsnprintf (buf, 1024, format, args);
595   va_end (args);
596
597   if (len > sizeof (buf))
598     {
599       printk ("osl_printf: buffer overrun\n");
600       return (0);
601     }
602
603   return (printk (buf));
604 }
605
606 int
607 osl_sprintf (char *buf, const char *format, ...)
608 {
609   va_list args;
610   int rc;
611
612   va_start (args, format);
613   rc = vsprintf (buf, format, args);
614   va_end (args);
615   return (rc);
616 }
617
618 int
619 osl_strcmp (const char *s1, const char *s2)
620 {
621   return (strcmp (s1, s2));
622 }
623
624 int
625 osl_strncmp (const char *s1, const char *s2, uint n)
626 {
627   return (strncmp (s1, s2, n));
628 }
629
630 int
631 osl_strlen (const char *s)
632 {
633   return (strlen (s));
634 }
635
636 char *
637 osl_strcpy (char *d, const char *s)
638 {
639   return (strcpy (d, s));
640 }
641
642 char *
643 osl_strncpy (char *d, const char *s, uint n)
644 {
645   return (strncpy (d, s, n));
646 }
647
648 void
649 bcopy (const void *src, void *dst, int len)
650 {
651   memcpy (dst, src, len);
652 }
653
654 int
655 bcmp (const void *b1, const void *b2, int len)
656 {
657   return (memcmp (b1, b2, len));
658 }
659
660 void
661 bzero (void *b, int len)
662 {
663   memset (b, '\0', len);
664 }
665
666 uint32
667 osl_readl (volatile uint32 * r)
668 {
669   return (readl (r));
670 }
671
672 uint16
673 osl_readw (volatile uint16 * r)
674 {
675   return (readw (r));
676 }
677
678 uint8
679 osl_readb (volatile uint8 * r)
680 {
681   return (readb (r));
682 }
683
684 void
685 osl_writel (uint32 v, volatile uint32 * r)
686 {
687   writel (v, r);
688 }
689
690 void
691 osl_writew (uint16 v, volatile uint16 * r)
692 {
693   writew (v, r);
694 }
695
696 void
697 osl_writeb (uint8 v, volatile uint8 * r)
698 {
699   writeb (v, r);
700 }
701
702 void *
703 osl_uncached (void *va)
704 {
705 #ifdef mips
706   return ((void *) KSEG1ADDR (va));
707 #else
708   return ((void *) va);
709 #endif /* mips */
710 }
711
712 uint
713 osl_getcycles (void)
714 {
715   uint cycles;
716
717 #if defined(mips)
718   cycles = read_c0_count () * 2;
719 #elif defined(__i386__)
720   rdtscl (cycles);
721 #else
722   cycles = 0;
723 #endif /* defined(mips) */
724   return cycles;
725 }
726
727 void *
728 osl_reg_map (uint32 pa, uint size)
729 {
730   return (ioremap_nocache ((unsigned long) pa, (unsigned long) size));
731 }
732
733 void
734 osl_reg_unmap (void *va)
735 {
736   iounmap (va);
737 }
738
739 int
740 osl_busprobe (uint32 * val, uint32 addr)
741 {
742 #ifdef mips
743   return get_dbe (*val, (uint32 *) addr);
744 #else
745   *val = readl ((uint32 *) (uintptr) addr);
746   return 0;
747 #endif /* mips */
748 }
749
750 bool
751 osl_pktshared (void *skb)
752 {
753   return (((struct sk_buff *) skb)->cloned);
754 }
755
756 uchar *
757 osl_pktdata (osl_t * osh, void *skb)
758 {
759   return (((struct sk_buff *) skb)->data);
760 }
761
762 uint
763 osl_pktlen (osl_t * osh, void *skb)
764 {
765   return (((struct sk_buff *) skb)->len);
766 }
767
768 uint
769 osl_pktheadroom (osl_t * osh, void *skb)
770 {
771   return (uint) skb_headroom ((struct sk_buff *) skb);
772 }
773
774 uint
775 osl_pkttailroom (osl_t * osh, void *skb)
776 {
777   return (uint) skb_tailroom ((struct sk_buff *) skb);
778 }
779
780 void *
781 osl_pktnext (osl_t * osh, void *skb)
782 {
783   return (((struct sk_buff *) skb)->next);
784 }
785
786 void
787 osl_pktsetnext (void *skb, void *x)
788 {
789   ((struct sk_buff *) skb)->next = (struct sk_buff *) x;
790 }
791
792 void
793 osl_pktsetlen (osl_t * osh, void *skb, uint len)
794 {
795   __skb_trim ((struct sk_buff *) skb, len);
796 }
797
798 uchar *
799 osl_pktpush (osl_t * osh, void *skb, int bytes)
800 {
801   return (skb_push ((struct sk_buff *) skb, bytes));
802 }
803
804 uchar *
805 osl_pktpull (osl_t * osh, void *skb, int bytes)
806 {
807   return (skb_pull ((struct sk_buff *) skb, bytes));
808 }
809
810 void *
811 osl_pkttag (void *skb)
812 {
813   return ((void *) (((struct sk_buff *) skb)->cb));
814 }
815
816 void *
817 osl_pktlink (void *skb)
818 {
819   return (((struct sk_buff *) skb)->prev);
820 }
821
822 void
823 osl_pktsetlink (void *skb, void *x)
824 {
825   ((struct sk_buff *) skb)->prev = (struct sk_buff *) x;
826 }
827
828 uint
829 osl_pktprio (void *skb)
830 {
831   return (((struct sk_buff *) skb)->priority);
832 }
833
834 void
835 osl_pktsetprio (void *skb, uint x)
836 {
837   ((struct sk_buff *) skb)->priority = x;
838 }
839
840 /* Convert a driver packet to native(OS) packet
841  * In the process, packettag is zeroed out before sending up
842  * IP code depends on skb->cb to be setup correctly with various options
843  * In our case, that means it should be 0
844  */
845 struct sk_buff *
846 osl_pkt_tonative (osl_t * osh, void *pkt)
847 {
848   struct sk_buff *nskb;
849
850   if (osh->pub.pkttag)
851     bzero ((void *) ((struct sk_buff *) pkt)->cb, OSL_PKTTAG_SZ);
852
853   /* Decrement the packet counter */
854   for (nskb = (struct sk_buff *) pkt; nskb; nskb = nskb->next)
855     {
856 #ifdef BCMDBG_PKT
857       pktlist_remove (&(osh->pktlist), (void *) nskb);
858 #endif /* BCMDBG_PKT */
859       osh->pub.pktalloced--;
860     }
861
862   return (struct sk_buff *) pkt;
863 }
864
865 /* Convert a native(OS) packet to driver packet.
866  * In the process, native packet is destroyed, there is no copying
867  * Also, a packettag is zeroed out
868  */
869 void *
870 osl_pkt_frmnative (osl_t * osh, struct sk_buff *skb)
871 {
872   struct sk_buff *nskb;
873
874   if (osh->pub.pkttag)
875     bzero ((void *) skb->cb, OSL_PKTTAG_SZ);
876
877   /* Increment the packet counter */
878   for (nskb = skb; nskb; nskb = nskb->next)
879     {
880 #ifdef BCMDBG_PKT
881       pktlist_add (&(osh->pktlist), (void *) nskb);
882 #endif /* BCMDBG_PKT */
883       osh->pub.pktalloced++;
884     }
885
886   return (void *) skb;
887 }
888
889 #endif /* BINOSL */