All of lore.kernel.org
 help / color / mirror / Atom feed
From: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
To: <ath12k@lists.infradead.org>, <johannes@sipsolutions.net>
Cc: <linux-wireless@vger.kernel.org>,
	Vasanthakumar Thiagarajan <quic_vthiagar@quicinc.com>,
	Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
Subject: [PATCH 11/13] wifi: mac80211: Add multi-hardware support in the iface comb helper
Date: Thu, 28 Mar 2024 12:59:14 +0530	[thread overview]
Message-ID: <20240328072916.1164195-12-quic_periyasa@quicinc.com> (raw)
In-Reply-To: <20240328072916.1164195-1-quic_periyasa@quicinc.com>

From: Vasanthakumar Thiagarajan <quic_vthiagar@quicinc.com>

Currently, iface combination param supports single physical hardware.
To support multi physical hardware, add hardware specific checks on the
channel context creation and populate hardware specific parameters from
the channel definition for which the interface combination need to check.

Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.1.1-00188-QCAHKSWPL_SILICONZ-1

Signed-off-by: Vasanthakumar Thiagarajan <quic_vthiagar@quicinc.com>
Co-developed-by: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
Signed-off-by: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
---
 net/mac80211/chan.c        |  33 +++++--
 net/mac80211/ieee80211_i.h |   3 +-
 net/mac80211/util.c        | 194 ++++++++++++++++++++++++++++++++++---
 3 files changed, 207 insertions(+), 23 deletions(-)

diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index 08a362892d9a..0558eafa45aa 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -47,24 +47,43 @@ int ieee80211_chanctx_refcount(struct ieee80211_local *local,
 	       ieee80211_chanctx_num_reserved(local, ctx);
 }
 
-static int ieee80211_num_chanctx(struct ieee80211_local *local)
+static int ieee80211_num_chanctx(struct ieee80211_local *local,
+				 const struct cfg80211_chan_def *chandef)
 {
 	struct ieee80211_chanctx *ctx;
-	int num = 0;
+	int num = 0, hw_idx = -1, ctx_idx;
 
 	lockdep_assert_wiphy(local->hw.wiphy);
 
-	list_for_each_entry(ctx, &local->chanctx_list, list)
-		num++;
+	if (chandef && cfg80211_chandef_valid(chandef))
+		hw_idx = cfg80211_get_hw_idx_by_chan(local->hw.wiphy,
+						     chandef->chan);
+
+	if (hw_idx < 0) {
+		list_for_each_entry(ctx, &local->chanctx_list, list)
+			num++;
+	} else {
+		list_for_each_entry(ctx, &local->chanctx_list, list) {
+			ctx_idx = cfg80211_get_hw_idx_by_chan(local->hw.wiphy,
+							      ctx->conf.def.chan);
+			if (ctx_idx != hw_idx)
+				continue;
+
+			num++;
+		}
+	}
 
 	return num;
 }
 
-static bool ieee80211_can_create_new_chanctx(struct ieee80211_local *local)
+static
+bool ieee80211_can_create_new_chanctx(struct ieee80211_local *local,
+				      const struct cfg80211_chan_def *chandef)
 {
 	lockdep_assert_wiphy(local->hw.wiphy);
 
-	return ieee80211_num_chanctx(local) < ieee80211_max_num_channels(local);
+	return ieee80211_num_chanctx(local, chandef) <
+	       ieee80211_max_num_channels(local, chandef);
 }
 
 struct ieee80211_chanctx *
