Пример #1
0
VOID RtmpPsModeChange(
	IN PRTMP_ADAPTER		pAd,
	IN UINT32				PsMode)
{
	if (pAd->StaCfg.BssType == BSS_INFRA)
	{
		/* reset ps mode */
		if (PsMode == Ndis802_11PowerModeMAX_PSP)
		{
			// do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
			// to exclude certain situations.
			//	   MlmeSetPsm(pAd, PWR_SAVE);
			OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
			if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
				pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeMAX_PSP;
			pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeMAX_PSP;
			pAd->StaCfg.DefaultListenCount = 5;
		}							
		else if (PsMode == Ndis802_11PowerModeFast_PSP)
		{
			// do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
			// to exclude certain situations.
			OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
			if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
				pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeFast_PSP;
			pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeFast_PSP;
			pAd->StaCfg.DefaultListenCount = 3;
		}
		else if (PsMode == Ndis802_11PowerModeLegacy_PSP)
		{
			// do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
			// to exclude certain situations.
			OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
			if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
				pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeLegacy_PSP;
			pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeLegacy_PSP;
#ifdef DOT11Z_TDLS_SUPPORT
			pAd->StaCfg.DefaultListenCount = 1;
#else
			pAd->StaCfg.DefaultListenCount = 3;
#endif // DOT11Z_TDLS_SUPPORT //
		}
		else
		{ //Default Ndis802_11PowerModeCAM
			// clear PSM bit immediately
			RTMP_SET_PSM_BIT(pAd, PWR_ACTIVE);
			OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
			if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
				pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM;
			pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM;
		}

		/* change ps mode */
		RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE, FALSE);

		DBGPRINT(RT_DEBUG_TRACE, ("PSMode=%ld\n", pAd->StaCfg.WindowsPowerMode));
	}
}
Пример #2
0
static INT scan_active(RTMP_ADAPTER *pAd, UCHAR OpMode, UCHAR ScanType)
{
	UCHAR *frm_buf = NULL;
	HEADER_802_11 Hdr80211;
	ULONG FrameLen = 0;
	UCHAR SsidLen = 0;
#ifdef CONFIG_STA_SUPPORT
	USHORT Status;
#endif /* CONFIG_STA_SUPPORT */


	if (MlmeAllocateMemory(pAd, &frm_buf) != NDIS_STATUS_SUCCESS)
	{
		DBGPRINT(RT_DEBUG_TRACE, ("SYNC - ScanNextChannel() allocate memory fail\n"));
#ifdef CONFIG_STA_SUPPORT
		if (OpMode == OPMODE_STA)
		{
			pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
			Status = MLME_FAIL_NO_RESOURCE;
			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status, 0);
		}
#endif /* CONFIG_STA_SUPPORT */

#ifdef CONFIG_AP_SUPPORT
		if (OpMode == OPMODE_AP)
			pAd->Mlme.ApSyncMachine.CurrState = AP_SYNC_IDLE;
#endif /* CONFIG_AP_SUPPORT */
		return FALSE;
	}

#ifdef DOT11_N_SUPPORT
#ifdef DOT11N_DRAFT3
	if (ScanType == SCAN_2040_BSS_COEXIST)
	{
		DBGPRINT(RT_DEBUG_INFO, ("SYNC - SCAN_2040_BSS_COEXIST !! Prepare to send Probe Request\n"));
	}
#endif /* DOT11N_DRAFT3 */
#endif /* DOT11_N_SUPPORT */
	
	/* There is no need to send broadcast probe request if active scan is in effect.*/
	SsidLen = 0;
	if ((ScanType == SCAN_ACTIVE) || (ScanType == FAST_SCAN_ACTIVE)
#ifdef WSC_STA_SUPPORT
		|| ((ScanType == SCAN_WSC_ACTIVE) && (OpMode == OPMODE_STA))
#endif /* WSC_STA_SUPPORT */
		)
		SsidLen = pAd->MlmeAux.SsidLen;

#ifdef P2P_SUPPORT
	if ((pAd->MlmeAux.ScanType == SCAN_P2P) || (pAd->MlmeAux.ScanType == SCAN_P2P_SEARCH)
#ifdef P2P_APCLI_SUPPORT
		 || ((pAd->MlmeAux.ScanType == SCAN_WSC_ACTIVE) && (OpMode == OPMODE_AP) && (P2P_CLI_ON(pAd)))
#endif /* P2P_APCLI_SUPPORT */
	)
	{
		PRT_P2P_CONFIG pP2PCtrl = &pAd->P2pCfg;
		UCHAR		SupRate[MAX_LEN_OF_SUPPORTED_RATES];
		UCHAR		SupRateLen = 0;

		SsidLen = WILDP2PSSIDLEN; /* Use Wildword SSID */
		SupRate[0]	= 0x8C;    /* 6 mbps, in units of 0.5 Mbps, basic rate */
		SupRate[1]	= 0x12;    /* 9 mbps, in units of 0.5 Mbps */
		SupRate[2]	= 0x98;    /* 12 mbps, in units of 0.5 Mbps, basic rate */
		SupRate[3]	= 0x24;    /* 18 mbps, in units of 0.5 Mbps */
		SupRate[4]	= 0xb0;    /* 24 mbps, in units of 0.5 Mbps, basic rate */
		SupRate[5]	= 0x48;    /* 36 mbps, in units of 0.5 Mbps */
		SupRate[6]	= 0x60;    /* 48 mbps, in units of 0.5 Mbps */
		SupRate[7]	= 0x6c;    /* 54 mbps, in units of 0.5 Mbps */
		SupRateLen	= 8;
		/* P2P scan must use P2P mac address. */
		MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR,
							pP2PCtrl->CurrentAddress,
							BROADCAST_ADDR);

		MakeOutgoingFrame(frm_buf,				&FrameLen,
							sizeof(HEADER_802_11),	&Hdr80211,
							1,						&SsidIe,
							1,						&SsidLen,
							SsidLen,					&WILDP2PSSID[0],
							1,						&SupRateIe,
							1,						&SupRateLen,
							SupRateLen, 			SupRate, 
							END_OF_ARGS);
	}
	else
#endif /* P2P_SUPPORT */
	{
#ifdef CONFIG_AP_SUPPORT
		/*IF_DEV_CONFIG_OPMODE_ON_AP(pAd) */
		if (OpMode == OPMODE_AP)
		{
			MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, 
#ifdef P2P_SUPPORT
								pAd->ApCfg.MBSSID[0].Bssid,
#endif /* P2P_SUPPORT */
								pAd->ApCfg.MBSSID[0].Bssid);
		}
#endif /* CONFIG_AP_SUPPORT */
#ifdef CONFIG_STA_SUPPORT
		/*IF_DEV_CONFIG_OPMODE_ON_STA(pAd) */
		if (OpMode == OPMODE_STA)
		{
			MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, 
#ifdef P2P_SUPPORT
								pAd->CurrentAddress,
#endif /* P2P_SUPPORT */
								BROADCAST_ADDR);
		}
