xref: /openbmc/linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_devlink.c (revision 9a87ffc99ec8eb8d35eed7c4f816d75f5cc9662e)
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