Pārlūkot izejas kodu

Merge "qca-wifi: Introduce regulatory APIs to access channel information"

Linux Build Service Account 4 gadi atpakaļ
vecāks
revīzija
2b8a916ce6

+ 197 - 0
umac/regulatory/core/reg_channel.c

@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: reg_channel.c
+ * This file defines the API to access/update/modify regulatory current channel
+ * list by WIN host umac components.
+ */
+
+#include <wlan_cmn.h>
+#include <reg_services_public_struct.h>
+#include <wlan_objmgr_psoc_obj.h>
+#include <reg_priv_objs.h>
+#include <reg_services_common.h>
+#include <reg_channel.h>
+
+#ifdef CONFIG_HOST_FIND_CHAN
+
+static inline int is_11ax_supported(uint32_t wireless_modes, uint32_t phybitmap)
+{
+	return (WIRELESS_11AX_MODES & wireless_modes) &&
+		!(phybitmap & REGULATORY_PHYMODE_NO11AX);
+}
+
+static inline int is_11ac_supported(uint32_t wireless_modes, uint32_t phybitmap)
+{
+	return (WIRELESS_11AC_MODES & wireless_modes) &&
+		!(phybitmap & REGULATORY_PHYMODE_NO11AC);
+}
+
+static inline int is_11n_supported(uint32_t wireless_modes, uint32_t phybitmap)
+{
+	return (WIRELESS_11N_MODES & wireless_modes) &&
+		!(phybitmap & REGULATORY_CHAN_NO11N);
+}
+
+static inline int is_11g_supported(uint32_t wireless_modes, uint32_t phybitmap)
+{
+	return (WIRELESS_11G_MODES & wireless_modes) &&
+		!(phybitmap & REGULATORY_PHYMODE_NO11G);
+}
+
+static inline int is_11b_supported(uint32_t wireless_modes, uint32_t phybitmap)
+{
+	return (WIRELESS_11B_MODES & wireless_modes) &&
+		!(phybitmap & REGULATORY_PHYMODE_NO11B);
+}
+
+static inline int is_11a_supported(uint32_t wireless_modes, uint32_t phybitmap)
+{
+	return (WIRELESS_11A_MODES & wireless_modes) &&
+		!(phybitmap & REGULATORY_PHYMODE_NO11A);
+}
+
+void reg_update_max_phymode_chwidth_for_pdev(
+		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
+{
+	uint32_t wireless_modes = pdev_priv_obj->wireless_modes;
+	uint32_t phybitmap = pdev_priv_obj->phybitmap;
+	enum phy_ch_width max_chwidth = CH_WIDTH_20MHZ;
+	enum reg_phymode max_phymode = REG_PHYMODE_MAX;
+
+	if (is_11ax_supported(wireless_modes, phybitmap)) {
+		max_phymode = REG_PHYMODE_11AX;
+		if (wireless_modes & WIRELESS_160_MODES)
+			max_chwidth = CH_WIDTH_160MHZ;
+		else if (wireless_modes & WIRELESS_80_MODES)
+			max_chwidth = CH_WIDTH_80MHZ;
+		else if (wireless_modes & WIRELESS_40_MODES)
+			max_chwidth = CH_WIDTH_40MHZ;
+	} else if (is_11ac_supported(wireless_modes, phybitmap)) {
+		max_phymode = REG_PHYMODE_11AC;
+		if (wireless_modes & WIRELESS_160_MODES)
+			max_chwidth = CH_WIDTH_160MHZ;
+		else if (wireless_modes & WIRELESS_80_MODES)
+			max_chwidth = CH_WIDTH_80MHZ;
+		else if (wireless_modes & WIRELESS_40_MODES)
+			max_chwidth = CH_WIDTH_40MHZ;
+	} else if (is_11n_supported(wireless_modes, phybitmap)) {
+		max_phymode = REG_PHYMODE_11N;
+		if (wireless_modes & WIRELESS_40_MODES)
+			max_chwidth = CH_WIDTH_40MHZ;
+	} else if (is_11g_supported(wireless_modes, phybitmap)) {
+		max_phymode = REG_PHYMODE_11G;
+	} else if (is_11b_supported(wireless_modes, phybitmap)) {
+		max_phymode = REG_PHYMODE_11B;
+	} else if (is_11a_supported(wireless_modes, phybitmap)) {
+		max_phymode = REG_PHYMODE_11A;
+	} else {
+		reg_err("Device does not support any wireless_mode! %0x",
+			wireless_modes);
+	}
+
+	pdev_priv_obj->max_phymode = max_phymode;
+	pdev_priv_obj->max_chwidth = max_chwidth;
+}
+
+void reg_modify_chan_list_for_max_chwidth(
+		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
+		struct regulatory_channel *cur_chan_list)
+{
+	int i;
+
+	for (i = 0; i < NUM_CHANNELS; i++) {
+		struct ch_params chan_params;
+
+		if (cur_chan_list[i].chan_flags & REGULATORY_CHAN_DISABLED)
+			continue;
+
+		chan_params.ch_width = pdev_priv_obj->max_chwidth;
+
+		/*
+		 * Correct the max bandwidths if they were not taken care of
+		 * while parsing the reg rules.
+		 */
+		reg_set_channel_params_for_freq(pdev_priv_obj->pdev_ptr,
+						cur_chan_list[i].center_freq,
+						0,
+						&chan_params);
+
+		if (chan_params.ch_width != CH_WIDTH_INVALID)
+			cur_chan_list[i].max_bw =
+				qdf_min(cur_chan_list[i].max_bw,
+					reg_get_bw_value(chan_params.ch_width));
+	}
+}
+
+static uint32_t convregphymode2wirelessmodes[REG_PHYMODE_MAX] = {
+	0xFFFFFFFF,                  /* REG_PHYMODE_INVALID */
+	WIRELESS_11B_MODES,          /* REG_PHYMODE_11B     */
+	WIRELESS_11G_MODES,          /* REG_PHYMODE_11G     */
+	WIRELESS_11A_MODES,          /* REG_PHYMODE_11A     */
+	WIRELESS_11N_MODES,          /* REG_PHYMODE_11N     */
+	WIRELESS_11AC_MODES,         /* REG_PHYMODE_11AC    */
+	WIRELESS_11AX_MODES,         /* REG_PHYMODE_11AX    */
+};
+
+static int reg_is_phymode_in_wireless_modes(enum reg_phymode phy_in,
+					    uint32_t wireless_modes)
+{
+	uint32_t sup_wireless_modes = convregphymode2wirelessmodes[phy_in];
+
+	return sup_wireless_modes & wireless_modes;
+}
+
+bool reg_is_phymode_chwidth_allowed(
+		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
+		enum reg_phymode phy_in,
+		enum phy_ch_width ch_width,
+		qdf_freq_t freq)
+{
+	uint32_t phymode_bitmap, wireless_modes;
+	uint16_t i, bw = reg_get_bw_value(ch_width);
+
+	if (ch_width == CH_WIDTH_INVALID)
+		return false;
+
+	phymode_bitmap = pdev_priv_obj->phybitmap;
+	wireless_modes = pdev_priv_obj->wireless_modes;
+
+	if (reg_is_phymode_unallowed(phy_in, phymode_bitmap) ||
+	    !reg_is_phymode_in_wireless_modes(phy_in, wireless_modes))
+		return false;
+
+	for (i = 0; i < NUM_CHANNELS; i++) {
+		if (pdev_priv_obj->cur_chan_list[i].center_freq != freq)
+			continue;
+
+		if (pdev_priv_obj->cur_chan_list[i].state ==
+		    CHANNEL_STATE_DISABLE)
+			return false;
+
+		if (bw < pdev_priv_obj->cur_chan_list[i].min_bw ||
+		    bw > pdev_priv_obj->cur_chan_list[i].max_bw)
+			return false;
+
+		return true;
+	}
+
+	return false;
+}
+
+#endif

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

@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: reg_channel.h
+ * This file provides prototypes of the channel list APIs in addition to
+ * predefined macros.
+ */
+
+#ifndef __REG_CHANNEL_H_
+#define __REG_CHANNEL_H_
+
+#ifdef CONFIG_HOST_FIND_CHAN
+
+/**
+ * enum HOST_REGDMN_MODE:
+ * @HOST_REGDMN_MODE_11A: 11a channels
+ * @HOST_REGDMN_MODE_TURBO: 11a turbo-only channels
+ * @HOST_REGDMN_MODE_11B: 11b channels
+ * @HOST_REGDMN_MODE_PUREG: 11g channels (OFDM only)
+ * @HOST_REGDMN_MODE_11G: historical
+ * @HOST_REGDMN_MODE_108G: 11g+Turbo channels
+ * @HOST_REGDMN_MODE_108A: 11a+Turbo channels
+ * @HOST_REGDMN_MODE_11AC_VHT20_2G: 2GHz, VHT20
+ * @HOST_REGDMN_MODE_XR: XR channels
+ * @HOST_REGDMN_MODE_11A_HALF_RATE: 11a half rate channels
+ * @HOST_REGDMN_MODE_11A_QUARTER_RATE: 11a quarter rate channels
+ * @HOST_REGDMN_MODE_11NG_HT20: 11ng HT20 channels
+ * @HOST_REGDMN_MODE_11NA_HT20: 11na HT20 channels
+ * @HOST_REGDMN_MODE_11NG_HT40PLUS: 11ng HT40+ channels
+ * @HOST_REGDMN_MODE_11NG_HT40MINUS: 11ng HT40- channels
+ * @HOST_REGDMN_MODE_11NA_HT40PLUS: 11na HT40+ channels
+ * @HOST_REGDMN_MODE_11NA_HT40MINUS: 11na HT40- channels
+ * @HOST_REGDMN_MODE_11AC_VHT20: 5GHz, VHT20
+ * @HOST_REGDMN_MODE_11AC_VHT40PLUS: 5GHz, VHT40+ channels
+ * @HOST_REGDMN_MODE_11AC_VHT40MINUS: 5GHz, VHT40- channels
+ * @HOST_REGDMN_MODE_11AC_VHT80: 5GHz, VHT80 channels
+ * @HOST_REGDMN_MODE_11AC_VHT160: 5GHz, VHT160 channels
+ * @HOST_REGDMN_MODE_11AC_VHT80_80: 5GHz, VHT80+80 channels
+ * @HOST_REGDMN_MODE_11AXG_HE20: 11ax 2.4GHz, HE20 channels
+ * @HOST_REGDMN_MODE_11AXA_HE20: 11ax 5GHz, HE20 channels
+ * @HOST_REGDMN_MODE_11AXG_HE40PLUS: 11ax 2.4GHz, HE40+ channels
+ * @HOST_REGDMN_MODE_11AXG_HE40MINUS: 11ax 2.4GHz, HE40- channels
+ * @HOST_REGDMN_MODE_11AXA_HE40PLUS: 11ax 5GHz, HE40+ channels
+ * @HOST_REGDMN_MODE_11AXA_HE40MINUS: 11ax 5GHz, HE40- channels
+ * @HOST_REGDMN_MODE_11AXA_HE80: 11ax 5GHz, HE80 channels
+ * @HOST_REGDMN_MODE_11AXA_HE160: 11ax 5GHz, HE160 channels
+ * @HOST_REGDMN_MODE_11AXA_HE80_80: 11ax 5GHz, HE80+80 channels
+ */
+enum {
+	HOST_REGDMN_MODE_11A = 0x00000001,
+	HOST_REGDMN_MODE_TURBO = 0x00000002,
+	HOST_REGDMN_MODE_11B = 0x00000004,
+	HOST_REGDMN_MODE_PUREG = 0x00000008,
+	HOST_REGDMN_MODE_11G = 0x00000008,
+	HOST_REGDMN_MODE_108G = 0x00000020,
+	HOST_REGDMN_MODE_108A = 0x00000040,
+	HOST_REGDMN_MODE_11AC_VHT20_2G = 0x00000080,
+	HOST_REGDMN_MODE_XR = 0x00000100,
+	HOST_REGDMN_MODE_11A_HALF_RATE = 0x00000200,
+	HOST_REGDMN_MODE_11A_QUARTER_RATE = 0x00000400,
+	HOST_REGDMN_MODE_11NG_HT20 = 0x00000800,
+	HOST_REGDMN_MODE_11NA_HT20 = 0x00001000,
+	HOST_REGDMN_MODE_11NG_HT40PLUS = 0x00002000,
+	HOST_REGDMN_MODE_11NG_HT40MINUS = 0x00004000,
+	HOST_REGDMN_MODE_11NA_HT40PLUS = 0x00008000,
+	HOST_REGDMN_MODE_11NA_HT40MINUS = 0x00010000,
+	HOST_REGDMN_MODE_11AC_VHT20 = 0x00020000,
+	HOST_REGDMN_MODE_11AC_VHT40PLUS = 0x00040000,
+	HOST_REGDMN_MODE_11AC_VHT40MINUS = 0x00080000,
+	HOST_REGDMN_MODE_11AC_VHT80 = 0x00100000,
+	HOST_REGDMN_MODE_11AC_VHT160 = 0x00200000,
+	HOST_REGDMN_MODE_11AC_VHT80_80 = 0x00400000,
+	HOST_REGDMN_MODE_11AXG_HE20 = 0x00800000,
+	HOST_REGDMN_MODE_11AXA_HE20 = 0x01000000,
+	HOST_REGDMN_MODE_11AXG_HE40PLUS = 0x02000000,
+	HOST_REGDMN_MODE_11AXG_HE40MINUS = 0x04000000,
+	HOST_REGDMN_MODE_11AXA_HE40PLUS = 0x08000000,
+	HOST_REGDMN_MODE_11AXA_HE40MINUS = 0x10000000,
+	HOST_REGDMN_MODE_11AXA_HE80 = 0x20000000,
+	HOST_REGDMN_MODE_11AXA_HE160 = 0x40000000,
+	HOST_REGDMN_MODE_11AXA_HE80_80 = 0x80000000,
+	HOST_REGDMN_MODE_ALL = 0xffffffff
+};
+
+#define WIRELESS_11AX_MODES  (HOST_REGDMN_MODE_11AXG_HE20 \
+			      | HOST_REGDMN_MODE_11AXG_HE40PLUS \
+			      | HOST_REGDMN_MODE_11AXG_HE40MINUS \
+			      | HOST_REGDMN_MODE_11AXA_HE20 \
+			      | HOST_REGDMN_MODE_11AXA_HE40PLUS \
+			      | HOST_REGDMN_MODE_11AXA_HE40MINUS \
+			      | HOST_REGDMN_MODE_11AXA_HE80 \
+			      | HOST_REGDMN_MODE_11AXA_HE160 \
+			      | HOST_REGDMN_MODE_11AXA_HE80_80)
+
+#define WIRELESS_11AC_MODES  (HOST_REGDMN_MODE_11AC_VHT20 \
+			      | HOST_REGDMN_MODE_11AC_VHT40PLUS \
+			      | HOST_REGDMN_MODE_11AC_VHT40MINUS \
+			      | HOST_REGDMN_MODE_11AC_VHT80 \
+			      | HOST_REGDMN_MODE_11AC_VHT160 \
+			      | HOST_REGDMN_MODE_11AC_VHT80_80)
+
+#define WIRELESS_11N_MODES   (HOST_REGDMN_MODE_11NG_HT20 \
+			      | HOST_REGDMN_MODE_11NA_HT20 \
+			      | HOST_REGDMN_MODE_11NG_HT40PLUS \
+			      | HOST_REGDMN_MODE_11NG_HT40MINUS \
+			      | HOST_REGDMN_MODE_11NA_HT40PLUS \
+			      | HOST_REGDMN_MODE_11NA_HT40MINUS)
+
+#define WIRELESS_11G_MODES   (HOST_REGDMN_MODE_PUREG \
+			      | HOST_REGDMN_MODE_11G \
+			      | HOST_REGDMN_MODE_108G)
+
+#define WIRELESS_11B_MODES   (HOST_REGDMN_MODE_11B)
+
+#define WIRELESS_11A_MODES   (HOST_REGDMN_MODE_11A \
+			      | HOST_REGDMN_MODE_TURBO \
+			      | HOST_REGDMN_MODE_108A \
+			      | HOST_REGDMN_MODE_11A_HALF_RATE \
+			      | HOST_REGDMN_MODE_11A_QUARTER_RATE)
+
+#define WIRELESS_40_MODES    (HOST_REGDMN_MODE_11NG_HT40PLUS \
+			      | HOST_REGDMN_MODE_11NG_HT40MINUS \
+			      | HOST_REGDMN_MODE_11NA_HT40PLUS \
+			      | HOST_REGDMN_MODE_11NA_HT40MINUS \
+			      | HOST_REGDMN_MODE_11AC_VHT40PLUS \
+			      | HOST_REGDMN_MODE_11AC_VHT40MINUS \
+			      | HOST_REGDMN_MODE_11AXG_HE40PLUS \
+			      | HOST_REGDMN_MODE_11AXG_HE40MINUS \
+			      | HOST_REGDMN_MODE_11AXA_HE40PLUS \
+			      | HOST_REGDMN_MODE_11AXA_HE40MINUS)
+
+#define WIRELESS_80_MODES    (HOST_REGDMN_MODE_11AC_VHT80 \
+			      | HOST_REGDMN_MODE_11AXA_HE80)
+
+#define WIRELESS_160_MODES   (HOST_REGDMN_MODE_11AC_VHT160 \
+			      | HOST_REGDMN_MODE_11AXA_HE160)
+
+/**
+ * reg_is_phymode_chwidth_allowed() - Check if requested phymode is allowed
+ * @pdev_priv_obj: Pointer to regulatory pdev private object.
+ * @phy_in: phymode that the user requested.
+ * @ch_width: Channel width that the user requested.
+ * @primary_freq: Input primary frequency.
+ *
+ * Return: true if phymode is allowed, else false.
+ */
+bool reg_is_phymode_chwidth_allowed(
+		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
+		enum reg_phymode phy_in,
+		enum phy_ch_width ch_width,
+		qdf_freq_t primary_freq);
+
+#else
+static inline bool reg_is_phymode_chwidth_allowed(
+		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj,
+		enum reg_phymode phy_in,
+		enum phy_ch_width ch_width,
+		qdf_freq_t primary_freq);
+{
+	return false;
+}
+
+#endif /* CONFIG_HOST_FIND_CHAN */
+
+#endif /* __REG_CHANNEL_H_ */

