aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorMike Marciniszyn <mike.marciniszyn@qlogic.com>2011-01-10 20:42:21 -0500
committerRoland Dreier <rolandd@cisco.com>2011-01-10 20:42:21 -0500
commit19ede2e422496b2a064b9b22823c6afb66ff927b (patch)
tree5d440053d4662acd8f9a5dac227156878bd99db2 /drivers/infiniband
parentaa7374ac19ca08715693b0a2d9f88f479af3ea7c (diff)
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: Mike Marciniszyn <mike.marciniszyn@qlogic.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/hw/qib/qib.h2
-rw-r--r--drivers/infiniband/hw/qib/qib_driver.c4
-rw-r--r--drivers/infiniband/hw/qib/qib_iba6120.c2
-rw-r--r--drivers/infiniband/hw/qib/qib_iba7220.c2
-rw-r--r--drivers/infiniband/hw/qib/qib_iba7322.c10
5 files changed, 12 insertions, 8 deletions
diff --git a/drivers/infiniband/hw/qib/qib.h b/drivers/infiniband/hw/qib/qib.h
index 64c9e7d02d4a..73225eee3cc6 100644
--- a/drivers/infiniband/hw/qib/qib.h
+++ b/drivers/infiniband/hw/qib/qib.h
@@ -766,7 +766,7 @@ struct qib_devdata {
766 void (*f_sdma_hw_start_up)(struct qib_pportdata *); 766 void (*f_sdma_hw_start_up)(struct qib_pportdata *);
767 void (*f_sdma_init_early)(struct qib_pportdata *); 767 void (*f_sdma_init_early)(struct qib_pportdata *);
768 void (*f_set_cntr_sample)(struct qib_pportdata *, u32, u32); 768 void (*f_set_cntr_sample)(struct qib_pportdata *, u32, u32);
769 void (*f_update_usrhead)(struct qib_ctxtdata *, u64, u32, u32); 769 void (*f_update_usrhead)(struct qib_ctxtdata *, u64, u32, u32, u32);
770 u32 (*f_hdrqempty)(struct qib_ctxtdata *); 770 u32 (*f_hdrqempty)(struct qib_ctxtdata *);
771 u64 (*f_portcntr)(struct qib_pportdata *, u32); 771 u64 (*f_portcntr)(struct qib_pportdata *, u32);
772 u32 (*f_read_cntrs)(struct qib_devdata *, loff_t, char **, 772 u32 (*f_read_cntrs)(struct qib_devdata *, loff_t, char **,
diff --git a/drivers/infiniband/hw/qib/qib_driver.c b/drivers/infiniband/hw/qib/qib_driver.c
index 3ed0d5a9a566..816a6bdc0b1c 100644
--- a/drivers/infiniband/hw/qib/qib_driver.c
+++ b/drivers/infiniband/hw/qib/qib_driver.c
@@ -410,7 +410,7 @@ move_along:
410 */ 410 */
411 lval = l; 411 lval = l;
412 if (!last && !(i & 0xf)) { 412 if (!last && !(i & 0xf)) {
413 dd->f_update_usrhead(rcd, lval, updegr, etail); 413 dd->f_update_usrhead(rcd, lval, updegr, etail, i);
414 updegr = 0; 414 updegr = 0;
415 } 415 }
416 } 416 }
@@ -452,7 +452,7 @@ bail:
452 * if no packets were processed. 452 * if no packets were processed.
453 */ 453 */
454 lval = (u64)rcd->head | dd->rhdrhead_intr_off; 454 lval = (u64)rcd->head | dd->rhdrhead_intr_off;
455 dd->f_update_usrhead(rcd, lval, updegr, etail); 455 dd->f_update_usrhead(rcd, lval, updegr, etail, i);
456 return crcs; 456 return crcs;
457} 457}
458 458
diff --git a/drivers/infiniband/hw/qib/qib_iba6120.c b/drivers/infiniband/hw/qib/qib_iba6120.c
index a5e29dbb9537..774dea897e9c 100644
--- a/drivers/infiniband/hw/qib/qib_iba6120.c
+++ b/drivers/infiniband/hw/qib/qib_iba6120.c
@@ -2074,7 +2074,7 @@ static void qib_6120_config_ctxts(struct qib_devdata *dd)
2074} 2074}
2075 2075
2076static void qib_update_6120_usrhead(struct qib_ctxtdata *rcd, u64 hd, 2076static void qib_update_6120_usrhead(struct qib_ctxtdata *rcd, u64 hd,
2077 u32 updegr, u32 egrhd) 2077 u32 updegr, u32 egrhd, u32 npkts)
2078{ 2078{
2079 qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt); 2079 qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt);
2080 if (updegr) 2080 if (updegr)
diff --git a/drivers/infiniband/hw/qib/qib_iba7220.c b/drivers/infiniband/hw/qib/qib_iba7220.c
index 6fd8d74e7392..df49e8e7cc2a 100644
--- a/drivers/infiniband/hw/qib/qib_iba7220.c
+++ b/drivers/infiniband/hw/qib/qib_iba7220.c
@@ -2703,7 +2703,7 @@ static int qib_7220_set_loopback(struct qib_pportdata *ppd, const char *what)
2703} 2703}
2704 2704
2705static void qib_update_7220_usrhead(struct qib_ctxtdata *rcd, u64 hd, 2705static void qib_update_7220_usrhead(struct qib_ctxtdata *rcd, u64 hd,
2706 u32 updegr, u32 egrhd) 2706 u32 updegr, u32 egrhd, u32 npkts)
2707{ 2707{
2708 qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt); 2708 qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt);
2709 if (updegr) 2709 if (updegr)
diff --git a/drivers/infiniband/hw/qib/qib_iba7322.c b/drivers/infiniband/hw/qib/qib_iba7322.c
index a9c8c7235fcd..9bc6d0835e30 100644
--- a/drivers/infiniband/hw/qib/qib_iba7322.c
+++ b/drivers/infiniband/hw/qib/qib_iba7322.c
@@ -2823,7 +2823,6 @@ static irqreturn_t qib_7322intr(int irq, void *data)
2823 ctxtrbits &= ~rmask; 2823 ctxtrbits &= ~rmask;
2824 if (dd->rcd[i]) { 2824 if (dd->rcd[i]) {
2825 qib_kreceive(dd->rcd[i], NULL, &npkts); 2825 qib_kreceive(dd->rcd[i], NULL, &npkts);
2826 adjust_rcv_timeout(dd->rcd[i], npkts);
2827 } 2826 }
2828 } 2827 }
2829 rmask <<= 1; 2828 rmask <<= 1;
@@ -2873,7 +2872,6 @@ static irqreturn_t qib_7322pintr(int irq, void *data)
2873 (1ULL << QIB_I_RCVURG_LSB)) << rcd->ctxt); 2872 (1ULL << QIB_I_RCVURG_LSB)) << rcd->ctxt);
2874 2873
2875 qib_kreceive(rcd, NULL, &npkts); 2874 qib_kreceive(rcd, NULL, &npkts);
2876 adjust_rcv_timeout(rcd, npkts);
2877 2875
2878 return IRQ_HANDLED; 2876 return IRQ_HANDLED;
2879} 2877}
@@ -4047,8 +4045,14 @@ static int qib_7322_set_ib_table(struct qib_pportdata *ppd, int which, void *t)
4047} 4045}
4048 4046
4049static void qib_update_7322_usrhead(struct qib_ctxtdata *rcd, u64 hd, 4047static void qib_update_7322_usrhead(struct qib_ctxtdata *rcd, u64 hd,
4050 u32 updegr, u32 egrhd) 4048 u32 updegr, u32 egrhd, u32 npkts)
4051{ 4049{
4050 /*
4051 * Need to write timeout register before updating rcvhdrhead to ensure
4052 * that the timer is enabled on reception of a packet.
4053 */
4054 if (hd >> IBA7322_HDRHEAD_PKTINT_SHIFT)
4055 adjust_rcv_timeout(rcd, npkts);
4052 qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt); 4056 qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt);
4053 qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt); 4057 qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt);
4054 if (updegr) 4058 if (updegr)