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 Oxide Computer Company
14  */
15 
16 #ifndef _SYS_NVME_WDC_SN840_H
17 #define	_SYS_NVME_WDC_SN840_H
18 
19 /*
20  * This header defines vendor-specific NVMe interfaces and is not a committed
21  * interface. Its contents and existence are subject to change.
22  *
23  * Vendor-specific definitions for the WDC SN840 NVMe device.
24  */
25 
26 #include <sys/debug.h>
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 
32 #define	WDC_SN840_DID	0x2500
33 
34 typedef enum {
35 	/*
36 	 * This log is the fixed wdc_vul_sn840_eol_t structure.
37 	 */
38 	WDC_SN840_LOG_EOL		= 0xc0,
39 	/*
40 	 * This log uses the wdc_log_vsd_t with a series of different entry
41 	 * types.
42 	 */
43 	WDC_SN840_LOG_DEV_MANAGE	= 0xc2,
44 	/*
45 	 * While this log exists, we do not know the data format of it.
46 	 */
47 	WDC_SN840_LOG_PCIE_SI		= 0xc4,
48 	/*
49 	 * This uses the common wdc_vul_power_t structure.
50 	 */
51 	WDC_SN840_LOG_POWER		= 0xc5,
52 	/*
53 	 * This uses the common wdc_vul_temp_t structure. The specific
54 	 * measurements are recorded in the wdc_log_sn840_temp_t.
55 	 */
56 	WDC_SN840_LOG_TEMP		= 0xc6,
57 	/*
58 	 * The firmware activation log uses the wdc_sn840_fw_act_hdr_t stucture
59 	 * as a header and then is followed by one or more
60 	 * wdc_vul_sn840_fw_act_ent_t structures that have entry information.
61 	 */
62 	WDC_SN840_LOG_FW_ACT		= 0xcb,
63 	/*
64 	 * This log uses the wdc_vul_sn840_ccds_info_t structure.
65 	 */
66 	WDC_SN840_LOG_CCDS		= 0xfa
67 } wdc_sn840_vul_t;
68 
69 /*
70  * All data structures must be packed to account for the layout from the various
71  * programmer's manuals.
72  */
73 #pragma pack(1)
74 
75 /*
76  * Device EOL Log Page
77  */
78 typedef struct {
79 	uint8_t		eol_rsvd0[76];
80 	uint32_t	eol_rbc;
81 	uint8_t		eol_rsvd1[4];
82 	uint32_t	eol_waf;
83 	uint32_t	eol_plr;
84 	uint8_t		eol_rsvd2[4];
85 	uint32_t	eol_pfc;
86 	uint32_t	eol_efc;
87 	uint8_t		eol_rss3[4];
88 	uint32_t	eol_vendor;
89 	uint16_t	eol_cust_sts;
90 	uint16_t	eol_sys_sts;
91 	uint8_t		eol_cust_state;
92 	uint8_t		eol_sys_state;
93 } wdc_vul_sn840_eol_t;
94 
95 /*
96  * Smatch can't handle packed structure sizeof calculations correctly,
97  * unfortunately.
98  */
99 #ifndef __CHECKER__
100 CTASSERT(sizeof (wdc_vul_sn840_eol_t) == 118);
101 #endif
102 
103 typedef enum {
104 	WDC_SN840_VSD_ID		= 0x01,		/* uint32_t */
105 	WDC_SN840_VSD_UEFI_VER		= 0x02,		/* CBS */
106 	WDC_SN840_VSD_SBL_VER		= 0x03,		/* CBS */
107 	WDC_SN840_VSD_DEF_USER_CAP	= 0x04,		/* uint64_t */
108 	WDC_SN840_VSD_MAX_USER_CAP	= 0x05,		/* uint64_t */
109 	WDC_SN840_VSD_MIN_USER_CAP	= 0x06,		/* uint64_t */
110 	WDC_SN840_VSD_NAME		= 0x07,		/* CBS */
111 	WDC_SN840_VSD_LOG_SUP		= 0x08,		/* CBS */
112 	WDC_SN840_VSD_FEAT_SUP		= 0x09,		/* CBS */
113 	WDC_SN840_VSD_FORM_FACTOR	= 0x0a,		/* uint32_t */
114 	WDC_SN840_VSD_RESIZE_GRAN	= 0x0b,		/* uint64_t */
115 	WDC_SN840_VSD_NS_ALLOC_SIZE	= 0x0c,		/* uint64_t */
116 	WDC_SN840_VSD_NS_REG_AVAIL	= 0x0d,		/* uint64_t */
117 	WDC_SN840_VSD_RAW_NVM		= 0x0e,		/* uint64_t */
118 	WDC_SN840_VSD_PORT_CFG_STS	= 0x0f,		/* uint32_t */
119 	WDC_SN840_VSD_MPN		= 0x10,		/* CBS */
120 	WDC_SN840_VSD_SN		= 0x11,		/* CBS */
121 	WDC_SN840_VSD_DEF_NS_ATTRS	= 0x12,		/* uint32_t */
122 	WDC_SN840_VSD_GIT_DESCR		= 0x13,		/* CBS */
123 	WDC_SN840_VSD_SMB_BL		= 0x14,		/* CBS */
124 	WDC_SN840_VSD_CUST_ID		= 0x15,		/* uint32_t */
125 	WDC_SN840_VSD_PROD_DESC		= 0x16,		/* CBS */
126 	WDC_SN840_VSD_TMM_VER		= 0x17,		/* CBS */
127 	WDC_SN840_VSD_THERM_THROT_STS	= 0x18,		/* uint32_t */
128 	WDC_SN840_VSD_ASSERT_DUMP	= 0x19,		/* uint32_t */
129 	WDC_SN840_VSD_CUST_EOL_STS	= 0x1a,		/* uint32_t */
130 	WDC_SN840_VSD_IFS_EOL_STS	= 0x1b,		/* uint32_t */
131 	WDC_SN840_VSD_CUST_EOL_STATE	= 0x1c,		/* uint32_t */
132 	WDC_SN840_VSD_IFS_EOL_STATE	= 0x1d,		/* uint32_t */
133 	WDC_SN840_VSD_FCR		= 0x1e,		/* uint32_t */
134 	WDC_SN840_VSD_VCA_BPC_REV	= 0x1f,		/* uint32_t */
135 	WDC_SN840_VSD_VCA_BPC_MIN_REV	= 0x20,		/* uint32_t */
136 	WDC_SN840_VSD_VCA_BPC_RST_SEQ	= 0x21,		/* uint32_t */
137 	WDC_SN840_VSD_VCA_TPC_RST_SEQ	= 0x22,		/* uint32_t */
138 	WDC_SN840_VSD_VCA_TPC_FSS_SEQ	= 0x23		/* uint32_t */
139 } wdc_sn840_vsd_id_t;
140 
141 typedef enum {
142 	WDC_SN840_VSD_NS_LIDS		= 0x08,		/* CBS */
143 	WDC_SN840_VSD_NS_FIDS		= 0x09		/* CBS */
144 } wdc_sn840_vsd_ns_id_t;
145 
146 typedef enum {
147 	WDC_SN840_TEMP_NAND	= 0,
148 	WDC_SN840_TEMP_BOARD,
149 	WDC_SN840_TEMP_FE,
150 	WDC_SN840_TEMP_FM0,
151 	WDC_SN840_TEMP_FM1,
152 	WDC_SN840_TEMP_AVG_NAND,
153 	WDC_SN840_TEMP_AVG_FE,
154 	WDC_SN840_TEMP_MAX_ASIC,
155 	WDC_SN840_TEMP_TOUCH,
156 	WDC_SN840_TEMP_COMP,
157 	WDC_SN840_TEMP_NSMAPLES
158 } wdc_sn840_temp_sample_t;
159 
160 /*
161  * These are structures for the firmware activation log. The first structure is
162  * an individual entry. The second is the header which points to these. The data
163  * is versioned and the entries have a specific size, but right now we only know
164  * of the one.
165  */
166 typedef struct {
167 	uint32_t	fah_ent_no;
168 	uint32_t	fah_pow_cyc;
169 	uint64_t	fah_pow_sec;
170 	uint64_t	fah_cur_fw_ver;
171 	uint64_t	fah_new_fw_ver;
172 	uint8_t		fah_slot_no;
173 	uint8_t		fah_commit_type;
174 	uint16_t	fah_result;
175 	uint8_t		fah_rsvd[12];
176 } wdc_vul_sn840_fw_act_ent_t;
177 
178 CTASSERT(sizeof (wdc_vul_sn840_fw_act_ent_t) == 48);
179 
180 typedef struct {
181 	uint8_t		fah_hdr[4];
182 	uint8_t		fah_vers;
183 	uint8_t		fah_rsvd0;
184 	uint8_t		fah_nent;
185 	uint8_t		fah_rsvd1;
186 	uint32_t	fah_entlen;
187 	uint32_t	fah_rsvd;
188 } wdc_vul_sn840_fw_act_hdr_t;
189 
190 CTASSERT(sizeof (wdc_vul_sn840_fw_act_hdr_t) == 16);
191 
192 typedef struct {
193 	uint8_t		cbi_hdr[8];
194 	uint32_t	cbi_cust_id;
195 	uint16_t	cbi_vers_id;
196 	uint16_t	cbi_rev_id;
197 	uint32_t	cbi_build_id;
198 	uint8_t		cbi_nand_head[8];
199 	uint32_t	cbi_cust_nand_id;
200 	uint16_t	cbi_nand_vers_id;
201 	uint16_t	cbi_nand_rev_id;
202 } wdc_vul_sn840_ccds_info_t;
203 
204 CTASSERT(sizeof (wdc_vul_sn840_ccds_info_t) == 36);
205 
206 #pragma	pack()	/* pack(1) */
207 
208 #ifdef __cplusplus
209 }
210 #endif
211 
212 #endif /* _SYS_NVME_WDC_SN840_H */
213