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