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/ofed/drivers/infiniband/ulp/ipoib/ipoib_verbs.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: BSD-2-Clause OR GPL-2.0
    3  *
    4  * Copyright (c) 2004, 2005 Topspin Communications.  All rights reserved.
    5  * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
    6  *
    7  * This software is available to you under a choice of one of two
    8  * licenses.  You may choose to be licensed under the terms of the GNU
    9  * General Public License (GPL) Version 2, available from the file
   10  * COPYING in the main directory of this source tree, or the
   11  * OpenIB.org BSD license below:
   12  *
   13  *     Redistribution and use in source and binary forms, with or
   14  *     without modification, are permitted provided that the following
   15  *     conditions are met:
   16  *
   17  *      - Redistributions of source code must retain the above
   18  *        copyright notice, this list of conditions and the following
   19  *        disclaimer.
   20  *
   21  *      - Redistributions in binary form must reproduce the above
   22  *        copyright notice, this list of conditions and the following
   23  *        disclaimer in the documentation and/or other materials
   24  *        provided with the distribution.
   25  *
   26  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
   27  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   28  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
   29  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
   30  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
   31  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
   32  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
   33  * SOFTWARE.
   34  */
   35 
   36 #include <sys/cdefs.h>
   37 __FBSDID("$FreeBSD$");
   38 
   39 #include "ipoib.h"
   40 
   41 int ipoib_mcast_attach(struct ipoib_dev_priv *priv, u16 mlid, union ib_gid *mgid, int set_qkey)
   42 {
   43         struct ib_qp_attr *qp_attr = NULL;
   44         int ret;
   45         u16 pkey_index;
   46 
   47         if (ib_find_pkey(priv->ca, priv->port, priv->pkey, &pkey_index)) {
   48                 clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags);
   49                 ret = -ENXIO;
   50                 goto out;
   51         }
   52         set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags);
   53 
   54         if (set_qkey) {
   55                 ret = -ENOMEM;
   56                 qp_attr = kmalloc(sizeof *qp_attr, GFP_KERNEL);
   57                 if (!qp_attr)
   58                         goto out;
   59 
   60                 /* set correct QKey for QP */
   61                 qp_attr->qkey = priv->qkey;
   62                 ret = ib_modify_qp(priv->qp, qp_attr, IB_QP_QKEY);
   63                 if (ret) {
   64                         ipoib_warn(priv, "failed to modify QP, ret = %d\n", ret);
   65                         goto out;
   66                 }
   67         }
   68 
   69         /* attach QP to multicast group */
   70         ret = ib_attach_mcast(priv->qp, mgid, mlid);
   71         if (ret)
   72                 ipoib_warn(priv, "failed to attach to multicast group, ret = %d\n", ret);
   73 
   74 out:
   75         kfree(qp_attr);
   76         return ret;
   77 }
   78 
   79 int ipoib_init_qp(struct ipoib_dev_priv *priv)
   80 {
   81         int ret;
   82         struct ib_qp_attr qp_attr;
   83         int attr_mask;
   84 
   85         if (!test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags))
   86                 return -1;
   87 
   88         qp_attr.qp_state = IB_QPS_INIT;
   89         qp_attr.qkey = 0;
   90         qp_attr.port_num = priv->port;
   91         qp_attr.pkey_index = priv->pkey_index;
   92         attr_mask =
   93             IB_QP_QKEY |
   94             IB_QP_PORT |
   95             IB_QP_PKEY_INDEX |
   96             IB_QP_STATE;
   97 
   98         ret = ib_modify_qp(priv->qp, &qp_attr, attr_mask);
   99         if (ret) {
  100                 ipoib_warn(priv, "failed to modify QP to init, ret = %d\n", ret);
  101                 goto out_fail;
  102         }
  103 
  104         qp_attr.qp_state = IB_QPS_RTR;
  105         /* Can't set this in a INIT->RTR transition */
  106         attr_mask &= ~IB_QP_PORT;
  107         ret = ib_modify_qp(priv->qp, &qp_attr, attr_mask);
  108         if (ret) {
  109                 ipoib_warn(priv, "failed to modify QP to RTR, ret = %d\n", ret);
  110                 goto out_fail;
  111         }
  112 
  113         qp_attr.qp_state = IB_QPS_RTS;
  114         qp_attr.sq_psn = 0;
  115         attr_mask |= IB_QP_SQ_PSN;
  116         attr_mask &= ~IB_QP_PKEY_INDEX;
  117         ret = ib_modify_qp(priv->qp, &qp_attr, attr_mask);
  118         if (ret) {
  119                 ipoib_warn(priv, "failed to modify QP to RTS, ret = %d\n", ret);
  120                 goto out_fail;
  121         }
  122 
  123         return 0;
  124 
  125 out_fail:
  126         qp_attr.qp_state = IB_QPS_RESET;
  127         if (ib_modify_qp(priv->qp, &qp_attr, IB_QP_STATE))
  128                 ipoib_warn(priv, "Failed to modify QP to RESET state\n");
  129 
  130         return ret;
  131 }
  132 
  133 int ipoib_transport_dev_init(struct ipoib_dev_priv *priv, struct ib_device *ca)
  134 {
  135         struct ib_qp_init_attr init_attr = {
  136                 .cap = {
  137                         .max_send_wr  = ipoib_sendq_size,
  138                         .max_recv_wr  = ipoib_recvq_size,
  139                         .max_send_sge = 1,
  140                         .max_recv_sge = IPOIB_UD_RX_SG
  141                 },
  142                 .sq_sig_type = IB_SIGNAL_ALL_WR,
  143                 .qp_type     = IB_QPT_UD
  144         };
  145         struct ib_cq_init_attr cq_attr = {};
  146 
  147         int ret, size;
  148         int i;
  149         /* XXX struct ethtool_coalesce *coal; */
  150 
  151         priv->pd = ib_alloc_pd(priv->ca, 0);
  152         if (IS_ERR(priv->pd)) {
  153                 printk(KERN_WARNING "%s: failed to allocate PD\n", ca->name);
  154                 return -ENODEV;
  155         }
  156 
  157         size = ipoib_recvq_size + 1;
  158         ret = ipoib_cm_dev_init(priv);
  159         if (!ret) {
  160                 size += ipoib_sendq_size;
  161                 if (ipoib_cm_has_srq(priv))
  162                         size += ipoib_recvq_size + 1; /* 1 extra for rx_drain_qp */
  163                 else
  164                         size += ipoib_recvq_size * ipoib_max_conn_qp;
  165         }
  166 
  167         cq_attr.cqe = size;
  168         priv->recv_cq = ib_create_cq(priv->ca, ipoib_ib_completion, NULL, priv, &cq_attr);
  169         if (IS_ERR(priv->recv_cq)) {
  170                 printk(KERN_WARNING "%s: failed to create receive CQ\n", ca->name);
  171                 goto out_free_mr;
  172         }
  173 
  174         cq_attr.cqe = ipoib_sendq_size;
  175         priv->send_cq = ib_create_cq(priv->ca, ipoib_send_comp_handler, NULL,
  176                                      priv, &cq_attr);
  177         if (IS_ERR(priv->send_cq)) {
  178                 printk(KERN_WARNING "%s: failed to create send CQ\n", ca->name);
  179                 goto out_free_recv_cq;
  180         }
  181 
  182         if (ib_req_notify_cq(priv->recv_cq, IB_CQ_NEXT_COMP))
  183                 goto out_free_send_cq;
  184 
  185 #if 0
  186         /* XXX */
  187         coal = kzalloc(sizeof *coal, GFP_KERNEL);
  188         if (coal) {
  189                 coal->rx_coalesce_usecs = 10;
  190                 coal->tx_coalesce_usecs = 10;
  191                 coal->rx_max_coalesced_frames = 16;
  192                 coal->tx_max_coalesced_frames = 16;
  193                 dev->ethtool_ops->set_coalesce(dev, coal);
  194                 kfree(coal);
  195         }
  196 #endif
  197 
  198         init_attr.send_cq = priv->send_cq;
  199         init_attr.recv_cq = priv->recv_cq;
  200 
  201         if (priv->hca_caps & IB_DEVICE_UD_TSO)
  202                 init_attr.create_flags |= IB_QP_CREATE_IPOIB_UD_LSO;
  203 
  204         if (priv->hca_caps & IB_DEVICE_BLOCK_MULTICAST_LOOPBACK)
  205                 init_attr.create_flags |= IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK;
  206 
  207         init_attr.cap.max_send_sge = IPOIB_UD_TX_SG;
  208 
  209         priv->qp = ib_create_qp(priv->pd, &init_attr);
  210         if (IS_ERR(priv->qp)) {
  211                 printk(KERN_WARNING "%s: failed to create QP\n", ca->name);
  212                 goto out_free_send_cq;
  213         }
  214 
  215         IF_LLADDR(priv->dev)[1] = (priv->qp->qp_num >> 16) & 0xff;
  216         IF_LLADDR(priv->dev)[2] = (priv->qp->qp_num >>  8) & 0xff;
  217         IF_LLADDR(priv->dev)[3] = (priv->qp->qp_num      ) & 0xff;
  218 
  219         for (i = 0; i < IPOIB_MAX_TX_SG; ++i)
  220                 priv->tx_sge[i].lkey = priv->pd->local_dma_lkey;
  221 
  222         priv->tx_wr.wr.opcode           = IB_WR_SEND;
  223         priv->tx_wr.wr.sg_list          = priv->tx_sge;
  224         priv->tx_wr.wr.send_flags       = IB_SEND_SIGNALED;
  225 
  226         for (i = 0; i < IPOIB_UD_RX_SG; ++i)
  227                 priv->rx_sge[i].lkey = priv->pd->local_dma_lkey;
  228         priv->rx_wr.next = NULL;
  229         priv->rx_wr.sg_list = priv->rx_sge;
  230 
  231         return 0;
  232 
  233 out_free_send_cq:
  234         ib_destroy_cq(priv->send_cq);
  235 
  236 out_free_recv_cq:
  237         ib_destroy_cq(priv->recv_cq);
  238 
  239 out_free_mr:
  240         ipoib_cm_dev_cleanup(priv);
  241 
  242         ib_dealloc_pd(priv->pd);
  243         return -ENODEV;
  244 }
  245 
  246 void ipoib_transport_dev_cleanup(struct ipoib_dev_priv *priv)
  247 {
  248 
  249         if (priv->qp) {
  250                 if (ib_destroy_qp(priv->qp))
  251                         ipoib_warn(priv, "ib_qp_destroy failed\n");
  252 
  253                 priv->qp = NULL;
  254                 clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags);
  255         }
  256 
  257         ib_destroy_cq(priv->send_cq);
  258 
  259         ib_destroy_cq(priv->recv_cq);
  260 
  261         ipoib_cm_dev_cleanup(priv);
  262 
  263         ib_dealloc_pd(priv->pd);
  264 }
  265 
  266 void ipoib_event(struct ib_event_handler *handler,
  267                  struct ib_event *record)
  268 {
  269         struct ipoib_dev_priv *priv =
  270                 container_of(handler, struct ipoib_dev_priv, event_handler);
  271 
  272         if (record->element.port_num != priv->port)
  273                 return;
  274 
  275         ipoib_dbg(priv, "Event %d on device %s port %d\n", record->event,
  276                   record->device->name, record->element.port_num);
  277 
  278         if (record->event == IB_EVENT_SM_CHANGE ||
  279             record->event == IB_EVENT_CLIENT_REREGISTER) {
  280                 queue_work(ipoib_workqueue, &priv->flush_light);
  281         } else if (record->event == IB_EVENT_PORT_ERR ||
  282                    record->event == IB_EVENT_PORT_ACTIVE ||
  283                    record->event == IB_EVENT_LID_CHANGE ||
  284                    record->event == IB_EVENT_DEVICE_FATAL) {
  285                 queue_work(ipoib_workqueue, &priv->flush_normal);
  286         } else if (record->event == IB_EVENT_PKEY_CHANGE) {
  287                 queue_work(ipoib_workqueue, &priv->flush_heavy);
  288         }
  289 }

Cache object: 0e09a71dc98ce92611135fc96ac7e758


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