hclgevf_devlink.c (3630B)
1// SPDX-License-Identifier: GPL-2.0+ 2/* Copyright (c) 2021 Hisilicon Limited. */ 3 4#include <net/devlink.h> 5 6#include "hclgevf_devlink.h" 7 8static int hclgevf_devlink_info_get(struct devlink *devlink, 9 struct devlink_info_req *req, 10 struct netlink_ext_ack *extack) 11{ 12#define HCLGEVF_DEVLINK_FW_STRING_LEN 32 13 struct hclgevf_devlink_priv *priv = devlink_priv(devlink); 14 char version_str[HCLGEVF_DEVLINK_FW_STRING_LEN]; 15 struct hclgevf_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 hclgevf_devlink_reload_down(struct devlink *devlink, 38 bool netns_change, 39 enum devlink_reload_action action, 40 enum devlink_reload_limit limit, 41 struct netlink_ext_ack *extack) 42{ 43 struct hclgevf_devlink_priv *priv = devlink_priv(devlink); 44 struct hclgevf_dev *hdev = priv->hdev; 45 struct hnae3_handle *h = &hdev->nic; 46 struct pci_dev *pdev = hdev->pdev; 47 int ret; 48 49 if (test_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state)) { 50 dev_err(&pdev->dev, "reset is handling\n"); 51 return -EBUSY; 52 } 53 54 switch (action) { 55 case DEVLINK_RELOAD_ACTION_DRIVER_REINIT: 56 rtnl_lock(); 57 ret = hdev->nic_client->ops->reset_notify(h, HNAE3_DOWN_CLIENT); 58 if (ret) { 59 rtnl_unlock(); 60 return ret; 61 } 62 63 ret = hdev->nic_client->ops->reset_notify(h, 64 HNAE3_UNINIT_CLIENT); 65 rtnl_unlock(); 66 return ret; 67 default: 68 return -EOPNOTSUPP; 69 } 70} 71 72static int hclgevf_devlink_reload_up(struct devlink *devlink, 73 enum devlink_reload_action action, 74 enum devlink_reload_limit limit, 75 u32 *actions_performed, 76 struct netlink_ext_ack *extack) 77{ 78 struct hclgevf_devlink_priv *priv = devlink_priv(devlink); 79 struct hclgevf_dev *hdev = priv->hdev; 80 struct hnae3_handle *h = &hdev->nic; 81 int ret; 82 83 *actions_performed = BIT(action); 84 switch (action) { 85 case DEVLINK_RELOAD_ACTION_DRIVER_REINIT: 86 rtnl_lock(); 87 ret = hdev->nic_client->ops->reset_notify(h, HNAE3_INIT_CLIENT); 88 if (ret) { 89 rtnl_unlock(); 90 return ret; 91 } 92 93 ret = hdev->nic_client->ops->reset_notify(h, HNAE3_UP_CLIENT); 94 rtnl_unlock(); 95 return ret; 96 default: 97 return -EOPNOTSUPP; 98 } 99} 100 101static const struct devlink_ops hclgevf_devlink_ops = { 102 .info_get = hclgevf_devlink_info_get, 103 .reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT), 104 .reload_down = hclgevf_devlink_reload_down, 105 .reload_up = hclgevf_devlink_reload_up, 106}; 107 108int hclgevf_devlink_init(struct hclgevf_dev *hdev) 109{ 110 struct pci_dev *pdev = hdev->pdev; 111 struct hclgevf_devlink_priv *priv; 112 struct devlink *devlink; 113 114 devlink = 115 devlink_alloc(&hclgevf_devlink_ops, 116 sizeof(struct hclgevf_devlink_priv), &pdev->dev); 117 if (!devlink) 118 return -ENOMEM; 119 120 priv = devlink_priv(devlink); 121 priv->hdev = hdev; 122 hdev->devlink = devlink; 123 124 devlink_set_features(devlink, DEVLINK_F_RELOAD); 125 devlink_register(devlink); 126 return 0; 127} 128 129void hclgevf_devlink_uninit(struct hclgevf_dev *hdev) 130{ 131 struct devlink *devlink = hdev->devlink; 132 133 devlink_unregister(devlink); 134 135 devlink_free(devlink); 136}