Received: by 2002:a05:6358:d09b:b0:dc:cd0c:909e with SMTP id jc27csp460834rwb; Tue, 29 Nov 2022 00:35:03 -0800 (PST) X-Google-Smtp-Source: AA0mqf5f4hmWck3naszij8H3TqRUWvln3vIXwb5KkJwVxfmrdxilAeaRVScRqMC8C48OoOcqxl20 X-Received: by 2002:a17:902:cf41:b0:189:3e36:28b8 with SMTP id e1-20020a170902cf4100b001893e3628b8mr23079845plg.94.1669710902882; Tue, 29 Nov 2022 00:35:02 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1669710902; cv=none; d=google.com; s=arc-20160816; b=tz8JFfzFoDTilpakdMU+gBxHxDinalCg8xmEqTwAadmBLWYPkG5gyOV/kqWQsvQBk/ nY6ZdInuaQlwINtRC+mHZjFAcDXrEANXbYCxBiAs7KkZaqo0ohs4489mOu5YWsT7bii/ khpVp8TYGU+I7GICN2bklegKvZ7GEZAp8ZcJNLuaEoS6Ry7mDl6CiBuucJu8wAp0SvxS NeQIkYhM2/78kUWfRaJhqsijxGmd2uqS+JLxl4JioU+IZTBygn6R5bpYVkmbiYzzH6aZ 67ykB5g5LN8vhpg0wq/4Il6lF+06GWz4QAT7PFGFthvkMKtqRQPFzkEDhNyT2wmEmnuZ IDOA== 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 :references:in-reply-to:message-id:date:subject:cc:to:from :authenticated-by; bh=/4pw54AUcBIINyRb51DounlpYJMRT/cjZAsp7ufBmUk=; b=DO2P/qLKab5IV9iexVJHx7UbHWl2uhkJhAPsV1eSaXOSEpOi6plIaEOM+QiBGL23gB l80v5RMcTcb6VwVnMxt/8s1Lz1wbbZ3ol1zb4IjuHTR+bAd+wTMSmF4Xe+Lbj25brD6f A39sab54MPIZv8mu43GqMTEntcV5Auq2xJe9c9/tEoeMVmaYLPNlUctGdaQOR6gjHsOv yN5eCtVI88Mz3CfywjaQ6rHQOykfstY7hyG890sZY3paMhQadNHFH8McMgy+2eVdHKql fVsguoVyuer3iuObbcPMU5suVHNFUKanandBjYzg6bKWxaXAyc1U6M7kLNAIMb/aWsha QoFw== 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 f14-20020a170902ce8e00b0018659963cdcsi16248308plg.514.2022.11.29.00.34.55; Tue, 29 Nov 2022 00:35:02 -0800 (PST) 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 S231128AbiK2Id6 (ORCPT + 67 others); Tue, 29 Nov 2022 03:33:58 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45386 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230497AbiK2IdS (ORCPT ); Tue, 29 Nov 2022 03:33:18 -0500 Received: from rtits2.realtek.com.tw (rtits2.realtek.com [211.75.126.72]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 772B21088 for ; Tue, 29 Nov 2022 00:32:39 -0800 (PST) Authenticated-By: X-SpamFilter-By: ArmorX SpamTrap 5.77 with qID 2AT8Vl3L2002154, This message is accepted by code: ctloc85258 Received: from mail.realtek.com (rtexh36505.realtek.com.tw[172.21.6.25]) by rtits2.realtek.com.tw (8.15.2/2.81/5.90) with ESMTPS id 2AT8Vl3L2002154 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=FAIL); Tue, 29 Nov 2022 16:31:47 +0800 Received: from RTEXMBS04.realtek.com.tw (172.21.6.97) by RTEXH36505.realtek.com.tw (172.21.6.25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.32; Tue, 29 Nov 2022 16:32:31 +0800 Received: from localhost (172.21.69.188) by RTEXMBS04.realtek.com.tw (172.21.6.97) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.7; Tue, 29 Nov 2022 16:32:31 +0800 From: Ping-Ke Shih To: CC: , Subject: [PATCH v2 3/6] wifi: rtw89: introduce helpers to wait/complete on condition Date: Tue, 29 Nov 2022 16:31:27 +0800 Message-ID: <20221129083130.45708-4-pkshih@realtek.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221129083130.45708-1-pkshih@realtek.com> References: <20221129083130.45708-1-pkshih@realtek.com> MIME-Version: 1.0 Content-Transfer-Encoding: 7BIT Content-Type: text/plain; charset=US-ASCII X-Originating-IP: [172.21.69.188] X-ClientProxiedBy: RTEXMBS02.realtek.com.tw (172.21.6.95) To RTEXMBS04.realtek.com.tw (172.21.6.97) X-KSE-ServerInfo: RTEXMBS04.realtek.com.tw, 9 X-KSE-AntiSpam-Interceptor-Info: trusted connection X-KSE-Antiphishing-Info: Clean X-KSE-Antiphishing-ScanningType: Deterministic X-KSE-Antiphishing-Method: None X-KSE-Antiphishing-Bases: 11/29/2022 08:08:00 X-KSE-AttachmentFiltering-Interceptor-Info: no applicable attachment filtering rules found X-KSE-Antivirus-Interceptor-Info: scan successful X-KSE-Antivirus-Info: =?big5?B?Q2xlYW4sIGJhc2VzOiAyMDIyLzExLzI5IKRXpMggMDY6MDE6MDA=?= X-KSE-BulkMessagesFiltering-Scan-Result: protection disabled X-KSE-ServerInfo: RTEXH36505.realtek.com.tw, 9 X-KSE-Attachment-Filter-Triggered-Rules: Clean X-KSE-Attachment-Filter-Triggered-Filters: Clean X-KSE-BulkMessagesFiltering-Scan-Result: protection disabled X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_NONE, SPF_PASS 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: Zong-Zhe Yang MCC (multi-channel concurrency) related H2Cs (host to chip commands) require to wait for C2H (chip to host events) responses to judge the execution result and data. We introduce helpers to assist this process. Besides, we would like the helpers to be generic for use in driver even outside of MCC H2C/C2H, so we make a independent patch for them. In the following, I describe the things first. ``` (A) C2H is generated by FW, and then transferred upto driver. Hence, driver cannot get it immediately without a bit waitting/blocking. For this, we choose to use wait_for_completion_*() instead of busy polling. (B) From the driver management perspective, a scenario, e.g. MCC, may have mulitple kind of H2C functions requiring this process to wait for corresponding C2Hs. But, the driver management flow uses mutex to protect each behavior. So, one scenario triggers one H2C function at one time. To avoid rampant instances of struct completion for each H2C function, we choose to use one struct completion with one condition flag for one scenario. (C) C2Hs, which H2Cs will be waitting for, cannot be ordered with driver management flow, i.e. cannot enqueue work to the same ordered workqueue and cannot lock by the same mutex, to prevent H2C side from getting no C2H responses. So, those C2Hs are parsed in interrupt context directly as done in previous commit. (D) Following (C), the above underline H2Cs and C2Hs will be handled in different contexts without sync. So, we use atomic_cmpxchg() to compare and change the condition in atomic. ``` So, we introduce struct rtw89_wait_info which combines struct completion and atomic_t. Then, the below are the descriptions for helper functions. * rtw89_wait_for_cond() to wait for a completion based on a condition. * rtw89_complete_cond() to complete a given condition and carry data. Each rtw89_wait_info instance independently determines the meaning of its waitting conditions. But, RTW89_WAIT_COND_IDLE (UINT_MAX) is reserved. Signed-off-by: Zong-Zhe Yang Signed-off-by: Ping-Ke Shih --- drivers/net/wireless/realtek/rtw89/core.c | 35 +++++++++++++++++++++++ drivers/net/wireless/realtek/rtw89/core.h | 25 ++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c index a5fe45d79f189..cd3c3320c5b92 100644 --- a/drivers/net/wireless/realtek/rtw89/core.c +++ b/drivers/net/wireless/realtek/rtw89/core.c @@ -2947,6 +2947,41 @@ void rtw89_core_update_beacon_work(struct work_struct *work) mutex_unlock(&rtwdev->mutex); } +int rtw89_wait_for_cond(struct rtw89_wait_info *wait, unsigned int cond) +{ + struct completion *cmpl = &wait->completion; + unsigned long timeout; + unsigned int cur; + + cur = atomic_cmpxchg(&wait->cond, RTW89_WAIT_COND_IDLE, cond); + if (cur != RTW89_WAIT_COND_IDLE) + return -EBUSY; + + timeout = wait_for_completion_timeout(cmpl, RTW89_WAIT_FOR_COND_TIMEOUT); + if (timeout == 0) { + atomic_set(&wait->cond, RTW89_WAIT_COND_IDLE); + return -ETIMEDOUT; + } + + if (wait->data.err) + return -EFAULT; + + return 0; +} + +void rtw89_complete_cond(struct rtw89_wait_info *wait, unsigned int cond, + const struct rtw89_completion_data *data) +{ + unsigned int cur; + + cur = atomic_cmpxchg(&wait->cond, cond, RTW89_WAIT_COND_IDLE); + if (cur != cond) + return; + + wait->data = *data; + complete(&wait->completion); +} + int rtw89_core_start(struct rtw89_dev *rtwdev) { int ret; diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 691d417d37334..2a049fab8cfca 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -2811,6 +2811,28 @@ struct rtw89_mac_info { u8 cpwm_seq_num; }; +#define RTW89_COMPLETION_BUF_SIZE 24 +#define RTW89_WAIT_COND_IDLE UINT_MAX + +struct rtw89_completion_data { + bool err; + u8 buf[RTW89_COMPLETION_BUF_SIZE]; +}; + +struct rtw89_wait_info { + atomic_t cond; + struct completion completion; + struct rtw89_completion_data data; +}; + +#define RTW89_WAIT_FOR_COND_TIMEOUT msecs_to_jiffies(100) + +static inline void rtw89_init_wait(struct rtw89_wait_info *wait) +{ + init_completion(&wait->completion); + atomic_set(&wait->cond, RTW89_WAIT_COND_IDLE); +} + enum rtw89_fw_type { RTW89_FW_NORMAL = 1, RTW89_FW_WOWLAN = 3, @@ -4451,6 +4473,9 @@ int rtw89_regd_init(struct rtw89_dev *rtwdev, void rtw89_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request); void rtw89_traffic_stats_init(struct rtw89_dev *rtwdev, struct rtw89_traffic_stats *stats); +int rtw89_wait_for_cond(struct rtw89_wait_info *wait, unsigned int cond); +void rtw89_complete_cond(struct rtw89_wait_info *wait, unsigned int cond, + const struct rtw89_completion_data *data); int rtw89_core_start(struct rtw89_dev *rtwdev); void rtw89_core_stop(struct rtw89_dev *rtwdev); void rtw89_core_update_beacon_work(struct work_struct *work); -- 2.25.1