From nobody Thu Sep 11 20:57:40 2025 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 F37BCE7C4E2 for ; Wed, 4 Oct 2023 17:29:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243736AbjJDR31 (ORCPT ); Wed, 4 Oct 2023 13:29:27 -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?q?J=C3=A9r=C3=B4me=20Pouiller?= To: Kalle Valo Cc: linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org, =?UTF-8?q?J=C3=A9r=C3=B4me=20Pouiller?= 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> Content-Transfer-Encoding: quoted-printable 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?B?VFRyZTFlakVvdXo1ZXk0WGtQVVFCRlQrWXNNVHVHcm5NRVhaa01QUldYVUFS?= =?utf-8?B?dVVUT2xyelRPdmIwUUh1aUtPK0ZqalBMV0pWc0YxQWJMMHZPUkdtUlZITDAy?= =?utf-8?B?Sk1JYlNGNFo2Sko1dk8yOXFHS3pyR2JkK1FualV1cU40b255OTZ1OCtpU29h?= =?utf-8?B?R2hmQVFTc1kva0VVdThaNzRndDAxSFpUbGN4aTBnV1FlNGhBQUdKekc2Y3pQ?= =?utf-8?B?KzE0NS9SUVkzbU5ITm45MGdYY1NZTFI0eDdLYkxsNVdzSEVxWnMzN2hwbk03?= =?utf-8?B?S2ZLYnlDRVlBSUVzQ2g1dk5ES0dPQjVUMWZodGVZb0VCU1lDcERFV2htR25v?= =?utf-8?B?OXJOeVhlblJ6QlhNZVlQYjhlYmlsRGpFVXdRUWdDeElieEh3bU1UeG9lRDMv?= =?utf-8?B?REozd3dTTHdubXZxa1hTL2daZGlJTjAyaDZlVUY5cUJ0ek1wZTlJZjZKWG8w?= =?utf-8?B?SisrbVNFTFg3U1R6K25oejMzY3VOYzRVUE9jSWcrZ0VTVmZxWVowdTZSLzF3?= =?utf-8?B?emxGVzRpaFVqeElMb2pWcjg5QS90YVB3TTJkMlpaenZMQjE0azJlRWc4bGpn?= =?utf-8?B?eHV2SlBEZERFdG10WFd1MThQTlN5Sk5xQ080d0pQeSszTENhRHl4V2RueGQ4?= =?utf-8?B?K3dXRW8rM3NENUVPWDYzQUxoVHFIT1BSZzVENDViZ1JOb1NOTWNoZHJ5S0Yw?= =?utf-8?B?NHdlOXhrNEM5YXZJSWg1Wi9JNjdyejFrY1c1bTBsYTBvd280VElUeVNxL0xK?= =?utf-8?B?Qis1TVVyNjNwVkw1cm9rR2c5VVVMUGIyZ09uSHpjMWVGa1JhbUdyR21ybjAw?= =?utf-8?B?dS9yQVFzNTl0YU5IYWtnNnp3VWVVU2lCMTdseUpSY0dJUU1YdWozZFN1dHdj?= =?utf-8?B?WEtTaTdodnp4S2VNTytsOTJIRGRBbWd0a2ZURjRqeTdTbldIcVloZ1FCdmtW?= =?utf-8?B?V1ZXaU5maFBZYUNjaDltTlQ4T0loMXhrWFF5TWZYeUhDZVFvSGFvbjY3SVlW?= =?utf-8?B?bzBzLzR5NFVaekhmRG9OOUw5bExJYUVzODhQdDBQL21XMHhQUlp4TGw0WUNt?= =?utf-8?B?bDhkcFFXbGpBTnp4UlRib1lDVHZkM0VLSjhxT0FQNTBZcGhKOVlxSUtOMkF6?= =?utf-8?B?QlFvTnVpdStZWDJtc3hyTEtiYllKRnMxWllqZGIzQkJQTk9UMEgxMVg0K243?= =?utf-8?B?MWFUckJiM1Q2NHFEZEZwRSt5UjQ2OVVWQUltUjVQVFlXRXZLK2FnKzBjTTBw?= =?utf-8?B?SDRVV1V5OTlRRmkyR2I1a2ExVVlLeXlZekZWR1VVcjFYMGRFN3N6UGdKVjdO?= =?utf-8?B?cDEreFBxMGkyT3FxbGhja1VzdUU3TEtiTWpFR2N4OUZEUWd2REg0VTVld3Bi?= =?utf-8?B?SzE0Q016d2lRQ0pTQVRVQ294L2JnRkx6cGMyZlRQaTFGN2loK3JJWjluSlBu?= =?utf-8?B?cjhkRmJYcUdzU25sY3RJZEJBMUdJMUtUbkFPcno5cnFhaEtKR0pmdEpQSy94?= =?utf-8?B?R28vZDdNbi96WnhxUVBONEk5b1YvOTBud3hIcGpnQThqR2ZHcHVINlRqNnRp?= =?utf-8?B?SnMyZFFlTWQxczI0N2ZjazVaNmhYZlFnZWcrNi9uQ2RqSFlyZ3dLR0NjZTZE?= =?utf-8?B?OERyMTJyVk5leFdKeTZBNEFYdllWUFhMcVdkWnpvVnBtazBOS0tLbldWc2ZD?= =?utf-8?B?dCtYV2hvOFhpUGxnQ25FR1ppUEpYbnppUDdVdndaWmZBT25HQ3VTZ1JORmxw?= =?utf-8?B?ZjFBYUplays5Z25naHFPSDZiMjZSN200U0NjWmdZRU1WQXBGUnVHUXh3S1Ro?= =?utf-8?B?UTlJaFdIbEk0RDMzbHdXa1JWQ2xXcndxQ2o1QkVuYnN1Tk5ZNmgvcTZ4Uk9K?= =?utf-8?B?SFllR1NnckpQbllGVXEzM2p2Rys4QU9kcTI4SVB1VkZ5WnZpYTBKM2k0L0JC?= =?utf-8?B?SGhRSzRhcGl1MXRQSkFLRVB1eVRTUTRkUEcyWS9UMnJybkJpVVNwR0VBNkF0?= =?utf-8?B?SXNJWlBQNTQ1S3liZEZxeTJiL2ZUcC9ZV1FpZUs0Rk9ZcGpvRXhxM2h3Ny9l?= =?utf-8?B?bzcwbDVjQ09KREFYRmtLZUZFM1drWm5BaUxKd25yRVE5amxCQnl6NFFiMDRa?= =?utf-8?B?TmQ5dmNTdXQ4TDh5YUQrUVdOSUpNRzlmZU9yeHBNU0IwWjdqeGZSNFptRmJ0?= =?utf-8?Q?WxTV+GcAht6i2jNzObs8AemDeJYkW4DVBJOpDfqJbdmN?= 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-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 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=C3=A9r=C3=B4me 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 =3D { .change_chanctx =3D wfx_change_chanctx, .assign_vif_chanctx =3D wfx_assign_vif_chanctx, .unassign_vif_chanctx =3D wfx_unassign_vif_chanctx, + .remain_on_channel =3D wfx_remain_on_channel, + .cancel_remain_on_channel =3D wfx_cancel_remain_on_channel, }; =20 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, con= st struct wfx_platform_da hw->wiphy->features |=3D NL80211_FEATURE_AP_SCAN; hw->wiphy->flags |=3D WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD; hw->wiphy->flags |=3D WIPHY_FLAG_AP_UAPSD; + hw->wiphy->max_remain_on_channel_duration =3D 5000; hw->wiphy->max_ap_assoc_sta =3D HIF_LINK_ID_MAX; hw->wiphy->max_scan_ssids =3D 2; hw->wiphy->max_scan_ie_len =3D 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_ch= an_done) wvif->scan_nb_chan_done =3D nb_chan_done; complete(&wvif->scan_complete); } + +void wfx_remain_on_channel_work(struct work_struct *work) +{ + struct wfx_vif *wvif =3D container_of(work, struct wfx_vif, remain_on_cha= nnel_work); + struct ieee80211_channel *chan =3D wvif->remain_on_channel_chan; + int duration =3D 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 =3D wfx_hif_scan_uniq(wvif, chan, duration); + if (ret) + goto end; + ieee80211_ready_on_channel(wvif->wdev->hw); + ret =3D wait_for_completion_timeout(&wvif->scan_complete, + msecs_to_jiffies(duration * 120 / 100)); + if (!ret) { + wfx_hif_stop_scan(wvif); + ret =3D 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 *v= if, + struct ieee80211_channel *chan, int duration, + enum ieee80211_roc_type type) +{ + struct wfx_dev *wdev =3D hw->priv; + struct wfx_vif *wvif =3D (struct wfx_vif *)vif->drv_priv; + + if (wfx_api_older_than(wdev, 3, 10)) + return -EOPNOTSUPP; + + wvif->remain_on_channel_duration =3D duration; + wvif->remain_on_channel_chan =3D 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 =3D (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 ieee8021= 1_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); =20 +void wfx_remain_on_channel_work(struct work_struct *work); +int wfx_remain_on_channel(struct ieee80211_hw *hw, struct ieee80211_vif *v= if, + 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/s= ilabs/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 i= eee80211_vif *vif) =20 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); =20 wfx_tx_queues_init(wvif); wfx_tx_policy_init(wvif); diff --git a/drivers/net/wireless/silabs/wfx/wfx.h b/drivers/net/wireless/s= ilabs/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 { =20 bool after_dtim_tx_allowed; bool join_in_progress; + struct completion set_pm_mode_complete; =20 struct delayed_work beacon_loss_work; =20 @@ -87,7 +88,9 @@ struct wfx_vif { bool scan_abort; struct ieee80211_scan_request *scan_req; =20 - 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; }; =20 static inline struct ieee80211_vif *wvif_to_vif(struct wfx_vif *wvif) --=20 2.39.2