summaryrefslogtreecommitdiff
path: root/cleopatre/devkit/mt7601udrv/common/scan.c
diff options
context:
space:
mode:
authorFisher Cheng2013-05-24 16:54:08 +0800
committerJulien Lacour2013-10-01 12:12:48 +0200
commit8c1eb022607c0aba81d93b961abbfb47a2dcc325 (patch)
tree13b1cd55172e93b3d1e5baa7141ba259fd71b0af /cleopatre/devkit/mt7601udrv/common/scan.c
parent9e4d9d72dcac9686f1b4720e46e3bb88f6375a1e (diff)
cleo/devkit: add MTK MT7601U drv source code, refs #4011
- Enable Wireless LAN and Wireless extension in linux26.config
Diffstat (limited to 'cleopatre/devkit/mt7601udrv/common/scan.c')
-rw-r--r--cleopatre/devkit/mt7601udrv/common/scan.c415
1 files changed, 415 insertions, 0 deletions
diff --git a/cleopatre/devkit/mt7601udrv/common/scan.c b/cleopatre/devkit/mt7601udrv/common/scan.c
new file mode 100644
index 0000000000..fc2b90dc7e
--- /dev/null
+++ b/cleopatre/devkit/mt7601udrv/common/scan.c
@@ -0,0 +1,415 @@
+/*
+
+*/
+
+#include "rt_config.h"
+
+
+#ifdef SCAN_SUPPORT
+static INT scan_ch_restore(RTMP_ADAPTER *pAd, UCHAR OpMode)
+{
+ 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_AP_SUPPORT
+ if (OpMode == OPMODE_AP)
+ {
+
+ 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;
+}
+
+
+
+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;
+
+
+ if (MlmeAllocateMemory(pAd, &frm_buf) != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - ScanNextChannel() allocate memory fail\n"));
+
+#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 CONFIG_AP_SUPPORT
+ /*IF_DEV_CONFIG_OPMODE_ON_AP(pAd) */
+ if (OpMode == OPMODE_AP)
+ {
+ MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR,
+ pAd->ApCfg.MBSSID[0].Bssid);
+ }
+#endif /* CONFIG_AP_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 */
+
+
+ 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 */
+
+
+
+ MiniportMMRequest(pAd, 0, frm_buf, FrameLen);
+
+
+ MlmeFreeMemory(pAd, frm_buf);
+
+ return TRUE;
+}
+
+
+/*
+ ==========================================================================
+ 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;
+ UCHAR ImprovedScan_MaxScanChannelCnt;
+
+
+#ifdef RALINK_ATE
+ /* Nothing to do in ATE mode. */
+ if (ATE_ON(pAd))
+ return;
+#endif /* RALINK_ATE */
+
+
+
+
+ if ((pAd->MlmeAux.Channel == 0) || ScanPending)
+ {
+ scan_ch_restore(pAd, OpMode);
+ }
+#ifdef RTMP_MAC_USB
+#endif /* RTMP_MAC_USB */
+ else
+ {
+
+ AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, TRUE);
+ AsicLockChannel(pAd, pAd->MlmeAux.Channel);
+
+
+ /* 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_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;
+ }
+#ifdef WIFI_P2P_CONCURRENT_FAST_SCAN
+ /* If this is not PASSIVE scan && Fast scan is enabled, we shorten the chanenl dwell time */
+ else if (ScanType != SCAN_PASSIVE && pAd->StaCfg.bImprovedScan)
+ stay_time = FAST_ACTIVE_SCAN_TIME;
+#endif /* WIFI_P2P_CONCURRENT_FAST_SCAN */
+ 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_AP_SUPPORT
+ if (OpMode == OPMODE_AP)
+ pAd->Mlme.ApSyncMachine.CurrState = AP_SCAN_LISTEN;
+#endif /* CONFIG_AP_SUPPORT */
+ }
+}
+
+
+BOOLEAN ScanRunning(
+ IN PRTMP_ADAPTER pAd)
+{
+ BOOLEAN rv = FALSE;
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef AP_SCAN_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ rv = ((pAd->Mlme.ApSyncMachine.CurrState == AP_SCAN_LISTEN) ? TRUE : FALSE);
+#endif /* AP_SCAN_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+ return rv;
+}
+
+#endif /* SCAN_SUPPORT */
+