summaryrefslogtreecommitdiffstats
path: root/drivers/staging/rdma/hfi1/chip.c
diff options
context:
space:
mode:
authorMark F. Brown2015-11-10 01:18:20 +0100
committerGreg Kroah-Hartman2015-11-20 01:58:14 +0100
commit46b010d3eeb8eb29c740c4ef09c666485f5c07e6 (patch)
treee615acff8a9edd3d1d285a8db63230ab7b32459f /drivers/staging/rdma/hfi1/chip.c
parentstaging/rdma/hfi1: pre-compute sc and sde for RC/UC QPs (diff)
downloadkernel-qcow2-linux-46b010d3eeb8eb29c740c4ef09c666485f5c07e6.tar.gz
kernel-qcow2-linux-46b010d3eeb8eb29c740c4ef09c666485f5c07e6.tar.xz
kernel-qcow2-linux-46b010d3eeb8eb29c740c4ef09c666485f5c07e6.zip
staging/rdma/hfi1: Workaround to prevent corruption during packet delivery
Disabling one receive context when RX_DMA is receiving a packet can cause incorrect packet delivery for a subsequent packet on another receive context. This is resolved by doing the following: 1. Programming dummy tail address for every receive context before enabling it 2. While deallocating receive context resetting tail address to dummy address 3. Leaving the dummy address in when disabling tail update 4. When disabling receive context leaving tail update enabled Reviewed-by: Dennis Dalessandro <dennis.dalessandro@intel.com> Reviewed-by: Mike Marciniszyn <mike.marciniszyn@intel.com> Reviewed-by: Mitko Haralanov <mitko.haralanov@intel.com> Signed-off-by: Mark F. Brown <mark.f.brown@intel.com> Signed-off-by: Jubin John <jubin.john@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/rdma/hfi1/chip.c')
-rw-r--r--drivers/staging/rdma/hfi1/chip.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/drivers/staging/rdma/hfi1/chip.c b/drivers/staging/rdma/hfi1/chip.c
index 0b07b364f666..456704e9629a 100644
--- a/drivers/staging/rdma/hfi1/chip.c
+++ b/drivers/staging/rdma/hfi1/chip.c
@@ -7785,6 +7785,17 @@ void hfi1_rcvctrl(struct hfi1_devdata *dd, unsigned int op, int ctxt)
}
if (op & HFI1_RCVCTRL_CTXT_DIS) {
write_csr(dd, RCV_VL15, 0);
+ /*
+ * When receive context is being disabled turn on tail
+ * update with a dummy tail address and then disable
+ * receive context.
+ */
+ if (dd->rcvhdrtail_dummy_physaddr) {
+ write_kctxt_csr(dd, ctxt, RCV_HDR_TAIL_ADDR,
+ dd->rcvhdrtail_dummy_physaddr);
+ rcvctrl |= RCV_CTXT_CTRL_TAIL_UPD_SMASK;
+ }
+
rcvctrl &= ~RCV_CTXT_CTRL_ENABLE_SMASK;
}
if (op & HFI1_RCVCTRL_INTRAVAIL_ENB)
@@ -7854,10 +7865,11 @@ void hfi1_rcvctrl(struct hfi1_devdata *dd, unsigned int op, int ctxt)
if (op & (HFI1_RCVCTRL_TAILUPD_DIS | HFI1_RCVCTRL_CTXT_DIS))
/*
* If the context has been disabled and the Tail Update has
- * been cleared, clear the RCV_HDR_TAIL_ADDR CSR so
- * it doesn't contain an address that is invalid.
+ * been cleared, set the RCV_HDR_TAIL_ADDR CSR to dummy address
+ * so it doesn't contain an address that is invalid.
*/
- write_kctxt_csr(dd, ctxt, RCV_HDR_TAIL_ADDR, 0);
+ write_kctxt_csr(dd, ctxt, RCV_HDR_TAIL_ADDR,
+ dd->rcvhdrtail_dummy_physaddr);
}
u32 hfi1_read_cntrs(struct hfi1_devdata *dd, loff_t pos, char **namep,