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