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 | 1647 | if (!ib_query_qp(qp, &attr, IB_QP_STATE | IB_QP_PORT, &init_attr)) { |
| 1648 | 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 | 1650 | IB_LINK_LAYER_INFINIBAND) |
| 1651 | 1651 | return true; |
| 1652 | 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 | 1656 | /* Can't get a quick answer, iterate over all ports */ |
| 1657 | 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 | 1659 | IB_LINK_LAYER_INFINIBAND) |
| 1660 | 1660 | num_eth_ports++; |
| 1661 | 1661 | |
| @@ -93,11 +93,13 @@ struct bnxt_re_dev { · 92 unmodified lines | ||
| 93 | 93 | struct ib_device ibdev; |
| 94 | 94 | struct list_head list; |
| 95 | 95 | unsigned long flags; |
| 96 | −#define BNXT_RE_FLAG_NETDEV_REGISTERED 0 | |
| 97 | −#define BNXT_RE_FLAG_IBDEV_REGISTERED 1 | |
| 98 | −#define BNXT_RE_FLAG_GOT_MSIX 2 | |
| 99 | −#define BNXT_RE_FLAG_RCFW_CHANNEL_EN 8 | |
| 100 | −#define BNXT_RE_FLAG_QOS_WORK_REG 16 | |
| 96 | +#define BNXT_RE_FLAG_NETDEV_REGISTERED 0 | |
| 97 | +#define BNXT_RE_FLAG_IBDEV_REGISTERED 1 | |
| 98 | +#define BNXT_RE_FLAG_GOT_MSIX 2 | |
| 99 | +#define BNXT_RE_FLAG_HAVE_L2_REF 3 | |
| 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 | 103 | struct net_device *netdev; |
| 102 | 104 | unsigned int version, major, minor; |
| 103 | 105 | struct bnxt_en_dev *en_dev; |
| @@ -108,6 +110,8 @@ struct bnxt_re_dev { · 4 unmodified lines | ||
| 108 | 110 | |
| 109 | 111 | struct delayed_work worker; |
| 110 | 112 | u8 cur_prio_map; |
| 113 | + u8 active_speed; | |
| 114 | + u8 active_width; | |
| 111 | 115 | |
| 112 | 116 | /* FP Notification Queue (CQ & SRQ) */ |
| 113 | 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 | 259 | port_attr->sm_sl = 0; |
| 260 | 260 | port_attr->subnet_timeout = 0; |
| 261 | 261 | port_attr->init_type_reply = 0; |
| 262 | − /* call the underlying netdev's ethtool hooks to query speed settings | |
| 263 | − * for which we acquire rtnl_lock _only_ if it's registered with | |
| 264 | − * IB stack to avoid race in the NETDEV_UNREG path | |
| 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; | |
| 262 | + port_attr->active_speed = rdev->active_speed; | |
| 263 | + port_attr->active_width = rdev->active_width; | |
| 264 | + | |
| 270 | 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 | 314 | struct bnxt_re_gid_ctx *ctx, **ctx_tbl; |
| 320 | 315 | struct bnxt_re_dev *rdev = to_bnxt_re_dev(ibdev, ibdev); |
| 321 | 316 | struct bnxt_qplib_sgid_tbl *sgid_tbl = &rdev->qplib_res.sgid_tbl; |
| 317 | + struct bnxt_qplib_gid *gid_to_del; | |
| 322 | 318 | |
| 323 | 319 | /* Delete the entry from the hardware */ |
| 324 | 320 | ctx = *context; |
| @@ -328,11 +324,25 @@ int bnxt_re_del_gid(struct ib_device *ibdev, u8 port_num, · 3 unmodified lines | ||
| 328 | 324 | if (sgid_tbl && sgid_tbl->active) { |
| 329 | 325 | if (ctx->idx >= sgid_tbl->max) |
| 330 | 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 | 343 | ctx->refcnt--; |
| 332 | 344 | if (!ctx->refcnt) { |
| 333 | − rc = bnxt_qplib_del_sgid(sgid_tbl, | |
| 334 | − &sgid_tbl->tbl[ctx->idx], | |
| 335 | − true); | |
| 345 | + rc = bnxt_qplib_del_sgid(sgid_tbl, gid_to_del, true); | |
| 336 | 346 | if (rc) { |
| 337 | 347 | dev_err(rdev_to_dev(rdev), |
| 338 | 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 | 827 | kfree(rdev->sqp_ah); |
| 818 | 828 | kfree(rdev->qp1_sqp); |
| 829 | + rdev->qp1_sqp = NULL; | |
| 830 | + rdev->sqp_ah = NULL; | |
| 819 | 831 | } |
| 820 | 832 | |
| 821 | 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 | 1448 | qp->qplib_qp.modify_flags |= |
| 1437 | 1449 | CMDQ_MODIFY_QP_MODIFY_MASK_PATH_MTU; |
| 1438 | 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 | 1452 | } else if (qp_attr->qp_state == IB_QPS_RTR) { |
| 1440 | 1453 | qp->qplib_qp.modify_flags |= |
| 1441 | 1454 | CMDQ_MODIFY_QP_MODIFY_MASK_PATH_MTU; |
| 1442 | 1455 | qp->qplib_qp.path_mtu = |
| 1443 | 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 | 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 | 1567 | struct bnxt_re_qp *qp = container_of(ib_qp, struct bnxt_re_qp, ib_qp); |
| 1553 | 1568 | struct bnxt_re_dev *rdev = qp->rdev; |
| 1554 | − struct bnxt_qplib_qp qplib_qp; | |
| 1569 | + struct bnxt_qplib_qp *qplib_qp; | |
| 1555 | 1570 | int rc; |
| 1556 | 1571 | |
| 1557 | − memset(&qplib_qp, 0, sizeof(struct bnxt_qplib_qp)); | |
| 1558 | − qplib_qp.id = qp->qplib_qp.id; | |
| 1559 | − qplib_qp.ah.host_sgid_index = qp->qplib_qp.ah.host_sgid_index; | |
| 1572 | + qplib_qp = kzalloc(sizeof(*qplib_qp), GFP_KERNEL); | |
| 1573 | + if (!qplib_qp) | |
| 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 | 1580 | if (rc) { |
| 1563 | 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); | |
| 1567 | − 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); | |
| 1569 | − qp_attr->pkey_index = qplib_qp.pkey_index; | |
| 1570 | − qp_attr->qkey = qplib_qp.qkey; | |
| 1584 | + qp_attr->qp_state = __to_ib_qp_state(qplib_qp->state); | |
| 1585 | + qp_attr->en_sqd_async_notify = qplib_qp->en_sqd_async_notify ? 1 : 0; | |
| 1586 | + qp_attr->qp_access_flags = __to_ib_access_flags(qplib_qp->access); | |
| 1587 | + qp_attr->pkey_index = qplib_qp->pkey_index; | |
| 1588 | + qp_attr->qkey = qplib_qp->qkey; | |
| 1571 | 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, | |
| 1573 | − qplib_qp.ah.host_sgid_index, | |
| 1574 | − qplib_qp.ah.hop_limit, | |
| 1575 | − qplib_qp.ah.traffic_class); | |
| 1576 | − 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); | |
| 1578 | − 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); | |
| 1580 | − qp_attr->timeout = qplib_qp.timeout; | |
| 1581 | − qp_attr->retry_cnt = qplib_qp.retry_cnt; | |
| 1582 | − qp_attr->rnr_retry = qplib_qp.rnr_retry; | |
| 1583 | − qp_attr->min_rnr_timer = qplib_qp.min_rnr_timer; | |
| 1584 | − qp_attr->rq_psn = qplib_qp.rq.psn; | |
| 1585 | − qp_attr->max_rd_atomic = qplib_qp.max_rd_atomic; | |
| 1586 | − qp_attr->sq_psn = qplib_qp.sq.psn; | |
| 1587 | − 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 : | |
| 1589 | − IB_SIGNAL_REQ_WR; | |
| 1590 | − qp_attr->dest_qp_num = qplib_qp.dest_qpn; | |
| 1590 | + rdma_ah_set_grh(&qp_attr->ah_attr, NULL, qplib_qp->ah.flow_label, | |
| 1591 | + qplib_qp->ah.host_sgid_index, | |
| 1592 | + qplib_qp->ah.hop_limit, | |
| 1593 | + qplib_qp->ah.traffic_class); | |
| 1594 | + rdma_ah_set_dgid_raw(&qp_attr->ah_attr, qplib_qp->ah.dgid.data); | |
| 1595 | + rdma_ah_set_sl(&qp_attr->ah_attr, qplib_qp->ah.sl); | |
| 1596 | + ether_addr_copy(qp_attr->ah_attr.roce.dmac, qplib_qp->ah.dmac); | |
| 1597 | + qp_attr->path_mtu = __to_ib_mtu(qplib_qp->path_mtu); | |
| 1598 | + qp_attr->timeout = qplib_qp->timeout; | |
| 1599 | + qp_attr->retry_cnt = qplib_qp->retry_cnt; | |
| 1600 | + qp_attr->rnr_retry = qplib_qp->rnr_retry; | |
| 1601 | + qp_attr->min_rnr_timer = qplib_qp->min_rnr_timer; | |
| 1602 | + qp_attr->rq_psn = qplib_qp->rq.psn; | |
| 1603 | + qp_attr->max_rd_atomic = qplib_qp->max_rd_atomic; | |
| 1604 | + qp_attr->sq_psn = qplib_qp->sq.psn; | |
| 1605 | + qp_attr->max_dest_rd_atomic = qplib_qp->max_dest_rd_atomic; | |
| 1606 | + qp_init_attr->sq_sig_type = qplib_qp->sig_type ? IB_SIGNAL_ALL_WR : | |
| 1607 | + IB_SIGNAL_REQ_WR; | |
| 1608 | + qp_attr->dest_qp_num = qplib_qp->dest_qpn; | |
| 1591 | 1609 | |
| 1592 | 1610 | qp_attr->cap.max_send_wr = qp->qplib_qp.sq.max_wqe; |
| 1593 | 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 | 1614 | qp_attr->cap.max_inline_data = qp->qplib_qp.max_inline_data; |
| 1597 | 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 | 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 | 1928 | switch (wr->opcode) { |
| 1909 | 1929 | case IB_WR_ATOMIC_CMP_AND_SWP: |
| 1910 | 1930 | wqe->type = BNXT_QPLIB_SWQE_TYPE_ATOMIC_CMP_AND_SWP; |
| 1931 | + wqe->atomic.cmp_data = atomic_wr(wr)->compare_add; | |
| 1911 | 1932 | wqe->atomic.swap_data = atomic_wr(wr)->swap; |
| 1912 | 1933 | break; |
| 1913 | 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 | 3083 | return rc; |
| 3063 | 3084 | } |
| 3064 | 3085 | |
| 3065 | − if (mr->npages && mr->pages) { | |
| 3086 | + if (mr->pages) { | |
| 3066 | 3087 | rc = bnxt_qplib_free_fast_reg_page_list(&rdev->qplib_res, |
| 3067 | 3088 | &mr->qplib_frpl); |
| 3068 | 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 | 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 | 1166 | bnxt_re_dispatch_event(&rdev->ibdev, NULL, 1, IB_EVENT_PORT_ACTIVE); |
| 1165 | 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 | 1257 | else if (netif_carrier_ok(rdev->netdev)) |
| 1256 | 1258 | bnxt_re_dispatch_event(&rdev->ibdev, NULL, 1, |
| 1257 | 1259 | IB_EVENT_PORT_ACTIVE); |
| 1260 | + ib_get_eth_speed(&rdev->ibdev, 1, &rdev->active_speed, | |
| 1261 | + &rdev->active_width); | |
| 1258 | 1262 | break; |
| 1259 | 1263 | default: |
| 1260 | 1264 | break; |
| 1261 | 1265 | } |
| 1266 | + smp_mb__before_atomic(); | |
| 1267 | + clear_bit(BNXT_RE_FLAG_TASK_IN_PROG, &rdev->flags); | |
| 1262 | 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 | 1323 | break; |
| 1318 | 1324 | |
| 1319 | 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 | 1331 | bnxt_re_ib_unreg(rdev, false); |
| 1321 | 1332 | bnxt_re_remove_one(rdev); |
| 1322 | 1333 | bnxt_re_dev_unreg(rdev); |
| @@ -1335,6 +1346,7 @@ static int bnxt_re_netdev_event(struct notifier_block *notifier, · 12 unmodified lines | ||
| 1335 | 1346 | re_work->vlan_dev = (real_dev == netdev ? |
| 1336 | 1347 | NULL : netdev); |
| 1337 | 1348 | INIT_WORK(&re_work->work, bnxt_re_task); |
| 1349 | + set_bit(BNXT_RE_FLAG_TASK_IN_PROG, &rdev->flags); | |
| 1338 | 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 | 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 | 1406 | unregister_netdevice_notifier(&bnxt_re_netdev_notifier); |
| 1379 | 1407 | if (bnxt_re_wq) |
| 1380 | 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 | 107 | return -EINVAL; |
| 108 | 108 | } |
| 109 | 109 | |
| 110 | + if (test_bit(FIRMWARE_TIMED_OUT, &rcfw->flags)) | |
| 111 | + return -ETIMEDOUT; | |
| 112 | + | |
| 110 | 113 | /* Cmdq are in 16-byte units, each request can consume 1 or more |
| 111 | 114 | * cmdqe |
| 112 | 115 | */ |
| @@ -226,6 +229,7 @@ int bnxt_qplib_rcfw_send_message(struct bnxt_qplib_rcfw *rcfw, · 113 unmodified lines | ||
| 226 | 229 | /* timed out */ |
| 227 | 230 | dev_err(&rcfw->pdev->dev, "QPLIB: cmdq[%#x]=%#x timedout (%d)msec", |
| 228 | 231 | cookie, opcode, RCFW_CMD_WAIT_TIME_MS); |
| 232 | + set_bit(FIRMWARE_TIMED_OUT, &rcfw->flags); | |
| 229 | 233 | return rc; |
| 230 | 234 | } |
| 231 | 235 | |
| @@ -162,8 +162,9 @@ struct bnxt_qplib_rcfw { · 161 unmodified lines | ||
| 162 | 162 | unsigned long *cmdq_bitmap; |
| 163 | 163 | u32 bmap_size; |
| 164 | 164 | unsigned long flags; |
| 165 | −#define FIRMWARE_INITIALIZED_FLAG 1 | |
| 165 | +#define FIRMWARE_INITIALIZED_FLAG BIT(0) | |
| 166 | 166 | #define FIRMWARE_FIRST_FLAG BIT(31) |
| 167 | +#define FIRMWARE_TIMED_OUT BIT(3) | |
| 167 | 168 | wait_queue_head_t waitq; |
| 168 | 169 | int (*aeq_handler)(struct bnxt_qplib_rcfw *, |
| 169 | 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 | 2333 | unsigned int stid = GET_TID(rpl); |
| 2334 | 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 | 2340 | pr_debug("%s ep %p\n", __func__, ep); |
| 2337 | 2341 | c4iw_wake_up(&ep->com.wr_wait, status2errno(rpl->status)); |
| 2338 | 2342 | c4iw_put_ep(&ep->com); |
| 2343 | +out: | |
| 2339 | 2344 | return 0; |
| 2340 | 2345 | } |
| 2341 | 2346 | |
| @@ -2594,9 +2599,9 @@ fail: · 252 unmodified lines | ||
| 2594 | 2599 | c4iw_put_ep(&child_ep->com); |
| 2595 | 2600 | reject: |
| 2596 | 2601 | reject_cr(dev, hwtid, skb); |
| 2602 | +out: | |
| 2597 | 2603 | if (parent_ep) |
| 2598 | 2604 | c4iw_put_ep(&parent_ep->com); |
| 2599 | −out: | |
| 2600 | 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 | 3462 | cm_id->provider_data = ep; |
| 3458 | 3463 | goto out; |
| 3459 | 3464 | } |
| 3460 | − | |
| 3465 | + remove_handle(ep->com.dev, &ep->com.dev->stid_idr, ep->stid); | |
| 3461 | 3466 | cxgb4_free_stid(ep->com.dev->rdev.lldi.tids, ep->stid, |
| 3462 | 3467 | ep->com.local_addr.ss_family); |
| 3463 | 3468 | fail2: |
| @@ -201,7 +201,6 @@ enum init_completion_state { · 200 unmodified lines | ||
| 201 | 201 | CEQ_CREATED, |
| 202 | 202 | ILQ_CREATED, |
| 203 | 203 | IEQ_CREATED, |
| 204 | − INET_NOTIFIER, | |
| 205 | 204 | IP_ADDR_REGISTERED, |
| 206 | 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 | |
| 1508 | − * @port: Listen port number | |
| 1507 | + * i40iw_port_in_use - determine if port is in use | |
| 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 | 1513 | struct i40iw_cm_listener *listen_node; |
| 1514 | + struct i40iw_cm_node *cm_node; | |
| 1513 | 1515 | unsigned long flags; |
| 1514 | 1516 | bool ret = false; |
| 1515 | 1517 | |
| 1516 | − spin_lock_irqsave(&cm_core->listen_list_lock, flags); | |
| 1517 | − list_for_each_entry(listen_node, &cm_core->listen_nodes, list) { | |
| 1518 | − if (listen_node->loc_port == port) { | |
| 1519 | − ret = true; | |
| 1520 | − break; | |
| 1518 | + if (active_side) { | |
| 1519 | + /* search connected node list */ | |
| 1520 | + spin_lock_irqsave(&cm_core->ht_lock, flags); | |
| 1521 | + list_for_each_entry(cm_node, &cm_core->connected_nodes, list) { | |
| 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 | 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 | 1885 | spin_unlock_irqrestore(&cm_core->listen_list_lock, flags); |
| 1869 | 1886 | |
| 1870 | 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 | 1889 | i40iw_manage_apbvt(listener->iwdev, |
| 1873 | 1890 | listener->loc_port, |
| 1874 | 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 | 2264 | if (cm_node->listener) { |
| 2248 | 2265 | i40iw_dec_refcnt_listen(cm_core, cm_node->listener, 0, true); |
| 2249 | 2266 | } else { |
| 2250 | − if (!i40iw_listen_port_in_use(cm_core, cm_node->loc_port) && | |
| 2251 | − cm_node->apbvt_set) { | |
| 2267 | + if (!i40iw_port_in_use(cm_core, cm_node->loc_port, true) && cm_node->apbvt_set) { | |
| 2252 | 2268 | i40iw_manage_apbvt(cm_node->iwdev, |
| 2253 | 2269 | cm_node->loc_port, |
| 2254 | 2270 | I40IW_MANAGE_APBVT_DEL); |
| 2255 | − i40iw_get_addr_info(cm_node, &nfo); | |
| 2256 | − if (cm_node->qhash_set) { | |
| 2257 | − i40iw_manage_qhash(cm_node->iwdev, | |
| 2258 | − &nfo, | |
| 2259 | − I40IW_QHASH_TYPE_TCP_ESTABLISHED, | |
| 2260 | − I40IW_QHASH_MANAGE_TYPE_DELETE, | |
| 2261 | − NULL, | |
| 2262 | − false); | |
| 2263 | − cm_node->qhash_set = 0; | |
| 2264 | − } | |
| 2271 | + cm_node->apbvt_set = 0; | |
| 2272 | + } | |
| 2273 | + i40iw_get_addr_info(cm_node, &nfo); | |
| 2274 | + if (cm_node->qhash_set) { | |
| 2275 | + i40iw_manage_qhash(cm_node->iwdev, | |
| 2276 | + &nfo, | |
| 2277 | + I40IW_QHASH_TYPE_TCP_ESTABLISHED, | |
| 2278 | + I40IW_QHASH_MANAGE_TYPE_DELETE, | |
| 2279 | + NULL, | |
| 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 | 3272 | tcp_info->snd_mss = cpu_to_le32(((u32)cm_node->tcp_cntxt.mss)); |
| 3256 | 3273 | if (cm_node->vlan_id < VLAN_TAG_PRESENT) { |
| 3257 | 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 | 3278 | if (cm_node->ipv4) { |
| 3261 | 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 | 3755 | struct sockaddr_in *raddr; |
| 3738 | 3756 | struct sockaddr_in6 *laddr6; |
| 3739 | 3757 | struct sockaddr_in6 *raddr6; |
| 3740 | − bool qhash_set = false; | |
| 3741 | − int apbvt_set = 0; | |
| 3742 | − int err = 0; | |
| 3743 | − enum i40iw_status_code status; | |
| 3758 | + int ret = 0; | |
| 3759 | + unsigned long flags; | |
| 3744 | 3760 | |
| 3745 | 3761 | ibqp = i40iw_get_qp(cm_id->device, conn_param->qpn); |
| 3746 | 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 | 3805 | cm_info.user_pri = rt_tos2priority(cm_id->tos); |
| 3790 | 3806 | i40iw_debug(&iwdev->sc_dev, I40IW_DEBUG_DCB, "%s TOS:[%d] UP:[%d]\n", |
| 3791 | 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 | 3808 | cm_id->add_ref(cm_id); |
| 3819 | 3809 | cm_node = i40iw_create_cm_node(&iwdev->cm_core, iwdev, |
| 3820 | 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 | 3812 | &cm_info); |
| 3823 | 3813 | |
| 3824 | 3814 | if (IS_ERR(cm_node)) { |
| 3825 | − err = PTR_ERR(cm_node); | |
| 3826 | − goto err_out; | |
| 3815 | + ret = PTR_ERR(cm_node); | |
| 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 | 3844 | i40iw_record_ird_ord(cm_node, (u16)conn_param->ird, (u16)conn_param->ord); |
| 3830 | 3845 | if (cm_node->send_rdma0_op == SEND_RDMA_READ_ZERO && |
| 3831 | 3846 | !cm_node->ord_size) |
| 3832 | 3847 | cm_node->ord_size = 1; |
| 3833 | 3848 | |
| 3834 | − cm_node->apbvt_set = apbvt_set; | |
| 3835 | − cm_node->qhash_set = qhash_set; | |
| 3836 | 3849 | iwqp->cm_node = cm_node; |
| 3837 | 3850 | cm_node->iwqp = iwqp; |
| 3838 | 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 | 3854 | if (cm_node->state != I40IW_CM_STATE_OFFLOADED) { |
| 3842 | 3855 | cm_node->state = I40IW_CM_STATE_SYN_SENT; |
| 3843 | − err = i40iw_send_syn(cm_node, 0); | |
| 3844 | − if (err) { | |
| 3845 | − i40iw_rem_ref_cm_node(cm_node); | |
| 3846 | − goto err_out; | |
| 3847 | − } | |
| 3856 | + ret = i40iw_send_syn(cm_node, 0); | |
| 3857 | + if (ret) | |
| 3858 | + goto err; | |
| 3848 | 3859 | } |
| 3849 | 3860 | |
| 3850 | 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 | 3864 | cm_node->rem_port, |
| 3854 | 3865 | cm_node, |
| 3855 | 3866 | cm_node->cm_id); |
| 3867 | + | |
| 3856 | 3868 | return 0; |
| 3857 | 3869 | |
| 3858 | −err_out: | |
| 3870 | +err: | |
| 3859 | 3871 | if (cm_info.ipv4) |
| 3860 | 3872 | i40iw_debug(&iwdev->sc_dev, |
| 3861 | 3873 | I40IW_DEBUG_CM, |
| @@ -3867,22 +3879,10 @@ err_out: · 5 unmodified lines | ||
| 3867 | 3879 | "Api - connect() FAILED: dest addr=%pI6", |
| 3868 | 3880 | cm_info.rem_addr); |
| 3869 | 3881 | |
| 3870 | − if (qhash_set) | |
| 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); | |
| 3882 | + i40iw_rem_ref_cm_node(cm_node); | |
| 3883 | 3883 | cm_id->rem_ref(cm_id); |
| 3884 | 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 | 71 | #define I40IW_HW_IRD_SETTING_32 32 |
| 72 | 72 | #define I40IW_HW_IRD_SETTING_64 64 |
| 73 | 73 | |
| 74 | +#define MAX_PORTS 65536 | |
| 75 | +#define I40IW_VLAN_PRIO_SHIFT 13 | |
| 76 | + | |
| 74 | 77 | enum ietf_mpa_flags { |
| 75 | 78 | IETF_MPA_FLAGS_MARKERS = 0x80, /* receive Markers */ |
| 76 | 79 | IETF_MPA_FLAGS_CRC = 0x40, /* receive Markers */ |
| @@ -411,6 +414,8 @@ struct i40iw_cm_core { · 334 unmodified lines | ||
| 411 | 414 | spinlock_t ht_lock; /* manage hash table */ |
| 412 | 415 | spinlock_t listen_list_lock; /* listen list */ |
| 413 | 416 | |
| 417 | + unsigned long active_side_ports[BITS_TO_LONGS(MAX_PORTS)]; | |
| 418 | + | |
| 414 | 419 | u64 stats_nodes_created; |
| 415 | 420 | u64 stats_nodes_destroyed; |
| 416 | 421 | u64 stats_listen_created; |
| @@ -99,8 +99,6 @@ static struct notifier_block i40iw_net_notifier = { · 98 unmodified lines | ||
| 99 | 99 | .notifier_call = i40iw_net_event |
| 100 | 100 | }; |
| 101 | 101 | |
| 102 | −static atomic_t i40iw_notifiers_registered; | |
| 103 | − | |
| 104 | 102 | /** |
| 105 | 103 | * i40iw_find_i40e_handler - find a handler given a client info |
| 106 | 104 | * @ldev: pointer to a client info |
| @@ -1376,11 +1374,20 @@ error: · 1269 unmodified lines | ||
| 1376 | 1374 | */ |
| 1377 | 1375 | static void i40iw_register_notifiers(void) |
| 1378 | 1376 | { |
| 1379 | − if (atomic_inc_return(&i40iw_notifiers_registered) == 1) { | |
| 1380 | − register_inetaddr_notifier(&i40iw_inetaddr_notifier); | |
| 1381 | − register_inet6addr_notifier(&i40iw_inetaddr6_notifier); | |
| 1382 | − register_netevent_notifier(&i40iw_net_notifier); | |
| 1383 | − } | |
| 1377 | + register_inetaddr_notifier(&i40iw_inetaddr_notifier); | |
| 1378 | + register_inet6addr_notifier(&i40iw_inetaddr6_notifier); | |
| 1379 | + register_netevent_notifier(&i40iw_net_notifier); | |
| 1380 | +} | |
| 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 | 1407 | u32 i; |
| 1401 | 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 | 1415 | iwdev->msix_count = ldev->msix_count; |
| 1404 | 1416 | |
| 1405 | 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 | 1474 | if (!iwdev->reset) |
| 1463 | 1475 | i40iw_del_macip_entry(iwdev, (u8)iwdev->mac_ip_table_idx); |
| 1464 | 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 | 1477 | /* fallthrough */ |
| 1472 | 1478 | case PBLE_CHUNK_MEM: |
| 1473 | 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 | 1557 | status = i40iw_save_msix_info(iwdev, ldev); |
| 1552 | 1558 | if (status) |
| 1553 | − goto exit; | |
| 1559 | + return status; | |
| 1554 | 1560 | iwdev->hw.dev_context = (void *)ldev->pcidev; |
| 1555 | 1561 | iwdev->hw.hw_addr = ldev->hw_addr; |
| 1556 | 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 | 1673 | break; |
| 1668 | 1674 | iwdev->init_state = PBLE_CHUNK_MEM; |
| 1669 | 1675 | iwdev->virtchnl_wq = alloc_ordered_workqueue("iwvch", WQ_MEM_RECLAIM); |
| 1670 | − i40iw_register_notifiers(); | |
| 1671 | − iwdev->init_state = INET_NOTIFIER; | |
| 1672 | 1676 | status = i40iw_add_mac_ip(iwdev); |
| 1673 | 1677 | if (status) |
| 1674 | 1678 | break; |
| @@ -2018,6 +2022,8 @@ static int __init i40iw_init_module(void) · 343 unmodified lines | ||
| 2018 | 2022 | i40iw_client.type = I40E_CLIENT_IWARP; |
| 2019 | 2023 | spin_lock_init(&i40iw_handler_lock); |
| 2020 | 2024 | ret = i40e_register_client(&i40iw_client); |
| 2025 | + i40iw_register_notifiers(); | |
| 2026 | + | |
| 2021 | 2027 | return ret; |
| 2022 | 2028 | } |
| 2023 | 2029 | |
| @@ -2029,6 +2035,7 @@ static int __init i40iw_init_module(void) · 5 unmodified lines | ||
| 2029 | 2035 | */ |
| 2030 | 2036 | static void __exit i40iw_exit_module(void) |
| 2031 | 2037 | { |
| 2038 | + i40iw_unregister_notifiers(); | |
| 2032 | 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 | 160 | return NOTIFY_DONE; |
| 161 | 161 | |
| 162 | 162 | iwdev = &hdl->device; |
| 163 | − if (iwdev->init_state < INET_NOTIFIER) | |
| 163 | + if (iwdev->init_state < IP_ADDR_REGISTERED || iwdev->closing) | |
| 164 | 164 | return NOTIFY_DONE; |
| 165 | 165 | |
| 166 | 166 | netdev = iwdev->ldev->netdev; |
| @@ -217,7 +217,7 @@ int i40iw_inet6addr_event(struct notifier_block *notifier, · 50 unmodified lines | ||
| 217 | 217 | return NOTIFY_DONE; |
| 218 | 218 | |
| 219 | 219 | iwdev = &hdl->device; |
| 220 | − if (iwdev->init_state < INET_NOTIFIER) | |
| 220 | + if (iwdev->init_state < IP_ADDR_REGISTERED || iwdev->closing) | |
| 221 | 221 | return NOTIFY_DONE; |
| 222 | 222 | |
| 223 | 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 | 266 | if (!iwhdl) |
| 267 | 267 | return NOTIFY_DONE; |
| 268 | 268 | iwdev = &iwhdl->device; |
| 269 | − if (iwdev->init_state < INET_NOTIFIER) | |
| 269 | + if (iwdev->init_state < IP_ADDR_REGISTERED || iwdev->closing) | |
| 270 | 270 | return NOTIFY_DONE; |
| 271 | 271 | p = (__be32 *)neigh->primary_key; |
| 272 | 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 | 1027 | iwqp->hw_tcp_state = I40IW_TCP_STATE_CLOSED; |
| 1028 | 1028 | iwqp->last_aeq = I40IW_AE_RESET_SENT; |
| 1029 | 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 | 1045 | return 0; |
| @@ -3837,11 +3837,13 @@ static int delay_drop_debugfs_init(struct mlx5_ib_dev *dev) · 3836 unmodified lines | ||
| 3837 | 3837 | if (!dbg) |
| 3838 | 3838 | return -ENOMEM; |
| 3839 | 3839 | |
| 3840 | + dev->delay_drop.dbg = dbg; | |
| 3841 | + | |
| 3840 | 3842 | dbg->dir_debugfs = |
| 3841 | 3843 | debugfs_create_dir("delay_drop", |
| 3842 | 3844 | dev->mdev->priv.dbg_root); |
| 3843 | 3845 | if (!dbg->dir_debugfs) |
| 3844 | − return -ENOMEM; | |
| 3846 | + goto out_debugfs; | |
| 3845 | 3847 | |
| 3846 | 3848 | dbg->events_cnt_debugfs = |
| 3847 | 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 | 3867 | if (!dbg->timeout_debugfs) |
| 3866 | 3868 | goto out_debugfs; |
| 3867 | 3869 | |
| 3868 | − dev->delay_drop.dbg = dbg; | |
| 3869 | − | |
| 3870 | 3870 | return 0; |
| 3871 | 3871 | |
| 3872 | 3872 | out_debugfs: |
| @@ -252,7 +252,10 @@ static int ocrdma_get_mbx_errno(u32 status) · 251 unmodified lines | ||
| 252 | 252 | case OCRDMA_MBX_ADDI_STATUS_INSUFFICIENT_RESOURCES: |
| 253 | 253 | err_num = -EAGAIN; |
| 254 | 254 | break; |
| 255 | + default: | |
| 256 | + err_num = -EFAULT; | |
| 255 | 257 | } |
| 258 | + break; | |
| 256 | 259 | default: |
| 257 | 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 | 416 | return (enum ib_wc_status)status; |
| 417 | 417 | } |
| 418 | 418 | |
| 419 | −static inline int pvrdma_wc_opcode_to_ib(int opcode) | |
| 420 | −{ | |
| 421 | − return opcode; | |
| 419 | +static inline int pvrdma_wc_opcode_to_ib(unsigned int opcode) | |
| 420 | +{ | |
| 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 | 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 | 823 | wc->status != IB_WC_WR_FLUSH_ERR) { |
| 824 | 824 | struct ipoib_neigh *neigh; |
| 825 | 825 | |
| 826 | − if (wc->status != IB_WC_RNR_RETRY_EXC_ERR) | |
| 827 | − ipoib_warn(priv, "failed cm send event (status=%d, wrid=%d vend_err %x)\n", | |
| 828 | − wc->status, wr_id, wc->vendor_err); | |
| 826 | + /* IB_WC[_RNR]_RETRY_EXC_ERR error is part of the life cycle, | |
| 827 | + * so don't make waves. | |
| 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 | 834 | else |
| 830 | − ipoib_dbg(priv, "failed cm send event (status=%d, wrid=%d vend_err %x)\n", | |
| 831 | − wc->status, wr_id, wc->vendor_err); | |
| 835 | + ipoib_warn(priv, | |
| 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 | 839 | spin_lock_irqsave(&priv->lock, flags); |
| 834 | 840 | neigh = tx->neigh; |