mirror of
https://github.com/corundum/corundum.git
synced 2025-02-06 08:38:23 +08:00
Rework interrupt handling
This commit is contained in:
parent
bee056e7d3
commit
49103b9df9
@ -77,6 +77,8 @@ struct mqnic_dev {
|
|||||||
|
|
||||||
char name[16];
|
char name[16];
|
||||||
|
|
||||||
|
int msi_nvecs;
|
||||||
|
|
||||||
unsigned int id;
|
unsigned int id;
|
||||||
struct list_head dev_list_node;
|
struct list_head dev_list_node;
|
||||||
|
|
||||||
@ -201,6 +203,8 @@ struct mqnic_eq_ring {
|
|||||||
struct net_device *ndev;
|
struct net_device *ndev;
|
||||||
int int_index;
|
int int_index;
|
||||||
|
|
||||||
|
int irq;
|
||||||
|
|
||||||
void (*handler) (struct mqnic_eq_ring *);
|
void (*handler) (struct mqnic_eq_ring *);
|
||||||
|
|
||||||
u32 hw_ptr_mask;
|
u32 hw_ptr_mask;
|
||||||
|
@ -94,6 +94,39 @@ done:
|
|||||||
return mqnic;
|
return mqnic;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static irqreturn_t mqnic_interrupt(int irq, void *data)
|
||||||
|
{
|
||||||
|
struct mqnic_dev *mqnic = data;
|
||||||
|
struct mqnic_priv *priv;
|
||||||
|
|
||||||
|
int k, l;
|
||||||
|
|
||||||
|
for (k = 0; k < MQNIC_MAX_IF; k++)
|
||||||
|
{
|
||||||
|
if (!mqnic->ndev[k])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
priv = netdev_priv(mqnic->ndev[k]);
|
||||||
|
|
||||||
|
if (unlikely(!priv->port_up))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (l = 0; l < priv->event_queue_count; l++)
|
||||||
|
{
|
||||||
|
if (unlikely(!priv->event_ring[l]))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (priv->event_ring[l]->irq == irq)
|
||||||
|
{
|
||||||
|
mqnic_process_eq(priv->ndev, priv->event_ring[l]);
|
||||||
|
mqnic_arm_eq(priv->event_ring[l]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return IRQ_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
static int mqnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
static int mqnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@ -203,13 +236,24 @@ static int mqnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||||||
dev_info(dev, "IF CSR offset: 0x%08x", mqnic->if_csr_offset);
|
dev_info(dev, "IF CSR offset: 0x%08x", mqnic->if_csr_offset);
|
||||||
|
|
||||||
// Allocate MSI IRQs
|
// Allocate MSI IRQs
|
||||||
ret = pci_alloc_irq_vectors(pdev, 1, 32, PCI_IRQ_MSI);
|
mqnic->msi_nvecs = pci_alloc_irq_vectors(pdev, 1, 32, PCI_IRQ_MSI);
|
||||||
if (ret < 0)
|
if (mqnic->msi_nvecs < 0)
|
||||||
{
|
{
|
||||||
dev_err(dev, "Failed to allocate IRQs");
|
dev_err(dev, "Failed to allocate IRQs");
|
||||||
goto fail_map_bars;
|
goto fail_map_bars;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set up interrupts
|
||||||
|
for (k = 0; k < mqnic->msi_nvecs; k++)
|
||||||
|
{
|
||||||
|
ret = pci_request_irq(pdev, k, mqnic_interrupt, 0, mqnic, "mqnic");
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
dev_err(dev, "Failed to request IRQ");
|
||||||
|
goto fail_irq;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Set up I2C interfaces
|
// Set up I2C interfaces
|
||||||
ret = mqnic_init_i2c(mqnic);
|
ret = mqnic_init_i2c(mqnic);
|
||||||
if (ret)
|
if (ret)
|
||||||
@ -285,6 +329,11 @@ fail_init_netdev:
|
|||||||
pci_clear_master(pdev);
|
pci_clear_master(pdev);
|
||||||
fail_i2c:
|
fail_i2c:
|
||||||
mqnic_remove_i2c(mqnic);
|
mqnic_remove_i2c(mqnic);
|
||||||
|
for (k = 0; k < mqnic->msi_nvecs; k++)
|
||||||
|
{
|
||||||
|
pci_free_irq(pdev, k, mqnic);
|
||||||
|
}
|
||||||
|
fail_irq:
|
||||||
pci_free_irq_vectors(pdev);
|
pci_free_irq_vectors(pdev);
|
||||||
fail_map_bars:
|
fail_map_bars:
|
||||||
pci_iounmap(pdev, mqnic->hw_addr);
|
pci_iounmap(pdev, mqnic->hw_addr);
|
||||||
@ -329,6 +378,10 @@ static void mqnic_remove(struct pci_dev *pdev)
|
|||||||
|
|
||||||
pci_clear_master(pdev);
|
pci_clear_master(pdev);
|
||||||
mqnic_remove_i2c(mqnic);
|
mqnic_remove_i2c(mqnic);
|
||||||
|
for (k = 0; k < mqnic->msi_nvecs; k++)
|
||||||
|
{
|
||||||
|
pci_free_irq(pdev, k, mqnic);
|
||||||
|
}
|
||||||
pci_free_irq_vectors(pdev);
|
pci_free_irq_vectors(pdev);
|
||||||
pci_iounmap(pdev, mqnic->hw_addr);
|
pci_iounmap(pdev, mqnic->hw_addr);
|
||||||
pci_release_regions(pdev);
|
pci_release_regions(pdev);
|
||||||
|
@ -44,14 +44,15 @@ static int mqnic_open(struct net_device *ndev)
|
|||||||
// set up event queues
|
// set up event queues
|
||||||
for (k = 0; k < priv->event_queue_count; k++)
|
for (k = 0; k < priv->event_queue_count; k++)
|
||||||
{
|
{
|
||||||
mqnic_activate_eq_ring(priv, priv->event_ring[k], priv->port); // TODO interrupt index
|
priv->event_ring[k]->irq = pci_irq_vector(mdev->pdev, k % mdev->msi_nvecs);
|
||||||
|
mqnic_activate_eq_ring(priv, priv->event_ring[k], k % mdev->msi_nvecs);
|
||||||
mqnic_arm_eq(priv->event_ring[k]);
|
mqnic_arm_eq(priv->event_ring[k]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set up RX completion queues
|
// set up RX completion queues
|
||||||
for (k = 0; k < priv->rx_cpl_queue_count; k++)
|
for (k = 0; k < priv->rx_cpl_queue_count; k++)
|
||||||
{
|
{
|
||||||
mqnic_activate_cq_ring(priv, priv->rx_cpl_ring[k], 0); // TODO configure/constant
|
mqnic_activate_cq_ring(priv, priv->rx_cpl_ring[k], k % priv->event_queue_count);
|
||||||
priv->rx_cpl_ring[k]->ring_index = k;
|
priv->rx_cpl_ring[k]->ring_index = k;
|
||||||
priv->rx_cpl_ring[k]->handler = mqnic_rx_irq;
|
priv->rx_cpl_ring[k]->handler = mqnic_rx_irq;
|
||||||
|
|
||||||
@ -70,7 +71,7 @@ static int mqnic_open(struct net_device *ndev)
|
|||||||
// set up TX completion queues
|
// set up TX completion queues
|
||||||
for (k = 0; k < priv->tx_cpl_queue_count; k++)
|
for (k = 0; k < priv->tx_cpl_queue_count; k++)
|
||||||
{
|
{
|
||||||
mqnic_activate_cq_ring(priv, priv->tx_cpl_ring[k], 0); // TODO configure/constant
|
mqnic_activate_cq_ring(priv, priv->tx_cpl_ring[k], k % priv->event_queue_count);
|
||||||
priv->tx_cpl_ring[k]->ring_index = k;
|
priv->tx_cpl_ring[k]->ring_index = k;
|
||||||
priv->tx_cpl_ring[k]->handler = mqnic_tx_irq;
|
priv->tx_cpl_ring[k]->handler = mqnic_tx_irq;
|
||||||
|
|
||||||
@ -311,27 +312,6 @@ static const struct net_device_ops mqnic_netdev_ops = {
|
|||||||
.ndo_do_ioctl = mqnic_ioctl,
|
.ndo_do_ioctl = mqnic_ioctl,
|
||||||
};
|
};
|
||||||
|
|
||||||
static irqreturn_t mqnic_netdev_interrupt(int irq, void *data)
|
|
||||||
{
|
|
||||||
struct mqnic_priv *priv = data;
|
|
||||||
|
|
||||||
int k;
|
|
||||||
|
|
||||||
if (likely(priv->port_up))
|
|
||||||
{
|
|
||||||
for (k = 0; k < priv->event_queue_count; k++)
|
|
||||||
{
|
|
||||||
if (likely(priv->event_ring[k]))
|
|
||||||
{
|
|
||||||
mqnic_process_eq(priv->ndev, priv->event_ring[k]);
|
|
||||||
mqnic_arm_eq(priv->event_ring[k]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return IRQ_HANDLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mqnic_init_netdev(struct mqnic_dev *mdev, int port, u8 __iomem *hw_addr)
|
int mqnic_init_netdev(struct mqnic_dev *mdev, int port, u8 __iomem *hw_addr)
|
||||||
{
|
{
|
||||||
struct device *dev = &mdev->pdev->dev;
|
struct device *dev = &mdev->pdev->dev;
|
||||||
@ -421,15 +401,6 @@ int mqnic_init_netdev(struct mqnic_dev *mdev, int port, u8 __iomem *hw_addr)
|
|||||||
netif_set_real_num_tx_queues(ndev, priv->tx_queue_count);
|
netif_set_real_num_tx_queues(ndev, priv->tx_queue_count);
|
||||||
netif_set_real_num_rx_queues(ndev, priv->rx_queue_count);
|
netif_set_real_num_rx_queues(ndev, priv->rx_queue_count);
|
||||||
|
|
||||||
// Set up interrupt
|
|
||||||
ret = pci_request_irq(mdev->pdev, priv->port, mqnic_netdev_interrupt, 0, priv, "mqnic%d", priv->port);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
dev_err(dev, "Failed to request IRQ");
|
|
||||||
free_netdev(ndev);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set MAC
|
// set MAC
|
||||||
ndev->addr_len = ETH_ALEN;
|
ndev->addr_len = ETH_ALEN;
|
||||||
memcpy(ndev->dev_addr, mdev->base_mac, ETH_ALEN);
|
memcpy(ndev->dev_addr, mdev->base_mac, ETH_ALEN);
|
||||||
@ -608,7 +579,6 @@ void mqnic_destroy_netdev(struct net_device *ndev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pci_free_irq(mdev->pdev, priv->port, priv);
|
|
||||||
free_netdev(ndev);
|
free_netdev(ndev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user