Skip to content

Commit ebec1d1

Browse files
kitakar5525qzed
authored andcommitted
mwifiex_pcie: remove()/probe() card on suspend()/resume()
(made based on commit https://github.com/sebanc/linux-kernel/commit/0f5283b42247cb8978ed9493936f9b5b72350121) On upstream mwifiex driver, it's reported that unloading the driver manually [1] fixes S0ix achievement during s2idle (suspend). Also, unloading/reloading the driver fixes "AP scanning (sometimes) not working after suspend". This commit removes/probes the card on suspend/resume on the driver side to fix such issues. [1] Run the following command for example $ sudo modprobe -r mwifiex_pcie sudo modprobe -r mwifiex Signed-off-by: Tsuchiya Yuto (kitakar5525) <kitakar@gmail.com> (cherry picked from commit 82204f8 from PR #44) Signed-off-by: Tsuchiya Yuto (kitakar5525) <kitakar@gmail.com>
1 parent 3b94e9a commit ebec1d1

File tree

1 file changed

+45
-34
lines changed
  • drivers/net/wireless/marvell/mwifiex

1 file changed

+45
-34
lines changed

drivers/net/wireless/marvell/mwifiex/pcie.c

Lines changed: 45 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -146,38 +146,45 @@ static bool mwifiex_pcie_ok_to_access_hw(struct mwifiex_adapter *adapter)
146146
*
147147
* If already not suspended, this function allocates and sends a host
148148
* sleep activate request to the firmware and turns off the traffic.
149+
*
150+
* XXX: ignoring all the above comment and just removes the card to
151+
* fix S0ix and "AP scanning (sometimes) not working after suspend".
152+
* Required code is extracted from mwifiex_pcie_remove().
149153
*/
150154
static int mwifiex_pcie_suspend(struct device *dev)
151155
{
156+
struct pci_dev *pdev = to_pci_dev(dev);
157+
struct pcie_service_card *card = pci_get_drvdata(pdev);
152158
struct mwifiex_adapter *adapter;
153-
struct pcie_service_card *card = dev_get_drvdata(dev);
154-
159+
struct mwifiex_private *priv;
160+
const struct mwifiex_pcie_card_reg *reg;
161+
u32 fw_status;
162+
int ret;
155163

156164
/* Might still be loading firmware */
157165
wait_for_completion(&card->fw_done);
158166

159167
adapter = card->adapter;
160-
if (!adapter) {
161-
dev_err(dev, "adapter is not valid\n");
168+
if (!adapter || !adapter->priv_num)
162169
return 0;
163-
}
164170

165-
mwifiex_enable_wake(adapter);
171+
reg = card->pcie.reg;
172+
if (reg)
173+
ret = mwifiex_read_reg(adapter, reg->fw_status, &fw_status);
174+
else
175+
fw_status = -1;
176+
177+
if (fw_status == FIRMWARE_READY_PCIE && !adapter->mfg_mode) {
178+
mwifiex_deauthenticate_all(adapter);
179+
180+
priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
166181

167-
/* Enable the Host Sleep */
168-
if (!mwifiex_enable_hs(adapter)) {
169-
mwifiex_dbg(adapter, ERROR,
170-
"cmd: failed to suspend\n");
171-
clear_bit(MWIFIEX_IS_HS_ENABLING, &adapter->work_flags);
172-
mwifiex_disable_wake(adapter);
173-
return -EFAULT;
174-
}
182+
mwifiex_disable_auto_ds(priv);
175183

176-
flush_workqueue(adapter->workqueue);
184+
mwifiex_init_shutdown_fw(priv, MWIFIEX_FUNC_SHUTDOWN);
185+
}
177186

178-
/* Indicate device suspended */
179-
set_bit(MWIFIEX_IS_SUSPENDED, &adapter->work_flags);
180-
clear_bit(MWIFIEX_IS_HS_ENABLING, &adapter->work_flags);
187+
mwifiex_remove_card(adapter);
181188

182189
return 0;
183190
}
@@ -189,31 +196,35 @@ static int mwifiex_pcie_suspend(struct device *dev)
189196
*
190197
* If already not resumed, this function turns on the traffic and
191198
* sends a host sleep cancel request to the firmware.
199+
*
200+
* XXX: ignoring all the above comment and probes the card that was
201+
* removed on suspend. Required code is extracted from mwifiex_pcie_probe().
192202
*/
193203
static int mwifiex_pcie_resume(struct device *dev)
194204
{
195-
struct mwifiex_adapter *adapter;
196-
struct pcie_service_card *card = dev_get_drvdata(dev);
205+
struct pci_dev *pdev = to_pci_dev(dev);
206+
struct pcie_service_card *card = pci_get_drvdata(pdev);
207+
int ret;
197208

209+
pr_debug("info: vendor=0x%4.04X device=0x%4.04X rev=%d\n",
210+
pdev->vendor, pdev->device, pdev->revision);
198211

199-
if (!card->adapter) {
200-
dev_err(dev, "adapter structure is not valid\n");
201-
return 0;
202-
}
212+
init_completion(&card->fw_done);
203213

204-
adapter = card->adapter;
214+
card->dev = pdev;
205215

206-
if (!test_bit(MWIFIEX_IS_SUSPENDED, &adapter->work_flags)) {
207-
mwifiex_dbg(adapter, WARN,
208-
"Device already resumed\n");
209-
return 0;
216+
/* device tree node parsing and platform specific configuration */
217+
if (pdev->dev.of_node) {
218+
ret = mwifiex_pcie_probe_of(&pdev->dev);
219+
if (ret)
220+
return ret;
210221
}
211222

212-
clear_bit(MWIFIEX_IS_SUSPENDED, &adapter->work_flags);
213-
214-
mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
215-
MWIFIEX_ASYNC_CMD);
216-
mwifiex_disable_wake(adapter);
223+
if (mwifiex_add_card(card, &card->fw_done, &pcie_ops,
224+
MWIFIEX_PCIE, &pdev->dev)) {
225+
pr_err("%s failed\n", __func__);
226+
return -1;
227+
}
217228

218229
return 0;
219230
}

0 commit comments

Comments
 (0)