• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2013-2015, Mellanox Technologies, Ltd.  All rights reserved.
3  *
4  * This software is available to you under a choice of one of two
5  * licenses.  You may choose to be licensed under the terms of the GNU
6  * General Public License (GPL) Version 2, available from the file
7  * COPYING in the main directory of this source tree, or the
8  * OpenIB.org BSD license below:
9  *
10  *     Redistribution and use in source and binary forms, with or
11  *     without modification, are permitted provided that the following
12  *     conditions are met:
13  *
14  *      - Redistributions of source code must retain the above
15  *        copyright notice, this list of conditions and the following
16  *        disclaimer.
17  *
18  *      - Redistributions in binary form must reproduce the above
19  *        copyright notice, this list of conditions and the following
20  *        disclaimer in the documentation and/or other materials
21  *        provided with the distribution.
22  *
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30  * SOFTWARE.
31  */
32 
33 #ifndef __MLX5_WQ_H__
34 #define __MLX5_WQ_H__
35 
36 #include <linux/mlx5/mlx5_ifc.h>
37 #include <linux/mlx5/cq.h>
38 #include <linux/mlx5/qp.h>
39 
40 struct mlx5_wq_param {
41 	int		linear;
42 	int		buf_numa_node;
43 	int		db_numa_node;
44 };
45 
46 struct mlx5_wq_ctrl {
47 	struct mlx5_core_dev	*mdev;
48 	struct mlx5_buf		buf;
49 	struct mlx5_db		db;
50 };
51 
52 struct mlx5_frag_wq_ctrl {
53 	struct mlx5_core_dev	*mdev;
54 	struct mlx5_frag_buf	frag_buf;
55 	struct mlx5_db		db;
56 };
57 
58 struct mlx5_wq_cyc {
59 	void			*buf;
60 	__be32			*db;
61 	u16			sz_m1;
62 	u8			log_stride;
63 };
64 
65 struct mlx5_wq_qp {
66 	struct mlx5_wq_cyc	rq;
67 	struct mlx5_wq_cyc	sq;
68 };
69 
70 struct mlx5_cqwq {
71 	struct mlx5_frag_buf	frag_buf;
72 	__be32			*db;
73 	u32			sz_m1;
74 	u32			frag_sz_m1;
75 	u32			cc; /* consumer counter */
76 	u8			log_sz;
77 	u8			log_stride;
78 	u8			log_frag_strides;
79 };
80 
81 struct mlx5_wq_ll {
82 	void			*buf;
83 	__be32			*db;
84 	__be16			*tail_next;
85 	u16			sz_m1;
86 	u16			head;
87 	u16			wqe_ctr;
88 	u16			cur_sz;
89 	u8			log_stride;
90 };
91 
92 int mlx5_wq_cyc_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param,
93 		       void *wqc, struct mlx5_wq_cyc *wq,
94 		       struct mlx5_wq_ctrl *wq_ctrl);
95 u32 mlx5_wq_cyc_get_size(struct mlx5_wq_cyc *wq);
96 
97 int mlx5_wq_qp_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param,
98 		      void *qpc, struct mlx5_wq_qp *wq,
99 		      struct mlx5_wq_ctrl *wq_ctrl);
100 
101 int mlx5_cqwq_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param,
102 		     void *cqc, struct mlx5_cqwq *wq,
103 		     struct mlx5_frag_wq_ctrl *wq_ctrl);
104 u32 mlx5_cqwq_get_size(struct mlx5_cqwq *wq);
105 
106 int mlx5_wq_ll_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param,
107 		      void *wqc, struct mlx5_wq_ll *wq,
108 		      struct mlx5_wq_ctrl *wq_ctrl);
109 u32 mlx5_wq_ll_get_size(struct mlx5_wq_ll *wq);
110 
111 void mlx5_wq_destroy(struct mlx5_wq_ctrl *wq_ctrl);
112 void mlx5_cqwq_destroy(struct mlx5_frag_wq_ctrl *wq_ctrl);
113 
mlx5_wq_cyc_ctr2ix(struct mlx5_wq_cyc * wq,u16 ctr)114 static inline u16 mlx5_wq_cyc_ctr2ix(struct mlx5_wq_cyc *wq, u16 ctr)
115 {
116 	return ctr & wq->sz_m1;
117 }
118 
mlx5_wq_cyc_get_wqe(struct mlx5_wq_cyc * wq,u16 ix)119 static inline void *mlx5_wq_cyc_get_wqe(struct mlx5_wq_cyc *wq, u16 ix)
120 {
121 	return wq->buf + (ix << wq->log_stride);
122 }
123 
mlx5_wq_cyc_cc_bigger(u16 cc1,u16 cc2)124 static inline int mlx5_wq_cyc_cc_bigger(u16 cc1, u16 cc2)
125 {
126 	int equal   = (cc1 == cc2);
127 	int smaller = 0x8000 & (cc1 - cc2);
128 
129 	return !equal && !smaller;
130 }
131 
mlx5_cqwq_get_ci(struct mlx5_cqwq * wq)132 static inline u32 mlx5_cqwq_get_ci(struct mlx5_cqwq *wq)
133 {
134 	return wq->cc & wq->sz_m1;
135 }
136 
mlx5_cqwq_get_wqe(struct mlx5_cqwq * wq,u32 ix)137 static inline void *mlx5_cqwq_get_wqe(struct mlx5_cqwq *wq, u32 ix)
138 {
139 	unsigned int frag = (ix >> wq->log_frag_strides);
140 
141 	return wq->frag_buf.frags[frag].buf +
142 		((wq->frag_sz_m1 & ix) << wq->log_stride);
143 }
144 
mlx5_cqwq_get_wrap_cnt(struct mlx5_cqwq * wq)145 static inline u32 mlx5_cqwq_get_wrap_cnt(struct mlx5_cqwq *wq)
146 {
147 	return wq->cc >> wq->log_sz;
148 }
149 
mlx5_cqwq_pop(struct mlx5_cqwq * wq)150 static inline void mlx5_cqwq_pop(struct mlx5_cqwq *wq)
151 {
152 	wq->cc++;
153 }
154 
mlx5_cqwq_update_db_record(struct mlx5_cqwq * wq)155 static inline void mlx5_cqwq_update_db_record(struct mlx5_cqwq *wq)
156 {
157 	*wq->db = cpu_to_be32(wq->cc & 0xffffff);
158 }
159 
mlx5_cqwq_get_cqe(struct mlx5_cqwq * wq)160 static inline struct mlx5_cqe64 *mlx5_cqwq_get_cqe(struct mlx5_cqwq *wq)
161 {
162 	u32 ci = mlx5_cqwq_get_ci(wq);
163 	struct mlx5_cqe64 *cqe = mlx5_cqwq_get_wqe(wq, ci);
164 	u8 cqe_ownership_bit = cqe->op_own & MLX5_CQE_OWNER_MASK;
165 	u8 sw_ownership_val = mlx5_cqwq_get_wrap_cnt(wq) & 1;
166 
167 	if (cqe_ownership_bit != sw_ownership_val)
168 		return NULL;
169 
170 	/* ensure cqe content is read after cqe ownership bit */
171 	dma_rmb();
172 
173 	return cqe;
174 }
175 
mlx5_wq_ll_is_full(struct mlx5_wq_ll * wq)176 static inline int mlx5_wq_ll_is_full(struct mlx5_wq_ll *wq)
177 {
178 	return wq->cur_sz == wq->sz_m1;
179 }
180 
mlx5_wq_ll_is_empty(struct mlx5_wq_ll * wq)181 static inline int mlx5_wq_ll_is_empty(struct mlx5_wq_ll *wq)
182 {
183 	return !wq->cur_sz;
184 }
185 
mlx5_wq_ll_get_wqe(struct mlx5_wq_ll * wq,u16 ix)186 static inline void *mlx5_wq_ll_get_wqe(struct mlx5_wq_ll *wq, u16 ix)
187 {
188 	return wq->buf + (ix << wq->log_stride);
189 }
190 
mlx5_wq_ll_push(struct mlx5_wq_ll * wq,u16 head_next)191 static inline void mlx5_wq_ll_push(struct mlx5_wq_ll *wq, u16 head_next)
192 {
193 	wq->head = head_next;
194 	wq->wqe_ctr++;
195 	wq->cur_sz++;
196 }
197 
mlx5_wq_ll_pop(struct mlx5_wq_ll * wq,__be16 ix,__be16 * next_tail_next)198 static inline void mlx5_wq_ll_pop(struct mlx5_wq_ll *wq, __be16 ix,
199 				  __be16 *next_tail_next)
200 {
201 	*wq->tail_next = ix;
202 	wq->tail_next = next_tail_next;
203 	wq->cur_sz--;
204 }
205 
mlx5_wq_ll_update_db_record(struct mlx5_wq_ll * wq)206 static inline void mlx5_wq_ll_update_db_record(struct mlx5_wq_ll *wq)
207 {
208 	*wq->db = cpu_to_be32(wq->wqe_ctr);
209 }
210 
211 #endif /* __MLX5_WQ_H__ */
212