From ed61857bc38ee2a8146938a47a8c1235945dec27 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 9 Mar 2026 22:23:56 -0700 Subject: [PATCH] cndm: Move interrupt handling out of CQ Signed-off-by: Alex Forencich --- src/cndm/modules/cndm/cndm.h | 8 ++++---- src/cndm/modules/cndm/cndm_cq.c | 30 +++++++++++++++++++++++++--- src/cndm/modules/cndm/cndm_netdev.c | 31 ++--------------------------- 3 files changed, 33 insertions(+), 36 deletions(-) diff --git a/src/cndm/modules/cndm/cndm.h b/src/cndm/modules/cndm/cndm.h index 4ab65a1..bfa533d 100644 --- a/src/cndm/modules/cndm/cndm.h +++ b/src/cndm/modules/cndm/cndm.h @@ -174,6 +174,9 @@ struct cndm_cq { struct cndm_ring *src_ring; + struct cndm_irq *irq; + struct notifier_block irq_nb; + void (*handler)(struct cndm_cq *cq); u32 db_offset; @@ -190,9 +193,6 @@ struct cndm_priv { void __iomem *hw_addr; - struct cndm_irq *irq; - struct notifier_block irq_nb; - struct hwtstamp_config hwts_config; int rxq_count; @@ -233,7 +233,7 @@ void cndm_unregister_phc(struct cndm_dev *cdev); // cndm_cq.c struct cndm_cq *cndm_create_cq(struct cndm_priv *priv); void cndm_destroy_cq(struct cndm_cq *cq); -int cndm_open_cq(struct cndm_cq *cq, int irqn, int size); +int cndm_open_cq(struct cndm_cq *cq, struct cndm_irq *irq, int size); void cndm_close_cq(struct cndm_cq *cq); void cndm_cq_write_cons_ptr(const struct cndm_cq *cq); void cndm_cq_write_cons_ptr_arm(const struct cndm_cq *cq); diff --git a/src/cndm/modules/cndm/cndm_cq.c b/src/cndm/modules/cndm/cndm_cq.c index c388902..90e3741 100644 --- a/src/cndm/modules/cndm/cndm_cq.c +++ b/src/cndm/modules/cndm/cndm_cq.c @@ -10,6 +10,15 @@ Authors: #include "cndm.h" +static int cndm_cq_int(struct notifier_block *nb, unsigned long action, void *data) +{ + struct cndm_cq *cq = container_of(nb, struct cndm_cq, irq_nb); + + napi_schedule_irqoff(&cq->napi); + + return NOTIFY_DONE; +} + struct cndm_cq *cndm_create_cq(struct cndm_priv *priv) { struct cndm_cq *cq; @@ -25,6 +34,8 @@ struct cndm_cq *cndm_create_cq(struct cndm_priv *priv) cq->cqn = -1; cq->enabled = 0; + cq->irq_nb.notifier_call = cndm_cq_int; + cq->cons_ptr = 0; cq->db_offset = 0; @@ -40,14 +51,14 @@ void cndm_destroy_cq(struct cndm_cq *cq) kfree(cq); } -int cndm_open_cq(struct cndm_cq *cq, int irqn, int size) +int cndm_open_cq(struct cndm_cq *cq, struct cndm_irq *irq, int size) { int ret = 0; struct cndm_cmd_queue cmd; struct cndm_cmd_queue rsp; - if (cq->enabled || cq->buf) + if (cq->enabled || cq->buf || !irq) return -EINVAL; cq->size = roundup_pow_of_two(size); @@ -59,6 +70,14 @@ int cndm_open_cq(struct cndm_cq *cq, int irqn, int size) if (!cq->buf) return -ENOMEM; + if (irq) { + ret = atomic_notifier_chain_register(&irq->nh, &cq->irq_nb); + if (ret) + goto fail; + + cq->irq = irq; + } + cq->cons_ptr = 0; // clear all phase tag bits @@ -68,7 +87,7 @@ int cndm_open_cq(struct cndm_cq *cq, int irqn, int size) cmd.flags = 0x00000000; cmd.port = cq->priv->ndev->dev_port; cmd.qn = 0; - cmd.qn2 = irqn; // TODO + cmd.qn2 = irq->index; // TODO cmd.pd = 0; cmd.size = ilog2(cq->size); cmd.dboffs = 0; @@ -121,6 +140,11 @@ void cndm_close_cq(struct cndm_cq *cq) cq->db_addr = NULL; } + if (cq->irq) { + atomic_notifier_chain_unregister(&cq->irq->nh, &cq->irq_nb); + cq->irq = NULL; + } + if (cq->buf) { dma_free_coherent(cq->dev, cq->buf_size, cq->buf, cq->buf_dma_addr); cq->buf = NULL; diff --git a/src/cndm/modules/cndm/cndm_netdev.c b/src/cndm/modules/cndm/cndm_netdev.c index 717ab9e..02a7e7a 100644 --- a/src/cndm/modules/cndm/cndm_netdev.c +++ b/src/cndm/modules/cndm/cndm_netdev.c @@ -38,7 +38,7 @@ static int cndm_open(struct net_device *ndev) goto fail; } - ret = cndm_open_cq(cq, 0, 256); + ret = cndm_open_cq(cq, &priv->cdev->irq[0], 256); if (ret) { cndm_destroy_cq(cq); goto fail; @@ -75,7 +75,7 @@ static int cndm_open(struct net_device *ndev) goto fail; } - ret = cndm_open_cq(cq, 0, 256); + ret = cndm_open_cq(cq, &priv->cdev->irq[0], 256); if (ret) { cndm_destroy_cq(cq); goto fail; @@ -278,20 +278,6 @@ static const struct net_device_ops cndm_netdev_ops = { #endif }; -static int cndm_netdev_irq(struct notifier_block *nb, unsigned long action, void *data) -{ - struct cndm_priv *priv = container_of(nb, struct cndm_priv, irq_nb); - - netdev_dbg(priv->ndev, "Interrupt"); - - if (priv->port_up) { - napi_schedule_irqoff(&priv->txq->cq->napi); - napi_schedule_irqoff(&priv->rxq->cq->napi); - } - - return NOTIFY_DONE; -} - struct net_device *cndm_create_netdev(struct cndm_dev *cdev, int port) { struct device *dev = cdev->dev; @@ -350,14 +336,6 @@ struct net_device *cndm_create_netdev(struct cndm_dev *cdev, int port) priv->registered = 1; - priv->irq_nb.notifier_call = cndm_netdev_irq; - priv->irq = &cdev->irq[port % cdev->irq_count]; - ret = atomic_notifier_chain_register(&priv->irq->nh, &priv->irq_nb); - if (ret) { - priv->irq = NULL; - goto fail; - } - return ndev; fail: @@ -372,10 +350,5 @@ void cndm_destroy_netdev(struct net_device *ndev) if (priv->registered) unregister_netdev(ndev); - if (priv->irq) - atomic_notifier_chain_unregister(&priv->irq->nh, &priv->irq_nb); - - priv->irq = NULL; - free_netdev(ndev); }