[openthread] Apply CSL frame patch Apply the following patch to ToT. https://github.com/openthread/openthread/pull/8464 Test: Host<->RCP communication is working. Sherlock/Nelson manual verification `lowpanctl network-scan` and `lowpanctl energy-scan`. Bug: 117440 Change-Id: Ibb19ab4521b53e65a7149b871ef9338a859709e8 Reviewed-on: https://fuchsia-review.googlesource.com/c/third_party/openthread/+/776204 Reviewed-by: Robert Quattlebaum <rquattle@google.com> (cherry picked from commit e67312647f10a5822aaa3b57e297b7f099cc55e4)
diff --git a/src/core/thread/csl_tx_scheduler.cpp b/src/core/thread/csl_tx_scheduler.cpp index 15beb59..f2dfbd4 100644 --- a/src/core/thread/csl_tx_scheduler.cpp +++ b/src/core/thread/csl_tx_scheduler.cpp
@@ -134,7 +134,7 @@ continue; } - delay = GetNextCslTransmissionDelay(child, cslTxDelay); + delay = GetNextCslTransmissionDelay(child, cslTxDelay, mCslFrameRequestAheadUs); if (delay < minDelayTime) { @@ -151,18 +151,23 @@ mCslTxChild = bestChild; } -uint32_t CslTxScheduler::GetNextCslTransmissionDelay(const Child &aChild, uint32_t &aDelayFromLastRx) const +uint32_t CslTxScheduler::GetNextCslTransmissionDelay(const Child &aChild, + uint32_t & aDelayFromLastRx, + uint32_t aAheadUs) const { uint64_t radioNow = otPlatRadioGetNow(&GetInstance()); uint32_t periodInUs = aChild.GetCslPeriod() * kUsPerTenSymbols; uint64_t firstTxWindow = aChild.GetLastRxTimestamp() + aChild.GetCslPhase() * kUsPerTenSymbols; uint64_t nextTxWindow = radioNow - (radioNow % periodInUs) + (firstTxWindow % periodInUs); - while (nextTxWindow < radioNow + mCslFrameRequestAheadUs) nextTxWindow += periodInUs; + while (nextTxWindow < radioNow + aAheadUs) + { + nextTxWindow += periodInUs; + } aDelayFromLastRx = static_cast<uint32_t>(nextTxWindow - aChild.GetLastRxTimestamp()); - return static_cast<uint32_t>(nextTxWindow - radioNow - mCslFrameRequestAheadUs); + return static_cast<uint32_t>(nextTxWindow - radioNow - aAheadUs); } #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE @@ -171,6 +176,7 @@ { Mac::TxFrame *frame = nullptr; uint32_t txDelay; + uint32_t delay; VerifyOrExit(mCslTxChild != nullptr); @@ -207,7 +213,25 @@ frame->SetChannel(mCslTxChild->GetCslChannel() == 0 ? Get<Mac::Mac>().GetPanChannel() : mCslTxChild->GetCslChannel()); - GetNextCslTransmissionDelay(*mCslTxChild, txDelay); + delay = GetNextCslTransmissionDelay(*mCslTxChild, txDelay, /* aAheadUs */ 0); + + // We make sure that delay is less than `mCslFrameRequestAheadUs` + // plus some guard time. Note that we used `mCslFrameRequestAheadUs` + // in `RescheduleCslTx()` when determining the next CSL delay to + // schedule CSL tx with `Mac` but here we calculate the delay with + // zero `aAheadUs`. All the timings are in usec but when passing + // delay to `Mac` we divide by `1000` (to covert to msec) which + // can round the value down and cause `Mac` to start operation a + // bit (some usec) earlier. This is covered by adding the guard + // time `kFramePreparationGuardInterval`. + // + // In general this check handles the case where `Mac` is busy with + // other operations and therefore late to start the CSL tx operation + // and by the time `HandleFrameRequest()` is invoked, we miss the + // current CSL window and move to the next window. + + VerifyOrExit(delay <= mCslFrameRequestAheadUs + kFramePreparationGuardInterval, frame = nullptr); + frame->SetTxDelay(txDelay); frame->SetTxDelayBaseTime( static_cast<uint32_t>(mCslTxChild->GetLastRxTimestamp())); // Only LSB part of the time is required.
diff --git a/src/core/thread/csl_tx_scheduler.hpp b/src/core/thread/csl_tx_scheduler.hpp index d8e0368..708de8a 100644 --- a/src/core/thread/csl_tx_scheduler.hpp +++ b/src/core/thread/csl_tx_scheduler.hpp
@@ -187,10 +187,13 @@ void Clear(void); private: + // Guard time in usec to add when checking delay while preparaing the CSL frame for tx. + static constexpr uint32_t kFramePreparationGuardInterval = 1500; + void InitFrameRequestAhead(void); void RescheduleCslTx(void); - uint32_t GetNextCslTransmissionDelay(const Child &aChild, uint32_t &aDelayFromLastRx) const; + uint32_t GetNextCslTransmissionDelay(const Child &aChild, uint32_t &aDelayFromLastRx, uint32_t aAheadUs) const; // Callbacks from `Mac` Mac::TxFrame *HandleFrameRequest(Mac::TxFrames &aTxFrames);