]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/net/ethernet/hisilicon/hns3/hnae3.c
UBUNTU: SAUCE: {topost} net: hns3: Use roce handle when calling roce callback function
[mirror_ubuntu-bionic-kernel.git] / drivers / net / ethernet / hisilicon / hns3 / hnae3.c
CommitLineData
4e2e261d
JS
1// SPDX-License-Identifier: GPL-2.0+
2// Copyright (c) 2016-2017 Hisilicon Limited.
38caee9d
S
3
4#include <linux/list.h>
38caee9d
S
5#include <linux/spinlock.h>
6
7#include "hnae3.h"
8
9static LIST_HEAD(hnae3_ae_algo_list);
10static LIST_HEAD(hnae3_client_list);
11static LIST_HEAD(hnae3_ae_dev_list);
12
13/* we are keeping things simple and using single lock for all the
14 * list. This is a non-critical code so other updations, if happen
15 * in parallel, can wait.
16 */
17static DEFINE_MUTEX(hnae3_common_lock);
18
19static bool hnae3_client_match(enum hnae3_client_type client_type,
20 enum hnae3_dev_type dev_type)
21{
22 if ((dev_type == HNAE3_DEV_KNIC) && (client_type == HNAE3_CLIENT_KNIC ||
23 client_type == HNAE3_CLIENT_ROCE))
24 return true;
25
26 if (dev_type == HNAE3_DEV_UNIC && client_type == HNAE3_CLIENT_UNIC)
27 return true;
28
29 return false;
30}
31
b46e2efa
PL
32static void hnae3_set_client_init_flag(struct hnae3_client *client,
33 struct hnae3_ae_dev *ae_dev, int inited)
34{
35 switch (client->type) {
36 case HNAE3_CLIENT_KNIC:
e22b531b 37 hnae3_set_bit(ae_dev->flag, HNAE3_KNIC_CLIENT_INITED_B, inited);
b46e2efa
PL
38 break;
39 case HNAE3_CLIENT_UNIC:
e22b531b 40 hnae3_set_bit(ae_dev->flag, HNAE3_UNIC_CLIENT_INITED_B, inited);
b46e2efa
PL
41 break;
42 case HNAE3_CLIENT_ROCE:
e22b531b 43 hnae3_set_bit(ae_dev->flag, HNAE3_ROCE_CLIENT_INITED_B, inited);
b46e2efa
PL
44 break;
45 default:
46 break;
47 }
48}
49
50static int hnae3_get_client_init_flag(struct hnae3_client *client,
51 struct hnae3_ae_dev *ae_dev)
52{
53 int inited = 0;
54
55 switch (client->type) {
56 case HNAE3_CLIENT_KNIC:
e22b531b 57 inited = hnae3_get_bit(ae_dev->flag,
b46e2efa
PL
58 HNAE3_KNIC_CLIENT_INITED_B);
59 break;
60 case HNAE3_CLIENT_UNIC:
e22b531b 61 inited = hnae3_get_bit(ae_dev->flag,
b46e2efa
PL
62 HNAE3_UNIC_CLIENT_INITED_B);
63 break;
64 case HNAE3_CLIENT_ROCE:
e22b531b 65 inited = hnae3_get_bit(ae_dev->flag,
b46e2efa
PL
66 HNAE3_ROCE_CLIENT_INITED_B);
67 break;
68 default:
69 break;
70 }
71
72 return inited;
73}
74
38caee9d 75static int hnae3_match_n_instantiate(struct hnae3_client *client,
90f7b11a 76 struct hnae3_ae_dev *ae_dev, bool is_reg)
38caee9d
S
77{
78 int ret;
79
38caee9d
S
80 /* check if this client matches the type of ae_dev */
81 if (!(hnae3_client_match(client->type, ae_dev->dev_type) &&
e22b531b 82 hnae3_get_bit(ae_dev->flag, HNAE3_DEV_INITED_B))) {
38caee9d
S
83 return 0;
84 }
38caee9d
S
85
86 /* now, (un-)instantiate client by calling lower layer */
87 if (is_reg) {
88 ret = ae_dev->ops->init_client_instance(client, ae_dev);
90400e41 89 if (ret) {
38caee9d 90 dev_err(&ae_dev->pdev->dev,
31ce0f41 91 "fail to instantiate client, ret = %d\n", ret);
90400e41
FL
92 return ret;
93 }
94
b46e2efa 95 hnae3_set_client_init_flag(client, ae_dev, 1);
90400e41
FL
96 return 0;
97 }
98
b46e2efa 99 if (hnae3_get_client_init_flag(client, ae_dev)) {
90400e41
FL
100 ae_dev->ops->uninit_client_instance(client, ae_dev);
101
b46e2efa 102 hnae3_set_client_init_flag(client, ae_dev, 0);
38caee9d
S
103 }
104
38caee9d
S
105 return 0;
106}
107
108int hnae3_register_client(struct hnae3_client *client)
109{
110 struct hnae3_client *client_tmp;
111 struct hnae3_ae_dev *ae_dev;
38caee9d
S
112 int ret = 0;
113
114 mutex_lock(&hnae3_common_lock);
115 /* one system should only have one client for every type */
116 list_for_each_entry(client_tmp, &hnae3_client_list, node) {
117 if (client_tmp->type == client->type)
118 goto exit;
119 }
120
121 list_add_tail(&client->node, &hnae3_client_list);
122
123 /* initialize the client on every matched port */
124 list_for_each_entry(ae_dev, &hnae3_ae_dev_list, node) {
125 /* if the client could not be initialized on current port, for
126 * any error reasons, move on to next available port
127 */
90f7b11a 128 ret = hnae3_match_n_instantiate(client, ae_dev, true);
38caee9d
S
129 if (ret)
130 dev_err(&ae_dev->pdev->dev,
31ce0f41
PL
131 "match and instantiation failed for port, ret = %d\n",
132 ret);
38caee9d
S
133 }
134
135exit:
136 mutex_unlock(&hnae3_common_lock);
137
e57c1f76 138 return 0;
38caee9d
S
139}
140EXPORT_SYMBOL(hnae3_register_client);
141
142void hnae3_unregister_client(struct hnae3_client *client)
143{
144 struct hnae3_ae_dev *ae_dev;
38caee9d
S
145
146 mutex_lock(&hnae3_common_lock);
147 /* un-initialize the client on every matched port */
148 list_for_each_entry(ae_dev, &hnae3_ae_dev_list, node) {
90f7b11a 149 hnae3_match_n_instantiate(client, ae_dev, false);
38caee9d
S
150 }
151
152 list_del(&client->node);
153 mutex_unlock(&hnae3_common_lock);
154}
155EXPORT_SYMBOL(hnae3_unregister_client);
156
157/* hnae3_register_ae_algo - register a AE algorithm to hnae3 framework
158 * @ae_algo: AE algorithm
159 * NOTE: the duplicated name will not be checked
160 */
a4d090cc 161void hnae3_register_ae_algo(struct hnae3_ae_algo *ae_algo)
38caee9d
S
162{
163 const struct pci_device_id *id;
164 struct hnae3_ae_dev *ae_dev;
165 struct hnae3_client *client;
38caee9d
S
166 int ret = 0;
167
168 mutex_lock(&hnae3_common_lock);
169
170 list_add_tail(&ae_algo->node, &hnae3_ae_algo_list);
171
172 /* Check if this algo/ops matches the list of ae_devs */
173 list_for_each_entry(ae_dev, &hnae3_ae_dev_list, node) {
174 id = pci_match_id(ae_algo->pdev_id_table, ae_dev->pdev);
175 if (!id)
176 continue;
177
178 /* ae_dev init should set flag */
179 ae_dev->ops = ae_algo->ops;
180 ret = ae_algo->ops->init_ae_dev(ae_dev);
181 if (ret) {
31ce0f41
PL
182 dev_err(&ae_dev->pdev->dev,
183 "init ae_dev error, ret = %d\n", ret);
38caee9d
S
184 continue;
185 }
186
e22b531b 187 hnae3_set_bit(ae_dev->flag, HNAE3_DEV_INITED_B, 1);
38caee9d
S
188
189 /* check the client list for the match with this ae_dev type and
190 * initialize the figure out client instance
191 */
192 list_for_each_entry(client, &hnae3_client_list, node) {
90f7b11a 193 ret = hnae3_match_n_instantiate(client, ae_dev, true);
38caee9d
S
194 if (ret)
195 dev_err(&ae_dev->pdev->dev,
31ce0f41
PL
196 "match and instantiation failed, ret = %d\n",
197 ret);
38caee9d
S
198 }
199 }
200
201 mutex_unlock(&hnae3_common_lock);
38caee9d
S
202}
203EXPORT_SYMBOL(hnae3_register_ae_algo);
204
205/* hnae3_unregister_ae_algo - unregisters a AE algorithm
206 * @ae_algo: the AE algorithm to unregister
207 */
208void hnae3_unregister_ae_algo(struct hnae3_ae_algo *ae_algo)
209{
210 const struct pci_device_id *id;
211 struct hnae3_ae_dev *ae_dev;
212 struct hnae3_client *client;
38caee9d
S
213
214 mutex_lock(&hnae3_common_lock);
215 /* Check if there are matched ae_dev */
216 list_for_each_entry(ae_dev, &hnae3_ae_dev_list, node) {
e22b531b 217 if (!hnae3_get_bit(ae_dev->flag, HNAE3_DEV_INITED_B))
6c46284e
FL
218 continue;
219
38caee9d
S
220 id = pci_match_id(ae_algo->pdev_id_table, ae_dev->pdev);
221 if (!id)
222 continue;
223
224 /* check the client list for the match with this ae_dev type and
225 * un-initialize the figure out client instance
226 */
90f7b11a
L
227 list_for_each_entry(client, &hnae3_client_list, node)
228 hnae3_match_n_instantiate(client, ae_dev, false);
38caee9d
S
229
230 ae_algo->ops->uninit_ae_dev(ae_dev);
e22b531b 231 hnae3_set_bit(ae_dev->flag, HNAE3_DEV_INITED_B, 0);
38caee9d
S
232 }
233
234 list_del(&ae_algo->node);
235 mutex_unlock(&hnae3_common_lock);
236}
237EXPORT_SYMBOL(hnae3_unregister_ae_algo);
238
239/* hnae3_register_ae_dev - registers a AE device to hnae3 framework
240 * @ae_dev: the AE device
241 * NOTE: the duplicated name will not be checked
242 */
fb919349 243void hnae3_register_ae_dev(struct hnae3_ae_dev *ae_dev)
38caee9d
S
244{
245 const struct pci_device_id *id;
246 struct hnae3_ae_algo *ae_algo;
247 struct hnae3_client *client;
bc59f827 248 int ret = 0;
a9c89a3f 249
bc59f827 250 mutex_lock(&hnae3_common_lock);
38caee9d 251
38caee9d
S
252 list_add_tail(&ae_dev->node, &hnae3_ae_dev_list);
253
254 /* Check if there are matched ae_algo */
255 list_for_each_entry(ae_algo, &hnae3_ae_algo_list, node) {
256 id = pci_match_id(ae_algo->pdev_id_table, ae_dev->pdev);
257 if (!id)
258 continue;
259
260 ae_dev->ops = ae_algo->ops;
261
262 if (!ae_dev->ops) {
263 dev_err(&ae_dev->pdev->dev, "ae_dev ops are null\n");
264 goto out_err;
265 }
266
267 /* ae_dev init should set flag */
268 ret = ae_dev->ops->init_ae_dev(ae_dev);
269 if (ret) {
31ce0f41
PL
270 dev_err(&ae_dev->pdev->dev,
271 "init ae_dev error, ret = %d\n", ret);
38caee9d
S
272 goto out_err;
273 }
274
e22b531b 275 hnae3_set_bit(ae_dev->flag, HNAE3_DEV_INITED_B, 1);
38caee9d
S
276 break;
277 }
278
279 /* check the client list for the match with this ae_dev type and
280 * initialize the figure out client instance
281 */
282 list_for_each_entry(client, &hnae3_client_list, node) {
90f7b11a 283 ret = hnae3_match_n_instantiate(client, ae_dev, true);
38caee9d
S
284 if (ret)
285 dev_err(&ae_dev->pdev->dev,
31ce0f41
PL
286 "match and instantiation failed, ret = %d\n",
287 ret);
38caee9d
S
288 }
289
290out_err:
291 mutex_unlock(&hnae3_common_lock);
38caee9d
S
292}
293EXPORT_SYMBOL(hnae3_register_ae_dev);
294
295/* hnae3_unregister_ae_dev - unregisters a AE device
296 * @ae_dev: the AE device to unregister
297 */
298void hnae3_unregister_ae_dev(struct hnae3_ae_dev *ae_dev)
299{
300 const struct pci_device_id *id;
301 struct hnae3_ae_algo *ae_algo;
302 struct hnae3_client *client;
38caee9d
S
303
304 mutex_lock(&hnae3_common_lock);
305 /* Check if there are matched ae_algo */
306 list_for_each_entry(ae_algo, &hnae3_ae_algo_list, node) {
e22b531b 307 if (!hnae3_get_bit(ae_dev->flag, HNAE3_DEV_INITED_B))
6c46284e
FL
308 continue;
309
38caee9d
S
310 id = pci_match_id(ae_algo->pdev_id_table, ae_dev->pdev);
311 if (!id)
312 continue;
313
90f7b11a
L
314 list_for_each_entry(client, &hnae3_client_list, node)
315 hnae3_match_n_instantiate(client, ae_dev, false);
38caee9d
S
316
317 ae_algo->ops->uninit_ae_dev(ae_dev);
e22b531b 318 hnae3_set_bit(ae_dev->flag, HNAE3_DEV_INITED_B, 0);
38caee9d
S
319 }
320
321 list_del(&ae_dev->node);
322 mutex_unlock(&hnae3_common_lock);
323}
324EXPORT_SYMBOL(hnae3_unregister_ae_dev);
325
326MODULE_AUTHOR("Huawei Tech. Co., Ltd.");
327MODULE_LICENSE("GPL");
328MODULE_DESCRIPTION("HNAE3(Hisilicon Network Acceleration Engine) Framework");
4786ad87 329MODULE_VERSION(HNAE3_MOD_VERSION);