Ejemplo n.º 1
0
/*
	==========================================================================
	Description:
		Scan next channel
	==========================================================================
 */
VOID ScanNextChannel(
	IN PRTMP_ADAPTER pAd,
	IN UCHAR OpMode) 
{
	UCHAR ScanType = pAd->MlmeAux.ScanType;
	UINT ScanTimeIn5gChannel = SHORT_CHANNEL_TIME;
	BOOLEAN ScanPending = FALSE;
	RALINK_TIMER_STRUCT *sc_timer;
	UINT stay_time = 0;
			

#ifdef RALINK_ATE
	/* Nothing to do in ATE mode. */
	if (ATE_ON(pAd))
		return;
#endif /* RALINK_ATE */


#ifdef CONFIG_STA_SUPPORT
	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
	{
		if (MONITOR_ON(pAd))
			return;
	}

	ScanPending = ((pAd->StaCfg.bImprovedScan) && (pAd->StaCfg.ScanChannelCnt>=7));
#endif /* CONFIG_STA_SUPPORT */

#ifdef RT_CFG80211_SUPPORT
#ifdef CONFIG_STA_SUPPORT
                if ( (pAd->pCfg80211ChanList != NULL) && (pAd->MlmeAux.Channel != 0))
                {
                        UINT32 ChanId;
                        for ( ChanId = 0 ; ChanId <pAd->Cfg80211ChanListLan ; ChanId++ )
                        {
                                if ( pAd->pCfg80211ChanList[ChanId] >= pAd->MlmeAux.Channel )
                                {
                                        pAd->MlmeAux.Channel = pAd->pCfg80211ChanList[ChanId];
                                        break;
                                }
                        }

                }
#endif /* CONFIG_STA_SUPPORT */
#endif /* RT_CFG80211_SUPPORT */

	if ((pAd->MlmeAux.Channel == 0) || ScanPending) 
	{
		scan_ch_restore(pAd, OpMode);
	} 
#ifdef RTMP_MAC_USB
#ifdef CONFIG_STA_SUPPORT
	else if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) &&
		(OpMode == OPMODE_STA))
	{
		pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
		MlmeCntlConfirm(pAd, MT2_SCAN_CONF, MLME_FAIL_NO_RESOURCE);
	}	
#endif /* CONFIG_STA_SUPPORT */
#endif /* RTMP_MAC_USB */
	else 
	{
#ifdef CONFIG_STA_SUPPORT
		if (OpMode == OPMODE_STA)
		{
			/* BBP and RF are not accessible in PS mode, we has to wake them up first*/
			if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
				AsicForceWakeup(pAd, TRUE);

			/* leave PSM during scanning. otherwise we may lost ProbeRsp & BEACON*/
			if (pAd->StaCfg.Psm == PWR_SAVE)
				RTMP_SET_PSM_BIT(pAd, PWR_ACTIVE);
		}
#endif /* CONFIG_STA_SUPPORT */

		AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, TRUE);
		AsicLockChannel(pAd, pAd->MlmeAux.Channel);

