linux/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_devlink.c
<<
>>
Prefs
   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        int ret;
 114
 115        devlink =
 116                devlink_alloc(&hclgevf_devlink_ops,
 117                              sizeof(struct hclgevf_devlink_priv), &pdev->dev);
 118        if (!devlink)
 119                return -ENOMEM;
 120
 121        priv = devlink_priv(devlink);
 122        priv->hdev = hdev;
 123        hdev->devlink = devlink;
 124
 125        ret = devlink_register(devlink);
 126        if (ret) {
 127                dev_err(&pdev->dev, "failed to register devlink, ret = %d\n",
 128                        ret);
 129                goto out_reg_fail;
 130        }
 131
 132        devlink_reload_enable(devlink);
 133
 134        return 0;
 135
 136out_reg_fail:
 137        devlink_free(devlink);
 138        return ret;
 139}
 140
 141void hclgevf_devlink_uninit(struct hclgevf_dev *hdev)
 142{
 143        struct devlink *devlink = hdev->devlink;
 144
 145        devlink_reload_disable(devlink);
 146
 147        devlink_unregister(devlink);
 148
 149        devlink_free(devlink);
 150}
 151