Skip to content

Commit 385aab8

Browse files
LorenzoBianconinbd168
authored andcommitted
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: 83eafc9 ("wifi: mt76: mt7996: add wed tx support") Tested-by: Daniel Pawlik <[email protected]> Tested-by: Matteo Croce <[email protected]> Signed-off-by: Lorenzo Bianconi <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Felix Fietkau <[email protected]>
1 parent b05ab4b commit 385aab8

File tree

4 files changed

+16
-5
lines changed

4 files changed

+16
-5
lines changed

drivers/net/wireless/mediatek/mt76/mt76.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1260,6 +1260,15 @@ static inline int mt76_wed_dma_setup(struct mt76_dev *dev, struct mt76_queue *q,
12601260
#define mt76_dereference(p, dev) \
12611261
rcu_dereference_protected(p, lockdep_is_held(&(dev)->mutex))
12621262

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+
12631272
static inline struct mt76_wcid *
12641273
__mt76_wcid_ptr(struct mt76_dev *dev, u16 idx)
12651274
{

drivers/net/wireless/mediatek/mt76/mt7996/mmio.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -595,6 +595,7 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
595595

596596
wed->wlan.nbuf = MT7996_HW_TOKEN_SIZE;
597597
wed->wlan.token_start = MT7996_TOKEN_SIZE - wed->wlan.nbuf;
598+
wed->wlan.hif2 = hif2;
598599

599600
wed->wlan.amsdu_max_subframes = 8;
600601
wed->wlan.amsdu_max_len = 1536;

drivers/net/wireless/mediatek/mt76/wed.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
void mt76_wed_release_rx_buf(struct mtk_wed_device *wed)
1010
{
11-
struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed);
11+
struct mt76_dev *dev = mt76_wed_to_dev(wed);
1212
int i;
1313

1414
for (i = 0; i < dev->rx_token_size; i++) {
@@ -31,8 +31,8 @@ EXPORT_SYMBOL_GPL(mt76_wed_release_rx_buf);
3131
#ifdef CONFIG_NET_MEDIATEK_SOC_WED
3232
u32 mt76_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
3333
{
34-
struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed);
3534
struct mtk_wed_bm_desc *desc = wed->rx_buf_ring.desc;
35+
struct mt76_dev *dev = mt76_wed_to_dev(wed);
3636
struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
3737
struct mt76_txwi_cache *t = NULL;
3838
int i;
@@ -80,7 +80,7 @@ EXPORT_SYMBOL_GPL(mt76_wed_init_rx_buf);
8080

8181
int mt76_wed_offload_enable(struct mtk_wed_device *wed)
8282
{
83-
struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed);
83+
struct mt76_dev *dev = mt76_wed_to_dev(wed);
8484

8585
spin_lock_bh(&dev->token_lock);
8686
dev->token_size = wed->wlan.token_start;
@@ -164,7 +164,7 @@ EXPORT_SYMBOL_GPL(mt76_wed_dma_setup);
164164

165165
void mt76_wed_offload_disable(struct mtk_wed_device *wed)
166166
{
167-
struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed);
167+
struct mt76_dev *dev = mt76_wed_to_dev(wed);
168168

169169
spin_lock_bh(&dev->token_lock);
170170
dev->token_size = dev->drv->token_size;
@@ -174,7 +174,7 @@ EXPORT_SYMBOL_GPL(mt76_wed_offload_disable);
174174

175175
void mt76_wed_reset_complete(struct mtk_wed_device *wed)
176176
{
177-
struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed);
177+
struct mt76_dev *dev = mt76_wed_to_dev(wed);
178178

179179
complete(&dev->mmio.wed_reset_complete);
180180
}

include/linux/soc/mediatek/mtk_wed.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ struct mtk_wed_device {
154154
bool wcid_512;
155155
bool hw_rro;
156156
bool msi;
157+
bool hif2;
157158

158159
u16 token_start;
159160
unsigned int nbuf;

0 commit comments

Comments
 (0)