All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/6] wifi: rtw89: adjust channel context stuffs for MCC and MLO
@ 2024-02-06  3:06 Ping-Ke Shih
  2024-02-06  3:06 ` [PATCH 1/6] wifi: rtw89: drop TIMING_BEACON_ONLY and sync beacon TSF by self Ping-Ke Shih
                   ` (5 more replies)
  0 siblings, 6 replies; 8+ messages in thread
From: Ping-Ke Shih @ 2024-02-06  3:06 UTC (permalink / raw)
  To: kvalo; +Cc: kevin_yang, linux-wireless

We are going to add MCC for WiFi 7 chips that uses similar flow like
WiFi 6 chips but new firmware H2C commands and events are added, because
these new firmware interfaces will support MCC over MLO as well. Before
that, we are adjusting the channel context stuffs by this patchset. Since
we still not support MLO yet, mostly we are adjusting to support legacy MCC.

Zong-Zhe Yang (6):
  wifi: rtw89: drop TIMING_BEACON_ONLY and sync beacon TSF by self
  wifi: rtw89: chan: add sub-entity swap function to cover replacing
  wifi: rtw89: chan: tweak bitmap recalc ahead before MLO
  wifi: rtw89: chan: tweak weight recalc ahead before MLO
  wifi: rtw89: chan: move handling from add/remove to assign/unassign
    for MLO
  wifi: rtw89: chan: MCC take reconfig into account

 drivers/net/wireless/realtek/rtw89/chan.c     | 204 ++++++++++++------
 drivers/net/wireless/realtek/rtw89/chan.h     |   5 +
 drivers/net/wireless/realtek/rtw89/core.c     |  23 +-
 drivers/net/wireless/realtek/rtw89/core.h     |   9 +-
 drivers/net/wireless/realtek/rtw89/mac80211.c |   1 +
 5 files changed, 174 insertions(+), 68 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/6] wifi: rtw89: drop TIMING_BEACON_ONLY and sync beacon TSF by self
  2024-02-06  3:06 [PATCH 0/6] wifi: rtw89: adjust channel context stuffs for MCC and MLO Ping-Ke Shih
