From patchwork Mon Oct 18 11:48:25 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Loic Poulain X-Patchwork-Id: 515910 Delivered-To: patch@linaro.org Received: by 2002:ac0:cd8c:0:0:0:0:0 with SMTP id d12csp1670744imp; Mon, 18 Oct 2021 04:37:16 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzyLbzRbMxv46khAbx81WMYItdjSRGbPS1z1STPnfsvCNJ44z7ESFkFCivfEQe6/J3dQtjH X-Received: by 2002:a92:c563:: with SMTP id b3mr13889455ilj.227.1634557036420; Mon, 18 Oct 2021 04:37:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1634557036; cv=none; d=google.com; s=arc-20160816; b=BA4sJjn7SuvfDc2cUp8wgpf4yA22aK3Q1kreepN9JJtvgPoHXXcBzCullxWuHY7jxz dWTdfEtbougz5CKaY6AgN0Jc+YDlaSr+8WG9XZ3Z6M3ZzLun8kwJ3NKhrryvDp7qSY86 rhRwpcYMBaswrZdhVCsDUMREvpwqLzg5OzchakgPUwF6f/WUZcyFJ0ngTEMU8UhHMXxS n6b4j7JT4MMQ+9O8rECsxzK5Ft5d1c58NKdcqPJ43+Tpkp4gSitwzqvoEJcEzgEOv4ap cnV2lZuud8Cz0wP9RSyDuRKGidyHfnBHCo40F/L/ssGGJjgiSHl8XJ0f37bXHsvMwhQX kIOQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:sender:content-transfer-encoding:mime-version :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:message-id:date:subject:cc:to:from :dkim-signature:dkim-signature; bh=VBIIUb3Tz/Daj2lCMAFWuta+kmaYR+KNpOL+SVlfx+8=; b=lezZvHg4KxqlNL/D5r4r5vKIRMO76s4zboE5gu+WL8qGyse7XnpPtNQiiCskVRa0JK MPlZVl6siRyvH9O7kYck/7Du+irfnDTqQy/sLdA9qFNY/gQ3jE7m4CdRv+PmAFQgdN00 F0COYs/fGchGR2C57dAMIDZAyaH5OgLrudR7SP8BU3uGr56r14ABRRyKE9Bu1A2ZDlQX 1o3X03hZnH0ipD+26JI+M0q1CqtpMB4fTAeoMHBWfvLLUuUGJpnAMtAwSmK+BEMdUO/k gkK2u6jKZ2pl/lTAG0wBFTjto64otJpTTx8G5PIPEDuv0+b8tbzCC1CCjxLVk8YpYDKs gFCg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.infradead.org header.s=bombadil.20210309 header.b=eSYIkag6; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=GUwiiueJ; spf=pass (google.com: best guess record for domain of wcn36xx-bounces+patch=linaro.org@lists.infradead.org designates 2607:7c80:54:e::133 as permitted sender) smtp.mailfrom="wcn36xx-bounces+patch=linaro.org@lists.infradead.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from bombadil.infradead.org (bombadil.infradead.org. [2607:7c80:54:e::133]) by mx.google.com with ESMTPS id u11si18438570ilv.73.2021.10.18.04.37.16 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 Oct 2021 04:37:16 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of wcn36xx-bounces+patch=linaro.org@lists.infradead.org designates 2607:7c80:54:e::133 as permitted sender) client-ip=2607:7c80:54:e::133; Authentication-Results: mx.google.com; dkim=pass header.i=@lists.infradead.org header.s=bombadil.20210309 header.b=eSYIkag6; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=GUwiiueJ; spf=pass (google.com: best guess record for domain of wcn36xx-bounces+patch=linaro.org@lists.infradead.org designates 2607:7c80:54:e::133 as permitted sender) smtp.mailfrom="wcn36xx-bounces+patch=linaro.org@lists.infradead.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:List-Subscribe:List-Help: List-Post:List-Archive:List-Unsubscribe:List-Id:Message-Id:Date:Subject:Cc: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=VBIIUb3Tz/Daj2lCMAFWuta+kmaYR+KNpOL+SVlfx+8=; b=eSYIkag6iaYetq 1q+B7Sagr2AjBsOGSkWovFmHl/AYKXmARSeddvK59Zg7OeKNTKWkRMey4umTiwc/2OCnWCiMKOTOk T9doxgb21LFjhU8fEvUoKoRYJv4WD5s5e+bWLASQs3xLPuTWU1vFv6kVj5zecjo84t58RsEDVF5pY 28ksk353DupNxnQgcGoSyMJUhkB3Xl9RU1C9y4SQ831vWgmP4vYJZTpqGJHptEfi3EwmXWNQEV9+z DxFcog3w+YN8G7cYAcepScNLDPCIBDkqTn5EAeGqTeQLJhJ46/uebZG21wZ0or1RhRexI47sRNOMV +hloZ0JweykkHtBGWc9w==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mcQx8-00FMhT-Ix; Mon, 18 Oct 2021 11:37:14 +0000 Received: from mail-wm1-x330.google.com ([2a00:1450:4864:20::330]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mcQx5-00FMfj-P6 for wcn36xx@lists.infradead.org; Mon, 18 Oct 2021 11:37:13 +0000 Received: by mail-wm1-x330.google.com with SMTP id 67-20020a1c1946000000b0030d4c90fa87so8207151wmz.2 for ; Mon, 18 Oct 2021 04:37:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=UAK4f4hejO/RUV7REAm7E11Qpe5FUY3MVwwYtDhcDDg=; b=GUwiiueJaGkc5eJRIwvqobtZsH/E1g9HL5p0p89Lm8ikOOk/w9aSP46wWly1s8LoAz ziKhcyq/mv9YNNv4nFSIQMSnMppaNtJZj+km8fsXodm/UHsvrMFtSy9rs6ptfUw2vwyT SdLXwLeU9VnhXDDkKRVUnxgcp2BeiLPlg9PvqWXW9L/7i39SCGrswtn+3gdXKcds6uj/ MnCw439QJstU1NUlQCB0733iGsbDzCQ67Uh9wMlmb6AYF8yxDpKFa/t0Eeh85uUH4/Xr lFAofJtw009k43Cg3ErhglehpMB1jUHXa9YowSBvldpu8nS43lO/Ab+ERbSCJy4rkZCO DlpQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=UAK4f4hejO/RUV7REAm7E11Qpe5FUY3MVwwYtDhcDDg=; b=h2UEYpBF79xJZlQ8u7oDgfqVF4qW6YyfUWOau2rcBTL4ncXgwM4Sn8jg90Peun6rt5 HHKfJTHFPrxxSHGhBKRcYLD/5h2QlDx7TO7OmfgXVWXhxlr2gZdJYIlI9k7ItCHNE+VX BSWp2o6xhiqh6bY+9Z37KKUv8baBNEHXznzWRc2rcWLD+wOfbLNS0bWfOEdGx80POXVb 5IhSS3vc4jw9rsRoXrT2LWa+WNhJEuWl7CMdQ/7yAOGozenoi7/Ttrm1XHQET3VQ945t /TwewA8/PhLWySfoIfdIVhwN3wILHNXaYcRDiWTTECIM45vo+OCNXx+iajuXcVfCaA5B KN9A== X-Gm-Message-State: AOAM533kVTz0lfurajnw0EwttKkwZxeLgjRL76S40grLdCvdpwD3P7KD BS2P03rr0gR9/Wif94dvYCWU9qhuINuRqQ== X-Received: by 2002:a1c:a558:: with SMTP id o85mr30218959wme.110.1634557030310; Mon, 18 Oct 2021 04:37:10 -0700 (PDT) Received: from localhost.localdomain ([2a01:e0a:82c:5f0:9df5:c752:530b:345b]) by smtp.gmail.com with ESMTPSA id r9sm11957609wrn.95.2021.10.18.04.37.09 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 18 Oct 2021 04:37:09 -0700 (PDT) From: Loic Poulain To: kvalo@codeaurora.org Cc: wcn36xx@lists.infradead.org, linux-wireless@vger.kernel.org, bryan.odonoghue@linaro.org, Loic Poulain Subject: [PATCH] wcn36xx: Add chained transfer support for AMSDU Date: Mon, 18 Oct 2021 13:48:25 +0200 Message-Id: <1634557705-11120-1-git-send-email-loic.poulain@linaro.org> X-Mailer: git-send-email 2.7.4 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211018_043711_852776_F2F795EF X-CRM114-Status: GOOD ( 24.03 ) X-Spam-Score: -0.2 (/) X-Spam-Report: Spam detection software, running on the system "bombadil.infradead.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: WCNSS RX DMA transfer support is limited to 3872 bytes, which is enough for simple MPDUs (single MSDU), but not enough for cases with A-MSDU (depending on max AMSDU size or max MPDU size). In that case the MPDU is spread ove multiple transfers, with the first transfer containing the MPDU header and (at least) the first A-MSDU subframe and additional transfer(s) containing the following [...] Content analysis details: (-0.2 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [2a00:1450:4864:20:0:0:0:330 listed in] [list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain X-BeenThere: wcn36xx@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "wcn36xx" Errors-To: wcn36xx-bounces+patch=linaro.org@lists.infradead.org WCNSS RX DMA transfer support is limited to 3872 bytes, which is enough for simple MPDUs (single MSDU), but not enough for cases with A-MSDU (depending on max AMSDU size or max MPDU size). In that case the MPDU is spread ove multiple transfers, with the first transfer containing the MPDU header and (at least) the first A-MSDU subframe and additional transfer(s) containing the following A-MSDUs. This can be handled with a series of flags to tagging the first and last A-MSDU transfers. In that case we have to bufferize and re-linearize the A-MSDU buffers into a proper MPDU skb before forwarding to mac80211 (in the same way as it is done in ath10k). This change also includes sanity check of the buffer descriptor to prevent skb overflow. Signed-off-by: Loic Poulain --- drivers/net/wireless/ath/wcn36xx/main.c | 3 ++ drivers/net/wireless/ath/wcn36xx/smd.c | 3 +- drivers/net/wireless/ath/wcn36xx/txrx.c | 83 ++++++++++++++++++++++++++++++ drivers/net/wireless/ath/wcn36xx/wcn36xx.h | 4 +- 4 files changed, 91 insertions(+), 2 deletions(-) -- 2.7.4 _______________________________________________ wcn36xx mailing list wcn36xx@lists.infradead.org http://lists.infradead.org/mailman/listinfo/wcn36xx diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c index b5aa20e..96bd99a 100644 --- a/drivers/net/wireless/ath/wcn36xx/main.c +++ b/drivers/net/wireless/ath/wcn36xx/main.c @@ -1501,6 +1501,7 @@ static int wcn36xx_probe(struct platform_device *pdev) mutex_init(&wcn->conf_mutex); mutex_init(&wcn->hal_mutex); mutex_init(&wcn->scan_lock); + __skb_queue_head_init(&wcn->amsdu); wcn->hal_buf = devm_kmalloc(wcn->dev, WCN36XX_HAL_BUF_SIZE, GFP_KERNEL); if (!wcn->hal_buf) { @@ -1578,6 +1579,8 @@ static int wcn36xx_remove(struct platform_device *pdev) iounmap(wcn->dxe_base); iounmap(wcn->ccu_base); + __skb_queue_purge(&wcn->amsdu); + mutex_destroy(&wcn->hal_mutex); ieee80211_free_hw(hw); diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c index 3979171..3cecc8f 100644 --- a/drivers/net/wireless/ath/wcn36xx/smd.c +++ b/drivers/net/wireless/ath/wcn36xx/smd.c @@ -266,7 +266,8 @@ static void wcn36xx_smd_set_sta_ht_params(struct ieee80211_sta *sta, sta_params->max_ampdu_size = sta->ht_cap.ampdu_factor; sta_params->max_ampdu_density = sta->ht_cap.ampdu_density; - sta_params->max_amsdu_size = is_cap_supported(caps, + /* max_amsdu_size: 1 : 3839 bytes, 0 : 7935 bytes (max) */ + sta_params->max_amsdu_size = !is_cap_supported(caps, IEEE80211_HT_CAP_MAX_AMSDU); sta_params->sgi_20Mhz = is_cap_supported(caps, IEEE80211_HT_CAP_SGI_20); diff --git a/drivers/net/wireless/ath/wcn36xx/txrx.c b/drivers/net/wireless/ath/wcn36xx/txrx.c index a3ef497..1edc703 100644 --- a/drivers/net/wireless/ath/wcn36xx/txrx.c +++ b/drivers/net/wireless/ath/wcn36xx/txrx.c @@ -231,6 +231,41 @@ static const struct wcn36xx_rate wcn36xx_rate_table[] = { { 4333, 9, RX_ENC_VHT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_80 }, }; +static struct sk_buff *wcn36xx_unchain_msdu(struct sk_buff_head *amsdu) +{ + struct sk_buff *skb, *first; + int total_len = 0; + int space; + + first = __skb_dequeue(amsdu); + + skb_queue_walk(amsdu, skb) + total_len += skb->len; + + space = total_len - skb_tailroom(first); + if (space > 0 && pskb_expand_head(first, 0, space, GFP_ATOMIC) < 0) { + __skb_queue_head(amsdu, first); + return NULL; + } + + /* Walk list again, copying contents into msdu_head */ + while ((skb = __skb_dequeue(amsdu))) { + skb_copy_from_linear_data(skb, skb_put(first, skb->len), + skb->len); + dev_kfree_skb_irq(skb); + } + + return first; +} + +static void __skb_queue_purge_irq(struct sk_buff_head *list) +{ + struct sk_buff *skb; + + while ((skb = __skb_dequeue(list)) != NULL) + dev_kfree_skb_irq(skb); +} + int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb) { struct ieee80211_rx_status status; @@ -252,6 +287,26 @@ int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb) "BD <<< ", (char *)bd, sizeof(struct wcn36xx_rx_bd)); + if (bd->pdu.mpdu_data_off <= bd->pdu.mpdu_header_off || + bd->pdu.mpdu_len < bd->pdu.mpdu_header_len) + goto drop; + + if (bd->asf && !bd->esf) { /* chained A-MSDU chunks */ + /* Sanity check */ + if (bd->pdu.mpdu_data_off + bd->pdu.mpdu_len > WCN36XX_PKT_SIZE) + goto drop; + + skb_put(skb, bd->pdu.mpdu_data_off + bd->pdu.mpdu_len); + skb_pull(skb, bd->pdu.mpdu_data_off); + + /* Only set status for first chained BD (with mac header) */ + goto done; + } + + if (bd->pdu.mpdu_header_off < sizeof(*bd) || + bd->pdu.mpdu_header_off + bd->pdu.mpdu_len > WCN36XX_PKT_SIZE) + goto drop; + skb_put(skb, bd->pdu.mpdu_header_off + bd->pdu.mpdu_len); skb_pull(skb, bd->pdu.mpdu_header_off); @@ -328,9 +383,37 @@ int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb) (char *)skb->data, skb->len); } +done: + /* Chained AMSDU ? slow path */ + if (unlikely(bd->asf && !(bd->lsf && bd->esf))) { + if (bd->esf && !skb_queue_empty(&wcn->amsdu)) { + wcn36xx_err("Discarding non complete chain"); + __skb_queue_purge_irq(&wcn->amsdu); + } + + __skb_queue_tail(&wcn->amsdu, skb); + + if (!bd->lsf) + return 0; /* Not the last AMSDU, wait for more */ + + skb = wcn36xx_unchain_msdu(&wcn->amsdu); + if (!skb) + goto drop; + } + ieee80211_rx_irqsafe(wcn->hw, skb); return 0; + +drop: /* drop everything */ + wcn36xx_err("Drop frame! skb:%p len:%u hoff:%u doff:%u asf=%u esf=%u lsf=%u\n", + skb, bd->pdu.mpdu_len, bd->pdu.mpdu_header_off, + bd->pdu.mpdu_data_off, bd->asf, bd->esf, bd->lsf); + + dev_kfree_skb_irq(skb); + __skb_queue_purge_irq(&wcn->amsdu); + + return -EINVAL; } static void wcn36xx_set_tx_pdu(struct wcn36xx_tx_bd *bd, diff --git a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h index add6e52..ae63bc6 100644 --- a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h +++ b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h @@ -269,6 +269,9 @@ struct wcn36xx { struct sk_buff *tx_ack_skb; struct timer_list tx_ack_timer; + /* For A-MSDU re-aggregation */ + struct sk_buff_head amsdu; + /* RF module */ unsigned rf_id; @@ -276,7 +279,6 @@ struct wcn36xx { /* Debug file system entry */ struct wcn36xx_dfs_entry dfs; #endif /* CONFIG_WCN36XX_DEBUGFS */ - }; static inline bool wcn36xx_is_fw_version(struct wcn36xx *wcn,