device.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2022, Microsoft Corporation. All rights reserved.
  4. */
  5. #include "mana_ib.h"
  6. #include <net/mana/mana_auxiliary.h>
  7. #include <net/addrconf.h>
  8. MODULE_DESCRIPTION("Microsoft Azure Network Adapter IB driver");
  9. MODULE_LICENSE("GPL");
  10. MODULE_IMPORT_NS(NET_MANA);
  11. static const struct ib_device_ops mana_ib_dev_ops = {
  12. .owner = THIS_MODULE,
  13. .driver_id = RDMA_DRIVER_MANA,
  14. .uverbs_abi_ver = MANA_IB_UVERBS_ABI_VERSION,
  15. .add_gid = mana_ib_gd_add_gid,
  16. .alloc_pd = mana_ib_alloc_pd,
  17. .alloc_ucontext = mana_ib_alloc_ucontext,
  18. .create_cq = mana_ib_create_cq,
  19. .create_qp = mana_ib_create_qp,
  20. .create_rwq_ind_table = mana_ib_create_rwq_ind_table,
  21. .create_wq = mana_ib_create_wq,
  22. .dealloc_pd = mana_ib_dealloc_pd,
  23. .dealloc_ucontext = mana_ib_dealloc_ucontext,
  24. .del_gid = mana_ib_gd_del_gid,
  25. .dereg_mr = mana_ib_dereg_mr,
  26. .destroy_cq = mana_ib_destroy_cq,
  27. .destroy_qp = mana_ib_destroy_qp,
  28. .destroy_rwq_ind_table = mana_ib_destroy_rwq_ind_table,
  29. .destroy_wq = mana_ib_destroy_wq,
  30. .disassociate_ucontext = mana_ib_disassociate_ucontext,
  31. .get_link_layer = mana_ib_get_link_layer,
  32. .get_port_immutable = mana_ib_get_port_immutable,
  33. .mmap = mana_ib_mmap,
  34. .modify_qp = mana_ib_modify_qp,
  35. .modify_wq = mana_ib_modify_wq,
  36. .query_device = mana_ib_query_device,
  37. .query_gid = mana_ib_query_gid,
  38. .query_pkey = mana_ib_query_pkey,
  39. .query_port = mana_ib_query_port,
  40. .reg_user_mr = mana_ib_reg_user_mr,
  41. INIT_RDMA_OBJ_SIZE(ib_cq, mana_ib_cq, ibcq),
  42. INIT_RDMA_OBJ_SIZE(ib_pd, mana_ib_pd, ibpd),
  43. INIT_RDMA_OBJ_SIZE(ib_qp, mana_ib_qp, ibqp),
  44. INIT_RDMA_OBJ_SIZE(ib_ucontext, mana_ib_ucontext, ibucontext),
  45. INIT_RDMA_OBJ_SIZE(ib_rwq_ind_table, mana_ib_rwq_ind_table,
  46. ib_ind_table),
  47. };
  48. static int mana_ib_probe(struct auxiliary_device *adev,
  49. const struct auxiliary_device_id *id)
  50. {
  51. struct mana_adev *madev = container_of(adev, struct mana_adev, adev);
  52. struct gdma_dev *mdev = madev->mdev;
  53. struct net_device *ndev;
  54. struct mana_context *mc;
  55. struct mana_ib_dev *dev;
  56. u8 mac_addr[ETH_ALEN];
  57. int ret;
  58. mc = mdev->driver_data;
  59. dev = ib_alloc_device(mana_ib_dev, ib_dev);
  60. if (!dev)
  61. return -ENOMEM;
  62. ib_set_device_ops(&dev->ib_dev, &mana_ib_dev_ops);
  63. dev->ib_dev.phys_port_cnt = mc->num_ports;
  64. ibdev_dbg(&dev->ib_dev, "mdev=%p id=%d num_ports=%d\n", mdev,
  65. mdev->dev_id.as_uint32, dev->ib_dev.phys_port_cnt);
  66. dev->ib_dev.node_type = RDMA_NODE_IB_CA;
  67. /*
  68. * num_comp_vectors needs to set to the max MSIX index
  69. * when interrupts and event queues are implemented
  70. */
  71. dev->ib_dev.num_comp_vectors = mdev->gdma_context->max_num_queues;
  72. dev->ib_dev.dev.parent = mdev->gdma_context->dev;
  73. rcu_read_lock(); /* required to get primary netdev */
  74. ndev = mana_get_primary_netdev_rcu(mc, 0);
  75. if (!ndev) {
  76. rcu_read_unlock();
  77. ret = -ENODEV;
  78. ibdev_err(&dev->ib_dev, "Failed to get netdev for IB port 1");
  79. goto free_ib_device;
  80. }
  81. ether_addr_copy(mac_addr, ndev->dev_addr);
  82. addrconf_addr_eui48((u8 *)&dev->ib_dev.node_guid, ndev->dev_addr);
  83. ret = ib_device_set_netdev(&dev->ib_dev, ndev, 1);
  84. rcu_read_unlock();
  85. if (ret) {
  86. ibdev_err(&dev->ib_dev, "Failed to set ib netdev, ret %d", ret);
  87. goto free_ib_device;
  88. }
  89. ret = mana_gd_register_device(&mdev->gdma_context->mana_ib);
  90. if (ret) {
  91. ibdev_err(&dev->ib_dev, "Failed to register device, ret %d",
  92. ret);
  93. goto free_ib_device;
  94. }
  95. dev->gdma_dev = &mdev->gdma_context->mana_ib;
  96. ret = mana_ib_gd_query_adapter_caps(dev);
  97. if (ret) {
  98. ibdev_err(&dev->ib_dev, "Failed to query device caps, ret %d",
  99. ret);
  100. goto deregister_device;
  101. }
  102. ret = mana_ib_create_eqs(dev);
  103. if (ret) {
  104. ibdev_err(&dev->ib_dev, "Failed to create EQs, ret %d", ret);
  105. goto deregister_device;
  106. }
  107. ret = mana_ib_gd_create_rnic_adapter(dev);
  108. if (ret)
  109. goto destroy_eqs;
  110. xa_init_flags(&dev->qp_table_wq, XA_FLAGS_LOCK_IRQ);
  111. ret = mana_ib_gd_config_mac(dev, ADDR_OP_ADD, mac_addr);
  112. if (ret) {
  113. ibdev_err(&dev->ib_dev, "Failed to add Mac address, ret %d",
  114. ret);
  115. goto destroy_rnic;
  116. }
  117. ret = ib_register_device(&dev->ib_dev, "mana_%d",
  118. mdev->gdma_context->dev);
  119. if (ret)
  120. goto destroy_rnic;
  121. dev_set_drvdata(&adev->dev, dev);
  122. return 0;
  123. destroy_rnic:
  124. xa_destroy(&dev->qp_table_wq);
  125. mana_ib_gd_destroy_rnic_adapter(dev);
  126. destroy_eqs:
  127. mana_ib_destroy_eqs(dev);
  128. deregister_device:
  129. mana_gd_deregister_device(dev->gdma_dev);
  130. free_ib_device:
  131. ib_dealloc_device(&dev->ib_dev);
  132. return ret;
  133. }
  134. static void mana_ib_remove(struct auxiliary_device *adev)
  135. {
  136. struct mana_ib_dev *dev = dev_get_drvdata(&adev->dev);
  137. ib_unregister_device(&dev->ib_dev);
  138. xa_destroy(&dev->qp_table_wq);
  139. mana_ib_gd_destroy_rnic_adapter(dev);
  140. mana_ib_destroy_eqs(dev);
  141. mana_gd_deregister_device(dev->gdma_dev);
  142. ib_dealloc_device(&dev->ib_dev);
  143. }
  144. static const struct auxiliary_device_id mana_id_table[] = {
  145. {
  146. .name = "mana.rdma",
  147. },
  148. {},
  149. };
  150. MODULE_DEVICE_TABLE(auxiliary, mana_id_table);
  151. static struct auxiliary_driver mana_driver = {
  152. .name = "rdma",
  153. .probe = mana_ib_probe,
  154. .remove = mana_ib_remove,
  155. .id_table = mana_id_table,
  156. };
  157. module_auxiliary_driver(mana_driver);