wl1251: set rate index and preamble flag on received packets
[pandora-wifi.git] / compat / compat-2.6.27.c
1 /*
2  * Copyright 2007       Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * Compatibility file for Linux wireless for kernels 2.6.27
9  */
10
11 #include <linux/compat.h>
12
13 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27))
14
15 #include <linux/pci.h>
16 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24))
17 #include <linux/mmc/sdio.h>
18 #include <linux/mmc/sdio_func.h>
19 #include <linux/mmc/card.h>
20 #include <linux/mmc/host.h>
21 #endif
22
23 /* rfkill notification chain */
24 #define RFKILL_STATE_CHANGED            0x0001  /* state of a normal rfkill
25                                                         switch has changed */
26
27 /*
28  * e5899e1b7d73e67de758a32174a859cc2586c0b9 made pci_pme_capable() external,
29  * it was defined internally, some drivers want access to this information.
30  *
31  * Unfortunately the old kernels do not have ->pm_cap or ->pme_support so
32  * we have to call the PCI routines directly.
33  */
34
35 /**
36  * pci_pme_capable - check the capability of PCI device to generate PME#
37  * @dev: PCI device to handle.
38  * @state: PCI state from which device will issue PME#.
39  *
40  * This is the backport code for older kernels for compat-wireless, we read stuff
41  * from the initialization stuff from pci_pm_init().
42  */
43 bool pci_pme_capable(struct pci_dev *dev, pci_power_t state)
44 {
45         int pm;
46         u16 pmc = 0;
47         u16 pme_support; /* as from the pci dev */
48         /* find PCI PM capability in list */
49         pm = pci_find_capability(dev, PCI_CAP_ID_PM);
50         if (!pm)
51                 return false;
52
53         if ((pmc & PCI_PM_CAP_VER_MASK) > 3) {
54                 dev_err(&dev->dev, "unsupported PM cap regs version (%u)\n",
55                         pmc & PCI_PM_CAP_VER_MASK);
56                 return false;
57         }
58
59         pmc &= PCI_PM_CAP_PME_MASK;
60
61         if (!pmc)
62                 return false;
63
64         pme_support = pmc >> PCI_PM_CAP_PME_SHIFT;
65
66         /* Check device's ability to generate PME# */
67
68         return !!(pme_support & (1 << state));
69 }
70 EXPORT_SYMBOL(pci_pme_capable);
71
72 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24))
73 /**
74  *      mmc_align_data_size - pads a transfer size to a more optimal value
75  *      @card: the MMC card associated with the data transfer
76  *      @sz: original transfer size
77  *
78  *      Pads the original data size with a number of extra bytes in
79  *      order to avoid controller bugs and/or performance hits
80  *      (e.g. some controllers revert to PIO for certain sizes).
81  *
82  *      Returns the improved size, which might be unmodified.
83  *
84  *      Note that this function is only relevant when issuing a
85  *      single scatter gather entry.
86  */
87 unsigned int mmc_align_data_size(struct mmc_card *card, unsigned int sz)
88 {
89         /*
90         * FIXME: We don't have a system for the controller to tell
91         * the core about its problems yet, so for now we just 32-bit
92         * align the size.
93         */
94         sz = ((sz + 3) / 4) * 4;
95
96         return sz;
97 }
98 EXPORT_SYMBOL(mmc_align_data_size);
99
100 /*
101  * Calculate the maximum byte mode transfer size
102  */
103 static inline unsigned int sdio_max_byte_size(struct sdio_func *func)
104 {
105         unsigned int mval = (unsigned int) min(func->card->host->max_seg_size,
106                             func->card->host->max_blk_size);
107         mval = min(mval, func->max_blksize);
108         return min(mval, 512u); /* maximum size for byte mode */
109 }
110
111 /**
112  *      sdio_align_size - pads a transfer size to a more optimal value
113  *      @func: SDIO function
114  *      @sz: original transfer size
115  *
116  *      Pads the original data size with a number of extra bytes in
117  *      order to avoid controller bugs and/or performance hits
118  *      (e.g. some controllers revert to PIO for certain sizes).
119  *
120  *      If possible, it will also adjust the size so that it can be
121  *      handled in just a single request.
122  *
123  *      Returns the improved size, which might be unmodified.
124  */
125 unsigned int sdio_align_size(struct sdio_func *func, unsigned int sz)
126 {
127         unsigned int orig_sz;
128         unsigned int blk_sz, byte_sz;
129         unsigned chunk_sz;
130
131         orig_sz = sz;
132
133         /*
134          * Do a first check with the controller, in case it
135          * wants to increase the size up to a point where it
136          * might need more than one block.
137          */
138         sz = mmc_align_data_size(func->card, sz);
139
140         /*
141          * If we can still do this with just a byte transfer, then
142          * we're done.
143          */
144         if (sz <= sdio_max_byte_size(func))
145                 return sz;
146
147         if (func->card->cccr.multi_block) {
148                 /*
149                  * Check if the transfer is already block aligned
150                  */
151                 if ((sz % func->cur_blksize) == 0)
152                         return sz;
153
154                 /*
155                  * Realign it so that it can be done with one request,
156                  * and recheck if the controller still likes it.
157                  */
158                 blk_sz = ((sz + func->cur_blksize - 1) /
159                         func->cur_blksize) * func->cur_blksize;
160                 blk_sz = mmc_align_data_size(func->card, blk_sz);
161
162                 /*
163                  * This value is only good if it is still just
164                  * one request.
165                  */
166                 if ((blk_sz % func->cur_blksize) == 0)
167                         return blk_sz;
168
169                 /*
170                  * We failed to do one request, but at least try to
171                  * pad the remainder properly.
172                  */
173                 byte_sz = mmc_align_data_size(func->card,
174                                 sz % func->cur_blksize);
175                 if (byte_sz <= sdio_max_byte_size(func)) {
176                         blk_sz = sz / func->cur_blksize;
177                         return blk_sz * func->cur_blksize + byte_sz;
178                 }
179         } else {
180                 /*
181                  * We need multiple requests, so first check that the
182                  * controller can handle the chunk size;
183                  */
184                 chunk_sz = mmc_align_data_size(func->card,
185                                 sdio_max_byte_size(func));
186                 if (chunk_sz == sdio_max_byte_size(func)) {
187                         /*
188                          * Fix up the size of the remainder (if any)
189                          */
190                         byte_sz = orig_sz % chunk_sz;
191                         if (byte_sz) {
192                                 byte_sz = mmc_align_data_size(func->card,
193                                                 byte_sz);
194                         }
195
196                         return (orig_sz / chunk_sz) * chunk_sz + byte_sz;
197                 }
198         }
199
200         /*
201          * The controller is simply incapable of transferring the size
202          * we want in decent manner, so just return the original size.
203          */
204         return orig_sz;
205 }
206 EXPORT_SYMBOL_GPL(sdio_align_size);
207 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) */
208
209 #ifdef CONFIG_DEBUG_FS
210 /*
211  * Backport of debugfs_remove_recursive() without using the internals globals
212  * which are used by the kernel's version with:
213  * simple_release_fs(&debugfs_mount, &debugfs_mount_count);
214  */
215 void debugfs_remove_recursive(struct dentry *dentry)
216 {
217         struct dentry *last = NULL;
218
219         /* Sanity checks */
220         if (!dentry || !dentry->d_parent || !dentry->d_parent->d_inode)
221                 return;
222
223         while (dentry != last) {
224                 struct dentry *child = dentry;
225
226                 /* Find a child without children */
227                 while (!list_empty(&child->d_subdirs))
228                         child = list_entry(child->d_subdirs.next,
229                                            struct dentry,
230                                            d_u.d_child);
231
232                 /* Bail out if we already tried to remove that entry */
233                 if (child == last)
234                         return;
235
236                 last = child;
237                 debugfs_remove(child);
238         }
239 }
240 EXPORT_SYMBOL_GPL(debugfs_remove_recursive);
241 #endif /* CONFIG_DEBUG_FS */
242
243 #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) */
244