#ifdef CONFIG_STA_SUPPORT
		if (OpMode == OPMODE_STA)
		{
			BOOLEAN bScanPassive = FALSE;
			if (pAd->MlmeAux.Channel > 14)
			{
				if ((pAd->CommonCfg.bIEEE80211H == 1)
					&& RadarChannelCheck(pAd, pAd->MlmeAux.Channel))
					bScanPassive = TRUE;
			}
#ifdef CARRIER_DETECTION_SUPPORT
			if (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
				bScanPassive = TRUE;
#endif /* CARRIER_DETECTION_SUPPORT */ 

			if (bScanPassive)
			{
				ScanType = SCAN_PASSIVE;
				ScanTimeIn5gChannel = MIN_CHANNEL_TIME;
			}
		}

#endif /* CONFIG_STA_SUPPORT */

		/* Check if channel if passive scan under current regulatory domain */
		if (CHAN_PropertyCheck(pAd, pAd->MlmeAux.Channel, CHANNEL_PASSIVE_SCAN) == TRUE)
			ScanType = SCAN_PASSIVE;


		if (OpMode == OPMODE_AP)
			sc_timer = &pAd->MlmeAux.APScanTimer;
		else
			sc_timer = &pAd->MlmeAux.ScanTimer;
			
		/* We need to shorten active scan time in order for WZC connect issue */
		/* Chnage the channel scan time for CISCO stuff based on its IAPP announcement */
		if (ScanType == FAST_SCAN_ACTIVE)
			stay_time = FAST_ACTIVE_SCAN_TIME;
		else /* must be SCAN_PASSIVE or SCAN_ACTIVE*/
		{
#ifdef CONFIG_STA_SUPPORT
			pAd->StaCfg.ScanChannelCnt++;
#endif /* CONFIG_STA_SUPPORT */

#ifdef CONFIG_AP_SUPPORT
			if ((OpMode == OPMODE_AP) && (pAd->ApCfg.bAutoChannelAtBootup))
				stay_time = AUTO_CHANNEL_SEL_TIMEOUT;
			else
#endif /* CONFIG_AP_SUPPORT */
			if (WMODE_CAP_2G(pAd->CommonCfg.PhyMode) &&
				WMODE_CAP_5G(pAd->CommonCfg.PhyMode))
			{
				if (pAd->MlmeAux.Channel > 14)
					stay_time = ScanTimeIn5gChannel;
				else
					stay_time = MIN_CHANNEL_TIME;
			}
			else
				stay_time = MAX_CHANNEL_TIME;
		}
				
		RTMPSetTimer(sc_timer, stay_time);
			
		if (SCAN_MODE_ACT(ScanType))
		{
			if (scan_active(pAd, OpMode, ScanType) == FALSE)
				return;
		}

		/* For SCAN_CISCO_PASSIVE, do nothing and silently wait for beacon or other probe reponse*/
		
#ifdef CONFIG_STA_SUPPORT
		if (OpMode == OPMODE_STA)
			pAd->Mlme.SyncMachine.CurrState = SCAN_LISTEN;
#endif /* CONFIG_STA_SUPPORT */
#ifdef CONFIG_AP_SUPPORT
		if (OpMode == OPMODE_AP)
			pAd->Mlme.ApSyncMachine.CurrState = AP_SCAN_LISTEN;
#endif /* CONFIG_AP_SUPPORT */
	}
}
Ejemplo n.º 2
0
/*
	==========================================================================
	Description:
		Scan next channel
	==========================================================================
 */
