wifi: Improve logic for switching main PHY when aux PHY that is not TX capable gains a TXOP
This commit is contained in:
@@ -229,9 +229,9 @@ DefaultEmlsrManager::DoNotifyTxopEnd(uint8_t linkId)
|
||||
}
|
||||
|
||||
void
|
||||
DefaultEmlsrManager::SwitchMainPhyIfTxopGainedByAuxPhy(uint8_t linkId)
|
||||
DefaultEmlsrManager::SwitchMainPhyIfTxopGainedByAuxPhy(uint8_t linkId, AcIndex aci)
|
||||
{
|
||||
NS_LOG_FUNCTION(this << linkId);
|
||||
NS_LOG_FUNCTION(this << linkId << aci);
|
||||
|
||||
NS_ASSERT_MSG(!m_auxPhyTxCapable,
|
||||
"This function should only be called if aux PHY is not TX capable");
|
||||
@@ -239,9 +239,12 @@ DefaultEmlsrManager::SwitchMainPhyIfTxopGainedByAuxPhy(uint8_t linkId)
|
||||
// the aux PHY is not TX capable; check if main PHY has to switch to the aux PHY's link
|
||||
auto mainPhy = GetStaMac()->GetDevice()->GetPhy(m_mainPhyId);
|
||||
|
||||
// if the main PHY is idle, check whether the remaining backoff counter on at least an AC with
|
||||
// queued packets is greater than the main PHY channel switch delay
|
||||
auto backoffGreaterThanSwitchDelay = false;
|
||||
// if the main PHY is idle, switch main PHY if we expect the main PHY to get channel access on
|
||||
// this link more quicky, i.e., if ALL the ACs with queued frames and with priority higher than
|
||||
// or equal to that of the AC for which Aux PHY gained TXOP have their backoff counter greater
|
||||
// than the channel switch delay plus PIFS
|
||||
|
||||
auto requestSwitch = false;
|
||||
|
||||
if (mainPhy->IsStateIdle())
|
||||
{
|
||||
@@ -255,19 +258,23 @@ DefaultEmlsrManager::SwitchMainPhyIfTxopGainedByAuxPhy(uint8_t linkId)
|
||||
Txop::HAD_FRAMES_TO_TRANSMIT,
|
||||
Txop::CHECK_MEDIUM_BUSY);
|
||||
|
||||
for (const auto& [aci, ac] : wifiAcList)
|
||||
for (const auto& [acIndex, ac] : wifiAcList)
|
||||
{
|
||||
if (auto edca = GetStaMac()->GetQosTxop(aci); edca->HasFramesToTransmit(linkId))
|
||||
if (auto edca = GetStaMac()->GetQosTxop(acIndex);
|
||||
acIndex >= aci && edca->HasFramesToTransmit(linkId))
|
||||
{
|
||||
requestSwitch = true;
|
||||
|
||||
auto backoffEnd =
|
||||
GetStaMac()->GetChannelAccessManager(*mainPhyLinkId)->GetBackoffEndFor(edca);
|
||||
NS_LOG_DEBUG("Backoff end for " << aci
|
||||
NS_LOG_DEBUG("Backoff end for " << acIndex
|
||||
<< " on primary link: " << backoffEnd.As(Time::US));
|
||||
|
||||
if (backoffEnd > Simulator::Now() + mainPhy->GetChannelSwitchDelay() +
|
||||
GetStaMac()->GetWifiPhy(linkId)->GetPifs())
|
||||
if (backoffEnd <= Simulator::Now() + mainPhy->GetChannelSwitchDelay() +
|
||||
GetStaMac()->GetWifiPhy(linkId)->GetPifs() &&
|
||||
edca->HasFramesToTransmit(*mainPhyLinkId))
|
||||
{
|
||||
backoffGreaterThanSwitchDelay = true;
|
||||
requestSwitch = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -275,7 +282,7 @@ DefaultEmlsrManager::SwitchMainPhyIfTxopGainedByAuxPhy(uint8_t linkId)
|
||||
}
|
||||
|
||||
if ((mainPhy->IsStateCcaBusy() && !mainPhy->IsReceivingPhyHeader()) ||
|
||||
(mainPhy->IsStateIdle() && backoffGreaterThanSwitchDelay))
|
||||
(mainPhy->IsStateIdle() && requestSwitch))
|
||||
{
|
||||
// switch main PHY
|
||||
SwitchMainPhy(linkId, false, RESET_BACKOFF, REQUEST_ACCESS);
|
||||
|
||||
@@ -37,7 +37,7 @@ class DefaultEmlsrManager : public EmlsrManager
|
||||
uint8_t GetLinkToSendEmlOmn() override;
|
||||
std::optional<uint8_t> ResendNotification(Ptr<const WifiMpdu> mpdu) override;
|
||||
Time DoGetDelayUntilAccessRequest(uint8_t linkId) override;
|
||||
void SwitchMainPhyIfTxopGainedByAuxPhy(uint8_t linkId) override;
|
||||
void SwitchMainPhyIfTxopGainedByAuxPhy(uint8_t linkId, AcIndex aci) override;
|
||||
Time GetDelayUnlessMainPhyTakesOverUlTxop(uint8_t linkId) override;
|
||||
|
||||
/**
|
||||
|
||||
@@ -279,7 +279,9 @@ EhtFrameExchangeManager::StartTransmission(Ptr<Txop> edca, MHz_u allowedWidth)
|
||||
const auto mainPhySwitching = mainPhy->IsStateSwitching();
|
||||
|
||||
// let EMLSR manager decide whether to prevent or allow this UL TXOP
|
||||
if (auto delay = emlsrManager->GetDelayUntilAccessRequest(m_linkId);
|
||||
if (auto delay = emlsrManager->GetDelayUntilAccessRequest(
|
||||
m_linkId,
|
||||
DynamicCast<QosTxop>(edca)->GetAccessCategory());
|
||||
delay.IsStrictlyPositive())
|
||||
{
|
||||
NotifyChannelReleased(edca);
|
||||
|
||||
@@ -409,7 +409,7 @@ EmlsrManager::NotifyIcfReceived(uint8_t linkId)
|
||||
}
|
||||
|
||||
Time
|
||||
EmlsrManager::GetDelayUntilAccessRequest(uint8_t linkId)
|
||||
EmlsrManager::GetDelayUntilAccessRequest(uint8_t linkId, AcIndex aci)
|
||||
{
|
||||
auto phy = m_staMac->GetWifiPhy(linkId);
|
||||
NS_ASSERT_MSG(phy, "No PHY operating on link " << +linkId);
|
||||
@@ -432,7 +432,7 @@ EmlsrManager::GetDelayUntilAccessRequest(uint8_t linkId)
|
||||
// whether the aux PHY is TX capable or not
|
||||
if (!m_auxPhyTxCapable)
|
||||
{
|
||||
SwitchMainPhyIfTxopGainedByAuxPhy(linkId);
|
||||
SwitchMainPhyIfTxopGainedByAuxPhy(linkId, aci);
|
||||
// if the aux PHY is not TX capable, we don't have to request channel access: if the main
|
||||
// PHY switches link, the UL TXOP will be started; if the main PHY does not switch, it is
|
||||
// because it is going to start an UL TXOP on another link and this link will be restarted
|
||||
|
||||
@@ -142,14 +142,15 @@ class EmlsrManager : public Object
|
||||
bool GetCamStateReset() const;
|
||||
|
||||
/**
|
||||
* Notify that an UL TXOP is gained on the given link. This method has to determine whether to
|
||||
* start the UL TXOP or release the channel.
|
||||
* Notify that an UL TXOP is gained on the given link by the given AC. This method has to
|
||||
* determine whether to start the UL TXOP or release the channel.
|
||||
*
|
||||
* \param linkId the ID of the given link
|
||||
* \param aci the index of the given AC
|
||||
* \return zero, if the UL TXOP can be started, or the delay after which the EMLSR client
|
||||
* restarts channel access, otherwise
|
||||
*/
|
||||
Time GetDelayUntilAccessRequest(uint8_t linkId);
|
||||
Time GetDelayUntilAccessRequest(uint8_t linkId, AcIndex aci);
|
||||
|
||||
/**
|
||||
* Set the member variable indicating whether Aux PHYs are capable of transmitting PPDUs.
|
||||
@@ -363,13 +364,14 @@ class EmlsrManager : public Object
|
||||
|
||||
/**
|
||||
* Subclasses have to provide an implementation for this method, that is called by the base
|
||||
* class when the EMLSR client gets channel access on the given link, on which an aux PHY that
|
||||
* is not TX capable is operating. This method has to request the main PHY to switch to the
|
||||
* given link to take over the TXOP, unless it is decided to give up the TXOP.
|
||||
* class when the given AC of the EMLSR client gets channel access on the given link, on which
|
||||
* an aux PHY that is not TX capable is operating. This method has to request the main PHY to
|
||||
* switch to the given link to take over the TXOP, unless it is decided to give up the TXOP.
|
||||
*
|
||||
* \param linkId the ID of the given link
|
||||
* \param aci the index of the given AC
|
||||
*/
|
||||
virtual void SwitchMainPhyIfTxopGainedByAuxPhy(uint8_t linkId) = 0;
|
||||
virtual void SwitchMainPhyIfTxopGainedByAuxPhy(uint8_t linkId, AcIndex aci) = 0;
|
||||
|
||||
/**
|
||||
* Subclasses have to provide an implementation for this method, that is called by the base
|
||||
|
||||
Reference in New Issue
Block a user