From patchwork Tue Oct 26 11:18:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wen Gong X-Patchwork-Id: 12584561 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 78813C433EF for ; Tue, 26 Oct 2021 11:19:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 617AC60238 for ; Tue, 26 Oct 2021 11:19:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234734AbhJZLWO (ORCPT ); Tue, 26 Oct 2021 07:22:14 -0400 Received: from alexa-out.qualcomm.com ([129.46.98.28]:47817 "EHLO alexa-out.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234304AbhJZLWN (ORCPT ); Tue, 26 Oct 2021 07:22:13 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1635247190; x=1666783190; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=dszUnoqU0uc1i+dM0m8lC2i9LJBR6A/k9YFSwTfixNs=; b=E8GFzuzNtPpq5cJwzeGHLK0bWO4aKW8rY1VcK2dyPYYC6nLmvYq+eeKd CdA02gBIgAKAEiWQfi8pycCHpWYr2e7ABcO6MULp6eCHX3jUlTiWn9xK/ AHNt9rpXFgN3r3XdIi4F7QuIJqXjS7gkR6IJGeS64tZR2fHypWv7KiPe0 Q=; Received: from ironmsg08-lv.qualcomm.com ([10.47.202.152]) by alexa-out.qualcomm.com with ESMTP; 26 Oct 2021 04:19:49 -0700 X-QCInternal: smtphost Received: from nalasex01a.na.qualcomm.com ([10.47.209.196]) by ironmsg08-lv.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Oct 2021 04:19:49 -0700 Received: from wgong-HP3-Z230-SFF-Workstation.qca.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.922.7; Tue, 26 Oct 2021 04:19:48 -0700 From: Wen Gong To: CC: , Subject: [PATCH 01/15] ath11k: add support for extended wmi service bit Date: Tue, 26 Oct 2021 07:18:59 -0400 Message-ID: <20211026111913.7346-2-quic_wgong@quicinc.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211026111913.7346-1-quic_wgong@quicinc.com> References: <20211026111913.7346-1-quic_wgong@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To nalasex01a.na.qualcomm.com (10.47.209.196) Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org The max wmi service bit is 256 in ath11k, Extend it for more wmi service bit. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1 Signed-off-by: Wen Gong --- drivers/net/wireless/ath/ath11k/wmi.c | 81 ++++++++++++++++----------- drivers/net/wireless/ath/ath11k/wmi.h | 6 +- 2 files changed, 53 insertions(+), 34 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c index 51b694c1f948..69c7b8355e52 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -6626,47 +6626,64 @@ static void ath11k_vdev_install_key_compl_event(struct ath11k_base *ab, rcu_read_unlock(); } -static void ath11k_service_available_event(struct ath11k_base *ab, struct sk_buff *skb) +static int ath11k_wmi_tlv_services_parser(struct ath11k_base *ab, + u16 tag, u16 len, + const void *ptr, void *data) { - const void **tb; const struct wmi_service_available_event *ev; - int ret; + u32 *wmi_ext2_service_bitmap; int i, j; - 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; - } + switch (tag) { + case WMI_TAG_SERVICE_AVAILABLE_EVENT: + ev = (struct wmi_service_available_event *)ptr; + for (i = 0, j = WMI_MAX_SERVICE; + i < WMI_SERVICE_SEGMENT_BM_SIZE32 && j < WMI_MAX_EXT_SERVICE; + i++) { + do { + if (ev->wmi_service_segment_bitmap[i] & + BIT(j % WMI_AVAIL_SERVICE_BITS_IN_SIZE32)) + set_bit(j, ab->wmi_ab.svc_map); + } while (++j % WMI_AVAIL_SERVICE_BITS_IN_SIZE32); + } - ev = tb[WMI_TAG_SERVICE_AVAILABLE_EVENT]; - if (!ev) { - ath11k_warn(ab, "failed to fetch svc available ev"); - kfree(tb); - return; - } + ath11k_dbg(ab, ATH11K_DBG_WMI, + "wmi_ext_service_bitmap 0:0x%04x, 1:0x%04x, 2:0x%04x, 3:0x%04x", + ev->wmi_service_segment_bitmap[0], + ev->wmi_service_segment_bitmap[1], + ev->wmi_service_segment_bitmap[2], + ev->wmi_service_segment_bitmap[3]); + break; + case WMI_TAG_ARRAY_UINT32: + wmi_ext2_service_bitmap = (u32 *)ptr; + for (i = 0, j = WMI_MAX_EXT_SERVICE; + i < WMI_SERVICE_SEGMENT_BM_SIZE32 && j < WMI_MAX_EXT2_SERVICE; + i++) { + do { + if (wmi_ext2_service_bitmap[i] & + BIT(j % WMI_AVAIL_SERVICE_BITS_IN_SIZE32)) + set_bit(j, ab->wmi_ab.svc_map); + } while (++j % WMI_AVAIL_SERVICE_BITS_IN_SIZE32); + } - /* TODO: Use wmi_service_segment_offset information to get the service - * especially when more services are advertised in multiple sevice - * available events. - */ - for (i = 0, j = WMI_MAX_SERVICE; - i < WMI_SERVICE_SEGMENT_BM_SIZE32 && j < WMI_MAX_EXT_SERVICE; - i++) { - do { - if (ev->wmi_service_segment_bitmap[i] & - BIT(j % WMI_AVAIL_SERVICE_BITS_IN_SIZE32)) - set_bit(j, ab->wmi_ab.svc_map); - } while (++j % WMI_AVAIL_SERVICE_BITS_IN_SIZE32); + ath11k_dbg(ab, ATH11K_DBG_WMI, + "wmi_ext2_service__bitmap 0:0x%04x, 1:0x%04x, 2:0x%04x, 3:0x%04x", + wmi_ext2_service_bitmap[0], wmi_ext2_service_bitmap[1], + wmi_ext2_service_bitmap[2], wmi_ext2_service_bitmap[3]); + break; } + return 0; +} - ath11k_dbg(ab, ATH11K_DBG_WMI, - "wmi_ext_service_bitmap 0:0x%x, 1:0x%x, 2:0x%x, 3:0x%x", - ev->wmi_service_segment_bitmap[0], ev->wmi_service_segment_bitmap[1], - ev->wmi_service_segment_bitmap[2], ev->wmi_service_segment_bitmap[3]); +static void ath11k_service_available_event(struct ath11k_base *ab, struct sk_buff *skb) +{ + int ret; - kfree(tb); + ret = ath11k_wmi_tlv_iter(ab, skb->data, skb->len, + ath11k_wmi_tlv_services_parser, + NULL); + if (ret) + ath11k_warn(ab, "failed to parse services available tlv %d\n", ret); } static void ath11k_peer_assoc_conf_event(struct ath11k_base *ab, struct sk_buff *skb) diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h index e1809ae8d628..79e9140b40d0 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.h +++ b/drivers/net/wireless/ath/ath11k/wmi.h @@ -2059,7 +2059,9 @@ enum wmi_tlv_service { WMI_TLV_SERVICE_EXT2_MSG = 220, WMI_TLV_SERVICE_SRG_SRP_SPATIAL_REUSE_SUPPORT = 249, - WMI_MAX_EXT_SERVICE + WMI_MAX_EXT_SERVICE = 256, + + WMI_MAX_EXT2_SERVICE }; enum { @@ -5066,7 +5068,7 @@ struct ath11k_wmi_base { struct completion service_ready; struct completion unified_ready; - DECLARE_BITMAP(svc_map, WMI_MAX_EXT_SERVICE); + DECLARE_BITMAP(svc_map, WMI_MAX_EXT2_SERVICE); wait_queue_head_t tx_credits_wq; const struct wmi_peer_flags_map *peer_flags; u32 num_mem_chunks; From patchwork Tue Oct 26 11:19:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wen Gong X-Patchwork-Id: 12584563 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 33062C433F5 for ; Tue, 26 Oct 2021 11:19:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1C8A560238 for ; Tue, 26 Oct 2021 11:19:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234304AbhJZLWP (ORCPT ); Tue, 26 Oct 2021 07:22:15 -0400 Received: from alexa-out.qualcomm.com ([129.46.98.28]:47817 "EHLO alexa-out.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234475AbhJZLWO (ORCPT ); Tue, 26 Oct 2021 07:22:14 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1635247191; x=1666783191; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=J1ObEXw5Z+lVr0sJqYope9tZrWqDzCZAkTBcMGLQ680=; b=NlL+PPCsqNpbrEZyexw4rXd9KGHRZ9rPZH6Jtan8Q8lhqrWwHeGxex7W wQouGNn1VBfWU0H1+4EEG0Wh090rVEedkL6XQYYm76VU6ase805ka0WTj sZV34K+4s/zqqnWXlK9I6cXpLhKN6LLAtusrq4MWdBltq0dpzHWbnD8hH Y=; Received: from ironmsg-lv-alpha.qualcomm.com ([10.47.202.13]) by alexa-out.qualcomm.com with ESMTP; 26 Oct 2021 04:19:51 -0700 X-QCInternal: smtphost Received: from nalasex01a.na.qualcomm.com ([10.47.209.196]) by ironmsg-lv-alpha.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Oct 2021 04:19:51 -0700 Received: from wgong-HP3-Z230-SFF-Workstation.qca.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.922.7; Tue, 26 Oct 2021 04:19:49 -0700 From: Wen Gong To: CC: , Subject: [PATCH 02/15] ath11k: Add support to parse new wmi event for 6 GHz regulatory Date: Tue, 26 Oct 2021 07:19:00 -0400 Message-ID: <20211026111913.7346-3-quic_wgong@quicinc.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211026111913.7346-1-quic_wgong@quicinc.com> References: <20211026111913.7346-1-quic_wgong@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To nalasex01a.na.qualcomm.com (10.47.209.196) Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org In order to support different power levels of 6 GHz AP and client, new wmi event for regulatory was added in firmware(WMI_REG_CHAN_LIST_CC_EXT_EVENTID) to provide new parameters required for 6 GHz regulatory rules. firmware advertises its capability of handling new event in wmi service ready event. Based on that, host needs to set host_service_flags in wmi init command to indicate that host supports processing of new wmi event. Based on advertised host capability, firmware decides to send old event (WMI_REG_CHAN_LIST_CC_EVENTID) or new event(WMI_REG_CHAN_LIST_CC_EXT_EVENTID). Add support for parsing 2.4 GHz/5 GHz/6 GHz reg rules and other parameters from WMI_REG_CHAN_LIST_CC_EXT_EVENTID, to populate the channel lists. Since 6 GHz requires additional power value fields(PSD info), update reg rule parsing function. Signed-off-by: Lavanya Suresh Signed-off-by: Wen Gong --- drivers/net/wireless/ath/ath11k/core.c | 1 + drivers/net/wireless/ath/ath11k/core.h | 6 + drivers/net/wireless/ath/ath11k/hw.h | 1 + drivers/net/wireless/ath/ath11k/reg.c | 37 ++- drivers/net/wireless/ath/ath11k/wmi.c | 378 ++++++++++++++++++++++++- drivers/net/wireless/ath/ath11k/wmi.h | 118 ++++++++ 6 files changed, 530 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index b8c95300f34a..66ceef24532d 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -230,6 +230,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .supports_suspend = true, .hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855), .fix_l1ss = false, + .support_ext_cc = true, }, }; diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index 67b843a92344..a65f7d00eea2 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -966,4 +966,10 @@ static inline const char *ath11k_bus_str(enum ath11k_bus bus) return "unknown"; } +static inline bool ath11k_support_cc_ext(struct ath11k_base *ab) +{ + return ab->hw_params.support_ext_cc && + test_bit(WMI_TLV_SERVICE_REG_CC_EXT_EVENT_SUPPORT, ab->wmi_ab.svc_map); +} + #endif /* _CORE_H_ */ diff --git a/drivers/net/wireless/ath/ath11k/hw.h b/drivers/net/wireless/ath/ath11k/hw.h index b17c37e9eda7..86fd9dc82983 100644 --- a/drivers/net/wireless/ath/ath11k/hw.h +++ b/drivers/net/wireless/ath/ath11k/hw.h @@ -164,6 +164,7 @@ struct ath11k_hw_params { bool supports_suspend; u32 hal_desc_sz; bool fix_l1ss; + bool support_ext_cc; }; struct ath11k_hw_ops { diff --git a/drivers/net/wireless/ath/ath11k/reg.c b/drivers/net/wireless/ath/ath11k/reg.c index 3e99c95fdf28..efd047ccf0df 100644 --- a/drivers/net/wireless/ath/ath11k/reg.c +++ b/drivers/net/wireless/ath/ath11k/reg.c @@ -583,7 +583,7 @@ ath11k_reg_build_regd(struct ath11k_base *ab, { 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; @@ -591,6 +591,13 @@ ath11k_reg_build_regd(struct ath11k_base *ab, num_rules = reg_info->num_5g_reg_rules + reg_info->num_2g_reg_rules; + /* FIXME: Currently taking reg rules for 6 GHz only from Indoor AP mode list. + * This can be updated to choose the combination dynamically based on AP + * type and client type, after complete 6 GHz regulatory support is added. + */ + if (reg_info->is_ext_reg_event) + num_rules += reg_info->num_6g_reg_rules_ap[WMI_REG_INDOOR_AP]; + if (!num_rules) goto ret; @@ -636,6 +643,13 @@ ath11k_reg_build_regd(struct ath11k_base *ab, * 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_6g_reg_rules_ap[WMI_REG_INDOOR_AP] && + (k < reg_info->num_6g_reg_rules_ap[WMI_REG_INDOOR_AP])) { + reg_rule = reg_info->reg_rules_6g_ap_ptr[WMI_REG_INDOOR_AP] + k++; + max_bw = min_t(u16, reg_rule->max_bw, + reg_info->max_bw_6g_ap[WMI_REG_INDOOR_AP]); + flags = NL80211_RRF_AUTO_BW; } else { break; } @@ -663,12 +677,21 @@ ath11k_reg_build_regd(struct ath11k_base *ab, 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; diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c index 69c7b8355e52..ff3a7bbbb27e 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -96,6 +96,8 @@ static const struct wmi_tlv_policy wmi_tlv_policies[] = { = { .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] @@ -3536,6 +3538,10 @@ ath11k_wmi_copy_resource_config(struct wmi_resource_config *wmi_cfg, 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, @@ -3754,6 +3760,9 @@ int ath11k_wmi_cmd_init(struct ath11k_base *ab) ab->hw_params.hw_ops->wmi_init_config(ab, &config); + if (ath11k_support_cc_ext(ab)) + 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; @@ -4569,6 +4578,8 @@ static int ath11k_pull_reg_chan_list_update_ev(struct ath11k_base *ab, 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->is_ext_reg_event = false; + reg_info->min_bw_2g = chan_list_event_hdr->min_bw_2g; reg_info->max_bw_2g = chan_list_event_hdr->max_bw_2g; reg_info->min_bw_5g = chan_list_event_hdr->min_bw_5g; @@ -4619,6 +4630,348 @@ static int ath11k_pull_reg_chan_list_update_ev(struct ath11k_base *ab, 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 = + FIELD_GET(REG_RULE_START_FREQ, + wmi_reg_rule[count].freq_info); + reg_rule_ptr[count].end_freq = + FIELD_GET(REG_RULE_END_FREQ, + wmi_reg_rule[count].freq_info); + reg_rule_ptr[count].max_bw = + FIELD_GET(REG_RULE_MAX_BW, + wmi_reg_rule[count].bw_pwr_info); + reg_rule_ptr[count].reg_power = + FIELD_GET(REG_RULE_REG_PWR, + wmi_reg_rule[count].bw_pwr_info); + reg_rule_ptr[count].ant_gain = + FIELD_GET(REG_RULE_ANT_GAIN, + wmi_reg_rule[count].bw_pwr_info); + reg_rule_ptr[count].flags = + FIELD_GET(REG_RULE_FLAGS, + wmi_reg_rule[count].flag_info); + reg_rule_ptr[count].psd_flag = + FIELD_GET(REG_RULE_PSD_INFO, + wmi_reg_rule[count].psd_power_info); + reg_rule_ptr[count].psd_eirp = + FIELD_GET(REG_RULE_PSD_EIRP, + wmi_reg_rule[count].psd_power_info); + } + + return reg_rule_ptr; +} + +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_2g_reg_rules, num_5g_reg_rules; + u32 num_6g_reg_rules_ap[WMI_REG_CURRENT_MAX_AP_TYPE]; + u32 num_6g_client[WMI_REG_CURRENT_MAX_AP_TYPE][WMI_REG_MAX_CLIENT_TYPE]; + u32 total_reg_rules = 0; + int ret, i, j; + + 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_2g_reg_rules = ext_chan_list_event_hdr->num_2g_reg_rules; + reg_info->num_5g_reg_rules = ext_chan_list_event_hdr->num_5g_reg_rules; + reg_info->num_6g_reg_rules_ap[WMI_REG_INDOOR_AP] = + ext_chan_list_event_hdr->num_6g_reg_rules_ap_lpi; + reg_info->num_6g_reg_rules_ap[WMI_REG_STANDARD_POWER_AP] = + ext_chan_list_event_hdr->num_6g_reg_rules_ap_sp; + reg_info->num_6g_reg_rules_ap[WMI_REG_VERY_LOW_POWER_AP] = + ext_chan_list_event_hdr->num_6g_reg_rules_ap_vlp; + + for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++) { + reg_info->num_6g_reg_rules_client[WMI_REG_INDOOR_AP][i] = + ext_chan_list_event_hdr->num_6g_reg_rules_client_lpi[i]; + reg_info->num_6g_reg_rules_client[WMI_REG_STANDARD_POWER_AP][i] = + ext_chan_list_event_hdr->num_6g_reg_rules_client_sp[i]; + reg_info->num_6g_reg_rules_client[WMI_REG_VERY_LOW_POWER_AP][i] = + ext_chan_list_event_hdr->num_6g_reg_rules_client_vlp[i]; + } + + num_2g_reg_rules = reg_info->num_2g_reg_rules; + total_reg_rules += num_2g_reg_rules; + num_5g_reg_rules = reg_info->num_5g_reg_rules; + total_reg_rules += num_5g_reg_rules; + + if ((num_2g_reg_rules > MAX_REG_RULES) || (num_5g_reg_rules > MAX_REG_RULES)) { + ath11k_warn(ab, "Num reg rules for 2.4 GHz/5 GHz exceeds max limit (num_2g_reg_rules: %d num_5g_reg_rules: %d max_rules: %d)\n", + num_2g_reg_rules, num_5g_reg_rules, MAX_REG_RULES); + kfree(tb); + return -EINVAL; + } + + for (i = 0; i < WMI_REG_CURRENT_MAX_AP_TYPE; i++) { + num_6g_reg_rules_ap[i] = reg_info->num_6g_reg_rules_ap[i]; + + if (num_6g_reg_rules_ap[i] > MAX_6G_REG_RULES) { + ath11k_warn(ab, "Num 6 GHz reg rules for AP mode(%d) exceeds max limit (num_6g_reg_rules_ap: %d, max_rules: %d)\n", + i, num_6g_reg_rules_ap[i], MAX_6G_REG_RULES); + kfree(tb); + return -EINVAL; + } + + total_reg_rules += num_6g_reg_rules_ap[i]; + } + + for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++) { + num_6g_client[WMI_REG_INDOOR_AP][i] = + reg_info->num_6g_reg_rules_client[WMI_REG_INDOOR_AP][i]; + total_reg_rules += num_6g_client[WMI_REG_INDOOR_AP][i]; + + num_6g_client[WMI_REG_STANDARD_POWER_AP][i] = + reg_info->num_6g_reg_rules_client[WMI_REG_STANDARD_POWER_AP][i]; + total_reg_rules += num_6g_client[WMI_REG_STANDARD_POWER_AP][i]; + + num_6g_client[WMI_REG_VERY_LOW_POWER_AP][i] = + reg_info->num_6g_reg_rules_client[WMI_REG_VERY_LOW_POWER_AP][i]; + total_reg_rules += num_6g_client[WMI_REG_VERY_LOW_POWER_AP][i]; + + if ((num_6g_client[WMI_REG_INDOOR_AP][i] > MAX_6G_REG_RULES) || + (num_6g_client[WMI_REG_STANDARD_POWER_AP][i] > MAX_6G_REG_RULES) || + (num_6g_client[WMI_REG_VERY_LOW_POWER_AP][i] > MAX_6G_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); + + /* FIXME: Currently firmware includes 6 GHz reg rule also in 5 GHz rule + * list for country US. + * 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. So added hack below to avoid + * parsing 6 GHz rule from 5 GHz reg rule list, and this can be + * removed later, after firmware updates to remove 6 GHz reg rule + * from 5 GHz rules list. + */ + if (memcmp(reg_info->alpha2, "US", 2) == 0) { + reg_info->num_5g_reg_rules = REG_US_5G_NUM_REG_RULES; + num_5g_reg_rules = reg_info->num_5g_reg_rules; + } + + 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; + + switch (ext_chan_list_event_hdr->status_code) { + case WMI_REG_SET_CC_STATUS_PASS: + reg_info->status_code = REG_SET_CC_STATUS_PASS; + break; + case WMI_REG_CURRENT_ALPHA2_NOT_FOUND: + reg_info->status_code = REG_CURRENT_ALPHA2_NOT_FOUND; + break; + case WMI_REG_INIT_ALPHA2_NOT_FOUND: + reg_info->status_code = REG_INIT_ALPHA2_NOT_FOUND; + break; + case WMI_REG_SET_CC_CHANGE_NOT_ALLOWED: + reg_info->status_code = REG_SET_CC_CHANGE_NOT_ALLOWED; + break; + case WMI_REG_SET_CC_STATUS_NO_MEMORY: + reg_info->status_code = REG_SET_CC_STATUS_NO_MEMORY; + break; + case WMI_REG_SET_CC_STATUS_FAIL: + reg_info->status_code = REG_SET_CC_STATUS_FAIL; + break; + } + + reg_info->is_ext_reg_event = true; + + reg_info->min_bw_2g = ext_chan_list_event_hdr->min_bw_2g; + reg_info->max_bw_2g = ext_chan_list_event_hdr->max_bw_2g; + reg_info->min_bw_5g = ext_chan_list_event_hdr->min_bw_5g; + reg_info->max_bw_5g = ext_chan_list_event_hdr->max_bw_5g; + reg_info->min_bw_6g_ap[WMI_REG_INDOOR_AP] = + ext_chan_list_event_hdr->min_bw_6g_ap_lpi; + reg_info->max_bw_6g_ap[WMI_REG_INDOOR_AP] = + ext_chan_list_event_hdr->max_bw_6g_ap_lpi; + reg_info->min_bw_6g_ap[WMI_REG_STANDARD_POWER_AP] = + ext_chan_list_event_hdr->min_bw_6g_ap_sp; + reg_info->max_bw_6g_ap[WMI_REG_STANDARD_POWER_AP] = + ext_chan_list_event_hdr->max_bw_6g_ap_sp; + reg_info->min_bw_6g_ap[WMI_REG_VERY_LOW_POWER_AP] = + ext_chan_list_event_hdr->min_bw_6g_ap_vlp; + reg_info->max_bw_6g_ap[WMI_REG_VERY_LOW_POWER_AP] = + ext_chan_list_event_hdr->max_bw_6g_ap_vlp; + + for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++) { + reg_info->min_bw_6g_client[WMI_REG_INDOOR_AP][i] = + ext_chan_list_event_hdr->min_bw_6g_client_lpi[i]; + reg_info->max_bw_6g_client[WMI_REG_INDOOR_AP][i] = + ext_chan_list_event_hdr->max_bw_6g_client_lpi[i]; + reg_info->min_bw_6g_client[WMI_REG_STANDARD_POWER_AP][i] = + ext_chan_list_event_hdr->min_bw_6g_client_sp[i]; + reg_info->max_bw_6g_client[WMI_REG_STANDARD_POWER_AP][i] = + ext_chan_list_event_hdr->max_bw_6g_client_sp[i]; + reg_info->min_bw_6g_client[WMI_REG_VERY_LOW_POWER_AP][i] = + ext_chan_list_event_hdr->min_bw_6g_client_vlp[i]; + reg_info->max_bw_6g_client[WMI_REG_VERY_LOW_POWER_AP][i] = + ext_chan_list_event_hdr->max_bw_6g_client_vlp[i]; + } + + ath11k_dbg(ab, ATH11K_DBG_WMI, + "%s:cc_ext %s dsf %d BW: min_2g %d max_2g %d min_5g %d max_5g %d", + __func__, reg_info->alpha2, reg_info->dfs_region, + reg_info->min_bw_2g, reg_info->max_bw_2g, + reg_info->min_bw_5g, reg_info->max_bw_5g); + + ath11k_dbg(ab, ATH11K_DBG_WMI, + "num_2g_reg_rules %d num_5g_reg_rules %d", + num_2g_reg_rules, num_5g_reg_rules); + + ath11k_dbg(ab, ATH11K_DBG_WMI, + "num_6g_reg_rules_ap_lpi: %d num_6g_reg_rules_ap_sp: %d num_6g_reg_rules_ap_vlp: %d", + num_6g_reg_rules_ap[WMI_REG_INDOOR_AP], + num_6g_reg_rules_ap[WMI_REG_STANDARD_POWER_AP], + num_6g_reg_rules_ap[WMI_REG_VERY_LOW_POWER_AP]); + + ath11k_dbg(ab, ATH11K_DBG_WMI, + "6 GHz Regular client: num_6g_reg_rules_lpi: %d num_6g_reg_rules_sp: %d num_6g_reg_rules_vlp: %d", + num_6g_client[WMI_REG_INDOOR_AP][WMI_REG_DEFAULT_CLIENT], + num_6g_client[WMI_REG_STANDARD_POWER_AP][WMI_REG_DEFAULT_CLIENT], + num_6g_client[WMI_REG_VERY_LOW_POWER_AP][WMI_REG_DEFAULT_CLIENT]); + + ath11k_dbg(ab, ATH11K_DBG_WMI, + "6 GHz Subordinate client: num_6g_reg_rules_lpi: %d num_6g_reg_rules_sp: %d num_6g_reg_rules_vlp: %d", + num_6g_client[WMI_REG_INDOOR_AP][WMI_REG_SUBORDINATE_CLIENT], + num_6g_client[WMI_REG_STANDARD_POWER_AP][WMI_REG_SUBORDINATE_CLIENT], + num_6g_client[WMI_REG_VERY_LOW_POWER_AP][WMI_REG_SUBORDINATE_CLIENT]); + + ext_wmi_reg_rule = tb[WMI_TAG_ARRAY_STRUCT]; + + if (num_2g_reg_rules) { + reg_info->reg_rules_2g_ptr = + create_ext_reg_rules_from_wmi(num_2g_reg_rules, + ext_wmi_reg_rule); + + if (!reg_info->reg_rules_2g_ptr) { + kfree(tb); + ath11k_warn(ab, "Unable to Allocate memory for 2g rules\n"); + return -ENOMEM; + } + } + + if (num_5g_reg_rules) { + ext_wmi_reg_rule += num_2g_reg_rules; + reg_info->reg_rules_5g_ptr = + create_ext_reg_rules_from_wmi(num_5g_reg_rules, + ext_wmi_reg_rule); + + if (!reg_info->reg_rules_5g_ptr) { + kfree(tb); + ath11k_warn(ab, "Unable to Allocate memory for 5g rules\n"); + return -ENOMEM; + } + } + + ext_wmi_reg_rule += num_5g_reg_rules; + + for (i = 0; i < WMI_REG_CURRENT_MAX_AP_TYPE; i++) { + reg_info->reg_rules_6g_ap_ptr[i] = + create_ext_reg_rules_from_wmi(num_6g_reg_rules_ap[i], + ext_wmi_reg_rule); + + if (!reg_info->reg_rules_6g_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_6g_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_6g_client_ptr[j][i] = + create_ext_reg_rules_from_wmi(num_6g_client[j][i], + ext_wmi_reg_rule); + + if (!reg_info->reg_rules_6g_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_6g_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_6g_ap[WMI_REG_INDOOR_AP] = + ext_chan_list_event_hdr->domain_code_6g_ap_lpi; + reg_info->domain_code_6g_ap[WMI_REG_STANDARD_POWER_AP] = + ext_chan_list_event_hdr->domain_code_6g_ap_sp; + reg_info->domain_code_6g_ap[WMI_REG_VERY_LOW_POWER_AP] = + ext_chan_list_event_hdr->domain_code_6g_ap_vlp; + + for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++) { + reg_info->domain_code_6g_client[WMI_REG_INDOOR_AP][i] = + ext_chan_list_event_hdr->domain_code_6g_client_lpi[i]; + reg_info->domain_code_6g_client[WMI_REG_STANDARD_POWER_AP][i] = + ext_chan_list_event_hdr->domain_code_6g_client_sp[i]; + reg_info->domain_code_6g_client[WMI_REG_VERY_LOW_POWER_AP][i] = + ext_chan_list_event_hdr->domain_code_6g_client_vlp[i]; + } + + reg_info->domain_code_6g_super_id = + ext_chan_list_event_hdr->domain_code_6g_super_id; + + ath11k_dbg(ab, ATH11K_DBG_WMI, "6 GHz client_type: %d domain_code_6g_super_id: %d", + reg_info->client_type, reg_info->domain_code_6g_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) { @@ -5797,12 +6150,14 @@ static bool ath11k_reg_is_world_alpha(char *alpha) return alpha[0] == '0' && alpha[1] == '0'; } -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); @@ -5811,7 +6166,11 @@ static int ath11k_reg_chan_list_event(struct ath11k_base *ab, struct sk_buff *sk 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; @@ -5906,6 +6265,14 @@ static int ath11k_reg_chan_list_event(struct ath11k_base *ab, struct sk_buff *sk if (reg_info) { kfree(reg_info->reg_rules_2g_ptr); kfree(reg_info->reg_rules_5g_ptr); + if (reg_info->is_ext_reg_event) { + for (i = 0; i < WMI_REG_CURRENT_MAX_AP_TYPE; i++) + kfree(reg_info->reg_rules_6g_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_6g_client_ptr[j][i]); + } kfree(reg_info); } return ret; @@ -7045,7 +7412,10 @@ static void ath11k_wmi_tlv_op_rx(struct ath11k_base *ab, struct sk_buff *skb) 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); diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h index 79e9140b40d0..53aa4167db7f 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.h +++ b/drivers/net/wireless/ath/ath11k/wmi.h @@ -769,6 +769,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, @@ -1834,6 +1835,9 @@ 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_MAX }; @@ -2061,6 +2065,8 @@ enum wmi_tlv_service { WMI_MAX_EXT_SERVICE = 256, + WMI_TLV_SERVICE_REG_CC_EXT_EVENT_SUPPORT = 281, + WMI_MAX_EXT2_SERVICE }; @@ -2246,6 +2252,8 @@ struct wmi_init_cmd { u32 num_host_mem_chunks; } __packed; +#define WMI_CFG_HOST_SERVICE_FLAG_REG_CC_EXT 4 + struct wmi_resource_config { u32 tlv_header; u32 num_vdevs; @@ -2305,6 +2313,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 { @@ -2773,6 +2790,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) @@ -3935,6 +3954,8 @@ struct wmi_he_rate_set { #define MAX_REG_RULES 10 #define REG_ALPHA2_LEN 2 +#define MAX_6G_REG_RULES 5 +#define REG_US_5G_NUM_REG_RULES 4 enum wmi_start_event_param { WMI_VDEV_START_RESP_EVENT = 0, @@ -3997,6 +4018,21 @@ enum { WMI_REG_SET_CC_STATUS_FAIL = 5, }; +enum wmi_reg_6g_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_SUPP_AP_TYPE = WMI_REG_VERY_LOW_POWER_AP, + WMI_REG_MAX_AP_TYPE = 7, +}; + +enum wmi_reg_6g_client_type { + WMI_REG_DEFAULT_CLIENT = 0, + WMI_REG_SUBORDINATE_CLIENT = 1, + WMI_REG_MAX_CLIENT_TYPE = 2, +}; + struct cur_reg_rule { u16 start_freq; u16 end_freq; @@ -4004,6 +4040,8 @@ struct cur_reg_rule { u8 reg_power; u8 ant_gain; u16 flags; + bool psd_flag; + u16 psd_eirp; }; struct cur_regulatory_info { @@ -4015,6 +4053,7 @@ struct cur_regulatory_info { u8 alpha2[REG_ALPHA2_LEN + 1]; u32 dfs_region; u32 phybitmap; + bool is_ext_reg_event; u32 min_bw_2g; u32 max_bw_2g; u32 min_bw_5g; @@ -4023,6 +4062,29 @@ struct cur_regulatory_info { u32 num_5g_reg_rules; struct cur_reg_rule *reg_rules_2g_ptr; struct cur_reg_rule *reg_rules_5g_ptr; + enum wmi_reg_6g_client_type client_type; + bool rnr_tpe_usable; + bool unspecified_ap_usable; + /* TODO: All 6 GHz related info can be stored only for required + * combination instead of all types, to optimize memory usage. + */ + u8 domain_code_6g_ap[WMI_REG_CURRENT_MAX_AP_TYPE]; + u8 domain_code_6g_client[WMI_REG_CURRENT_MAX_AP_TYPE][WMI_REG_MAX_CLIENT_TYPE]; + u32 domain_code_6g_super_id; + u32 min_bw_6g_ap[WMI_REG_CURRENT_MAX_AP_TYPE]; + u32 max_bw_6g_ap[WMI_REG_CURRENT_MAX_AP_TYPE]; + u32 min_bw_6g_client[WMI_REG_CURRENT_MAX_AP_TYPE][WMI_REG_MAX_CLIENT_TYPE]; + u32 max_bw_6g_client[WMI_REG_CURRENT_MAX_AP_TYPE][WMI_REG_MAX_CLIENT_TYPE]; + u32 num_6g_reg_rules_ap[WMI_REG_CURRENT_MAX_AP_TYPE]; + u32 num_6g_reg_rules_client[WMI_REG_CURRENT_MAX_AP_TYPE][WMI_REG_MAX_CLIENT_TYPE]; + struct cur_reg_rule *reg_rules_6g_ap_ptr[WMI_REG_CURRENT_MAX_AP_TYPE]; + struct cur_reg_rule *reg_rules_6g_client_ptr + [WMI_REG_CURRENT_MAX_AP_TYPE][WMI_REG_MAX_CLIENT_TYPE]; +}; + +enum wmi_reg_chan_list_cmd_type { + WMI_REG_CHAN_LIST_CC_ID = 0, + WMI_REG_CHAN_LIST_CC_EXT_ID = 1, }; struct wmi_reg_chan_list_cc_event { @@ -4053,6 +4115,61 @@ struct wmi_vdev_delete_resp_event { u32 vdev_id; } __packed; +#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_2g; + u32 max_bw_2g; + u32 min_bw_5g; + u32 max_bw_5g; + u32 num_2g_reg_rules; + u32 num_5g_reg_rules; + u32 client_type; + u32 rnr_tpe_usable; + u32 unspecified_ap_usable; + u32 domain_code_6g_ap_lpi; + u32 domain_code_6g_ap_sp; + u32 domain_code_6g_ap_vlp; + u32 domain_code_6g_client_lpi[WMI_REG_CLIENT_MAX]; + u32 domain_code_6g_client_sp[WMI_REG_CLIENT_MAX]; + u32 domain_code_6g_client_vlp[WMI_REG_CLIENT_MAX]; + u32 domain_code_6g_super_id; + u32 min_bw_6g_ap_sp; + u32 max_bw_6g_ap_sp; + u32 min_bw_6g_ap_lpi; + u32 max_bw_6g_ap_lpi; + u32 min_bw_6g_ap_vlp; + u32 max_bw_6g_ap_vlp; + u32 min_bw_6g_client_sp[WMI_REG_CLIENT_MAX]; + u32 max_bw_6g_client_sp[WMI_REG_CLIENT_MAX]; + u32 min_bw_6g_client_lpi[WMI_REG_CLIENT_MAX]; + u32 max_bw_6g_client_lpi[WMI_REG_CLIENT_MAX]; + u32 min_bw_6g_client_vlp[WMI_REG_CLIENT_MAX]; + u32 max_bw_6g_client_vlp[WMI_REG_CLIENT_MAX]; + u32 num_6g_reg_rules_ap_sp; + u32 num_6g_reg_rules_ap_lpi; + u32 num_6g_reg_rules_ap_vlp; + u32 num_6g_reg_rules_client_sp[WMI_REG_CLIENT_MAX]; + u32 num_6g_reg_rules_client_lpi[WMI_REG_CLIENT_MAX]; + u32 num_6g_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; +}; + struct wmi_peer_delete_resp_event { u32 vdev_id; struct wmi_mac_addr peer_macaddr; @@ -5051,6 +5168,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; }; #define WMI_MAX_MEM_REQS 32 From patchwork Tue Oct 26 11:19:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wen Gong X-Patchwork-Id: 12584565 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A0EA7C433EF for ; Tue, 26 Oct 2021 11:19:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 83DED60238 for ; Tue, 26 Oct 2021 11:19:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234475AbhJZLWQ (ORCPT ); Tue, 26 Oct 2021 07:22:16 -0400 Received: from alexa-out.qualcomm.com ([129.46.98.28]:19852 "EHLO alexa-out.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234946AbhJZLWQ (ORCPT ); Tue, 26 Oct 2021 07:22:16 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1635247192; x=1666783192; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=fxTQpgOq/Gf7CwIaKwgi78/KG8G+NnCRuF/yoWfnnMA=; b=CR+HQjIN6bKe40z03zlm577y3aaEmoMHJ0bDRIS8O8xsimOJVZvUlp2G BRgtN27Q0BOtCg8oP64knineIF98TSiKTdJ9K5OMGm3c5fynnM39Pi8Ww qbFNpU+JuUFCIPf2SZdS3j3KORq/7bEBP+4y2ND/nusK51zOfkA4SWrm4 E=; Received: from ironmsg07-lv.qualcomm.com ([10.47.202.151]) by alexa-out.qualcomm.com with ESMTP; 26 Oct 2021 04:19:52 -0700 X-QCInternal: smtphost Received: from nalasex01a.na.qualcomm.com ([10.47.209.196]) by ironmsg07-lv.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Oct 2021 04:19:52 -0700 Received: from wgong-HP3-Z230-SFF-Workstation.qca.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.922.7; Tue, 26 Oct 2021 04:19:50 -0700 From: Wen Gong To: CC: , Subject: [PATCH 03/15] ath11k: add support to select 6 GHz Regulatory type Date: Tue, 26 Oct 2021 07:19:01 -0400 Message-ID: <20211026111913.7346-4-quic_wgong@quicinc.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211026111913.7346-1-quic_wgong@quicinc.com> References: <20211026111913.7346-1-quic_wgong@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To nalasex01a.na.qualcomm.com (10.47.209.196) Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org There are 3 types of regulatory rules for AP mode and 6 type for station mode. Add wmi_vdev_type and ieee80211_ap_reg_power to select the exact reg rules. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1 Signed-off-by: Wen Gong --- drivers/net/wireless/ath/ath11k/reg.c | 61 ++++++-- drivers/net/wireless/ath/ath11k/reg.h | 6 +- drivers/net/wireless/ath/ath11k/wmi.c | 192 +++++++++++++++++++++++++- drivers/net/wireless/ath/ath11k/wmi.h | 25 +++- 4 files changed, 268 insertions(+), 16 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/reg.c b/drivers/net/wireless/ath/ath11k/reg.c index efd047ccf0df..4992f498c8a7 100644 --- a/drivers/net/wireless/ath/ath11k/reg.c +++ b/drivers/net/wireless/ath/ath11k/reg.c @@ -577,16 +577,33 @@ ath11k_reg_update_weather_radar_band(struct ath11k_base *ab, *rule_idx = i; } +enum wmi_reg_6g_ap_type +ath11k_ieee80211_ap_pwr_type_convert(enum ieee80211_ap_reg_power power_type) +{ + switch (power_type) { + case IEEE80211_REG_LPI_AP: + return WMI_REG_INDOOR_AP; + case IEEE80211_REG_SP_AP: + return WMI_REG_STANDARD_POWER_AP; + case IEEE80211_REG_VLP_AP: + return WMI_REG_VERY_LOW_POWER_AP; + default: + return WMI_REG_MAX_AP_TYPE; + } +} + struct ieee80211_regdomain * ath11k_reg_build_regd(struct ath11k_base *ab, - struct cur_regulatory_info *reg_info, bool intersect) + struct cur_regulatory_info *reg_info, bool intersect, + enum wmi_vdev_type vdev_type, + enum ieee80211_ap_reg_power power_type) { struct ieee80211_regdomain *tmp_regd, *default_regd, *new_regd = NULL; - struct cur_reg_rule *reg_rule; + struct cur_reg_rule *reg_rule, *reg_rule_6g; u8 i = 0, j = 0, k = 0; u8 num_rules; u16 max_bw; - u32 flags; + u32 flags, reg_6g_number, max_bw_6g; char alpha2[3]; num_rules = reg_info->num_5g_reg_rules + reg_info->num_2g_reg_rules; @@ -595,8 +612,32 @@ ath11k_reg_build_regd(struct ath11k_base *ab, * This can be updated to choose the combination dynamically based on AP * type and client type, after complete 6 GHz regulatory support is added. */ - if (reg_info->is_ext_reg_event) - num_rules += reg_info->num_6g_reg_rules_ap[WMI_REG_INDOOR_AP]; + if (reg_info->is_ext_reg_event) { + if (vdev_type == WMI_VDEV_TYPE_STA) { + enum wmi_reg_6g_ap_type ap_type; + + ap_type = ath11k_ieee80211_ap_pwr_type_convert(power_type); + + if (ap_type == WMI_REG_MAX_AP_TYPE) + ap_type = WMI_REG_INDOOR_AP; + reg_6g_number = reg_info->num_6g_reg_rules_client + [ap_type][WMI_REG_DEFAULT_CLIENT]; + if (reg_6g_number == 0) { + ap_type = WMI_REG_INDOOR_AP; + reg_6g_number = reg_info->num_6g_reg_rules_client + [ap_type][WMI_REG_DEFAULT_CLIENT]; + } + reg_rule_6g = reg_info->reg_rules_6g_client_ptr + [ap_type][WMI_REG_DEFAULT_CLIENT]; + max_bw_6g = reg_info->max_bw_6g_client + [ap_type][WMI_REG_DEFAULT_CLIENT]; + } else { + reg_6g_number = reg_info->num_6g_reg_rules_ap[WMI_REG_INDOOR_AP]; + reg_rule_6g = reg_info->reg_rules_6g_ap_ptr[WMI_REG_INDOOR_AP]; + max_bw_6g = reg_info->max_bw_6g_ap[WMI_REG_INDOOR_AP]; + } + num_rules += reg_6g_number; + } if (!num_rules) goto ret; @@ -643,12 +684,10 @@ ath11k_reg_build_regd(struct ath11k_base *ab, * 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_6g_reg_rules_ap[WMI_REG_INDOOR_AP] && - (k < reg_info->num_6g_reg_rules_ap[WMI_REG_INDOOR_AP])) { - reg_rule = reg_info->reg_rules_6g_ap_ptr[WMI_REG_INDOOR_AP] + k++; - max_bw = min_t(u16, reg_rule->max_bw, - reg_info->max_bw_6g_ap[WMI_REG_INDOOR_AP]); + } else if (reg_info->is_ext_reg_event && reg_6g_number && + (k < reg_6g_number)) { + reg_rule = reg_rule_6g + k++; + max_bw = min_t(u16, reg_rule->max_bw, max_bw_6g); flags = NL80211_RRF_AUTO_BW; } else { break; diff --git a/drivers/net/wireless/ath/ath11k/reg.h b/drivers/net/wireless/ath/ath11k/reg.h index 65d56d44796f..3c8af2924290 100644 --- a/drivers/net/wireless/ath/ath11k/reg.h +++ b/drivers/net/wireless/ath/ath11k/reg.h @@ -30,7 +30,11 @@ void ath11k_reg_free(struct ath11k_base *ab); void ath11k_regd_update_work(struct work_struct *work); struct ieee80211_regdomain * ath11k_reg_build_regd(struct ath11k_base *ab, - struct cur_regulatory_info *reg_info, bool intersect); + struct cur_regulatory_info *reg_info, bool intersect, + enum wmi_vdev_type vdev_type, + enum ieee80211_ap_reg_power power_type); +enum wmi_reg_6g_ap_type +ath11k_ieee80211_ap_pwr_type_convert(enum ieee80211_ap_reg_power power_type); int ath11k_regd_update(struct ath11k *ar, bool init); int ath11k_reg_update_chan_list(struct ath11k *ar); #endif diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c index ff3a7bbbb27e..3a286b70c73f 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -4522,6 +4522,26 @@ static struct cur_reg_rule return reg_rule_ptr; } +static char *ath11k_cc_status_to_str(enum cc_setting_code code) +{ + switch (code) { + case REG_SET_CC_STATUS_PASS: + return "REG_SET_CC_STATUS_PASS"; + case REG_CURRENT_ALPHA2_NOT_FOUND: + return "REG_CURRENT_ALPHA2_NOT_FOUND"; + case REG_INIT_ALPHA2_NOT_FOUND: + return "REG_INIT_ALPHA2_NOT_FOUND"; + case REG_SET_CC_CHANGE_NOT_ALLOWED: + return "REG_SET_CC_CHANGE_NOT_ALLOWED"; + case REG_SET_CC_STATUS_NO_MEMORY: + return "REG_SET_CC_STATUS_NO_MEMORY"; + case REG_SET_CC_STATUS_FAIL: + return "REG_SET_CC_STATUS_FAIL"; + default: + return "unknown cc status"; + } +}; + static int ath11k_pull_reg_chan_list_update_ev(struct ath11k_base *ab, struct sk_buff *skb, struct cur_regulatory_info *reg_info) @@ -4588,6 +4608,10 @@ static int ath11k_pull_reg_chan_list_update_ev(struct ath11k_base *ab, num_2g_reg_rules = reg_info->num_2g_reg_rules; num_5g_reg_rules = reg_info->num_5g_reg_rules; + ath11k_dbg(ab, ATH11K_DBG_WMI, + "%s: status_code %s", __func__, + ath11k_cc_status_to_str(reg_info->status_code)); + ath11k_dbg(ab, ATH11K_DBG_WMI, "%s:cc %s dsf %d BW: min_2g %d max_2g %d min_5g %d max_5g %d", __func__, reg_info->alpha2, reg_info->dfs_region, @@ -4630,6 +4654,99 @@ static int ath11k_pull_reg_chan_list_update_ev(struct ath11k_base *ab, return 0; } +static char *ath11k_super_reg_6g_to_str(enum reg_super_domain_6g domain_id) +{ + switch (domain_id) { + case FCC1_6G: + return "FCC1_6G"; + case ETSI1_6G: + return "ETSI1_6G"; + case ETSI2_6G: + return "ETSI2_6G"; + case APL1_6G: + return "APL1_6G"; + case FCC1_6G_CL: + return "FCC1_6G_CL"; + default: + return "unknown domain id"; + } +}; + +static char *ath11k_6g_client_type_to_str(enum wmi_reg_6g_client_type type) +{ + switch (type) { + case WMI_REG_DEFAULT_CLIENT: + return "DEFAULT CLIENT"; + case WMI_REG_SUBORDINATE_CLIENT: + return "SUBORDINATE CLIENT"; + default: + return "unknown client type"; + } +}; + +static char *ath11k_6g_ap_type_to_str(enum wmi_reg_6g_ap_type type) +{ + switch (type) { + case WMI_REG_INDOOR_AP: + return "INDOOR AP"; + case WMI_REG_STANDARD_POWER_AP: + return "STANDARD POWER AP"; + case WMI_REG_VERY_LOW_POWER_AP: + return "VERY LOW POWER AP"; + default: + return "unknown AP type"; + } +}; + +static char *ath11k_sub_reg_6g_to_str(enum reg_subdomains_6g sub_id) +{ + switch (sub_id) { + case FCC1_CLIENT_LPI_REGULAR_6G: + return "FCC1_CLIENT_LPI_REGULAR_6G"; + case FCC1_CLIENT_SP_6G: + return "FCC1_CLIENT_SP_6G"; + case FCC1_AP_LPI_6G: + return "FCC1_AP_LPI_6G/FCC1_CLIENT_LPI_SUBORDINATE"; + case FCC1_AP_SP_6G: + return "FCC1_AP_SP_6G"; + case ETSI1_LPI_6G: + return "ETSI1_LPI_6G"; + case ETSI1_VLP_6G: + return "ETSI1_VLP_6G"; + case ETSI2_LPI_6G: + return "ETSI2_LPI_6G"; + case ETSI2_VLP_6G: + return "ETSI2_VLP_6G"; + case APL1_LPI_6G: + return "APL1_LPI_6G"; + case APL1_VLP_6G: + return "APL1_VLP_6G"; + case EMPTY_6G: + return "N/A"; + default: + return "unknown sub reg id"; + } +}; + +static void ath11k_print_reg_rule(struct ath11k_base *ab, char *prev, + u32 num_reg_rules, + struct cur_reg_rule *reg_rule_ptr) +{ + struct cur_reg_rule *reg_rule = reg_rule_ptr; + u32 count; + + ath11k_dbg(ab, ATH11K_DBG_WMI, "%s reg rules number %d\n", prev, num_reg_rules); + + for (count = 0; count < num_reg_rules; count++) { + ath11k_dbg(ab, ATH11K_DBG_WMI, + "reg rule %d: (%d - %d @ %d) (%d, %d) (FLAGS %d) (psd flag %d EIRP %d dB/MHz)\n", + count + 1, reg_rule->start_freq, reg_rule->end_freq, + reg_rule->max_bw, reg_rule->ant_gain, reg_rule->reg_power, + reg_rule->flags, reg_rule->psd_flag, reg_rule->psd_eirp); + reg_rule++; + } +} + static struct cur_reg_rule *create_ext_reg_rules_from_wmi(u32 num_reg_rules, struct wmi_regulatory_ext_rule *wmi_reg_rule) @@ -4787,6 +4904,10 @@ static int ath11k_pull_reg_chan_list_ext_update_ev(struct ath11k_base *ab, * from 5 GHz rules list. */ if (memcmp(reg_info->alpha2, "US", 2) == 0) { + ath11k_dbg(ab, ATH11K_DBG_WMI, + "US 5g reg rules number %d from firmware", + reg_info->num_5g_reg_rules); + reg_info->num_5g_reg_rules = REG_US_5G_NUM_REG_RULES; num_5g_reg_rules = reg_info->num_5g_reg_rules; } @@ -4819,6 +4940,10 @@ static int ath11k_pull_reg_chan_list_ext_update_ev(struct ath11k_base *ab, break; } + ath11k_dbg(ab, ATH11K_DBG_WMI, + "%s: status_code %s", __func__, + ath11k_cc_status_to_str(reg_info->status_code)); + reg_info->is_ext_reg_event = true; reg_info->min_bw_2g = ext_chan_list_event_hdr->min_bw_2g; @@ -4838,6 +4963,15 @@ static int ath11k_pull_reg_chan_list_ext_update_ev(struct ath11k_base *ab, reg_info->max_bw_6g_ap[WMI_REG_VERY_LOW_POWER_AP] = ext_chan_list_event_hdr->max_bw_6g_ap_vlp; + ath11k_dbg(ab, ATH11K_DBG_WMI, + "6 GHz AP BW: lpi %d - %d sp %d - %d vlp %d - %d\n", + ext_chan_list_event_hdr->min_bw_6g_ap_lpi, + ext_chan_list_event_hdr->max_bw_6g_ap_lpi, + ext_chan_list_event_hdr->min_bw_6g_ap_sp, + ext_chan_list_event_hdr->max_bw_6g_ap_sp, + ext_chan_list_event_hdr->min_bw_6g_ap_vlp, + ext_chan_list_event_hdr->max_bw_6g_ap_vlp); + for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++) { reg_info->min_bw_6g_client[WMI_REG_INDOOR_AP][i] = ext_chan_list_event_hdr->min_bw_6g_client_lpi[i]; @@ -4851,6 +4985,17 @@ static int ath11k_pull_reg_chan_list_ext_update_ev(struct ath11k_base *ab, ext_chan_list_event_hdr->min_bw_6g_client_vlp[i]; reg_info->max_bw_6g_client[WMI_REG_VERY_LOW_POWER_AP][i] = ext_chan_list_event_hdr->max_bw_6g_client_vlp[i]; + + ath11k_dbg(ab, ATH11K_DBG_WMI, + "6 GHz %s BW: lpi (%d - %d) sp (%d - %d) vlp (%d - %d)\n", + ath11k_6g_client_type_to_str(i), + ext_chan_list_event_hdr->min_bw_6g_client_lpi[i], + ext_chan_list_event_hdr->max_bw_6g_client_lpi[i], + ext_chan_list_event_hdr->min_bw_6g_client_sp[i], + ext_chan_list_event_hdr->max_bw_6g_client_sp[i], + ext_chan_list_event_hdr->min_bw_6g_client_vlp[i], + ext_chan_list_event_hdr->max_bw_6g_client_vlp[i]); + } ath11k_dbg(ab, ATH11K_DBG_WMI, @@ -4893,6 +5038,9 @@ static int ath11k_pull_reg_chan_list_ext_update_ev(struct ath11k_base *ab, ath11k_warn(ab, "Unable to Allocate memory for 2g rules\n"); return -ENOMEM; } + ath11k_print_reg_rule(ab, "2g", + num_2g_reg_rules, + reg_info->reg_rules_2g_ptr); } if (num_5g_reg_rules) { @@ -4906,6 +5054,9 @@ static int ath11k_pull_reg_chan_list_ext_update_ev(struct ath11k_base *ab, ath11k_warn(ab, "Unable to Allocate memory for 5g rules\n"); return -ENOMEM; } + ath11k_print_reg_rule(ab, "5g", + num_5g_reg_rules, + reg_info->reg_rules_5g_ptr); } ext_wmi_reg_rule += num_5g_reg_rules; @@ -4921,10 +5072,17 @@ static int ath11k_pull_reg_chan_list_ext_update_ev(struct ath11k_base *ab, return -ENOMEM; } + ath11k_print_reg_rule(ab, ath11k_6g_ap_type_to_str(i), + num_6g_reg_rules_ap[i], + reg_info->reg_rules_6g_ap_ptr[i]); + ext_wmi_reg_rule += num_6g_reg_rules_ap[i]; } for (j = 0; j < WMI_REG_CURRENT_MAX_AP_TYPE; j++) { + ath11k_dbg(ab, ATH11K_DBG_WMI, + "AP type %s", ath11k_6g_ap_type_to_str(j)); + for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++) { reg_info->reg_rules_6g_client_ptr[j][i] = create_ext_reg_rules_from_wmi(num_6g_client[j][i], @@ -4936,6 +5094,10 @@ static int ath11k_pull_reg_chan_list_ext_update_ev(struct ath11k_base *ab, return -ENOMEM; } + ath11k_print_reg_rule(ab, ath11k_6g_client_type_to_str(i), + num_6g_client[j][i], + reg_info->reg_rules_6g_client_ptr[j][i]); + ext_wmi_reg_rule += num_6g_client[j][i]; } } @@ -4951,6 +5113,18 @@ static int ath11k_pull_reg_chan_list_ext_update_ev(struct ath11k_base *ab, reg_info->domain_code_6g_ap[WMI_REG_VERY_LOW_POWER_AP] = ext_chan_list_event_hdr->domain_code_6g_ap_vlp; + ath11k_dbg(ab, ATH11K_DBG_WMI, + "6 GHz reg info client type %s rnr_tpe_usable %d unspecified_ap_usable %d AP sub domain: lpi %s , sp %s , vlp %s\n", + ath11k_6g_client_type_to_str(reg_info->client_type), + reg_info->rnr_tpe_usable, + reg_info->unspecified_ap_usable, + ath11k_sub_reg_6g_to_str + (ext_chan_list_event_hdr->domain_code_6g_ap_lpi), + ath11k_sub_reg_6g_to_str + (ext_chan_list_event_hdr->domain_code_6g_ap_sp), + ath11k_sub_reg_6g_to_str + (ext_chan_list_event_hdr->domain_code_6g_ap_vlp)); + for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++) { reg_info->domain_code_6g_client[WMI_REG_INDOOR_AP][i] = ext_chan_list_event_hdr->domain_code_6g_client_lpi[i]; @@ -4958,13 +5132,24 @@ static int ath11k_pull_reg_chan_list_ext_update_ev(struct ath11k_base *ab, ext_chan_list_event_hdr->domain_code_6g_client_sp[i]; reg_info->domain_code_6g_client[WMI_REG_VERY_LOW_POWER_AP][i] = ext_chan_list_event_hdr->domain_code_6g_client_vlp[i]; + + ath11k_dbg(ab, ATH11K_DBG_WMI, + "6 GHz client type %s client sub domain: lpi %s , sp %s , vlp %s\n", + ath11k_6g_client_type_to_str(i), + ath11k_sub_reg_6g_to_str + (ext_chan_list_event_hdr->domain_code_6g_client_lpi[i]), + ath11k_sub_reg_6g_to_str + (ext_chan_list_event_hdr->domain_code_6g_client_sp[i]), + ath11k_sub_reg_6g_to_str + (ext_chan_list_event_hdr->domain_code_6g_client_vlp[i])); } reg_info->domain_code_6g_super_id = ext_chan_list_event_hdr->domain_code_6g_super_id; - ath11k_dbg(ab, ATH11K_DBG_WMI, "6 GHz client_type: %d domain_code_6g_super_id: %d", - reg_info->client_type, reg_info->domain_code_6g_super_id); + ath11k_dbg(ab, ATH11K_DBG_WMI, "6 GHz client type %s 6 GHz super domain %s", + ath11k_6g_client_type_to_str(reg_info->client_type), + ath11k_super_reg_6g_to_str(reg_info->domain_code_6g_super_id)); ath11k_dbg(ab, ATH11K_DBG_WMI, "processed regulatory ext channel list\n"); @@ -6217,7 +6402,8 @@ static int ath11k_reg_chan_list_event(struct ath11k_base *ab, !ath11k_reg_is_world_alpha((char *)reg_info->alpha2)) intersect = true; - regd = ath11k_reg_build_regd(ab, reg_info, intersect); + regd = ath11k_reg_build_regd(ab, reg_info, intersect, + WMI_VDEV_TYPE_AP, IEEE80211_REG_UNSET_AP); if (!regd) { ath11k_warn(ab, "failed to build regd from reg_info\n"); goto fallback; diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h index 53aa4167db7f..c346937b8d4e 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.h +++ b/drivers/net/wireless/ath/ath11k/wmi.h @@ -4041,7 +4041,30 @@ struct cur_reg_rule { u8 ant_gain; u16 flags; bool psd_flag; - u16 psd_eirp; + s8 psd_eirp; +}; + +enum reg_subdomains_6g { + EMPTY_6G = 0x0, + FCC1_CLIENT_LPI_REGULAR_6G = 0x01, + FCC1_CLIENT_SP_6G = 0x02, + FCC1_AP_LPI_6G = 0x03, + FCC1_CLIENT_LPI_SUBORDINATE = FCC1_AP_LPI_6G, + FCC1_AP_SP_6G = 0x04, + ETSI1_LPI_6G = 0x10, + ETSI1_VLP_6G = 0x11, + ETSI2_LPI_6G = 0x12, + ETSI2_VLP_6G = 0x13, + APL1_LPI_6G = 0x20, + APL1_VLP_6G = 0x21, +}; + +enum reg_super_domain_6g { + FCC1_6G = 0x01, + ETSI1_6G = 0x02, + ETSI2_6G = 0x03, + APL1_6G = 0x04, + FCC1_6G_CL = 0x05, }; struct cur_regulatory_info { From patchwork Tue Oct 26 11:19:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wen Gong X-Patchwork-Id: 12584567 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1187BC433F5 for ; Tue, 26 Oct 2021 11:19:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id EBF4260238 for ; Tue, 26 Oct 2021 11:19:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235472AbhJZLWS (ORCPT ); Tue, 26 Oct 2021 07:22:18 -0400 Received: from alexa-out.qualcomm.com ([129.46.98.28]:47817 "EHLO alexa-out.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234946AbhJZLWR (ORCPT ); Tue, 26 Oct 2021 07:22:17 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1635247194; x=1666783194; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=3D/VUADKnb7G3mKyABz343EVM5vSqCrGoJnBl084SOo=; b=IZKv7VU41I8/dKqYpnHxJEAwF+ZOC/GwA+DoQkyXZkoOY4/P0ZOGE5zh Z3g/SieOWZzZHqv1yG317XrX5UrRV05c2f8AGyAN7ixwlZZzZeWbPEVcb pXyU9zfAhhHWCHuObkZdHFVWqE8TNpUD5+kfXsf0thYhN+HsJdt/PJjae 0=; Received: from ironmsg-lv-alpha.qualcomm.com ([10.47.202.13]) by alexa-out.qualcomm.com with ESMTP; 26 Oct 2021 04:19:54 -0700 X-QCInternal: smtphost Received: from nalasex01a.na.qualcomm.com ([10.47.209.196]) by ironmsg-lv-alpha.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Oct 2021 04:19:54 -0700 Received: from wgong-HP3-Z230-SFF-Workstation.qca.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.922.7; Tue, 26 Oct 2021 04:19:52 -0700 From: Wen Gong To: CC: , Subject: [PATCH 04/15] ath11k: allow only one interface up simultaneously for WCN6855 Date: Tue, 26 Oct 2021 07:19:02 -0400 Message-ID: <20211026111913.7346-5-quic_wgong@quicinc.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211026111913.7346-1-quic_wgong@quicinc.com> References: <20211026111913.7346-1-quic_wgong@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To nalasex01a.na.qualcomm.com (10.47.209.196) Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org Currently ath11k support both station/AP mode for WCN6855, and it is configured with single_pdev_only, it means it has only one ath11k and one ieee80211_hw which registered in mac80211 and one wiphy registered in cfg80211. Now it does not have requirement to start up both station and AP interface simultaneously for WCN6855, this is to disable station and AP concurrency mode. After this patch, when station interface is up, then AP interface can not start up. AP interface can start up after station interface down. Also when AP interface is up, station interface can not start up. station interface can start up after AP interface down. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1 Signed-off-by: Wen Gong --- drivers/net/wireless/ath/ath11k/core.h | 5 +++++ drivers/net/wireless/ath/ath11k/mac.c | 17 ++++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index a65f7d00eea2..e6c4963e41ac 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -972,4 +972,9 @@ static inline bool ath11k_support_cc_ext(struct ath11k_base *ab) test_bit(WMI_TLV_SERVICE_REG_CC_EXT_EVENT_SUPPORT, ab->wmi_ab.svc_map); } +static inline bool ath11k_support_6G_cc_ext(struct ath11k *ar) +{ + return ath11k_support_cc_ext(ar->ab) && ar->supports_6ghz; +} + #endif /* _CORE_H_ */ diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index 61e70f3b4a7c..2d96eea9300d 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -6431,7 +6431,22 @@ static int ath11k_mac_setup_iface_combinations(struct ath11k *ar) combinations[0].limits = limits; combinations[0].n_limits = n_limits; - combinations[0].max_interfaces = 16; + + /* When single pdev is set, there is only one ieee80211_hw/wiphy + * of mac80211/cfg80211, and it has only one reg rules stored + * The reg rules of 6 GHz is different for station and AP, please + * refer WMI_REG_CHAN_LIST_CC_EXT_EVENTID handler. + * When start station/AP simultaneously, there is not more + * struct to store the second reg rules in cfg80211. + * Also it does not have requirement for station/AP concurrency + * for WCN6855, so disable it currently. + */ + if (ab->hw_params.single_pdev_only && + ath11k_support_6G_cc_ext(ar)) + combinations[0].max_interfaces = 1; + else + combinations[0].max_interfaces = 16; + combinations[0].num_different_channels = 1; combinations[0].beacon_int_infra_match = true; combinations[0].beacon_int_min_gcd = 100; From patchwork Tue Oct 26 11:19:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wen Gong X-Patchwork-Id: 12584569 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0E630C433FE for ; Tue, 26 Oct 2021 11:19:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id ECB5760238 for ; Tue, 26 Oct 2021 11:19:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235510AbhJZLWT (ORCPT ); Tue, 26 Oct 2021 07:22:19 -0400 Received: from alexa-out.qualcomm.com ([129.46.98.28]:47817 "EHLO alexa-out.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234946AbhJZLWS (ORCPT ); Tue, 26 Oct 2021 07:22:18 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1635247195; x=1666783195; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=9lGa7mxORSU/j0gF8iIjAeCvLsvHUHhV7+LO5ODul5s=; b=n6tzzWB79qZy8RgMS44aCIDRadUzoVDyqxZFYSRv+/VFhzFv260Wgrth iKXi5B0WVpXOOti6vnmHfa/lARHah8XFdIxkxRFRLlcVbefG4adp4HDK9 zedhf3mZgn2LEi44DRggM5FuFxWi7Go6lk/B1xF4wlqinOU9mNmiAEuc3 8=; Received: from ironmsg-lv-alpha.qualcomm.com ([10.47.202.13]) by alexa-out.qualcomm.com with ESMTP; 26 Oct 2021 04:19:55 -0700 X-QCInternal: smtphost Received: from nalasex01a.na.qualcomm.com ([10.47.209.196]) by ironmsg-lv-alpha.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Oct 2021 04:19:55 -0700 Received: from wgong-HP3-Z230-SFF-Workstation.qca.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.922.7; Tue, 26 Oct 2021 04:19:53 -0700 From: Wen Gong To: CC: , Subject: [PATCH 05/15] ath11k: store cur_regulatory_info for each radio Date: Tue, 26 Oct 2021 07:19:03 -0400 Message-ID: <20211026111913.7346-6-quic_wgong@quicinc.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211026111913.7346-1-quic_wgong@quicinc.com> References: <20211026111913.7346-1-quic_wgong@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To nalasex01a.na.qualcomm.com (10.47.209.196) Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org The regulatory info of WMI_REG_CHAN_LIST_CC_EXT_EVENTID is not saved in ath11k now, the info should be saved in ath11k. Save the info for each radio and support switch regulatory rules dynamically. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1 Signed-off-by: Wen Gong --- drivers/net/wireless/ath/ath11k/core.c | 9 ++ drivers/net/wireless/ath/ath11k/core.h | 1 + drivers/net/wireless/ath/ath11k/mac.c | 11 +++ drivers/net/wireless/ath/ath11k/mac.h | 2 +- drivers/net/wireless/ath/ath11k/wmi.c | 117 +++++++++++++++++-------- drivers/net/wireless/ath/ath11k/wmi.h | 6 +- 6 files changed, 106 insertions(+), 40 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index 66ceef24532d..d8ac26f730db 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -1115,6 +1115,15 @@ EXPORT_SYMBOL(ath11k_core_deinit); void ath11k_core_free(struct ath11k_base *ab) { + if (ab) { + int i; + + for (i = 0; i < ab->num_radios; i++) + ath11k_reg_reset_info(&ab->reg_info_store[i]); + + kfree(ab->reg_info_store); + } + kfree(ab); } EXPORT_SYMBOL(ath11k_core_free); diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index e6c4963e41ac..dfe62a3490d2 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -721,6 +721,7 @@ struct ath11k_base { * This may or may not be used during the runtime */ struct ieee80211_regdomain *new_regd[MAX_RADIOS]; + struct cur_regulatory_info *reg_info_store; /* Current DFS Regulatory */ enum ath11k_dfs_region dfs_region; diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index 2d96eea9300d..16ab9b451bde 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -518,6 +518,17 @@ struct ath11k *ath11k_mac_get_ar_by_vdev_id(struct ath11k_base *ab, u32 vdev_id) return NULL; } +enum wmi_vdev_type ath11k_mac_get_ar_vdev_type(struct ath11k *ar) +{ + struct ath11k_vif *arvif; + + list_for_each_entry(arvif, &ar->arvifs, list) { + return arvif->vdev_type; + } + + return WMI_VDEV_TYPE_UNSPEC; +} + struct ath11k *ath11k_mac_get_ar_by_pdev_id(struct ath11k_base *ab, u32 pdev_id) { int i; diff --git a/drivers/net/wireless/ath/ath11k/mac.h b/drivers/net/wireless/ath/ath11k/mac.h index 4bc59bdaf244..6d308267e4b8 100644 --- a/drivers/net/wireless/ath/ath11k/mac.h +++ b/drivers/net/wireless/ath/ath11k/mac.h @@ -143,7 +143,7 @@ struct ath11k_vif *ath11k_mac_get_arvif_by_vdev_id(struct ath11k_base *ab, u32 vdev_id); struct ath11k *ath11k_mac_get_ar_by_vdev_id(struct ath11k_base *ab, u32 vdev_id); struct ath11k *ath11k_mac_get_ar_by_pdev_id(struct ath11k_base *ab, u32 pdev_id); - +enum wmi_vdev_type ath11k_mac_get_ar_vdev_type(struct ath11k *ar); void ath11k_mac_drain_tx(struct ath11k *ar); void ath11k_mac_peer_cleanup_all(struct ath11k *ar); int ath11k_mac_tx_mgmt_pending_free(int buf_id, void *skb, void *ctx); diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c index 3a286b70c73f..2684c042bbad 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -4205,6 +4205,10 @@ static int ath11k_wmi_tlv_ext_soc_hal_reg_caps_parse(struct ath11k_base *soc, soc->pdevs[0].pdev_id = 0; } + soc->reg_info_store = kcalloc(soc->num_radios, + sizeof(*soc->reg_info_store), + GFP_ATOMIC); + return 0; } @@ -6335,31 +6339,34 @@ static bool ath11k_reg_is_world_alpha(char *alpha) return alpha[0] == '0' && alpha[1] == '0'; } -static int ath11k_reg_chan_list_event(struct ath11k_base *ab, - struct sk_buff *skb, - enum wmi_reg_chan_list_cmd_type id) +void ath11k_reg_reset_info(struct cur_regulatory_info *reg_info) { - struct cur_regulatory_info *reg_info = NULL; - struct ieee80211_regdomain *regd = NULL; - bool intersect = false; - int ret = 0, pdev_idx, i, j; - struct ath11k *ar; + int i, j; - reg_info = kzalloc(sizeof(*reg_info), GFP_ATOMIC); - if (!reg_info) { - ret = -ENOMEM; - goto fallback; - } + if (reg_info) { + kfree(reg_info->reg_rules_2g_ptr); - 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); + kfree(reg_info->reg_rules_5g_ptr); - if (ret) { - ath11k_warn(ab, "failed to extract regulatory info from received event\n"); - goto fallback; + for (i = 0; i < WMI_REG_CURRENT_MAX_AP_TYPE; i++) { + kfree(reg_info->reg_rules_6g_ap_ptr[i]); + for (j = 0; j < WMI_REG_MAX_CLIENT_TYPE; j++) + kfree(reg_info->reg_rules_6g_client_ptr[i][j]); + } + + memset(reg_info, 0, sizeof(*reg_info)); } +} + +int ath11k_reg_handle_chan_list(struct ath11k_base *ab, + struct cur_regulatory_info *reg_info, + enum ieee80211_ap_reg_power power_type) +{ + struct ieee80211_regdomain *regd; + bool intersect = false; + int pdev_idx; + struct ath11k *ar; + enum wmi_vdev_type vdev_type; if (reg_info->status_code != REG_SET_CC_STATUS_PASS) { /* In case of failure to set the requested ctry, @@ -6367,7 +6374,7 @@ static int ath11k_reg_chan_list_event(struct ath11k_base *ab, * and return from here. */ ath11k_warn(ab, "Failed to set the requested Country regulatory setting\n"); - goto mem_free; + return -EINVAL; } pdev_idx = reg_info->phy_id; @@ -6379,7 +6386,7 @@ static int ath11k_reg_chan_list_event(struct ath11k_base *ab, */ if (ab->hw_params.single_pdev_only && pdev_idx < ab->hw_params.num_rxmda_per_pdev) - goto mem_free; + goto retfail; else goto fallback; } @@ -6390,7 +6397,7 @@ static int ath11k_reg_chan_list_event(struct ath11k_base *ab, if (ab->default_regd[pdev_idx] && !ab->new_regd[pdev_idx] && !memcmp((char *)ab->default_regd[pdev_idx]->alpha2, (char *)reg_info->alpha2, 2)) - goto mem_free; + goto retfail; /* Intersect new rules with default regd if a new country setting was * requested, i.e a default regd was already set during initialization @@ -6402,13 +6409,24 @@ static int ath11k_reg_chan_list_event(struct ath11k_base *ab, !ath11k_reg_is_world_alpha((char *)reg_info->alpha2)) intersect = true; - regd = ath11k_reg_build_regd(ab, reg_info, intersect, - WMI_VDEV_TYPE_AP, IEEE80211_REG_UNSET_AP); + ar = ab->pdevs[pdev_idx].ar; + vdev_type = ath11k_mac_get_ar_vdev_type(ar); + + ath11k_dbg(ab, ATH11K_DBG_WMI, + "wmi handle chan list power type %d vdev type %d intersect %d\n", + power_type, vdev_type, intersect); + + regd = ath11k_reg_build_regd(ab, reg_info, intersect, vdev_type, power_type); if (!regd) { ath11k_warn(ab, "failed to build regd from reg_info\n"); goto fallback; } + if (power_type == IEEE80211_REG_UNSET_AP) { + ath11k_reg_reset_info(&ab->reg_info_store[pdev_idx]); + ab->reg_info_store[pdev_idx] = *reg_info; + } + spin_lock(&ab->base_lock); if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags)) { /* Once mac is registered, ar is valid and all CC events from @@ -6435,7 +6453,7 @@ static int ath11k_reg_chan_list_event(struct ath11k_base *ab, ab->dfs_region = reg_info->dfs_region; spin_unlock(&ab->base_lock); - goto mem_free; + return 0; fallback: /* Fallback to older reg (by sending previous country setting @@ -6447,20 +6465,43 @@ static int ath11k_reg_chan_list_event(struct ath11k_base *ab, */ /* TODO: This is rare, but still should also be handled */ WARN_ON(1); -mem_free: - if (reg_info) { - kfree(reg_info->reg_rules_2g_ptr); - kfree(reg_info->reg_rules_5g_ptr); - if (reg_info->is_ext_reg_event) { - for (i = 0; i < WMI_REG_CURRENT_MAX_AP_TYPE; i++) - kfree(reg_info->reg_rules_6g_ap_ptr[i]); +retfail: - 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_6g_client_ptr[j][i]); - } - kfree(reg_info); + return -EINVAL; +} + +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; + int ret; + + reg_info = kzalloc(sizeof(*reg_info), GFP_ATOMIC); + if (!reg_info) + return -ENOMEM; + + 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 mem_free; } + + ret = ath11k_reg_handle_chan_list(ab, reg_info, IEEE80211_REG_UNSET_AP); + if (ret) { + ath11k_warn(ab, "failed to process regulatory info from received event\n"); + goto mem_free; + } + + kfree(reg_info); + return 0; + +mem_free: + ath11k_reg_reset_info(reg_info); + kfree(reg_info); return ret; } diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h index c346937b8d4e..c62c9e1982ce 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.h +++ b/drivers/net/wireless/ath/ath11k/wmi.h @@ -4607,6 +4607,7 @@ struct ath11k_targ_cap { }; enum wmi_vdev_type { + WMI_VDEV_TYPE_UNSPEC = 0, WMI_VDEV_TYPE_AP = 1, WMI_VDEV_TYPE_STA = 2, WMI_VDEV_TYPE_IBSS = 3, @@ -5528,5 +5529,8 @@ int ath11k_wmi_set_hw_mode(struct ath11k_base *ab, enum wmi_host_hw_mode_config_type mode); int ath11k_wmi_wow_host_wakeup_ind(struct ath11k *ar); int ath11k_wmi_wow_enable(struct ath11k *ar); - +void ath11k_reg_reset_info(struct cur_regulatory_info *reg_info); +int ath11k_reg_handle_chan_list(struct ath11k_base *ab, + struct cur_regulatory_info *reg_info, + enum ieee80211_ap_reg_power power_type); #endif From patchwork Tue Oct 26 11:19:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wen Gong X-Patchwork-Id: 12584571 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 62341C433F5 for ; Tue, 26 Oct 2021 11:19:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4A7C560238 for ; Tue, 26 Oct 2021 11:19:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233382AbhJZLWU (ORCPT ); Tue, 26 Oct 2021 07:22:20 -0400 Received: from alexa-out.qualcomm.com ([129.46.98.28]:47817 "EHLO alexa-out.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234450AbhJZLWT (ORCPT ); Tue, 26 Oct 2021 07:22:19 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1635247197; x=1666783197; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=a3S2FktU30a9FSIgul8lUwvkHDsTsJxiwPWkjsP414o=; b=P5nx9F4iAG9TqYKjdVtJM68q2bhdSo4Mj4Emv6LprqN/n2Nz98AdIwiG aWh40NFhCCgle9CMetgcMIcVYpfZU9qntc0WIah63EecCVKHyN4wfYqZk YOxvPaI4X9XugWUzgTxCjjiUNmdK4E7CnsrI9FYNT8xkRiI5dcYSCSu7A 0=; Received: from ironmsg-lv-alpha.qualcomm.com ([10.47.202.13]) by alexa-out.qualcomm.com with ESMTP; 26 Oct 2021 04:19:56 -0700 X-QCInternal: smtphost Received: from nalasex01a.na.qualcomm.com ([10.47.209.196]) by ironmsg-lv-alpha.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Oct 2021 04:19:57 -0700 Received: from wgong-HP3-Z230-SFF-Workstation.qca.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.922.7; Tue, 26 Oct 2021 04:19:55 -0700 From: Wen Gong To: CC: , Subject: [PATCH 06/15] ath11k: update regulatory rules when interface added Date: Tue, 26 Oct 2021 07:19:04 -0400 Message-ID: <20211026111913.7346-7-quic_wgong@quicinc.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211026111913.7346-1-quic_wgong@quicinc.com> References: <20211026111913.7346-1-quic_wgong@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To nalasex01a.na.qualcomm.com (10.47.209.196) Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org When wlan boot up, WMI_REG_CHAN_LIST_CC_EXT_EVENTID is sent from firmware at an early stage, the interface mode is not decided at this point, then ath11k select reg rules of AP mode as default. After interface is created, it is exactly decided AP/station mode, then ath11k need to update reg rules to the exact one. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1 Signed-off-by: Wen Gong --- drivers/net/wireless/ath/ath11k/mac.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index 16ab9b451bde..fbfc7f139854 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -4920,6 +4920,14 @@ static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw, ath11k_dp_vdev_tx_attach(ar, arvif); + if (ath11k_support_6G_cc_ext(ar)) { + struct cur_regulatory_info *reg_info; + + reg_info = &ab->reg_info_store[ar->pdev_idx]; + ath11k_dbg(ab, ATH11K_DBG_MAC, "mac interface added to change reg rules\n"); + ath11k_reg_handle_chan_list(ab, reg_info, IEEE80211_REG_LPI_AP); + } + mutex_unlock(&ar->conf_mutex); return 0; From patchwork Tue Oct 26 11:19:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wen Gong X-Patchwork-Id: 12584573 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7345DC4332F for ; Tue, 26 Oct 2021 11:19:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5D2E060238 for ; Tue, 26 Oct 2021 11:19:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235500AbhJZLWW (ORCPT ); Tue, 26 Oct 2021 07:22:22 -0400 Received: from alexa-out.qualcomm.com ([129.46.98.28]:47817 "EHLO alexa-out.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234276AbhJZLWV (ORCPT ); Tue, 26 Oct 2021 07:22:21 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1635247198; x=1666783198; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=M72rrJu6jvtu6sAzW8B4eMmtRyk9ZLkO4UK2qFnPAuM=; b=HuB/Ms0iK52am6Vj7NL+hBfGzGdCnrhqH+P+WrclnSPmyrIAbHMQSSQ9 ZG7osrWRoyTL5bjmZ7S8nM8Dx0JTAguU9aTBoaw5sofsBpoI9yUck2enm 2LCmafh/D4M/8op6JhlFdGBBO0f+rsHSBKWsrKBo5PtdIErwKWELXxV3t 0=; Received: from ironmsg-lv-alpha.qualcomm.com ([10.47.202.13]) by alexa-out.qualcomm.com with ESMTP; 26 Oct 2021 04:19:58 -0700 X-QCInternal: smtphost Received: from nalasex01a.na.qualcomm.com ([10.47.209.196]) by ironmsg-lv-alpha.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Oct 2021 04:19:58 -0700 Received: from wgong-HP3-Z230-SFF-Workstation.qca.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.922.7; Tue, 26 Oct 2021 04:19:56 -0700 From: Wen Gong To: CC: , Subject: [PATCH 07/15] ath11k: update regulatory rules when connect to AP on 6 GHz band for station Date: Tue, 26 Oct 2021 07:19:05 -0400 Message-ID: <20211026111913.7346-8-quic_wgong@quicinc.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211026111913.7346-1-quic_wgong@quicinc.com> References: <20211026111913.7346-1-quic_wgong@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To nalasex01a.na.qualcomm.com (10.47.209.196) Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org When station connect to AP on 6 GHz band, it need switch the regulatory rules according to the regulatory info subfield in HE operation element. Swith to the power type of AP for station mode. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1 Signed-off-by: Wen Gong --- drivers/net/wireless/ath/ath11k/mac.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index fbfc7f139854..76ccc99e77ae 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -5590,6 +5590,8 @@ ath11k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, struct ath11k_vif *arvif = (void *)vif->drv_priv; int ret; struct peer_create_params param; + struct cur_regulatory_info *reg_info; + enum ieee80211_ap_reg_power power_type; mutex_lock(&ar->conf_mutex); @@ -5597,6 +5599,17 @@ ath11k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, "mac chanctx assign ptr %pK vdev_id %i\n", ctx, arvif->vdev_id); + if (ar->supports_6ghz && ctx->def.chan->band == NL80211_BAND_6GHZ && + arvif->vdev_type == WMI_VDEV_TYPE_STA) { + reg_info = &ab->reg_info_store[ar->pdev_idx]; + power_type = vif->bss_conf.power_type; + ath11k_dbg(ab, ATH11K_DBG_MAC, "mac chanctx power type %d\n", + power_type); + if (power_type == IEEE80211_REG_UNSET_AP) + power_type = IEEE80211_REG_LPI_AP; + ath11k_reg_handle_chan_list(ab, reg_info, power_type); + } + /* for QCA6390 bss peer must be created before vdev_start */ if (ab->hw_params.vdev_start_delay && arvif->vdev_type != WMI_VDEV_TYPE_AP && From patchwork Tue Oct 26 11:19:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wen Gong X-Patchwork-Id: 12584575 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E1D2FC433F5 for ; Tue, 26 Oct 2021 11:20:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id CEB7060238 for ; Tue, 26 Oct 2021 11:20:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235512AbhJZLWX (ORCPT ); Tue, 26 Oct 2021 07:22:23 -0400 Received: from alexa-out.qualcomm.com ([129.46.98.28]:1435 "EHLO alexa-out.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234535AbhJZLWW (ORCPT ); Tue, 26 Oct 2021 07:22:22 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1635247199; x=1666783199; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=t46YeLoXPPPhCcwTGbgxwYSI/kDyb8WxpLpPJ3sV0v0=; b=pBtDq+B3552bYG00L2XgX0eY5xk5ixLruWMia6MXIAqcKPYrEKx+GCDs XIewtfwv0Ud9u90JDoBJqeB8ZviNmwRreWbwslJl9YyK+fNzDFaB/nIvD bR82qHYhbHa4LAlHtU/fdepZlwbioxJq8QQr1j/x1+DniG14yTcFy4DsM 4=; Received: from ironmsg07-lv.qualcomm.com ([10.47.202.151]) by alexa-out.qualcomm.com with ESMTP; 26 Oct 2021 04:19:59 -0700 X-QCInternal: smtphost Received: from nalasex01a.na.qualcomm.com ([10.47.209.196]) by ironmsg07-lv.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Oct 2021 04:19:59 -0700 Received: from wgong-HP3-Z230-SFF-Workstation.qca.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.922.7; Tue, 26 Oct 2021 04:19:57 -0700 From: Wen Gong To: CC: , Subject: [PATCH 08/15] ath11k: save power spectral density(psd) of regulatory rule Date: Tue, 26 Oct 2021 07:19:06 -0400 Message-ID: <20211026111913.7346-9-quic_wgong@quicinc.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211026111913.7346-1-quic_wgong@quicinc.com> References: <20211026111913.7346-1-quic_wgong@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To nalasex01a.na.qualcomm.com (10.47.209.196) Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org Save the power spectral density(psd) report from firmware to struct ieee80211_reg_rule. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1 Signed-off-by: Wen Gong --- drivers/net/wireless/ath/ath11k/reg.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/reg.c b/drivers/net/wireless/ath/ath11k/reg.c index 4992f498c8a7..30cd2f81f89e 100644 --- a/drivers/net/wireless/ath/ath11k/reg.c +++ b/drivers/net/wireless/ath/ath11k/reg.c @@ -392,6 +392,10 @@ static void ath11k_reg_intersect_rules(struct ieee80211_reg_rule *rule1, /* Use the flags of both the rules */ new_rule->flags = rule1->flags | rule2->flags; + if ((rule1->flags & NL80211_RRF_PSD) && (rule2->flags & NL80211_RRF_PSD)) + new_rule->psd = min_t(s8, rule1->psd, rule2->psd); + else + new_rule->flags &= ~NL80211_RRF_PSD; /* To be safe, lts use the max cac timeout of both rules */ new_rule->dfs_cac_ms = max_t(u32, rule1->dfs_cac_ms, @@ -490,13 +494,14 @@ ath11k_reg_adjust_bw(u16 start_freq, u16 end_freq, u16 max_bw) static void ath11k_reg_update_rule(struct ieee80211_reg_rule *reg_rule, u32 start_freq, u32 end_freq, u32 bw, u32 ant_gain, u32 reg_pwr, - u32 reg_flags) + s8 psd, u32 reg_flags) { reg_rule->freq_range.start_freq_khz = MHZ_TO_KHZ(start_freq); reg_rule->freq_range.end_freq_khz = MHZ_TO_KHZ(end_freq); reg_rule->freq_range.max_bandwidth_khz = MHZ_TO_KHZ(bw); reg_rule->power_rule.max_antenna_gain = DBI_TO_MBI(ant_gain); reg_rule->power_rule.max_eirp = DBM_TO_MBM(reg_pwr); + reg_rule->psd = psd; reg_rule->flags = reg_flags; } @@ -518,7 +523,7 @@ ath11k_reg_update_weather_radar_band(struct ath11k_base *ab, ath11k_reg_update_rule(regd->reg_rules + i, reg_rule->start_freq, ETSI_WEATHER_RADAR_BAND_LOW, bw, reg_rule->ant_gain, reg_rule->reg_power, - flags); + reg_rule->psd_eirp, flags); ath11k_dbg(ab, ATH11K_DBG_REG, "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n", @@ -540,7 +545,7 @@ ath11k_reg_update_weather_radar_band(struct ath11k_base *ab, ath11k_reg_update_rule(regd->reg_rules + i, ETSI_WEATHER_RADAR_BAND_LOW, end_freq, bw, reg_rule->ant_gain, reg_rule->reg_power, - flags); + reg_rule->psd_eirp, flags); regd->reg_rules[i].dfs_cac_ms = ETSI_WEATHER_RADAR_BAND_CAC_TIMEOUT; @@ -565,7 +570,7 @@ ath11k_reg_update_weather_radar_band(struct ath11k_base *ab, ath11k_reg_update_rule(regd->reg_rules + i, ETSI_WEATHER_RADAR_BAND_HIGH, reg_rule->end_freq, bw, reg_rule->ant_gain, reg_rule->reg_power, - flags); + reg_rule->psd_eirp, flags); ath11k_dbg(ab, ATH11K_DBG_REG, "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n", @@ -689,6 +694,8 @@ ath11k_reg_build_regd(struct ath11k_base *ab, reg_rule = reg_rule_6g + k++; max_bw = min_t(u16, reg_rule->max_bw, max_bw_6g); flags = NL80211_RRF_AUTO_BW; + if (reg_rule->psd_flag) + flags |= NL80211_RRF_PSD; } else { break; } @@ -699,7 +706,7 @@ ath11k_reg_build_regd(struct ath11k_base *ab, reg_rule->start_freq, reg_rule->end_freq, max_bw, reg_rule->ant_gain, reg_rule->reg_power, - flags); + reg_rule->psd_eirp, flags); /* Update dfs cac timeout if the dfs domain is ETSI and the * new rule covers weather radar band. From patchwork Tue Oct 26 11:19:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Wen Gong X-Patchwork-Id: 12584577 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5F57FC4332F for ; Tue, 26 Oct 2021 11:20:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4CA5B60EDF for ; Tue, 26 Oct 2021 11:20:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234276AbhJZLWZ (ORCPT ); Tue, 26 Oct 2021 07:22:25 -0400 Received: from alexa-out.qualcomm.com ([129.46.98.28]:47817 "EHLO alexa-out.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234827AbhJZLWY (ORCPT ); Tue, 26 Oct 2021 07:22:24 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1635247201; x=1666783201; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=PoJNNu3sKojCddKdbpx2J4FfYr9Iv03974Kbxw4jIEY=; b=DrjxbWKJYwimI6llQJ4SQy1pothPezEDZJOzwt7snuevzWUwkVr2aYQ8 SZp4Md/yrYj2UtcYT6/BriMe7vQ/Ww3DkfLjzz+iPnBeUQWB0ERFDN+q+ 5pAOUVnQ5DkYPlaRBw3J8W3mSWFv7JjRrojZYuR0iPUbCh5ONfoa9ZsfY U=; Received: from ironmsg-lv-alpha.qualcomm.com ([10.47.202.13]) by alexa-out.qualcomm.com with ESMTP; 26 Oct 2021 04:20:01 -0700 X-QCInternal: smtphost Received: from nalasex01a.na.qualcomm.com ([10.47.209.196]) by ironmsg-lv-alpha.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Oct 2021 04:20:01 -0700 Received: from wgong-HP3-Z230-SFF-Workstation.qca.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.922.7; Tue, 26 Oct 2021 04:19:59 -0700 From: Wen Gong To: CC: , Subject: [PATCH 09/15] ath11k: add parse of transmit power envelope element Date: Tue, 26 Oct 2021 07:19:07 -0400 Message-ID: <20211026111913.7346-10-quic_wgong@quicinc.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211026111913.7346-1-quic_wgong@quicinc.com> References: <20211026111913.7346-1-quic_wgong@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To nalasex01a.na.qualcomm.com (10.47.209.196) Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org The transmit power envelope element has some fields for power, ath11k should parse it according to IEEE Std 802.11ax™‐2021. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1 Signed-off-by: Wen Gong --- drivers/net/wireless/ath/ath11k/core.h | 38 +++++ drivers/net/wireless/ath/ath11k/mac.c | 197 +++++++++++++++++++++++++ 2 files changed, 235 insertions(+) diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index dfe62a3490d2..94516d14f89b 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -196,6 +196,43 @@ enum ath11k_monitor_flags { ATH11K_FLAG_MONITOR_ENABLED, }; +/** + * struct chan_power_info - TPE containing power info per channel chunk + * @chan_cfreq: channel center freq (MHz) + * e.g. + * channel 37/20 MHz, it is 6135 + * channel 37/40 MHz, it is 6125 + * channel 37/80 MHz, it is 6145 + * channel 37/160 MHz, it is 6185 + * @tx_power: transmit power (dBm) + */ +struct chan_power_info { + u16 chan_cfreq; + s8 tx_power; +}; + +/** + * struct reg_tpc_power_info - regulatory TPC power info + * @is_psd_power: is PSD power or not + * @eirp_power: Maximum EIRP power (dBm), valid only if power is PSD + * @power_type_6g: type of power (SP/LPI/VLP) + * @num_pwr_levels: number of power levels + * @reg_max: Array of maximum TX power (dBm) per PSD value + * @ap_constraint_power: AP constraint power (dBm) + * @tpe: TPE values processed from TPE IE + * @chan_power_info: power info to send to firmware + */ +struct ath11k_reg_tpc_power_info { + bool is_psd_power; + u8 eirp_power; + enum wmi_reg_6g_ap_type power_type_6g; + u8 num_pwr_levels; + u8 reg_max[IEEE80211_MAX_NUM_PWR_LEVEL]; + u8 ap_constraint_power; + s8 tpe[IEEE80211_MAX_NUM_PWR_LEVEL]; + struct chan_power_info chan_power_info[IEEE80211_MAX_NUM_PWR_LEVEL]; +}; + struct ath11k_vif { u32 vdev_id; enum wmi_vdev_type vdev_type; @@ -244,6 +281,7 @@ struct ath11k_vif { bool rsnie_present; bool wpaie_present; struct ieee80211_chanctx_conf chanctx; + struct ath11k_reg_tpc_power_info reg_tpc_info; }; struct ath11k_vif_iter { diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index 76ccc99e77ae..71991178a830 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -5580,6 +5580,201 @@ static int ath11k_start_vdev_delay(struct ieee80211_hw *hw, return 0; } +static u8 ath11k_mac_get_tpe_count(u8 txpwr_intrprt, u8 txpwr_cnt) +{ + switch (txpwr_intrprt) { + /* Refer "Table 9-276-Meaning of Maximum Transmit Power Count subfield + * if the Maximum Transmit Power Interpretation subfield is 0 or 2" of + * "IEEE Std 802.11ax 2021". + */ + case IEEE80211_TPE_LOCAL_EIRP: + case IEEE80211_TPE_REG_CLIENT_EIRP: + txpwr_cnt = txpwr_cnt <= 3 ? txpwr_cnt : 3; + txpwr_cnt = txpwr_cnt + 1; + break; + /* Refer "Table 9-277-Meaning of Maximum Transmit Power Count subfield + * if Maximum Transmit Power Interpretation subfield is 1 or 3" of + * "IEEE Std 802.11ax 2021". + */ + case IEEE80211_TPE_LOCAL_EIRP_PSD: + case IEEE80211_TPE_REG_CLIENT_EIRP_PSD: + txpwr_cnt = txpwr_cnt <= 4 ? txpwr_cnt : 4; + txpwr_cnt = txpwr_cnt ? (BIT(txpwr_cnt - 1)) : 1; + break; + } + + return txpwr_cnt; +} + +static u8 ath11k_mac_get_num_pwr_levels(struct cfg80211_chan_def *chan_def) +{ + u8 num_pwr_levels; + + if (chan_def->chan->flags & IEEE80211_CHAN_PSD) { + switch (chan_def->width) { + case NL80211_CHAN_WIDTH_20: + num_pwr_levels = 1; + break; + case NL80211_CHAN_WIDTH_40: + num_pwr_levels = 2; + break; + case NL80211_CHAN_WIDTH_80: + num_pwr_levels = 4; + break; + case NL80211_CHAN_WIDTH_80P80: + case NL80211_CHAN_WIDTH_160: + num_pwr_levels = 8; + break; + default: + return 1; + } + } else { + switch (chan_def->width) { + case NL80211_CHAN_WIDTH_20: + num_pwr_levels = 1; + break; + case NL80211_CHAN_WIDTH_40: + num_pwr_levels = 2; + break; + case NL80211_CHAN_WIDTH_80: + num_pwr_levels = 3; + break; + case NL80211_CHAN_WIDTH_80P80: + case NL80211_CHAN_WIDTH_160: + num_pwr_levels = 4; + break; + default: + return 1; + } + } + + return num_pwr_levels; +} + +static void ath11k_mac_parse_tx_pwr_env(struct ath11k *ar, + struct ieee80211_vif *vif, + struct ieee80211_chanctx_conf *ctx) +{ + struct ath11k_base *ab = ar->ab; + struct ath11k_vif *arvif = (void *)vif->drv_priv; + struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; + struct ieee80211_tx_pwr_env *single_tpe; + enum wmi_reg_6g_client_type client_type; + struct cur_regulatory_info *reg_info; + int i; + u8 pwr_count, pwr_interpret, pwr_category; + u8 psd_index = 0, non_psd_index = 0, local_tpe_count = 0, reg_tpe_count = 0; + bool use_local_tpe, non_psd_set = false, psd_set = false; + + reg_info = &ab->reg_info_store[ar->pdev_idx]; + client_type = reg_info->client_type; + + for (i = 0; i < bss_conf->tx_pwr_env_num; i++) { + single_tpe = &bss_conf->tx_pwr_env[i]; + pwr_category = u8_get_bits(single_tpe->tx_power_info, + IEEE80211_TX_PWR_ENV_INFO_CATEGORY); + pwr_interpret = u8_get_bits(single_tpe->tx_power_info, + IEEE80211_TX_PWR_ENV_INFO_INTERPRET); + + if (pwr_category == client_type) { + if (pwr_interpret == IEEE80211_TPE_LOCAL_EIRP || + pwr_interpret == IEEE80211_TPE_LOCAL_EIRP_PSD) + local_tpe_count++; + else if (pwr_interpret == IEEE80211_TPE_REG_CLIENT_EIRP || + pwr_interpret == IEEE80211_TPE_REG_CLIENT_EIRP_PSD) + reg_tpe_count++; + } + } + + if (!reg_tpe_count && !local_tpe_count) { + ath11k_warn(ab, + "no transmit power envelope match client power type %d\n", + client_type); + return; + } else if (!reg_tpe_count) { + use_local_tpe = true; + } else { + use_local_tpe = false; + } + + for (i = 0; i < bss_conf->tx_pwr_env_num; i++) { + single_tpe = &bss_conf->tx_pwr_env[i]; + pwr_category = u8_get_bits(single_tpe->tx_power_info, + IEEE80211_TX_PWR_ENV_INFO_CATEGORY); + pwr_interpret = u8_get_bits(single_tpe->tx_power_info, + IEEE80211_TX_PWR_ENV_INFO_INTERPRET); + + if (pwr_category != client_type) + continue; + + /* get local transmit power envelope */ + if (use_local_tpe) { + if (pwr_interpret == IEEE80211_TPE_LOCAL_EIRP) { + non_psd_index = i; + non_psd_set = true; + } else if (pwr_interpret == IEEE80211_TPE_LOCAL_EIRP_PSD) { + psd_index = i; + psd_set = true; + } + /* get regulatory transmit power envelope */ + } else { + if (pwr_interpret == IEEE80211_TPE_REG_CLIENT_EIRP) { + non_psd_index = i; + non_psd_set = true; + } else if (pwr_interpret == IEEE80211_TPE_REG_CLIENT_EIRP_PSD) { + psd_index = i; + psd_set = true; + } + } + } + + if (non_psd_set && !psd_set) { + single_tpe = &bss_conf->tx_pwr_env[non_psd_index]; + pwr_count = u8_get_bits(single_tpe->tx_power_info, + IEEE80211_TX_PWR_ENV_INFO_COUNT); + pwr_interpret = u8_get_bits(single_tpe->tx_power_info, + IEEE80211_TX_PWR_ENV_INFO_INTERPRET); + arvif->reg_tpc_info.is_psd_power = false; + arvif->reg_tpc_info.eirp_power = 0; + + arvif->reg_tpc_info.num_pwr_levels = + ath11k_mac_get_tpe_count(pwr_interpret, pwr_count); + for (i = 0; i < arvif->reg_tpc_info.num_pwr_levels; i++) { + ath11k_dbg(ab, ATH11K_DBG_MAC, + "non PSD power[%d] : %d\n", + i, single_tpe->tx_power[i]); + arvif->reg_tpc_info.tpe[i] = single_tpe->tx_power[i] / 2; + } + } + + if (psd_set) { + single_tpe = &bss_conf->tx_pwr_env[psd_index]; + pwr_count = u8_get_bits(single_tpe->tx_power_info, + IEEE80211_TX_PWR_ENV_INFO_COUNT); + pwr_interpret = u8_get_bits(single_tpe->tx_power_info, + IEEE80211_TX_PWR_ENV_INFO_INTERPRET); + arvif->reg_tpc_info.is_psd_power = true; + + if (pwr_count == 0) { + ath11k_dbg(ab, ATH11K_DBG_MAC, + "TPE PSD power : %d\n", single_tpe->tx_power[0]); + arvif->reg_tpc_info.num_pwr_levels = + ath11k_mac_get_num_pwr_levels(&ctx->def); + for (i = 0; i < arvif->reg_tpc_info.num_pwr_levels; i++) + arvif->reg_tpc_info.tpe[i] = single_tpe->tx_power[0] / 2; + } else { + arvif->reg_tpc_info.num_pwr_levels = + ath11k_mac_get_tpe_count(pwr_interpret, pwr_count); + for (i = 0; i < arvif->reg_tpc_info.num_pwr_levels; i++) { + ath11k_dbg(ab, ATH11K_DBG_MAC, + "TPE PSD power[%d] : %d\n", + i, single_tpe->tx_power[i]); + arvif->reg_tpc_info.tpe[i] = single_tpe->tx_power[i] / 2; + } + } + } +} + static int ath11k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, @@ -5608,6 +5803,8 @@ ath11k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, if (power_type == IEEE80211_REG_UNSET_AP) power_type = IEEE80211_REG_LPI_AP; ath11k_reg_handle_chan_list(ab, reg_info, power_type); + + ath11k_mac_parse_tx_pwr_env(ar, vif, ctx); } /* for QCA6390 bss peer must be created before vdev_start */ From patchwork Tue Oct 26 11:19:08 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wen Gong X-Patchwork-Id: 12584579 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 352F5C433F5 for ; Tue, 26 Oct 2021 11:20:04 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 20C8B60232 for ; Tue, 26 Oct 2021 11:20:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235515AbhJZLW0 (ORCPT ); Tue, 26 Oct 2021 07:22:26 -0400 Received: from alexa-out.qualcomm.com ([129.46.98.28]:47817 "EHLO alexa-out.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234910AbhJZLWZ (ORCPT ); Tue, 26 Oct 2021 07:22:25 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1635247202; x=1666783202; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=/VdXjZeertDBhheMPWEn+odbnDuSPrVDKp4B0qugQGw=; b=r6viQJzKSPubsqhVyhoYhvd9sqSi3KCJkoYbv2520C4pvze0TL9EisgI umGbmlVi7uPi7Nn8OmIZT631YY7h+Y4XjQlSQ/xn9o6hbrIDHRh0uODu3 GYlifkdJwV/lTV838wIH4LLjU5sCphyUVIjgIvG2UxrAdb5qi+hxoFAOY c=; Received: from ironmsg09-lv.qualcomm.com ([10.47.202.153]) by alexa-out.qualcomm.com with ESMTP; 26 Oct 2021 04:20:02 -0700 X-QCInternal: smtphost Received: from nalasex01a.na.qualcomm.com ([10.47.209.196]) by ironmsg09-lv.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Oct 2021 04:20:02 -0700 Received: from wgong-HP3-Z230-SFF-Workstation.qca.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.922.7; Tue, 26 Oct 2021 04:20:00 -0700 From: Wen Gong To: CC: , Subject: [PATCH 10/15] ath11k: save max tx power in vdev start response event from firmware Date: Tue, 26 Oct 2021 07:19:08 -0400 Message-ID: <20211026111913.7346-11-quic_wgong@quicinc.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211026111913.7346-1-quic_wgong@quicinc.com> References: <20211026111913.7346-1-quic_wgong@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To nalasex01a.na.qualcomm.com (10.47.209.196) Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org Save the max tx power received in the vdev start response event from firmware. A subsequent patch will use this to calculate the final power value for WMI_VDEV_SET_TPC_POWER_CMDID. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1 Signed-off-by: Wen Gong --- drivers/net/wireless/ath/ath11k/core.h | 1 + drivers/net/wireless/ath/ath11k/wmi.c | 3 ++- drivers/net/wireless/ath/ath11k/wmi.h | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index 94516d14f89b..6969e0a6fc7b 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -605,6 +605,7 @@ struct ath11k { #endif bool dfs_block_radar_events; struct ath11k_thermal thermal; + s8 max_allowed_tx_power; }; struct ath11k_band_cap { diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c index 2684c042bbad..985035fab744 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -4484,6 +4484,7 @@ static int ath11k_pull_vdev_start_resp_tlv(struct ath11k_base *ab, struct sk_buf vdev_rsp->mac_id = ev->mac_id; vdev_rsp->cfgd_tx_streams = ev->cfgd_tx_streams; vdev_rsp->cfgd_rx_streams = ev->cfgd_rx_streams; + vdev_rsp->max_allowed_tx_power = ev->max_allowed_tx_power; kfree(tb); return 0; @@ -6655,7 +6656,7 @@ static void ath11k_vdev_start_resp_event(struct ath11k_base *ab, struct sk_buff } ar->last_wmi_vdev_start_status = 0; - + ar->max_allowed_tx_power = vdev_start_resp.max_allowed_tx_power; status = vdev_start_resp.status; if (WARN_ON_ONCE(status)) { diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h index c62c9e1982ce..2fc48aa662c6 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.h +++ b/drivers/net/wireless/ath/ath11k/wmi.h @@ -3975,6 +3975,7 @@ struct wmi_vdev_start_resp_event { }; u32 cfgd_tx_streams; u32 cfgd_rx_streams; + s32 max_allowed_tx_power; } __packed; /* VDEV start response status codes */ From patchwork Tue Oct 26 11:19:09 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wen Gong X-Patchwork-Id: 12584581 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 631AAC433EF for ; Tue, 26 Oct 2021 11:20:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 49DF160232 for ; Tue, 26 Oct 2021 11:20:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235521AbhJZLW1 (ORCPT ); Tue, 26 Oct 2021 07:22:27 -0400 Received: from alexa-out.qualcomm.com ([129.46.98.28]:1435 "EHLO alexa-out.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234586AbhJZLW1 (ORCPT ); Tue, 26 Oct 2021 07:22:27 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1635247203; x=1666783203; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=sbpeQREjnVTq37wlxm8JLwp65pWdIgu7PDfdXTli39I=; b=MytnxQ2d7x9h30QfKM+7R7aL1SPQLJNNglJr7H0q6aWRN6yBB5Ba8kQe 9/QvyHBqbm6UY8ftUKfTNS7N4LiY7WIdM8LnYSWpQo18eI0sRobMc6snN sK34M0fn+Yx9PGPh9qnWewUKRw8H6QqNtcyOCO81oWuKupe3zGNX1U+po w=; Received: from ironmsg07-lv.qualcomm.com ([10.47.202.151]) by alexa-out.qualcomm.com with ESMTP; 26 Oct 2021 04:20:03 -0700 X-QCInternal: smtphost Received: from nalasex01a.na.qualcomm.com ([10.47.209.196]) by ironmsg07-lv.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Oct 2021 04:20:03 -0700 Received: from wgong-HP3-Z230-SFF-Workstation.qca.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.922.7; Tue, 26 Oct 2021 04:20:02 -0700 From: Wen Gong To: CC: , Subject: [PATCH 11/15] ath11k: fill parameters for vdev_set_tpc_power wmi command Date: Tue, 26 Oct 2021 07:19:09 -0400 Message-ID: <20211026111913.7346-12-quic_wgong@quicinc.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211026111913.7346-1-quic_wgong@quicinc.com> References: <20211026111913.7346-1-quic_wgong@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To nalasex01a.na.qualcomm.com (10.47.209.196) Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org Prepare the parameters which is needed for wmi cmd vdev_set_tpc_power. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1 Signed-off-by: Wen Gong --- drivers/net/wireless/ath/ath11k/mac.c | 280 ++++++++++++++++++++++++++ drivers/net/wireless/ath/ath11k/mac.h | 3 + 2 files changed, 283 insertions(+) diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index 71991178a830..ed2dc4c81de8 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -5651,6 +5651,286 @@ static u8 ath11k_mac_get_num_pwr_levels(struct cfg80211_chan_def *chan_def) return num_pwr_levels; } +static u16 ath11k_mac_get_6g_start_frequency(struct cfg80211_chan_def *chan_def) +{ + u16 diff_seq; + + /* It is to get the lowest channel number's center frequency of the chan. + * For example, + * bandwidth=40 MHz, center frequency is 5965, lowest channel is 1 + * with center frequency 5955, its diff is 5965 - 5955 = 10. + * bandwidth=80 MHz, center frequency is 5985, lowest channel is 1 + * with center frequency 5955, its diff is 5985 - 5955 = 30. + * bandwidth=160 MHz, center frequency is 6025, lowest channel is 1 + * with center frequency 5955, its diff is 6025 - 5955 = 70. + */ + switch (chan_def->width) { + case NL80211_CHAN_WIDTH_160: + diff_seq = 70; + break; + case NL80211_CHAN_WIDTH_80: + case NL80211_CHAN_WIDTH_80P80: + diff_seq = 30; + break; + case NL80211_CHAN_WIDTH_40: + diff_seq = 10; + break; + default: + diff_seq = 0; + } + + return chan_def->center_freq1 - diff_seq; +} + +static u16 ath11k_mac_get_seg_freq(struct cfg80211_chan_def *chan_def, + u16 start_seq, u8 seq) +{ + u16 seg_seq; + + /* It is to get the center frequency of the specific bandwidth. + * start_seq means the lowest channel number's center frequency. + * seq 0/1/2/3 means 20 MHz/40 MHz/80 MHz/160 MHz&80P80. + * For example, + * lowest channel is 1, its center frequency 5955, + * center frequency is 5955 when bandwidth=20 MHz, its diff is 5955 - 5955 = 0. + * lowest channel is 1, its center frequency 5955, + * center frequency is 5965 when bandwidth=40 MHz, its diff is 5965 - 5955 = 10. + * lowest channel is 1, its center frequency 5955, + * center frequency is 5985 when bandwidth=80 MHz, its diff is 5985 - 5955 = 30. + * lowest channel is 1, its center frequency 5955, + * center frequency is 6025 when bandwidth=160 MHz, its diff is 6025 - 5955 = 70. + */ + if (chan_def->width == NL80211_CHAN_WIDTH_80P80 && seq == 3) + return chan_def->center_freq2; + + seg_seq = 10 * (BIT(seq) - 1); + return seg_seq + start_seq; +} + +static void ath11k_mac_get_psd_channel(struct ath11k *ar, + u16 step_freq, + u16 *start_freq, + u16 *center_freq, + u8 i, + struct ieee80211_channel **temp_chan, + s8 *tx_power) +{ + /* It is to get the the center frequency for each 20 MHz. + * For example, if the chan is 160 MHz and center frequency is 6025, + * then it include 8 channels, they are 1/5/9/13/17/21/25/29, + * channel number 1's center frequency is 5955, it is parameter start_freq. + * parameter i is the step of the 8 channels. i is 0~7 for the 8 channels. + * the channel 1/5/9/13/17/21/25/29 maps i=0/1/2/3/4/5/6/7, + * and maps its center frequency is 5955/5975/5995/6015/6035/6055/6075/6095, + * the gap is 20 for each channel, parameter step_freq means the gap. + * after get the center frequency of each channel, it is easy to find the + * struct ieee80211_channel of it and get the max_reg_power. + */ + *center_freq = *start_freq + i * step_freq; + *temp_chan = ieee80211_get_channel(ar->hw->wiphy, *center_freq); + *tx_power = (*temp_chan)->max_reg_power; +} + +static void ath11k_mac_get_eirp_power(struct ath11k *ar, + u16 *start_freq, + u16 *center_freq, + u8 i, + struct ieee80211_channel **temp_chan, + struct cfg80211_chan_def *def, + s8 *tx_power) +{ + /* It is to get the the center frequency for 20 MHz/40 MHz/80 MHz/ + * 160 MHz&80P80 bandwidth, and then plus 10 to the center frequency, + * it is the center frequency of a channel number. + * For example, when configured channel number is 1. + * center frequency is 5965 when bandwidth=40 MHz, after plus 10, it is 5975, + * then it is channel number 5. + * center frequency is 5985 when bandwidth=80 MHz, after plus 10, it is 5995, + * then it is channel number 9. + * center frequency is 6025 when bandwidth=160 MHz, after plus 10, it is 6035, + * then it is channel number 17. + * after get the center frequency of each channel, it is easy to find the + * struct ieee80211_channel of it and get the max_reg_power. + */ + *center_freq = ath11k_mac_get_seg_freq(def, *start_freq, i); + + /* For the 20 MHz, its center frequency is same with same channel */ + if (i != 0) + *center_freq += 10; + + *temp_chan = ieee80211_get_channel(ar->hw->wiphy, *center_freq); + *tx_power = (*temp_chan)->max_reg_power; +} + +void ath11k_mac_fill_reg_tpc_info(struct ath11k *ar, + struct ieee80211_vif *vif, + struct ieee80211_chanctx_conf *ctx) +{ + struct ath11k_base *ab = ar->ab; + struct ath11k_vif *arvif = (void *)vif->drv_priv; + struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; + struct ath11k_reg_tpc_power_info *reg_tpc_info = &arvif->reg_tpc_info; + struct ieee80211_channel *chan, *temp_chan; + u8 pwr_lvl_idx, num_pwr_levels, pwr_reduction; + bool is_psd_power = false, is_tpe_present = false; + s8 max_tx_power[IEEE80211_MAX_NUM_PWR_LEVEL], + psd_power, tx_power, eirp_power; + u16 oper_freq, start_freq, center_freq; + + chan = ctx->def.chan; + oper_freq = ctx->def.chan->center_freq; + start_freq = ath11k_mac_get_6g_start_frequency(&ctx->def); + pwr_reduction = bss_conf->pwr_reduction; + + if (arvif->reg_tpc_info.num_pwr_levels) { + is_tpe_present = true; + num_pwr_levels = arvif->reg_tpc_info.num_pwr_levels; + } else { + num_pwr_levels = ath11k_mac_get_num_pwr_levels(&ctx->def); + } + + for (pwr_lvl_idx = 0; pwr_lvl_idx < num_pwr_levels; pwr_lvl_idx++) { + /* STA received TPE IE*/ + if (is_tpe_present) { + /* local power is PSD power*/ + if (chan->flags & IEEE80211_CHAN_PSD) { + /* Connecting AP is psd power */ + if (reg_tpc_info->is_psd_power) { + is_psd_power = true; + ath11k_mac_get_psd_channel(ar, 20, + &start_freq, + ¢er_freq, + pwr_lvl_idx, + &temp_chan, + &tx_power); + psd_power = temp_chan->psd; + eirp_power = tx_power; + max_tx_power[pwr_lvl_idx] = + min_t(s8, + psd_power, + reg_tpc_info->tpe[pwr_lvl_idx]); + /* Connecting AP is not psd power */ + } else { + ath11k_mac_get_eirp_power(ar, + &start_freq, + ¢er_freq, + pwr_lvl_idx, + &temp_chan, + &ctx->def, + &tx_power); + psd_power = temp_chan->psd; + /* convert psd power to EIRP power based + * on channel width + */ + tx_power = + min_t(s8, tx_power, + psd_power + 13 + pwr_lvl_idx * 3); + max_tx_power[pwr_lvl_idx] = + min_t(s8, + tx_power, + reg_tpc_info->tpe[pwr_lvl_idx]); + } + /* local power is not PSD power */ + } else { + /* Connecting AP is psd power */ + if (reg_tpc_info->is_psd_power) { + is_psd_power = true; + ath11k_mac_get_psd_channel(ar, 20, + &start_freq, + ¢er_freq, + pwr_lvl_idx, + &temp_chan, + &tx_power); + eirp_power = tx_power; + max_tx_power[pwr_lvl_idx] = + reg_tpc_info->tpe[pwr_lvl_idx]; + /* Connecting AP is not psd power */ + } else { + ath11k_mac_get_eirp_power(ar, + &start_freq, + ¢er_freq, + pwr_lvl_idx, + &temp_chan, + &ctx->def, + &tx_power); + max_tx_power[pwr_lvl_idx] = + min_t(s8, + tx_power, + reg_tpc_info->tpe[pwr_lvl_idx]); + } + } + /* STA not received TPE IE */ + } else { + /* local power is PSD power*/ + if (chan->flags & IEEE80211_CHAN_PSD) { + is_psd_power = true; + ath11k_mac_get_psd_channel(ar, 20, + &start_freq, + ¢er_freq, + pwr_lvl_idx, + &temp_chan, + &tx_power); + psd_power = temp_chan->psd; + eirp_power = tx_power; + max_tx_power[pwr_lvl_idx] = psd_power; + } else { + ath11k_mac_get_eirp_power(ar, + &start_freq, + ¢er_freq, + pwr_lvl_idx, + &temp_chan, + &ctx->def, + &tx_power); + max_tx_power[pwr_lvl_idx] = + min_t(s8, + tx_power, + reg_tpc_info->tpe[pwr_lvl_idx]); + } + } + + if (is_psd_power) { + /* If AP local power constraint is present */ + if (pwr_reduction) + eirp_power = eirp_power - pwr_reduction; + + /* If firmware updated max tx power is non zero, then take + * the min of firmware updated ap tx power + * and max power derived from above mentioned parameters. + */ + ath11k_dbg(ab, ATH11K_DBG_MAC, + "eirp power : %d firmware report power : %d\n", + eirp_power, ar->max_allowed_tx_power); + if (ar->max_allowed_tx_power) + eirp_power = min_t(s8, + eirp_power, + ar->max_allowed_tx_power); + } else { + /* If AP local power constraint is present */ + if (pwr_reduction) + max_tx_power[pwr_lvl_idx] = + max_tx_power[pwr_lvl_idx] - pwr_reduction; + /* If firmware updated max tx power is non zero, then take + * the min of firmware updated ap tx power + * and max power derived from above mentioned parameters. + */ + if (ar->max_allowed_tx_power) + max_tx_power[pwr_lvl_idx] = + min_t(s8, + max_tx_power[pwr_lvl_idx], + ar->max_allowed_tx_power); + } + reg_tpc_info->chan_power_info[pwr_lvl_idx].chan_cfreq = center_freq; + reg_tpc_info->chan_power_info[pwr_lvl_idx].tx_power = + max_tx_power[pwr_lvl_idx]; + } + + reg_tpc_info->num_pwr_levels = num_pwr_levels; + reg_tpc_info->is_psd_power = is_psd_power; + reg_tpc_info->eirp_power = eirp_power; + reg_tpc_info->power_type_6g = + ath11k_ieee80211_ap_pwr_type_convert(vif->bss_conf.power_type); +} + static void ath11k_mac_parse_tx_pwr_env(struct ath11k *ar, struct ieee80211_vif *vif, struct ieee80211_chanctx_conf *ctx) diff --git a/drivers/net/wireless/ath/ath11k/mac.h b/drivers/net/wireless/ath/ath11k/mac.h index 6d308267e4b8..1c26934729df 100644 --- a/drivers/net/wireless/ath/ath11k/mac.h +++ b/drivers/net/wireless/ath/ath11k/mac.h @@ -152,4 +152,7 @@ enum ath11k_supported_bw ath11k_mac_mac80211_bw_to_ath11k_bw(enum rate_info_bw b enum hal_encrypt_type ath11k_dp_tx_get_encrypt_type(u32 cipher); void ath11k_mac_handle_beacon(struct ath11k *ar, struct sk_buff *skb); void ath11k_mac_handle_beacon_miss(struct ath11k *ar, u32 vdev_id); +void ath11k_mac_fill_reg_tpc_info(struct ath11k *ar, + struct ieee80211_vif *vif, + struct ieee80211_chanctx_conf *ctx); #endif From patchwork Tue Oct 26 11:19:10 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wen Gong X-Patchwork-Id: 12584583 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B13BCC433F5 for ; Tue, 26 Oct 2021 11:20:06 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9961D60238 for ; Tue, 26 Oct 2021 11:20:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234535AbhJZLW3 (ORCPT ); Tue, 26 Oct 2021 07:22:29 -0400 Received: from alexa-out.qualcomm.com ([129.46.98.28]:47817 "EHLO alexa-out.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234827AbhJZLW2 (ORCPT ); Tue, 26 Oct 2021 07:22:28 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1635247205; x=1666783205; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=pcDXgAvScubWMYKqa9HXGkpyxH1Z8qPtr+OQbiS2bLo=; b=gyZepDz8ZFJrtZFw+0x/ZgIs5yw0aC+CtyeYLmsPGjPlKE8cxwpsPgG9 cmIzXm+CLau2RqVpWn9nltg9vCRFTU0y1NOhUQiLfvxrBtGHYEmxORHI+ egOEny19soMCmFQgPQ7BYIsF6vyUlc1dbIatIiJfNrWiJ0T0VZd0e3A52 0=; Received: from ironmsg-lv-alpha.qualcomm.com ([10.47.202.13]) by alexa-out.qualcomm.com with ESMTP; 26 Oct 2021 04:20:05 -0700 X-QCInternal: smtphost Received: from nalasex01a.na.qualcomm.com ([10.47.209.196]) by ironmsg-lv-alpha.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Oct 2021 04:20:05 -0700 Received: from wgong-HP3-Z230-SFF-Workstation.qca.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.922.7; Tue, 26 Oct 2021 04:20:03 -0700 From: Wen Gong To: CC: , Subject: [PATCH 12/15] ath11k: add WMI_TLV_SERVICE_EXT_TPC_REG_SUPPORT service bit Date: Tue, 26 Oct 2021 07:19:10 -0400 Message-ID: <20211026111913.7346-13-quic_wgong@quicinc.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211026111913.7346-1-quic_wgong@quicinc.com> References: <20211026111913.7346-1-quic_wgong@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To nalasex01a.na.qualcomm.com (10.47.209.196) Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org Firmware advertises support for SERVICE_EXT_TPC_REG via a WMI service bit. Add the definition of this service bit so that a subsequent patch can check whether or not firmware supports this service. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1 Signed-off-by: Wen Gong --- drivers/net/wireless/ath/ath11k/wmi.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h index 2fc48aa662c6..ead6c26fafa4 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.h +++ b/drivers/net/wireless/ath/ath11k/wmi.h @@ -2065,6 +2065,8 @@ enum wmi_tlv_service { WMI_MAX_EXT_SERVICE = 256, + WMI_TLV_SERVICE_EXT_TPC_REG_SUPPORT = 280, + WMI_TLV_SERVICE_REG_CC_EXT_EVENT_SUPPORT = 281, WMI_MAX_EXT2_SERVICE From patchwork Tue Oct 26 11:19:11 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wen Gong X-Patchwork-Id: 12584585 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 53CEBC433F5 for ; Tue, 26 Oct 2021 11:20:08 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 41D1C60238 for ; Tue, 26 Oct 2021 11:20:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235525AbhJZLWa (ORCPT ); Tue, 26 Oct 2021 07:22:30 -0400 Received: from alexa-out.qualcomm.com ([129.46.98.28]:47817 "EHLO alexa-out.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235506AbhJZLWa (ORCPT ); Tue, 26 Oct 2021 07:22:30 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1635247207; x=1666783207; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=N4FQ+ESHIEwX2dIl8VLFLizSBZV3arl7rG3DDOVO4+Y=; b=pBXJWuNCNmbuoPzdp3xbzHX8fFr6T2Mv9ucoJq9kUbNJF9J6kBtOMTXM l9SSkfdpiGg+5yMkJ+c06lM3zHhFtAWFpcEeKC0Z0s4bldPAGHBY3Kykj C5HdyutM2KPEaFR7+pp3ZIzjIcEaz1nrd96Iq1N3JY0jreDgcGuGRWTk6 I=; Received: from ironmsg-lv-alpha.qualcomm.com ([10.47.202.13]) by alexa-out.qualcomm.com with ESMTP; 26 Oct 2021 04:20:07 -0700 X-QCInternal: smtphost Received: from nalasex01a.na.qualcomm.com ([10.47.209.196]) by ironmsg-lv-alpha.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Oct 2021 04:20:07 -0700 Received: from wgong-HP3-Z230-SFF-Workstation.qca.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.922.7; Tue, 26 Oct 2021 04:20:04 -0700 From: Wen Gong To: CC: , Subject: [PATCH 13/15] ath11k: discard BSS_CHANGED_TXPOWER when EXT_TPC_REG_SUPPORT for 6 GHz Date: Tue, 26 Oct 2021 07:19:11 -0400 Message-ID: <20211026111913.7346-14-quic_wgong@quicinc.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211026111913.7346-1-quic_wgong@quicinc.com> References: <20211026111913.7346-1-quic_wgong@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To nalasex01a.na.qualcomm.com (10.47.209.196) Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org When station is connected to a 6 GHz AP, it has 2 way to configure the power limit to firmware. The first way is to send 2 wmi command WMI_PDEV_PARAM_TXPOWER_LIMIT2G/WMI_PDEV_PARAM_TXPOWER_LIMIT5G to firmware, the second way is to send WMI_VDEV_SET_TPC_POWER_CMDID to firmware which include more parameters for power control. When firmware support SERVICE_EXT_TPC_REG, it means firmware support the second way for WMI_VDEV_SET_TPC_POWER_CMDID, then ath11k discard BSS_CHANGED_TXPOWER flag from mac80211 which is used to the first way for 6 GHz band in this patch and select the second way in the subsequent patch. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1 Signed-off-by: Wen Gong --- drivers/net/wireless/ath/ath11k/core.h | 6 ++++++ drivers/net/wireless/ath/ath11k/mac.c | 19 +++++++++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index 6969e0a6fc7b..6ef639975725 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -1017,4 +1017,10 @@ static inline bool ath11k_support_6G_cc_ext(struct ath11k *ar) return ath11k_support_cc_ext(ar->ab) && ar->supports_6ghz; } +static inline bool ath11k_support_tpc_ext(struct ath11k *ar) +{ + return ath11k_support_6G_cc_ext(ar) && + test_bit(WMI_TLV_SERVICE_EXT_TPC_REG_SUPPORT, ar->ab->wmi_ab.svc_map); +} + #endif /* _CORE_H_ */ diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index ed2dc4c81de8..301e08a85f47 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -2170,6 +2170,16 @@ static int ath11k_mac_config_obss_pd(struct ath11k *ar, return 0; } +static bool ath11k_mac_station_support_tpc(struct ath11k *ar, + struct ath11k_vif *arvif, + struct cfg80211_chan_def *chandef) +{ + return ath11k_support_tpc_ext(ar) && + arvif->vdev_type == WMI_VDEV_TYPE_STA && + chandef->chan && + chandef->chan->band == NL80211_BAND_6GHZ; +} + static void ath11k_mac_op_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *info, @@ -2353,8 +2363,13 @@ static void ath11k_mac_op_bss_info_changed(struct ieee80211_hw *hw, ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac vdev_id %i txpower %d\n", arvif->vdev_id, info->txpower); - arvif->txpower = info->txpower; - ath11k_mac_txpower_recalc(ar); + if (ath11k_mac_station_support_tpc(ar, arvif, &info->chandef)) { + ath11k_dbg(ar->ab, ATH11K_DBG_MAC, + "discard tx power, change to set TPC power\n"); + } else { + arvif->txpower = info->txpower; + ath11k_mac_txpower_recalc(ar); + } } if (changed & BSS_CHANGED_MCAST_RATE && From patchwork Tue Oct 26 11:19:12 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wen Gong X-Patchwork-Id: 12584587 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 55FF6C4332F for ; Tue, 26 Oct 2021 11:20:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3C44060232 for ; Tue, 26 Oct 2021 11:20:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235523AbhJZLWb (ORCPT ); Tue, 26 Oct 2021 07:22:31 -0400 Received: from alexa-out.qualcomm.com ([129.46.98.28]:1435 "EHLO alexa-out.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234586AbhJZLWb (ORCPT ); Tue, 26 Oct 2021 07:22:31 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1635247208; x=1666783208; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=sBR8Q1VwDW3hNaTsS7QoeMLSi+MpcCoVcWml3hLms6s=; b=tpCUbYqbxkVov338Xj9Hn6RPs80vrGXwuSuY4kbfWh1TruyG+3ZNQWuv FvmWGUnR0To5am+DO7IZEyRP7T/eRBW3QP7k6vAxwilFHBw1k2KHsxseC YZDyg/ozg35MgsTlDQnb/O1QHtMhLxGkwkiBc9DrWJ1SnSpc8vUFjC4Ke 4=; Received: from ironmsg07-lv.qualcomm.com ([10.47.202.151]) by alexa-out.qualcomm.com with ESMTP; 26 Oct 2021 04:20:07 -0700 X-QCInternal: smtphost Received: from nalasex01a.na.qualcomm.com ([10.47.209.196]) by ironmsg07-lv.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Oct 2021 04:20:08 -0700 Received: from wgong-HP3-Z230-SFF-Workstation.qca.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.922.7; Tue, 26 Oct 2021 04:20:06 -0700 From: Wen Gong To: CC: , Subject: [PATCH 14/15] ath11k: add handler for WMI_VDEV_SET_TPC_POWER_CMDID Date: Tue, 26 Oct 2021 07:19:12 -0400 Message-ID: <20211026111913.7346-15-quic_wgong@quicinc.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211026111913.7346-1-quic_wgong@quicinc.com> References: <20211026111913.7346-1-quic_wgong@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To nalasex01a.na.qualcomm.com (10.47.209.196) Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org Add the handler for WMI_VDEV_SET_TPC_POWER_CMDID, it is for 6 GHz band. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1 Signed-off-by: Wen Gong --- drivers/net/wireless/ath/ath11k/wmi.c | 63 +++++++++++++++++++++++++++ drivers/net/wireless/ath/ath11k/wmi.h | 61 ++++++++++++++++++++++++++ 2 files changed, 124 insertions(+) diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c index 985035fab744..603a4373af57 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -2225,6 +2225,69 @@ int ath11k_wmi_send_scan_start_cmd(struct ath11k *ar, return ret; } +int ath11k_wmi_send_vdev_set_tpc_power(struct ath11k *ar, + u32 vdev_id, + struct ath11k_reg_tpc_power_info *param) +{ + struct ath11k_pdev_wmi *wmi = ar->wmi; + struct wmi_vdev_set_tpc_power_cmd *cmd; + struct wmi_vdev_ch_power_info *ch; + struct sk_buff *skb; + struct wmi_tlv *tlv; + u8 *ptr; + int i, ret, len; + + len = sizeof(*cmd) + TLV_HDR_SIZE; + len += (sizeof(struct wmi_vdev_ch_power_info) * param->num_pwr_levels); + + skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len); + if (!skb) + return -ENOMEM; + + ptr = skb->data; + + cmd = (struct wmi_vdev_set_tpc_power_cmd *)ptr; + cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_VDEV_SET_TPC_POWER_CMD) | + FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); + cmd->vdev_id = vdev_id; + cmd->psd_power = param->is_psd_power; + cmd->eirp_power = param->eirp_power; + cmd->power_type_6ghz = param->power_type_6g; + ath11k_dbg(ar->ab, ATH11K_DBG_WMI, + "wmi TPC vdev_id: %d is_psd_power: %d eirp_power: %d power_type_6g: %d\n", + vdev_id, param->is_psd_power, param->eirp_power, param->power_type_6g); + + ptr += sizeof(*cmd); + tlv = (struct wmi_tlv *)ptr; + tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_STRUCT) | + FIELD_PREP(WMI_TLV_LEN, param->num_pwr_levels * sizeof(*ch)); + + ptr += TLV_HDR_SIZE; + ch = (struct wmi_vdev_ch_power_info *)ptr; + + for (i = 0; i < param->num_pwr_levels; i++, ch++) { + ch->tlv_header = FIELD_PREP(WMI_TLV_TAG, + WMI_TAG_VDEV_CH_POWER_INFO) | + FIELD_PREP(WMI_TLV_LEN, + sizeof(*ch) - TLV_HDR_SIZE); + + ch->chan_cfreq = param->chan_power_info[i].chan_cfreq; + ch->tx_power = param->chan_power_info[i].tx_power; + + ath11k_dbg(ar->ab, ATH11K_DBG_WMI, + "wmi TPC chan_cfreq: %d , tx_power: %d\n", + ch->chan_cfreq, ch->tx_power); + } + + ret = ath11k_wmi_cmd_send(wmi, skb, + WMI_VDEV_SET_TPC_POWER_CMDID); + if (ret) { + ath11k_warn(ar->ab, "failed to send WMI_VDEV_SET_TPC_POWER_CMDID\n"); + dev_kfree_skb(skb); + } + return ret; +} + int ath11k_wmi_send_scan_stop_cmd(struct ath11k *ar, struct scan_cancel_param *param) { diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h index ead6c26fafa4..8f5c14537fdc 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.h +++ b/drivers/net/wireless/ath/ath11k/wmi.h @@ -12,6 +12,7 @@ struct ath11k_base; struct ath11k; struct ath11k_fw_stats; +struct ath11k_reg_tpc_power_info; #define PSOC_HOST_MAX_NUM_SS (8) @@ -294,6 +295,36 @@ enum wmi_tlv_cmd_id { WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID, WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID, WMI_VDEV_ADD_MAC_ADDR_TO_RX_FILTER_CMDID, + /** WMI commands related to dbg arp stats */ + WMI_VDEV_SET_ARP_STAT_CMDID, + WMI_VDEV_GET_ARP_STAT_CMDID, + /** get tx power for the current vdev */ + WMI_VDEV_GET_TX_POWER_CMDID, + /* limit STA offchannel activity */ + WMI_VDEV_LIMIT_OFFCHAN_CMDID, + /** To set custom software retries per-AC for vdev */ + WMI_VDEV_SET_CUSTOM_SW_RETRY_TH_CMDID, + /** To set chainmask configuration for vdev */ + WMI_VDEV_CHAINMASK_CONFIG_CMDID, + WMI_VDEV_GET_BCN_RECEPTION_STATS_CMDID, + /* request LTE-Coex info */ + WMI_VDEV_GET_MWS_COEX_INFO_CMDID, + /** delete all peer (excluding bss peer) */ + WMI_VDEV_DELETE_ALL_PEER_CMDID, + /* To set bss max idle time related parameters */ + WMI_VDEV_BSS_MAX_IDLE_TIME_CMDID, + /** Indicates firmware to trigger Audio sync */ + WMI_VDEV_AUDIO_SYNC_TRIGGER_CMDID, + /** Gives Qtimer value to firmware */ + WMI_VDEV_AUDIO_SYNC_QTIMER_CMDID, + /** Preferred channel list for each vdev */ + WMI_VDEV_SET_PCL_CMDID, + /** VDEV_GET_BIG_DATA_CMD IS DEPRECATED - DO NOT USE */ + WMI_VDEV_GET_BIG_DATA_CMDID, + /** Get per vdev BIG DATA stats phase 2 */ + WMI_VDEV_GET_BIG_DATA_P2_CMDID, + /** set TPC PSD/non-PSD power */ + WMI_VDEV_SET_TPC_POWER_CMDID, WMI_PEER_CREATE_CMDID = WMI_TLV_CMD(WMI_GRP_PEER), WMI_PEER_DELETE_CMDID, WMI_PEER_FLUSH_TIDS_CMDID, @@ -1837,6 +1868,8 @@ enum wmi_tlv_tag { 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_VDEV_SET_TPC_POWER_CMD = 0x3B5, + WMI_TAG_VDEV_CH_POWER_INFO, WMI_TAG_MAX }; @@ -3061,6 +3094,31 @@ struct wlan_ssid { u8 ssid[WLAN_SSID_MAX_LEN]; }; +struct wmi_vdev_ch_power_info { + u32 tlv_header; + u32 chan_cfreq; /* Channel center frequency (MHz) */ + /* Unit: dBm, either PSD/EIRP power for this frequency or + * incremental for non-PSD BW + */ + u32 tx_power; +} __packed; + +struct wmi_vdev_set_tpc_power_cmd { + u32 tlv_header; + u32 vdev_id; + u32 psd_power; /* Value: 0 or 1, is PSD power or not */ + u32 eirp_power; /* Maximum EIRP power (dBm units), valid only if power is PSD */ + u32 power_type_6ghz; /* Type: WMI_6GHZ_REG_TYPE, used for halphy CTL lookup */ + /* This fixed_param TLV is followed by the below TLVs: + * num_pwr_levels of wmi_vdev_ch_power_info + * For PSD power, it is the PSD/EIRP power of the frequency (20 MHz chunks). + * For non-PSD power, the power values are for 20, 40, and till + * BSS BW power levels. + * The num_pwr_levels will be checked by sw how many elements present + * in the variable-length array. + */ +} __packed; + #define WMI_IE_BITMAP_SIZE 8 #define WMI_SCAN_MAX_NUM_SSID 0x0A @@ -5536,4 +5594,7 @@ void ath11k_reg_reset_info(struct cur_regulatory_info *reg_info); int ath11k_reg_handle_chan_list(struct ath11k_base *ab, struct cur_regulatory_info *reg_info, enum ieee80211_ap_reg_power power_type); +int ath11k_wmi_send_vdev_set_tpc_power(struct ath11k *ar, + u32 vdev_id, + struct ath11k_reg_tpc_power_info *param); #endif From patchwork Tue Oct 26 11:19:13 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wen Gong X-Patchwork-Id: 12584589 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id DF965C433EF for ; Tue, 26 Oct 2021 11:20:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id CCE6D60238 for ; Tue, 26 Oct 2021 11:20:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234910AbhJZLWd (ORCPT ); Tue, 26 Oct 2021 07:22:33 -0400 Received: from alexa-out.qualcomm.com ([129.46.98.28]:47817 "EHLO alexa-out.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235527AbhJZLWc (ORCPT ); Tue, 26 Oct 2021 07:22:32 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1635247209; x=1666783209; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=0ZhUzRgAxpp99YUc6DckpZ0gEBQu58giLRw4uQmyJXE=; b=zELk4TzqYixmi6UyTMlEvPumVNUPaM6VtuuiVJ6ohg8Yjz6rN1dW59Nn k30UfWiFGUxQtPBl8Fe4xSmgJb1W0Ggd5FoyYn11Zg4ZKfnQiXWLTUlxq 5kTFVAbIgRWTvzZ1CkCYWmUcF191g787pVYAu3M5Z24ktO8H3HDrlGePJ k=; Received: from ironmsg09-lv.qualcomm.com ([10.47.202.153]) by alexa-out.qualcomm.com with ESMTP; 26 Oct 2021 04:20:09 -0700 X-QCInternal: smtphost Received: from nalasex01a.na.qualcomm.com ([10.47.209.196]) by ironmsg09-lv.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Oct 2021 04:20:09 -0700 Received: from wgong-HP3-Z230-SFF-Workstation.qca.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.922.7; Tue, 26 Oct 2021 04:20:07 -0700 From: Wen Gong To: CC: , Subject: [PATCH 15/15] ath11k: send TPC power to firmware for 6 GHz station Date: Tue, 26 Oct 2021 07:19:13 -0400 Message-ID: <20211026111913.7346-16-quic_wgong@quicinc.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211026111913.7346-1-quic_wgong@quicinc.com> References: <20211026111913.7346-1-quic_wgong@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To nalasex01a.na.qualcomm.com (10.47.209.196) Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org When station is connected to a 6 GHz AP, it has 2 way to configure the power limit to firmware. The first way is to send 2 wmi command WMI_PDEV_PARAM_TXPOWER_LIMIT2G/WMI_PDEV_PARAM_TXPOWER_LIMIT5G to firmware, the second way is to send WMI_VDEV_SET_TPC_POWER_CMDID to firmware which include more parameters for power control. The first way is disabled in previous patch "ath11k: discard BSS_CHANGED_TXPOWER when EXT_TPC_REG_SUPPORT for 6 GHz". Prepare the parameter for wmi command WMI_VDEV_SET_TPC_POWER_CMDID and send the firmware after vdev start response success from firmware, it is for the second way of power control. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1 Signed-off-by: Wen Gong --- drivers/net/wireless/ath/ath11k/mac.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index 301e08a85f47..88c18ffee7a3 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -5312,6 +5312,12 @@ ath11k_mac_vdev_start_restart(struct ath11k_vif *arvif, return ret; } + if (ath11k_mac_station_support_tpc(ar, arvif, chandef)) { + ath11k_mac_fill_reg_tpc_info(ar, arvif->vif, &arvif->chanctx); + ath11k_wmi_send_vdev_set_tpc_power(ar, arvif->vdev_id, + &arvif->reg_tpc_info); + } + ar->num_started_vdevs++; ath11k_dbg(ab, ATH11K_DBG_MAC, "vdev %pM started, vdev_id %d\n", arvif->vif->addr, arvif->vdev_id); @@ -6098,7 +6104,7 @@ ath11k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, if (power_type == IEEE80211_REG_UNSET_AP) power_type = IEEE80211_REG_LPI_AP; ath11k_reg_handle_chan_list(ab, reg_info, power_type); - + arvif->chanctx = *ctx; ath11k_mac_parse_tx_pwr_env(ar, vif, ctx); }