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/mlx4/mlx4_en/mlx4_en_cq.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  * Copyright (c) 2007, 2014 Mellanox Technologies. All rights reserved.
    3  *
    4  * This software is available to you under a choice of one of two
    5  * licenses.  You may choose to be licensed under the terms of the GNU
    6  * General Public License (GPL) Version 2, available from the file
    7  * COPYING in the main directory of this source tree, or the
    8  * OpenIB.org BSD license below:
    9  *
   10  *     Redistribution and use in source and binary forms, with or
   11  *     without modification, are permitted provided that the following
   12  *     conditions are met:
   13  *
   14  *      - Redistributions of source code must retain the above
   15  *        copyright notice, this list of conditions and the following
   16  *        disclaimer.
   17  *
   18  *      - Redistributions in binary form must reproduce the above
   19  *        copyright notice, this list of conditions and the following
   20  *        disclaimer in the documentation and/or other materials
   21  *        provided with the distribution.
   22  *
   23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
   24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
   26  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
   27  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
   28  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
   29  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
   30  * SOFTWARE.
   31  *
   32  */
   33 
   34 #include <linux/rcupdate.h>
   35 
   36 #include <dev/mlx4/cq.h>
   37 #include <dev/mlx4/qp.h>
   38 #include <dev/mlx4/cmd.h>
   39 
   40 #include "en.h"
   41 
   42 static void mlx4_en_cq_event(struct mlx4_cq *cq, enum mlx4_event event)
   43 {
   44         return;
   45 }
   46 
   47 static void mlx4_en_tx_que(void *arg, int pending)
   48 {
   49 
   50 }
   51 
   52 int mlx4_en_create_cq(struct mlx4_en_priv *priv,
   53                       struct mlx4_en_cq **pcq,
   54                       int entries, int ring, enum cq_type mode,
   55                       int node)
   56 {
   57         struct mlx4_en_dev *mdev = priv->mdev;
   58         struct mlx4_en_cq *cq;
   59         int err;
   60 
   61         cq = kzalloc_node(sizeof(*cq), GFP_KERNEL, node);
   62         if (!cq) {
   63                 cq = kzalloc(sizeof(*cq), GFP_KERNEL);
   64                 if (!cq) {
   65                         en_err(priv, "Failed to allocate CQ structure\n");
   66                         return -ENOMEM;
   67                 }
   68         }
   69 
   70         cq->size = entries;
   71         cq->buf_size = cq->size * mdev->dev->caps.cqe_size;
   72 
   73         cq->tq = taskqueue_create_fast("mlx4_en_que", M_NOWAIT,
   74                         taskqueue_thread_enqueue, &cq->tq);
   75         if (mode == RX) {
   76                 TASK_INIT(&cq->cq_task, 0, mlx4_en_rx_que, cq);
   77                 taskqueue_start_threads(&cq->tq, 1, PI_NET, "%s rx cq",
   78                                 if_name(priv->dev));
   79 
   80         } else {
   81                 TASK_INIT(&cq->cq_task, 0, mlx4_en_tx_que, cq);
   82                 taskqueue_start_threads(&cq->tq, 1, PI_NET, "%s tx cq",
   83                                 if_name(priv->dev));
   84         }
   85 
   86         cq->ring = ring;
   87         cq->is_tx = mode;
   88         cq->vector = mdev->dev->caps.num_comp_vectors;
   89         spin_lock_init(&cq->lock);
   90 
   91         err = mlx4_alloc_hwq_res(mdev->dev, &cq->wqres,
   92                                 cq->buf_size, 2 * PAGE_SIZE);
   93         if (err)
   94                 goto err_cq;
   95 
   96         err = mlx4_en_map_buffer(&cq->wqres.buf);
   97         if (err)
   98                 goto err_res;
   99 
  100         cq->buf = (struct mlx4_cqe *)cq->wqres.buf.direct.buf;
  101         *pcq = cq;
  102 
  103         return 0;
  104 
  105 err_res:
  106         mlx4_free_hwq_res(mdev->dev, &cq->wqres, cq->buf_size);
  107 err_cq:
  108         kfree(cq);
  109         *pcq = NULL;
  110         return err;
  111 }
  112 
  113 int mlx4_en_activate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq,
  114                         int cq_idx)
  115 {
  116         struct mlx4_en_dev *mdev = priv->mdev;
  117         int err = 0;
  118         int timestamp_en = 0;
  119         bool assigned_eq = false;
  120 
  121         cq->dev = mdev->pndev[priv->port];
  122         cq->mcq.set_ci_db  = cq->wqres.db.db;
  123         cq->mcq.arm_db     = cq->wqres.db.db + 1;
  124         *cq->mcq.set_ci_db = 0;
  125         *cq->mcq.arm_db    = 0;
  126         memset(cq->buf, 0, cq->buf_size);
  127 
  128         if (cq->is_tx == RX) {
  129                 if (!mlx4_is_eq_vector_valid(mdev->dev, priv->port,
  130                                              cq->vector)) {
  131                         cq->vector = cq_idx % mdev->dev->caps.num_comp_vectors;
  132 
  133                         err = mlx4_assign_eq(mdev->dev, priv->port,
  134                                              &cq->vector);
  135                         if (err) {
  136                                 mlx4_err(mdev, "Failed assigning an EQ to CQ vector %d\n",
  137                                          cq->vector);
  138                                 goto free_eq;
  139                         }
  140 
  141                         assigned_eq = true;
  142                 }
  143         } else {
  144                 struct mlx4_en_cq *rx_cq;
  145                 /*
  146                  * For TX we use the same irq per
  147                  * ring we assigned for the RX
  148                  */
  149                 cq_idx = cq_idx % priv->rx_ring_num;
  150                 rx_cq = priv->rx_cq[cq_idx];
  151                 cq->vector = rx_cq->vector;
  152         }
  153 
  154         if (!cq->is_tx)
  155                 cq->size = priv->rx_ring[cq->ring]->actual_size;
  156 
  157         err = mlx4_cq_alloc(mdev->dev, cq->size, &cq->wqres.mtt,
  158                             &mdev->priv_uar, cq->wqres.db.dma, &cq->mcq,
  159                             cq->vector, 0, timestamp_en);
  160         if (err)
  161                 goto free_eq;
  162 
  163         cq->mcq.comp  = cq->is_tx ? mlx4_en_tx_irq : mlx4_en_rx_irq;
  164         cq->mcq.event = mlx4_en_cq_event;
  165 
  166         if (cq->is_tx) {
  167                 init_timer(&cq->timer);
  168                 cq->timer.function = mlx4_en_poll_tx_cq;
  169                 cq->timer.data = (unsigned long) cq;
  170         }
  171 
  172 
  173         return 0;
  174 
  175 free_eq:
  176         if (assigned_eq)
  177                 mlx4_release_eq(mdev->dev, cq->vector);
  178         cq->vector = mdev->dev->caps.num_comp_vectors;
  179         return err;
  180 }
  181 
  182 void mlx4_en_destroy_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq **pcq)
  183 {
  184         struct mlx4_en_dev *mdev = priv->mdev;
  185         struct mlx4_en_cq *cq = *pcq;
  186 
  187         taskqueue_drain(cq->tq, &cq->cq_task);
  188         taskqueue_free(cq->tq);
  189         mlx4_en_unmap_buffer(&cq->wqres.buf);
  190         mlx4_free_hwq_res(mdev->dev, &cq->wqres, cq->buf_size);
  191         if (mlx4_is_eq_vector_valid(mdev->dev, priv->port, cq->vector) &&
  192             cq->is_tx == RX)
  193                 mlx4_release_eq(priv->mdev->dev, cq->vector);
  194         cq->vector = 0;
  195         cq->buf_size = 0;
  196         cq->buf = NULL;
  197         kfree(cq);
  198         *pcq = NULL;
  199 }
  200 
  201 void mlx4_en_deactivate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq)
  202 {
  203         taskqueue_drain(cq->tq, &cq->cq_task);
  204         if (!cq->is_tx) {
  205                 synchronize_rcu();
  206         } else {
  207                 del_timer_sync(&cq->timer);
  208         }
  209 
  210         mlx4_cq_free(priv->mdev->dev, &cq->mcq);
  211 }
  212 
  213 /* Set rx cq moderation parameters */
  214 int mlx4_en_set_cq_moder(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq)
  215 {
  216         return mlx4_cq_modify(priv->mdev->dev, &cq->mcq,
  217                               cq->moder_cnt, cq->moder_time);
  218 }
  219 
  220 int mlx4_en_arm_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq)
  221 {
  222         mlx4_cq_arm(&cq->mcq, MLX4_CQ_DB_REQ_NOT, priv->mdev->uar_map,
  223                     &priv->mdev->uar_lock);
  224 
  225         return 0;
  226 }
  227 
  228 

Cache object: 214a900416f39147b627d8fbdb445f97


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