/* ========================================================================== Description: Upper Layer request to kick out a STA ========================================================================== */ static VOID APMlmeDeauthReqAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { MLME_DEAUTH_REQ_STRUCT *pInfo; HEADER_802_11 Hdr; PUCHAR pOutBuffer = NULL; NDIS_STATUS NStatus; ULONG FrameLen = 0; MAC_TABLE_ENTRY *pEntry; UCHAR apidx; pInfo = (MLME_DEAUTH_REQ_STRUCT *)Elem->Msg; if (Elem->Wcid < MAX_LEN_OF_MAC_TABLE) { pEntry = &pAd->MacTab.Content[Elem->Wcid]; if (!pEntry) return; #ifdef WAPI_SUPPORT WAPI_InternalCmdAction(pAd, pEntry->AuthMode, pEntry->func_tb_idx, pEntry->Addr, WAI_MLME_DISCONNECT); #endif /* WAPI_SUPPORT */ /* send wireless event - for deauthentication */ RTMPSendWirelessEvent(pAd, IW_DEAUTH_EVENT_FLAG, pInfo->Addr, 0, 0); ApLogEvent(pAd, pInfo->Addr, EVENT_DISASSOCIATED); apidx = pEntry->func_tb_idx; /* 1. remove this STA from MAC table */ MacTableDeleteEntry(pAd, Elem->Wcid, pInfo->Addr); /* 2. send out DE-AUTH request frame */ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); if (NStatus != NDIS_STATUS_SUCCESS) return; DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Send DE-AUTH req to %02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(pInfo->Addr))); MgtMacHeaderInit(pAd, &Hdr, SUBTYPE_DEAUTH, 0, pInfo->Addr, pAd->ApCfg.MBSSID[apidx].wdev.if_addr, pAd->ApCfg.MBSSID[apidx].wdev.bssid); MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(HEADER_802_11), &Hdr, 2, &pInfo->Reason, END_OF_ARGS); MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); } }
static VOID APPeerDeauthReqAction( IN PRTMP_ADAPTER pAd, IN PMLME_QUEUE_ELEM Elem) { UCHAR Addr2[MAC_ADDR_LEN]; USHORT Reason; UINT16 SeqNum; MAC_TABLE_ENTRY *pEntry; if (! PeerDeauthReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &SeqNum, &Reason)) return; pEntry = NULL; /*pEntry = MacTableLookup(pAd, Addr2); */ if (Elem->Wcid < MAX_LEN_OF_MAC_TABLE) { pEntry = &pAd->MacTab.Content[Elem->Wcid]; #ifdef DOT1X_SUPPORT /* Notify 802.1x daemon to clear this sta info */ if (pEntry->AuthMode == Ndis802_11AuthModeWPA || pEntry->AuthMode == Ndis802_11AuthModeWPA2 || pAd->ApCfg.MBSSID[pEntry->apidx].IEEE8021X) DOT1X_InternalCmdAction(pAd, pEntry, DOT1X_DISCONNECT_ENTRY); #endif /* DOT1X_SUPPORT */ #ifdef WAPI_SUPPORT WAPI_InternalCmdAction(pAd, pEntry->AuthMode, pEntry->apidx, pEntry->Addr, WAI_MLME_DISCONNECT); #endif /* WAPI_SUPPORT */ /* send wireless event - for deauthentication */ RTMPSendWirelessEvent(pAd, IW_DEAUTH_EVENT_FLAG, Addr2, 0, 0); ApLogEvent(pAd, Addr2, EVENT_DISASSOCIATED); if (pEntry->CMTimerRunning == TRUE) { /* If one who initilized Counter Measure deauth itself, AP doesn't log the MICFailTime */ pAd->ApCfg.aMICFailTime = pAd->ApCfg.PrevaMICFailTime; } MacTableDeleteEntry(pAd, Elem->Wcid, Addr2); DBGPRINT(RT_DEBUG_TRACE, ("AUTH - receive DE-AUTH(seq-%d) from " "%02x:%02x:%02x:%02x:%02x:%02x, reason=%d\n", SeqNum, Addr2[0], Addr2[1], Addr2[2], Addr2[3], Addr2[4], Addr2[5], Reason)); } }
/* ========================================================================== Description: Upper Layer request to kick out a STA ========================================================================== */ static VOID APMlmeDeauthReqAction( IN struct rtmp_adapter *pAd, IN MLME_QUEUE_ELEM *Elem) { MLME_DEAUTH_REQ_STRUCT *pInfo; HEADER_802_11 Hdr; u8 * pOutBuffer = NULL; int NStatus; ULONG FrameLen = 0; MAC_TABLE_ENTRY *pEntry; u8 apidx; pInfo = (MLME_DEAUTH_REQ_STRUCT *)Elem->Msg; if (Elem->Wcid < MAX_LEN_OF_MAC_TABLE) { pEntry = &pAd->MacTab.Content[Elem->Wcid]; if (!pEntry) return; /* send wireless event - for deauthentication */ RTMPSendWirelessEvent(pAd, IW_DEAUTH_EVENT_FLAG, pInfo->Addr, 0, 0); ApLogEvent(pAd, pInfo->Addr, EVENT_DISASSOCIATED); apidx = pEntry->apidx; /* 1. remove this STA from MAC table */ MacTableDeleteEntry(pAd, Elem->Wcid, pInfo->Addr); /* 2. send out DE-AUTH request frame */ pOutBuffer = kmalloc(MGMT_DMA_BUFFER_SIZE, GFP_ATOMIC); if (pOutBuffer == NULL) return; DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Send DE-AUTH req to %02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(pInfo->Addr))); MgtMacHeaderInit(pAd, &Hdr, SUBTYPE_DEAUTH, 0, pInfo->Addr, pAd->ApCfg.MBSSID[apidx].wdev.if_addr, pAd->ApCfg.MBSSID[apidx].wdev.bssid); MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(HEADER_802_11), &Hdr, 2, &pInfo->Reason, END_OF_ARGS); MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); kfree(pOutBuffer); } }
static VOID APPeerDeauthReqAction( IN PRTMP_ADAPTER pAd, IN PMLME_QUEUE_ELEM Elem) { UCHAR Addr2[MAC_ADDR_LEN]; UINT16 Reason, SeqNum; MAC_TABLE_ENTRY *pEntry; if (! PeerDeauthReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &SeqNum, &Reason)) return; pEntry = NULL; /*pEntry = MacTableLookup(pAd, Addr2); */ if (Elem->Wcid < MAX_LEN_OF_MAC_TABLE) { pEntry = &pAd->MacTab.Content[Elem->Wcid]; //JERRY { BSS_STRUCT *pMbss = &pAd->ApCfg.MBSSID[pEntry->apidx]; PFRAME_802_11 Fr = (PFRAME_802_11)Elem->Msg; unsigned char *tmp = (unsigned char *)pMbss->wdev.bssid; unsigned char *tmp2 = (unsigned char *)&Fr->Hdr.Addr1; if (memcmp(&Fr->Hdr.Addr1, pMbss->wdev.bssid, 6) != 0) { printk("da not match bssid,bssid:0x%02x%02x%02x%02x%02x%02x, addr1:0x%02x%02x%02x%02x%02x%02x\n",*tmp, *(tmp+1), *(tmp+2), *(tmp+3), *(tmp+4), *(tmp+5), *tmp2, *(tmp2+1), *(tmp2+2), *(tmp2+3), *(tmp2+4), *(tmp2+5)); return; } else printk("da match,0x%02x%02x%02x%02x%02x%02x\n", *tmp, *(tmp+1), *(tmp+2), *(tmp+3), *(tmp+4), *(tmp+5)); } #ifdef DOT1X_SUPPORT /* Notify 802.1x daemon to clear this sta info */ if (pEntry->AuthMode == Ndis802_11AuthModeWPA || pEntry->AuthMode == Ndis802_11AuthModeWPA2 || pAd->ApCfg.MBSSID[pEntry->func_tb_idx].wdev.IEEE8021X) DOT1X_InternalCmdAction(pAd, pEntry, DOT1X_DISCONNECT_ENTRY); #endif /* DOT1X_SUPPORT */ #ifdef WAPI_SUPPORT WAPI_InternalCmdAction(pAd, pEntry->AuthMode, pEntry->func_tb_idx, pEntry->Addr, WAI_MLME_DISCONNECT); #endif /* WAPI_SUPPORT */ /* send wireless event - for deauthentication */ RTMPSendWirelessEvent(pAd, IW_DEAUTH_EVENT_FLAG, Addr2, 0, 0); ApLogEvent(pAd, Addr2, EVENT_DISASSOCIATED); if (pEntry->CMTimerRunning == TRUE) { /* If one who initilized Counter Measure deauth itself, AP doesn't log the MICFailTime */ pAd->ApCfg.aMICFailTime = pAd->ApCfg.PrevaMICFailTime; } MacTableDeleteEntry(pAd, Elem->Wcid, Addr2); DBGPRINT(RT_DEBUG_TRACE, ("AUTH - receive DE-AUTH(seq-%d) from " "%02x:%02x:%02x:%02x:%02x:%02x, reason=%d\n", SeqNum, PRINT_MAC(Addr2), Reason)); #ifdef MAC_REPEATER_SUPPORT if (pAd->ApCfg.bMACRepeaterEn == TRUE) { UCHAR apCliIdx, CliIdx; REPEATER_CLIENT_ENTRY *pReptEntry = NULL; pReptEntry = RTMPLookupRepeaterCliEntry(pAd, TRUE, Addr2); if (pReptEntry && (pReptEntry->CliConnectState != 0)) { apCliIdx = pReptEntry->MatchApCliIdx; CliIdx = pReptEntry->MatchLinkIdx; MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_DISCONNECT_REQ, 0, NULL, (64 + MAX_EXT_MAC_ADDR_SIZE*apCliIdx + CliIdx)); RTMP_MLME_HANDLER(pAd); RTMPRemoveRepeaterEntry(pAd, apCliIdx, CliIdx); } } #endif /* MAC_REPEATER_SUPPORT */ } }
static VOID APPeerDeauthReqAction( IN PRTMP_ADAPTER pAd, IN PMLME_QUEUE_ELEM Elem) { UCHAR Addr2[MAC_ADDR_LEN]; USHORT Reason; UINT16 SeqNum; MAC_TABLE_ENTRY *pEntry; if (! PeerDeauthReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &SeqNum, &Reason)) return; pEntry = NULL; /*pEntry = MacTableLookup(pAd, Addr2); */ if (Elem->Wcid < MAX_LEN_OF_MAC_TABLE) { pEntry = &pAd->MacTab.Content[Elem->Wcid]; #ifdef DOT1X_SUPPORT /* Notify 802.1x daemon to clear this sta info */ if (pEntry->AuthMode == Ndis802_11AuthModeWPA || pEntry->AuthMode == Ndis802_11AuthModeWPA2 || pAd->ApCfg.MBSSID[pEntry->apidx].IEEE8021X) DOT1X_InternalCmdAction(pAd, pEntry, DOT1X_DISCONNECT_ENTRY); #endif /* DOT1X_SUPPORT */ #ifdef WAPI_SUPPORT WAPI_InternalCmdAction(pAd, pEntry->AuthMode, pEntry->apidx, pEntry->Addr, WAI_MLME_DISCONNECT); #endif /* WAPI_SUPPORT */ /* send wireless event - for deauthentication */ RTMPSendWirelessEvent(pAd, IW_DEAUTH_EVENT_FLAG, Addr2, 0, 0); ApLogEvent(pAd, Addr2, EVENT_DISASSOCIATED); if (pEntry->CMTimerRunning == TRUE) { /* If one who initilized Counter Measure deauth itself, AP doesn't log the MICFailTime */ pAd->ApCfg.aMICFailTime = pAd->ApCfg.PrevaMICFailTime; } MacTableDeleteEntry(pAd, Elem->Wcid, Addr2); DBGPRINT(RT_DEBUG_TRACE, // ("AUTH - receive DE-AUTH(seq-%d) from " "%02x:%02x:%02x:%02x:%02x:%02x, reason=%d\n", SeqNum, Addr2[0], Addr2[1], Addr2[2], Addr2[3], Addr2[4], Addr2[5], Reason)); #ifdef MAC_REPEATER_SUPPORT if (pAd->ApCfg.bMACRepeaterEn == TRUE) { UCHAR apCliIdx, CliIdx; REPEATER_CLIENT_ENTRY *pReptEntry = NULL; pReptEntry = RTMPLookupRepeaterCliEntry(pAd, TRUE, Addr2); if (pReptEntry && (pReptEntry->CliConnectState != 0)) { apCliIdx = pReptEntry->MatchApCliIdx; CliIdx = pReptEntry->MatchLinkIdx; MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_DISCONNECT_REQ, 0, NULL, (64 + MAX_EXT_MAC_ADDR_SIZE*apCliIdx + CliIdx)); RTMP_MLME_HANDLER(pAd); RTMPRemoveRepeaterEntry(pAd, apCliIdx, CliIdx); } } #endif /* MAC_REPEATER_SUPPORT */ } }
/* ========================================================================== Description: Function to handle countermeasures active attack. Init 60-sec timer if necessary. Return: ========================================================================== */ VOID HandleCounterMeasure(struct rtmp_adapter *pAd, MAC_TABLE_ENTRY *pEntry) { INT i; bool Cancelled; if (!pEntry) return; /* Todo by AlbertY - Not support currently in ApClient-link */ if (IS_ENTRY_APCLI(pEntry)) return; /* if entry not set key done, ignore this RX MIC ERROR */ if ((pEntry->WpaState < AS_PTKINITDONE) || (pEntry->GTKState != REKEY_ESTABLISHED)) return; DBGPRINT(RT_DEBUG_TRACE, ("HandleCounterMeasure ===> \n")); /* record which entry causes this MIC error, if this entry sends disauth/disassoc, AP doesn't need to log the CM */ pEntry->CMTimerRunning = true; pAd->ApCfg.MICFailureCounter++; /* send wireless event - for MIC error */ RTMPSendWirelessEvent(pAd, IW_MIC_ERROR_EVENT_FLAG, pEntry->Addr, 0, 0); if (pAd->ApCfg.CMTimerRunning == true) { DBGPRINT(RT_DEBUG_ERROR, ("Receive CM Attack Twice within 60 seconds ====>>> \n")); /* send wireless event - for counter measures */ RTMPSendWirelessEvent(pAd, IW_COUNTER_MEASURES_EVENT_FLAG, pEntry->Addr, 0, 0); ApLogEvent(pAd, pEntry->Addr, EVENT_COUNTER_M); /* renew GTK */ GenRandom(pAd, pAd->ApCfg.MBSSID[pEntry->apidx].wdev.bssid, pAd->ApCfg.MBSSID[pEntry->apidx].GNonce); /* Cancel CounterMeasure Timer */ RTMPCancelTimer(&pAd->ApCfg.CounterMeasureTimer, &Cancelled); pAd->ApCfg.CMTimerRunning = false; for (i = 0; i < MAX_LEN_OF_MAC_TABLE; i++) { /* happened twice within 60 sec, AP SENDS disaccociate all associated STAs. All STA's transition to State 2 */ if (IS_ENTRY_CLIENT(&pAd->MacTab.Content[i])) { MlmeDeAuthAction(pAd, &pAd->MacTab.Content[i], REASON_MIC_FAILURE, false); } } /* Further, ban all Class 3 DATA transportation for a period 0f 60 sec disallow new association , too */ pAd->ApCfg.BANClass3Data = true; /* check how many entry left... should be zero */ /*pAd->ApCfg.MBSSID[pEntry->apidx].GKeyDoneStations = pAd->MacTab.Size; */ /*DBGPRINT(RT_DEBUG_TRACE, ("GKeyDoneStations=%d \n", pAd->ApCfg.MBSSID[pEntry->apidx].GKeyDoneStations)); */ } RTMPSetTimer(&pAd->ApCfg.CounterMeasureTimer, 60 * MLME_TASK_EXEC_INTV * MLME_TASK_EXEC_MULTIPLE); pAd->ApCfg.CMTimerRunning = true; pAd->ApCfg.PrevaMICFailTime = pAd->ApCfg.aMICFailTime; RTMP_GetCurrentSystemTime(&pAd->ApCfg.aMICFailTime); }
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; }