@@ -1029,7 +1048,7 @@ int ieee80211_link_reserve_chanctx(struct ieee80211_link_data *link,
 
 	new_ctx = ieee80211_find_reservation_chanctx(local, chanreq, mode);
 	if (!new_ctx) {
-		if (ieee80211_can_create_new_chanctx(local)) {
+		if (ieee80211_can_create_new_chanctx(local, &chanreq->oper)) {
 			new_ctx = ieee80211_new_chanctx(local, chanreq, mode);
 			if (IS_ERR(new_ctx))
 				return PTR_ERR(new_ctx);
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 202bbffec746..42f4211c622b 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -2600,7 +2600,8 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata,
 				 const struct cfg80211_chan_def *chandef,
 				 enum ieee80211_chanctx_mode chanmode,
 				 u8 radar_detect);
-int ieee80211_max_num_channels(struct ieee80211_local *local);
+int ieee80211_max_num_channels(struct ieee80211_local *local,
+			       const struct cfg80211_chan_def *chandef);
 void ieee80211_recalc_chanctx_chantype(struct ieee80211_local *local,
 				       struct ieee80211_chanctx *ctx);
 
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index b1f3b1eb053d..f8ffc8ad0cd8 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -3926,6 +3926,44 @@ static u8 ieee80211_chanctx_radar_detect(struct ieee80211_local *local,
 	return radar_detect;
 }
 
+static void
+ieee80211_get_per_hw_sdata_active_iface(struct ieee80211_sub_if_data *sdata,
+					struct iface_comb_per_hw_params *per_hw,
+					int iftype_num[NUM_NL80211_IFTYPES],
+					int *total)
+{
+	struct ieee80211_local *local = sdata->local;
+	unsigned int link_id;
+	int hw_idx;
+
+	for (link_id = 0; link_id < ARRAY_SIZE(sdata->link); link_id++) {
+		struct ieee80211_link_data *link;
+		struct ieee80211_chanctx *ctx;
+
+		link = sdata_dereference(sdata->link[link_id], sdata);
+		if (!link)
+			continue;
+
+		ctx = ieee80211_link_get_chanctx(link);
+		if (ctx &&
+		    ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED)
+			ctx = ctx->replace_ctx;
+
+		hw_idx = -1;
+		if (ctx && cfg80211_chandef_valid(&ctx->conf.def))
+			hw_idx = cfg80211_get_hw_idx_by_chan(local->hw.wiphy,
+							     ctx->conf.def.chan);
+
+		if (hw_idx >= 0)
+			per_hw[hw_idx].iftype_num[sdata->wdev.iftype]++;
+		else
+			iftype_num[sdata->wdev.iftype]++;
+
+		if (total)
+			(*total)++;
+	}
+}
+
 int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata,
 				 const struct cfg80211_chan_def *chandef,
 				 enum ieee80211_chanctx_mode chanmode,
@@ -3936,9 +3974,12 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata,
 	enum nl80211_iftype iftype = sdata->wdev.iftype;
 	struct ieee80211_chanctx *ctx;
 	int total = 1;
+	struct iface_comb_per_hw_params *per_hw __free(kfree) = NULL;
 	struct iface_combination_params params = {
 		.radar_detect = radar_detect,
 	};
+	bool is_per_hw;
+	int hchan_idx = -1;
 
 	lockdep_assert_wiphy(local->hw.wiphy);
 
@@ -3969,26 +4010,68 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata,
 		return 0;
 	}
 
-	if (chandef)
-		params.num_different_channels = 1;
+	is_per_hw = cfg80211_per_hw_iface_comb_advertised(local->hw.wiphy);
+	if (is_per_hw) {
+		per_hw = kcalloc(local->hw.wiphy->num_hw, sizeof(*per_hw),
+				 GFP_KERNEL);
+		if (!per_hw)
+			return -ENOMEM;
+
+		if (chandef && cfg80211_chandef_valid(chandef)) {
+			hchan_idx = cfg80211_get_hw_idx_by_chan(local->hw.wiphy,
+								chandef->chan);
+			if (hchan_idx < 0)
+				goto skip;
 
-	if (iftype != NL80211_IFTYPE_UNSPECIFIED)
-		params.iftype_num[iftype] = 1;
+			per_hw[hchan_idx].num_different_channels = 1;
 
+			if (iftype != NL80211_IFTYPE_UNSPECIFIED)
+				per_hw[hchan_idx].iftype_num[iftype] = 1;
+		}
+	} else {
+		if (chandef)
+			params.num_different_channels = 1;
+
+		if (iftype != NL80211_IFTYPE_UNSPECIFIED)
+			params.iftype_num[iftype] = 1;
+	}
+
+skip:
 	list_for_each_entry(ctx, &local->chanctx_list, list) {
 		if (ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED)
 			continue;
+
+		if (is_per_hw) {
+			if (WARN_ON(!cfg80211_chandef_valid(&ctx->conf.def)))
+				continue;
+
+			hchan_idx = cfg80211_get_hw_idx_by_chan(local->hw.wiphy,
+								ctx->conf.def.chan);
+			if (WARN_ON(hchan_idx < 0))
+				continue;
+		}
+
 		params.radar_detect |=
 			ieee80211_chanctx_radar_detect(local, ctx);
+
 		if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE) {
-			params.num_different_channels++;
+			if (is_per_hw)
+				per_hw[hchan_idx].num_different_channels++;
+			else
+				params.num_different_channels++;
+
 			continue;
 		}
+
 		if (chandef && chanmode == IEEE80211_CHANCTX_SHARED &&
 		    cfg80211_chandef_compatible(chandef,
 						&ctx->conf.def))
 			continue;
-		params.num_different_channels++;
+
+		if (is_per_hw)
+			per_hw[hchan_idx].num_different_channels++;
+		else
+			params.num_different_channels++;
 	}
 
 	list_for_each_entry_rcu(sdata_iter, &local->interfaces, list) {
@@ -4002,13 +4085,25 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata,
 					    wdev_iter->iftype, 0, 1))
 			continue;
 
