cndm: Use event queues in driver

Signed-off-by: Alex Forencich <alex@alexforencich.com>
This commit is contained in:
Alex Forencich
2026-03-10 13:06:40 -07:00
parent d7eb1b21a2
commit 962950a1e3
7 changed files with 110 additions and 26 deletions

View File

@@ -12,6 +12,7 @@ cndm-y += cndm_dev.o
cndm-y += cndm_netdev.o cndm-y += cndm_netdev.o
cndm-y += cndm_ethtool.o cndm-y += cndm_ethtool.o
cndm-y += cndm_ptp.o cndm-y += cndm_ptp.o
cndm-y += cndm_eq.o
cndm-y += cndm_cq.o cndm-y += cndm_cq.o
cndm-y += cndm_sq.o cndm-y += cndm_sq.o
cndm-y += cndm_rq.o cndm-y += cndm_rq.o

View File

@@ -173,7 +173,7 @@ struct cndm_cq {
int enabled; int enabled;
struct cndm_ring *src_ring; struct cndm_ring *src_ring;
struct cndm_eq *eq;
struct cndm_irq *irq; struct cndm_irq *irq;
struct notifier_block irq_nb; struct notifier_block irq_nb;
@@ -183,6 +183,35 @@ struct cndm_cq {
u8 __iomem *db_addr; u8 __iomem *db_addr;
}; };
struct cndm_eq {
u32 cons_ptr;
u32 size;
u32 size_mask;
u32 stride;
size_t buf_size;
u8 *buf;
dma_addr_t buf_dma_addr;
struct device *dev;
struct cndm_dev *cdev;
struct cndm_priv *priv;
int eqn;
int enabled;
struct cndm_irq *irq;
struct notifier_block irq_nb;
void (*handler)(struct cndm_eq *eq);
spinlock_t table_lock;
struct radix_tree_root cq_table;
u32 db_offset;
u8 __iomem *db_addr;
};
struct cndm_priv { struct cndm_priv {
struct device *dev; struct device *dev;
struct net_device *ndev; struct net_device *ndev;
@@ -198,6 +227,8 @@ struct cndm_priv {
int rxq_count; int rxq_count;
int txq_count; int txq_count;
struct cndm_eq *eq;
struct cndm_ring *txq; struct cndm_ring *txq;
struct cndm_ring *rxq; struct cndm_ring *rxq;
}; };
@@ -230,10 +261,20 @@ ktime_t cndm_read_cpl_ts(struct cndm_ring *ring, const struct cndm_cpl *cpl);
void cndm_register_phc(struct cndm_dev *cdev); void cndm_register_phc(struct cndm_dev *cdev);
void cndm_unregister_phc(struct cndm_dev *cdev); void cndm_unregister_phc(struct cndm_dev *cdev);
// cndm_eq.c
struct cndm_eq *cndm_create_eq(struct cndm_priv *priv);
void cndm_destroy_eq(struct cndm_eq *eq);
int cndm_open_eq(struct cndm_eq *eq, struct cndm_irq *irq, int size);
void cndm_close_eq(struct cndm_eq *eq);
int cndm_eq_attach_cq(struct cndm_eq *eq, struct cndm_cq *cq);
void cndm_eq_detach_cq(struct cndm_eq *eq, struct cndm_cq *cq);
void cndm_eq_write_cons_ptr(const struct cndm_eq *eq);
void cndm_eq_write_cons_ptr_arm(const struct cndm_eq *eq);
// cndm_cq.c // cndm_cq.c
struct cndm_cq *cndm_create_cq(struct cndm_priv *priv); struct cndm_cq *cndm_create_cq(struct cndm_priv *priv);
void cndm_destroy_cq(struct cndm_cq *cq); void cndm_destroy_cq(struct cndm_cq *cq);
int cndm_open_cq(struct cndm_cq *cq, struct cndm_irq *irq, int size); int cndm_open_cq(struct cndm_cq *cq, struct cndm_eq *eq, struct cndm_irq *irq, int size);
void cndm_close_cq(struct cndm_cq *cq); 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(const struct cndm_cq *cq);
void cndm_cq_write_cons_ptr_arm(const struct cndm_cq *cq); void cndm_cq_write_cons_ptr_arm(const struct cndm_cq *cq);

View File

@@ -10,14 +10,7 @@ Authors:
#include "cndm.h" #include "cndm.h"
static int cndm_cq_int(struct notifier_block *nb, unsigned long action, void *data) 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 *cndm_create_cq(struct cndm_priv *priv)
{ {
@@ -51,14 +44,15 @@ void cndm_destroy_cq(struct cndm_cq *cq)
kfree(cq); kfree(cq);
} }
int cndm_open_cq(struct cndm_cq *cq, struct cndm_irq *irq, int size) int cndm_open_cq(struct cndm_cq *cq, struct cndm_eq *eq, struct cndm_irq *irq, int size)
{ {
u32 dqn;
int ret = 0; int ret = 0;
struct cndm_cmd_queue cmd; struct cndm_cmd_queue cmd;
struct cndm_cmd_queue rsp; struct cndm_cmd_queue rsp;
if (cq->enabled || cq->buf || !irq) if (cq->enabled || cq->buf || (!irq && !eq))
return -EINVAL; return -EINVAL;
cq->size = roundup_pow_of_two(size); cq->size = roundup_pow_of_two(size);
@@ -70,12 +64,17 @@ int cndm_open_cq(struct cndm_cq *cq, struct cndm_irq *irq, int size)
if (!cq->buf) if (!cq->buf)
return -ENOMEM; return -ENOMEM;
if (irq) { // can use either EQ or IRQ, but prefer EQ if both are specified
if (eq) {
cq->eq = eq;
dqn = eq->eqn;
} else if (irq) {
ret = atomic_notifier_chain_register(&irq->nh, &cq->irq_nb); ret = atomic_notifier_chain_register(&irq->nh, &cq->irq_nb);
if (ret) if (ret)
goto fail; goto fail;
cq->irq = irq; cq->irq = irq;
dqn = irq->index | 0x80000000;
} }
cq->cons_ptr = 0; cq->cons_ptr = 0;
@@ -87,7 +86,7 @@ int cndm_open_cq(struct cndm_cq *cq, struct cndm_irq *irq, int size)
cmd.flags = 0x00000000; cmd.flags = 0x00000000;
cmd.port = cq->priv->ndev->dev_port; cmd.port = cq->priv->ndev->dev_port;
cmd.qn = 0; cmd.qn = 0;
cmd.qn2 = irq->index; // TODO cmd.qn2 = dqn;
cmd.pd = 0; cmd.pd = 0;
cmd.size = ilog2(cq->size); cmd.size = ilog2(cq->size);
cmd.dboffs = 0; cmd.dboffs = 0;
@@ -106,6 +105,10 @@ int cndm_open_cq(struct cndm_cq *cq, struct cndm_irq *irq, int size)
cq->db_offset = rsp.dboffs; cq->db_offset = rsp.dboffs;
cq->db_addr = cq->cdev->hw_addr + rsp.dboffs; cq->db_addr = cq->cdev->hw_addr + rsp.dboffs;
if (eq) {
cndm_eq_attach_cq(eq, cq);
}
cq->enabled = 1; cq->enabled = 1;
cndm_cq_write_cons_ptr_arm(cq); cndm_cq_write_cons_ptr_arm(cq);
@@ -140,6 +143,11 @@ void cndm_close_cq(struct cndm_cq *cq)
cq->db_addr = NULL; cq->db_addr = NULL;
} }
if (cq->eq) {
cndm_eq_detach_cq(cq->eq, cq);
cq->eq = NULL;
}
if (cq->irq) { if (cq->irq) {
atomic_notifier_chain_unregister(&cq->irq->nh, &cq->irq_nb); atomic_notifier_chain_unregister(&cq->irq->nh, &cq->irq_nb);
cq->irq = NULL; cq->irq = NULL;
@@ -161,3 +169,13 @@ void cndm_cq_write_cons_ptr_arm(const struct cndm_cq *cq)
{ {
iowrite32((cq->cons_ptr & 0xffff) | 0x80000000, cq->db_addr); iowrite32((cq->cons_ptr & 0xffff) | 0x80000000, cq->db_addr);
} }
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);
if (likely(cq->handler))
cq->handler(cq);
return NOTIFY_DONE;
}

View File

@@ -202,14 +202,10 @@ struct cndm_cpl {
}; };
struct cndm_event { struct cndm_event {
__le16 rsvd0;
__le16 type; __le16 type;
__le16 source; __le32 source;
__le32 rsvd0;
__le32 rsvd1; __le32 rsvd1;
__le32 rsvd2;
__le32 rsvd3;
__le32 rsvd4;
__le32 rsvd5;
__le32 phase; __le32 phase;
}; };

