1/*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source.  A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12/*
13 * Copyright (c) 2017, Joyent, Inc.
14 */
15
16/*
17 * Print and tests SFF compliance values.
18 */
19
20#include <stdio.h>
21#include <errno.h>
22#include <strings.h>
23#include <err.h>
24#include <libsff.h>
25
26/*
27 * Pick up private sff header file with offsets from lib/libsff.
28 */
29#include "sff.h"
30
31static void
32lsc_print_array(nvlist_t *nvl, const char *key)
33{
34	int ret;
35	uint_t i, count;
36	char **vals;
37
38	if ((ret = nvlist_lookup_string_array(nvl, key, &vals, &count)) != 0) {
39		errx(1, "TEST FAILED failed to find key %s: %s\n", key,
40		    strerror(ret));
41	}
42
43	(void) puts(key);
44	for (i = 0; i < count; i++) {
45		(void) printf("\t%d\t%s\n", i, vals[i]);
46	}
47}
48
49int
50main(void)
51{
52	int ret;
53	uint8_t buf[256];
54	nvlist_t *nvl;
55
56	/*
57	 * Set every shared bit for compliance then print them all out. Note we
58	 * include reserved bits so that way if someone ends up adding something
59	 * to one of the reserved fields, we end up printing it.
60	 */
61	bzero(buf, sizeof (buf));
62	buf[SFF_8472_COMPLIANCE_10GE] = 0xff;
63	buf[SFF_8472_COMPLIANCE_SONET_LOW] = 0xff;
64	buf[SFF_8472_COMPLIANCE_SONET_HIGH] = 0xff;
65	buf[SFF_8472_COMPLIANCE_ETHERNET] = 0xff;
66	buf[SFF_8472_COMPLIANCE_FC_LOW] = 0xff;
67	buf[SFF_8472_COMPLIANCE_FC_HIGH] = 0xff;
68	buf[SFF_8472_COMPLIANCE_FC_MEDIA] = 0xff;
69	buf[SFF_8472_COMPLIANCE_FC_SPEED] = 0xff;
70
71	if ((ret = libsff_parse(buf, sizeof (buf), 0xa0, &nvl)) != 0) {
72		errx(1, "TEST FAILED: failed to parse SFP compliance "
73		    "values: %s\n", strerror(ret));
74	}
75
76	lsc_print_array(nvl, LIBSFF_KEY_COMPLIANCE_10GBE);
77	lsc_print_array(nvl, LIBSFF_KEY_COMPLIANCE_IB);
78	lsc_print_array(nvl, LIBSFF_KEY_COMPLIANCE_ESCON);
79	lsc_print_array(nvl, LIBSFF_KEY_COMPLIANCE_SONET);
80	lsc_print_array(nvl, LIBSFF_KEY_COMPLIANCE_GBE);
81	lsc_print_array(nvl, LIBSFF_KEY_COMPLIANCE_FC_LEN);
82	lsc_print_array(nvl, LIBSFF_KEY_COMPLIANCE_FC_TECH);
83	lsc_print_array(nvl, LIBSFF_KEY_COMPLIANCE_SFP);
84	lsc_print_array(nvl, LIBSFF_KEY_COMPLIANCE_FC_MEDIA);
85	lsc_print_array(nvl, LIBSFF_KEY_COMPLIANCE_FC_SPEED);
86
87	nvlist_free(nvl);
88
89	/*
90	 * Now for QSFP+
91	 */
92	(void) puts("\n\nQSFP\n");
93	bzero(buf, sizeof (buf));
94	buf[SFF_8472_IDENTIFIER] = SFF_8024_ID_QSFP;
95	buf[SFF_8636_COMPLIANCE_10GBEP] = 0xff;
96	buf[SFF_8636_COMPLIANCE_SONET] = 0xff;
97	buf[SFF_8636_COMPLIANCE_SAS] = 0xff;
98	buf[SFF_8636_COMPLIANCE_ETHERNET] = 0xff;
99	buf[SFF_8636_COMPLIANCE_FCLEN] = 0xff;
100	buf[SFF_8636_COMPLIANCE_FC_LOW] = 0xff;
101	buf[SFF_8636_COMPLIANCE_FC_HIGH] = 0xff;
102	buf[SFF_8636_COMPLIANCE_FC_MEDIA] = 0xff;
103	buf[SFF_8636_COMPLIANCE_FC_SPEED] = 0xff;
104	buf[SFF_8636_EXTENDED_MODULE] = 0xff;
105
106	if ((ret = libsff_parse(buf, sizeof (buf), 0xa0, &nvl)) != 0) {
107		errx(1, "TEST FAILED: failed to parse QSFP compliance "
108		    "values: %s\n", strerror(ret));
109	}
110
111	lsc_print_array(nvl, LIBSFF_KEY_COMPLIANCE_10GBE);
112	lsc_print_array(nvl, LIBSFF_KEY_COMPLIANCE_SONET);
113	lsc_print_array(nvl, LIBSFF_KEY_COMPLIANCE_SAS);
114	lsc_print_array(nvl, LIBSFF_KEY_COMPLIANCE_GBE);
115	lsc_print_array(nvl, LIBSFF_KEY_COMPLIANCE_FC_LEN);
116	lsc_print_array(nvl, LIBSFF_KEY_COMPLIANCE_FC_TECH);
117	lsc_print_array(nvl, LIBSFF_KEY_COMPLIANCE_FC_MEDIA);
118	lsc_print_array(nvl, LIBSFF_KEY_COMPLIANCE_FC_SPEED);
119	lsc_print_array(nvl, LIBSFF_KEY_EXT_MOD_CODES);
120
121	nvlist_free(nvl);
122
123	return (0);
124}
125