diff options
Diffstat (limited to 'drivers/staging/vt6655/IEEE11h.c')
-rw-r--r-- | drivers/staging/vt6655/IEEE11h.c | 324 |
1 files changed, 324 insertions, 0 deletions
diff --git a/drivers/staging/vt6655/IEEE11h.c b/drivers/staging/vt6655/IEEE11h.c new file mode 100644 index 00000000000..5f25b8e88bd --- /dev/null +++ b/drivers/staging/vt6655/IEEE11h.c @@ -0,0 +1,324 @@ +/* + * Copyright (c) 1996, 2005 VIA Networking Technologies, Inc. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * + * File: IEEE11h.c + * + * Purpose: + * + * Functions: + * + * Revision History: + * + * Author: Yiching Chen + * + * Date: Mar. 31, 2005 + * + */ + + +#if !defined(__TTYPE_H__) +#include "ttype.h" +#endif +#if !defined(__UMEM_H__) +#include "umem.h" +#endif +#if !defined(__TMACRO_H__) +#include "tmacro.h" +#endif +#if !defined(__TETHER_H__) +#include "tether.h" +#endif +#if !defined(__IEEE11h_H__) +#include "IEEE11h.h" +#endif + +#if !defined(__DEVICE_H__) +#include "device.h" +#endif +#if !defined(__WMGR_H__) +#include "wmgr.h" +#endif +#if !defined(__RXTX_H__) +#include "rxtx.h" +#endif + + + +/*--------------------- Static Definitions -------------------------*/ +static int msglevel =MSG_LEVEL_INFO; + +#pragma pack(1) + +typedef struct _WLAN_FRAME_ACTION { + WLAN_80211HDR_A3 Header; + BYTE byCategory; + BYTE byAction; + BYTE abyVars[1]; +} WLAN_FRAME_ACTION, *PWLAN_FRAME_ACTION; + +typedef struct _WLAN_FRAME_MSRREQ { + WLAN_80211HDR_A3 Header; + BYTE byCategory; + BYTE byAction; + BYTE byDialogToken; + WLAN_IE_MEASURE_REQ sMSRReqEIDs[1]; +} WLAN_FRAME_MSRREQ, *PWLAN_FRAME_MSRREQ; + +typedef struct _WLAN_FRAME_MSRREP { + WLAN_80211HDR_A3 Header; + BYTE byCategory; + BYTE byAction; + BYTE byDialogToken; + WLAN_IE_MEASURE_REP sMSRRepEIDs[1]; +} WLAN_FRAME_MSRREP, *PWLAN_FRAME_MSRREP; + +typedef struct _WLAN_FRAME_TPCREQ { + WLAN_80211HDR_A3 Header; + BYTE byCategory; + BYTE byAction; + BYTE byDialogToken; + WLAN_IE_TPC_REQ sTPCReqEIDs; +} WLAN_FRAME_TPCREQ, *PWLAN_FRAME_TPCREQ; + +typedef struct _WLAN_FRAME_TPCREP { + WLAN_80211HDR_A3 Header; + BYTE byCategory; + BYTE byAction; + BYTE byDialogToken; + WLAN_IE_TPC_REP sTPCRepEIDs; +} WLAN_FRAME_TPCREP, *PWLAN_FRAME_TPCREP; + +#pragma pack() + +// action field reference ieee 802.11h Table 20e +#define ACTION_MSRREQ 0 +#define ACTION_MSRREP 1 +#define ACTION_TPCREQ 2 +#define ACTION_TPCREP 3 +#define ACTION_CHSW 4 + +/*--------------------- Static Classes ----------------------------*/ + +/*--------------------- Static Variables --------------------------*/ + +/*--------------------- Static Functions --------------------------*/ +static BOOL s_bRxMSRReq(PSMgmtObject pMgmt, PWLAN_FRAME_MSRREQ pMSRReq, UINT uLength) +{ + UINT uNumOfEIDs = 0; + BOOL bResult = TRUE; + + if (uLength <= WLAN_A3FR_MAXLEN) { + MEMvCopy(pMgmt->abyCurrentMSRReq, pMSRReq, uLength); + } + uNumOfEIDs = ((uLength - OFFSET(WLAN_FRAME_MSRREQ, sMSRReqEIDs))/ (sizeof(WLAN_IE_MEASURE_REQ))); + pMgmt->pCurrMeasureEIDRep = &(((PWLAN_FRAME_MSRREP) (pMgmt->abyCurrentMSRRep))->sMSRRepEIDs[0]); + pMgmt->uLengthOfRepEIDs = 0; + bResult = CARDbStartMeasure(pMgmt->pAdapter, + ((PWLAN_FRAME_MSRREQ) (pMgmt->abyCurrentMSRReq))->sMSRReqEIDs, + uNumOfEIDs + ); + return (bResult); +} + + +static BOOL s_bRxTPCReq(PSMgmtObject pMgmt, PWLAN_FRAME_TPCREQ pTPCReq, BYTE byRate, BYTE byRSSI) +{ + PWLAN_FRAME_TPCREP pFrame; + PSTxMgmtPacket pTxPacket = NULL; + + + pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; + memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN); + pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket)); + + pFrame = (PWLAN_FRAME_TPCREP)((PBYTE)pTxPacket + sizeof(STxMgmtPacket)); + + pFrame->Header.wFrameCtl = ( WLAN_SET_FC_FTYPE(WLAN_FTYPE_MGMT) | + WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ACTION) + ); + + MEMvCopy( pFrame->Header.abyAddr1, pTPCReq->Header.abyAddr2, WLAN_ADDR_LEN); + MEMvCopy( pFrame->Header.abyAddr2, CARDpGetCurrentAddress(pMgmt->pAdapter), WLAN_ADDR_LEN); + MEMvCopy( pFrame->Header.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); + + pFrame->byCategory = 0; + pFrame->byAction = 3; + pFrame->byDialogToken = ((PWLAN_FRAME_MSRREQ) (pMgmt->abyCurrentMSRReq))->byDialogToken; + + pFrame->sTPCRepEIDs.byElementID = WLAN_EID_TPC_REP; + pFrame->sTPCRepEIDs.len = 2; + pFrame->sTPCRepEIDs.byTxPower = CARDbyGetTransmitPower(pMgmt->pAdapter); + switch (byRate) { + case RATE_54M: + pFrame->sTPCRepEIDs.byLinkMargin = 65 - byRSSI; + break; + case RATE_48M: + pFrame->sTPCRepEIDs.byLinkMargin = 66 - byRSSI; + break; + case RATE_36M: + pFrame->sTPCRepEIDs.byLinkMargin = 70 - byRSSI; + break; + case RATE_24M: + pFrame->sTPCRepEIDs.byLinkMargin = 74 - byRSSI; + break; + case RATE_18M: + pFrame->sTPCRepEIDs.byLinkMargin = 77 - byRSSI; + break; + case RATE_12M: + pFrame->sTPCRepEIDs.byLinkMargin = 79 - byRSSI; + break; + case RATE_9M: + pFrame->sTPCRepEIDs.byLinkMargin = 81 - byRSSI; + break; + case RATE_6M: + default: + pFrame->sTPCRepEIDs.byLinkMargin = 82 - byRSSI; + break; + } + + pTxPacket->cbMPDULen = sizeof(WLAN_FRAME_TPCREP); + pTxPacket->cbPayloadLen = sizeof(WLAN_FRAME_TPCREP) - WLAN_HDR_ADDR3_LEN; + if (csMgmt_xmit(pMgmt->pAdapter, pTxPacket) != CMD_STATUS_PENDING) + return (FALSE); + return (TRUE); +// return (CARDbSendPacket(pMgmt->pAdapter, pFrame, PKT_TYPE_802_11_MNG, sizeof(WLAN_FRAME_TPCREP))); + +} + + +/*--------------------- Export Variables --------------------------*/ + +/*--------------------- Export Functions --------------------------*/ + + +/*+ + * + * Description: + * Handles action management frames. + * + * Parameters: + * In: + * pMgmt - Management Object structure + * pRxPacket - Received packet + * Out: + * none + * + * Return Value: None. + * +-*/ +BOOL +IEEE11hbMgrRxAction ( + IN PVOID pMgmtHandle, + IN PVOID pRxPacket + ) +{ + PSMgmtObject pMgmt = (PSMgmtObject) pMgmtHandle; + PWLAN_FRAME_ACTION pAction = NULL; + UINT uLength = 0; + PWLAN_IE_CH_SW pChannelSwitch = NULL; + + + // decode the frame + uLength = ((PSRxMgmtPacket)pRxPacket)->cbMPDULen; + if (uLength > WLAN_A3FR_MAXLEN) { + return (FALSE); + } + + + pAction = (PWLAN_FRAME_ACTION) (((PSRxMgmtPacket)pRxPacket)->p80211Header); + + if (pAction->byCategory == 0) { + switch (pAction->byAction) { + case ACTION_MSRREQ: + return (s_bRxMSRReq(pMgmt, (PWLAN_FRAME_MSRREQ) pAction, uLength)); + break; + case ACTION_MSRREP: + break; + case ACTION_TPCREQ: + return (s_bRxTPCReq(pMgmt, + (PWLAN_FRAME_TPCREQ) pAction, + ((PSRxMgmtPacket)pRxPacket)->byRxRate, + (BYTE) ((PSRxMgmtPacket)pRxPacket)->uRSSI)); + break; + case ACTION_TPCREP: + break; + case ACTION_CHSW: + pChannelSwitch = (PWLAN_IE_CH_SW) (pAction->abyVars); + if ((pChannelSwitch->byElementID == WLAN_EID_CH_SWITCH) && + (pChannelSwitch->len == 3)) { + // valid element id + CARDbChannelSwitch( pMgmt->pAdapter, + pChannelSwitch->byMode, + CARDbyGetChannelMapping(pMgmt->pAdapter, pChannelSwitch->byChannel, pMgmt->eCurrentPHYMode), + pChannelSwitch->byCount + ); + } + break; + default: + DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Unknown Action = %d\n", pAction->byAction); + break; + } + } else { + DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Unknown Category = %d\n", pAction->byCategory); + pAction->byCategory |= 0x80; + + //return (CARDbSendPacket(pMgmt->pAdapter, pAction, PKT_TYPE_802_11_MNG, uLength)); + return (TRUE); + } + return (TRUE); +} + + +BOOL IEEE11hbMSRRepTx ( + IN PVOID pMgmtHandle + ) +{ + PSMgmtObject pMgmt = (PSMgmtObject) pMgmtHandle; + PWLAN_FRAME_MSRREP pMSRRep = (PWLAN_FRAME_MSRREP) (pMgmt->abyCurrentMSRRep + sizeof(STxMgmtPacket)); + UINT uLength = 0; + PSTxMgmtPacket pTxPacket = NULL; + + pTxPacket = (PSTxMgmtPacket)pMgmt->abyCurrentMSRRep; + memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN); + pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket)); + + + pMSRRep->Header.wFrameCtl = ( WLAN_SET_FC_FTYPE(WLAN_FTYPE_MGMT) | + WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ACTION) + ); + + MEMvCopy( pMSRRep->Header.abyAddr1, ((PWLAN_FRAME_MSRREQ) (pMgmt->abyCurrentMSRReq))->Header.abyAddr2, WLAN_ADDR_LEN); + MEMvCopy( pMSRRep->Header.abyAddr2, CARDpGetCurrentAddress(pMgmt->pAdapter), WLAN_ADDR_LEN); + MEMvCopy( pMSRRep->Header.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); + + pMSRRep->byCategory = 0; + pMSRRep->byAction = 1; + pMSRRep->byDialogToken = ((PWLAN_FRAME_MSRREQ) (pMgmt->abyCurrentMSRReq))->byDialogToken; + + uLength = pMgmt->uLengthOfRepEIDs + OFFSET(WLAN_FRAME_MSRREP, sMSRRepEIDs); + + pTxPacket->cbMPDULen = uLength; + pTxPacket->cbPayloadLen = uLength - WLAN_HDR_ADDR3_LEN; + if (csMgmt_xmit(pMgmt->pAdapter, pTxPacket) != CMD_STATUS_PENDING) + return (FALSE); + return (TRUE); +// return (CARDbSendPacket(pMgmt->pAdapter, pMSRRep, PKT_TYPE_802_11_MNG, uLength)); + +} + |