-		params.iftype_num[wdev_iter->iftype]++;
-		total++;
+		if (is_per_hw) {
+			ieee80211_get_per_hw_sdata_active_iface(sdata_iter,
+								per_hw,
+								params.iftype_num,
+								&total);
+		} else {
+			params.iftype_num[wdev_iter->iftype]++;
+			total++;
+		}
 	}
 
 	if (total == 1 && !params.radar_detect)
 		return 0;
 
+	if (is_per_hw) {
+		params.n_per_hw = local->hw.wiphy->num_hw;
+		params.per_hw = per_hw;
+	}
+
 	return cfg80211_check_combinations(local->hw.wiphy, &params);
 }
 
@@ -4022,31 +4117,100 @@ ieee80211_iter_max_chans(const struct ieee80211_iface_combination *c,
 					  c->num_different_channels);
 }
 
-int ieee80211_max_num_channels(struct ieee80211_local *local)
+static void
+ieee80211_iter_per_hw_max_chans(const struct ieee80211_iface_combination *c,
+				int hw_chan_idx, void *data)
+{
+	u32 *max_num_diff_chans = data;
+	u32 max_supp_diff_chans = 0;
+	int i;
+
+	for (i = 0; i < c->n_hw_list; i++) {
+		const struct ieee80211_iface_per_hw *h;
+
+		h = &c->iface_hw_list[i];
+		if (hw_chan_idx != -1) {
+			if (h->hw_chans_idx == hw_chan_idx) {
+				max_supp_diff_chans = h->num_different_channels;
+				break;
+			}
+			continue;
+		}
+		max_supp_diff_chans += h->num_different_channels;
+	}
+
+	*max_num_diff_chans = max(*max_num_diff_chans, max_supp_diff_chans);
+}
+
+int ieee80211_max_num_channels(struct ieee80211_local *local,
+			       const struct cfg80211_chan_def *chandef)
 {
 	struct ieee80211_sub_if_data *sdata;
 	struct ieee80211_chanctx *ctx;
+	struct iface_comb_per_hw_params *per_hw __free(kfree) = NULL;
+	struct iface_combination_params params = {0};
+	void (*iter)(const struct ieee80211_iface_combination *c,
+		     int hw_chan_idx, void *data) = ieee80211_iter_max_chans;
 	u32 max_num_different_channels = 1;
+	bool is_per_hw;
 	int err;
-	struct iface_combination_params params = {0};
 
 	lockdep_assert_wiphy(local->hw.wiphy);
 
+	is_per_hw = cfg80211_per_hw_iface_comb_advertised(local->hw.wiphy);
+	if (is_per_hw) {
+		per_hw = kcalloc(local->hw.wiphy->num_hw,
+				 sizeof(*params.per_hw),
+				 GFP_KERNEL);
+		if (!per_hw)
+			return -ENOMEM;
+
+		params.chandef = chandef;
+		iter = ieee80211_iter_per_hw_max_chans;
+	}
+
 	list_for_each_entry(ctx, &local->chanctx_list, list) {
-		if (ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED)
+		if (ctx->replace_state ==
+		    IEEE80211_CHANCTX_WILL_BE_REPLACED)
 			continue;
 
-		params.num_different_channels++;
+		if (is_per_hw) {
+			int hw_idx;
+
+			if (WARN_ON(!cfg80211_chandef_valid(&ctx->conf.def)))
+				continue;
+
+			hw_idx = cfg80211_get_hw_idx_by_chan(local->hw.wiphy,
+							     ctx->conf.def.chan);
+			if (WARN_ON(hw_idx < 0))
+				continue;
+
+			per_hw[hw_idx].num_different_channels++;
+		} else {
+			params.num_different_channels++;
+		}
 
 		params.radar_detect |=
 			ieee80211_chanctx_radar_detect(local, ctx);
 	}
 
-	list_for_each_entry_rcu(sdata, &local->interfaces, list)
-		params.iftype_num[sdata->wdev.iftype]++;
+	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
+		if (is_per_hw && ieee80211_sdata_running(sdata))
+			ieee80211_get_per_hw_sdata_active_iface(sdata,
+								per_hw,
+								params.iftype_num,
+								NULL);
+		else
+			params.iftype_num[sdata->wdev.iftype]++;
+	}
+
+	if (is_per_hw) {
+		params.n_per_hw = local->hw.wiphy->num_hw;
+		params.per_hw = per_hw;
+	}
 
 	err = cfg80211_iter_combinations(local->hw.wiphy, &params,
-					 ieee80211_iter_max_chans,
+					 iter,
 					 &max_num_different_channels);
 	if (err < 0)
 		return err;
-- 
2.34.1


  parent reply	other threads:[~2024-03-28  7:30 UTC|newest]

Thread overview: 85+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-03-28  7:29 [PATCH 00/13] wifi: Add multi physical hardware iface combination support Karthikeyan Periyasamy
2024-03-28  7:29 ` [PATCH 01/13] wifi: cfg80211: Add provision to advertise multiple radio in one wiphy Karthikeyan Periyasamy
2024-03-28  7:46   ` Johannes Berg
2024-03-29 14:11     ` Vasanthakumar Thiagarajan
2024-03-29 14:30       ` Johannes Berg
2024-03-29 14:47         ` Ben Greear
2024-04-10  7:56           ` Johannes Berg
2024-04-10 14:37             ` Ben Greear
2024-04-10 15:42               ` Johannes Berg
2024-04-10 16:23                 ` Ben Greear
2024-04-10 16:43                   ` Jeff Johnson
2024-04-10 18:08                     ` Maxime Bizon
2024-04-11 16:26                       ` Vasanthakumar Thiagarajan
2024-04-11 16:39                         ` Maxime Bizon
2024-04-12  3:50                           ` Vasanthakumar Thiagarajan
2024-04-12  7:38                             ` Nicolas Escande
2024-04-12  8:01                               ` Vasanthakumar Thiagarajan
2024-04-12 12:00                                 ` James Dutton
2024-04-12 14:39                                   ` Vasanthakumar Thiagarajan
2024-04-10 18:01                   ` Maxime Bizon
2024-04-10 21:03                 ` Ben Greear
2024-04-12  4:11                   ` Vasanthakumar Thiagarajan
2024-04-12 14:08                     ` Ben Greear
2024-04-12 14:31                       ` Vasanthakumar Thiagarajan
2024-04-12 15:58                         ` Ben Greear
2024-04-13 15:40                           ` Ben Greear
2024-04-14 16:02                             ` Vasanthakumar Thiagarajan
2024-04-15 13:59                               ` Ben Greear
2024-04-14 15:52                           ` Vasanthakumar Thiagarajan
2024-04-15 13:53                             ` Ben Greear
2024-04-01  4:19     ` Karthikeyan Periyasamy
2024-04-10  9:08     ` Karthikeyan Periyasamy
2024-04-10  9:09       ` Johannes Berg
2024-04-10  9:15         ` Karthikeyan Periyasamy
2024-03-28  7:29 ` [PATCH 02/13] wifi: nl80211: send underlying multi-hardware channel capabilities to user space Karthikeyan Periyasamy
2024-03-28  7:49   ` Johannes Berg
2024-03-28 10:18     ` Karthikeyan Periyasamy
2024-03-28 12:01       ` Johannes Berg
2024-03-28 15:10         ` Karthikeyan Periyasamy
2024-03-28 16:09           ` Johannes Berg
2024-03-28 16:14             ` Jeff Johnson
2024-03-28 16:17               ` Jeff Johnson
2024-03-28 16:17               ` Johannes Berg
2024-03-28 16:18                 ` Johannes Berg
2024-03-28 18:49         ` Jakub Kicinski
2024-03-28 18:53           ` Johannes Berg
2024-03-28 18:57             ` Jakub Kicinski
2024-03-28 19:32               ` Johannes Berg
2024-03-29 14:21         ` Vasanthakumar Thiagarajan
2024-04-10  7:59           ` Johannes Berg
2024-04-10 16:52             ` Jeff Johnson
2024-03-28  7:29 ` [PATCH 03/13] wifi: cfg80211: Refactor the interface combination limit check Karthikeyan Periyasamy
2024-03-28  7:29 ` [PATCH 04/13] wifi: cfg80211/mac80211: extend iface comb advertisement for multi-hardware dev Karthikeyan Periyasamy
2024-03-28 13:22   ` Johannes Berg
2024-04-01  9:56     ` Karthikeyan Periyasamy
2024-03-28  7:29 ` [PATCH 05/13] wifi: nl80211: Refactor the interface combination limit check Karthikeyan Periyasamy
2024-03-28  7:29 ` [PATCH 06/13] wifi: nl80211: send iface combination to user space in multi-hardware wiphy Karthikeyan Periyasamy
2024-03-28 13:33   ` Johannes Berg
2024-03-28 16:19     ` Jeff Johnson
2024-03-29 14:34     ` Vasanthakumar Thiagarajan
2024-04-10  4:10       ` Karthikeyan Periyasamy
2024-04-10  6:59         ` Johannes Berg
2024-04-12  5:27       ` Karthikeyan Periyasamy
2024-04-12  5:45         ` Karthikeyan Periyasamy
2024-04-15 14:27         ` Johannes Berg
2024-04-15 15:57           ` Karthikeyan Periyasamy
2024-03-28  7:29 ` [PATCH 07/13] wifi: cfg80211/mac80211: Refactor iface comb iterate callback for multi-hardware dev Karthikeyan Periyasamy
2024-03-28 13:36   ` Johannes Berg
2024-03-28  7:29 ` [PATCH 08/13] wifi: cfg80211: Refactor the iface combination iteration helper function Karthikeyan Periyasamy
2024-03-28 13:43   ` Johannes Berg
2024-04-02 16:35     ` Karthikeyan Periyasamy
2024-03-28  7:29 ` [PATCH 09/13] wifi: cfg80211: Add multi-hardware iface combination support Karthikeyan Periyasamy
2024-03-28 14:16   ` Johannes Berg
2024-04-03  9:58     ` Karthikeyan Periyasamy
2024-03-28  7:29 ` [PATCH 10/13] wifi: mac80211: expose channel context helper function Karthikeyan Periyasamy
2024-03-28  7:29 ` Karthikeyan Periyasamy [this message]
2024-03-28 14:41   ` [PATCH 11/13] wifi: mac80211: Add multi-hardware support in the iface comb helper Johannes Berg
2024-03-28 16:39     ` Jeff Johnson
2024-04-23 16:01     ` Karthikeyan Periyasamy
2024-03-28  7:29 ` [PATCH 12/13] wifi: ath12k: Introduce iface combination cleanup helper Karthikeyan Periyasamy
2024-03-28  7:29 ` [PATCH 13/13] wifi: ath12k: Advertise multi hardware iface combination Karthikeyan Periyasamy
2024-03-28 23:42   ` kernel test robot
2024-05-22 14:55 ` [PATCH 00/13] wifi: Add multi physical hardware iface combination support Felix Fietkau
2024-05-23 16:41   ` Johannes Berg
2024-05-27  6:58     ` Aditya Kumar Singh

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=20240328072916.1164195-12-quic_periyasa@quicinc.com \
    --to=quic_periyasa@quicinc.com \
    --cc=ath12k@lists.infradead.org \
    --cc=johannes@sipsolutions.net \
    --cc=linux-wireless@vger.kernel.org \
    --cc=quic_vthiagar@quicinc.com \
    /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 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.