/src/wireshark/epan/dissectors/packet-dpaux.c
Line | Count | Source |
1 | | /* packet-dpaux.c |
2 | | * Routines for DisplayPort AUX-Channel dissection |
3 | | * Copyright 2018, Dirk Eibach, Guntermann & Drunck GmbH <dirk.eibach@gdsys.cc> |
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 | | #include <config.h> |
13 | | #include <conversation.h> |
14 | | |
15 | | #include <epan/packet.h> |
16 | | #include <epan/proto_data.h> |
17 | | |
18 | | #include "packet-dpaux.h" |
19 | | |
20 | | void proto_register_dpaux(void); |
21 | | |
22 | | static int proto_dpaux; |
23 | | |
24 | | static int hf_dpaux_transaction_type; |
25 | | static int hf_dpaux_native_req_cmd; |
26 | | static int hf_dpaux_i2c_req_cmd; |
27 | | static int hf_dpaux_reply_cmd; |
28 | | static int hf_dpaux_mot; |
29 | | static int hf_dpaux_addr; |
30 | | static int hf_dpaux_len; |
31 | | static int hf_dpaux_data; |
32 | | |
33 | | static int hf_dpaux_reg_addr; |
34 | | |
35 | | static int hf_00000; |
36 | | static int hf_00000_MINOR; |
37 | | static int hf_00000_MAJOR; |
38 | | static int * const reg00000_fields[] = { |
39 | | &hf_00000_MAJOR, |
40 | | &hf_00000_MINOR, |
41 | | NULL |
42 | | }; |
43 | | |
44 | | static int hf_00001; |
45 | | static int hf_00001_MAX_LINK_RATE; |
46 | | static int * const reg00001_fields[] = { |
47 | | &hf_00001_MAX_LINK_RATE, |
48 | | NULL |
49 | | }; |
50 | | |
51 | | static int hf_00002; |
52 | | static int hf_00002_MAX_LANE_COUNT; |
53 | | static int hf_00002_POST_LT_ADJ_REQ_SUPPORTED; |
54 | | static int hf_00002_TPS3_SUPPORTED; |
55 | | static int hf_00002_ENHANCED_FRAME_CAP; |
56 | | static int * const reg00002_fields[] = { |
57 | | &hf_00002_MAX_LANE_COUNT, |
58 | | &hf_00002_POST_LT_ADJ_REQ_SUPPORTED, |
59 | | &hf_00002_TPS3_SUPPORTED, |
60 | | &hf_00002_ENHANCED_FRAME_CAP, |
61 | | NULL |
62 | | }; |
63 | | |
64 | | static int hf_00003; |
65 | | static int hf_00003_MAX_DOWNSPREAD; |
66 | | static int hf_00003_NO_AUX_TRANSACTION_LINK_TRAINING; |
67 | | static int hf_00003_TPS4_SUPPORTED; |
68 | | static int * const reg00003_fields[] = { |
69 | | &hf_00003_MAX_DOWNSPREAD, |
70 | | &hf_00003_NO_AUX_TRANSACTION_LINK_TRAINING, |
71 | | &hf_00003_TPS4_SUPPORTED, |
72 | | NULL |
73 | | }; |
74 | | |
75 | | static int hf_00004; |
76 | | static int hf_00004_NORP; |
77 | | static int hf_00004_5V_DP_PWR_CAP; |
78 | | static int hf_00004_12V_DP_PWR_CAP; |
79 | | static int hf_00004_18V_DP_PWR_CAP; |
80 | | static int * const reg00004_fields[] = { |
81 | | &hf_00004_NORP, |
82 | | &hf_00004_5V_DP_PWR_CAP, |
83 | | &hf_00004_12V_DP_PWR_CAP, |
84 | | &hf_00004_18V_DP_PWR_CAP, |
85 | | NULL |
86 | | }; |
87 | | |
88 | | /* Initialize the subtree pointers */ |
89 | | static int ett_dpaux; |
90 | | static int ett_register; |
91 | | |
92 | | struct dpaux_transaction { |
93 | | bool is_native; |
94 | | uint32_t addr; |
95 | | }; |
96 | | |
97 | | enum { |
98 | | DPAUX_TRANSACTION_NATIVE, |
99 | | DPAUX_TRANSACTION_I2C_OVER_AUX, |
100 | | DPAUX_TRANSACTION_N_A, |
101 | | }; |
102 | | |
103 | | enum { |
104 | | DPAUX_REPLY_CODE_ACK = 0x0, |
105 | | DPAUX_REPLY_CODE_I2C_ACK = 0x0, |
106 | | DPAUX_REPLY_CODE_NACK = 0x1, |
107 | | DPAUX_REPLY_CODE_DEFER = 0x2, |
108 | | DPAUX_REPLY_CODE_I2C_NACK = 0x4, |
109 | | DPAUX_REPLY_CODE_I2C_DEFER = 0x8, |
110 | | }; |
111 | | |
112 | | enum { |
113 | | DPAUX_REGISTER_TYPE_BITFIELD, |
114 | | }; |
115 | | |
116 | | struct bitfield_data { |
117 | | int *hf; |
118 | | int * const *fields; |
119 | | }; |
120 | | |
121 | | struct dpaux_register { |
122 | | uint32_t addr; |
123 | | uint8_t type; |
124 | | union { |
125 | | struct bitfield_data bitfield; |
126 | | } data; |
127 | | }; |
128 | | |
129 | | static struct dpaux_register registers[] = { |
130 | | { 0x0, DPAUX_REGISTER_TYPE_BITFIELD, .data.bitfield = { &hf_00000, reg00000_fields } }, |
131 | | { 0x1, DPAUX_REGISTER_TYPE_BITFIELD, .data.bitfield = { &hf_00001, reg00001_fields } }, |
132 | | { 0x2, DPAUX_REGISTER_TYPE_BITFIELD, .data.bitfield = { &hf_00002, reg00002_fields } }, |
133 | | { 0x3, DPAUX_REGISTER_TYPE_BITFIELD, .data.bitfield = { &hf_00003, reg00003_fields } }, |
134 | | { 0x4, DPAUX_REGISTER_TYPE_BITFIELD, .data.bitfield = { &hf_00004, reg00004_fields } }, |
135 | | }; |
136 | | |
137 | | static int |
138 | | dissect_dpaux_register(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, |
139 | | unsigned int offset, unsigned int register_addr) |
140 | 0 | { |
141 | 0 | unsigned int k; |
142 | 0 | struct dpaux_register *reg = NULL; |
143 | |
|
144 | 0 | for (k = 0; k < G_N_ELEMENTS(registers); ++k) { |
145 | 0 | if (registers[k].addr == register_addr) { |
146 | 0 | reg = ®isters[k]; |
147 | 0 | break; |
148 | 0 | } |
149 | 0 | } |
150 | |
|
151 | 0 | if (!reg) |
152 | 0 | return -1; |
153 | | |
154 | 0 | switch (reg->type) { |
155 | 0 | case DPAUX_REGISTER_TYPE_BITFIELD: |
156 | 0 | proto_tree_add_bitmask_with_flags(tree, tvb, offset, |
157 | 0 | *reg->data.bitfield.hf, 0, |
158 | 0 | reg->data.bitfield.fields, |
159 | 0 | ENC_BIG_ENDIAN, BMT_NO_FLAGS); |
160 | 0 | break; |
161 | 0 | } |
162 | | |
163 | 0 | return 1; |
164 | 0 | } |
165 | | |
166 | | static int |
167 | | dissect_dpaux_from_source(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) |
168 | 0 | { |
169 | 0 | uint8_t type = tvb_get_bits8(tvb, 0, 1); |
170 | 0 | uint8_t mot = tvb_get_bits8(tvb, 1, 1); |
171 | 0 | uint8_t cmd = tvb_get_bits8(tvb, 2, 2); |
172 | 0 | uint32_t addr = tvb_get_bits32(tvb, 4, 20, ENC_BIG_ENDIAN); |
173 | 0 | unsigned len = tvb_get_uint8(tvb, 3) + 1; |
174 | 0 | bool is_read = cmd & 0x1; |
175 | | |
176 | | /* Remember the request for the reply, on the first pass only */ |
177 | 0 | if (!PINFO_FD_VISITED(pinfo)) { |
178 | 0 | conversation_t *conversation; |
179 | 0 | struct dpaux_transaction *transaction; |
180 | |
|
181 | 0 | conversation = conversation_new(pinfo->num, &pinfo->src, &pinfo->dst, |
182 | 0 | CONVERSATION_NONE, pinfo->srcport, pinfo->destport, 0); |
183 | |
|
184 | 0 | transaction = wmem_new(wmem_file_scope(), struct dpaux_transaction); |
185 | 0 | transaction->is_native = type; |
186 | 0 | transaction->addr = addr; |
187 | |
|
188 | 0 | conversation_add_proto_data(conversation, proto_dpaux, (void *)transaction); |
189 | 0 | } |
190 | |
|
191 | 0 | proto_tree_add_uint(tree, hf_dpaux_transaction_type, tvb, 0, 0, |
192 | 0 | type ? DPAUX_TRANSACTION_NATIVE : DPAUX_TRANSACTION_I2C_OVER_AUX); |
193 | |
|
194 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, |
195 | 0 | type ? "Native" : "I2C-over-AUX"); |
196 | 0 | col_set_str(pinfo->cinfo, COL_INFO, is_read ? "RD" : "WR"); |
197 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, " %u byte%s %s 0x%05x", |
198 | 0 | len, len > 1 ? "s" : "", is_read ? "FROM" : "TO", addr); |
199 | |
|
200 | 0 | if (type) { |
201 | 0 | proto_tree_add_uint(tree, hf_dpaux_native_req_cmd, tvb, 0, 1, cmd); |
202 | 0 | } else { |
203 | 0 | proto_tree_add_uint(tree, hf_dpaux_i2c_req_cmd, tvb, 0, 1, cmd); |
204 | 0 | proto_tree_add_boolean(tree, hf_dpaux_mot, tvb, 0, 1, mot); |
205 | 0 | } |
206 | 0 | proto_tree_add_uint(tree, hf_dpaux_addr, tvb, 0, 3, addr); |
207 | 0 | proto_tree_add_uint(tree, hf_dpaux_len, tvb, 3, 1, len); |
208 | | |
209 | |
|
210 | 0 | if (!is_read) |
211 | 0 | proto_tree_add_item(tree, hf_dpaux_data, tvb, 4, len, ENC_NA); |
212 | |
|
213 | 0 | return 0; |
214 | 0 | } |
215 | | |
216 | | static int |
217 | | dissect_dpaux_from_sink(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) |
218 | 0 | { |
219 | | /* Reply command: I2C-over-AUX reply in bits 7:6, AUX reply in bits 5:4 */ |
220 | 0 | uint8_t cmd = tvb_get_bits8(tvb, 0, 4); |
221 | 0 | unsigned len = (tvb_reported_length(tvb) > 1) ? tvb_reported_length(tvb) -1 : 0; |
222 | 0 | conversation_t *conversation = NULL; |
223 | 0 | struct dpaux_transaction *transaction = NULL; |
224 | 0 | proto_item *ti; |
225 | |
|
226 | 0 | conversation = find_conversation(pinfo->num, &pinfo->src, &pinfo->dst, |
227 | 0 | CONVERSATION_NONE, pinfo->srcport, pinfo->destport, 0); |
228 | 0 | if (conversation) |
229 | 0 | transaction = (struct dpaux_transaction*)conversation_get_proto_data( |
230 | 0 | conversation, proto_dpaux); |
231 | |
|
232 | 0 | if (transaction) { |
233 | 0 | proto_tree_add_uint(tree, hf_dpaux_transaction_type, tvb, 0, 0, |
234 | 0 | transaction->is_native ? DPAUX_TRANSACTION_NATIVE : |
235 | 0 | DPAUX_TRANSACTION_I2C_OVER_AUX); |
236 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, |
237 | 0 | transaction->is_native ? "Native" : "I2C-over-AUX"); |
238 | 0 | } else { |
239 | 0 | proto_tree_add_uint(tree, hf_dpaux_transaction_type, tvb, 0, 0, DPAUX_TRANSACTION_N_A); |
240 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "N/A"); |
241 | 0 | } |
242 | |
|
243 | 0 | switch (cmd) { |
244 | 0 | case DPAUX_REPLY_CODE_ACK: |
245 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "ACK"); |
246 | 0 | break; |
247 | 0 | case DPAUX_REPLY_CODE_NACK: |
248 | 0 | case DPAUX_REPLY_CODE_I2C_NACK: |
249 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "NACK"); |
250 | 0 | break; |
251 | 0 | case DPAUX_REPLY_CODE_DEFER: |
252 | 0 | case DPAUX_REPLY_CODE_I2C_DEFER: |
253 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "DEFER"); |
254 | 0 | break; |
255 | 0 | }; |
256 | |
|
257 | 0 | proto_tree_add_uint(tree, hf_dpaux_reply_cmd, tvb, 0, 1, cmd); |
258 | |
|
259 | 0 | if (len) { |
260 | 0 | if (transaction) { |
261 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, " with %u byte%s FROM 0x%05x", |
262 | 0 | len, len > 1 ? "s" : "", transaction->addr); |
263 | 0 | proto_tree_add_uint(tree, hf_dpaux_addr, tvb, 0, 3, transaction->addr); |
264 | 0 | } else { |
265 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, " with %u byte%s", len, |
266 | 0 | len > 1 ? "s" : ""); |
267 | 0 | } |
268 | | /* A reply has no length field, the length is that of the data */ |
269 | 0 | ti = proto_tree_add_uint(tree, hf_dpaux_len, tvb, 0, 0, len); |
270 | 0 | proto_item_set_generated(ti); |
271 | 0 | proto_tree_add_item(tree, hf_dpaux_data, tvb, 1, len, ENC_NA); |
272 | |
|
273 | 0 | if (transaction && transaction->is_native) { |
274 | 0 | unsigned int k; |
275 | |
|
276 | 0 | for (k = 0; k < len;) { |
277 | 0 | proto_tree *register_tree; |
278 | 0 | int res; |
279 | |
|
280 | 0 | ti = proto_tree_add_uint_format(tree, hf_dpaux_reg_addr, |
281 | 0 | tvb, k + 1, 1, |
282 | 0 | transaction->addr + k, |
283 | 0 | "DPCD 0x%05x: 0x%02x", |
284 | 0 | transaction->addr + k, |
285 | 0 | tvb_get_uint8(tvb, k + 1)); |
286 | 0 | register_tree = proto_item_add_subtree(ti, ett_register); |
287 | |
|
288 | 0 | res = dissect_dpaux_register(tvb, pinfo, register_tree, k + 1, |
289 | 0 | transaction->addr + k); |
290 | |
|
291 | 0 | k += (res > 0) ? res : 1; |
292 | 0 | } |
293 | 0 | } |
294 | 0 | } |
295 | |
|
296 | 0 | return 0; |
297 | 0 | } |
298 | | |
299 | | static int |
300 | | dissect_dpaux(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) |
301 | 0 | { |
302 | 0 | proto_item *ti; |
303 | 0 | proto_tree *dpaux_tree; |
304 | 0 | bool from_source = false; |
305 | 0 | struct dpaux_info *dpaux_info = (struct dpaux_info*)data; |
306 | |
|
307 | 0 | if (dpaux_info != NULL) |
308 | 0 | from_source = dpaux_info->from_source; |
309 | |
|
310 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "dpaux"); |
311 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "DisplayPort AUX channel"); |
312 | 0 | col_set_str(pinfo->cinfo, COL_RES_DL_DST, "N/A"); |
313 | |
|
314 | 0 | if (from_source) |
315 | 0 | col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "DP-Source"); |
316 | 0 | else |
317 | 0 | col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "DP-Sink"); |
318 | | |
319 | | /* create display subtree for the protocol */ |
320 | 0 | ti = proto_tree_add_item(tree, proto_dpaux, tvb, 0, -1, ENC_NA); |
321 | 0 | dpaux_tree = proto_item_add_subtree(ti, ett_dpaux); |
322 | |
|
323 | 0 | if (from_source) |
324 | 0 | dissect_dpaux_from_source(tvb, pinfo, dpaux_tree); |
325 | 0 | else |
326 | 0 | dissect_dpaux_from_sink(tvb, pinfo, dpaux_tree); |
327 | |
|
328 | 0 | return tvb_captured_length(tvb); |
329 | 0 | } |
330 | | |
331 | | /* Register the protocol with Wireshark. |
332 | | * |
333 | | * This format is required because a script is used to build the C function that |
334 | | * calls all the protocol registration. |
335 | | */ |
336 | | void |
337 | | proto_register_dpaux(void) |
338 | 16 | { |
339 | 16 | static const value_string convert_transaction_type[] = { |
340 | 16 | { DPAUX_TRANSACTION_NATIVE, "Native" }, |
341 | 16 | { DPAUX_TRANSACTION_I2C_OVER_AUX, "I2C-over-AUX" }, |
342 | 16 | { DPAUX_TRANSACTION_N_A, "N/A," }, |
343 | 16 | { 0, NULL } |
344 | 16 | }; |
345 | | |
346 | 16 | static const value_string convert_native_req_cmd[] = { |
347 | 16 | { 0, "Write" }, |
348 | 16 | { 1, "Read" }, |
349 | 16 | { 0, NULL } |
350 | 16 | }; |
351 | | |
352 | 16 | static const value_string convert_i2c_req_cmd[] = { |
353 | 16 | { 0, "Write" }, |
354 | 16 | { 1, "Read" }, |
355 | 16 | { 2, "Write_Status_Update_Request" }, |
356 | 16 | { 0, NULL } |
357 | 16 | }; |
358 | | |
359 | 16 | static const value_string convert_reply_cmd[] = { |
360 | 16 | { 0, "AUX ACK" }, |
361 | 16 | { 1, "AUX NACK" }, |
362 | 16 | { 2, "AUX DEFER" }, |
363 | 16 | { 1 << 2, "I2C NACK" }, |
364 | 16 | { 2 << 2, "I2C DEFER" }, |
365 | 16 | { 0, NULL } |
366 | 16 | }; |
367 | | |
368 | 16 | static const value_string convert_link_rate[] = { |
369 | 16 | { 0x06, "1.62Gbps/lane" }, |
370 | 16 | { 0x0a, "2.7Gbps/lane" }, |
371 | 16 | { 0x14, "5.4Gbps/lane" }, |
372 | 16 | { 0x1e, "8.1Gbps/lane" }, |
373 | 16 | { 0, NULL } |
374 | 16 | }; |
375 | | |
376 | 16 | static const value_string convert_downspread[] = { |
377 | 16 | { 0x00, "none" }, |
378 | 16 | { 0x01, "up to 0.5%" }, |
379 | 16 | { 0, NULL } |
380 | 16 | }; |
381 | | |
382 | 16 | static const value_string convert_norp[] = { |
383 | 16 | { 0x00, "One receiver port" }, |
384 | 16 | { 0x01, "Two or more receiver ports" }, |
385 | 16 | { 0, NULL } |
386 | 16 | }; |
387 | | |
388 | | /* Setup protocol subtree array */ |
389 | 16 | static int *ett[] = { |
390 | 16 | &ett_dpaux, |
391 | 16 | &ett_register, |
392 | 16 | }; |
393 | | |
394 | 16 | static hf_register_info hf[] = { |
395 | 16 | { &hf_dpaux_transaction_type, { "Transaction type", "dpaux.transaction_type", FT_UINT8, BASE_DEC, VALS(convert_transaction_type), 0, NULL, HFILL } }, |
396 | 16 | { &hf_dpaux_native_req_cmd, { "Native Request Command", "dpaux.native_req_cmd", FT_UINT8, BASE_DEC, VALS(convert_native_req_cmd), 0, NULL, HFILL } }, |
397 | 16 | { &hf_dpaux_i2c_req_cmd, { "I2C over AUX Request Command", "dpaux.native_i2c_req_cmd", FT_UINT8, BASE_DEC, VALS(convert_i2c_req_cmd), 0, NULL, HFILL } }, |
398 | 16 | { &hf_dpaux_reply_cmd, { "Reply Command", "dpaux.reply_cmd", FT_UINT8, BASE_DEC, VALS(convert_reply_cmd), 0, NULL, HFILL } }, |
399 | 16 | { &hf_dpaux_mot, { "MOT (Middle-of-Transaction)", "dpaux.mot", FT_BOOLEAN, BASE_NONE, NULL, 0, NULL, HFILL } }, |
400 | 16 | { &hf_dpaux_addr, { "Address", "dpaux.addr", FT_UINT24, BASE_HEX, NULL, 0, NULL, HFILL } }, |
401 | 16 | { &hf_dpaux_len, { "Data Length", "dpaux.len", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } }, |
402 | 16 | { &hf_dpaux_data, { "Data", "dpaux.data", FT_BYTES, SEP_SPACE, NULL, 0, NULL, HFILL } }, |
403 | 16 | { &hf_dpaux_reg_addr, { "DPCD", "dpaux.reg", FT_UINT24, BASE_HEX, NULL, 0, NULL, HFILL } }, |
404 | | |
405 | 16 | { &hf_00000, { "DPCD_REV", "dpaux.00000", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } }, |
406 | 16 | { &hf_00000_MINOR, { "MINOR", "dpaux.00000_MINOR", FT_UINT8, BASE_HEX, NULL, 0x0f, NULL, HFILL } }, |
407 | 16 | { &hf_00000_MAJOR, { "MAJOR", "dpaux.00000_MAJOR", FT_UINT8, BASE_HEX, NULL, 0xf0, NULL, HFILL } }, |
408 | | |
409 | 16 | { &hf_00001, { "MAX_LINK_RATE", "dpaux.00001", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } }, |
410 | 16 | { &hf_00001_MAX_LINK_RATE, { "MAX_LINK_RATE", "dpaux.00001_MAX_LINK_RATE", FT_UINT8, BASE_HEX, VALS(convert_link_rate), 0xff, NULL, HFILL } }, |
411 | | |
412 | 16 | { &hf_00002, { "MAX_LANE_COUNT", "dpaux.00002", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } }, |
413 | 16 | { &hf_00002_MAX_LANE_COUNT, { "MAX_LANE_COUNT", "dpaux.00002_MAX_LANE_COUNT", FT_UINT8, BASE_DEC, NULL, 0x0f, NULL, HFILL } }, |
414 | 16 | { &hf_00002_POST_LT_ADJ_REQ_SUPPORTED, { "POST_LT_ADJ_REQ_SUPPORTED", "dpaux.00002_POST_LT_ADJ_REQ_SUPPORTED", FT_BOOLEAN, 8, NULL, 1<<5, NULL, HFILL } }, |
415 | 16 | { &hf_00002_TPS3_SUPPORTED, { "TPS3_SUPPORTED", "dpaux.00002_TPS3_SUPPORTED", FT_BOOLEAN, 8, NULL, 1<<6, NULL, HFILL } }, |
416 | 16 | { &hf_00002_ENHANCED_FRAME_CAP, { "ENHANCED_FRAME_CAP", "dpaux.00002_ENHANCED_FRAME_CAP", FT_BOOLEAN, 8, NULL, 1<<7, NULL, HFILL } }, |
417 | | |
418 | 16 | { &hf_00003, { "MAX_DOWNSPREAD", "dpaux.00003", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } }, |
419 | 16 | { &hf_00003_MAX_DOWNSPREAD, { "MAX_DOWNSPREAD", "dpaux.00003_MAX_DOWNSPREAD", FT_UINT8, BASE_DEC, VALS(convert_downspread), 0x01, NULL, HFILL } }, |
420 | 16 | { &hf_00003_NO_AUX_TRANSACTION_LINK_TRAINING, { "NO_AUX_TRANSACTION_LINK_TRAINING", "dpaux.00003_NO_AUX_TRANSACTION_LINK_TRAINING", FT_BOOLEAN, 8, NULL, 1<<6, NULL, HFILL } }, |
421 | 16 | { &hf_00003_TPS4_SUPPORTED, { "TPS4_SUPPORTED", "dpaux.00003_TPS4_SUPPORTED", FT_BOOLEAN, 8, NULL, 1<<7, NULL, HFILL } }, |
422 | | |
423 | 16 | { &hf_00004, { "NORP & DP_PWR_VOLTAGE_CAP", "dpaux.00004", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } }, |
424 | 16 | { &hf_00004_NORP, { "NORP", "dpaux.00004_NORP", FT_UINT8, BASE_DEC, VALS(convert_norp), 0x01, NULL, HFILL } }, |
425 | 16 | { &hf_00004_5V_DP_PWR_CAP, { "5V_DP_PWR_CAP", "dpaux.00004_5V_DP_PWR_CAP", FT_BOOLEAN, 8, NULL, 1<<5, NULL, HFILL } }, |
426 | 16 | { &hf_00004_12V_DP_PWR_CAP, { "12V_DP_PWR_CAP", "dpaux.00004_12V_DP_PWR_CAP", FT_BOOLEAN, 8, NULL, 1<<6, NULL, HFILL } }, |
427 | 16 | { &hf_00004_18V_DP_PWR_CAP, { "18V_DP_PWR_CAP", "dpaux.00004_18V_DP_PWR_CAP", FT_BOOLEAN, 8, NULL, 1<<7, NULL, HFILL } }, |
428 | 16 | }; |
429 | | |
430 | | /* Register the protocol name and description */ |
431 | 16 | proto_dpaux = proto_register_protocol("DisplayPort AUX-Channel", "DPAUX", "dpaux"); |
432 | 16 | register_dissector("dpaux", dissect_dpaux, proto_dpaux); |
433 | | |
434 | 16 | proto_register_field_array(proto_dpaux, hf, array_length(hf)); |
435 | | proto_register_subtree_array(ett, array_length(ett)); |
436 | 16 | } |
437 | | |
438 | | |
439 | | /* |
440 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
441 | | * |
442 | | * Local variables: |
443 | | * c-basic-offset: 4 |
444 | | * tab-width: 8 |
445 | | * indent-tabs-mode: nil |
446 | | * End: |
447 | | * |
448 | | * vi: set shiftwidth=4 tabstop=8 expandtab: |
449 | | * :indentSize=4:tabSize=8:noTabs=true: |
450 | | */ |