1 /* packet-ncsi.c
2  *
3  * Extends NCSI dissection based on DMTF Document Identifier: DSP0222 Version: 1.2.0_2b
4  * Copyright 2019-2021, Caleb Chiu <caleb.chiu@macnica.com>
5  *
6  * Routines for NCSI dissection
7  * Copyright 2017-2019, Jeremy Kerr <jk@ozlabs.org>
8  *
9  * Wireshark - Network traffic analyzer
10  * By Gerald Combs <gerald@wireshark.org>
11  * Copyright 1998 Gerald Combs
12  *
13  * SPDX-License-Identifier: GPL-2.0-or-later
14  */
15 
16 /*
17  * Network Controller Sideband Interface (NCSI) protocol support.
18  * Specs at http://www.dmtf.org/sites/default/files/standards/documents/DSP0222_1.0.1.pdf
19  */
20 
21 
22 #include <config.h>
23 
24 #include <epan/packet.h>
25 #include <epan/etypes.h>
26 #include <epan/expert.h>
27 #include <epan/addr_resolv.h>
28 #include <epan/pci-ids.h>
29 #include <stdio.h>
30 
31 void proto_reg_handoff_ncsi(void);
32 void proto_register_ncsi(void);
33 
34 static int proto_ncsi = -1;
35 
36 /* Common header fields */
37 static int hf_ncsi_mc_id = -1;
38 static int hf_ncsi_revision = -1;
39 static int hf_ncsi_iid = -1;
40 static int hf_ncsi_type = -1;
41 static int hf_ncsi_type_code = -1;
42 static int hf_ncsi_type_code_masked = -1;
43 static int hf_ncsi_type_resp = -1;
44 static int hf_ncsi_chan = -1;
45 static int hf_ncsi_plen = -1;
46 
47 /* Decode the Package# and internal channel# */
48 static int hf_ncsi_pkg = -1;
49 static int hf_ncsi_ichan = -1;
50 
51 /* Response generics */
52 static int hf_ncsi_resp = -1;
53 static int hf_ncsi_reason = -1;
54 
55 /* Select package */
56 static int hf_ncsi_sp_hwarb = -1;
57 
58 /* Disable channel */
59 static int hf_ncsi_dc_ald = -1;
60 
61 /* AEN enable */
62 static int hf_ncsi_aene_mc = -1;
63 
64 /* Set MAC Address */
65 static int hf_ncsi_sm_mac = -1;
66 static int hf_ncsi_sm_macno = -1;
67 static int hf_ncsi_sm_at = -1;
68 static int hf_ncsi_sm_e = -1;
69 
70 /* Broadcast filter */
71 static int hf_ncsi_bf = -1;
72 static int hf_ncsi_bf_arp = -1;
73 static int hf_ncsi_bf_dhcpc = -1;
74 static int hf_ncsi_bf_dhcps = -1;
75 static int hf_ncsi_bf_netbios = -1;
76 
77 /* AEN payload fields */
78 static int hf_ncsi_aen_type = -1;
79 static int hf_ncsi_aen_lsc_oemstat = -1;
80 static int hf_ncsi_aen_hcds = -1;
81 static int hf_ncsi_aen_drr_orig_type = -1;
82 static int hf_ncsi_aen_drr_orig_iid = -1;
83 
84 /* generic link status */
85 static int hf_ncsi_lstat = -1;
86 static int hf_ncsi_lstat_flag = -1;
87 static int hf_ncsi_lstat_speed_duplex = -1;
88 static int hf_ncsi_lstat_autoneg = -1;
89 static int hf_ncsi_lstat_autoneg_complete = -1;
90 static int hf_ncsi_lstat_parallel_detection = -1;
91 static int hf_ncsi_lstat_1000TFD = -1;
92 static int hf_ncsi_lstat_1000THD = -1;
93 static int hf_ncsi_lstat_100T4 = -1;
94 static int hf_ncsi_lstat_100TXFD = -1;
95 static int hf_ncsi_lstat_100TXHD = -1;
96 static int hf_ncsi_lstat_10TFD = -1;
97 static int hf_ncsi_lstat_10THD = -1;
98 static int hf_ncsi_lstat_tx_flow = -1;
99 static int hf_ncsi_lstat_rx_flow = -1;
100 static int hf_ncsi_lstat_partner_flow = -1;
101 static int hf_ncsi_lstat_serdes = -1;
102 static int hf_ncsi_lstat_oem_speed_valid = -1;
103 
104 /* Set Link command (0x09) */
105 static int hf_ncsi_ls = -1;
106 static int hf_ncsi_ls_an = -1;
107 static int hf_ncsi_ls_10m = -1;
108 static int hf_ncsi_ls_100m = -1;
109 static int hf_ncsi_ls_1g = -1;
110 static int hf_ncsi_ls_10g = -1;
111 static int hf_ncsi_ls_20g = -1;
112 static int hf_ncsi_ls_25g = -1;
113 static int hf_ncsi_ls_40g = -1;
114 static int hf_ncsi_ls_hd = -1;
115 static int hf_ncsi_ls_fd = -1;
116 static int hf_ncsi_ls_pc = -1;
117 static int hf_ncsi_ls_apc = -1;
118 static int hf_ncsi_ls_50g = -1;
119 static int hf_ncsi_ls_100g = -1;
120 static int hf_ncsi_ls_2_5g = -1;
121 static int hf_ncsi_ls_5g = -1;
122 static int hf_ncsi_ls_rsv = -1;
123 static int hf_ncsi_ls_oemls = -1;
124 
125 /*Get Capabilities*/
126 static int hf_ncsi_cap_flag = -1;        /* Offset 20..23 Capabilities Flags */
127 static int hf_ncsi_cap_flag_ha = -1;     /* bit 0 Hardware Arbitration  */
128 static int hf_ncsi_cap_flag_op = -1;     /* bit 1 OS Presence  */
129 static int hf_ncsi_cap_flag_n2mfc = -1;  /* bit 2 Network Controller to Management Controller Flow Control Support */
130 static int hf_ncsi_cap_flag_m2nfc = -1;  /* bit 3 Management Controller to Network Controller Flow Control Support */
131 static int hf_ncsi_cap_flag_ama = -1;    /* bit 4 All multicast addresses support */
132 
133 static int hf_ncsi_cap_bf = -1;          /* Offset 24..27 Broadcast Packet Filter Capabilities, the variable names are align with Broadcast filter above */
134 static int hf_ncsi_cap_bf_arp = -1;
135 static int hf_ncsi_cap_bf_dhcpc = -1;
136 static int hf_ncsi_cap_bf_dhcps = -1;
137 static int hf_ncsi_cap_bf_netbios = -1;
138 
139 static int hf_ncsi_cap_mf = -1;          /* Offset 28..31 Multicast Packet Filter Capabilities */
140 static int hf_ncsi_cap_mf_v6na = -1;
141 static int hf_ncsi_cap_mf_v6ra = -1;
142 static int hf_ncsi_cap_mf_dhcpv6 = -1;
143 
144 static int hf_ncsi_cap_buf = -1;         /* Offset 32..35 Buffering Capability */
145 
146 static int hf_ncsi_cap_aen = -1;         /* Offset 36..39 AEN Control Support  */
147 static int hf_ncsi_cap_aen_lstat = -1;   /* bit 0 Link Status Change AEN control */
148 static int hf_ncsi_cap_aen_cfg = -1;     /* bit 1 Configuration Required AEN control */
149 static int hf_ncsi_cap_aen_drv = -1;     /* bit 2 Host NC Driver Status Change AEN control */
150 static int hf_ncsi_cap_aen_resv = -1;    /* bit 3..15 Reserved Reserved */
151 static int hf_ncsi_cap_aen_oem = -1;     /* bit 16..31 OEM-specific AEN control OEM */
152 
153 static int hf_ncsi_cap_vcnt = -1;        /* VLAN Filter Count */
154 static int hf_ncsi_cap_mixcnt = -1;      /* Mixed Filter Count */
155 static int hf_ncsi_cap_mccnt = -1;       /* Multicast Filter Count */
156 static int hf_ncsi_cap_uccnt = -1;       /* Unicast Filter Count */
157 
158 static int hf_ncsi_cap_vmode = -1;       /* VLAN Mode Support */
159 static int hf_ncsi_cap_vmode_vo = -1;    /* bit 0 VLAN only  */
160 static int hf_ncsi_cap_vmode_both = -1;  /* bit 1 VLAN + non-VLAN  */
161 static int hf_ncsi_cap_vmode_any = -1;  /* bit 2 Any VLAN + non-VLAN  */
162 static int hf_ncsi_cap_chcnt = -1;    /* Channel Count */
163 
164 /*Get Version ID*/
165 static int hf_ncsi_ver = -1;
166 static int hf_ncsi_fw_name = -1;
167 static int hf_ncsi_fw_ver = -1;
168 static int hf_ncsi_pci_did = -1;
169 static int hf_ncsi_pci_vid = -1;
170 static int hf_ncsi_pci_ssid = -1;
171 static int hf_ncsi_iana = -1;
172 
173 /* OEM ID */
174 static int hf_ncsi_oem_id = -1;
175 /* OEM Mellanox Command, Parameter, Host number */
176 static int hf_ncsi_mlnx_cmd = -1;
177 static int hf_ncsi_mlnx_parm = -1;
178 static int hf_ncsi_mlnx_host = -1;
179 /* OEM Mellanox Set MC Affinity (Command = 0x1, parameter 0x7) */
180 static int hf_ncsi_mlnx_rbt = -1; /* MC RBT address */
181 static int hf_ncsi_mlnx_sms = -1;  /* Supported Medias Status */
182 static int hf_ncsi_mlnx_sms_rbt = -1;
183 static int hf_ncsi_mlnx_sms_smbus = -1;
184 static int hf_ncsi_mlnx_sms_pcie = -1;
185 static int hf_ncsi_mlnx_sms_rbts = -1;
186 static int hf_ncsi_mlnx_sms_smbuss = -1;
187 static int hf_ncsi_mlnx_sms_pcies = -1;
188 
189 static int hf_ncsi_mlnx_beid = -1; /* MC SMBus EID */
190 static int hf_ncsi_mlnx_bidx = -1; /* SMBus INDX */
191 static int hf_ncsi_mlnx_baddr = -1; /* MC SMBus Address */
192 static int hf_ncsi_mlnx_peid = -1; /* MC PCIe EID */
193 static int hf_ncsi_mlnx_pidx = -1; /* PCIe INDX */
194 static int hf_ncsi_mlnx_paddr = -1; /* MC PCIe Address */
195 static int hf_ncsi_mlnx_ifm = -1; /* IP Filter Mode */
196 static int hf_ncsi_mlnx_ifm_byip = -1; /* Bits 1-0 - Filter by IP Address */
197 static int hf_ncsi_mlnx_ifm_v4en = -1; /* Bit 2 - IPv4 Enable */
198 static int hf_ncsi_mlnx_ifm_v6len = -1; /* Bit 3 - IPv6 Link Local Address Enable */
199 static int hf_ncsi_mlnx_ifm_v6gen = -1; /* Bit 4 - IPv6 Global Address Enable */
200 static int hf_ncsi_mlnx_v4addr = -1; /* MC IPv4 Address */
201 static int hf_ncsi_mlnx_v6local = -1; /* MC IPv6 Link Local Address */
202 static int hf_ncsi_mlnx_v6gbl = -1; /* MC IPv6 Global Address */
203 
204 /* Get Allocated Management Address (Command = 0x0, Parameter 0x1B) */
205 static int hf_ncsi_mlnx_gama_st = -1;  /*Get Allocated Management Address Status */
206 static int hf_ncsi_mlnx_gama_mac = -1; /*Allocated MC MAC address */
207 
208 
209 
210 static gint ett_ncsi = -1;
211 static gint ett_ncsi_type = -1;
212 static gint ett_ncsi_chan = -1;
213 static gint ett_ncsi_payload = -1;
214 static gint ett_ncsi_lstat = -1;
215 static gint ett_ncsi_cap_flag = -1;
216 static gint ett_ncsi_cap_bf = -1;
217 static gint ett_ncsi_cap_mf = -1;
218 static gint ett_ncsi_cap_aen = -1;
219 static gint ett_ncsi_cap_vmode = -1;
220 static gint ett_ncsi_ls = -1;
221 static gint ett_ncsi_mlnx = -1;
222 static gint ett_ncsi_mlnx_sms = -1;
223 static gint ett_ncsi_mlnx_ifm = -1;
224 
225 #define NCSI_MIN_LENGTH 8
226 
227 /* DMTF Document Identifier: DSP0222 Version: 1.2.0_2b */
228 enum ncsi_type {
229     NCSI_TYPE_CLS = 0x00,           /* Clear Initial State */
230     NCSI_TYPE_SEL = 0x01,           /* Select Package */
231     NCSI_TYPE_DSL = 0x02,           /* Deselect Package */
232     NCSI_TYPE_ECH = 0x03,           /* Enable Channel */
233     NCSI_TYPE_DCH = 0x04,           /* Disable Channel */
234     NCSI_TYPE_RCH = 0x05,           /* Reset Channel */
235     NCSI_TYPE_ETX = 0x06,           /* Enable Channel Network TX */
236     NCSI_TYPE_DTX = 0x07,           /* Disable Channel Network TX */
237     NCSI_TYPE_ANE = 0x08,           /* AEN Enable */
238     NCSI_TYPE_SLK = 0x09,           /* Set Link */
239     NCSI_TYPE_GLS = 0x0a,           /* Get Link Status */
240     NCSI_TYPE_SVF = 0x0b,           /* Set VLAN Filter */
241     NCSI_TYPE_EVL = 0x0c,           /* Enable VLAN */
242     NCSI_TYPE_DVL = 0x0d,           /* Disable VLAN */
243     NCSI_TYPE_MAC = 0x0e,           /* Set MAC Address */
244     NCSI_TYPE_EBF = 0x10,           /* Enable Broadcast Filter */
245     NCSI_TYPE_DBF = 0x11,           /* Disable Broadcast Filter */
246     NCSI_TYPE_EMF = 0x12,           /* Enable Global Multicast Filter */
247     NCSI_TYPE_DMF = 0x13,           /* Disable Global Multicast Filter */
248     NCSI_TYPE_SFC = 0x14,           /* Set NC-SI Flow Control */
249     NCSI_TYPE_VER = 0x15,           /* Get Version ID */
250     NCSI_TYPE_CAP = 0x16,           /* Get Capabilities */
251     NCSI_TYPE_PAR = 0x17,           /* Get Parameters */
252     NCSI_TYPE_CPS = 0x18,           /* Get Controller Packet Statistics */
253     NCSI_TYPE_GST = 0x19,           /* Get NC-SI Statistics */
254     NCSI_TYPE_PST = 0x1a,           /* Get NC-SI Pass- through Statistics */
255     NCSI_TYPE_GPS = 0x1b,           /* Get Package Status */
256     NCSI_TYPE_GPA = 0x1c,           /* Get PF Assignment */
257     NCSI_TYPE_SPA = 0x1d,           /* Set PF Assignment */
258     NCSI_TYPE_GBC = 0x1e,           /* Get Boot Config */
259     NCSI_TYPE_SBC = 0x1f,           /* Set Boot Config */
260     NCSI_TYPE_IOS = 0x20,           /* Get iSCSI Offload Statistics */
261     NCSI_TYPE_GPB = 0x21,           /* Get Partition TX Bandwidth */
262     NCSI_TYPE_SPB = 0x22,           /* Set Partition TX Bandwidth */
263     NCSI_TYPE_GIT = 0x23,           /* Get ASIC Temperature */
264     NCSI_TYPE_GAT = 0x24,           /* Get Ambient Temperature */
265     NCSI_TYPE_GMT = 0x25,           /* Get SFF Module Temp */
266     NCSI_TYPE_OEM = 0x50,           /* OEM Command */
267     NCSI_TYPE_PLDM = 0x51,          /* PLDM */
268     NCSI_TYPE_UUID = 0x52,          /* Get Package UUID */
269     NCSI_TYPE_AEN = 0xff,
270 };
271 
272 
273 enum ncsi_oem_id {
274     NCSI_OEM_MLX  = 0x8119,
275     NCSI_OEM_BCM  = 0x113d,
276 };
277 
278 static const value_string ncsi_resp_code_vals[] = {
279     { 0x0000, "Command Completed" },
280     { 0x0001, "Command Failed" },
281     { 0x0002, "Command Unavailable" },
282     { 0x0003, "Command Unsupported" },
283     { 0x0004, "Delayed" },
284     { 0, NULL },
285 };
286 
287 static const value_string ncsi_resp_reason_vals[] = {
288     { 0x0000, "No Error/No Reason Code" },
289     { 0x0001, "Interface Initialization Required" },
290     { 0x0002, "Parameter Is Invalid, Unsupported, or Out-of-Range" },
291     { 0x0003, "Channel Not Ready" },
292     { 0x0004, "Package Not Ready" },
293     { 0x0005, "Invalid payload length" },
294     { 0x0006, "Information not available" },
295     { 0x0901, "Set Link Host OS/ Driver Conflict" },
296     { 0x0902, "Set Link Media Conflict" },
297     { 0x0903, "Set Link Parameter Conflict" },
298     { 0x0904, "Set Link Power Mode Conflict" },
299     { 0x0905, "Set Link Speed Conflict" },
300     { 0x0906, "Link Command Failed-Hardware Access Error" },
301     { 0x0a06, "Link Command Failed-Hardware Access Error" },
302     { 0x0b07, "VLAN Tag Is Invalid"},
303     { 0x0e08, "MAC Address Is Zero"},
304     { 0x1409, "Independent transmit and receive enable/disable control is not supported"},
305     { 0x800c, "Link Command Failed-Hardware Access Error"},
306     { 0, NULL },
307 };
308 
309 
310 
311 static const value_string ncsi_type_vals[] = {
312     { NCSI_TYPE_CLS, "Clear Initial State" },
313     { NCSI_TYPE_SEL, "Select Package" },
314     { NCSI_TYPE_DSL, "Deselect Package" },
315     { NCSI_TYPE_ECH, "Enable Channel" },
316     { NCSI_TYPE_DCH, "Disable Channel" },
317     { NCSI_TYPE_RCH, "Reset Channel" },
318     { NCSI_TYPE_ETX, "Enable Channel Network TX" },
319     { NCSI_TYPE_DTX, "Disable Channel Network TX" },
320     { NCSI_TYPE_ANE, "AEN Enable" },
321     { NCSI_TYPE_SLK, "Set Link" },
322     { NCSI_TYPE_GLS, "Get Link Status" },
323     { NCSI_TYPE_SVF, "Set VLAN Filter" },
324     { NCSI_TYPE_EVL, "Enable VLAN" },
325     { NCSI_TYPE_DVL, "Disable VLAN" },
326     { NCSI_TYPE_MAC, "Set MAC Address" },
327     { NCSI_TYPE_EBF, "Enable Broadcast Filter" },
328     { NCSI_TYPE_DBF, "Disable Broadcast Filter" },
329     { NCSI_TYPE_EMF, "Enable Global Multicast Filter" },
330     { NCSI_TYPE_DMF, "Disable Global Multicast Filter" },
331     { NCSI_TYPE_SFC, "Set NC-SI Flow Control" },
332     { NCSI_TYPE_VER, "Get Version ID" },
333     { NCSI_TYPE_CAP, "Get Capabilities" },
334     { NCSI_TYPE_PAR, "Get Parameters" },
335     { NCSI_TYPE_CPS, "Get Controller Packet Statistics" },
336     { NCSI_TYPE_GST, "Get NC-SI Statistics" },
337     { NCSI_TYPE_PST, "Get NC-SI Pass- through Statistics" },
338     { NCSI_TYPE_GPS, "Get Package Status" },
339     { NCSI_TYPE_GPA, "Get PF Assignment" },
340     { NCSI_TYPE_SPA, "Set PF Assignment" },
341     { NCSI_TYPE_GBC, "Get Boot Config" },
342     { NCSI_TYPE_SBC, "Set Boot Config" },
343     { NCSI_TYPE_IOS, "Get iSCSI Offload Statistics" },
344     { NCSI_TYPE_GPB, "Get Partition TX Bandwidth" },
345     { NCSI_TYPE_SPB, "Set Partition TX Bandwidth" },
346     { NCSI_TYPE_GIT, "Get ASIC Temperature" },
347     { NCSI_TYPE_GAT, "Get Ambient Temperature" },
348     { NCSI_TYPE_GMT, "Get SFF Module Temp" },
349     { NCSI_TYPE_OEM, "OEM Command" },
350     { NCSI_TYPE_PLDM, "PLDM" },
351     { NCSI_TYPE_UUID, "Get Package UUID" },
352     { NCSI_TYPE_AEN, "Async Event Notification" },
353     { 0, NULL },
354 };
355 
356 static const value_string ncsi_oem_id_vals[] = {
357     { NCSI_OEM_MLX, "Mellanox" },
358     { NCSI_OEM_BCM, "Broadcom" },
359     { 0, NULL },
360 };
361 
362 static const value_string ncsi_type_resp_vals[] = {
363     { 0x00, "request" },
364     { 0x01, "response" },
365     { 0, NULL },
366 };
367 
368 static const value_string ncsi_aen_type_vals[] = {
369     { 0x00, "Link status change" },
370     { 0x01, "Configuration required" },
371     { 0x02, "Host NC driver status change" },
372     { 0x03, "Delayed Response Ready" },
373     { 0, NULL },
374 };
375 
376 static const true_false_string tfs_linkup_linkdown = { "Link up", "Link down" };
377 
378 static const value_string ncsi_lstat_speed_duplex_vals[] = {
379     { 0x00, "Auto-negotiate not complete" },
380     { 0x01, "10BaseT half duplex" },
381     { 0x02, "10BaseT full duplex" },
382     { 0x03, "100BaseT half duplex" },
383     { 0x04, "100BaseT4" },
384     { 0x05, "100BaseTX full duplex" },
385     { 0x06, "1000BaseT half duplex" },
386     { 0x07, "1000BaseT full duplex" },
387     { 0x08, "10GBaseT support" },
388     { 0, NULL },
389 };
390 
391 /* Mellanox MC IP Filter Mode */
392 static const value_string ncsi_mlnx_ifm_byip_vals[] = {
393     { 0x00, "MAC address is used and IP address is ignored on pass-through" },
394     { 0x01, "MAC address is used and IP address is used on pass-through" },
395     { 0x02, "MAC address is ignored and IP address is used on pass-through" },
396     { 0x03, "Reserved" },
397     { 0, NULL },
398 };
399 
400 static const true_false_string tfs_complete_disable_inprog = { "Complete", "Disabled/In-progress" };
401 
402 static const value_string ncsi_partner_flow_vals[] = {
403     { 0x00, "Not pause capable" },
404     { 0x01, "Symmetric pause" },
405     { 0x02, "Assymmetric pause" },
406     { 0x03, "Symmetric & Assymetric pause" },
407     { 0, NULL },
408 };
409 
410 
411 static const value_string ncsi_mlnx_gama_st_vals[] = {
412     { 0x00, "No MAC address was allocated for the requested BMC channel" },
413     { 0x01, "An address was allocated for the requested BMC channel" },
414     { 0, NULL },
415 };
416 
417 static const true_false_string tfs_running_not_running = { "Running", "Not running" };
418 
419 static const value_string ncsi_sm_at_vals[] = {
420     { 0x00, "unicast" },
421     { 0x01, "multicast" },
422     { 0, NULL },
423 };
424 
425 static const value_string ncsi_bf_filter_vals[] = {
426     { 0x00, "drop" },
427     { 0x01, "forward" },
428     { 0, NULL },
429 };
430 
431 
432 static void
433 ncsi_proto_tree_add_lstat(tvbuff_t *tvb, proto_tree *tree, int offset)
434 {
435     static int * const lstat_fields[] = {
436         &hf_ncsi_lstat_flag,
437         &hf_ncsi_lstat_speed_duplex,
438         &hf_ncsi_lstat_autoneg,
439         &hf_ncsi_lstat_autoneg_complete,
440         &hf_ncsi_lstat_parallel_detection,
441         &hf_ncsi_lstat_1000TFD,
442         &hf_ncsi_lstat_1000THD,
443         &hf_ncsi_lstat_100T4,
444         &hf_ncsi_lstat_100TXFD,
445         &hf_ncsi_lstat_100TXHD,
446         &hf_ncsi_lstat_10TFD,
447         &hf_ncsi_lstat_10THD,
448         &hf_ncsi_lstat_tx_flow,
449         &hf_ncsi_lstat_rx_flow,
450         &hf_ncsi_lstat_partner_flow,
451         &hf_ncsi_lstat_serdes,
452         &hf_ncsi_lstat_oem_speed_valid,
453         NULL,
454     };
455 
456     proto_tree_add_bitmask_with_flags(tree, tvb, offset, hf_ncsi_lstat,
457             ett_ncsi_lstat, lstat_fields, ENC_BIG_ENDIAN, BMT_NO_APPEND);
458 }
459 
460 static void
461 dissect_ncsi_aen(tvbuff_t *tvb, proto_tree *tree)
462 {
463     guint8 type = tvb_get_guint8(tvb, 19);
464 	proto_item *pi;
465 
466     pi = proto_tree_add_item(tree, hf_ncsi_aen_type, tvb, 19, 1, ENC_NA);
467 
468     if(type >= 0x4 && type <= 0x6f)
469 	{
470 	    proto_item_set_text(pi, "Reserved (0x%02x)", type);
471 	}
472 	else
473     if(type >= 0x70 && type <= 0x7f)
474 	{
475 	    proto_item_set_text(pi, "Transport-specific AENs (0x%02x)", type);
476 	}
477 	else
478     if(type >= 0x80)
479 	{
480 	    proto_item_set_text(pi, "OEM-specific AENs (0x%02x)", type);
481 	}
482 
483     switch (type) {
484     case 0x00: //Link Status Change
485         ncsi_proto_tree_add_lstat(tvb, tree, 20);
486         proto_tree_add_item(tree, hf_ncsi_aen_lsc_oemstat, tvb, 24, 4, ENC_NA);
487         break;
488     case 0x02: //Host Network Controller Driver Status
489         proto_tree_add_item(tree, hf_ncsi_aen_hcds, tvb, 20, 4, ENC_NA);
490         break;
491     case 0x03: //Delayed Response Ready
492 		proto_tree_add_item(tree, hf_ncsi_aen_drr_orig_type, tvb, 20, 1, ENC_NA);
493 		proto_tree_add_item(tree, hf_ncsi_aen_drr_orig_iid, tvb, 21, 1, ENC_NA);
494 
495         break;
496     }
497 }
498 
499 
500 
501 /* NC-SI Version encoding
502  *
503  * EXAMPLE: Version 3.7.10a      0xF3F7104100
504  *          Version 10.01.7      0x1001F70000
505  *          Version 3.1          0xF3F1FF0000
506  *          Version 1.0a         0xF1F0FF4100
507  *          Version 1.0ab        0xF1F0FF4142 (Alpha1 = 0x41, Alpha2 = 0x42)
508  */
509 
510 #define HEXSTR(x) (((x) < 10)? '0' + (x): 'A' + ((x) - 10))
511 
512 static const gchar *
513 ncsi_bcd_dig_to_str(tvbuff_t *tvb, const gint offset)
514 {
515     int     length = 16; /* MM.mm.uu.aa.bb */
516     guint8  octet;
517     int     i;
518     char   *digit_str;
519     int     str_offset = 0;
520 
521 
522     digit_str = (char *)wmem_alloc(wmem_packet_scope(), length);
523 
524     for (i = 0 ; i < 3; i++) {
525         octet = tvb_get_guint8(tvb, offset + i);
526 
527         if (octet == 0xff) {
528             break;
529         }
530 
531         if (i != 0) {
532             digit_str[str_offset++] = '.';
533         }
534 
535         if ((octet >> 4) != 0xf) {
536             digit_str[str_offset++] =  HEXSTR((octet >> 4) & 0x0f);
537         }
538 
539         digit_str[str_offset++] = HEXSTR(octet & 0x0f);
540 
541     }
542 
543     octet = tvb_get_guint8(tvb, offset + 3);
544     if (octet) {
545         digit_str[str_offset++] = '.';
546         digit_str[str_offset++] = octet;
547 
548         octet = tvb_get_guint8(tvb, offset + 7);
549         if (octet) {
550             digit_str[str_offset++] = '.';
551             digit_str[str_offset++] = octet;
552         }
553 
554     }
555 
556     digit_str[str_offset] = '\0';
557     return digit_str;
558 
559 }
560 
561 
562 static const gchar *
563 ncsi_fw_version(tvbuff_t *tvb, const gint offset)
564 {
565     int     length = 16; /* hh.hh.hh.hh */
566     guint8  octet;
567     int     i;
568     char   *ver_str;
569     int     str_offset = 0;
570 
571 
572     ver_str = (char *)wmem_alloc(wmem_packet_scope(), length);
573 
574     for (i = 0 ; i < 4; i++) {
575         octet = tvb_get_guint8(tvb, offset + i);
576 
577         if (i != 0) {
578             ver_str[str_offset++] = '.';
579         }
580 
581         ver_str[str_offset++] = HEXSTR((octet >> 4) & 0x0f);
582         ver_str[str_offset++] = HEXSTR(octet & 0x0f);
583 
584     }
585     ver_str[str_offset++] = 0;
586     return ver_str;
587 }
588 
589 
590 static void
591 ncsi_proto_tree_add_cap(tvbuff_t *tvb, proto_tree *tree, int offset)
592 {
593     static int * const cap_fields[] = {
594         &hf_ncsi_cap_flag_ha,
595         &hf_ncsi_cap_flag_op,
596         &hf_ncsi_cap_flag_n2mfc,
597         &hf_ncsi_cap_flag_m2nfc,
598         &hf_ncsi_cap_flag_ama,
599         NULL,
600     };
601 
602     static int * const cap_bf_fields[] = {
603         &hf_ncsi_cap_bf_arp,
604         &hf_ncsi_cap_bf_dhcpc,
605         &hf_ncsi_cap_bf_dhcps,
606         &hf_ncsi_cap_bf_netbios,
607         NULL,
608     };
609 
610     static int * const cap_mf_fields[] = {
611         &hf_ncsi_cap_mf_v6na,
612         &hf_ncsi_cap_mf_v6ra,
613         &hf_ncsi_cap_mf_dhcpv6,
614         NULL,
615     };
616 
617     static int * const cap_aen_fields[] = {
618         &hf_ncsi_cap_aen_lstat,
619         &hf_ncsi_cap_aen_cfg,
620         &hf_ncsi_cap_aen_drv,
621         &hf_ncsi_cap_aen_resv,
622         &hf_ncsi_cap_aen_oem,
623         NULL,
624     };
625 
626     static int * const cap_vmode_fields[] = {
627         &hf_ncsi_cap_vmode_vo,
628         &hf_ncsi_cap_vmode_both,
629         &hf_ncsi_cap_vmode_any,
630         NULL,
631     };
632 
633     proto_tree_add_bitmask_with_flags(tree, tvb, offset, hf_ncsi_cap_flag,
634             ett_ncsi_cap_flag, cap_fields, ENC_BIG_ENDIAN, BMT_NO_APPEND);
635 
636     proto_tree_add_bitmask_with_flags(tree, tvb, offset += 4, hf_ncsi_cap_bf,
637             ett_ncsi_cap_bf, cap_bf_fields, ENC_BIG_ENDIAN, BMT_NO_APPEND);
638 
639     proto_tree_add_bitmask_with_flags(tree, tvb, offset += 4, hf_ncsi_cap_mf,
640             ett_ncsi_cap_mf, cap_mf_fields, ENC_BIG_ENDIAN, BMT_NO_APPEND);
641 
642     proto_tree_add_item(tree, hf_ncsi_cap_buf, tvb, offset += 4, 4, ENC_NA);
643 
644     proto_tree_add_bitmask_with_flags(tree, tvb, offset += 4, hf_ncsi_cap_aen,
645             ett_ncsi_cap_aen, cap_aen_fields, ENC_BIG_ENDIAN, BMT_NO_APPEND);
646 
647     proto_tree_add_item(tree, hf_ncsi_cap_vcnt, tvb, offset += 4, 1, ENC_NA);
648     proto_tree_add_item(tree, hf_ncsi_cap_mixcnt, tvb, offset += 1, 1, ENC_NA);
649     proto_tree_add_item(tree, hf_ncsi_cap_mccnt, tvb, offset += 1, 1, ENC_NA);
650     proto_tree_add_item(tree, hf_ncsi_cap_uccnt, tvb, offset += 1, 1, ENC_NA);
651     proto_tree_add_bitmask_with_flags(tree, tvb, offset += 3, hf_ncsi_cap_vmode,
652             ett_ncsi_cap_vmode, cap_vmode_fields, ENC_BIG_ENDIAN, BMT_NO_APPEND);
653     proto_tree_add_item(tree, hf_ncsi_cap_chcnt, tvb, offset, 1, ENC_NA);
654 
655 }
656 
657 
658 static void
659 ncsi_proto_tree_add_setlink(tvbuff_t *tvb, proto_tree *tree, int offset)
660 {
661 
662     static int * const ls_fields[] = {
663         &hf_ncsi_ls_an,
664         &hf_ncsi_ls_10m,
665         &hf_ncsi_ls_100m,
666         &hf_ncsi_ls_1g,
667         &hf_ncsi_ls_10g,
668         &hf_ncsi_ls_20g,
669         &hf_ncsi_ls_25g,
670         &hf_ncsi_ls_40g,
671         &hf_ncsi_ls_hd,
672         &hf_ncsi_ls_fd,
673         &hf_ncsi_ls_pc,
674         &hf_ncsi_ls_apc,
675         &hf_ncsi_ls_50g,
676         &hf_ncsi_ls_100g,
677         &hf_ncsi_ls_2_5g,
678         &hf_ncsi_ls_5g,
679         &hf_ncsi_ls_rsv,
680         NULL,
681     };
682 
683 
684 
685     proto_tree_add_bitmask_with_flags(tree, tvb, offset, hf_ncsi_ls,
686             ett_ncsi_ls, ls_fields, ENC_BIG_ENDIAN, BMT_NO_APPEND);
687 
688     proto_tree_add_item(tree, hf_ncsi_ls_oemls, tvb, offset + 4, 4, ENC_NA);
689 
690 
691 }
692 
693 /* Code to actually dissect the packets */
694 static int
695 dissect_ncsi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
696         void *data _U_)
697 {
698     proto_tree *ncsi_tree, *ncsi_payload_tree;
699     proto_item *ti, *pti;
700     guint8 type, plen, poffset;
701 
702     static int * const type_masked_fields[] = {
703         &hf_ncsi_type_code_masked,
704         &hf_ncsi_type_resp,
705         NULL,
706     };
707 
708     static int * const chan_fields[] = {
709         &hf_ncsi_pkg,
710         &hf_ncsi_ichan,
711         NULL,
712     };
713 
714     /* Check that the packet is long enough for it to belong to us. */
715     if (tvb_reported_length(tvb) < NCSI_MIN_LENGTH)
716         return 0;
717 
718 
719     col_set_str(pinfo->cinfo, COL_PROTOCOL, "NCSI");
720 
721     type = tvb_get_guint8(tvb, 4);
722     plen = tvb_get_guint8(tvb, 7);
723 
724     col_clear(pinfo->cinfo, COL_INFO);
725     if (type == 0xff) {
726         col_add_fstr(pinfo->cinfo, COL_INFO,
727                 "Async Event Notification, chan 0x%02x",
728                 tvb_get_guint8(tvb, 5));
729     } else {
730         col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s, id 0x%02x, chan 0x%02x",
731                 val_to_str(type & 0x7f, ncsi_type_vals, "Unknown type 0x%02x"),
732                 type & 0x80 ? "response" : "request ",
733                 tvb_get_guint8(tvb, 3),
734                 tvb_get_guint8(tvb, 5));
735     }
736 
737 
738     /* Top-level NCSI protocol item & tree */
739     ti = proto_tree_add_item(tree, proto_ncsi, tvb, 0, -1, ENC_NA);
740     ncsi_tree = proto_item_add_subtree(ti, ett_ncsi);
741     /* Standard header fields */
742     proto_tree_add_item(ncsi_tree, hf_ncsi_mc_id, tvb, 0, 1, ENC_NA);
743     proto_tree_add_item(ncsi_tree, hf_ncsi_revision, tvb, 1, 1, ENC_NA);
744     proto_tree_add_item(ncsi_tree, hf_ncsi_iid, tvb, 3, 1, ENC_NA);
745     if (type == NCSI_TYPE_AEN)
746 	    proto_tree_add_uint(ncsi_tree, hf_ncsi_type_code, tvb, 4, 1, type);
747 	else
748         proto_tree_add_bitmask(ncsi_tree, tvb, 4, hf_ncsi_type,
749             ett_ncsi_type, type_masked_fields, ENC_NA);
750     /* Package# and internal channel id */
751     proto_tree_add_bitmask(ncsi_tree, tvb, 5, hf_ncsi_chan,
752             ett_ncsi_chan, chan_fields, ENC_NA);
753     proto_tree_add_item(ncsi_tree, hf_ncsi_plen, tvb, 7, 1, ENC_NA);
754     if (!plen)
755         return 16;
756 
757     /* Payload tree */
758     ncsi_payload_tree = proto_tree_add_subtree(ncsi_tree, tvb, 16,
759             plen, ett_ncsi_payload, &pti, "Payload");
760 
761     /* All responses start with response code & reason data */
762     if (type != 0xff && type & 0x80) {
763         proto_tree_add_item(ncsi_payload_tree, hf_ncsi_resp, tvb,
764                 16, 2, ENC_NA);
765         proto_tree_add_item(ncsi_payload_tree, hf_ncsi_reason, tvb,
766                 18, 2, ENC_NA);
767     }
768 
769     if (type == NCSI_TYPE_AEN) {
770         proto_item_set_text(pti, "Async Event Notification");
771     } else {
772         proto_item_set_text(pti,"%s", val_to_str((type & 0x7f), ncsi_type_vals, "Unknown type 0x%02x"));
773         proto_item_append_text(pti, type & 0x80 ? " response" : " request");
774     }
775 
776     switch (type) {
777     case 0x01:
778         proto_tree_add_item(ncsi_payload_tree, hf_ncsi_sp_hwarb, tvb,
779                 19, 1, ENC_NA);
780         break;
781     case 0x04:
782         proto_tree_add_item(ncsi_payload_tree, hf_ncsi_dc_ald, tvb,
783                 19, 1, ENC_NA);
784         break;
785     case 0x08:
786         proto_tree_add_item(ncsi_payload_tree, hf_ncsi_aene_mc, tvb,
787                 19, 1, ENC_NA);
788         break;
789 
790     case 0x09:
791         ncsi_proto_tree_add_setlink(tvb, ncsi_payload_tree, 16);
792         break;
793 
794     case 0x0e:
795         proto_tree_add_item(ncsi_payload_tree, hf_ncsi_sm_mac, tvb,
796                 16, 6, ENC_NA);
797         proto_tree_add_item(ncsi_payload_tree, hf_ncsi_sm_macno, tvb,
798                 22, 1, ENC_NA);
799         proto_tree_add_item(ncsi_payload_tree, hf_ncsi_sm_at, tvb,
800                 23, 1, ENC_NA);
801         proto_tree_add_item(ncsi_payload_tree, hf_ncsi_sm_e, tvb,
802                 23, 1, ENC_NA);
803         break;
804     case 0x10:
805         proto_tree_add_item(ncsi_payload_tree, hf_ncsi_bf, tvb,
806                 16, 4, ENC_NA);
807         proto_tree_add_item(ncsi_payload_tree, hf_ncsi_bf_arp, tvb,
808                 16, 4, ENC_NA);
809         proto_tree_add_item(ncsi_payload_tree, hf_ncsi_bf_dhcpc, tvb,
810                 16, 4, ENC_NA);
811         proto_tree_add_item(ncsi_payload_tree, hf_ncsi_bf_dhcps, tvb,
812                 16, 4, ENC_NA);
813         proto_tree_add_item(ncsi_payload_tree, hf_ncsi_bf_netbios, tvb,
814                 16, 4, ENC_NA);
815         break;
816     case NCSI_TYPE_OEM:
817     case NCSI_TYPE_OEM | 0x80:
818         poffset = 0;
819         if (type == (NCSI_TYPE_OEM | 0x80)) {
820             poffset = 4;
821         }
822 
823         proto_tree_add_item(ncsi_payload_tree, hf_ncsi_oem_id, tvb,
824                 16 + poffset, 4, ENC_NA);
825 
826         if (tvb_get_guint32(tvb, 16 + poffset, ENC_BIG_ENDIAN) == NCSI_OEM_MLX) {
827             proto_item *opti;
828             proto_tree *oem_payload_tree;
829             guint mlnx_cmd, mlnx_param;
830 
831             mlnx_cmd = tvb_get_guint8(tvb, 16 + poffset + 5);
832             mlnx_param = tvb_get_guint8(tvb, 16 + poffset + 6);
833             /* OEM payload tree */
834             oem_payload_tree = proto_tree_add_subtree(ncsi_payload_tree, tvb, 16 + poffset + 4, plen - poffset - 4, ett_ncsi_mlnx, &opti, "Mellanox OEM");
835 
836             proto_tree_add_item(oem_payload_tree, hf_ncsi_mlnx_cmd, tvb, 16 + poffset + 5, 1, ENC_NA);
837             proto_tree_add_item(oem_payload_tree, hf_ncsi_mlnx_parm, tvb, 16 + poffset + 6, 1, ENC_NA);
838             proto_tree_add_item(oem_payload_tree, hf_ncsi_mlnx_host, tvb, 16 + poffset + 7, 1, ENC_NA);
839 
840 
841             if (type == (NCSI_TYPE_OEM | 0x80)) { /* Reply */
842 
843                 if (mlnx_cmd == 0x0 && mlnx_param == 0x1b) { /* Get Allocated Management Address (Command = 0x0, Parameter 0x1B) */
844                     proto_item_set_text(opti, "Get Allocated Management Address reply");
845                     proto_tree_add_item(oem_payload_tree, hf_ncsi_mlnx_gama_st, tvb, 28, 1, ENC_NA);
846                     proto_tree_add_item(oem_payload_tree, hf_ncsi_mlnx_gama_mac, tvb, 32, 6, ENC_NA);
847                 } else if (mlnx_cmd == 0x1 && mlnx_param == 0x7) { /* Set MC Affinity (Command = 0x1, parameter 0x7) */
848                     proto_item_set_text(opti, "Set MC Affinity reply");
849                 } else {
850                     proto_item_set_text(opti, "Unknown OEM reply");
851                 }
852                 break;
853             }
854 
855             /* Request */
856 
857             if (mlnx_cmd == 0x0 && mlnx_param == 0x1b) { /* Get Allocated Management Address (Command = 0x0, Parameter 0x1B) */
858                 proto_item_set_text(opti, "Get Allocated Management Address request");
859             } else if (mlnx_cmd == 0x1 && mlnx_param == 0x7) { /* Set MC Affinity (Command = 0x1, parameter 0x7) */
860                 static int * const mlnx_sms_fields[] = {
861                     &hf_ncsi_mlnx_sms_rbt,
862                     &hf_ncsi_mlnx_sms_smbus,
863                     &hf_ncsi_mlnx_sms_pcie,
864                     &hf_ncsi_mlnx_sms_rbts,
865                     &hf_ncsi_mlnx_sms_smbuss,
866                     &hf_ncsi_mlnx_sms_pcies,
867                     NULL,
868                 };
869 
870                 static int * const mlnx_ifm_fields[] = {
871                     &hf_ncsi_mlnx_ifm_byip,
872                     &hf_ncsi_mlnx_ifm_v4en,
873                     &hf_ncsi_mlnx_ifm_v6len,
874                     &hf_ncsi_mlnx_ifm_v6gen,
875                     NULL,
876                 };
877 
878                 proto_item_set_text(opti, "Set MC Affinity request");
879                 proto_tree_add_item(oem_payload_tree, hf_ncsi_mlnx_rbt, tvb, 24, 6, ENC_NA);
880                 proto_tree_add_bitmask_with_flags(oem_payload_tree, tvb, 30, hf_ncsi_mlnx_sms, ett_ncsi_mlnx_sms, mlnx_sms_fields, ENC_BIG_ENDIAN, BMT_NO_APPEND);
881                 proto_tree_add_item(oem_payload_tree, hf_ncsi_mlnx_beid, tvb, 31, 1, ENC_NA);
882                 proto_tree_add_item(oem_payload_tree, hf_ncsi_mlnx_bidx, tvb, 32, 1, ENC_NA);
883                 proto_tree_add_item(oem_payload_tree, hf_ncsi_mlnx_baddr, tvb, 33, 1, ENC_NA);
884                 proto_tree_add_item(oem_payload_tree, hf_ncsi_mlnx_peid, tvb, 34, 1, ENC_NA);
885                 proto_tree_add_item(oem_payload_tree, hf_ncsi_mlnx_pidx, tvb, 35, 1, ENC_NA);
886                 proto_tree_add_item(oem_payload_tree, hf_ncsi_mlnx_paddr, tvb, 36, 2, ENC_NA);
887 
888                 proto_tree_add_bitmask_with_flags(oem_payload_tree, tvb, 30, hf_ncsi_mlnx_ifm, ett_ncsi_mlnx_ifm, mlnx_ifm_fields, ENC_BIG_ENDIAN, BMT_NO_APPEND);
889 
890                 /* IP Filter Mode */
891 
892                 proto_tree_add_item(oem_payload_tree, hf_ncsi_mlnx_v4addr, tvb, 40, 4, ENC_NA);
893                 proto_tree_add_item(oem_payload_tree, hf_ncsi_mlnx_v6local, tvb, 44, 16, ENC_NA);
894                 proto_tree_add_item(oem_payload_tree, hf_ncsi_mlnx_v6gbl, tvb, 60, 16, ENC_NA);
895             } else {
896                 proto_item_set_text(opti, "Unknown OEM request");
897             }
898 
899         } /* NCSI_OEM_MLX */
900 
901         break;
902     case NCSI_TYPE_GLS | 0x80:
903         ncsi_proto_tree_add_lstat(tvb, ncsi_payload_tree, 20);
904         break;
905     case NCSI_TYPE_AEN:
906         dissect_ncsi_aen(tvb, ncsi_payload_tree);
907         break;
908     case NCSI_TYPE_VER | 0x80:
909         if (plen >= 40) { /*  We got complete payload*/
910             const gchar *ver_str;
911             proto_tree  *ncsi_ver_tree;
912             gchar fw_name[13];
913             guint16 vid, did, svid, ssid;
914 
915             ncsi_ver_tree = proto_tree_add_subtree(ncsi_payload_tree, tvb, 20,
916                             plen - 4, ett_ncsi_payload, NULL, "Version ID");
917             ver_str = ncsi_bcd_dig_to_str(tvb, 20);
918             proto_tree_add_string(ncsi_ver_tree, hf_ncsi_ver, tvb, 20, 8, ver_str);
919 
920             tvb_memcpy(tvb, fw_name, 28, 12);
921             fw_name[12] = 0;
922             proto_tree_add_string(ncsi_ver_tree, hf_ncsi_fw_name, tvb, 28, 12, fw_name);
923             proto_tree_add_string(ncsi_ver_tree, hf_ncsi_fw_ver, tvb, 40, 4, ncsi_fw_version(tvb, 40));
924 
925             vid = tvb_get_guint16(tvb, 46, ENC_BIG_ENDIAN);
926             did = tvb_get_guint16(tvb, 44, ENC_BIG_ENDIAN);
927             svid = tvb_get_guint16(tvb, 50, ENC_BIG_ENDIAN);
928             ssid = tvb_get_guint16(tvb, 48, ENC_BIG_ENDIAN);
929 
930             proto_tree_add_string(ncsi_ver_tree, hf_ncsi_pci_vid, tvb,  46, 2, pci_id_str(vid, 0xffff, 0xffff, 0xffff));
931             proto_tree_add_string(ncsi_ver_tree, hf_ncsi_pci_did, tvb,  44, 2, pci_id_str(vid, did, 0xffff, 0xffff));
932             proto_tree_add_string(ncsi_ver_tree, hf_ncsi_pci_ssid, tvb,  48, 4, pci_id_str(vid, did, svid, ssid));
933             proto_tree_add_item(ncsi_ver_tree, hf_ncsi_iana, tvb, 52, 4, ENC_BIG_ENDIAN);
934         }
935         break;
936     case NCSI_TYPE_CAP | 0x80:
937         if (plen >= 32) { /*  We got complete payload */
938             ncsi_proto_tree_add_cap(tvb, ncsi_payload_tree, 20);
939         }
940         break;
941     }
942 
943     return tvb_captured_length(tvb);
944 }
945 
946 void
947 proto_register_ncsi(void)
948 {
949     /* *INDENT-OFF* */
950     /* Field definitions */
951     static hf_register_info hf[] = {
952         { &hf_ncsi_mc_id,
953           { "MC ID", "ncsi.mc_id",
954             FT_UINT8, BASE_HEX, NULL, 0x0,
955             "Management controller ID", HFILL },
956         },
957         { &hf_ncsi_revision,
958           { "Revision", "ncsi.revision",
959             FT_UINT8, BASE_HEX, NULL, 0x0,
960             "Header revision", HFILL },
961         },
962         { &hf_ncsi_iid,
963           { "IID", "ncsi.iid",
964             FT_UINT8, BASE_HEX, NULL, 0x0,
965             "Instance ID", HFILL },
966         },
967         { &hf_ncsi_type,
968           { "Type", "ncsi.type",
969             FT_UINT8, BASE_HEX, NULL, 0x0,
970             "Packet type", HFILL },
971         },
972         { &hf_ncsi_type_code,
973           { "Type code", "ncsi.type.code",
974 			FT_UINT8, BASE_HEX, VALS(ncsi_type_vals), 0,
975             "Packet type code", HFILL },
976         },
977         { &hf_ncsi_type_code_masked,
978           { "Type code", "ncsi.type.code_masked",
979             FT_UINT8, BASE_HEX, VALS(ncsi_type_vals), 0x7f,
980             "Packet type code (masked)", HFILL },
981         },
982         { &hf_ncsi_type_resp,
983           { "Type req/resp", "ncsi.type.resp",
984             FT_UINT8, BASE_HEX, VALS(ncsi_type_resp_vals), 0x80,
985             "Packet type request/response", HFILL },
986         },
987 
988         { &hf_ncsi_chan,
989           { "Channel", "ncsi.chan",
990             FT_UINT8, BASE_HEX, NULL, 0x0,
991             "NCSI Channel", HFILL },
992         },
993         { &hf_ncsi_pkg,
994           { "Package ID", "ncsi.pkg",
995             FT_UINT8, BASE_HEX, NULL, 0xe0, /* bits 7..5 */
996             "NCSI Internal Channel", HFILL },
997         },
998         { &hf_ncsi_ichan,
999           { "Internal Channel ID", "ncsi.ichan", /* bits 4..0 */
1000             FT_UINT8, BASE_HEX, NULL, 0x1f,
1001             "NCSI Internal Channel", HFILL },
1002         },
1003         { &hf_ncsi_plen,
1004           { "Payload Length", "ncsi.plen",
1005             FT_UINT8, BASE_HEX, NULL, 0x0,
1006             NULL, HFILL },
1007         },
1008         { &hf_ncsi_resp,
1009           { "Response", "ncsi.resp",
1010             FT_UINT8, BASE_HEX, VALS(ncsi_resp_code_vals), 0x0,
1011             "Response code", HFILL },
1012         },
1013         { &hf_ncsi_reason,
1014           { "Reason", "ncsi.reason",
1015             FT_UINT8, BASE_HEX, VALS(ncsi_resp_reason_vals), 0x0,
1016             "Reason code", HFILL },
1017         },
1018         { &hf_ncsi_sp_hwarb,
1019           { "Hardware arbitration disable", "ncsi.sp.hwarb",
1020             FT_UINT8, BASE_HEX, NULL, 0x0,
1021             NULL, HFILL },
1022         },
1023         { &hf_ncsi_dc_ald,
1024           { "Allow link down", "ncsi.dc.ald",
1025             FT_UINT8, BASE_HEX, NULL, 0x1,
1026             NULL, HFILL },
1027         },
1028         { &hf_ncsi_aene_mc,
1029           { "Management controller ID", "ncsi.aene.mc",
1030             FT_UINT8, BASE_HEX, NULL, 0x1,
1031             NULL, HFILL },
1032         },
1033         { &hf_ncsi_sm_mac,
1034           { "MAC address", "ncsi.sm.mac",
1035             FT_ETHER, BASE_NONE, NULL, 0,
1036             NULL, HFILL },
1037         },
1038         { &hf_ncsi_sm_macno,
1039           { "MAC address number", "ncsi.sm.macno",
1040             FT_UINT8, BASE_HEX, NULL, 0,
1041             NULL, HFILL },
1042         },
1043         { &hf_ncsi_sm_at,
1044           { "Address type", "ncsi.sm.at",
1045             FT_UINT8, BASE_HEX, VALS(ncsi_sm_at_vals), 0xe0,
1046             NULL, HFILL },
1047         },
1048         { &hf_ncsi_sm_e,
1049           { "Enabled", "ncsi.sm.e",
1050 			FT_BOOLEAN, 8, TFS(&tfs_enabled_disabled), 0x1,
1051             NULL, HFILL },
1052         },
1053         { &hf_ncsi_aen_type,
1054           { "AEN type", "ncsi.aen_type",
1055             FT_UINT8, BASE_HEX, VALS(ncsi_aen_type_vals), 0,
1056             NULL, HFILL },
1057         },
1058         { &hf_ncsi_aen_lsc_oemstat,
1059           { "AEN link OEM status", "ncsi.aen_lsc_oemstat",
1060             FT_UINT32, BASE_HEX, NULL, 0x0,
1061             NULL, HFILL },
1062         },
1063         { &hf_ncsi_aen_hcds,
1064           { "AEN Host Network Controller Driver Status", "ncsi.aen_hcds",
1065 			FT_BOOLEAN, 32, TFS(&tfs_running_not_running), 1 << 0,
1066             NULL, HFILL },
1067         },
1068         { &hf_ncsi_aen_drr_orig_type,
1069           { "Original Command Type", "ncsi.aen_drr.otype",
1070             FT_UINT8, BASE_HEX, NULL, 0x0,
1071             NULL, HFILL },
1072         },
1073         { &hf_ncsi_aen_drr_orig_iid,
1074           { "Original Command IID", "ncsi.aen_drr.oiid",
1075             FT_UINT8, BASE_HEX, NULL, 0x0,
1076             NULL, HFILL },
1077         },
1078         /* Broadcast filter */
1079         { &hf_ncsi_bf,
1080           { "Broadcast filter settings", "ncsi.bf.settings",
1081             FT_UINT32, BASE_HEX, NULL, 0x0,
1082             NULL, HFILL },
1083         },
1084         { &hf_ncsi_bf_arp,
1085           { "ARP", "ncsi.bf.settings.arp",
1086             FT_UINT32, BASE_HEX, VALS(ncsi_bf_filter_vals), 1 << 0,
1087             NULL, HFILL },
1088         },
1089         { &hf_ncsi_bf_dhcpc,
1090           { "DHCP Client", "ncsi.bf.settings.dhcpc",
1091             FT_UINT32, BASE_HEX, VALS(ncsi_bf_filter_vals), 1 << 1,
1092             NULL, HFILL },
1093         },
1094         { &hf_ncsi_bf_dhcps,
1095           { "DHCP Server", "ncsi.bf.settings.dhcps",
1096             FT_UINT32, BASE_HEX, VALS(ncsi_bf_filter_vals), 1 << 2,
1097             NULL, HFILL },
1098         },
1099         { &hf_ncsi_bf_netbios,
1100           { "NetBIOS", "ncsi.bf.settings.netbios",
1101             FT_UINT32, BASE_HEX, VALS(ncsi_bf_filter_vals), 1 << 3,
1102             NULL, HFILL },
1103         },
1104        /* Link settings */
1105         { &hf_ncsi_ls,
1106           { "Link Settings", "ncsi.ls",
1107             FT_UINT32, BASE_HEX, NULL, 0x0,
1108             NULL, HFILL },
1109         },
1110         { &hf_ncsi_ls_an,
1111           { "Auto Negotiation", "ncsi.ls.an",
1112 			FT_BOOLEAN, 32, TFS(&tfs_enabled_disabled), 1 << 0,
1113             NULL, HFILL },
1114         },
1115         { &hf_ncsi_ls_10m,
1116           { "enable 10 Mbps", "ncsi.ls.10m",
1117 			FT_BOOLEAN, 32, TFS(&tfs_set_notset), 1 << 1,
1118             NULL, HFILL },
1119         },
1120         { &hf_ncsi_ls_100m,
1121           { "enable 100 Mbps", "ncsi.ls.100m",
1122             FT_BOOLEAN, 32, TFS(&tfs_set_notset), 1 << 2,
1123             NULL, HFILL },
1124         },
1125         { &hf_ncsi_ls_1g,
1126           { "enable 1000 Mbps (1 Gbps)", "ncsi.ls.1g",
1127             FT_BOOLEAN, 32, TFS(&tfs_set_notset), 1 << 3,
1128             NULL, HFILL },
1129         },
1130         { &hf_ncsi_ls_10g,
1131           { "enable 10 Gbps", "ncsi.ls.10g",
1132             FT_BOOLEAN, 32, TFS(&tfs_set_notset), 1 << 4,
1133             NULL, HFILL },
1134         },
1135         { &hf_ncsi_ls_20g,
1136           { "enable 20 Gbps", "ncsi.ls.20g",
1137             FT_BOOLEAN, 32, TFS(&tfs_set_notset), 1 << 5,
1138             NULL, HFILL },
1139         },
1140         { &hf_ncsi_ls_25g,
1141           { "enable 25 Gbps", "ncsi.ls.25g",
1142             FT_BOOLEAN, 32, TFS(&tfs_set_notset), 1 << 6,
1143             NULL, HFILL },
1144         },
1145         { &hf_ncsi_ls_40g,
1146           { "enable 40 Gbps", "ncsi.ls.40g",
1147             FT_BOOLEAN, 32, TFS(&tfs_set_notset), 1 << 7,
1148             NULL, HFILL },
1149         },
1150         { &hf_ncsi_ls_hd,
1151           { "enable half-duplex", "ncsi.ls.hd",
1152             FT_BOOLEAN, 32, TFS(&tfs_set_notset), 1 << 8,
1153             NULL, HFILL },
1154         },
1155         { &hf_ncsi_ls_fd,
1156           { "enable full-duplex", "ncsi.ls.fd",
1157             FT_BOOLEAN, 32, TFS(&tfs_set_notset), 1 << 9,
1158             NULL, HFILL },
1159         },
1160         { &hf_ncsi_ls_pc,
1161           { "Pause Capability", "ncsi.ls.pc",
1162 			FT_BOOLEAN, 32, TFS(&tfs_enabled_disabled), 1 << 10,
1163             NULL, HFILL },
1164         },
1165         { &hf_ncsi_ls_apc,
1166           { "Asymmetric Pause Capability", "ncsi.ls.apc",
1167 			FT_BOOLEAN, 32, TFS(&tfs_enabled_disabled), 1 << 11,
1168             NULL, HFILL },
1169         },
1170         { &hf_ncsi_ls_50g,
1171           { "enable 50 Gbps", "ncsi.ls.50g",
1172             FT_BOOLEAN, 32, TFS(&tfs_set_notset), 1 << 13,
1173             NULL, HFILL },
1174         },
1175         { &hf_ncsi_ls_100g,
1176           { "enable 100 Gbps", "ncsi.ls.100g",
1177             FT_BOOLEAN, 32, TFS(&tfs_set_notset), 1 << 14,
1178             NULL, HFILL },
1179         },
1180         { &hf_ncsi_ls_2_5g,
1181           { "enable 2.5 Gbps", "ncsi.ls.2_5g",
1182             FT_BOOLEAN, 32, TFS(&tfs_set_notset), 1 << 15,
1183             NULL, HFILL },
1184         },
1185         { &hf_ncsi_ls_5g,
1186           { "enable 2.5 Gbps", "ncsi.ls.5g",
1187             FT_BOOLEAN, 32, TFS(&tfs_set_notset), 1 << 16,
1188             NULL, HFILL },
1189         },
1190         { &hf_ncsi_ls_rsv,
1191           { "Reserved", "ncsi.ls.rsv",
1192             FT_UINT32, BASE_HEX, NULL, 0xfffe0000, /* bits 17..31 */
1193             NULL, HFILL },
1194         },
1195         { &hf_ncsi_ls_oemls,
1196           { "OEM Link Settings", "ncsi.ls.oemls",
1197             FT_UINT32, BASE_HEX, NULL, 0x0 ,
1198             NULL, HFILL },
1199         },
1200 
1201         /* generic link status */
1202         { &hf_ncsi_lstat,
1203           { "Link status", "ncsi.lstat",
1204             FT_UINT32, BASE_HEX, NULL, 0x0,
1205             NULL, HFILL },
1206         },
1207         { &hf_ncsi_lstat_flag,
1208           { "Link flag", "ncsi.lstat.flag",
1209 			FT_BOOLEAN, 32, TFS(&tfs_linkup_linkdown), 0x1,
1210             NULL, HFILL },
1211         },
1212         { &hf_ncsi_lstat_speed_duplex,
1213           { "Speed & duplex", "ncsi.lstat.speed_duplex",
1214             FT_UINT32, BASE_HEX, VALS(ncsi_lstat_speed_duplex_vals), 0x1e,
1215             NULL, HFILL },
1216         },
1217         { &hf_ncsi_lstat_autoneg,
1218           { "Autonegotiation", "ncsi.lstat.autoneg",
1219 	    FT_BOOLEAN, 32, TFS(&tfs_enabled_disabled), 1 << 5,
1220             NULL, HFILL },
1221         },
1222         { &hf_ncsi_lstat_autoneg_complete,
1223           { "Autonegotiation complete", "ncsi.lstat.autoneg_complete",
1224 			FT_BOOLEAN, 32, TFS(&tfs_complete_disable_inprog), 1 << 6,
1225             NULL, HFILL },
1226         },
1227         { &hf_ncsi_lstat_parallel_detection,
1228           { "Parallel detection", "ncsi.lstat.parallel_detection",
1229 			FT_BOOLEAN, 32, TFS(&tfs_used_notused), 1 << 7,
1230             NULL, HFILL },
1231         },
1232         { &hf_ncsi_lstat_1000TFD,
1233           { "1000TFD", "ncsi.lstat.1000tfd",
1234 			FT_BOOLEAN, 32, TFS(&tfs_capable_not_capable), 1 << 9,
1235             "Partner advertised 1000TFD", HFILL },
1236         },
1237         { &hf_ncsi_lstat_1000THD,
1238           { "1000THD", "ncsi.lstat.1000thd",
1239 			FT_BOOLEAN, 32, TFS(&tfs_capable_not_capable), 1 << 10,
1240             "Partner advertised 1000THD", HFILL },
1241         },
1242         { &hf_ncsi_lstat_100T4,
1243           { "100T4", "ncsi.lstat.100t4",
1244 			FT_BOOLEAN, 32, TFS(&tfs_capable_not_capable), 1 << 11,
1245             "Partner advertised 100T4", HFILL },
1246         },
1247         { &hf_ncsi_lstat_100TXFD,
1248           { "100TXFD", "ncsi.lstat.100txfd",
1249 			FT_BOOLEAN, 32, TFS(&tfs_capable_not_capable), 1 << 12,
1250             "Partner advertised 100TXFD", HFILL },
1251         },
1252         { &hf_ncsi_lstat_100TXHD,
1253           { "100TXHD", "ncsi.lstat.100txhd",
1254 			FT_BOOLEAN, 32, TFS(&tfs_capable_not_capable), 1 << 13,
1255             "Partner advertised 100TXHD", HFILL },
1256         },
1257         { &hf_ncsi_lstat_10TFD,
1258           { "10TFD", "ncsi.lstat.10tfd",
1259 	    FT_BOOLEAN, 32, TFS(&tfs_capable_not_capable), 1 << 14,
1260             "Partner advertised 10TFD", HFILL },
1261         },
1262         { &hf_ncsi_lstat_10THD,
1263           { "10THD", "ncsi.lstat.10thd",
1264 	    FT_BOOLEAN, 32, TFS(&tfs_capable_not_capable), 1 << 15,
1265             "Partner advertised 10THD", HFILL },
1266         },
1267         { &hf_ncsi_lstat_tx_flow,
1268           { "TX flow", "ncsi.lstat.tx_flow",
1269 	    FT_BOOLEAN, 32, TFS(&tfs_enabled_disabled), 1 << 16,
1270             "TX flow control", HFILL },
1271         },
1272         { &hf_ncsi_lstat_rx_flow,
1273           { "RX flow", "ncsi.lstat.rx_flow",
1274 	    FT_BOOLEAN, 32, TFS(&tfs_enabled_disabled), 1 << 17,
1275             "RX flow control", HFILL },
1276         },
1277         { &hf_ncsi_lstat_partner_flow,
1278           { "Partner flow", "ncsi.lstat.partner_flow",
1279             FT_UINT32, BASE_HEX, VALS(ncsi_partner_flow_vals), 3<<18,
1280             "Partner-advertised flow control", HFILL },
1281         },
1282         { &hf_ncsi_lstat_serdes,
1283           { "SerDes", "ncsi.lstat.serdes",
1284 			FT_BOOLEAN, 32, TFS(&tfs_used_notused), 1 << 20,
1285             NULL, HFILL },
1286         },
1287         { &hf_ncsi_lstat_oem_speed_valid,
1288           { "OEM Speed", "ncsi.lstat.oem_speed_valid",
1289 			FT_BOOLEAN, 32, TFS(&tfs_valid_invalid), 1 << 21,
1290             NULL, HFILL },
1291         },
1292 
1293         /* Get Verison ID */
1294         { &hf_ncsi_ver,
1295           { "NC-SI version", "ncsi.ver",
1296             FT_STRING, BASE_NONE, NULL, 0,
1297             NULL, HFILL },
1298         },
1299 
1300         { &hf_ncsi_fw_name,
1301           { "Firmware name", "ncsi.fw.name",
1302             FT_STRING, BASE_NONE, NULL, 0,
1303             NULL, HFILL },
1304         },
1305         { &hf_ncsi_fw_ver,
1306           { "Firmware version", "ncsi.fw.ver",
1307             FT_STRING, BASE_NONE, NULL, 0,
1308             NULL, HFILL },
1309         },
1310         { &hf_ncsi_pci_did,
1311           { "PCI DID", "ncsi.pci.did",
1312             FT_STRING, BASE_NONE, NULL, 0,
1313             NULL, HFILL },
1314         },
1315         { &hf_ncsi_pci_vid,
1316           { "PCI VID", "ncsi.pci.vid",
1317             FT_STRING, BASE_NONE, NULL, 0,
1318             NULL, HFILL },
1319         },
1320         { &hf_ncsi_pci_ssid,
1321           { "PCI SVID-SSID", "ncsi.pci.ssid",
1322             FT_STRING, BASE_NONE, NULL, 0,
1323             NULL, HFILL },
1324         },
1325         { &hf_ncsi_iana,
1326           { "IANA Enterprise Number", "ncsi.iana",
1327             FT_UINT32, BASE_ENTERPRISES, STRINGS_ENTERPRISES, 0,
1328             NULL, HFILL },
1329         },
1330 
1331         /* Get Capabilities */
1332         { &hf_ncsi_cap_flag,
1333           { "Capabilities Flags", "ncsi.cap",
1334             FT_UINT32, BASE_HEX, NULL, 0x0,
1335             NULL, HFILL },
1336         },
1337         { &hf_ncsi_cap_flag_ha,
1338           { "Hardware Arbitration", "ncsi.cap.ha",
1339 			FT_BOOLEAN, 32, TFS(&tfs_capable_not_capable), 1 << 0,
1340             NULL, HFILL },
1341         },
1342         { &hf_ncsi_cap_flag_op,
1343           { "OS Presence", "ncsi.cap.op",
1344 			FT_BOOLEAN, 32, TFS(&tfs_capable_not_capable), 1 << 1,
1345             NULL, HFILL },
1346         },
1347         { &hf_ncsi_cap_flag_n2mfc,
1348           { "Network Controller to Management Controller Flow Control Support", "ncsi.cap.n2mfc",
1349 			FT_BOOLEAN, 32, TFS(&tfs_capable_not_capable), 1 << 2,
1350             NULL, HFILL },
1351         },
1352         { &hf_ncsi_cap_flag_m2nfc,
1353           { "Management Controller to Network Controller Flow Control Support", "ncsi.cap.m2nfc",
1354 			FT_BOOLEAN, 32, TFS(&tfs_capable_not_capable), 1 << 3,
1355             NULL, HFILL },
1356         },
1357         { &hf_ncsi_cap_flag_ama,
1358           { "All multicast addresses support", "ncsi.cap.ama",
1359 			FT_BOOLEAN, 32, TFS(&tfs_capable_not_capable), 1 << 4,
1360             NULL, HFILL },
1361         },
1362         /* Broadcast Packet Filter Capabilities*/
1363         { &hf_ncsi_cap_bf,
1364           { "Broadcast Packet Filter Capabilities", "ncsi.cap.bf",
1365             FT_UINT32, BASE_HEX, NULL, 0x0,
1366             NULL, HFILL },
1367         },
1368         { &hf_ncsi_cap_bf_arp,
1369           { "ARP", "ncsi.cap.bf.arp",
1370 			FT_BOOLEAN, 32, TFS(&tfs_capable_not_capable), 1 << 0,
1371             NULL, HFILL },
1372         },
1373         { &hf_ncsi_cap_bf_dhcpc,
1374           { "DHCP Client", "ncsi.cap.bf.dhcpc",
1375 			FT_BOOLEAN, 32, TFS(&tfs_capable_not_capable), 1 << 1,
1376             NULL, HFILL },
1377         },
1378         { &hf_ncsi_cap_bf_dhcps,
1379           { "DHCP Server", "ncsi.cap.bf.dhcps",
1380 			FT_BOOLEAN, 32, TFS(&tfs_capable_not_capable), 1 << 2,
1381             NULL, HFILL },
1382         },
1383         { &hf_ncsi_cap_bf_netbios,
1384           { "NetBIOS", "ncsi.cap.bf.netbios",
1385 			FT_BOOLEAN, 32, TFS(&tfs_capable_not_capable), 1 << 3,
1386             NULL, HFILL },
1387         },
1388         /*Multicast Packet Filter Capabilities*/
1389         { &hf_ncsi_cap_mf,
1390           { "Multicast Packet Filter Capabilities", "ncsi.cap.mf",
1391             FT_UINT32, BASE_HEX, NULL, 0x0,
1392             NULL, HFILL },
1393         },
1394         { &hf_ncsi_cap_mf_v6na,
1395           { "IPv6 Neighbor Advertisement", "ncsi.cap.mf.v6na",
1396 			FT_BOOLEAN, 32, TFS(&tfs_capable_not_capable), 1 << 0,
1397             NULL, HFILL },
1398         },
1399         { &hf_ncsi_cap_mf_v6ra,
1400           { "IPv6 Router Advertisement", "ncsi.cap.mf.v6ra",
1401 			FT_BOOLEAN, 32, TFS(&tfs_capable_not_capable), 1 << 1,
1402             NULL, HFILL },
1403         },
1404         { &hf_ncsi_cap_mf_dhcpv6,
1405           { "DHCPv6 relay and server multicast", "ncsi.cap.mf.v6na",
1406 			FT_BOOLEAN, 32, TFS(&tfs_capable_not_capable), 1 << 2,
1407             NULL, HFILL },
1408         },
1409         /*Buffering Capability*/
1410         { &hf_ncsi_cap_buf,
1411           { "Buffering Capability (bytes)", "ncsi.cap.buf",
1412             FT_UINT32, BASE_HEX, NULL, 0x0,
1413             NULL, HFILL },
1414         },
1415         /*AEN Control Support*/
1416         { &hf_ncsi_cap_aen,
1417           { "AEN Control Support", "ncsi.cap.aen",
1418             FT_UINT32, BASE_HEX, NULL, 0x0,
1419             NULL, HFILL },
1420         },
1421         { &hf_ncsi_cap_aen_lstat,
1422           { "Link Status Change AEN control", "ncsi.cap.aen.lstat",
1423 			FT_BOOLEAN, 32, TFS(&tfs_capable_not_capable), 1 << 0,
1424             NULL, HFILL },
1425         },
1426         { &hf_ncsi_cap_aen_cfg,
1427           { "Configuration Required AEN control", "ncsi.cap.aen.cfg",
1428 			FT_BOOLEAN, 32, TFS(&tfs_capable_not_capable), 1 << 1,
1429             NULL, HFILL },
1430         },
1431         { &hf_ncsi_cap_aen_drv,
1432           { "Host NC Driver Status Change AEN control", "ncsi.cap.mf.drv",
1433 			FT_BOOLEAN, 32, TFS(&tfs_capable_not_capable), 1 << 2,
1434             NULL, HFILL },
1435         },
1436         { &hf_ncsi_cap_aen_resv, /* bit 3..15 Reserved Reserved */
1437           { "Reserved", "ncsi.cap.mf.resv",
1438             FT_UINT32, BASE_HEX, NULL,  0xfff8,
1439             NULL, HFILL },
1440         },
1441         { &hf_ncsi_cap_aen_oem,
1442           { "OEM-specific AEN control", "ncsi.cap.mf.oem",
1443             FT_UINT32, BASE_HEX, NULL,  0xffff0000,
1444             NULL, HFILL },
1445         },
1446 
1447         { &hf_ncsi_cap_vcnt,
1448           { "VLAN Filter Count", "ncsi.cap.vcnt",
1449             FT_UINT8, BASE_HEX, NULL, 0x0,
1450             NULL, HFILL },
1451         },
1452         { &hf_ncsi_cap_mixcnt,
1453           { "Mixed Filter Count", "ncsi.cap.mixcnt",
1454             FT_UINT8, BASE_HEX, NULL, 0x0,
1455             NULL, HFILL },
1456         },
1457         { &hf_ncsi_cap_mccnt,
1458           { "Multicast Filter Count", "ncsi.cap.mccnt",
1459             FT_UINT8, BASE_HEX, NULL, 0x0,
1460             NULL, HFILL },
1461         },
1462         { &hf_ncsi_cap_uccnt,
1463           { "Unicast Filter Count", "ncsi.cap.uccnt",
1464             FT_UINT8, BASE_HEX, NULL, 0x0,
1465             NULL, HFILL },
1466         },
1467         /*VLAN mode*/
1468         { &hf_ncsi_cap_vmode,
1469           { "VLAN Mode Support", "ncsi.cap.vmode",
1470             FT_UINT8, BASE_HEX, NULL, 0x0,
1471             NULL, HFILL },
1472         },
1473         { &hf_ncsi_cap_vmode_vo,
1474           { "VLAN only", "ncsi.cap.aen.vmode.vo",
1475 			FT_BOOLEAN, 8, TFS(&tfs_capable_not_capable), 1 << 0,
1476             NULL, HFILL },
1477         },
1478         { &hf_ncsi_cap_vmode_both,
1479           { "VLAN + non-VLAN", "ncsi.cap.aen.vmode.both",
1480 			FT_BOOLEAN, 8, TFS(&tfs_capable_not_capable), 1 << 1,
1481             NULL, HFILL },
1482         },
1483         { &hf_ncsi_cap_vmode_any,
1484           { "Any VLAN + non-VLAN", "ncsi.cap.aen.vmode.any",
1485 			FT_BOOLEAN, 8, TFS(&tfs_capable_not_capable), 1 << 2,
1486             NULL, HFILL },
1487         },
1488         { &hf_ncsi_cap_chcnt,
1489           { "Channel Count", "ncsi.cap.chcnt",
1490             FT_UINT8, BASE_HEX, NULL, 0x0,
1491             NULL, HFILL },
1492         },
1493         /* OEM command */
1494         { &hf_ncsi_oem_id,
1495           { "OEM ID", "ncsi.oem.id",
1496             FT_UINT32, BASE_HEX, VALS(ncsi_oem_id_vals), 0x0,
1497             "Manufacturer ID (IANA)", HFILL },
1498         },
1499         /* OEM Mellanox Command, Parameter, Host number */
1500         { &hf_ncsi_mlnx_cmd,
1501           { "Command ID", "ncsi.mlnx.cmd",
1502             FT_UINT8, BASE_HEX, NULL, 0x0,
1503             "Mellanox command id", HFILL },
1504         },
1505         { &hf_ncsi_mlnx_parm,
1506           { "Parameter", "ncsi.mlnx.parm",
1507             FT_UINT8, BASE_HEX, NULL, 0x0,
1508             "Mellanox parameter", HFILL },
1509         },
1510         { &hf_ncsi_mlnx_host,
1511           { "Host number", "ncsi.mlnx.host",
1512             FT_UINT8, BASE_HEX, NULL, 0x0,
1513             "Mellanox host number", HFILL },
1514         },
1515         /* OEM Mellanox Set MC Affinity (Command = 0x1, parameter 0x7) */
1516         { &hf_ncsi_mlnx_rbt,
1517           { "MC RBT address", "ncsi.mlnx.rbt",
1518             FT_ETHER, BASE_NONE, NULL, 0x0,
1519             NULL, HFILL },
1520         },
1521 
1522         { &hf_ncsi_mlnx_sms,
1523           { "Supported Medias Status", "ncsi.mlx.sms",
1524             FT_UINT8, BASE_HEX, NULL, 0x0,
1525             NULL, HFILL },
1526         },
1527         { &hf_ncsi_mlnx_sms_rbt,
1528           { "RBT", "ncsi.mlx.sms.rbt",
1529 			FT_BOOLEAN, 8, TFS(&tfs_supported_not_supported), 1 << 0,
1530             "When set the MC supports RBT", HFILL },
1531         },
1532         { &hf_ncsi_mlnx_sms_smbus,
1533           { "SMBus", "ncsi.mlx.sms.smbus",
1534 			FT_BOOLEAN, 8, TFS(&tfs_supported_not_supported), 1 << 1,
1535             "When set, the MC supports MCTP over SMBus", HFILL },
1536         },
1537         { &hf_ncsi_mlnx_sms_pcie,
1538           { "PCIe", "ncsi.mlx.sms.pcie",
1539 			FT_BOOLEAN, 8, TFS(&tfs_supported_not_supported), 1 << 2,
1540             "When set, the MC supports MCTP over PCIe", HFILL },
1541         },
1542         { &hf_ncsi_mlnx_sms_rbts,
1543           { "RBT medium status", "ncsi.mlx.sms.rbts",
1544 			FT_BOOLEAN, 8, TFS(&tfs_available_not_available), 1 << 3,
1545             NULL, HFILL },
1546         },
1547         { &hf_ncsi_mlnx_sms_smbuss,
1548           { "SMBus medium status", "ncsi.mlx.sms.smbuss",
1549 			FT_BOOLEAN, 8, TFS(&tfs_available_not_available), 1 << 4,
1550             NULL, HFILL },
1551         },
1552         { &hf_ncsi_mlnx_sms_pcies,
1553           { "PCIe medium status", "ncsi.mlx.sms.pcies",
1554 			FT_BOOLEAN, 8, TFS(&tfs_available_not_available), 1 << 5,
1555             NULL, HFILL },
1556         },
1557         { &hf_ncsi_mlnx_beid,
1558           { "MC SMBus EID", "ncsi.mlx.beid",
1559             FT_UINT8, BASE_HEX, NULL, 0x0,
1560             NULL, HFILL },
1561         },
1562         { &hf_ncsi_mlnx_bidx,
1563           { "SMBus index", "ncsi.mlx.bidx",
1564             FT_UINT8, BASE_HEX, NULL, 0x0,
1565             NULL, HFILL },
1566         },
1567         { &hf_ncsi_mlnx_baddr,
1568           { "MC SMBus address", "ncsi.mlx.baddr",
1569             FT_UINT8, BASE_HEX, NULL, 0x0,
1570             NULL, HFILL },
1571         },
1572         { &hf_ncsi_mlnx_peid,
1573           { "MC PCIe EID", "ncsi.mlx.peid",
1574             FT_UINT8, BASE_HEX, NULL, 0x0,
1575             NULL, HFILL },
1576         },
1577         { &hf_ncsi_mlnx_pidx,
1578           { "PCIe index", "ncsi.mlx.pidx",
1579             FT_UINT8, BASE_HEX, NULL, 0x0,
1580             NULL, HFILL },
1581         },
1582         { &hf_ncsi_mlnx_paddr,
1583           { "MC PCIe Address", "ncsi.mlx.paddr",
1584             FT_UINT16, BASE_HEX, NULL, 0x0,
1585             NULL, HFILL },
1586         },
1587         { &hf_ncsi_mlnx_ifm,
1588           { "MC IP Filter Mode", "ncsi.mlx.ifm",
1589             FT_UINT8, BASE_HEX, NULL, 0x0,
1590             NULL, HFILL },
1591         },
1592         { &hf_ncsi_mlnx_ifm_byip,
1593           { "Filter by IP Address", "ncsi.mlx.ifm.byip",
1594             FT_UINT8, BASE_HEX, VALS(ncsi_mlnx_ifm_byip_vals), 0x3,
1595             NULL, HFILL },
1596         },
1597         { &hf_ncsi_mlnx_ifm_v4en,
1598           { "IPv4", "ncsi.mlx.ifm.v4en",
1599 			FT_BOOLEAN, 8, TFS(&tfs_used_notused), 1 << 2,
1600             NULL, HFILL },
1601         },
1602         { &hf_ncsi_mlnx_ifm_v6len,
1603           { "IPv6 Link Local Address", "ncsi.mlx.ifm.v6len",
1604 			FT_BOOLEAN, 8, TFS(&tfs_used_notused), 1 << 3,
1605             NULL, HFILL },
1606         },
1607         { &hf_ncsi_mlnx_ifm_v6gen,
1608           { "IPv6 Global Address", "ncsi.mlx.ifm.v6gen",
1609 			FT_BOOLEAN, 8, TFS(&tfs_used_notused), 1 << 4,
1610             NULL, HFILL },
1611         },
1612         { &hf_ncsi_mlnx_v4addr,
1613           { "MC IPv4 Address", "ncsi.mlnx.v4addr",
1614             FT_IPv4, BASE_NONE, NULL, 0x0,
1615             NULL, HFILL },
1616         },
1617         { &hf_ncsi_mlnx_v6local,
1618           { "MC IPv6 Link Local Address", "ncsi.mlnx.v6local",
1619             FT_IPv6, BASE_NONE, NULL, 0x0,
1620             NULL, HFILL },
1621         },
1622         { &hf_ncsi_mlnx_v6gbl,
1623           { "MC IPv6 Global Address", "ncsi.mlnx.v6gbl",
1624             FT_IPv6, BASE_NONE, NULL, 0x0,
1625             NULL, HFILL },
1626         },
1627         /* Get Allocated Management Address (Command = 0x0, Parameter 0x1B) */
1628         { &hf_ncsi_mlnx_gama_st,
1629           { "Status", "ncsi.mlx.gama.st",
1630             FT_UINT8, BASE_HEX, VALS(ncsi_mlnx_gama_st_vals), 0x0,
1631             NULL, HFILL },
1632         },
1633         { &hf_ncsi_mlnx_gama_mac,
1634           { "Allocated MC MAC address", "ncsi.mlx.gama.mac",
1635             FT_ETHER, BASE_NONE, NULL, 0x0,
1636             NULL, HFILL },
1637         },
1638 
1639 
1640 
1641     };
1642 
1643 	/* *INDENT-ON* */
1644 
1645     /* Setup protocol subtree array */
1646     static gint *ett[] = {
1647         &ett_ncsi,
1648         &ett_ncsi_type,
1649         &ett_ncsi_chan,
1650         &ett_ncsi_payload,
1651         &ett_ncsi_lstat,
1652         &ett_ncsi_cap_flag,
1653         &ett_ncsi_cap_bf,
1654         &ett_ncsi_cap_mf,
1655         &ett_ncsi_cap_aen,
1656         &ett_ncsi_cap_vmode,
1657         &ett_ncsi_ls,
1658         &ett_ncsi_mlnx,
1659         &ett_ncsi_mlnx_sms,
1660         &ett_ncsi_mlnx_ifm
1661     };
1662 
1663     /* Register the protocol name and description */
1664     proto_ncsi = proto_register_protocol("NCSI", "NCSI", "ncsi");
1665 
1666     /* Required function calls to register the header fields and subtrees */
1667     proto_register_field_array(proto_ncsi, hf, array_length(hf));
1668     proto_register_subtree_array(ett, array_length(ett));
1669 }
1670 
1671 void
1672 proto_reg_handoff_ncsi(void)
1673 {
1674     dissector_handle_t ncsi_handle;
1675     ncsi_handle = create_dissector_handle(dissect_ncsi, proto_ncsi);
1676     dissector_add_uint("ethertype", ETHERTYPE_NCSI, ncsi_handle);
1677 }
1678 
1679 /*
1680  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
1681  *
1682  * Local variables:
1683  * c-basic-offset: 4
1684  * tab-width: 8
1685  * indent-tabs-mode: nil
1686  * End:
1687  *
1688  * vi: set shiftwidth=4 tabstop=8 expandtab:
1689  * :indentSize=4:tabSize=8:noTabs=true:
1690  */
1691 
1692 /*
1693  * Formatted by AStyle (3.1) -A10YcHjk3pUxUxBxt2 if under Windows
1694  */
1695