Root/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
34typedef 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
44struct 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
59static 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 */
108int
109osl_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
120osl_t *
121osl_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
166void
167osl_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 */
177void *
178osl_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 */
198void
199osl_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
236uint32
237osl_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
264void
265osl_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 */
292uint
293osl_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 */
301uint
302osl_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
309static void
310osl_pcmcia_attr (osl_t * osh, uint offset, char *buf, int size, bool write)
311{
312}
313
314void
315osl_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
320void
321osl_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
329void *
330osl_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
367void
368osl_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
405int
406osl_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
423void *
424osl_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
444void
445osl_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
455uint
456osl_malloced (osl_t * osh)
457{
458  ASSERT ((osh && (osh->magic == OS_HANDLE_MAGIC)));
459  return (osh->malloced);
460}
461
462uint
463osl_malloc_failed (osl_t * osh)
464{
465  ASSERT ((osh && (osh->magic == OS_HANDLE_MAGIC)));
466  return (osh->failed);
467}
468
469void *
470osl_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
477void
478osl_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
485uint
486osl_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
495void
496osl_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)
506void
507osl_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
517void
518osl_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 */
533void *
534osl_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
553uint
554osl_pktalloced (osl_t * osh)
555{
556  return (osh->pub.pktalloced);
557}
558
559#ifdef BCMDBG_PKT
560char *
561osl_pktlist_dump (osl_t * osh, char *buf)
562{
563  pktlist_dump (&(osh->pktlist), buf);
564  return buf;
565}
566
567void
568osl_pktlist_add (osl_t * osh, void *p)
569{
570  pktlist_add (&(osh->pktlist), p);
571}
572
573void
574osl_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
585int
586osl_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
606int
607osl_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
618int
619osl_strcmp (const char *s1, const char *s2)
620{
621  return (strcmp (s1, s2));
622}
623
624int
625osl_strncmp (const char *s1, const char *s2, uint n)
626{
627  return (strncmp (s1, s2, n));
628}
629
630int
631osl_strlen (const char *s)
632{
633  return (strlen (s));
634}
635
636char *
637osl_strcpy (char *d, const char *s)
638{
639  return (strcpy (d, s));
640}
641
642char *
643osl_strncpy (char *d, const char *s, uint n)
644{
645  return (strncpy (d, s, n));
646}
647
648void
649bcopy (const void *src, void *dst, int len)
650{
651  memcpy (dst, src, len);
652}
653
654int
655bcmp (const void *b1, const void *b2, int len)
656{
657  return (memcmp (b1, b2, len));
658}
659
660void
661bzero (void *b, int len)
662{
663  memset (b, '\0', len);
664}
665
666uint32
667osl_readl (volatile uint32 * r)
668{
669  return (readl (r));
670}
671
672uint16
673osl_readw (volatile uint16 * r)
674{
675  return (readw (r));
676}
677
678uint8
679osl_readb (volatile uint8 * r)
680{
681  return (readb (r));
682}
683
684void
685osl_writel (uint32 v, volatile uint32 * r)
686{
687  writel (v, r);
688}
689
690void
691osl_writew (uint16 v, volatile uint16 * r)
692{
693  writew (v, r);
694}
695
696void
697osl_writeb (uint8 v, volatile uint8 * r)
698{
699  writeb (v, r);
700}
701
702void *
703osl_uncached (void *va)
704{
705#ifdef mips
706  return ((void *) KSEG1ADDR (va));
707#else
708  return ((void *) va);
709#endif /* mips */
710}
711
712uint
713osl_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
727void *
728osl_reg_map (uint32 pa, uint size)
729{
730  return (ioremap_nocache ((unsigned long) pa, (unsigned long) size));
731}
732
733void
734osl_reg_unmap (void *va)
735{
736  iounmap (va);
737}
738
739int
740osl_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
750bool
751osl_pktshared (void *skb)
752{
753  return (((struct sk_buff *) skb)->cloned);
754}
755
756uchar *
757osl_pktdata (osl_t * osh, void *skb)
758{
759  return (((struct sk_buff *) skb)->data);
760}
761
762uint
763osl_pktlen (osl_t * osh, void *skb)
764{
765  return (((struct sk_buff *) skb)->len);
766}
767
768uint
769osl_pktheadroom (osl_t * osh, void *skb)
770{
771  return (uint) skb_headroom ((struct sk_buff *) skb);
772}
773
774uint
775osl_pkttailroom (osl_t * osh, void *skb)
776{
777  return (uint) skb_tailroom ((struct sk_buff *) skb);
778}
779
780void *
781osl_pktnext (osl_t * osh, void *skb)
782{
783  return (((struct sk_buff *) skb)->next);
784}
785
786void
787osl_pktsetnext (void *skb, void *x)
788{
789  ((struct sk_buff *) skb)->next = (struct sk_buff *) x;
790}
791
792void
793osl_pktsetlen (osl_t * osh, void *skb, uint len)
794{
795  __skb_trim ((struct sk_buff *) skb, len);
796}
797
798uchar *
799osl_pktpush (osl_t * osh, void *skb, int bytes)
800{
801  return (skb_push ((struct sk_buff *) skb, bytes));
802}
803
804uchar *
805osl_pktpull (osl_t * osh, void *skb, int bytes)
806{
807  return (skb_pull ((struct sk_buff *) skb, bytes));
808}
809
810void *
811osl_pkttag (void *skb)
812{
813  return ((void *) (((struct sk_buff *) skb)->cb));
814}
815
816void *
817osl_pktlink (void *skb)
818{
819  return (((struct sk_buff *) skb)->prev);
820}
821
822void
823osl_pktsetlink (void *skb, void *x)
824{
825  ((struct sk_buff *) skb)->prev = (struct sk_buff *) x;
826}
827
828uint
829osl_pktprio (void *skb)
830{
831  return (((struct sk_buff *) skb)->priority);
832}
833
834void
835osl_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 */
845struct sk_buff *
846osl_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 */
869void *
870osl_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 */
890

Archive Download this file



interactive