xref: /freebsd/sys/dev/cxgbe/iw_cxgbe/provider.c (revision 5c831a5bd61576cacb48b39f8eeb47b92707a355)
1 /*
2  * Copyright (c) 2009-2013, 2016 Chelsio, Inc. All rights reserved.
3  *
4  * This software is available to you under a choice of one of two
5  * licenses.  You may choose to be licensed under the terms of the GNU
6  * General Public License (GPL) Version 2, available from the file
7  * COPYING in the main directory of this source tree, or the
8  * OpenIB.org BSD license below:
9  *
10  *     Redistribution and use in source and binary forms, with or
11  *     without modification, are permitted provided that the following
12  *     conditions are met:
13  *
14  *      - Redistributions of source code must retain the above
15  *        copyright notice, this list of conditions and the following
16  *        disclaimer.
17  *
18  *      - Redistributions in binary form must reproduce the above
19  *        copyright notice, this list of conditions and the following
20  *        disclaimer in the documentation and/or other materials
21  *        provided with the distribution.
22  *
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30  * SOFTWARE.
31  */
32 #include <sys/cdefs.h>
33 __FBSDID("$FreeBSD$");
34 
35 #define	LINUXKPI_PARAM_PREFIX iw_cxgbe_
36 
37 #include "opt_inet.h"
38 
39 #ifdef TCP_OFFLOAD
40 #include <asm/pgtable.h>
41 #include <linux/page.h>
42 #include <rdma/ib_verbs.h>
43 #include <rdma/ib_user_verbs.h>
44 
45 #include "iw_cxgbe.h"
46 #include "user.h"
47 
48 static int fastreg_support = 1;
49 module_param(fastreg_support, int, 0644);
50 MODULE_PARM_DESC(fastreg_support, "Advertise fastreg support (default = 1)");
51 
52 static int c4iw_modify_port(struct ib_device *ibdev,
53 			    u8 port, int port_modify_mask,
54 			    struct ib_port_modify *props)
55 {
56 	return -ENOSYS;
57 }
58 
59 static struct ib_ah *c4iw_ah_create(struct ib_pd *pd,
60 				    struct ib_ah_attr *ah_attr)
61 {
62 	return ERR_PTR(-ENOSYS);
63 }
64 
65 static int c4iw_ah_destroy(struct ib_ah *ah)
66 {
67 	return -ENOSYS;
68 }
69 
70 static int c4iw_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
71 {
72 	return -ENOSYS;
73 }
74 
75 static int c4iw_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
76 {
77 	return -ENOSYS;
78 }
79 
80 static int c4iw_process_mad(struct ib_device *ibdev, int mad_flags,
81 			    u8 port_num, struct ib_wc *in_wc,
82 			    struct ib_grh *in_grh, struct ib_mad *in_mad,
83 			    struct ib_mad *out_mad)
84 {
85 	return -ENOSYS;
86 }
87 
88 static int c4iw_dealloc_ucontext(struct ib_ucontext *context)
89 {
90 	struct c4iw_dev *rhp = to_c4iw_dev(context->device);
91 	struct c4iw_ucontext *ucontext = to_c4iw_ucontext(context);
92 	struct c4iw_mm_entry *mm, *tmp;
93 
94 	CTR2(KTR_IW_CXGBE, "%s context %p", __func__, context);
95 	list_for_each_entry_safe(mm, tmp, &ucontext->mmaps, entry)
96 		kfree(mm);
97 	c4iw_release_dev_ucontext(&rhp->rdev, &ucontext->uctx);
98 	kfree(ucontext);
99 	return 0;
100 }
101 
102 static struct ib_ucontext *c4iw_alloc_ucontext(struct ib_device *ibdev,
103 					       struct ib_udata *udata)
104 {
105 	struct c4iw_ucontext *context;
106 	struct c4iw_dev *rhp = to_c4iw_dev(ibdev);
107 
108 	CTR2(KTR_IW_CXGBE, "%s ibdev %p", __func__, ibdev);
109 	context = kzalloc(sizeof(*context), GFP_KERNEL);
110 	if (!context)
111 		return ERR_PTR(-ENOMEM);
112 	c4iw_init_dev_ucontext(&rhp->rdev, &context->uctx);
113 	INIT_LIST_HEAD(&context->mmaps);
114 	spin_lock_init(&context->mmap_lock);
115 	return &context->ibucontext;
116 }
117 
118 #ifdef DOT5
119 static inline pgprot_t t4_pgprot_wc(pgprot_t prot)
120 {
121     return pgprot_writecombine(prot);
122 }
123 #endif
124 
125 static int c4iw_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
126 {
127 	int len = vma->vm_end - vma->vm_start;
128 	u32 key = vma->vm_pgoff << PAGE_SHIFT;
129 	struct c4iw_rdev *rdev;
130 	int ret = 0;
131 	struct c4iw_mm_entry *mm;
132 	struct c4iw_ucontext *ucontext;
133 	u64 addr, paddr;
134 
135 	u64 va_regs_res = 0, va_udbs_res = 0;
136 	u64 len_regs_res = 0, len_udbs_res = 0;
137 
138 	CTR3(KTR_IW_CXGBE, "%s:1 ctx %p vma %p", __func__, context, vma);
139 
140 	CTR4(KTR_IW_CXGBE, "%s:1a pgoff 0x%lx key 0x%x len %d", __func__,
141 	    vma->vm_pgoff, key, len);
142 
143 	if (vma->vm_start & (PAGE_SIZE-1)) {
144 		CTR3(KTR_IW_CXGBE, "%s:2 unaligned vm_start %u vma %p",
145 		    __func__, vma->vm_start, vma);
146 		return -EINVAL;
147 	}
148 
149 	rdev = &(to_c4iw_dev(context->device)->rdev);
150 	ucontext = to_c4iw_ucontext(context);
151 
152 	mm = remove_mmap(ucontext, key, len);
153 	if (!mm) {
154 		CTR4(KTR_IW_CXGBE, "%s:3 ucontext %p key %u len %u", __func__,
155 		    ucontext, key, len);
156 		return -EINVAL;
157 	}
158 	addr = mm->addr;
159 	kfree(mm);
160 
161 	va_regs_res = (u64)rman_get_virtual(rdev->adap->regs_res);
162 	len_regs_res = (u64)rman_get_size(rdev->adap->regs_res);
163 	va_udbs_res = (u64)rman_get_virtual(rdev->adap->udbs_res);
164 	len_udbs_res = (u64)rman_get_size(rdev->adap->udbs_res);
165 
166 	CTR6(KTR_IW_CXGBE,
167 	    "%s:4 addr %p, masync region %p:%p, udb region %p:%p", __func__,
168 	    addr, va_regs_res, va_regs_res+len_regs_res, va_udbs_res,
169 	    va_udbs_res+len_udbs_res);
170 
171 	if (addr >= va_regs_res && addr < va_regs_res + len_regs_res) {
172 		CTR4(KTR_IW_CXGBE, "%s:5 MA_SYNC addr %p region %p, reglen %u",
173 		    __func__, addr, va_regs_res, len_regs_res);
174 		/*
175 		 * MA_SYNC register...
176 		 */
177 		paddr = vtophys(addr);
178 		vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
179 		ret = io_remap_pfn_range(vma, vma->vm_start,
180 				paddr >> PAGE_SHIFT,
181 				len, vma->vm_page_prot);
182 	} else {
183 
184 		if (addr >= va_udbs_res && addr < va_udbs_res + len_udbs_res) {
185 			/*
186 			* Map user DB or OCQP memory...
187 			*/
188 			paddr = vtophys(addr);
189 			CTR4(KTR_IW_CXGBE,
190 			    "%s:6 USER DB-GTS addr %p region %p, reglen %u",
191 			    __func__, addr, va_udbs_res, len_udbs_res);
192 #ifdef DOT5
193 			if (!is_t4(rdev->lldi.adapter_type) && map_udb_as_wc)
194 				vma->vm_page_prot = t4_pgprot_wc(vma->vm_page_prot);
195 			else
196 #endif
197 				vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
198 			ret = io_remap_pfn_range(vma, vma->vm_start,
199 					paddr >> PAGE_SHIFT,
200 					len, vma->vm_page_prot);
201 		} else {
202 			/*
203 			 * Map WQ or CQ contig dma memory...
204 			 */
205 			CTR4(KTR_IW_CXGBE,
206 			    "%s:7 WQ/CQ addr %p vm_start %u vma %p", __func__,
207 			    addr, vma->vm_start, vma);
208 			ret = io_remap_pfn_range(vma, vma->vm_start,
209 				addr >> PAGE_SHIFT,
210 				len, vma->vm_page_prot);
211 		}
212 	}
213 	CTR4(KTR_IW_CXGBE, "%s:8 ctx %p vma %p ret %u", __func__, context, vma,
214 	    ret);
215 	return ret;
216 }
217 
218 static int
219 c4iw_deallocate_pd(struct ib_pd *pd)
220 {
221 	struct c4iw_pd *php = to_c4iw_pd(pd);
222 	struct c4iw_dev *rhp = php->rhp;
223 
224 	CTR3(KTR_IW_CXGBE, "%s: pd %p, pdid 0x%x", __func__, pd, php->pdid);
225 
226 	c4iw_put_resource(&rhp->rdev.resource.pdid_table, php->pdid);
227 	mutex_lock(&rhp->rdev.stats.lock);
228 	rhp->rdev.stats.pd.cur--;
229 	mutex_unlock(&rhp->rdev.stats.lock);
230 	kfree(php);
231 
232 	return (0);
233 }
234 
235 static struct ib_pd *
236 c4iw_allocate_pd(struct ib_device *ibdev, struct ib_ucontext *context,
237     struct ib_udata *udata)
238 {
239 	struct c4iw_pd *php;
240 	u32 pdid;
241 	struct c4iw_dev *rhp;
242 
243 	CTR4(KTR_IW_CXGBE, "%s: ibdev %p, context %p, data %p", __func__, ibdev,
244 	    context, udata);
245 	rhp = (struct c4iw_dev *) ibdev;
246 	pdid =  c4iw_get_resource(&rhp->rdev.resource.pdid_table);
247 	if (!pdid)
248 		return ERR_PTR(-EINVAL);
249 	php = kzalloc(sizeof(*php), GFP_KERNEL);
250 	if (!php) {
251 		c4iw_put_resource(&rhp->rdev.resource.pdid_table, pdid);
252 		return ERR_PTR(-ENOMEM);
253 	}
254 	php->pdid = pdid;
255 	php->rhp = rhp;
256 	if (context) {
257 		if (ib_copy_to_udata(udata, &php->pdid, sizeof(u32))) {
258 			c4iw_deallocate_pd(&php->ibpd);
259 			return ERR_PTR(-EFAULT);
260 		}
261 	}
262 	mutex_lock(&rhp->rdev.stats.lock);
263 	rhp->rdev.stats.pd.cur++;
264 	if (rhp->rdev.stats.pd.cur > rhp->rdev.stats.pd.max)
265 		rhp->rdev.stats.pd.max = rhp->rdev.stats.pd.cur;
266 	mutex_unlock(&rhp->rdev.stats.lock);
267 
268 	CTR6(KTR_IW_CXGBE,
269 	    "%s: ibdev %p, context %p, data %p, pddid 0x%x, pd %p", __func__,
270 	    ibdev, context, udata, pdid, php);
271 	return (&php->ibpd);
272 }
273 
274 static int
275 c4iw_query_pkey(struct ib_device *ibdev, u8 port, u16 index, u16 *pkey)
276 {
277 
278 	CTR5(KTR_IW_CXGBE, "%s ibdev %p, port %d, index %d, pkey %p", __func__,
279 	    ibdev, port, index, pkey);
280 
281 	*pkey = 0;
282 	return (0);
283 }
284 
285 static int
286 c4iw_query_gid(struct ib_device *ibdev, u8 port, int index, union ib_gid *gid)
287 {
288 	struct c4iw_dev *dev;
289 	struct port_info *pi;
290 	struct adapter *sc;
291 
292 	CTR5(KTR_IW_CXGBE, "%s ibdev %p, port %d, index %d, gid %p", __func__,
293 	    ibdev, port, index, gid);
294 
295 	memset(&gid->raw[0], 0, sizeof(gid->raw));
296 	dev = to_c4iw_dev(ibdev);
297 	sc = dev->rdev.adap;
298 	if (port == 0 || port > sc->params.nports)
299 		return (-EINVAL);
300 	pi = sc->port[port - 1];
301 	memcpy(&gid->raw[0], pi->vi[0].hw_addr, ETHER_ADDR_LEN);
302 	return (0);
303 }
304 
305 static int
306 c4iw_query_device(struct ib_device *ibdev, struct ib_device_attr *props)
307 {
308 	struct c4iw_dev *dev = to_c4iw_dev(ibdev);
309 	struct adapter *sc = dev->rdev.adap;
310 	const int spg_ndesc = sc->params.sge.spg_len / EQ_ESIZE;
311 
312 	CTR3(KTR_IW_CXGBE, "%s ibdev %p, props %p", __func__, ibdev, props);
313 
314 	memset(props, 0, sizeof *props);
315 	memcpy(&props->sys_image_guid, sc->port[0]->vi[0].hw_addr,
316 	    ETHER_ADDR_LEN);
317 	props->hw_ver = sc->params.chipid;
318 	props->fw_ver = sc->params.fw_vers;
319 	props->device_cap_flags = dev->device_cap_flags;
320 	props->page_size_cap = T4_PAGESIZE_MASK;
321 	props->vendor_id = pci_get_vendor(sc->dev);
322 	props->vendor_part_id = pci_get_device(sc->dev);
323 	props->max_mr_size = T4_MAX_MR_SIZE;
324 	props->max_qp = sc->vres.qp.size / 2;
325 	props->max_qp_wr = T4_MAX_QP_DEPTH(spg_ndesc);
326 	props->max_sge = T4_MAX_RECV_SGE;
327 	props->max_sge_rd = 1;
328 	props->max_res_rd_atom = sc->params.max_ird_adapter;
329 	props->max_qp_rd_atom = min(sc->params.max_ordird_qp,
330 	    c4iw_max_read_depth);
331 	props->max_qp_init_rd_atom = props->max_qp_rd_atom;
332 	props->max_cq = sc->vres.qp.size;
333 	props->max_cqe = T4_MAX_CQ_DEPTH;
334 	props->max_mr = c4iw_num_stags(&dev->rdev);
335 	props->max_pd = T4_MAX_NUM_PD;
336 	props->local_ca_ack_delay = 0;
337 	props->max_fast_reg_page_list_len = T4_MAX_FR_DEPTH;
338 
339 	return (0);
340 }
341 
342 /*
343  * Returns -errno on failure.
344  */
345 static int
346 c4iw_query_port(struct ib_device *ibdev, u8 port, struct ib_port_attr *props)
347 {
348 	struct c4iw_dev *dev;
349 	struct adapter *sc;
350 	struct port_info *pi;
351 	struct ifnet *ifp;
352 
353 	CTR4(KTR_IW_CXGBE, "%s ibdev %p, port %d, props %p", __func__, ibdev,
354 	    port, props);
355 
356 	dev = to_c4iw_dev(ibdev);
357 	sc = dev->rdev.adap;
358 	if (port > sc->params.nports)
359 		return (-EINVAL);
360 	pi = sc->port[port - 1];
361 	ifp = pi->vi[0].ifp;
362 
363 	memset(props, 0, sizeof(struct ib_port_attr));
364 	props->max_mtu = IB_MTU_4096;
365 	if (ifp->if_mtu >= 4096)
366 		props->active_mtu = IB_MTU_4096;
367 	else if (ifp->if_mtu >= 2048)
368 		props->active_mtu = IB_MTU_2048;
369 	else if (ifp->if_mtu >= 1024)
370 		props->active_mtu = IB_MTU_1024;
371 	else if (ifp->if_mtu >= 512)
372 		props->active_mtu = IB_MTU_512;
373 	else
374 		props->active_mtu = IB_MTU_256;
375 	props->state = pi->link_cfg.link_ok ? IB_PORT_ACTIVE : IB_PORT_DOWN;
376 	props->port_cap_flags =
377 	    IB_PORT_CM_SUP |
378 	    IB_PORT_SNMP_TUNNEL_SUP |
379 	    IB_PORT_REINIT_SUP |
380 	    IB_PORT_DEVICE_MGMT_SUP |
381 	    IB_PORT_VENDOR_CLASS_SUP | IB_PORT_BOOT_MGMT_SUP;
382 	props->gid_tbl_len = 1;
383 	props->pkey_tbl_len = 1;
384 	props->active_width = 2;
385 	props->active_speed = 2;
386 	props->max_msg_sz = -1;
387 
388 	return 0;
389 }
390 
391 /*
392  * Returns -errno on error.
393  */
394 int
395 c4iw_register_device(struct c4iw_dev *dev)
396 {
397 	struct adapter *sc = dev->rdev.adap;
398 	struct ib_device *ibdev = &dev->ibdev;
399 	struct iw_cm_verbs *iwcm;
400 	int ret;
401 
402 	CTR3(KTR_IW_CXGBE, "%s c4iw_dev %p, adapter %p", __func__, dev, sc);
403 	BUG_ON(!sc->port[0]);
404 	strlcpy(ibdev->name, device_get_nameunit(sc->dev), sizeof(ibdev->name));
405 	memset(&ibdev->node_guid, 0, sizeof(ibdev->node_guid));
406 	memcpy(&ibdev->node_guid, sc->port[0]->vi[0].hw_addr, ETHER_ADDR_LEN);
407 	ibdev->owner = THIS_MODULE;
408 	dev->device_cap_flags = IB_DEVICE_LOCAL_DMA_LKEY | IB_DEVICE_MEM_WINDOW;
409 	if (fastreg_support)
410 		dev->device_cap_flags |= IB_DEVICE_MEM_MGT_EXTENSIONS;
411 	ibdev->local_dma_lkey = 0;
412 	ibdev->uverbs_cmd_mask =
413 	    (1ull << IB_USER_VERBS_CMD_GET_CONTEXT) |
414 	    (1ull << IB_USER_VERBS_CMD_QUERY_DEVICE) |
415 	    (1ull << IB_USER_VERBS_CMD_QUERY_PORT) |
416 	    (1ull << IB_USER_VERBS_CMD_ALLOC_PD) |
417 	    (1ull << IB_USER_VERBS_CMD_DEALLOC_PD) |
418 	    (1ull << IB_USER_VERBS_CMD_REG_MR) |
419 	    (1ull << IB_USER_VERBS_CMD_DEREG_MR) |
420 	    (1ull << IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL) |
421 	    (1ull << IB_USER_VERBS_CMD_CREATE_CQ) |
422 	    (1ull << IB_USER_VERBS_CMD_DESTROY_CQ) |
423 	    (1ull << IB_USER_VERBS_CMD_REQ_NOTIFY_CQ) |
424 	    (1ull << IB_USER_VERBS_CMD_CREATE_QP) |
425 	    (1ull << IB_USER_VERBS_CMD_MODIFY_QP) |
426 	    (1ull << IB_USER_VERBS_CMD_QUERY_QP) |
427 	    (1ull << IB_USER_VERBS_CMD_POLL_CQ) |
428 	    (1ull << IB_USER_VERBS_CMD_DESTROY_QP) |
429 	    (1ull << IB_USER_VERBS_CMD_POST_SEND) |
430 	    (1ull << IB_USER_VERBS_CMD_POST_RECV);
431 	ibdev->node_type = RDMA_NODE_RNIC;
432 	strlcpy(ibdev->node_desc, C4IW_NODE_DESC, sizeof(ibdev->node_desc));
433 	ibdev->phys_port_cnt = sc->params.nports;
434 	ibdev->num_comp_vectors = 1;
435 	ibdev->dma_device = NULL;
436 	ibdev->query_device = c4iw_query_device;
437 	ibdev->query_port = c4iw_query_port;
438 	ibdev->modify_port = c4iw_modify_port;
439 	ibdev->query_pkey = c4iw_query_pkey;
440 	ibdev->query_gid = c4iw_query_gid;
441 	ibdev->alloc_ucontext = c4iw_alloc_ucontext;
442 	ibdev->dealloc_ucontext = c4iw_dealloc_ucontext;
443 	ibdev->mmap = c4iw_mmap;
444 	ibdev->alloc_pd = c4iw_allocate_pd;
445 	ibdev->dealloc_pd = c4iw_deallocate_pd;
446 	ibdev->create_ah = c4iw_ah_create;
447 	ibdev->destroy_ah = c4iw_ah_destroy;
448 	ibdev->create_qp = c4iw_create_qp;
449 	ibdev->modify_qp = c4iw_ib_modify_qp;
450 	ibdev->query_qp = c4iw_ib_query_qp;
451 	ibdev->destroy_qp = c4iw_destroy_qp;
452 	ibdev->create_cq = c4iw_create_cq;
453 	ibdev->destroy_cq = c4iw_destroy_cq;
454 	ibdev->resize_cq = c4iw_resize_cq;
455 	ibdev->poll_cq = c4iw_poll_cq;
456 	ibdev->get_dma_mr = c4iw_get_dma_mr;
457 	ibdev->reg_phys_mr = c4iw_register_phys_mem;
458 	ibdev->rereg_phys_mr = c4iw_reregister_phys_mem;
459 	ibdev->reg_user_mr = c4iw_reg_user_mr;
460 	ibdev->dereg_mr = c4iw_dereg_mr;
461 	ibdev->alloc_mw = c4iw_alloc_mw;
462 	ibdev->bind_mw = c4iw_bind_mw;
463 	ibdev->dealloc_mw = c4iw_dealloc_mw;
464 	ibdev->alloc_fast_reg_mr = c4iw_alloc_fast_reg_mr;
465 	ibdev->alloc_fast_reg_page_list = c4iw_alloc_fastreg_pbl;
466 	ibdev->free_fast_reg_page_list = c4iw_free_fastreg_pbl;
467 	ibdev->attach_mcast = c4iw_multicast_attach;
468 	ibdev->detach_mcast = c4iw_multicast_detach;
469 	ibdev->process_mad = c4iw_process_mad;
470 	ibdev->req_notify_cq = c4iw_arm_cq;
471 	ibdev->post_send = c4iw_post_send;
472 	ibdev->post_recv = c4iw_post_receive;
473 	ibdev->uverbs_abi_ver = C4IW_UVERBS_ABI_VERSION;
474 
475 	iwcm = kmalloc(sizeof(*iwcm), GFP_KERNEL);
476 	if (iwcm == NULL)
477 		return (-ENOMEM);
478 
479 	iwcm->connect = c4iw_connect;
480 	iwcm->accept = c4iw_accept_cr;
481 	iwcm->reject = c4iw_reject_cr;
482 	iwcm->create_listen_ep = c4iw_create_listen_ep;
483 	iwcm->destroy_listen_ep = c4iw_destroy_listen_ep;
484 	iwcm->newconn = process_newconn;
485 	iwcm->add_ref = c4iw_qp_add_ref;
486 	iwcm->rem_ref = c4iw_qp_rem_ref;
487 	iwcm->get_qp = c4iw_get_qp;
488 	ibdev->iwcm = iwcm;
489 
490 	ret = ib_register_device(&dev->ibdev, NULL);
491 	if (ret)
492 		kfree(iwcm);
493 
494 	return (ret);
495 }
496 
497 void
498 c4iw_unregister_device(struct c4iw_dev *dev)
499 {
500 
501 	CTR3(KTR_IW_CXGBE, "%s c4iw_dev %p, adapter %p", __func__, dev,
502 	    dev->rdev.adap);
503 	ib_unregister_device(&dev->ibdev);
504 	kfree(dev->ibdev.iwcm);
505 	return;
506 }
507 #endif
508