void ScanNextChannel(struct rt_rtmp_adapter *pAd)
{
	struct rt_header_802_11 Hdr80211;
	u8 *pOutBuffer = NULL;
	int NStatus;
	unsigned long FrameLen = 0;
	u8 SsidLen = 0, ScanType = pAd->MlmeAux.ScanType, BBPValue = 0;
	u16 Status;
	struct rt_header_802_11 * pHdr80211;
	u32 ScanTimeIn5gChannel = SHORT_CHANNEL_TIME;

	{
		if (MONITOR_ON(pAd))
			return;
	}

	if (pAd->MlmeAux.Channel == 0) {
		if ((pAd->CommonCfg.BBPCurrentBW == BW_40)
		    && (INFRA_ON(pAd)
			|| (pAd->OpMode == OPMODE_AP))
		    ) {
			AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel,
					  FALSE);
			AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
			BBPValue &= (~0x18);
			BBPValue |= 0x10;
			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
			DBGPRINT(RT_DEBUG_TRACE,
				 ("SYNC - End of SCAN, restore to 40MHz channel %d, Total BSS[%02d]\n",
				  pAd->CommonCfg.CentralChannel,
				  pAd->ScanTab.BssNr));
		} else {
			AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
			AsicLockChannel(pAd, pAd->CommonCfg.Channel);
			DBGPRINT(RT_DEBUG_TRACE,
				 ("SYNC - End of SCAN, restore to channel %d, Total BSS[%02d]\n",
				  pAd->CommonCfg.Channel, pAd->ScanTab.BssNr));
		}

		{
			/* */
			/* To prevent data lost. */
			/* Send an NULL data with turned PSM bit on to current associated AP before SCAN progress. */
			/* Now, we need to send an NULL data with turned PSM bit off to AP, when scan progress done */
			/* */
			if (OPSTATUS_TEST_FLAG
			    (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
			    && (INFRA_ON(pAd))) {
				NStatus =
				    MlmeAllocateMemory(pAd,
						       (void *)& pOutBuffer);
				if (NStatus == NDIS_STATUS_SUCCESS) {
					pHdr80211 = (struct rt_header_802_11 *) pOutBuffer;
					MgtMacHeaderInit(pAd, pHdr80211,
							 SUBTYPE_NULL_FUNC, 1,
							 pAd->CommonCfg.Bssid,
							 pAd->CommonCfg.Bssid);
					pHdr80211->Duration = 0;
					pHdr80211->FC.Type = BTYPE_DATA;
					pHdr80211->FC.PwrMgmt =
					    (pAd->StaCfg.Psm == PWR_SAVE);

					/* Send using priority queue */
					MiniportMMRequest(pAd, 0, pOutBuffer,
							  sizeof
							  (struct rt_header_802_11));
					DBGPRINT(RT_DEBUG_TRACE,
						 ("MlmeScanReqAction -- Send PSM Data frame\n"));
					MlmeFreeMemory(pAd, pOutBuffer);
					RTMPusecDelay(5000);
				}
			}

			pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
			Status = MLME_SUCCESS;
			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF,
				    2, &Status);
		}

		RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
	}
#ifdef RTMP_MAC_USB
	else if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)
		 && (pAd->OpMode == OPMODE_STA)) {
		pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
		MlmeCntlConfirm(pAd, MT2_SCAN_CONF, MLME_FAIL_NO_RESOURCE);
	}
