linux-wireless.vger.kernel.org archive mirror
 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 09/13] wifi: cfg80211: Add multi-hardware iface combination support
Date: Thu, 28 Mar 2024 12:59:12 +0530	[thread overview]
Message-ID: <20240328072916.1164195-10-quic_periyasa@quicinc.com> (raw)
In-Reply-To: <20240328072916.1164195-1-quic_periyasa@quicinc.com>

From: Vasanthakumar Thiagarajan <quic_vthiagar@quicinc.com>

Currently, the interface combination parameter supports a single physical
hardware configuration. To support multiple physical hardware interface
combination, add per hardware configuration parameters
(like num_different_channels, iftype_num[NUM_NL80211_IFTYPES]) and channel
definition for which the interface combination will be checked. Modify the
iface combination iterate helper function to retrieve the per hardware
parameters and validate the iface combination limits. For the per hardware
parameters, retrieve the respective hardware index from the channel
definition and pass them to the iterator callback.

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>
---
 include/net/cfg80211.h |  53 +++++++++++
 net/wireless/util.c    | 196 +++++++++++++++++++++++++++++++++++++++--
 2 files changed, 241 insertions(+), 8 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 246a8c07becf..8668b877fc3a 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1585,6 +1585,23 @@ struct cfg80211_color_change_settings {
 	u8 color;
 };
 
