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:
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user