]>
Commit | Line | Data |
---|---|---|
8700e3e7 MS |
1 | /* |
2 | * Copyright (c) 2016 Mellanox Technologies Ltd. All rights reserved. | |
3 | * Copyright (c) 2015 System Fabric Works, Inc. All rights reserved. | |
4 | * | |
5 | * This software is available to you under a choice of one of two | |
6 | * licenses. You may choose to be licensed under the terms of the GNU | |
7 | * General Public License (GPL) Version 2, available from the file | |
8 | * COPYING in the main directory of this source tree, or the | |
9 | * OpenIB.org BSD license below: | |
10 | * | |
11 | * Redistribution and use in source and binary forms, with or | |
12 | * without modification, are permitted provided that the following | |
13 | * conditions are met: | |
14 | * | |
15 | * - Redistributions of source code must retain the above | |
16 | * copyright notice, this list of conditions and the following | |
17 | * disclaimer. | |
18 | * | |
19 | * - Redistributions in binary form must reproduce the above | |
20 | * copyright notice, this list of conditions and the following | |
21 | * disclaimer in the documentation and/or other materials | |
22 | * provided with the distribution. | |
23 | * | |
24 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
25 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
26 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
27 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | |
28 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | |
29 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |
30 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
31 | * SOFTWARE. | |
32 | */ | |
33 | ||
4d6f2859 | 34 | #include <net/addrconf.h> |
8700e3e7 MS |
35 | #include "rxe.h" |
36 | #include "rxe_loc.h" | |
37 | ||
38 | MODULE_AUTHOR("Bob Pearson, Frank Zago, John Groves, Kamal Heib"); | |
39 | MODULE_DESCRIPTION("Soft RDMA transport"); | |
40 | MODULE_LICENSE("Dual BSD/GPL"); | |
8700e3e7 MS |
41 | |
42 | /* free resources for all ports on a device */ | |
43 | static void rxe_cleanup_ports(struct rxe_dev *rxe) | |
44 | { | |
45 | kfree(rxe->port.pkey_tbl); | |
46 | rxe->port.pkey_tbl = NULL; | |
47 | ||
48 | } | |
49 | ||
50 | /* free resources for a rxe device all objects created for this device must | |
51 | * have been destroyed | |
52 | */ | |
53 | static void rxe_cleanup(struct rxe_dev *rxe) | |
54 | { | |
55 | rxe_pool_cleanup(&rxe->uc_pool); | |
56 | rxe_pool_cleanup(&rxe->pd_pool); | |
57 | rxe_pool_cleanup(&rxe->ah_pool); | |
58 | rxe_pool_cleanup(&rxe->srq_pool); | |
59 | rxe_pool_cleanup(&rxe->qp_pool); | |
60 | rxe_pool_cleanup(&rxe->cq_pool); | |
61 | rxe_pool_cleanup(&rxe->mr_pool); | |
62 | rxe_pool_cleanup(&rxe->mw_pool); | |
63 | rxe_pool_cleanup(&rxe->mc_grp_pool); | |
64 | rxe_pool_cleanup(&rxe->mc_elem_pool); | |
65 | ||
66 | rxe_cleanup_ports(rxe); | |
cee2688e | 67 | |
68 | crypto_free_shash(rxe->tfm); | |
8700e3e7 MS |
69 | } |
70 | ||
71 | /* called when all references have been dropped */ | |
72 | void rxe_release(struct kref *kref) | |
73 | { | |
74 | struct rxe_dev *rxe = container_of(kref, struct rxe_dev, ref_cnt); | |
75 | ||
76 | rxe_cleanup(rxe); | |
77 | ib_dealloc_device(&rxe->ib_dev); | |
78 | } | |
79 | ||
80 | void rxe_dev_put(struct rxe_dev *rxe) | |
81 | { | |
82 | kref_put(&rxe->ref_cnt, rxe_release); | |
83 | } | |
84 | EXPORT_SYMBOL_GPL(rxe_dev_put); | |
85 | ||
86 | /* initialize rxe device parameters */ | |
87 | static int rxe_init_device_param(struct rxe_dev *rxe) | |
88 | { | |
89 | rxe->max_inline_data = RXE_MAX_INLINE_DATA; | |
90 | ||
91 | rxe->attr.fw_ver = RXE_FW_VER; | |
92 | rxe->attr.max_mr_size = RXE_MAX_MR_SIZE; | |
93 | rxe->attr.page_size_cap = RXE_PAGE_SIZE_CAP; | |
94 | rxe->attr.vendor_id = RXE_VENDOR_ID; | |
95 | rxe->attr.vendor_part_id = RXE_VENDOR_PART_ID; | |
96 | rxe->attr.hw_ver = RXE_HW_VER; | |
97 | rxe->attr.max_qp = RXE_MAX_QP; | |
98 | rxe->attr.max_qp_wr = RXE_MAX_QP_WR; | |
99 | rxe->attr.device_cap_flags = RXE_DEVICE_CAP_FLAGS; | |
100 | rxe->attr.max_sge = RXE_MAX_SGE; | |
101 | rxe->attr.max_sge_rd = RXE_MAX_SGE_RD; | |
102 | rxe->attr.max_cq = RXE_MAX_CQ; | |
103 | rxe->attr.max_cqe = (1 << RXE_MAX_LOG_CQE) - 1; | |
104 | rxe->attr.max_mr = RXE_MAX_MR; | |
105 | rxe->attr.max_pd = RXE_MAX_PD; | |
106 | rxe->attr.max_qp_rd_atom = RXE_MAX_QP_RD_ATOM; | |
107 | rxe->attr.max_ee_rd_atom = RXE_MAX_EE_RD_ATOM; | |
108 | rxe->attr.max_res_rd_atom = RXE_MAX_RES_RD_ATOM; | |
109 | rxe->attr.max_qp_init_rd_atom = RXE_MAX_QP_INIT_RD_ATOM; | |
110 | rxe->attr.max_ee_init_rd_atom = RXE_MAX_EE_INIT_RD_ATOM; | |
111 | rxe->attr.atomic_cap = RXE_ATOMIC_CAP; | |
112 | rxe->attr.max_ee = RXE_MAX_EE; | |
113 | rxe->attr.max_rdd = RXE_MAX_RDD; | |
114 | rxe->attr.max_mw = RXE_MAX_MW; | |
115 | rxe->attr.max_raw_ipv6_qp = RXE_MAX_RAW_IPV6_QP; | |
116 | rxe->attr.max_raw_ethy_qp = RXE_MAX_RAW_ETHY_QP; | |
117 | rxe->attr.max_mcast_grp = RXE_MAX_MCAST_GRP; | |
118 | rxe->attr.max_mcast_qp_attach = RXE_MAX_MCAST_QP_ATTACH; | |
119 | rxe->attr.max_total_mcast_qp_attach = RXE_MAX_TOT_MCAST_QP_ATTACH; | |
120 | rxe->attr.max_ah = RXE_MAX_AH; | |
121 | rxe->attr.max_fmr = RXE_MAX_FMR; | |
122 | rxe->attr.max_map_per_fmr = RXE_MAX_MAP_PER_FMR; | |
123 | rxe->attr.max_srq = RXE_MAX_SRQ; | |
124 | rxe->attr.max_srq_wr = RXE_MAX_SRQ_WR; | |
125 | rxe->attr.max_srq_sge = RXE_MAX_SRQ_SGE; | |
126 | rxe->attr.max_fast_reg_page_list_len = RXE_MAX_FMR_PAGE_LIST_LEN; | |
127 | rxe->attr.max_pkeys = RXE_MAX_PKEYS; | |
128 | rxe->attr.local_ca_ack_delay = RXE_LOCAL_CA_ACK_DELAY; | |
129 | ||
130 | rxe->max_ucontext = RXE_MAX_UCONTEXT; | |
131 | ||
132 | return 0; | |
133 | } | |
134 | ||
135 | /* initialize port attributes */ | |
136 | static int rxe_init_port_param(struct rxe_port *port) | |
137 | { | |
138 | port->attr.state = RXE_PORT_STATE; | |
139 | port->attr.max_mtu = RXE_PORT_MAX_MTU; | |
140 | port->attr.active_mtu = RXE_PORT_ACTIVE_MTU; | |
141 | port->attr.gid_tbl_len = RXE_PORT_GID_TBL_LEN; | |
142 | port->attr.port_cap_flags = RXE_PORT_PORT_CAP_FLAGS; | |
143 | port->attr.max_msg_sz = RXE_PORT_MAX_MSG_SZ; | |
144 | port->attr.bad_pkey_cntr = RXE_PORT_BAD_PKEY_CNTR; | |
145 | port->attr.qkey_viol_cntr = RXE_PORT_QKEY_VIOL_CNTR; | |
146 | port->attr.pkey_tbl_len = RXE_PORT_PKEY_TBL_LEN; | |
147 | port->attr.lid = RXE_PORT_LID; | |
148 | port->attr.sm_lid = RXE_PORT_SM_LID; | |
149 | port->attr.lmc = RXE_PORT_LMC; | |
150 | port->attr.max_vl_num = RXE_PORT_MAX_VL_NUM; | |
151 | port->attr.sm_sl = RXE_PORT_SM_SL; | |
152 | port->attr.subnet_timeout = RXE_PORT_SUBNET_TIMEOUT; | |
153 | port->attr.init_type_reply = RXE_PORT_INIT_TYPE_REPLY; | |
154 | port->attr.active_width = RXE_PORT_ACTIVE_WIDTH; | |
155 | port->attr.active_speed = RXE_PORT_ACTIVE_SPEED; | |
156 | port->attr.phys_state = RXE_PORT_PHYS_STATE; | |
157 | port->mtu_cap = | |
158 | ib_mtu_enum_to_int(RXE_PORT_ACTIVE_MTU); | |
159 | port->subnet_prefix = cpu_to_be64(RXE_PORT_SUBNET_PREFIX); | |
160 | ||
161 | return 0; | |
162 | } | |
163 | ||
164 | /* initialize port state, note IB convention that HCA ports are always | |
165 | * numbered from 1 | |
166 | */ | |
167 | static int rxe_init_ports(struct rxe_dev *rxe) | |
168 | { | |
169 | struct rxe_port *port = &rxe->port; | |
170 | ||
171 | rxe_init_port_param(port); | |
172 | ||
8700e3e7 MS |
173 | port->pkey_tbl = kcalloc(port->attr.pkey_tbl_len, |
174 | sizeof(*port->pkey_tbl), GFP_KERNEL); | |
175 | ||
176 | if (!port->pkey_tbl) | |
177 | return -ENOMEM; | |
178 | ||
179 | port->pkey_tbl[0] = 0xffff; | |
4d6f2859 YS |
180 | addrconf_addr_eui48((unsigned char *)&port->port_guid, |
181 | rxe->ndev->dev_addr); | |
8700e3e7 MS |
182 | |
183 | spin_lock_init(&port->port_lock); | |
184 | ||
185 | return 0; | |
186 | } | |
187 | ||
188 | /* init pools of managed objects */ | |
189 | static int rxe_init_pools(struct rxe_dev *rxe) | |
190 | { | |
191 | int err; | |
192 | ||
193 | err = rxe_pool_init(rxe, &rxe->uc_pool, RXE_TYPE_UC, | |
194 | rxe->max_ucontext); | |
195 | if (err) | |
196 | goto err1; | |
197 | ||
198 | err = rxe_pool_init(rxe, &rxe->pd_pool, RXE_TYPE_PD, | |
199 | rxe->attr.max_pd); | |
200 | if (err) | |
201 | goto err2; | |
202 | ||
203 | err = rxe_pool_init(rxe, &rxe->ah_pool, RXE_TYPE_AH, | |
204 | rxe->attr.max_ah); | |
205 | if (err) | |
206 | goto err3; | |
207 | ||
208 | err = rxe_pool_init(rxe, &rxe->srq_pool, RXE_TYPE_SRQ, | |
209 | rxe->attr.max_srq); | |
210 | if (err) | |
211 | goto err4; | |
212 | ||
213 | err = rxe_pool_init(rxe, &rxe->qp_pool, RXE_TYPE_QP, | |
214 | rxe->attr.max_qp); | |
215 | if (err) | |
216 | goto err5; | |
217 | ||
218 | err = rxe_pool_init(rxe, &rxe->cq_pool, RXE_TYPE_CQ, | |
219 | rxe->attr.max_cq); | |
220 | if (err) | |
221 | goto err6; | |
222 | ||
223 | err = rxe_pool_init(rxe, &rxe->mr_pool, RXE_TYPE_MR, | |
224 | rxe->attr.max_mr); | |
225 | if (err) | |
226 | goto err7; | |
227 | ||
228 | err = rxe_pool_init(rxe, &rxe->mw_pool, RXE_TYPE_MW, | |
229 | rxe->attr.max_mw); | |
230 | if (err) | |
231 | goto err8; | |
232 | ||
233 | err = rxe_pool_init(rxe, &rxe->mc_grp_pool, RXE_TYPE_MC_GRP, | |
234 | rxe->attr.max_mcast_grp); | |
235 | if (err) | |
236 | goto err9; | |
237 | ||
238 | err = rxe_pool_init(rxe, &rxe->mc_elem_pool, RXE_TYPE_MC_ELEM, | |
239 | rxe->attr.max_total_mcast_qp_attach); | |
240 | if (err) | |
241 | goto err10; | |
242 | ||
243 | return 0; | |
244 | ||
245 | err10: | |
246 | rxe_pool_cleanup(&rxe->mc_grp_pool); | |
247 | err9: | |
248 | rxe_pool_cleanup(&rxe->mw_pool); | |
249 | err8: | |
250 | rxe_pool_cleanup(&rxe->mr_pool); | |
251 | err7: | |
252 | rxe_pool_cleanup(&rxe->cq_pool); | |
253 | err6: | |
254 | rxe_pool_cleanup(&rxe->qp_pool); | |
255 | err5: | |
256 | rxe_pool_cleanup(&rxe->srq_pool); | |
257 | err4: | |
258 | rxe_pool_cleanup(&rxe->ah_pool); | |
259 | err3: | |
260 | rxe_pool_cleanup(&rxe->pd_pool); | |
261 | err2: | |
262 | rxe_pool_cleanup(&rxe->uc_pool); | |
263 | err1: | |
264 | return err; | |
265 | } | |
266 | ||
267 | /* initialize rxe device state */ | |
268 | static int rxe_init(struct rxe_dev *rxe) | |
269 | { | |
270 | int err; | |
271 | ||
272 | /* init default device parameters */ | |
273 | rxe_init_device_param(rxe); | |
274 | ||
275 | err = rxe_init_ports(rxe); | |
276 | if (err) | |
277 | goto err1; | |
278 | ||
279 | err = rxe_init_pools(rxe); | |
280 | if (err) | |
281 | goto err2; | |
282 | ||
283 | /* init pending mmap list */ | |
284 | spin_lock_init(&rxe->mmap_offset_lock); | |
285 | spin_lock_init(&rxe->pending_lock); | |
286 | INIT_LIST_HEAD(&rxe->pending_mmaps); | |
287 | INIT_LIST_HEAD(&rxe->list); | |
288 | ||
289 | mutex_init(&rxe->usdev_lock); | |
290 | ||
291 | return 0; | |
292 | ||
293 | err2: | |
294 | rxe_cleanup_ports(rxe); | |
295 | err1: | |
296 | return err; | |
297 | } | |
298 | ||
299 | int rxe_set_mtu(struct rxe_dev *rxe, unsigned int ndev_mtu) | |
300 | { | |
301 | struct rxe_port *port = &rxe->port; | |
302 | enum ib_mtu mtu; | |
303 | ||
304 | mtu = eth_mtu_int_to_enum(ndev_mtu); | |
305 | ||
306 | /* Make sure that new MTU in range */ | |
307 | mtu = mtu ? min_t(enum ib_mtu, mtu, RXE_PORT_MAX_MTU) : IB_MTU_256; | |
308 | ||
309 | port->attr.active_mtu = mtu; | |
310 | port->mtu_cap = ib_mtu_enum_to_int(mtu); | |
311 | ||
312 | return 0; | |
313 | } | |
314 | EXPORT_SYMBOL(rxe_set_mtu); | |
315 | ||
316 | /* called by ifc layer to create new rxe device. | |
317 | * The caller should allocate memory for rxe by calling ib_alloc_device. | |
318 | */ | |
319 | int rxe_add(struct rxe_dev *rxe, unsigned int mtu) | |
320 | { | |
321 | int err; | |
322 | ||
323 | kref_init(&rxe->ref_cnt); | |
324 | ||
325 | err = rxe_init(rxe); | |
326 | if (err) | |
327 | goto err1; | |
328 | ||
329 | err = rxe_set_mtu(rxe, mtu); | |
330 | if (err) | |
331 | goto err1; | |
332 | ||
333 | err = rxe_register_device(rxe); | |
334 | if (err) | |
335 | goto err1; | |
336 | ||
337 | return 0; | |
338 | ||
339 | err1: | |
340 | rxe_dev_put(rxe); | |
341 | return err; | |
342 | } | |
343 | EXPORT_SYMBOL(rxe_add); | |
344 | ||
345 | /* called by the ifc layer to remove a device */ | |
346 | void rxe_remove(struct rxe_dev *rxe) | |
347 | { | |
348 | rxe_unregister_device(rxe); | |
349 | ||
350 | rxe_dev_put(rxe); | |
351 | } | |
352 | EXPORT_SYMBOL(rxe_remove); | |
353 | ||
354 | static int __init rxe_module_init(void) | |
355 | { | |
356 | int err; | |
357 | ||
358 | /* initialize slab caches for managed objects */ | |
359 | err = rxe_cache_init(); | |
360 | if (err) { | |
e404f945 | 361 | pr_err("unable to init object pools\n"); |
8700e3e7 MS |
362 | return err; |
363 | } | |
364 | ||
e404f945 PP |
365 | err = rxe_net_init(); |
366 | if (err) | |
367 | return err; | |
8700e3e7 | 368 | |
e404f945 | 369 | pr_info("loaded\n"); |
8700e3e7 MS |
370 | return 0; |
371 | } | |
372 | ||
373 | static void __exit rxe_module_exit(void) | |
374 | { | |
375 | rxe_remove_all(); | |
376 | rxe_net_exit(); | |
377 | rxe_cache_exit(); | |
378 | ||
e404f945 | 379 | pr_info("unloaded\n"); |
8700e3e7 MS |
380 | } |
381 | ||
b9fe856e | 382 | late_initcall(rxe_module_init); |
8700e3e7 | 383 | module_exit(rxe_module_exit); |