xref: /freebsd/sys/dev/mlx5/mlx5_core/wq.h (revision cd0d51baaa4509a1db83251a601d34404d20c990)
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