xref: /freebsd/sys/dev/irdma/fbsd_kcompat.c (revision 5b5f7d0e77a9eee73eb5d596f43aef4e1a3674d8)
1cdcd52d4SBartosz Sobczak /*-
2cdcd52d4SBartosz Sobczak  * SPDX-License-Identifier: GPL-2.0 or Linux-OpenIB
3cdcd52d4SBartosz Sobczak  *
401fbb869SBartosz Sobczak  * Copyright (c) 2021 - 2023 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 
35cdcd52d4SBartosz Sobczak #include "osdep.h"
36cdcd52d4SBartosz Sobczak #include "ice_rdma.h"
37cdcd52d4SBartosz Sobczak #include "irdma_di_if.h"
38cdcd52d4SBartosz Sobczak #include "irdma_main.h"
39cdcd52d4SBartosz Sobczak #include <sys/gsb_crc32.h>
40cdcd52d4SBartosz Sobczak #include <netinet/in_fib.h>
41cdcd52d4SBartosz Sobczak #include <netinet6/in6_fib.h>
42cdcd52d4SBartosz Sobczak #include <net/route/nhop.h>
43777e472cSBartosz Sobczak #include <net/if_llatbl.h>
44cdcd52d4SBartosz Sobczak 
45cdcd52d4SBartosz Sobczak /* additional QP debuging option. Keep false unless needed */
46cdcd52d4SBartosz Sobczak bool irdma_upload_context = false;
47cdcd52d4SBartosz Sobczak 
48cdcd52d4SBartosz Sobczak inline u32
irdma_rd32(struct irdma_dev_ctx * dev_ctx,u32 reg)49cdcd52d4SBartosz Sobczak irdma_rd32(struct irdma_dev_ctx *dev_ctx, u32 reg){
50cdcd52d4SBartosz Sobczak 
51cdcd52d4SBartosz Sobczak 	KASSERT(reg < dev_ctx->mem_bus_space_size,
52cdcd52d4SBartosz Sobczak 		("irdma: register offset %#jx too large (max is %#jx)",
53cdcd52d4SBartosz Sobczak 		 (uintmax_t)reg, (uintmax_t)dev_ctx->mem_bus_space_size));
54cdcd52d4SBartosz Sobczak 
55cdcd52d4SBartosz Sobczak 	return (bus_space_read_4(dev_ctx->mem_bus_space_tag,
56cdcd52d4SBartosz Sobczak 				 dev_ctx->mem_bus_space_handle, reg));
57cdcd52d4SBartosz Sobczak }
58cdcd52d4SBartosz Sobczak 
59cdcd52d4SBartosz Sobczak inline void
irdma_wr32(struct irdma_dev_ctx * dev_ctx,u32 reg,u32 value)60cdcd52d4SBartosz Sobczak irdma_wr32(struct irdma_dev_ctx *dev_ctx, u32 reg, u32 value)
61cdcd52d4SBartosz Sobczak {
62cdcd52d4SBartosz Sobczak 
63cdcd52d4SBartosz Sobczak 	KASSERT(reg < dev_ctx->mem_bus_space_size,
64cdcd52d4SBartosz Sobczak 		("irdma: register offset %#jx too large (max is %#jx)",
65cdcd52d4SBartosz Sobczak 		 (uintmax_t)reg, (uintmax_t)dev_ctx->mem_bus_space_size));
66cdcd52d4SBartosz Sobczak 
67cdcd52d4SBartosz Sobczak 	bus_space_write_4(dev_ctx->mem_bus_space_tag,
68cdcd52d4SBartosz Sobczak 			  dev_ctx->mem_bus_space_handle, reg, value);
69cdcd52d4SBartosz Sobczak }
70cdcd52d4SBartosz Sobczak 
71cdcd52d4SBartosz Sobczak inline u64
irdma_rd64(struct irdma_dev_ctx * dev_ctx,u32 reg)72cdcd52d4SBartosz Sobczak irdma_rd64(struct irdma_dev_ctx *dev_ctx, u32 reg){
73cdcd52d4SBartosz Sobczak 
74cdcd52d4SBartosz Sobczak 	KASSERT(reg < dev_ctx->mem_bus_space_size,
75cdcd52d4SBartosz Sobczak 		("irdma: register offset %#jx too large (max is %#jx)",
76cdcd52d4SBartosz Sobczak 		 (uintmax_t)reg, (uintmax_t)dev_ctx->mem_bus_space_size));
77cdcd52d4SBartosz Sobczak 
78cdcd52d4SBartosz Sobczak 	return (bus_space_read_8(dev_ctx->mem_bus_space_tag,
79cdcd52d4SBartosz Sobczak 				 dev_ctx->mem_bus_space_handle, reg));
80cdcd52d4SBartosz Sobczak }
81cdcd52d4SBartosz Sobczak 
82cdcd52d4SBartosz Sobczak inline void
irdma_wr64(struct irdma_dev_ctx * dev_ctx,u32 reg,u64 value)83cdcd52d4SBartosz Sobczak irdma_wr64(struct irdma_dev_ctx *dev_ctx, u32 reg, u64 value)
84cdcd52d4SBartosz Sobczak {
85cdcd52d4SBartosz Sobczak 
86cdcd52d4SBartosz Sobczak 	KASSERT(reg < dev_ctx->mem_bus_space_size,
87cdcd52d4SBartosz Sobczak 		("irdma: register offset %#jx too large (max is %#jx)",
88cdcd52d4SBartosz Sobczak 		 (uintmax_t)reg, (uintmax_t)dev_ctx->mem_bus_space_size));
89cdcd52d4SBartosz Sobczak 
90cdcd52d4SBartosz Sobczak 	bus_space_write_8(dev_ctx->mem_bus_space_tag,
91cdcd52d4SBartosz Sobczak 			  dev_ctx->mem_bus_space_handle, reg, value);
92cdcd52d4SBartosz Sobczak 
93cdcd52d4SBartosz Sobczak }
94cdcd52d4SBartosz Sobczak 
9535105900SBartosz Sobczak void
irdma_request_reset(struct irdma_pci_f * rf)9635105900SBartosz Sobczak irdma_request_reset(struct irdma_pci_f *rf)
9735105900SBartosz Sobczak {
9835105900SBartosz Sobczak 	struct ice_rdma_peer *peer = rf->peer_info;
9935105900SBartosz Sobczak 	struct ice_rdma_request req = {0};
10035105900SBartosz Sobczak 
10135105900SBartosz Sobczak 	req.type = ICE_RDMA_EVENT_RESET;
10235105900SBartosz Sobczak 
10335105900SBartosz Sobczak 	printf("%s:%d requesting pf-reset\n", __func__, __LINE__);
10435105900SBartosz Sobczak 	IRDMA_DI_REQ_HANDLER(peer, &req);
10535105900SBartosz Sobczak }
10635105900SBartosz Sobczak 
107cdcd52d4SBartosz Sobczak int
irdma_register_qset(struct irdma_sc_vsi * vsi,struct irdma_ws_node * tc_node)108cdcd52d4SBartosz Sobczak irdma_register_qset(struct irdma_sc_vsi *vsi, struct irdma_ws_node *tc_node)
109cdcd52d4SBartosz Sobczak {
110cdcd52d4SBartosz Sobczak 	struct irdma_device *iwdev = vsi->back_vsi;
111cdcd52d4SBartosz Sobczak 	struct ice_rdma_peer *peer = iwdev->rf->peer_info;
112cdcd52d4SBartosz Sobczak 	struct ice_rdma_request req = {0};
113cdcd52d4SBartosz Sobczak 	struct ice_rdma_qset_update *res = &req.res;
114cdcd52d4SBartosz Sobczak 
115cdcd52d4SBartosz Sobczak 	req.type = ICE_RDMA_EVENT_QSET_REGISTER;
116cdcd52d4SBartosz Sobczak 	res->cnt_req = 1;
117cdcd52d4SBartosz Sobczak 	res->res_type = ICE_RDMA_QSET_ALLOC;
118cdcd52d4SBartosz Sobczak 	res->qsets.qs_handle = tc_node->qs_handle;
119cdcd52d4SBartosz Sobczak 	res->qsets.tc = tc_node->traffic_class;
120cdcd52d4SBartosz Sobczak 	res->qsets.vsi_id = vsi->vsi_idx;
121cdcd52d4SBartosz Sobczak 
122cdcd52d4SBartosz Sobczak 	IRDMA_DI_REQ_HANDLER(peer, &req);
123cdcd52d4SBartosz Sobczak 
124cdcd52d4SBartosz Sobczak 	tc_node->l2_sched_node_id = res->qsets.teid;
125cdcd52d4SBartosz Sobczak 	vsi->qos[tc_node->user_pri].l2_sched_node_id =
126cdcd52d4SBartosz Sobczak 	    res->qsets.teid;
127cdcd52d4SBartosz Sobczak 
128cdcd52d4SBartosz Sobczak 	return 0;
129cdcd52d4SBartosz Sobczak }
130cdcd52d4SBartosz Sobczak 
131cdcd52d4SBartosz Sobczak void
irdma_unregister_qset(struct irdma_sc_vsi * vsi,struct irdma_ws_node * tc_node)132cdcd52d4SBartosz Sobczak irdma_unregister_qset(struct irdma_sc_vsi *vsi, struct irdma_ws_node *tc_node)
133cdcd52d4SBartosz Sobczak {
134cdcd52d4SBartosz Sobczak 	struct irdma_device *iwdev = vsi->back_vsi;
135cdcd52d4SBartosz Sobczak 	struct ice_rdma_peer *peer = iwdev->rf->peer_info;
136cdcd52d4SBartosz Sobczak 	struct ice_rdma_request req = {0};
137cdcd52d4SBartosz Sobczak 	struct ice_rdma_qset_update *res = &req.res;
138cdcd52d4SBartosz Sobczak 
139cdcd52d4SBartosz Sobczak 	req.type = ICE_RDMA_EVENT_QSET_REGISTER;
140cdcd52d4SBartosz Sobczak 	res->res_allocated = 1;
141cdcd52d4SBartosz Sobczak 	res->res_type = ICE_RDMA_QSET_FREE;
142cdcd52d4SBartosz Sobczak 	res->qsets.vsi_id = vsi->vsi_idx;
143cdcd52d4SBartosz Sobczak 	res->qsets.teid = tc_node->l2_sched_node_id;
144cdcd52d4SBartosz Sobczak 	res->qsets.qs_handle = tc_node->qs_handle;
145cdcd52d4SBartosz Sobczak 
146cdcd52d4SBartosz Sobczak 	IRDMA_DI_REQ_HANDLER(peer, &req);
147cdcd52d4SBartosz Sobczak }
148cdcd52d4SBartosz Sobczak 
149cdcd52d4SBartosz Sobczak void *
hw_to_dev(struct irdma_hw * hw)150cdcd52d4SBartosz Sobczak hw_to_dev(struct irdma_hw *hw)
151cdcd52d4SBartosz Sobczak {
152cdcd52d4SBartosz Sobczak 	struct irdma_pci_f *rf;
153cdcd52d4SBartosz Sobczak 
154cdcd52d4SBartosz Sobczak 	rf = container_of(hw, struct irdma_pci_f, hw);
155cdcd52d4SBartosz Sobczak 	return rf->pcidev;
156cdcd52d4SBartosz Sobczak }
157cdcd52d4SBartosz Sobczak 
158cdcd52d4SBartosz Sobczak void
irdma_free_hash_desc(void * desc)159cdcd52d4SBartosz Sobczak irdma_free_hash_desc(void *desc)
160cdcd52d4SBartosz Sobczak {
161cdcd52d4SBartosz Sobczak 	return;
162cdcd52d4SBartosz Sobczak }
163cdcd52d4SBartosz Sobczak 
164cdcd52d4SBartosz Sobczak int
irdma_init_hash_desc(void ** desc)165cdcd52d4SBartosz Sobczak irdma_init_hash_desc(void **desc)
166cdcd52d4SBartosz Sobczak {
167cdcd52d4SBartosz Sobczak 	return 0;
168cdcd52d4SBartosz Sobczak }
169cdcd52d4SBartosz Sobczak 
170cdcd52d4SBartosz Sobczak int
irdma_ieq_check_mpacrc(void * desc,void * addr,u32 len,u32 val)171cdcd52d4SBartosz Sobczak irdma_ieq_check_mpacrc(void *desc,
172cdcd52d4SBartosz Sobczak 		       void *addr, u32 len, u32 val)
173cdcd52d4SBartosz Sobczak {
174cdcd52d4SBartosz Sobczak 	u32 crc = calculate_crc32c(0xffffffff, addr, len) ^ 0xffffffff;
175cdcd52d4SBartosz Sobczak 	int ret_code = 0;
176cdcd52d4SBartosz Sobczak 
177cdcd52d4SBartosz Sobczak 	if (crc != val) {
178cdcd52d4SBartosz Sobczak 		irdma_pr_err("mpa crc check fail %x %x\n", crc, val);
179cdcd52d4SBartosz Sobczak 		ret_code = -EINVAL;
180cdcd52d4SBartosz Sobczak 	}
181cdcd52d4SBartosz Sobczak 	printf("%s: result crc=%x value=%x\n", __func__, crc, val);
182cdcd52d4SBartosz Sobczak 	return ret_code;
183cdcd52d4SBartosz Sobczak }
184cdcd52d4SBartosz Sobczak 
185cfaab41cSJustin Hibbits static u_int
irdma_add_ipv6_cb(void * arg,struct ifaddr * addr,u_int count __unused)186cfaab41cSJustin Hibbits irdma_add_ipv6_cb(void *arg, struct ifaddr *addr, u_int count __unused)
187cdcd52d4SBartosz Sobczak {
188cfaab41cSJustin Hibbits 	struct irdma_device *iwdev = arg;
189cdcd52d4SBartosz Sobczak 	struct sockaddr_in6 *sin6;
190cfaab41cSJustin Hibbits 	u32 local_ipaddr6[4] = {};
191cdcd52d4SBartosz Sobczak 	char ip6buf[INET6_ADDRSTRLEN];
192cfaab41cSJustin Hibbits 	u8 *mac_addr;
193cdcd52d4SBartosz Sobczak 
194cfaab41cSJustin Hibbits 	sin6 = (struct sockaddr_in6 *)addr->ifa_addr;
195cdcd52d4SBartosz Sobczak 
196cdcd52d4SBartosz Sobczak 	irdma_copy_ip_ntohl(local_ipaddr6, (u32 *)&sin6->sin6_addr);
197cfaab41cSJustin Hibbits 
198cfaab41cSJustin Hibbits 	mac_addr = if_getlladdr(addr->ifa_ifp);
199cdcd52d4SBartosz Sobczak 
200cdcd52d4SBartosz Sobczak 	printf("%s:%d IP=%s, MAC=%02x:%02x:%02x:%02x:%02x:%02x\n",
201cdcd52d4SBartosz Sobczak 	       __func__, __LINE__,
202cdcd52d4SBartosz Sobczak 	       ip6_sprintf(ip6buf, &sin6->sin6_addr),
203cdcd52d4SBartosz Sobczak 	       mac_addr[0], mac_addr[1], mac_addr[2],
204cdcd52d4SBartosz Sobczak 	       mac_addr[3], mac_addr[4], mac_addr[5]);
205cdcd52d4SBartosz Sobczak 
206cdcd52d4SBartosz Sobczak 	irdma_manage_arp_cache(iwdev->rf, mac_addr, local_ipaddr6,
207cdcd52d4SBartosz Sobczak 			       IRDMA_ARP_ADD);
208cfaab41cSJustin Hibbits 	return (0);
209cdcd52d4SBartosz Sobczak }
210cdcd52d4SBartosz Sobczak 
211cdcd52d4SBartosz Sobczak /**
212cfaab41cSJustin Hibbits  * irdma_add_ipv6_addr - add ipv6 address to the hw arp table
213cdcd52d4SBartosz Sobczak  * @iwdev: irdma device
214cdcd52d4SBartosz Sobczak  * @ifp: interface network device pointer
215cdcd52d4SBartosz Sobczak  */
216cdcd52d4SBartosz Sobczak static void
irdma_add_ipv6_addr(struct irdma_device * iwdev,struct ifnet * ifp)217cfaab41cSJustin Hibbits irdma_add_ipv6_addr(struct irdma_device *iwdev, struct ifnet *ifp)
218cdcd52d4SBartosz Sobczak {
219cfaab41cSJustin Hibbits 	if_addr_rlock(ifp);
220cfaab41cSJustin Hibbits 	if_foreach_addr_type(ifp, AF_INET6, irdma_add_ipv6_cb, iwdev);
221cfaab41cSJustin Hibbits 	if_addr_runlock(ifp);
222cfaab41cSJustin Hibbits }
223cfaab41cSJustin Hibbits 
224cfaab41cSJustin Hibbits static u_int
irdma_add_ipv4_cb(void * arg,struct ifaddr * addr,u_int count __unused)225cfaab41cSJustin Hibbits irdma_add_ipv4_cb(void *arg, struct ifaddr *addr, u_int count __unused)
226cfaab41cSJustin Hibbits {
227cfaab41cSJustin Hibbits 	struct irdma_device *iwdev = arg;
228cdcd52d4SBartosz Sobczak 	struct sockaddr_in *sin;
229cdcd52d4SBartosz Sobczak 	u32 ip_addr[4] = {};
230cfaab41cSJustin Hibbits 	uint8_t *mac_addr;
231cdcd52d4SBartosz Sobczak 
232cfaab41cSJustin Hibbits 	sin = (struct sockaddr_in *)addr->ifa_addr;
233cdcd52d4SBartosz Sobczak 
234cdcd52d4SBartosz Sobczak 	ip_addr[0] = ntohl(sin->sin_addr.s_addr);
235cfaab41cSJustin Hibbits 
236cfaab41cSJustin Hibbits 	mac_addr = if_getlladdr(addr->ifa_ifp);
237cdcd52d4SBartosz Sobczak 
238cdcd52d4SBartosz Sobczak 	printf("%s:%d IP=%d.%d.%d.%d, MAC=%02x:%02x:%02x:%02x:%02x:%02x\n",
239cdcd52d4SBartosz Sobczak 	       __func__, __LINE__,
240cdcd52d4SBartosz Sobczak 	       ip_addr[0] >> 24,
241cdcd52d4SBartosz Sobczak 	       (ip_addr[0] >> 16) & 0xFF,
242cdcd52d4SBartosz Sobczak 	       (ip_addr[0] >> 8) & 0xFF,
243cdcd52d4SBartosz Sobczak 	       ip_addr[0] & 0xFF,
244cdcd52d4SBartosz Sobczak 	       mac_addr[0], mac_addr[1], mac_addr[2],
245cdcd52d4SBartosz Sobczak 	       mac_addr[3], mac_addr[4], mac_addr[5]);
246cdcd52d4SBartosz Sobczak 
247cdcd52d4SBartosz Sobczak 	irdma_manage_arp_cache(iwdev->rf, mac_addr, ip_addr,
248cdcd52d4SBartosz Sobczak 			       IRDMA_ARP_ADD);
249cfaab41cSJustin Hibbits 	return (0);
250cdcd52d4SBartosz Sobczak }
251cfaab41cSJustin Hibbits 
252cfaab41cSJustin Hibbits /**
253cfaab41cSJustin Hibbits  * irdma_add_ipv4_addr - add ipv4 address to the hw arp table
254cfaab41cSJustin Hibbits  * @iwdev: irdma device
255cfaab41cSJustin Hibbits  * @ifp: interface network device pointer
256cfaab41cSJustin Hibbits  */
257cfaab41cSJustin Hibbits static void
irdma_add_ipv4_addr(struct irdma_device * iwdev,struct ifnet * ifp)258cfaab41cSJustin Hibbits irdma_add_ipv4_addr(struct irdma_device *iwdev, struct ifnet *ifp)
259cfaab41cSJustin Hibbits {
260cfaab41cSJustin Hibbits 	if_addr_rlock(ifp);
261cfaab41cSJustin Hibbits 	if_foreach_addr_type(ifp, AF_INET, irdma_add_ipv4_cb, iwdev);
262cdcd52d4SBartosz Sobczak 	if_addr_runlock(ifp);
263cdcd52d4SBartosz Sobczak }
264cdcd52d4SBartosz Sobczak 
265cdcd52d4SBartosz Sobczak /**
266cdcd52d4SBartosz Sobczak  * irdma_add_ip - add ip addresses
267cdcd52d4SBartosz Sobczak  * @iwdev: irdma device
268cdcd52d4SBartosz Sobczak  *
269cdcd52d4SBartosz Sobczak  * Add ipv4/ipv6 addresses to the arp cache
270cdcd52d4SBartosz Sobczak  */
271cdcd52d4SBartosz Sobczak void
irdma_add_ip(struct irdma_device * iwdev)272cdcd52d4SBartosz Sobczak irdma_add_ip(struct irdma_device *iwdev)
273cdcd52d4SBartosz Sobczak {
274cdcd52d4SBartosz Sobczak 	struct ifnet *ifp = iwdev->netdev;
275cdcd52d4SBartosz Sobczak 	struct ifnet *ifv;
27601fbb869SBartosz Sobczak 	struct epoch_tracker et;
277cdcd52d4SBartosz Sobczak 	int i;
278cdcd52d4SBartosz Sobczak 
279cdcd52d4SBartosz Sobczak 	irdma_add_ipv4_addr(iwdev, ifp);
280cdcd52d4SBartosz Sobczak 	irdma_add_ipv6_addr(iwdev, ifp);
281cfaab41cSJustin Hibbits 	for (i = 0; if_getvlantrunk(ifp) != NULL && i < VLAN_N_VID; ++i) {
28201fbb869SBartosz Sobczak 		NET_EPOCH_ENTER(et);
283cdcd52d4SBartosz Sobczak 		ifv = VLAN_DEVAT(ifp, i);
28401fbb869SBartosz Sobczak 		NET_EPOCH_EXIT(et);
285cdcd52d4SBartosz Sobczak 		if (!ifv)
286cdcd52d4SBartosz Sobczak 			continue;
287cdcd52d4SBartosz Sobczak 		irdma_add_ipv4_addr(iwdev, ifv);
288cdcd52d4SBartosz Sobczak 		irdma_add_ipv6_addr(iwdev, ifv);
289cdcd52d4SBartosz Sobczak 	}
290cdcd52d4SBartosz Sobczak }
291cdcd52d4SBartosz Sobczak 
292cdcd52d4SBartosz Sobczak static void
irdma_ifaddrevent_handler(void * arg,struct ifnet * ifp,struct ifaddr * ifa,int event)293cdcd52d4SBartosz Sobczak irdma_ifaddrevent_handler(void *arg, struct ifnet *ifp, struct ifaddr *ifa, int event)
294cdcd52d4SBartosz Sobczak {
295cdcd52d4SBartosz Sobczak 	struct irdma_pci_f *rf = arg;
296cdcd52d4SBartosz Sobczak 	struct ifnet *ifv = NULL;
297cdcd52d4SBartosz Sobczak 	struct sockaddr_in *sin;
298cdcd52d4SBartosz Sobczak 	struct epoch_tracker et;
299cdcd52d4SBartosz Sobczak 	int arp_index = 0, i = 0;
300cdcd52d4SBartosz Sobczak 	u32 ip[4] = {};
301cdcd52d4SBartosz Sobczak 
302cdcd52d4SBartosz Sobczak 	if (!ifa || !ifa->ifa_addr || !ifp)
303cdcd52d4SBartosz Sobczak 		return;
304cdcd52d4SBartosz Sobczak 	if (rf->iwdev->netdev != ifp) {
305cfaab41cSJustin Hibbits 		for (i = 0; if_getvlantrunk(rf->iwdev->netdev) != NULL && i < VLAN_N_VID; ++i) {
306cdcd52d4SBartosz Sobczak 			NET_EPOCH_ENTER(et);
307cdcd52d4SBartosz Sobczak 			ifv = VLAN_DEVAT(rf->iwdev->netdev, i);
308cdcd52d4SBartosz Sobczak 			NET_EPOCH_EXIT(et);
309cdcd52d4SBartosz Sobczak 			if (ifv == ifp)
310cdcd52d4SBartosz Sobczak 				break;
311cdcd52d4SBartosz Sobczak 		}
312cdcd52d4SBartosz Sobczak 		if (ifv != ifp)
313cdcd52d4SBartosz Sobczak 			return;
314cdcd52d4SBartosz Sobczak 	}
315cdcd52d4SBartosz Sobczak 	sin = (struct sockaddr_in *)ifa->ifa_addr;
316cdcd52d4SBartosz Sobczak 
317cdcd52d4SBartosz Sobczak 	switch (event) {
318cdcd52d4SBartosz Sobczak 	case IFADDR_EVENT_ADD:
319cdcd52d4SBartosz Sobczak 		if (sin->sin_family == AF_INET)
320cdcd52d4SBartosz Sobczak 			irdma_add_ipv4_addr(rf->iwdev, ifp);
321cdcd52d4SBartosz Sobczak 		else if (sin->sin_family == AF_INET6)
322cdcd52d4SBartosz Sobczak 			irdma_add_ipv6_addr(rf->iwdev, ifp);
323cdcd52d4SBartosz Sobczak 		break;
324cdcd52d4SBartosz Sobczak 	case IFADDR_EVENT_DEL:
325cdcd52d4SBartosz Sobczak 		if (sin->sin_family == AF_INET) {
326cdcd52d4SBartosz Sobczak 			ip[0] = ntohl(sin->sin_addr.s_addr);
327cdcd52d4SBartosz Sobczak 		} else if (sin->sin_family == AF_INET6) {
328cdcd52d4SBartosz Sobczak 			irdma_copy_ip_ntohl(ip, (u32 *)&((struct sockaddr_in6 *)sin)->sin6_addr);
329cdcd52d4SBartosz Sobczak 		} else {
330cdcd52d4SBartosz Sobczak 			break;
331cdcd52d4SBartosz Sobczak 		}
332cdcd52d4SBartosz Sobczak 		for_each_set_bit(arp_index, rf->allocated_arps, rf->arp_table_size) {
333cdcd52d4SBartosz Sobczak 			if (!memcmp(rf->arp_table[arp_index].ip_addr, ip, sizeof(ip))) {
334cdcd52d4SBartosz Sobczak 				irdma_manage_arp_cache(rf, rf->arp_table[arp_index].mac_addr,
335cdcd52d4SBartosz Sobczak 						       rf->arp_table[arp_index].ip_addr,
336cdcd52d4SBartosz Sobczak 						       IRDMA_ARP_DELETE);
337cdcd52d4SBartosz Sobczak 			}
338cdcd52d4SBartosz Sobczak 		}
339cdcd52d4SBartosz Sobczak 		break;
340cdcd52d4SBartosz Sobczak 	default:
341cdcd52d4SBartosz Sobczak 		break;
342cdcd52d4SBartosz Sobczak 	}
343cdcd52d4SBartosz Sobczak }
344cdcd52d4SBartosz Sobczak 
345cdcd52d4SBartosz Sobczak void
irdma_reg_ipaddr_event_cb(struct irdma_pci_f * rf)346cdcd52d4SBartosz Sobczak irdma_reg_ipaddr_event_cb(struct irdma_pci_f *rf)
347cdcd52d4SBartosz Sobczak {
348cdcd52d4SBartosz Sobczak 	rf->irdma_ifaddr_event = EVENTHANDLER_REGISTER(ifaddr_event_ext,
349cdcd52d4SBartosz Sobczak 						       irdma_ifaddrevent_handler,
350cdcd52d4SBartosz Sobczak 						       rf,
351cdcd52d4SBartosz Sobczak 						       EVENTHANDLER_PRI_ANY);
352cdcd52d4SBartosz Sobczak }
353cdcd52d4SBartosz Sobczak 
354cdcd52d4SBartosz Sobczak void
irdma_dereg_ipaddr_event_cb(struct irdma_pci_f * rf)355cdcd52d4SBartosz Sobczak irdma_dereg_ipaddr_event_cb(struct irdma_pci_f *rf)
356cdcd52d4SBartosz Sobczak {
357cdcd52d4SBartosz Sobczak 	EVENTHANDLER_DEREGISTER(ifaddr_event_ext, rf->irdma_ifaddr_event);
358cdcd52d4SBartosz Sobczak }
359cdcd52d4SBartosz Sobczak 
360cdcd52d4SBartosz Sobczak static int
irdma_get_route_ifp(struct sockaddr * dst_sin,struct ifnet * netdev,struct ifnet ** ifp,struct sockaddr ** nexthop,bool * gateway)361cdcd52d4SBartosz Sobczak irdma_get_route_ifp(struct sockaddr *dst_sin, struct ifnet *netdev,
362cdcd52d4SBartosz Sobczak 		    struct ifnet **ifp, struct sockaddr **nexthop, bool *gateway)
363cdcd52d4SBartosz Sobczak {
364cdcd52d4SBartosz Sobczak 	struct nhop_object *nh;
365cdcd52d4SBartosz Sobczak 
366cdcd52d4SBartosz Sobczak 	if (dst_sin->sa_family == AF_INET6)
36701fbb869SBartosz Sobczak 		nh = fib6_lookup(RT_DEFAULT_FIB, &((struct sockaddr_in6 *)dst_sin)->sin6_addr,
36801fbb869SBartosz Sobczak 				 ((struct sockaddr_in6 *)dst_sin)->sin6_scope_id, NHR_NONE, 0);
369cdcd52d4SBartosz Sobczak 	else
370cdcd52d4SBartosz Sobczak 		nh = fib4_lookup(RT_DEFAULT_FIB, ((struct sockaddr_in *)dst_sin)->sin_addr, 0, NHR_NONE, 0);
371cdcd52d4SBartosz Sobczak 	if (!nh || (nh->nh_ifp != netdev &&
372cdcd52d4SBartosz Sobczak 		    rdma_vlan_dev_real_dev(nh->nh_ifp) != netdev))
373cdcd52d4SBartosz Sobczak 		goto rt_not_found;
374cdcd52d4SBartosz Sobczak 	*gateway = (nh->nh_flags & NHF_GATEWAY) ? true : false;
375cdcd52d4SBartosz Sobczak 	*nexthop = (*gateway) ? &nh->gw_sa : dst_sin;
376cdcd52d4SBartosz Sobczak 	*ifp = nh->nh_ifp;
377cdcd52d4SBartosz Sobczak 
378cdcd52d4SBartosz Sobczak 	return 0;
379cdcd52d4SBartosz Sobczak 
380cdcd52d4SBartosz Sobczak rt_not_found:
381cdcd52d4SBartosz Sobczak 	pr_err("irdma: route not found\n");
382cdcd52d4SBartosz Sobczak 	return -ENETUNREACH;
383cdcd52d4SBartosz Sobczak }
384cdcd52d4SBartosz Sobczak 
385cdcd52d4SBartosz Sobczak /**
386cdcd52d4SBartosz Sobczak  * irdma_get_dst_mac - get destination mac address
387cdcd52d4SBartosz Sobczak  * @cm_node: connection's node
388cdcd52d4SBartosz Sobczak  * @dst_sin: destination address information
389cdcd52d4SBartosz Sobczak  * @dst_mac: mac address array to return
390cdcd52d4SBartosz Sobczak  */
391cdcd52d4SBartosz Sobczak int
irdma_get_dst_mac(struct irdma_cm_node * cm_node,struct sockaddr * dst_sin,u8 * dst_mac)392cdcd52d4SBartosz Sobczak irdma_get_dst_mac(struct irdma_cm_node *cm_node, struct sockaddr *dst_sin, u8 *dst_mac)
393cdcd52d4SBartosz Sobczak {
394cdcd52d4SBartosz Sobczak 	struct ifnet *netdev = cm_node->iwdev->netdev;
395cdcd52d4SBartosz Sobczak #ifdef VIMAGE
396bc3a013cSBartosz Sobczak 	struct vnet *vnet = irdma_cmid_to_vnet(cm_node->cm_id);
397cdcd52d4SBartosz Sobczak #endif
398cdcd52d4SBartosz Sobczak 	struct ifnet *ifp;
399cdcd52d4SBartosz Sobczak 	struct llentry *lle;
400cdcd52d4SBartosz Sobczak 	struct sockaddr *nexthop;
401cdcd52d4SBartosz Sobczak 	struct epoch_tracker et;
402cdcd52d4SBartosz Sobczak 	int err;
403cdcd52d4SBartosz Sobczak 	bool gateway;
404cdcd52d4SBartosz Sobczak 
405cdcd52d4SBartosz Sobczak 	NET_EPOCH_ENTER(et);
406cdcd52d4SBartosz Sobczak 	CURVNET_SET_QUIET(vnet);
407cdcd52d4SBartosz Sobczak 	err = irdma_get_route_ifp(dst_sin, netdev, &ifp, &nexthop, &gateway);
408cdcd52d4SBartosz Sobczak 	if (err)
409cdcd52d4SBartosz Sobczak 		goto get_route_fail;
410cdcd52d4SBartosz Sobczak 
411cdcd52d4SBartosz Sobczak 	if (dst_sin->sa_family == AF_INET) {
412cdcd52d4SBartosz Sobczak 		err = arpresolve(ifp, gateway, NULL, nexthop, dst_mac, NULL, &lle);
413cdcd52d4SBartosz Sobczak 	} else if (dst_sin->sa_family == AF_INET6) {
414777e472cSBartosz Sobczak 		err = nd6_resolve(ifp, LLE_SF(AF_INET6, gateway), NULL, nexthop,
415777e472cSBartosz Sobczak 				  dst_mac, NULL, &lle);
416cdcd52d4SBartosz Sobczak 	} else {
417cdcd52d4SBartosz Sobczak 		err = -EPROTONOSUPPORT;
418cdcd52d4SBartosz Sobczak 	}
419cdcd52d4SBartosz Sobczak 
420cdcd52d4SBartosz Sobczak get_route_fail:
421cdcd52d4SBartosz Sobczak 	CURVNET_RESTORE();
422cdcd52d4SBartosz Sobczak 	NET_EPOCH_EXIT(et);
423cdcd52d4SBartosz Sobczak 	if (err) {
424cdcd52d4SBartosz Sobczak 		pr_err("failed to resolve neighbor address (err=%d)\n",
425cdcd52d4SBartosz Sobczak 		       err);
426cdcd52d4SBartosz Sobczak 		return -ENETUNREACH;
427cdcd52d4SBartosz Sobczak 	}
428cdcd52d4SBartosz Sobczak 
429cdcd52d4SBartosz Sobczak 	return 0;
430cdcd52d4SBartosz Sobczak }
431cdcd52d4SBartosz Sobczak 
432cdcd52d4SBartosz Sobczak /**
433cdcd52d4SBartosz Sobczak  * irdma_addr_resolve_neigh - resolve neighbor address
434cdcd52d4SBartosz Sobczak  * @cm_node: connection's node
435cdcd52d4SBartosz Sobczak  * @dst_ip: remote ip address
436cdcd52d4SBartosz Sobczak  * @arpindex: if there is an arp entry
437cdcd52d4SBartosz Sobczak  */
438cdcd52d4SBartosz Sobczak int
irdma_addr_resolve_neigh(struct irdma_cm_node * cm_node,u32 dst_ip,int arpindex)439cdcd52d4SBartosz Sobczak irdma_addr_resolve_neigh(struct irdma_cm_node *cm_node,
440cdcd52d4SBartosz Sobczak 			 u32 dst_ip, int arpindex)
441cdcd52d4SBartosz Sobczak {
442cdcd52d4SBartosz Sobczak 	struct irdma_device *iwdev = cm_node->iwdev;
443cdcd52d4SBartosz Sobczak 	struct sockaddr_in dst_sin = {};
444cdcd52d4SBartosz Sobczak 	int err;
445cdcd52d4SBartosz Sobczak 	u32 ip[4] = {};
446cdcd52d4SBartosz Sobczak 	u8 dst_mac[MAX_ADDR_LEN];
447cdcd52d4SBartosz Sobczak 
448cdcd52d4SBartosz Sobczak 	dst_sin.sin_len = sizeof(dst_sin);
449cdcd52d4SBartosz Sobczak 	dst_sin.sin_family = AF_INET;
450cdcd52d4SBartosz Sobczak 	dst_sin.sin_port = 0;
451cdcd52d4SBartosz Sobczak 	dst_sin.sin_addr.s_addr = htonl(dst_ip);
452cdcd52d4SBartosz Sobczak 
453cdcd52d4SBartosz Sobczak 	err = irdma_get_dst_mac(cm_node, (struct sockaddr *)&dst_sin, dst_mac);
454cdcd52d4SBartosz Sobczak 	if (err)
455cdcd52d4SBartosz Sobczak 		return arpindex;
456cdcd52d4SBartosz Sobczak 
457cdcd52d4SBartosz Sobczak 	ip[0] = dst_ip;
458cdcd52d4SBartosz Sobczak 
459cdcd52d4SBartosz Sobczak 	return irdma_add_arp(iwdev->rf, ip, dst_mac);
460cdcd52d4SBartosz Sobczak }
461cdcd52d4SBartosz Sobczak 
462cdcd52d4SBartosz Sobczak /**
463cdcd52d4SBartosz Sobczak  * irdma_addr_resolve_neigh_ipv6 - resolve neighbor ipv6 address
464cdcd52d4SBartosz Sobczak  * @cm_node: connection's node
465cdcd52d4SBartosz Sobczak  * @dest: remote ip address
466cdcd52d4SBartosz Sobczak  * @arpindex: if there is an arp entry
467cdcd52d4SBartosz Sobczak  */
468cdcd52d4SBartosz Sobczak int
irdma_addr_resolve_neigh_ipv6(struct irdma_cm_node * cm_node,u32 * dest,int arpindex)469cdcd52d4SBartosz Sobczak irdma_addr_resolve_neigh_ipv6(struct irdma_cm_node *cm_node,
470cdcd52d4SBartosz Sobczak 			      u32 *dest, int arpindex)
471cdcd52d4SBartosz Sobczak {
472cdcd52d4SBartosz Sobczak 	struct irdma_device *iwdev = cm_node->iwdev;
473cdcd52d4SBartosz Sobczak 	struct sockaddr_in6 dst_addr = {};
474cdcd52d4SBartosz Sobczak 	int err;
475cdcd52d4SBartosz Sobczak 	u8 dst_mac[MAX_ADDR_LEN];
476cdcd52d4SBartosz Sobczak 
477cdcd52d4SBartosz Sobczak 	dst_addr.sin6_family = AF_INET6;
478cdcd52d4SBartosz Sobczak 	dst_addr.sin6_len = sizeof(dst_addr);
479cfaab41cSJustin Hibbits 	dst_addr.sin6_scope_id = if_getindex(iwdev->netdev);
480cdcd52d4SBartosz Sobczak 
481cdcd52d4SBartosz Sobczak 	irdma_copy_ip_htonl(dst_addr.sin6_addr.__u6_addr.__u6_addr32, dest);
482cdcd52d4SBartosz Sobczak 	err = irdma_get_dst_mac(cm_node, (struct sockaddr *)&dst_addr, dst_mac);
483cdcd52d4SBartosz Sobczak 	if (err)
484cdcd52d4SBartosz Sobczak 		return arpindex;
485cdcd52d4SBartosz Sobczak 
486cdcd52d4SBartosz Sobczak 	return irdma_add_arp(iwdev->rf, dest, dst_mac);
487cdcd52d4SBartosz Sobczak }
488cdcd52d4SBartosz Sobczak 
489cdcd52d4SBartosz Sobczak int
irdma_resolve_neigh_lpb_chk(struct irdma_device * iwdev,struct irdma_cm_node * cm_node,struct irdma_cm_info * cm_info)490cdcd52d4SBartosz Sobczak irdma_resolve_neigh_lpb_chk(struct irdma_device *iwdev, struct irdma_cm_node *cm_node,
491cdcd52d4SBartosz Sobczak 			    struct irdma_cm_info *cm_info)
492cdcd52d4SBartosz Sobczak {
493777e472cSBartosz Sobczak #ifdef VIMAGE
494bc3a013cSBartosz Sobczak 	struct vnet *vnet = irdma_cmid_to_vnet(cm_node->cm_id);
495777e472cSBartosz Sobczak #endif
496cdcd52d4SBartosz Sobczak 	int arpindex;
497cdcd52d4SBartosz Sobczak 	int oldarpindex;
498777e472cSBartosz Sobczak 	bool is_lpb = false;
499cdcd52d4SBartosz Sobczak 
500777e472cSBartosz Sobczak 	CURVNET_SET_QUIET(vnet);
501777e472cSBartosz Sobczak 	is_lpb = cm_node->ipv4 ?
502777e472cSBartosz Sobczak 	    irdma_ipv4_is_lpb(cm_node->loc_addr[0], cm_node->rem_addr[0]) :
503777e472cSBartosz Sobczak 	    irdma_ipv6_is_lpb(cm_node->loc_addr, cm_node->rem_addr);
504777e472cSBartosz Sobczak 	CURVNET_RESTORE();
505777e472cSBartosz Sobczak 	if (is_lpb) {
506cdcd52d4SBartosz Sobczak 		cm_node->do_lpb = true;
507cdcd52d4SBartosz Sobczak 		arpindex = irdma_arp_table(iwdev->rf, cm_node->rem_addr,
508cdcd52d4SBartosz Sobczak 					   NULL,
509cdcd52d4SBartosz Sobczak 					   IRDMA_ARP_RESOLVE);
510cdcd52d4SBartosz Sobczak 	} else {
511cdcd52d4SBartosz Sobczak 		oldarpindex = irdma_arp_table(iwdev->rf, cm_node->rem_addr,
512cdcd52d4SBartosz Sobczak 					      NULL,
513cdcd52d4SBartosz Sobczak 					      IRDMA_ARP_RESOLVE);
514cdcd52d4SBartosz Sobczak 		if (cm_node->ipv4)
515cdcd52d4SBartosz Sobczak 			arpindex = irdma_addr_resolve_neigh(cm_node,
516cdcd52d4SBartosz Sobczak 							    cm_info->rem_addr[0],
517cdcd52d4SBartosz Sobczak 							    oldarpindex);
518cdcd52d4SBartosz Sobczak 		else
519cdcd52d4SBartosz Sobczak 			arpindex = irdma_addr_resolve_neigh_ipv6(cm_node,
520cdcd52d4SBartosz Sobczak 								 cm_info->rem_addr,
521cdcd52d4SBartosz Sobczak 								 oldarpindex);
522cdcd52d4SBartosz Sobczak 	}
523cdcd52d4SBartosz Sobczak 	return arpindex;
524cdcd52d4SBartosz Sobczak }
525cdcd52d4SBartosz Sobczak 
526cdcd52d4SBartosz Sobczak /**
527cdcd52d4SBartosz Sobczak  * irdma_add_handler - add a handler to the list
528cdcd52d4SBartosz Sobczak  * @hdl: handler to be added to the handler list
529cdcd52d4SBartosz Sobczak  */
530cdcd52d4SBartosz Sobczak void
irdma_add_handler(struct irdma_handler * hdl)531cdcd52d4SBartosz Sobczak irdma_add_handler(struct irdma_handler *hdl)
532cdcd52d4SBartosz Sobczak {
533cdcd52d4SBartosz Sobczak 	unsigned long flags;
534cdcd52d4SBartosz Sobczak 
535cdcd52d4SBartosz Sobczak 	spin_lock_irqsave(&irdma_handler_lock, flags);
536cdcd52d4SBartosz Sobczak 	list_add(&hdl->list, &irdma_handlers);
537cdcd52d4SBartosz Sobczak 	spin_unlock_irqrestore(&irdma_handler_lock, flags);
538cdcd52d4SBartosz Sobczak }
539cdcd52d4SBartosz Sobczak 
540cdcd52d4SBartosz Sobczak /**
541cdcd52d4SBartosz Sobczak  * irdma_del_handler - delete a handler from the list
542cdcd52d4SBartosz Sobczak  * @hdl: handler to be deleted from the handler list
543cdcd52d4SBartosz Sobczak  */
544cdcd52d4SBartosz Sobczak void
irdma_del_handler(struct irdma_handler * hdl)545cdcd52d4SBartosz Sobczak irdma_del_handler(struct irdma_handler *hdl)
546cdcd52d4SBartosz Sobczak {
547cdcd52d4SBartosz Sobczak 	unsigned long flags;
548cdcd52d4SBartosz Sobczak 
549cdcd52d4SBartosz Sobczak 	spin_lock_irqsave(&irdma_handler_lock, flags);
550cdcd52d4SBartosz Sobczak 	list_del(&hdl->list);
551cdcd52d4SBartosz Sobczak 	spin_unlock_irqrestore(&irdma_handler_lock, flags);
552cdcd52d4SBartosz Sobczak }
553cdcd52d4SBartosz Sobczak 
554cdcd52d4SBartosz Sobczak /**
555cdcd52d4SBartosz Sobczak  * irdma_set_rf_user_cfg_params - apply user configurable settings
556cdcd52d4SBartosz Sobczak  * @rf: RDMA PCI function
557cdcd52d4SBartosz Sobczak  */
558cdcd52d4SBartosz Sobczak void
irdma_set_rf_user_cfg_params(struct irdma_pci_f * rf)559cdcd52d4SBartosz Sobczak irdma_set_rf_user_cfg_params(struct irdma_pci_f *rf)
560cdcd52d4SBartosz Sobczak {
561cdcd52d4SBartosz Sobczak 	int en_rem_endpoint_trk = 0;
562cdcd52d4SBartosz Sobczak 	int limits_sel = 4;
563cdcd52d4SBartosz Sobczak 
564cdcd52d4SBartosz Sobczak 	rf->en_rem_endpoint_trk = en_rem_endpoint_trk;
565cdcd52d4SBartosz Sobczak 	rf->limits_sel = limits_sel;
566cdcd52d4SBartosz Sobczak 	rf->rst_to = IRDMA_RST_TIMEOUT_HZ;
567cdcd52d4SBartosz Sobczak 	/* Enable DCQCN algorithm by default */
568cdcd52d4SBartosz Sobczak 	rf->dcqcn_ena = true;
569cdcd52d4SBartosz Sobczak }
570cdcd52d4SBartosz Sobczak 
571cdcd52d4SBartosz Sobczak /**
572cdcd52d4SBartosz Sobczak  * irdma_sysctl_dcqcn_update - handle dcqcn_ena sysctl update
573cdcd52d4SBartosz Sobczak  * @arg1: pointer to rf
574cdcd52d4SBartosz Sobczak  * @arg2: unused
575cdcd52d4SBartosz Sobczak  * @oidp: sysctl oid structure
576cdcd52d4SBartosz Sobczak  * @req: sysctl request pointer
577cdcd52d4SBartosz Sobczak  */
578cdcd52d4SBartosz Sobczak static int
irdma_sysctl_dcqcn_update(SYSCTL_HANDLER_ARGS)579cdcd52d4SBartosz Sobczak irdma_sysctl_dcqcn_update(SYSCTL_HANDLER_ARGS)
580cdcd52d4SBartosz Sobczak {
581cdcd52d4SBartosz Sobczak 	struct irdma_pci_f *rf = (struct irdma_pci_f *)arg1;
582cdcd52d4SBartosz Sobczak 	int ret;
583cdcd52d4SBartosz Sobczak 	u8 dcqcn_ena = rf->dcqcn_ena;
584cdcd52d4SBartosz Sobczak 
585cdcd52d4SBartosz Sobczak 	ret = sysctl_handle_8(oidp, &dcqcn_ena, 0, req);
586cdcd52d4SBartosz Sobczak 	if ((ret) || (req->newptr == NULL))
587cdcd52d4SBartosz Sobczak 		return ret;
588cdcd52d4SBartosz Sobczak 	if (dcqcn_ena == 0)
589cdcd52d4SBartosz Sobczak 		rf->dcqcn_ena = false;
590cdcd52d4SBartosz Sobczak 	else
591cdcd52d4SBartosz Sobczak 		rf->dcqcn_ena = true;
592cdcd52d4SBartosz Sobczak 
593cdcd52d4SBartosz Sobczak 	return 0;
594cdcd52d4SBartosz Sobczak }
595cdcd52d4SBartosz Sobczak 
59601fbb869SBartosz Sobczak enum irdma_cqp_stats_info {
59701fbb869SBartosz Sobczak 	IRDMA_CQP_REQ_CMDS = 28,
59801fbb869SBartosz Sobczak 	IRDMA_CQP_CMPL_CMDS = 29
59901fbb869SBartosz Sobczak };
60001fbb869SBartosz Sobczak 
60101fbb869SBartosz Sobczak static int
irdma_sysctl_cqp_stats(SYSCTL_HANDLER_ARGS)60201fbb869SBartosz Sobczak irdma_sysctl_cqp_stats(SYSCTL_HANDLER_ARGS)
60301fbb869SBartosz Sobczak {
60401fbb869SBartosz Sobczak 	struct irdma_sc_cqp *cqp = (struct irdma_sc_cqp *)arg1;
60501fbb869SBartosz Sobczak 	char rslt[192] = "no cqp available yet";
60601fbb869SBartosz Sobczak 	int rslt_size = sizeof(rslt) - 1;
60701fbb869SBartosz Sobczak 	int option = (int)arg2;
60801fbb869SBartosz Sobczak 
60901fbb869SBartosz Sobczak 	if (!cqp) {
61001fbb869SBartosz Sobczak 		return sysctl_handle_string(oidp, rslt, sizeof(rslt), req);
61101fbb869SBartosz Sobczak 	}
61201fbb869SBartosz Sobczak 
61301fbb869SBartosz Sobczak 	snprintf(rslt, sizeof(rslt), "");
61401fbb869SBartosz Sobczak 	switch (option) {
61501fbb869SBartosz Sobczak 	case IRDMA_CQP_REQ_CMDS:
61601fbb869SBartosz Sobczak 		snprintf(rslt, rslt_size, "%lu", cqp->requested_ops);
61701fbb869SBartosz Sobczak 		break;
61801fbb869SBartosz Sobczak 	case IRDMA_CQP_CMPL_CMDS:
61901fbb869SBartosz Sobczak 		snprintf(rslt, rslt_size, "%lu", atomic64_read(&cqp->completed_ops));
62001fbb869SBartosz Sobczak 		break;
62101fbb869SBartosz Sobczak 	}
62201fbb869SBartosz Sobczak 
62301fbb869SBartosz Sobczak 	return sysctl_handle_string(oidp, rslt, sizeof(rslt), req);
62401fbb869SBartosz Sobczak }
62501fbb869SBartosz Sobczak 
62601fbb869SBartosz Sobczak struct irdma_sw_stats_tunable_info {
62701fbb869SBartosz Sobczak 	u8 op_type;
62801fbb869SBartosz Sobczak 	const char name[32];
62901fbb869SBartosz Sobczak 	const char desc[32];
63001fbb869SBartosz Sobczak 	uintptr_t value;
63101fbb869SBartosz Sobczak };
63201fbb869SBartosz Sobczak 
63301fbb869SBartosz Sobczak static const struct irdma_sw_stats_tunable_info irdma_sws_list[] = {
63401fbb869SBartosz Sobczak 	{IRDMA_OP_CEQ_DESTROY, "ceq_destroy", "ceq_destroy", 0},
63501fbb869SBartosz Sobczak 	{IRDMA_OP_AEQ_DESTROY, "aeq_destroy", "aeq_destroy", 0},
63601fbb869SBartosz Sobczak 	{IRDMA_OP_DELETE_ARP_CACHE_ENTRY, "delete_arp_cache_entry",
63701fbb869SBartosz Sobczak 	"delete_arp_cache_entry", 0},
63801fbb869SBartosz Sobczak 	{IRDMA_OP_MANAGE_APBVT_ENTRY, "manage_apbvt_entry",
63901fbb869SBartosz Sobczak 	"manage_apbvt_entry", 0},
64001fbb869SBartosz Sobczak 	{IRDMA_OP_CEQ_CREATE, "ceq_create", "ceq_create", 0},
64101fbb869SBartosz Sobczak 	{IRDMA_OP_AEQ_CREATE, "aeq_create", "aeq_create", 0},
64201fbb869SBartosz Sobczak 	{IRDMA_OP_MANAGE_QHASH_TABLE_ENTRY, "manage_qhash_table_entry",
64301fbb869SBartosz Sobczak 	"manage_qhash_table_entry", 0},
64401fbb869SBartosz Sobczak 	{IRDMA_OP_QP_MODIFY, "qp_modify", "qp_modify", 0},
64501fbb869SBartosz Sobczak 	{IRDMA_OP_QP_UPLOAD_CONTEXT, "qp_upload_context", "qp_upload_context",
64601fbb869SBartosz Sobczak 	0},
64701fbb869SBartosz Sobczak 	{IRDMA_OP_CQ_CREATE, "cq_create", "cq_create", 0},
64801fbb869SBartosz Sobczak 	{IRDMA_OP_CQ_DESTROY, "cq_destroy", "cq_destroy", 0},
64901fbb869SBartosz Sobczak 	{IRDMA_OP_QP_CREATE, "qp_create", "qp_create", 0},
65001fbb869SBartosz Sobczak 	{IRDMA_OP_QP_DESTROY, "qp_destroy", "qp_destroy", 0},
65101fbb869SBartosz Sobczak 	{IRDMA_OP_ALLOC_STAG, "alloc_stag", "alloc_stag", 0},
65201fbb869SBartosz Sobczak 	{IRDMA_OP_MR_REG_NON_SHARED, "mr_reg_non_shared", "mr_reg_non_shared",
65301fbb869SBartosz Sobczak 	0},
65401fbb869SBartosz Sobczak 	{IRDMA_OP_DEALLOC_STAG, "dealloc_stag", "dealloc_stag", 0},
65501fbb869SBartosz Sobczak 	{IRDMA_OP_MW_ALLOC, "mw_alloc", "mw_alloc", 0},
65601fbb869SBartosz Sobczak 	{IRDMA_OP_QP_FLUSH_WQES, "qp_flush_wqes", "qp_flush_wqes", 0},
65701fbb869SBartosz Sobczak 	{IRDMA_OP_ADD_ARP_CACHE_ENTRY, "add_arp_cache_entry",
65801fbb869SBartosz Sobczak 	"add_arp_cache_entry", 0},
65901fbb869SBartosz Sobczak 	{IRDMA_OP_MANAGE_PUSH_PAGE, "manage_push_page", "manage_push_page", 0},
66001fbb869SBartosz Sobczak 	{IRDMA_OP_UPDATE_PE_SDS, "update_pe_sds", "update_pe_sds", 0},
66101fbb869SBartosz Sobczak 	{IRDMA_OP_MANAGE_HMC_PM_FUNC_TABLE, "manage_hmc_pm_func_table",
66201fbb869SBartosz Sobczak 	"manage_hmc_pm_func_table", 0},
66301fbb869SBartosz Sobczak 	{IRDMA_OP_SUSPEND, "suspend", "suspend", 0},
66401fbb869SBartosz Sobczak 	{IRDMA_OP_RESUME, "resume", "resume", 0},
665*5b5f7d0eSBartosz Sobczak 	{25, "manage_vchnl_req_pble_bp", "manage_vchnl_req_pble_bp", 0},
66601fbb869SBartosz Sobczak 	{IRDMA_OP_QUERY_FPM_VAL, "query_fpm_val", "query_fpm_val", 0},
66701fbb869SBartosz Sobczak 	{IRDMA_OP_COMMIT_FPM_VAL, "commit_fpm_val", "commit_fpm_val", 0},
66801fbb869SBartosz Sobczak 	{IRDMA_OP_AH_CREATE, "ah_create", "ah_create", 0},
66901fbb869SBartosz Sobczak 	{IRDMA_OP_AH_MODIFY, "ah_modify", "ah_modify", 0},
67001fbb869SBartosz Sobczak 	{IRDMA_OP_AH_DESTROY, "ah_destroy", "ah_destroy", 0},
67101fbb869SBartosz Sobczak 	{IRDMA_OP_MC_CREATE, "mc_create", "mc_create", 0},
67201fbb869SBartosz Sobczak 	{IRDMA_OP_MC_DESTROY, "mc_destroy", "mc_destroy", 0},
67301fbb869SBartosz Sobczak 	{IRDMA_OP_MC_MODIFY, "mc_modify", "mc_modify", 0},
67401fbb869SBartosz Sobczak 	{IRDMA_OP_STATS_ALLOCATE, "stats_allocate", "stats_allocate", 0},
67501fbb869SBartosz Sobczak 	{IRDMA_OP_STATS_FREE, "stats_free", "stats_free", 0},
67601fbb869SBartosz Sobczak 	{IRDMA_OP_STATS_GATHER, "stats_gather", "stats_gather", 0},
67701fbb869SBartosz Sobczak 	{IRDMA_OP_WS_ADD_NODE, "ws_add_node", "ws_add_node", 0},
67801fbb869SBartosz Sobczak 	{IRDMA_OP_WS_MODIFY_NODE, "ws_modify_node", "ws_modify_node", 0},
67901fbb869SBartosz Sobczak 	{IRDMA_OP_WS_DELETE_NODE, "ws_delete_node", "ws_delete_node", 0},
68001fbb869SBartosz Sobczak 	{IRDMA_OP_WS_FAILOVER_START, "ws_failover_start", "ws_failover_start",
68101fbb869SBartosz Sobczak 	0},
68201fbb869SBartosz Sobczak 	{IRDMA_OP_WS_FAILOVER_COMPLETE, "ws_failover_complete",
68301fbb869SBartosz Sobczak 	"ws_failover_complete", 0},
68401fbb869SBartosz Sobczak 	{IRDMA_OP_SET_UP_MAP, "set_up_map", "set_up_map", 0},
68501fbb869SBartosz Sobczak 	{IRDMA_OP_GEN_AE, "gen_ae", "gen_ae", 0},
68601fbb869SBartosz Sobczak 	{IRDMA_OP_QUERY_RDMA_FEATURES, "query_rdma_features",
68701fbb869SBartosz Sobczak 	"query_rdma_features", 0},
68801fbb869SBartosz Sobczak 	{IRDMA_OP_ALLOC_LOCAL_MAC_ENTRY, "alloc_local_mac_entry",
68901fbb869SBartosz Sobczak 	"alloc_local_mac_entry", 0},
69001fbb869SBartosz Sobczak 	{IRDMA_OP_ADD_LOCAL_MAC_ENTRY, "add_local_mac_entry",
69101fbb869SBartosz Sobczak 	"add_local_mac_entry", 0},
69201fbb869SBartosz Sobczak 	{IRDMA_OP_DELETE_LOCAL_MAC_ENTRY, "delete_local_mac_entry",
69301fbb869SBartosz Sobczak 	"delete_local_mac_entry", 0},
69401fbb869SBartosz Sobczak 	{IRDMA_OP_CQ_MODIFY, "cq_modify", "cq_modify", 0}
69501fbb869SBartosz Sobczak };
69601fbb869SBartosz Sobczak 
69701fbb869SBartosz Sobczak static const struct irdma_sw_stats_tunable_info irdma_cmcs_list[] = {
69801fbb869SBartosz Sobczak 	{0, "cm_nodes_created", "cm_nodes_created",
69901fbb869SBartosz Sobczak 	offsetof(struct irdma_cm_core, stats_nodes_created)},
70001fbb869SBartosz Sobczak 	{0, "cm_nodes_destroyed", "cm_nodes_destroyed",
70101fbb869SBartosz Sobczak 	offsetof(struct irdma_cm_core, stats_nodes_destroyed)},
70201fbb869SBartosz Sobczak 	{0, "cm_listen_created", "cm_listen_created",
70301fbb869SBartosz Sobczak 	offsetof(struct irdma_cm_core, stats_listen_created)},
70401fbb869SBartosz Sobczak 	{0, "cm_listen_destroyed", "cm_listen_destroyed",
70501fbb869SBartosz Sobczak 	offsetof(struct irdma_cm_core, stats_listen_destroyed)},
70601fbb869SBartosz Sobczak 	{0, "cm_listen_nodes_created", "cm_listen_nodes_created",
70701fbb869SBartosz Sobczak 	offsetof(struct irdma_cm_core, stats_listen_nodes_created)},
70801fbb869SBartosz Sobczak 	{0, "cm_listen_nodes_destroyed", "cm_listen_nodes_destroyed",
70901fbb869SBartosz Sobczak 	offsetof(struct irdma_cm_core, stats_listen_nodes_destroyed)},
71001fbb869SBartosz Sobczak 	{0, "cm_lpbs", "cm_lpbs", offsetof(struct irdma_cm_core, stats_lpbs)},
71101fbb869SBartosz Sobczak 	{0, "cm_accepts", "cm_accepts", offsetof(struct irdma_cm_core,
71201fbb869SBartosz Sobczak 						 stats_accepts)},
71301fbb869SBartosz Sobczak 	{0, "cm_rejects", "cm_rejects", offsetof(struct irdma_cm_core,
71401fbb869SBartosz Sobczak 						 stats_rejects)},
71501fbb869SBartosz Sobczak 	{0, "cm_connect_errs", "cm_connect_errs",
71601fbb869SBartosz Sobczak 	offsetof(struct irdma_cm_core, stats_connect_errs)},
71701fbb869SBartosz Sobczak 	{0, "cm_passive_errs", "cm_passive_errs",
71801fbb869SBartosz Sobczak 	offsetof(struct irdma_cm_core, stats_passive_errs)},
71901fbb869SBartosz Sobczak 	{0, "cm_pkt_retrans", "cm_pkt_retrans", offsetof(struct irdma_cm_core,
72001fbb869SBartosz Sobczak 							 stats_pkt_retrans)},
72101fbb869SBartosz Sobczak 	{0, "cm_backlog_drops", "cm_backlog_drops",
72201fbb869SBartosz Sobczak 	offsetof(struct irdma_cm_core, stats_backlog_drops)},
72301fbb869SBartosz Sobczak };
72401fbb869SBartosz Sobczak 
72501fbb869SBartosz Sobczak static const struct irdma_sw_stats_tunable_info irdma_ilqs32_list[] = {
72601fbb869SBartosz Sobczak 	{0, "ilq_avail_buf_count", "ilq_avail_buf_count",
72701fbb869SBartosz Sobczak 	offsetof(struct irdma_puda_rsrc, avail_buf_count)},
72801fbb869SBartosz Sobczak 	{0, "ilq_alloc_buf_count", "ilq_alloc_buf_count",
72901fbb869SBartosz Sobczak 	offsetof(struct irdma_puda_rsrc, alloc_buf_count)}
73001fbb869SBartosz Sobczak };
73101fbb869SBartosz Sobczak 
73201fbb869SBartosz Sobczak static const struct irdma_sw_stats_tunable_info irdma_ilqs_list[] = {
73301fbb869SBartosz Sobczak 	{0, "ilq_stats_buf_alloc_fail", "ilq_stats_buf_alloc_fail",
73401fbb869SBartosz Sobczak 	offsetof(struct irdma_puda_rsrc, stats_buf_alloc_fail)},
73501fbb869SBartosz Sobczak 	{0, "ilq_stats_pkt_rcvd", "ilq_stats_pkt_rcvd",
73601fbb869SBartosz Sobczak 	offsetof(struct irdma_puda_rsrc, stats_pkt_rcvd)},
73701fbb869SBartosz Sobczak 	{0, "ilq_stats_pkt_sent", "ilq_stats_pkt_sent",
73801fbb869SBartosz Sobczak 	offsetof(struct irdma_puda_rsrc, stats_pkt_sent)},
73901fbb869SBartosz Sobczak 	{0, "ilq_stats_rcvd_pkt_err", "ilq_stats_rcvd_pkt_err",
74001fbb869SBartosz Sobczak 	offsetof(struct irdma_puda_rsrc, stats_rcvd_pkt_err)},
74101fbb869SBartosz Sobczak 	{0, "ilq_stats_sent_pkt_q", "ilq_stats_sent_pkt_q",
74201fbb869SBartosz Sobczak 	offsetof(struct irdma_puda_rsrc, stats_sent_pkt_q)}
74301fbb869SBartosz Sobczak };
74401fbb869SBartosz Sobczak 
74501fbb869SBartosz Sobczak static const struct irdma_sw_stats_tunable_info irdma_ieqs32_list[] = {
74601fbb869SBartosz Sobczak 	{0, "ieq_avail_buf_count", "ieq_avail_buf_count",
74701fbb869SBartosz Sobczak 	offsetof(struct irdma_puda_rsrc, avail_buf_count)},
74801fbb869SBartosz Sobczak 	{0, "ieq_alloc_buf_count", "ieq_alloc_buf_count",
74901fbb869SBartosz Sobczak 	offsetof(struct irdma_puda_rsrc, alloc_buf_count)}
75001fbb869SBartosz Sobczak };
75101fbb869SBartosz Sobczak 
75201fbb869SBartosz Sobczak static const struct irdma_sw_stats_tunable_info irdma_ieqs_list[] = {
75301fbb869SBartosz Sobczak 	{0, "ieq_stats_buf_alloc_fail", "ieq_stats_buf_alloc_fail",
75401fbb869SBartosz Sobczak 	offsetof(struct irdma_puda_rsrc, stats_buf_alloc_fail)},
75501fbb869SBartosz Sobczak 	{0, "ieq_stats_pkt_rcvd", "ieq_stats_pkt_rcvd",
75601fbb869SBartosz Sobczak 	offsetof(struct irdma_puda_rsrc, stats_pkt_rcvd)},
75701fbb869SBartosz Sobczak 	{0, "ieq_stats_pkt_sent", "ieq_stats_pkt_sent",
75801fbb869SBartosz Sobczak 	offsetof(struct irdma_puda_rsrc, stats_pkt_sent)},
75901fbb869SBartosz Sobczak 	{0, "ieq_stats_rcvd_pkt_err", "ieq_stats_rcvd_pkt_err",
76001fbb869SBartosz Sobczak 	offsetof(struct irdma_puda_rsrc, stats_rcvd_pkt_err)},
76101fbb869SBartosz Sobczak 	{0, "ieq_stats_sent_pkt_q", "ieq_stats_sent_pkt_q",
76201fbb869SBartosz Sobczak 	offsetof(struct irdma_puda_rsrc, stats_sent_pkt_q)},
76301fbb869SBartosz Sobczak 	{0, "ieq_stats_bad_qp_id", "ieq_stats_bad_qp_id",
76401fbb869SBartosz Sobczak 	offsetof(struct irdma_puda_rsrc, stats_bad_qp_id)},
76501fbb869SBartosz Sobczak 	{0, "ieq_fpdu_processed", "ieq_fpdu_processed",
76601fbb869SBartosz Sobczak 	offsetof(struct irdma_puda_rsrc, fpdu_processed)},
76701fbb869SBartosz Sobczak 	{0, "ieq_bad_seq_num", "ieq_bad_seq_num",
76801fbb869SBartosz Sobczak 	offsetof(struct irdma_puda_rsrc, bad_seq_num)},
76901fbb869SBartosz Sobczak 	{0, "ieq_crc_err", "ieq_crc_err", offsetof(struct irdma_puda_rsrc,
77001fbb869SBartosz Sobczak 						   crc_err)},
77101fbb869SBartosz Sobczak 	{0, "ieq_pmode_count", "ieq_pmode_count",
77201fbb869SBartosz Sobczak 	offsetof(struct irdma_puda_rsrc, pmode_count)},
77301fbb869SBartosz Sobczak 	{0, "ieq_partials_handled", "ieq_partials_handled",
77401fbb869SBartosz Sobczak 	offsetof(struct irdma_puda_rsrc, partials_handled)},
77501fbb869SBartosz Sobczak };
77601fbb869SBartosz Sobczak 
777cdcd52d4SBartosz Sobczak /**
778cdcd52d4SBartosz Sobczak  * irdma_dcqcn_tunables_init - create tunables for dcqcn settings
779cdcd52d4SBartosz Sobczak  * @rf: RDMA PCI function
780cdcd52d4SBartosz Sobczak  *
781cdcd52d4SBartosz Sobczak  * Create DCQCN related sysctls for the driver.
782cdcd52d4SBartosz Sobczak  * dcqcn_ena is writeable settings and applicable to next QP creation or
783cdcd52d4SBartosz Sobczak  * context setting.
784cdcd52d4SBartosz Sobczak  * all other settings are of RDTUN type (read on driver load) and are
785cdcd52d4SBartosz Sobczak  * applicable only to CQP creation.
786cdcd52d4SBartosz Sobczak  */
787cdcd52d4SBartosz Sobczak void
irdma_dcqcn_tunables_init(struct irdma_pci_f * rf)788cdcd52d4SBartosz Sobczak irdma_dcqcn_tunables_init(struct irdma_pci_f *rf)
789cdcd52d4SBartosz Sobczak {
790cdcd52d4SBartosz Sobczak 	struct sysctl_oid_list *irdma_sysctl_oid_list;
791cdcd52d4SBartosz Sobczak 
792cdcd52d4SBartosz Sobczak 	irdma_sysctl_oid_list = SYSCTL_CHILDREN(rf->tun_info.irdma_sysctl_tree);
793cdcd52d4SBartosz Sobczak 
794cdcd52d4SBartosz Sobczak 	SYSCTL_ADD_PROC(&rf->tun_info.irdma_sysctl_ctx, irdma_sysctl_oid_list,
795cdcd52d4SBartosz Sobczak 			OID_AUTO, "dcqcn_enable", CTLFLAG_RW | CTLTYPE_U8, rf, 0,
796cdcd52d4SBartosz Sobczak 			irdma_sysctl_dcqcn_update, "A",
797cdcd52d4SBartosz Sobczak 			"enables DCQCN algorithm for RoCEv2 on all ports, default=true");
798cdcd52d4SBartosz Sobczak 
799cdcd52d4SBartosz Sobczak 	SYSCTL_ADD_U8(&rf->tun_info.irdma_sysctl_ctx, irdma_sysctl_oid_list,
800cdcd52d4SBartosz Sobczak 		      OID_AUTO, "dcqcn_cc_cfg_valid", CTLFLAG_RDTUN,
801cdcd52d4SBartosz Sobczak 		      &rf->dcqcn_params.cc_cfg_valid, 0,
802cdcd52d4SBartosz Sobczak 		      "set DCQCN parameters to be valid, default=false");
803cdcd52d4SBartosz Sobczak 
804cdcd52d4SBartosz Sobczak 	rf->dcqcn_params.min_dec_factor = 1;
805cdcd52d4SBartosz Sobczak 	SYSCTL_ADD_U8(&rf->tun_info.irdma_sysctl_ctx, irdma_sysctl_oid_list,
806cdcd52d4SBartosz Sobczak 		      OID_AUTO, "dcqcn_min_dec_factor", CTLFLAG_RDTUN,
807cdcd52d4SBartosz Sobczak 		      &rf->dcqcn_params.min_dec_factor, 0,
808cdcd52d4SBartosz Sobczak 		    "set minimum percentage factor by which tx rate can be changed for CNP, Range: 1-100, default=1");
809cdcd52d4SBartosz Sobczak 
810cdcd52d4SBartosz Sobczak 	SYSCTL_ADD_U8(&rf->tun_info.irdma_sysctl_ctx, irdma_sysctl_oid_list,
811cdcd52d4SBartosz Sobczak 		      OID_AUTO, "dcqcn_min_rate_MBps", CTLFLAG_RDTUN,
812cdcd52d4SBartosz Sobczak 		      &rf->dcqcn_params.min_rate, 0,
813cdcd52d4SBartosz Sobczak 		      "set minimum rate limit value, in MBits per second, default=0");
814cdcd52d4SBartosz Sobczak 
81535105900SBartosz Sobczak 	rf->dcqcn_params.dcqcn_f = 5;
816cdcd52d4SBartosz Sobczak 	SYSCTL_ADD_U8(&rf->tun_info.irdma_sysctl_ctx, irdma_sysctl_oid_list,
817cdcd52d4SBartosz Sobczak 		      OID_AUTO, "dcqcn_F", CTLFLAG_RDTUN, &rf->dcqcn_params.dcqcn_f, 0,
81835105900SBartosz Sobczak 		      "set number of times to stay in each stage of bandwidth recovery, default=5");
819cdcd52d4SBartosz Sobczak 
82035105900SBartosz Sobczak 	rf->dcqcn_params.dcqcn_t = 0x37;
821cdcd52d4SBartosz Sobczak 	SYSCTL_ADD_U16(&rf->tun_info.irdma_sysctl_ctx, irdma_sysctl_oid_list,
822cdcd52d4SBartosz Sobczak 		       OID_AUTO, "dcqcn_T", CTLFLAG_RDTUN, &rf->dcqcn_params.dcqcn_t, 0,
82301fbb869SBartosz Sobczak 		       "number of us to elapse before increasing the CWND in DCQCN mode, default=0x37");
824cdcd52d4SBartosz Sobczak 
82535105900SBartosz Sobczak 	rf->dcqcn_params.dcqcn_b = 0x249f0;
826cdcd52d4SBartosz Sobczak 	SYSCTL_ADD_U32(&rf->tun_info.irdma_sysctl_ctx, irdma_sysctl_oid_list,
827cdcd52d4SBartosz Sobczak 		       OID_AUTO, "dcqcn_B", CTLFLAG_RDTUN, &rf->dcqcn_params.dcqcn_b, 0,
82835105900SBartosz Sobczak 		       "set number of MSS to add to the congestion window in additive increase mode, default=0x249f0");
829cdcd52d4SBartosz Sobczak 
83035105900SBartosz Sobczak 	rf->dcqcn_params.rai_factor = 1;
831cdcd52d4SBartosz Sobczak 	SYSCTL_ADD_U16(&rf->tun_info.irdma_sysctl_ctx, irdma_sysctl_oid_list,
832cdcd52d4SBartosz Sobczak 		       OID_AUTO, "dcqcn_rai_factor", CTLFLAG_RDTUN,
833cdcd52d4SBartosz Sobczak 		       &rf->dcqcn_params.rai_factor, 0,
83435105900SBartosz Sobczak 		       "set number of MSS to add to the congestion window in additive increase mode, default=1");
835cdcd52d4SBartosz Sobczak 
83635105900SBartosz Sobczak 	rf->dcqcn_params.hai_factor = 5;
837cdcd52d4SBartosz Sobczak 	SYSCTL_ADD_U16(&rf->tun_info.irdma_sysctl_ctx, irdma_sysctl_oid_list,
838cdcd52d4SBartosz Sobczak 		       OID_AUTO, "dcqcn_hai_factor", CTLFLAG_RDTUN,
839cdcd52d4SBartosz Sobczak 		       &rf->dcqcn_params.hai_factor, 0,
84035105900SBartosz Sobczak 		       "set number of MSS to add to the congestion window in hyperactive increase mode, default=5");
841cdcd52d4SBartosz Sobczak 
84235105900SBartosz Sobczak 	rf->dcqcn_params.rreduce_mperiod = 50;
843cdcd52d4SBartosz Sobczak 	SYSCTL_ADD_U32(&rf->tun_info.irdma_sysctl_ctx, irdma_sysctl_oid_list,
844cdcd52d4SBartosz Sobczak 		       OID_AUTO, "dcqcn_rreduce_mperiod", CTLFLAG_RDTUN,
845cdcd52d4SBartosz Sobczak 		       &rf->dcqcn_params.rreduce_mperiod, 0,
84635105900SBartosz Sobczak 		       "set minimum time between 2 consecutive rate reductions for a single flow, default=50");
847cdcd52d4SBartosz Sobczak }
848cdcd52d4SBartosz Sobczak 
849cdcd52d4SBartosz Sobczak /**
85001fbb869SBartosz Sobczak  * irdma_sysctl_settings - sysctl runtime settings init
85101fbb869SBartosz Sobczak  * @rf: RDMA PCI function
85201fbb869SBartosz Sobczak  */
85301fbb869SBartosz Sobczak void
irdma_sysctl_settings(struct irdma_pci_f * rf)85401fbb869SBartosz Sobczak irdma_sysctl_settings(struct irdma_pci_f *rf)
85501fbb869SBartosz Sobczak {
85601fbb869SBartosz Sobczak 	struct sysctl_oid_list *irdma_sysctl_oid_list;
85701fbb869SBartosz Sobczak 
85801fbb869SBartosz Sobczak 	irdma_sysctl_oid_list = SYSCTL_CHILDREN(rf->tun_info.irdma_sysctl_tree);
85901fbb869SBartosz Sobczak 
86001fbb869SBartosz Sobczak 	SYSCTL_ADD_BOOL(&rf->tun_info.irdma_sysctl_ctx, irdma_sysctl_oid_list,
86101fbb869SBartosz Sobczak 			OID_AUTO, "upload_context", CTLFLAG_RWTUN,
86201fbb869SBartosz Sobczak 			&irdma_upload_context, 0,
86301fbb869SBartosz Sobczak 			"allow for generating QP's upload context, default=0");
86401fbb869SBartosz Sobczak }
86501fbb869SBartosz Sobczak 
86601fbb869SBartosz Sobczak void
irdma_sw_stats_tunables_init(struct irdma_pci_f * rf)86701fbb869SBartosz Sobczak irdma_sw_stats_tunables_init(struct irdma_pci_f *rf)
86801fbb869SBartosz Sobczak {
86901fbb869SBartosz Sobczak 	struct sysctl_oid_list *sws_oid_list;
87001fbb869SBartosz Sobczak 	struct sysctl_ctx_list *irdma_ctx = &rf->tun_info.irdma_sysctl_ctx;
87101fbb869SBartosz Sobczak 	struct irdma_sc_dev *dev = &rf->sc_dev;
87201fbb869SBartosz Sobczak 	struct irdma_cm_core *cm_core = &rf->iwdev->cm_core;
87301fbb869SBartosz Sobczak 	struct irdma_puda_rsrc *ilq = rf->iwdev->vsi.ilq;
87401fbb869SBartosz Sobczak 	struct irdma_puda_rsrc *ieq = rf->iwdev->vsi.ieq;
87501fbb869SBartosz Sobczak 	u64 *ll_ptr;
87601fbb869SBartosz Sobczak 	u32 *l_ptr;
87701fbb869SBartosz Sobczak 	int cqp_stat_cnt = sizeof(irdma_sws_list) / sizeof(struct irdma_sw_stats_tunable_info);
87801fbb869SBartosz Sobczak 	int cmcore_stat_cnt = sizeof(irdma_cmcs_list) / sizeof(struct irdma_sw_stats_tunable_info);
87901fbb869SBartosz Sobczak 	int ilqs_stat_cnt = sizeof(irdma_ilqs_list) / sizeof(struct irdma_sw_stats_tunable_info);
88001fbb869SBartosz Sobczak 	int ilqs32_stat_cnt = sizeof(irdma_ilqs32_list) / sizeof(struct irdma_sw_stats_tunable_info);
88101fbb869SBartosz Sobczak 	int ieqs_stat_cnt = sizeof(irdma_ieqs_list) / sizeof(struct irdma_sw_stats_tunable_info);
88201fbb869SBartosz Sobczak 	int ieqs32_stat_cnt = sizeof(irdma_ieqs32_list) / sizeof(struct irdma_sw_stats_tunable_info);
88301fbb869SBartosz Sobczak 	int i;
88401fbb869SBartosz Sobczak 
88501fbb869SBartosz Sobczak 	sws_oid_list = SYSCTL_CHILDREN(rf->tun_info.sws_sysctl_tree);
88601fbb869SBartosz Sobczak 
88701fbb869SBartosz Sobczak 	for (i = 0; i < cqp_stat_cnt; ++i) {
88801fbb869SBartosz Sobczak 		SYSCTL_ADD_U64(irdma_ctx, sws_oid_list, OID_AUTO,
88901fbb869SBartosz Sobczak 			       irdma_sws_list[i].name, CTLFLAG_RD,
89001fbb869SBartosz Sobczak 			       &dev->cqp_cmd_stats[irdma_sws_list[i].op_type],
89101fbb869SBartosz Sobczak 			       0, irdma_sws_list[i].desc);
89201fbb869SBartosz Sobczak 	}
89301fbb869SBartosz Sobczak 	SYSCTL_ADD_PROC(irdma_ctx, sws_oid_list, OID_AUTO,
89401fbb869SBartosz Sobczak 			"req_cmds", CTLFLAG_RD | CTLTYPE_STRING,
89501fbb869SBartosz Sobczak 			dev->cqp, IRDMA_CQP_REQ_CMDS, irdma_sysctl_cqp_stats, "A",
89601fbb869SBartosz Sobczak 			"req_cmds");
89701fbb869SBartosz Sobczak 	SYSCTL_ADD_PROC(irdma_ctx, sws_oid_list, OID_AUTO,
89801fbb869SBartosz Sobczak 			"cmpl_cmds", CTLFLAG_RD | CTLTYPE_STRING,
89901fbb869SBartosz Sobczak 			dev->cqp, IRDMA_CQP_CMPL_CMDS, irdma_sysctl_cqp_stats, "A",
90001fbb869SBartosz Sobczak 			"cmpl_cmds");
90101fbb869SBartosz Sobczak 	for (i = 0; i < cmcore_stat_cnt; ++i) {
90201fbb869SBartosz Sobczak 		ll_ptr = (u64 *)((uintptr_t)cm_core + irdma_cmcs_list[i].value);
90301fbb869SBartosz Sobczak 		SYSCTL_ADD_U64(irdma_ctx, sws_oid_list, OID_AUTO,
90401fbb869SBartosz Sobczak 			       irdma_cmcs_list[i].name, CTLFLAG_RD, ll_ptr,
90501fbb869SBartosz Sobczak 			       0, irdma_cmcs_list[i].desc);
90601fbb869SBartosz Sobczak 	}
90701fbb869SBartosz Sobczak 	for (i = 0; ilq && i < ilqs_stat_cnt; ++i) {
90801fbb869SBartosz Sobczak 		ll_ptr = (u64 *)((uintptr_t)ilq + irdma_ilqs_list[i].value);
90901fbb869SBartosz Sobczak 		SYSCTL_ADD_U64(irdma_ctx, sws_oid_list, OID_AUTO,
91001fbb869SBartosz Sobczak 			       irdma_ilqs_list[i].name, CTLFLAG_RD, ll_ptr,
91101fbb869SBartosz Sobczak 			       0, irdma_ilqs_list[i].desc);
91201fbb869SBartosz Sobczak 	}
91301fbb869SBartosz Sobczak 	for (i = 0; ilq && i < ilqs32_stat_cnt; ++i) {
91401fbb869SBartosz Sobczak 		l_ptr = (u32 *)((uintptr_t)ilq + irdma_ilqs32_list[i].value);
91501fbb869SBartosz Sobczak 		SYSCTL_ADD_U32(irdma_ctx, sws_oid_list, OID_AUTO,
91601fbb869SBartosz Sobczak 			       irdma_ilqs32_list[i].name, CTLFLAG_RD, l_ptr,
91701fbb869SBartosz Sobczak 			       0, irdma_ilqs32_list[i].desc);
91801fbb869SBartosz Sobczak 	}
91901fbb869SBartosz Sobczak 	for (i = 0; ieq && i < ieqs_stat_cnt; ++i) {
92001fbb869SBartosz Sobczak 		ll_ptr = (u64 *)((uintptr_t)ieq + irdma_ieqs_list[i].value);
92101fbb869SBartosz Sobczak 		SYSCTL_ADD_U64(irdma_ctx, sws_oid_list, OID_AUTO,
92201fbb869SBartosz Sobczak 			       irdma_ieqs_list[i].name, CTLFLAG_RD, ll_ptr,
92301fbb869SBartosz Sobczak 			       0, irdma_ieqs_list[i].desc);
92401fbb869SBartosz Sobczak 	}
92501fbb869SBartosz Sobczak 	for (i = 0; ieq && i < ieqs32_stat_cnt; ++i) {
92601fbb869SBartosz Sobczak 		l_ptr = (u32 *)((uintptr_t)ieq + irdma_ieqs32_list[i].value);
92701fbb869SBartosz Sobczak 		SYSCTL_ADD_U32(irdma_ctx, sws_oid_list, OID_AUTO,
92801fbb869SBartosz Sobczak 			       irdma_ieqs32_list[i].name, CTLFLAG_RD, l_ptr,
92901fbb869SBartosz Sobczak 			       0, irdma_ieqs32_list[i].desc);
93001fbb869SBartosz Sobczak 	}
93101fbb869SBartosz Sobczak }
93201fbb869SBartosz Sobczak 
93301fbb869SBartosz Sobczak /**
934cdcd52d4SBartosz Sobczak  * irdma_dmamap_cb - callback for bus_dmamap_load
935cdcd52d4SBartosz Sobczak  */
936cdcd52d4SBartosz Sobczak static void
irdma_dmamap_cb(void * arg,bus_dma_segment_t * segs,int nseg,int error)937cdcd52d4SBartosz Sobczak irdma_dmamap_cb(void *arg, bus_dma_segment_t * segs, int nseg, int error)
938cdcd52d4SBartosz Sobczak {
939cdcd52d4SBartosz Sobczak 	if (error)
940cdcd52d4SBartosz Sobczak 		return;
941cdcd52d4SBartosz Sobczak 	*(bus_addr_t *) arg = segs->ds_addr;
942cdcd52d4SBartosz Sobczak 	return;
943cdcd52d4SBartosz Sobczak }
944cdcd52d4SBartosz Sobczak 
945cdcd52d4SBartosz Sobczak /**
946cdcd52d4SBartosz Sobczak  * irdma_allocate_dma_mem - allocate dma memory
947cdcd52d4SBartosz Sobczak  * @hw: pointer to hw structure
948cdcd52d4SBartosz Sobczak  * @mem: structure holding memory information
949cdcd52d4SBartosz Sobczak  * @size: requested size
950cdcd52d4SBartosz Sobczak  * @alignment: requested alignment
951cdcd52d4SBartosz Sobczak  */
952cdcd52d4SBartosz Sobczak void *
irdma_allocate_dma_mem(struct irdma_hw * hw,struct irdma_dma_mem * mem,u64 size,u32 alignment)953cdcd52d4SBartosz Sobczak irdma_allocate_dma_mem(struct irdma_hw *hw, struct irdma_dma_mem *mem,
954cdcd52d4SBartosz Sobczak 		       u64 size, u32 alignment)
955cdcd52d4SBartosz Sobczak {
956cdcd52d4SBartosz Sobczak 	struct irdma_dev_ctx *dev_ctx = (struct irdma_dev_ctx *)hw->dev_context;
957cdcd52d4SBartosz Sobczak 	device_t dev = dev_ctx->dev;
958cdcd52d4SBartosz Sobczak 	void *va;
959cdcd52d4SBartosz Sobczak 	int ret;
960cdcd52d4SBartosz Sobczak 
961cdcd52d4SBartosz Sobczak 	ret = bus_dma_tag_create(bus_get_dma_tag(dev),	/* parent */
962cdcd52d4SBartosz Sobczak 				 alignment, 0,	/* alignment, bounds */
963cdcd52d4SBartosz Sobczak 				 BUS_SPACE_MAXADDR,	/* lowaddr */
964cdcd52d4SBartosz Sobczak 				 BUS_SPACE_MAXADDR,	/* highaddr */
965cdcd52d4SBartosz Sobczak 				 NULL, NULL,	/* filter, filterarg */
966cdcd52d4SBartosz Sobczak 				 size,	/* maxsize */
967cdcd52d4SBartosz Sobczak 				 1,	/* nsegments */
968cdcd52d4SBartosz Sobczak 				 size,	/* maxsegsize */
969cdcd52d4SBartosz Sobczak 				 BUS_DMA_ALLOCNOW,	/* flags */
970cdcd52d4SBartosz Sobczak 				 NULL,	/* lockfunc */
971cdcd52d4SBartosz Sobczak 				 NULL,	/* lockfuncarg */
972cdcd52d4SBartosz Sobczak 				 &mem->tag);
973cdcd52d4SBartosz Sobczak 	if (ret != 0) {
974cdcd52d4SBartosz Sobczak 		device_printf(dev, "%s: bus_dma_tag_create failed, error %u\n",
975cdcd52d4SBartosz Sobczak 			      __func__, ret);
976cdcd52d4SBartosz Sobczak 		goto fail_0;
977cdcd52d4SBartosz Sobczak 	}
978cdcd52d4SBartosz Sobczak 	ret = bus_dmamem_alloc(mem->tag, (void **)&va,
979cdcd52d4SBartosz Sobczak 			       BUS_DMA_NOWAIT | BUS_DMA_ZERO, &mem->map);
980cdcd52d4SBartosz Sobczak 	if (ret != 0) {
981cdcd52d4SBartosz Sobczak 		device_printf(dev, "%s: bus_dmamem_alloc failed, error %u\n",
982cdcd52d4SBartosz Sobczak 			      __func__, ret);
983cdcd52d4SBartosz Sobczak 		goto fail_1;
984cdcd52d4SBartosz Sobczak 	}
985cdcd52d4SBartosz Sobczak 	ret = bus_dmamap_load(mem->tag, mem->map, va, size,
986cdcd52d4SBartosz Sobczak 			      irdma_dmamap_cb, &mem->pa, BUS_DMA_NOWAIT);
987cdcd52d4SBartosz Sobczak 	if (ret != 0) {
988cdcd52d4SBartosz Sobczak 		device_printf(dev, "%s: bus_dmamap_load failed, error %u\n",
989cdcd52d4SBartosz Sobczak 			      __func__, ret);
990cdcd52d4SBartosz Sobczak 		goto fail_2;
991cdcd52d4SBartosz Sobczak 	}
992cdcd52d4SBartosz Sobczak 	mem->nseg = 1;
993cdcd52d4SBartosz Sobczak 	mem->size = size;
994cdcd52d4SBartosz Sobczak 	bus_dmamap_sync(mem->tag, mem->map,
995cdcd52d4SBartosz Sobczak 			BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
996cdcd52d4SBartosz Sobczak 
997cdcd52d4SBartosz Sobczak 	return va;
998cdcd52d4SBartosz Sobczak fail_2:
999cdcd52d4SBartosz Sobczak 	bus_dmamem_free(mem->tag, va, mem->map);
1000cdcd52d4SBartosz Sobczak fail_1:
1001cdcd52d4SBartosz Sobczak 	bus_dma_tag_destroy(mem->tag);
1002cdcd52d4SBartosz Sobczak fail_0:
1003cdcd52d4SBartosz Sobczak 	mem->map = NULL;
1004cdcd52d4SBartosz Sobczak 	mem->tag = NULL;
1005cdcd52d4SBartosz Sobczak 
1006cdcd52d4SBartosz Sobczak 	return NULL;
1007cdcd52d4SBartosz Sobczak }
1008cdcd52d4SBartosz Sobczak 
1009cdcd52d4SBartosz Sobczak /**
1010cdcd52d4SBartosz Sobczak  * irdma_free_dma_mem - Memory free helper fn
1011cdcd52d4SBartosz Sobczak  * @hw: pointer to hw structure
1012cdcd52d4SBartosz Sobczak  * @mem: ptr to mem struct to free
1013cdcd52d4SBartosz Sobczak  */
1014cdcd52d4SBartosz Sobczak int
irdma_free_dma_mem(struct irdma_hw * hw,struct irdma_dma_mem * mem)1015cdcd52d4SBartosz Sobczak irdma_free_dma_mem(struct irdma_hw *hw, struct irdma_dma_mem *mem)
1016cdcd52d4SBartosz Sobczak {
1017cdcd52d4SBartosz Sobczak 	if (!mem)
1018cdcd52d4SBartosz Sobczak 		return -EINVAL;
1019cdcd52d4SBartosz Sobczak 	bus_dmamap_sync(mem->tag, mem->map,
1020cdcd52d4SBartosz Sobczak 			BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
1021cdcd52d4SBartosz Sobczak 	bus_dmamap_unload(mem->tag, mem->map);
1022cdcd52d4SBartosz Sobczak 	if (!mem->va)
1023cdcd52d4SBartosz Sobczak 		return -ENOMEM;
1024cdcd52d4SBartosz Sobczak 	bus_dmamem_free(mem->tag, mem->va, mem->map);
1025cdcd52d4SBartosz Sobczak 	bus_dma_tag_destroy(mem->tag);
1026cdcd52d4SBartosz Sobczak 
1027cdcd52d4SBartosz Sobczak 	mem->va = NULL;
1028cdcd52d4SBartosz Sobczak 
1029cdcd52d4SBartosz Sobczak 	return 0;
1030cdcd52d4SBartosz Sobczak }
1031cdcd52d4SBartosz Sobczak 
103235105900SBartosz Sobczak void
irdma_cleanup_dead_qps(struct irdma_sc_vsi * vsi)103335105900SBartosz Sobczak irdma_cleanup_dead_qps(struct irdma_sc_vsi *vsi)
103435105900SBartosz Sobczak {
103535105900SBartosz Sobczak 	struct irdma_sc_qp *qp = NULL;
103635105900SBartosz Sobczak 	struct irdma_qp *iwqp;
103735105900SBartosz Sobczak 	struct irdma_pci_f *rf;
103835105900SBartosz Sobczak 	u8 i;
103935105900SBartosz Sobczak 
104035105900SBartosz Sobczak 	for (i = 0; i < IRDMA_MAX_USER_PRIORITY; i++) {
104135105900SBartosz Sobczak 		qp = irdma_get_qp_from_list(&vsi->qos[i].qplist, qp);
104235105900SBartosz Sobczak 		while (qp) {
104335105900SBartosz Sobczak 			if (qp->qp_uk.qp_type == IRDMA_QP_TYPE_UDA) {
104435105900SBartosz Sobczak 				qp = irdma_get_qp_from_list(&vsi->qos[i].qplist, qp);
104535105900SBartosz Sobczak 				continue;
104635105900SBartosz Sobczak 			}
104735105900SBartosz Sobczak 			iwqp = qp->qp_uk.back_qp;
104835105900SBartosz Sobczak 			rf = iwqp->iwdev->rf;
104935105900SBartosz Sobczak 			irdma_free_dma_mem(rf->sc_dev.hw, &iwqp->q2_ctx_mem);
105035105900SBartosz Sobczak 			irdma_free_dma_mem(rf->sc_dev.hw, &iwqp->kqp.dma_mem);
105135105900SBartosz Sobczak 
105235105900SBartosz Sobczak 			kfree(iwqp->kqp.sq_wrid_mem);
105335105900SBartosz Sobczak 			kfree(iwqp->kqp.rq_wrid_mem);
105435105900SBartosz Sobczak 			qp = irdma_get_qp_from_list(&vsi->qos[i].qplist, qp);
105535105900SBartosz Sobczak 			kfree(iwqp);
105635105900SBartosz Sobczak 		}
105735105900SBartosz Sobczak 	}
105835105900SBartosz Sobczak }
1059