Commit | Line | Data |
---|---|---|
0266a177 LL |
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 | ||
faafb8b1 | 18 | .add_gid = mana_ib_gd_add_gid, |
0266a177 LL |
19 | .alloc_pd = mana_ib_alloc_pd, |
20 | .alloc_ucontext = mana_ib_alloc_ucontext, | |
21 | .create_cq = mana_ib_create_cq, | |
22 | .create_qp = mana_ib_create_qp, | |
23 | .create_rwq_ind_table = mana_ib_create_rwq_ind_table, | |
24 | .create_wq = mana_ib_create_wq, | |
25 | .dealloc_pd = mana_ib_dealloc_pd, | |
26 | .dealloc_ucontext = mana_ib_dealloc_ucontext, | |
faafb8b1 | 27 | .del_gid = mana_ib_gd_del_gid, |
0266a177 LL |
28 | .dereg_mr = mana_ib_dereg_mr, |
29 | .destroy_cq = mana_ib_destroy_cq, | |
30 | .destroy_qp = mana_ib_destroy_qp, | |
31 | .destroy_rwq_ind_table = mana_ib_destroy_rwq_ind_table, | |
32 | .destroy_wq = mana_ib_destroy_wq, | |
33 | .disassociate_ucontext = mana_ib_disassociate_ucontext, | |
4bda1d53 | 34 | .get_link_layer = mana_ib_get_link_layer, |
0266a177 LL |
35 | .get_port_immutable = mana_ib_get_port_immutable, |
36 | .mmap = mana_ib_mmap, | |
37 | .modify_qp = mana_ib_modify_qp, | |
38 | .modify_wq = mana_ib_modify_wq, | |
39 | .query_device = mana_ib_query_device, | |
40 | .query_gid = mana_ib_query_gid, | |
4bda1d53 | 41 | .query_pkey = mana_ib_query_pkey, |
0266a177 LL |
42 | .query_port = mana_ib_query_port, |
43 | .reg_user_mr = mana_ib_reg_user_mr, | |
44 | ||
45 | INIT_RDMA_OBJ_SIZE(ib_cq, mana_ib_cq, ibcq), | |
46 | INIT_RDMA_OBJ_SIZE(ib_pd, mana_ib_pd, ibpd), | |
47 | INIT_RDMA_OBJ_SIZE(ib_qp, mana_ib_qp, ibqp), | |
48 | INIT_RDMA_OBJ_SIZE(ib_ucontext, mana_ib_ucontext, ibucontext), | |
49 | INIT_RDMA_OBJ_SIZE(ib_rwq_ind_table, mana_ib_rwq_ind_table, | |
50 | ib_ind_table), | |
51 | }; | |
52 | ||
53 | static int mana_ib_probe(struct auxiliary_device *adev, | |
54 | const struct auxiliary_device_id *id) | |
55 | { | |
56 | struct mana_adev *madev = container_of(adev, struct mana_adev, adev); | |
57 | struct gdma_dev *mdev = madev->mdev; | |
8b184e4f | 58 | struct net_device *upper_ndev; |
0266a177 LL |
59 | struct mana_context *mc; |
60 | struct mana_ib_dev *dev; | |
8859f009 | 61 | u8 mac_addr[ETH_ALEN]; |
0266a177 LL |
62 | int ret; |
63 | ||
64 | mc = mdev->driver_data; | |
65 | ||
66 | dev = ib_alloc_device(mana_ib_dev, ib_dev); | |
67 | if (!dev) | |
68 | return -ENOMEM; | |
69 | ||
70 | ib_set_device_ops(&dev->ib_dev, &mana_ib_dev_ops); | |
71 | ||
72 | dev->ib_dev.phys_port_cnt = mc->num_ports; | |
73 | ||
74 | ibdev_dbg(&dev->ib_dev, "mdev=%p id=%d num_ports=%d\n", mdev, | |
75 | mdev->dev_id.as_uint32, dev->ib_dev.phys_port_cnt); | |
76 | ||
0266a177 LL |
77 | dev->ib_dev.node_type = RDMA_NODE_IB_CA; |
78 | ||
79 | /* | |
80 | * num_comp_vectors needs to set to the max MSIX index | |
81 | * when interrupts and event queues are implemented | |
82 | */ | |
23f59f4e | 83 | dev->ib_dev.num_comp_vectors = mdev->gdma_context->max_num_queues; |
0266a177 LL |
84 | dev->ib_dev.dev.parent = mdev->gdma_context->dev; |
85 | ||
8b184e4f KT |
86 | rcu_read_lock(); /* required to get upper dev */ |
87 | upper_ndev = netdev_master_upper_dev_get_rcu(mc->ports[0]); | |
88 | if (!upper_ndev) { | |
89 | rcu_read_unlock(); | |
f88320b6 | 90 | ret = -ENODEV; |
8b184e4f KT |
91 | ibdev_err(&dev->ib_dev, "Failed to get master netdev"); |
92 | goto free_ib_device; | |
93 | } | |
8859f009 | 94 | ether_addr_copy(mac_addr, upper_ndev->dev_addr); |
8b184e4f KT |
95 | ret = ib_device_set_netdev(&dev->ib_dev, upper_ndev, 1); |
96 | rcu_read_unlock(); | |
97 | if (ret) { | |
98 | ibdev_err(&dev->ib_dev, "Failed to set ib netdev, ret %d", ret); | |
99 | goto free_ib_device; | |
100 | } | |
101 | ||
a7f0636d | 102 | ret = mana_gd_register_device(&mdev->gdma_context->mana_ib); |
0266a177 | 103 | if (ret) { |
a7f0636d LL |
104 | ibdev_err(&dev->ib_dev, "Failed to register device, ret %d", |
105 | ret); | |
106 | goto free_ib_device; | |
0266a177 | 107 | } |
a7f0636d LL |
108 | dev->gdma_dev = &mdev->gdma_context->mana_ib; |
109 | ||
2c20e20b LL |
110 | ret = mana_ib_gd_query_adapter_caps(dev); |
111 | if (ret) { | |
112 | ibdev_err(&dev->ib_dev, "Failed to query device caps, ret %d", | |
113 | ret); | |
114 | goto deregister_device; | |
115 | } | |
116 | ||
98b889c4 KT |
117 | ret = mana_ib_create_eqs(dev); |
118 | if (ret) { | |
119 | ibdev_err(&dev->ib_dev, "Failed to create EQs, ret %d", ret); | |
120 | goto deregister_device; | |
121 | } | |
122 | ||
1a79c2b9 KT |
123 | ret = mana_ib_gd_create_rnic_adapter(dev); |
124 | if (ret) | |
125 | goto destroy_eqs; | |
126 | ||
8859f009 KT |
127 | ret = mana_ib_gd_config_mac(dev, ADDR_OP_ADD, mac_addr); |
128 | if (ret) { | |
129 | ibdev_err(&dev->ib_dev, "Failed to add Mac address, ret %d", | |
130 | ret); | |
131 | goto destroy_rnic; | |
132 | } | |
133 | ||
a7f0636d LL |
134 | ret = ib_register_device(&dev->ib_dev, "mana_%d", |
135 | mdev->gdma_context->dev); | |
136 | if (ret) | |
1a79c2b9 | 137 | goto destroy_rnic; |
0266a177 LL |
138 | |
139 | dev_set_drvdata(&adev->dev, dev); | |
140 | ||
141 | return 0; | |
a7f0636d | 142 | |
1a79c2b9 KT |
143 | destroy_rnic: |
144 | mana_ib_gd_destroy_rnic_adapter(dev); | |
98b889c4 KT |
145 | destroy_eqs: |
146 | mana_ib_destroy_eqs(dev); | |
a7f0636d LL |
147 | deregister_device: |
148 | mana_gd_deregister_device(dev->gdma_dev); | |
149 | free_ib_device: | |
150 | ib_dealloc_device(&dev->ib_dev); | |
151 | return ret; | |
0266a177 LL |
152 | } |
153 | ||
154 | static void mana_ib_remove(struct auxiliary_device *adev) | |
155 | { | |
156 | struct mana_ib_dev *dev = dev_get_drvdata(&adev->dev); | |
157 | ||
158 | ib_unregister_device(&dev->ib_dev); | |
1a79c2b9 | 159 | mana_ib_gd_destroy_rnic_adapter(dev); |
98b889c4 | 160 | mana_ib_destroy_eqs(dev); |
a7f0636d | 161 | mana_gd_deregister_device(dev->gdma_dev); |
0266a177 LL |
162 | ib_dealloc_device(&dev->ib_dev); |
163 | } | |
164 | ||
165 | static const struct auxiliary_device_id mana_id_table[] = { | |
166 | { | |
167 | .name = "mana.rdma", | |
168 | }, | |
169 | {}, | |
170 | }; | |
171 | ||
172 | MODULE_DEVICE_TABLE(auxiliary, mana_id_table); | |
173 | ||
174 | static struct auxiliary_driver mana_driver = { | |
175 | .name = "rdma", | |
176 | .probe = mana_ib_probe, | |
177 | .remove = mana_ib_remove, | |
178 | .id_table = mana_id_table, | |
179 | }; | |
180 | ||
181 | module_auxiliary_driver(mana_driver); |