devlink: Set device as early as possible
[linux-2.6-microblaze.git] / drivers / net / ethernet / hisilicon / hns3 / hns3pf / hclge_devlink.c
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
8 static 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
37 static 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
71 static 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
100 static 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
107 int 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
122         ret = devlink_register(devlink);
123         if (ret) {
124                 dev_err(&pdev->dev, "failed to register devlink, ret = %d\n",
125                         ret);
126                 goto out_reg_fail;
127         }
128
129         hdev->devlink = devlink;
130
131         devlink_reload_enable(devlink);
132
133         return 0;
134
135 out_reg_fail:
136         devlink_free(devlink);
137         return ret;
138 }
139
140 void hclge_devlink_uninit(struct hclge_dev *hdev)
141 {
142         struct devlink *devlink = hdev->devlink;
143
144         if (!devlink)
145                 return;
146
147         devlink_reload_disable(devlink);
148
149         devlink_unregister(devlink);
150
151         devlink_free(devlink);
152
153         hdev->devlink = NULL;
154 }