Commit | Line | Data |
---|---|---|
4bd43f50 LR |
1 | /* |
2 | * Copyright (c) 2007-2008 Atheros Communications Inc. | |
3 | * | |
4 | * Permission to use, copy, modify, and/or distribute this software for any | |
5 | * purpose with or without fee is hereby granted, provided that the above | |
6 | * copyright notice and this permission notice appear in all copies. | |
7 | * | |
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
15 | */ | |
16 | /* Module Name : wwrap.c */ | |
17 | /* Abstract */ | |
18 | /* This module contains wrapper functions. */ | |
19 | /* */ | |
20 | /* NOTES */ | |
21 | /* Platform dependent. */ | |
22 | /* */ | |
23 | ||
24 | /* Please include your header files here */ | |
25 | #include "oal_dt.h" | |
26 | #include "usbdrv.h" | |
27 | ||
28 | #include <linux/netlink.h> | |
4bd43f50 | 29 | #include <net/iw_handler.h> |
4bd43f50 | 30 | |
4bd43f50 LR |
31 | extern void zfiRecv80211(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* addInfo); |
32 | extern void zfCoreRecv(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* addInfo); | |
33 | extern void zfIdlChkRsp(zdev_t* dev, u32_t* rsp, u16_t rspLen); | |
34 | extern void zfIdlRsp(zdev_t* dev, u32_t *rsp, u16_t rspLen); | |
35 | ||
36 | ||
37 | ||
38 | //extern struct zsWdsStruct wds[ZM_WDS_PORT_NUMBER]; | |
39 | extern struct zsVapStruct vap[ZM_VAP_PORT_NUMBER]; | |
40 | ||
41 | u32_t zfLnxUsbSubmitTxData(zdev_t* dev); | |
42 | u32_t zfLnxUsbIn(zdev_t* dev, urb_t *urb, zbuf_t *buf); | |
43 | u32_t zfLnxSubmitRegInUrb(zdev_t *dev); | |
44 | u32_t zfLnxUsbSubmitBulkUrb(urb_t *urb, struct usb_device *usb, u16_t epnum, u16_t direction, | |
45 | void *transfer_buffer, int buffer_length, usb_complete_t complete, void *context); | |
46 | u32_t zfLnxUsbSubmitIntUrb(urb_t *urb, struct usb_device *usb, u16_t epnum, u16_t direction, | |
47 | void *transfer_buffer, int buffer_length, usb_complete_t complete, void *context, | |
48 | u32_t interval); | |
49 | ||
50 | u16_t zfLnxGetFreeTxUrb(zdev_t *dev) | |
51 | { | |
da3e8908 | 52 | struct usbdrv_private *macp = dev->ml_priv; |
4bd43f50 LR |
53 | u16_t idx; |
54 | unsigned long irqFlag; | |
55 | ||
da3e8908 | 56 | spin_lock_irqsave(&macp->cs_lock, irqFlag); |
4bd43f50 LR |
57 | |
58 | //idx = ((macp->TxUrbTail + 1) & (ZM_MAX_TX_URB_NUM - 1)); | |
59 | ||
60 | //if (idx != macp->TxUrbHead) | |
61 | if (macp->TxUrbCnt != 0) | |
62 | { | |
63 | idx = macp->TxUrbTail; | |
64 | macp->TxUrbTail = ((macp->TxUrbTail + 1) & (ZM_MAX_TX_URB_NUM - 1)); | |
65 | macp->TxUrbCnt--; | |
66 | } | |
67 | else | |
68 | { | |
69 | //printk(KERN_ERR "macp->TxUrbCnt: %d\n", macp->TxUrbCnt); | |
70 | idx = 0xffff; | |
71 | } | |
72 | ||
da3e8908 | 73 | spin_unlock_irqrestore(&macp->cs_lock, irqFlag); |
4bd43f50 LR |
74 | return idx; |
75 | } | |
76 | ||
77 | void zfLnxPutTxUrb(zdev_t *dev) | |
78 | { | |
da3e8908 | 79 | struct usbdrv_private *macp = dev->ml_priv; |
4bd43f50 LR |
80 | u16_t idx; |
81 | unsigned long irqFlag; | |
82 | ||
da3e8908 | 83 | spin_lock_irqsave(&macp->cs_lock, irqFlag); |
4bd43f50 LR |
84 | |
85 | idx = ((macp->TxUrbHead + 1) & (ZM_MAX_TX_URB_NUM - 1)); | |
86 | ||
87 | //if (idx != macp->TxUrbTail) | |
88 | if (macp->TxUrbCnt < ZM_MAX_TX_URB_NUM) | |
89 | { | |
90 | macp->TxUrbHead = idx; | |
91 | macp->TxUrbCnt++; | |
92 | } | |
93 | else | |
94 | { | |
95 | printk("UsbTxUrbQ inconsistent: TxUrbHead: %d, TxUrbTail: %d\n", | |
96 | macp->TxUrbHead, macp->TxUrbTail); | |
97 | } | |
98 | ||
da3e8908 | 99 | spin_unlock_irqrestore(&macp->cs_lock, irqFlag); |
4bd43f50 LR |
100 | } |
101 | ||
102 | u16_t zfLnxCheckTxBufferCnt(zdev_t *dev) | |
103 | { | |
da3e8908 | 104 | struct usbdrv_private *macp = dev->ml_priv; |
4bd43f50 LR |
105 | u16_t TxBufCnt; |
106 | unsigned long irqFlag; | |
107 | ||
da3e8908 | 108 | spin_lock_irqsave(&macp->cs_lock, irqFlag); |
4bd43f50 LR |
109 | |
110 | TxBufCnt = macp->TxBufCnt; | |
111 | ||
da3e8908 | 112 | spin_unlock_irqrestore(&macp->cs_lock, irqFlag); |
4bd43f50 LR |
113 | return TxBufCnt; |
114 | } | |
115 | ||
116 | UsbTxQ_t *zfLnxGetUsbTxBuffer(zdev_t *dev) | |
117 | { | |
da3e8908 | 118 | struct usbdrv_private *macp = dev->ml_priv; |
4bd43f50 LR |
119 | u16_t idx; |
120 | UsbTxQ_t *TxQ; | |
121 | unsigned long irqFlag; | |
122 | ||
da3e8908 | 123 | spin_lock_irqsave(&macp->cs_lock, irqFlag); |
4bd43f50 LR |
124 | |
125 | idx = ((macp->TxBufHead+1) & (ZM_MAX_TX_BUF_NUM - 1)); | |
126 | ||
127 | //if (idx != macp->TxBufTail) | |
128 | if (macp->TxBufCnt > 0) | |
129 | { | |
130 | //printk("CWY - zfwGetUsbTxBuffer ,macp->TxBufCnt = %d\n", macp->TxBufCnt); | |
131 | TxQ = (UsbTxQ_t *)&(macp->UsbTxBufQ[macp->TxBufHead]); | |
132 | macp->TxBufHead = ((macp->TxBufHead+1) & (ZM_MAX_TX_BUF_NUM - 1)); | |
133 | macp->TxBufCnt--; | |
134 | } | |
135 | else | |
136 | { | |
137 | if (macp->TxBufHead != macp->TxBufTail) | |
138 | { | |
139 | printk(KERN_ERR "zfwGetUsbTxBuf UsbTxBufQ inconsistent: TxBufHead: %d, TxBufTail: %d\n", | |
140 | macp->TxBufHead, macp->TxBufTail); | |
141 | } | |
142 | ||
da3e8908 | 143 | spin_unlock_irqrestore(&macp->cs_lock, irqFlag); |
4bd43f50 LR |
144 | return NULL; |
145 | } | |
146 | ||
da3e8908 | 147 | spin_unlock_irqrestore(&macp->cs_lock, irqFlag); |
4bd43f50 LR |
148 | return TxQ; |
149 | } | |
150 | ||
151 | u16_t zfLnxPutUsbTxBuffer(zdev_t *dev, u8_t *hdr, u16_t hdrlen, | |
152 | u8_t *snap, u16_t snapLen, u8_t *tail, u16_t tailLen, | |
153 | zbuf_t *buf, u16_t offset) | |
154 | { | |
da3e8908 | 155 | struct usbdrv_private *macp = dev->ml_priv; |
4bd43f50 LR |
156 | u16_t idx; |
157 | UsbTxQ_t *TxQ; | |
158 | unsigned long irqFlag; | |
159 | ||
da3e8908 | 160 | spin_lock_irqsave(&macp->cs_lock, irqFlag); |
4bd43f50 LR |
161 | |
162 | idx = ((macp->TxBufTail+1) & (ZM_MAX_TX_BUF_NUM - 1)); | |
163 | ||
164 | /* For Tx debug */ | |
165 | //zm_assert(macp->TxBufCnt >= 0); // deleted because of always true | |
166 | ||
167 | //if (idx != macp->TxBufHead) | |
168 | if (macp->TxBufCnt < ZM_MAX_TX_BUF_NUM) | |
169 | { | |
170 | //printk("CWY - zfwPutUsbTxBuffer ,macp->TxBufCnt = %d\n", macp->TxBufCnt); | |
171 | TxQ = (UsbTxQ_t *)&(macp->UsbTxBufQ[macp->TxBufTail]); | |
172 | memcpy(TxQ->hdr, hdr, hdrlen); | |
173 | TxQ->hdrlen = hdrlen; | |
174 | memcpy(TxQ->snap, snap, snapLen); | |
175 | TxQ->snapLen = snapLen; | |
176 | memcpy(TxQ->tail, tail, tailLen); | |
177 | TxQ->tailLen = tailLen; | |
178 | TxQ->buf = buf; | |
179 | TxQ->offset = offset; | |
180 | ||
181 | macp->TxBufTail = ((macp->TxBufTail+1) & (ZM_MAX_TX_BUF_NUM - 1)); | |
182 | macp->TxBufCnt++; | |
183 | } | |
184 | else | |
185 | { | |
186 | printk(KERN_ERR "zfLnxPutUsbTxBuffer UsbTxBufQ inconsistent: TxBufHead: %d, TxBufTail: %d, TxBufCnt: %d\n", | |
187 | macp->TxBufHead, macp->TxBufTail, macp->TxBufCnt); | |
da3e8908 | 188 | spin_unlock_irqrestore(&macp->cs_lock, irqFlag); |
4bd43f50 LR |
189 | return 0xffff; |
190 | } | |
191 | ||
da3e8908 | 192 | spin_unlock_irqrestore(&macp->cs_lock, irqFlag); |
4bd43f50 LR |
193 | return 0; |
194 | } | |
195 | ||
196 | zbuf_t *zfLnxGetUsbRxBuffer(zdev_t *dev) | |
197 | { | |
da3e8908 | 198 | struct usbdrv_private *macp = dev->ml_priv; |
4bd43f50 LR |
199 | //u16_t idx; |
200 | zbuf_t *buf; | |
201 | unsigned long irqFlag; | |
202 | ||
da3e8908 | 203 | spin_lock_irqsave(&macp->cs_lock, irqFlag); |
4bd43f50 LR |
204 | |
205 | //idx = ((macp->RxBufHead+1) & (ZM_MAX_RX_URB_NUM - 1)); | |
206 | ||
207 | //if (idx != macp->RxBufTail) | |
208 | if (macp->RxBufCnt != 0) | |
209 | { | |
210 | buf = macp->UsbRxBufQ[macp->RxBufHead]; | |
211 | macp->RxBufHead = ((macp->RxBufHead+1) & (ZM_MAX_RX_URB_NUM - 1)); | |
212 | macp->RxBufCnt--; | |
213 | } | |
214 | else | |
215 | { | |
216 | printk("RxBufQ inconsistent: RxBufHead: %d, RxBufTail: %d\n", | |
217 | macp->RxBufHead, macp->RxBufTail); | |
da3e8908 | 218 | spin_unlock_irqrestore(&macp->cs_lock, irqFlag); |
4bd43f50 LR |
219 | return NULL; |
220 | } | |
221 | ||
da3e8908 | 222 | spin_unlock_irqrestore(&macp->cs_lock, irqFlag); |
4bd43f50 LR |
223 | return buf; |
224 | } | |
225 | ||
226 | u32_t zfLnxPutUsbRxBuffer(zdev_t *dev, zbuf_t *buf) | |
227 | { | |
da3e8908 | 228 | struct usbdrv_private *macp = dev->ml_priv; |
4bd43f50 LR |
229 | u16_t idx; |
230 | unsigned long irqFlag; | |
231 | ||
da3e8908 | 232 | spin_lock_irqsave(&macp->cs_lock, irqFlag); |
4bd43f50 LR |
233 | |
234 | idx = ((macp->RxBufTail+1) & (ZM_MAX_RX_URB_NUM - 1)); | |
235 | ||
236 | //if (idx != macp->RxBufHead) | |
237 | if (macp->RxBufCnt != ZM_MAX_RX_URB_NUM) | |
238 | { | |
239 | macp->UsbRxBufQ[macp->RxBufTail] = buf; | |
240 | macp->RxBufTail = idx; | |
241 | macp->RxBufCnt++; | |
242 | } | |
243 | else | |
244 | { | |
245 | printk("RxBufQ inconsistent: RxBufHead: %d, RxBufTail: %d\n", | |
246 | macp->RxBufHead, macp->RxBufTail); | |
da3e8908 | 247 | spin_unlock_irqrestore(&macp->cs_lock, irqFlag); |
4bd43f50 LR |
248 | return 0xffff; |
249 | } | |
250 | ||
da3e8908 | 251 | spin_unlock_irqrestore(&macp->cs_lock, irqFlag); |
4bd43f50 LR |
252 | return 0; |
253 | } | |
254 | ||
4bd43f50 | 255 | void zfLnxUsbDataOut_callback(urb_t *urb) |
4bd43f50 LR |
256 | { |
257 | zdev_t* dev = urb->context; | |
258 | //UsbTxQ_t *TxData; | |
259 | ||
260 | /* Give the urb back */ | |
261 | zfLnxPutTxUrb(dev); | |
262 | ||
263 | /* Check whether there is any pending buffer needed */ | |
264 | /* to be sent */ | |
265 | if (zfLnxCheckTxBufferCnt(dev) != 0) | |
266 | { | |
267 | //TxData = zfwGetUsbTxBuffer(dev); | |
268 | ||
269 | //if (TxData == NULL) | |
270 | //{ | |
271 | // printk("Get a NULL buffer from zfwGetUsbTxBuffer\n"); | |
272 | // return; | |
273 | //} | |
274 | //else | |
275 | //{ | |
276 | zfLnxUsbSubmitTxData(dev); | |
277 | //} | |
278 | } | |
279 | } | |
280 | ||
4bd43f50 | 281 | void zfLnxUsbDataIn_callback(urb_t *urb) |
4bd43f50 LR |
282 | { |
283 | zdev_t* dev = urb->context; | |
da3e8908 | 284 | struct usbdrv_private *macp = dev->ml_priv; |
4bd43f50 LR |
285 | zbuf_t *buf; |
286 | zbuf_t *new_buf; | |
287 | int status; | |
288 | ||
289 | #if ZM_USB_STREAM_MODE == 1 | |
290 | static int remain_len = 0, check_pad = 0, check_len = 0; | |
291 | int index = 0; | |
292 | int chk_idx; | |
293 | u16_t pkt_len; | |
294 | u16_t pkt_tag; | |
295 | u16_t ii; | |
296 | zbuf_t *rxBufPool[8]; | |
297 | u16_t rxBufPoolIndex = 0; | |
298 | #endif | |
299 | ||
300 | /* Check status for URB */ | |
301 | if (urb->status != 0){ | |
302 | printk("zfLnxUsbDataIn_callback() : status=0x%x\n", urb->status); | |
303 | if ((urb->status != -ENOENT) && (urb->status != -ECONNRESET) | |
304 | && (urb->status != -ESHUTDOWN)) | |
305 | { | |
4bd43f50 LR |
306 | if (urb->status == -EPIPE){ |
307 | //printk(KERN_ERR "nonzero read bulk status received: -EPIPE"); | |
308 | status = -1; | |
309 | } | |
310 | ||
311 | if (urb->status == -EPROTO){ | |
312 | //printk(KERN_ERR "nonzero read bulk status received: -EPROTO"); | |
313 | status = -1; | |
314 | } | |
4bd43f50 LR |
315 | } |
316 | ||
317 | //printk(KERN_ERR "urb->status: 0x%08x\n", urb->status); | |
318 | ||
319 | /* Dequeue skb buffer */ | |
320 | buf = zfLnxGetUsbRxBuffer(dev); | |
321 | dev_kfree_skb_any(buf); | |
322 | #if 0 | |
323 | /* Enqueue skb buffer */ | |
324 | zfLnxPutUsbRxBuffer(dev, buf); | |
325 | ||
326 | /* Submit a Rx urb */ | |
327 | zfLnxUsbIn(dev, urb, buf); | |
328 | #endif | |
329 | return; | |
330 | } | |
331 | ||
332 | if (urb->actual_length == 0) | |
333 | { | |
334 | printk(KERN_ERR "Get an URB whose length is zero"); | |
335 | status = -1; | |
336 | } | |
337 | ||
338 | /* Dequeue skb buffer */ | |
339 | buf = zfLnxGetUsbRxBuffer(dev); | |
340 | ||
341 | //zfwBufSetSize(dev, buf, urb->actual_length); | |
342 | #ifdef NET_SKBUFF_DATA_USES_OFFSET | |
343 | buf->tail = 0; | |
344 | buf->len = 0; | |
345 | #else | |
346 | buf->tail = buf->data; | |
347 | buf->len = 0; | |
348 | #endif | |
349 | ||
2961f24f | 350 | BUG_ON((buf->tail + urb->actual_length) > buf->end); |
4bd43f50 LR |
351 | |
352 | skb_put(buf, urb->actual_length); | |
353 | ||
354 | #if ZM_USB_STREAM_MODE == 1 | |
355 | if (remain_len != 0) | |
356 | { | |
357 | zbuf_t *remain_buf = macp->reamin_buf; | |
358 | ||
359 | index = remain_len; | |
360 | remain_len -= check_pad; | |
361 | ||
362 | /* Copy data */ | |
363 | memcpy(&(remain_buf->data[check_len]), buf->data, remain_len); | |
364 | check_len += remain_len; | |
365 | remain_len = 0; | |
366 | ||
367 | rxBufPool[rxBufPoolIndex++] = remain_buf; | |
368 | } | |
369 | ||
370 | while(index < urb->actual_length) | |
371 | { | |
372 | pkt_len = buf->data[index] + (buf->data[index+1] << 8); | |
373 | pkt_tag = buf->data[index+2] + (buf->data[index+3] << 8); | |
374 | ||
375 | if (pkt_tag == 0x4e00) | |
376 | { | |
377 | int pad_len; | |
378 | ||
379 | //printk("Get a packet, index: %d, pkt_len: 0x%04x\n", index, pkt_len); | |
380 | #if 0 | |
381 | /* Dump data */ | |
382 | for (ii = index; ii < pkt_len+4;) | |
383 | { | |
384 | printk("%02x ", (buf->data[ii] & 0xff)); | |
385 | ||
386 | if ((++ii % 16) == 0) | |
387 | printk("\n"); | |
388 | } | |
389 | ||
390 | printk("\n"); | |
391 | #endif | |
392 | ||
393 | pad_len = 4 - (pkt_len & 0x3); | |
394 | ||
395 | if(pad_len == 4) | |
396 | pad_len = 0; | |
397 | ||
398 | chk_idx = index; | |
399 | index = index + 4 + pkt_len + pad_len; | |
400 | ||
401 | if (index > ZM_MAX_RX_BUFFER_SIZE) | |
402 | { | |
403 | remain_len = index - ZM_MAX_RX_BUFFER_SIZE; // - pad_len; | |
404 | check_len = ZM_MAX_RX_BUFFER_SIZE - chk_idx - 4; | |
405 | check_pad = pad_len; | |
406 | ||
407 | /* Allocate a skb buffer */ | |
408 | //new_buf = zfwBufAllocate(dev, ZM_MAX_RX_BUFFER_SIZE); | |
409 | new_buf = dev_alloc_skb(ZM_MAX_RX_BUFFER_SIZE); | |
410 | ||
411 | /* Set skb buffer length */ | |
412 | #ifdef NET_SKBUFF_DATA_USES_OFFSET | |
413 | new_buf->tail = 0; | |
414 | new_buf->len = 0; | |
415 | #else | |
416 | new_buf->tail = new_buf->data; | |
417 | new_buf->len = 0; | |
418 | #endif | |
419 | ||
420 | skb_put(new_buf, pkt_len); | |
421 | ||
422 | /* Copy the buffer */ | |
423 | memcpy(new_buf->data, &(buf->data[chk_idx+4]), check_len); | |
424 | ||
425 | /* Record the buffer pointer */ | |
426 | macp->reamin_buf = new_buf; | |
427 | } | |
428 | else | |
429 | { | |
430 | #ifdef ZM_DONT_COPY_RX_BUFFER | |
431 | if (rxBufPoolIndex == 0) | |
432 | { | |
433 | new_buf = skb_clone(buf, GFP_ATOMIC); | |
434 | ||
435 | new_buf->data = &(buf->data[chk_idx+4]); | |
436 | new_buf->len = pkt_len; | |
437 | } | |
438 | else | |
439 | { | |
440 | #endif | |
441 | /* Allocate a skb buffer */ | |
442 | new_buf = dev_alloc_skb(ZM_MAX_RX_BUFFER_SIZE); | |
443 | ||
444 | /* Set skb buffer length */ | |
445 | #ifdef NET_SKBUFF_DATA_USES_OFFSET | |
446 | new_buf->tail = 0; | |
447 | new_buf->len = 0; | |
448 | #else | |
449 | new_buf->tail = new_buf->data; | |
450 | new_buf->len = 0; | |
451 | #endif | |
452 | ||
453 | skb_put(new_buf, pkt_len); | |
454 | ||
455 | /* Copy the buffer */ | |
456 | memcpy(new_buf->data, &(buf->data[chk_idx+4]), pkt_len); | |
457 | ||
458 | #ifdef ZM_DONT_COPY_RX_BUFFER | |
459 | } | |
460 | #endif | |
461 | rxBufPool[rxBufPoolIndex++] = new_buf; | |
462 | } | |
463 | } | |
464 | else | |
465 | { | |
466 | printk(KERN_ERR "Can't find tag, pkt_len: 0x%04x, tag: 0x%04x\n", pkt_len, pkt_tag); | |
467 | ||
468 | /* Free buffer */ | |
469 | dev_kfree_skb_any(buf); | |
470 | ||
471 | /* Allocate a skb buffer */ | |
472 | new_buf = dev_alloc_skb(ZM_MAX_RX_BUFFER_SIZE); | |
473 | ||
474 | /* Enqueue skb buffer */ | |
475 | zfLnxPutUsbRxBuffer(dev, new_buf); | |
476 | ||
477 | /* Submit a Rx urb */ | |
478 | zfLnxUsbIn(dev, urb, new_buf); | |
479 | ||
480 | return; | |
481 | } | |
482 | } | |
483 | ||
484 | /* Free buffer */ | |
485 | dev_kfree_skb_any(buf); | |
486 | #endif | |
487 | ||
488 | /* Allocate a skb buffer */ | |
489 | new_buf = dev_alloc_skb(ZM_MAX_RX_BUFFER_SIZE); | |
490 | ||
491 | /* Enqueue skb buffer */ | |
492 | zfLnxPutUsbRxBuffer(dev, new_buf); | |
493 | ||
494 | /* Submit a Rx urb */ | |
495 | zfLnxUsbIn(dev, urb, new_buf); | |
496 | ||
497 | #if ZM_USB_STREAM_MODE == 1 | |
498 | for(ii = 0; ii < rxBufPoolIndex; ii++) | |
499 | { | |
500 | macp->usbCbFunctions.zfcbUsbRecv(dev, rxBufPool[ii]); | |
501 | } | |
502 | #else | |
503 | /* pass data to upper layer */ | |
504 | macp->usbCbFunctions.zfcbUsbRecv(dev, buf); | |
505 | #endif | |
506 | } | |
507 | ||
4bd43f50 | 508 | void zfLnxUsbRegOut_callback(urb_t *urb) |
4bd43f50 LR |
509 | { |
510 | //dev_t* dev = urb->context; | |
511 | ||
512 | //printk(KERN_ERR "zfwUsbRegOut_callback\n"); | |
513 | } | |
514 | ||
4bd43f50 | 515 | void zfLnxUsbRegIn_callback(urb_t *urb) |
4bd43f50 LR |
516 | { |
517 | zdev_t* dev = urb->context; | |
518 | u32_t rsp[64/4]; | |
519 | int status; | |
da3e8908 | 520 | struct usbdrv_private *macp = dev->ml_priv; |
4bd43f50 LR |
521 | |
522 | /* Check status for URB */ | |
523 | if (urb->status != 0){ | |
524 | printk("zfLnxUsbRegIn_callback() : status=0x%x\n", urb->status); | |
525 | if ((urb->status != -ENOENT) && (urb->status != -ECONNRESET) | |
526 | && (urb->status != -ESHUTDOWN)) | |
527 | { | |
4bd43f50 LR |
528 | if (urb->status == -EPIPE){ |
529 | //printk(KERN_ERR "nonzero read bulk status received: -EPIPE"); | |
530 | status = -1; | |
531 | } | |
532 | ||
533 | if (urb->status == -EPROTO){ | |
534 | //printk(KERN_ERR "nonzero read bulk status received: -EPROTO"); | |
535 | status = -1; | |
536 | } | |
4bd43f50 LR |
537 | } |
538 | ||
539 | //printk(KERN_ERR "urb->status: 0x%08x\n", urb->status); | |
540 | return; | |
541 | } | |
542 | ||
543 | if (urb->actual_length == 0) | |
544 | { | |
545 | printk(KERN_ERR "Get an URB whose length is zero"); | |
546 | status = -1; | |
547 | } | |
548 | ||
549 | /* Copy data into respone buffer */ | |
550 | memcpy(rsp, macp->regUsbReadBuf, urb->actual_length); | |
551 | ||
552 | /* Notify to upper layer */ | |
553 | //zfIdlChkRsp(dev, rsp, (u16_t)urb->actual_length); | |
554 | //zfiUsbRegIn(dev, rsp, (u16_t)urb->actual_length); | |
555 | macp->usbCbFunctions.zfcbUsbRegIn(dev, rsp, (u16_t)urb->actual_length); | |
556 | ||
557 | /* Issue another USB IN URB */ | |
558 | zfLnxSubmitRegInUrb(dev); | |
559 | } | |
560 | ||
561 | u32_t zfLnxSubmitRegInUrb(zdev_t *dev) | |
562 | { | |
563 | u32_t ret; | |
da3e8908 | 564 | struct usbdrv_private *macp = dev->ml_priv; |
4bd43f50 LR |
565 | |
566 | /* Submit a rx urb */ | |
567 | //ret = zfLnxUsbSubmitBulkUrb(macp->RegInUrb, macp->udev, | |
568 | // USB_REG_IN_PIPE, USB_DIR_IN, macp->regUsbReadBuf, | |
569 | // ZM_USB_REG_MAX_BUF_SIZE, zfLnxUsbRegIn_callback, dev); | |
570 | //CWYang(-) | |
571 | //if (ret != 0) | |
572 | // printk("zfwUsbSubmitBulkUrb fail, status: 0x%08x\n", (int)ret); | |
573 | ||
574 | ret = zfLnxUsbSubmitIntUrb(macp->RegInUrb, macp->udev, | |
575 | USB_REG_IN_PIPE, USB_DIR_IN, macp->regUsbReadBuf, | |
576 | ZM_USB_REG_MAX_BUF_SIZE, zfLnxUsbRegIn_callback, dev, 1); | |
577 | ||
578 | return ret; | |
579 | } | |
580 | ||
581 | u32_t zfLnxUsbSubmitTxData(zdev_t* dev) | |
582 | { | |
583 | u32_t i; | |
584 | u32_t ret; | |
585 | u16_t freeTxUrb; | |
586 | u8_t *puTxBuf = NULL; | |
587 | UsbTxQ_t *TxData; | |
588 | int len = 0; | |
da3e8908 | 589 | struct usbdrv_private *macp = dev->ml_priv; |
4bd43f50 LR |
590 | #if ZM_USB_TX_STREAM_MODE == 1 |
591 | u8_t ii; | |
592 | u16_t offset = 0; | |
593 | u16_t usbTxAggCnt; | |
594 | u16_t *pUsbTxHdr; | |
595 | UsbTxQ_t *TxQPool[ZM_MAX_TX_AGGREGATE_NUM]; | |
596 | #endif | |
597 | ||
598 | /* First check whether there is a free URB */ | |
599 | freeTxUrb = zfLnxGetFreeTxUrb(dev); | |
600 | ||
601 | /* If there is no any free Tx Urb */ | |
602 | if (freeTxUrb == 0xffff) | |
603 | { | |
604 | //printk(KERN_ERR "Can't get free Tx Urb\n"); | |
605 | //printk("CWY - Can't get free Tx Urb\n"); | |
606 | return 0xffff; | |
607 | } | |
608 | ||
609 | #if ZM_USB_TX_STREAM_MODE == 1 | |
610 | usbTxAggCnt = zfLnxCheckTxBufferCnt(dev); | |
611 | ||
612 | if (usbTxAggCnt >= ZM_MAX_TX_AGGREGATE_NUM) | |
613 | { | |
614 | usbTxAggCnt = ZM_MAX_TX_AGGREGATE_NUM; | |
615 | } | |
616 | else | |
617 | { | |
618 | usbTxAggCnt = 1; | |
619 | } | |
620 | ||
621 | //printk("usbTxAggCnt: %d\n", usbTxAggCnt); | |
622 | #endif | |
623 | ||
624 | #if ZM_USB_TX_STREAM_MODE == 1 | |
625 | for(ii = 0; ii < usbTxAggCnt; ii++) | |
626 | { | |
627 | #endif | |
628 | /* Dequeue the packet from UsbTxBufQ */ | |
629 | TxData = zfLnxGetUsbTxBuffer(dev); | |
630 | if (TxData == NULL) | |
631 | { | |
632 | /* Give the urb back */ | |
633 | zfLnxPutTxUrb(dev); | |
634 | return 0xffff; | |
635 | } | |
636 | ||
637 | /* Point to the freeTxUrb buffer */ | |
638 | puTxBuf = macp->txUsbBuf[freeTxUrb]; | |
639 | ||
640 | #if ZM_USB_TX_STREAM_MODE == 1 | |
641 | puTxBuf += offset; | |
642 | pUsbTxHdr = (u16_t *)puTxBuf; | |
643 | ||
644 | /* Add the packet length and tag information */ | |
645 | *pUsbTxHdr++ = TxData->hdrlen + TxData->snapLen + | |
646 | (TxData->buf->len - TxData->offset) + TxData->tailLen; | |
647 | ||
648 | *pUsbTxHdr++ = 0x697e; | |
649 | ||
650 | puTxBuf += 4; | |
651 | #endif // #ifdef ZM_USB_TX_STREAM_MODE | |
652 | ||
653 | /* Copy WLAN header and packet buffer into USB buffer */ | |
654 | for(i = 0; i < TxData->hdrlen; i++) | |
655 | { | |
656 | *puTxBuf++ = TxData->hdr[i]; | |
657 | } | |
658 | ||
659 | /* Copy SNAP header */ | |
660 | for(i = 0; i < TxData->snapLen; i++) | |
661 | { | |
662 | *puTxBuf++ = TxData->snap[i]; | |
663 | } | |
664 | ||
665 | /* Copy packet buffer */ | |
666 | for(i = 0; i < TxData->buf->len - TxData->offset; i++) | |
667 | { | |
668 | //*puTxBuf++ = zmw_rx_buf_readb(dev, TxData->buf, i); | |
669 | *puTxBuf++ = *(u8_t*)((u8_t*)TxData->buf->data+i+TxData->offset); | |
670 | } | |
671 | ||
672 | /* Copy tail */ | |
673 | for(i = 0; i < TxData->tailLen; i++) | |
674 | { | |
675 | *puTxBuf++ = TxData->tail[i]; | |
676 | } | |
677 | ||
678 | len = TxData->hdrlen+TxData->snapLen+TxData->buf->len+TxData->tailLen-TxData->offset; | |
679 | ||
680 | #if 0 | |
681 | if (TxData->hdrlen != 0) | |
682 | { | |
683 | puTxBuf = macp->txUsbBuf[freeTxUrb]; | |
684 | for (i = 0; i < len; i++) | |
685 | { | |
686 | printk("%02x ", puTxBuf[i]); | |
687 | if (i % 16 == 15) | |
688 | printk("\n"); | |
689 | } | |
690 | printk("\n"); | |
691 | } | |
692 | #endif | |
693 | #if 0 | |
694 | /* For debug purpose */ | |
695 | if(TxData->hdr[9] & 0x40) | |
696 | { | |
697 | int i; | |
698 | u16_t ctrlLen = TxData->hdr[0] + (TxData->hdr[1] << 8); | |
699 | ||
700 | if (ctrlLen != len + 4) | |
701 | { | |
702 | /* Dump control setting */ | |
703 | for(i = 0; i < 8; i++) | |
704 | { | |
705 | printk(KERN_ERR "0x%02x ", TxData->hdr[i]); | |
706 | } | |
707 | printk(KERN_ERR "\n"); | |
708 | ||
709 | printk(KERN_ERR "ctrLen: %d, hdrLen: %d, snapLen: %d\n", ctrlLen, TxData->hdrlen, TxData->snapLen); | |
710 | printk(KERN_ERR "bufLen: %d, tailLen: %d, len: %d\n", TxData->buf->len, TxData->tailLen, len); | |
711 | } | |
712 | } | |
713 | #endif | |
714 | ||
715 | #if ZM_USB_TX_STREAM_MODE == 1 | |
716 | // Add the Length and Tag | |
717 | len += 4; | |
718 | ||
719 | //printk("%d packet, length: %d\n", ii+1, len); | |
720 | ||
721 | if (ii < (ZM_MAX_TX_AGGREGATE_NUM-1)) | |
722 | { | |
723 | /* Pad the buffer to firmware descriptor boundary */ | |
724 | offset += (((len-1) / 4) + 1) * 4; | |
725 | } | |
726 | ||
727 | if (ii == (ZM_MAX_TX_AGGREGATE_NUM-1)) | |
728 | { | |
729 | len += offset; | |
730 | } | |
731 | ||
732 | TxQPool[ii] = TxData; | |
733 | ||
734 | //DbgPrint("%d packet, offset: %d\n", ii+1, pUsbTxTransfer->offset); | |
735 | ||
736 | /* free packet */ | |
737 | //zfBufFree(dev, txData->buf); | |
738 | } | |
739 | #endif | |
740 | //printk("CWY - call zfwUsbSubmitBulkUrb(), len = 0x%d\n", len); | |
741 | /* Submit a tx urb */ | |
742 | ret = zfLnxUsbSubmitBulkUrb(macp->WlanTxDataUrb[freeTxUrb], macp->udev, | |
743 | USB_WLAN_TX_PIPE, USB_DIR_OUT, macp->txUsbBuf[freeTxUrb], | |
744 | len, zfLnxUsbDataOut_callback, dev); | |
745 | //CWYang(-) | |
746 | //if (ret != 0) | |
747 | // printk("zfwUsbSubmitBulkUrb fail, status: 0x%08x\n", (int)ret); | |
748 | ||
749 | /* free packet */ | |
750 | //dev_kfree_skb_any(TxData->buf); | |
751 | #if ZM_USB_TX_STREAM_MODE == 1 | |
752 | for(ii = 0; ii < usbTxAggCnt; ii++) | |
753 | macp->usbCbFunctions.zfcbUsbOutComplete(dev, TxQPool[ii]->buf, 1, TxQPool[ii]->hdr); | |
754 | #else | |
755 | macp->usbCbFunctions.zfcbUsbOutComplete(dev, TxData->buf, 1, TxData->hdr); | |
756 | #endif | |
757 | ||
758 | return ret; | |
759 | } | |
760 | ||
761 | ||
762 | ||
763 | u32_t zfLnxUsbIn(zdev_t* dev, urb_t *urb, zbuf_t *buf) | |
764 | { | |
765 | u32_t ret; | |
da3e8908 | 766 | struct usbdrv_private *macp = dev->ml_priv; |
4bd43f50 LR |
767 | |
768 | /* Submit a rx urb */ | |
769 | ret = zfLnxUsbSubmitBulkUrb(urb, macp->udev, USB_WLAN_RX_PIPE, | |
770 | USB_DIR_IN, buf->data, ZM_MAX_RX_BUFFER_SIZE, | |
771 | zfLnxUsbDataIn_callback, dev); | |
772 | //CWYang(-) | |
773 | //if (ret != 0) | |
774 | // printk("zfwUsbSubmitBulkUrb fail, status: 0x%08x\n", (int)ret); | |
775 | ||
776 | return ret; | |
777 | } | |
778 | ||
779 | u32_t zfLnxUsbWriteReg(zdev_t* dev, u32_t* cmd, u16_t cmdLen) | |
780 | { | |
da3e8908 | 781 | struct usbdrv_private *macp = dev->ml_priv; |
4bd43f50 LR |
782 | u32_t ret; |
783 | ||
784 | #ifdef ZM_CONFIG_BIG_ENDIAN | |
785 | int ii = 0; | |
786 | ||
787 | for(ii=0; ii<(cmdLen>>2); ii++) | |
788 | cmd[ii] = cpu_to_le32(cmd[ii]); | |
789 | #endif | |
790 | ||
791 | memcpy(macp->regUsbWriteBuf, cmd, cmdLen); | |
792 | ||
793 | /* Issue an USB Out transfer */ | |
794 | /* Submit a tx urb */ | |
4bd43f50 LR |
795 | ret = zfLnxUsbSubmitIntUrb(macp->RegOutUrb, macp->udev, |
796 | USB_REG_OUT_PIPE, USB_DIR_OUT, macp->regUsbWriteBuf, | |
797 | cmdLen, zfLnxUsbRegOut_callback, dev, 1); | |
4bd43f50 LR |
798 | |
799 | return ret; | |
800 | } | |
801 | ||
802 | ||
803 | u32_t zfLnxUsbOut(zdev_t* dev, u8_t *hdr, u16_t hdrlen, u8_t *snap, u16_t snapLen, | |
804 | u8_t *tail, u16_t tailLen, zbuf_t *buf, u16_t offset) | |
805 | { | |
806 | u32_t ret; | |
da3e8908 | 807 | struct usbdrv_private *macp = dev->ml_priv; |
4bd43f50 LR |
808 | |
809 | /* Check length of tail buffer */ | |
810 | //zm_assert((tailLen <= 16)); | |
811 | ||
812 | /* Enqueue the packet into UsbTxBufQ */ | |
813 | if (zfLnxPutUsbTxBuffer(dev, hdr, hdrlen, snap, snapLen, tail, tailLen, buf, offset) == 0xffff) | |
814 | { | |
815 | /* free packet */ | |
816 | //printk("CWY - zfwPutUsbTxBuffer Error, free packet\n"); | |
817 | //dev_kfree_skb_any(buf); | |
818 | macp->usbCbFunctions.zfcbUsbOutComplete(dev, buf, 0, hdr); | |
819 | return 0xffff; | |
820 | } | |
821 | ||
822 | //return 0; | |
823 | //printk("CWY - call zfwUsbSubmitTxData()\n"); | |
824 | ret = zfLnxUsbSubmitTxData(dev); | |
825 | return ret; | |
826 | } | |
827 | ||
828 | void zfLnxInitUsbTxQ(zdev_t* dev) | |
829 | { | |
da3e8908 | 830 | struct usbdrv_private *macp = dev->ml_priv; |
4bd43f50 LR |
831 | |
832 | printk(KERN_ERR "zfwInitUsbTxQ\n"); | |
833 | ||
834 | /* Zero memory for UsbTxBufQ */ | |
835 | memset(macp->UsbTxBufQ, 0, sizeof(UsbTxQ_t) * ZM_MAX_TX_URB_NUM); | |
836 | ||
837 | macp->TxBufHead = 0; | |
838 | macp->TxBufTail = 0; | |
839 | macp->TxUrbHead = 0; | |
840 | macp->TxUrbTail = 0; | |
841 | macp->TxUrbCnt = ZM_MAX_TX_URB_NUM; | |
842 | } | |
843 | ||
844 | void zfLnxInitUsbRxQ(zdev_t* dev) | |
845 | { | |
846 | u16_t i; | |
847 | zbuf_t *buf; | |
da3e8908 | 848 | struct usbdrv_private *macp = dev->ml_priv; |
4bd43f50 LR |
849 | |
850 | /* Zero memory for UsbRxBufQ */ | |
851 | memset(macp->UsbRxBufQ, 0, sizeof(zbuf_t *) * ZM_MAX_RX_URB_NUM); | |
852 | ||
853 | macp->RxBufHead = 0; | |
854 | ||
855 | for (i = 0; i < ZM_MAX_RX_URB_NUM; i++) | |
856 | { | |
857 | //buf = zfwBufAllocate(dev, ZM_MAX_RX_BUFFER_SIZE); | |
858 | buf = dev_alloc_skb(ZM_MAX_RX_BUFFER_SIZE); | |
859 | macp->UsbRxBufQ[i] = buf; | |
860 | } | |
861 | ||
862 | //macp->RxBufTail = ZM_MAX_RX_URB_NUM - 1; | |
863 | macp->RxBufTail = 0; | |
864 | ||
865 | /* Submit all Rx urbs */ | |
866 | for (i = 0; i < ZM_MAX_RX_URB_NUM; i++) | |
867 | { | |
868 | zfLnxPutUsbRxBuffer(dev, macp->UsbRxBufQ[i]); | |
869 | zfLnxUsbIn(dev, macp->WlanRxDataUrb[i], macp->UsbRxBufQ[i]); | |
870 | } | |
871 | } | |
872 | ||
873 | ||
874 | ||
875 | u32_t zfLnxUsbSubmitBulkUrb(urb_t *urb, struct usb_device *usb, u16_t epnum, u16_t direction, | |
876 | void *transfer_buffer, int buffer_length, usb_complete_t complete, void *context) | |
877 | { | |
878 | u32_t ret; | |
879 | ||
880 | if(direction == USB_DIR_OUT) | |
881 | { | |
882 | usb_fill_bulk_urb(urb, usb, usb_sndbulkpipe(usb, epnum), | |
883 | transfer_buffer, buffer_length, complete, context); | |
884 | ||
885 | urb->transfer_flags |= URB_ZERO_PACKET; | |
886 | } | |
887 | else | |
888 | { | |
889 | usb_fill_bulk_urb(urb, usb, usb_rcvbulkpipe(usb, epnum), | |
890 | transfer_buffer, buffer_length, complete, context); | |
891 | } | |
892 | ||
4bd43f50 LR |
893 | if (epnum == 4) |
894 | { | |
895 | if (urb->hcpriv) | |
896 | { | |
897 | //printk("CWY - urb->hcpriv set by unknown reason, reset it\n"); | |
898 | //urb->hcpriv = 0; | |
899 | } | |
900 | } | |
901 | ||
4bd43f50 | 902 | ret = usb_submit_urb(urb, GFP_ATOMIC); |
4bd43f50 LR |
903 | if ((epnum == 4) & (ret != 0)) |
904 | { | |
905 | //printk("CWY - ret = %x\n", ret); | |
906 | } | |
907 | return ret; | |
908 | } | |
909 | ||
910 | u32_t zfLnxUsbSubmitIntUrb(urb_t *urb, struct usb_device *usb, u16_t epnum, u16_t direction, | |
911 | void *transfer_buffer, int buffer_length, usb_complete_t complete, void *context, | |
912 | u32_t interval) | |
913 | { | |
914 | u32_t ret; | |
915 | ||
916 | if(direction == USB_DIR_OUT) | |
917 | { | |
918 | usb_fill_int_urb(urb, usb, usb_sndbulkpipe(usb, epnum), | |
919 | transfer_buffer, buffer_length, complete, context, interval); | |
920 | } | |
921 | else | |
922 | { | |
923 | usb_fill_int_urb(urb, usb, usb_rcvbulkpipe(usb, epnum), | |
924 | transfer_buffer, buffer_length, complete, context, interval); | |
925 | } | |
926 | ||
4bd43f50 | 927 | ret = usb_submit_urb(urb, GFP_ATOMIC); |
4bd43f50 LR |
928 | |
929 | return ret; | |
930 | } | |
931 | ||
932 | #ifdef ZM_ENABLE_CENC | |
933 | int zfLnxCencSendMsg(struct sock *netlink_sk, u_int8_t *msg, int len) | |
934 | { | |
935 | #define COMMTYPE_GROUP 8 | |
936 | #define WAI_K_MSG 0x11 | |
937 | ||
938 | int ret = -1; | |
939 | int size; | |
940 | unsigned char *old_tail; | |
941 | struct sk_buff *skb; | |
942 | struct nlmsghdr *nlh; | |
943 | char *pos = NULL; | |
944 | ||
945 | size = NLMSG_SPACE(len); | |
946 | skb = alloc_skb(size, GFP_ATOMIC); | |
947 | ||
948 | if(skb == NULL) | |
949 | { | |
950 | printk("dev_alloc_skb failure \n"); | |
951 | goto out; | |
952 | } | |
953 | old_tail = skb->tail; | |
954 | ||
955 |