Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

wifi: mt76: wed: use proper wed reference in mt76 wed driver callabacks

MT7996 driver can use both wed and wed_hif2 devices to offload traffic
from/to the wireless NIC. In the current codebase we assume to always
use the primary wed device in wed callbacks resulting in the following
crash if the hw runs wed_hif2 (e.g. 6GHz link).

[ 297.455876] Unable to handle kernel read from unreadable memory at virtual address 000000000000080a
[ 297.464928] Mem abort info:
[ 297.467722] ESR = 0x0000000096000005
[ 297.471461] EC = 0x25: DABT (current EL), IL = 32 bits
[ 297.476766] SET = 0, FnV = 0
[ 297.479809] EA = 0, S1PTW = 0
[ 297.482940] FSC = 0x05: level 1 translation fault
[ 297.487809] Data abort info:
[ 297.490679] ISV = 0, ISS = 0x00000005, ISS2 = 0x00000000
[ 297.496156] CM = 0, WnR = 0, TnD = 0, TagAccess = 0
[ 297.501196] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
[ 297.506500] user pgtable: 4k pages, 39-bit VAs, pgdp=0000000107480000
[ 297.512927] [000000000000080a] pgd=08000001097fb003, p4d=08000001097fb003, pud=08000001097fb003, pmd=0000000000000000
[ 297.523532] Internal error: Oops: 0000000096000005 [#1] SMP
[ 297.715393] CPU: 2 UID: 0 PID: 45 Comm: kworker/u16:2 Tainted: G O 6.12.50 #0
[ 297.723908] Tainted: [O]=OOT_MODULE
[ 297.727384] Hardware name: Banana Pi BPI-R4 (2x SFP+) (DT)
[ 297.732857] Workqueue: nf_ft_offload_del nf_flow_rule_route_ipv6 [nf_flow_table]
[ 297.740254] pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[ 297.747205] pc : mt76_wed_offload_disable+0x64/0xa0 [mt76]
[ 297.752688] lr : mtk_wed_flow_remove+0x58/0x80
[ 297.757126] sp : ffffffc080fe3ae0
[ 297.760430] x29: ffffffc080fe3ae0 x28: ffffffc080fe3be0 x27: 00000000deadbef7
[ 297.767557] x26: ffffff80c5ebca00 x25: 0000000000000001 x24: ffffff80c85f4c00
[ 297.774683] x23: ffffff80c1875b78 x22: ffffffc080d42cd0 x21: ffffffc080660018
[ 297.781809] x20: ffffff80c6a076d0 x19: ffffff80c6a043c8 x18: 0000000000000000
[ 297.788935] x17: 0000000000000000 x16: 0000000000000001 x15: 0000000000000000
[ 297.796060] x14: 0000000000000019 x13: ffffff80c0ad8ec0 x12: 00000000fa83b2da
[ 297.803185] x11: ffffff80c02700c0 x10: ffffff80c0ad8ec0 x9 : ffffff81fef96200
[ 297.810311] x8 : ffffff80c02700c0 x7 : ffffff80c02700d0 x6 : 0000000000000002
[ 297.817435] x5 : 0000000000000400 x4 : 0000000000000000 x3 : 0000000000000000
[ 297.824561] x2 : 0000000000000001 x1 : 0000000000000800 x0 : ffffff80c6a063c8
[ 297.831686] Call trace:
[ 297.834123] mt76_wed_offload_disable+0x64/0xa0 [mt76]
[ 297.839254] mtk_wed_flow_remove+0x58/0x80
[ 297.843342] mtk_flow_offload_cmd+0x434/0x574
[ 297.847689] mtk_wed_setup_tc_block_cb+0x30/0x40
[ 297.852295] nf_flow_offload_ipv6_hook+0x7f4/0x964 [nf_flow_table]
[ 297.858466] nf_flow_rule_route_ipv6+0x438/0x4a4 [nf_flow_table]
[ 297.864463] process_one_work+0x174/0x300
[ 297.868465] worker_thread+0x278/0x430
[ 297.872204] kthread+0xd8/0xdc
[ 297.875251] ret_from_fork+0x10/0x20
[ 297.878820] Code: 928b5ae0 8b000273 91400a60 f943fa61 (79401421)
[ 297.884901] ---[ end trace 0000000000000000 ]---

Fix the issue detecting the proper wed reference to use running wed
callabacks.

Fixes: 83eafc9251d6 ("wifi: mt76: mt7996: add wed tx support")
Tested-by: Daniel Pawlik <pawlik.dan@gmail.com>
Tested-by: Matteo Croce <teknoraver@meta.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://patch.msgid.link/20251008-wed-fixes-v1-1-8f7678583385@kernel.org
Signed-off-by: Felix Fietkau <nbd@nbd.name>

authored by

Lorenzo Bianconi and committed by
Felix Fietkau
385aab8f b05ab4be

+16 -5
+9
drivers/net/wireless/mediatek/mt76/mt76.h
··· 1260 1260 #define mt76_dereference(p, dev) \ 1261 1261 rcu_dereference_protected(p, lockdep_is_held(&(dev)->mutex)) 1262 1262 1263 + static inline struct mt76_dev *mt76_wed_to_dev(struct mtk_wed_device *wed) 1264 + { 1265 + #ifdef CONFIG_NET_MEDIATEK_SOC_WED 1266 + if (wed->wlan.hif2) 1267 + return container_of(wed, struct mt76_dev, mmio.wed_hif2); 1268 + #endif /* CONFIG_NET_MEDIATEK_SOC_WED */ 1269 + return container_of(wed, struct mt76_dev, mmio.wed); 1270 + } 1271 + 1263 1272 static inline struct mt76_wcid * 1264 1273 __mt76_wcid_ptr(struct mt76_dev *dev, u16 idx) 1265 1274 {
+1
drivers/net/wireless/mediatek/mt76/mt7996/mmio.c
··· 595 595 596 596 wed->wlan.nbuf = MT7996_HW_TOKEN_SIZE; 597 597 wed->wlan.token_start = MT7996_TOKEN_SIZE - wed->wlan.nbuf; 598 + wed->wlan.hif2 = hif2; 598 599 599 600 wed->wlan.amsdu_max_subframes = 8; 600 601 wed->wlan.amsdu_max_len = 1536;
+5 -5
drivers/net/wireless/mediatek/mt76/wed.c
··· 8 8 9 9 void mt76_wed_release_rx_buf(struct mtk_wed_device *wed) 10 10 { 11 - struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed); 11 + struct mt76_dev *dev = mt76_wed_to_dev(wed); 12 12 int i; 13 13 14 14 for (i = 0; i < dev->rx_token_size; i++) { ··· 31 31 #ifdef CONFIG_NET_MEDIATEK_SOC_WED 32 32 u32 mt76_wed_init_rx_buf(struct mtk_wed_device *wed, int size) 33 33 { 34 - struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed); 35 34 struct mtk_wed_bm_desc *desc = wed->rx_buf_ring.desc; 35 + struct mt76_dev *dev = mt76_wed_to_dev(wed); 36 36 struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN]; 37 37 struct mt76_txwi_cache *t = NULL; 38 38 int i; ··· 80 80 81 81 int mt76_wed_offload_enable(struct mtk_wed_device *wed) 82 82 { 83 - struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed); 83 + struct mt76_dev *dev = mt76_wed_to_dev(wed); 84 84 85 85 spin_lock_bh(&dev->token_lock); 86 86 dev->token_size = wed->wlan.token_start; ··· 164 164 165 165 void mt76_wed_offload_disable(struct mtk_wed_device *wed) 166 166 { 167 - struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed); 167 + struct mt76_dev *dev = mt76_wed_to_dev(wed); 168 168 169 169 spin_lock_bh(&dev->token_lock); 170 170 dev->token_size = dev->drv->token_size; ··· 174 174 175 175 void mt76_wed_reset_complete(struct mtk_wed_device *wed) 176 176 { 177 - struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed); 177 + struct mt76_dev *dev = mt76_wed_to_dev(wed); 178 178 179 179 complete(&dev->mmio.wed_reset_complete); 180 180 }
+1
include/linux/soc/mediatek/mtk_wed.h
··· 154 154 bool wcid_512; 155 155 bool hw_rro; 156 156 bool msi; 157 + bool hif2; 157 158 158 159 u16 token_start; 159 160 unsigned int nbuf;