#endif /* RTMP_MAC_USB // */
	else {
		{
			/* BBP and RF are not accessible in PS mode, we has to wake them up first */
			if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
				AsicForceWakeup(pAd, TRUE);

			/* leave PSM during scanning. otherwise we may lost ProbeRsp & BEACON */
			if (pAd->StaCfg.Psm == PWR_SAVE)
				RTMP_SET_PSM_BIT(pAd, PWR_ACTIVE);
		}

		AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, TRUE);
		AsicLockChannel(pAd, pAd->MlmeAux.Channel);

		{
			if (pAd->MlmeAux.Channel > 14) {
				if ((pAd->CommonCfg.bIEEE80211H == 1)
				    && RadarChannelCheck(pAd,
							 pAd->MlmeAux.
							 Channel)) {
					ScanType = SCAN_PASSIVE;
					ScanTimeIn5gChannel = MIN_CHANNEL_TIME;
				}
			}
		}

		/*Global country domain(ch1-11:active scan, ch12-14 passive scan) */
		if ((pAd->MlmeAux.Channel <= 14) && (pAd->MlmeAux.Channel >= 12)
		    && ((pAd->CommonCfg.CountryRegion & 0x7f) ==
			REGION_31_BG_BAND)) {
			ScanType = SCAN_PASSIVE;
		}
		/* We need to shorten active scan time in order for WZC connect issue */
		/* Chnage the channel scan time for CISCO stuff based on its IAPP announcement */
		if (ScanType == FAST_SCAN_ACTIVE)
			RTMPSetTimer(&pAd->MlmeAux.ScanTimer,
				     FAST_ACTIVE_SCAN_TIME);
		else		/* must be SCAN_PASSIVE or SCAN_ACTIVE */
		{
			if ((pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED)
			    || (pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED)
			    || (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED)
			    ) {
				if (pAd->MlmeAux.Channel > 14)
					RTMPSetTimer(&pAd->MlmeAux.ScanTimer,
						     ScanTimeIn5gChannel);
				else
					RTMPSetTimer(&pAd->MlmeAux.ScanTimer,
						     MIN_CHANNEL_TIME);
			} else
				RTMPSetTimer(&pAd->MlmeAux.ScanTimer,
					     MAX_CHANNEL_TIME);
		}

		if ((ScanType == SCAN_ACTIVE)
		    || (ScanType == FAST_SCAN_ACTIVE)
		    ) {
			NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	/*Get an unused nonpaged memory */
			if (NStatus != NDIS_STATUS_SUCCESS) {
				DBGPRINT(RT_DEBUG_TRACE,
					 ("SYNC - ScanNextChannel() allocate memory fail\n"));

				{
					pAd->Mlme.SyncMachine.CurrState =
					    SYNC_IDLE;
					Status = MLME_FAIL_NO_RESOURCE;
					MlmeEnqueue(pAd,
						    MLME_CNTL_STATE_MACHINE,
						    MT2_SCAN_CONF, 2, &Status);
				}

				return;
			}
			/* There is no need to send broadcast probe request if active scan is in effect. */
			if ((ScanType == SCAN_ACTIVE)
			    || (ScanType == FAST_SCAN_ACTIVE)
			    )
				SsidLen = pAd->MlmeAux.SsidLen;
			else
				SsidLen = 0;

			MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0,
					 BROADCAST_ADDR, BROADCAST_ADDR);
			MakeOutgoingFrame(pOutBuffer, &FrameLen,
					  sizeof(struct rt_header_802_11), &Hdr80211, 1,
					  &SsidIe, 1, &SsidLen, SsidLen,
					  pAd->MlmeAux.Ssid, 1, &SupRateIe, 1,
					  &pAd->CommonCfg.SupRateLen,
					  pAd->CommonCfg.SupRateLen,
					  pAd->CommonCfg.SupRate, END_OF_ARGS);

			if (pAd->CommonCfg.ExtRateLen) {
				unsigned long Tmp;
				MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
						  1, &ExtRateIe,
						  1, &pAd->CommonCfg.ExtRateLen,
						  pAd->CommonCfg.ExtRateLen,
						  pAd->CommonCfg.ExtRate,
						  END_OF_ARGS);
				FrameLen += Tmp;
			}

			if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) {
				unsigned long Tmp;
				u8 HtLen;
				u8 BROADCOM[4] = { 0x0, 0x90, 0x4c, 0x33 };

				if (pAd->bBroadComHT == TRUE) {
					HtLen =
					    pAd->MlmeAux.HtCapabilityLen + 4;

					MakeOutgoingFrame(pOutBuffer + FrameLen,
							  &Tmp, 1, &WpaIe, 1,
							  &HtLen, 4,
							  &BROADCOM[0],
							  pAd->MlmeAux.
							  HtCapabilityLen,
							  &pAd->MlmeAux.
							  HtCapability,
							  END_OF_ARGS);
				} else {
					HtLen = pAd->MlmeAux.HtCapabilityLen;

					MakeOutgoingFrame(pOutBuffer + FrameLen,
							  &Tmp, 1, &HtCapIe, 1,
							  &HtLen, HtLen,
							  &pAd->CommonCfg.
							  HtCapability,
							  END_OF_ARGS);
				}
				FrameLen += Tmp;
			}

			MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
			MlmeFreeMemory(pAd, pOutBuffer);
		}
		/* For SCAN_CISCO_PASSIVE, do nothing and silently wait for beacon or other probe reponse */

		pAd->Mlme.SyncMachine.CurrState = SCAN_LISTEN;
	}
}