xref: /freebsd/sys/dev/irdma/fbsd_kcompat.c (revision af23369a6deaaeb612ab266eb88b8bb8d560c322)
1 /*-
2  * SPDX-License-Identifier: GPL-2.0 or Linux-OpenIB
3  *
4  * Copyright (c) 2021 - 2022 Intel Corporation
5  *
6  * This software is available to you under a choice of one of two
7  * licenses.  You may choose to be licensed under the terms of the GNU
8  * General Public License (GPL) Version 2, available from the file
9  * COPYING in the main directory of this source tree, or the
10  * OpenFabrics.org BSD license below:
11  *
12  *   Redistribution and use in source and binary forms, with or
13  *   without modification, are permitted provided that the following
14  *   conditions are met:
15  *
16  *    - Redistributions of source code must retain the above
17  *	copyright notice, this list of conditions and the following
18  *	disclaimer.
19  *
20  *    - Redistributions in binary form must reproduce the above
21  *	copyright notice, this list of conditions and the following
22  *	disclaimer in the documentation and/or other materials
23  *	provided with the distribution.
24  *
25  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32  * SOFTWARE.
33  */
34 /*$FreeBSD$*/
35 
36 #include "osdep.h"
37 #include "ice_rdma.h"
38 #include "irdma_di_if.h"
39 #include "irdma_main.h"
40 #include <sys/gsb_crc32.h>
41 #include <netinet/in_fib.h>
42 #include <netinet6/in6_fib.h>
43 #include <net/route/nhop.h>
44 #include <net/if_llatbl.h>
45 
46 /* additional QP debuging option. Keep false unless needed */
47 bool irdma_upload_context = false;
48 
49 inline u32
50 irdma_rd32(struct irdma_dev_ctx *dev_ctx, u32 reg){
51 
52 	KASSERT(reg < dev_ctx->mem_bus_space_size,
53 		("irdma: register offset %#jx too large (max is %#jx)",
54 		 (uintmax_t)reg, (uintmax_t)dev_ctx->mem_bus_space_size));
55 
56 	return (bus_space_read_4(dev_ctx->mem_bus_space_tag,
57 				 dev_ctx->mem_bus_space_handle, reg));
58 }
59 
60 inline void
61 irdma_wr32(struct irdma_dev_ctx *dev_ctx, u32 reg, u32 value)
62 {
63 
64 	KASSERT(reg < dev_ctx->mem_bus_space_size,
65 		("irdma: register offset %#jx too large (max is %#jx)",
66 		 (uintmax_t)reg, (uintmax_t)dev_ctx->mem_bus_space_size));
67 
68 	bus_space_write_4(dev_ctx->mem_bus_space_tag,
69 			  dev_ctx->mem_bus_space_handle, reg, value);
70 }
71 
72 inline u64
73 irdma_rd64(struct irdma_dev_ctx *dev_ctx, u32 reg){
74 
75 	KASSERT(reg < dev_ctx->mem_bus_space_size,
76 		("irdma: register offset %#jx too large (max is %#jx)",
77 		 (uintmax_t)reg, (uintmax_t)dev_ctx->mem_bus_space_size));
78 
79 	return (bus_space_read_8(dev_ctx->mem_bus_space_tag,
80 				 dev_ctx->mem_bus_space_handle, reg));
81 }
82 
83 inline void
84 irdma_wr64(struct irdma_dev_ctx *dev_ctx, u32 reg, u64 value)
85 {
86 
87 	KASSERT(reg < dev_ctx->mem_bus_space_size,
88 		("irdma: register offset %#jx too large (max is %#jx)",
89 		 (uintmax_t)reg, (uintmax_t)dev_ctx->mem_bus_space_size));
90 
91 	bus_space_write_8(dev_ctx->mem_bus_space_tag,
92 			  dev_ctx->mem_bus_space_handle, reg, value);
93 
94 }
95 
96 int
97 irdma_register_qset(struct irdma_sc_vsi *vsi, struct irdma_ws_node *tc_node)
98 {
99 	struct irdma_device *iwdev = vsi->back_vsi;
100 	struct ice_rdma_peer *peer = iwdev->rf->peer_info;
101 	struct ice_rdma_request req = {0};
102 	struct ice_rdma_qset_update *res = &req.res;
103 
104 	req.type = ICE_RDMA_EVENT_QSET_REGISTER;
105 	res->cnt_req = 1;
106 	res->res_type = ICE_RDMA_QSET_ALLOC;
107 	res->qsets.qs_handle = tc_node->qs_handle;
108 	res->qsets.tc = tc_node->traffic_class;
109 	res->qsets.vsi_id = vsi->vsi_idx;
110 
111 	IRDMA_DI_REQ_HANDLER(peer, &req);
112 
113 	tc_node->l2_sched_node_id = res->qsets.teid;
114 	vsi->qos[tc_node->user_pri].l2_sched_node_id =
115 	    res->qsets.teid;
116 
117 	return 0;
118 }
119 
120 void
121 irdma_unregister_qset(struct irdma_sc_vsi *vsi, struct irdma_ws_node *tc_node)
122 {
123 	struct irdma_device *iwdev = vsi->back_vsi;
124 	struct ice_rdma_peer *peer = iwdev->rf->peer_info;
125 	struct ice_rdma_request req = {0};
126 	struct ice_rdma_qset_update *res = &req.res;
127 
128 	req.type = ICE_RDMA_EVENT_QSET_REGISTER;
129 	res->res_allocated = 1;
130 	res->res_type = ICE_RDMA_QSET_FREE;
131 	res->qsets.vsi_id = vsi->vsi_idx;
132 	res->qsets.teid = tc_node->l2_sched_node_id;
133 	res->qsets.qs_handle = tc_node->qs_handle;
134 
135 	IRDMA_DI_REQ_HANDLER(peer, &req);
136 }
137 
138 void *
139 hw_to_dev(struct irdma_hw *hw)
140 {
141 	struct irdma_pci_f *rf;
142 
143 	rf = container_of(hw, struct irdma_pci_f, hw);
144 	return rf->pcidev;
145 }
146 
147 void
148 irdma_free_hash_desc(void *desc)
149 {
150 	return;
151 }
152 
153 int
154 irdma_init_hash_desc(void **desc)
155 {
156 	return 0;
157 }
158 
159 int
160 irdma_ieq_check_mpacrc(void *desc,
161 		       void *addr, u32 len, u32 val)
162 {
163 	u32 crc = calculate_crc32c(0xffffffff, addr, len) ^ 0xffffffff;
164 	int ret_code = 0;
165 
166 	if (crc != val) {
167 		irdma_pr_err("mpa crc check fail %x %x\n", crc, val);
168 		ret_code = -EINVAL;
169 	}
170 	printf("%s: result crc=%x value=%x\n", __func__, crc, val);
171 	return ret_code;
172 }
173 
174 /**
175  * irdma_add_ipv6_addr - add ipv6 address to the hw arp table
176  * @iwdev: irdma device
177  * @ifp: interface network device pointer
178  */
179 static void
180 irdma_add_ipv6_addr(struct irdma_device *iwdev, struct ifnet *ifp)
181 {
182 	struct ifaddr *ifa, *tmp;
183 	struct sockaddr_in6 *sin6;
184 	u32 local_ipaddr6[4];
185 	u8 *mac_addr;
186 	char ip6buf[INET6_ADDRSTRLEN];
187 
188 	if_addr_rlock(ifp);
189 	IRDMA_TAILQ_FOREACH_SAFE(ifa, &ifp->if_addrhead, ifa_link, tmp) {
190 		sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
191 		if (sin6->sin6_family != AF_INET6)
192 			continue;
193 
194 		irdma_copy_ip_ntohl(local_ipaddr6, (u32 *)&sin6->sin6_addr);
195 		mac_addr = IF_LLADDR(ifp);
196 
197 		printf("%s:%d IP=%s, MAC=%02x:%02x:%02x:%02x:%02x:%02x\n",
198 		       __func__, __LINE__,
199 		       ip6_sprintf(ip6buf, &sin6->sin6_addr),
200 		       mac_addr[0], mac_addr[1], mac_addr[2],
201 		       mac_addr[3], mac_addr[4], mac_addr[5]);
202 
203 		irdma_manage_arp_cache(iwdev->rf, mac_addr, local_ipaddr6,
204 				       IRDMA_ARP_ADD);
205 
206 	}
207 	if_addr_runlock(ifp);
208 }
209 
210 /**
211  * irdma_add_ipv4_addr - add ipv4 address to the hw arp table
212  * @iwdev: irdma device
213  * @ifp: interface network device pointer
214  */
215 static void
216 irdma_add_ipv4_addr(struct irdma_device *iwdev, struct ifnet *ifp)
217 {
218 	struct ifaddr *ifa;
219 	struct sockaddr_in *sin;
220 	u32 ip_addr[4] = {};
221 	u8 *mac_addr;
222 
223 	if_addr_rlock(ifp);
224 	IRDMA_TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
225 		sin = (struct sockaddr_in *)ifa->ifa_addr;
226 		if (sin->sin_family != AF_INET)
227 			continue;
228 
229 		ip_addr[0] = ntohl(sin->sin_addr.s_addr);
230 		mac_addr = IF_LLADDR(ifp);
231 
232 		printf("%s:%d IP=%d.%d.%d.%d, MAC=%02x:%02x:%02x:%02x:%02x:%02x\n",
233 		       __func__, __LINE__,
234 		       ip_addr[0] >> 24,
235 		       (ip_addr[0] >> 16) & 0xFF,
236 		       (ip_addr[0] >> 8) & 0xFF,
237 		       ip_addr[0] & 0xFF,
238 		       mac_addr[0], mac_addr[1], mac_addr[2],
239 		       mac_addr[3], mac_addr[4], mac_addr[5]);
240 
241 		irdma_manage_arp_cache(iwdev->rf, mac_addr, ip_addr,
242 				       IRDMA_ARP_ADD);
243 	}
244 	if_addr_runlock(ifp);
245 }
246 
247 /**
248  * irdma_add_ip - add ip addresses
249  * @iwdev: irdma device
250  *
251  * Add ipv4/ipv6 addresses to the arp cache
252  */
253 void
254 irdma_add_ip(struct irdma_device *iwdev)
255 {
256 	struct ifnet *ifp = iwdev->netdev;
257 	struct ifnet *ifv;
258 	int i;
259 
260 	irdma_add_ipv4_addr(iwdev, ifp);
261 	irdma_add_ipv6_addr(iwdev, ifp);
262 	for (i = 0; ifp->if_vlantrunk != NULL && i < VLAN_N_VID; ++i) {
263 		ifv = VLAN_DEVAT(ifp, i);
264 		if (!ifv)
265 			continue;
266 		irdma_add_ipv4_addr(iwdev, ifv);
267 		irdma_add_ipv6_addr(iwdev, ifv);
268 	}
269 }
270 
271 static void
272 irdma_ifaddrevent_handler(void *arg, struct ifnet *ifp, struct ifaddr *ifa, int event)
273 {
274 	struct irdma_pci_f *rf = arg;
275 	struct ifnet *ifv = NULL;
276 	struct sockaddr_in *sin;
277 	struct epoch_tracker et;
278 	int arp_index = 0, i = 0;
279 	u32 ip[4] = {};
280 
281 	if (!ifa || !ifa->ifa_addr || !ifp)
282 		return;
283 	if (rf->iwdev->netdev != ifp) {
284 		for (i = 0; rf->iwdev->netdev->if_vlantrunk != NULL && i < VLAN_N_VID; ++i) {
285 			NET_EPOCH_ENTER(et);
286 			ifv = VLAN_DEVAT(rf->iwdev->netdev, i);
287 			NET_EPOCH_EXIT(et);
288 			if (ifv == ifp)
289 				break;
290 		}
291 		if (ifv != ifp)
292 			return;
293 	}
294 	sin = (struct sockaddr_in *)ifa->ifa_addr;
295 
296 	switch (event) {
297 	case IFADDR_EVENT_ADD:
298 		if (sin->sin_family == AF_INET)
299 			irdma_add_ipv4_addr(rf->iwdev, ifp);
300 		else if (sin->sin_family == AF_INET6)
301 			irdma_add_ipv6_addr(rf->iwdev, ifp);
302 		break;
303 	case IFADDR_EVENT_DEL:
304 		if (sin->sin_family == AF_INET) {
305 			ip[0] = ntohl(sin->sin_addr.s_addr);
306 		} else if (sin->sin_family == AF_INET6) {
307 			irdma_copy_ip_ntohl(ip, (u32 *)&((struct sockaddr_in6 *)sin)->sin6_addr);
308 		} else {
309 			break;
310 		}
311 		for_each_set_bit(arp_index, rf->allocated_arps, rf->arp_table_size) {
312 			if (!memcmp(rf->arp_table[arp_index].ip_addr, ip, sizeof(ip))) {
313 				irdma_manage_arp_cache(rf, rf->arp_table[arp_index].mac_addr,
314 						       rf->arp_table[arp_index].ip_addr,
315 						       IRDMA_ARP_DELETE);
316 			}
317 		}
318 		break;
319 	default:
320 		break;
321 	}
322 }
323 
324 void
325 irdma_reg_ipaddr_event_cb(struct irdma_pci_f *rf)
326 {
327 	rf->irdma_ifaddr_event = EVENTHANDLER_REGISTER(ifaddr_event_ext,
328 						       irdma_ifaddrevent_handler,
329 						       rf,
330 						       EVENTHANDLER_PRI_ANY);
331 }
332 
333 void
334 irdma_dereg_ipaddr_event_cb(struct irdma_pci_f *rf)
335 {
336 	EVENTHANDLER_DEREGISTER(ifaddr_event_ext, rf->irdma_ifaddr_event);
337 }
338 
339 static int
340 irdma_get_route_ifp(struct sockaddr *dst_sin, struct ifnet *netdev,
341 		    struct ifnet **ifp, struct sockaddr **nexthop, bool *gateway)
342 {
343 	struct nhop_object *nh;
344 
345 	if (dst_sin->sa_family == AF_INET6)
346 		nh = fib6_lookup(RT_DEFAULT_FIB, &((struct sockaddr_in6 *)dst_sin)->sin6_addr, 0, NHR_NONE, 0);
347 	else
348 		nh = fib4_lookup(RT_DEFAULT_FIB, ((struct sockaddr_in *)dst_sin)->sin_addr, 0, NHR_NONE, 0);
349 	if (!nh || (nh->nh_ifp != netdev &&
350 		    rdma_vlan_dev_real_dev(nh->nh_ifp) != netdev))
351 		goto rt_not_found;
352 	*gateway = (nh->nh_flags & NHF_GATEWAY) ? true : false;
353 	*nexthop = (*gateway) ? &nh->gw_sa : dst_sin;
354 	*ifp = nh->nh_ifp;
355 
356 	return 0;
357 
358 rt_not_found:
359 	pr_err("irdma: route not found\n");
360 	return -ENETUNREACH;
361 }
362 
363 /**
364  * irdma_get_dst_mac - get destination mac address
365  * @cm_node: connection's node
366  * @dst_sin: destination address information
367  * @dst_mac: mac address array to return
368  */
369 int
370 irdma_get_dst_mac(struct irdma_cm_node *cm_node, struct sockaddr *dst_sin, u8 *dst_mac)
371 {
372 	struct ifnet *netdev = cm_node->iwdev->netdev;
373 #ifdef VIMAGE
374 	struct rdma_cm_id *rdma_id = (struct rdma_cm_id *)cm_node->cm_id->context;
375 	struct vnet *vnet = rdma_id->route.addr.dev_addr.net;
376 #endif
377 	struct ifnet *ifp;
378 	struct llentry *lle;
379 	struct sockaddr *nexthop;
380 	struct epoch_tracker et;
381 	int err;
382 	bool gateway;
383 
384 	NET_EPOCH_ENTER(et);
385 	CURVNET_SET_QUIET(vnet);
386 	err = irdma_get_route_ifp(dst_sin, netdev, &ifp, &nexthop, &gateway);
387 	if (err)
388 		goto get_route_fail;
389 
390 	if (dst_sin->sa_family == AF_INET) {
391 		err = arpresolve(ifp, gateway, NULL, nexthop, dst_mac, NULL, &lle);
392 	} else if (dst_sin->sa_family == AF_INET6) {
393 		err = nd6_resolve(ifp, LLE_SF(AF_INET6, gateway), NULL, nexthop,
394 				  dst_mac, NULL, &lle);
395 	} else {
396 		err = -EPROTONOSUPPORT;
397 	}
398 
399 get_route_fail:
400 	CURVNET_RESTORE();
401 	NET_EPOCH_EXIT(et);
402 	if (err) {
403 		pr_err("failed to resolve neighbor address (err=%d)\n",
404 		       err);
405 		return -ENETUNREACH;
406 	}
407 
408 	return 0;
409 }
410 
411 /**
412  * irdma_addr_resolve_neigh - resolve neighbor address
413  * @cm_node: connection's node
414  * @dst_ip: remote ip address
415  * @arpindex: if there is an arp entry
416  */
417 int
418 irdma_addr_resolve_neigh(struct irdma_cm_node *cm_node,
419 			 u32 dst_ip, int arpindex)
420 {
421 	struct irdma_device *iwdev = cm_node->iwdev;
422 	struct sockaddr_in dst_sin = {};
423 	int err;
424 	u32 ip[4] = {};
425 	u8 dst_mac[MAX_ADDR_LEN];
426 
427 	dst_sin.sin_len = sizeof(dst_sin);
428 	dst_sin.sin_family = AF_INET;
429 	dst_sin.sin_port = 0;
430 	dst_sin.sin_addr.s_addr = htonl(dst_ip);
431 
432 	err = irdma_get_dst_mac(cm_node, (struct sockaddr *)&dst_sin, dst_mac);
433 	if (err)
434 		return arpindex;
435 
436 	ip[0] = dst_ip;
437 
438 	return irdma_add_arp(iwdev->rf, ip, dst_mac);
439 }
440 
441 /**
442  * irdma_addr_resolve_neigh_ipv6 - resolve neighbor ipv6 address
443  * @cm_node: connection's node
444  * @dest: remote ip address
445  * @arpindex: if there is an arp entry
446  */
447 int
448 irdma_addr_resolve_neigh_ipv6(struct irdma_cm_node *cm_node,
449 			      u32 *dest, int arpindex)
450 {
451 	struct irdma_device *iwdev = cm_node->iwdev;
452 	struct sockaddr_in6 dst_addr = {};
453 	int err;
454 	u8 dst_mac[MAX_ADDR_LEN];
455 
456 	dst_addr.sin6_family = AF_INET6;
457 	dst_addr.sin6_len = sizeof(dst_addr);
458 	dst_addr.sin6_scope_id = iwdev->netdev->if_index;
459 
460 	irdma_copy_ip_htonl(dst_addr.sin6_addr.__u6_addr.__u6_addr32, dest);
461 	err = irdma_get_dst_mac(cm_node, (struct sockaddr *)&dst_addr, dst_mac);
462 	if (err)
463 		return arpindex;
464 
465 	return irdma_add_arp(iwdev->rf, dest, dst_mac);
466 }
467 
468 int
469 irdma_resolve_neigh_lpb_chk(struct irdma_device *iwdev, struct irdma_cm_node *cm_node,
470 			    struct irdma_cm_info *cm_info)
471 {
472 #ifdef VIMAGE
473 	struct rdma_cm_id *rdma_id = (struct rdma_cm_id *)cm_node->cm_id->context;
474 	struct vnet *vnet = rdma_id->route.addr.dev_addr.net;
475 #endif
476 	int arpindex;
477 	int oldarpindex;
478 	bool is_lpb = false;
479 
480 	CURVNET_SET_QUIET(vnet);
481 	is_lpb = cm_node->ipv4 ?
482 	    irdma_ipv4_is_lpb(cm_node->loc_addr[0], cm_node->rem_addr[0]) :
483 	    irdma_ipv6_is_lpb(cm_node->loc_addr, cm_node->rem_addr);
484 	CURVNET_RESTORE();
485 	if (is_lpb) {
486 		cm_node->do_lpb = true;
487 		arpindex = irdma_arp_table(iwdev->rf, cm_node->rem_addr,
488 					   NULL,
489 					   IRDMA_ARP_RESOLVE);
490 	} else {
491 		oldarpindex = irdma_arp_table(iwdev->rf, cm_node->rem_addr,
492 					      NULL,
493 					      IRDMA_ARP_RESOLVE);
494 		if (cm_node->ipv4)
495 			arpindex = irdma_addr_resolve_neigh(cm_node,
496 							    cm_info->rem_addr[0],
497 							    oldarpindex);
498 		else
499 			arpindex = irdma_addr_resolve_neigh_ipv6(cm_node,
500 								 cm_info->rem_addr,
501 								 oldarpindex);
502 	}
503 	return arpindex;
504 }
505 
506 /**
507  * irdma_add_handler - add a handler to the list
508  * @hdl: handler to be added to the handler list
509  */
510 void
511 irdma_add_handler(struct irdma_handler *hdl)
512 {
513 	unsigned long flags;
514 
515 	spin_lock_irqsave(&irdma_handler_lock, flags);
516 	list_add(&hdl->list, &irdma_handlers);
517 	spin_unlock_irqrestore(&irdma_handler_lock, flags);
518 }
519 
520 /**
521  * irdma_del_handler - delete a handler from the list
522  * @hdl: handler to be deleted from the handler list
523  */
524 void
525 irdma_del_handler(struct irdma_handler *hdl)
526 {
527 	unsigned long flags;
528 
529 	spin_lock_irqsave(&irdma_handler_lock, flags);
530 	list_del(&hdl->list);
531 	spin_unlock_irqrestore(&irdma_handler_lock, flags);
532 }
533 
534 /**
535  * irdma_set_rf_user_cfg_params - apply user configurable settings
536  * @rf: RDMA PCI function
537  */
538 void
539 irdma_set_rf_user_cfg_params(struct irdma_pci_f *rf)
540 {
541 	int en_rem_endpoint_trk = 0;
542 	int limits_sel = 4;
543 
544 	rf->en_rem_endpoint_trk = en_rem_endpoint_trk;
545 	rf->limits_sel = limits_sel;
546 	rf->rst_to = IRDMA_RST_TIMEOUT_HZ;
547 	/* Enable DCQCN algorithm by default */
548 	rf->dcqcn_ena = true;
549 }
550 
551 /**
552  * irdma_sysctl_dcqcn_update - handle dcqcn_ena sysctl update
553  * @arg1: pointer to rf
554  * @arg2: unused
555  * @oidp: sysctl oid structure
556  * @req: sysctl request pointer
557  */
558 static int
559 irdma_sysctl_dcqcn_update(SYSCTL_HANDLER_ARGS)
560 {
561 	struct irdma_pci_f *rf = (struct irdma_pci_f *)arg1;
562 	int ret;
563 	u8 dcqcn_ena = rf->dcqcn_ena;
564 
565 	ret = sysctl_handle_8(oidp, &dcqcn_ena, 0, req);
566 	if ((ret) || (req->newptr == NULL))
567 		return ret;
568 	if (dcqcn_ena == 0)
569 		rf->dcqcn_ena = false;
570 	else
571 		rf->dcqcn_ena = true;
572 
573 	return 0;
574 }
575 
576 /**
577  * irdma_dcqcn_tunables_init - create tunables for dcqcn settings
578  * @rf: RDMA PCI function
579  *
580  * Create DCQCN related sysctls for the driver.
581  * dcqcn_ena is writeable settings and applicable to next QP creation or
582  * context setting.
583  * all other settings are of RDTUN type (read on driver load) and are
584  * applicable only to CQP creation.
585  */
586 void
587 irdma_dcqcn_tunables_init(struct irdma_pci_f *rf)
588 {
589 	struct sysctl_oid_list *irdma_sysctl_oid_list;
590 
591 	irdma_sysctl_oid_list = SYSCTL_CHILDREN(rf->tun_info.irdma_sysctl_tree);
592 
593 	SYSCTL_ADD_PROC(&rf->tun_info.irdma_sysctl_ctx, irdma_sysctl_oid_list,
594 			OID_AUTO, "dcqcn_enable", CTLFLAG_RW | CTLTYPE_U8, rf, 0,
595 			irdma_sysctl_dcqcn_update, "A",
596 			"enables DCQCN algorithm for RoCEv2 on all ports, default=true");
597 
598 	SYSCTL_ADD_U8(&rf->tun_info.irdma_sysctl_ctx, irdma_sysctl_oid_list,
599 		      OID_AUTO, "dcqcn_cc_cfg_valid", CTLFLAG_RDTUN,
600 		      &rf->dcqcn_params.cc_cfg_valid, 0,
601 		      "set DCQCN parameters to be valid, default=false");
602 
603 	rf->dcqcn_params.min_dec_factor = 1;
604 	SYSCTL_ADD_U8(&rf->tun_info.irdma_sysctl_ctx, irdma_sysctl_oid_list,
605 		      OID_AUTO, "dcqcn_min_dec_factor", CTLFLAG_RDTUN,
606 		      &rf->dcqcn_params.min_dec_factor, 0,
607 		    "set minimum percentage factor by which tx rate can be changed for CNP, Range: 1-100, default=1");
608 
609 	SYSCTL_ADD_U8(&rf->tun_info.irdma_sysctl_ctx, irdma_sysctl_oid_list,
610 		      OID_AUTO, "dcqcn_min_rate_MBps", CTLFLAG_RDTUN,
611 		      &rf->dcqcn_params.min_rate, 0,
612 		      "set minimum rate limit value, in MBits per second, default=0");
613 
614 	SYSCTL_ADD_U8(&rf->tun_info.irdma_sysctl_ctx, irdma_sysctl_oid_list,
615 		      OID_AUTO, "dcqcn_F", CTLFLAG_RDTUN, &rf->dcqcn_params.dcqcn_f, 0,
616 		      "set number of times to stay in each stage of bandwidth recovery, default=0");
617 
618 	SYSCTL_ADD_U16(&rf->tun_info.irdma_sysctl_ctx, irdma_sysctl_oid_list,
619 		       OID_AUTO, "dcqcn_T", CTLFLAG_RDTUN, &rf->dcqcn_params.dcqcn_t, 0,
620 		       "set number of usecs that should elapse before increasing the CWND in DCQCN mode, default=0");
621 
622 	SYSCTL_ADD_U32(&rf->tun_info.irdma_sysctl_ctx, irdma_sysctl_oid_list,
623 		       OID_AUTO, "dcqcn_B", CTLFLAG_RDTUN, &rf->dcqcn_params.dcqcn_b, 0,
624 		       "set number of MSS to add to the congestion window in additive increase mode, default=0");
625 
626 	SYSCTL_ADD_U16(&rf->tun_info.irdma_sysctl_ctx, irdma_sysctl_oid_list,
627 		       OID_AUTO, "dcqcn_rai_factor", CTLFLAG_RDTUN,
628 		       &rf->dcqcn_params.rai_factor, 0,
629 		       "set number of MSS to add to the congestion window in additive increase mode, default=0");
630 
631 	SYSCTL_ADD_U16(&rf->tun_info.irdma_sysctl_ctx, irdma_sysctl_oid_list,
632 		       OID_AUTO, "dcqcn_hai_factor", CTLFLAG_RDTUN,
633 		       &rf->dcqcn_params.hai_factor, 0,
634 		       "set number of MSS to add to the congestion window in hyperactive increase mode, default=0");
635 
636 	SYSCTL_ADD_U32(&rf->tun_info.irdma_sysctl_ctx, irdma_sysctl_oid_list,
637 		       OID_AUTO, "dcqcn_rreduce_mperiod", CTLFLAG_RDTUN,
638 		       &rf->dcqcn_params.rreduce_mperiod, 0,
639 		       "set minimum time between 2 consecutive rate reductions for a single flow, default=0");
640 }
641 
642 /**
643  * irdma_dmamap_cb - callback for bus_dmamap_load
644  */
645 static void
646 irdma_dmamap_cb(void *arg, bus_dma_segment_t * segs, int nseg, int error)
647 {
648 	if (error)
649 		return;
650 	*(bus_addr_t *) arg = segs->ds_addr;
651 	return;
652 }
653 
654 /**
655  * irdma_allocate_dma_mem - allocate dma memory
656  * @hw: pointer to hw structure
657  * @mem: structure holding memory information
658  * @size: requested size
659  * @alignment: requested alignment
660  */
661 void *
662 irdma_allocate_dma_mem(struct irdma_hw *hw, struct irdma_dma_mem *mem,
663 		       u64 size, u32 alignment)
664 {
665 	struct irdma_dev_ctx *dev_ctx = (struct irdma_dev_ctx *)hw->dev_context;
666 	device_t dev = dev_ctx->dev;
667 	void *va;
668 	int ret;
669 
670 	ret = bus_dma_tag_create(bus_get_dma_tag(dev),	/* parent */
671 				 alignment, 0,	/* alignment, bounds */
672 				 BUS_SPACE_MAXADDR,	/* lowaddr */
673 				 BUS_SPACE_MAXADDR,	/* highaddr */
674 				 NULL, NULL,	/* filter, filterarg */
675 				 size,	/* maxsize */
676 				 1,	/* nsegments */
677 				 size,	/* maxsegsize */
678 				 BUS_DMA_ALLOCNOW,	/* flags */
679 				 NULL,	/* lockfunc */
680 				 NULL,	/* lockfuncarg */
681 				 &mem->tag);
682 	if (ret != 0) {
683 		device_printf(dev, "%s: bus_dma_tag_create failed, error %u\n",
684 			      __func__, ret);
685 		goto fail_0;
686 	}
687 	ret = bus_dmamem_alloc(mem->tag, (void **)&va,
688 			       BUS_DMA_NOWAIT | BUS_DMA_ZERO, &mem->map);
689 	if (ret != 0) {
690 		device_printf(dev, "%s: bus_dmamem_alloc failed, error %u\n",
691 			      __func__, ret);
692 		goto fail_1;
693 	}
694 	ret = bus_dmamap_load(mem->tag, mem->map, va, size,
695 			      irdma_dmamap_cb, &mem->pa, BUS_DMA_NOWAIT);
696 	if (ret != 0) {
697 		device_printf(dev, "%s: bus_dmamap_load failed, error %u\n",
698 			      __func__, ret);
699 		goto fail_2;
700 	}
701 	mem->nseg = 1;
702 	mem->size = size;
703 	bus_dmamap_sync(mem->tag, mem->map,
704 			BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
705 
706 	return va;
707 fail_2:
708 	bus_dmamem_free(mem->tag, va, mem->map);
709 fail_1:
710 	bus_dma_tag_destroy(mem->tag);
711 fail_0:
712 	mem->map = NULL;
713 	mem->tag = NULL;
714 
715 	return NULL;
716 }
717 
718 /**
719  * irdma_free_dma_mem - Memory free helper fn
720  * @hw: pointer to hw structure
721  * @mem: ptr to mem struct to free
722  */
723 int
724 irdma_free_dma_mem(struct irdma_hw *hw, struct irdma_dma_mem *mem)
725 {
726 	if (!mem)
727 		return -EINVAL;
728 	bus_dmamap_sync(mem->tag, mem->map,
729 			BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
730 	bus_dmamap_unload(mem->tag, mem->map);
731 	if (!mem->va)
732 		return -ENOMEM;
733 	bus_dmamem_free(mem->tag, mem->va, mem->map);
734 	bus_dma_tag_destroy(mem->tag);
735 
736 	mem->va = NULL;
737 
738 	return 0;
739 }
740 
741 inline void
742 irdma_prm_rem_bitmapmem(struct irdma_hw *hw, struct irdma_chunk *chunk)
743 {
744 	kfree(chunk->bitmapmem.va);
745 }
746