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