#endif /* CONFIG_STA_SUPPORT */

		MakeOutgoingFrame(frm_buf,               &FrameLen,
						  sizeof(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)
		{
			ULONG Tmp;
			MakeOutgoingFrame(frm_buf + FrameLen,            &Tmp,
							  1,                                &ExtRateIe,
							  1,                                &pAd->CommonCfg.ExtRateLen,
							  pAd->CommonCfg.ExtRateLen,          pAd->CommonCfg.ExtRate, 
							  END_OF_ARGS);
			FrameLen += Tmp;
		}
	}
#ifdef DOT11_N_SUPPORT
	if (WMODE_CAP_N(pAd->CommonCfg.PhyMode))
	{
		ULONG	Tmp;
		UCHAR	HtLen;
		UCHAR	BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33};
#ifdef RT_BIG_ENDIAN
		HT_CAPABILITY_IE HtCapabilityTmp;
#endif
		if (pAd->bBroadComHT == TRUE)
		{
			HtLen = pAd->MlmeAux.HtCapabilityLen + 4;
#ifdef RT_BIG_ENDIAN
			NdisMoveMemory(&HtCapabilityTmp, &pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE);
			*(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
#ifdef UNALIGNMENT_SUPPORT
			{
				EXT_HT_CAP_INFO extHtCapInfo;

				NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO));
				*(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo));
				NdisMoveMemory((PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO));		
			}
#else				
			*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = cpu2le16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
#endif /* UNALIGNMENT_SUPPORT */

			MakeOutgoingFrame(frm_buf + FrameLen,          &Tmp,
							1,                                &WpaIe,
							1,                                &HtLen,
							4,                                &BROADCOM[0],
							pAd->MlmeAux.HtCapabilityLen,     &HtCapabilityTmp, 
							END_OF_ARGS);
#else
			MakeOutgoingFrame(frm_buf + FrameLen,          &Tmp,
							1,                                &WpaIe,
							1,                                &HtLen,
							4,                                &BROADCOM[0],
							pAd->MlmeAux.HtCapabilityLen,     &pAd->MlmeAux.HtCapability, 
							END_OF_ARGS);
#endif /* RT_BIG_ENDIAN */
		}
		else				
		{
			HtLen = sizeof(HT_CAPABILITY_IE);
#ifdef RT_BIG_ENDIAN
			NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, SIZE_HT_CAP_IE);
			*(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
#ifdef UNALIGNMENT_SUPPORT
			{
				EXT_HT_CAP_INFO extHtCapInfo;

				NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO));
				*(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo));
				NdisMoveMemory((PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO));		
			}
#else				
			*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = cpu2le16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
#endif /* UNALIGNMENT_SUPPORT */

			MakeOutgoingFrame(frm_buf + FrameLen,          &Tmp,
							1,                                &HtCapIe,
							1,                                &HtLen,
							HtLen,                            &HtCapabilityTmp, 
							END_OF_ARGS);
#else
			MakeOutgoingFrame(frm_buf + FrameLen,          &Tmp,
							1,                                &HtCapIe,
							1,                                &HtLen,
							HtLen,                            &pAd->CommonCfg.HtCapability, 
							END_OF_ARGS);
#endif /* RT_BIG_ENDIAN */
		}
		FrameLen += Tmp;

#ifdef DOT11N_DRAFT3
		if ((pAd->MlmeAux.Channel <= 14) && (pAd->CommonCfg.bBssCoexEnable == TRUE))
		{
			ULONG Tmp;
			HtLen = 1;
			MakeOutgoingFrame(frm_buf + FrameLen,            &Tmp,
							  1,					&ExtHtCapIe,
							  1,					&HtLen,
							  1,          			&pAd->CommonCfg.BSSCoexist2040.word, 
							  END_OF_ARGS);

			FrameLen += Tmp;
		}
#endif /* DOT11N_DRAFT3 */
	}
#endif /* DOT11_N_SUPPORT */

#ifdef DOT11_VHT_AC
	if (WMODE_CAP_AC(pAd->CommonCfg.PhyMode) &&
		(pAd->MlmeAux.Channel > 14)) {		
		FrameLen += build_vht_ies(pAd, (UCHAR *)(frm_buf + FrameLen), SUBTYPE_PROBE_REQ);
	}
#endif /* DOT11_VHT_AC */

#ifdef WSC_STA_SUPPORT
	if (OpMode == OPMODE_STA)
	{
		BOOLEAN bHasWscIe = FALSE;
		/* 
			Append WSC information in probe request if WSC state is running
		*/
		if ((pAd->StaCfg.WscControl.WscEnProbeReqIE) && 
			(pAd->StaCfg.WscControl.WscConfMode != WSC_DISABLE) &&
			(pAd->StaCfg.WscControl.bWscTrigger == TRUE))
			bHasWscIe = TRUE;
#ifdef WSC_V2_SUPPORT
		else if ((pAd->StaCfg.WscControl.WscEnProbeReqIE) && 
			(pAd->StaCfg.WscControl.WscV2Info.bEnableWpsV2))
			bHasWscIe = TRUE;
#endif /* WSC_V2_SUPPORT */

#ifdef P2P_SUPPORT
	/* 
		P2pMakeProbeReqIE will build WSC IE for P2P, 
		it is not good to append normal WSC IE into P2P probe request frame here.
	*/
	if ((pAd->MlmeAux.ScanType == SCAN_P2P) || (pAd->MlmeAux.ScanType == SCAN_P2P_SEARCH) ||
		((pAd->MlmeAux.ScanType == SCAN_WSC_ACTIVE) && (OpMode == OPMODE_AP) && (P2P_CLI_ON(pAd))))
		bHasWscIe = FALSE;
#endif /* P2P_SUPPORT */

		if (bHasWscIe)
		{
			UCHAR *pWscBuf = NULL, WscIeLen = 0;
			ULONG WscTmpLen = 0;

			os_alloc_mem(NULL, (UCHAR **)&pWscBuf, 512);
			if (pWscBuf != NULL)
			{
				NdisZeroMemory(pWscBuf, 512);
				WscBuildProbeReqIE(pAd, STA_MODE, pWscBuf, &WscIeLen);

				MakeOutgoingFrame(frm_buf + FrameLen,              &WscTmpLen,
								WscIeLen,                             pWscBuf,
								END_OF_ARGS);

				FrameLen += WscTmpLen;
				os_free_mem(NULL, pWscBuf);
			}
			else
				DBGPRINT(RT_DEBUG_WARN, ("%s:: WscBuf Allocate failed!\n", __FUNCTION__));
		}
	}

#endif /* WSC_STA_SUPPORT */

#ifdef WPA_SUPPLICANT_SUPPORT
	if ((OpMode == OPMODE_STA) &&
		(pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) &&
		(pAd->StaCfg.WpsProbeReqIeLen != 0))
	{
		ULONG 		WpsTmpLen = 0;
		
		MakeOutgoingFrame(frm_buf + FrameLen,              &WpsTmpLen,
						pAd->StaCfg.WpsProbeReqIeLen,	pAd->StaCfg.pWpsProbeReqIe,
						END_OF_ARGS);

		FrameLen += WpsTmpLen;
	}
#endif /* WPA_SUPPLICANT_SUPPORT */

