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(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 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(ops: &hclgevf_devlink_ops,
111 priv_size: sizeof(struct hclgevf_devlink_priv), dev: &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}
131

source code of linux/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_devlink.c