[PATCH mt76 09/11] wifi: mt76: mt7996: Integrate NPU in RRO session management
Lorenzo Bianconi
lorenzo at kernel.org
Thu Dec 4 00:10:51 PST 2025
Add NPU integration in RRO 3.0 session management.
This is a preliminary patch to enable NPU offload for MT7996
(7990-Eagle) chipset.
Tested-by: Hui Ma <hui.ma at airoha.com>
Signed-off-by: Lorenzo Bianconi <lorenzo at kernel.org>
---
drivers/net/wireless/mediatek/mt76/mt76.h | 10 ++++++++
drivers/net/wireless/mediatek/mt76/mt7996/init.c | 16 ++++++++++++-
drivers/net/wireless/mediatek/mt76/npu.c | 30 ++++++++++++++++++++++++
3 files changed, 55 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index d05e83ea1cacc43512f37743e1708390c3cb2f35..eefc3f555f8afea2af67517683d522b657e20b7b 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -1649,6 +1649,9 @@ void mt76_npu_txdesc_cleanup(struct mt76_queue *q, int index);
int mt76_npu_net_setup_tc(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct net_device *dev, enum tc_setup_type type,
void *type_data);
+int mt76_npu_send_txrx_addr(struct mt76_dev *dev, int ifindex,
+ u32 direction, u32 i_count_addr,
+ u32 o_status_addr, u32 o_count_addr);
#else
static inline void mt76_npu_check_ppe(struct mt76_dev *dev,
struct sk_buff *skb, u32 info)
@@ -1707,6 +1710,13 @@ static inline int mt76_npu_net_setup_tc(struct ieee80211_hw *hw,
{
return -EOPNOTSUPP;
}
+
+static inline int mt76_npu_send_txrx_addr(struct mt76_dev *dev, int ifindex,
+ u32 direction, u32 i_count_addr,
+ u32 o_status_addr, u32 o_count_addr)
+{
+ return -EOPNOTSUPP;
+}
#endif /* CONFIG_MT76_NPU */
static inline bool mt76_npu_device_active(struct mt76_dev *dev)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/init.c b/drivers/net/wireless/mediatek/mt76/mt7996/init.c
index 9fbe4235de0d0d42776d5661fa1c297e431b8d27..03c1ccb49ef02ebe9c2ae91db836593e680ee2c0 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/init.c
@@ -941,6 +941,12 @@ static int mt7996_wed_rro_init(struct mt7996_dev *dev)
addr++;
}
+ if (is_mt7996(&dev->mt76) &&
+ mt76_npu_device_active(&dev->mt76))
+ mt76_npu_send_txrx_addr(&dev->mt76, 0, i,
+ dev->wed_rro.addr_elem[i].phy_addr,
+ 0, 0);
+
#ifdef CONFIG_NET_MEDIATEK_SOC_WED
if (mtk_wed_device_active(&dev->mt76.mmio.wed) &&
mtk_wed_get_rx_capa(&dev->mt76.mmio.wed)) {
@@ -1001,6 +1007,10 @@ static int mt7996_wed_rro_init(struct mt7996_dev *dev)
addr++;
}
+ if (is_mt7996(&dev->mt76) && mt76_npu_device_active(&dev->mt76))
+ mt76_npu_send_txrx_addr(&dev->mt76, 1, 0,
+ dev->wed_rro.session.phy_addr, 0, 0);
+
mt7996_rro_hw_init(dev);
return mt7996_dma_rro_init(dev);
@@ -1087,8 +1097,12 @@ static void mt7996_wed_rro_work(struct work_struct *work)
list);
list_del_init(&e->list);
- if (mt76_npu_device_active(&dev->mt76))
+ if (mt76_npu_device_active(&dev->mt76)) {
+ if (is_mt7996(&dev->mt76))
+ mt76_npu_send_txrx_addr(&dev->mt76, 3, e->id,
+ 0, 0, 0);
goto reset_session;
+ }
for (i = 0; i < MT7996_RRO_WINDOW_MAX_LEN; i++) {
void *ptr = dev->wed_rro.session.ptr;
diff --git a/drivers/net/wireless/mediatek/mt76/npu.c b/drivers/net/wireless/mediatek/mt76/npu.c
index 9679237f739842bd44497e0b1022a868cb3a0d6c..bc8f2012be9dbe2c7fc1fc885b6135d796d8c0d6 100644
--- a/drivers/net/wireless/mediatek/mt76/npu.c
+++ b/drivers/net/wireless/mediatek/mt76/npu.c
@@ -390,6 +390,36 @@ int mt76_npu_net_setup_tc(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
}
EXPORT_SYMBOL_GPL(mt76_npu_net_setup_tc);
+int mt76_npu_send_txrx_addr(struct mt76_dev *dev, int ifindex,
+ u32 direction, u32 i_count_addr,
+ u32 o_status_addr, u32 o_count_addr)
+{
+ struct {
+ __le32 dir;
+ __le32 in_count_addr;
+ __le32 out_status_addr;
+ __le32 out_count_addr;
+ } info = {
+ .dir = cpu_to_le32(direction),
+ .in_count_addr = cpu_to_le32(i_count_addr),
+ .out_status_addr = cpu_to_le32(o_status_addr),
+ .out_count_addr = cpu_to_le32(o_count_addr),
+ };
+ struct airoha_npu *npu;
+ int err = -ENODEV;
+
+ rcu_read_lock();
+ npu = rcu_dereference(dev->mmio.npu);
+ if (npu)
+ err = airoha_npu_wlan_send_msg(npu, ifindex,
+ WLAN_FUNC_SET_WAIT_INODE_TXRX_REG_ADDR,
+ &info, sizeof(info), GFP_ATOMIC);
+ rcu_read_unlock();
+
+ return err;
+}
+EXPORT_SYMBOL_GPL(mt76_npu_send_txrx_addr);
+
void mt76_npu_disable_irqs(struct mt76_dev *dev)
{
struct airoha_npu *npu;
--
2.52.0
More information about the Linux-mediatek
mailing list