167 lines · 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 3241 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}167