+ 124 - 0
umac/regulatory/dispatcher/inc/wlan_reg_channel_api.h

@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: wlan_reg_channel_api.h
+ * This file provides prototypes of the routines needed for the
+ * external components to utilize the services provided by the
+ * regulatory component with respect to channel list access.
+ */
+
+#ifndef __WLAN_REG_CHANNEL_API_H
+#define __WLAN_REG_CHANNEL_API_H
+
+#include <reg_services_public_struct.h>
+
+#ifdef CONFIG_HOST_FIND_CHAN
+
+#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 */
+#define WLAN_CHAN_PSC              0x0400  /* 6GHz PSC frequency */
+
+/**
+ * wlan_reg_is_phymode_chwidth_allowed() - Check if requested phymode is allowed
+ * @pdev: pdev pointer.
+ * @phy_in: phymode that the user requested.
+ * @ch_width: Channel width that the user requested.
+ *
+ * Return: true if phymode is allowed, else false.
+ */
+bool wlan_reg_is_phymode_chwidth_allowed(struct wlan_objmgr_pdev *pdev,
+					 enum reg_phymode phy_in,
+					 enum phy_ch_width ch_width,
+					 qdf_freq_t primary_freq);
+
+/**
+ * wlan_reg_get_max_phymode_and_chwidth() - Find the maximum regmode and
+ * channel width combo supported by the device.
+ * @phy_in: Maximum reg_phymode.
+ * @ch_width: Maximum channel width.
+ * @primary_freq: Input primary frequency.
+ *
+ * Return QDF_STATUS_SUCCESS if a combination is found, else return failure.
+ */
+QDF_STATUS wlan_reg_get_max_phymode_and_chwidth(struct wlan_objmgr_pdev *pdev,
+						enum reg_phymode *phy_in,
+						enum phy_ch_width *ch_width);
+
+/**
+ * wlan_reg_get_txpow_ant_gain() - Find the tx power and antenna gain for
+ * the given frequency.
+ * @pdev: pdev pointer.
+ * @freq: Given frequency.
+ * @txpower: tx power to be filled.
+ * @ant_gain: Antenna gain to be filled.
+ *
+ */
+void wlan_reg_get_txpow_ant_gain(struct wlan_objmgr_pdev *pdev,
+				 qdf_freq_t freq,
+				 uint32_t *txpower,
+				 uint8_t *ant_gain);
+
+/**
+ * wlan_reg_get_chan_flags() - Find the channel flags for freq1 and freq2.
+ * @pdev: pdev pointer.
+ * @freq1: Frequency in primary segment.
+ * @freq2: Frequency in secondary segment.
+ * @flags: 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);
+#else
+static inline bool
+wlan_reg_is_phymode_chwidth_allowed(struct wlan_objmgr_pdev *pdev,
+				    enum reg_phymode phy_in,
+				    enum phy_ch_width ch_width,
+				    qdf_freq_t primary_freq)
+{
+	return false;
+}
+
+static inline QDF_STATUS
+wlan_reg_get_max_phymode_and_chwidth(struct wlan_objmgr_pdev *pdev,
+				     enum reg_phymode *phy_in,
+				     enum phy_ch_width *ch_width)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline void
+wlan_reg_get_txpow_ant_gain(struct wlan_objmgr_pdev *pdev,
+			    qdf_freq_t freq,
+			    uint32_t *txpower,
+			    uint8_t *ant_gain)
+{
+}
+
+static inline void
+wlan_reg_get_chan_flags(struct wlan_objmgr_pdev *pdev,
+			qdf_freq_t freq1,
+			qdf_freq_t freq2,
+			uint16_t *flags)
+{
+}
+#endif /* CONFIG_HOST_FIND_CHAN */
+
+#endif /* __WLAN_REG_CHANNEL_API_H */

