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