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 "hclge_devlink.h"
  7
  8static int hclge_devlink_info_get(struct devlink *devlink,
  9				  struct devlink_info_req *req,
 10				  struct netlink_ext_ack *extack)
 11{
 12#define	HCLGE_DEVLINK_FW_STRING_LEN	32
 13	struct hclge_devlink_priv *priv = devlink_priv(devlink);
 14	char version_str[HCLGE_DEVLINK_FW_STRING_LEN];
 15	struct hclge_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 hclge_devlink_reload_down(struct devlink *devlink, bool netns_change,
 33				     enum devlink_reload_action action,
 34				     enum devlink_reload_limit limit,
 35				     struct netlink_ext_ack *extack)
 36{
 37	struct hclge_devlink_priv *priv = devlink_priv(devlink);
 38	struct hclge_dev *hdev = priv->hdev;
 39	struct hnae3_handle *h = &hdev->vport->nic;
 40	struct pci_dev *pdev = hdev->pdev;
 41	int ret;
 42
 43	if (test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state)) {
 44		dev_err(&pdev->dev, "reset is handling\n");
 45		return -EBUSY;
 46	}
 47
 48	switch (action) {
 49	case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
 50		rtnl_lock();
 51		ret = hdev->nic_client->ops->reset_notify(h, HNAE3_DOWN_CLIENT);
 52		if (ret) {
 53			rtnl_unlock();
 54			return ret;
 55		}
 56
 57		ret = hdev->nic_client->ops->reset_notify(h,
 58							  HNAE3_UNINIT_CLIENT);
 59		rtnl_unlock();
 60		return ret;
 61	default:
 62		return -EOPNOTSUPP;
 63	}
 64}
 65
 66static int hclge_devlink_reload_up(struct devlink *devlink,
 67				   enum devlink_reload_action action,
 68				   enum devlink_reload_limit limit,
 69				   u32 *actions_performed,
 70				   struct netlink_ext_ack *extack)
 71{
 72	struct hclge_devlink_priv *priv = devlink_priv(devlink);
 73	struct hclge_dev *hdev = priv->hdev;
 74	struct hnae3_handle *h = &hdev->vport->nic;
 75	int ret;
 76
 77	*actions_performed = BIT(action);
 78	switch (action) {
 79	case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
 80		rtnl_lock();
 81		ret = hdev->nic_client->ops->reset_notify(h, HNAE3_INIT_CLIENT);
 82		if (ret) {
 83			rtnl_unlock();
 84			return ret;
 85		}
 86
 87		ret = hdev->nic_client->ops->reset_notify(h, HNAE3_UP_CLIENT);
 88		rtnl_unlock();
 89		return ret;
 90	default:
 91		return -EOPNOTSUPP;
 92	}
 93}
 94
 95static const struct devlink_ops hclge_devlink_ops = {
 96	.info_get = hclge_devlink_info_get,
 97	.reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT),
 98	.reload_down = hclge_devlink_reload_down,
 99	.reload_up = hclge_devlink_reload_up,
100};
101
102int hclge_devlink_init(struct hclge_dev *hdev)
103{
104	struct pci_dev *pdev = hdev->pdev;
105	struct hclge_devlink_priv *priv;
106	struct devlink *devlink;
107
108	devlink = devlink_alloc(&hclge_devlink_ops,
109				sizeof(struct hclge_devlink_priv), &pdev->dev);
110	if (!devlink)
111		return -ENOMEM;
112
113	priv = devlink_priv(devlink);
114	priv->hdev = hdev;
115	hdev->devlink = devlink;
116
117	devlink_register(devlink);
118	return 0;
119}
120
121void hclge_devlink_uninit(struct hclge_dev *hdev)
122{
123	struct devlink *devlink = hdev->devlink;
124
125	devlink_unregister(devlink);
126
127	devlink_free(devlink);
128}