Received: by 2002:ad5:4acb:0:0:0:0:0 with SMTP id n11csp3837321imw; Mon, 18 Jul 2022 15:41:04 -0700 (PDT) X-Google-Smtp-Source: AGRyM1sdyqqf5k37BN+zUEpKFJ59Qj0Dn5QLyvOZbCD6Kr2ihQZat7baPFAE4hhlqH2blxweu67k X-Received: by 2002:a17:906:974d:b0:72f:2835:f664 with SMTP id o13-20020a170906974d00b0072f2835f664mr8264819ejy.543.1658184063860; Mon, 18 Jul 2022 15:41:03 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1658184063; cv=none; d=google.com; s=arc-20160816; b=zJVw2aKoy84USQyYuOQFehbMrnK0o3HzEZ5uccNYNZQXv7rT8ylZrMfk8inlT/EqBR qv0TMDgTMGAMWhB1Ec3TSR6mcuyYdC/ZVc055ZXgvkPa7uFIqSsvPR3Vb2iGv6bSgDmY iXLAWcV/UBD6D8eWlKsfEA/Nuy4+JjCeaBJOLRQKTwFlFmiY1LXYZnKaETaICQQiDlg6 VYyLTX/kY5Wpnz1Jjo6EnFT7zHB8y0z+5I32ppUbyS9SwiP6Ne4mgnpDILZi3p3ilshl 88h2zZM/Bb0j0HQczfnIjv6FW/6MskzBCIoM7+cNUGUTO0z8vhAqg+Dxevm6s2fDNcMd OFKg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from; bh=cXgnNHUg9lt1npQxL1e6diZLsfGDj46nhYd9betwNas=; b=R2S+1mu3WU/3IA3/mevuMSN597/Rk3QGXVhfsRYTMc6xmVovyXAEezyA6FRO0Y02ep vSSQPhM5rEdRIUPUL5fOrV2vzn8evC0SaOgqmsn4Lzqu2+sL5w/CGZ7ZtVHrbU7dcizZ yQINAmhF9HsZBcKctUmSYLZeqmmv+ClLd5uXarsC1UIzoj++RaeunKeOn0H4tfDFWTvl 6ll80av9fTJuxnTzeeSh+3lCYa+DhomMWOnm+dFU9W24G84cntWP7rg/gQLNrJhO9FMH CqQkOPcyfp5nZ03297AtooNUl+dO0Tkc1OC4QbU5Vmkc6KwVDRC+tSUNNgK+BlQ9a7zK 94iw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-wireless-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-wireless-owner@vger.kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id bq17-20020a170906d0d100b0072ab5d0fc33si12422781ejb.863.2022.07.18.15.40.42; Mon, 18 Jul 2022 15:41:03 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-wireless-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-wireless-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-wireless-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234332AbiGRWg2 (ORCPT + 65 others); Mon, 18 Jul 2022 18:36:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40134 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230263AbiGRWg2 (ORCPT ); Mon, 18 Jul 2022 18:36:28 -0400 X-Greylist: delayed 474 seconds by postgrey-1.37 at lindbergh.monkeyblade.net; Mon, 18 Jul 2022 15:36:26 PDT Received: from mail.aperture-lab.de (mail.aperture-lab.de [116.203.183.178]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D3D0E22BED; Mon, 18 Jul 2022 15:36:26 -0700 (PDT) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 2ADCC3EEC0; Tue, 19 Jul 2022 00:28:19 +0200 (CEST) From: =?UTF-8?q?Linus=20L=C3=BCssing?= To: Johannes Berg Cc: "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= , Kalle Valo , Felix Fietkau , Simon Wunderlich , Sven Eckelmann , =?UTF-8?q?Linus=20L=C3=BCssing?= , ath10k@lists.infradead.org, linux-wireless@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, =?UTF-8?q?Linus=20L=C3=BCssing?= Subject: [PATCH] mac80211: Fix wrong channel bandwidths reported for aggregates Date: Tue, 19 Jul 2022 00:28:04 +0200 Message-Id: <20220718222804.21708-1-linus.luessing@c0d3.blue> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Last-TLS-Session-Version: TLSv1.3 X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_MED, SPF_HELO_NONE,SPF_NONE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Linus Lüssing AR9003 based wifi chips have a hardware bug, they always report a channel bandwidth of HT40 for any sub-frame of an aggregate which is not the last one. Only the last sub-frame has correct channel bandwidth information. This can be easily reproduced by setting an ath9k based wifi to HT20 and running an iperf test. Then "iw dev wlan0 station dump" will occasionally, wrongly show something like: rx bitrate: 121.5 MBit/s MCS 6 40MHz Debug output in ath9k_hw_process_rxdesc_edma() confirmed that it is always frames with (rxs->rs_isaggr && !rxs->rs_moreaggr) and no others which report RATE_INFO_BW_40. Unfortunately we cannot easily fix this within ath9k as in ath9k we cannot peek at the rate/bandwidth info of the last aggregate sub-frame and there is no queueing within ath9k after receiving the frame from the wifi chip, it is directly handed over to mac80211. Therefore fixing this within mac80211: For an aggergated AMPDU only update the RX "last_rate" variable from the last sub-frame of an aggregate. In theory, without hardware bugs, rate/bandwidth info should be the same for all sub-frames of an aggregate anyway. This change only affects ath9k, ath9k-htc and ath10k as these are currently the only drivers implementing the RX_FLAG_AMPDU_LAST_KNOWN flag. Tested-on: 8devices Lima board, QCA9531 WiFi Cc: Sven Eckelmann Cc: Simon Wunderlich Cc: Linus Lüssing Signed-off-by: Linus Lüssing --- net/mac80211/rx.c | 8 ++++---- net/mac80211/sta_info.h | 16 +++++++++++++--- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 304b9909f025..988dbf058489 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -1723,6 +1723,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) struct sk_buff *skb = rx->skb; struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + u32 *last_rate = &sta->deflink.rx_stats.last_rate; int i; if (!sta) @@ -1744,8 +1745,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) sta->deflink.rx_stats.last_rx = jiffies; if (ieee80211_is_data(hdr->frame_control) && !is_multicast_ether_addr(hdr->addr1)) - sta->deflink.rx_stats.last_rate = - sta_stats_encode_rate(status); + sta_stats_encode_rate(status, last_rate); } } else if (rx->sdata->vif.type == NL80211_IFTYPE_OCB) { sta->deflink.rx_stats.last_rx = jiffies; @@ -1757,7 +1757,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) */ sta->deflink.rx_stats.last_rx = jiffies; if (ieee80211_is_data(hdr->frame_control)) - sta->deflink.rx_stats.last_rate = sta_stats_encode_rate(status); + sta_stats_encode_rate(status, last_rate); } sta->deflink.rx_stats.fragments++; @@ -4502,7 +4502,7 @@ static void ieee80211_rx_8023(struct ieee80211_rx_data *rx, /* end of statistics */ stats->last_rx = jiffies; - stats->last_rate = sta_stats_encode_rate(status); + sta_stats_encode_rate(status, &stats->last_rate); stats->fragments++; stats->packets++; diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 70ee55ec5518..67f9c1647567 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -941,10 +941,19 @@ enum sta_stats_type { #define STA_STATS_RATE_INVALID 0 -static inline u32 sta_stats_encode_rate(struct ieee80211_rx_status *s) +static inline void +sta_stats_encode_rate(struct ieee80211_rx_status *s, u32 *rate) { u32 r; + /* some drivers (notably ath9k) only report a valid bandwidth + * in the last subframe of an aggregate, skip the others + * in that case + */ + if (s->flag & RX_FLAG_AMPDU_LAST_KNOWN && + !(s->flag & RX_FLAG_AMPDU_IS_LAST)) + return; + r = STA_STATS_FIELD(BW, s->bw); if (s->enc_flags & RX_ENC_FLAG_SHORT_GI) @@ -975,10 +984,11 @@ static inline u32 sta_stats_encode_rate(struct ieee80211_rx_status *s) break; default: WARN_ON(1); - return STA_STATS_RATE_INVALID; + *rate = STA_STATS_RATE_INVALID; + return; } - return r; + *rate = r; } #endif /* STA_INFO_H */ -- 2.36.1