Linux Audio

Check our new training course

Loading...
  1// SPDX-License-Identifier: GPL-2.0+
  2/* Copyright (c) 2021 Hisilicon Limited. */
  3
  4#include <net/devlink.h>
  5
  6#include "hclgevf_devlink.h"
  7
  8static int hclgevf_devlink_info_get(struct devlink *devlink,
  9				    struct devlink_info_req *req,
 10				    struct netlink_ext_ack *extack)
 11{
 12#define	HCLGEVF_DEVLINK_FW_STRING_LEN	32
 13	struct hclgevf_devlink_priv *priv = devlink_priv(devlink);
 14	char version_str[HCLGEVF_DEVLINK_FW_STRING_LEN];
 15	struct hclgevf_dev *hdev = priv->hdev;
 16
 17	snprintf(version_str, sizeof(version_str), "%lu.%lu.%lu.%lu",
 18		 hnae3_get_field(hdev->fw_version, HNAE3_FW_VERSION_BYTE3_MASK,
 19				 HNAE3_FW_VERSION_BYTE3_SHIFT),
 20		 hnae3_get_field(hdev->fw_version, HNAE3_FW_VERSION_BYTE2_MASK,
 21				 HNAE3_FW_VERSION_BYTE2_SHIFT),
 22		 hnae3_get_field(hdev->fw_version, HNAE3_FW_VERSION_BYTE1_MASK,
 23				 HNAE3_FW_VERSION_BYTE1_SHIFT),
 24		 hnae3_get_field(hdev->fw_version, HNAE3_FW_VERSION_BYTE0_MASK,
 25				 HNAE3_FW_VERSION_BYTE0_SHIFT));
 26
 27	return devlink_info_version_running_put(req,
 28						DEVLINK_INFO_VERSION_GENERIC_FW,
 29						version_str);
 30}
 31
 32static int hclgevf_devlink_reload_down(struct devlink *devlink,
 33				       bool netns_change,
 34				       enum devlink_reload_action action,
 35				       enum devlink_reload_limit limit,
 36				       struct netlink_ext_ack *extack)
 37{
 38	struct hclgevf_devlink_priv *priv = devlink_priv(devlink);
 39	struct hclgevf_dev *hdev = priv->hdev;
 40	struct hnae3_handle *h = &hdev->nic;
 41	struct pci_dev *pdev = hdev->pdev;
 42	int ret;
 43
 44	if (test_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state)) {
 45		dev_err(&pdev->dev, "reset is handling\n");
 46		return -EBUSY;
 47	}
 48
 49	switch (action) {
 50	case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
 51		rtnl_lock();
 52		ret = hdev->nic_client->ops->reset_notify(h, HNAE3_DOWN_CLIENT);
 53		if (ret) {
 54			rtnl_unlock();
 55			return ret;
 56		}
 57
 58		ret = hdev->nic_client->ops->reset_notify(h,
 59							  HNAE3_UNINIT_CLIENT);
 60		rtnl_unlock();
 61		return ret;
 62	default:
 63		return -EOPNOTSUPP;
 64	}
 65}
 66
 67static int hclgevf_devlink_reload_up(struct devlink *devlink,
 68				     enum devlink_reload_action action,
 69				     enum devlink_reload_limit limit,
 70				     u32 *actions_performed,
 71				     struct netlink_ext_ack *extack)
 72{
 73	struct hclgevf_devlink_priv *priv = devlink_priv(devlink);
 74	struct hclgevf_dev *hdev = priv->hdev;
 75	struct hnae3_handle *h = &hdev->nic;
 76	int ret;
 77
 78	*actions_performed = BIT(action);
 79	switch (action) {
 80	case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
 81		rtnl_lock();
 82		ret = hdev->nic_client->ops->reset_notify(h, HNAE3_INIT_CLIENT);
 83		if (ret) {
 84			rtnl_unlock();
 85			return ret;
 86		}
 87
 88		ret = hdev->nic_client->ops->reset_notify(h, HNAE3_UP_CLIENT);
 89		rtnl_unlock();
 90		return ret;
 91	default:
 92		return -EOPNOTSUPP;
 93	}
 94}
 95
 96static const struct devlink_ops hclgevf_devlink_ops = {
 97	.info_get = hclgevf_devlink_info_get,
 98	.reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT),
 99	.reload_down = hclgevf_devlink_reload_down,
100	.reload_up = hclgevf_devlink_reload_up,
101};
102
103int hclgevf_devlink_init(struct hclgevf_dev *hdev)
104{
105	struct pci_dev *pdev = hdev->pdev;
106	struct hclgevf_devlink_priv *priv;
107	struct devlink *devlink;
108
109	devlink =
110		devlink_alloc(&hclgevf_devlink_ops,
111			      sizeof(struct hclgevf_devlink_priv), &pdev->dev);
112	if (!devlink)
113		return -ENOMEM;
114
115	priv = devlink_priv(devlink);
116	priv->hdev = hdev;
117	hdev->devlink = devlink;
118
119	devlink_register(devlink);
120	return 0;
121}
122
123void hclgevf_devlink_uninit(struct hclgevf_dev *hdev)
124{
125	struct devlink *devlink = hdev->devlink;
126
127	devlink_unregister(devlink);
128
129	devlink_free(devlink);
130}