staging: brcm80211: remove the rest of broadcom specific byte swapping routines
[cascardo/linux.git] / drivers / staging / brcm80211 / util / linux_osl.c
1 /*
2  * Copyright (c) 2010 Broadcom Corporation
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16
17 #include <linux/delay.h>
18 #include <linux/fs.h>
19 #ifdef mips
20 #include <asm/paccess.h>
21 #endif                          /* mips */
22 #include <linux/module.h>
23 #include <linux/pci.h>
24 #include <linux/netdevice.h>
25 #include <linux/sched.h>
26 #include <bcmdefs.h>
27 #include <osl.h>
28 #include <bcmutils.h>
29 #include <pcicfg.h>
30
31
32 #define OS_HANDLE_MAGIC         0x1234abcd      /* Magic # to recognise osh */
33 #define BCM_MEM_FILENAME_LEN    24      /* Mem. filename length */
34
35 /* Global ASSERT type flag */
36 u32 g_assert_type;
37
38 struct osl_info *osl_attach(void *pdev, uint bustype)
39 {
40         struct osl_info *osh;
41
42         osh = kmalloc(sizeof(struct osl_info), GFP_ATOMIC);
43         ASSERT(osh);
44
45         memset(osh, 0, sizeof(struct osl_info));
46
47         osh->magic = OS_HANDLE_MAGIC;
48         osh->pdev = pdev;
49         osh->bustype = bustype;
50
51         switch (bustype) {
52         case PCI_BUS:
53         case SI_BUS:
54         case PCMCIA_BUS:
55                 osh->mmbus = true;
56                 break;
57         case JTAG_BUS:
58         case SDIO_BUS:
59         case USB_BUS:
60         case SPI_BUS:
61         case RPC_BUS:
62                 osh->mmbus = false;
63                 break;
64         default:
65                 ASSERT(false);
66                 break;
67         }
68
69         return osh;
70 }
71
72 void osl_detach(struct osl_info *osh)
73 {
74         if (osh == NULL)
75                 return;
76
77         ASSERT(osh->magic == OS_HANDLE_MAGIC);
78         kfree(osh);
79 }
80
81 struct sk_buff *BCMFASTPATH pkt_buf_get_skb(struct osl_info *osh, uint len)
82 {
83         struct sk_buff *skb;
84
85         skb = dev_alloc_skb(len);
86         if (skb) {
87                 skb_put(skb, len);
88                 skb->priority = 0;
89
90                 osh->pktalloced++;
91         }
92
93         return skb;
94 }
95
96 /* Free the driver packet. Free the tag if present */
97 void BCMFASTPATH pkt_buf_free_skb(struct osl_info *osh, struct sk_buff *skb, bool send)
98 {
99         struct sk_buff *nskb;
100         int nest = 0;
101
102         ASSERT(skb);
103
104         /* perversion: we use skb->next to chain multi-skb packets */
105         while (skb) {
106                 nskb = skb->next;
107                 skb->next = NULL;
108
109                 if (skb->destructor)
110                         /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if
111                          * destructor exists
112                          */
113                         dev_kfree_skb_any(skb);
114                 else
115                         /* can free immediately (even in_irq()) if destructor
116                          * does not exist
117                          */
118                         dev_kfree_skb(skb);
119
120                 osh->pktalloced--;
121                 nest++;
122                 skb = nskb;
123         }
124 }
125
126 /* return bus # for the pci device pointed by osh->pdev */
127 uint osl_pci_bus(struct osl_info *osh)
128 {
129         ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev);
130
131         return ((struct pci_dev *)osh->pdev)->bus->number;
132 }
133
134 /* return slot # for the pci device pointed by osh->pdev */
135 uint osl_pci_slot(struct osl_info *osh)
136 {
137         ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev);
138
139         return PCI_SLOT(((struct pci_dev *)osh->pdev)->devfn);
140 }
141
142 void *osl_dma_alloc_consistent(struct osl_info *osh, uint size, u16 align_bits,
143                                uint *alloced, unsigned long *pap)
144 {
145         ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
146
147         if (align_bits) {
148                 u16 align = (1 << align_bits);
149                 if (!IS_ALIGNED(PAGE_SIZE, align))
150                         size += align;
151                 *alloced = size;
152         }
153         return pci_alloc_consistent(osh->pdev, size, (dma_addr_t *) pap);
154 }
155
156 void osl_dma_free_consistent(struct osl_info *osh, void *va, uint size,
157                              unsigned long pa)
158 {
159         ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
160
161         pci_free_consistent(osh->pdev, size, va, (dma_addr_t) pa);
162 }
163
164 uint BCMFASTPATH osl_dma_map(struct osl_info *osh, void *va, uint size,
165                              int direction)
166 {
167         int dir;
168
169         ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
170         dir = (direction == DMA_TX) ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE;
171         return pci_map_single(osh->pdev, va, size, dir);
172 }
173
174 void BCMFASTPATH osl_dma_unmap(struct osl_info *osh, uint pa, uint size,
175                                int direction)
176 {
177         int dir;
178
179         ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
180         dir = (direction == DMA_TX) ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE;
181         pci_unmap_single(osh->pdev, (u32) pa, size, dir);
182 }
183
184 #if defined(BCMDBG_ASSERT)
185 void osl_assert(char *exp, char *file, int line)
186 {
187         char tempbuf[256];
188         char *basename;
189
190         basename = strrchr(file, '/');
191         /* skip the '/' */
192         if (basename)
193                 basename++;
194
195         if (!basename)
196                 basename = file;
197
198 #ifdef BCMDBG_ASSERT
199         snprintf(tempbuf, 256,
200                  "assertion \"%s\" failed: file \"%s\", line %d\n", exp,
201                  basename, line);
202
203         /* Print assert message and give it time to be written to /var/log/messages */
204         if (!in_interrupt()) {
205                 const int delay = 3;
206                 printk(KERN_ERR "%s", tempbuf);
207                 printk(KERN_ERR "panic in %d seconds\n", delay);
208                 set_current_state(TASK_INTERRUPTIBLE);
209                 schedule_timeout(delay * HZ);
210         }
211
212         switch (g_assert_type) {
213         case 0:
214                 panic(KERN_ERR "%s", tempbuf);
215                 break;
216         case 1:
217                 printk(KERN_ERR "%s", tempbuf);
218                 BUG();
219                 break;
220         case 2:
221                 printk(KERN_ERR "%s", tempbuf);
222                 break;
223         default:
224                 break;
225         }
226 #endif                          /* BCMDBG_ASSERT */
227
228 }
229 #endif                          /* defined(BCMDBG_ASSERT) */
230