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
hclge_devlink_info_get(struct devlink * devlink,struct devlink_info_req * req,struct netlink_ext_ack * extack)8 static 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 int ret;
17
18 ret = devlink_info_driver_name_put(req, KBUILD_MODNAME);
19 if (ret)
20 return ret;
21
22 snprintf(version_str, sizeof(version_str), "%lu.%lu.%lu.%lu",
23 hnae3_get_field(hdev->fw_version, HNAE3_FW_VERSION_BYTE3_MASK,
24 HNAE3_FW_VERSION_BYTE3_SHIFT),
25 hnae3_get_field(hdev->fw_version, HNAE3_FW_VERSION_BYTE2_MASK,
26 HNAE3_FW_VERSION_BYTE2_SHIFT),
27 hnae3_get_field(hdev->fw_version, HNAE3_FW_VERSION_BYTE1_MASK,
28 HNAE3_FW_VERSION_BYTE1_SHIFT),
29 hnae3_get_field(hdev->fw_version, HNAE3_FW_VERSION_BYTE0_MASK,
30 HNAE3_FW_VERSION_BYTE0_SHIFT));
31
32 return devlink_info_version_running_put(req,
33 DEVLINK_INFO_VERSION_GENERIC_FW,
34 version_str);
35 }
36
hclge_devlink_reload_down(struct devlink * devlink,bool netns_change,enum devlink_reload_action action,enum devlink_reload_limit limit,struct netlink_ext_ack * extack)37 static int hclge_devlink_reload_down(struct devlink *devlink, bool netns_change,
38 enum devlink_reload_action action,
39 enum devlink_reload_limit limit,
40 struct netlink_ext_ack *extack)
41 {
42 struct hclge_devlink_priv *priv = devlink_priv(devlink);
43 struct hclge_dev *hdev = priv->hdev;
44 struct hnae3_handle *h = &hdev->vport->nic;
45 struct pci_dev *pdev = hdev->pdev;
46 int ret;
47
48 if (test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state)) {
49 dev_err(&pdev->dev, "reset is handling\n");
50 return -EBUSY;
51 }
52
53 switch (action) {
54 case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
55 rtnl_lock();
56 ret = hdev->nic_client->ops->reset_notify(h, HNAE3_DOWN_CLIENT);
57 if (ret) {
58 rtnl_unlock();
59 return ret;
60 }
61
62 ret = hdev->nic_client->ops->reset_notify(h,
63 HNAE3_UNINIT_CLIENT);
64 rtnl_unlock();
65 return ret;
66 default:
67 return -EOPNOTSUPP;
68 }
69 }
70
hclge_devlink_reload_up(struct devlink * devlink,enum devlink_reload_action action,enum devlink_reload_limit limit,u32 * actions_performed,struct netlink_ext_ack * extack)71 static int hclge_devlink_reload_up(struct devlink *devlink,
72 enum devlink_reload_action action,
73 enum devlink_reload_limit limit,
74 u32 *actions_performed,
75 struct netlink_ext_ack *extack)
76 {
77 struct hclge_devlink_priv *priv = devlink_priv(devlink);
78 struct hclge_dev *hdev = priv->hdev;
79 struct hnae3_handle *h = &hdev->vport->nic;
80 int ret;
81
82 *actions_performed = BIT(action);
83 switch (action) {
84 case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
85 rtnl_lock();
86 ret = hdev->nic_client->ops->reset_notify(h, HNAE3_INIT_CLIENT);
87 if (ret) {
88 rtnl_unlock();
89 return ret;
90 }
91
92 ret = hdev->nic_client->ops->reset_notify(h, HNAE3_UP_CLIENT);
93 rtnl_unlock();
94 return ret;
95 default:
96 return -EOPNOTSUPP;
97 }
98 }
99
100 static const struct devlink_ops hclge_devlink_ops = {
101 .info_get = hclge_devlink_info_get,
102 .reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT),
103 .reload_down = hclge_devlink_reload_down,
104 .reload_up = hclge_devlink_reload_up,
105 };
106
hclge_devlink_init(struct hclge_dev * hdev)107 int hclge_devlink_init(struct hclge_dev *hdev)
108 {
109 struct pci_dev *pdev = hdev->pdev;
110 struct hclge_devlink_priv *priv;
111 struct devlink *devlink;
112 int ret;
113
114 devlink = devlink_alloc(&hclge_devlink_ops,
115 sizeof(struct hclge_devlink_priv), &pdev->dev);
116 if (!devlink)
117 return -ENOMEM;
118
119 priv = devlink_priv(devlink);
120 priv->hdev = hdev;
121 hdev->devlink = devlink;
122
123 ret = devlink_register(devlink);
124 if (ret) {
125 dev_err(&pdev->dev, "failed to register devlink, ret = %d\n",
126 ret);
127 goto out_reg_fail;
128 }
129
130 devlink_reload_enable(devlink);
131
132 return 0;
133
134 out_reg_fail:
135 devlink_free(devlink);
136 return ret;
137 }
138
hclge_devlink_uninit(struct hclge_dev * hdev)139 void hclge_devlink_uninit(struct hclge_dev *hdev)
140 {
141 struct devlink *devlink = hdev->devlink;
142
143 devlink_reload_disable(devlink);
144
145 devlink_unregister(devlink);
146
147 devlink_free(devlink);
148 }
149