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(buf: version_str, size: sizeof(version_str), fmt: "%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_value: 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(ops: &hclge_devlink_ops,
109 priv_size: sizeof(struct hclge_devlink_priv), dev: &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}
129

source code of linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_devlink.c