File Index
Files and directories
Sign in
FILE

hclge_devlink.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_devlink.c C
  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
  8static int hclge_devlink_scc_info_get(struct devlink *devlink,
  9				      struct devlink_info_req *req)
 10{
 11	struct hclge_devlink_priv *priv = devlink_priv(devlink);
 12	char scc_version[HCLGE_DEVLINK_FW_SCC_LEN];
 13	struct hclge_dev *hdev = priv->hdev;
 14	u32 scc_version_tmp;
 15	int ret;
 16
 17	ret = hclge_query_scc_version(hdev, &scc_version_tmp);
 18	if (ret) {
 19		dev_err(&hdev->pdev->dev,
 20			"failed to get scc version, ret = %d\n", ret);
 21		return ret;
 22	}
 23
 24	snprintf(scc_version, sizeof(scc_version), "%lu.%lu.%lu.%lu",
 25		 hnae3_get_field(scc_version_tmp, HNAE3_SCC_VERSION_BYTE3_MASK,
 26				 HNAE3_FW_VERSION_BYTE3_SHIFT),
 27		 hnae3_get_field(scc_version_tmp, HNAE3_SCC_VERSION_BYTE2_MASK,
 28				 HNAE3_FW_VERSION_BYTE2_SHIFT),
 29		 hnae3_get_field(scc_version_tmp, HNAE3_SCC_VERSION_BYTE1_MASK,
 30				 HNAE3_FW_VERSION_BYTE1_SHIFT),
 31		 hnae3_get_field(scc_version_tmp, HNAE3_SCC_VERSION_BYTE0_MASK,
 32				 HNAE3_FW_VERSION_BYTE0_SHIFT));
 33	return devlink_info_version_running_put(req, "fw.scc", scc_version);
 34}
 35
 36static int hclge_devlink_info_get(struct devlink *devlink,
 37				  struct devlink_info_req *req,
 38				  struct netlink_ext_ack *extack)
 39{
 40#define	HCLGE_DEVLINK_FW_STRING_LEN	32
 41	struct hclge_devlink_priv *priv = devlink_priv(devlink);
 42	char version_str[HCLGE_DEVLINK_FW_STRING_LEN];
 43	struct hclge_dev *hdev = priv->hdev;
 44	int ret;
 45
 46	snprintf(version_str, sizeof(version_str), "%lu.%lu.%lu.%lu",
 47		 hnae3_get_field(hdev->fw_version, HNAE3_FW_VERSION_BYTE3_MASK,
 48				 HNAE3_FW_VERSION_BYTE3_SHIFT),
 49		 hnae3_get_field(hdev->fw_version, HNAE3_FW_VERSION_BYTE2_MASK,
 50				 HNAE3_FW_VERSION_BYTE2_SHIFT),
 51		 hnae3_get_field(hdev->fw_version, HNAE3_FW_VERSION_BYTE1_MASK,
 52				 HNAE3_FW_VERSION_BYTE1_SHIFT),
 53		 hnae3_get_field(hdev->fw_version, HNAE3_FW_VERSION_BYTE0_MASK,
 54				 HNAE3_FW_VERSION_BYTE0_SHIFT));
 55
 56	ret = devlink_info_version_running_put(req,
 57					       DEVLINK_INFO_VERSION_GENERIC_FW,
 58					       version_str);
 59	if (ret) {
 60		dev_err(&hdev->pdev->dev, "failed to set running version of fw\n");
 61		return ret;
 62	}
 63
 64	if (hdev->pdev->revision > HNAE3_DEVICE_VERSION_V2)
 65		ret = hclge_devlink_scc_info_get(devlink, req);
 66
 67	return ret;
 68}
 69
 70static int hclge_devlink_reload_down(struct devlink *devlink, bool netns_change,
 71				     enum devlink_reload_action action,
 72				     enum devlink_reload_limit limit,
 73				     struct netlink_ext_ack *extack)
 74{
 75	struct hclge_devlink_priv *priv = devlink_priv(devlink);
 76	struct hclge_dev *hdev = priv->hdev;
 77	struct hnae3_handle *h = &hdev->vport->nic;
 78	struct pci_dev *pdev = hdev->pdev;
 79	int ret;
 80
 81	if (test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state)) {
 82		dev_err(&pdev->dev, "reset is handling\n");
 83		return -EBUSY;
 84	}
 85
 86	switch (action) {
 87	case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
 88		rtnl_lock();
 89		ret = hdev->nic_client->ops->reset_notify(h, HNAE3_DOWN_CLIENT);
 90		if (ret) {
 91			rtnl_unlock();
 92			return ret;
 93		}
 94
 95		ret = hdev->nic_client->ops->reset_notify(h,
 96							  HNAE3_UNINIT_CLIENT);
 97		rtnl_unlock();
 98		return ret;
 99	default:
100		return -EOPNOTSUPP;
101	}
102}
103
104static int hclge_devlink_reload_up(struct devlink *devlink,
105				   enum devlink_reload_action action,
106				   enum devlink_reload_limit limit,
107				   u32 *actions_performed,
108				   struct netlink_ext_ack *extack)
109{
110	struct hclge_devlink_priv *priv = devlink_priv(devlink);
111	struct hclge_dev *hdev = priv->hdev;
112	struct hnae3_handle *h = &hdev->vport->nic;
113	int ret;
114
115	*actions_performed = BIT(action);
116	switch (action) {
117	case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
118		rtnl_lock();
119		ret = hdev->nic_client->ops->reset_notify(h, HNAE3_INIT_CLIENT);
120		if (ret) {
121			rtnl_unlock();
122			return ret;
123		}
124
125		ret = hdev->nic_client->ops->reset_notify(h, HNAE3_UP_CLIENT);
126		rtnl_unlock();
127		return ret;
128	default:
129		return -EOPNOTSUPP;
130	}
131}
132
133static const struct devlink_ops hclge_devlink_ops = {
134	.info_get = hclge_devlink_info_get,
135	.reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT),
136	.reload_down = hclge_devlink_reload_down,
137	.reload_up = hclge_devlink_reload_up,
138};
139
140int hclge_devlink_init(struct hclge_dev *hdev)
141{
142	struct pci_dev *pdev = hdev->pdev;
143	struct hclge_devlink_priv *priv;
144	struct devlink *devlink;
145
146	devlink = devlink_alloc(&hclge_devlink_ops,
147				sizeof(struct hclge_devlink_priv), &pdev->dev);
148	if (!devlink)
149		return -ENOMEM;
150
151	priv = devlink_priv(devlink);
152	priv->hdev = hdev;
153	hdev->devlink = devlink;
154
155	devlink_register(devlink);
156	return 0;
157}
158
159void hclge_devlink_uninit(struct hclge_dev *hdev)
160{
161	struct devlink *devlink = hdev->devlink;
162
163	devlink_unregister(devlink);
164
165	devlink_free(devlink);
166}
~/ Read-only file preview.