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