From cad70ccae29bc77c13c432b74b392a1fd44c6652 Mon Sep 17 00:00:00 2001 From: Hariharan Basuthkar Date: Wed, 12 Aug 2020 19:04:18 +0530 Subject: [PATCH] qcacmn: Add an API to get max TxPower for 6G TPE Add an API wlan_reg_get_max_txpower_for_6g_tpe, to get the max tx-power in PSD or EIRP format, based on the client type as follows: =======|=============================================== | S No. | Default Client | Subordinate Client| |=======|===============================================| | EIRP | reg_get_channel_reg_power | 24 dBm | | | _for_freq(pdev, freq) | | |-------------------------------------------------------| | PSD | (-1) dBm | 5 dBm | ======================================================= Change-Id: Ic4946cd3e3f2e13469b0d5e2020e3fcda5040c2f CRs-Fixed: 2765566 --- .../regulatory/core/src/reg_services_common.c | 93 +++++++++++++++++++ .../regulatory/core/src/reg_services_common.h | 32 +++++++ .../inc/reg_services_public_struct.h | 35 ++++++- .../dispatcher/inc/wlan_reg_services_api.h | 33 +++++++ .../dispatcher/src/wlan_reg_services_api.c | 14 +++ 5 files changed, 206 insertions(+), 1 deletion(-) diff --git a/umac/regulatory/core/src/reg_services_common.c b/umac/regulatory/core/src/reg_services_common.c index eab114051b..1e6f853c7e 100644 --- a/umac/regulatory/core/src/reg_services_common.c +++ b/umac/regulatory/core/src/reg_services_common.c @@ -2626,6 +2626,99 @@ bool reg_is_6g_freq_indoor(struct wlan_objmgr_pdev *pdev, qdf_freq_t freq) return (REG_IS_6GHZ_FREQ(freq) && reg_is_freq_indoor(pdev, freq)); } +/** + * reg_get_max_psd() - Get max PSD. + * @freq: Channel frequency. + * @bw: Channel bandwidth. + * @reg_ap: Regulatory 6G AP type. + * @reg_client: Regulatory 6G client type. + * @tx_power: Pointer to tx-power. + * + * Return: Return QDF_STATUS_SUCCESS, if PSD is filled for 6G TPE IE + * else return QDF_STATUS_E_FAILURE. + */ +static QDF_STATUS reg_get_max_psd(qdf_freq_t freq, + uint16_t bw, + enum reg_6g_ap_type reg_ap, + enum reg_6g_client_type reg_client, + uint8_t *tx_power) +{ + if (reg_ap == REG_INDOOR_AP) { + switch (reg_client) { + case REG_DEFAULT_CLIENT: + *tx_power = REG_PSD_MAX_TXPOWER_FOR_DEFAULT_CLIENT; + return QDF_STATUS_SUCCESS; + case REG_SUBORDINATE_CLIENT: + *tx_power = REG_PSD_MAX_TXPOWER_FOR_SUBORDINATE_CLIENT; + return QDF_STATUS_SUCCESS; + default: + reg_err_rl("Invalid client type"); + return QDF_STATUS_E_FAILURE; + } + } + + return QDF_STATUS_E_FAILURE; +} + +/** + * reg_get_max_txpower_for_eirp() - Get max EIRP. + * @pdev: Pointer to pdev. + * @freq: Channel frequency. + * @bw: Channel bandwidth. + * @reg_ap: Regulatory 6G AP type. + * @reg_client: Regulatory client type. + * @tx_power: Pointer to tx-power. + * + * Return: Return QDF_STATUS_SUCCESS, if EIRP is filled for 6G TPE IE + * else return QDF_STATUS_E_FAILURE. + */ +static QDF_STATUS reg_get_max_eirp(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq, + uint16_t bw, + enum reg_6g_ap_type reg_ap, + enum reg_6g_client_type reg_client, + uint8_t *tx_power) +{ + if (reg_ap == REG_INDOOR_AP) { + switch (reg_client) { + case REG_DEFAULT_CLIENT: + *tx_power = reg_get_channel_reg_power_for_freq(pdev, + freq); + return QDF_STATUS_SUCCESS; + case REG_SUBORDINATE_CLIENT: + *tx_power = REG_EIRP_MAX_TXPOWER_FOR_SUBORDINATE_CLIENT; + return QDF_STATUS_SUCCESS; + default: + reg_err_rl("Invalid client type"); + return QDF_STATUS_E_FAILURE; + } + } + + return QDF_STATUS_E_FAILURE; +} + +QDF_STATUS reg_get_max_txpower_for_6g_tpe(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq, uint8_t bw, + enum reg_6g_ap_type reg_ap, + enum reg_6g_client_type reg_client, + bool is_psd, + uint8_t *tx_power) +{ + if (!REG_IS_6GHZ_FREQ(freq)) { + reg_err_rl("%d is not a 6G channel frequency", freq); + return QDF_STATUS_E_FAILURE; + } + + /* + * For now, there is support only for Indoor AP and we have only + * LPI power values. + */ + if (is_psd) + return reg_get_max_psd(freq, bw, reg_ap, reg_client, tx_power); + + return reg_get_max_eirp(pdev, freq, bw, reg_ap, reg_client, tx_power); +} + /** * BAND_6G_PRESENT() - Check if REG_BAND_6G is set in the band_mask * @band_mask: Bitmask for bands diff --git a/umac/regulatory/core/src/reg_services_common.h b/umac/regulatory/core/src/reg_services_common.h index 1f7b2649dd..71e8fcf422 100644 --- a/umac/regulatory/core/src/reg_services_common.h +++ b/umac/regulatory/core/src/reg_services_common.h @@ -647,6 +647,27 @@ bool reg_is_6ghz_psc_chan_freq(uint16_t freq); */ bool reg_is_6g_freq_indoor(struct wlan_objmgr_pdev *pdev, qdf_freq_t freq); +/** + * reg_get_max_txpower_for_6g_tpe() - Get max txpower for 6G TPE IE. + * @pdev: Pointer to pdev. + * @freq: Channel frequency. + * @bw: Channel bandwidth. + * @reg_ap: Regulatory 6G AP type. + * @reg_client: Regulatory 6G client type. + * @is_psd: True if txpower is needed in PSD format, and false if needed in EIRP + * format. + * @tx_power: Pointer to tx-power. + * + * Return: Return QDF_STATUS_SUCCESS, if tx_power is filled for 6G TPE IE + * else return QDF_STATUS_E_FAILURE. + */ +QDF_STATUS reg_get_max_txpower_for_6g_tpe(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq, uint8_t bw, + enum reg_6g_ap_type reg_ap, + enum reg_6g_client_type reg_client, + bool is_psd, + uint8_t *tx_power); + /** * reg_min_6ghz_chan_freq() - Get minimum 6GHz channel center frequency * @@ -672,6 +693,17 @@ reg_is_6g_freq_indoor(struct wlan_objmgr_pdev *pdev, qdf_freq_t freq) return false; } +static inline QDF_STATUS +reg_get_max_txpower_for_6g_tpe(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq, uint8_t bw, + enum reg_6g_ap_type reg_ap, + enum reg_6g_client_type reg_client, + bool is_psd, + uint8_t *tx_power) +{ + return QDF_STATUS_E_FAILURE; +} + #ifdef CONFIG_6G_FREQ_OVERLAP static inline bool reg_is_range_overlap_6g(qdf_freq_t low_freq, qdf_freq_t high_freq) diff --git a/umac/regulatory/dispatcher/inc/reg_services_public_struct.h b/umac/regulatory/dispatcher/inc/reg_services_public_struct.h index 1eafc26aea..7a942a405b 100644 --- a/umac/regulatory/dispatcher/inc/reg_services_public_struct.h +++ b/umac/regulatory/dispatcher/inc/reg_services_public_struct.h @@ -27,7 +27,14 @@ #define REG_SBS_SEPARATION_THRESHOLD 100 #ifdef CONFIG_BAND_6GHZ -#define REG_MAX_CHANNELS_PER_OPERATING_CLASS 70 +#define REG_MAX_CHANNELS_PER_OPERATING_CLASS 70 +/* + * These tx-power macros are present till the 6G regdomains are defined to + * support tx-power values for various client types. + */ +#define REG_PSD_MAX_TXPOWER_FOR_DEFAULT_CLIENT (-1) /* dBm */ +#define REG_PSD_MAX_TXPOWER_FOR_SUBORDINATE_CLIENT 5 /* dBm */ +#define REG_EIRP_MAX_TXPOWER_FOR_SUBORDINATE_CLIENT 24 /* dBm */ #else #define REG_MAX_CHANNELS_PER_OPERATING_CLASS 25 #endif @@ -515,6 +522,32 @@ enum channel_state { CHANNEL_STATE_INVALID, }; +/** + * enum reg_6g_ap_type - Regulatory AP type for regulatory info subfield. + * @REG_INDOOR_AP: Indoor AP + * @REG_STANDARD_POWER_AP: Standard Power AP + * @REG_MAX_AP_TYPE: Maximum value possible for (3 bits) regulatory info + * sub-field in the 6G HE Operation IE + */ +enum reg_6g_ap_type { + REG_INDOOR_AP = 0, + REG_STANDARD_POWER_AP = 1, + REG_MAX_AP_TYPE = 7, +}; + +/** + * enum reg_6g_client_type - Regulatory client type for max tx-power category + * @REG_DEFAULT_CLIENT: Default client + * @REG_SUBORDINATE_CLIENT: Subordinate client + * @REG_MAX_CLIENT_TYPE: Maximum value possible for max tx-power category + * (2 bits) sub-field in the TPE (Transmit Power Envelope) IE + */ +enum reg_6g_client_type { + REG_DEFAULT_CLIENT = 0, + REG_SUBORDINATE_CLIENT = 1, + REG_MAX_CLIENT_TYPE = 3, +}; + /** * enum reg_domain: reg domain * @REGDOMAIN_FCC: FCC domain diff --git a/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h b/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h index a2073aae4c..6d6d8a272f 100644 --- a/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h +++ b/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h @@ -244,6 +244,28 @@ uint16_t wlan_reg_max_6ghz_chan_freq(void); wlan_reg_is_6g_freq_indoor(pdev, freq) bool wlan_reg_is_6g_freq_indoor(struct wlan_objmgr_pdev *pdev, qdf_freq_t freq); +/** + * wlan_reg_get_max_txpower_for_6g_tpe() - Get max txpower for 6G TPE IE. + * @pdev: Pointer to pdev. + * @freq: Channel frequency. + * @bw: Channel bandwidth. + * @reg_ap: Regulatory 6G AP type. + * @reg_client: Regulatory client type. + * @is_psd: True if txpower is needed in PSD format, and false if needed in EIRP + * format. + * @tx_power: Pointer to tx-power. + * + * Return: Return QDF_STATUS_SUCCESS, if tx_power is filled for 6G TPE IE + * else return QDF_STATUS_E_FAILURE. + */ +QDF_STATUS +wlan_reg_get_max_txpower_for_6g_tpe(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq, uint8_t bw, + enum reg_6g_ap_type reg_ap, + enum reg_6g_client_type reg_client, + bool is_psd, + uint8_t *tx_power); + #else #define WLAN_REG_IS_6GHZ_CHAN_FREQ(freq) (false) @@ -282,6 +304,17 @@ wlan_reg_is_6g_freq_indoor(struct wlan_objmgr_pdev *pdev, qdf_freq_t freq) { return false; } + +static inline QDF_STATUS +wlan_reg_get_max_txpower_for_6g_tpe(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq, uint8_t bw, + enum reg_6g_ap_type reg_ap, + enum reg_6g_client_type reg_client, + bool is_psd, + uint8_t *tx_power) +{ + return QDF_STATUS_E_FAILURE; +} #endif /* CONFIG_BAND_6GHZ */ /** diff --git a/umac/regulatory/dispatcher/src/wlan_reg_services_api.c b/umac/regulatory/dispatcher/src/wlan_reg_services_api.c index d9678d1eab..20c23c8cfb 100644 --- a/umac/regulatory/dispatcher/src/wlan_reg_services_api.c +++ b/umac/regulatory/dispatcher/src/wlan_reg_services_api.c @@ -836,6 +836,20 @@ bool wlan_reg_is_6g_freq_indoor(struct wlan_objmgr_pdev *pdev, qdf_freq_t freq) { return reg_is_6g_freq_indoor(pdev, freq); } + +QDF_STATUS +wlan_reg_get_max_txpower_for_6g_tpe(struct wlan_objmgr_pdev *pdev, + qdf_freq_t freq, uint8_t bw, + enum reg_6g_ap_type reg_ap, + enum reg_6g_client_type reg_client, + bool is_psd, + uint8_t *tx_power) +{ + return reg_get_max_txpower_for_6g_tpe(pdev, freq, bw, + reg_ap, + reg_client, is_psd, + tx_power); +} #endif /* CONFIG_BAND_6GHZ */ uint16_t