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