dpc.c revision 22c5291e70ba66880c6a6acffbd8200a623c4556
15449c685a4b39534f18869a93896370224463715Forest Bond/*
25449c685a4b39534f18869a93896370224463715Forest Bond * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
35449c685a4b39534f18869a93896370224463715Forest Bond * All rights reserved.
45449c685a4b39534f18869a93896370224463715Forest Bond *
55449c685a4b39534f18869a93896370224463715Forest Bond * This program is free software; you can redistribute it and/or modify
65449c685a4b39534f18869a93896370224463715Forest Bond * it under the terms of the GNU General Public License as published by
75449c685a4b39534f18869a93896370224463715Forest Bond * the Free Software Foundation; either version 2 of the License, or
85449c685a4b39534f18869a93896370224463715Forest Bond * (at your option) any later version.
95449c685a4b39534f18869a93896370224463715Forest Bond *
105449c685a4b39534f18869a93896370224463715Forest Bond * This program is distributed in the hope that it will be useful,
115449c685a4b39534f18869a93896370224463715Forest Bond * but WITHOUT ANY WARRANTY; without even the implied warranty of
125449c685a4b39534f18869a93896370224463715Forest Bond * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
135449c685a4b39534f18869a93896370224463715Forest Bond * GNU General Public License for more details.
145449c685a4b39534f18869a93896370224463715Forest Bond *
155449c685a4b39534f18869a93896370224463715Forest Bond * You should have received a copy of the GNU General Public License along
165449c685a4b39534f18869a93896370224463715Forest Bond * with this program; if not, write to the Free Software Foundation, Inc.,
175449c685a4b39534f18869a93896370224463715Forest Bond * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
185449c685a4b39534f18869a93896370224463715Forest Bond *
195449c685a4b39534f18869a93896370224463715Forest Bond * File: dpc.c
205449c685a4b39534f18869a93896370224463715Forest Bond *
215449c685a4b39534f18869a93896370224463715Forest Bond * Purpose: handle dpc rx functions
225449c685a4b39534f18869a93896370224463715Forest Bond *
235449c685a4b39534f18869a93896370224463715Forest Bond * Author: Lyndon Chen
245449c685a4b39534f18869a93896370224463715Forest Bond *
255449c685a4b39534f18869a93896370224463715Forest Bond * Date: May 20, 2003
265449c685a4b39534f18869a93896370224463715Forest Bond *
275449c685a4b39534f18869a93896370224463715Forest Bond * Functions:
285449c685a4b39534f18869a93896370224463715Forest Bond *      device_receive_frame - Rcv 802.11 frame function
295449c685a4b39534f18869a93896370224463715Forest Bond *      s_bAPModeRxCtl- AP Rcv frame filer Ctl.
305449c685a4b39534f18869a93896370224463715Forest Bond *      s_bAPModeRxData- AP Rcv data frame handle
315449c685a4b39534f18869a93896370224463715Forest Bond *      s_bHandleRxEncryption- Rcv decrypted data via on-fly
325449c685a4b39534f18869a93896370224463715Forest Bond *      s_bHostWepRxEncryption- Rcv encrypted data via host
335449c685a4b39534f18869a93896370224463715Forest Bond *      s_byGetRateIdx- get rate index
345449c685a4b39534f18869a93896370224463715Forest Bond *      s_vGetDASA- get data offset
355449c685a4b39534f18869a93896370224463715Forest Bond *      s_vProcessRxMACHeader- Rcv 802.11 and translate to 802.3
365449c685a4b39534f18869a93896370224463715Forest Bond *
375449c685a4b39534f18869a93896370224463715Forest Bond * Revision History:
385449c685a4b39534f18869a93896370224463715Forest Bond *
395449c685a4b39534f18869a93896370224463715Forest Bond */
405449c685a4b39534f18869a93896370224463715Forest Bond
415449c685a4b39534f18869a93896370224463715Forest Bond#include "device.h"
425449c685a4b39534f18869a93896370224463715Forest Bond#include "rxtx.h"
435449c685a4b39534f18869a93896370224463715Forest Bond#include "tether.h"
445449c685a4b39534f18869a93896370224463715Forest Bond#include "card.h"
455449c685a4b39534f18869a93896370224463715Forest Bond#include "bssdb.h"
465449c685a4b39534f18869a93896370224463715Forest Bond#include "mac.h"
475449c685a4b39534f18869a93896370224463715Forest Bond#include "baseband.h"
485449c685a4b39534f18869a93896370224463715Forest Bond#include "michael.h"
495449c685a4b39534f18869a93896370224463715Forest Bond#include "tkip.h"
505449c685a4b39534f18869a93896370224463715Forest Bond#include "tcrc.h"
515449c685a4b39534f18869a93896370224463715Forest Bond#include "wctl.h"
525449c685a4b39534f18869a93896370224463715Forest Bond#include "wroute.h"
535449c685a4b39534f18869a93896370224463715Forest Bond#include "hostap.h"
545449c685a4b39534f18869a93896370224463715Forest Bond#include "rf.h"
555449c685a4b39534f18869a93896370224463715Forest Bond#include "iowpa.h"
565449c685a4b39534f18869a93896370224463715Forest Bond#include "aes_ccmp.h"
575449c685a4b39534f18869a93896370224463715Forest Bond
585449c685a4b39534f18869a93896370224463715Forest Bond
595449c685a4b39534f18869a93896370224463715Forest Bond
605449c685a4b39534f18869a93896370224463715Forest Bond/*---------------------  Static Definitions -------------------------*/
615449c685a4b39534f18869a93896370224463715Forest Bond
625449c685a4b39534f18869a93896370224463715Forest Bond/*---------------------  Static Classes  ----------------------------*/
635449c685a4b39534f18869a93896370224463715Forest Bond
645449c685a4b39534f18869a93896370224463715Forest Bond/*---------------------  Static Variables  --------------------------*/
655449c685a4b39534f18869a93896370224463715Forest Bond//static int          msglevel                =MSG_LEVEL_DEBUG;
6622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perchesstatic int msglevel = MSG_LEVEL_INFO;
675449c685a4b39534f18869a93896370224463715Forest Bond
683fc9b584c28095fe0d46cfb8bddafdf93947042eCharles Clémentconst unsigned char acbyRxRate[MAX_RATE] =
695449c685a4b39534f18869a93896370224463715Forest Bond{2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108};
705449c685a4b39534f18869a93896370224463715Forest Bond
715449c685a4b39534f18869a93896370224463715Forest Bond
725449c685a4b39534f18869a93896370224463715Forest Bond/*---------------------  Static Functions  --------------------------*/
735449c685a4b39534f18869a93896370224463715Forest Bond
745449c685a4b39534f18869a93896370224463715Forest Bond/*---------------------  Static Definitions -------------------------*/
755449c685a4b39534f18869a93896370224463715Forest Bond
765449c685a4b39534f18869a93896370224463715Forest Bond/*---------------------  Static Functions  --------------------------*/
775449c685a4b39534f18869a93896370224463715Forest Bond
783fc9b584c28095fe0d46cfb8bddafdf93947042eCharles Clémentstatic unsigned char s_byGetRateIdx(unsigned char byRate);
795449c685a4b39534f18869a93896370224463715Forest Bond
805449c685a4b39534f18869a93896370224463715Forest Bond
81fe4f34bde28f5a9f3793cced5b4029eda5b78be2Charles Clémentstatic void
82fe4f34bde28f5a9f3793cced5b4029eda5b78be2Charles Cléments_vGetDASA(unsigned char *pbyRxBufferAddr, unsigned int *pcbHeaderSize,
8322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	   PSEthernetHeader psEthHeader);
845449c685a4b39534f18869a93896370224463715Forest Bond
85fe4f34bde28f5a9f3793cced5b4029eda5b78be2Charles Clémentstatic void
86fe4f34bde28f5a9f3793cced5b4029eda5b78be2Charles Cléments_vProcessRxMACHeader(PSDevice pDevice, unsigned char *pbyRxBufferAddr,
8722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		      unsigned int cbPacketSize, bool bIsWEP, bool bExtIV,
8822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		      unsigned int *pcbHeadSize);
895449c685a4b39534f18869a93896370224463715Forest Bond
907b6a001313a9b11a1f0985de05fff514db41d72dCharles Clémentstatic bool s_bAPModeRxCtl(
9122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PSDevice pDevice,
9222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyFrame,
9322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	int      iSANodeIndex
9422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches);
955449c685a4b39534f18869a93896370224463715Forest Bond
965449c685a4b39534f18869a93896370224463715Forest Bond
97612822f5dd1638de442cf50eb9da54632fba0e66Jim Lieb
9822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perchesstatic bool s_bAPModeRxData(
9922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PSDevice pDevice,
10022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	struct sk_buff *skb,
10122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned int FrameSize,
10222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned int cbHeaderOffset,
10322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	int      iSANodeIndex,
10422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	int      iDANodeIndex
10522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches);
1065449c685a4b39534f18869a93896370224463715Forest Bond
1075449c685a4b39534f18869a93896370224463715Forest Bond
1087b6a001313a9b11a1f0985de05fff514db41d72dCharles Clémentstatic bool s_bHandleRxEncryption(
10922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PSDevice     pDevice,
11022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyFrame,
11122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned int FrameSize,
11222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyRsr,
11322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyNewRsr,
11422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PSKeyItem   *pKeyOut,
11522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	bool *pbExtIV,
11622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned short *pwRxTSC15_0,
11722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned long *pdwRxTSC47_16
11822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches);
1195449c685a4b39534f18869a93896370224463715Forest Bond
1207b6a001313a9b11a1f0985de05fff514db41d72dCharles Clémentstatic bool s_bHostWepRxEncryption(
1215449c685a4b39534f18869a93896370224463715Forest Bond
12222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PSDevice     pDevice,
12322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyFrame,
12422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned int FrameSize,
12522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyRsr,
12622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	bool bOnFly,
12722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PSKeyItem    pKey,
12822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyNewRsr,
12922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	bool *pbExtIV,
13022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned short *pwRxTSC15_0,
13122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned long *pdwRxTSC47_16
1325449c685a4b39534f18869a93896370224463715Forest Bond
13322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches);
1345449c685a4b39534f18869a93896370224463715Forest Bond
1355449c685a4b39534f18869a93896370224463715Forest Bond/*---------------------  Export Variables  --------------------------*/
1365449c685a4b39534f18869a93896370224463715Forest Bond
1375449c685a4b39534f18869a93896370224463715Forest Bond/*+
1385449c685a4b39534f18869a93896370224463715Forest Bond *
1395449c685a4b39534f18869a93896370224463715Forest Bond * Description:
1405449c685a4b39534f18869a93896370224463715Forest Bond *    Translate Rcv 802.11 header to 802.3 header with Rx buffer
1415449c685a4b39534f18869a93896370224463715Forest Bond *
1425449c685a4b39534f18869a93896370224463715Forest Bond * Parameters:
1435449c685a4b39534f18869a93896370224463715Forest Bond *  In:
1445449c685a4b39534f18869a93896370224463715Forest Bond *      pDevice
1455449c685a4b39534f18869a93896370224463715Forest Bond *      dwRxBufferAddr  - Address of Rcv Buffer
1465449c685a4b39534f18869a93896370224463715Forest Bond *      cbPacketSize    - Rcv Packet size
1475449c685a4b39534f18869a93896370224463715Forest Bond *      bIsWEP          - If Rcv with WEP
1485449c685a4b39534f18869a93896370224463715Forest Bond *  Out:
1495449c685a4b39534f18869a93896370224463715Forest Bond *      pcbHeaderSize   - 802.11 header size
1505449c685a4b39534f18869a93896370224463715Forest Bond *
1515449c685a4b39534f18869a93896370224463715Forest Bond * Return Value: None
1525449c685a4b39534f18869a93896370224463715Forest Bond *
15322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches -*/
154fe4f34bde28f5a9f3793cced5b4029eda5b78be2Charles Clémentstatic void
155fe4f34bde28f5a9f3793cced5b4029eda5b78be2Charles Cléments_vProcessRxMACHeader(PSDevice pDevice, unsigned char *pbyRxBufferAddr,
15622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		      unsigned int cbPacketSize, bool bIsWEP, bool bExtIV,
15722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		      unsigned int *pcbHeadSize)
1585449c685a4b39534f18869a93896370224463715Forest Bond{
15922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyRxBuffer;
16022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned int cbHeaderSize = 0;
16122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned short *pwType;
16222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PS802_11Header  pMACHeader;
16322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	int             ii;
16422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
16522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
16622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	pMACHeader = (PS802_11Header) (pbyRxBufferAddr + cbHeaderSize);
16722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
16822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	s_vGetDASA((unsigned char *)pMACHeader, &cbHeaderSize, &pDevice->sRxEthHeader);
16922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
17022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (bIsWEP) {
17122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (bExtIV) {
17222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// strip IV&ExtIV , add 8 byte
17322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			cbHeaderSize += (WLAN_HDR_ADDR3_LEN + 8);
17422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		} else {
17522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// strip IV , add 4 byte
17622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			cbHeaderSize += (WLAN_HDR_ADDR3_LEN + 4);
17722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
17822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
17922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	else {
18022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		cbHeaderSize += WLAN_HDR_ADDR3_LEN;
18122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	};
18222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
18322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	pbyRxBuffer = (unsigned char *)(pbyRxBufferAddr + cbHeaderSize);
18422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (!compare_ether_addr(pbyRxBuffer, &pDevice->abySNAP_Bridgetunnel[0])) {
18522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		cbHeaderSize += 6;
18622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
18722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	else if (!compare_ether_addr(pbyRxBuffer, &pDevice->abySNAP_RFC1042[0])) {
18822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		cbHeaderSize += 6;
18922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		pwType = (unsigned short *)(pbyRxBufferAddr + cbHeaderSize);
19022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if ((*pwType != TYPE_PKT_IPX) && (*pwType != cpu_to_le16(0xF380))) {
19122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
19222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		else {
19322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			cbHeaderSize -= 8;
19422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			pwType = (unsigned short *)(pbyRxBufferAddr + cbHeaderSize);
19522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			if (bIsWEP) {
19622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				if (bExtIV) {
19722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					*pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 8);    // 8 is IV&ExtIV
19822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				} else {
19922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					*pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 4);    // 4 is IV
20022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				}
20122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
20222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			else {
20322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				*pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN);
20422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
20522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
20622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
20722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	else {
20822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		cbHeaderSize -= 2;
20922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		pwType = (unsigned short *)(pbyRxBufferAddr + cbHeaderSize);
21022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (bIsWEP) {
21122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			if (bExtIV) {
21222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				*pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 8);    // 8 is IV&ExtIV
21322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			} else {
21422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				*pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 4);    // 4 is IV
21522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
21622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
21722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		else {
21822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			*pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN);
21922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
22022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
22122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
22222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	cbHeaderSize -= (ETH_ALEN * 2);
22322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	pbyRxBuffer = (unsigned char *)(pbyRxBufferAddr + cbHeaderSize);
22422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	for (ii = 0; ii < ETH_ALEN; ii++)
22522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		*pbyRxBuffer++ = pDevice->sRxEthHeader.abyDstAddr[ii];
22622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	for (ii = 0; ii < ETH_ALEN; ii++)
22722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		*pbyRxBuffer++ = pDevice->sRxEthHeader.abySrcAddr[ii];
22822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
22922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	*pcbHeadSize = cbHeaderSize;
2305449c685a4b39534f18869a93896370224463715Forest Bond}
2315449c685a4b39534f18869a93896370224463715Forest Bond
2325449c685a4b39534f18869a93896370224463715Forest Bond
2335449c685a4b39534f18869a93896370224463715Forest Bond
2345449c685a4b39534f18869a93896370224463715Forest Bond
23522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perchesstatic unsigned char s_byGetRateIdx(unsigned char byRate)
2365449c685a4b39534f18869a93896370224463715Forest Bond{
23722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char byRateIdx;
2385449c685a4b39534f18869a93896370224463715Forest Bond
23922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	for (byRateIdx = 0; byRateIdx < MAX_RATE; byRateIdx++) {
24022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (acbyRxRate[byRateIdx % MAX_RATE] == byRate)
24122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			return byRateIdx;
24222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
24322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	return 0;
2445449c685a4b39534f18869a93896370224463715Forest Bond}
2455449c685a4b39534f18869a93896370224463715Forest Bond
2465449c685a4b39534f18869a93896370224463715Forest Bond
247fe4f34bde28f5a9f3793cced5b4029eda5b78be2Charles Clémentstatic void
248fe4f34bde28f5a9f3793cced5b4029eda5b78be2Charles Cléments_vGetDASA(unsigned char *pbyRxBufferAddr, unsigned int *pcbHeaderSize,
24922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	   PSEthernetHeader psEthHeader)
2505449c685a4b39534f18869a93896370224463715Forest Bond{
25122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned int cbHeaderSize = 0;
25222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PS802_11Header  pMACHeader;
25322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	int             ii;
25422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
25522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	pMACHeader = (PS802_11Header) (pbyRxBufferAddr + cbHeaderSize);
25622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
25722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if ((pMACHeader->wFrameCtl & FC_TODS) == 0) {
25822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (pMACHeader->wFrameCtl & FC_FROMDS) {
25922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			for (ii = 0; ii < ETH_ALEN; ii++) {
26022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				psEthHeader->abyDstAddr[ii] = pMACHeader->abyAddr1[ii];
26122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				psEthHeader->abySrcAddr[ii] = pMACHeader->abyAddr3[ii];
26222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
26322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
26422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		else {
26522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// IBSS mode
26622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			for (ii = 0; ii < ETH_ALEN; ii++) {
26722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				psEthHeader->abyDstAddr[ii] = pMACHeader->abyAddr1[ii];
26822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				psEthHeader->abySrcAddr[ii] = pMACHeader->abyAddr2[ii];
26922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
27022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
27122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
27222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	else {
27322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		// Is AP mode..
27422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (pMACHeader->wFrameCtl & FC_FROMDS) {
27522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			for (ii = 0; ii < ETH_ALEN; ii++) {
27622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				psEthHeader->abyDstAddr[ii] = pMACHeader->abyAddr3[ii];
27722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				psEthHeader->abySrcAddr[ii] = pMACHeader->abyAddr4[ii];
27822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				cbHeaderSize += 6;
27922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
28022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
28122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		else {
28222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			for (ii = 0; ii < ETH_ALEN; ii++) {
28322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				psEthHeader->abyDstAddr[ii] = pMACHeader->abyAddr3[ii];
28422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				psEthHeader->abySrcAddr[ii] = pMACHeader->abyAddr2[ii];
28522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
28622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
28722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	};
28822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	*pcbHeaderSize = cbHeaderSize;
2895449c685a4b39534f18869a93896370224463715Forest Bond}
2905449c685a4b39534f18869a93896370224463715Forest Bond
2915449c685a4b39534f18869a93896370224463715Forest Bond
2925449c685a4b39534f18869a93896370224463715Forest Bond
2935449c685a4b39534f18869a93896370224463715Forest Bond
2945449c685a4b39534f18869a93896370224463715Forest Bond//PLICE_DEBUG ->
2955449c685a4b39534f18869a93896370224463715Forest Bond
296830a619c02a53d52c86534f7d857b2e8d0ba893fCharles Clémentvoid	MngWorkItem(void *Context)
2975449c685a4b39534f18869a93896370224463715Forest Bond{
2985449c685a4b39534f18869a93896370224463715Forest Bond	PSRxMgmtPacket			pRxMgmtPacket;
2995449c685a4b39534f18869a93896370224463715Forest Bond	PSDevice	pDevice =  (PSDevice) Context;
3005449c685a4b39534f18869a93896370224463715Forest Bond	//printk("Enter MngWorkItem,Queue packet num is %d\n",pDevice->rxManeQueue.packet_num);
3015449c685a4b39534f18869a93896370224463715Forest Bond	spin_lock_irq(&pDevice->lock);
30222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	while (pDevice->rxManeQueue.packet_num != 0)
30322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	{
30422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		pRxMgmtPacket =  DeQueue(pDevice);
30522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		vMgrRxManagePacket(pDevice, pDevice->pMgmt, pRxMgmtPacket);
3065449c685a4b39534f18869a93896370224463715Forest Bond	}
3075449c685a4b39534f18869a93896370224463715Forest Bond	spin_unlock_irq(&pDevice->lock);
3085449c685a4b39534f18869a93896370224463715Forest Bond}
3095449c685a4b39534f18869a93896370224463715Forest Bond
3105449c685a4b39534f18869a93896370224463715Forest Bond
3115449c685a4b39534f18869a93896370224463715Forest Bond//PLICE_DEBUG<-
3125449c685a4b39534f18869a93896370224463715Forest Bond
3135449c685a4b39534f18869a93896370224463715Forest Bond
3145449c685a4b39534f18869a93896370224463715Forest Bond
3157b6a001313a9b11a1f0985de05fff514db41d72dCharles Clémentbool
31622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perchesdevice_receive_frame(
31722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PSDevice pDevice,
31822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PSRxDesc pCurrRD
31922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches)
3205449c685a4b39534f18869a93896370224463715Forest Bond{
3215449c685a4b39534f18869a93896370224463715Forest Bond
32222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PDEVICE_RD_INFO  pRDInfo = pCurrRD->pRDInfo;
3235449c685a4b39534f18869a93896370224463715Forest Bond#ifdef	PLICE_DEBUG
3245449c685a4b39534f18869a93896370224463715Forest Bond	//printk("device_receive_frame:pCurrRD is %x,pRDInfo is %x\n",pCurrRD,pCurrRD->pRDInfo);
3255449c685a4b39534f18869a93896370224463715Forest Bond#endif
32622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	struct net_device_stats *pStats = &pDevice->stats;
32722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	struct sk_buff *skb;
32822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PSMgmtObject    pMgmt = pDevice->pMgmt;
32922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PSRxMgmtPacket  pRxPacket = &(pDevice->pMgmt->sRxPacket);
33022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PS802_11Header  p802_11Header;
33122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyRsr;
33222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyNewRsr;
33322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyRSSI;
33422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PQWORD          pqwTSFTime;
33522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned short *pwFrameSize;
33622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyFrame;
33722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	bool bDeFragRx = false;
33822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	bool bIsWEP = false;
33922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned int cbHeaderOffset;
34022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned int FrameSize;
34122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned short wEtherType = 0;
34222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	int             iSANodeIndex = -1;
34322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	int             iDANodeIndex = -1;
34422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned int ii;
34522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned int cbIVOffset;
34622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	bool bExtIV = false;
34722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyRxSts;
34822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyRxRate;
34922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbySQ;
35022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned int cbHeaderSize;
35122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PSKeyItem       pKey = NULL;
35222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned short wRxTSC15_0 = 0;
35322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned long dwRxTSC47_16 = 0;
35422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	SKeyItem        STempKey;
35522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	// 802.11h RPI
35622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned long dwDuration = 0;
35722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	long            ldBm = 0;
35822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	long            ldBmThreshold = 0;
35922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PS802_11Header pMACHeader;
36022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	bool bRxeapol_key = false;
36122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
36222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches//    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "---------- device_receive_frame---\n");
36322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
36422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	skb = pRDInfo->skb;
3655449c685a4b39534f18869a93896370224463715Forest Bond
3665449c685a4b39534f18869a93896370224463715Forest Bond
3675449c685a4b39534f18869a93896370224463715Forest Bond//PLICE_DEBUG->
3685449c685a4b39534f18869a93896370224463715Forest Bond#if 1
3695449c685a4b39534f18869a93896370224463715Forest Bond	pci_unmap_single(pDevice->pcid, pRDInfo->skb_dma,
37022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			 pDevice->rx_buf_sz, PCI_DMA_FROMDEVICE);
3715449c685a4b39534f18869a93896370224463715Forest Bond#endif
3725449c685a4b39534f18869a93896370224463715Forest Bond//PLICE_DEBUG<-
37322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	pwFrameSize = (unsigned short *)(skb->data + 2);
37422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	FrameSize = cpu_to_le16(pCurrRD->m_rd1RD1.wReqCount) - cpu_to_le16(pCurrRD->m_rd0RD0.wResCount);
37522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
37622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	// Max: 2312Payload + 30HD +4CRC + 2Padding + 4Len + 8TSF + 4RSR
37722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	// Min (ACK): 10HD +4CRC + 2Padding + 4Len + 8TSF + 4RSR
37822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if ((FrameSize > 2364) || (FrameSize <= 32)) {
37922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		// Frame Size error drop this packet.
38022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "---------- WRONG Length 1 \n");
38122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		return false;
38222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
38322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
38422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	pbyRxSts = (unsigned char *)(skb->data);
38522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	pbyRxRate = (unsigned char *)(skb->data + 1);
38622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	pbyRsr = (unsigned char *)(skb->data + FrameSize - 1);
38722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	pbyRSSI = (unsigned char *)(skb->data + FrameSize - 2);
38822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	pbyNewRsr = (unsigned char *)(skb->data + FrameSize - 3);
38922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	pbySQ = (unsigned char *)(skb->data + FrameSize - 4);
39022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	pqwTSFTime = (PQWORD)(skb->data + FrameSize - 12);
39122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	pbyFrame = (unsigned char *)(skb->data + 4);
39222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
39322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	// get packet size
39422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	FrameSize = cpu_to_le16(*pwFrameSize);
39522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
39622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if ((FrameSize > 2346)|(FrameSize < 14)) { // Max: 2312Payload + 30HD +4CRC
39722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		// Min: 14 bytes ACK
39822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "---------- WRONG Length 2 \n");
39922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		return false;
40022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
4015449c685a4b39534f18869a93896370224463715Forest Bond//PLICE_DEBUG->
4025449c685a4b39534f18869a93896370224463715Forest Bond#if 1
4035449c685a4b39534f18869a93896370224463715Forest Bond	// update receive statistic counter
40422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	STAvUpdateRDStatCounter(&pDevice->scStatistic,
40522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				*pbyRsr,
40622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				*pbyNewRsr,
40722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				*pbyRxRate,
40822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				pbyFrame,
40922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				FrameSize);
4105449c685a4b39534f18869a93896370224463715Forest Bond
4115449c685a4b39534f18869a93896370224463715Forest Bond#endif
4125449c685a4b39534f18869a93896370224463715Forest Bond
41322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	pMACHeader = (PS802_11Header)((unsigned char *)(skb->data) + 8);
4145449c685a4b39534f18869a93896370224463715Forest Bond//PLICE_DEBUG<-
4151b12068a804711ae2f4fd2876d5706542c1d7ad9Charles Clément	if (pDevice->bMeasureInProgress == true) {
41622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if ((*pbyRsr & RSR_CRCOK) != 0) {
41722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			pDevice->byBasicMap |= 0x01;
41822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
41922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		dwDuration = (FrameSize << 4);
42022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		dwDuration /= acbyRxRate[*pbyRxRate%MAX_RATE];
42122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (*pbyRxRate <= RATE_11M) {
42222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			if (*pbyRxSts & 0x01) {
42322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				// long preamble
42422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				dwDuration += 192;
42522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			} else {
42622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				// short preamble
42722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				dwDuration += 96;
42822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
42922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		} else {
43022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			dwDuration += 16;
43122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
43222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		RFvRSSITodBm(pDevice, *pbyRSSI, &ldBm);
43322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		ldBmThreshold = -57;
43422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		for (ii = 7; ii > 0;) {
43522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			if (ldBm > ldBmThreshold) {
43622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				break;
43722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
43822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			ldBmThreshold -= 5;
43922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			ii--;
44022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
44122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		pDevice->dwRPIs[ii] += dwDuration;
44222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		return false;
44322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
44422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
44522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (!is_multicast_ether_addr(pbyFrame)) {
44622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (WCTLbIsDuplicate(&(pDevice->sDupRxCache), (PS802_11Header)(skb->data + 4))) {
44722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			pDevice->s802_11Counter.FrameDuplicateCount++;
44822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			return false;
44922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
45022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
45122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
45222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
45322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	// Use for TKIP MIC
45422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	s_vGetDASA(skb->data+4, &cbHeaderSize, &pDevice->sRxEthHeader);
45522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
45622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	// filter packet send from myself
45722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (!compare_ether_addr((unsigned char *)&(pDevice->sRxEthHeader.abySrcAddr[0]), pDevice->abyCurrentNetAddr))
45822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		return false;
45922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
46022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) || (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) {
46122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (IS_CTL_PSPOLL(pbyFrame) || !IS_TYPE_CONTROL(pbyFrame)) {
46222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			p802_11Header = (PS802_11Header)(pbyFrame);
46322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// get SA NodeIndex
46422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			if (BSSDBbIsSTAInNodeDB(pMgmt, (unsigned char *)(p802_11Header->abyAddr2), &iSANodeIndex)) {
46522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				pMgmt->sNodeDBTable[iSANodeIndex].ulLastRxJiffer = jiffies;
46622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				pMgmt->sNodeDBTable[iSANodeIndex].uInActiveCount = 0;
46722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
46822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
46922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
47022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
47122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
47222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (s_bAPModeRxCtl(pDevice, pbyFrame, iSANodeIndex) == true) {
47322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			return false;
47422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
47522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
47622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
47722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
47822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (IS_FC_WEP(pbyFrame)) {
47922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		bool bRxDecryOK = false;
48022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
48122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx WEP pkt\n");
48222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		bIsWEP = true;
48322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if ((pDevice->bEnableHostWEP) && (iSANodeIndex >= 0)) {
48422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			pKey = &STempKey;
48522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			pKey->byCipherSuite = pMgmt->sNodeDBTable[iSANodeIndex].byCipherSuite;
48622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			pKey->dwKeyIndex = pMgmt->sNodeDBTable[iSANodeIndex].dwKeyIndex;
48722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			pKey->uKeyLength = pMgmt->sNodeDBTable[iSANodeIndex].uWepKeyLength;
48822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			pKey->dwTSC47_16 = pMgmt->sNodeDBTable[iSANodeIndex].dwTSC47_16;
48922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			pKey->wTSC15_0 = pMgmt->sNodeDBTable[iSANodeIndex].wTSC15_0;
49022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			memcpy(pKey->abyKey,
49122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			       &pMgmt->sNodeDBTable[iSANodeIndex].abyWepKey[0],
49222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			       pKey->uKeyLength
49322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches);
49422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
49522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			bRxDecryOK = s_bHostWepRxEncryption(pDevice,
49622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							    pbyFrame,
49722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							    FrameSize,
49822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							    pbyRsr,
49922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							    pMgmt->sNodeDBTable[iSANodeIndex].bOnFly,
50022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							    pKey,
50122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							    pbyNewRsr,
50222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							    &bExtIV,
50322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							    &wRxTSC15_0,
50422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							    &dwRxTSC47_16);
50522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		} else {
50622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			bRxDecryOK = s_bHandleRxEncryption(pDevice,
50722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							   pbyFrame,
50822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							   FrameSize,
50922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							   pbyRsr,
51022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							   pbyNewRsr,
51122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							   &pKey,
51222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							   &bExtIV,
51322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							   &wRxTSC15_0,
51422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							   &dwRxTSC47_16);
51522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
51622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
51722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (bRxDecryOK) {
51822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			if ((*pbyNewRsr & NEWRSR_DECRYPTOK) == 0) {
51922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ICV Fail\n");
52022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				if ((pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPA) ||
52122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				    (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) ||
52222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				    (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) ||
52322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				    (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPA2) ||
52422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				    (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) {
52522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
52622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_TKIP)) {
52722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						pDevice->s802_11Counter.TKIPICVErrors++;
52822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					} else if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_CCMP)) {
52922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						pDevice->s802_11Counter.CCMPDecryptErrors++;
53022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					} else if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_WEP)) {
5315449c685a4b39534f18869a93896370224463715Forest Bond//                      pDevice->s802_11Counter.WEPICVErrorCount.QuadPart++;
53222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					}
53322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				}
53422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				return false;
53522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
53622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		} else {
53722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WEP Func Fail\n");
53822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			return false;
53922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
54022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_CCMP))
54122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			FrameSize -= 8;         // Message Integrity Code
54222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		else
54322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			FrameSize -= 4;         // 4 is ICV
54422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
54522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
54622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
54722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	//
54822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	// RX OK
54922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	//
55022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	//remove the CRC length
55122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	FrameSize -= ETH_FCS_LEN;
55222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
55322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if ((!(*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI))) && // unicast address
55422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	    (IS_FRAGMENT_PKT((skb->data+4)))
55522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches) {
55622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		// defragment
55722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		bDeFragRx = WCTLbHandleFragment(pDevice, (PS802_11Header)(skb->data+4), FrameSize, bIsWEP, bExtIV);
55822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		pDevice->s802_11Counter.ReceivedFragmentCount++;
55922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (bDeFragRx) {
56022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// defrag complete
56122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			skb = pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].skb;
56222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			FrameSize = pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength;
56322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
56422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
56522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		else {
56622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			return false;
56722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
56822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
5695449c685a4b39534f18869a93896370224463715Forest Bond
5705449c685a4b39534f18869a93896370224463715Forest Bond
5715449c685a4b39534f18869a93896370224463715Forest Bond// Management & Control frame Handle
57222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if ((IS_TYPE_DATA((skb->data+4))) == false) {
57322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		// Handle Control & Manage Frame
57422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
57522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (IS_TYPE_MGMT((skb->data+4))) {
57622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			unsigned char *pbyData1;
57722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			unsigned char *pbyData2;
57822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
57922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			pRxPacket->p80211Header = (PUWLAN_80211HDR)(skb->data+4);
58022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			pRxPacket->cbMPDULen = FrameSize;
58122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			pRxPacket->uRSSI = *pbyRSSI;
58222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			pRxPacket->bySQ = *pbySQ;
58322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			HIDWORD(pRxPacket->qwLocalTSF) = cpu_to_le32(HIDWORD(*pqwTSFTime));
58422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			LODWORD(pRxPacket->qwLocalTSF) = cpu_to_le32(LODWORD(*pqwTSFTime));
58522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			if (bIsWEP) {
58622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				// strip IV
58722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				pbyData1 = WLAN_HDR_A3_DATA_PTR(skb->data+4);
58822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				pbyData2 = WLAN_HDR_A3_DATA_PTR(skb->data+4) + 4;
58922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				for (ii = 0; ii < (FrameSize - 4); ii++) {
59022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					*pbyData1 = *pbyData2;
59122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					pbyData1++;
59222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					pbyData2++;
59322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				}
59422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
59522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			pRxPacket->byRxRate = s_byGetRateIdx(*pbyRxRate);
59622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			pRxPacket->byRxChannel = (*pbyRxSts) >> 2;
5975449c685a4b39534f18869a93896370224463715Forest Bond//PLICE_DEBUG->
5985449c685a4b39534f18869a93896370224463715Forest Bond//EnQueue(pDevice,pRxPacket);
5995449c685a4b39534f18869a93896370224463715Forest Bond
6005449c685a4b39534f18869a93896370224463715Forest Bond#ifdef	THREAD
60122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			EnQueue(pDevice, pRxPacket);
6025449c685a4b39534f18869a93896370224463715Forest Bond
60322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			//printk("enque time is %x\n",jiffies);
60422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			//up(&pDevice->mlme_semaphore);
6055449c685a4b39534f18869a93896370224463715Forest Bond			//Enque (pDevice->FirstRecvMngList,pDevice->LastRecvMngList,pMgmt);
6065449c685a4b39534f18869a93896370224463715Forest Bond#else
6075449c685a4b39534f18869a93896370224463715Forest Bond
6085449c685a4b39534f18869a93896370224463715Forest Bond#ifdef	TASK_LET
60922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			EnQueue(pDevice, pRxPacket);
61022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			tasklet_schedule(&pDevice->RxMngWorkItem);
6115449c685a4b39534f18869a93896370224463715Forest Bond#else
6125449c685a4b39534f18869a93896370224463715Forest Bond//printk("RxMan\n");
61322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			vMgrRxManagePacket((void *)pDevice, pDevice->pMgmt, pRxPacket);
61422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			//tasklet_schedule(&pDevice->RxMngWorkItem);
6155449c685a4b39534f18869a93896370224463715Forest Bond#endif
6165449c685a4b39534f18869a93896370224463715Forest Bond
6175449c685a4b39534f18869a93896370224463715Forest Bond#endif
6185449c685a4b39534f18869a93896370224463715Forest Bond//PLICE_DEBUG<-
619e64354c0be3b7134c85571a525b2e37fc4a95eefCharles Clément			//vMgrRxManagePacket((void *)pDevice, pDevice->pMgmt, pRxPacket);
62022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// hostap Deamon handle 802.11 management
62122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			if (pDevice->bEnableHostapd) {
62222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				skb->dev = pDevice->apdev;
62322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				skb->data += 4;
62422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				skb->tail += 4;
62522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				skb_put(skb, FrameSize);
62622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				skb_reset_mac_header(skb);
62722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				skb->pkt_type = PACKET_OTHERHOST;
62822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				skb->protocol = htons(ETH_P_802_2);
62922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				memset(skb->cb, 0, sizeof(skb->cb));
63022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				netif_rx(skb);
63122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				return true;
63222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
63322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
63422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		else {
63522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// Control Frame
63622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		};
63722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		return false;
63822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
63922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	else {
64022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
64122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			//In AP mode, hw only check addr1(BSSID or RA) if equal to local MAC.
64222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			if (!(*pbyRsr & RSR_BSSIDOK)) {
64322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				if (bDeFragRx) {
64422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
64522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: can not alloc more frag bufs\n",
64622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							pDevice->dev->name);
64722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					}
64822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				}
64922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				return false;
65022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
65122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
65222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		else {
65322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// discard DATA packet while not associate || BSSID error
65422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			if ((pDevice->bLinkPass == false) ||
65522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			    !(*pbyRsr & RSR_BSSIDOK)) {
65622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				if (bDeFragRx) {
65722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
65822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: can not alloc more frag bufs\n",
65922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							pDevice->dev->name);
66022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					}
66122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				}
66222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				return false;
66322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
66422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			//mike add:station mode check eapol-key challenge--->
66522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			{
66622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				unsigned char Protocol_Version;    //802.1x Authentication
66722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				unsigned char Packet_Type;           //802.1x Authentication
66822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				if (bIsWEP)
66922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					cbIVOffset = 8;
67022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				else
67122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					cbIVOffset = 0;
67222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				wEtherType = (skb->data[cbIVOffset + 8 + 24 + 6] << 8) |
67322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					skb->data[cbIVOffset + 8 + 24 + 6 + 1];
67422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				Protocol_Version = skb->data[cbIVOffset + 8 + 24 + 6 + 1 + 1];
67522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				Packet_Type = skb->data[cbIVOffset + 8 + 24 + 6 + 1 + 1 + 1];
67622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				if (wEtherType == ETH_P_PAE) {         //Protocol Type in LLC-Header
67722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					if (((Protocol_Version == 1) || (Protocol_Version == 2)) &&
67822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					    (Packet_Type == 3)) {  //802.1x OR eapol-key challenge frame receive
67922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						bRxeapol_key = true;
68022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					}
68122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				}
68222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
68322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			//mike add:station mode check eapol-key challenge<---
68422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
68522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
6865449c685a4b39534f18869a93896370224463715Forest Bond
687612822f5dd1638de442cf50eb9da54632fba0e66Jim Lieb
6885449c685a4b39534f18869a93896370224463715Forest Bond// Data frame Handle
6895449c685a4b39534f18869a93896370224463715Forest Bond
690612822f5dd1638de442cf50eb9da54632fba0e66Jim Lieb
69122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (pDevice->bEnablePSMode) {
69222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (IS_FC_MOREDATA((skb->data+4))) {
69322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			if (*pbyRsr & RSR_ADDROK) {
69422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				//PSbSendPSPOLL((PSDevice)pDevice);
69522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
69622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
69722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		else {
69822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			if (pDevice->pMgmt->bInTIMWake == true) {
69922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				pDevice->pMgmt->bInTIMWake = false;
70022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
70122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
70222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
70322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
70422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	// Now it only supports 802.11g Infrastructure Mode, and support rate must up to 54 Mbps
70522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (pDevice->bDiversityEnable && (FrameSize > 50) &&
70622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	    (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) &&
70722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	    (pDevice->bLinkPass == true)) {
70822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		//printk("device_receive_frame: RxRate is %d\n",*pbyRxRate);
7095449c685a4b39534f18869a93896370224463715Forest Bond		BBvAntennaDiversity(pDevice, s_byGetRateIdx(*pbyRxRate), 0);
71022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
7115449c685a4b39534f18869a93896370224463715Forest Bond
71222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
71322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (pDevice->byLocalID != REV_ID_VT3253_B1) {
71422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		pDevice->uCurrRSSI = *pbyRSSI;
71522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
71622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	pDevice->byCurrSQ = *pbySQ;
71722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
71822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if ((*pbyRSSI != 0) &&
71922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	    (pMgmt->pCurrBSS != NULL)) {
72022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		RFvRSSITodBm(pDevice, *pbyRSSI, &ldBm);
72122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		// Monitor if RSSI is too strong.
72222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		pMgmt->pCurrBSS->byRSSIStatCnt++;
72322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		pMgmt->pCurrBSS->byRSSIStatCnt %= RSSI_STAT_COUNT;
72422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		pMgmt->pCurrBSS->ldBmAverage[pMgmt->pCurrBSS->byRSSIStatCnt] = ldBm;
72522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		for (ii = 0; ii < RSSI_STAT_COUNT; ii++) {
72622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			if (pMgmt->pCurrBSS->ldBmAverage[ii] != 0) {
72722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				pMgmt->pCurrBSS->ldBmMAX = max(pMgmt->pCurrBSS->ldBmAverage[ii], ldBm);
72822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
72922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
73022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
73122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
73222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	// -----------------------------------------------
73322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
73422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && (pDevice->bEnable8021x == true)) {
73522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		unsigned char abyMacHdr[24];
73622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
73722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		// Only 802.1x packet incoming allowed
73822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (bIsWEP)
73922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			cbIVOffset = 8;
74022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		else
74122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			cbIVOffset = 0;
74222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		wEtherType = (skb->data[cbIVOffset + 4 + 24 + 6] << 8) |
74322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			skb->data[cbIVOffset + 4 + 24 + 6 + 1];
74422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
74522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wEtherType = %04x \n", wEtherType);
74622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (wEtherType == ETH_P_PAE) {
74722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			skb->dev = pDevice->apdev;
74822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
74922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			if (bIsWEP == true) {
75022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				// strip IV header(8)
75122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				memcpy(&abyMacHdr[0], (skb->data + 4), 24);
75222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				memcpy((skb->data + 4 + cbIVOffset), &abyMacHdr[0], 24);
75322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
75422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			skb->data +=  (cbIVOffset + 4);
75522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			skb->tail +=  (cbIVOffset + 4);
75622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			skb_put(skb, FrameSize);
75722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			skb_reset_mac_header(skb);
75822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
75922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			skb->pkt_type = PACKET_OTHERHOST;
76022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			skb->protocol = htons(ETH_P_802_2);
76122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			memset(skb->cb, 0, sizeof(skb->cb));
76222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			netif_rx(skb);
76322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			return true;
76422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
76522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
76622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		// check if 802.1x authorized
76722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (!(pMgmt->sNodeDBTable[iSANodeIndex].dwFlags & WLAN_STA_AUTHORIZED))
76822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			return false;
76922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
77022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
77122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
77222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_TKIP)) {
77322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (bIsWEP) {
77422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			FrameSize -= 8;  //MIC
77522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
77622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
77722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
77822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	//--------------------------------------------------------------------------------
77922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	// Soft MIC
78022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_TKIP)) {
78122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (bIsWEP) {
78222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			unsigned long *pdwMIC_L;
78322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			unsigned long *pdwMIC_R;
78422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			unsigned long dwMIC_Priority;
78522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			unsigned long dwMICKey0 = 0, dwMICKey1 = 0;
78622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			unsigned long dwLocalMIC_L = 0;
78722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			unsigned long dwLocalMIC_R = 0;
78822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			viawget_wpa_header *wpahdr;
78922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
79022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
79122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
79222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				dwMICKey0 = cpu_to_le32(*(unsigned long *)(&pKey->abyKey[24]));
79322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				dwMICKey1 = cpu_to_le32(*(unsigned long *)(&pKey->abyKey[28]));
79422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
79522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			else {
79622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				if (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
79722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					dwMICKey0 = cpu_to_le32(*(unsigned long *)(&pKey->abyKey[16]));
79822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					dwMICKey1 = cpu_to_le32(*(unsigned long *)(&pKey->abyKey[20]));
79922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				} else if ((pKey->dwKeyIndex & BIT28) == 0) {
80022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					dwMICKey0 = cpu_to_le32(*(unsigned long *)(&pKey->abyKey[16]));
80122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					dwMICKey1 = cpu_to_le32(*(unsigned long *)(&pKey->abyKey[20]));
80222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				} else {
80322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					dwMICKey0 = cpu_to_le32(*(unsigned long *)(&pKey->abyKey[24]));
80422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					dwMICKey1 = cpu_to_le32(*(unsigned long *)(&pKey->abyKey[28]));
80522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				}
80622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
80722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
80822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			MIC_vInit(dwMICKey0, dwMICKey1);
80922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			MIC_vAppend((unsigned char *)&(pDevice->sRxEthHeader.abyDstAddr[0]), 12);
81022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			dwMIC_Priority = 0;
81122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			MIC_vAppend((unsigned char *)&dwMIC_Priority, 4);
81222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// 4 is Rcv buffer header, 24 is MAC Header, and 8 is IV and Ext IV.
81322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			MIC_vAppend((unsigned char *)(skb->data + 4 + WLAN_HDR_ADDR3_LEN + 8),
81422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				    FrameSize - WLAN_HDR_ADDR3_LEN - 8);
81522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			MIC_vGetMIC(&dwLocalMIC_L, &dwLocalMIC_R);
81622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			MIC_vUnInit();
81722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
81822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			pdwMIC_L = (unsigned long *)(skb->data + 4 + FrameSize);
81922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			pdwMIC_R = (unsigned long *)(skb->data + 4 + FrameSize + 4);
82022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			//DBG_PRN_GRP12(("RxL: %lx, RxR: %lx\n", *pdwMIC_L, *pdwMIC_R));
82122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			//DBG_PRN_GRP12(("LocalL: %lx, LocalR: %lx\n", dwLocalMIC_L, dwLocalMIC_R));
82222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			//DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dwMICKey0= %lx,dwMICKey1= %lx \n", dwMICKey0, dwMICKey1);
82322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
82422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
82522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			if ((cpu_to_le32(*pdwMIC_L) != dwLocalMIC_L) || (cpu_to_le32(*pdwMIC_R) != dwLocalMIC_R) ||
82622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			    (pDevice->bRxMICFail == true)) {
82722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MIC comparison is fail!\n");
82822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				pDevice->bRxMICFail = false;
82922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				//pDevice->s802_11Counter.TKIPLocalMICFailures.QuadPart++;
83022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				pDevice->s802_11Counter.TKIPLocalMICFailures++;
83122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				if (bDeFragRx) {
83222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
83322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: can not alloc more frag bufs\n",
83422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							pDevice->dev->name);
83522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					}
83622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				}
83722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				//2008-0409-07, <Add> by Einsn Liu
83822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
8395449c685a4b39534f18869a93896370224463715Forest Bond				//send event to wpa_supplicant
84022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				//if (pDevice->bWPADevEnable == true)
841612822f5dd1638de442cf50eb9da54632fba0e66Jim Lieb				{
8425449c685a4b39534f18869a93896370224463715Forest Bond					union iwreq_data wrqu;
8435449c685a4b39534f18869a93896370224463715Forest Bond					struct iw_michaelmicfailure ev;
8445449c685a4b39534f18869a93896370224463715Forest Bond					int keyidx = pbyFrame[cbHeaderSize+3] >> 6; //top two-bits
8455449c685a4b39534f18869a93896370224463715Forest Bond					memset(&ev, 0, sizeof(ev));
8465449c685a4b39534f18869a93896370224463715Forest Bond					ev.flags = keyidx & IW_MICFAILURE_KEY_ID;
8475449c685a4b39534f18869a93896370224463715Forest Bond					if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
84822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					    (pMgmt->eCurrState == WMAC_STATE_ASSOC) &&
84922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					    (*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI)) == 0) {
8505449c685a4b39534f18869a93896370224463715Forest Bond						ev.flags |= IW_MICFAILURE_PAIRWISE;
8515449c685a4b39534f18869a93896370224463715Forest Bond					} else {
8525449c685a4b39534f18869a93896370224463715Forest Bond						ev.flags |= IW_MICFAILURE_GROUP;
8535449c685a4b39534f18869a93896370224463715Forest Bond					}
8545449c685a4b39534f18869a93896370224463715Forest Bond
8555449c685a4b39534f18869a93896370224463715Forest Bond					ev.src_addr.sa_family = ARPHRD_ETHER;
8565449c685a4b39534f18869a93896370224463715Forest Bond					memcpy(ev.src_addr.sa_data, pMACHeader->abyAddr2, ETH_ALEN);
8575449c685a4b39534f18869a93896370224463715Forest Bond					memset(&wrqu, 0, sizeof(wrqu));
8585449c685a4b39534f18869a93896370224463715Forest Bond					wrqu.data.length = sizeof(ev);
8595449c685a4b39534f18869a93896370224463715Forest Bond					wireless_send_event(pDevice->dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&ev);
8605449c685a4b39534f18869a93896370224463715Forest Bond
8615449c685a4b39534f18869a93896370224463715Forest Bond				}
86222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches#endif
86322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
86422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
86522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) {
86622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					wpahdr = (viawget_wpa_header *)pDevice->skb->data;
86722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					if ((pDevice->pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
86822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					    (pDevice->pMgmt->eCurrState == WMAC_STATE_ASSOC) &&
86922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					    (*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI)) == 0) {
87022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						//s802_11_Status.Flags = NDIS_802_11_AUTH_REQUEST_PAIRWISE_ERROR;
87122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						wpahdr->type = VIAWGET_PTK_MIC_MSG;
87222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					} else {
87322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						//s802_11_Status.Flags = NDIS_802_11_AUTH_REQUEST_GROUP_ERROR;
87422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						wpahdr->type = VIAWGET_GTK_MIC_MSG;
87522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					}
87622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					wpahdr->resp_ie_len = 0;
87722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					wpahdr->req_ie_len = 0;
87822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					skb_put(pDevice->skb, sizeof(viawget_wpa_header));
87922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					pDevice->skb->dev = pDevice->wpadev;
88022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					skb_reset_mac_header(pDevice->skb);
88122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					pDevice->skb->pkt_type = PACKET_HOST;
88222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					pDevice->skb->protocol = htons(ETH_P_802_2);
88322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
88422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					netif_rx(pDevice->skb);
88522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
88622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				}
88722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
88822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				return false;
88922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
89022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
89122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
89222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	} //---end of SOFT MIC-----------------------------------------------------------------------
89322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
89422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	// ++++++++++ Reply Counter Check +++++++++++++
89522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
89622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if ((pKey != NULL) && ((pKey->byCipherSuite == KEY_CTL_TKIP) ||
89722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			       (pKey->byCipherSuite == KEY_CTL_CCMP))) {
89822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (bIsWEP) {
89922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			unsigned short wLocalTSC15_0 = 0;
90022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			unsigned long dwLocalTSC47_16 = 0;
90122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			unsigned long long       RSC = 0;
90222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// endian issues
90322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			RSC = *((unsigned long long *)&(pKey->KeyRSC));
90422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			wLocalTSC15_0 = (unsigned short)RSC;
90522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			dwLocalTSC47_16 = (unsigned long)(RSC>>16);
90622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
90722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			RSC = dwRxTSC47_16;
90822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			RSC <<= 16;
90922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			RSC += wRxTSC15_0;
91022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			memcpy(&(pKey->KeyRSC), &RSC,  sizeof(QWORD));
91122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
91222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			if ((pDevice->sMgmtObj.eCurrMode == WMAC_MODE_ESS_STA) &&
91322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			    (pDevice->sMgmtObj.eCurrState == WMAC_STATE_ASSOC)) {
91422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				// check RSC
91522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				if ((wRxTSC15_0 < wLocalTSC15_0) &&
91622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				    (dwRxTSC47_16 <= dwLocalTSC47_16) &&
91722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				    !((dwRxTSC47_16 == 0) && (dwLocalTSC47_16 == 0xFFFFFFFF))) {
91822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "TSC is illegal~~!\n ");
91922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					if (pKey->byCipherSuite == KEY_CTL_TKIP)
92022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						//pDevice->s802_11Counter.TKIPReplays.QuadPart++;
92122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						pDevice->s802_11Counter.TKIPReplays++;
92222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					else
92322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						//pDevice->s802_11Counter.CCMPReplays.QuadPart++;
92422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						pDevice->s802_11Counter.CCMPReplays++;
92522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
92622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					if (bDeFragRx) {
92722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
92822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: can not alloc more frag bufs\n",
92922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches								pDevice->dev->name);
93022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						}
93122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					}
93222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					return false;
93322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				}
93422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
93522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
93622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	} // ----- End of Reply Counter Check --------------------------
93722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
93822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
93922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
94022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if ((pKey != NULL) && (bIsWEP)) {
9415449c685a4b39534f18869a93896370224463715Forest Bond//      pDevice->s802_11Counter.DecryptSuccessCount.QuadPart++;
94222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
94322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
94422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
94522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	s_vProcessRxMACHeader(pDevice, (unsigned char *)(skb->data+4), FrameSize, bIsWEP, bExtIV, &cbHeaderOffset);
94622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	FrameSize -= cbHeaderOffset;
94722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	cbHeaderOffset += 4;        // 4 is Rcv buffer header
94822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
94922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	// Null data, framesize = 14
95022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (FrameSize < 15)
95122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		return false;
95222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
95322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
95422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (s_bAPModeRxData(pDevice,
95522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				    skb,
95622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				    FrameSize,
95722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				    cbHeaderOffset,
95822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				    iSANodeIndex,
95922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				    iDANodeIndex
96022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches) == false) {
96122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
96222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			if (bDeFragRx) {
96322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
96422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: can not alloc more frag bufs\n",
96522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						pDevice->dev->name);
96622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				}
96722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
96822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			return false;
96922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
97022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
97122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches//        if (pDevice->bRxMICFail == false) {
9725449c685a4b39534f18869a93896370224463715Forest Bond//           for (ii =0; ii < 100; ii++)
9735449c685a4b39534f18869a93896370224463715Forest Bond//                printk(" %02x", *(skb->data + ii));
9745449c685a4b39534f18869a93896370224463715Forest Bond//           printk("\n");
9755449c685a4b39534f18869a93896370224463715Forest Bond//	    }
9765449c685a4b39534f18869a93896370224463715Forest Bond
97722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
9785449c685a4b39534f18869a93896370224463715Forest Bond
9795449c685a4b39534f18869a93896370224463715Forest Bond	skb->data += cbHeaderOffset;
9805449c685a4b39534f18869a93896370224463715Forest Bond	skb->tail += cbHeaderOffset;
98122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	skb_put(skb, FrameSize);
98222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	skb->protocol = eth_type_trans(skb, skb->dev);
9835449c685a4b39534f18869a93896370224463715Forest Bond
9845449c685a4b39534f18869a93896370224463715Forest Bond
9855449c685a4b39534f18869a93896370224463715Forest Bond	//drop frame not met IEEE 802.3
9865449c685a4b39534f18869a93896370224463715Forest Bond/*
98722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches  if (pDevice->flags & DEVICE_FLAGS_VAL_PKT_LEN) {
98822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches  if ((skb->protocol==htons(ETH_P_802_3)) &&
98922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches  (skb->len!=htons(skb->mac.ethernet->h_proto))) {
99022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches  pStats->rx_length_errors++;
99122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches  pStats->rx_dropped++;
99222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches  if (bDeFragRx) {
99322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches  if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
99422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches  DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
99522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches  pDevice->dev->name);
99622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches  }
99722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches  }
99822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches  return false;
99922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches  }
100022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches  }
10015449c685a4b39534f18869a93896370224463715Forest Bond*/
10025449c685a4b39534f18869a93896370224463715Forest Bond
100322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	skb->ip_summed = CHECKSUM_NONE;
100422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	pStats->rx_bytes += skb->len;
100522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	pStats->rx_packets++;
100622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	netif_rx(skb);
10075449c685a4b39534f18869a93896370224463715Forest Bond
100822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (bDeFragRx) {
100922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
101022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: can not alloc more frag bufs\n",
101122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				pDevice->dev->name);
101222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
101322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		return false;
101422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
1015612822f5dd1638de442cf50eb9da54632fba0e66Jim Lieb
101622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	return true;
10175449c685a4b39534f18869a93896370224463715Forest Bond}
10185449c685a4b39534f18869a93896370224463715Forest Bond
10195449c685a4b39534f18869a93896370224463715Forest Bond
102022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perchesstatic bool s_bAPModeRxCtl(
102122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PSDevice pDevice,
102222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyFrame,
102322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	int      iSANodeIndex
102422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches)
10255449c685a4b39534f18869a93896370224463715Forest Bond{
102622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PS802_11Header      p802_11Header;
102722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	CMD_STATUS          Status;
102822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PSMgmtObject        pMgmt = pDevice->pMgmt;
102922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
103022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
103122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (IS_CTL_PSPOLL(pbyFrame) || !IS_TYPE_CONTROL(pbyFrame)) {
103222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
103322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		p802_11Header = (PS802_11Header)(pbyFrame);
103422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (!IS_TYPE_MGMT(pbyFrame)) {
103522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
103622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// Data & PS-Poll packet
103722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// check frame class
103822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			if (iSANodeIndex > 0) {
103922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				// frame class 3 fliter & checking
104022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				if (pMgmt->sNodeDBTable[iSANodeIndex].eNodeState < NODE_AUTH) {
104122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					// send deauth notification
104222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					// reason = (6) class 2 received from nonauth sta
104322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					vMgrDeAuthenBeginSta(pDevice,
104422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							     pMgmt,
104522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							     (unsigned char *)(p802_11Header->abyAddr2),
104622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							     (WLAN_MGMT_REASON_CLASS2_NONAUTH),
104722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							     &Status
104822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches);
104922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: send vMgrDeAuthenBeginSta 1\n");
105022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					return true;
105122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				}
105222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				if (pMgmt->sNodeDBTable[iSANodeIndex].eNodeState < NODE_ASSOC) {
105322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					// send deassoc notification
105422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					// reason = (7) class 3 received from nonassoc sta
105522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					vMgrDisassocBeginSta(pDevice,
105622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							     pMgmt,
105722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							     (unsigned char *)(p802_11Header->abyAddr2),
105822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							     (WLAN_MGMT_REASON_CLASS3_NONASSOC),
105922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							     &Status
106022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches);
106122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: send vMgrDisassocBeginSta 2\n");
106222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					return true;
106322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				}
106422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
106522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				if (pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable) {
106622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					// delcare received ps-poll event
106722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					if (IS_CTL_PSPOLL(pbyFrame)) {
106822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = true;
106922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						bScheduleCommand((void *)pDevice, WLAN_CMD_RX_PSPOLL, NULL);
107022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: WLAN_CMD_RX_PSPOLL 1\n");
107122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					}
107222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					else {
107322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						// check Data PS state
107422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						// if PW bit off, send out all PS bufferring packets.
107522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						if (!IS_FC_POWERMGT(pbyFrame)) {
107622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = false;
107722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = true;
107822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							bScheduleCommand((void *)pDevice, WLAN_CMD_RX_PSPOLL, NULL);
107922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: WLAN_CMD_RX_PSPOLL 2\n");
108022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						}
108122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					}
108222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				}
108322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				else {
108422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					if (IS_FC_POWERMGT(pbyFrame)) {
108522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = true;
108622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						// Once if STA in PS state, enable multicast bufferring
108722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						pMgmt->sNodeDBTable[0].bPSEnable = true;
108822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					}
108922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					else {
109022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						// clear all pending PS frame.
109122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						if (pMgmt->sNodeDBTable[iSANodeIndex].wEnQueueCnt > 0) {
109222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = false;
109322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = true;
109422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							bScheduleCommand((void *)pDevice, WLAN_CMD_RX_PSPOLL, NULL);
109522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: WLAN_CMD_RX_PSPOLL 3\n");
109622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
109722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						}
109822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					}
109922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				}
110022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
110122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			else {
110222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				vMgrDeAuthenBeginSta(pDevice,
110322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						     pMgmt,
110422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						     (unsigned char *)(p802_11Header->abyAddr2),
110522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						     (WLAN_MGMT_REASON_CLASS2_NONAUTH),
110622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						     &Status
110722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches);
110822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: send vMgrDeAuthenBeginSta 3\n");
110922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BSSID:%pM\n",
111022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					p802_11Header->abyAddr3);
111122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ADDR2:%pM\n",
111222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					p802_11Header->abyAddr2);
111322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ADDR1:%pM\n",
111422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					p802_11Header->abyAddr1);
111522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: wFrameCtl= %x\n", p802_11Header->wFrameCtl);
111622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				VNSvInPortB(pDevice->PortOffset + MAC_REG_RCR, &(pDevice->byRxMode));
111722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc:pDevice->byRxMode = %x\n", pDevice->byRxMode);
111822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				return true;
111922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
112022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
112122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
112222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	return false;
11235449c685a4b39534f18869a93896370224463715Forest Bond
11245449c685a4b39534f18869a93896370224463715Forest Bond}
11255449c685a4b39534f18869a93896370224463715Forest Bond
112622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perchesstatic bool s_bHandleRxEncryption(
112722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PSDevice     pDevice,
112822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyFrame,
112922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned int FrameSize,
113022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyRsr,
113122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyNewRsr,
113222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PSKeyItem   *pKeyOut,
113322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	bool *pbExtIV,
113422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned short *pwRxTSC15_0,
113522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned long *pdwRxTSC47_16
113622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches)
11375449c685a4b39534f18869a93896370224463715Forest Bond{
113822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned int PayloadLen = FrameSize;
113922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyIV;
114022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char byKeyIdx;
114122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PSKeyItem       pKey = NULL;
114222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char byDecMode = KEY_CTL_WEP;
114322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PSMgmtObject    pMgmt = pDevice->pMgmt;
114422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
114522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
114622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	*pwRxTSC15_0 = 0;
114722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	*pdwRxTSC47_16 = 0;
114822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
114922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN;
115022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (WLAN_GET_FC_TODS(*(unsigned short *)pbyFrame) &&
115122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	    WLAN_GET_FC_FROMDS(*(unsigned short *)pbyFrame)) {
115222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		pbyIV += 6;             // 6 is 802.11 address4
115322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		PayloadLen -= 6;
115422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
115522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	byKeyIdx = (*(pbyIV+3) & 0xc0);
115622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	byKeyIdx >>= 6;
115722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "\nKeyIdx: %d\n", byKeyIdx);
115822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
115922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA) ||
116022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	    (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) ||
116122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	    (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) ||
116222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	    (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) ||
116322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	    (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) {
116422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (((*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI)) == 0) &&
116522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		    (pDevice->pMgmt->byCSSPK != KEY_CTL_NONE)) {
116622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// unicast pkt use pairwise key
116722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "unicast pkt\n");
116822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			if (KeybGetKey(&(pDevice->sKey), pDevice->abyBSSID, 0xFFFFFFFF, &pKey) == true) {
116922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				if (pDevice->pMgmt->byCSSPK == KEY_CTL_TKIP)
117022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					byDecMode = KEY_CTL_TKIP;
117122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				else if (pDevice->pMgmt->byCSSPK == KEY_CTL_CCMP)
117222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					byDecMode = KEY_CTL_CCMP;
117322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
117422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "unicast pkt: %d, %p\n", byDecMode, pKey);
117522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		} else {
117622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// use group key
117722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			KeybGetKey(&(pDevice->sKey), pDevice->abyBSSID, byKeyIdx, &pKey);
117822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			if (pDevice->pMgmt->byCSSGK == KEY_CTL_TKIP)
117922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				byDecMode = KEY_CTL_TKIP;
118022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			else if (pDevice->pMgmt->byCSSGK == KEY_CTL_CCMP)
118122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				byDecMode = KEY_CTL_CCMP;
118222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "group pkt: %d, %d, %p\n", byKeyIdx, byDecMode, pKey);
118322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
118422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
118522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	// our WEP only support Default Key
118622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (pKey == NULL) {
118722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		// use default group key
118822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, byKeyIdx, &pKey);
118922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (pDevice->pMgmt->byCSSGK == KEY_CTL_TKIP)
119022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			byDecMode = KEY_CTL_TKIP;
119122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		else if (pDevice->pMgmt->byCSSGK == KEY_CTL_CCMP)
119222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			byDecMode = KEY_CTL_CCMP;
119322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
119422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	*pKeyOut = pKey;
119522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
119622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "AES:%d %d %d\n", pDevice->pMgmt->byCSSPK, pDevice->pMgmt->byCSSGK, byDecMode);
119722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
119822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (pKey == NULL) {
119922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey == NULL\n");
120022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (byDecMode == KEY_CTL_WEP) {
12015449c685a4b39534f18869a93896370224463715Forest Bond//            pDevice->s802_11Counter.WEPUndecryptableCount.QuadPart++;
120222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		} else if (pDevice->bLinkPass == true) {
12035449c685a4b39534f18869a93896370224463715Forest Bond//            pDevice->s802_11Counter.DecryptFailureCount.QuadPart++;
120422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
120522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		return false;
120622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
120722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (byDecMode != pKey->byCipherSuite) {
120822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (byDecMode == KEY_CTL_WEP) {
12095449c685a4b39534f18869a93896370224463715Forest Bond//            pDevice->s802_11Counter.WEPUndecryptableCount.QuadPart++;
121022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		} else if (pDevice->bLinkPass == true) {
12115449c685a4b39534f18869a93896370224463715Forest Bond//            pDevice->s802_11Counter.DecryptFailureCount.QuadPart++;
121222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
121322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		*pKeyOut = NULL;
121422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		return false;
121522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
121622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (byDecMode == KEY_CTL_WEP) {
121722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		// handle WEP
121822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if ((pDevice->byLocalID <= REV_ID_VT3253_A1) ||
121922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		    (((PSKeyTable)(pKey->pvKeyTable))->bSoftWEP == true)) {
122022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// Software WEP
122122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// 1. 3253A
122222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// 2. WEP 256
122322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
122422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			PayloadLen -= (WLAN_HDR_ADDR3_LEN + 4 + 4); // 24 is 802.11 header,4 is IV, 4 is crc
122522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			memcpy(pDevice->abyPRNG, pbyIV, 3);
122622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			memcpy(pDevice->abyPRNG + 3, pKey->abyKey, pKey->uKeyLength);
122722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			rc4_init(&pDevice->SBox, pDevice->abyPRNG, pKey->uKeyLength + 3);
122822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			rc4_encrypt(&pDevice->SBox, pbyIV+4, pbyIV+4, PayloadLen);
122922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
123022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			if (ETHbIsBufferCrc32Ok(pbyIV+4, PayloadLen)) {
123122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				*pbyNewRsr |= NEWRSR_DECRYPTOK;
123222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
123322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
123422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	} else if ((byDecMode == KEY_CTL_TKIP) ||
123522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		   (byDecMode == KEY_CTL_CCMP)) {
123622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		// TKIP/AES
123722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
123822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		PayloadLen -= (WLAN_HDR_ADDR3_LEN + 8 + 4); // 24 is 802.11 header, 8 is IV&ExtIV, 4 is crc
123922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		*pdwRxTSC47_16 = cpu_to_le32(*(unsigned long *)(pbyIV + 4));
124022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ExtIV: %lx\n", *pdwRxTSC47_16);
124122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (byDecMode == KEY_CTL_TKIP) {
124222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			*pwRxTSC15_0 = cpu_to_le16(MAKEWORD(*(pbyIV + 2), *pbyIV));
124322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		} else {
124422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			*pwRxTSC15_0 = cpu_to_le16(*(unsigned short *)pbyIV);
124522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
124622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "TSC0_15: %x\n", *pwRxTSC15_0);
124722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
124822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if ((byDecMode == KEY_CTL_TKIP) &&
124922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		    (pDevice->byLocalID <= REV_ID_VT3253_A1)) {
125022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// Software TKIP
125122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// 1. 3253 A
125222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			PS802_11Header  pMACHeader = (PS802_11Header)(pbyFrame);
125322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			TKIPvMixKey(pKey->abyKey, pMACHeader->abyAddr2, *pwRxTSC15_0, *pdwRxTSC47_16, pDevice->abyPRNG);
125422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			rc4_init(&pDevice->SBox, pDevice->abyPRNG, TKIP_KEY_LEN);
125522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			rc4_encrypt(&pDevice->SBox, pbyIV+8, pbyIV+8, PayloadLen);
125622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			if (ETHbIsBufferCrc32Ok(pbyIV+8, PayloadLen)) {
125722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				*pbyNewRsr |= NEWRSR_DECRYPTOK;
125822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ICV OK!\n");
125922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			} else {
126022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ICV FAIL!!!\n");
126122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "PayloadLen = %d\n", PayloadLen);
126222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
126322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
126422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}// end of TKIP/AES
126522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
126622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if ((*(pbyIV+3) & 0x20) != 0)
126722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		*pbExtIV = true;
126822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	return true;
12695449c685a4b39534f18869a93896370224463715Forest Bond}
12705449c685a4b39534f18869a93896370224463715Forest Bond
12715449c685a4b39534f18869a93896370224463715Forest Bond
127222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perchesstatic bool s_bHostWepRxEncryption(
127322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PSDevice     pDevice,
127422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyFrame,
127522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned int FrameSize,
127622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyRsr,
127722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	bool bOnFly,
127822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PSKeyItem    pKey,
127922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyNewRsr,
128022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	bool *pbExtIV,
128122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned short *pwRxTSC15_0,
128222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned long *pdwRxTSC47_16
128322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches)
12845449c685a4b39534f18869a93896370224463715Forest Bond{
128522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned int PayloadLen = FrameSize;
128622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyIV;
128722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char byKeyIdx;
128822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char byDecMode = KEY_CTL_WEP;
128922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PS802_11Header  pMACHeader;
12905449c685a4b39534f18869a93896370224463715Forest Bond
12915449c685a4b39534f18869a93896370224463715Forest Bond
12925449c685a4b39534f18869a93896370224463715Forest Bond
129322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	*pwRxTSC15_0 = 0;
129422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	*pdwRxTSC47_16 = 0;
12955449c685a4b39534f18869a93896370224463715Forest Bond
129622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN;
129722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (WLAN_GET_FC_TODS(*(unsigned short *)pbyFrame) &&
129822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	    WLAN_GET_FC_FROMDS(*(unsigned short *)pbyFrame)) {
129922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		pbyIV += 6;             // 6 is 802.11 address4
130022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		PayloadLen -= 6;
130122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
130222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	byKeyIdx = (*(pbyIV+3) & 0xc0);
130322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	byKeyIdx >>= 6;
130422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "\nKeyIdx: %d\n", byKeyIdx);
13055449c685a4b39534f18869a93896370224463715Forest Bond
13065449c685a4b39534f18869a93896370224463715Forest Bond
130722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (pDevice->pMgmt->byCSSGK == KEY_CTL_TKIP)
130822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		byDecMode = KEY_CTL_TKIP;
130922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	else if (pDevice->pMgmt->byCSSGK == KEY_CTL_CCMP)
131022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		byDecMode = KEY_CTL_CCMP;
13115449c685a4b39534f18869a93896370224463715Forest Bond
131222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "AES:%d %d %d\n", pDevice->pMgmt->byCSSPK, pDevice->pMgmt->byCSSGK, byDecMode);
13135449c685a4b39534f18869a93896370224463715Forest Bond
131422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (byDecMode != pKey->byCipherSuite) {
131522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (byDecMode == KEY_CTL_WEP) {
13165449c685a4b39534f18869a93896370224463715Forest Bond//            pDevice->s802_11Counter.WEPUndecryptableCount.QuadPart++;
131722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		} else if (pDevice->bLinkPass == true) {
13185449c685a4b39534f18869a93896370224463715Forest Bond//            pDevice->s802_11Counter.DecryptFailureCount.QuadPart++;
131922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
132022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		return false;
132122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
132222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
132322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (byDecMode == KEY_CTL_WEP) {
132422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		// handle WEP
132522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "byDecMode == KEY_CTL_WEP \n");
132622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if ((pDevice->byLocalID <= REV_ID_VT3253_A1) ||
132722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		    (((PSKeyTable)(pKey->pvKeyTable))->bSoftWEP == true) ||
132822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		    (bOnFly == false)) {
132922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// Software WEP
133022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// 1. 3253A
133122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// 2. WEP 256
133222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// 3. NotOnFly
133322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
133422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			PayloadLen -= (WLAN_HDR_ADDR3_LEN + 4 + 4); // 24 is 802.11 header,4 is IV, 4 is crc
133522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			memcpy(pDevice->abyPRNG, pbyIV, 3);
133622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			memcpy(pDevice->abyPRNG + 3, pKey->abyKey, pKey->uKeyLength);
133722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			rc4_init(&pDevice->SBox, pDevice->abyPRNG, pKey->uKeyLength + 3);
133822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			rc4_encrypt(&pDevice->SBox, pbyIV+4, pbyIV+4, PayloadLen);
133922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
134022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			if (ETHbIsBufferCrc32Ok(pbyIV+4, PayloadLen)) {
134122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				*pbyNewRsr |= NEWRSR_DECRYPTOK;
134222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
134322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
134422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	} else if ((byDecMode == KEY_CTL_TKIP) ||
134522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		   (byDecMode == KEY_CTL_CCMP)) {
134622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		// TKIP/AES
134722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
134822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		PayloadLen -= (WLAN_HDR_ADDR3_LEN + 8 + 4); // 24 is 802.11 header, 8 is IV&ExtIV, 4 is crc
134922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		*pdwRxTSC47_16 = cpu_to_le32(*(unsigned long *)(pbyIV + 4));
135022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ExtIV: %lx\n", *pdwRxTSC47_16);
135122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
135222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (byDecMode == KEY_CTL_TKIP) {
135322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			*pwRxTSC15_0 = cpu_to_le16(MAKEWORD(*(pbyIV+2), *pbyIV));
135422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		} else {
135522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			*pwRxTSC15_0 = cpu_to_le16(*(unsigned short *)pbyIV);
135622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
135722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "TSC0_15: %x\n", *pwRxTSC15_0);
135822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
135922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (byDecMode == KEY_CTL_TKIP) {
136022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
136122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			if ((pDevice->byLocalID <= REV_ID_VT3253_A1) || (bOnFly == false)) {
136222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				// Software TKIP
136322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				// 1. 3253 A
136422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				// 2. NotOnFly
136522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "soft KEY_CTL_TKIP \n");
136622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				pMACHeader = (PS802_11Header)(pbyFrame);
136722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				TKIPvMixKey(pKey->abyKey, pMACHeader->abyAddr2, *pwRxTSC15_0, *pdwRxTSC47_16, pDevice->abyPRNG);
136822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				rc4_init(&pDevice->SBox, pDevice->abyPRNG, TKIP_KEY_LEN);
136922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				rc4_encrypt(&pDevice->SBox, pbyIV+8, pbyIV+8, PayloadLen);
137022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				if (ETHbIsBufferCrc32Ok(pbyIV+8, PayloadLen)) {
137122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					*pbyNewRsr |= NEWRSR_DECRYPTOK;
137222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ICV OK!\n");
137322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				} else {
137422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ICV FAIL!!!\n");
137522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "PayloadLen = %d\n", PayloadLen);
137622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				}
137722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
137822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
137922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
138022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (byDecMode == KEY_CTL_CCMP) {
138122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			if (bOnFly == false) {
138222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				// Software CCMP
138322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				// NotOnFly
138422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "soft KEY_CTL_CCMP\n");
138522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				if (AESbGenCCMP(pKey->abyKey, pbyFrame, FrameSize)) {
138622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					*pbyNewRsr |= NEWRSR_DECRYPTOK;
138722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "CCMP MIC compare OK!\n");
138822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				} else {
138922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "CCMP MIC fail!\n");
139022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				}
139122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
139222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
139322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
139422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}// end of TKIP/AES
139522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
139622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if ((*(pbyIV+3) & 0x20) != 0)
139722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		*pbExtIV = true;
139822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	return true;
13995449c685a4b39534f18869a93896370224463715Forest Bond}
14005449c685a4b39534f18869a93896370224463715Forest Bond
14015449c685a4b39534f18869a93896370224463715Forest Bond
14025449c685a4b39534f18869a93896370224463715Forest Bond
140322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perchesstatic bool s_bAPModeRxData(
140422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PSDevice pDevice,
140522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	struct sk_buff *skb,
140622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned int FrameSize,
140722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned int cbHeaderOffset,
140822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	int      iSANodeIndex,
140922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	int      iDANodeIndex
141022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches)
14115449c685a4b39534f18869a93896370224463715Forest Bond{
141222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PSMgmtObject        pMgmt = pDevice->pMgmt;
141322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	bool bRelayAndForward = false;
141422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	bool bRelayOnly = false;
141522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
141622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned short wAID;
141722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
141822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
141922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	struct sk_buff *skbcpy = NULL;
142022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
142122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (FrameSize > CB_MAX_BUF_SIZE)
142222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		return false;
142322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	// check DA
142422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (is_multicast_ether_addr((unsigned char *)(skb->data+cbHeaderOffset))) {
142522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (pMgmt->sNodeDBTable[0].bPSEnable) {
142622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
142722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			skbcpy = dev_alloc_skb((int)pDevice->rx_buf_sz);
142822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
142922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// if any node in PS mode, buffer packet until DTIM.
143022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			if (skbcpy == NULL) {
143122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "relay multicast no skb available \n");
143222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
143322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			else {
143422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				skbcpy->dev = pDevice->dev;
143522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				skbcpy->len = FrameSize;
143622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				memcpy(skbcpy->data, skb->data+cbHeaderOffset, FrameSize);
143722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				skb_queue_tail(&(pMgmt->sNodeDBTable[0].sTxPSQueue), skbcpy);
143822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
143922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				pMgmt->sNodeDBTable[0].wEnQueueCnt++;
144022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				// set tx map
144122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				pMgmt->abyPSTxMap[0] |= byMask[0];
144222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
144322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
144422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		else {
144522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			bRelayAndForward = true;
144622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
144722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
144822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	else {
144922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		// check if relay
145022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (BSSDBbIsSTAInNodeDB(pMgmt, (unsigned char *)(skb->data+cbHeaderOffset), &iDANodeIndex)) {
145122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			if (pMgmt->sNodeDBTable[iDANodeIndex].eNodeState >= NODE_ASSOC) {
145222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				if (pMgmt->sNodeDBTable[iDANodeIndex].bPSEnable) {
145322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					// queue this skb until next PS tx, and then release.
145422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
145522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					skb->data += cbHeaderOffset;
145622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					skb->tail += cbHeaderOffset;
145722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					skb_put(skb, FrameSize);
145822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					skb_queue_tail(&pMgmt->sNodeDBTable[iDANodeIndex].sTxPSQueue, skb);
145922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					pMgmt->sNodeDBTable[iDANodeIndex].wEnQueueCnt++;
146022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					wAID = pMgmt->sNodeDBTable[iDANodeIndex].wAID;
146122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					pMgmt->abyPSTxMap[wAID >> 3] |=  byMask[wAID & 7];
146222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "relay: index= %d, pMgmt->abyPSTxMap[%d]= %d\n",
146322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						iDANodeIndex, (wAID >> 3), pMgmt->abyPSTxMap[wAID >> 3]);
146422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					return true;
146522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				}
146622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				else {
146722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					bRelayOnly = true;
146822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				}
146922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
147022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
147122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
147222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
147322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (bRelayOnly || bRelayAndForward) {
147422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		// relay this packet right now
147522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (bRelayAndForward)
147622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			iDANodeIndex = 0;
147722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
147822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if ((pDevice->uAssocCount > 1) && (iDANodeIndex >= 0)) {
147922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			ROUTEbRelay(pDevice, (unsigned char *)(skb->data + cbHeaderOffset), FrameSize, (unsigned int)iDANodeIndex);
148022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
148122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
148222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (bRelayOnly)
148322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			return false;
148422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
148522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	// none associate, don't forward
148622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (pDevice->uAssocCount == 0)
148722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		return false;
148822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
148922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	return true;
14905449c685a4b39534f18869a93896370224463715Forest Bond}
14915449c685a4b39534f18869a93896370224463715Forest Bond
1492