The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/irdma/fbsd_kcompat.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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 }

Cache object: eb953490c446c67cca0437c547489caa


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.