Commit 19ede2e4 authored by Mike Marciniszyn's avatar Mike Marciniszyn Committed by Roland Dreier

IB/qib: Fix interrupt mitigation

For SusieQ we need to write to the interrupt timer register before
updating the header queue head with interrupt count.  This is to
ensure that the timer is enabled properly and a receive available
interrupt is delivered.  Otherwise this interrupt can be lost if the
receiver header/eager queues are full before the timer is enabled.
Signed-off-by: default avatarMike Marciniszyn <mike.marciniszyn@qlogic.com>
Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent aa7374ac
...@@ -766,7 +766,7 @@ struct qib_devdata { ...@@ -766,7 +766,7 @@ struct qib_devdata {
void (*f_sdma_hw_start_up)(struct qib_pportdata *); void (*f_sdma_hw_start_up)(struct qib_pportdata *);
void (*f_sdma_init_early)(struct qib_pportdata *); void (*f_sdma_init_early)(struct qib_pportdata *);
void (*f_set_cntr_sample)(struct qib_pportdata *, u32, u32); void (*f_set_cntr_sample)(struct qib_pportdata *, u32, u32);
void (*f_update_usrhead)(struct qib_ctxtdata *, u64, u32, u32); void (*f_update_usrhead)(struct qib_ctxtdata *, u64, u32, u32, u32);
u32 (*f_hdrqempty)(struct qib_ctxtdata *); u32 (*f_hdrqempty)(struct qib_ctxtdata *);
u64 (*f_portcntr)(struct qib_pportdata *, u32); u64 (*f_portcntr)(struct qib_pportdata *, u32);
u32 (*f_read_cntrs)(struct qib_devdata *, loff_t, char **, u32 (*f_read_cntrs)(struct qib_devdata *, loff_t, char **,
......
...@@ -410,7 +410,7 @@ u32 qib_kreceive(struct qib_ctxtdata *rcd, u32 *llic, u32 *npkts) ...@@ -410,7 +410,7 @@ u32 qib_kreceive(struct qib_ctxtdata *rcd, u32 *llic, u32 *npkts)
*/ */
lval = l; lval = l;
if (!last && !(i & 0xf)) { if (!last && !(i & 0xf)) {
dd->f_update_usrhead(rcd, lval, updegr, etail); dd->f_update_usrhead(rcd, lval, updegr, etail, i);
updegr = 0; updegr = 0;
} }
} }
...@@ -452,7 +452,7 @@ u32 qib_kreceive(struct qib_ctxtdata *rcd, u32 *llic, u32 *npkts) ...@@ -452,7 +452,7 @@ u32 qib_kreceive(struct qib_ctxtdata *rcd, u32 *llic, u32 *npkts)
* if no packets were processed. * if no packets were processed.
*/ */
lval = (u64)rcd->head | dd->rhdrhead_intr_off; lval = (u64)rcd->head | dd->rhdrhead_intr_off;
dd->f_update_usrhead(rcd, lval, updegr, etail); dd->f_update_usrhead(rcd, lval, updegr, etail, i);
return crcs; return crcs;
} }
......
...@@ -2074,7 +2074,7 @@ static void qib_6120_config_ctxts(struct qib_devdata *dd) ...@@ -2074,7 +2074,7 @@ static void qib_6120_config_ctxts(struct qib_devdata *dd)
} }
static void qib_update_6120_usrhead(struct qib_ctxtdata *rcd, u64 hd, static void qib_update_6120_usrhead(struct qib_ctxtdata *rcd, u64 hd,
u32 updegr, u32 egrhd) u32 updegr, u32 egrhd, u32 npkts)
{ {
qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt); qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt);
if (updegr) if (updegr)
......
...@@ -2703,7 +2703,7 @@ static int qib_7220_set_loopback(struct qib_pportdata *ppd, const char *what) ...@@ -2703,7 +2703,7 @@ static int qib_7220_set_loopback(struct qib_pportdata *ppd, const char *what)
} }
static void qib_update_7220_usrhead(struct qib_ctxtdata *rcd, u64 hd, static void qib_update_7220_usrhead(struct qib_ctxtdata *rcd, u64 hd,
u32 updegr, u32 egrhd) u32 updegr, u32 egrhd, u32 npkts)
{ {
qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt); qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt);
if (updegr) if (updegr)
......
...@@ -2823,7 +2823,6 @@ static irqreturn_t qib_7322intr(int irq, void *data) ...@@ -2823,7 +2823,6 @@ static irqreturn_t qib_7322intr(int irq, void *data)
ctxtrbits &= ~rmask; ctxtrbits &= ~rmask;
if (dd->rcd[i]) { if (dd->rcd[i]) {
qib_kreceive(dd->rcd[i], NULL, &npkts); qib_kreceive(dd->rcd[i], NULL, &npkts);
adjust_rcv_timeout(dd->rcd[i], npkts);
} }
} }
rmask <<= 1; rmask <<= 1;
...@@ -2873,7 +2872,6 @@ static irqreturn_t qib_7322pintr(int irq, void *data) ...@@ -2873,7 +2872,6 @@ static irqreturn_t qib_7322pintr(int irq, void *data)
(1ULL << QIB_I_RCVURG_LSB)) << rcd->ctxt); (1ULL << QIB_I_RCVURG_LSB)) << rcd->ctxt);
qib_kreceive(rcd, NULL, &npkts); qib_kreceive(rcd, NULL, &npkts);
adjust_rcv_timeout(rcd, npkts);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -4047,8 +4045,14 @@ static int qib_7322_set_ib_table(struct qib_pportdata *ppd, int which, void *t) ...@@ -4047,8 +4045,14 @@ static int qib_7322_set_ib_table(struct qib_pportdata *ppd, int which, void *t)
} }
static void qib_update_7322_usrhead(struct qib_ctxtdata *rcd, u64 hd, static void qib_update_7322_usrhead(struct qib_ctxtdata *rcd, u64 hd,
u32 updegr, u32 egrhd) u32 updegr, u32 egrhd, u32 npkts)
{ {
/*
* Need to write timeout register before updating rcvhdrhead to ensure
* that the timer is enabled on reception of a packet.
*/
if (hd >> IBA7322_HDRHEAD_PKTINT_SHIFT)
adjust_rcv_timeout(rcd, npkts);
qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt); qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt);
qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt); qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt);
if (updegr) if (updegr)
......
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