diff --git a/src/wifi/model/rate-control/minstrel-ht-wifi-manager.cc b/src/wifi/model/rate-control/minstrel-ht-wifi-manager.cc index 3fd41158b..ed44a10b2 100644 --- a/src/wifi/model/rate-control/minstrel-ht-wifi-manager.cc +++ b/src/wifi/model/rate-control/minstrel-ht-wifi-manager.cc @@ -79,6 +79,16 @@ const std::map minstre .maxStreams = 8, }, }, + { + WIFI_MOD_CLASS_EHT, + { + .groupType = WIFI_MINSTREL_GROUP_EHT, + .maxMcs = 13, + .maxWidth = MHz_u{320}, + .guardIntervals = {NanoSeconds(3200), NanoSeconds(1600), NanoSeconds(800)}, + .maxStreams = 8, + }, + }, }; /// MinstrelHtWifiRemoteStation structure @@ -307,10 +317,15 @@ MinstrelHtWifiManager::DoInitialize() m_numGroups += GetNumGroups(WIFI_MOD_CLASS_HE); m_numRates = minstrelHtStandardInfos.at(WIFI_MOD_CLASS_HE).maxMcs + 1; } + if (GetEhtSupported()) + { + m_numGroups += GetNumGroups(WIFI_MOD_CLASS_EHT); + m_numRates = minstrelHtStandardInfos.at(WIFI_MOD_CLASS_EHT).maxMcs + 1; + } /** * Initialize the groups array. - * The HT groups come first, then the VHT ones, and finally the HE ones. + * The HT groups come first, then the VHT ones, then the HE ones, and finally the EHT ones. * Minstrel maintains different types of indexes: * - A global continuous index, which identifies all rates within all groups, in [0, * m_numGroups * m_numRates] @@ -340,6 +355,12 @@ MinstrelHtWifiManager::DoInitialize() // Initialize all HE groups InitializeGroups(WIFI_MOD_CLASS_HE); } + + if (GetEhtSupported()) + { + // Initialize all EHT groups + InitializeGroups(WIFI_MOD_CLASS_EHT); + } } bool @@ -1670,6 +1691,12 @@ MinstrelHtWifiManager::RateInit(MinstrelHtWifiRemoteStation* station) { station->m_groupsTable[groupId].m_supported = false; + if ((m_minstrelGroups[groupId].type == WIFI_MINSTREL_GROUP_EHT) && + !GetEhtSupported(station)) + { + // It is a EHT group but the receiver does not support EHT: skip + continue; + } if ((m_minstrelGroups[groupId].type == WIFI_MINSTREL_GROUP_HE) && !GetHeSupported(station)) { @@ -1682,10 +1709,18 @@ MinstrelHtWifiManager::RateInit(MinstrelHtWifiRemoteStation* station) // It is a VHT group but the receiver does not support VHT: skip continue; } - if ((m_minstrelGroups[groupId].type != WIFI_MINSTREL_GROUP_HE) && + if ((m_minstrelGroups[groupId].type != WIFI_MINSTREL_GROUP_EHT) && + GetEhtSupported(station) && m_useLatestAmendmentOnly) + { + // It is not a EHT group and the receiver supports EHT: skip since + // UseLatestAmendmentOnly attribute is enabled + continue; + } + if (!GetEhtSupported(station) && + (m_minstrelGroups[groupId].type != WIFI_MINSTREL_GROUP_HE) && GetHeSupported(station) && m_useLatestAmendmentOnly) { - // It is not a HE group and the receiver supports HE: skip since + // It is not a HE group and the receiver supports HE (but not EHT): skip since // UseLatestAmendmentOnly attribute is enabled continue; } @@ -2092,6 +2127,19 @@ MinstrelHtWifiManager::GetHeGroupId(uint8_t streams, Time guardInterval, MHz_u c return allHtGroups + allVhtGroups + heGroupId; } +std::size_t +MinstrelHtWifiManager::GetEhtGroupId(uint8_t streams, Time guardInterval, MHz_u chWidth) +{ + NS_LOG_FUNCTION(this << streams << guardInterval << chWidth); + // This check is needed since HT is not supported in 6 GHz band + std::size_t allHtGroups = (GetHtSupported()) ? GetNumGroups(WIFI_MOD_CLASS_HT) : 0; + // This check is needed since VHT is not supported in 2.4 and 6 GHz bands + std::size_t allVhtGroups = (GetVhtSupported()) ? GetNumGroups(WIFI_MOD_CLASS_VHT) : 0; + const auto allHeGroups = GetNumGroups(WIFI_MOD_CLASS_HE); + const auto ehtGroupId = GetIdInGroup(WIFI_MOD_CLASS_EHT, streams, guardInterval, chWidth); + return allHtGroups + allVhtGroups + allHeGroups + ehtGroupId; +} + std::size_t MinstrelHtWifiManager::GetGroupIdForType(McsGroupType type, uint8_t streams, @@ -2106,6 +2154,8 @@ MinstrelHtWifiManager::GetGroupIdForType(McsGroupType type, return GetVhtGroupId(streams, guardInterval, chWidth); case WIFI_MINSTREL_GROUP_HE: return GetHeGroupId(streams, guardInterval, chWidth); + case WIFI_MINSTREL_GROUP_EHT: + return GetEhtGroupId(streams, guardInterval, chWidth); default: NS_ABORT_MSG("Unknown group type: " << type); } diff --git a/src/wifi/model/rate-control/minstrel-ht-wifi-manager.h b/src/wifi/model/rate-control/minstrel-ht-wifi-manager.h index f6bdac9b5..fd9951e95 100644 --- a/src/wifi/model/rate-control/minstrel-ht-wifi-manager.h +++ b/src/wifi/model/rate-control/minstrel-ht-wifi-manager.h @@ -37,6 +37,7 @@ enum McsGroupType WIFI_MINSTREL_GROUP_HT, WIFI_MINSTREL_GROUP_VHT, WIFI_MINSTREL_GROUP_HE, + WIFI_MINSTREL_GROUP_EHT, WIFI_MINSTREL_GROUP_COUNT }; @@ -58,6 +59,8 @@ operator<<(std::ostream& os, McsGroupType type) return (os << "VHT"); case WIFI_MINSTREL_GROUP_HE: return (os << "HE"); + case WIFI_MINSTREL_GROUP_EHT: + return (os << "EHT"); default: case WIFI_MINSTREL_GROUP_INVALID: return (os << "INVALID"); @@ -629,6 +632,17 @@ class MinstrelHtWifiManager : public WifiRemoteStationManager */ std::size_t GetHeGroupId(uint8_t streams, Time guardInterval, MHz_u chWidth); + /** + * Returns the groupId of an EHT MCS with the given number of streams, GI and channel width + * used. + * + * @param streams the number of streams + * @param guardInterval guard interval duration + * @param chWidth the channel width + * @returns the EHT group ID + */ + std::size_t GetEhtGroupId(uint8_t streams, Time guardInterval, MHz_u chWidth); + /** * Returns the group ID of an MCS of a given group type with the given number of streams, GI and * channel width used.