aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/winbond/wb35rx.c
diff options
context:
space:
mode:
authorPekka Enberg <penberg@cs.helsinki.fi>2008-10-30 13:04:53 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-01-06 16:51:51 -0500
commitc139a814ab1735a8a1fa1b63cad71bd4f8dd8935 (patch)
tree1a115572a010bdfa28bf6c4e8914c52f5f09b141 /drivers/staging/winbond/wb35rx.c
parenta22517fec0b13b5813932a3583a2b11a2ee17f5d (diff)
Staging: w35und: make functions local to wb35rx.c static
While there are no functional changes, the diff is quite large because we need to shuffle code around to avoid forward declarations. Acked-by: Pavel Machek <pavel@suse.cz> Signed-off-by: Pekka Enberg <penberg@cs.helsinki.fi> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging/winbond/wb35rx.c')
-rw-r--r--drivers/staging/winbond/wb35rx.c425
1 files changed, 213 insertions, 212 deletions
diff --git a/drivers/staging/winbond/wb35rx.c b/drivers/staging/winbond/wb35rx.c
index 85b861c4e9c..7f8b6d749a4 100644
--- a/drivers/staging/winbond/wb35rx.c
+++ b/drivers/staging/winbond/wb35rx.c
@@ -14,85 +14,150 @@
14#include "sysdef.h" 14#include "sysdef.h"
15#include "wb35rx_f.h" 15#include "wb35rx_f.h"
16 16
17void Wb35Rx_start(struct ieee80211_hw *hw) 17static void packet_came(struct ieee80211_hw *hw, char *pRxBufferAddress, int PacketSize)
18{ 18{
19 struct wbsoft_priv *priv = hw->priv; 19 struct wbsoft_priv *priv = hw->priv;
20 phw_data_t pHwData = &priv->sHwData; 20 struct sk_buff *skb;
21 PWB35RX pWb35Rx = &pHwData->Wb35Rx; 21 struct ieee80211_rx_status rx_status = {0};
22 22
23 // Allow only one thread to run into the Wb35Rx() function 23 if (!priv->enabled)
24 if (atomic_inc_return(&pWb35Rx->RxFireCounter) == 1) { 24 return;
25 pWb35Rx->EP3vm_state = VM_RUNNING; 25
26 Wb35Rx(hw); 26 skb = dev_alloc_skb(PacketSize);
27 } else 27 if (!skb) {
28 atomic_dec(&pWb35Rx->RxFireCounter); 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 rx_status.rate = 10;
38 rx_status.channel = 1;
39 rx_status.freq = 12345;
40 rx_status.phymode = MODE_IEEE80211B;
41*/
42
43 ieee80211_rx_irqsafe(hw, skb, &rx_status);
29} 44}
30 45
31// This function cannot reentrain 46static void Wb35Rx_adjust(PDESCRIPTOR pRxDes)
32void Wb35Rx(struct ieee80211_hw *hw) 47{
48 u32 * pRxBufferAddress;
49 u32 DecryptionMethod;
50 u32 i;
51 u16 BufferSize;
52
53 DecryptionMethod = pRxDes->R01.R01_decryption_method;
54 pRxBufferAddress = pRxDes->buffer_address[0];
55 BufferSize = pRxDes->buffer_size[0];
56
57 // Adjust the last part of data. Only data left
58 BufferSize -= 4; // For CRC-32
59 if (DecryptionMethod)
60 BufferSize -= 4;
61 if (DecryptionMethod == 3) // For CCMP
62 BufferSize -= 4;
63
64 // Adjust the IV field which after 802.11 header and ICV field.
65 if (DecryptionMethod == 1) // For WEP
66 {
67 for( i=6; i>0; i-- )
68 pRxBufferAddress[i] = pRxBufferAddress[i-1];
69 pRxDes->buffer_address[0] = pRxBufferAddress + 1;
70 BufferSize -= 4; // 4 byte for IV
71 }
72 else if( DecryptionMethod ) // For TKIP and CCMP
73 {
74 for (i=7; i>1; i--)
75 pRxBufferAddress[i] = pRxBufferAddress[i-2];
76 pRxDes->buffer_address[0] = pRxBufferAddress + 2;//Update the descriptor, shift 8 byte
77 BufferSize -= 8; // 8 byte for IV + ICV
78 }
79 pRxDes->buffer_size[0] = BufferSize;
80}
81
82static u16 Wb35Rx_indicate(struct ieee80211_hw *hw)
33{ 83{
34 struct wbsoft_priv *priv = hw->priv; 84 struct wbsoft_priv *priv = hw->priv;
35 phw_data_t pHwData = &priv->sHwData; 85 phw_data_t pHwData = &priv->sHwData;
86 DESCRIPTOR RxDes;
36 PWB35RX pWb35Rx = &pHwData->Wb35Rx; 87 PWB35RX pWb35Rx = &pHwData->Wb35Rx;
37 u8 * pRxBufferAddress; 88 u8 * pRxBufferAddress;
38 struct urb *urb = pWb35Rx->RxUrb; 89 u16 PacketSize;
39 int retv; 90 u16 stmp, BufferSize, stmp2 = 0;
40 u32 RxBufferId; 91 u32 RxBufferId;
41 92
42 // 93 // Only one thread be allowed to run into the following
43 // Issuing URB 94 do {
44 // 95 RxBufferId = pWb35Rx->RxProcessIndex;
45 if (pHwData->SurpriseRemove || pHwData->HwStop) 96 if (pWb35Rx->RxOwner[ RxBufferId ]) //Owner by VM
46 goto error; 97 break;
47 98
48 if (pWb35Rx->rx_halt) 99 pWb35Rx->RxProcessIndex++;
49 goto error; 100 pWb35Rx->RxProcessIndex %= MAX_USB_RX_BUFFER_NUMBER;
50 101
51 // Get RxBuffer's ID 102 pRxBufferAddress = pWb35Rx->pDRx;
52 RxBufferId = pWb35Rx->RxBufferId; 103 BufferSize = pWb35Rx->RxBufferSize[ RxBufferId ];
53 if (!pWb35Rx->RxOwner[RxBufferId]) {
54 // It's impossible to run here.
55 #ifdef _PE_RX_DUMP_
56 WBDEBUG(("Rx driver fifo unavailable\n"));
57 #endif
58 goto error;
59 }
60 104
61 // Update buffer point, then start to bulkin the data from USB 105 // Parse the bulkin buffer
62 pWb35Rx->RxBufferId++; 106 while (BufferSize >= 4) {
63 pWb35Rx->RxBufferId %= MAX_USB_RX_BUFFER_NUMBER; 107 if ((cpu_to_le32(*(u32 *)pRxBufferAddress) & 0x0fffffff) == RX_END_TAG) //Is ending? 921002.9.a
108 break;
64 109
65 pWb35Rx->CurrentRxBufferId = RxBufferId; 110 // Get the R00 R01 first
111 RxDes.R00.value = le32_to_cpu(*(u32 *)pRxBufferAddress);
112 PacketSize = (u16)RxDes.R00.R00_receive_byte_count;
113 RxDes.R01.value = le32_to_cpu(*((u32 *)(pRxBufferAddress+4)));
114 // For new DMA 4k
115 if ((PacketSize & 0x03) > 0)
116 PacketSize -= 4;
66 117
67 pWb35Rx->pDRx = kzalloc(MAX_USB_RX_BUFFER, GFP_ATOMIC); 118 // Basic check for Rx length. Is length valid?
68 if (!pWb35Rx->pDRx) { 119 if (PacketSize > MAX_PACKET_SIZE) {
69 printk("w35und: Rx memory alloc failed\n"); 120 #ifdef _PE_RX_DUMP_
70 goto error; 121 WBDEBUG(("Serious ERROR : Rx data size too long, size =%d\n", PacketSize));
71 } 122 #endif
72 pRxBufferAddress = pWb35Rx->pDRx;
73 123
74 usb_fill_bulk_urb(urb, pHwData->WbUsb.udev, 124 pWb35Rx->EP3vm_state = VM_STOP;
75 usb_rcvbulkpipe(pHwData->WbUsb.udev, 3), 125 pWb35Rx->Ep3ErrorCount2++;
76 pRxBufferAddress, MAX_USB_RX_BUFFER, 126 break;
77 Wb35Rx_Complete, hw); 127 }
78 128
79 pWb35Rx->EP3vm_state = VM_RUNNING; 129 // Start to process Rx buffer
130// RxDes.Descriptor_ID = RxBufferId; // Due to synchronous indicate, the field doesn't necessary to use.
131 BufferSize -= 8; //subtract 8 byte for 35's USB header length
132 pRxBufferAddress += 8;
80 133
81 retv = usb_submit_urb(urb, GFP_ATOMIC); 134 RxDes.buffer_address[0] = pRxBufferAddress;
135 RxDes.buffer_size[0] = PacketSize;
136 RxDes.buffer_number = 1;
137 RxDes.buffer_start_index = 0;
138 RxDes.buffer_total_size = RxDes.buffer_size[0];
139 Wb35Rx_adjust(&RxDes);
82 140
83 if (retv != 0) { 141 packet_came(hw, pRxBufferAddress, PacketSize);
84 printk("Rx URB sending error\n");
85 goto error;
86 }
87 return;
88 142
89error: 143 // Move RxBuffer point to the next
90 // VM stop 144 stmp = PacketSize + 3;
91 pWb35Rx->EP3vm_state = VM_STOP; 145 stmp &= ~0x03; // 4n alignment
92 atomic_dec(&pWb35Rx->RxFireCounter); 146 pRxBufferAddress += stmp;
147 BufferSize -= stmp;
148 stmp2 += stmp;
149 }
150
151 // Reclaim resource
152 pWb35Rx->RxOwner[ RxBufferId ] = 1;
153 } while (true);
154
155 return stmp2;
93} 156}
94 157
95void Wb35Rx_Complete(struct urb *urb) 158static void Wb35Rx(struct ieee80211_hw *hw);
159
160static void Wb35Rx_Complete(struct urb *urb)
96{ 161{
97 struct ieee80211_hw *hw = urb->context; 162 struct ieee80211_hw *hw = urb->context;
98 struct wbsoft_priv *priv = hw->priv; 163 struct wbsoft_priv *priv = hw->priv;
@@ -170,49 +235,86 @@ error:
170 pWb35Rx->EP3vm_state = VM_STOP; 235 pWb35Rx->EP3vm_state = VM_STOP;
171} 236}
172 237
173//===================================================================================== 238// This function cannot reentrain
174unsigned char Wb35Rx_initial(phw_data_t pHwData) 239static void Wb35Rx(struct ieee80211_hw *hw)
175{ 240{
176 PWB35RX pWb35Rx = &pHwData->Wb35Rx; 241 struct wbsoft_priv *priv = hw->priv;
177 242 phw_data_t pHwData = &priv->sHwData;
178 // Initial the Buffer Queue 243 PWB35RX pWb35Rx = &pHwData->Wb35Rx;
179 Wb35Rx_reset_descriptor( pHwData ); 244 u8 * pRxBufferAddress;
245 struct urb *urb = pWb35Rx->RxUrb;
246 int retv;
247 u32 RxBufferId;
180 248
181 pWb35Rx->RxUrb = usb_alloc_urb(0, GFP_ATOMIC); 249 //
182 return (!!pWb35Rx->RxUrb); 250 // Issuing URB
183} 251 //
252 if (pHwData->SurpriseRemove || pHwData->HwStop)
253 goto error;
184 254
185void Wb35Rx_stop(phw_data_t pHwData) 255 if (pWb35Rx->rx_halt)
186{ 256 goto error;
187 PWB35RX pWb35Rx = &pHwData->Wb35Rx;
188 257
189 // Canceling the Irp if already sends it out. 258 // Get RxBuffer's ID
190 if (pWb35Rx->EP3vm_state == VM_RUNNING) { 259 RxBufferId = pWb35Rx->RxBufferId;
191 usb_unlink_urb( pWb35Rx->RxUrb ); // Only use unlink, let Wb35Rx_destroy to free them 260 if (!pWb35Rx->RxOwner[RxBufferId]) {
261 // It's impossible to run here.
192 #ifdef _PE_RX_DUMP_ 262 #ifdef _PE_RX_DUMP_
193 WBDEBUG(("EP3 Rx stop\n")); 263 WBDEBUG(("Rx driver fifo unavailable\n"));
194 #endif 264 #endif
265 goto error;
266 }
267
268 // Update buffer point, then start to bulkin the data from USB
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;
195 } 293 }
294 return;
295
296error:
297 // VM stop
298 pWb35Rx->EP3vm_state = VM_STOP;
299 atomic_dec(&pWb35Rx->RxFireCounter);
196} 300}
197 301
198// Needs process context 302void Wb35Rx_start(struct ieee80211_hw *hw)
199void Wb35Rx_destroy(phw_data_t pHwData)
200{ 303{
304 struct wbsoft_priv *priv = hw->priv;
305 phw_data_t pHwData = &priv->sHwData;
201 PWB35RX pWb35Rx = &pHwData->Wb35Rx; 306 PWB35RX pWb35Rx = &pHwData->Wb35Rx;
202 307
203 do { 308 // Allow only one thread to run into the Wb35Rx() function
204 msleep(10); // Delay for waiting function enter 940623.1.a 309 if (atomic_inc_return(&pWb35Rx->RxFireCounter) == 1) {
205 } while (pWb35Rx->EP3vm_state != VM_STOP); 310 pWb35Rx->EP3vm_state = VM_RUNNING;
206 msleep(10); // Delay for waiting function exit 940623.1.b 311 Wb35Rx(hw);
207 312 } else
208 if (pWb35Rx->RxUrb) 313 atomic_dec(&pWb35Rx->RxFireCounter);
209 usb_free_urb( pWb35Rx->RxUrb );
210 #ifdef _PE_RX_DUMP_
211 WBDEBUG(("Wb35Rx_destroy OK\n"));
212 #endif
213} 314}
214 315
215void Wb35Rx_reset_descriptor( phw_data_t pHwData ) 316//=====================================================================================
317static void Wb35Rx_reset_descriptor( phw_data_t pHwData )
216{ 318{
217 PWB35RX pWb35Rx = &pHwData->Wb35Rx; 319 PWB35RX pWb35Rx = &pHwData->Wb35Rx;
218 u32 i; 320 u32 i;
@@ -228,145 +330,44 @@ void Wb35Rx_reset_descriptor( phw_data_t pHwData )
228 pWb35Rx->RxOwner[i] = 1; 330 pWb35Rx->RxOwner[i] = 1;
229} 331}
230 332
231void Wb35Rx_adjust(PDESCRIPTOR pRxDes) 333unsigned char Wb35Rx_initial(phw_data_t pHwData)
232{ 334{
233 u32 * pRxBufferAddress; 335 PWB35RX pWb35Rx = &pHwData->Wb35Rx;
234 u32 DecryptionMethod;
235 u32 i;
236 u16 BufferSize;
237
238 DecryptionMethod = pRxDes->R01.R01_decryption_method;
239 pRxBufferAddress = pRxDes->buffer_address[0];
240 BufferSize = pRxDes->buffer_size[0];
241 336
242 // Adjust the last part of data. Only data left 337 // Initial the Buffer Queue
243 BufferSize -= 4; // For CRC-32 338 Wb35Rx_reset_descriptor( pHwData );
244 if (DecryptionMethod)
245 BufferSize -= 4;
246 if (DecryptionMethod == 3) // For CCMP
247 BufferSize -= 4;
248 339
249 // Adjust the IV field which after 802.11 header and ICV field. 340 pWb35Rx->RxUrb = usb_alloc_urb(0, GFP_ATOMIC);
250 if (DecryptionMethod == 1) // For WEP 341 return (!!pWb35Rx->RxUrb);
251 {
252 for( i=6; i>0; i-- )
253 pRxBufferAddress[i] = pRxBufferAddress[i-1];
254 pRxDes->buffer_address[0] = pRxBufferAddress + 1;
255 BufferSize -= 4; // 4 byte for IV
256 }
257 else if( DecryptionMethod ) // For TKIP and CCMP
258 {
259 for (i=7; i>1; i--)
260 pRxBufferAddress[i] = pRxBufferAddress[i-2];
261 pRxDes->buffer_address[0] = pRxBufferAddress + 2;//Update the descriptor, shift 8 byte
262 BufferSize -= 8; // 8 byte for IV + ICV
263 }
264 pRxDes->buffer_size[0] = BufferSize;
265} 342}
266 343
267static void packet_came(struct ieee80211_hw *hw, char *pRxBufferAddress, int PacketSize) 344void Wb35Rx_stop(phw_data_t pHwData)
268{ 345{
269 struct wbsoft_priv *priv = hw->priv; 346 PWB35RX pWb35Rx = &pHwData->Wb35Rx;
270 struct sk_buff *skb;
271 struct ieee80211_rx_status rx_status = {0};
272
273 if (!priv->enabled)
274 return;
275 347
276 skb = dev_alloc_skb(PacketSize); 348 // Canceling the Irp if already sends it out.
277 if (!skb) { 349 if (pWb35Rx->EP3vm_state == VM_RUNNING) {
278 printk("Not enough memory for packet, FIXME\n"); 350 usb_unlink_urb( pWb35Rx->RxUrb ); // Only use unlink, let Wb35Rx_destroy to free them
279 return; 351 #ifdef _PE_RX_DUMP_
352 WBDEBUG(("EP3 Rx stop\n"));
353 #endif
280 } 354 }
281
282 memcpy(skb_put(skb, PacketSize),
283 pRxBufferAddress,
284 PacketSize);
285
286/*
287 rx_status.rate = 10;
288 rx_status.channel = 1;
289 rx_status.freq = 12345;
290 rx_status.phymode = MODE_IEEE80211B;
291*/
292
293 ieee80211_rx_irqsafe(hw, skb, &rx_status);
294} 355}
295 356
296u16 Wb35Rx_indicate(struct ieee80211_hw *hw) 357// Needs process context
358void Wb35Rx_destroy(phw_data_t pHwData)
297{ 359{
298 struct wbsoft_priv *priv = hw->priv; 360 PWB35RX pWb35Rx = &pHwData->Wb35Rx;
299 phw_data_t pHwData = &priv->sHwData;
300 DESCRIPTOR RxDes;
301 PWB35RX pWb35Rx = &pHwData->Wb35Rx;
302 u8 * pRxBufferAddress;
303 u16 PacketSize;
304 u16 stmp, BufferSize, stmp2 = 0;
305 u32 RxBufferId;
306 361
307 // Only one thread be allowed to run into the following
308 do { 362 do {
309 RxBufferId = pWb35Rx->RxProcessIndex; 363 msleep(10); // Delay for waiting function enter 940623.1.a
310 if (pWb35Rx->RxOwner[ RxBufferId ]) //Owner by VM 364 } while (pWb35Rx->EP3vm_state != VM_STOP);
311 break; 365 msleep(10); // Delay for waiting function exit 940623.1.b
312
313 pWb35Rx->RxProcessIndex++;
314 pWb35Rx->RxProcessIndex %= MAX_USB_RX_BUFFER_NUMBER;
315
316 pRxBufferAddress = pWb35Rx->pDRx;
317 BufferSize = pWb35Rx->RxBufferSize[ RxBufferId ];
318
319 // Parse the bulkin buffer
320 while (BufferSize >= 4) {
321 if ((cpu_to_le32(*(u32 *)pRxBufferAddress) & 0x0fffffff) == RX_END_TAG) //Is ending? 921002.9.a
322 break;
323
324 // Get the R00 R01 first
325 RxDes.R00.value = le32_to_cpu(*(u32 *)pRxBufferAddress);
326 PacketSize = (u16)RxDes.R00.R00_receive_byte_count;
327 RxDes.R01.value = le32_to_cpu(*((u32 *)(pRxBufferAddress+4)));
328 // For new DMA 4k
329 if ((PacketSize & 0x03) > 0)
330 PacketSize -= 4;
331
332 // Basic check for Rx length. Is length valid?
333 if (PacketSize > MAX_PACKET_SIZE) {
334 #ifdef _PE_RX_DUMP_
335 WBDEBUG(("Serious ERROR : Rx data size too long, size =%d\n", PacketSize));
336 #endif
337
338 pWb35Rx->EP3vm_state = VM_STOP;
339 pWb35Rx->Ep3ErrorCount2++;
340 break;
341 }
342
343 // Start to process Rx buffer
344// RxDes.Descriptor_ID = RxBufferId; // Due to synchronous indicate, the field doesn't necessary to use.
345 BufferSize -= 8; //subtract 8 byte for 35's USB header length
346 pRxBufferAddress += 8;
347
348 RxDes.buffer_address[0] = pRxBufferAddress;
349 RxDes.buffer_size[0] = PacketSize;
350 RxDes.buffer_number = 1;
351 RxDes.buffer_start_index = 0;
352 RxDes.buffer_total_size = RxDes.buffer_size[0];
353 Wb35Rx_adjust(&RxDes);
354
355 packet_came(hw, pRxBufferAddress, PacketSize);
356
357 // Move RxBuffer point to the next
358 stmp = PacketSize + 3;
359 stmp &= ~0x03; // 4n alignment
360 pRxBufferAddress += stmp;
361 BufferSize -= stmp;
362 stmp2 += stmp;
363 }
364
365 // Reclaim resource
366 pWb35Rx->RxOwner[ RxBufferId ] = 1;
367 } while (true);
368 366
369 return stmp2; 367 if (pWb35Rx->RxUrb)
368 usb_free_urb( pWb35Rx->RxUrb );
369 #ifdef _PE_RX_DUMP_
370 WBDEBUG(("Wb35Rx_destroy OK\n"));
371 #endif
370} 372}
371 373
372