diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c b/drivers/net/ethernet/cavium/liquidio/lio_main.c index ca529a78bca7..761061b96948 100644 --- a/drivers/net/ethernet/cavium/liquidio/lio_main.c +++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c @@ -1084,16 +1084,35 @@ static int octeon_setup_interrupt(struct octeon_device *oct) int i; int num_ioq_vectors; int num_alloc_ioq_vectors; + char *queue_irq_names = NULL; + char *aux_irq_name = NULL; if (OCTEON_CN23XX_PF(oct) && oct->msix_on) { oct->num_msix_irqs = oct->sriov_info.num_pf_rings; /* one non ioq interrupt for handling sli_mac_pf_int_sum */ oct->num_msix_irqs += 1; + /* allocate storage for the names assigned to each irq */ + oct->irq_name_storage = + kcalloc((MAX_IOQ_INTERRUPTS_PER_PF + 1), INTRNAMSIZ, + GFP_KERNEL); + if (!oct->irq_name_storage) { + dev_err(&oct->pci_dev->dev, "Irq name storage alloc failed...\n"); + return -ENOMEM; + } + + queue_irq_names = oct->irq_name_storage; + aux_irq_name = &queue_irq_names + [IRQ_NAME_OFF(MAX_IOQ_INTERRUPTS_PER_PF)]; + oct->msix_entries = kcalloc( oct->num_msix_irqs, sizeof(struct msix_entry), GFP_KERNEL); - if (!oct->msix_entries) - return 1; + if (!oct->msix_entries) { + dev_err(&oct->pci_dev->dev, "Memory Alloc failed...\n"); + kfree(oct->irq_name_storage); + oct->irq_name_storage = NULL; + return -ENOMEM; + } msix_entries = (struct msix_entry *)oct->msix_entries; /*Assumption is that pf msix vectors start from pf srn to pf to @@ -1111,7 +1130,9 @@ static int octeon_setup_interrupt(struct octeon_device *oct) dev_err(&oct->pci_dev->dev, "unable to Allocate MSI-X interrupts\n"); kfree(oct->msix_entries); oct->msix_entries = NULL; - return 1; + kfree(oct->irq_name_storage); + oct->irq_name_storage = NULL; + return num_alloc_ioq_vectors; } dev_dbg(&oct->pci_dev->dev, "OCTEON: Enough MSI-X interrupts are allocated...\n"); @@ -1119,9 +1140,12 @@ static int octeon_setup_interrupt(struct octeon_device *oct) /** For PF, there is one non-ioq interrupt handler */ num_ioq_vectors -= 1; + + snprintf(aux_irq_name, INTRNAMSIZ, + "LiquidIO%u-pf%u-aux", oct->octeon_id, oct->pf_num); irqret = request_irq(msix_entries[num_ioq_vectors].vector, - liquidio_legacy_intr_handler, 0, "octeon", - oct); + liquidio_legacy_intr_handler, 0, + aux_irq_name, oct); if (irqret) { dev_err(&oct->pci_dev->dev, "OCTEON: Request_irq failed for MSIX interrupt Error: %d\n", @@ -1129,13 +1153,20 @@ static int octeon_setup_interrupt(struct octeon_device *oct) pci_disable_msix(oct->pci_dev); kfree(oct->msix_entries); oct->msix_entries = NULL; - return 1; + kfree(oct->irq_name_storage); + oct->irq_name_storage = NULL; + return irqret; } for (i = 0; i < num_ioq_vectors; i++) { + snprintf(&queue_irq_names[IRQ_NAME_OFF(i)], INTRNAMSIZ, + "LiquidIO%u-pf%u-rxtx-%u", + oct->octeon_id, oct->pf_num, i); + irqret = request_irq(msix_entries[i].vector, liquidio_msix_intr_handler, 0, - "octeon", &oct->ioq_vector[i]); + &queue_irq_names[IRQ_NAME_OFF(i)], + &oct->ioq_vector[i]); if (irqret) { dev_err(&oct->pci_dev->dev, "OCTEON: Request_irq failed for MSIX interrupt Error: %d\n", @@ -1155,7 +1186,9 @@ static int octeon_setup_interrupt(struct octeon_device *oct) pci_disable_msix(oct->pci_dev); kfree(oct->msix_entries); oct->msix_entries = NULL; - return 1; + kfree(oct->irq_name_storage); + oct->irq_name_storage = NULL; + return irqret; } oct->ioq_vector[i].vector = msix_entries[i].vector; /* assign the cpu mask for this msix interrupt vector */ @@ -1173,15 +1206,29 @@ static int octeon_setup_interrupt(struct octeon_device *oct) else oct->flags |= LIO_FLAG_MSI_ENABLED; + /* allocate storage for the names assigned to the irq */ + oct->irq_name_storage = kcalloc(1, INTRNAMSIZ, GFP_KERNEL); + if (!oct->irq_name_storage) + return -ENOMEM; + + queue_irq_names = oct->irq_name_storage; + + snprintf(&queue_irq_names[IRQ_NAME_OFF(0)], INTRNAMSIZ, + "LiquidIO%u-pf%u-rxtx-%u", + oct->octeon_id, oct->pf_num, 0); + irqret = request_irq(oct->pci_dev->irq, - liquidio_legacy_intr_handler, IRQF_SHARED, - "octeon", oct); + liquidio_legacy_intr_handler, + IRQF_SHARED, + &queue_irq_names[IRQ_NAME_OFF(0)], oct); if (irqret) { if (oct->flags & LIO_FLAG_MSI_ENABLED) pci_disable_msi(oct->pci_dev); dev_err(&oct->pci_dev->dev, "Request IRQ failed with code: %d\n", irqret); - return 1; + kfree(oct->irq_name_storage); + oct->irq_name_storage = NULL; + return irqret; } } return 0; @@ -1449,6 +1496,9 @@ static void octeon_destroy_resources(struct octeon_device *oct) pci_disable_msi(oct->pci_dev); } + kfree(oct->irq_name_storage); + oct->irq_name_storage = NULL; + /* fallthrough */ case OCT_DEV_MSIX_ALLOC_VECTOR_DONE: if (OCTEON_CN23XX_PF(oct)) diff --git a/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c b/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c index 7b83be4ce1fe..5ec5c24cee5d 100644 --- a/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c +++ b/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c @@ -780,6 +780,7 @@ liquidio_msix_intr_handler(int irq __attribute__((unused)), void *dev) static int octeon_setup_interrupt(struct octeon_device *oct) { struct msix_entry *msix_entries; + char *queue_irq_names = NULL; int num_alloc_ioq_vectors; int num_ioq_vectors; int irqret; @@ -788,10 +789,25 @@ static int octeon_setup_interrupt(struct octeon_device *oct) if (oct->msix_on) { oct->num_msix_irqs = oct->sriov_info.rings_per_vf; + /* allocate storage for the names assigned to each irq */ + oct->irq_name_storage = + kcalloc(MAX_IOQ_INTERRUPTS_PER_VF, INTRNAMSIZ, + GFP_KERNEL); + if (!oct->irq_name_storage) { + dev_err(&oct->pci_dev->dev, "Irq name storage alloc failed...\n"); + return -ENOMEM; + } + + queue_irq_names = oct->irq_name_storage; + oct->msix_entries = kcalloc( oct->num_msix_irqs, sizeof(struct msix_entry), GFP_KERNEL); - if (!oct->msix_entries) - return 1; + if (!oct->msix_entries) { + dev_err(&oct->pci_dev->dev, "Memory Alloc failed...\n"); + kfree(oct->irq_name_storage); + oct->irq_name_storage = NULL; + return -ENOMEM; + } msix_entries = (struct msix_entry *)oct->msix_entries; @@ -805,16 +821,23 @@ static int octeon_setup_interrupt(struct octeon_device *oct) dev_err(&oct->pci_dev->dev, "unable to Allocate MSI-X interrupts\n"); kfree(oct->msix_entries); oct->msix_entries = NULL; - return 1; + kfree(oct->irq_name_storage); + oct->irq_name_storage = NULL; + return num_alloc_ioq_vectors; } dev_dbg(&oct->pci_dev->dev, "OCTEON: Enough MSI-X interrupts are allocated...\n"); num_ioq_vectors = oct->num_msix_irqs; for (i = 0; i < num_ioq_vectors; i++) { + snprintf(&queue_irq_names[IRQ_NAME_OFF(i)], INTRNAMSIZ, + "LiquidIO%u-vf%u-rxtx-%u", + oct->octeon_id, oct->vf_num, i); + irqret = request_irq(msix_entries[i].vector, liquidio_msix_intr_handler, 0, - "octeon", &oct->ioq_vector[i]); + &queue_irq_names[IRQ_NAME_OFF(i)], + &oct->ioq_vector[i]); if (irqret) { dev_err(&oct->pci_dev->dev, "OCTEON: Request_irq failed for MSIX interrupt Error: %d\n", @@ -830,7 +853,9 @@ static int octeon_setup_interrupt(struct octeon_device *oct) pci_disable_msix(oct->pci_dev); kfree(oct->msix_entries); oct->msix_entries = NULL; - return 1; + kfree(oct->irq_name_storage); + oct->irq_name_storage = NULL; + return irqret; } oct->ioq_vector[i].vector = msix_entries[i].vector; /* assign the cpu mask for this msix interrupt vector */ @@ -975,6 +1000,8 @@ static void octeon_destroy_resources(struct octeon_device *oct) pci_disable_msix(oct->pci_dev); kfree(oct->msix_entries); oct->msix_entries = NULL; + kfree(oct->irq_name_storage); + oct->irq_name_storage = NULL; } /* Soft reset the octeon device before exiting */ if (oct->pci_dev->reset_fn) diff --git a/drivers/net/ethernet/cavium/liquidio/liquidio_common.h b/drivers/net/ethernet/cavium/liquidio/liquidio_common.h index 294c6f3c6b48..4a07c0ac9fab 100644 --- a/drivers/net/ethernet/cavium/liquidio/liquidio_common.h +++ b/drivers/net/ethernet/cavium/liquidio/liquidio_common.h @@ -100,6 +100,11 @@ enum octeon_tag_type { #define BYTES_PER_DHLEN_UNIT 8 #define MAX_REG_CNT 2000000U +#define INTRNAMSIZ 32 +#define IRQ_NAME_OFF(i) ((i) * INTRNAMSIZ) +#define MAX_IOQ_INTERRUPTS_PER_PF (64 * 2) +#define MAX_IOQ_INTERRUPTS_PER_VF (8 * 2) + static inline u32 incr_index(u32 index, u32 count, u32 max) { diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_device.h b/drivers/net/ethernet/cavium/liquidio/octeon_device.h index c301a3852482..8c5d33e53cfa 100644 --- a/drivers/net/ethernet/cavium/liquidio/octeon_device.h +++ b/drivers/net/ethernet/cavium/liquidio/octeon_device.h @@ -517,6 +517,9 @@ struct octeon_device { void *msix_entries; + /* when requesting IRQs, the names are stored here */ + void *irq_name_storage; + struct octeon_sriov_info sriov_info; struct octeon_pf_vf_hs_word pfvf_hsword;