2 * Copyright (c) 2016-2017 Hisilicon Limited.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
10 #include <linux/list.h>
11 #include <linux/spinlock.h>
15 static LIST_HEAD(hnae3_ae_algo_list
);
16 static LIST_HEAD(hnae3_client_list
);
17 static LIST_HEAD(hnae3_ae_dev_list
);
19 /* we are keeping things simple and using single lock for all the
20 * list. This is a non-critical code so other updations, if happen
21 * in parallel, can wait.
23 static DEFINE_MUTEX(hnae3_common_lock
);
25 static bool hnae3_client_match(enum hnae3_client_type client_type
,
26 enum hnae3_dev_type dev_type
)
28 if ((dev_type
== HNAE3_DEV_KNIC
) && (client_type
== HNAE3_CLIENT_KNIC
||
29 client_type
== HNAE3_CLIENT_ROCE
))
32 if (dev_type
== HNAE3_DEV_UNIC
&& client_type
== HNAE3_CLIENT_UNIC
)
38 static void hnae3_set_client_init_flag(struct hnae3_client
*client
,
39 struct hnae3_ae_dev
*ae_dev
, int inited
)
41 switch (client
->type
) {
42 case HNAE3_CLIENT_KNIC
:
43 hnae_set_bit(ae_dev
->flag
, HNAE3_KNIC_CLIENT_INITED_B
, inited
);
45 case HNAE3_CLIENT_UNIC
:
46 hnae_set_bit(ae_dev
->flag
, HNAE3_UNIC_CLIENT_INITED_B
, inited
);
48 case HNAE3_CLIENT_ROCE
:
49 hnae_set_bit(ae_dev
->flag
, HNAE3_ROCE_CLIENT_INITED_B
, inited
);
56 static int hnae3_get_client_init_flag(struct hnae3_client
*client
,
57 struct hnae3_ae_dev
*ae_dev
)
61 switch (client
->type
) {
62 case HNAE3_CLIENT_KNIC
:
63 inited
= hnae_get_bit(ae_dev
->flag
,
64 HNAE3_KNIC_CLIENT_INITED_B
);
66 case HNAE3_CLIENT_UNIC
:
67 inited
= hnae_get_bit(ae_dev
->flag
,
68 HNAE3_UNIC_CLIENT_INITED_B
);
70 case HNAE3_CLIENT_ROCE
:
71 inited
= hnae_get_bit(ae_dev
->flag
,
72 HNAE3_ROCE_CLIENT_INITED_B
);
81 static int hnae3_match_n_instantiate(struct hnae3_client
*client
,
82 struct hnae3_ae_dev
*ae_dev
, bool is_reg
)
86 /* check if this client matches the type of ae_dev */
87 if (!(hnae3_client_match(client
->type
, ae_dev
->dev_type
) &&
88 hnae_get_bit(ae_dev
->flag
, HNAE3_DEV_INITED_B
))) {
92 /* now, (un-)instantiate client by calling lower layer */
94 ret
= ae_dev
->ops
->init_client_instance(client
, ae_dev
);
96 dev_err(&ae_dev
->pdev
->dev
,
97 "fail to instantiate client, ret = %d\n", ret
);
101 hnae3_set_client_init_flag(client
, ae_dev
, 1);
105 if (hnae3_get_client_init_flag(client
, ae_dev
)) {
106 ae_dev
->ops
->uninit_client_instance(client
, ae_dev
);
108 hnae3_set_client_init_flag(client
, ae_dev
, 0);
114 int hnae3_register_client(struct hnae3_client
*client
)
116 struct hnae3_client
*client_tmp
;
117 struct hnae3_ae_dev
*ae_dev
;
120 mutex_lock(&hnae3_common_lock
);
121 /* one system should only have one client for every type */
122 list_for_each_entry(client_tmp
, &hnae3_client_list
, node
) {
123 if (client_tmp
->type
== client
->type
)
127 list_add_tail(&client
->node
, &hnae3_client_list
);
129 /* initialize the client on every matched port */
130 list_for_each_entry(ae_dev
, &hnae3_ae_dev_list
, node
) {
131 /* if the client could not be initialized on current port, for
132 * any error reasons, move on to next available port
134 ret
= hnae3_match_n_instantiate(client
, ae_dev
, true);
136 dev_err(&ae_dev
->pdev
->dev
,
137 "match and instantiation failed for port, ret = %d\n",
142 mutex_unlock(&hnae3_common_lock
);
146 EXPORT_SYMBOL(hnae3_register_client
);
148 void hnae3_unregister_client(struct hnae3_client
*client
)
150 struct hnae3_ae_dev
*ae_dev
;
152 mutex_lock(&hnae3_common_lock
);
153 /* un-initialize the client on every matched port */
154 list_for_each_entry(ae_dev
, &hnae3_ae_dev_list
, node
) {
155 hnae3_match_n_instantiate(client
, ae_dev
, false);
158 list_del(&client
->node
);
159 mutex_unlock(&hnae3_common_lock
);
161 EXPORT_SYMBOL(hnae3_unregister_client
);
163 /* hnae3_register_ae_algo - register a AE algorithm to hnae3 framework
164 * @ae_algo: AE algorithm
165 * NOTE: the duplicated name will not be checked
167 void hnae3_register_ae_algo(struct hnae3_ae_algo
*ae_algo
)
169 const struct pci_device_id
*id
;
170 struct hnae3_ae_dev
*ae_dev
;
171 struct hnae3_client
*client
;
174 mutex_lock(&hnae3_common_lock
);
176 list_add_tail(&ae_algo
->node
, &hnae3_ae_algo_list
);
178 /* Check if this algo/ops matches the list of ae_devs */
179 list_for_each_entry(ae_dev
, &hnae3_ae_dev_list
, node
) {
180 id
= pci_match_id(ae_algo
->pdev_id_table
, ae_dev
->pdev
);
184 /* ae_dev init should set flag */
185 ae_dev
->ops
= ae_algo
->ops
;
186 ret
= ae_algo
->ops
->init_ae_dev(ae_dev
);
188 dev_err(&ae_dev
->pdev
->dev
,
189 "init ae_dev error, ret = %d\n", ret
);
193 hnae_set_bit(ae_dev
->flag
, HNAE3_DEV_INITED_B
, 1);
195 /* check the client list for the match with this ae_dev type and
196 * initialize the figure out client instance
198 list_for_each_entry(client
, &hnae3_client_list
, node
) {
199 ret
= hnae3_match_n_instantiate(client
, ae_dev
, true);
201 dev_err(&ae_dev
->pdev
->dev
,
202 "match and instantiation failed, ret = %d\n",
207 mutex_unlock(&hnae3_common_lock
);
209 EXPORT_SYMBOL(hnae3_register_ae_algo
);
211 /* hnae3_unregister_ae_algo - unregisters a AE algorithm
212 * @ae_algo: the AE algorithm to unregister
214 void hnae3_unregister_ae_algo(struct hnae3_ae_algo
*ae_algo
)
216 const struct pci_device_id
*id
;
217 struct hnae3_ae_dev
*ae_dev
;
218 struct hnae3_client
*client
;
220 mutex_lock(&hnae3_common_lock
);
221 /* Check if there are matched ae_dev */
222 list_for_each_entry(ae_dev
, &hnae3_ae_dev_list
, node
) {
223 if (!hnae_get_bit(ae_dev
->flag
, HNAE3_DEV_INITED_B
))
226 id
= pci_match_id(ae_algo
->pdev_id_table
, ae_dev
->pdev
);
230 /* check the client list for the match with this ae_dev type and
231 * un-initialize the figure out client instance
233 list_for_each_entry(client
, &hnae3_client_list
, node
)
234 hnae3_match_n_instantiate(client
, ae_dev
, false);
236 ae_algo
->ops
->uninit_ae_dev(ae_dev
);
237 hnae_set_bit(ae_dev
->flag
, HNAE3_DEV_INITED_B
, 0);
240 list_del(&ae_algo
->node
);
241 mutex_unlock(&hnae3_common_lock
);
243 EXPORT_SYMBOL(hnae3_unregister_ae_algo
);
245 /* hnae3_register_ae_dev - registers a AE device to hnae3 framework
246 * @ae_dev: the AE device
247 * NOTE: the duplicated name will not be checked
249 void hnae3_register_ae_dev(struct hnae3_ae_dev
*ae_dev
)
251 const struct pci_device_id
*id
;
252 struct hnae3_ae_algo
*ae_algo
;
253 struct hnae3_client
*client
;
256 mutex_lock(&hnae3_common_lock
);
258 list_add_tail(&ae_dev
->node
, &hnae3_ae_dev_list
);
260 /* Check if there are matched ae_algo */
261 list_for_each_entry(ae_algo
, &hnae3_ae_algo_list
, node
) {
262 id
= pci_match_id(ae_algo
->pdev_id_table
, ae_dev
->pdev
);
266 ae_dev
->ops
= ae_algo
->ops
;
269 dev_err(&ae_dev
->pdev
->dev
, "ae_dev ops are null\n");
273 /* ae_dev init should set flag */
274 ret
= ae_dev
->ops
->init_ae_dev(ae_dev
);
276 dev_err(&ae_dev
->pdev
->dev
,
277 "init ae_dev error, ret = %d\n", ret
);
281 hnae_set_bit(ae_dev
->flag
, HNAE3_DEV_INITED_B
, 1);
285 /* check the client list for the match with this ae_dev type and
286 * initialize the figure out client instance
288 list_for_each_entry(client
, &hnae3_client_list
, node
) {
289 ret
= hnae3_match_n_instantiate(client
, ae_dev
, true);
291 dev_err(&ae_dev
->pdev
->dev
,
292 "match and instantiation failed, ret = %d\n",
297 mutex_unlock(&hnae3_common_lock
);
299 EXPORT_SYMBOL(hnae3_register_ae_dev
);
301 /* hnae3_unregister_ae_dev - unregisters a AE device
302 * @ae_dev: the AE device to unregister
304 void hnae3_unregister_ae_dev(struct hnae3_ae_dev
*ae_dev
)
306 const struct pci_device_id
*id
;
307 struct hnae3_ae_algo
*ae_algo
;
308 struct hnae3_client
*client
;
310 mutex_lock(&hnae3_common_lock
);
311 /* Check if there are matched ae_algo */
312 list_for_each_entry(ae_algo
, &hnae3_ae_algo_list
, node
) {
313 if (!hnae_get_bit(ae_dev
->flag
, HNAE3_DEV_INITED_B
))
316 id
= pci_match_id(ae_algo
->pdev_id_table
, ae_dev
->pdev
);
320 list_for_each_entry(client
, &hnae3_client_list
, node
)
321 hnae3_match_n_instantiate(client
, ae_dev
, false);
323 ae_algo
->ops
->uninit_ae_dev(ae_dev
);
324 hnae_set_bit(ae_dev
->flag
, HNAE3_DEV_INITED_B
, 0);
327 list_del(&ae_dev
->node
);
328 mutex_unlock(&hnae3_common_lock
);
330 EXPORT_SYMBOL(hnae3_unregister_ae_dev
);
332 MODULE_AUTHOR("Huawei Tech. Co., Ltd.");
333 MODULE_LICENSE("GPL");
334 MODULE_DESCRIPTION("HNAE3(Hisilicon Network Acceleration Engine) Framework");
335 MODULE_VERSION(HNAE3_MOD_VERSION
);