#ifdef P2P_SUPPORT
	if ((pAd->MlmeAux.ScanType == SCAN_P2P) || (pAd->MlmeAux.ScanType == SCAN_P2P_SEARCH)
#ifdef P2P_APCLI_SUPPORT
		|| ((pAd->MlmeAux.ScanType == SCAN_WSC_ACTIVE) && (OpMode == OPMODE_AP) && (P2P_CLI_ON(pAd)))
#endif /* P2P_APCLI_SUPPORT */
	)
	{
		ULONG P2PIeLen;
		UCHAR tmp_len;
		PUCHAR ptr;
		ptr = frm_buf + FrameLen;
		P2pMakeProbeReqIE(pAd, ptr, &tmp_len);
		FrameLen += tmp_len;
		
		/* Put P2P IE to the last. */
		ptr = frm_buf + FrameLen;
		P2pMakeP2pIE(pAd, SUBTYPE_PROBE_REQ, ptr, &P2PIeLen);

		FrameLen += P2PIeLen;
	}

#endif /* P2P_SUPPORT */

	MiniportMMRequest(pAd, 0, frm_buf, FrameLen);

#ifdef CONFIG_STA_SUPPORT
	if (OpMode == OPMODE_STA)
	{
		/*
			To prevent data lost.
			Send an NULL data with turned PSM bit on to current associated AP when SCAN in the channel where
			associated AP located.
		*/
		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && 
			(INFRA_ON(pAd)) &&
			(pAd->CommonCfg.Channel == pAd->MlmeAux.Channel))
		{
			RTMPSendNullFrame(pAd, 
						  pAd->CommonCfg.TxRate, 
						  (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) ? TRUE:FALSE),
						  PWR_SAVE);
			DBGPRINT(RT_DEBUG_TRACE, ("ScanNextChannel():Send PWA NullData frame to notify the associated AP!\n"));
		}
	}

#if 0//def RT_CFG80211_SUPPORT                                      
                if (pAd->ApCfg.ApCliTab[MAIN_MBSSID].Valid && RTMP_CFG80211_VIF_P2P_CLI_ON(pAd) 
			&& (pAd->CommonCfg.Channel == pAd->MlmeAux.Channel))
		{
                
			DBGPRINT(RT_DEBUG_TRACE, ("CFG80211_NULL: PWR_SAVE SCANNING\n"));
			RT_CFG80211_P2P_CLI_SEND_NULL_FRAME(pAd, PWR_SAVE);
		}
#endif /* RT_CFG80211_SUPPORT */

#endif /* CONFIG_STA_SUPPORT */

	MlmeFreeMemory(pAd, frm_buf);

	return TRUE;
}
Пример #3
0
static INT scan_ch_restore(RTMP_ADAPTER *pAd, UCHAR OpMode)
{
#ifdef CONFIG_STA_SUPPORT
	USHORT Status;
#endif /* CONFIG_STA_SUPPORT */
	INT bw, ch;
		
	if (pAd->CommonCfg.BBPCurrentBW != pAd->hw_cfg.bbp_bw)
	{	
		rtmp_bbp_set_bw(pAd, pAd->hw_cfg.bbp_bw);

		AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
		AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);

		ch = pAd->CommonCfg.CentralChannel;
	}
	else
	{
		AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
		AsicLockChannel(pAd, pAd->CommonCfg.Channel);
		ch = pAd->CommonCfg.Channel;

	}

	switch(pAd->CommonCfg.BBPCurrentBW)
	{
		case BW_80:
			bw = 80;
			break;
		case BW_40:
			bw = 40;
			break;
		case BW_10:
			bw = 10;
			break;
		case BW_20:
		default:
			bw =20;
			break;
	}
	DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to %dMHz channel %d, Total BSS[%02d]\n",
				bw, ch, pAd->ScanTab.BssNr));
		
