From 52ccb5e6158008a5ecab8b0d8ab66b89e678a6fa Mon Sep 17 00:00:00 2001 From: Hariharan Basuthkar Date: Thu, 21 Nov 2019 10:35:23 +0530 Subject: [PATCH] qcacmn: Disable coex channels in the current_chan_list The 5G cellular RF band and wifi frequency band of UNII-1 (IEEE channels 36, 40, 44, 48) and UNII-2A band (52, 56, 60, 64) can coexist. UNII-1 and UNII-2A are represented by bits 0x1 and 0x2 respectively in this implementation. The user space command should set the bits by applying the following algorithm: 1) To disable only the UNII-1 band channels, set the value as 0x1. 2) To disable only the UNII-2A band channels, set the value as 0x2. 3) To disable both the UNII-1 and UNII-2A band channels, set the value as 0x3. 4) To restore both the UNII-1 and UNII-2A band channels, set the value as 0x0. Change-Id: I8ff747e53b079ee9e0dc762980aee0eea32b23a5 CRs-Fixed: 2571546 --- .../lmac_if/inc/wlan_lmac_if_def.h | 2 + .../lmac_if/src/wlan_lmac_if.c | 3 + .../regulatory/core/src/reg_build_chan_list.c | 130 ++++++++++++++++++ umac/regulatory/core/src/reg_priv_objs.c | 20 +++ umac/regulatory/core/src/reg_priv_objs.h | 3 + .../regulatory/core/src/reg_services_common.c | 69 ++++++++++ .../regulatory/core/src/reg_services_common.h | 13 ++ .../inc/reg_services_public_struct.h | 25 +++- .../dispatcher/inc/wlan_reg_services_api.h | 20 +++ .../dispatcher/src/wlan_reg_services_api.c | 8 ++ 10 files changed, 292 insertions(+), 1 deletion(-) diff --git a/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h b/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h index 574169824ac6..a16df17faac1 100644 --- a/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h +++ b/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h @@ -989,6 +989,8 @@ struct wlan_lmac_if_reg_rx_ops { bool dfs_enable); QDF_STATUS (*reg_modify_pdev_chan_range)(struct wlan_objmgr_pdev *pdev); + QDF_STATUS (*reg_disable_chan_coex)(struct wlan_objmgr_pdev *pdev, + uint8_t unii_5g_bitmap); bool (*reg_ignore_fw_reg_offload_ind)(struct wlan_objmgr_psoc *psoc); }; diff --git a/umac/global_umac_dispatcher/lmac_if/src/wlan_lmac_if.c b/umac/global_umac_dispatcher/lmac_if/src/wlan_lmac_if.c index 40e01e851757..d4e22dcd16c4 100644 --- a/umac/global_umac_dispatcher/lmac_if/src/wlan_lmac_if.c +++ b/umac/global_umac_dispatcher/lmac_if/src/wlan_lmac_if.c @@ -323,6 +323,9 @@ static void wlan_lmac_if_umac_reg_rx_ops_register( rx_ops->reg_rx_ops.reg_ignore_fw_reg_offload_ind = tgt_reg_ignore_fw_reg_offload_ind; + + rx_ops->reg_rx_ops.reg_disable_chan_coex = + wlan_reg_disable_chan_coex; } #ifdef CONVERGED_P2P_ENABLE diff --git a/umac/regulatory/core/src/reg_build_chan_list.c b/umac/regulatory/core/src/reg_build_chan_list.c index c2f3e72c47c7..01cac6ea4373 100644 --- a/umac/regulatory/core/src/reg_build_chan_list.c +++ b/umac/regulatory/core/src/reg_build_chan_list.c @@ -615,6 +615,134 @@ reg_modify_chan_list_for_srd_channels(struct wlan_objmgr_pdev *pdev, } #endif +#ifdef DISABLE_UNII_SHARED_BANDS +/** + * reg_is_reg_unii_band_1_set() - Check UNII bitmap + * @unii_bitmap: 5G UNII band bitmap + * + * This function checks the input bitmap to disable UNII-1 band channels. + * + * Return: Return true if UNII-1 channels need to be disabled, + * else return false. + */ +static bool reg_is_reg_unii_band_1_set(uint8_t unii_bitmap) +{ + return !!(unii_bitmap & BIT(REG_UNII_BAND_1)); +} + +/** + * reg_is_reg_unii_band_2a_set() - Check UNII bitmap + * @unii_bitmap: 5G UNII band bitmap + * + * This function checks the input bitmap to disable UNII-2A band channels. + * + * Return: Return true if UNII-2A channels need to be disabled, + * else return false. + */ +static bool reg_is_reg_unii_band_2a_set(uint8_t unii_bitmap) +{ + return !!(unii_bitmap & BIT(REG_UNII_BAND_2A)); +} + +/** + * reg_is_5g_enum() - Check if channel enum is a 5G channel enum + * @chan_enum: channel enum + * + * Return: Return true if the input channel enum is 5G, else return false. + */ +static bool reg_is_5g_enum(enum channel_enum chan_enum) +{ + return (chan_enum >= MIN_5GHZ_CHANNEL && chan_enum <= MAX_5GHZ_CHANNEL); +} + +/** + * reg_remove_unii_chan_from_chan_list() - Remove UNII band channels + * @chan_list: Pointer to current channel list + * @start_enum: starting enum value + * @end_enum: ending enum value + * + * Remove channels in a unii band based in on the input start_enum and end_enum. + * Disable the state and flags. Set disable_coex flag to true. + * + * return: void. + */ +static void +reg_remove_unii_chan_from_chan_list(struct regulatory_channel *chan_list, + enum channel_enum start_enum, + enum channel_enum end_enum) +{ + enum channel_enum chan_enum; + + if (!(reg_is_5g_enum(start_enum) && reg_is_5g_enum(end_enum))) { + reg_err_rl("start_enum or end_enum is invalid"); + return; + } + + for (chan_enum = start_enum; chan_enum <= end_enum; chan_enum++) { + chan_list[chan_enum].state = CHANNEL_STATE_DISABLE; + chan_list[chan_enum].chan_flags |= REGULATORY_CHAN_DISABLED; + } +} + +/** + * reg_modify_disable_chan_list_for_unii1_and_unii2a() - Disable UNII-1 and + * UNII2A band + * @pdev_priv_obj: Pointer to pdev private object + * + * This function disables the UNII-1 and UNII-2A band channels + * based on input unii_5g_bitmap. + * + * Return: void. + */ +static void +reg_modify_disable_chan_list_for_unii1_and_unii2a( + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) +{ + uint8_t unii_bitmap = pdev_priv_obj->unii_5g_bitmap; + struct regulatory_channel *chan_list = pdev_priv_obj->cur_chan_list; + + if (reg_is_reg_unii_band_1_set(unii_bitmap)) { + reg_remove_unii_chan_from_chan_list(chan_list, + MIN_UNII_1_BAND_CHANNEL, + MAX_UNII_1_BAND_CHANNEL); + } + + if (reg_is_reg_unii_band_2a_set(unii_bitmap)) { + reg_remove_unii_chan_from_chan_list(chan_list, + MIN_UNII_2A_BAND_CHANNEL, + MAX_UNII_2A_BAND_CHANNEL); + } +} +#else +static inline bool reg_is_reg_unii_band_1_set(uint8_t unii_bitmap) +{ + return false; +} + +static inline bool reg_is_reg_unii_band_2a_set(uint8_t unii_bitmap) +{ + return false; +} + +static inline bool reg_is_5g_enum(enum channel_enum chan_enum) +{ + return false; +} + +static inline void +reg_remove_unii_chan_from_chan_list(struct regulatory_channel *chan_list, + enum channel_enum start_enum, + enum channel_enum end_enum) +{ +} + +static inline void +reg_modify_disable_chan_list_for_unii1_and_unii2a( + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) +{ +} +#endif + void reg_compute_pdev_current_chan_list(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) { @@ -630,6 +758,8 @@ void reg_compute_pdev_current_chan_list(struct wlan_regulatory_pdev_priv_obj reg_modify_chan_list_for_band(pdev_priv_obj->cur_chan_list, pdev_priv_obj->band_capability); + reg_modify_disable_chan_list_for_unii1_and_unii2a(pdev_priv_obj); + reg_modify_chan_list_for_dfs_channels(pdev_priv_obj->cur_chan_list, pdev_priv_obj->dfs_enabled); diff --git a/umac/regulatory/core/src/reg_priv_objs.c b/umac/regulatory/core/src/reg_priv_objs.c index 81e23c36ce5e..00696f9b0518 100644 --- a/umac/regulatory/core/src/reg_priv_objs.c +++ b/umac/regulatory/core/src/reg_priv_objs.c @@ -156,6 +156,25 @@ QDF_STATUS wlan_regulatory_psoc_obj_destroyed_notification( return status; } +#ifdef DISABLE_UNII_SHARED_BANDS +/** + * reg_reset_unii_5g_bitmap() - Reset the value of unii_5g_bitmap. + * @pdev_priv_obj: pointer to wlan_regulatory_pdev_priv_obj. + * + * Return : void + */ +static void +reg_reset_unii_5g_bitmap(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) +{ + pdev_priv_obj->unii_5g_bitmap = 0x0; +} +#else +static void inline +reg_reset_unii_5g_bitmap(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) +{ +} +#endif + QDF_STATUS wlan_regulatory_pdev_obj_created_notification( struct wlan_objmgr_pdev *pdev, void *arg_list) { @@ -193,6 +212,7 @@ QDF_STATUS wlan_regulatory_pdev_obj_created_notification( pdev_priv_obj->indoor_chan_enabled = psoc_priv_obj->indoor_chan_enabled; pdev_priv_obj->en_chan_144 = true; + reg_reset_unii_5g_bitmap(pdev_priv_obj); qdf_spinlock_create(&pdev_priv_obj->reg_rules_lock); diff --git a/umac/regulatory/core/src/reg_priv_objs.h b/umac/regulatory/core/src/reg_priv_objs.h index 5d9e9bd929ab..c3d2be090fdf 100644 --- a/umac/regulatory/core/src/reg_priv_objs.h +++ b/umac/regulatory/core/src/reg_priv_objs.h @@ -156,6 +156,9 @@ struct wlan_regulatory_pdev_priv_obj { char current_country[REG_ALPHA2_LEN + 1]; uint16_t reg_dmn_pair; uint16_t ctry_code; +#ifdef DISABLE_UNII_SHARED_BANDS + uint8_t unii_5g_bitmap; +#endif enum dfs_reg dfs_region; uint32_t phybitmap; struct wlan_objmgr_pdev *pdev_ptr; diff --git a/umac/regulatory/core/src/reg_services_common.c b/umac/regulatory/core/src/reg_services_common.c index f8e23e246f24..6c5db0149961 100644 --- a/umac/regulatory/core/src/reg_services_common.c +++ b/umac/regulatory/core/src/reg_services_common.c @@ -2731,6 +2731,75 @@ QDF_STATUS reg_modify_pdev_chan_range(struct wlan_objmgr_pdev *pdev) return status; } +#ifdef DISABLE_UNII_SHARED_BANDS +/** + * reg_is_reg_unii_band_1_or_reg_unii_band_2a() - Check the input bitmap + * @unii_5g_bitmap: 5G UNII band bitmap + * + * This function checks if either REG_UNII_BAND_1 or REG_UNII_BAND_2A, + * are present in the 5G UNII band bitmap. + * + * Return: Return true if REG_UNII_BAND_1 or REG_UNII_BAND_2A, are present in + * the UNII 5g bitmap else return false. + */ +static bool +reg_is_reg_unii_band_1_or_reg_unii_band_2a(uint8_t unii_5g_bitmap) +{ + if (!unii_5g_bitmap) + return false; + + return ((unii_5g_bitmap & (BIT(REG_UNII_BAND_1) | + BIT(REG_UNII_BAND_2A))) == unii_5g_bitmap); +} + +QDF_STATUS reg_disable_chan_coex(struct wlan_objmgr_pdev *pdev, + uint8_t unii_5g_bitmap) +{ + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; + struct wlan_lmac_if_reg_tx_ops *reg_tx_ops; + struct wlan_objmgr_psoc *psoc; + + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) { + reg_err("psoc is NULL"); + return QDF_STATUS_E_INVAL; + } + + pdev_priv_obj = reg_get_pdev_obj(pdev); + + if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { + reg_err_rl("reg pdev priv obj is NULL"); + return QDF_STATUS_E_FAILURE; + } + + if (unii_5g_bitmap && + !reg_is_reg_unii_band_1_or_reg_unii_band_2a(unii_5g_bitmap)) { + reg_err_rl("Invalid unii_5g_bitmap = %d", unii_5g_bitmap); + return QDF_STATUS_E_FAILURE; + } + + if (pdev_priv_obj->unii_5g_bitmap == unii_5g_bitmap) { + reg_debug_rl("UNII bitmask for 5G channels is already set %d", + unii_5g_bitmap); + return QDF_STATUS_SUCCESS; + } + + reg_debug_rl("Setting UNII bitmask for 5G: %d", unii_5g_bitmap); + pdev_priv_obj->unii_5g_bitmap = unii_5g_bitmap; + + reg_compute_pdev_current_chan_list(pdev_priv_obj); + + reg_tx_ops = reg_get_psoc_tx_ops(psoc); + + if (reg_tx_ops->fill_umac_legacy_chanlist) { + reg_tx_ops->fill_umac_legacy_chanlist(pdev, + pdev_priv_obj->cur_chan_list); + } + + return QDF_STATUS_SUCCESS; +} +#endif + #ifdef CONFIG_CHAN_FREQ_API QDF_STATUS reg_get_channel_list_with_power_for_freq(struct wlan_objmgr_pdev *pdev, diff --git a/umac/regulatory/core/src/reg_services_common.h b/umac/regulatory/core/src/reg_services_common.h index 9e1cba45cba4..43d70c084df8 100644 --- a/umac/regulatory/core/src/reg_services_common.h +++ b/umac/regulatory/core/src/reg_services_common.h @@ -734,6 +734,19 @@ bool reg_is_regdmn_en302502_applicable(struct wlan_objmgr_pdev *pdev); */ QDF_STATUS reg_modify_pdev_chan_range(struct wlan_objmgr_pdev *pdev); +#ifdef DISABLE_UNII_SHARED_BANDS +/** + * reg_disable_chan_coex() - Disable Coexisting channels based on the input + * bitmask. + * @pdev: pointer to wlan_objmgr_pdev. + * unii_5g_bitmap: UNII 5G bitmap. + * + * Return : QDF_STATUS + */ +QDF_STATUS reg_disable_chan_coex(struct wlan_objmgr_pdev *pdev, + uint8_t unii_5g_bitmap); +#endif + #ifdef CONFIG_CHAN_FREQ_API /** * reg_get_chan_enum_for_freq() - Get channel enum for given channel frequency diff --git a/umac/regulatory/dispatcher/inc/reg_services_public_struct.h b/umac/regulatory/dispatcher/inc/reg_services_public_struct.h index b3966d8152f4..6fb14b8df25a 100644 --- a/umac/regulatory/dispatcher/inc/reg_services_public_struct.h +++ b/umac/regulatory/dispatcher/inc/reg_services_public_struct.h @@ -435,6 +435,18 @@ enum channel_enum { INVALID_CHANNEL = 0xBAD, +#ifdef DISABLE_UNII_SHARED_BANDS + MIN_UNII_1_BAND_CHANNEL = CHAN_ENUM_5180, + MAX_UNII_1_BAND_CHANNEL = CHAN_ENUM_5240, + NUM_UNII_1_BAND_CHANNELS = (MAX_UNII_1_BAND_CHANNEL - + MIN_UNII_1_BAND_CHANNEL + 1), + + MIN_UNII_2A_BAND_CHANNEL = CHAN_ENUM_5260, + MAX_UNII_2A_BAND_CHANNEL = CHAN_ENUM_5320, + NUM_UNII_2A_BAND_CHANNELS = (MAX_UNII_2A_BAND_CHANNEL - + MIN_UNII_2A_BAND_CHANNEL + 1), +#endif + #ifdef CONFIG_BAND_6GHZ MIN_6GHZ_CHANNEL = CHAN_ENUM_5945, MAX_6GHZ_CHANNEL = CHAN_ENUM_7105, @@ -659,7 +671,6 @@ struct regulatory_channel { bool nol_history; }; - /** * struct regulatory: regulatory information * @reg_domain: regulatory domain pair @@ -833,6 +844,18 @@ enum reg_wifi_band { REG_BAND_UNKNOWN }; +#ifdef DISABLE_UNII_SHARED_BANDS +/** + * enum reg_unii_band + * @REG_UNII_BAND_1: Disable UNII-1 band channels + * @REG_UNII_BAND_2A: Disable UNII-2A band channels + */ +enum reg_unii_band { + REG_UNII_BAND_1 = 0x0, + REG_UNII_BAND_2A = 0x1, +}; +#endif + #define REG_BAND_MASK_ALL (BIT(REG_BAND_2G) | BIT(REG_BAND_5G) \ | BIT(REG_BAND_6G)) diff --git a/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h b/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h index 7f393e91a9a8..a413551e92bb 100644 --- a/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h +++ b/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h @@ -894,6 +894,26 @@ bool wlan_reg_is_regdmn_en302502_applicable(struct wlan_objmgr_pdev *pdev); */ QDF_STATUS wlan_reg_modify_pdev_chan_range(struct wlan_objmgr_pdev *pdev); +/** + * wlan_reg_disable_chan_coex() - Disable Coexisting channels based on the input + * bitmask + * @pdev: pointer to wlan_objmgr_pdev. + * unii_5g_bitmap: UNII 5G bitmap. + * + * Return : QDF_STATUS + */ +#ifdef DISABLE_UNII_SHARED_BANDS +QDF_STATUS wlan_reg_disable_chan_coex(struct wlan_objmgr_pdev *pdev, + uint8_t unii_5g_bitmap); +#else +static inline QDF_STATUS +wlan_reg_disable_chan_coex(struct wlan_objmgr_pdev *pdev, + uint8_t unii_5g_bitmap) +{ + return QDF_STATUS_SUCCESS; +} +#endif + #ifdef CONFIG_CHAN_FREQ_API /** * wlan_reg_is_same_band_freqs() - Check if two channel frequencies diff --git a/umac/regulatory/dispatcher/src/wlan_reg_services_api.c b/umac/regulatory/dispatcher/src/wlan_reg_services_api.c index 0406a1a98be0..d21a43296f36 100644 --- a/umac/regulatory/dispatcher/src/wlan_reg_services_api.c +++ b/umac/regulatory/dispatcher/src/wlan_reg_services_api.c @@ -833,6 +833,14 @@ QDF_STATUS wlan_reg_modify_pdev_chan_range(struct wlan_objmgr_pdev *pdev) return reg_modify_pdev_chan_range(pdev); } +#ifdef DISABLE_UNII_SHARED_BANDS +QDF_STATUS wlan_reg_disable_chan_coex(struct wlan_objmgr_pdev *pdev, + uint8_t unii_5g_bitmap) +{ + return reg_disable_chan_coex(pdev, unii_5g_bitmap); +} +#endif + #ifdef CONFIG_CHAN_FREQ_API bool wlan_reg_is_same_band_freqs(uint16_t freq1, uint16_t freq2) {