]>
Commit | Line | Data |
---|---|---|
4bd43f50 LR |
1 | /* |
2 | * Copyright (c) 2007-2008 Atheros Communications Inc. | |
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 | |
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
15 | */ | |
16 | /* Module Name : wwrap.c */ | |
17 | /* Abstract */ | |
18 | /* This module contains wrapper functions. */ | |
19 | /* */ | |
20 | /* NOTES */ | |
21 | /* Platform dependent. */ | |
22 | /* */ | |
23 | ||
24 | /* Please include your header files here */ | |
25 | #include "oal_dt.h" | |
26 | #include "usbdrv.h" | |
27 | ||
28 | #include <linux/netlink.h> | |
5a0e3ad6 | 29 | #include <linux/slab.h> |
4bd43f50 | 30 | #include <net/iw_handler.h> |
4bd43f50 | 31 | |
4bd43f50 LR |
32 | extern void zfiRecv80211(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* addInfo); |
33 | extern void zfCoreRecv(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* addInfo); | |
34 | extern void zfIdlChkRsp(zdev_t* dev, u32_t* rsp, u16_t rspLen); | |
35 | extern void zfIdlRsp(zdev_t* dev, u32_t *rsp, u16_t rspLen); | |
36 | ||
37 | ||
38 | ||
39 | //extern struct zsWdsStruct wds[ZM_WDS_PORT_NUMBER]; | |
40 | extern struct zsVapStruct vap[ZM_VAP_PORT_NUMBER]; | |
41 | ||
42 | u32_t zfLnxUsbSubmitTxData(zdev_t* dev); | |
43 | u32_t zfLnxUsbIn(zdev_t* dev, urb_t *urb, zbuf_t *buf); | |
44 | u32_t zfLnxSubmitRegInUrb(zdev_t *dev); | |
45 | u32_t zfLnxUsbSubmitBulkUrb(urb_t *urb, struct usb_device *usb, u16_t epnum, u16_t direction, | |
46 | void *transfer_buffer, int buffer_length, usb_complete_t complete, void *context); | |
47 | u32_t zfLnxUsbSubmitIntUrb(urb_t *urb, struct usb_device *usb, u16_t epnum, u16_t direction, | |
48 | void *transfer_buffer, int buffer_length, usb_complete_t complete, void *context, | |
49 | u32_t interval); | |
50 | ||
51 | u16_t zfLnxGetFreeTxUrb(zdev_t *dev) | |
52 | { | |
da3e8908 | 53 | struct usbdrv_private *macp = dev->ml_priv; |
4bd43f50 LR |
54 | u16_t idx; |
55 | unsigned long irqFlag; | |
56 | ||
da3e8908 | 57 | spin_lock_irqsave(&macp->cs_lock, irqFlag); |
4bd43f50 LR |
58 | |
59 | //idx = ((macp->TxUrbTail + 1) & (ZM_MAX_TX_URB_NUM - 1)); | |
60 | ||
61 | //if (idx != macp->TxUrbHead) | |
62 | if (macp->TxUrbCnt != 0) | |
63 | { | |
64 | idx = macp->TxUrbTail; | |
65 | macp->TxUrbTail = ((macp->TxUrbTail + 1) & (ZM_MAX_TX_URB_NUM - 1)); | |
66 | macp->TxUrbCnt--; | |
67 | } | |
68 | else | |
69 | { | |
70 | //printk(KERN_ERR "macp->TxUrbCnt: %d\n", macp->TxUrbCnt); | |
71 | idx = 0xffff; | |
72 | } | |
73 | ||
da3e8908 | 74 | spin_unlock_irqrestore(&macp->cs_lock, irqFlag); |
4bd43f50 LR |
75 | return idx; |
76 | } | |
77 | ||
78 | void zfLnxPutTxUrb(zdev_t *dev) | |
79 | { | |
da3e8908 | 80 | struct usbdrv_private *macp = dev->ml_priv; |
4bd43f50 LR |
81 | u16_t idx; |
82 | unsigned long irqFlag; | |
83 | ||
da3e8908 | 84 | spin_lock_irqsave(&macp->cs_lock, irqFlag); |
4bd43f50 LR |
85 | |
86 | idx = ((macp->TxUrbHead + 1) & (ZM_MAX_TX_URB_NUM - 1)); | |
87 | ||
88 | //if (idx != macp->TxUrbTail) | |
89 | if (macp->TxUrbCnt < ZM_MAX_TX_URB_NUM) | |
90 | { | |
91 | macp->TxUrbHead = idx; | |
92 | macp->TxUrbCnt++; | |
93 | } | |
94 | else | |
95 | { | |
96 | printk("UsbTxUrbQ inconsistent: TxUrbHead: %d, TxUrbTail: %d\n", | |
97 | macp->TxUrbHead, macp->TxUrbTail); | |
98 | } | |
99 | ||
da3e8908 | 100 | spin_unlock_irqrestore(&macp->cs_lock, irqFlag); |
4bd43f50 LR |
101 | } |
102 | ||
103 | u16_t zfLnxCheckTxBufferCnt(zdev_t *dev) | |
104 | { | |
da3e8908 | 105 | struct usbdrv_private *macp = dev->ml_priv; |
4bd43f50 LR |
106 | u16_t TxBufCnt; |
107 | unsigned long irqFlag; | |
108 | ||
da3e8908 | 109 | spin_lock_irqsave(&macp->cs_lock, irqFlag); |
4bd43f50 LR |
110 | |
111 | TxBufCnt = macp->TxBufCnt; | |
112 | ||
da3e8908 | 113 | spin_unlock_irqrestore(&macp->cs_lock, irqFlag); |
4bd43f50 LR |
114 | return TxBufCnt; |
115 | } | |
116 | ||
117 | UsbTxQ_t *zfLnxGetUsbTxBuffer(zdev_t *dev) | |
118 | { | |
da3e8908 | 119 | struct usbdrv_private *macp = dev->ml_priv; |
4bd43f50 LR |
120 | u16_t idx; |
121 | UsbTxQ_t *TxQ; | |
122 | unsigned long irqFlag; | |
123 | ||
da3e8908 | 124 | spin_lock_irqsave(&macp->cs_lock, irqFlag); |
4bd43f50 LR |
125 | |
126 | idx = ((macp->TxBufHead+1) & (ZM_MAX_TX_BUF_NUM - 1)); | |
127 | ||
128 | //if (idx != macp->TxBufTail) | |
129 | if (macp->TxBufCnt > 0) | |
130 | { | |
131 | //printk("CWY - zfwGetUsbTxBuffer ,macp->TxBufCnt = %d\n", macp->TxBufCnt); | |
132 | TxQ = (UsbTxQ_t *)&(macp->UsbTxBufQ[macp->TxBufHead]); | |
133 | macp->TxBufHead = ((macp->TxBufHead+1) & (ZM_MAX_TX_BUF_NUM - 1)); | |
134 | macp->TxBufCnt--; | |
135 | } | |
136 | else | |
137 | { | |
138 | if (macp->TxBufHead != macp->TxBufTail) | |
139 | { | |
140 | printk(KERN_ERR "zfwGetUsbTxBuf UsbTxBufQ inconsistent: TxBufHead: %d, TxBufTail: %d\n", | |
141 | macp->TxBufHead, macp->TxBufTail); | |
142 | } | |
143 | ||
da3e8908 | 144 | spin_unlock_irqrestore(&macp->cs_lock, irqFlag); |
4bd43f50 LR |
145 | return NULL; |
146 | } | |
147 | ||
da3e8908 | 148 | spin_unlock_irqrestore(&macp->cs_lock, irqFlag); |
4bd43f50 LR |
149 | return TxQ; |
150 | } | |
151 | ||
152 | u16_t zfLnxPutUsbTxBuffer(zdev_t *dev, u8_t *hdr, u16_t hdrlen, | |
153 | u8_t *snap, u16_t snapLen, u8_t *tail, u16_t tailLen, | |
154 | zbuf_t *buf, u16_t offset) | |
155 | { | |
da3e8908 | 156 | struct usbdrv_private *macp = dev->ml_priv; |
4bd43f50 LR |
157 | u16_t idx; |
158 | UsbTxQ_t *TxQ; | |
159 | unsigned long irqFlag; | |
160 | ||
da3e8908 | 161 | spin_lock_irqsave(&macp->cs_lock, irqFlag); |
4bd43f50 LR |
162 | |
163 | idx = ((macp->TxBufTail+1) & (ZM_MAX_TX_BUF_NUM - 1)); | |
164 | ||
165 | /* For Tx debug */ | |
166 | //zm_assert(macp->TxBufCnt >= 0); // deleted because of always true | |
167 | ||
168 | //if (idx != macp->TxBufHead) | |
169 | if (macp->TxBufCnt < ZM_MAX_TX_BUF_NUM) | |
170 | { | |
171 | //printk("CWY - zfwPutUsbTxBuffer ,macp->TxBufCnt = %d\n", macp->TxBufCnt); | |
172 | TxQ = (UsbTxQ_t *)&(macp->UsbTxBufQ[macp->TxBufTail]); | |
173 | memcpy(TxQ->hdr, hdr, hdrlen); | |
174 | TxQ->hdrlen = hdrlen; | |
175 | memcpy(TxQ->snap, snap, snapLen); | |
176 | TxQ->snapLen = snapLen; | |
177 | memcpy(TxQ->tail, tail, tailLen); | |
178 | TxQ->tailLen = tailLen; | |
179 | TxQ->buf = buf; | |
180 | TxQ->offset = offset; | |
181 | ||
182 | macp->TxBufTail = ((macp->TxBufTail+1) & (ZM_MAX_TX_BUF_NUM - 1)); | |
183 | macp->TxBufCnt++; | |
184 | } | |
185 | else | |
186 | { | |
187 | printk(KERN_ERR "zfLnxPutUsbTxBuffer UsbTxBufQ inconsistent: TxBufHead: %d, TxBufTail: %d, TxBufCnt: %d\n", | |
188 | macp->TxBufHead, macp->TxBufTail, macp->TxBufCnt); | |
da3e8908 | 189 | spin_unlock_irqrestore(&macp->cs_lock, irqFlag); |
4bd43f50 LR |
190 | return 0xffff; |
191 | } | |
192 | ||
da3e8908 | 193 | spin_unlock_irqrestore(&macp->cs_lock, irqFlag); |
4bd43f50 LR |
194 | return 0; |
195 | } | |
196 | ||
197 | zbuf_t *zfLnxGetUsbRxBuffer(zdev_t *dev) | |
198 | { | |
da3e8908 | 199 | struct usbdrv_private *macp = dev->ml_priv; |
4bd43f50 LR |
200 | //u16_t idx; |
201 | zbuf_t *buf; | |
202 | unsigned long irqFlag; | |
203 | ||
da3e8908 | 204 | spin_lock_irqsave(&macp->cs_lock, irqFlag); |
4bd43f50 LR |
205 | |
206 | //idx = ((macp->RxBufHead+1) & (ZM_MAX_RX_URB_NUM - 1)); | |
207 | ||
208 | //if (idx != macp->RxBufTail) | |
209 | if (macp->RxBufCnt != 0) | |
210 | { | |
211 | buf = macp->UsbRxBufQ[macp->RxBufHead]; | |
212 | macp->RxBufHead = ((macp->RxBufHead+1) & (ZM_MAX_RX_URB_NUM - 1)); | |
213 | macp->RxBufCnt--; | |
214 | } | |
215 | else | |
216 | { | |
217 | printk("RxBufQ inconsistent: RxBufHead: %d, RxBufTail: %d\n", | |
218 | macp->RxBufHead, macp->RxBufTail); | |
da3e8908 | 219 | spin_unlock_irqrestore(&macp->cs_lock, irqFlag); |
4bd43f50 LR |
220 | return NULL; |
221 | } | |
222 | ||
da3e8908 | 223 | spin_unlock_irqrestore(&macp->cs_lock, irqFlag); |
4bd43f50 LR |
224 | return buf; |
225 | } | |
226 | ||
227 | u32_t zfLnxPutUsbRxBuffer(zdev_t *dev, zbuf_t *buf) | |
228 | { | |
da3e8908 | 229 | struct usbdrv_private *macp = dev->ml_priv; |
4bd43f50 LR |
230 | u16_t idx; |
231 | unsigned long irqFlag; | |
232 | ||
da3e8908 | 233 | spin_lock_irqsave(&macp->cs_lock, irqFlag); |
4bd43f50 LR |
234 | |
235 | idx = ((macp->RxBufTail+1) & (ZM_MAX_RX_URB_NUM - 1)); | |
236 | ||
237 | //if (idx != macp->RxBufHead) | |
238 | if (macp->RxBufCnt != ZM_MAX_RX_URB_NUM) | |
239 | { | |
240 | macp->UsbRxBufQ[macp->RxBufTail] = buf; | |
241 | macp->RxBufTail = idx; | |
242 | macp->RxBufCnt++; | |
243 | } | |
244 | else | |
245 | { | |
246 | printk("RxBufQ inconsistent: RxBufHead: %d, RxBufTail: %d\n", | |
247 | macp->RxBufHead, macp->RxBufTail); | |
da3e8908 | 248 | spin_unlock_irqrestore(&macp->cs_lock, irqFlag); |
4bd43f50 LR |
249 | return 0xffff; |
250 | } | |
251 | ||
da3e8908 | 252 | spin_unlock_irqrestore(&macp->cs_lock, irqFlag); |
4bd43f50 LR |
253 | return 0; |
254 | } | |
255 | ||
4bd43f50 | 256 | void zfLnxUsbDataOut_callback(urb_t *urb) |
4bd43f50 LR |
257 | { |
258 | zdev_t* dev = urb->context; | |
259 | //UsbTxQ_t *TxData; | |
260 | ||
261 | /* Give the urb back */ | |
262 | zfLnxPutTxUrb(dev); | |
263 | ||
264 | /* Check whether there is any pending buffer needed */ | |
265 | /* to be sent */ | |
266 | if (zfLnxCheckTxBufferCnt(dev) != 0) | |
267 | { | |
268 | //TxData = zfwGetUsbTxBuffer(dev); | |
269 | ||
270 | //if (TxData == NULL) | |
271 | //{ | |
272 | // printk("Get a NULL buffer from zfwGetUsbTxBuffer\n"); | |
273 | // return; | |
274 | //} | |
275 | //else | |
276 | //{ | |
277 | zfLnxUsbSubmitTxData(dev); | |
278 | //} | |
279 | } | |
280 | } | |
281 | ||
4bd43f50 | 282 | void zfLnxUsbDataIn_callback(urb_t *urb) |
4bd43f50 LR |
283 | { |
284 | zdev_t* dev = urb->context; | |
da3e8908 | 285 | struct usbdrv_private *macp = dev->ml_priv; |
4bd43f50 LR |
286 | zbuf_t *buf; |
287 | zbuf_t *new_buf; | |
288 | int status; | |
289 | ||
290 | #if ZM_USB_STREAM_MODE == 1 | |
291 | static int remain_len = 0, check_pad = 0, check_len = 0; | |
292 | int index = 0; | |
293 | int chk_idx; | |
294 | u16_t pkt_len; | |
295 | u16_t pkt_tag; | |
296 | u16_t ii; | |
297 | zbuf_t *rxBufPool[8]; | |
298 | u16_t rxBufPoolIndex = 0; | |
299 | #endif | |
300 | ||
301 | /* Check status for URB */ | |
302 | if (urb->status != 0){ | |
303 | printk("zfLnxUsbDataIn_callback() : status=0x%x\n", urb->status); | |
304 | if ((urb->status != -ENOENT) && (urb->status != -ECONNRESET) | |
305 | && (urb->status != -ESHUTDOWN)) | |
306 | { | |
4bd43f50 LR |
307 | if (urb->status == -EPIPE){ |
308 | //printk(KERN_ERR "nonzero read bulk status received: -EPIPE"); | |
309 | status = -1; | |
310 | } | |
311 | ||
312 | if (urb->status == -EPROTO){ | |
313 | //printk(KERN_ERR "nonzero read bulk status received: -EPROTO"); | |
314 | status = -1; | |
315 | } | |
4bd43f50 LR |
316 | } |
317 | ||
318 | //printk(KERN_ERR "urb->status: 0x%08x\n", urb->status); | |
319 | ||
320 | /* Dequeue skb buffer */ | |
321 | buf = zfLnxGetUsbRxBuffer(dev); | |
322 | dev_kfree_skb_any(buf); | |
323 | #if 0 | |
324 | /* Enqueue skb buffer */ | |
325 | zfLnxPutUsbRxBuffer(dev, buf); | |
326 | ||
327 | /* Submit a Rx urb */ | |
328 | zfLnxUsbIn(dev, urb, buf); | |
329 | #endif | |
330 | return; | |
331 | } | |
332 | ||
333 | if (urb->actual_length == 0) | |
334 | { | |
335 | printk(KERN_ERR "Get an URB whose length is zero"); | |
336 | status = -1; | |
337 | } | |
338 | ||
339 | /* Dequeue skb buffer */ | |
340 | buf = zfLnxGetUsbRxBuffer(dev); | |
341 | ||
342 | //zfwBufSetSize(dev, buf, urb->actual_length); | |
343 | #ifdef NET_SKBUFF_DATA_USES_OFFSET | |
344 | buf->tail = 0; | |
345 | buf->len = 0; | |
346 | #else | |
347 | buf->tail = buf->data; | |
348 | buf->len = 0; | |
349 | #endif | |
350 | ||
2961f24f | 351 | BUG_ON((buf->tail + urb->actual_length) > buf->end); |
4bd43f50 LR |
352 | |
353 | skb_put(buf, urb->actual_length); | |
354 | ||
355 | #if ZM_USB_STREAM_MODE == 1 | |
356 | if (remain_len != 0) | |
357 | { | |
358 | zbuf_t *remain_buf = macp->reamin_buf; | |
359 | ||
360 | index = remain_len; | |
361 | remain_len -= check_pad; | |
362 | ||
363 | /* Copy data */ | |
364 | memcpy(&(remain_buf->data[check_len]), buf->data, remain_len); | |
365 | check_len += remain_len; | |
366 | remain_len = 0; | |
367 | ||
368 | rxBufPool[rxBufPoolIndex++] = remain_buf; | |
369 | } | |
370 | ||
371 | while(index < urb->actual_length) | |
372 | { | |
373 | pkt_len = buf->data[index] + (buf->data[index+1] << 8); | |
374 | pkt_tag = buf->data[index+2] + (buf->data[index+3] << 8); | |
375 | ||
376 | if (pkt_tag == 0x4e00) | |
377 | { | |
378 | int pad_len; | |
379 | ||
380 | //printk("Get a packet, index: %d, pkt_len: 0x%04x\n", index, pkt_len); | |
381 | #if 0 | |
382 | /* Dump data */ | |
383 | for (ii = index; ii < pkt_len+4;) | |
384 | { | |
385 | printk("%02x ", (buf->data[ii] & 0xff)); | |
386 | ||
387 | if ((++ii % 16) == 0) | |
388 | printk("\n"); | |
389 | } | |
390 | ||
391 | printk("\n"); | |
392 | #endif | |
393 | ||
394 | pad_len = 4 - (pkt_len & 0x3); | |
395 | ||
396 | if(pad_len == 4) | |
397 | pad_len = 0; | |
398 | ||
399 | chk_idx = index; | |
400 | index = index + 4 + pkt_len + pad_len; | |
401 | ||
402 | if (index > ZM_MAX_RX_BUFFER_SIZE) | |
403 | { | |
404 | remain_len = index - ZM_MAX_RX_BUFFER_SIZE; // - pad_len; | |
405 | check_len = ZM_MAX_RX_BUFFER_SIZE - chk_idx - 4; | |
406 | check_pad = pad_len; | |
407 | ||
408 | /* Allocate a skb buffer */ | |
409 | //new_buf = zfwBufAllocate(dev, ZM_MAX_RX_BUFFER_SIZE); | |
410 | new_buf = dev_alloc_skb(ZM_MAX_RX_BUFFER_SIZE); | |
411 | ||
412 | /* Set skb buffer length */ | |
413 | #ifdef NET_SKBUFF_DATA_USES_OFFSET | |
414 | new_buf->tail = 0; | |
415 | new_buf->len = 0; | |
416 | #else | |
417 | new_buf->tail = new_buf->data; | |
418 | new_buf->len = 0; | |
419 | #endif | |
420 | ||
421 | skb_put(new_buf, pkt_len); | |
422 | ||
423 | /* Copy the buffer */ | |
424 | memcpy(new_buf->data, &(buf->data[chk_idx+4]), check_len); | |
425 | ||
426 | /* Record the buffer pointer */ | |
427 | macp->reamin_buf = new_buf; | |
428 | } | |
429 | else | |
430 | { | |
431 | #ifdef ZM_DONT_COPY_RX_BUFFER | |
432 | if (rxBufPoolIndex == 0) | |
433 | { | |
434 | new_buf = skb_clone(buf, GFP_ATOMIC); | |
435 | ||
436 | new_buf->data = &(buf->data[chk_idx+4]); | |
437 | new_buf->len = pkt_len; | |
438 | } | |
439 | else | |
440 | { | |
441 | #endif | |
442 | /* Allocate a skb buffer */ | |
443 | new_buf = dev_alloc_skb(ZM_MAX_RX_BUFFER_SIZE); | |
444 | ||
445 | /* Set skb buffer length */ | |
446 | #ifdef NET_SKBUFF_DATA_USES_OFFSET | |
447 | new_buf->tail = 0; | |
448 | new_buf->len = 0; | |
449 | #else | |
450 | new_buf->tail = new_buf->data; | |
451 | new_buf->len = 0; | |
452 | #endif | |
453 | ||
454 | skb_put(new_buf, pkt_len); | |
455 | ||
456 | /* Copy the buffer */ | |
457 | memcpy(new_buf->data, &(buf->data[chk_idx+4]), pkt_len); | |
458 | ||
459 | #ifdef ZM_DONT_COPY_RX_BUFFER | |
460 | } | |
461 | #endif | |
462 | rxBufPool[rxBufPoolIndex++] = new_buf; | |
463 | } | |
464 | } | |
465 | else | |
466 | { | |
467 | printk(KERN_ERR "Can't find tag, pkt_len: 0x%04x, tag: 0x%04x\n", pkt_len, pkt_tag); | |
468 | ||
469 | /* Free buffer */ | |
470 | dev_kfree_skb_any(buf); | |
471 | ||
472 | /* Allocate a skb buffer */ | |
473 | new_buf = dev_alloc_skb(ZM_MAX_RX_BUFFER_SIZE); | |
474 | ||
475 | /* Enqueue skb buffer */ | |
476 | zfLnxPutUsbRxBuffer(dev, new_buf); | |
477 | ||
478 | /* Submit a Rx urb */ | |
479 | zfLnxUsbIn(dev, urb, new_buf); | |
480 | ||
481 | return; | |
482 | } | |
483 | } | |
484 | ||
485 | /* Free buffer */ | |
486 | dev_kfree_skb_any(buf); | |
487 | #endif | |
488 | ||
489 | /* Allocate a skb buffer */ | |
490 | new_buf = dev_alloc_skb(ZM_MAX_RX_BUFFER_SIZE); | |
491 | ||
492 | /* Enqueue skb buffer */ | |
493 | zfLnxPutUsbRxBuffer(dev, new_buf); | |
494 | ||
495 | /* Submit a Rx urb */ | |
496 | zfLnxUsbIn(dev, urb, new_buf); | |
497 | ||
498 | #if ZM_USB_STREAM_MODE == 1 | |
499 | for(ii = 0; ii < rxBufPoolIndex; ii++) | |
500 | { | |
501 | macp->usbCbFunctions.zfcbUsbRecv(dev, rxBufPool[ii]); | |
502 | } | |
503 | #else | |
504 | /* pass data to upper layer */ | |
505 | macp->usbCbFunctions.zfcbUsbRecv(dev, buf); | |
506 | #endif | |
507 | } | |
508 | ||
4bd43f50 | 509 | void zfLnxUsbRegOut_callback(urb_t *urb) |
4bd43f50 LR |
510 | { |
511 | //dev_t* dev = urb->context; | |
512 | ||
513 | //printk(KERN_ERR "zfwUsbRegOut_callback\n"); | |
514 | } | |
515 | ||
4bd43f50 | 516 | void zfLnxUsbRegIn_callback(urb_t *urb) |
4bd43f50 LR |
517 | { |
518 | zdev_t* dev = urb->context; | |
519 | u32_t rsp[64/4]; | |
520 | int status; | |
da3e8908 | 521 | struct usbdrv_private *macp = dev->ml_priv; |
4bd43f50 LR |
522 | |
523 | /* Check status for URB */ | |
524 | if (urb->status != 0){ | |
525 | printk("zfLnxUsbRegIn_callback() : status=0x%x\n", urb->status); | |
526 | if ((urb->status != -ENOENT) && (urb->status != -ECONNRESET) | |
527 | && (urb->status != -ESHUTDOWN)) | |
528 | { | |
4bd43f50 LR |
529 | if (urb->status == -EPIPE){ |
530 | //printk(KERN_ERR "nonzero read bulk status received: -EPIPE"); | |
531 | status = -1; | |
532 | } | |
533 | ||
534 | if (urb->status == -EPROTO){ | |
535 | //printk(KERN_ERR "nonzero read bulk status received: -EPROTO"); | |
536 | status = -1; | |
537 | } | |
4bd43f50 LR |
538 | } |
539 | ||
540 | //printk(KERN_ERR "urb->status: 0x%08x\n", urb->status); | |
541 | return; | |
542 | } | |
543 | ||
544 | if (urb->actual_length == 0) | |
545 | { | |
546 | printk(KERN_ERR "Get an URB whose length is zero"); | |
547 | status = -1; | |
548 | } | |
549 | ||
550 | /* Copy data into respone buffer */ | |
551 | memcpy(rsp, macp->regUsbReadBuf, urb->actual_length); | |
552 | ||
553 | /* Notify to upper layer */ | |
554 | //zfIdlChkRsp(dev, rsp, (u16_t)urb->actual_length); | |
555 | //zfiUsbRegIn(dev, rsp, (u16_t)urb->actual_length); | |
556 | macp->usbCbFunctions.zfcbUsbRegIn(dev, rsp, (u16_t)urb->actual_length); | |
557 | ||
558 | /* Issue another USB IN URB */ | |
559 | zfLnxSubmitRegInUrb(dev); | |
560 | } | |
561 | ||
562 | u32_t zfLnxSubmitRegInUrb(zdev_t *dev) | |
563 | { | |
564 | u32_t ret; | |
da3e8908 | 565 | struct usbdrv_private *macp = dev->ml_priv; |
4bd43f50 LR |
566 | |
567 | /* Submit a rx urb */ | |
568 | //ret = zfLnxUsbSubmitBulkUrb(macp->RegInUrb, macp->udev, | |
569 | // USB_REG_IN_PIPE, USB_DIR_IN, macp->regUsbReadBuf, | |
570 | // ZM_USB_REG_MAX_BUF_SIZE, zfLnxUsbRegIn_callback, dev); | |
571 | //CWYang(-) | |
572 | //if (ret != 0) | |
573 | // printk("zfwUsbSubmitBulkUrb fail, status: 0x%08x\n", (int)ret); | |
574 | ||
575 | ret = zfLnxUsbSubmitIntUrb(macp->RegInUrb, macp->udev, | |
576 | USB_REG_IN_PIPE, USB_DIR_IN, macp->regUsbReadBuf, | |
577 | ZM_USB_REG_MAX_BUF_SIZE, zfLnxUsbRegIn_callback, dev, 1); | |
578 | ||
579 | return ret; | |
580 | } | |
581 | ||
582 | u32_t zfLnxUsbSubmitTxData(zdev_t* dev) | |
583 | { | |
584 | u32_t i; | |
585 | u32_t ret; | |
586 | u16_t freeTxUrb; | |
587 | u8_t *puTxBuf = NULL; | |
588 | UsbTxQ_t *TxData; | |
589 | int len = 0; | |
da3e8908 | 590 | struct usbdrv_private *macp = dev->ml_priv; |
4bd43f50 LR |
591 | #if ZM_USB_TX_STREAM_MODE == 1 |
592 | u8_t ii; | |
593 | u16_t offset = 0; | |
594 | u16_t usbTxAggCnt; | |
595 | u16_t *pUsbTxHdr; | |
596 | UsbTxQ_t *TxQPool[ZM_MAX_TX_AGGREGATE_NUM]; | |
597 | #endif | |
598 | ||
599 | /* First check whether there is a free URB */ | |
600 | freeTxUrb = zfLnxGetFreeTxUrb(dev); | |
601 | ||
602 | /* If there is no any free Tx Urb */ | |
603 | if (freeTxUrb == 0xffff) | |
604 | { | |
605 | //printk(KERN_ERR "Can't get free Tx Urb\n"); | |
606 | //printk("CWY - Can't get free Tx Urb\n"); | |
607 | return 0xffff; | |
608 | } | |
609 | ||
610 | #if ZM_USB_TX_STREAM_MODE == 1 | |
611 | usbTxAggCnt = zfLnxCheckTxBufferCnt(dev); | |
612 | ||
613 | if (usbTxAggCnt >= ZM_MAX_TX_AGGREGATE_NUM) | |
614 | { | |
615 | usbTxAggCnt = ZM_MAX_TX_AGGREGATE_NUM; | |
616 | } | |
617 | else | |
618 | { | |
619 | usbTxAggCnt = 1; | |
620 | } | |
621 | ||
622 | //printk("usbTxAggCnt: %d\n", usbTxAggCnt); | |
623 | #endif | |
624 | ||
625 | #if ZM_USB_TX_STREAM_MODE == 1 | |
626 | for(ii = 0; ii < usbTxAggCnt; ii++) | |
627 | { | |
628 | #endif | |
629 | /* Dequeue the packet from UsbTxBufQ */ | |
630 | TxData = zfLnxGetUsbTxBuffer(dev); | |
631 | if (TxData == NULL) | |
632 | { | |
633 | /* Give the urb back */ | |
634 | zfLnxPutTxUrb(dev); | |
635 | return 0xffff; | |
636 | } | |
637 | ||
638 | /* Point to the freeTxUrb buffer */ | |
639 | puTxBuf = macp->txUsbBuf[freeTxUrb]; | |
640 | ||
641 | #if ZM_USB_TX_STREAM_MODE == 1 | |
642 | puTxBuf += offset; | |
643 | pUsbTxHdr = (u16_t *)puTxBuf; | |
644 | ||
645 | /* Add the packet length and tag information */ | |
646 | *pUsbTxHdr++ = TxData->hdrlen + TxData->snapLen + | |
647 | (TxData->buf->len - TxData->offset) + TxData->tailLen; | |
648 | ||
649 | *pUsbTxHdr++ = 0x697e; | |
650 | ||
651 | puTxBuf += 4; | |
652 | #endif // #ifdef ZM_USB_TX_STREAM_MODE | |
653 | ||
654 | /* Copy WLAN header and packet buffer into USB buffer */ | |
655 | for(i = 0; i < TxData->hdrlen; i++) | |
656 | { | |
657 | *puTxBuf++ = TxData->hdr[i]; | |
658 | } | |
659 | ||
660 | /* Copy SNAP header */ | |
661 | for(i = 0; i < TxData->snapLen; i++) | |
662 | { | |
663 | *puTxBuf++ = TxData->snap[i]; | |
664 | } | |
665 | ||
666 | /* Copy packet buffer */ | |
667 | for(i = 0; i < TxData->buf->len - TxData->offset; i++) | |
668 | { | |
669 | //*puTxBuf++ = zmw_rx_buf_readb(dev, TxData->buf, i); | |
670 | *puTxBuf++ = *(u8_t*)((u8_t*)TxData->buf->data+i+TxData->offset); | |
671 | } | |
672 | ||
673 | /* Copy tail */ | |
674 | for(i = 0; i < TxData->tailLen; i++) | |
675 | { | |
676 | *puTxBuf++ = TxData->tail[i]; | |
677 | } | |
678 | ||
679 | len = TxData->hdrlen+TxData->snapLen+TxData->buf->len+TxData->tailLen-TxData->offset; | |
680 | ||
681 | #if 0 | |
682 | if (TxData->hdrlen != 0) | |
683 | { | |
684 | puTxBuf = macp->txUsbBuf[freeTxUrb]; | |
685 | for (i = 0; i < len; i++) | |
686 | { | |
687 | printk("%02x ", puTxBuf[i]); | |
688 | if (i % 16 == 15) | |
689 | printk("\n"); | |
690 | } | |
691 | printk("\n"); | |
692 | } | |
693 | #endif | |
694 | #if 0 | |
695 | /* For debug purpose */ | |
696 | if(TxData->hdr[9] & 0x40) | |
697 | { | |
698 | int i; | |
699 | u16_t ctrlLen = TxData->hdr[0] + (TxData->hdr[1] << 8); | |
700 | ||
701 | if (ctrlLen != len + 4) | |
702 | { | |
703 | /* Dump control setting */ | |
704 | for(i = 0; i < 8; i++) | |
705 | { | |
706 | printk(KERN_ERR "0x%02x ", TxData->hdr[i]); | |
707 | } | |
708 | printk(KERN_ERR "\n"); | |
709 | ||
710 | printk(KERN_ERR "ctrLen: %d, hdrLen: %d, snapLen: %d\n", ctrlLen, TxData->hdrlen, TxData->snapLen); | |
711 | printk(KERN_ERR "bufLen: %d, tailLen: %d, len: %d\n", TxData->buf->len, TxData->tailLen, len); | |
712 | } | |
713 | } | |
714 | #endif | |
715 | ||
716 | #if ZM_USB_TX_STREAM_MODE == 1 | |
717 | // Add the Length and Tag | |
718 | len += 4; | |
719 | ||
720 | //printk("%d packet, length: %d\n", ii+1, len); | |
721 | ||
722 | if (ii < (ZM_MAX_TX_AGGREGATE_NUM-1)) | |
723 | { | |
724 | /* Pad the buffer to firmware descriptor boundary */ | |
725 | offset += (((len-1) / 4) + 1) * 4; | |
726 | } | |
727 | ||
728 | if (ii == (ZM_MAX_TX_AGGREGATE_NUM-1)) | |
729 | { | |
730 | len += offset; | |
731 | } | |
732 | ||
733 | TxQPool[ii] = TxData; | |
734 | ||
735 | //DbgPrint("%d packet, offset: %d\n", ii+1, pUsbTxTransfer->offset); | |
736 | ||
737 | /* free packet */ | |
738 | //zfBufFree(dev, txData->buf); | |
739 | } | |
740 | #endif | |
741 | //printk("CWY - call zfwUsbSubmitBulkUrb(), len = 0x%d\n", len); | |
742 | /* Submit a tx urb */ | |
743 | ret = zfLnxUsbSubmitBulkUrb(macp->WlanTxDataUrb[freeTxUrb], macp->udev, | |
744 | USB_WLAN_TX_PIPE, USB_DIR_OUT, macp->txUsbBuf[freeTxUrb], | |
745 | len, zfLnxUsbDataOut_callback, dev); | |
746 | //CWYang(-) | |
747 | //if (ret != 0) | |
748 | // printk("zfwUsbSubmitBulkUrb fail, status: 0x%08x\n", (int)ret); | |
749 | ||
750 | /* free packet */ | |
751 | //dev_kfree_skb_any(TxData->buf); | |
752 | #if ZM_USB_TX_STREAM_MODE == 1 | |
753 | for(ii = 0; ii < usbTxAggCnt; ii++) | |
754 | macp->usbCbFunctions.zfcbUsbOutComplete(dev, TxQPool[ii]->buf, 1, TxQPool[ii]->hdr); | |
755 | #else | |
756 | macp->usbCbFunctions.zfcbUsbOutComplete(dev, TxData->buf, 1, TxData->hdr); | |
757 | #endif | |
758 | ||
759 | return ret; | |
760 | } | |
761 | ||
762 | ||
763 | ||
764 | u32_t zfLnxUsbIn(zdev_t* dev, urb_t *urb, zbuf_t *buf) | |
765 | { | |
766 | u32_t ret; | |
da3e8908 | 767 | struct usbdrv_private *macp = dev->ml_priv; |
4bd43f50 LR |
768 | |
769 | /* Submit a rx urb */ | |
770 | ret = zfLnxUsbSubmitBulkUrb(urb, macp->udev, USB_WLAN_RX_PIPE, | |
771 | USB_DIR_IN, buf->data, ZM_MAX_RX_BUFFER_SIZE, | |
772 | zfLnxUsbDataIn_callback, dev); | |
773 | //CWYang(-) | |
774 | //if (ret != 0) | |
775 | // printk("zfwUsbSubmitBulkUrb fail, status: 0x%08x\n", (int)ret); | |
776 | ||
777 | return ret; | |
778 | } | |
779 | ||
780 | u32_t zfLnxUsbWriteReg(zdev_t* dev, u32_t* cmd, u16_t cmdLen) | |
781 | { | |
da3e8908 | 782 | struct usbdrv_private *macp = dev->ml_priv; |
4bd43f50 LR |
783 | u32_t ret; |
784 | ||
785 | #ifdef ZM_CONFIG_BIG_ENDIAN | |
786 | int ii = 0; | |
787 | ||
788 | for(ii=0; ii<(cmdLen>>2); ii++) | |
789 | cmd[ii] = cpu_to_le32(cmd[ii]); | |
790 | #endif | |
791 | ||
792 | memcpy(macp->regUsbWriteBuf, cmd, cmdLen); | |
793 | ||
794 | /* Issue an USB Out transfer */ | |
795 | /* Submit a tx urb */ | |
4bd43f50 LR |
796 | ret = zfLnxUsbSubmitIntUrb(macp->RegOutUrb, macp->udev, |
797 | USB_REG_OUT_PIPE, USB_DIR_OUT, macp->regUsbWriteBuf, | |
798 | cmdLen, zfLnxUsbRegOut_callback, dev, 1); | |
4bd43f50 LR |
799 | |
800 | return ret; | |
801 | } | |
802 | ||
803 | ||
804 | u32_t zfLnxUsbOut(zdev_t* dev, u8_t *hdr, u16_t hdrlen, u8_t *snap, u16_t snapLen, | |
805 | u8_t *tail, u16_t tailLen, zbuf_t *buf, u16_t offset) | |
806 | { | |
807 | u32_t ret; | |
da3e8908 | 808 | struct usbdrv_private *macp = dev->ml_priv; |
4bd43f50 LR |
809 | |
810 | /* Check length of tail buffer */ | |
811 | //zm_assert((tailLen <= 16)); | |
812 | ||
813 | /* Enqueue the packet into UsbTxBufQ */ | |
814 | if (zfLnxPutUsbTxBuffer(dev, hdr, hdrlen, snap, snapLen, tail, tailLen, buf, offset) == 0xffff) | |
815 | { | |
816 | /* free packet */ | |
817 | //printk("CWY - zfwPutUsbTxBuffer Error, free packet\n"); | |
818 | //dev_kfree_skb_any(buf); | |
819 | macp->usbCbFunctions.zfcbUsbOutComplete(dev, buf, 0, hdr); | |
820 | return 0xffff; | |
821 | } | |
822 | ||
823 | //return 0; | |
824 | //printk("CWY - call zfwUsbSubmitTxData()\n"); | |
825 | ret = zfLnxUsbSubmitTxData(dev); | |
826 | return ret; | |
827 | } | |
828 | ||
829 | void zfLnxInitUsbTxQ(zdev_t* dev) | |
830 | { | |
da3e8908 | 831 | struct usbdrv_private *macp = dev->ml_priv; |
4bd43f50 LR |
832 | |
833 | printk(KERN_ERR "zfwInitUsbTxQ\n"); | |
834 | ||
835 | /* Zero memory for UsbTxBufQ */ | |
836 | memset(macp->UsbTxBufQ, 0, sizeof(UsbTxQ_t) * ZM_MAX_TX_URB_NUM); | |
837 | ||
838 | macp->TxBufHead = 0; | |
839 | macp->TxBufTail = 0; | |
840 | macp->TxUrbHead = 0; | |
841 | macp->TxUrbTail = 0; | |
842 | macp->TxUrbCnt = ZM_MAX_TX_URB_NUM; | |
843 | } | |
844 | ||
845 | void zfLnxInitUsbRxQ(zdev_t* dev) | |
846 | { | |
847 | u16_t i; | |
848 | zbuf_t *buf; | |
da3e8908 | 849 | struct usbdrv_private *macp = dev->ml_priv; |
4bd43f50 LR |
850 | |
851 | /* Zero memory for UsbRxBufQ */ | |
852 | memset(macp->UsbRxBufQ, 0, sizeof(zbuf_t *) * ZM_MAX_RX_URB_NUM); | |
853 | ||
854 | macp->RxBufHead = 0; | |
855 | ||
856 | for (i = 0; i < ZM_MAX_RX_URB_NUM; i++) | |
857 | { | |
858 | //buf = zfwBufAllocate(dev, ZM_MAX_RX_BUFFER_SIZE); | |
859 | buf = dev_alloc_skb(ZM_MAX_RX_BUFFER_SIZE); | |
860 | macp->UsbRxBufQ[i] = buf; | |
861 | } | |
862 | ||
863 | //macp->RxBufTail = ZM_MAX_RX_URB_NUM - 1; | |
864 | macp->RxBufTail = 0; | |
865 | ||
866 | /* Submit all Rx urbs */ | |
867 | for (i = 0; i < ZM_MAX_RX_URB_NUM; i++) | |
868 | { | |
869 | zfLnxPutUsbRxBuffer(dev, macp->UsbRxBufQ[i]); | |
870 | zfLnxUsbIn(dev, macp->WlanRxDataUrb[i], macp->UsbRxBufQ[i]); | |
871 | } | |
872 | } | |
873 | ||
874 | ||
875 | ||
876 | u32_t zfLnxUsbSubmitBulkUrb(urb_t *urb, struct usb_device *usb, u16_t epnum, u16_t direction, | |
877 | void *transfer_buffer, int buffer_length, usb_complete_t complete, void *context) | |
878 | { | |
879 | u32_t ret; | |
880 | ||
881 | if(direction == USB_DIR_OUT) | |
882 | { | |
883 | usb_fill_bulk_urb(urb, usb, usb_sndbulkpipe(usb, epnum), | |
884 | transfer_buffer, buffer_length, complete, context); | |
885 | ||
886 | urb->transfer_flags |= URB_ZERO_PACKET; | |
887 | } | |
888 | else | |
889 | { | |
890 | usb_fill_bulk_urb(urb, usb, usb_rcvbulkpipe(usb, epnum), | |
891 | transfer_buffer, buffer_length, complete, context); | |
892 | } | |
893 | ||
4bd43f50 LR |
894 | if (epnum == 4) |
895 | { | |
896 | if (urb->hcpriv) | |
897 | { | |
898 | //printk("CWY - urb->hcpriv set by unknown reason, reset it\n"); | |
899 | //urb->hcpriv = 0; | |
900 | } | |
901 | } | |
902 | ||
4bd43f50 | 903 | ret = usb_submit_urb(urb, GFP_ATOMIC); |
4bd43f50 LR |
904 | if ((epnum == 4) & (ret != 0)) |
905 | { | |
906 | //printk("CWY - ret = %x\n", ret); | |
907 | } | |
908 | return ret; | |
909 | } | |
910 | ||
911 | u32_t zfLnxUsbSubmitIntUrb(urb_t *urb, struct usb_device *usb, u16_t epnum, u16_t direction, | |
912 | void *transfer_buffer, int buffer_length, usb_complete_t complete, void *context, | |
913 | u32_t interval) | |
914 | { | |
915 | u32_t ret; | |
916 | ||
917 | if(direction == USB_DIR_OUT) | |
918 | { | |
919 | usb_fill_int_urb(urb, usb, usb_sndbulkpipe(usb, epnum), | |
920 | transfer_buffer, buffer_length, complete, context, interval); | |
921 | } | |
922 | else | |
923 | { | |
924 | usb_fill_int_urb(urb, usb, usb_rcvbulkpipe(usb, epnum), | |
925 | transfer_buffer, buffer_length, complete, context, interval); | |
926 | } | |
927 | ||
4bd43f50 | 928 | ret = usb_submit_urb(urb, GFP_ATOMIC); |
4bd43f50 LR |
929 | |
930 | return ret; | |
931 | } | |
932 | ||
933 | #ifdef ZM_ENABLE_CENC | |
934 | int zfLnxCencSendMsg(struct sock *netlink_sk, u_int8_t *msg, int len) | |
935 | { | |
936 | #define COMMTYPE_GROUP 8 | |
937 | #define WAI_K_MSG 0x11 | |
938 | ||
939 | int ret = -1; | |
940 | int size; | |
941 | unsigned char *old_tail; | |
942 | struct sk_buff *skb; | |
943 | struct nlmsghdr *nlh; | |
944 | char *pos = NULL; | |
945 | ||
946 | size = NLMSG_SPACE(len); | |
947 | skb = alloc_skb(size, GFP_ATOMIC); | |
948 | ||
949 | if(skb == NULL) | |
950 | { | |
951 | printk("dev_alloc_skb failure \n"); | |
952 | goto out; | |
953 | } | |
954 | old_tail = skb->tail; | |
955 | ||
956 |