upload tizen1.0 source
[kernel/linux-2.6.36.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 #include <linux/slab.h>
30 #include <net/iw_handler.h>
31
32 extern void zfiRecv80211(zdev_t *dev, zbuf_t *buf, struct zsAdditionInfo *addInfo);
33 extern void zfCoreRecv(zdev_t *dev, zbuf_t *buf, struct zsAdditionInfo *addInfo);
34 extern void zfIdlChkRsp(zdev_t *dev, u32_t *rsp, u16_t rspLen);
35 extern void zfIdlRsp(zdev_t *dev, u32_t *rsp, u16_t rspLen);
36
37
38
39 /*extern struct zsWdsStruct wds[ZM_WDS_PORT_NUMBER];*/
40 extern struct zsVapStruct vap[ZM_VAP_PORT_NUMBER];
41
42 u32_t zfLnxUsbSubmitTxData(zdev_t *dev);
43 u32_t zfLnxUsbIn(zdev_t *dev, urb_t *urb, zbuf_t *buf);
44 u32_t zfLnxSubmitRegInUrb(zdev_t *dev);
45 u32_t zfLnxUsbSubmitBulkUrb(urb_t *urb, struct usb_device *usb, u16_t epnum, u16_t direction,
46         void *transfer_buffer, int buffer_length, usb_complete_t complete, void *context);
47 u32_t zfLnxUsbSubmitIntUrb(urb_t *urb, struct usb_device *usb, u16_t epnum, u16_t direction,
48         void *transfer_buffer, int buffer_length, usb_complete_t complete, void *context,
49         u32_t interval);
50
51 u16_t zfLnxGetFreeTxUrb(zdev_t *dev)
52 {
53     struct usbdrv_private *macp = dev->ml_priv;
54     u16_t idx;
55     unsigned long irqFlag;
56
57     spin_lock_irqsave(&macp->cs_lock, irqFlag);
58
59     /*idx = ((macp->TxUrbTail + 1) & (ZM_MAX_TX_URB_NUM - 1));*/
60
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         }
70
71         spin_unlock_irqrestore(&macp->cs_lock, irqFlag);
72     return idx;
73 }
74
75 void zfLnxPutTxUrb(zdev_t *dev)
76 {
77     struct usbdrv_private *macp = dev->ml_priv;
78     u16_t idx;
79     unsigned long irqFlag;
80
81     spin_lock_irqsave(&macp->cs_lock, irqFlag);
82
83     idx = ((macp->TxUrbHead + 1) & (ZM_MAX_TX_URB_NUM - 1));
84
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);
92     }
93
94     spin_unlock_irqrestore(&macp->cs_lock, irqFlag);
95 }
96
97 u16_t zfLnxCheckTxBufferCnt(zdev_t *dev)
98 {
99     struct usbdrv_private *macp = dev->ml_priv;
100     u16_t TxBufCnt;
101     unsigned long irqFlag;
102
103     spin_lock_irqsave(&macp->cs_lock, irqFlag);
104
105     TxBufCnt = macp->TxBufCnt;
106
107     spin_unlock_irqrestore(&macp->cs_lock, irqFlag);
108     return TxBufCnt;
109 }
110
111 UsbTxQ_t *zfLnxGetUsbTxBuffer(zdev_t *dev)
112 {
113     struct usbdrv_private *macp = dev->ml_priv;
114     u16_t idx;
115     UsbTxQ_t *TxQ;
116     unsigned long irqFlag;
117
118     spin_lock_irqsave(&macp->cs_lock, irqFlag);
119
120     idx = ((macp->TxBufHead+1) & (ZM_MAX_TX_BUF_NUM - 1));
121
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;
136     }
137
138     spin_unlock_irqrestore(&macp->cs_lock, irqFlag);
139     return TxQ;
140 }
141
142 u16_t zfLnxPutUsbTxBuffer(zdev_t *dev, u8_t *hdr, u16_t hdrlen,
143         u8_t *snap, u16_t snapLen, u8_t *tail, u16_t tailLen,
144         zbuf_t *buf, u16_t offset)
145 {
146     struct usbdrv_private *macp = dev->ml_priv;
147     u16_t idx;
148     UsbTxQ_t *TxQ;
149     unsigned long irqFlag;
150
151     spin_lock_irqsave(&macp->cs_lock, irqFlag);
152
153     idx = ((macp->TxBufTail+1) & (ZM_MAX_TX_BUF_NUM - 1));
154
155     /* For Tx debug */
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         }
179
180     spin_unlock_irqrestore(&macp->cs_lock, irqFlag);
181     return 0;
182 }
183
184 zbuf_t *zfLnxGetUsbRxBuffer(zdev_t *dev)
185 {
186     struct usbdrv_private *macp = dev->ml_priv;
187     /*u16_t idx;*/
188     zbuf_t *buf;
189     unsigned long irqFlag;
190
191     spin_lock_irqsave(&macp->cs_lock, irqFlag);
192
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         }
206
207     spin_unlock_irqrestore(&macp->cs_lock, irqFlag);
208     return buf;
209 }
210
211 u32_t zfLnxPutUsbRxBuffer(zdev_t *dev, zbuf_t *buf)
212 {
213     struct usbdrv_private *macp = dev->ml_priv;
214     u16_t idx;
215     unsigned long irqFlag;
216
217     spin_lock_irqsave(&macp->cs_lock, irqFlag);
218
219     idx = ((macp->RxBufTail+1) & (ZM_MAX_RX_URB_NUM - 1));
220
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         }
232
233         spin_unlock_irqrestore(&macp->cs_lock, irqFlag);
234         return 0;
235 }
236
237 void zfLnxUsbDataOut_callback(urb_t *urb)
238 {
239     zdev_t *dev = urb->context;
240     /*UsbTxQ_t *TxData;*/
241
242     /* Give the urb back */
243     zfLnxPutTxUrb(dev);
244
245     /* Check whether there is any pending buffer needed */
246     /* to be sent */
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         //}*/
258     }
259 }
260
261 void zfLnxUsbDataIn_callback(urb_t *urb)
262 {
263     zdev_t *dev = urb->context;
264     struct usbdrv_private *macp = dev->ml_priv;
265     zbuf_t *buf;
266     zbuf_t *new_buf;
267     int status;
268
269 #if ZM_USB_STREAM_MODE == 1
270     static int remain_len, check_pad, check_len;
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 */
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);
304
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;
314     }
315
316     /* Dequeue skb buffer */
317     buf = zfLnxGetUsbRxBuffer(dev);
318
319     /*zfwBufSetSize(dev, buf, urb->actual_length);*/
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
328     BUG_ON((buf->tail + urb->actual_length) > buf->end);
329
330     skb_put(buf, urb->actual_length);
331
332 #if ZM_USB_STREAM_MODE == 1
333     if (remain_len != 0) {
334         zbuf_t *remain_buf = macp->reamin_buf;
335
336         index = remain_len;
337         remain_len -= check_pad;
338
339         /*  Copy data */
340         memcpy(&(remain_buf->data[check_len]), buf->data, remain_len);
341         check_len += remain_len;
342         remain_len = 0;
343
344         rxBufPool[rxBufPoolIndex++] = remain_buf;
345     }
346
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                 }
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
464     for (ii = 0; ii < rxBufPoolIndex; ii++) {
465         macp->usbCbFunctions.zfcbUsbRecv(dev, rxBufPool[ii]);
466     }
467 #else
468     /* pass data to upper layer */
469     macp->usbCbFunctions.zfcbUsbRecv(dev, buf);
470 #endif
471 }
472
473 void zfLnxUsbRegOut_callback(urb_t *urb)
474 {
475     /*dev_t* dev = urb->context;*/
476
477         /*printk(KERN_ERR "zfwUsbRegOut_callback\n");*/
478 }
479
480 void zfLnxUsbRegIn_callback(urb_t *urb)
481 {
482     zdev_t *dev = urb->context;
483     u32_t rsp[64/4];
484     int status;
485     struct usbdrv_private *macp = dev->ml_priv;
486
487     /* Check status for URB */
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         }
505
506     if (urb->actual_length == 0) {
507         printk(KERN_ERR "Get an URB whose length is zero");
508         status = -1;
509     }
510
511     /* Copy data into respone buffer */
512     memcpy(rsp, macp->regUsbReadBuf, urb->actual_length);
513
514     /* Notify to upper layer */
515     /*zfIdlChkRsp(dev, rsp, (u16_t)urb->actual_length);*/
516     /*zfiUsbRegIn(dev, rsp, (u16_t)urb->actual_length);*/
517     macp->usbCbFunctions.zfcbUsbRegIn(dev, rsp, (u16_t)urb->actual_length);
518
519     /* Issue another USB IN URB */
520     zfLnxSubmitRegInUrb(dev);
521 }
522
523 u32_t zfLnxSubmitRegInUrb(zdev_t *dev)
524 {
525     u32_t ret;
526     struct usbdrv_private *macp = dev->ml_priv;
527
528     /* Submit a rx urb
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)
534     //    printk("zfwUsbSubmitBulkUrb fail, status: 0x%08x\n", (int)ret);*/
535
536     ret = zfLnxUsbSubmitIntUrb(macp->RegInUrb, macp->udev,
537         USB_REG_IN_PIPE, USB_DIR_IN, macp->regUsbReadBuf,
538         ZM_USB_REG_MAX_BUF_SIZE, zfLnxUsbRegIn_callback, dev, 1);
539
540     return ret;
541 }
542
543 u32_t zfLnxUsbSubmitTxData(zdev_t *dev)
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;
551     struct usbdrv_private *macp = dev->ml_priv;
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 */
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;
568     }
569
570 #if ZM_USB_TX_STREAM_MODE == 1
571     usbTxAggCnt = zfLnxCheckTxBufferCnt(dev);
572
573     if (usbTxAggCnt >= ZM_MAX_TX_AGGREGATE_NUM) {
574         usbTxAggCnt = ZM_MAX_TX_AGGREGATE_NUM;
575     } else {
576         usbTxAggCnt = 1;
577     }
578
579     /*printk("usbTxAggCnt: %d\n", usbTxAggCnt);*/
580 #endif
581
582 #if ZM_USB_TX_STREAM_MODE == 1
583     for (ii = 0; ii < usbTxAggCnt; ii++) {
584 #endif
585     /* Dequeue the packet from UsbTxBufQ */
586     TxData = zfLnxGetUsbTxBuffer(dev);
587     if (TxData == NULL) {
588         /* Give the urb back */
589         zfLnxPutTxUrb(dev);
590         return 0xffff;
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 +
602         (TxData->buf->len - TxData->offset) +  TxData->tailLen;
603
604     *pUsbTxHdr++ = 0x697e;
605
606     puTxBuf += 4;
607 #endif /* #ifdef ZM_USB_TX_STREAM_MODE*/
608
609     /* Copy WLAN header and packet buffer into USB buffer */
610     for (i = 0; i < TxData->hdrlen; i++) {
611         *puTxBuf++ = TxData->hdr[i];
612     }
613
614     /* Copy SNAP header */
615     for (i = 0; i < TxData->snapLen; i++) {
616         *puTxBuf++ = TxData->snap[i];
617     }
618
619     /* Copy packet buffer */
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);
623     }
624
625     /* Copy tail */
626     for (i = 0; i < TxData->tailLen; i++) {
627         *puTxBuf++ = TxData->tail[i];
628     }
629
630     len = TxData->hdrlen+TxData->snapLen+TxData->buf->len+TxData->tailLen-TxData->offset;
631
632     #if 0
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         }
642     #endif
643     #if 0
644     /* For debug purpose */
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         }
659     }
660     #endif
661
662 #if ZM_USB_TX_STREAM_MODE == 1
663     /* Add the Length and Tag*/
664     len += 4;
665
666     /*printk("%d packet, length: %d\n", ii+1, len);*/
667
668     if (ii < (ZM_MAX_TX_AGGREGATE_NUM-1)) {
669         /* Pad the buffer to firmware descriptor boundary */
670         offset += (((len-1) / 4) + 1) * 4;
671     }
672
673     if (ii == (ZM_MAX_TX_AGGREGATE_NUM-1)) {
674         len += offset;
675     }
676
677     TxQPool[ii] = TxData;
678
679     /*DbgPrint("%d packet, offset: %d\n", ii+1, pUsbTxTransfer->offset);*/
680
681     /* free packet */
682     /*zfBufFree(dev, txData->buf);*/
683     }
684 #endif
685     /*printk("CWY - call zfwUsbSubmitBulkUrb(), len = 0x%d\n", len);*/
686     /* Submit a tx urb */
687     ret = zfLnxUsbSubmitBulkUrb(macp->WlanTxDataUrb[freeTxUrb], macp->udev,
688         USB_WLAN_TX_PIPE, USB_DIR_OUT, macp->txUsbBuf[freeTxUrb],
689         len, zfLnxUsbDataOut_callback, dev);
690     /*CWYang(-)
691     //if (ret != 0)
692     //    printk("zfwUsbSubmitBulkUrb fail, status: 0x%08x\n", (int)ret);*/
693
694     /* free packet */
695     /*dev_kfree_skb_any(TxData->buf);*/
696 #if ZM_USB_TX_STREAM_MODE == 1
697     for (ii = 0; ii < usbTxAggCnt; ii++)
698         macp->usbCbFunctions.zfcbUsbOutComplete(dev, TxQPool[ii]->buf, 1, TxQPool[ii]->hdr);
699 #else
700     macp->usbCbFunctions.zfcbUsbOutComplete(dev, TxData->buf, 1, TxData->hdr);
701 #endif
702
703     return ret;
704 }
705
706
707
708 u32_t zfLnxUsbIn(zdev_t *dev, urb_t *urb, zbuf_t *buf)
709 {
710     u32_t ret;
711     struct usbdrv_private *macp = dev->ml_priv;
712
713     /* Submit a rx urb */
714     ret = zfLnxUsbSubmitBulkUrb(urb, macp->udev, USB_WLAN_RX_PIPE,
715         USB_DIR_IN, buf->data, ZM_MAX_RX_BUFFER_SIZE,
716         zfLnxUsbDataIn_callback, dev);
717     /*CWYang(-)
718     //if (ret != 0)
719     //    printk("zfwUsbSubmitBulkUrb fail, status: 0x%08x\n", (int)ret);*/
720
721     return ret;
722 }
723
724 u32_t zfLnxUsbWriteReg(zdev_t *dev, u32_t *cmd, u16_t cmdLen)
725 {
726     struct usbdrv_private *macp = dev->ml_priv;
727     u32_t ret;
728
729 #ifdef ZM_CONFIG_BIG_ENDIAN
730     int ii = 0;
731
732     for (ii = 0; ii < (cmdLen>>2); ii++)
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 */
740     ret = zfLnxUsbSubmitIntUrb(macp->RegOutUrb, macp->udev,
741         USB_REG_OUT_PIPE, USB_DIR_OUT, macp->regUsbWriteBuf,
742         cmdLen, zfLnxUsbRegOut_callback, dev, 1);
743
744     return ret;
745 }
746
747
748 u32_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)
750 {
751     u32_t ret;
752     struct usbdrv_private *macp = dev->ml_priv;
753
754     /* Check length of tail buffer */
755     /*zm_assert((tailLen <= 16));*/
756
757     /* Enqueue the packet into UsbTxBufQ */
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         }
765
766     /*return 0;
767     //printk("CWY - call zfwUsbSubmitTxData()\n");*/
768     ret = zfLnxUsbSubmitTxData(dev);
769     return ret;
770 }
771
772 void zfLnxInitUsbTxQ(zdev_t *dev)
773 {
774     struct usbdrv_private *macp = dev->ml_priv;
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
788 void zfLnxInitUsbRxQ(zdev_t *dev)
789 {
790     u16_t i;
791     zbuf_t *buf;
792     struct usbdrv_private *macp = dev->ml_priv;
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
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         }
804
805     /*macp->RxBufTail = ZM_MAX_RX_URB_NUM - 1;*/
806     macp->RxBufTail = 0;
807
808     /* Submit all Rx urbs */
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         }
813 }
814
815
816
817 u32_t zfLnxUsbSubmitBulkUrb(urb_t *urb, struct usb_device *usb, u16_t epnum, u16_t direction,
818         void *transfer_buffer, int buffer_length, usb_complete_t complete, void *context)
819 {
820     u32_t ret;
821
822     if (direction == USB_DIR_OUT) {
823         usb_fill_bulk_urb(urb, usb, usb_sndbulkpipe(usb, epnum),
824                 transfer_buffer, buffer_length, complete, context);
825
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);
830     }
831
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         }
838
839     ret = usb_submit_urb(urb, GFP_ATOMIC);
840     if ((epnum == 4) & (ret != 0)) {
841         /*printk("CWY - ret = %x\n", ret);*/
842     }
843     return ret;
844 }
845
846 u32_t zfLnxUsbSubmitIntUrb(urb_t *urb, struct usb_device *usb, u16_t epnum, u16_t direction,
847         void *transfer_buffer, int buffer_length, usb_complete_t complete, void *context,
848         u32_t interval)
849 {
850     u32_t ret;
851
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);
858     }
859
860     ret = usb_submit_urb(urb, GFP_ATOMIC);
861
862     return ret;
863 }
864
865 #ifdef ZM_ENABLE_CENC
866 int 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
881         if (skb == NULL) {
882                 printk("dev_alloc_skb failure \n");
883                 goto out;
884         }
885         old_tail = skb->tail;
886
887         /* */
888         nlh = NLMSG_PUT(skb, 0, 0, WAI_K_MSG, size-sizeof(*nlh));
889         pos = NLMSG_DATA(nlh);
890
891         /* */
892         memcpy(pos, msg,  len);
893         /* */
894         nlh->nlmsg_len = skb->tail - old_tail;
895         NETLINK_CB(skb).dst_group = COMMTYPE_GROUP;
896         netlink_broadcast(netlink_sk, skb, 0, COMMTYPE_GROUP, GFP_ATOMIC);
897         ret = 0;
898 out:
899         return ret;
900 nlmsg_failure: /* */
901         kfree_skb(skb);
902         goto out;
903
904 #undef COMMTYPE_GROUP
905 #undef WAI_K_MSG
906 }
907 #endif /*ZM_ENABLE_CENC*/
908
909 /* Simply return 0xffff if VAP function is not supported */
910 u16_t zfLnxGetVapId(zdev_t *dev)
911 {
912     u16_t i;
913
914     for (i = 0; i < ZM_VAP_PORT_NUMBER; i++) {
915         if (vap[i].dev == dev) {
916                 return i;
917                 }
918         }
919         return 0xffff;
920 }
921
922 u32_t zfwReadReg(zdev_t *dev, u32_t offset)
923 {
924     return 0;
925 }
926
927 #ifndef INIT_WORK
928 #define work_struct tq_struct
929
930 #define schedule_work(a)  schedule_task(a)
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
939 u32_t smp_kevent_Lock = 0;
940
941 void kevent(struct work_struct *work)
942 {
943     struct usbdrv_private *macp =
944         container_of(work, struct usbdrv_private, kevent);
945         zdev_t *dev = macp->device;
946
947     if (test_and_set_bit(0, (void *)&smp_kevent_Lock)) {
948         /*schedule_work(&macp->kevent);*/
949         return;
950     }
951
952     down(&macp->ioctl_sem);
953
954     if (test_and_clear_bit(KEVENT_WATCHDOG, &macp->kevent_flags)) {
955     extern u16_t zfHpStartRecv(zdev_t *dev);
956         /*zfiHwWatchDogReinit(dev);*/
957         printk(("\n ************ Hw watchDog occur!! ************** \n"));
958         zfiWlanSuspend(dev);
959         zfiWlanResume(dev , 0);
960         zfHpStartRecv(dev);
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 /************************************************************************/
982 u8_t zfLnxCreateThread(zdev_t *dev)
983 {
984     struct usbdrv_private *macp = dev->ml_priv;
985
986     /* Create Mutex and keventd */
987     INIT_WORK(&macp->kevent, kevent);
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 /************************************************************************/
1009 void zfLnxSignalThread(zdev_t *dev, int flag)
1010 {
1011     struct usbdrv_private *macp = dev->ml_priv;
1012
1013     if (macp == NULL) {
1014         printk("macp is NULL\n");
1015         return;
1016     }
1017
1018     if (0 && macp->kevent_ready != 1) {
1019         printk("Kevent not ready\n");
1020         return;
1021     }
1022
1023     set_bit(flag, &macp->kevent_flags);
1024
1025     if (!schedule_work(&macp->kevent)) {
1026         /*Fails is Normal
1027         //printk(KERN_ERR "schedule_task failed, flag = %x\n", flag);*/
1028         }
1029 }
1030
1031 /* Notify wrapper todo redownload firmware and reinit procedure when */
1032 /* hardware watchdog occur : zfiHwWatchDogReinit() */
1033 void zfLnxWatchDogNotify(zdev_t *dev)
1034 {
1035     zfLnxSignalThread(dev, KEVENT_WATCHDOG);
1036 }
1037
1038 /* Query Durantion of Active Scan */
1039 void zfwGetActiveScanDur(zdev_t *dev, u8_t *Dur)
1040 {
1041     *Dur = 30; /* default 30 ms*/
1042 }
1043
1044 void zfwGetShowZeroLengthSSID(zdev_t *dev, u8_t *Dur)
1045 {
1046     *Dur = 0;
1047 }
1048