Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / src / drivers / net / ath / ath_main.c
1 /*
2  * Copyright (c) 2009 Atheros Communications Inc.
3  *
4  * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
5  * Original from Linux kernel 3.0.1
6  *
7  * Permission to use, copy, modify, and/or distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19
20 #include <ipxe/io.h>
21
22 #include "ath.h"
23
24 struct io_buffer *ath_rxbuf_alloc(struct ath_common *common,
25                                 u32 len,
26                                 u32 *iob_addr)
27 {
28         struct io_buffer *iob;
29         u32 off;
30
31         /*
32          * Cache-line-align.  This is important (for the
33          * 5210 at least) as not doing so causes bogus data
34          * in rx'd frames.
35          */
36
37         /* Note: the kernel can allocate a value greater than
38          * what we ask it to give us. We really only need 4 KB as that
39          * is this hardware supports and in fact we need at least 3849
40          * as that is the MAX AMSDU size this hardware supports.
41          * Unfortunately this means we may get 8 KB here from the
42          * kernel... and that is actually what is observed on some
43          * systems :( */
44         iob = alloc_iob(len + common->cachelsz - 1);
45         if (iob != NULL) {
46                 *iob_addr = virt_to_bus(iob->data);
47                 off = ((unsigned long) iob->data) % common->cachelsz;
48                 if (off != 0)
49                 {
50                         iob_reserve(iob, common->cachelsz - off);
51                         *iob_addr += common->cachelsz - off;
52                 }
53         } else {
54                 DBG("ath: iobuffer alloc of size %d failed\n", len);
55                 return NULL;
56         }
57
58         return iob;
59 }