Introduce wlan_init_reserved_memory callback used by MT76 driver during NPU wlan offloading setup. This is a preliminary patch to enable wlan flowtable offload for EN7581 SoC with MT76 driver. Signed-off-by: Lorenzo Bianconi --- drivers/net/ethernet/airoha/airoha_npu.c | 123 +++++++++++++++++++++++++++++++ drivers/net/ethernet/airoha/airoha_npu.h | 1 + 2 files changed, 124 insertions(+) diff --git a/drivers/net/ethernet/airoha/airoha_npu.c b/drivers/net/ethernet/airoha/airoha_npu.c index 0e5b8c21b9aa8bacdfb2e1572afe4324003e8279..f8057072cfd7bb114e34af176aabaa1ef9f052c0 100644 --- a/drivers/net/ethernet/airoha/airoha_npu.c +++ b/drivers/net/ethernet/airoha/airoha_npu.c @@ -124,6 +124,54 @@ struct ppe_mbox_data { }; }; +enum { + WLAN_FUNC_SET_WAIT_PCIE_ADDR, + WLAN_FUNC_SET_WAIT_DESC, + WLAN_FUNC_SET_WAIT_NPU_INIT_DONE, + WLAN_FUNC_SET_WAIT_TRAN_TO_CPU, + WLAN_FUNC_SET_WAIT_BA_WIN_SIZE, + WLAN_FUNC_SET_WAIT_DRIVER_MODEL, + WLAN_FUNC_SET_WAIT_DEL_STA, + WLAN_FUNC_SET_WAIT_DRAM_BA_NODE_ADDR, + WLAN_FUNC_SET_WAIT_PKT_BUF_ADDR, + WLAN_FUNC_SET_WAIT_IS_TEST_NOBA, + WLAN_FUNC_SET_WAIT_FLUSHONE_TIMEOUT, + WLAN_FUNC_SET_WAIT_FLUSHALL_TIMEOUT, + WLAN_FUNC_SET_WAIT_IS_FORCE_TO_CPU, + WLAN_FUNC_SET_WAIT_PCIE_STATE, + WLAN_FUNC_SET_WAIT_PCIE_PORT_TYPE, + WLAN_FUNC_SET_WAIT_ERROR_RETRY_TIMES, + WLAN_FUNC_SET_WAIT_BAR_INFO, + WLAN_FUNC_SET_WAIT_FAST_FLAG, + WLAN_FUNC_SET_WAIT_NPU_BAND0_ONCPU, + WLAN_FUNC_SET_WAIT_TX_RING_PCIE_ADDR, + WLAN_FUNC_SET_WAIT_TX_DESC_HW_BASE, + WLAN_FUNC_SET_WAIT_TX_BUF_SPACE_HW_BASE, + WLAN_FUNC_SET_WAIT_RX_RING_FOR_TXDONE_HW_BASE, + WLAN_FUNC_SET_WAIT_TX_PKT_BUF_ADDR, + WLAN_FUNC_SET_WAIT_INODE_TXRX_REG_ADDR, + WLAN_FUNC_SET_WAIT_INODE_DEBUG_FLAG, + WLAN_FUNC_SET_WAIT_INODE_HW_CFG_INFO, + WLAN_FUNC_SET_WAIT_INODE_STOP_ACTION, + WLAN_FUNC_SET_WAIT_INODE_PCIE_SWAP, + WLAN_FUNC_SET_WAIT_RATELIMIT_CTRL, + WLAN_FUNC_SET_WAIT_HWNAT_INIT, + WLAN_FUNC_SET_WAIT_ARHT_CHIP_INFO, + WLAN_FUNC_SET_WAIT_TX_BUF_CHECK_ADDR, + WLAN_FUNC_SET_WAIT_DEBUG_ARRAY_ADDR, +}; + +#define WLAN_MAX_STATS_SIZE 4408 +struct wlan_mbox_data { + u32 ifindex:4; + u32 func_type:4; + u32 func_id; + union { + u32 data; + u8 stats[WLAN_MAX_STATS_SIZE]; + }; +}; + static int airoha_npu_send_msg(struct airoha_npu *npu, int func_id, void *p, int size) { @@ -390,6 +438,80 @@ static int airoha_npu_stats_setup(struct airoha_npu *npu, return err; } +static int airoha_npu_wlan_send_msg(struct airoha_npu *npu, int ifindex, + int func_id, u32 data, gfp_t gfp) +{ + struct wlan_mbox_data *wlan_data; + int err; + + wlan_data = kzalloc(sizeof(*wlan_data), gfp); + if (!wlan_data) + return -ENOMEM; + + wlan_data->ifindex = ifindex; + wlan_data->func_type = NPU_OP_SET; + wlan_data->func_id = func_id; + wlan_data->data = data; + + err = airoha_npu_send_msg(npu, NPU_FUNC_WIFI, wlan_data, + sizeof(*wlan_data)); + kfree(wlan_data); + + return err; +} + +static int airoha_npu_wlan_set_reserved_memory(struct airoha_npu *npu, + int ifindex, const char *name, + int func_id) +{ + struct device *dev = npu->dev; + struct reserved_mem *rmem; + struct device_node *np; + int index; + + index = of_property_match_string(dev->of_node, "memory-region-names", + name); + if (index < 0) + return -ENODEV; + + np = of_parse_phandle(dev->of_node, "memory-region", index); + if (!np) + return -ENODEV; + + rmem = of_reserved_mem_lookup(np); + of_node_put(np); + + return airoha_npu_wlan_send_msg(npu, ifindex, func_id, rmem->base, + GFP_KERNEL); +} + +static int airoha_npu_wlan_init_memory(struct airoha_npu *npu) +{ + int err, cmd = WLAN_FUNC_SET_WAIT_NPU_BAND0_ONCPU; + + err = airoha_npu_wlan_send_msg(npu, 1, cmd, 0, GFP_KERNEL); + if (err) + return err; + + cmd = WLAN_FUNC_SET_WAIT_TX_BUF_CHECK_ADDR; + err = airoha_npu_wlan_set_reserved_memory(npu, 0, "tx-bufid", cmd); + if (err) + return err; + + cmd = WLAN_FUNC_SET_WAIT_PKT_BUF_ADDR; + err = airoha_npu_wlan_set_reserved_memory(npu, 0, "pkt", cmd); + if (err) + return err; + + cmd = WLAN_FUNC_SET_WAIT_TX_PKT_BUF_ADDR; + err = airoha_npu_wlan_set_reserved_memory(npu, 0, "tx-pkt", cmd); + if (err) + return err; + + cmd = WLAN_FUNC_SET_WAIT_IS_FORCE_TO_CPU; + return airoha_npu_wlan_send_msg(npu, 0, cmd, 0, GFP_KERNEL); +} + struct airoha_npu *airoha_npu_get(struct device *dev, dma_addr_t *stats_addr) { struct platform_device *pdev; @@ -493,6 +615,7 @@ static int airoha_npu_probe(struct platform_device *pdev) npu->ops.ppe_deinit = airoha_npu_ppe_deinit; npu->ops.ppe_flush_sram_entries = airoha_npu_ppe_flush_sram_entries; npu->ops.ppe_foe_commit_entry = airoha_npu_foe_commit_entry; + npu->ops.wlan_init_reserved_memory = airoha_npu_wlan_init_memory; npu->regmap = devm_regmap_init_mmio(dev, base, ®map_config); if (IS_ERR(npu->regmap)) diff --git a/drivers/net/ethernet/airoha/airoha_npu.h b/drivers/net/ethernet/airoha/airoha_npu.h index 98ec3be74ce450bf4fa8bc771d19d174e8c157e5..242f0d15b2f7c262daaf7bb78ee386ccc8a0433d 100644 --- a/drivers/net/ethernet/airoha/airoha_npu.h +++ b/drivers/net/ethernet/airoha/airoha_npu.h @@ -29,6 +29,7 @@ struct airoha_npu { dma_addr_t foe_addr, u32 entry_size, u32 hash, bool ppe2); + int (*wlan_init_reserved_memory)(struct airoha_npu *npu); } ops; }; -- 2.50.0 Introduce more NPU wlan callbacks used by wlan driver (MT76) to initialize NPU module register for offloading wireless-wired offloading. This is a preliminary patch to enable wlan flowtable offload for EN7581 SoC with MT76 driver. Signed-off-by: Lorenzo Bianconi --- drivers/net/ethernet/airoha/airoha_npu.c | 163 +++++++++++++++++++++++++++++++ drivers/net/ethernet/airoha/airoha_npu.h | 21 ++++ 2 files changed, 184 insertions(+) diff --git a/drivers/net/ethernet/airoha/airoha_npu.c b/drivers/net/ethernet/airoha/airoha_npu.c index f8057072cfd7bb114e34af176aabaa1ef9f052c0..8acb2c627dc32386f40795a26e03d36fffe359ac 100644 --- a/drivers/net/ethernet/airoha/airoha_npu.c +++ b/drivers/net/ethernet/airoha/airoha_npu.c @@ -42,6 +42,22 @@ #define REG_CR_MBQ8_CTRL(_n) (NPU_MBOX_BASE_ADDR + 0x0b0 + ((_n) << 2)) #define REG_CR_NPU_MIB(_n) (NPU_MBOX_BASE_ADDR + 0x140 + ((_n) << 2)) +#define NPU_WLAN_BASE_ADDR 0x30d000 + +#define REG_IRQ_STATUS (NPU_WLAN_BASE_ADDR + 0x030) +#define REG_IRQ_RXDONE(_n) (NPU_WLAN_BASE_ADDR + ((_n) << 2) + 0x034) +#define NPU_IRQ_RX_MASK(_n) ((_n) == 1 ? BIT(17) : BIT(16)) + +#define REG_TX_BASE(_n) (NPU_WLAN_BASE_ADDR + ((_n) << 4) + 0x080) +#define REG_TX_DSCP_NUM(_n) (NPU_WLAN_BASE_ADDR + ((_n) << 4) + 0x084) +#define REG_TX_CPU_IDX(_n) (NPU_WLAN_BASE_ADDR + ((_n) << 4) + 0x088) +#define REG_TX_DMA_IDX(_n) (NPU_WLAN_BASE_ADDR + ((_n) << 4) + 0x08c) + +#define REG_RX_BASE(_n) (NPU_WLAN_BASE_ADDR + ((_n) << 4) + 0x180) +#define REG_RX_DSCP_NUM(_n) (NPU_WLAN_BASE_ADDR + ((_n) << 4) + 0x184) +#define REG_RX_CPU_IDX(_n) (NPU_WLAN_BASE_ADDR + ((_n) << 4) + 0x188) +#define REG_RX_DMA_IDX(_n) (NPU_WLAN_BASE_ADDR + ((_n) << 4) + 0x18c) + #define NPU_TIMER_BASE_ADDR 0x310100 #define REG_WDT_TIMER_CTRL(_n) (NPU_TIMER_BASE_ADDR + ((_n) * 0x100)) #define WDT_EN_MASK BIT(25) @@ -161,6 +177,19 @@ enum { WLAN_FUNC_SET_WAIT_DEBUG_ARRAY_ADDR, }; +enum { + WLAN_FUNC_GET_WAIT_NPU_INFO, + WLAN_FUNC_GET_WAIT_LAST_RATE, + WLAN_FUNC_GET_WAIT_COUNTER, + WLAN_FUNC_GET_WAIT_DBG_COUNTER, + WLAN_FUNC_GET_WAIT_RXDESC_BASE, + WLAN_FUNC_GET_WAIT_WCID_DBG_COUNTER, + WLAN_FUNC_GET_WAIT_DMA_ADDR, + WLAN_FUNC_GET_WAIT_RING_SIZE, + WLAN_FUNC_GET_WAIT_NPU_SUPPORT_MAP, + WLAN_FUNC_GET_WAIT_MDC_LOCK_ADDRESS, +}; + #define WLAN_MAX_STATS_SIZE 4408 struct wlan_mbox_data { u32 ifindex:4; @@ -168,6 +197,12 @@ struct wlan_mbox_data { u32 func_id; union { u32 data; + struct { + u32 dir; + u32 in_counter_addr; + u32 out_status_addr; + u32 out_counter_addr; + } txrx_addr; u8 stats[WLAN_MAX_STATS_SIZE]; }; }; @@ -460,6 +495,29 @@ static int airoha_npu_wlan_send_msg(struct airoha_npu *npu, int ifindex, return err; } +static int airoha_npu_wlan_get_msg(struct airoha_npu *npu, int index, + int func_id, u32 *data) +{ + struct wlan_mbox_data *wlan_data; + int err; + + wlan_data = kzalloc(sizeof(*wlan_data), GFP_ATOMIC); + if (!wlan_data) + return -ENOMEM; + + wlan_data->ifindex = index; + wlan_data->func_type = NPU_OP_GET; + wlan_data->func_id = func_id; + + err = airoha_npu_send_msg(npu, NPU_FUNC_WIFI, wlan_data, + sizeof(*wlan_data)); + if (!err) + *data = wlan_data->data; + kfree(wlan_data); + + return err; +} + static int airoha_npu_wlan_set_reserved_memory(struct airoha_npu *npu, int ifindex, const char *name, int func_id) @@ -512,6 +570,99 @@ static int airoha_npu_wlan_init_memory(struct airoha_npu *npu) return airoha_npu_wlan_send_msg(npu, 0, cmd, 0, GFP_KERNEL); } +static int airoha_npu_wlan_txrx_reg_addr_set(struct airoha_npu *npu, + int ifindex, u32 dir, + u32 in_counter_addr, + u32 out_status_addr, + u32 out_counter_addr) +{ + struct wlan_mbox_data *wlan_data; + int err; + + wlan_data = kzalloc(sizeof(*wlan_data), GFP_ATOMIC); + if (!wlan_data) + return -ENOMEM; + + wlan_data->ifindex = ifindex; + wlan_data->func_type = NPU_OP_SET; + wlan_data->func_id = WLAN_FUNC_SET_WAIT_INODE_TXRX_REG_ADDR; + wlan_data->txrx_addr.dir = dir; + wlan_data->txrx_addr.in_counter_addr = in_counter_addr; + wlan_data->txrx_addr.out_status_addr = out_status_addr; + wlan_data->txrx_addr.out_counter_addr = out_counter_addr; + + err = airoha_npu_send_msg(npu, NPU_FUNC_WIFI, wlan_data, + sizeof(*wlan_data)); + kfree(wlan_data); + + return err; +} + +static int airoha_npu_wlan_pcie_port_type_set(struct airoha_npu *npu, + int ifindex, u32 port_type) +{ + return airoha_npu_wlan_send_msg(npu, ifindex, + WLAN_FUNC_SET_WAIT_PCIE_PORT_TYPE, + port_type, GFP_ATOMIC); +} + +static int airoha_npu_wlan_pcie_addr_set(struct airoha_npu *npu, + int ifindex, u32 addr) +{ + return airoha_npu_wlan_send_msg(npu, ifindex, + WLAN_FUNC_SET_WAIT_PCIE_ADDR, addr, + GFP_ATOMIC); +} + +static int airoha_npu_wlan_desc_set(struct airoha_npu *npu, int ifindex, + u32 desc) +{ + return airoha_npu_wlan_send_msg(npu, ifindex, + WLAN_FUNC_SET_WAIT_DESC, desc, + GFP_ATOMIC); +} + +static int airoha_npu_wlan_tx_ring_pcie_addr_set(struct airoha_npu *npu, + int ifindex, u32 addr) +{ + return airoha_npu_wlan_send_msg(npu, ifindex, + WLAN_FUNC_SET_WAIT_TX_RING_PCIE_ADDR, + addr, GFP_ATOMIC); +} + +static int airoha_npu_wlan_rx_desc_base_get(struct airoha_npu *npu, + int ifindex, u32 *data) + +{ + return airoha_npu_wlan_get_msg(npu, ifindex, + WLAN_FUNC_GET_WAIT_RXDESC_BASE, data); +} + +static int airoha_npu_wlan_tx_buf_space_base_set(struct airoha_npu *npu, + int ifindex, u32 addr) +{ + return airoha_npu_wlan_send_msg(npu, ifindex, + WLAN_FUNC_SET_WAIT_TX_BUF_SPACE_HW_BASE, + addr, GFP_ATOMIC); +} + +static int airoha_npu_wlan_rx_ring_for_txdone_set(struct airoha_npu *npu, + int ifindex, u32 addr) +{ + return airoha_npu_wlan_send_msg(npu, ifindex, + WLAN_FUNC_SET_WAIT_RX_RING_FOR_TXDONE_HW_BASE, + addr, GFP_ATOMIC); +} + +static u32 airoha_npu_wlan_queue_addr_get(struct airoha_npu *npu, int qid, + bool xmit) +{ + if (xmit) + return REG_TX_BASE(qid + 2); + + return REG_RX_BASE(qid); +} + struct airoha_npu *airoha_npu_get(struct device *dev, dma_addr_t *stats_addr) { struct platform_device *pdev; @@ -616,6 +767,18 @@ static int airoha_npu_probe(struct platform_device *pdev) npu->ops.ppe_flush_sram_entries = airoha_npu_ppe_flush_sram_entries; npu->ops.ppe_foe_commit_entry = airoha_npu_foe_commit_entry; npu->ops.wlan_init_reserved_memory = airoha_npu_wlan_init_memory; + npu->ops.wlan_set_txrx_reg_addr = airoha_npu_wlan_txrx_reg_addr_set; + npu->ops.wlan_set_pcie_port_type = airoha_npu_wlan_pcie_port_type_set; + npu->ops.wlan_set_pcie_addr = airoha_npu_wlan_pcie_addr_set; + npu->ops.wlan_set_desc = airoha_npu_wlan_desc_set; + npu->ops.wlan_set_tx_ring_pcie_addr = + airoha_npu_wlan_tx_ring_pcie_addr_set; + npu->ops.wlan_get_rx_desc_base = airoha_npu_wlan_rx_desc_base_get; + npu->ops.wlan_set_tx_buf_space_base = + airoha_npu_wlan_tx_buf_space_base_set; + npu->ops.wlan_set_rx_ring_for_txdone = + airoha_npu_wlan_rx_ring_for_txdone_set; + npu->ops.wlan_get_queue_addr = airoha_npu_wlan_queue_addr_get; npu->regmap = devm_regmap_init_mmio(dev, base, ®map_config); if (IS_ERR(npu->regmap)) diff --git a/drivers/net/ethernet/airoha/airoha_npu.h b/drivers/net/ethernet/airoha/airoha_npu.h index 242f0d15b2f7c262daaf7bb78ee386ccc8a0433d..9fdec469e7b0e7caa5d988dfd78578d860a0e66d 100644 --- a/drivers/net/ethernet/airoha/airoha_npu.h +++ b/drivers/net/ethernet/airoha/airoha_npu.h @@ -30,6 +30,27 @@ struct airoha_npu { u32 entry_size, u32 hash, bool ppe2); int (*wlan_init_reserved_memory)(struct airoha_npu *npu); + int (*wlan_set_txrx_reg_addr)(struct airoha_npu *npu, + int ifindex, u32 dir, + u32 in_counter_addr, + u32 out_status_addr, + u32 out_counter_addr); + int (*wlan_set_pcie_port_type)(struct airoha_npu *npu, + int ifindex, u32 port_type); + int (*wlan_set_pcie_addr)(struct airoha_npu *npu, int ifindex, + u32 addr); + int (*wlan_set_desc)(struct airoha_npu *npu, int ifindex, + u32 desc); + int (*wlan_set_tx_ring_pcie_addr)(struct airoha_npu *npu, + int ifindex, u32 addr); + int (*wlan_get_rx_desc_base)(struct airoha_npu *npu, + int ifindex, u32 *data); + int (*wlan_set_tx_buf_space_base)(struct airoha_npu *npu, + int ifindex, u32 addr); + int (*wlan_set_rx_ring_for_txdone)(struct airoha_npu *npu, + int ifindex, u32 addr); + u32 (*wlan_get_queue_addr)(struct airoha_npu *npu, int qid, + bool xmit); } ops; }; -- 2.50.0 Introduce callbacks used by the MT76 driver to configure NPU SoC interrupts. This is a preliminary patch to enable wlan flowtable offload for EN7581 SoC with MT76 driver. Signed-off-by: Lorenzo Bianconi --- drivers/net/ethernet/airoha/airoha_npu.c | 27 +++++++++++++++++++++++++++ drivers/net/ethernet/airoha/airoha_npu.h | 4 ++++ 2 files changed, 31 insertions(+) diff --git a/drivers/net/ethernet/airoha/airoha_npu.c b/drivers/net/ethernet/airoha/airoha_npu.c index 8acb2c627dc32386f40795a26e03d36fffe359ac..7d552ab7f692ba0f720e4fef89082e6ab233d809 100644 --- a/drivers/net/ethernet/airoha/airoha_npu.c +++ b/drivers/net/ethernet/airoha/airoha_npu.c @@ -663,6 +663,29 @@ static u32 airoha_npu_wlan_queue_addr_get(struct airoha_npu *npu, int qid, return REG_RX_BASE(qid); } +static void airoha_npu_wlan_irq_status_set(struct airoha_npu *npu, u32 val) +{ + regmap_write(npu->regmap, REG_IRQ_STATUS, val); +} + +static u32 airoha_npu_wlan_irq_status_get(struct airoha_npu *npu, int q) +{ + u32 val; + + regmap_read(npu->regmap, REG_IRQ_STATUS, &val); + return val; +} + +static void airoha_npu_wlan_irq_enable(struct airoha_npu *npu, int q) +{ + regmap_set_bits(npu->regmap, REG_IRQ_RXDONE(q), NPU_IRQ_RX_MASK(q)); +} + +static void airoha_npu_wlan_irq_disable(struct airoha_npu *npu, int q) +{ + regmap_clear_bits(npu->regmap, REG_IRQ_RXDONE(q), NPU_IRQ_RX_MASK(q)); +} + struct airoha_npu *airoha_npu_get(struct device *dev, dma_addr_t *stats_addr) { struct platform_device *pdev; @@ -779,6 +802,10 @@ static int airoha_npu_probe(struct platform_device *pdev) npu->ops.wlan_set_rx_ring_for_txdone = airoha_npu_wlan_rx_ring_for_txdone_set; npu->ops.wlan_get_queue_addr = airoha_npu_wlan_queue_addr_get; + npu->ops.wlan_set_irq_status = airoha_npu_wlan_irq_status_set; + npu->ops.wlan_get_irq_status = airoha_npu_wlan_irq_status_get; + npu->ops.wlan_enable_irq = airoha_npu_wlan_irq_enable; + npu->ops.wlan_disable_irq = airoha_npu_wlan_irq_disable; npu->regmap = devm_regmap_init_mmio(dev, base, ®map_config); if (IS_ERR(npu->regmap)) diff --git a/drivers/net/ethernet/airoha/airoha_npu.h b/drivers/net/ethernet/airoha/airoha_npu.h index 9fdec469e7b0e7caa5d988dfd78578d860a0e66d..23318b708f81eacc11753f54350ae33ea83a11ee 100644 --- a/drivers/net/ethernet/airoha/airoha_npu.h +++ b/drivers/net/ethernet/airoha/airoha_npu.h @@ -51,6 +51,10 @@ struct airoha_npu { int ifindex, u32 addr); u32 (*wlan_get_queue_addr)(struct airoha_npu *npu, int qid, bool xmit); + void (*wlan_set_irq_status)(struct airoha_npu *npu, u32 val); + u32 (*wlan_get_irq_status)(struct airoha_npu *npu, int q); + void (*wlan_enable_irq)(struct airoha_npu *npu, int q); + void (*wlan_disable_irq)(struct airoha_npu *npu, int q); } ops; }; -- 2.50.0 Read all NPU supported IRQ lines from NPU device-tree node. This is a preliminary patch to enable wlan flowtable offload for EN7581 SoC. Signed-off-by: Lorenzo Bianconi --- drivers/net/ethernet/airoha/airoha_npu.c | 8 ++++++++ drivers/net/ethernet/airoha/airoha_npu.h | 3 +++ 2 files changed, 11 insertions(+) diff --git a/drivers/net/ethernet/airoha/airoha_npu.c b/drivers/net/ethernet/airoha/airoha_npu.c index 7d552ab7f692ba0f720e4fef89082e6ab233d809..1cf431469ca034bbaeb922fed3ebdab41aafef05 100644 --- a/drivers/net/ethernet/airoha/airoha_npu.c +++ b/drivers/net/ethernet/airoha/airoha_npu.c @@ -848,6 +848,14 @@ static int airoha_npu_probe(struct platform_device *pdev) INIT_WORK(&core->wdt_work, airoha_npu_wdt_work); } + for (i = 0; i < ARRAY_SIZE(npu->irqs); i++) { + irq = platform_get_irq(pdev, i + ARRAY_SIZE(npu->cores) + 1); + if (irq < 0) + return irq; + + npu->irqs[i] = irq; + } + err = dma_set_coherent_mask(dev, DMA_BIT_MASK(32)); if (err) return err; diff --git a/drivers/net/ethernet/airoha/airoha_npu.h b/drivers/net/ethernet/airoha/airoha_npu.h index 23318b708f81eacc11753f54350ae33ea83a11ee..19cfc6b7fb52f4a176d91c7b39383b4c3e13d777 100644 --- a/drivers/net/ethernet/airoha/airoha_npu.h +++ b/drivers/net/ethernet/airoha/airoha_npu.h @@ -5,6 +5,7 @@ */ #define NPU_NUM_CORES 8 +#define NPU_NUM_IRQ 6 struct airoha_npu { struct device *dev; @@ -17,6 +18,8 @@ struct airoha_npu { struct work_struct wdt_work; } cores[NPU_NUM_CORES]; + int irqs[NPU_NUM_IRQ]; + struct airoha_foe_stats __iomem *stats; struct { -- 2.50.0 NPU core 3 is responsible for WiFi offloading so enable it during NPU probe. Signed-off-by: Lorenzo Bianconi --- drivers/net/ethernet/airoha/airoha_npu.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/ethernet/airoha/airoha_npu.c b/drivers/net/ethernet/airoha/airoha_npu.c index 1cf431469ca034bbaeb922fed3ebdab41aafef05..3e30cd424085d882aad98a0e751743de73f135fe 100644 --- a/drivers/net/ethernet/airoha/airoha_npu.c +++ b/drivers/net/ethernet/airoha/airoha_npu.c @@ -877,8 +877,7 @@ static int airoha_npu_probe(struct platform_device *pdev) usleep_range(1000, 2000); /* enable NPU cores */ - /* do not start core3 since it is used for WiFi offloading */ - regmap_write(npu->regmap, REG_CR_BOOT_CONFIG, 0xf7); + regmap_write(npu->regmap, REG_CR_BOOT_CONFIG, 0xff); regmap_write(npu->regmap, REG_CR_BOOT_TRIGGER, 0x1); msleep(100); -- 2.50.0 Move NPU definitions to airoha_offload.h in include/linux/soc/airoha/ in order to allow the MT76 driver to access the callback definitions. Signed-off-by: Lorenzo Bianconi --- drivers/net/ethernet/airoha/airoha_npu.c | 2 +- drivers/net/ethernet/airoha/airoha_npu.h | 65 ------- drivers/net/ethernet/airoha/airoha_ppe.c | 2 +- include/linux/soc/airoha/airoha_offload.h | 295 ++++++++++++++++++++++++++++++ 4 files changed, 297 insertions(+), 67 deletions(-) diff --git a/drivers/net/ethernet/airoha/airoha_npu.c b/drivers/net/ethernet/airoha/airoha_npu.c index 3e30cd424085d882aad98a0e751743de73f135fe..46cc3598defa409f0465de0362883ec0e59280fc 100644 --- a/drivers/net/ethernet/airoha/airoha_npu.c +++ b/drivers/net/ethernet/airoha/airoha_npu.c @@ -11,9 +11,9 @@ #include #include #include +#include #include "airoha_eth.h" -#include "airoha_npu.h" #define NPU_EN7581_FIRMWARE_DATA "airoha/en7581_npu_data.bin" #define NPU_EN7581_FIRMWARE_RV32 "airoha/en7581_npu_rv32.bin" diff --git a/drivers/net/ethernet/airoha/airoha_npu.h b/drivers/net/ethernet/airoha/airoha_npu.h deleted file mode 100644 index 19cfc6b7fb52f4a176d91c7b39383b4c3e13d777..0000000000000000000000000000000000000000 --- a/drivers/net/ethernet/airoha/airoha_npu.h +++ /dev/null @@ -1,65 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (c) 2025 AIROHA Inc - * Author: Lorenzo Bianconi - */ - -#define NPU_NUM_CORES 8 -#define NPU_NUM_IRQ 6 - -struct airoha_npu { - struct device *dev; - struct regmap *regmap; - - struct airoha_npu_core { - struct airoha_npu *npu; - /* protect concurrent npu memory accesses */ - spinlock_t lock; - struct work_struct wdt_work; - } cores[NPU_NUM_CORES]; - - int irqs[NPU_NUM_IRQ]; - - struct airoha_foe_stats __iomem *stats; - - struct { - int (*ppe_init)(struct airoha_npu *npu); - int (*ppe_deinit)(struct airoha_npu *npu); - int (*ppe_flush_sram_entries)(struct airoha_npu *npu, - dma_addr_t foe_addr, - int sram_num_entries); - int (*ppe_foe_commit_entry)(struct airoha_npu *npu, - dma_addr_t foe_addr, - u32 entry_size, u32 hash, - bool ppe2); - int (*wlan_init_reserved_memory)(struct airoha_npu *npu); - int (*wlan_set_txrx_reg_addr)(struct airoha_npu *npu, - int ifindex, u32 dir, - u32 in_counter_addr, - u32 out_status_addr, - u32 out_counter_addr); - int (*wlan_set_pcie_port_type)(struct airoha_npu *npu, - int ifindex, u32 port_type); - int (*wlan_set_pcie_addr)(struct airoha_npu *npu, int ifindex, - u32 addr); - int (*wlan_set_desc)(struct airoha_npu *npu, int ifindex, - u32 desc); - int (*wlan_set_tx_ring_pcie_addr)(struct airoha_npu *npu, - int ifindex, u32 addr); - int (*wlan_get_rx_desc_base)(struct airoha_npu *npu, - int ifindex, u32 *data); - int (*wlan_set_tx_buf_space_base)(struct airoha_npu *npu, - int ifindex, u32 addr); - int (*wlan_set_rx_ring_for_txdone)(struct airoha_npu *npu, - int ifindex, u32 addr); - u32 (*wlan_get_queue_addr)(struct airoha_npu *npu, int qid, - bool xmit); - void (*wlan_set_irq_status)(struct airoha_npu *npu, u32 val); - u32 (*wlan_get_irq_status)(struct airoha_npu *npu, int q); - void (*wlan_enable_irq)(struct airoha_npu *npu, int q); - void (*wlan_disable_irq)(struct airoha_npu *npu, int q); - } ops; -}; - -struct airoha_npu *airoha_npu_get(struct device *dev, dma_addr_t *stats_addr); -void airoha_npu_put(struct airoha_npu *npu); diff --git a/drivers/net/ethernet/airoha/airoha_ppe.c b/drivers/net/ethernet/airoha/airoha_ppe.c index c354d536bc66e97ab853792e4ab4273283d2fb91..5d12bde6b20a89b3037ae4405b383d75307e8239 100644 --- a/drivers/net/ethernet/airoha/airoha_ppe.c +++ b/drivers/net/ethernet/airoha/airoha_ppe.c @@ -7,10 +7,10 @@ #include #include #include +#include #include #include -#include "airoha_npu.h" #include "airoha_regs.h" #include "airoha_eth.h" diff --git a/include/linux/soc/airoha/airoha_offload.h b/include/linux/soc/airoha/airoha_offload.h new file mode 100644 index 0000000000000000000000000000000000000000..d2353da154d7ab1ae97901a46062ef49fcefa74d --- /dev/null +++ b/include/linux/soc/airoha/airoha_offload.h @@ -0,0 +1,295 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2025 AIROHA Inc + * Author: Lorenzo Bianconi + */ +#ifndef AIROHA_OFFLOAD_H +#define AIROHA_OFFLOAD_H + +#define NPU_NUM_CORES 8 +#define NPU_NUM_IRQ 6 +#define NPU_RX0_DESC_NUM 512 +#define NPU_RX1_DESC_NUM 512 + +/* CTRL */ +#define NPU_RX_DMA_DESC_LAST_MASK BIT(29) +#define NPU_RX_DMA_DESC_LEN_MASK GENMASK(28, 15) +#define NPU_RX_DMA_DESC_CUR_LEN_MASK GENMASK(14, 1) +#define NPU_RX_DMA_DESC_DONE_MASK BIT(0) +/* INFO */ +#define NPU_RX_DMA_PKT_COUNT_MASK GENMASK(31, 28) +#define NPU_RX_DMA_PKT_ID_MASK GENMASK(28, 26) +#define NPU_RX_DMA_SRC_PORT_MASK GENMASK(25, 21) +#define NPU_RX_DMA_CRSN_MASK GENMASK(20, 16) +#define NPU_RX_DMA_FOE_ID_MASK GENMASK(15, 0) +/* DATA */ +#define NPU_RX_DMA_SID_MASK GENMASK(31, 16) +#define NPU_RX_DMA_FRAG_TYPE_MASK GENMASK(15, 14) +#define NPU_RX_DMA_PRIORITY_MASK GENMASK(13, 10) +#define NPU_RX_DMA_RADIO_ID_MASK GENMASK(9, 6) +#define NPU_RX_DMA_VAP_ID_MASK GENMASK(5, 2) +#define NPU_RX_DMA_FRAME_TYPE_MASK GENMASK(1, 0) + +struct airoha_npu_rx_dma_desc { + u32 ctrl; + u32 info; + u32 data; + u32 addr; + u64 rsv; +} __packed; + +/* CTRL */ +#define NPU_TX_DMA_DESC_SCHED_MASK BIT(31) +#define NPU_TX_DMA_DESC_LEN_MASK GENMASK(30, 18) +#define NPU_TX_DMA_DESC_VEND_LEN_MASK GENMASK(17, 1) +#define NPU_TX_DMA_DESC_DONE_MASK BIT(0) + +#define NPU_TXWI_LEN 192 + +struct airoha_npu_tx_dma_desc { + u32 ctrl; + u32 addr; + u64 rsv; + u8 txwi[NPU_TXWI_LEN]; +} __packed; + +struct airoha_npu { +#if (IS_BUILTIN(CONFIG_NET_AIROHA_NPU) || IS_MODULE(CONFIG_NET_AIROHA_NPU)) + struct device *dev; + struct regmap *regmap; + + struct airoha_npu_core { + struct airoha_npu *npu; + /* protect concurrent npu memory accesses */ + spinlock_t lock; + struct work_struct wdt_work; + } cores[NPU_NUM_CORES]; + + int irqs[NPU_NUM_IRQ]; + + struct airoha_foe_stats __iomem *stats; + + struct { + int (*ppe_init)(struct airoha_npu *npu); + int (*ppe_deinit)(struct airoha_npu *npu); + int (*ppe_flush_sram_entries)(struct airoha_npu *npu, + dma_addr_t foe_addr, + int sram_num_entries); + int (*ppe_foe_commit_entry)(struct airoha_npu *npu, + dma_addr_t foe_addr, + u32 entry_size, u32 hash, + bool ppe2); + int (*wlan_init_reserved_memory)(struct airoha_npu *npu); + int (*wlan_set_txrx_reg_addr)(struct airoha_npu *npu, + int ifindex, u32 dir, + u32 in_counter_addr, + u32 out_status_addr, + u32 out_counter_addr); + int (*wlan_set_pcie_port_type)(struct airoha_npu *npu, + int ifindex, u32 port_type); + int (*wlan_set_pcie_addr)(struct airoha_npu *npu, int ifindex, + u32 addr); + int (*wlan_set_desc)(struct airoha_npu *npu, int ifindex, + u32 desc); + int (*wlan_set_tx_ring_pcie_addr)(struct airoha_npu *npu, + int ifindex, u32 addr); + int (*wlan_get_rx_desc_base)(struct airoha_npu *npu, + int ifindex, u32 *data); + int (*wlan_set_tx_buf_space_base)(struct airoha_npu *npu, + int ifindex, u32 addr); + int (*wlan_set_rx_ring_for_txdone)(struct airoha_npu *npu, + int ifindex, u32 addr); + u32 (*wlan_get_queue_addr)(struct airoha_npu *npu, int qid, + bool xmit); + void (*wlan_set_irq_status)(struct airoha_npu *npu, u32 val); + u32 (*wlan_get_irq_status)(struct airoha_npu *npu, int q); + void (*wlan_enable_irq)(struct airoha_npu *npu, int q); + void (*wlan_disable_irq)(struct airoha_npu *npu, int q); + } ops; +#endif +}; + +#if (IS_BUILTIN(CONFIG_NET_AIROHA_NPU) || IS_MODULE(CONFIG_NET_AIROHA_NPU)) +struct airoha_npu *airoha_npu_get(struct device *dev, dma_addr_t *stats_addr); +void airoha_npu_put(struct airoha_npu *npu); + +static inline int airoha_npu_wlan_init_reserved_memory(struct airoha_npu *npu) +{ + return npu->ops.wlan_init_reserved_memory(npu); +} + +static inline int airoha_npu_wlan_set_txrx_reg_addr(struct airoha_npu *npu, + int ifindex, u32 dir, + u32 in_counter_addr, + u32 out_status_addr, + u32 out_counter_addr) +{ + return npu->ops.wlan_set_txrx_reg_addr(npu, ifindex, dir, + in_counter_addr, + out_status_addr, + out_counter_addr); +} + +static inline int airoha_npu_wlan_set_pcie_port_type(struct airoha_npu *npu, + int ifindex, + u32 port_type) +{ + return npu->ops.wlan_set_pcie_port_type(npu, ifindex, port_type); +} + +static inline int airoha_npu_wlan_set_pcie_addr(struct airoha_npu *npu, + int ifindex, u32 addr) +{ + return npu->ops.wlan_set_pcie_addr(npu, ifindex, addr); +} + +static inline int airoha_npu_wlan_set_desc(struct airoha_npu *npu, int ifindex, + u32 desc) +{ + return npu->ops.wlan_set_desc(npu, ifindex, desc); +} + +static inline int airoha_npu_wlan_set_tx_ring_pcie_addr(struct airoha_npu *npu, + int ifindex, u32 addr) +{ + return npu->ops.wlan_set_tx_ring_pcie_addr(npu, ifindex, addr); +} + +static inline int airoha_npu_wlan_get_rx_desc_base(struct airoha_npu *npu, int ifindex, + u32 *data) +{ + return npu->ops.wlan_get_rx_desc_base(npu, ifindex, data); +} + +static inline int airoha_npu_wlan_set_tx_buf_space_base(struct airoha_npu *npu, + int ifindex, u32 addr) +{ + return npu->ops.wlan_set_tx_buf_space_base(npu, ifindex, addr); +} + +static inline int airoha_npu_wlan_set_rx_ring_for_txdone(struct airoha_npu *npu, + int ifindex, u32 addr) +{ + return npu->ops.wlan_set_rx_ring_for_txdone(npu, ifindex, addr); +} + +static inline u32 airoha_npu_wlan_get_queue_addr(struct airoha_npu *npu, int qid, + bool xmit) +{ + return npu->ops.wlan_get_queue_addr(npu, qid, xmit); +} + +static inline void airoha_npu_wlan_set_irq_status(struct airoha_npu *npu, + u32 val) +{ + npu->ops.wlan_set_irq_status(npu, val); +} + +static inline u32 airoha_npu_wlan_get_irq_status(struct airoha_npu *npu, int q) +{ + return npu->ops.wlan_get_irq_status(npu, q); +} + +static inline void airoha_npu_wlan_enable_irq(struct airoha_npu *npu, int q) +{ + npu->ops.wlan_enable_irq(npu, q); +} + +static inline void airoha_npu_wlan_disable_irq(struct airoha_npu *npu, int q) +{ + npu->ops.wlan_disable_irq(npu, q); +} +#else +static inline struct airoha_npu *airoha_npu_get(struct device *dev, + dma_addr_t *foe_stats_addr) +{ + return NULL; +} + +static inline void airoha_npu_put(struct airoha_npu *npu) +{ +} + +static inline int airoha_npu_wlan_init_reserved_memory(struct airoha_npu *npu) +{ + return -EOPNOTSUPP; +} + +static inline int airoha_npu_wlan_set_txrx_reg_addr(struct airoha_npu *npu, + int ifindex, u32 dir, + u32 in_counter_addr, + u32 out_status_addr, + u32 out_counter_addr) +{ + return -EOPNOTSUPP; +} + +static inline int airoha_npu_wlan_set_pcie_port_type(struct airoha_npu *npu, + int ifindex, u32 port_type) +{ + return -EOPNOTSUPP; +} + +static inline int airoha_npu_wlan_set_pcie_addr(struct airoha_npu *npu, + int ifindex, u32 addr) +{ + return -EOPNOTSUPP; +} + +static inline int airoha_npu_wlan_set_desc(struct airoha_npu *npu, int ifindex, + u32 desc) +{ + return -EOPNOTSUPP; +} + +static inline int airoha_npu_wlan_set_tx_ring_pcie_addr(struct airoha_npu *npu, + int ifindex, u32 addr) +{ + return -EOPNOTSUPP; +} + +static inline int airoha_npu_wlan_get_rx_desc_base(struct airoha_npu *npu, + int ifindex, u32 *data) +{ + return -EOPNOTSUPP; +} + +static inline int airoha_npu_wlan_set_tx_buf_space_base(struct airoha_npu *npu, + int ifindex, u32 addr) +{ + return -EOPNOTSUPP; +} + +static inline int airoha_npu_wlan_set_rx_ring_for_txdone(struct airoha_npu *npu, + int ifindex, u32 addr) +{ + return -EOPNOTSUPP; +} + +static inline u32 airoha_npu_wlan_get_queue_addr(struct airoha_npu *npu, + int qid, bool xmit) +{ + return 0; +} + +static inline void airoha_npu_wlan_set_irq_status(struct airoha_npu *npu, + u32 val) +{ +} + +static inline u32 airoha_npu_wlan_get_irq_status(struct airoha_npu *npu, + int q) +{ + return 0; +} + +static inline void airoha_npu_wlan_enable_irq(struct airoha_npu *npu, int q) +{ +} + +static inline void airoha_npu_wlan_disable_irq(struct airoha_npu *npu, int q) +{ +} +#endif + +#endif /* AIROHA_OFFLOAD_H */ -- 2.50.0