1 // SPDX-License-Identifier: GPL-2.0+
2 // Copyright (c) 2016-2017 Hisilicon Limited.
4 #include <linux/list.h>
5 #include <linux/spinlock.h>
9 static LIST_HEAD(hnae3_ae_algo_list);
10 static LIST_HEAD(hnae3_client_list);
11 static LIST_HEAD(hnae3_ae_dev_list);
13 void hnae3_unregister_ae_algo_prepare(struct hnae3_ae_algo *ae_algo)
15 const struct pci_device_id *pci_id;
16 struct hnae3_ae_dev *ae_dev;
21 list_for_each_entry(ae_dev, &hnae3_ae_dev_list, node) {
22 if (!hnae3_get_bit(ae_dev->flag, HNAE3_DEV_INITED_B))
25 pci_id = pci_match_id(ae_algo->pdev_id_table, ae_dev->pdev);
28 if (IS_ENABLED(CONFIG_PCI_IOV))
29 pci_disable_sriov(ae_dev->pdev);
32 EXPORT_SYMBOL(hnae3_unregister_ae_algo_prepare);
34 /* we are keeping things simple and using single lock for all the
35 * list. This is a non-critical code so other updations, if happen
36 * in parallel, can wait.
38 static DEFINE_MUTEX(hnae3_common_lock);
40 static bool hnae3_client_match(enum hnae3_client_type client_type,
41 enum hnae3_dev_type dev_type)
43 if ((dev_type == HNAE3_DEV_KNIC) && (client_type == HNAE3_CLIENT_KNIC ||
44 client_type == HNAE3_CLIENT_ROCE))
47 if (dev_type == HNAE3_DEV_UNIC && client_type == HNAE3_CLIENT_UNIC)
53 void hnae3_set_client_init_flag(struct hnae3_client *client,
54 struct hnae3_ae_dev *ae_dev, int inited)
56 switch (client->type) {
57 case HNAE3_CLIENT_KNIC:
58 hnae3_set_bit(ae_dev->flag, HNAE3_KNIC_CLIENT_INITED_B, inited);
60 case HNAE3_CLIENT_UNIC:
61 hnae3_set_bit(ae_dev->flag, HNAE3_UNIC_CLIENT_INITED_B, inited);
63 case HNAE3_CLIENT_ROCE:
64 hnae3_set_bit(ae_dev->flag, HNAE3_ROCE_CLIENT_INITED_B, inited);
70 EXPORT_SYMBOL(hnae3_set_client_init_flag);
72 static int hnae3_get_client_init_flag(struct hnae3_client *client,
73 struct hnae3_ae_dev *ae_dev)
77 switch (client->type) {
78 case HNAE3_CLIENT_KNIC:
79 inited = hnae3_get_bit(ae_dev->flag,
80 HNAE3_KNIC_CLIENT_INITED_B);
82 case HNAE3_CLIENT_UNIC:
83 inited = hnae3_get_bit(ae_dev->flag,
84 HNAE3_UNIC_CLIENT_INITED_B);
86 case HNAE3_CLIENT_ROCE:
87 inited = hnae3_get_bit(ae_dev->flag,
88 HNAE3_ROCE_CLIENT_INITED_B);
97 static int hnae3_match_n_instantiate(struct hnae3_client *client,
98 struct hnae3_ae_dev *ae_dev, bool is_reg)
102 /* check if this client matches the type of ae_dev */
103 if (!(hnae3_client_match(client->type, ae_dev->dev_type) &&
104 hnae3_get_bit(ae_dev->flag, HNAE3_DEV_INITED_B))) {
108 /* now, (un-)instantiate client by calling lower layer */
110 ret = ae_dev->ops->init_client_instance(client, ae_dev);
112 dev_err(&ae_dev->pdev->dev,
113 "fail to instantiate client, ret = %d\n", ret);
118 if (hnae3_get_client_init_flag(client, ae_dev)) {
119 ae_dev->ops->uninit_client_instance(client, ae_dev);
121 hnae3_set_client_init_flag(client, ae_dev, 0);
127 int hnae3_register_client(struct hnae3_client *client)
129 struct hnae3_client *client_tmp;
130 struct hnae3_ae_dev *ae_dev;
133 mutex_lock(&hnae3_common_lock);
134 /* one system should only have one client for every type */
135 list_for_each_entry(client_tmp, &hnae3_client_list, node) {
136 if (client_tmp->type == client->type)
140 list_add_tail(&client->node, &hnae3_client_list);
142 /* initialize the client on every matched port */
143 list_for_each_entry(ae_dev, &hnae3_ae_dev_list, node) {
144 /* if the client could not be initialized on current port, for
145 * any error reasons, move on to next available port
147 ret = hnae3_match_n_instantiate(client, ae_dev, true);
149 dev_err(&ae_dev->pdev->dev,
150 "match and instantiation failed for port, ret = %d\n",
155 mutex_unlock(&hnae3_common_lock);
159 EXPORT_SYMBOL(hnae3_register_client);
161 void hnae3_unregister_client(struct hnae3_client *client)
163 struct hnae3_ae_dev *ae_dev;
165 mutex_lock(&hnae3_common_lock);
166 /* un-initialize the client on every matched port */
167 list_for_each_entry(ae_dev, &hnae3_ae_dev_list, node) {
168 hnae3_match_n_instantiate(client, ae_dev, false);
171 list_del(&client->node);
172 mutex_unlock(&hnae3_common_lock);
174 EXPORT_SYMBOL(hnae3_unregister_client);
176 /* hnae3_register_ae_algo - register a AE algorithm to hnae3 framework
177 * @ae_algo: AE algorithm
178 * NOTE: the duplicated name will not be checked
180 void hnae3_register_ae_algo(struct hnae3_ae_algo *ae_algo)
182 const struct pci_device_id *id;
183 struct hnae3_ae_dev *ae_dev;
184 struct hnae3_client *client;
187 mutex_lock(&hnae3_common_lock);
189 list_add_tail(&ae_algo->node, &hnae3_ae_algo_list);
191 /* Check if this algo/ops matches the list of ae_devs */
192 list_for_each_entry(ae_dev, &hnae3_ae_dev_list, node) {
193 id = pci_match_id(ae_algo->pdev_id_table, ae_dev->pdev);
198 dev_err(&ae_dev->pdev->dev, "ae_algo ops are null\n");
201 ae_dev->ops = ae_algo->ops;
203 ret = ae_algo->ops->init_ae_dev(ae_dev);
205 dev_err(&ae_dev->pdev->dev,
206 "init ae_dev error, ret = %d\n", ret);
210 /* ae_dev init should set flag */
211 hnae3_set_bit(ae_dev->flag, HNAE3_DEV_INITED_B, 1);
213 /* check the client list for the match with this ae_dev type and
214 * initialize the figure out client instance
216 list_for_each_entry(client, &hnae3_client_list, node) {
217 ret = hnae3_match_n_instantiate(client, ae_dev, true);
219 dev_err(&ae_dev->pdev->dev,
220 "match and instantiation failed, ret = %d\n",
225 mutex_unlock(&hnae3_common_lock);
227 EXPORT_SYMBOL(hnae3_register_ae_algo);
229 /* hnae3_unregister_ae_algo - unregisters a AE algorithm
230 * @ae_algo: the AE algorithm to unregister
232 void hnae3_unregister_ae_algo(struct hnae3_ae_algo *ae_algo)
234 const struct pci_device_id *id;
235 struct hnae3_ae_dev *ae_dev;
236 struct hnae3_client *client;
238 mutex_lock(&hnae3_common_lock);
239 /* Check if there are matched ae_dev */
240 list_for_each_entry(ae_dev, &hnae3_ae_dev_list, node) {
241 if (!hnae3_get_bit(ae_dev->flag, HNAE3_DEV_INITED_B))
244 id = pci_match_id(ae_algo->pdev_id_table, ae_dev->pdev);
248 /* check the client list for the match with this ae_dev type and
249 * un-initialize the figure out client instance
251 list_for_each_entry(client, &hnae3_client_list, node)
252 hnae3_match_n_instantiate(client, ae_dev, false);
254 ae_algo->ops->uninit_ae_dev(ae_dev);
255 hnae3_set_bit(ae_dev->flag, HNAE3_DEV_INITED_B, 0);
259 list_del(&ae_algo->node);
260 mutex_unlock(&hnae3_common_lock);
262 EXPORT_SYMBOL(hnae3_unregister_ae_algo);
264 /* hnae3_register_ae_dev - registers a AE device to hnae3 framework
265 * @ae_dev: the AE device
266 * NOTE: the duplicated name will not be checked
268 int hnae3_register_ae_dev(struct hnae3_ae_dev *ae_dev)
270 const struct pci_device_id *id;
271 struct hnae3_ae_algo *ae_algo;
272 struct hnae3_client *client;
275 mutex_lock(&hnae3_common_lock);
277 list_add_tail(&ae_dev->node, &hnae3_ae_dev_list);
279 /* Check if there are matched ae_algo */
280 list_for_each_entry(ae_algo, &hnae3_ae_algo_list, node) {
281 id = pci_match_id(ae_algo->pdev_id_table, ae_dev->pdev);
286 dev_err(&ae_dev->pdev->dev, "ae_algo ops are null\n");
290 ae_dev->ops = ae_algo->ops;
292 ret = ae_dev->ops->init_ae_dev(ae_dev);
294 dev_err(&ae_dev->pdev->dev,
295 "init ae_dev error, ret = %d\n", ret);
299 /* ae_dev init should set flag */
300 hnae3_set_bit(ae_dev->flag, HNAE3_DEV_INITED_B, 1);
304 /* check the client list for the match with this ae_dev type and
305 * initialize the figure out client instance
307 list_for_each_entry(client, &hnae3_client_list, node) {
308 ret = hnae3_match_n_instantiate(client, ae_dev, true);
310 dev_err(&ae_dev->pdev->dev,
311 "match and instantiation failed, ret = %d\n",
315 mutex_unlock(&hnae3_common_lock);
320 list_del(&ae_dev->node);
321 mutex_unlock(&hnae3_common_lock);
325 EXPORT_SYMBOL(hnae3_register_ae_dev);
327 /* hnae3_unregister_ae_dev - unregisters a AE device
328 * @ae_dev: the AE device to unregister
330 void hnae3_unregister_ae_dev(struct hnae3_ae_dev *ae_dev)
332 const struct pci_device_id *id;
333 struct hnae3_ae_algo *ae_algo;
334 struct hnae3_client *client;
336 mutex_lock(&hnae3_common_lock);
337 /* Check if there are matched ae_algo */
338 list_for_each_entry(ae_algo, &hnae3_ae_algo_list, node) {
339 if (!hnae3_get_bit(ae_dev->flag, HNAE3_DEV_INITED_B))
342 id = pci_match_id(ae_algo->pdev_id_table, ae_dev->pdev);
346 list_for_each_entry(client, &hnae3_client_list, node)
347 hnae3_match_n_instantiate(client, ae_dev, false);
349 ae_algo->ops->uninit_ae_dev(ae_dev);
350 hnae3_set_bit(ae_dev->flag, HNAE3_DEV_INITED_B, 0);
354 list_del(&ae_dev->node);
355 mutex_unlock(&hnae3_common_lock);
357 EXPORT_SYMBOL(hnae3_unregister_ae_dev);
359 MODULE_AUTHOR("Huawei Tech. Co., Ltd.");
360 MODULE_LICENSE("GPL");
361 MODULE_DESCRIPTION("HNAE3(Hisilicon Network Acceleration Engine) Framework");
362 MODULE_VERSION(HNAE3_MOD_VERSION);