| 1 | |
| 2 | /* |
| 3 | * |
| 4 | * Copyright (c) 2004-2007 Atheros Communications Inc. |
| 5 | * All rights reserved. |
| 6 | * |
| 7 | * |
| 8 | * This program is free software; you can redistribute it and/or modify |
| 9 | * it under the terms of the GNU General Public License version 2 as |
| 10 | * published by the Free Software Foundation; |
| 11 | * |
| 12 | * Software distributed under the License is distributed on an "AS |
| 13 | * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 14 | * implied. See the License for the specific language governing |
| 15 | * rights and limitations under the License. |
| 16 | * |
| 17 | * |
| 18 | * |
| 19 | */ |
| 20 | #include <linux/kernel.h> |
| 21 | #include <linux/skbuff.h> |
| 22 | #include <a_config.h> |
| 23 | #include "athdefs.h" |
| 24 | #include "a_types.h" |
| 25 | #include "a_osapi.h" |
| 26 | #include "htc_packet.h" |
| 27 | |
| 28 | #define AR6000_DATA_OFFSET 64 |
| 29 | |
| 30 | void a_netbuf_enqueue(A_NETBUF_QUEUE_T *q, void *pkt) |
| 31 | { |
| 32 | skb_queue_tail((struct sk_buff_head *) q, (struct sk_buff *) pkt); |
| 33 | } |
| 34 | |
| 35 | void a_netbuf_prequeue(A_NETBUF_QUEUE_T *q, void *pkt) |
| 36 | { |
| 37 | skb_queue_head((struct sk_buff_head *) q, (struct sk_buff *) pkt); |
| 38 | } |
| 39 | |
| 40 | void *a_netbuf_dequeue(A_NETBUF_QUEUE_T *q) |
| 41 | { |
| 42 | return((void *) skb_dequeue((struct sk_buff_head *) q)); |
| 43 | } |
| 44 | |
| 45 | int a_netbuf_queue_size(A_NETBUF_QUEUE_T *q) |
| 46 | { |
| 47 | return(skb_queue_len((struct sk_buff_head *) q)); |
| 48 | } |
| 49 | |
| 50 | int a_netbuf_queue_empty(A_NETBUF_QUEUE_T *q) |
| 51 | { |
| 52 | return(skb_queue_empty((struct sk_buff_head *) q)); |
| 53 | } |
| 54 | |
| 55 | void a_netbuf_queue_init(A_NETBUF_QUEUE_T *q) |
| 56 | { |
| 57 | skb_queue_head_init((struct sk_buff_head *) q); |
| 58 | } |
| 59 | |
| 60 | void * |
| 61 | a_netbuf_alloc(int size) |
| 62 | { |
| 63 | struct sk_buff *skb; |
| 64 | skb = dev_alloc_skb(AR6000_DATA_OFFSET + sizeof(HTC_PACKET) + size); |
| 65 | skb_reserve(skb, AR6000_DATA_OFFSET + sizeof(HTC_PACKET)); |
| 66 | return ((void *)skb); |
| 67 | } |
| 68 | |
| 69 | /* |
| 70 | * Allocate an SKB w.o. any encapsulation requirement. |
| 71 | */ |
| 72 | void * |
| 73 | a_netbuf_alloc_raw(int size) |
| 74 | { |
| 75 | struct sk_buff *skb; |
| 76 | |
| 77 | skb = dev_alloc_skb(size); |
| 78 | |
| 79 | return ((void *)skb); |
| 80 | } |
| 81 | |
| 82 | void |
| 83 | a_netbuf_free(void *bufPtr) |
| 84 | { |
| 85 | struct sk_buff *skb = (struct sk_buff *)bufPtr; |
| 86 | |
| 87 | dev_kfree_skb(skb); |
| 88 | } |
| 89 | |
| 90 | A_UINT32 |
| 91 | a_netbuf_to_len(void *bufPtr) |
| 92 | { |
| 93 | return (((struct sk_buff *)bufPtr)->len); |
| 94 | } |
| 95 | |
| 96 | void * |
| 97 | a_netbuf_to_data(void *bufPtr) |
| 98 | { |
| 99 | return (((struct sk_buff *)bufPtr)->data); |
| 100 | } |
| 101 | |
| 102 | /* |
| 103 | * Add len # of bytes to the beginning of the network buffer |
| 104 | * pointed to by bufPtr |
| 105 | */ |
| 106 | A_STATUS |
| 107 | a_netbuf_push(void *bufPtr, A_INT32 len) |
| 108 | { |
| 109 | skb_push((struct sk_buff *)bufPtr, len); |
| 110 | |
| 111 | return A_OK; |
| 112 | } |
| 113 | |
| 114 | /* |
| 115 | * Add len # of bytes to the beginning of the network buffer |
| 116 | * pointed to by bufPtr and also fill with data |
| 117 | */ |
| 118 | A_STATUS |
| 119 | a_netbuf_push_data(void *bufPtr, char *srcPtr, A_INT32 len) |
| 120 | { |
| 121 | skb_push((struct sk_buff *) bufPtr, len); |
| 122 | A_MEMCPY(((struct sk_buff *)bufPtr)->data, srcPtr, len); |
| 123 | |
| 124 | return A_OK; |
| 125 | } |
| 126 | |
| 127 | /* |
| 128 | * Add len # of bytes to the end of the network buffer |
| 129 | * pointed to by bufPtr |
| 130 | */ |
| 131 | A_STATUS |
| 132 | a_netbuf_put(void *bufPtr, A_INT32 len) |
| 133 | { |
| 134 | skb_put((struct sk_buff *)bufPtr, len); |
| 135 | |
| 136 | return A_OK; |
| 137 | } |
| 138 | |
| 139 | /* |
| 140 | * Add len # of bytes to the end of the network buffer |
| 141 | * pointed to by bufPtr and also fill with data |
| 142 | */ |
| 143 | A_STATUS |
| 144 | a_netbuf_put_data(void *bufPtr, char *srcPtr, A_INT32 len) |
| 145 | { |
| 146 | char *start = ((struct sk_buff *)bufPtr)->data + |
| 147 | ((struct sk_buff *)bufPtr)->len; |
| 148 | skb_put((struct sk_buff *)bufPtr, len); |
| 149 | A_MEMCPY(start, srcPtr, len); |
| 150 | |
| 151 | return A_OK; |
| 152 | } |
| 153 | |
| 154 | |
| 155 | /* |
| 156 | * Trim the network buffer pointed to by bufPtr to len # of bytes |
| 157 | */ |
| 158 | A_STATUS |
| 159 | a_netbuf_setlen(void *bufPtr, A_INT32 len) |
| 160 | { |
| 161 | skb_trim((struct sk_buff *)bufPtr, len); |
| 162 | |
| 163 | return A_OK; |
| 164 | } |
| 165 | |
| 166 | /* |
| 167 | * Chop of len # of bytes from the end of the buffer. |
| 168 | */ |
| 169 | A_STATUS |
| 170 | a_netbuf_trim(void *bufPtr, A_INT32 len) |
| 171 | { |
| 172 | skb_trim((struct sk_buff *)bufPtr, ((struct sk_buff *)bufPtr)->len - len); |
| 173 | |
| 174 | return A_OK; |
| 175 | } |
| 176 | |
| 177 | /* |
| 178 | * Chop of len # of bytes from the end of the buffer and return the data. |
| 179 | */ |
| 180 | A_STATUS |
| 181 | a_netbuf_trim_data(void *bufPtr, char *dstPtr, A_INT32 len) |
| 182 | { |
| 183 | char *start = ((struct sk_buff *)bufPtr)->data + |
| 184 | (((struct sk_buff *)bufPtr)->len - len); |
| 185 | |
| 186 | A_MEMCPY(dstPtr, start, len); |
| 187 | skb_trim((struct sk_buff *)bufPtr, ((struct sk_buff *)bufPtr)->len - len); |
| 188 | |
| 189 | return A_OK; |
| 190 | } |
| 191 | |
| 192 | |
| 193 | /* |
| 194 | * Returns the number of bytes available to a a_netbuf_push() |
| 195 | */ |
| 196 | A_INT32 |
| 197 | a_netbuf_headroom(void *bufPtr) |
| 198 | { |
| 199 | return (skb_headroom((struct sk_buff *)bufPtr)); |
| 200 | } |
| 201 | |
| 202 | /* |
| 203 | * Removes specified number of bytes from the beginning of the buffer |
| 204 | */ |
| 205 | A_STATUS |
| 206 | a_netbuf_pull(void *bufPtr, A_INT32 len) |
| 207 | { |
| 208 | skb_pull((struct sk_buff *)bufPtr, len); |
| 209 | |
| 210 | return A_OK; |
| 211 | } |
| 212 | |
| 213 | /* |
| 214 | * Removes specified number of bytes from the beginning of the buffer |
| 215 | * and return the data |
| 216 | */ |
| 217 | A_STATUS |
| 218 | a_netbuf_pull_data(void *bufPtr, char *dstPtr, A_INT32 len) |
| 219 | { |
| 220 | A_MEMCPY(dstPtr, ((struct sk_buff *)bufPtr)->data, len); |
| 221 | skb_pull((struct sk_buff *)bufPtr, len); |
| 222 | |
| 223 | return A_OK; |
| 224 | } |
| 225 | |
| 226 | |