erdma_main.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664
  1. // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
  2. /* Authors: Cheng Xu <chengyou@linux.alibaba.com> */
  3. /* Kai Shen <kaishen@linux.alibaba.com> */
  4. /* Copyright (c) 2020-2022, Alibaba Group. */
  5. #include <linux/module.h>
  6. #include <net/addrconf.h>
  7. #include <rdma/erdma-abi.h>
  8. #include "erdma.h"
  9. #include "erdma_cm.h"
  10. #include "erdma_verbs.h"
  11. MODULE_AUTHOR("Cheng Xu <chengyou@linux.alibaba.com>");
  12. MODULE_DESCRIPTION("Alibaba elasticRDMA adapter driver");
  13. MODULE_LICENSE("Dual BSD/GPL");
  14. static int erdma_netdev_event(struct notifier_block *nb, unsigned long event,
  15. void *arg)
  16. {
  17. struct net_device *netdev = netdev_notifier_info_to_dev(arg);
  18. struct erdma_dev *dev = container_of(nb, struct erdma_dev, netdev_nb);
  19. if (dev->netdev == NULL || dev->netdev != netdev)
  20. goto done;
  21. switch (event) {
  22. case NETDEV_UP:
  23. dev->state = IB_PORT_ACTIVE;
  24. erdma_port_event(dev, IB_EVENT_PORT_ACTIVE);
  25. break;
  26. case NETDEV_DOWN:
  27. dev->state = IB_PORT_DOWN;
  28. erdma_port_event(dev, IB_EVENT_PORT_ERR);
  29. break;
  30. case NETDEV_CHANGEMTU:
  31. if (dev->mtu != netdev->mtu) {
  32. erdma_set_mtu(dev, netdev->mtu);
  33. dev->mtu = netdev->mtu;
  34. }
  35. break;
  36. case NETDEV_REGISTER:
  37. case NETDEV_UNREGISTER:
  38. case NETDEV_CHANGEADDR:
  39. case NETDEV_GOING_DOWN:
  40. case NETDEV_CHANGE:
  41. default:
  42. break;
  43. }
  44. done:
  45. return NOTIFY_OK;
  46. }
  47. static int erdma_enum_and_get_netdev(struct erdma_dev *dev)
  48. {
  49. struct net_device *netdev;
  50. int ret = -EPROBE_DEFER;
  51. /* Already binded to a net_device, so we skip. */
  52. if (dev->netdev)
  53. return 0;
  54. rtnl_lock();
  55. for_each_netdev(&init_net, netdev) {
  56. /*
  57. * In erdma, the paired netdev and ibdev should have the same
  58. * MAC address. erdma can get the value from its PCIe bar
  59. * registers. Since erdma can not get the paired netdev
  60. * reference directly, we do a traverse here to get the paired
  61. * netdev.
  62. */
  63. if (ether_addr_equal_unaligned(netdev->perm_addr,
  64. dev->attrs.peer_addr)) {
  65. ret = ib_device_set_netdev(&dev->ibdev, netdev, 1);
  66. if (ret) {
  67. rtnl_unlock();
  68. ibdev_warn(&dev->ibdev,
  69. "failed (%d) to link netdev", ret);
  70. return ret;
  71. }
  72. dev->netdev = netdev;
  73. break;
  74. }
  75. }
  76. rtnl_unlock();
  77. return ret;
  78. }
  79. static int erdma_device_register(struct erdma_dev *dev)
  80. {
  81. struct ib_device *ibdev = &dev->ibdev;
  82. int ret;
  83. ret = erdma_enum_and_get_netdev(dev);
  84. if (ret)
  85. return ret;
  86. dev->mtu = dev->netdev->mtu;
  87. addrconf_addr_eui48((u8 *)&ibdev->node_guid, dev->netdev->dev_addr);
  88. ret = ib_register_device(ibdev, "erdma_%d", &dev->pdev->dev);
  89. if (ret) {
  90. dev_err(&dev->pdev->dev,
  91. "ib_register_device failed: ret = %d\n", ret);
  92. return ret;
  93. }
  94. dev->netdev_nb.notifier_call = erdma_netdev_event;
  95. ret = register_netdevice_notifier(&dev->netdev_nb);
  96. if (ret) {
  97. ibdev_err(&dev->ibdev, "failed to register notifier.\n");
  98. ib_unregister_device(ibdev);
  99. }
  100. return ret;
  101. }
  102. static irqreturn_t erdma_comm_irq_handler(int irq, void *data)
  103. {
  104. struct erdma_dev *dev = data;
  105. erdma_cmdq_completion_handler(&dev->cmdq);
  106. erdma_aeq_event_handler(dev);
  107. return IRQ_HANDLED;
  108. }
  109. static int erdma_request_vectors(struct erdma_dev *dev)
  110. {
  111. int expect_irq_num = min(num_possible_cpus() + 1, ERDMA_NUM_MSIX_VEC);
  112. int ret;
  113. ret = pci_alloc_irq_vectors(dev->pdev, 1, expect_irq_num, PCI_IRQ_MSIX);
  114. if (ret < 0) {
  115. dev_err(&dev->pdev->dev, "request irq vectors failed(%d)\n",
  116. ret);
  117. return ret;
  118. }
  119. dev->attrs.irq_num = ret;
  120. return 0;
  121. }
  122. static int erdma_comm_irq_init(struct erdma_dev *dev)
  123. {
  124. snprintf(dev->comm_irq.name, ERDMA_IRQNAME_SIZE, "erdma-common@pci:%s",
  125. pci_name(dev->pdev));
  126. dev->comm_irq.msix_vector =
  127. pci_irq_vector(dev->pdev, ERDMA_MSIX_VECTOR_CMDQ);
  128. cpumask_set_cpu(cpumask_first(cpumask_of_pcibus(dev->pdev->bus)),
  129. &dev->comm_irq.affinity_hint_mask);
  130. irq_set_affinity_hint(dev->comm_irq.msix_vector,
  131. &dev->comm_irq.affinity_hint_mask);
  132. return request_irq(dev->comm_irq.msix_vector, erdma_comm_irq_handler, 0,
  133. dev->comm_irq.name, dev);
  134. }
  135. static void erdma_comm_irq_uninit(struct erdma_dev *dev)
  136. {
  137. irq_set_affinity_hint(dev->comm_irq.msix_vector, NULL);
  138. free_irq(dev->comm_irq.msix_vector, dev);
  139. }
  140. static int erdma_device_init(struct erdma_dev *dev, struct pci_dev *pdev)
  141. {
  142. int ret;
  143. dev->resp_pool = dma_pool_create("erdma_resp_pool", &pdev->dev,
  144. ERDMA_HW_RESP_SIZE, ERDMA_HW_RESP_SIZE,
  145. 0);
  146. if (!dev->resp_pool)
  147. return -ENOMEM;
  148. dev->db_pool = dma_pool_create("erdma_db_pool", &pdev->dev,
  149. ERDMA_DB_SIZE, ERDMA_DB_SIZE, 0);
  150. if (!dev->db_pool) {
  151. ret = -ENOMEM;
  152. goto destroy_resp_pool;
  153. }
  154. ret = dma_set_mask_and_coherent(&pdev->dev,
  155. DMA_BIT_MASK(ERDMA_PCI_WIDTH));
  156. if (ret)
  157. goto destroy_db_pool;
  158. dma_set_max_seg_size(&pdev->dev, UINT_MAX);
  159. return 0;
  160. destroy_db_pool:
  161. dma_pool_destroy(dev->db_pool);
  162. destroy_resp_pool:
  163. dma_pool_destroy(dev->resp_pool);
  164. return ret;
  165. }
  166. static void erdma_device_uninit(struct erdma_dev *dev)
  167. {
  168. dma_pool_destroy(dev->db_pool);
  169. dma_pool_destroy(dev->resp_pool);
  170. }
  171. static void erdma_hw_reset(struct erdma_dev *dev)
  172. {
  173. u32 ctrl = FIELD_PREP(ERDMA_REG_DEV_CTRL_RESET_MASK, 1);
  174. erdma_reg_write32(dev, ERDMA_REGS_DEV_CTRL_REG, ctrl);
  175. }
  176. static int erdma_wait_hw_init_done(struct erdma_dev *dev)
  177. {
  178. int i;
  179. erdma_reg_write32(dev, ERDMA_REGS_DEV_CTRL_REG,
  180. FIELD_PREP(ERDMA_REG_DEV_CTRL_INIT_MASK, 1));
  181. for (i = 0; i < ERDMA_WAIT_DEV_DONE_CNT; i++) {
  182. if (erdma_reg_read32_filed(dev, ERDMA_REGS_DEV_ST_REG,
  183. ERDMA_REG_DEV_ST_INIT_DONE_MASK))
  184. break;
  185. msleep(ERDMA_REG_ACCESS_WAIT_MS);
  186. }
  187. if (i == ERDMA_WAIT_DEV_DONE_CNT) {
  188. dev_err(&dev->pdev->dev, "wait init done failed.\n");
  189. return -ETIMEDOUT;
  190. }
  191. return 0;
  192. }
  193. static const struct pci_device_id erdma_pci_tbl[] = {
  194. { PCI_DEVICE(PCI_VENDOR_ID_ALIBABA, 0x107f) },
  195. {}
  196. };
  197. static int erdma_probe_dev(struct pci_dev *pdev)
  198. {
  199. struct erdma_dev *dev;
  200. int bars, err;
  201. u32 version;
  202. err = pci_enable_device(pdev);
  203. if (err) {
  204. dev_err(&pdev->dev, "pci_enable_device failed(%d)\n", err);
  205. return err;
  206. }
  207. pci_set_master(pdev);
  208. dev = ib_alloc_device(erdma_dev, ibdev);
  209. if (!dev) {
  210. dev_err(&pdev->dev, "ib_alloc_device failed\n");
  211. err = -ENOMEM;
  212. goto err_disable_device;
  213. }
  214. pci_set_drvdata(pdev, dev);
  215. dev->pdev = pdev;
  216. dev->attrs.numa_node = dev_to_node(&pdev->dev);
  217. bars = pci_select_bars(pdev, IORESOURCE_MEM);
  218. err = pci_request_selected_regions(pdev, bars, DRV_MODULE_NAME);
  219. if (bars != ERDMA_BAR_MASK || err) {
  220. err = err ? err : -EINVAL;
  221. goto err_ib_device_release;
  222. }
  223. dev->func_bar_addr = pci_resource_start(pdev, ERDMA_FUNC_BAR);
  224. dev->func_bar_len = pci_resource_len(pdev, ERDMA_FUNC_BAR);
  225. dev->func_bar =
  226. devm_ioremap(&pdev->dev, dev->func_bar_addr, dev->func_bar_len);
  227. if (!dev->func_bar) {
  228. dev_err(&pdev->dev, "devm_ioremap failed.\n");
  229. err = -EFAULT;
  230. goto err_release_bars;
  231. }
  232. version = erdma_reg_read32(dev, ERDMA_REGS_VERSION_REG);
  233. if (version == 0) {
  234. /* we knows that it is a non-functional function. */
  235. err = -ENODEV;
  236. goto err_iounmap_func_bar;
  237. }
  238. err = erdma_device_init(dev, pdev);
  239. if (err)
  240. goto err_iounmap_func_bar;
  241. err = erdma_request_vectors(dev);
  242. if (err)
  243. goto err_uninit_device;
  244. err = erdma_comm_irq_init(dev);
  245. if (err)
  246. goto err_free_vectors;
  247. err = erdma_aeq_init(dev);
  248. if (err)
  249. goto err_uninit_comm_irq;
  250. err = erdma_cmdq_init(dev);
  251. if (err)
  252. goto err_uninit_aeq;
  253. err = erdma_wait_hw_init_done(dev);
  254. if (err)
  255. goto err_uninit_cmdq;
  256. err = erdma_ceqs_init(dev);
  257. if (err)
  258. goto err_reset_hw;
  259. erdma_finish_cmdq_init(dev);
  260. return 0;
  261. err_reset_hw:
  262. erdma_hw_reset(dev);
  263. err_uninit_cmdq:
  264. erdma_cmdq_destroy(dev);
  265. err_uninit_aeq:
  266. erdma_eq_destroy(dev, &dev->aeq);
  267. err_uninit_comm_irq:
  268. erdma_comm_irq_uninit(dev);
  269. err_free_vectors:
  270. pci_free_irq_vectors(dev->pdev);
  271. err_uninit_device:
  272. erdma_device_uninit(dev);
  273. err_iounmap_func_bar:
  274. devm_iounmap(&pdev->dev, dev->func_bar);
  275. err_release_bars:
  276. pci_release_selected_regions(pdev, bars);
  277. err_ib_device_release:
  278. ib_dealloc_device(&dev->ibdev);
  279. err_disable_device:
  280. pci_disable_device(pdev);
  281. return err;
  282. }
  283. static void erdma_remove_dev(struct pci_dev *pdev)
  284. {
  285. struct erdma_dev *dev = pci_get_drvdata(pdev);
  286. erdma_ceqs_uninit(dev);
  287. erdma_hw_reset(dev);
  288. erdma_cmdq_destroy(dev);
  289. erdma_eq_destroy(dev, &dev->aeq);
  290. erdma_comm_irq_uninit(dev);
  291. pci_free_irq_vectors(dev->pdev);
  292. erdma_device_uninit(dev);
  293. devm_iounmap(&pdev->dev, dev->func_bar);
  294. pci_release_selected_regions(pdev, ERDMA_BAR_MASK);
  295. ib_dealloc_device(&dev->ibdev);
  296. pci_disable_device(pdev);
  297. }
  298. #define ERDMA_GET_CAP(name, cap) FIELD_GET(ERDMA_CMD_DEV_CAP_##name##_MASK, cap)
  299. static int erdma_dev_attrs_init(struct erdma_dev *dev)
  300. {
  301. int err;
  302. u64 req_hdr, cap0, cap1;
  303. erdma_cmdq_build_reqhdr(&req_hdr, CMDQ_SUBMOD_RDMA,
  304. CMDQ_OPCODE_QUERY_DEVICE);
  305. err = erdma_post_cmd_wait(&dev->cmdq, &req_hdr, sizeof(req_hdr), &cap0,
  306. &cap1);
  307. if (err)
  308. return err;
  309. dev->attrs.max_cqe = 1 << ERDMA_GET_CAP(MAX_CQE, cap0);
  310. dev->attrs.max_mr_size = 1ULL << ERDMA_GET_CAP(MAX_MR_SIZE, cap0);
  311. dev->attrs.max_mw = 1 << ERDMA_GET_CAP(MAX_MW, cap1);
  312. dev->attrs.max_recv_wr = 1 << ERDMA_GET_CAP(MAX_RECV_WR, cap0);
  313. dev->attrs.local_dma_key = ERDMA_GET_CAP(DMA_LOCAL_KEY, cap1);
  314. dev->attrs.cc = ERDMA_GET_CAP(DEFAULT_CC, cap1);
  315. dev->attrs.max_qp = ERDMA_NQP_PER_QBLOCK * ERDMA_GET_CAP(QBLOCK, cap1);
  316. dev->attrs.max_mr = dev->attrs.max_qp << 1;
  317. dev->attrs.max_cq = dev->attrs.max_qp << 1;
  318. dev->attrs.cap_flags = ERDMA_GET_CAP(FLAGS, cap0);
  319. dev->attrs.max_send_wr = ERDMA_MAX_SEND_WR;
  320. dev->attrs.max_ord = ERDMA_MAX_ORD;
  321. dev->attrs.max_ird = ERDMA_MAX_IRD;
  322. dev->attrs.max_send_sge = ERDMA_MAX_SEND_SGE;
  323. dev->attrs.max_recv_sge = ERDMA_MAX_RECV_SGE;
  324. dev->attrs.max_sge_rd = ERDMA_MAX_SGE_RD;
  325. dev->attrs.max_pd = ERDMA_MAX_PD;
  326. dev->res_cb[ERDMA_RES_TYPE_PD].max_cap = ERDMA_MAX_PD;
  327. dev->res_cb[ERDMA_RES_TYPE_STAG_IDX].max_cap = dev->attrs.max_mr;
  328. erdma_cmdq_build_reqhdr(&req_hdr, CMDQ_SUBMOD_COMMON,
  329. CMDQ_OPCODE_QUERY_FW_INFO);
  330. err = erdma_post_cmd_wait(&dev->cmdq, &req_hdr, sizeof(req_hdr), &cap0,
  331. &cap1);
  332. if (!err)
  333. dev->attrs.fw_version =
  334. FIELD_GET(ERDMA_CMD_INFO0_FW_VER_MASK, cap0);
  335. return err;
  336. }
  337. static int erdma_device_config(struct erdma_dev *dev)
  338. {
  339. struct erdma_cmdq_config_device_req req = {};
  340. if (!(dev->attrs.cap_flags & ERDMA_DEV_CAP_FLAGS_EXTEND_DB))
  341. return 0;
  342. erdma_cmdq_build_reqhdr(&req.hdr, CMDQ_SUBMOD_COMMON,
  343. CMDQ_OPCODE_CONF_DEVICE);
  344. req.cfg = FIELD_PREP(ERDMA_CMD_CONFIG_DEVICE_PGSHIFT_MASK, PAGE_SHIFT) |
  345. FIELD_PREP(ERDMA_CMD_CONFIG_DEVICE_PS_EN_MASK, 1);
  346. return erdma_post_cmd_wait(&dev->cmdq, &req, sizeof(req), NULL, NULL);
  347. }
  348. static int erdma_res_cb_init(struct erdma_dev *dev)
  349. {
  350. int i, j;
  351. for (i = 0; i < ERDMA_RES_CNT; i++) {
  352. dev->res_cb[i].next_alloc_idx = 1;
  353. spin_lock_init(&dev->res_cb[i].lock);
  354. dev->res_cb[i].bitmap =
  355. bitmap_zalloc(dev->res_cb[i].max_cap, GFP_KERNEL);
  356. if (!dev->res_cb[i].bitmap)
  357. goto err;
  358. }
  359. return 0;
  360. err:
  361. for (j = 0; j < i; j++)
  362. bitmap_free(dev->res_cb[j].bitmap);
  363. return -ENOMEM;
  364. }
  365. static void erdma_res_cb_free(struct erdma_dev *dev)
  366. {
  367. int i;
  368. for (i = 0; i < ERDMA_RES_CNT; i++)
  369. bitmap_free(dev->res_cb[i].bitmap);
  370. }
  371. static const struct ib_device_ops erdma_device_ops = {
  372. .owner = THIS_MODULE,
  373. .driver_id = RDMA_DRIVER_ERDMA,
  374. .uverbs_abi_ver = ERDMA_ABI_VERSION,
  375. .alloc_hw_port_stats = erdma_alloc_hw_port_stats,
  376. .alloc_mr = erdma_ib_alloc_mr,
  377. .alloc_pd = erdma_alloc_pd,
  378. .alloc_ucontext = erdma_alloc_ucontext,
  379. .create_cq = erdma_create_cq,
  380. .create_qp = erdma_create_qp,
  381. .dealloc_pd = erdma_dealloc_pd,
  382. .dealloc_ucontext = erdma_dealloc_ucontext,
  383. .dereg_mr = erdma_dereg_mr,
  384. .destroy_cq = erdma_destroy_cq,
  385. .destroy_qp = erdma_destroy_qp,
  386. .disassociate_ucontext = erdma_disassociate_ucontext,
  387. .get_dma_mr = erdma_get_dma_mr,
  388. .get_hw_stats = erdma_get_hw_stats,
  389. .get_port_immutable = erdma_get_port_immutable,
  390. .iw_accept = erdma_accept,
  391. .iw_add_ref = erdma_qp_get_ref,
  392. .iw_connect = erdma_connect,
  393. .iw_create_listen = erdma_create_listen,
  394. .iw_destroy_listen = erdma_destroy_listen,
  395. .iw_get_qp = erdma_get_ibqp,
  396. .iw_reject = erdma_reject,
  397. .iw_rem_ref = erdma_qp_put_ref,
  398. .map_mr_sg = erdma_map_mr_sg,
  399. .mmap = erdma_mmap,
  400. .mmap_free = erdma_mmap_free,
  401. .modify_qp = erdma_modify_qp,
  402. .post_recv = erdma_post_recv,
  403. .post_send = erdma_post_send,
  404. .poll_cq = erdma_poll_cq,
  405. .query_device = erdma_query_device,
  406. .query_gid = erdma_query_gid,
  407. .query_port = erdma_query_port,
  408. .query_qp = erdma_query_qp,
  409. .req_notify_cq = erdma_req_notify_cq,
  410. .reg_user_mr = erdma_reg_user_mr,
  411. INIT_RDMA_OBJ_SIZE(ib_cq, erdma_cq, ibcq),
  412. INIT_RDMA_OBJ_SIZE(ib_pd, erdma_pd, ibpd),
  413. INIT_RDMA_OBJ_SIZE(ib_ucontext, erdma_ucontext, ibucontext),
  414. INIT_RDMA_OBJ_SIZE(ib_qp, erdma_qp, ibqp),
  415. };
  416. static int erdma_ib_device_add(struct pci_dev *pdev)
  417. {
  418. struct erdma_dev *dev = pci_get_drvdata(pdev);
  419. struct ib_device *ibdev = &dev->ibdev;
  420. u64 mac;
  421. int ret;
  422. ret = erdma_dev_attrs_init(dev);
  423. if (ret)
  424. return ret;
  425. ret = erdma_device_config(dev);
  426. if (ret)
  427. return ret;
  428. ibdev->node_type = RDMA_NODE_RNIC;
  429. memcpy(ibdev->node_desc, ERDMA_NODE_DESC, sizeof(ERDMA_NODE_DESC));
  430. /*
  431. * Current model (one-to-one device association):
  432. * One ERDMA device per net_device or, equivalently,
  433. * per physical port.
  434. */
  435. ibdev->phys_port_cnt = 1;
  436. ibdev->num_comp_vectors = dev->attrs.irq_num - 1;
  437. ib_set_device_ops(ibdev, &erdma_device_ops);
  438. INIT_LIST_HEAD(&dev->cep_list);
  439. spin_lock_init(&dev->lock);
  440. xa_init_flags(&dev->qp_xa, XA_FLAGS_ALLOC1);
  441. xa_init_flags(&dev->cq_xa, XA_FLAGS_ALLOC1);
  442. dev->next_alloc_cqn = 1;
  443. dev->next_alloc_qpn = 1;
  444. ret = erdma_res_cb_init(dev);
  445. if (ret)
  446. return ret;
  447. atomic_set(&dev->num_ctx, 0);
  448. mac = erdma_reg_read32(dev, ERDMA_REGS_NETDEV_MAC_L_REG);
  449. mac |= (u64)erdma_reg_read32(dev, ERDMA_REGS_NETDEV_MAC_H_REG) << 32;
  450. u64_to_ether_addr(mac, dev->attrs.peer_addr);
  451. dev->reflush_wq = alloc_workqueue("erdma-reflush-wq", WQ_UNBOUND,
  452. WQ_UNBOUND_MAX_ACTIVE);
  453. if (!dev->reflush_wq) {
  454. ret = -ENOMEM;
  455. goto err_alloc_workqueue;
  456. }
  457. ret = erdma_device_register(dev);
  458. if (ret)
  459. goto err_register;
  460. return 0;
  461. err_register:
  462. destroy_workqueue(dev->reflush_wq);
  463. err_alloc_workqueue:
  464. xa_destroy(&dev->qp_xa);
  465. xa_destroy(&dev->cq_xa);
  466. erdma_res_cb_free(dev);
  467. return ret;
  468. }
  469. static void erdma_ib_device_remove(struct pci_dev *pdev)
  470. {
  471. struct erdma_dev *dev = pci_get_drvdata(pdev);
  472. unregister_netdevice_notifier(&dev->netdev_nb);
  473. ib_unregister_device(&dev->ibdev);
  474. destroy_workqueue(dev->reflush_wq);
  475. erdma_res_cb_free(dev);
  476. xa_destroy(&dev->qp_xa);
  477. xa_destroy(&dev->cq_xa);
  478. }
  479. static int erdma_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
  480. {
  481. int ret;
  482. ret = erdma_probe_dev(pdev);
  483. if (ret)
  484. return ret;
  485. ret = erdma_ib_device_add(pdev);
  486. if (ret) {
  487. erdma_remove_dev(pdev);
  488. return ret;
  489. }
  490. return 0;
  491. }
  492. static void erdma_remove(struct pci_dev *pdev)
  493. {
  494. erdma_ib_device_remove(pdev);
  495. erdma_remove_dev(pdev);
  496. }
  497. static struct pci_driver erdma_pci_driver = {
  498. .name = DRV_MODULE_NAME,
  499. .id_table = erdma_pci_tbl,
  500. .probe = erdma_probe,
  501. .remove = erdma_remove
  502. };
  503. MODULE_DEVICE_TABLE(pci, erdma_pci_tbl);
  504. static __init int erdma_init_module(void)
  505. {
  506. int ret;
  507. ret = erdma_cm_init();
  508. if (ret)
  509. return ret;
  510. ret = pci_register_driver(&erdma_pci_driver);
  511. if (ret)
  512. erdma_cm_exit();
  513. return ret;
  514. }
  515. static void __exit erdma_exit_module(void)
  516. {
  517. pci_unregister_driver(&erdma_pci_driver);
  518. erdma_cm_exit();
  519. }
  520. module_init(erdma_init_module);
  521. module_exit(erdma_exit_module);