From patchwork Thu Sep 9 15:33:20 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bryan O'Donoghue X-Patchwork-Id: 508360 Delivered-To: patch@linaro.org Received: by 2002:a02:8629:0:0:0:0:0 with SMTP id e38csp431204jai; Thu, 9 Sep 2021 08:31:32 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzD9uBpHKl56fRJ13aVvld93PcFowvhnpY6MXqwIImQL3JCF6KlYtCXua81F5xPmI+NCj7h X-Received: by 2002:a5e:8e04:: with SMTP id a4mr3214135ion.56.1631201492574; Thu, 09 Sep 2021 08:31:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1631201492; cv=none; d=google.com; s=arc-20160816; b=wQUZ2Rjb60oyPms3X6x21KDY/fLbPSOOWDT0rE11/DU5Q5hJHiOa8p9aPl6UWF4BZr e/a4zlRvz2xwTq+zUr206hwFFdBkkGFKfZ75jBbQcl0Py2cgNny3RpPaCCJASmC5cMId J9/1IrQreJ3Mr1PGP1T7VHyLL4az4QIw740wjJ5cQRRExOm59S1CCJwB46Jt38rum5Uk 8Xx0ZeP1w9/wqn/GjI4qhYj5CC8OfEeGK6ydL6ZT1qb9OgulxFiOceHbVGb9Vc1Wvdh7 8YmSJ8gVXYLkoVzycyxBpa9X6F2ihKi2n9RU1Vr+tDiFq8udOMkF9GxSVRylNcnd4Q8r xrog== 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:dkim-signature; bh=6bcT8H0XxYOwPfG/ex8rhH7MU/535fM35JAq8iCTSoM=; b=ZdNY5wWYWbfh47jcv7rTVHv2qnMobLqu0SxH1RnwD5rwbYWOG2hKIKbkDJoeqejEld ypyutYiEkbmbCXJ9v+3rhOMYLxbEFqcYrOUSzAZObkujHX+N95lohoALEtfECibYeehw EwSFjmq+uf79UsRbS7j/Lav8brQNgfPXztld/+AHxvgH3K2eBpl/EAEq08+GMdqql0uq hihHZ6HgF1CYjK+Qmpcbe1eFDxQIDADgL73WX0G79J46xExBOSnHfsIh+RN9i866x7ek Glh3RzbR5R9Jw7xHfsEr0aDnXKT8LPnt/YaPJeAgJrFyslRz7gp7NTy/qBt++mC/57iO 9D7Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=uanjnRZB; spf=pass (google.com: domain of linux-wireless-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-wireless-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id c11si1900888ild.118.2021.09.09.08.31.32; Thu, 09 Sep 2021 08:31:32 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-wireless-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=uanjnRZB; spf=pass (google.com: domain of linux-wireless-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-wireless-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232656AbhIIPcl (ORCPT + 2 others); Thu, 9 Sep 2021 11:32:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58944 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232359AbhIIPck (ORCPT ); Thu, 9 Sep 2021 11:32:40 -0400 Received: from mail-wr1-x42f.google.com (mail-wr1-x42f.google.com [IPv6:2a00:1450:4864:20::42f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AE376C061574 for ; Thu, 9 Sep 2021 08:31:30 -0700 (PDT) Received: by mail-wr1-x42f.google.com with SMTP id u16so3158541wrn.5 for ; Thu, 09 Sep 2021 08:31:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=6bcT8H0XxYOwPfG/ex8rhH7MU/535fM35JAq8iCTSoM=; b=uanjnRZBU/oz1r5Bss7O464Ys4xNnm1ivBZYeLSt1FKixG552OIuOR/TMJMlPRW2zq Ku1X9WRpDHYYBcYCmmjKFpAEuWGuFPbTDrieqXILNiWBodrFAodlhmDy1hhyDfb1lttG euuDGfq5KnDcjrO7MwmcqibTM3949vQjo02/7uKSedftpFnoljmBrjvCn17RbxX2HjtA ppydnhTmanFQ0yMJJzoKwakwPq+ygUz+/DMLA/8CvQrfmbeekWmoxrNghtgk4cFZIQrJ Dps9mUBs/qjRDV5KHW+MRRNPZVLdixtUJnwtsMiLJDqctgwoXlbCxSBnD+0/npV7Ktlu 2rYw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=6bcT8H0XxYOwPfG/ex8rhH7MU/535fM35JAq8iCTSoM=; b=0oX5TrtQibLpwC2xZgnk7yRMntvcdaU4c2p0rImHbNLsUQYyAbMRmZWe+2C/cHMw9M EoAsZ0o0i+9rJavBzjdARvnletzNNTHOTWS3XULRvmyNIA2n2p6GCXFdGt/PR5LU4+k2 UGHGhqDuduv5FrJA7tAS/CFRxnUffMPVjIQ37yv7r/1Fsed3f0qtRBzV88zFy2HMKMeU mQ9nSJSicpbMggTk/loqkjhbn4ti41guSGHPVTJ6HA5eOgz+TLdCZhKwBMYXdgXMB8b1 uzIADO85qEsxunP1ma8MTXxKq976iUzTBPcgR1/rtdD80um1aJBzB5QrUgjiI0H1bPTP HAbw== X-Gm-Message-State: AOAM532sK2FZs9G+ivyyab53lAMt5eQMdKgePpnm7lSa2a8D3bYiWJfm /LXIJnyZMNAmF07rIyaLEtTaPw== X-Received: by 2002:adf:8b19:: with SMTP id n25mr4549458wra.216.1631201487554; Thu, 09 Sep 2021 08:31:27 -0700 (PDT) Received: from sagittarius-a.chello.ie (188-141-3-169.dynamic.upc.ie. [188.141.3.169]) by smtp.gmail.com with ESMTPSA id f5sm1856536wmb.47.2021.09.09.08.31.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Sep 2021 08:31:27 -0700 (PDT) From: Bryan O'Donoghue To: kvalo@codeaurora.org, linux-wireless@vger.kernel.org, wcn36xx@lists.infradead.org Cc: loic.poulain@linaro.org, benl@squareup.com, bryan.odonoghue@linaro.org Subject: [PATCH] wcn36xx: Implement Idle Mode Power Save Date: Thu, 9 Sep 2021 16:33:20 +0100 Message-Id: <20210909153320.2624649-1-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.33.0 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org Idle Mode Power Save (IMPS) is a power saving mechanism which when called by wcn36xx will cause the radio hardware to enter power collapse. This particular call maps nicely to a simple conjunction/disjunction around IEEE80211_CONF_CHANGE_IDLE and IEEE80211_CONF_IDLE. Here we enter idle when we are not associated with an AP. The kernel will incrementally toggle idle on/off in the process of trying to establish a connection, thus saving power until we are connected to the AP again, at which point we give way to BMPS if power_save is on. We've validated that with IMPS an apq8039 device which has the wcn36xx module loaded but, has not authenticated with an AP will get to VMIN on suspend and will not without IMPS. Signed-off-by: Bryan O'Donoghue Tested-by: Benjamin Li --- drivers/net/wireless/ath/wcn36xx/hal.h | 6 +-- drivers/net/wireless/ath/wcn36xx/main.c | 7 ++++ drivers/net/wireless/ath/wcn36xx/smd.c | 55 +++++++++++++++++++++++++ drivers/net/wireless/ath/wcn36xx/smd.h | 3 ++ 4 files changed, 68 insertions(+), 3 deletions(-) -- 2.33.0 diff --git a/drivers/net/wireless/ath/wcn36xx/hal.h b/drivers/net/wireless/ath/wcn36xx/hal.h index 455143c4164e..5f1f2480459a 100644 --- a/drivers/net/wireless/ath/wcn36xx/hal.h +++ b/drivers/net/wireless/ath/wcn36xx/hal.h @@ -3384,11 +3384,11 @@ struct tl_hal_flush_ac_rsp_msg { struct wcn36xx_hal_enter_imps_req_msg { struct wcn36xx_hal_msg_header header; -}; +} __packed; -struct wcn36xx_hal_exit_imps_req { +struct wcn36xx_hal_exit_imps_req_msg { struct wcn36xx_hal_msg_header header; -}; +} __packed; struct wcn36xx_hal_enter_bmps_req_msg { struct wcn36xx_hal_msg_header header; diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c index 2561ae9cde65..412c629705a6 100644 --- a/drivers/net/wireless/ath/wcn36xx/main.c +++ b/drivers/net/wireless/ath/wcn36xx/main.c @@ -443,6 +443,13 @@ static int wcn36xx_config(struct ieee80211_hw *hw, u32 changed) if (changed & IEEE80211_CONF_CHANGE_PS) wcn36xx_change_ps(wcn, hw->conf.flags & IEEE80211_CONF_PS); + if (changed & IEEE80211_CONF_CHANGE_IDLE) { + if (hw->conf.flags & IEEE80211_CONF_IDLE) + wcn36xx_smd_enter_imps(wcn); + else + wcn36xx_smd_exit_imps(wcn); + } + mutex_unlock(&wcn->conf_mutex); return 0; diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c index 57fa857b290b..599cb220b150 100644 --- a/drivers/net/wireless/ath/wcn36xx/smd.c +++ b/drivers/net/wireless/ath/wcn36xx/smd.c @@ -2184,6 +2184,59 @@ int wcn36xx_smd_exit_bmps(struct wcn36xx *wcn, struct ieee80211_vif *vif) return ret; } +int wcn36xx_smd_enter_imps(struct wcn36xx *wcn) +{ + struct wcn36xx_hal_enter_imps_req_msg msg_body; + int ret; + + mutex_lock(&wcn->hal_mutex); + INIT_HAL_MSG(msg_body, WCN36XX_HAL_ENTER_IMPS_REQ); + + PREPARE_HAL_BUF(wcn->hal_buf, msg_body); + + ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len); + if (ret) { + wcn36xx_err("Sending hal_enter_imps failed\n"); + goto out; + } + ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len); + if (ret) { + wcn36xx_err("hal_enter_imps response failed err=%d\n", ret); + goto out; + } + + wcn36xx_dbg(WCN36XX_DBG_HAL, "Entered idle mode\n"); +out: + mutex_unlock(&wcn->hal_mutex); + return ret; +} + +int wcn36xx_smd_exit_imps(struct wcn36xx *wcn) +{ + struct wcn36xx_hal_exit_imps_req_msg msg_body; + int ret; + + mutex_lock(&wcn->hal_mutex); + INIT_HAL_MSG(msg_body, WCN36XX_HAL_EXIT_IMPS_REQ); + + PREPARE_HAL_BUF(wcn->hal_buf, msg_body); + + ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len); + if (ret) { + wcn36xx_err("Sending hal_exit_imps failed\n"); + goto out; + } + ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len); + if (ret) { + wcn36xx_err("hal_exit_imps response failed err=%d\n", ret); + goto out; + } + wcn36xx_dbg(WCN36XX_DBG_HAL, "Exited idle mode\n"); +out: + mutex_unlock(&wcn->hal_mutex); + return ret; +} + int wcn36xx_smd_set_power_params(struct wcn36xx *wcn, bool ignore_dtim) { struct wcn36xx_hal_set_power_params_req_msg msg_body; @@ -3060,6 +3113,8 @@ int wcn36xx_smd_rsp_process(struct rpmsg_device *rpdev, case WCN36XX_HAL_GTK_OFFLOAD_RSP: case WCN36XX_HAL_GTK_OFFLOAD_GETINFO_RSP: case WCN36XX_HAL_HOST_RESUME_RSP: + case WCN36XX_HAL_ENTER_IMPS_RSP: + case WCN36XX_HAL_EXIT_IMPS_RSP: memcpy(wcn->hal_buf, buf, len); wcn->hal_rsp_len = len; complete(&wcn->hal_rsp_compl); diff --git a/drivers/net/wireless/ath/wcn36xx/smd.h b/drivers/net/wireless/ath/wcn36xx/smd.h index 75d1a6d663bb..dbca0bd1b6ae 100644 --- a/drivers/net/wireless/ath/wcn36xx/smd.h +++ b/drivers/net/wireless/ath/wcn36xx/smd.h @@ -165,4 +165,7 @@ int wcn36xx_smd_wlan_host_suspend_ind(struct wcn36xx *wcn); int wcn36xx_smd_host_resume(struct wcn36xx *wcn); +int wcn36xx_smd_enter_imps(struct wcn36xx *wcn); +int wcn36xx_smd_exit_imps(struct wcn36xx *wcn); + #endif /* _SMD_H_ */