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
mlx5_wq_cyc_ctr2ix(struct mlx5_wq_cyc * wq,u16 ctr)96 static inline u16 mlx5_wq_cyc_ctr2ix(struct mlx5_wq_cyc *wq, u16 ctr)
97 {
98 return ctr & wq->sz_m1;
99 }
100
mlx5_wq_cyc_get_wqe(struct mlx5_wq_cyc * wq,u16 ix)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
mlx5_wq_cyc_cc_bigger(u16 cc1,u16 cc2)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
mlx5_cqwq_get_ci(struct mlx5_cqwq * wq)114 static inline u32 mlx5_cqwq_get_ci(struct mlx5_cqwq *wq)
115 {
116 return wq->cc & wq->sz_m1;
117 }
118
mlx5_cqwq_get_wqe(struct mlx5_cqwq * wq,u32 ix)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
mlx5_cqwq_get_wrap_cnt(struct mlx5_cqwq * wq)124 static inline u32 mlx5_cqwq_get_wrap_cnt(struct mlx5_cqwq *wq)
125 {
126 return wq->cc >> wq->log_sz;
127 }
128
mlx5_cqwq_pop(struct mlx5_cqwq * wq)129 static inline void mlx5_cqwq_pop(struct mlx5_cqwq *wq)
130 {
131 wq->cc++;
132 }
133
mlx5_cqwq_update_db_record(struct mlx5_cqwq * wq)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
mlx5_wq_ll_is_full(struct mlx5_wq_ll * wq)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
mlx5_wq_ll_is_empty(struct mlx5_wq_ll * wq)144 static inline int mlx5_wq_ll_is_empty(struct mlx5_wq_ll *wq)
145 {
146 return !wq->cur_sz;
147 }
148
mlx5_wq_ll_push(struct mlx5_wq_ll * wq,u16 head_next)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
mlx5_wq_ll_pop(struct mlx5_wq_ll * wq,__be16 ix,__be16 * next_tail_next)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 }
mlx5_wq_ll_update_db_record(struct mlx5_wq_ll * wq)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
mlx5_wq_ll_get_wqe(struct mlx5_wq_ll * wq,u16 ix)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