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