Commit | Line | Data |
---|---|---|
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 | |
29 | * s_bAPModeRxCtl- AP Rcv frame filer Ctl. | |
30 | * s_bAPModeRxData- AP Rcv data frame handle | |
31 | * s_bHandleRxEncryption- Rcv decrypted data via on-fly | |
32 | * s_bHostWepRxEncryption- Rcv encrypted data via host | |
33 | * s_byGetRateIdx- get rate index | |
34 | * s_vGetDASA- get data offset | |
35 | * s_vProcessRxMACHeader- Rcv 802.11 and translate to 802.3 | |
36 | * | |
37 | * Revision History: | |
38 | * | |
39 | */ | |
40 | ||
92b96797 | 41 | #include "device.h" |
92b96797 | 42 | #include "rxtx.h" |
92b96797 | 43 | #include "tether.h" |
92b96797 | 44 | #include "card.h" |
92b96797 | 45 | #include "bssdb.h" |
92b96797 | 46 | #include "mac.h" |
92b96797 | 47 | #include "baseband.h" |
92b96797 | 48 | #include "michael.h" |
92b96797 | 49 | #include "tkip.h" |
92b96797 | 50 | #include "tcrc.h" |
92b96797 | 51 | #include "wctl.h" |
92b96797 | 52 | #include "hostap.h" |
92b96797 | 53 | #include "rf.h" |
92b96797 | 54 | #include "iowpa.h" |
92b96797 | 55 | #include "aes_ccmp.h" |
92b96797 | 56 | #include "datarate.h" |
92b96797 | 57 | #include "usbpipe.h" |
92b96797 | 58 | |
92b96797 FB |
59 | //static int msglevel =MSG_LEVEL_DEBUG; |
60 | static int msglevel =MSG_LEVEL_INFO; | |
61 | ||
3b138851 | 62 | static const u8 acbyRxRate[MAX_RATE] = |
92b96797 FB |
63 | {2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108}; |
64 | ||
b902fbfe | 65 | static u8 s_byGetRateIdx(u8 byRate); |
92b96797 FB |
66 | |
67 | static | |
8611a29a | 68 | void |
92b96797 | 69 | s_vGetDASA( |
b902fbfe | 70 | u8 * pbyRxBufferAddr, |
93a94c42 | 71 | unsigned int *pcbHeaderSize, |
ceb8c5da | 72 | struct ethhdr *psEthHeader |
92b96797 FB |
73 | ); |
74 | ||
45c73bb1 MP |
75 | static void s_vProcessRxMACHeader(struct vnt_private *pDevice, |
76 | u8 *pbyRxBufferAddr, u32 cbPacketSize, int bIsWEP, int bExtIV, | |
77 | u32 *pcbHeadSize); | |
92b96797 | 78 | |
45c73bb1 MP |
79 | static int s_bAPModeRxCtl(struct vnt_private *pDevice, u8 *pbyFrame, |
80 | s32 iSANodeIndex); | |
92b96797 | 81 | |
45c73bb1 MP |
82 | static int s_bAPModeRxData(struct vnt_private *pDevice, struct sk_buff *skb, |
83 | u32 FrameSize, u32 cbHeaderOffset, s32 iSANodeIndex, s32 iDANodeIndex); | |
92b96797 | 84 | |
45c73bb1 MP |
85 | static int s_bHandleRxEncryption(struct vnt_private *pDevice, u8 *pbyFrame, |
86 | u32 FrameSize, u8 *pbyRsr, u8 *pbyNewRsr, PSKeyItem *pKeyOut, | |
87 | s32 *pbExtIV, u16 *pwRxTSC15_0, u32 *pdwRxTSC47_16); | |
92b96797 | 88 | |
45c73bb1 MP |
89 | static int s_bHostWepRxEncryption(struct vnt_private *pDevice, u8 *pbyFrame, |
90 | u32 FrameSize, u8 *pbyRsr, int bOnFly, PSKeyItem pKey, u8 *pbyNewRsr, | |
91 | s32 *pbExtIV, u16 *pwRxTSC15_0, u32 *pdwRxTSC47_16); | |
92b96797 | 92 | |
92b96797 FB |
93 | /*+ |
94 | * | |
95 | * Description: | |
96 | * Translate Rcv 802.11 header to 802.3 header with Rx buffer | |
97 | * | |
98 | * Parameters: | |
99 | * In: | |
100 | * pDevice | |
101 | * dwRxBufferAddr - Address of Rcv Buffer | |
102 | * cbPacketSize - Rcv Packet size | |
103 | * bIsWEP - If Rcv with WEP | |
104 | * Out: | |
105 | * pcbHeaderSize - 802.11 header size | |
106 | * | |
107 | * Return Value: None | |
108 | * | |
109 | -*/ | |
45c73bb1 MP |
110 | |
111 | static void s_vProcessRxMACHeader(struct vnt_private *pDevice, | |
112 | u8 *pbyRxBufferAddr, u32 cbPacketSize, int bIsWEP, int bExtIV, | |
113 | u32 *pcbHeadSize) | |
92b96797 | 114 | { |
45c73bb1 MP |
115 | u8 *pbyRxBuffer; |
116 | u32 cbHeaderSize = 0; | |
117 | u16 *pwType; | |
1cac4a4b | 118 | struct ieee80211_hdr *pMACHeader; |
45c73bb1 | 119 | int ii; |
92b96797 | 120 | |
1cac4a4b | 121 | pMACHeader = (struct ieee80211_hdr *) (pbyRxBufferAddr + cbHeaderSize); |
92b96797 | 122 | |
b902fbfe | 123 | s_vGetDASA((u8 *)pMACHeader, &cbHeaderSize, &pDevice->sRxEthHeader); |
92b96797 FB |
124 | |
125 | if (bIsWEP) { | |
126 | if (bExtIV) { | |
127 | // strip IV&ExtIV , add 8 byte | |
128 | cbHeaderSize += (WLAN_HDR_ADDR3_LEN + 8); | |
129 | } else { | |
130 | // strip IV , add 4 byte | |
131 | cbHeaderSize += (WLAN_HDR_ADDR3_LEN + 4); | |
132 | } | |
133 | } | |
134 | else { | |
135 | cbHeaderSize += WLAN_HDR_ADDR3_LEN; | |
136 | }; | |
137 | ||
b902fbfe | 138 | pbyRxBuffer = (u8 *) (pbyRxBufferAddr + cbHeaderSize); |
8329419a | 139 | if (ether_addr_equal(pbyRxBuffer, pDevice->abySNAP_Bridgetunnel)) { |
92b96797 | 140 | cbHeaderSize += 6; |
8329419a | 141 | } else if (ether_addr_equal(pbyRxBuffer, pDevice->abySNAP_RFC1042)) { |
92b96797 | 142 | cbHeaderSize += 6; |
3eaca0d2 | 143 | pwType = (u16 *) (pbyRxBufferAddr + cbHeaderSize); |
aa209eef | 144 | if ((*pwType == cpu_to_be16(ETH_P_IPX)) || |
203e4615 AM |
145 | (*pwType == cpu_to_le16(0xF380))) { |
146 | cbHeaderSize -= 8; | |
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 | } | |
160 | else { | |
161 | cbHeaderSize -= 2; | |
3eaca0d2 | 162 | pwType = (u16 *) (pbyRxBufferAddr + cbHeaderSize); |
92b96797 FB |
163 | if (bIsWEP) { |
164 | if (bExtIV) { | |
165 | *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 8); // 8 is IV&ExtIV | |
166 | } else { | |
167 | *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 4); // 4 is IV | |
168 | } | |
169 | } | |
170 | else { | |
171 | *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN); | |
172 | } | |
173 | } | |
174 | ||
9a0e756c | 175 | cbHeaderSize -= (ETH_ALEN * 2); |
b902fbfe | 176 | pbyRxBuffer = (u8 *) (pbyRxBufferAddr + cbHeaderSize); |
9a0e756c | 177 | for (ii = 0; ii < ETH_ALEN; ii++) |
ceb8c5da | 178 | *pbyRxBuffer++ = pDevice->sRxEthHeader.h_dest[ii]; |
9a0e756c | 179 | for (ii = 0; ii < ETH_ALEN; ii++) |
ceb8c5da | 180 | *pbyRxBuffer++ = pDevice->sRxEthHeader.h_source[ii]; |
92b96797 FB |
181 | |
182 | *pcbHeadSize = cbHeaderSize; | |
183 | } | |
184 | ||
b902fbfe | 185 | static u8 s_byGetRateIdx(u8 byRate) |
92b96797 | 186 | { |
b902fbfe | 187 | u8 byRateIdx; |
92b96797 FB |
188 | |
189 | for (byRateIdx = 0; byRateIdx <MAX_RATE ; byRateIdx++) { | |
190 | if (acbyRxRate[byRateIdx%MAX_RATE] == byRate) | |
191 | return byRateIdx; | |
192 | } | |
193 | return 0; | |
194 | } | |
195 | ||
92b96797 | 196 | static |
8611a29a | 197 | void |
92b96797 | 198 | s_vGetDASA ( |
b902fbfe | 199 | u8 * pbyRxBufferAddr, |
93a94c42 | 200 | unsigned int *pcbHeaderSize, |
ceb8c5da | 201 | struct ethhdr *psEthHeader |
92b96797 FB |
202 | ) |
203 | { | |
cc856e61 | 204 | unsigned int cbHeaderSize = 0; |
1cac4a4b | 205 | struct ieee80211_hdr *pMACHeader; |
9a0e756c AM |
206 | int ii; |
207 | ||
1cac4a4b | 208 | pMACHeader = (struct ieee80211_hdr *) (pbyRxBufferAddr + cbHeaderSize); |
9a0e756c | 209 | |
1cac4a4b AM |
210 | if ((pMACHeader->frame_control & FC_TODS) == 0) { |
211 | if (pMACHeader->frame_control & FC_FROMDS) { | |
9a0e756c | 212 | for (ii = 0; ii < ETH_ALEN; ii++) { |
ceb8c5da | 213 | psEthHeader->h_dest[ii] = |
1cac4a4b | 214 | pMACHeader->addr1[ii]; |
ceb8c5da | 215 | psEthHeader->h_source[ii] = |
1cac4a4b | 216 | pMACHeader->addr3[ii]; |
9a0e756c AM |
217 | } |
218 | } else { | |
219 | /* IBSS mode */ | |
220 | for (ii = 0; ii < ETH_ALEN; ii++) { | |
ceb8c5da | 221 | psEthHeader->h_dest[ii] = |
1cac4a4b | 222 | pMACHeader->addr1[ii]; |
ceb8c5da | 223 | psEthHeader->h_source[ii] = |
1cac4a4b | 224 | pMACHeader->addr2[ii]; |
9a0e756c AM |
225 | } |
226 | } | |
227 | } else { | |
228 | /* Is AP mode.. */ | |
1cac4a4b | 229 | if (pMACHeader->frame_control & FC_FROMDS) { |
9a0e756c | 230 | for (ii = 0; ii < ETH_ALEN; ii++) { |
ceb8c5da | 231 | psEthHeader->h_dest[ii] = |
1cac4a4b | 232 | pMACHeader->addr3[ii]; |
ceb8c5da | 233 | psEthHeader->h_source[ii] = |
1cac4a4b | 234 | pMACHeader->addr4[ii]; |
9a0e756c AM |
235 | cbHeaderSize += 6; |
236 | } | |
237 | } else { | |
238 | for (ii = 0; ii < ETH_ALEN; ii++) { | |
ceb8c5da | 239 | psEthHeader->h_dest[ii] = |
1cac4a4b | 240 | pMACHeader->addr3[ii]; |
ceb8c5da | 241 | psEthHeader->h_source[ii] = |
1cac4a4b | 242 | pMACHeader->addr2[ii]; |
9a0e756c AM |
243 | } |
244 | } | |
245 | }; | |
92b96797 FB |
246 | *pcbHeaderSize = cbHeaderSize; |
247 | } | |
248 | ||
115cac2e | 249 | int RXbBulkInProcessData(struct vnt_private *pDevice, struct vnt_rcb *pRCB, |
45c73bb1 | 250 | unsigned long BytesToIndicate) |
92b96797 | 251 | { |
45c73bb1 MP |
252 | struct net_device_stats *pStats = &pDevice->stats; |
253 | struct sk_buff *skb; | |
254 | struct vnt_manager *pMgmt = &pDevice->vnt_mgmt; | |
255 | struct vnt_rx_mgmt *pRxPacket = &pMgmt->sRxPacket; | |
1cac4a4b | 256 | struct ieee80211_hdr *p802_11Header; |
45c73bb1 | 257 | u8 *pbyRsr, *pbyNewRsr, *pbyRSSI, *pbyFrame; |
7c65fa2a | 258 | u64 *pqwTSFTime; |
e269fc2d | 259 | u32 bDeFragRx = false; |
45c73bb1 | 260 | u32 cbHeaderOffset, cbIVOffset; |
cf5d170e | 261 | u32 FrameSize; |
45c73bb1 MP |
262 | u16 wEtherType = 0; |
263 | s32 iSANodeIndex = -1, iDANodeIndex = -1; | |
264 | int ii; | |
265 | u8 *pbyRxSts, *pbyRxRate, *pbySQ, *pby3SQ; | |
266 | u32 cbHeaderSize; | |
267 | PSKeyItem pKey = NULL; | |
268 | u16 wRxTSC15_0 = 0; | |
269 | u32 dwRxTSC47_16 = 0; | |
270 | SKeyItem STempKey; | |
271 | /* signed long ldBm = 0; */ | |
e269fc2d | 272 | int bIsWEP = false; int bExtIV = false; |
cf5d170e | 273 | u32 dwWbkStatus; |
115cac2e | 274 | struct vnt_rcb *pRCBIndicate = pRCB; |
45c73bb1 MP |
275 | u8 *pbyDAddress; |
276 | u16 *pwPLCP_Length; | |
277 | u8 abyVaildRate[MAX_RATE] | |
278 | = {2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108}; | |
279 | u16 wPLCPwithPadding; | |
1cac4a4b | 280 | struct ieee80211_hdr *pMACHeader; |
e269fc2d | 281 | int bRxeapol_key = false; |
92b96797 | 282 | |
92b96797 FB |
283 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---------- RXbBulkInProcessData---\n"); |
284 | ||
285 | skb = pRCB->skb; | |
286 | ||
cf5d170e MP |
287 | /* [31:16]RcvByteCount ( not include 4-byte Status ) */ |
288 | dwWbkStatus = *((u32 *)(skb->data)); | |
289 | FrameSize = dwWbkStatus >> 16; | |
290 | FrameSize += 4; | |
92b96797 | 291 | |
cf5d170e MP |
292 | if (BytesToIndicate != FrameSize) { |
293 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"------- WRONG Length 1\n"); | |
9a450f9a | 294 | pStats->rx_frame_errors++; |
e269fc2d | 295 | return false; |
cf5d170e | 296 | } |
92b96797 | 297 | |
bd2bc4c7 | 298 | if ((BytesToIndicate > 2372) || (BytesToIndicate <= 40)) { |
92b96797 | 299 | // Frame Size error drop this packet. |
bd2bc4c7 | 300 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "---------- WRONG Length 2\n"); |
9a450f9a | 301 | pStats->rx_frame_errors++; |
e269fc2d | 302 | return false; |
92b96797 FB |
303 | } |
304 | ||
b902fbfe | 305 | pbyDAddress = (u8 *)(skb->data); |
92b96797 FB |
306 | pbyRxSts = pbyDAddress+4; |
307 | pbyRxRate = pbyDAddress+5; | |
308 | ||
309 | //real Frame Size = USBFrameSize -4WbkStatus - 4RxStatus - 8TSF - 4RSR - 4SQ3 - ?Padding | |
310 | //if SQ3 the range is 24~27, if no SQ3 the range is 20~23 | |
311 | //real Frame size in PLCPLength field. | |
3eaca0d2 | 312 | pwPLCP_Length = (u16 *) (pbyDAddress + 6); |
92b96797 FB |
313 | //Fix hardware bug => PLCP_Length error |
314 | if ( ((BytesToIndicate - (*pwPLCP_Length)) > 27) || | |
315 | ((BytesToIndicate - (*pwPLCP_Length)) < 24) || | |
316 | (BytesToIndicate < (*pwPLCP_Length)) ) { | |
317 | ||
318 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Wrong PLCP Length %x\n", (int) *pwPLCP_Length); | |
9a450f9a | 319 | pStats->rx_frame_errors++; |
e269fc2d | 320 | return false; |
92b96797 FB |
321 | } |
322 | for ( ii=RATE_1M;ii<MAX_RATE;ii++) { | |
323 | if ( *pbyRxRate == abyVaildRate[ii] ) { | |
324 | break; | |
325 | } | |
326 | } | |
327 | if ( ii==MAX_RATE ) { | |
328 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Wrong RxRate %x\n",(int) *pbyRxRate); | |
e269fc2d | 329 | return false; |
92b96797 FB |
330 | } |
331 | ||
332 | wPLCPwithPadding = ( (*pwPLCP_Length / 4) + ( (*pwPLCP_Length % 4) ? 1:0 ) ) *4; | |
333 | ||
7c65fa2a | 334 | pqwTSFTime = (u64 *)(pbyDAddress + 8 + wPLCPwithPadding); |
92b96797 FB |
335 | if(pDevice->byBBType == BB_TYPE_11G) { |
336 | pby3SQ = pbyDAddress + 8 + wPLCPwithPadding + 12; | |
337 | pbySQ = pby3SQ; | |
338 | } | |
339 | else { | |
340 | pbySQ = pbyDAddress + 8 + wPLCPwithPadding + 8; | |
341 | pby3SQ = pbySQ; | |
342 | } | |
92b96797 FB |
343 | pbyNewRsr = pbyDAddress + 8 + wPLCPwithPadding + 9; |
344 | pbyRSSI = pbyDAddress + 8 + wPLCPwithPadding + 10; | |
345 | pbyRsr = pbyDAddress + 8 + wPLCPwithPadding + 11; | |
346 | ||
347 | FrameSize = *pwPLCP_Length; | |
348 | ||
349 | pbyFrame = pbyDAddress + 8; | |
350 | // update receive statistic counter | |
351 | ||
352 | STAvUpdateRDStatCounter(&pDevice->scStatistic, | |
353 | *pbyRsr, | |
354 | *pbyNewRsr, | |
355 | *pbyRxSts, | |
356 | *pbyRxRate, | |
357 | pbyFrame, | |
358 | FrameSize | |
359 | ); | |
360 | ||
1cac4a4b | 361 | pMACHeader = (struct ieee80211_hdr *) pbyFrame; |
92b96797 FB |
362 | |
363 | //mike add: to judge if current AP is activated? | |
364 | if ((pMgmt->eCurrMode == WMAC_MODE_STANDBY) || | |
365 | (pMgmt->eCurrMode == WMAC_MODE_ESS_STA)) { | |
366 | if (pMgmt->sNodeDBTable[0].bActive) { | |
8329419a | 367 | if (ether_addr_equal(pMgmt->abyCurrBSSID, pMACHeader->addr2)) { |
92b96797 FB |
368 | if (pMgmt->sNodeDBTable[0].uInActiveCount != 0) |
369 | pMgmt->sNodeDBTable[0].uInActiveCount = 0; | |
370 | } | |
371 | } | |
372 | } | |
373 | ||
1cac4a4b AM |
374 | if (!is_multicast_ether_addr(pMACHeader->addr1)) { |
375 | if (WCTLbIsDuplicate(&(pDevice->sDupRxCache), (struct ieee80211_hdr *) pbyFrame)) { | |
92b96797 | 376 | pDevice->s802_11Counter.FrameDuplicateCount++; |
e269fc2d | 377 | return false; |
92b96797 FB |
378 | } |
379 | ||
8329419a | 380 | if (!ether_addr_equal(pDevice->abyCurrentNetAddr, pMACHeader->addr1)) { |
e269fc2d | 381 | return false; |
92b96797 FB |
382 | } |
383 | } | |
384 | ||
92b96797 FB |
385 | // Use for TKIP MIC |
386 | s_vGetDASA(pbyFrame, &cbHeaderSize, &pDevice->sRxEthHeader); | |
387 | ||
8329419a JP |
388 | if (ether_addr_equal((u8 *)pDevice->sRxEthHeader.h_source, |
389 | pDevice->abyCurrentNetAddr)) | |
e269fc2d | 390 | return false; |
92b96797 FB |
391 | |
392 | if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) || (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) { | |
393 | if (IS_CTL_PSPOLL(pbyFrame) || !IS_TYPE_CONTROL(pbyFrame)) { | |
1cac4a4b | 394 | p802_11Header = (struct ieee80211_hdr *) (pbyFrame); |
92b96797 | 395 | // get SA NodeIndex |
1cac4a4b | 396 | if (BSSbIsSTAInNodeDB(pDevice, (u8 *)(p802_11Header->addr2), &iSANodeIndex)) { |
92b96797 FB |
397 | pMgmt->sNodeDBTable[iSANodeIndex].ulLastRxJiffer = jiffies; |
398 | pMgmt->sNodeDBTable[iSANodeIndex].uInActiveCount = 0; | |
399 | } | |
400 | } | |
401 | } | |
402 | ||
403 | if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { | |
4e9b5e2b | 404 | if (s_bAPModeRxCtl(pDevice, pbyFrame, iSANodeIndex) == true) { |
e269fc2d | 405 | return false; |
92b96797 FB |
406 | } |
407 | } | |
408 | ||
92b96797 | 409 | if (IS_FC_WEP(pbyFrame)) { |
e269fc2d | 410 | bool bRxDecryOK = false; |
92b96797 FB |
411 | |
412 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"rx WEP pkt\n"); | |
4e9b5e2b | 413 | bIsWEP = true; |
92b96797 FB |
414 | if ((pDevice->bEnableHostWEP) && (iSANodeIndex >= 0)) { |
415 | pKey = &STempKey; | |
416 | pKey->byCipherSuite = pMgmt->sNodeDBTable[iSANodeIndex].byCipherSuite; | |
417 | pKey->dwKeyIndex = pMgmt->sNodeDBTable[iSANodeIndex].dwKeyIndex; | |
418 | pKey->uKeyLength = pMgmt->sNodeDBTable[iSANodeIndex].uWepKeyLength; | |
419 | pKey->dwTSC47_16 = pMgmt->sNodeDBTable[iSANodeIndex].dwTSC47_16; | |
420 | pKey->wTSC15_0 = pMgmt->sNodeDBTable[iSANodeIndex].wTSC15_0; | |
421 | memcpy(pKey->abyKey, | |
422 | &pMgmt->sNodeDBTable[iSANodeIndex].abyWepKey[0], | |
423 | pKey->uKeyLength | |
424 | ); | |
425 | ||
426 | bRxDecryOK = s_bHostWepRxEncryption(pDevice, | |
427 | pbyFrame, | |
428 | FrameSize, | |
429 | pbyRsr, | |
430 | pMgmt->sNodeDBTable[iSANodeIndex].bOnFly, | |
431 | pKey, | |
432 | pbyNewRsr, | |
433 | &bExtIV, | |
434 | &wRxTSC15_0, | |
435 | &dwRxTSC47_16); | |
436 | } else { | |
437 | bRxDecryOK = s_bHandleRxEncryption(pDevice, | |
438 | pbyFrame, | |
439 | FrameSize, | |
440 | pbyRsr, | |
441 | pbyNewRsr, | |
442 | &pKey, | |
443 | &bExtIV, | |
444 | &wRxTSC15_0, | |
445 | &dwRxTSC47_16); | |
446 | } | |
447 | ||
448 | if (bRxDecryOK) { | |
449 | if ((*pbyNewRsr & NEWRSR_DECRYPTOK) == 0) { | |
450 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV Fail\n"); | |
451 | if ( (pMgmt->eAuthenMode == WMAC_AUTH_WPA) || | |
452 | (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) || | |
453 | (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) || | |
454 | (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || | |
455 | (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) { | |
456 | ||
457 | if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_TKIP)) { | |
458 | pDevice->s802_11Counter.TKIPICVErrors++; | |
459 | } else if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_CCMP)) { | |
460 | pDevice->s802_11Counter.CCMPDecryptErrors++; | |
461 | } else if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_WEP)) { | |
462 | // pDevice->s802_11Counter.WEPICVErrorCount.QuadPart++; | |
463 | } | |
464 | } | |
e269fc2d | 465 | return false; |
92b96797 FB |
466 | } |
467 | } else { | |
468 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"WEP Func Fail\n"); | |
e269fc2d | 469 | return false; |
92b96797 FB |
470 | } |
471 | if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_CCMP)) | |
472 | FrameSize -= 8; // Message Integrity Code | |
473 | else | |
474 | FrameSize -= 4; // 4 is ICV | |
475 | } | |
476 | ||
92b96797 FB |
477 | // |
478 | // RX OK | |
479 | // | |
abad19d0 AM |
480 | /* remove the FCS/CRC length */ |
481 | FrameSize -= ETH_FCS_LEN; | |
92b96797 | 482 | |
8a3d91b0 | 483 | if ( !(*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI)) && // unicast address |
92b96797 FB |
484 | (IS_FRAGMENT_PKT((pbyFrame))) |
485 | ) { | |
486 | // defragment | |
1cac4a4b | 487 | bDeFragRx = WCTLbHandleFragment(pDevice, (struct ieee80211_hdr *) (pbyFrame), FrameSize, bIsWEP, bExtIV); |
92b96797 FB |
488 | pDevice->s802_11Counter.ReceivedFragmentCount++; |
489 | if (bDeFragRx) { | |
490 | // defrag complete | |
491 | // TODO skb, pbyFrame | |
492 | skb = pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].skb; | |
493 | FrameSize = pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength; | |
494 | pbyFrame = skb->data + 8; | |
495 | } | |
496 | else { | |
e269fc2d | 497 | return false; |
92b96797 FB |
498 | } |
499 | } | |
500 | ||
501 | // | |
502 | // Management & Control frame Handle | |
503 | // | |
e269fc2d | 504 | if ((IS_TYPE_DATA((pbyFrame))) == false) { |
92b96797 FB |
505 | // Handle Control & Manage Frame |
506 | ||
507 | if (IS_TYPE_MGMT((pbyFrame))) { | |
b902fbfe AM |
508 | u8 * pbyData1; |
509 | u8 * pbyData2; | |
92b96797 FB |
510 | |
511 | pRxPacket = &(pRCB->sMngPacket); | |
512 | pRxPacket->p80211Header = (PUWLAN_80211HDR)(pbyFrame); | |
513 | pRxPacket->cbMPDULen = FrameSize; | |
514 | pRxPacket->uRSSI = *pbyRSSI; | |
515 | pRxPacket->bySQ = *pbySQ; | |
7c65fa2a | 516 | pRxPacket->qwLocalTSF = cpu_to_le64(*pqwTSFTime); |
92b96797 FB |
517 | if (bIsWEP) { |
518 | // strip IV | |
519 | pbyData1 = WLAN_HDR_A3_DATA_PTR(pbyFrame); | |
520 | pbyData2 = WLAN_HDR_A3_DATA_PTR(pbyFrame) + 4; | |
521 | for (ii = 0; ii < (FrameSize - 4); ii++) { | |
522 | *pbyData1 = *pbyData2; | |
523 | pbyData1++; | |
524 | pbyData2++; | |
525 | } | |
526 | } | |
527 | ||
528 | pRxPacket->byRxRate = s_byGetRateIdx(*pbyRxRate); | |
529 | ||
530 | if ( *pbyRxSts == 0 ) { | |
531 | //Discard beacon packet which channel is 0 | |
532 | if ( (WLAN_GET_FC_FSTYPE((pRxPacket->p80211Header->sA3.wFrameCtl)) == WLAN_FSTYPE_BEACON) || | |
533 | (WLAN_GET_FC_FSTYPE((pRxPacket->p80211Header->sA3.wFrameCtl)) == WLAN_FSTYPE_PROBERESP) ) { | |
e269fc2d | 534 | return false; |
92b96797 FB |
535 | } |
536 | } | |
537 | pRxPacket->byRxChannel = (*pbyRxSts) >> 2; | |
538 | ||
539 | // hostap Deamon handle 802.11 management | |
540 | if (pDevice->bEnableHostapd) { | |
541 | skb->dev = pDevice->apdev; | |
542 | //skb->data += 4; | |
543 | //skb->tail += 4; | |
544 | skb->data += 8; | |
545 | skb->tail += 8; | |
546 | skb_put(skb, FrameSize); | |
d899d403 | 547 | skb_reset_mac_header(skb); |
92b96797 FB |
548 | skb->pkt_type = PACKET_OTHERHOST; |
549 | skb->protocol = htons(ETH_P_802_2); | |
550 | memset(skb->cb, 0, sizeof(skb->cb)); | |
551 | netif_rx(skb); | |
4e9b5e2b | 552 | return true; |
92b96797 FB |
553 | } |
554 | ||
555 | // | |
556 | // Insert the RCB in the Recv Mng list | |
557 | // | |
558 | EnqueueRCB(pDevice->FirstRecvMngList, pDevice->LastRecvMngList, pRCBIndicate); | |
559 | pDevice->NumRecvMngList++; | |
e269fc2d | 560 | if ( bDeFragRx == false) { |
92b96797 FB |
561 | pRCB->Ref++; |
562 | } | |
e269fc2d | 563 | if (pDevice->bIsRxMngWorkItemQueued == false) { |
4e9b5e2b | 564 | pDevice->bIsRxMngWorkItemQueued = true; |
a21fc2f5 | 565 | schedule_work(&pDevice->rx_mng_work_item); |
92b96797 FB |
566 | } |
567 | ||
568 | } | |
569 | else { | |
570 | // Control Frame | |
571 | }; | |
e269fc2d | 572 | return false; |
92b96797 FB |
573 | } |
574 | else { | |
575 | if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { | |
576 | //In AP mode, hw only check addr1(BSSID or RA) if equal to local MAC. | |
8a3d91b0 | 577 | if ( !(*pbyRsr & RSR_BSSIDOK)) { |
92b96797 FB |
578 | if (bDeFragRx) { |
579 | if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) { | |
580 | DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n", | |
581 | pDevice->dev->name); | |
582 | } | |
583 | } | |
e269fc2d | 584 | return false; |
92b96797 FB |
585 | } |
586 | } | |
587 | else { | |
588 | // discard DATA packet while not associate || BSSID error | |
e269fc2d | 589 | if ((pDevice->bLinkPass == false) || |
8a3d91b0 | 590 | !(*pbyRsr & RSR_BSSIDOK)) { |
92b96797 FB |
591 | if (bDeFragRx) { |
592 | if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) { | |
593 | DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n", | |
594 | pDevice->dev->name); | |
595 | } | |
596 | } | |
e269fc2d | 597 | return false; |
92b96797 FB |
598 | } |
599 | //mike add:station mode check eapol-key challenge---> | |
600 | { | |
b902fbfe AM |
601 | u8 Protocol_Version; //802.1x Authentication |
602 | u8 Packet_Type; //802.1x Authentication | |
603 | u8 Descriptor_type; | |
3eaca0d2 | 604 | u16 Key_info; |
92b96797 FB |
605 | if (bIsWEP) |
606 | cbIVOffset = 8; | |
607 | else | |
608 | cbIVOffset = 0; | |
609 | wEtherType = (skb->data[cbIVOffset + 8 + 24 + 6] << 8) | | |
610 | skb->data[cbIVOffset + 8 + 24 + 6 + 1]; | |
611 | Protocol_Version = skb->data[cbIVOffset + 8 + 24 + 6 + 1 +1]; | |
612 | Packet_Type = skb->data[cbIVOffset + 8 + 24 + 6 + 1 +1+1]; | |
613 | if (wEtherType == ETH_P_PAE) { //Protocol Type in LLC-Header | |
614 | if(((Protocol_Version==1) ||(Protocol_Version==2)) && | |
615 | (Packet_Type==3)) { //802.1x OR eapol-key challenge frame receive | |
4e9b5e2b | 616 | bRxeapol_key = true; |
92b96797 FB |
617 | Descriptor_type = skb->data[cbIVOffset + 8 + 24 + 6 + 1 +1+1+1+2]; |
618 | 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] ; | |
619 | if(Descriptor_type==2) { //RSN | |
620 | // printk("WPA2_Rx_eapol-key_info<-----:%x\n",Key_info); | |
621 | } | |
622 | else if(Descriptor_type==254) { | |
623 | // printk("WPA_Rx_eapol-key_info<-----:%x\n",Key_info); | |
624 | } | |
625 | } | |
626 | } | |
627 | } | |
628 | //mike add:station mode check eapol-key challenge<--- | |
629 | } | |
630 | } | |
631 | ||
92b96797 FB |
632 | // Data frame Handle |
633 | ||
92b96797 FB |
634 | if (pDevice->bEnablePSMode) { |
635 | if (IS_FC_MOREDATA((pbyFrame))) { | |
8a3d91b0 | 636 | if (*pbyRsr & RSR_ADDROK) { |
92b96797 FB |
637 | //PSbSendPSPOLL((PSDevice)pDevice); |
638 | } | |
639 | } | |
640 | else { | |
4e9b5e2b | 641 | if (pMgmt->bInTIMWake == true) { |
e269fc2d | 642 | pMgmt->bInTIMWake = false; |
92b96797 FB |
643 | } |
644 | } | |
9fc86028 | 645 | } |
92b96797 FB |
646 | |
647 | // Now it only supports 802.11g Infrastructure Mode, and support rate must up to 54 Mbps | |
648 | if (pDevice->bDiversityEnable && (FrameSize>50) && | |
649 | (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) && | |
4e9b5e2b | 650 | (pDevice->bLinkPass == true)) { |
92b96797 FB |
651 | BBvAntennaDiversity(pDevice, s_byGetRateIdx(*pbyRxRate), 0); |
652 | } | |
653 | ||
654 | // ++++++++ For BaseBand Algorithm +++++++++++++++ | |
655 | pDevice->uCurrRSSI = *pbyRSSI; | |
656 | pDevice->byCurrSQ = *pbySQ; | |
657 | ||
658 | // todo | |
659 | /* | |
660 | if ((*pbyRSSI != 0) && | |
661 | (pMgmt->pCurrBSS!=NULL)) { | |
662 | RFvRSSITodBm(pDevice, *pbyRSSI, &ldBm); | |
a0a1f61a | 663 | // Monitor if RSSI is too strong. |
92b96797 FB |
664 | pMgmt->pCurrBSS->byRSSIStatCnt++; |
665 | pMgmt->pCurrBSS->byRSSIStatCnt %= RSSI_STAT_COUNT; | |
666 | pMgmt->pCurrBSS->ldBmAverage[pMgmt->pCurrBSS->byRSSIStatCnt] = ldBm; | |
33d33e42 AM |
667 | for (ii = 0; ii < RSSI_STAT_COUNT; ii++) { |
668 | if (pMgmt->pCurrBSS->ldBmAverage[ii] != 0) { | |
669 | pMgmt->pCurrBSS->ldBmMAX = | |
670 | max(pMgmt->pCurrBSS->ldBmAverage[ii], ldBm); | |
671 | } | |
92b96797 FB |
672 | } |
673 | } | |
674 | */ | |
675 | ||
92b96797 FB |
676 | // ----------------------------------------------- |
677 | ||
4e9b5e2b | 678 | if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && (pDevice->bEnable8021x == true)){ |
b902fbfe | 679 | u8 abyMacHdr[24]; |
92b96797 FB |
680 | |
681 | // Only 802.1x packet incoming allowed | |
682 | if (bIsWEP) | |
683 | cbIVOffset = 8; | |
684 | else | |
685 | cbIVOffset = 0; | |
686 | wEtherType = (skb->data[cbIVOffset + 8 + 24 + 6] << 8) | | |
687 | skb->data[cbIVOffset + 8 + 24 + 6 + 1]; | |
688 | ||
689 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wEtherType = %04x \n", wEtherType); | |
690 | if (wEtherType == ETH_P_PAE) { | |
691 | skb->dev = pDevice->apdev; | |
692 | ||
4e9b5e2b | 693 | if (bIsWEP == true) { |
92b96797 FB |
694 | // strip IV header(8) |
695 | memcpy(&abyMacHdr[0], (skb->data + 8), 24); | |
696 | memcpy((skb->data + 8 + cbIVOffset), &abyMacHdr[0], 24); | |
697 | } | |
698 | ||
699 | skb->data += (cbIVOffset + 8); | |
700 | skb->tail += (cbIVOffset + 8); | |
701 | skb_put(skb, FrameSize); | |
d899d403 | 702 | skb_reset_mac_header(skb); |
92b96797 FB |
703 | skb->pkt_type = PACKET_OTHERHOST; |
704 | skb->protocol = htons(ETH_P_802_2); | |
705 | memset(skb->cb, 0, sizeof(skb->cb)); | |
706 | netif_rx(skb); | |
4e9b5e2b | 707 | return true; |
92b96797 FB |
708 | |
709 | } | |
710 | // check if 802.1x authorized | |
711 | if (!(pMgmt->sNodeDBTable[iSANodeIndex].dwFlags & WLAN_STA_AUTHORIZED)) | |
e269fc2d | 712 | return false; |
92b96797 FB |
713 | } |
714 | ||
92b96797 FB |
715 | if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_TKIP)) { |
716 | if (bIsWEP) { | |
717 | FrameSize -= 8; //MIC | |
718 | } | |
719 | } | |
720 | ||
721 | //-------------------------------------------------------------------------------- | |
722 | // Soft MIC | |
723 | if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_TKIP)) { | |
724 | if (bIsWEP) { | |
52a7e64b AM |
725 | u32 * pdwMIC_L; |
726 | u32 * pdwMIC_R; | |
727 | u32 dwMIC_Priority; | |
728 | u32 dwMICKey0 = 0, dwMICKey1 = 0; | |
729 | u32 dwLocalMIC_L = 0; | |
730 | u32 dwLocalMIC_R = 0; | |
92b96797 | 731 | |
92b96797 | 732 | if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { |
52a7e64b AM |
733 | dwMICKey0 = cpu_to_le32(*(u32 *)(&pKey->abyKey[24])); |
734 | dwMICKey1 = cpu_to_le32(*(u32 *)(&pKey->abyKey[28])); | |
92b96797 FB |
735 | } |
736 | else { | |
737 | if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) { | |
52a7e64b AM |
738 | dwMICKey0 = cpu_to_le32(*(u32 *)(&pKey->abyKey[16])); |
739 | dwMICKey1 = cpu_to_le32(*(u32 *)(&pKey->abyKey[20])); | |
92b96797 | 740 | } else if ((pKey->dwKeyIndex & BIT28) == 0) { |
52a7e64b AM |
741 | dwMICKey0 = cpu_to_le32(*(u32 *)(&pKey->abyKey[16])); |
742 | dwMICKey1 = cpu_to_le32(*(u32 *)(&pKey->abyKey[20])); | |
92b96797 | 743 | } else { |
52a7e64b AM |
744 | dwMICKey0 = cpu_to_le32(*(u32 *)(&pKey->abyKey[24])); |
745 | dwMICKey1 = cpu_to_le32(*(u32 *)(&pKey->abyKey[28])); | |
92b96797 FB |
746 | } |
747 | } | |
748 | ||
749 | MIC_vInit(dwMICKey0, dwMICKey1); | |
ceb8c5da | 750 | MIC_vAppend((u8 *)&(pDevice->sRxEthHeader.h_dest[0]), 12); |
92b96797 | 751 | dwMIC_Priority = 0; |
b902fbfe | 752 | MIC_vAppend((u8 *)&dwMIC_Priority, 4); |
92b96797 | 753 | // 4 is Rcv buffer header, 24 is MAC Header, and 8 is IV and Ext IV. |
b902fbfe | 754 | MIC_vAppend((u8 *)(skb->data + 8 + WLAN_HDR_ADDR3_LEN + 8), |
92b96797 FB |
755 | FrameSize - WLAN_HDR_ADDR3_LEN - 8); |
756 | MIC_vGetMIC(&dwLocalMIC_L, &dwLocalMIC_R); | |
757 | MIC_vUnInit(); | |
758 | ||
52a7e64b AM |
759 | pdwMIC_L = (u32 *)(skb->data + 8 + FrameSize); |
760 | pdwMIC_R = (u32 *)(skb->data + 8 + FrameSize + 4); | |
92b96797 | 761 | |
92b96797 | 762 | if ((cpu_to_le32(*pdwMIC_L) != dwLocalMIC_L) || (cpu_to_le32(*pdwMIC_R) != dwLocalMIC_R) || |
4e9b5e2b | 763 | (pDevice->bRxMICFail == true)) { |
92b96797 | 764 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC comparison is fail!\n"); |
e269fc2d | 765 | pDevice->bRxMICFail = false; |
92b96797 FB |
766 | //pDevice->s802_11Counter.TKIPLocalMICFailures.QuadPart++; |
767 | pDevice->s802_11Counter.TKIPLocalMICFailures++; | |
768 | if (bDeFragRx) { | |
769 | if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) { | |
770 | DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n", | |
771 | pDevice->dev->name); | |
772 | } | |
773 | } | |
92b96797 | 774 | //send event to wpa_supplicant |
4e9b5e2b | 775 | //if(pDevice->bWPASuppWextEnabled == true) |
92b96797 FB |
776 | { |
777 | union iwreq_data wrqu; | |
778 | struct iw_michaelmicfailure ev; | |
779 | int keyidx = pbyFrame[cbHeaderSize+3] >> 6; //top two-bits | |
780 | memset(&ev, 0, sizeof(ev)); | |
781 | ev.flags = keyidx & IW_MICFAILURE_KEY_ID; | |
782 | if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && | |
783 | (pMgmt->eCurrState == WMAC_STATE_ASSOC) && | |
784 | (*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI)) == 0) { | |
785 | ev.flags |= IW_MICFAILURE_PAIRWISE; | |
786 | } else { | |
787 | ev.flags |= IW_MICFAILURE_GROUP; | |
788 | } | |
789 | ||
790 | ev.src_addr.sa_family = ARPHRD_ETHER; | |
1cac4a4b | 791 | memcpy(ev.src_addr.sa_data, pMACHeader->addr2, ETH_ALEN); |
92b96797 FB |
792 | memset(&wrqu, 0, sizeof(wrqu)); |
793 | wrqu.data.length = sizeof(ev); | |
794 | PRINT_K("wireless_send_event--->IWEVMICHAELMICFAILURE\n"); | |
795 | wireless_send_event(pDevice->dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&ev); | |
796 | ||
797 | } | |
92b96797 | 798 | |
e269fc2d | 799 | return false; |
92b96797 FB |
800 | |
801 | } | |
802 | } | |
803 | } //---end of SOFT MIC----------------------------------------------------------------------- | |
804 | ||
805 | // ++++++++++ Reply Counter Check +++++++++++++ | |
806 | ||
807 | if ((pKey != NULL) && ((pKey->byCipherSuite == KEY_CTL_TKIP) || | |
808 | (pKey->byCipherSuite == KEY_CTL_CCMP))) { | |
809 | if (bIsWEP) { | |
3eaca0d2 | 810 | u16 wLocalTSC15_0 = 0; |
52a7e64b | 811 | u32 dwLocalTSC47_16 = 0; |
cc856e61 | 812 | unsigned long long RSC = 0; |
92b96797 | 813 | // endian issues |
cc856e61 | 814 | RSC = *((unsigned long long *) &(pKey->KeyRSC)); |
3eaca0d2 | 815 | wLocalTSC15_0 = (u16) RSC; |
52a7e64b | 816 | dwLocalTSC47_16 = (u32) (RSC>>16); |
92b96797 FB |
817 | |
818 | RSC = dwRxTSC47_16; | |
819 | RSC <<= 16; | |
820 | RSC += wRxTSC15_0; | |
7c65fa2a | 821 | memcpy(&(pKey->KeyRSC), &RSC, sizeof(u64)); |
92b96797 | 822 | |
14c5ef57 MP |
823 | if (pDevice->vnt_mgmt.eCurrMode == WMAC_MODE_ESS_STA && |
824 | pDevice->vnt_mgmt.eCurrState == WMAC_STATE_ASSOC) { | |
825 | /* check RSC */ | |
92b96797 FB |
826 | if ( (wRxTSC15_0 < wLocalTSC15_0) && |
827 | (dwRxTSC47_16 <= dwLocalTSC47_16) && | |
828 | !((dwRxTSC47_16 == 0) && (dwLocalTSC47_16 == 0xFFFFFFFF))) { | |
829 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"TSC is illegal~~!\n "); | |
830 | if (pKey->byCipherSuite == KEY_CTL_TKIP) | |
831 | //pDevice->s802_11Counter.TKIPReplays.QuadPart++; | |
832 | pDevice->s802_11Counter.TKIPReplays++; | |
833 | else | |
834 | //pDevice->s802_11Counter.CCMPReplays.QuadPart++; | |
835 | pDevice->s802_11Counter.CCMPReplays++; | |
836 | ||
837 | if (bDeFragRx) { | |
838 | if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) { | |
839 | DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n", | |
840 | pDevice->dev->name); | |
841 | } | |
842 | } | |
e269fc2d | 843 | return false; |
92b96797 FB |
844 | } |
845 | } | |
846 | } | |
847 | } // ----- End of Reply Counter Check -------------------------- | |
848 | ||
b902fbfe | 849 | s_vProcessRxMACHeader(pDevice, (u8 *)(skb->data+8), FrameSize, bIsWEP, bExtIV, &cbHeaderOffset); |
92b96797 FB |
850 | FrameSize -= cbHeaderOffset; |
851 | cbHeaderOffset += 8; // 8 is Rcv buffer header | |
852 | ||
853 | // Null data, framesize = 12 | |
854 | if (FrameSize < 12) | |
e269fc2d | 855 | return false; |
92b96797 FB |
856 | |
857 | if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { | |
858 | if (s_bAPModeRxData(pDevice, | |
859 | skb, | |
860 | FrameSize, | |
861 | cbHeaderOffset, | |
862 | iSANodeIndex, | |
863 | iDANodeIndex | |
e269fc2d | 864 | ) == false) { |
92b96797 FB |
865 | |
866 | if (bDeFragRx) { | |
867 | if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) { | |
868 | DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n", | |
869 | pDevice->dev->name); | |
870 | } | |
871 | } | |
e269fc2d | 872 | return false; |
92b96797 FB |
873 | } |
874 | ||
875 | } | |
876 | ||
877 | skb->data += cbHeaderOffset; | |
878 | skb->tail += cbHeaderOffset; | |
879 | skb_put(skb, FrameSize); | |
880 | skb->protocol=eth_type_trans(skb, skb->dev); | |
881 | skb->ip_summed=CHECKSUM_NONE; | |
882 | pStats->rx_bytes +=skb->len; | |
883 | pStats->rx_packets++; | |
884 | netif_rx(skb); | |
885 | if (bDeFragRx) { | |
886 | if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) { | |
887 | DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n", | |
888 | pDevice->dev->name); | |
889 | } | |
e269fc2d | 890 | return false; |
92b96797 FB |
891 | } |
892 | ||
4e9b5e2b | 893 | return true; |
92b96797 FB |
894 | } |
895 | ||
45c73bb1 MP |
896 | static int s_bAPModeRxCtl(struct vnt_private *pDevice, u8 *pbyFrame, |
897 | s32 iSANodeIndex) | |
92b96797 | 898 | { |
14c5ef57 | 899 | struct vnt_manager *pMgmt = &pDevice->vnt_mgmt; |
1cac4a4b | 900 | struct ieee80211_hdr *p802_11Header; |
45c73bb1 | 901 | CMD_STATUS Status; |
92b96797 | 902 | |
92b96797 FB |
903 | if (IS_CTL_PSPOLL(pbyFrame) || !IS_TYPE_CONTROL(pbyFrame)) { |
904 | ||
1cac4a4b | 905 | p802_11Header = (struct ieee80211_hdr *) (pbyFrame); |
92b96797 FB |
906 | if (!IS_TYPE_MGMT(pbyFrame)) { |
907 | ||
908 | // Data & PS-Poll packet | |
909 | // check frame class | |
910 | if (iSANodeIndex > 0) { | |
911 | // frame class 3 fliter & checking | |
912 | if (pMgmt->sNodeDBTable[iSANodeIndex].eNodeState < NODE_AUTH) { | |
913 | // send deauth notification | |
914 | // reason = (6) class 2 received from nonauth sta | |
915 | vMgrDeAuthenBeginSta(pDevice, | |
916 | pMgmt, | |
1cac4a4b | 917 | (u8 *)(p802_11Header->addr2), |
92b96797 FB |
918 | (WLAN_MGMT_REASON_CLASS2_NONAUTH), |
919 | &Status | |
920 | ); | |
921 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: send vMgrDeAuthenBeginSta 1\n"); | |
4e9b5e2b | 922 | return true; |
9fc86028 | 923 | } |
92b96797 FB |
924 | if (pMgmt->sNodeDBTable[iSANodeIndex].eNodeState < NODE_ASSOC) { |
925 | // send deassoc notification | |
926 | // reason = (7) class 3 received from nonassoc sta | |
927 | vMgrDisassocBeginSta(pDevice, | |
928 | pMgmt, | |
1cac4a4b | 929 | (u8 *)(p802_11Header->addr2), |
92b96797 FB |
930 | (WLAN_MGMT_REASON_CLASS3_NONASSOC), |
931 | &Status | |
932 | ); | |
933 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: send vMgrDisassocBeginSta 2\n"); | |
4e9b5e2b | 934 | return true; |
9fc86028 | 935 | } |
92b96797 FB |
936 | |
937 | if (pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable) { | |
938 | // delcare received ps-poll event | |
939 | if (IS_CTL_PSPOLL(pbyFrame)) { | |
4e9b5e2b | 940 | pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = true; |
0cbd8d98 AM |
941 | bScheduleCommand((void *) pDevice, |
942 | WLAN_CMD_RX_PSPOLL, | |
943 | NULL); | |
92b96797 FB |
944 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: WLAN_CMD_RX_PSPOLL 1\n"); |
945 | } | |
946 | else { | |
947 | // check Data PS state | |
948 | // if PW bit off, send out all PS bufferring packets. | |
949 | if (!IS_FC_POWERMGT(pbyFrame)) { | |
e269fc2d | 950 | pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = false; |
4e9b5e2b | 951 | pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = true; |
0cbd8d98 AM |
952 | bScheduleCommand((void *) pDevice, |
953 | WLAN_CMD_RX_PSPOLL, | |
954 | NULL); | |
92b96797 FB |
955 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: WLAN_CMD_RX_PSPOLL 2\n"); |
956 | } | |
957 | } | |
958 | } | |
959 | else { | |
960 | if (IS_FC_POWERMGT(pbyFrame)) { | |
4e9b5e2b | 961 | pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = true; |
92b96797 | 962 | // Once if STA in PS state, enable multicast bufferring |
4e9b5e2b | 963 | pMgmt->sNodeDBTable[0].bPSEnable = true; |
92b96797 FB |
964 | } |
965 | else { | |
966 | // clear all pending PS frame. | |
967 | if (pMgmt->sNodeDBTable[iSANodeIndex].wEnQueueCnt > 0) { | |
e269fc2d | 968 | pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = false; |
4e9b5e2b | 969 | pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = true; |
0cbd8d98 AM |
970 | bScheduleCommand((void *) pDevice, |
971 | WLAN_CMD_RX_PSPOLL, | |
972 | NULL); | |
92b96797 FB |
973 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: WLAN_CMD_RX_PSPOLL 3\n"); |
974 | ||
975 | } | |
976 | } | |
977 | } | |
978 | } | |
979 | else { | |
980 | vMgrDeAuthenBeginSta(pDevice, | |
981 | pMgmt, | |
1cac4a4b | 982 | (u8 *)(p802_11Header->addr2), |
92b96797 FB |
983 | (WLAN_MGMT_REASON_CLASS2_NONAUTH), |
984 | &Status | |
985 | ); | |
986 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: send vMgrDeAuthenBeginSta 3\n"); | |
d6a32aa1 | 987 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BSSID:%pM\n", |
1cac4a4b | 988 | p802_11Header->addr3); |
d6a32aa1 | 989 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ADDR2:%pM\n", |
1cac4a4b | 990 | p802_11Header->addr2); |
d6a32aa1 | 991 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ADDR1:%pM\n", |
1cac4a4b AM |
992 | p802_11Header->addr1); |
993 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: frame_control= %x\n", p802_11Header->frame_control); | |
4e9b5e2b | 994 | return true; |
92b96797 FB |
995 | } |
996 | } | |
997 | } | |
e269fc2d | 998 | return false; |
92b96797 FB |
999 | |
1000 | } | |
1001 | ||
45c73bb1 MP |
1002 | static int s_bHandleRxEncryption(struct vnt_private *pDevice, u8 *pbyFrame, |
1003 | u32 FrameSize, u8 *pbyRsr, u8 *pbyNewRsr, PSKeyItem *pKeyOut, | |
1004 | s32 *pbExtIV, u16 *pwRxTSC15_0, u32 *pdwRxTSC47_16) | |
92b96797 | 1005 | { |
45c73bb1 MP |
1006 | struct vnt_manager *pMgmt = &pDevice->vnt_mgmt; |
1007 | u32 PayloadLen = FrameSize; | |
1008 | u8 *pbyIV; | |
1009 | u8 byKeyIdx; | |
1010 | PSKeyItem pKey = NULL; | |
1011 | u8 byDecMode = KEY_CTL_WEP; | |
92b96797 | 1012 | |
92b96797 FB |
1013 | *pwRxTSC15_0 = 0; |
1014 | *pdwRxTSC47_16 = 0; | |
1015 | ||
1016 | pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN; | |
3eaca0d2 AM |
1017 | if ( WLAN_GET_FC_TODS(*(u16 *)pbyFrame) && |
1018 | WLAN_GET_FC_FROMDS(*(u16 *)pbyFrame) ) { | |
92b96797 FB |
1019 | pbyIV += 6; // 6 is 802.11 address4 |
1020 | PayloadLen -= 6; | |
1021 | } | |
1022 | byKeyIdx = (*(pbyIV+3) & 0xc0); | |
1023 | byKeyIdx >>= 6; | |
1024 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\nKeyIdx: %d\n", byKeyIdx); | |
1025 | ||
1026 | if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA) || | |
1027 | (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) || | |
1028 | (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) || | |
1029 | (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || | |
1030 | (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) { | |
1031 | if (((*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI)) == 0) && | |
1032 | (pMgmt->byCSSPK != KEY_CTL_NONE)) { | |
1033 | // unicast pkt use pairwise key | |
1034 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"unicast pkt\n"); | |
4e9b5e2b | 1035 | if (KeybGetKey(&(pDevice->sKey), pDevice->abyBSSID, 0xFFFFFFFF, &pKey) == true) { |
92b96797 FB |
1036 | if (pMgmt->byCSSPK == KEY_CTL_TKIP) |
1037 | byDecMode = KEY_CTL_TKIP; | |
1038 | else if (pMgmt->byCSSPK == KEY_CTL_CCMP) | |
1039 | byDecMode = KEY_CTL_CCMP; | |
1040 | } | |
1041 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"unicast pkt: %d, %p\n", byDecMode, pKey); | |
1042 | } else { | |
1043 | // use group key | |
1044 | KeybGetKey(&(pDevice->sKey), pDevice->abyBSSID, byKeyIdx, &pKey); | |
1045 | if (pMgmt->byCSSGK == KEY_CTL_TKIP) | |
1046 | byDecMode = KEY_CTL_TKIP; | |
1047 | else if (pMgmt->byCSSGK == KEY_CTL_CCMP) | |
1048 | byDecMode = KEY_CTL_CCMP; | |
1049 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"group pkt: %d, %d, %p\n", byKeyIdx, byDecMode, pKey); | |
1050 | } | |
1051 | } | |
1052 | // our WEP only support Default Key | |
1053 | if (pKey == NULL) { | |
1054 | // use default group key | |
1055 | KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, byKeyIdx, &pKey); | |
1056 | if (pMgmt->byCSSGK == KEY_CTL_TKIP) | |
1057 | byDecMode = KEY_CTL_TKIP; | |
1058 | else if (pMgmt->byCSSGK == KEY_CTL_CCMP) | |
1059 | byDecMode = KEY_CTL_CCMP; | |
1060 | } | |
1061 | *pKeyOut = pKey; | |
1062 | ||
1063 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"AES:%d %d %d\n", pMgmt->byCSSPK, pMgmt->byCSSGK, byDecMode); | |
1064 | ||
1065 | if (pKey == NULL) { | |
1066 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey == NULL\n"); | |
1067 | if (byDecMode == KEY_CTL_WEP) { | |
1068 | // pDevice->s802_11Counter.WEPUndecryptableCount.QuadPart++; | |
4e9b5e2b | 1069 | } else if (pDevice->bLinkPass == true) { |
92b96797 FB |
1070 | // pDevice->s802_11Counter.DecryptFailureCount.QuadPart++; |
1071 | } | |
e269fc2d | 1072 | return false; |
92b96797 FB |
1073 | } |
1074 | if (byDecMode != pKey->byCipherSuite) { | |
1075 | if (byDecMode == KEY_CTL_WEP) { | |
1076 | // pDevice->s802_11Counter.WEPUndecryptableCount.QuadPart++; | |
4e9b5e2b | 1077 | } else if (pDevice->bLinkPass == true) { |
92b96797 FB |
1078 | // pDevice->s802_11Counter.DecryptFailureCount.QuadPart++; |
1079 | } | |
1080 | *pKeyOut = NULL; | |
e269fc2d | 1081 | return false; |
92b96797 FB |
1082 | } |
1083 | if (byDecMode == KEY_CTL_WEP) { | |
1084 | // handle WEP | |
1085 | if ((pDevice->byLocalID <= REV_ID_VT3253_A1) || | |
4e9b5e2b | 1086 | (((PSKeyTable)(pKey->pvKeyTable))->bSoftWEP == true)) { |
92b96797 FB |
1087 | // Software WEP |
1088 | // 1. 3253A | |
1089 | // 2. WEP 256 | |
1090 | ||
1091 | PayloadLen -= (WLAN_HDR_ADDR3_LEN + 4 + 4); // 24 is 802.11 header,4 is IV, 4 is crc | |
3e362598 JL |
1092 | memcpy(pDevice->abyPRNG, pbyIV, 3); |
1093 | memcpy(pDevice->abyPRNG + 3, pKey->abyKey, pKey->uKeyLength); | |
92b96797 FB |
1094 | rc4_init(&pDevice->SBox, pDevice->abyPRNG, pKey->uKeyLength + 3); |
1095 | rc4_encrypt(&pDevice->SBox, pbyIV+4, pbyIV+4, PayloadLen); | |
1096 | ||
1097 | if (ETHbIsBufferCrc32Ok(pbyIV+4, PayloadLen)) { | |
1098 | *pbyNewRsr |= NEWRSR_DECRYPTOK; | |
1099 | } | |
1100 | } | |
1101 | } else if ((byDecMode == KEY_CTL_TKIP) || | |
1102 | (byDecMode == KEY_CTL_CCMP)) { | |
1103 | // TKIP/AES | |
1104 | ||
1105 | PayloadLen -= (WLAN_HDR_ADDR3_LEN + 8 + 4); // 24 is 802.11 header, 8 is IV&ExtIV, 4 is crc | |
52a7e64b | 1106 | *pdwRxTSC47_16 = cpu_to_le32(*(u32 *)(pbyIV + 4)); |
b4dc03af | 1107 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ExtIV: %x\n", *pdwRxTSC47_16); |
92b96797 FB |
1108 | if (byDecMode == KEY_CTL_TKIP) { |
1109 | *pwRxTSC15_0 = cpu_to_le16(MAKEWORD(*(pbyIV+2), *pbyIV)); | |
1110 | } else { | |
3eaca0d2 | 1111 | *pwRxTSC15_0 = cpu_to_le16(*(u16 *)pbyIV); |
92b96797 FB |
1112 | } |
1113 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"TSC0_15: %x\n", *pwRxTSC15_0); | |
1114 | ||
1115 | if ((byDecMode == KEY_CTL_TKIP) && | |
1116 | (pDevice->byLocalID <= REV_ID_VT3253_A1)) { | |
1117 | // Software TKIP | |
1118 | // 1. 3253 A | |
1cac4a4b AM |
1119 | struct ieee80211_hdr *pMACHeader = (struct ieee80211_hdr *) (pbyFrame); |
1120 | TKIPvMixKey(pKey->abyKey, pMACHeader->addr2, *pwRxTSC15_0, *pdwRxTSC47_16, pDevice->abyPRNG); | |
92b96797 FB |
1121 | rc4_init(&pDevice->SBox, pDevice->abyPRNG, TKIP_KEY_LEN); |
1122 | rc4_encrypt(&pDevice->SBox, pbyIV+8, pbyIV+8, PayloadLen); | |
1123 | if (ETHbIsBufferCrc32Ok(pbyIV+8, PayloadLen)) { | |
1124 | *pbyNewRsr |= NEWRSR_DECRYPTOK; | |
1125 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV OK!\n"); | |
1126 | } else { | |
1127 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV FAIL!!!\n"); | |
1128 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"PayloadLen = %d\n", PayloadLen); | |
1129 | } | |
1130 | } | |
1131 | }// end of TKIP/AES | |
1132 | ||
1133 | if ((*(pbyIV+3) & 0x20) != 0) | |
4e9b5e2b AM |
1134 | *pbExtIV = true; |
1135 | return true; | |
92b96797 FB |
1136 | } |
1137 | ||
45c73bb1 MP |
1138 | static int s_bHostWepRxEncryption(struct vnt_private *pDevice, u8 *pbyFrame, |
1139 | u32 FrameSize, u8 *pbyRsr, int bOnFly, PSKeyItem pKey, u8 *pbyNewRsr, | |
1140 | s32 *pbExtIV, u16 *pwRxTSC15_0, u32 *pdwRxTSC47_16) | |
92b96797 | 1141 | { |
45c73bb1 | 1142 | struct vnt_manager *pMgmt = &pDevice->vnt_mgmt; |
1cac4a4b | 1143 | struct ieee80211_hdr *pMACHeader; |
45c73bb1 MP |
1144 | u32 PayloadLen = FrameSize; |
1145 | u8 *pbyIV; | |
1146 | u8 byKeyIdx; | |
1147 | u8 byDecMode = KEY_CTL_WEP; | |
92b96797 | 1148 | |
45c73bb1 MP |
1149 | *pwRxTSC15_0 = 0; |
1150 | *pdwRxTSC47_16 = 0; | |
92b96797 FB |
1151 | |
1152 | pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN; | |
3eaca0d2 AM |
1153 | if ( WLAN_GET_FC_TODS(*(u16 *)pbyFrame) && |
1154 | WLAN_GET_FC_FROMDS(*(u16 *)pbyFrame) ) { | |
92b96797 FB |
1155 | pbyIV += 6; // 6 is 802.11 address4 |
1156 | PayloadLen -= 6; | |
1157 | } | |
1158 | byKeyIdx = (*(pbyIV+3) & 0xc0); | |
1159 | byKeyIdx >>= 6; | |
1160 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\nKeyIdx: %d\n", byKeyIdx); | |
1161 | ||
92b96797 FB |
1162 | if (pMgmt->byCSSGK == KEY_CTL_TKIP) |
1163 | byDecMode = KEY_CTL_TKIP; | |
1164 | else if (pMgmt->byCSSGK == KEY_CTL_CCMP) | |
1165 | byDecMode = KEY_CTL_CCMP; | |
1166 | ||
1167 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"AES:%d %d %d\n", pMgmt->byCSSPK, pMgmt->byCSSGK, byDecMode); | |
1168 | ||
1169 | if (byDecMode != pKey->byCipherSuite) { | |
1170 | if (byDecMode == KEY_CTL_WEP) { | |
1171 | // pDevice->s802_11Counter.WEPUndecryptableCount.QuadPart++; | |
4e9b5e2b | 1172 | } else if (pDevice->bLinkPass == true) { |
92b96797 FB |
1173 | // pDevice->s802_11Counter.DecryptFailureCount.QuadPart++; |
1174 | } | |
e269fc2d | 1175 | return false; |
92b96797 FB |
1176 | } |
1177 | ||
1178 | if (byDecMode == KEY_CTL_WEP) { | |
1179 | // handle WEP | |
eb304bdd | 1180 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"byDecMode == KEY_CTL_WEP\n"); |
92b96797 | 1181 | if ((pDevice->byLocalID <= REV_ID_VT3253_A1) || |
4e9b5e2b | 1182 | (((PSKeyTable)(pKey->pvKeyTable))->bSoftWEP == true) || |
e269fc2d | 1183 | (bOnFly == false)) { |
92b96797 FB |
1184 | // Software WEP |
1185 | // 1. 3253A | |
1186 | // 2. WEP 256 | |
1187 | // 3. NotOnFly | |
1188 | ||
1189 | PayloadLen -= (WLAN_HDR_ADDR3_LEN + 4 + 4); // 24 is 802.11 header,4 is IV, 4 is crc | |
3e362598 JL |
1190 | memcpy(pDevice->abyPRNG, pbyIV, 3); |
1191 | memcpy(pDevice->abyPRNG + 3, pKey->abyKey, pKey->uKeyLength); | |
92b96797 FB |
1192 | rc4_init(&pDevice->SBox, pDevice->abyPRNG, pKey->uKeyLength + 3); |
1193 | rc4_encrypt(&pDevice->SBox, pbyIV+4, pbyIV+4, PayloadLen); | |
1194 | ||
1195 | if (ETHbIsBufferCrc32Ok(pbyIV+4, PayloadLen)) { | |
1196 | *pbyNewRsr |= NEWRSR_DECRYPTOK; | |
1197 | } | |
1198 | } | |
1199 | } else if ((byDecMode == KEY_CTL_TKIP) || | |
1200 | (byDecMode == KEY_CTL_CCMP)) { | |
1201 | // TKIP/AES | |
1202 | ||
1203 | PayloadLen -= (WLAN_HDR_ADDR3_LEN + 8 + 4); // 24 is 802.11 header, 8 is IV&ExtIV, 4 is crc | |
52a7e64b | 1204 | *pdwRxTSC47_16 = cpu_to_le32(*(u32 *)(pbyIV + 4)); |
b4dc03af | 1205 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ExtIV: %x\n", *pdwRxTSC47_16); |
92b96797 FB |
1206 | |
1207 | if (byDecMode == KEY_CTL_TKIP) { | |
1208 | *pwRxTSC15_0 = cpu_to_le16(MAKEWORD(*(pbyIV+2), *pbyIV)); | |
1209 | } else { | |
3eaca0d2 | 1210 | *pwRxTSC15_0 = cpu_to_le16(*(u16 *)pbyIV); |
92b96797 FB |
1211 | } |
1212 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"TSC0_15: %x\n", *pwRxTSC15_0); | |
1213 | ||
1214 | if (byDecMode == KEY_CTL_TKIP) { | |
1215 | ||
e269fc2d | 1216 | if ((pDevice->byLocalID <= REV_ID_VT3253_A1) || (bOnFly == false)) { |
92b96797 FB |
1217 | // Software TKIP |
1218 | // 1. 3253 A | |
1219 | // 2. NotOnFly | |
1220 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"soft KEY_CTL_TKIP \n"); | |
1cac4a4b AM |
1221 | pMACHeader = (struct ieee80211_hdr *) (pbyFrame); |
1222 | TKIPvMixKey(pKey->abyKey, pMACHeader->addr2, *pwRxTSC15_0, *pdwRxTSC47_16, pDevice->abyPRNG); | |
92b96797 FB |
1223 | rc4_init(&pDevice->SBox, pDevice->abyPRNG, TKIP_KEY_LEN); |
1224 | rc4_encrypt(&pDevice->SBox, pbyIV+8, pbyIV+8, PayloadLen); | |
1225 | if (ETHbIsBufferCrc32Ok(pbyIV+8, PayloadLen)) { | |
1226 | *pbyNewRsr |= NEWRSR_DECRYPTOK; | |
1227 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV OK!\n"); | |
1228 | } else { | |
1229 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV FAIL!!!\n"); | |
1230 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"PayloadLen = %d\n", PayloadLen); | |
1231 | } | |
1232 | } | |
1233 | } | |
1234 | ||
1235 | if (byDecMode == KEY_CTL_CCMP) { | |
e269fc2d | 1236 | if (bOnFly == false) { |
92b96797 FB |
1237 | // Software CCMP |
1238 | // NotOnFly | |
1239 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"soft KEY_CTL_CCMP\n"); | |
1240 | if (AESbGenCCMP(pKey->abyKey, pbyFrame, FrameSize)) { | |
1241 | *pbyNewRsr |= NEWRSR_DECRYPTOK; | |
1242 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"CCMP MIC compare OK!\n"); | |
1243 | } else { | |
1244 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"CCMP MIC fail!\n"); | |
1245 | } | |
1246 | } | |
1247 | } | |
1248 | ||
1249 | }// end of TKIP/AES | |
1250 | ||
1251 | if ((*(pbyIV+3) & 0x20) != 0) | |
4e9b5e2b AM |
1252 | *pbExtIV = true; |
1253 | return true; | |
92b96797 FB |
1254 | } |
1255 | ||
45c73bb1 MP |
1256 | static int s_bAPModeRxData(struct vnt_private *pDevice, struct sk_buff *skb, |
1257 | u32 FrameSize, u32 cbHeaderOffset, s32 iSANodeIndex, s32 iDANodeIndex) | |
92b96797 | 1258 | { |
45c73bb1 MP |
1259 | struct sk_buff *skbcpy; |
1260 | struct vnt_manager *pMgmt = &pDevice->vnt_mgmt; | |
e269fc2d AM |
1261 | int bRelayAndForward = false; |
1262 | int bRelayOnly = false; | |
45c73bb1 MP |
1263 | u8 byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80}; |
1264 | u16 wAID; | |
92b96797 | 1265 | |
92b96797 | 1266 | if (FrameSize > CB_MAX_BUF_SIZE) |
e269fc2d | 1267 | return false; |
92b96797 | 1268 | // check DA |
b902fbfe | 1269 | if (is_multicast_ether_addr((u8 *)(skb->data+cbHeaderOffset))) { |
92b96797 FB |
1270 | if (pMgmt->sNodeDBTable[0].bPSEnable) { |
1271 | ||
1272 | skbcpy = dev_alloc_skb((int)pDevice->rx_buf_sz); | |
1273 | ||
1274 | // if any node in PS mode, buffer packet until DTIM. | |
1275 | if (skbcpy == NULL) { | |
1276 | DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "relay multicast no skb available \n"); | |
1277 | } | |
1278 | else { | |
1279 | skbcpy->dev = pDevice->dev; | |
1280 | skbcpy->len = FrameSize; | |
1281 | memcpy(skbcpy->data, skb->data+cbHeaderOffset, FrameSize); | |
1282 | skb_queue_tail(&(pMgmt->sNodeDBTable[0].sTxPSQueue), skbcpy); | |
1283 | pMgmt->sNodeDBTable[0].wEnQueueCnt++; | |
1284 | // set tx map | |
1285 | pMgmt->abyPSTxMap[0] |= byMask[0]; | |
1286 | } | |
1287 | } | |
1288 | else { | |
4e9b5e2b | 1289 | bRelayAndForward = true; |
92b96797 FB |
1290 | } |
1291 | } | |
1292 | else { | |
1293 | // check if relay | |
b902fbfe | 1294 | if (BSSbIsSTAInNodeDB(pDevice, (u8 *)(skb->data+cbHeaderOffset), &iDANodeIndex)) { |
92b96797 FB |
1295 | if (pMgmt->sNodeDBTable[iDANodeIndex].eNodeState >= NODE_ASSOC) { |
1296 | if (pMgmt->sNodeDBTable[iDANodeIndex].bPSEnable) { | |
1297 | // queue this skb until next PS tx, and then release. | |
1298 | ||
1299 | skb->data += cbHeaderOffset; | |
1300 | skb->tail += cbHeaderOffset; | |
1301 | skb_put(skb, FrameSize); | |
1302 | skb_queue_tail(&pMgmt->sNodeDBTable[iDANodeIndex].sTxPSQueue, skb); | |
1303 | ||
1304 | pMgmt->sNodeDBTable[iDANodeIndex].wEnQueueCnt++; | |
1305 | wAID = pMgmt->sNodeDBTable[iDANodeIndex].wAID; | |
1306 | pMgmt->abyPSTxMap[wAID >> 3] |= byMask[wAID & 7]; | |
1307 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "relay: index= %d, pMgmt->abyPSTxMap[%d]= %d\n", | |
1308 | iDANodeIndex, (wAID >> 3), pMgmt->abyPSTxMap[wAID >> 3]); | |
4e9b5e2b | 1309 | return true; |
92b96797 FB |
1310 | } |
1311 | else { | |
4e9b5e2b | 1312 | bRelayOnly = true; |
92b96797 FB |
1313 | } |
1314 | } | |
9fc86028 | 1315 | } |
92b96797 FB |
1316 | } |
1317 | ||
1318 | if (bRelayOnly || bRelayAndForward) { | |
1319 | // relay this packet right now | |
1320 | if (bRelayAndForward) | |
1321 | iDANodeIndex = 0; | |
1322 | ||
1323 | if ((pDevice->uAssocCount > 1) && (iDANodeIndex >= 0)) { | |
b902fbfe | 1324 | bRelayPacketSend(pDevice, (u8 *) (skb->data + cbHeaderOffset), |
cc856e61 | 1325 | FrameSize, (unsigned int) iDANodeIndex); |
92b96797 FB |
1326 | } |
1327 | ||
1328 | if (bRelayOnly) | |
e269fc2d | 1329 | return false; |
92b96797 FB |
1330 | } |
1331 | // none associate, don't forward | |
1332 | if (pDevice->uAssocCount == 0) | |
e269fc2d | 1333 | return false; |
92b96797 | 1334 | |
4e9b5e2b | 1335 | return true; |
92b96797 FB |
1336 | } |
1337 | ||
81d720d3 | 1338 | void RXvWorkItem(struct work_struct *work) |
92b96797 | 1339 | { |
81d720d3 MP |
1340 | struct vnt_private *pDevice = |
1341 | container_of(work, struct vnt_private, read_work_item); | |
45c73bb1 | 1342 | int ntStatus; |
115cac2e | 1343 | struct vnt_rcb *pRCB = NULL; |
92b96797 | 1344 | |
17f3ced0 MP |
1345 | if (pDevice->Flags & fMP_DISCONNECTED) |
1346 | return; | |
1347 | ||
92b96797 FB |
1348 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Rx Polling Thread\n"); |
1349 | spin_lock_irq(&pDevice->lock); | |
731047f9 AM |
1350 | |
1351 | while ((pDevice->Flags & fMP_POST_READS) && | |
92b96797 FB |
1352 | MP_IS_READY(pDevice) && |
1353 | (pDevice->NumRecvFreeList != 0) ) { | |
1354 | pRCB = pDevice->FirstRecvFreeList; | |
1355 | pDevice->NumRecvFreeList--; | |
92b96797 FB |
1356 | DequeueRCB(pDevice->FirstRecvFreeList, pDevice->LastRecvFreeList); |
1357 | ntStatus = PIPEnsBulkInUsbRead(pDevice, pRCB); | |
1358 | } | |
e269fc2d | 1359 | pDevice->bIsRxWorkItemQueued = false; |
92b96797 FB |
1360 | spin_unlock_irq(&pDevice->lock); |
1361 | ||
1362 | } | |
1363 | ||
115cac2e | 1364 | void RXvFreeRCB(struct vnt_rcb *pRCB, int bReAllocSkb) |
92b96797 | 1365 | { |
45c73bb1 | 1366 | struct vnt_private *pDevice = pRCB->pDevice; |
92b96797 | 1367 | |
92b96797 FB |
1368 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->RXvFreeRCB\n"); |
1369 | ||
e269fc2d | 1370 | if (bReAllocSkb == false) { |
28044e01 | 1371 | kfree_skb(pRCB->skb); |
4e9b5e2b | 1372 | bReAllocSkb = true; |
28044e01 MP |
1373 | } |
1374 | ||
4e9b5e2b | 1375 | if (bReAllocSkb == true) { |
92b96797 FB |
1376 | pRCB->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); |
1377 | // todo error handling | |
1378 | if (pRCB->skb == NULL) { | |
1379 | DBG_PRT(MSG_LEVEL_ERR,KERN_ERR" Failed to re-alloc rx skb\n"); | |
1380 | }else { | |
1381 | pRCB->skb->dev = pDevice->dev; | |
1382 | } | |
1383 | } | |
1384 | // | |
1385 | // Insert the RCB back in the Recv free list | |
1386 | // | |
1387 | EnqueueRCB(pDevice->FirstRecvFreeList, pDevice->LastRecvFreeList, pRCB); | |
1388 | pDevice->NumRecvFreeList++; | |
1389 | ||
731047f9 | 1390 | if ((pDevice->Flags & fMP_POST_READS) && MP_IS_READY(pDevice) && |
e269fc2d | 1391 | (pDevice->bIsRxWorkItemQueued == false) ) { |
92b96797 | 1392 | |
4e9b5e2b | 1393 | pDevice->bIsRxWorkItemQueued = true; |
81d720d3 | 1394 | schedule_work(&pDevice->read_work_item); |
92b96797 FB |
1395 | } |
1396 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"<----RXFreeRCB %d %d\n",pDevice->NumRecvFreeList, pDevice->NumRecvMngList); | |
1397 | } | |
1398 | ||
a21fc2f5 | 1399 | void RXvMngWorkItem(struct work_struct *work) |
92b96797 | 1400 | { |
a21fc2f5 MP |
1401 | struct vnt_private *pDevice = |
1402 | container_of(work, struct vnt_private, rx_mng_work_item); | |
115cac2e | 1403 | struct vnt_rcb *pRCB = NULL; |
45c73bb1 | 1404 | struct vnt_rx_mgmt *pRxPacket; |
e269fc2d | 1405 | int bReAllocSkb = false; |
92b96797 | 1406 | |
17f3ced0 MP |
1407 | if (pDevice->Flags & fMP_DISCONNECTED) |
1408 | return; | |
1409 | ||
92b96797 FB |
1410 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Rx Mng Thread\n"); |
1411 | ||
1412 | spin_lock_irq(&pDevice->lock); | |
1413 | while (pDevice->NumRecvMngList!=0) | |
1414 | { | |
1415 | pRCB = pDevice->FirstRecvMngList; | |
1416 | pDevice->NumRecvMngList--; | |
1417 | DequeueRCB(pDevice->FirstRecvMngList, pDevice->LastRecvMngList); | |
1418 | if(!pRCB){ | |
1419 | break; | |
1420 | } | |
92b96797 | 1421 | pRxPacket = &(pRCB->sMngPacket); |
14c5ef57 | 1422 | vMgrRxManagePacket(pDevice, &pDevice->vnt_mgmt, pRxPacket); |
92b96797 FB |
1423 | pRCB->Ref--; |
1424 | if(pRCB->Ref == 0) { | |
1425 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"RxvFreeMng %d %d\n",pDevice->NumRecvFreeList, pDevice->NumRecvMngList); | |
1426 | RXvFreeRCB(pRCB, bReAllocSkb); | |
1427 | } else { | |
1428 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Rx Mng Only we have the right to free RCB\n"); | |
1429 | } | |
1430 | } | |
1431 | ||
e269fc2d | 1432 | pDevice->bIsRxMngWorkItemQueued = false; |
ba5c2b3d | 1433 | spin_unlock_irq(&pDevice->lock); |
92b96797 FB |
1434 | |
1435 | } | |
1436 |