mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-22 19:22:28 +07:00
rtlwifi: rtl8821ae: Fix system lockups on boot
In commit1277fa2ab2
("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:1277fa2ab2
("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+] Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
This commit is contained in:
parent
76d164f582
commit
54328e6404
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user