Subject: Re: [PATCH] wifi: mt76: Stop unmapping all buffers when WED not present

From: Lorenzo Bianconi <[email-masked]>
Date: Thu, 12 Jan 2023 18:23:54 +0100

> Before the introduction of WED RX support, this driver was resetting
> buf0 and the TXWI pointer only on the head of the passed queue but
> now it's doing that on all buffers: while this is fine on systems
> that are not relying on IOMMU, such as the MT8192 Asurada Spherion
> Chromebook (MT7921E), it causes a crash on others using IOMMUs, such
> as the MT8195 Cherry Tomato Chromebook (MT7921E again!).
> 
> Reverting to the described behavior solves the following kernel panic:
> 
> [   20.357772] Unable to handle kernel paging request at virtual address ffff170fc0000000
> [   20.365943] Mem abort info:
> [   20.368989]   ESR = 0x0000000096000145
> [   20.372988]   EC = 0x25: DABT (current EL), IL = 32 bits
> [   20.378551]   SET = 0, FnV = 0
> [   20.381857]   EA = 0, S1PTW = 0
> [   20.385248]   FSC = 0x05: level 1 translation fault
> [   20.390376] Data abort info:
> [   20.393507]   ISV = 0, ISS = 0x00000145
> [   20.397593]   CM = 1, WnR = 1
> [   20.400811] swapper pgtable: 4k pages, 48-bit VAs, pgdp=0000000041fb3000
> [   20.407763] [ffff170fc0000000] pgd=180000023fff7003, p4d=180000023fff7003, pud=0000000000000000
> [   20.416714] Internal error: Oops: 0000000096000145 [#1] SMP
> [   20.422535] Modules linked in: af_alg qrtr mt7921e mt7921_common mt76_connac_lib mt76 mac80211 btusb btrtl btintel btmtk btbcm 8021q cfg80211 bluetooth uvcvideo garp mrp snd_sof_ipc_msg_injector snd_sof_ipc_flood_test stp snd_sof_mt8195 videobuf2_vmalloc llc panfrost cros_ec_sensors cros_ec_lid_angle crct10dif_ce mtk_adsp_common ecdh_generic cros_ec_sensors_core ecc snd_sof_xtensa_dsp gpu_sched rfkill snd_sof_of sbs_battery hid_multitouch cros_usbpd_logger snd_sof snd_sof_utils fuse ipv6
> [   20.465969] CPU: 6 PID: 9 Comm: kworker/u16:0 Tainted: G        W          6.2.0-rc3-next-20230111+ #237
> [   20.475695] Hardware name: Acer Tomato (rev2) board (DT)
> [   20.481254] Workqueue: phy0 ieee80211_iface_work [mac80211]
> [   20.487119] pstate: 80400009 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> [   20.494328] pc : dcache_clean_poc+0x20/0x38
> [   20.498764] lr : arch_sync_dma_for_device+0x2c/0x40
> [   20.503893] sp : ffff8000080cb430
> [   20.507457] x29: ffff8000080cb430 x28: 0000000000000000 x27: ffff1710c740e0d0
> [   20.514842] x26: ffff1710d8c03b38 x25: ffff1710d75e4fb0 x24: ffff1710c619e280
> [   20.522225] x23: ffff8000080cb578 x22: 0000000000000001 x21: 0000000000000040
> [   20.529608] x20: 0000000000000000 x19: ffff1710c740e0d0 x18: 0000000000000030
> [   20.536991] x17: 000000040044ffff x16: ffffc06d4c37d200 x15: ffffffffffffffff
> [   20.544373] x14: 0000000000000000 x13: 0000000000007800 x12: 0000000000000000
> [   20.551755] x11: 0000000000007961 x10: 0000000000007961 x9 : ffffc06d4cbe0ff8
> [   20.559137] x8 : 0000000000000001 x7 : 0000000000008000 x6 : 0000000000000000
> [   20.566518] x5 : 000000000000801e x4 : 0000000054765809 x3 : 000000000000003f
> [   20.573899] x2 : 0000000000000040 x1 : ffff170fc0000040 x0 : ffff170fc0000000
> [   20.581282] Call trace:
> [   20.583976]  dcache_clean_poc+0x20/0x38
> [   20.588061]  iommu_dma_sync_single_for_device+0xc4/0xdc
> [   20.593534]  dma_sync_single_for_device+0x38/0x120
> [   20.598574]  mt76_dma_tx_queue_skb+0x4f4/0x5b0 [mt76]
> [   20.603880]  __mt76_tx_queue_skb+0x5c/0xe0 [mt76]
> [   20.608836]  mt76_tx+0xbc/0x164 [mt76]
> [   20.612838]  mt7921_tx+0x9c/0x170 [mt7921_common]
> [   20.617795]  ieee80211_tx_frags+0x22c/0x2a0 [mac80211]
> [   20.623215]  __ieee80211_tx+0x90/0x1c0 [mac80211]
> [   20.628195]  ieee80211_tx+0x114/0x160 [mac80211]
> [   20.633088]  ieee80211_xmit+0xa0/0xd4 [mac80211]
> [   20.637980]  __ieee80211_tx_skb_tid_band+0xa8/0x2e0 [mac80211]
> [   20.644087]  ieee80211_tx_skb_tid+0xac/0x270 [mac80211]
> [   20.649585]  ieee80211_send_auth+0x1ac/0x250 [mac80211]
> [   20.655080]  ieee80211_auth+0x16c/0x2dc [mac80211]
> [   20.660145]  ieee80211_sta_work+0x3a0/0xab4 [mac80211]
> [   20.665557]  ieee80211_iface_work+0x394/0x400 [mac80211]
> [   20.671144]  process_one_work+0x294/0x674
> [   20.675406]  worker_thread+0x7c/0x45c
> [   20.679316]  kthread+0x104/0x110
> [   20.682793]  ret_from_fork+0x10/0x20
> [   20.686621] Code: d2800082 9ac32042 d1000443 8a230000 (d50b7a20)
> [   20.692962] ---[ end trace 0000000000000000 ]---
> 
> Fixes: cd372b8c99c5 ("wifi: mt76: add WED RX support to mt76_dma_{add,get}_buf")
> Signed-off-by: AngeloGioacchino Del Regno <[email-masked]>
> ---
>  drivers/net/wireless/mediatek/mt76/dma.c | 11 ++++++-----
>  1 file changed, 6 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c
> index 420302ff0328..a0fe3ab0126d 100644
> --- a/drivers/net/wireless/mediatek/mt76/dma.c
> +++ b/drivers/net/wireless/mediatek/mt76/dma.c
> @@ -215,6 +215,12 @@ mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q,
>  	u32 ctrl;
>  	int i, idx = -1;
>  
> +	if (txwi && !(q->flags & MT_QFLAG_WED) &&
> +	    !FIELD_GET(MT_QFLAG_WED_TYPE, q->flags)) {
> +		q->entry[q->head].txwi = DMA_DUMMY_DATA;
> +		q->entry[q->head].skip_buf0 = true;
> +	}
> +
>  	for (i = 0; i < nbufs; i += 2, buf += 2) {
>  		u32 buf0 = buf[0].addr, buf1 = 0;
>  
> @@ -238,11 +244,6 @@ mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q,
>  			ctrl = FIELD_PREP(MT_DMA_CTL_SD_LEN0, buf[0].len) |
>  			       MT_DMA_CTL_TO_HOST;
>  		} else {
> -			if (txwi) {
> -				q->entry[q->head].txwi = DMA_DUMMY_DATA;
> -				q->entry[q->head].skip_buf0 = true;
> -			}
> -
>  			if (buf[0].skip_unmap)
>  				entry->skip_buf0 = true;
>  			entry->skip_buf1 = i == nbufs - 1;
> -- 
> 2.39.0
> 

I think this issue has been already fixed by Felix here:
https://lore.kernel.org/linux-wireless/[email-masked]/

Regards,
Lorenzo