mirror of
https://github.com/fpganinja/taxi.git
synced 2026-04-07 04:38:42 -07:00
cndm: Move interrupt handling out of CQ
Signed-off-by: Alex Forencich <alex@alexforencich.com>
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user