Pull rdma fixes from Doug Ledford: - Smattering of miscellanous fixes - A five patch series for i40iw that had a patch (5/5) that was larger than I would like, but I took it because it's needed for large scale users - An 8 patch series for bnxt_re that landed right as I was leaving on PTO and so had to wait until now...they are all appropriate fixes for -rc IMO * tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dledford/rdma: (22 commits) bnxt_re: Don't issue cmd to delete GID for QP1 GID entry before the QP is destroyed bnxt_re: Fix memory leak in FRMR path bnxt_re: Remove RTNL lock dependency in bnxt_re_query_port bnxt_re: Fix race between the netdev register and unregister events bnxt_re: Free up devices in module_exit path bnxt_re: Fix compare and swap atomic operands bnxt_re: Stop issuing further cmds to FW once a cmd times out bnxt_re: Fix update of qplib_qp.mtu when modified i40iw: Add support for port reuse on active side connections i40iw: Add missing VLAN priority i40iw: Call i40iw_cm_disconn on modify QP to disconnect i40iw: Prevent multiple netdev event notifier registrations i40iw: Fail open if there are no available MSI-X vectors RDMA/vmw_pvrdma: Fix reporting correct opcodes for completion IB/bnxt_re: Fix frame stack compilation warning IB/mlx5: fix debugfs cleanup IB/ocrdma: fix incorrect fall-through on switch statement IB/ipoib: Suppress the retry related completion errors iw_cxgb4: remove the stid on listen create failure iw_cxgb4: drop listen destroy replies if no ep found ...
Unified · Split
| @@ -1646,7 +1646,7 @@ static bool is_valid_mcast_lid(struct ib_qp *qp, u16 lid) · 1645 unmodified lines | |||
| 1646 | */ | 1646 | */ |
| 1647 | if (!ib_query_qp(qp, &attr, IB_QP_STATE | IB_QP_PORT, &init_attr)) { | 1647 | if (!ib_query_qp(qp, &attr, IB_QP_STATE | IB_QP_PORT, &init_attr)) { |
| 1648 | if (attr.qp_state >= IB_QPS_INIT) { | 1648 | if (attr.qp_state >= IB_QPS_INIT) { |
| 1649 | if (qp->device->get_link_layer(qp->device, attr.port_num) != | 1649 | if (rdma_port_get_link_layer(qp->device, attr.port_num) != |
| 1650 | IB_LINK_LAYER_INFINIBAND) | 1650 | IB_LINK_LAYER_INFINIBAND) |
| 1651 | return true; | 1651 | return true; |
| 1652 | goto lid_check; | 1652 | goto lid_check; |
| @@ -1655,7 +1655,7 @@ static bool is_valid_mcast_lid(struct ib_qp *qp, u16 lid) · 2 unmodified lines | |||
| 1655 | 1655 | ||
| 1656 | /* Can't get a quick answer, iterate over all ports */ | 1656 | /* Can't get a quick answer, iterate over all ports */ |
| 1657 | for (port = 0; port < qp->device->phys_port_cnt; port++) | 1657 | for (port = 0; port < qp->device->phys_port_cnt; port++) |
| 1658 | if (qp->device->get_link_layer(qp->device, port) != | 1658 | if (rdma_port_get_link_layer(qp->device, port) != |
| 1659 | IB_LINK_LAYER_INFINIBAND) | 1659 | IB_LINK_LAYER_INFINIBAND) |
| 1660 | num_eth_ports++; | 1660 | num_eth_ports++; |
| 1661 | 1661 | ||
| @@ -93,11 +93,13 @@ struct bnxt_re_dev { · 92 unmodified lines | |||
| 93 | struct ib_device ibdev; | 93 | struct ib_device ibdev; |
| 94 | struct list_head list; | 94 | struct list_head list; |
| 95 | unsigned long flags; | 95 | unsigned long flags; |
| 96 | #define BNXT_RE_FLAG_NETDEV_REGISTERED 0 | 96 | #define BNXT_RE_FLAG_NETDEV_REGISTERED 0 |
| 97 | #define BNXT_RE_FLAG_IBDEV_REGISTERED 1 | 97 | #define BNXT_RE_FLAG_IBDEV_REGISTERED 1 |
| 98 | #define BNXT_RE_FLAG_GOT_MSIX 2 | 98 | #define BNXT_RE_FLAG_GOT_MSIX 2 |
| 99 | #define BNXT_RE_FLAG_RCFW_CHANNEL_EN 8 | 99 | #define BNXT_RE_FLAG_HAVE_L2_REF 3 |
| 100 | #define BNXT_RE_FLAG_QOS_WORK_REG 16 | 100 | #define BNXT_RE_FLAG_RCFW_CHANNEL_EN 4 |
| 101 | #define BNXT_RE_FLAG_QOS_WORK_REG 5 | ||
| 102 | #define BNXT_RE_FLAG_TASK_IN_PROG 6 | ||
| 101 | struct net_device *netdev; | 103 | struct net_device *netdev; |
| 102 | unsigned int version, major, minor; | 104 | unsigned int version, major, minor; |
| 103 | struct bnxt_en_dev *en_dev; | 105 | struct bnxt_en_dev *en_dev; |
| @@ -108,6 +110,8 @@ struct bnxt_re_dev { · 4 unmodified lines | |||
| 108 | 110 | ||
| 109 | struct delayed_work worker; | 111 | struct delayed_work worker; |
| 110 | u8 cur_prio_map; | 112 | u8 cur_prio_map; |
| 113 | u8 active_speed; | ||
| 114 | u8 active_width; | ||
| 111 | 115 | ||
| 112 | /* FP Notification Queue (CQ & SRQ) */ | 116 | /* FP Notification Queue (CQ & SRQ) */ |
| 113 | struct tasklet_struct nq_task; | 117 | struct tasklet_struct nq_task; |
| @@ -259,14 +259,9 @@ int bnxt_re_query_port(struct ib_device *ibdev, u8 port_num, · 258 unmodified lines | |||
| 259 | port_attr->sm_sl = 0; | 259 | port_attr->sm_sl = 0; |
| 260 | port_attr->subnet_timeout = 0; | 260 | port_attr->subnet_timeout = 0; |
| 261 | port_attr->init_type_reply = 0; | 261 | port_attr->init_type_reply = 0; |
| 262 | /* call the underlying netdev's ethtool hooks to query speed settings | 262 | port_attr->active_speed = rdev->active_speed; |
| 263 | * for which we acquire rtnl_lock _only_ if it's registered with | 263 | port_attr->active_width = rdev->active_width; |
| 264 | * IB stack to avoid race in the NETDEV_UNREG path | 264 | |
| 265 | */ | ||
| 266 | if (test_bit(BNXT_RE_FLAG_IBDEV_REGISTERED, &rdev->flags)) | ||
| 267 | if (ib_get_eth_speed(ibdev, port_num, &port_attr->active_speed, | ||
| 268 | &port_attr->active_width)) | ||
| 269 | return -EINVAL; | ||
| 270 | return 0; | 265 | return 0; |
| 271 | } | 266 | } |
| 272 | 267 | ||
| @@ -319,6 +314,7 @@ int bnxt_re_del_gid(struct ib_device *ibdev, u8 port_num, · 46 unmodified lines | |||
| 319 | struct bnxt_re_gid_ctx *ctx, **ctx_tbl; | 314 | struct bnxt_re_gid_ctx *ctx, **ctx_tbl; |
| 320 | struct bnxt_re_dev *rdev = to_bnxt_re_dev(ibdev, ibdev); | 315 | struct bnxt_re_dev *rdev = to_bnxt_re_dev(ibdev, ibdev); |
| 321 | 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; | ||
| 322 | 318 | ||
| 323 | /* Delete the entry from the hardware */ | 319 | /* Delete the entry from the hardware */ |
| 324 | ctx = *context; | 320 | ctx = *context; |
| @@ -328,11 +324,25 @@ int bnxt_re_del_gid(struct ib_device *ibdev, u8 port_num, · 3 unmodified lines | |||
| 328 | if (sgid_tbl && sgid_tbl->active) { | 324 | if (sgid_tbl && sgid_tbl->active) { |
| 329 | if (ctx->idx >= sgid_tbl->max) | 325 | if (ctx->idx >= sgid_tbl->max) |
| 330 | 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 | } | ||
| 331 | ctx->refcnt--; | 343 | ctx->refcnt--; |
| 332 | if (!ctx->refcnt) { | 344 | if (!ctx->refcnt) { |
| 333 | rc = bnxt_qplib_del_sgid(sgid_tbl, | 345 | rc = bnxt_qplib_del_sgid(sgid_tbl, gid_to_del, true); |
| 334 | &sgid_tbl->tbl[ctx->idx], | ||
| 335 | true); | ||
| 336 | if (rc) { | 346 | if (rc) { |
| 337 | dev_err(rdev_to_dev(rdev), | 347 | dev_err(rdev_to_dev(rdev), |
| 338 | "Failed to remove GID: %#x", rc); | 348 | "Failed to remove GID: %#x", rc); |
| @@ -816,6 +826,8 @@ int bnxt_re_destroy_qp(struct ib_qp *ib_qp) · 477 unmodified lines | |||
| 816 | 826 | ||
| 817 | kfree(rdev->sqp_ah); | 827 | kfree(rdev->sqp_ah); |
| 818 | kfree(rdev->qp1_sqp); | 828 | kfree(rdev->qp1_sqp); |
| 829 | rdev->qp1_sqp = NULL; | ||
| 830 | rdev->sqp_ah = NULL; | ||
| 819 | } | 831 | } |
| 820 | 832 | ||
| 821 | if (!IS_ERR_OR_NULL(qp->rumem)) | 833 | if (!IS_ERR_OR_NULL(qp->rumem)) |
| @@ -1436,11 +1448,14 @@ int bnxt_re_modify_qp(struct ib_qp *ib_qp, struct ib_qp_attr *qp_attr, · 614 unmodified lines | |||
| 1436 | qp->qplib_qp.modify_flags |= | 1448 | qp->qplib_qp.modify_flags |= |
| 1437 | CMDQ_MODIFY_QP_MODIFY_MASK_PATH_MTU; | 1449 | CMDQ_MODIFY_QP_MODIFY_MASK_PATH_MTU; |
| 1438 | qp->qplib_qp.path_mtu = __from_ib_mtu(qp_attr->path_mtu); | 1450 | qp->qplib_qp.path_mtu = __from_ib_mtu(qp_attr->path_mtu); |
| 1451 | qp->qplib_qp.mtu = ib_mtu_enum_to_int(qp_attr->path_mtu); | ||
| 1439 | } else if (qp_attr->qp_state == IB_QPS_RTR) { | 1452 | } else if (qp_attr->qp_state == IB_QPS_RTR) { |
| 1440 | qp->qplib_qp.modify_flags |= | 1453 | qp->qplib_qp.modify_flags |= |
| 1441 | CMDQ_MODIFY_QP_MODIFY_MASK_PATH_MTU; | 1454 | CMDQ_MODIFY_QP_MODIFY_MASK_PATH_MTU; |
| 1442 | qp->qplib_qp.path_mtu = | 1455 | qp->qplib_qp.path_mtu = |
| 1443 | __from_ib_mtu(iboe_get_mtu(rdev->netdev->mtu)); | 1456 | __from_ib_mtu(iboe_get_mtu(rdev->netdev->mtu)); |
| 1457 | qp->qplib_qp.mtu = | ||
| 1458 | ib_mtu_enum_to_int(iboe_get_mtu(rdev->netdev->mtu)); | ||
| 1444 | } | 1459 | } |
| 1445 | 1460 | ||
| 1446 | if (qp_attr_mask & IB_QP_TIMEOUT) { | 1461 | if (qp_attr_mask & IB_QP_TIMEOUT) { |
| @@ -1551,43 +1566,46 @@ int bnxt_re_query_qp(struct ib_qp *ib_qp, struct ib_qp_attr *qp_attr, · 104 unmodified lines | |||
| 1551 | { | 1566 | { |
| 1552 | struct bnxt_re_qp *qp = container_of(ib_qp, struct bnxt_re_qp, ib_qp); | 1567 | struct bnxt_re_qp *qp = container_of(ib_qp, struct bnxt_re_qp, ib_qp); |
| 1553 | struct bnxt_re_dev *rdev = qp->rdev; | 1568 | struct bnxt_re_dev *rdev = qp->rdev; |
| 1554 | struct bnxt_qplib_qp qplib_qp; | 1569 | struct bnxt_qplib_qp *qplib_qp; |
| 1555 | int rc; | 1570 | int rc; |
| 1556 | 1571 | ||
| 1557 | memset(&qplib_qp, 0, sizeof(struct bnxt_qplib_qp)); | 1572 | qplib_qp = kzalloc(sizeof(*qplib_qp), GFP_KERNEL); |
| 1558 | qplib_qp.id = qp->qplib_qp.id; | 1573 | if (!qplib_qp) |
| 1559 | qplib_qp.ah.host_sgid_index = qp->qplib_qp.ah.host_sgid_index; | 1574 | return -ENOMEM; |
| 1575 | |||
| 1576 | qplib_qp->id = qp->qplib_qp.id; | ||
| 1577 | qplib_qp->ah.host_sgid_index = qp->qplib_qp.ah.host_sgid_index; | ||
| 1560 | 1578 | ||
| 1561 | rc = bnxt_qplib_query_qp(&rdev->qplib_res, &qplib_qp); | 1579 | rc = bnxt_qplib_query_qp(&rdev->qplib_res, qplib_qp); |
| 1562 | if (rc) { | 1580 | if (rc) { |
| 1563 | dev_err(rdev_to_dev(rdev), "Failed to query HW QP"); | 1581 | dev_err(rdev_to_dev(rdev), "Failed to query HW QP"); |
| 1564 | return rc; | 1582 | goto out; |
| 1565 | } | 1583 | } |
| 1566 | qp_attr->qp_state = __to_ib_qp_state(qplib_qp.state); | 1584 | qp_attr->qp_state = __to_ib_qp_state(qplib_qp->state); |
| 1567 | qp_attr->en_sqd_async_notify = qplib_qp.en_sqd_async_notify ? 1 : 0; | 1585 | qp_attr->en_sqd_async_notify = qplib_qp->en_sqd_async_notify ? 1 : 0; |
| 1568 | qp_attr->qp_access_flags = __to_ib_access_flags(qplib_qp.access); | 1586 | qp_attr->qp_access_flags = __to_ib_access_flags(qplib_qp->access); |
| 1569 | qp_attr->pkey_index = qplib_qp.pkey_index; | 1587 | qp_attr->pkey_index = qplib_qp->pkey_index; |
| 1570 | qp_attr->qkey = qplib_qp.qkey; | 1588 | qp_attr->qkey = qplib_qp->qkey; |
| 1571 | qp_attr->ah_attr.type = RDMA_AH_ATTR_TYPE_ROCE; | 1589 | qp_attr->ah_attr.type = RDMA_AH_ATTR_TYPE_ROCE; |
| 1572 | rdma_ah_set_grh(&qp_attr->ah_attr, NULL, qplib_qp.ah.flow_label, | 1590 | rdma_ah_set_grh(&qp_attr->ah_attr, NULL, qplib_qp->ah.flow_label, |
| 1573 | qplib_qp.ah.host_sgid_index, | 1591 | qplib_qp->ah.host_sgid_index, |
| 1574 | qplib_qp.ah.hop_limit, | 1592 | qplib_qp->ah.hop_limit, |
| 1575 | qplib_qp.ah.traffic_class); | 1593 | qplib_qp->ah.traffic_class); |
| 1576 | rdma_ah_set_dgid_raw(&qp_attr->ah_attr, qplib_qp.ah.dgid.data); | 1594 | rdma_ah_set_dgid_raw(&qp_attr->ah_attr, qplib_qp->ah.dgid.data); |
| 1577 | rdma_ah_set_sl(&qp_attr->ah_attr, qplib_qp.ah.sl); | 1595 | rdma_ah_set_sl(&qp_attr->ah_attr, qplib_qp->ah.sl); |
| 1578 | ether_addr_copy(qp_attr->ah_attr.roce.dmac, qplib_qp.ah.dmac); | 1596 | ether_addr_copy(qp_attr->ah_attr.roce.dmac, qplib_qp->ah.dmac); |
| 1579 | qp_attr->path_mtu = __to_ib_mtu(qplib_qp.path_mtu); | 1597 | qp_attr->path_mtu = __to_ib_mtu(qplib_qp->path_mtu); |
| 1580 | qp_attr->timeout = qplib_qp.timeout; | 1598 | qp_attr->timeout = qplib_qp->timeout; |
| 1581 | qp_attr->retry_cnt = qplib_qp.retry_cnt; | 1599 | qp_attr->retry_cnt = qplib_qp->retry_cnt; |
| 1582 | qp_attr->rnr_retry = qplib_qp.rnr_retry; | 1600 | qp_attr->rnr_retry = qplib_qp->rnr_retry; |
| 1583 | qp_attr->min_rnr_timer = qplib_qp.min_rnr_timer; | 1601 | qp_attr->min_rnr_timer = qplib_qp->min_rnr_timer; |
| 1584 | qp_attr->rq_psn = qplib_qp.rq.psn; | 1602 | qp_attr->rq_psn = qplib_qp->rq.psn; |
| 1585 | qp_attr->max_rd_atomic = qplib_qp.max_rd_atomic; | 1603 | qp_attr->max_rd_atomic = qplib_qp->max_rd_atomic; |
| 1586 | qp_attr->sq_psn = qplib_qp.sq.psn; | 1604 | qp_attr->sq_psn = qplib_qp->sq.psn; |
| 1587 | qp_attr->max_dest_rd_atomic = qplib_qp.max_dest_rd_atomic; | 1605 | qp_attr->max_dest_rd_atomic = qplib_qp->max_dest_rd_atomic; |
| 1588 | qp_init_attr->sq_sig_type = qplib_qp.sig_type ? IB_SIGNAL_ALL_WR : | 1606 | qp_init_attr->sq_sig_type = qplib_qp->sig_type ? IB_SIGNAL_ALL_WR : |
| 1589 | IB_SIGNAL_REQ_WR; | 1607 | IB_SIGNAL_REQ_WR; |
| 1590 | qp_attr->dest_qp_num = qplib_qp.dest_qpn; | 1608 | qp_attr->dest_qp_num = qplib_qp->dest_qpn; |
| 1591 | 1609 | ||
| 1592 | qp_attr->cap.max_send_wr = qp->qplib_qp.sq.max_wqe; | 1610 | qp_attr->cap.max_send_wr = qp->qplib_qp.sq.max_wqe; |
| 1593 | qp_attr->cap.max_send_sge = qp->qplib_qp.sq.max_sge; | 1611 | qp_attr->cap.max_send_sge = qp->qplib_qp.sq.max_sge; |
| @@ -1596,7 +1614,9 @@ int bnxt_re_query_qp(struct ib_qp *ib_qp, struct ib_qp_attr *qp_attr, · 2 unmodified lines | |||
| 1596 | qp_attr->cap.max_inline_data = qp->qplib_qp.max_inline_data; | 1614 | qp_attr->cap.max_inline_data = qp->qplib_qp.max_inline_data; |
| 1597 | qp_init_attr->cap = qp_attr->cap; | 1615 | qp_init_attr->cap = qp_attr->cap; |
| 1598 | 1616 | ||
| 1599 | return 0; | 1617 | out: |
| 1618 | kfree(qplib_qp); | ||
| 1619 | return rc; | ||
| 1600 | } | 1620 | } |
| 1601 | 1621 | ||
| 1602 | /* Routine for sending QP1 packets for RoCE V1 an V2 | 1622 | /* Routine for sending QP1 packets for RoCE V1 an V2 |
| @@ -1908,6 +1928,7 @@ static int bnxt_re_build_atomic_wqe(struct ib_send_wr *wr, · 305 unmodified lines | |||
| 1908 | switch (wr->opcode) { | 1928 | switch (wr->opcode) { |
| 1909 | case IB_WR_ATOMIC_CMP_AND_SWP: | 1929 | case IB_WR_ATOMIC_CMP_AND_SWP: |
| 1910 | wqe->type = BNXT_QPLIB_SWQE_TYPE_ATOMIC_CMP_AND_SWP; | 1930 | wqe->type = BNXT_QPLIB_SWQE_TYPE_ATOMIC_CMP_AND_SWP; |
| 1931 | wqe->atomic.cmp_data = atomic_wr(wr)->compare_add; | ||
| 1911 | wqe->atomic.swap_data = atomic_wr(wr)->swap; | 1932 | wqe->atomic.swap_data = atomic_wr(wr)->swap; |
| 1912 | break; | 1933 | break; |
| 1913 | case IB_WR_ATOMIC_FETCH_AND_ADD: | 1934 | case IB_WR_ATOMIC_FETCH_AND_ADD: |
| @@ -3062,7 +3083,7 @@ int bnxt_re_dereg_mr(struct ib_mr *ib_mr) · 1148 unmodified lines | |||
| 3062 | return rc; | 3083 | return rc; |
| 3063 | } | 3084 | } |
| 3064 | 3085 | ||
| 3065 | if (mr->npages && mr->pages) { | 3086 | if (mr->pages) { |
| 3066 | rc = bnxt_qplib_free_fast_reg_page_list(&rdev->qplib_res, | 3087 | rc = bnxt_qplib_free_fast_reg_page_list(&rdev->qplib_res, |
| 3067 | &mr->qplib_frpl); | 3088 | &mr->qplib_frpl); |
| 3068 | kfree(mr->pages); | 3089 | kfree(mr->pages); |
| @@ -1161,6 +1161,8 @@ static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev) · 1160 unmodified lines | |||
| 1161 | } | 1161 | } |
| 1162 | } | 1162 | } |
| 1163 | set_bit(BNXT_RE_FLAG_IBDEV_REGISTERED, &rdev->flags); | 1163 | set_bit(BNXT_RE_FLAG_IBDEV_REGISTERED, &rdev->flags); |
| 1164 | ib_get_eth_speed(&rdev->ibdev, 1, &rdev->active_speed, | ||
| 1165 | &rdev->active_width); | ||
| 1164 | bnxt_re_dispatch_event(&rdev->ibdev, NULL, 1, IB_EVENT_PORT_ACTIVE); | 1166 | bnxt_re_dispatch_event(&rdev->ibdev, NULL, 1, IB_EVENT_PORT_ACTIVE); |
| 1165 | bnxt_re_dispatch_event(&rdev->ibdev, NULL, 1, IB_EVENT_GID_CHANGE); | 1167 | bnxt_re_dispatch_event(&rdev->ibdev, NULL, 1, IB_EVENT_GID_CHANGE); |
| 1166 | 1168 | ||
| @@ -1255,10 +1257,14 @@ static void bnxt_re_task(struct work_struct *work) · 88 unmodified lines | |||
| 1255 | else if (netif_carrier_ok(rdev->netdev)) | 1257 | else if (netif_carrier_ok(rdev->netdev)) |
| 1256 | bnxt_re_dispatch_event(&rdev->ibdev, NULL, 1, | 1258 | bnxt_re_dispatch_event(&rdev->ibdev, NULL, 1, |
| 1257 | IB_EVENT_PORT_ACTIVE); | 1259 | IB_EVENT_PORT_ACTIVE); |
| 1260 | ib_get_eth_speed(&rdev->ibdev, 1, &rdev->active_speed, | ||
| 1261 | &rdev->active_width); | ||
| 1258 | break; | 1262 | break; |
| 1259 | default: | 1263 | default: |
| 1260 | break; | 1264 | break; |
| 1261 | } | 1265 | } |
| 1266 | smp_mb__before_atomic(); | ||
| 1267 | clear_bit(BNXT_RE_FLAG_TASK_IN_PROG, &rdev->flags); | ||
| 1262 | kfree(re_work); | 1268 | kfree(re_work); |
| 1263 | } | 1269 | } |
| 1264 | 1270 | ||
| @@ -1317,6 +1323,11 @@ static int bnxt_re_netdev_event(struct notifier_block *notifier, · 52 unmodified lines | |||
| 1317 | break; | 1323 | break; |
| 1318 | 1324 | ||
| 1319 | case NETDEV_UNREGISTER: | 1325 | case NETDEV_UNREGISTER: |
| 1326 | /* netdev notifier will call NETDEV_UNREGISTER again later since | ||
| 1327 | * we are still holding the reference to the netdev | ||
| 1328 | */ | ||
| 1329 | if (test_bit(BNXT_RE_FLAG_TASK_IN_PROG, &rdev->flags)) | ||
| 1330 | goto exit; | ||
| 1320 | bnxt_re_ib_unreg(rdev, false); | 1331 | bnxt_re_ib_unreg(rdev, false); |
| 1321 | bnxt_re_remove_one(rdev); | 1332 | bnxt_re_remove_one(rdev); |
| 1322 | bnxt_re_dev_unreg(rdev); | 1333 | bnxt_re_dev_unreg(rdev); |
| @@ -1335,6 +1346,7 @@ static int bnxt_re_netdev_event(struct notifier_block *notifier, · 12 unmodified lines | |||
| 1335 | re_work->vlan_dev = (real_dev == netdev ? | 1346 | re_work->vlan_dev = (real_dev == netdev ? |
| 1336 | NULL : netdev); | 1347 | NULL : netdev); |
| 1337 | INIT_WORK(&re_work->work, bnxt_re_task); | 1348 | INIT_WORK(&re_work->work, bnxt_re_task); |
| 1349 | set_bit(BNXT_RE_FLAG_TASK_IN_PROG, &rdev->flags); | ||
| 1338 | queue_work(bnxt_re_wq, &re_work->work); | 1350 | queue_work(bnxt_re_wq, &re_work->work); |
| 1339 | } | 1351 | } |
| 1340 | } | 1352 | } |
| @@ -1375,6 +1387,22 @@ err_netdev: · 34 unmodified lines | |||
| 1375 | 1387 | ||
| 1376 | static void __exit bnxt_re_mod_exit(void) | 1388 | static void __exit bnxt_re_mod_exit(void) |
| 1377 | { | 1389 | { |
| 1390 | struct bnxt_re_dev *rdev; | ||
| 1391 | LIST_HEAD(to_be_deleted); | ||
| 1392 | |||
| 1393 | mutex_lock(&bnxt_re_dev_lock); | ||
| 1394 | /* Free all adapter allocated resources */ | ||
| 1395 | if (!list_empty(&bnxt_re_dev_list)) | ||
| 1396 | list_splice_init(&bnxt_re_dev_list, &to_be_deleted); | ||
| 1397 | mutex_unlock(&bnxt_re_dev_lock); | ||
| 1398 | |||
| 1399 | list_for_each_entry(rdev, &to_be_deleted, list) { | ||
| 1400 | dev_info(rdev_to_dev(rdev), "Unregistering Device"); | ||
| 1401 | bnxt_re_dev_stop(rdev); | ||
| 1402 | bnxt_re_ib_unreg(rdev, true); | ||
| 1403 | bnxt_re_remove_one(rdev); | ||
| 1404 | bnxt_re_dev_unreg(rdev); | ||
| 1405 | } | ||
| 1378 | unregister_netdevice_notifier(&bnxt_re_netdev_notifier); | 1406 | unregister_netdevice_notifier(&bnxt_re_netdev_notifier); |
| 1379 | if (bnxt_re_wq) | 1407 | if (bnxt_re_wq) |
| 1380 | destroy_workqueue(bnxt_re_wq); | 1408 | destroy_workqueue(bnxt_re_wq); |
| @@ -107,6 +107,9 @@ static int __send_message(struct bnxt_qplib_rcfw *rcfw, struct cmdq_base *req, · 106 unmodified lines | |||
| 107 | return -EINVAL; | 107 | return -EINVAL; |
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | if (test_bit(FIRMWARE_TIMED_OUT, &rcfw->flags)) | ||
| 111 | return -ETIMEDOUT; | ||
| 112 | |||
| 110 | /* Cmdq are in 16-byte units, each request can consume 1 or more | 113 | /* Cmdq are in 16-byte units, each request can consume 1 or more |
| 111 | * cmdqe | 114 | * cmdqe |
| 112 | */ | 115 | */ |
| @@ -226,6 +229,7 @@ int bnxt_qplib_rcfw_send_message(struct bnxt_qplib_rcfw *rcfw, · 113 unmodified lines | |||
| 226 | /* timed out */ | 229 | /* timed out */ |
| 227 | dev_err(&rcfw->pdev->dev, "QPLIB: cmdq[%#x]=%#x timedout (%d)msec", | 230 | dev_err(&rcfw->pdev->dev, "QPLIB: cmdq[%#x]=%#x timedout (%d)msec", |
| 228 | cookie, opcode, RCFW_CMD_WAIT_TIME_MS); | 231 | cookie, opcode, RCFW_CMD_WAIT_TIME_MS); |
| 232 | set_bit(FIRMWARE_TIMED_OUT, &rcfw->flags); | ||
| 229 | return rc; | 233 | return rc; |
| 230 | } | 234 | } |
| 231 | 235 | ||
| @@ -162,8 +162,9 @@ struct bnxt_qplib_rcfw { · 161 unmodified lines | |||
| 162 | unsigned long *cmdq_bitmap; | 162 | unsigned long *cmdq_bitmap; |
| 163 | u32 bmap_size; | 163 | u32 bmap_size; |
| 164 | unsigned long flags; | 164 | unsigned long flags; |
| 165 | #define FIRMWARE_INITIALIZED_FLAG 1 | 165 | #define FIRMWARE_INITIALIZED_FLAG BIT(0) |
| 166 | #define FIRMWARE_FIRST_FLAG BIT(31) | 166 | #define FIRMWARE_FIRST_FLAG BIT(31) |
| 167 | #define FIRMWARE_TIMED_OUT BIT(3) | ||
| 167 | wait_queue_head_t waitq; | 168 | wait_queue_head_t waitq; |
| 168 | int (*aeq_handler)(struct bnxt_qplib_rcfw *, | 169 | int (*aeq_handler)(struct bnxt_qplib_rcfw *, |
| 169 | struct creq_func_event *); | 170 | struct creq_func_event *); |
| @@ -2333,9 +2333,14 @@ static int close_listsrv_rpl(struct c4iw_dev *dev, struct sk_buff *skb) · 2332 unmodified lines | |||
| 2333 | unsigned int stid = GET_TID(rpl); | 2333 | unsigned int stid = GET_TID(rpl); |
| 2334 | struct c4iw_listen_ep *ep = get_ep_from_stid(dev, stid); | 2334 | struct c4iw_listen_ep *ep = get_ep_from_stid(dev, stid); |
| 2335 | 2335 | ||
| 2336 | if (!ep) { | ||
| 2337 | pr_debug("%s stid %d lookup failure!\n", __func__, stid); | ||
| 2338 | goto out; | ||
| 2339 | } | ||
| 2336 | pr_debug("%s ep %p\n", __func__, ep); | 2340 | pr_debug("%s ep %p\n", __func__, ep); |
| 2337 | c4iw_wake_up(&ep->com.wr_wait, status2errno(rpl->status)); | 2341 | c4iw_wake_up(&ep->com.wr_wait, status2errno(rpl->status)); |
| 2338 | c4iw_put_ep(&ep->com); | 2342 | c4iw_put_ep(&ep->com); |
| 2343 | out: | ||
| 2339 | return 0; | 2344 | return 0; |
| 2340 | } | 2345 | } |
| 2341 | 2346 | ||
| @@ -2594,9 +2599,9 @@ fail: · 252 unmodified lines | |||
| 2594 | c4iw_put_ep(&child_ep->com); | 2599 | c4iw_put_ep(&child_ep->com); |
| 2595 | reject: | 2600 | reject: |
| 2596 | reject_cr(dev, hwtid, skb); | 2601 | reject_cr(dev, hwtid, skb); |
| 2602 | out: | ||
| 2597 | if (parent_ep) | 2603 | if (parent_ep) |
| 2598 | c4iw_put_ep(&parent_ep->com); | 2604 | c4iw_put_ep(&parent_ep->com); |
| 2599 | out: | ||
| 2600 | return 0; | 2605 | return 0; |
| 2601 | } | 2606 | } |
| 2602 | 2607 | ||
| @@ -3457,7 +3462,7 @@ int c4iw_create_listen(struct iw_cm_id *cm_id, int backlog) · 854 unmodified lines | |||
| 3457 | cm_id->provider_data = ep; | 3462 | cm_id->provider_data = ep; |
| 3458 | goto out; | 3463 | goto out; |
| 3459 | } | 3464 | } |
| 3460 | 3465 | remove_handle(ep->com.dev, &ep->com.dev->stid_idr, ep->stid); | |
| 3461 | cxgb4_free_stid(ep->com.dev->rdev.lldi.tids, ep->stid, | 3466 | cxgb4_free_stid(ep->com.dev->rdev.lldi.tids, ep->stid, |
| 3462 | ep->com.local_addr.ss_family); | 3467 | ep->com.local_addr.ss_family); |
| 3463 | fail2: | 3468 | fail2: |
| @@ -201,7 +201,6 @@ enum init_completion_state { · 200 unmodified lines | |||
| 201 | CEQ_CREATED, | 201 | CEQ_CREATED, |
| 202 | ILQ_CREATED, | 202 | ILQ_CREATED, |
| 203 | IEQ_CREATED, | 203 | IEQ_CREATED, |
| 204 | INET_NOTIFIER, | ||
| 205 | IP_ADDR_REGISTERED, | 204 | IP_ADDR_REGISTERED, |
| 206 | RDMA_DEV_REGISTERED | 205 | RDMA_DEV_REGISTERED |
| 207 | }; | 206 | }; |
| @@ -1504,23 +1504,40 @@ static void i40iw_add_hte_node(struct i40iw_cm_core *cm_core, · 1503 unmodified lines | |||
| 1504 | } | 1504 | } |
| 1505 | 1505 | ||
| 1506 | /** | 1506 | /** |
| 1507 | * listen_port_in_use - determine if port is in use | 1507 | * i40iw_port_in_use - determine if port is in use |
| 1508 | * @port: Listen port number | 1508 | * @port: port number |
| 1509 | * @active_side: flag for listener side vs active side | ||
| 1509 | */ | 1510 | */ |
| 1510 | static bool i40iw_listen_port_in_use(struct i40iw_cm_core *cm_core, u16 port) | 1511 | static bool i40iw_port_in_use(struct i40iw_cm_core *cm_core, u16 port, bool active_side) |
| 1511 | { | 1512 | { |
| 1512 | struct i40iw_cm_listener *listen_node; | 1513 | struct i40iw_cm_listener *listen_node; |
| 1514 | struct i40iw_cm_node *cm_node; | ||
| 1513 | unsigned long flags; | 1515 | unsigned long flags; |
| 1514 | bool ret = false; | 1516 | bool ret = false; |
| 1515 | 1517 | ||
| 1516 | spin_lock_irqsave(&cm_core->listen_list_lock, flags); | 1518 | if (active_side) { |
| 1517 | list_for_each_entry(listen_node, &cm_core->listen_nodes, list) { | 1519 | /* search connected node list */ |
| 1518 | if (listen_node->loc_port == port) { | 1520 | spin_lock_irqsave(&cm_core->ht_lock, flags); |
| 1519 | ret = true; | 1521 | list_for_each_entry(cm_node, &cm_core->connected_nodes, list) { |
| 1520 | break; | 1522 | if (cm_node->loc_port == port) { |
| 1523 | ret = true; | ||
| 1524 | break; | ||
| 1525 | } | ||
| 1526 | } | ||
| 1527 | if (!ret) | ||
| 1528 | clear_bit(port, cm_core->active_side_ports); | ||
| 1529 | spin_unlock_irqrestore(&cm_core->ht_lock, flags); | ||
| 1530 | } else { | ||
| 1531 | spin_lock_irqsave(&cm_core->listen_list_lock, flags); | ||
| 1532 | list_for_each_entry(listen_node, &cm_core->listen_nodes, list) { | ||
| 1533 | if (listen_node->loc_port == port) { | ||
| 1534 | ret = true; | ||
| 1535 | break; | ||
| 1536 | } | ||
| 1521 | } | 1537 | } |
| 1538 | spin_unlock_irqrestore(&cm_core->listen_list_lock, flags); | ||
| 1522 | } | 1539 | } |
| 1523 | spin_unlock_irqrestore(&cm_core->listen_list_lock, flags); | 1540 | |
| 1524 | return ret; | 1541 | return ret; |
| 1525 | } | 1542 | } |
| 1526 | 1543 | ||
| @@ -1868,7 +1885,7 @@ static int i40iw_dec_refcnt_listen(struct i40iw_cm_core *cm_core, · 341 unmodified lines | |||
| 1868 | spin_unlock_irqrestore(&cm_core->listen_list_lock, flags); | 1885 | spin_unlock_irqrestore(&cm_core->listen_list_lock, flags); |
| 1869 | 1886 | ||
| 1870 | if (listener->iwdev) { | 1887 | if (listener->iwdev) { |
| 1871 | if (apbvt_del && !i40iw_listen_port_in_use(cm_core, listener->loc_port)) | 1888 | if (apbvt_del && !i40iw_port_in_use(cm_core, listener->loc_port, false)) |
| 1872 | i40iw_manage_apbvt(listener->iwdev, | 1889 | i40iw_manage_apbvt(listener->iwdev, |
| 1873 | listener->loc_port, | 1890 | listener->loc_port, |
| 1874 | I40IW_MANAGE_APBVT_DEL); | 1891 | I40IW_MANAGE_APBVT_DEL); |
| @@ -2247,21 +2264,21 @@ static void i40iw_rem_ref_cm_node(struct i40iw_cm_node *cm_node) · 372 unmodified lines | |||
| 2247 | if (cm_node->listener) { | 2264 | if (cm_node->listener) { |
| 2248 | i40iw_dec_refcnt_listen(cm_core, cm_node->listener, 0, true); | 2265 | i40iw_dec_refcnt_listen(cm_core, cm_node->listener, 0, true); |
| 2249 | } else { | 2266 | } else { |
| 2250 | if (!i40iw_listen_port_in_use(cm_core, cm_node->loc_port) && | 2267 | if (!i40iw_port_in_use(cm_core, cm_node->loc_port, true) && cm_node->apbvt_set) { |
| 2251 | cm_node->apbvt_set) { | ||
| 2252 | i40iw_manage_apbvt(cm_node->iwdev, | 2268 | i40iw_manage_apbvt(cm_node->iwdev, |
| 2253 | cm_node->loc_port, | 2269 | cm_node->loc_port, |
| 2254 | I40IW_MANAGE_APBVT_DEL); | 2270 | I40IW_MANAGE_APBVT_DEL); |
| 2255 | i40iw_get_addr_info(cm_node, &nfo); | 2271 | cm_node->apbvt_set = 0; |
| 2256 | if (cm_node->qhash_set) { | 2272 | } |
| 2257 | i40iw_manage_qhash(cm_node->iwdev, | 2273 | i40iw_get_addr_info(cm_node, &nfo); |
| 2258 | &nfo, | 2274 | if (cm_node->qhash_set) { |
| 2259 | I40IW_QHASH_TYPE_TCP_ESTABLISHED, | 2275 | i40iw_manage_qhash(cm_node->iwdev, |
| 2260 | I40IW_QHASH_MANAGE_TYPE_DELETE, | 2276 | &nfo, |
| 2261 | NULL, | 2277 | I40IW_QHASH_TYPE_TCP_ESTABLISHED, |
| 2262 | false); | 2278 | I40IW_QHASH_MANAGE_TYPE_DELETE, |
| 2263 | cm_node->qhash_set = 0; | 2279 | NULL, |
| 2264 | } | 2280 | false); |
| 2281 | cm_node->qhash_set = 0; | ||
| 2265 | } | 2282 | } |
| 2266 | } | 2283 | } |
| 2267 | 2284 | ||
| @@ -3255,7 +3272,8 @@ static void i40iw_init_tcp_ctx(struct i40iw_cm_node *cm_node, · 987 unmodified lines | |||
| 3255 | tcp_info->snd_mss = cpu_to_le32(((u32)cm_node->tcp_cntxt.mss)); | 3272 | tcp_info->snd_mss = cpu_to_le32(((u32)cm_node->tcp_cntxt.mss)); |
| 3256 | if (cm_node->vlan_id < VLAN_TAG_PRESENT) { | 3273 | if (cm_node->vlan_id < VLAN_TAG_PRESENT) { |
| 3257 | tcp_info->insert_vlan_tag = true; | 3274 | tcp_info->insert_vlan_tag = true; |
| 3258 | tcp_info->vlan_tag = cpu_to_le16(cm_node->vlan_id); | 3275 | tcp_info->vlan_tag = cpu_to_le16(((u16)cm_node->user_pri << I40IW_VLAN_PRIO_SHIFT) | |
| 3276 | cm_node->vlan_id); | ||
| 3259 | } | 3277 | } |
| 3260 | if (cm_node->ipv4) { | 3278 | if (cm_node->ipv4) { |
| 3261 | tcp_info->src_port = cpu_to_le16(cm_node->loc_port); | 3279 | tcp_info->src_port = cpu_to_le16(cm_node->loc_port); |
| @@ -3737,10 +3755,8 @@ int i40iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) · 475 unmodified lines | |||
| 3737 | struct sockaddr_in *raddr; | 3755 | struct sockaddr_in *raddr; |
| 3738 | struct sockaddr_in6 *laddr6; | 3756 | struct sockaddr_in6 *laddr6; |
| 3739 | struct sockaddr_in6 *raddr6; | 3757 | struct sockaddr_in6 *raddr6; |
| 3740 | bool qhash_set = false; | 3758 | int ret = 0; |
| 3741 | int apbvt_set = 0; | 3759 | unsigned long flags; |
| 3742 | int err = 0; | ||
| 3743 | enum i40iw_status_code status; | ||
| 3744 | 3760 | ||
| 3745 | ibqp = i40iw_get_qp(cm_id->device, conn_param->qpn); | 3761 | ibqp = i40iw_get_qp(cm_id->device, conn_param->qpn); |
| 3746 | if (!ibqp) | 3762 | if (!ibqp) |
| @@ -3789,32 +3805,6 @@ int i40iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) · 42 unmodified lines | |||
| 3789 | cm_info.user_pri = rt_tos2priority(cm_id->tos); | 3805 | cm_info.user_pri = rt_tos2priority(cm_id->tos); |
| 3790 | i40iw_debug(&iwdev->sc_dev, I40IW_DEBUG_DCB, "%s TOS:[%d] UP:[%d]\n", | 3806 | i40iw_debug(&iwdev->sc_dev, I40IW_DEBUG_DCB, "%s TOS:[%d] UP:[%d]\n", |
| 3791 | __func__, cm_id->tos, cm_info.user_pri); | 3807 | __func__, cm_id->tos, cm_info.user_pri); |
| 3792 | if ((cm_info.ipv4 && (laddr->sin_addr.s_addr != raddr->sin_addr.s_addr)) || | ||
| 3793 | (!cm_info.ipv4 && memcmp(laddr6->sin6_addr.in6_u.u6_addr32, | ||
| 3794 | raddr6->sin6_addr.in6_u.u6_addr32, | ||
| 3795 | sizeof(laddr6->sin6_addr.in6_u.u6_addr32)))) { | ||
| 3796 | status = i40iw_manage_qhash(iwdev, | ||
| 3797 | &cm_info, | ||
| 3798 | I40IW_QHASH_TYPE_TCP_ESTABLISHED, | ||
| 3799 | I40IW_QHASH_MANAGE_TYPE_ADD, | ||
| 3800 | NULL, | ||
| 3801 | true); | ||
| 3802 | if (status) | ||
| 3803 | return -EINVAL; | ||
| 3804 | qhash_set = true; | ||
| 3805 | } | ||
| 3806 | status = i40iw_manage_apbvt(iwdev, cm_info.loc_port, I40IW_MANAGE_APBVT_ADD); | ||
| 3807 | if (status) { | ||
| 3808 | i40iw_manage_qhash(iwdev, | ||
| 3809 | &cm_info, | ||
| 3810 | I40IW_QHASH_TYPE_TCP_ESTABLISHED, | ||
| 3811 | I40IW_QHASH_MANAGE_TYPE_DELETE, | ||
| 3812 | NULL, | ||
| 3813 | false); | ||
| 3814 | return -EINVAL; | ||
| 3815 | } | ||
| 3816 | |||
| 3817 | apbvt_set = 1; | ||
| 3818 | cm_id->add_ref(cm_id); | 3808 | cm_id->add_ref(cm_id); |
| 3819 | cm_node = i40iw_create_cm_node(&iwdev->cm_core, iwdev, | 3809 | cm_node = i40iw_create_cm_node(&iwdev->cm_core, iwdev, |
| 3820 | conn_param->private_data_len, | 3810 | conn_param->private_data_len, |
| @@ -3822,17 +3812,40 @@ int i40iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) · 1 unmodified line | |||
| 3822 | &cm_info); | 3812 | &cm_info); |
| 3823 | 3813 | ||
| 3824 | if (IS_ERR(cm_node)) { | 3814 | if (IS_ERR(cm_node)) { |
| 3825 | err = PTR_ERR(cm_node); | 3815 | ret = PTR_ERR(cm_node); |
| 3826 | goto err_out; | 3816 | cm_id->rem_ref(cm_id); |
| 3817 | return ret; | ||
| 3818 | } | ||
| 3819 | |||
| 3820 | if ((cm_info.ipv4 && (laddr->sin_addr.s_addr != raddr->sin_addr.s_addr)) || | ||
| 3821 | (!cm_info.ipv4 && memcmp(laddr6->sin6_addr.in6_u.u6_addr32, | ||
| 3822 | raddr6->sin6_addr.in6_u.u6_addr32, | ||
| 3823 | sizeof(laddr6->sin6_addr.in6_u.u6_addr32)))) { | ||
| 3824 | if (i40iw_manage_qhash(iwdev, &cm_info, I40IW_QHASH_TYPE_TCP_ESTABLISHED, | ||
| 3825 | I40IW_QHASH_MANAGE_TYPE_ADD, NULL, true)) { | ||
| 3826 | ret = -EINVAL; | ||
| 3827 | goto err; | ||
| 3828 | } | ||
| 3829 | cm_node->qhash_set = true; | ||
| 3827 | } | 3830 | } |
| 3828 | 3831 | ||
| 3832 | spin_lock_irqsave(&iwdev->cm_core.ht_lock, flags); | ||
| 3833 | if (!test_and_set_bit(cm_info.loc_port, iwdev->cm_core.active_side_ports)) { | ||
| 3834 | spin_unlock_irqrestore(&iwdev->cm_core.ht_lock, flags); | ||
| 3835 | if (i40iw_manage_apbvt(iwdev, cm_info.loc_port, I40IW_MANAGE_APBVT_ADD)) { | ||
| 3836 | ret = -EINVAL; | ||
| 3837 | goto err; | ||
| 3838 | } | ||
| 3839 | } else { | ||
| 3840 | spin_unlock_irqrestore(&iwdev->cm_core.ht_lock, flags); | ||
| 3841 | } | ||
| 3842 | |||
| 3843 | cm_node->apbvt_set = true; | ||
| 3829 | i40iw_record_ird_ord(cm_node, (u16)conn_param->ird, (u16)conn_param->ord); | 3844 | i40iw_record_ird_ord(cm_node, (u16)conn_param->ird, (u16)conn_param->ord); |
| 3830 | if (cm_node->send_rdma0_op == SEND_RDMA_READ_ZERO && | 3845 | if (cm_node->send_rdma0_op == SEND_RDMA_READ_ZERO && |
| 3831 | !cm_node->ord_size) | 3846 | !cm_node->ord_size) |
| 3832 | cm_node->ord_size = 1; | 3847 | cm_node->ord_size = 1; |
| 3833 | 3848 | ||
| 3834 | cm_node->apbvt_set = apbvt_set; | ||
| 3835 | cm_node->qhash_set = qhash_set; | ||
| 3836 | iwqp->cm_node = cm_node; | 3849 | iwqp->cm_node = cm_node; |
| 3837 | cm_node->iwqp = iwqp; | 3850 | cm_node->iwqp = iwqp; |
| 3838 | iwqp->cm_id = cm_id; | 3851 | iwqp->cm_id = cm_id; |
| @@ -3840,11 +3853,9 @@ int i40iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) · 1 unmodified line | |||
| 3840 | 3853 | ||
| 3841 | if (cm_node->state != I40IW_CM_STATE_OFFLOADED) { | 3854 | if (cm_node->state != I40IW_CM_STATE_OFFLOADED) { |
| 3842 | cm_node->state = I40IW_CM_STATE_SYN_SENT; | 3855 | cm_node->state = I40IW_CM_STATE_SYN_SENT; |
| 3843 | err = i40iw_send_syn(cm_node, 0); | 3856 | ret = i40iw_send_syn(cm_node, 0); |
| 3844 | if (err) { | 3857 | if (ret) |
| 3845 | i40iw_rem_ref_cm_node(cm_node); | 3858 | goto err; |
| 3846 | goto err_out; | ||
| 3847 | } | ||
| 3848 | } | 3859 | } |
| 3849 | 3860 | ||
| 3850 | i40iw_debug(cm_node->dev, | 3861 | i40iw_debug(cm_node->dev, |
| @@ -3853,9 +3864,10 @@ int i40iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) · 2 unmodified lines | |||
| 3853 | cm_node->rem_port, | 3864 | cm_node->rem_port, |
| 3854 | cm_node, | 3865 | cm_node, |
| 3855 | cm_node->cm_id); | 3866 | cm_node->cm_id); |
| 3867 | |||
| 3856 | return 0; | 3868 | return 0; |
| 3857 | 3869 | ||
| 3858 | err_out: | 3870 | err: |
| 3859 | if (cm_info.ipv4) | 3871 | if (cm_info.ipv4) |
| 3860 | i40iw_debug(&iwdev->sc_dev, | 3872 | i40iw_debug(&iwdev->sc_dev, |
| 3861 | I40IW_DEBUG_CM, | 3873 | I40IW_DEBUG_CM, |
| @@ -3867,22 +3879,10 @@ err_out: · 5 unmodified lines | |||
| 3867 | "Api - connect() FAILED: dest addr=%pI6", | 3879 | "Api - connect() FAILED: dest addr=%pI6", |
| 3868 | cm_info.rem_addr); | 3880 | cm_info.rem_addr); |
| 3869 | 3881 | ||
| 3870 | if (qhash_set) | 3882 | i40iw_rem_ref_cm_node(cm_node); |
| 3871 | i40iw_manage_qhash(iwdev, | ||
| 3872 | &cm_info, | ||
| 3873 | I40IW_QHASH_TYPE_TCP_ESTABLISHED, | ||
| 3874 | I40IW_QHASH_MANAGE_TYPE_DELETE, | ||
| 3875 | NULL, | ||
| 3876 | false); | ||
| 3877 | |||
| 3878 | if (apbvt_set && !i40iw_listen_port_in_use(&iwdev->cm_core, | ||
| 3879 | cm_info.loc_port)) | ||
| 3880 | i40iw_manage_apbvt(iwdev, | ||
| 3881 | cm_info.loc_port, | ||
| 3882 | I40IW_MANAGE_APBVT_DEL); | ||
| 3883 | cm_id->rem_ref(cm_id); | 3883 | cm_id->rem_ref(cm_id); |
| 3884 | iwdev->cm_core.stats_connect_errs++; | 3884 | iwdev->cm_core.stats_connect_errs++; |
| 3885 | return err; | 3885 | return ret; |
| 3886 | } | 3886 | } |
| 3887 | 3887 | ||
| 3888 | /** | 3888 | /** |
| @@ -71,6 +71,9 @@ · 70 unmodified lines | |||
| 71 | #define I40IW_HW_IRD_SETTING_32 32 | 71 | #define I40IW_HW_IRD_SETTING_32 32 |
| 72 | #define I40IW_HW_IRD_SETTING_64 64 | 72 | #define I40IW_HW_IRD_SETTING_64 64 |
| 73 | 73 | ||
| 74 | #define MAX_PORTS 65536 | ||
| 75 | #define I40IW_VLAN_PRIO_SHIFT 13 | ||
| 76 | |||
| 74 | enum ietf_mpa_flags { | 77 | enum ietf_mpa_flags { |
| 75 | IETF_MPA_FLAGS_MARKERS = 0x80, /* receive Markers */ | 78 | IETF_MPA_FLAGS_MARKERS = 0x80, /* receive Markers */ |
| 76 | IETF_MPA_FLAGS_CRC = 0x40, /* receive Markers */ | 79 | IETF_MPA_FLAGS_CRC = 0x40, /* receive Markers */ |
| @@ -411,6 +414,8 @@ struct i40iw_cm_core { · 334 unmodified lines | |||
| 411 | spinlock_t ht_lock; /* manage hash table */ | 414 | spinlock_t ht_lock; /* manage hash table */ |
| 412 | spinlock_t listen_list_lock; /* listen list */ | 415 | spinlock_t listen_list_lock; /* listen list */ |
| 413 | 416 | ||
| 417 | unsigned long active_side_ports[BITS_TO_LONGS(MAX_PORTS)]; | ||
| 418 | |||
| 414 | u64 stats_nodes_created; | 419 | u64 stats_nodes_created; |
| 415 | u64 stats_nodes_destroyed; | 420 | u64 stats_nodes_destroyed; |
| 416 | u64 stats_listen_created; | 421 | u64 stats_listen_created; |
| @@ -99,8 +99,6 @@ static struct notifier_block i40iw_net_notifier = { · 98 unmodified lines | |||
| 99 | .notifier_call = i40iw_net_event | 99 | .notifier_call = i40iw_net_event |
| 100 | }; | 100 | }; |
| 101 | 101 | ||
| 102 | static atomic_t i40iw_notifiers_registered; | ||
| 103 | |||
| 104 | /** | 102 | /** |
| 105 | * i40iw_find_i40e_handler - find a handler given a client info | 103 | * i40iw_find_i40e_handler - find a handler given a client info |
| 106 | * @ldev: pointer to a client info | 104 | * @ldev: pointer to a client info |
| @@ -1376,11 +1374,20 @@ error: · 1269 unmodified lines | |||
| 1376 | */ | 1374 | */ |
| 1377 | static void i40iw_register_notifiers(void) | 1375 | static void i40iw_register_notifiers(void) |
| 1378 | { | 1376 | { |
| 1379 | if (atomic_inc_return(&i40iw_notifiers_registered) == 1) { | 1377 | register_inetaddr_notifier(&i40iw_inetaddr_notifier); |
| 1380 | register_inetaddr_notifier(&i40iw_inetaddr_notifier); | 1378 | register_inet6addr_notifier(&i40iw_inetaddr6_notifier); |
| 1381 | register_inet6addr_notifier(&i40iw_inetaddr6_notifier); | 1379 | register_netevent_notifier(&i40iw_net_notifier); |
| 1382 | register_netevent_notifier(&i40iw_net_notifier); | 1380 | } |
| 1383 | } | 1381 | |
| 1382 | /** | ||
| 1383 | * i40iw_unregister_notifiers - unregister tcp ip notifiers | ||
| 1384 | */ | ||
| 1385 | |||
| 1386 | static void i40iw_unregister_notifiers(void) | ||
| 1387 | { | ||
| 1388 | unregister_netevent_notifier(&i40iw_net_notifier); | ||
| 1389 | unregister_inetaddr_notifier(&i40iw_inetaddr_notifier); | ||
| 1390 | unregister_inet6addr_notifier(&i40iw_inetaddr6_notifier); | ||
| 1384 | } | 1391 | } |
| 1385 | 1392 | ||
| 1386 | /** | 1393 | /** |
| @@ -1400,6 +1407,11 @@ static enum i40iw_status_code i40iw_save_msix_info(struct i40iw_device *iwdev, · 13 unmodified lines | |||
| 1400 | u32 i; | 1407 | u32 i; |
| 1401 | u32 size; | 1408 | u32 size; |
| 1402 | 1409 | ||
| 1410 | if (!ldev->msix_count) { | ||
| 1411 | i40iw_pr_err("No MSI-X vectors\n"); | ||
| 1412 | return I40IW_ERR_CONFIG; | ||
| 1413 | } | ||
| 1414 | |||
| 1403 | iwdev->msix_count = ldev->msix_count; | 1415 | iwdev->msix_count = ldev->msix_count; |
| 1404 | 1416 | ||
| 1405 | size = sizeof(struct i40iw_msix_vector) * iwdev->msix_count; | 1417 | size = sizeof(struct i40iw_msix_vector) * iwdev->msix_count; |
| @@ -1462,12 +1474,6 @@ static void i40iw_deinit_device(struct i40iw_device *iwdev) · 56 unmodified lines | |||
| 1462 | if (!iwdev->reset) | 1474 | if (!iwdev->reset) |
| 1463 | i40iw_del_macip_entry(iwdev, (u8)iwdev->mac_ip_table_idx); | 1475 | i40iw_del_macip_entry(iwdev, (u8)iwdev->mac_ip_table_idx); |
| 1464 | /* fallthrough */ | 1476 | /* fallthrough */ |
| 1465 | case INET_NOTIFIER: | ||
| 1466 | if (!atomic_dec_return(&i40iw_notifiers_registered)) { | ||
| 1467 | unregister_netevent_notifier(&i40iw_net_notifier); | ||
| 1468 | unregister_inetaddr_notifier(&i40iw_inetaddr_notifier); | ||
| 1469 | unregister_inet6addr_notifier(&i40iw_inetaddr6_notifier); | ||
| 1470 | } | ||
| 1471 | /* fallthrough */ | 1477 | /* fallthrough */ |
| 1472 | case PBLE_CHUNK_MEM: | 1478 | case PBLE_CHUNK_MEM: |
| 1473 | i40iw_destroy_pble_pool(dev, iwdev->pble_rsrc); | 1479 | i40iw_destroy_pble_pool(dev, iwdev->pble_rsrc); |
| @@ -1550,7 +1556,7 @@ static enum i40iw_status_code i40iw_setup_init_state(struct i40iw_handler *hdl, · 76 unmodified lines | |||
| 1550 | 1556 | ||
| 1551 | status = i40iw_save_msix_info(iwdev, ldev); | 1557 | status = i40iw_save_msix_info(iwdev, ldev); |
| 1552 | if (status) | 1558 | if (status) |
| 1553 | goto exit; | 1559 | return status; |
| 1554 | iwdev->hw.dev_context = (void *)ldev->pcidev; | 1560 | iwdev->hw.dev_context = (void *)ldev->pcidev; |
| 1555 | iwdev->hw.hw_addr = ldev->hw_addr; | 1561 | iwdev->hw.hw_addr = ldev->hw_addr; |
| 1556 | status = i40iw_allocate_dma_mem(&iwdev->hw, | 1562 | status = i40iw_allocate_dma_mem(&iwdev->hw, |
| @@ -1667,8 +1673,6 @@ static int i40iw_open(struct i40e_info *ldev, struct i40e_client *client) · 110 unmodified lines | |||
| 1667 | break; | 1673 | break; |
| 1668 | iwdev->init_state = PBLE_CHUNK_MEM; | 1674 | iwdev->init_state = PBLE_CHUNK_MEM; |
| 1669 | iwdev->virtchnl_wq = alloc_ordered_workqueue("iwvch", WQ_MEM_RECLAIM); | 1675 | iwdev->virtchnl_wq = alloc_ordered_workqueue("iwvch", WQ_MEM_RECLAIM); |
| 1670 | i40iw_register_notifiers(); | ||
| 1671 | iwdev->init_state = INET_NOTIFIER; | ||
| 1672 | status = i40iw_add_mac_ip(iwdev); | 1676 | status = i40iw_add_mac_ip(iwdev); |
| 1673 | if (status) | 1677 | if (status) |
| 1674 | break; | 1678 | break; |
| @@ -2018,6 +2022,8 @@ static int __init i40iw_init_module(void) · 343 unmodified lines | |||
| 2018 | i40iw_client.type = I40E_CLIENT_IWARP; | 2022 | i40iw_client.type = I40E_CLIENT_IWARP; |
| 2019 | spin_lock_init(&i40iw_handler_lock); | 2023 | spin_lock_init(&i40iw_handler_lock); |
| 2020 | ret = i40e_register_client(&i40iw_client); | 2024 | ret = i40e_register_client(&i40iw_client); |
| 2025 | i40iw_register_notifiers(); | ||
| 2026 | |||
| 2021 | return ret; | 2027 | return ret; |
| 2022 | } | 2028 | } |
| 2023 | 2029 | ||
| @@ -2029,6 +2035,7 @@ static int __init i40iw_init_module(void) · 5 unmodified lines | |||
| 2029 | */ | 2035 | */ |
| 2030 | static void __exit i40iw_exit_module(void) | 2036 | static void __exit i40iw_exit_module(void) |
| 2031 | { | 2037 | { |
| 2038 | i40iw_unregister_notifiers(); | ||
| 2032 | i40e_unregister_client(&i40iw_client); | 2039 | i40e_unregister_client(&i40iw_client); |
| 2033 | } | 2040 | } |
| 2034 | 2041 | ||
| @@ -160,7 +160,7 @@ int i40iw_inetaddr_event(struct notifier_block *notifier, · 159 unmodified lines | |||
| 160 | return NOTIFY_DONE; | 160 | return NOTIFY_DONE; |
| 161 | 161 | ||
| 162 | iwdev = &hdl->device; | 162 | iwdev = &hdl->device; |
| 163 | if (iwdev->init_state < INET_NOTIFIER) | 163 | if (iwdev->init_state < IP_ADDR_REGISTERED || iwdev->closing) |
| 164 | return NOTIFY_DONE; | 164 | return NOTIFY_DONE; |
| 165 | 165 | ||
| 166 | netdev = iwdev->ldev->netdev; | 166 | netdev = iwdev->ldev->netdev; |
| @@ -217,7 +217,7 @@ int i40iw_inet6addr_event(struct notifier_block *notifier, · 50 unmodified lines | |||
| 217 | return NOTIFY_DONE; | 217 | return NOTIFY_DONE; |
| 218 | 218 | ||
| 219 | iwdev = &hdl->device; | 219 | iwdev = &hdl->device; |
| 220 | if (iwdev->init_state < INET_NOTIFIER) | 220 | if (iwdev->init_state < IP_ADDR_REGISTERED || iwdev->closing) |
| 221 | return NOTIFY_DONE; | 221 | return NOTIFY_DONE; |
| 222 | 222 | ||
| 223 | netdev = iwdev->ldev->netdev; | 223 | netdev = iwdev->ldev->netdev; |
| @@ -266,7 +266,7 @@ int i40iw_net_event(struct notifier_block *notifier, unsigned long event, void * · 42 unmodified lines | |||
| 266 | if (!iwhdl) | 266 | if (!iwhdl) |
| 267 | return NOTIFY_DONE; | 267 | return NOTIFY_DONE; |
| 268 | iwdev = &iwhdl->device; | 268 | iwdev = &iwhdl->device; |
| 269 | if (iwdev->init_state < INET_NOTIFIER) | 269 | if (iwdev->init_state < IP_ADDR_REGISTERED || iwdev->closing) |
| 270 | return NOTIFY_DONE; | 270 | return NOTIFY_DONE; |
| 271 | p = (__be32 *)neigh->primary_key; | 271 | p = (__be32 *)neigh->primary_key; |
| 272 | i40iw_copy_ip_ntohl(local_ipaddr, p); | 272 | i40iw_copy_ip_ntohl(local_ipaddr, p); |
| @@ -1027,7 +1027,19 @@ int i40iw_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, · 1026 unmodified lines | |||
| 1027 | iwqp->hw_tcp_state = I40IW_TCP_STATE_CLOSED; | 1027 | iwqp->hw_tcp_state = I40IW_TCP_STATE_CLOSED; |
| 1028 | iwqp->last_aeq = I40IW_AE_RESET_SENT; | 1028 | iwqp->last_aeq = I40IW_AE_RESET_SENT; |
| 1029 | spin_unlock_irqrestore(&iwqp->lock, flags); | 1029 | spin_unlock_irqrestore(&iwqp->lock, flags); |
| 1030 | i40iw_cm_disconn(iwqp); | ||
| 1030 | } | 1031 | } |
| 1032 | } else { | ||
| 1033 | spin_lock_irqsave(&iwqp->lock, flags); | ||
| 1034 | if (iwqp->cm_id) { | ||
| 1035 | if (atomic_inc_return(&iwqp->close_timer_started) == 1) { | ||
| 1036 | iwqp->cm_id->add_ref(iwqp->cm_id); | ||
| 1037 | i40iw_schedule_cm_timer(iwqp->cm_node, | ||
| 1038 | (struct i40iw_puda_buf *)iwqp, | ||
| 1039 | I40IW_TIMER_TYPE_CLOSE, 1, 0); | ||
| 1040 | } | ||
| 1041 | } | ||
| 1042 | spin_unlock_irqrestore(&iwqp->lock, flags); | ||
| 1031 | } | 1043 | } |
| 1032 | } | 1044 | } |
| 1033 | return 0; | 1045 | return 0; |
| @@ -3837,11 +3837,13 @@ static int delay_drop_debugfs_init(struct mlx5_ib_dev *dev) · 3836 unmodified lines | |||
| 3837 | if (!dbg) | 3837 | if (!dbg) |
| 3838 | return -ENOMEM; | 3838 | return -ENOMEM; |
| 3839 | 3839 | ||
| 3840 | dev->delay_drop.dbg = dbg; | ||
| 3841 | |||
| 3840 | dbg->dir_debugfs = | 3842 | dbg->dir_debugfs = |
| 3841 | debugfs_create_dir("delay_drop", | 3843 | debugfs_create_dir("delay_drop", |
| 3842 | dev->mdev->priv.dbg_root); | 3844 | dev->mdev->priv.dbg_root); |
| 3843 | if (!dbg->dir_debugfs) | 3845 | if (!dbg->dir_debugfs) |
| 3844 | return -ENOMEM; | 3846 | goto out_debugfs; |
| 3845 | 3847 | ||
| 3846 | dbg->events_cnt_debugfs = | 3848 | dbg->events_cnt_debugfs = |
| 3847 | debugfs_create_atomic_t("num_timeout_events", 0400, | 3849 | debugfs_create_atomic_t("num_timeout_events", 0400, |
| @@ -3865,8 +3867,6 @@ static int delay_drop_debugfs_init(struct mlx5_ib_dev *dev) · 17 unmodified lines | |||
| 3865 | if (!dbg->timeout_debugfs) | 3867 | if (!dbg->timeout_debugfs) |
| 3866 | goto out_debugfs; | 3868 | goto out_debugfs; |
| 3867 | 3869 | ||
| 3868 | dev->delay_drop.dbg = dbg; | ||
| 3869 | |||
| 3870 | return 0; | 3870 | return 0; |
| 3871 | 3871 | ||
| 3872 | out_debugfs: | 3872 | out_debugfs: |
| @@ -252,7 +252,10 @@ static int ocrdma_get_mbx_errno(u32 status) · 251 unmodified lines | |||
| 252 | case OCRDMA_MBX_ADDI_STATUS_INSUFFICIENT_RESOURCES: | 252 | case OCRDMA_MBX_ADDI_STATUS_INSUFFICIENT_RESOURCES: |
| 253 | err_num = -EAGAIN; | 253 | err_num = -EAGAIN; |
| 254 | break; | 254 | break; |
| 255 | default: | ||
| 256 | err_num = -EFAULT; | ||
| 255 | } | 257 | } |
| 258 | break; | ||
| 256 | default: | 259 | default: |
| 257 | err_num = -EFAULT; | 260 | err_num = -EFAULT; |
| 258 | } | 261 | } |
| @@ -416,9 +416,34 @@ static inline enum ib_wc_status pvrdma_wc_status_to_ib( · 415 unmodified lines | |||
| 416 | return (enum ib_wc_status)status; | 416 | return (enum ib_wc_status)status; |
| 417 | } | 417 | } |
| 418 | 418 | ||
| 419 | static inline int pvrdma_wc_opcode_to_ib(int opcode) | 419 | static inline int pvrdma_wc_opcode_to_ib(unsigned int opcode) |
| 420 | { | 420 | { |
| 421 | return opcode; | 421 | switch (opcode) { |
| 422 | case PVRDMA_WC_SEND: | ||
| 423 | return IB_WC_SEND; | ||
| 424 | case PVRDMA_WC_RDMA_WRITE: | ||
| 425 | return IB_WC_RDMA_WRITE; | ||
| 426 | case PVRDMA_WC_RDMA_READ: | ||
| 427 | return IB_WC_RDMA_READ; | ||
| 428 | case PVRDMA_WC_COMP_SWAP: | ||
| 429 | return IB_WC_COMP_SWAP; | ||
| 430 | case PVRDMA_WC_FETCH_ADD: | ||
| 431 | return IB_WC_FETCH_ADD; | ||
| 432 | case PVRDMA_WC_LOCAL_INV: | ||
| 433 | return IB_WC_LOCAL_INV; | ||
| 434 | case PVRDMA_WC_FAST_REG_MR: | ||
| 435 | return IB_WC_REG_MR; | ||
| 436 | case PVRDMA_WC_MASKED_COMP_SWAP: | ||
| 437 | return IB_WC_MASKED_COMP_SWAP; | ||
| 438 | case PVRDMA_WC_MASKED_FETCH_ADD: | ||
| 439 | return IB_WC_MASKED_FETCH_ADD; | ||
| 440 | case PVRDMA_WC_RECV: | ||
| 441 | return IB_WC_RECV; | ||
| 442 | case PVRDMA_WC_RECV_RDMA_WITH_IMM: | ||
| 443 | return IB_WC_RECV_RDMA_WITH_IMM; | ||
| 444 | default: | ||
| 445 | return IB_WC_SEND; | ||
| 446 | } | ||
| 422 | } | 447 | } |
| 423 | 448 | ||
| 424 | static inline int pvrdma_wc_flags_to_ib(int flags) | 449 | static inline int pvrdma_wc_flags_to_ib(int flags) |
| @@ -823,12 +823,18 @@ void ipoib_cm_handle_tx_wc(struct net_device *dev, struct ib_wc *wc) · 822 unmodified lines | |||
| 823 | wc->status != IB_WC_WR_FLUSH_ERR) { | 823 | wc->status != IB_WC_WR_FLUSH_ERR) { |
| 824 | struct ipoib_neigh *neigh; | 824 | struct ipoib_neigh *neigh; |
| 825 | 825 | ||
| 826 | if (wc->status != IB_WC_RNR_RETRY_EXC_ERR) | 826 | /* IB_WC[_RNR]_RETRY_EXC_ERR error is part of the life cycle, |
| 827 | ipoib_warn(priv, "failed cm send event (status=%d, wrid=%d vend_err %x)\n", | 827 | * so don't make waves. |
| 828 | wc->status, wr_id, wc->vendor_err); | 828 | */ |
| 829 | if (wc->status == IB_WC_RNR_RETRY_EXC_ERR || | ||
| 830 | wc->status == IB_WC_RETRY_EXC_ERR) | ||
| 831 | ipoib_dbg(priv, | ||
| 832 | "%s: failed cm send event (status=%d, wrid=%d vend_err 0x%x)\n", | ||
| 833 | __func__, wc->status, wr_id, wc->vendor_err); | ||
| 829 | else | 834 | else |
| 830 | ipoib_dbg(priv, "failed cm send event (status=%d, wrid=%d vend_err %x)\n", | 835 | ipoib_warn(priv, |
| 831 | wc->status, wr_id, wc->vendor_err); | 836 | "%s: failed cm send event (status=%d, wrid=%d vend_err 0x%x)\n", |
| 837 | __func__, wc->status, wr_id, wc->vendor_err); | ||
| 832 | 838 | ||
| 833 | spin_lock_irqsave(&priv->lock, flags); | 839 | spin_lock_irqsave(&priv->lock, flags); |
| 834 | neigh = tx->neigh; | 840 | neigh = tx->neigh; |