summaryrefslogtreecommitdiffstats
path: root/drivers/staging/rdma/hfi1/chip.c
diff options
context:
space:
mode:
authorMitko Haralanov2016-02-03 23:32:49 +0100
committerDoug Ledford2016-03-11 02:37:50 +0100
commit566c157cbd2113a18bfc40170de16227357434d7 (patch)
treec716911b2a7ddd605ff84fa7bb160380e61db07a /drivers/staging/rdma/hfi1/chip.c
parentstaging/rdma/hfi1: Fix for 32-bit counter overflow in driver and hfi1stats (diff)
downloadkernel-qcow2-linux-566c157cbd2113a18bfc40170de16227357434d7.tar.gz
kernel-qcow2-linux-566c157cbd2113a18bfc40170de16227357434d7.tar.xz
kernel-qcow2-linux-566c157cbd2113a18bfc40170de16227357434d7.zip
staging/rdma/hfi1: Correctly set RcvCtxtCtrl register
The RcvCtxtCtrl register was being incorrectly set upon context initialization and clean up resulting, in many cases, of contexts using settings from previous contexts' initialization. This resulted in bad and unexpected behavior. This was especially important for the TailUpd bit, which requires special handling and if set incorrectly could lead to severely degraded performance. This patch fixes the handling of the RcvCtxtCtrl register, ensuring that each context gets initialized with settings applicable only for that context. It also ensures the proper setting for the TailUpd bit by setting it to either 0 or 1 (as needed by the context's configuration) explicitly. Reviewed-by: Ira Weiny <ira.weiny@intel.com> Signed-off-by: Mitko Haralanov <mitko.haralanov@intel.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
Diffstat (limited to 'drivers/staging/rdma/hfi1/chip.c')
-rw-r--r--drivers/staging/rdma/hfi1/chip.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/drivers/staging/rdma/hfi1/chip.c b/drivers/staging/rdma/hfi1/chip.c
index a90e6e6699c0..d10ba6732e72 100644
--- a/drivers/staging/rdma/hfi1/chip.c
+++ b/drivers/staging/rdma/hfi1/chip.c
@@ -6684,11 +6684,17 @@ static void rxe_freeze(struct hfi1_devdata *dd)
*/
static void rxe_kernel_unfreeze(struct hfi1_devdata *dd)
{
+ u32 rcvmask;
int i;
/* enable all kernel contexts */
- for (i = 0; i < dd->n_krcv_queues; i++)
- hfi1_rcvctrl(dd, HFI1_RCVCTRL_CTXT_ENB, i);
+ for (i = 0; i < dd->n_krcv_queues; i++) {
+ rcvmask = HFI1_RCVCTRL_CTXT_ENB;
+ /* HFI1_RCVCTRL_TAILUPD_[ENB|DIS] needs to be set explicitly */
+ rcvmask |= HFI1_CAP_KGET_MASK(dd->rcd[i]->flags, DMA_RTAIL) ?
+ HFI1_RCVCTRL_TAILUPD_ENB : HFI1_RCVCTRL_TAILUPD_DIS;
+ hfi1_rcvctrl(dd, rcvmask, i);
+ }
/* enable port */
add_rcvctrl(dd, RCV_CTRL_RCV_PORT_ENABLE_SMASK);
@@ -11255,6 +11261,7 @@ void hfi1_rcvctrl(struct hfi1_devdata *dd, unsigned int op, int ctxt)
if (dd->rcvhdrtail_dummy_physaddr) {
write_kctxt_csr(dd, ctxt, RCV_HDR_TAIL_ADDR,
dd->rcvhdrtail_dummy_physaddr);
+ /* Enabling RcvCtxtCtrl.TailUpd is intentional. */
rcvctrl |= RCV_CTXT_CTRL_TAIL_UPD_SMASK;
}
@@ -11266,8 +11273,11 @@ void hfi1_rcvctrl(struct hfi1_devdata *dd, unsigned int op, int ctxt)
rcvctrl &= ~RCV_CTXT_CTRL_INTR_AVAIL_SMASK;
if (op & HFI1_RCVCTRL_TAILUPD_ENB && rcd->rcvhdrqtailaddr_phys)
rcvctrl |= RCV_CTXT_CTRL_TAIL_UPD_SMASK;
- if (op & HFI1_RCVCTRL_TAILUPD_DIS)
- rcvctrl &= ~RCV_CTXT_CTRL_TAIL_UPD_SMASK;
+ if (op & HFI1_RCVCTRL_TAILUPD_DIS) {
+ /* See comment on RcvCtxtCtrl.TailUpd above */
+ if (!(op & HFI1_RCVCTRL_CTXT_DIS))
+ rcvctrl &= ~RCV_CTXT_CTRL_TAIL_UPD_SMASK;
+ }
if (op & HFI1_RCVCTRL_TIDFLOW_ENB)
rcvctrl |= RCV_CTXT_CTRL_TID_FLOW_ENABLE_SMASK;
if (op & HFI1_RCVCTRL_TIDFLOW_DIS)