From patchwork Mon Apr 30 21:30:46 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sebastian Gottschall X-Patchwork-Id: 10372949 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id BAFD060384 for ; Mon, 30 Apr 2018 21:31:31 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A800528BA1 for ; Mon, 30 Apr 2018 21:31:31 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9AC1128BA6; Mon, 30 Apr 2018 21:31:31 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id F1E8828BA1 for ; Mon, 30 Apr 2018 21:31:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To: References:List-Owner; bh=/BwY4uwQKsGl7DZkzsbqZDGT4du8kU65F80jZ/KY+NA=; b=RgD /TtHPaHkQsNK/3kPWd6anYzFA88q34uJFXKkizy195Xpi87vdH2PL/TB9ype+8qS2oSzt44Ypdt6y 9ibQQSDB5agU9iA9b2NjzsCwEH1neY/Ys7TE9INdznkgA7tt+rB51RbfYvajO2pxolPuk29dwAe0X FnUxlJkWIh5DWZeAtag8KbIbYFI9lOhYTWKqHPVyAJDFpL48RMMDAIfinL89hGftxTPuOIWYsdcwv SozF5PrzsWgZLe8noQIeD+7oBmg2Jj64f59ffy888FaQ0dTWfcr9w2EQ4sLwlg6FQ9g/Gi/1c0X0j d26Mkq2F0YqLx5gltOJReBJrakQUCDA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1fDGOI-0000Op-AS; Mon, 30 Apr 2018 21:31:22 +0000 Received: from smtps.newmedia-net.de ([2a05:a1c0:0:de::167] helo=webmail.newmedia-net.de) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1fDGO3-0000L2-I1 for ath10k@lists.infradead.org; Mon, 30 Apr 2018 21:31:19 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=dd-wrt.com; s=mikd; h=Message-Id:Date:Subject:Cc:To:From; bh=k9zlUFt53+/0Ud3yIl9WJmbGqbQIQ2NQNOdR7mPJMwk=; b=h84p2fpFs8FZuXQNhFU/LWsaeGs877NVr8m9VfQTUVdGAszOO4JijmmrkeYEG2gHoFb+nQAHnw8HTn625lJ6SgU6zVh6j4vT4id+227OQFxccViYZYngcr+xt2EUUbLH+ikA+j0D33REh6fmKx/HwdS0J9sDsmqgslPFK+ZeeaI=; From: s.gottschall@dd-wrt.com To: ath10k@lists.infradead.org, linux-wireless@vger.kernel.org Subject: [PATCH v7] ath10k: fix crash in recent 3.5.3 9984 firmware due wrong handling of peer_bw_rxnss_override parameter Date: Mon, 30 Apr 2018 23:30:46 +0200 Message-Id: <20180430213046.8393-1-s.gottschall@dd-wrt.com> X-Mailer: git-send-email 2.17.0 X-Received: from [2003:c9:3f40:cb00:be5f:f4ff:febd:cb45] (helo=localhost.localdomain) by webmail.newmedia-net.de with esmtpa (Exim 4.72) (envelope-from ) id 1fDGNp-0003MM-AQ; Mon, 30 Apr 2018 23:30:53 +0200 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180430_143107_935616_C1B45BEA X-CRM114-Status: GOOD ( 14.65 ) X-BeenThere: ath10k@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Sebastian Gottschall , kvalo@codeaurora.org MIME-Version: 1.0 Sender: "ath10k" Errors-To: ath10k-bounces+patchwork-ath10k=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Sebastian Gottschall current handling of peer_bw_rxnss_override parameter is based on guessing the VHT160/8080 capability by rx rate. this is wrong and may lead to a non initialized peer_bw_rxnss_override parameter which is required since VHT160 operation mode only supports 2x2 chainmasks in addition the original code initialized the parameter with wrong masked values. This patch uses the peer phymode and peer nss information for correct initialisation of the peer_bw_rxnss_override parameter. if this peer information is not available, we initialize the parameter by minimum nss which is suggested by QCA as temporary workaround according to the QCA sourcecodes. Signed-off-by: Sebastian Gottschall v2: remove debug messages v3: apply some cosmetics, update documentation v4: fix compile warning and truncate nss to maximum of 2x2 since current chipsets only support 2x2 at vht160 v5: handle maximum nss for chipsets supportig vht160 with 1x1 only v7: use more simple code variant and take care about hw/sw chainmask configuration --- drivers/net/wireless/ath/ath10k/mac.c | 40 +++++++++++++++------------ drivers/net/wireless/ath/ath10k/wmi.c | 7 +---- drivers/net/wireless/ath/ath10k/wmi.h | 14 +++++++++- 3 files changed, 36 insertions(+), 25 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 5be6386ede8f..0483ebf15e23 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -2468,7 +2468,7 @@ static void ath10k_peer_assoc_h_vht(struct ath10k *ar, const u16 *vht_mcs_mask; u8 ampdu_factor; u8 max_nss, vht_mcs; - int i; + int i, nss160; if (WARN_ON(ath10k_mac_vif_chan(vif, &def))) return; @@ -2528,23 +2528,27 @@ static void ath10k_peer_assoc_h_vht(struct ath10k *ar, __le16_to_cpu(vht_cap->vht_mcs.tx_highest); arg->peer_vht_rates.tx_mcs_set = ath10k_peer_assoc_h_vht_limit( __le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map), vht_mcs_mask); - - ath10k_dbg(ar, ATH10K_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_vht_rates.rx_max_rate && - (sta->vht_cap.cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK)) { - switch (arg->peer_vht_rates.rx_max_rate) { - case 1560: - /* Must be 2x2 at 160Mhz is all it can do. */ - arg->peer_bw_rxnss_override = 2; - break; - case 780: - /* Can only do 1x1 at 160Mhz (Long Guard Interval) */ - arg->peer_bw_rxnss_override = 1; - break; - } + arg->peer_bw_rxnss_override = 0; + nss160 = 1; /* 1x1 default config for VHT160 */ + + /* only 4x4 configuration do support 2x2 for VHT160, everything else must use 1x1 */ + if (ar->cfg_rx_chainmask == 15) + nss160 = arg->peer_num_spatial_streams <= 2 ? arg->peer_num_spatial_streams : 2; + + /* in case if peer is connected with vht160 or vht80+80, we need to properly adjust rxnss parameters otherwise firmware will raise a assert */ + switch(arg->peer_phymode) { + case MODE_11AC_VHT80_80: + arg->peer_bw_rxnss_override = BW_NSS_FWCONF_80_80(nss160); + /* fall through */ + case MODE_11AC_VHT160: + arg->peer_bw_rxnss_override |= BW_NSS_FWCONF_160(nss160); + break; + default: + break; } + + ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vht peer %pM max_mpdu %d flags 0x%x peer_bw_rxnss_override 0x%x\n", + sta->addr, arg->peer_max_mpdu, arg->peer_flags, arg->peer_bw_rxnss_override); } static void ath10k_peer_assoc_h_qos(struct ath10k *ar, @@ -2696,9 +2700,9 @@ static int ath10k_peer_assoc_prepare(struct ath10k *ar, ath10k_peer_assoc_h_crypto(ar, vif, sta, arg); ath10k_peer_assoc_h_rates(ar, vif, sta, arg); ath10k_peer_assoc_h_ht(ar, vif, sta, arg); + ath10k_peer_assoc_h_phymode(ar, vif, sta, arg); ath10k_peer_assoc_h_vht(ar, vif, sta, arg); ath10k_peer_assoc_h_qos(ar, vif, sta, arg); - ath10k_peer_assoc_h_phymode(ar, vif, sta, arg); return 0; } diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index 2c36256a441d..3797dca317ff 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -7211,12 +7211,7 @@ ath10k_wmi_peer_assoc_fill_10_4(struct ath10k *ar, void *buf, struct wmi_10_4_peer_assoc_complete_cmd *cmd = buf; ath10k_wmi_peer_assoc_fill_10_2(ar, buf, arg); - if (arg->peer_bw_rxnss_override) - cmd->peer_bw_rxnss_override = - __cpu_to_le32((arg->peer_bw_rxnss_override - 1) | - BIT(PEER_BW_RXNSS_OVERRIDE_OFFSET)); - else - cmd->peer_bw_rxnss_override = 0; + cmd->peer_bw_rxnss_override = __cpu_to_le32(arg->peer_bw_rxnss_override); } static int diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h index 46ae19bb2c92..1fe0aa5523a6 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.h +++ b/drivers/net/wireless/ath/ath10k/wmi.h @@ -6380,7 +6380,19 @@ struct wmi_10_2_peer_assoc_complete_cmd { __le32 info0; /* WMI_PEER_ASSOC_INFO0_ */ } __packed; -#define PEER_BW_RXNSS_OVERRIDE_OFFSET 31 +#define BW_NSS_FWCONF_MAP_ENABLE (1 << 31) +#define BW_NSS_FWCONF_MAP_160MHZ_S (0) +#define BW_NSS_FWCONF_MAP_160MHZ_M (0x00000007) +#define BW_NSS_FWCONF_MAP_80_80MHZ_S (3) +#define BW_NSS_FWCONF_MAP_80_80MHZ_M (0x00000038) +#define BW_NSS_FWCONF_MAP_M (0x0000003F) + +#define GET_BW_NSS_FWCONF_160(x) ((((x) & BW_NSS_FWCONF_MAP_160MHZ_M) >> BW_NSS_FWCONF_MAP_160MHZ_S) + 1) +#define GET_BW_NSS_FWCONF_80_80(x) ((((x) & BW_NSS_FWCONF_MAP_80_80MHZ_M) >> BW_NSS_FWCONF_MAP_80_80MHZ_S) + 1) + +/* Values defined to set 160 MHz Bandwidth NSS Mapping into FW*/ +#define BW_NSS_FWCONF_160(x) (BW_NSS_FWCONF_MAP_ENABLE | (((x - 1) << BW_NSS_FWCONF_MAP_160MHZ_S) & BW_NSS_FWCONF_MAP_160MHZ_M)) +#define BW_NSS_FWCONF_80_80(x) (BW_NSS_FWCONF_MAP_ENABLE | (((x - 1) << BW_NSS_FWCONF_MAP_80_80MHZ_S) & BW_NSS_FWCONF_MAP_80_80MHZ_M)) struct wmi_10_4_peer_assoc_complete_cmd { struct wmi_10_2_peer_assoc_complete_cmd cmd;