hclge_devlink.c (3560B)
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_info_get(struct devlink *devlink, 9 struct devlink_info_req *req, 10 struct netlink_ext_ack *extack) 11{ 12#define HCLGE_DEVLINK_FW_STRING_LEN 32 13 struct hclge_devlink_priv *priv = devlink_priv(devlink); 14 char version_str[HCLGE_DEVLINK_FW_STRING_LEN]; 15 struct hclge_dev *hdev = priv->hdev; 16 int ret; 17 18 ret = devlink_info_driver_name_put(req, KBUILD_MODNAME); 19 if (ret) 20 return ret; 21 22 snprintf(version_str, sizeof(version_str), "%lu.%lu.%lu.%lu", 23 hnae3_get_field(hdev->fw_version, HNAE3_FW_VERSION_BYTE3_MASK, 24 HNAE3_FW_VERSION_BYTE3_SHIFT), 25 hnae3_get_field(hdev->fw_version, HNAE3_FW_VERSION_BYTE2_MASK, 26 HNAE3_FW_VERSION_BYTE2_SHIFT), 27 hnae3_get_field(hdev->fw_version, HNAE3_FW_VERSION_BYTE1_MASK, 28 HNAE3_FW_VERSION_BYTE1_SHIFT), 29 hnae3_get_field(hdev->fw_version, HNAE3_FW_VERSION_BYTE0_MASK, 30 HNAE3_FW_VERSION_BYTE0_SHIFT)); 31 32 return devlink_info_version_running_put(req, 33 DEVLINK_INFO_VERSION_GENERIC_FW, 34 version_str); 35} 36 37static int hclge_devlink_reload_down(struct devlink *devlink, bool netns_change, 38 enum devlink_reload_action action, 39 enum devlink_reload_limit limit, 40 struct netlink_ext_ack *extack) 41{ 42 struct hclge_devlink_priv *priv = devlink_priv(devlink); 43 struct hclge_dev *hdev = priv->hdev; 44 struct hnae3_handle *h = &hdev->vport->nic; 45 struct pci_dev *pdev = hdev->pdev; 46 int ret; 47 48 if (test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state)) { 49 dev_err(&pdev->dev, "reset is handling\n"); 50 return -EBUSY; 51 } 52 53 switch (action) { 54 case DEVLINK_RELOAD_ACTION_DRIVER_REINIT: 55 rtnl_lock(); 56 ret = hdev->nic_client->ops->reset_notify(h, HNAE3_DOWN_CLIENT); 57 if (ret) { 58 rtnl_unlock(); 59 return ret; 60 } 61 62 ret = hdev->nic_client->ops->reset_notify(h, 63 HNAE3_UNINIT_CLIENT); 64 rtnl_unlock(); 65 return ret; 66 default: 67 return -EOPNOTSUPP; 68 } 69} 70 71static int hclge_devlink_reload_up(struct devlink *devlink, 72 enum devlink_reload_action action, 73 enum devlink_reload_limit limit, 74 u32 *actions_performed, 75 struct netlink_ext_ack *extack) 76{ 77 struct hclge_devlink_priv *priv = devlink_priv(devlink); 78 struct hclge_dev *hdev = priv->hdev; 79 struct hnae3_handle *h = &hdev->vport->nic; 80 int ret; 81 82 *actions_performed = BIT(action); 83 switch (action) { 84 case DEVLINK_RELOAD_ACTION_DRIVER_REINIT: 85 rtnl_lock(); 86 ret = hdev->nic_client->ops->reset_notify(h, HNAE3_INIT_CLIENT); 87 if (ret) { 88 rtnl_unlock(); 89 return ret; 90 } 91 92 ret = hdev->nic_client->ops->reset_notify(h, HNAE3_UP_CLIENT); 93 rtnl_unlock(); 94 return ret; 95 default: 96 return -EOPNOTSUPP; 97 } 98} 99 100static const struct devlink_ops hclge_devlink_ops = { 101 .info_get = hclge_devlink_info_get, 102 .reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT), 103 .reload_down = hclge_devlink_reload_down, 104 .reload_up = hclge_devlink_reload_up, 105}; 106 107int hclge_devlink_init(struct hclge_dev *hdev) 108{ 109 struct pci_dev *pdev = hdev->pdev; 110 struct hclge_devlink_priv *priv; 111 struct devlink *devlink; 112 113 devlink = devlink_alloc(&hclge_devlink_ops, 114 sizeof(struct hclge_devlink_priv), &pdev->dev); 115 if (!devlink) 116 return -ENOMEM; 117 118 priv = devlink_priv(devlink); 119 priv->hdev = hdev; 120 hdev->devlink = devlink; 121 122 devlink_set_features(devlink, DEVLINK_F_RELOAD); 123 devlink_register(devlink); 124 return 0; 125} 126 127void hclge_devlink_uninit(struct hclge_dev *hdev) 128{ 129 struct devlink *devlink = hdev->devlink; 130 131 devlink_unregister(devlink); 132 133 devlink_free(devlink); 134}