Merge https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next
[linux-2.6-microblaze.git] / drivers / net / ethernet / hisilicon / hns3 / hns3vf / hclgevf_devlink.c
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
8 static 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
37 static 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
72 static 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
101 static 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
108 int 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
124         ret = devlink_register(devlink);
125         if (ret) {
126                 dev_err(&pdev->dev, "failed to register devlink, ret = %d\n",
127                         ret);
128                 goto out_reg_fail;
129         }
130
131         hdev->devlink = devlink;
132
133         devlink_reload_enable(devlink);
134
135         return 0;
136
137 out_reg_fail:
138         devlink_free(devlink);
139         return ret;
140 }
141
142 void hclgevf_devlink_uninit(struct hclgevf_dev *hdev)
143 {
144         struct devlink *devlink = hdev->devlink;
145
146         if (!devlink)
147                 return;
148
149         devlink_reload_disable(devlink);
150
151         devlink_unregister(devlink);
152
153         devlink_free(devlink);
154
155         hdev->devlink = NULL;
156 }