109e71899SMichael J. Ruhl // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
209e71899SMichael J. Ruhl /*
389dcaa36SGrzegorz Andrejczuk * Copyright(c) 2018 - 2020 Intel Corporation.
409e71899SMichael J. Ruhl */
509e71899SMichael J. Ruhl
609e71899SMichael J. Ruhl #include "hfi.h"
76eb4eb10SMichael J. Ruhl #include "affinity.h"
809e71899SMichael J. Ruhl #include "sdma.h"
90bae02d5SGrzegorz Andrejczuk #include "netdev.h"
1009e71899SMichael J. Ruhl
116eb4eb10SMichael J. Ruhl /**
126eb4eb10SMichael J. Ruhl * msix_initialize() - Calculate, request and configure MSIx IRQs
136eb4eb10SMichael J. Ruhl * @dd: valid hfi1 devdata
146eb4eb10SMichael J. Ruhl *
1509e71899SMichael J. Ruhl */
msix_initialize(struct hfi1_devdata * dd)166eb4eb10SMichael J. Ruhl int msix_initialize(struct hfi1_devdata *dd)
1709e71899SMichael J. Ruhl {
1809e71899SMichael J. Ruhl u32 total;
196eb4eb10SMichael J. Ruhl int ret;
206eb4eb10SMichael J. Ruhl struct hfi1_msix_entry *entries;
2109e71899SMichael J. Ruhl
2209e71899SMichael J. Ruhl /*
236eb4eb10SMichael J. Ruhl * MSIx interrupt count:
246eb4eb10SMichael J. Ruhl * one for the general, "slow path" interrupt
256eb4eb10SMichael J. Ruhl * one per used SDMA engine
266eb4eb10SMichael J. Ruhl * one per kernel receive context
276eb4eb10SMichael J. Ruhl * one for each VNIC context
286eb4eb10SMichael J. Ruhl * ...any new IRQs should be added here.
2909e71899SMichael J. Ruhl */
3089dcaa36SGrzegorz Andrejczuk total = 1 + dd->num_sdma + dd->n_krcv_queues + dd->num_netdev_contexts;
3109e71899SMichael J. Ruhl
326eb4eb10SMichael J. Ruhl if (total >= CCE_NUM_MSIX_VECTORS)
336eb4eb10SMichael J. Ruhl return -EINVAL;
346eb4eb10SMichael J. Ruhl
356eb4eb10SMichael J. Ruhl ret = pci_alloc_irq_vectors(dd->pcidev, total, total, PCI_IRQ_MSIX);
366eb4eb10SMichael J. Ruhl if (ret < 0) {
376eb4eb10SMichael J. Ruhl dd_dev_err(dd, "pci_alloc_irq_vectors() failed: %d\n", ret);
386eb4eb10SMichael J. Ruhl return ret;
396eb4eb10SMichael J. Ruhl }
406eb4eb10SMichael J. Ruhl
416eb4eb10SMichael J. Ruhl entries = kcalloc(total, sizeof(*dd->msix_info.msix_entries),
4209e71899SMichael J. Ruhl GFP_KERNEL);
436eb4eb10SMichael J. Ruhl if (!entries) {
446eb4eb10SMichael J. Ruhl pci_free_irq_vectors(dd->pcidev);
456eb4eb10SMichael J. Ruhl return -ENOMEM;
4609e71899SMichael J. Ruhl }
476eb4eb10SMichael J. Ruhl
486eb4eb10SMichael J. Ruhl dd->msix_info.msix_entries = entries;
496eb4eb10SMichael J. Ruhl spin_lock_init(&dd->msix_info.msix_lock);
506eb4eb10SMichael J. Ruhl bitmap_zero(dd->msix_info.in_use_msix, total);
516eb4eb10SMichael J. Ruhl dd->msix_info.max_requested = total;
5209e71899SMichael J. Ruhl dd_dev_info(dd, "%u MSI-X interrupts allocated\n", total);
5309e71899SMichael J. Ruhl
5409e71899SMichael J. Ruhl return 0;
5509e71899SMichael J. Ruhl }
5609e71899SMichael J. Ruhl
576eb4eb10SMichael J. Ruhl /**
586eb4eb10SMichael J. Ruhl * msix_request_irq() - Allocate a free MSIx IRQ
596eb4eb10SMichael J. Ruhl * @dd: valid devdata
606eb4eb10SMichael J. Ruhl * @arg: context information for the IRQ
616eb4eb10SMichael J. Ruhl * @handler: IRQ handler
626eb4eb10SMichael J. Ruhl * @thread: IRQ thread handler (could be NULL)
636eb4eb10SMichael J. Ruhl * @type: affinty IRQ type
64e57a8db9SLee Jones * @name: IRQ name
656eb4eb10SMichael J. Ruhl *
666eb4eb10SMichael J. Ruhl * Allocated an MSIx vector if available, and then create the appropriate
676eb4eb10SMichael J. Ruhl * meta data needed to keep track of the pci IRQ request.
686eb4eb10SMichael J. Ruhl *
696eb4eb10SMichael J. Ruhl * Return:
706eb4eb10SMichael J. Ruhl * < 0 Error
716eb4eb10SMichael J. Ruhl * >= 0 MSIx vector
726eb4eb10SMichael J. Ruhl *
736eb4eb10SMichael J. Ruhl */
msix_request_irq(struct hfi1_devdata * dd,void * arg,irq_handler_t handler,irq_handler_t thread,enum irq_type type,const char * name)746eb4eb10SMichael J. Ruhl static int msix_request_irq(struct hfi1_devdata *dd, void *arg,
756eb4eb10SMichael J. Ruhl irq_handler_t handler, irq_handler_t thread,
7613d2a838SGrzegorz Andrejczuk enum irq_type type, const char *name)
7709e71899SMichael J. Ruhl {
786eb4eb10SMichael J. Ruhl unsigned long nr;
796eb4eb10SMichael J. Ruhl int irq;
806eb4eb10SMichael J. Ruhl int ret;
816eb4eb10SMichael J. Ruhl struct hfi1_msix_entry *me;
8209e71899SMichael J. Ruhl
836eb4eb10SMichael J. Ruhl /* Allocate an MSIx vector */
846eb4eb10SMichael J. Ruhl spin_lock(&dd->msix_info.msix_lock);
856eb4eb10SMichael J. Ruhl nr = find_first_zero_bit(dd->msix_info.in_use_msix,
866eb4eb10SMichael J. Ruhl dd->msix_info.max_requested);
876eb4eb10SMichael J. Ruhl if (nr < dd->msix_info.max_requested)
886eb4eb10SMichael J. Ruhl __set_bit(nr, dd->msix_info.in_use_msix);
896eb4eb10SMichael J. Ruhl spin_unlock(&dd->msix_info.msix_lock);
906eb4eb10SMichael J. Ruhl
916eb4eb10SMichael J. Ruhl if (nr == dd->msix_info.max_requested)
926eb4eb10SMichael J. Ruhl return -ENOSPC;
936eb4eb10SMichael J. Ruhl
9479ba4f93SNathan Chancellor if (type < IRQ_SDMA || type >= IRQ_OTHER)
956eb4eb10SMichael J. Ruhl return -EINVAL;
966eb4eb10SMichael J. Ruhl
976eb4eb10SMichael J. Ruhl irq = pci_irq_vector(dd->pcidev, nr);
986eb4eb10SMichael J. Ruhl ret = pci_request_irq(dd->pcidev, nr, handler, thread, arg, name);
9909e71899SMichael J. Ruhl if (ret) {
10009e71899SMichael J. Ruhl dd_dev_err(dd,
1010bae02d5SGrzegorz Andrejczuk "%s: request for IRQ %d failed, MSIx %lx, err %d\n",
10213d2a838SGrzegorz Andrejczuk name, irq, nr, ret);
1036eb4eb10SMichael J. Ruhl spin_lock(&dd->msix_info.msix_lock);
1046eb4eb10SMichael J. Ruhl __clear_bit(nr, dd->msix_info.in_use_msix);
1056eb4eb10SMichael J. Ruhl spin_unlock(&dd->msix_info.msix_lock);
10609e71899SMichael J. Ruhl return ret;
10709e71899SMichael J. Ruhl }
1086eb4eb10SMichael J. Ruhl
10909e71899SMichael J. Ruhl /*
11009e71899SMichael J. Ruhl * assign arg after pci_request_irq call, so it will be
11109e71899SMichael J. Ruhl * cleaned up
11209e71899SMichael J. Ruhl */
1136eb4eb10SMichael J. Ruhl me = &dd->msix_info.msix_entries[nr];
1146eb4eb10SMichael J. Ruhl me->irq = irq;
11509e71899SMichael J. Ruhl me->arg = arg;
1166eb4eb10SMichael J. Ruhl me->type = type;
11709e71899SMichael J. Ruhl
1186eb4eb10SMichael J. Ruhl /* This is a request, so a failure is not fatal */
11909e71899SMichael J. Ruhl ret = hfi1_get_irq_affinity(dd, me);
12009e71899SMichael J. Ruhl if (ret)
1210bae02d5SGrzegorz Andrejczuk dd_dev_err(dd, "%s: unable to pin IRQ %d\n", name, ret);
1226eb4eb10SMichael J. Ruhl
1236eb4eb10SMichael J. Ruhl return nr;
12409e71899SMichael J. Ruhl }
12509e71899SMichael J. Ruhl
msix_request_rcd_irq_common(struct hfi1_ctxtdata * rcd,irq_handler_t handler,irq_handler_t thread,const char * name)12613d2a838SGrzegorz Andrejczuk static int msix_request_rcd_irq_common(struct hfi1_ctxtdata *rcd,
12713d2a838SGrzegorz Andrejczuk irq_handler_t handler,
12813d2a838SGrzegorz Andrejczuk irq_handler_t thread,
12913d2a838SGrzegorz Andrejczuk const char *name)
1306eb4eb10SMichael J. Ruhl {
13113d2a838SGrzegorz Andrejczuk int nr = msix_request_irq(rcd->dd, rcd, handler, thread,
1324730f4a6SGrzegorz Andrejczuk rcd->is_vnic ? IRQ_NETDEVCTXT : IRQ_RCVCTXT,
1334730f4a6SGrzegorz Andrejczuk name);
1346eb4eb10SMichael J. Ruhl if (nr < 0)
1356eb4eb10SMichael J. Ruhl return nr;
1366eb4eb10SMichael J. Ruhl
1376eb4eb10SMichael J. Ruhl /*
1386eb4eb10SMichael J. Ruhl * Set the interrupt register and mask for this
1396eb4eb10SMichael J. Ruhl * context's interrupt.
1406eb4eb10SMichael J. Ruhl */
1416eb4eb10SMichael J. Ruhl rcd->ireg = (IS_RCVAVAIL_START + rcd->ctxt) / 64;
1426eb4eb10SMichael J. Ruhl rcd->imask = ((u64)1) << ((IS_RCVAVAIL_START + rcd->ctxt) % 64);
1436eb4eb10SMichael J. Ruhl rcd->msix_intr = nr;
1446eb4eb10SMichael J. Ruhl remap_intr(rcd->dd, IS_RCVAVAIL_START + rcd->ctxt, nr);
1456eb4eb10SMichael J. Ruhl
1466eb4eb10SMichael J. Ruhl return 0;
1476eb4eb10SMichael J. Ruhl }
1486eb4eb10SMichael J. Ruhl
1496eb4eb10SMichael J. Ruhl /**
15013d2a838SGrzegorz Andrejczuk * msix_request_rcd_irq() - Helper function for RCVAVAIL IRQs
15113d2a838SGrzegorz Andrejczuk * @rcd: valid rcd context
15213d2a838SGrzegorz Andrejczuk *
15313d2a838SGrzegorz Andrejczuk */
msix_request_rcd_irq(struct hfi1_ctxtdata * rcd)15413d2a838SGrzegorz Andrejczuk int msix_request_rcd_irq(struct hfi1_ctxtdata *rcd)
15513d2a838SGrzegorz Andrejczuk {
15613d2a838SGrzegorz Andrejczuk char name[MAX_NAME_SIZE];
15713d2a838SGrzegorz Andrejczuk
15813d2a838SGrzegorz Andrejczuk snprintf(name, sizeof(name), DRIVER_NAME "_%d kctxt%d",
15913d2a838SGrzegorz Andrejczuk rcd->dd->unit, rcd->ctxt);
16013d2a838SGrzegorz Andrejczuk
16113d2a838SGrzegorz Andrejczuk return msix_request_rcd_irq_common(rcd, receive_context_interrupt,
16213d2a838SGrzegorz Andrejczuk receive_context_thread, name);
16313d2a838SGrzegorz Andrejczuk }
16413d2a838SGrzegorz Andrejczuk
16513d2a838SGrzegorz Andrejczuk /**
166*ae360f41SLeon Romanovsky * msix_netdev_request_rcd_irq - Helper function for RCVAVAIL IRQs
1670bae02d5SGrzegorz Andrejczuk * for netdev context
1680bae02d5SGrzegorz Andrejczuk * @rcd: valid netdev contexti
1690bae02d5SGrzegorz Andrejczuk */
msix_netdev_request_rcd_irq(struct hfi1_ctxtdata * rcd)1700bae02d5SGrzegorz Andrejczuk int msix_netdev_request_rcd_irq(struct hfi1_ctxtdata *rcd)
1710bae02d5SGrzegorz Andrejczuk {
1720bae02d5SGrzegorz Andrejczuk char name[MAX_NAME_SIZE];
1730bae02d5SGrzegorz Andrejczuk
1740bae02d5SGrzegorz Andrejczuk snprintf(name, sizeof(name), DRIVER_NAME "_%d nd kctxt%d",
1750bae02d5SGrzegorz Andrejczuk rcd->dd->unit, rcd->ctxt);
1760bae02d5SGrzegorz Andrejczuk return msix_request_rcd_irq_common(rcd, receive_context_interrupt_napi,
1770bae02d5SGrzegorz Andrejczuk NULL, name);
1780bae02d5SGrzegorz Andrejczuk }
1790bae02d5SGrzegorz Andrejczuk
1800bae02d5SGrzegorz Andrejczuk /**
181*ae360f41SLeon Romanovsky * msix_request_sdma_irq - Helper for getting SDMA IRQ resources
1826eb4eb10SMichael J. Ruhl * @sde: valid sdma engine
1836eb4eb10SMichael J. Ruhl *
1846eb4eb10SMichael J. Ruhl */
msix_request_sdma_irq(struct sdma_engine * sde)1856eb4eb10SMichael J. Ruhl int msix_request_sdma_irq(struct sdma_engine *sde)
1866eb4eb10SMichael J. Ruhl {
1876eb4eb10SMichael J. Ruhl int nr;
18813d2a838SGrzegorz Andrejczuk char name[MAX_NAME_SIZE];
1896eb4eb10SMichael J. Ruhl
19013d2a838SGrzegorz Andrejczuk snprintf(name, sizeof(name), DRIVER_NAME "_%d sdma%d",
19113d2a838SGrzegorz Andrejczuk sde->dd->unit, sde->this_idx);
1926eb4eb10SMichael J. Ruhl nr = msix_request_irq(sde->dd, sde, sdma_interrupt, NULL,
19313d2a838SGrzegorz Andrejczuk IRQ_SDMA, name);
1946eb4eb10SMichael J. Ruhl if (nr < 0)
1956eb4eb10SMichael J. Ruhl return nr;
1966eb4eb10SMichael J. Ruhl sde->msix_intr = nr;
1976eb4eb10SMichael J. Ruhl remap_sdma_interrupts(sde->dd, sde->this_idx, nr);
1986eb4eb10SMichael J. Ruhl
1996eb4eb10SMichael J. Ruhl return 0;
2006eb4eb10SMichael J. Ruhl }
2016eb4eb10SMichael J. Ruhl
2026eb4eb10SMichael J. Ruhl /**
203*ae360f41SLeon Romanovsky * msix_request_general_irq - Helper for getting general IRQ
20413d2a838SGrzegorz Andrejczuk * resources
20513d2a838SGrzegorz Andrejczuk * @dd: valid device data
20613d2a838SGrzegorz Andrejczuk */
msix_request_general_irq(struct hfi1_devdata * dd)20713d2a838SGrzegorz Andrejczuk int msix_request_general_irq(struct hfi1_devdata *dd)
20813d2a838SGrzegorz Andrejczuk {
20913d2a838SGrzegorz Andrejczuk int nr;
21013d2a838SGrzegorz Andrejczuk char name[MAX_NAME_SIZE];
21113d2a838SGrzegorz Andrejczuk
21213d2a838SGrzegorz Andrejczuk snprintf(name, sizeof(name), DRIVER_NAME "_%d", dd->unit);
21313d2a838SGrzegorz Andrejczuk nr = msix_request_irq(dd, dd, general_interrupt, NULL, IRQ_GENERAL,
21413d2a838SGrzegorz Andrejczuk name);
21513d2a838SGrzegorz Andrejczuk if (nr < 0)
21613d2a838SGrzegorz Andrejczuk return nr;
21713d2a838SGrzegorz Andrejczuk
21813d2a838SGrzegorz Andrejczuk /* general interrupt must be MSIx vector 0 */
21913d2a838SGrzegorz Andrejczuk if (nr) {
22013d2a838SGrzegorz Andrejczuk msix_free_irq(dd, (u8)nr);
22113d2a838SGrzegorz Andrejczuk dd_dev_err(dd, "Invalid index %d for GENERAL IRQ\n", nr);
22213d2a838SGrzegorz Andrejczuk return -EINVAL;
22313d2a838SGrzegorz Andrejczuk }
22413d2a838SGrzegorz Andrejczuk
22513d2a838SGrzegorz Andrejczuk return 0;
22613d2a838SGrzegorz Andrejczuk }
22713d2a838SGrzegorz Andrejczuk
22813d2a838SGrzegorz Andrejczuk /**
229*ae360f41SLeon Romanovsky * enable_sdma_srcs - Helper to enable SDMA IRQ srcs
230a2f7bbdcSMichael J. Ruhl * @dd: valid devdata structure
231a2f7bbdcSMichael J. Ruhl * @i: index of SDMA engine
232a2f7bbdcSMichael J. Ruhl */
enable_sdma_srcs(struct hfi1_devdata * dd,int i)233a2f7bbdcSMichael J. Ruhl static void enable_sdma_srcs(struct hfi1_devdata *dd, int i)
234a2f7bbdcSMichael J. Ruhl {
235a2f7bbdcSMichael J. Ruhl set_intr_bits(dd, IS_SDMA_START + i, IS_SDMA_START + i, true);
236a2f7bbdcSMichael J. Ruhl set_intr_bits(dd, IS_SDMA_PROGRESS_START + i,
237a2f7bbdcSMichael J. Ruhl IS_SDMA_PROGRESS_START + i, true);
238a2f7bbdcSMichael J. Ruhl set_intr_bits(dd, IS_SDMA_IDLE_START + i, IS_SDMA_IDLE_START + i, true);
239a2f7bbdcSMichael J. Ruhl set_intr_bits(dd, IS_SDMAENG_ERR_START + i, IS_SDMAENG_ERR_START + i,
240a2f7bbdcSMichael J. Ruhl true);
241a2f7bbdcSMichael J. Ruhl }
242a2f7bbdcSMichael J. Ruhl
243a2f7bbdcSMichael J. Ruhl /**
2446eb4eb10SMichael J. Ruhl * msix_request_irqs() - Allocate all MSIx IRQs
2456eb4eb10SMichael J. Ruhl * @dd: valid devdata structure
2466eb4eb10SMichael J. Ruhl *
2476eb4eb10SMichael J. Ruhl * Helper function to request the used MSIx IRQs.
2486eb4eb10SMichael J. Ruhl *
2496eb4eb10SMichael J. Ruhl */
msix_request_irqs(struct hfi1_devdata * dd)2506eb4eb10SMichael J. Ruhl int msix_request_irqs(struct hfi1_devdata *dd)
2516eb4eb10SMichael J. Ruhl {
2526eb4eb10SMichael J. Ruhl int i;
25313d2a838SGrzegorz Andrejczuk int ret = msix_request_general_irq(dd);
2546eb4eb10SMichael J. Ruhl
25513d2a838SGrzegorz Andrejczuk if (ret)
2566eb4eb10SMichael J. Ruhl return ret;
2576eb4eb10SMichael J. Ruhl
2586eb4eb10SMichael J. Ruhl for (i = 0; i < dd->num_sdma; i++) {
2596eb4eb10SMichael J. Ruhl struct sdma_engine *sde = &dd->per_sdma[i];
2606eb4eb10SMichael J. Ruhl
2616eb4eb10SMichael J. Ruhl ret = msix_request_sdma_irq(sde);
2626eb4eb10SMichael J. Ruhl if (ret)
26309e71899SMichael J. Ruhl return ret;
264a2f7bbdcSMichael J. Ruhl enable_sdma_srcs(sde->dd, i);
26509e71899SMichael J. Ruhl }
26609e71899SMichael J. Ruhl
2676eb4eb10SMichael J. Ruhl for (i = 0; i < dd->n_krcv_queues; i++) {
2686eb4eb10SMichael J. Ruhl struct hfi1_ctxtdata *rcd = hfi1_rcd_get_by_index_safe(dd, i);
2696eb4eb10SMichael J. Ruhl
2706eb4eb10SMichael J. Ruhl if (rcd)
2716eb4eb10SMichael J. Ruhl ret = msix_request_rcd_irq(rcd);
2726eb4eb10SMichael J. Ruhl hfi1_rcd_put(rcd);
2736eb4eb10SMichael J. Ruhl if (ret)
2746eb4eb10SMichael J. Ruhl return ret;
2756eb4eb10SMichael J. Ruhl }
2766eb4eb10SMichael J. Ruhl
2776eb4eb10SMichael J. Ruhl return 0;
2786eb4eb10SMichael J. Ruhl }
2796eb4eb10SMichael J. Ruhl
2806eb4eb10SMichael J. Ruhl /**
2816eb4eb10SMichael J. Ruhl * msix_free_irq() - Free the specified MSIx resources and IRQ
2826eb4eb10SMichael J. Ruhl * @dd: valid devdata
2836eb4eb10SMichael J. Ruhl * @msix_intr: MSIx vector to free.
2846eb4eb10SMichael J. Ruhl *
2856eb4eb10SMichael J. Ruhl */
msix_free_irq(struct hfi1_devdata * dd,u8 msix_intr)2866eb4eb10SMichael J. Ruhl void msix_free_irq(struct hfi1_devdata *dd, u8 msix_intr)
2876eb4eb10SMichael J. Ruhl {
2886eb4eb10SMichael J. Ruhl struct hfi1_msix_entry *me;
2896eb4eb10SMichael J. Ruhl
2906eb4eb10SMichael J. Ruhl if (msix_intr >= dd->msix_info.max_requested)
2916eb4eb10SMichael J. Ruhl return;
2926eb4eb10SMichael J. Ruhl
2936eb4eb10SMichael J. Ruhl me = &dd->msix_info.msix_entries[msix_intr];
2946eb4eb10SMichael J. Ruhl
2956eb4eb10SMichael J. Ruhl if (!me->arg) /* => no irq, no affinity */
2966eb4eb10SMichael J. Ruhl return;
2976eb4eb10SMichael J. Ruhl
2986eb4eb10SMichael J. Ruhl hfi1_put_irq_affinity(dd, me);
2996eb4eb10SMichael J. Ruhl pci_free_irq(dd->pcidev, msix_intr, me->arg);
3006eb4eb10SMichael J. Ruhl
3016eb4eb10SMichael J. Ruhl me->arg = NULL;
3026eb4eb10SMichael J. Ruhl
3036eb4eb10SMichael J. Ruhl spin_lock(&dd->msix_info.msix_lock);
3046eb4eb10SMichael J. Ruhl __clear_bit(msix_intr, dd->msix_info.in_use_msix);
3056eb4eb10SMichael J. Ruhl spin_unlock(&dd->msix_info.msix_lock);
3066eb4eb10SMichael J. Ruhl }
3076eb4eb10SMichael J. Ruhl
3086eb4eb10SMichael J. Ruhl /**
309*ae360f41SLeon Romanovsky * msix_clean_up_interrupts - Free all MSIx IRQ resources
3106eb4eb10SMichael J. Ruhl * @dd: valid device data data structure
3116eb4eb10SMichael J. Ruhl *
3126eb4eb10SMichael J. Ruhl * Free the MSIx and associated PCI resources, if they have been allocated.
3136eb4eb10SMichael J. Ruhl */
msix_clean_up_interrupts(struct hfi1_devdata * dd)3146eb4eb10SMichael J. Ruhl void msix_clean_up_interrupts(struct hfi1_devdata *dd)
3156eb4eb10SMichael J. Ruhl {
3166eb4eb10SMichael J. Ruhl int i;
3176eb4eb10SMichael J. Ruhl struct hfi1_msix_entry *me = dd->msix_info.msix_entries;
3186eb4eb10SMichael J. Ruhl
3196eb4eb10SMichael J. Ruhl /* remove irqs - must happen before disabling/turning off */
3206eb4eb10SMichael J. Ruhl for (i = 0; i < dd->msix_info.max_requested; i++, me++)
3216eb4eb10SMichael J. Ruhl msix_free_irq(dd, i);
3226eb4eb10SMichael J. Ruhl
3236eb4eb10SMichael J. Ruhl /* clean structures */
3246eb4eb10SMichael J. Ruhl kfree(dd->msix_info.msix_entries);
3256eb4eb10SMichael J. Ruhl dd->msix_info.msix_entries = NULL;
3266eb4eb10SMichael J. Ruhl dd->msix_info.max_requested = 0;
3276eb4eb10SMichael J. Ruhl
3286eb4eb10SMichael J. Ruhl pci_free_irq_vectors(dd->pcidev);
3296eb4eb10SMichael J. Ruhl }
3306eb4eb10SMichael J. Ruhl
3316eb4eb10SMichael J. Ruhl /**
332*ae360f41SLeon Romanovsky * msix_netdev_synchronize_irq - netdev IRQ synchronize
3336eb4eb10SMichael J. Ruhl * @dd: valid devdata
3346eb4eb10SMichael J. Ruhl */
msix_netdev_synchronize_irq(struct hfi1_devdata * dd)3354730f4a6SGrzegorz Andrejczuk void msix_netdev_synchronize_irq(struct hfi1_devdata *dd)
33609e71899SMichael J. Ruhl {
33709e71899SMichael J. Ruhl int i;
3384730f4a6SGrzegorz Andrejczuk int ctxt_count = hfi1_netdev_ctxt_count(dd);
33909e71899SMichael J. Ruhl
3404730f4a6SGrzegorz Andrejczuk for (i = 0; i < ctxt_count; i++) {
3414730f4a6SGrzegorz Andrejczuk struct hfi1_ctxtdata *rcd = hfi1_netdev_get_ctxt(dd, i);
3426eb4eb10SMichael J. Ruhl struct hfi1_msix_entry *me;
3436eb4eb10SMichael J. Ruhl
3446eb4eb10SMichael J. Ruhl me = &dd->msix_info.msix_entries[rcd->msix_intr];
34509e71899SMichael J. Ruhl
34609e71899SMichael J. Ruhl synchronize_irq(me->irq);
34709e71899SMichael J. Ruhl }
34809e71899SMichael J. Ruhl }
349