mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-23 23:42:43 +00:00
845 lines
29 KiB
Diff
845 lines
29 KiB
Diff
|
From 91fa00fa69224aae5afb720c5e68b22e4c4f7333 Mon Sep 17 00:00:00 2001
|
||
|
From: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
||
|
Date: Wed, 1 Mar 2023 16:20:59 +0200
|
||
|
Subject: [PATCH] wifi: ath11k: add support to parse new WMI event for 6 GHz
|
||
|
|
||
|
In order to support different power levels of 6 GHz AP and client,
|
||
|
new WMI event for regulatory - WMI_REG_CHAN_LIST_CC_EXT_EVENTID is
|
||
|
added in firmware. This event provides new parameters required for
|
||
|
6 GHz regulatory rules.
|
||
|
|
||
|
Add support for parsing 2.4 GHz, 5 GHz and 6 GHz reg rules and other
|
||
|
parameters from WMI_REG_CHAN_LIST_CC_EXT_EVENTID.
|
||
|
|
||
|
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1
|
||
|
Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1
|
||
|
Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.5.0.1-01100-QCAHKSWPL_SILICONZ-1
|
||
|
|
||
|
Signed-off-by: Lavanya Suresh <quic_lavaks@quicinc.com>
|
||
|
Signed-off-by: Wen Gong <quic_wgong@quicinc.com>
|
||
|
Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
||
|
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
|
||
|
Link: https://lore.kernel.org/r/20230110121024.14051-3-quic_adisi@quicinc.com
|
||
|
---
|
||
|
drivers/net/wireless/ath/ath11k/reg.c | 37 ++-
|
||
|
drivers/net/wireless/ath/ath11k/wmi.c | 418 +++++++++++++++++++++++++-
|
||
|
drivers/net/wireless/ath/ath11k/wmi.h | 163 +++++++++-
|
||
|
3 files changed, 584 insertions(+), 34 deletions(-)
|
||
|
|
||
|
--- a/drivers/net/wireless/ath/ath11k/reg.c
|
||
|
+++ b/drivers/net/wireless/ath/ath11k/reg.c
|
||
|
@@ -613,7 +613,7 @@ ath11k_reg_build_regd(struct ath11k_base
|
||
|
{
|
||
|
struct ieee80211_regdomain *tmp_regd, *default_regd, *new_regd = NULL;
|
||
|
struct cur_reg_rule *reg_rule;
|
||
|
- u8 i = 0, j = 0;
|
||
|
+ u8 i = 0, j = 0, k = 0;
|
||
|
u8 num_rules;
|
||
|
u16 max_bw;
|
||
|
u32 flags;
|
||
|
@@ -621,6 +621,12 @@ ath11k_reg_build_regd(struct ath11k_base
|
||
|
|
||
|
num_rules = reg_info->num_5ghz_reg_rules + reg_info->num_2ghz_reg_rules;
|
||
|
|
||
|
+ /* FIXME: Currently taking reg rules for 6 GHz only from Indoor AP mode list.
|
||
|
+ * This can be updated after complete 6 GHz regulatory support is added.
|
||
|
+ */
|
||
|
+ if (reg_info->is_ext_reg_event)
|
||
|
+ num_rules += reg_info->num_6ghz_rules_ap[WMI_REG_INDOOR_AP];
|
||
|
+
|
||
|
if (!num_rules)
|
||
|
goto ret;
|
||
|
|
||
|
@@ -666,6 +672,14 @@ ath11k_reg_build_regd(struct ath11k_base
|
||
|
* per other BW rule flags we pass from here
|
||
|
*/
|
||
|
flags = NL80211_RRF_AUTO_BW;
|
||
|
+ } else if (reg_info->is_ext_reg_event &&
|
||
|
+ reg_info->num_6ghz_rules_ap[WMI_REG_INDOOR_AP] &&
|
||
|
+ (k < reg_info->num_6ghz_rules_ap[WMI_REG_INDOOR_AP])) {
|
||
|
+ reg_rule = reg_info->reg_rules_6ghz_ap_ptr[WMI_REG_INDOOR_AP] +
|
||
|
+ k++;
|
||
|
+ max_bw = min_t(u16, reg_rule->max_bw,
|
||
|
+ reg_info->max_bw_6ghz_ap[WMI_REG_INDOOR_AP]);
|
||
|
+ flags = NL80211_RRF_AUTO_BW;
|
||
|
} else {
|
||
|
break;
|
||
|
}
|
||
|
@@ -693,12 +707,21 @@ ath11k_reg_build_regd(struct ath11k_base
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
- ath11k_dbg(ab, ATH11K_DBG_REG,
|
||
|
- "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n",
|
||
|
- i + 1, reg_rule->start_freq, reg_rule->end_freq,
|
||
|
- max_bw, reg_rule->ant_gain, reg_rule->reg_power,
|
||
|
- tmp_regd->reg_rules[i].dfs_cac_ms,
|
||
|
- flags);
|
||
|
+ if (reg_info->is_ext_reg_event) {
|
||
|
+ ath11k_dbg(ab, ATH11K_DBG_REG,
|
||
|
+ "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d) (%d, %d)\n",
|
||
|
+ i + 1, reg_rule->start_freq, reg_rule->end_freq,
|
||
|
+ max_bw, reg_rule->ant_gain, reg_rule->reg_power,
|
||
|
+ tmp_regd->reg_rules[i].dfs_cac_ms, flags,
|
||
|
+ reg_rule->psd_flag, reg_rule->psd_eirp);
|
||
|
+ } else {
|
||
|
+ ath11k_dbg(ab, ATH11K_DBG_REG,
|
||
|
+ "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n",
|
||
|
+ i + 1, reg_rule->start_freq, reg_rule->end_freq,
|
||
|
+ max_bw, reg_rule->ant_gain, reg_rule->reg_power,
|
||
|
+ tmp_regd->reg_rules[i].dfs_cac_ms,
|
||
|
+ flags);
|
||
|
+ }
|
||
|
}
|
||
|
|
||
|
tmp_regd->n_reg_rules = i;
|
||
|
--- a/drivers/net/wireless/ath/ath11k/wmi.c
|
||
|
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
|
||
|
@@ -105,6 +105,8 @@ static const struct wmi_tlv_policy wmi_t
|
||
|
= { .min_len = sizeof(struct wmi_vdev_stopped_event) },
|
||
|
[WMI_TAG_REG_CHAN_LIST_CC_EVENT]
|
||
|
= { .min_len = sizeof(struct wmi_reg_chan_list_cc_event) },
|
||
|
+ [WMI_TAG_REG_CHAN_LIST_CC_EXT_EVENT]
|
||
|
+ = { .min_len = sizeof(struct wmi_reg_chan_list_cc_ext_event) },
|
||
|
[WMI_TAG_MGMT_RX_HDR]
|
||
|
= { .min_len = sizeof(struct wmi_mgmt_rx_hdr) },
|
||
|
[WMI_TAG_MGMT_TX_COMPL_EVENT]
|
||
|
@@ -3974,6 +3976,10 @@ ath11k_wmi_copy_resource_config(struct w
|
||
|
wmi_cfg->sched_params = tg_cfg->sched_params;
|
||
|
wmi_cfg->twt_ap_pdev_count = tg_cfg->twt_ap_pdev_count;
|
||
|
wmi_cfg->twt_ap_sta_count = tg_cfg->twt_ap_sta_count;
|
||
|
+ wmi_cfg->host_service_flags &=
|
||
|
+ ~(1 << WMI_CFG_HOST_SERVICE_FLAG_REG_CC_EXT);
|
||
|
+ wmi_cfg->host_service_flags |= (tg_cfg->is_reg_cc_ext_event_supported <<
|
||
|
+ WMI_CFG_HOST_SERVICE_FLAG_REG_CC_EXT);
|
||
|
}
|
||
|
|
||
|
static int ath11k_init_cmd_send(struct ath11k_pdev_wmi *wmi,
|
||
|
@@ -4192,6 +4198,10 @@ int ath11k_wmi_cmd_init(struct ath11k_ba
|
||
|
|
||
|
ab->hw_params.hw_ops->wmi_init_config(ab, &config);
|
||
|
|
||
|
+ if (test_bit(WMI_TLV_SERVICE_REG_CC_EXT_EVENT_SUPPORT,
|
||
|
+ ab->wmi_ab.svc_map))
|
||
|
+ config.is_reg_cc_ext_event_supported = 1;
|
||
|
+
|
||
|
memcpy(&wmi_sc->wlan_resource_config, &config, sizeof(config));
|
||
|
|
||
|
init_param.res_cfg = &wmi_sc->wlan_resource_config;
|
||
|
@@ -4995,18 +5005,11 @@ static int ath11k_pull_reg_chan_list_upd
|
||
|
reg_info->phy_id = chan_list_event_hdr->phy_id;
|
||
|
reg_info->ctry_code = chan_list_event_hdr->country_id;
|
||
|
reg_info->reg_dmn_pair = chan_list_event_hdr->domain_code;
|
||
|
- if (chan_list_event_hdr->status_code == WMI_REG_SET_CC_STATUS_PASS)
|
||
|
- reg_info->status_code = REG_SET_CC_STATUS_PASS;
|
||
|
- else if (chan_list_event_hdr->status_code == WMI_REG_CURRENT_ALPHA2_NOT_FOUND)
|
||
|
- reg_info->status_code = REG_CURRENT_ALPHA2_NOT_FOUND;
|
||
|
- else if (chan_list_event_hdr->status_code == WMI_REG_INIT_ALPHA2_NOT_FOUND)
|
||
|
- reg_info->status_code = REG_INIT_ALPHA2_NOT_FOUND;
|
||
|
- else if (chan_list_event_hdr->status_code == WMI_REG_SET_CC_CHANGE_NOT_ALLOWED)
|
||
|
- reg_info->status_code = REG_SET_CC_CHANGE_NOT_ALLOWED;
|
||
|
- else if (chan_list_event_hdr->status_code == WMI_REG_SET_CC_STATUS_NO_MEMORY)
|
||
|
- reg_info->status_code = REG_SET_CC_STATUS_NO_MEMORY;
|
||
|
- else if (chan_list_event_hdr->status_code == WMI_REG_SET_CC_STATUS_FAIL)
|
||
|
- reg_info->status_code = REG_SET_CC_STATUS_FAIL;
|
||
|
+
|
||
|
+ reg_info->status_code =
|
||
|
+ ath11k_wmi_cc_setting_code_to_reg(chan_list_event_hdr->status_code);
|
||
|
+
|
||
|
+ reg_info->is_ext_reg_event = false;
|
||
|
|
||
|
reg_info->min_bw_2ghz = chan_list_event_hdr->min_bw_2ghz;
|
||
|
reg_info->max_bw_2ghz = chan_list_event_hdr->max_bw_2ghz;
|
||
|
@@ -5060,6 +5063,372 @@ static int ath11k_pull_reg_chan_list_upd
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
+static struct cur_reg_rule
|
||
|
+*create_ext_reg_rules_from_wmi(u32 num_reg_rules,
|
||
|
+ struct wmi_regulatory_ext_rule *wmi_reg_rule)
|
||
|
+{
|
||
|
+ struct cur_reg_rule *reg_rule_ptr;
|
||
|
+ u32 count;
|
||
|
+
|
||
|
+ reg_rule_ptr = kcalloc(num_reg_rules, sizeof(*reg_rule_ptr), GFP_ATOMIC);
|
||
|
+
|
||
|
+ if (!reg_rule_ptr)
|
||
|
+ return NULL;
|
||
|
+
|
||
|
+ for (count = 0; count < num_reg_rules; count++) {
|
||
|
+ reg_rule_ptr[count].start_freq =
|
||
|
+ u32_get_bits(wmi_reg_rule[count].freq_info,
|
||
|
+ REG_RULE_START_FREQ);
|
||
|
+ reg_rule_ptr[count].end_freq =
|
||
|
+ u32_get_bits(wmi_reg_rule[count].freq_info,
|
||
|
+ REG_RULE_END_FREQ);
|
||
|
+ reg_rule_ptr[count].max_bw =
|
||
|
+ u32_get_bits(wmi_reg_rule[count].bw_pwr_info,
|
||
|
+ REG_RULE_MAX_BW);
|
||
|
+ reg_rule_ptr[count].reg_power =
|
||
|
+ u32_get_bits(wmi_reg_rule[count].bw_pwr_info,
|
||
|
+ REG_RULE_REG_PWR);
|
||
|
+ reg_rule_ptr[count].ant_gain =
|
||
|
+ u32_get_bits(wmi_reg_rule[count].bw_pwr_info,
|
||
|
+ REG_RULE_ANT_GAIN);
|
||
|
+ reg_rule_ptr[count].flags =
|
||
|
+ u32_get_bits(wmi_reg_rule[count].flag_info,
|
||
|
+ REG_RULE_FLAGS);
|
||
|
+ reg_rule_ptr[count].psd_flag =
|
||
|
+ u32_get_bits(wmi_reg_rule[count].psd_power_info,
|
||
|
+ REG_RULE_PSD_INFO);
|
||
|
+ reg_rule_ptr[count].psd_eirp =
|
||
|
+ u32_get_bits(wmi_reg_rule[count].psd_power_info,
|
||
|
+ REG_RULE_PSD_EIRP);
|
||
|
+ }
|
||
|
+
|
||
|
+ return reg_rule_ptr;
|
||
|
+}
|
||
|
+
|
||
|
+static u8
|
||
|
+ath11k_invalid_5ghz_reg_ext_rules_from_wmi(u32 num_reg_rules,
|
||
|
+ const struct wmi_regulatory_ext_rule *rule)
|
||
|
+{
|
||
|
+ u8 num_invalid_5ghz_rules = 0;
|
||
|
+ u32 count, start_freq;
|
||
|
+
|
||
|
+ for (count = 0; count < num_reg_rules; count++) {
|
||
|
+ start_freq = u32_get_bits(rule[count].freq_info,
|
||
|
+ REG_RULE_START_FREQ);
|
||
|
+
|
||
|
+ if (start_freq >= ATH11K_MIN_6G_FREQ)
|
||
|
+ num_invalid_5ghz_rules++;
|
||
|
+ }
|
||
|
+
|
||
|
+ return num_invalid_5ghz_rules;
|
||
|
+}
|
||
|
+
|
||
|
+static int ath11k_pull_reg_chan_list_ext_update_ev(struct ath11k_base *ab,
|
||
|
+ struct sk_buff *skb,
|
||
|
+ struct cur_regulatory_info *reg_info)
|
||
|
+{
|
||
|
+ const void **tb;
|
||
|
+ const struct wmi_reg_chan_list_cc_ext_event *ext_chan_list_event_hdr;
|
||
|
+ struct wmi_regulatory_ext_rule *ext_wmi_reg_rule;
|
||
|
+ u32 num_2ghz_reg_rules, num_5ghz_reg_rules;
|
||
|
+ u32 num_6ghz_reg_rules_ap[WMI_REG_CURRENT_MAX_AP_TYPE];
|
||
|
+ u32 num_6ghz_client[WMI_REG_CURRENT_MAX_AP_TYPE][WMI_REG_MAX_CLIENT_TYPE];
|
||
|
+ u32 total_reg_rules = 0;
|
||
|
+ int ret, i, j, num_invalid_5ghz_ext_rules = 0;
|
||
|
+
|
||
|
+ ath11k_dbg(ab, ATH11K_DBG_WMI, "processing regulatory ext channel list\n");
|
||
|
+
|
||
|
+ tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||
|
+ if (IS_ERR(tb)) {
|
||
|
+ ret = PTR_ERR(tb);
|
||
|
+ ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||
|
+ return ret;
|
||
|
+ }
|
||
|
+
|
||
|
+ ext_chan_list_event_hdr = tb[WMI_TAG_REG_CHAN_LIST_CC_EXT_EVENT];
|
||
|
+ if (!ext_chan_list_event_hdr) {
|
||
|
+ ath11k_warn(ab, "failed to fetch reg chan list ext update ev\n");
|
||
|
+ kfree(tb);
|
||
|
+ return -EPROTO;
|
||
|
+ }
|
||
|
+
|
||
|
+ reg_info->num_2ghz_reg_rules =
|
||
|
+ ext_chan_list_event_hdr->num_2ghz_reg_rules;
|
||
|
+ reg_info->num_5ghz_reg_rules =
|
||
|
+ ext_chan_list_event_hdr->num_5ghz_reg_rules;
|
||
|
+ reg_info->num_6ghz_rules_ap[WMI_REG_INDOOR_AP] =
|
||
|
+ ext_chan_list_event_hdr->num_6ghz_reg_rules_ap_lpi;
|
||
|
+ reg_info->num_6ghz_rules_ap[WMI_REG_STANDARD_POWER_AP] =
|
||
|
+ ext_chan_list_event_hdr->num_6ghz_reg_rules_ap_sp;
|
||
|
+ reg_info->num_6ghz_rules_ap[WMI_REG_VERY_LOW_POWER_AP] =
|
||
|
+ ext_chan_list_event_hdr->num_6ghz_reg_rules_ap_vlp;
|
||
|
+
|
||
|
+ for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++) {
|
||
|
+ reg_info->num_6ghz_rules_client[WMI_REG_INDOOR_AP][i] =
|
||
|
+ ext_chan_list_event_hdr->num_6ghz_reg_rules_client_lpi[i];
|
||
|
+ reg_info->num_6ghz_rules_client[WMI_REG_STANDARD_POWER_AP][i] =
|
||
|
+ ext_chan_list_event_hdr->num_6ghz_reg_rules_client_sp[i];
|
||
|
+ reg_info->num_6ghz_rules_client[WMI_REG_VERY_LOW_POWER_AP][i] =
|
||
|
+ ext_chan_list_event_hdr->num_6ghz_reg_rules_client_vlp[i];
|
||
|
+ }
|
||
|
+
|
||
|
+ num_2ghz_reg_rules = reg_info->num_2ghz_reg_rules;
|
||
|
+ num_5ghz_reg_rules = reg_info->num_5ghz_reg_rules;
|
||
|
+
|
||
|
+ total_reg_rules += num_2ghz_reg_rules;
|
||
|
+ total_reg_rules += num_5ghz_reg_rules;
|
||
|
+
|
||
|
+ if ((num_2ghz_reg_rules > MAX_REG_RULES) ||
|
||
|
+ (num_5ghz_reg_rules > MAX_REG_RULES)) {
|
||
|
+ ath11k_warn(ab, "Num reg rules for 2.4 GHz/5 GHz exceeds max limit (num_2ghz_reg_rules: %d num_5ghz_reg_rules: %d max_rules: %d)\n",
|
||
|
+ num_2ghz_reg_rules, num_5ghz_reg_rules, MAX_REG_RULES);
|
||
|
+ kfree(tb);
|
||
|
+ return -EINVAL;
|
||
|
+ }
|
||
|
+
|
||
|
+ for (i = 0; i < WMI_REG_CURRENT_MAX_AP_TYPE; i++) {
|
||
|
+ num_6ghz_reg_rules_ap[i] = reg_info->num_6ghz_rules_ap[i];
|
||
|
+
|
||
|
+ if (num_6ghz_reg_rules_ap[i] > MAX_6GHZ_REG_RULES) {
|
||
|
+ ath11k_warn(ab, "Num 6 GHz reg rules for AP mode(%d) exceeds max limit (num_6ghz_reg_rules_ap: %d, max_rules: %d)\n",
|
||
|
+ i, num_6ghz_reg_rules_ap[i], MAX_6GHZ_REG_RULES);
|
||
|
+ kfree(tb);
|
||
|
+ return -EINVAL;
|
||
|
+ }
|
||
|
+
|
||
|
+ total_reg_rules += num_6ghz_reg_rules_ap[i];
|
||
|
+ }
|
||
|
+
|
||
|
+ for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++) {
|
||
|
+ num_6ghz_client[WMI_REG_INDOOR_AP][i] =
|
||
|
+ reg_info->num_6ghz_rules_client[WMI_REG_INDOOR_AP][i];
|
||
|
+ total_reg_rules += num_6ghz_client[WMI_REG_INDOOR_AP][i];
|
||
|
+
|
||
|
+ num_6ghz_client[WMI_REG_STANDARD_POWER_AP][i] =
|
||
|
+ reg_info->num_6ghz_rules_client[WMI_REG_STANDARD_POWER_AP][i];
|
||
|
+ total_reg_rules += num_6ghz_client[WMI_REG_STANDARD_POWER_AP][i];
|
||
|
+
|
||
|
+ num_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][i] =
|
||
|
+ reg_info->num_6ghz_rules_client[WMI_REG_VERY_LOW_POWER_AP][i];
|
||
|
+ total_reg_rules += num_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][i];
|
||
|
+
|
||
|
+ if ((num_6ghz_client[WMI_REG_INDOOR_AP][i] > MAX_6GHZ_REG_RULES) ||
|
||
|
+ (num_6ghz_client[WMI_REG_STANDARD_POWER_AP][i] >
|
||
|
+ MAX_6GHZ_REG_RULES) ||
|
||
|
+ (num_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][i] >
|
||
|
+ MAX_6GHZ_REG_RULES)) {
|
||
|
+ ath11k_warn(ab,
|
||
|
+ "Num 6 GHz client reg rules exceeds max limit, for client(type: %d)\n",
|
||
|
+ i);
|
||
|
+ kfree(tb);
|
||
|
+ return -EINVAL;
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ if (!total_reg_rules) {
|
||
|
+ ath11k_warn(ab, "No reg rules available\n");
|
||
|
+ kfree(tb);
|
||
|
+ return -EINVAL;
|
||
|
+ }
|
||
|
+
|
||
|
+ memcpy(reg_info->alpha2, &ext_chan_list_event_hdr->alpha2,
|
||
|
+ REG_ALPHA2_LEN);
|
||
|
+
|
||
|
+ reg_info->dfs_region = ext_chan_list_event_hdr->dfs_region;
|
||
|
+ reg_info->phybitmap = ext_chan_list_event_hdr->phybitmap;
|
||
|
+ reg_info->num_phy = ext_chan_list_event_hdr->num_phy;
|
||
|
+ reg_info->phy_id = ext_chan_list_event_hdr->phy_id;
|
||
|
+ reg_info->ctry_code = ext_chan_list_event_hdr->country_id;
|
||
|
+ reg_info->reg_dmn_pair = ext_chan_list_event_hdr->domain_code;
|
||
|
+
|
||
|
+ reg_info->status_code =
|
||
|
+ ath11k_wmi_cc_setting_code_to_reg(ext_chan_list_event_hdr->status_code);
|
||
|
+
|
||
|
+ reg_info->is_ext_reg_event = true;
|
||
|
+
|
||
|
+ reg_info->min_bw_2ghz = ext_chan_list_event_hdr->min_bw_2ghz;
|
||
|
+ reg_info->max_bw_2ghz = ext_chan_list_event_hdr->max_bw_2ghz;
|
||
|
+ reg_info->min_bw_5ghz = ext_chan_list_event_hdr->min_bw_5ghz;
|
||
|
+ reg_info->max_bw_5ghz = ext_chan_list_event_hdr->max_bw_5ghz;
|
||
|
+
|
||
|
+ reg_info->min_bw_6ghz_ap[WMI_REG_INDOOR_AP] =
|
||
|
+ ext_chan_list_event_hdr->min_bw_6ghz_ap_lpi;
|
||
|
+ reg_info->max_bw_6ghz_ap[WMI_REG_INDOOR_AP] =
|
||
|
+ ext_chan_list_event_hdr->max_bw_6ghz_ap_lpi;
|
||
|
+ reg_info->min_bw_6ghz_ap[WMI_REG_STANDARD_POWER_AP] =
|
||
|
+ ext_chan_list_event_hdr->min_bw_6ghz_ap_sp;
|
||
|
+ reg_info->max_bw_6ghz_ap[WMI_REG_STANDARD_POWER_AP] =
|
||
|
+ ext_chan_list_event_hdr->max_bw_6ghz_ap_sp;
|
||
|
+ reg_info->min_bw_6ghz_ap[WMI_REG_VERY_LOW_POWER_AP] =
|
||
|
+ ext_chan_list_event_hdr->min_bw_6ghz_ap_vlp;
|
||
|
+ reg_info->max_bw_6ghz_ap[WMI_REG_VERY_LOW_POWER_AP] =
|
||
|
+ ext_chan_list_event_hdr->max_bw_6ghz_ap_vlp;
|
||
|
+
|
||
|
+ for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++) {
|
||
|
+ reg_info->min_bw_6ghz_client[WMI_REG_INDOOR_AP][i] =
|
||
|
+ ext_chan_list_event_hdr->min_bw_6ghz_client_lpi[i];
|
||
|
+ reg_info->max_bw_6ghz_client[WMI_REG_INDOOR_AP][i] =
|
||
|
+ ext_chan_list_event_hdr->max_bw_6ghz_client_lpi[i];
|
||
|
+ reg_info->min_bw_6ghz_client[WMI_REG_STANDARD_POWER_AP][i] =
|
||
|
+ ext_chan_list_event_hdr->min_bw_6ghz_client_sp[i];
|
||
|
+ reg_info->max_bw_6ghz_client[WMI_REG_STANDARD_POWER_AP][i] =
|
||
|
+ ext_chan_list_event_hdr->max_bw_6ghz_client_sp[i];
|
||
|
+ reg_info->min_bw_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][i] =
|
||
|
+ ext_chan_list_event_hdr->min_bw_6ghz_client_vlp[i];
|
||
|
+ reg_info->max_bw_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][i] =
|
||
|
+ ext_chan_list_event_hdr->max_bw_6ghz_client_vlp[i];
|
||
|
+ }
|
||
|
+
|
||
|
+ ath11k_dbg(ab, ATH11K_DBG_WMI,
|
||
|
+ "%s:cc_ext %s dsf %d BW: min_2ghz %d max_2ghz %d min_5ghz %d max_5ghz %d",
|
||
|
+ __func__, reg_info->alpha2, reg_info->dfs_region,
|
||
|
+ reg_info->min_bw_2ghz, reg_info->max_bw_2ghz,
|
||
|
+ reg_info->min_bw_5ghz, reg_info->max_bw_5ghz);
|
||
|
+
|
||
|
+ ath11k_dbg(ab, ATH11K_DBG_WMI,
|
||
|
+ "num_2ghz_reg_rules %d num_5ghz_reg_rules %d",
|
||
|
+ num_2ghz_reg_rules, num_5ghz_reg_rules);
|
||
|
+
|
||
|
+ ath11k_dbg(ab, ATH11K_DBG_WMI,
|
||
|
+ "num_6ghz_reg_rules_ap_lpi: %d num_6ghz_reg_rules_ap_sp: %d num_6ghz_reg_rules_ap_vlp: %d",
|
||
|
+ num_6ghz_reg_rules_ap[WMI_REG_INDOOR_AP],
|
||
|
+ num_6ghz_reg_rules_ap[WMI_REG_STANDARD_POWER_AP],
|
||
|
+ num_6ghz_reg_rules_ap[WMI_REG_VERY_LOW_POWER_AP]);
|
||
|
+
|
||
|
+ j = WMI_REG_DEFAULT_CLIENT;
|
||
|
+ ath11k_dbg(ab, ATH11K_DBG_WMI,
|
||
|
+ "6 GHz Regular client: num_6ghz_reg_rules_lpi: %d num_6ghz_reg_rules_sp: %d num_6ghz_reg_rules_vlp: %d",
|
||
|
+ num_6ghz_client[WMI_REG_INDOOR_AP][j],
|
||
|
+ num_6ghz_client[WMI_REG_STANDARD_POWER_AP][j],
|
||
|
+ num_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][j]);
|
||
|
+
|
||
|
+ j = WMI_REG_SUBORDINATE_CLIENT;
|
||
|
+ ath11k_dbg(ab, ATH11K_DBG_WMI,
|
||
|
+ "6 GHz Subordinate client: num_6ghz_reg_rules_lpi: %d num_6ghz_reg_rules_sp: %d num_6ghz_reg_rules_vlp: %d",
|
||
|
+ num_6ghz_client[WMI_REG_INDOOR_AP][j],
|
||
|
+ num_6ghz_client[WMI_REG_STANDARD_POWER_AP][j],
|
||
|
+ num_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][j]);
|
||
|
+
|
||
|
+ ext_wmi_reg_rule =
|
||
|
+ (struct wmi_regulatory_ext_rule *)((u8 *)ext_chan_list_event_hdr
|
||
|
+ + sizeof(*ext_chan_list_event_hdr)
|
||
|
+ + sizeof(struct wmi_tlv));
|
||
|
+ if (num_2ghz_reg_rules) {
|
||
|
+ reg_info->reg_rules_2ghz_ptr =
|
||
|
+ create_ext_reg_rules_from_wmi(num_2ghz_reg_rules,
|
||
|
+ ext_wmi_reg_rule);
|
||
|
+
|
||
|
+ if (!reg_info->reg_rules_2ghz_ptr) {
|
||
|
+ kfree(tb);
|
||
|
+ ath11k_warn(ab, "Unable to Allocate memory for 2 GHz rules\n");
|
||
|
+ return -ENOMEM;
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ ext_wmi_reg_rule += num_2ghz_reg_rules;
|
||
|
+
|
||
|
+ /* Firmware might include 6 GHz reg rule in 5 GHz rule list
|
||
|
+ * for few countries along with separate 6 GHz rule.
|
||
|
+ * Having same 6 GHz reg rule in 5 GHz and 6 GHz rules list
|
||
|
+ * causes intersect check to be true, and same rules will be
|
||
|
+ * shown multiple times in iw cmd.
|
||
|
+ * Hence, avoid parsing 6 GHz rule from 5 GHz reg rule list
|
||
|
+ */
|
||
|
+ num_invalid_5ghz_ext_rules =
|
||
|
+ ath11k_invalid_5ghz_reg_ext_rules_from_wmi(num_5ghz_reg_rules,
|
||
|
+ ext_wmi_reg_rule);
|
||
|
+
|
||
|
+ if (num_invalid_5ghz_ext_rules) {
|
||
|
+ ath11k_dbg(ab, ATH11K_DBG_WMI,
|
||
|
+ "CC: %s 5 GHz reg rules number %d from fw, %d number of invalid 5 GHz rules",
|
||
|
+ reg_info->alpha2, reg_info->num_5ghz_reg_rules,
|
||
|
+ num_invalid_5ghz_ext_rules);
|
||
|
+
|
||
|
+ num_5ghz_reg_rules = num_5ghz_reg_rules - num_invalid_5ghz_ext_rules;
|
||
|
+ reg_info->num_5ghz_reg_rules = num_5ghz_reg_rules;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (num_5ghz_reg_rules) {
|
||
|
+ reg_info->reg_rules_5ghz_ptr =
|
||
|
+ create_ext_reg_rules_from_wmi(num_5ghz_reg_rules,
|
||
|
+ ext_wmi_reg_rule);
|
||
|
+
|
||
|
+ if (!reg_info->reg_rules_5ghz_ptr) {
|
||
|
+ kfree(tb);
|
||
|
+ ath11k_warn(ab, "Unable to Allocate memory for 5 GHz rules\n");
|
||
|
+ return -ENOMEM;
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ /* We have adjusted the number of 5 GHz reg rules above. But still those
|
||
|
+ * many rules needs to be adjusted in ext_wmi_reg_rule.
|
||
|
+ *
|
||
|
+ * NOTE: num_invalid_5ghz_ext_rules will be 0 for rest other cases.
|
||
|
+ */
|
||
|
+ ext_wmi_reg_rule += (num_5ghz_reg_rules + num_invalid_5ghz_ext_rules);
|
||
|
+
|
||
|
+ for (i = 0; i < WMI_REG_CURRENT_MAX_AP_TYPE; i++) {
|
||
|
+ reg_info->reg_rules_6ghz_ap_ptr[i] =
|
||
|
+ create_ext_reg_rules_from_wmi(num_6ghz_reg_rules_ap[i],
|
||
|
+ ext_wmi_reg_rule);
|
||
|
+
|
||
|
+ if (!reg_info->reg_rules_6ghz_ap_ptr[i]) {
|
||
|
+ kfree(tb);
|
||
|
+ ath11k_warn(ab, "Unable to Allocate memory for 6 GHz AP rules\n");
|
||
|
+ return -ENOMEM;
|
||
|
+ }
|
||
|
+
|
||
|
+ ext_wmi_reg_rule += num_6ghz_reg_rules_ap[i];
|
||
|
+ }
|
||
|
+
|
||
|
+ for (j = 0; j < WMI_REG_CURRENT_MAX_AP_TYPE; j++) {
|
||
|
+ for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++) {
|
||
|
+ reg_info->reg_rules_6ghz_client_ptr[j][i] =
|
||
|
+ create_ext_reg_rules_from_wmi(num_6ghz_client[j][i],
|
||
|
+ ext_wmi_reg_rule);
|
||
|
+
|
||
|
+ if (!reg_info->reg_rules_6ghz_client_ptr[j][i]) {
|
||
|
+ kfree(tb);
|
||
|
+ ath11k_warn(ab, "Unable to Allocate memory for 6 GHz client rules\n");
|
||
|
+ return -ENOMEM;
|
||
|
+ }
|
||
|
+
|
||
|
+ ext_wmi_reg_rule += num_6ghz_client[j][i];
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ reg_info->client_type = ext_chan_list_event_hdr->client_type;
|
||
|
+ reg_info->rnr_tpe_usable = ext_chan_list_event_hdr->rnr_tpe_usable;
|
||
|
+ reg_info->unspecified_ap_usable =
|
||
|
+ ext_chan_list_event_hdr->unspecified_ap_usable;
|
||
|
+ reg_info->domain_code_6ghz_ap[WMI_REG_INDOOR_AP] =
|
||
|
+ ext_chan_list_event_hdr->domain_code_6ghz_ap_lpi;
|
||
|
+ reg_info->domain_code_6ghz_ap[WMI_REG_STANDARD_POWER_AP] =
|
||
|
+ ext_chan_list_event_hdr->domain_code_6ghz_ap_sp;
|
||
|
+ reg_info->domain_code_6ghz_ap[WMI_REG_VERY_LOW_POWER_AP] =
|
||
|
+ ext_chan_list_event_hdr->domain_code_6ghz_ap_vlp;
|
||
|
+
|
||
|
+ for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++) {
|
||
|
+ reg_info->domain_code_6ghz_client[WMI_REG_INDOOR_AP][i] =
|
||
|
+ ext_chan_list_event_hdr->domain_code_6ghz_client_lpi[i];
|
||
|
+ reg_info->domain_code_6ghz_client[WMI_REG_STANDARD_POWER_AP][i] =
|
||
|
+ ext_chan_list_event_hdr->domain_code_6ghz_client_sp[i];
|
||
|
+ reg_info->domain_code_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][i] =
|
||
|
+ ext_chan_list_event_hdr->domain_code_6ghz_client_vlp[i];
|
||
|
+ }
|
||
|
+
|
||
|
+ reg_info->domain_code_6ghz_super_id =
|
||
|
+ ext_chan_list_event_hdr->domain_code_6ghz_super_id;
|
||
|
+
|
||
|
+ ath11k_dbg(ab, ATH11K_DBG_WMI, "6 GHz client_type: %d domain_code_6ghz_super_id: %d",
|
||
|
+ reg_info->client_type, reg_info->domain_code_6ghz_super_id);
|
||
|
+
|
||
|
+ ath11k_dbg(ab, ATH11K_DBG_WMI, "processed regulatory ext channel list\n");
|
||
|
+
|
||
|
+ kfree(tb);
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
static int ath11k_pull_peer_del_resp_ev(struct ath11k_base *ab, struct sk_buff *skb,
|
||
|
struct wmi_peer_delete_resp_event *peer_del_resp)
|
||
|
{
|
||
|
@@ -6507,12 +6876,14 @@ static bool ath11k_reg_is_world_alpha(ch
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
-static int ath11k_reg_chan_list_event(struct ath11k_base *ab, struct sk_buff *skb)
|
||
|
+static int ath11k_reg_chan_list_event(struct ath11k_base *ab,
|
||
|
+ struct sk_buff *skb,
|
||
|
+ enum wmi_reg_chan_list_cmd_type id)
|
||
|
{
|
||
|
struct cur_regulatory_info *reg_info = NULL;
|
||
|
struct ieee80211_regdomain *regd = NULL;
|
||
|
bool intersect = false;
|
||
|
- int ret = 0, pdev_idx;
|
||
|
+ int ret = 0, pdev_idx, i, j;
|
||
|
struct ath11k *ar;
|
||
|
|
||
|
reg_info = kzalloc(sizeof(*reg_info), GFP_ATOMIC);
|
||
|
@@ -6521,7 +6892,11 @@ static int ath11k_reg_chan_list_event(st
|
||
|
goto fallback;
|
||
|
}
|
||
|
|
||
|
- ret = ath11k_pull_reg_chan_list_update_ev(ab, skb, reg_info);
|
||
|
+ if (id == WMI_REG_CHAN_LIST_CC_ID)
|
||
|
+ ret = ath11k_pull_reg_chan_list_update_ev(ab, skb, reg_info);
|
||
|
+ else
|
||
|
+ ret = ath11k_pull_reg_chan_list_ext_update_ev(ab, skb, reg_info);
|
||
|
+
|
||
|
if (ret) {
|
||
|
ath11k_warn(ab, "failed to extract regulatory info from received event\n");
|
||
|
goto fallback;
|
||
|
@@ -6623,6 +6998,14 @@ mem_free:
|
||
|
if (reg_info) {
|
||
|
kfree(reg_info->reg_rules_2ghz_ptr);
|
||
|
kfree(reg_info->reg_rules_5ghz_ptr);
|
||
|
+ if (reg_info->is_ext_reg_event) {
|
||
|
+ for (i = 0; i < WMI_REG_CURRENT_MAX_AP_TYPE; i++)
|
||
|
+ kfree(reg_info->reg_rules_6ghz_ap_ptr[i]);
|
||
|
+
|
||
|
+ for (j = 0; j < WMI_REG_CURRENT_MAX_AP_TYPE; j++)
|
||
|
+ for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++)
|
||
|
+ kfree(reg_info->reg_rules_6ghz_client_ptr[j][i]);
|
||
|
+ }
|
||
|
kfree(reg_info);
|
||
|
}
|
||
|
return ret;
|
||
|
@@ -8054,7 +8437,10 @@ static void ath11k_wmi_tlv_op_rx(struct
|
||
|
ath11k_service_ready_ext2_event(ab, skb);
|
||
|
break;
|
||
|
case WMI_REG_CHAN_LIST_CC_EVENTID:
|
||
|
- ath11k_reg_chan_list_event(ab, skb);
|
||
|
+ ath11k_reg_chan_list_event(ab, skb, WMI_REG_CHAN_LIST_CC_ID);
|
||
|
+ break;
|
||
|
+ case WMI_REG_CHAN_LIST_CC_EXT_EVENTID:
|
||
|
+ ath11k_reg_chan_list_event(ab, skb, WMI_REG_CHAN_LIST_CC_EXT_ID);
|
||
|
break;
|
||
|
case WMI_READY_EVENTID:
|
||
|
ath11k_ready_event(ab, skb);
|
||
|
--- a/drivers/net/wireless/ath/ath11k/wmi.h
|
||
|
+++ b/drivers/net/wireless/ath/ath11k/wmi.h
|
||
|
@@ -797,6 +797,7 @@ enum wmi_tlv_event_id {
|
||
|
WMI_RMC_NEW_LEADER_EVENTID = WMI_TLV_CMD(WMI_GRP_RMC),
|
||
|
WMI_REG_CHAN_LIST_CC_EVENTID = WMI_TLV_CMD(WMI_GRP_REGULATORY),
|
||
|
WMI_11D_NEW_COUNTRY_EVENTID,
|
||
|
+ WMI_REG_CHAN_LIST_CC_EXT_EVENTID,
|
||
|
WMI_NDI_CAP_RSP_EVENTID = WMI_TLV_CMD(WMI_GRP_PROTOTYPE),
|
||
|
WMI_NDP_INITIATOR_RSP_EVENTID,
|
||
|
WMI_NDP_RESPONDER_RSP_EVENTID,
|
||
|
@@ -1865,6 +1866,8 @@ enum wmi_tlv_tag {
|
||
|
WMI_TAG_PDEV_SRG_OBSS_BSSID_ENABLE_BITMAP_CMD,
|
||
|
WMI_TAG_PDEV_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMD,
|
||
|
WMI_TAG_PDEV_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMD,
|
||
|
+ WMI_TAG_REGULATORY_RULE_EXT_STRUCT = 0x3A9,
|
||
|
+ WMI_TAG_REG_CHAN_LIST_CC_EXT_EVENT,
|
||
|
WMI_TAG_PDEV_SET_BIOS_SAR_TABLE_CMD = 0x3D8,
|
||
|
WMI_TAG_PDEV_SET_BIOS_GEO_TABLE_CMD,
|
||
|
WMI_TAG_MAX
|
||
|
@@ -2097,6 +2100,7 @@ enum wmi_tlv_service {
|
||
|
|
||
|
/* The second 128 bits */
|
||
|
WMI_MAX_EXT_SERVICE = 256,
|
||
|
+ WMI_TLV_SERVICE_REG_CC_EXT_EVENT_SUPPORT = 281,
|
||
|
WMI_TLV_SERVICE_BIOS_SAR_SUPPORT = 326,
|
||
|
|
||
|
/* The third 128 bits */
|
||
|
@@ -2313,6 +2317,8 @@ struct wmi_init_cmd {
|
||
|
#define WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64 BIT(5)
|
||
|
#define WMI_RSRC_CFG_FLAG1_ACK_RSSI BIT(18)
|
||
|
|
||
|
+#define WMI_CFG_HOST_SERVICE_FLAG_REG_CC_EXT 4
|
||
|
+
|
||
|
struct wmi_resource_config {
|
||
|
u32 tlv_header;
|
||
|
u32 num_vdevs;
|
||
|
@@ -2372,6 +2378,15 @@ struct wmi_resource_config {
|
||
|
u32 sched_params;
|
||
|
u32 twt_ap_pdev_count;
|
||
|
u32 twt_ap_sta_count;
|
||
|
+ u32 max_nlo_ssids;
|
||
|
+ u32 num_pkt_filters;
|
||
|
+ u32 num_max_sta_vdevs;
|
||
|
+ u32 max_bssid_indicator;
|
||
|
+ u32 ul_resp_config;
|
||
|
+ u32 msdu_flow_override_config0;
|
||
|
+ u32 msdu_flow_override_config1;
|
||
|
+ u32 flags2;
|
||
|
+ u32 host_service_flags;
|
||
|
} __packed;
|
||
|
|
||
|
struct wmi_service_ready_event {
|
||
|
@@ -2854,6 +2869,8 @@ struct rx_reorder_queue_remove_params {
|
||
|
#define REG_RULE_MAX_BW 0x0000ffff
|
||
|
#define REG_RULE_REG_PWR 0x00ff0000
|
||
|
#define REG_RULE_ANT_GAIN 0xff000000
|
||
|
+#define REG_RULE_PSD_INFO BIT(0)
|
||
|
+#define REG_RULE_PSD_EIRP 0xff0000
|
||
|
|
||
|
#define WMI_VDEV_PARAM_TXBF_SU_TX_BFEE BIT(0)
|
||
|
#define WMI_VDEV_PARAM_TXBF_MU_TX_BFEE BIT(1)
|
||
|
@@ -4049,6 +4066,7 @@ struct wmi_he_rate_set {
|
||
|
|
||
|
#define MAX_REG_RULES 10
|
||
|
#define REG_ALPHA2_LEN 2
|
||
|
+#define MAX_6GHZ_REG_RULES 5
|
||
|
|
||
|
enum wmi_start_event_param {
|
||
|
WMI_VDEV_START_RESP_EVENT = 0,
|
||
|
@@ -4079,16 +4097,6 @@ enum wmi_vdev_start_resp_status_code {
|
||
|
WMI_VDEV_START_RESPONSE_INVALID_REGDOMAIN = 4,
|
||
|
};
|
||
|
|
||
|
-;
|
||
|
-enum cc_setting_code {
|
||
|
- REG_SET_CC_STATUS_PASS = 0,
|
||
|
- REG_CURRENT_ALPHA2_NOT_FOUND = 1,
|
||
|
- REG_INIT_ALPHA2_NOT_FOUND = 2,
|
||
|
- REG_SET_CC_CHANGE_NOT_ALLOWED = 3,
|
||
|
- REG_SET_CC_STATUS_NO_MEMORY = 4,
|
||
|
- REG_SET_CC_STATUS_FAIL = 5,
|
||
|
-};
|
||
|
-
|
||
|
/* Regaulatory Rule Flags Passed by FW */
|
||
|
#define REGULATORY_CHAN_DISABLED BIT(0)
|
||
|
#define REGULATORY_CHAN_NO_IR BIT(1)
|
||
|
@@ -4102,13 +4110,72 @@ enum cc_setting_code {
|
||
|
#define REGULATORY_CHAN_NO_20MHZ BIT(11)
|
||
|
#define REGULATORY_CHAN_NO_10MHZ BIT(12)
|
||
|
|
||
|
-enum {
|
||
|
+enum wmi_reg_chan_list_cmd_type {
|
||
|
+ WMI_REG_CHAN_LIST_CC_ID = 0,
|
||
|
+ WMI_REG_CHAN_LIST_CC_EXT_ID = 1,
|
||
|
+};
|
||
|
+
|
||
|
+enum wmi_reg_cc_setting_code {
|
||
|
WMI_REG_SET_CC_STATUS_PASS = 0,
|
||
|
WMI_REG_CURRENT_ALPHA2_NOT_FOUND = 1,
|
||
|
WMI_REG_INIT_ALPHA2_NOT_FOUND = 2,
|
||
|
WMI_REG_SET_CC_CHANGE_NOT_ALLOWED = 3,
|
||
|
WMI_REG_SET_CC_STATUS_NO_MEMORY = 4,
|
||
|
WMI_REG_SET_CC_STATUS_FAIL = 5,
|
||
|
+
|
||
|
+ /* add new setting code above, update in
|
||
|
+ * @enum cc_setting_code as well.
|
||
|
+ * Also handle it in ath11k_wmi_cc_setting_code_to_reg()
|
||
|
+ */
|
||
|
+};
|
||
|
+
|
||
|
+enum cc_setting_code {
|
||
|
+ REG_SET_CC_STATUS_PASS = 0,
|
||
|
+ REG_CURRENT_ALPHA2_NOT_FOUND = 1,
|
||
|
+ REG_INIT_ALPHA2_NOT_FOUND = 2,
|
||
|
+ REG_SET_CC_CHANGE_NOT_ALLOWED = 3,
|
||
|
+ REG_SET_CC_STATUS_NO_MEMORY = 4,
|
||
|
+ REG_SET_CC_STATUS_FAIL = 5,
|
||
|
+
|
||
|
+ /* add new setting code above, update in
|
||
|
+ * @enum wmi_reg_cc_setting_code as well.
|
||
|
+ */
|
||
|
+};
|
||
|
+
|
||
|
+static inline enum cc_setting_code
|
||
|
+ath11k_wmi_cc_setting_code_to_reg(enum wmi_reg_cc_setting_code status_code)
|
||
|
+{
|
||
|
+ switch (status_code) {
|
||
|
+ case WMI_REG_SET_CC_STATUS_PASS:
|
||
|
+ return REG_SET_CC_STATUS_PASS;
|
||
|
+ case WMI_REG_CURRENT_ALPHA2_NOT_FOUND:
|
||
|
+ return REG_CURRENT_ALPHA2_NOT_FOUND;
|
||
|
+ case WMI_REG_INIT_ALPHA2_NOT_FOUND:
|
||
|
+ return REG_INIT_ALPHA2_NOT_FOUND;
|
||
|
+ case WMI_REG_SET_CC_CHANGE_NOT_ALLOWED:
|
||
|
+ return REG_SET_CC_CHANGE_NOT_ALLOWED;
|
||
|
+ case WMI_REG_SET_CC_STATUS_NO_MEMORY:
|
||
|
+ return REG_SET_CC_STATUS_NO_MEMORY;
|
||
|
+ case WMI_REG_SET_CC_STATUS_FAIL:
|
||
|
+ return REG_SET_CC_STATUS_FAIL;
|
||
|
+ }
|
||
|
+
|
||
|
+ return REG_SET_CC_STATUS_FAIL;
|
||
|
+}
|
||
|
+
|
||
|
+enum wmi_reg_6ghz_ap_type {
|
||
|
+ WMI_REG_INDOOR_AP = 0,
|
||
|
+ WMI_REG_STANDARD_POWER_AP = 1,
|
||
|
+ WMI_REG_VERY_LOW_POWER_AP = 2,
|
||
|
+
|
||
|
+ WMI_REG_CURRENT_MAX_AP_TYPE,
|
||
|
+ WMI_REG_MAX_AP_TYPE = 7,
|
||
|
+};
|
||
|
+
|
||
|
+enum wmi_reg_6ghz_client_type {
|
||
|
+ WMI_REG_DEFAULT_CLIENT = 0,
|
||
|
+ WMI_REG_SUBORDINATE_CLIENT = 1,
|
||
|
+ WMI_REG_MAX_CLIENT_TYPE = 2,
|
||
|
};
|
||
|
|
||
|
struct cur_reg_rule {
|
||
|
@@ -4118,6 +4185,8 @@ struct cur_reg_rule {
|
||
|
u8 reg_power;
|
||
|
u8 ant_gain;
|
||
|
u16 flags;
|
||
|
+ bool psd_flag;
|
||
|
+ s8 psd_eirp;
|
||
|
};
|
||
|
|
||
|
struct cur_regulatory_info {
|
||
|
@@ -4137,6 +4206,22 @@ struct cur_regulatory_info {
|
||
|
u32 num_5ghz_reg_rules;
|
||
|
struct cur_reg_rule *reg_rules_2ghz_ptr;
|
||
|
struct cur_reg_rule *reg_rules_5ghz_ptr;
|
||
|
+ bool is_ext_reg_event;
|
||
|
+ enum wmi_reg_6ghz_client_type client_type;
|
||
|
+ bool rnr_tpe_usable;
|
||
|
+ bool unspecified_ap_usable;
|
||
|
+ u8 domain_code_6ghz_ap[WMI_REG_CURRENT_MAX_AP_TYPE];
|
||
|
+ u8 domain_code_6ghz_client[WMI_REG_CURRENT_MAX_AP_TYPE][WMI_REG_MAX_CLIENT_TYPE];
|
||
|
+ u32 domain_code_6ghz_super_id;
|
||
|
+ u32 min_bw_6ghz_ap[WMI_REG_CURRENT_MAX_AP_TYPE];
|
||
|
+ u32 max_bw_6ghz_ap[WMI_REG_CURRENT_MAX_AP_TYPE];
|
||
|
+ u32 min_bw_6ghz_client[WMI_REG_CURRENT_MAX_AP_TYPE][WMI_REG_MAX_CLIENT_TYPE];
|
||
|
+ u32 max_bw_6ghz_client[WMI_REG_CURRENT_MAX_AP_TYPE][WMI_REG_MAX_CLIENT_TYPE];
|
||
|
+ u32 num_6ghz_rules_ap[WMI_REG_CURRENT_MAX_AP_TYPE];
|
||
|
+ u32 num_6ghz_rules_client[WMI_REG_CURRENT_MAX_AP_TYPE][WMI_REG_MAX_CLIENT_TYPE];
|
||
|
+ struct cur_reg_rule *reg_rules_6ghz_ap_ptr[WMI_REG_CURRENT_MAX_AP_TYPE];
|
||
|
+ struct cur_reg_rule *reg_rules_6ghz_client_ptr
|
||
|
+ [WMI_REG_CURRENT_MAX_AP_TYPE][WMI_REG_MAX_CLIENT_TYPE];
|
||
|
};
|
||
|
|
||
|
struct wmi_reg_chan_list_cc_event {
|
||
|
@@ -4163,6 +4248,61 @@ struct wmi_regulatory_rule_struct {
|
||
|
u32 flag_info;
|
||
|
};
|
||
|
|
||
|
+#define WMI_REG_CLIENT_MAX 4
|
||
|
+
|
||
|
+struct wmi_reg_chan_list_cc_ext_event {
|
||
|
+ u32 status_code;
|
||
|
+ u32 phy_id;
|
||
|
+ u32 alpha2;
|
||
|
+ u32 num_phy;
|
||
|
+ u32 country_id;
|
||
|
+ u32 domain_code;
|
||
|
+ u32 dfs_region;
|
||
|
+ u32 phybitmap;
|
||
|
+ u32 min_bw_2ghz;
|
||
|
+ u32 max_bw_2ghz;
|
||
|
+ u32 min_bw_5ghz;
|
||
|
+ u32 max_bw_5ghz;
|
||
|
+ u32 num_2ghz_reg_rules;
|
||
|
+ u32 num_5ghz_reg_rules;
|
||
|
+ u32 client_type;
|
||
|
+ u32 rnr_tpe_usable;
|
||
|
+ u32 unspecified_ap_usable;
|
||
|
+ u32 domain_code_6ghz_ap_lpi;
|
||
|
+ u32 domain_code_6ghz_ap_sp;
|
||
|
+ u32 domain_code_6ghz_ap_vlp;
|
||
|
+ u32 domain_code_6ghz_client_lpi[WMI_REG_CLIENT_MAX];
|
||
|
+ u32 domain_code_6ghz_client_sp[WMI_REG_CLIENT_MAX];
|
||
|
+ u32 domain_code_6ghz_client_vlp[WMI_REG_CLIENT_MAX];
|
||
|
+ u32 domain_code_6ghz_super_id;
|
||
|
+ u32 min_bw_6ghz_ap_sp;
|
||
|
+ u32 max_bw_6ghz_ap_sp;
|
||
|
+ u32 min_bw_6ghz_ap_lpi;
|
||
|
+ u32 max_bw_6ghz_ap_lpi;
|
||
|
+ u32 min_bw_6ghz_ap_vlp;
|
||
|
+ u32 max_bw_6ghz_ap_vlp;
|
||
|
+ u32 min_bw_6ghz_client_sp[WMI_REG_CLIENT_MAX];
|
||
|
+ u32 max_bw_6ghz_client_sp[WMI_REG_CLIENT_MAX];
|
||
|
+ u32 min_bw_6ghz_client_lpi[WMI_REG_CLIENT_MAX];
|
||
|
+ u32 max_bw_6ghz_client_lpi[WMI_REG_CLIENT_MAX];
|
||
|
+ u32 min_bw_6ghz_client_vlp[WMI_REG_CLIENT_MAX];
|
||
|
+ u32 max_bw_6ghz_client_vlp[WMI_REG_CLIENT_MAX];
|
||
|
+ u32 num_6ghz_reg_rules_ap_sp;
|
||
|
+ u32 num_6ghz_reg_rules_ap_lpi;
|
||
|
+ u32 num_6ghz_reg_rules_ap_vlp;
|
||
|
+ u32 num_6ghz_reg_rules_client_sp[WMI_REG_CLIENT_MAX];
|
||
|
+ u32 num_6ghz_reg_rules_client_lpi[WMI_REG_CLIENT_MAX];
|
||
|
+ u32 num_6ghz_reg_rules_client_vlp[WMI_REG_CLIENT_MAX];
|
||
|
+} __packed;
|
||
|
+
|
||
|
+struct wmi_regulatory_ext_rule {
|
||
|
+ u32 tlv_header;
|
||
|
+ u32 freq_info;
|
||
|
+ u32 bw_pwr_info;
|
||
|
+ u32 flag_info;
|
||
|
+ u32 psd_power_info;
|
||
|
+} __packed;
|
||
|
+
|
||
|
struct wmi_vdev_delete_resp_event {
|
||
|
u32 vdev_id;
|
||
|
} __packed;
|
||
|
@@ -5358,6 +5498,7 @@ struct target_resource_config {
|
||
|
u32 sched_params;
|
||
|
u32 twt_ap_pdev_count;
|
||
|
u32 twt_ap_sta_count;
|
||
|
+ u8 is_reg_cc_ext_event_supported;
|
||
|
};
|
||
|
|
||
|
enum wmi_debug_log_param {
|