wb35rx.c revision 27d4642105b3fc6781e9110c7f4d0741434985ca
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 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 rx_status.rate = 10; 38 rx_status.channel = 1; 39 rx_status.freq = 12345; 40 rx_status.phymode = MODE_IEEE80211B; 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 // Adjust the last part of data. Only data left 59 BufferSize -= 4; // For CRC-32 60 if (DecryptionMethod) 61 BufferSize -= 4; 62 if (DecryptionMethod == 3) // For CCMP 63 BufferSize -= 4; 64 65 // Adjust the IV field which after 802.11 header and ICV field. 66 if (DecryptionMethod == 1) // For WEP 67 { 68 for( i=6; i>0; i-- ) 69 pRxBufferAddress[i] = pRxBufferAddress[i-1]; 70 pRxDes->buffer_address[0] = pRxBufferAddress + 1; 71 BufferSize -= 4; // 4 byte for IV 72 } 73 else if( DecryptionMethod ) // For TKIP and CCMP 74 { 75 for (i=7; i>1; i--) 76 pRxBufferAddress[i] = pRxBufferAddress[i-2]; 77 pRxDes->buffer_address[0] = pRxBufferAddress + 2;//Update the descriptor, shift 8 byte 78 BufferSize -= 8; // 8 byte for IV + ICV 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 // Only one thread be allowed to run into the following 95 do { 96 RxBufferId = pWb35Rx->RxProcessIndex; 97 if (pWb35Rx->RxOwner[ RxBufferId ]) //Owner by VM 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 // Parse the bulkin buffer 107 while (BufferSize >= 4) { 108 if ((cpu_to_le32(*(u32 *)pRxBufferAddress) & 0x0fffffff) == RX_END_TAG) //Is ending? 921002.9.a 109 break; 110 111 // Get the R00 R01 first 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 // For new DMA 4k 116 if ((PacketSize & 0x03) > 0) 117 PacketSize -= 4; 118 119 // Basic check for Rx length. Is length valid? 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 // Start to process Rx buffer 131// RxDes.Descriptor_ID = RxBufferId; // Due to synchronous indicate, the field doesn't necessary to use. 132 BufferSize -= 8; //subtract 8 byte for 35's USB header length 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 // Move RxBuffer point to the next 145 stmp = PacketSize + 3; 146 stmp &= ~0x03; // 4n alignment 147 pRxBufferAddress += stmp; 148 BufferSize -= stmp; 149 stmp2 += stmp; 150 } 151 152 // Reclaim resource 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 // Variable setting 174 pWb35Rx->EP3vm_state = VM_COMPLETED; 175 pWb35Rx->EP3VM_status = urb->status;//Store the last result of Irp 176 177 RxBufferId = pWb35Rx->CurrentRxBufferId; 178 179 pRxBufferAddress = pWb35Rx->pDRx; 180 BulkLength = (u16)urb->actual_length; 181 182 // The IRP is completed 183 pWb35Rx->EP3vm_state = VM_COMPLETED; 184 185 if (pHwData->SurpriseRemove || pHwData->HwStop) // Must be here, or RxBufferId is invalid 186 goto error; 187 188 if (pWb35Rx->rx_halt) 189 goto error; 190 191 // Start to process the data only in successful condition 192 pWb35Rx->RxOwner[ RxBufferId ] = 0; // Set the owner to driver 193 R00.value = le32_to_cpu(*(u32 *)pRxBufferAddress); 194 195 // The URB is completed, check the result 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 // 20060220 For recovering. check if operating in single USB mode 205 if (!HAL_USB_MODE_BURST(pHwData)) { 206 SizeCheck = R00.R00_receive_byte_count; //20060926 anson's endian 207 if ((SizeCheck & 0x03) > 0) 208 SizeCheck -= 4; 209 SizeCheck = (SizeCheck + 3) & ~0x03; 210 SizeCheck += 12; // 8 + 4 badbeef 211 if ((BulkLength > 1600) || 212 (SizeCheck > 1600) || 213 (BulkLength != SizeCheck) || 214 (BulkLength == 0)) { // Add for fail Urb 215 pWb35Rx->EP3vm_state = VM_STOP; 216 pWb35Rx->Ep3ErrorCount2++; 217 } 218 } 219 220 // Indicating the receiving data 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 // Do the next receive 229 Wb35Rx(hw); 230 return; 231 232error: 233 pWb35Rx->RxOwner[ RxBufferId ] = 1; // Set the owner to hardware 234 atomic_dec(&pWb35Rx->RxFireCounter); 235 pWb35Rx->EP3vm_state = VM_STOP; 236} 237 238// This function cannot reentrain 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 // Issuing URB 251 // 252 if (pHwData->SurpriseRemove || pHwData->HwStop) 253 goto error; 254 255 if (pWb35Rx->rx_halt) 256 goto error; 257 258 // Get RxBuffer's ID 259 RxBufferId = pWb35Rx->RxBufferId; 260 if (!pWb35Rx->RxOwner[RxBufferId]) { 261 // It's impossible to run here. 262 #ifdef _PE_RX_DUMP_ 263 printk("Rx driver fifo unavailable\n"); 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; 293 } 294 return; 295 296error: 297 // VM stop 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 // Allow only one thread to run into the Wb35Rx() function 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 // Initial the Queue. The last buffer is reserved for used if the Rx resource is unavailable. 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 // Initial the Buffer Queue 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 // Canceling the Irp if already sends it out. 349 if (pWb35Rx->EP3vm_state == VM_RUNNING) { 350 usb_unlink_urb( pWb35Rx->RxUrb ); // Only use unlink, let Wb35Rx_destroy to free them 351 #ifdef _PE_RX_DUMP_ 352 printk("EP3 Rx stop\n"); 353 #endif 354 } 355} 356 357// Needs process context 358void Wb35Rx_destroy(struct hw_data * pHwData) 359{ 360 struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx; 361 362 do { 363 msleep(10); // Delay for waiting function enter 940623.1.a 364 } while (pWb35Rx->EP3vm_state != VM_STOP); 365 msleep(10); // Delay for waiting function exit 940623.1.b 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