aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/bcmdhd/linux_osl.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
commitfcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch)
treea57612d1888735a2ec7972891b68c1ac5ec8faea /drivers/net/wireless/bcmdhd/linux_osl.c
parent8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff)
Added missing tegra files.HEADmaster
Diffstat (limited to 'drivers/net/wireless/bcmdhd/linux_osl.c')
-rw-r--r--drivers/net/wireless/bcmdhd/linux_osl.c919
1 files changed, 919 insertions, 0 deletions
diff --git a/drivers/net/wireless/bcmdhd/linux_osl.c b/drivers/net/wireless/bcmdhd/linux_osl.c
new file mode 100644
index 00000000000..1a544378c1e
--- /dev/null
+++ b/drivers/net/wireless/bcmdhd/linux_osl.c
@@ -0,0 +1,919 @@
1/*
2 * Linux OS Independent Layer
3 *
4 * Copyright (C) 1999-2011, Broadcom Corporation
5 *
6 * Unless you and Broadcom execute a separate written software license
7 * agreement governing use of this software, this software is licensed to you
8 * under the terms of the GNU General Public License version 2 (the "GPL"),
9 * available at http://www.broadcom.com/licenses/GPLv2.php, with the
10 * following added to such license:
11 *
12 * As a special exception, the copyright holders of this software give you
13 * permission to link this software with independent modules, and to copy and
14 * distribute the resulting executable under terms of your choice, provided that
15 * you also meet, for each linked independent module, the terms and conditions of
16 * the license of that module. An independent module is a module which is not
17 * derived from this software. The special exception does not apply to any
18 * modifications of the software.
19 *
20 * Notwithstanding the above, under no circumstances may you combine this
21 * software in any way with any other Broadcom software provided under a license
22 * other than the GPL, without Broadcom's express prior written consent.
23 *
24 * $Id: linux_osl.c,v 1.168.2.7 2011-01-27 17:01:13 Exp $
25 */
26
27
28#define LINUX_PORT
29
30#include <typedefs.h>
31#include <bcmendian.h>
32#include <linuxver.h>
33#include <bcmdefs.h>
34#include <osl.h>
35#include <bcmutils.h>
36#include <linux/delay.h>
37#include <pcicfg.h>
38
39#ifdef BCMASSERT_LOG
40#include <bcm_assert_log.h>
41#endif
42
43#include <linux/fs.h>
44
45#define PCI_CFG_RETRY 10
46
47#define OS_HANDLE_MAGIC 0x1234abcd
48#define BCM_MEM_FILENAME_LEN 24
49
50#ifdef DHD_USE_STATIC_BUF
51#define STATIC_BUF_MAX_NUM 16
52#define STATIC_BUF_SIZE (PAGE_SIZE * 2)
53#define STATIC_BUF_TOTAL_LEN (STATIC_BUF_MAX_NUM * STATIC_BUF_SIZE)
54
55typedef struct bcm_static_buf {
56 struct semaphore static_sem;
57 unsigned char *buf_ptr;
58 unsigned char buf_use[STATIC_BUF_MAX_NUM];
59} bcm_static_buf_t;
60
61static bcm_static_buf_t *bcm_static_buf = 0;
62
63#define STATIC_PKT_MAX_NUM 8
64
65typedef struct bcm_static_pkt {
66 struct sk_buff *skb_4k[STATIC_PKT_MAX_NUM];
67 struct sk_buff *skb_8k[STATIC_PKT_MAX_NUM];
68 struct semaphore osl_pkt_sem;
69 unsigned char pkt_use[STATIC_PKT_MAX_NUM * 2];
70} bcm_static_pkt_t;
71
72static bcm_static_pkt_t *bcm_static_skb = 0;
73#endif
74
75typedef struct bcm_mem_link {
76 struct bcm_mem_link *prev;
77 struct bcm_mem_link *next;
78 uint size;
79 int line;
80 char file[BCM_MEM_FILENAME_LEN];
81} bcm_mem_link_t;
82
83struct osl_info {
84 osl_pubinfo_t pub;
85#ifdef CTFPOOL
86 ctfpool_t *ctfpool;
87#endif
88 uint magic;
89 void *pdev;
90 atomic_t malloced;
91 uint failed;
92 uint bustype;
93 bcm_mem_link_t *dbgmem_list;
94};
95
96
97
98
99uint32 g_assert_type = FALSE;
100
101static int16 linuxbcmerrormap[] =
102{ 0,
103 -EINVAL,
104 -EINVAL,
105 -EINVAL,
106 -EINVAL,
107 -EINVAL,
108 -EINVAL,
109 -EINVAL,
110 -EINVAL,
111 -EINVAL,
112 -EINVAL,
113 -EINVAL,
114 -EINVAL,
115 -EINVAL,
116 -E2BIG,
117 -E2BIG,
118 -EBUSY,
119 -EINVAL,
120 -EINVAL,
121 -EINVAL,
122 -EINVAL,
123 -EFAULT,
124 -ENOMEM,
125 -EOPNOTSUPP,
126 -EMSGSIZE,
127 -EINVAL,
128 -EPERM,
129 -ENOMEM,
130 -EINVAL,
131 -ERANGE,
132 -EINVAL,
133 -EINVAL,
134 -EINVAL,
135 -EINVAL,
136 -EINVAL,
137 -EIO,
138 -ENODEV,
139 -EINVAL,
140 -EIO,
141 -EIO,
142 -ENODEV,
143 -EINVAL,
144 -ENODATA,
145
146
147
148#if BCME_LAST != -42
149#error "You need to add a OS error translation in the linuxbcmerrormap \
150 for new error code defined in bcmutils.h"
151#endif
152};
153
154
155int
156osl_error(int bcmerror)
157{
158 if (bcmerror > 0)
159 bcmerror = 0;
160 else if (bcmerror < BCME_LAST)
161 bcmerror = BCME_ERROR;
162
163
164 return linuxbcmerrormap[-bcmerror];
165}
166
167extern uint8* dhd_os_prealloc(void *osh, int section, int size);
168
169osl_t *
170osl_attach(void *pdev, uint bustype, bool pkttag)
171{
172 osl_t *osh;
173#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
174 gfp_t flags;
175
176 flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL;
177 osh = kmalloc(sizeof(osl_t), flags);
178#else
179 osh = kmalloc(sizeof(osl_t), GFP_ATOMIC);
180#endif
181 ASSERT(osh);
182
183 bzero(osh, sizeof(osl_t));
184
185
186 ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(linuxbcmerrormap) - 1));
187
188 osh->magic = OS_HANDLE_MAGIC;
189 atomic_set(&osh->malloced, 0);
190 osh->failed = 0;
191 osh->dbgmem_list = NULL;
192 osh->pdev = pdev;
193 osh->pub.pkttag = pkttag;
194 osh->bustype = bustype;
195
196 switch (bustype) {
197 case PCI_BUS:
198 case SI_BUS:
199 case PCMCIA_BUS:
200 osh->pub.mmbus = TRUE;
201 break;
202 case JTAG_BUS:
203 case SDIO_BUS:
204 case USB_BUS:
205 case SPI_BUS:
206 case RPC_BUS:
207 osh->pub.mmbus = FALSE;
208 break;
209 default:
210 ASSERT(FALSE);
211 break;
212 }
213
214#if defined(DHD_USE_STATIC_BUF)
215 if (!bcm_static_buf) {
216 if (!(bcm_static_buf = (bcm_static_buf_t *)dhd_os_prealloc(osh, 3, STATIC_BUF_SIZE+
217 STATIC_BUF_TOTAL_LEN))) {
218 printk("can not alloc static buf!\n");
219 }
220 else
221 printk("alloc static buf at %x!\n", (unsigned int)bcm_static_buf);
222
223
224 sema_init(&bcm_static_buf->static_sem, 1);
225
226 bcm_static_buf->buf_ptr = (unsigned char *)bcm_static_buf + STATIC_BUF_SIZE;
227 }
228
229 if (!bcm_static_skb) {
230 int i;
231 void *skb_buff_ptr = 0;
232 bcm_static_skb = (bcm_static_pkt_t *)((char *)bcm_static_buf + 2048);
233 skb_buff_ptr = dhd_os_prealloc(osh, 4, 0);
234
235 bcopy(skb_buff_ptr, bcm_static_skb, sizeof(struct sk_buff *) * 16);
236 for (i = 0; i < STATIC_PKT_MAX_NUM * 2; i++)
237 bcm_static_skb->pkt_use[i] = 0;
238
239 sema_init(&bcm_static_skb->osl_pkt_sem, 1);
240 }
241#endif
242
243 return osh;
244}
245
246void
247osl_detach(osl_t *osh)
248{
249 if (osh == NULL)
250 return;
251
252 ASSERT(osh->magic == OS_HANDLE_MAGIC);
253 kfree(osh);
254}
255
256static struct sk_buff *osl_alloc_skb(unsigned int len)
257{
258#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
259 gfp_t flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL;
260
261 return __dev_alloc_skb(len, flags);
262#else
263 return dev_alloc_skb(len);
264#endif
265}
266
267#ifdef CTFPOOL
268
269void *
270osl_ctfpool_add(osl_t *osh)
271{
272 struct sk_buff *skb;
273
274 if ((osh == NULL) || (osh->ctfpool == NULL))
275 return NULL;
276
277 spin_lock_bh(&osh->ctfpool->lock);
278 ASSERT(osh->ctfpool->curr_obj <= osh->ctfpool->max_obj);
279
280
281 if (osh->ctfpool->curr_obj == osh->ctfpool->max_obj) {
282 spin_unlock_bh(&osh->ctfpool->lock);
283 return NULL;
284 }
285
286
287 skb = osl_alloc_skb(osh->ctfpool->obj_size);
288 if (skb == NULL) {
289 printf("%s: skb alloc of len %d failed\n", __FUNCTION__,
290 osh->ctfpool->obj_size);
291 spin_unlock_bh(&osh->ctfpool->lock);
292 return NULL;
293 }
294
295
296 skb->next = (struct sk_buff *)osh->ctfpool->head;
297 osh->ctfpool->head = skb;
298 osh->ctfpool->fast_frees++;
299 osh->ctfpool->curr_obj++;
300
301
302 CTFPOOLPTR(osh, skb) = (void *)osh->ctfpool;
303
304
305 PKTFAST(osh, skb) = FASTBUF;
306
307 spin_unlock_bh(&osh->ctfpool->lock);
308
309 return skb;
310}
311
312
313void
314osl_ctfpool_replenish(osl_t *osh, uint thresh)
315{
316 if ((osh == NULL) || (osh->ctfpool == NULL))
317 return;
318
319
320 while ((osh->ctfpool->refills > 0) && (thresh--)) {
321 osl_ctfpool_add(osh);
322 osh->ctfpool->refills--;
323 }
324}
325
326
327int32
328osl_ctfpool_init(osl_t *osh, uint numobj, uint size)
329{
330#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
331 gfp_t flags;
332
333 flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL;
334 osh->ctfpool = kmalloc(sizeof(ctfpool_t), flags);
335#else
336 osh->ctfpool = kmalloc(sizeof(ctfpool_t), GFP_ATOMIC);
337#endif
338 ASSERT(osh->ctfpool);
339 bzero(osh->ctfpool, sizeof(ctfpool_t));
340
341 osh->ctfpool->max_obj = numobj;
342 osh->ctfpool->obj_size = size;
343
344 spin_lock_init(&osh->ctfpool->lock);
345
346 while (numobj--) {
347 if (!osl_ctfpool_add(osh))
348 return -1;
349 osh->ctfpool->fast_frees--;
350 }
351
352 return 0;
353}
354
355
356void
357osl_ctfpool_cleanup(osl_t *osh)
358{
359 struct sk_buff *skb, *nskb;
360
361 if ((osh == NULL) || (osh->ctfpool == NULL))
362 return;
363
364 spin_lock_bh(&osh->ctfpool->lock);
365
366 skb = osh->ctfpool->head;
367
368 while (skb != NULL) {
369 nskb = skb->next;
370 dev_kfree_skb(skb);
371 skb = nskb;
372 osh->ctfpool->curr_obj--;
373 }
374
375 ASSERT(osh->ctfpool->curr_obj == 0);
376 osh->ctfpool->head = NULL;
377 spin_unlock_bh(&osh->ctfpool->lock);
378
379 kfree(osh->ctfpool);
380 osh->ctfpool = NULL;
381}
382
383void
384osl_ctfpool_stats(osl_t *osh, void *b)
385{
386 struct bcmstrbuf *bb;
387
388 if ((osh == NULL) || (osh->ctfpool == NULL))
389 return;
390
391#ifdef DHD_USE_STATIC_BUF
392 if (bcm_static_buf) {
393 bcm_static_buf = 0;
394 }
395 if (bcm_static_skb) {
396 bcm_static_skb = 0;
397 }
398#endif
399
400 bb = b;
401
402 ASSERT((osh != NULL) && (bb != NULL));
403
404 bcm_bprintf(bb, "max_obj %d obj_size %d curr_obj %d refills %d\n",
405 osh->ctfpool->max_obj, osh->ctfpool->obj_size,
406 osh->ctfpool->curr_obj, osh->ctfpool->refills);
407 bcm_bprintf(bb, "fast_allocs %d fast_frees %d slow_allocs %d\n",
408 osh->ctfpool->fast_allocs, osh->ctfpool->fast_frees,
409 osh->ctfpool->slow_allocs);
410}
411
412static inline struct sk_buff *
413osl_pktfastget(osl_t *osh, uint len)
414{
415 struct sk_buff *skb;
416
417
418 if (osh->ctfpool == NULL)
419 return NULL;
420
421 spin_lock_bh(&osh->ctfpool->lock);
422 if (osh->ctfpool->head == NULL) {
423 ASSERT(osh->ctfpool->curr_obj == 0);
424 osh->ctfpool->slow_allocs++;
425 spin_unlock_bh(&osh->ctfpool->lock);
426 return NULL;
427 }
428
429 ASSERT(len <= osh->ctfpool->obj_size);
430
431
432 skb = (struct sk_buff *)osh->ctfpool->head;
433 osh->ctfpool->head = (void *)skb->next;
434
435 osh->ctfpool->fast_allocs++;
436 osh->ctfpool->curr_obj--;
437 ASSERT(CTFPOOLHEAD(osh, skb) == (struct sock *)osh->ctfpool->head);
438 spin_unlock_bh(&osh->ctfpool->lock);
439
440
441 skb->next = skb->prev = NULL;
442 skb->data = skb->head + 16;
443 skb->tail = skb->head + 16;
444
445 skb->len = 0;
446 skb->cloned = 0;
447#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 14)
448 skb->list = NULL;
449#endif
450 atomic_set(&skb->users, 1);
451
452 return skb;
453}
454#endif
455
456
457void * BCMFASTPATH
458osl_pktget(osl_t *osh, uint len)
459{
460 struct sk_buff *skb;
461
462#ifdef CTFPOOL
463 skb = osl_pktfastget(osh, len);
464 if ((skb != NULL) || ((skb = osl_alloc_skb(len)) != NULL)) {
465#else
466 if ((skb = osl_alloc_skb(len))) {
467#endif
468 skb_put(skb, len);
469 skb->priority = 0;
470
471 osh->pub.pktalloced++;
472 }
473
474 return ((void*) skb);
475}
476
477#ifdef CTFPOOL
478static inline void
479osl_pktfastfree(osl_t *osh, struct sk_buff *skb)
480{
481 ctfpool_t *ctfpool;
482
483 ctfpool = (ctfpool_t *)CTFPOOLPTR(osh, skb);
484 ASSERT(ctfpool != NULL);
485
486
487 spin_lock_bh(&ctfpool->lock);
488 skb->next = (struct sk_buff *)ctfpool->head;
489 ctfpool->head = (void *)skb;
490
491 ctfpool->fast_frees++;
492 ctfpool->curr_obj++;
493
494 ASSERT(ctfpool->curr_obj <= ctfpool->max_obj);
495 spin_unlock_bh(&ctfpool->lock);
496
497#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14)
498 skb->tstamp.tv.sec = 0;
499#else
500 skb->stamp.tv_sec = 0;
501#endif
502
503
504 skb->dev = NULL;
505 skb->dst = NULL;
506 memset(skb->cb, 0, sizeof(skb->cb));
507 skb->ip_summed = 0;
508 skb->destructor = NULL;
509}
510#endif
511
512
513void BCMFASTPATH
514osl_pktfree(osl_t *osh, void *p, bool send)
515{
516 struct sk_buff *skb, *nskb;
517
518 skb = (struct sk_buff*) p;
519
520 if (send && osh->pub.tx_fn)
521 osh->pub.tx_fn(osh->pub.tx_ctx, p, 0);
522
523
524 while (skb) {
525 nskb = skb->next;
526 skb->next = NULL;
527
528
529#ifdef CTFPOOL
530 if (PKTISFAST(osh, skb))
531 osl_pktfastfree(osh, skb);
532 else {
533#else
534 {
535#endif
536
537 if (skb->destructor)
538
539 dev_kfree_skb_any(skb);
540 else
541
542 dev_kfree_skb(skb);
543 }
544
545 osh->pub.pktalloced--;
546
547 skb = nskb;
548 }
549}
550
551#ifdef DHD_USE_STATIC_BUF
552void *
553osl_pktget_static(osl_t *osh, uint len)
554{
555 int i;
556 struct sk_buff *skb;
557
558 if (len > (PAGE_SIZE * 2)) {
559 printk("%s: attempt to allocate huge packet (0x%x)\n", __FUNCTION__, len);
560 return osl_pktget(osh, len);
561 }
562
563 down(&bcm_static_skb->osl_pkt_sem);
564
565 if (len <= PAGE_SIZE) {
566 for (i = 0; i < STATIC_PKT_MAX_NUM; i++) {
567 if (bcm_static_skb->pkt_use[i] == 0)
568 break;
569 }
570
571 if (i != STATIC_PKT_MAX_NUM) {
572 bcm_static_skb->pkt_use[i] = 1;
573 up(&bcm_static_skb->osl_pkt_sem);
574 skb = bcm_static_skb->skb_4k[i];
575 skb->tail = skb->data + len;
576 skb->len = len;
577 return skb;
578 }
579 }
580
581
582 for (i = 0; i < STATIC_PKT_MAX_NUM; i++) {
583 if (bcm_static_skb->pkt_use[i+STATIC_PKT_MAX_NUM] == 0)
584 break;
585 }
586
587 if (i != STATIC_PKT_MAX_NUM) {
588 bcm_static_skb->pkt_use[i+STATIC_PKT_MAX_NUM] = 1;
589 up(&bcm_static_skb->osl_pkt_sem);
590 skb = bcm_static_skb->skb_8k[i];
591 skb->tail = skb->data + len;
592 skb->len = len;
593 return skb;
594 }
595
596 up(&bcm_static_skb->osl_pkt_sem);
597 printk("%s: all static pkt in use!\n", __FUNCTION__);
598 return osl_pktget(osh, len);
599}
600
601void
602osl_pktfree_static(osl_t *osh, void *p, bool send)
603{
604 int i;
605
606 for (i = 0; i < STATIC_PKT_MAX_NUM; i++) {
607 if (p == bcm_static_skb->skb_4k[i]) {
608 down(&bcm_static_skb->osl_pkt_sem);
609 bcm_static_skb->pkt_use[i] = 0;
610 up(&bcm_static_skb->osl_pkt_sem);
611 return;
612 }
613 }
614
615 for (i = 0; i < STATIC_PKT_MAX_NUM; i++) {
616 if (p == bcm_static_skb->skb_8k[i]) {
617 down(&bcm_static_skb->osl_pkt_sem);
618 bcm_static_skb->pkt_use[i + STATIC_PKT_MAX_NUM] = 0;
619 up(&bcm_static_skb->osl_pkt_sem);
620 return;
621 }
622 }
623
624 return osl_pktfree(osh, p, send);
625}
626#endif
627
628uint32
629osl_pci_read_config(osl_t *osh, uint offset, uint size)
630{
631 uint val = 0;
632 uint retry = PCI_CFG_RETRY;
633
634 ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
635
636
637 ASSERT(size == 4);
638
639 do {
640 pci_read_config_dword(osh->pdev, offset, &val);
641 if (val != 0xffffffff)
642 break;
643 } while (retry--);
644
645
646 return (val);
647}
648
649void
650osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val)
651{
652 uint retry = PCI_CFG_RETRY;
653
654 ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
655
656
657 ASSERT(size == 4);
658
659 do {
660 pci_write_config_dword(osh->pdev, offset, val);
661 if (offset != PCI_BAR0_WIN)
662 break;
663 if (osl_pci_read_config(osh, offset, size) == val)
664 break;
665 } while (retry--);
666
667}
668
669
670uint
671osl_pci_bus(osl_t *osh)
672{
673 ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev);
674
675 return ((struct pci_dev *)osh->pdev)->bus->number;
676}
677
678
679uint
680osl_pci_slot(osl_t *osh)
681{
682 ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev);
683
684 return PCI_SLOT(((struct pci_dev *)osh->pdev)->devfn);
685}
686
687static void
688osl_pcmcia_attr(osl_t *osh, uint offset, char *buf, int size, bool write)
689{
690}
691
692void
693osl_pcmcia_read_attr(osl_t *osh, uint offset, void *buf, int size)
694{
695 osl_pcmcia_attr(osh, offset, (char *) buf, size, FALSE);
696}
697
698void
699osl_pcmcia_write_attr(osl_t *osh, uint offset, void *buf, int size)
700{
701 osl_pcmcia_attr(osh, offset, (char *) buf, size, TRUE);
702}
703
704void *
705osl_malloc(osl_t *osh, uint size)
706{
707 void *addr;
708#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
709 gfp_t flags;
710
711
712 if (osh)
713 ASSERT(osh->magic == OS_HANDLE_MAGIC);
714
715 flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL;
716 if ((addr = kmalloc(size, flags)) == NULL) {
717#else
718 if ((addr = kmalloc(size, GFP_ATOMIC)) == NULL) {
719#endif
720 if (osh)
721 osh->failed++;
722 return (NULL);
723 }
724 if (osh)
725 atomic_add(size, &osh->malloced);
726
727 return (addr);
728}
729
730void
731osl_mfree(osl_t *osh, void *addr, uint size)
732{
733 if (osh) {
734 ASSERT(osh->magic == OS_HANDLE_MAGIC);
735 atomic_sub(size, &osh->malloced);
736 }
737 kfree(addr);
738}
739
740uint
741osl_malloced(osl_t *osh)
742{
743 ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
744 return (atomic_read(&osh->malloced));
745}
746
747uint
748osl_malloc_failed(osl_t *osh)
749{
750 ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
751 return (osh->failed);
752}
753
754
755
756uint
757osl_dma_consistent_align(void)
758{
759 return (PAGE_SIZE);
760}
761
762void*
763osl_dma_alloc_consistent(osl_t *osh, uint size, uint16 align_bits, uint *alloced, ulong *pap)
764{
765 uint16 align = (1 << align_bits);
766 ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
767
768 if (!ISALIGNED(DMA_CONSISTENT_ALIGN, align))
769 size += align;
770 *alloced = size;
771
772 return (pci_alloc_consistent(osh->pdev, size, (dma_addr_t*)pap));
773}
774
775void
776osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa)
777{
778 ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
779
780 pci_free_consistent(osh->pdev, size, va, (dma_addr_t)pa);
781}
782
783uint BCMFASTPATH
784osl_dma_map(osl_t *osh, void *va, uint size, int direction)
785{
786 int dir;
787
788 ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
789 dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE;
790 return (pci_map_single(osh->pdev, va, size, dir));
791}
792
793void BCMFASTPATH
794osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction)
795{
796 int dir;
797
798 ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
799 dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE;
800 pci_unmap_single(osh->pdev, (uint32)pa, size, dir);
801}
802
803#if defined(BCMASSERT_LOG)
804void
805osl_assert(char *exp, char *file, int line)
806{
807 char tempbuf[256];
808 char *basename;
809
810 basename = strrchr(file, '/');
811
812 if (basename)
813 basename++;
814
815 if (!basename)
816 basename = file;
817
818#ifdef BCMASSERT_LOG
819 snprintf(tempbuf, 64, "\"%s\": file \"%s\", line %d\n",
820 exp, basename, line);
821
822 bcm_assert_log(tempbuf);
823#endif
824
825
826}
827#endif
828
829void
830osl_delay(uint usec)
831{
832 uint d;
833
834 while (usec > 0) {
835 d = MIN(usec, 1000);
836 udelay(d);
837 usec -= d;
838 }
839}
840
841
842
843void *
844osl_pktdup(osl_t *osh, void *skb)
845{
846 void * p;
847#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
848 gfp_t flags;
849
850 flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL;
851 if ((p = skb_clone((struct sk_buff *)skb, flags)) == NULL)
852#else
853 if ((p = skb_clone((struct sk_buff*)skb, GFP_ATOMIC)) == NULL)
854#endif
855 return NULL;
856
857#ifdef CTFPOOL
858 if (PKTISFAST(osh, skb)) {
859 ctfpool_t *ctfpool;
860
861
862 ctfpool = (ctfpool_t *)CTFPOOLPTR(osh, skb);
863 ASSERT(ctfpool != NULL);
864 PKTCLRFAST(osh, p);
865 PKTCLRFAST(osh, skb);
866 ctfpool->refills++;
867 }
868#endif
869
870
871 if (osh->pub.pkttag)
872 bzero((void*)((struct sk_buff *)p)->cb, OSL_PKTTAG_SZ);
873
874
875 osh->pub.pktalloced++;
876 return (p);
877}
878
879
880
881
882
883
884
885void *
886osl_os_open_image(char *filename)
887{
888 struct file *fp;
889
890 fp = filp_open(filename, O_RDONLY, 0);
891
892 if (IS_ERR(fp))
893 fp = NULL;
894
895 return fp;
896}
897
898int
899osl_os_get_image_block(char *buf, int len, void *image)
900{
901 struct file *fp = (struct file *)image;
902 int rdlen;
903
904 if (!image)
905 return 0;
906
907 rdlen = kernel_read(fp, fp->f_pos, buf, len);
908 if (rdlen > 0)
909 fp->f_pos += rdlen;
910
911 return rdlen;
912}
913
914void
915osl_os_close_image(void *image)
916{
917 if (image)
918 filp_close((struct file *)image, NULL);
919}