Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /* Copyright (c) 2021 Hisilicon Limited. */
0003 
0004 #include <net/devlink.h>
0005 
0006 #include "hclge_devlink.h"
0007 
0008 static int hclge_devlink_info_get(struct devlink *devlink,
0009                   struct devlink_info_req *req,
0010                   struct netlink_ext_ack *extack)
0011 {
0012 #define HCLGE_DEVLINK_FW_STRING_LEN 32
0013     struct hclge_devlink_priv *priv = devlink_priv(devlink);
0014     char version_str[HCLGE_DEVLINK_FW_STRING_LEN];
0015     struct hclge_dev *hdev = priv->hdev;
0016     int ret;
0017 
0018     ret = devlink_info_driver_name_put(req, KBUILD_MODNAME);
0019     if (ret)
0020         return ret;
0021 
0022     snprintf(version_str, sizeof(version_str), "%lu.%lu.%lu.%lu",
0023          hnae3_get_field(hdev->fw_version, HNAE3_FW_VERSION_BYTE3_MASK,
0024                  HNAE3_FW_VERSION_BYTE3_SHIFT),
0025          hnae3_get_field(hdev->fw_version, HNAE3_FW_VERSION_BYTE2_MASK,
0026                  HNAE3_FW_VERSION_BYTE2_SHIFT),
0027          hnae3_get_field(hdev->fw_version, HNAE3_FW_VERSION_BYTE1_MASK,
0028                  HNAE3_FW_VERSION_BYTE1_SHIFT),
0029          hnae3_get_field(hdev->fw_version, HNAE3_FW_VERSION_BYTE0_MASK,
0030                  HNAE3_FW_VERSION_BYTE0_SHIFT));
0031 
0032     return devlink_info_version_running_put(req,
0033                         DEVLINK_INFO_VERSION_GENERIC_FW,
0034                         version_str);
0035 }
0036 
0037 static int hclge_devlink_reload_down(struct devlink *devlink, bool netns_change,
0038                      enum devlink_reload_action action,
0039                      enum devlink_reload_limit limit,
0040                      struct netlink_ext_ack *extack)
0041 {
0042     struct hclge_devlink_priv *priv = devlink_priv(devlink);
0043     struct hclge_dev *hdev = priv->hdev;
0044     struct hnae3_handle *h = &hdev->vport->nic;
0045     struct pci_dev *pdev = hdev->pdev;
0046     int ret;
0047 
0048     if (test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state)) {
0049         dev_err(&pdev->dev, "reset is handling\n");
0050         return -EBUSY;
0051     }
0052 
0053     switch (action) {
0054     case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
0055         rtnl_lock();
0056         ret = hdev->nic_client->ops->reset_notify(h, HNAE3_DOWN_CLIENT);
0057         if (ret) {
0058             rtnl_unlock();
0059             return ret;
0060         }
0061 
0062         ret = hdev->nic_client->ops->reset_notify(h,
0063                               HNAE3_UNINIT_CLIENT);
0064         rtnl_unlock();
0065         return ret;
0066     default:
0067         return -EOPNOTSUPP;
0068     }
0069 }
0070 
0071 static int hclge_devlink_reload_up(struct devlink *devlink,
0072                    enum devlink_reload_action action,
0073                    enum devlink_reload_limit limit,
0074                    u32 *actions_performed,
0075                    struct netlink_ext_ack *extack)
0076 {
0077     struct hclge_devlink_priv *priv = devlink_priv(devlink);
0078     struct hclge_dev *hdev = priv->hdev;
0079     struct hnae3_handle *h = &hdev->vport->nic;
0080     int ret;
0081 
0082     *actions_performed = BIT(action);
0083     switch (action) {
0084     case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
0085         rtnl_lock();
0086         ret = hdev->nic_client->ops->reset_notify(h, HNAE3_INIT_CLIENT);
0087         if (ret) {
0088             rtnl_unlock();
0089             return ret;
0090         }
0091 
0092         ret = hdev->nic_client->ops->reset_notify(h, HNAE3_UP_CLIENT);
0093         rtnl_unlock();
0094         return ret;
0095     default:
0096         return -EOPNOTSUPP;
0097     }
0098 }
0099 
0100 static const struct devlink_ops hclge_devlink_ops = {
0101     .info_get = hclge_devlink_info_get,
0102     .reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT),
0103     .reload_down = hclge_devlink_reload_down,
0104     .reload_up = hclge_devlink_reload_up,
0105 };
0106 
0107 int hclge_devlink_init(struct hclge_dev *hdev)
0108 {
0109     struct pci_dev *pdev = hdev->pdev;
0110     struct hclge_devlink_priv *priv;
0111     struct devlink *devlink;
0112 
0113     devlink = devlink_alloc(&hclge_devlink_ops,
0114                 sizeof(struct hclge_devlink_priv), &pdev->dev);
0115     if (!devlink)
0116         return -ENOMEM;
0117 
0118     priv = devlink_priv(devlink);
0119     priv->hdev = hdev;
0120     hdev->devlink = devlink;
0121 
0122     devlink_set_features(devlink, DEVLINK_F_RELOAD);
0123     devlink_register(devlink);
0124     return 0;
0125 }
0126 
0127 void hclge_devlink_uninit(struct hclge_dev *hdev)
0128 {
0129     struct devlink *devlink = hdev->devlink;
0130 
0131     devlink_unregister(devlink);
0132 
0133     devlink_free(devlink);
0134 }