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 Wavelength values. Note that in both SFF 8472 and SFF
18 * 8636 the wavelength values also double for various copper complaince values.
19 * We check both forms here. Note that the copper compliance in SFF 8472 is
20 * currently tested in libsff_compliance.c. SFF 8636's Copper Attenuation values
21 * are tested here.
22 */
23
24 #include <stdio.h>
25 #include <errno.h>
26 #include <strings.h>
27 #include <err.h>
28 #include <libsff.h>
29
30 /*
31 * Pick up private sff header file with offsets from lib/libsff.
32 */
33 #include "sff.h"
34
35 int
main(void)36 main(void)
37 {
38 int ret, i;
39 uint8_t buf[256];
40 nvlist_t *nvl;
41 char *val;
42 char *attenuate[] = { LIBSFF_KEY_ATTENUATE_2G, LIBSFF_KEY_ATTENUATE_5G,
43 LIBSFF_KEY_ATTENUATE_7G, LIBSFF_KEY_ATTENUATE_12G, NULL };
44 char *wave[] = { LIBSFF_KEY_WAVELENGTH, LIBSFF_KEY_WAVE_TOLERANCE,
45 NULL };
46
47 bzero(buf, sizeof (buf));
48 buf[SFF_8472_WAVELENGTH_HI] = 0x12;
49 buf[SFF_8472_WAVELENGTH_LOW] = 0x34;
50
51 if ((ret = libsff_parse(buf, sizeof (buf), 0xa0, &nvl)) != 0) {
52 errc(1, ret, "TEST FAILED: failed to parse SFP wavelength "
53 "values");
54 }
55
56 if ((ret = nvlist_lookup_string(nvl, LIBSFF_KEY_WAVELENGTH, &val)) !=
57 0) {
58 errc(1, ret, "TEST FAILED: failed to find %s",
59 LIBSFF_KEY_WAVELENGTH);
60 }
61 (void) printf("%s: %s\n", LIBSFF_KEY_WAVELENGTH, val);
62 nvlist_free(nvl);
63
64 /*
65 * Make sure wavelength is missing if we specify a copper compliance.
66 */
67 bzero(buf, sizeof (buf));
68 buf[SFF_8472_COMPLIANCE_SFP] = 0x08;
69 buf[SFF_8472_WAVELENGTH_HI] = 0x12;
70 buf[SFF_8472_WAVELENGTH_LOW] = 0x34;
71
72 if ((ret = libsff_parse(buf, sizeof (buf), 0xa0, &nvl)) != 0) {
73 errc(1, ret, "TEST FAILED: failed to parse SFP wavelength "
74 "values");
75 }
76
77 if ((ret = nvlist_lookup_string(nvl, LIBSFF_KEY_WAVELENGTH, &val)) !=
78 ENOENT) {
79 errx(1, "TEST FALIED: found unexpected return value for key "
80 "%s: %d", LIBSFF_KEY_WAVELENGTH, ret);
81 }
82
83 nvlist_free(nvl);
84
85 bzero(buf, sizeof (buf));
86 buf[SFF_8472_COMPLIANCE_SFP] = 0x04;
87 buf[SFF_8472_WAVELENGTH_HI] = 0x12;
88 buf[SFF_8472_WAVELENGTH_LOW] = 0x34;
89
90 if ((ret = libsff_parse(buf, sizeof (buf), 0xa0, &nvl)) != 0) {
91 errc(1, ret, "TEST FAILED: failed to parse SFP wavelength "
92 "values");
93 }
94
95 if ((ret = nvlist_lookup_string(nvl, LIBSFF_KEY_WAVELENGTH, &val)) !=
96 ENOENT) {
97 errx(1, "TEST FALIED: found unexpected return value for key "
98 "%s: %d", LIBSFF_KEY_WAVELENGTH, ret);
99 }
100
101 nvlist_free(nvl);
102
103 /*
104 * Now for QSFP+
105 */
106 (void) puts("\n\nQSFP\n");
107
108 /* First copper */
109 bzero(buf, sizeof (buf));
110 buf[SFF_8472_IDENTIFIER] = SFF_8024_ID_QSFP;
111 buf[SFF_8636_DEVICE_TECH] = 0xa0;
112
113 buf[SFF_8636_ATTENUATE_2G] = 0x42;
114 buf[SFF_8636_ATTENUATE_5G] = 0x43;
115 buf[SFF_8636_ATTENUATE_7G] = 0x44;
116 buf[SFF_8636_ATTENUATE_12G] = 0x45;
117
118 if ((ret = libsff_parse(buf, sizeof (buf), 0xa0, &nvl)) != 0) {
119 errc(1, ret, "TEST FAILED: failed to parse QSFP BR "
120 "values");
121 }
122
123 for (i = 0; attenuate[i] != NULL; i++) {
124 if ((ret = nvlist_lookup_string(nvl, attenuate[i], &val)) !=
125 0) {
126 errc(1, ret, "TEST FAILED: failed to find %s",
127 attenuate[i]);
128 }
129 (void) printf("%s: %s\n", attenuate[i], val);
130 }
131
132 for (i = 0; wave[i] != NULL; i++) {
133 if ((ret = nvlist_lookup_string(nvl, wave[i], &val)) !=
134 ENOENT) {
135 errx(1, "TEST FAILED: found unexpected return value "
136 "for key %s: %d", attenuate[i], ret);
137 }
138
139 }
140 nvlist_free(nvl);
141
142 /* Now normal wavelengths */
143 bzero(buf, sizeof (buf));
144 buf[SFF_8472_IDENTIFIER] = SFF_8024_ID_QSFP;
145
146 buf[SFF_8636_WAVELENGTH_NOMINAL_HI] = 0x12;
147 buf[SFF_8636_WAVELENGTH_NOMINAL_LOW] = 0x34;
148 buf[SFF_8636_WAVELENGTH_TOLERANCE_HI] = 0x56;
149 buf[SFF_8636_WAVELENGTH_TOLERANCE_LOW] = 0x78;
150
151 if ((ret = libsff_parse(buf, sizeof (buf), 0xa0, &nvl)) != 0) {
152 errc(1, ret, "TEST FAILED: failed to parse QSFP Wavelength "
153 "values");
154 }
155
156 for (i = 0; wave[i] != NULL; i++) {
157 if ((ret = nvlist_lookup_string(nvl, wave[i], &val)) != 0) {
158 errc(1, ret, "TEST FAILED: failed to find %s", wave[i]);
159 }
160 (void) printf("%s: %s\n", wave[i], val);
161 }
162
163 for (i = 0; attenuate[i] != NULL; i++) {
164 if ((ret = nvlist_lookup_string(nvl, attenuate[i], &val)) !=
165 ENOENT) {
166 errx(1, "TEST FALIED: found unexpected return value "
167 "for key %s: %d", attenuate[i], ret);
168 }
169
170 }
171 nvlist_free(nvl);
172
173 return (0);
174 }
175