From patchwork Fri Aug 27 17:06:32 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chad Monroe X-Patchwork-Id: 12462457 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.5 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7C25DC432BE for ; Fri, 27 Aug 2021 17:07:02 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id F352360FD9 for ; Fri, 27 Aug 2021 17:07:01 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org F352360FD9 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=monroe.io Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.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:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: 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: List-Owner; bh=ldxii74w867UMZjZWHeIibjyoqr0LemEJzj3/nCkMX4=; b=4ZnkPj85sAkjYk 74AtEMMczjv6E7L9HWg0SQ66VnfHrTbNigJUVxe1Gwoi92d/3AKdC541uQZAOrTegvgOH6ZYUDBjH h2jdBaeXZ5Voxpl1wd0gkGiJWjL49DpM6Usa70MbpwesajB/ZFEtBQFW/C2UGzNVicvx+q0paqSIg AmonGrf55QE6nYWmzhJJYumQJIPfBYkh/5NufFRUk1mlyP3DIjdK6k/rUagTLSi/HqfFQ5U+qZIMs oQPREHluxDOJul9tWaa1xlSwuAWtvFv3+4lVQRYu3tL1IRHkY9U49VjK/+hohkGEmgXsFA6Rg8uxl BlOKemr33rG5s9SU2SVA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mJfJa-00Covv-Hp; Fri, 27 Aug 2021 17:06:50 +0000 Received: from mail-pl1-x635.google.com ([2607:f8b0:4864:20::635]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mJfJW-00Couw-Qk for linux-mediatek@lists.infradead.org; Fri, 27 Aug 2021 17:06:48 +0000 Received: by mail-pl1-x635.google.com with SMTP id d17so4310010plr.12 for ; Fri, 27 Aug 2021 10:06:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=monroe-io.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=mNFw7xoNmzK6n+hoew3r+jmAx5ozOzvIkhn9LjQvX+U=; b=go6ybA/RROR1WvT6aJrLOSMZpBnNm1UtgOxxqdgS6r6CUnDf5OTaLfSao660V2yDdP tqfOt9N7TFggaVqTGE+8TlVwpAnkvnKZ8mYzjrUqE6dJtvvpxoJBsLus6Wc6w792pg/h St4rOzt3RKU9ZZVySjPxX7NChqZ72Yb0nQO/w5b017ijb6sqk/LQpz/awu5odL4bmZKo mnz/fF+n6pRXC8gJqizPDRz3fCDExUKDODAHSPwYTziNq//OEM5hroYT7Dk3/V61SYU6 g2+iE5ysQCPwwQyELFSfCMLETu1HYtqvNXqfOML/cEi027opHeagsr3hfP9khHzvd+MX VTdg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=mNFw7xoNmzK6n+hoew3r+jmAx5ozOzvIkhn9LjQvX+U=; b=b3rVWzfvsrnaVjVPnBitTgjCdOUKpUlf58Nv+1EFgGmB17XoS2mLW69uQ9Aw5vslmj iXjAeawMYyG01+h7YXNiJBed+CyBKWUknr3RRl77VkGc/76dfzB1WqOF30oVbZoGWNUZ /X6rNj/82inJcPzFGSnlweoYhlj1xvXoViJCM6ZUqPI/lU/PRtwGKHohi0Z+WaEJ5dWt JoQgH1gXiG9GGUNZL7vXO4XZxcL7mnoijl20r/Wu0ZiaVu3KHEgha1ui/TgrbPo2HHf4 gKhJEM7SVZvSIPfB0+zQJXq8ZdZT4Si92Z9H4Hr8hWXrNBdl0TvKmppiCw7pRbYUJpUi wUEg== X-Gm-Message-State: AOAM530h4W6JX1ImtiqvI6stX4/pZf+uYUCTcSOGGdEO4YMMiY6LrS5H LhdzyUU9Yxyd3QdxkkMIiNTDMQ== X-Google-Smtp-Source: ABdhPJym4dbKHsj8jDZ8SlEdw3TVmEuvZeGu/MZVsczAqbPDCZdHsJgcWGg/Rar+GMIdfj/FW2z9mw== X-Received: by 2002:a17:90a:e511:: with SMTP id t17mr11740185pjy.172.1630084006146; Fri, 27 Aug 2021 10:06:46 -0700 (PDT) Received: from bfg9000.smartrg.link (wsip-98-173-202-84.sb.sd.cox.net. [98.173.202.84]) by smtp.googlemail.com with ESMTPSA id s32sm6546670pfw.84.2021.08.27.10.06.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 27 Aug 2021 10:06:45 -0700 (PDT) From: Chad Monroe To: Felix Fietkau , Johannes Berg Cc: Lorenzo Bianconi , Shayne Chen , Evelyn Tsai , Ryder Lee , linux-wireless@vger.kernel.org, linux-mediatek@lists.infradead.org, Chad Monroe , Ben Greear Subject: [PATCH 2/2] mt76: mt7615: fix radar detector logic Date: Fri, 27 Aug 2021 10:06:32 -0700 Message-Id: <4a4bb98aa6dd1c7f4671d11a901fb8cf35f49308.1630081048.git.chad@monroe.io> X-Mailer: git-send-email 2.20.1 In-Reply-To: <54c9a89210608d2a9b9adf37a8c2a743275e5723.1630081048.git.chad@monroe.io> References: <54c9a89210608d2a9b9adf37a8c2a743275e5723.1630081048.git.chad@monroe.io> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210827_100646_917850_135A3B3F X-CRM114-Status: GOOD ( 25.14 ) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org Before this patch, if AP went from ch 100 to ch 36, the radar detector logic in the firmware was not being disabled. This made the AP appear to be up, but no beacons were seen on air until module reload or reboot. To reproduce this, I change hostapd.conf and restart hostapd. Others on openwrt used their UI to make changes and problem was seen, but stil others changed channels in some other way and/or had some other difference and could *not* reproduce it. So, something perhaps a bit subtle. To fix the problem, stop depending on comparing dfs_state, store last freq/bandwidth to detect changes in that, and streamline code that checks to enable/disable radar detection. And add in error checking and dev_dbg logic so one can see what is actually happening if need to debug this again. Signed-off-by: Ben Greear Signed-off-by: Chad Monroe --- .../net/wireless/mediatek/mt76/mt7615/init.c | 12 ++- .../net/wireless/mediatek/mt76/mt7615/mac.c | 102 ++++++++++++------ .../net/wireless/mediatek/mt76/mt7615/main.c | 25 ++++- .../wireless/mediatek/mt76/mt7615/mt7615.h | 6 +- 4 files changed, 104 insertions(+), 41 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/init.c b/drivers/net/wireless/mediatek/mt76/mt7615/init.c index 05235a60d413..23dde13c2703 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/init.c @@ -333,6 +333,7 @@ mt7615_regd_notifier(struct wiphy *wiphy, struct mt76_phy *mphy = hw->priv; struct mt7615_phy *phy = mphy->priv; struct cfg80211_chan_def *chandef = &mphy->chandef; + int ret; memcpy(dev->mt76.alpha2, request->alpha2, sizeof(dev->mt76.alpha2)); dev->mt76.region = request->dfs_region; @@ -342,14 +343,18 @@ mt7615_regd_notifier(struct wiphy *wiphy, mt7615_mutex_acquire(dev); - if (chandef->chan->flags & IEEE80211_CHAN_RADAR) - mt7615_dfs_init_radar_detector(phy); - if (mt7615_firmware_offload(phy->dev)) { mt76_connac_mcu_set_channel_domain(mphy); mt76_connac_mcu_set_rate_txpower(mphy); } + if (chandef->chan->flags & IEEE80211_CHAN_RADAR) { + ret = mt7615_dfs_init_radar_detector(phy); + if (ret < 0) + dev_err(dev->mt76.dev, "init-wifi: dfs-init-radar-detector failed: %d", + ret); + } + mt7615_mutex_release(dev); } @@ -550,7 +555,6 @@ void mt7615_init_device(struct mt7615_dev *dev) dev->pm.stats.last_wake_event = jiffies; dev->pm.stats.last_doze_event = jiffies; mt7615_cap_dbdc_disable(dev); - dev->phy.dfs_state = -1; #ifdef CONFIG_NL80211_TESTMODE dev->mt76.test_ops = &mt7615_testmode_ops; diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c index 78b55e872da0..571fa73baa76 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c @@ -2101,14 +2101,29 @@ void mt7615_tx_token_put(struct mt7615_dev *dev) } EXPORT_SYMBOL_GPL(mt7615_tx_token_put); -static void mt7615_dfs_stop_radar_detector(struct mt7615_phy *phy) +int mt7615_dfs_stop_radar_detector(struct mt7615_phy *phy, bool ext_phy) { struct mt7615_dev *dev = phy->dev; + int err; + + dev_dbg(dev->mt76.dev, "dfs-stop-radar-detector, rdd-state: 0x%x", + phy->rdd_state); + + err = mt7615_mcu_rdd_cmd(dev, RDD_NORMAL_START, ext_phy, + MT_RX_SEL0, 0); + if (err < 0) { + dev_err(dev->mt76.dev, "mcu-rdd-cmd RDD_NORMAL_START failed: %d", + err); + /* I think best to carry on, even if we have an error here. */ + } if (phy->rdd_state & BIT(0)) mt7615_mcu_rdd_cmd(dev, RDD_STOP, 0, MT_RX_SEL0, 0); if (phy->rdd_state & BIT(1)) mt7615_mcu_rdd_cmd(dev, RDD_STOP, 1, MT_RX_SEL0, 0); + phy->rdd_state = 0; + + return err; } static int mt7615_dfs_start_rdd(struct mt7615_dev *dev, int chain) @@ -2116,11 +2131,14 @@ static int mt7615_dfs_start_rdd(struct mt7615_dev *dev, int chain) int err; err = mt7615_mcu_rdd_cmd(dev, RDD_START, chain, MT_RX_SEL0, 0); + + dev_dbg(dev->mt76.dev, "dfs-start-rdd, RDD_START rv: %d", err); if (err < 0) return err; - return mt7615_mcu_rdd_cmd(dev, RDD_DET_MODE, chain, - MT_RX_SEL0, 1); + err = mt7615_mcu_rdd_cmd(dev, RDD_DET_MODE, chain, MT_RX_SEL0, 1); + dev_dbg(dev->mt76.dev, "dfs-start-rdd, RDD_DET_MODE rv: %d", err); + return err; } static int mt7615_dfs_start_radar_detector(struct mt7615_phy *phy) @@ -2227,48 +2245,70 @@ int mt7615_dfs_init_radar_detector(struct mt7615_phy *phy) if (is_mt7663(&dev->mt76)) return 0; - if (dev->mt76.region == NL80211_DFS_UNSET) { - phy->dfs_state = -1; - if (phy->rdd_state) - goto stop; + dev_dbg(dev->mt76.dev, + "dfs-init-radar-detector, region: %d freq: %d chandef dfs-state: %d", + dev->mt76.region, chandef->chan->center_freq, + chandef->chan->dfs_state); + if (test_bit(MT76_SCANNING, &phy->mt76->state)) { + dev_dbg(dev->mt76.dev, "init-radar, was scanning, no change.\n"); return 0; } - if (test_bit(MT76_SCANNING, &phy->mt76->state)) - return 0; + if (dev->mt76.region == NL80211_DFS_UNSET) { + dev_dbg(dev->mt76.dev, + "dfs-init-radar, region is UNSET, disable radar."); + goto stop; + } + + if (!(chandef->chan->flags & IEEE80211_CHAN_RADAR)) { + dev_dbg(dev->mt76.dev, + "dfs-init-radar, chandef does not want radar."); + goto stop; + } + + ieee80211_iterate_active_interfaces(phy->mt76->hw, + IEEE80211_IFACE_ITER_RESUME_ALL, + mt7615_vif_counts, &counts); + + if (!(counts.ap + counts.adhoc + counts.mesh)) { + /* No beaconning interfaces, do not start CAC */ + dev_dbg(dev->mt76.dev, + "dfs-init-radar, no AP/Mesh/Adhoc vifs active, stop radar."); + goto stop; + } - if (phy->dfs_state == chandef->chan->dfs_state) + /* At this point, we need radar detection, see if we have started + * it already. + */ + if (phy->rdd_state) { + if (chandef->chan->dfs_state == NL80211_DFS_AVAILABLE) { + /* CAC is already complete. */ + dev_dbg(dev->mt76.dev, + "init-radar, RADAR started and DFS state is AVAILABLE, call RDD_CAC_END"); + return mt7615_mcu_rdd_cmd(dev, RDD_CAC_END, ext_phy, + MT_RX_SEL0, 0); + } + dev_dbg(dev->mt76.dev, + "init-radar, rdd_state indicates RADAR already started," + " DFS state: %d not YET available, rdd_state: 0x%x", + chandef->chan->dfs_state, phy->rdd_state); return 0; + } err = mt7615_dfs_init_radar_specs(phy); if (err < 0) { - phy->dfs_state = -1; + dev_err(dev->mt76.dev, "dfs-init-radar-specs failed: %d", + err); goto stop; } - phy->dfs_state = chandef->chan->dfs_state; - - if (chandef->chan->flags & IEEE80211_CHAN_RADAR) { - if (chandef->chan->dfs_state != NL80211_DFS_AVAILABLE) { - ieee80211_iterate_active_interfaces(phy->mt76->hw, - IEEE80211_IFACE_ITER_RESUME_ALL, - mt7615_vif_counts, &counts); - if (counts.ap + counts.adhoc + counts.mesh) - mt7615_dfs_start_radar_detector(phy); - return 0; - } - return mt7615_mcu_rdd_cmd(dev, RDD_CAC_END, ext_phy, - MT_RX_SEL0, 0); - } + err = mt7615_dfs_start_radar_detector(phy); + dev_dbg(dev->mt76.dev, "dfs-start-radar-detector rv: %d", err); + return err; stop: - err = mt7615_mcu_rdd_cmd(dev, RDD_NORMAL_START, ext_phy, MT_RX_SEL0, 0); - if (err < 0) - return err; - - mt7615_dfs_stop_radar_detector(phy); - return 0; + return mt7615_dfs_stop_radar_detector(phy, ext_phy); } int mt7615_mac_set_beacon_filter(struct mt7615_phy *phy, diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/main.c b/drivers/net/wireless/mediatek/mt76/mt7615/main.c index 7154acf3eb9b..484c8803726f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/main.c @@ -291,6 +291,8 @@ static void mt7615_init_dfs_state(struct mt7615_phy *phy) struct mt76_phy *mphy = phy->mt76; struct ieee80211_hw *hw = mphy->hw; struct cfg80211_chan_def *chandef = &hw->conf.chandef; + struct mt7615_dev *dev = phy->dev; + bool ext_phy = phy != &dev->phy; if (hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) return; @@ -298,11 +300,23 @@ static void mt7615_init_dfs_state(struct mt7615_phy *phy) if (!(chandef->chan->flags & IEEE80211_CHAN_RADAR)) return; - if (mphy->chandef.chan->center_freq == chandef->chan->center_freq && - mphy->chandef.width == chandef->width) + if (phy->dfs_center_freq == chandef->chan->center_freq && + phy->dfs_ch_width == chandef->width) return; - phy->dfs_state = -1; + /* We are being moved to a new frequency/bw, still on DFS. Stop + * any existing DFS, then will start it again in the + * init-radar-detector logic. + */ + if (phy->rdd_state) { + dev_dbg(dev->mt76.dev, + "init-dfs-state, channel changed, old: %d:%d new: %d:%d, stopping radar.", + phy->dfs_center_freq, phy->dfs_ch_width, + chandef->chan->center_freq, chandef->width); + mt7615_dfs_stop_radar_detector(phy, ext_phy); + } + phy->dfs_center_freq = chandef->chan->center_freq; + phy->dfs_ch_width = chandef->width; } int mt7615_set_channel(struct mt7615_phy *phy) @@ -336,8 +350,11 @@ int mt7615_set_channel(struct mt7615_phy *phy) mt7615_mac_set_timing(phy); ret = mt7615_dfs_init_radar_detector(phy); - if (ret) + if (ret < 0) { + dev_err(dev->mt76.dev, "set-channel: dfs-init-radar-detector failed: %d", + ret); goto out; + } mt7615_mac_cca_stats_reset(phy); ret = mt7615_mcu_set_sku_en(phy, true); diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h b/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h index 58a98b5c0cbc..6a3209439492 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h +++ b/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h @@ -164,8 +164,9 @@ struct mt7615_phy { u8 slottime; u8 chfreq; - u8 rdd_state; - int dfs_state; + u8 rdd_state; /* radar detection started bitfield */ + enum nl80211_chan_width dfs_ch_width; + u32 dfs_center_freq; u32 rx_ampdu_ts; u32 ampdu_ref; @@ -540,6 +541,7 @@ int mt7615_mcu_set_sku_en(struct mt7615_phy *phy, bool enable); int mt7615_mcu_apply_rx_dcoc(struct mt7615_phy *phy); int mt7615_mcu_apply_tx_dpd(struct mt7615_phy *phy); int mt7615_dfs_init_radar_detector(struct mt7615_phy *phy); +int mt7615_dfs_stop_radar_detector(struct mt7615_phy *phy, bool ext_phy); int mt7615_mcu_set_roc(struct mt7615_phy *phy, struct ieee80211_vif *vif, struct ieee80211_channel *chan, int duration);