1b741269bSYufeng Mo // SPDX-License-Identifier: GPL-2.0+
2b741269bSYufeng Mo /* Copyright (c) 2021 Hisilicon Limited. */
3b741269bSYufeng Mo
4b741269bSYufeng Mo #include <net/devlink.h>
5b741269bSYufeng Mo
6b741269bSYufeng Mo #include "hclge_devlink.h"
7b741269bSYufeng Mo
hclge_devlink_info_get(struct devlink * devlink,struct devlink_info_req * req,struct netlink_ext_ack * extack)826fbf511SYufeng Mo static int hclge_devlink_info_get(struct devlink *devlink,
926fbf511SYufeng Mo struct devlink_info_req *req,
1026fbf511SYufeng Mo struct netlink_ext_ack *extack)
1126fbf511SYufeng Mo {
1226fbf511SYufeng Mo #define HCLGE_DEVLINK_FW_STRING_LEN 32
1326fbf511SYufeng Mo struct hclge_devlink_priv *priv = devlink_priv(devlink);
1426fbf511SYufeng Mo char version_str[HCLGE_DEVLINK_FW_STRING_LEN];
1526fbf511SYufeng Mo struct hclge_dev *hdev = priv->hdev;
1626fbf511SYufeng Mo
1726fbf511SYufeng Mo snprintf(version_str, sizeof(version_str), "%lu.%lu.%lu.%lu",
1826fbf511SYufeng Mo hnae3_get_field(hdev->fw_version, HNAE3_FW_VERSION_BYTE3_MASK,
1926fbf511SYufeng Mo HNAE3_FW_VERSION_BYTE3_SHIFT),
2026fbf511SYufeng Mo hnae3_get_field(hdev->fw_version, HNAE3_FW_VERSION_BYTE2_MASK,
2126fbf511SYufeng Mo HNAE3_FW_VERSION_BYTE2_SHIFT),
2226fbf511SYufeng Mo hnae3_get_field(hdev->fw_version, HNAE3_FW_VERSION_BYTE1_MASK,
2326fbf511SYufeng Mo HNAE3_FW_VERSION_BYTE1_SHIFT),
2426fbf511SYufeng Mo hnae3_get_field(hdev->fw_version, HNAE3_FW_VERSION_BYTE0_MASK,
2526fbf511SYufeng Mo HNAE3_FW_VERSION_BYTE0_SHIFT));
2626fbf511SYufeng Mo
2726fbf511SYufeng Mo return devlink_info_version_running_put(req,
2826fbf511SYufeng Mo DEVLINK_INFO_VERSION_GENERIC_FW,
2926fbf511SYufeng Mo version_str);
3026fbf511SYufeng Mo }
3126fbf511SYufeng Mo
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)3298fa7525SHao Chen static int hclge_devlink_reload_down(struct devlink *devlink, bool netns_change,
3398fa7525SHao Chen enum devlink_reload_action action,
3498fa7525SHao Chen enum devlink_reload_limit limit,
3598fa7525SHao Chen struct netlink_ext_ack *extack)
3698fa7525SHao Chen {
3798fa7525SHao Chen struct hclge_devlink_priv *priv = devlink_priv(devlink);
3898fa7525SHao Chen struct hclge_dev *hdev = priv->hdev;
3998fa7525SHao Chen struct hnae3_handle *h = &hdev->vport->nic;
4098fa7525SHao Chen struct pci_dev *pdev = hdev->pdev;
4198fa7525SHao Chen int ret;
4298fa7525SHao Chen
4398fa7525SHao Chen if (test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state)) {
4498fa7525SHao Chen dev_err(&pdev->dev, "reset is handling\n");
4598fa7525SHao Chen return -EBUSY;
4698fa7525SHao Chen }
4798fa7525SHao Chen
4898fa7525SHao Chen switch (action) {
4998fa7525SHao Chen case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
5098fa7525SHao Chen rtnl_lock();
5198fa7525SHao Chen ret = hdev->nic_client->ops->reset_notify(h, HNAE3_DOWN_CLIENT);
5298fa7525SHao Chen if (ret) {
5398fa7525SHao Chen rtnl_unlock();
5498fa7525SHao Chen return ret;
5598fa7525SHao Chen }
5698fa7525SHao Chen
5798fa7525SHao Chen ret = hdev->nic_client->ops->reset_notify(h,
5898fa7525SHao Chen HNAE3_UNINIT_CLIENT);
5998fa7525SHao Chen rtnl_unlock();
6098fa7525SHao Chen return ret;
6198fa7525SHao Chen default:
6298fa7525SHao Chen return -EOPNOTSUPP;
6398fa7525SHao Chen }
6498fa7525SHao Chen }
6598fa7525SHao Chen
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)6698fa7525SHao Chen static int hclge_devlink_reload_up(struct devlink *devlink,
6798fa7525SHao Chen enum devlink_reload_action action,
6898fa7525SHao Chen enum devlink_reload_limit limit,
6998fa7525SHao Chen u32 *actions_performed,
7098fa7525SHao Chen struct netlink_ext_ack *extack)
7198fa7525SHao Chen {
7298fa7525SHao Chen struct hclge_devlink_priv *priv = devlink_priv(devlink);
7398fa7525SHao Chen struct hclge_dev *hdev = priv->hdev;
7498fa7525SHao Chen struct hnae3_handle *h = &hdev->vport->nic;
7598fa7525SHao Chen int ret;
7698fa7525SHao Chen
7798fa7525SHao Chen *actions_performed = BIT(action);
7898fa7525SHao Chen switch (action) {
7998fa7525SHao Chen case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
8098fa7525SHao Chen rtnl_lock();
8198fa7525SHao Chen ret = hdev->nic_client->ops->reset_notify(h, HNAE3_INIT_CLIENT);
8298fa7525SHao Chen if (ret) {
8398fa7525SHao Chen rtnl_unlock();
8498fa7525SHao Chen return ret;
8598fa7525SHao Chen }
8698fa7525SHao Chen
8798fa7525SHao Chen ret = hdev->nic_client->ops->reset_notify(h, HNAE3_UP_CLIENT);
8898fa7525SHao Chen rtnl_unlock();
8998fa7525SHao Chen return ret;
9098fa7525SHao Chen default:
9198fa7525SHao Chen return -EOPNOTSUPP;
9298fa7525SHao Chen }
9398fa7525SHao Chen }
9498fa7525SHao Chen
95b741269bSYufeng Mo static const struct devlink_ops hclge_devlink_ops = {
9626fbf511SYufeng Mo .info_get = hclge_devlink_info_get,
9798fa7525SHao Chen .reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT),
9898fa7525SHao Chen .reload_down = hclge_devlink_reload_down,
9998fa7525SHao Chen .reload_up = hclge_devlink_reload_up,
100b741269bSYufeng Mo };
101b741269bSYufeng Mo
hclge_devlink_init(struct hclge_dev * hdev)102b741269bSYufeng Mo int hclge_devlink_init(struct hclge_dev *hdev)
103b741269bSYufeng Mo {
104b741269bSYufeng Mo struct pci_dev *pdev = hdev->pdev;
105b741269bSYufeng Mo struct hclge_devlink_priv *priv;
106b741269bSYufeng Mo struct devlink *devlink;
107b741269bSYufeng Mo
108b741269bSYufeng Mo devlink = devlink_alloc(&hclge_devlink_ops,
109919d13a7SLeon Romanovsky sizeof(struct hclge_devlink_priv), &pdev->dev);
110b741269bSYufeng Mo if (!devlink)
111b741269bSYufeng Mo return -ENOMEM;
112b741269bSYufeng Mo
113b741269bSYufeng Mo priv = devlink_priv(devlink);
114b741269bSYufeng Mo priv->hdev = hdev;
115a1fcb106SLeon Romanovsky hdev->devlink = devlink;
116b741269bSYufeng Mo
117*db4278c5SLeon Romanovsky devlink_register(devlink);
118b741269bSYufeng Mo return 0;
119b741269bSYufeng Mo }
120b741269bSYufeng Mo
hclge_devlink_uninit(struct hclge_dev * hdev)121b741269bSYufeng Mo void hclge_devlink_uninit(struct hclge_dev *hdev)
122b741269bSYufeng Mo {
123b741269bSYufeng Mo struct devlink *devlink = hdev->devlink;
124b741269bSYufeng Mo
125b741269bSYufeng Mo devlink_unregister(devlink);
126b741269bSYufeng Mo
127b741269bSYufeng Mo devlink_free(devlink);
128b741269bSYufeng Mo }
129