wb35rx.c revision 5a0e3ad6af8660be21ca98a971cd00f331318c05
1//============================================================================ 2// Copyright (c) 1996-2002 Winbond Electronic Corporation 3// 4// Module Name: 5// Wb35Rx.c 6// 7// Abstract: 8// Processing the Rx message from down layer 9// 10//============================================================================ 11#include <linux/usb.h> 12#include <linux/slab.h> 13 14#include "core.h" 15#include "sysdef.h" 16#include "wb35rx_f.h" 17 18static void packet_came(struct ieee80211_hw *hw, char *pRxBufferAddress, int PacketSize) 19{ 20 struct wbsoft_priv *priv = hw->priv; 21 struct sk_buff *skb; 22 struct ieee80211_rx_status rx_status = {0}; 23 24 if (!priv->enabled) 25 return; 26 27 skb = dev_alloc_skb(PacketSize); 28 if (!skb) { 29 printk("Not enough memory for packet, FIXME\n"); 30 return; 31 } 32 33 memcpy(skb_put(skb, PacketSize), 34 pRxBufferAddress, 35 PacketSize); 36 37/* 38 rx_status.rate = 10; 39 rx_status.channel = 1; 40 rx_status.freq = 12345; 41 rx_status.phymode = MODE_IEEE80211B; 42*/ 43 44 memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); 45 ieee80211_rx_irqsafe(hw, skb); 46} 47 48static void Wb35Rx_adjust(struct wb35_descriptor *pRxDes) 49{ 50 u32 * pRxBufferAddress; 51 u32 DecryptionMethod; 52 u32 i; 53 u16 BufferSize; 54 55 DecryptionMethod = pRxDes->R01.R01_decryption_method; 56 pRxBufferAddress = pRxDes->buffer_address[0]; 57 BufferSize = pRxDes->buffer_size[0]; 58 59 // Adjust the last part of data. Only data left 60 BufferSize -= 4; // For CRC-32 61 if (DecryptionMethod) 62 BufferSize -= 4; 63 if (DecryptionMethod == 3) // For CCMP 64 BufferSize -= 4; 65 66 // Adjust the IV field which after 802.11 header and ICV field. 67 if (DecryptionMethod == 1) // For WEP 68 { 69 for( i=6; i>0; i-- ) 70 pRxBufferAddress[i] = pRxBufferAddress[i-1]; 71 pRxDes->buffer_address[0] = pRxBufferAddress + 1; 72 BufferSize -= 4; // 4 byte for IV 73 } 74 else if( DecryptionMethod ) // For TKIP and CCMP 75 { 76 for (i=7; i>1; i--) 77 pRxBufferAddress[i] = pRxBufferAddress[i-2]; 78 pRxDes->buffer_address[0] = pRxBufferAddress + 2;//Update the descriptor, shift 8 byte 79 BufferSize -= 8; // 8 byte for IV + ICV 80 } 81 pRxDes->buffer_size[0] = BufferSize; 82} 83 84static u16 Wb35Rx_indicate(struct ieee80211_hw *hw) 85{ 86 struct wbsoft_priv *priv = hw->priv; 87 struct hw_data * pHwData = &priv->sHwData; 88 struct wb35_descriptor RxDes; 89 struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx; 90 u8 * pRxBufferAddress; 91 u16 PacketSize; 92 u16 stmp, BufferSize, stmp2 = 0; 93 u32 RxBufferId; 94 95 // Only one thread be allowed to run into the following 96 do { 97 RxBufferId = pWb35Rx->RxProcessIndex; 98 if (pWb35Rx->RxOwner[ RxBufferId ]) //Owner by VM 99 break; 100 101 pWb35Rx->RxProcessIndex++; 102 pWb35Rx->RxProcessIndex %= MAX_USB_RX_BUFFER_NUMBER; 103 104 pRxBufferAddress = pWb35Rx->pDRx; 105 BufferSize = pWb35Rx->RxBufferSize[ RxBufferId ]; 106 107 // Parse the bulkin buffer 108 while (BufferSize >= 4) { 109 if ((cpu_to_le32(*(u32 *)pRxBufferAddress) & 0x0fffffff) == RX_END_TAG) //Is ending? 921002.9.a 110 break; 111 112 // Get the R00 R01 first 113 RxDes.R00.value = le32_to_cpu(*(u32 *)pRxBufferAddress); 114 PacketSize = (u16)RxDes.R00.R00_receive_byte_count; 115 RxDes.R01.value = le32_to_cpu(*((u32 *)(pRxBufferAddress+4))); 116 // For new DMA 4k 117 if ((PacketSize & 0x03) > 0) 118 PacketSize -= 4; 119 120 // Basic check for Rx length. Is length valid? 121 if (PacketSize > MAX_PACKET_SIZE) { 122 #ifdef _PE_RX_DUMP_ 123 printk("Serious ERROR : Rx data size too long, size =%d\n", PacketSize); 124 #endif 125 126 pWb35Rx->EP3vm_state = VM_STOP; 127 pWb35Rx->Ep3ErrorCount2++; 128 break; 129 } 130 131 // Start to process Rx buffer 132// RxDes.Descriptor_ID = RxBufferId; // Due to synchronous indicate, the field doesn't necessary to use. 133 BufferSize -= 8; //subtract 8 byte for 35's USB header length 134 pRxBufferAddress += 8; 135 136 RxDes.buffer_address[0] = pRxBufferAddress; 137 RxDes.buffer_size[0] = PacketSize; 138 RxDes.buffer_number = 1; 139 RxDes.buffer_start_index = 0; 140 RxDes.buffer_total_size = RxDes.buffer_size[0]; 141 Wb35Rx_adjust(&RxDes); 142 143 packet_came(hw, pRxBufferAddress, PacketSize); 144 145 // Move RxBuffer point to the next 146 stmp = PacketSize + 3; 147 stmp &= ~0x03; // 4n alignment 148 pRxBufferAddress += stmp; 149 BufferSize -= stmp; 150 stmp2 += stmp; 151 } 152 153 // Reclaim resource 154 pWb35Rx->RxOwner[ RxBufferId ] = 1; 155 } while (true); 156 157 return stmp2; 158} 159 160static void Wb35Rx(struct ieee80211_hw *hw); 161 162static void Wb35Rx_Complete(struct urb *urb) 163{ 164 struct ieee80211_hw *hw = urb->context; 165 struct wbsoft_priv *priv = hw->priv; 166 struct hw_data * pHwData = &priv->sHwData; 167 struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx; 168 u8 * pRxBufferAddress; 169 u32 SizeCheck; 170 u16 BulkLength; 171 u32 RxBufferId; 172 R00_DESCRIPTOR R00; 173 174 // Variable setting 175 pWb35Rx->EP3vm_state = VM_COMPLETED; 176 pWb35Rx->EP3VM_status = urb->status;//Store the last result of Irp 177 178 RxBufferId = pWb35Rx->CurrentRxBufferId; 179 180 pRxBufferAddress = pWb35Rx->pDRx; 181 BulkLength = (u16)urb->actual_length; 182 183 // The IRP is completed 184 pWb35Rx->EP3vm_state = VM_COMPLETED; 185 186 if (pHwData->SurpriseRemove || pHwData->HwStop) // Must be here, or RxBufferId is invalid 187 goto error; 188 189 if (pWb35Rx->rx_halt) 190 goto error; 191 192 // Start to process the data only in successful condition 193 pWb35Rx->RxOwner[ RxBufferId ] = 0; // Set the owner to driver 194 R00.value = le32_to_cpu(*(u32 *)pRxBufferAddress); 195 196 // The URB is completed, check the result 197 if (pWb35Rx->EP3VM_status != 0) { 198 #ifdef _PE_USB_STATE_DUMP_ 199 printk("EP3 IoCompleteRoutine return error\n"); 200 #endif 201 pWb35Rx->EP3vm_state = VM_STOP; 202 goto error; 203 } 204 205 // 20060220 For recovering. check if operating in single USB mode 206 if (!HAL_USB_MODE_BURST(pHwData)) { 207 SizeCheck = R00.R00_receive_byte_count; //20060926 anson's endian 208 if ((SizeCheck & 0x03) > 0) 209 SizeCheck -= 4; 210 SizeCheck = (SizeCheck + 3) & ~0x03; 211 SizeCheck += 12; // 8 + 4 badbeef 212 if ((BulkLength > 1600) || 213 (SizeCheck > 1600) || 214 (BulkLength != SizeCheck) || 215 (BulkLength == 0)) { // Add for fail Urb 216 pWb35Rx->EP3vm_state = VM_STOP; 217 pWb35Rx->Ep3ErrorCount2++; 218 } 219 } 220 221 // Indicating the receiving data 222 pWb35Rx->ByteReceived += BulkLength; 223 pWb35Rx->RxBufferSize[ RxBufferId ] = BulkLength; 224 225 if (!pWb35Rx->RxOwner[ RxBufferId ]) 226 Wb35Rx_indicate(hw); 227 228 kfree(pWb35Rx->pDRx); 229 // Do the next receive 230 Wb35Rx(hw); 231 return; 232 233error: 234 pWb35Rx->RxOwner[ RxBufferId ] = 1; // Set the owner to hardware 235 atomic_dec(&pWb35Rx->RxFireCounter); 236 pWb35Rx->EP3vm_state = VM_STOP; 237} 238 239// This function cannot reentrain 240static void Wb35Rx(struct ieee80211_hw *hw) 241{ 242 struct wbsoft_priv *priv = hw->priv; 243 struct hw_data * pHwData = &priv->sHwData; 244 struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx; 245 u8 * pRxBufferAddress; 246 struct urb *urb = pWb35Rx->RxUrb; 247 int retv; 248 u32 RxBufferId; 249 250 // 251 // Issuing URB 252 // 253 if (pHwData->SurpriseRemove || pHwData->HwStop) 254 goto error; 255 256 if (pWb35Rx->rx_halt) 257 goto error; 258 259 // Get RxBuffer's ID 260 RxBufferId = pWb35Rx->RxBufferId; 261 if (!pWb35Rx->RxOwner[RxBufferId]) { 262 // It's impossible to run here. 263 #ifdef _PE_RX_DUMP_ 264 printk("Rx driver fifo unavailable\n"); 265 #endif 266 goto error; 267 } 268 269 // Update buffer point, then start to bulkin the data from USB 270 pWb35Rx->RxBufferId++; 271 pWb35Rx->RxBufferId %= MAX_USB_RX_BUFFER_NUMBER; 272 273 pWb35Rx->CurrentRxBufferId = RxBufferId; 274 275 pWb35Rx->pDRx = kzalloc(MAX_USB_RX_BUFFER, GFP_ATOMIC); 276 if (!pWb35Rx->pDRx) { 277 printk("w35und: Rx memory alloc failed\n"); 278 goto error; 279 } 280 pRxBufferAddress = pWb35Rx->pDRx; 281 282 usb_fill_bulk_urb(urb, pHwData->WbUsb.udev, 283 usb_rcvbulkpipe(pHwData->WbUsb.udev, 3), 284 pRxBufferAddress, MAX_USB_RX_BUFFER, 285 Wb35Rx_Complete, hw); 286 287 pWb35Rx->EP3vm_state = VM_RUNNING; 288 289 retv = usb_submit_urb(urb, GFP_ATOMIC); 290 291 if (retv != 0) { 292 printk("Rx URB sending error\n"); 293 goto error; 294 } 295 return; 296 297error: 298 // VM stop 299 pWb35Rx->EP3vm_state = VM_STOP; 300 atomic_dec(&pWb35Rx->RxFireCounter); 301} 302 303void Wb35Rx_start(struct ieee80211_hw *hw) 304{ 305 struct wbsoft_priv *priv = hw->priv; 306 struct hw_data * pHwData = &priv->sHwData; 307 struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx; 308 309 // Allow only one thread to run into the Wb35Rx() function 310 if (atomic_inc_return(&pWb35Rx->RxFireCounter) == 1) { 311 pWb35Rx->EP3vm_state = VM_RUNNING; 312 Wb35Rx(hw); 313 } else 314 atomic_dec(&pWb35Rx->RxFireCounter); 315} 316 317//===================================================================================== 318static void Wb35Rx_reset_descriptor( struct hw_data * pHwData ) 319{ 320 struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx; 321 u32 i; 322 323 pWb35Rx->ByteReceived = 0; 324 pWb35Rx->RxProcessIndex = 0; 325 pWb35Rx->RxBufferId = 0; 326 pWb35Rx->EP3vm_state = VM_STOP; 327 pWb35Rx->rx_halt = 0; 328 329 // Initial the Queue. The last buffer is reserved for used if the Rx resource is unavailable. 330 for( i=0; i<MAX_USB_RX_BUFFER_NUMBER; i++ ) 331 pWb35Rx->RxOwner[i] = 1; 332} 333 334unsigned char Wb35Rx_initial(struct hw_data * pHwData) 335{ 336 struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx; 337 338 // Initial the Buffer Queue 339 Wb35Rx_reset_descriptor( pHwData ); 340 341 pWb35Rx->RxUrb = usb_alloc_urb(0, GFP_ATOMIC); 342 return (!!pWb35Rx->RxUrb); 343} 344 345void Wb35Rx_stop(struct hw_data * pHwData) 346{ 347 struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx; 348 349 // Canceling the Irp if already sends it out. 350 if (pWb35Rx->EP3vm_state == VM_RUNNING) { 351 usb_unlink_urb( pWb35Rx->RxUrb ); // Only use unlink, let Wb35Rx_destroy to free them 352 #ifdef _PE_RX_DUMP_ 353 printk("EP3 Rx stop\n"); 354 #endif 355 } 356} 357 358// Needs process context 359void Wb35Rx_destroy(struct hw_data * pHwData) 360{ 361 struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx; 362 363 do { 364 msleep(10); // Delay for waiting function enter 940623.1.a 365 } while (pWb35Rx->EP3vm_state != VM_STOP); 366 msleep(10); // Delay for waiting function exit 940623.1.b 367 368 if (pWb35Rx->RxUrb) 369 usb_free_urb( pWb35Rx->RxUrb ); 370 #ifdef _PE_RX_DUMP_ 371 printk("Wb35Rx_destroy OK\n"); 372 #endif 373} 374 375