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