diff options
author | Mark F. Brown | 2015-11-10 01:18:20 +0100 |
---|---|---|
committer | Greg Kroah-Hartman | 2015-11-20 01:58:14 +0100 |
commit | 46b010d3eeb8eb29c740c4ef09c666485f5c07e6 (patch) | |
tree | e615acff8a9edd3d1d285a8db63230ab7b32459f /drivers/staging/rdma/hfi1/chip.c | |
parent | staging/rdma/hfi1: pre-compute sc and sde for RC/UC QPs (diff) | |
download | kernel-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.c | 18 |
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, |