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