aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSomnath Kotur <somnath.kotur@broadcom.com>2017-08-30 23:57:35 -0400
committerDoug Ledford <dledford@redhat.com>2017-09-22 13:57:33 -0400
commit89aaca54ba60e91f02c1c168fbef5d71f71a6d43 (patch)
tree256b3592ac6257f84c2dc5467b8081c4b8d69cdd
parent1993519be8bc86342687c61d8d11c3ade62b3b84 (diff)
bnxt_re: Don't issue cmd to delete GID for QP1 GID entry before the QP is destroyed
FW needs the 0th GID Entry in the Table to be preserved before it's corresponding QP1 is deleted, else it will fail the cmd. Check for the same and return to prevent error msg being logged for cmd failure. Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
-rw-r--r--drivers/infiniband/hw/bnxt_re/ib_verbs.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
index d7be4e4227ce..0d89621d9fe8 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
@@ -314,6 +314,7 @@ int bnxt_re_del_gid(struct ib_device *ibdev, u8 port_num,
314 struct bnxt_re_gid_ctx *ctx, **ctx_tbl; 314 struct bnxt_re_gid_ctx *ctx, **ctx_tbl;
315 struct bnxt_re_dev *rdev = to_bnxt_re_dev(ibdev, ibdev); 315 struct bnxt_re_dev *rdev = to_bnxt_re_dev(ibdev, ibdev);
316 struct bnxt_qplib_sgid_tbl *sgid_tbl = &rdev->qplib_res.sgid_tbl; 316 struct bnxt_qplib_sgid_tbl *sgid_tbl = &rdev->qplib_res.sgid_tbl;
317 struct bnxt_qplib_gid *gid_to_del;
317 318
318 /* Delete the entry from the hardware */ 319 /* Delete the entry from the hardware */
319 ctx = *context; 320 ctx = *context;
@@ -323,11 +324,25 @@ int bnxt_re_del_gid(struct ib_device *ibdev, u8 port_num,
323 if (sgid_tbl && sgid_tbl->active) { 324 if (sgid_tbl && sgid_tbl->active) {
324 if (ctx->idx >= sgid_tbl->max) 325 if (ctx->idx >= sgid_tbl->max)
325 return -EINVAL; 326 return -EINVAL;
327 gid_to_del = &sgid_tbl->tbl[ctx->idx];
328 /* DEL_GID is called in WQ context(netdevice_event_work_handler)
329 * or via the ib_unregister_device path. In the former case QP1
330 * may not be destroyed yet, in which case just return as FW
331 * needs that entry to be present and will fail it's deletion.
332 * We could get invoked again after QP1 is destroyed OR get an
333 * ADD_GID call with a different GID value for the same index
334 * where we issue MODIFY_GID cmd to update the GID entry -- TBD
335 */
336 if (ctx->idx == 0 &&
337 rdma_link_local_addr((struct in6_addr *)gid_to_del) &&
338 ctx->refcnt == 1 && rdev->qp1_sqp) {
339 dev_dbg(rdev_to_dev(rdev),
340 "Trying to delete GID0 while QP1 is alive\n");
341 return -EFAULT;
342 }
326 ctx->refcnt--; 343 ctx->refcnt--;
327 if (!ctx->refcnt) { 344 if (!ctx->refcnt) {
328 rc = bnxt_qplib_del_sgid(sgid_tbl, 345 rc = bnxt_qplib_del_sgid(sgid_tbl, gid_to_del, true);
329 &sgid_tbl->tbl[ctx->idx],
330 true);
331 if (rc) { 346 if (rc) {
332 dev_err(rdev_to_dev(rdev), 347 dev_err(rdev_to_dev(rdev),
333 "Failed to remove GID: %#x", rc); 348 "Failed to remove GID: %#x", rc);
@@ -811,6 +826,8 @@ int bnxt_re_destroy_qp(struct ib_qp *ib_qp)
811 826
812 kfree(rdev->sqp_ah); 827 kfree(rdev->sqp_ah);
813 kfree(rdev->qp1_sqp); 828 kfree(rdev->qp1_sqp);
829 rdev->qp1_sqp = NULL;
830 rdev->sqp_ah = NULL;
814 } 831 }
815 832
816 if (!IS_ERR_OR_NULL(qp->rumem)) 833 if (!IS_ERR_OR_NULL(qp->rumem))