/* ======================================================================== Routine Description: Caller ensures we has 802.11n support. Calls at setting HT from AP/STASetinformation Arguments: pAd - Pointer to our adapter phymode - ======================================================================== */ VOID RTMPSetIndividualHT( IN RTMP_ADAPTER *pAd, IN UCHAR apidx) { RT_PHY_INFO *pDesired_ht_phy = NULL; UCHAR TxStream = pAd->CommonCfg.TxStream; UCHAR DesiredMcs = MCS_AUTO; UCHAR encrypt_mode = Ndis802_11EncryptionDisabled; do { #ifdef CONFIG_AP_SUPPORT #ifdef APCLI_SUPPORT if (apidx >= MIN_NET_DEVICE_FOR_APCLI) { UCHAR idx = apidx - MIN_NET_DEVICE_FOR_APCLI; if (idx < MAX_APCLI_NUM) { pDesired_ht_phy = &pAd->ApCfg.ApCliTab[idx].DesiredHtPhyInfo; DesiredMcs = pAd->ApCfg.ApCliTab[idx].DesiredTransmitSetting.field.MCS; encrypt_mode = pAd->ApCfg.ApCliTab[idx].WepStatus; pAd->ApCfg.ApCliTab[idx].bAutoTxRateSwitch = (DesiredMcs == MCS_AUTO) ? TRUE : FALSE; break; } else { DBGPRINT(RT_DEBUG_ERROR, ("RTMPSetIndividualHT: invalid idx(%d)\n", idx)); return; } } #endif /* APCLI_SUPPORT */ IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { #ifdef WDS_SUPPORT if (apidx >= MIN_NET_DEVICE_FOR_WDS) { UCHAR idx = apidx - MIN_NET_DEVICE_FOR_WDS; if (idx < MAX_WDS_ENTRY) { pDesired_ht_phy = &pAd->WdsTab.WdsEntry[idx].DesiredHtPhyInfo; DesiredMcs = pAd->WdsTab.WdsEntry[idx].DesiredTransmitSetting.field.MCS; /*encrypt_mode = pAd->WdsTab.WdsEntry[idx].WepStatus;*/ pAd->WdsTab.WdsEntry[idx].bAutoTxRateSwitch = (DesiredMcs == MCS_AUTO) ? TRUE : FALSE; break; } else { DBGPRINT(RT_DEBUG_ERROR, ("RTMPSetIndividualHT: invalid apidx(%d)\n", apidx)); return; } } #endif /* WDS_SUPPORT */ if ((apidx < pAd->ApCfg.BssidNum) && (apidx < MAX_MBSSID_NUM(pAd)) && (apidx < HW_BEACON_MAX_NUM)) { pDesired_ht_phy = &pAd->ApCfg.MBSSID[apidx].DesiredHtPhyInfo; DesiredMcs = pAd->ApCfg.MBSSID[apidx].DesiredTransmitSetting.field.MCS; encrypt_mode = pAd->ApCfg.MBSSID[apidx].WepStatus; pAd->ApCfg.MBSSID[apidx].bWmmCapable = TRUE; pAd->ApCfg.MBSSID[apidx].bAutoTxRateSwitch = (DesiredMcs == MCS_AUTO) ? TRUE : FALSE; break; } DBGPRINT(RT_DEBUG_ERROR, ("RTMPSetIndividualHT: invalid apidx(%d)\n", apidx)); return; } #endif /* CONFIG_AP_SUPPORT */ } while (FALSE); if (pDesired_ht_phy == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("RTMPSetIndividualHT: invalid apidx(%d)\n", apidx)); return; } RTMPZeroMemory(pDesired_ht_phy, sizeof(RT_PHY_INFO)); DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetIndividualHT : Desired MCS = %d\n", DesiredMcs)); /* Check the validity of MCS */ if ((TxStream == 1) && ((DesiredMcs >= MCS_8) && (DesiredMcs <= MCS_15))) { DBGPRINT(RT_DEBUG_WARN, ("RTMPSetIndividualHT: MCS(%d) is invalid in 1S, reset it as MCS_7\n", DesiredMcs)); DesiredMcs = MCS_7; } if ((pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BW_20) && (DesiredMcs == MCS_32)) { DBGPRINT(RT_DEBUG_WARN, ("RTMPSetIndividualHT: MCS_32 is only supported in 40-MHz, reset it as MCS_0\n")); DesiredMcs = MCS_0; } /* WFA recommend to restrict the encryption type in 11n-HT mode. So, the WEP and TKIP are not allowed in HT rate. */ if (pAd->CommonCfg.HT_DisallowTKIP && IS_INVALID_HT_SECURITY(encrypt_mode)) { DBGPRINT(RT_DEBUG_WARN, ("%s : Use legacy rate in WEP/TKIP encryption mode (apidx=%d)\n", __FUNCTION__, apidx)); return; } if (pAd->CommonCfg.HT_Disable) { DBGPRINT(RT_DEBUG_TRACE, ("%s : HT is disabled\n", __FUNCTION__)); return; } pDesired_ht_phy->bHtEnable = TRUE; /* Decide desired Tx MCS*/ switch (TxStream) { case 1: if (DesiredMcs == MCS_AUTO) pDesired_ht_phy->MCSSet[0]= 0xff; else if (DesiredMcs <= MCS_7) pDesired_ht_phy->MCSSet[0]= 1<<DesiredMcs; break; case 2: if (DesiredMcs == MCS_AUTO) { pDesired_ht_phy->MCSSet[0]= 0xff; pDesired_ht_phy->MCSSet[1]= 0xff; } else if (DesiredMcs <= MCS_15) { ULONG mode; mode = DesiredMcs / 8; if (mode < 2) pDesired_ht_phy->MCSSet[mode] = (1 << (DesiredMcs - mode * 8)); } break; case 3: if (DesiredMcs == MCS_AUTO) { /* MCS0 ~ MCS23, 3 bytes */ pDesired_ht_phy->MCSSet[0]= 0xff; pDesired_ht_phy->MCSSet[1]= 0xff; pDesired_ht_phy->MCSSet[2]= 0xff; } else if (DesiredMcs <= MCS_23) { ULONG mode; mode = DesiredMcs / 8; if (mode < 3) pDesired_ht_phy->MCSSet[mode] = (1 << (DesiredMcs - mode * 8)); } break; } if(pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BW_40) { if (DesiredMcs == MCS_AUTO || DesiredMcs == MCS_32) pDesired_ht_phy->MCSSet[4] = 0x1; } /* update HT Rate setting */ if (pAd->OpMode == OPMODE_STA) { MlmeUpdateHtTxRates(pAd, BSS0); } else MlmeUpdateHtTxRates(pAd, apidx); #ifdef DOT11_VHT_AC if (WMODE_CAP_AC(pAd->CommonCfg.PhyMode)) { pDesired_ht_phy->bVhtEnable = TRUE; rtmp_set_vht(pAd, pDesired_ht_phy); } #endif /* DOT11_VHT_AC */ }
/* ========================================================================== Description: When waiting joining the (I)BSS, beacon received from external ========================================================================== */ static VOID ApCliPeerProbeRspAtJoinAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { USHORT LenVIE; UCHAR *VarIE = NULL; NDIS_802_11_VARIABLE_IEs *pVIE = NULL; APCLI_CTRL_MSG_STRUCT ApCliCtrlMsg; PAPCLI_STRUCT pApCliEntry = NULL; struct wifi_dev *wdev; #ifdef DOT11_N_SUPPORT UCHAR CentralChannel; #endif /* DOT11_N_SUPPORT */ USHORT ifIndex = (USHORT)(Elem->Priv); ULONG *pCurrState; BCN_IE_LIST *ie_list = NULL; if (ifIndex >= MAX_APCLI_NUM) return; /* Init Variable IE structure */ os_alloc_mem(NULL, (UCHAR **)&VarIE, MAX_VIE_LEN); if (VarIE == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); goto LabelErr; } pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE; pVIE->Length = 0; os_alloc_mem(NULL, (UCHAR **)&ie_list, sizeof(BCN_IE_LIST)); if (ie_list == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate ie_list fail!!!\n", __FUNCTION__)); goto LabelErr; } NdisZeroMemory(ie_list, sizeof(BCN_IE_LIST)); pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].SyncCurrState; if (PeerBeaconAndProbeRspSanity(pAd, Elem->Msg, Elem->MsgLen, Elem->Channel, ie_list, &LenVIE, pVIE)) { /* BEACON from desired BSS/IBSS found. We should be able to decide most BSS parameters here. Q. But what happen if this JOIN doesn't conclude a successful ASSOCIATEION? Do we need to receover back all parameters belonging to previous BSS? A. Should be not. There's no back-door recover to previous AP. It still need a new JOIN-AUTH-ASSOC sequence. */ INT ssidEqualFlag = FALSE; INT ssidEmptyFlag = FALSE; INT bssidEqualFlag = FALSE; INT bssidEmptyFlag = FALSE; INT matchFlag = FALSE; ULONG Bssidx; CHAR RealRssi = -127; RealRssi = (LONG)(RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2))); /* Update ScanTab */ Bssidx = BssTableSearch(&pAd->ScanTab, ie_list->Bssid, ie_list->Channel); if (Bssidx == BSS_NOT_FOUND) { /* discover new AP of this network, create BSS entry */ Bssidx = BssTableSetEntry(pAd, &pAd->ScanTab, ie_list, -127, LenVIE, pVIE); if (Bssidx == BSS_NOT_FOUND) /* return if BSS table full */ { DBGPRINT(RT_DEBUG_ERROR, ("ERROR: Driver ScanTable Full In Apcli ProbeRsp Join\n")); goto LabelErr; } NdisMoveMemory(pAd->ScanTab.BssEntry[Bssidx].PTSF, &Elem->Msg[24], 4); NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4); NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4); pAd->ScanTab.BssEntry[Bssidx].MinSNR = Elem->Signal % 10; if (pAd->ScanTab.BssEntry[Bssidx].MinSNR == 0) pAd->ScanTab.BssEntry[Bssidx].MinSNR = -5; NdisMoveMemory(pAd->ScanTab.BssEntry[Bssidx].MacAddr, ie_list->Addr2, MAC_ADDR_LEN); } #ifdef RT_CFG80211_P2P_CONCURRENT_DEVICE DBGPRINT(RT_DEBUG_TRACE, ("Info: Update the SSID %s in Kernel Table\n", ie_list->Ssid)); RT_CFG80211_SCANNING_INFORM(pAd, Bssidx, ie_list->Channel, (UCHAR *)Elem->Msg, Elem->MsgLen, RealRssi); #endif /* RT_CFG80211_P2P_CONCURRENT_DEVICE */ pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex]; wdev = &pApCliEntry->wdev; /* Check the Probe-Rsp's Bssid. */ if(!MAC_ADDR_EQUAL(pApCliEntry->CfgApCliBssid, ZERO_MAC_ADDR)) bssidEqualFlag = MAC_ADDR_EQUAL(pApCliEntry->CfgApCliBssid, ie_list->Bssid); else bssidEmptyFlag = TRUE; /* Check the Probe-Rsp's Ssid. */ if(pApCliEntry->CfgSsidLen != 0) ssidEqualFlag = SSID_EQUAL(pApCliEntry->CfgSsid, pApCliEntry->CfgSsidLen, ie_list->Ssid, ie_list->SsidLen); else ssidEmptyFlag = TRUE; /* bssid and ssid, Both match. */ if (bssidEqualFlag && ssidEqualFlag) matchFlag = TRUE; /* ssid match but bssid doesn't be indicate. */ else if(ssidEqualFlag && bssidEmptyFlag) matchFlag = TRUE; /* user doesn't indicate any bssid or ssid. AP-Clinet will auto pick a AP to join by most strong siganl strength. */ else if (bssidEmptyFlag && ssidEmptyFlag) matchFlag = TRUE; DBGPRINT(RT_DEBUG_TRACE, ("SYNC - bssidEqualFlag=%d, ssidEqualFlag=%d, matchFlag=%d\n", bssidEqualFlag, ssidEqualFlag, matchFlag)); if (matchFlag) { /* Validate RSN IE if necessary, then copy store this information */ if ((LenVIE > 0) #ifdef RT_CFG80211_P2P_CONCURRENT_DEVICE /* When using CFG80211 and trigger WPS, do not check security. */ && ! (pApCliEntry->wpa_supplicant_info.WpaSupplicantUP & WPA_SUPPLICANT_ENABLE_WPS) #endif /* RT_CFG80211_P2P_CONCURRENT_DEVICE */ ) { if (ApCliValidateRSNIE(pAd, (PEID_STRUCT)pVIE, LenVIE, ifIndex)) { pApCliEntry->MlmeAux.VarIELen = LenVIE; NdisMoveMemory(pApCliEntry->MlmeAux.VarIEs, pVIE, pApCliEntry->MlmeAux.VarIELen); } else { /* ignore this response */ pApCliEntry->MlmeAux.VarIELen = 0; DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The RSN IE of this received Probe-resp is dis-match !!!!!!!!!! \n")); goto LabelErr; } } else { if (pApCliEntry->wdev.AuthMode >= Ndis802_11AuthModeWPA ) { /* ignore this response */ DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The received Probe-resp has empty RSN IE !!!!!!!!!! \n")); goto LabelErr; } pApCliEntry->MlmeAux.VarIELen = 0; } DBGPRINT(RT_DEBUG_TRACE, ("SYNC - receive desired PROBE_RSP at JoinWaitProbeRsp... Channel = %d\n", ie_list->Channel)); /* if the Bssid doesn't be indicated then you need to decide which AP to connect by most strong Rssi signal strength. */ if (bssidEqualFlag == FALSE) { /* caculate real rssi value. */ CHAR Rssi0 = ConvertToRssi(pAd, Elem->Rssi0, RSSI_0); CHAR Rssi1 = ConvertToRssi(pAd, Elem->Rssi1, RSSI_1); CHAR Rssi2 = ConvertToRssi(pAd, Elem->Rssi2, RSSI_2); LONG RealRssi = (LONG)(RTMPMaxRssi(pAd, Rssi0, Rssi1, Rssi2)); DBGPRINT(RT_DEBUG_TRACE, ("SYNC - previous Rssi = %ld current Rssi=%ld\n", pApCliEntry->MlmeAux.Rssi, (LONG)RealRssi)); if (pApCliEntry->MlmeAux.Rssi > (LONG)RealRssi) goto LabelErr; else pApCliEntry->MlmeAux.Rssi = RealRssi; } else { BOOLEAN Cancelled; RTMPCancelTimer(&pApCliEntry->MlmeAux.ProbeTimer, &Cancelled); } NdisMoveMemory(pApCliEntry->MlmeAux.Ssid, ie_list->Ssid, ie_list->SsidLen); pApCliEntry->MlmeAux.SsidLen = ie_list->SsidLen; NdisMoveMemory(pApCliEntry->MlmeAux.Bssid, ie_list->Bssid, MAC_ADDR_LEN); pApCliEntry->MlmeAux.CapabilityInfo = ie_list->CapabilityInfo & SUPPORTED_CAPABILITY_INFO; pApCliEntry->MlmeAux.BssType = ie_list->BssType; pApCliEntry->MlmeAux.BeaconPeriod = ie_list->BeaconPeriod; pApCliEntry->MlmeAux.Channel = ie_list->Channel; pApCliEntry->MlmeAux.AtimWin = ie_list->AtimWin; pApCliEntry->MlmeAux.CfpPeriod = ie_list->CfParm.CfpPeriod; pApCliEntry->MlmeAux.CfpMaxDuration = ie_list->CfParm.CfpMaxDuration; pApCliEntry->MlmeAux.APRalinkIe = ie_list->RalinkIe; /* Copy AP's supported rate to MlmeAux for creating assoication request */ /* Also filter out not supported rate */ pApCliEntry->MlmeAux.SupRateLen = ie_list->SupRateLen; NdisMoveMemory(pApCliEntry->MlmeAux.SupRate, ie_list->SupRate, ie_list->SupRateLen); RTMPCheckRates(pAd, pApCliEntry->MlmeAux.SupRate, &pApCliEntry->MlmeAux.SupRateLen); pApCliEntry->MlmeAux.ExtRateLen = ie_list->ExtRateLen; NdisMoveMemory(pApCliEntry->MlmeAux.ExtRate, ie_list->ExtRate, ie_list->ExtRateLen); RTMPCheckRates(pAd, pApCliEntry->MlmeAux.ExtRate, &pApCliEntry->MlmeAux.ExtRateLen); #ifdef APCLI_CERT_SUPPORT /* Get the ext capability info element */ if (pAd->bApCliCertTest == TRUE #ifdef DOT11N_DRAFT3 && pAd->CommonCfg.bBssCoexEnable == TRUE #endif /* DOT11N_DRAFT3 */ ) { NdisMoveMemory(&pApCliEntry->MlmeAux.ExtCapInfo, &ie_list->ExtCapInfo,sizeof(ie_list->ExtCapInfo)); #ifdef DOT11_N_SUPPORT #ifdef DOT11N_DRAFT3 DBGPRINT(RT_DEBUG_TRACE, ("\x1b[31m ApCliMlmeAux.ExtCapInfo=%d \x1b[m\n", pApCliEntry->MlmeAux.ExtCapInfo.BssCoexistMgmtSupport)); //zero debug 210121122 pAd->CommonCfg.ExtCapIE.BssCoexistMgmtSupport = 1; #endif /* DOT11N_DRAFT3 */ #endif /* DOT11_N_SUPPORT */ } #endif /* APCLI_CERT_SUPPORT */ #ifdef DOT11_N_SUPPORT NdisZeroMemory(pApCliEntry->RxMcsSet,sizeof(pApCliEntry->RxMcsSet)); /* filter out un-supported ht rates */ if ((ie_list->HtCapabilityLen > 0) && (pApCliEntry->wdev.DesiredHtPhyInfo.bHtEnable) && WMODE_CAP_N(pAd->CommonCfg.PhyMode) && /* For Dissallow TKIP rule on STA */ !(pAd->CommonCfg.HT_DisallowTKIP && IS_INVALID_HT_SECURITY(wdev->WepStatus))) { RTMPZeroMemory(&pApCliEntry->MlmeAux.HtCapability, SIZE_HT_CAP_IE); pApCliEntry->MlmeAux.NewExtChannelOffset = ie_list->NewExtChannelOffset; pApCliEntry->MlmeAux.HtCapabilityLen = ie_list->HtCapabilityLen; ApCliCheckHt(pAd, ifIndex, &ie_list->HtCapability, &ie_list->AddHtInfo); if (ie_list->AddHtInfoLen > 0) { CentralChannel = ie_list->AddHtInfo.ControlChan; /* Check again the Bandwidth capability of this AP. */ CentralChannel = get_cent_ch_by_htinfo(pAd, &ie_list->AddHtInfo, &ie_list->HtCapability); DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAtJoinAction HT===>CentralCh = %d, ControlCh = %d\n", CentralChannel, ie_list->AddHtInfo.ControlChan)); } } else #endif /* DOT11_N_SUPPORT */ { RTMPZeroMemory(&pApCliEntry->MlmeAux.HtCapability, SIZE_HT_CAP_IE); RTMPZeroMemory(&pApCliEntry->MlmeAux.AddHtInfo, SIZE_ADD_HT_INFO_IE); pApCliEntry->MlmeAux.HtCapabilityLen = 0; } ApCliUpdateMlmeRate(pAd, ifIndex); #ifdef DOT11_N_SUPPORT /* copy QOS related information */ if (WMODE_CAP_N(pAd->CommonCfg.PhyMode)) { NdisMoveMemory(&pApCliEntry->MlmeAux.APEdcaParm, &ie_list->EdcaParm, sizeof(EDCA_PARM)); NdisMoveMemory(&pApCliEntry->MlmeAux.APQbssLoad, &ie_list->QbssLoad, sizeof(QBSS_LOAD_PARM)); NdisMoveMemory(&pApCliEntry->MlmeAux.APQosCapability, &ie_list->QosCapability, sizeof(QOS_CAPABILITY_PARM)); } else #endif /* DOT11_N_SUPPORT */ { NdisZeroMemory(&pApCliEntry->MlmeAux.APEdcaParm, sizeof(EDCA_PARM)); NdisZeroMemory(&pApCliEntry->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM)); NdisZeroMemory(&pApCliEntry->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM)); } DBGPRINT(RT_DEBUG_TRACE, ("APCLI SYNC - after JOIN, SupRateLen=%d, ExtRateLen=%d\n", pApCliEntry->MlmeAux.SupRateLen, pApCliEntry->MlmeAux.ExtRateLen)); if (ie_list->AironetCellPowerLimit != 0xFF) { /* We need to change our TxPower for CCX 2.0 AP Control of Client Transmit Power */ ChangeToCellPowerLimit(pAd, ie_list->AironetCellPowerLimit); } else /* Used the default TX Power Percentage. */ pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault; if(bssidEqualFlag == TRUE) { *pCurrState = APCLI_SYNC_IDLE; ApCliCtrlMsg.Status = MLME_SUCCESS; MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_PROBE_RSP, sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex); } } } LabelErr: if (VarIE != NULL) os_free_mem(NULL, VarIE); if (ie_list != NULL) os_free_mem(NULL, ie_list); return; }
/* ========================================================================== Description: mlme assoc req handling procedure Parameters: Adapter - Adapter pointer Elem - MLME Queue Element Pre: the station has been authenticated and the following information is stored in the config -# SSID -# supported rates and their length Post : -# An association request frame is generated and sent to the air -# Association timer starts -# Association state -> ASSOC_WAIT_RSP ========================================================================== */ static VOID ApCliMlmeAssocReqAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { NDIS_STATUS NStatus; BOOLEAN Cancelled; UCHAR ApAddr[6]; HEADER_802_11 AssocHdr; UCHAR WmeIe[9] = {IE_VENDOR_SPECIFIC, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00}; USHORT ListenIntv; ULONG Timeout; USHORT CapabilityInfo; PUCHAR pOutBuffer = NULL; ULONG FrameLen = 0; ULONG tmp; UCHAR SsidIe = IE_SSID; UCHAR SupRateIe = IE_SUPP_RATES; UCHAR ExtRateIe = IE_EXT_SUPP_RATES; APCLI_CTRL_MSG_STRUCT ApCliCtrlMsg; USHORT ifIndex = (USHORT)(Elem->Priv); PULONG pCurrState = NULL; UCHAR RSNIe = IE_WPA; APCLI_STRUCT *apcli_entry; struct wifi_dev *wdev; #ifdef MAC_REPEATER_SUPPORT UCHAR CliIdx = 0xFF; #endif /* MAC_REPEATER_SUPPORT */ if ((ifIndex >= MAX_APCLI_NUM) #ifdef MAC_REPEATER_SUPPORT && (ifIndex < 64) #endif /* MAC_REPEATER_SUPPORT */ ) return; #ifdef MAC_REPEATER_SUPPORT if (ifIndex >= 64) { CliIdx = ((ifIndex - 64) % 16); ifIndex = ((ifIndex - 64) / 16); pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].RepeaterCli[CliIdx].AssocCurrState; } else #endif /* MAC_REPEATER_SUPPORT */ pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].AssocCurrState; apcli_entry = &pAd->ApCfg.ApCliTab[ifIndex]; wdev = &apcli_entry->wdev; /* Block all authentication request durning WPA block period */ if (apcli_entry->bBlockAssoc == TRUE) { DBGPRINT(RT_DEBUG_TRACE, ("APCLI_ASSOC - Block Auth request durning WPA block period!\n")); *pCurrState = APCLI_ASSOC_IDLE; ApCliCtrlMsg.Status = MLME_STATE_MACHINE_REJECT; MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_ASSOC_RSP, sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex); } else if(MlmeAssocReqSanity(pAd, Elem->Msg, Elem->MsgLen, ApAddr, &CapabilityInfo, &Timeout, &ListenIntv)) { //RTMPCancelTimer(&apcli_entry->MlmeAux.ApCliAssocTimer, &Cancelled); #ifdef MAC_REPEATER_SUPPORT if (CliIdx != 0xFF) RTMPCancelTimer(&apcli_entry->RepeaterCli[CliIdx].ApCliAssocTimer, &Cancelled); else #endif /* MAC_REPEATER_SUPPORT */ RTMPCancelTimer(&apcli_entry->MlmeAux.ApCliAssocTimer, &Cancelled); /* allocate and send out AssocRsp frame */ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */ if (NStatus != NDIS_STATUS_SUCCESS) { DBGPRINT(RT_DEBUG_TRACE, ("APCLI_ASSOC - ApCliMlmeAssocReqAction() allocate memory failed \n")); *pCurrState = APCLI_ASSOC_IDLE; ApCliCtrlMsg.Status = MLME_FAIL_NO_RESOURCE; MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_ASSOC_RSP, sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex); return; } DBGPRINT(RT_DEBUG_TRACE, ("APCLI_ASSOC - Send ASSOC request...\n")); ApCliMgtMacHeaderInit(pAd, &AssocHdr, SUBTYPE_ASSOC_REQ, 0, ApAddr, ApAddr, ifIndex); #ifdef MAC_REPEATER_SUPPORT if (CliIdx != 0xFF) COPY_MAC_ADDR(AssocHdr.Addr2, apcli_entry->RepeaterCli[CliIdx].CurrentAddress); #endif /* MAC_REPEATER_SUPPORT */ /* Build basic frame first */ MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(HEADER_802_11), &AssocHdr, 2, &CapabilityInfo, 2, &ListenIntv, 1, &SsidIe, 1, &apcli_entry->MlmeAux.SsidLen, apcli_entry->MlmeAux.SsidLen, apcli_entry->MlmeAux.Ssid, 1, &SupRateIe, 1, &apcli_entry->MlmeAux.SupRateLen, apcli_entry->MlmeAux.SupRateLen, apcli_entry->MlmeAux.SupRate, END_OF_ARGS); if(apcli_entry->MlmeAux.ExtRateLen != 0) { MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, 1, &ExtRateIe, 1, &apcli_entry->MlmeAux.ExtRateLen, apcli_entry->MlmeAux.ExtRateLen, apcli_entry->MlmeAux.ExtRate, END_OF_ARGS); FrameLen += tmp; } #ifdef DOT11_N_SUPPORT /* WFA recommend to restrict the encryption type in 11n-HT mode. So, the WEP and TKIP are not allowed in HT rate. */ if (pAd->CommonCfg.HT_DisallowTKIP && IS_INVALID_HT_SECURITY(wdev->WepStatus)) { /* Force to None-HT mode due to WiFi 11n policy */ apcli_entry->MlmeAux.HtCapabilityLen = 0; #ifdef DOT11_VHT_AC apcli_entry->MlmeAux.vht_cap_len = 0; #endif /* DOT11_VHT_AC */ DBGPRINT(RT_DEBUG_TRACE, ("%s : Force AP-client as Non-HT mode\n", __FUNCTION__)); } /* HT */ if ((apcli_entry->MlmeAux.HtCapabilityLen > 0) && WMODE_CAP_N(pAd->CommonCfg.PhyMode)) { ULONG TmpLen; HT_CAPABILITY_IE HtCapabilityTmp; NdisZeroMemory(&HtCapabilityTmp, sizeof(HT_CAPABILITY_IE)); NdisMoveMemory(&HtCapabilityTmp, &apcli_entry->MlmeAux.HtCapability, apcli_entry->MlmeAux.HtCapabilityLen); #ifdef DOT11N_SS3_SUPPORT HtCapabilityTmp.MCSSet[2] = (apcli_entry->MlmeAux.HtCapability.MCSSet[2] & apcli_entry->RxMcsSet[2]); #endif /* DOT11N_SS3_SUPPORT */ #ifdef RT_BIG_ENDIAN *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo)); *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo)); #endif /* RT_BIG_ENDINA */ MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &HtCapIe, 1, &apcli_entry->MlmeAux.HtCapabilityLen, apcli_entry->MlmeAux.HtCapabilityLen, &HtCapabilityTmp, END_OF_ARGS); FrameLen += TmpLen; #ifdef DOT11_VHT_AC if (WMODE_CAP_AC(pAd->CommonCfg.PhyMode) && (pAd->CommonCfg.Channel > 14) && (apcli_entry->MlmeAux.vht_cap_len)) { FrameLen += build_vht_ies(pAd, (UCHAR *)(pOutBuffer + FrameLen), SUBTYPE_ASSOC_REQ); } #endif /* DOT11_VHT_AC */ } #endif /* DOT11_N_SUPPORT */ #ifdef AGGREGATION_SUPPORT /* add Ralink proprietary IE to inform AP this STA is going to use AGGREGATION or PIGGY-BACK+AGGREGATION Case I: (Aggregation + Piggy-Back) 1. user enable aggregation, AND 2. Mac support piggy-back 3. AP annouces it's PIGGY-BACK+AGGREGATION-capable in BEACON Case II: (Aggregation) 1. user enable aggregation, AND 2. AP annouces it's AGGREGATION-capable in BEACON */ if (pAd->CommonCfg.bAggregationCapable) { #ifdef PIGGYBACK_SUPPORT if ((pAd->CommonCfg.bPiggyBackCapable) && ((apcli_entry->MlmeAux.APRalinkIe & 0x00000003) == 3)) { ULONG TmpLen; UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x03, 0x00, 0x00, 0x00}; MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 9, RalinkIe, END_OF_ARGS); FrameLen += TmpLen; } else #endif /* PIGGYBACK_SUPPORT */ if (apcli_entry->MlmeAux.APRalinkIe & 0x00000001) { ULONG TmpLen; UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x01, 0x00, 0x00, 0x00}; MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 9, RalinkIe, END_OF_ARGS); FrameLen += TmpLen; } } else { ULONG TmpLen; UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x06, 0x00, 0x00, 0x00}; MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 9, RalinkIe, END_OF_ARGS); FrameLen += TmpLen; } #endif /* AGGREGATION_SUPPORT */ if (apcli_entry->MlmeAux.APEdcaParm.bValid) { if (apcli_entry->wdev.UapsdInfo.bAPSDCapable && apcli_entry->MlmeAux.APEdcaParm.bAPSDCapable) { QBSS_STA_INFO_PARM QosInfo; NdisZeroMemory(&QosInfo, sizeof(QBSS_STA_INFO_PARM)); QosInfo.UAPSD_AC_BE = pAd->CommonCfg.bAPSDAC_BE; QosInfo.UAPSD_AC_BK = pAd->CommonCfg.bAPSDAC_BK; QosInfo.UAPSD_AC_VI = pAd->CommonCfg.bAPSDAC_VI; QosInfo.UAPSD_AC_VO = pAd->CommonCfg.bAPSDAC_VO; QosInfo.MaxSPLength = pAd->CommonCfg.MaxSPLength; WmeIe[8] |= *(PUCHAR)&QosInfo; } else { /* The Parameter Set Count is set to бз0би in the association request frames */ /* WmeIe[8] |= (pAd->MlmeAux.APEdcaParm.EdcaUpdateCount & 0x0f); */ } MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, 9, &WmeIe[0], END_OF_ARGS); FrameLen += tmp; } #if defined(RT_CFG80211_P2P_CONCURRENT_DEVICE) || defined(CFG80211_MULTI_STA) apcli_entry->ReqVarIELen = 0; NdisZeroMemory(apcli_entry->ReqVarIEs, MAX_VIE_LEN); if ((apcli_entry->wpa_supplicant_info.WpaSupplicantUP & 0x7F ) == WPA_SUPPLICANT_ENABLE) { DBGPRINT(RT_DEBUG_TRACE,("%s:: APCLI WPA_ASSOC_IE FROM SUPPLICANT\n", __FUNCTION__)); ULONG TmpWpaAssocIeLen = 0; MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpWpaAssocIeLen, apcli_entry->wpa_supplicant_info.WpaAssocIeLen, apcli_entry->wpa_supplicant_info.pWpaAssocIe, END_OF_ARGS); FrameLen += TmpWpaAssocIeLen; VarIesOffset = 0; NdisMoveMemory(apcli_entry->ReqVarIEs + VarIesOffset, apcli_entry->wpa_supplicant_info.pWpaAssocIe, apcli_entry->wpa_supplicant_info.WpaAssocIeLen); VarIesOffset += apcli_entry->wpa_supplicant_info.WpaAssocIeLen; // Set Variable IEs Length apcli_entry->ReqVarIELen = VarIesOffset; } else #endif /* RT_CFG80211_P2P_CONCURRENT_DEVICE || CFG80211_MULTI_STA */ /* Append RSN_IE when WPAPSK OR WPA2PSK, */ if (((wdev->AuthMode == Ndis802_11AuthModeWPAPSK) || (wdev->AuthMode == Ndis802_11AuthModeWPA2PSK)) #ifdef WSC_AP_SUPPORT && ((apcli_entry->WscControl.WscConfMode == WSC_DISABLE) || ((apcli_entry->WscControl.WscConfMode != WSC_DISABLE) && !(apcli_entry->WscControl.bWscTrigger))) #endif /* WSC_AP_SUPPORT */ ) { RSNIe = IE_WPA; if ((wdev->AuthMode == Ndis802_11AuthModeWPA2PSK) ) RSNIe = IE_WPA2; MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, 1, &RSNIe, 1, &apcli_entry->RSNIE_Len, apcli_entry->RSNIE_Len, apcli_entry->RSN_IE, END_OF_ARGS); FrameLen += tmp; } #ifdef WSC_AP_SUPPORT /* Add WSC IE if we are connecting to WSC AP */ if ((pAd->ApCfg.ApCliTab[ifIndex].WscControl.WscConfMode != WSC_DISABLE) && (pAd->ApCfg.ApCliTab[ifIndex].WscControl.bWscTrigger)) { UCHAR *pWscBuf = NULL, WscIeLen = 0; ULONG WscTmpLen = 0; os_alloc_mem(pAd, (UCHAR **) &pWscBuf, 512); /* if( (pWscBuf = kmalloc(512, GFP_ATOMIC)) != NULL) */ if (pWscBuf != NULL) { NdisZeroMemory(pWscBuf, 512); WscBuildAssocReqIE(&pAd->ApCfg.ApCliTab[ifIndex].WscControl, pWscBuf, &WscIeLen); MakeOutgoingFrame(pOutBuffer + FrameLen, &WscTmpLen, WscIeLen, pWscBuf, END_OF_ARGS); FrameLen += WscTmpLen; /* kfree(pWscBuf); */ os_free_mem(NULL, pWscBuf); } else DBGPRINT(RT_DEBUG_WARN, ("%s:: WscBuf Allocate failed!\n", __FUNCTION__)); } #endif /* WSC_AP_SUPPORT */ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); #ifdef MAC_REPEATER_SUPPORT if (CliIdx != 0xFF) RTMPSetTimer(&apcli_entry->RepeaterCli[CliIdx].ApCliAssocTimer, Timeout); else #endif /* MAC_REPEATER_SUPPORT */ RTMPSetTimer(&apcli_entry->MlmeAux.ApCliAssocTimer, Timeout); *pCurrState = APCLI_ASSOC_WAIT_RSP; } else { DBGPRINT(RT_DEBUG_TRACE, ("APCLI_ASSOC - ApCliMlmeAssocReqAction() sanity check failed. BUG!!!!!! \n")); *pCurrState = APCLI_ASSOC_IDLE; ApCliCtrlMsg.Status = MLME_INVALID_FORMAT; MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_ASSOC_RSP, sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex); } return; }
static USHORT update_associated_mac_entry( IN RTMP_ADAPTER *pAd, IN MAC_TABLE_ENTRY *pEntry, IN IE_LISTS *ie_list, IN UCHAR MaxSupportedRate) { MULTISSID_STRUCT *wdev; #ifdef TXBF_SUPPORT BOOLEAN supportsETxBF = FALSE; #endif // TXBF_SUPPORT // wdev = &pAd->ApCfg.MBSSID[pEntry->apidx]; /* Update auth, wep, legacy transmit rate setting . */ pEntry->Sst = SST_ASSOC; pEntry->MaxSupportedRate = min(pAd->CommonCfg.MaxTxRate, MaxSupportedRate); set_entry_phy_cfg(pAd, pEntry); pEntry->CapabilityInfo = ie_list->CapabilityInfo; if ((pEntry->AuthMode == Ndis802_11AuthModeWPAPSK) || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)) { pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP; pEntry->WpaState = AS_INITPSK; } #ifdef DOT1X_SUPPORT else if ((pEntry->AuthMode == Ndis802_11AuthModeWPA) || (pEntry->AuthMode == Ndis802_11AuthModeWPA2) || (wdev->IEEE8021X == TRUE)) { pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP; pEntry->WpaState = AS_AUTHENTICATION; } #endif /* DOT1X_SUPPORT */ /*if (ClientRalinkIe & 0x00000004) */ if (ie_list->RalinkIe != 0x0) CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RALINK_CHIPSET); else CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_RALINK_CHIPSET); /* Ralink proprietary Piggyback and Aggregation support for legacy RT61 chip */ CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE); CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE); #ifdef AGGREGATION_SUPPORT if ((pAd->CommonCfg.bAggregationCapable) && (ie_list->RalinkIe & 0x00000001)) { CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE); DBGPRINT(RT_DEBUG_TRACE, ("ASSOC -RaAggregate= 1\n")); } #endif /* AGGREGATION_SUPPORT */ #ifdef PIGGYBACK_SUPPORT if ((pAd->CommonCfg.bPiggyBackCapable) && (ie_list->RalinkIe & 0x00000002)) { CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE); DBGPRINT(RT_DEBUG_TRACE, ("ASSOC -PiggyBack= 1\n")); } #endif /* PIGGYBACK_SUPPORT */ /* In WPA or 802.1x mode, the port is not secured, otherwise is secued. */ if ((pEntry->AuthMode >= Ndis802_11AuthModeWPA) #ifdef DOT1X_SUPPORT || (wdev->IEEE8021X == TRUE) #endif /* DOT1X_SUPPORT */ ) pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED; else pEntry->PortSecured = WPA_802_1X_PORT_SECURED; #ifdef SOFT_ENCRYPT /* There are some situation to need to encryption by software 1. The Client support PMF. It shall ony support AES cipher. 2. The Client support WAPI. If use RT3883 or later, HW can handle the above. */ #endif /* SOFT_ENCRYPT */ #ifdef DOT11_N_SUPPORT /* WFA recommend to restrict the encryption type in 11n-HT mode. So, the WEP and TKIP are not allowed in HT rate. */ if (pAd->CommonCfg.HT_DisallowTKIP && IS_INVALID_HT_SECURITY(pEntry->WepStatus)) { /* Force to None-HT mode due to WiFi 11n policy */ ie_list->ht_cap_len = 0; DBGPRINT(RT_DEBUG_TRACE, ("%s : Force the STA as Non-HT mode\n", __FUNCTION__)); } /* If this Entry supports 802.11n, upgrade to HT rate. */ if ((ie_list->ht_cap_len != 0) && (wdev->DesiredHtPhyInfo.bHtEnable) && WMODE_CAP_N(pAd->CommonCfg.PhyMode)) { ht_mode_adjust(pAd, pEntry, &ie_list->HTCapability, &pAd->CommonCfg.DesiredHtPhy); #ifdef DOT11N_DRAFT3 if (ie_list->ExtCapInfo.BssCoexistMgmtSupport) pEntry->BSS2040CoexistenceMgmtSupport = 1; #endif /* DOT11N_DRAFT3 */ /* 40Mhz BSS Width Trigger events */ if (ie_list->HTCapability.HtCapInfo.Forty_Mhz_Intolerant) { #ifdef DOT11N_DRAFT3 pEntry->bForty_Mhz_Intolerant = TRUE; pAd->MacTab.fAnyStaFortyIntolerant = TRUE; if(((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) && (pAd->CommonCfg.Channel <=14)) && ((pAd->CommonCfg.bBssCoexEnable == TRUE) && (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth != 0) && (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset != 0)) ) { pAd->CommonCfg.LastBSSCoexist2040.field.BSS20WidthReq = 1; pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 0; pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = 0; pAd->CommonCfg.Bss2040CoexistFlag |= BSS_2040_COEXIST_INFO_SYNC; } DBGPRINT(RT_DEBUG_TRACE, ("pEntry set 40MHz Intolerant as 1\n")); #endif /* DOT11N_DRAFT3 */ Handle_BSS_Width_Trigger_Events(pAd); } #ifdef TXBF_SUPPORT supportsETxBF = clientSupportsETxBF(pAd, &ie_list->HtCapability.TxBFCap); #endif /* TXBF_SUPPORT */ /* find max fixed rate */ pEntry->MaxHTPhyMode.field.MCS = get_ht_max_mcs(pAd, &wdev->DesiredHtPhyInfo.MCSSet[0], &ie_list->HTCapability.MCSSet[0]); if (wdev->DesiredTransmitSetting.field.MCS != MCS_AUTO) { DBGPRINT(RT_DEBUG_TRACE, ("@@@ IF-ra%d DesiredTransmitSetting.field.MCS = %d\n", pEntry->apidx, wdev->DesiredTransmitSetting.field.MCS)); set_ht_fixed_mcs(pAd, pEntry, wdev->DesiredTransmitSetting.field.MCS, wdev->HTPhyMode.field.MCS); } pEntry->MaxHTPhyMode.field.STBC = (ie_list->HTCapability.HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC)); // TODO: shiang-6590, check if this is necessary here, perforce didn't have this if (ie_list->HTCapability.HtCapParm.MpduDensity < 5) ie_list->HTCapability.HtCapParm.MpduDensity = 5; pEntry->MpduDensity = ie_list->HTCapability.HtCapParm.MpduDensity; pEntry->MaxRAmpduFactor = ie_list->HTCapability.HtCapParm.MaxRAmpduFactor; pEntry->MmpsMode = (UCHAR)ie_list->HTCapability.HtCapInfo.MimoPs; pEntry->AMsduSize = (UCHAR)ie_list->HTCapability.HtCapInfo.AMsduSize; if (pAd->CommonCfg.DesiredHtPhy.AmsduEnable && (pAd->CommonCfg.REGBACapability.field.AutoBA == FALSE)) CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_AMSDU_INUSED); if (ie_list->HTCapability.HtCapInfo.ShortGIfor20) CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE); if (ie_list->HTCapability.HtCapInfo.ShortGIfor40) CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE); if (ie_list->HTCapability.HtCapInfo.TxSTBC) CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE); if (ie_list->HTCapability.HtCapInfo.RxSTBC) CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE); if (ie_list->HTCapability.ExtHtCapInfo.PlusHTC) CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE); if (pAd->CommonCfg.bRdg && ie_list->HTCapability.ExtHtCapInfo.RDGSupport) CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE); if (ie_list->HTCapability.ExtHtCapInfo.MCSFeedback == 0x03) CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE); /* Record the received capability from association request */ NdisMoveMemory(&pEntry->HTCapability, &ie_list->HTCapability, sizeof(HT_CAPABILITY_IE)); #ifdef DOT11_VHT_AC if (WMODE_CAP_AC(pAd->CommonCfg.PhyMode) && (pAd->CommonCfg.Channel > 14) && ie_list->vht_cap_len) { pEntry->MaxHTPhyMode.field.MODE = MODE_VHT; if ((pEntry->MaxHTPhyMode.field.BW== BW_40) && (wdev->DesiredHtPhyInfo.vht_bw)) pEntry->MaxHTPhyMode.field.BW = BW_80; NdisMoveMemory(&pEntry->vht_cap_ie, &ie_list->vht_cap, sizeof(VHT_CAP_IE)); } #endif /* DOT11_VHT_AC */ } else { pAd->MacTab.fAnyStationIsLegacy = TRUE; NdisZeroMemory(&pEntry->HTCapability, sizeof(HT_CAPABILITY_IE)); } #endif /* DOT11_N_SUPPORT */ pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word; pEntry->CurrTxRate = pEntry->MaxSupportedRate; #ifdef MFB_SUPPORT pEntry->lastLegalMfb = 0; pEntry->isMfbChanged = FALSE; pEntry->fLastChangeAccordingMfb = FALSE; pEntry->toTxMrq = TRUE; pEntry->msiToTx = 0;/*has to increment whenever a mrq is sent */ pEntry->mrqCnt = 0; pEntry->pendingMfsi = 0; pEntry->toTxMfb = FALSE; pEntry->mfbToTx = 0; pEntry->mfb0 = 0; pEntry->mfb1 = 0; #endif /* MFB_SUPPORT */ pEntry->freqOffsetValid = FALSE; #ifdef TXBF_SUPPORT if (pAd->chipCap.FlgHwTxBfCap) TxBFInit(pAd, pEntry, supportsETxBF); #endif // TXBF_SUPPORT // // Initialize Rate Adaptation MlmeRAInit(pAd, pEntry); /* Set asic auto fall back */ if (wdev->bAutoTxRateSwitch == TRUE) { UCHAR TableSize = 0; MlmeSelectTxRateTable(pAd, pEntry, &pEntry->pTable, &TableSize, &pEntry->CurrTxRateIndex); MlmeNewTxRate(pAd, pEntry); pEntry->bAutoTxRateSwitch = TRUE; #ifdef NEW_RATE_ADAPT_SUPPORT if (! ADAPT_RATE_TABLE(pEntry->pTable)) #endif /* NEW_RATE_ADAPT_SUPPORT */ pEntry->HTPhyMode.field.ShortGI = GI_800; } else { pEntry->HTPhyMode.field.MCS = wdev->HTPhyMode.field.MCS; pEntry->bAutoTxRateSwitch = FALSE; /* If the legacy mode is set, overwrite the transmit setting of this entry. */ RTMPUpdateLegacyTxSetting((UCHAR)wdev->DesiredTransmitSetting.field.FixedTxMode, pEntry); } if (pEntry->AuthMode < Ndis802_11AuthModeWPA) ApLogEvent(pAd, pEntry->Addr, EVENT_ASSOCIATED); APUpdateCapabilityAndErpIe(pAd); #ifdef DOT11_N_SUPPORT APUpdateOperationMode(pAd); #endif /* DOT11_N_SUPPORT */ pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR; #ifdef HOSTAPD_SUPPORT if((wdev->Hostapd == TRUE) && ((wdev->AuthMode >= Ndis802_11AuthModeWPA) || wdev->IEEE8021X)) { RtmpOSWrielessEventSendExt(pAd->net_dev, RT_WLAN_EVENT_EXPIRED, -1, pEntry->Addr, NULL, 0, ((pEntry->CapabilityInfo & 0x0010) == 0 ? 0xFFFD : 0xFFFC)); } #endif /*HOSTAPD_SUPPORT*/ return MLME_SUCCESS; }
/* ========================================================================== Description: When waiting joining the (I)BSS, beacon received from external ========================================================================== */ static VOID ApCliPeerProbeRspAtJoinAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { USHORT LenVIE; UCHAR *VarIE = NULL; NDIS_802_11_VARIABLE_IEs *pVIE = NULL; APCLI_CTRL_MSG_STRUCT ApCliCtrlMsg; PAPCLI_STRUCT pApCliEntry = NULL; struct wifi_dev *wdev; #ifdef DOT11_N_SUPPORT UCHAR CentralChannel; #endif /* DOT11_N_SUPPORT */ USHORT ifIndex = (USHORT)(Elem->Priv); ULONG *pCurrState; BCN_IE_LIST *ie_list = NULL; UCHAR PhyMode = pAd->CommonCfg.PhyMode; PFRAME_802_11 pFrame = NULL; if (ifIndex >= MAX_APCLI_NUM) return; /* Init Variable IE structure */ os_alloc_mem(NULL, (UCHAR **)&VarIE, MAX_VIE_LEN); if (VarIE == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); goto LabelErr; } pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE; pVIE->Length = 0; os_alloc_mem(NULL, (UCHAR **)&ie_list, sizeof(BCN_IE_LIST)); if (ie_list == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate ie_list fail!!!\n", __FUNCTION__)); goto LabelErr; } NdisZeroMemory(ie_list, sizeof(BCN_IE_LIST)); pFrame = (PFRAME_802_11)Elem->Msg; pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].SyncCurrState; if (PeerBeaconAndProbeRspSanity(pAd, Elem->Msg, Elem->MsgLen, Elem->Channel, ie_list, &LenVIE, pVIE)) { /* BEACON from desired BSS/IBSS found. We should be able to decide most BSS parameters here. Q. But what happen if this JOIN doesn't conclude a successful ASSOCIATEION? Do we need to receover back all parameters belonging to previous BSS? A. Should be not. There's no back-door recover to previous AP. It still need a new JOIN-AUTH-ASSOC sequence. */ INT ssidEqualFlag = FALSE; INT ssidEmptyFlag = FALSE; INT bssidEqualFlag = FALSE; INT bssidEmptyFlag = FALSE; INT matchFlag = FALSE; ULONG Bssidx; LONG RealRssi = -127; #ifdef RT_CFG80211_P2P_CONCURRENT_DEVICE RealRssi = (LONG)(RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2))); #endif /* RT_CFG80211_P2P_CONCURRENT_DEVICE */ /* Update ScanTab */ Bssidx = BssTableSearch(&pAd->ScanTab, ie_list->Bssid, ie_list->Channel); if (Bssidx == BSS_NOT_FOUND) { /* discover new AP of this network, create BSS entry */ #ifdef CUSTOMER_DCC_FEATURE Bssidx = BssTableSetEntry(pAd, &pAd->ScanTab, ie_list, -127, LenVIE, pVIE, Elem->Snr0, Elem->Snr1); #else Bssidx = BssTableSetEntry(pAd, &pAd->ScanTab, ie_list, -127, LenVIE, pVIE); #endif if (Bssidx == BSS_NOT_FOUND) /* return if BSS table full */ { DBGPRINT(RT_DEBUG_ERROR, ("ERROR: Driver ScanTable Full In Apcli ProbeRsp Join\n")); goto LabelErr; } NdisMoveMemory(pAd->ScanTab.BssEntry[Bssidx].PTSF, &Elem->Msg[24], 4); NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4); NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4); pAd->ScanTab.BssEntry[Bssidx].MinSNR = Elem->Signal % 10; if (pAd->ScanTab.BssEntry[Bssidx].MinSNR == 0) pAd->ScanTab.BssEntry[Bssidx].MinSNR = -5; NdisMoveMemory(pAd->ScanTab.BssEntry[Bssidx].MacAddr, ie_list->Addr2, MAC_ADDR_LEN); } #ifdef RT_CFG80211_P2P_CONCURRENT_DEVICE DBGPRINT(RT_DEBUG_TRACE, ("Info: Update the SSID %s in Kernel Table\n", ie_list->Ssid)); RT_CFG80211_SCANNING_INFORM(pAd, Bssidx, ie_list->Channel, (UCHAR *)Elem->Msg, Elem->MsgLen, RealRssi); #endif /* RT_CFG80211_P2P_CONCURRENT_DEVICE */ pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex]; wdev = &pApCliEntry->wdev; /* Check the Probe-Rsp's Ssid. */ #ifdef WSC_AP_SUPPORT if ((pApCliEntry->WscControl.WscConfMode != WSC_DISABLE) && (pApCliEntry->WscControl.bWscTrigger == TRUE)) { #ifdef SMART_MESH if((pApCliEntry->WscControl.WscMode == 2) && (pApCliEntry->WscControl.bWscPBCAddrMode == TRUE)) bssidEqualFlag = MAC_ADDR_EQUAL(pApCliEntry->WscControl.WscPBCAddr, ie_list->Bssid); else #endif /* SMART_MESH */ { if(!MAC_ADDR_EQUAL(pApCliEntry->CfgApCliBssid, ZERO_MAC_ADDR)) bssidEqualFlag = MAC_ADDR_EQUAL(pApCliEntry->CfgApCliBssid, ie_list->Bssid); else bssidEmptyFlag = TRUE; } if(pApCliEntry->WscControl.WscSsid.SsidLength != 0) ssidEqualFlag = SSID_EQUAL(pApCliEntry->WscControl.WscSsid.Ssid, pApCliEntry->WscControl.WscSsid.SsidLength,ie_list->Ssid, ie_list->SsidLen); else ssidEmptyFlag = TRUE; } else #endif /* WSC_AP_SUPPORT */ { /* Check the Probe-Rsp's Bssid. */ if(!MAC_ADDR_EQUAL(pApCliEntry->CfgApCliBssid, ZERO_MAC_ADDR)) bssidEqualFlag = MAC_ADDR_EQUAL(pApCliEntry->CfgApCliBssid, ie_list->Bssid); else bssidEmptyFlag = TRUE; if(pApCliEntry->CfgSsidLen != 0) ssidEqualFlag = SSID_EQUAL(pApCliEntry->CfgSsid, pApCliEntry->CfgSsidLen, ie_list->Ssid, ie_list->SsidLen); else ssidEmptyFlag = TRUE; } /* bssid and ssid, Both match. */ if (bssidEqualFlag && ssidEqualFlag) matchFlag = TRUE; /* ssid match but bssid doesn't be indicate. */ else if(ssidEqualFlag && bssidEmptyFlag) matchFlag = TRUE; /* user doesn't indicate any bssid or ssid. AP-Clinet will auto pick a AP to join by most strong siganl strength. */ else if (bssidEmptyFlag && ssidEmptyFlag) { matchFlag = TRUE; #ifdef SMART_MESH matchFlag = FALSE; #endif /* SMART_MESH */ } DBGPRINT(RT_DEBUG_TRACE, ("SYNC - bssidEqualFlag=%d, ssidEqualFlag=%d, matchFlag=%d\n", bssidEqualFlag, ssidEqualFlag, matchFlag)); if (matchFlag) { /* Validate RSN IE if necessary, then copy store this information */ if ((LenVIE > 0) #ifdef WSC_AP_SUPPORT && ((pApCliEntry->WscControl.WscConfMode == WSC_DISABLE) || (pApCliEntry->WscControl.bWscTrigger == FALSE)) #endif /* WSC_AP_SUPPORT */ #ifdef RT_CFG80211_P2P_CONCURRENT_DEVICE /* When using CFG80211 and trigger WPS, do not check security. */ && ! (pApCliEntry->wpa_supplicant_info.WpaSupplicantUP & WPA_SUPPLICANT_ENABLE_WPS) #endif /* RT_CFG80211_P2P_CONCURRENT_DEVICE */ ) { if (ApCliValidateRSNIE(pAd, (PEID_STRUCT)pVIE, LenVIE, ifIndex)) { pApCliEntry->MlmeAux.VarIELen = LenVIE; NdisMoveMemory(pApCliEntry->MlmeAux.VarIEs, pVIE, pApCliEntry->MlmeAux.VarIELen); } else { /* ignore this response */ pApCliEntry->MlmeAux.VarIELen = 0; DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The RSN IE of this received Probe-resp is dis-match !!!!!!!!!! \n")); goto LabelErr; } } else { if (pApCliEntry->wdev.AuthMode >= Ndis802_11AuthModeWPA #ifdef WSC_AP_SUPPORT && ((pApCliEntry->WscControl.WscConfMode == WSC_DISABLE) || (pApCliEntry->WscControl.bWscTrigger == FALSE)) #endif /* WSC_AP_SUPPORT */ ) { /* ignore this response */ DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The received Probe-resp has empty RSN IE !!!!!!!!!! \n")); goto LabelErr; } pApCliEntry->MlmeAux.VarIELen = 0; } #ifdef SMART_MESH PSMART_MESH_CFG pSmartMeshCfg = NULL; pSmartMeshCfg = &pApCliEntry->SmartMeshCfg; if(((pSmartMeshCfg->HiFiFlagMask != 0) && (pSmartMeshCfg->HiFiFlagValue != 0)) && ((ie_list->VIEFlag & pSmartMeshCfg->HiFiFlagMask) == pSmartMeshCfg->HiFiFlagValue)) { pAd->ScanTab.BssEntry[Bssidx].bHyperFiPeer = TRUE; pApCliEntry->MlmeAux.bHyperFiPeer = TRUE; } else { pAd->ScanTab.BssEntry[Bssidx].bHyperFiPeer = FALSE; pApCliEntry->MlmeAux.bHyperFiPeer = FALSE; } if((pSmartMeshCfg->bHiFiPeerFilter == TRUE) && (pAd->ScanTab.BssEntry[Bssidx].bHyperFiPeer == FALSE)) { DBGPRINT(RT_DEBUG_OFF, ("Reject this PROBE_RSP due to not desired Hyper-Fi peer(%02X:%02X:%02X:%02X:%02X:%02X).\n",PRINT_MAC(pAd->ScanTab.BssEntry[Bssidx].Bssid))); goto LabelErr; } if(pAd->ScanTab.BssEntry[Bssidx].bSupportSmartMesh != ie_list->bSupportSmartMesh) pAd->ScanTab.BssEntry[Bssidx].bSupportSmartMesh = ie_list->bSupportSmartMesh; if(pAd->ScanTab.BssEntry[Bssidx].bSupportSmartMesh) { pApCliEntry->MlmeAux.bSupportSmartMesh = TRUE; DBGPRINT(RT_DEBUG_OFF, ("AP supports SMART MESH\n")); } else pApCliEntry->MlmeAux.bSupportSmartMesh = FALSE; if(pAd->ScanTab.BssEntry[Bssidx].bHyperFiPeer) DBGPRINT(RT_DEBUG_OFF, ("AP is Hyper-Fi device\n")); #endif /* SMART_MESH */ #ifdef MWDS if(pAd->ScanTab.BssEntry[Bssidx].bSupportMWDS != ie_list->bSupportMWDS) pAd->ScanTab.BssEntry[Bssidx].bSupportMWDS = ie_list->bSupportMWDS; if(pAd->ScanTab.BssEntry[Bssidx].bSupportMWDS) { pApCliEntry->MlmeAux.bSupportMWDS = TRUE; DBGPRINT(RT_DEBUG_OFF, ("AP supports MWDS\n")); } else pApCliEntry->MlmeAux.bSupportMWDS = FALSE; #endif /* MWDS */ #ifdef WSC_AP_SUPPORT #ifdef SMART_MESH_HIDDEN_WPS if(pAd->ScanTab.BssEntry[Bssidx].bSupportHiddenWPS != ie_list->bSupportHiddenWPS) pAd->ScanTab.BssEntry[Bssidx].bSupportHiddenWPS = ie_list->bSupportHiddenWPS; if(pAd->ScanTab.BssEntry[Bssidx].bSupportHiddenWPS) DBGPRINT(RT_DEBUG_OFF, ("AP supports HiddenWPS\n")); if(pAd->ScanTab.BssEntry[Bssidx].bRunningHiddenWPS != ie_list->bRunningHiddenWPS) pAd->ScanTab.BssEntry[Bssidx].bRunningHiddenWPS = ie_list->bRunningHiddenWPS; if(pAd->ScanTab.BssEntry[Bssidx].bRunningHiddenWPS) DBGPRINT(RT_DEBUG_OFF, ("AP is running HiddenWPS\n")); #endif /* SMART_MESH_HIDDEN_WPS */ #endif /* WSC_AP_SUPPORT */ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - receive desired PROBE_RSP at JoinWaitProbeRsp... Channel = %d\n", ie_list->Channel)); /* if the Bssid doesn't be indicated then you need to decide which AP to connect by most strong Rssi signal strength. */ if (bssidEqualFlag == FALSE) { /* caculate real rssi value. */ CHAR Rssi0 = ConvertToRssi(pAd, Elem->Rssi0, RSSI_0); CHAR Rssi1 = ConvertToRssi(pAd, Elem->Rssi1, RSSI_1); CHAR Rssi2 = ConvertToRssi(pAd, Elem->Rssi2, RSSI_2); LONG RealMaxRssi = (LONG)(RTMPMaxRssi(pAd, Rssi0, Rssi1, Rssi2)); DBGPRINT(RT_DEBUG_TRACE, ("SYNC - previous Rssi = %ld current Rssi=%ld\n", pApCliEntry->MlmeAux.Rssi, (LONG)RealMaxRssi)); if (pApCliEntry->MlmeAux.Rssi > (LONG)RealMaxRssi) goto LabelErr; else pApCliEntry->MlmeAux.Rssi = RealMaxRssi; } else { BOOLEAN Cancelled; RTMPCancelTimer(&pApCliEntry->MlmeAux.ProbeTimer, &Cancelled); } NdisMoveMemory(pApCliEntry->MlmeAux.Ssid, ie_list->Ssid, ie_list->SsidLen); pApCliEntry->MlmeAux.SsidLen = ie_list->SsidLen; NdisMoveMemory(pApCliEntry->MlmeAux.Bssid, ie_list->Bssid, MAC_ADDR_LEN); pApCliEntry->MlmeAux.CapabilityInfo = ie_list->CapabilityInfo & SUPPORTED_CAPABILITY_INFO; pApCliEntry->MlmeAux.BssType = ie_list->BssType; pApCliEntry->MlmeAux.BeaconPeriod = ie_list->BeaconPeriod; pApCliEntry->MlmeAux.Channel = ie_list->Channel; pApCliEntry->MlmeAux.CentralChannel = ie_list->Channel; /* by default */ pApCliEntry->MlmeAux.AtimWin = ie_list->AtimWin; pApCliEntry->MlmeAux.CfpPeriod = ie_list->CfParm.CfpPeriod; pApCliEntry->MlmeAux.CfpMaxDuration = ie_list->CfParm.CfpMaxDuration; pApCliEntry->MlmeAux.APRalinkIe = ie_list->RalinkIe; /* Copy AP's supported rate to MlmeAux for creating assoication request */ /* Also filter out not supported rate */ pApCliEntry->MlmeAux.SupRateLen = ie_list->SupRateLen; NdisMoveMemory(pApCliEntry->MlmeAux.SupRate, ie_list->SupRate, ie_list->SupRateLen); RTMPCheckRates(pAd, pApCliEntry->MlmeAux.SupRate, &pApCliEntry->MlmeAux.SupRateLen); pApCliEntry->MlmeAux.ExtRateLen = ie_list->ExtRateLen; NdisMoveMemory(pApCliEntry->MlmeAux.ExtRate, ie_list->ExtRate, ie_list->ExtRateLen); RTMPCheckRates(pAd, pApCliEntry->MlmeAux.ExtRate, &pApCliEntry->MlmeAux.ExtRateLen); #ifdef APCLI_CERT_SUPPORT /* Get the ext capability info element */ if (pAd->bApCliCertTest == TRUE #ifdef DOT11N_DRAFT3 && pAd->CommonCfg.bBssCoexEnable == TRUE #endif /* DOT11N_DRAFT3 */ ) { NdisMoveMemory(&pApCliEntry->MlmeAux.ExtCapInfo, &ie_list->ExtCapInfo,sizeof(ie_list->ExtCapInfo)); #ifdef DOT11_N_SUPPORT #ifdef DOT11N_DRAFT3 DBGPRINT(RT_DEBUG_TRACE, ("\x1b[31m ApCliMlmeAux.ExtCapInfo=%d \x1b[m\n", pApCliEntry->MlmeAux.ExtCapInfo.BssCoexistMgmtSupport)); //zero debug 210121122 pAd->CommonCfg.ExtCapIE.BssCoexistMgmtSupport = 1; #endif /* DOT11N_DRAFT3 */ #endif /* DOT11_N_SUPPORT */ } #endif /* APCLI_CERT_SUPPORT */ #ifdef DOT11_N_SUPPORT NdisZeroMemory(pApCliEntry->RxMcsSet,sizeof(pApCliEntry->RxMcsSet)); #ifdef APCLI_AUTO_BW_SUPPORT PhyMode = pApCliEntry->wdev.PhyMode; DBGPRINT(RT_DEBUG_OFF, ("%s: check HT Rule --> %d %d %d %d\n", __FUNCTION__, (ie_list->HtCapabilityLen > 0), (pApCliEntry->wdev.DesiredHtPhyInfo.bHtEnable), WMODE_CAP_N(pApCliEntry->wdev.PhyMode), !(pAd->CommonCfg.HT_DisallowTKIP && IS_INVALID_HT_SECURITY(wdev->WepStatus)))); #endif /* APCLI_AUTO_BW_SUPPORT */ /* filter out un-supported ht rates */ if ((ie_list->HtCapabilityLen > 0) && (pApCliEntry->wdev.DesiredHtPhyInfo.bHtEnable) && WMODE_CAP_N(PhyMode) && /* For Dissallow TKIP rule on STA */ !(pAd->CommonCfg.HT_DisallowTKIP && IS_INVALID_HT_SECURITY(wdev->WepStatus))) { RTMPZeroMemory(&pApCliEntry->MlmeAux.HtCapability, SIZE_HT_CAP_IE); pApCliEntry->MlmeAux.NewExtChannelOffset = ie_list->NewExtChannelOffset; pApCliEntry->MlmeAux.HtCapabilityLen = ie_list->HtCapabilityLen; ApCliCheckHt(pAd, ifIndex, &ie_list->HtCapability, &ie_list->AddHtInfo); if (ie_list->AddHtInfoLen > 0) { CentralChannel = ie_list->AddHtInfo.ControlChan; /* Check again the Bandwidth capability of this AP. */ CentralChannel = get_cent_ch_by_htinfo(pAd, &ie_list->AddHtInfo, &ie_list->HtCapability); pApCliEntry->MlmeAux.CentralChannel = CentralChannel; DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAtJoinAction HT===>CentralCh = %d, ControlCh = %d\n", CentralChannel, ie_list->AddHtInfo.ControlChan)); } } else #endif /* DOT11_N_SUPPORT */ { RTMPZeroMemory(&pApCliEntry->MlmeAux.HtCapability, SIZE_HT_CAP_IE); RTMPZeroMemory(&pApCliEntry->MlmeAux.AddHtInfo, SIZE_ADD_HT_INFO_IE); pApCliEntry->MlmeAux.HtCapabilityLen = 0; } ApCliUpdateMlmeRate(pAd, ifIndex); #ifdef DOT11_N_SUPPORT /* copy QOS related information */ if (WMODE_CAP_N(PhyMode)) { NdisMoveMemory(&pApCliEntry->MlmeAux.APEdcaParm, &ie_list->EdcaParm, sizeof(EDCA_PARM)); NdisMoveMemory(&pApCliEntry->MlmeAux.APQbssLoad, &ie_list->QbssLoad, sizeof(QBSS_LOAD_PARM)); NdisMoveMemory(&pApCliEntry->MlmeAux.APQosCapability, &ie_list->QosCapability, sizeof(QOS_CAPABILITY_PARM)); } else #endif /* DOT11_N_SUPPORT */ { NdisZeroMemory(&pApCliEntry->MlmeAux.APEdcaParm, sizeof(EDCA_PARM)); NdisZeroMemory(&pApCliEntry->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM)); NdisZeroMemory(&pApCliEntry->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM)); } DBGPRINT(RT_DEBUG_TRACE, ("APCLI SYNC - after JOIN, SupRateLen=%d, ExtRateLen=%d\n", pApCliEntry->MlmeAux.SupRateLen, pApCliEntry->MlmeAux.ExtRateLen)); if (ie_list->AironetCellPowerLimit != 0xFF) { /* We need to change our TxPower for CCX 2.0 AP Control of Client Transmit Power */ ChangeToCellPowerLimit(pAd, ie_list->AironetCellPowerLimit); } else /* Used the default TX Power Percentage. */ pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault; #ifdef APCLI_AUTO_BW_SUPPORT if ((ie_list->HtCapabilityLen > 0) && (ie_list->HtCapability.HtCapInfo.ChannelWidth == BW_40)) { ApCliAutoBwAction(pAd, ifIndex); } #endif /* APCLI_AUTO_BW_SUPPORT */ if(bssidEqualFlag == TRUE) { *pCurrState = APCLI_SYNC_IDLE; ApCliCtrlMsg.Status = MLME_SUCCESS; #ifdef MAC_REPEATER_SUPPORT ApCliCtrlMsg.BssIdx = ifIndex; ApCliCtrlMsg.CliIdx = 0xFF; #endif /* MAC_REPEATER_SUPPORT */ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_PROBE_RSP, sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex); } #ifdef SMART_MESH_MONITOR if(pFrame && (pFrame->Hdr.FC.SubType == SUBTYPE_PROBE_RSP)) { struct nsmpif_drvevnt_buf drvevnt; drvevnt.data.proberesp.type = NSMPIF_DRVEVNT_AP_PROBE_RESP; drvevnt.data.proberesp.channel = ie_list->Channel; COPY_MAC_ADDR(drvevnt.data.proberesp.ap_mac, ie_list->Addr2); drvevnt.data.proberesp.is_ucast = 1; drvevnt.data.proberesp.rate = pAd->LastMgmtRxRate; drvevnt.data.proberesp.rssi = RealRssi; drvevnt.data.proberesp.snr = ConvertToSnr(pAd, Elem->Signal); #ifdef RTMP_MAC if (pAd->chipCap.hif_type == HIF_RTMP) { if (IS_RT6352(pAd)) { if ((42 - drvevnt.data.proberesp.snr) >= 0) drvevnt.data.proberesp.snr = (42 - drvevnt.data.proberesp.snr); else drvevnt.data.proberesp.snr = 0; } } #endif /* RTMP_MAC */ NdisZeroMemory(drvevnt.data.proberesp.ssid,sizeof(drvevnt.data.proberesp.ssid)); NdisCopyMemory(drvevnt.data.proberesp.ssid,ie_list->Ssid,ie_list->SsidLen); drvevnt.data.proberesp.cap = 0; #ifdef DOT11_N_SUPPORT if(ie_list->HtCapabilityLen > 0) drvevnt.data.proberesp.cap |= NSMP_WLCAP_80211_N; #endif /* DOT11_N_SUPPORT */ #ifdef DOT11_VHT_AC if (ie_list->vht_cap_len > 0) drvevnt.data.proberesp.cap |= NSMP_WLCAP_80211_AC; #endif /* DOT11_VHT_AC */ // Bandwdith if (ie_list->HtCapability.HtCapInfo.ChannelWidth == BW_40) { #ifdef DOT11_VHT_AC if(ie_list->vht_op_len > 0 && ie_list->vht_op_ie.vht_op_info.ch_width >= 1) drvevnt.data.proberesp.cap |= NSMP_WLCAP_HT80; else #endif /* DOT11_VHT_AC */ drvevnt.data.proberesp.cap |= NSMP_WLCAP_HT40; } // RX/TX STREAM drvevnt.data.proberesp.cap |= \ (ie_list->HtCapability.MCSSet[3] != 0x00) ? (NSMP_WLCAP_RX_4_STREAMS|NSMP_WLCAP_TX_4_STREAMS) :\ (ie_list->HtCapability.MCSSet[2] != 0x00) ? (NSMP_WLCAP_RX_3_STREAMS|NSMP_WLCAP_TX_3_STREAMS) :\ (ie_list->HtCapability.MCSSet[1] != 0x00) ? (NSMP_WLCAP_RX_2_STREAMS|NSMP_WLCAP_TX_2_STREAMS) : 0; /* Vendor information element */ drvevnt.data.proberesp.ntgr_vie_len = ie_list->vendor_ie_len; NdisZeroMemory(drvevnt.data.proberesp.ntgr_vie,sizeof(drvevnt.data.proberesp.ntgr_vie)); if(ie_list->vendor_ie_len > 0) NdisCopyMemory(drvevnt.data.proberesp.ntgr_vie,ie_list->vendor_ie,ie_list->vendor_ie_len); RtmpOSWrielessEventSend(pAd->net_dev, RT_WLAN_EVENT_CUSTOM,NSMPIF_DRVEVNT_AP_PROBE_RESP, NULL, (PUCHAR)&drvevnt.data.proberesp, sizeof(drvevnt.data.proberesp)); } #endif /* SMART_MESH_MONITOR */ } } LabelErr: if (VarIE != NULL) os_free_mem(NULL, VarIE); if (ie_list != NULL) os_free_mem(NULL, ie_list); return; }
/* ======================================================================== Routine Description: Caller ensures we has 802.11n support. Calls at setting HT from AP/STASetinformation Arguments: pAd - Pointer to our adapter phymode - ======================================================================== */ VOID RTMPSetIndividualHT(struct rtmp_adapter *pAd, u8 apidx) { RT_PHY_INFO *pDesired_ht_phy = NULL; u8 TxStream = pAd->CommonCfg.TxStream; u8 DesiredMcs = MCS_AUTO; u8 encrypt_mode = Ndis802_11EncryptionDisabled; struct rtmp_wifi_dev *wdev; do { #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { if ((apidx < pAd->ApCfg.BssidNum) && (apidx < MAX_MBSSID_NUM(pAd)) && (apidx < HW_BEACON_MAX_NUM)) { wdev = &pAd->ApCfg.MBSSID[apidx].wdev; pDesired_ht_phy = &wdev->DesiredHtPhyInfo; DesiredMcs = wdev->DesiredTransmitSetting.field.MCS; #ifdef WFA_VHT_PF // TODO: Sigma, this code segment used to work around for Sigma Automation! if (WMODE_CAP_AC(pAd->CommonCfg.PhyMode) && (DesiredMcs != MCS_AUTO)) { DesiredMcs += ((TxStream - 1) << 4); pAd->ApCfg.MBSSID[apidx].DesiredTransmitSetting.field.FixedTxMode = FIXED_TXMODE_VHT; RT_CfgSetAutoFallBack(pAd, "0"); } else { RT_CfgSetAutoFallBack(pAd, "1"); } #endif /* WFA_VHT_PF */ encrypt_mode = wdev->WepStatus; pAd->ApCfg.MBSSID[apidx].wdev.bWmmCapable = true; wdev->bAutoTxRateSwitch = (DesiredMcs == MCS_AUTO) ? true : false; break; } DBGPRINT(RT_DEBUG_ERROR, ("RTMPSetIndividualHT: invalid apidx(%d)\n", apidx)); return; } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { wdev = &pAd->StaCfg.wdev; pDesired_ht_phy = &wdev->DesiredHtPhyInfo; DesiredMcs = wdev->DesiredTransmitSetting.field.MCS; encrypt_mode = wdev->WepStatus; break; } #endif /* CONFIG_STA_SUPPORT */ } while (false); if (pDesired_ht_phy == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("RTMPSetIndividualHT: invalid apidx(%d)\n", apidx)); return; } RTMPZeroMemory(pDesired_ht_phy, sizeof(RT_PHY_INFO)); DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetIndividualHT : Desired MCS = %d\n", DesiredMcs)); /* Check the validity of MCS */ if ((TxStream == 1) && ((DesiredMcs >= MCS_8) && (DesiredMcs <= MCS_15))) { DBGPRINT(RT_DEBUG_WARN, ("RTMPSetIndividualHT: MCS(%d) is invalid in 1S, reset it as MCS_7\n", DesiredMcs)); DesiredMcs = MCS_7; } if ((pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BW_20) && (DesiredMcs == MCS_32)) { DBGPRINT(RT_DEBUG_WARN, ("RTMPSetIndividualHT: MCS_32 is only supported in 40-MHz, reset it as MCS_0\n")); DesiredMcs = MCS_0; } #ifdef CONFIG_STA_SUPPORT if ((pAd->OpMode == OPMODE_STA) && (pAd->StaCfg.BssType == BSS_INFRA) && (apidx == MIN_NET_DEVICE_FOR_MBSSID)) ; else #endif /* CONFIG_STA_SUPPORT */ /* WFA recommend to restrict the encryption type in 11n-HT mode. So, the WEP and TKIP are not allowed in HT rate. */ if (pAd->CommonCfg.HT_DisallowTKIP && IS_INVALID_HT_SECURITY(encrypt_mode)) { #ifdef CONFIG_STA_SUPPORT pAd->StaCfg.bAdhocN = false; #endif /* CONFIG_STA_SUPPORT */ DBGPRINT(RT_DEBUG_WARN, ("%s : Use legacy rate in WEP/TKIP encryption mode (apidx=%d)\n", __FUNCTION__, apidx)); return; } if (pAd->CommonCfg.HT_Disable) { #ifdef CONFIG_STA_SUPPORT pAd->StaCfg.bAdhocN = false; #endif /* CONFIG_STA_SUPPORT */ DBGPRINT(RT_DEBUG_TRACE, ("%s : HT is disabled\n", __FUNCTION__)); return; } pDesired_ht_phy->bHtEnable = true; /* Decide desired Tx MCS*/ switch (TxStream) { case 1: if (DesiredMcs == MCS_AUTO) pDesired_ht_phy->MCSSet[0]= 0xff; else if (DesiredMcs <= MCS_7) pDesired_ht_phy->MCSSet[0]= 1<<DesiredMcs; break; case 2: if (DesiredMcs == MCS_AUTO) { pDesired_ht_phy->MCSSet[0]= 0xff; pDesired_ht_phy->MCSSet[1]= 0xff; } else if (DesiredMcs <= MCS_15) { ULONG mode; mode = DesiredMcs / 8; if (mode < 2) pDesired_ht_phy->MCSSet[mode] = (1 << (DesiredMcs - mode * 8)); } break; case 3: if (DesiredMcs == MCS_AUTO) { /* MCS0 ~ MCS23, 3 bytes */ pDesired_ht_phy->MCSSet[0]= 0xff; pDesired_ht_phy->MCSSet[1]= 0xff; pDesired_ht_phy->MCSSet[2]= 0xff; } else if (DesiredMcs <= MCS_23) { ULONG mode; mode = DesiredMcs / 8; if (mode < 3) pDesired_ht_phy->MCSSet[mode] = (1 << (DesiredMcs - mode * 8)); } break; } if(pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BW_40) { if (DesiredMcs == MCS_AUTO || DesiredMcs == MCS_32) pDesired_ht_phy->MCSSet[4] = 0x1; } /* update HT Rate setting */ if (pAd->OpMode == OPMODE_STA) { MlmeUpdateHtTxRates(pAd, BSS0); } else MlmeUpdateHtTxRates(pAd, apidx); if (WMODE_CAP_AC(pAd->CommonCfg.PhyMode)) { pDesired_ht_phy->bVhtEnable = true; rtmp_set_vht(pAd, pDesired_ht_phy); } }