Commit 52358aad authored by Sunil Goutham's avatar Sunil Goutham Committed by David S. Miller

net: thunderx: Enable mailbox interrupts on 81xx/83xx

88xx has 128 VFs, 81xx has 8 VFs and 83xx will have 32VFs.
Made changes to PF driver such that mailbox interrupt enable
registers are configuired based on number of VFs HW supports.
Also cleanedup mailbox irq handler registration code.
Signed-off-by: default avatarSunil Goutham <sgoutham@cavium.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 02a72bd8
...@@ -66,8 +66,9 @@ struct nicpf { ...@@ -66,8 +66,9 @@ struct nicpf {
/* MSI-X */ /* MSI-X */
bool msix_enabled; bool msix_enabled;
u8 num_vec; u8 num_vec;
struct msix_entry msix_entries[NIC_PF_MSIX_VECTORS]; struct msix_entry *msix_entries;
bool irq_allocated[NIC_PF_MSIX_VECTORS]; bool irq_allocated[NIC_PF_MSIX_VECTORS];
char irq_name[NIC_PF_MSIX_VECTORS][20];
}; };
/* Supported devices */ /* Supported devices */
...@@ -105,9 +106,22 @@ static u64 nic_reg_read(struct nicpf *nic, u64 offset) ...@@ -105,9 +106,22 @@ static u64 nic_reg_read(struct nicpf *nic, u64 offset)
/* PF -> VF mailbox communication APIs */ /* PF -> VF mailbox communication APIs */
static void nic_enable_mbx_intr(struct nicpf *nic) static void nic_enable_mbx_intr(struct nicpf *nic)
{ {
/* Enable mailbox interrupt for all 128 VFs */ int vf_cnt = pci_sriov_get_totalvfs(nic->pdev);
nic_reg_write(nic, NIC_PF_MAILBOX_ENA_W1S, ~0ull);
nic_reg_write(nic, NIC_PF_MAILBOX_ENA_W1S + sizeof(u64), ~0ull); #define INTR_MASK(vfs) ((vfs < 64) ? (BIT_ULL(vfs) - 1) : (~0ull))
/* Clear it, to avoid spurious interrupts (if any) */
nic_reg_write(nic, NIC_PF_MAILBOX_INT, INTR_MASK(vf_cnt));
/* Enable mailbox interrupt for all VFs */
nic_reg_write(nic, NIC_PF_MAILBOX_ENA_W1S, INTR_MASK(vf_cnt));
/* One mailbox intr enable reg per 64 VFs */
if (vf_cnt > 64) {
nic_reg_write(nic, NIC_PF_MAILBOX_INT + sizeof(u64),
INTR_MASK(vf_cnt - 64));
nic_reg_write(nic, NIC_PF_MAILBOX_ENA_W1S + sizeof(u64),
INTR_MASK(vf_cnt - 64));
}
} }
static void nic_clear_mbx_intr(struct nicpf *nic, int vf, int mbx_reg) static void nic_clear_mbx_intr(struct nicpf *nic, int vf, int mbx_reg)
...@@ -894,11 +908,18 @@ static void nic_handle_mbx_intr(struct nicpf *nic, int vf) ...@@ -894,11 +908,18 @@ static void nic_handle_mbx_intr(struct nicpf *nic, int vf)
nic->mbx_lock[vf] = false; nic->mbx_lock[vf] = false;
} }
static void nic_mbx_intr_handler (struct nicpf *nic, int mbx) static irqreturn_t nic_mbx_intr_handler(int irq, void *nic_irq)
{ {
struct nicpf *nic = (struct nicpf *)nic_irq;
int mbx;
u64 intr; u64 intr;
u8 vf, vf_per_mbx_reg = 64; u8 vf, vf_per_mbx_reg = 64;
if (irq == nic->msix_entries[NIC_PF_INTR_ID_MBOX0].vector)
mbx = 0;
else
mbx = 1;
intr = nic_reg_read(nic, NIC_PF_MAILBOX_INT + (mbx << 3)); intr = nic_reg_read(nic, NIC_PF_MAILBOX_INT + (mbx << 3));
dev_dbg(&nic->pdev->dev, "PF interrupt Mbox%d 0x%llx\n", mbx, intr); dev_dbg(&nic->pdev->dev, "PF interrupt Mbox%d 0x%llx\n", mbx, intr);
for (vf = 0; vf < vf_per_mbx_reg; vf++) { for (vf = 0; vf < vf_per_mbx_reg; vf++) {
...@@ -910,23 +931,6 @@ static void nic_mbx_intr_handler (struct nicpf *nic, int mbx) ...@@ -910,23 +931,6 @@ static void nic_mbx_intr_handler (struct nicpf *nic, int mbx)
nic_clear_mbx_intr(nic, vf, mbx); nic_clear_mbx_intr(nic, vf, mbx);
} }
} }
}
static irqreturn_t nic_mbx0_intr_handler (int irq, void *nic_irq)
{
struct nicpf *nic = (struct nicpf *)nic_irq;
nic_mbx_intr_handler(nic, 0);
return IRQ_HANDLED;
}
static irqreturn_t nic_mbx1_intr_handler (int irq, void *nic_irq)
{
struct nicpf *nic = (struct nicpf *)nic_irq;
nic_mbx_intr_handler(nic, 1);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -934,7 +938,13 @@ static int nic_enable_msix(struct nicpf *nic) ...@@ -934,7 +938,13 @@ static int nic_enable_msix(struct nicpf *nic)
{ {
int i, ret; int i, ret;
nic->num_vec = NIC_PF_MSIX_VECTORS; nic->num_vec = pci_msix_vec_count(nic->pdev);
nic->msix_entries = kmalloc_array(nic->num_vec,
sizeof(struct msix_entry),
GFP_KERNEL);
if (!nic->msix_entries)
return -ENOMEM;
for (i = 0; i < nic->num_vec; i++) for (i = 0; i < nic->num_vec; i++)
nic->msix_entries[i].entry = i; nic->msix_entries[i].entry = i;
...@@ -942,8 +952,9 @@ static int nic_enable_msix(struct nicpf *nic) ...@@ -942,8 +952,9 @@ static int nic_enable_msix(struct nicpf *nic)
ret = pci_enable_msix(nic->pdev, nic->msix_entries, nic->num_vec); ret = pci_enable_msix(nic->pdev, nic->msix_entries, nic->num_vec);
if (ret) { if (ret) {
dev_err(&nic->pdev->dev, dev_err(&nic->pdev->dev,
"Request for #%d msix vectors failed\n", "Request for #%d msix vectors failed, returned %d\n",
nic->num_vec); nic->num_vec, ret);
kfree(nic->msix_entries);
return ret; return ret;
} }
...@@ -955,6 +966,7 @@ static void nic_disable_msix(struct nicpf *nic) ...@@ -955,6 +966,7 @@ static void nic_disable_msix(struct nicpf *nic)
{ {
if (nic->msix_enabled) { if (nic->msix_enabled) {
pci_disable_msix(nic->pdev); pci_disable_msix(nic->pdev);
kfree(nic->msix_entries);
nic->msix_enabled = 0; nic->msix_enabled = 0;
nic->num_vec = 0; nic->num_vec = 0;
} }
...@@ -973,27 +985,26 @@ static void nic_free_all_interrupts(struct nicpf *nic) ...@@ -973,27 +985,26 @@ static void nic_free_all_interrupts(struct nicpf *nic)
static int nic_register_interrupts(struct nicpf *nic) static int nic_register_interrupts(struct nicpf *nic)
{ {
int ret; int i, ret;
/* Enable MSI-X */ /* Enable MSI-X */
ret = nic_enable_msix(nic); ret = nic_enable_msix(nic);
if (ret) if (ret)
return ret; return ret;
/* Register mailbox interrupt handlers */ /* Register mailbox interrupt handler */
ret = request_irq(nic->msix_entries[NIC_PF_INTR_ID_MBOX0].vector, for (i = NIC_PF_INTR_ID_MBOX0; i < nic->num_vec; i++) {
nic_mbx0_intr_handler, 0, "NIC Mbox0", nic); sprintf(nic->irq_name[i],
if (ret) "NICPF Mbox%d", (i - NIC_PF_INTR_ID_MBOX0));
goto fail;
nic->irq_allocated[NIC_PF_INTR_ID_MBOX0] = true; ret = request_irq(nic->msix_entries[i].vector,
nic_mbx_intr_handler, 0,
ret = request_irq(nic->msix_entries[NIC_PF_INTR_ID_MBOX1].vector, nic->irq_name[i], nic);
nic_mbx1_intr_handler, 0, "NIC Mbox1", nic);
if (ret) if (ret)
goto fail; goto fail;
nic->irq_allocated[NIC_PF_INTR_ID_MBOX1] = true; nic->irq_allocated[i] = true;
}
/* Enable mailbox interrupt */ /* Enable mailbox interrupt */
nic_enable_mbx_intr(nic); nic_enable_mbx_intr(nic);
...@@ -1002,6 +1013,7 @@ static int nic_register_interrupts(struct nicpf *nic) ...@@ -1002,6 +1013,7 @@ static int nic_register_interrupts(struct nicpf *nic)
fail: fail:
dev_err(&nic->pdev->dev, "Request irq failed\n"); dev_err(&nic->pdev->dev, "Request irq failed\n");
nic_free_all_interrupts(nic); nic_free_all_interrupts(nic);
nic_disable_msix(nic);
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment