From 00567301313d784c635db1dc39110a2a2b3b008b Mon Sep 17 00:00:00 2001 From: Hariharan Basuthkar Date: Tue, 6 Aug 2019 15:04:46 +0530 Subject: [PATCH] qcacmn: Add an API to get the channel list for bands Add the API wlan_reg_get_band_channel_list, to get the channel list from the current channel list based on the input bandmask provided. The bandmask may have more than one bands as input. Change-Id: I082a5dd6a9ddb449d64d13e636f42ad58d2de16b CRs-Fixed: 2523254 --- .../regulatory/core/src/reg_services_common.c | 99 ++++++++++++++++++- .../regulatory/core/src/reg_services_common.h | 17 ++++ .../inc/reg_services_public_struct.h | 33 +++++-- .../dispatcher/inc/wlan_reg_services_api.h | 16 +++ .../dispatcher/src/wlan_reg_services_api.c | 13 +++ 5 files changed, 170 insertions(+), 8 deletions(-) diff --git a/umac/regulatory/core/src/reg_services_common.c b/umac/regulatory/core/src/reg_services_common.c index f9b5448195cb..9d35862bdc89 100644 --- a/umac/regulatory/core/src/reg_services_common.c +++ b/umac/regulatory/core/src/reg_services_common.c @@ -2226,6 +2226,28 @@ bool reg_is_5ghz_ch_freq(uint32_t freq) return REG_IS_5GHZ_FREQ(freq); } +/** + * BAND_2G_PRESENT() - Check if REG_BAND_2G is set in the band_mask + * @band_mask: Bitmask for bands + * + * Return: True if REG_BAND_2G is set in the band_mask, else false + */ +static inline bool BAND_2G_PRESENT(uint8_t band_mask) +{ + return !!(band_mask & (BIT(REG_BAND_2G))); +} + +/** + * BAND_5G_PRESENT() - Check if REG_BAND_5G is set in the band_mask + * @band_mask: Bitmask for bands + * + * Return: True if REG_BAND_5G is set in the band_mask, else false + */ +static inline bool BAND_5G_PRESENT(uint8_t band_mask) +{ + return !!(band_mask & (BIT(REG_BAND_5G))); +} + #ifdef CONFIG_BAND_6GHZ bool reg_is_6ghz_chan_freq(uint16_t freq) { @@ -2260,7 +2282,79 @@ bool reg_is_6ghz_psc_chan_freq(uint16_t freq) return false; } -#endif + +/** + * BAND_6G_PRESENT() - Check if REG_BAND_6G is set in the band_mask + * @band_mask: Bitmask for bands + * + * Return: True if REG_BAND_6G is set in the band_mask, else false + */ +static inline bool BAND_6G_PRESENT(uint8_t band_mask) +{ + return !!(band_mask & (BIT(REG_BAND_6G))); +} +#else +static inline bool BAND_6G_PRESENT(uint8_t band_mask) +{ + return false; +} +#endif /* CONFIG_BAND_6GHZ */ + +uint16_t +reg_get_band_channel_list(struct wlan_objmgr_pdev *pdev, + uint8_t band_mask, + struct regulatory_channel *channel_list) +{ + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; + struct regulatory_channel *cur_chan_list; + uint16_t i, num_channels = 0; + + pdev_priv_obj = reg_get_pdev_obj(pdev); + if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { + reg_err("reg pdev priv obj is NULL"); + return 0; + } + + cur_chan_list = pdev_priv_obj->cur_chan_list; + + if (BAND_2G_PRESENT(band_mask)) { + for (i = MIN_24GHZ_CHANNEL; i <= MAX_24GHZ_CHANNEL; i++) { + if ((cur_chan_list[i].state != CHANNEL_STATE_DISABLE) && + !(cur_chan_list[i].chan_flags & + REGULATORY_CHAN_DISABLED)) { + channel_list[num_channels] = cur_chan_list[i]; + num_channels++; + } + } + } + if (BAND_5G_PRESENT(band_mask)) { + for (i = MIN_49GHZ_CHANNEL; i <= MAX_5GHZ_CHANNEL; i++) { + if ((cur_chan_list[i].state != CHANNEL_STATE_DISABLE) && + !(cur_chan_list[i].chan_flags & + REGULATORY_CHAN_DISABLED)) { + channel_list[num_channels] = cur_chan_list[i]; + num_channels++; + } + } + } + if (BAND_6G_PRESENT(band_mask)) { + for (i = MIN_6GHZ_CHANNEL; i <= MAX_6GHZ_CHANNEL; i++) { + if ((cur_chan_list[i].state != CHANNEL_STATE_DISABLE) && + !(cur_chan_list[i].chan_flags & + REGULATORY_CHAN_DISABLED)) { + channel_list[num_channels] = cur_chan_list[i]; + num_channels++; + } + } + } + + if (!num_channels) { + reg_err("Failed to retrieve the channel list"); + return 0; + } + + return num_channels; +} bool reg_is_49ghz_freq(uint32_t freq) { @@ -2828,7 +2922,8 @@ static void reg_set_5g_channel_params_for_freq(struct wlan_objmgr_pdev *pdev, if (ch_params->ch_width == CH_WIDTH_80P80MHZ) { chan_state2 = reg_get_5g_bonded_channel_state_for_freq( - pdev, ch_params->mhz_freq_seg1 - 10, + pdev, ch_params->mhz_freq_seg1 - + NEAREST_20MHZ_CHAN_FREQ_OFFSET, CH_WIDTH_80MHZ); chan_state = reg_combine_channel_states( diff --git a/umac/regulatory/core/src/reg_services_common.h b/umac/regulatory/core/src/reg_services_common.h index 97cadcb5d58e..29f2f33ceb71 100644 --- a/umac/regulatory/core/src/reg_services_common.h +++ b/umac/regulatory/core/src/reg_services_common.h @@ -29,6 +29,8 @@ #define IS_VALID_PSOC_REG_OBJ(psoc_priv_obj) (psoc_priv_obj) #define IS_VALID_PDEV_REG_OBJ(pdev_priv_obj) (pdev_priv_obj) #define FREQ_TO_CHAN_SCALE 5 +/* The distance between the 80Mhz center and the nearest 20Mhz channel */ +#define NEAREST_20MHZ_CHAN_FREQ_OFFSET 10 #ifdef CONFIG_CHAN_NUM_API #define REG_MIN_24GHZ_CH_NUM channel_map[MIN_24GHZ_CHANNEL].chan_num @@ -556,6 +558,21 @@ static inline uint16_t reg_max_6ghz_chan_freq(void) } #endif /* CONFIG_BAND_6GHZ */ +/** + * reg_get_band_channel_list() - Get the channel list and number of channels + * @pdev: pdev ptr + * @band_mask: Input bitmap with band set + * @channel_list: Pointer to Channel List + * + * Get the given channel list and number of channels from the current channel + * list based on input band bitmap. + * + * Return: Number of channels, else 0 to indicate error + */ +uint16_t reg_get_band_channel_list(struct wlan_objmgr_pdev *pdev, + uint8_t band_mask, + struct regulatory_channel *channel_list); + /** * reg_is_49ghz_freq() - Check if the given channel frequency is 4.9GHz * @freq: 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 1ac4e4317442..b1b193e128b5 100644 --- a/umac/regulatory/dispatcher/inc/reg_services_public_struct.h +++ b/umac/regulatory/dispatcher/inc/reg_services_public_struct.h @@ -423,17 +423,21 @@ enum channel_enum { MAX_5GHZ_CHANNEL = CHAN_ENUM_5920, NUM_5GHZ_CHANNELS = (MAX_5GHZ_CHANNEL - MIN_5GHZ_CHANNEL + 1), -#ifdef CONFIG_BAND_6GHZ - MIN_6GHZ_CHANNEL = CHAN_ENUM_5945, - MAX_6GHZ_CHANNEL = CHAN_ENUM_7105, - NUM_6GHZ_CHANNELS = (MAX_6GHZ_CHANNEL - MIN_6GHZ_CHANNEL + 1), -#endif /* CONFIG_BAND_6GHZ */ - MIN_DSRC_CHANNEL = CHAN_ENUM_5850, MAX_DSRC_CHANNEL = CHAN_ENUM_5920, NUM_DSRC_CHANNELS = (MAX_DSRC_CHANNEL - MIN_DSRC_CHANNEL + 1), INVALID_CHANNEL = 0xBAD, + +#ifdef CONFIG_BAND_6GHZ + MIN_6GHZ_CHANNEL = CHAN_ENUM_5945, + MAX_6GHZ_CHANNEL = CHAN_ENUM_7105, + NUM_6GHZ_CHANNELS = (MAX_6GHZ_CHANNEL - MIN_6GHZ_CHANNEL + 1), +#else + MIN_6GHZ_CHANNEL = INVALID_CHANNEL, + MAX_6GHZ_CHANNEL = INVALID_CHANNEL, + NUM_6GHZ_CHANNELS = 0, +#endif /* CONFIG_BAND_6GHZ */ }; /** @@ -789,6 +793,23 @@ struct reg_rule_info { struct cur_reg_rule reg_rules[MAX_REG_RULES]; }; +/** + * enum reg_wifi_band + * @REG_BAND_2G: 2G band + * @REG_BAND_5G: 5G band + * @REG_BAND_6G: 6G band + * @REG_BAND_UNKNOWN: Unsupported band + */ +enum reg_wifi_band { + REG_BAND_2G, + REG_BAND_5G, + REG_BAND_6G, + REG_BAND_UNKNOWN +}; + +/* Avoid the use of band_info as it does not support 6GHz band. Use + * reg_wifi_band, as it supports the 6GHz band + */ /** * enum band_info * @BAND_ALL:all bands diff --git a/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h b/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h index 1f29f9efaec8..537540608540 100644 --- a/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h +++ b/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h @@ -196,6 +196,22 @@ static inline uint16_t wlan_reg_max_6ghz_chan_freq(void) } #endif /* CONFIG_BAND_6GHZ */ +/** + * wlan_reg_get_band_channel_list() - Get channel list based on the band_mask + * @pdev: pdev ptr + * @band_mask: Input bitmap with band set + * @channel_list: Pointer to Channel List + * + * Get the given channel list and number of channels from the current channel + * list based on input band bitmap. + * + * Return: Number of channels, else 0 to indicate error + */ +uint16_t +wlan_reg_get_band_channel_list(struct wlan_objmgr_pdev *pdev, + uint8_t band_mask, + struct regulatory_channel *channel_list); + /** * wlan_reg_is_49ghz_freq() - Check if the given channel frequency is 4.9GHz * @freq: Channel frequency diff --git a/umac/regulatory/dispatcher/src/wlan_reg_services_api.c b/umac/regulatory/dispatcher/src/wlan_reg_services_api.c index d6c4720f2024..a12e2a5fd091 100644 --- a/umac/regulatory/dispatcher/src/wlan_reg_services_api.c +++ b/umac/regulatory/dispatcher/src/wlan_reg_services_api.c @@ -748,6 +748,19 @@ bool wlan_reg_is_6ghz_psc_chan_freq(uint16_t freq) } #endif /* CONFIG_BAND_6GHZ */ +uint16_t +wlan_reg_get_band_channel_list(struct wlan_objmgr_pdev *pdev, + uint8_t band_mask, + struct regulatory_channel *channel_list) +{ + if (!pdev) { + reg_err("pdev object is NULL"); + return 0; + } + + return reg_get_band_channel_list(pdev, band_mask, channel_list); +} + bool wlan_reg_is_49ghz_freq(uint32_t freq) { return reg_is_49ghz_freq(freq);