| From c713fb071edc0efc01a955f65a006b0e1795d2eb Mon Sep 17 00:00:00 2001 |
| From: Larry Finger <Larry.Finger@lwfinger.net> |
| Date: Mon, 5 Feb 2018 12:38:11 -0600 |
| Subject: rtlwifi: rtl8821ae: Fix connection lost problem correctly |
| |
| From: Larry Finger <Larry.Finger@lwfinger.net> |
| |
| commit c713fb071edc0efc01a955f65a006b0e1795d2eb upstream. |
| |
| There has been a coding error in rtl8821ae since it was first introduced, |
| namely that an 8-bit register was read using a 16-bit read in |
| _rtl8821ae_dbi_read(). This error was fixed with commit 40b368af4b75 |
| ("rtlwifi: Fix alignment issues"); however, this change led to |
| instability in the connection. To restore stability, this change |
| was reverted in commit b8b8b16352cd ("rtlwifi: rtl8821ae: Fix connection |
| lost problem"). |
| |
| Unfortunately, the unaligned access causes machine checks in ARM |
| architecture, and we were finally forced to find the actual cause of the |
| problem on x86 platforms. Following a suggestion from Pkshih |
| <pkshih@realtek.com>, it was found that increasing the ASPM L1 |
| latency from 0 to 7 fixed the instability. This parameter was varied to |
| see if a smaller value would work; however, it appears that 7 is the |
| safest value. A new symbol is defined for this quantity, thus it can be |
| easily changed if necessary. |
| |
| Fixes: b8b8b16352cd ("rtlwifi: rtl8821ae: Fix connection lost problem") |
| Cc: Stable <stable@vger.kernel.org> # 4.14+ |
| Fix-suggested-by: Pkshih <pkshih@realtek.com> |
| Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net> |
| Tested-by: James Cameron <quozl@laptop.org> # x86_64 OLPC NL3 |
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c | 5 +++-- |
| drivers/net/wireless/realtek/rtlwifi/wifi.h | 1 + |
| 2 files changed, 4 insertions(+), 2 deletions(-) |
| |
| --- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c |
| +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c |
| @@ -1127,7 +1127,7 @@ static u8 _rtl8821ae_dbi_read(struct rtl |
| } |
| if (0 == tmp) { |
| read_addr = REG_DBI_RDATA + addr % 4; |
| - ret = rtl_read_word(rtlpriv, read_addr); |
| + ret = rtl_read_byte(rtlpriv, read_addr); |
| } |
| return ret; |
| } |
| @@ -1169,7 +1169,8 @@ static void _rtl8821ae_enable_aspm_back_ |
| } |
| |
| tmp = _rtl8821ae_dbi_read(rtlpriv, 0x70f); |
| - _rtl8821ae_dbi_write(rtlpriv, 0x70f, tmp | BIT(7)); |
| + _rtl8821ae_dbi_write(rtlpriv, 0x70f, tmp | BIT(7) | |
| + ASPM_L1_LATENCY << 3); |
| |
| tmp = _rtl8821ae_dbi_read(rtlpriv, 0x719); |
| _rtl8821ae_dbi_write(rtlpriv, 0x719, tmp | BIT(3) | BIT(4)); |
| --- a/drivers/net/wireless/realtek/rtlwifi/wifi.h |
| +++ b/drivers/net/wireless/realtek/rtlwifi/wifi.h |
| @@ -99,6 +99,7 @@ |
| #define RTL_USB_MAX_RX_COUNT 100 |
| #define QBSS_LOAD_SIZE 5 |
| #define MAX_WMMELE_LENGTH 64 |
| +#define ASPM_L1_LATENCY 7 |
| |
| #define TOTAL_CAM_ENTRY 32 |
| |