mirror of
https://github.com/fpganinja/taxi.git
synced 2026-04-07 12:38:44 -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_ring *src_ring;
|
||||||
|
|
||||||
|
struct cndm_irq *irq;
|
||||||
|
struct notifier_block irq_nb;
|
||||||
|
|
||||||
void (*handler)(struct cndm_cq *cq);
|
void (*handler)(struct cndm_cq *cq);
|
||||||
|
|
||||||
u32 db_offset;
|
u32 db_offset;
|
||||||
@@ -190,9 +193,6 @@ struct cndm_priv {
|
|||||||
|
|
||||||
void __iomem *hw_addr;
|
void __iomem *hw_addr;
|
||||||
|
|
||||||
struct cndm_irq *irq;
|
|
||||||
struct notifier_block irq_nb;
|
|
||||||
|
|
||||||
struct hwtstamp_config hwts_config;
|
struct hwtstamp_config hwts_config;
|
||||||
|
|
||||||
int rxq_count;
|
int rxq_count;
|
||||||
@@ -233,7 +233,7 @@ void cndm_unregister_phc(struct cndm_dev *cdev);
|
|||||||
// 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, 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_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);
|
||||||
|
|||||||
@@ -10,6 +10,15 @@ Authors:
|
|||||||
|
|
||||||
#include "cndm.h"
|
#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 *cndm_create_cq(struct cndm_priv *priv)
|
||||||
{
|
{
|
||||||
struct cndm_cq *cq;
|
struct cndm_cq *cq;
|
||||||
@@ -25,6 +34,8 @@ struct cndm_cq *cndm_create_cq(struct cndm_priv *priv)
|
|||||||
cq->cqn = -1;
|
cq->cqn = -1;
|
||||||
cq->enabled = 0;
|
cq->enabled = 0;
|
||||||
|
|
||||||
|
cq->irq_nb.notifier_call = cndm_cq_int;
|
||||||
|
|
||||||
cq->cons_ptr = 0;
|
cq->cons_ptr = 0;
|
||||||
|
|
||||||
cq->db_offset = 0;
|
cq->db_offset = 0;
|
||||||
@@ -40,14 +51,14 @@ void cndm_destroy_cq(struct cndm_cq *cq)
|
|||||||
kfree(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;
|
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)
|
if (cq->enabled || cq->buf || !irq)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
cq->size = roundup_pow_of_two(size);
|
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)
|
if (!cq->buf)
|
||||||
return -ENOMEM;
|
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;
|
cq->cons_ptr = 0;
|
||||||
|
|
||||||
// clear all phase tag bits
|
// 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.flags = 0x00000000;
|
||||||
cmd.port = cq->priv->ndev->dev_port;
|
cmd.port = cq->priv->ndev->dev_port;
|
||||||
cmd.qn = 0;
|
cmd.qn = 0;
|
||||||
cmd.qn2 = irqn; // TODO
|
cmd.qn2 = irq->index; // TODO
|
||||||
cmd.pd = 0;
|
cmd.pd = 0;
|
||||||
cmd.size = ilog2(cq->size);
|
cmd.size = ilog2(cq->size);
|
||||||
cmd.dboffs = 0;
|
cmd.dboffs = 0;
|
||||||
@@ -121,6 +140,11 @@ void cndm_close_cq(struct cndm_cq *cq)
|
|||||||
cq->db_addr = NULL;
|
cq->db_addr = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cq->irq) {
|
||||||
|
atomic_notifier_chain_unregister(&cq->irq->nh, &cq->irq_nb);
|
||||||
|
cq->irq = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (cq->buf) {
|
if (cq->buf) {
|
||||||
dma_free_coherent(cq->dev, cq->buf_size, cq->buf, cq->buf_dma_addr);
|
dma_free_coherent(cq->dev, cq->buf_size, cq->buf, cq->buf_dma_addr);
|
||||||
cq->buf = NULL;
|
cq->buf = NULL;
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ static int cndm_open(struct net_device *ndev)
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = cndm_open_cq(cq, 0, 256);
|
ret = cndm_open_cq(cq, &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, 0, 256);
|
ret = cndm_open_cq(cq, &priv->cdev->irq[0], 256);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
cndm_destroy_cq(cq);
|
cndm_destroy_cq(cq);
|
||||||
goto fail;
|
goto fail;
|
||||||
@@ -278,20 +278,6 @@ static const struct net_device_ops cndm_netdev_ops = {
|
|||||||
#endif
|
#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 net_device *cndm_create_netdev(struct cndm_dev *cdev, int port)
|
||||||
{
|
{
|
||||||
struct device *dev = cdev->dev;
|
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->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;
|
return ndev;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
@@ -372,10 +350,5 @@ void cndm_destroy_netdev(struct net_device *ndev)
|
|||||||
if (priv->registered)
|
if (priv->registered)
|
||||||
unregister_netdev(ndev);
|
unregister_netdev(ndev);
|
||||||
|
|
||||||
if (priv->irq)
|
|
||||||
atomic_notifier_chain_unregister(&priv->irq->nh, &priv->irq_nb);
|
|
||||||
|
|
||||||
priv->irq = NULL;
|
|
||||||
|
|
||||||
free_netdev(ndev);
|
free_netdev(ndev);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user