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