wifi: Enable interrupting main PHY switch if channel access is (to be) gained on aux PHY link

This commit is contained in:
Stefano Avallone
2025-03-19 11:45:11 +01:00
parent 5094865d26
commit 8fb0b402fc
4 changed files with 29 additions and 7 deletions

View File

@@ -1368,7 +1368,8 @@ auxiliary link. The following conditions must all hold in order to request the m
to the auxiliary link:
* the main PHY is not in TX state
* the main PHY is not switching nor is it trying to get channel access on another auxiliary link
* the main PHY is not switching (unless switching can be interrupted, see below) nor is it trying
to get channel access on another auxiliary link
* no MediumSyncDelay timer is running on the auxiliary link or the maximum number of TXOP attempts
has not yet been reached
* the main PHY is expected to get channel access on the auxiliary link more quickly. More precisely,
@@ -1485,6 +1486,10 @@ and the new channel switch starts. This opportunity is exploited in some situati
* If the main PHY is switching while an aux PHY is receiving an ICF, the switch can be interrupted
so that the main PHY can start switching to the aux PHY link and be ready to operate on that link
upon reception of the ICF.
* If channel access is gained, or is about to be gained, on a link on which a non-TX capable aux PHY
is operating and the main PHY is switching, the main PHY switch can be interrupted and the main
PHY can start switching to the aux PHY link, provided that the main PHY was not switching to start
a (DL or UL) TXOP and the other conditions to request the main PHY to switch are satisfied.
AP EMLSR Manager
----------------

View File

@@ -746,12 +746,14 @@ AdvancedEmlsrManager::RequestMainPhyToSwitch(uint8_t linkId, AcIndex aci, const
// 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);
const auto mainPhyLinkId = GetStaMac()->GetLinkForPhy(mainPhy);
// if main PHY is not operating on a link, it is switching, hence do not request another switch
if (!mainPhyLinkId.has_value())
// if main PHY is not operating on a link and is trying to start a (DL or UL) TXOP, then do
// not request another switch
if (m_mainPhySwitchInfo.disconnected &&
(!m_interruptSwitching || m_mainPhySwitchInfo.reason == "DlTxopIcfReceivedByAuxPhy" ||
m_mainPhySwitchInfo.reason == "UlTxopAuxPhyNotTxCapable"))
{
NS_LOG_DEBUG("Main PHY is not operating on any link");
NS_LOG_DEBUG("Main PHY is not operating on any link and cannot switch to another link");
return false;
}
@@ -787,9 +789,11 @@ AdvancedEmlsrManager::RequestMainPhyToSwitch(uint8_t linkId, AcIndex aci, const
return false;
}
// DoGetDelayUntilAccessRequest has already checked if the main PHY is receiving an ICF
// DoGetDelayUntilAccessRequest has already checked if the main PHY is receiving an ICF and
// above it is checked whether we can request another switch while already switching
if (const auto state = mainPhy->GetState()->GetState();
state != WifiPhyState::IDLE && state != WifiPhyState::CCA_BUSY && state != WifiPhyState::RX)
state != WifiPhyState::IDLE && state != WifiPhyState::CCA_BUSY &&
state != WifiPhyState::RX && state != WifiPhyState::SWITCHING)
{
NS_LOG_DEBUG("Cannot request main PHY to switch when in state " << state);
return false;
@@ -812,6 +816,17 @@ AdvancedEmlsrManager::RequestMainPhyToSwitch(uint8_t linkId, AcIndex aci, const
return true;
}
const auto mainPhyLinkId = GetStaMac()->GetLinkForPhy(mainPhy);
if (!mainPhyLinkId.has_value())
{
NS_ASSERT(m_mainPhySwitchInfo.disconnected);
NS_LOG_DEBUG("The main PHY is not connected to any link");
// we don't know when the main PHY will be connected to the link it is switching to, nor
// which backoff value it will possibly generate; therefore, request it to switch to the
// aux PHY link
return true;
}
// let AC X be the AC that is about to gain channel access on the aux PHY link, request to
// switch the main PHY if we do not expect any AC, with priority higher than or equal to that
// of AC X and with frames to send on the main PHY link, to gain channel access on the main PHY

View File

@@ -906,6 +906,7 @@ EmlsrManager::SwitchMainPhy(uint8_t linkId,
m_mainPhySwitchInfo.to = linkId;
m_mainPhySwitchInfo.start = Simulator::Now();
m_mainPhySwitchInfo.disconnected = true;
m_mainPhySwitchInfo.reason = traceInfo.GetName();
const auto newMainPhyChannel = GetChannelForMainPhy(linkId);

View File

@@ -510,6 +510,7 @@ class EmlsrManager : public Object
//!< is switching or waiting to be connected to a link
uint8_t from{}; //!< ID of the link which the main PHY is/has been leaving
uint8_t to{}; //!< ID of the link which the main PHY is moving to
std::string reason; //!< the reason for switching the main PHY
};
Time m_emlsrPaddingDelay; //!< EMLSR Padding delay