Merge branch 'perf/core' into perf/urgent, to pick up the latest fixes
[deliverable/linux.git] / drivers / staging / vt6656 / dpc.c
CommitLineData
92b96797
FB
1/*
2 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
3 * All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * File: dpc.c
20 *
21 * Purpose: handle dpc rx functions
22 *
23 * Author: Lyndon Chen
24 *
25 * Date: May 20, 2003
26 *
27 * Functions:
28 * device_receive_frame - Rcv 802.11 frame function
92b96797 29 * s_bHandleRxEncryption- Rcv decrypted data via on-fly
92b96797
FB
30 * s_byGetRateIdx- get rate index
31 * s_vGetDASA- get data offset
32 * s_vProcessRxMACHeader- Rcv 802.11 and translate to 802.3
33 *
34 * Revision History:
35 *
36 */
37
d820fa95 38#include "dpc.h"
92b96797 39#include "device.h"
92b96797 40#include "rxtx.h"
92b96797 41#include "tether.h"
92b96797 42#include "card.h"
92b96797 43#include "bssdb.h"
92b96797 44#include "mac.h"
92b96797 45#include "baseband.h"
92b96797 46#include "michael.h"
92b96797 47#include "tkip.h"
92b96797 48#include "wctl.h"
92b96797 49#include "rf.h"
92b96797 50#include "iowpa.h"
92b96797 51#include "datarate.h"
92b96797 52#include "usbpipe.h"
92b96797 53
92b96797
FB
54//static int msglevel =MSG_LEVEL_DEBUG;
55static int msglevel =MSG_LEVEL_INFO;
56
3b138851 57static const u8 acbyRxRate[MAX_RATE] =
92b96797
FB
58{2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108};
59
b902fbfe 60static u8 s_byGetRateIdx(u8 byRate);
92b96797
FB
61
62static
8611a29a 63void
92b96797 64s_vGetDASA(
b902fbfe 65 u8 * pbyRxBufferAddr,
93a94c42 66 unsigned int *pcbHeaderSize,
ceb8c5da 67 struct ethhdr *psEthHeader
92b96797
FB
68 );
69
45c73bb1
MP
70static void s_vProcessRxMACHeader(struct vnt_private *pDevice,
71 u8 *pbyRxBufferAddr, u32 cbPacketSize, int bIsWEP, int bExtIV,
72 u32 *pcbHeadSize);
92b96797 73
45c73bb1
MP
74static int s_bHandleRxEncryption(struct vnt_private *pDevice, u8 *pbyFrame,
75 u32 FrameSize, u8 *pbyRsr, u8 *pbyNewRsr, PSKeyItem *pKeyOut,
76 s32 *pbExtIV, u16 *pwRxTSC15_0, u32 *pdwRxTSC47_16);
92b96797 77
92b96797
FB
78/*+
79 *
80 * Description:
81 * Translate Rcv 802.11 header to 802.3 header with Rx buffer
82 *
83 * Parameters:
84 * In:
85 * pDevice
86 * dwRxBufferAddr - Address of Rcv Buffer
87 * cbPacketSize - Rcv Packet size
88 * bIsWEP - If Rcv with WEP
89 * Out:
90 * pcbHeaderSize - 802.11 header size
91 *
92 * Return Value: None
93 *
94-*/
45c73bb1
MP
95
96static void s_vProcessRxMACHeader(struct vnt_private *pDevice,
97 u8 *pbyRxBufferAddr, u32 cbPacketSize, int bIsWEP, int bExtIV,
98 u32 *pcbHeadSize)
92b96797 99{
45c73bb1
MP
100 u8 *pbyRxBuffer;
101 u32 cbHeaderSize = 0;
102 u16 *pwType;
1cac4a4b 103 struct ieee80211_hdr *pMACHeader;
45c73bb1 104 int ii;
92b96797 105
1cac4a4b 106 pMACHeader = (struct ieee80211_hdr *) (pbyRxBufferAddr + cbHeaderSize);
92b96797 107
b902fbfe 108 s_vGetDASA((u8 *)pMACHeader, &cbHeaderSize, &pDevice->sRxEthHeader);
92b96797
FB
109
110 if (bIsWEP) {
111 if (bExtIV) {
112 // strip IV&ExtIV , add 8 byte
113 cbHeaderSize += (WLAN_HDR_ADDR3_LEN + 8);
114 } else {
115 // strip IV , add 4 byte
116 cbHeaderSize += (WLAN_HDR_ADDR3_LEN + 4);
117 }
118 }
119 else {
120 cbHeaderSize += WLAN_HDR_ADDR3_LEN;
121 };
122
b902fbfe 123 pbyRxBuffer = (u8 *) (pbyRxBufferAddr + cbHeaderSize);
8329419a 124 if (ether_addr_equal(pbyRxBuffer, pDevice->abySNAP_Bridgetunnel)) {
92b96797 125 cbHeaderSize += 6;
8329419a 126 } else if (ether_addr_equal(pbyRxBuffer, pDevice->abySNAP_RFC1042)) {
92b96797 127 cbHeaderSize += 6;
3eaca0d2 128 pwType = (u16 *) (pbyRxBufferAddr + cbHeaderSize);
aa209eef 129 if ((*pwType == cpu_to_be16(ETH_P_IPX)) ||
203e4615
AM
130 (*pwType == cpu_to_le16(0xF380))) {
131 cbHeaderSize -= 8;
3eaca0d2 132 pwType = (u16 *) (pbyRxBufferAddr + cbHeaderSize);
92b96797
FB
133 if (bIsWEP) {
134 if (bExtIV) {
135 *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 8); // 8 is IV&ExtIV
136 } else {
137 *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 4); // 4 is IV
138 }
139 }
140 else {
141 *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN);
142 }
143 }
144 }
145 else {
146 cbHeaderSize -= 2;
3eaca0d2 147 pwType = (u16 *) (pbyRxBufferAddr + cbHeaderSize);
92b96797
FB
148 if (bIsWEP) {
149 if (bExtIV) {
150 *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 8); // 8 is IV&ExtIV
151 } else {
152 *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 4); // 4 is IV
153 }
154 }
155 else {
156 *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN);
157 }
158 }
159
9a0e756c 160 cbHeaderSize -= (ETH_ALEN * 2);
b902fbfe 161 pbyRxBuffer = (u8 *) (pbyRxBufferAddr + cbHeaderSize);
9a0e756c 162 for (ii = 0; ii < ETH_ALEN; ii++)
ceb8c5da 163 *pbyRxBuffer++ = pDevice->sRxEthHeader.h_dest[ii];
9a0e756c 164 for (ii = 0; ii < ETH_ALEN; ii++)
ceb8c5da 165 *pbyRxBuffer++ = pDevice->sRxEthHeader.h_source[ii];
92b96797
FB
166
167 *pcbHeadSize = cbHeaderSize;
168}
169
b902fbfe 170static u8 s_byGetRateIdx(u8 byRate)
92b96797 171{
b902fbfe 172 u8 byRateIdx;
92b96797
FB
173
174 for (byRateIdx = 0; byRateIdx <MAX_RATE ; byRateIdx++) {
175 if (acbyRxRate[byRateIdx%MAX_RATE] == byRate)
176 return byRateIdx;
177 }
178 return 0;
179}
180
92b96797 181static
8611a29a 182void
92b96797 183s_vGetDASA (
b902fbfe 184 u8 * pbyRxBufferAddr,
93a94c42 185 unsigned int *pcbHeaderSize,
ceb8c5da 186 struct ethhdr *psEthHeader
92b96797
FB
187 )
188{
cc856e61 189 unsigned int cbHeaderSize = 0;
1cac4a4b 190 struct ieee80211_hdr *pMACHeader;
9a0e756c
AM
191 int ii;
192
1cac4a4b 193 pMACHeader = (struct ieee80211_hdr *) (pbyRxBufferAddr + cbHeaderSize);
9a0e756c 194
1cac4a4b
AM
195 if ((pMACHeader->frame_control & FC_TODS) == 0) {
196 if (pMACHeader->frame_control & FC_FROMDS) {
9a0e756c 197 for (ii = 0; ii < ETH_ALEN; ii++) {
ceb8c5da 198 psEthHeader->h_dest[ii] =
1cac4a4b 199 pMACHeader->addr1[ii];
ceb8c5da 200 psEthHeader->h_source[ii] =
1cac4a4b 201 pMACHeader->addr3[ii];
9a0e756c
AM
202 }
203 } else {
204 /* IBSS mode */
205 for (ii = 0; ii < ETH_ALEN; ii++) {
ceb8c5da 206 psEthHeader->h_dest[ii] =
1cac4a4b 207 pMACHeader->addr1[ii];
ceb8c5da 208 psEthHeader->h_source[ii] =
1cac4a4b 209 pMACHeader->addr2[ii];
9a0e756c
AM
210 }
211 }
212 } else {
213 /* Is AP mode.. */
1cac4a4b 214 if (pMACHeader->frame_control & FC_FROMDS) {
9a0e756c 215 for (ii = 0; ii < ETH_ALEN; ii++) {
ceb8c5da 216 psEthHeader->h_dest[ii] =
1cac4a4b 217 pMACHeader->addr3[ii];
ceb8c5da 218 psEthHeader->h_source[ii] =
1cac4a4b 219 pMACHeader->addr4[ii];
9a0e756c
AM
220 cbHeaderSize += 6;
221 }
222 } else {
223 for (ii = 0; ii < ETH_ALEN; ii++) {
ceb8c5da 224 psEthHeader->h_dest[ii] =
1cac4a4b 225 pMACHeader->addr3[ii];
ceb8c5da 226 psEthHeader->h_source[ii] =
1cac4a4b 227 pMACHeader->addr2[ii];
9a0e756c
AM
228 }
229 }
230 };
92b96797
FB
231 *pcbHeaderSize = cbHeaderSize;
232}
233
115cac2e 234int RXbBulkInProcessData(struct vnt_private *pDevice, struct vnt_rcb *pRCB,
45c73bb1 235 unsigned long BytesToIndicate)
92b96797 236{
45c73bb1
MP
237 struct net_device_stats *pStats = &pDevice->stats;
238 struct sk_buff *skb;
239 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
240 struct vnt_rx_mgmt *pRxPacket = &pMgmt->sRxPacket;
1cac4a4b 241 struct ieee80211_hdr *p802_11Header;
45c73bb1 242 u8 *pbyRsr, *pbyNewRsr, *pbyRSSI, *pbyFrame;
7c65fa2a 243 u64 *pqwTSFTime;
e269fc2d 244 u32 bDeFragRx = false;
45c73bb1 245 u32 cbHeaderOffset, cbIVOffset;
cf5d170e 246 u32 FrameSize;
45c73bb1 247 u16 wEtherType = 0;
c0fcac91 248 s32 iSANodeIndex = -1;
45c73bb1
MP
249 int ii;
250 u8 *pbyRxSts, *pbyRxRate, *pbySQ, *pby3SQ;
251 u32 cbHeaderSize;
252 PSKeyItem pKey = NULL;
253 u16 wRxTSC15_0 = 0;
254 u32 dwRxTSC47_16 = 0;
45c73bb1 255 /* signed long ldBm = 0; */
e269fc2d 256 int bIsWEP = false; int bExtIV = false;
cf5d170e 257 u32 dwWbkStatus;
115cac2e 258 struct vnt_rcb *pRCBIndicate = pRCB;
45c73bb1
MP
259 u8 *pbyDAddress;
260 u16 *pwPLCP_Length;
261 u8 abyVaildRate[MAX_RATE]
262 = {2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108};
263 u16 wPLCPwithPadding;
1cac4a4b 264 struct ieee80211_hdr *pMACHeader;
e269fc2d 265 int bRxeapol_key = false;
92b96797 266
92b96797
FB
267 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---------- RXbBulkInProcessData---\n");
268
269 skb = pRCB->skb;
270
cf5d170e
MP
271 /* [31:16]RcvByteCount ( not include 4-byte Status ) */
272 dwWbkStatus = *((u32 *)(skb->data));
273 FrameSize = dwWbkStatus >> 16;
274 FrameSize += 4;
92b96797 275
cf5d170e
MP
276 if (BytesToIndicate != FrameSize) {
277 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"------- WRONG Length 1\n");
9a450f9a 278 pStats->rx_frame_errors++;
e269fc2d 279 return false;
cf5d170e 280 }
92b96797 281
bd2bc4c7 282 if ((BytesToIndicate > 2372) || (BytesToIndicate <= 40)) {
92b96797 283 // Frame Size error drop this packet.
bd2bc4c7 284 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "---------- WRONG Length 2\n");
9a450f9a 285 pStats->rx_frame_errors++;
e269fc2d 286 return false;
92b96797
FB
287 }
288
b902fbfe 289 pbyDAddress = (u8 *)(skb->data);
92b96797
FB
290 pbyRxSts = pbyDAddress+4;
291 pbyRxRate = pbyDAddress+5;
292
293 //real Frame Size = USBFrameSize -4WbkStatus - 4RxStatus - 8TSF - 4RSR - 4SQ3 - ?Padding
294 //if SQ3 the range is 24~27, if no SQ3 the range is 20~23
295 //real Frame size in PLCPLength field.
3eaca0d2 296 pwPLCP_Length = (u16 *) (pbyDAddress + 6);
92b96797
FB
297 //Fix hardware bug => PLCP_Length error
298 if ( ((BytesToIndicate - (*pwPLCP_Length)) > 27) ||
299 ((BytesToIndicate - (*pwPLCP_Length)) < 24) ||
300 (BytesToIndicate < (*pwPLCP_Length)) ) {
301
302 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Wrong PLCP Length %x\n", (int) *pwPLCP_Length);
9a450f9a 303 pStats->rx_frame_errors++;
e269fc2d 304 return false;
92b96797
FB
305 }
306 for ( ii=RATE_1M;ii<MAX_RATE;ii++) {
307 if ( *pbyRxRate == abyVaildRate[ii] ) {
308 break;
309 }
310 }
311 if ( ii==MAX_RATE ) {
312 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Wrong RxRate %x\n",(int) *pbyRxRate);
e269fc2d 313 return false;
92b96797
FB
314 }
315
316 wPLCPwithPadding = ( (*pwPLCP_Length / 4) + ( (*pwPLCP_Length % 4) ? 1:0 ) ) *4;
317
7c65fa2a 318 pqwTSFTime = (u64 *)(pbyDAddress + 8 + wPLCPwithPadding);
92b96797
FB
319 if(pDevice->byBBType == BB_TYPE_11G) {
320 pby3SQ = pbyDAddress + 8 + wPLCPwithPadding + 12;
321 pbySQ = pby3SQ;
322 }
323 else {
324 pbySQ = pbyDAddress + 8 + wPLCPwithPadding + 8;
325 pby3SQ = pbySQ;
326 }
92b96797
FB
327 pbyNewRsr = pbyDAddress + 8 + wPLCPwithPadding + 9;
328 pbyRSSI = pbyDAddress + 8 + wPLCPwithPadding + 10;
329 pbyRsr = pbyDAddress + 8 + wPLCPwithPadding + 11;
330
331 FrameSize = *pwPLCP_Length;
332
333 pbyFrame = pbyDAddress + 8;
92b96797 334
1cac4a4b 335 pMACHeader = (struct ieee80211_hdr *) pbyFrame;
92b96797
FB
336
337//mike add: to judge if current AP is activated?
338 if ((pMgmt->eCurrMode == WMAC_MODE_STANDBY) ||
339 (pMgmt->eCurrMode == WMAC_MODE_ESS_STA)) {
340 if (pMgmt->sNodeDBTable[0].bActive) {
8329419a 341 if (ether_addr_equal(pMgmt->abyCurrBSSID, pMACHeader->addr2)) {
92b96797
FB
342 if (pMgmt->sNodeDBTable[0].uInActiveCount != 0)
343 pMgmt->sNodeDBTable[0].uInActiveCount = 0;
344 }
345 }
346 }
347
1cac4a4b
AM
348 if (!is_multicast_ether_addr(pMACHeader->addr1)) {
349 if (WCTLbIsDuplicate(&(pDevice->sDupRxCache), (struct ieee80211_hdr *) pbyFrame)) {
e269fc2d 350 return false;
92b96797
FB
351 }
352
8329419a 353 if (!ether_addr_equal(pDevice->abyCurrentNetAddr, pMACHeader->addr1)) {
e269fc2d 354 return false;
92b96797
FB
355 }
356 }
357
92b96797
FB
358 // Use for TKIP MIC
359 s_vGetDASA(pbyFrame, &cbHeaderSize, &pDevice->sRxEthHeader);
360
8329419a
JP
361 if (ether_addr_equal((u8 *)pDevice->sRxEthHeader.h_source,
362 pDevice->abyCurrentNetAddr))
e269fc2d 363 return false;
92b96797
FB
364
365 if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) || (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) {
366 if (IS_CTL_PSPOLL(pbyFrame) || !IS_TYPE_CONTROL(pbyFrame)) {
1cac4a4b 367 p802_11Header = (struct ieee80211_hdr *) (pbyFrame);
92b96797 368 // get SA NodeIndex
1cac4a4b 369 if (BSSbIsSTAInNodeDB(pDevice, (u8 *)(p802_11Header->addr2), &iSANodeIndex)) {
92b96797
FB
370 pMgmt->sNodeDBTable[iSANodeIndex].ulLastRxJiffer = jiffies;
371 pMgmt->sNodeDBTable[iSANodeIndex].uInActiveCount = 0;
372 }
373 }
374 }
375
92b96797 376 if (IS_FC_WEP(pbyFrame)) {
e269fc2d 377 bool bRxDecryOK = false;
92b96797
FB
378
379 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"rx WEP pkt\n");
4e9b5e2b 380 bIsWEP = true;
90f96acd
MP
381
382 bRxDecryOK = s_bHandleRxEncryption(pDevice, pbyFrame, FrameSize,
383 pbyRsr, pbyNewRsr, &pKey, &bExtIV, &wRxTSC15_0, &dwRxTSC47_16);
92b96797
FB
384
385 if (bRxDecryOK) {
386 if ((*pbyNewRsr & NEWRSR_DECRYPTOK) == 0) {
387 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV Fail\n");
388 if ( (pMgmt->eAuthenMode == WMAC_AUTH_WPA) ||
389 (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) ||
390 (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) ||
391 (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) ||
392 (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) {
92b96797 393 }
e269fc2d 394 return false;
92b96797
FB
395 }
396 } else {
397 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"WEP Func Fail\n");
e269fc2d 398 return false;
92b96797
FB
399 }
400 if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_CCMP))
401 FrameSize -= 8; // Message Integrity Code
402 else
403 FrameSize -= 4; // 4 is ICV
404 }
405
92b96797
FB
406 //
407 // RX OK
408 //
abad19d0
AM
409 /* remove the FCS/CRC length */
410 FrameSize -= ETH_FCS_LEN;
92b96797 411
8a3d91b0 412 if ( !(*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI)) && // unicast address
92b96797
FB
413 (IS_FRAGMENT_PKT((pbyFrame)))
414 ) {
415 // defragment
1cac4a4b 416 bDeFragRx = WCTLbHandleFragment(pDevice, (struct ieee80211_hdr *) (pbyFrame), FrameSize, bIsWEP, bExtIV);
92b96797
FB
417 if (bDeFragRx) {
418 // defrag complete
419 // TODO skb, pbyFrame
420 skb = pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].skb;
421 FrameSize = pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength;
422 pbyFrame = skb->data + 8;
423 }
424 else {
e269fc2d 425 return false;
92b96797
FB
426 }
427 }
428
429 //
430 // Management & Control frame Handle
431 //
e269fc2d 432 if ((IS_TYPE_DATA((pbyFrame))) == false) {
92b96797
FB
433 // Handle Control & Manage Frame
434
435 if (IS_TYPE_MGMT((pbyFrame))) {
b902fbfe
AM
436 u8 * pbyData1;
437 u8 * pbyData2;
92b96797
FB
438
439 pRxPacket = &(pRCB->sMngPacket);
440 pRxPacket->p80211Header = (PUWLAN_80211HDR)(pbyFrame);
441 pRxPacket->cbMPDULen = FrameSize;
442 pRxPacket->uRSSI = *pbyRSSI;
443 pRxPacket->bySQ = *pbySQ;
7c65fa2a 444 pRxPacket->qwLocalTSF = cpu_to_le64(*pqwTSFTime);
92b96797
FB
445 if (bIsWEP) {
446 // strip IV
447 pbyData1 = WLAN_HDR_A3_DATA_PTR(pbyFrame);
448 pbyData2 = WLAN_HDR_A3_DATA_PTR(pbyFrame) + 4;
449 for (ii = 0; ii < (FrameSize - 4); ii++) {
450 *pbyData1 = *pbyData2;
451 pbyData1++;
452 pbyData2++;
453 }
454 }
455
456 pRxPacket->byRxRate = s_byGetRateIdx(*pbyRxRate);
457
458 if ( *pbyRxSts == 0 ) {
459 //Discard beacon packet which channel is 0
460 if ( (WLAN_GET_FC_FSTYPE((pRxPacket->p80211Header->sA3.wFrameCtl)) == WLAN_FSTYPE_BEACON) ||
461 (WLAN_GET_FC_FSTYPE((pRxPacket->p80211Header->sA3.wFrameCtl)) == WLAN_FSTYPE_PROBERESP) ) {
e269fc2d 462 return false;
92b96797
FB
463 }
464 }
465 pRxPacket->byRxChannel = (*pbyRxSts) >> 2;
466
92b96797
FB
467 //
468 // Insert the RCB in the Recv Mng list
469 //
470 EnqueueRCB(pDevice->FirstRecvMngList, pDevice->LastRecvMngList, pRCBIndicate);
471 pDevice->NumRecvMngList++;
e269fc2d 472 if ( bDeFragRx == false) {
92b96797
FB
473 pRCB->Ref++;
474 }
e269fc2d 475 if (pDevice->bIsRxMngWorkItemQueued == false) {
4e9b5e2b 476 pDevice->bIsRxMngWorkItemQueued = true;
a21fc2f5 477 schedule_work(&pDevice->rx_mng_work_item);
92b96797
FB
478 }
479
480 }
481 else {
482 // Control Frame
483 };
e269fc2d 484 return false;
92b96797
FB
485 }
486 else {
487 if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
488 //In AP mode, hw only check addr1(BSSID or RA) if equal to local MAC.
8a3d91b0 489 if ( !(*pbyRsr & RSR_BSSIDOK)) {
92b96797
FB
490 if (bDeFragRx) {
491 if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
492 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
493 pDevice->dev->name);
494 }
495 }
e269fc2d 496 return false;
92b96797
FB
497 }
498 }
499 else {
500 // discard DATA packet while not associate || BSSID error
e269fc2d 501 if ((pDevice->bLinkPass == false) ||
8a3d91b0 502 !(*pbyRsr & RSR_BSSIDOK)) {
92b96797
FB
503 if (bDeFragRx) {
504 if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
505 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
506 pDevice->dev->name);
507 }
508 }
e269fc2d 509 return false;
92b96797
FB
510 }
511 //mike add:station mode check eapol-key challenge--->
512 {
b902fbfe
AM
513 u8 Protocol_Version; //802.1x Authentication
514 u8 Packet_Type; //802.1x Authentication
515 u8 Descriptor_type;
3eaca0d2 516 u16 Key_info;
92b96797
FB
517 if (bIsWEP)
518 cbIVOffset = 8;
519 else
520 cbIVOffset = 0;
521 wEtherType = (skb->data[cbIVOffset + 8 + 24 + 6] << 8) |
522 skb->data[cbIVOffset + 8 + 24 + 6 + 1];
523 Protocol_Version = skb->data[cbIVOffset + 8 + 24 + 6 + 1 +1];
524 Packet_Type = skb->data[cbIVOffset + 8 + 24 + 6 + 1 +1+1];
525 if (wEtherType == ETH_P_PAE) { //Protocol Type in LLC-Header
526 if(((Protocol_Version==1) ||(Protocol_Version==2)) &&
527 (Packet_Type==3)) { //802.1x OR eapol-key challenge frame receive
4e9b5e2b 528 bRxeapol_key = true;
92b96797
FB
529 Descriptor_type = skb->data[cbIVOffset + 8 + 24 + 6 + 1 +1+1+1+2];
530 Key_info = (skb->data[cbIVOffset + 8 + 24 + 6 + 1 +1+1+1+2+1]<<8) |skb->data[cbIVOffset + 8 + 24 + 6 + 1 +1+1+1+2+2] ;
531 if(Descriptor_type==2) { //RSN
532 // printk("WPA2_Rx_eapol-key_info<-----:%x\n",Key_info);
533 }
534 else if(Descriptor_type==254) {
535 // printk("WPA_Rx_eapol-key_info<-----:%x\n",Key_info);
536 }
537 }
538 }
539 }
540 //mike add:station mode check eapol-key challenge<---
541 }
542 }
543
92b96797
FB
544// Data frame Handle
545
92b96797
FB
546 if (pDevice->bEnablePSMode) {
547 if (IS_FC_MOREDATA((pbyFrame))) {
8a3d91b0 548 if (*pbyRsr & RSR_ADDROK) {
92b96797
FB
549 //PSbSendPSPOLL((PSDevice)pDevice);
550 }
551 }
552 else {
4e9b5e2b 553 if (pMgmt->bInTIMWake == true) {
e269fc2d 554 pMgmt->bInTIMWake = false;
92b96797
FB
555 }
556 }
9fc86028 557 }
92b96797 558
92b96797
FB
559 // ++++++++ For BaseBand Algorithm +++++++++++++++
560 pDevice->uCurrRSSI = *pbyRSSI;
561 pDevice->byCurrSQ = *pbySQ;
562
563 // todo
564/*
565 if ((*pbyRSSI != 0) &&
566 (pMgmt->pCurrBSS!=NULL)) {
567 RFvRSSITodBm(pDevice, *pbyRSSI, &ldBm);
a0a1f61a 568 // Monitor if RSSI is too strong.
92b96797
FB
569 pMgmt->pCurrBSS->byRSSIStatCnt++;
570 pMgmt->pCurrBSS->byRSSIStatCnt %= RSSI_STAT_COUNT;
571 pMgmt->pCurrBSS->ldBmAverage[pMgmt->pCurrBSS->byRSSIStatCnt] = ldBm;
33d33e42
AM
572 for (ii = 0; ii < RSSI_STAT_COUNT; ii++) {
573 if (pMgmt->pCurrBSS->ldBmAverage[ii] != 0) {
574 pMgmt->pCurrBSS->ldBmMAX =
575 max(pMgmt->pCurrBSS->ldBmAverage[ii], ldBm);
576 }
92b96797
FB
577 }
578 }
579*/
580
92b96797
FB
581 if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_TKIP)) {
582 if (bIsWEP) {
583 FrameSize -= 8; //MIC
584 }
585 }
586
587 //--------------------------------------------------------------------------------
588 // Soft MIC
589 if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_TKIP)) {
590 if (bIsWEP) {
52a7e64b
AM
591 u32 * pdwMIC_L;
592 u32 * pdwMIC_R;
593 u32 dwMIC_Priority;
594 u32 dwMICKey0 = 0, dwMICKey1 = 0;
595 u32 dwLocalMIC_L = 0;
596 u32 dwLocalMIC_R = 0;
92b96797 597
92b96797 598 if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
52a7e64b
AM
599 dwMICKey0 = cpu_to_le32(*(u32 *)(&pKey->abyKey[24]));
600 dwMICKey1 = cpu_to_le32(*(u32 *)(&pKey->abyKey[28]));
92b96797
FB
601 }
602 else {
603 if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
52a7e64b
AM
604 dwMICKey0 = cpu_to_le32(*(u32 *)(&pKey->abyKey[16]));
605 dwMICKey1 = cpu_to_le32(*(u32 *)(&pKey->abyKey[20]));
92b96797 606 } else if ((pKey->dwKeyIndex & BIT28) == 0) {
52a7e64b
AM
607 dwMICKey0 = cpu_to_le32(*(u32 *)(&pKey->abyKey[16]));
608 dwMICKey1 = cpu_to_le32(*(u32 *)(&pKey->abyKey[20]));
92b96797 609 } else {
52a7e64b
AM
610 dwMICKey0 = cpu_to_le32(*(u32 *)(&pKey->abyKey[24]));
611 dwMICKey1 = cpu_to_le32(*(u32 *)(&pKey->abyKey[28]));
92b96797
FB
612 }
613 }
614
615 MIC_vInit(dwMICKey0, dwMICKey1);
ceb8c5da 616 MIC_vAppend((u8 *)&(pDevice->sRxEthHeader.h_dest[0]), 12);
92b96797 617 dwMIC_Priority = 0;
b902fbfe 618 MIC_vAppend((u8 *)&dwMIC_Priority, 4);
92b96797 619 // 4 is Rcv buffer header, 24 is MAC Header, and 8 is IV and Ext IV.
b902fbfe 620 MIC_vAppend((u8 *)(skb->data + 8 + WLAN_HDR_ADDR3_LEN + 8),
92b96797
FB
621 FrameSize - WLAN_HDR_ADDR3_LEN - 8);
622 MIC_vGetMIC(&dwLocalMIC_L, &dwLocalMIC_R);
623 MIC_vUnInit();
624
52a7e64b
AM
625 pdwMIC_L = (u32 *)(skb->data + 8 + FrameSize);
626 pdwMIC_R = (u32 *)(skb->data + 8 + FrameSize + 4);
92b96797 627
92b96797 628 if ((cpu_to_le32(*pdwMIC_L) != dwLocalMIC_L) || (cpu_to_le32(*pdwMIC_R) != dwLocalMIC_R) ||
4e9b5e2b 629 (pDevice->bRxMICFail == true)) {
92b96797 630 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC comparison is fail!\n");
e269fc2d 631 pDevice->bRxMICFail = false;
92b96797
FB
632 if (bDeFragRx) {
633 if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
634 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
635 pDevice->dev->name);
636 }
637 }
92b96797 638 //send event to wpa_supplicant
4e9b5e2b 639 //if(pDevice->bWPASuppWextEnabled == true)
92b96797
FB
640 {
641 union iwreq_data wrqu;
642 struct iw_michaelmicfailure ev;
643 int keyidx = pbyFrame[cbHeaderSize+3] >> 6; //top two-bits
644 memset(&ev, 0, sizeof(ev));
645 ev.flags = keyidx & IW_MICFAILURE_KEY_ID;
646 if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
647 (pMgmt->eCurrState == WMAC_STATE_ASSOC) &&
648 (*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI)) == 0) {
649 ev.flags |= IW_MICFAILURE_PAIRWISE;
650 } else {
651 ev.flags |= IW_MICFAILURE_GROUP;
652 }
653
654 ev.src_addr.sa_family = ARPHRD_ETHER;
1cac4a4b 655 memcpy(ev.src_addr.sa_data, pMACHeader->addr2, ETH_ALEN);
92b96797
FB
656 memset(&wrqu, 0, sizeof(wrqu));
657 wrqu.data.length = sizeof(ev);
658 PRINT_K("wireless_send_event--->IWEVMICHAELMICFAILURE\n");
659 wireless_send_event(pDevice->dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&ev);
660
661 }
92b96797 662
e269fc2d 663 return false;
92b96797
FB
664
665 }
666 }
667 } //---end of SOFT MIC-----------------------------------------------------------------------
668
669 // ++++++++++ Reply Counter Check +++++++++++++
670
671 if ((pKey != NULL) && ((pKey->byCipherSuite == KEY_CTL_TKIP) ||
672 (pKey->byCipherSuite == KEY_CTL_CCMP))) {
673 if (bIsWEP) {
3eaca0d2 674 u16 wLocalTSC15_0 = 0;
52a7e64b 675 u32 dwLocalTSC47_16 = 0;
cc856e61 676 unsigned long long RSC = 0;
92b96797 677 // endian issues
cc856e61 678 RSC = *((unsigned long long *) &(pKey->KeyRSC));
3eaca0d2 679 wLocalTSC15_0 = (u16) RSC;
52a7e64b 680 dwLocalTSC47_16 = (u32) (RSC>>16);
92b96797
FB
681
682 RSC = dwRxTSC47_16;
683 RSC <<= 16;
684 RSC += wRxTSC15_0;
7c65fa2a 685 memcpy(&(pKey->KeyRSC), &RSC, sizeof(u64));
92b96797 686
14c5ef57
MP
687 if (pDevice->vnt_mgmt.eCurrMode == WMAC_MODE_ESS_STA &&
688 pDevice->vnt_mgmt.eCurrState == WMAC_STATE_ASSOC) {
689 /* check RSC */
92b96797
FB
690 if ( (wRxTSC15_0 < wLocalTSC15_0) &&
691 (dwRxTSC47_16 <= dwLocalTSC47_16) &&
692 !((dwRxTSC47_16 == 0) && (dwLocalTSC47_16 == 0xFFFFFFFF))) {
693 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"TSC is illegal~~!\n ");
92b96797
FB
694
695 if (bDeFragRx) {
696 if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
697 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
698 pDevice->dev->name);
699 }
700 }
e269fc2d 701 return false;
92b96797
FB
702 }
703 }
704 }
705 } // ----- End of Reply Counter Check --------------------------
706
b902fbfe 707 s_vProcessRxMACHeader(pDevice, (u8 *)(skb->data+8), FrameSize, bIsWEP, bExtIV, &cbHeaderOffset);
92b96797
FB
708 FrameSize -= cbHeaderOffset;
709 cbHeaderOffset += 8; // 8 is Rcv buffer header
710
711 // Null data, framesize = 12
712 if (FrameSize < 12)
e269fc2d 713 return false;
92b96797 714
92b96797
FB
715 skb->data += cbHeaderOffset;
716 skb->tail += cbHeaderOffset;
717 skb_put(skb, FrameSize);
718 skb->protocol=eth_type_trans(skb, skb->dev);
719 skb->ip_summed=CHECKSUM_NONE;
720 pStats->rx_bytes +=skb->len;
721 pStats->rx_packets++;
722 netif_rx(skb);
723 if (bDeFragRx) {
724 if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
725 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
726 pDevice->dev->name);
727 }
e269fc2d 728 return false;
92b96797
FB
729 }
730
4e9b5e2b 731 return true;
92b96797
FB
732}
733
45c73bb1
MP
734static int s_bHandleRxEncryption(struct vnt_private *pDevice, u8 *pbyFrame,
735 u32 FrameSize, u8 *pbyRsr, u8 *pbyNewRsr, PSKeyItem *pKeyOut,
736 s32 *pbExtIV, u16 *pwRxTSC15_0, u32 *pdwRxTSC47_16)
92b96797 737{
45c73bb1
MP
738 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
739 u32 PayloadLen = FrameSize;
740 u8 *pbyIV;
741 u8 byKeyIdx;
742 PSKeyItem pKey = NULL;
743 u8 byDecMode = KEY_CTL_WEP;
92b96797 744
92b96797
FB
745 *pwRxTSC15_0 = 0;
746 *pdwRxTSC47_16 = 0;
747
748 pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN;
3eaca0d2
AM
749 if ( WLAN_GET_FC_TODS(*(u16 *)pbyFrame) &&
750 WLAN_GET_FC_FROMDS(*(u16 *)pbyFrame) ) {
92b96797
FB
751 pbyIV += 6; // 6 is 802.11 address4
752 PayloadLen -= 6;
753 }
754 byKeyIdx = (*(pbyIV+3) & 0xc0);
755 byKeyIdx >>= 6;
756 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\nKeyIdx: %d\n", byKeyIdx);
757
758 if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA) ||
759 (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) ||
760 (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) ||
761 (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) ||
762 (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) {
763 if (((*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI)) == 0) &&
764 (pMgmt->byCSSPK != KEY_CTL_NONE)) {
765 // unicast pkt use pairwise key
766 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"unicast pkt\n");
4e9b5e2b 767 if (KeybGetKey(&(pDevice->sKey), pDevice->abyBSSID, 0xFFFFFFFF, &pKey) == true) {
92b96797
FB
768 if (pMgmt->byCSSPK == KEY_CTL_TKIP)
769 byDecMode = KEY_CTL_TKIP;
770 else if (pMgmt->byCSSPK == KEY_CTL_CCMP)
771 byDecMode = KEY_CTL_CCMP;
772 }
773 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"unicast pkt: %d, %p\n", byDecMode, pKey);
774 } else {
775 // use group key
776 KeybGetKey(&(pDevice->sKey), pDevice->abyBSSID, byKeyIdx, &pKey);
777 if (pMgmt->byCSSGK == KEY_CTL_TKIP)
778 byDecMode = KEY_CTL_TKIP;
779 else if (pMgmt->byCSSGK == KEY_CTL_CCMP)
780 byDecMode = KEY_CTL_CCMP;
781 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"group pkt: %d, %d, %p\n", byKeyIdx, byDecMode, pKey);
782 }
783 }
784 // our WEP only support Default Key
785 if (pKey == NULL) {
786 // use default group key
787 KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, byKeyIdx, &pKey);
788 if (pMgmt->byCSSGK == KEY_CTL_TKIP)
789 byDecMode = KEY_CTL_TKIP;
790 else if (pMgmt->byCSSGK == KEY_CTL_CCMP)
791 byDecMode = KEY_CTL_CCMP;
792 }
793 *pKeyOut = pKey;
794
795 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"AES:%d %d %d\n", pMgmt->byCSSPK, pMgmt->byCSSGK, byDecMode);
796
797 if (pKey == NULL) {
798 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey == NULL\n");
e269fc2d 799 return false;
92b96797
FB
800 }
801 if (byDecMode != pKey->byCipherSuite) {
92b96797 802 *pKeyOut = NULL;
e269fc2d 803 return false;
92b96797
FB
804 }
805 if (byDecMode == KEY_CTL_WEP) {
806 // handle WEP
807 if ((pDevice->byLocalID <= REV_ID_VT3253_A1) ||
4e9b5e2b 808 (((PSKeyTable)(pKey->pvKeyTable))->bSoftWEP == true)) {
92b96797
FB
809 // Software WEP
810 // 1. 3253A
811 // 2. WEP 256
812
813 PayloadLen -= (WLAN_HDR_ADDR3_LEN + 4 + 4); // 24 is 802.11 header,4 is IV, 4 is crc
3e362598
JL
814 memcpy(pDevice->abyPRNG, pbyIV, 3);
815 memcpy(pDevice->abyPRNG + 3, pKey->abyKey, pKey->uKeyLength);
92b96797
FB
816 rc4_init(&pDevice->SBox, pDevice->abyPRNG, pKey->uKeyLength + 3);
817 rc4_encrypt(&pDevice->SBox, pbyIV+4, pbyIV+4, PayloadLen);
818
819 if (ETHbIsBufferCrc32Ok(pbyIV+4, PayloadLen)) {
820 *pbyNewRsr |= NEWRSR_DECRYPTOK;
821 }
822 }
823 } else if ((byDecMode == KEY_CTL_TKIP) ||
824 (byDecMode == KEY_CTL_CCMP)) {
825 // TKIP/AES
826
827 PayloadLen -= (WLAN_HDR_ADDR3_LEN + 8 + 4); // 24 is 802.11 header, 8 is IV&ExtIV, 4 is crc
52a7e64b 828 *pdwRxTSC47_16 = cpu_to_le32(*(u32 *)(pbyIV + 4));
b4dc03af 829 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ExtIV: %x\n", *pdwRxTSC47_16);
92b96797
FB
830 if (byDecMode == KEY_CTL_TKIP) {
831 *pwRxTSC15_0 = cpu_to_le16(MAKEWORD(*(pbyIV+2), *pbyIV));
832 } else {
3eaca0d2 833 *pwRxTSC15_0 = cpu_to_le16(*(u16 *)pbyIV);
92b96797
FB
834 }
835 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"TSC0_15: %x\n", *pwRxTSC15_0);
836
837 if ((byDecMode == KEY_CTL_TKIP) &&
838 (pDevice->byLocalID <= REV_ID_VT3253_A1)) {
839 // Software TKIP
840 // 1. 3253 A
1cac4a4b
AM
841 struct ieee80211_hdr *pMACHeader = (struct ieee80211_hdr *) (pbyFrame);
842 TKIPvMixKey(pKey->abyKey, pMACHeader->addr2, *pwRxTSC15_0, *pdwRxTSC47_16, pDevice->abyPRNG);
92b96797
FB
843 rc4_init(&pDevice->SBox, pDevice->abyPRNG, TKIP_KEY_LEN);
844 rc4_encrypt(&pDevice->SBox, pbyIV+8, pbyIV+8, PayloadLen);
845 if (ETHbIsBufferCrc32Ok(pbyIV+8, PayloadLen)) {
846 *pbyNewRsr |= NEWRSR_DECRYPTOK;
847 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV OK!\n");
848 } else {
849 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV FAIL!!!\n");
850 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"PayloadLen = %d\n", PayloadLen);
851 }
852 }
853 }// end of TKIP/AES
854
855 if ((*(pbyIV+3) & 0x20) != 0)
4e9b5e2b
AM
856 *pbExtIV = true;
857 return true;
92b96797
FB
858}
859
81d720d3 860void RXvWorkItem(struct work_struct *work)
92b96797 861{
49d73a98 862 struct vnt_private *priv =
81d720d3 863 container_of(work, struct vnt_private, read_work_item);
49d73a98
MP
864 int status;
865 struct vnt_rcb *rcb = NULL;
0b596b2a 866 unsigned long flags;
92b96797 867
49d73a98 868 if (priv->Flags & fMP_DISCONNECTED)
17f3ced0
MP
869 return;
870
49d73a98 871 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Rx Polling Thread\n");
731047f9 872
0b596b2a 873 spin_lock_irqsave(&priv->lock, flags);
49d73a98
MP
874
875 while ((priv->Flags & fMP_POST_READS) && MP_IS_READY(priv) &&
876 (priv->NumRecvFreeList != 0)) {
877 rcb = priv->FirstRecvFreeList;
878
879 priv->NumRecvFreeList--;
880
881 DequeueRCB(priv->FirstRecvFreeList, priv->LastRecvFreeList);
882
883 status = PIPEnsBulkInUsbRead(priv, rcb);
884 }
885
886 priv->bIsRxWorkItemQueued = false;
92b96797 887
0b596b2a 888 spin_unlock_irqrestore(&priv->lock, flags);
92b96797
FB
889}
890
5a30e0b6 891void RXvFreeRCB(struct vnt_rcb *rcb, int re_alloc_skb)
92b96797 892{
5a30e0b6 893 struct vnt_private *priv = rcb->pDevice;
92b96797 894
5a30e0b6 895 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->RXvFreeRCB\n");
92b96797 896
5a30e0b6
MP
897 if (re_alloc_skb == false) {
898 kfree_skb(rcb->skb);
899 re_alloc_skb = true;
28044e01
MP
900 }
901
5a30e0b6 902 if (re_alloc_skb == true) {
29263661 903 rcb->skb = netdev_alloc_skb(priv->dev, priv->rx_buf_sz);
5a30e0b6 904 /* TODO error handling */
29263661 905 if (!rcb->skb) {
5a30e0b6
MP
906 DBG_PRT(MSG_LEVEL_ERR, KERN_ERR
907 " Failed to re-alloc rx skb\n");
5a30e0b6
MP
908 }
909 }
92b96797 910
5a30e0b6
MP
911 /* Insert the RCB back in the Recv free list */
912 EnqueueRCB(priv->FirstRecvFreeList, priv->LastRecvFreeList, rcb);
913 priv->NumRecvFreeList++;
92b96797 914
5a30e0b6
MP
915 if ((priv->Flags & fMP_POST_READS) && MP_IS_READY(priv) &&
916 (priv->bIsRxWorkItemQueued == false)) {
917 priv->bIsRxWorkItemQueued = true;
918 schedule_work(&priv->read_work_item);
919 }
920
921 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"<----RXFreeRCB %d %d\n",
922 priv->NumRecvFreeList, priv->NumRecvMngList);
92b96797
FB
923}
924
a21fc2f5 925void RXvMngWorkItem(struct work_struct *work)
92b96797 926{
a21fc2f5
MP
927 struct vnt_private *pDevice =
928 container_of(work, struct vnt_private, rx_mng_work_item);
115cac2e 929 struct vnt_rcb *pRCB = NULL;
45c73bb1 930 struct vnt_rx_mgmt *pRxPacket;
e269fc2d 931 int bReAllocSkb = false;
e03ce839 932 unsigned long flags;
92b96797 933
17f3ced0
MP
934 if (pDevice->Flags & fMP_DISCONNECTED)
935 return;
936
92b96797
FB
937 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Rx Mng Thread\n");
938
92b96797
FB
939 while (pDevice->NumRecvMngList!=0)
940 {
e03ce839
MP
941 spin_lock_irqsave(&pDevice->lock, flags);
942
92b96797
FB
943 pRCB = pDevice->FirstRecvMngList;
944 pDevice->NumRecvMngList--;
945 DequeueRCB(pDevice->FirstRecvMngList, pDevice->LastRecvMngList);
e03ce839
MP
946
947 spin_unlock_irqrestore(&pDevice->lock, flags);
948
92b96797
FB
949 if(!pRCB){
950 break;
951 }
92b96797 952 pRxPacket = &(pRCB->sMngPacket);
14c5ef57 953 vMgrRxManagePacket(pDevice, &pDevice->vnt_mgmt, pRxPacket);
92b96797 954 pRCB->Ref--;
e03ce839
MP
955 if (pRCB->Ref == 0) {
956 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"RxvFreeMng %d %d\n",
957 pDevice->NumRecvFreeList, pDevice->NumRecvMngList);
958
959 spin_lock_irqsave(&pDevice->lock, flags);
960
961 RXvFreeRCB(pRCB, bReAllocSkb);
962
963 spin_unlock_irqrestore(&pDevice->lock, flags);
964 } else {
92b96797
FB
965 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Rx Mng Only we have the right to free RCB\n");
966 }
967 }
968
e269fc2d 969 pDevice->bIsRxMngWorkItemQueued = false;
92b96797
FB
970}
971
This page took 0.594367 seconds and 5 git commands to generate.