]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: mt76: mt7996: Integrate NPU in RRO session management
authorLorenzo Bianconi <lorenzo@kernel.org>
Thu, 22 Jan 2026 10:39:53 +0000 (11:39 +0100)
committerFelix Fietkau <nbd@nbd.name>
Mon, 23 Mar 2026 09:23:00 +0000 (09:23 +0000)
Add NPU integration in RRO 3.0 session management.
This is a preliminary patch to enable NPU offload for MT7996 (Eagle)
chipset.

Tested-by: Kang Yang <kang.yang@airoha.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://patch.msgid.link/20260122-mt76-npu-eagle-offload-v2-9-2374614c0de6@kernel.org
Signed-off-by: Felix Fietkau <nbd@nbd.name>
drivers/net/wireless/mediatek/mt76/mt76.h
drivers/net/wireless/mediatek/mt76/mt7996/init.c
drivers/net/wireless/mediatek/mt76/npu.c

index d05e83ea1cacc43512f37743e1708390c3cb2f35..eefc3f555f8afea2af67517683d522b657e20b7b 100644 (file)
@@ -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)
index e678f06b4556dcc79c5b9b350c1f7c61f41efe26..b0f0d3adbb04c65672dcceff0ee3d9f2117d570f 100644 (file)
@@ -959,6 +959,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)) {
@@ -1019,6 +1025,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);
@@ -1105,8 +1115,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;
index 9679237f739842bd44497e0b1022a868cb3a0d6c..bc8f2012be9dbe2c7fc1fc885b6135d796d8c0d6 100644 (file)
@@ -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;