From patchwork Tue Nov 12 12:40:19 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ulf Hansson X-Patchwork-Id: 179184 Delivered-To: patches@linaro.org Received: by 2002:a92:38d5:0:0:0:0:0 with SMTP id g82csp8058591ilf; Tue, 12 Nov 2019 04:40:33 -0800 (PST) X-Received: by 2002:a2e:2c19:: with SMTP id s25mr5979296ljs.26.1573562433102; Tue, 12 Nov 2019 04:40:33 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1573562433; cv=none; d=google.com; s=arc-20160816; b=tCkoORUtS3qj4OD3xElY6CpW7xGs8ykvR4oD28k8Nw7eSk4dXEVOI0VnIytoTUlt6E stm6oGCfw0VncID8C3tRbgHG+7Cf5C+xRjiw7Fh0RtvceMUeM9bgEe+GWuYT16e9BUxV 7UPoW1j8aDv8HjqbyLEvNimpWstHGYqJdgrR1KV3WJwQSFmQzys9IVrzL0Aab9j0fg9R QEX9XqXaXSUpNeZGfPKuqb8QKmUFHqIGQcnEcZGzawwRTUxYlv23lQa30yuxR2ek01gk Oyoa200pYz/qNF8JLX3/Evd1uWtFFR3EL1eXpH6d4+ePs8xxsiMMXUDbhw8XXZ/fNlev VN9A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=ua0Ewl6JuBhKFh9q7mTyegdBAFgNWUEtu2UoO7aKj0U=; b=us61Nofstcz0gBzGHxcAtP5U1t6DToeD3Uw4J7qpjsn3y37Y9O0tsNlD0LHoqe5tcV pRRQfrOZdYLzhTcqwH9sPJbzAOdCtylCzqxOmWtWaxD0urDum2v2c33JIgs4PQAyjHS5 Pa4TsGp3/9P6V8MoNRYIFJmWrWnSXz93+vXhKvlqIlqoBpzXsBENAdw8jN1N3n6FtU9o txsiatkq4P5QZB0XEs3J5kBvZe35DTzRwOgoLbtAERhF4/+IOYLG+7HGUDPI8aI0B2pe PKgi6zvea3td58BWDPbqhzSNRQEbJcP64koB2/+dpIcwjIb+VwgPbiurpUT/OlHuBenk gXCg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=iquP1sqS; spf=pass (google.com: domain of ulf.hansson@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=ulf.hansson@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from mail-sor-f65.google.com (mail-sor-f65.google.com. [209.85.220.65]) by mx.google.com with SMTPS id d16sor5098794lfi.66.2019.11.12.04.40.30 for (Google Transport Security); Tue, 12 Nov 2019 04:40:33 -0800 (PST) Received-SPF: pass (google.com: domain of ulf.hansson@linaro.org designates 209.85.220.65 as permitted sender) client-ip=209.85.220.65; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=iquP1sqS; spf=pass (google.com: domain of ulf.hansson@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=ulf.hansson@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=ua0Ewl6JuBhKFh9q7mTyegdBAFgNWUEtu2UoO7aKj0U=; b=iquP1sqSevDyN6H4A0gAob9E9nwT6mnSoekR+cRxTs9X53+YlmG+LaN167dDKZ5Gan gZoWe5j1hLDegpBYIb3CM+6rqy3xxqj1HIe/sDGSrKqgB0FOCq6hstZ6bV33oYwIBxwR xmk8GVvhquNb7xsF1HBK5Z86pK6yHlSwQBB3a3/J20s353hEdEoGD6h+G9dMvnnL2/bh T1fbssj4pvKA6CkccU034eVO8Xc6LhuswNyDGOTi75CQwgh2+eGSZCDHnGWeWzc888QV 6G8voK5p+WOpR1Sn+04Nx+S2aMEfUgyNHIRyAXTABA4o6ahmb98wkKkXaare8o4uoHNU FxfQ== 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; bh=ua0Ewl6JuBhKFh9q7mTyegdBAFgNWUEtu2UoO7aKj0U=; b=H7E6ef2lWK98O9hR0JBpUYN4vBm7i7Y46fWC8cj2T1eW3CP2HGssii155m4M53UK95 FeyEc/Dlu9JJT7IEw9MnSCiiuxQizhR7ldCkm4jvp+XftI0lst1xBXV1q5TexyaCdAQk No2X8rC+0urHpsDHCeFMaPvf98l5gkDu19SDt3No4iVLGEOa9JvoypFnqughA2JiatVh Mxw44LOc1id8SJYZYRexTX6et1+XRNDqxhN83pGTITm+4+hoOChvWB4gXQJYDrbm6YTf pFGxEZUHfymEEQLk/HKrY6zqAa7ARPndZYQa9f+qGLovULgNT1OOecrj4nmPgYH233vg SPsQ== X-Gm-Message-State: APjAAAXgmDGoBTUAmHtXYUYiQtXDwGWFjPWrHwmpdl/l6cvqQ9Zkjmgf se4rEr55lkv13lprnLWWiKu5ZV9+ X-Google-Smtp-Source: APXvYqxxXzYQvwF+vKgB/yos7imzceRusxPiynjFik+jDFzy0koMp4aiZO329S7Es2YzErYJ7JFiXQ== X-Received: by 2002:a19:22d3:: with SMTP id i202mr19032642lfi.69.1573562429941; Tue, 12 Nov 2019 04:40:29 -0800 (PST) Return-Path: Received: from uffe-XPS-13-9360.ideon.se ([85.235.10.227]) by smtp.gmail.com with ESMTPSA id z19sm8375096ljk.66.2019.11.12.04.40.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Nov 2019 04:40:29 -0800 (PST) From: Ulf Hansson To: linux-mmc@vger.kernel.org, Ulf Hansson , Adrian Hunter , Douglas Anderson , Matthias Kaehlcke Cc: Kalle Valo , Tony Lindgren , Wen Gong , Erik Stromdahl , Eyal Reizer , linux-wireless@vger.kernel.org Subject: [PATCH v3 1/3] mwifiex: Re-work support for SDIO HW reset Date: Tue, 12 Nov 2019 13:40:19 +0100 Message-Id: <20191112124021.8718-2-ulf.hansson@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191112124021.8718-1-ulf.hansson@linaro.org> References: <20191112124021.8718-1-ulf.hansson@linaro.org> The SDIO HW reset procedure in mwifiex_sdio_card_reset_work() is broken, when the SDIO card is shared with another SDIO func driver. This is the case when the Bluetooth btmrvl driver is being used in combination with mwifiex. More precisely, when mwifiex_sdio_card_reset_work() runs to resets the SDIO card, the btmrvl driver doesn't get notified about it. Beyond that point, the btmrvl driver will fail to communicate with the SDIO card. This is a generic problem for SDIO func drivers sharing an SDIO card, which are about to be addressed in subsequent changes to the mmc core and the mmc_hw_reset() interface. In principle, these changes means the mmc_hw_reset() interface starts to return 1 if the are multiple drivers for the SDIO card, as to indicate to the caller that the reset needed to be scheduled asynchronously through a hotplug mechanism of the SDIO card. Let's prepare the mwifiex driver to support the upcoming new behaviour of mmc_hw_reset(), which means extending the mwifiex_sdio_card_reset_work() to support the asynchronous SDIO HW reset path. This also means, we need to allow the ->remove() callback to run, without waiting for the FW to be loaded. Additionally, during system suspend, mwifiex_sdio_suspend() may be called when a reset has been scheduled, but waiting to be executed. In this scenario let's simply return -EBUSY to abort the suspend process, as to allow the reset to be completed first. Reviewed-by: Douglas Anderson Tested-by: Douglas Anderson Signed-off-by: Ulf Hansson --- drivers/net/wireless/marvell/mwifiex/main.c | 5 +++- drivers/net/wireless/marvell/mwifiex/main.h | 1 + drivers/net/wireless/marvell/mwifiex/sdio.c | 33 ++++++++++++++------- 3 files changed, 27 insertions(+), 12 deletions(-) -- 2.17.1 diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c index a9657ae6d782..d14e55e3c9da 100644 --- a/drivers/net/wireless/marvell/mwifiex/main.c +++ b/drivers/net/wireless/marvell/mwifiex/main.c @@ -631,6 +631,7 @@ static int _mwifiex_fw_dpc(const struct firmware *firmware, void *context) mwifiex_drv_get_driver_version(adapter, fmt, sizeof(fmt) - 1); mwifiex_dbg(adapter, MSG, "driver_version = %s\n", fmt); + adapter->is_up = true; goto done; err_add_intf: @@ -1469,6 +1470,7 @@ int mwifiex_shutdown_sw(struct mwifiex_adapter *adapter) mwifiex_deauthenticate(priv, NULL); mwifiex_uninit_sw(adapter); + adapter->is_up = false; if (adapter->if_ops.down_dev) adapter->if_ops.down_dev(adapter); @@ -1730,7 +1732,8 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter) if (!adapter) return 0; - mwifiex_uninit_sw(adapter); + if (adapter->is_up) + mwifiex_uninit_sw(adapter); if (adapter->irq_wakeup >= 0) device_init_wakeup(adapter->dev, false); diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h index 095837fba300..547ff3c578ee 100644 --- a/drivers/net/wireless/marvell/mwifiex/main.h +++ b/drivers/net/wireless/marvell/mwifiex/main.h @@ -1017,6 +1017,7 @@ struct mwifiex_adapter { /* For synchronizing FW initialization with device lifecycle. */ struct completion *fw_done; + bool is_up; bool ext_scan; u8 fw_api_ver; diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.c b/drivers/net/wireless/marvell/mwifiex/sdio.c index 24c041dad9f6..fec38b6e86ff 100644 --- a/drivers/net/wireless/marvell/mwifiex/sdio.c +++ b/drivers/net/wireless/marvell/mwifiex/sdio.c @@ -444,6 +444,9 @@ static int mwifiex_sdio_suspend(struct device *dev) return 0; } + if (!adapter->is_up) + return -EBUSY; + mwifiex_enable_wake(adapter); /* Enable the Host Sleep */ @@ -2220,22 +2223,30 @@ static void mwifiex_sdio_card_reset_work(struct mwifiex_adapter *adapter) struct sdio_func *func = card->func; int ret; + /* Prepare the adapter for the reset. */ mwifiex_shutdown_sw(adapter); + clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &card->work_flags); + clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &card->work_flags); - /* power cycle the adapter */ + /* Run a HW reset of the SDIO interface. */ sdio_claim_host(func); - mmc_hw_reset(func->card->host); + ret = mmc_hw_reset(func->card->host); sdio_release_host(func); - /* Previous save_adapter won't be valid after this. We will cancel - * pending work requests. - */ - clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &card->work_flags); - clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &card->work_flags); - - ret = mwifiex_reinit_sw(adapter); - if (ret) - dev_err(&func->dev, "reinit failed: %d\n", ret); + switch (ret) { + case 1: + dev_dbg(&func->dev, "SDIO HW reset asynchronous\n"); + complete_all(adapter->fw_done); + break; + case 0: + ret = mwifiex_reinit_sw(adapter); + if (ret) + dev_err(&func->dev, "reinit failed: %d\n", ret); + break; + default: + dev_err(&func->dev, "SDIO HW reset failed: %d\n", ret); + break; + } } /* This function read/write firmware */