@ 2024-02-06  3:06 ` Ping-Ke Shih
  2024-02-12 15:37   ` Kalle Valo
  2024-02-06  3:06 ` [PATCH 2/6] wifi: rtw89: chan: add sub-entity swap function to cover replacing Ping-Ke Shih
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 8+ messages in thread
From: Ping-Ke Shih @ 2024-02-06  3:06 UTC (permalink / raw)
  To: kvalo; +Cc: kevin_yang, linux-wireless

From: Zong-Zhe Yang <kevin_yang@realtek.com>

Some of our calculation during concurrent mode depend on last beacon
TSF. Originally, we just set IEEE80211_HW_TIMING_BEACON_ONLY and get
what we want from mac80211. But, IEEE80211_HW_TIMING_BEACON_ONLY will
be restricted once we declare MLO.

Since we are about to consider the MLO stuffs, so sync beacon TSF by
ourselves now and unset IEEE80211_HW_TIMING_BEACON_ONLY.

Signed-off-by: Zong-Zhe Yang <kevin_yang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw89/chan.c     |  9 +--------
 drivers/net/wireless/realtek/rtw89/core.c     | 18 ++++++++++++++----
 drivers/net/wireless/realtek/rtw89/core.h     |  1 +
 drivers/net/wireless/realtek/rtw89/mac80211.c |  1 +
 4 files changed, 17 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw89/chan.c b/drivers/net/wireless/realtek/rtw89/chan.c
index 21449cb9b069..2a95f9db83f9 100644
--- a/drivers/net/wireless/realtek/rtw89/chan.c
+++ b/drivers/net/wireless/realtek/rtw89/chan.c
@@ -320,19 +320,12 @@ int rtw89_iterate_mcc_roles(struct rtw89_dev *rtwdev,
 	return 0;
 }
 
-/* For now, IEEE80211_HW_TIMING_BEACON_ONLY can make things simple to ensure
- * correctness of MCC calculation logic below. We have noticed that once driver
- * declares WIPHY_FLAG_SUPPORTS_MLO, the use of IEEE80211_HW_TIMING_BEACON_ONLY
- * will be restricted. We will make an alternative in driver when it is ready
- * for MLO.
- */
 static u32 rtw89_mcc_get_tbtt_ofst(struct rtw89_dev *rtwdev,
 				   struct rtw89_mcc_role *role, u64 tsf)
 {
 	struct rtw89_vif *rtwvif = role->rtwvif;
-	struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
 	u32 bcn_intvl_us = ieee80211_tu_to_usec(role->beacon_interval);
-	u64 sync_tsf = vif->bss_conf.sync_tsf;
+	u64 sync_tsf = READ_ONCE(rtwvif->sync_bcn_tsf);
 	u32 remainder;
 
 	if (tsf < sync_tsf) {
diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index 260da86bf04a..de4c37c48f4e 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -1868,6 +1868,17 @@ static void rtw89_core_cancel_6ghz_probe_tx(struct rtw89_dev *rtwdev,
 		ieee80211_queue_work(rtwdev->hw, &rtwdev->cancel_6ghz_probe_work);
 }
 
+static void rtw89_vif_sync_bcn_tsf(struct rtw89_vif *rtwvif,
+				   struct ieee80211_hdr *hdr, size_t len)
+{
+	struct ieee80211_mgmt *mgmt = (typeof(mgmt))hdr;
+
+	if (len < offsetof(typeof(*mgmt), u.beacon.variable))
+		return;
+
+	WRITE_ONCE(rtwvif->sync_bcn_tsf, le64_to_cpu(mgmt->u.beacon.timestamp));
+}
+
 static void rtw89_vif_rx_stats_iter(void *data, u8 *mac,
 				    struct ieee80211_vif *vif)
 {
@@ -1898,8 +1909,10 @@ static void rtw89_vif_rx_stats_iter(void *data, u8 *mac,
 		return;
 
 	if (ieee80211_is_beacon(hdr->frame_control)) {
-		if (vif->type == NL80211_IFTYPE_STATION)
+		if (vif->type == NL80211_IFTYPE_STATION) {
+			rtw89_vif_sync_bcn_tsf(rtwvif, hdr, skb->len);
 			rtw89_fw_h2c_rssi_offload(rtwdev, phy_ppdu);
+		}
 		pkt_stat->beacon_nr++;
 	}
 
@@ -4445,9 +4458,6 @@ static int rtw89_core_register_hw(struct rtw89_dev *rtwdev)
 	ieee80211_hw_set(hw, SUPPORTS_MULTI_BSSID);
 	ieee80211_hw_set(hw, WANT_MONITOR_VIF);
 
-	/* ref: description of rtw89_mcc_get_tbtt_ofst() in chan.c */
-	ieee80211_hw_set(hw, TIMING_BEACON_ONLY);
-
 	if (chip->support_bandwidths & BIT(NL80211_CHAN_WIDTH_160))
 		ieee80211_hw_set(hw, SUPPORTS_VHT_EXT_NSS_BW);
 
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 30cc77ac78c5..927356861cb8 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -3043,6 +3043,7 @@ struct rtw89_vif {
 	u8 bcn_hit_cond;
 	u8 hit_rule;
 	u8 last_noa_nr;
+	u64 sync_bcn_tsf;
 	bool offchan;
 	bool trigger;
 	bool lsig_txop;
diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c
index b61c5be8cae3..31d1ffb16e83 100644
--- a/drivers/net/wireless/realtek/rtw89/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c
@@ -449,6 +449,7 @@ static void rtw89_ops_bss_info_changed(struct ieee80211_hw *hw,
 		ether_addr_copy(rtwvif->bssid, conf->bssid);
 		rtw89_cam_bssid_changed(rtwdev, rtwvif);
 		rtw89_fw_h2c_cam(rtwdev, rtwvif, NULL, NULL);
+		WRITE_ONCE(rtwvif->sync_bcn_tsf, 0);
 	}
 
 	if (changed & BSS_CHANGED_BEACON)
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/6] wifi: rtw89: chan: add sub-entity swap function to cover replacing
  2024-02-06  3:06 [PATCH 0/6] wifi: rtw89: adjust channel context stuffs for MCC and MLO Ping-Ke Shih
  2024-02-06  3:06 ` [PATCH 1/6] wifi: rtw89: drop TIMING_BEACON_ONLY and sync beacon TSF by self Ping-Ke Shih
@ 2024-02-06  3:06 ` Ping-Ke Shih
  2024-02-06  3:06 ` [PATCH 3/6] wifi: rtw89: chan: tweak bitmap recalc ahead before MLO Ping-Ke Shih
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Ping-Ke Shih @ 2024-02-06  3:06 UTC (permalink / raw)
  To: kvalo; +Cc: kevin_yang, linux-wireless

From: Zong-Zhe Yang <kevin_yang@realtek.com>

Originally, we replaced sub-entity of index 0 with another one in some
cases. However, we will need a swap here in following implementations.
So, we introduce it ahead and change code from replacing to swapping.

Signed-off-by: Zong-Zhe Yang <kevin_yang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw89/chan.c | 47 +++++++++++++++++------
 1 file changed, 36 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw89/chan.c b/drivers/net/wireless/realtek/rtw89/chan.c
index 2a95f9db83f9..11d46878f51e 100644
--- a/drivers/net/wireless/realtek/rtw89/chan.c
+++ b/drivers/net/wireless/realtek/rtw89/chan.c
@@ -1893,6 +1893,41 @@ void rtw89_chanctx_proceed(struct rtw89_dev *rtwdev)
 	rtw89_queue_chanctx_work(rtwdev);
 }
 
