1 /*
2  * This file and its contents are supplied under the terms of the
3  * Common Development and Distribution License ("CDDL"), version 1.0.
4  * You may only use this file in accordance with the terms of version
5  * 1.0 of the CDDL.
6  *
7  * A full copy of the text of the CDDL should have accompanied this
8  * source.  A copy of the CDDL is also available via the Internet at
9  * http://www.illumos.org/license/CDDL.
10  */
11 
12 /*
13  * Copyright 2023 Racktop Systems, Inc.
14  */
15 
16 #ifndef _LMRC_RAID_H
17 #define	_LMRC_RAID_H
18 
19 #include <sys/types.h>
20 #include <sys/debug.h>
21 
22 #include <sys/scsi/adapters/mpi/mpi2_type.h>
23 #include <sys/scsi/adapters/mpi/mpi2.h>
24 #include <sys/scsi/adapters/mpi/mpi2_cnfg.h>
25 #include <sys/scsi/adapters/mpi/mpi2_ioc.h>
26 
27 typedef struct lmrc_raidctx_g35		lmrc_raidctx_g35_t;
28 typedef struct lmrc_devhdl_info		lmrc_devhdl_info_t;
29 typedef struct lmrc_array_info		lmrc_array_info_t;
30 typedef struct lmrc_quad_element	lmrc_quad_element_t;
31 typedef struct lmrc_span_info		lmrc_span_info_t;
32 typedef struct lmrc_ld_span		lmrc_ld_span_t;
33 typedef struct lmrc_span_block_info	lmrc_span_block_info_t;
34 typedef struct lmrc_ld_raid		lmrc_ld_raid_t;
35 typedef struct lmrc_ld_span_map		lmrc_ld_span_map_t;
36 
37 typedef struct lmrc_fw_raid_map		lmrc_fw_raid_map_t;
38 typedef struct lmrc_raid_map_desc	lmrc_raid_map_desc_t;
39 
40 typedef struct lmrc_ld_tgt		lmrc_ld_tgt_t;
41 typedef struct lmrc_ld_ref		lmrc_ld_ref_t;
42 typedef	struct lmrc_ld_cfg		lmrc_ld_cfg_t;
43 typedef struct lmrc_ld_list		lmrc_ld_list_t;
44 typedef struct lmrc_ld_tgtid_list	lmrc_ld_tgtid_list_t;
45 
46 #include "lmrc.h"
47 
48 #pragma pack(1)
49 
50 struct lmrc_raidctx_g35 {
51 	uint8_t		rc_type:4;
52 	uint8_t		rc_nseg:4;
53 	uint8_t		rc_rsvd0;
54 	uint16_t	rc_timeout;
55 
56 	struct {
57 		uint16_t	rf_rsvd:1;
58 		uint16_t	rf_sld:1;
59 		uint16_t	rf_c2f:1;
60 		uint16_t	rf_fwn:1;
61 		uint16_t	rf_sqn:1;
62 		uint16_t	rf_sbs:1;
63 		uint16_t	rf_rw:1;
64 		uint16_t	rf_log:1;
65 		uint16_t	rf_cpu_sel:4;
66 		uint16_t	rf_set_divert:4;
67 	} rc_routing_flags;
68 
69 	uint16_t	rc_ld_tgtid;
70 	uint64_t	rc_reg_lock_rowlba;
71 	uint32_t	rc_reg_lock_len;
72 
73 	union {
74 		uint16_t	rc_next_lmid;
75 		uint16_t	rc_peer_smid;
76 	} rc_smid;
77 
78 	uint8_t		rc_exstatus;
79 	uint8_t		rc_status;
80 
81 	struct {
82 		uint8_t	rf_pref_cpu:1;
83 		uint8_t	rf_rsvd1:3;
84 		uint8_t	rf_io_subtype:3;
85 		uint8_t	rf_rsvd2:1;
86 	} rc_raid_flags;
87 
88 	uint8_t		rc_span_arm;
89 	uint16_t	rc_cfg_seqnum;
90 	struct {
91 		uint16_t	rc_num_sge:12;
92 		uint16_t	rc_rsvd1:3;
93 		uint16_t	rc_stream_detected:1;
94 	};
95 	uint8_t		rc_rsvd2[2];
96 };
97 CTASSERT(sizeof (lmrc_raidctx_g35_t) == 0x20);
98 
99 /*
100  * rc_raid_flags values
101  */
102 #define	LMRC_RF_IO_SUBTYPE_NONE			0
103 #define	LMRC_RF_IO_SUBTYPE_SYSTEM_PD		1
104 #define	LMRC_RF_IO_SUBTYPE_RMW_DATA		2
105 #define	LMRC_RF_IO_SUBTYPE_RMW_P		3
106 #define	LMRC_RF_IO_SUBTYPE_RMW_Q		4
107 #define	LMRC_RF_IO_SUBTYPE_CACHE_BYPASS		6
108 #define	LMRC_RF_IO_SUBTYPE_LDIO_BW_LIMIT	7
109 
110 /*
111  * RAID map related structures
112  */
113 #define	LMRC_MIN_MAP_SIZE			0x10000
114 
115 #define	LMRC_MAX_SPAN_DEPTH		8
116 #define	LMRC_MAX_QUAD_DEPTH		LMRC_SPAN_DEPTH
117 #define	LMRC_MAX_ROW_SIZE		32
118 #define	LMRC_MAX_LOGICAL_DRIVES		64
119 #define	LMRC_MAX_LOGICAL_DRIVES_EXT	256
120 #define	LMRC_MAX_LOGICAL_DRIVES_DYN	512
121 #define	LMRC_MAX_ARRAYS			128
122 #define	LMRC_MAX_ARRAYS_EXT		256
123 #define	LMRC_MAX_API_ARRAYS_EXT		(LMRC_MAX_ARRAYS_EXT)
124 #define	LMRC_MAX_API_ARRAYS_DYN		512
125 #define	LMRC_MAX_PHYS_DEV		256
126 
127 #define	LMRC_RAIDMAP_MAX_SPAN_DEPTH	(LMRC_MAX_SPAN_DEPTH)
128 #define	LMRC_RAIDMAP_MAX_ROW_SIZE	(LMRC_MAX_ROW_SIZE)
129 #define	LMRC_RAIDMAP_ARRAYS		(LMRC_MAX_ARRAYS)
130 #define	LMRC_RAIDMAP_MAX_PHYS_DEV_DYN	512
131 
132 #define	LMRC_DEVHDL_IFTYPE_UNKNOWN		0
133 #define	LMRC_DEVHDL_IFTYPE_PARALLEL_SCSI	1
134 #define	LMRC_DEVHDL_IFTYPE_SAS_PD		2
135 #define	LMRC_DEVHDL_IFTYPE_SATA_PD		3
136 #define	LMRC_DEVHDL_IFTYPE_FC_PD		4
137 #define	LMRC_DEVHDL_IFTYPE_NVME_PD		5
138 
139 #define	LMRC_DEVHDL_INVALID			0xFFFF
140 
141 struct lmrc_devhdl_info {
142 	uint16_t	di_cur_devhdl;
143 	uint8_t		di_valid_handles;
144 	uint8_t		di_iftype;
145 	uint16_t	di_devhdl[2];
146 };
147 
148 struct lmrc_array_info {
149 	uint16_t	ai_pd[LMRC_RAIDMAP_MAX_ROW_SIZE];
150 };
151 
152 struct lmrc_quad_element {
153 	uint64_t	qe_logstart;
154 	uint64_t	qe_logend;
155 	uint64_t	qe_offset_in_span;
156 	uint32_t	qe_diff;
157 	uint32_t	qe_reserved;
158 };
159 
160 struct lmrc_span_info {
161 	uint32_t		si_nelem;
162 	uint32_t		si_reserved;
163 	lmrc_quad_element_t	si_quad[LMRC_RAIDMAP_MAX_SPAN_DEPTH];
164 };
165 
166 struct lmrc_ld_span {
167 	uint64_t	ls_start_blk;
168 	uint64_t	ls_nblk;
169 	uint16_t	ls_arrayref;
170 	uint8_t		ls_span_rowsz;
171 	uint8_t		ls_span_row_datasz;
172 	uint8_t		ls_reserved[4];
173 };
174 
175 struct lmrc_span_block_info {
176 	uint64_t	sbi_num_rows;
177 	lmrc_ld_span_t	sbi_span;
178 	lmrc_span_info_t	sbi_block_span_info;
179 };
180 
181 struct lmrc_ld_raid {
182 	struct {
183 		uint32_t lc_fp_cap:1;
184 		uint32_t lc_ra_cap:1;
185 		uint32_t lc_reserved5:2;
186 		uint32_t lc_ld_pi_mode:4;
187 		uint32_t lc_pd_pi_mode:4;
188 		uint32_t lc_encryption_type:8;
189 		uint32_t lc_fp_write_cap:1;
190 		uint32_t lc_fp_read_cap:1;
191 		uint32_t lc_fp_write_across_stripe:1;
192 		uint32_t lc_fp_read_across_stripe:1;
193 		uint32_t lc_fp_non_rw_cap:1;
194 		uint32_t lc_tm_cap:1;
195 		uint32_t lc_fp_cache_bypass_cap:1;
196 		uint32_t lc_reserved4:5;
197 	} lr_cap;
198 
199 	uint32_t lr_reserved6;
200 	uint64_t lr_size;
201 
202 	uint8_t lr_span_depth;
203 	uint8_t lr_level;
204 	uint8_t lr_stripe_shift;
205 	uint8_t lr_row_size;
206 
207 	uint8_t lr_row_data_size;
208 	uint8_t lr_write_mode;
209 	uint8_t lr_prl;
210 	uint8_t lr_srl;
211 
212 	uint16_t lr_target_id;
213 	uint8_t lr_ld_state;
214 	uint8_t lr_reg_type_req_on_write;
215 	uint8_t lr_mod_factor;
216 	uint8_t lr_reg_type_req_on_read;
217 	uint16_t lr_seq_num;
218 
219 	struct {
220 		uint32_t lf_reserved:30;
221 		uint32_t lf_reg_type_req_on_read_ls_valid:1;
222 		uint32_t lf_ld_sync_required:1;
223 	} lr_flags;
224 
225 	uint8_t lr_lun[8];
226 	uint8_t lr_fp_io_timeout_for_ld;
227 	uint8_t lr_reserved2[3];
228 	uint32_t lr_logical_block_length;
229 
230 	struct {
231 		uint32_t le_reserved1:24;
232 		uint32_t le_ld_logical_block_exp:4;
233 		uint32_t le_ld_pi_exp:4;
234 	} lr_exponent;
235 	uint8_t lr_reserved3[0x80 - 0x38];
236 };
237 
238 struct lmrc_ld_span_map {
239 	lmrc_ld_raid_t sm_ld_raid;
240 	uint8_t sm_data_arm_map[LMRC_RAIDMAP_MAX_ROW_SIZE];
241 	lmrc_span_block_info_t sm_span_block[LMRC_RAIDMAP_MAX_SPAN_DEPTH];
242 };
243 
244 /*
245  * RAID map descriptor
246  */
247 struct lmrc_raid_map_desc {
248 	uint32_t	rmd_type;	/* descriptor type */
249 	uint32_t	rmd_off;	/* offset in RAID map buffer */
250 	uint32_t	rmd_bufsz;	/* size of buffer */
251 	uint32_t	rmd_desc_nelem;	/* number of elements in buffer */
252 };
253 
254 #define	LMRC_RAID_MAP_DESC_TYPE_DEVHDL	0
255 #define	LMRC_RAID_MAP_DESC_TYPE_LD_ID	1
256 #define	LMRC_RAID_MAP_DESC_TYPE_ARRAY	2
257 #define	LMRC_RAID_MAP_DESC_TYPE_SPAN	3
258 #define	LMRC_RAID_MAP_DESC_TYPES_COUNT	(LMRC_RAID_MAP_DESC_TYPE_SPAN + 1)
259 
260 /*
261  * Dynamic RAID Map
262  */
263 struct lmrc_fw_raid_map {
264 	uint32_t	rm_raidmap_sz;
265 	uint32_t	rm_desc_table_off;
266 	uint32_t	rm_desc_table_sz;
267 	uint32_t	rm_desc_table_nelem;
268 	uint64_t	rm_pci_thres_bandw;
269 	uint32_t	rm_rsvd[3];
270 
271 	uint8_t		rm_fp_pd_io_timeout;
272 	uint8_t		rm_rsvd2[3];
273 	uint32_t	rm_rmw_fp_seqnum;
274 	uint16_t	rm_ld_count;
275 	uint16_t	rm_ar_count;
276 	uint16_t	rm_span_count;
277 	uint16_t	rm_rsvd3[3];
278 
279 	/*
280 	 * FreeBSD uses this for driver purposes and claims FW doesn't
281 	 * modify this.
282 	 */
283 	union {
284 		struct {
285 			lmrc_devhdl_info_t	*rm_devhdl;
286 			uint16_t		*rm_ld_id;
287 			lmrc_array_info_t	*rm_array;
288 			lmrc_ld_span_map_t	*rm_span;
289 		};
290 		void		*rm_desc_ptrs[LMRC_RAID_MAP_DESC_TYPES_COUNT];
291 	};
292 
293 	/* Variable size descriptor table. */
294 	lmrc_raid_map_desc_t	rm_desc_table[LMRC_RAID_MAP_DESC_TYPES_COUNT];
295 
296 	/* Variable size buffer containing all data */
297 	uint32_t	rm_desc_data[0];
298 };
299 
300 /*
301  * LD target list
302  */
303 struct lmrc_ld_tgt {
304 	uint8_t		lt_tgtid;
305 	uint8_t		lt_rsvd;
306 	uint16_t	lt_seqnum;
307 };
308 
309 struct lmrc_ld_tgtid_list {
310 	uint32_t	ltl_size;
311 	uint32_t	ltl_count;
312 	uint8_t		ltl_rsvd[3];
313 	uint8_t		ltl_tgtid[0];
314 };
315 
316 #pragma pack(0)
317 
318 /* RAID map accessor functions */
319 static inline lmrc_ld_raid_t *
lmrc_ld_raid_get(uint16_t ld_id,lmrc_fw_raid_map_t * rm)320 lmrc_ld_raid_get(uint16_t ld_id, lmrc_fw_raid_map_t *rm)
321 {
322 	if (ld_id >= rm->rm_ld_count)
323 		return (NULL);
324 
325 	return (&rm->rm_span[ld_id].sm_ld_raid);
326 }
327 
328 static inline uint16_t
lmrc_ld_id_get(uint16_t tgtid,lmrc_fw_raid_map_t * rm)329 lmrc_ld_id_get(uint16_t tgtid, lmrc_fw_raid_map_t *rm)
330 {
331 	ASSERT3U(tgtid, <,
332 	    rm->rm_desc_table[LMRC_RAID_MAP_DESC_TYPE_LD_ID].rmd_desc_nelem);
333 
334 	uint32_t nelem =
335 	    rm->rm_desc_table[LMRC_RAID_MAP_DESC_TYPE_LD_ID].rmd_desc_nelem;
336 
337 	if (tgtid >= nelem)
338 		return (LMRC_DEVHDL_INVALID);
339 
340 	return (rm->rm_ld_id[tgtid]);
341 }
342 
343 static inline uint16_t
lmrc_tgtid_get(uint16_t ld_id,lmrc_fw_raid_map_t * rm)344 lmrc_tgtid_get(uint16_t ld_id, lmrc_fw_raid_map_t *rm)
345 {
346 	lmrc_ld_raid_t *raid;
347 
348 	if (ld_id >= rm->rm_ld_count)
349 		return (LMRC_DEVHDL_INVALID);
350 
351 	raid = lmrc_ld_raid_get(ld_id, rm);
352 	if (raid == NULL)
353 		return (LMRC_DEVHDL_INVALID);
354 
355 	return (raid->lr_target_id);
356 }
357 
358 /* other helper functions */
359 static inline boolean_t
lmrc_cmd_is_rw(uint8_t cdb0)360 lmrc_cmd_is_rw(uint8_t cdb0)
361 {
362 	switch (cdb0) {
363 	case SCMD_READ:
364 	case SCMD_WRITE:
365 	case SCMD_READ_G1:
366 	case SCMD_WRITE_G1:
367 	case SCMD_READ_G4:
368 	case SCMD_WRITE_G4:
369 	case SCMD_READ_G5:
370 	case SCMD_WRITE_G5:
371 		return (B_TRUE);
372 	default:
373 		return (B_FALSE);
374 	}
375 }
376 
377 typedef lmrc_raidctx_g35_t			MPI25_SCSI_IO_VENDOR_UNIQUE;
378 #define	MPI25_SCSI_IO_VENDOR_UNIQUE_REGION
379 #include <sys/scsi/adapters/mpi/mpi2_init.h>
380 
381 int lmrc_setup_raidmap(lmrc_t *);
382 void lmrc_free_raidmap(lmrc_t *);
383 
384 boolean_t lmrc_ld_tm_capable(lmrc_t *, uint16_t);
385 
386 int lmrc_get_ld_list(lmrc_t *);
387 
388 int lmrc_raid_attach(dev_info_t *);
389 int lmrc_raid_detach(dev_info_t *);
390 
391 int lmrc_raid_aen_handler(lmrc_t *, lmrc_evt_t *);
392 
393 #endif /* _LMRC_RAID_H */
394