wifi: Fill EHT-MCS And NSS Set field in EHT capabilities

This commit is contained in:
Sébastien Deronne
2022-08-07 15:02:34 +02:00
committed by Sebastien Deronne
parent 4a05823c5c
commit 413b9b64a3
3 changed files with 178 additions and 0 deletions

View File

@@ -363,6 +363,111 @@ EhtCapabilities::GetMaxAmpduLength() const
15523200);
}
void
EhtCapabilities::SetSupportedRxEhtMcsAndNss(EhtMcsAndNssSet::EhtMcsMapType mapType,
uint8_t upperMcs,
uint8_t maxNss)
{
NS_ASSERT_MSG(maxNss <= 8, "Invalid maximum NSS " << maxNss);
std::size_t index = 0;
switch (upperMcs)
{
case 7:
NS_ASSERT(mapType == EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_20_MHZ_ONLY);
index = 0;
break;
case 9:
index = (mapType == EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_20_MHZ_ONLY) ? 1 : 0;
break;
case 11:
index = (mapType == EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_20_MHZ_ONLY) ? 2 : 1;
break;
case 13:
index = (mapType == EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_20_MHZ_ONLY) ? 3 : 2;
break;
default:
NS_ASSERT_MSG(false, "Invalid upper MCS " << +upperMcs);
}
uint8_t nBytes = 0;
switch (mapType)
{
case EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_20_MHZ_ONLY:
nBytes = 4;
break;
case EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_NOT_LARGER_THAN_80_MHZ:
case EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_160_MHZ:
case EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_320_MHZ:
nBytes = 3;
break;
default:
NS_ASSERT_MSG(false, "Invalid map type " << mapType);
}
auto it = m_supportedEhtMcsAndNssSet.supportedEhtMcsAndNssSet.find(mapType);
if (it == m_supportedEhtMcsAndNssSet.supportedEhtMcsAndNssSet.end())
{
m_supportedEhtMcsAndNssSet.supportedEhtMcsAndNssSet[mapType].resize(nBytes);
m_supportedEhtMcsAndNssSet.supportedEhtMcsAndNssSet[mapType][index] = (maxNss & 0x0f);
}
else
{
NS_ASSERT(it->second.size() == nBytes);
it->second[index] |= (maxNss & 0x0f);
}
}
void
EhtCapabilities::SetSupportedTxEhtMcsAndNss(EhtMcsAndNssSet::EhtMcsMapType mapType,
uint8_t upperMcs,
uint8_t maxNss)
{
NS_ASSERT_MSG(maxNss <= 8, "Invalid maximum NSS " << maxNss);
std::size_t index = 0;
switch (upperMcs)
{
case 7:
NS_ASSERT(mapType == EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_20_MHZ_ONLY);
index = 0;
break;
case 9:
index = (mapType == EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_20_MHZ_ONLY) ? 1 : 0;
break;
case 11:
index = (mapType == EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_20_MHZ_ONLY) ? 2 : 1;
break;
case 13:
index = (mapType == EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_20_MHZ_ONLY) ? 3 : 2;
break;
default:
NS_ASSERT_MSG(false, "Invalid upper MCS " << upperMcs);
}
uint8_t nBytes = 0;
switch (mapType)
{
case EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_20_MHZ_ONLY:
nBytes = 4;
break;
case EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_NOT_LARGER_THAN_80_MHZ:
case EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_160_MHZ:
case EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_320_MHZ:
nBytes = 3;
break;
default:
NS_ASSERT_MSG(false, "Invalid map type " << mapType);
}
auto it = m_supportedEhtMcsAndNssSet.supportedEhtMcsAndNssSet.find(mapType);
if (it == m_supportedEhtMcsAndNssSet.supportedEhtMcsAndNssSet.end())
{
m_supportedEhtMcsAndNssSet.supportedEhtMcsAndNssSet[mapType].resize(nBytes);
m_supportedEhtMcsAndNssSet.supportedEhtMcsAndNssSet[mapType][index] =
((maxNss & 0x0f) << 4);
}
else
{
NS_ASSERT(it->second.size() == nBytes);
it->second[index] |= ((maxNss & 0x0f) << 4);
}
}
void
EhtCapabilities::SerializeInformationField(Buffer::Iterator start) const
{

View File

@@ -249,6 +249,27 @@ class EhtCapabilities : public WifiInformationElement
*/
uint16_t GetMaxMpduLength() const;
/**
* Set a subfield of the Supported EHT-MCS And NSS Set.
*
* \param mapType the type of the subfield
* \param upperMcs the upper MCS of the range
* \param maxNss the maximum NSS supported for transmission in the MCS range
*/
void SetSupportedTxEhtMcsAndNss(EhtMcsAndNssSet::EhtMcsMapType mapType,
uint8_t upperMcs,
uint8_t maxNss);
/**
* Set a subfield of the Supported EHT-MCS And NSS Set.
*
* \param mapType the type of the subfield
* \param upperMcs the upper MCS of the range
* \param maxNss the maximum NSS supported for reception in the MCS range
*/
void SetSupportedRxEhtMcsAndNss(EhtMcsAndNssSet::EhtMcsMapType mapType,
uint8_t upperMcs,
uint8_t maxNss);
EhtMacCapabilities m_macCapabilities; //!< EHT MAC Capabilities Info subfield
EhtPhyCapabilities m_phyCapabilities; //!< EHT PHY Capabilities Info subfield
EhtMcsAndNssSet m_supportedEhtMcsAndNssSet; //!< Supported EHT-MCS And NSS Set subfield

View File

@@ -1616,6 +1616,58 @@ WifiMac::GetEhtCapabilities(uint8_t linkId) const
capabilities.m_phyCapabilities.supportRx1024And4096QamForRuSmallerThan242Tones =
support4096Qam ? 1 : 0;
const uint8_t maxTxNss = phy->GetMaxSupportedTxSpatialStreams();
const uint8_t maxRxNss = phy->GetMaxSupportedRxSpatialStreams();
if (phy->GetChannelWidth() == 20)
{
for (auto maxMcs : {7, 9, 11, 13})
{
capabilities.SetSupportedRxEhtMcsAndNss(
EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_20_MHZ_ONLY,
maxMcs,
phy->IsMcsSupported(WIFI_MOD_CLASS_EHT, maxMcs) ? maxRxNss : 0);
capabilities.SetSupportedTxEhtMcsAndNss(
EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_20_MHZ_ONLY,
maxMcs,
phy->IsMcsSupported(WIFI_MOD_CLASS_EHT, maxMcs) ? maxTxNss : 0);
}
}
else
{
if (phy->GetPhyBand() != WIFI_PHY_BAND_2_4GHZ)
{
NS_ABORT_MSG_IF(phy->GetChannelWidth() == 40,
"A 802.11be STA cannot support 40 MHz without supporting 80 MHz except "
"in 2.4 GHz band");
}
for (auto maxMcs : {9, 11, 13})
{
capabilities.SetSupportedRxEhtMcsAndNss(
EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_NOT_LARGER_THAN_80_MHZ,
maxMcs,
phy->IsMcsSupported(WIFI_MOD_CLASS_EHT, maxMcs) ? maxRxNss : 0);
capabilities.SetSupportedTxEhtMcsAndNss(
EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_NOT_LARGER_THAN_80_MHZ,
maxMcs,
phy->IsMcsSupported(WIFI_MOD_CLASS_EHT, maxMcs) ? maxTxNss : 0);
}
}
if (phy->GetChannelWidth() >= 160)
{
for (auto maxMcs : {9, 11, 13})
{
capabilities.SetSupportedRxEhtMcsAndNss(
EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_160_MHZ,
maxMcs,
phy->IsMcsSupported(WIFI_MOD_CLASS_EHT, maxMcs) ? maxRxNss : 0);
capabilities.SetSupportedTxEhtMcsAndNss(
EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_160_MHZ,
maxMcs,
phy->IsMcsSupported(WIFI_MOD_CLASS_EHT, maxMcs) ? maxTxNss : 0);
}
}
// 320 MHz not supported yet
return capabilities;
}