+static void rtw89_swap_sub_entity(struct rtw89_dev *rtwdev,
+				  enum rtw89_sub_entity_idx idx1,
+				  enum rtw89_sub_entity_idx idx2)
+{
+	struct rtw89_hal *hal = &rtwdev->hal;
+	struct rtw89_sub_entity tmp;
+	struct rtw89_vif *rtwvif;
+	u8 cur;
+
+	if (idx1 == idx2)
+		return;
+
+	hal->sub[idx1].cfg->idx = idx2;
+	hal->sub[idx2].cfg->idx = idx1;
+
+	tmp = hal->sub[idx1];
+	hal->sub[idx1] = hal->sub[idx2];
+	hal->sub[idx2] = tmp;
+
+	rtw89_for_each_rtwvif(rtwdev, rtwvif) {
+		if (!rtwvif->chanctx_assigned)
+			continue;
+		if (rtwvif->sub_entity_idx == idx1)
+			rtwvif->sub_entity_idx = idx2;
+		else if (rtwvif->sub_entity_idx == idx2)
+			rtwvif->sub_entity_idx = idx1;
+	}
+
+	cur = atomic_read(&hal->roc_entity_idx);
+	if (cur == idx1)
+		atomic_set(&hal->roc_entity_idx, idx2);
+	else if (cur == idx2)
+		atomic_set(&hal->roc_entity_idx, idx1);
+}
+
 int rtw89_chanctx_ops_add(struct rtw89_dev *rtwdev,
 			  struct ieee80211_chanctx_conf *ctx)
 {
@@ -1918,7 +1953,6 @@ void rtw89_chanctx_ops_remove(struct rtw89_dev *rtwdev,
 	struct rtw89_hal *hal = &rtwdev->hal;
 	struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv;
 	enum rtw89_entity_mode mode;
-	struct rtw89_vif *rtwvif;
 	u8 drop, roll;
 
 	drop = cfg->idx;
@@ -1934,16 +1968,7 @@ void rtw89_chanctx_ops_remove(struct rtw89_dev *rtwdev,
 	/* RTW89_SUB_ENTITY_0 is going to release, and another exists.
 	 * Make another roll down to RTW89_SUB_ENTITY_0 to replace.
 	 */
-	hal->sub[roll].cfg->idx = RTW89_SUB_ENTITY_0;
-	hal->sub[RTW89_SUB_ENTITY_0] = hal->sub[roll];
-
-	rtw89_for_each_rtwvif(rtwdev, rtwvif) {
-		if (rtwvif->sub_entity_idx == roll)
-			rtwvif->sub_entity_idx = RTW89_SUB_ENTITY_0;
-	}
-
-	atomic_cmpxchg(&hal->roc_entity_idx, roll, RTW89_SUB_ENTITY_0);
-
+	rtw89_swap_sub_entity(rtwdev, RTW89_SUB_ENTITY_0, roll);
 	drop = roll;
 
 out:
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 3/6] wifi: rtw89: chan: tweak bitmap recalc ahead before MLO
  2024-02-06  3:06 [PATCH 0/6] wifi: rtw89: adjust channel context stuffs for MCC and MLO Ping-Ke Shih
  2024-02-06  3:06 ` [PATCH 1/6] wifi: rtw89: drop TIMING_BEACON_ONLY and sync beacon TSF by self Ping-Ke Shih
  2024-02-06  3:06 ` [PATCH 2/6] wifi: rtw89: chan: add sub-entity swap function to cover replacing Ping-Ke Shih
@ 2024-02-06  3:06 ` Ping-Ke Shih
  2024-02-06  3:06 ` [PATCH 4/6] wifi: rtw89: chan: tweak weight " Ping-Ke Shih
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Ping-Ke Shih @ 2024-02-06  3:06 UTC (permalink / raw)
  To: kvalo; +Cc: kevin_yang, linux-wireless

From: Zong-Zhe Yang <kevin_yang@realtek.com>

Originally, we just declared two sub-entity, and according to rolling
down mechanism, we ensured that index 0 contained sub-entity as long
as there are sub-entity. So, we could use for-loop after deciding the
last index.

But, we are preparing to expand num of sub-entity for MLO. Then, there
won't be just two sub-entity. And, there might be holes between two bits
in the bitmap. So, we cannot simply do for-loop as before. Instead, we
need to follow the set bits.

Signed-off-by: Zong-Zhe Yang <kevin_yang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw89/chan.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw89/chan.c b/drivers/net/wireless/realtek/rtw89/chan.c
index 11d46878f51e..6a666a92b59b 100644
--- a/drivers/net/wireless/realtek/rtw89/chan.c
+++ b/drivers/net/wireless/realtek/rtw89/chan.c
@@ -214,31 +214,32 @@ void rtw89_entity_init(struct rtw89_dev *rtwdev)
 
 enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev)
 {
+	DECLARE_BITMAP(recalc_map, NUM_OF_RTW89_SUB_ENTITY) = {};
 	struct rtw89_hal *hal = &rtwdev->hal;
 	const struct cfg80211_chan_def *chandef;
 	enum rtw89_entity_mode mode;
 	struct rtw89_chan chan;
 	u8 weight;
-	u8 last;
 	u8 idx;
 
 	lockdep_assert_held(&rtwdev->mutex);
 
+	bitmap_copy(recalc_map, hal->entity_map, NUM_OF_RTW89_SUB_ENTITY);
+
 	weight = bitmap_weight(hal->entity_map, NUM_OF_RTW89_SUB_ENTITY);
 	switch (weight) {
 	default:
 		rtw89_warn(rtwdev, "unknown ent chan weight: %d\n", weight);
-		bitmap_zero(hal->entity_map, NUM_OF_RTW89_SUB_ENTITY);
+		bitmap_zero(recalc_map, NUM_OF_RTW89_SUB_ENTITY);
 		fallthrough;
 	case 0:
 		rtw89_config_default_chandef(rtwdev);
+		set_bit(RTW89_SUB_ENTITY_0, recalc_map);
 		fallthrough;
 	case 1:
-		last = RTW89_SUB_ENTITY_0;
 		mode = RTW89_ENTITY_MODE_SCC;
 		break;
 	case 2:
-		last = RTW89_SUB_ENTITY_1;
 		mode = rtw89_get_entity_mode(rtwdev);
 		if (mode == RTW89_ENTITY_MODE_MCC)
 			break;
@@ -247,7 +248,7 @@ enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev)
 		break;
 	}
 
-	for (idx = 0; idx <= last; idx++) {
+	for_each_set_bit(idx, recalc_map, NUM_OF_RTW89_SUB_ENTITY) {
 		chandef = rtw89_chandef_get(rtwdev, idx);
 		rtw89_get_channel_params(chandef, &chan);
 		if (chan.channel == 0) {
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 4/6] wifi: rtw89: chan: tweak weight recalc ahead before MLO
  2024-02-06  3:06 [PATCH 0/6] wifi: rtw89: adjust channel context stuffs for MCC and MLO Ping-Ke Shih
                   ` (2 preceding siblings ...)
  2024-02-06  3:06 ` [PATCH 3/6] wifi: rtw89: chan: tweak bitmap recalc ahead before MLO Ping-Ke Shih
@ 2024-02-06  3:06 ` Ping-Ke Shih
  2024-02-06  3:06 ` [PATCH 5/6] wifi: rtw89: chan: move handling from add/remove to assign/unassign for MLO Ping-Ke Shih
  2024-02-06  3:06 ` [PATCH 6/6] wifi: rtw89: chan: MCC take reconfig into account Ping-Ke Shih
  5 siblings, 0 replies; 8+ messages in thread
From: Ping-Ke Shih @ 2024-02-06  3:06 UTC (permalink / raw)
  To: kvalo; +Cc: kevin_yang, linux-wireless

From: Zong-Zhe Yang <kevin_yang@realtek.com>

Originally, we consider weight only based on how many chanctxs that
mac80211 sets. However, we need to consider both active chanctxs and
active interfaces to distinguish MCC (multiple channel concurrent)
from impending MLO.

Although the logic of handling is extended, for now, behavior might
not be different under current condition.

Signed-off-by: Zong-Zhe Yang <kevin_yang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw89/chan.c | 51 ++++++++++++++++++++---
 drivers/net/wireless/realtek/rtw89/chan.h |  5 +++
 drivers/net/wireless/realtek/rtw89/core.h |  6 ++-
 3 files changed, 56 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw89/chan.c b/drivers/net/wireless/realtek/rtw89/chan.c
index 6a666a92b59b..57fabc05dab9 100644
--- a/drivers/net/wireless/realtek/rtw89/chan.c
+++ b/drivers/net/wireless/realtek/rtw89/chan.c
@@ -212,24 +212,51 @@ void rtw89_entity_init(struct rtw89_dev *rtwdev)
 	rtw89_config_default_chandef(rtwdev);
 }
 
+static void rtw89_entity_calculate_weight(struct rtw89_dev *rtwdev,
+					  struct rtw89_entity_weight *w)
+{
+	struct rtw89_hal *hal = &rtwdev->hal;
+	const struct rtw89_chanctx_cfg *cfg;
+	struct rtw89_vif *rtwvif;
+	int idx;
+
+	for_each_set_bit(idx, hal->entity_map, NUM_OF_RTW89_SUB_ENTITY) {
+		cfg = hal->sub[idx].cfg;
+		if (!cfg) {
+			/* doesn't run with chanctx ops; one channel at most */
+			w->active_chanctxs = 1;
+			break;
+		}
+
+		if (cfg->ref_count > 0)
+			w->active_chanctxs++;
+	}
+
+	rtw89_for_each_rtwvif(rtwdev, rtwvif) {
+		if (rtwvif->chanctx_assigned)
+			w->active_roles++;
+	}
+}
+
 enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev)
 {
 	DECLARE_BITMAP(recalc_map, NUM_OF_RTW89_SUB_ENTITY) = {};
 	struct rtw89_hal *hal = &rtwdev->hal;
 	const struct cfg80211_chan_def *chandef;
+	struct rtw89_entity_weight w = {};
 	enum rtw89_entity_mode mode;
 	struct rtw89_chan chan;
-	u8 weight;
 	u8 idx;
 
 	lockdep_assert_held(&rtwdev->mutex);
 
 	bitmap_copy(recalc_map, hal->entity_map, NUM_OF_RTW89_SUB_ENTITY);
 
-	weight = bitmap_weight(hal->entity_map, NUM_OF_RTW89_SUB_ENTITY);
-	switch (weight) {
+	rtw89_entity_calculate_weight(rtwdev, &w);
+	switch (w.active_chanctxs) {
 	default:
-		rtw89_warn(rtwdev, "unknown ent chan weight: %d\n", weight);
+		rtw89_warn(rtwdev, "unknown ent chanctxs weight: %d\n",
+			   w.active_chanctxs);
 		bitmap_zero(recalc_map, NUM_OF_RTW89_SUB_ENTITY);
 		fallthrough;
 	case 0:
@@ -239,7 +266,14 @@ enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev)
 	case 1:
 		mode = RTW89_ENTITY_MODE_SCC;
 		break;
-	case 2:
+	case 2 ... NUM_OF_RTW89_SUB_ENTITY:
+		if (w.active_roles != NUM_OF_RTW89_MCC_ROLES) {
+			rtw89_debug(rtwdev, RTW89_DBG_CHAN,
+				    "unhandled ent: %d chanctxs %d roles\n",
+				    w.active_chanctxs, w.active_roles);
+			return RTW89_ENTITY_MODE_UNHANDLED;
+		}
+
 		mode = rtw89_get_entity_mode(rtwdev);
 		if (mode == RTW89_ENTITY_MODE_MCC)
 			break;
@@ -582,6 +616,9 @@ static int rtw89_mcc_fill_all_roles(struct rtw89_dev *rtwdev)
 	int ret;
 
 	rtw89_for_each_rtwvif(rtwdev, rtwvif) {
+		if (!rtwvif->chanctx_assigned)
+			continue;
+
 		if (sel.bind_vif[rtwvif->sub_entity_idx]) {
 			rtw89_warn(rtwdev,
 				   "MCC skip extra vif <macid %d> on chanctx[%d]\n",
@@ -2007,6 +2044,7 @@ int rtw89_chanctx_ops_assign_vif(struct rtw89_dev *rtwdev,
 
 	rtwvif->sub_entity_idx = cfg->idx;
 	rtwvif->chanctx_assigned = true;
+	cfg->ref_count++;
 	return 0;
 }
 
@@ -2014,6 +2052,9 @@ void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev *rtwdev,
 				    struct rtw89_vif *rtwvif,
 				    struct ieee80211_chanctx_conf *ctx)
 {
+	struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv;
+
 	rtwvif->sub_entity_idx = RTW89_SUB_ENTITY_0;
 	rtwvif->chanctx_assigned = false;
+	cfg->ref_count--;
 }
diff --git a/drivers/net/wireless/realtek/rtw89/chan.h b/drivers/net/wireless/realtek/rtw89/chan.h
index 9b98d8f4ee9d..ffa412f281f3 100644
--- a/drivers/net/wireless/realtek/rtw89/chan.h
+++ b/drivers/net/wireless/realtek/rtw89/chan.h
@@ -38,6 +38,11 @@ enum rtw89_chanctx_pause_reasons {
 	RTW89_CHANCTX_PAUSE_REASON_ROC,
 };
 
+struct rtw89_entity_weight {
+	unsigned int active_chanctxs;
+	unsigned int active_roles;
+};
+
 static inline bool rtw89_get_entity_state(struct rtw89_dev *rtwdev)
 {
 	struct rtw89_hal *hal = &rtwdev->hal;
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 927356861cb8..ba2b298c4a9b 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -4119,6 +4119,7 @@ struct rtw89_tas_info {
 
 struct rtw89_chanctx_cfg {
 	enum rtw89_sub_entity_idx idx;
+	int ref_count;
 };
 
 enum rtw89_chanctx_changes {
@@ -4138,13 +4139,16 @@ enum rtw89_entity_mode {
 	RTW89_ENTITY_MODE_MCC,
 
 	NUM_OF_RTW89_ENTITY_MODE,
-	RTW89_ENTITY_MODE_INVALID = NUM_OF_RTW89_ENTITY_MODE,
+	RTW89_ENTITY_MODE_INVALID = -EINVAL,
+	RTW89_ENTITY_MODE_UNHANDLED = -ESRCH,
 };
 
 struct rtw89_sub_entity {
 	struct cfg80211_chan_def chandef;
 	struct rtw89_chan chan;
 	struct rtw89_chan_rcd rcd;
+
+	/* only assigned when running with chanctx_ops */
 	struct rtw89_chanctx_cfg *cfg;
 };
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 5/6] wifi: rtw89: chan: move handling from add/remove to assign/unassign for MLO
  2024-02-06  3:06 [PATCH 0/6] wifi: rtw89: adjust channel context stuffs for MCC and MLO Ping-Ke Shih
                   ` (3 preceding siblings ...)
  2024-02-06  3:06 ` [PATCH 4/6] wifi: rtw89: chan: tweak weight " Ping-Ke Shih
@ 2024-02-06  3:06 ` Ping-Ke Shih
  2024-02-06  3:06 ` [PATCH 6/6] wifi: rtw89: chan: MCC take reconfig into account Ping-Ke Shih
  5 siblings, 0 replies; 8+ messages in thread
From: Ping-Ke Shih @ 2024-02-06  3:06 UTC (permalink / raw)
  To: kvalo; +Cc: kevin_yang, linux-wireless

From: Zong-Zhe Yang <kevin_yang@realtek.com>

After MLO, we will need to consider not only active chanctx but also active
interfaces (roles) to decide entity things. So in advance, we move handling
from chanctx_ops::add/remove to chanctx_ops::assign_vif/unassign_vif. Then,
we can recalculate and aware active interfaces' changes.

For now, behavior should not be really different, since active chanctx and
active interface are one-to-one mapping before MLO.

Signed-off-by: Zong-Zhe Yang <kevin_yang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw89/chan.c | 75 +++++++++++++----------
 drivers/net/wireless/realtek/rtw89/core.c |  5 +-
 drivers/net/wireless/realtek/rtw89/core.h |  2 +-
 3 files changed, 47 insertions(+), 35 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw89/chan.c b/drivers/net/wireless/realtek/rtw89/chan.c
index 57fabc05dab9..71fe0d3ab3b0 100644
--- a/drivers/net/wireless/realtek/rtw89/chan.c
+++ b/drivers/net/wireless/realtek/rtw89/chan.c
@@ -1979,7 +1979,6 @@ int rtw89_chanctx_ops_add(struct rtw89_dev *rtwdev,
 		return -ENOENT;
 
 	rtw89_config_entity_chandef(rtwdev, idx, &ctx->def);
-	rtw89_set_channel(rtwdev);
 	cfg->idx = idx;
 	hal->sub[idx].cfg = cfg;
 	return 0;
@@ -1990,37 +1989,8 @@ void rtw89_chanctx_ops_remove(struct rtw89_dev *rtwdev,
 {
 	struct rtw89_hal *hal = &rtwdev->hal;
 	struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv;
-	enum rtw89_entity_mode mode;
-	u8 drop, roll;
-
-	drop = cfg->idx;
-	if (drop != RTW89_SUB_ENTITY_0)
-		goto out;
-
-	roll = find_next_bit(hal->entity_map, NUM_OF_RTW89_SUB_ENTITY, drop + 1);
-
-	/* Follow rtw89_config_default_chandef() when rtw89_entity_recalc(). */
-	if (roll == NUM_OF_RTW89_SUB_ENTITY)
-		goto out;
-
-	/* RTW89_SUB_ENTITY_0 is going to release, and another exists.
-	 * Make another roll down to RTW89_SUB_ENTITY_0 to replace.
-	 */
-	rtw89_swap_sub_entity(rtwdev, RTW89_SUB_ENTITY_0, roll);
-	drop = roll;
 
-out:
-	mode = rtw89_get_entity_mode(rtwdev);
-	switch (mode) {
-	case RTW89_ENTITY_MODE_MCC:
-		rtw89_mcc_stop(rtwdev);
-		break;
-	default:
-		break;
-	}
-
-	clear_bit(drop, hal->entity_map);
-	rtw89_set_channel(rtwdev);
+	clear_bit(cfg->idx, hal->entity_map);
 }
 
 void rtw89_chanctx_ops_change(struct rtw89_dev *rtwdev,
@@ -2045,7 +2015,8 @@ int rtw89_chanctx_ops_assign_vif(struct rtw89_dev *rtwdev,
 	rtwvif->sub_entity_idx = cfg->idx;
 	rtwvif->chanctx_assigned = true;
 	cfg->ref_count++;
-	return 0;
+
+	return rtw89_set_channel(rtwdev);
 }
 
 void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev *rtwdev,
@@ -2053,8 +2024,48 @@ void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev *rtwdev,
 				    struct ieee80211_chanctx_conf *ctx)
 {
 	struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv;
+	struct rtw89_hal *hal = &rtwdev->hal;
+	struct rtw89_entity_weight w = {};
+	enum rtw89_sub_entity_idx roll;
+	enum rtw89_entity_mode cur;
 
 	rtwvif->sub_entity_idx = RTW89_SUB_ENTITY_0;
 	rtwvif->chanctx_assigned = false;
 	cfg->ref_count--;
+
+	if (cfg->ref_count != 0)
+		goto out;
+
+	if (cfg->idx != RTW89_SUB_ENTITY_0)
+		goto out;
+
+	roll = find_next_bit(hal->entity_map, NUM_OF_RTW89_SUB_ENTITY,
+			     cfg->idx + 1);
+	/* Follow rtw89_config_default_chandef() when rtw89_entity_recalc(). */
+	if (roll == NUM_OF_RTW89_SUB_ENTITY)
+		goto out;
+
+	/* RTW89_SUB_ENTITY_0 is going to release, and another exists.
+	 * Make another roll down to RTW89_SUB_ENTITY_0 to replace.
+	 */
+	rtw89_swap_sub_entity(rtwdev, cfg->idx, roll);
+
+out:
+	rtw89_entity_calculate_weight(rtwdev, &w);
+
+	cur = rtw89_get_entity_mode(rtwdev);
+	switch (cur) {
+	case RTW89_ENTITY_MODE_MCC:
+		/* If still multi-roles, re-plan MCC for chanctx changes.
+		 * Otherwise, just stop MCC.
+		 */
+		rtw89_mcc_stop(rtwdev);
+		if (w.active_roles == NUM_OF_RTW89_MCC_ROLES)
+			rtw89_mcc_start(rtwdev);
+		break;
+	default:
+		break;
+	}
+
+	rtw89_set_channel(rtwdev);
 }
diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index de4c37c48f4e..1da01514f171 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -372,7 +372,7 @@ void rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev)
 	chip->ops->set_txpwr(rtwdev, chan, phy_idx);
 }
 
-void rtw89_set_channel(struct rtw89_dev *rtwdev)
+int rtw89_set_channel(struct rtw89_dev *rtwdev)
 {
 	struct rtw89_hal *hal = &rtwdev->hal;
 	const struct rtw89_chip_info *chip = rtwdev->chip;
@@ -399,7 +399,7 @@ void rtw89_set_channel(struct rtw89_dev *rtwdev)
 		break;
 	default:
 		WARN(1, "Invalid ent mode: %d\n", mode);
-		return;
+		return -EINVAL;
 	}
 
 	roc_idx = atomic_read(&hal->roc_entity_idx);
@@ -426,6 +426,7 @@ void rtw89_set_channel(struct rtw89_dev *rtwdev)
 	}
 
 	rtw89_set_entity_state(rtwdev, true);
+	return 0;
 }
 
 void rtw89_get_channel(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index ba2b298c4a9b..c20d21f5b0a6 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -5987,7 +5987,7 @@ void rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev);
 void rtw89_get_default_chandef(struct cfg80211_chan_def *chandef);
 void rtw89_get_channel_params(const struct cfg80211_chan_def *chandef,
 			      struct rtw89_chan *chan);
-void rtw89_set_channel(struct rtw89_dev *rtwdev);
+int rtw89_set_channel(struct rtw89_dev *rtwdev);
 void rtw89_get_channel(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
 		       struct rtw89_chan *chan);
 u8 rtw89_core_acquire_bit_map(unsigned long *addr, unsigned long size);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 6/6] wifi: rtw89: chan: MCC take reconfig into account
  2024-02-06  3:06 [PATCH 0/6] wifi: rtw89: adjust channel context stuffs for MCC and MLO Ping-Ke Shih
                   ` (4 preceding siblings ...)
  2024-02-06  3:06 ` [PATCH 5/6] wifi: rtw89: chan: move handling from add/remove to assign/unassign for MLO Ping-Ke Shih
@ 2024-02-06  3:06 ` Ping-Ke Shih
  5 siblings, 0 replies; 8+ messages in thread
From: Ping-Ke Shih @ 2024-02-06  3:06 UTC (permalink / raw)
  To: kvalo; +Cc: kevin_yang, linux-wireless

From: Zong-Zhe Yang <kevin_yang@realtek.com>

During mac80211 reconfig, chanctx ops of multiple channels might not
be called in order as normal cases. However, we expect the first active
chanctx always to be put at our sub entity index 0. So, if it does not,
we do a swap there. Besides, reconfig won't allocate a new chanctx object.
So, we should reset the reference count when ops add chanctx.

Signed-off-by: Zong-Zhe Yang <kevin_yang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw89/chan.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtw89/chan.c b/drivers/net/wireless/realtek/rtw89/chan.c
index 71fe0d3ab3b0..7b9baf4db70f 100644
--- a/drivers/net/wireless/realtek/rtw89/chan.c
+++ b/drivers/net/wireless/realtek/rtw89/chan.c
@@ -1980,6 +1980,7 @@ int rtw89_chanctx_ops_add(struct rtw89_dev *rtwdev,
 
 	rtw89_config_entity_chandef(rtwdev, idx, &ctx->def);
 	cfg->idx = idx;
+	cfg->ref_count = 0;
 	hal->sub[idx].cfg = cfg;
 	return 0;
 }
@@ -2011,11 +2012,23 @@ int rtw89_chanctx_ops_assign_vif(struct rtw89_dev *rtwdev,
 				 struct ieee80211_chanctx_conf *ctx)
 {
 	struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv;
+	struct rtw89_entity_weight w = {};
 
 	rtwvif->sub_entity_idx = cfg->idx;
 	rtwvif->chanctx_assigned = true;
 	cfg->ref_count++;
 
+	if (cfg->idx == RTW89_SUB_ENTITY_0)
+		goto out;
+
+	rtw89_entity_calculate_weight(rtwdev, &w);
+	if (w.active_chanctxs != 1)
+		goto out;
+
+	/* put the first active chanctx at RTW89_SUB_ENTITY_0 */
+	rtw89_swap_sub_entity(rtwdev, cfg->idx, RTW89_SUB_ENTITY_0);
+
+out:
 	return rtw89_set_channel(rtwdev);
 }
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/6] wifi: rtw89: drop TIMING_BEACON_ONLY and sync beacon TSF by self
  2024-02-06  3:06 ` [PATCH 1/6] wifi: rtw89: drop TIMING_BEACON_ONLY and sync beacon TSF by self Ping-Ke Shih
@ 2024-02-12 15:37   ` Kalle Valo
  0 siblings, 0 replies; 8+ messages in thread
From: Kalle Valo @ 2024-02-12 15:37 UTC (permalink / raw)
  To: Ping-Ke Shih; +Cc: kevin_yang, linux-wireless

Ping-Ke Shih <pkshih@realtek.com> wrote:

> From: Zong-Zhe Yang <kevin_yang@realtek.com>
> 
> Some of our calculation during concurrent mode depend on last beacon
> TSF. Originally, we just set IEEE80211_HW_TIMING_BEACON_ONLY and get
> what we want from mac80211. But, IEEE80211_HW_TIMING_BEACON_ONLY will
> be restricted once we declare MLO.
> 
> Since we are about to consider the MLO stuffs, so sync beacon TSF by
> ourselves now and unset IEEE80211_HW_TIMING_BEACON_ONLY.
> 
> Signed-off-by: Zong-Zhe Yang <kevin_yang@realtek.com>
> Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>

6 patches applied to wireless-next.git, thanks.

188045a85614 wifi: rtw89: drop TIMING_BEACON_ONLY and sync beacon TSF by self
4f0beeefcce8 wifi: rtw89: chan: add sub-entity swap function to cover replacing
ab12a3bfbf77 wifi: rtw89: chan: tweak bitmap recalc ahead before MLO
d79fa0a6d8c2 wifi: rtw89: chan: tweak weight recalc ahead before MLO
1ae9fbaf22ee wifi: rtw89: chan: move handling from add/remove to assign/unassign for MLO
162bf67f74c7 wifi: rtw89: chan: MCC take reconfig into account

-- 
https://patchwork.kernel.org/project/linux-wireless/patch/20240206030624.23382-2-pkshih@realtek.com/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2024-02-12 15:37 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-02-06  3:06 [PATCH 0/6] wifi: rtw89: adjust channel context stuffs for MCC and MLO Ping-Ke Shih
2024-02-06  3:06 ` [PATCH 1/6] wifi: rtw89: drop TIMING_BEACON_ONLY and sync beacon TSF by self Ping-Ke Shih
2024-02-12 15:37   ` Kalle Valo
2024-02-06  3:06 ` [PATCH 2/6] wifi: rtw89: chan: add sub-entity swap function to cover replacing Ping-Ke Shih
2024-02-06  3:06 ` [PATCH 3/6] wifi: rtw89: chan: tweak bitmap recalc ahead before MLO Ping-Ke Shih
2024-02-06  3:06 ` [PATCH 4/6] wifi: rtw89: chan: tweak weight " Ping-Ke Shih
2024-02-06  3:06 ` [PATCH 5/6] wifi: rtw89: chan: move handling from add/remove to assign/unassign for MLO Ping-Ke Shih
2024-02-06  3:06 ` [PATCH 6/6] wifi: rtw89: chan: MCC take reconfig into account Ping-Ke Shih

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.