> mt76_npu_device_active() and mt76_ppe_device_active() read dev->mmio.npu > and dev->mmio.ppe_dev. The mmio, usb and sdio bus structs share a union in > struct mt76_dev, so on USB and SDIO these read unrelated data from the > usb/sdio struct, which is non-NULL in practice. > > mt76_npu_device_active() then returns true on USB, and > mt76_rx_poll_complete() takes the offload path and skips > mt76_rx_aggr_reorder(). RX A-MPDU subframes are delivered out of order and > the peer's TCP stack treats that as loss: heavy retransmissions and reduced > throughput in AP mode. Seen on mt7921u, mt7925u, mt76x2u and mt76x0u. > > Gate both helpers on mt76_is_mmio() so they only run for the bus type that > owns the mmio union member. > > Fixes: 7fb554b1b623 ("wifi: mt76: Introduce the NPU generic layer") > Cc: stable@vger.kernel.org > Tested-by: Nick Morrow > Signed-off-by: Devin Wittmayer Acked-by: Lorenzo Bianconi > --- > drivers/net/wireless/mediatek/mt76/mt76.h | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h > index 07955555f84d..a32ba7c23f92 100644 > --- a/drivers/net/wireless/mediatek/mt76/mt76.h > +++ b/drivers/net/wireless/mediatek/mt76/mt76.h > @@ -1736,12 +1736,12 @@ static inline int mt76_npu_send_txrx_addr(struct mt76_dev *dev, int ifindex, > > static inline bool mt76_npu_device_active(struct mt76_dev *dev) > { > - return !!rcu_access_pointer(dev->mmio.npu); > + return mt76_is_mmio(dev) && !!rcu_access_pointer(dev->mmio.npu); > } > > static inline bool mt76_ppe_device_active(struct mt76_dev *dev) > { > - return !!rcu_access_pointer(dev->mmio.ppe_dev); > + return mt76_is_mmio(dev) && !!rcu_access_pointer(dev->mmio.ppe_dev); > } > > static inline int mt76_npu_send_msg(struct airoha_npu *npu, int ifindex, > -- > 2.55.0 >