#ifdef CONFIG_STA_SUPPORT
	if (OpMode == OPMODE_STA)
	{
		/*
		If all peer Ad-hoc clients leave, driver would do LinkDown and LinkUp.
		In LinkUp, CommonCfg.Ssid would copy SSID from MlmeAux. 
		To prevent SSID is zero or wrong in Beacon, need to recover MlmeAux.SSID here.
		*/
		if (ADHOC_ON(pAd))
		{
			NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
			pAd->MlmeAux.SsidLen = pAd->CommonCfg.SsidLen;
			NdisMoveMemory(pAd->MlmeAux.Ssid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen);
		}


		/*
		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)))
		{
			RTMPSendNullFrame(pAd, 
								pAd->CommonCfg.TxRate, 
								(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) ? TRUE:FALSE),
								pAd->CommonCfg.bAPSDForcePowerSave ? PWR_SAVE : pAd->StaCfg.Psm);
			DBGPRINT(RT_DEBUG_TRACE, ("%s -- Send null frame\n", __FUNCTION__));
		}

#ifdef RT_CFG80211_SUPPORT                                      
                if (pAd->ApCfg.ApCliTab[MAIN_MBSSID].Valid && RTMP_CFG80211_VIF_P2P_CLI_ON(pAd))
		{	
			DBGPRINT(RT_DEBUG_TRACE, ("CFG80211_NULL: PWR_ACTIVE SCAN_END\n"));
			RT_CFG80211_P2P_CLI_SEND_NULL_FRAME(pAd, PWR_ACTIVE);
		}

#endif /* RT_CFG80211_SUPPORT */
		

		/* keep the latest scan channel, could be 0 for scan complete, or other channel*/
		pAd->StaCfg.LastScanChannel = pAd->MlmeAux.Channel;

		pAd->StaCfg.ScanChannelCnt = 0;

		/* Suspend scanning and Resume TxData for Fast Scanning*/
		if ((pAd->MlmeAux.Channel != 0) &&
		(pAd->StaCfg.bImprovedScan))	/* it is scan pending*/
		{
			pAd->Mlme.SyncMachine.CurrState = SCAN_PENDING;
			Status = MLME_SUCCESS;
			DBGPRINT(RT_DEBUG_WARN, ("bFastRoamingScan ~~~ Get back to send data ~~~\n"));

			RTMPResumeMsduTransmission(pAd);
		}
		else
		{
			pAd->StaCfg.BssNr = pAd->ScanTab.BssNr;
			pAd->StaCfg.bImprovedScan = FALSE;

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

	}
#endif /* CONFIG_STA_SUPPORT */

#ifdef CONFIG_AP_SUPPORT
	if (OpMode == OPMODE_AP)
	{
#ifdef P2P_APCLI_SUPPORT
		/* P2P CLIENT in WSC Scan or Re-Connect scanning. */
		if (P2P_CLI_ON(pAd) && (ApScanRunning(pAd) == TRUE))
		{
			/*MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_JOIN_REQ_TIMEOUT, 0, NULL, 0);*/
			DBGPRINT(RT_DEBUG_INFO, ("%s::  Scan Done! reset APCLI CTRL State Machine!\n", __FUNCTION__));
			pAd->ApCfg.ApCliTab[0].CtrlCurrState = APCLI_CTRL_DISCONNECTED;
		}
#endif /* P2P_APCLI_SUPPORT */

		pAd->Mlme.ApSyncMachine.CurrState = AP_SYNC_IDLE;
		RTMPResumeMsduTransmission(pAd);

		/* iwpriv set auto channel selection*/
		/* scanned all channels*/
		if (pAd->ApCfg.bAutoChannelAtBootup==TRUE)
		{
			pAd->CommonCfg.Channel = SelectBestChannel(pAd, pAd->ApCfg.AutoChannelAlg);
			pAd->ApCfg.bAutoChannelAtBootup = FALSE;
#ifdef DOT11_N_SUPPORT
			N_ChannelCheck(pAd);
#endif /* DOT11_N_SUPPORT */
			APStop(pAd);
			APStartUp(pAd);
		}

		if (!((pAd->CommonCfg.Channel > 14) && (pAd->CommonCfg.bIEEE80211H == TRUE)))
			AsicEnableBssSync(pAd);
	}
#endif /* CONFIG_AP_SUPPORT */


	return TRUE;
}
Пример #4
0
VOID CFG80211_SwitchTxChannel(RTMP_ADAPTER *pAd, ULONG Data)
{
	//UCHAR lock_channel = CFG80211_getCenCh(pAd, Data);
	UCHAR lock_channel = Data;

#ifdef CONFIG_MULTI_CHANNEL

#ifdef RT_CFG80211_P2P_SUPPORT
	UINT apidx = CFG_GO_BSSID_IDX;
#else
	UINT apidx = MAIN_MBSSID;
#endif /*RT_CFG80211_P2P_SUPPORT*/
	PMULTISSID_STRUCT pMbss = &pAd->ApCfg.MBSSID[apidx];
	struct wifi_dev *wdev = &pMbss->wdev;


	if ((pAd->MCC_InfraConnect_Protect == TRUE) || (pAd->Mlme.bStartMcc == TRUE) || (pAd->MCC_GOConnect_Protect == TRUE))
	{
//		DBGPRINT(RT_DEBUG_TRACE, ("Connecting Or MCC Enabled, Do not switch channel for Tx  lock_channel %d \n",lock_channel));
		return;
	}
	if(pAd->Mlme.bStartScc == TRUE)
	{
//		DBGPRINT(RT_DEBUG_TRACE, ("SCC Enabled, Do not switch channel for Tx  %d\n",lock_channel));
		return;
	}

#if 1
	if (RTMP_CFG80211_VIF_P2P_GO_ON(pAd) && (wdev->channel == lock_channel) && (wdev->bw==1))
	{
		DBGPRINT(RT_DEBUG_TRACE, ("40 BW Enabled || GO enable , wait for CLI connect, Do not switch channel for Tx\n"));
		DBGPRINT(RT_DEBUG_TRACE, ("GO wdev->channel  %d  lock_channel %d \n",wdev->channel,lock_channel));

		return;
	}
#endif
#endif /* CONFIG_MULTI_CHANNEL */


#ifdef CONFIG_MULTI_CHANNEL
	if (INFRA_ON(pAd) &&
	   	     (((pAd->LatchRfRegs.Channel != pAd->StaCfg.wdev.CentralChannel) && (pAd->StaCfg.wdev.CentralChannel != 0))) 
	   	     || (pAd->LatchRfRegs.Channel != lock_channel)
	   	     )
#else /* CONFIG_MULTI_CHANNEL */
	if (RTMP_GetPrimaryCh(pAd, pAd->LatchRfRegs.Channel) != lock_channel)
#endif /* CONFIG_MULTI_CHANNEL */
	{

		if (INFRA_ON(pAd))	
		{
    		DBGPRINT(RT_DEBUG_TRACE, ("CFG80211_NULL: STA PWR_SAVE ROC_START\n"));
			RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, 
				  (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) ? TRUE:FALSE),
				  PWR_SAVE);				
		}	

		DBGPRINT(RT_DEBUG_TRACE, ("Off-Channel Send Packet: From(%d)-To(%d)\n", 
					pAd->LatchRfRegs.Channel, lock_channel));

		if(pAd->CommonCfg.BBPCurrentBW != BW_20)
		bbp_set_bw(pAd, BW_20);

		AsicSwitchChannel(pAd, lock_channel, FALSE);
		AsicLockChannel(pAd, lock_channel);
		
	}
	else
		DBGPRINT(RT_DEBUG_INFO, ("Off-Channel Channel Equal: %d\n", pAd->LatchRfRegs.Channel));

}
Пример #5
0
static int usb_rtusb_close(struct net_device *net_dev)
{
	PRTMP_ADAPTER   pAd = (PRTMP_ADAPTER)  RTMP_OS_NETDEV_GET_PRIV(net_dev);
	int	            i = 0;
	MLME_DISASSOC_REQ_STRUCT DisReq;
	MLME_QUEUE_ELEM          MsgElem;
	wait_queue_head_t wait;

//	if (!pAd->ProbeFinish)
//		return -1;

	init_waitqueue_head(&wait);

	DBGPRINT(RT_DEBUG_TRACE, "%s-->\n", __FUNCTION__);

	netif_carrier_off(pAd->net_dev);
	netif_stop_queue(pAd->net_dev);

	if (INFRA_ON(pAd))
	{
		COPY_MAC_ADDR(DisReq.Addr, pAd->PortCfg.Bssid);
		DisReq.Reason =  REASON_DISASSOC_STA_LEAVING;

		MsgElem.Machine = ASSOC_STATE_MACHINE;
		MsgElem.MsgType = MT2_MLME_DISASSOC_REQ;
		MsgElem.MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT);
		NdisMoveMemory(MsgElem.Msg, &DisReq, sizeof(MLME_DISASSOC_REQ_STRUCT));

		MlmeDisassocReqAction(pAd, &MsgElem);
		wait_event_interruptible_timeout(wait,0,HZ/1000);
	}

	VIRTUAL_IF_DEC(pAd);
	if (VIRTUAL_IF_NUM(pAd) == 0)
	{
		for(i=0;i<10 || pAd->CmdHandlerIsRunning==TRUE;i++)
			wait_event_interruptible_timeout(wait,0,HZ/1000);
		
		for(i=0;i<10 || pAd->Mlme.bRunning==TRUE;i++)
			wait_event_interruptible_timeout(wait,0,HZ/1000);

		//
		// Patch to fully turn off BBP, need to send a fake NULL frame.
		//
		RTUSBWriteMACRegister(pAd, MAC_CSR10, 0x0018);
		for (i=0; i<10; i++)
		{
			RTMPSendNullFrame(pAd, RATE_6);
			RTMPusecDelay(1000);
		}
			

		AsicDisableSync(pAd);
		
		RTMPSetLED(pAd, LED_HALT);
		atomic_set(&pAd->PendingRx, 0);
	}

#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
{
	// TODO: Shall we send wireless event to notfiy user space that if-down??
}
#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
	module_put(THIS_MODULE);
#else
	MOD_DEC_USE_COUNT;