+ 135 - 0
umac/regulatory/dispatcher/src/wlan_reg_channel_api.c

@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * @file wlan_reg_channel_api.c
+ * @brief contains regulatory channel access functions
+ */
+
+#include <qdf_status.h>
+#include <qdf_types.h>
+#include <qdf_module.h>
+#include <wlan_cmn.h>
+#include <wlan_reg_channel_api.h>
+#include <wlan_objmgr_pdev_obj.h>
+#include <wlan_objmgr_psoc_obj.h>
+#include <reg_priv_objs.h>
+#include <reg_services_common.h>
+#include <reg_channel.h>
+#include <wlan_reg_services_api.h>
+
+#ifdef CONFIG_HOST_FIND_CHAN
+bool wlan_reg_is_phymode_chwidth_allowed(struct wlan_objmgr_pdev *pdev,
+					 enum reg_phymode phy_in,
+					 enum phy_ch_width ch_width,
+					 qdf_freq_t primary_freq)
+{
+	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 false;
+	}
+
+	return reg_is_phymode_chwidth_allowed(pdev_priv_obj, phy_in, ch_width,
+					      primary_freq);
+}
+
+QDF_STATUS wlan_reg_get_max_phymode_and_chwidth(struct wlan_objmgr_pdev *pdev,
+						enum reg_phymode *phy_in,
+						enum phy_ch_width *ch_width)
+{
+	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 QDF_STATUS_E_FAILURE;
+	}
+
+	*phy_in = pdev_priv_obj->max_phymode;
+	*ch_width = pdev_priv_obj->max_chwidth;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void wlan_reg_get_txpow_ant_gain(struct wlan_objmgr_pdev *pdev,
+				 qdf_freq_t freq,
+				 uint32_t *txpower,
+				 uint8_t *ant_gain)
+{
+	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
+	struct regulatory_channel *cur_chan_list;
+	int i;
+
+	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;
+	}
+
+	cur_chan_list = pdev_priv_obj->cur_chan_list;
+
+	for (i = 0; i < NUM_CHANNELS; i++) {
+		if (cur_chan_list[i].center_freq == freq) {
+			*txpower = cur_chan_list[i].tx_power;
+			*ant_gain = cur_chan_list[i].ant_gain;
+		}
+	}
+}
+
+void wlan_reg_get_chan_flags(struct wlan_objmgr_pdev *pdev,
+			     qdf_freq_t freq1,
+			     qdf_freq_t freq2,
+			     uint16_t *flags)
+{
+	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
+	struct regulatory_channel *cur_chan_list;
+	int i;
+
+	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;
+	}
+
+	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 == freq2 &&
+		    cur_chan_list[i].chan_flags & REGULATORY_CHAN_RADAR) {
+			*flags |= WLAN_CHAN_DFS_CFREQ2;
+			*flags |= WLAN_CHAN_DISALLOW_ADHOC;
+		}
+	}
+
+	if (WLAN_REG_IS_6GHZ_PSC_CHAN_FREQ(freq1))
+		*flags |= WLAN_CHAN_PSC;
+}
+
+#endif /* CONFIG_HOST_FIND_CHAN */