• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/drivers/staging/otus/
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
32extern void zfiRecv80211(zdev_t *dev, zbuf_t *buf, struct zsAdditionInfo *addInfo);
33extern void zfCoreRecv(zdev_t *dev, zbuf_t *buf, struct zsAdditionInfo *addInfo);
34extern void zfIdlChkRsp(zdev_t *dev, u32_t *rsp, u16_t rspLen);
35extern void zfIdlRsp(zdev_t *dev, u32_t *rsp, u16_t rspLen);
36
37
38
39/*extern struct zsWdsStruct wds[ZM_WDS_PORT_NUMBER];*/
40extern struct zsVapStruct vap[ZM_VAP_PORT_NUMBER];
41
42u32_t zfLnxUsbSubmitTxData(zdev_t *dev);
43u32_t zfLnxUsbIn(zdev_t *dev, urb_t *urb, zbuf_t *buf);
44u32_t zfLnxSubmitRegInUrb(zdev_t *dev);
45u32_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);
47u32_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
51u16_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
75void 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
97u16_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
111UsbTxQ_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
142u16_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
184zbuf_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
211u32_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
237void 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
261void 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	return;
302	}
303
304    if (urb->actual_length == 0) {
305	printk(KERN_ERR "Get an URB whose length is zero");
306	status = -1;
307    }
308
309    /* Dequeue skb buffer */
310    buf = zfLnxGetUsbRxBuffer(dev);
311
312    /*zfwBufSetSize(dev, buf, urb->actual_length);*/
313#ifdef NET_SKBUFF_DATA_USES_OFFSET
314    buf->tail = 0;
315    buf->len = 0;
316#else
317    buf->tail = buf->data;
318    buf->len = 0;
319#endif
320
321    BUG_ON((buf->tail + urb->actual_length) > buf->end);
322
323    skb_put(buf, urb->actual_length);
324
325#if ZM_USB_STREAM_MODE == 1
326    if (remain_len != 0) {
327	zbuf_t *remain_buf = macp->reamin_buf;
328
329	index = remain_len;
330	remain_len -= check_pad;
331
332	/*  Copy data */
333	memcpy(&(remain_buf->data[check_len]), buf->data, remain_len);
334	check_len += remain_len;
335	remain_len = 0;
336
337	rxBufPool[rxBufPoolIndex++] = remain_buf;
338    }
339
340    while (index < urb->actual_length) {
341	pkt_len = buf->data[index] + (buf->data[index+1] << 8);
342	pkt_tag = buf->data[index+2] + (buf->data[index+3] << 8);
343
344	if (pkt_tag == 0x4e00) {
345		int pad_len;
346
347		/*printk("Get a packet, index: %d, pkt_len: 0x%04x\n", index, pkt_len);*/
348
349		pad_len = 4 - (pkt_len & 0x3);
350
351		if (pad_len == 4)
352		pad_len = 0;
353
354		chk_idx = index;
355		index = index + 4 + pkt_len + pad_len;
356
357		if (index > ZM_MAX_RX_BUFFER_SIZE) {
358			remain_len = index - ZM_MAX_RX_BUFFER_SIZE; /* - pad_len;*/
359			check_len = ZM_MAX_RX_BUFFER_SIZE - chk_idx - 4;
360			check_pad = pad_len;
361
362			/* Allocate a skb buffer */
363			/*new_buf = zfwBufAllocate(dev, ZM_MAX_RX_BUFFER_SIZE);*/
364			new_buf = dev_alloc_skb(ZM_MAX_RX_BUFFER_SIZE);
365
366			/* Set skb buffer length */
367			#ifdef NET_SKBUFF_DATA_USES_OFFSET
368			new_buf->tail = 0;
369			new_buf->len = 0;
370			#else
371			new_buf->tail = new_buf->data;
372			new_buf->len = 0;
373			#endif
374
375			skb_put(new_buf, pkt_len);
376
377			/* Copy the buffer */
378			memcpy(new_buf->data, &(buf->data[chk_idx+4]), check_len);
379
380			/* Record the buffer pointer */
381			macp->reamin_buf = new_buf;
382		} else  {
383			#ifdef ZM_DONT_COPY_RX_BUFFER
384			if (rxBufPoolIndex == 0) {
385				new_buf = skb_clone(buf, GFP_ATOMIC);
386
387				new_buf->data = &(buf->data[chk_idx+4]);
388				new_buf->len = pkt_len;
389			} else  {
390				#endif
391				/* Allocate a skb buffer */
392				new_buf = dev_alloc_skb(ZM_MAX_RX_BUFFER_SIZE);
393
394				/* Set skb buffer length */
395				#ifdef NET_SKBUFF_DATA_USES_OFFSET
396				new_buf->tail = 0;
397				new_buf->len = 0;
398				#else
399				new_buf->tail = new_buf->data;
400				new_buf->len = 0;
401				#endif
402
403				skb_put(new_buf, pkt_len);
404
405				/* Copy the buffer */
406				memcpy(new_buf->data, &(buf->data[chk_idx+4]), pkt_len);
407
408				#ifdef ZM_DONT_COPY_RX_BUFFER
409				}
410			#endif
411			rxBufPool[rxBufPoolIndex++] = new_buf;
412			}
413		} else {
414			printk(KERN_ERR "Can't find tag, pkt_len: 0x%04x, tag: 0x%04x\n", pkt_len, pkt_tag);
415
416			/* Free buffer */
417			dev_kfree_skb_any(buf);
418
419			/* Allocate a skb buffer */
420			new_buf = dev_alloc_skb(ZM_MAX_RX_BUFFER_SIZE);
421
422			/* Enqueue skb buffer */
423			zfLnxPutUsbRxBuffer(dev, new_buf);
424
425			/* Submit a Rx urb */
426			zfLnxUsbIn(dev, urb, new_buf);
427
428			return;
429			}
430		}
431
432    /* Free buffer */
433    dev_kfree_skb_any(buf);
434#endif
435
436    /* Allocate a skb buffer */
437    new_buf = dev_alloc_skb(ZM_MAX_RX_BUFFER_SIZE);
438
439    /* Enqueue skb buffer */
440    zfLnxPutUsbRxBuffer(dev, new_buf);
441
442    /* Submit a Rx urb */
443    zfLnxUsbIn(dev, urb, new_buf);
444
445#if ZM_USB_STREAM_MODE == 1
446    for (ii = 0; ii < rxBufPoolIndex; ii++) {
447	macp->usbCbFunctions.zfcbUsbRecv(dev, rxBufPool[ii]);
448    }
449#else
450    /* pass data to upper layer */
451    macp->usbCbFunctions.zfcbUsbRecv(dev, buf);
452#endif
453}
454
455void zfLnxUsbRegOut_callback(urb_t *urb)
456{
457    /*dev_t* dev = urb->context;*/
458
459	/*printk(KERN_ERR "zfwUsbRegOut_callback\n");*/
460}
461
462void zfLnxUsbRegIn_callback(urb_t *urb)
463{
464    zdev_t *dev = urb->context;
465    u32_t rsp[64/4];
466    int status;
467    struct usbdrv_private *macp = dev->ml_priv;
468
469    /* Check status for URB */
470    if (urb->status != 0) {
471	printk("zfLnxUsbRegIn_callback() : status=0x%x\n", urb->status);
472	if ((urb->status != -ENOENT) && (urb->status != -ECONNRESET) && (urb->status != -ESHUTDOWN)) {
473		if (urb->status == -EPIPE) {
474			/*printk(KERN_ERR "nonzero read bulk status received: -EPIPE");*/
475			status = -1;
476		}
477
478		if (urb->status == -EPROTO) {
479			/*printk(KERN_ERR "nonzero read bulk status received: -EPROTO");*/
480			status = -1;
481		}
482	}
483
484	/*printk(KERN_ERR "urb->status: 0x%08x\n", urb->status);*/
485	return;
486	}
487
488    if (urb->actual_length == 0) {
489	printk(KERN_ERR "Get an URB whose length is zero");
490	status = -1;
491    }
492
493    /* Copy data into respone buffer */
494    memcpy(rsp, macp->regUsbReadBuf, urb->actual_length);
495
496    /* Notify to upper layer */
497    /*zfIdlChkRsp(dev, rsp, (u16_t)urb->actual_length);*/
498    /*zfiUsbRegIn(dev, rsp, (u16_t)urb->actual_length);*/
499    macp->usbCbFunctions.zfcbUsbRegIn(dev, rsp, (u16_t)urb->actual_length);
500
501    /* Issue another USB IN URB */
502    zfLnxSubmitRegInUrb(dev);
503}
504
505u32_t zfLnxSubmitRegInUrb(zdev_t *dev)
506{
507    u32_t ret;
508    struct usbdrv_private *macp = dev->ml_priv;
509
510    /* Submit a rx urb
511    //ret = zfLnxUsbSubmitBulkUrb(macp->RegInUrb, macp->udev,
512    //        USB_REG_IN_PIPE, USB_DIR_IN, macp->regUsbReadBuf,
513    //        ZM_USB_REG_MAX_BUF_SIZE, zfLnxUsbRegIn_callback, dev);
514    //CWYang(-)
515    //if (ret != 0)
516    //    printk("zfwUsbSubmitBulkUrb fail, status: 0x%08x\n", (int)ret);*/
517
518    ret = zfLnxUsbSubmitIntUrb(macp->RegInUrb, macp->udev,
519	USB_REG_IN_PIPE, USB_DIR_IN, macp->regUsbReadBuf,
520	ZM_USB_REG_MAX_BUF_SIZE, zfLnxUsbRegIn_callback, dev, 1);
521
522    return ret;
523}
524
525u32_t zfLnxUsbSubmitTxData(zdev_t *dev)
526{
527    u32_t i;
528    u32_t ret;
529    u16_t freeTxUrb;
530    u8_t *puTxBuf = NULL;
531    UsbTxQ_t *TxData;
532    int len = 0;
533    struct usbdrv_private *macp = dev->ml_priv;
534#if ZM_USB_TX_STREAM_MODE == 1
535    u8_t               ii;
536    u16_t              offset = 0;
537    u16_t              usbTxAggCnt;
538    u16_t              *pUsbTxHdr;
539    UsbTxQ_t           *TxQPool[ZM_MAX_TX_AGGREGATE_NUM];
540#endif
541
542    /* First check whether there is a free URB */
543    freeTxUrb = zfLnxGetFreeTxUrb(dev);
544
545    /* If there is no any free Tx Urb */
546    if (freeTxUrb == 0xffff) {
547	/*printk(KERN_ERR "Can't get free Tx Urb\n");
548	//printk("CWY - Can't get free Tx Urb\n");*/
549	return 0xffff;
550    }
551
552#if ZM_USB_TX_STREAM_MODE == 1
553    usbTxAggCnt = zfLnxCheckTxBufferCnt(dev);
554
555    if (usbTxAggCnt >= ZM_MAX_TX_AGGREGATE_NUM) {
556	usbTxAggCnt = ZM_MAX_TX_AGGREGATE_NUM;
557    } else {
558	usbTxAggCnt = 1;
559    }
560
561    /*printk("usbTxAggCnt: %d\n", usbTxAggCnt);*/
562#endif
563
564#if ZM_USB_TX_STREAM_MODE == 1
565    for (ii = 0; ii < usbTxAggCnt; ii++) {
566#endif
567    /* Dequeue the packet from UsbTxBufQ */
568    TxData = zfLnxGetUsbTxBuffer(dev);
569    if (TxData == NULL) {
570	/* Give the urb back */
571	zfLnxPutTxUrb(dev);
572	return 0xffff;
573    }
574
575    /* Point to the freeTxUrb buffer */
576    puTxBuf = macp->txUsbBuf[freeTxUrb];
577
578#if ZM_USB_TX_STREAM_MODE == 1
579    puTxBuf += offset;
580    pUsbTxHdr = (u16_t *)puTxBuf;
581
582    /* Add the packet length and tag information */
583    *pUsbTxHdr++ = TxData->hdrlen + TxData->snapLen +
584	(TxData->buf->len - TxData->offset) +  TxData->tailLen;
585
586    *pUsbTxHdr++ = 0x697e;
587
588    puTxBuf += 4;
589#endif /* #ifdef ZM_USB_TX_STREAM_MODE*/
590
591    /* Copy WLAN header and packet buffer into USB buffer */
592    for (i = 0; i < TxData->hdrlen; i++) {
593	*puTxBuf++ = TxData->hdr[i];
594    }
595
596    /* Copy SNAP header */
597    for (i = 0; i < TxData->snapLen; i++) {
598	*puTxBuf++ = TxData->snap[i];
599    }
600
601    /* Copy packet buffer */
602    for (i = 0; i < TxData->buf->len - TxData->offset; i++) {
603	/*puTxBuf++ = zmw_rx_buf_readb(dev, TxData->buf, i);*/
604	*puTxBuf++ = *(u8_t *)((u8_t *)TxData->buf->data+i+TxData->offset);
605    }
606
607    /* Copy tail */
608    for (i = 0; i < TxData->tailLen; i++) {
609	*puTxBuf++ = TxData->tail[i];
610    }
611
612    len = TxData->hdrlen+TxData->snapLen+TxData->buf->len+TxData->tailLen-TxData->offset;
613
614
615#if ZM_USB_TX_STREAM_MODE == 1
616    /* Add the Length and Tag*/
617    len += 4;
618
619    /*printk("%d packet, length: %d\n", ii+1, len);*/
620
621    if (ii < (ZM_MAX_TX_AGGREGATE_NUM-1)) {
622	/* Pad the buffer to firmware descriptor boundary */
623	offset += (((len-1) / 4) + 1) * 4;
624    }
625
626    if (ii == (ZM_MAX_TX_AGGREGATE_NUM-1)) {
627	len += offset;
628    }
629
630    TxQPool[ii] = TxData;
631
632    /*DbgPrint("%d packet, offset: %d\n", ii+1, pUsbTxTransfer->offset);*/
633
634    /* free packet */
635    /*zfBufFree(dev, txData->buf);*/
636    }
637#endif
638    /*printk("CWY - call zfwUsbSubmitBulkUrb(), len = 0x%d\n", len);*/
639    /* Submit a tx urb */
640    ret = zfLnxUsbSubmitBulkUrb(macp->WlanTxDataUrb[freeTxUrb], macp->udev,
641	USB_WLAN_TX_PIPE, USB_DIR_OUT, macp->txUsbBuf[freeTxUrb],
642	len, zfLnxUsbDataOut_callback, dev);
643    /*CWYang(-)
644    //if (ret != 0)
645    //    printk("zfwUsbSubmitBulkUrb fail, status: 0x%08x\n", (int)ret);*/
646
647    /* free packet */
648    /*dev_kfree_skb_any(TxData->buf);*/
649#if ZM_USB_TX_STREAM_MODE == 1
650    for (ii = 0; ii < usbTxAggCnt; ii++)
651	macp->usbCbFunctions.zfcbUsbOutComplete(dev, TxQPool[ii]->buf, 1, TxQPool[ii]->hdr);
652#else
653    macp->usbCbFunctions.zfcbUsbOutComplete(dev, TxData->buf, 1, TxData->hdr);
654#endif
655
656    return ret;
657}
658
659
660
661u32_t zfLnxUsbIn(zdev_t *dev, urb_t *urb, zbuf_t *buf)
662{
663    u32_t ret;
664    struct usbdrv_private *macp = dev->ml_priv;
665
666    /* Submit a rx urb */
667    ret = zfLnxUsbSubmitBulkUrb(urb, macp->udev, USB_WLAN_RX_PIPE,
668	USB_DIR_IN, buf->data, ZM_MAX_RX_BUFFER_SIZE,
669	zfLnxUsbDataIn_callback, dev);
670    /*CWYang(-)
671    //if (ret != 0)
672    //    printk("zfwUsbSubmitBulkUrb fail, status: 0x%08x\n", (int)ret);*/
673
674    return ret;
675}
676
677u32_t zfLnxUsbWriteReg(zdev_t *dev, u32_t *cmd, u16_t cmdLen)
678{
679    struct usbdrv_private *macp = dev->ml_priv;
680    u32_t ret;
681
682#ifdef ZM_CONFIG_BIG_ENDIAN
683    int ii = 0;
684
685    for (ii = 0; ii < (cmdLen>>2); ii++)
686	cmd[ii] = cpu_to_le32(cmd[ii]);
687#endif
688
689    memcpy(macp->regUsbWriteBuf, cmd, cmdLen);
690
691    /* Issue an USB Out transfer */
692    /* Submit a tx urb */
693    ret = zfLnxUsbSubmitIntUrb(macp->RegOutUrb, macp->udev,
694	USB_REG_OUT_PIPE, USB_DIR_OUT, macp->regUsbWriteBuf,
695	cmdLen, zfLnxUsbRegOut_callback, dev, 1);
696
697    return ret;
698}
699
700
701u32_t zfLnxUsbOut(zdev_t *dev, u8_t *hdr, u16_t hdrlen, u8_t *snap, u16_t snapLen,
702	u8_t *tail, u16_t tailLen, zbuf_t *buf, u16_t offset)
703{
704    u32_t ret;
705    struct usbdrv_private *macp = dev->ml_priv;
706
707    /* Check length of tail buffer */
708    /*zm_assert((tailLen <= 16));*/
709
710    /* Enqueue the packet into UsbTxBufQ */
711    if (zfLnxPutUsbTxBuffer(dev, hdr, hdrlen, snap, snapLen, tail, tailLen, buf, offset) == 0xffff) {
712	/* free packet */
713	/*printk("CWY - zfwPutUsbTxBuffer Error, free packet\n");
714	//dev_kfree_skb_any(buf);*/
715	macp->usbCbFunctions.zfcbUsbOutComplete(dev, buf, 0, hdr);
716	return 0xffff;
717	}
718
719    /*return 0;
720    //printk("CWY - call zfwUsbSubmitTxData()\n");*/
721    ret = zfLnxUsbSubmitTxData(dev);
722    return ret;
723}
724
725void zfLnxInitUsbTxQ(zdev_t *dev)
726{
727    struct usbdrv_private *macp = dev->ml_priv;
728
729    printk(KERN_ERR "zfwInitUsbTxQ\n");
730
731    /* Zero memory for UsbTxBufQ */
732    memset(macp->UsbTxBufQ, 0, sizeof(UsbTxQ_t) * ZM_MAX_TX_URB_NUM);
733
734    macp->TxBufHead = 0;
735    macp->TxBufTail = 0;
736    macp->TxUrbHead = 0;
737    macp->TxUrbTail = 0;
738    macp->TxUrbCnt = ZM_MAX_TX_URB_NUM;
739}
740
741void zfLnxInitUsbRxQ(zdev_t *dev)
742{
743    u16_t i;
744    zbuf_t *buf;
745    struct usbdrv_private *macp = dev->ml_priv;
746
747    /* Zero memory for UsbRxBufQ */
748    memset(macp->UsbRxBufQ, 0, sizeof(zbuf_t *) * ZM_MAX_RX_URB_NUM);
749
750    macp->RxBufHead = 0;
751
752    for (i = 0; i < ZM_MAX_RX_URB_NUM; i++) {
753	/*buf = zfwBufAllocate(dev, ZM_MAX_RX_BUFFER_SIZE);*/
754	buf = dev_alloc_skb(ZM_MAX_RX_BUFFER_SIZE);
755	macp->UsbRxBufQ[i] = buf;
756	}
757
758    /*macp->RxBufTail = ZM_MAX_RX_URB_NUM - 1;*/
759    macp->RxBufTail = 0;
760
761    /* Submit all Rx urbs */
762    for (i = 0; i < ZM_MAX_RX_URB_NUM; i++) {
763	zfLnxPutUsbRxBuffer(dev, macp->UsbRxBufQ[i]);
764	zfLnxUsbIn(dev, macp->WlanRxDataUrb[i], macp->UsbRxBufQ[i]);
765	}
766}
767
768
769
770u32_t zfLnxUsbSubmitBulkUrb(urb_t *urb, struct usb_device *usb, u16_t epnum, u16_t direction,
771	void *transfer_buffer, int buffer_length, usb_complete_t complete, void *context)
772{
773    u32_t ret;
774
775    if (direction == USB_DIR_OUT) {
776	usb_fill_bulk_urb(urb, usb, usb_sndbulkpipe(usb, epnum),
777		transfer_buffer, buffer_length, complete, context);
778
779	urb->transfer_flags |= URB_ZERO_PACKET;
780    } else {
781	usb_fill_bulk_urb(urb, usb, usb_rcvbulkpipe(usb, epnum),
782		transfer_buffer, buffer_length, complete, context);
783    }
784
785    if (epnum == 4) {
786	if (urb->hcpriv) {
787		/*printk("CWY - urb->hcpriv set by unknown reason, reset it\n");
788		//urb->hcpriv = 0;*/
789		}
790	}
791
792    ret = usb_submit_urb(urb, GFP_ATOMIC);
793    if ((epnum == 4) & (ret != 0)) {
794	/*printk("CWY - ret = %x\n", ret);*/
795    }
796    return ret;
797}
798
799u32_t zfLnxUsbSubmitIntUrb(urb_t *urb, struct usb_device *usb, u16_t epnum, u16_t direction,
800	void *transfer_buffer, int buffer_length, usb_complete_t complete, void *context,
801	u32_t interval)
802{
803    u32_t ret;
804
805    if (direction == USB_DIR_OUT) {
806	usb_fill_int_urb(urb, usb, usb_sndbulkpipe(usb, epnum),
807		transfer_buffer, buffer_length, complete, context, interval);
808    } else {
809	usb_fill_int_urb(urb, usb, usb_rcvbulkpipe(usb, epnum),
810	transfer_buffer, buffer_length, complete, context, interval);
811    }
812
813    ret = usb_submit_urb(urb, GFP_ATOMIC);
814
815    return ret;
816}
817
818#ifdef ZM_ENABLE_CENC
819int zfLnxCencSendMsg(struct sock *netlink_sk, u_int8_t *msg, int len)
820{
821#define COMMTYPE_GROUP   8
822#define WAI_K_MSG        0x11
823
824	int ret = -1;
825	int size;
826	unsigned char *old_tail;
827	struct sk_buff *skb;
828	struct nlmsghdr *nlh;
829	char *pos = NULL;
830
831	size = NLMSG_SPACE(len);
832	skb = alloc_skb(size, GFP_ATOMIC);
833
834	if (skb == NULL) {
835		printk("dev_alloc_skb failure \n");
836		goto out;
837	}
838	old_tail = skb->tail;
839
840	/* */
841	nlh = NLMSG_PUT(skb, 0, 0, WAI_K_MSG, size-sizeof(*nlh));
842	pos = NLMSG_DATA(nlh);
843
844	/* */
845	memcpy(pos, msg,  len);
846	/* */
847	nlh->nlmsg_len = skb->tail - old_tail;
848	NETLINK_CB(skb).dst_group = COMMTYPE_GROUP;
849	netlink_broadcast(netlink_sk, skb, 0, COMMTYPE_GROUP, GFP_ATOMIC);
850	ret = 0;
851out:
852	return ret;
853nlmsg_failure: /* */
854	kfree_skb(skb);
855	goto out;
856
857#undef COMMTYPE_GROUP
858#undef WAI_K_MSG
859}
860#endif /*ZM_ENABLE_CENC*/
861
862/* Simply return 0xffff if VAP function is not supported */
863u16_t zfLnxGetVapId(zdev_t *dev)
864{
865    u16_t i;
866
867    for (i = 0; i < ZM_VAP_PORT_NUMBER; i++) {
868	if (vap[i].dev == dev) {
869		return i;
870		}
871	}
872	return 0xffff;
873}
874
875u32_t zfwReadReg(zdev_t *dev, u32_t offset)
876{
877    return 0;
878}
879
880#ifndef INIT_WORK
881#define work_struct tq_struct
882
883#define schedule_work(a)  schedule_task(a)
884
885#define flush_scheduled_work  flush_scheduled_tasks
886#define INIT_WORK(_wq, _routine, _data)  INIT_TQUEUE(_wq, _routine, _data)
887#define PREPARE_WORK(_wq, _routine, _data)  PREPARE_TQUEUE(_wq, _routine, _data)
888#endif
889
890#define KEVENT_WATCHDOG        0x00000001
891
892u32_t smp_kevent_Lock = 0;
893
894void kevent(struct work_struct *work)
895{
896    struct usbdrv_private *macp =
897	container_of(work, struct usbdrv_private, kevent);
898	zdev_t *dev = macp->device;
899
900    if (test_and_set_bit(0, (void *)&smp_kevent_Lock)) {
901	/*schedule_work(&macp->kevent);*/
902	return;
903    }
904
905    down(&macp->ioctl_sem);
906
907    if (test_and_clear_bit(KEVENT_WATCHDOG, &macp->kevent_flags)) {
908    extern u16_t zfHpStartRecv(zdev_t *dev);
909	/*zfiHwWatchDogReinit(dev);*/
910	printk(("\n ************ Hw watchDog occur!! ************** \n"));
911	zfiWlanSuspend(dev);
912	zfiWlanResume(dev , 0);
913	zfHpStartRecv(dev);
914    }
915
916    clear_bit(0, (void *)&smp_kevent_Lock);
917    up(&macp->ioctl_sem);
918}
919
920/************************************************************************/
921/*                                                                      */
922/*    FUNCTION DESCRIPTION                 zfLnxCreateThread            */
923/*      Create a Thread                                                 */
924/*                                                                      */
925/*    INPUTS                                                            */
926/*      dev : device pointer                                            */
927/*                                                                      */
928/*    OUTPUTS                                                           */
929/*      always 0                                                        */
930/*                                                                      */
931/*    AUTHOR                                                            */
932/*      Yuan-Gu Wei         Atheros Communications, INC.    2007.3      */
933/*                                                                      */
934/************************************************************************/
935u8_t zfLnxCreateThread(zdev_t *dev)
936{
937    struct usbdrv_private *macp = dev->ml_priv;
938
939    /* Create Mutex and keventd */
940    INIT_WORK(&macp->kevent, kevent);
941    init_MUTEX(&macp->ioctl_sem);
942
943    return 0;
944}
945
946/************************************************************************/
947/*                                                                      */
948/*    FUNCTION DESCRIPTION                 zfLnxSignalThread            */
949/*      Signal Thread with Flag                                         */
950/*                                                                      */
951/*    INPUTS                                                            */
952/*      dev : device pointer                                            */
953/*      flag : signal thread flag                                       */
954/*                                                                      */
955/*    OUTPUTS                                                           */
956/*      none                                                            */
957/*                                                                      */
958/*    AUTHOR                                                            */
959/*      Yuan-Gu Wei         Atheros Communications, INC.    2007.3      */
960/*                                                                      */
961/************************************************************************/
962void zfLnxSignalThread(zdev_t *dev, int flag)
963{
964    struct usbdrv_private *macp = dev->ml_priv;
965
966    if (macp == NULL) {
967	printk("macp is NULL\n");
968	return;
969    }
970
971    if (0 && macp->kevent_ready != 1) {
972	printk("Kevent not ready\n");
973	return;
974    }
975
976    set_bit(flag, &macp->kevent_flags);
977
978    if (!schedule_work(&macp->kevent)) {
979	/*Fails is Normal
980	//printk(KERN_ERR "schedule_task failed, flag = %x\n", flag);*/
981	}
982}
983
984/* Notify wrapper todo redownload firmware and reinit procedure when */
985/* hardware watchdog occur : zfiHwWatchDogReinit() */
986void zfLnxWatchDogNotify(zdev_t *dev)
987{
988    zfLnxSignalThread(dev, KEVENT_WATCHDOG);
989}
990
991/* Query Durantion of Active Scan */
992void zfwGetActiveScanDur(zdev_t *dev, u8_t *Dur)
993{
994    *Dur = 30; /* default 30 ms*/
995}
996
997void zfwGetShowZeroLengthSSID(zdev_t *dev, u8_t *Dur)
998{
999    *Dur = 0;
1000}
1001