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 2024 Racktop Systems, Inc.
14  */
15 
16 #ifndef	_MFI_H
17 #define	_MFI_H
18 
19 #include <sys/bitext.h>
20 #include <sys/debug.h>
21 #include <sys/stddef.h>
22 
23 #ifdef __cplusplus
24 extern "C" {
25 #endif
26 
27 /*
28  * Forward declaration of various types defined by the MFI headers.
29  */
30 typedef struct mfi_drv_ver		mfi_drv_ver_t;
31 typedef struct mfi_pci_info		mfi_pci_info_t;
32 typedef struct mfi_ioctl		mfi_ioctl_t;
33 
34 typedef union mfi_cap			mfi_cap_t;
35 typedef union mfi_sgl			mfi_sgl_t;
36 typedef struct mfi_header		mfi_header_t;
37 typedef	struct mfi_init_payload		mfi_init_payload_t;
38 typedef struct mfi_io_payload		mfi_io_payload_t;
39 typedef struct mfi_pthru_payload	mfi_pthru_payload_t;
40 typedef struct mfi_dcmd_payload		mfi_dcmd_payload_t;
41 typedef struct mfi_abort_payload	mfi_abort_payload_t;
42 typedef struct mfi_frame		mfi_frame_t;
43 
44 typedef struct mfi_array		mfi_array_t;
45 typedef struct mfi_spare		mfi_spare_t;
46 
47 typedef struct mfi_ld_config		mfi_ld_config_t;
48 typedef struct mfi_ld_info		mfi_ld_info_t;
49 typedef struct mfi_ld_list		mfi_ld_list_t;
50 typedef struct mfi_ld_parameters	mfi_ld_parameters_t;
51 typedef struct mfi_ld_progress		mfi_ld_progress_t;
52 typedef struct mfi_ld_properties	mfi_ld_properties_t;
53 typedef struct mfi_ld_ref		mfi_ld_ref_t;
54 typedef struct mfi_ld_tgtid_list	mfi_ld_tgtid_list_t;
55 typedef struct mfi_span			mfi_span_t;
56 
57 typedef struct mfi_config_data		mfi_config_data_t;
58 
59 typedef struct mfi_pd_ref		mfi_pd_ref_t;
60 typedef struct mfi_pd_info		mfi_pd_info_t;
61 typedef struct mfi_pd_cfg		mfi_pd_cfg_t;
62 typedef struct mfi_pd_map		mfi_pd_map_t;
63 typedef struct mfi_pd_addr		mfi_pd_addr_t;
64 typedef struct mfi_pd_list		mfi_pd_list_t;
65 
66 typedef struct mfi_ctrl_props		mfi_ctrl_props_t;
67 typedef struct mfi_image_comp		mfi_image_comp_t;
68 typedef struct mfi_ctrl_info		mfi_ctrl_info_t;
69 
70 typedef struct mfi_bbu_capacity		mfi_bbu_capacity_t;
71 typedef struct mfi_bbu_design_info	mfi_bbu_design_info_t;
72 typedef struct mfi_bbu_properties	mfi_bbu_properties_t;
73 typedef struct mfi_ibbu_state		mfi_ibbu_state_t;
74 typedef struct mfi_bbu_state		mfi_bbu_state_t;
75 typedef struct mfi_bbu_status		mfi_bbu_status_t;
76 
77 typedef struct mfi_pr_properties	mfi_pr_properties_t;
78 typedef struct mfi_pr_status		mfi_pr_status_t;
79 
80 typedef struct mfi_progress		mfi_progress_t;
81 
82 /*
83  * MegaRAID Firmware Interface
84  *
85  * MFI stands for MegaRAID Firmware Interface. This is just a moniker
86  * for the protocol between the software and the firmware. Commands are
87  * issued using "message frames".
88  */
89 
90 #define	MFI_MAX_LOGICAL_DRIVES		64
91 #define	MFI_MAX_PHYSICAL_DRIVES		256
92 
93 /*
94  * During FW init, clear pending cmds & reset state using the doorbell register
95  *
96  * ABORT:		Abort all pending cmds
97  * READY:		Move from OPERATIONAL to READY state; discard queue info
98  * MFIMODE:		Discard (possible) low MFA posted in 64-bit mode (??)
99  * CLEAR_HANDSHAKE:	FW is waiting for HANDSHAKE from BIOS or Driver
100  * HOTPLUG:		Resume from Hotplug
101  * MFI_STOP_ADP:	Send signal to FW to stop processing
102  */
103 #define	MFI_INIT_ABORT				0x00000001
104 #define	MFI_INIT_READY				0x00000002
105 #define	MFI_INIT_MFIMODE			0x00000004
106 #define	MFI_INIT_CLEAR_HANDSHAKE		0x00000008
107 #define	MFI_INIT_HOTPLUG			0x00000010
108 #define	MFI_STOP_ADP				0x00000020
109 #define	MFI_RESET_FLAGS	(MFI_INIT_READY | MFI_INIT_MFIMODE | MFI_INIT_ABORT)
110 
111 /*
112  * MFI frame flags
113  */
114 #define	MFI_FRAME_DONT_POST_IN_REPLY_QUEUE	0x0001
115 #define	MFI_FRAME_SGL64				0x0002
116 #define	MFI_FRAME_SENSE64			0x0004
117 #define	MFI_FRAME_DIR_NONE			0
118 #define	MFI_FRAME_DIR_WRITE			0x0008
119 #define	MFI_FRAME_DIR_READ			0x0010
120 #define	MFI_FRAME_DIR_BOTH			0x0018
121 #define	MFI_FRAME_IEEE				0x0020
122 
123 /*
124  * MFI command opcodes
125  */
126 #define	MFI_CMD_INIT				0x00
127 #define	MFI_CMD_LD_READ				0x01
128 #define	MFI_CMD_LD_WRITE			0x02
129 #define	MFI_CMD_LD_SCSI_IO			0x03
130 #define	MFI_CMD_PD_SCSI_IO			0x04
131 #define	MFI_CMD_DCMD				0x05
132 #define	MFI_CMD_ABORT				0x06
133 #define	MFI_CMD_SMP				0x07
134 #define	MFI_CMD_STP				0x08
135 #define	MFI_CMD_INVALID				0xff
136 
137 /*
138  * MFI command status completion codes
139  */
140 #define	MFI_STAT_OK				0x00
141 #define	MFI_STAT_INVALID_CMD			0x01
142 #define	MFI_STAT_INVALID_DCMD			0x02
143 #define	MFI_STAT_INVALID_PARAMETER		0x03
144 #define	MFI_STAT_INVALID_SEQUENCE_NUMBER	0x04
145 #define	MFI_STAT_ABORT_NOT_POSSIBLE		0x05
146 #define	MFI_STAT_APP_HOST_CODE_NOT_FOUND	0x06
147 #define	MFI_STAT_APP_IN_USE			0x07
148 #define	MFI_STAT_APP_NOT_INITIALIZED		0x08
149 #define	MFI_STAT_ARRAY_INDEX_INVALID		0x09
150 #define	MFI_STAT_ARRAY_ROW_NOT_EMPTY		0x0a
151 #define	MFI_STAT_CONFIG_RESOURCE_CONFLICT	0x0b
152 #define	MFI_STAT_DEVICE_NOT_FOUND		0x0c
153 #define	MFI_STAT_DRIVE_TOO_SMALL		0x0d
154 #define	MFI_STAT_FLASH_ALLOC_FAIL		0x0e
155 #define	MFI_STAT_FLASH_BUSY			0x0f
156 #define	MFI_STAT_FLASH_ERROR			0x10
157 #define	MFI_STAT_FLASH_IMAGE_BAD		0x11
158 #define	MFI_STAT_FLASH_IMAGE_INCOMPLETE		0x12
159 #define	MFI_STAT_FLASH_NOT_OPEN			0x13
160 #define	MFI_STAT_FLASH_NOT_STARTED		0x14
161 #define	MFI_STAT_FLUSH_FAILED			0x15
162 #define	MFI_STAT_HOST_CODE_NOT_FOUNT		0x16
163 #define	MFI_STAT_LD_CC_IN_PROGRESS		0x17
164 #define	MFI_STAT_LD_INIT_IN_PROGRESS		0x18
165 #define	MFI_STAT_LD_LBA_OUT_OF_RANGE		0x19
166 #define	MFI_STAT_LD_MAX_CONFIGURED		0x1a
167 #define	MFI_STAT_LD_NOT_OPTIMAL			0x1b
168 #define	MFI_STAT_LD_RBLD_IN_PROGRESS		0x1c
169 #define	MFI_STAT_LD_RECON_IN_PROGRESS		0x1d
170 #define	MFI_STAT_LD_WRONG_RAID_LEVEL		0x1e
171 #define	MFI_STAT_MAX_SPARES_EXCEEDED		0x1f
172 #define	MFI_STAT_MEMORY_NOT_AVAILABLE		0x20
173 #define	MFI_STAT_MFC_HW_ERROR			0x21
174 #define	MFI_STAT_NO_HW_PRESENT			0x22
175 #define	MFI_STAT_NOT_FOUND			0x23
176 #define	MFI_STAT_NOT_IN_ENCL			0x24
177 #define	MFI_STAT_PD_CLEAR_IN_PROGRESS		0x25
178 #define	MFI_STAT_PD_TYPE_WRONG			0x26
179 #define	MFI_STAT_PR_DISABLED			0x27
180 #define	MFI_STAT_ROW_INDEX_INVALID		0x28
181 #define	MFI_STAT_SAS_CONFIG_INVALID_ACTION	0x29
182 #define	MFI_STAT_SAS_CONFIG_INVALID_DATA	0x2a
183 #define	MFI_STAT_SAS_CONFIG_INVALID_PAGE	0x2b
184 #define	MFI_STAT_SAS_CONFIG_INVALID_TYPE	0x2c
185 #define	MFI_STAT_SCSI_DONE_WITH_ERROR		0x2d
186 #define	MFI_STAT_SCSI_IO_FAILED			0x2e
187 #define	MFI_STAT_SCSI_RESERVATION_CONFLICT	0x2f
188 #define	MFI_STAT_SHUTDOWN_FAILED		0x30
189 #define	MFI_STAT_TIME_NOT_SET			0x31
190 #define	MFI_STAT_WRONG_STATE			0x32
191 #define	MFI_STAT_LD_OFFLINE			0x33
192 #define	MFI_STAT_PEER_NOTIFICATION_REJECTED	0x34
193 #define	MFI_STAT_PEER_NOTIFICATION_FAILED	0x35
194 #define	MFI_STAT_RESERVATION_IN_PROGRESS	0x36
195 #define	MFI_STAT_I2C_ERRORS_DETECTED		0x37
196 #define	MFI_STAT_PCI_ERRORS_DETECTED		0x38
197 #define	MFI_STAT_CONFIG_SEQ_MISMATCH		0x67
198 
199 #define	MFI_STAT_INVALID_STATUS			0xFF
200 
201 /*
202  * MFI DCMDs
203  */
204 #define	MFI_DCMD_CTRL_GET_INFO			0x01010000
205 #define	MFI_DCMD_CTRL_GET_PROPS			0x01020100
206 #define	MFI_DCMD_CTRL_SET_PROPS			0x01020200
207 #define	MFI_DCMD_CTRL_EVENT_GET_INFO		0x01040100
208 #define	MFI_DCMD_CTRL_EVENT_GET			0x01040300
209 #define	MFI_DCMD_CTRL_EVENT_WAIT		0x01040500
210 #define	MFI_DCMD_CTRL_SHUTDOWN			0x01050000
211 #define	MFI_DCMD_PR_GET_STATUS			0x01070100
212 #define	MFI_DCMD_PR_GET_PROPERTIES		0x01070200
213 #define	MFI_DCMD_PR_SET_PROPERTIES		0x01070300
214 #define	MFI_DCMD_PR_START			0x01070400
215 #define	MFI_DCMD_PR_STOP			0x01070500
216 #define	MFI_DCMD_TIME_SECS_GET			0x01080201
217 #define	MFI_DCMD_FLASH_FW_OPEN			0x010f0100
218 #define	MFI_DCMD_FLASH_FW_DOWNLOAD		0x010f0200
219 #define	MFI_DCMD_FLASH_FW_FLASH			0x010f0300
220 #define	MFI_DCMD_FLASH_FW_CLOSE			0x010f0400
221 #define	MFI_DCMD_SYSTEM_PD_MAP_GET_INFO		0x0200e102
222 #define	MFI_DCMD_PD_GET_LIST			0x02010000
223 #define	MFI_DCMD_PD_LIST_QUERY			0x02010100
224 #define	MFI_DCMD_PD_GET_INFO			0x02020000
225 #define	MFI_DCMD_PD_STATE_SET			0x02030100
226 #define	MFI_DCMD_PD_REBUILD_START		0x02040100
227 #define	MFI_DCMD_PD_REBUILD_ABORT		0x02040200
228 #define	MFI_DCMD_PD_CLEAR_START			0x02050100
229 #define	MFI_DCMD_PD_CLEAR_ABORT			0x02050200
230 #define	MFI_DCMD_PD_LOCATE_START		0x02070100
231 #define	MFI_DCMD_PD_LOCATE_STOP			0x02070200
232 #define	MFI_DCMD_LD_MAP_GET_INFO		0x0300e101
233 #define	MFI_DCMD_LD_GET_LIST			0x03010000
234 #define	MFI_DCMD_LD_GET_INFO			0x03020000
235 #define	MFI_DCMD_LD_GET_PROP			0x03030000
236 #define	MFI_DCMD_LD_SET_PROP			0x03040000
237 #define	MFI_DCMD_LD_LIST_QUERY			0x03010100
238 #define	MFI_DCMD_LD_DELETE			0x03090000
239 #define	MFI_DCMD_CFG_READ			0x04010000
240 #define	MFI_DCMD_CFG_ADD			0x04020000
241 #define	MFI_DCMD_CFG_CLEAR			0x04030000
242 #define	MFI_DCMD_CFG_MAKE_SPARE			0x04040000
243 #define	MFI_DCMD_CFG_REMOVE_SPARE		0x04050000
244 #define	MFI_DCMD_CFG_FOREIGN_SCAN		0x04060100
245 #define	MFI_DCMD_CFG_FOREIGN_DISPLAY		0x04060200
246 #define	MFI_DCMD_CFG_FOREIGN_PREVIEW		0x04060300
247 #define	MFI_DCMD_CFG_FOREIGN_IMPORT		0x04060400
248 #define	MFI_DCMD_CFG_FOREIGN_CLEAR		0x04060500
249 #define	MFI_DCMD_BBU_GET_STATUS			0x05010000
250 #define	MFI_DCMD_BBU_GET_CAPACITY_INFO		0x05020000
251 #define	MFI_DCMD_BBU_GET_DESIGN_INFO		0x05030000
252 #define	MFI_DCMD_BBU_START_LEARN		0x05040000
253 #define	MFI_DCMD_BBU_GET_PROP			0x05050100
254 #define	MFI_DCMD_BBU_SET_PROP			0x05050200
255 
256 #define	MFI_BBU_TYPE_NONE			0
257 #define	MFI_BBU_TYPE_IBBU			1
258 #define	MFI_BBU_TYPE_BBU			2
259 
260 #define	MFI_PR_STATE_STOPPED			0
261 #define	MFI_PR_STATE_READY			1
262 #define	MFI_PR_STATE_ACTIVE			2
263 #define	MFI_PR_STATE_ABORTED			3
264 
265 #define	MFI_PR_OPMODE_AUTO			0
266 #define	MFI_PR_OPMODE_MANUAL			1
267 #define	MFI_PR_OPMODE_DISABLED			2
268 
269 #define	MFI_PD_QUERY_TYPE_ALL			0
270 #define	MFI_PD_QUERY_TYPE_STATE			1
271 #define	MFI_PD_QUERY_TYPE_POWER_STATE		2
272 #define	MFI_PD_QUERY_TYPE_MEDIA_TYPE		3
273 #define	MFI_PD_QUERY_TYPE_SPEED			4
274 #define	MFI_PD_QUERY_TYPE_EXPOSED_TO_HOST	5
275 
276 #define	MFI_LD_QUERY_TYPE_ALL			0
277 #define	MFI_LD_QUERY_TYPE_EXPOSED_TO_HOST	1
278 #define	MFI_LD_QUERY_TYPE_USED_TGT_IDS		2
279 #define	MFI_LD_QUERY_TYPE_CLUSTER_ACCESS	3
280 #define	MFI_LD_QUERY_TYPE_CLUSTER_LOCALE	4
281 
282 #define	MFI_DCMD_MBOX_PEND_FLAG	0x01
283 
284 #pragma pack(1)
285 
286 union mfi_cap {
287 	struct {
288 		uint32_t mc_support_fp_remote_lun:1;
289 		uint32_t mc_support_additional_msix:1;
290 		uint32_t mc_support_fastpath_wb:1;
291 		uint32_t mc_support_max_255lds:1;
292 		uint32_t mc_support_ndrive_r1_lb:1;
293 		uint32_t mc_support_core_affinity:1;
294 		uint32_t mc_support_security_protocol_cmds_fw:1;
295 		uint32_t mc_support_ext_queue_depth:1;
296 		uint32_t mc_support_ext_io_size:1;
297 		uint32_t mc_reserved:23;
298 	};
299 	uint32_t	mc_reg;
300 };
301 CTASSERT(sizeof (mfi_cap_t) == 4);
302 
303 union mfi_sgl {
304 	struct {
305 		uint32_t	ms32_phys_addr;
306 		uint32_t	ms32_length;
307 	};
308 	struct {
309 		uint64_t	ms64_phys_addr;
310 		uint32_t	ms64_length;
311 	};
312 };
313 
314 struct mfi_header {
315 	uint8_t		mh_cmd;				/* 0x00 */
316 	uint8_t		mh_sense_len;			/* 0x01 */
317 	uint8_t		mh_cmd_status;			/* 0x02 */
318 	uint8_t		mh_scsi_status;			/* 0x03 */
319 
320 	union {
321 		mfi_cap_t	mh_drv_opts;		/* 0x04 */
322 		struct {
323 			uint8_t	mh_target_id;		/* 0x04 */
324 			union {
325 				uint8_t	mh_lun;		/* 0x05 */
326 				uint8_t mh_access_byte;	/* 0x05 */
327 			};
328 			uint8_t mh_cdb_len;		/* 0x06 */
329 			uint8_t mh_sge_count;		/* 0x07 */
330 		};
331 	};
332 
333 	uint32_t	mh_context;			/* 0x08 */
334 	uint32_t	mh_pad_0;			/* 0x0c */
335 
336 	uint16_t	mh_flags;			/* 0x10 */
337 	uint16_t	mh_timeout;			/* 0x12 */
338 	union {
339 		uint32_t mh_data_xfer_len;		/* 0x14 */
340 		uint32_t mh_lba_count;			/* 0x14 */
341 	};
342 };
343 
344 struct mfi_init_payload {
345 	uint64_t	mi_queue_info_new_phys_addr;	/* 0x18 */
346 	uint64_t	mi_queue_info_old_phys_addr;	/* 0x20 */
347 	uint64_t	mi_driver_ver_phys_addr;	/* 0x28 */
348 };
349 
350 struct mfi_io_payload {
351 	uint64_t	mio_sense_buf_phys_addr;	/* 0x18 */
352 	uint64_t	mio_start_lba;			/* 0x20 */
353 	mfi_sgl_t	mio_sgl;			/* 0x28 */
354 };
355 
356 struct mfi_pthru_payload {
357 	uint64_t	mp_sense_buf_phys_addr;		/* 0x18 */
358 	uint8_t		mp_cdb[16];			/* 0x20 */
359 	mfi_sgl_t	mp_sgl;				/* 0x30 */
360 };
361 
362 struct mfi_dcmd_payload {
363 	uint32_t	md_opcode;			/* 0x18 */
364 
365 	union {						/* 0x1c */
366 		uint8_t		md_mbox_8[12];
367 		uint16_t	md_mbox_16[6];
368 		uint32_t	md_mbox_32[3];
369 	};
370 
371 	mfi_sgl_t	md_sgl;				/* 0x28 */
372 };
373 
374 struct mfi_abort_payload {
375 	uint32_t	ma_abort_context;		/* 0x18 */
376 	uint32_t	ma_pad_1;			/* 0x1c */
377 	uint64_t	ma_abort_mfi_phys_addr;		/* 0x20 */
378 };
379 
380 struct mfi_frame {
381 	mfi_header_t	mf_hdr;
382 	union {
383 		mfi_init_payload_t	mf_init;
384 		mfi_io_payload_t	mf_io;
385 		mfi_pthru_payload_t	mf_pthru;
386 		mfi_dcmd_payload_t	mf_dcmd;
387 		mfi_abort_payload_t	mf_abort;
388 		uint8_t mf_raw[64 - sizeof (mfi_header_t)];
389 	};
390 };
391 CTASSERT(offsetof(mfi_frame_t, mf_init) == 0x18);
392 CTASSERT(sizeof (mfi_frame_t) == 64);
393 
394 
395 /*
396  * MFI controller properties
397  */
398 struct mfi_ctrl_props {
399 	uint16_t cp_seq_num;
400 	uint16_t cp_pred_fail_poll_interval;
401 	uint16_t cp_intr_throttle_count;
402 	uint16_t cp_intr_throttle_timeouts;
403 	uint8_t cp_rebuild_rate;
404 	uint8_t cp_patrol_read_rate;
405 	uint8_t cp_bgi_rate;
406 	uint8_t cp_cc_rate;
407 	uint8_t cp_recon_rate;
408 	uint8_t cp_cache_flush_interval;
409 	uint8_t cp_spinup_drv_count;
410 	uint8_t cp_spinup_delay;
411 	uint8_t cp_cluster_enable;
412 	uint8_t cp_coercion_mode;
413 	uint8_t cp_alarm_enable;
414 	uint8_t cp_disable_auto_rebuild;
415 	uint8_t cp_disable_battery_warn;
416 	uint8_t cp_ecc_bucket_size;
417 	uint16_t cp_ecc_bucket_leak_rate;
418 	uint8_t cp_restore_hotspare_on_insertion;
419 	uint8_t cp_expose_encl_devices;
420 	uint8_t cp_maintain_pd_fail_history;
421 	uint8_t cp_disallow_host_request_reordering;
422 	uint8_t cp_abort_cc_on_error;
423 	uint8_t cp_load_balance_mode;
424 	uint8_t cp_disable_auto_detect_backplane;
425 	uint8_t cp_snap_vd_space;
426 
427 	struct {
428 		uint32_t cp_copy_back_disabled:1;
429 		uint32_t cp_smarter_enabled:1;
430 		uint32_t cp_pr_correct_unconfigured_areas:1;
431 		uint32_t cp_use_FDE_only:1;
432 		uint32_t cp_disable_NCQ:1;
433 		uint32_t cp_SSD_smarter_enabled:1;
434 		uint32_t cp_SSD_patrol_read_enabled:1;
435 		uint32_t cp_enable_spin_down_unconfigured:1;
436 		uint32_t cp_auto_enhanced_import:1;
437 		uint32_t cp_enable_secret_key_control:1;
438 		uint32_t cp_disable_online_ctrl_reset:1;
439 		uint32_t cp_allow_boot_with_pinned_cache:1;
440 		uint32_t cp_disable_spin_down_HS:1;
441 		uint32_t cp_enable_JBOD:1;
442 		uint32_t cp_disable_cache_bypass:1;
443 		uint32_t cp_use_disk_activity_for_locate:1;
444 		uint32_t cp_enable_PI:1;
445 		uint32_t cp_prevent_PI_import:1;
446 		uint32_t cp_use_global_spares_for_emergency:1;
447 		uint32_t cp_use_unconf_good_for_emergency:1;
448 		uint32_t cp_use_emergency_spares_for_smarter:1;
449 		uint32_t cp_force_sgpio_for_quad_only:1;
450 		uint32_t cp_enable_config_auto_balance:1;
451 		uint32_t cp_enable_virtual_cache:1;
452 		uint32_t cp_enable_auto_lock_recovery:1;
453 		uint32_t cp_disable_immediate_io:1;
454 		uint32_t cp_disable_T10_rebuild_assist:1;
455 		uint32_t cp_ignore64_ld_restriction:1;
456 		uint32_t cp_enable_sw_zone:1;
457 		uint32_t cp_limit_max_rate_SATA_3G:1;
458 		uint32_t cp_reserved:2;
459 	};
460 	uint8_t cp_auto_snap_vd_space;
461 	uint8_t cp_view_space;
462 	uint16_t cp_spin_down_time;
463 	uint8_t cp_reserved2[24];
464 };
465 CTASSERT(sizeof (mfi_ctrl_props_t) == 64);
466 
467 /*
468  * MFI firmware image component
469  */
470 struct mfi_image_comp {
471 	char ic_name[8];
472 	char ic_version[32];
473 	char ic_build_date[16];
474 	char ic_build_time[16];
475 };
476 CTASSERT(sizeof (mfi_image_comp_t) == 72);
477 
478 /*
479  * MFI controller information
480  */
481 struct mfi_ctrl_info {
482 	/* PCI device information */
483 	struct {
484 		uint16_t pci_vendor_id;
485 		uint16_t pci_device_id;
486 		uint16_t pci_sub_vendor_id;
487 		uint16_t pci_sub_device_id;
488 		uint8_t pci_reserved[24];
489 	} ci_pci;
490 
491 	/* Host interface information */
492 	struct {
493 		uint8_t hi_PCIX:1;
494 		uint8_t hi_PCIE:1;
495 		uint8_t hi_iSCSI:1;
496 		uint8_t hi_SAS_3G:1;
497 		uint8_t hi_reserved_0:4;
498 		uint8_t hi_reserved_1[6];
499 		uint8_t hi_port_count;
500 		uint64_t hi_port_addr[8];
501 	} ci_host_interface;
502 
503 	/* Target interface information */
504 	struct {
505 		uint8_t di_SPI:1;
506 		uint8_t di_SAS_3G:1;
507 		uint8_t di_SATA_1_5G:1;
508 		uint8_t di_SATA_3G:1;
509 		uint8_t di_reserved_0:4;
510 		uint8_t di_reserved_1[6];
511 		uint8_t di_port_count;
512 		uint64_t di_port_addr[8];
513 	} ci_device_interface;
514 
515 	uint32_t ci_image_check_word;
516 
517 	uint32_t ci_image_component_count;
518 	mfi_image_comp_t ci_image_component[8];
519 
520 	uint32_t ci_pending_image_component_count;
521 	mfi_image_comp_t ci_pending_image_component[8];
522 
523 	uint8_t ci_max_arms;
524 	uint8_t ci_max_spans;
525 	uint8_t ci_max_arrays;
526 	uint8_t ci_max_lds;
527 	char ci_product_name[80];
528 	char ci_serial_no[32];
529 
530 	/*
531 	 * Hardware features
532 	 */
533 	struct {
534 		uint32_t hw_bbu:1;
535 		uint32_t hw_alarm:1;
536 		uint32_t hw_nvram:1;
537 		uint32_t hw_uart:1;
538 		uint32_t hw_reserved:28;
539 	} ci_hw_present;
540 
541 	uint32_t ci_current_fw_time;
542 
543 	/* Maximum data transfer sizes */
544 	uint16_t ci_max_concurrent_cmds;
545 	uint16_t ci_max_sge_count;
546 	uint32_t ci_max_request_size;
547 
548 	/* Logical and physical device counts */
549 	uint16_t ci_ld_present_count;
550 	uint16_t ci_ld_degraded_count;
551 	uint16_t ci_ld_offline_count;
552 
553 	uint16_t ci_pd_present_count;
554 	uint16_t ci_pd_disk_present_count;
555 	uint16_t ci_pd_disk_pred_failure_count;
556 	uint16_t ci_pd_disk_failed_count;
557 
558 	/* Memory size information */
559 	uint16_t ci_nvram_size;
560 	uint16_t ci_memory_size;
561 	uint16_t ci_flash_size;
562 
563 	/* Error counters */
564 	uint16_t ci_mem_correctable_error_count;
565 	uint16_t ci_mem_uncorrectable_error_count;
566 
567 	/* Cluster information */
568 	uint8_t ci_cluster_permitted;
569 	uint8_t ci_cluster_active;
570 
571 	/* Additional max data transfer sizes */
572 	uint16_t ci_max_stripes_per_io;
573 
574 	/* Controller capabilities structures */
575 	struct {
576 		uint32_t rl_raid_level_0:1;
577 		uint32_t rl_raid_level_1:1;
578 		uint32_t rl_raid_level_5:1;
579 		uint32_t rl_raid_level_1E:1;
580 		uint32_t rl_raid_level_6:1;
581 		uint32_t rl_reserved:27;
582 	} ci_raid_levels;
583 
584 	struct {
585 		uint32_t ao_rbld_rate:1;
586 		uint32_t ao_cc_rate:1;
587 		uint32_t ao_bgi_rate:1;
588 		uint32_t ao_recon_rate:1;
589 		uint32_t ao_patrol_rate:1;
590 		uint32_t ao_alarm_control:1;
591 		uint32_t ao_cluster_supported:1;
592 		uint32_t ao_bbu:1;
593 		uint32_t ao_spanning_allowed:1;
594 		uint32_t ao_dedicated_hotspares:1;
595 		uint32_t ao_revertible_hotspares:1;
596 		uint32_t ao_foreign_config_import:1;
597 		uint32_t ao_self_diagnostic:1;
598 		uint32_t ao_mixed_redundancy_arr:1;
599 		uint32_t ao_global_hot_spares:1;
600 		uint32_t ao_reserved:17;
601 	} ci_adapter_opts;
602 
603 	struct {
604 		uint32_t ld_read_policy:1;
605 		uint32_t ld_write_policy:1;
606 		uint32_t ld_io_policy:1;
607 		uint32_t ld_access_policy:1;
608 		uint32_t ld_disk_cache_policy:1;
609 		uint32_t ld_reserved:27;
610 	} ci_ld_opts;
611 
612 	struct {
613 		uint8_t raid_stripe_sz_min;
614 		uint8_t raid_stripe_sz_max;
615 		uint8_t raid_reserved[2];
616 	} ci_raid_opts;
617 
618 	struct {
619 		uint32_t pd_force_online:1;
620 		uint32_t pd_force_offline:1;
621 		uint32_t pd_force_rebuild:1;
622 		uint32_t pd_reserved:29;
623 	} ci_pd_opts;
624 
625 	struct {
626 		uint32_t pd_ctrl_supports_sas:1;
627 		uint32_t pd_ctrl_supports_sata:1;
628 		uint32_t pd_allow_mix_in_encl:1;
629 		uint32_t pd_allow_mix_in_ld:1;
630 		uint32_t pd_allow_sata_in_cluster:1;
631 		uint32_t pd_reserved:27;
632 	} ci_pd_mix_support;
633 
634 	/* ECC single-bit error bucket information */
635 	uint8_t ci_ecc_bucket_count;
636 	uint8_t ci_reserved_2[11];
637 
638 	/* Controller properties */
639 	mfi_ctrl_props_t ci_prop;
640 
641 	char ci_package_version[0x60];
642 
643 	uint64_t ci_device_interface_port_addr2[8];
644 	uint8_t ci_reserved3[128];
645 
646 	struct {
647 		uint16_t pd_min_pd_raid_level_0:4;
648 		uint16_t pd_max_pd_raid_level_0:12;
649 
650 		uint16_t pd_min_pd_raid_level_1:4;
651 		uint16_t pd_max_pd_raid_level_1:12;
652 
653 		uint16_t pd_min_pd_raid_level_5:4;
654 		uint16_t pd_max_pd_raid_level_5:12;
655 
656 		uint16_t pd_min_pd_raid_level_1E:4;
657 		uint16_t pd_max_pd_raid_level_1E:12;
658 
659 		uint16_t pd_min_pd_raid_level_6:4;
660 		uint16_t pd_max_pd_raid_level_6:12;
661 
662 		uint16_t pd_min_pd_raid_level_10:4;
663 		uint16_t pd_max_pd_raid_level_10:12;
664 
665 		uint16_t pd_min_pd_raid_level_50:4;
666 		uint16_t pd_max_pd_raid_level_50:12;
667 
668 		uint16_t pd_min_pd_raid_level_60:4;
669 		uint16_t pd_max_pd_raid_level_60:12;
670 
671 		uint16_t pd_min_pd_raid_level_1E_RLQ0:4;
672 		uint16_t pd_max_pd_raid_level_1E_RLQ0:12;
673 
674 		uint16_t pd_min_pd_raid_level_1E0_RLQ0:4;
675 		uint16_t pd_max_pd_raid_level_1E0_RLQ0:12;
676 
677 		uint16_t pd_reserved[6];
678 	} ci_pds_for_raid_levels;
679 
680 	uint16_t ci_max_pds;			/* 0x780 */
681 	uint16_t ci_max_ded_HSPs;		/* 0x782 */
682 	uint16_t ci_max_global_HSPs;		/* 0x784 */
683 	uint16_t ci_ddf_size;			/* 0x786 */
684 	uint8_t ci_max_lds_per_array;		/* 0x788 */
685 	uint8_t ci_partitions_in_DDF;		/* 0x789 */
686 	uint8_t ci_lock_key_binding;		/* 0x78a */
687 	uint8_t ci_max_PITs_per_ld;		/* 0x78b */
688 	uint8_t ci_max_views_per_ld;		/* 0x78c */
689 	uint8_t ci_max_target_id;		/* 0x78d */
690 	uint16_t ci_max_bvl_vd_size;		/* 0x78e */
691 
692 	uint16_t ci_max_configurable_SSC_size;	/* 0x790 */
693 	uint16_t ci_current_SSC_size;		/* 0x792 */
694 
695 	char ci_expander_fw_version[12];	/* 0x794 */
696 
697 	uint16_t ci_PFK_trial_time_remaining;	/* 0x7A0 */
698 
699 	uint16_t ci_cache_memory_size;		/* 0x7A2 */
700 
701 	struct {				/* 0x7A4 */
702 		uint32_t ao2_support_PI_controller:1;
703 		uint32_t ao2_support_ld_PI_type1:1;
704 		uint32_t ao2_support_ld_PI_type2:1;
705 		uint32_t ao2_support_ld_PI_type3:1;
706 		uint32_t ao2_support_ld_BBM_info:1;
707 		uint32_t ao2_support_shield_state:1;
708 		uint32_t ao2_block_SSD_write_cache_change:1;
709 		uint32_t ao2_support_suspend_resume_b_Gops:1;
710 		uint32_t ao2_support_emergency_spares:1;
711 		uint32_t ao2_support_set_link_speed:1;
712 		uint32_t ao2_support_boot_time_PFK_change:1;
713 		uint32_t ao2_support_JBOD:1;
714 		uint32_t ao2_disable_online_PFK_change:1;
715 		uint32_t ao2_support_perf_tuning:1;
716 		uint32_t ao2_support_SSD_patrol_read:1;
717 		uint32_t ao2_real_time_scheduler:1;
718 
719 		uint32_t ao2_support_reset_now:1;
720 		uint32_t ao2_support_emulated_drives:1;
721 		uint32_t ao2_headless_mode:1;
722 		uint32_t ao2_dedicated_hot_spares_limited:1;
723 
724 		uint32_t ao2_support_uneven_spans:1;
725 		uint32_t ao2_reserved:11;
726 	} ci_adapter_opts2;
727 
728 	uint8_t ci_driver_version[32];		/* 0x7A8 */
729 	uint8_t ci_max_DAP_d_count_spinup60;	/* 0x7C8 */
730 	uint8_t ci_temperature_ROC;		/* 0x7C9 */
731 	uint8_t ci_temperature_ctrl;		/* 0x7CA */
732 	uint8_t ci_reserved4;			/* 0x7CB */
733 	uint16_t ci_max_configurable_pds;	/* 0x7CC */
734 
735 	uint8_t ci_reserved5[2];		/* 0x7CD reserved */
736 
737 	struct {
738 		uint32_t cl_peer_is_present:1;
739 		uint32_t cl_peer_is_incompatible:1;
740 
741 		uint32_t cl_hw_incompatible:1;
742 		uint32_t cl_fw_version_mismatch:1;
743 		uint32_t cl_ctrl_prop_incompatible:1;
744 		uint32_t cl_premium_feature_mismatch:1;
745 		uint32_t cl_reserved:26;
746 	} ci_cluster;
747 
748 	char ci_cluster_id[16];			/* 0x7D4 */
749 
750 	char ci_reserved6[4];			/* 0x7E4 RESERVED FOR IOV */
751 
752 	struct {				/* 0x7E8 */
753 		uint32_t ao3_support_personality_change:2;
754 		uint32_t ao3_support_thermal_poll_interval:1;
755 		uint32_t ao3_support_disable_immediate_IO:1;
756 		uint32_t ao3_support_T10_rebuild_assist:1;
757 		uint32_t ao3_support_max_ext_lds:1;
758 		uint32_t ao3_support_crash_dump:1;
759 		uint32_t ao3_support_sw_zone:1;
760 		uint32_t ao3_support_debug_queue:1;
761 		uint32_t ao3_support_NV_cache_erase:1;
762 		uint32_t ao3_support_force_to_512e:1;
763 		uint32_t ao3_support_HOQ_rebuild:1;
764 		uint32_t ao3_support_allowed_opsfor_drv_removal:1;
765 		uint32_t ao3_support_drv_activity_LED_setting:1;
766 		uint32_t ao3_support_NVDRAM:1;
767 		uint32_t ao3_support_force_flash:1;
768 		uint32_t ao3_support_disable_SES_monitoring:1;
769 		uint32_t ao3_support_cache_bypass_modes:1;
770 		uint32_t ao3_support_securityon_JBOD:1;
771 		uint32_t ao3_discard_cache_during_ld_delete:1;
772 		uint32_t ao3_support_TTY_log_compression:1;
773 		uint32_t ao3_support_CPLD_update:1;
774 		uint32_t ao3_support_disk_cache_setting_for_sys_pds:1;
775 		uint32_t ao3_support_extended_SSC_size:1;
776 		uint32_t ao3_use_seq_num_jbod_FP:1;
777 		uint32_t ao3_reserved:7;
778 	} ci_adapter_opts3;
779 
780 	uint8_t ci_pad_cpld[16];
781 
782 	struct {
783 		uint16_t ao4_ctrl_info_ext_supported:1;
784 		uint16_t ao4_support_ibutton_less:1;
785 		uint16_t ao4_supported_enc_algo:1;
786 		uint16_t ao4_support_encrypted_mfc:1;
787 		uint16_t ao4_image_upload_supported:1;
788 		uint16_t ao4_support_SES_ctrl_in_multipath_cfg:1;
789 		uint16_t ao4_support_pd_map_target_id:1;
790 		uint16_t ao4_fw_swaps_bbu_vpd_info:1;
791 		uint16_t ao4_reserved:8;
792 	} ci_adapter_opts4;
793 
794 	uint8_t ci_pad[0x800 - 0x7FE];	/* 0x7FE */
795 };
796 CTASSERT(sizeof (mfi_ctrl_info_t) == 0x800);
797 
798 /*
799  * PR (patrol read) properties & status
800  */
801 struct mfi_pr_properties {
802 	uint8_t		pp_op_mode;
803 	uint8_t		pp_max_pd;
804 	uint8_t		pp_rsvd;
805 	uint8_t		pp_exclude_ld_cnt;
806 	uint16_t	pp_excluded_ld[MFI_MAX_LOGICAL_DRIVES];
807 	uint8_t		pp_cur_pd_map[MFI_MAX_PHYSICAL_DRIVES / 8];
808 	uint8_t		pp_last_pd_map[MFI_MAX_PHYSICAL_DRIVES / 8];
809 	uint32_t	pp_next_exec;
810 	uint32_t	pp_exec_freq;
811 	uint32_t	pp_clear_freq;
812 };
813 
814 struct mfi_pr_status {
815 	uint32_t	ps_num_iteration;
816 	uint8_t		ps_state;
817 	uint8_t		ps_num_pd_done;
818 	uint8_t		ps_rsvd[10];
819 };
820 
821 struct mfi_progress {
822 	uint16_t	mp_progress;
823 	uint16_t	mp_elapsed;
824 };
825 CTASSERT(sizeof (mfi_progress_t) == 4);
826 
827 #pragma pack(0)
828 
829 #ifdef __cplusplus
830 }
831 #endif
832 
833 #endif	/* _MFI_H */
834