linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] rtlwifi: rtl8821ae: Fix system lockups on boot
@ 2015-10-02 16:44 Larry Finger
  2015-10-03  6:44 ` Kalle Valo
  0 siblings, 1 reply; 2+ messages in thread
From: Larry Finger @ 2015-10-02 16:44 UTC (permalink / raw)
  To: kvalo; +Cc: devel, linux-wireless, Larry Finger, Stable

In commit 1277fa2ab2f9, the code that cleared all interrupt enable
bits before setting them was removed for all PCI drivers. This fixed an
issue that caused TX to be blocked for 3-5 seconds. On some RTL8821AE units,
this change causes soft lockups to occur on boot. For that reason, the portion
of the earlier commit that applied to rtl8821ae is reverted. Kernels 4.1 and
newer are affected.

See http://marc.info/?l=linux-wireless&m=144373370103285&w=2 and
https://bugzilla.opensuse.org/show_bug.cgi?id=944978 for two cases where
this regression affected user systems. Note that this bug does not appear on
any of the developer's setups. For those users whose systems are affected
by the TX blockage, but do not lock up on boot, a module parameter is added
to disable the interrupt clear

Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Cc: Stable <stable@vger.kernel.org> [V4.1+]
---

Kalle,

If possible, please send this patch upstream for inclusion in kernel 4.3.
As noted, the bug affects kernels 4.1 and newer.

This patch applies to wireless-drivers-next, and assumes that the patch that
moved all the Realtek drivers into drivers/net/wireless/realtek has NOT been
applied.

Thanks,

Larry
---
 drivers/net/wireless/rtlwifi/pci.h          |  2 ++
 drivers/net/wireless/rtlwifi/rtl8821ae/hw.c | 17 +++++++++++++++++
 drivers/net/wireless/rtlwifi/rtl8821ae/sw.c |  5 +++++
 drivers/net/wireless/rtlwifi/wifi.h         |  3 +++
 4 files changed, 27 insertions(+)

diff --git a/drivers/net/wireless/rtlwifi/pci.h b/drivers/net/wireless/rtlwifi/pci.h
index d4567d1..5da6703 100644
--- a/drivers/net/wireless/rtlwifi/pci.h
+++ b/drivers/net/wireless/rtlwifi/pci.h
@@ -247,6 +247,8 @@ struct rtl_pci {
 	/* MSI support */
 	bool msi_support;
 	bool using_msi;
+	/* interrupt clear before set */
+	bool int_clear;
 };
 
 struct mp_adapter {
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/hw.c b/drivers/net/wireless/rtlwifi/rtl8821ae/hw.c
index b7f18e21..6e9418e 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8821ae/hw.c
@@ -2253,11 +2253,28 @@ void rtl8821ae_set_qos(struct ieee80211_hw *hw, int aci)
 	}
 }
 
+static void rtl8821ae_clear_interrupt(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	u32 tmp = rtl_read_dword(rtlpriv, REG_HISR);
+
+	rtl_write_dword(rtlpriv, REG_HISR, tmp);
+
+	tmp = rtl_read_dword(rtlpriv, REG_HISRE);
+	rtl_write_dword(rtlpriv, REG_HISRE, tmp);
+
+	tmp = rtl_read_dword(rtlpriv, REG_HSISR);
+	rtl_write_dword(rtlpriv, REG_HSISR, tmp);
+}
+
 void rtl8821ae_enable_interrupt(struct ieee80211_hw *hw)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 
+	if (!rtlpci->int_clear)
+		rtl8821ae_clear_interrupt(hw);/*clear it here first*/
+
 	rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF);
 	rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & 0xFFFFFFFF);
 	rtlpci->irq_enabled = true;
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/sw.c b/drivers/net/wireless/rtlwifi/rtl8821ae/sw.c
index a4988121..8ee141a 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8821ae/sw.c
@@ -96,6 +96,7 @@ int rtl8821ae_init_sw_vars(struct ieee80211_hw *hw)
 
 	rtl8821ae_bt_reg_init(hw);
 	rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support;
+	rtlpci->int_clear = rtlpriv->cfg->mod_params->int_clear;
 	rtlpriv->btcoexist.btc_ops = rtl_btc_get_ops_pointer();
 
 	rtlpriv->dm.dm_initialgain_enable = 1;
@@ -167,6 +168,7 @@ int rtl8821ae_init_sw_vars(struct ieee80211_hw *hw)
 	rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
 	rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps;
 	rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support;
+	rtlpci->msi_support = rtlpriv->cfg->mod_params->int_clear;
 	if (rtlpriv->cfg->mod_params->disable_watchdog)
 		pr_info("watchdog disabled\n");
 	rtlpriv->psc.reg_fwctrl_lps = 3;
@@ -308,6 +310,7 @@ static struct rtl_mod_params rtl8821ae_mod_params = {
 	.swctrl_lps = false,
 	.fwctrl_lps = true,
 	.msi_support = true,
+	.int_clear = true,
 	.debug = DBG_EMERG,
 	.disable_watchdog = 0,
 };
@@ -437,6 +440,7 @@ module_param_named(fwlps, rtl8821ae_mod_params.fwctrl_lps, bool, 0444);
 module_param_named(msi, rtl8821ae_mod_params.msi_support, bool, 0444);
 module_param_named(disable_watchdog, rtl8821ae_mod_params.disable_watchdog,
 		   bool, 0444);
+module_param_named(int_clear, rtl8821ae_mod_params.int_clear, bool, 0444);
 MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n");
 MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n");
 MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
@@ -444,6 +448,7 @@ MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n");
 MODULE_PARM_DESC(msi, "Set to 1 to use MSI interrupts mode (default 1)\n");
 MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
 MODULE_PARM_DESC(disable_watchdog, "Set to 1 to disable the watchdog (default 0)\n");
+MODULE_PARM_DESC(int_clear, "Set to 1 to disable interrupt clear before set (default 0)\n");
 
 static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume);
 
diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h
index b90ca61..4544752 100644
--- a/drivers/net/wireless/rtlwifi/wifi.h
+++ b/drivers/net/wireless/rtlwifi/wifi.h
@@ -2249,6 +2249,9 @@ struct rtl_mod_params {
 
 	/* default 0: 1 means disable */
 	bool disable_watchdog;
+
+	/* default 0: 1 means do not disable interrupts */
+	bool int_clear;
 };
 
 struct rtl_hal_usbint_cfg {
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: rtlwifi: rtl8821ae: Fix system lockups on boot
  2015-10-02 16:44 [PATCH] rtlwifi: rtl8821ae: Fix system lockups on boot Larry Finger
@ 2015-10-03  6:44 ` Kalle Valo
  0 siblings, 0 replies; 2+ messages in thread
