1
2
3
4
5
6
7
8
9
10
11#include <linux/usb.h>
12
13#include "core.h"
14#include "sysdef.h"
15#include "wb35rx_f.h"
16
17static void packet_came(struct ieee80211_hw *hw, char *pRxBufferAddress, int PacketSize)
18{
19 struct wbsoft_priv *priv = hw->priv;
20 struct sk_buff *skb;
21 struct ieee80211_rx_status rx_status = {0};
22
23 if (!priv->enabled)
24 return;
25
26 skb = dev_alloc_skb(PacketSize);
27 if (!skb) {
28 printk("Not enough memory for packet, FIXME\n");
29 return;
30 }
31
32 memcpy(skb_put(skb, PacketSize),
33 pRxBufferAddress,
34 PacketSize);
35
36
37
38
39
40
41
42
43 memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
44 ieee80211_rx_irqsafe(hw, skb);
45}
46
47static void Wb35Rx_adjust(struct wb35_descriptor *pRxDes)
48{
49 u32 * pRxBufferAddress;
50 u32 DecryptionMethod;
51 u32 i;
52 u16 BufferSize;
53
54 DecryptionMethod = pRxDes->R01.R01_decryption_method;
55 pRxBufferAddress = pRxDes->buffer_address[0];
56 BufferSize = pRxDes->buffer_size[0];
57
58
59 BufferSize -= 4;
60 if (DecryptionMethod)
61 BufferSize -= 4;
62 if (DecryptionMethod == 3)
63 BufferSize -= 4;
64
65
66 if (DecryptionMethod == 1)
67 {
68 for( i=6; i>0; i-- )
69 pRxBufferAddress[i] = pRxBufferAddress[i-1];
70 pRxDes->buffer_address[0] = pRxBufferAddress + 1;
71 BufferSize -= 4;
72 }
73 else if( DecryptionMethod )
74 {
75 for (i=7; i>1; i--)
76 pRxBufferAddress[i] = pRxBufferAddress[i-2];
77 pRxDes->buffer_address[0] = pRxBufferAddress + 2;
78 BufferSize -= 8;
79 }
80 pRxDes->buffer_size[0] = BufferSize;
81}
82
83static u16 Wb35Rx_indicate(struct ieee80211_hw *hw)
84{
85 struct wbsoft_priv *priv = hw->priv;
86 struct hw_data * pHwData = &priv->sHwData;
87 struct wb35_descriptor RxDes;
88 struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx;
89 u8 * pRxBufferAddress;
90 u16 PacketSize;
91 u16 stmp, BufferSize, stmp2 = 0;
92 u32 RxBufferId;
93
94
95 do {
96 RxBufferId = pWb35Rx->RxProcessIndex;
97 if (pWb35Rx->RxOwner[ RxBufferId ])
98 break;
99
100 pWb35Rx->RxProcessIndex++;
101 pWb35Rx->RxProcessIndex %= MAX_USB_RX_BUFFER_NUMBER;
102
103 pRxBufferAddress = pWb35Rx->pDRx;
104 BufferSize = pWb35Rx->RxBufferSize[ RxBufferId ];
105
106
107 while (BufferSize >= 4) {
108 if ((cpu_to_le32(*(u32 *)pRxBufferAddress) & 0x0fffffff) == RX_END_TAG)
109 break;
110
111
112 RxDes.R00.value = le32_to_cpu(*(u32 *)pRxBufferAddress);
113 PacketSize = (u16)RxDes.R00.R00_receive_byte_count;
114 RxDes.R01.value = le32_to_cpu(*((u32 *)(pRxBufferAddress+4)));
115
116 if ((PacketSize & 0x03) > 0)
117 PacketSize -= 4;
118
119
120 if (PacketSize > MAX_PACKET_SIZE) {
121 #ifdef _PE_RX_DUMP_
122 printk("Serious ERROR : Rx data size too long, size =%d\n", PacketSize);
123 #endif
124
125 pWb35Rx->EP3vm_state = VM_STOP;
126 pWb35Rx->Ep3ErrorCount2++;
127 break;
128 }
129
130
131
132 BufferSize -= 8;
133 pRxBufferAddress += 8;
134
135 RxDes.buffer_address[0] = pRxBufferAddress;
136 RxDes.buffer_size[0] = PacketSize;
137 RxDes.buffer_number = 1;
138 RxDes.buffer_start_index = 0;
139 RxDes.buffer_total_size = RxDes.buffer_size[0];
140 Wb35Rx_adjust(&RxDes);
141
142 packet_came(hw, pRxBufferAddress, PacketSize);
143
144
145 stmp = PacketSize + 3;
146 stmp &= ~0x03;
147 pRxBufferAddress += stmp;
148 BufferSize -= stmp;
149 stmp2 += stmp;
150 }
151
152
153 pWb35Rx->RxOwner[ RxBufferId ] = 1;
154 } while (true);
155
156 return stmp2;
157}
158
159static void Wb35Rx(struct ieee80211_hw *hw);
160
161static void Wb35Rx_Complete(struct urb *urb)
162{
163 struct ieee80211_hw *hw = urb->context;
164 struct wbsoft_priv *priv = hw->priv;
165 struct hw_data * pHwData = &priv->sHwData;
166 struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx;
167 u8 * pRxBufferAddress;
168 u32 SizeCheck;
169 u16 BulkLength;
170 u32 RxBufferId;
171 R00_DESCRIPTOR R00;
172
173
174 pWb35Rx->EP3vm_state = VM_COMPLETED;
175 pWb35Rx->EP3VM_status = urb->status;
176
177 RxBufferId = pWb35Rx->CurrentRxBufferId;
178
179 pRxBufferAddress = pWb35Rx->pDRx;
180 BulkLength = (u16)urb->actual_length;
181
182
183 pWb35Rx->EP3vm_state = VM_COMPLETED;
184
185 if (pHwData->SurpriseRemove || pHwData->HwStop)
186 goto error;
187
188 if (pWb35Rx->rx_halt)
189 goto error;
190
191
192 pWb35Rx->RxOwner[ RxBufferId ] = 0;
193 R00.value = le32_to_cpu(*(u32 *)pRxBufferAddress);
194
195
196 if (pWb35Rx->EP3VM_status != 0) {
197 #ifdef _PE_USB_STATE_DUMP_
198 printk("EP3 IoCompleteRoutine return error\n");
199 #endif
200 pWb35Rx->EP3vm_state = VM_STOP;
201 goto error;
202 }
203
204
205 if (!HAL_USB_MODE_BURST(pHwData)) {
206 SizeCheck = R00.R00_receive_byte_count;
207 if ((SizeCheck & 0x03) > 0)
208 SizeCheck -= 4;
209 SizeCheck = (SizeCheck + 3) & ~0x03;
210 SizeCheck += 12;
211 if ((BulkLength > 1600) ||
212 (SizeCheck > 1600) ||
213 (BulkLength != SizeCheck) ||
214 (BulkLength == 0)) {
215 pWb35Rx->EP3vm_state = VM_STOP;
216 pWb35Rx->Ep3ErrorCount2++;
217 }
218 }
219
220
221 pWb35Rx->ByteReceived += BulkLength;
222 pWb35Rx->RxBufferSize[ RxBufferId ] = BulkLength;
223
224 if (!pWb35Rx->RxOwner[ RxBufferId ])
225 Wb35Rx_indicate(hw);
226
227 kfree(pWb35Rx->pDRx);
228
229 Wb35Rx(hw);
230 return;
231
232error:
233 pWb35Rx->RxOwner[ RxBufferId ] = 1;
234 atomic_dec(&pWb35Rx->RxFireCounter);
235 pWb35Rx->EP3vm_state = VM_STOP;
236}
237
238
239static void Wb35Rx(struct ieee80211_hw *hw)
240{
241 struct wbsoft_priv *priv = hw->priv;
242 struct hw_data * pHwData = &priv->sHwData;
243 struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx;
244 u8 * pRxBufferAddress;
245 struct urb *urb = pWb35Rx->RxUrb;
246 int retv;
247 u32 RxBufferId;
248
249
250
251
252 if (pHwData->SurpriseRemove || pHwData->HwStop)
253 goto error;
254
255 if (pWb35Rx->rx_halt)
256 goto error;
257
258
259 RxBufferId = pWb35Rx->RxBufferId;
260 if (!pWb35Rx->RxOwner[RxBufferId]) {
261
262 #ifdef _PE_RX_DUMP_
263 printk("Rx driver fifo unavailable\n");
264 #endif
265 goto error;
266 }
267
268
269 pWb35Rx->RxBufferId++;
270 pWb35Rx->RxBufferId %= MAX_USB_RX_BUFFER_NUMBER;
271
272 pWb35Rx->CurrentRxBufferId = RxBufferId;
273
274 pWb35Rx->pDRx = kzalloc(MAX_USB_RX_BUFFER, GFP_ATOMIC);
275 if (!pWb35Rx->pDRx) {
276 printk("w35und: Rx memory alloc failed\n");
277 goto error;
278 }
279 pRxBufferAddress = pWb35Rx->pDRx;
280
281 usb_fill_bulk_urb(urb, pHwData->WbUsb.udev,
282 usb_rcvbulkpipe(pHwData->WbUsb.udev, 3),
283 pRxBufferAddress, MAX_USB_RX_BUFFER,
284 Wb35Rx_Complete, hw);
285
286 pWb35Rx->EP3vm_state = VM_RUNNING;
287
288 retv = usb_submit_urb(urb, GFP_ATOMIC);
289
290 if (retv != 0) {
291 printk("Rx URB sending error\n");
292 goto error;
293 }
294 return;
295
296error:
297
298 pWb35Rx->EP3vm_state = VM_STOP;
299 atomic_dec(&pWb35Rx->RxFireCounter);
300}
301
302void Wb35Rx_start(struct ieee80211_hw *hw)
303{
304 struct wbsoft_priv *priv = hw->priv;
305 struct hw_data * pHwData = &priv->sHwData;
306 struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx;
307
308
309 if (atomic_inc_return(&pWb35Rx->RxFireCounter) == 1) {
310 pWb35Rx->EP3vm_state = VM_RUNNING;
311 Wb35Rx(hw);
312 } else
313 atomic_dec(&pWb35Rx->RxFireCounter);
314}
315
316
317static void Wb35Rx_reset_descriptor( struct hw_data * pHwData )
318{
319 struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx;
320 u32 i;
321
322 pWb35Rx->ByteReceived = 0;
323 pWb35Rx->RxProcessIndex = 0;
324 pWb35Rx->RxBufferId = 0;
325 pWb35Rx->EP3vm_state = VM_STOP;
326 pWb35Rx->rx_halt = 0;
327
328
329 for( i=0; i<MAX_USB_RX_BUFFER_NUMBER; i++ )
330 pWb35Rx->RxOwner[i] = 1;
331}
332
333unsigned char Wb35Rx_initial(struct hw_data * pHwData)
334{
335 struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx;
336
337
338 Wb35Rx_reset_descriptor( pHwData );
339
340 pWb35Rx->RxUrb = usb_alloc_urb(0, GFP_ATOMIC);
341 return (!!pWb35Rx->RxUrb);
342}
343
344void Wb35Rx_stop(struct hw_data * pHwData)
345{
346 struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx;
347
348
349 if (pWb35Rx->EP3vm_state == VM_RUNNING) {
350 usb_unlink_urb( pWb35Rx->RxUrb );
351 #ifdef _PE_RX_DUMP_
352 printk("EP3 Rx stop\n");
353 #endif
354 }
355}
356
357
358void Wb35Rx_destroy(struct hw_data * pHwData)
359{
360 struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx;
361
362 do {
363 msleep(10);
364 } while (pWb35Rx->EP3vm_state != VM_STOP);
365 msleep(10);
366
367 if (pWb35Rx->RxUrb)
368 usb_free_urb( pWb35Rx->RxUrb );
369 #ifdef _PE_RX_DUMP_
370 printk("Wb35Rx_destroy OK\n");
371 #endif
372}
373
374