2 * Linux OS Independent Layer
4 * Copyright 2006, Broadcom Corporation
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.
12 * $Id: linux_osl.c,v 1.1.1.14 2006/04/08 06:13:39 honor Exp $
18 #include <bcmendian.h>
19 #include <linux/module.h>
23 #include "linux_osl.h"
25 #include <linux/delay.h>
27 #include <asm/paccess.h>
31 #define PCI_CFG_RETRY 10
33 #define OS_HANDLE_MAGIC 0x1234abcd /* Magic # to recognise osh */
34 #define BCM_MEM_FILENAME_LEN 24 /* Mem. filename length */
36 typedef struct bcm_mem_link
{
37 struct bcm_mem_link
*prev
;
38 struct bcm_mem_link
*next
;
41 char file
[BCM_MEM_FILENAME_LEN
];
44 static int16 linuxbcmerrormap
[] = \
46 -EINVAL
, /* BCME_ERROR */
47 -EINVAL
, /* BCME_BADARG */
48 -EINVAL
, /* BCME_BADOPTION */
49 -EINVAL
, /* BCME_NOTUP */
50 -EINVAL
, /* BCME_NOTDOWN */
51 -EINVAL
, /* BCME_NOTAP */
52 -EINVAL
, /* BCME_NOTSTA */
53 -EINVAL
, /* BCME_BADKEYIDX */
54 -EINVAL
, /* BCME_RADIOOFF */
55 -EINVAL
, /* BCME_NOTBANDLOCKED */
56 -EINVAL
, /* BCME_NOCLK */
57 -EINVAL
, /* BCME_BADRATESET */
58 -EINVAL
, /* BCME_BADBAND */
59 -E2BIG
, /* BCME_BUFTOOSHORT */
60 -E2BIG
, /* BCME_BUFTOOLONG */
61 -EBUSY
, /* BCME_BUSY */
62 -EINVAL
, /* BCME_NOTASSOCIATED */
63 -EINVAL
, /* BCME_BADSSIDLEN */
64 -EINVAL
, /* BCME_OUTOFRANGECHAN */
65 -EINVAL
, /* BCME_BADCHAN */
66 -EFAULT
, /* BCME_BADADDR */
67 -ENOMEM
, /* BCME_NORESOURCE */
68 -EOPNOTSUPP
, /* BCME_UNSUPPORTED */
69 -EMSGSIZE
, /* BCME_BADLENGTH */
70 -EINVAL
, /* BCME_NOTREADY */
71 -EPERM
, /* BCME_NOTPERMITTED */
72 -ENOMEM
, /* BCME_NOMEM */
73 -EINVAL
, /* BCME_ASSOCIATED */
74 -ERANGE
, /* BCME_RANGE */
75 -EINVAL
, /* BCME_NOTFOUND */
76 -EINVAL
, /* BCME_WME_NOT_ENABLED */
77 -EINVAL
, /* BCME_TSPEC_NOTFOUND */
78 -EINVAL
, /* BCME_ACM_NOTSUPPORTED */
79 -EINVAL
, /* BCME_NOT_WME_ASSOCIATION */
80 -EIO
, /* BCME_SDIO_ERROR */
81 -ENODEV
/* BCME_DONGLE_DOWN */
84 /* translate bcmerrors into linux errors */
86 osl_error(int bcmerror
)
89 int array_size
= ARRAYSIZE(linuxbcmerrormap
);
91 abs_bcmerror
= ABS(bcmerror
);
96 else if (abs_bcmerror
>= array_size
)
97 abs_bcmerror
= BCME_ERROR
;
99 return linuxbcmerrormap
[abs_bcmerror
];
103 osl_attach(void *pdev
, bool pkttag
)
107 osh
= kmalloc(sizeof(osl_t
), GFP_ATOMIC
);
110 bzero(osh
, sizeof(osl_t
));
113 * check the cases where
114 * 1.Error code Added to bcmerror table, but forgot to add it to the OS
115 * dependent error code
116 * 2. Error code is added to the bcmerror table, but forgot to add the
117 * corresponding errorstring(dummy call to bcmerrorstr)
120 ASSERT(ABS(BCME_LAST
) == (ARRAYSIZE(linuxbcmerrormap
) - 1));
122 osh
->magic
= OS_HANDLE_MAGIC
;
125 osh
->dbgmem_list
= NULL
;
127 osh
->pub
.pkttag
= pkttag
;
133 osl_detach(osl_t
*osh
)
138 ASSERT(osh
->magic
== OS_HANDLE_MAGIC
);
142 /* Return a new packet. zero out pkttag */
144 osl_pktget(osl_t
*osh
, uint len
, bool send
)
148 if ((skb
= dev_alloc_skb(len
))) {
153 pktlist_add(&(osh
->pktlist
), (void *) skb
);
154 #endif /* BCMDBG_PKT */
156 osh
->pub
.pktalloced
++;
159 return ((void*) skb
);
162 typedef void (*pktfree_cb_fn_t
)(void *ctx
, void *pkt
, uint16 status
);
163 /* Free the driver packet. Free the tag if present */
165 osl_pktfree(osl_t
*osh
, void *p
, bool send
)
167 struct sk_buff
*skb
, *nskb
;
168 pktfree_cb_fn_t tx_fn
= osh
->pub
.tx_fn
;
170 skb
= (struct sk_buff
*) p
;
173 tx_fn(osh
->pub
.tx_ctx
, p
, 0);
175 /* perversion: we use skb->next to chain multi-skb packets */
181 pktlist_remove(&(osh
->pktlist
), (void *) skb
);
182 #endif /* BCMDBG_PKT */
184 if (skb
->destructor
) {
185 /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if destructor exists
187 dev_kfree_skb_any(skb
);
189 /* can free immediately (even in_irq()) if destructor does not exist */
193 osh
->pub
.pktalloced
--;
200 osl_malloc(osl_t
*osh
, uint size
)
204 /* only ASSERT if osh is defined */
206 ASSERT(osh
->magic
== OS_HANDLE_MAGIC
);
208 if ((addr
= kmalloc(size
, GFP_ATOMIC
)) == NULL
) {
214 osh
->malloced
+= size
;
220 osl_mfree(osl_t
*osh
, void *addr
, uint size
)
223 ASSERT(osh
->magic
== OS_HANDLE_MAGIC
);
224 osh
->malloced
-= size
;
230 osl_malloced(osl_t
*osh
)
232 ASSERT((osh
&& (osh
->magic
== OS_HANDLE_MAGIC
)));
233 return (osh
->malloced
);
236 uint
osl_malloc_failed(osl_t
*osh
)
238 ASSERT((osh
&& (osh
->magic
== OS_HANDLE_MAGIC
)));
239 return (osh
->failed
);
250 * The pkttag contents are NOT cloned.
253 osl_pktdup(osl_t
*osh
, void *skb
)
257 if ((p
= skb_clone((struct sk_buff
*)skb
, GFP_ATOMIC
)) == NULL
)
260 /* skb_clone copies skb->cb.. we don't want that */
262 bzero((void*)((struct sk_buff
*)p
)->cb
, OSL_PKTTAG_SZ
);
264 /* Increment the packet counter */
265 osh
->pub
.pktalloced
++;
270 osl_pktalloced(osl_t
*osh
)
272 return (osh
->pub
.pktalloced
);
This page took 0.05217 seconds and 5 git commands to generate.