Browse Source

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
Hariharan Basuthkar 5 years ago
parent
commit
0056730131

+ 97 - 2
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(

+ 17 - 0
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

+ 27 - 6
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

+ 16 - 0
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

+ 13 - 0
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);