wifi: Fill EHT-MCS And NSS Set field in EHT capabilities
This commit is contained in:
committed by
Sebastien Deronne
parent
4a05823c5c
commit
413b9b64a3
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user