diff mbox series

[3/7] mac80211: add combined power type definition for 6 GHz

Message ID 20220704102341.5692-4-quic_adisi@quicinc.com (mailing list archive)
State Changes Requested
Delegated to: Johannes Berg
Headers show
Series cfg80211/mac80211: extend 6 GHz support for all power modes | expand

Commit Message

Aditya Kumar Singh July 4, 2022, 10:23 a.m. UTC
6 GHz regulatory domain introduces different power modes for 6 GHz AP
operation - Low Power Indoor(LPI), Standard Power(SP) and Very Low
Power(VLP). 6 GHz STAs could be operated as either Regular or
Subordinate clients. We have separate definitions of AP and client.

However, during concurrency (multi-interfaces), it would be
difficult to keep different enum containers for different interface
types in order to track its power mode.

Add new combined power type definition for 6 GHz interfaces. Also add
support to convert existing AP/Client Power type to this new combined
power type enum.

Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
---
 include/net/cfg80211.h       | 19 ++++++++++++
 include/uapi/linux/nl80211.h | 38 +++++++++++++++++++++++
 net/wireless/util.c          | 60 ++++++++++++++++++++++++++++++++++++
 3 files changed, 117 insertions(+)

Comments

Johannes Berg Sept. 6, 2022, 11:01 a.m. UTC | #1
On Mon, 2022-07-04 at 15:53 +0530, Aditya Kumar Singh wrote:
> 
> +/**
> + * enum nl80211_regulatory_power_modes - 6 GHz regulatory power
> + *					 modes
> + * @NL80211_REG_AP_LPI: Low Power Indoor (Access Point)
> + * @NL80211_REG_AP_SP: Standard Power (Access Point)
> + * @NL80211_REG_AP_VLP: Very Low Power (Access Point)
> + * @NL80211_REG_REGULAR_CLIENT_LPI: Low Power Indoor (Regular
> + *				    or Default Client)

REG_REGULAR reads a bit weird, and anyway "REG" as the prefix for
"regulatory_power_mode" is a bit strange?

Maybe use something like REG_PWR_MODE_... ?

> +++ b/net/wireless/util.c
> @@ -190,6 +190,66 @@ struct ieee80211_channel *ieee80211_get_channel_khz(struct wiphy *wiphy,
>  }
>  EXPORT_SYMBOL(ieee80211_get_channel_khz);
>  
> +enum nl80211_regulatory_power_modes
> +ieee80211_ap_reg_power_to_reg_power_mode(enum ieee80211_ap_reg_power ap_type)
> +{
> +	switch (ap_type) {
> +	case IEEE80211_REG_LPI_AP:
> +		return NL80211_REG_AP_LPI;
> +	case IEEE80211_REG_SP_AP:
> +		return NL80211_REG_AP_SP;
> +	case IEEE80211_REG_VLP_AP:
> +		return NL80211_REG_AP_VLP;
> +	default:
> +		return NL80211_REG_MAX_POWER_MODES + 1;
> +	}
> +}
> +EXPORT_SYMBOL(ieee80211_ap_reg_power_to_reg_power_mode);

What is the use of that, why export it? Same for the other function.

johannes
Aditya Kumar Singh Feb. 16, 2023, 6:39 a.m. UTC | #2
On 9/6/2022 16:31, Johannes Berg wrote:
> On Mon, 2022-07-04 at 15:53 +0530, Aditya Kumar Singh wrote:
>>
>> +/**
>> + * enum nl80211_regulatory_power_modes - 6 GHz regulatory power
>> + *					 modes
>> + * @NL80211_REG_AP_LPI: Low Power Indoor (Access Point)
>> + * @NL80211_REG_AP_SP: Standard Power (Access Point)
>> + * @NL80211_REG_AP_VLP: Very Low Power (Access Point)
>> + * @NL80211_REG_REGULAR_CLIENT_LPI: Low Power Indoor (Regular
>> + *				    or Default Client)
> 
> REG_REGULAR reads a bit weird, and anyway "REG" as the prefix for
> "regulatory_power_mode" is a bit strange?
> 
> Maybe use something like REG_PWR_MODE_... ?
Sure will use. Thanks for the suggestion.


> 
>> +++ b/net/wireless/util.c
>> @@ -190,6 +190,66 @@ struct ieee80211_channel *ieee80211_get_channel_khz(struct wiphy *wiphy,
>>   }
>>   EXPORT_SYMBOL(ieee80211_get_channel_khz);
>>   
>> +enum nl80211_regulatory_power_modes
>> +ieee80211_ap_reg_power_to_reg_power_mode(enum ieee80211_ap_reg_power ap_type)
>> +{
>> +	switch (ap_type) {
>> +	case IEEE80211_REG_LPI_AP:
>> +		return NL80211_REG_AP_LPI;
>> +	case IEEE80211_REG_SP_AP:
>> +		return NL80211_REG_AP_SP;
>> +	case IEEE80211_REG_VLP_AP:
>> +		return NL80211_REG_AP_VLP;
>> +	default:
>> +		return NL80211_REG_MAX_POWER_MODES + 1;
>> +	}
>> +}
>> +EXPORT_SYMBOL(ieee80211_ap_reg_power_to_reg_power_mode);
> 
> What is the use of that, why export it? Same for the other function.
We have two enum - one defined in ieee80211 header file having
two separate enum of AP and client power modes respectively and one in 
nl80211 header which is combined power type. At times there can be 
use-case to convert from enum in ieee80211 to nl80211. These helper
function will do that.

And in kernel layer whenever we need we can call these function. But if 
driver needs to call it, at that point we need these functions to be 
exported (called from different kernel module).

> 
> johannes
diff mbox series

Patch

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 600c080a280b..ed482b23fb9c 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -5902,6 +5902,25 @@  ieee80211_frequency_to_channel(int freq)
 struct ieee80211_channel *
 ieee80211_get_channel_khz(struct wiphy *wiphy, u32 freq);
 
+/**
+ * ieee80211_ap_reg_power_to_reg_power_mode - convert AP specific 6 GHz power
+ *				type into combined 6 GHz power type
+ * @ap_type: AP's power mode
+ * Return: Power mode as referenced in &enum nl80211_regulatory_power_modes
+ */
+enum nl80211_regulatory_power_modes
+ieee80211_ap_reg_power_to_reg_power_mode(enum ieee80211_ap_reg_power ap_type);
+
+/**
+ * ieee80211_client_reg_power_to_reg_power_mode - convert Client specific 6 GHz
+ *				power type into combined 6 GHz power type
+ * @client_type: Client's power mode
+ * @ap_type: AP's power mode to which this client is associating
+ * Return: Power mode as referenced in &enum nl80211_regulatory_power_modes
+ */
+enum nl80211_regulatory_power_modes
+ieee80211_client_reg_power_to_reg_power_mode(enum ieee80211_client_reg_power client_type,
+					     enum ieee80211_ap_reg_power ap_type);
 /**
  * ieee80211_get_channel - get channel struct from wiphy for specified frequency
  *
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 8c21136ac18c..789f73878f50 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -3970,6 +3970,44 @@  enum nl80211_band_attr {
 
 #define NL80211_BAND_ATTR_HT_CAPA NL80211_BAND_ATTR_HT_CAPA
 
+/**
+ * enum nl80211_regulatory_power_modes - 6 GHz regulatory power
+ *					 modes
+ * @NL80211_REG_AP_LPI: Low Power Indoor (Access Point)
+ * @NL80211_REG_AP_SP: Standard Power (Access Point)
+ * @NL80211_REG_AP_VLP: Very Low Power (Access Point)
+ * @NL80211_REG_REGULAR_CLIENT_LPI: Low Power Indoor (Regular
+ *				    or Default Client)
+ * @NL80211_REG_REGULAR_CLIENT_SP: Standard Power (Regular
+ *				   or Default Client)
+ * @NL80211_REG_REGULAR_CLIENT_VLP: Very Low Power (Regular
+ *				    or Default Client)
+ * @NL80211_REG_SUBORDINATE_CLIENT_LPI: Low Power Indoor
+ *					(Subordinate Client)
+ * @NL80211_REG_SUBORDINATE_CLIENT_SP: Standard Power
+ *				       (Subordinate Client)
+ * @NL80211_REG_SUBORDINATE_CLIENT_VLP: Very Low Power
+ *					(Subordinate Client)
+ * @NL80211_REG_MAX_POWER_MODES: Max supported number of power
+ *				 modes
+ * @__NL80211_REG_LAST: Internal use
+ */
+enum nl80211_regulatory_power_modes {
+	NL80211_REG_AP_LPI,
+	NL80211_REG_AP_SP,
+	NL80211_REG_AP_VLP,
+	NL80211_REG_REGULAR_CLIENT_LPI,
+	NL80211_REG_REGULAR_CLIENT_SP,
+	NL80211_REG_REGULAR_CLIENT_VLP,
+	NL80211_REG_SUBORDINATE_CLIENT_LPI,
+	NL80211_REG_SUBORDINATE_CLIENT_SP,
+	NL80211_REG_SUBORDINATE_CLIENT_VLP,
+
+	/* keep last */
+	__NL80211_REG_LAST,
+	NL80211_REG_MAX_POWER_MODES = __NL80211_REG_LAST - 1,
+};
+
 /**
  * enum nl80211_wmm_rule - regulatory wmm rule
  *
diff --git a/net/wireless/util.c b/net/wireless/util.c
index b7257862e0fe..cca0ee321a03 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -190,6 +190,66 @@  struct ieee80211_channel *ieee80211_get_channel_khz(struct wiphy *wiphy,
 }
 EXPORT_SYMBOL(ieee80211_get_channel_khz);
 
+enum nl80211_regulatory_power_modes
+ieee80211_ap_reg_power_to_reg_power_mode(enum ieee80211_ap_reg_power ap_type)
+{
+	switch (ap_type) {
+	case IEEE80211_REG_LPI_AP:
+		return NL80211_REG_AP_LPI;
+	case IEEE80211_REG_SP_AP:
+		return NL80211_REG_AP_SP;
+	case IEEE80211_REG_VLP_AP:
+		return NL80211_REG_AP_VLP;
+	default:
+		return NL80211_REG_MAX_POWER_MODES + 1;
+	}
+}
+EXPORT_SYMBOL(ieee80211_ap_reg_power_to_reg_power_mode);
+
+/* ieee80211_client_reg_power_to_reg_power_mode: Accepts the individual power type of
+ * a 6 GHz client and power type of AP to which the client is associating and returns
+ * the final combined power mode as enumerated in &enum nl80211_regulatory_power_modes.
+ *
+ * Unlike AP, for client there is no direct mapping because final power mode of
+ * operation of client is dependent upon the power type of AP.
+ * For example -
+ * If client is a Regular client and AP is Low Power Indoor then combined power mode
+ * will be Regular Low Power Indoor where as if AP is Standard Power, then it will be
+ * Regular Standard Power Mode.
+ */
+enum nl80211_regulatory_power_modes
+ieee80211_client_reg_power_to_reg_power_mode(enum ieee80211_client_reg_power client_type,
+					     enum ieee80211_ap_reg_power ap_type)
+{
+	switch (client_type) {
+	case IEEE80211_REG_DEFAULT_CLIENT:
+		switch (ap_type) {
+		case IEEE80211_REG_LPI_AP:
+			return NL80211_REG_REGULAR_CLIENT_LPI;
+		case IEEE80211_REG_SP_AP:
+			return NL80211_REG_REGULAR_CLIENT_SP;
+		case IEEE80211_REG_VLP_AP:
+			return NL80211_REG_REGULAR_CLIENT_VLP;
+		default:
+			return NL80211_REG_MAX_POWER_MODES  + 1;
+		}
+	case IEEE80211_REG_SUBORDINATE_CLIENT:
+		switch (ap_type) {
+		case IEEE80211_REG_LPI_AP:
+			return NL80211_REG_SUBORDINATE_CLIENT_LPI;
+		case IEEE80211_REG_SP_AP:
+			return NL80211_REG_SUBORDINATE_CLIENT_SP;
+		case IEEE80211_REG_VLP_AP:
+			return NL80211_REG_SUBORDINATE_CLIENT_SP;
+		default:
+			return NL80211_REG_MAX_POWER_MODES;
+		}
+	default:
+		return NL80211_REG_MAX_POWER_MODES + 1;
+	}
+}
+EXPORT_SYMBOL(ieee80211_client_reg_power_to_reg_power_mode);
+
 static void set_mandatory_flags_band(struct ieee80211_supported_band *sband)
 {
 	int i, want;