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