summaryrefslogtreecommitdiffstats
path: root/drivers/staging/rt2870
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2009-04-26 16:06:31 +0200
committerGreg Kroah-Hartman <gregkh@suse.de>2009-06-19 11:00:50 -0700
commitddaf557500664b88951f8b1e9b4cb9d368892fd6 (patch)
treeba273e23eced5308cfc7843d4c3464e0616d604b /drivers/staging/rt2870
parent5f5d2df8ab0b5b6e8514c69b33cc92cac45cda75 (diff)
Staging: rt28[67]0: merge rt28[67]0/sta/*.[ch]
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging/rt2870')
-rw-r--r--drivers/staging/rt2870/sta/aironet.c1313
-rw-r--r--drivers/staging/rt2870/sta/assoc.c1740
-rw-r--r--drivers/staging/rt2870/sta/auth.c461
-rw-r--r--drivers/staging/rt2870/sta/auth_rsp.c149
-rw-r--r--drivers/staging/rt2870/sta/connect.c2470
-rw-r--r--drivers/staging/rt2870/sta/rtmp_data.c2429
-rw-r--r--drivers/staging/rt2870/sta/sanity.c419
-rw-r--r--drivers/staging/rt2870/sta/sync.c1605
-rw-r--r--drivers/staging/rt2870/sta/wpa.c2101
9 files changed, 9 insertions, 12678 deletions
diff --git a/drivers/staging/rt2870/sta/aironet.c b/drivers/staging/rt2870/sta/aironet.c
index 4af4a1906181..72b7f2e6bf7f 100644
--- a/drivers/staging/rt2870/sta/aironet.c
+++ b/drivers/staging/rt2870/sta/aironet.c
@@ -1,1312 +1 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- * *
- *************************************************************************
-
- Module Name:
- aironet.c
-
- Abstract:
-
- Revision History:
- Who When What
- -------- ---------- ----------------------------------------------
- Paul Lin 04-06-15 Initial
-*/
-#include "../rt_config.h"
-
-/*
- ==========================================================================
- Description:
- association state machine init, including state transition and timer init
- Parameters:
- S - pointer to the association state machine
- ==========================================================================
- */
-VOID AironetStateMachineInit(
- IN PRTMP_ADAPTER pAd,
- IN STATE_MACHINE *S,
- OUT STATE_MACHINE_FUNC Trans[])
-{
- StateMachineInit(S, Trans, MAX_AIRONET_STATE, MAX_AIRONET_MSG, (STATE_MACHINE_FUNC)Drop, AIRONET_IDLE, AIRONET_MACHINE_BASE);
- StateMachineSetAction(S, AIRONET_IDLE, MT2_AIRONET_MSG, (STATE_MACHINE_FUNC)AironetMsgAction);
- StateMachineSetAction(S, AIRONET_IDLE, MT2_AIRONET_SCAN_REQ, (STATE_MACHINE_FUNC)AironetRequestAction);
- StateMachineSetAction(S, AIRONET_SCANNING, MT2_AIRONET_SCAN_DONE, (STATE_MACHINE_FUNC)AironetReportAction);
-}
-
-/*
- ==========================================================================
- Description:
- This is state machine function.
- When receiving EAPOL packets which is for 802.1x key management.
- Use both in WPA, and WPAPSK case.
- In this function, further dispatch to different functions according to the received packet. 3 categories are :
- 1. normal 4-way pairwisekey and 2-way groupkey handshake
- 2. MIC error (Countermeasures attack) report packet from STA.
- 3. Request for pairwise/group key update from STA
- Return:
- ==========================================================================
-*/
-VOID AironetMsgAction(
- IN PRTMP_ADAPTER pAd,
- IN MLME_QUEUE_ELEM *Elem)
-{
- USHORT Length;
- UCHAR Index, i;
- PUCHAR pData;
- PAIRONET_RM_REQUEST_FRAME pRMReq;
- PRM_REQUEST_ACTION pReqElem;
-
- DBGPRINT(RT_DEBUG_TRACE, ("-----> AironetMsgAction\n"));
-
- // 0. Get Aironet IAPP header first
- pRMReq = (PAIRONET_RM_REQUEST_FRAME) &Elem->Msg[LENGTH_802_11];
- pData = (PUCHAR) &Elem->Msg[LENGTH_802_11];
-
- // 1. Change endian format form network to little endian
- Length = be2cpu16(pRMReq->IAPP.Length);
-
- // 2.0 Sanity check, this should only happen when CCX 2.0 support is enabled
- if (pAd->StaCfg.CCXEnable != TRUE)
- return;
-
- // 2.1 Radio measurement must be on
- if (pAd->StaCfg.CCXControl.field.RMEnable != 1)
- return;
-
- // 2.2. Debug print all bit information
- DBGPRINT(RT_DEBUG_TRACE, ("IAPP ID & Length %d\n", Length));
- DBGPRINT(RT_DEBUG_TRACE, ("IAPP Type %x\n", pRMReq->IAPP.Type));
- DBGPRINT(RT_DEBUG_TRACE, ("IAPP SubType %x\n", pRMReq->IAPP.SubType));
- DBGPRINT(RT_DEBUG_TRACE, ("IAPP Dialog Token %x\n", pRMReq->IAPP.Token));
- DBGPRINT(RT_DEBUG_TRACE, ("IAPP Activation Delay %x\n", pRMReq->Delay));
- DBGPRINT(RT_DEBUG_TRACE, ("IAPP Measurement Offset %x\n", pRMReq->Offset));
-
- // 3. Check IAPP frame type, it must be 0x32 for Cisco Aironet extension
- if (pRMReq->IAPP.Type != AIRONET_IAPP_TYPE)
- {
- DBGPRINT(RT_DEBUG_ERROR, ("Wrong IAPP type for Cisco Aironet extension\n"));
- return;
- }
-
- // 4. Check IAPP frame subtype, it must be 0x01 for Cisco Aironet extension request.
- // Since we are acting as client only, we will disregards reply subtype.
- if (pRMReq->IAPP.SubType != AIRONET_IAPP_SUBTYPE_REQUEST)
- {
- DBGPRINT(RT_DEBUG_ERROR, ("Wrong IAPP subtype for Cisco Aironet extension\n"));
- return;
- }
-
- // 5. Verify Destination MAC and Source MAC, both should be all zeros.
- if (! MAC_ADDR_EQUAL(pRMReq->IAPP.DA, ZERO_MAC_ADDR))
- {
- DBGPRINT(RT_DEBUG_ERROR, ("Wrong IAPP DA for Cisco Aironet extension, it's not Zero\n"));
- return;
- }
-
- if (! MAC_ADDR_EQUAL(pRMReq->IAPP.SA, ZERO_MAC_ADDR))
- {
- DBGPRINT(RT_DEBUG_ERROR, ("Wrong IAPP SA for Cisco Aironet extension, it's not Zero\n"));
- return;
- }
-
- // 6. Reinit all report related fields
- NdisZeroMemory(pAd->StaCfg.FrameReportBuf, 2048);
- NdisZeroMemory(pAd->StaCfg.BssReportOffset, sizeof(USHORT) * MAX_LEN_OF_BSS_TABLE);
- NdisZeroMemory(pAd->StaCfg.MeasurementRequest, sizeof(RM_REQUEST_ACTION) * 4);
-
- // 7. Point to the start of first element report element
- pAd->StaCfg.FrameReportLen = LENGTH_802_11 + sizeof(AIRONET_IAPP_HEADER);
- DBGPRINT(RT_DEBUG_TRACE, ("FR len = %d\n", pAd->StaCfg.FrameReportLen));
- pAd->StaCfg.LastBssIndex = 0xff;
- pAd->StaCfg.RMReqCnt = 0;
- pAd->StaCfg.ParallelReq = FALSE;
- pAd->StaCfg.ParallelDuration = 0;
- pAd->StaCfg.ParallelChannel = 0;
- pAd->StaCfg.IAPPToken = pRMReq->IAPP.Token;
- pAd->StaCfg.CurrentRMReqIdx = 0;
- pAd->StaCfg.CLBusyBytes = 0;
- // Reset the statistics
- for (i = 0; i < 8; i++)
- pAd->StaCfg.RPIDensity[i] = 0;
-
- Index = 0;
-
- // 8. Save dialog token for report
- pAd->StaCfg.IAPPToken = pRMReq->IAPP.Token;
-
- // Save Activation delay & measurement offset, Not really needed
-
- // 9. Point to the first request element
- pData += sizeof(AIRONET_RM_REQUEST_FRAME);
- // Length should exclude the CISCO Aironet SNAP header
- Length -= (sizeof(AIRONET_RM_REQUEST_FRAME) - LENGTH_802_1_H);
-
- // 10. Start Parsing the Measurement elements.
- // Be careful about multiple MR elements within one frames.
- while (Length > 0)
- {
- pReqElem = (PRM_REQUEST_ACTION) pData;
- switch (pReqElem->ReqElem.Eid)
- {
- case IE_MEASUREMENT_REQUEST:
- // From the example, it seems we only need to support one request in one frame
- // There is no multiple request in one frame.
- // Besides, looks like we need to take care the measurement request only.
- // The measurement request is always 4 bytes.
-
- // Start parsing this type of request.
- // 0. Eid is IE_MEASUREMENT_REQUEST
- // 1. Length didn't include Eid and Length field, it always be 8.
- // 2. Measurement Token, we nned to save it for the corresponding report.
- // 3. Measurement Mode, Although there are definitions, but we din't see value other than
- // 0 from test specs examples.
- // 4. Measurement Type, this is what we need to do.
- switch (pReqElem->ReqElem.Type)
- {
- case MSRN_TYPE_CHANNEL_LOAD_REQ:
- case MSRN_TYPE_NOISE_HIST_REQ:
- case MSRN_TYPE_BEACON_REQ:
- // Check the Enable non-serving channel measurement control
- if (pAd->StaCfg.CCXControl.field.DCRMEnable == 0)
- {
- // Check channel before enqueue the action
- if (pReqElem->Measurement.Channel != pAd->CommonCfg.Channel)
- break;
- }
- else
- {
- // If off channel measurement, check the TU duration limit
- if (pReqElem->Measurement.Channel != pAd->CommonCfg.Channel)
- if (pReqElem->Measurement.Duration > pAd->StaCfg.CCXControl.field.TuLimit)
- break;
- }
-
- // Save requests and execute actions later
- NdisMoveMemory(&pAd->StaCfg.MeasurementRequest[Index], pReqElem, sizeof(RM_REQUEST_ACTION));
- Index += 1;
- break;
-
- case MSRN_TYPE_FRAME_REQ:
- // Since it's option, we will support later
- // FrameRequestAction(pAd, pData);
- break;
-
- default:
- break;
- }
-
- // Point to next Measurement request
- pData += sizeof(RM_REQUEST_ACTION);
- Length -= sizeof(RM_REQUEST_ACTION);
- break;
-
- // We accept request only, all others are dropped
- case IE_MEASUREMENT_REPORT:
- case IE_AP_TX_POWER:
- case IE_MEASUREMENT_CAPABILITY:
- default:
- return;
- }
- }
-
- // 11. Update some flags and index
- pAd->StaCfg.RMReqCnt = Index;
-
- if (Index)
- {
- MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_REQ, 0, NULL);
- RT28XX_MLME_HANDLER(pAd);
- }
-
- DBGPRINT(RT_DEBUG_TRACE, ("<----- AironetMsgAction\n"));
-}
-
-/*
- ========================================================================
-
- Routine Description:
-
- Arguments:
-
- Return Value:
- None
-
- Note:
-
- ========================================================================
-*/
-VOID AironetRequestAction(
- IN PRTMP_ADAPTER pAd,
- IN MLME_QUEUE_ELEM *Elem)
-{
- PRM_REQUEST_ACTION pReq;
-
- // 1. Point to next request element
- pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[pAd->StaCfg.CurrentRMReqIdx];
-
- // 2. Parse measurement type and call appropriate functions
- if (pReq->ReqElem.Type == MSRN_TYPE_CHANNEL_LOAD_REQ)
- // Channel Load measurement request
- ChannelLoadRequestAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
- else if (pReq->ReqElem.Type == MSRN_TYPE_NOISE_HIST_REQ)
- // Noise Histogram measurement request
- NoiseHistRequestAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
- else if (pReq->ReqElem.Type == MSRN_TYPE_BEACON_REQ)
- // Beacon measurement request
- BeaconRequestAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
- else
- // Unknown. Do nothing and return, this should never happen
- return;
-
- // 3. Peek into the next request, if it's parallel, we will update the scan time to the largest one
- if ((pAd->StaCfg.CurrentRMReqIdx + 1) < pAd->StaCfg.RMReqCnt)
- {
- pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[pAd->StaCfg.CurrentRMReqIdx + 1];
- // Check for parallel bit
- if ((pReq->ReqElem.Mode & 0x01) && (pReq->Measurement.Channel == pAd->StaCfg.CCXScanChannel))
- {
- // Update parallel mode request information
- pAd->StaCfg.ParallelReq = TRUE;
- pAd->StaCfg.CCXScanTime = ((pReq->Measurement.Duration > pAd->StaCfg.CCXScanTime) ?
- (pReq->Measurement.Duration) : (pAd->StaCfg.CCXScanTime));
- }
- }
-
- // 4. Call RT28XX_MLME_HANDLER to execute the request mlme commands, Scan request is the only one used
- RT28XX_MLME_HANDLER(pAd);
-
-}
-
-
-/*
- ========================================================================
-
- Routine Description:
- Prepare channel load report action, special scan operation added
- to support
-
- Arguments:
- pAd Pointer to our adapter
- pData Start from element ID
-
- Return Value:
- None
-
- Note:
-
- ========================================================================
-*/
-VOID ChannelLoadRequestAction(
- IN PRTMP_ADAPTER pAd,
- IN UCHAR Index)
-{
- PRM_REQUEST_ACTION pReq;
- MLME_SCAN_REQ_STRUCT ScanReq;
- UCHAR ZeroSsid[32];
- NDIS_STATUS NStatus;
- PUCHAR pOutBuffer = NULL;
- PHEADER_802_11 pNullFrame;
-
- DBGPRINT(RT_DEBUG_TRACE, ("ChannelLoadRequestAction ----->\n"));
-
- pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[Index];
- NdisZeroMemory(ZeroSsid, 32);
-
- // Prepare for special scan request
- // The scan definition is different with our Active, Passive scan definition.
- // For CCX2, Active means send out probe request with broadcast BSSID.
- // Passive means no probe request sent, only listen to the beacons.
- // The channel scanned is fixed as specified, no need to scan all channels.
- // The scan wait time is specified in the request too.
- // Passive scan Mode
-
- // Control state machine is not idle, reject the request
- if ((pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) && (Index == 0))
- return;
-
- // Fill out stuff for scan request
- ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_CISCO_CHANNEL_LOAD);
- MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
- pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
-
- // Reset some internal control flags to make sure this scan works.
- BssTableInit(&pAd->StaCfg.CCXBssTab);
- pAd->StaCfg.ScanCnt = 0;
- pAd->StaCfg.CCXScanChannel = pReq->Measurement.Channel;
- pAd->StaCfg.CCXScanTime = pReq->Measurement.Duration;
-
- DBGPRINT(RT_DEBUG_TRACE, ("Duration %d, Channel %d!\n", pReq->Measurement.Duration, pReq->Measurement.Channel));
-
- // If it's non serving channel scan, send out a null frame with PSM bit on.
- if (pAd->StaCfg.CCXScanChannel != pAd->CommonCfg.Channel)
- {
- // Use MLME enqueue method
- NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory
- if (NStatus != NDIS_STATUS_SUCCESS)
- return;
-
- pNullFrame = (PHEADER_802_11) pOutBuffer;;
- // Make the power save Null frame with PSM bit on
- MgtMacHeaderInit(pAd, pNullFrame, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
- pNullFrame->Duration = 0;
- pNullFrame->FC.Type = BTYPE_DATA;
- pNullFrame->FC.PwrMgmt = PWR_SAVE;
-
- // Send using priority queue
- MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
- MlmeFreeMemory(pAd, pOutBuffer);
- DBGPRINT(RT_DEBUG_TRACE, ("Send PSM Data frame for off channel RM\n"));
- RTMPusecDelay(5000);
- }
-
- pAd->StaCfg.CCXReqType = MSRN_TYPE_CHANNEL_LOAD_REQ;
- pAd->StaCfg.CLBusyBytes = 0;
- // Enable Rx with promiscuous reception
- RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, 0x1010);
-
- // Set channel load measurement flag
- RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_MEASUREMENT);
-
- pAd->Mlme.AironetMachine.CurrState = AIRONET_SCANNING;
-
- DBGPRINT(RT_DEBUG_TRACE, ("ChannelLoadRequestAction <-----\n"));
-}
-
-/*
- ========================================================================
-
- Routine Description:
- Prepare noise histogram report action, special scan operation added
- to support
-
- Arguments:
- pAd Pointer to our adapter
- pData Start from element ID
-
- Return Value:
- None
-
- Note:
-
- ========================================================================
-*/
-VOID NoiseHistRequestAction(
- IN PRTMP_ADAPTER pAd,
- IN UCHAR Index)
-{
- PRM_REQUEST_ACTION pReq;
- MLME_SCAN_REQ_STRUCT ScanReq;
- UCHAR ZeroSsid[32], i;
- NDIS_STATUS NStatus;
- PUCHAR pOutBuffer = NULL;
- PHEADER_802_11 pNullFrame;
-
- DBGPRINT(RT_DEBUG_TRACE, ("NoiseHistRequestAction ----->\n"));
-
- pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[Index];
- NdisZeroMemory(ZeroSsid, 32);
-
- // Prepare for special scan request
- // The scan definition is different with our Active, Passive scan definition.
- // For CCX2, Active means send out probe request with broadcast BSSID.
- // Passive means no probe request sent, only listen to the beacons.
- // The channel scanned is fixed as specified, no need to scan all channels.
- // The scan wait time is specified in the request too.
- // Passive scan Mode
-
- // Control state machine is not idle, reject the request
- if ((pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) && (Index == 0))
- return;
-
- // Fill out stuff for scan request
- ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_CISCO_NOISE);
- MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
- pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
-
- // Reset some internal control flags to make sure this scan works.
- BssTableInit(&pAd->StaCfg.CCXBssTab);
- pAd->StaCfg.ScanCnt = 0;
- pAd->StaCfg.CCXScanChannel = pReq->Measurement.Channel;
- pAd->StaCfg.CCXScanTime = pReq->Measurement.Duration;
- pAd->StaCfg.CCXReqType = MSRN_TYPE_NOISE_HIST_REQ;
-
- DBGPRINT(RT_DEBUG_TRACE, ("Duration %d, Channel %d!\n", pReq->Measurement.Duration, pReq->Measurement.Channel));
-
- // If it's non serving channel scan, send out a null frame with PSM bit on.
- if (pAd->StaCfg.CCXScanChannel != pAd->CommonCfg.Channel)
- {
- // Use MLME enqueue method
- NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory
- if (NStatus != NDIS_STATUS_SUCCESS)
- return;
-
- pNullFrame = (PHEADER_802_11) pOutBuffer;
- // Make the power save Null frame with PSM bit on
- MgtMacHeaderInit(pAd, pNullFrame, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
- pNullFrame->Duration = 0;
- pNullFrame->FC.Type = BTYPE_DATA;
- pNullFrame->FC.PwrMgmt = PWR_SAVE;
-
- // Send using priority queue
- MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
- MlmeFreeMemory(pAd, pOutBuffer);
- DBGPRINT(RT_DEBUG_TRACE, ("Send PSM Data frame for off channel RM\n"));
- RTMPusecDelay(5000);
- }
-
- // Reset the statistics
- for (i = 0; i < 8; i++)
- pAd->StaCfg.RPIDensity[i] = 0;
-
- // Enable Rx with promiscuous reception
- RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, 0x1010);
-
- // Set channel load measurement flag
- RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_MEASUREMENT);
-
- pAd->Mlme.AironetMachine.CurrState = AIRONET_SCANNING;
-
- DBGPRINT(RT_DEBUG_TRACE, ("NoiseHistRequestAction <-----\n"));
-}
-
-/*
- ========================================================================
-
- Routine Description:
- Prepare Beacon report action, special scan operation added
- to support
-
- Arguments:
- pAd Pointer to our adapter
- pData Start from element ID
-
- Return Value:
- None
-
- Note:
-
- ========================================================================
-*/
-VOID BeaconRequestAction(
- IN PRTMP_ADAPTER pAd,
- IN UCHAR Index)
-{
- PRM_REQUEST_ACTION pReq;
- NDIS_STATUS NStatus;
- PUCHAR pOutBuffer = NULL;
- PHEADER_802_11 pNullFrame;
- MLME_SCAN_REQ_STRUCT ScanReq;
- UCHAR ZeroSsid[32];
-
- DBGPRINT(RT_DEBUG_TRACE, ("BeaconRequestAction ----->\n"));
-
- pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[Index];
- NdisZeroMemory(ZeroSsid, 32);
-
- // Prepare for special scan request
- // The scan definition is different with our Active, Passive scan definition.
- // For CCX2, Active means send out probe request with broadcast BSSID.
- // Passive means no probe request sent, only listen to the beacons.
- // The channel scanned is fixed as specified, no need to scan all channels.
- // The scan wait time is specified in the request too.
- if (pReq->Measurement.ScanMode == MSRN_SCAN_MODE_PASSIVE)
- {
- // Passive scan Mode
- DBGPRINT(RT_DEBUG_TRACE, ("Passive Scan Mode!\n"));
-
- // Control state machine is not idle, reject the request
- if ((pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) && (Index == 0))
- return;
-
- // Fill out stuff for scan request
- ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_CISCO_PASSIVE);
- MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
- pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
-
- // Reset some internal control flags to make sure this scan works.
- BssTableInit(&pAd->StaCfg.CCXBssTab);
- pAd->StaCfg.ScanCnt = 0;
- pAd->StaCfg.CCXScanChannel = pReq->Measurement.Channel;
- pAd->StaCfg.CCXScanTime = pReq->Measurement.Duration;
- pAd->StaCfg.CCXReqType = MSRN_TYPE_BEACON_REQ;
- DBGPRINT(RT_DEBUG_TRACE, ("Duration %d!\n", pReq->Measurement.Duration));
-
- // If it's non serving channel scan, send out a null frame with PSM bit on.
- if (pAd->StaCfg.CCXScanChannel != pAd->CommonCfg.Channel)
- {
- // Use MLME enqueue method
- NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory
- if (NStatus != NDIS_STATUS_SUCCESS)
- return;
-
- pNullFrame = (PHEADER_802_11) pOutBuffer;
- // Make the power save Null frame with PSM bit on
- MgtMacHeaderInit(pAd, pNullFrame, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
- pNullFrame->Duration = 0;
- pNullFrame->FC.Type = BTYPE_DATA;
- pNullFrame->FC.PwrMgmt = PWR_SAVE;
-
- // Send using priority queue
- MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
- MlmeFreeMemory(pAd, pOutBuffer);
- DBGPRINT(RT_DEBUG_TRACE, ("Send PSM Data frame for off channel RM\n"));
- RTMPusecDelay(5000);
- }
-
- pAd->Mlme.AironetMachine.CurrState = AIRONET_SCANNING;
- }
- else if (pReq->Measurement.ScanMode == MSRN_SCAN_MODE_ACTIVE)
- {
- // Active scan Mode
- DBGPRINT(RT_DEBUG_TRACE, ("Active Scan Mode!\n"));
-
- // Control state machine is not idle, reject the request
- if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE)
- return;
-
- // Fill out stuff for scan request
- ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_CISCO_ACTIVE);
- MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
- pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
-
- // Reset some internal control flags to make sure this scan works.
- BssTableInit(&pAd->StaCfg.CCXBssTab);
- pAd->StaCfg.ScanCnt = 0;
- pAd->StaCfg.CCXScanChannel = pReq->Measurement.Channel;
- pAd->StaCfg.CCXScanTime = pReq->Measurement.Duration;
- pAd->StaCfg.CCXReqType = MSRN_TYPE_BEACON_REQ;
- DBGPRINT(RT_DEBUG_TRACE, ("Duration %d!\n", pReq->Measurement.Duration));
-
- // If it's non serving channel scan, send out a null frame with PSM bit on.
- if (pAd->StaCfg.CCXScanChannel != pAd->CommonCfg.Channel)
- {
- // Use MLME enqueue method
- NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory
- if (NStatus != NDIS_STATUS_SUCCESS)
- return;
-
- pNullFrame = (PHEADER_802_11) pOutBuffer;
- // Make the power save Null frame with PSM bit on
- MgtMacHeaderInit(pAd, pNullFrame, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
- pNullFrame->Duration = 0;
- pNullFrame->FC.Type = BTYPE_DATA;
- pNullFrame->FC.PwrMgmt = PWR_SAVE;
-
- // Send using priority queue
- MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
- MlmeFreeMemory(pAd, pOutBuffer);
- DBGPRINT(RT_DEBUG_TRACE, ("Send PSM Data frame for off channel RM\n"));
- RTMPusecDelay(5000);
- }
-
- pAd->Mlme.AironetMachine.CurrState = AIRONET_SCANNING;
- }
- else if (pReq->Measurement.ScanMode == MSRN_SCAN_MODE_BEACON_TABLE)
- {
- // Beacon report Mode, report all the APS in current bss table
- DBGPRINT(RT_DEBUG_TRACE, ("Beacon Report Mode!\n"));
-
- // Copy current BSS table to CCX table, we can omit this step later on.
- NdisMoveMemory(&pAd->StaCfg.CCXBssTab, &pAd->ScanTab, sizeof(BSS_TABLE));
-
- // Create beacon report from Bss table
- AironetCreateBeaconReportFromBssTable(pAd);
-
- // Set state to scanning
- pAd->Mlme.AironetMachine.CurrState = AIRONET_SCANNING;
-
- // Enqueue report request
- // Cisco scan request is finished, prepare beacon report
- MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_DONE, 0, NULL);
- }
- else
- {
- // Wrong scan Mode
- DBGPRINT(RT_DEBUG_TRACE, ("Wrong Scan Mode!\n"));
- }
-
- DBGPRINT(RT_DEBUG_TRACE, ("BeaconRequestAction <-----\n"));
-}
-
-/*
- ========================================================================
-
- Routine Description:
-
- Arguments:
-
- Return Value:
- None
-
- Note:
-
- ========================================================================
-*/
-VOID AironetReportAction(
- IN PRTMP_ADAPTER pAd,
- IN MLME_QUEUE_ELEM *Elem)
-{
- PRM_REQUEST_ACTION pReq;
- ULONG Now32;
-
- NdisGetSystemUpTime(&Now32);
- pAd->StaCfg.LastBeaconRxTime = Now32;
-
- pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[pAd->StaCfg.CurrentRMReqIdx];
-
- DBGPRINT(RT_DEBUG_TRACE, ("AironetReportAction ----->\n"));
-
- // 1. Parse measurement type and call appropriate functions
- if (pReq->ReqElem.Type == MSRN_TYPE_CHANNEL_LOAD_REQ)
- // Channel Load measurement request
- ChannelLoadReportAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
- else if (pReq->ReqElem.Type == MSRN_TYPE_NOISE_HIST_REQ)
- // Noise Histogram measurement request
- NoiseHistReportAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
- else if (pReq->ReqElem.Type == MSRN_TYPE_BEACON_REQ)
- // Beacon measurement request
- BeaconReportAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
- else
- // Unknown. Do nothing and return
- ;
-
- // 2. Point to the correct index of action element, start from 0
- pAd->StaCfg.CurrentRMReqIdx++;
-
- // 3. Check for parallel actions
- if (pAd->StaCfg.ParallelReq == TRUE)
- {
- pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[pAd->StaCfg.CurrentRMReqIdx];
-
- // Process next action right away
- if (pReq->ReqElem.Type == MSRN_TYPE_CHANNEL_LOAD_REQ)
- // Channel Load measurement request
- ChannelLoadReportAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
- else if (pReq->ReqElem.Type == MSRN_TYPE_NOISE_HIST_REQ)
- // Noise Histogram measurement request
- NoiseHistReportAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
-
- pAd->StaCfg.ParallelReq = FALSE;
- pAd->StaCfg.CurrentRMReqIdx++;
- }
-
- if (pAd->StaCfg.CurrentRMReqIdx >= pAd->StaCfg.RMReqCnt)
- {
- // 4. There is no more unprocessed measurement request, go for transmit this report
- AironetFinalReportAction(pAd);
- pAd->Mlme.AironetMachine.CurrState = AIRONET_IDLE;
- }
- else
- {
- pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[pAd->StaCfg.CurrentRMReqIdx];
-
- if (pReq->Measurement.Channel != pAd->CommonCfg.Channel)
- {
- RTMPusecDelay(100000);
- }
-
- // 5. There are more requests to be measure
- MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_REQ, 0, NULL);
- RT28XX_MLME_HANDLER(pAd);
- }
-
- DBGPRINT(RT_DEBUG_TRACE, ("AironetReportAction <-----\n"));
-}
-
-/*
- ========================================================================
-
- Routine Description:
-
- Arguments:
-
- Return Value:
- None
-
- Note:
-
- ========================================================================
-*/
-VOID AironetFinalReportAction(
- IN PRTMP_ADAPTER pAd)
-{
- PUCHAR pDest;
- PAIRONET_IAPP_HEADER pIAPP;
- PHEADER_802_11 pHeader;
- UCHAR AckRate = RATE_2;
- USHORT AckDuration = 0;
- NDIS_STATUS NStatus;
- PUCHAR pOutBuffer = NULL;
- ULONG FrameLen = 0;
-
- DBGPRINT(RT_DEBUG_TRACE, ("AironetFinalReportAction ----->\n"));
-
- // 0. Set up the frame pointer, Frame was inited at the end of message action
- pDest = &pAd->StaCfg.FrameReportBuf[LENGTH_802_11];
-
- // 1. Update report IAPP fields
- pIAPP = (PAIRONET_IAPP_HEADER) pDest;
-
- // 2. Copy Cisco SNAP header
- NdisMoveMemory(pIAPP->CiscoSnapHeader, SNAP_AIRONET, LENGTH_802_1_H);
-
- // 3. network order for this 16bit length
- pIAPP->Length = cpu2be16(pAd->StaCfg.FrameReportLen - LENGTH_802_11 - LENGTH_802_1_H);
-
- // 3.1 sanity check the report length, ignore it if there is nothing to report
- if (be2cpu16(pIAPP->Length) <= 18)
- return;
-
- // 4. Type must be 0x32
- pIAPP->Type = AIRONET_IAPP_TYPE;
-
- // 5. SubType for report must be 0x81
- pIAPP->SubType = AIRONET_IAPP_SUBTYPE_REPORT;
-
- // 6. DA is not used and must be zero, although the whole frame was cleared at the start of function
- // We will do it again here. We can use BSSID instead
- COPY_MAC_ADDR(pIAPP->DA, pAd->CommonCfg.Bssid);
-
- // 7. SA is the client reporting which must be our MAC
- COPY_MAC_ADDR(pIAPP->SA, pAd->CurrentAddress);
-
- // 8. Copy the saved dialog token
- pIAPP->Token = pAd->StaCfg.IAPPToken;
-
- // 9. Make the Report frame 802.11 header
- // Reuse function in wpa.c
- pHeader = (PHEADER_802_11) pAd->StaCfg.FrameReportBuf;
- pAd->Sequence ++;
- WpaMacHeaderInit(pAd, pHeader, 0, pAd->CommonCfg.Bssid);
-
- // ACK size is 14 include CRC, and its rate is based on real time information
- AckRate = pAd->CommonCfg.ExpectedACKRate[pAd->CommonCfg.MlmeRate];
- AckDuration = RTMPCalcDuration(pAd, AckRate, 14);
- pHeader->Duration = pAd->CommonCfg.Dsifs + AckDuration;
-
- // Use MLME enqueue method
- NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
- if (NStatus != NDIS_STATUS_SUCCESS)
- return;
-
- // 10. Prepare report frame with dynamic outbuffer. Just simply copy everything.
- MakeOutgoingFrame(pOutBuffer, &FrameLen,
- pAd->StaCfg.FrameReportLen, pAd->StaCfg.FrameReportBuf,
- END_OF_ARGS);
-
- // 11. Send using priority queue
- MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
- MlmeFreeMemory(pAd, pOutBuffer);
-
- pAd->StaCfg.CCXReqType = MSRN_TYPE_UNUSED;
-
- DBGPRINT(RT_DEBUG_TRACE, ("AironetFinalReportAction <-----\n"));
-}
-
-/*
- ========================================================================
-
- Routine Description:
-
- Arguments:
-
- Return Value:
- None
-
- Note:
-
- ========================================================================
-*/
-VOID ChannelLoadReportAction(
- IN PRTMP_ADAPTER pAd,
- IN UCHAR Index)
-{
- PMEASUREMENT_REPORT_ELEMENT pReport;
- PCHANNEL_LOAD_REPORT pLoad;
- PUCHAR pDest;
- UCHAR CCABusyFraction;
-
- DBGPRINT(RT_DEBUG_TRACE, ("ChannelLoadReportAction ----->\n"));
-
- // Disable Rx with promiscuous reception, make it back to normal
- RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, STANORMAL); // Staion not drop control frame will fail WiFi Certification.
-
- // 0. Setup pointer for processing beacon & probe response
- pDest = (PUCHAR) &pAd->StaCfg.FrameReportBuf[pAd->StaCfg.FrameReportLen];
- pReport = (PMEASUREMENT_REPORT_ELEMENT) pDest;
-
- // 1. Fill Measurement report element field.
- pReport->Eid = IE_MEASUREMENT_REPORT;
- // Fixed Length at 9, not include Eid and length fields
- pReport->Length = 9;
- pReport->Token = pAd->StaCfg.MeasurementRequest[Index].ReqElem.Token;
- pReport->Mode = pAd->StaCfg.MeasurementRequest[Index].ReqElem.Mode;
- pReport->Type = MSRN_TYPE_CHANNEL_LOAD_REQ;
-
- // 2. Fill channel report measurement data
- pDest += sizeof(MEASUREMENT_REPORT_ELEMENT);
- pLoad = (PCHANNEL_LOAD_REPORT) pDest;
- pLoad->Channel = pAd->StaCfg.MeasurementRequest[Index].Measurement.Channel;
- pLoad->Spare = 0;
- pLoad->Duration = pAd->StaCfg.MeasurementRequest[Index].Measurement.Duration;
-
- // 3. Calculate the CCA Busy Fraction
- // (Bytes + ACK size) * 8 / Tx speed * 255 / 1000 / measurement duration, use 24 us Tx speed
- // = (Bytes + ACK) / 12 / duration
- // 9 is the good value for pAd->StaCfg.CLFactor
- // CCABusyFraction = (UCHAR) (pAd->StaCfg.CLBusyBytes / 9 / pLoad->Duration);
- CCABusyFraction = (UCHAR) (pAd->StaCfg.CLBusyBytes / pAd->StaCfg.CLFactor / pLoad->Duration);
- if (CCABusyFraction < 10)
- CCABusyFraction = (UCHAR) (pAd->StaCfg.CLBusyBytes / 3 / pLoad->Duration) + 1;
-
- pLoad->CCABusy = CCABusyFraction;
- DBGPRINT(RT_DEBUG_TRACE, ("CLBusyByte %ld, Duration %d, Result, %d\n", pAd->StaCfg.CLBusyBytes, pLoad->Duration, CCABusyFraction));
-
- DBGPRINT(RT_DEBUG_TRACE, ("FrameReportLen %d\n", pAd->StaCfg.FrameReportLen));
- pAd->StaCfg.FrameReportLen += (sizeof(MEASUREMENT_REPORT_ELEMENT) + sizeof(CHANNEL_LOAD_REPORT));
- DBGPRINT(RT_DEBUG_TRACE, ("FrameReportLen %d\n", pAd->StaCfg.FrameReportLen));
-
- // 4. Clear channel load measurement flag
- RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_MEASUREMENT);
-
- // 5. reset to idle state
- pAd->Mlme.AironetMachine.CurrState = AIRONET_IDLE;
-
- DBGPRINT(RT_DEBUG_TRACE, ("ChannelLoadReportAction <-----\n"));
-}
-
-/*
- ========================================================================
-
- Routine Description:
-
- Arguments:
-
- Return Value:
- None
-
- Note:
-
- ========================================================================
-*/
-VOID NoiseHistReportAction(
- IN PRTMP_ADAPTER pAd,
- IN UCHAR Index)
-{
- PMEASUREMENT_REPORT_ELEMENT pReport;
- PNOISE_HIST_REPORT pNoise;
- PUCHAR pDest;
- UCHAR i,NoiseCnt;
- USHORT TotalRPICnt, TotalRPISum;
-
- DBGPRINT(RT_DEBUG_TRACE, ("NoiseHistReportAction ----->\n"));
-
- // 0. Disable Rx with promiscuous reception, make it back to normal
- RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, STANORMAL); // Staion not drop control frame will fail WiFi Certification.
- // 1. Setup pointer for processing beacon & probe response
- pDest = (PUCHAR) &pAd->StaCfg.FrameReportBuf[pAd->StaCfg.FrameReportLen];
- pReport = (PMEASUREMENT_REPORT_ELEMENT) pDest;
-
- // 2. Fill Measurement report element field.
- pReport->Eid = IE_MEASUREMENT_REPORT;
- // Fixed Length at 16, not include Eid and length fields
- pReport->Length = 16;
- pReport->Token = pAd->StaCfg.MeasurementRequest[Index].ReqElem.Token;
- pReport->Mode = pAd->StaCfg.MeasurementRequest[Index].ReqElem.Mode;
- pReport->Type = MSRN_TYPE_NOISE_HIST_REQ;
-
- // 3. Fill noise histogram report measurement data
- pD