From patchwork Mon Nov 19 07:48:23 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bhagavathi Perumal S X-Patchwork-Id: 10688253 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 90D6814BD for ; Mon, 19 Nov 2018 07:50:24 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8265229690 for ; Mon, 19 Nov 2018 07:50:24 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 762CC299E2; Mon, 19 Nov 2018 07:50:24 +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=-3.6 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_LOW autolearn=unavailable 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 693B729690 for ; Mon, 19 Nov 2018 07:50:23 +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=aRnk07xgc+QeqsD0QDh5F1ZT36qnNmXK9GuZqwfOFfo=; b=uOI uIWq0LYwxLNS5pJzVNclREmbvYARFDqa06O8HDieh6o3/BvuVnJCKouA5bbY+ImD0y4Jls/z1HyW/ dLZ0PdEaxqqNzVIpIyxlyi/YaFOQMGWZK6J9ni+IcjhkPh2/W3fLx5MTVZH6lA1lhkEKCFInSDVm8 aJTJ0mrEncaJp5h6Pj+Yc6YmIFy9qYcqpdF0BCqFugZ0dDnV7bSVFfwfUmUFEADsL9HeqEuh/GGsS p3n+fJhhvq3IAuqDh32dOh4Wb5xuA524LNI2AO+9wp/VecYBaULdYyJBWyfn59ay2tne38XoS+NGq DmnZF0Wl9JxKLee5JF5QBJmZ00j9Xsw==; 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 1gOeK2-0000uG-Uw; Mon, 19 Nov 2018 07:50:18 +0000 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1gOeK0-0000uA-TD for ath10k@bombadil.infradead.org; Mon, 19 Nov 2018 07:50:17 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Message-Id:Date:Subject:Cc:To:From: Sender:Reply-To:MIME-Version:Content-Type:Content-Transfer-Encoding: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=MDTbd9kvj2dmAfOiRA9pxPvT/CWR2qhGTL4MLGaULy4=; b=ANKbk35R4inLlUitqlpszlbXq A9RJN4fz0DpQ2+0VI+pdzrU5HBEqRHmKUEkRsP70mVA4xZu3aLT8ku6DgKv7q02MYNSUH+OdYoSyO hv7PvsmpgDC6j6yoZghrlF23vqr1zDSjpGvDVY+c/Qm1Hzjag+aNEjhV4HunOLswpaBqfxSURk1s+ YOw2l/51KPrNHC+h3e03TFr4JKqEgD7lWjZz6sA95GgSOjdeKLy8jAczCZsnJiCCz7VfX6pv9LiEO Br+Zbd+EPEyUnm5jLTT+xwDw462Q39aYFKFIAxc/OdHOGWFr+wZu0l+NIo8rjzeXG7Tl9eK7GXXuK d9wCtmm0A==; Received: from smtp.codeaurora.org ([198.145.29.96]) by casper.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1gOeJx-0003yE-At for ath10k@lists.infradead.org; Mon, 19 Nov 2018 07:50:15 +0000 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 62BC6609F3; Mon, 19 Nov 2018 07:49:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1542613799; bh=oELrnCKFqAkK9S/CU6/96gYvRF0yfs6371qmYqPOoz0=; h=From:To:Cc:Subject:Date:From; b=ksGoFK/VDMPyFVyJ2zzVB38wUfc5ED0NBZPBiOcgXOE4mAneYmwqys8/gD64Bp6yI e/8J9iFXtK3QwvFbjMAAKpmR5w5yVvewwCAJ3yId+rlM7k4HFNe/Ed4QSXRypU+H/K KbSW5ETGs9XHxsA/7NKT4O5JiCXypyb1xp7bDN/8= Received: from localhost (blr-c-bdr-fw-01_globalnat_allzones-outside.qualcomm.com [103.229.19.19]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) (Authenticated sender: bperumal@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id 4FAA360452; Mon, 19 Nov 2018 07:49:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1542613798; bh=oELrnCKFqAkK9S/CU6/96gYvRF0yfs6371qmYqPOoz0=; h=From:To:Cc:Subject:Date:From; b=O7hmSYK/0pZmStlEUEApCI4owxbGoRzAAbAcknBz62ZppObiTE2LZoH5laHROx3zC kMM8nbNlH90feo5krf1kwzjemwFwoLY1T4ag5amcFe2DFNifMToluE5xr9K4sZmFdT xodoB3uL2O8Fg+aSm94MtNc5u8HUDpt8E64GikuM= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 4FAA360452 Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=bperumal@codeaurora.org From: Bhagavathi Perumal S To: ath10k@lists.infradead.org Subject: [PATCH] ath10k: Fix warning due to msdu limit error Date: Mon, 19 Nov 2018 13:18:23 +0530 Message-Id: <1542613703-9704-1-git-send-email-bperumal@codeaurora.org> X-Mailer: git-send-email 1.9.1 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181119_075013_653135_D9657827 X-CRM114-Status: GOOD ( 20.71 ) 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: linux-wireless@vger.kernel.org, Bhagavathi Perumal S MIME-Version: 1.0 Sender: "ath10k" Errors-To: ath10k-bounces+patchwork-ath10k=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Some hardwares variants(QCA99x0) are limiting msdu deaggregation with some threshold value(default limit in QCA99x0 is 64 msdus), it was introduced to avoid excessive MSDU-deaggregation in error cases. When number of sub frames exceeds the limit, target hardware will send all msdus starting from present msdu in RAW format as a single msdu packet and it will be indicated with error status bit "RX_MSDU_END_INFO0_MSDU_LIMIT_ERR" set in rx descriptor. This msdu frame is a partial raw MSDU and does't have first msdu and ieee80211 header. It caused below warning message. [ 320.151332] ------------[ cut here ]------------ [ 320.155006] WARNING: CPU: 0 PID: 3 at drivers/net/wireless/ath/ath10k/htt_rx.c:1188 In our issue case, MSDU limit error happened due to FCS error and generated this warning message. This fixes the warning by handling the MSDU limit error. If msdu limit error happens, driver adds first MSDU's ieee80211 header and sets A-MSDU present bit in QOS header so that upper layer processes this frame if it is valid or drop it if FCS error set. And removed the warning message, hence partial msdus without first msdu is expected in msdu limit error cases. Tested on QCA9984, Firmware 10.4-3.6-00104 Signed-off-by: Bhagavathi Perumal S --- drivers/net/wireless/ath/ath10k/htt_rx.c | 41 ++++++++++++++++++++++++++++--- drivers/net/wireless/ath/ath10k/hw.c | 7 ++++++ drivers/net/wireless/ath/ath10k/hw.h | 10 ++++++++ drivers/net/wireless/ath/ath10k/rx_desc.h | 7 ++++++ 4 files changed, 61 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index 984b045..a42f4d9 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -1159,7 +1159,8 @@ static void ath10k_htt_rx_h_undecap_raw(struct ath10k *ar, struct sk_buff *msdu, struct ieee80211_rx_status *status, enum htt_rx_mpdu_encrypt_type enctype, - bool is_decrypted) + bool is_decrypted, + const u8 first_hdr[64]) { struct ieee80211_hdr *hdr; struct htt_rx_desc *rxd; @@ -1167,6 +1168,9 @@ static void ath10k_htt_rx_h_undecap_raw(struct ath10k *ar, size_t crypto_len; bool is_first; bool is_last; + bool msdu_limit_err; + int bytes_aligned = ar->hw_params.decap_align_bytes; + u8 *qos; rxd = (void *)msdu->data - sizeof(*rxd); is_first = !!(rxd->msdu_end.common.info0 & @@ -1184,16 +1188,45 @@ static void ath10k_htt_rx_h_undecap_raw(struct ath10k *ar, * [FCS] <-- at end, needs to be trimmed */ + /* Some hardwares(QCA99x0 variants) limit number of msdus in a-msdu when + * deaggregate, so that unwanted MSDU-deaggregation is avoided for + * error packets. If limit exceeds, hw sends all remaining MSDUs as + * a single last MSDU with this msdu limit error set. + */ + msdu_limit_err = ath10k_rx_desc_msdu_limit_error(&ar->hw_params, rxd); + + /* If MSDU limit error happens, then don't warn on, the partial raw MSDU + * without first MSDU is expected in that case, and handled later here. + */ /* This probably shouldn't happen but warn just in case */ - if (WARN_ON_ONCE(!is_first)) + if (WARN_ON_ONCE(!is_first && !msdu_limit_err)) return; /* This probably shouldn't happen but warn just in case */ - if (WARN_ON_ONCE(!(is_first && is_last))) + if (WARN_ON_ONCE(!(is_first && is_last) && !msdu_limit_err)) return; skb_trim(msdu, msdu->len - FCS_LEN); + /* Push original 80211 header */ + if (unlikely(msdu_limit_err)) { + hdr = (struct ieee80211_hdr *)first_hdr; + hdr_len = ieee80211_hdrlen(hdr->frame_control); + crypto_len = ath10k_htt_rx_crypto_param_len(ar, enctype); + + if (ieee80211_is_data_qos(hdr->frame_control)) { + qos = ieee80211_get_qos_ctl(hdr); + qos[0] |= IEEE80211_QOS_CTL_A_MSDU_PRESENT; + } + + if (crypto_len) + memcpy(skb_push(msdu, crypto_len), + (void *)hdr + round_up(hdr_len, bytes_aligned), + crypto_len); + + memcpy(skb_push(msdu, hdr_len), hdr, hdr_len); + } + /* In most cases this will be true for sniffed frames. It makes sense * to deliver them as-is without stripping the crypto param. This is * necessary for software based decryption. @@ -1467,7 +1500,7 @@ static void ath10k_htt_rx_h_undecap(struct ath10k *ar, switch (decap) { case RX_MSDU_DECAP_RAW: ath10k_htt_rx_h_undecap_raw(ar, msdu, status, enctype, - is_decrypted); + is_decrypted, first_hdr); break; case RX_MSDU_DECAP_NATIVE_WIFI: ath10k_htt_rx_h_undecap_nwifi(ar, msdu, status, first_hdr, diff --git a/drivers/net/wireless/ath/ath10k/hw.c b/drivers/net/wireless/ath/ath10k/hw.c index af8ae81..61ecf93 100644 --- a/drivers/net/wireless/ath/ath10k/hw.c +++ b/drivers/net/wireless/ath/ath10k/hw.c @@ -1119,8 +1119,15 @@ static int ath10k_qca99x0_rx_desc_get_l3_pad_bytes(struct htt_rx_desc *rxd) RX_MSDU_END_INFO1_L3_HDR_PAD); } +static bool ath10k_qca99x0_rx_desc_msdu_limit_error(struct htt_rx_desc *rxd) +{ + return !!(rxd->msdu_end.common.info0 & + __cpu_to_le32(RX_MSDU_END_INFO0_MSDU_LIMIT_ERR)); +} + const struct ath10k_hw_ops qca99x0_ops = { .rx_desc_get_l3_pad_bytes = ath10k_qca99x0_rx_desc_get_l3_pad_bytes, + .rx_desc_get_msdu_limit_error = ath10k_qca99x0_rx_desc_msdu_limit_error, }; const struct ath10k_hw_ops qca6174_ops = { diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h index 1b5da27..e50a8dc5 100644 --- a/drivers/net/wireless/ath/ath10k/hw.h +++ b/drivers/net/wireless/ath/ath10k/hw.h @@ -624,6 +624,7 @@ struct ath10k_hw_ops { int (*rx_desc_get_l3_pad_bytes)(struct htt_rx_desc *rxd); void (*set_coverage_class)(struct ath10k *ar, s16 value); int (*enable_pll_clk)(struct ath10k *ar); + bool (*rx_desc_get_msdu_limit_error)(struct htt_rx_desc *rxd); }; extern const struct ath10k_hw_ops qca988x_ops; @@ -642,6 +643,15 @@ struct ath10k_hw_ops { return 0; } +static inline bool +ath10k_rx_desc_msdu_limit_error(struct ath10k_hw_params *hw, + struct htt_rx_desc *rxd) +{ + if (hw->hw_ops->rx_desc_get_msdu_limit_error) + return hw->hw_ops->rx_desc_get_msdu_limit_error(rxd); + return false; +} + /* Target specific defines for MAIN firmware */ #define TARGET_NUM_VDEVS 8 #define TARGET_NUM_PEER_AST 2 diff --git a/drivers/net/wireless/ath/ath10k/rx_desc.h b/drivers/net/wireless/ath/ath10k/rx_desc.h index 310674d..b626cc2 100644 --- a/drivers/net/wireless/ath/ath10k/rx_desc.h +++ b/drivers/net/wireless/ath/ath10k/rx_desc.h @@ -572,6 +572,7 @@ struct rx_msdu_start { #define RX_MSDU_END_INFO0_REPORTED_MPDU_LENGTH_LSB 0 #define RX_MSDU_END_INFO0_FIRST_MSDU BIT(14) #define RX_MSDU_END_INFO0_LAST_MSDU BIT(15) +#define RX_MSDU_END_INFO0_MSDU_LIMIT_ERR BIT(18) #define RX_MSDU_END_INFO0_PRE_DELIM_ERR BIT(30) #define RX_MSDU_END_INFO0_RESERVED_3B BIT(31) @@ -676,6 +677,12 @@ struct rx_msdu_end { * Indicates the last MSDU of the A-MSDU. MPDU end status is * only valid when last_msdu is set. * + *msdu_limit_error + * Indicates that the MSDU threshold was exceeded and thus + * all the rest of the MSDUs will not be scattered and + * will not be decapsulated but will be received in RAW format + * as a single MSDU buffer. + * *reserved_3a * Reserved: HW should fill with zero. FW should ignore. *