فهرست منبع

Merge "qca-wifi: Add a new API to check band capability"

Linux Build Service Account 4 سال پیش
والد
کامیت
8b7f1bb615

+ 87 - 8
umac/regulatory/core/reg_channel.c

@@ -26,7 +26,8 @@
 #include <wlan_objmgr_psoc_obj.h>
 #include <reg_priv_objs.h>
 #include <reg_services_common.h>
-#include <reg_channel.h>
+#include "reg_channel.h"
+#include <wlan_reg_channel_api.h>
 
 #ifdef CONFIG_HOST_FIND_CHAN
 
@@ -66,13 +67,23 @@ static inline int is_11a_supported(uint32_t wireless_modes, uint32_t phybitmap)
 		!(phybitmap & REGULATORY_PHYMODE_NO11A);
 }
 
-void reg_update_max_phymode_chwidth_for_pdev(
-		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
+void reg_update_max_phymode_chwidth_for_pdev(struct wlan_objmgr_pdev *pdev)
 {
-	uint32_t wireless_modes = pdev_priv_obj->wireless_modes;
-	uint32_t phybitmap = pdev_priv_obj->phybitmap;
+	uint32_t wireless_modes;
+	uint32_t phybitmap;
 	enum phy_ch_width max_chwidth = CH_WIDTH_20MHZ;
 	enum reg_phymode max_phymode = REG_PHYMODE_MAX;
+	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
+
+	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;
+	}
+
+	wireless_modes = pdev_priv_obj->wireless_modes;
+	phybitmap = pdev_priv_obj->phybitmap;
 
 	if (is_11ax_supported(wireless_modes, phybitmap)) {
 		max_phymode = REG_PHYMODE_11AX;
@@ -110,10 +121,18 @@ void reg_update_max_phymode_chwidth_for_pdev(
 }
 
 void reg_modify_chan_list_for_max_chwidth(
-		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
+		struct wlan_objmgr_pdev *pdev,
 		struct regulatory_channel *cur_chan_list)
 {
 	int i;
+	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
+
+	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;
+	}
 
 	for (i = 0; i < NUM_CHANNELS; i++) {
 		struct ch_params chan_params;
@@ -180,8 +199,10 @@ bool reg_is_phymode_chwidth_allowed(
 		if (pdev_priv_obj->cur_chan_list[i].center_freq != freq)
 			continue;
 
-		if (pdev_priv_obj->cur_chan_list[i].state ==
-		    CHANNEL_STATE_DISABLE)
+		if ((pdev_priv_obj->cur_chan_list[i].state ==
+		     CHANNEL_STATE_DISABLE) &&
+		    !(pdev_priv_obj->cur_chan_list[i].nol_chan) &&
+		    !(pdev_priv_obj->cur_chan_list[i].nol_history))
 			return false;
 
 		if (bw < pdev_priv_obj->cur_chan_list[i].min_bw ||
@@ -257,4 +278,62 @@ void reg_clear_allchan_blocked(struct wlan_objmgr_pdev *pdev)
 	for (i = 0; i < NUM_CHANNELS; i++)
 		cur_chan_list[i].is_chan_hop_blocked = false;
 }
+
+/*
+ * reg_is_band_found_internal - Check if a band channel is found in the
+ * current channel list.
+ *
+ * @start_idx - Start index.
+ * @end_idx - End index.
+ * @cur_chan_list - Pointer to cur_chan_list.
+ */
+static bool reg_is_band_found_internal(enum channel_enum start_idx,
+				       enum channel_enum end_idx,
+				       struct regulatory_channel *cur_chan_list)
+{
+	uint8_t i;
+
+	for (i = start_idx; i <= end_idx; i++)
+		if (!(reg_is_chan_disabled(cur_chan_list[i])))
+			return true;
+
+	return false;
+}
+
+bool reg_is_band_present(struct wlan_objmgr_pdev *pdev,
+			 enum reg_wifi_band reg_band)
+{
+	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
+	struct regulatory_channel *cur_chan_list;
+	enum channel_enum min_chan_idx, max_chan_idx;
+
+	switch (reg_band) {
+	case REG_BAND_2G:
+		min_chan_idx = MIN_24GHZ_CHANNEL;
+		max_chan_idx = MAX_24GHZ_CHANNEL;
+		break;
+	case REG_BAND_5G:
+		min_chan_idx = MIN_49GHZ_CHANNEL;
+		max_chan_idx = MAX_5GHZ_CHANNEL;
+		break;
+	case REG_BAND_6G:
+		min_chan_idx = MIN_6GHZ_CHANNEL;
+		max_chan_idx = MAX_6GHZ_CHANNEL;
+		break;
+	default:
+		return false;
+	}
+
+	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 false;
+	}
+
+	cur_chan_list = pdev_priv_obj->cur_chan_list;
+
+	return reg_is_band_found_internal(min_chan_idx, max_chan_idx,
+					  cur_chan_list);
+}
 #endif

+ 31 - 0
umac/regulatory/core/reg_channel.h

@@ -150,6 +150,22 @@ enum {
 #define WIRELESS_160_MODES   (HOST_REGDMN_MODE_11AC_VHT160 \
 			      | HOST_REGDMN_MODE_11AXA_HE160)
 
+/**
+ * REG_IS_CHAN_DISABLED() - In the regulatory channel list, a channel
+ * may be disabled by the regulatory/device or by radar. Radar is temporary
+ * and a radar disabled channel does not mean that the channel is permanently
+ * disabled. The API checks if the channel is disabled, but not due to radar.
+ * @chan - Regulatory channel object
+ *
+ * Return - True,  the channel is disabled, but not due to radar, else false.
+ */
+static bool reg_is_chan_disabled(struct regulatory_channel chan)
+{
+	return (((chan).chan_flags & REGULATORY_CHAN_DISABLED) &&
+		((chan).state == CHANNEL_STATE_DISABLE) &&
+		(!((chan).nol_chan)) && (!((chan).nol_history)));
+}
+
 /**
  * reg_is_phymode_chwidth_allowed() - Check if requested phymode is allowed
  * @pdev_priv_obj: Pointer to regulatory pdev private object.
@@ -195,6 +211,15 @@ bool reg_is_chan_blocked(struct wlan_objmgr_pdev *pdev, qdf_freq_t freq);
  */
 void reg_clear_allchan_blocked(struct wlan_objmgr_pdev *pdev);
 
+/*
+ * reg_is_band_present() - Check if input band channels are present
+ * in the regulatory current channel list.
+ * @pdev: pdev pointer.
+ * @reg_band: regulatory band.
+ *
+ */
+bool reg_is_band_present(struct wlan_objmgr_pdev *pdev,
+			 enum reg_wifi_band reg_band);
 #else
 static inline bool reg_is_phymode_chwidth_allowed(
 		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
@@ -219,6 +244,12 @@ bool reg_is_chan_blocked(struct wlan_objmgr_pdev *pdev, qdf_freq_t freq)
 static inline void reg_clear_allchan_blocked(struct wlan_objmgr_pdev *pdev)
 {
 }
+
+static inline bool
+reg_is_band_present(struct wlan_objmgr_pdev *pdev, enum reg_wifi_band reg_band)
+{
+	return false;
+}
 #endif /* CONFIG_HOST_FIND_CHAN */
 
 #endif /* __REG_CHANNEL_H_ */

+ 25 - 3
umac/regulatory/dispatcher/inc/wlan_reg_channel_api.h

@@ -29,6 +29,8 @@
 
 #ifdef CONFIG_HOST_FIND_CHAN
 
+#define WLAN_CHAN_PASSIVE       0x0000000000000200 /* Passive channel flag */
+
 #define WLAN_CHAN_DFS              0x0002  /* DFS set on primary segment */
 #define WLAN_CHAN_DFS_CFREQ2       0x0004  /* DFS set on secondary segment */
 #define WLAN_CHAN_DISALLOW_ADHOC   0x0040  /* ad-hoc is not allowed */
@@ -111,13 +113,25 @@ void wlan_reg_get_txpow_ant_gain(struct wlan_objmgr_pdev *pdev,
  * @pdev: pdev pointer.
  * @freq1: Frequency in primary segment.
  * @freq2: Frequency in secondary segment.
- * @flags: Flags to be filled.
+ * @sec_flags: Secondary flags to be filled.
+ * @pri_flags: Primary flags to be filled.
  *
  */
 void wlan_reg_get_chan_flags(struct wlan_objmgr_pdev *pdev,
 			     qdf_freq_t freq1,
 			     qdf_freq_t freq2,
-			     uint16_t *flags);
+			     uint16_t *sec_flags,
+			     uint64_t *pri_flags);
+
+/**
+ * wlan_reg_is_band_present() - Check if input band channels are present
+ * in the regulatory current channel list.
+ * @pdev: pdev pointer.
+ * @reg_band: regulatory band.
+ *
+ */
+bool wlan_reg_is_band_present(struct wlan_objmgr_pdev *pdev,
+			      enum reg_wifi_band reg_band);
 #else
 static inline
 void wlan_reg_set_chan_blocked(struct wlan_objmgr_pdev *pdev, qdf_freq_t freq)
@@ -163,9 +177,17 @@ static inline void
 wlan_reg_get_chan_flags(struct wlan_objmgr_pdev *pdev,
 			qdf_freq_t freq1,
 			qdf_freq_t freq2,
-			uint16_t *flags)
+			uint16_t *sec_flags,
+			uint64_t *pri_flags)
 {
 }
+
+static inline
+bool wlan_reg_is_band_present(struct wlan_objmgr_pdev *pdev,
+			      enum reg_wifi_band reg_band)
+{
+	return false;
+}
 #endif /* CONFIG_HOST_FIND_CHAN */
 
 #endif /* __WLAN_REG_CHANNEL_API_H */

+ 25 - 9
umac/regulatory/dispatcher/src/wlan_reg_channel_api.c

@@ -29,7 +29,7 @@
 #include <wlan_objmgr_psoc_obj.h>
 #include <reg_priv_objs.h>
 #include <reg_services_common.h>
-#include <reg_channel.h>
+#include "../../core/reg_channel.h"
 #include <wlan_reg_services_api.h>
 
 #ifdef CONFIG_HOST_FIND_CHAN
@@ -99,7 +99,8 @@ void wlan_reg_get_txpow_ant_gain(struct wlan_objmgr_pdev *pdev,
 void wlan_reg_get_chan_flags(struct wlan_objmgr_pdev *pdev,
 			     qdf_freq_t freq1,
 			     qdf_freq_t freq2,
-			     uint16_t *flags)
+			     uint16_t *sec_flags,
+			     uint64_t *pri_flags)
 {
 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
 	struct regulatory_channel *cur_chan_list;
@@ -115,21 +116,28 @@ void wlan_reg_get_chan_flags(struct wlan_objmgr_pdev *pdev,
 	cur_chan_list = pdev_priv_obj->cur_chan_list;
 
 	for (i = 0; i < NUM_CHANNELS; i++) {
-		if (cur_chan_list[i].center_freq == freq1 &&
-		    cur_chan_list[i].chan_flags & REGULATORY_CHAN_RADAR) {
-			*flags |= WLAN_CHAN_DFS;
-			*flags |= WLAN_CHAN_DISALLOW_ADHOC;
+		if (cur_chan_list[i].center_freq == freq1) {
+			if (cur_chan_list[i].chan_flags &
+			    REGULATORY_CHAN_RADAR) {
+				*sec_flags |= WLAN_CHAN_DFS;
+				*pri_flags |= WLAN_CHAN_PASSIVE;
+				*sec_flags |= WLAN_CHAN_DISALLOW_ADHOC;
+			} else if (cur_chan_list[i].chan_flags &
+				   REGULATORY_CHAN_NO_IR) {
+				/* For 2Ghz passive channels. */
+				*pri_flags |= WLAN_CHAN_PASSIVE;
+			}
 		}
 
 		if (cur_chan_list[i].center_freq == freq2 &&
 		    cur_chan_list[i].chan_flags & REGULATORY_CHAN_RADAR) {
-			*flags |= WLAN_CHAN_DFS_CFREQ2;
-			*flags |= WLAN_CHAN_DISALLOW_ADHOC;
+			*sec_flags |= WLAN_CHAN_DFS_CFREQ2;
+			*sec_flags |= WLAN_CHAN_DISALLOW_ADHOC;
 		}
 	}
 
 	if (WLAN_REG_IS_6GHZ_PSC_CHAN_FREQ(freq1))
-		*flags |= WLAN_CHAN_PSC;
+		*sec_flags |= WLAN_CHAN_PSC;
 }
 
 void wlan_reg_set_chan_blocked(struct wlan_objmgr_pdev *pdev,
@@ -148,4 +156,12 @@ void wlan_reg_clear_allchan_blocked(struct wlan_objmgr_pdev *pdev)
 {
 	 reg_clear_allchan_blocked(pdev);
 }
+
+bool wlan_reg_is_band_present(struct wlan_objmgr_pdev *pdev,
+			      enum reg_wifi_band reg_band)
+{
+	return reg_is_band_present(pdev, reg_band);
+}
+
+qdf_export_symbol(wlan_reg_is_band_present);
 #endif /* CONFIG_HOST_FIND_CHAN */