1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Copyright (c) 2022, Microsoft Corporation. All rights reserved. |
4 | */ |
5 | |
6 | #include "mana_ib.h" |
7 | #include <net/mana/mana_auxiliary.h> |
8 | |
9 | MODULE_DESCRIPTION("Microsoft Azure Network Adapter IB driver" ); |
10 | MODULE_LICENSE("GPL" ); |
11 | MODULE_IMPORT_NS(NET_MANA); |
12 | |
13 | static const struct ib_device_ops mana_ib_dev_ops = { |
14 | .owner = THIS_MODULE, |
15 | .driver_id = RDMA_DRIVER_MANA, |
16 | .uverbs_abi_ver = MANA_IB_UVERBS_ABI_VERSION, |
17 | |
18 | .alloc_pd = mana_ib_alloc_pd, |
19 | .alloc_ucontext = mana_ib_alloc_ucontext, |
20 | .create_cq = mana_ib_create_cq, |
21 | .create_qp = mana_ib_create_qp, |
22 | .create_rwq_ind_table = mana_ib_create_rwq_ind_table, |
23 | .create_wq = mana_ib_create_wq, |
24 | .dealloc_pd = mana_ib_dealloc_pd, |
25 | .dealloc_ucontext = mana_ib_dealloc_ucontext, |
26 | .dereg_mr = mana_ib_dereg_mr, |
27 | .destroy_cq = mana_ib_destroy_cq, |
28 | .destroy_qp = mana_ib_destroy_qp, |
29 | .destroy_rwq_ind_table = mana_ib_destroy_rwq_ind_table, |
30 | .destroy_wq = mana_ib_destroy_wq, |
31 | .disassociate_ucontext = mana_ib_disassociate_ucontext, |
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_port = mana_ib_query_port, |
39 | .reg_user_mr = mana_ib_reg_user_mr, |
40 | |
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 | |
49 | static int mana_ib_probe(struct auxiliary_device *adev, |
50 | const struct auxiliary_device_id *id) |
51 | { |
52 | struct mana_adev *madev = container_of(adev, struct mana_adev, adev); |
53 | struct gdma_dev *mdev = madev->mdev; |
54 | struct mana_context *mc; |
55 | struct mana_ib_dev *dev; |
56 | int ret; |
57 | |
58 | mc = mdev->driver_data; |
59 | |
60 | dev = ib_alloc_device(mana_ib_dev, ib_dev); |
61 | if (!dev) |
62 | return -ENOMEM; |
63 | |
64 | ib_set_device_ops(device: &dev->ib_dev, ops: &mana_ib_dev_ops); |
65 | |
66 | dev->ib_dev.phys_port_cnt = mc->num_ports; |
67 | |
68 | ibdev_dbg(&dev->ib_dev, "mdev=%p id=%d num_ports=%d\n" , mdev, |
69 | mdev->dev_id.as_uint32, dev->ib_dev.phys_port_cnt); |
70 | |
71 | dev->ib_dev.node_type = RDMA_NODE_IB_CA; |
72 | |
73 | /* |
74 | * num_comp_vectors needs to set to the max MSIX index |
75 | * when interrupts and event queues are implemented |
76 | */ |
77 | dev->ib_dev.num_comp_vectors = 1; |
78 | dev->ib_dev.dev.parent = mdev->gdma_context->dev; |
79 | |
80 | ret = mana_gd_register_device(gd: &mdev->gdma_context->mana_ib); |
81 | if (ret) { |
82 | ibdev_err(ibdev: &dev->ib_dev, format: "Failed to register device, ret %d" , |
83 | ret); |
84 | goto free_ib_device; |
85 | } |
86 | dev->gdma_dev = &mdev->gdma_context->mana_ib; |
87 | |
88 | ret = mana_ib_gd_query_adapter_caps(mdev: dev); |
89 | if (ret) { |
90 | ibdev_err(ibdev: &dev->ib_dev, format: "Failed to query device caps, ret %d" , |
91 | ret); |
92 | goto deregister_device; |
93 | } |
94 | |
95 | ret = ib_register_device(device: &dev->ib_dev, name: "mana_%d" , |
96 | dma_device: mdev->gdma_context->dev); |
97 | if (ret) |
98 | goto deregister_device; |
99 | |
100 | dev_set_drvdata(dev: &adev->dev, data: dev); |
101 | |
102 | return 0; |
103 | |
104 | deregister_device: |
105 | mana_gd_deregister_device(gd: dev->gdma_dev); |
106 | free_ib_device: |
107 | ib_dealloc_device(device: &dev->ib_dev); |
108 | return ret; |
109 | } |
110 | |
111 | static void mana_ib_remove(struct auxiliary_device *adev) |
112 | { |
113 | struct mana_ib_dev *dev = dev_get_drvdata(dev: &adev->dev); |
114 | |
115 | ib_unregister_device(device: &dev->ib_dev); |
116 | |
117 | mana_gd_deregister_device(gd: dev->gdma_dev); |
118 | |
119 | ib_dealloc_device(device: &dev->ib_dev); |
120 | } |
121 | |
122 | static const struct auxiliary_device_id mana_id_table[] = { |
123 | { |
124 | .name = "mana.rdma" , |
125 | }, |
126 | {}, |
127 | }; |
128 | |
129 | MODULE_DEVICE_TABLE(auxiliary, mana_id_table); |
130 | |
131 | static struct auxiliary_driver mana_driver = { |
132 | .name = "rdma" , |
133 | .probe = mana_ib_probe, |
134 | .remove = mana_ib_remove, |
135 | .id_table = mana_id_table, |
136 | }; |
137 | |
138 | module_auxiliary_driver(mana_driver); |
139 | |