#endif

	DBGPRINT(RT_DEBUG_TRACE, "%s<--\n", __FUNCTION__);
	return 0;
}
/*
==========================================================================
	Description:

	IRQL = PASSIVE_LEVEL
==========================================================================
*/
VOID
TDLS_PeerChannelSwitchRspAction(
    IN PRTMP_ADAPTER pAd,
    IN MLME_QUEUE_ELEM *Elem)
{
    PRT_802_11_TDLS		pTDLS = NULL;
    int					LinkId = 0xff;
    UCHAR				PeerAddr[MAC_ADDR_LEN];
    //BOOLEAN				IsInitator;
    BOOLEAN				TimerCancelled;
    //UCHAR				RegulatoryClass;
    //UCHAR				NewExtChannelOffset = 0xff;
    UCHAR				LinkIdentLen;
    USHORT				PeerChSwitchTime;
    USHORT				PeerChSwitchTimeOut;
    TDLS_LINK_IDENT_ELEMENT	LinkIdent;
    //NDIS_STATUS			NStatus = NDIS_STATUS_SUCCESS;
    USHORT				StatusCode = MLME_SUCCESS;

    DBGPRINT(RT_DEBUG_WARN,("TDLS ===> TDLS_PeerChannelSwitchRspAction() \n"));

    // Not TDLS Capable, ignore it
    if (!IS_TDLS_SUPPORT(pAd))
        return;

    if (!INFRA_ON(pAd))
        return;

    hex_dump("TDLS peer channel switch response receive pack", Elem->Msg, Elem->MsgLen);

    if (!PeerTdlsChannelSwitchRspSanity(pAd,
                                        Elem->Msg,
                                        Elem->MsgLen,
                                        PeerAddr,
                                        &StatusCode,
                                        &PeerChSwitchTime,
                                        &PeerChSwitchTimeOut,
                                        &LinkIdentLen,
                                        &LinkIdent))
    {
        DBGPRINT(RT_DEBUG_ERROR,("%s(%d):  from %02x:%02x:%02x:%02x:%02x:%02x Sanity Check Fail !!!\n",
                                 __FUNCTION__,__LINE__, PeerAddr[0], PeerAddr[1], PeerAddr[2], PeerAddr[3], PeerAddr[4], PeerAddr[5]));
        return;
    }

    // Drop not within my TDLS Table that created before !
    LinkId = TDLS_SearchLinkId(pAd, PeerAddr);
    if (LinkId == -1 || LinkId == MAX_NUM_OF_TDLS_ENTRY)
    {
        DBGPRINT(RT_DEBUG_ERROR,("%s(%d):  can not find from %02x:%02x:%02x:%02x:%02x:%02x on TDLS entry !!!\n",
                                 __FUNCTION__,__LINE__, PeerAddr[0], PeerAddr[1], PeerAddr[2], PeerAddr[3], PeerAddr[4], PeerAddr[5]));
        return;
    }

    // Point to the current Link ID
    pTDLS = &pAd->StaCfg.TdlsInfo.TDLSEntry[LinkId];

    if ((pTDLS->ChannelSwitchCurrentState == TDLS_CHANNEL_SWITCH_NONE) &&
            (StatusCode == MLME_REQUEST_DECLINED))
    {
        DBGPRINT(RT_DEBUG_OFF,("%s(%d): received a failed StatusCode = %d on Unsolicited response !!!\n",
                               __FUNCTION__, __LINE__, StatusCode));
        return;
    }

    if (StatusCode == MLME_REQUEST_DECLINED)
    {
        if ((pAd->StaCfg.TdlsChannelSwitchRetryCount > 0) &&
                (pTDLS->bDoingPeriodChannelSwitch) &&
                (pAd->StaCfg.bDoingPeriodChannelSwitch))
        {
            pAd->StaCfg.TdlsChannelSwitchRetryCount--;

            DBGPRINT(RT_DEBUG_OFF,("%s(%d): received a failed StatusCode = %d  re-try again !!!\n",
                                   __FUNCTION__, __LINE__, StatusCode));
        }
        else
        {
            pTDLS->bDoingPeriodChannelSwitch = FALSE;
            pAd->StaCfg.bDoingPeriodChannelSwitch = FALSE;
            pAd->StaCfg.bTdlsNoticeAPPowerSave = FALSE;
            pAd->StaCfg.TdlsForcePowerSaveWithAP = FALSE;
            RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE, FALSE);
        }

        DBGPRINT(RT_DEBUG_OFF,("TDLS - TDLS_PeerChannelSwitchRspAction() received a failed StatusCode = %d !!!\n", StatusCode ));
        return;
    }

    DBGPRINT(RT_DEBUG_WARN,("%s(%d):  from %02x:%02x:%02x:%02x:%02x:%02x !!!\n",
                            __FUNCTION__,__LINE__, PeerAddr[0], PeerAddr[1], PeerAddr[2], PeerAddr[3], PeerAddr[4], PeerAddr[5]));



    if (StatusCode == MLME_SUCCESS)
    {
        if (pTDLS->ChannelSwitchCurrentState == TDLS_CHANNEL_SWITCH_NONE)
        {
            if (pAd->StaCfg.bChannelSwitchInitiator == FALSE)
            {
                RTMPCancelTimer(&pAd->StaCfg.TdlsResponderGoBackBaseChTimer, &TimerCancelled);
                DBGPRINT(RT_DEBUG_WARN,("%s(%d): i am responder!!!\n",  __FUNCTION__,__LINE__));
            }
            else
            {
                RTMPCancelTimer(&pAd->StaCfg.TdlsPeriodGoBackBaseChTimer, &TimerCancelled);
                DBGPRINT(RT_DEBUG_WARN,("%s(%d): i am Initiator !!!\n", __FUNCTION__,__LINE__));
            }

            if (pAd->StaCfg.TdlsCurrentOperateChannel != pAd->CommonCfg.Channel)
            {
                DBGPRINT(RT_DEBUG_ERROR, ("106. %ld !!!\n", (jiffies * 1000) / OS_HZ));

                RTMPusecDelay(300);
                NdisGetSystemUpTime(&pAd->StaCfg.TdlsGoBackStartTime);

                RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_TDLS_DOING_CHANNEL_SWITCH);
                if (pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel)
                    TDLS_InitChannelRelatedValue(pAd, pAd->CommonCfg.Channel, EXTCHA_ABOVE);
                else if (pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel)
                    TDLS_InitChannelRelatedValue(pAd, pAd->CommonCfg.Channel, EXTCHA_BELOW);
                else
                    TDLS_InitChannelRelatedValue(pAd, pAd->CommonCfg.Channel, EXTCHA_NONE);
                TDLS_EnablePktChannel(pAd, TDLS_FIFO_ALL);
                RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_TDLS_DOING_CHANNEL_SWITCH);
            }
        }
        else
        {
            if (pAd->StaCfg.TdlsCurrentChannel != pAd->CommonCfg.Channel)
            {
                if (pAd->StaCfg.bChannelSwitchInitiator)
                {
                    UINT16 SwitchTime = pAd->StaCfg.TdlsInfo.TdlsSwitchTime; //micro seconds
                    UINT16 SwitchTimeout = pAd->StaCfg.TdlsInfo.TdlsSwitchTimeout; // micro seconds

                    pAd->StaCfg.TdlsChannelSwitchPairCount--;
                    pAd->StaCfg.TdlsChannelSwitchRetryCount = 10;
                    //pAd->StaCfg.bDoingPeriodChannelSwitch = TRUE;

                    if (SwitchTime >= PeerChSwitchTime)
                        PeerChSwitchTime = SwitchTime;

                    if (SwitchTimeout >= PeerChSwitchTimeOut)
                        PeerChSwitchTimeOut = SwitchTimeout;

                    pTDLS->ChSwitchTime = PeerChSwitchTime;
                    pAd->StaCfg.TdlsGlobalSwitchTime = PeerChSwitchTime;
                    pTDLS->ChSwitchTimeout = PeerChSwitchTimeOut;
                    pAd->StaCfg.TdlsGlobalSwitchTimeOut = PeerChSwitchTimeOut;
                    pTDLS->ChannelSwitchCurrentState = TDLS_CHANNEL_SWITCH_NONE;

                    RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_TDLS_DOING_CHANNEL_SWITCH);
                    //Cancel the timer since the received packet to me.
#ifdef TDLS_HWTIMER_SUPPORT
                    TDLS_SetChannelSwitchTimer(pAd,  ((PeerChSwitchTime + pAd->StaCfg.TdlsOffChannelDelay) / 1000));
#else
                    RTMPCancelTimer(&pTDLS->ChannelSwitchTimer, &TimerCancelled);
                    pTDLS->bEnableChSwitchTime = TRUE;
                    NdisGetSystemUpTime(&pTDLS->ChannelSwitchTimerStartTime);
                    RTMPSetTimer(&pTDLS->ChannelSwitchTimer, ((PeerChSwitchTime + pAd->StaCfg.TdlsOffChannelDelay) / 1000));
#endif // TDLS_HWTIMER_SUPPORT //

                    if (RTDebugLevel < RT_DEBUG_ERROR)
                        RTMPusecDelay(300);
                    else
                        DBGPRINT(RT_DEBUG_ERROR, ("104. %ld !!!\n", (jiffies * 1000) / OS_HZ));
                    TDLS_InitChannelRelatedValue(pAd, pAd->StaCfg.TdlsCurrentChannel, pAd->StaCfg.TdlsCurrentChannelBW);
                }
            }
            else
            {
                pTDLS->bDoingPeriodChannelSwitch = FALSE;
                pAd->StaCfg.bDoingPeriodChannelSwitch = FALSE;
                pAd->StaCfg.TdlsForcePowerSaveWithAP = FALSE;
                pAd->StaCfg.bTdlsNoticeAPPowerSave = FALSE;

                if (pAd->StaCfg.bChannelSwitchInitiator == FALSE)
                {
                    DBGPRINT(RT_DEBUG_OFF,("%s(%d): i am channel switch responder!!!\n",  __FUNCTION__,__LINE__));
                }
                else
                {
                    RTMPCancelTimer(&pAd->StaCfg.TdlsDisableChannelSwitchTimer, &TimerCancelled);
                    pAd->StaCfg.bChannelSwitchInitiator = FALSE;
                    DBGPRINT(RT_DEBUG_OFF,("%s(%d): i am channel switch Initiator !!!\n", __FUNCTION__,__LINE__));
                }

                if (pAd->StaCfg.TdlsCurrentOperateChannel != pAd->CommonCfg.Channel)
                {
                    RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_TDLS_DOING_CHANNEL_SWITCH);
                    if (pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel)
                        TDLS_InitChannelRelatedValue(pAd, pAd->CommonCfg.Channel, EXTCHA_ABOVE);
                    else if (pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel)
                        TDLS_InitChannelRelatedValue(pAd, pAd->CommonCfg.Channel, EXTCHA_BELOW);
                    else
                        TDLS_InitChannelRelatedValue(pAd, pAd->CommonCfg.Channel, EXTCHA_NONE);
                    TDLS_EnablePktChannel(pAd, TDLS_FIFO_ALL);
                    RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_TDLS_DOING_CHANNEL_SWITCH);
                }

                RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE, FALSE);
            }
        }
    }




    DBGPRINT(RT_DEBUG_WARN,("TDLS <=== TDLS_PeerChannelSwitchRspAction() \n"));

    return;
}
/*
==========================================================================
	Description:

	IRQL = PASSIVE_LEVEL
==========================================================================
*/
VOID
TDLS_PeerChannelSwitchReqAction(
    IN PRTMP_ADAPTER pAd,
    IN MLME_QUEUE_ELEM *Elem)
{
    PRT_802_11_TDLS		pTDLS = NULL;
    int					LinkId = 0xff;
    UCHAR				PeerAddr[MAC_ADDR_LEN];
    BOOLEAN				IsInitator;
    //BOOLEAN				TimerCancelled;
    UCHAR				TargetChannel;
    UCHAR				RegulatoryClass;
    UCHAR				NewExtChannelOffset = 0xff;
    UCHAR				LinkIdentLen;
    USHORT				PeerChSwitchTime;
    USHORT				PeerChSwitchTimeOut;
    TDLS_LINK_IDENT_ELEMENT	LinkIdent;
    NDIS_STATUS			NStatus = NDIS_STATUS_SUCCESS;
    USHORT				StatusCode = MLME_SUCCESS;
    UINT16				SwitchTime = pAd->StaCfg.TdlsInfo.TdlsSwitchTime; //micro seconds
    UINT16				SwitchTimeout = pAd->StaCfg.TdlsInfo.TdlsSwitchTimeout; // micro seconds

    DBGPRINT(RT_DEBUG_WARN,("TDLS ===> TDLS_PeerChannelSwitchReqAction() \n"));

    // Not TDLS Capable, ignore it
    if (!IS_TDLS_SUPPORT(pAd))
        return;

    if (!INFRA_ON(pAd))
        return;

    if (pAd->StaActive.ExtCapInfo.TDLSChSwitchProhibited == TRUE)
    {
        DBGPRINT(RT_DEBUG_OFF,("%s(%d): AP Prohibite TDLS Channel Switch !!!\n", __FUNCTION__, __LINE__));
        return;
    }

    tdls_hex_dump("TDLS peer channel switch request receive pack", Elem->Msg, Elem->MsgLen);

    if (!PeerTdlsChannelSwitchReqSanity(pAd,
                                        Elem->Msg,
                                        Elem->MsgLen,
                                        PeerAddr,
                                        &IsInitator,
                                        &TargetChannel,
                                        &RegulatoryClass,
                                        &NewExtChannelOffset,
                                        &PeerChSwitchTime,
                                        &PeerChSwitchTimeOut,
                                        &LinkIdentLen,
                                        &LinkIdent))
    {
        DBGPRINT(RT_DEBUG_ERROR,("%s(%d):  from %02x:%02x:%02x:%02x:%02x:%02x Sanity Check Fail !!!\n",
                                 __FUNCTION__,__LINE__, PeerAddr[0], PeerAddr[1], PeerAddr[2], PeerAddr[3], PeerAddr[4], PeerAddr[5]));
        return;
    }

    DBGPRINT(RT_DEBUG_WARN,("%s(%d):  from %02x:%02x:%02x:%02x:%02x:%02x !!!\n",
                            __FUNCTION__,__LINE__, PeerAddr[0], PeerAddr[1], PeerAddr[2], PeerAddr[3], PeerAddr[4], PeerAddr[5]));

    DBGPRINT(RT_DEBUG_ERROR, ("300. %ld !!!\n", (jiffies * 1000) / OS_HZ));

    // Drop not within my TDLS Table that created before !
    LinkId = TDLS_SearchLinkId(pAd, PeerAddr);
    if (LinkId == -1 || LinkId == MAX_NUM_OF_TDLS_ENTRY)
    {
        DBGPRINT(RT_DEBUG_ERROR,("%s(%d):  can not find from %02x:%02x:%02x:%02x:%02x:%02x on TDLS entry !!!\n",
                                 __FUNCTION__,__LINE__, PeerAddr[0], PeerAddr[1], PeerAddr[2], PeerAddr[3], PeerAddr[4], PeerAddr[5]));
        return;
    }

    if (pAd->StaCfg.bChannelSwitchInitiator == FALSE)
    {
        pAd->StaCfg.TdlsForcePowerSaveWithAP = TRUE;

        if (pAd->StaCfg.bTdlsNoticeAPPowerSave == FALSE)
        {
            pAd->StaCfg.TdlsSendNullFrameCount = 0;
            pAd->StaCfg.bTdlsNoticeAPPowerSave = TRUE;
            RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE, TRUE);
        }
        else
        {
            pAd->StaCfg.TdlsSendNullFrameCount++;
            if (pAd->StaCfg.TdlsSendNullFrameCount >= 200)
                pAd->StaCfg.bTdlsNoticeAPPowerSave = FALSE;
        }
    }



    // Point to the current Link ID
    pTDLS = &pAd->StaCfg.TdlsInfo.TDLSEntry[LinkId];

    if (SwitchTime >= PeerChSwitchTime)
        PeerChSwitchTime = SwitchTime;

    if (SwitchTimeout >= PeerChSwitchTimeOut)
        PeerChSwitchTimeOut = SwitchTimeout;

    if (RtmpPktPmBitCheck(pAd))
    {
        RTMP_SET_PSM_BIT(pAd, PWR_ACTIVE);
        TDLS_SendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE, 0);
    }

    {
        UINT32 macCfg, TxCount;
        UINT32 MTxCycle;

        RTMP_IO_READ32(pAd, TX_REPORT_CNT, &macCfg);

        if  (TargetChannel != pAd->CommonCfg.Channel)
            NStatus = TDLS_ChannelSwitchRspAction(pAd, pTDLS, PeerChSwitchTime, PeerChSwitchTimeOut, StatusCode, RTMP_TDLS_SPECIFIC_CS_RSP_WAIT_ACK);
        else
            NStatus = TDLS_ChannelSwitchRspAction(pAd, pTDLS, PeerChSwitchTime, PeerChSwitchTimeOut, StatusCode, (RTMP_TDLS_SPECIFIC_CS_RSP_WAIT_ACK + RTMP_TDLS_SPECIFIC_HCCA));


        for (MTxCycle = 0; MTxCycle < 500; MTxCycle++)
        {
            RTMP_IO_READ32(pAd, TX_REPORT_CNT, &macCfg);
            TxCount = macCfg & 0x0000ffff;
            if (TxCount > 0)
            {
                DBGPRINT(RT_DEBUG_ERROR, ("MTxCycle = %d, %ld !!!\n", MTxCycle, (jiffies * 1000) / OS_HZ));
                break;
            }
            else
                RTMPusecDelay(50);
        }

        if (MTxCycle >= 500)
        {
            NStatus = NDIS_STATUS_FAILURE;
            DBGPRINT(RT_DEBUG_OFF,("TDLS Transmit Channel Switch Response Fail !!!\n"));
        }
    }

    if (NStatus == NDIS_STATUS_SUCCESS)
    {

        {
            if  (TargetChannel != pAd->CommonCfg.Channel)
            {
                BOOLEAN TimerCancelled;
                //ULONG Now, temp1, temp2, temp3;

                pAd->StaCfg.TdlsCurrentChannel = TargetChannel;

                if (NewExtChannelOffset != 0)
                    pAd->StaCfg.TdlsCurrentChannelBW = NewExtChannelOffset;
                else
                    pAd->StaCfg.TdlsCurrentChannelBW = EXTCHA_NONE;

                pTDLS->ChSwitchTime = PeerChSwitchTime;
                pAd->StaCfg.TdlsGlobalSwitchTime = PeerChSwitchTime;
                pTDLS->ChSwitchTimeout = PeerChSwitchTimeOut;
                pAd->StaCfg.TdlsGlobalSwitchTimeOut = PeerChSwitchTimeOut;

                RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_TDLS_DOING_CHANNEL_SWITCH);
                //Cancel the timer since the received packet to me.
#ifdef TDLS_HWTIMER_SUPPORT
                TDLS_SetChannelSwitchTimer(pAd,  (PeerChSwitchTimeOut / 1000));
#else
                RTMPCancelTimer(&pTDLS->ChannelSwitchTimeoutTimer, &TimerCancelled);
                NdisGetSystemUpTime(&pTDLS->ChannelSwitchTimerStartTime);
                RTMPSetTimer(&pTDLS->ChannelSwitchTimeoutTimer, (PeerChSwitchTimeOut / 1000));
#endif // TDLS_HWTIMER_SUPPORT //
                RTMPCancelTimer(&pAd->StaCfg.TdlsDisableChannelSwitchTimer, &TimerCancelled);
                pAd->StaCfg.bTdlsCurrentDoingChannelSwitchWaitSuccess = TRUE;
                pAd->StaCfg.bDoingPeriodChannelSwitch = TRUE;

                if (RTDebugLevel < RT_DEBUG_ERROR)
                    RTMPusecDelay(300);
                else
                    DBGPRINT(RT_DEBUG_ERROR, ("1041. %ld !!!\n", (jiffies * 1000) / OS_HZ));
                TDLS_InitChannelRelatedValue(pAd, pAd->StaCfg.TdlsCurrentChannel, pAd->StaCfg.TdlsCurrentChannelBW);
            }
            else
            {
                pTDLS->bDoingPeriodChannelSwitch = FALSE;
                pAd->StaCfg.bDoingPeriodChannelSwitch = FALSE;
                pAd->StaCfg.TdlsForcePowerSaveWithAP = FALSE;
                pAd->StaCfg.bTdlsNoticeAPPowerSave = FALSE;

                RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_TDLS_DOING_CHANNEL_SWITCH);
                RTMPusecDelay(300);

                if (pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel)
                    TDLS_InitChannelRelatedValue(pAd, pAd->CommonCfg.Channel, EXTCHA_ABOVE);
                else if (pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel)
                    TDLS_InitChannelRelatedValue(pAd, pAd->CommonCfg.Channel, EXTCHA_BELOW);
                else
                    TDLS_InitChannelRelatedValue(pAd, pAd->CommonCfg.Channel, EXTCHA_NONE);
                TDLS_EnablePktChannel(pAd, TDLS_FIFO_ALL);
                RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_TDLS_DOING_CHANNEL_SWITCH);

                RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE, FALSE);
            }
        }
    }

    DBGPRINT(RT_DEBUG_WARN,("TDLS <=== TDLS_PeerChannelSwitchReqAction() \n"));

    return;
}
/*
==========================================================================
	Description:

	IRQL = PASSIVE_LEVEL
==========================================================================
*/
VOID
TDLS_MlmeChannelSwitchAction(
    IN PRTMP_ADAPTER pAd,
    IN MLME_QUEUE_ELEM *Elem)
{
    PMLME_TDLS_CH_SWITCH_STRUCT pChSwReq = NULL;
    NDIS_STATUS	NStatus = NDIS_STATUS_SUCCESS;
    int	LinkId = 0xff;

    DBGPRINT(RT_DEBUG_WARN,("TDLS ===> TDLS_MlmeChannelSwitchAction() \n"));

    pChSwReq = (PMLME_TDLS_CH_SWITCH_STRUCT)Elem->Msg;

    if (pAd->StaActive.ExtCapInfo.TDLSChSwitchProhibited == TRUE)
    {
        DBGPRINT(RT_DEBUG_OFF,("%s(%d): AP Prohibite TDLS Channel Switch !!!\n", __FUNCTION__, __LINE__));
        return;
    }

    if (INFRA_ON(pAd))
    {
        // Drop not within my TDLS Table that created before !
        LinkId = TDLS_SearchLinkId(pAd, pChSwReq->PeerMacAddr);

        if (LinkId == -1 || LinkId == MAX_NUM_OF_TDLS_ENTRY)
        {
            DBGPRINT(RT_DEBUG_ERROR,("TDLS - TDLS_MlmeChannelSwitchAction() can not find the LinkId!\n"));
            return;
        }

        pAd->StaCfg.TdlsForcePowerSaveWithAP = TRUE;

        if (pAd->StaCfg.bTdlsNoticeAPPowerSave == FALSE)
        {
            pAd->StaCfg.TdlsSendNullFrameCount = 0;
            pAd->StaCfg.bTdlsNoticeAPPowerSave = TRUE;
            RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE, TRUE);
        }
        else
        {
            pAd->StaCfg.TdlsSendNullFrameCount++;
            if (pAd->StaCfg.TdlsSendNullFrameCount >= 200)
                pAd->StaCfg.bTdlsNoticeAPPowerSave = FALSE;
        }

        DBGPRINT(RT_DEBUG_ERROR, ("103. %ld !!!\n", (jiffies * 1000) / OS_HZ));

        /* Build TDLS channel switch Request Frame */
        NStatus = TDLS_ChannelSwitchReqAction(pAd, pChSwReq);
        if (NStatus	!= NDIS_STATUS_SUCCESS)
        {
            DBGPRINT(RT_DEBUG_ERROR,("TDLS - TDLS_MlmeChannelSwitchAction() Build Channel Switch Request Fail !!!\n"));
        }
        else
        {
            pAd->StaCfg.TdlsChannelSwitchPairCount++;
            DBGPRINT(RT_DEBUG_WARN,("TDLS <=== TDLS_MlmeChannelSwitchAction() \n"));
        }
    }
    else
    {
        DBGPRINT(RT_DEBUG_WARN,("TDLS <=== TDLS_MlmeChannelSwitchAction() TDLS only support infra mode !!!\n"));
    }

    return;
}
Пример #9
0
/*
	==========================================================================
	Description:
		Scan next channel
	==========================================================================
 */
