VOID WdsPeerBeaconProc( IN PRTMP_ADAPTER pAd, IN PMAC_TABLE_ENTRY pEntry, IN USHORT CapabilityInfo, IN UCHAR MaxSupportedRateIn500Kbps, IN UCHAR MaxSupportedRateLen, IN BOOLEAN bWmmCapable, IN ULONG ClientRalinkIe, IN HT_CAPABILITY_IE *pHtCapability, IN UCHAR HtCapabilityLen) { UCHAR MaxSupportedRate = RATE_11; MaxSupportedRate = dot11_2_ra_rate(MaxSupportedRateIn500Kbps); if (pEntry && IS_ENTRY_WDS(pEntry)) { pEntry->MaxSupportedRate = min(pAd->CommonCfg.MaxTxRate, MaxSupportedRate); pEntry->RateLen = MaxSupportedRateLen; set_entry_phy_cfg(pAd, pEntry); pEntry->MaxHTPhyMode.field.BW = BW_20; pEntry->MinHTPhyMode.field.BW = BW_20; #ifdef DOT11_N_SUPPORT pEntry->HTCapability.MCSSet[0] = 0; pEntry->HTCapability.MCSSet[1] = 0; #endif /* DOT11_N_SUPPORT */ CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE); pEntry->CapabilityInfo = CapabilityInfo; set_sta_ra_cap(pAd, pEntry, ClientRalinkIe); #ifdef DOT11_N_SUPPORT /* If this Entry supports 802.11n, upgrade to HT rate. */ if ((HtCapabilityLen != 0) && WMODE_CAP_N(pAd->CommonCfg.PhyMode)) { ht_mode_adjust(pAd, pEntry, pHtCapability, &pAd->CommonCfg.DesiredHtPhy); /* find max fixed rate */ pEntry->MaxHTPhyMode.field.MCS = get_ht_max_mcs(pAd, &pAd->WdsTab.WdsEntry[pEntry->func_tb_idx].wdev.DesiredHtPhyInfo.MCSSet[0], &pHtCapability->MCSSet[0]); if ((pEntry->MaxHTPhyMode.field.MCS > pAd->WdsTab.WdsEntry[pEntry->func_tb_idx].wdev.HTPhyMode.field.MCS) && (pAd->WdsTab.WdsEntry[pEntry->func_tb_idx].wdev.HTPhyMode.field.MCS != MCS_AUTO)) pEntry->MaxHTPhyMode.field.MCS = pAd->WdsTab.WdsEntry[pEntry->func_tb_idx].wdev.HTPhyMode.field.MCS; pEntry->MaxHTPhyMode.field.STBC = (pHtCapability->HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC)); pEntry->MpduDensity = pHtCapability->HtCapParm.MpduDensity; pEntry->MaxRAmpduFactor = pHtCapability->HtCapParm.MaxRAmpduFactor; pEntry->MmpsMode = (UCHAR)pHtCapability->HtCapInfo.MimoPs; pEntry->AMsduSize = (UCHAR)pHtCapability->HtCapInfo.AMsduSize; if (pAd->CommonCfg.DesiredHtPhy.AmsduEnable && (pAd->CommonCfg.REGBACapability.field.AutoBA == FALSE)) CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_AMSDU_INUSED); set_sta_ht_cap(pAd, pEntry, pHtCapability); NdisMoveMemory(&pEntry->HTCapability, pHtCapability, sizeof(HT_CAPABILITY_IE)); } else { NdisZeroMemory(&pEntry->HTCapability, sizeof(HT_CAPABILITY_IE)); pAd->MacTab.fAnyStationIsLegacy = TRUE; } #endif /* DOT11_N_SUPPORT */ if (bWmmCapable #ifdef DOT11_N_SUPPORT || (pEntry->MaxHTPhyMode.field.MODE >= MODE_HTMIX) #endif /* DOT11_N_SUPPORT */ ) { CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE); } else { CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE); } pEntry->HTPhyMode.field.MODE = pEntry->MaxHTPhyMode.field.MODE; pEntry->HTPhyMode.field.STBC = pEntry->MaxHTPhyMode.field.STBC; pEntry->HTPhyMode.field.ShortGI = pEntry->MaxHTPhyMode.field.ShortGI; pEntry->HTPhyMode.field.BW = pEntry->MaxHTPhyMode.field.BW; switch (pEntry->HTPhyMode.field.MODE) { case MODE_OFDM: /* specific OFDM mode. */ pEntry->SupportRateMode = SUPPORT_OFDM_MODE; break; case MODE_CCK: pEntry->SupportRateMode = SUPPORT_CCK_MODE; break; #ifdef DOT11_N_SUPPORT case MODE_HTMIX: case MODE_HTGREENFIELD: pEntry->SupportRateMode = (SUPPORT_HT_MODE | SUPPORT_OFDM_MODE | SUPPORT_CCK_MODE); break; #endif /* DOT11_N_SUPPORT */ default: break; } } }
VOID WdsPeerBeaconProc( IN PRTMP_ADAPTER pAd, IN PMAC_TABLE_ENTRY pEntry, IN USHORT CapabilityInfo, IN UCHAR MaxSupportedRateIn500Kbps, IN UCHAR MaxSupportedRateLen, IN BOOLEAN bWmmCapable, IN ULONG ClientRalinkIe, IN HT_CAPABILITY_IE *pHtCapability, IN UCHAR HtCapabilityLen) { UCHAR MaxSupportedRate = RATE_11; MaxSupportedRate = dot11_2_ra_rate(MaxSupportedRateIn500Kbps); if (pEntry && IS_ENTRY_WDS(pEntry)) { pEntry->MaxSupportedRate = min(pAd->CommonCfg.MaxTxRate, MaxSupportedRate); pEntry->RateLen = MaxSupportedRateLen; set_entry_phy_cfg(pAd, pEntry); pEntry->MaxHTPhyMode.field.BW = BW_20; pEntry->MinHTPhyMode.field.BW = BW_20; #ifdef DOT11_N_SUPPORT pEntry->HTCapability.MCSSet[0] = 0; pEntry->HTCapability.MCSSet[1] = 0; #endif /* DOT11_N_SUPPORT */ CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE); pEntry->CapabilityInfo = CapabilityInfo; if (ClientRalinkIe & 0x00000004) CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RALINK_CHIPSET); else { CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_RALINK_CHIPSET); CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE); } if (pAd->CommonCfg.bAggregationCapable) { if ((pAd->CommonCfg.bPiggyBackCapable) && (ClientRalinkIe & 0x00000003) == 3) { CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE); CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE); /*RTMPSetPiggyBack(pAd, TRUE); */ } else if (ClientRalinkIe & 0x00000001) { CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE); CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE); } else { CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE); CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE); } } else { CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE); if ((pAd->CommonCfg.bPiggyBackCapable) && (ClientRalinkIe & 0x00000002) == 2) { CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE); /*RTMPSetPiggyBack(pAd, TRUE); */ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC -PiggyBack2= 1\n")); } else CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE); } #ifdef DOT11_N_SUPPORT /* If this Entry supports 802.11n, upgrade to HT rate. */ if ((HtCapabilityLen != 0) && WMODE_CAP_N(pAd->CommonCfg.PhyMode)) { ht_mode_adjust(pAd, pEntry, pHtCapability, &pAd->CommonCfg.DesiredHtPhy); /* find max fixed rate */ pEntry->MaxHTPhyMode.field.MCS = get_ht_max_mcs(pAd, &pAd->WdsTab.WdsEntry[pEntry->MatchWDSTabIdx].DesiredHtPhyInfo.MCSSet[0], &pHtCapability->MCSSet[0]); if ((pEntry->MaxHTPhyMode.field.MCS > pAd->WdsTab.WdsEntry[pEntry->MatchWDSTabIdx].HTPhyMode.field.MCS) && (pAd->WdsTab.WdsEntry[pEntry->MatchWDSTabIdx].HTPhyMode.field.MCS != MCS_AUTO)) pEntry->MaxHTPhyMode.field.MCS = pAd->WdsTab.WdsEntry[pEntry->MatchWDSTabIdx].HTPhyMode.field.MCS; pEntry->MaxHTPhyMode.field.STBC = (pHtCapability->HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC)); pEntry->MpduDensity = pHtCapability->HtCapParm.MpduDensity; pEntry->MaxRAmpduFactor = pHtCapability->HtCapParm.MaxRAmpduFactor; pEntry->MmpsMode = (UCHAR)pHtCapability->HtCapInfo.MimoPs; pEntry->AMsduSize = (UCHAR)pHtCapability->HtCapInfo.AMsduSize; if (pAd->CommonCfg.DesiredHtPhy.AmsduEnable && (pAd->CommonCfg.REGBACapability.field.AutoBA == FALSE)) CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_AMSDU_INUSED); if (pHtCapability->HtCapInfo.ShortGIfor20) CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE); if (pHtCapability->HtCapInfo.ShortGIfor40) CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE); if (pHtCapability->HtCapInfo.TxSTBC) CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE); if (pHtCapability->HtCapInfo.RxSTBC) CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE); if (pHtCapability->ExtHtCapInfo.PlusHTC) CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE); if (pAd->CommonCfg.bRdg && pHtCapability->ExtHtCapInfo.RDGSupport) CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE); else CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE); if (pHtCapability->ExtHtCapInfo.MCSFeedback == 0x03) CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE); NdisMoveMemory(&pEntry->HTCapability, pHtCapability, sizeof(HT_CAPABILITY_IE)); } else { NdisZeroMemory(&pEntry->HTCapability, sizeof(HT_CAPABILITY_IE)); pAd->MacTab.fAnyStationIsLegacy = TRUE; } #endif /* DOT11_N_SUPPORT */ if (bWmmCapable #ifdef DOT11_N_SUPPORT || (pEntry->MaxHTPhyMode.field.MODE >= MODE_HTMIX) #endif /* DOT11_N_SUPPORT */ ) { CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE); } else { CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE); } pEntry->HTPhyMode.field.MODE = pEntry->MaxHTPhyMode.field.MODE; pEntry->HTPhyMode.field.STBC = pEntry->MaxHTPhyMode.field.STBC; pEntry->HTPhyMode.field.ShortGI = pEntry->MaxHTPhyMode.field.ShortGI; pEntry->HTPhyMode.field.BW = pEntry->MaxHTPhyMode.field.BW; switch (pEntry->HTPhyMode.field.MODE) { case MODE_OFDM: /* specific OFDM mode. */ pEntry->SupportRateMode = SUPPORT_OFDM_MODE; break; case MODE_CCK: pEntry->SupportRateMode = SUPPORT_CCK_MODE; break; #ifdef DOT11_N_SUPPORT case MODE_HTMIX: case MODE_HTGREENFIELD: pEntry->SupportRateMode = (SUPPORT_HT_MODE | SUPPORT_OFDM_MODE | SUPPORT_CCK_MODE); break; #endif /* DOT11_N_SUPPORT */ default: break; } } }
/* ========================================================================== Description: assign a new AID to the newly associated/re-associated STA and decide its MaxSupportedRate and CurrTxRate. Both rates should not exceed AP's capapbility Return: MLME_SUCCESS - association successfully built others - association failed due to resource issue ========================================================================== */ static USHORT APBuildAssociation( IN RTMP_ADAPTER *pAd, IN MAC_TABLE_ENTRY *pEntry, IN IE_LISTS *ie_list, IN UCHAR MaxSupportedRateIn500Kbps, OUT USHORT *pAid) { USHORT StatusCode = MLME_SUCCESS; UCHAR MaxSupportedRate = RATE_11; MULTISSID_STRUCT *wdev; MaxSupportedRate = dot11_2_ra_rate(MaxSupportedRateIn500Kbps); if ((WMODE_EQUAL(pAd->CommonCfg.PhyMode, WMODE_G) #ifdef DOT11_N_SUPPORT || WMODE_EQUAL(pAd->CommonCfg.PhyMode, (WMODE_G | WMODE_GN)) #endif /* DOT11_N_SUPPORT */ ) && (MaxSupportedRate < RATE_FIRST_OFDM_RATE) ) return MLME_ASSOC_REJ_DATA_RATE; #ifdef DOT11_N_SUPPORT /* 11n only */ if (WMODE_HT_ONLY(pAd->CommonCfg.PhyMode)&& (ie_list->ht_cap_len == 0)) return MLME_ASSOC_REJ_DATA_RATE; #endif /* DOT11_N_SUPPORT */ if (!pEntry) return MLME_UNSPECIFY_FAIL; if (pEntry && ((pEntry->Sst == SST_AUTH) || (pEntry->Sst == SST_ASSOC))) { /* TODO: */ /* should qualify other parameters, for example - capablity, supported rates, listen interval, ... etc */ /* to decide the Status Code */ /**pAid = APAssignAid(pAd, pEntry); */ /*pEntry->Aid = *pAid; */ *pAid = pEntry->Aid; pEntry->NoDataIdleCount = 0; pEntry->StaConnectTime = 0; { /* check the validity of the received RSNIE */ if ((StatusCode = APValidateRSNIE(pAd, pEntry, &ie_list->RSN_IE[0], ie_list->RSNIE_Len)) != MLME_SUCCESS) return StatusCode; } NdisMoveMemory(pEntry->RSN_IE, &ie_list->RSN_IE[0], ie_list->RSNIE_Len); pEntry->RSNIE_Len = ie_list->RSNIE_Len; wdev = &pAd->ApCfg.MBSSID[pEntry->apidx]; if (*pAid == 0) StatusCode = MLME_ASSOC_REJ_UNABLE_HANDLE_STA; else if ((pEntry->RSNIE_Len == 0) && (wdev->AuthMode >= Ndis802_11AuthModeWPA) #ifdef HOSTAPD_SUPPORT && (wdev->Hostapd == TRUE) #endif ) { StatusCode = MLME_ASSOC_DENY_OUT_SCOPE; #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*/ } else { StatusCode = update_associated_mac_entry(pAd, pEntry, ie_list, MaxSupportedRate); } } else /* CLASS 3 error should have been handled beforehand; here should be MAC table full */ StatusCode = MLME_ASSOC_REJ_UNABLE_HANDLE_STA; if (StatusCode == MLME_SUCCESS) { if (ie_list->bWmmCapable) { CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE); } else { CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE); } } return StatusCode; }