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"
5704d521970bd430b613a000a6b66c568d419b1ff3James A Shackleford#include "dpc.h"
585449c685a4b39534f18869a93896370224463715Forest Bond
595449c685a4b39534f18869a93896370224463715Forest Bond/*---------------------  Static Definitions -------------------------*/
605449c685a4b39534f18869a93896370224463715Forest Bond
615449c685a4b39534f18869a93896370224463715Forest Bond/*---------------------  Static Classes  ----------------------------*/
625449c685a4b39534f18869a93896370224463715Forest Bond
635449c685a4b39534f18869a93896370224463715Forest Bond/*---------------------  Static Variables  --------------------------*/
6404d521970bd430b613a000a6b66c568d419b1ff3James A Shacklefordstatic const unsigned char acbyRxRate[MAX_RATE] =
655449c685a4b39534f18869a93896370224463715Forest Bond{2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108};
665449c685a4b39534f18869a93896370224463715Forest Bond
675449c685a4b39534f18869a93896370224463715Forest Bond/*---------------------  Static Functions  --------------------------*/
685449c685a4b39534f18869a93896370224463715Forest Bond
695449c685a4b39534f18869a93896370224463715Forest Bond/*---------------------  Static Definitions -------------------------*/
705449c685a4b39534f18869a93896370224463715Forest Bond
715449c685a4b39534f18869a93896370224463715Forest Bond/*---------------------  Static Functions  --------------------------*/
725449c685a4b39534f18869a93896370224463715Forest Bond
733fc9b584c28095fe0d46cfb8bddafdf93947042eCharles Clémentstatic unsigned char s_byGetRateIdx(unsigned char byRate);
745449c685a4b39534f18869a93896370224463715Forest Bond
75fe4f34bde28f5a9f3793cced5b4029eda5b78be2Charles Clémentstatic void
76fe4f34bde28f5a9f3793cced5b4029eda5b78be2Charles Cléments_vGetDASA(unsigned char *pbyRxBufferAddr, unsigned int *pcbHeaderSize,
7722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	   PSEthernetHeader psEthHeader);
785449c685a4b39534f18869a93896370224463715Forest Bond
79fe4f34bde28f5a9f3793cced5b4029eda5b78be2Charles Clémentstatic void
80cf76dc4b85447e17678d61505eb1b92743c4b67bMalcolm Priestleys_vProcessRxMACHeader(struct vnt_private *pDevice, unsigned char *pbyRxBufferAddr,
8122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		      unsigned int cbPacketSize, bool bIsWEP, bool bExtIV,
8222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		      unsigned int *pcbHeadSize);
835449c685a4b39534f18869a93896370224463715Forest Bond
847b6a001313a9b11a1f0985de05fff514db41d72dCharles Clémentstatic bool s_bAPModeRxCtl(
85cf76dc4b85447e17678d61505eb1b92743c4b67bMalcolm Priestley	struct vnt_private *pDevice,
8622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyFrame,
8722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	int      iSANodeIndex
8822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches);
895449c685a4b39534f18869a93896370224463715Forest Bond
9022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perchesstatic bool s_bAPModeRxData(
91cf76dc4b85447e17678d61505eb1b92743c4b67bMalcolm Priestley	struct vnt_private *pDevice,
9222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	struct sk_buff *skb,
9322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned int FrameSize,
9422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned int cbHeaderOffset,
9522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	int      iSANodeIndex,
9622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	int      iDANodeIndex
9722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches);
985449c685a4b39534f18869a93896370224463715Forest Bond
997b6a001313a9b11a1f0985de05fff514db41d72dCharles Clémentstatic bool s_bHandleRxEncryption(
100cf76dc4b85447e17678d61505eb1b92743c4b67bMalcolm Priestley	struct vnt_private *pDevice,
10122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyFrame,
10222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned int FrameSize,
10322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyRsr,
10422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyNewRsr,
10522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PSKeyItem   *pKeyOut,
10622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	bool *pbExtIV,
10722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned short *pwRxTSC15_0,
10822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned long *pdwRxTSC47_16
10922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches);
1105449c685a4b39534f18869a93896370224463715Forest Bond
1117b6a001313a9b11a1f0985de05fff514db41d72dCharles Clémentstatic bool s_bHostWepRxEncryption(
1125449c685a4b39534f18869a93896370224463715Forest Bond
113cf76dc4b85447e17678d61505eb1b92743c4b67bMalcolm Priestley	struct vnt_private *pDevice,
11422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyFrame,
11522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned int FrameSize,
11622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyRsr,
11722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	bool bOnFly,
11822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PSKeyItem    pKey,
11922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyNewRsr,
12022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	bool *pbExtIV,
12122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned short *pwRxTSC15_0,
12222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned long *pdwRxTSC47_16
1235449c685a4b39534f18869a93896370224463715Forest Bond
12422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches);
1255449c685a4b39534f18869a93896370224463715Forest Bond
1265449c685a4b39534f18869a93896370224463715Forest Bond/*---------------------  Export Variables  --------------------------*/
1275449c685a4b39534f18869a93896370224463715Forest Bond
1285449c685a4b39534f18869a93896370224463715Forest Bond/*+
1295449c685a4b39534f18869a93896370224463715Forest Bond *
1305449c685a4b39534f18869a93896370224463715Forest Bond * Description:
1315449c685a4b39534f18869a93896370224463715Forest Bond *    Translate Rcv 802.11 header to 802.3 header with Rx buffer
1325449c685a4b39534f18869a93896370224463715Forest Bond *
1335449c685a4b39534f18869a93896370224463715Forest Bond * Parameters:
1345449c685a4b39534f18869a93896370224463715Forest Bond *  In:
1355449c685a4b39534f18869a93896370224463715Forest Bond *      pDevice
1365449c685a4b39534f18869a93896370224463715Forest Bond *      dwRxBufferAddr  - Address of Rcv Buffer
1375449c685a4b39534f18869a93896370224463715Forest Bond *      cbPacketSize    - Rcv Packet size
1385449c685a4b39534f18869a93896370224463715Forest Bond *      bIsWEP          - If Rcv with WEP
1395449c685a4b39534f18869a93896370224463715Forest Bond *  Out:
1405449c685a4b39534f18869a93896370224463715Forest Bond *      pcbHeaderSize   - 802.11 header size
1415449c685a4b39534f18869a93896370224463715Forest Bond *
1425449c685a4b39534f18869a93896370224463715Forest Bond * Return Value: None
1435449c685a4b39534f18869a93896370224463715Forest Bond *
14422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches -*/
145fe4f34bde28f5a9f3793cced5b4029eda5b78be2Charles Clémentstatic void
146cf76dc4b85447e17678d61505eb1b92743c4b67bMalcolm Priestleys_vProcessRxMACHeader(struct vnt_private *pDevice,
147cf76dc4b85447e17678d61505eb1b92743c4b67bMalcolm Priestley		      unsigned char *pbyRxBufferAddr,
14822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		      unsigned int cbPacketSize, bool bIsWEP, bool bExtIV,
14922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		      unsigned int *pcbHeadSize)
1505449c685a4b39534f18869a93896370224463715Forest Bond{
15122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyRxBuffer;
15222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned int cbHeaderSize = 0;
15322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned short *pwType;
15422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PS802_11Header  pMACHeader;
15522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	int             ii;
15622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
15722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	pMACHeader = (PS802_11Header) (pbyRxBufferAddr + cbHeaderSize);
15822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
15922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	s_vGetDASA((unsigned char *)pMACHeader, &cbHeaderSize, &pDevice->sRxEthHeader);
16022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
16122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (bIsWEP) {
16222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (bExtIV) {
16322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// strip IV&ExtIV , add 8 byte
16422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			cbHeaderSize += (WLAN_HDR_ADDR3_LEN + 8);
16522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		} else {
16622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// strip IV , add 4 byte
16722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			cbHeaderSize += (WLAN_HDR_ADDR3_LEN + 4);
16822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
1695e0cc8a231be82b0ec44cdf2a406b1a97dd3c971Joe Perches	} else {
17022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		cbHeaderSize += WLAN_HDR_ADDR3_LEN;
17188cc85075d1e53731e90fec8670cd9ccafcbe9aaTeodora Baluta	}
17222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
17322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	pbyRxBuffer = (unsigned char *)(pbyRxBufferAddr + cbHeaderSize);
1748329419a29d15abebc3aefb57f4c6bfdbded7d89Joe Perches	if (ether_addr_equal(pbyRxBuffer, pDevice->abySNAP_Bridgetunnel)) {
17522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		cbHeaderSize += 6;
1768329419a29d15abebc3aefb57f4c6bfdbded7d89Joe Perches	} else if (ether_addr_equal(pbyRxBuffer, pDevice->abySNAP_RFC1042)) {
17722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		cbHeaderSize += 6;
17822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		pwType = (unsigned short *)(pbyRxBufferAddr + cbHeaderSize);
17922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if ((*pwType != TYPE_PKT_IPX) && (*pwType != cpu_to_le16(0xF380))) {
1805e0cc8a231be82b0ec44cdf2a406b1a97dd3c971Joe Perches		} else {
18122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			cbHeaderSize -= 8;
18222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			pwType = (unsigned short *)(pbyRxBufferAddr + cbHeaderSize);
18322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			if (bIsWEP) {
184bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez				if (bExtIV)
18522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					*pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 8);    // 8 is IV&ExtIV
186bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez				else
18722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					*pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 4);    // 4 is IV
188bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez
1895e0cc8a231be82b0ec44cdf2a406b1a97dd3c971Joe Perches			} else {
19022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				*pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN);
19122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
19222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
1935e0cc8a231be82b0ec44cdf2a406b1a97dd3c971Joe Perches	} else {
19422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		cbHeaderSize -= 2;
19522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		pwType = (unsigned short *)(pbyRxBufferAddr + cbHeaderSize);
19622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (bIsWEP) {
197bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez			if (bExtIV)
19822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				*pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 8);    // 8 is IV&ExtIV
199bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez			else
20022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				*pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 4);    // 4 is IV
201bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez
2025e0cc8a231be82b0ec44cdf2a406b1a97dd3c971Joe Perches		} else {
20322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			*pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN);
20422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
20522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
20622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
20722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	cbHeaderSize -= (ETH_ALEN * 2);
20822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	pbyRxBuffer = (unsigned char *)(pbyRxBufferAddr + cbHeaderSize);
20922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	for (ii = 0; ii < ETH_ALEN; ii++)
21022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		*pbyRxBuffer++ = pDevice->sRxEthHeader.abyDstAddr[ii];
21122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	for (ii = 0; ii < ETH_ALEN; ii++)
21222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		*pbyRxBuffer++ = pDevice->sRxEthHeader.abySrcAddr[ii];
21322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
21422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	*pcbHeadSize = cbHeaderSize;
2155449c685a4b39534f18869a93896370224463715Forest Bond}
2165449c685a4b39534f18869a93896370224463715Forest Bond
21722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perchesstatic unsigned char s_byGetRateIdx(unsigned char byRate)
2185449c685a4b39534f18869a93896370224463715Forest Bond{
21922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char byRateIdx;
2205449c685a4b39534f18869a93896370224463715Forest Bond
22122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	for (byRateIdx = 0; byRateIdx < MAX_RATE; byRateIdx++) {
22222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (acbyRxRate[byRateIdx % MAX_RATE] == byRate)
22322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			return byRateIdx;
22422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
225bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez
22622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	return 0;
2275449c685a4b39534f18869a93896370224463715Forest Bond}
2285449c685a4b39534f18869a93896370224463715Forest Bond
229fe4f34bde28f5a9f3793cced5b4029eda5b78be2Charles Clémentstatic void
230fe4f34bde28f5a9f3793cced5b4029eda5b78be2Charles Cléments_vGetDASA(unsigned char *pbyRxBufferAddr, unsigned int *pcbHeaderSize,
23122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	   PSEthernetHeader psEthHeader)
2325449c685a4b39534f18869a93896370224463715Forest Bond{
23322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned int cbHeaderSize = 0;
23422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PS802_11Header  pMACHeader;
23522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	int             ii;
23622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
23722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	pMACHeader = (PS802_11Header) (pbyRxBufferAddr + cbHeaderSize);
23822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
23922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if ((pMACHeader->wFrameCtl & FC_TODS) == 0) {
24022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (pMACHeader->wFrameCtl & FC_FROMDS) {
24122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			for (ii = 0; ii < ETH_ALEN; ii++) {
24222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				psEthHeader->abyDstAddr[ii] = pMACHeader->abyAddr1[ii];
24322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				psEthHeader->abySrcAddr[ii] = pMACHeader->abyAddr3[ii];
24422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
2455e0cc8a231be82b0ec44cdf2a406b1a97dd3c971Joe Perches		} else {
24622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// IBSS mode
24722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			for (ii = 0; ii < ETH_ALEN; ii++) {
24822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				psEthHeader->abyDstAddr[ii] = pMACHeader->abyAddr1[ii];
24922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				psEthHeader->abySrcAddr[ii] = pMACHeader->abyAddr2[ii];
25022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
25122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
2525e0cc8a231be82b0ec44cdf2a406b1a97dd3c971Joe Perches	} else {
25322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		// Is AP mode..
25422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (pMACHeader->wFrameCtl & FC_FROMDS) {
25522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			for (ii = 0; ii < ETH_ALEN; ii++) {
25622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				psEthHeader->abyDstAddr[ii] = pMACHeader->abyAddr3[ii];
25722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				psEthHeader->abySrcAddr[ii] = pMACHeader->abyAddr4[ii];
25822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				cbHeaderSize += 6;
25922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
2605e0cc8a231be82b0ec44cdf2a406b1a97dd3c971Joe Perches		} else {
26122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			for (ii = 0; ii < ETH_ALEN; ii++) {
26222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				psEthHeader->abyDstAddr[ii] = pMACHeader->abyAddr3[ii];
26322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				psEthHeader->abySrcAddr[ii] = pMACHeader->abyAddr2[ii];
26422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
26522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
26688cc85075d1e53731e90fec8670cd9ccafcbe9aaTeodora Baluta	}
26722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	*pcbHeaderSize = cbHeaderSize;
2685449c685a4b39534f18869a93896370224463715Forest Bond}
2695449c685a4b39534f18869a93896370224463715Forest Bond
2707b6a001313a9b11a1f0985de05fff514db41d72dCharles Clémentbool
27122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perchesdevice_receive_frame(
272cf76dc4b85447e17678d61505eb1b92743c4b67bMalcolm Priestley	struct vnt_private *pDevice,
27322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PSRxDesc pCurrRD
27422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches)
2755449c685a4b39534f18869a93896370224463715Forest Bond{
27622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PDEVICE_RD_INFO  pRDInfo = pCurrRD->pRDInfo;
27722981e0e5ab3aedfb46698ed7c12c7b944781bd3Tobias Klauser	struct net_device_stats *pStats = &pDevice->dev->stats;
27822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	struct sk_buff *skb;
27922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PSMgmtObject    pMgmt = pDevice->pMgmt;
28022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PSRxMgmtPacket  pRxPacket = &(pDevice->pMgmt->sRxPacket);
28122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PS802_11Header  p802_11Header;
28222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyRsr;
28322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyNewRsr;
28422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyRSSI;
2850fc2a76eef05ee1aa82b3d9bf34eea2b50f5e1baMalcolm Priestley	__le64 *pqwTSFTime;
28622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned short *pwFrameSize;
28722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyFrame;
28822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	bool bDeFragRx = false;
28922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	bool bIsWEP = false;
29022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned int cbHeaderOffset;
29122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned int FrameSize;
29222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned short wEtherType = 0;
29322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	int             iSANodeIndex = -1;
29422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	int             iDANodeIndex = -1;
29522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned int ii;
29622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned int cbIVOffset;
29722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	bool bExtIV = false;
29822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyRxSts;
29922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyRxRate;
30022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbySQ;
30122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned int cbHeaderSize;
30222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PSKeyItem       pKey = NULL;
30322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned short wRxTSC15_0 = 0;
30422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned long dwRxTSC47_16 = 0;
30522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	SKeyItem        STempKey;
30622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	// 802.11h RPI
30722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned long dwDuration = 0;
30822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	long            ldBm = 0;
30922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	long            ldBmThreshold = 0;
31022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PS802_11Header pMACHeader;
31122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	bool bRxeapol_key = false;
31222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
31322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	skb = pRDInfo->skb;
3145449c685a4b39534f18869a93896370224463715Forest Bond
3155449c685a4b39534f18869a93896370224463715Forest Bond	pci_unmap_single(pDevice->pcid, pRDInfo->skb_dma,
31622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			 pDevice->rx_buf_sz, PCI_DMA_FROMDEVICE);
3179e9df6704c1929ffd76e73f4740a468e00c44c11Malcolm Priestley
31822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	pwFrameSize = (unsigned short *)(skb->data + 2);
31922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	FrameSize = cpu_to_le16(pCurrRD->m_rd1RD1.wReqCount) - cpu_to_le16(pCurrRD->m_rd0RD0.wResCount);
32022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
32122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	// Max: 2312Payload + 30HD +4CRC + 2Padding + 4Len + 8TSF + 4RSR
32222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	// Min (ACK): 10HD +4CRC + 2Padding + 4Len + 8TSF + 4RSR
32322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if ((FrameSize > 2364) || (FrameSize <= 32)) {
32422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		// Frame Size error drop this packet.
32548caf5a060491edb2e1793539dad72e70c54c869Joe Perches		pr_debug("---------- WRONG Length 1\n");
32622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		return false;
32722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
32822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
32922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	pbyRxSts = (unsigned char *)(skb->data);
33022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	pbyRxRate = (unsigned char *)(skb->data + 1);
33122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	pbyRsr = (unsigned char *)(skb->data + FrameSize - 1);
33222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	pbyRSSI = (unsigned char *)(skb->data + FrameSize - 2);
33322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	pbyNewRsr = (unsigned char *)(skb->data + FrameSize - 3);
33422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	pbySQ = (unsigned char *)(skb->data + FrameSize - 4);
3350fc2a76eef05ee1aa82b3d9bf34eea2b50f5e1baMalcolm Priestley	pqwTSFTime = (__le64 *)(skb->data + FrameSize - 12);
33622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	pbyFrame = (unsigned char *)(skb->data + 4);
33722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
33822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	// get packet size
33922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	FrameSize = cpu_to_le16(*pwFrameSize);
34022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
34122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if ((FrameSize > 2346)|(FrameSize < 14)) { // Max: 2312Payload + 30HD +4CRC
34222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		// Min: 14 bytes ACK
34348caf5a060491edb2e1793539dad72e70c54c869Joe Perches		pr_debug("---------- WRONG Length 2\n");
34422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		return false;
34522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
3469e9df6704c1929ffd76e73f4740a468e00c44c11Malcolm Priestley
3475449c685a4b39534f18869a93896370224463715Forest Bond	// update receive statistic counter
34822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	STAvUpdateRDStatCounter(&pDevice->scStatistic,
34922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				*pbyRsr,
35022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				*pbyNewRsr,
35122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				*pbyRxRate,
35222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				pbyFrame,
35322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				FrameSize);
3545449c685a4b39534f18869a93896370224463715Forest Bond
35522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	pMACHeader = (PS802_11Header)((unsigned char *)(skb->data) + 8);
3569e9df6704c1929ffd76e73f4740a468e00c44c11Malcolm Priestley
3571208f14a37fde2669b86bf1b1cd1122ad2ba3579Teodora Baluta	if (pDevice->bMeasureInProgress) {
358bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez		if ((*pbyRsr & RSR_CRCOK) != 0)
35922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			pDevice->byBasicMap |= 0x01;
360bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez
36122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		dwDuration = (FrameSize << 4);
36222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		dwDuration /= acbyRxRate[*pbyRxRate%MAX_RATE];
36322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (*pbyRxRate <= RATE_11M) {
36422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			if (*pbyRxSts & 0x01) {
36522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				// long preamble
36622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				dwDuration += 192;
36722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			} else {
36822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				// short preamble
36922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				dwDuration += 96;
37022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
37122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		} else {
37222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			dwDuration += 16;
37322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
37422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		RFvRSSITodBm(pDevice, *pbyRSSI, &ldBm);
37522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		ldBmThreshold = -57;
37622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		for (ii = 7; ii > 0;) {
377bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez			if (ldBm > ldBmThreshold)
37822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				break;
379bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez
38022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			ldBmThreshold -= 5;
38122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			ii--;
38222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
38322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		pDevice->dwRPIs[ii] += dwDuration;
38422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		return false;
38522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
38622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
38722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (!is_multicast_ether_addr(pbyFrame)) {
38822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (WCTLbIsDuplicate(&(pDevice->sDupRxCache), (PS802_11Header)(skb->data + 4))) {
38922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			pDevice->s802_11Counter.FrameDuplicateCount++;
39022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			return false;
39122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
39222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
39322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
39422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	// Use for TKIP MIC
39522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	s_vGetDASA(skb->data+4, &cbHeaderSize, &pDevice->sRxEthHeader);
39622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
39722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	// filter packet send from myself
3988329419a29d15abebc3aefb57f4c6bfdbded7d89Joe Perches	if (ether_addr_equal(pDevice->sRxEthHeader.abySrcAddr,
3998329419a29d15abebc3aefb57f4c6bfdbded7d89Joe Perches			     pDevice->abyCurrentNetAddr))
40022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		return false;
40122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
40222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) || (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) {
40322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (IS_CTL_PSPOLL(pbyFrame) || !IS_TYPE_CONTROL(pbyFrame)) {
40422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			p802_11Header = (PS802_11Header)(pbyFrame);
40522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// get SA NodeIndex
40622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			if (BSSDBbIsSTAInNodeDB(pMgmt, (unsigned char *)(p802_11Header->abyAddr2), &iSANodeIndex)) {
40722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				pMgmt->sNodeDBTable[iSANodeIndex].ulLastRxJiffer = jiffies;
40822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				pMgmt->sNodeDBTable[iSANodeIndex].uInActiveCount = 0;
40922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
41022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
41122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
41222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
41322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
414bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez		if (s_bAPModeRxCtl(pDevice, pbyFrame, iSANodeIndex))
41522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			return false;
41622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
41722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
41822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (IS_FC_WEP(pbyFrame)) {
41922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		bool bRxDecryOK = false;
42022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
42148caf5a060491edb2e1793539dad72e70c54c869Joe Perches		pr_debug("rx WEP pkt\n");
42222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		bIsWEP = true;
42322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if ((pDevice->bEnableHostWEP) && (iSANodeIndex >= 0)) {
42422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			pKey = &STempKey;
42522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			pKey->byCipherSuite = pMgmt->sNodeDBTable[iSANodeIndex].byCipherSuite;
42622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			pKey->dwKeyIndex = pMgmt->sNodeDBTable[iSANodeIndex].dwKeyIndex;
42722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			pKey->uKeyLength = pMgmt->sNodeDBTable[iSANodeIndex].uWepKeyLength;
42822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			pKey->dwTSC47_16 = pMgmt->sNodeDBTable[iSANodeIndex].dwTSC47_16;
42922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			pKey->wTSC15_0 = pMgmt->sNodeDBTable[iSANodeIndex].wTSC15_0;
43022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			memcpy(pKey->abyKey,
43122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			       &pMgmt->sNodeDBTable[iSANodeIndex].abyWepKey[0],
43222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			       pKey->uKeyLength
43322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches);
43422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
43522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			bRxDecryOK = s_bHostWepRxEncryption(pDevice,
43622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							    pbyFrame,
43722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							    FrameSize,
43822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							    pbyRsr,
43922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							    pMgmt->sNodeDBTable[iSANodeIndex].bOnFly,
44022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							    pKey,
44122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							    pbyNewRsr,
44222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							    &bExtIV,
44322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							    &wRxTSC15_0,
44422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							    &dwRxTSC47_16);
44522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		} else {
44622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			bRxDecryOK = s_bHandleRxEncryption(pDevice,
44722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							   pbyFrame,
44822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							   FrameSize,
44922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							   pbyRsr,
45022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							   pbyNewRsr,
45122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							   &pKey,
45222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							   &bExtIV,
45322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							   &wRxTSC15_0,
45422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							   &dwRxTSC47_16);
45522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
45622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
45722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (bRxDecryOK) {
45822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			if ((*pbyNewRsr & NEWRSR_DECRYPTOK) == 0) {
45948caf5a060491edb2e1793539dad72e70c54c869Joe Perches				pr_debug("ICV Fail\n");
46022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				if ((pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPA) ||
46122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				    (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) ||
46222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				    (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) ||
46322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				    (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPA2) ||
46422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				    (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) {
465bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez					if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_TKIP))
46622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						pDevice->s802_11Counter.TKIPICVErrors++;
467bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez					else if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_CCMP))
46822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						pDevice->s802_11Counter.CCMPDecryptErrors++;
46922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				}
47022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				return false;
47122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
47222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		} else {
47348caf5a060491edb2e1793539dad72e70c54c869Joe Perches			pr_debug("WEP Func Fail\n");
47422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			return false;
47522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
47622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_CCMP))
47722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			FrameSize -= 8;         // Message Integrity Code
47822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		else
47922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			FrameSize -= 4;         // 4 is ICV
48022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
48122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
48222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	//
48322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	// RX OK
48422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	//
48522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	//remove the CRC length
48622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	FrameSize -= ETH_FCS_LEN;
48722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
48822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if ((!(*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI))) && // unicast address
48922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	    (IS_FRAGMENT_PKT((skb->data+4)))
49022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches) {
49122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		// defragment
49222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		bDeFragRx = WCTLbHandleFragment(pDevice, (PS802_11Header)(skb->data+4), FrameSize, bIsWEP, bExtIV);
49322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		pDevice->s802_11Counter.ReceivedFragmentCount++;
49422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (bDeFragRx) {
49522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// defrag complete
49622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			skb = pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].skb;
49722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			FrameSize = pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength;
49822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
4995e0cc8a231be82b0ec44cdf2a406b1a97dd3c971Joe Perches		} else {
50022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			return false;
50122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
50222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
5035449c685a4b39534f18869a93896370224463715Forest Bond
5045449c685a4b39534f18869a93896370224463715Forest Bond// Management & Control frame Handle
50522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if ((IS_TYPE_DATA((skb->data+4))) == false) {
50622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		// Handle Control & Manage Frame
50722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
50822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (IS_TYPE_MGMT((skb->data+4))) {
50922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			unsigned char *pbyData1;
51022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			unsigned char *pbyData2;
51122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
51222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			pRxPacket->p80211Header = (PUWLAN_80211HDR)(skb->data+4);
51322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			pRxPacket->cbMPDULen = FrameSize;
51422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			pRxPacket->uRSSI = *pbyRSSI;
51522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			pRxPacket->bySQ = *pbySQ;
5160fc2a76eef05ee1aa82b3d9bf34eea2b50f5e1baMalcolm Priestley			pRxPacket->qwLocalTSF = le64_to_cpu(*pqwTSFTime);
51722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			if (bIsWEP) {
51822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				// strip IV
51922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				pbyData1 = WLAN_HDR_A3_DATA_PTR(skb->data+4);
52022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				pbyData2 = WLAN_HDR_A3_DATA_PTR(skb->data+4) + 4;
52122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				for (ii = 0; ii < (FrameSize - 4); ii++) {
52222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					*pbyData1 = *pbyData2;
52322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					pbyData1++;
52422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					pbyData2++;
52522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				}
52622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
52722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			pRxPacket->byRxRate = s_byGetRateIdx(*pbyRxRate);
52822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			pRxPacket->byRxChannel = (*pbyRxSts) >> 2;
5295449c685a4b39534f18869a93896370224463715Forest Bond
53022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			vMgrRxManagePacket((void *)pDevice, pDevice->pMgmt, pRxPacket);
5319a802f2edc5bfc3d19ccb094182e60fdd36ee6ecMalcolm Priestley
53222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// hostap Deamon handle 802.11 management
53322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			if (pDevice->bEnableHostapd) {
53422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				skb->dev = pDevice->apdev;
53522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				skb->data += 4;
53622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				skb->tail += 4;
53722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				skb_put(skb, FrameSize);
53822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				skb_reset_mac_header(skb);
53922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				skb->pkt_type = PACKET_OTHERHOST;
54022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				skb->protocol = htons(ETH_P_802_2);
54122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				memset(skb->cb, 0, sizeof(skb->cb));
54222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				netif_rx(skb);
54322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				return true;
54422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
54588cc85075d1e53731e90fec8670cd9ccafcbe9aaTeodora Baluta		}
5464e8a7e5fc29697f881f5c358f84df52914908703Guido Martínez
54722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		return false;
5485e0cc8a231be82b0ec44cdf2a406b1a97dd3c971Joe Perches	} else {
54922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
55022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			//In AP mode, hw only check addr1(BSSID or RA) if equal to local MAC.
55122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			if (!(*pbyRsr & RSR_BSSIDOK)) {
55222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				if (bDeFragRx) {
55322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
55448caf5a060491edb2e1793539dad72e70c54c869Joe Perches						pr_err("%s: can not alloc more frag bufs\n",
55548caf5a060491edb2e1793539dad72e70c54c869Joe Perches						       pDevice->dev->name);
55622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					}
55722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				}
55822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				return false;
55922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
5605e0cc8a231be82b0ec44cdf2a406b1a97dd3c971Joe Perches		} else {
56122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// discard DATA packet while not associate || BSSID error
5621208f14a37fde2669b86bf1b1cd1122ad2ba3579Teodora Baluta			if (!pDevice->bLinkPass || !(*pbyRsr & RSR_BSSIDOK)) {
56322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				if (bDeFragRx) {
56422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
56548caf5a060491edb2e1793539dad72e70c54c869Joe Perches						pr_err("%s: can not alloc more frag bufs\n",
56648caf5a060491edb2e1793539dad72e70c54c869Joe Perches						       pDevice->dev->name);
56722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					}
56822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				}
56922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				return false;
57022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
57122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			//mike add:station mode check eapol-key challenge--->
57222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			{
57322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				unsigned char Protocol_Version;    //802.1x Authentication
57422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				unsigned char Packet_Type;           //802.1x Authentication
5756b7112719fd48c29f35333ef152a5a450f01dc83Guillaume Clement
57622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				if (bIsWEP)
57722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					cbIVOffset = 8;
57822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				else
57922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					cbIVOffset = 0;
58022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				wEtherType = (skb->data[cbIVOffset + 8 + 24 + 6] << 8) |
58122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					skb->data[cbIVOffset + 8 + 24 + 6 + 1];
58222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				Protocol_Version = skb->data[cbIVOffset + 8 + 24 + 6 + 1 + 1];
58322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				Packet_Type = skb->data[cbIVOffset + 8 + 24 + 6 + 1 + 1 + 1];
58422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				if (wEtherType == ETH_P_PAE) {         //Protocol Type in LLC-Header
58522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					if (((Protocol_Version == 1) || (Protocol_Version == 2)) &&
58622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					    (Packet_Type == 3)) {  //802.1x OR eapol-key challenge frame receive
58722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						bRxeapol_key = true;
58822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					}
58922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				}
59022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
59122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			//mike add:station mode check eapol-key challenge<---
59222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
59322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
5945449c685a4b39534f18869a93896370224463715Forest Bond
5955449c685a4b39534f18869a93896370224463715Forest Bond// Data frame Handle
5965449c685a4b39534f18869a93896370224463715Forest Bond
59722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (pDevice->bEnablePSMode) {
5984e8a7e5fc29697f881f5c358f84df52914908703Guido Martínez		if (!IS_FC_MOREDATA((skb->data+4))) {
5994e8a7e5fc29697f881f5c358f84df52914908703Guido Martínez			if (pDevice->pMgmt->bInTIMWake == true)
60022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				pDevice->pMgmt->bInTIMWake = false;
60122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
60222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
60322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
60422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	// Now it only supports 802.11g Infrastructure Mode, and support rate must up to 54 Mbps
60522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (pDevice->bDiversityEnable && (FrameSize > 50) &&
606a9873673484b5aa4346111d021c83a2f11d62eb5Malcolm Priestley	    (pDevice->op_mode == NL80211_IFTYPE_STATION) &&
6071208f14a37fde2669b86bf1b1cd1122ad2ba3579Teodora Baluta	    pDevice->bLinkPass) {
6085449c685a4b39534f18869a93896370224463715Forest Bond		BBvAntennaDiversity(pDevice, s_byGetRateIdx(*pbyRxRate), 0);
60922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
6105449c685a4b39534f18869a93896370224463715Forest Bond
611bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez	if (pDevice->byLocalID != REV_ID_VT3253_B1)
61222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		pDevice->uCurrRSSI = *pbyRSSI;
613bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez
61422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	pDevice->byCurrSQ = *pbySQ;
61522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
61622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if ((*pbyRSSI != 0) &&
61722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	    (pMgmt->pCurrBSS != NULL)) {
61822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		RFvRSSITodBm(pDevice, *pbyRSSI, &ldBm);
61922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		// Monitor if RSSI is too strong.
62022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		pMgmt->pCurrBSS->byRSSIStatCnt++;
62122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		pMgmt->pCurrBSS->byRSSIStatCnt %= RSSI_STAT_COUNT;
62222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		pMgmt->pCurrBSS->ldBmAverage[pMgmt->pCurrBSS->byRSSIStatCnt] = ldBm;
623bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez		for (ii = 0; ii < RSSI_STAT_COUNT; ii++)
624bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez			if (pMgmt->pCurrBSS->ldBmAverage[ii] != 0)
62522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				pMgmt->pCurrBSS->ldBmMAX = max(pMgmt->pCurrBSS->ldBmAverage[ii], ldBm);
626bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez
62722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
62822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
62922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	// -----------------------------------------------
63022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
6311208f14a37fde2669b86bf1b1cd1122ad2ba3579Teodora Baluta	if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && pDevice->bEnable8021x) {
63222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		unsigned char abyMacHdr[24];
63322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
63422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		// Only 802.1x packet incoming allowed
63522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (bIsWEP)
63622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			cbIVOffset = 8;
63722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		else
63822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			cbIVOffset = 0;
63922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		wEtherType = (skb->data[cbIVOffset + 4 + 24 + 6] << 8) |
64022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			skb->data[cbIVOffset + 4 + 24 + 6 + 1];
64122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
64248caf5a060491edb2e1793539dad72e70c54c869Joe Perches		pr_debug("wEtherType = %04x\n", wEtherType);
64322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (wEtherType == ETH_P_PAE) {
64422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			skb->dev = pDevice->apdev;
64522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
6461208f14a37fde2669b86bf1b1cd1122ad2ba3579Teodora Baluta			if (bIsWEP) {
64722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				// strip IV header(8)
64822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				memcpy(&abyMacHdr[0], (skb->data + 4), 24);
64922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				memcpy((skb->data + 4 + cbIVOffset), &abyMacHdr[0], 24);
65022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
65122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			skb->data +=  (cbIVOffset + 4);
65222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			skb->tail +=  (cbIVOffset + 4);
65322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			skb_put(skb, FrameSize);
65422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			skb_reset_mac_header(skb);
65522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
65622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			skb->pkt_type = PACKET_OTHERHOST;
65722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			skb->protocol = htons(ETH_P_802_2);
65822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			memset(skb->cb, 0, sizeof(skb->cb));
65922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			netif_rx(skb);
66022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			return true;
66122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
66222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
66322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		// check if 802.1x authorized
66422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (!(pMgmt->sNodeDBTable[iSANodeIndex].dwFlags & WLAN_STA_AUTHORIZED))
66522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			return false;
66622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
66722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
66822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_TKIP)) {
669bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez		if (bIsWEP)
67022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			FrameSize -= 8;  //MIC
67122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
67222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
67322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	//--------------------------------------------------------------------------------
67422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	// Soft MIC
67522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_TKIP)) {
67622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (bIsWEP) {
67735a9562b02441dee7e0a822f5273f84afb2f150bMalcolm Priestley			__le32 *pdwMIC_L;
67835a9562b02441dee7e0a822f5273f84afb2f150bMalcolm Priestley			__le32 *pdwMIC_R;
67935a9562b02441dee7e0a822f5273f84afb2f150bMalcolm Priestley			__le32 dwMIC_Priority;
68035a9562b02441dee7e0a822f5273f84afb2f150bMalcolm Priestley			__le32 dwMICKey0 = 0, dwMICKey1 = 0;
681d0daef301d8451eaf75ece9636d2cfa6180c34deMalcolm Priestley			u32 dwLocalMIC_L = 0;
682d0daef301d8451eaf75ece9636d2cfa6180c34deMalcolm Priestley			u32 dwLocalMIC_R = 0;
68322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			viawget_wpa_header *wpahdr;
68422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
68522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
68635a9562b02441dee7e0a822f5273f84afb2f150bMalcolm Priestley				dwMICKey0 = cpu_to_le32(*(u32 *)(&pKey->abyKey[24]));
68735a9562b02441dee7e0a822f5273f84afb2f150bMalcolm Priestley				dwMICKey1 = cpu_to_le32(*(u32 *)(&pKey->abyKey[28]));
6885e0cc8a231be82b0ec44cdf2a406b1a97dd3c971Joe Perches			} else {
68922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				if (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
69035a9562b02441dee7e0a822f5273f84afb2f150bMalcolm Priestley					dwMICKey0 = cpu_to_le32(*(u32 *)(&pKey->abyKey[16]));
69135a9562b02441dee7e0a822f5273f84afb2f150bMalcolm Priestley					dwMICKey1 = cpu_to_le32(*(u32 *)(&pKey->abyKey[20]));
69222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				} else if ((pKey->dwKeyIndex & BIT28) == 0) {
69335a9562b02441dee7e0a822f5273f84afb2f150bMalcolm Priestley					dwMICKey0 = cpu_to_le32(*(u32 *)(&pKey->abyKey[16]));
69435a9562b02441dee7e0a822f5273f84afb2f150bMalcolm Priestley					dwMICKey1 = cpu_to_le32(*(u32 *)(&pKey->abyKey[20]));
69522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				} else {
69635a9562b02441dee7e0a822f5273f84afb2f150bMalcolm Priestley					dwMICKey0 = cpu_to_le32(*(u32 *)(&pKey->abyKey[24]));
69735a9562b02441dee7e0a822f5273f84afb2f150bMalcolm Priestley					dwMICKey1 = cpu_to_le32(*(u32 *)(&pKey->abyKey[28]));
69822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				}
69922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
70022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
70122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			MIC_vInit(dwMICKey0, dwMICKey1);
70222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			MIC_vAppend((unsigned char *)&(pDevice->sRxEthHeader.abyDstAddr[0]), 12);
70322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			dwMIC_Priority = 0;
70422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			MIC_vAppend((unsigned char *)&dwMIC_Priority, 4);
70522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// 4 is Rcv buffer header, 24 is MAC Header, and 8 is IV and Ext IV.
70622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			MIC_vAppend((unsigned char *)(skb->data + 4 + WLAN_HDR_ADDR3_LEN + 8),
70722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				    FrameSize - WLAN_HDR_ADDR3_LEN - 8);
70822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			MIC_vGetMIC(&dwLocalMIC_L, &dwLocalMIC_R);
70922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			MIC_vUnInit();
71022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
71135a9562b02441dee7e0a822f5273f84afb2f150bMalcolm Priestley			pdwMIC_L = (__le32 *)(skb->data + 4 + FrameSize);
71235a9562b02441dee7e0a822f5273f84afb2f150bMalcolm Priestley			pdwMIC_R = (__le32 *)(skb->data + 4 + FrameSize + 4);
71322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
71435a9562b02441dee7e0a822f5273f84afb2f150bMalcolm Priestley			if ((le32_to_cpu(*pdwMIC_L) != dwLocalMIC_L) ||
71535a9562b02441dee7e0a822f5273f84afb2f150bMalcolm Priestley			    (le32_to_cpu(*pdwMIC_R) != dwLocalMIC_R) ||
7161208f14a37fde2669b86bf1b1cd1122ad2ba3579Teodora Baluta			    pDevice->bRxMICFail) {
71748caf5a060491edb2e1793539dad72e70c54c869Joe Perches				pr_debug("MIC comparison is fail!\n");
71822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				pDevice->bRxMICFail = false;
71922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				pDevice->s802_11Counter.TKIPLocalMICFailures++;
72022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				if (bDeFragRx) {
72122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
72248caf5a060491edb2e1793539dad72e70c54c869Joe Perches						pr_err("%s: can not alloc more frag bufs\n",
72348caf5a060491edb2e1793539dad72e70c54c869Joe Perches						       pDevice->dev->name);
72422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					}
72522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				}
72622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				//2008-0409-07, <Add> by Einsn Liu
72722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
7285449c685a4b39534f18869a93896370224463715Forest Bond				//send event to wpa_supplicant
729612822f5dd1638de442cf50eb9da54632fba0e66Jim Lieb				{
7305449c685a4b39534f18869a93896370224463715Forest Bond					union iwreq_data wrqu;
7315449c685a4b39534f18869a93896370224463715Forest Bond					struct iw_michaelmicfailure ev;
7325449c685a4b39534f18869a93896370224463715Forest Bond					int keyidx = pbyFrame[cbHeaderSize+3] >> 6; //top two-bits
7336b7112719fd48c29f35333ef152a5a450f01dc83Guillaume Clement
7345449c685a4b39534f18869a93896370224463715Forest Bond					memset(&ev, 0, sizeof(ev));
7355449c685a4b39534f18869a93896370224463715Forest Bond					ev.flags = keyidx & IW_MICFAILURE_KEY_ID;
7365449c685a4b39534f18869a93896370224463715Forest Bond					if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
73722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					    (pMgmt->eCurrState == WMAC_STATE_ASSOC) &&
73822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					    (*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI)) == 0) {
7395449c685a4b39534f18869a93896370224463715Forest Bond						ev.flags |= IW_MICFAILURE_PAIRWISE;
7405449c685a4b39534f18869a93896370224463715Forest Bond					} else {
7415449c685a4b39534f18869a93896370224463715Forest Bond						ev.flags |= IW_MICFAILURE_GROUP;
7425449c685a4b39534f18869a93896370224463715Forest Bond					}
7435449c685a4b39534f18869a93896370224463715Forest Bond
7445449c685a4b39534f18869a93896370224463715Forest Bond					ev.src_addr.sa_family = ARPHRD_ETHER;
7455449c685a4b39534f18869a93896370224463715Forest Bond					memcpy(ev.src_addr.sa_data, pMACHeader->abyAddr2, ETH_ALEN);
7465449c685a4b39534f18869a93896370224463715Forest Bond					memset(&wrqu, 0, sizeof(wrqu));
7475449c685a4b39534f18869a93896370224463715Forest Bond					wrqu.data.length = sizeof(ev);
7485449c685a4b39534f18869a93896370224463715Forest Bond					wireless_send_event(pDevice->dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&ev);
7495449c685a4b39534f18869a93896370224463715Forest Bond
7505449c685a4b39534f18869a93896370224463715Forest Bond				}
75122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches#endif
75222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
75322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) {
75422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					wpahdr = (viawget_wpa_header *)pDevice->skb->data;
75522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					if ((pDevice->pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
75622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					    (pDevice->pMgmt->eCurrState == WMAC_STATE_ASSOC) &&
75722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					    (*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI)) == 0) {
75822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						wpahdr->type = VIAWGET_PTK_MIC_MSG;
75922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					} else {
76022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						wpahdr->type = VIAWGET_GTK_MIC_MSG;
76122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					}
76222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					wpahdr->resp_ie_len = 0;
76322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					wpahdr->req_ie_len = 0;
76422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					skb_put(pDevice->skb, sizeof(viawget_wpa_header));
76522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					pDevice->skb->dev = pDevice->wpadev;
76622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					skb_reset_mac_header(pDevice->skb);
76722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					pDevice->skb->pkt_type = PACKET_HOST;
76822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					pDevice->skb->protocol = htons(ETH_P_802_2);
76922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
77022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					netif_rx(pDevice->skb);
77122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
77222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				}
77322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
77422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				return false;
77522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
77622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
77722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
77822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	} //---end of SOFT MIC-----------------------------------------------------------------------
77922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
78022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	// ++++++++++ Reply Counter Check +++++++++++++
78122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
78222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if ((pKey != NULL) && ((pKey->byCipherSuite == KEY_CTL_TKIP) ||
78322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			       (pKey->byCipherSuite == KEY_CTL_CCMP))) {
78422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (bIsWEP) {
78522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			unsigned short wLocalTSC15_0 = 0;
78622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			unsigned long dwLocalTSC47_16 = 0;
78722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			unsigned long long       RSC = 0;
78822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// endian issues
78922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			RSC = *((unsigned long long *)&(pKey->KeyRSC));
79022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			wLocalTSC15_0 = (unsigned short)RSC;
79122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			dwLocalTSC47_16 = (unsigned long)(RSC>>16);
79222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
79322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			RSC = dwRxTSC47_16;
79422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			RSC <<= 16;
79522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			RSC += wRxTSC15_0;
7960fc2a76eef05ee1aa82b3d9bf34eea2b50f5e1baMalcolm Priestley			pKey->KeyRSC = RSC;
79722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
79822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			if ((pDevice->sMgmtObj.eCurrMode == WMAC_MODE_ESS_STA) &&
79922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			    (pDevice->sMgmtObj.eCurrState == WMAC_STATE_ASSOC)) {
80022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				// check RSC
80122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				if ((wRxTSC15_0 < wLocalTSC15_0) &&
80222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				    (dwRxTSC47_16 <= dwLocalTSC47_16) &&
80322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				    !((dwRxTSC47_16 == 0) && (dwLocalTSC47_16 == 0xFFFFFFFF))) {
80448caf5a060491edb2e1793539dad72e70c54c869Joe Perches					pr_debug("TSC is illegal~~!\n ");
80522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					if (pKey->byCipherSuite == KEY_CTL_TKIP)
80622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						pDevice->s802_11Counter.TKIPReplays++;
80722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					else
80822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						pDevice->s802_11Counter.CCMPReplays++;
80922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
81022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					if (bDeFragRx) {
81122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
81248caf5a060491edb2e1793539dad72e70c54c869Joe Perches							pr_err("%s: can not alloc more frag bufs\n",
81348caf5a060491edb2e1793539dad72e70c54c869Joe Perches							       pDevice->dev->name);
81422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						}
81522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					}
81622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					return false;
81722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				}
81822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
81922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
82022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	} // ----- End of Reply Counter Check --------------------------
82122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
82222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	s_vProcessRxMACHeader(pDevice, (unsigned char *)(skb->data+4), FrameSize, bIsWEP, bExtIV, &cbHeaderOffset);
82322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	FrameSize -= cbHeaderOffset;
82422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	cbHeaderOffset += 4;        // 4 is Rcv buffer header
82522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
82622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	// Null data, framesize = 14
82722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (FrameSize < 15)
82822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		return false;
82922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
83022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
8311208f14a37fde2669b86bf1b1cd1122ad2ba3579Teodora Baluta		if (!s_bAPModeRxData(pDevice,
83222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				    skb,
83322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				    FrameSize,
83422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				    cbHeaderOffset,
83522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				    iSANodeIndex,
83622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				    iDANodeIndex
8371208f14a37fde2669b86bf1b1cd1122ad2ba3579Teodora Baluta)) {
83822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			if (bDeFragRx) {
83922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
84048caf5a060491edb2e1793539dad72e70c54c869Joe Perches					pr_err("%s: can not alloc more frag bufs\n",
84148caf5a060491edb2e1793539dad72e70c54c869Joe Perches					       pDevice->dev->name);
84222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				}
84322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
84422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			return false;
84522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
84622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
8475449c685a4b39534f18869a93896370224463715Forest Bond
8485449c685a4b39534f18869a93896370224463715Forest Bond	skb->data += cbHeaderOffset;
8495449c685a4b39534f18869a93896370224463715Forest Bond	skb->tail += cbHeaderOffset;
85022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	skb_put(skb, FrameSize);
85122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	skb->protocol = eth_type_trans(skb, skb->dev);
8525449c685a4b39534f18869a93896370224463715Forest Bond
8535449c685a4b39534f18869a93896370224463715Forest Bond	//drop frame not met IEEE 802.3
8545449c685a4b39534f18869a93896370224463715Forest Bond
85522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	skb->ip_summed = CHECKSUM_NONE;
85622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	pStats->rx_bytes += skb->len;
85722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	pStats->rx_packets++;
85822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	netif_rx(skb);
8595449c685a4b39534f18869a93896370224463715Forest Bond
86022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (bDeFragRx) {
86122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
86248caf5a060491edb2e1793539dad72e70c54c869Joe Perches			pr_err("%s: can not alloc more frag bufs\n",
86348caf5a060491edb2e1793539dad72e70c54c869Joe Perches			       pDevice->dev->name);
86422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
86522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		return false;
86622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
867612822f5dd1638de442cf50eb9da54632fba0e66Jim Lieb
86822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	return true;
8695449c685a4b39534f18869a93896370224463715Forest Bond}
8705449c685a4b39534f18869a93896370224463715Forest Bond
87122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perchesstatic bool s_bAPModeRxCtl(
872cf76dc4b85447e17678d61505eb1b92743c4b67bMalcolm Priestley	struct vnt_private *pDevice,
87322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyFrame,
87422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	int      iSANodeIndex
87522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches)
8765449c685a4b39534f18869a93896370224463715Forest Bond{
87722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PS802_11Header      p802_11Header;
87822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	CMD_STATUS          Status;
87922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PSMgmtObject        pMgmt = pDevice->pMgmt;
88022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
88122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (IS_CTL_PSPOLL(pbyFrame) || !IS_TYPE_CONTROL(pbyFrame)) {
88222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		p802_11Header = (PS802_11Header)(pbyFrame);
88322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (!IS_TYPE_MGMT(pbyFrame)) {
88422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// Data & PS-Poll packet
88522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// check frame class
88622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			if (iSANodeIndex > 0) {
88722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				// frame class 3 fliter & checking
88822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				if (pMgmt->sNodeDBTable[iSANodeIndex].eNodeState < NODE_AUTH) {
88922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					// send deauth notification
89022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					// reason = (6) class 2 received from nonauth sta
89122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					vMgrDeAuthenBeginSta(pDevice,
89222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							     pMgmt,
89322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							     (unsigned char *)(p802_11Header->abyAddr2),
89422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							     (WLAN_MGMT_REASON_CLASS2_NONAUTH),
89522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							     &Status
89622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches);
89748caf5a060491edb2e1793539dad72e70c54c869Joe Perches					pr_debug("dpc: send vMgrDeAuthenBeginSta 1\n");
89822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					return true;
89922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				}
90022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				if (pMgmt->sNodeDBTable[iSANodeIndex].eNodeState < NODE_ASSOC) {
90122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					// send deassoc notification
90222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					// reason = (7) class 3 received from nonassoc sta
90322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					vMgrDisassocBeginSta(pDevice,
90422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							     pMgmt,
90522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							     (unsigned char *)(p802_11Header->abyAddr2),
90622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							     (WLAN_MGMT_REASON_CLASS3_NONASSOC),
90722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							     &Status
90822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches);
90948caf5a060491edb2e1793539dad72e70c54c869Joe Perches					pr_debug("dpc: send vMgrDisassocBeginSta 2\n");
91022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					return true;
91122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				}
91222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
91322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				if (pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable) {
91422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					// delcare received ps-poll event
91522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					if (IS_CTL_PSPOLL(pbyFrame)) {
91622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = true;
91722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						bScheduleCommand((void *)pDevice, WLAN_CMD_RX_PSPOLL, NULL);
91848caf5a060491edb2e1793539dad72e70c54c869Joe Perches						pr_debug("dpc: WLAN_CMD_RX_PSPOLL 1\n");
9195e0cc8a231be82b0ec44cdf2a406b1a97dd3c971Joe Perches					} else {
92022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						// check Data PS state
92122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						// if PW bit off, send out all PS bufferring packets.
92222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						if (!IS_FC_POWERMGT(pbyFrame)) {
92322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = false;
92422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = true;
92522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							bScheduleCommand((void *)pDevice, WLAN_CMD_RX_PSPOLL, NULL);
92648caf5a060491edb2e1793539dad72e70c54c869Joe Perches							pr_debug("dpc: WLAN_CMD_RX_PSPOLL 2\n");
92722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						}
92822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					}
9295e0cc8a231be82b0ec44cdf2a406b1a97dd3c971Joe Perches				} else {
93022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					if (IS_FC_POWERMGT(pbyFrame)) {
93122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = true;
93222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						// Once if STA in PS state, enable multicast bufferring
93322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						pMgmt->sNodeDBTable[0].bPSEnable = true;
9345e0cc8a231be82b0ec44cdf2a406b1a97dd3c971Joe Perches					} else {
93522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						// clear all pending PS frame.
93622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						if (pMgmt->sNodeDBTable[iSANodeIndex].wEnQueueCnt > 0) {
93722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = false;
93822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = true;
93922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches							bScheduleCommand((void *)pDevice, WLAN_CMD_RX_PSPOLL, NULL);
94048caf5a060491edb2e1793539dad72e70c54c869Joe Perches							pr_debug("dpc: WLAN_CMD_RX_PSPOLL 3\n");
94122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
94222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						}
94322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					}
94422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				}
9455e0cc8a231be82b0ec44cdf2a406b1a97dd3c971Joe Perches			} else {
94622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				vMgrDeAuthenBeginSta(pDevice,
94722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						     pMgmt,
94822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						     (unsigned char *)(p802_11Header->abyAddr2),
94922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						     (WLAN_MGMT_REASON_CLASS2_NONAUTH),
95022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches						     &Status
95122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches);
95248caf5a060491edb2e1793539dad72e70c54c869Joe Perches				pr_debug("dpc: send vMgrDeAuthenBeginSta 3\n");
95348caf5a060491edb2e1793539dad72e70c54c869Joe Perches				pr_debug("BSSID:%pM\n",
95448caf5a060491edb2e1793539dad72e70c54c869Joe Perches					 p802_11Header->abyAddr3);
95548caf5a060491edb2e1793539dad72e70c54c869Joe Perches				pr_debug("ADDR2:%pM\n",
95648caf5a060491edb2e1793539dad72e70c54c869Joe Perches					 p802_11Header->abyAddr2);
95748caf5a060491edb2e1793539dad72e70c54c869Joe Perches				pr_debug("ADDR1:%pM\n",
95848caf5a060491edb2e1793539dad72e70c54c869Joe Perches					 p802_11Header->abyAddr1);
95948caf5a060491edb2e1793539dad72e70c54c869Joe Perches				pr_debug("dpc: wFrameCtl= %x\n",
96048caf5a060491edb2e1793539dad72e70c54c869Joe Perches					 p802_11Header->wFrameCtl);
96122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				VNSvInPortB(pDevice->PortOffset + MAC_REG_RCR, &(pDevice->byRxMode));
96248caf5a060491edb2e1793539dad72e70c54c869Joe Perches				pr_debug("dpc:pDevice->byRxMode = %x\n",
96348caf5a060491edb2e1793539dad72e70c54c869Joe Perches					 pDevice->byRxMode);
96422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				return true;
96522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
96622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
96722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
96822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	return false;
9695449c685a4b39534f18869a93896370224463715Forest Bond}
9705449c685a4b39534f18869a93896370224463715Forest Bond
97122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perchesstatic bool s_bHandleRxEncryption(
972cf76dc4b85447e17678d61505eb1b92743c4b67bMalcolm Priestley	struct vnt_private *pDevice,
97322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyFrame,
97422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned int FrameSize,
97522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyRsr,
97622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyNewRsr,
97722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PSKeyItem   *pKeyOut,
97822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	bool *pbExtIV,
97922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned short *pwRxTSC15_0,
98022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned long *pdwRxTSC47_16
98122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches)
9825449c685a4b39534f18869a93896370224463715Forest Bond{
98322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned int PayloadLen = FrameSize;
98422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyIV;
98522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char byKeyIdx;
98622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PSKeyItem       pKey = NULL;
98722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char byDecMode = KEY_CTL_WEP;
98822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PSMgmtObject    pMgmt = pDevice->pMgmt;
98922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
99022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	*pwRxTSC15_0 = 0;
99122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	*pdwRxTSC47_16 = 0;
99222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
99322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN;
99422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (WLAN_GET_FC_TODS(*(unsigned short *)pbyFrame) &&
99522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	    WLAN_GET_FC_FROMDS(*(unsigned short *)pbyFrame)) {
99622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		pbyIV += 6;             // 6 is 802.11 address4
99722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		PayloadLen -= 6;
99822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
99922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	byKeyIdx = (*(pbyIV+3) & 0xc0);
100022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	byKeyIdx >>= 6;
100148caf5a060491edb2e1793539dad72e70c54c869Joe Perches	pr_debug("\nKeyIdx: %d\n", byKeyIdx);
100222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
100322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA) ||
100422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	    (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) ||
100522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	    (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) ||
100622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	    (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) ||
100722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	    (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) {
100822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (((*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI)) == 0) &&
100922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		    (pDevice->pMgmt->byCSSPK != KEY_CTL_NONE)) {
101022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// unicast pkt use pairwise key
101148caf5a060491edb2e1793539dad72e70c54c869Joe Perches			pr_debug("unicast pkt\n");
101222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			if (KeybGetKey(&(pDevice->sKey), pDevice->abyBSSID, 0xFFFFFFFF, &pKey) == true) {
101322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				if (pDevice->pMgmt->byCSSPK == KEY_CTL_TKIP)
101422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					byDecMode = KEY_CTL_TKIP;
101522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				else if (pDevice->pMgmt->byCSSPK == KEY_CTL_CCMP)
101622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					byDecMode = KEY_CTL_CCMP;
101722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
101848caf5a060491edb2e1793539dad72e70c54c869Joe Perches			pr_debug("unicast pkt: %d, %p\n", byDecMode, pKey);
101922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		} else {
102022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// use group key
102122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			KeybGetKey(&(pDevice->sKey), pDevice->abyBSSID, byKeyIdx, &pKey);
102222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			if (pDevice->pMgmt->byCSSGK == KEY_CTL_TKIP)
102322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				byDecMode = KEY_CTL_TKIP;
102422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			else if (pDevice->pMgmt->byCSSGK == KEY_CTL_CCMP)
102522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				byDecMode = KEY_CTL_CCMP;
102648caf5a060491edb2e1793539dad72e70c54c869Joe Perches			pr_debug("group pkt: %d, %d, %p\n",
102748caf5a060491edb2e1793539dad72e70c54c869Joe Perches				 byKeyIdx, byDecMode, pKey);
102822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
102922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
103022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	// our WEP only support Default Key
103122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (pKey == NULL) {
103222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		// use default group key
103322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, byKeyIdx, &pKey);
103422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (pDevice->pMgmt->byCSSGK == KEY_CTL_TKIP)
103522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			byDecMode = KEY_CTL_TKIP;
103622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		else if (pDevice->pMgmt->byCSSGK == KEY_CTL_CCMP)
103722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			byDecMode = KEY_CTL_CCMP;
103822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
103922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	*pKeyOut = pKey;
104022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
104148caf5a060491edb2e1793539dad72e70c54c869Joe Perches	pr_debug("AES:%d %d %d\n",
104248caf5a060491edb2e1793539dad72e70c54c869Joe Perches		 pDevice->pMgmt->byCSSPK, pDevice->pMgmt->byCSSGK, byDecMode);
104322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
104422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (pKey == NULL) {
104548caf5a060491edb2e1793539dad72e70c54c869Joe Perches		pr_debug("pKey == NULL\n");
10464e8a7e5fc29697f881f5c358f84df52914908703Guido Martínez
104722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		return false;
104822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
104922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (byDecMode != pKey->byCipherSuite) {
10504e8a7e5fc29697f881f5c358f84df52914908703Guido Martínez
105122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		*pKeyOut = NULL;
105222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		return false;
105322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
105422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (byDecMode == KEY_CTL_WEP) {
105522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		// handle WEP
105622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if ((pDevice->byLocalID <= REV_ID_VT3253_A1) ||
105722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		    (((PSKeyTable)(pKey->pvKeyTable))->bSoftWEP == true)) {
105822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// Software WEP
105922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// 1. 3253A
106022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// 2. WEP 256
106122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
106222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			PayloadLen -= (WLAN_HDR_ADDR3_LEN + 4 + 4); // 24 is 802.11 header,4 is IV, 4 is crc
106322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			memcpy(pDevice->abyPRNG, pbyIV, 3);
106422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			memcpy(pDevice->abyPRNG + 3, pKey->abyKey, pKey->uKeyLength);
106522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			rc4_init(&pDevice->SBox, pDevice->abyPRNG, pKey->uKeyLength + 3);
106622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			rc4_encrypt(&pDevice->SBox, pbyIV+4, pbyIV+4, PayloadLen);
106722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
1068bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez			if (ETHbIsBufferCrc32Ok(pbyIV+4, PayloadLen))
106922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				*pbyNewRsr |= NEWRSR_DECRYPTOK;
1070bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez
107122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
107222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	} else if ((byDecMode == KEY_CTL_TKIP) ||
107322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		   (byDecMode == KEY_CTL_CCMP)) {
107422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		// TKIP/AES
107522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
107622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		PayloadLen -= (WLAN_HDR_ADDR3_LEN + 8 + 4); // 24 is 802.11 header, 8 is IV&ExtIV, 4 is crc
107722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		*pdwRxTSC47_16 = cpu_to_le32(*(unsigned long *)(pbyIV + 4));
107848caf5a060491edb2e1793539dad72e70c54c869Joe Perches		pr_debug("ExtIV: %lx\n", *pdwRxTSC47_16);
1079bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez		if (byDecMode == KEY_CTL_TKIP)
108022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			*pwRxTSC15_0 = cpu_to_le16(MAKEWORD(*(pbyIV + 2), *pbyIV));
1081bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez		else
108222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			*pwRxTSC15_0 = cpu_to_le16(*(unsigned short *)pbyIV);
1083bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez
108448caf5a060491edb2e1793539dad72e70c54c869Joe Perches		pr_debug("TSC0_15: %x\n", *pwRxTSC15_0);
108522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
108622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if ((byDecMode == KEY_CTL_TKIP) &&
108722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		    (pDevice->byLocalID <= REV_ID_VT3253_A1)) {
108822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// Software TKIP
108922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// 1. 3253 A
109022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			PS802_11Header  pMACHeader = (PS802_11Header)(pbyFrame);
10916b7112719fd48c29f35333ef152a5a450f01dc83Guillaume Clement
109222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			TKIPvMixKey(pKey->abyKey, pMACHeader->abyAddr2, *pwRxTSC15_0, *pdwRxTSC47_16, pDevice->abyPRNG);
109322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			rc4_init(&pDevice->SBox, pDevice->abyPRNG, TKIP_KEY_LEN);
109422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			rc4_encrypt(&pDevice->SBox, pbyIV+8, pbyIV+8, PayloadLen);
109522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			if (ETHbIsBufferCrc32Ok(pbyIV+8, PayloadLen)) {
109622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				*pbyNewRsr |= NEWRSR_DECRYPTOK;
109748caf5a060491edb2e1793539dad72e70c54c869Joe Perches				pr_debug("ICV OK!\n");
109822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			} else {
109948caf5a060491edb2e1793539dad72e70c54c869Joe Perches				pr_debug("ICV FAIL!!!\n");
110048caf5a060491edb2e1793539dad72e70c54c869Joe Perches				pr_debug("PayloadLen = %d\n", PayloadLen);
110122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
110222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
110322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}// end of TKIP/AES
110422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
110522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if ((*(pbyIV+3) & 0x20) != 0)
110622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		*pbExtIV = true;
110722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	return true;
11085449c685a4b39534f18869a93896370224463715Forest Bond}
11095449c685a4b39534f18869a93896370224463715Forest Bond
111022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perchesstatic bool s_bHostWepRxEncryption(
1111cf76dc4b85447e17678d61505eb1b92743c4b67bMalcolm Priestley	struct vnt_private *pDevice,
111222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyFrame,
111322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned int FrameSize,
111422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyRsr,
111522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	bool bOnFly,
111622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PSKeyItem    pKey,
111722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyNewRsr,
111822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	bool *pbExtIV,
111922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned short *pwRxTSC15_0,
112022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned long *pdwRxTSC47_16
112122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches)
11225449c685a4b39534f18869a93896370224463715Forest Bond{
112322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned int PayloadLen = FrameSize;
112422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char *pbyIV;
112522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char byKeyIdx;
112622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char byDecMode = KEY_CTL_WEP;
112722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PS802_11Header  pMACHeader;
11285449c685a4b39534f18869a93896370224463715Forest Bond
112922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	*pwRxTSC15_0 = 0;
113022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	*pdwRxTSC47_16 = 0;
11315449c685a4b39534f18869a93896370224463715Forest Bond
113222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN;
113322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (WLAN_GET_FC_TODS(*(unsigned short *)pbyFrame) &&
113422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	    WLAN_GET_FC_FROMDS(*(unsigned short *)pbyFrame)) {
113522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		pbyIV += 6;             // 6 is 802.11 address4
113622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		PayloadLen -= 6;
113722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
113822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	byKeyIdx = (*(pbyIV+3) & 0xc0);
113922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	byKeyIdx >>= 6;
114048caf5a060491edb2e1793539dad72e70c54c869Joe Perches	pr_debug("\nKeyIdx: %d\n", byKeyIdx);
11415449c685a4b39534f18869a93896370224463715Forest Bond
114222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (pDevice->pMgmt->byCSSGK == KEY_CTL_TKIP)
114322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		byDecMode = KEY_CTL_TKIP;
114422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	else if (pDevice->pMgmt->byCSSGK == KEY_CTL_CCMP)
114522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		byDecMode = KEY_CTL_CCMP;
11465449c685a4b39534f18869a93896370224463715Forest Bond
114748caf5a060491edb2e1793539dad72e70c54c869Joe Perches	pr_debug("AES:%d %d %d\n",
114848caf5a060491edb2e1793539dad72e70c54c869Joe Perches		 pDevice->pMgmt->byCSSPK, pDevice->pMgmt->byCSSGK, byDecMode);
11495449c685a4b39534f18869a93896370224463715Forest Bond
11504e8a7e5fc29697f881f5c358f84df52914908703Guido Martínez	if (byDecMode != pKey->byCipherSuite)
115122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		return false;
115222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
115322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (byDecMode == KEY_CTL_WEP) {
115422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		// handle WEP
115548caf5a060491edb2e1793539dad72e70c54c869Joe Perches		pr_debug("byDecMode == KEY_CTL_WEP\n");
1156bfd7a2819051fc0ab401609aedbe65df46ed1259Guillaume Clement
115722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if ((pDevice->byLocalID <= REV_ID_VT3253_A1) ||
115822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		    (((PSKeyTable)(pKey->pvKeyTable))->bSoftWEP == true) ||
11591208f14a37fde2669b86bf1b1cd1122ad2ba3579Teodora Baluta		    !bOnFly) {
116022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// Software WEP
116122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// 1. 3253A
116222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// 2. WEP 256
116322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// 3. NotOnFly
116422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
116522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			PayloadLen -= (WLAN_HDR_ADDR3_LEN + 4 + 4); // 24 is 802.11 header,4 is IV, 4 is crc
116622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			memcpy(pDevice->abyPRNG, pbyIV, 3);
116722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			memcpy(pDevice->abyPRNG + 3, pKey->abyKey, pKey->uKeyLength);
116822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			rc4_init(&pDevice->SBox, pDevice->abyPRNG, pKey->uKeyLength + 3);
116922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			rc4_encrypt(&pDevice->SBox, pbyIV+4, pbyIV+4, PayloadLen);
117022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
1171bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez			if (ETHbIsBufferCrc32Ok(pbyIV+4, PayloadLen))
117222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				*pbyNewRsr |= NEWRSR_DECRYPTOK;
1173bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez
117422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
117522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	} else if ((byDecMode == KEY_CTL_TKIP) ||
117622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		   (byDecMode == KEY_CTL_CCMP)) {
117722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		// TKIP/AES
117822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
117922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		PayloadLen -= (WLAN_HDR_ADDR3_LEN + 8 + 4); // 24 is 802.11 header, 8 is IV&ExtIV, 4 is crc
118022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		*pdwRxTSC47_16 = cpu_to_le32(*(unsigned long *)(pbyIV + 4));
118148caf5a060491edb2e1793539dad72e70c54c869Joe Perches		pr_debug("ExtIV: %lx\n", *pdwRxTSC47_16);
118222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
1183bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez		if (byDecMode == KEY_CTL_TKIP)
118422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			*pwRxTSC15_0 = cpu_to_le16(MAKEWORD(*(pbyIV+2), *pbyIV));
1185bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez		else
118622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			*pwRxTSC15_0 = cpu_to_le16(*(unsigned short *)pbyIV);
1187bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez
118848caf5a060491edb2e1793539dad72e70c54c869Joe Perches		pr_debug("TSC0_15: %x\n", *pwRxTSC15_0);
118922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
119022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (byDecMode == KEY_CTL_TKIP) {
11911208f14a37fde2669b86bf1b1cd1122ad2ba3579Teodora Baluta			if ((pDevice->byLocalID <= REV_ID_VT3253_A1) || !bOnFly) {
119222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				// Software TKIP
119322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				// 1. 3253 A
119422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				// 2. NotOnFly
119548caf5a060491edb2e1793539dad72e70c54c869Joe Perches				pr_debug("soft KEY_CTL_TKIP\n");
119622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				pMACHeader = (PS802_11Header)(pbyFrame);
119722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				TKIPvMixKey(pKey->abyKey, pMACHeader->abyAddr2, *pwRxTSC15_0, *pdwRxTSC47_16, pDevice->abyPRNG);
119822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				rc4_init(&pDevice->SBox, pDevice->abyPRNG, TKIP_KEY_LEN);
119922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				rc4_encrypt(&pDevice->SBox, pbyIV+8, pbyIV+8, PayloadLen);
120022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				if (ETHbIsBufferCrc32Ok(pbyIV+8, PayloadLen)) {
120122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					*pbyNewRsr |= NEWRSR_DECRYPTOK;
120248caf5a060491edb2e1793539dad72e70c54c869Joe Perches					pr_debug("ICV OK!\n");
120322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				} else {
120448caf5a060491edb2e1793539dad72e70c54c869Joe Perches					pr_debug("ICV FAIL!!!\n");
120548caf5a060491edb2e1793539dad72e70c54c869Joe Perches					pr_debug("PayloadLen = %d\n",
120648caf5a060491edb2e1793539dad72e70c54c869Joe Perches						 PayloadLen);
120722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				}
120822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
120922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
121022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
121122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (byDecMode == KEY_CTL_CCMP) {
12121208f14a37fde2669b86bf1b1cd1122ad2ba3579Teodora Baluta			if (!bOnFly) {
121322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				// Software CCMP
121422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				// NotOnFly
121548caf5a060491edb2e1793539dad72e70c54c869Joe Perches				pr_debug("soft KEY_CTL_CCMP\n");
121622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				if (AESbGenCCMP(pKey->abyKey, pbyFrame, FrameSize)) {
121722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					*pbyNewRsr |= NEWRSR_DECRYPTOK;
121848caf5a060491edb2e1793539dad72e70c54c869Joe Perches					pr_debug("CCMP MIC compare OK!\n");
121922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				} else {
122048caf5a060491edb2e1793539dad72e70c54c869Joe Perches					pr_debug("CCMP MIC fail!\n");
122122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				}
122222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
122322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
122422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
122522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}// end of TKIP/AES
122622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
122722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if ((*(pbyIV+3) & 0x20) != 0)
122822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		*pbExtIV = true;
122922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	return true;
12305449c685a4b39534f18869a93896370224463715Forest Bond}
12315449c685a4b39534f18869a93896370224463715Forest Bond
123222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perchesstatic bool s_bAPModeRxData(
1233cf76dc4b85447e17678d61505eb1b92743c4b67bMalcolm Priestley	struct vnt_private *pDevice,
123422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	struct sk_buff *skb,
123522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned int FrameSize,
123622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned int cbHeaderOffset,
123722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	int      iSANodeIndex,
123822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	int      iDANodeIndex
123922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches)
12405449c685a4b39534f18869a93896370224463715Forest Bond{
124122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	PSMgmtObject        pMgmt = pDevice->pMgmt;
124222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	bool bRelayAndForward = false;
124322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	bool bRelayOnly = false;
124422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
124522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	unsigned short wAID;
124622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
124722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	struct sk_buff *skbcpy = NULL;
124822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
124922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (FrameSize > CB_MAX_BUF_SIZE)
125022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		return false;
125122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	// check DA
125222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (is_multicast_ether_addr((unsigned char *)(skb->data+cbHeaderOffset))) {
125322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (pMgmt->sNodeDBTable[0].bPSEnable) {
125422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			skbcpy = dev_alloc_skb((int)pDevice->rx_buf_sz);
125522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
125622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			// if any node in PS mode, buffer packet until DTIM.
125722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			if (skbcpy == NULL) {
125848caf5a060491edb2e1793539dad72e70c54c869Joe Perches				pr_info("relay multicast no skb available\n");
12595e0cc8a231be82b0ec44cdf2a406b1a97dd3c971Joe Perches			} else {
126022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				skbcpy->dev = pDevice->dev;
126122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				skbcpy->len = FrameSize;
126222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				memcpy(skbcpy->data, skb->data+cbHeaderOffset, FrameSize);
126322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				skb_queue_tail(&(pMgmt->sNodeDBTable[0].sTxPSQueue), skbcpy);
126422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
126522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				pMgmt->sNodeDBTable[0].wEnQueueCnt++;
126622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				// set tx map
126722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				pMgmt->abyPSTxMap[0] |= byMask[0];
126822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
12695e0cc8a231be82b0ec44cdf2a406b1a97dd3c971Joe Perches		} else {
127022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			bRelayAndForward = true;
127122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
12725e0cc8a231be82b0ec44cdf2a406b1a97dd3c971Joe Perches	} else {
127322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		// check if relay
127422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (BSSDBbIsSTAInNodeDB(pMgmt, (unsigned char *)(skb->data+cbHeaderOffset), &iDANodeIndex)) {
127522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			if (pMgmt->sNodeDBTable[iDANodeIndex].eNodeState >= NODE_ASSOC) {
127622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				if (pMgmt->sNodeDBTable[iDANodeIndex].bPSEnable) {
127722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					// queue this skb until next PS tx, and then release.
127822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
127922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					skb->data += cbHeaderOffset;
128022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					skb->tail += cbHeaderOffset;
128122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					skb_put(skb, FrameSize);
128222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					skb_queue_tail(&pMgmt->sNodeDBTable[iDANodeIndex].sTxPSQueue, skb);
128322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					pMgmt->sNodeDBTable[iDANodeIndex].wEnQueueCnt++;
128422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					wAID = pMgmt->sNodeDBTable[iDANodeIndex].wAID;
128522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					pMgmt->abyPSTxMap[wAID >> 3] |=  byMask[wAID & 7];
128648caf5a060491edb2e1793539dad72e70c54c869Joe Perches					pr_debug("relay: index= %d, pMgmt->abyPSTxMap[%d]= %d\n",
128748caf5a060491edb2e1793539dad72e70c54c869Joe Perches						 iDANodeIndex, (wAID >> 3),
128848caf5a060491edb2e1793539dad72e70c54c869Joe Perches						 pMgmt->abyPSTxMap[wAID >> 3]);
128922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					return true;
12905e0cc8a231be82b0ec44cdf2a406b1a97dd3c971Joe Perches				} else {
129122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches					bRelayOnly = true;
129222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches				}
129322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			}
129422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		}
129522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
129622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
129722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (bRelayOnly || bRelayAndForward) {
129822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		// relay this packet right now
129922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (bRelayAndForward)
130022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			iDANodeIndex = 0;
130122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
1302bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez		if ((pDevice->uAssocCount > 1) && (iDANodeIndex >= 0))
130322c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			ROUTEbRelay(pDevice, (unsigned char *)(skb->data + cbHeaderOffset), FrameSize, (unsigned int)iDANodeIndex);
130422c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
130522c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		if (bRelayOnly)
130622c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches			return false;
130722c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	}
130822c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	// none associate, don't forward
130922c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	if (pDevice->uAssocCount == 0)
131022c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches		return false;
131122c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches
131222c5291e70ba66880c6a6acffbd8200a623c4556Joe Perches	return true;
13135449c685a4b39534f18869a93896370224463715Forest Bond}
1314