Commit a2f7bbdc authored by Michael J. Ruhl's avatar Michael J. Ruhl Committed by Doug Ledford

IB/hfi1: Rework the IRQ API to be more flexible

The current IRQ API is an all or nothing interface.  This has two
problems:

  1. All IRQs are enabled regardless of use
  2. Moving from general interrupt to MSIx handling is difficult

Introduce a new API to enable/disable specific IRQs or a range of IRQs.

Do not enable and disable all IRQs in one step.

Rework various modules to enable/disable IRQs when needed.
Reviewed-by: default avatarMike Marciniszyn <mike.marciniszyn@intel.com>
Reviewed-by: default avatarSadanand Warrier <sadanand.warrier@intel.com>
Signed-off-by: default avatarMichael J. Ruhl <michael.j.ruhl@intel.com>
Signed-off-by: default avatarDennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent e63bb50d
...@@ -1098,9 +1098,9 @@ struct err_reg_info { ...@@ -1098,9 +1098,9 @@ struct err_reg_info {
const char *desc; const char *desc;
}; };
#define NUM_MISC_ERRS (IS_GENERAL_ERR_END - IS_GENERAL_ERR_START) #define NUM_MISC_ERRS (IS_GENERAL_ERR_END + 1 - IS_GENERAL_ERR_START)
#define NUM_DC_ERRS (IS_DC_END - IS_DC_START) #define NUM_DC_ERRS (IS_DC_END + 1 - IS_DC_START)
#define NUM_VARIOUS (IS_VARIOUS_END - IS_VARIOUS_START) #define NUM_VARIOUS (IS_VARIOUS_END + 1 - IS_VARIOUS_START)
/* /*
* Helpers for building HFI and DC error interrupt table entries. Different * Helpers for building HFI and DC error interrupt table entries. Different
...@@ -8176,7 +8176,7 @@ static void is_rcv_avail_int(struct hfi1_devdata *dd, unsigned int source) ...@@ -8176,7 +8176,7 @@ static void is_rcv_avail_int(struct hfi1_devdata *dd, unsigned int source)
/** /**
* is_rcv_urgent_int() - User receive context urgent IRQ handler * is_rcv_urgent_int() - User receive context urgent IRQ handler
* @dd: valid dd * @dd: valid dd
* @source: logical IRQ source (ofse from IS_RCVURGENT_START) * @source: logical IRQ source (offset from IS_RCVURGENT_START)
* *
* RX block receive urgent interrupt. Source is < 160. * RX block receive urgent interrupt. Source is < 160.
* *
...@@ -8226,7 +8226,7 @@ static const struct is_table is_table[] = { ...@@ -8226,7 +8226,7 @@ static const struct is_table is_table[] = {
is_sdma_eng_err_name, is_sdma_eng_err_int }, is_sdma_eng_err_name, is_sdma_eng_err_int },
{ IS_SENDCTXT_ERR_START, IS_SENDCTXT_ERR_END, { IS_SENDCTXT_ERR_START, IS_SENDCTXT_ERR_END,
is_sendctxt_err_name, is_sendctxt_err_int }, is_sendctxt_err_name, is_sendctxt_err_int },
{ IS_SDMA_START, IS_SDMA_END, { IS_SDMA_START, IS_SDMA_IDLE_END,
is_sdma_eng_name, is_sdma_eng_int }, is_sdma_eng_name, is_sdma_eng_int },
{ IS_VARIOUS_START, IS_VARIOUS_END, { IS_VARIOUS_START, IS_VARIOUS_END,
is_various_name, is_various_int }, is_various_name, is_various_int },
...@@ -8252,7 +8252,7 @@ static void is_interrupt(struct hfi1_devdata *dd, unsigned int source) ...@@ -8252,7 +8252,7 @@ static void is_interrupt(struct hfi1_devdata *dd, unsigned int source)
/* avoids a double compare by walking the table in-order */ /* avoids a double compare by walking the table in-order */
for (entry = &is_table[0]; entry->is_name; entry++) { for (entry = &is_table[0]; entry->is_name; entry++) {
if (source < entry->end) { if (source <= entry->end) {
trace_hfi1_interrupt(dd, entry, source); trace_hfi1_interrupt(dd, entry, source);
entry->is_int(dd, source - entry->start); entry->is_int(dd, source - entry->start);
return; return;
...@@ -9646,30 +9646,10 @@ void qsfp_event(struct work_struct *work) ...@@ -9646,30 +9646,10 @@ void qsfp_event(struct work_struct *work)
} }
} }
static void init_qsfp_int(struct hfi1_devdata *dd) void init_qsfp_int(struct hfi1_devdata *dd)
{ {
struct hfi1_pportdata *ppd = dd->pport; struct hfi1_pportdata *ppd = dd->pport;
u64 qsfp_mask, cce_int_mask; u64 qsfp_mask;
const int qsfp1_int_smask = QSFP1_INT % 64;
const int qsfp2_int_smask = QSFP2_INT % 64;
/*
* disable QSFP1 interrupts for HFI1, QSFP2 interrupts for HFI0
* Qsfp1Int and Qsfp2Int are adjacent bits in the same CSR,
* therefore just one of QSFP1_INT/QSFP2_INT can be used to find
* the index of the appropriate CSR in the CCEIntMask CSR array
*/
cce_int_mask = read_csr(dd, CCE_INT_MASK +
(8 * (QSFP1_INT / 64)));
if (dd->hfi1_id) {
cce_int_mask &= ~((u64)1 << qsfp1_int_smask);
write_csr(dd, CCE_INT_MASK + (8 * (QSFP1_INT / 64)),
cce_int_mask);
} else {
cce_int_mask &= ~((u64)1 << qsfp2_int_smask);
write_csr(dd, CCE_INT_MASK + (8 * (QSFP2_INT / 64)),
cce_int_mask);
}
qsfp_mask = (u64)(QSFP_HFI0_INT_N | QSFP_HFI0_MODPRST_N); qsfp_mask = (u64)(QSFP_HFI0_INT_N | QSFP_HFI0_MODPRST_N);
/* Clear current status to avoid spurious interrupts */ /* Clear current status to avoid spurious interrupts */
...@@ -9686,6 +9666,12 @@ static void init_qsfp_int(struct hfi1_devdata *dd) ...@@ -9686,6 +9666,12 @@ static void init_qsfp_int(struct hfi1_devdata *dd)
write_csr(dd, write_csr(dd,
dd->hfi1_id ? ASIC_QSFP2_INVERT : ASIC_QSFP1_INVERT, dd->hfi1_id ? ASIC_QSFP2_INVERT : ASIC_QSFP1_INVERT,
qsfp_mask); qsfp_mask);
/* Enable the appropriate QSFP IRQ source */
if (!dd->hfi1_id)
set_intr_bits(dd, QSFP1_INT, QSFP1_INT, true);
else
set_intr_bits(dd, QSFP2_INT, QSFP2_INT, true);
} }
/* /*
...@@ -11926,10 +11912,16 @@ void hfi1_rcvctrl(struct hfi1_devdata *dd, unsigned int op, ...@@ -11926,10 +11912,16 @@ void hfi1_rcvctrl(struct hfi1_devdata *dd, unsigned int op,
rcvctrl &= ~RCV_CTXT_CTRL_ENABLE_SMASK; rcvctrl &= ~RCV_CTXT_CTRL_ENABLE_SMASK;
} }
if (op & HFI1_RCVCTRL_INTRAVAIL_ENB) if (op & HFI1_RCVCTRL_INTRAVAIL_ENB) {
set_intr_bits(dd, IS_RCVAVAIL_START + rcd->ctxt,
IS_RCVAVAIL_START + rcd->ctxt, true);
rcvctrl |= RCV_CTXT_CTRL_INTR_AVAIL_SMASK; rcvctrl |= RCV_CTXT_CTRL_INTR_AVAIL_SMASK;
if (op & HFI1_RCVCTRL_INTRAVAIL_DIS) }
if (op & HFI1_RCVCTRL_INTRAVAIL_DIS) {
set_intr_bits(dd, IS_RCVAVAIL_START + rcd->ctxt,
IS_RCVAVAIL_START + rcd->ctxt, false);
rcvctrl &= ~RCV_CTXT_CTRL_INTR_AVAIL_SMASK; rcvctrl &= ~RCV_CTXT_CTRL_INTR_AVAIL_SMASK;
}
if ((op & HFI1_RCVCTRL_TAILUPD_ENB) && rcd->rcvhdrtail_kvaddr) if ((op & HFI1_RCVCTRL_TAILUPD_ENB) && rcd->rcvhdrtail_kvaddr)
rcvctrl |= RCV_CTXT_CTRL_TAIL_UPD_SMASK; rcvctrl |= RCV_CTXT_CTRL_TAIL_UPD_SMASK;
if (op & HFI1_RCVCTRL_TAILUPD_DIS) { if (op & HFI1_RCVCTRL_TAILUPD_DIS) {
...@@ -12957,57 +12949,65 @@ int hfi1_tempsense_rd(struct hfi1_devdata *dd, struct hfi1_temp *temp) ...@@ -12957,57 +12949,65 @@ int hfi1_tempsense_rd(struct hfi1_devdata *dd, struct hfi1_temp *temp)
return ret; return ret;
} }
/* ========================================================================= */
/** /**
* get_int_mask - get 64 bit int mask * read_mod_write() - Calculate the IRQ register index and set/clear the bits
* @dd - the devdata * @dd: valid devdata
* @i - the csr (relative to CCE_INT_MASK) * @src: IRQ source to determine register index from
* @bits: the bits to set or clear
* @set: true == set the bits, false == clear the bits
* *
* Returns the mask with the urgent interrupt mask
* bit clear for kernel receive contexts.
*/ */
static u64 get_int_mask(struct hfi1_devdata *dd, u32 i) static void read_mod_write(struct hfi1_devdata *dd, u16 src, u64 bits,
bool set)
{ {
u64 mask = U64_MAX; /* default to no change */ u64 reg;
u16 idx = src / BITS_PER_REGISTER;
if (i >= (IS_RCVURGENT_START / 64) && i < (IS_RCVURGENT_END / 64)) {
int j = (i - (IS_RCVURGENT_START / 64)) * 64;
int k = !j ? IS_RCVURGENT_START % 64 : 0;
if (j) spin_lock(&dd->irq_src_lock);
j -= IS_RCVURGENT_START % 64; reg = read_csr(dd, CCE_INT_MASK + (8 * idx));
/* j = 0..dd->first_dyn_alloc_ctxt - 1,k = 0..63 */ if (set)
for (; j < dd->first_dyn_alloc_ctxt && k < 64; j++, k++) reg |= bits;
/* convert to bit in mask and clear */ else
mask &= ~BIT_ULL(k); reg &= ~bits;
} write_csr(dd, CCE_INT_MASK + (8 * idx), reg);
return mask; spin_unlock(&dd->irq_src_lock);
} }
/* ========================================================================= */ /**
* set_intr_bits() - Enable/disable a range (one or more) IRQ sources
/* * @dd: valid devdata
* Enable/disable chip from delivering interrupts. * @first: first IRQ source to set/clear
* @last: last IRQ source (inclusive) to set/clear
* @set: true == set the bits, false == clear the bits
*
* If first == last, set the exact source.
*/ */
void set_intr_state(struct hfi1_devdata *dd, u32 enable) int set_intr_bits(struct hfi1_devdata *dd, u16 first, u16 last, bool set)
{ {
int i; u64 bits = 0;
u64 bit;
u16 src;
/* if (first > NUM_INTERRUPT_SOURCES || last > NUM_INTERRUPT_SOURCES)
* In HFI, the mask needs to be 1 to allow interrupts. return -EINVAL;
*/
if (enable) {
/* enable all interrupts but urgent on kernel contexts */
for (i = 0; i < CCE_NUM_INT_CSRS; i++) {
u64 mask = get_int_mask(dd, i);
write_csr(dd, CCE_INT_MASK + (8 * i), mask); if (last < first)
} return -ERANGE;
init_qsfp_int(dd); for (src = first; src <= last; src++) {
} else { bit = src % BITS_PER_REGISTER;
for (i = 0; i < CCE_NUM_INT_CSRS; i++) /* wrapped to next register? */
write_csr(dd, CCE_INT_MASK + (8 * i), 0ull); if (!bit && bits) {
read_mod_write(dd, src - 1, bits, set);
bits = 0;
}
bits |= BIT_ULL(bit);
} }
read_mod_write(dd, src, bits, set);
return 0;
} }
/* /*
...@@ -13074,12 +13074,9 @@ void remap_sdma_interrupts(struct hfi1_devdata *dd, int engine, int msix_intr) ...@@ -13074,12 +13074,9 @@ void remap_sdma_interrupts(struct hfi1_devdata *dd, int engine, int msix_intr)
* SDMAProgress * SDMAProgress
* SDMAIdle * SDMAIdle
*/ */
remap_intr(dd, IS_SDMA_START + 0 * TXE_NUM_SDMA_ENGINES + engine, remap_intr(dd, IS_SDMA_START + engine, msix_intr);
msix_intr); remap_intr(dd, IS_SDMA_PROGRESS_START + engine, msix_intr);
remap_intr(dd, IS_SDMA_START + 1 * TXE_NUM_SDMA_ENGINES + engine, remap_intr(dd, IS_SDMA_IDLE_START + engine, msix_intr);
msix_intr);
remap_intr(dd, IS_SDMA_START + 2 * TXE_NUM_SDMA_ENGINES + engine,
msix_intr);
} }
/* /*
...@@ -13109,7 +13106,8 @@ static int set_up_interrupts(struct hfi1_devdata *dd) ...@@ -13109,7 +13106,8 @@ static int set_up_interrupts(struct hfi1_devdata *dd)
int ret; int ret;
/* mask all interrupts */ /* mask all interrupts */
set_intr_state(dd, 0); set_intr_bits(dd, IS_FIRST_SOURCE, IS_LAST_SOURCE, false);
/* clear all pending interrupts */ /* clear all pending interrupts */
clear_all_interrupts(dd); clear_all_interrupts(dd);
......
...@@ -52,9 +52,7 @@ ...@@ -52,9 +52,7 @@
*/ */
/* sizes */ /* sizes */
#define CCE_NUM_MSIX_VECTORS 256 #define BITS_PER_REGISTER (BITS_PER_BYTE * sizeof(u64))
#define CCE_NUM_INT_CSRS 12
#define CCE_NUM_INT_MAP_CSRS 96
#define NUM_INTERRUPT_SOURCES 768 #define NUM_INTERRUPT_SOURCES 768
#define RXE_NUM_CONTEXTS 160 #define RXE_NUM_CONTEXTS 160
#define RXE_PER_CONTEXT_SIZE 0x1000 /* 4k */ #define RXE_PER_CONTEXT_SIZE 0x1000 /* 4k */
...@@ -161,34 +159,49 @@ ...@@ -161,34 +159,49 @@
(CR_CREDIT_RETURN_DUE_TO_FORCE_MASK << \ (CR_CREDIT_RETURN_DUE_TO_FORCE_MASK << \
CR_CREDIT_RETURN_DUE_TO_FORCE_SHIFT) CR_CREDIT_RETURN_DUE_TO_FORCE_SHIFT)
/* interrupt source numbers */ /* Specific IRQ sources */
#define IS_GENERAL_ERR_START 0 #define CCE_ERR_INT 0
#define IS_SDMAENG_ERR_START 16 #define RXE_ERR_INT 1
#define IS_SENDCTXT_ERR_START 32 #define MISC_ERR_INT 2
#define IS_SDMA_START 192 /* includes SDmaProgress,SDmaIdle */ #define PIO_ERR_INT 4
#define SDMA_ERR_INT 5
#define EGRESS_ERR_INT 6
#define TXE_ERR_INT 7
#define PBC_INT 240
#define GPIO_ASSERT_INT 241
#define QSFP1_INT 242
#define QSFP2_INT 243
#define TCRIT_INT 244
/* interrupt source ranges */
#define IS_FIRST_SOURCE CCE_ERR_INT
#define IS_GENERAL_ERR_START 0
#define IS_SDMAENG_ERR_START 16
#define IS_SENDCTXT_ERR_START 32
#define IS_SDMA_START 192
#define IS_SDMA_PROGRESS_START 208
#define IS_SDMA_IDLE_START 224
#define IS_VARIOUS_START 240 #define IS_VARIOUS_START 240
#define IS_DC_START 248 #define IS_DC_START 248
#define IS_RCVAVAIL_START 256 #define IS_RCVAVAIL_START 256
#define IS_RCVURGENT_START 416 #define IS_RCVURGENT_START 416
#define IS_SENDCREDIT_START 576 #define IS_SENDCREDIT_START 576
#define IS_RESERVED_START 736 #define IS_RESERVED_START 736
#define IS_MAX_SOURCES 768 #define IS_LAST_SOURCE 767
/* derived interrupt source values */ /* derived interrupt source values */
#define IS_GENERAL_ERR_END IS_SDMAENG_ERR_START #define IS_GENERAL_ERR_END 7
#define IS_SDMAENG_ERR_END IS_SENDCTXT_ERR_START #define IS_SDMAENG_ERR_END 31
#define IS_SENDCTXT_ERR_END IS_SDMA_START #define IS_SENDCTXT_ERR_END 191
#define IS_SDMA_END IS_VARIOUS_START #define IS_SDMA_END 207
#define IS_VARIOUS_END IS_DC_START #define IS_SDMA_PROGRESS_END 223
#define IS_DC_END IS_RCVAVAIL_START #define IS_SDMA_IDLE_END 239
#define IS_RCVAVAIL_END IS_RCVURGENT_START #define IS_VARIOUS_END 244
#define IS_RCVURGENT_END IS_SENDCREDIT_START #define IS_DC_END 255
#define IS_SENDCREDIT_END IS_RESERVED_START #define IS_RCVAVAIL_END 415
#define IS_RESERVED_END IS_MAX_SOURCES #define IS_RCVURGENT_END 575
#define IS_SENDCREDIT_END 735
/* absolute interrupt numbers for QSFP1Int and QSFP2Int */ #define IS_RESERVED_END IS_LAST_SOURCE
#define QSFP1_INT 242
#define QSFP2_INT 243
/* DCC_CFG_PORT_CONFIG logical link states */ /* DCC_CFG_PORT_CONFIG logical link states */
#define LSTATE_DOWN 0x1 #define LSTATE_DOWN 0x1
...@@ -1421,6 +1434,8 @@ irqreturn_t sdma_interrupt(int irq, void *data); ...@@ -1421,6 +1434,8 @@ irqreturn_t sdma_interrupt(int irq, void *data);
irqreturn_t receive_context_interrupt(int irq, void *data); irqreturn_t receive_context_interrupt(int irq, void *data);
irqreturn_t receive_context_thread(int irq, void *data); irqreturn_t receive_context_thread(int irq, void *data);
int set_intr_bits(struct hfi1_devdata *dd, u16 first, u16 last, bool set);
void init_qsfp_int(struct hfi1_devdata *dd);
void clear_all_interrupts(struct hfi1_devdata *dd); void clear_all_interrupts(struct hfi1_devdata *dd);
void remap_intr(struct hfi1_devdata *dd, int isrc, int msix_intr); void remap_intr(struct hfi1_devdata *dd, int isrc, int msix_intr);
void remap_sdma_interrupts(struct hfi1_devdata *dd, int engine, int msix_intr); void remap_sdma_interrupts(struct hfi1_devdata *dd, int engine, int msix_intr);
......
...@@ -639,6 +639,9 @@ static int hfi1_file_close(struct inode *inode, struct file *fp) ...@@ -639,6 +639,9 @@ static int hfi1_file_close(struct inode *inode, struct file *fp)
hfi1_cdbg(PROC, "closing ctxt %u:%u", uctxt->ctxt, fdata->subctxt); hfi1_cdbg(PROC, "closing ctxt %u:%u", uctxt->ctxt, fdata->subctxt);
set_intr_bits(dd, IS_RCVURGENT_START + uctxt->ctxt,
IS_RCVURGENT_START + uctxt->ctxt, false);
flush_wc(); flush_wc();
/* drain user sdma queue */ /* drain user sdma queue */
hfi1_user_sdma_free_queues(fdata, uctxt); hfi1_user_sdma_free_queues(fdata, uctxt);
...@@ -1217,6 +1220,10 @@ static int setup_base_ctxt(struct hfi1_filedata *fd, ...@@ -1217,6 +1220,10 @@ static int setup_base_ctxt(struct hfi1_filedata *fd,
fd->uctxt = uctxt; fd->uctxt = uctxt;
hfi1_rcd_get(uctxt); hfi1_rcd_get(uctxt);
/* Enable the Urgent IRQ for this user context */
set_intr_bits(dd, IS_RCVURGENT_START + uctxt->ctxt,
IS_RCVURGENT_START + uctxt->ctxt, true);
done: done:
if (uctxt->subctxt_cnt) { if (uctxt->subctxt_cnt) {
/* /*
......
...@@ -1213,9 +1213,6 @@ struct hfi1_devdata { ...@@ -1213,9 +1213,6 @@ struct hfi1_devdata {
struct diag_client *diag_client; struct diag_client *diag_client;
/* MSI-X information */
struct hfi1_msix_info msix_info;
/* general interrupt: mask of handled interrupts */ /* general interrupt: mask of handled interrupts */
u64 gi_mask[CCE_NUM_INT_CSRS]; u64 gi_mask[CCE_NUM_INT_CSRS];
...@@ -1229,6 +1226,9 @@ struct hfi1_devdata { ...@@ -1229,6 +1226,9 @@ struct hfi1_devdata {
*/ */
struct timer_list synth_stats_timer; struct timer_list synth_stats_timer;
/* MSI-X information */
struct hfi1_msix_info msix_info;
/* /*
* device counters * device counters
*/ */
...@@ -1355,6 +1355,8 @@ struct hfi1_devdata { ...@@ -1355,6 +1355,8 @@ struct hfi1_devdata {
/* vnic data */ /* vnic data */
struct hfi1_vnic_data vnic; struct hfi1_vnic_data vnic;
/* Lock to protect IRQ SRC register access */
spinlock_t irq_src_lock;
}; };
static inline bool hfi1_vnic_is_rsm_full(struct hfi1_devdata *dd, int spare) static inline bool hfi1_vnic_is_rsm_full(struct hfi1_devdata *dd, int spare)
......
...@@ -831,6 +831,23 @@ static int create_workqueues(struct hfi1_devdata *dd) ...@@ -831,6 +831,23 @@ static int create_workqueues(struct hfi1_devdata *dd)
return -ENOMEM; return -ENOMEM;
} }
/**
* enable_general_intr() - Enable the IRQs that will be handled by the
* general interrupt handler.
* @dd: valid devdata
*
*/
static void enable_general_intr(struct hfi1_devdata *dd)
{
set_intr_bits(dd, CCE_ERR_INT, MISC_ERR_INT, true);
set_intr_bits(dd, PIO_ERR_INT, TXE_ERR_INT, true);
set_intr_bits(dd, IS_SENDCTXT_ERR_START, IS_SENDCTXT_ERR_END, true);
set_intr_bits(dd, PBC_INT, GPIO_ASSERT_INT, true);
set_intr_bits(dd, TCRIT_INT, TCRIT_INT, true);
set_intr_bits(dd, IS_DC_START, IS_DC_END, true);
set_intr_bits(dd, IS_SENDCREDIT_START, IS_SENDCREDIT_END, true);
}
/** /**
* hfi1_init - do the actual initialization sequence on the chip * hfi1_init - do the actual initialization sequence on the chip
* @dd: the hfi1_ib device * @dd: the hfi1_ib device
...@@ -915,6 +932,7 @@ int hfi1_init(struct hfi1_devdata *dd, int reinit) ...@@ -915,6 +932,7 @@ int hfi1_init(struct hfi1_devdata *dd, int reinit)
"failed to allocate kernel ctxt's rcvhdrq and/or egr bufs\n"); "failed to allocate kernel ctxt's rcvhdrq and/or egr bufs\n");
ret = lastfail; ret = lastfail;
} }
/* enable IRQ */
hfi1_rcd_put(rcd); hfi1_rcd_put(rcd);
} }
...@@ -953,7 +971,8 @@ int hfi1_init(struct hfi1_devdata *dd, int reinit) ...@@ -953,7 +971,8 @@ int hfi1_init(struct hfi1_devdata *dd, int reinit)
HFI1_STATUS_INITTED; HFI1_STATUS_INITTED;
if (!ret) { if (!ret) {
/* enable all interrupts from the chip */ /* enable all interrupts from the chip */
set_intr_state(dd, 1); enable_general_intr(dd);
init_qsfp_int(dd);
/* chip is OK for user apps; mark it as initialized */ /* chip is OK for user apps; mark it as initialized */
for (pidx = 0; pidx < dd->num_pports; ++pidx) { for (pidx = 0; pidx < dd->num_pports; ++pidx) {
...@@ -1050,8 +1069,8 @@ static void shutdown_device(struct hfi1_devdata *dd) ...@@ -1050,8 +1069,8 @@ static void shutdown_device(struct hfi1_devdata *dd)
} }
dd->flags &= ~HFI1_INITTED; dd->flags &= ~HFI1_INITTED;
/* mask and clean up interrupts, but not errors */ /* mask and clean up interrupts */
set_intr_state(dd, 0); set_intr_bits(dd, IS_FIRST_SOURCE, IS_LAST_SOURCE, false);
msix_clean_up_interrupts(dd); msix_clean_up_interrupts(dd);
for (pidx = 0; pidx < dd->num_pports; ++pidx) { for (pidx = 0; pidx < dd->num_pports; ++pidx) {
...@@ -1312,6 +1331,7 @@ static struct hfi1_devdata *hfi1_alloc_devdata(struct pci_dev *pdev, ...@@ -1312,6 +1331,7 @@ static struct hfi1_devdata *hfi1_alloc_devdata(struct pci_dev *pdev,
spin_lock_init(&dd->pio_map_lock); spin_lock_init(&dd->pio_map_lock);
mutex_init(&dd->dc8051_lock); mutex_init(&dd->dc8051_lock);
init_waitqueue_head(&dd->event_queue); init_waitqueue_head(&dd->event_queue);
spin_lock_init(&dd->irq_src_lock);
dd->int_counter = alloc_percpu(u64); dd->int_counter = alloc_percpu(u64);
if (!dd->int_counter) { if (!dd->int_counter) {
......
...@@ -240,6 +240,21 @@ int msix_request_sdma_irq(struct sdma_engine *sde) ...@@ -240,6 +240,21 @@ int msix_request_sdma_irq(struct sdma_engine *sde)
return 0; return 0;
} }
/**
* enable_sdma_src() - Helper to enable SDMA IRQ srcs
* @dd: valid devdata structure
* @i: index of SDMA engine
*/
static void enable_sdma_srcs(struct hfi1_devdata *dd, int i)
{
set_intr_bits(dd, IS_SDMA_START + i, IS_SDMA_START + i, true);
set_intr_bits(dd, IS_SDMA_PROGRESS_START + i,
IS_SDMA_PROGRESS_START + i, true);
set_intr_bits(dd, IS_SDMA_IDLE_START + i, IS_SDMA_IDLE_START + i, true);
set_intr_bits(dd, IS_SDMAENG_ERR_START + i, IS_SDMAENG_ERR_START + i,
true);
}
/** /**
* msix_request_irqs() - Allocate all MSIx IRQs * msix_request_irqs() - Allocate all MSIx IRQs
* @dd: valid devdata structure * @dd: valid devdata structure
...@@ -262,6 +277,7 @@ int msix_request_irqs(struct hfi1_devdata *dd) ...@@ -262,6 +277,7 @@ int msix_request_irqs(struct hfi1_devdata *dd)
ret = msix_request_sdma_irq(sde); ret = msix_request_sdma_irq(sde);
if (ret) if (ret)
return ret; return ret;
enable_sdma_srcs(sde->dd, i);
} }
for (i = 0; i < dd->n_krcv_queues; i++) { for (i = 0; i < dd->n_krcv_queues; i++) {
......
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