Skip to content

Commit

Permalink
kmod/vdpa: support more interrupts per virtio device
Browse files Browse the repository at this point in the history
Each OCTEON EP VF supports up to 8 MSI-X interrupts. Currently, the vDPA
driver uses only a single vector. This patch allocates all the vectors
supported by the device.

Signed-off-by: Shijith Thotton <sthotton@marvell.com>
Change-Id: I2d9d50c93953d57d224293a4efebbbd296077c1e
Reviewed-on: https://sj1git1.cavium.com/c/IP/SW/dataplane/dpu-offload/+/135466
Reviewed-by: Nithin Kumar Dabilpuram <ndabilpuram@marvell.com>
Reviewed-by: Jerin Jacob <jerinj@marvell.com>
Tested-by: Jerin Jacob <jerinj@marvell.com>
  • Loading branch information
Shijith Thotton authored and jerinjacobk committed Oct 1, 2024
1 parent ef15488 commit f4d3610
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 32 deletions.
10 changes: 5 additions & 5 deletions kmod/vdpa/octeon_ep/octep_vdpa.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@
#define OCTEP_EPF_RINFO(x) (0x000209f0 | ((x) << 25))
#define OCTEP_VF_MBOX_DATA(x) (0x00010210 | ((x) << 17))
#define OCTEP_PF_MBOX_DATA(x) (0x00022000 | ((x) << 4))

#define OCTEP_EPF_RINFO_RPVF(val) (((val) >> 32) & 0xF)
#define OCTEP_EPF_RINFO_NVFS(val) (((val) >> 48) & 0x7F)
#define OCTEP_VF_IN_CTRL(x) (0x00010000 | ((x) << 17))
#define OCTEP_VF_IN_CTRL_RPVF(val) (((val) >> 48) & 0xF)

#define OCTEP_FW_READY_SIGNATURE0 0xFEEDFEED
#define OCTEP_FW_READY_SIGNATURE1 0x3355ffaa
#define OCTEP_MAX_CB_INTR 8