+/**
+ * struct iface_comb_per_hw_params - HW specific interface combinations input
+ *
+ * Used to pass per-hw interface combination parameters
+ *
+ * @num_different_channels: the number of different channels we want to use
+ *	with in the per-hw supported channels.
+ * @iftype_num: array with the number of interfaces of each interface
+ *	type. The index is the interface type as specified in &enum
+ *	nl80211_iftype.
+ */
+
+struct iface_comb_per_hw_params {
+	int num_different_channels;
+	int iftype_num[NUM_NL80211_IFTYPES];
+};
+
 /**
  * struct iface_combination_params - input parameters for interface combinations
  *
@@ -1601,12 +1618,27 @@ struct cfg80211_color_change_settings {
  * @new_beacon_int: set this to the beacon interval of a new interface
  *	that's not operating yet, if such is to be checked as part of
  *	the verification
+ * @chandef: Channel definition for which the interface combination is to be
+ *	checked, when checking during interface preparation on a new channel,
+ *	for example. This will be used when the driver advertises underlying
+ *	hw specific interface combination in a multi physical hardware device.
+ *	This will be NULL when the interface combination check is not due to
+ *	channel or the interface combination does not include per-hw
+ *	advertisement.
+ * @n_per_hw: number of Per-HW interface combinations.
+ * @per_hw: @n_per_hw of hw specific interface combinations. Per-hw channel
+ *	list index as advertised in wiphy @hw_chans is used as index
+ *	in @per_hw to maintain the interface combination of the corresponding
+ *	hw.
  */
 struct iface_combination_params {
 	int num_different_channels;
 	u8 radar_detect;
 	int iftype_num[NUM_NL80211_IFTYPES];
 	u32 new_beacon_int;
+	const struct cfg80211_chan_def *chandef;
+	u8 n_per_hw;
+	const struct iface_comb_per_hw_params *per_hw;
 };
 
 /**
@@ -9236,6 +9268,27 @@ int cfg80211_iter_combinations(struct wiphy *wiphy,
 					    int hw_chan_idx, void *data),
 			       void *data);
 
+/**
+ * cfg80211_per_hw_iface_comb_advertised - if per-hw iface combination supported
+ *
+ * @wiphy: the wiphy
+ *
+ * This function is used to check underlying per-hw interface combination is
+ * advertised by the driver.
+ */
+bool cfg80211_per_hw_iface_comb_advertised(struct wiphy *wiphy);
+
+/**
+ * cfg80211_get_hw_idx_by_chan - get the hw index by the channel
+ *
+ * @wiphy: the wiphy
+ * @chan: channel for which the supported hw index is required
+ *
+ * returns -1 in case the channel is not supported by any of the constituent hw
+ */
+int cfg80211_get_hw_idx_by_chan(struct wiphy *wiphy,
+				const struct ieee80211_channel *chan);
+
 /*
  * cfg80211_stop_iface - trigger interface disconnection
  *
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 39358b69dd36..635fd2637b73 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -2390,6 +2390,78 @@ cfg80211_validate_iface_limits(struct wiphy *wiphy,
 	return 0;
 }
 
+static const struct ieee80211_iface_per_hw *
+cfg80211_get_hw_iface_comb_by_idx(struct wiphy *wiphy,
+				  const struct ieee80211_iface_combination *c,
+				  int idx)
+{
+	int i;
+
+	for (i = 0; i < c->n_hw_list; i++)
+		if (c->iface_hw_list[i].hw_chans_idx == idx)
+			break;
+
+	if (i == c->n_hw_list)
+		return NULL;
+
+	return &c->iface_hw_list[i];
+}
+
+static int
+cfg80211_validate_iface_comb_per_hw_limits(struct wiphy *wiphy,
+					   struct iface_combination_params *params,
+					   const struct ieee80211_iface_combination *c,
+					   u16 *num_ifaces, u32 *all_iftypes)
+{
+	struct ieee80211_iface_limit *limits;
+	const struct iface_comb_per_hw_params *per_hw;
+	const struct ieee80211_iface_per_hw *per_hw_comb;
+	int i, ret = 0;
+
+	for (i = 0; i < params->n_per_hw; i++) {
+		per_hw = &params->per_hw[i];
+
+		per_hw_comb = cfg80211_get_hw_iface_comb_by_idx(wiphy, c, i);
+		if (!per_hw_comb) {
+			ret = -EINVAL;
+			goto out;
+		}
+
+		if (num_ifaces[i] > per_hw_comb->max_interfaces) {
+			ret = -EINVAL;
+			goto out;
+		}
+
+		if (per_hw->num_different_channels >
+		    per_hw_comb->num_different_channels) {
+			ret = -EINVAL;
+			goto out;
+		}
+
+		limits = kmemdup(per_hw_comb->limits,
+				 sizeof(limits[0]) * per_hw_comb->n_limits,
+				 GFP_KERNEL);
+		if (!limits) {
+			ret = -ENOMEM;
+			goto out;
+		}
+
+		ret = cfg80211_validate_iface_limits(wiphy,
+						     per_hw->iftype_num,
+						     limits,
+						     per_hw_comb->n_limits,
+						     all_iftypes);
+
+		kfree(limits);
+
+		if (ret)
+			goto out;
+	}
+
+out:
+	return ret;
+}
+
 static int
 cfg80211_validate_iface_comb_limits(struct wiphy *wiphy,
 				    struct iface_combination_params *params,
@@ -2421,6 +2493,23 @@ cfg80211_validate_iface_comb_limits(struct wiphy *wiphy,
 	return ret;
 }
 
+bool cfg80211_per_hw_iface_comb_advertised(struct wiphy *wiphy)
+{
+	int i;
+
+	for (i = 0; i < wiphy->n_iface_combinations; i++)
+		if (wiphy->iface_combinations[i].n_hw_list)
+			return true;
+
+	return false;
+}
+EXPORT_SYMBOL(cfg80211_per_hw_iface_comb_advertised);
+
+static void cfg80211_put_iface_comb_iftypes(u16 *num_ifaces)
+{
+	kfree(num_ifaces);
+}
+
 static u16 cfg80211_get_iftype_info(struct wiphy *wiphy,
 				    const int iftype_num[NUM_NL80211_IFTYPES],
 				    u32 *used_iftypes)
@@ -2438,6 +2527,69 @@ static u16 cfg80211_get_iftype_info(struct wiphy *wiphy,
 	return num_interfaces;
 }
 
+static u16*
+cfg80211_get_iface_comb_iftypes(struct wiphy *wiphy,
+				struct iface_combination_params *params,
+				u32 *used_iftypes)
+{
+	const struct iface_comb_per_hw_params *per_hw;
+	u16 *num_ifaces;
+	int i;
+	u8 num_hw;
+
+	num_hw = params->n_per_hw ? params->n_per_hw : 1;
+
+	num_ifaces = kcalloc(num_hw, sizeof(*num_ifaces), GFP_KERNEL);
+	if (!num_ifaces)
+		return NULL;
+
+	if (!params->n_per_hw) {
+		num_ifaces[0] = cfg80211_get_iftype_info(wiphy,
+							 params->iftype_num,
+							 used_iftypes);
+	} else {
+		/* account per_hw interfaces, if advertised */
+		for (i = 0; i < params->n_per_hw; i++) {
+			per_hw = &params->per_hw[i];
+			num_ifaces[i] = cfg80211_get_iftype_info(wiphy,
+								 per_hw->iftype_num,
+								 used_iftypes);
+		}
+	}
+
+	return num_ifaces;
+}
+
+static bool
+cfg80211_chan_supported_by_sub_hw(const struct ieee80211_chans_per_hw *hw_chans,
+				  const struct ieee80211_channel *chan)
+{
+	int i;
+
+	for (i = 0; i < hw_chans->n_chans; i++)
+		if (chan->center_freq == hw_chans->chans[i].center_freq)
+			return true;
+
+	return false;
+}
+
+int
+cfg80211_get_hw_idx_by_chan(struct wiphy *wiphy,
+			    const struct ieee80211_channel *chan)
+{
+	int i;
+
+	if (!chan)
+		return -1;
+
+	for (i = 0; i < wiphy->num_hw; i++)
+		if (cfg80211_chan_supported_by_sub_hw(wiphy->hw_chans[i], chan))
+			return i;
+
+	return -1;
+}
+EXPORT_SYMBOL(cfg80211_get_hw_idx_by_chan);
+
 int cfg80211_iter_combinations(struct wiphy *wiphy,
 			       struct iface_combination_params *params,
 			       void (*iter)(const struct ieee80211_iface_combination *c,
@@ -2450,8 +2602,8 @@ int cfg80211_iter_combinations(struct wiphy *wiphy,
 	int hw_chan_idx = -1;
 	u32 used_iftypes = 0;
 	u32 beacon_int_gcd;
-	u16 num_interfaces = 0;
-	bool beacon_int_different;
+	u16 *num_ifaces = NULL;
+	bool beacon_int_different, is_per_hw;
 	int ret = 0;
 
 	/*
@@ -2475,9 +2627,26 @@ int cfg80211_iter_combinations(struct wiphy *wiphy,
 		rcu_read_unlock();
 	}
 
-	num_interfaces = cfg80211_get_iftype_info(wiphy,
-						  params->iftype_num,
-						  &used_iftypes);
+	is_per_hw = cfg80211_per_hw_iface_comb_advertised(wiphy);
+	/* check per HW validation */
+	if (params->n_per_hw) {
+		if (!is_per_hw)
+			return -EINVAL;
+
+		if (params->n_per_hw > wiphy->num_hw)
+			return -EINVAL;
+	}
+
+	if (is_per_hw && params->chandef &&
+	    cfg80211_chandef_valid(params->chandef))
+		hw_chan_idx = cfg80211_get_hw_idx_by_chan(wiphy,
+							  params->chandef->chan);
+
+	num_ifaces = cfg80211_get_iface_comb_iftypes(wiphy,
+						     params,
+						     &used_iftypes);
+	if (!num_ifaces)
+		return -ENOMEM;
 
 	for (i = 0; i < wiphy->n_iface_combinations; i++) {
 		const struct ieee80211_iface_combination *c;
@@ -2485,9 +2654,18 @@ int cfg80211_iter_combinations(struct wiphy *wiphy,
 
 		c = &wiphy->iface_combinations[i];
 
-		ret = cfg80211_validate_iface_comb_limits(wiphy, params,
-							  c, num_interfaces,
-							  &all_iftypes);
+		if (params->n_per_hw)
+			ret = cfg80211_validate_iface_comb_per_hw_limits(wiphy,
+									 params,
+									 c,
+									 num_ifaces,
+									 &all_iftypes);
+		else
+			ret = cfg80211_validate_iface_comb_limits(wiphy,
+								  params,
+								  c,
+								  num_ifaces[0],
+								  &all_iftypes);
 		if (ret == -ENOMEM) {
 			break;
 		} else if (ret) {
@@ -2526,6 +2704,8 @@ int cfg80211_iter_combinations(struct wiphy *wiphy,
 		(*iter)(c, hw_chan_idx, data);
 	}
 
+	cfg80211_put_iface_comb_iftypes(num_ifaces);
+
 	return ret;
 }
 EXPORT_SYMBOL(cfg80211_iter_combinations);
-- 
2.34.1


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

Thread overview: 81+ 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-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 ` Karthikeyan Periyasamy [this message]
2024-03-28 14:16   ` [PATCH 09/13] wifi: cfg80211: Add multi-hardware iface combination support 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 ` [PATCH 11/13] wifi: mac80211: Add multi-hardware support in the iface comb helper Karthikeyan Periyasamy
2024-03-28 14:41   ` 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

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-10-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 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).