Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma
[linux-2.6-block.git] / drivers / infiniband / hw / mana / device.c
CommitLineData
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
9MODULE_DESCRIPTION("Microsoft Azure Network Adapter IB driver");
10MODULE_LICENSE("GPL");
11MODULE_IMPORT_NS(NET_MANA);
12
13static 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
53static 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
143destroy_rnic:
144 mana_ib_gd_destroy_rnic_adapter(dev);
98b889c4
KT
145destroy_eqs:
146 mana_ib_destroy_eqs(dev);
a7f0636d
LL
147deregister_device:
148 mana_gd_deregister_device(dev->gdma_dev);
149free_ib_device:
150 ib_dealloc_device(&dev->ib_dev);
151 return ret;
0266a177
LL
152}
153
154static 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
165static const struct auxiliary_device_id mana_id_table[] = {
166 {
167 .name = "mana.rdma",
168 },
169 {},
170};
171
172MODULE_DEVICE_TABLE(auxiliary, mana_id_table);
173
174static 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
181module_auxiliary_driver(mana_driver);