From patchwork Wed Oct 4 17:28:43 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?SsOpcsO0bWUgUG91aWxsZXI=?= X-Patchwork-Id: 13409101 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B11F1E7C4E2 for ; Wed, 4 Oct 2023 17:29:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243722AbjJDR3V (ORCPT ); Wed, 4 Oct 2023 13:29:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44912 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243682AbjJDR3Q (ORCPT ); Wed, 4 Oct 2023 13:29:16 -0400 Received: from NAM10-MW2-obe.outbound.protection.outlook.com (mail-mw2nam10on2082.outbound.protection.outlook.com [40.107.94.82]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1E7E1A7; Wed, 4 Oct 2023 10:29:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=GwYnkz+p9NrPsf3Em/4aKfK7x+QSgcGo0qHXJisNY4TZy4pZlRZ2+8HMUCGUVBiXd5QCUj0rtDAafScQKpNrL4fAIdE7PIpGUT7lAfHOy7drHQHtMngMTqp0LoOFoDGUrN7bD+9/O1eZYKitz6J5/GmHmxFzS/wh+wQcBum+F79X0MgU7PnxkhbvScBnxhEa5/QoE0dtCZZfvNspq7iZPHidfwXscDXw+8yrf9Cj2Sb+qJWnERd5zzS+H3DwtpEgr9wSXraFC4NpWeE+iP/vDd3K4GDwezHUupHsNT8EC78ezwWnVePUTwSiGRYTlPaY9/UYnZ+2EUF2qd185RcWJg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=mNDmDVuFCvF2iziaqZUbvbxc9ZC7LQvUPA+ZPlkd+bw=; b=ZH3GdxY6qbPaAQUglnU4WB4c4bfJxRtszcJ7iUEF62aOxXw5MeSpyB/0RGyTlWtzKF7wiDcbl8lbbt91u1izp0rxrif8FvY+ZW+BUhvktITd6n5IAEfn5CvBXKnprt7CcoSWEwuOpREZC0l1QnREkdizRjDtyiyg/vleDHm4z8lsyi51QpZEMfekj9TGsFiKLFqfzSpFsUyysK7PeTHKHXI08ql7iZMElKUwFa+ymtYPOvEZF9MyctvnUtI0NP4O+cozKsgmj0hG3gLwoiy+x4aJva7zFStGL8EqdxjqlXcwDZDsboIZ1s1wRv6j9JVDpRgPpCNGCAAwhqz2GErsVw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=silabs.com; dmarc=pass action=none header.from=silabs.com; dkim=pass header.d=silabs.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=silabs.onmicrosoft.com; s=selector2-silabs-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=mNDmDVuFCvF2iziaqZUbvbxc9ZC7LQvUPA+ZPlkd+bw=; b=O5ilAbjWxI3610J8VD682DP7oneiteiPxwUxFIKLaq8cOYk5vHIy3hDa6K6pxTAf/p3gNk7bCJ/dtOzQbwlFxN74vl76pk4X9hwN+J5mlEagJn1Pl/ZHf5avCSvzlhqGbhGfNk2OcuyDBRjKtd8SU8g1XtLtrFsUM3fjn0ONkiw= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=silabs.com; Received: from IA1PR11MB7773.namprd11.prod.outlook.com (2603:10b6:208:3f0::21) by PH7PR11MB5982.namprd11.prod.outlook.com (2603:10b6:510:1e1::20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6838.34; Wed, 4 Oct 2023 17:29:06 +0000 Received: from IA1PR11MB7773.namprd11.prod.outlook.com ([fe80::d6c8:4cb6:2594:d8f3]) by IA1PR11MB7773.namprd11.prod.outlook.com ([fe80::d6c8:4cb6:2594:d8f3%4]) with mapi id 15.20.6838.030; Wed, 4 Oct 2023 17:29:06 +0000 From: =?utf-8?b?SsOpcsO0bWUgUG91aWxsZXI=?= To: Kalle Valo Cc: linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org, =?utf-8?b?SsOpcsO0bWUgUG91aWxsZXI=?= Subject: [PATCH v3 8/8] wifi: wfx: implement wfx_remain_on_channel() Date: Wed, 4 Oct 2023 19:28:43 +0200 Message-Id: <20231004172843.195332-9-jerome.pouiller@silabs.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231004172843.195332-1-jerome.pouiller@silabs.com> References: <20231004172843.195332-1-jerome.pouiller@silabs.com> X-ClientProxiedBy: DS7PR03CA0305.namprd03.prod.outlook.com (2603:10b6:8:2b::25) To IA1PR11MB7773.namprd11.prod.outlook.com (2603:10b6:208:3f0::21) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: IA1PR11MB7773:EE_|PH7PR11MB5982:EE_ X-MS-Office365-Filtering-Correlation-Id: 55343e5e-b01e-4e13-4256-08dbc4ff68fa X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: iEiV6vlPpPoT54FJSCkdpt3L4y7wiOFtKoWZV9TeFA1hskiMF7DNt2WldhUj0gFev3kRLBgTTgWOG8lw5pcXNrG272BfBG+6O7uz0kB5ecFIlJZ0hzBX2TkXoPPtv2P3ie5mLeFx8lBK9ZAILLlge+n9ea5DOvTW9yHTa//x2PguuQeW/RRYqyJYgIt6A2kEKttbfYJ97T9ZRk3qXJ223wPd4gf89RXrMy+lhoFCDCAKHPgHWzWsjoYWtfPj9QiJeUjDTm1E9QGtRxhamcaFf3t0A7eABaKCHqjj8Wm9xDjR2PDxFkfHKH/2iQQgIYUhNzui94l1qMeqmijwQHNgk6pKyFsHZj9L0uvoSjKMa2vfeB8mitZR27O9PgfvXVKr8qv2ViVj0ZBrPj65yFHZ/AnertUKddgcLEB1rfhV8bRZPkEVU7q9ADirjJYItp/o0a1ckFuPzs0f6XhFzxGcwqzUzaiFx4M92fK9jaqUKaN11lG96IxD/yE9yW5AeLYdbGjBwXAKyjin1VKlwQYDRvpD+7Qgr/GGOqBJ9BQ+j1zxc51SVPehod/f0DrVdSMV X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:IA1PR11MB7773.namprd11.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230031)(376002)(136003)(366004)(346002)(39850400004)(396003)(230922051799003)(451199024)(186009)(64100799003)(1800799009)(6486002)(36756003)(6512007)(38100700002)(6666004)(52116002)(86362001)(478600001)(6506007)(66556008)(66946007)(66476007)(316002)(6916009)(41300700001)(2616005)(107886003)(1076003)(8936002)(4326008)(8676002)(66574015)(5660300002)(83380400001)(2906002);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?q?TTre1ejEouz5ey4XkPUQBFT+YsMT?= =?utf-8?q?uGrnMEXZkMPRWXUARuUTOlrzTOvb0QHuiKO+FjjPLWJVsF1AbL0vORGmRVHL02JMI?= =?utf-8?q?bSF4Z6JJ5vO29qGKzrGbd+QnjUuqN4ony96u8+iSoaGhfAQSsY/kEUu8Z74gt01HZ?= =?utf-8?q?Tlcxi0gWQe4hAAGJzG6czP+145/RQY3mNHNn90gXcSYLR4x7KbLl5WsHEqZs37hpn?= =?utf-8?q?M7KfKbyCEYAIEsCh5vNDKGOB5T1fhteYoEBSYCpDEWhmGno9rNyXenRzBXMeYPb8e?= =?utf-8?q?bilDjEUwQQgCxIbxHwmMTxoeD3/DJ3wwSLwnmvqkXS/gZdiIN02h6eUF9qBtzMpe9?= =?utf-8?q?If6JXo0J++mSELX7STz+nhz33cuNc4UPOcIg+gESVfqYZ0u6R/1wzlFW4ihUjxILo?= =?utf-8?q?jVr89A/taPwM2d2ZZzvLB14k2eEg8ljgxuvJPDdDEtmtXWu18PNSyJNqCO4wJPy+3?= =?utf-8?q?LCaDyxWdnxd8+wWEo+3sD5EOX63ALhTqHOPRg5D45bgRNoSNMchdryKF04we9xk4C?= =?utf-8?q?9avIIh5Z/I67rz1kcW5m0la0owo4TITySq/LJB+5MUr63pVL5rokGg9UULPb2gOnH?= =?utf-8?q?zc1eFkRamGrGmrn00u/rAQs59taNHakg6zwUeUSiB17lyJRcGIQMXuj3dSutwcXKS?= =?utf-8?q?i7hvzxKeMO+l92HDdAmgtkfTF4jy7SnWHqYhgQBvkVWVWiNfhPYaCch9mNT8OIh1x?= =?utf-8?q?kXQyMfXyHCeQoHaon67IYVo0s/4y4UZzHfDoN9L9lLIaEs88Pt0P/mW0xPRZxLl4Y?= =?utf-8?q?Cml8dpQWljANzxRTboYCTvd3EKJ8qOAP50YphJ9YqIKN2AzBQoNuiu+YX2msxrLKb?= =?utf-8?q?bYJFs1ZYjdb3BBPNOT0H11X4+n71aTrBb3T64qDdFpE+yR469UVAImR5PTYWEvK+a?= =?utf-8?q?g+0cM0pH4UWUy99QFi2Gb5ka1UYKyyYzFVGUUr1X0dE7szPgJV7Np1+xPq0i2Oqql?= =?utf-8?q?hckUsuE7LKbMjEGcx9FDQgvDH4U5ewpbK14CMzwiQCJSATUCox/bgFLzpc2fTPi1F?= =?utf-8?q?7ih+rIZ9nJPnr8dFbXqGsSnlctIdBA1GI1KTnAOrz9rqahKJGJftJPK/xGo/d7Mn/?= =?utf-8?q?zZxqQPN4I9oV/90nwxHpjgA8jGfGpuH6Tj6tiJs2dQeMd1s247fck5Z6hXfQgeg+6?= =?utf-8?q?/nCdjHYrgwKGCce6D8Dr12rVNexWJy6A4AXvYVPXLqWdZzoVpmk0NKKKnWVsfCt+X?= =?utf-8?q?Who8XiPlgCnEGZiPJXnziP7UvwZZfAOnGCuSgRNFlpf1AaJek+9gnghqOH6b26R7m?= =?utf-8?q?4SCcZgYEMVApFRuGQxwKThQ9IhWHlI4D33lwWkRVClWrwqCj5BEnbsuNNY6h/q6xR?= =?utf-8?q?OJHYeGSgrJPnYFUq33jvG+8AOdq28IPuVFyZvia0J3i4/BBHhQK4apiu1tPJAKEPu?= =?utf-8?q?yTSQ4dPG2Y/T2rrnBiUSpGEA6AtIsIZPP545KybdFqy2b/fTp/YWQieK4FOYpjoEx?= =?utf-8?q?q3hw7/eo70l5cCOJDAXFkKeFE3WkZnAiLJwnrEQ9jlBByz4Qb04ZNd9vcSut8L8ya?= =?utf-8?q?D+QWNIJMG9feOrxpMSB0Z7jxfR4ZmFbtWxTV+GcAht6i2jNzObs8AemDeJYkW4DVB?= =?utf-8?q?JOpDfqJbdmN?= X-OriginatorOrg: silabs.com X-MS-Exchange-CrossTenant-Network-Message-Id: 55343e5e-b01e-4e13-4256-08dbc4ff68fa X-MS-Exchange-CrossTenant-AuthSource: IA1PR11MB7773.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 04 Oct 2023 17:29:06.2623 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 54dbd822-5231-4b20-944d-6f4abcd541fb X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: wkHEs6wU7R/U65zxK1fGHehLRabFK/zQoSo4VClh6riWjUbbkKNXUaF6LchlP/KPeWJTczj2MSzwwJ3yJg5lYw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH7PR11MB5982 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org With some conditions, the device is able to send/receive frames during scan operation. So, it is possible to use it implement the "remain on channel" feature. We just ask for a passive scan (without sending any probe request) on one channel. This architecture allows to leverage some interesting features: - if the device is AP, the device switches channel just after the next beacon and the beacons are stopped during the off-channel interval. - if the device is connected, it advertises it is asleep before to switch channel (so the AP should stop to try to send data) Signed-off-by: Jérôme Pouiller --- drivers/net/wireless/silabs/wfx/main.c | 3 ++ drivers/net/wireless/silabs/wfx/scan.c | 62 ++++++++++++++++++++++++++ drivers/net/wireless/silabs/wfx/scan.h | 6 +++ drivers/net/wireless/silabs/wfx/sta.c | 1 + drivers/net/wireless/silabs/wfx/wfx.h | 5 ++- 5 files changed, 76 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/silabs/wfx/main.c b/drivers/net/wireless/silabs/wfx/main.c index 4bf16bceb0bbc..e7198520bdffc 100644 --- a/drivers/net/wireless/silabs/wfx/main.c +++ b/drivers/net/wireless/silabs/wfx/main.c @@ -151,6 +151,8 @@ static const struct ieee80211_ops wfx_ops = { .change_chanctx = wfx_change_chanctx, .assign_vif_chanctx = wfx_assign_vif_chanctx, .unassign_vif_chanctx = wfx_unassign_vif_chanctx, + .remain_on_channel = wfx_remain_on_channel, + .cancel_remain_on_channel = wfx_cancel_remain_on_channel, }; bool wfx_api_older_than(struct wfx_dev *wdev, int major, int minor) @@ -289,6 +291,7 @@ struct wfx_dev *wfx_init_common(struct device *dev, const struct wfx_platform_da hw->wiphy->features |= NL80211_FEATURE_AP_SCAN; hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD; hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD; + hw->wiphy->max_remain_on_channel_duration = 5000; hw->wiphy->max_ap_assoc_sta = HIF_LINK_ID_MAX; hw->wiphy->max_scan_ssids = 2; hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN; diff --git a/drivers/net/wireless/silabs/wfx/scan.c b/drivers/net/wireless/silabs/wfx/scan.c index d6f98035f6844..c3c103ff88cce 100644 --- a/drivers/net/wireless/silabs/wfx/scan.c +++ b/drivers/net/wireless/silabs/wfx/scan.c @@ -145,3 +145,65 @@ void wfx_scan_complete(struct wfx_vif *wvif, int nb_chan_done) wvif->scan_nb_chan_done = nb_chan_done; complete(&wvif->scan_complete); } + +void wfx_remain_on_channel_work(struct work_struct *work) +{ + struct wfx_vif *wvif = container_of(work, struct wfx_vif, remain_on_channel_work); + struct ieee80211_channel *chan = wvif->remain_on_channel_chan; + int duration = wvif->remain_on_channel_duration; + int ret; + + /* Hijack scan request to implement Remain-On-Channel */ + mutex_lock(&wvif->wdev->conf_mutex); + mutex_lock(&wvif->wdev->scan_lock); + if (wvif->join_in_progress) { + dev_info(wvif->wdev->dev, "abort in-progress REQ_JOIN"); + wfx_reset(wvif); + } + wfx_tx_flush(wvif->wdev); + + reinit_completion(&wvif->scan_complete); + ret = wfx_hif_scan_uniq(wvif, chan, duration); + if (ret) + goto end; + ieee80211_ready_on_channel(wvif->wdev->hw); + ret = wait_for_completion_timeout(&wvif->scan_complete, + msecs_to_jiffies(duration * 120 / 100)); + if (!ret) { + wfx_hif_stop_scan(wvif); + ret = wait_for_completion_timeout(&wvif->scan_complete, 1 * HZ); + dev_dbg(wvif->wdev->dev, "roc timeout\n"); + } + if (!ret) + dev_err(wvif->wdev->dev, "roc didn't stop\n"); + ieee80211_remain_on_channel_expired(wvif->wdev->hw); +end: + mutex_unlock(&wvif->wdev->scan_lock); + mutex_unlock(&wvif->wdev->conf_mutex); + wfx_bh_request_tx(wvif->wdev); +} + +int wfx_remain_on_channel(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_channel *chan, int duration, + enum ieee80211_roc_type type) +{ + struct wfx_dev *wdev = hw->priv; + struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv; + + if (wfx_api_older_than(wdev, 3, 10)) + return -EOPNOTSUPP; + + wvif->remain_on_channel_duration = duration; + wvif->remain_on_channel_chan = chan; + schedule_work(&wvif->remain_on_channel_work); + return 0; +} + +int wfx_cancel_remain_on_channel(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +{ + struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv; + + wfx_hif_stop_scan(wvif); + flush_work(&wvif->remain_on_channel_work); + return 0; +} diff --git a/drivers/net/wireless/silabs/wfx/scan.h b/drivers/net/wireless/silabs/wfx/scan.h index 78e3b984f375c..995ab8c6cb5ef 100644 --- a/drivers/net/wireless/silabs/wfx/scan.h +++ b/drivers/net/wireless/silabs/wfx/scan.h @@ -19,4 +19,10 @@ int wfx_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, void wfx_cancel_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif); void wfx_scan_complete(struct wfx_vif *wvif, int nb_chan_done); +void wfx_remain_on_channel_work(struct work_struct *work); +int wfx_remain_on_channel(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_channel *chan, int duration, + enum ieee80211_roc_type type); +int wfx_cancel_remain_on_channel(struct ieee80211_hw *hw, struct ieee80211_vif *vif); + #endif diff --git a/drivers/net/wireless/silabs/wfx/sta.c b/drivers/net/wireless/silabs/wfx/sta.c index 8533bad6caeae..1b6c158457b42 100644 --- a/drivers/net/wireless/silabs/wfx/sta.c +++ b/drivers/net/wireless/silabs/wfx/sta.c @@ -728,6 +728,7 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) init_completion(&wvif->scan_complete); INIT_WORK(&wvif->scan_work, wfx_hw_scan_work); + INIT_WORK(&wvif->remain_on_channel_work, wfx_remain_on_channel_work); wfx_tx_queues_init(wvif); wfx_tx_policy_init(wvif); diff --git a/drivers/net/wireless/silabs/wfx/wfx.h b/drivers/net/wireless/silabs/wfx/wfx.h index a41b2c35fa415..bd0df2e1ea990 100644 --- a/drivers/net/wireless/silabs/wfx/wfx.h +++ b/drivers/net/wireless/silabs/wfx/wfx.h @@ -70,6 +70,7 @@ struct wfx_vif { bool after_dtim_tx_allowed; bool join_in_progress; + struct completion set_pm_mode_complete; struct delayed_work beacon_loss_work; @@ -87,7 +88,9 @@ struct wfx_vif { bool scan_abort; struct ieee80211_scan_request *scan_req; - struct completion set_pm_mode_complete; + struct ieee80211_channel *remain_on_channel_chan; + int remain_on_channel_duration; + struct work_struct remain_on_channel_work; }; static inline struct ieee80211_vif *wvif_to_vif(struct wfx_vif *wvif)