xref: /OK3568_Linux_fs/kernel/drivers/infiniband/sw/rxe/rxe.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright (c) 2016 Mellanox Technologies Ltd. All rights reserved.
4*4882a593Smuzhiyun  * Copyright (c) 2015 System Fabric Works, Inc. All rights reserved.
5*4882a593Smuzhiyun  */
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun #include <rdma/rdma_netlink.h>
8*4882a593Smuzhiyun #include <net/addrconf.h>
9*4882a593Smuzhiyun #include "rxe.h"
10*4882a593Smuzhiyun #include "rxe_loc.h"
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun MODULE_AUTHOR("Bob Pearson, Frank Zago, John Groves, Kamal Heib");
13*4882a593Smuzhiyun MODULE_DESCRIPTION("Soft RDMA transport");
14*4882a593Smuzhiyun MODULE_LICENSE("Dual BSD/GPL");
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun bool rxe_initialized;
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun /* free resources for a rxe device all objects created for this device must
19*4882a593Smuzhiyun  * have been destroyed
20*4882a593Smuzhiyun  */
rxe_dealloc(struct ib_device * ib_dev)21*4882a593Smuzhiyun void rxe_dealloc(struct ib_device *ib_dev)
22*4882a593Smuzhiyun {
23*4882a593Smuzhiyun 	struct rxe_dev *rxe = container_of(ib_dev, struct rxe_dev, ib_dev);
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun 	rxe_pool_cleanup(&rxe->uc_pool);
26*4882a593Smuzhiyun 	rxe_pool_cleanup(&rxe->pd_pool);
27*4882a593Smuzhiyun 	rxe_pool_cleanup(&rxe->ah_pool);
28*4882a593Smuzhiyun 	rxe_pool_cleanup(&rxe->srq_pool);
29*4882a593Smuzhiyun 	rxe_pool_cleanup(&rxe->qp_pool);
30*4882a593Smuzhiyun 	rxe_pool_cleanup(&rxe->cq_pool);
31*4882a593Smuzhiyun 	rxe_pool_cleanup(&rxe->mr_pool);
32*4882a593Smuzhiyun 	rxe_pool_cleanup(&rxe->mw_pool);
33*4882a593Smuzhiyun 	rxe_pool_cleanup(&rxe->mc_grp_pool);
34*4882a593Smuzhiyun 	rxe_pool_cleanup(&rxe->mc_elem_pool);
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun 	if (rxe->tfm)
37*4882a593Smuzhiyun 		crypto_free_shash(rxe->tfm);
38*4882a593Smuzhiyun }
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun /* initialize rxe device parameters */
rxe_init_device_param(struct rxe_dev * rxe)41*4882a593Smuzhiyun static void rxe_init_device_param(struct rxe_dev *rxe)
42*4882a593Smuzhiyun {
43*4882a593Smuzhiyun 	rxe->max_inline_data			= RXE_MAX_INLINE_DATA;
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun 	rxe->attr.vendor_id			= RXE_VENDOR_ID;
46*4882a593Smuzhiyun 	rxe->attr.max_mr_size			= RXE_MAX_MR_SIZE;
47*4882a593Smuzhiyun 	rxe->attr.page_size_cap			= RXE_PAGE_SIZE_CAP;
48*4882a593Smuzhiyun 	rxe->attr.max_qp			= RXE_MAX_QP;
49*4882a593Smuzhiyun 	rxe->attr.max_qp_wr			= RXE_MAX_QP_WR;
50*4882a593Smuzhiyun 	rxe->attr.device_cap_flags		= RXE_DEVICE_CAP_FLAGS;
51*4882a593Smuzhiyun 	rxe->attr.max_send_sge			= RXE_MAX_SGE;
52*4882a593Smuzhiyun 	rxe->attr.max_recv_sge			= RXE_MAX_SGE;
53*4882a593Smuzhiyun 	rxe->attr.max_sge_rd			= RXE_MAX_SGE_RD;
54*4882a593Smuzhiyun 	rxe->attr.max_cq			= RXE_MAX_CQ;
55*4882a593Smuzhiyun 	rxe->attr.max_cqe			= (1 << RXE_MAX_LOG_CQE) - 1;
56*4882a593Smuzhiyun 	rxe->attr.max_mr			= RXE_MAX_MR;
57*4882a593Smuzhiyun 	rxe->attr.max_pd			= RXE_MAX_PD;
58*4882a593Smuzhiyun 	rxe->attr.max_qp_rd_atom		= RXE_MAX_QP_RD_ATOM;
59*4882a593Smuzhiyun 	rxe->attr.max_res_rd_atom		= RXE_MAX_RES_RD_ATOM;
60*4882a593Smuzhiyun 	rxe->attr.max_qp_init_rd_atom		= RXE_MAX_QP_INIT_RD_ATOM;
61*4882a593Smuzhiyun 	rxe->attr.atomic_cap			= IB_ATOMIC_HCA;
62*4882a593Smuzhiyun 	rxe->attr.max_mcast_grp			= RXE_MAX_MCAST_GRP;
63*4882a593Smuzhiyun 	rxe->attr.max_mcast_qp_attach		= RXE_MAX_MCAST_QP_ATTACH;
64*4882a593Smuzhiyun 	rxe->attr.max_total_mcast_qp_attach	= RXE_MAX_TOT_MCAST_QP_ATTACH;
65*4882a593Smuzhiyun 	rxe->attr.max_ah			= RXE_MAX_AH;
66*4882a593Smuzhiyun 	rxe->attr.max_srq			= RXE_MAX_SRQ;
67*4882a593Smuzhiyun 	rxe->attr.max_srq_wr			= RXE_MAX_SRQ_WR;
68*4882a593Smuzhiyun 	rxe->attr.max_srq_sge			= RXE_MAX_SRQ_SGE;
69*4882a593Smuzhiyun 	rxe->attr.max_fast_reg_page_list_len	= RXE_MAX_FMR_PAGE_LIST_LEN;
70*4882a593Smuzhiyun 	rxe->attr.max_pkeys			= RXE_MAX_PKEYS;
71*4882a593Smuzhiyun 	rxe->attr.local_ca_ack_delay		= RXE_LOCAL_CA_ACK_DELAY;
72*4882a593Smuzhiyun 	addrconf_addr_eui48((unsigned char *)&rxe->attr.sys_image_guid,
73*4882a593Smuzhiyun 			rxe->ndev->dev_addr);
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun 	rxe->max_ucontext			= RXE_MAX_UCONTEXT;
76*4882a593Smuzhiyun }
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun /* initialize port attributes */
rxe_init_port_param(struct rxe_port * port)79*4882a593Smuzhiyun static void rxe_init_port_param(struct rxe_port *port)
80*4882a593Smuzhiyun {
81*4882a593Smuzhiyun 	port->attr.state		= IB_PORT_DOWN;
82*4882a593Smuzhiyun 	port->attr.max_mtu		= IB_MTU_4096;
83*4882a593Smuzhiyun 	port->attr.active_mtu		= IB_MTU_256;
84*4882a593Smuzhiyun 	port->attr.gid_tbl_len		= RXE_PORT_GID_TBL_LEN;
85*4882a593Smuzhiyun 	port->attr.port_cap_flags	= RXE_PORT_PORT_CAP_FLAGS;
86*4882a593Smuzhiyun 	port->attr.max_msg_sz		= RXE_PORT_MAX_MSG_SZ;
87*4882a593Smuzhiyun 	port->attr.bad_pkey_cntr	= RXE_PORT_BAD_PKEY_CNTR;
88*4882a593Smuzhiyun 	port->attr.qkey_viol_cntr	= RXE_PORT_QKEY_VIOL_CNTR;
89*4882a593Smuzhiyun 	port->attr.pkey_tbl_len		= RXE_PORT_PKEY_TBL_LEN;
90*4882a593Smuzhiyun 	port->attr.lid			= RXE_PORT_LID;
91*4882a593Smuzhiyun 	port->attr.sm_lid		= RXE_PORT_SM_LID;
92*4882a593Smuzhiyun 	port->attr.lmc			= RXE_PORT_LMC;
93*4882a593Smuzhiyun 	port->attr.max_vl_num		= RXE_PORT_MAX_VL_NUM;
94*4882a593Smuzhiyun 	port->attr.sm_sl		= RXE_PORT_SM_SL;
95*4882a593Smuzhiyun 	port->attr.subnet_timeout	= RXE_PORT_SUBNET_TIMEOUT;
96*4882a593Smuzhiyun 	port->attr.init_type_reply	= RXE_PORT_INIT_TYPE_REPLY;
97*4882a593Smuzhiyun 	port->attr.active_width		= RXE_PORT_ACTIVE_WIDTH;
98*4882a593Smuzhiyun 	port->attr.active_speed		= RXE_PORT_ACTIVE_SPEED;
99*4882a593Smuzhiyun 	port->attr.phys_state		= RXE_PORT_PHYS_STATE;
100*4882a593Smuzhiyun 	port->mtu_cap			= ib_mtu_enum_to_int(IB_MTU_256);
101*4882a593Smuzhiyun 	port->subnet_prefix		= cpu_to_be64(RXE_PORT_SUBNET_PREFIX);
102*4882a593Smuzhiyun }
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun /* initialize port state, note IB convention that HCA ports are always
105*4882a593Smuzhiyun  * numbered from 1
106*4882a593Smuzhiyun  */
rxe_init_ports(struct rxe_dev * rxe)107*4882a593Smuzhiyun static void rxe_init_ports(struct rxe_dev *rxe)
108*4882a593Smuzhiyun {
109*4882a593Smuzhiyun 	struct rxe_port *port = &rxe->port;
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun 	rxe_init_port_param(port);
112*4882a593Smuzhiyun 	addrconf_addr_eui48((unsigned char *)&port->port_guid,
113*4882a593Smuzhiyun 			    rxe->ndev->dev_addr);
114*4882a593Smuzhiyun 	spin_lock_init(&port->port_lock);
115*4882a593Smuzhiyun }
116*4882a593Smuzhiyun 
117*4882a593Smuzhiyun /* init pools of managed objects */
rxe_init_pools(struct rxe_dev * rxe)118*4882a593Smuzhiyun static int rxe_init_pools(struct rxe_dev *rxe)
119*4882a593Smuzhiyun {
120*4882a593Smuzhiyun 	int err;
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun 	err = rxe_pool_init(rxe, &rxe->uc_pool, RXE_TYPE_UC,
123*4882a593Smuzhiyun 			    rxe->max_ucontext);
124*4882a593Smuzhiyun 	if (err)
125*4882a593Smuzhiyun 		goto err1;
126*4882a593Smuzhiyun 
127*4882a593Smuzhiyun 	err = rxe_pool_init(rxe, &rxe->pd_pool, RXE_TYPE_PD,
128*4882a593Smuzhiyun 			    rxe->attr.max_pd);
129*4882a593Smuzhiyun 	if (err)
130*4882a593Smuzhiyun 		goto err2;
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun 	err = rxe_pool_init(rxe, &rxe->ah_pool, RXE_TYPE_AH,
133*4882a593Smuzhiyun 			    rxe->attr.max_ah);
134*4882a593Smuzhiyun 	if (err)
135*4882a593Smuzhiyun 		goto err3;
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun 	err = rxe_pool_init(rxe, &rxe->srq_pool, RXE_TYPE_SRQ,
138*4882a593Smuzhiyun 			    rxe->attr.max_srq);
139*4882a593Smuzhiyun 	if (err)
140*4882a593Smuzhiyun 		goto err4;
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun 	err = rxe_pool_init(rxe, &rxe->qp_pool, RXE_TYPE_QP,
143*4882a593Smuzhiyun 			    rxe->attr.max_qp);
144*4882a593Smuzhiyun 	if (err)
145*4882a593Smuzhiyun 		goto err5;
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun 	err = rxe_pool_init(rxe, &rxe->cq_pool, RXE_TYPE_CQ,
148*4882a593Smuzhiyun 			    rxe->attr.max_cq);
149*4882a593Smuzhiyun 	if (err)
150*4882a593Smuzhiyun 		goto err6;
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun 	err = rxe_pool_init(rxe, &rxe->mr_pool, RXE_TYPE_MR,
153*4882a593Smuzhiyun 			    rxe->attr.max_mr);
154*4882a593Smuzhiyun 	if (err)
155*4882a593Smuzhiyun 		goto err7;
156*4882a593Smuzhiyun 
157*4882a593Smuzhiyun 	err = rxe_pool_init(rxe, &rxe->mw_pool, RXE_TYPE_MW,
158*4882a593Smuzhiyun 			    rxe->attr.max_mw);
159*4882a593Smuzhiyun 	if (err)
160*4882a593Smuzhiyun 		goto err8;
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun 	err = rxe_pool_init(rxe, &rxe->mc_grp_pool, RXE_TYPE_MC_GRP,
163*4882a593Smuzhiyun 			    rxe->attr.max_mcast_grp);
164*4882a593Smuzhiyun 	if (err)
165*4882a593Smuzhiyun 		goto err9;
166*4882a593Smuzhiyun 
167*4882a593Smuzhiyun 	err = rxe_pool_init(rxe, &rxe->mc_elem_pool, RXE_TYPE_MC_ELEM,
168*4882a593Smuzhiyun 			    rxe->attr.max_total_mcast_qp_attach);
169*4882a593Smuzhiyun 	if (err)
170*4882a593Smuzhiyun 		goto err10;
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun 	return 0;
173*4882a593Smuzhiyun 
174*4882a593Smuzhiyun err10:
175*4882a593Smuzhiyun 	rxe_pool_cleanup(&rxe->mc_grp_pool);
176*4882a593Smuzhiyun err9:
177*4882a593Smuzhiyun 	rxe_pool_cleanup(&rxe->mw_pool);
178*4882a593Smuzhiyun err8:
179*4882a593Smuzhiyun 	rxe_pool_cleanup(&rxe->mr_pool);
180*4882a593Smuzhiyun err7:
181*4882a593Smuzhiyun 	rxe_pool_cleanup(&rxe->cq_pool);
182*4882a593Smuzhiyun err6:
183*4882a593Smuzhiyun 	rxe_pool_cleanup(&rxe->qp_pool);
184*4882a593Smuzhiyun err5:
185*4882a593Smuzhiyun 	rxe_pool_cleanup(&rxe->srq_pool);
186*4882a593Smuzhiyun err4:
187*4882a593Smuzhiyun 	rxe_pool_cleanup(&rxe->ah_pool);
188*4882a593Smuzhiyun err3:
189*4882a593Smuzhiyun 	rxe_pool_cleanup(&rxe->pd_pool);
190*4882a593Smuzhiyun err2:
191*4882a593Smuzhiyun 	rxe_pool_cleanup(&rxe->uc_pool);
192*4882a593Smuzhiyun err1:
193*4882a593Smuzhiyun 	return err;
194*4882a593Smuzhiyun }
195*4882a593Smuzhiyun 
196*4882a593Smuzhiyun /* initialize rxe device state */
rxe_init(struct rxe_dev * rxe)197*4882a593Smuzhiyun static int rxe_init(struct rxe_dev *rxe)
198*4882a593Smuzhiyun {
199*4882a593Smuzhiyun 	int err;
200*4882a593Smuzhiyun 
201*4882a593Smuzhiyun 	/* init default device parameters */
202*4882a593Smuzhiyun 	rxe_init_device_param(rxe);
203*4882a593Smuzhiyun 
204*4882a593Smuzhiyun 	rxe_init_ports(rxe);
205*4882a593Smuzhiyun 
206*4882a593Smuzhiyun 	err = rxe_init_pools(rxe);
207*4882a593Smuzhiyun 	if (err)
208*4882a593Smuzhiyun 		return err;
209*4882a593Smuzhiyun 
210*4882a593Smuzhiyun 	/* init pending mmap list */
211*4882a593Smuzhiyun 	spin_lock_init(&rxe->mmap_offset_lock);
212*4882a593Smuzhiyun 	spin_lock_init(&rxe->pending_lock);
213*4882a593Smuzhiyun 	INIT_LIST_HEAD(&rxe->pending_mmaps);
214*4882a593Smuzhiyun 
215*4882a593Smuzhiyun 	mutex_init(&rxe->usdev_lock);
216*4882a593Smuzhiyun 
217*4882a593Smuzhiyun 	return 0;
218*4882a593Smuzhiyun }
219*4882a593Smuzhiyun 
rxe_set_mtu(struct rxe_dev * rxe,unsigned int ndev_mtu)220*4882a593Smuzhiyun void rxe_set_mtu(struct rxe_dev *rxe, unsigned int ndev_mtu)
221*4882a593Smuzhiyun {
222*4882a593Smuzhiyun 	struct rxe_port *port = &rxe->port;
223*4882a593Smuzhiyun 	enum ib_mtu mtu;
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun 	mtu = eth_mtu_int_to_enum(ndev_mtu);
226*4882a593Smuzhiyun 
227*4882a593Smuzhiyun 	/* Make sure that new MTU in range */
228*4882a593Smuzhiyun 	mtu = mtu ? min_t(enum ib_mtu, mtu, IB_MTU_4096) : IB_MTU_256;
229*4882a593Smuzhiyun 
230*4882a593Smuzhiyun 	port->attr.active_mtu = mtu;
231*4882a593Smuzhiyun 	port->mtu_cap = ib_mtu_enum_to_int(mtu);
232*4882a593Smuzhiyun }
233*4882a593Smuzhiyun 
234*4882a593Smuzhiyun /* called by ifc layer to create new rxe device.
235*4882a593Smuzhiyun  * The caller should allocate memory for rxe by calling ib_alloc_device.
236*4882a593Smuzhiyun  */
rxe_add(struct rxe_dev * rxe,unsigned int mtu,const char * ibdev_name)237*4882a593Smuzhiyun int rxe_add(struct rxe_dev *rxe, unsigned int mtu, const char *ibdev_name)
238*4882a593Smuzhiyun {
239*4882a593Smuzhiyun 	int err;
240*4882a593Smuzhiyun 
241*4882a593Smuzhiyun 	err = rxe_init(rxe);
242*4882a593Smuzhiyun 	if (err)
243*4882a593Smuzhiyun 		return err;
244*4882a593Smuzhiyun 
245*4882a593Smuzhiyun 	rxe_set_mtu(rxe, mtu);
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun 	return rxe_register_device(rxe, ibdev_name);
248*4882a593Smuzhiyun }
249*4882a593Smuzhiyun 
rxe_newlink(const char * ibdev_name,struct net_device * ndev)250*4882a593Smuzhiyun static int rxe_newlink(const char *ibdev_name, struct net_device *ndev)
251*4882a593Smuzhiyun {
252*4882a593Smuzhiyun 	struct rxe_dev *exists;
253*4882a593Smuzhiyun 	int err = 0;
254*4882a593Smuzhiyun 
255*4882a593Smuzhiyun 	if (is_vlan_dev(ndev)) {
256*4882a593Smuzhiyun 		pr_err("rxe creation allowed on top of a real device only\n");
257*4882a593Smuzhiyun 		err = -EPERM;
258*4882a593Smuzhiyun 		goto err;
259*4882a593Smuzhiyun 	}
260*4882a593Smuzhiyun 
261*4882a593Smuzhiyun 	exists = rxe_get_dev_from_net(ndev);
262*4882a593Smuzhiyun 	if (exists) {
263*4882a593Smuzhiyun 		ib_device_put(&exists->ib_dev);
264*4882a593Smuzhiyun 		pr_err("already configured on %s\n", ndev->name);
265*4882a593Smuzhiyun 		err = -EEXIST;
266*4882a593Smuzhiyun 		goto err;
267*4882a593Smuzhiyun 	}
268*4882a593Smuzhiyun 
269*4882a593Smuzhiyun 	err = rxe_net_add(ibdev_name, ndev);
270*4882a593Smuzhiyun 	if (err) {
271*4882a593Smuzhiyun 		pr_err("failed to add %s\n", ndev->name);
272*4882a593Smuzhiyun 		goto err;
273*4882a593Smuzhiyun 	}
274*4882a593Smuzhiyun err:
275*4882a593Smuzhiyun 	return err;
276*4882a593Smuzhiyun }
277*4882a593Smuzhiyun 
278*4882a593Smuzhiyun static struct rdma_link_ops rxe_link_ops = {
279*4882a593Smuzhiyun 	.type = "rxe",
280*4882a593Smuzhiyun 	.newlink = rxe_newlink,
281*4882a593Smuzhiyun };
282*4882a593Smuzhiyun 
rxe_module_init(void)283*4882a593Smuzhiyun static int __init rxe_module_init(void)
284*4882a593Smuzhiyun {
285*4882a593Smuzhiyun 	int err;
286*4882a593Smuzhiyun 
287*4882a593Smuzhiyun 	err = rxe_net_init();
288*4882a593Smuzhiyun 	if (err)
289*4882a593Smuzhiyun 		return err;
290*4882a593Smuzhiyun 
291*4882a593Smuzhiyun 	rdma_link_register(&rxe_link_ops);
292*4882a593Smuzhiyun 	rxe_initialized = true;
293*4882a593Smuzhiyun 	pr_info("loaded\n");
294*4882a593Smuzhiyun 	return 0;
295*4882a593Smuzhiyun }
296*4882a593Smuzhiyun 
rxe_module_exit(void)297*4882a593Smuzhiyun static void __exit rxe_module_exit(void)
298*4882a593Smuzhiyun {
299*4882a593Smuzhiyun 	rdma_link_unregister(&rxe_link_ops);
300*4882a593Smuzhiyun 	ib_unregister_driver(RDMA_DRIVER_RXE);
301*4882a593Smuzhiyun 	rxe_net_exit();
302*4882a593Smuzhiyun 
303*4882a593Smuzhiyun 	rxe_initialized = false;
304*4882a593Smuzhiyun 	pr_info("unloaded\n");
305*4882a593Smuzhiyun }
306*4882a593Smuzhiyun 
307*4882a593Smuzhiyun late_initcall(rxe_module_init);
308*4882a593Smuzhiyun module_exit(rxe_module_exit);
309*4882a593Smuzhiyun 
310*4882a593Smuzhiyun MODULE_ALIAS_RDMA_LINK("rxe");
311