wifi: Minstrel HT manager skips HT rates if HT is not supported

This is the case when operating in 6 GHz links
This commit is contained in:
Stefano Avallone
2024-05-19 10:58:08 +02:00
parent ee09494ddf
commit bef9d87431

View File

@@ -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
}