linux/drivers/net/ethernet/mellanox/mlx5/core/wq.h
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2013-2015, Mellanox Technologies, Ltd.  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#ifndef __MLX5_WQ_H__
  34#define __MLX5_WQ_H__
  35
  36#include <linux/mlx5/mlx5_ifc.h>
  37#include <linux/mlx5/cq.h>
  38#include <linux/mlx5/qp.h>
  39
  40struct mlx5_wq_param {
  41        int             linear;
  42        int             buf_numa_node;
  43        int             db_numa_node;
  44};
  45
  46struct mlx5_wq_ctrl {
  47        struct mlx5_core_dev    *mdev;
  48        struct mlx5_buf         buf;
  49        struct mlx5_db          db;
  50};
  51
  52struct mlx5_frag_wq_ctrl {
  53        struct mlx5_core_dev    *mdev;
  54        struct mlx5_frag_buf    frag_buf;
  55        struct mlx5_db          db;
  56};
  57
  58struct mlx5_wq_cyc {
  59        void                    *buf;
  60        __be32                  *db;
  61        u16                     sz_m1;
  62        u8                      log_stride;
  63};
  64
  65struct mlx5_wq_qp {
  66        struct mlx5_wq_cyc      rq;
  67        struct mlx5_wq_cyc      sq;
  68};
  69
  70struct mlx5_cqwq {
  71        struct mlx5_frag_buf    frag_buf;
  72        __be32                  *db;
  73        u32                     sz_m1;
  74        u32                     frag_sz_m1;
  75        u32                     cc; /* consumer counter */
  76        u8                      log_sz;
  77        u8                      log_stride;
  78        u8                      log_frag_strides;
  79};
  80
  81struct mlx5_wq_ll {
  82        void                    *buf;
  83        __be32                  *db;
  84        __be16                  *tail_next;
  85        u16                     sz_m1;
  86        u16                     head;
  87        u16                     wqe_ctr;
  88        u16                     cur_sz;
  89        u8                      log_stride;
  90};
  91
  92int mlx5_wq_cyc_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param,
  93                       void *wqc, struct mlx5_wq_cyc *wq,
  94                       struct mlx5_wq_ctrl *wq_ctrl);
  95u32 mlx5_wq_cyc_get_size(struct mlx5_wq_cyc *wq);
  96
  97int mlx5_wq_qp_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param,
  98                      void *qpc, struct mlx5_wq_qp *wq,
  99                      struct mlx5_wq_ctrl *wq_ctrl);
 100
 101int mlx5_cqwq_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param,
 102                     void *cqc, struct mlx5_cqwq *wq,
 103                     struct mlx5_frag_wq_ctrl *wq_ctrl);
 104u32 mlx5_cqwq_get_size(struct mlx5_cqwq *wq);
 105
 106int mlx5_wq_ll_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param,
 107                      void *wqc, struct mlx5_wq_ll *wq,
 108                      struct mlx5_wq_ctrl *wq_ctrl);
 109u32 mlx5_wq_ll_get_size(struct mlx5_wq_ll *wq);
 110
 111void mlx5_wq_destroy(struct mlx5_wq_ctrl *wq_ctrl);
 112void mlx5_cqwq_destroy(struct mlx5_frag_wq_ctrl *wq_ctrl);
 113
 114static inline u16 mlx5_wq_cyc_ctr2ix(struct mlx5_wq_cyc *wq, u16 ctr)
 115{
 116        return ctr & wq->sz_m1;
 117}
 118
 119static inline void *mlx5_wq_cyc_get_wqe(struct mlx5_wq_cyc *wq, u16 ix)
 120{
 121        return wq->buf + (ix << wq->log_stride);
 122}
 123
 124static inline int mlx5_wq_cyc_cc_bigger(u16 cc1, u16 cc2)
 125{
 126        int equal   = (cc1 == cc2);
 127        int smaller = 0x8000 & (cc1 - cc2);
 128
 129        return !equal && !smaller;
 130}
 131
 132static inline u32 mlx5_cqwq_get_ci(struct mlx5_cqwq *wq)
 133{
 134        return wq->cc & wq->sz_m1;
 135}
 136
 137static inline void *mlx5_cqwq_get_wqe(struct mlx5_cqwq *wq, u32 ix)
 138{
 139        unsigned int frag = (ix >> wq->log_frag_strides);
 140
 141        return wq->frag_buf.frags[frag].buf +
 142                ((wq->frag_sz_m1 & ix) << wq->log_stride);
 143}
 144
 145static inline u32 mlx5_cqwq_get_wrap_cnt(struct mlx5_cqwq *wq)
 146{
 147        return wq->cc >> wq->log_sz;
 148}
 149
 150static inline void mlx5_cqwq_pop(struct mlx5_cqwq *wq)
 151{
 152        wq->cc++;
 153}
 154
 155static inline void mlx5_cqwq_update_db_record(struct mlx5_cqwq *wq)
 156{
 157        *wq->db = cpu_to_be32(wq->cc & 0xffffff);
 158}
 159
 160static inline struct mlx5_cqe64 *mlx5_cqwq_get_cqe(struct mlx5_cqwq *wq)
 161{
 162        u32 ci = mlx5_cqwq_get_ci(wq);
 163        struct mlx5_cqe64 *cqe = mlx5_cqwq_get_wqe(wq, ci);
 164        u8 cqe_ownership_bit = cqe->op_own & MLX5_CQE_OWNER_MASK;
 165        u8 sw_ownership_val = mlx5_cqwq_get_wrap_cnt(wq) & 1;
 166
 167        if (cqe_ownership_bit != sw_ownership_val)
 168                return NULL;
 169
 170        /* ensure cqe content is read after cqe ownership bit */
 171        dma_rmb();
 172
 173        return cqe;
 174}
 175
 176static inline int mlx5_wq_ll_is_full(struct mlx5_wq_ll *wq)
 177{
 178        return wq->cur_sz == wq->sz_m1;
 179}
 180
 181static inline int mlx5_wq_ll_is_empty(struct mlx5_wq_ll *wq)
 182{
 183        return !wq->cur_sz;
 184}
 185
 186static inline void *mlx5_wq_ll_get_wqe(struct mlx5_wq_ll *wq, u16 ix)
 187{
 188        return wq->buf + (ix << wq->log_stride);
 189}
 190
 191static inline void mlx5_wq_ll_push(struct mlx5_wq_ll *wq, u16 head_next)
 192{
 193        wq->head = head_next;
 194        wq->wqe_ctr++;
 195        wq->cur_sz++;
 196}
 197
 198static inline void mlx5_wq_ll_pop(struct mlx5_wq_ll *wq, __be16 ix,
 199                                  __be16 *next_tail_next)
 200{
 201        *wq->tail_next = ix;
 202        wq->tail_next = next_tail_next;
 203        wq->cur_sz--;
 204}
 205
 206static inline void mlx5_wq_ll_update_db_record(struct mlx5_wq_ll *wq)
 207{
 208        *wq->db = cpu_to_be32(wq->wqe_ctr);
 209}
 210
 211#endif /* __MLX5_WQ_H__ */
 212