From: Kalle Valo @ 2015-10-03  6:44 UTC (permalink / raw)
  To: Larry Finger; +Cc: devel, linux-wireless, Larry Finger, Stable


> In commit 1277fa2ab2f9 ("rtlwifi: Remove the clear interrupt routine from all
> drivers"), the code that cleared all interrupt enable bits before setting them
> was removed for all PCI drivers. This fixed an issue that caused TX to be
> blocked for 3-5 seconds. On some RTL8821AE units, this change causes soft
> lockups to occur on boot. For that reason, the portion of the earlier commit
> that applied to rtl8821ae is reverted. Kernels 4.1 and newer are affected.
> 
> See http://marc.info/?l=linux-wireless&m=144373370103285&w=2 and
> https://bugzilla.opensuse.org/show_bug.cgi?id=944978 for two cases where
> this regression affected user systems. Note that this bug does not appear on
> any of the developer's setups. For those users whose systems are affected
> by the TX blockage, but do not lock up on boot, a module parameter is added
> to disable the interrupt clear
> 
> Fixes: 1277fa2ab2f9 ("rtlwifi: Remove the clear interrupt routine from all drivers")
> Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
> Cc: Stable <stable@vger.kernel.org> [V4.1+]

Thanks, applied to wireless-drivers.git.

Kalle Valo

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2015-10-03  6:44 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-10-02 16:44 [PATCH] rtlwifi: rtl8821ae: Fix system lockups on boot Larry Finger
2015-10-03  6:44 ` Kalle Valo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).