1 /*- 2 * Copyright (c) 2013-2015, Mellanox Technologies, Ltd. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS `AS IS' AND 14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 * 25 * $FreeBSD$ 26 */ 27 28 #ifndef __MLX5_WQ_H__ 29 #define __MLX5_WQ_H__ 30 31 #include <dev/mlx5/mlx5_ifc.h> 32 33 struct mlx5_wq_param { 34 int linear; 35 int buf_numa_node; 36 int db_numa_node; 37 }; 38 39 struct mlx5_wq_ctrl { 40 struct mlx5_core_dev *mdev; 41 struct mlx5_buf buf; 42 struct mlx5_db db; 43 }; 44 45 struct mlx5_wq_cyc { 46 void *buf; 47 __be32 *db; 48 u16 sz_m1; 49 u8 log_stride; 50 }; 51 52 struct mlx5_cqwq { 53 void *buf; 54 __be32 *db; 55 u32 sz_m1; 56 u32 cc; /* consumer counter */ 57 u8 log_sz; 58 u8 log_stride; 59 }; 60 61 struct mlx5_wq_ll { 62 void *buf; 63 __be32 *db; 64 __be16 *tail_next; 65 u16 sz_m1; 66 u16 head; 67 u16 wqe_ctr; 68 u16 cur_sz; 69 u8 log_stride; 70 }; 71 72 int mlx5_wq_cyc_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param, 73 void *wqc, struct mlx5_wq_cyc *wq, 74 struct mlx5_wq_ctrl *wq_ctrl); 75 u32 mlx5_wq_cyc_get_size(struct mlx5_wq_cyc *wq); 76 77 int mlx5_cqwq_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param, 78 void *cqc, struct mlx5_cqwq *wq, 79 struct mlx5_wq_ctrl *wq_ctrl); 80 u32 mlx5_cqwq_get_size(struct mlx5_cqwq *wq); 81 82 int mlx5_wq_ll_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param, 83 void *wqc, struct mlx5_wq_ll *wq, 84 struct mlx5_wq_ctrl *wq_ctrl); 85 u32 mlx5_wq_ll_get_size(struct mlx5_wq_ll *wq); 86 87 void mlx5_wq_destroy(struct mlx5_wq_ctrl *wq_ctrl); 88 89 static inline u16 mlx5_wq_cyc_ctr2ix(struct mlx5_wq_cyc *wq, u16 ctr) 90 { 91 return ctr & wq->sz_m1; 92 } 93 94 static inline void *mlx5_wq_cyc_get_wqe(struct mlx5_wq_cyc *wq, u16 ix) 95 { 96 return wq->buf + (ix << wq->log_stride); 97 } 98 99 static inline int mlx5_wq_cyc_cc_bigger(u16 cc1, u16 cc2) 100 { 101 int equal = (cc1 == cc2); 102 int smaller = 0x8000 & (cc1 - cc2); 103 104 return !equal && !smaller; 105 } 106 107 static inline u32 mlx5_cqwq_get_ci(struct mlx5_cqwq *wq) 108 { 109 return wq->cc & wq->sz_m1; 110 } 111 112 static inline void *mlx5_cqwq_get_wqe(struct mlx5_cqwq *wq, u32 ix) 113 { 114 return wq->buf + (ix << wq->log_stride); 115 } 116 117 static inline u32 mlx5_cqwq_get_wrap_cnt(struct mlx5_cqwq *wq) 118 { 119 return wq->cc >> wq->log_sz; 120 } 121 122 static inline void mlx5_cqwq_pop(struct mlx5_cqwq *wq) 123 { 124 wq->cc++; 125 } 126 127 static inline void mlx5_cqwq_update_db_record(struct mlx5_cqwq *wq) 128 { 129 *wq->db = cpu_to_be32(wq->cc & 0xffffff); 130 } 131 132 static inline int mlx5_wq_ll_is_full(struct mlx5_wq_ll *wq) 133 { 134 return wq->cur_sz == wq->sz_m1; 135 } 136 137 static inline int mlx5_wq_ll_is_empty(struct mlx5_wq_ll *wq) 138 { 139 return !wq->cur_sz; 140 } 141 142 static inline void mlx5_wq_ll_push(struct mlx5_wq_ll *wq, u16 head_next) 143 { 144 wq->head = head_next; 145 wq->wqe_ctr++; 146 wq->cur_sz++; 147 } 148 149 static inline void mlx5_wq_ll_pop(struct mlx5_wq_ll *wq, __be16 ix, 150 __be16 *next_tail_next) 151 { 152 *wq->tail_next = ix; 153 wq->tail_next = next_tail_next; 154 wq->cur_sz--; 155 } 156 static inline void mlx5_wq_ll_update_db_record(struct mlx5_wq_ll *wq) 157 { 158 *wq->db = cpu_to_be32(wq->wqe_ctr); 159 } 160 161 static inline void *mlx5_wq_ll_get_wqe(struct mlx5_wq_ll *wq, u16 ix) 162 { 163 return wq->buf + (ix << wq->log_stride); 164 } 165 166 #endif /* __MLX5_WQ_H__ */ 167