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