From: Ping-Ke Shih <pkshih@realtek.com>
To: <kvalo@kernel.org>
Cc: <kevin_yang@realtek.com>, <linux-wireless@vger.kernel.org>
Subject: [PATCH v2 2/6] wifi: rtw89: mcc: fill fundamental configurations
Date: Thu, 31 Aug 2023 13:31:29 +0800 [thread overview]
Message-ID: <20230831053133.24015-3-pkshih@realtek.com> (raw)
In-Reply-To: <20230831053133.24015-1-pkshih@realtek.com>
From: Zong-Zhe Yang <kevin_yang@realtek.com>
We determine the fundamental settings shown below.
|< MCC interval >|
|< duration ref >|< duration aux >|
| | | |
|< beacon offset >|
| |
V V
(tbtt ref) (tbtt aux)
(where `ref` (reference) and `aux` (auxiliary) mean the two MCC roles)
Based on MCC mode (GO+STA or GC+STA), we fill configurations of
MCC interval and beacon offset. And, we make sure each MCC role
have a basically required duration in the MCC interval.
The beacon offset mentioned above is a parameter for further MCC
pattern calculation. If MCC is in GC+STA mode, we will calculate
the real beacon offset through TSFs shown in beacons of both MCC
roles. Otherwise, we will use a default beacon offset, and make
GO sync STA's TSF timer with this offset.
MCC pattern calculation will break down each MCC role's duration
in more detail. We will implement it in the following.
Signed-off-by: Zong-Zhe Yang <kevin_yang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
v2:
- fix unfined '__umoddi3' issue found by 0-DAY CI Kernel Test Service
---
drivers/net/wireless/realtek/rtw89/chan.c | 167 ++++++++++++++++++++++
drivers/net/wireless/realtek/rtw89/chan.h | 11 ++
drivers/net/wireless/realtek/rtw89/core.h | 9 ++
3 files changed, 187 insertions(+)
diff --git a/drivers/net/wireless/realtek/rtw89/chan.c b/drivers/net/wireless/realtek/rtw89/chan.c
index c71b0864426b..3778a569bb64 100644
--- a/drivers/net/wireless/realtek/rtw89/chan.c
+++ b/drivers/net/wireless/realtek/rtw89/chan.c
@@ -324,6 +324,39 @@ static u32 rtw89_mcc_get_tbtt_ofst(struct rtw89_dev *rtwdev,
return remainder;
}
+static u16 rtw89_mcc_get_bcn_ofst(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_mcc_info *mcc = &rtwdev->mcc;
+ struct rtw89_mcc_role *ref = &mcc->role_ref;
+ struct rtw89_mcc_role *aux = &mcc->role_aux;
+ struct rtw89_mac_mcc_tsf_rpt rpt = {};
+ struct rtw89_fw_mcc_tsf_req req = {};
+ u32 bcn_intvl_ref_us = ieee80211_tu_to_usec(ref->beacon_interval);
+ u32 tbtt_ofst_ref, tbtt_ofst_aux;
+ u64 tsf_ref, tsf_aux;
+ int ret;
+
+ req.group = mcc->group;
+ req.macid_x = ref->rtwvif->mac_id;
+ req.macid_y = aux->rtwvif->mac_id;
+ ret = rtw89_fw_h2c_mcc_req_tsf(rtwdev, &req, &rpt);
+ if (ret) {
+ rtw89_debug(rtwdev, RTW89_DBG_CHAN,
+ "MCC h2c failed to request tsf: %d\n", ret);
+ return RTW89_MCC_DFLT_BCN_OFST_TIME;
+ }
+
+ tsf_ref = (u64)rpt.tsf_x_high << 32 | rpt.tsf_x_low;
+ tsf_aux = (u64)rpt.tsf_y_high << 32 | rpt.tsf_y_low;
+ tbtt_ofst_ref = rtw89_mcc_get_tbtt_ofst(rtwdev, ref, tsf_ref);
+ tbtt_ofst_aux = rtw89_mcc_get_tbtt_ofst(rtwdev, aux, tsf_aux);
+
+ while (tbtt_ofst_ref < tbtt_ofst_aux)
+ tbtt_ofst_ref += bcn_intvl_ref_us;
+
+ return (tbtt_ofst_ref - tbtt_ofst_aux) / 1024;
+}
+
static
void rtw89_mcc_role_fw_macid_bitmap_set_bit(struct rtw89_mcc_role *mcc_role,
unsigned int bit)
@@ -611,6 +644,112 @@ static void rtw89_mcc_set_default_pattern(struct rtw89_dev *rtwdev)
rtw89_mcc_assign_pattern(rtwdev, &tmp);
}
+static void rtw89_mcc_set_duration_go_sta(struct rtw89_dev *rtwdev,
+ struct rtw89_mcc_role *role_go,
+ struct rtw89_mcc_role *role_sta)
+{
+ struct rtw89_mcc_info *mcc = &rtwdev->mcc;
+ struct rtw89_mcc_config *config = &mcc->config;
+ u16 mcc_intvl = config->mcc_interval;
+ u16 dur_go, dur_sta;
+
+ dur_go = clamp_t(u16, role_go->duration, RTW89_MCC_MIN_GO_DURATION,
+ mcc_intvl - RTW89_MCC_MIN_STA_DURATION);
+ if (role_go->limit.enable)
+ dur_go = min(dur_go, role_go->limit.max_dur);
+ dur_sta = mcc_intvl - dur_go;
+
+ rtw89_debug(rtwdev, RTW89_DBG_CHAN,
+ "MCC set dur: (go, sta) {%d, %d} -> {%d, %d}\n",
+ role_go->duration, role_sta->duration, dur_go, dur_sta);
+
+ role_go->duration = dur_go;
+ role_sta->duration = dur_sta;
+}
+
+static void rtw89_mcc_set_duration_gc_sta(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_mcc_info *mcc = &rtwdev->mcc;
+ struct rtw89_mcc_role *ref = &mcc->role_ref;
+ struct rtw89_mcc_role *aux = &mcc->role_aux;
+ struct rtw89_mcc_config *config = &mcc->config;
+ u16 mcc_intvl = config->mcc_interval;
+ u16 dur_ref, dur_aux;
+
+ if (ref->duration < RTW89_MCC_MIN_STA_DURATION) {
+ dur_ref = RTW89_MCC_MIN_STA_DURATION;
+ dur_aux = mcc_intvl - dur_ref;
+ } else if (aux->duration < RTW89_MCC_MIN_STA_DURATION) {
+ dur_aux = RTW89_MCC_MIN_STA_DURATION;
+ dur_ref = mcc_intvl - dur_aux;
+ } else {
+ dur_ref = ref->duration;
+ dur_aux = mcc_intvl - dur_ref;
+ }
+
+ if (ref->limit.enable) {
+ dur_ref = min(dur_ref, ref->limit.max_dur);
+ dur_aux = mcc_intvl - dur_ref;
+ } else if (aux->limit.enable) {
+ dur_aux = min(dur_aux, aux->limit.max_dur);
+ dur_ref = mcc_intvl - dur_aux;
+ }
+
+ rtw89_debug(rtwdev, RTW89_DBG_CHAN,
+ "MCC set dur: (ref, aux) {%d ~ %d} -> {%d ~ %d}\n",
+ ref->duration, aux->duration, dur_ref, dur_aux);
+
+ ref->duration = dur_ref;
+ aux->duration = dur_aux;
+}
+
+static void rtw89_mcc_sync_tbtt(struct rtw89_dev *rtwdev,
+ struct rtw89_mcc_role *tgt,
+ struct rtw89_mcc_role *src,
+ bool ref_is_src)
+{
+ struct rtw89_mcc_info *mcc = &rtwdev->mcc;
+ struct rtw89_mcc_config *config = &mcc->config;
+ u16 beacon_offset_us = ieee80211_tu_to_usec(config->beacon_offset);
+ u32 bcn_intvl_src_us = ieee80211_tu_to_usec(src->beacon_interval);
+ u32 cur_tbtt_ofst_src;
+ u32 tsf_ofst_tgt;
+ u32 remainder;
+ u64 tbtt_tgt;
+ u64 tsf_src;
+ int ret;
+
+ ret = rtw89_mac_port_get_tsf(rtwdev, src->rtwvif, &tsf_src);
+ if (ret) {
+ rtw89_warn(rtwdev, "MCC failed to get port tsf: %d\n", ret);
+ return;
+ }
+
+ cur_tbtt_ofst_src = rtw89_mcc_get_tbtt_ofst(rtwdev, src, tsf_src);
+
+ if (ref_is_src)
+ tbtt_tgt = tsf_src - cur_tbtt_ofst_src + beacon_offset_us;
+ else
+ tbtt_tgt = tsf_src - cur_tbtt_ofst_src +
+ (bcn_intvl_src_us - beacon_offset_us);
+
+ div_u64_rem(tbtt_tgt, bcn_intvl_src_us, &remainder);
+ tsf_ofst_tgt = bcn_intvl_src_us - remainder;
+
+ config->sync.macid_tgt = tgt->rtwvif->mac_id;
+ config->sync.macid_src = src->rtwvif->mac_id;
+ config->sync.offset = tsf_ofst_tgt / 1024;
+ config->sync.enable = true;
+
+ rtw89_debug(rtwdev, RTW89_DBG_CHAN,
+ "MCC sync tbtt: tgt %d, src %d, offset %d\n",
+ config->sync.macid_tgt, config->sync.macid_src,
+ config->sync.offset);
+
+ rtw89_mac_port_tsf_sync(rtwdev, tgt->rtwvif, src->rtwvif,
+ config->sync.offset);
+}
+
static int rtw89_mcc_fill_start_tsf(struct rtw89_dev *rtwdev)
{
struct rtw89_mcc_info *mcc = &rtwdev->mcc;
@@ -648,9 +787,35 @@ static int rtw89_mcc_fill_start_tsf(struct rtw89_dev *rtwdev)
static int rtw89_mcc_fill_config(struct rtw89_dev *rtwdev)
{
struct rtw89_mcc_info *mcc = &rtwdev->mcc;
+ struct rtw89_mcc_role *ref = &mcc->role_ref;
+ struct rtw89_mcc_role *aux = &mcc->role_aux;
struct rtw89_mcc_config *config = &mcc->config;
memset(config, 0, sizeof(*config));
+
+ switch (mcc->mode) {
+ case RTW89_MCC_MODE_GO_STA:
+ config->beacon_offset = RTW89_MCC_DFLT_BCN_OFST_TIME;
+ if (ref->is_go) {
+ rtw89_mcc_sync_tbtt(rtwdev, ref, aux, false);
+ config->mcc_interval = ref->beacon_interval;
+ rtw89_mcc_set_duration_go_sta(rtwdev, ref, aux);
+ } else {
+ rtw89_mcc_sync_tbtt(rtwdev, aux, ref, true);
+ config->mcc_interval = aux->beacon_interval;
+ rtw89_mcc_set_duration_go_sta(rtwdev, aux, ref);
+ }
+ break;
+ case RTW89_MCC_MODE_GC_STA:
+ config->beacon_offset = rtw89_mcc_get_bcn_ofst(rtwdev);
+ config->mcc_interval = ref->beacon_interval;
+ rtw89_mcc_set_duration_gc_sta(rtwdev);
+ break;
+ default:
+ rtw89_warn(rtwdev, "MCC unknown mode: %d\n", mcc->mode);
+ return -EFAULT;
+ }
+
rtw89_mcc_set_default_pattern(rtwdev);
return rtw89_mcc_fill_start_tsf(rtwdev);
}
@@ -680,6 +845,8 @@ static int rtw89_mcc_start(struct rtw89_dev *rtwdev)
rtw89_debug(rtwdev, RTW89_DBG_CHAN, "MCC sel mode: %d\n", mcc->mode);
+ mcc->group = RTW89_MCC_DFLT_GROUP;
+
ret = rtw89_mcc_fill_config(rtwdev);
if (ret)
return ret;
diff --git a/drivers/net/wireless/realtek/rtw89/chan.h b/drivers/net/wireless/realtek/rtw89/chan.h
index eac5e0460e10..9bdf3d1637bb 100644
--- a/drivers/net/wireless/realtek/rtw89/chan.h
+++ b/drivers/net/wireless/realtek/rtw89/chan.h
@@ -13,7 +13,18 @@
/* various MCC setting time in TU */
#define RTW89_MCC_LONG_TRIGGER_TIME 300
#define RTW89_MCC_SHORT_TRIGGER_TIME 100
+#define RTW89_MCC_EARLY_TX_BCN_TIME 10
+#define RTW89_MCC_EARLY_RX_BCN_TIME 5
+#define RTW89_MCC_MIN_RX_BCN_TIME 10
+#define RTW89_MCC_DFLT_BCN_OFST_TIME 40
+#define RTW89_MCC_MIN_GO_DURATION \
+ (RTW89_MCC_EARLY_TX_BCN_TIME + RTW89_MCC_MIN_RX_BCN_TIME)
+
+#define RTW89_MCC_MIN_STA_DURATION \
+ (RTW89_MCC_EARLY_RX_BCN_TIME + RTW89_MCC_MIN_RX_BCN_TIME)
+
+#define RTW89_MCC_DFLT_GROUP 0
#define RTW89_MCC_DFLT_TX_NULL_EARLY 3
#define RTW89_MCC_DFLT_COURTESY_SLOT 3
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index c14fd08cac98..4775fb490034 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -4415,8 +4415,16 @@ struct rtw89_mcc_pattern {
struct rtw89_mcc_courtesy courtesy;
};
+struct rtw89_mcc_sync {
+ bool enable;
+ u16 offset; /* TU */
+ u8 macid_src;
+ u8 macid_tgt;
+};
+
struct rtw89_mcc_config {
struct rtw89_mcc_pattern pattern;
+ struct rtw89_mcc_sync sync;
u64 start_tsf;
u16 mcc_interval; /* TU */
u16 beacon_offset; /* TU */
@@ -4430,6 +4438,7 @@ enum rtw89_mcc_mode {
struct rtw89_mcc_info {
struct rtw89_wait_info wait;
+ u8 group;
enum rtw89_mcc_mode mode;
struct rtw89_mcc_role role_ref; /* reference role */
struct rtw89_mcc_role role_aux; /* auxiliary role */
--
2.25.1
next prev parent reply other threads:[~2023-08-31 5:32 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-08-31 5:31 [PATCH v2 0/6] wifi: rtw89: prepare timeslot and trigger firmware for MCC Ping-Ke Shih
2023-08-31 5:31 ` [PATCH v2 1/6] wifi: rtw89: mcc: initialize start flow Ping-Ke Shih
2023-09-07 5:56 ` Kalle Valo
2023-08-31 5:31 ` Ping-Ke Shih [this message]
2023-08-31 5:31 ` [PATCH v2 3/6] wifi: rtw89: mcc: consider and determine BT duration Ping-Ke Shih
2023-08-31 5:31 ` [PATCH v2 4/6] wifi: rtw89: mcc: decide pattern and calculate parameters Ping-Ke Shih
2023-08-31 5:31 ` [PATCH v2 5/6] wifi: rtw89: fix typo of rtw89_fw_h2c_mcc_macid_bitmap() Ping-Ke Shih
2023-08-31 5:31 ` [PATCH v2 6/6] wifi: rtw89: mcc: trigger FW to start/stop MCC Ping-Ke Shih
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230831053133.24015-3-pkshih@realtek.com \
--to=pkshih@realtek.com \
--cc=kevin_yang@realtek.com \
--cc=kvalo@kernel.org \
--cc=linux-wireless@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).