View File

@@ -38,7 +38,7 @@ static int cndm_open(struct net_device *ndev)
goto fail; goto fail;
} }
ret = cndm_open_cq(cq, &priv->cdev->irq[0], 256); ret = cndm_open_cq(cq, priv->eq, &priv->cdev->irq[0], 256);
if (ret) { if (ret) {
cndm_destroy_cq(cq); cndm_destroy_cq(cq);
goto fail; goto fail;
@@ -75,7 +75,7 @@ static int cndm_open(struct net_device *ndev)
goto fail; goto fail;
} }
ret = cndm_open_cq(cq, &priv->cdev->irq[0], 256); ret = cndm_open_cq(cq, priv->eq, &priv->cdev->irq[0], 256);
if (ret) { if (ret) {
cndm_destroy_cq(cq); cndm_destroy_cq(cq);
goto fail; goto fail;
@@ -326,6 +326,19 @@ struct net_device *cndm_create_netdev(struct cndm_dev *cdev, int port)
ndev->min_mtu = ETH_MIN_MTU; ndev->min_mtu = ETH_MIN_MTU;
ndev->max_mtu = 1500; ndev->max_mtu = 1500;
priv->eq = cndm_create_eq(priv);
if (IS_ERR_OR_NULL(priv->eq)) {
ret = PTR_ERR(priv->eq);
priv->eq = NULL;
goto fail;
}
ret = cndm_open_eq(priv->eq, &priv->cdev->irq[0], 256);
if (ret) {
cndm_destroy_eq(priv->eq);
goto fail;
}
netif_carrier_off(ndev); netif_carrier_off(ndev);
ret = register_netdev(ndev); ret = register_netdev(ndev);
@@ -350,5 +363,8 @@ void cndm_destroy_netdev(struct net_device *ndev)
if (priv->registered) if (priv->registered)
unregister_netdev(ndev); unregister_netdev(ndev);
if (priv->eq)
cndm_destroy_eq(priv->eq);
free_netdev(ndev); free_netdev(ndev);
} }

