1 /*- 2 * Copyright (c) 2013-2017, 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_frag_wq_ctrl { 46 struct mlx5_core_dev *mdev; 47 struct mlx5_frag_buf frag_buf; 48 struct mlx5_db db; 49 }; 50 51 struct mlx5_wq_cyc { 52 void *buf; 53 __be32 *db; 54 u16 sz_m1; 55 u8 log_stride; 56 }; 57 58 struct mlx5_wq_qp { 59 struct mlx5_wq_cyc rq; 60 struct mlx5_wq_cyc sq; 61 }; 62 63 struct mlx5_cqwq { 64 void *buf; 65 __be32 *db; 66 u32 sz_m1; 67 u32 cc; /* consumer counter */ 68 u8 log_sz; 69 u8 log_stride; 70 }; 71 72 struct mlx5_wq_ll { 73 void *buf; 74 __be32 *db; 75 __be16 *tail_next; 76 u16 sz_m1; 77 u16 head; 78 u16 wqe_ctr; 79 u16 cur_sz; 80 u8 log_stride; 81 }; 82 83 int mlx5_wq_cyc_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param, 84 void *wqc, struct mlx5_wq_cyc *wq, 85 struct mlx5_wq_ctrl *wq_ctrl); 86 u32 mlx5_wq_cyc_get_size(struct mlx5_wq_cyc *wq); 87 88 int mlx5_cqwq_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param, 89 void *cqc, struct mlx5_cqwq *wq, 90 struct mlx5_wq_ctrl *wq_ctrl); 91 u32 mlx5_cqwq_get_size(struct mlx5_cqwq *wq); 92 93 int mlx5_wq_ll_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param, 94 void *wqc, struct mlx5_wq_ll *wq, 95 struct mlx5_wq_ctrl *wq_ctrl); 96 u32 mlx5_wq_ll_get_size(struct mlx5_wq_ll *wq); 97 98 void mlx5_wq_destroy(struct mlx5_wq_ctrl *wq_ctrl); 99 100 static inline u16 mlx5_wq_cyc_ctr2ix(struct mlx5_wq_cyc *wq, u16 ctr) 101 { 102 return ctr & wq->sz_m1; 103 } 104 105 static inline void *mlx5_wq_cyc_get_wqe(struct mlx5_wq_cyc *wq, u16 ix) 106 { 107 return wq->buf + (ix << wq->log_stride); 108 } 109 110 static inline int mlx5_wq_cyc_cc_bigger(u16 cc1, u16 cc2) 111 { 112 int equal = (cc1 == cc2); 113 int smaller = 0x8000 & (cc1 - cc2); 114 115 return !equal && !smaller; 116 } 117 118 static inline u32 mlx5_cqwq_get_ci(struct mlx5_cqwq *wq) 119 { 120 return wq->cc & wq->sz_m1; 121 } 122 123 static inline void *mlx5_cqwq_get_wqe(struct mlx5_cqwq *wq, u32 ix) 124 { 125 return wq->buf + (ix << wq->log_stride); 126 } 127 128 static inline u32 mlx5_cqwq_get_wrap_cnt(struct mlx5_cqwq *wq) 129 { 130 return wq->cc >> wq->log_sz; 131 } 132 133 static inline void mlx5_cqwq_pop(struct mlx5_cqwq *wq) 134 { 135 wq->cc++; 136 } 137 138 static inline void mlx5_cqwq_update_db_record(struct mlx5_cqwq *wq) 139 { 140 *wq->db = cpu_to_be32(wq->cc & 0xffffff); 141 } 142 143 static inline int mlx5_wq_ll_is_full(struct mlx5_wq_ll *wq) 144 { 145 return wq->cur_sz == wq->sz_m1; 146 } 147 148 static inline int mlx5_wq_ll_is_empty(struct mlx5_wq_ll *wq) 149 { 150 return !wq->cur_sz; 151 } 152 153 static inline void mlx5_wq_ll_push(struct mlx5_wq_ll *wq, u16 head_next) 154 { 155 wq->head = head_next; 156 wq->wqe_ctr++; 157 wq->cur_sz++; 158 } 159 160 static inline void mlx5_wq_ll_pop(struct mlx5_wq_ll *wq, __be16 ix, 161 __be16 *next_tail_next) 162 { 163 *wq->tail_next = ix; 164 wq->tail_next = next_tail_next; 165 wq->cur_sz--; 166 } 167 static inline void mlx5_wq_ll_update_db_record(struct mlx5_wq_ll *wq) 168 { 169 *wq->db = cpu_to_be32(wq->wqe_ctr); 170 } 171 172 static inline void *mlx5_wq_ll_get_wqe(struct mlx5_wq_ll *wq, u16 ix) 173 { 174 return wq->buf + (ix << wq->log_stride); 175 } 176 177 #endif /* __MLX5_WQ_H__ */ 178