Skip to content

Commit a3ccc7d

Browse files
committed
rtw88: Update code to match 2021 dec 20 version of wireless-testing-next
This code will appear in kernel 5.16. The main change is entitled "Disable PCIe ASPM while doing NAPI poll on 8821CE". For some users, this fix will prevcent the system getting bogged down while doing NAPI. The commit message for this patch is as follows Many Intel based platforms face system random freeze after commit 9e2fd29864c5 ("rtw88: add napi support"). The commit itself shouldn't be the culprit. My guess is that the 8821CE only leaves ASPM L1 for a short period when IRQ is raised. Since IRQ is masked during NAPI polling, the PCIe link stays at L1 and makes RX DMA extremely slow. Eventually the RX ring becomes messed up: [ 1133.194697] rtw_8821ce 0000:02:00.0: pci bus timeout, check dma status Since the 8821CE hardware may fail to leave ASPM L1, manually do it in the driver to resolve the issue. Signed-off-by: Larry Finger <[email protected]>
1 parent f9a0cba commit a3ccc7d

File tree

12 files changed

+105
-63
lines changed

12 files changed

+105
-63
lines changed

bf.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,8 @@ void rtw_bf_cfg_sounding(struct rtw_dev *rtwdev, struct rtw_vif *vif,
130130
BIT_WMAC_USE_NDPARATE |
131131
(csi_rsc << 13);
132132

133-
rtw_write8(rtwdev, REG_SND_PTCL_CTRL, RTW_SND_CTRL_SOUNDING);
133+
rtw_write8_mask(rtwdev, REG_SND_PTCL_CTRL, BIT_MASK_BEAMFORM,
134+
RTW_SND_CTRL_SOUNDING);
134135
rtw_write8(rtwdev, REG_SND_PTCL_CTRL + 3, 0x26);
135136
rtw_write8_clr(rtwdev, REG_RXFLTMAP1, BIT_RXFLTMAP1_BF_REPORT_POLL);
136137
rtw_write8_clr(rtwdev, REG_RXFLTMAP4, BIT_RXFLTMAP4_BF_REPORT_POLL);
@@ -177,7 +178,7 @@ void rtw_bf_del_bfer_entry_mu(struct rtw_dev *rtwdev)
177178

178179
void rtw_bf_del_sounding(struct rtw_dev *rtwdev)
179180
{
180-
rtw_write8(rtwdev, REG_SND_PTCL_CTRL, 0);
181+
rtw_write8_mask(rtwdev, REG_SND_PTCL_CTRL, BIT_MASK_BEAMFORM, 0);
181182
}
182183

183184
void rtw_bf_enable_bfee_su(struct rtw_dev *rtwdev, struct rtw_vif *vif,
@@ -204,7 +205,8 @@ void rtw_bf_enable_bfee_su(struct rtw_dev *rtwdev, struct rtw_vif *vif,
204205
}
205206

206207
/* Sounding protocol control */
207-
rtw_write8(rtwdev, REG_SND_PTCL_CTRL, RTW_SND_CTRL_SOUNDING);
208+
rtw_write8_mask(rtwdev, REG_SND_PTCL_CTRL, BIT_MASK_BEAMFORM,
209+
RTW_SND_CTRL_SOUNDING);
208210

209211
/* MAC address/Partial AID of Beamformer */
210212
for (i = 0; i < ETH_ALEN; i++)
@@ -273,7 +275,8 @@ void rtw_bf_remove_bfee_su(struct rtw_dev *rtwdev,
273275
struct rtw_bf_info *bfinfo = &rtwdev->bf_info;
274276

275277
rtw_dbg(rtwdev, RTW_DBG_BF, "remove as a su bfee\n");
276-
rtw_write8(rtwdev, REG_SND_PTCL_CTRL, RTW_SND_CTRL_REMOVE);
278+
rtw_write8_mask(rtwdev, REG_SND_PTCL_CTRL, BIT_MASK_BEAMFORM,
279+
RTW_SND_CTRL_REMOVE);
277280

278281
switch (bfee->su_reg_index) {
279282
case 0:
@@ -298,7 +301,8 @@ void rtw_bf_remove_bfee_mu(struct rtw_dev *rtwdev,
298301
{
299302
struct rtw_bf_info *bfinfo = &rtwdev->bf_info;
300303

301-
rtw_write8(rtwdev, REG_SND_PTCL_CTRL, RTW_SND_CTRL_REMOVE);
304+
rtw_write8_mask(rtwdev, REG_SND_PTCL_CTRL, BIT_MASK_BEAMFORM,
305+
RTW_SND_CTRL_REMOVE);
302306

303307
rtw_bf_del_bfer_entry_mu(rtwdev);
304308

bf.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
#define REG_ASSOCIATED_BFMER1_INFO 0x06EC
1414
#define REG_TX_CSI_RPT_PARAM_BW20 0x06F4
1515
#define REG_SND_PTCL_CTRL 0x0718
16+
#define BIT_DIS_CHK_VHTSIGB_CRC BIT(6)
17+
#define BIT_DIS_CHK_VHTSIGA_CRC BIT(5)
18+
#define BIT_MASK_BEAMFORM (GENMASK(4, 0) | BIT(7))
1619
#define REG_MU_TX_CTL 0x14C0
1720
#define REG_MU_STA_GID_VLD 0x14C4
1821
#define REG_MU_STA_USER_POS_INFO 0x14C8
@@ -42,8 +45,8 @@
4245
#define BIT_RXFLTMAP4_BF_REPORT_POLL BIT(4)
4346

4447
#define RTW_NDP_RX_STANDBY_TIME 0x70
45-
#define RTW_SND_CTRL_REMOVE 0xD8
46-
#define RTW_SND_CTRL_SOUNDING 0xDB
48+
#define RTW_SND_CTRL_REMOVE 0x98
49+
#define RTW_SND_CTRL_SOUNDING 0x9B
4750

4851
enum csi_seg_len {
4952
HAL_CSI_SEG_4K = 0,

debug.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,22 @@ static int rtw_debugfs_get_rf_read(struct seq_file *m, void *v)
152152
return 0;
153153
}
154154

155+
static int rtw_debugfs_get_fix_rate(struct seq_file *m, void *v)
156+
{
157+
struct rtw_debugfs_priv *debugfs_priv = m->private;
158+
struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
159+
struct rtw_dm_info *dm_info = &rtwdev->dm_info;
160+
u8 fix_rate = dm_info->fix_rate;
161+
162+
if (fix_rate >= DESC_RATE_MAX) {
163+
seq_printf(m, "Fix rate disabled, fix_rate = %u\n", fix_rate);
164+
return 0;
165+
}
166+
167+
seq_printf(m, "Data frames fixed at desc rate %u\n", fix_rate);
168+
return 0;
169+
}
170+
155171
static int rtw_debugfs_copy_from_user(char tmp[], int size,
156172
const char __user *buffer, size_t count,
157173
int num)
@@ -437,6 +453,31 @@ static ssize_t rtw_debugfs_set_rf_read(struct file *filp,
437453
return count;
438454
}
439455

456+
static ssize_t rtw_debugfs_set_fix_rate(struct file *filp,
457+
const char __user *buffer,
458+
size_t count, loff_t *loff)
459+
{
460+
struct seq_file *seqpriv = (struct seq_file *)filp->private_data;
461+
struct rtw_debugfs_priv *debugfs_priv = seqpriv->private;
462+
struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
463+
struct rtw_dm_info *dm_info = &rtwdev->dm_info;
464+
u8 fix_rate;
465+
char tmp[32 + 1];
466+
int ret;
467+
468+
rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1);
469+
470+
ret = kstrtou8(tmp, 0, &fix_rate);
471+
if (ret) {
472+
rtw_warn(rtwdev, "invalid args, [rate]\n");
473+
return ret;
474+
}
475+
476+
dm_info->fix_rate = fix_rate;
477+
478+
return count;
479+
}
480+
440481
static int rtw_debug_get_mac_page(struct seq_file *m, void *v)
441482
{
442483
struct rtw_debugfs_priv *debugfs_priv = m->private;
@@ -590,6 +631,8 @@ static int rtw_debugfs_get_tx_pwr_tbl(struct seq_file *m, void *v)
590631
u8 ch = hal->current_channel;
591632
u8 regd = rtw_regd_get(rtwdev);
592633

634+
seq_printf(m, "channel: %u\n", ch);
635+
seq_printf(m, "bandwidth: %u\n", bw);
593636
seq_printf(m, "regulatory: %s\n", rtw_get_regd_string(regd));
594637
seq_printf(m, "%-4s %-10s %-3s%6s %-4s %4s (%-4s %-4s) %-4s\n",
595638
"path", "rate", "pwr", "", "base", "", "byr", "lmt", "rem");
@@ -1094,6 +1137,11 @@ static struct rtw_debugfs_priv rtw_debug_priv_read_reg = {
10941137
.cb_read = rtw_debugfs_get_read_reg,
10951138
};
10961139

1140+
static struct rtw_debugfs_priv rtw_debug_priv_fix_rate = {
1141+
.cb_write = rtw_debugfs_set_fix_rate,
1142+
.cb_read = rtw_debugfs_get_fix_rate,
1143+
};
1144+
10971145
static struct rtw_debugfs_priv rtw_debug_priv_dump_cam = {
10981146
.cb_write = rtw_debugfs_set_single_input,
10991147
.cb_read = rtw_debugfs_get_dump_cam,
@@ -1164,6 +1212,7 @@ void rtw_debugfs_init(struct rtw_dev *rtwdev)
11641212
rtw_debugfs_add_rw(read_reg);
11651213
rtw_debugfs_add_w(rf_write);
11661214
rtw_debugfs_add_rw(rf_read);
1215+
rtw_debugfs_add_rw(fix_rate);
11671216
rtw_debugfs_add_rw(dump_cam);
11681217
rtw_debugfs_add_rw(rsvd_page);
11691218
rtw_debugfs_add_r(phy_info);

main.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1868,13 +1868,14 @@ int rtw_core_init(struct rtw_dev *rtwdev)
18681868

18691869
rtwdev->sec.total_cam_num = 32;
18701870
rtwdev->hal.current_channel = 1;
1871+
rtwdev->dm_info.fix_rate = U8_MAX;
18711872
set_bit(RTW_BC_MC_MACID, rtwdev->mac_id_map);
18721873

18731874
rtw_stats_init(rtwdev);
18741875

18751876
/* default rx filter setting */
18761877
rtwdev->hal.rcr = BIT_APP_FCS | BIT_APP_MIC | BIT_APP_ICV |
1877-
BIT_HTC_LOC_CTRL | BIT_APP_PHYSTS |
1878+
BIT_PKTCTL_DLEN | BIT_HTC_LOC_CTRL | BIT_APP_PHYSTS |
18781879
BIT_AB | BIT_AM | BIT_APM;
18791880

18801881
ret = rtw_load_firmware(rtwdev, RTW_NORMAL_FW);

main.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1726,6 +1726,7 @@ struct rtw_dm_info {
17261726
u8 cck_gi_u_bnd;
17271727
u8 cck_gi_l_bnd;
17281728

1729+
u8 fix_rate;
17291730
u8 tx_rate;
17301731
u32 rrsr_val_init;
17311732
u32 rrsr_mask_min;

pci.c

Lines changed: 19 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
/* Copyright(c) 2018-2019 Realtek Corporation
33
*/
44

5-
#include <linux/dmi.h>
65
#include <linux/module.h>
76
#include <linux/pci.h>
87
#include "main.h"
@@ -1407,7 +1406,11 @@ static void rtw_pci_link_ps(struct rtw_dev *rtwdev, bool enter)
14071406
* throughput. This is probably because the ASPM behavior slightly
14081407
* varies from different SOC.
14091408
*/
1410-
if (rtwpci->link_ctrl & PCI_EXP_LNKCTL_ASPM_L1)
1409+
if (!(rtwpci->link_ctrl & PCI_EXP_LNKCTL_ASPM_L1))
1410+
return;
1411+
1412+
if ((enter && atomic_dec_if_positive(&rtwpci->link_usage) == 0) ||
1413+
(!enter && atomic_inc_return(&rtwpci->link_usage) == 1))
14111414
rtw_pci_aspm_set(rtwdev, enter);
14121415
}
14131416

@@ -1656,6 +1659,9 @@ static int rtw_pci_napi_poll(struct napi_struct *napi, int budget)
16561659
priv);
16571660
int work_done = 0;
16581661

1662+
if (rtwpci->rx_no_aspm)
1663+
rtw_pci_link_ps(rtwdev, false);
1664+
16591665
while (work_done < budget) {
16601666
u32 work_done_once;
16611667

@@ -1679,6 +1685,8 @@ static int rtw_pci_napi_poll(struct napi_struct *napi, int budget)
16791685
if (rtw_pci_get_hw_rx_ring_nr(rtwdev, rtwpci))
16801686
napi_schedule(napi);
16811687
}
1688+
if (rtwpci->rx_no_aspm)
1689+
rtw_pci_link_ps(rtwdev, true);
16821690

16831691
return work_done;
16841692
}
@@ -1700,59 +1708,13 @@ static void rtw_pci_napi_deinit(struct rtw_dev *rtwdev)
17001708
netif_napi_del(&rtwpci->napi);
17011709
}
17021710

1703-
enum rtw88_quirk_dis_pci_caps {
1704-
QUIRK_DIS_PCI_CAP_MSI,
1705-
QUIRK_DIS_PCI_CAP_ASPM,
1706-
};
1707-
1708-
static int disable_pci_caps(const struct dmi_system_id *dmi)
1709-
{
1710-
uintptr_t dis_caps = (uintptr_t)dmi->driver_data;
1711-
1712-
if (dis_caps & BIT(QUIRK_DIS_PCI_CAP_MSI))
1713-
rtw_disable_msi = true;
1714-
if (dis_caps & BIT(QUIRK_DIS_PCI_CAP_ASPM))
1715-
rtw_pci_disable_aspm = true;
1716-
1717-
return 1;
1718-
}
1719-
1720-
static const struct dmi_system_id rtw88_pci_quirks[] = {
1721-
{
1722-
.callback = disable_pci_caps,
1723-
.ident = "Protempo Ltd L116HTN6SPW",
1724-
.matches = {
1725-
DMI_MATCH(DMI_SYS_VENDOR, "Protempo Ltd"),
1726-
DMI_MATCH(DMI_PRODUCT_NAME, "L116HTN6SPW"),
1727-
},
1728-
.driver_data = (void *)BIT(QUIRK_DIS_PCI_CAP_ASPM),
1729-
},
1730-
{
1731-
.callback = disable_pci_caps,
1732-
.ident = "HP HP Pavilion Laptop 14-ce0xxx",
1733-
.matches = {
1734-
DMI_MATCH(DMI_SYS_VENDOR, "HP"),
1735-
DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Laptop 14-ce0xxx"),
1736-
},
1737-
.driver_data = (void *)BIT(QUIRK_DIS_PCI_CAP_ASPM),
1738-
},
1739-
{
1740-
.callback = disable_pci_caps,
1741-
.ident = "HP HP 250 G7 Notebook PC",
1742-
.matches = {
1743-
DMI_MATCH(DMI_SYS_VENDOR, "HP"),
1744-
DMI_MATCH(DMI_PRODUCT_NAME, "HP 250 G7 Notebook PC"),
1745-
},
1746-
.driver_data = (void *)BIT(QUIRK_DIS_PCI_CAP_ASPM),
1747-
},
1748-
{}
1749-
};
1750-
17511711
int rtw_pci_probe(struct pci_dev *pdev,
17521712
const struct pci_device_id *id)
17531713
{
1714+
struct pci_dev *bridge = pci_upstream_bridge(pdev);
17541715
struct ieee80211_hw *hw;
17551716
struct rtw_dev *rtwdev;
1717+
struct rtw_pci *rtwpci;
17561718
int drv_data_size;
17571719
int ret;
17581720

@@ -1770,6 +1732,9 @@ int rtw_pci_probe(struct pci_dev *pdev,
17701732
rtwdev->hci.ops = &rtw_pci_ops;
17711733
rtwdev->hci.type = RTW_HCI_TYPE_PCIE;
17721734

1735+
rtwpci = (struct rtw_pci *)rtwdev->priv;
1736+
atomic_set(&rtwpci->link_usage, 1);
1737+
17731738
ret = rtw_core_init(rtwdev);
17741739
if (ret)
17751740
goto err_release_hw;
@@ -1798,7 +1763,10 @@ int rtw_pci_probe(struct pci_dev *pdev,
17981763
goto err_destroy_pci;
17991764
}
18001765

1801-
dmi_check_system(rtw88_pci_quirks);
1766+
/* Disable PCIe ASPM L1 while doing NAPI poll for 8821CE */
1767+
if (pdev->device == 0xc821 && bridge->vendor == PCI_VENDOR_ID_INTEL)
1768+
rtwpci->rx_no_aspm = true;
1769+
18021770
rtw_pci_phy_cfg(rtwdev);
18031771

18041772
ret = rtw_register_hw(rtwdev, hw);

pci.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,8 @@ struct rtw_pci {
223223
struct rtw_pci_tx_ring tx_rings[RTK_MAX_TX_QUEUE_NUM];
224224
struct rtw_pci_rx_ring rx_rings[RTK_MAX_RX_QUEUE_NUM];
225225
u16 link_ctrl;
226+
atomic_t link_usage;
227+
bool rx_no_aspm;
226228
DECLARE_BITMAP(flags, NUM_OF_RTW_PCI_FLAGS);
227229

228230
void __iomem *mmap;

rtw8821c.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,8 @@ static int rtw8821c_mac_init(struct rtw_dev *rtwdev)
223223
rtw_write8(rtwdev, REG_TCR + 1, WLAN_TX_FUNC_CFG1);
224224
rtw_write8(rtwdev, REG_ACKTO_CCK, 0x40);
225225
rtw_write8_set(rtwdev, REG_WMAC_TRXPTCL_CTL_H, BIT(1));
226-
rtw_write8_set(rtwdev, REG_SND_PTCL_CTRL, BIT(6));
226+
rtw_write8_set(rtwdev, REG_SND_PTCL_CTRL,
227+
BIT_DIS_CHK_VHTSIGB_CRC);
227228
rtw_write32(rtwdev, REG_WMAC_OPTION_FUNCTION + 8, WLAN_MAC_OPT_FUNC2);
228229
rtw_write8(rtwdev, REG_WMAC_OPTION_FUNCTION + 4, WLAN_MAC_OPT_NORM_FUNC1);
229230

rtw8821c.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ _rtw_write32s_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 data)
131131
#define WLAN_TX_FUNC_CFG2 0x30
132132
#define WLAN_MAC_OPT_NORM_FUNC1 0x98
133133
#define WLAN_MAC_OPT_LB_FUNC1 0x80
134-
#define WLAN_MAC_OPT_FUNC2 0x30810041
134+
#define WLAN_MAC_OPT_FUNC2 0xb0810041
135135

136136
#define WLAN_SIFS_CFG (WLAN_SIFS_CCK_CONT_TX | \
137137
(WLAN_SIFS_OFDM_CONT_TX << BIT_SHIFT_SIFS_OFDM_CTX) | \

rtw8822b.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ static void rtw8822b_phy_set_param(struct rtw_dev *rtwdev)
205205
#define WLAN_TX_FUNC_CFG2 0x30
206206
#define WLAN_MAC_OPT_NORM_FUNC1 0x98
207207
#define WLAN_MAC_OPT_LB_FUNC1 0x80
208-
#define WLAN_MAC_OPT_FUNC2 0x30810041
208+
#define WLAN_MAC_OPT_FUNC2 0xb0810041
209209

210210
#define WLAN_SIFS_CFG (WLAN_SIFS_CCK_CONT_TX | \
211211
(WLAN_SIFS_OFDM_CONT_TX << BIT_SHIFT_SIFS_OFDM_CTX) | \
@@ -262,6 +262,8 @@ static int rtw8822b_mac_init(struct rtw_dev *rtwdev)
262262
rtw_write8(rtwdev, REG_TCR + 1, WLAN_TX_FUNC_CFG1);
263263
rtw_write32(rtwdev, REG_WMAC_OPTION_FUNCTION + 8, WLAN_MAC_OPT_FUNC2);
264264
rtw_write8(rtwdev, REG_WMAC_OPTION_FUNCTION + 4, WLAN_MAC_OPT_NORM_FUNC1);
265+
rtw_write8_set(rtwdev, REG_SND_PTCL_CTRL,
266+
BIT_DIS_CHK_VHTSIGB_CRC);
265267

266268
return 0;
267269
}

0 commit comments

Comments
 (0)