View File

@@ -10,6 +10,8 @@ Authors:
#include "cndm.h" #include "cndm.h"
static void cndm_rq_cq_handler(struct cndm_cq *cq);
struct cndm_ring *cndm_create_rq(struct cndm_priv *priv) struct cndm_ring *cndm_create_rq(struct cndm_priv *priv)
{ {
struct cndm_ring *rq; struct cndm_ring *rq;
@@ -69,7 +71,7 @@ int cndm_open_rq(struct cndm_ring *rq, struct cndm_priv *priv, struct cndm_cq *c
rq->priv = priv; rq->priv = priv;
rq->cq = cq; rq->cq = cq;
cq->src_ring = rq; cq->src_ring = rq;
// cq->handler = cndm_rx_irq; cq->handler = cndm_rq_cq_handler;
rq->prod_ptr = 0; rq->prod_ptr = 0;
rq->cons_ptr = 0; rq->cons_ptr = 0;
@@ -352,6 +354,11 @@ rx_drop:
return done; return done;
} }
static void cndm_rq_cq_handler(struct cndm_cq *cq)
{
napi_schedule_irqoff(&cq->napi);
}
int cndm_poll_rx_cq(struct napi_struct *napi, int budget) int cndm_poll_rx_cq(struct napi_struct *napi, int budget)
{ {
struct cndm_cq *cq = container_of(napi, struct cndm_cq, napi); struct cndm_cq *cq = container_of(napi, struct cndm_cq, napi);
@@ -364,7 +371,6 @@ int cndm_poll_rx_cq(struct napi_struct *napi, int budget)
napi_complete(napi); napi_complete(napi);
// TODO re-enable interrupts
cndm_cq_write_cons_ptr_arm(cq); cndm_cq_write_cons_ptr_arm(cq);
return done; return done;

View File

@@ -10,6 +10,8 @@ Authors:
#include "cndm.h" #include "cndm.h"
static void cndm_sq_cq_handler(struct cndm_cq *cq);
struct cndm_ring *cndm_create_sq(struct cndm_priv *priv) struct cndm_ring *cndm_create_sq(struct cndm_priv *priv)
{ {
struct cndm_ring *sq; struct cndm_ring *sq;
@@ -69,7 +71,7 @@ int cndm_open_sq(struct cndm_ring *sq, struct cndm_priv *priv, struct cndm_cq *c
sq->priv = priv; sq->priv = priv;
sq->cq = cq; sq->cq = cq;
cq->src_ring = sq; cq->src_ring = sq;
// cq->handler = cndm_tx_irq; cq->handler = cndm_sq_cq_handler;
sq->prod_ptr = 0; sq->prod_ptr = 0;
sq->cons_ptr = 0; sq->cons_ptr = 0;
@@ -252,6 +254,11 @@ static int cndm_process_tx_cq(struct cndm_cq *cq, int napi_budget)
return done; return done;
} }
static void cndm_sq_cq_handler(struct cndm_cq *cq)
{
napi_schedule_irqoff(&cq->napi);
}
int cndm_poll_tx_cq(struct napi_struct *napi, int budget) int cndm_poll_tx_cq(struct napi_struct *napi, int budget)
{ {
struct cndm_cq *cq = container_of(napi, struct cndm_cq, napi); struct cndm_cq *cq = container_of(napi, struct cndm_cq, napi);
@@ -264,7 +271,6 @@ int cndm_poll_tx_cq(struct napi_struct *napi, int budget)
napi_complete(napi); napi_complete(napi);
// TODO re-enable interrupts
cndm_cq_write_cons_ptr_arm(cq); cndm_cq_write_cons_ptr_arm(cq);
return done; return done;