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/icrdma.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 <sys/param.h>
   37 #include <sys/systm.h>
   38 #include <sys/bus.h>
   39 #include <sys/kernel.h>
   40 #include <sys/module.h>
   41 #include <sys/sysctl.h>
   42 #include <machine/bus.h>
   43 #include <linux/device.h>
   44 #include <sys/rman.h>
   45 
   46 #include "ice_rdma.h"
   47 #include "irdma_main.h"
   48 #include "icrdma_hw.h"
   49 
   50 #include "irdma_if.h"
   51 #include "irdma_di_if.h"
   52 
   53 /**
   54  *  Driver version
   55  */
   56 char irdma_driver_version[] = "1.1.5-k";
   57 
   58 #define pf_if_d(peer) peer->ifp->if_dunit
   59 
   60 /**
   61  * irdma_init_tunable - prepare tunables
   62  * @rf: RDMA PCI function
   63  * @pf_id: id of the pf
   64  */
   65 static void
   66 irdma_init_tunable(struct irdma_pci_f *rf, uint8_t pf_id)
   67 {
   68         struct sysctl_oid_list *irdma_sysctl_oid_list;
   69         char pf_name[16];
   70 
   71         snprintf(pf_name, 15, "irdma%d", pf_id);
   72         sysctl_ctx_init(&rf->tun_info.irdma_sysctl_ctx);
   73 
   74         rf->tun_info.irdma_sysctl_tree = SYSCTL_ADD_NODE(&rf->tun_info.irdma_sysctl_ctx,
   75                                                          SYSCTL_STATIC_CHILDREN(_dev),
   76                                                          OID_AUTO, pf_name, CTLFLAG_RD,
   77                                                          NULL, "");
   78 
   79         irdma_sysctl_oid_list = SYSCTL_CHILDREN(rf->tun_info.irdma_sysctl_tree);
   80 
   81         /*
   82          * debug mask setting
   83          */
   84         SYSCTL_ADD_S32(&rf->tun_info.irdma_sysctl_ctx, irdma_sysctl_oid_list,
   85                        OID_AUTO, "debug", CTLFLAG_RWTUN, &rf->sc_dev.debug_mask,
   86                        0, "irdma debug");
   87 
   88         /*
   89          * RoCEv2/iWARP setting RoCEv2 the default mode
   90          */
   91         rf->tun_info.roce_ena = 1;
   92         SYSCTL_ADD_U8(&rf->tun_info.irdma_sysctl_ctx, irdma_sysctl_oid_list, OID_AUTO,
   93                       "roce_enable", CTLFLAG_RDTUN, &rf->tun_info.roce_ena, 0,
   94                       "RoCEv2 mode enable");
   95 
   96         rf->protocol_used = IRDMA_IWARP_PROTOCOL_ONLY;
   97         if (rf->tun_info.roce_ena == 1)
   98                 rf->protocol_used = IRDMA_ROCE_PROTOCOL_ONLY;
   99         else if (rf->tun_info.roce_ena != 0)
  100                 printf("%s:%d wrong roce_enable value (%d), using iWARP\n",
  101                        __func__, __LINE__, rf->tun_info.roce_ena);
  102         printf("%s:%d protocol: %s, roce_enable value: %d\n", __func__, __LINE__,
  103                (rf->protocol_used == IRDMA_IWARP_PROTOCOL_ONLY) ? "iWARP" : "RoCEv2",
  104                rf->tun_info.roce_ena);
  105 
  106         snprintf(rf->tun_info.drv_ver, IRDMA_VER_LEN, "%s", irdma_driver_version);
  107         SYSCTL_ADD_STRING(&rf->tun_info.irdma_sysctl_ctx, irdma_sysctl_oid_list,
  108                           OID_AUTO, "drv_ver", CTLFLAG_RDTUN, rf->tun_info.drv_ver,
  109                           IRDMA_VER_LEN, "driver version");
  110 
  111         irdma_dcqcn_tunables_init(rf);
  112 }
  113 
  114 /**
  115  * irdma_find_handler - obtain hdl object to identify pf
  116  * @p_dev: the peer interface structure
  117  */
  118 static struct irdma_handler *
  119 irdma_find_handler(struct ice_rdma_peer *p_dev)
  120 {
  121         struct irdma_handler *hdl;
  122         unsigned long flags;
  123 
  124         spin_lock_irqsave(&irdma_handler_lock, flags);
  125         list_for_each_entry(hdl, &irdma_handlers, list) {
  126                 if (!hdl)
  127                         continue;
  128                 if (!hdl->iwdev->rf->peer_info)
  129                         continue;
  130                 if (hdl->iwdev->rf->peer_info->dev == p_dev->dev) {
  131                         spin_unlock_irqrestore(&irdma_handler_lock, flags);
  132                         return hdl;
  133                 }
  134         }
  135         spin_unlock_irqrestore(&irdma_handler_lock, flags);
  136 
  137         return NULL;
  138 }
  139 
  140 /**
  141  * peer_to_iwdev - return iwdev based on peer
  142  * @peer: the peer interface structure
  143  */
  144 static struct irdma_device *
  145 peer_to_iwdev(struct ice_rdma_peer *peer)
  146 {
  147         struct irdma_handler *hdl;
  148 
  149         hdl = irdma_find_handler(peer);
  150         if (!hdl) {
  151                 printf("%s:%d rdma handler not found\n", __func__, __LINE__);
  152                 return NULL;
  153         }
  154 
  155         return hdl->iwdev;
  156 }
  157 
  158 /**
  159  * irdma_get_qos_info - save qos info from parameters to internal struct
  160  * @l2params: destination, qos, tc, mtu info structure
  161  * @qos_info: source, DCB settings structure
  162  */
  163 static void
  164 irdma_get_qos_info(struct irdma_l2params *l2params, struct ice_qos_params *qos_info)
  165 {
  166         int i;
  167 
  168         l2params->num_tc = qos_info->num_tc;
  169         l2params->num_apps = qos_info->num_apps;
  170         l2params->vsi_prio_type = qos_info->vsi_priority_type;
  171         l2params->vsi_rel_bw = qos_info->vsi_relative_bw;
  172         for (i = 0; i < l2params->num_tc; i++) {
  173                 l2params->tc_info[i].egress_virt_up =
  174                     qos_info->tc_info[i].egress_virt_up;
  175                 l2params->tc_info[i].ingress_virt_up =
  176                     qos_info->tc_info[i].ingress_virt_up;
  177                 l2params->tc_info[i].prio_type = qos_info->tc_info[i].prio_type;
  178                 l2params->tc_info[i].rel_bw = qos_info->tc_info[i].rel_bw;
  179                 l2params->tc_info[i].tc_ctx = qos_info->tc_info[i].tc_ctx;
  180         }
  181         for (i = 0; i < IRDMA_MAX_USER_PRIORITY; i++)
  182                 l2params->up2tc[i] = qos_info->up2tc[i];
  183 
  184         if (qos_info->pfc_mode == IRDMA_QOS_MODE_DSCP) {
  185                 l2params->dscp_mode = true;
  186                 memcpy(l2params->dscp_map, qos_info->dscp_map, sizeof(l2params->dscp_map));
  187         }
  188         printf("%s:%d: l2params settings:\n num_tc %d,\n num_apps %d,\n",
  189                __func__, __LINE__, l2params->num_tc, l2params->num_apps);
  190         printf(" vsi_prio_type %d,\n vsi_rel_bw %d,\n egress_virt_up:",
  191                l2params->vsi_prio_type, l2params->vsi_rel_bw);
  192         for (i = 0; i < l2params->num_tc; i++)
  193                 printf(" %d", l2params->tc_info[i].egress_virt_up);
  194         printf("\n ingress_virt_up:");
  195         for (i = 0; i < l2params->num_tc; i++)
  196                 printf(" %d", l2params->tc_info[i].ingress_virt_up);
  197         printf("\n prio_type:");
  198         for (i = 0; i < l2params->num_tc; i++)
  199                 printf(" %d", l2params->tc_info[i].prio_type);
  200         printf("\n rel_bw:");
  201         for (i = 0; i < l2params->num_tc; i++)
  202                 printf(" %d", l2params->tc_info[i].rel_bw);
  203         printf("\n tc_ctx:");
  204         for (i = 0; i < l2params->num_tc; i++)
  205                 printf(" %lu", l2params->tc_info[i].tc_ctx);
  206         printf("\n up2tc:");
  207         for (i = 0; i < IRDMA_MAX_USER_PRIORITY; i++)
  208                 printf(" %d", l2params->up2tc[i]);
  209         printf(" dscp_mode: %d,\n", l2params->dscp_mode);
  210         for (i = 0; i < IRDMA_DSCP_NUM_VAL; i++)
  211                 printf(" %d", l2params->dscp_map[i]);
  212         printf("\n");
  213 
  214         dump_struct(l2params, sizeof(*l2params), "l2params");
  215 }
  216 
  217 /**
  218  * irdma_log_invalid_mtu - check mtu setting validity
  219  * @mtu: mtu value
  220  * @dev: hardware control device structure
  221  */
  222 static void
  223 irdma_log_invalid_mtu(u16 mtu, struct irdma_sc_dev *dev)
  224 {
  225         if (mtu < IRDMA_MIN_MTU_IPV4)
  226                 irdma_dev_warn(dev, "MTU setting [%d] too low for RDMA traffic. Minimum MTU is 576 for IPv4\n", mtu);
  227         else if (mtu < IRDMA_MIN_MTU_IPV6)
  228                 irdma_dev_warn(dev, "MTU setting [%d] too low for RDMA traffic. Minimum MTU is 1280 for IPv6\\n", mtu);
  229 }
  230 
  231 /**
  232  * irdma_event_handler - handling events from lan driver
  233  * @peer: the peer interface structure
  234  * @event: event info structure
  235  */
  236 static void
  237 irdma_event_handler(struct ice_rdma_peer *peer, struct ice_rdma_event *event)
  238 {
  239         struct irdma_device *iwdev;
  240         struct irdma_l2params l2params = {};
  241 
  242         printf("%s:%d event_handler %s (%x) on pf %d (%d)\n", __func__, __LINE__,
  243                (event->type == 1) ? "LINK CHANGE" :
  244                (event->type == 2) ? "MTU CHANGE" :
  245                (event->type == 3) ? "TC CHANGE" : "UNKNOWN",
  246                event->type, peer->pf_id, pf_if_d(peer));
  247         iwdev = peer_to_iwdev(peer);
  248         if (!iwdev) {
  249                 printf("%s:%d rdma device not found\n", __func__, __LINE__);
  250                 return;
  251         }
  252 
  253         switch (event->type) {
  254         case ICE_RDMA_EVENT_LINK_CHANGE:
  255                 printf("%s:%d PF: %x (%x), state: %d, speed: %lu\n", __func__, __LINE__,
  256                        peer->pf_id, pf_if_d(peer), event->linkstate, event->baudrate);
  257                 break;
  258         case ICE_RDMA_EVENT_MTU_CHANGE:
  259                 if (iwdev->vsi.mtu != event->mtu) {
  260                         l2params.mtu = event->mtu;
  261                         l2params.mtu_changed = true;
  262                         irdma_log_invalid_mtu(l2params.mtu, &iwdev->rf->sc_dev);
  263                         irdma_change_l2params(&iwdev->vsi, &l2params);
  264                 }
  265                 break;
  266         case ICE_RDMA_EVENT_TC_CHANGE:
  267                 /*
  268                  * 1. check if it is pre or post 2. check if it is currently being done
  269                  */
  270                 if (event->prep == iwdev->vsi.tc_change_pending) {
  271                         printf("%s:%d can't process %s TC change if TC change is %spending\n",
  272                                __func__, __LINE__,
  273                                event->prep ? "pre" : "post",
  274                                event->prep ? " " : "not ");
  275                         goto done;
  276                 }
  277                 if (event->prep) {
  278                         iwdev->vsi.tc_change_pending = true;
  279                         irdma_sc_suspend_resume_qps(&iwdev->vsi, IRDMA_OP_SUSPEND);
  280                         wait_event_timeout(iwdev->suspend_wq,
  281                                            !atomic_read(&iwdev->vsi.qp_suspend_reqs),
  282                                            IRDMA_EVENT_TIMEOUT_MS * 10);
  283                         irdma_ws_reset(&iwdev->vsi);
  284                         printf("%s:%d TC change preparation done\n", __func__, __LINE__);
  285                 } else {
  286                         l2params.tc_changed = true;
  287                         irdma_get_qos_info(&l2params, &event->port_qos);
  288                         if (iwdev->rf->protocol_used != IRDMA_IWARP_PROTOCOL_ONLY)
  289                                 iwdev->dcb_vlan_mode = l2params.num_tc > 1 && !l2params.dscp_mode;
  290 
  291                         irdma_check_fc_for_tc_update(&iwdev->vsi, &l2params);
  292                         irdma_change_l2params(&iwdev->vsi, &l2params);
  293                         printf("%s:%d TC change done\n", __func__, __LINE__);
  294                 }
  295                 break;
  296         case ICE_RDMA_EVENT_CRIT_ERR:
  297                 printf("%s:%d event type received: %d\n", __func__, __LINE__, event->type);
  298                 break;
  299         default:
  300                 printf("%s:%d event type unsupported: %d\n", __func__, __LINE__, event->type);
  301         }
  302 done:
  303         return;
  304 }
  305 
  306 /**
  307  * irdma_link_change - Callback for link state change
  308  * @peer: the peer interface structure
  309  * @linkstate: state of the link
  310  * @baudrate: speed of the link
  311  */
  312 static void
  313 irdma_link_change(struct ice_rdma_peer *peer, int linkstate, uint64_t baudrate)
  314 {
  315         printf("%s:%d PF: %x (%x), state: %d, speed: %lu\n", __func__, __LINE__,
  316                peer->pf_id, pf_if_d(peer), linkstate, baudrate);
  317 }
  318 
  319 /**
  320  * irdma_finalize_task - Finish open or close phase in a separate thread
  321  * @context: instance holding peer and iwdev information
  322  *
  323  * Triggered from irdma_open or irdma_close to perform rt_init_hw or
  324  * rt_deinit_hw respectively. Does registration and unregistration of
  325  * the device.
  326  */
  327 static void
  328 irdma_finalize_task(void *context, int pending)
  329 {
  330         struct irdma_task_arg *task_arg = (struct irdma_task_arg *)context;
  331         struct irdma_device *iwdev = task_arg->iwdev;
  332         struct irdma_pci_f *rf = iwdev->rf;
  333         struct ice_rdma_peer *peer = task_arg->peer;
  334         struct irdma_l2params l2params = {{{0}}};
  335         struct ice_rdma_request req = {0};
  336         int status = 0;
  337 
  338         if (iwdev->iw_status) {
  339                 irdma_debug(&rf->sc_dev, IRDMA_DEBUG_INIT, "Starting deferred closing %d (%d)\n",
  340                             rf->peer_info->pf_id, pf_if_d(peer));
  341                 irdma_dereg_ipaddr_event_cb(rf);
  342                 irdma_ib_unregister_device(iwdev);
  343                 req.type = ICE_RDMA_EVENT_VSI_FILTER_UPDATE;
  344                 req.enable_filter = false;
  345                 IRDMA_DI_REQ_HANDLER(peer, &req);
  346                 irdma_rt_deinit_hw(iwdev);
  347         } else {
  348                 irdma_debug(&rf->sc_dev, IRDMA_DEBUG_INIT, "Starting deferred opening %d (%d)\n",
  349                             rf->peer_info->pf_id, pf_if_d(peer));
  350                 l2params.mtu = peer->mtu;
  351                 irdma_get_qos_info(&l2params, &peer->initial_qos_info);
  352                 if (iwdev->rf->protocol_used != IRDMA_IWARP_PROTOCOL_ONLY)
  353                         iwdev->dcb_vlan_mode = l2params.num_tc > 1 && !l2params.dscp_mode;
  354 
  355                 status = irdma_rt_init_hw(iwdev, &l2params);
  356                 if (status) {
  357                         irdma_pr_err("RT init failed %d\n", status);
  358                         ib_dealloc_device(&iwdev->ibdev);
  359                         return;
  360                 }
  361                 status = irdma_ib_register_device(iwdev);
  362                 if (status) {
  363                         irdma_pr_err("Registration failed %d\n", status);
  364                         irdma_rt_deinit_hw(iwdev);
  365                         ib_dealloc_device(&iwdev->ibdev);
  366                 }
  367                 req.type = ICE_RDMA_EVENT_VSI_FILTER_UPDATE;
  368                 req.enable_filter = true;
  369                 IRDMA_DI_REQ_HANDLER(peer, &req);
  370                 irdma_reg_ipaddr_event_cb(rf);
  371                 irdma_debug(&rf->sc_dev, IRDMA_DEBUG_INIT, "Deferred opening finished %d (%d)\n",
  372                             rf->peer_info->pf_id, pf_if_d(peer));
  373         }
  374 }
  375 
  376 /**
  377  * irdma_open - Callback for operation open for RDMA device
  378  * @peer: the new peer interface structure
  379  *
  380  * Callback implementing the RDMA_OPEN function. Called by the ice driver to
  381  * notify the RDMA client driver that a new device has been initialized.
  382  */
  383 static int
  384 irdma_open(struct ice_rdma_peer *peer)
  385 {
  386         struct ice_rdma_event event = {0};
  387 
  388         event.type = ICE_RDMA_EVENT_MTU_CHANGE;
  389         event.mtu = peer->mtu;
  390 
  391         irdma_event_handler(peer, &event);
  392 
  393         return 0;
  394 }
  395 
  396 /**
  397  * irdma_close - Callback to notify that a peer device is down
  398  * @peer: the RDMA peer device being stopped
  399  *
  400  * Callback implementing the RDMA_CLOSE function. Called by the ice driver to
  401  * notify the RDMA client driver that a peer device is being stopped.
  402  */
  403 static int
  404 irdma_close(struct ice_rdma_peer *peer)
  405 {
  406         /*
  407          * This is called when ifconfig down. Keeping it for compatibility with ice. This event might be usefull for
  408          * future.
  409          */
  410         return 0;
  411 }
  412 
  413 /**
  414  * irdma_alloc_pcidev - allocate memory for pcidev and populate data
  415  * @peer: the new peer interface structure
  416  * @rf: RDMA PCI function
  417  */
  418 static int
  419 irdma_alloc_pcidev(struct ice_rdma_peer *peer, struct irdma_pci_f *rf)
  420 {
  421         rf->pcidev = kzalloc(sizeof(struct pci_dev), GFP_KERNEL);
  422         if (!rf->pcidev) {
  423                 return -ENOMEM;
  424         }
  425         if (linux_pci_attach_device(rf->dev_ctx.dev, NULL, NULL, rf->pcidev))
  426                 return -ENOMEM;
  427 
  428         return 0;
  429 }
  430 
  431 /**
  432  * irdma_dealloc_pcidev - deallocate memory for pcidev
  433  * @rf: RDMA PCI function
  434  */
  435 static void
  436 irdma_dealloc_pcidev(struct irdma_pci_f *rf)
  437 {
  438         linux_pci_detach_device(rf->pcidev);
  439         kfree(rf->pcidev);
  440 }
  441 
  442 /**
  443  * irdma_fill_device_info - assign initial values to rf variables
  444  * @iwdev: irdma device
  445  * @peer: the peer interface structure
  446  */
  447 static void
  448 irdma_fill_device_info(struct irdma_device *iwdev,
  449                        struct ice_rdma_peer *peer)
  450 {
  451         struct irdma_pci_f *rf = iwdev->rf;
  452 
  453         rf->peer_info = peer;
  454         rf->gen_ops.register_qset = irdma_register_qset;
  455         rf->gen_ops.unregister_qset = irdma_unregister_qset;
  456 
  457         rf->rdma_ver = IRDMA_GEN_2;
  458         rf->sc_dev.hw_attrs.uk_attrs.hw_rev = IRDMA_GEN_2;
  459         rf->rsrc_profile = IRDMA_HMC_PROFILE_DEFAULT;
  460         rf->rst_to = IRDMA_RST_TIMEOUT_HZ;
  461         rf->check_fc = irdma_check_fc_for_qp;
  462         irdma_set_rf_user_cfg_params(rf);
  463 
  464         rf->default_vsi.vsi_idx = peer->pf_vsi_num;
  465         rf->dev_ctx.dev = peer->dev;
  466         rf->dev_ctx.mem_bus_space_tag = rman_get_bustag(peer->pci_mem);
  467         rf->dev_ctx.mem_bus_space_handle = rman_get_bushandle(peer->pci_mem);
  468         rf->dev_ctx.mem_bus_space_size = rman_get_size(peer->pci_mem);
  469 
  470         rf->hw.dev_context = &rf->dev_ctx;
  471         rf->hw.hw_addr = (u8 *)rman_get_virtual(peer->pci_mem);
  472         rf->msix_count = peer->msix.count;
  473         rf->msix_info.entry = peer->msix.base;
  474         rf->msix_info.vector = peer->msix.count;
  475         printf("%s:%d msix_info: %d %d %d\n", __func__, __LINE__,
  476                rf->msix_count, rf->msix_info.entry, rf->msix_info.vector);
  477 
  478         rf->iwdev = iwdev;
  479         iwdev->netdev = peer->ifp;
  480         iwdev->init_state = INITIAL_STATE;
  481         iwdev->vsi_num = peer->pf_vsi_num;
  482         iwdev->rcv_wnd = IRDMA_CM_DEFAULT_RCV_WND_SCALED;
  483         iwdev->rcv_wscale = IRDMA_CM_DEFAULT_RCV_WND_SCALE;
  484         iwdev->roce_cwnd = IRDMA_ROCE_CWND_DEFAULT;
  485         iwdev->roce_ackcreds = IRDMA_ROCE_ACKCREDS_DEFAULT;
  486 
  487         if (rf->protocol_used == IRDMA_ROCE_PROTOCOL_ONLY) {
  488                 iwdev->roce_mode = true;
  489         }
  490 }
  491 
  492 /**
  493  * irdma_probe - Callback to probe a new RDMA peer device
  494  * @peer: the new peer interface structure
  495  *
  496  * Callback implementing the RDMA_PROBE function. Called by the ice driver to
  497  * notify the RDMA client driver that a new device has been created
  498  */
  499 static int
  500 irdma_probe(struct ice_rdma_peer *peer)
  501 {
  502         struct irdma_device *iwdev;
  503         struct irdma_pci_f *rf;
  504         struct irdma_handler *hdl;
  505         int err = 0;
  506 
  507         irdma_pr_info("probe: irdma-%s peer=%p, peer->pf_id=%d, peer->ifp=%p, peer->ifp->if_dunit=%d, peer->pci_mem->r_bustag=%p\n",
  508                       irdma_driver_version, peer, peer->pf_id, peer->ifp,
  509                       pf_if_d(peer), (void *)(uintptr_t)peer->pci_mem->r_bustag);
  510 
  511         hdl = irdma_find_handler(peer);
  512         if (hdl)
  513                 return -EBUSY;
  514 
  515         hdl = kzalloc(sizeof(*hdl), GFP_KERNEL);
  516         if (!hdl)
  517                 return -ENOMEM;
  518 
  519         iwdev = (struct irdma_device *)ib_alloc_device(sizeof(*iwdev));
  520         if (!iwdev) {
  521                 kfree(hdl);
  522                 return -ENOMEM;
  523         }
  524 
  525         iwdev->rf = kzalloc(sizeof(*rf), GFP_KERNEL);
  526         if (!iwdev->rf) {
  527                 ib_dealloc_device(&iwdev->ibdev);
  528                 kfree(hdl);
  529                 return -ENOMEM;
  530         }
  531         hdl->iwdev = iwdev;
  532         iwdev->hdl = hdl;
  533 
  534         irdma_init_tunable(iwdev->rf, pf_if_d(peer));
  535         irdma_fill_device_info(iwdev, peer);
  536         rf = iwdev->rf;
  537 
  538         if (irdma_alloc_pcidev(peer, rf))
  539                 goto err_pcidev;
  540 
  541         irdma_add_handler(hdl);
  542 
  543         if (irdma_ctrl_init_hw(rf)) {
  544                 err = -EIO;
  545                 goto err_ctrl_init;
  546         }
  547 
  548         rf->dev_ctx.task_arg.peer = peer;
  549         rf->dev_ctx.task_arg.iwdev = iwdev;
  550         rf->dev_ctx.task_arg.peer = peer;
  551 
  552         TASK_INIT(&hdl->deferred_task, 0, irdma_finalize_task, &rf->dev_ctx.task_arg);
  553         hdl->deferred_tq = taskqueue_create_fast("irdma_defer",
  554                                                  M_NOWAIT, taskqueue_thread_enqueue,
  555                                                  &hdl->deferred_tq);
  556         taskqueue_start_threads(&hdl->deferred_tq, 1, PI_NET, "irdma_defer_t");
  557 
  558         taskqueue_enqueue(hdl->deferred_tq, &hdl->deferred_task);
  559 
  560         return 0;
  561 
  562 err_ctrl_init:
  563         irdma_del_handler(hdl);
  564         irdma_dealloc_pcidev(rf);
  565 err_pcidev:
  566         kfree(iwdev->rf);
  567         ib_dealloc_device(&iwdev->ibdev);
  568         kfree(hdl);
  569 
  570         return err;
  571 }
  572 
  573 /**
  574  * irdma_remove - Callback to remove an RDMA peer device
  575  * @peer: the new peer interface structure
  576  *
  577  * Callback implementing the RDMA_REMOVE function. Called by the ice driver to
  578  * notify the RDMA client driver that the device wille be delated
  579  */
  580 static int
  581 irdma_remove(struct ice_rdma_peer *peer)
  582 {
  583         struct irdma_handler *hdl;
  584         struct irdma_device *iwdev;
  585 
  586         irdma_debug((struct irdma_sc_dev *)NULL, IRDMA_DEBUG_INIT, "removing %s\n", __FUNCTION__);
  587 
  588         hdl = irdma_find_handler(peer);
  589         if (!hdl)
  590                 return 0;
  591 
  592         iwdev = hdl->iwdev;
  593 
  594         if (iwdev->vsi.tc_change_pending) {
  595                 iwdev->vsi.tc_change_pending = false;
  596                 irdma_sc_suspend_resume_qps(&iwdev->vsi, IRDMA_OP_RESUME);
  597         }
  598 
  599         taskqueue_enqueue(hdl->deferred_tq, &hdl->deferred_task);
  600 
  601         taskqueue_drain(hdl->deferred_tq, &hdl->deferred_task);
  602         taskqueue_free(hdl->deferred_tq);
  603         hdl->iwdev->rf->dev_ctx.task_arg.iwdev = NULL;
  604         hdl->iwdev->rf->dev_ctx.task_arg.peer = NULL;
  605 
  606         sysctl_ctx_free(&iwdev->rf->tun_info.irdma_sysctl_ctx);
  607         hdl->iwdev->rf->tun_info.irdma_sysctl_tree = NULL;
  608 
  609         irdma_ctrl_deinit_hw(iwdev->rf);
  610 
  611         irdma_dealloc_pcidev(iwdev->rf);
  612 
  613         irdma_del_handler(iwdev->hdl);
  614         kfree(iwdev->hdl);
  615         kfree(iwdev->rf);
  616         ib_dealloc_device(&iwdev->ibdev);
  617         irdma_pr_info("IRDMA hardware deinitialization complete\n");
  618 
  619         return 0;
  620 }
  621 
  622 /**
  623  * irdma_prep_for_unregister - ensure the driver is ready to unregister
  624  */
  625 static void
  626 irdma_prep_for_unregister(void)
  627 {
  628         struct irdma_handler *hdl;
  629         unsigned long flags;
  630         bool hdl_valid;
  631 
  632         do {
  633                 hdl_valid = false;
  634                 spin_lock_irqsave(&irdma_handler_lock, flags);
  635                 list_for_each_entry(hdl, &irdma_handlers, list) {
  636                         if (!hdl)
  637                                 continue;
  638                         if (!hdl->iwdev->rf->peer_info)
  639                                 continue;
  640                         hdl_valid = true;
  641                         break;
  642                 }
  643                 spin_unlock_irqrestore(&irdma_handler_lock, flags);
  644                 if (!hdl || !hdl_valid)
  645                         break;
  646                 IRDMA_CLOSE(hdl->iwdev->rf->peer_info);
  647                 IRDMA_REMOVE(hdl->iwdev->rf->peer_info);
  648         } while (1);
  649 }
  650 
  651 static kobj_method_t irdma_methods[] = {
  652         KOBJMETHOD(irdma_probe, irdma_probe),
  653             KOBJMETHOD(irdma_open, irdma_open),
  654             KOBJMETHOD(irdma_close, irdma_close),
  655             KOBJMETHOD(irdma_remove, irdma_remove),
  656             KOBJMETHOD(irdma_link_change, irdma_link_change),
  657             KOBJMETHOD(irdma_event_handler, irdma_event_handler),
  658             KOBJMETHOD_END
  659 };
  660 
  661 /* declare irdma_class which extends the ice_rdma_di class */
  662 DEFINE_CLASS_1(irdma, irdma_class, irdma_methods, sizeof(struct ice_rdma_peer), ice_rdma_di_class);
  663 
  664 static struct ice_rdma_info irdma_info = {
  665         .major_version = ICE_RDMA_MAJOR_VERSION,
  666         .minor_version = ICE_RDMA_MINOR_VERSION,
  667         .patch_version = ICE_RDMA_PATCH_VERSION,
  668         .rdma_class = &irdma_class,
  669 };
  670 
  671 /**
  672  * irdma_module_event_handler - Module event handler callback
  673  * @mod: unused mod argument
  674  * @what: the module event to handle
  675  * @arg: unused module event argument
  676  *
  677  * Callback used by the FreeBSD module stack to notify the driver of module
  678  * events. Used to implement custom handling for certain module events such as
  679  * load and unload.
  680  */
  681 static int
  682 irdma_module_event_handler(module_t __unused mod, int what, void __unused * arg)
  683 {
  684         switch (what) {
  685         case MOD_LOAD:
  686                 printf("Loading irdma module\n");
  687                 return ice_rdma_register(&irdma_info);
  688         case MOD_UNLOAD:
  689                 printf("Unloading irdma module\n");
  690                 irdma_prep_for_unregister();
  691                 ice_rdma_unregister();
  692                 return (0);
  693         default:
  694                 return (EOPNOTSUPP);
  695         }
  696 
  697         return (0);
  698 }
  699 
  700 static moduledata_t irdma_moduledata = {
  701         "irdma",
  702             irdma_module_event_handler,
  703             NULL
  704 };
  705 
  706 DECLARE_MODULE(irdma, irdma_moduledata, SI_SUB_LAST, SI_ORDER_ANY);
  707 MODULE_VERSION(irdma, 1);
  708 MODULE_DEPEND(irdma, ice, 1, 1, 1);
  709 MODULE_DEPEND(irdma, ibcore, 1, 1, 1);

Cache object: 129330a15efdb746f9604acfb2226a14


[ 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.