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