VOID ScanNextChannel(
	IN PRTMP_ADAPTER pAd) 
{
	HEADER_802_11   Hdr80211;
	PUCHAR          pOutBuffer = NULL;
	NDIS_STATUS     NStatus;
	ULONG           FrameLen = 0;
	UCHAR           SsidLen = 0, ScanType = pAd->MlmeAux.ScanType, BBPValue = 0;
#ifdef CONFIG_STA_SUPPORT
	USHORT          Status;
#endif // CONFIG_STA_SUPPORT //
	UINT			ScanTimeIn5gChannel = SHORT_CHANNEL_TIME;
	BOOLEAN			ScanPending = FALSE;

#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 RALINK_ATE
	// Nothing to do in ATE mode. 
	if (ATE_ON(pAd))
		return;
#endif // RALINK_ATE //

	if ((pAd->MlmeAux.Channel == 0) || ScanPending) 
	{
		if ((pAd->CommonCfg.BBPCurrentBW == BW_40)
#ifdef CONFIG_STA_SUPPORT
			&& (INFRA_ON(pAd) || ADHOC_ON(pAd)
				|| (pAd->OpMode == OPMODE_AP))
#endif // CONFIG_STA_SUPPORT //
			)
		{
			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));
		}
		
#ifdef CONFIG_STA_SUPPORT
		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
		{

			/*
				If all peer Ad-hoc clients leave, driver would do LinkDown and LinkUp.
				In LinkUp, CommonCfg.Ssid would copy SSID from MlmeAux. 
				To prevent SSID is zero or wrong in Beacon, need to recover MlmeAux.SSID here.
			*/
			if (ADHOC_ON(pAd))
			{
				NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
				pAd->MlmeAux.SsidLen = pAd->CommonCfg.SsidLen;
				NdisMoveMemory(pAd->MlmeAux.Ssid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen);
			}
		
			//
			// 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)))
			{
				RTMPSendNullFrame(pAd, 
								  pAd->CommonCfg.TxRate, 
								  (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) ? TRUE:FALSE));
				DBGPRINT(RT_DEBUG_TRACE, ("%s -- Send PSM Data frame\n", __FUNCTION__));
			}

			// keep the latest scan channel, could be 0 for scan complete, or other channel
			pAd->StaCfg.LastScanChannel = pAd->MlmeAux.Channel;

			pAd->StaCfg.ScanChannelCnt = 0;

			// Suspend scanning and Resume TxData for Fast Scanning
			if ((pAd->MlmeAux.Channel != 0) &&
				(pAd->StaCfg.bImprovedScan))	// it is scan pending
			{
				pAd->Mlme.SyncMachine.CurrState = SCAN_PENDING;
				Status = MLME_SUCCESS;
				DBGPRINT(RT_DEBUG_WARN, ("bFastRoamingScan ~~~~~~~~~~~~~ Get back to send data ~~~~~~~~~~~~~\n"));

				RTMPResumeMsduTransmission(pAd);
			}
			else
			{
				pAd->StaCfg.BssNr = pAd->ScanTab.BssNr;
				pAd->StaCfg.bImprovedScan = FALSE;
				
				pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
				Status = MLME_SUCCESS;
				MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status, 0);

				RTMPSendWirelessEvent(pAd, IW_SCAN_COMPLETED_EVENT_FLAG, NULL, BSS0, 0);
#ifdef WPA_SUPPLICANT_SUPPORT
				RtmpOSWrielessEventSend(pAd, SIOCGIWSCAN, -1, NULL, NULL, 0);
#endif // WPA_SUPPLICANT_SUPPORT //
			}

#ifdef LINUX
#ifdef RT_CFG80211_SUPPORT
			RTEnqueueInternalCmd(pAd, CMDTHREAD_SCAN_END, NULL, 0);
#endif // RT_CFG80211_SUPPORT //
#endif // LINUX //
		}
#endif // CONFIG_STA_SUPPORT //



	} 
	else 
	{