Browse Source

qcacmn: Add an API to get frequency from country,chan,opclass

Add wlan regulatory API reg_country_chan_opclass_to_freq
to calculate channel frequency given country, opclass and channel
number. The API gets channel frequency from country's operating
class table by opclass and channel number pair. If the driver
can not find the pair, then try to find the frequency (MHz) by
channel number only.

Change-Id: I6a23a53e2e53e0b7c81b36f9f5c7794e9749c734
CRs-Fixed: 2605920
Liangwei Dong 5 năm trước cách đây
mục cha
commit
54be27be16

+ 47 - 0
umac/regulatory/core/src/reg_opclass.c

@@ -652,6 +652,53 @@ uint16_t reg_chan_opclass_to_freq(uint8_t chan,
 	return 0;
 }
 
+#ifdef HOST_OPCLASS_EXT
+qdf_freq_t reg_country_chan_opclass_to_freq(struct wlan_objmgr_pdev *pdev,
+					    const uint8_t country[3],
+					    uint8_t chan, uint8_t op_class,
+					    bool strict)
+{
+	const struct reg_dmn_op_class_map_t *op_class_tbl, *op_class_tbl_org;
+	uint16_t i;
+
+	if (reg_is_6ghz_op_class(pdev, op_class))
+		op_class_tbl_org = global_op_class;
+	else
+		op_class_tbl_org =
+			reg_get_class_from_country((uint8_t *)country);
+	op_class_tbl = op_class_tbl_org;
+	while (op_class_tbl && op_class_tbl->op_class) {
+		if  (op_class_tbl->op_class == op_class) {
+			for (i = 0; (i < REG_MAX_CHANNELS_PER_OPERATING_CLASS &&
+				     op_class_tbl->channels[i]); i++) {
+				if (op_class_tbl->channels[i] == chan)
+					return op_class_tbl->start_freq +
+						(chan * FREQ_TO_CHAN_SCALE);
+			}
+		}
+		op_class_tbl++;
+	}
+	reg_debug_rl("Not found ch %d in op class %d ch list, strict %d",
+		     chan, op_class, strict);
+	if (strict)
+		return 0;
+
+	op_class_tbl = op_class_tbl_org;
+	while (op_class_tbl && op_class_tbl->op_class) {
+		for (i = 0; (i < REG_MAX_CHANNELS_PER_OPERATING_CLASS &&
+			     op_class_tbl->channels[i]); i++) {
+			if (op_class_tbl->channels[i] == chan)
+				return op_class_tbl->start_freq +
+					(chan * FREQ_TO_CHAN_SCALE);
+		}
+		op_class_tbl++;
+	}
+	reg_debug_rl("Got invalid freq 0 for ch %d", chan);
+
+	return 0;
+}
+#endif
+
 static void
 reg_get_op_class_tbl_by_chan_map(const struct
 				 reg_dmn_op_class_map_t **op_class_tbl)

+ 34 - 0
umac/regulatory/core/src/reg_opclass.h

@@ -196,6 +196,29 @@ uint16_t reg_get_op_class_width(struct wlan_objmgr_pdev *pdev,
 				uint8_t op_class,
 				bool global_tbl_lookup);
 
+#ifdef HOST_OPCLASS_EXT
+/**
+ * reg_country_chan_opclass_to_freq() - Convert channel number to frequency
+ * based on country code and op class
+ * @pdev: pdev object.
+ * @country: country code.
+ * @chan: IEEE Channel Number.
+ * @op_class: Opclass.
+ * @strict: flag to find channel from matched operating class code.
+ *
+ * Look up (channel, operating class) pair in country operating class tables
+ * and return the channel frequency.
+ * If not found and "strict" flag is false, try to get frequency (Mhz) by
+ * channel number only.
+ *
+ * Return: Channel center frequency else return 0.
+ */
+qdf_freq_t reg_country_chan_opclass_to_freq(struct wlan_objmgr_pdev *pdev,
+					    const uint8_t country[3],
+					    uint8_t chan, uint8_t op_class,
+					    bool strict);
+#endif
+
 /**
  * reg_chan_opclass_to_freq() - Convert channel number and opclass to frequency
  * @chan: IEEE Channel Number.
@@ -309,6 +332,17 @@ static inline uint16_t reg_get_op_class_width(struct wlan_objmgr_pdev *pdev,
 	return 0;
 }
 
+#ifdef HOST_OPCLASS_EXT
+static inline
+qdf_freq_t reg_country_chan_opclass_to_freq(struct wlan_objmgr_pdev *pdev,
+					    const uint8_t country[3],
+					    uint8_t chan, uint8_t op_class,
+					    bool strict)
+{
+	return 0;
+}
+#endif
+
 static inline uint16_t
 reg_chan_opclass_to_freq(uint8_t chan,
 			 uint8_t op_class,

+ 24 - 0
umac/regulatory/dispatcher/inc/wlan_reg_services_api.h

@@ -1259,6 +1259,30 @@ bool wlan_reg_is_6ghz_op_class(struct wlan_objmgr_pdev *pdev,
  */
 bool wlan_reg_is_6ghz_supported(struct wlan_objmgr_pdev *pdev);
 
+#ifdef HOST_OPCLASS_EXT
+/**
+ * wlan_reg_country_chan_opclass_to_freq() - Convert channel number to
+ * frequency based on country code and op class
+ * @pdev: pdev object.
+ * @country: country code.
+ * @chan: IEEE Channel Number.
+ * @op_class: Opclass.
+ * @strict: flag to find channel from matched operating class code.
+ *
+ * Look up (channel, operating class) pair in country operating class tables
+ * and return the channel frequency.
+ * If not found and "strict" flag is false, try to get frequency (Mhz) by
+ * channel number only.
+ *
+ * Return: Channel center frequency else return 0.
+ */
+qdf_freq_t
+wlan_reg_country_chan_opclass_to_freq(struct wlan_objmgr_pdev *pdev,
+				      const uint8_t country[3],
+				      uint8_t chan, uint8_t op_class,
+				      bool strict);
+#endif
+
 /**
  * reg_chan_opclass_to_freq() - Convert channel number and opclass to frequency
  * @chan: IEEE Channel Number.

+ 12 - 0
umac/regulatory/dispatcher/src/wlan_reg_services_api.c

@@ -1073,6 +1073,18 @@ bool wlan_reg_is_6ghz_supported(struct wlan_objmgr_pdev *pdev)
 	return reg_is_6ghz_supported(pdev);
 }
 
+#ifdef HOST_OPCLASS_EXT
+qdf_freq_t
+wlan_reg_country_chan_opclass_to_freq(struct wlan_objmgr_pdev *pdev,
+				      const uint8_t country[3],
+				      uint8_t chan, uint8_t op_class,
+				      bool strict)
+{
+	return reg_country_chan_opclass_to_freq(pdev, country, chan, op_class,
+						strict);
+}
+#endif
+
 uint16_t wlan_reg_chan_opclass_to_freq(uint8_t chan,
 				       uint8_t op_class,
 				       bool global_tbl_lookup)