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