xref: /freebsd/sys/dev/ocs_fc/ocs_utils.h (revision e2afbc45258f2fa4bdcf126e959ac660e76fc802)
1 /*-
2  * Copyright (c) 2017 Broadcom. All rights reserved.
3  * The term "Broadcom" refers to Broadcom Limited and/or its subsidiaries.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  *    this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  *    this list of conditions and the following disclaimer in the documentation
13  *    and/or other materials provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 /**
33  * @file
34  *
35  */
36 
37 #ifndef __OCS_UTILS_H
38 #define __OCS_UTILS_H
39 
40 #include "ocs_list.h"
41 typedef struct ocs_array_s ocs_array_t;
42 
43 extern void ocs_array_set_slablen(uint32_t len);
44 extern ocs_array_t *ocs_array_alloc(ocs_os_handle_t os, uint32_t size, uint32_t count);
45 extern void ocs_array_free(ocs_array_t *array);
46 extern void *ocs_array_get(ocs_array_t *array, uint32_t idx);
47 extern uint32_t ocs_array_get_count(ocs_array_t *array);
48 extern uint32_t ocs_array_get_size(ocs_array_t *array);
49 
50 /* Void pointer array and iterator */
51 typedef struct ocs_varray_s ocs_varray_t;
52 
53 extern ocs_varray_t *ocs_varray_alloc(ocs_os_handle_t os, uint32_t entry_count);
54 extern void ocs_varray_free(ocs_varray_t *ai);
55 extern int32_t ocs_varray_add(ocs_varray_t *ai, void *entry);
56 extern void ocs_varray_iter_reset(ocs_varray_t *ai);
57 extern void *ocs_varray_iter_next(ocs_varray_t *ai);
58 extern void *_ocs_varray_iter_next(ocs_varray_t *ai);
59 extern void ocs_varray_lock(ocs_varray_t *ai);
60 extern void ocs_varray_unlock(ocs_varray_t *ai);
61 extern uint32_t ocs_varray_get_count(ocs_varray_t *ai);
62 
63 /***************************************************************************
64  * Circular buffer
65  *
66  */
67 
68 typedef struct ocs_cbuf_s ocs_cbuf_t;
69 
70 extern ocs_cbuf_t *ocs_cbuf_alloc(ocs_os_handle_t os, uint32_t entry_count);
71 extern void ocs_cbuf_free(ocs_cbuf_t *cbuf);
72 extern void *ocs_cbuf_get(ocs_cbuf_t *cbuf, int32_t timeout_usec);
73 extern int32_t ocs_cbuf_put(ocs_cbuf_t *cbuf, void *elem);
74 extern int32_t ocs_cbuf_prime(ocs_cbuf_t *cbuf, ocs_array_t *array);
75 
76 typedef struct {
77         void *vaddr;
78         uint32_t length;
79 } ocs_scsi_vaddr_len_t;
80 
81 #define OCS_TEXTBUF_MAX_ALLOC_LEN	(256*1024)
82 
83 typedef struct {
84 	ocs_list_link_t link;
85 	uint8_t user_allocated:1;
86 	uint8_t *buffer;
87 	uint32_t buffer_length;
88 	uint32_t buffer_written;
89 } ocs_textbuf_segment_t;
90 
91 typedef struct {
92 	ocs_t *ocs;
93 	ocs_list_t segment_list;
94 	uint8_t extendable:1;
95 	uint32_t allocation_length;
96 	uint32_t total_allocation_length;
97 	uint32_t max_allocation_length;
98 } ocs_textbuf_t;
99 
100 extern int32_t ocs_textbuf_alloc(ocs_t *ocs, ocs_textbuf_t *textbuf, uint32_t length);
101 extern uint32_t ocs_textbuf_initialized(ocs_textbuf_t *textbuf);
102 extern int32_t ocs_textbuf_init(ocs_t *ocs, ocs_textbuf_t *textbuf, void *buffer, uint32_t length);
103 extern void ocs_textbuf_free(ocs_t *ocs, ocs_textbuf_t *textbuf);
104 extern void ocs_textbuf_putc(ocs_textbuf_t *textbuf, uint8_t c);
105 extern void ocs_textbuf_puts(ocs_textbuf_t *textbuf, char *s);
106 extern void ocs_textbuf_printf(ocs_textbuf_t *textbuf, const char *fmt, ...) __printflike(2, 3);
107 extern void ocs_textbuf_vprintf(ocs_textbuf_t *textbuf, const char *fmt, va_list ap) __printflike(2, 0);
108 extern void ocs_textbuf_buffer(ocs_textbuf_t *textbuf, uint8_t *buffer, uint32_t buffer_length);
109 extern void ocs_textbuf_copy(ocs_textbuf_t *textbuf, uint8_t *buffer, uint32_t buffer_length);
110 extern int32_t ocs_textbuf_remaining(ocs_textbuf_t *textbuf);
111 extern void ocs_textbuf_reset(ocs_textbuf_t *textbuf);
112 extern uint8_t *ocs_textbuf_get_buffer(ocs_textbuf_t *textbuf);
113 extern int32_t ocs_textbuf_get_length(ocs_textbuf_t *textbuf);
114 extern int32_t ocs_textbuf_get_written(ocs_textbuf_t *textbuf);
115 extern uint8_t *ocs_textbuf_ext_get_buffer(ocs_textbuf_t *textbuf, uint32_t idx);
116 extern int32_t ocs_textbuf_ext_get_length(ocs_textbuf_t *textbuf, uint32_t idx);
117 extern int32_t ocs_textbuf_ext_get_written(ocs_textbuf_t *textbuf, uint32_t idx);
118 
119 typedef struct ocs_pool_s ocs_pool_t;
120 
121 extern ocs_pool_t *ocs_pool_alloc(ocs_os_handle_t os, uint32_t size, uint32_t count, uint32_t use_lock);
122 extern void ocs_pool_reset(ocs_pool_t *pool);
123 extern void ocs_pool_free(ocs_pool_t *pool);
124 extern void *ocs_pool_get(ocs_pool_t *pool);
125 extern void ocs_pool_put(ocs_pool_t *pool, void *item);
126 extern uint32_t ocs_pool_get_count(ocs_pool_t *pool);
127 extern void *ocs_pool_get_instance(ocs_pool_t *pool, uint32_t idx);
128 extern uint32_t ocs_pool_get_freelist_count(ocs_pool_t *pool);
129 
130 /* Uncomment this line to enable logging extended queue history
131  */
132 //#define OCS_DEBUG_QUEUE_HISTORY
133 
134 /* Allocate maximum allowed (4M) */
135 #if defined(OCS_DEBUG_QUEUE_HISTORY)
136 #define OCS_Q_HIST_SIZE (1000000UL)		/* Size in words */
137 #endif
138 
139 #define OCS_LOG_ENABLE_SM_TRACE(ocs)		(((ocs) != NULL) ? (((ocs)->logmask & (1U << 0)) != 0) : 0)
140 #define OCS_LOG_ENABLE_ELS_TRACE(ocs)		(((ocs) != NULL) ? (((ocs)->logmask & (1U << 1)) != 0) : 0)
141 #define OCS_LOG_ENABLE_SCSI_TRACE(ocs)		(((ocs) != NULL) ? (((ocs)->logmask & (1U << 2)) != 0) : 0)
142 #define OCS_LOG_ENABLE_SCSI_TGT_TRACE(ocs)	(((ocs) != NULL) ? (((ocs)->logmask & (1U << 3)) != 0) : 0)
143 #define OCS_LOG_ENABLE_DOMAIN_SM_TRACE(ocs)	(((ocs) != NULL) ? (((ocs)->logmask & (1U << 4)) != 0) : 0)
144 #define OCS_LOG_ENABLE_Q_FULL_BUSY_MSG(ocs)	(((ocs) != NULL) ? (((ocs)->logmask & (1U << 5)) != 0) : 0)
145 #define OCS_LOG_ENABLE_IO_ERRORS(ocs)		(((ocs) != NULL) ? (((ocs)->logmask & (1U << 6)) != 0) : 0)
146 
147 extern void ocs_dump32(uint32_t, ocs_os_handle_t, const char *, void *, uint32_t);
148 extern void ocs_debug_enable(uint32_t mask);
149 extern void ocs_debug_disable(uint32_t mask);
150 extern int ocs_debug_is_enabled(uint32_t mask);
151 extern void ocs_debug_attach(void *);
152 extern void ocs_debug_detach(void *);
153 
154 #if defined(OCS_DEBUG_QUEUE_HISTORY)
155 
156 /**
157  * @brief Queue history footer
158  */
159 typedef union ocs_q_hist_ftr_u {
160 	uint32_t word;
161 	struct {
162 #define Q_HIST_TYPE_LEN 		3
163 #define Q_HIST_MASK_LEN 		29
164 		uint32_t mask:Q_HIST_MASK_LEN,
165 			 type:Q_HIST_TYPE_LEN;
166 	} s;
167 } ocs_q_hist_ftr_t;
168 
169 /**
170  * @brief WQE command mask lookup
171  */
172 typedef struct ocs_q_hist_wqe_mask_s {
173 	uint8_t command;
174 	uint32_t mask;
175 } ocs_q_hist_wqe_mask_t;
176 
177 /**
178  * @brief CQE mask lookup
179  */
180 typedef struct ocs_q_hist_cqe_mask_s {
181 	uint8_t ctype;
182 	uint32_t :Q_HIST_MASK_LEN,
183 		 type:Q_HIST_TYPE_LEN;
184 	uint32_t mask;
185 	uint32_t mask_err;
186 } ocs_q_hist_cqe_mask_t;
187 
188 /**
189  * @brief Queue history type
190  */
191 typedef enum {
192 	/* changes need to be made to ocs_queue_history_type_name() as well */
193 	OCS_Q_HIST_TYPE_WQE = 0,
194 	OCS_Q_HIST_TYPE_CWQE,
195 	OCS_Q_HIST_TYPE_CXABT,
196 	OCS_Q_HIST_TYPE_MISC,
197 } ocs_q_hist_type_t;
198 
199 static __inline const char *
200 ocs_queue_history_type_name(ocs_q_hist_type_t type)
201 {
202 	switch (type) {
203 	case OCS_Q_HIST_TYPE_WQE: return "wqe"; break;
204 	case OCS_Q_HIST_TYPE_CWQE: return "wcqe"; break;
205 	case OCS_Q_HIST_TYPE_CXABT: return "xacqe"; break;
206 	case OCS_Q_HIST_TYPE_MISC: return "misc"; break;
207 	default: return "unknown"; break;
208 	}
209 }
210 
211 typedef struct {
212 	ocs_t		*ocs;
213 	uint32_t	*q_hist;
214 	uint32_t	q_hist_index;
215 	ocs_lock_t	q_hist_lock;
216 } ocs_hw_q_hist_t;
217 
218 extern void ocs_queue_history_cqe(ocs_hw_q_hist_t*, uint8_t, uint32_t *, uint8_t, uint32_t, uint32_t);
219 extern void ocs_queue_history_wq(ocs_hw_q_hist_t*, uint32_t *, uint32_t, uint32_t);
220 extern void ocs_queue_history_misc(ocs_hw_q_hist_t*, uint32_t *, uint32_t);
221 extern void ocs_queue_history_init(ocs_t *, ocs_hw_q_hist_t*);
222 extern void ocs_queue_history_free(ocs_hw_q_hist_t*);
223 extern uint32_t ocs_queue_history_prev_index(uint32_t);
224 extern uint8_t ocs_queue_history_q_info_enabled(void);
225 extern uint8_t ocs_queue_history_timestamp_enabled(void);
226 #else
227 #define ocs_queue_history_wq(...)
228 #define ocs_queue_history_cqe(...)
229 #define ocs_queue_history_misc(...)
230 #define ocs_queue_history_init(...)
231 #define ocs_queue_history_free(...)
232 #endif
233 
234 #define OCS_DEBUG_ALWAYS		(1U << 0)
235 #define OCS_DEBUG_ENABLE_MQ_DUMP	(1U << 1)
236 #define OCS_DEBUG_ENABLE_CQ_DUMP	(1U << 2)
237 #define OCS_DEBUG_ENABLE_WQ_DUMP	(1U << 3)
238 #define OCS_DEBUG_ENABLE_EQ_DUMP	(1U << 4)
239 #define OCS_DEBUG_ENABLE_SPARAM_DUMP	(1U << 5)
240 
241 extern void _ocs_assert(const char *cond, const char *filename, int linenum);
242 
243 #define ocs_assert(cond, ...) \
244 	do { \
245 		if (!(cond)) { \
246 			_ocs_assert(#cond, __FILE__, __LINE__); \
247 			return __VA_ARGS__; \
248 		} \
249 	} while (0)
250 
251 extern void ocs_dump_service_params(const char *label, void *sparms);
252 extern void ocs_display_sparams(const char *prelabel, const char *reqlabel, int dest, void *textbuf, void *sparams);
253 
254 typedef struct {
255 	uint16_t crc;
256 	uint16_t app_tag;
257 	uint32_t ref_tag;
258 } ocs_dif_t;
259 
260 /* DIF guard calculations */
261 extern uint16_t ocs_scsi_dif_calc_crc(const uint8_t *, uint32_t size, uint16_t crc);
262 extern uint16_t ocs_scsi_dif_calc_checksum(ocs_scsi_vaddr_len_t addrlen[], uint32_t addrlen_count);
263 
264 /**
265  * @brief Power State change message types
266  *
267  */
268 typedef enum {
269 	OCS_PM_PREPARE = 1,
270 	OCS_PM_SLEEP,
271 	OCS_PM_HIBERNATE,
272 	OCS_PM_RESUME,
273 } ocs_pm_msg_e;
274 
275 /**
276  * @brief Power State values
277  *
278  */
279 typedef enum {
280 	OCS_PM_STATE_S0 = 0,
281 	OCS_PM_STATE_S1,
282 	OCS_PM_STATE_S2,
283 	OCS_PM_STATE_S3,
284 	OCS_PM_STATE_S4,
285 } ocs_pm_state_e;
286 
287 typedef struct {
288 	ocs_pm_state_e pm_state;		/*<< Current PM state */
289 } ocs_pm_context_t;
290 
291 extern int32_t ocs_pm_request(ocs_t *ocs, ocs_pm_msg_e msg, int32_t (*callback)(ocs_t *ocs, int32_t status, void *arg),
292 	void *arg);
293 extern ocs_pm_state_e ocs_pm_get_state(ocs_t *ocs);
294 extern const char *ocs_pm_get_state_string(ocs_t *ocs);
295 
296 #define SPV_ROWLEN	256
297 #define SPV_DIM		3
298 
299 /*!
300 * @defgroup spv Sparse Vector
301 */
302 
303 /**
304  * @brief Sparse vector structure.
305  */
306 typedef struct sparse_vector_s {
307 	ocs_os_handle_t os;
308 	uint32_t max_idx;		/**< maximum index value */
309 	void **array;			/**< pointer to 3D array */
310 } *sparse_vector_t;
311 
312 extern void spv_del(sparse_vector_t spv);
313 extern sparse_vector_t spv_new(ocs_os_handle_t os);
314 extern void spv_set(sparse_vector_t sv, uint32_t idx, void *value);
315 extern void *spv_get(sparse_vector_t sv, uint32_t idx);
316 
317 extern unsigned short t10crc16(const unsigned char *blk_adr, unsigned long blk_len, unsigned short crc);
318 
319 typedef struct ocs_ramlog_s ocs_ramlog_t;
320 
321 #define OCS_RAMLOG_DEFAULT_BUFFERS              5
322 
323 extern ocs_ramlog_t *ocs_ramlog_init(ocs_t *ocs, uint32_t buffer_len, uint32_t buffer_count);
324 extern void ocs_ramlog_free(ocs_t *ocs, ocs_ramlog_t *ramlog);
325 extern void ocs_ramlog_clear(ocs_t *ocs, ocs_ramlog_t *ramlog, int clear_start_of_day, int clear_recent);
326 extern int32_t ocs_ramlog_printf(void *os, const char *fmt, ...) __printflike(2, 3);
327 extern int32_t ocs_ramlog_vprintf(ocs_ramlog_t *ramlog, const char *fmt, va_list ap) __printflike(2, 0);
328 extern int32_t ocs_ddump_ramlog(ocs_textbuf_t *textbuf, ocs_ramlog_t *ramlog);
329 
330 #endif
331