From bef9d874311cacfd5ecec44330ef488762cb6fed Mon Sep 17 00:00:00 2001 From: Stefano Avallone Date: Sun, 19 May 2024 10:58:08 +0200 Subject: [PATCH] wifi: Minstrel HT manager skips HT rates if HT is not supported This is the case when operating in 6 GHz links --- .../rate-control/minstrel-ht-wifi-manager.cc | 350 +++++++++--------- 1 file changed, 175 insertions(+), 175 deletions(-) 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 883b6d414..5b62df720 100644 --- a/src/wifi/model/rate-control/minstrel-ht-wifi-manager.cc +++ b/src/wifi/model/rate-control/minstrel-ht-wifi-manager.cc @@ -194,36 +194,39 @@ MinstrelHtWifiManager::DoInitialize() * station. */ - if (GetPhy()->GetDevice()->GetHtConfiguration()) + if (GetHtSupported()) { m_numGroups = MAX_HT_SUPPORTED_STREAMS * MAX_HT_STREAM_GROUPS; m_numRates = MAX_HT_GROUP_RATES; - if (GetVhtSupported()) - { - m_numGroups += MAX_VHT_SUPPORTED_STREAMS * MAX_VHT_STREAM_GROUPS; - m_numRates = MAX_VHT_GROUP_RATES; - } - if (GetHeSupported()) - { - m_numGroups += MAX_HE_SUPPORTED_STREAMS * MAX_HE_STREAM_GROUPS; - m_numRates = MAX_HE_GROUP_RATES; - } + } + if (GetVhtSupported()) + { + m_numGroups += MAX_VHT_SUPPORTED_STREAMS * MAX_VHT_STREAM_GROUPS; + m_numRates = MAX_VHT_GROUP_RATES; + } + if (GetHeSupported()) + { + m_numGroups += MAX_HE_SUPPORTED_STREAMS * MAX_HE_STREAM_GROUPS; + m_numRates = MAX_HE_GROUP_RATES; + } - /** - * Initialize the groups array. - * The HT groups come first, then the VHT ones, and finally the HE ones. - * Minstrel maintains different types of indexes: - * - A global continuous index, which identifies all rates within all groups, in [0, - * m_numGroups * m_numRates] - * - A groupId, which indexes a group in the array, in [0, m_numGroups] - * - A rateId, which identifies a rate within a group, in [0, m_numRates] - * - A deviceIndex, which indexes a MCS in the PHY MCS array. - * - A mcsIndex, which indexes a MCS in the wifi-remote-station-manager supported MCSs - * array. - */ - NS_LOG_DEBUG("Initialize MCS Groups:"); - m_minstrelGroups = MinstrelMcsGroups(m_numGroups); + /** + * Initialize the groups array. + * The HT groups come first, then the VHT ones, and finally the HE ones. + * Minstrel maintains different types of indexes: + * - A global continuous index, which identifies all rates within all groups, in [0, + * m_numGroups * m_numRates] + * - A groupId, which indexes a group in the array, in [0, m_numGroups] + * - A rateId, which identifies a rate within a group, in [0, m_numRates] + * - A deviceIndex, which indexes a MCS in the PHY MCS array. + * - A mcsIndex, which indexes a MCS in the wifi-remote-station-manager supported MCSs + * array. + */ + NS_LOG_DEBUG("Initialize MCS Groups:"); + m_minstrelGroups = MinstrelMcsGroups(m_numGroups); + if (GetHtSupported()) + { // Initialize all HT groups for (uint16_t chWidth = 20; chWidth <= MAX_HT_WIDTH; chWidth *= 2) { @@ -279,133 +282,129 @@ MinstrelHtWifiManager::DoInitialize() gi /= 2; } } + } - if (GetVhtSupported()) + if (GetVhtSupported()) + { + // Initialize all VHT groups + for (uint16_t chWidth = 20; chWidth <= MAX_VHT_WIDTH; chWidth *= 2) { - // Initialize all VHT groups - for (uint16_t chWidth = 20; chWidth <= MAX_VHT_WIDTH; chWidth *= 2) + for (int gi = 800; gi >= 400;) { - for (int gi = 800; gi >= 400;) + for (uint8_t streams = 1; streams <= MAX_VHT_SUPPORTED_STREAMS; streams++) { - for (uint8_t streams = 1; streams <= MAX_VHT_SUPPORTED_STREAMS; streams++) + uint8_t groupId = GetVhtGroupId(streams, gi, chWidth); + + m_minstrelGroups[groupId].streams = streams; + m_minstrelGroups[groupId].gi = gi; + m_minstrelGroups[groupId].chWidth = chWidth; + m_minstrelGroups[groupId].type = WIFI_MINSTREL_GROUP_VHT; + m_minstrelGroups[groupId].isSupported = false; + + // Check capabilities of the device + if (!(!GetShortGuardIntervalSupported() && + (gi == 400)) /// Is SGI supported by the transmitter? + && (GetPhy()->GetChannelWidth() >= + chWidth) /// Is channel width supported by the transmitter? + && (GetPhy()->GetMaxSupportedTxSpatialStreams() >= + streams)) /// Are streams supported by the transmitter? { - uint8_t groupId = GetVhtGroupId(streams, gi, chWidth); + m_minstrelGroups[groupId].isSupported = true; - m_minstrelGroups[groupId].streams = streams; - m_minstrelGroups[groupId].gi = gi; - m_minstrelGroups[groupId].chWidth = chWidth; - m_minstrelGroups[groupId].type = WIFI_MINSTREL_GROUP_VHT; - m_minstrelGroups[groupId].isSupported = false; - - // Check capabilities of the device - if (!(!GetShortGuardIntervalSupported() && - (gi == 400)) /// Is SGI supported by the transmitter? - && (GetPhy()->GetChannelWidth() >= - chWidth) /// Is channel width supported by the transmitter? - && (GetPhy()->GetMaxSupportedTxSpatialStreams() >= - streams)) /// Are streams supported by the transmitter? + // Calculate TX time for all rates of the group + WifiModeList vhtMcsList = GetVhtDeviceMcsList(); + for (uint8_t i = 0; i < MAX_VHT_GROUP_RATES; i++) { - m_minstrelGroups[groupId].isSupported = true; - - // Calculate TX time for all rates of the group - WifiModeList vhtMcsList = GetVhtDeviceMcsList(); - for (uint8_t i = 0; i < MAX_VHT_GROUP_RATES; i++) + WifiMode mode = vhtMcsList[i]; + // Check for invalid VHT MCSs and do not add time to array. + if (IsValidMcs(GetPhy(), streams, chWidth, mode)) { - WifiMode mode = vhtMcsList[i]; - // Check for invalid VHT MCSs and do not add time to array. - if (IsValidMcs(GetPhy(), streams, chWidth, mode)) - { - AddFirstMpduTxTime( - groupId, - mode, - CalculateMpduTxDuration(GetPhy(), - streams, - gi, - chWidth, - mode, - FIRST_MPDU_IN_AGGREGATE)); - AddMpduTxTime( - groupId, - mode, - CalculateMpduTxDuration(GetPhy(), - streams, - gi, - chWidth, - mode, - MIDDLE_MPDU_IN_AGGREGATE)); - } + AddFirstMpduTxTime( + groupId, + mode, + CalculateMpduTxDuration(GetPhy(), + streams, + gi, + chWidth, + mode, + FIRST_MPDU_IN_AGGREGATE)); + AddMpduTxTime(groupId, + mode, + CalculateMpduTxDuration(GetPhy(), + streams, + gi, + chWidth, + mode, + MIDDLE_MPDU_IN_AGGREGATE)); } - NS_LOG_DEBUG("Initialized group " << +groupId << ": (" << +streams - << "," << gi << "," << chWidth - << ")"); } + NS_LOG_DEBUG("Initialized group " << +groupId << ": (" << +streams << "," + << gi << "," << chWidth << ")"); } - gi /= 2; } + gi /= 2; } } + } - if (GetHeSupported()) + if (GetHeSupported()) + { + // Initialize all HE groups + for (uint16_t chWidth = 20; chWidth <= MAX_HE_WIDTH; chWidth *= 2) { - // Initialize all HE groups - for (uint16_t chWidth = 20; chWidth <= MAX_HE_WIDTH; chWidth *= 2) + for (int gi = 3200; gi >= 800;) { - for (int gi = 3200; gi >= 800;) + for (uint8_t streams = 1; streams <= MAX_HE_SUPPORTED_STREAMS; streams++) { - for (uint8_t streams = 1; streams <= MAX_HE_SUPPORTED_STREAMS; streams++) + uint8_t groupId = GetHeGroupId(streams, gi, chWidth); + + m_minstrelGroups[groupId].streams = streams; + m_minstrelGroups[groupId].gi = gi; + m_minstrelGroups[groupId].chWidth = chWidth; + m_minstrelGroups[groupId].type = WIFI_MINSTREL_GROUP_HE; + m_minstrelGroups[groupId].isSupported = false; + + // Check capabilities of the device + if ((GetGuardInterval() <= gi) /// Is GI supported by the transmitter? + && (GetPhy()->GetChannelWidth() >= + chWidth) /// Is channel width supported by the transmitter? + && (GetPhy()->GetMaxSupportedTxSpatialStreams() >= + streams)) /// Are streams supported by the transmitter? { - uint8_t groupId = GetHeGroupId(streams, gi, chWidth); + m_minstrelGroups[groupId].isSupported = true; - m_minstrelGroups[groupId].streams = streams; - m_minstrelGroups[groupId].gi = gi; - m_minstrelGroups[groupId].chWidth = chWidth; - m_minstrelGroups[groupId].type = WIFI_MINSTREL_GROUP_HE; - m_minstrelGroups[groupId].isSupported = false; - - // Check capabilities of the device - if ((GetGuardInterval() <= gi) /// Is GI supported by the transmitter? - && (GetPhy()->GetChannelWidth() >= - chWidth) /// Is channel width supported by the transmitter? - && (GetPhy()->GetMaxSupportedTxSpatialStreams() >= - streams)) /// Are streams supported by the transmitter? + // Calculate tx time for all rates of the group + WifiModeList heMcsList = GetHeDeviceMcsList(); + for (uint8_t i = 0; i < MAX_HE_GROUP_RATES; i++) { - m_minstrelGroups[groupId].isSupported = true; - - // Calculate tx time for all rates of the group - WifiModeList heMcsList = GetHeDeviceMcsList(); - for (uint8_t i = 0; i < MAX_HE_GROUP_RATES; i++) + WifiMode mode = heMcsList.at(i); + // Check for invalid HE MCSs and do not add time to array. + if (IsValidMcs(GetPhy(), streams, chWidth, mode)) { - WifiMode mode = heMcsList.at(i); - // Check for invalid HE MCSs and do not add time to array. - if (IsValidMcs(GetPhy(), streams, chWidth, mode)) - { - AddFirstMpduTxTime( - groupId, - mode, - CalculateMpduTxDuration(GetPhy(), - streams, - gi, - chWidth, - mode, - FIRST_MPDU_IN_AGGREGATE)); - AddMpduTxTime( - groupId, - mode, - CalculateMpduTxDuration(GetPhy(), - streams, - gi, - chWidth, - mode, - MIDDLE_MPDU_IN_AGGREGATE)); - } + AddFirstMpduTxTime( + groupId, + mode, + CalculateMpduTxDuration(GetPhy(), + streams, + gi, + chWidth, + mode, + FIRST_MPDU_IN_AGGREGATE)); + AddMpduTxTime(groupId, + mode, + CalculateMpduTxDuration(GetPhy(), + streams, + gi, + chWidth, + mode, + MIDDLE_MPDU_IN_AGGREGATE)); } - NS_LOG_DEBUG("Initialized group " << +groupId << ": (" << +streams - << "," << gi << "," << chWidth - << ")"); } + NS_LOG_DEBUG("Initialized group " << +groupId << ": (" << +streams << "," + << gi << "," << chWidth << ")"); } - gi /= 2; } + gi /= 2; } } } @@ -1043,55 +1042,52 @@ MinstrelHtWifiManager::DoGetDataTxVector(WifiRemoteStation* st, uint16_t allowed } return vector; } - else + + station->m_txrate = UpdateRateAfterAllowedWidth(station->m_txrate, allowedWidth); + NS_LOG_DEBUG("DoGetDataMode m_txrate= " << station->m_txrate); + + uint8_t rateId = GetRateId(station->m_txrate); + uint8_t groupId = GetGroupId(station->m_txrate); + uint8_t mcsIndex = station->m_groupsTable[groupId].m_ratesTable[rateId].mcsIndex; + + NS_LOG_DEBUG("DoGetDataMode rateId= " << +rateId << " groupId= " << +groupId + << " mode= " << GetMcsSupported(station, mcsIndex)); + + McsGroup group = m_minstrelGroups[groupId]; + + // Check consistency of rate selected. + if (((group.type == WIFI_MINSTREL_GROUP_HE) && (group.gi < GetGuardInterval(station))) || + (((group.type == WIFI_MINSTREL_GROUP_HT) || (group.type == WIFI_MINSTREL_GROUP_VHT)) && + (group.gi == 400) && !GetShortGuardIntervalSupported(station)) || + (group.chWidth > GetChannelWidth(station)) || + (group.streams > GetNumberOfSupportedStreams(station))) { - station->m_txrate = UpdateRateAfterAllowedWidth(station->m_txrate, allowedWidth); - NS_LOG_DEBUG("DoGetDataMode m_txrate= " << station->m_txrate); - - uint8_t rateId = GetRateId(station->m_txrate); - uint8_t groupId = GetGroupId(station->m_txrate); - uint8_t mcsIndex = station->m_groupsTable[groupId].m_ratesTable[rateId].mcsIndex; - - NS_LOG_DEBUG("DoGetDataMode rateId= " << +rateId << " groupId= " << +groupId - << " mode= " << GetMcsSupported(station, mcsIndex)); - - McsGroup group = m_minstrelGroups[groupId]; - - // Check consistency of rate selected. - if (((group.type == WIFI_MINSTREL_GROUP_HE) && (group.gi < GetGuardInterval(station))) || - (((group.type == WIFI_MINSTREL_GROUP_HT) || (group.type == WIFI_MINSTREL_GROUP_VHT)) && - (group.gi == 400) && !GetShortGuardIntervalSupported(station)) || - (group.chWidth > GetChannelWidth(station)) || - (group.streams > GetNumberOfSupportedStreams(station))) - { - NS_FATAL_ERROR("Inconsistent group selected. Group: (" - << +group.streams << "," << group.gi << "," << group.chWidth << ")" - << " Station capabilities: (" << GetNumberOfSupportedStreams(station) - << "," - << ((group.type == WIFI_MINSTREL_GROUP_HE) - ? GetGuardInterval(station) - : (GetShortGuardIntervalSupported(station) ? 400 : 800)) - << "," << GetChannelWidth(station) << ")"); - } - WifiMode mode = GetMcsSupported(station, mcsIndex); - WifiTxVector txVector{ - mode, - GetDefaultTxPowerLevel(), - GetPreambleForTransmission(mode.GetModulationClass(), GetShortPreambleEnabled()), - group.gi, - GetNumberOfAntennas(), - group.streams, - GetNess(station), - GetPhy()->GetTxBandwidth(mode, group.chWidth), - GetAggregation(station) && !station->m_isSampling}; - uint64_t dataRate = mode.GetDataRate(txVector); - if (m_currentRate != dataRate && !station->m_isSampling) - { - NS_LOG_DEBUG("New datarate: " << dataRate); - m_currentRate = dataRate; - } - return txVector; + NS_FATAL_ERROR("Inconsistent group selected. Group: (" + << +group.streams << "," << group.gi << "," << group.chWidth << ")" + << " Station capabilities: (" << GetNumberOfSupportedStreams(station) << "," + << ((group.type == WIFI_MINSTREL_GROUP_HE) + ? GetGuardInterval(station) + : (GetShortGuardIntervalSupported(station) ? 400 : 800)) + << "," << GetChannelWidth(station) << ")"); } + WifiMode mode = GetMcsSupported(station, mcsIndex); + WifiTxVector txVector{ + mode, + GetDefaultTxPowerLevel(), + GetPreambleForTransmission(mode.GetModulationClass(), GetShortPreambleEnabled()), + group.gi, + GetNumberOfAntennas(), + group.streams, + GetNess(station), + GetPhy()->GetTxBandwidth(mode, group.chWidth), + GetAggregation(station) && !station->m_isSampling}; + uint64_t dataRate = mode.GetDataRate(txVector); + if (m_currentRate != dataRate && !station->m_isSampling) + { + NS_LOG_DEBUG("New datarate: " << dataRate); + m_currentRate = dataRate; + } + return txVector; } WifiTxVector @@ -2183,8 +2179,12 @@ MinstrelHtWifiManager::GetHeGroupId(uint8_t txstreams, uint16_t gi, uint16_t chW { widthIndex = 0; } - uint8_t groupId = (MAX_HT_STREAM_GROUPS * MAX_HT_SUPPORTED_STREAMS); /// add all HT groups - if (GetVhtSupported()) /// This check is needed since we do not support VHT in 2.4 GHz band + uint8_t groupId = 0; + if (GetHtSupported()) // This check is needed since HT is not supported in 6 GHz band + { + groupId = MAX_HT_STREAM_GROUPS * MAX_HT_SUPPORTED_STREAMS; + } + if (GetVhtSupported()) // This check is needed since VHT is not supported in 2.4 and 6 GHz bands { groupId += MAX_VHT_STREAM_GROUPS * MAX_VHT_SUPPORTED_STREAMS; /// add all VHT groups }