From patchwork Wed Sep 18 21:20:48 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pradeep Kumar Chitrapu X-Patchwork-Id: 829541 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A06681CA6B9 for ; Wed, 18 Sep 2024 21:21:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726694475; cv=none; b=HjUnHV2ZbMRZne/OD71kC1p0zBs+1+LVanM+3YbUfCnjvvtSry2r0Dj0HBjHnId1ltZw0ebTJaEZDcXBybkc2yiiGRlcH5s4feXisp9WApElGptz2Qn1SEtO3VDLKyE5m56eJftK/dpin6HPZGOk3hMBHkxoo966Jp4vlC9e2rY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726694475; c=relaxed/simple; bh=lJX5iM2Ahf/ROaeR2Kk4suhcbwA47aOSPqyQsesg4A0=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=RYEWdi9+UZKYtzHKfAF5xdIOkpdgQjBK8hE1SX/f0rJDxozjZe1jDY28C+kzN4uhSwcBSwr7pZjMLL8LELNITE6fIk/zDY5UAO/jdeUPBnTrmrckzZOwaCFIQ1nt6ssDZDfpJADBjCIuMXB7HNChH3qSMlmYTV9QTDxpBK0fQxM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=EtpV59A6; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="EtpV59A6" Received: from pps.filterd (m0279862.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 48IL3WbX003099; Wed, 18 Sep 2024 21:21:07 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= 3ukRiLVgAcc9GoJxAaFrgsHYImZ/9ZPgSlMf75Ew/1Y=; b=EtpV59A6K8yD5o5B 8JSYPL7TI2tnIQciUmyLNJig3DWGn3AZbFqPjgTYUgoQLHjsNWd+WRAKx13tQhSW peq0OW9986uI1TFVpaw0pwVXoBiStEI5MH/7ThiA5nIAI4hYBI6+iiwL7qWpboSL UrG9sWI35wsgcjedTtrzR2QfpeTAvlnReoac/49o5GAysu1oGDN79VAAP7tDZbO2 trx/XdQmW/8iqtRR3Idhjcod6B6ovXKkmAZUHzhp4zRupTUsKOU84X3aTYZQLN/B 46HuFZSlOJEB/63Co7I2K8YfQT3FikP2mkrIsDwH78Y2OekhXJWFe7dU4SsX6nh6 sIXVxA== Received: from nalasppmta04.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 41n4gd387e-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 18 Sep 2024 21:21:07 +0000 (GMT) Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com [10.47.209.196]) by NALASPPMTA04.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id 48ILL6rr020545 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 18 Sep 2024 21:21:06 GMT Received: from ath12k-linux1.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.1544.9; Wed, 18 Sep 2024 14:21:06 -0700 From: Pradeep Kumar Chitrapu To: CC: , Pradeep Kumar Chitrapu , Muna Sinada , "Jeff Johnson" Subject: [PATCH V8 1/9] wifi: ath12k: push HE MU-MIMO params to hardware Date: Wed, 18 Sep 2024 14:20:48 -0700 Message-ID: <20240918212056.4137076-2-quic_pradeepc@quicinc.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240918212056.4137076-1-quic_pradeepc@quicinc.com> References: <20240918212056.4137076-1-quic_pradeepc@quicinc.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01a.na.qualcomm.com (10.47.209.196) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-ORIG-GUID: QTgqLsl2p5OGLwWEQsGrsmA8q68U11H8 X-Proofpoint-GUID: QTgqLsl2p5OGLwWEQsGrsmA8q68U11H8 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.60.29 definitions=2024-09-06_09,2024-09-06_01,2024-09-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 suspectscore=0 bulkscore=0 clxscore=1015 spamscore=0 adultscore=0 lowpriorityscore=0 mlxlogscore=999 impostorscore=0 mlxscore=0 priorityscore=1501 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2408220000 definitions=main-2409180140 Currently, only the HE IE in management frames is updated with respect to MU-MIMO configurations, but this change is not reflected in the hardware. Add support to propagate MU-MIMO configurations to the hardware as well. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1 Co-developed-by: Muna Sinada Signed-off-by: Muna Sinada Signed-off-by: Pradeep Kumar Chitrapu Acked-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/mac.c | 215 +++++++++++++++++--------- drivers/net/wireless/ath/ath12k/mac.h | 15 ++ drivers/net/wireless/ath/ath12k/wmi.h | 28 +--- 3 files changed, 156 insertions(+), 102 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 137394c36460..8ab15de8243e 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -2848,6 +2848,108 @@ static int ath12k_setup_peer_smps(struct ath12k *ar, struct ath12k_vif *arvif, ath12k_smps_map[smps]); } +static int ath12k_mac_set_he_txbf_conf(struct ath12k_vif *arvif) +{ + struct ath12k *ar = arvif->ar; + u32 param = WMI_VDEV_PARAM_SET_HEMU_MODE; + u32 value = 0; + int ret; + + if (!arvif->vif->bss_conf.he_support) + return 0; + + if (arvif->vif->bss_conf.he_su_beamformer) { + value |= u32_encode_bits(HE_SU_BFER_ENABLE, HE_MODE_SU_TX_BFER); + if (arvif->vif->bss_conf.he_mu_beamformer && + arvif->vdev_type == WMI_VDEV_TYPE_AP) + value |= u32_encode_bits(HE_MU_BFER_ENABLE, HE_MODE_MU_TX_BFER); + } + + if (arvif->vif->type != NL80211_IFTYPE_MESH_POINT) { + value |= u32_encode_bits(HE_DL_MUOFDMA_ENABLE, HE_MODE_DL_OFDMA) | + u32_encode_bits(HE_UL_MUOFDMA_ENABLE, HE_MODE_UL_OFDMA); + + if (arvif->vif->bss_conf.he_full_ul_mumimo) + value |= u32_encode_bits(HE_UL_MUMIMO_ENABLE, HE_MODE_UL_MUMIMO); + + if (arvif->vif->bss_conf.he_su_beamformee) + value |= u32_encode_bits(HE_SU_BFEE_ENABLE, HE_MODE_SU_TX_BFEE); + } + + ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, param, value); + if (ret) { + ath12k_warn(ar->ab, "failed to set vdev %d HE MU mode: %d\n", + arvif->vdev_id, ret); + return ret; + } + + param = WMI_VDEV_PARAM_SET_HE_SOUNDING_MODE; + value = u32_encode_bits(HE_VHT_SOUNDING_MODE_ENABLE, HE_VHT_SOUNDING_MODE) | + u32_encode_bits(HE_TRIG_NONTRIG_SOUNDING_MODE_ENABLE, + HE_TRIG_NONTRIG_SOUNDING_MODE); + ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, + param, value); + if (ret) { + ath12k_warn(ar->ab, "failed to set vdev %d sounding mode: %d\n", + arvif->vdev_id, ret); + return ret; + } + + return 0; +} + +static int ath12k_mac_vif_recalc_sta_he_txbf(struct ath12k *ar, + struct ieee80211_vif *vif, + struct ieee80211_sta_he_cap *he_cap, + int *hemode) +{ + struct ieee80211_he_cap_elem he_cap_elem = {}; + struct ieee80211_sta_he_cap *cap_band; + struct cfg80211_chan_def def; + + if (!vif->bss_conf.he_support) + return 0; + + if (vif->type != NL80211_IFTYPE_STATION) + return -EINVAL; + + if (WARN_ON(ath12k_mac_vif_chan(vif, &def))) + return -EINVAL; + + if (def.chan->band == NL80211_BAND_2GHZ) + cap_band = &ar->mac.iftype[NL80211_BAND_2GHZ][vif->type].he_cap; + else + cap_band = &ar->mac.iftype[NL80211_BAND_5GHZ][vif->type].he_cap; + + memcpy(&he_cap_elem, &cap_band->he_cap_elem, sizeof(he_cap_elem)); + + *hemode = 0; + if (HECAP_PHY_SUBFME_GET(he_cap_elem.phy_cap_info)) { + if (HECAP_PHY_SUBFMR_GET(he_cap->he_cap_elem.phy_cap_info)) + *hemode |= u32_encode_bits(HE_SU_BFEE_ENABLE, HE_MODE_SU_TX_BFEE); + if (HECAP_PHY_MUBFMR_GET(he_cap->he_cap_elem.phy_cap_info)) + *hemode |= u32_encode_bits(HE_MU_BFEE_ENABLE, HE_MODE_MU_TX_BFEE); + } + + if (vif->type != NL80211_IFTYPE_MESH_POINT) { + *hemode |= u32_encode_bits(HE_DL_MUOFDMA_ENABLE, HE_MODE_DL_OFDMA) | + u32_encode_bits(HE_UL_MUOFDMA_ENABLE, HE_MODE_UL_OFDMA); + + if (HECAP_PHY_ULMUMIMO_GET(he_cap_elem.phy_cap_info)) + if (HECAP_PHY_ULMUMIMO_GET(he_cap->he_cap_elem.phy_cap_info)) + *hemode |= u32_encode_bits(HE_UL_MUMIMO_ENABLE, + HE_MODE_UL_MUMIMO); + + if (u32_get_bits(*hemode, HE_MODE_MU_TX_BFEE)) + *hemode |= u32_encode_bits(HE_SU_BFEE_ENABLE, HE_MODE_SU_TX_BFEE); + + if (u32_get_bits(*hemode, HE_MODE_MU_TX_BFER)) + *hemode |= u32_encode_bits(HE_SU_BFER_ENABLE, HE_MODE_SU_TX_BFER); + } + + return 0; +} + static void ath12k_bss_assoc(struct ath12k *ar, struct ath12k_vif *arvif, struct ieee80211_bss_conf *bss_conf) @@ -2855,9 +2957,11 @@ static void ath12k_bss_assoc(struct ath12k *ar, struct ieee80211_vif *vif = arvif->vif; struct ath12k_wmi_vdev_up_params params = {}; struct ath12k_wmi_peer_assoc_arg peer_arg; + struct ieee80211_sta_he_cap he_cap; struct ieee80211_sta *ap_sta; struct ath12k_peer *peer; bool is_auth = false; + u32 hemode = 0; int ret; lockdep_assert_held(&ar->conf_mutex); @@ -2877,8 +2981,29 @@ static void ath12k_bss_assoc(struct ath12k *ar, ath12k_peer_assoc_prepare(ar, vif, ap_sta, &peer_arg, false); + /* he_cap here is updated at assoc success for sta mode only */ + he_cap = ap_sta->deflink.he_cap; + + /* ap_sta->deflink.he_cap must be protected by rcu_read_lock */ + ret = ath12k_mac_vif_recalc_sta_he_txbf(ar, vif, &he_cap, &hemode); + if (ret) { + ath12k_warn(ar->ab, "failed to recalc he txbf for vdev %i on bss %pM: %d\n", + arvif->vdev_id, bss_conf->bssid, ret); + rcu_read_unlock(); + return; + } + rcu_read_unlock(); + /* keep this before ath12k_wmi_send_peer_assoc_cmd() */ + ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, + WMI_VDEV_PARAM_SET_HEMU_MODE, hemode); + if (ret) { + ath12k_warn(ar->ab, "failed to submit vdev param txbf 0x%x: %d\n", + hemode, ret); + return; + } + ret = ath12k_wmi_send_peer_assoc_cmd(ar, &peer_arg); if (ret) { ath12k_warn(ar->ab, "failed to run peer assoc for %pM vdev %i: %d\n", @@ -3212,6 +3337,13 @@ static void ath12k_mac_bss_info_changed(struct ath12k *ar, ether_addr_copy(arvif->bssid, info->bssid); if (changed & BSS_CHANGED_BEACON_ENABLED) { + if (info->enable_beacon) { + ret = ath12k_mac_set_he_txbf_conf(arvif); + if (ret) + ath12k_warn(ar->ab, + "failed to set HE TXBF config for vdev: %d\n", + arvif->vdev_id); + } ath12k_control_beaconing(arvif, info); if (arvif->is_up && vif->bss_conf.he_support && @@ -5335,11 +5467,14 @@ static void ath12k_mac_copy_he_cap(struct ath12k_band_cap *band_cap, he_cap_elem->mac_cap_info[1] &= IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_MASK; - + he_cap_elem->phy_cap_info[0] &= + IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G | + IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G | + IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G; + he_cap_elem->phy_cap_info[0] &= + ~IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G; he_cap_elem->phy_cap_info[5] &= ~IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_MASK; - he_cap_elem->phy_cap_info[5] &= - ~IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_MASK; he_cap_elem->phy_cap_info[5] |= num_tx_chains - 1; switch (iftype) { @@ -6298,71 +6433,6 @@ static int ath12k_mac_setup_vdev_create_arg(struct ath12k_vif *arvif, return 0; } -static u32 -ath12k_mac_prepare_he_mode(struct ath12k_pdev *pdev, u32 viftype) -{ - struct ath12k_pdev_cap *pdev_cap = &pdev->cap; - struct ath12k_band_cap *cap_band = NULL; - u32 *hecap_phy_ptr = NULL; - u32 hemode; - - if (pdev->cap.supported_bands & WMI_HOST_WLAN_2G_CAP) - cap_band = &pdev_cap->band[NL80211_BAND_2GHZ]; - else - cap_band = &pdev_cap->band[NL80211_BAND_5GHZ]; - - hecap_phy_ptr = &cap_band->he_cap_phy_info[0]; - - hemode = u32_encode_bits(HE_SU_BFEE_ENABLE, HE_MODE_SU_TX_BFEE) | - u32_encode_bits(HECAP_PHY_SUBFMR_GET(hecap_phy_ptr), - HE_MODE_SU_TX_BFER) | - u32_encode_bits(HECAP_PHY_ULMUMIMO_GET(hecap_phy_ptr), - HE_MODE_UL_MUMIMO); - - /* TODO: WDS and other modes */ - if (viftype == NL80211_IFTYPE_AP) { - hemode |= u32_encode_bits(HECAP_PHY_MUBFMR_GET(hecap_phy_ptr), - HE_MODE_MU_TX_BFER) | - u32_encode_bits(HE_DL_MUOFDMA_ENABLE, HE_MODE_DL_OFDMA) | - u32_encode_bits(HE_UL_MUOFDMA_ENABLE, HE_MODE_UL_OFDMA); - } else { - hemode |= u32_encode_bits(HE_MU_BFEE_ENABLE, HE_MODE_MU_TX_BFEE); - } - - return hemode; -} - -static int ath12k_set_he_mu_sounding_mode(struct ath12k *ar, - struct ath12k_vif *arvif) -{ - u32 param_id, param_value; - struct ath12k_base *ab = ar->ab; - int ret; - - param_id = WMI_VDEV_PARAM_SET_HEMU_MODE; - param_value = ath12k_mac_prepare_he_mode(ar->pdev, arvif->vif->type); - ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, - param_id, param_value); - if (ret) { - ath12k_warn(ab, "failed to set vdev %d HE MU mode: %d param_value %x\n", - arvif->vdev_id, ret, param_value); - return ret; - } - param_id = WMI_VDEV_PARAM_SET_HE_SOUNDING_MODE; - param_value = - u32_encode_bits(HE_VHT_SOUNDING_MODE_ENABLE, HE_VHT_SOUNDING_MODE) | - u32_encode_bits(HE_TRIG_NONTRIG_SOUNDING_MODE_ENABLE, - HE_TRIG_NONTRIG_SOUNDING_MODE); - ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, - param_id, param_value); - if (ret) { - ath12k_warn(ab, "failed to set vdev %d HE MU mode: %d\n", - arvif->vdev_id, ret); - return ret; - } - return ret; -} - static void ath12k_mac_update_vif_offload(struct ath12k_vif *arvif) { struct ieee80211_vif *vif = arvif->vif; @@ -7196,7 +7266,6 @@ ath12k_mac_vdev_start_restart(struct ath12k_vif *arvif, struct ath12k_base *ab = ar->ab; struct wmi_vdev_start_req_arg arg = {}; const struct cfg80211_chan_def *chandef = &ctx->def; - int he_support = arvif->vif->bss_conf.he_support; int ret; lockdep_assert_held(&ar->conf_mutex); @@ -7252,14 +7321,6 @@ ath12k_mac_vdev_start_restart(struct ath12k_vif *arvif, spin_unlock_bh(&ab->base_lock); /* TODO: Notify if secondary 80Mhz also needs radar detection */ - if (he_support) { - ret = ath12k_set_he_mu_sounding_mode(ar, arvif); - if (ret) { - ath12k_warn(ar->ab, "failed to set he mode vdev %i\n", - arg.vdev_id); - return ret; - } - } } arg.passive |= !!(chandef->chan->flags & IEEE80211_CHAN_NO_IR); diff --git a/drivers/net/wireless/ath/ath12k/mac.h b/drivers/net/wireless/ath/ath12k/mac.h index 5efbb6822628..8d541f1c2d80 100644 --- a/drivers/net/wireless/ath/ath12k/mac.h +++ b/drivers/net/wireless/ath/ath12k/mac.h @@ -41,6 +41,21 @@ struct ath12k_generic_iter { #define ATH12K_TX_POWER_MAX_VAL 70 #define ATH12K_TX_POWER_MIN_VAL 0 +#define HECAP_PHY_SUBFMR_GET(hecap_phy) \ + u8_get_bits(hecap_phy[3], IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER) + +#define HECAP_PHY_SUBFME_GET(hecap_phy) \ + u8_get_bits(hecap_phy[4], IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE) + +#define HECAP_PHY_MUBFMR_GET(hecap_phy) \ + u8_get_bits(hecap_phy[4], IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER) + +#define HECAP_PHY_ULMUMIMO_GET(hecap_phy) \ + u8_get_bits(hecap_phy[2], IEEE80211_HE_PHY_CAP2_UL_MU_FULL_MU_MIMO) + +#define HECAP_PHY_ULOFDMA_GET(hecap_phy) \ + u8_get_bits(hecap_phy[2], IEEE80211_HE_PHY_CAP2_UL_MU_PARTIAL_MU_MIMO) + enum ath12k_supported_bw { ATH12K_BW_20 = 0, ATH12K_BW_40 = 1, diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h index 6a913f9b8315..3a0fd1c5015d 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.h +++ b/drivers/net/wireless/ath/ath12k/wmi.h @@ -2995,31 +2995,6 @@ struct ath12k_wmi_rx_reorder_queue_remove_arg { #define WMI_VDEV_PARAM_TXBF_SU_TX_BFER BIT(2) #define WMI_VDEV_PARAM_TXBF_MU_TX_BFER BIT(3) -#define HECAP_PHYDWORD_0 0 -#define HECAP_PHYDWORD_1 1 -#define HECAP_PHYDWORD_2 2 - -#define HECAP_PHY_SU_BFER BIT(31) -#define HECAP_PHY_SU_BFEE BIT(0) -#define HECAP_PHY_MU_BFER BIT(1) -#define HECAP_PHY_UL_MUMIMO BIT(22) -#define HECAP_PHY_UL_MUOFDMA BIT(23) - -#define HECAP_PHY_SUBFMR_GET(hecap_phy) \ - u32_get_bits(hecap_phy[HECAP_PHYDWORD_0], HECAP_PHY_SU_BFER) - -#define HECAP_PHY_SUBFME_GET(hecap_phy) \ - u32_get_bits(hecap_phy[HECAP_PHYDWORD_1], HECAP_PHY_SU_BFEE) - -#define HECAP_PHY_MUBFMR_GET(hecap_phy) \ - u32_get_bits(hecap_phy[HECAP_PHYDWORD_1], HECAP_PHY_MU_BFER) - -#define HECAP_PHY_ULMUMIMO_GET(hecap_phy) \ - u32_get_bits(hecap_phy[HECAP_PHYDWORD_0], HECAP_PHY_UL_MUMIMO) - -#define HECAP_PHY_ULOFDMA_GET(hecap_phy) \ - u32_get_bits(hecap_phy[HECAP_PHYDWORD_0], HECAP_PHY_UL_MUOFDMA) - #define HE_MODE_SU_TX_BFEE BIT(0) #define HE_MODE_SU_TX_BFER BIT(1) #define HE_MODE_MU_TX_BFEE BIT(2) @@ -3031,8 +3006,11 @@ struct ath12k_wmi_rx_reorder_queue_remove_arg { #define HE_DL_MUOFDMA_ENABLE 1 #define HE_UL_MUOFDMA_ENABLE 1 #define HE_DL_MUMIMO_ENABLE 1 +#define HE_UL_MUMIMO_ENABLE 1 #define HE_MU_BFEE_ENABLE 1 #define HE_SU_BFEE_ENABLE 1 +#define HE_MU_BFER_ENABLE 1 +#define HE_SU_BFER_ENABLE 1 #define HE_VHT_SOUNDING_MODE_ENABLE 1 #define HE_SU_MU_SOUNDING_MODE_ENABLE 1 From patchwork Wed Sep 18 21:20:49 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pradeep Kumar Chitrapu X-Patchwork-Id: 829542 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B81C317967F for ; Wed, 18 Sep 2024 21:21:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726694474; cv=none; b=SYN3tI9xaTiXuxK7CUAD6gXBOqoyS1qZxAGNOXDt4yS1Q6oU0YiwQonIkVrnux7/DC3bCm2JScN5vIxVzkGOkFztaIHlZMM/TRsp6GzSIbZdasVpxySumoe965kRna+5fYAmf4i3wJupfj9p6509u7j6kXzz1ZxlSStR4wLObcE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726694474; c=relaxed/simple; bh=yQPaApb7knqLxhkxSrizMfAanw18TDUbxBPbfnhzlV0=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=W+Rk8/tiKUvP6A8WYQFxi97//4Yj4m/rYPXAg0YP+6K+GXDcFK2VD+yEzmymA/fsenli+7ZEJ1zH6XgzLe4+1QFctCYGnq1LPoD01a4AIF8VqJGVdgs6e1ZwCKv8AOLkZUb09QkmM8Ur4R1xFhc4oVqhlvm3NMc24NERWmxzGjI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=XJxqlj7h; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="XJxqlj7h" Received: from pps.filterd (m0279867.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 48IHKWuA006417; Wed, 18 Sep 2024 21:21:08 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= hcoreX5pgczyblwh1gpL6Ax4OV0yrVpAaKX7psGXczI=; b=XJxqlj7hhoW4GYMB +B9r7ajbqV+ZxP+/1uDt5veOBY8aQgsorBoEbZFKm+ccV0u5SQJ/fFSomLg8QYpE iojXUyYsGJMsXSPW+OdC0DQ2JrhDEHWFQa/6c3C0sdBE5IGgTa8YiAmYAx/A1ti1 ruMNSyT8H/xEKkR953axz1DOGJZfp9dCtOM5Xw6nrqpeUEYBShgvQ+1LLXqrH8U4 qUlYW2vKFKJgZUe97nwRrwOiunhTD4M2ARe6xHqZ7bL+2bW27sRTSI69vGrcEdKM Ied7A8KmlUAN5BBsOj5MeKAaoy0+h4iY/9W3JgDfOu+LwjuAaKzgPNrttmPehdhJ Q8q0JQ== Received: from nalasppmta01.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 41n4kjk65k-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 18 Sep 2024 21:21:07 +0000 (GMT) Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com [10.47.209.196]) by NALASPPMTA01.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id 48ILL7IZ032342 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 18 Sep 2024 21:21:07 GMT Received: from ath12k-linux1.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.1544.9; Wed, 18 Sep 2024 14:21:06 -0700 From: Pradeep Kumar Chitrapu To: CC: , Pradeep Kumar Chitrapu , Muna Sinada , "Jeff Johnson" Subject: [PATCH V8 2/9] wifi: ath12k: push EHT MU-MIMO params to hardware Date: Wed, 18 Sep 2024 14:20:49 -0700 Message-ID: <20240918212056.4137076-3-quic_pradeepc@quicinc.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240918212056.4137076-1-quic_pradeepc@quicinc.com> References: <20240918212056.4137076-1-quic_pradeepc@quicinc.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01a.na.qualcomm.com (10.47.209.196) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: DiIEaDHD4453WG2b31qitb3_i0JkAM4u X-Proofpoint-ORIG-GUID: DiIEaDHD4453WG2b31qitb3_i0JkAM4u X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.60.29 definitions=2024-09-06_09,2024-09-06_01,2024-09-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 bulkscore=0 adultscore=0 suspectscore=0 mlxscore=0 clxscore=1015 lowpriorityscore=0 malwarescore=0 phishscore=0 impostorscore=0 mlxlogscore=999 priorityscore=1501 spamscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2408220000 definitions=main-2409180140 Currently, only the EHT IE in management frames is updated with respect to MU-MIMO configurations, but this change is not reflected in the hardware. Add support to propagate MU-MIMO configurations to the hardware as well for AP mode. Similar support for STA mode will be added in future. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1 Co-developed-by: Muna Sinada Signed-off-by: Muna Sinada Signed-off-by: Pradeep Kumar Chitrapu Acked-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/mac.c | 50 +++++++++++++++++++++++++++ drivers/net/wireless/ath/ath12k/wmi.h | 21 +++++++++++ 2 files changed, 71 insertions(+) diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 8ab15de8243e..ee672060ba92 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -2950,6 +2950,50 @@ static int ath12k_mac_vif_recalc_sta_he_txbf(struct ath12k *ar, return 0; } +static int ath12k_mac_set_eht_txbf_conf(struct ath12k_vif *arvif) +{ + u32 param = WMI_VDEV_PARAM_SET_EHT_MU_MODE; + struct ath12k *ar = arvif->ar; + u32 value = 0; + int ret; + + if (!arvif->vif->bss_conf.eht_support) + return 0; + + if (arvif->vif->bss_conf.eht_su_beamformer) { + value |= u32_encode_bits(EHT_SU_BFER_ENABLE, EHT_MODE_SU_TX_BFER); + if (arvif->vif->bss_conf.eht_mu_beamformer && + arvif->vdev_type == WMI_VDEV_TYPE_AP) + value |= u32_encode_bits(EHT_MU_BFER_ENABLE, + EHT_MODE_MU_TX_BFER) | + u32_encode_bits(EHT_DL_MUOFDMA_ENABLE, + EHT_MODE_DL_OFDMA_MUMIMO) | + u32_encode_bits(EHT_UL_MUOFDMA_ENABLE, + EHT_MODE_UL_OFDMA_MUMIMO); + } + + if (arvif->vif->type != NL80211_IFTYPE_MESH_POINT) { + value |= u32_encode_bits(EHT_DL_MUOFDMA_ENABLE, EHT_MODE_DL_OFDMA) | + u32_encode_bits(EHT_UL_MUOFDMA_ENABLE, EHT_MODE_UL_OFDMA); + + if (arvif->vif->bss_conf.eht_80mhz_full_bw_ul_mumimo) + value |= u32_encode_bits(EHT_UL_MUMIMO_ENABLE, EHT_MODE_MUMIMO); + + if (arvif->vif->bss_conf.eht_su_beamformee) + value |= u32_encode_bits(EHT_SU_BFEE_ENABLE, + EHT_MODE_SU_TX_BFEE); + } + + ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, param, value); + if (ret) { + ath12k_warn(ar->ab, "failed to set vdev %d EHT MU mode: %d\n", + arvif->vdev_id, ret); + return ret; + } + + return 0; +} + static void ath12k_bss_assoc(struct ath12k *ar, struct ath12k_vif *arvif, struct ieee80211_bss_conf *bss_conf) @@ -3343,6 +3387,12 @@ static void ath12k_mac_bss_info_changed(struct ath12k *ar, ath12k_warn(ar->ab, "failed to set HE TXBF config for vdev: %d\n", arvif->vdev_id); + + ret = ath12k_mac_set_eht_txbf_conf(arvif); + if (ret) + ath12k_warn(ar->ab, + "failed to set EHT TXBF config for vdev: %d\n", + arvif->vdev_id); } ath12k_control_beaconing(arvif, info); diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h index 3a0fd1c5015d..b4cf0e849387 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.h +++ b/drivers/net/wireless/ath/ath12k/wmi.h @@ -1139,6 +1139,7 @@ enum wmi_tlv_vdev_param { WMI_VDEV_PARAM_BSS_COLOR, WMI_VDEV_PARAM_SET_HEMU_MODE, WMI_VDEV_PARAM_HEOPS_0_31 = 0x8003, + WMI_VDEV_PARAM_SET_EHT_MU_MODE = 0x8005, }; enum wmi_tlv_peer_flags { @@ -3012,6 +3013,26 @@ struct ath12k_wmi_rx_reorder_queue_remove_arg { #define HE_MU_BFER_ENABLE 1 #define HE_SU_BFER_ENABLE 1 +#define EHT_MODE_SU_TX_BFEE BIT(0) +#define EHT_MODE_SU_TX_BFER BIT(1) +#define EHT_MODE_MU_TX_BFEE BIT(2) +#define EHT_MODE_MU_TX_BFER BIT(3) +#define EHT_MODE_DL_OFDMA BIT(4) +#define EHT_MODE_UL_OFDMA BIT(5) +#define EHT_MODE_MUMIMO BIT(6) +#define EHT_MODE_DL_OFDMA_TXBF BIT(7) +#define EHT_MODE_DL_OFDMA_MUMIMO BIT(8) +#define EHT_MODE_UL_OFDMA_MUMIMO BIT(9) + +#define EHT_DL_MUOFDMA_ENABLE 1 +#define EHT_UL_MUOFDMA_ENABLE 1 +#define EHT_DL_MUMIMO_ENABLE 1 +#define EHT_UL_MUMIMO_ENABLE 1 +#define EHT_MU_BFEE_ENABLE 1 +#define EHT_SU_BFEE_ENABLE 1 +#define EHT_MU_BFER_ENABLE 1 +#define EHT_SU_BFER_ENABLE 1 + #define HE_VHT_SOUNDING_MODE_ENABLE 1 #define HE_SU_MU_SOUNDING_MODE_ENABLE 1 #define HE_TRIG_NONTRIG_SOUNDING_MODE_ENABLE 1 From patchwork Wed Sep 18 21:20:50 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pradeep Kumar Chitrapu X-Patchwork-Id: 829829 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4B2B11CB312 for ; Wed, 18 Sep 2024 21:21:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726694475; cv=none; b=uo8JC/iAnxSCZyXzNFarViwWJNwY+JldG9aDgn6LOK7yCxMusODCN3rw4mSCs0sLxHrfxFouDKWpiKeM7hGb/fzQzU2eh6bHNvzhjOqaTjAsJo7sVGj4L2QK1UPb2ZxMke35L51ztNTVhAc7IS17sn6blDZnU+1+RGRKXskHc78= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726694475; c=relaxed/simple; bh=nhEu2OadboIpWVwShgMmYabjiVuEo2mUKJhJlcUzvgI=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=iPc43CIgA4O9RfgxO3cfBBvDShW3nh4Q/MVoL1JTtx8u/9t1CeFY7KstjtKiPdJ6vxx0yhZwXcwCRFfbZdfRduyybDRKPmgqN/VogzkwizBSFWBL41H02pCvee2mV3poTyZz9CnCJ5L7An5k7ARI3Eo6EwsgaAYIncO/tU2Jsao= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=iXyzdRBT; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="iXyzdRBT" Received: from pps.filterd (m0279869.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 48I90GrT001584; Wed, 18 Sep 2024 21:21:09 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= aj0umwCwR0cGrc/Vc7qz7QRYcnU4amMo6KwLL9RZRaA=; b=iXyzdRBTMie5qv2n KocnG3cRtZjxDUMbNTj+in3o4zrIU5RFumLb3ZmgpbCZD9jcmxkc9fcTdtwxUz8e LTodO1mKSkqtOufy45keXIYYJN3lxfFsZtA5bcmG+QCJZJmPaTpMaf9L9Us9e+JZ Ngjh4JNR3UIXn5+UvNGrRNEWeAlCrwf9Z5bWl1mQmwmkVVuH3nMu1IyPidF3tzRk AdQTPkPtpnoGlYwEWL/noPAYTf4OuZrqPCAj31iBfZvq2RjAdWtPx/ayYEQsNKCu xoBLKjb8hppxfGqn06TpV73nTxvhEDwnwBTwfgrr+xVeKvwz6Mrh8aoYBdUeFUAh OiuxDA== Received: from nalasppmta03.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 41n4hf38cn-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 18 Sep 2024 21:21:08 +0000 (GMT) Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com [10.47.209.196]) by NALASPPMTA03.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id 48ILL7e8005093 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 18 Sep 2024 21:21:07 GMT Received: from ath12k-linux1.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.1544.9; Wed, 18 Sep 2024 14:21:07 -0700 From: Pradeep Kumar Chitrapu To: CC: , Pradeep Kumar Chitrapu , Muna Sinada , "Jeff Johnson" Subject: [PATCH V8 3/9] wifi: ath12k: move HE MCS mapper to a separate function Date: Wed, 18 Sep 2024 14:20:50 -0700 Message-ID: <20240918212056.4137076-4-quic_pradeepc@quicinc.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240918212056.4137076-1-quic_pradeepc@quicinc.com> References: <20240918212056.4137076-1-quic_pradeepc@quicinc.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01a.na.qualcomm.com (10.47.209.196) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-ORIG-GUID: zHmCiFNBcWNOH7v_I9cuj0l6gmfKvBVa X-Proofpoint-GUID: zHmCiFNBcWNOH7v_I9cuj0l6gmfKvBVa X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.60.29 definitions=2024-09-06_09,2024-09-06_01,2024-09-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 mlxscore=0 suspectscore=0 bulkscore=0 lowpriorityscore=0 spamscore=0 clxscore=1015 mlxlogscore=999 adultscore=0 malwarescore=0 phishscore=0 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2408220000 definitions=main-2409180140 Refactor the HE MCS mapper functionality in ath12k_mac_copy_he_cap() into a new function. This helps improve readability, extensibility and will be used when adding support for 160 MHz bandwidth in subsequent patches. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1 Co-developed-by: Muna Sinada Signed-off-by: Muna Sinada Signed-off-by: Pradeep Kumar Chitrapu Acked-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/mac.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index ee672060ba92..daf00f5bc966 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -5502,12 +5502,24 @@ static __le16 ath12k_mac_setup_he_6ghz_cap(struct ath12k_pdev_cap *pcap, return cpu_to_le16(bcap->he_6ghz_capa); } +static void ath12k_mac_set_hemcsmap(struct ath12k_band_cap *band_cap, + struct ieee80211_sta_he_cap *he_cap) +{ + struct ieee80211_he_mcs_nss_supp *mcs_nss = &he_cap->he_mcs_nss_supp; + + mcs_nss->rx_mcs_80 = cpu_to_le16(band_cap->he_mcs & 0xffff); + mcs_nss->tx_mcs_80 = cpu_to_le16(band_cap->he_mcs & 0xffff); + mcs_nss->rx_mcs_160 = cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff); + mcs_nss->tx_mcs_160 = cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff); + mcs_nss->rx_mcs_80p80 = cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff); + mcs_nss->tx_mcs_80p80 = cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff); +} + static void ath12k_mac_copy_he_cap(struct ath12k_band_cap *band_cap, int iftype, u8 num_tx_chains, struct ieee80211_sta_he_cap *he_cap) { struct ieee80211_he_cap_elem *he_cap_elem = &he_cap->he_cap_elem; - struct ieee80211_he_mcs_nss_supp *mcs_nss = &he_cap->he_mcs_nss_supp; he_cap->has_he = true; memcpy(he_cap_elem->mac_cap_info, band_cap->he_cap_info, @@ -5545,13 +5557,7 @@ static void ath12k_mac_copy_he_cap(struct ath12k_band_cap *band_cap, break; } - mcs_nss->rx_mcs_80 = cpu_to_le16(band_cap->he_mcs & 0xffff); - mcs_nss->tx_mcs_80 = cpu_to_le16(band_cap->he_mcs & 0xffff); - mcs_nss->rx_mcs_160 = cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff); - mcs_nss->tx_mcs_160 = cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff); - mcs_nss->rx_mcs_80p80 = cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff); - mcs_nss->tx_mcs_80p80 = cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff); - + ath12k_mac_set_hemcsmap(band_cap, he_cap); memset(he_cap->ppe_thres, 0, sizeof(he_cap->ppe_thres)); if (he_cap_elem->phy_cap_info[6] & IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT) From patchwork Wed Sep 18 21:20:51 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pradeep Kumar Chitrapu X-Patchwork-Id: 829828 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A88651CB32C for ; Wed, 18 Sep 2024 21:21:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726694476; cv=none; b=Lkqx2oSLyeGRxKcm+N4Vmg+KOuwHpt6xhgWj9SpyWNXxxWkVExVyHvPrWaP/u4OXd0YjYBJC3Dg0NJYY9WJyL0A3RP8GK++s9CiRloNaEmEjI71S/f3+0HVXu5bCmi8cyiIMFzCpAcNuZ67J7r/WxvNRbeox3iZHmXK1WFUb4Hs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726694476; c=relaxed/simple; bh=nv4kc89H7eGC0FLgCwC70zFDhNkClMNiRf5HjDZHHuQ=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=B1oJWv7vHZKRChjamOFJnRzQVtL7qBs7/Ho9GojLQtHyCKtrCEOJt/lWvhkqISf48/5MaQOCdkHhCrQT/eHP9hZ1wnCdeOKXh6Wmk/QYt9yEcc0X6HT5wUxgpaA3PooH/cMlJCX0c8hyhT7XBm6vWnPwQjt/FnLTubA3uj+X8oE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=WweZPnje; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="WweZPnje" Received: from pps.filterd (m0279872.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 48IACJst031540; Wed, 18 Sep 2024 21:21:09 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= ARu9Fu0s66NeuLm2pdCBchANS+rlgd275Q/E4KE2T1o=; b=WweZPnjehL/ZQW57 4JHJDsl8A5hyljMaJrVPdmZwNktTurJPMpD5z0akqx2dq3bfjzx2rx5NAtMb831x ieysvT1ApK5V32fmb9xzG7FMIU3DH4eqr/9ApZbHFVPTglHrVoVzHJLps3I+Ts5P gi1dsIAdwTai7hW1FchcW/pZ2kJMq6zN7oljoFs7pc1CvzHfIJowQM8gFfslkqlL lvm9A9knvnUlkrEvzgpoZfZxm/91t9bQzkQDTX91wRc0oGR/9liT+z4Sdum2rLwb fri8rhQIw8w1ExGM1nzChPaajmDIsE86ODjDL2xBbd/DcdsVvOYl8ewJ8AX45qNs +LpHtg== Received: from nalasppmta03.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 41n4j6uagq-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 18 Sep 2024 21:21:09 +0000 (GMT) Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com [10.47.209.196]) by NALASPPMTA03.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id 48ILL8gM005103 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 18 Sep 2024 21:21:08 GMT Received: from ath12k-linux1.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.1544.9; Wed, 18 Sep 2024 14:21:07 -0700 From: Pradeep Kumar Chitrapu To: CC: , Pradeep Kumar Chitrapu , Muna Sinada , "Jeff Johnson" Subject: [PATCH V8 4/9] wifi: ath12k: generate rx and tx mcs maps for supported HE mcs Date: Wed, 18 Sep 2024 14:20:51 -0700 Message-ID: <20240918212056.4137076-5-quic_pradeepc@quicinc.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240918212056.4137076-1-quic_pradeepc@quicinc.com> References: <20240918212056.4137076-1-quic_pradeepc@quicinc.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01a.na.qualcomm.com (10.47.209.196) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-ORIG-GUID: wHJ63GZpWGKZ4XSyQZiVlsARNAgr5CQM X-Proofpoint-GUID: wHJ63GZpWGKZ4XSyQZiVlsARNAgr5CQM X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.60.29 definitions=2024-09-06_09,2024-09-06_01,2024-09-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 mlxlogscore=999 mlxscore=0 malwarescore=0 bulkscore=0 priorityscore=1501 clxscore=1015 adultscore=0 suspectscore=0 lowpriorityscore=0 spamscore=0 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2408220000 definitions=main-2409180140 Generate rx and tx mcs maps in ath12k_mac_set_hemcsmap() based on number of supported tx/rx chains and set them in supported mcs/nss for HE capabilities. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1 Co-developed-by: Muna Sinada Signed-off-by: Muna Sinada Signed-off-by: Pradeep Kumar Chitrapu Acked-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/mac.c | 40 ++++++++++++++++++++------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index daf00f5bc966..34a9bbdbcf48 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -5502,20 +5502,40 @@ static __le16 ath12k_mac_setup_he_6ghz_cap(struct ath12k_pdev_cap *pcap, return cpu_to_le16(bcap->he_6ghz_capa); } -static void ath12k_mac_set_hemcsmap(struct ath12k_band_cap *band_cap, +static void ath12k_mac_set_hemcsmap(struct ath12k *ar, + struct ath12k_pdev_cap *cap, struct ieee80211_sta_he_cap *he_cap) { struct ieee80211_he_mcs_nss_supp *mcs_nss = &he_cap->he_mcs_nss_supp; + u16 txmcs_map, rxmcs_map; + u32 i; + + rxmcs_map = 0; + txmcs_map = 0; + for (i = 0; i < 8; i++) { + if (i < ar->num_tx_chains && + (ar->cfg_tx_chainmask >> cap->tx_chain_mask_shift) & BIT(i)) + txmcs_map |= IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2); + else + txmcs_map |= IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2); + + if (i < ar->num_rx_chains && + (ar->cfg_rx_chainmask >> cap->tx_chain_mask_shift) & BIT(i)) + rxmcs_map |= IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2); + else + rxmcs_map |= IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2); + } - mcs_nss->rx_mcs_80 = cpu_to_le16(band_cap->he_mcs & 0xffff); - mcs_nss->tx_mcs_80 = cpu_to_le16(band_cap->he_mcs & 0xffff); - mcs_nss->rx_mcs_160 = cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff); - mcs_nss->tx_mcs_160 = cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff); - mcs_nss->rx_mcs_80p80 = cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff); - mcs_nss->tx_mcs_80p80 = cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff); + mcs_nss->rx_mcs_80 = cpu_to_le16(rxmcs_map & 0xffff); + mcs_nss->tx_mcs_80 = cpu_to_le16(txmcs_map & 0xffff); + mcs_nss->rx_mcs_160 = cpu_to_le16(rxmcs_map & 0xffff); + mcs_nss->tx_mcs_160 = cpu_to_le16(txmcs_map & 0xffff); + mcs_nss->rx_mcs_80p80 = cpu_to_le16(rxmcs_map & 0xffff); + mcs_nss->tx_mcs_80p80 = cpu_to_le16(txmcs_map & 0xffff); } -static void ath12k_mac_copy_he_cap(struct ath12k_band_cap *band_cap, +static void ath12k_mac_copy_he_cap(struct ath12k *ar, + struct ath12k_band_cap *band_cap, int iftype, u8 num_tx_chains, struct ieee80211_sta_he_cap *he_cap) { @@ -5557,7 +5577,7 @@ static void ath12k_mac_copy_he_cap(struct ath12k_band_cap *band_cap, break; } - ath12k_mac_set_hemcsmap(band_cap, he_cap); + ath12k_mac_set_hemcsmap(ar, &ar->pdev->cap, he_cap); memset(he_cap->ppe_thres, 0, sizeof(he_cap->ppe_thres)); if (he_cap_elem->phy_cap_info[6] & IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT) @@ -5746,7 +5766,7 @@ static int ath12k_mac_copy_sband_iftype_data(struct ath12k *ar, data[idx].types_mask = BIT(i); - ath12k_mac_copy_he_cap(band_cap, i, ar->num_tx_chains, he_cap); + ath12k_mac_copy_he_cap(ar, band_cap, i, ar->num_tx_chains, he_cap); if (band == NL80211_BAND_6GHZ) { data[idx].he_6ghz_capa.capa = ath12k_mac_setup_he_6ghz_cap(cap, band_cap); From patchwork Wed Sep 18 21:20:52 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pradeep Kumar Chitrapu X-Patchwork-Id: 829830 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 77FB41CA6AC for ; Wed, 18 Sep 2024 21:21:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726694475; cv=none; b=RN/ddoo5Vh8RVGeYZ8k8lXTOb7bzs7wSIAQGFjyvpfc9NICOpTDXpM3ai/D/fFtXLR8mFmYa4uIMFdrWML1x/UjZtd+jJnNyL/jo4/t5+ONN0nU4brd/dW7fv/biqLA6CkFbjnw01XnInXLzGT8IIm4NvxBkMy/RVj0tC33y7os= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726694475; c=relaxed/simple; bh=bsvgv033jSAPUVmS0VlMcScTn/1aM6tw3aACOOiqxvA=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=rDT2TKhzEg9vR1RSVstUP/e9Z+sWhPbag7vxjm3nmkSJBFS5bR72jSO3YnpEGSQLOgd0c+ou8ce0GQOHHZBEpr8VlMP4o6SK8T3BVg4yPiHhqLzwadektVXzAofZ0K+caSvYUjsPvDd2wH1xDyUPHgvr/DjsPh8bhO1MP80pTYk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=DbZeRJ9u; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="DbZeRJ9u" Received: from pps.filterd (m0279867.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 48I9TNqc020283; Wed, 18 Sep 2024 21:21:09 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= azR+5F3oXqRD0oIXJq+q0F3HbuiVUYwPuvX5vVskhnw=; b=DbZeRJ9uo40mL5rR p0cASEsdLU8yr/aYeIXTSWCHBf5P73m5S26EYVv6MqTdcnmRT7flYyQWzotNV+gg oHJpR7L5sN+omhK+7gDPRcm5j29/U9+7rMG7I0JwrfR6KbUUNJkrg+omW45ZdRPS /92XJynSBDgzEGETs0AjLe+PLPW4Ucnncc+YscEVm/dtR4f5vQBYwGdCwv4IuczO FJrEmDh3mj7m6JtNVV+A3LT5qS7PCAbiS7qhTAkDfhH9gDZJuUTO2b6ByyO4UkWp afB41wIc4KUDYsTHkThkApxxp0vHfJJLGCweUi+YKYaqvQETgLhHx/UkSRdoRBII N708pg== Received: from nalasppmta05.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 41n4kjk65m-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 18 Sep 2024 21:21:09 +0000 (GMT) Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com [10.47.209.196]) by NALASPPMTA05.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id 48ILL8Gi009579 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 18 Sep 2024 21:21:08 GMT Received: from ath12k-linux1.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.1544.9; Wed, 18 Sep 2024 14:21:08 -0700 From: Pradeep Kumar Chitrapu To: CC: , Pradeep Kumar Chitrapu , Jeff Johnson Subject: [PATCH V8 5/9] wifi: ath12k: fix TX and RX MCS rate configurations in HE mode Date: Wed, 18 Sep 2024 14:20:52 -0700 Message-ID: <20240918212056.4137076-6-quic_pradeepc@quicinc.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240918212056.4137076-1-quic_pradeepc@quicinc.com> References: <20240918212056.4137076-1-quic_pradeepc@quicinc.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01a.na.qualcomm.com (10.47.209.196) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: JNJY4yItbZ8HP8WQjm82lNqNLkxUdf1v X-Proofpoint-ORIG-GUID: JNJY4yItbZ8HP8WQjm82lNqNLkxUdf1v X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.60.29 definitions=2024-09-06_09,2024-09-06_01,2024-09-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 bulkscore=0 adultscore=0 suspectscore=0 mlxscore=0 clxscore=1015 lowpriorityscore=0 malwarescore=0 phishscore=0 impostorscore=0 mlxlogscore=999 priorityscore=1501 spamscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2408220000 definitions=main-2409180140 Currently, the TX and RX MCS rate configurations per peer are reversed when sent to the firmware. As a result, RX MCS rates are configured for TX, and vice versa. This commit rectifies the configuration to match what the firmware expects. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1 Fixes: d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices") Signed-off-by: Pradeep Kumar Chitrapu Acked-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/wmi.c | 4 ++-- drivers/net/wireless/ath/ath12k/wmi.h | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c index 2cd3ff9b0164..7aabee813de6 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.c +++ b/drivers/net/wireless/ath/ath12k/wmi.c @@ -2138,8 +2138,8 @@ int ath12k_wmi_send_peer_assoc_cmd(struct ath12k *ar, he_mcs->tlv_header = ath12k_wmi_tlv_cmd_hdr(WMI_TAG_HE_RATE_SET, sizeof(*he_mcs)); - he_mcs->rx_mcs_set = cpu_to_le32(arg->peer_he_rx_mcs_set[i]); - he_mcs->tx_mcs_set = cpu_to_le32(arg->peer_he_tx_mcs_set[i]); + he_mcs->rx_mcs_set = cpu_to_le32(arg->peer_he_tx_mcs_set[i]); + he_mcs->tx_mcs_set = cpu_to_le32(arg->peer_he_rx_mcs_set[i]); ptr += sizeof(*he_mcs); } diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h index b4cf0e849387..0e472df28717 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.h +++ b/drivers/net/wireless/ath/ath12k/wmi.h @@ -3929,7 +3929,9 @@ struct ath12k_wmi_vht_rate_set_params { struct ath12k_wmi_he_rate_set_params { __le32 tlv_header; + /* MCS at which the peer can receive */ __le32 rx_mcs_set; + /* MCS at which the peer can transmit */ __le32 tx_mcs_set; } __packed; From patchwork Wed Sep 18 21:20:53 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pradeep Kumar Chitrapu X-Patchwork-Id: 829827 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 01CB41CB521 for ; Wed, 18 Sep 2024 21:21:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726694478; cv=none; b=CCnmzPX7wAnXz6jkBGnfJkO3OTVTa1pEVXaY+i3jcRKLwLmYLBkbQB7d5qZASnEWRw4vJRXQbpKaSNlechv1fw+VqQci5hz7GrwDmSDWwFwNKynwUkaS+V6CUoPkxGmvijlkSH5/Sp7n4JBdH9MZdY9ACaPCGZlgpTeAiRpgqyQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726694478; c=relaxed/simple; bh=mOCMplbDFdsxafoM0lh9GOTg8poXfVWSA2JaaPzd5gg=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=m9Y3ZEQjhVcT6ObjX34KItzxLUdCbzQDCo4za4qtMsxHQCEQSny2a/lTtWTbAB42n+JZkBRjC1xrrdmRnXSxy58EZpvKNutjY0YonbJ/hMfa97U5qRTD/50prvNqxkFINPijMCNMgKsnCBz6tfcB78j3qnEvZjNP4eV4rbTicUg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=lKsSrYSp; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="lKsSrYSp" Received: from pps.filterd (m0279864.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 48IINFa1032091; Wed, 18 Sep 2024 21:21:09 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= 97aZlelAxnf1oZWK/vk3qg6OISdr4sArbqi18OQE/2Y=; b=lKsSrYSpewbykrq1 6WJRbLR0y481zo+GgIgfHUNcpF2NhItbbS8mgWYFPaMaoohciRsbAYdFFZrc9BG3 9IyAzZvpFzBox/oaJjDm/zLc2GVYMSGtwO3W0mMk2uVXU7ZB8dBDNimtsLmXTa1t jyV6n0wj3jlGU1kDYu6zPgrcxWF1NnScnosftToVpHqM7TLfDaj8EJWuzsJnau2A CUOS2o9wPZPAScyeL91kJOHtJddltuJrvLFxbi4gGZW7dWUus99UjFzGTAan/JVK yb5Xr8iEzP2141KqZ9FMQqwqYOGc10t+yYXPMep/fo1mfziiB5kQ0tRtaWQ01Auw uPa6OQ== Received: from nalasppmta04.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 41n4geb5e1-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 18 Sep 2024 21:21:09 +0000 (GMT) Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com [10.47.209.196]) by NALASPPMTA04.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id 48ILL8jN020567 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 18 Sep 2024 21:21:08 GMT Received: from ath12k-linux1.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.1544.9; Wed, 18 Sep 2024 14:21:08 -0700 From: Pradeep Kumar Chitrapu To: CC: , Pradeep Kumar Chitrapu , Muna Sinada , "Jeff Johnson" Subject: [PATCH V8 6/9] wifi: ath12k: add support for setting fixed HE rate/GI/LTF Date: Wed, 18 Sep 2024 14:20:53 -0700 Message-ID: <20240918212056.4137076-7-quic_pradeepc@quicinc.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240918212056.4137076-1-quic_pradeepc@quicinc.com> References: <20240918212056.4137076-1-quic_pradeepc@quicinc.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01a.na.qualcomm.com (10.47.209.196) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: GGIeqOgMFye5oFp39WDjK5DZ7YoCK3Ap X-Proofpoint-ORIG-GUID: GGIeqOgMFye5oFp39WDjK5DZ7YoCK3Ap X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.60.29 definitions=2024-09-06_09,2024-09-06_01,2024-09-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 mlxlogscore=999 impostorscore=0 bulkscore=0 clxscore=1015 lowpriorityscore=0 adultscore=0 phishscore=0 suspectscore=0 priorityscore=1501 mlxscore=0 spamscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2408220000 definitions=main-2409180140 Add support to set fixed HE rate/GI/LTF values using nl80211. Reuse parts of the existing code path already used for HT/VHT to implement the new helpers symmetrically, similar to how HT/VHT is handled. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1 Co-developed-by: Muna Sinada Signed-off-by: Muna Sinada Signed-off-by: Pradeep Kumar Chitrapu Acked-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/mac.c | 604 ++++++++++++++++++++++++-- drivers/net/wireless/ath/ath12k/wmi.h | 18 + 2 files changed, 574 insertions(+), 48 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 34a9bbdbcf48..a41a63da9d48 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -441,6 +441,18 @@ ath12k_mac_max_vht_nss(const u16 *vht_mcs_mask) return 1; } +static u32 +ath12k_mac_max_he_nss(const u16 he_mcs_mask[NL80211_HE_NSS_MAX]) +{ + int nss; + + for (nss = NL80211_HE_NSS_MAX - 1; nss >= 0; nss--) + if (he_mcs_mask[nss]) + return nss + 1; + + return 1; +} + static u8 ath12k_parse_mpdudensity(u8 mpdudensity) { /* From IEEE Std 802.11-2020 defined values for "Minimum MPDU Start Spacing": @@ -1913,6 +1925,14 @@ static void ath12k_peer_assoc_h_ht(struct ath12k *ar, arg->peer_rate_caps |= WMI_HOST_RC_CW40_FLAG; } + /* As firmware handles these two flags (IEEE80211_HT_CAP_SGI_20 + * and IEEE80211_HT_CAP_SGI_40) for enabling SGI, reset both + * flags if guard interval is Default GI + */ + if (arvif->bitrate_mask.control[band].gi == NL80211_TXRATE_DEFAULT_GI) + arg->peer_ht_caps &= ~(IEEE80211_HT_CAP_SGI_20 | + IEEE80211_HT_CAP_SGI_40); + if (arvif->bitrate_mask.control[band].gi != NL80211_TXRATE_FORCE_LGI) { if (ht_cap->cap & (IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40)) @@ -2036,11 +2056,12 @@ static void ath12k_peer_assoc_h_vht(struct ath12k *ar, struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif); struct cfg80211_chan_def def; enum nl80211_band band; - const u16 *vht_mcs_mask; + u16 *vht_mcs_mask; u16 tx_mcs_map; u8 ampdu_factor; u8 max_nss, vht_mcs; - int i; + int i, vht_nss, nss_idx; + bool user_rate_valid = true; if (WARN_ON(ath12k_mac_vif_chan(vif, &def))) return; @@ -2083,6 +2104,25 @@ static void ath12k_peer_assoc_h_vht(struct ath12k *ar, if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_160) arg->bw_160 = true; + vht_nss = ath12k_mac_max_vht_nss(vht_mcs_mask); + + if (vht_nss > sta->deflink.rx_nss) { + user_rate_valid = false; + for (nss_idx = sta->deflink.rx_nss - 1; nss_idx >= 0; nss_idx--) { + if (vht_mcs_mask[nss_idx]) { + user_rate_valid = true; + break; + } + } + } + + if (!user_rate_valid) { + ath12k_dbg(ar->ab, ATH12K_DBG_MAC, + "Setting vht range MCS value to peer supported nss:%d for peer %pM\n", + sta->deflink.rx_nss, sta->deflink.addr); + vht_mcs_mask[sta->deflink.rx_nss - 1] = vht_mcs_mask[vht_nss - 1]; + } + /* Calculate peer NSS capability from VHT capabilities if STA * supports VHT. */ @@ -2122,23 +2162,105 @@ static void ath12k_peer_assoc_h_vht(struct ath12k *ar, /* TODO: rxnss_override */ } +static int ath12k_mac_get_max_he_mcs_map(u16 mcs_map, int nss) +{ + switch ((mcs_map >> (2 * nss)) & 0x3) { + case IEEE80211_HE_MCS_SUPPORT_0_7: return BIT(8) - 1; + case IEEE80211_HE_MCS_SUPPORT_0_9: return BIT(10) - 1; + case IEEE80211_HE_MCS_SUPPORT_0_11: return BIT(12) - 1; + } + return 0; +} + +static u16 ath12k_peer_assoc_h_he_limit(u16 tx_mcs_set, + const u16 *he_mcs_limit) +{ + int idx_limit; + int nss; + u16 mcs_map; + u16 mcs; + + for (nss = 0; nss < NL80211_HE_NSS_MAX; nss++) { + mcs_map = ath12k_mac_get_max_he_mcs_map(tx_mcs_set, nss) & + he_mcs_limit[nss]; + + if (mcs_map) + idx_limit = fls(mcs_map) - 1; + else + idx_limit = -1; + + switch (idx_limit) { + case 0 ... 7: + mcs = IEEE80211_HE_MCS_SUPPORT_0_7; + break; + case 8: + case 9: + mcs = IEEE80211_HE_MCS_SUPPORT_0_9; + break; + case 10: + case 11: + mcs = IEEE80211_HE_MCS_SUPPORT_0_11; + break; + default: + WARN_ON(1); + fallthrough; + case -1: + mcs = IEEE80211_HE_MCS_NOT_SUPPORTED; + break; + } + + tx_mcs_set &= ~(0x3 << (nss * 2)); + tx_mcs_set |= mcs << (nss * 2); + } + + return tx_mcs_set; +} + +static bool +ath12k_peer_assoc_h_he_masked(const u16 he_mcs_mask[NL80211_HE_NSS_MAX]) +{ + int nss; + + for (nss = 0; nss < NL80211_HE_NSS_MAX; nss++) + if (he_mcs_mask[nss]) + return false; + + return true; +} + static void ath12k_peer_assoc_h_he(struct ath12k *ar, struct ieee80211_vif *vif, struct ieee80211_sta *sta, struct ath12k_wmi_peer_assoc_arg *arg) { const struct ieee80211_sta_he_cap *he_cap = &sta->deflink.he_cap; + struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif); + struct cfg80211_chan_def def; int i; u8 ampdu_factor, max_nss; u8 rx_mcs_80 = IEEE80211_HE_MCS_NOT_SUPPORTED; u8 rx_mcs_160 = IEEE80211_HE_MCS_NOT_SUPPORTED; u16 mcs_160_map, mcs_80_map; bool support_160; - u16 v; + enum nl80211_band band; + u16 *he_mcs_mask; + u8 he_mcs; + u16 he_tx_mcs = 0, v = 0; + int he_nss, nss_idx; + bool user_rate_valid = true; + + if (WARN_ON(ath12k_mac_vif_chan(vif, &def))) + return; if (!he_cap->has_he) return; + band = def.chan->band; + he_mcs_mask = arvif->bitrate_mask.control[band].he_mcs; + + if (ath12k_peer_assoc_h_he_masked(he_mcs_mask)) + return; + arg->he_flag = true; support_160 = !!(he_cap->he_cap_elem.phy_cap_info[0] & @@ -2244,25 +2366,47 @@ static void ath12k_peer_assoc_h_he(struct ath12k *ar, if (he_cap->he_cap_elem.mac_cap_info[0] & IEEE80211_HE_MAC_CAP0_TWT_REQ) arg->twt_requester = true; + he_nss = ath12k_mac_max_he_nss(he_mcs_mask); + + if (he_nss > sta->deflink.rx_nss) { + user_rate_valid = false; + for (nss_idx = sta->deflink.rx_nss - 1; nss_idx >= 0; nss_idx--) { + if (he_mcs_mask[nss_idx]) { + user_rate_valid = true; + break; + } + } + } + + if (!user_rate_valid) { + ath12k_dbg(ar->ab, ATH12K_DBG_MAC, + "Setting he range MCS value to peer supported nss:%d for peer %pM\n", + sta->deflink.rx_nss, sta->deflink.addr); + he_mcs_mask[sta->deflink.rx_nss - 1] = he_mcs_mask[he_nss - 1]; + } + switch (sta->deflink.bandwidth) { case IEEE80211_STA_RX_BW_160: if (he_cap->he_cap_elem.phy_cap_info[0] & IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G) { - v = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_80p80); + v = ath12k_peer_assoc_h_he_limit(v, he_mcs_mask); arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80_80] = v; v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_80p80); arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80_80] = v; arg->peer_he_mcs_count++; + he_tx_mcs = v; } v = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_160); arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_160] = v; - v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_160); + v = ath12k_peer_assoc_h_he_limit(v, he_mcs_mask); arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_160] = v; arg->peer_he_mcs_count++; + if (!he_tx_mcs) + he_tx_mcs = v; fallthrough; default: @@ -2270,11 +2414,34 @@ static void ath12k_peer_assoc_h_he(struct ath12k *ar, arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80] = v; v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_80); + v = ath12k_peer_assoc_h_he_limit(v, he_mcs_mask); arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80] = v; arg->peer_he_mcs_count++; + if (!he_tx_mcs) + he_tx_mcs = v; break; } + + /* Calculate peer NSS capability from HE capabilities if STA + * supports HE. + */ + for (i = 0, max_nss = 0, he_mcs = 0; i < NL80211_HE_NSS_MAX; i++) { + he_mcs = he_tx_mcs >> (2 * i) & 3; + + /* In case of fixed rates, MCS Range in he_tx_mcs might have + * unsupported range, with he_mcs_mask set, so check either of them + * to find nss. + */ + if (he_mcs != IEEE80211_HE_MCS_NOT_SUPPORTED || + he_mcs_mask[i]) + max_nss = i + 1; + } + arg->peer_nss = min(sta->deflink.rx_nss, max_nss); + + ath12k_dbg(ar->ab, ATH12K_DBG_MAC, + "mac he peer %pM nss %d mcs cnt %d\n", + sta->deflink.addr, arg->peer_nss, arg->peer_he_mcs_count); } static void ath12k_peer_assoc_h_he_6ghz(struct ath12k *ar, @@ -2583,6 +2750,7 @@ static void ath12k_peer_assoc_h_phymode(struct ath12k *ar, enum nl80211_band band; const u8 *ht_mcs_mask; const u16 *vht_mcs_mask; + const u16 *he_mcs_mask; enum wmi_phy_mode phymode = MODE_UNKNOWN; if (WARN_ON(ath12k_mac_vif_chan(vif, &def))) @@ -2591,6 +2759,7 @@ static void ath12k_peer_assoc_h_phymode(struct ath12k *ar, band = def.chan->band; ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs; vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs; + he_mcs_mask = arvif->bitrate_mask.control[band].he_mcs; switch (band) { case NL80211_BAND_2GHZ: @@ -2599,7 +2768,8 @@ static void ath12k_peer_assoc_h_phymode(struct ath12k *ar, phymode = MODE_11BE_EHT40_2G; else phymode = MODE_11BE_EHT20_2G; - } else if (sta->deflink.he_cap.has_he) { + } else if (sta->deflink.he_cap.has_he && + !ath12k_peer_assoc_h_he_masked(he_mcs_mask)) { if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_80) phymode = MODE_11AX_HE80_2G; else if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_40) @@ -2629,7 +2799,8 @@ static void ath12k_peer_assoc_h_phymode(struct ath12k *ar, /* Check EHT first */ if (sta->deflink.eht_cap.has_eht) { phymode = ath12k_mac_get_phymode_eht(ar, sta); - } else if (sta->deflink.he_cap.has_he) { + } else if (sta->deflink.he_cap.has_he && + !ath12k_peer_assoc_h_he_masked(he_mcs_mask)) { phymode = ath12k_mac_get_phymode_he(ar, sta); } else if (sta->deflink.vht_cap.vht_supported && !ath12k_peer_assoc_h_vht_masked(vht_mcs_mask)) { @@ -4292,6 +4463,20 @@ ath12k_mac_bitrate_mask_num_vht_rates(struct ath12k *ar, return num_rates; } +static int +ath12k_mac_bitrate_mask_num_he_rates(struct ath12k *ar, + enum nl80211_band band, + const struct cfg80211_bitrate_mask *mask) +{ + int num_rates = 0; + int i; + + for (i = 0; i < ARRAY_SIZE(mask->control[band].he_mcs); i++) + num_rates += hweight16(mask->control[band].he_mcs[i]); + + return num_rates; +} + static int ath12k_mac_set_peer_vht_fixed_rate(struct ath12k_vif *arvif, struct ieee80211_sta *sta, @@ -4338,6 +4523,57 @@ ath12k_mac_set_peer_vht_fixed_rate(struct ath12k_vif *arvif, return ret; } +static int +ath12k_mac_set_peer_he_fixed_rate(struct ath12k_vif *arvif, + struct ieee80211_sta *sta, + const struct cfg80211_bitrate_mask *mask, + enum nl80211_band band) +{ + struct ath12k *ar = arvif->ar; + u8 he_rate, nss; + u32 rate_code; + int ret, i; + + lockdep_assert_held(&ar->conf_mutex); + + nss = 0; + + for (i = 0; i < ARRAY_SIZE(mask->control[band].he_mcs); i++) { + if (hweight16(mask->control[band].he_mcs[i]) == 1) { + nss = i + 1; + he_rate = ffs(mask->control[band].he_mcs[i]) - 1; + } + } + + if (!nss) { + ath12k_warn(ar->ab, "No single HE Fixed rate found to set for %pM", + sta->deflink.addr); + return -EINVAL; + } + + /* Avoid updating invalid nss as fixed rate*/ + if (nss > sta->deflink.rx_nss) + return -EINVAL; + + ath12k_dbg(ar->ab, ATH12K_DBG_MAC, + "Setting Fixed HE Rate for peer %pM. Device will not switch to any other selected rates", + sta->deflink.addr); + + rate_code = ATH12K_HW_RATE_CODE(he_rate, nss - 1, + WMI_RATE_PREAMBLE_HE); + + ret = ath12k_wmi_set_peer_param(ar, sta->deflink.addr, + arvif->vdev_id, + WMI_PEER_PARAM_FIXED_RATE, + rate_code); + if (ret) + ath12k_warn(ar->ab, + "failed to update STA %pM Fixed Rate %d: %d\n", + sta->deflink.addr, rate_code, ret); + + return ret; +} + static int ath12k_station_assoc(struct ath12k *ar, struct ieee80211_vif *vif, struct ieee80211_sta *sta, @@ -4349,7 +4585,7 @@ static int ath12k_station_assoc(struct ath12k *ar, struct cfg80211_chan_def def; enum nl80211_band band; struct cfg80211_bitrate_mask *mask; - u8 num_vht_rates; + u8 num_vht_rates, num_he_rates; lockdep_assert_held(&ar->conf_mutex); @@ -4380,15 +4616,19 @@ static int ath12k_station_assoc(struct ath12k *ar, } num_vht_rates = ath12k_mac_bitrate_mask_num_vht_rates(ar, band, mask); + num_he_rates = ath12k_mac_bitrate_mask_num_he_rates(ar, band, mask); - /* If single VHT rate is configured (by set_bitrate_mask()), - * peer_assoc will disable VHT. This is now enabled by a peer specific + /* If single VHT/HE rate is configured (by set_bitrate_mask()), + * peer_assoc will disable VHT/HE. This is now enabled by a peer specific * fixed param. * Note that all other rates and NSS will be disabled for this peer. */ if (sta->deflink.vht_cap.vht_supported && num_vht_rates == 1) { - ret = ath12k_mac_set_peer_vht_fixed_rate(arvif, sta, mask, - band); + ret = ath12k_mac_set_peer_vht_fixed_rate(arvif, sta, mask, band); + if (ret) + return ret; + } else if (sta->deflink.he_cap.has_he && num_he_rates == 1) { + ret = ath12k_mac_set_peer_he_fixed_rate(arvif, sta, mask, band); if (ret) return ret; } @@ -4462,8 +4702,9 @@ static void ath12k_sta_rc_update_wk(struct work_struct *wk) enum nl80211_band band; const u8 *ht_mcs_mask; const u16 *vht_mcs_mask; - u32 changed, bw, nss, smps, bw_prev; - int err, num_vht_rates; + const u16 *he_mcs_mask; + u32 changed, bw, nss, mac_nss, smps, bw_prev; + int err, num_vht_rates, num_he_rates; const struct cfg80211_bitrate_mask *mask; struct ath12k_wmi_peer_assoc_arg peer_arg; enum wmi_phy_mode peer_phymode; @@ -4479,6 +4720,7 @@ static void ath12k_sta_rc_update_wk(struct work_struct *wk) band = def.chan->band; ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs; vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs; + he_mcs_mask = arvif->bitrate_mask.control[band].he_mcs; spin_lock_bh(&ar->data_lock); @@ -4495,8 +4737,10 @@ static void ath12k_sta_rc_update_wk(struct work_struct *wk) mutex_lock(&ar->conf_mutex); nss = max_t(u32, 1, nss); - nss = min(nss, max(ath12k_mac_max_ht_nss(ht_mcs_mask), - ath12k_mac_max_vht_nss(vht_mcs_mask))); + mac_nss = max3(ath12k_mac_max_ht_nss(ht_mcs_mask), + ath12k_mac_max_vht_nss(vht_mcs_mask), + ath12k_mac_max_he_nss(he_mcs_mask)); + nss = min(nss, mac_nss); if (changed & IEEE80211_RC_BW_CHANGED) { ath12k_peer_assoc_h_phymode(ar, arvif->vif, sta, &peer_arg); @@ -4574,6 +4818,8 @@ static void ath12k_sta_rc_update_wk(struct work_struct *wk) mask = &arvif->bitrate_mask; num_vht_rates = ath12k_mac_bitrate_mask_num_vht_rates(ar, band, mask); + num_he_rates = ath12k_mac_bitrate_mask_num_he_rates(ar, band, + mask); /* Peer_assoc_prepare will reject vht rates in * bitrate_mask if its not available in range format and @@ -4589,11 +4835,24 @@ static void ath12k_sta_rc_update_wk(struct work_struct *wk) if (sta->deflink.vht_cap.vht_supported && num_vht_rates == 1) { ath12k_mac_set_peer_vht_fixed_rate(arvif, sta, mask, band); + } else if (sta->deflink.he_cap.has_he && num_he_rates == 1) { + ath12k_mac_set_peer_he_fixed_rate(arvif, sta, mask, band); } else { - /* If the peer is non-VHT or no fixed VHT rate + /* If the peer is non-VHT/HE or no fixed VHT/HE rate * is provided in the new bitrate mask we set the - * other rates using peer_assoc command. + * other rates using peer_assoc command. Also clear + * the peer fixed rate settings as it has higher proprity + * than peer assoc */ + + err = ath12k_wmi_set_peer_param(ar, sta->deflink.addr, + arvif->vdev_id, + WMI_PEER_PARAM_FIXED_RATE, + WMI_FIXED_RATE_NONE); + if (err) + ath12k_warn(ar->ab, + "failed to disable peer fixed rate for STA %pM ret %d\n", + sta->deflink.addr, err); ath12k_peer_assoc_prepare(ar, arvif->vif, sta, &peer_arg, true); @@ -6920,10 +7179,13 @@ static int ath12k_mac_op_add_interface(struct ieee80211_hw *hw, for (i = 0; i < ARRAY_SIZE(arvif->bitrate_mask.control); i++) { arvif->bitrate_mask.control[i].legacy = 0xffffffff; + arvif->bitrate_mask.control[i].gi = NL80211_TXRATE_FORCE_SGI; memset(arvif->bitrate_mask.control[i].ht_mcs, 0xff, sizeof(arvif->bitrate_mask.control[i].ht_mcs)); memset(arvif->bitrate_mask.control[i].vht_mcs, 0xff, sizeof(arvif->bitrate_mask.control[i].vht_mcs)); + memset(arvif->bitrate_mask.control[i].he_mcs, 0xff, + sizeof(arvif->bitrate_mask.control[i].he_mcs)); } /* Allocate Default Queue now and reassign during actual vdev create */ @@ -8071,19 +8333,40 @@ ath12k_mac_has_single_legacy_rate(struct ath12k *ar, if (ath12k_mac_bitrate_mask_num_vht_rates(ar, band, mask)) return false; + if (ath12k_mac_bitrate_mask_num_he_rates(ar, band, mask)) + return false; + return num_rates == 1; } +static __le16 +ath12k_mac_get_tx_mcs_map(const struct ieee80211_sta_he_cap *he_cap) +{ + if (he_cap->he_cap_elem.phy_cap_info[0] & + IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G) + return he_cap->he_mcs_nss_supp.tx_mcs_80p80; + + if (he_cap->he_cap_elem.phy_cap_info[0] & + IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G) + return he_cap->he_mcs_nss_supp.tx_mcs_160; + + return he_cap->he_mcs_nss_supp.tx_mcs_80; +} + static bool ath12k_mac_bitrate_mask_get_single_nss(struct ath12k *ar, + struct ieee80211_vif *vif, enum nl80211_band band, const struct cfg80211_bitrate_mask *mask, int *nss) { struct ieee80211_supported_band *sband = &ar->mac.sbands[band]; u16 vht_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map); + const struct ieee80211_sta_he_cap *he_cap; + u16 he_mcs_map = 0; u8 ht_nss_mask = 0; u8 vht_nss_mask = 0; + u8 he_nss_mask = 0; int i; /* No need to consider legacy here. Basic rates are always present @@ -8110,7 +8393,24 @@ ath12k_mac_bitrate_mask_get_single_nss(struct ath12k *ar, return false; } - if (ht_nss_mask != vht_nss_mask) + he_cap = ieee80211_get_he_iftype_cap_vif(sband, vif); + if (!he_cap) + return false; + + he_mcs_map = le16_to_cpu(ath12k_mac_get_tx_mcs_map(he_cap)); + + for (i = 0; i < ARRAY_SIZE(mask->control[band].he_mcs); i++) { + if (mask->control[band].he_mcs[i] == 0) + continue; + + if (mask->control[band].he_mcs[i] == + ath12k_mac_get_max_he_mcs_map(he_mcs_map, i)) + he_nss_mask |= BIT(i); + else + return false; + } + + if (ht_nss_mask != vht_nss_mask || ht_nss_mask != he_nss_mask) return false; if (ht_nss_mask == 0) @@ -8157,54 +8457,158 @@ ath12k_mac_get_single_legacy_rate(struct ath12k *ar, return 0; } -static int ath12k_mac_set_fixed_rate_params(struct ath12k_vif *arvif, - u32 rate, u8 nss, u8 sgi, u8 ldpc) +static int +ath12k_mac_set_fixed_rate_gi_ltf(struct ath12k_vif *arvif, u8 he_gi, u8 he_ltf) { struct ath12k *ar = arvif->ar; - u32 vdev_param; int ret; - lockdep_assert_held(&ar->conf_mutex); + /* 0.8 = 0, 1.6 = 2 and 3.2 = 3. */ + if (he_gi && he_gi != 0xFF) + he_gi += 1; - ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac set fixed rate params vdev %i rate 0x%02x nss %u sgi %u\n", - arvif->vdev_id, rate, nss, sgi); + ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, + WMI_VDEV_PARAM_SGI, he_gi); + if (ret) { + ath12k_warn(ar->ab, "failed to set HE GI:%d, error:%d\n", + he_gi, ret); + return ret; + } + /* start from 1 */ + if (he_ltf != 0xFF) + he_ltf += 1; - vdev_param = WMI_VDEV_PARAM_FIXED_RATE; ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, - vdev_param, rate); + WMI_VDEV_PARAM_HE_LTF, he_ltf); if (ret) { - ath12k_warn(ar->ab, "failed to set fixed rate param 0x%02x: %d\n", - rate, ret); + ath12k_warn(ar->ab, "failed to set HE LTF:%d, error:%d\n", + he_ltf, ret); return ret; } + return 0; +} + +static int +ath12k_mac_set_auto_rate_gi_ltf(struct ath12k_vif *arvif, u16 he_gi, u8 he_ltf) +{ + struct ath12k *ar = arvif->ar; + int ret; + u32 he_ar_gi_ltf; + + if (he_gi != 0xFF) { + switch (he_gi) { + case NL80211_RATE_INFO_HE_GI_0_8: + he_gi = WMI_AUTORATE_800NS_GI; + break; + case NL80211_RATE_INFO_HE_GI_1_6: + he_gi = WMI_AUTORATE_1600NS_GI; + break; + case NL80211_RATE_INFO_HE_GI_3_2: + he_gi = WMI_AUTORATE_3200NS_GI; + break; + default: + ath12k_warn(ar->ab, "Invalid GI\n"); + return -EINVAL; + } + } + + if (he_ltf != 0xFF) { + switch (he_ltf) { + case NL80211_RATE_INFO_HE_1XLTF: + he_ltf = WMI_HE_AUTORATE_LTF_1X; + break; + case NL80211_RATE_INFO_HE_2XLTF: + he_ltf = WMI_HE_AUTORATE_LTF_2X; + break; + case NL80211_RATE_INFO_HE_4XLTF: + he_ltf = WMI_HE_AUTORATE_LTF_4X; + break; + default: + ath12k_warn(ar->ab, "Invalid LTF\n"); + return -EINVAL; + } + } + + he_ar_gi_ltf = he_gi | he_ltf; - vdev_param = WMI_VDEV_PARAM_NSS; ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, - vdev_param, nss); + WMI_VDEV_PARAM_AUTORATE_MISC_CFG, + he_ar_gi_ltf); if (ret) { - ath12k_warn(ar->ab, "failed to set nss param %d: %d\n", - nss, ret); + ath12k_warn(ar->ab, + "failed to set HE autorate GI:%u, LTF:%u params, error:%d\n", + he_gi, he_ltf, ret); return ret; } - vdev_param = WMI_VDEV_PARAM_SGI; + return 0; +} + +static int ath12k_mac_set_rate_params(struct ath12k_vif *arvif, + u32 rate, u8 nss, u8 sgi, u8 ldpc, + u8 he_gi, u8 he_ltf, bool he_fixed_rate) +{ + struct ath12k *ar = arvif->ar; + u32 vdev_param; + int ret; + + lockdep_assert_held(&ar->conf_mutex); + + ath12k_dbg(ar->ab, ATH12K_DBG_MAC, + "mac set rate params vdev %i rate 0x%02x nss 0x%02x sgi 0x%02x ldpc 0x%02x\n", + arvif->vdev_id, rate, nss, sgi, ldpc); + + ath12k_dbg(ar->ab, ATH12K_DBG_MAC, + "he_gi 0x%02x he_ltf 0x%02x he_fixed_rate %d\n", he_gi, + he_ltf, he_fixed_rate); + + if (!arvif->vif->bss_conf.he_support) { + vdev_param = WMI_VDEV_PARAM_FIXED_RATE; + ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, + vdev_param, rate); + if (ret) { + ath12k_warn(ar->ab, "failed to set fixed rate param 0x%02x: %d\n", + rate, ret); + return ret; + } + } + + vdev_param = WMI_VDEV_PARAM_NSS; + ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, - vdev_param, sgi); + vdev_param, nss); if (ret) { - ath12k_warn(ar->ab, "failed to set sgi param %d: %d\n", - sgi, ret); + ath12k_warn(ar->ab, "failed to set nss param %d: %d\n", + nss, ret); return ret; } - vdev_param = WMI_VDEV_PARAM_LDPC; ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, - vdev_param, ldpc); + WMI_VDEV_PARAM_LDPC, ldpc); if (ret) { ath12k_warn(ar->ab, "failed to set ldpc param %d: %d\n", ldpc, ret); return ret; } + if (arvif->vif->bss_conf.he_support) { + if (he_fixed_rate) + ret = ath12k_mac_set_fixed_rate_gi_ltf(arvif, he_gi, he_ltf); + else + ret = ath12k_mac_set_auto_rate_gi_ltf(arvif, he_gi, he_ltf); + if (ret) + return ret; + } else { + vdev_param = WMI_VDEV_PARAM_SGI; + ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, + vdev_param, sgi); + if (ret) { + ath12k_warn(ar->ab, "failed to set sgi param %d: %d\n", + sgi, ret); + return ret; + } + } + return 0; } @@ -8233,6 +8637,31 @@ ath12k_mac_vht_mcs_range_present(struct ath12k *ar, return true; } +static bool +ath12k_mac_he_mcs_range_present(struct ath12k *ar, + enum nl80211_band band, + const struct cfg80211_bitrate_mask *mask) +{ + int i; + u16 he_mcs; + + for (i = 0; i < NL80211_HE_NSS_MAX; i++) { + he_mcs = mask->control[band].he_mcs[i]; + + switch (he_mcs) { + case 0: + case BIT(8) - 1: + case BIT(10) - 1: + case BIT(12) - 1: + break; + default: + return false; + } + } + + return true; +} + static void ath12k_mac_set_bitrate_mask_iter(void *data, struct ieee80211_sta *sta) { @@ -8271,6 +8700,54 @@ static void ath12k_mac_disable_peer_fixed_rate(void *data, sta->addr, ret); } +static int +ath12k_mac_validate_vht_he_fixed_rate_settings(struct ath12k *ar, enum nl80211_band band, + const struct cfg80211_bitrate_mask *mask) +{ + bool he_fixed_rate = false, vht_fixed_rate = false; + struct ath12k_peer *peer; + const u16 *vht_mcs_mask, *he_mcs_mask; + u8 vht_nss, he_nss; + int ret = 0; + + vht_mcs_mask = mask->control[band].vht_mcs; + he_mcs_mask = mask->control[band].he_mcs; + + if (ath12k_mac_bitrate_mask_num_vht_rates(ar, band, mask) == 1) + vht_fixed_rate = true; + + if (ath12k_mac_bitrate_mask_num_he_rates(ar, band, mask) == 1) + he_fixed_rate = true; + + if (!vht_fixed_rate && !he_fixed_rate) + return 0; + + vht_nss = ath12k_mac_max_vht_nss(vht_mcs_mask); + he_nss = ath12k_mac_max_he_nss(he_mcs_mask); + + rcu_read_lock(); + spin_lock_bh(&ar->ab->base_lock); + list_for_each_entry(peer, &ar->ab->peers, list) { + if (peer->sta) { + if (vht_fixed_rate && + (!peer->sta->deflink.vht_cap.vht_supported || + peer->sta->deflink.rx_nss < vht_nss)) { + ret = -EINVAL; + goto exit; + } + if (he_fixed_rate && (!peer->sta->deflink.he_cap.has_he || + peer->sta->deflink.rx_nss < he_nss)) { + ret = -EINVAL; + goto exit; + } + } + } +exit: + spin_unlock_bh(&ar->ab->base_lock); + rcu_read_unlock(); + return ret; +} + static int ath12k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif, @@ -8282,13 +8759,17 @@ ath12k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw, enum nl80211_band band; const u8 *ht_mcs_mask; const u16 *vht_mcs_mask; + const u16 *he_mcs_mask; + u8 he_ltf = 0; + u8 he_gi = 0; u32 rate; - u8 nss; + u8 nss, mac_nss; u8 sgi; u8 ldpc; int single_nss; int ret; int num_rates; + bool he_fixed_rate = false; if (ath12k_mac_vif_chan(vif, &def)) return -EPERM; @@ -8296,6 +8777,7 @@ ath12k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw, band = def.chan->band; ht_mcs_mask = mask->control[band].ht_mcs; vht_mcs_mask = mask->control[band].vht_mcs; + he_mcs_mask = mask->control[band].he_mcs; ldpc = !!(ar->ht_cap_info & WMI_HT_CAP_LDPC); sgi = mask->control[band].gi; @@ -8304,6 +8786,9 @@ ath12k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw, goto out; } + he_gi = mask->control[band].he_gi; + he_ltf = mask->control[band].he_ltf; + /* mac80211 doesn't support sending a fixed HT/VHT MCS alone, rather it * requires passing at least one of used basic rates along with them. * Fixed rate setting across different preambles(legacy, HT, VHT) is @@ -8323,15 +8808,27 @@ ath12k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw, ieee80211_iterate_stations_atomic(hw, ath12k_mac_disable_peer_fixed_rate, arvif); - } else if (ath12k_mac_bitrate_mask_get_single_nss(ar, band, mask, + } else if (ath12k_mac_bitrate_mask_get_single_nss(ar, vif, band, mask, &single_nss)) { rate = WMI_FIXED_RATE_NONE; nss = single_nss; + mutex_lock(&ar->conf_mutex); + arvif->bitrate_mask = *mask; + ieee80211_iterate_stations_atomic(hw, + ath12k_mac_set_bitrate_mask_iter, + arvif); + mutex_unlock(&ar->conf_mutex); } else { rate = WMI_FIXED_RATE_NONE; - nss = min_t(u32, ar->num_tx_chains, - max(ath12k_mac_max_ht_nss(ht_mcs_mask), - ath12k_mac_max_vht_nss(vht_mcs_mask))); + + if (!ath12k_mac_validate_vht_he_fixed_rate_settings(ar, band, mask)) + ath12k_warn(ar->ab, + "could not update fixed rate settings to all peers due to mcs/nss incompatiblity\n"); + + mac_nss = max3(ath12k_mac_max_ht_nss(ht_mcs_mask), + ath12k_mac_max_vht_nss(vht_mcs_mask), + ath12k_mac_max_he_nss(he_mcs_mask)); + nss = min_t(u32, ar->num_tx_chains, mac_nss); /* If multiple rates across different preambles are given * we can reconfigure this info with all peers using PEER_ASSOC @@ -8367,12 +8864,22 @@ ath12k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw, goto out; } + num_rates = ath12k_mac_bitrate_mask_num_he_rates(ar, band, mask); + if (num_rates == 1) + he_fixed_rate = true; + + if (!ath12k_mac_he_mcs_range_present(ar, band, mask) && + num_rates > 1) { + ath12k_warn(ar->ab, + "Setting more than one HE MCS Value in bitrate mask not supported\n"); + return -EINVAL; + } + + mutex_lock(&ar->conf_mutex); ieee80211_iterate_stations_atomic(hw, ath12k_mac_disable_peer_fixed_rate, arvif); - mutex_lock(&ar->conf_mutex); - arvif->bitrate_mask = *mask; ieee80211_iterate_stations_atomic(hw, ath12k_mac_set_bitrate_mask_iter, @@ -8383,9 +8890,10 @@ ath12k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw, mutex_lock(&ar->conf_mutex); - ret = ath12k_mac_set_fixed_rate_params(arvif, rate, nss, sgi, ldpc); + ret = ath12k_mac_set_rate_params(arvif, rate, nss, sgi, ldpc, he_gi, + he_ltf, he_fixed_rate); if (ret) { - ath12k_warn(ar->ab, "failed to set fixed rate params on vdev %i: %d\n", + ath12k_warn(ar->ab, "failed to set rate params on vdev %i: %d\n", arvif->vdev_id, ret); } diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h index 0e472df28717..23ee32f6b06e 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.h +++ b/drivers/net/wireless/ath/ath12k/wmi.h @@ -220,6 +220,22 @@ enum WMI_HOST_WLAN_BAND { WMI_HOST_WLAN_2G_5G_CAP = 3, }; +/* Parameters used for WMI_VDEV_PARAM_AUTORATE_MISC_CFG command. + * Used only for HE auto rate mode. + */ +enum { + /* HE LTF related configuration */ + WMI_HE_AUTORATE_LTF_1X = BIT(0), + WMI_HE_AUTORATE_LTF_2X = BIT(1), + WMI_HE_AUTORATE_LTF_4X = BIT(2), + + /* HE GI related configuration */ + WMI_AUTORATE_400NS_GI = BIT(8), + WMI_AUTORATE_800NS_GI = BIT(9), + WMI_AUTORATE_1600NS_GI = BIT(10), + WMI_AUTORATE_3200NS_GI = BIT(11), +}; + enum wmi_cmd_group { /* 0 to 2 are reserved */ WMI_GRP_START = 0x3, @@ -1132,7 +1148,9 @@ enum wmi_tlv_vdev_param { WMI_VDEV_PARAM_HE_RANGE_EXT, WMI_VDEV_PARAM_ENABLE_BCAST_PROBE_RESPONSE, WMI_VDEV_PARAM_FILS_MAX_CHANNEL_GUARD_TIME, + WMI_VDEV_PARAM_HE_LTF = 0x74, WMI_VDEV_PARAM_BA_MODE = 0x7e, + WMI_VDEV_PARAM_AUTORATE_MISC_CFG = 0x80, WMI_VDEV_PARAM_SET_HE_SOUNDING_MODE = 0x87, WMI_VDEV_PARAM_6GHZ_PARAMS = 0x99, WMI_VDEV_PARAM_PROTOTYPE = 0x8000, From patchwork Wed Sep 18 21:20:54 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pradeep Kumar Chitrapu X-Patchwork-Id: 829538 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E7A2C15853D for ; Wed, 18 Sep 2024 21:21:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726694491; cv=none; b=IDDUnQF/Tnpw/FvWitX7ofLgG/RwY2FyN79K1j9v3STIk2mbRSVtS7kUmHv83gWDgLeingrnJyz3kE7pWhAK5Zt+U/d3HoSbyXlaWdr1m98ZLPJnOIO51q8LBaUW4uPaZbMJiRGvTbhFw+0k6FNjQse034o2zQ5vHk1qETT9XsU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726694491; c=relaxed/simple; bh=4Sbgjg6TXf4A547Y46Qiyw4U55YEFrIGdUXLZjEx5C0=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Y+NDqrjfpb1iFWpY9XYrVbCXhYRTFGsK7MN6jcsgZur7Ro+ZQsyZfhkFA+t+Bb52hk2p2N7v1TAdqLDK2CiFXaWPy/JfESHATwktCnNG+8/UL3n0VIjl+qxGTWt3pS/aWzI6yQjM2FB6tKc4kMnGX//RrgXhEIrh1M4ROs3IpJ0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=Kt1nBSex; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="Kt1nBSex" Received: from pps.filterd (m0279866.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 48IJrYUI005813; Wed, 18 Sep 2024 21:21:27 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= 7iZtYFy4NRmF2YHXqLd4zDMUbigsFxIkBQ6OeDD3zOs=; b=Kt1nBSex9R0mUQFv fimFwEUDD2mzhj9KyoJnJsvbpzJOV9sBCCp3nPyxHNB66qzQUi/U904HE+wQ26S+ Dmo2aGOzcx4GHLU8agTSdb51h1ylcD1ulUXKpEqDIEkWv7leWNteXYTqoj2aUvXQ MH261Yr4HRs5iWT53+FXUrPvY1eipkyG20XH2RcNT7XMMIT29hm5DRVTwU0kzAVU /0hrrSBcgbTJP0KA5zSfO+bFE7fyWSxrjOzt7ugW9KdHlAj5iNAeePRUUlvqSGe7 07QprF1ixgWWpsIbUnZdd9UZLPKot8h5Vous/24QLAznqmj/FgipHLT6+Dy61eVq L/T40w== Received: from nalasppmta04.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 41n4jdu9q1-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 18 Sep 2024 21:21:27 +0000 (GMT) Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com [10.47.209.196]) by NALASPPMTA04.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id 48ILL9Ux020570 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 18 Sep 2024 21:21:09 GMT Received: from ath12k-linux1.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.1544.9; Wed, 18 Sep 2024 14:21:08 -0700 From: Pradeep Kumar Chitrapu To: CC: , Pradeep Kumar Chitrapu , Jeff Johnson Subject: [PATCH V8 7/9] wifi: ath12k: clean up 80P80 support Date: Wed, 18 Sep 2024 14:20:54 -0700 Message-ID: <20240918212056.4137076-8-quic_pradeepc@quicinc.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240918212056.4137076-1-quic_pradeepc@quicinc.com> References: <20240918212056.4137076-1-quic_pradeepc@quicinc.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01a.na.qualcomm.com (10.47.209.196) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-ORIG-GUID: zOl2cVhwvoAFaH70WioUIdrk_oIr5c-T X-Proofpoint-GUID: zOl2cVhwvoAFaH70WioUIdrk_oIr5c-T X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.60.29 definitions=2024-09-06_09,2024-09-06_01,2024-09-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 impostorscore=0 clxscore=1015 adultscore=0 mlxscore=0 suspectscore=0 malwarescore=0 priorityscore=1501 spamscore=0 bulkscore=0 lowpriorityscore=0 mlxlogscore=999 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2408220000 definitions=main-2409180141 Clean up unused 80P80 references as hardware does not support it. This is applicable to both QCN9274 and WCN7850. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1 Signed-off-by: Pradeep Kumar Chitrapu Acked-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/mac.c | 51 ++++++--------------------- drivers/net/wireless/ath/ath12k/wmi.c | 5 +-- drivers/net/wireless/ath/ath12k/wmi.h | 1 - 3 files changed, 11 insertions(+), 46 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index a41a63da9d48..3434b69a0a4b 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -206,7 +206,7 @@ ath12k_phymodes[NUM_NL80211_BANDS][ATH12K_CHAN_WIDTH_NUM] = { [NL80211_CHAN_WIDTH_40] = MODE_11BE_EHT40, [NL80211_CHAN_WIDTH_80] = MODE_11BE_EHT80, [NL80211_CHAN_WIDTH_160] = MODE_11BE_EHT160, - [NL80211_CHAN_WIDTH_80P80] = MODE_11BE_EHT80_80, + [NL80211_CHAN_WIDTH_80P80] = MODE_UNKNOWN, [NL80211_CHAN_WIDTH_320] = MODE_11BE_EHT320, }, [NL80211_BAND_6GHZ] = { @@ -217,7 +217,7 @@ ath12k_phymodes[NUM_NL80211_BANDS][ATH12K_CHAN_WIDTH_NUM] = { [NL80211_CHAN_WIDTH_40] = MODE_11BE_EHT40, [NL80211_CHAN_WIDTH_80] = MODE_11BE_EHT80, [NL80211_CHAN_WIDTH_160] = MODE_11BE_EHT160, - [NL80211_CHAN_WIDTH_80P80] = MODE_11BE_EHT80_80, + [NL80211_CHAN_WIDTH_80P80] = MODE_UNKNOWN, [NL80211_CHAN_WIDTH_320] = MODE_11BE_EHT320, }, @@ -2387,17 +2387,6 @@ static void ath12k_peer_assoc_h_he(struct ath12k *ar, switch (sta->deflink.bandwidth) { case IEEE80211_STA_RX_BW_160: - if (he_cap->he_cap_elem.phy_cap_info[0] & - IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G) { - v = ath12k_peer_assoc_h_he_limit(v, he_mcs_mask); - arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80_80] = v; - - v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_80p80); - arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80_80] = v; - - arg->peer_he_mcs_count++; - he_tx_mcs = v; - } v = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_160); arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_160] = v; @@ -2655,16 +2644,11 @@ static enum wmi_phy_mode ath12k_mac_get_phymode_vht(struct ath12k *ar, struct ieee80211_sta *sta) { if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_160) { - switch (sta->deflink.vht_cap.cap & - IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) { - case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ: - return MODE_11AC_VHT160; - case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ: - return MODE_11AC_VHT80_80; - default: - /* not sure if this is a valid case? */ + if (sta->deflink.vht_cap.cap & + IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ) return MODE_11AC_VHT160; - } + + return MODE_UNKNOWN; } if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_80) @@ -2686,11 +2670,8 @@ static enum wmi_phy_mode ath12k_mac_get_phymode_he(struct ath12k *ar, if (sta->deflink.he_cap.he_cap_elem.phy_cap_info[0] & IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G) return MODE_11AX_HE160; - else if (sta->deflink.he_cap.he_cap_elem.phy_cap_info[0] & - IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G) - return MODE_11AX_HE80_80; - /* not sure if this is a valid case? */ - return MODE_11AX_HE160; + + return MODE_UNKNOWN; } if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_80) @@ -2718,14 +2699,7 @@ static enum wmi_phy_mode ath12k_mac_get_phymode_eht(struct ath12k *ar, IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G) return MODE_11BE_EHT160; - if (sta->deflink.he_cap.he_cap_elem.phy_cap_info[0] & - IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G) - return MODE_11BE_EHT80_80; - - ath12k_warn(ar->ab, "invalid EHT PHY capability info for 160 Mhz: %d\n", - sta->deflink.he_cap.he_cap_elem.phy_cap_info[0]); - - return MODE_11BE_EHT160; + return MODE_UNKNOWN; } if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_80) @@ -5789,8 +5763,6 @@ static void ath12k_mac_set_hemcsmap(struct ath12k *ar, mcs_nss->tx_mcs_80 = cpu_to_le16(txmcs_map & 0xffff); mcs_nss->rx_mcs_160 = cpu_to_le16(rxmcs_map & 0xffff); mcs_nss->tx_mcs_160 = cpu_to_le16(txmcs_map & 0xffff); - mcs_nss->rx_mcs_80p80 = cpu_to_le16(rxmcs_map & 0xffff); - mcs_nss->tx_mcs_80p80 = cpu_to_le16(txmcs_map & 0xffff); } static void ath12k_mac_copy_he_cap(struct ath12k *ar, @@ -5812,6 +5784,7 @@ static void ath12k_mac_copy_he_cap(struct ath12k *ar, IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G | IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G | IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G; + /* 80PLUS80 is not supported */ he_cap_elem->phy_cap_info[0] &= ~IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G; he_cap_elem->phy_cap_info[5] &= @@ -8342,10 +8315,6 @@ ath12k_mac_has_single_legacy_rate(struct ath12k *ar, static __le16 ath12k_mac_get_tx_mcs_map(const struct ieee80211_sta_he_cap *he_cap) { - if (he_cap->he_cap_elem.phy_cap_info[0] & - IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G) - return he_cap->he_mcs_nss_supp.tx_mcs_80p80; - if (he_cap->he_cap_elem.phy_cap_info[0] & IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G) return he_cap->he_mcs_nss_supp.tx_mcs_160; diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c index 7aabee813de6..e98b79c1b191 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.c +++ b/drivers/net/wireless/ath/ath12k/wmi.c @@ -984,10 +984,7 @@ static void ath12k_wmi_put_wmi_channel(struct ath12k_wmi_channel_params *chan, chan->mhz = cpu_to_le32(arg->freq); chan->band_center_freq1 = cpu_to_le32(arg->band_center_freq1); - if (arg->mode == MODE_11AC_VHT80_80) - chan->band_center_freq2 = cpu_to_le32(arg->band_center_freq2); - else - chan->band_center_freq2 = 0; + chan->band_center_freq2 = 0; chan->info |= le32_encode_bits(arg->mode, WMI_CHAN_INFO_MODE); if (arg->passive) diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h index 23ee32f6b06e..0600995d0cb0 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.h +++ b/drivers/net/wireless/ath/ath12k/wmi.h @@ -3633,7 +3633,6 @@ struct wmi_vdev_install_key_arg { #define WMI_HOST_MAX_HE_RATE_SET 3 #define WMI_HECAP_TXRX_MCS_NSS_IDX_80 0 #define WMI_HECAP_TXRX_MCS_NSS_IDX_160 1 -#define WMI_HECAP_TXRX_MCS_NSS_IDX_80_80 2 struct wmi_rate_set_arg { u32 num_rates; From patchwork Wed Sep 18 21:20:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pradeep Kumar Chitrapu X-Patchwork-Id: 829539 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C64DB1CB518 for ; Wed, 18 Sep 2024 21:21:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726694477; cv=none; b=aWI5JISgL9c0iB/8EAXYKF/Lb2sJoeG+v5+Va4eb/voqwiSQ4FtwPkCC00b9attXvu4dD9wEHGKPW8Uh2kb1tSTl0uNHxijRmLYK2VUWkLHsZ3Pd6VvGoTpbtmOTgsGklZHZiFd+jyWgGkHB4ZBkHSkG9JH6VR44MSIgNj8g14A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726694477; c=relaxed/simple; bh=AYJpDHbXZ0n0NNHQi7/aGcqo7YfyoYhv+FrXZ143wMA=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=jD1C2mzFvENculg9HS0v02iWUDzrWXiuU5GXTyC/0BKAJirnQkOUdVm7u0AEPiMxfkktLT3QCJLuvnKu3ZqSXWNbc2zOdUHTyW12fKdDNHib1WYYySBnfqu4EmiJKGcTE57VFlVdbklngOCDTCqHvVgP7YitGg2fWLPqBP/4yhM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=OMqc+btb; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="OMqc+btb" Received: from pps.filterd (m0279872.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 48I8sxTR020476; Wed, 18 Sep 2024 21:21:11 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= dFohRj9vqwjJTRRYk31/1oJCFqLLKUuQ/verxCo/cGo=; b=OMqc+btbHl9cHSxO NauW5WX4C34QsGL/4d03QTtCDlctfB5PRmINiP2/jGcVZk3NZWS3d2f5zjPY7+hd uaUDslDMQwvAj1Jay/we1qNaFIPuzj4c9BbHqvvXa0WiCgQWpBC2h2jcFLXbeVHE 5bqH+plXU5cz1d2YbsRpCXsdUWL/+S3u6A6/qxj6UraJ1s/rkE4ndQe/AQuf96Ja ylYiZPdtJJXzB6rPDN1bQsSET/PNXzIkrYTaDLF9A6688WU9izJdAjRcsu8oB8o1 U+yftDfoegI7+ZyTZ4JUnQs7zJp171L/qsF0U9RONZCIbSLN9pkTo6xp6CrHGeLQ 0tCmwQ== Received: from nalasppmta05.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 41n4j6uagr-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 18 Sep 2024 21:21:10 +0000 (GMT) Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com [10.47.209.196]) by NALASPPMTA05.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id 48ILL9IB009589 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 18 Sep 2024 21:21:09 GMT Received: from ath12k-linux1.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.1544.9; Wed, 18 Sep 2024 14:21:09 -0700 From: Pradeep Kumar Chitrapu To: CC: , Pradeep Kumar Chitrapu , P Praneesh , "Jeff Johnson" Subject: [PATCH V8 8/9] wifi: ath12k: add support for 160 MHz bandwidth Date: Wed, 18 Sep 2024 14:20:55 -0700 Message-ID: <20240918212056.4137076-9-quic_pradeepc@quicinc.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240918212056.4137076-1-quic_pradeepc@quicinc.com> References: <20240918212056.4137076-1-quic_pradeepc@quicinc.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01a.na.qualcomm.com (10.47.209.196) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-ORIG-GUID: wO0mnzqAAbcWYLNaoEhU3YfsdCyDJ2hk X-Proofpoint-GUID: wO0mnzqAAbcWYLNaoEhU3YfsdCyDJ2hk X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.60.29 definitions=2024-09-06_09,2024-09-06_01,2024-09-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 mlxlogscore=999 mlxscore=0 malwarescore=0 bulkscore=0 priorityscore=1501 clxscore=1015 adultscore=0 suspectscore=0 lowpriorityscore=0 spamscore=0 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2408220000 definitions=main-2409180140 Add support to configure maximum NSS in 160 MHz bandwidth. Firmware advertises support for handling NSS ratio information as a part of service ready ext event using nss_ratio_enabled flag. Save this information in ath12k_pdev_cap to calculate NSS ratio. Additionally, reorder the code by moving ath12k_peer_assoc_h_phymode() before ath12k_peer_assoc_h_vht() to ensure that arg->peer_phymode correctly reflects the bandwidth in the max NSS calculation. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1 Co-developed-by: P Praneesh Signed-off-by: P Praneesh Signed-off-by: Pradeep Kumar Chitrapu Acked-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/core.h | 2 + drivers/net/wireless/ath/ath12k/mac.c | 85 ++++++++++++++++++++++---- drivers/net/wireless/ath/ath12k/mac.h | 2 + drivers/net/wireless/ath/ath12k/wmi.c | 19 +++++- drivers/net/wireless/ath/ath12k/wmi.h | 28 +++++++++ 5 files changed, 124 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index 7f2e9a9b4097..6f7fb4d94957 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -702,6 +702,8 @@ struct ath12k_pdev_cap { u32 tx_chain_mask_shift; u32 rx_chain_mask_shift; struct ath12k_band_cap band[NUM_NL80211_BANDS]; + bool nss_ratio_enabled; + u8 nss_ratio_info; }; struct mlo_timestamp { diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 3434b69a0a4b..7af421107f79 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -2047,6 +2047,34 @@ ath12k_peer_assoc_h_vht_limit(u16 tx_mcs_set, return tx_mcs_set; } +static u8 ath12k_get_nss_160mhz(struct ath12k *ar, + u8 max_nss) +{ + u8 nss_ratio_info = ar->pdev->cap.nss_ratio_info; + u8 max_sup_nss = 0; + + switch (nss_ratio_info) { + case WMI_NSS_RATIO_1BY2_NSS: + max_sup_nss = max_nss >> 1; + break; + case WMI_NSS_RATIO_3BY4_NSS: + ath12k_warn(ar->ab, "WMI_NSS_RATIO_3BY4_NSS not supported\n"); + break; + case WMI_NSS_RATIO_1_NSS: + max_sup_nss = max_nss; + break; + case WMI_NSS_RATIO_2_NSS: + ath12k_warn(ar->ab, "WMI_NSS_RATIO_2_NSS not supported\n"); + break; + default: + ath12k_warn(ar->ab, "invalid nss ratio received from fw: %d\n", + nss_ratio_info); + break; + } + + return max_sup_nss; +} + static void ath12k_peer_assoc_h_vht(struct ath12k *ar, struct ieee80211_vif *vif, struct ieee80211_sta *sta, @@ -2062,6 +2090,7 @@ static void ath12k_peer_assoc_h_vht(struct ath12k *ar, u8 max_nss, vht_mcs; int i, vht_nss, nss_idx; bool user_rate_valid = true; + u32 rx_nss, tx_nss, nss_160; if (WARN_ON(ath12k_mac_vif_chan(vif, &def))) return; @@ -2156,10 +2185,24 @@ static void ath12k_peer_assoc_h_vht(struct ath12k *ar, /* TODO: Check */ arg->tx_max_mcs_nss = 0xFF; - ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac vht peer %pM max_mpdu %d flags 0x%x\n", - sta->addr, arg->peer_max_mpdu, arg->peer_flags); + if (arg->peer_phymode == MODE_11AC_VHT160) { + tx_nss = ath12k_get_nss_160mhz(ar, max_nss); + rx_nss = min(arg->peer_nss, tx_nss); + arg->peer_bw_rxnss_override = ATH12K_BW_NSS_MAP_ENABLE; - /* TODO: rxnss_override */ + if (!rx_nss) { + ath12k_warn(ar->ab, "invalid max_nss\n"); + return; + } + + nss_160 = u32_encode_bits(rx_nss - 1, ATH12K_PEER_RX_NSS_160MHZ); + arg->peer_bw_rxnss_override |= nss_160; + } + + ath12k_dbg(ar->ab, ATH12K_DBG_MAC, + "mac vht peer %pM max_mpdu %d flags 0x%x nss_override 0x%x\n", + sta->addr, arg->peer_max_mpdu, arg->peer_flags, + arg->peer_bw_rxnss_override); } static int ath12k_mac_get_max_he_mcs_map(u16 mcs_map, int nss) @@ -2248,6 +2291,7 @@ static void ath12k_peer_assoc_h_he(struct ath12k *ar, u16 he_tx_mcs = 0, v = 0; int he_nss, nss_idx; bool user_rate_valid = true; + u32 rx_nss, tx_nss, nss_160; if (WARN_ON(ath12k_mac_vif_chan(vif, &def))) return; @@ -2426,11 +2470,28 @@ static void ath12k_peer_assoc_h_he(struct ath12k *ar, he_mcs_mask[i]) max_nss = i + 1; } + max_nss = min(max_nss, ar->num_tx_chains); arg->peer_nss = min(sta->deflink.rx_nss, max_nss); + if (arg->peer_phymode == MODE_11AX_HE160) { + tx_nss = ath12k_get_nss_160mhz(ar, max_nss); + rx_nss = min(arg->peer_nss, tx_nss); + arg->peer_bw_rxnss_override = ATH12K_BW_NSS_MAP_ENABLE; + + if (!rx_nss) { + ath12k_warn(ar->ab, "invalid max_nss\n"); + return; + } + + nss_160 = u32_encode_bits(rx_nss - 1, ATH12K_PEER_RX_NSS_160MHZ); + arg->peer_bw_rxnss_override |= nss_160; + } + ath12k_dbg(ar->ab, ATH12K_DBG_MAC, - "mac he peer %pM nss %d mcs cnt %d\n", - sta->deflink.addr, arg->peer_nss, arg->peer_he_mcs_count); + "mac he peer %pM nss %d mcs cnt %d nss_override 0x%x\n", + sta->deflink.addr, arg->peer_nss, + arg->peer_he_mcs_count, + arg->peer_bw_rxnss_override); } static void ath12k_peer_assoc_h_he_6ghz(struct ath12k *ar, @@ -2962,13 +3023,13 @@ static void ath12k_peer_assoc_prepare(struct ath12k *ar, ath12k_peer_assoc_h_basic(ar, vif, sta, arg); ath12k_peer_assoc_h_crypto(ar, vif, sta, arg); ath12k_peer_assoc_h_rates(ar, vif, sta, arg); + ath12k_peer_assoc_h_phymode(ar, vif, sta, arg); ath12k_peer_assoc_h_ht(ar, vif, sta, arg); ath12k_peer_assoc_h_vht(ar, vif, sta, arg); ath12k_peer_assoc_h_he(ar, vif, sta, arg); ath12k_peer_assoc_h_he_6ghz(ar, vif, sta, arg); ath12k_peer_assoc_h_eht(ar, vif, sta, arg); ath12k_peer_assoc_h_qos(ar, vif, sta, arg); - ath12k_peer_assoc_h_phymode(ar, vif, sta, arg); ath12k_peer_assoc_h_smps(sta, arg); /* TODO: amsdu_disable req? */ @@ -5533,10 +5594,8 @@ ath12k_create_vht_cap(struct ath12k *ar, u32 rate_cap_tx_chainmask, ath12k_set_vht_txbf_cap(ar, &vht_cap.cap); - /* TODO: Enable back VHT160 mode once association issues are fixed */ - /* Disabling VHT160 and VHT80+80 modes */ - vht_cap.cap &= ~IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK; - vht_cap.cap &= ~IEEE80211_VHT_CAP_SHORT_GI_160; + /* 80P80 is not supported */ + vht_cap.cap &= ~IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ; rxmcs_map = 0; txmcs_map = 0; @@ -9551,7 +9610,8 @@ static int ath12k_mac_setup_iface_combinations(struct ath12k_hw *ah) combinations[0].radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) | BIT(NL80211_CHAN_WIDTH_20) | BIT(NL80211_CHAN_WIDTH_40) | - BIT(NL80211_CHAN_WIDTH_80); + BIT(NL80211_CHAN_WIDTH_80) | + BIT(NL80211_CHAN_WIDTH_160); wiphy->iface_combinations = combinations; wiphy->n_iface_combinations = 1; @@ -9767,6 +9827,9 @@ static int ath12k_mac_hw_register(struct ath12k_hw *ah) ieee80211_hw_set(hw, SUPPORTS_TX_FRAG); ieee80211_hw_set(hw, REPORTS_LOW_ACK); + if (cap->nss_ratio_enabled) + ieee80211_hw_set(hw, SUPPORTS_VHT_EXT_NSS_BW); + if ((ht_cap & WMI_HT_CAP_ENABLED) || ar->supports_6ghz) { ieee80211_hw_set(hw, AMPDU_AGGREGATION); ieee80211_hw_set(hw, TX_AMPDU_SETUP_IN_HW); diff --git a/drivers/net/wireless/ath/ath12k/mac.h b/drivers/net/wireless/ath/ath12k/mac.h index 8d541f1c2d80..e7e29bb9fcf0 100644 --- a/drivers/net/wireless/ath/ath12k/mac.h +++ b/drivers/net/wireless/ath/ath12k/mac.h @@ -37,6 +37,8 @@ struct ath12k_generic_iter { #define IEEE80211_DISABLE_VHT_MCS_SUPPORT_0_11 BIT(24) #define ATH12K_CHAN_WIDTH_NUM 14 +#define ATH12K_BW_NSS_MAP_ENABLE BIT(31) +#define ATH12K_PEER_RX_NSS_160MHZ GENMASK(2, 0) #define ATH12K_TX_POWER_MAX_VAL 70 #define ATH12K_TX_POWER_MIN_VAL 0 diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c index e98b79c1b191..15c08a2313bc 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.c +++ b/drivers/net/wireless/ath/ath12k/wmi.c @@ -523,6 +523,10 @@ ath12k_pull_mac_phy_cap_svc_ready_ext(struct ath12k_wmi_pdev *wmi_handle, pdev_cap->he_mcs = le32_to_cpu(mac_caps->he_supp_mcs_5g); pdev_cap->tx_chain_mask = le32_to_cpu(mac_caps->tx_chain_mask_5g); pdev_cap->rx_chain_mask = le32_to_cpu(mac_caps->rx_chain_mask_5g); + pdev_cap->nss_ratio_enabled = + WMI_NSS_RATIO_EN_DIS_GET(mac_caps->nss_ratio); + pdev_cap->nss_ratio_info = + WMI_NSS_RATIO_INFO_GET(mac_caps->nss_ratio); } else { return -EINVAL; } @@ -980,11 +984,24 @@ int ath12k_wmi_vdev_down(struct ath12k *ar, u8 vdev_id) static void ath12k_wmi_put_wmi_channel(struct ath12k_wmi_channel_params *chan, struct wmi_vdev_start_req_arg *arg) { + u32 center_freq1 = arg->band_center_freq1; + memset(chan, 0, sizeof(*chan)); chan->mhz = cpu_to_le32(arg->freq); chan->band_center_freq1 = cpu_to_le32(arg->band_center_freq1); - chan->band_center_freq2 = 0; + if (arg->mode == MODE_11AX_HE160) { + if (arg->freq > center_freq1) + chan->band_center_freq1 = + cpu_to_le32(center_freq1 + 40); + else + chan->band_center_freq1 = + cpu_to_le32(center_freq1 - 40); + + chan->band_center_freq2 = cpu_to_le32(arg->band_center_freq1); + } else { + chan->band_center_freq2 = 0; + } chan->info |= le32_encode_bits(arg->mode, WMI_CHAN_INFO_MODE); if (arg->passive) diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h index 0600995d0cb0..6f9ba0e39fe8 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.h +++ b/drivers/net/wireless/ath/ath12k/wmi.h @@ -2264,6 +2264,21 @@ enum wmi_direct_buffer_module { WMI_DIRECT_BUF_MAX }; +/** + * enum wmi_nss_ratio - NSS ratio received from FW during service ready ext event + * @WMI_NSS_RATIO_1BY2_NSS: Max nss of 160MHz is equals to half of the max nss of 80MHz + * @WMI_NSS_RATIO_3BY4_NSS: Max nss of 160MHz is equals to 3/4 of the max nss of 80MHz + * @WMI_NSS_RATIO_1_NSS: Max nss of 160MHz is equals to the max nss of 80MHz + * @WMI_NSS_RATIO_2_NSS: Max nss of 160MHz is equals to two times the max nss of 80MHz + */ + +enum wmi_nss_ratio { + WMI_NSS_RATIO_1BY2_NSS, + WMI_NSS_RATIO_3BY4_NSS, + WMI_NSS_RATIO_1_NSS, + WMI_NSS_RATIO_2_NSS +}; + struct ath12k_wmi_pdev_band_arg { u32 pdev_id; u32 start_freq; @@ -2580,6 +2595,12 @@ struct ath12k_wmi_hw_mode_cap_params { } __packed; #define WMI_MAX_HECAP_PHY_SIZE (3) +#define WMI_NSS_RATIO_EN_DIS_BITPOS BIT(0) +#define WMI_NSS_RATIO_EN_DIS_GET(_val) \ + le32_get_bits(_val, WMI_NSS_RATIO_EN_DIS_BITPOS) +#define WMI_NSS_RATIO_INFO_BITPOS GENMASK(4, 1) +#define WMI_NSS_RATIO_INFO_GET(_val) \ + le32_get_bits(_val, WMI_NSS_RATIO_INFO_BITPOS) /* pdev_id is present in lower 16 bits of pdev_and_hw_link_ids in * ath12k_wmi_mac_phy_caps_params & ath12k_wmi_caps_ext_params. @@ -2621,6 +2642,13 @@ struct ath12k_wmi_mac_phy_caps_params { __le32 he_cap_info_2g_ext; __le32 he_cap_info_5g_ext; __le32 he_cap_info_internal; + __le32 wireless_modes; + __le32 low_2ghz_chan_freq; + __le32 high_2ghz_chan_freq; + __le32 low_5ghz_chan_freq; + __le32 high_5ghz_chan_freq; + __le32 nss_ratio; + } __packed; struct ath12k_wmi_hal_reg_caps_ext_params { From patchwork Wed Sep 18 21:20:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pradeep Kumar Chitrapu X-Patchwork-Id: 829540 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A44471CB32B for ; Wed, 18 Sep 2024 21:21:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726694476; cv=none; b=YnQUUZ4IfmLtgtYCtYRGhH8uRGd6VL74IRylGv6Ihb2PMO/n5UdfZlDk/m9w0OH4/sSsqULSz2lupiSTwXCPxc+73uK+OUjIEmCfPlNdrtzK2naXyiXAASPqonpnRBnyoIFwaE8zj8AHUqk5TAajedqpK9EnOaboX2XGYVbe0yI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726694476; c=relaxed/simple; bh=TAPBD6g5pYNuC8Odk6t6JkL8GvKdG9H30IPHTEgA7C0=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=djAINL+wQRgQaGOI4fotrExnm1Yz5quwEW2I7s85hWLI3gB+HsjwPKWJypllDKm8W0FDcrsoZWFmOrfx0wJ5LIe+OtXJ4ijSG7xcJeGtgDXZ3hAA5ZBk/B+CD+g+NZ3c0mwkSKpUm5dUBPKi1+kJsPuVEwKeCmdMVj8QHSYMXPw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=i4iTJD+Z; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="i4iTJD+Z" Received: from pps.filterd (m0279863.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 48I9VJ15022098; Wed, 18 Sep 2024 21:21:11 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= 2gwv4CbPGErAHv9NWtZrCSVk7NoZpHzKz9tuTs+8dV4=; b=i4iTJD+ZMXDp8Ul8 HTo5IL/NLwS3mnlutEaaL+juUKm+wsFdl/BeMp9CC4H/sapolIhM4Zje9t3H9K0R +z1OxQDEekvWrrfUlikEaUHjOEwQ4YKSPJ+1uAIrbbA3REWeW5z39IITJ3dGU05N hnfPQEiFcPgDbFQv0Iaf434znv8rbOow6dc+M1E6EjpGd92Mq80BpsJqP8Ee0RUr WO3rsws1kXzFs6ELsg/FmC3l6eG9A4z9SUxcZ7QqTaz8aPOAZS/lclN0cOJT7VgK 7UNPGoDoJhTmHEX17W/rQR8RiV8c0hMciOuB1sfI7H/1uGkEPMjmfIsEdBjQ/9oa DDiHrg== Received: from nalasppmta02.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 41n4hfk92c-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 18 Sep 2024 21:21:11 +0000 (GMT) Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com [10.47.209.196]) by NALASPPMTA02.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id 48ILLA0u011397 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 18 Sep 2024 21:21:10 GMT Received: from ath12k-linux1.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.1544.9; Wed, 18 Sep 2024 14:21:09 -0700 From: Pradeep Kumar Chitrapu To: CC: , Pradeep Kumar Chitrapu , Jeff Johnson Subject: [PATCH V8 9/9] wifi: ath12k: add extended NSS bandwidth support for 160 MHz Date: Wed, 18 Sep 2024 14:20:56 -0700 Message-ID: <20240918212056.4137076-10-quic_pradeepc@quicinc.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240918212056.4137076-1-quic_pradeepc@quicinc.com> References: <20240918212056.4137076-1-quic_pradeepc@quicinc.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01a.na.qualcomm.com (10.47.209.196) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: Mta6b5FqdCLrvsiUf1WwMHFr8SiJUh5L X-Proofpoint-ORIG-GUID: Mta6b5FqdCLrvsiUf1WwMHFr8SiJUh5L X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.60.29 definitions=2024-09-06_09,2024-09-06_01,2024-09-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 clxscore=1015 phishscore=0 malwarescore=0 mlxlogscore=999 mlxscore=0 impostorscore=0 adultscore=0 suspectscore=0 lowpriorityscore=0 spamscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2408220000 definitions=main-2409180140 Currently rx and tx MCS map for 160 MHz under HE capabilities are not updating properly, when 160 MHz is configured with NSS lesser than max NSS support. Fix this by utilizing nss_ratio_enabled and nss_ratio_info fields sent by firmware in service ready event. However, if firmware advertises EXT NSS BW support in VHT caps as 1(1x2) and when nss_ratio_info indicates 1:1, reset the EXT NSS BW Support in VHT caps to 0 which indicates 1x1. This is to avoid incorrectly choosing 1:2 NSS ratio when using the default VHT caps advertised by firmware. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1 Signed-off-by: Pradeep Kumar Chitrapu Acked-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/mac.c | 33 ++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 7af421107f79..ff036922f925 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -2474,8 +2474,10 @@ static void ath12k_peer_assoc_h_he(struct ath12k *ar, arg->peer_nss = min(sta->deflink.rx_nss, max_nss); if (arg->peer_phymode == MODE_11AX_HE160) { - tx_nss = ath12k_get_nss_160mhz(ar, max_nss); + tx_nss = ath12k_get_nss_160mhz(ar, ar->num_tx_chains); rx_nss = min(arg->peer_nss, tx_nss); + + arg->peer_nss = min(sta->deflink.rx_nss, ar->num_rx_chains); arg->peer_bw_rxnss_override = ATH12K_BW_NSS_MAP_ENABLE; if (!rx_nss) { @@ -5617,6 +5619,12 @@ ath12k_create_vht_cap(struct ath12k *ar, u32 rate_cap_tx_chainmask, vht_cap.vht_mcs.rx_mcs_map = cpu_to_le16(rxmcs_map); vht_cap.vht_mcs.tx_mcs_map = cpu_to_le16(txmcs_map); + /* Check if the HW supports 1:1 NSS ratio and reset + * EXT NSS BW Support field to 0 to indicate 1:1 ratio + */ + if (ar->pdev->cap.nss_ratio_info == WMI_NSS_RATIO_1_NSS) + vht_cap.cap &= ~IEEE80211_VHT_CAP_EXT_NSS_BW_MASK; + return vht_cap; } @@ -5799,11 +5807,12 @@ static void ath12k_mac_set_hemcsmap(struct ath12k *ar, struct ieee80211_sta_he_cap *he_cap) { struct ieee80211_he_mcs_nss_supp *mcs_nss = &he_cap->he_mcs_nss_supp; - u16 txmcs_map, rxmcs_map; + u8 maxtxnss_160 = ath12k_get_nss_160mhz(ar, ar->num_tx_chains); + u8 maxrxnss_160 = ath12k_get_nss_160mhz(ar, ar->num_rx_chains); + u16 txmcs_map_160 = 0, rxmcs_map_160 = 0; + u16 txmcs_map = 0, rxmcs_map = 0; u32 i; - rxmcs_map = 0; - txmcs_map = 0; for (i = 0; i < 8; i++) { if (i < ar->num_tx_chains && (ar->cfg_tx_chainmask >> cap->tx_chain_mask_shift) & BIT(i)) @@ -5816,12 +5825,24 @@ static void ath12k_mac_set_hemcsmap(struct ath12k *ar, rxmcs_map |= IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2); else rxmcs_map |= IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2); + + if (i < maxtxnss_160 && + (ar->cfg_tx_chainmask >> cap->tx_chain_mask_shift) & BIT(i)) + txmcs_map_160 |= IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2); + else + txmcs_map_160 |= IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2); + + if (i < maxrxnss_160 && + (ar->cfg_tx_chainmask >> cap->tx_chain_mask_shift) & BIT(i)) + rxmcs_map_160 |= IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2); + else + rxmcs_map_160 |= IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2); } mcs_nss->rx_mcs_80 = cpu_to_le16(rxmcs_map & 0xffff); mcs_nss->tx_mcs_80 = cpu_to_le16(txmcs_map & 0xffff); - mcs_nss->rx_mcs_160 = cpu_to_le16(rxmcs_map & 0xffff); - mcs_nss->tx_mcs_160 = cpu_to_le16(txmcs_map & 0xffff); + mcs_nss->rx_mcs_160 = cpu_to_le16(rxmcs_map_160 & 0xffff); + mcs_nss->tx_mcs_160 = cpu_to_le16(txmcs_map_160 & 0xffff); } static void ath12k_mac_copy_he_cap(struct ath12k *ar,