0001
0002
0003
0004 #include <linux/list.h>
0005 #include <linux/spinlock.h>
0006
0007 #include "hnae3.h"
0008
0009 static LIST_HEAD(hnae3_ae_algo_list);
0010 static LIST_HEAD(hnae3_client_list);
0011 static LIST_HEAD(hnae3_ae_dev_list);
0012
0013 void hnae3_unregister_ae_algo_prepare(struct hnae3_ae_algo *ae_algo)
0014 {
0015 const struct pci_device_id *pci_id;
0016 struct hnae3_ae_dev *ae_dev;
0017
0018 if (!ae_algo)
0019 return;
0020
0021 list_for_each_entry(ae_dev, &hnae3_ae_dev_list, node) {
0022 if (!hnae3_get_bit(ae_dev->flag, HNAE3_DEV_INITED_B))
0023 continue;
0024
0025 pci_id = pci_match_id(ae_algo->pdev_id_table, ae_dev->pdev);
0026 if (!pci_id)
0027 continue;
0028 if (IS_ENABLED(CONFIG_PCI_IOV))
0029 pci_disable_sriov(ae_dev->pdev);
0030 }
0031 }
0032 EXPORT_SYMBOL(hnae3_unregister_ae_algo_prepare);
0033
0034
0035
0036
0037
0038 static DEFINE_MUTEX(hnae3_common_lock);
0039
0040 static bool hnae3_client_match(enum hnae3_client_type client_type)
0041 {
0042 if (client_type == HNAE3_CLIENT_KNIC ||
0043 client_type == HNAE3_CLIENT_ROCE)
0044 return true;
0045
0046 return false;
0047 }
0048
0049 void hnae3_set_client_init_flag(struct hnae3_client *client,
0050 struct hnae3_ae_dev *ae_dev,
0051 unsigned int inited)
0052 {
0053 if (!client || !ae_dev)
0054 return;
0055
0056 switch (client->type) {
0057 case HNAE3_CLIENT_KNIC:
0058 hnae3_set_bit(ae_dev->flag, HNAE3_KNIC_CLIENT_INITED_B, inited);
0059 break;
0060 case HNAE3_CLIENT_ROCE:
0061 hnae3_set_bit(ae_dev->flag, HNAE3_ROCE_CLIENT_INITED_B, inited);
0062 break;
0063 default:
0064 break;
0065 }
0066 }
0067 EXPORT_SYMBOL(hnae3_set_client_init_flag);
0068
0069 static int hnae3_get_client_init_flag(struct hnae3_client *client,
0070 struct hnae3_ae_dev *ae_dev)
0071 {
0072 int inited = 0;
0073
0074 switch (client->type) {
0075 case HNAE3_CLIENT_KNIC:
0076 inited = hnae3_get_bit(ae_dev->flag,
0077 HNAE3_KNIC_CLIENT_INITED_B);
0078 break;
0079 case HNAE3_CLIENT_ROCE:
0080 inited = hnae3_get_bit(ae_dev->flag,
0081 HNAE3_ROCE_CLIENT_INITED_B);
0082 break;
0083 default:
0084 break;
0085 }
0086
0087 return inited;
0088 }
0089
0090 static int hnae3_init_client_instance(struct hnae3_client *client,
0091 struct hnae3_ae_dev *ae_dev)
0092 {
0093 int ret;
0094
0095
0096 if (!(hnae3_client_match(client->type) &&
0097 hnae3_get_bit(ae_dev->flag, HNAE3_DEV_INITED_B))) {
0098 return 0;
0099 }
0100
0101 ret = ae_dev->ops->init_client_instance(client, ae_dev);
0102 if (ret)
0103 dev_err(&ae_dev->pdev->dev,
0104 "fail to instantiate client, ret = %d\n", ret);
0105
0106 return ret;
0107 }
0108
0109 static void hnae3_uninit_client_instance(struct hnae3_client *client,
0110 struct hnae3_ae_dev *ae_dev)
0111 {
0112
0113 if (!(hnae3_client_match(client->type) &&
0114 hnae3_get_bit(ae_dev->flag, HNAE3_DEV_INITED_B)))
0115 return;
0116
0117 if (hnae3_get_client_init_flag(client, ae_dev)) {
0118 ae_dev->ops->uninit_client_instance(client, ae_dev);
0119
0120 hnae3_set_client_init_flag(client, ae_dev, 0);
0121 }
0122 }
0123
0124 int hnae3_register_client(struct hnae3_client *client)
0125 {
0126 struct hnae3_client *client_tmp;
0127 struct hnae3_ae_dev *ae_dev;
0128
0129 if (!client)
0130 return -ENODEV;
0131
0132 mutex_lock(&hnae3_common_lock);
0133
0134 list_for_each_entry(client_tmp, &hnae3_client_list, node) {
0135 if (client_tmp->type == client->type)
0136 goto exit;
0137 }
0138
0139 list_add_tail(&client->node, &hnae3_client_list);
0140
0141
0142 list_for_each_entry(ae_dev, &hnae3_ae_dev_list, node) {
0143
0144
0145
0146 int ret = hnae3_init_client_instance(client, ae_dev);
0147 if (ret)
0148 dev_err(&ae_dev->pdev->dev,
0149 "match and instantiation failed for port, ret = %d\n",
0150 ret);
0151 }
0152
0153 exit:
0154 mutex_unlock(&hnae3_common_lock);
0155
0156 return 0;
0157 }
0158 EXPORT_SYMBOL(hnae3_register_client);
0159
0160 void hnae3_unregister_client(struct hnae3_client *client)
0161 {
0162 struct hnae3_client *client_tmp;
0163 struct hnae3_ae_dev *ae_dev;
0164 bool existed = false;
0165
0166 if (!client)
0167 return;
0168
0169 mutex_lock(&hnae3_common_lock);
0170
0171 list_for_each_entry(client_tmp, &hnae3_client_list, node) {
0172 if (client_tmp->type == client->type) {
0173 existed = true;
0174 break;
0175 }
0176 }
0177
0178 if (!existed) {
0179 mutex_unlock(&hnae3_common_lock);
0180 pr_err("client %s does not exist!\n", client->name);
0181 return;
0182 }
0183
0184
0185 list_for_each_entry(ae_dev, &hnae3_ae_dev_list, node) {
0186 hnae3_uninit_client_instance(client, ae_dev);
0187 }
0188
0189 list_del(&client->node);
0190 mutex_unlock(&hnae3_common_lock);
0191 }
0192 EXPORT_SYMBOL(hnae3_unregister_client);
0193
0194
0195
0196
0197
0198 void hnae3_register_ae_algo(struct hnae3_ae_algo *ae_algo)
0199 {
0200 const struct pci_device_id *id;
0201 struct hnae3_ae_dev *ae_dev;
0202 struct hnae3_client *client;
0203 int ret;
0204
0205 if (!ae_algo)
0206 return;
0207
0208 mutex_lock(&hnae3_common_lock);
0209
0210 list_add_tail(&ae_algo->node, &hnae3_ae_algo_list);
0211
0212
0213 list_for_each_entry(ae_dev, &hnae3_ae_dev_list, node) {
0214 id = pci_match_id(ae_algo->pdev_id_table, ae_dev->pdev);
0215 if (!id)
0216 continue;
0217
0218 if (!ae_algo->ops) {
0219 dev_err(&ae_dev->pdev->dev, "ae_algo ops are null\n");
0220 continue;
0221 }
0222 ae_dev->ops = ae_algo->ops;
0223
0224 ret = ae_algo->ops->init_ae_dev(ae_dev);
0225 if (ret) {
0226 dev_err(&ae_dev->pdev->dev,
0227 "init ae_dev error, ret = %d\n", ret);
0228 continue;
0229 }
0230
0231
0232 hnae3_set_bit(ae_dev->flag, HNAE3_DEV_INITED_B, 1);
0233
0234
0235
0236
0237 list_for_each_entry(client, &hnae3_client_list, node) {
0238 ret = hnae3_init_client_instance(client, ae_dev);
0239 if (ret)
0240 dev_err(&ae_dev->pdev->dev,
0241 "match and instantiation failed, ret = %d\n",
0242 ret);
0243 }
0244 }
0245
0246 mutex_unlock(&hnae3_common_lock);
0247 }
0248 EXPORT_SYMBOL(hnae3_register_ae_algo);
0249
0250
0251
0252
0253 void hnae3_unregister_ae_algo(struct hnae3_ae_algo *ae_algo)
0254 {
0255 const struct pci_device_id *id;
0256 struct hnae3_ae_dev *ae_dev;
0257 struct hnae3_client *client;
0258
0259 if (!ae_algo)
0260 return;
0261
0262 mutex_lock(&hnae3_common_lock);
0263
0264 list_for_each_entry(ae_dev, &hnae3_ae_dev_list, node) {
0265 if (!hnae3_get_bit(ae_dev->flag, HNAE3_DEV_INITED_B))
0266 continue;
0267
0268 id = pci_match_id(ae_algo->pdev_id_table, ae_dev->pdev);
0269 if (!id)
0270 continue;
0271
0272
0273
0274
0275 list_for_each_entry(client, &hnae3_client_list, node)
0276 hnae3_uninit_client_instance(client, ae_dev);
0277
0278 ae_algo->ops->uninit_ae_dev(ae_dev);
0279 hnae3_set_bit(ae_dev->flag, HNAE3_DEV_INITED_B, 0);
0280 ae_dev->ops = NULL;
0281 }
0282
0283 list_del(&ae_algo->node);
0284 mutex_unlock(&hnae3_common_lock);
0285 }
0286 EXPORT_SYMBOL(hnae3_unregister_ae_algo);
0287
0288
0289
0290
0291
0292 int hnae3_register_ae_dev(struct hnae3_ae_dev *ae_dev)
0293 {
0294 const struct pci_device_id *id;
0295 struct hnae3_ae_algo *ae_algo;
0296 struct hnae3_client *client;
0297 int ret;
0298
0299 if (!ae_dev)
0300 return -ENODEV;
0301
0302 mutex_lock(&hnae3_common_lock);
0303
0304 list_add_tail(&ae_dev->node, &hnae3_ae_dev_list);
0305
0306
0307 list_for_each_entry(ae_algo, &hnae3_ae_algo_list, node) {
0308 id = pci_match_id(ae_algo->pdev_id_table, ae_dev->pdev);
0309 if (!id)
0310 continue;
0311
0312 if (!ae_algo->ops) {
0313 dev_err(&ae_dev->pdev->dev, "ae_algo ops are null\n");
0314 ret = -EOPNOTSUPP;
0315 goto out_err;
0316 }
0317 ae_dev->ops = ae_algo->ops;
0318
0319 ret = ae_dev->ops->init_ae_dev(ae_dev);
0320 if (ret) {
0321 dev_err(&ae_dev->pdev->dev,
0322 "init ae_dev error, ret = %d\n", ret);
0323 goto out_err;
0324 }
0325
0326
0327 hnae3_set_bit(ae_dev->flag, HNAE3_DEV_INITED_B, 1);
0328 break;
0329 }
0330
0331
0332
0333
0334 list_for_each_entry(client, &hnae3_client_list, node) {
0335 ret = hnae3_init_client_instance(client, ae_dev);
0336 if (ret)
0337 dev_err(&ae_dev->pdev->dev,
0338 "match and instantiation failed, ret = %d\n",
0339 ret);
0340 }
0341
0342 mutex_unlock(&hnae3_common_lock);
0343
0344 return 0;
0345
0346 out_err:
0347 list_del(&ae_dev->node);
0348 mutex_unlock(&hnae3_common_lock);
0349
0350 return ret;
0351 }
0352 EXPORT_SYMBOL(hnae3_register_ae_dev);
0353
0354
0355
0356
0357 void hnae3_unregister_ae_dev(struct hnae3_ae_dev *ae_dev)
0358 {
0359 const struct pci_device_id *id;
0360 struct hnae3_ae_algo *ae_algo;
0361 struct hnae3_client *client;
0362
0363 if (!ae_dev)
0364 return;
0365
0366 mutex_lock(&hnae3_common_lock);
0367
0368 list_for_each_entry(ae_algo, &hnae3_ae_algo_list, node) {
0369 if (!hnae3_get_bit(ae_dev->flag, HNAE3_DEV_INITED_B))
0370 continue;
0371
0372 id = pci_match_id(ae_algo->pdev_id_table, ae_dev->pdev);
0373 if (!id)
0374 continue;
0375
0376 list_for_each_entry(client, &hnae3_client_list, node)
0377 hnae3_uninit_client_instance(client, ae_dev);
0378
0379 ae_algo->ops->uninit_ae_dev(ae_dev);
0380 hnae3_set_bit(ae_dev->flag, HNAE3_DEV_INITED_B, 0);
0381 ae_dev->ops = NULL;
0382 }
0383
0384 list_del(&ae_dev->node);
0385 mutex_unlock(&hnae3_common_lock);
0386 }
0387 EXPORT_SYMBOL(hnae3_unregister_ae_dev);
0388
0389 MODULE_AUTHOR("Huawei Tech. Co., Ltd.");
0390 MODULE_LICENSE("GPL");
0391 MODULE_DESCRIPTION("HNAE3(Hisilicon Network Acceleration Engine) Framework");
0392 MODULE_VERSION(HNAE3_MOD_VERSION);