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 "hclgevf_devlink.h"
0007 
0008 static int hclgevf_devlink_info_get(struct devlink *devlink,
0009                     struct devlink_info_req *req,
0010                     struct netlink_ext_ack *extack)
0011 {
0012 #define HCLGEVF_DEVLINK_FW_STRING_LEN   32
0013     struct hclgevf_devlink_priv *priv = devlink_priv(devlink);
0014     char version_str[HCLGEVF_DEVLINK_FW_STRING_LEN];
0015     struct hclgevf_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 hclgevf_devlink_reload_down(struct devlink *devlink,
0038                        bool netns_change,
0039                        enum devlink_reload_action action,
0040                        enum devlink_reload_limit limit,
0041                        struct netlink_ext_ack *extack)
0042 {
0043     struct hclgevf_devlink_priv *priv = devlink_priv(devlink);
0044     struct hclgevf_dev *hdev = priv->hdev;
0045     struct hnae3_handle *h = &hdev->nic;
0046     struct pci_dev *pdev = hdev->pdev;
0047     int ret;
0048 
0049     if (test_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state)) {
0050         dev_err(&pdev->dev, "reset is handling\n");
0051         return -EBUSY;
0052     }
0053 
0054     switch (action) {
0055     case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
0056         rtnl_lock();
0057         ret = hdev->nic_client->ops->reset_notify(h, HNAE3_DOWN_CLIENT);
0058         if (ret) {
0059             rtnl_unlock();
0060             return ret;
0061         }
0062 
0063         ret = hdev->nic_client->ops->reset_notify(h,
0064                               HNAE3_UNINIT_CLIENT);
0065         rtnl_unlock();
0066         return ret;
0067     default:
0068         return -EOPNOTSUPP;
0069     }
0070 }
0071 
0072 static int hclgevf_devlink_reload_up(struct devlink *devlink,
0073                      enum devlink_reload_action action,
0074                      enum devlink_reload_limit limit,
0075                      u32 *actions_performed,
0076                      struct netlink_ext_ack *extack)
0077 {
0078     struct hclgevf_devlink_priv *priv = devlink_priv(devlink);
0079     struct hclgevf_dev *hdev = priv->hdev;
0080     struct hnae3_handle *h = &hdev->nic;
0081     int ret;
0082 
0083     *actions_performed = BIT(action);
0084     switch (action) {
0085     case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
0086         rtnl_lock();
0087         ret = hdev->nic_client->ops->reset_notify(h, HNAE3_INIT_CLIENT);
0088         if (ret) {
0089             rtnl_unlock();
0090             return ret;
0091         }
0092 
0093         ret = hdev->nic_client->ops->reset_notify(h, HNAE3_UP_CLIENT);
0094         rtnl_unlock();
0095         return ret;
0096     default:
0097         return -EOPNOTSUPP;
0098     }
0099 }
0100 
0101 static const struct devlink_ops hclgevf_devlink_ops = {
0102     .info_get = hclgevf_devlink_info_get,
0103     .reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT),
0104     .reload_down = hclgevf_devlink_reload_down,
0105     .reload_up = hclgevf_devlink_reload_up,
0106 };
0107 
0108 int hclgevf_devlink_init(struct hclgevf_dev *hdev)
0109 {
0110     struct pci_dev *pdev = hdev->pdev;
0111     struct hclgevf_devlink_priv *priv;
0112     struct devlink *devlink;
0113 
0114     devlink =
0115         devlink_alloc(&hclgevf_devlink_ops,
0116                   sizeof(struct hclgevf_devlink_priv), &pdev->dev);
0117     if (!devlink)
0118         return -ENOMEM;
0119 
0120     priv = devlink_priv(devlink);
0121     priv->hdev = hdev;
0122     hdev->devlink = devlink;
0123 
0124     devlink_set_features(devlink, DEVLINK_F_RELOAD);
0125     devlink_register(devlink);
0126     return 0;
0127 }
0128 
0129 void hclgevf_devlink_uninit(struct hclgevf_dev *hdev)
0130 {
0131     struct devlink *devlink = hdev->devlink;
0132 
0133     devlink_unregister(devlink);
0134 
0135     devlink_free(devlink);
0136 }