enum octep_vdpa_dev_status {
OCTEP_VDPA_DEV_STATUS_INVALID,
Expand All @@ -50,7 +50,6 @@ struct octep_vring_info {
void __iomem *notify_addr;
u32 __iomem *cb_notify_addr;
phys_addr_t notify_pa;
char msix_name[256];
};

struct octep_hw {
Expand All @@ -68,7 +67,8 @@ struct octep_hw {
u64 features;
u16 nr_vring;
u32 config_size;
int irq;
int nb_irqs;
int *irqs;
};

u8 octep_hw_get_status(struct octep_hw *oct_hw);
Expand Down
2 changes: 0 additions & 2 deletions kmod/vdpa/octeon_ep/octep_vdpa_hw.c
Original file line number Diff line number Diff line change
Expand Up @@ -495,8 +495,6 @@ int octep_hw_caps_read(struct octep_hw *oct_hw, struct pci_dev *pdev)
if (!oct_hw->vqs)
return -ENOMEM;

oct_hw->irq = -1;

dev_info(&pdev->dev, "Device features : %llx\n", oct_hw->features);
dev_info(&pdev->dev, "Maximum queues : %u\n", oct_hw->nr_vring);

Expand Down
66 changes: 41 additions & 25 deletions kmod/vdpa/octeon_ep/octep_vdpa_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,18 @@ static struct octep_hw *vdpa_to_octep_hw(struct vdpa_device *vdpa_dev)
static irqreturn_t octep_vdpa_intr_handler(int irq, void *data)
{
struct octep_hw *oct_hw = data;
int i;
int i, queue_start, queue_stride;

if (unlikely(oct_hw->config_cb.callback && ioread8(oct_hw->isr))) {
iowrite8(0, oct_hw->isr);
oct_hw->config_cb.callback(oct_hw->config_cb.private);
}
for (i = 0; i < oct_hw->nr_vring; i++) {

/* Rx queues are at even indices */
queue_start = (irq - oct_hw->irqs[0]) * 2;
queue_stride = oct_hw->nb_irqs * 2;

for (i = queue_start; i < oct_hw->nr_vring; i += queue_stride) {
if (oct_hw->vqs[i].cb.callback && ioread32(oct_hw->vqs[i].cb_notify_addr)) {
/* Acknowledge the per queue notification to the device */
iowrite32(0, oct_hw->vqs[i].cb_notify_addr);
Expand All @@ -68,39 +73,48 @@ static irqreturn_t octep_vdpa_intr_handler(int irq, void *data)
static void octep_free_irqs(struct octep_hw *oct_hw)
{
struct pci_dev *pdev = oct_hw->pdev;
int irq;

if (oct_hw->irq != -1) {
devm_free_irq(&pdev->dev, oct_hw->irq, oct_hw);
oct_hw->irq = -1;
for (irq = 0; irq < oct_hw->nb_irqs; irq++) {
if (oct_hw->irqs[irq] < 0)
continue;

devm_free_irq(&pdev->dev, oct_hw->irqs[irq], oct_hw);
}

pci_free_irq_vectors(pdev);
kfree(oct_hw->irqs);
}

static int octep_request_irqs(struct octep_hw *oct_hw)
{
struct pci_dev *pdev = oct_hw->pdev;
int ret, irq;
int ret, irq, idx;

/* Currently HW device provisions one IRQ per VF, hence
* allocate one IRQ for all virtqueues call interface.
*/
ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSIX);
ret = pci_alloc_irq_vectors(pdev, 1, oct_hw->nb_irqs, PCI_IRQ_MSIX);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to alloc msix vector");
return ret;
}

snprintf(oct_hw->vqs->msix_name, sizeof(oct_hw->vqs->msix_name),
OCTEP_VDPA_DRIVER_NAME "-vf-%d", pci_iov_vf_id(pdev));

irq = pci_irq_vector(pdev, 0);
ret = devm_request_irq(&pdev->dev, irq, octep_vdpa_intr_handler, 0,
oct_hw->vqs->msix_name, oct_hw);
if (ret) {
dev_err(&pdev->dev, "Failed to register interrupt handler\n");
oct_hw->irqs = kcalloc(oct_hw->nb_irqs, sizeof(int), GFP_KERNEL);
if (!oct_hw->irqs) {
ret = -ENOMEM;
goto free_irq_vec;
}
oct_hw->irq = irq;

memset(oct_hw->irqs, -1, sizeof(oct_hw->irqs));

for (idx = 0; idx < oct_hw->nb_irqs; idx++) {
irq = pci_irq_vector(pdev, idx);
ret = devm_request_irq(&pdev->dev, irq, octep_vdpa_intr_handler, 0,
dev_name(&pdev->dev), oct_hw);
if (ret) {
dev_err(&pdev->dev, "Failed to register interrupt handler\n");
goto free_irq_vec;
}
oct_hw->irqs[idx] = irq;
}

return 0;

Expand Down Expand Up @@ -574,6 +588,7 @@ static void octep_vdpa_setup_task(struct work_struct *work)
struct device *dev = &pdev->dev;
struct octep_hw *oct_hw;
unsigned long timeout;
u64 val;
int ret;

oct_hw = &mgmt_dev->oct_hw;
Expand Down Expand Up @@ -605,6 +620,13 @@ static void octep_vdpa_setup_task(struct work_struct *work)
if (ret)
return;

val = readq(oct_hw->base[OCTEP_HW_MBOX_BAR] + OCTEP_VF_IN_CTRL(0));
oct_hw->nb_irqs = OCTEP_VF_IN_CTRL_RPVF(val);
if (!oct_hw->nb_irqs || oct_hw->nb_irqs > OCTEP_MAX_CB_INTR) {
dev_err(dev, "Invalid number of interrupts %d\n", oct_hw->nb_irqs);
goto unmap_region;
}

ret = octep_hw_caps_read(oct_hw, pdev);
if (ret < 0)
goto unmap_region;
Expand Down Expand Up @@ -783,12 +805,6 @@ static int octep_vdpa_pf_setup(struct octep_pf *octpf)
return -EINVAL;
}

if (OCTEP_EPF_RINFO_RPVF(val) != BIT_ULL(0)) {
val &= ~GENMASK_ULL(35, 32);
val |= BIT_ULL(32);
writeq(val, addr + OCTEP_EPF_RINFO(0));
}

len = pci_resource_len(pdev, OCTEP_HW_CAPS_BAR);

octpf->vf_stride = len / totalvfs;
Expand Down

0 comments on commit f4d3610

Please sign in to comment.