[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);