/src/wireshark/epan/dissectors/packet-nvme-mi-mi.c
Line | Count | Source |
1 | | /* packet-nvme-mi-mi.c |
2 | | * NVMe-MI MI Command dissector (NMIMT=1, NVMe-MI 2.1 §5) |
3 | | * Copyright 2026, Brandon Chiu |
4 | | * |
5 | | * Wireshark - Network traffic analyzer |
6 | | * By Gerald Combs <gerald@wireshark.org> |
7 | | * Copyright 1998 Gerald Combs |
8 | | * |
9 | | * SPDX-License-Identifier: GPL-2.0-or-later |
10 | | */ |
11 | | |
12 | | /* Reference: NVM Express Management Interface specification |
13 | | * https://nvmexpress.org/specification/nvme-mi-specification/ |
14 | | * |
15 | | * Decodes the Management Interface Command Set request dwords (NMD0/NMD1), |
16 | | * the command-specific NVMe Management Response field, and the Response Data |
17 | | * structures for opcodes 00h-04h. Opcodes 05h-0Ch are named but their |
18 | | * bodies are rendered as raw dwords/data until fixtures exist for them. |
19 | | */ |
20 | | |
21 | | #include <config.h> |
22 | | |
23 | | #include <epan/expert.h> |
24 | | #include <epan/packet.h> |
25 | | #include <epan/tfs.h> |
26 | | #include <wsutil/array.h> |
27 | | #include <wsutil/utf8_entities.h> |
28 | | #include "packet-nvme.h" |
29 | | #include "packet-nvme-mi.h" |
30 | | |
31 | | void proto_register_nvme_mi_mi(void); |
32 | | void proto_reg_handoff_nvme_mi_mi(void); |
33 | | |
34 | | static int proto_nvme_mi_mi; |
35 | | |
36 | | static dissector_handle_t nvme_mi_mi_handle; |
37 | | |
38 | | static int hf_nvme_mi_mi_opcode; |
39 | | static int hf_nvme_mi_mi_cdw0; |
40 | | static int hf_nvme_mi_mi_cdw1; |
41 | | static int hf_nvme_mi_mi_status; |
42 | | static int hf_nvme_mi_mi_nmresp; |
43 | | static int hf_nvme_mi_mi_data; |
44 | | |
45 | | /* Read NVMe-MI Data Structure (00h) */ |
46 | | static int hf_nvme_mi_mi_rds_dtyp; |
47 | | static int hf_nvme_mi_mi_rds_portid; |
48 | | static int hf_nvme_mi_mi_rds_ctrlid; |
49 | | static int hf_nvme_mi_mi_rds_iocsi; |
50 | | static int hf_nvme_mi_mi_rds_rdl; |
51 | | |
52 | | /* NVM Subsystem Health Status Poll (01h) */ |
53 | | static int hf_nvme_mi_mi_nshsp_cs; |
54 | | |
55 | | /* Controller Health Status Poll (02h) */ |
56 | | static int hf_nvme_mi_mi_chsp_all; |
57 | | static int hf_nvme_mi_mi_chsp_incvf; |
58 | | static int hf_nvme_mi_mi_chsp_incpf; |
59 | | static int hf_nvme_mi_mi_chsp_incf; |
60 | | static int hf_nvme_mi_mi_chsp_maxrent; |
61 | | static int hf_nvme_mi_mi_chsp_sctlid; |
62 | | static int hf_nvme_mi_mi_chsp_ccf; |
63 | | static int hf_nvme_mi_mi_chsp_cwarn; |
64 | | static int hf_nvme_mi_mi_chsp_spare; |
65 | | static int hf_nvme_mi_mi_chsp_pdlu; |
66 | | static int hf_nvme_mi_mi_chsp_ctemp; |
67 | | static int hf_nvme_mi_mi_chsp_csts; |
68 | | static int hf_nvme_mi_mi_chsp_rent; |
69 | | |
70 | | /* Configuration Set (03h) / Configuration Get (04h) */ |
71 | | static int hf_nvme_mi_mi_cfg_cid; |
72 | | static int hf_nvme_mi_mi_cfg_portid; |
73 | | static int hf_nvme_mi_mi_cfg_sfreq; |
74 | | static int hf_nvme_mi_mi_cfg_mtus; |
75 | | static int hf_nvme_mi_mi_cfg_sfreq_cur; |
76 | | static int hf_nvme_mi_mi_cfg_mtus_cur; |
77 | | static int hf_nvme_mi_mi_cfg_aeelver; |
78 | | /* Health Status Change clear-selection bits (Configuration Set, NMD1) */ |
79 | | static int hf_nvme_mi_mi_cfg_hsc_tcida; |
80 | | static int hf_nvme_mi_mi_cfg_hsc_cwarn; |
81 | | static int hf_nvme_mi_mi_cfg_hsc_spare; |
82 | | static int hf_nvme_mi_mi_cfg_hsc_pdlu; |
83 | | static int hf_nvme_mi_mi_cfg_hsc_ctemp; |
84 | | static int hf_nvme_mi_mi_cfg_hsc_cschng; |
85 | | static int hf_nvme_mi_mi_cfg_hsc_fa; |
86 | | static int hf_nvme_mi_mi_cfg_hsc_nac; |
87 | | static int hf_nvme_mi_mi_cfg_hsc_ceco; |
88 | | static int hf_nvme_mi_mi_cfg_hsc_nssro; |
89 | | static int hf_nvme_mi_mi_cfg_hsc_shst; |
90 | | static int hf_nvme_mi_mi_cfg_hsc_cfs; |
91 | | static int hf_nvme_mi_mi_cfg_hsc_rdy; |
92 | | |
93 | | /* VPD Read (05h) / VPD Write (06h) — shared layout */ |
94 | | static int hf_nvme_mi_mi_vpd_dofst; |
95 | | static int hf_nvme_mi_mi_vpd_dlen; |
96 | | static int hf_nvme_mi_mi_vpd_data; |
97 | | |
98 | | /* Configuration Set (03h) Asynchronous Event — request dword 0 |
99 | | * and the AE Enable List request data */ |
100 | | static int hf_nvme_mi_mi_cfg_ae_envfa; |
101 | | static int hf_nvme_mi_mi_cfg_ae_enpfa; |
102 | | static int hf_nvme_mi_mi_cfg_ae_encfa; |
103 | | static int hf_nvme_mi_mi_cfg_ae_aemd; |
104 | | static int hf_nvme_mi_mi_cfg_ae_aerd; |
105 | | static int hf_nvme_mi_mi_ae; |
106 | | static int hf_nvme_mi_mi_ae_numaee; |
107 | | static int hf_nvme_mi_mi_ae_aeelver; |
108 | | static int hf_nvme_mi_mi_ae_aeetl; |
109 | | static int hf_nvme_mi_mi_ae_aeelhl; |
110 | | static int hf_nvme_mi_mi_ae_entry; |
111 | | static int hf_nvme_mi_mi_ae_aeel; |
112 | | static int hf_nvme_mi_mi_ae_aee; |
113 | | static int hf_nvme_mi_mi_ae_id; |
114 | | |
115 | | /* Configuration Get (04h) Asynchronous Event — AE Supported List response |
116 | | * data; same shape as the AE Enable List, different names. */ |
117 | | static int hf_nvme_mi_mi_aes; |
118 | | static int hf_nvme_mi_mi_aes_numaes; |
119 | | static int hf_nvme_mi_mi_aes_aeslver; |
120 | | static int hf_nvme_mi_mi_aes_aestl; |
121 | | static int hf_nvme_mi_mi_aes_aeslhl; |
122 | | static int hf_nvme_mi_mi_aes_entry; |
123 | | static int hf_nvme_mi_mi_aes_aesl; |
124 | | static int hf_nvme_mi_mi_aes_aese; |
125 | | static int hf_nvme_mi_mi_aes_id; |
126 | | |
127 | | /* Reset (07h) */ |
128 | | static int hf_nvme_mi_mi_reset_rsttyp; |
129 | | |
130 | | /* Shutdown (0Ch) */ |
131 | | static int hf_nvme_mi_mi_shutdown_shdntyp; |
132 | | |
133 | | /* NVM Subsystem Information data structure (DTYP 00h) */ |
134 | | static int hf_nvme_mi_mi_subsys_nump; |
135 | | static int hf_nvme_mi_mi_subsys_mjr; |
136 | | static int hf_nvme_mi_mi_subsys_mnr; |
137 | | static int hf_nvme_mi_mi_subsys_nnsc; |
138 | | static int hf_nvme_mi_mi_subsys_sre; |
139 | | |
140 | | /* Port Information data structure (DTYP 01h) */ |
141 | | static int hf_nvme_mi_mi_port_prttyp; |
142 | | static int hf_nvme_mi_mi_port_prtcap; |
143 | | static int hf_nvme_mi_mi_port_aems; |
144 | | static int hf_nvme_mi_mi_port_ciaps; |
145 | | static int hf_nvme_mi_mi_port_mmtus; |
146 | | static int hf_nvme_mi_mi_port_mebs; |
147 | | static int hf_nvme_mi_mi_port_pcie_mps; |
148 | | static int hf_nvme_mi_mi_port_pcie_slsv; |
149 | | static int hf_nvme_mi_mi_port_pcie_cls; |
150 | | static int hf_nvme_mi_mi_port_pcie_mlw; |
151 | | static int hf_nvme_mi_mi_port_pcie_nlw; |
152 | | static int hf_nvme_mi_mi_port_pcie_pn; |
153 | | static int hf_nvme_mi_mi_port_twire_cvpdaddr; |
154 | | static int hf_nvme_mi_mi_port_twire_mvpdfreq; |
155 | | static int hf_nvme_mi_mi_port_twire_cmeaddr; |
156 | | static int hf_nvme_mi_mi_port_twire_twprt; |
157 | | static int hf_nvme_mi_mi_port_twire_i3csprt; |
158 | | static int hf_nvme_mi_mi_port_twire_msmbfreq; |
159 | | static int hf_nvme_mi_mi_port_twire_nvmebm; |
160 | | static int hf_nvme_mi_mi_port_twire_nvmebms; |
161 | | |
162 | | /* Controller List data structure (DTYP 02h, NVMe Base) */ |
163 | | static int hf_nvme_mi_mi_ctrllist_numids; |
164 | | static int hf_nvme_mi_mi_ctrllist_ctrlid; |
165 | | |
166 | | /* Controller Information data structure (DTYP 03h) */ |
167 | | static int hf_nvme_mi_mi_ctrlinfo_portid; |
168 | | static int hf_nvme_mi_mi_ctrlinfo_prii; |
169 | | static int hf_nvme_mi_mi_ctrlinfo_riv; |
170 | | static int hf_nvme_mi_mi_ctrlinfo_pri; |
171 | | static int hf_nvme_mi_mi_ctrlinfo_pri_bus; |
172 | | static int hf_nvme_mi_mi_ctrlinfo_pri_dev; |
173 | | static int hf_nvme_mi_mi_ctrlinfo_pri_fn; |
174 | | static int hf_nvme_mi_mi_ctrlinfo_pcivid; |
175 | | static int hf_nvme_mi_mi_ctrlinfo_pcidid; |
176 | | static int hf_nvme_mi_mi_ctrlinfo_pcisvid; |
177 | | static int hf_nvme_mi_mi_ctrlinfo_pcisdid; |
178 | | static int hf_nvme_mi_mi_ctrlinfo_pciesn; |
179 | | |
180 | | /* Optionally Supported / MEB Supported Command List (DTYP 04h/05h) */ |
181 | | static int hf_nvme_mi_mi_cmdlist_numcmd; |
182 | | static int hf_nvme_mi_mi_cmdlist_ctyp; |
183 | | static int hf_nvme_mi_mi_cmdlist_nmimt; |
184 | | static int hf_nvme_mi_mi_cmdlist_opc; |
185 | | |
186 | | /* NVM Subsystem Health Data Structure (NSHDS) */ |
187 | | static int hf_nvme_mi_mi_nshds_nss; |
188 | | static int hf_nvme_mi_mi_nshds_nss_atf; |
189 | | static int hf_nvme_mi_mi_nshds_nss_sfm; |
190 | | static int hf_nvme_mi_mi_nshds_nss_df; |
191 | | static int hf_nvme_mi_mi_nshds_nss_rnr; |
192 | | static int hf_nvme_mi_mi_nshds_nss_p0la; |
193 | | static int hf_nvme_mi_mi_nshds_nss_p1la; |
194 | | static int hf_nvme_mi_mi_nshds_nss_snfm; |
195 | | static int hf_nvme_mi_mi_nshds_sw; |
196 | | static int hf_nvme_mi_mi_nshds_sw_ips; |
197 | | static int hf_nvme_mi_mi_nshds_sw_pmre; |
198 | | static int hf_nvme_mi_mi_nshds_sw_vmbf; |
199 | | static int hf_nvme_mi_mi_nshds_sw_ro; |
200 | | static int hf_nvme_mi_mi_nshds_sw_rd; |
201 | | static int hf_nvme_mi_mi_nshds_sw_taut; |
202 | | static int hf_nvme_mi_mi_nshds_sw_st; |
203 | | static int hf_nvme_mi_mi_nshds_ctemp; |
204 | | static int hf_nvme_mi_mi_nshds_pdlu; |
205 | | static int hf_nvme_mi_mi_nshds_ccs; |
206 | | |
207 | | /* Shared health-status flag bits — same bit layout in the NVMe-MI 2.1 |
208 | | * "Composite Controller Status Data Structure (CCSDS)" and "Controller |
209 | | * Health Status Changed Flags (CHSCF)" figures. */ |
210 | | static int hf_nvme_mi_mi_hsf_tcida; |
211 | | static int hf_nvme_mi_mi_hsf_cwarn; |
212 | | static int hf_nvme_mi_mi_hsf_spare; |
213 | | static int hf_nvme_mi_mi_hsf_pdlu; |
214 | | static int hf_nvme_mi_mi_hsf_ctemp; |
215 | | static int hf_nvme_mi_mi_hsf_csts; |
216 | | static int hf_nvme_mi_mi_hsf_fa; |
217 | | static int hf_nvme_mi_mi_hsf_nac; |
218 | | static int hf_nvme_mi_mi_hsf_ceco; |
219 | | static int hf_nvme_mi_mi_hsf_nssro; |
220 | | static int hf_nvme_mi_mi_hsf_shst; |
221 | | static int hf_nvme_mi_mi_hsf_cfs; |
222 | | static int hf_nvme_mi_mi_hsf_rdy; |
223 | | |
224 | | /* Controller Health Data Structure (CHDS) */ |
225 | | static int hf_nvme_mi_mi_chds_ctlid; |
226 | | static int hf_nvme_mi_mi_chds_csts; |
227 | | static int hf_nvme_mi_mi_chds_csts_tcida; |
228 | | static int hf_nvme_mi_mi_chds_csts_fa; |
229 | | static int hf_nvme_mi_mi_chds_csts_nac; |
230 | | static int hf_nvme_mi_mi_chds_csts_ceco; |
231 | | static int hf_nvme_mi_mi_chds_csts_nssro; |
232 | | static int hf_nvme_mi_mi_chds_csts_shst; |
233 | | static int hf_nvme_mi_mi_chds_csts_cfs; |
234 | | static int hf_nvme_mi_mi_chds_csts_rdy; |
235 | | static int hf_nvme_mi_mi_chds_ctemp; |
236 | | static int hf_nvme_mi_mi_chds_pdlu; |
237 | | static int hf_nvme_mi_mi_chds_spare; |
238 | | static int hf_nvme_mi_mi_chds_cwarn; |
239 | | static int hf_nvme_mi_mi_chds_cwarn_ips; |
240 | | static int hf_nvme_mi_mi_chds_cwarn_pmre; |
241 | | static int hf_nvme_mi_mi_chds_cwarn_vmbf; |
242 | | static int hf_nvme_mi_mi_chds_cwarn_ro; |
243 | | static int hf_nvme_mi_mi_chds_cwarn_rd; |
244 | | static int hf_nvme_mi_mi_chds_cwarn_taut; |
245 | | static int hf_nvme_mi_mi_chds_cwarn_st; |
246 | | static int hf_nvme_mi_mi_chds_chsc; |
247 | | |
248 | | static int ett_nvme_mi_mi; |
249 | | static int ett_nvme_mi_mi_field; |
250 | | static int ett_nvme_mi_mi_entry; |
251 | | |
252 | | static expert_field ei_nvme_mi_mi_truncated; |
253 | | static expert_field ei_nvme_mi_mi_orphan_response; |
254 | | static expert_field ei_nvme_mi_mi_reserved_dtyp; |
255 | | static expert_field ei_nvme_mi_mi_reserved_configid; |
256 | | static expert_field ei_nvme_mi_mi_reserved_value; |
257 | | |
258 | | /* MI command opcodes (NVMe-MI 2.1 "Opcodes for Management Interface Command |
259 | | * Set"). Only 00h-07h, 0Ch get field-level |
260 | | * decode; 08h-0Bh are named for display and fall through to the raw dword |
261 | | * rendering. */ |
262 | | enum nvme_mi_mi_opc { |
263 | | NVME_MI_MI_OPC_READ_DS = 0x00, |
264 | | NVME_MI_MI_OPC_SUBSYS_HSP = 0x01, |
265 | | NVME_MI_MI_OPC_CTRL_HSP = 0x02, |
266 | | NVME_MI_MI_OPC_CONFIG_SET = 0x03, |
267 | | NVME_MI_MI_OPC_CONFIG_GET = 0x04, |
268 | | NVME_MI_MI_OPC_VPD_READ = 0x05, |
269 | | NVME_MI_MI_OPC_VPD_WRITE = 0x06, |
270 | | NVME_MI_MI_OPC_RESET = 0x07, |
271 | | NVME_MI_MI_OPC_SES_RECV = 0x08, |
272 | | NVME_MI_MI_OPC_SES_SEND = 0x09, |
273 | | NVME_MI_MI_OPC_MEB_READ = 0x0A, |
274 | | NVME_MI_MI_OPC_MEB_WRITE = 0x0B, |
275 | | NVME_MI_MI_OPC_SHUTDOWN = 0x0C, |
276 | | }; |
277 | | |
278 | | static const range_string mi_opcode_vals[] = { |
279 | | { NVME_MI_MI_OPC_READ_DS, NVME_MI_MI_OPC_READ_DS, "Read NVMe-MI Data Structure" }, |
280 | | { NVME_MI_MI_OPC_SUBSYS_HSP, NVME_MI_MI_OPC_SUBSYS_HSP, "NVM Subsystem Health Status Poll" }, |
281 | | { NVME_MI_MI_OPC_CTRL_HSP, NVME_MI_MI_OPC_CTRL_HSP, "Controller Health Status Poll" }, |
282 | | { NVME_MI_MI_OPC_CONFIG_SET, NVME_MI_MI_OPC_CONFIG_SET, "Configuration Set" }, |
283 | | { NVME_MI_MI_OPC_CONFIG_GET, NVME_MI_MI_OPC_CONFIG_GET, "Configuration Get" }, |
284 | | { NVME_MI_MI_OPC_VPD_READ, NVME_MI_MI_OPC_VPD_READ, "VPD Read" }, |
285 | | { NVME_MI_MI_OPC_VPD_WRITE, NVME_MI_MI_OPC_VPD_WRITE, "VPD Write" }, |
286 | | { NVME_MI_MI_OPC_RESET, NVME_MI_MI_OPC_RESET, "Reset" }, |
287 | | { NVME_MI_MI_OPC_SES_RECV, NVME_MI_MI_OPC_SES_RECV, "SES Receive" }, |
288 | | { NVME_MI_MI_OPC_SES_SEND, NVME_MI_MI_OPC_SES_SEND, "SES Send" }, |
289 | | { NVME_MI_MI_OPC_MEB_READ, NVME_MI_MI_OPC_MEB_READ, "Management Endpoint Buffer Read" }, |
290 | | { NVME_MI_MI_OPC_MEB_WRITE, NVME_MI_MI_OPC_MEB_WRITE, "Management Endpoint Buffer Write" }, |
291 | | { NVME_MI_MI_OPC_SHUTDOWN, NVME_MI_MI_OPC_SHUTDOWN, "Shutdown" }, |
292 | | { 0xC0, 0xFF, "Vendor Specific" }, |
293 | | { 0, 0, NULL }, |
294 | | }; |
295 | | |
296 | | /* Data Structure Types (Read NVMe-MI Data Structure NVMe Management |
297 | | * Dword 0); 06h-FFh are reserved. */ |
298 | | enum nvme_mi_dtyp { |
299 | | NVME_MI_DTYP_SUBSYS_INFO = 0x00, |
300 | | NVME_MI_DTYP_PORT_INFO = 0x01, |
301 | | NVME_MI_DTYP_CTRL_LIST = 0x02, |
302 | | NVME_MI_DTYP_CTRL_INFO = 0x03, |
303 | | NVME_MI_DTYP_OSC_LIST = 0x04, |
304 | | NVME_MI_DTYP_MEB_LIST = 0x05, |
305 | | NVME_MI_DTYP_MAX = NVME_MI_DTYP_MEB_LIST, |
306 | | }; |
307 | | |
308 | | static const value_string mi_dtyp_vals[] = { |
309 | | { NVME_MI_DTYP_SUBSYS_INFO, "NVM Subsystem Information" }, |
310 | | { NVME_MI_DTYP_PORT_INFO, "Port Information" }, |
311 | | { NVME_MI_DTYP_CTRL_LIST, "Controller List" }, |
312 | | { NVME_MI_DTYP_CTRL_INFO, "Controller Information" }, |
313 | | { NVME_MI_DTYP_OSC_LIST, "Optionally Supported Command List" }, |
314 | | { NVME_MI_DTYP_MEB_LIST, "Management Endpoint Buffer Command Support List" }, |
315 | | { 0, NULL }, |
316 | | }; |
317 | | |
318 | | /* Configuration Identifiers; 00h and 05h-BFh are reserved, |
319 | | * C0h-FFh vendor specific. */ |
320 | | enum nvme_mi_cfgid { |
321 | | NVME_MI_CFGID_SMBUS_FREQ = 0x01, |
322 | | NVME_MI_CFGID_HSC = 0x02, |
323 | | NVME_MI_CFGID_MTUS = 0x03, |
324 | | NVME_MI_CFGID_AE = 0x04, |
325 | | NVME_MI_CFGID_RESERVED_FIRST = 0x05, |
326 | | NVME_MI_CFGID_RESERVED_LAST = 0xBF, |
327 | | }; |
328 | | |
329 | | static const range_string mi_configid_vals[] = { |
330 | | { 0x00, 0x00, "Reserved" }, |
331 | | { NVME_MI_CFGID_SMBUS_FREQ, NVME_MI_CFGID_SMBUS_FREQ, "SMBus/I2C Frequency" }, |
332 | | { NVME_MI_CFGID_HSC, NVME_MI_CFGID_HSC, "Health Status Change" }, |
333 | | { NVME_MI_CFGID_MTUS, NVME_MI_CFGID_MTUS, "MCTP Transmission Unit Size" }, |
334 | | { NVME_MI_CFGID_AE, NVME_MI_CFGID_AE, "Asynchronous Event" }, |
335 | | { NVME_MI_CFGID_RESERVED_FIRST, NVME_MI_CFGID_RESERVED_LAST, "Reserved" }, |
336 | | { 0xC0, 0xFF, "Vendor Specific" }, |
337 | | { 0, 0, NULL }, |
338 | | }; |
339 | | |
340 | | /* AE Enable ID — Asynchronous Events */ |
341 | | static const range_string mi_ae_id_vals[] = { |
342 | | { 0x00, 0x00, "Controller Ready" }, |
343 | | { 0x01, 0x01, "Controller Fatal Status" }, |
344 | | { 0x02, 0x02, "Shutdown Status" }, |
345 | | { 0x03, 0x03, "Controller Enable" }, |
346 | | { 0x04, 0x04, "Namespace Attribute Changed" }, |
347 | | { 0x05, 0x05, "Firmware Activated" }, |
348 | | { 0x06, 0x06, "Composite Temperature" }, |
349 | | { 0x07, 0x07, "Percentage Drive Life Used" }, |
350 | | { 0x08, 0x08, "Available Spare" }, |
351 | | { 0x09, 0x09, "SMART Warnings" }, |
352 | | { 0x0a, 0x0a, "Telemetry Controller-Initiated Data Available" }, |
353 | | { 0x0b, 0x0b, "PCIe Link Active" }, |
354 | | { 0x0c, 0x0c, "Sanitize Failure Mode" }, |
355 | | { 0x0d, 0x0d, "Sanitize Namespace Failure Mode" }, |
356 | | { 0x0e, 0x0e, "Power Threshold Exceeded" }, |
357 | | { 0xC0, 0xFF, "Vendor Specific" }, |
358 | | { 0, 0, NULL }, |
359 | | }; |
360 | | |
361 | | /* SMBus/I2C frequency encoding */ |
362 | | static const value_string mi_sfreq_vals[] = { |
363 | | { 0x0, "Obsolete/Reserved" }, |
364 | | { 0x1, "100 kHz" }, |
365 | | { 0x2, "400 kHz" }, |
366 | | { 0x3, "1 MHz" }, |
367 | | { 0, NULL }, |
368 | | }; |
369 | | |
370 | | /* Maximum VPD access / maximum SMBus frequency (2-Wire Port Specific |
371 | | * Data) */ |
372 | | static const value_string mi_vpdfreq_vals[] = { |
373 | | { 0x0, "Not supported" }, |
374 | | { 0x1, "100 kHz" }, |
375 | | { 0x2, "400 kHz" }, |
376 | | { 0x3, "1 MHz" }, |
377 | | { 0, NULL }, |
378 | | }; |
379 | | |
380 | | static const value_string mi_prttyp_vals[] = { |
381 | | { 0x0, "Inactive" }, |
382 | | { 0x1, "PCIe" }, |
383 | | { 0x2, "2-Wire" }, |
384 | | { 0, NULL }, |
385 | | }; |
386 | | |
387 | | static const value_string mi_pciemps_vals[] = { |
388 | | { 0x0, "128 bytes" }, |
389 | | { 0x1, "256 bytes" }, |
390 | | { 0x2, "512 bytes" }, |
391 | | { 0x3, "1 KiB" }, |
392 | | { 0x4, "2 KiB" }, |
393 | | { 0x5, "4 KiB" }, |
394 | | { 0, NULL }, |
395 | | }; |
396 | | |
397 | | static const value_string mi_pciecls_vals[] = { |
398 | | { 0x0, "Link not active" }, |
399 | | { 0x1, "2.5 GT/s" }, |
400 | | { 0x2, "5.0 GT/s" }, |
401 | | { 0x3, "8.0 GT/s" }, |
402 | | { 0x4, "16.0 GT/s" }, |
403 | | { 0x5, "32.0 GT/s" }, |
404 | | { 0x6, "64.0 GT/s" }, |
405 | | { 0, NULL }, |
406 | | }; |
407 | | |
408 | | /* Reset Type; 01h-FFh reserved */ |
409 | 0 | #define NVME_MI_RSTTYP_MAX 0x00 /* highest valid Reset Type */ |
410 | | static const value_string mi_rsttyp_vals[] = { |
411 | | { 0x00, "Reset NVM Subsystem" }, |
412 | | { 0, NULL }, |
413 | | }; |
414 | | |
415 | | /* Shutdown Type; 02h-FFh reserved */ |
416 | 0 | #define NVME_MI_SHDNTYP_MAX 0x01 /* highest valid Shutdown Type */ |
417 | | static const value_string mi_shdntyp_vals[] = { |
418 | | { 0x00, "Normal NVM Subsystem Shutdown" }, |
419 | | { 0x01, "Abrupt NVM Subsystem Shutdown" }, |
420 | | { 0, NULL }, |
421 | | }; |
422 | | |
423 | | /* |
424 | | * CSTS.SHST shutdown status: reuse packet-nvme.c's shst_table (shared via |
425 | | * packet-nvme.h) so the MI CHDS decode and the NVMe Base decode never drift. |
426 | | * |
427 | | * NMIMT in command-list entries (the Optionally/MEB Supported Command Data |
428 | | * Structure entries) uses the same encoding as the |
429 | | * message header, so the entry decode reuses mi_type_vals (packet-nvme-mi.h). |
430 | | */ |
431 | | |
432 | | /* |
433 | | * Per-transaction request context hung off nvme_mi_transaction.body_ctx |
434 | | * (wmem_file_scope). Records the request parameter that selects the |
435 | | * response layout; only the member matching the transaction's opcode is |
436 | | * meaningful. |
437 | | */ |
438 | | struct nvme_mi_mi_req_ctx { |
439 | | uint8_t dtyp; /* Read NVMe-MI Data Structure (00h) */ |
440 | | uint8_t configid; /* Configuration Set/Get (03h/04h) */ |
441 | | }; |
442 | | |
443 | | static int * const rds_cdw0_fields[] = { |
444 | | &hf_nvme_mi_mi_rds_dtyp, |
445 | | &hf_nvme_mi_mi_rds_portid, |
446 | | &hf_nvme_mi_mi_rds_ctrlid, |
447 | | NULL, |
448 | | }; |
449 | | static int * const rds_cdw1_fields[] = { |
450 | | &hf_nvme_mi_mi_rds_iocsi, |
451 | | NULL, |
452 | | }; |
453 | | static int * const nshsp_cdw1_fields[] = { |
454 | | &hf_nvme_mi_mi_nshsp_cs, |
455 | | NULL, |
456 | | }; |
457 | | static int * const chsp_cdw0_fields[] = { |
458 | | &hf_nvme_mi_mi_chsp_all, |
459 | | &hf_nvme_mi_mi_chsp_incvf, |
460 | | &hf_nvme_mi_mi_chsp_incpf, |
461 | | &hf_nvme_mi_mi_chsp_incf, |
462 | | &hf_nvme_mi_mi_chsp_maxrent, |
463 | | &hf_nvme_mi_mi_chsp_sctlid, |
464 | | NULL, |
465 | | }; |
466 | | static int * const chsp_cdw1_fields[] = { |
467 | | &hf_nvme_mi_mi_chsp_ccf, |
468 | | &hf_nvme_mi_mi_chsp_cwarn, |
469 | | &hf_nvme_mi_mi_chsp_spare, |
470 | | &hf_nvme_mi_mi_chsp_pdlu, |
471 | | &hf_nvme_mi_mi_chsp_ctemp, |
472 | | &hf_nvme_mi_mi_chsp_csts, |
473 | | NULL, |
474 | | }; |
475 | | static int * const cfg_cdw0_fields_cid[] = { |
476 | | &hf_nvme_mi_mi_cfg_cid, |
477 | | NULL, |
478 | | }; |
479 | | static int * const cfg_cdw0_fields_port[] = { |
480 | | &hf_nvme_mi_mi_cfg_portid, |
481 | | &hf_nvme_mi_mi_cfg_cid, |
482 | | NULL, |
483 | | }; |
484 | | static int * const cfg_cdw0_fields_sfreq[] = { |
485 | | &hf_nvme_mi_mi_cfg_portid, |
486 | | &hf_nvme_mi_mi_cfg_sfreq, |
487 | | &hf_nvme_mi_mi_cfg_cid, |
488 | | NULL, |
489 | | }; |
490 | | static int * const cfg_cdw1_fields_hsc[] = { |
491 | | &hf_nvme_mi_mi_cfg_hsc_tcida, |
492 | | &hf_nvme_mi_mi_cfg_hsc_cwarn, |
493 | | &hf_nvme_mi_mi_cfg_hsc_spare, |
494 | | &hf_nvme_mi_mi_cfg_hsc_pdlu, |
495 | | &hf_nvme_mi_mi_cfg_hsc_ctemp, |
496 | | &hf_nvme_mi_mi_cfg_hsc_cschng, |
497 | | &hf_nvme_mi_mi_cfg_hsc_fa, |
498 | | &hf_nvme_mi_mi_cfg_hsc_nac, |
499 | | &hf_nvme_mi_mi_cfg_hsc_ceco, |
500 | | &hf_nvme_mi_mi_cfg_hsc_nssro, |
501 | | &hf_nvme_mi_mi_cfg_hsc_shst, |
502 | | &hf_nvme_mi_mi_cfg_hsc_cfs, |
503 | | &hf_nvme_mi_mi_cfg_hsc_rdy, |
504 | | NULL, |
505 | | }; |
506 | | static int * const cfg_cdw1_fields_mtus[] = { |
507 | | &hf_nvme_mi_mi_cfg_mtus, |
508 | | NULL, |
509 | | }; |
510 | | /* Configuration Set of the Asynchronous Event configuration; the |
511 | | * Configuration Get form has these bits reserved. */ |
512 | | static int * const cfg_cdw0_fields_ae_set[] = { |
513 | | &hf_nvme_mi_mi_cfg_ae_envfa, |
514 | | &hf_nvme_mi_mi_cfg_ae_enpfa, |
515 | | &hf_nvme_mi_mi_cfg_ae_encfa, |
516 | | &hf_nvme_mi_mi_cfg_ae_aemd, |
517 | | &hf_nvme_mi_mi_cfg_ae_aerd, |
518 | | &hf_nvme_mi_mi_cfg_cid, |
519 | | NULL, |
520 | | }; |
521 | | static int * const vpd_cdw0_fields[] = { |
522 | | &hf_nvme_mi_mi_vpd_dofst, |
523 | | NULL, |
524 | | }; |
525 | | static int * const vpd_cdw1_fields[] = { |
526 | | &hf_nvme_mi_mi_vpd_dlen, |
527 | | NULL, |
528 | | }; |
529 | | static int * const reset_cdw0_fields[] = { |
530 | | &hf_nvme_mi_mi_reset_rsttyp, |
531 | | NULL, |
532 | | }; |
533 | | static int * const shutdown_cdw0_fields[] = { |
534 | | &hf_nvme_mi_mi_shutdown_shdntyp, |
535 | | NULL, |
536 | | }; |
537 | | static int * const subsys_nnsc_fields[] = { |
538 | | &hf_nvme_mi_mi_subsys_sre, |
539 | | NULL, |
540 | | }; |
541 | | static int * const port_prtcap_fields[] = { |
542 | | &hf_nvme_mi_mi_port_aems, |
543 | | &hf_nvme_mi_mi_port_ciaps, |
544 | | NULL, |
545 | | }; |
546 | | static int * const port_twprt_fields[] = { |
547 | | &hf_nvme_mi_mi_port_twire_i3csprt, |
548 | | &hf_nvme_mi_mi_port_twire_msmbfreq, |
549 | | NULL, |
550 | | }; |
551 | | static int * const port_nvmebm_fields[] = { |
552 | | &hf_nvme_mi_mi_port_twire_nvmebms, |
553 | | NULL, |
554 | | }; |
555 | | static int * const ctrlinfo_prii_fields[] = { |
556 | | &hf_nvme_mi_mi_ctrlinfo_riv, |
557 | | NULL, |
558 | | }; |
559 | | static int * const ctrlinfo_pri_fields[] = { |
560 | | &hf_nvme_mi_mi_ctrlinfo_pri_bus, |
561 | | &hf_nvme_mi_mi_ctrlinfo_pri_dev, |
562 | | &hf_nvme_mi_mi_ctrlinfo_pri_fn, |
563 | | NULL, |
564 | | }; |
565 | | static int * const cmdlist_ctyp_fields[] = { |
566 | | &hf_nvme_mi_mi_cmdlist_nmimt, |
567 | | NULL, |
568 | | }; |
569 | | static int * const nshds_nss_fields[] = { |
570 | | &hf_nvme_mi_mi_nshds_nss_atf, |
571 | | &hf_nvme_mi_mi_nshds_nss_sfm, |
572 | | &hf_nvme_mi_mi_nshds_nss_df, |
573 | | &hf_nvme_mi_mi_nshds_nss_rnr, |
574 | | &hf_nvme_mi_mi_nshds_nss_p0la, |
575 | | &hf_nvme_mi_mi_nshds_nss_p1la, |
576 | | &hf_nvme_mi_mi_nshds_nss_snfm, |
577 | | NULL, |
578 | | }; |
579 | | /* |
580 | | * NSHDS SMART Warnings is the bitwise *inverse* of the SMART / Health |
581 | | * Information Critical Warning field: a bit is set to '1' when the condition |
582 | | * is clear on every Controller in the NVM Subsystem, and cleared to '0' when |
583 | | * any Controller asserts it. The bit positions match CHDS CWARN, but the |
584 | | * sense is opposite, so these must not use tfs_set_notset. |
585 | | */ |
586 | | static const true_false_string tfs_nshds_sw = { "Normal", "Warning" }; |
587 | | static int * const nshds_sw_fields[] = { |
588 | | &hf_nvme_mi_mi_nshds_sw_ips, |
589 | | &hf_nvme_mi_mi_nshds_sw_pmre, |
590 | | &hf_nvme_mi_mi_nshds_sw_vmbf, |
591 | | &hf_nvme_mi_mi_nshds_sw_ro, |
592 | | &hf_nvme_mi_mi_nshds_sw_rd, |
593 | | &hf_nvme_mi_mi_nshds_sw_taut, |
594 | | &hf_nvme_mi_mi_nshds_sw_st, |
595 | | NULL, |
596 | | }; |
597 | | static int * const hsf_fields[] = { |
598 | | &hf_nvme_mi_mi_hsf_tcida, |
599 | | &hf_nvme_mi_mi_hsf_cwarn, |
600 | | &hf_nvme_mi_mi_hsf_spare, |
601 | | &hf_nvme_mi_mi_hsf_pdlu, |
602 | | &hf_nvme_mi_mi_hsf_ctemp, |
603 | | &hf_nvme_mi_mi_hsf_csts, |
604 | | &hf_nvme_mi_mi_hsf_fa, |
605 | | &hf_nvme_mi_mi_hsf_nac, |
606 | | &hf_nvme_mi_mi_hsf_ceco, |
607 | | &hf_nvme_mi_mi_hsf_nssro, |
608 | | &hf_nvme_mi_mi_hsf_shst, |
609 | | &hf_nvme_mi_mi_hsf_cfs, |
610 | | &hf_nvme_mi_mi_hsf_rdy, |
611 | | NULL, |
612 | | }; |
613 | | static int * const chds_csts_fields[] = { |
614 | | &hf_nvme_mi_mi_chds_csts_tcida, |
615 | | &hf_nvme_mi_mi_chds_csts_fa, |
616 | | &hf_nvme_mi_mi_chds_csts_nac, |
617 | | &hf_nvme_mi_mi_chds_csts_ceco, |
618 | | &hf_nvme_mi_mi_chds_csts_nssro, |
619 | | &hf_nvme_mi_mi_chds_csts_shst, |
620 | | &hf_nvme_mi_mi_chds_csts_cfs, |
621 | | &hf_nvme_mi_mi_chds_csts_rdy, |
622 | | NULL, |
623 | | }; |
624 | | static int * const chds_cwarn_fields[] = { |
625 | | &hf_nvme_mi_mi_chds_cwarn_ips, |
626 | | &hf_nvme_mi_mi_chds_cwarn_pmre, |
627 | | &hf_nvme_mi_mi_chds_cwarn_vmbf, |
628 | | &hf_nvme_mi_mi_chds_cwarn_ro, |
629 | | &hf_nvme_mi_mi_chds_cwarn_rd, |
630 | | &hf_nvme_mi_mi_chds_cwarn_taut, |
631 | | &hf_nvme_mi_mi_chds_cwarn_st, |
632 | | NULL, |
633 | | }; |
634 | | |
635 | | /* |
636 | | * NSHDS CTEMP encoding: 00h-7Eh = 0-126 °C, 7Fh = 127 °C or |
637 | | * higher, 80h/81h = sentinel codes, C4h = -60 °C or lower, C5h-FFh = |
638 | | * -59 to -1 °C in two's complement, the rest reserved. |
639 | | */ |
640 | | static void |
641 | | nvme_mi_mi_fmt_nshds_ctemp(char *buf, uint32_t value) |
642 | 0 | { |
643 | 0 | if (value <= 0x7e) |
644 | 0 | snprintf(buf, ITEM_LABEL_LENGTH, "%u " UTF8_DEGREE_SIGN "C", value); |
645 | 0 | else if (value == 0x7f) |
646 | 0 | snprintf(buf, ITEM_LABEL_LENGTH, "127 " UTF8_DEGREE_SIGN "C or higher"); |
647 | 0 | else if (value == 0x80) |
648 | 0 | snprintf(buf, ITEM_LABEL_LENGTH, "No temperature data or data is stale"); |
649 | 0 | else if (value == 0x81) |
650 | 0 | snprintf(buf, ITEM_LABEL_LENGTH, "Temperature sensor failure"); |
651 | 0 | else if (value <= 0xc3) |
652 | 0 | snprintf(buf, ITEM_LABEL_LENGTH, "Reserved (0x%02x)", value); |
653 | 0 | else if (value == 0xc4) |
654 | 0 | snprintf(buf, ITEM_LABEL_LENGTH, "-60 " UTF8_DEGREE_SIGN "C or lower"); |
655 | 0 | else |
656 | 0 | snprintf(buf, ITEM_LABEL_LENGTH, "%d " UTF8_DEGREE_SIGN "C", |
657 | 0 | (int)value - 256); |
658 | 0 | } |
659 | | |
660 | | /* Flag truncated response data and render the leftover bytes raw. */ |
661 | | static void |
662 | | nvme_mi_mi_data_truncated(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, |
663 | | proto_item *it, int off) |
664 | 0 | { |
665 | 0 | nvme_mi_dissect_truncated(tvb, pinfo, tree, it, &ei_nvme_mi_mi_truncated, |
666 | 0 | hf_nvme_mi_mi_data, off); |
667 | 0 | } |
668 | | |
669 | | /* DTYP 00h — NVM Subsystem Information Data Structure */ |
670 | | static void |
671 | | nvme_mi_mi_data_subsys_info(tvbuff_t *tvb, packet_info *pinfo, |
672 | | proto_tree *tree, proto_item *it, int off, int len) |
673 | 0 | { |
674 | 0 | if (len < 4) { |
675 | 0 | nvme_mi_mi_data_truncated(tvb, pinfo, tree, it, off); |
676 | 0 | return; |
677 | 0 | } |
678 | 0 | proto_tree_add_item(tree, hf_nvme_mi_mi_subsys_nump, tvb, off, 1, ENC_NA); |
679 | 0 | proto_tree_add_item(tree, hf_nvme_mi_mi_subsys_mjr, tvb, off + 1, 1, ENC_NA); |
680 | 0 | proto_tree_add_item(tree, hf_nvme_mi_mi_subsys_mnr, tvb, off + 2, 1, ENC_NA); |
681 | 0 | proto_tree_add_bitmask(tree, tvb, off + 3, hf_nvme_mi_mi_subsys_nnsc, |
682 | 0 | ett_nvme_mi_mi_field, subsys_nnsc_fields, ENC_NA); |
683 | | /* bytes 31:04 reserved */ |
684 | 0 | } |
685 | | |
686 | | /* DTYP 01h — Port Information Data Structure */ |
687 | | static void |
688 | | nvme_mi_mi_data_port_info(tvbuff_t *tvb, packet_info *pinfo, |
689 | | proto_tree *tree, proto_item *it, int off, int len) |
690 | 0 | { |
691 | 0 | uint32_t prttyp; |
692 | |
|
693 | 0 | if (len < 8) { |
694 | 0 | nvme_mi_mi_data_truncated(tvb, pinfo, tree, it, off); |
695 | 0 | return; |
696 | 0 | } |
697 | 0 | proto_tree_add_item_ret_uint(tree, hf_nvme_mi_mi_port_prttyp, |
698 | 0 | tvb, off, 1, ENC_NA, &prttyp); |
699 | 0 | proto_tree_add_bitmask(tree, tvb, off + 1, hf_nvme_mi_mi_port_prtcap, |
700 | 0 | ett_nvme_mi_mi_field, port_prtcap_fields, ENC_NA); |
701 | 0 | proto_tree_add_item(tree, hf_nvme_mi_mi_port_mmtus, |
702 | 0 | tvb, off + 2, 2, ENC_LITTLE_ENDIAN); |
703 | 0 | proto_tree_add_item(tree, hf_nvme_mi_mi_port_mebs, |
704 | 0 | tvb, off + 4, 4, ENC_LITTLE_ENDIAN); |
705 | |
|
706 | 0 | switch (prttyp) { |
707 | 0 | case 0x1: /* PCIe Port Specific Data */ |
708 | 0 | if (len < 14) { |
709 | 0 | nvme_mi_mi_data_truncated(tvb, pinfo, tree, it, off + 8); |
710 | 0 | return; |
711 | 0 | } |
712 | 0 | proto_tree_add_item(tree, hf_nvme_mi_mi_port_pcie_mps, |
713 | 0 | tvb, off + 8, 1, ENC_NA); |
714 | 0 | proto_tree_add_item(tree, hf_nvme_mi_mi_port_pcie_slsv, |
715 | 0 | tvb, off + 9, 1, ENC_NA); |
716 | 0 | proto_tree_add_item(tree, hf_nvme_mi_mi_port_pcie_cls, |
717 | 0 | tvb, off + 10, 1, ENC_NA); |
718 | 0 | proto_tree_add_item(tree, hf_nvme_mi_mi_port_pcie_mlw, |
719 | 0 | tvb, off + 11, 1, ENC_NA); |
720 | 0 | proto_tree_add_item(tree, hf_nvme_mi_mi_port_pcie_nlw, |
721 | 0 | tvb, off + 12, 1, ENC_NA); |
722 | 0 | proto_tree_add_item(tree, hf_nvme_mi_mi_port_pcie_pn, |
723 | 0 | tvb, off + 13, 1, ENC_NA); |
724 | 0 | break; |
725 | 0 | case 0x2: /* 2-Wire Port Specific Data */ |
726 | 0 | if (len < 13) { |
727 | 0 | nvme_mi_mi_data_truncated(tvb, pinfo, tree, it, off + 8); |
728 | 0 | return; |
729 | 0 | } |
730 | 0 | proto_tree_add_item(tree, hf_nvme_mi_mi_port_twire_cvpdaddr, |
731 | 0 | tvb, off + 8, 1, ENC_NA); |
732 | 0 | proto_tree_add_item(tree, hf_nvme_mi_mi_port_twire_mvpdfreq, |
733 | 0 | tvb, off + 9, 1, ENC_NA); |
734 | 0 | proto_tree_add_item(tree, hf_nvme_mi_mi_port_twire_cmeaddr, |
735 | 0 | tvb, off + 10, 1, ENC_NA); |
736 | 0 | proto_tree_add_bitmask(tree, tvb, off + 11, |
737 | 0 | hf_nvme_mi_mi_port_twire_twprt, |
738 | 0 | ett_nvme_mi_mi_field, port_twprt_fields, ENC_NA); |
739 | 0 | proto_tree_add_bitmask(tree, tvb, off + 12, |
740 | 0 | hf_nvme_mi_mi_port_twire_nvmebm, |
741 | 0 | ett_nvme_mi_mi_field, port_nvmebm_fields, ENC_NA); |
742 | 0 | break; |
743 | 0 | default: |
744 | | /* Inactive or reserved port type: PTSP bytes rendered raw */ |
745 | 0 | if (len > 8) |
746 | 0 | proto_tree_add_item(tree, hf_nvme_mi_mi_data, tvb, off + 8, -1, |
747 | 0 | ENC_NA); |
748 | 0 | break; |
749 | 0 | } |
750 | 0 | } |
751 | | |
752 | | /* DTYP 02h — Controller List (NVMe Base format: count + uint16le IDs) */ |
753 | | static void |
754 | | nvme_mi_mi_data_ctrl_list(tvbuff_t *tvb, packet_info *pinfo, |
755 | | proto_tree *tree, proto_item *it, int off, int len) |
756 | 0 | { |
757 | 0 | uint32_t numids; |
758 | 0 | int pos = off + 2; |
759 | |
|
760 | 0 | if (len < 2) { |
761 | 0 | nvme_mi_mi_data_truncated(tvb, pinfo, tree, it, off); |
762 | 0 | return; |
763 | 0 | } |
764 | 0 | proto_tree_add_item_ret_uint(tree, hf_nvme_mi_mi_ctrllist_numids, |
765 | 0 | tvb, off, 2, ENC_LITTLE_ENDIAN, &numids); |
766 | 0 | for (uint32_t i = 0; i < numids; i++) { |
767 | 0 | if (pos + 2 > off + len) { |
768 | 0 | nvme_mi_mi_data_truncated(tvb, pinfo, tree, it, pos); |
769 | 0 | return; |
770 | 0 | } |
771 | 0 | proto_tree_add_item(tree, hf_nvme_mi_mi_ctrllist_ctrlid, |
772 | 0 | tvb, pos, 2, ENC_LITTLE_ENDIAN); |
773 | 0 | pos += 2; |
774 | 0 | } |
775 | 0 | } |
776 | | |
777 | | /* DTYP 03h — Controller Information Data Structure */ |
778 | | static void |
779 | | nvme_mi_mi_data_ctrl_info(tvbuff_t *tvb, packet_info *pinfo, |
780 | | proto_tree *tree, proto_item *it, int off, int len) |
781 | 0 | { |
782 | 0 | if (len < 17) { |
783 | 0 | nvme_mi_mi_data_truncated(tvb, pinfo, tree, it, off); |
784 | 0 | return; |
785 | 0 | } |
786 | 0 | proto_tree_add_item(tree, hf_nvme_mi_mi_ctrlinfo_portid, |
787 | 0 | tvb, off, 1, ENC_NA); |
788 | | /* bytes 04:01 reserved */ |
789 | 0 | proto_tree_add_bitmask(tree, tvb, off + 5, hf_nvme_mi_mi_ctrlinfo_prii, |
790 | 0 | ett_nvme_mi_mi_field, ctrlinfo_prii_fields, ENC_NA); |
791 | 0 | proto_tree_add_bitmask(tree, tvb, off + 6, hf_nvme_mi_mi_ctrlinfo_pri, |
792 | 0 | ett_nvme_mi_mi_field, ctrlinfo_pri_fields, |
793 | 0 | ENC_LITTLE_ENDIAN); |
794 | 0 | proto_tree_add_item(tree, hf_nvme_mi_mi_ctrlinfo_pcivid, |
795 | 0 | tvb, off + 8, 2, ENC_LITTLE_ENDIAN); |
796 | 0 | proto_tree_add_item(tree, hf_nvme_mi_mi_ctrlinfo_pcidid, |
797 | 0 | tvb, off + 10, 2, ENC_LITTLE_ENDIAN); |
798 | 0 | proto_tree_add_item(tree, hf_nvme_mi_mi_ctrlinfo_pcisvid, |
799 | 0 | tvb, off + 12, 2, ENC_LITTLE_ENDIAN); |
800 | 0 | proto_tree_add_item(tree, hf_nvme_mi_mi_ctrlinfo_pcisdid, |
801 | 0 | tvb, off + 14, 2, ENC_LITTLE_ENDIAN); |
802 | 0 | proto_tree_add_item(tree, hf_nvme_mi_mi_ctrlinfo_pciesn, |
803 | 0 | tvb, off + 16, 1, ENC_NA); |
804 | | /* bytes 31:17 reserved */ |
805 | 0 | } |
806 | | |
807 | | /* DTYP 04h/05h — Optionally Supported / MEB Supported Command List |
808 | | * (both share the count + (CTYP, OPC) entry format) */ |
809 | | static void |
810 | | nvme_mi_mi_data_cmd_list(tvbuff_t *tvb, packet_info *pinfo, |
811 | | proto_tree *tree, proto_item *it, int off, int len) |
812 | 0 | { |
813 | 0 | uint32_t numcmd; |
814 | 0 | int pos = off + 2; |
815 | |
|
816 | 0 | if (len < 2) { |
817 | 0 | nvme_mi_mi_data_truncated(tvb, pinfo, tree, it, off); |
818 | 0 | return; |
819 | 0 | } |
820 | 0 | proto_tree_add_item_ret_uint(tree, hf_nvme_mi_mi_cmdlist_numcmd, |
821 | 0 | tvb, off, 2, ENC_LITTLE_ENDIAN, &numcmd); |
822 | 0 | for (uint32_t i = 0; i < numcmd; i++) { |
823 | 0 | uint64_t ctyp; |
824 | 0 | uint8_t opc; |
825 | 0 | proto_item *opc_it; |
826 | 0 | const char *opc_name = NULL; |
827 | |
|
828 | 0 | if (pos + 2 > off + len) { |
829 | 0 | nvme_mi_mi_data_truncated(tvb, pinfo, tree, it, pos); |
830 | 0 | return; |
831 | 0 | } |
832 | 0 | proto_tree_add_bitmask_ret_uint64(tree, tvb, pos, hf_nvme_mi_mi_cmdlist_ctyp, |
833 | 0 | ett_nvme_mi_mi_field, cmdlist_ctyp_fields, |
834 | 0 | ENC_NA, &ctyp); |
835 | 0 | opc_it = proto_tree_add_item_ret_uint8(tree, hf_nvme_mi_mi_cmdlist_opc, |
836 | 0 | tvb, pos + 1, 1, ENC_NA, &opc); |
837 | | /* NMIMT (CTYP bits 6:3) selects which opcode namespace OPC belongs to |
838 | | * -- both tables already exist in-tree, so name the entry from |
839 | | * whichever one the command actually lives in instead of leaving it |
840 | | * a bare byte. */ |
841 | 0 | switch ((ctyp & 0x78) >> 3) { |
842 | 0 | case NVME_MI_TYPE_MI: |
843 | 0 | opc_name = rval_to_str_const(opc, mi_opcode_vals, "Unknown"); |
844 | 0 | break; |
845 | 0 | case NVME_MI_TYPE_ADMIN: |
846 | 0 | opc_name = nvme_get_opcode_string(opc, 0); |
847 | 0 | break; |
848 | 0 | default: |
849 | 0 | break; |
850 | 0 | } |
851 | 0 | if (opc_name) |
852 | 0 | proto_item_append_text(opc_it, " (%s)", opc_name); |
853 | 0 | pos += 2; |
854 | 0 | } |
855 | 0 | } |
856 | | |
857 | | /* NVM Subsystem Health Data Structure (NSHDS; 8 bytes) */ |
858 | | static void |
859 | | nvme_mi_mi_data_nshds(tvbuff_t *tvb, packet_info *pinfo, |
860 | | proto_tree *tree, proto_item *it, int off, int len) |
861 | 0 | { |
862 | 0 | if (len < 8) { |
863 | 0 | nvme_mi_mi_data_truncated(tvb, pinfo, tree, it, off); |
864 | 0 | return; |
865 | 0 | } |
866 | 0 | proto_tree_add_bitmask(tree, tvb, off, hf_nvme_mi_mi_nshds_nss, |
867 | 0 | ett_nvme_mi_mi_field, nshds_nss_fields, ENC_NA); |
868 | 0 | proto_tree_add_bitmask(tree, tvb, off + 1, hf_nvme_mi_mi_nshds_sw, |
869 | 0 | ett_nvme_mi_mi_field, nshds_sw_fields, ENC_NA); |
870 | 0 | proto_tree_add_item(tree, hf_nvme_mi_mi_nshds_ctemp, |
871 | 0 | tvb, off + 2, 1, ENC_NA); |
872 | 0 | proto_tree_add_item(tree, hf_nvme_mi_mi_nshds_pdlu, |
873 | 0 | tvb, off + 3, 1, ENC_NA); |
874 | 0 | proto_tree_add_bitmask(tree, tvb, off + 4, hf_nvme_mi_mi_nshds_ccs, |
875 | 0 | ett_nvme_mi_mi_field, hsf_fields, |
876 | 0 | ENC_LITTLE_ENDIAN); |
877 | | /* bytes 7:6 reserved */ |
878 | 0 | } |
879 | | |
880 | | /* Array of 16-byte Controller Health Data Structures (CHDS) */ |
881 | | static void |
882 | | nvme_mi_mi_data_chds_list(tvbuff_t *tvb, packet_info *pinfo, |
883 | | proto_tree *tree, proto_item *it, int off, int len) |
884 | 0 | { |
885 | 0 | unsigned idx = 0; |
886 | 0 | int pos = off; |
887 | |
|
888 | 0 | while (off + len - pos >= 16) { |
889 | 0 | proto_tree *etree = proto_tree_add_subtree_format(tree, tvb, pos, 16, |
890 | 0 | ett_nvme_mi_mi_entry, NULL, |
891 | 0 | "Controller Health Data Structure %u", idx); |
892 | 0 | proto_tree_add_item(etree, hf_nvme_mi_mi_chds_ctlid, |
893 | 0 | tvb, pos, 2, ENC_LITTLE_ENDIAN); |
894 | 0 | proto_tree_add_bitmask(etree, tvb, pos + 2, hf_nvme_mi_mi_chds_csts, |
895 | 0 | ett_nvme_mi_mi_field, chds_csts_fields, |
896 | 0 | ENC_LITTLE_ENDIAN); |
897 | 0 | proto_tree_add_item(etree, hf_nvme_mi_mi_chds_ctemp, |
898 | 0 | tvb, pos + 4, 2, ENC_LITTLE_ENDIAN); |
899 | 0 | proto_tree_add_item(etree, hf_nvme_mi_mi_chds_pdlu, |
900 | 0 | tvb, pos + 6, 1, ENC_NA); |
901 | 0 | proto_tree_add_item(etree, hf_nvme_mi_mi_chds_spare, |
902 | 0 | tvb, pos + 7, 1, ENC_NA); |
903 | 0 | proto_tree_add_bitmask(etree, tvb, pos + 8, hf_nvme_mi_mi_chds_cwarn, |
904 | 0 | ett_nvme_mi_mi_field, chds_cwarn_fields, |
905 | 0 | ENC_NA); |
906 | 0 | proto_tree_add_bitmask(etree, tvb, pos + 9, hf_nvme_mi_mi_chds_chsc, |
907 | 0 | ett_nvme_mi_mi_field, hsf_fields, |
908 | 0 | ENC_LITTLE_ENDIAN); |
909 | | /* bytes 15:11 reserved */ |
910 | 0 | pos += 16; |
911 | 0 | idx++; |
912 | 0 | } |
913 | 0 | if (pos < off + len) |
914 | 0 | nvme_mi_mi_data_truncated(tvb, pinfo, tree, it, pos); |
915 | 0 | } |
916 | | |
917 | | /* Append " (<opcode>[: <detail>])" to COL_INFO. */ |
918 | | static void |
919 | | nvme_mi_mi_col_append(packet_info *pinfo, unsigned opcode, const char *detail) |
920 | 0 | { |
921 | 0 | const char *name = rval_to_str_const(opcode, mi_opcode_vals, "Unknown"); |
922 | |
|
923 | 0 | if (detail) |
924 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, " (%s: %s)", name, detail); |
925 | 0 | else |
926 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)", name); |
927 | 0 | } |
928 | | |
929 | | static const char * |
930 | | nvme_mi_mi_configid_name(uint8_t cid) |
931 | 0 | { |
932 | 0 | return rval_to_str_const(cid, mi_configid_vals, "Reserved"); |
933 | 0 | } |
934 | | |
935 | | /* |
936 | | * Decode a request whose only parameter is a type byte in NMD0 bits 31:24 |
937 | | * with NMD1 reserved (Reset RSTTYP; Shutdown SHDNTYP). Values above |
938 | | * max_valid are in the Reserved range. Returns |
939 | | * the type's display name for COL_INFO. |
940 | | */ |
941 | | static const char * |
942 | | nvme_mi_mi_dissect_typebyte_req(tvbuff_t *tvb, packet_info *pinfo, |
943 | | proto_tree *mi_tree, int * const *cdw0_fields, |
944 | | uint8_t max_valid, const value_string *vals) |
945 | 0 | { |
946 | 0 | proto_item *cdw_it; |
947 | 0 | uint64_t cdw0; |
948 | 0 | uint8_t typ; |
949 | |
|
950 | 0 | cdw_it = proto_tree_add_bitmask_ret_uint64(mi_tree, tvb, 4, |
951 | 0 | hf_nvme_mi_mi_cdw0, ett_nvme_mi_mi_field, |
952 | 0 | cdw0_fields, ENC_LITTLE_ENDIAN, &cdw0); |
953 | 0 | typ = (uint8_t)(cdw0 >> 24); |
954 | 0 | if (typ > max_valid) |
955 | 0 | expert_add_info(pinfo, cdw_it, &ei_nvme_mi_mi_reserved_value); |
956 | 0 | proto_tree_add_item(mi_tree, hf_nvme_mi_mi_cdw1, |
957 | 0 | tvb, 8, 4, ENC_LITTLE_ENDIAN); |
958 | 0 | return val_to_str_const(typ, vals, "Reserved"); |
959 | 0 | } |
960 | | |
961 | | /* |
962 | | * The AE Enable List sent as Configuration Set (03h) request data and the |
963 | | * AE Supported List returned as Configuration Get (04h) response data share |
964 | | * one layout: a header (count, version, |
965 | | * total length, header length) followed by <count> entries, each a 1-byte |
966 | | * length plus a 2-byte info word (flag bit 15, AE ID bits 7:0). Only the |
967 | | * field names differ, so the walk below is driven by this descriptor. |
968 | | */ |
969 | | struct nvme_mi_mi_ae_list_hf { |
970 | | int list; |
971 | | int num; |
972 | | int ver; |
973 | | int total_len; |
974 | | int hdr_len; |
975 | | int entry; |
976 | | int entry_len; |
977 | | int flag; |
978 | | int id; |
979 | | const char *entry_name; |
980 | | }; |
981 | | |
982 | | static void |
983 | | dissect_nvme_mi_mi_ae_list(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, |
984 | | proto_item *it, unsigned off, unsigned len, |
985 | | const struct nvme_mi_mi_ae_list_hf *hf) |
986 | 0 | { |
987 | 0 | proto_tree *ae_tree; |
988 | 0 | proto_item *ti; |
989 | 0 | uint32_t num, hdr_len, i; |
990 | 0 | unsigned pos; |
991 | |
|
992 | 0 | ti = proto_tree_add_item(tree, hf->list, tvb, off, len, ENC_NA); |
993 | 0 | ae_tree = proto_item_add_subtree(ti, ett_nvme_mi_mi); |
994 | | |
995 | | /* The list header is 5 bytes; anything shorter is truncated. */ |
996 | 0 | if (len < 5) { |
997 | 0 | nvme_mi_mi_data_truncated(tvb, pinfo, ae_tree, it, off); |
998 | 0 | return; |
999 | 0 | } |
1000 | | |
1001 | 0 | proto_tree_add_item_ret_uint(ae_tree, hf->num, |
1002 | 0 | tvb, off, 1, ENC_LITTLE_ENDIAN, &num); |
1003 | 0 | proto_tree_add_item(ae_tree, hf->ver, |
1004 | 0 | tvb, off + 1, 1, ENC_LITTLE_ENDIAN); |
1005 | 0 | proto_tree_add_item(ae_tree, hf->total_len, |
1006 | 0 | tvb, off + 2, 2, ENC_LITTLE_ENDIAN); |
1007 | 0 | proto_tree_add_item_ret_uint(ae_tree, hf->hdr_len, |
1008 | 0 | tvb, off + 4, 1, ENC_LITTLE_ENDIAN, &hdr_len); |
1009 | | |
1010 | | /* The list body starts at the offset the header declares, not at a fixed |
1011 | | * 5; a value below the 5 defined header bytes is bogus, so clamp forward |
1012 | | * to keep the entry walk inside the body. */ |
1013 | 0 | if (hdr_len < 5) |
1014 | 0 | hdr_len = 5; |
1015 | |
|
1016 | 0 | pos = off + hdr_len; |
1017 | 0 | for (i = 0; i < num; i++) { |
1018 | 0 | proto_tree *e_tree; |
1019 | 0 | proto_item *e_ti; |
1020 | 0 | unsigned elen, entry_len; |
1021 | | |
1022 | | /* Each entry is at least 3 bytes (length + info word). Stop if the |
1023 | | * next entry would run past the list data. */ |
1024 | 0 | if (pos + 3 > off + len) |
1025 | 0 | break; |
1026 | 0 | elen = tvb_get_uint8(tvb, pos); |
1027 | 0 | if (elen < 3) |
1028 | 0 | elen = 3; /* spec value is 3h; guarantee forward progress */ |
1029 | | |
1030 | | /* A bogus length must not drive the entry item past the list data; |
1031 | | * clamp its displayed length to what remains so a truncated list |
1032 | | * stops cleanly rather than raising a bounds exception. */ |
1033 | 0 | entry_len = elen; |
1034 | 0 | if (pos + entry_len > off + len) |
1035 | 0 | entry_len = off + len - pos; |
1036 | |
|
1037 | 0 | e_ti = proto_tree_add_item(ae_tree, hf->entry, |
1038 | 0 | tvb, pos, entry_len, ENC_NA); |
1039 | 0 | proto_item_set_text(e_ti, "%s %u", hf->entry_name, i); |
1040 | 0 | e_tree = proto_item_add_subtree(e_ti, ett_nvme_mi_mi_field); |
1041 | 0 | proto_tree_add_item(e_tree, hf->entry_len, |
1042 | 0 | tvb, pos, 1, ENC_LITTLE_ENDIAN); |
1043 | 0 | proto_tree_add_item(e_tree, hf->flag, |
1044 | 0 | tvb, pos + 1, 2, ENC_LITTLE_ENDIAN); |
1045 | 0 | proto_tree_add_item(e_tree, hf->id, |
1046 | 0 | tvb, pos + 1, 2, ENC_LITTLE_ENDIAN); |
1047 | 0 | pos += elen; |
1048 | 0 | } |
1049 | 0 | } |
1050 | | |
1051 | | /* AE Enable List (Configuration Set request data). */ |
1052 | | static void |
1053 | | dissect_nvme_mi_mi_ae_enable_list(tvbuff_t *tvb, packet_info *pinfo, |
1054 | | proto_tree *tree, proto_item *it, |
1055 | | unsigned off, unsigned len) |
1056 | 0 | { |
1057 | 0 | const struct nvme_mi_mi_ae_list_hf hf = { |
1058 | 0 | hf_nvme_mi_mi_ae, hf_nvme_mi_mi_ae_numaee, |
1059 | 0 | hf_nvme_mi_mi_ae_aeelver, hf_nvme_mi_mi_ae_aeetl, |
1060 | 0 | hf_nvme_mi_mi_ae_aeelhl, hf_nvme_mi_mi_ae_entry, |
1061 | 0 | hf_nvme_mi_mi_ae_aeel, hf_nvme_mi_mi_ae_aee, |
1062 | 0 | hf_nvme_mi_mi_ae_id, "AE Enable", |
1063 | 0 | }; |
1064 | |
|
1065 | 0 | dissect_nvme_mi_mi_ae_list(tvb, pinfo, tree, it, off, len, &hf); |
1066 | 0 | } |
1067 | | |
1068 | | /* AE Supported List (Configuration Get response data). */ |
1069 | | static void |
1070 | | dissect_nvme_mi_mi_ae_supported_list(tvbuff_t *tvb, packet_info *pinfo, |
1071 | | proto_tree *tree, proto_item *it, |
1072 | | unsigned off, unsigned len) |
1073 | 0 | { |
1074 | 0 | const struct nvme_mi_mi_ae_list_hf hf = { |
1075 | 0 | hf_nvme_mi_mi_aes, hf_nvme_mi_mi_aes_numaes, |
1076 | 0 | hf_nvme_mi_mi_aes_aeslver, hf_nvme_mi_mi_aes_aestl, |
1077 | 0 | hf_nvme_mi_mi_aes_aeslhl, hf_nvme_mi_mi_aes_entry, |
1078 | 0 | hf_nvme_mi_mi_aes_aesl, hf_nvme_mi_mi_aes_aese, |
1079 | 0 | hf_nvme_mi_mi_aes_id, "AE Supported", |
1080 | 0 | }; |
1081 | |
|
1082 | 0 | dissect_nvme_mi_mi_ae_list(tvb, pinfo, tree, it, off, len, &hf); |
1083 | 0 | } |
1084 | | |
1085 | | /* |
1086 | | * Body worker. Kept separate from the registered wrapper so that a future |
1087 | | * in-band NVMe-MI Send/Receive decode (NVMe Admin opcodes 1Dh/1Eh tunnel the |
1088 | | * same MI command bytes) can call it directly with an explicit direction and |
1089 | | * a NULL transaction. |
1090 | | */ |
1091 | | static int |
1092 | | dissect_nvme_mi_mi_body(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, |
1093 | | bool resp, struct nvme_mi_transaction *trans) |
1094 | 0 | { |
1095 | 0 | proto_item *it, *it2; |
1096 | 0 | proto_tree *mi_tree; |
1097 | 0 | unsigned len = tvb_reported_length(tvb); |
1098 | |
|
1099 | 0 | it = proto_tree_add_item(tree, proto_nvme_mi_mi, tvb, 0, -1, ENC_NA); |
1100 | 0 | mi_tree = proto_item_add_subtree(it, ett_nvme_mi_mi); |
1101 | |
|
1102 | 0 | if (!resp) { |
1103 | 0 | struct nvme_mi_mi_req_ctx *req = NULL; |
1104 | 0 | const char *detail = NULL; |
1105 | 0 | proto_item *cdw_it; |
1106 | 0 | uint8_t opcode; |
1107 | |
|
1108 | 0 | if (len < 1) { |
1109 | 0 | expert_add_info(pinfo, it, &ei_nvme_mi_mi_truncated); |
1110 | 0 | return tvb_captured_length(tvb); |
1111 | 0 | } |
1112 | | |
1113 | 0 | proto_tree_add_item_ret_uint8(mi_tree, hf_nvme_mi_mi_opcode, tvb, 0, 1, ENC_NA, &opcode); |
1114 | |
|
1115 | 0 | if (len < 12) { |
1116 | 0 | nvme_mi_mi_col_append(pinfo, opcode, NULL); |
1117 | 0 | nvme_mi_mi_data_truncated(tvb, pinfo, mi_tree, it, 1); |
1118 | 0 | return tvb_captured_length(tvb); |
1119 | 0 | } |
1120 | | |
1121 | | /* The command dwords are present; persist the response-layout |
1122 | | * selectors for the response pass. */ |
1123 | 0 | if (trans) |
1124 | 0 | req = nvme_mi_trans_body_ctx(trans, sizeof(*req)); |
1125 | |
|
1126 | 0 | switch (opcode) { |
1127 | 0 | case NVME_MI_MI_OPC_READ_DS: { |
1128 | 0 | uint64_t cdw0; |
1129 | 0 | uint8_t dtyp; |
1130 | |
|
1131 | 0 | cdw_it = proto_tree_add_bitmask_ret_uint64(mi_tree, tvb, 4, |
1132 | 0 | hf_nvme_mi_mi_cdw0, ett_nvme_mi_mi_field, |
1133 | 0 | rds_cdw0_fields, ENC_LITTLE_ENDIAN, &cdw0); |
1134 | 0 | dtyp = (uint8_t)(cdw0 >> 24); |
1135 | 0 | if (dtyp > NVME_MI_DTYP_MAX) |
1136 | 0 | expert_add_info(pinfo, cdw_it, &ei_nvme_mi_mi_reserved_dtyp); |
1137 | 0 | proto_tree_add_bitmask(mi_tree, tvb, 8, hf_nvme_mi_mi_cdw1, |
1138 | 0 | ett_nvme_mi_mi_field, rds_cdw1_fields, |
1139 | 0 | ENC_LITTLE_ENDIAN); |
1140 | 0 | if (req) |
1141 | 0 | req->dtyp = dtyp; |
1142 | 0 | detail = val_to_str_const(dtyp, mi_dtyp_vals, "Reserved"); |
1143 | 0 | break; |
1144 | 0 | } |
1145 | 0 | case NVME_MI_MI_OPC_SUBSYS_HSP: |
1146 | | /* NMD0 is reserved for this command */ |
1147 | 0 | proto_tree_add_item(mi_tree, hf_nvme_mi_mi_cdw0, |
1148 | 0 | tvb, 4, 4, ENC_LITTLE_ENDIAN); |
1149 | 0 | proto_tree_add_bitmask(mi_tree, tvb, 8, hf_nvme_mi_mi_cdw1, |
1150 | 0 | ett_nvme_mi_mi_field, nshsp_cdw1_fields, |
1151 | 0 | ENC_LITTLE_ENDIAN); |
1152 | 0 | break; |
1153 | 0 | case NVME_MI_MI_OPC_CTRL_HSP: |
1154 | 0 | proto_tree_add_bitmask(mi_tree, tvb, 4, hf_nvme_mi_mi_cdw0, |
1155 | 0 | ett_nvme_mi_mi_field, chsp_cdw0_fields, |
1156 | 0 | ENC_LITTLE_ENDIAN); |
1157 | 0 | proto_tree_add_bitmask(mi_tree, tvb, 8, hf_nvme_mi_mi_cdw1, |
1158 | 0 | ett_nvme_mi_mi_field, chsp_cdw1_fields, |
1159 | 0 | ENC_LITTLE_ENDIAN); |
1160 | 0 | break; |
1161 | 0 | case NVME_MI_MI_OPC_CONFIG_SET: |
1162 | 0 | case NVME_MI_MI_OPC_CONFIG_GET: { |
1163 | | /* The CONFIGID value in NMD0 bits 7:0 selects the layout of the |
1164 | | * surrounding configuration-specific fields, so peek it before |
1165 | | * choosing which field array decodes the dword. */ |
1166 | 0 | uint8_t cid = tvb_get_uint8(tvb, 4); |
1167 | 0 | int * const *f0 = cfg_cdw0_fields_cid; |
1168 | 0 | int * const *f1 = NULL; |
1169 | |
|
1170 | 0 | switch (cid) { |
1171 | 0 | case NVME_MI_CFGID_SMBUS_FREQ: |
1172 | 0 | f0 = (opcode == NVME_MI_MI_OPC_CONFIG_SET) |
1173 | 0 | ? cfg_cdw0_fields_sfreq : cfg_cdw0_fields_port; |
1174 | 0 | break; |
1175 | 0 | case NVME_MI_CFGID_HSC: |
1176 | 0 | if (opcode == NVME_MI_MI_OPC_CONFIG_SET) |
1177 | 0 | f1 = cfg_cdw1_fields_hsc; |
1178 | 0 | break; |
1179 | 0 | case NVME_MI_CFGID_MTUS: |
1180 | 0 | f0 = cfg_cdw0_fields_port; |
1181 | 0 | if (opcode == NVME_MI_MI_OPC_CONFIG_SET) |
1182 | 0 | f1 = cfg_cdw1_fields_mtus; |
1183 | 0 | break; |
1184 | 0 | case NVME_MI_CFGID_AE: |
1185 | 0 | if (opcode == NVME_MI_MI_OPC_CONFIG_SET) |
1186 | 0 | f0 = cfg_cdw0_fields_ae_set; |
1187 | 0 | break; |
1188 | 0 | default: |
1189 | 0 | break; |
1190 | 0 | } |
1191 | | |
1192 | 0 | cdw_it = proto_tree_add_bitmask(mi_tree, tvb, 4, |
1193 | 0 | hf_nvme_mi_mi_cdw0, ett_nvme_mi_mi_field, f0, |
1194 | 0 | ENC_LITTLE_ENDIAN); |
1195 | 0 | if (cid == 0 || (cid >= NVME_MI_CFGID_RESERVED_FIRST && |
1196 | 0 | cid <= NVME_MI_CFGID_RESERVED_LAST)) |
1197 | 0 | expert_add_info(pinfo, cdw_it, |
1198 | 0 | &ei_nvme_mi_mi_reserved_configid); |
1199 | 0 | if (f1) |
1200 | 0 | proto_tree_add_bitmask(mi_tree, tvb, 8, hf_nvme_mi_mi_cdw1, |
1201 | 0 | ett_nvme_mi_mi_field, f1, |
1202 | 0 | ENC_LITTLE_ENDIAN); |
1203 | 0 | else |
1204 | 0 | proto_tree_add_item(mi_tree, hf_nvme_mi_mi_cdw1, |
1205 | 0 | tvb, 8, 4, ENC_LITTLE_ENDIAN); |
1206 | 0 | if (req) |
1207 | 0 | req->configid = cid; |
1208 | 0 | detail = nvme_mi_mi_configid_name(cid); |
1209 | 0 | break; |
1210 | 0 | } |
1211 | 0 | case NVME_MI_MI_OPC_VPD_READ: |
1212 | 0 | case NVME_MI_MI_OPC_VPD_WRITE: { |
1213 | | /* DOFST in NMD0 bits 15:0, DLEN in NMD1 bits 15:0 (Figures |
1214 | | * 128/129 and 131/132 — identical layouts). */ |
1215 | 0 | uint64_t cdw0, cdw1; |
1216 | |
|
1217 | 0 | proto_tree_add_bitmask_ret_uint64(mi_tree, tvb, 4, |
1218 | 0 | hf_nvme_mi_mi_cdw0, ett_nvme_mi_mi_field, |
1219 | 0 | vpd_cdw0_fields, ENC_LITTLE_ENDIAN, &cdw0); |
1220 | 0 | proto_tree_add_bitmask_ret_uint64(mi_tree, tvb, 8, |
1221 | 0 | hf_nvme_mi_mi_cdw1, ett_nvme_mi_mi_field, |
1222 | 0 | vpd_cdw1_fields, ENC_LITTLE_ENDIAN, &cdw1); |
1223 | 0 | detail = wmem_strdup_printf(pinfo->pool, "offset %u, %u bytes", |
1224 | 0 | (unsigned)(cdw0 & 0xFFFF), |
1225 | 0 | (unsigned)(cdw1 & 0xFFFF)); |
1226 | 0 | break; |
1227 | 0 | } |
1228 | 0 | case NVME_MI_MI_OPC_RESET: |
1229 | 0 | detail = nvme_mi_mi_dissect_typebyte_req(tvb, pinfo, mi_tree, |
1230 | 0 | reset_cdw0_fields, NVME_MI_RSTTYP_MAX, mi_rsttyp_vals); |
1231 | 0 | break; |
1232 | 0 | case NVME_MI_MI_OPC_SHUTDOWN: |
1233 | 0 | detail = nvme_mi_mi_dissect_typebyte_req(tvb, pinfo, mi_tree, |
1234 | 0 | shutdown_cdw0_fields, NVME_MI_SHDNTYP_MAX, |
1235 | 0 | mi_shdntyp_vals); |
1236 | 0 | break; |
1237 | 0 | default: |
1238 | 0 | proto_tree_add_item(mi_tree, hf_nvme_mi_mi_cdw0, |
1239 | 0 | tvb, 4, 4, ENC_LITTLE_ENDIAN); |
1240 | 0 | proto_tree_add_item(mi_tree, hf_nvme_mi_mi_cdw1, |
1241 | 0 | tvb, 8, 4, ENC_LITTLE_ENDIAN); |
1242 | 0 | break; |
1243 | 0 | } |
1244 | | |
1245 | 0 | nvme_mi_mi_col_append(pinfo, opcode, detail); |
1246 | |
|
1247 | 0 | if (len > 12) { |
1248 | | /* A few commands carry structured Request Data after the command |
1249 | | * dwords: a Configuration Set of the Asynchronous Event config |
1250 | | * sends an AE Enable List; VPD Write sends the VPD bytes (opaque, |
1251 | | * just labeled). Everything else is an opaque blob. */ |
1252 | 0 | if (opcode == NVME_MI_MI_OPC_CONFIG_SET && |
1253 | 0 | tvb_get_uint8(tvb, 4) == NVME_MI_CFGID_AE) { |
1254 | 0 | dissect_nvme_mi_mi_ae_enable_list(tvb, pinfo, mi_tree, it, 12, |
1255 | 0 | len - 12); |
1256 | 0 | } else { |
1257 | 0 | int data_hf = (opcode == NVME_MI_MI_OPC_VPD_WRITE) |
1258 | 0 | ? hf_nvme_mi_mi_vpd_data : hf_nvme_mi_mi_data; |
1259 | 0 | proto_tree_add_item(mi_tree, data_hf, tvb, 12, -1, ENC_NA); |
1260 | 0 | } |
1261 | 0 | } |
1262 | 0 | } else { |
1263 | | /* The response carries no opcode; recover it from the matching request |
1264 | | * (of this same NMIMT). Without one, the helper notes an orphan |
1265 | | * response rather than fabricating an opcode-0 item. */ |
1266 | 0 | unsigned opcode; |
1267 | 0 | it2 = nvme_mi_recover_resp_opcode(tvb, pinfo, mi_tree, it, trans, |
1268 | 0 | NVME_MI_TYPE_MI, hf_nvme_mi_mi_opcode, |
1269 | 0 | &ei_nvme_mi_mi_orphan_response, |
1270 | 0 | &opcode); |
1271 | 0 | bool opcode_known = (it2 != NULL); |
1272 | 0 | const struct nvme_mi_mi_req_ctx *req = opcode_known |
1273 | 0 | ? (const struct nvme_mi_mi_req_ctx *)trans->body_ctx : NULL; |
1274 | 0 | const char *detail = NULL; |
1275 | 0 | uint8_t status; |
1276 | |
|
1277 | 0 | if (opcode_known) { |
1278 | 0 | if (req) { |
1279 | 0 | if (opcode == NVME_MI_MI_OPC_READ_DS) |
1280 | 0 | detail = val_to_str_const(req->dtyp, mi_dtyp_vals, |
1281 | 0 | "Reserved"); |
1282 | 0 | else if (opcode == NVME_MI_MI_OPC_CONFIG_SET || |
1283 | 0 | opcode == NVME_MI_MI_OPC_CONFIG_GET) |
1284 | 0 | detail = nvme_mi_mi_configid_name(req->configid); |
1285 | 0 | } |
1286 | 0 | nvme_mi_mi_col_append(pinfo, opcode, detail); |
1287 | 0 | } |
1288 | |
|
1289 | 0 | if (len < 1) { |
1290 | 0 | expert_add_info(pinfo, it, &ei_nvme_mi_mi_truncated); |
1291 | 0 | return tvb_captured_length(tvb); |
1292 | 0 | } |
1293 | | |
1294 | 0 | proto_tree_add_item_ret_uint8(mi_tree, hf_nvme_mi_mi_status, |
1295 | 0 | tvb, 0, 1, ENC_NA, &status); |
1296 | |
|
1297 | 0 | if (len < 4) { |
1298 | 0 | nvme_mi_mi_data_truncated(tvb, pinfo, mi_tree, it, 1); |
1299 | 0 | return tvb_captured_length(tvb); |
1300 | 0 | } |
1301 | | |
1302 | | /* The NVMe Management Response field and the Response Data are only |
1303 | | * defined for a Success Response. On an error response those same |
1304 | | * bytes are the Parameter Error Location, the More Processing Required |
1305 | | * Time, or Reserved, so the shared helper owns them and NMRESP is not |
1306 | | * rendered over them (NVMe-MI 2.1 "Generic Error Response" / |
1307 | | * "Invalid Parameter Error Response Fields" / "More Processing |
1308 | | * Required Response Fields"). */ |
1309 | 0 | bool success = nvme_mi_dissect_resp_status_bytes(tvb, mi_tree, status); |
1310 | |
|
1311 | 0 | if (success) |
1312 | 0 | proto_tree_add_item(mi_tree, hf_nvme_mi_mi_nmresp, |
1313 | 0 | tvb, 1, 3, ENC_LITTLE_ENDIAN); |
1314 | |
|
1315 | 0 | if (success && opcode_known) { |
1316 | 0 | switch (opcode) { |
1317 | 0 | case NVME_MI_MI_OPC_READ_DS: |
1318 | | /* NMRESP bits 15:0 = Response Data Length (Read NVMe-MI |
1319 | | * Data Structure NVMe Management Response) */ |
1320 | 0 | proto_tree_add_item(mi_tree, hf_nvme_mi_mi_rds_rdl, |
1321 | 0 | tvb, 1, 2, ENC_LITTLE_ENDIAN); |
1322 | 0 | break; |
1323 | 0 | case NVME_MI_MI_OPC_CTRL_HSP: |
1324 | | /* NMRESP bits 23:16 = Response Entries (Controller Health |
1325 | | * Status Poll NVMe Management Response) */ |
1326 | 0 | proto_tree_add_item(mi_tree, hf_nvme_mi_mi_chsp_rent, |
1327 | 0 | tvb, 3, 1, ENC_NA); |
1328 | 0 | break; |
1329 | 0 | case NVME_MI_MI_OPC_CONFIG_GET: |
1330 | 0 | if (!req) |
1331 | 0 | break; |
1332 | 0 | switch (req->configid) { |
1333 | 0 | case NVME_MI_CFGID_SMBUS_FREQ: |
1334 | 0 | proto_tree_add_item(mi_tree, hf_nvme_mi_mi_cfg_sfreq_cur, |
1335 | 0 | tvb, 1, 1, ENC_NA); |
1336 | 0 | break; |
1337 | 0 | case NVME_MI_CFGID_MTUS: |
1338 | 0 | proto_tree_add_item(mi_tree, hf_nvme_mi_mi_cfg_mtus_cur, |
1339 | 0 | tvb, 1, 2, ENC_LITTLE_ENDIAN); |
1340 | 0 | break; |
1341 | 0 | case NVME_MI_CFGID_AE: |
1342 | 0 | proto_tree_add_item(mi_tree, hf_nvme_mi_mi_cfg_aeelver, |
1343 | 0 | tvb, 1, 1, ENC_NA); |
1344 | 0 | break; |
1345 | 0 | default: |
1346 | 0 | break; |
1347 | 0 | } |
1348 | 0 | break; |
1349 | 0 | default: |
1350 | 0 | break; |
1351 | 0 | } |
1352 | 0 | } |
1353 | | |
1354 | 0 | if (len > 4) { |
1355 | 0 | int dlen = (int)len - 4; |
1356 | | |
1357 | | /* Response Data is only defined for a Success response of a known |
1358 | | * opcode; everything else (errors, MPR, orphan) renders raw. */ |
1359 | 0 | if (success && opcode_known) { |
1360 | 0 | switch (opcode) { |
1361 | 0 | case NVME_MI_MI_OPC_READ_DS: |
1362 | | /* The request's DTYP selects the structure layout; without |
1363 | | * it (truncated request) fall back to raw. */ |
1364 | 0 | if (!req) { |
1365 | 0 | proto_tree_add_item(mi_tree, hf_nvme_mi_mi_data, |
1366 | 0 | tvb, 4, -1, ENC_NA); |
1367 | 0 | break; |
1368 | 0 | } |
1369 | 0 | switch (req->dtyp) { |
1370 | 0 | case NVME_MI_DTYP_SUBSYS_INFO: |
1371 | 0 | nvme_mi_mi_data_subsys_info(tvb, pinfo, mi_tree, it, |
1372 | 0 | 4, dlen); |
1373 | 0 | break; |
1374 | 0 | case NVME_MI_DTYP_PORT_INFO: |
1375 | 0 | nvme_mi_mi_data_port_info(tvb, pinfo, mi_tree, it, |
1376 | 0 | 4, dlen); |
1377 | 0 | break; |
1378 | 0 | case NVME_MI_DTYP_CTRL_LIST: |
1379 | 0 | nvme_mi_mi_data_ctrl_list(tvb, pinfo, mi_tree, it, |
1380 | 0 | 4, dlen); |
1381 | 0 | break; |
1382 | 0 | case NVME_MI_DTYP_CTRL_INFO: |
1383 | 0 | nvme_mi_mi_data_ctrl_info(tvb, pinfo, mi_tree, it, |
1384 | 0 | 4, dlen); |
1385 | 0 | break; |
1386 | 0 | case NVME_MI_DTYP_OSC_LIST: |
1387 | 0 | case NVME_MI_DTYP_MEB_LIST: |
1388 | 0 | nvme_mi_mi_data_cmd_list(tvb, pinfo, mi_tree, it, |
1389 | 0 | 4, dlen); |
1390 | 0 | break; |
1391 | 0 | default: |
1392 | 0 | proto_tree_add_item(mi_tree, hf_nvme_mi_mi_data, |
1393 | 0 | tvb, 4, -1, ENC_NA); |
1394 | 0 | break; |
1395 | 0 | } |
1396 | 0 | break; |
1397 | 0 | case NVME_MI_MI_OPC_SUBSYS_HSP: |
1398 | 0 | nvme_mi_mi_data_nshds(tvb, pinfo, mi_tree, it, 4, dlen); |
1399 | 0 | break; |
1400 | 0 | case NVME_MI_MI_OPC_CTRL_HSP: |
1401 | 0 | nvme_mi_mi_data_chds_list(tvb, pinfo, mi_tree, it, 4, dlen); |
1402 | 0 | break; |
1403 | 0 | case NVME_MI_MI_OPC_CONFIG_GET: |
1404 | | /* Only the Asynchronous Event configuration returns |
1405 | | * Response Data: the AE Supported List. */ |
1406 | 0 | if (req && req->configid == NVME_MI_CFGID_AE) |
1407 | 0 | dissect_nvme_mi_mi_ae_supported_list(tvb, pinfo, |
1408 | 0 | mi_tree, it, 4, dlen); |
1409 | 0 | else |
1410 | 0 | proto_tree_add_item(mi_tree, hf_nvme_mi_mi_data, |
1411 | 0 | tvb, 4, -1, ENC_NA); |
1412 | 0 | break; |
1413 | 0 | case NVME_MI_MI_OPC_VPD_READ: |
1414 | | /* Response Data is the requested window of VPD bytes |
1415 | | * (the "VPD Read Response Data" figure). */ |
1416 | 0 | proto_tree_add_item(mi_tree, hf_nvme_mi_mi_vpd_data, |
1417 | 0 | tvb, 4, -1, ENC_NA); |
1418 | 0 | break; |
1419 | 0 | default: |
1420 | 0 | proto_tree_add_item(mi_tree, hf_nvme_mi_mi_data, |
1421 | 0 | tvb, 4, -1, ENC_NA); |
1422 | 0 | break; |
1423 | 0 | } |
1424 | 0 | } else { |
1425 | 0 | proto_tree_add_item(mi_tree, hf_nvme_mi_mi_data, |
1426 | 0 | tvb, 4, -1, ENC_NA); |
1427 | 0 | } |
1428 | 0 | } |
1429 | 0 | } |
1430 | | |
1431 | 0 | return tvb_captured_length(tvb); |
1432 | 0 | } |
1433 | | |
1434 | | static int |
1435 | | dissect_nvme_mi_mi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, |
1436 | | void *data) |
1437 | 0 | { |
1438 | 0 | struct nvme_mi_dissect_ctx *ctx = (struct nvme_mi_dissect_ctx *)data; |
1439 | |
|
1440 | 0 | if (!ctx) |
1441 | 0 | return 0; |
1442 | | |
1443 | 0 | return dissect_nvme_mi_mi_body(tvb, pinfo, tree, ctx->resp, ctx->trans); |
1444 | 0 | } |
1445 | | |
1446 | | void |
1447 | | proto_register_nvme_mi_mi(void) |
1448 | 16 | { |
1449 | | /* *INDENT-OFF* */ |
1450 | 16 | static hf_register_info hf[] = { |
1451 | 16 | { &hf_nvme_mi_mi_opcode, |
1452 | 16 | { "Opcode", "nvme-mi.mi.opcode", |
1453 | 16 | FT_UINT8, BASE_HEX | BASE_RANGE_STRING, RVALS(mi_opcode_vals), 0, |
1454 | 16 | NULL, HFILL }, |
1455 | 16 | }, |
1456 | 16 | { &hf_nvme_mi_mi_cdw0, |
1457 | 16 | { "Command dword 0", "nvme-mi.mi.cdw0", |
1458 | 16 | FT_UINT32, BASE_HEX, NULL, 0, |
1459 | 16 | "NVMe Management Dword 0 (NMD0)", HFILL }, |
1460 | 16 | }, |
1461 | 16 | { &hf_nvme_mi_mi_cdw1, |
1462 | 16 | { "Command dword 1", "nvme-mi.mi.cdw1", |
1463 | 16 | FT_UINT32, BASE_HEX, NULL, 0, |
1464 | 16 | "NVMe Management Dword 1 (NMD1)", HFILL }, |
1465 | 16 | }, |
1466 | 16 | { &hf_nvme_mi_mi_status, |
1467 | 16 | { "Status", "nvme-mi.mi.status", |
1468 | 16 | FT_UINT8, BASE_HEX | BASE_RANGE_STRING, RVALS(nvme_mi_status_vals), 0, |
1469 | 16 | "Response Message Status (NVMe-MI 2.1 'Response Message" |
1470 | 16 | " Status Values')", HFILL }, |
1471 | 16 | }, |
1472 | 16 | { &hf_nvme_mi_mi_nmresp, |
1473 | 16 | { "Management Response", "nvme-mi.mi.nmresp", |
1474 | 16 | FT_UINT24, BASE_HEX, NULL, 0, |
1475 | 16 | NULL, HFILL }, |
1476 | 16 | }, |
1477 | 16 | { &hf_nvme_mi_mi_data, |
1478 | 16 | { "Data", "nvme-mi.mi.data", |
1479 | 16 | FT_BYTES, SEP_SPACE, NULL, 0, |
1480 | 16 | NULL, HFILL }, |
1481 | 16 | }, |
1482 | | |
1483 | | /* Read NVMe-MI Data Structure (00h) */ |
1484 | 16 | { &hf_nvme_mi_mi_rds_dtyp, |
1485 | 16 | { "Data Structure Type (DTYP)", "nvme-mi.mi.rds.dtyp", |
1486 | 16 | FT_UINT32, BASE_HEX, VALS(mi_dtyp_vals), 0xFF000000, |
1487 | 16 | "Data structure to return", HFILL }, |
1488 | 16 | }, |
1489 | 16 | { &hf_nvme_mi_mi_rds_portid, |
1490 | 16 | { "Port Identifier (PORTID)", "nvme-mi.mi.rds.portid", |
1491 | 16 | FT_UINT32, BASE_DEC, NULL, 0x00FF0000, |
1492 | 16 | "Port whose data structure is returned (DTYP 01h/05h)", HFILL }, |
1493 | 16 | }, |
1494 | 16 | { &hf_nvme_mi_mi_rds_ctrlid, |
1495 | 16 | { "Controller Identifier (CTRLID)", "nvme-mi.mi.rds.ctrlid", |
1496 | 16 | FT_UINT32, BASE_HEX, NULL, 0x0000FFFF, |
1497 | 16 | "Controller whose data structure is returned (DTYP 02h-04h)", |
1498 | 16 | HFILL }, |
1499 | 16 | }, |
1500 | 16 | { &hf_nvme_mi_mi_rds_iocsi, |
1501 | 16 | { "I/O Command Set Identifier (IOCSI)", "nvme-mi.mi.rds.iocsi", |
1502 | 16 | FT_UINT32, BASE_HEX, NULL, 0x000000FF, |
1503 | 16 | "Selects the I/O Command Set for Admin entries (DTYP 04h/05h)", |
1504 | 16 | HFILL }, |
1505 | 16 | }, |
1506 | 16 | { &hf_nvme_mi_mi_rds_rdl, |
1507 | 16 | { "Response Data Length (RDL)", "nvme-mi.mi.rds.rdl", |
1508 | 16 | FT_UINT16, BASE_DEC, NULL, 0, |
1509 | 16 | "Length in bytes of the Response Data field", |
1510 | 16 | HFILL }, |
1511 | 16 | }, |
1512 | | |
1513 | | /* NVM Subsystem Health Status Poll (01h) */ |
1514 | 16 | { &hf_nvme_mi_mi_nshsp_cs, |
1515 | 16 | { "Clear Status (CS)", "nvme-mi.mi.nshsp.cs", |
1516 | 16 | FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x80000000, |
1517 | 16 | "Clear the Composite Controller Status Flags after copying them" |
1518 | 16 | " into the response", HFILL }, |
1519 | 16 | }, |
1520 | | |
1521 | | /* Controller Health Status Poll (02h) */ |
1522 | 16 | { &hf_nvme_mi_mi_chsp_all, |
1523 | 16 | { "Report All (ALL)", "nvme-mi.mi.chsp.all", |
1524 | 16 | FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x80000000, |
1525 | 16 | "Ignore the error selection bits when selecting Controllers", |
1526 | 16 | HFILL }, |
1527 | 16 | }, |
1528 | 16 | { &hf_nvme_mi_mi_chsp_incvf, |
1529 | 16 | { "Include SR-IOV Virtual Functions (INCVF)", "nvme-mi.mi.chsp.incvf", |
1530 | 16 | FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x04000000, |
1531 | 16 | NULL, HFILL }, |
1532 | 16 | }, |
1533 | 16 | { &hf_nvme_mi_mi_chsp_incpf, |
1534 | 16 | { "Include SR-IOV Physical Functions (INCPF)", "nvme-mi.mi.chsp.incpf", |
1535 | 16 | FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x02000000, |
1536 | 16 | NULL, HFILL }, |
1537 | 16 | }, |
1538 | 16 | { &hf_nvme_mi_mi_chsp_incf, |
1539 | 16 | { "Include PCI Functions (INCF)", "nvme-mi.mi.chsp.incf", |
1540 | 16 | FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x01000000, |
1541 | 16 | NULL, HFILL }, |
1542 | 16 | }, |
1543 | 16 | { &hf_nvme_mi_mi_chsp_maxrent, |
1544 | 16 | { "Maximum Response Entries (MAXRENT)", "nvme-mi.mi.chsp.maxrent", |
1545 | 16 | FT_UINT32, BASE_DEC, NULL, 0x00FF0000, |
1546 | 16 | "Maximum number of CHDS entries to return, 0's based", HFILL }, |
1547 | 16 | }, |
1548 | 16 | { &hf_nvme_mi_mi_chsp_sctlid, |
1549 | 16 | { "Starting Controller ID (SCTLID)", "nvme-mi.mi.chsp.sctlid", |
1550 | 16 | FT_UINT32, BASE_HEX, NULL, 0x0000FFFF, |
1551 | 16 | NULL, HFILL }, |
1552 | 16 | }, |
1553 | 16 | { &hf_nvme_mi_mi_chsp_ccf, |
1554 | 16 | { "Clear Changed Flags (CCF)", "nvme-mi.mi.chsp.ccf", |
1555 | 16 | FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x80000000, |
1556 | 16 | "Copy then clear each returned Controller's Health Status" |
1557 | 16 | " Changed Flags", HFILL }, |
1558 | 16 | }, |
1559 | 16 | { &hf_nvme_mi_mi_chsp_cwarn, |
1560 | 16 | { "Select on Critical Warning (CWARN)", "nvme-mi.mi.chsp.cwarn", |
1561 | 16 | FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00000010, |
1562 | 16 | NULL, HFILL }, |
1563 | 16 | }, |
1564 | 16 | { &hf_nvme_mi_mi_chsp_spare, |
1565 | 16 | { "Select on Available Spare (SPARE)", "nvme-mi.mi.chsp.spare", |
1566 | 16 | FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00000008, |
1567 | 16 | NULL, HFILL }, |
1568 | 16 | }, |
1569 | 16 | { &hf_nvme_mi_mi_chsp_pdlu, |
1570 | 16 | { "Select on Percentage Used (PDLU)", "nvme-mi.mi.chsp.pdlu", |
1571 | 16 | FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00000004, |
1572 | 16 | NULL, HFILL }, |
1573 | 16 | }, |
1574 | 16 | { &hf_nvme_mi_mi_chsp_ctemp, |
1575 | 16 | { "Select on Composite Temperature Changes (CTEMP)", |
1576 | 16 | "nvme-mi.mi.chsp.ctemp", |
1577 | 16 | FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00000002, |
1578 | 16 | NULL, HFILL }, |
1579 | 16 | }, |
1580 | 16 | { &hf_nvme_mi_mi_chsp_csts, |
1581 | 16 | { "Select on Controller Status Changes (CSTS)", |
1582 | 16 | "nvme-mi.mi.chsp.csts", |
1583 | 16 | FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00000001, |
1584 | 16 | NULL, HFILL }, |
1585 | 16 | }, |
1586 | 16 | { &hf_nvme_mi_mi_chsp_rent, |
1587 | 16 | { "Response Entries (RENT)", "nvme-mi.mi.chsp.rent", |
1588 | 16 | FT_UINT8, BASE_DEC, NULL, 0, |
1589 | 16 | "Number of CHDS entries in the Response Data", |
1590 | 16 | HFILL }, |
1591 | 16 | }, |
1592 | | |
1593 | | /* Configuration Set (03h) / Configuration Get (04h) */ |
1594 | 16 | { &hf_nvme_mi_mi_cfg_cid, |
1595 | 16 | { "Configuration Identifier (CID)", "nvme-mi.mi.config.cid", |
1596 | 16 | FT_UINT32, BASE_HEX | BASE_RANGE_STRING, RVALS(mi_configid_vals), 0x000000FF, |
1597 | 16 | "Configuration being read or written (NVMe-MI 2.1 'NVMe" |
1598 | 16 | " Management Interface Configuration Identifiers')", HFILL }, |
1599 | 16 | }, |
1600 | 16 | { &hf_nvme_mi_mi_cfg_portid, |
1601 | 16 | { "Port Identifier (PORTID)", "nvme-mi.mi.config.portid", |
1602 | 16 | FT_UINT32, BASE_DEC, NULL, 0xFF000000, |
1603 | 16 | NULL, HFILL }, |
1604 | 16 | }, |
1605 | 16 | { &hf_nvme_mi_mi_cfg_sfreq, |
1606 | 16 | { "SMBus/I2C Frequency (SFREQ)", "nvme-mi.mi.config.sfreq", |
1607 | 16 | FT_UINT32, BASE_HEX, VALS(mi_sfreq_vals), 0x00000F00, |
1608 | 16 | "New frequency for the 2-Wire port", HFILL }, |
1609 | 16 | }, |
1610 | 16 | { &hf_nvme_mi_mi_cfg_mtus, |
1611 | 16 | { "MCTP Transmission Unit Size (MTUS)", "nvme-mi.mi.config.mtus", |
1612 | 16 | FT_UINT32, BASE_DEC, NULL, 0x0000FFFF, |
1613 | 16 | "Requested MCTP Transmission Unit Size in bytes", |
1614 | 16 | HFILL }, |
1615 | 16 | }, |
1616 | 16 | { &hf_nvme_mi_mi_cfg_sfreq_cur, |
1617 | 16 | { "Current SMBus/I2C Frequency (SFREQ)", |
1618 | 16 | "nvme-mi.mi.config.sfreq_cur", |
1619 | 16 | FT_UINT8, BASE_HEX, VALS(mi_sfreq_vals), 0x0F, |
1620 | 16 | "Current 2-Wire frequency", HFILL }, |
1621 | 16 | }, |
1622 | 16 | { &hf_nvme_mi_mi_cfg_mtus_cur, |
1623 | 16 | { "Current MCTP Transmission Unit Size (MTUS)", |
1624 | 16 | "nvme-mi.mi.config.mtus_cur", |
1625 | 16 | FT_UINT16, BASE_DEC, NULL, 0, |
1626 | 16 | "Current MCTP Transmission Unit Size in bytes", |
1627 | 16 | HFILL }, |
1628 | 16 | }, |
1629 | 16 | { &hf_nvme_mi_mi_cfg_aeelver, |
1630 | 16 | { "AE Enable List Version Number (AEELVER)", |
1631 | 16 | "nvme-mi.mi.config.aeelver", |
1632 | 16 | FT_UINT8, BASE_HEX, NULL, 0, |
1633 | 16 | "Version of the AE Enable List data structure", |
1634 | 16 | HFILL }, |
1635 | 16 | }, |
1636 | 16 | { &hf_nvme_mi_mi_cfg_hsc_tcida, |
1637 | 16 | { "Clear Telemetry Controller-Initiated Data Available (TCIDA)", |
1638 | 16 | "nvme-mi.mi.config.hsc.tcida", |
1639 | 16 | FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00001000, |
1640 | 16 | NULL, HFILL }, |
1641 | 16 | }, |
1642 | 16 | { &hf_nvme_mi_mi_cfg_hsc_cwarn, |
1643 | 16 | { "Clear Critical Warning (CWARN)", "nvme-mi.mi.config.hsc.cwarn", |
1644 | 16 | FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00000800, |
1645 | 16 | NULL, HFILL }, |
1646 | 16 | }, |
1647 | 16 | { &hf_nvme_mi_mi_cfg_hsc_spare, |
1648 | 16 | { "Clear Available Spare (SPARE)", "nvme-mi.mi.config.hsc.spare", |
1649 | 16 | FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00000400, |
1650 | 16 | NULL, HFILL }, |
1651 | 16 | }, |
1652 | 16 | { &hf_nvme_mi_mi_cfg_hsc_pdlu, |
1653 | 16 | { "Clear Percentage Used (PDLU)", "nvme-mi.mi.config.hsc.pdlu", |
1654 | 16 | FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00000200, |
1655 | 16 | NULL, HFILL }, |
1656 | 16 | }, |
1657 | 16 | { &hf_nvme_mi_mi_cfg_hsc_ctemp, |
1658 | 16 | { "Clear Composite Temperature (CTEMP)", |
1659 | 16 | "nvme-mi.mi.config.hsc.ctemp", |
1660 | 16 | FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00000100, |
1661 | 16 | NULL, HFILL }, |
1662 | 16 | }, |
1663 | 16 | { &hf_nvme_mi_mi_cfg_hsc_cschng, |
1664 | 16 | { "Clear Controller Status Change (CSCHNG)", |
1665 | 16 | "nvme-mi.mi.config.hsc.cschng", |
1666 | 16 | FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00000080, |
1667 | 16 | NULL, HFILL }, |
1668 | 16 | }, |
1669 | 16 | { &hf_nvme_mi_mi_cfg_hsc_fa, |
1670 | 16 | { "Clear Firmware Activated (FA)", "nvme-mi.mi.config.hsc.fa", |
1671 | 16 | FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00000040, |
1672 | 16 | NULL, HFILL }, |
1673 | 16 | }, |
1674 | 16 | { &hf_nvme_mi_mi_cfg_hsc_nac, |
1675 | 16 | { "Clear Namespace Attribute Changed (NAC)", |
1676 | 16 | "nvme-mi.mi.config.hsc.nac", |
1677 | 16 | FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00000020, |
1678 | 16 | NULL, HFILL }, |
1679 | 16 | }, |
1680 | 16 | { &hf_nvme_mi_mi_cfg_hsc_ceco, |
1681 | 16 | { "Clear Controller Enable Change Occurred (CECO)", |
1682 | 16 | "nvme-mi.mi.config.hsc.ceco", |
1683 | 16 | FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00000010, |
1684 | 16 | NULL, HFILL }, |
1685 | 16 | }, |
1686 | 16 | { &hf_nvme_mi_mi_cfg_hsc_nssro, |
1687 | 16 | { "Clear NVM Subsystem Reset Occurred (NSSRO)", |
1688 | 16 | "nvme-mi.mi.config.hsc.nssro", |
1689 | 16 | FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00000008, |
1690 | 16 | NULL, HFILL }, |
1691 | 16 | }, |
1692 | 16 | { &hf_nvme_mi_mi_cfg_hsc_shst, |
1693 | 16 | { "Clear Shutdown Status (SHST)", "nvme-mi.mi.config.hsc.shst", |
1694 | 16 | FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00000004, |
1695 | 16 | NULL, HFILL }, |
1696 | 16 | }, |
1697 | 16 | { &hf_nvme_mi_mi_cfg_hsc_cfs, |
1698 | 16 | { "Clear Controller Fatal Status (CFS)", |
1699 | 16 | "nvme-mi.mi.config.hsc.cfs", |
1700 | 16 | FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00000002, |
1701 | 16 | NULL, HFILL }, |
1702 | 16 | }, |
1703 | 16 | { &hf_nvme_mi_mi_cfg_hsc_rdy, |
1704 | 16 | { "Clear Ready (RDY)", "nvme-mi.mi.config.hsc.rdy", |
1705 | 16 | FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00000001, |
1706 | 16 | NULL, HFILL }, |
1707 | 16 | }, |
1708 | | |
1709 | | /* VPD Read (05h) / VPD Write (06h) */ |
1710 | 16 | { &hf_nvme_mi_mi_vpd_dofst, |
1711 | 16 | { "Data Offset (DOFST)", "nvme-mi.mi.vpd.dofst", |
1712 | 16 | FT_UINT32, BASE_DEC, NULL, 0x0000FFFF, |
1713 | 16 | "Starting byte offset into the VPD", HFILL }, |
1714 | 16 | }, |
1715 | 16 | { &hf_nvme_mi_mi_vpd_dlen, |
1716 | 16 | { "Data Length (DLEN)", "nvme-mi.mi.vpd.dlen", |
1717 | 16 | FT_UINT32, BASE_DEC, NULL, 0x0000FFFF, |
1718 | 16 | "Length in bytes to read from or write to the VPD", HFILL }, |
1719 | 16 | }, |
1720 | 16 | { &hf_nvme_mi_mi_vpd_data, |
1721 | 16 | { "VPD Data", "nvme-mi.mi.vpd.data", |
1722 | 16 | FT_BYTES, SEP_SPACE, NULL, 0, |
1723 | 16 | "VPD contents transferred by the command (NVMe-MI 2.1 'VPD" |
1724 | 16 | " Read Response Data' / 'VPD Write Request Data')", |
1725 | 16 | HFILL }, |
1726 | 16 | }, |
1727 | | |
1728 | | /* Configuration Set (03h) Asynchronous Event — command dword 0 */ |
1729 | 16 | { &hf_nvme_mi_mi_cfg_ae_envfa, |
1730 | 16 | { "Enable SR-IOV Virtual Functions AE (ENVFA)", |
1731 | 16 | "nvme-mi.mi.config.ae.envfa", |
1732 | 16 | FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x04000000, |
1733 | 16 | NULL, HFILL }, |
1734 | 16 | }, |
1735 | 16 | { &hf_nvme_mi_mi_cfg_ae_enpfa, |
1736 | 16 | { "Enable SR-IOV Physical Functions AE (ENPFA)", |
1737 | 16 | "nvme-mi.mi.config.ae.enpfa", |
1738 | 16 | FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x02000000, |
1739 | 16 | NULL, HFILL }, |
1740 | 16 | }, |
1741 | 16 | { &hf_nvme_mi_mi_cfg_ae_encfa, |
1742 | 16 | { "Enable PCI Functions AE (ENCFA)", "nvme-mi.mi.config.ae.encfa", |
1743 | 16 | FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x01000000, |
1744 | 16 | NULL, HFILL }, |
1745 | 16 | }, |
1746 | 16 | { &hf_nvme_mi_mi_cfg_ae_aemd, |
1747 | 16 | { "AEM Delay (AEMD)", "nvme-mi.mi.config.ae.aemd", |
1748 | 16 | FT_UINT32, BASE_DEC, NULL, 0x00FF0000, |
1749 | 16 | "Delay in seconds before an AEM is transmitted", |
1750 | 16 | HFILL }, |
1751 | 16 | }, |
1752 | 16 | { &hf_nvme_mi_mi_cfg_ae_aerd, |
1753 | 16 | { "AEM Retry Delay (AERD)", "nvme-mi.mi.config.ae.aerd", |
1754 | 16 | FT_UINT32, BASE_DEC, NULL, 0x0000FF00, |
1755 | 16 | "Delay in 100 ms units between AEM retransmissions", |
1756 | 16 | HFILL }, |
1757 | 16 | }, |
1758 | | |
1759 | | /* Configuration Set (03h) Asynchronous Event — AE Enable List */ |
1760 | 16 | { &hf_nvme_mi_mi_ae, |
1761 | 16 | { "AE Enable List", "nvme-mi.mi.ae", |
1762 | 16 | FT_BYTES, BASE_NONE, NULL, 0, |
1763 | 16 | "Asynchronous Event Enable List request data (NVMe-MI 2.1" |
1764 | 16 | " 'AE Enable List Data Structure')", HFILL }, |
1765 | 16 | }, |
1766 | 16 | { &hf_nvme_mi_mi_ae_numaee, |
1767 | 16 | { "Number of AE Enable Data Structures (NUMAEE)", "nvme-mi.mi.ae.numaee", |
1768 | 16 | FT_UINT8, BASE_DEC, NULL, 0, |
1769 | 16 | NULL, HFILL }, |
1770 | 16 | }, |
1771 | 16 | { &hf_nvme_mi_mi_ae_aeelver, |
1772 | 16 | { "AE Enable List Version (AEELVER)", "nvme-mi.mi.ae.aeelver", |
1773 | 16 | FT_UINT8, BASE_DEC, NULL, 0, |
1774 | 16 | NULL, HFILL }, |
1775 | 16 | }, |
1776 | 16 | { &hf_nvme_mi_mi_ae_aeetl, |
1777 | 16 | { "AE Enable Total Length (AEETL)", "nvme-mi.mi.ae.aeetl", |
1778 | 16 | FT_UINT16, BASE_DEC, NULL, 0, |
1779 | 16 | NULL, HFILL }, |
1780 | 16 | }, |
1781 | 16 | { &hf_nvme_mi_mi_ae_aeelhl, |
1782 | 16 | { "AE Enable List Header Length (AEELHL)", "nvme-mi.mi.ae.aeelhl", |
1783 | 16 | FT_UINT8, BASE_DEC, NULL, 0, |
1784 | 16 | NULL, HFILL }, |
1785 | 16 | }, |
1786 | 16 | { &hf_nvme_mi_mi_ae_entry, |
1787 | 16 | { "AE Enable", "nvme-mi.mi.ae.entry", |
1788 | 16 | FT_BYTES, BASE_NONE, NULL, 0, |
1789 | 16 | "AE Enable data structure", HFILL }, |
1790 | 16 | }, |
1791 | 16 | { &hf_nvme_mi_mi_ae_aeel, |
1792 | 16 | { "AE Enable Length (AEEL)", "nvme-mi.mi.ae.aeel", |
1793 | 16 | FT_UINT8, BASE_DEC, NULL, 0, |
1794 | 16 | NULL, HFILL }, |
1795 | 16 | }, |
1796 | 16 | { &hf_nvme_mi_mi_ae_aee, |
1797 | 16 | { "AE Enable (AEE)", "nvme-mi.mi.ae.aee", |
1798 | 16 | FT_BOOLEAN, 16, TFS(&tfs_set_notset), 0x8000, |
1799 | 16 | "Enable (1) or disable (0) the indicated asynchronous event", HFILL }, |
1800 | 16 | }, |
1801 | 16 | { &hf_nvme_mi_mi_ae_id, |
1802 | 16 | { "AE Enable ID", "nvme-mi.mi.ae.id", |
1803 | 16 | FT_UINT16, BASE_HEX | BASE_RANGE_STRING, RVALS(mi_ae_id_vals), 0x00FF, |
1804 | 16 | "Identifier of the asynchronous event (NVMe-MI 2.1" |
1805 | 16 | " 'Asynchronous Events')", HFILL }, |
1806 | 16 | }, |
1807 | | |
1808 | | /* Configuration Get (04h) Asynchronous Event — AE Supported List */ |
1809 | 16 | { &hf_nvme_mi_mi_aes, |
1810 | 16 | { "AE Supported List", "nvme-mi.mi.aes", |
1811 | 16 | FT_BYTES, BASE_NONE, NULL, 0, |
1812 | 16 | "Asynchronous Event Supported List response data (NVMe-MI 2.1" |
1813 | 16 | " 'AE Supported List Data Structure')", |
1814 | 16 | HFILL }, |
1815 | 16 | }, |
1816 | 16 | { &hf_nvme_mi_mi_aes_numaes, |
1817 | 16 | { "Number of AE Supported Data Structures (NUMAES)", |
1818 | 16 | "nvme-mi.mi.aes.numaes", |
1819 | 16 | FT_UINT8, BASE_DEC, NULL, 0, |
1820 | 16 | NULL, HFILL }, |
1821 | 16 | }, |
1822 | 16 | { &hf_nvme_mi_mi_aes_aeslver, |
1823 | 16 | { "AE Supported List Version (AESLVER)", "nvme-mi.mi.aes.aeslver", |
1824 | 16 | FT_UINT8, BASE_DEC, NULL, 0, |
1825 | 16 | NULL, HFILL }, |
1826 | 16 | }, |
1827 | 16 | { &hf_nvme_mi_mi_aes_aestl, |
1828 | 16 | { "AE Supported Total Length (AESTL)", "nvme-mi.mi.aes.aestl", |
1829 | 16 | FT_UINT16, BASE_DEC, NULL, 0, |
1830 | 16 | NULL, HFILL }, |
1831 | 16 | }, |
1832 | 16 | { &hf_nvme_mi_mi_aes_aeslhl, |
1833 | 16 | { "AE Supported List Header Length (AESLHL)", |
1834 | 16 | "nvme-mi.mi.aes.aeslhl", |
1835 | 16 | FT_UINT8, BASE_DEC, NULL, 0, |
1836 | 16 | NULL, HFILL }, |
1837 | 16 | }, |
1838 | 16 | { &hf_nvme_mi_mi_aes_entry, |
1839 | 16 | { "AE Supported", "nvme-mi.mi.aes.entry", |
1840 | 16 | FT_BYTES, BASE_NONE, NULL, 0, |
1841 | 16 | "AE Supported data structure", HFILL }, |
1842 | 16 | }, |
1843 | 16 | { &hf_nvme_mi_mi_aes_aesl, |
1844 | 16 | { "AE Supported Length (AESL)", "nvme-mi.mi.aes.aesl", |
1845 | 16 | FT_UINT8, BASE_DEC, NULL, 0, |
1846 | 16 | NULL, HFILL }, |
1847 | 16 | }, |
1848 | 16 | { &hf_nvme_mi_mi_aes_aese, |
1849 | 16 | { "AE Supported Enable (AESE)", "nvme-mi.mi.aes.aese", |
1850 | 16 | FT_BOOLEAN, 16, TFS(&tfs_set_notset), 0x8000, |
1851 | 16 | "The indicated asynchronous event is currently enabled", HFILL }, |
1852 | 16 | }, |
1853 | 16 | { &hf_nvme_mi_mi_aes_id, |
1854 | 16 | { "AE Supported ID", "nvme-mi.mi.aes.id", |
1855 | 16 | FT_UINT16, BASE_HEX | BASE_RANGE_STRING, RVALS(mi_ae_id_vals), 0x00FF, |
1856 | 16 | "Identifier of the asynchronous event (NVMe-MI 2.1" |
1857 | 16 | " 'Asynchronous Events')", HFILL }, |
1858 | 16 | }, |
1859 | | |
1860 | | /* Reset (07h) */ |
1861 | 16 | { &hf_nvme_mi_mi_reset_rsttyp, |
1862 | 16 | { "Reset Type (RSTTYP)", "nvme-mi.mi.reset.rsttyp", |
1863 | 16 | FT_UINT32, BASE_HEX, VALS(mi_rsttyp_vals), 0xFF000000, |
1864 | 16 | "Type of reset to perform", HFILL }, |
1865 | 16 | }, |
1866 | | |
1867 | | /* Shutdown (0Ch) */ |
1868 | 16 | { &hf_nvme_mi_mi_shutdown_shdntyp, |
1869 | 16 | { "Shutdown Type (SHDNTYP)", "nvme-mi.mi.shutdown.shdntyp", |
1870 | 16 | FT_UINT32, BASE_HEX, VALS(mi_shdntyp_vals), 0xFF000000, |
1871 | 16 | "Type of shutdown to perform", HFILL }, |
1872 | 16 | }, |
1873 | | |
1874 | | /* NVM Subsystem Information (DTYP 00h) */ |
1875 | 16 | { &hf_nvme_mi_mi_subsys_nump, |
1876 | 16 | { "Number of Ports (NUMP)", "nvme-mi.mi.subsys.nump", |
1877 | 16 | FT_UINT8, BASE_DEC, NULL, 0, |
1878 | 16 | "Maximum number of ports supported, 0's based", HFILL }, |
1879 | 16 | }, |
1880 | 16 | { &hf_nvme_mi_mi_subsys_mjr, |
1881 | 16 | { "NVMe-MI Major Version Number (MJR)", "nvme-mi.mi.subsys.mjr", |
1882 | 16 | FT_UINT8, BASE_DEC, NULL, 0, |
1883 | 16 | NULL, HFILL }, |
1884 | 16 | }, |
1885 | 16 | { &hf_nvme_mi_mi_subsys_mnr, |
1886 | 16 | { "NVMe-MI Minor Version Number (MNR)", "nvme-mi.mi.subsys.mnr", |
1887 | 16 | FT_UINT8, BASE_DEC, NULL, 0, |
1888 | 16 | NULL, HFILL }, |
1889 | 16 | }, |
1890 | 16 | { &hf_nvme_mi_mi_subsys_nnsc, |
1891 | 16 | { "NVM Subsystem Capabilities (NNSC)", "nvme-mi.mi.subsys.nnsc", |
1892 | 16 | FT_UINT8, BASE_HEX, NULL, 0, |
1893 | 16 | NULL, HFILL }, |
1894 | 16 | }, |
1895 | 16 | { &hf_nvme_mi_mi_subsys_sre, |
1896 | 16 | { "Status Reporting Enhancements (SRE)", "nvme-mi.mi.subsys.sre", |
1897 | 16 | FT_BOOLEAN, 8, TFS(&tfs_supported_not_supported), 0x01, |
1898 | 16 | NULL, HFILL }, |
1899 | 16 | }, |
1900 | | |
1901 | | /* Port Information (DTYP 01h) */ |
1902 | 16 | { &hf_nvme_mi_mi_port_prttyp, |
1903 | 16 | { "Port Type (PRTTYP)", "nvme-mi.mi.port.prttyp", |
1904 | 16 | FT_UINT8, BASE_HEX, VALS(mi_prttyp_vals), 0, |
1905 | 16 | NULL, HFILL }, |
1906 | 16 | }, |
1907 | 16 | { &hf_nvme_mi_mi_port_prtcap, |
1908 | 16 | { "Port Capabilities (PRTCAP)", "nvme-mi.mi.port.prtcap", |
1909 | 16 | FT_UINT8, BASE_HEX, NULL, 0, |
1910 | 16 | NULL, HFILL }, |
1911 | 16 | }, |
1912 | 16 | { &hf_nvme_mi_mi_port_aems, |
1913 | 16 | { "Asynchronous Event Messages Supported (AEMS)", |
1914 | 16 | "nvme-mi.mi.port.aems", |
1915 | 16 | FT_BOOLEAN, 8, TFS(&tfs_supported_not_supported), 0x02, |
1916 | 16 | NULL, HFILL }, |
1917 | 16 | }, |
1918 | 16 | { &hf_nvme_mi_mi_port_ciaps, |
1919 | 16 | { "Command Initiated Auto Pause Supported (CIAPS)", |
1920 | 16 | "nvme-mi.mi.port.ciaps", |
1921 | 16 | FT_BOOLEAN, 8, TFS(&tfs_supported_not_supported), 0x01, |
1922 | 16 | NULL, HFILL }, |
1923 | 16 | }, |
1924 | 16 | { &hf_nvme_mi_mi_port_mmtus, |
1925 | 16 | { "Maximum MCTP Transmission Unit Size (MMTUS)", |
1926 | 16 | "nvme-mi.mi.port.mmtus", |
1927 | 16 | FT_UINT16, BASE_DEC, NULL, 0, |
1928 | 16 | NULL, HFILL }, |
1929 | 16 | }, |
1930 | 16 | { &hf_nvme_mi_mi_port_mebs, |
1931 | 16 | { "Management Endpoint Buffer Size (MEBS)", "nvme-mi.mi.port.mebs", |
1932 | 16 | FT_UINT32, BASE_DEC, NULL, 0, |
1933 | 16 | "Size in bytes; 0 = no Management Endpoint Buffer", HFILL }, |
1934 | 16 | }, |
1935 | 16 | { &hf_nvme_mi_mi_port_pcie_mps, |
1936 | 16 | { "PCIe Maximum Payload Size (PCIEMPS)", "nvme-mi.mi.port.pcie.mps", |
1937 | 16 | FT_UINT8, BASE_HEX, VALS(mi_pciemps_vals), 0, |
1938 | 16 | NULL, HFILL }, |
1939 | 16 | }, |
1940 | 16 | { &hf_nvme_mi_mi_port_pcie_slsv, |
1941 | 16 | { "PCIe Supported Link Speeds Vector (PCIESLSV)", |
1942 | 16 | "nvme-mi.mi.port.pcie.slsv", |
1943 | 16 | FT_UINT8, BASE_HEX, NULL, 0, |
1944 | 16 | "Bit 0 = 2.5, 1 = 5.0, 2 = 8.0, 3 = 16.0, 4 = 32.0, 5 = 64.0 GT/s", |
1945 | 16 | HFILL }, |
1946 | 16 | }, |
1947 | 16 | { &hf_nvme_mi_mi_port_pcie_cls, |
1948 | 16 | { "PCIe Current Link Speed (PCIECLS)", "nvme-mi.mi.port.pcie.cls", |
1949 | 16 | FT_UINT8, BASE_HEX, VALS(mi_pciecls_vals), 0, |
1950 | 16 | NULL, HFILL }, |
1951 | 16 | }, |
1952 | 16 | { &hf_nvme_mi_mi_port_pcie_mlw, |
1953 | 16 | { "PCIe Maximum Link Width (PCIEMLW)", "nvme-mi.mi.port.pcie.mlw", |
1954 | 16 | FT_UINT8, BASE_DEC, NULL, 0, |
1955 | 16 | "Maximum link width in lanes", HFILL }, |
1956 | 16 | }, |
1957 | 16 | { &hf_nvme_mi_mi_port_pcie_nlw, |
1958 | 16 | { "PCIe Negotiated Link Width (PCIENLW)", "nvme-mi.mi.port.pcie.nlw", |
1959 | 16 | FT_UINT8, BASE_DEC, NULL, 0, |
1960 | 16 | "Negotiated link width in lanes; 0 = link not active", HFILL }, |
1961 | 16 | }, |
1962 | 16 | { &hf_nvme_mi_mi_port_pcie_pn, |
1963 | 16 | { "PCIe Port Number (PCIEPN)", "nvme-mi.mi.port.pcie.pn", |
1964 | 16 | FT_UINT8, BASE_DEC, NULL, 0, |
1965 | 16 | NULL, HFILL }, |
1966 | 16 | }, |
1967 | 16 | { &hf_nvme_mi_mi_port_twire_cvpdaddr, |
1968 | 16 | { "Current VPD Address (CVPDADDR)", "nvme-mi.mi.port.cvpdaddr", |
1969 | 16 | FT_UINT8, BASE_HEX, NULL, 0, |
1970 | 16 | "Current VPD SMBus/I2C address; 0 = no VPD", HFILL }, |
1971 | 16 | }, |
1972 | 16 | { &hf_nvme_mi_mi_port_twire_mvpdfreq, |
1973 | 16 | { "Maximum VPD Access Frequency (MVPDFREQ)", |
1974 | 16 | "nvme-mi.mi.port.mvpdfreq", |
1975 | 16 | FT_UINT8, BASE_HEX, VALS(mi_vpdfreq_vals), 0, |
1976 | 16 | NULL, HFILL }, |
1977 | 16 | }, |
1978 | 16 | { &hf_nvme_mi_mi_port_twire_cmeaddr, |
1979 | 16 | { "Current Management Endpoint Address (CMEADDR)", |
1980 | 16 | "nvme-mi.mi.port.cmeaddr", |
1981 | 16 | FT_UINT8, BASE_HEX, NULL, 0, |
1982 | 16 | "Current 2-Wire address; 0 = no Management Endpoint", HFILL }, |
1983 | 16 | }, |
1984 | 16 | { &hf_nvme_mi_mi_port_twire_twprt, |
1985 | 16 | { "2-Wire Protocols Supported (TWPRT)", "nvme-mi.mi.port.twprt", |
1986 | 16 | FT_UINT8, BASE_HEX, NULL, 0, |
1987 | 16 | NULL, HFILL }, |
1988 | 16 | }, |
1989 | 16 | { &hf_nvme_mi_mi_port_twire_i3csprt, |
1990 | 16 | { "I3C Support (I3CSPRT)", "nvme-mi.mi.port.i3csprt", |
1991 | 16 | FT_BOOLEAN, 8, TFS(&tfs_supported_not_supported), 0x80, |
1992 | 16 | NULL, HFILL }, |
1993 | 16 | }, |
1994 | 16 | { &hf_nvme_mi_mi_port_twire_msmbfreq, |
1995 | 16 | { "Maximum SMBus/I2C Frequency (MSMBFREQ)", |
1996 | 16 | "nvme-mi.mi.port.msmbfreq", |
1997 | 16 | FT_UINT8, BASE_HEX, VALS(mi_vpdfreq_vals), 0x03, |
1998 | 16 | NULL, HFILL }, |
1999 | 16 | }, |
2000 | 16 | { &hf_nvme_mi_mi_port_twire_nvmebm, |
2001 | 16 | { "NVMe Basic Management (NVMEBM)", "nvme-mi.mi.port.nvmebm", |
2002 | 16 | FT_UINT8, BASE_HEX, NULL, 0, |
2003 | 16 | NULL, HFILL }, |
2004 | 16 | }, |
2005 | 16 | { &hf_nvme_mi_mi_port_twire_nvmebms, |
2006 | 16 | { "NVMe Basic Management Support (NVMEBMS)", |
2007 | 16 | "nvme-mi.mi.port.nvmebms", |
2008 | 16 | FT_BOOLEAN, 8, TFS(&tfs_supported_not_supported), 0x01, |
2009 | 16 | NULL, HFILL }, |
2010 | 16 | }, |
2011 | | |
2012 | | /* Controller List (DTYP 02h) */ |
2013 | 16 | { &hf_nvme_mi_mi_ctrllist_numids, |
2014 | 16 | { "Number of Identifiers", "nvme-mi.mi.ctrllist.numids", |
2015 | 16 | FT_UINT16, BASE_DEC, NULL, 0, |
2016 | 16 | NULL, HFILL }, |
2017 | 16 | }, |
2018 | 16 | { &hf_nvme_mi_mi_ctrllist_ctrlid, |
2019 | 16 | { "Controller Identifier", "nvme-mi.mi.ctrllist.ctrlid", |
2020 | 16 | FT_UINT16, BASE_HEX, NULL, 0, |
2021 | 16 | NULL, HFILL }, |
2022 | 16 | }, |
2023 | | |
2024 | | /* Controller Information (DTYP 03h) */ |
2025 | 16 | { &hf_nvme_mi_mi_ctrlinfo_portid, |
2026 | 16 | { "Port Identifier (PORTID)", "nvme-mi.mi.ctrlinfo.portid", |
2027 | 16 | FT_UINT8, BASE_DEC, NULL, 0, |
2028 | 16 | "PCIe port with which the Controller is associated", HFILL }, |
2029 | 16 | }, |
2030 | 16 | { &hf_nvme_mi_mi_ctrlinfo_prii, |
2031 | 16 | { "PCIe Routing ID Information (PRII)", "nvme-mi.mi.ctrlinfo.prii", |
2032 | 16 | FT_UINT8, BASE_HEX, NULL, 0, |
2033 | 16 | NULL, HFILL }, |
2034 | 16 | }, |
2035 | 16 | { &hf_nvme_mi_mi_ctrlinfo_riv, |
2036 | 16 | { "PCIe Routing ID Valid (PCIERIV)", "nvme-mi.mi.ctrlinfo.riv", |
2037 | 16 | FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x01, |
2038 | 16 | "Bus and Device numbers have been captured", HFILL }, |
2039 | 16 | }, |
2040 | 16 | { &hf_nvme_mi_mi_ctrlinfo_pri, |
2041 | 16 | { "PCIe Routing ID (PRI)", "nvme-mi.mi.ctrlinfo.pri", |
2042 | 16 | FT_UINT16, BASE_HEX, NULL, 0, |
2043 | 16 | NULL, HFILL }, |
2044 | 16 | }, |
2045 | 16 | { &hf_nvme_mi_mi_ctrlinfo_pri_bus, |
2046 | 16 | { "PCI Bus Number (PCIBN)", "nvme-mi.mi.ctrlinfo.pri.bus", |
2047 | 16 | FT_UINT16, BASE_HEX, NULL, 0xFF00, |
2048 | 16 | NULL, HFILL }, |
2049 | 16 | }, |
2050 | 16 | { &hf_nvme_mi_mi_ctrlinfo_pri_dev, |
2051 | 16 | { "PCI Device Number (PCIDN)", "nvme-mi.mi.ctrlinfo.pri.dev", |
2052 | 16 | FT_UINT16, BASE_HEX, NULL, 0x00F8, |
2053 | 16 | NULL, HFILL }, |
2054 | 16 | }, |
2055 | 16 | { &hf_nvme_mi_mi_ctrlinfo_pri_fn, |
2056 | 16 | { "PCI Function Number (PCIFN)", "nvme-mi.mi.ctrlinfo.pri.fn", |
2057 | 16 | FT_UINT16, BASE_HEX, NULL, 0x0007, |
2058 | 16 | NULL, HFILL }, |
2059 | 16 | }, |
2060 | 16 | { &hf_nvme_mi_mi_ctrlinfo_pcivid, |
2061 | 16 | { "PCI Vendor ID (PCIVID)", "nvme-mi.mi.ctrlinfo.pcivid", |
2062 | 16 | FT_UINT16, BASE_HEX, NULL, 0, |
2063 | 16 | NULL, HFILL }, |
2064 | 16 | }, |
2065 | 16 | { &hf_nvme_mi_mi_ctrlinfo_pcidid, |
2066 | 16 | { "PCI Device ID (PCIDID)", "nvme-mi.mi.ctrlinfo.pcidid", |
2067 | 16 | FT_UINT16, BASE_HEX, NULL, 0, |
2068 | 16 | NULL, HFILL }, |
2069 | 16 | }, |
2070 | 16 | { &hf_nvme_mi_mi_ctrlinfo_pcisvid, |
2071 | 16 | { "PCI Subsystem Vendor ID (PCISVID)", "nvme-mi.mi.ctrlinfo.pcisvid", |
2072 | 16 | FT_UINT16, BASE_HEX, NULL, 0, |
2073 | 16 | NULL, HFILL }, |
2074 | 16 | }, |
2075 | 16 | { &hf_nvme_mi_mi_ctrlinfo_pcisdid, |
2076 | 16 | { "PCI Subsystem Device ID (PCISDID)", "nvme-mi.mi.ctrlinfo.pcisdid", |
2077 | 16 | FT_UINT16, BASE_HEX, NULL, 0, |
2078 | 16 | NULL, HFILL }, |
2079 | 16 | }, |
2080 | 16 | { &hf_nvme_mi_mi_ctrlinfo_pciesn, |
2081 | 16 | { "PCIe Segment Number (PCIESN)", "nvme-mi.mi.ctrlinfo.pciesn", |
2082 | 16 | FT_UINT8, BASE_DEC, NULL, 0, |
2083 | 16 | "Segment Number when the PCIe link is in Flit mode", HFILL }, |
2084 | 16 | }, |
2085 | | |
2086 | | /* Command lists (DTYP 04h/05h) */ |
2087 | 16 | { &hf_nvme_mi_mi_cmdlist_numcmd, |
2088 | 16 | { "Number of Commands (NUMCMD)", "nvme-mi.mi.cmdlist.numcmd", |
2089 | 16 | FT_UINT16, BASE_DEC, NULL, 0, |
2090 | 16 | NULL, HFILL }, |
2091 | 16 | }, |
2092 | 16 | { &hf_nvme_mi_mi_cmdlist_ctyp, |
2093 | 16 | { "Command Type (CTYP)", "nvme-mi.mi.cmdlist.ctyp", |
2094 | 16 | FT_UINT8, BASE_HEX, NULL, 0, |
2095 | 16 | NULL, HFILL }, |
2096 | 16 | }, |
2097 | 16 | { &hf_nvme_mi_mi_cmdlist_nmimt, |
2098 | 16 | { "NVMe-MI Message Type (NMIMT)", "nvme-mi.mi.cmdlist.nmimt", |
2099 | 16 | FT_UINT8, BASE_HEX, VALS(mi_type_vals), 0x78, |
2100 | 16 | NULL, HFILL }, |
2101 | 16 | }, |
2102 | 16 | { &hf_nvme_mi_mi_cmdlist_opc, |
2103 | 16 | { "Opcode (OPC)", "nvme-mi.mi.cmdlist.opc", |
2104 | 16 | FT_UINT8, BASE_HEX, NULL, 0, |
2105 | 16 | NULL, HFILL }, |
2106 | 16 | }, |
2107 | | |
2108 | | /* NVM Subsystem Health Data Structure */ |
2109 | 16 | { &hf_nvme_mi_mi_nshds_nss, |
2110 | 16 | { "NVM Subsystem Status (NSS)", "nvme-mi.mi.nshds.nss", |
2111 | 16 | FT_UINT8, BASE_HEX, NULL, 0, |
2112 | 16 | NULL, HFILL }, |
2113 | 16 | }, |
2114 | 16 | { &hf_nvme_mi_mi_nshds_nss_atf, |
2115 | 16 | { "AEM Transmission Failure (ATF)", "nvme-mi.mi.nshds.nss.atf", |
2116 | 16 | FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x80, |
2117 | 16 | NULL, HFILL }, |
2118 | 16 | }, |
2119 | 16 | { &hf_nvme_mi_mi_nshds_nss_sfm, |
2120 | 16 | { "Sanitize Failure Mode (SFM)", "nvme-mi.mi.nshds.nss.sfm", |
2121 | 16 | FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x40, |
2122 | 16 | NULL, HFILL }, |
2123 | 16 | }, |
2124 | 16 | { &hf_nvme_mi_mi_nshds_nss_df, |
2125 | 16 | { "Drive Functional (DF)", "nvme-mi.mi.nshds.nss.df", |
2126 | 16 | FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x20, |
2127 | 16 | NULL, HFILL }, |
2128 | 16 | }, |
2129 | 16 | { &hf_nvme_mi_mi_nshds_nss_rnr, |
2130 | 16 | { "Reset Not Required (RNR)", "nvme-mi.mi.nshds.nss.rnr", |
2131 | 16 | FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x10, |
2132 | 16 | NULL, HFILL }, |
2133 | 16 | }, |
2134 | 16 | { &hf_nvme_mi_mi_nshds_nss_p0la, |
2135 | 16 | { "Port 0 PCIe Link Active (P0LA)", "nvme-mi.mi.nshds.nss.p0la", |
2136 | 16 | FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x08, |
2137 | 16 | NULL, HFILL }, |
2138 | 16 | }, |
2139 | 16 | { &hf_nvme_mi_mi_nshds_nss_p1la, |
2140 | 16 | { "Port 1 PCIe Link Active (P1LA)", "nvme-mi.mi.nshds.nss.p1la", |
2141 | 16 | FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x04, |
2142 | 16 | NULL, HFILL }, |
2143 | 16 | }, |
2144 | 16 | { &hf_nvme_mi_mi_nshds_nss_snfm, |
2145 | 16 | { "Sanitize Namespace Failure Mode (SNFM)", |
2146 | 16 | "nvme-mi.mi.nshds.nss.snfm", |
2147 | 16 | FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x02, |
2148 | 16 | NULL, HFILL }, |
2149 | 16 | }, |
2150 | 16 | { &hf_nvme_mi_mi_nshds_sw, |
2151 | 16 | { "SMART Warnings (SW)", "nvme-mi.mi.nshds.sw", |
2152 | 16 | FT_UINT8, BASE_HEX, NULL, 0, |
2153 | 16 | "Inverted Critical Warning field of the SMART log page", |
2154 | 16 | HFILL }, |
2155 | 16 | }, |
2156 | 16 | { &hf_nvme_mi_mi_nshds_sw_ips, |
2157 | 16 | { "Indeterminate Personality State (IPS)", |
2158 | 16 | "nvme-mi.mi.nshds.sw.ips", |
2159 | 16 | FT_BOOLEAN, 8, TFS(&tfs_nshds_sw), 0x40, |
2160 | 16 | NULL, HFILL }, |
2161 | 16 | }, |
2162 | 16 | { &hf_nvme_mi_mi_nshds_sw_pmre, |
2163 | 16 | { "Persistent Memory Region Error (PMRE)", |
2164 | 16 | "nvme-mi.mi.nshds.sw.pmre", |
2165 | 16 | FT_BOOLEAN, 8, TFS(&tfs_nshds_sw), 0x20, |
2166 | 16 | NULL, HFILL }, |
2167 | 16 | }, |
2168 | 16 | { &hf_nvme_mi_mi_nshds_sw_vmbf, |
2169 | 16 | { "Volatile Memory Backup Failed (VMBF)", |
2170 | 16 | "nvme-mi.mi.nshds.sw.vmbf", |
2171 | 16 | FT_BOOLEAN, 8, TFS(&tfs_nshds_sw), 0x10, |
2172 | 16 | NULL, HFILL }, |
2173 | 16 | }, |
2174 | 16 | { &hf_nvme_mi_mi_nshds_sw_ro, |
2175 | 16 | { "Read Only (RO)", "nvme-mi.mi.nshds.sw.ro", |
2176 | 16 | FT_BOOLEAN, 8, TFS(&tfs_nshds_sw), 0x08, |
2177 | 16 | NULL, HFILL }, |
2178 | 16 | }, |
2179 | 16 | { &hf_nvme_mi_mi_nshds_sw_rd, |
2180 | 16 | { "Reliability Degraded (RD)", "nvme-mi.mi.nshds.sw.rd", |
2181 | 16 | FT_BOOLEAN, 8, TFS(&tfs_nshds_sw), 0x04, |
2182 | 16 | NULL, HFILL }, |
2183 | 16 | }, |
2184 | 16 | { &hf_nvme_mi_mi_nshds_sw_taut, |
2185 | 16 | { "Temperature Above or Under Threshold (TAUT)", |
2186 | 16 | "nvme-mi.mi.nshds.sw.taut", |
2187 | 16 | FT_BOOLEAN, 8, TFS(&tfs_nshds_sw), 0x02, |
2188 | 16 | NULL, HFILL }, |
2189 | 16 | }, |
2190 | 16 | { &hf_nvme_mi_mi_nshds_sw_st, |
2191 | 16 | { "Spare Threshold (ST)", "nvme-mi.mi.nshds.sw.st", |
2192 | 16 | FT_BOOLEAN, 8, TFS(&tfs_nshds_sw), 0x01, |
2193 | 16 | NULL, HFILL }, |
2194 | 16 | }, |
2195 | 16 | { &hf_nvme_mi_mi_nshds_ctemp, |
2196 | 16 | { "Composite Temperature (CTEMP)", "nvme-mi.mi.nshds.ctemp", |
2197 | 16 | FT_UINT8, BASE_CUSTOM, CF_FUNC(nvme_mi_mi_fmt_nshds_ctemp), 0, |
2198 | 16 | "Composite temperature of the NVM Subsystem", HFILL }, |
2199 | 16 | }, |
2200 | 16 | { &hf_nvme_mi_mi_nshds_pdlu, |
2201 | 16 | { "Percentage Drive Life Used (PDLU)", "nvme-mi.mi.nshds.pdlu", |
2202 | 16 | FT_UINT8, BASE_DEC, NULL, 0, |
2203 | 16 | NULL, HFILL }, |
2204 | 16 | }, |
2205 | 16 | { &hf_nvme_mi_mi_nshds_ccs, |
2206 | 16 | { "Composite Controller Status (CCS)", "nvme-mi.mi.nshds.ccs", |
2207 | 16 | FT_UINT16, BASE_HEX, NULL, 0, |
2208 | 16 | "Composite Controller Status Flags (NVMe-MI 2.1 'Composite" |
2209 | 16 | " Controller Status Data Structure (CCSDS)')", HFILL }, |
2210 | 16 | }, |
2211 | | |
2212 | | /* Shared health-status flag bits (NVMe-MI 2.1 "Controller Health |
2213 | | * Status Changed Flags (CHSCF)" / "Composite Controller Status |
2214 | | * Data Structure (CCSDS)") */ |
2215 | 16 | { &hf_nvme_mi_mi_hsf_tcida, |
2216 | 16 | { "Telemetry Controller-Initiated Data Available (TCIDA)", |
2217 | 16 | "nvme-mi.mi.hsf.tcida", |
2218 | 16 | FT_BOOLEAN, 16, TFS(&tfs_set_notset), 0x2000, |
2219 | 16 | NULL, HFILL }, |
2220 | 16 | }, |
2221 | 16 | { &hf_nvme_mi_mi_hsf_cwarn, |
2222 | 16 | { "Critical Warning (CWARN)", "nvme-mi.mi.hsf.cwarn", |
2223 | 16 | FT_BOOLEAN, 16, TFS(&tfs_set_notset), 0x1000, |
2224 | 16 | NULL, HFILL }, |
2225 | 16 | }, |
2226 | 16 | { &hf_nvme_mi_mi_hsf_spare, |
2227 | 16 | { "Available Spare (SPARE)", "nvme-mi.mi.hsf.spare", |
2228 | 16 | FT_BOOLEAN, 16, TFS(&tfs_set_notset), 0x0800, |
2229 | 16 | NULL, HFILL }, |
2230 | 16 | }, |
2231 | 16 | { &hf_nvme_mi_mi_hsf_pdlu, |
2232 | 16 | { "Percentage Used (PDLU)", "nvme-mi.mi.hsf.pdlu", |
2233 | 16 | FT_BOOLEAN, 16, TFS(&tfs_set_notset), 0x0400, |
2234 | 16 | NULL, HFILL }, |
2235 | 16 | }, |
2236 | 16 | { &hf_nvme_mi_mi_hsf_ctemp, |
2237 | 16 | { "Composite Temperature Change (CTEMP)", "nvme-mi.mi.hsf.ctemp", |
2238 | 16 | FT_BOOLEAN, 16, TFS(&tfs_set_notset), 0x0200, |
2239 | 16 | NULL, HFILL }, |
2240 | 16 | }, |
2241 | 16 | { &hf_nvme_mi_mi_hsf_csts, |
2242 | 16 | { "Controller Status Change (CSTS)", "nvme-mi.mi.hsf.csts", |
2243 | 16 | FT_BOOLEAN, 16, TFS(&tfs_set_notset), 0x0100, |
2244 | 16 | NULL, HFILL }, |
2245 | 16 | }, |
2246 | 16 | { &hf_nvme_mi_mi_hsf_fa, |
2247 | 16 | { "Firmware Activated (FA)", "nvme-mi.mi.hsf.fa", |
2248 | 16 | FT_BOOLEAN, 16, TFS(&tfs_set_notset), 0x0080, |
2249 | 16 | NULL, HFILL }, |
2250 | 16 | }, |
2251 | 16 | { &hf_nvme_mi_mi_hsf_nac, |
2252 | 16 | { "Namespace Attribute Changed (NAC)", "nvme-mi.mi.hsf.nac", |
2253 | 16 | FT_BOOLEAN, 16, TFS(&tfs_set_notset), 0x0040, |
2254 | 16 | NULL, HFILL }, |
2255 | 16 | }, |
2256 | 16 | { &hf_nvme_mi_mi_hsf_ceco, |
2257 | 16 | { "Controller Enable Change Occurred (CECO)", "nvme-mi.mi.hsf.ceco", |
2258 | 16 | FT_BOOLEAN, 16, TFS(&tfs_set_notset), 0x0020, |
2259 | 16 | NULL, HFILL }, |
2260 | 16 | }, |
2261 | 16 | { &hf_nvme_mi_mi_hsf_nssro, |
2262 | 16 | { "NVM Subsystem Reset Occurred (NSSRO)", "nvme-mi.mi.hsf.nssro", |
2263 | 16 | FT_BOOLEAN, 16, TFS(&tfs_set_notset), 0x0010, |
2264 | 16 | NULL, HFILL }, |
2265 | 16 | }, |
2266 | 16 | { &hf_nvme_mi_mi_hsf_shst, |
2267 | 16 | { "Shutdown Status (SHST)", "nvme-mi.mi.hsf.shst", |
2268 | 16 | FT_BOOLEAN, 16, TFS(&tfs_set_notset), 0x0004, |
2269 | 16 | NULL, HFILL }, |
2270 | 16 | }, |
2271 | 16 | { &hf_nvme_mi_mi_hsf_cfs, |
2272 | 16 | { "Controller Fatal Status (CFS)", "nvme-mi.mi.hsf.cfs", |
2273 | 16 | FT_BOOLEAN, 16, TFS(&tfs_set_notset), 0x0002, |
2274 | 16 | NULL, HFILL }, |
2275 | 16 | }, |
2276 | 16 | { &hf_nvme_mi_mi_hsf_rdy, |
2277 | 16 | { "Ready (RDY)", "nvme-mi.mi.hsf.rdy", |
2278 | 16 | FT_BOOLEAN, 16, TFS(&tfs_set_notset), 0x0001, |
2279 | 16 | NULL, HFILL }, |
2280 | 16 | }, |
2281 | | |
2282 | | /* Controller Health Data Structure */ |
2283 | 16 | { &hf_nvme_mi_mi_chds_ctlid, |
2284 | 16 | { "Controller Identifier (CTLID)", "nvme-mi.mi.chds.ctlid", |
2285 | 16 | FT_UINT16, BASE_HEX, NULL, 0, |
2286 | 16 | NULL, HFILL }, |
2287 | 16 | }, |
2288 | 16 | { &hf_nvme_mi_mi_chds_csts, |
2289 | 16 | { "Controller Status (CSTS)", "nvme-mi.mi.chds.csts", |
2290 | 16 | FT_UINT16, BASE_HEX, NULL, 0, |
2291 | 16 | NULL, HFILL }, |
2292 | 16 | }, |
2293 | 16 | { &hf_nvme_mi_mi_chds_csts_tcida, |
2294 | 16 | { "Telemetry Controller-Initiated Data Available (TCIDA)", |
2295 | 16 | "nvme-mi.mi.chds.csts.tcida", |
2296 | 16 | FT_BOOLEAN, 16, TFS(&tfs_set_notset), 0x0100, |
2297 | 16 | NULL, HFILL }, |
2298 | 16 | }, |
2299 | 16 | { &hf_nvme_mi_mi_chds_csts_fa, |
2300 | 16 | { "Firmware Activated (FA)", "nvme-mi.mi.chds.csts.fa", |
2301 | 16 | FT_BOOLEAN, 16, TFS(&tfs_set_notset), 0x0080, |
2302 | 16 | NULL, HFILL }, |
2303 | 16 | }, |
2304 | 16 | { &hf_nvme_mi_mi_chds_csts_nac, |
2305 | 16 | { "Namespace Attribute Changed (NAC)", "nvme-mi.mi.chds.csts.nac", |
2306 | 16 | FT_BOOLEAN, 16, TFS(&tfs_set_notset), 0x0040, |
2307 | 16 | NULL, HFILL }, |
2308 | 16 | }, |
2309 | 16 | { &hf_nvme_mi_mi_chds_csts_ceco, |
2310 | 16 | { "Controller Enable Change Occurred (CECO)", |
2311 | 16 | "nvme-mi.mi.chds.csts.ceco", |
2312 | 16 | FT_BOOLEAN, 16, TFS(&tfs_set_notset), 0x0020, |
2313 | 16 | "Indicates the value of CC.EN", HFILL }, |
2314 | 16 | }, |
2315 | 16 | { &hf_nvme_mi_mi_chds_csts_nssro, |
2316 | 16 | { "NVM Subsystem Reset Occurred (NSSRO)", |
2317 | 16 | "nvme-mi.mi.chds.csts.nssro", |
2318 | 16 | FT_BOOLEAN, 16, TFS(&tfs_set_notset), 0x0010, |
2319 | 16 | NULL, HFILL }, |
2320 | 16 | }, |
2321 | 16 | { &hf_nvme_mi_mi_chds_csts_shst, |
2322 | 16 | { "Shutdown Status (SHST)", "nvme-mi.mi.chds.csts.shst", |
2323 | 16 | FT_UINT16, BASE_HEX, VALS(shst_table), 0x000C, |
2324 | 16 | NULL, HFILL }, |
2325 | 16 | }, |
2326 | 16 | { &hf_nvme_mi_mi_chds_csts_cfs, |
2327 | 16 | { "Controller Fatal Status (CFS)", "nvme-mi.mi.chds.csts.cfs", |
2328 | 16 | FT_BOOLEAN, 16, TFS(&tfs_set_notset), 0x0002, |
2329 | 16 | NULL, HFILL }, |
2330 | 16 | }, |
2331 | 16 | { &hf_nvme_mi_mi_chds_csts_rdy, |
2332 | 16 | { "Ready (RDY)", "nvme-mi.mi.chds.csts.rdy", |
2333 | 16 | FT_BOOLEAN, 16, TFS(&tfs_set_notset), 0x0001, |
2334 | 16 | NULL, HFILL }, |
2335 | 16 | }, |
2336 | 16 | { &hf_nvme_mi_mi_chds_ctemp, |
2337 | 16 | { "Composite Temperature (CTEMP)", "nvme-mi.mi.chds.ctemp", |
2338 | 16 | FT_UINT16, BASE_DEC, NULL, 0, |
2339 | 16 | "Composite temperature of the Controller in Kelvins", HFILL }, |
2340 | 16 | }, |
2341 | 16 | { &hf_nvme_mi_mi_chds_pdlu, |
2342 | 16 | { "Percentage Used (PDLU)", "nvme-mi.mi.chds.pdlu", |
2343 | 16 | FT_UINT8, BASE_DEC, NULL, 0, |
2344 | 16 | NULL, HFILL }, |
2345 | 16 | }, |
2346 | 16 | { &hf_nvme_mi_mi_chds_spare, |
2347 | 16 | { "Available Spare (SPARE)", "nvme-mi.mi.chds.spare", |
2348 | 16 | FT_UINT8, BASE_DEC, NULL, 0, |
2349 | 16 | "Normalized percentage of remaining spare capacity", HFILL }, |
2350 | 16 | }, |
2351 | 16 | { &hf_nvme_mi_mi_chds_cwarn, |
2352 | 16 | { "Critical Warning (CWARN)", "nvme-mi.mi.chds.cwarn", |
2353 | 16 | FT_UINT8, BASE_HEX, NULL, 0, |
2354 | 16 | NULL, HFILL }, |
2355 | 16 | }, |
2356 | 16 | { &hf_nvme_mi_mi_chds_cwarn_ips, |
2357 | 16 | { "Indeterminate Personality State (IPS)", |
2358 | 16 | "nvme-mi.mi.chds.cwarn.ips", |
2359 | 16 | FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x40, |
2360 | 16 | NULL, HFILL }, |
2361 | 16 | }, |
2362 | 16 | { &hf_nvme_mi_mi_chds_cwarn_pmre, |
2363 | 16 | { "Persistent Memory Region Error (PMRE)", |
2364 | 16 | "nvme-mi.mi.chds.cwarn.pmre", |
2365 | 16 | FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x20, |
2366 | 16 | NULL, HFILL }, |
2367 | 16 | }, |
2368 | 16 | { &hf_nvme_mi_mi_chds_cwarn_vmbf, |
2369 | 16 | { "Volatile Memory Backup Failed (VMBF)", |
2370 | 16 | "nvme-mi.mi.chds.cwarn.vmbf", |
2371 | 16 | FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x10, |
2372 | 16 | NULL, HFILL }, |
2373 | 16 | }, |
2374 | 16 | { &hf_nvme_mi_mi_chds_cwarn_ro, |
2375 | 16 | { "Read Only (RO)", "nvme-mi.mi.chds.cwarn.ro", |
2376 | 16 | FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x08, |
2377 | 16 | NULL, HFILL }, |
2378 | 16 | }, |
2379 | 16 | { &hf_nvme_mi_mi_chds_cwarn_rd, |
2380 | 16 | { "Reliability Degraded (RD)", "nvme-mi.mi.chds.cwarn.rd", |
2381 | 16 | FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x04, |
2382 | 16 | NULL, HFILL }, |
2383 | 16 | }, |
2384 | 16 | { &hf_nvme_mi_mi_chds_cwarn_taut, |
2385 | 16 | { "Temperature Above or Under Threshold (TAUT)", |
2386 | 16 | "nvme-mi.mi.chds.cwarn.taut", |
2387 | 16 | FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x02, |
2388 | 16 | NULL, HFILL }, |
2389 | 16 | }, |
2390 | 16 | { &hf_nvme_mi_mi_chds_cwarn_st, |
2391 | 16 | { "Spare Threshold (ST)", "nvme-mi.mi.chds.cwarn.st", |
2392 | 16 | FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x01, |
2393 | 16 | NULL, HFILL }, |
2394 | 16 | }, |
2395 | 16 | { &hf_nvme_mi_mi_chds_chsc, |
2396 | 16 | { "Controller Health Status Changed (CHSC)", |
2397 | 16 | "nvme-mi.mi.chds.chsc", |
2398 | 16 | FT_UINT16, BASE_HEX, NULL, 0, |
2399 | 16 | "Controller Health Status Changed Flags (CHSCF)", HFILL }, |
2400 | 16 | }, |
2401 | 16 | }; |
2402 | | /* *INDENT-ON* */ |
2403 | | |
2404 | 16 | static int *ett[] = { |
2405 | 16 | &ett_nvme_mi_mi, |
2406 | 16 | &ett_nvme_mi_mi_field, |
2407 | 16 | &ett_nvme_mi_mi_entry, |
2408 | 16 | }; |
2409 | | |
2410 | 16 | static ei_register_info ei[] = { |
2411 | 16 | { &ei_nvme_mi_mi_truncated, |
2412 | 16 | { "nvme-mi.mi.truncated", PI_MALFORMED, PI_WARN, |
2413 | 16 | "MI command payload truncated", EXPFILL } |
2414 | 16 | }, |
2415 | 16 | { &ei_nvme_mi_mi_orphan_response, |
2416 | 16 | { "nvme-mi.mi.orphan_response", PI_SEQUENCE, PI_NOTE, |
2417 | 16 | "MI response without a usable matching request (missing or" |
2418 | 16 | " truncated); opcode could not be recovered", EXPFILL } |
2419 | 16 | }, |
2420 | 16 | { &ei_nvme_mi_mi_reserved_dtyp, |
2421 | 16 | { "nvme-mi.mi.reserved_dtyp", PI_PROTOCOL, PI_NOTE, |
2422 | 16 | "Data Structure Type is in the Reserved range (06h-FFh)", |
2423 | 16 | EXPFILL } |
2424 | 16 | }, |
2425 | 16 | { &ei_nvme_mi_mi_reserved_configid, |
2426 | 16 | { "nvme-mi.mi.reserved_configid", PI_PROTOCOL, PI_NOTE, |
2427 | 16 | "Configuration Identifier is in a Reserved range (00h, 05h-BFh)", |
2428 | 16 | EXPFILL } |
2429 | 16 | }, |
2430 | 16 | { &ei_nvme_mi_mi_reserved_value, |
2431 | 16 | { "nvme-mi.mi.reserved_value", PI_PROTOCOL, PI_NOTE, |
2432 | 16 | "A command-specific field carries a Reserved value", EXPFILL } |
2433 | 16 | } |
2434 | 16 | }; |
2435 | | |
2436 | 16 | expert_module_t *expert_nvme_mi_mi; |
2437 | | |
2438 | 16 | proto_nvme_mi_mi = proto_register_protocol( |
2439 | 16 | "NVMe-MI MI Command", "NVMe-MI MI", "nvme-mi.mi"); |
2440 | 16 | proto_register_field_array(proto_nvme_mi_mi, hf, array_length(hf)); |
2441 | 16 | proto_register_subtree_array(ett, array_length(ett)); |
2442 | | |
2443 | 16 | expert_nvme_mi_mi = expert_register_protocol(proto_nvme_mi_mi); |
2444 | 16 | expert_register_field_array(expert_nvme_mi_mi, ei, array_length(ei)); |
2445 | | |
2446 | 16 | nvme_mi_mi_handle = register_dissector_with_description( |
2447 | 16 | "nvme-mi.mi", "NVMe-MI MI Command", |
2448 | 16 | dissect_nvme_mi_mi, proto_nvme_mi_mi); |
2449 | 16 | } |
2450 | | |
2451 | | void |
2452 | | proto_reg_handoff_nvme_mi_mi(void) |
2453 | 16 | { |
2454 | 16 | dissector_add_uint("nvme-mi.type", NVME_MI_TYPE_MI, |
2455 | 16 | nvme_mi_mi_handle); |
2456 | 16 | } |
2457 | | |
2458 | | /* |
2459 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
2460 | | * |
2461 | | * Local variables: |
2462 | | * c-basic-offset: 4 |
2463 | | * tab-width: 8 |
2464 | | * indent-tabs-mode: nil |
2465 | | * End: |
2466 | | * |
2467 | | * vi: set shiftwidth=4 tabstop=8 expandtab: |
2468 | | * :indentSize=4:tabSize=8:noTabs=true: |
2469 | | */ |