Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/1282822/?format=api
{ "id": 1282822, "url": "http://patchwork.ozlabs.org/api/patches/1282822/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/20200504164349.1523441-3-jeffrey.t.kirsher@intel.com/", "project": { "id": 46, "url": "http://patchwork.ozlabs.org/api/projects/46/?format=api", "name": "Intel Wired Ethernet development", "link_name": "intel-wired-lan", "list_id": "intel-wired-lan.osuosl.org", "list_email": "intel-wired-lan@osuosl.org", "web_url": "", "scm_url": "", "webscm_url": "", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20200504164349.1523441-3-jeffrey.t.kirsher@intel.com>", "list_archive_url": null, "date": "2020-05-04T16:43:43", "name": "[net-next,v3,3/9] ice: Complete RDMA peer registration", "commit_ref": null, "pull_url": null, "state": "changes-requested", "archived": false, "hash": "3aa82b40f8a6a0152a7d853f3e50e7960c748301", "submitter": { "id": 473, "url": "http://patchwork.ozlabs.org/api/people/473/?format=api", "name": "Kirsher, Jeffrey T", "email": "jeffrey.t.kirsher@intel.com" }, "delegate": { "id": 68, "url": "http://patchwork.ozlabs.org/api/users/68/?format=api", "username": "jtkirshe", "first_name": "Jeff", "last_name": "Kirsher", "email": "jeffrey.t.kirsher@intel.com" }, "mbox": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/20200504164349.1523441-3-jeffrey.t.kirsher@intel.com/mbox/", "series": [ { "id": 174549, "url": "http://patchwork.ozlabs.org/api/series/174549/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/list/?series=174549", "date": "2020-05-04T16:43:44", "name": "[net-next,v3,1/9] Implementation of Virtual Bus", "version": 3, "mbox": "http://patchwork.ozlabs.org/series/174549/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/1282822/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/1282822/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<intel-wired-lan-bounces@osuosl.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "intel-wired-lan@lists.osuosl.org" ], "Delivered-To": [ "patchwork-incoming@bilbo.ozlabs.org", "intel-wired-lan@lists.osuosl.org" ], "Authentication-Results": [ "ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=osuosl.org\n (client-ip=140.211.166.138; helo=whitealder.osuosl.org;\n envelope-from=intel-wired-lan-bounces@osuosl.org; receiver=<UNKNOWN>)", "ozlabs.org;\n dmarc=fail (p=none dis=none) header.from=intel.com" ], "Received": [ "from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 49G7wd4rwDz9sSm\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 5 May 2020 02:44:01 +1000 (AEST)", "from localhost (localhost [127.0.0.1])\n\tby whitealder.osuosl.org (Postfix) with ESMTP id B17D38663C;\n\tMon, 4 May 2020 16:43:59 +0000 (UTC)", "from whitealder.osuosl.org ([127.0.0.1])\n\tby localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n\twith ESMTP id qUZ6bQghUdaH; Mon, 4 May 2020 16:43:55 +0000 (UTC)", "from ash.osuosl.org (ash.osuosl.org [140.211.166.34])\n\tby whitealder.osuosl.org (Postfix) with ESMTP id 25AA885F9B;\n\tMon, 4 May 2020 16:43:55 +0000 (UTC)", "from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133])\n by ash.osuosl.org (Postfix) with ESMTP id 17B191BF857\n for <intel-wired-lan@lists.osuosl.org>; Mon, 4 May 2020 16:43:54 +0000 (UTC)", "from localhost (localhost [127.0.0.1])\n by hemlock.osuosl.org (Postfix) with ESMTP id 13C5688378\n for <intel-wired-lan@lists.osuosl.org>; Mon, 4 May 2020 16:43:54 +0000 (UTC)", "from hemlock.osuosl.org ([127.0.0.1])\n by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n with ESMTP id aaJwSRC1yEx7 for <intel-wired-lan@lists.osuosl.org>;\n Mon, 4 May 2020 16:43:52 +0000 (UTC)", "from mga03.intel.com (mga03.intel.com [134.134.136.65])\n by hemlock.osuosl.org (Postfix) with ESMTPS id 967F7883F5\n for <intel-wired-lan@lists.osuosl.org>; Mon, 4 May 2020 16:43:52 +0000 (UTC)", "from fmsmga006.fm.intel.com ([10.253.24.20])\n by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 04 May 2020 09:43:51 -0700", "from jtkirshe-desk1.jf.intel.com ([134.134.177.86])\n by fmsmga006.fm.intel.com with ESMTP; 04 May 2020 09:43:51 -0700" ], "X-Virus-Scanned": [ "amavisd-new at osuosl.org", "amavisd-new at osuosl.org" ], "X-Greylist": "domain auto-whitelisted by SQLgrey-1.7.6", "IronPort-SDR": [ "\n OlfYoZpquHzjdQkRkS43oISjYClKSqJPPs3Deqbkly+97qOvAxJKTDarYX4fcnj9pTtdYd3RIx\n BXmZfHgbZW5g==", "\n 3MTovFuII5CbQpGnvxfifDgh6ELiUnED19/oo5VK3bVKS6YrTxn4dT6Kmz5iF5jPJgA6Gc0LB6\n ZnLfWcMXV6OQ==" ], "X-Amp-Result": "SKIPPED(no attachment in message)", "X-Amp-File-Uploaded": "False", "X-ExtLoop1": "1", "X-IronPort-AV": "E=Sophos;i=\"5.73,352,1583222400\"; d=\"scan'208\";a=\"461073915\"", "From": "Jeff Kirsher <jeffrey.t.kirsher@intel.com>", "To": "intel-wired-lan@lists.osuosl.org", "Date": "Mon, 4 May 2020 09:43:43 -0700", "Message-Id": "<20200504164349.1523441-3-jeffrey.t.kirsher@intel.com>", "X-Mailer": "git-send-email 2.26.2", "In-Reply-To": "<20200504164349.1523441-1-jeffrey.t.kirsher@intel.com>", "References": "<20200504164349.1523441-1-jeffrey.t.kirsher@intel.com>", "MIME-Version": "1.0", "Subject": "[Intel-wired-lan] [net-next v3 3/9] ice: Complete RDMA peer\n registration", "X-BeenThere": "intel-wired-lan@osuosl.org", "X-Mailman-Version": "2.1.29", "Precedence": "list", "List-Id": "Intel Wired Ethernet Linux Kernel Driver Development\n <intel-wired-lan.osuosl.org>", "List-Unsubscribe": "<https://lists.osuosl.org/mailman/options/intel-wired-lan>,\n <mailto:intel-wired-lan-request@osuosl.org?subject=unsubscribe>", "List-Archive": "<http://lists.osuosl.org/pipermail/intel-wired-lan/>", "List-Post": "<mailto:intel-wired-lan@osuosl.org>", "List-Help": "<mailto:intel-wired-lan-request@osuosl.org?subject=help>", "List-Subscribe": "<https://lists.osuosl.org/mailman/listinfo/intel-wired-lan>,\n <mailto:intel-wired-lan-request@osuosl.org?subject=subscribe>", "Content-Type": "text/plain; charset=\"us-ascii\"", "Content-Transfer-Encoding": "7bit", "Errors-To": "intel-wired-lan-bounces@osuosl.org", "Sender": "\"Intel-wired-lan\" <intel-wired-lan-bounces@osuosl.org>" }, "content": "From: Dave Ertman <david.m.ertman@intel.com>\n\nEnsure that the peer supports the minimal set of operations required\nfor operation and, if so, open the connection to the peer.\n\nSigned-off-by: Dave Ertman <david.m.ertman@intel.com>\nSigned-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>\nTested-by: Andrew Bowers <andrewx.bowers@intel.com>\nSigned-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>\n---\n drivers/net/ethernet/intel/ice/ice_idc.c | 288 ++++++++++++++++++\n drivers/net/ethernet/intel/ice/ice_idc_int.h | 36 +++\n drivers/net/ethernet/intel/ice/ice_lib.c | 33 ++\n drivers/net/ethernet/intel/ice/ice_lib.h | 2 +\n drivers/net/ethernet/intel/ice/ice_main.c | 18 +-\n drivers/net/ethernet/intel/ice/ice_switch.c | 23 ++\n drivers/net/ethernet/intel/ice/ice_switch.h | 2 +\n .../net/ethernet/intel/ice/ice_virtchnl_pf.c | 25 --\n 8 files changed, 401 insertions(+), 26 deletions(-)", "diff": "diff --git a/drivers/net/ethernet/intel/ice/ice_idc.c b/drivers/net/ethernet/intel/ice/ice_idc.c\nindex 68d6b524d6d4..499c1b77dfc9 100644\n--- a/drivers/net/ethernet/intel/ice/ice_idc.c\n+++ b/drivers/net/ethernet/intel/ice/ice_idc.c\n@@ -146,6 +146,78 @@ ice_peer_state_change(struct ice_peer_dev_int *peer_dev, long new_state,\n \t\tmutex_unlock(&peer_dev->peer_dev_state_mutex);\n }\n \n+/**\n+ * ice_peer_close - close a peer device\n+ * @peer_dev_int: device to close\n+ * @data: pointer to opaque data\n+ *\n+ * This function will also set the state bit for the peer to CLOSED. This\n+ * function is meant to be called from a ice_for_each_peer().\n+ */\n+int ice_peer_close(struct ice_peer_dev_int *peer_dev_int, void *data)\n+{\n+\tenum iidc_close_reason reason = *(enum iidc_close_reason *)(data);\n+\tstruct iidc_peer_dev *peer_dev;\n+\tstruct ice_pf *pf;\n+\tint i;\n+\n+\tpeer_dev = &peer_dev_int->peer_dev;\n+\t/* return 0 so ice_for_each_peer will continue closing other peers */\n+\tif (!ice_validate_peer_dev(peer_dev))\n+\t\treturn 0;\n+\tpf = pci_get_drvdata(peer_dev->pdev);\n+\n+\tif (test_bit(__ICE_DOWN, pf->state) ||\n+\t test_bit(__ICE_SUSPENDED, pf->state) ||\n+\t test_bit(__ICE_NEEDS_RESTART, pf->state))\n+\t\treturn 0;\n+\n+\tmutex_lock(&peer_dev_int->peer_dev_state_mutex);\n+\n+\t/* no peer driver, already closed, closing or opening nothing to do */\n+\tif (test_bit(ICE_PEER_DEV_STATE_CLOSED, peer_dev_int->state) ||\n+\t test_bit(ICE_PEER_DEV_STATE_CLOSING, peer_dev_int->state) ||\n+\t test_bit(ICE_PEER_DEV_STATE_OPENING, peer_dev_int->state) ||\n+\t test_bit(ICE_PEER_DEV_STATE_REMOVED, peer_dev_int->state))\n+\t\tgoto peer_close_out;\n+\n+\t/* Set the peer state to CLOSING */\n+\tice_peer_state_change(peer_dev_int, ICE_PEER_DEV_STATE_CLOSING, true);\n+\n+\tfor (i = 0; i < IIDC_EVENT_NBITS; i++)\n+\t\tbitmap_zero(peer_dev_int->current_events[i].type,\n+\t\t\t IIDC_EVENT_NBITS);\n+\n+\tif (peer_dev->peer_ops && peer_dev->peer_ops->close)\n+\t\tpeer_dev->peer_ops->close(peer_dev, reason);\n+\n+\t/* Set the peer state to CLOSED */\n+\tice_peer_state_change(peer_dev_int, ICE_PEER_DEV_STATE_CLOSED, true);\n+\n+peer_close_out:\n+\tmutex_unlock(&peer_dev_int->peer_dev_state_mutex);\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * ice_peer_update_vsi - update the pf_vsi info in peer_dev struct\n+ * @peer_dev_int: pointer to peer dev internal struct\n+ * @data: opaque pointer - VSI to be updated\n+ */\n+int ice_peer_update_vsi(struct ice_peer_dev_int *peer_dev_int, void *data)\n+{\n+\tstruct ice_vsi *vsi = (struct ice_vsi *)data;\n+\tstruct iidc_peer_dev *peer_dev;\n+\n+\tpeer_dev = &peer_dev_int->peer_dev;\n+\tif (!peer_dev)\n+\t\treturn 0;\n+\n+\tpeer_dev->pf_vsi_num = vsi->vsi_num;\n+\treturn 0;\n+}\n+\n /**\n * ice_for_each_peer - iterate across and call function for each peer dev\n * @pf: pointer to private board struct\n@@ -176,6 +248,89 @@ ice_for_each_peer(struct ice_pf *pf, void *data,\n \treturn 0;\n }\n \n+/**\n+ * ice_finish_init_peer_device - complete peer device initialization\n+ * @peer_dev_int: ptr to peer device internal struct\n+ * @data: ptr to opaque data\n+ *\n+ * This function completes remaining initialization of peer_devices\n+ */\n+int\n+ice_finish_init_peer_device(struct ice_peer_dev_int *peer_dev_int,\n+\t\t\t void __always_unused *data)\n+{\n+\tstruct iidc_peer_dev *peer_dev;\n+\tstruct iidc_peer_drv *peer_drv;\n+\tstruct device *dev;\n+\tstruct ice_pf *pf;\n+\tint ret = 0;\n+\n+\tpeer_dev = &peer_dev_int->peer_dev;\n+\t/* peer_dev will not always be populated at the time of this check */\n+\tif (!ice_validate_peer_dev(peer_dev))\n+\t\treturn ret;\n+\n+\tpeer_drv = peer_dev->peer_drv;\n+\tpf = pci_get_drvdata(peer_dev->pdev);\n+\tdev = ice_pf_to_dev(pf);\n+\t/* There will be several assessments of the peer_dev's state in this\n+\t * chunk of logic. We need to hold the peer_dev_int's state mutex\n+\t * for the entire part so that the flow progresses without another\n+\t * context changing things mid-flow\n+\t */\n+\tmutex_lock(&peer_dev_int->peer_dev_state_mutex);\n+\n+\tif (!peer_dev->peer_ops) {\n+\t\tdev_err(dev, \"peer_ops not defined on peer dev\\n\");\n+\t\tgoto init_unlock;\n+\t}\n+\n+\tif (!peer_dev->peer_ops->open) {\n+\t\tdev_err(dev, \"peer_ops:open not defined on peer dev\\n\");\n+\t\tgoto init_unlock;\n+\t}\n+\n+\tif (!peer_dev->peer_ops->close) {\n+\t\tdev_err(dev, \"peer_ops:close not defined on peer dev\\n\");\n+\t\tgoto init_unlock;\n+\t}\n+\n+\t/* Peer driver expected to set driver_id during registration */\n+\tif (!peer_drv->driver_id) {\n+\t\tdev_err(dev, \"Peer driver did not set driver_id\\n\");\n+\t\tgoto init_unlock;\n+\t}\n+\n+\tif ((test_bit(ICE_PEER_DEV_STATE_CLOSED, peer_dev_int->state) ||\n+\t test_bit(ICE_PEER_DEV_STATE_PROBED, peer_dev_int->state)) &&\n+\t ice_pf_state_is_nominal(pf)) {\n+\t\t/* If the RTNL is locked, we defer opening the peer\n+\t\t * until the next time this function is called by the\n+\t\t * service task.\n+\t\t */\n+\t\tif (rtnl_is_locked())\n+\t\t\tgoto init_unlock;\n+\t\tice_peer_state_change(peer_dev_int, ICE_PEER_DEV_STATE_OPENING,\n+\t\t\t\t true);\n+\t\tret = peer_dev->peer_ops->open(peer_dev);\n+\t\tif (ret) {\n+\t\t\tdev_err(dev, \"Peer %d failed to open\\n\",\n+\t\t\t\tpeer_dev->peer_dev_id);\n+\t\t\tice_peer_state_change(peer_dev_int,\n+\t\t\t\t\t ICE_PEER_DEV_STATE_PROBED, true);\n+\t\t\tgoto init_unlock;\n+\t\t}\n+\n+\t\tice_peer_state_change(peer_dev_int, ICE_PEER_DEV_STATE_OPENED,\n+\t\t\t\t true);\n+\t}\n+\n+init_unlock:\n+\tmutex_unlock(&peer_dev_int->peer_dev_state_mutex);\n+\n+\treturn ret;\n+}\n+\n /**\n * ice_unreg_peer_device - unregister specified device\n * @peer_dev_int: ptr to peer device internal\n@@ -200,6 +355,9 @@ ice_unreg_peer_device(struct ice_peer_dev_int *peer_dev_int,\n \tif (peer_dev_int->ice_peer_wq) {\n \t\tif (peer_dev_int->peer_prep_task.func)\n \t\t\tcancel_work_sync(&peer_dev_int->peer_prep_task);\n+\n+\t\tif (peer_dev_int->peer_close_task.func)\n+\t\t\tcancel_work_sync(&peer_dev_int->peer_close_task);\n \t\tdestroy_workqueue(peer_dev_int->ice_peer_wq);\n \t}\n \n@@ -230,6 +388,134 @@ ice_unroll_peer(struct ice_peer_dev_int *peer_dev_int,\n \treturn 0;\n }\n \n+/**\n+ * ice_peer_unregister - request to unregister peer\n+ * @peer_dev: peer device\n+ *\n+ * This function triggers close/remove on peer_dev allowing peer\n+ * to unregister.\n+ */\n+static int ice_peer_unregister(struct iidc_peer_dev *peer_dev)\n+{\n+\tenum iidc_close_reason reason = IIDC_REASON_PEER_DEV_UNINIT;\n+\tstruct ice_peer_dev_int *peer_dev_int;\n+\tstruct ice_pf *pf;\n+\tint ret;\n+\n+\tif (!ice_validate_peer_dev(peer_dev))\n+\t\treturn -EINVAL;\n+\n+\tpf = pci_get_drvdata(peer_dev->pdev);\n+\tif (ice_is_reset_in_progress(pf->state))\n+\t\treturn -EBUSY;\n+\n+\tpeer_dev_int = peer_to_ice_dev_int(peer_dev);\n+\n+\tret = ice_peer_close(peer_dev_int, &reason);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tpeer_dev->peer_ops = NULL;\n+\n+\tice_peer_state_change(peer_dev_int, ICE_PEER_DEV_STATE_REMOVED, false);\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * ice_peer_register - Called by peer to open communication with LAN\n+ * @peer_dev: ptr to peer device\n+ *\n+ * registering peer is expected to populate the ice_peerdrv->name field\n+ * before calling this function.\n+ */\n+static int ice_peer_register(struct iidc_peer_dev *peer_dev)\n+{\n+\tstruct ice_peer_drv_int *peer_drv_int;\n+\tstruct ice_peer_dev_int *peer_dev_int;\n+\tstruct iidc_peer_drv *peer_drv;\n+\n+\tif (!peer_dev) {\n+\t\tpr_err(\"Failed to reg peer dev: peer_dev ptr NULL\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (!peer_dev->pdev) {\n+\t\tpr_err(\"Failed to reg peer dev: peer dev pdev NULL\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (!peer_dev->peer_ops || !peer_dev->ops) {\n+\t\tpr_err(\"Failed to reg peer dev: peer dev peer_ops/ops NULL\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tpeer_drv = peer_dev->peer_drv;\n+\tif (!peer_drv) {\n+\t\tpr_err(\"Failed to reg peer dev: peer drv NULL\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tpeer_dev_int = peer_to_ice_dev_int(peer_dev);\n+\tpeer_drv_int = peer_dev_int->peer_drv_int;\n+\tif (!peer_drv_int) {\n+\t\tpr_err(\"Failed to match peer_drv_int to peer_dev\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tpeer_drv_int->peer_drv = peer_drv;\n+\n+\tice_peer_state_change(peer_dev_int, ICE_PEER_DEV_STATE_PROBED, false);\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * ice_peer_update_vsi_filter - update main VSI filters for RDMA\n+ * @peer_dev: pointer to RDMA peer device\n+ * @filter: selection of filters to enable or disable\n+ * @enable: bool whether to enable or disable filters\n+ */\n+static int\n+ice_peer_update_vsi_filter(struct iidc_peer_dev *peer_dev,\n+\t\t\t enum iidc_rdma_filter __always_unused filter,\n+\t\t\t bool enable)\n+{\n+\tstruct ice_vsi *vsi;\n+\tstruct ice_pf *pf;\n+\tint ret;\n+\n+\tif (!ice_validate_peer_dev(peer_dev))\n+\t\treturn -EINVAL;\n+\n+\tpf = pci_get_drvdata(peer_dev->pdev);\n+\n+\tvsi = ice_get_main_vsi(pf);\n+\tif (!vsi)\n+\t\treturn -EINVAL;\n+\n+\tret = ice_cfg_iwarp_fltr(&pf->hw, vsi->idx, enable);\n+\n+\tif (ret) {\n+\t\tdev_err(ice_pf_to_dev(pf), \"Failed to %sable iWARP filtering\\n\",\n+\t\t\tenable ? \"en\" : \"dis\");\n+\t} else {\n+\t\tif (enable)\n+\t\t\tvsi->info.q_opt_flags |= ICE_AQ_VSI_Q_OPT_PE_FLTR_EN;\n+\t\telse\n+\t\t\tvsi->info.q_opt_flags &= ~ICE_AQ_VSI_Q_OPT_PE_FLTR_EN;\n+\t}\n+\n+\treturn ret;\n+}\n+\n+/* Initialize the ice_ops struct, which is used in 'ice_init_peer_devices' */\n+static const struct iidc_ops ops = {\n+\t.peer_register\t\t\t= ice_peer_register,\n+\t.peer_unregister\t\t= ice_peer_unregister,\n+\t.update_vsi_filter\t\t= ice_peer_update_vsi_filter,\n+};\n+\n /**\n * ice_reserve_peer_qvector - Reserve vector resources for peer drivers\n * @pf: board private structure to initialize\n@@ -364,6 +650,8 @@ int ice_init_peer_devices(struct ice_pf *pf)\n \n \t\t/* for DCB, override the qos_info defaults. */\n \t\tice_setup_dcb_qos_info(pf, qos_info);\n+\t\t/* Initialize ice_ops */\n+\t\tpeer_dev->ops = &ops;\n \n \t\t/* make sure peer specific resources such as msix_count and\n \t\t * msix_entries are initialized\ndiff --git a/drivers/net/ethernet/intel/ice/ice_idc_int.h b/drivers/net/ethernet/intel/ice/ice_idc_int.h\nindex daac19c45490..d22e6f5bb50e 100644\n--- a/drivers/net/ethernet/intel/ice/ice_idc_int.h\n+++ b/drivers/net/ethernet/intel/ice/ice_idc_int.h\n@@ -62,6 +62,42 @@ struct ice_peer_dev_int {\n \tenum iidc_close_reason rst_type;\n };\n \n+int ice_peer_update_vsi(struct ice_peer_dev_int *peer_dev_int, void *data);\n int ice_unroll_peer(struct ice_peer_dev_int *peer_dev_int, void *data);\n int ice_unreg_peer_device(struct ice_peer_dev_int *peer_dev_int, void *data);\n+int ice_peer_close(struct ice_peer_dev_int *peer_dev_int, void *data);\n+int\n+ice_finish_init_peer_device(struct ice_peer_dev_int *peer_dev_int, void *data);\n+\n+static inline struct\n+ice_peer_dev_int *peer_to_ice_dev_int(struct iidc_peer_dev *peer_dev)\n+{\n+\treturn container_of(peer_dev, struct ice_peer_dev_int, peer_dev);\n+}\n+\n+static inline bool ice_validate_peer_dev(struct iidc_peer_dev *peer_dev)\n+{\n+\tstruct ice_peer_dev_int *peer_dev_int;\n+\tstruct ice_pf *pf;\n+\n+\tif (!peer_dev || !peer_dev->pdev)\n+\t\treturn false;\n+\n+\tif (!peer_dev->peer_ops)\n+\t\treturn false;\n+\n+\tpf = pci_get_drvdata(peer_dev->pdev);\n+\tif (!pf)\n+\t\treturn false;\n+\n+\tpeer_dev_int = peer_to_ice_dev_int(peer_dev);\n+\tif (!peer_dev_int)\n+\t\treturn false;\n+\n+\tif (test_bit(ICE_PEER_DEV_STATE_REMOVED, peer_dev_int->state) ||\n+\t test_bit(ICE_PEER_DEV_STATE_INIT, peer_dev_int->state))\n+\t\treturn false;\n+\n+\treturn true;\n+}\n #endif /* !_ICE_IDC_INT_H_ */\ndiff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c\nindex 205ac5900551..5043d5ed1b2a 100644\n--- a/drivers/net/ethernet/intel/ice/ice_lib.c\n+++ b/drivers/net/ethernet/intel/ice/ice_lib.c\n@@ -1379,6 +1379,30 @@ ice_add_mac_to_list(struct ice_vsi *vsi, struct list_head *add_list,\n \treturn 0;\n }\n \n+/**\n+ * ice_pf_state_is_nominal - checks the PF for nominal state\n+ * @pf: pointer to PF to check\n+ *\n+ * Check the PF's state for a collection of bits that would indicate\n+ * the PF is in a state that would inhibit normal operation for\n+ * driver functionality.\n+ *\n+ * Returns true if PF is in a nominal state, false otherwise\n+ */\n+bool ice_pf_state_is_nominal(struct ice_pf *pf)\n+{\n+\tDECLARE_BITMAP(check_bits, __ICE_STATE_NBITS) = { 0 };\n+\n+\tif (!pf)\n+\t\treturn false;\n+\n+\tbitmap_set(check_bits, 0, __ICE_STATE_NOMINAL_CHECK_BITS);\n+\tif (bitmap_intersects(pf->state, check_bits, __ICE_STATE_NBITS))\n+\t\treturn false;\n+\n+\treturn true;\n+}\n+\n /**\n * ice_update_eth_stats - Update VSI-specific ethernet statistics counters\n * @vsi: the VSI to be updated\n@@ -2390,6 +2414,15 @@ void ice_vsi_free_rx_rings(struct ice_vsi *vsi)\n */\n void ice_vsi_close(struct ice_vsi *vsi)\n {\n+\tenum iidc_close_reason reason = IIDC_REASON_INTERFACE_DOWN;\n+\n+\tif (!ice_is_safe_mode(vsi->back) && vsi->type == ICE_VSI_PF) {\n+\t\tint ret = ice_for_each_peer(vsi->back, &reason, ice_peer_close);\n+\n+\t\tif (ret)\n+\t\t\tdev_dbg(ice_pf_to_dev(vsi->back), \"Peer device did not implement close function\\n\");\n+\t}\n+\n \tif (!test_and_set_bit(__ICE_DOWN, vsi->state))\n \t\tice_down(vsi);\n \ndiff --git a/drivers/net/ethernet/intel/ice/ice_lib.h b/drivers/net/ethernet/intel/ice/ice_lib.h\nindex db07cc065b10..f77ddd6883c3 100644\n--- a/drivers/net/ethernet/intel/ice/ice_lib.h\n+++ b/drivers/net/ethernet/intel/ice/ice_lib.h\n@@ -14,6 +14,8 @@ ice_add_mac_to_list(struct ice_vsi *vsi, struct list_head *add_list,\n \n void ice_free_fltr_list(struct device *dev, struct list_head *h);\n \n+bool ice_pf_state_is_nominal(struct ice_pf *pf);\n+\n void ice_update_eth_stats(struct ice_vsi *vsi);\n \n int ice_vsi_cfg_rxqs(struct ice_vsi *vsi);\ndiff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c\nindex 033e463bcdf1..ac0c6d5b01e4 100644\n--- a/drivers/net/ethernet/intel/ice/ice_main.c\n+++ b/drivers/net/ethernet/intel/ice/ice_main.c\n@@ -1492,6 +1492,9 @@ static void ice_service_task(struct work_struct *work)\n \t\treturn;\n \t}\n \n+\t/* Invoke remaining initialization of peer devices */\n+\tice_for_each_peer(pf, NULL, ice_finish_init_peer_device);\n+\n \tice_process_vflr_event(pf);\n \tice_clean_mailboxq_subtask(pf);\n \n@@ -3451,6 +3454,7 @@ ice_probe(struct pci_dev *pdev, const struct pci_device_id __always_unused *ent)\n static void ice_remove(struct pci_dev *pdev)\n {\n \tstruct ice_pf *pf = pci_get_drvdata(pdev);\n+\tenum iidc_close_reason reason;\n \tint i;\n \n \tif (!pf)\n@@ -3467,8 +3471,12 @@ static void ice_remove(struct pci_dev *pdev)\n \t\tice_free_vfs(pf);\n \t}\n \n-\tset_bit(__ICE_DOWN, pf->state);\n \tice_service_task_stop(pf);\n+\tif (ice_is_peer_ena(pf)) {\n+\t\treason = IIDC_REASON_INTERFACE_DOWN;\n+\t\tice_for_each_peer(pf, &reason, ice_peer_close);\n+\t}\n+\tset_bit(__ICE_DOWN, pf->state);\n \n \tice_devlink_destroy_port(pf);\n \tice_vsi_release_all(pf);\n@@ -4785,7 +4793,15 @@ static void ice_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)\n \t\tdev_err(dev, \"PF VSI rebuild failed: %d\\n\", err);\n \t\tgoto err_vsi_rebuild;\n \t}\n+\tif (ice_is_peer_ena(pf)) {\n+\t\tstruct ice_vsi *vsi = ice_get_main_vsi(pf);\n \n+\t\tif (!vsi) {\n+\t\t\tdev_err(dev, \"No PF_VSI to update peer\\n\");\n+\t\t\tgoto err_vsi_rebuild;\n+\t\t}\n+\t\tice_for_each_peer(pf, vsi, ice_peer_update_vsi);\n+\t}\n \tif (test_bit(ICE_FLAG_SRIOV_ENA, pf->flags)) {\n \t\terr = ice_vsi_rebuild_by_type(pf, ICE_VSI_VF);\n \t\tif (err) {\ndiff --git a/drivers/net/ethernet/intel/ice/ice_switch.c b/drivers/net/ethernet/intel/ice/ice_switch.c\nindex 51825a203e35..cf8e1553599a 100644\n--- a/drivers/net/ethernet/intel/ice/ice_switch.c\n+++ b/drivers/net/ethernet/intel/ice/ice_switch.c\n@@ -430,6 +430,29 @@ ice_update_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,\n \treturn ice_aq_update_vsi(hw, vsi_ctx, cd);\n }\n \n+/**\n+ * ice_cfg_iwarp_fltr - enable/disable iWARP filtering on VSI\n+ * @hw: pointer to HW struct\n+ * @vsi_handle: VSI SW index\n+ * @enable: boolean for enable/disable\n+ */\n+enum ice_status\n+ice_cfg_iwarp_fltr(struct ice_hw *hw, u16 vsi_handle, bool enable)\n+{\n+\tstruct ice_vsi_ctx *ctx;\n+\n+\tctx = ice_get_vsi_ctx(hw, vsi_handle);\n+\tif (!ctx)\n+\t\treturn ICE_ERR_DOES_NOT_EXIST;\n+\n+\tif (enable)\n+\t\tctx->info.q_opt_flags |= ICE_AQ_VSI_Q_OPT_PE_FLTR_EN;\n+\telse\n+\t\tctx->info.q_opt_flags &= ~ICE_AQ_VSI_Q_OPT_PE_FLTR_EN;\n+\n+\treturn ice_update_vsi(hw, vsi_handle, ctx, NULL);\n+}\n+\n /**\n * ice_aq_alloc_free_vsi_list\n * @hw: pointer to the HW struct\ndiff --git a/drivers/net/ethernet/intel/ice/ice_switch.h b/drivers/net/ethernet/intel/ice/ice_switch.h\nindex fa14b9545dab..96010d3d96fd 100644\n--- a/drivers/net/ethernet/intel/ice/ice_switch.h\n+++ b/drivers/net/ethernet/intel/ice/ice_switch.h\n@@ -220,6 +220,8 @@ void ice_remove_vsi_fltr(struct ice_hw *hw, u16 vsi_handle);\n enum ice_status\n ice_add_vlan(struct ice_hw *hw, struct list_head *m_list);\n enum ice_status ice_remove_vlan(struct ice_hw *hw, struct list_head *v_list);\n+enum ice_status\n+ice_cfg_iwarp_fltr(struct ice_hw *hw, u16 vsi_handle, bool enable);\n \n /* Promisc/defport setup for VSIs */\n enum ice_status\ndiff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c b/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c\nindex 15191a325918..07f3d4b456c7 100644\n--- a/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c\n+++ b/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c\n@@ -1375,31 +1375,6 @@ static int ice_alloc_vfs(struct ice_pf *pf, u16 num_alloc_vfs)\n \treturn ret;\n }\n \n-/**\n- * ice_pf_state_is_nominal - checks the PF for nominal state\n- * @pf: pointer to PF to check\n- *\n- * Check the PF's state for a collection of bits that would indicate\n- * the PF is in a state that would inhibit normal operation for\n- * driver functionality.\n- *\n- * Returns true if PF is in a nominal state.\n- * Returns false otherwise\n- */\n-static bool ice_pf_state_is_nominal(struct ice_pf *pf)\n-{\n-\tDECLARE_BITMAP(check_bits, __ICE_STATE_NBITS) = { 0 };\n-\n-\tif (!pf)\n-\t\treturn false;\n-\n-\tbitmap_set(check_bits, 0, __ICE_STATE_NOMINAL_CHECK_BITS);\n-\tif (bitmap_intersects(pf->state, check_bits, __ICE_STATE_NBITS))\n-\t\treturn false;\n-\n-\treturn true;\n-}\n-\n /**\n * ice_pci_sriov_ena - Enable or change number of VFs\n * @pf: pointer to the PF structure\n", "prefixes": [ "net-next", "v3", "3/9" ] }