|
@@ -35,6 +35,7 @@
|
|
#include "reg_build_chan_list.h"
|
|
#include "reg_build_chan_list.h"
|
|
#include "reg_opclass.h"
|
|
#include "reg_opclass.h"
|
|
#include "reg_services_common.h"
|
|
#include "reg_services_common.h"
|
|
|
|
+#include <wlan_objmgr_pdev_obj.h>
|
|
|
|
|
|
#ifdef HOST_OPCLASS
|
|
#ifdef HOST_OPCLASS
|
|
static struct reg_dmn_supp_op_classes reg_dmn_curr_supp_opp_classes = { 0 };
|
|
static struct reg_dmn_supp_op_classes reg_dmn_curr_supp_opp_classes = { 0 };
|
|
@@ -1598,6 +1599,8 @@ static bool reg_is_cfi_supported(struct wlan_objmgr_pdev *pdev,
|
|
* @pdev: Pointer to pdev
|
|
* @pdev: Pointer to pdev
|
|
* @cap: Pointer to regdmn_ap_cap_opclass_t
|
|
* @cap: Pointer to regdmn_ap_cap_opclass_t
|
|
* @op_class_tbl: Pointer to op_class_tbl
|
|
* @op_class_tbl: Pointer to op_class_tbl
|
|
|
|
+ * @in_opclass_conf: input opclass configuration
|
|
|
|
+ * Supported or not-supported by current HW mode
|
|
*
|
|
*
|
|
* Populate channels from opclass map to regdmn_ap_cap_opclass_t as supported
|
|
* Populate channels from opclass map to regdmn_ap_cap_opclass_t as supported
|
|
* and non-supported channels for 6Ghz.
|
|
* and non-supported channels for 6Ghz.
|
|
@@ -1607,7 +1610,8 @@ static bool reg_is_cfi_supported(struct wlan_objmgr_pdev *pdev,
|
|
static void reg_get_cfis_from_opclassmap_for_6g(
|
|
static void reg_get_cfis_from_opclassmap_for_6g(
|
|
struct wlan_objmgr_pdev *pdev,
|
|
struct wlan_objmgr_pdev *pdev,
|
|
struct regdmn_ap_cap_opclass_t *cap,
|
|
struct regdmn_ap_cap_opclass_t *cap,
|
|
- const struct reg_dmn_op_class_map_t *op_class_tbl)
|
|
|
|
|
|
+ const struct reg_dmn_op_class_map_t *op_class_tbl,
|
|
|
|
+ enum opclass_config in_opclass_conf)
|
|
{
|
|
{
|
|
uint8_t n_sup_chans = 0, n_unsup_chans = 0, j;
|
|
uint8_t n_sup_chans = 0, n_unsup_chans = 0, j;
|
|
const struct c_freq_lst *p_cfi_lst = op_class_tbl->p_cfi_lst_obj;
|
|
const struct c_freq_lst *p_cfi_lst = op_class_tbl->p_cfi_lst_obj;
|
|
@@ -1624,7 +1628,9 @@ static void reg_get_cfis_from_opclassmap_for_6g(
|
|
cfi_freq,
|
|
cfi_freq,
|
|
bw,
|
|
bw,
|
|
op_class_tbl->op_class);
|
|
op_class_tbl->op_class);
|
|
- if (is_cfi_supported) {
|
|
|
|
|
|
+ if (is_cfi_supported &&
|
|
|
|
+ (in_opclass_conf == OPCLASSES_SUPPORTED_BY_CUR_HWMODE ||
|
|
|
|
+ in_opclass_conf == OPCLASSES_SUPPORTED_BY_DOMAIN)) {
|
|
cap->sup_chan_list[n_sup_chans++] = cfi;
|
|
cap->sup_chan_list[n_sup_chans++] = cfi;
|
|
cap->num_supported_chan++;
|
|
cap->num_supported_chan++;
|
|
} else {
|
|
} else {
|
|
@@ -1646,6 +1652,8 @@ static uint16_t reg_find_nearest_ieee_bw(uint16_t spacing)
|
|
* @pdev: Pointer to pdev
|
|
* @pdev: Pointer to pdev
|
|
* @cap: Pointer to regdmn_ap_cap_opclass_t
|
|
* @cap: Pointer to regdmn_ap_cap_opclass_t
|
|
* @op_class_tbl: Pointer to op_class_tbl
|
|
* @op_class_tbl: Pointer to op_class_tbl
|
|
|
|
+ * @in_opclass_conf: input opclass configuration
|
|
|
|
+ * Supported or not-supported by current HW mode
|
|
*
|
|
*
|
|
* Populate channels from opclass map to regdmn_ap_cap_opclass_t as supported
|
|
* Populate channels from opclass map to regdmn_ap_cap_opclass_t as supported
|
|
* and non-supported channels for non-6Ghz.
|
|
* and non-supported channels for non-6Ghz.
|
|
@@ -1655,7 +1663,8 @@ static uint16_t reg_find_nearest_ieee_bw(uint16_t spacing)
|
|
static void reg_get_cfis_from_opclassmap_for_non6g(
|
|
static void reg_get_cfis_from_opclassmap_for_non6g(
|
|
struct wlan_objmgr_pdev *pdev,
|
|
struct wlan_objmgr_pdev *pdev,
|
|
struct regdmn_ap_cap_opclass_t *cap,
|
|
struct regdmn_ap_cap_opclass_t *cap,
|
|
- const struct reg_dmn_op_class_map_t *op_class_tbl)
|
|
|
|
|
|
+ const struct reg_dmn_op_class_map_t *op_class_tbl,
|
|
|
|
+ enum opclass_config in_opclass_conf)
|
|
{
|
|
{
|
|
qdf_freq_t start_freq = op_class_tbl->start_freq;
|
|
qdf_freq_t start_freq = op_class_tbl->start_freq;
|
|
uint8_t chan_idx = 0, n_sup_chans = 0, n_unsup_chans = 0;
|
|
uint8_t chan_idx = 0, n_sup_chans = 0, n_unsup_chans = 0;
|
|
@@ -1680,12 +1689,14 @@ static void reg_get_cfis_from_opclassmap_for_non6g(
|
|
0,
|
|
0,
|
|
ch_width);
|
|
ch_width);
|
|
|
|
|
|
- if (!is_supported) {
|
|
|
|
- cap->non_sup_chan_list[n_unsup_chans++] = op_cls_chan;
|
|
|
|
- cap->num_non_supported_chan++;
|
|
|
|
- } else {
|
|
|
|
|
|
+ if (is_supported &&
|
|
|
|
+ (in_opclass_conf == OPCLASSES_SUPPORTED_BY_CUR_HWMODE ||
|
|
|
|
+ in_opclass_conf == OPCLASSES_SUPPORTED_BY_DOMAIN)) {
|
|
cap->sup_chan_list[n_sup_chans++] = op_cls_chan;
|
|
cap->sup_chan_list[n_sup_chans++] = op_cls_chan;
|
|
cap->num_supported_chan++;
|
|
cap->num_supported_chan++;
|
|
|
|
+ } else {
|
|
|
|
+ cap->non_sup_chan_list[n_unsup_chans++] = op_cls_chan;
|
|
|
|
+ cap->num_non_supported_chan++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -1697,6 +1708,8 @@ static void reg_get_cfis_from_opclassmap_for_non6g(
|
|
* @index: Pointer to index of reg_ap_cap
|
|
* @index: Pointer to index of reg_ap_cap
|
|
* @op_class_tbl: Pointer to op_class_tbl
|
|
* @op_class_tbl: Pointer to op_class_tbl
|
|
* @is_opclass_operable: Set true if opclass is operable, else set false
|
|
* @is_opclass_operable: Set true if opclass is operable, else set false
|
|
|
|
+ * @in_opclass_conf: input opclass configuration
|
|
|
|
+ * Supported or not-supported by current HW mode
|
|
*
|
|
*
|
|
* Populate channels from opclass map to reg_ap_cap as supported and
|
|
* Populate channels from opclass map to reg_ap_cap as supported and
|
|
* non-supported channels.
|
|
* non-supported channels.
|
|
@@ -1709,18 +1722,21 @@ reg_get_channels_from_opclassmap(
|
|
struct regdmn_ap_cap_opclass_t *reg_ap_cap,
|
|
struct regdmn_ap_cap_opclass_t *reg_ap_cap,
|
|
uint8_t index,
|
|
uint8_t index,
|
|
const struct reg_dmn_op_class_map_t *op_class_tbl,
|
|
const struct reg_dmn_op_class_map_t *op_class_tbl,
|
|
- bool *is_opclass_operable)
|
|
|
|
|
|
+ bool *is_opclass_operable,
|
|
|
|
+ enum opclass_config in_opclass_conf)
|
|
{
|
|
{
|
|
struct regdmn_ap_cap_opclass_t *cap = ®_ap_cap[index];
|
|
struct regdmn_ap_cap_opclass_t *cap = ®_ap_cap[index];
|
|
|
|
|
|
if (reg_is_6ghz_op_class(pdev, op_class_tbl->op_class)) {
|
|
if (reg_is_6ghz_op_class(pdev, op_class_tbl->op_class)) {
|
|
reg_get_cfis_from_opclassmap_for_6g(pdev,
|
|
reg_get_cfis_from_opclassmap_for_6g(pdev,
|
|
cap,
|
|
cap,
|
|
- op_class_tbl);
|
|
|
|
|
|
+ op_class_tbl,
|
|
|
|
+ in_opclass_conf);
|
|
} else {
|
|
} else {
|
|
reg_get_cfis_from_opclassmap_for_non6g(pdev,
|
|
reg_get_cfis_from_opclassmap_for_non6g(pdev,
|
|
cap,
|
|
cap,
|
|
- op_class_tbl);
|
|
|
|
|
|
+ op_class_tbl,
|
|
|
|
+ in_opclass_conf);
|
|
}
|
|
}
|
|
|
|
|
|
if (cap->num_supported_chan >= 1)
|
|
if (cap->num_supported_chan >= 1)
|
|
@@ -1736,6 +1752,7 @@ QDF_STATUS reg_get_opclass_details(struct wlan_objmgr_pdev *pdev,
|
|
uint8_t max_reg_power = 0;
|
|
uint8_t max_reg_power = 0;
|
|
const struct reg_dmn_op_class_map_t *op_class_tbl;
|
|
const struct reg_dmn_op_class_map_t *op_class_tbl;
|
|
uint8_t index = 0;
|
|
uint8_t index = 0;
|
|
|
|
+ enum opclass_config opclass_conf = OPCLASSES_SUPPORTED_BY_DOMAIN;
|
|
|
|
|
|
if (global_tbl_lookup)
|
|
if (global_tbl_lookup)
|
|
op_class_tbl = global_op_class;
|
|
op_class_tbl = global_op_class;
|
|
@@ -1757,7 +1774,8 @@ QDF_STATUS reg_get_opclass_details(struct wlan_objmgr_pdev *pdev,
|
|
reg_ap_cap,
|
|
reg_ap_cap,
|
|
index,
|
|
index,
|
|
op_class_tbl,
|
|
op_class_tbl,
|
|
- &is_opclass_operable);
|
|
|
|
|
|
+ &is_opclass_operable,
|
|
|
|
+ opclass_conf);
|
|
if (is_opclass_operable) {
|
|
if (is_opclass_operable) {
|
|
reg_ap_cap[index].op_class = op_class_tbl->op_class;
|
|
reg_ap_cap[index].op_class = op_class_tbl->op_class;
|
|
reg_ap_cap[index].ch_width =
|
|
reg_ap_cap[index].ch_width =
|
|
@@ -1835,4 +1853,132 @@ bool reg_is_2ghz_op_class(const uint8_t *country, uint8_t op_class)
|
|
{
|
|
{
|
|
return reg_is_opclass_band_found(country, op_class, BIT(REG_BAND_2G));
|
|
return reg_is_opclass_band_found(country, op_class, BIT(REG_BAND_2G));
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * reg_convert_chan_spacing_to_width() - Convert channel spacing to
|
|
|
|
+ * channel width.
|
|
|
|
+ * @chan_spacing: Channel spacing
|
|
|
|
+ * @opclass_chwidth: Opclass channel width
|
|
|
|
+ * Return - None
|
|
|
|
+ */
|
|
|
|
+#ifdef WLAN_FEATURE_11BE
|
|
|
|
+static void reg_convert_chan_spacing_to_width(uint16_t chan_spacing,
|
|
|
|
+ uint16_t *opclass_chwidth)
|
|
|
|
+{
|
|
|
|
+ switch (chan_spacing) {
|
|
|
|
+ case BW_20_MHZ:
|
|
|
|
+ case BW_25_MHZ:
|
|
|
|
+ *opclass_chwidth = BW_20_MHZ;
|
|
|
|
+ break;
|
|
|
|
+ case BW_40_MHZ:
|
|
|
|
+ *opclass_chwidth = BW_40_MHZ;
|
|
|
|
+ break;
|
|
|
|
+ case BW_80_MHZ:
|
|
|
|
+ *opclass_chwidth = BW_80_MHZ;
|
|
|
|
+ break;
|
|
|
|
+ case BW_160_MHZ:
|
|
|
|
+ *opclass_chwidth = BW_160_MHZ;
|
|
|
|
+ break;
|
|
|
|
+ case BW_320_MHZ:
|
|
|
|
+ *opclass_chwidth = BW_320_MHZ;
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ *opclass_chwidth = 0;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+#else
|
|
|
|
+static void reg_convert_chan_spacing_to_width(uint16_t chan_spacing,
|
|
|
|
+ uint16_t *opclass_chwidth)
|
|
|
|
+{
|
|
|
|
+ switch (chan_spacing) {
|
|
|
|
+ case BW_20_MHZ:
|
|
|
|
+ case BW_25_MHZ:
|
|
|
|
+ *opclass_chwidth = BW_20_MHZ;
|
|
|
|
+ break;
|
|
|
|
+ case BW_40_MHZ:
|
|
|
|
+ *opclass_chwidth = BW_40_MHZ;
|
|
|
|
+ break;
|
|
|
|
+ case BW_80_MHZ:
|
|
|
|
+ *opclass_chwidth = BW_80_MHZ;
|
|
|
|
+ break;
|
|
|
|
+ case BW_160_MHZ:
|
|
|
|
+ *opclass_chwidth = BW_160_MHZ;
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ *opclass_chwidth = 0;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+QDF_STATUS
|
|
|
|
+reg_get_opclass_for_cur_hwmode(struct wlan_objmgr_pdev *pdev,
|
|
|
|
+ struct regdmn_ap_cap_opclass_t *reg_ap_cap,
|
|
|
|
+ uint8_t *n_opclasses,
|
|
|
|
+ uint8_t max_supp_op_class,
|
|
|
|
+ bool global_tbl_lookup,
|
|
|
|
+ enum phy_ch_width max_chwidth,
|
|
|
|
+ bool is_80p80_supp)
|
|
|
|
+{
|
|
|
|
+ uint8_t max_reg_power = 0;
|
|
|
|
+ const struct reg_dmn_op_class_map_t *op_class_tbl;
|
|
|
|
+ uint8_t index = 0;
|
|
|
|
+ uint16_t out_width;
|
|
|
|
+
|
|
|
|
+ if (global_tbl_lookup)
|
|
|
|
+ op_class_tbl = global_op_class;
|
|
|
|
+ else
|
|
|
|
+ reg_get_op_class_tbl_by_chan_map(&op_class_tbl);
|
|
|
|
+
|
|
|
|
+ max_reg_power = reg_get_max_tx_power(pdev);
|
|
|
|
+
|
|
|
|
+ out_width = reg_get_bw_value(max_chwidth);
|
|
|
|
+
|
|
|
|
+ while (op_class_tbl->op_class && (index < max_supp_op_class)) {
|
|
|
|
+ bool is_opclass_operable = false;
|
|
|
|
+ enum opclass_config opclass_in_config =
|
|
|
|
+ OPCLASSES_SUPPORTED_BY_CUR_HWMODE;
|
|
|
|
+ uint16_t opclass_width;
|
|
|
|
+
|
|
|
|
+ qdf_mem_zero(reg_ap_cap[index].sup_chan_list,
|
|
|
|
+ REG_MAX_CHANNELS_PER_OPERATING_CLASS);
|
|
|
|
+ reg_ap_cap[index].num_supported_chan = 0;
|
|
|
|
+ qdf_mem_zero(reg_ap_cap[index].non_sup_chan_list,
|
|
|
|
+ REG_MAX_CHANNELS_PER_OPERATING_CLASS);
|
|
|
|
+ reg_ap_cap[index].num_non_supported_chan = 0;
|
|
|
|
+
|
|
|
|
+ reg_convert_chan_spacing_to_width(op_class_tbl->chan_spacing,
|
|
|
|
+ &opclass_width);
|
|
|
|
+
|
|
|
|
+ if ((opclass_width > out_width) ||
|
|
|
|
+ ((op_class_tbl->behav_limit == BIT(BEHAV_BW80_PLUS)) &&
|
|
|
|
+ !is_80p80_supp))
|
|
|
|
+ opclass_in_config =
|
|
|
|
+ OPCLASSES_NOT_SUPPORTED_BY_CUR_HWMODE;
|
|
|
|
+
|
|
|
|
+ reg_get_channels_from_opclassmap(pdev,
|
|
|
|
+ reg_ap_cap,
|
|
|
|
+ index,
|
|
|
|
+ op_class_tbl,
|
|
|
|
+ &is_opclass_operable,
|
|
|
|
+ opclass_in_config);
|
|
|
|
+
|
|
|
|
+ if (is_opclass_operable && opclass_in_config ==
|
|
|
|
+ OPCLASSES_SUPPORTED_BY_CUR_HWMODE) {
|
|
|
|
+ reg_ap_cap[index].op_class = op_class_tbl->op_class;
|
|
|
|
+ reg_ap_cap[index].ch_width =
|
|
|
|
+ op_class_tbl->chan_spacing;
|
|
|
|
+ reg_ap_cap[index].start_freq =
|
|
|
|
+ op_class_tbl->start_freq;
|
|
|
|
+ reg_ap_cap[index].max_tx_pwr_dbm = max_reg_power;
|
|
|
|
+ reg_ap_cap[index].behav_limit =
|
|
|
|
+ op_class_tbl->behav_limit;
|
|
|
|
+ index++;
|
|
|
|
+ }
|
|
|
|
+ op_class_tbl++;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ *n_opclasses = index;
|
|
|
|
+
|
|
|
|
+ return QDF_STATUS_SUCCESS;
|
|
|
|
+}
|
|
#endif
|
|
#endif
|