145d3dd98SRobert Mustacchi /*
245d3dd98SRobert Mustacchi * This file and its contents are supplied under the terms of the
345d3dd98SRobert Mustacchi * Common Development and Distribution License ("CDDL"), version 1.0.
445d3dd98SRobert Mustacchi * You may only use this file in accordance with the terms of version
545d3dd98SRobert Mustacchi * 1.0 of the CDDL.
645d3dd98SRobert Mustacchi *
745d3dd98SRobert Mustacchi * A full copy of the text of the CDDL should have accompanied this
845d3dd98SRobert Mustacchi * source. A copy of the CDDL is also available via the Internet at
945d3dd98SRobert Mustacchi * http://www.illumos.org/license/CDDL.
1045d3dd98SRobert Mustacchi */
1145d3dd98SRobert Mustacchi
1245d3dd98SRobert Mustacchi /*
1345d3dd98SRobert Mustacchi * Copyright (c) 2017, Joyent, Inc.
1445d3dd98SRobert Mustacchi */
1545d3dd98SRobert Mustacchi
1645d3dd98SRobert Mustacchi /*
1745d3dd98SRobert Mustacchi * Print and tests SFF Wavelength values. Note that in both SFF 8472 and SFF
1845d3dd98SRobert Mustacchi * 8636 the wavelength values also double for various copper complaince values.
1945d3dd98SRobert Mustacchi * We check both forms here. Note that the copper compliance in SFF 8472 is
2045d3dd98SRobert Mustacchi * currently tested in libsff_compliance.c. SFF 8636's Copper Attenuation values
2145d3dd98SRobert Mustacchi * are tested here.
2245d3dd98SRobert Mustacchi */
2345d3dd98SRobert Mustacchi
2445d3dd98SRobert Mustacchi #include <stdio.h>
2545d3dd98SRobert Mustacchi #include <errno.h>
2645d3dd98SRobert Mustacchi #include <strings.h>
2745d3dd98SRobert Mustacchi #include <err.h>
2845d3dd98SRobert Mustacchi #include <libsff.h>
2945d3dd98SRobert Mustacchi
3045d3dd98SRobert Mustacchi /*
3145d3dd98SRobert Mustacchi * Pick up private sff header file with offsets from lib/libsff.
3245d3dd98SRobert Mustacchi */
3345d3dd98SRobert Mustacchi #include "sff.h"
3445d3dd98SRobert Mustacchi
3545d3dd98SRobert Mustacchi int
main(void)3645d3dd98SRobert Mustacchi main(void)
3745d3dd98SRobert Mustacchi {
3845d3dd98SRobert Mustacchi int ret, i;
3945d3dd98SRobert Mustacchi uint8_t buf[256];
4045d3dd98SRobert Mustacchi nvlist_t *nvl;
4145d3dd98SRobert Mustacchi char *val;
4245d3dd98SRobert Mustacchi char *attenuate[] = { LIBSFF_KEY_ATTENUATE_2G, LIBSFF_KEY_ATTENUATE_5G,
4345d3dd98SRobert Mustacchi LIBSFF_KEY_ATTENUATE_7G, LIBSFF_KEY_ATTENUATE_12G, NULL };
4445d3dd98SRobert Mustacchi char *wave[] = { LIBSFF_KEY_WAVELENGTH, LIBSFF_KEY_WAVE_TOLERANCE,
4545d3dd98SRobert Mustacchi NULL };
4645d3dd98SRobert Mustacchi
4745d3dd98SRobert Mustacchi bzero(buf, sizeof (buf));
4845d3dd98SRobert Mustacchi buf[SFF_8472_WAVELENGTH_HI] = 0x12;
4945d3dd98SRobert Mustacchi buf[SFF_8472_WAVELENGTH_LOW] = 0x34;
5045d3dd98SRobert Mustacchi
5145d3dd98SRobert Mustacchi if ((ret = libsff_parse(buf, sizeof (buf), 0xa0, &nvl)) != 0) {
52*8d195583SRobert Mustacchi errc(1, ret, "TEST FAILED: failed to parse SFP wavelength "
53*8d195583SRobert Mustacchi "values");
5445d3dd98SRobert Mustacchi }
5545d3dd98SRobert Mustacchi
5645d3dd98SRobert Mustacchi if ((ret = nvlist_lookup_string(nvl, LIBSFF_KEY_WAVELENGTH, &val)) !=
5745d3dd98SRobert Mustacchi 0) {
58*8d195583SRobert Mustacchi errc(1, ret, "TEST FAILED: failed to find %s",
59*8d195583SRobert Mustacchi LIBSFF_KEY_WAVELENGTH);
6045d3dd98SRobert Mustacchi }
6145d3dd98SRobert Mustacchi (void) printf("%s: %s\n", LIBSFF_KEY_WAVELENGTH, val);
6245d3dd98SRobert Mustacchi nvlist_free(nvl);
6345d3dd98SRobert Mustacchi
6445d3dd98SRobert Mustacchi /*
6545d3dd98SRobert Mustacchi * Make sure wavelength is missing if we specify a copper compliance.
6645d3dd98SRobert Mustacchi */
6745d3dd98SRobert Mustacchi bzero(buf, sizeof (buf));
6845d3dd98SRobert Mustacchi buf[SFF_8472_COMPLIANCE_SFP] = 0x08;
6945d3dd98SRobert Mustacchi buf[SFF_8472_WAVELENGTH_HI] = 0x12;
7045d3dd98SRobert Mustacchi buf[SFF_8472_WAVELENGTH_LOW] = 0x34;
7145d3dd98SRobert Mustacchi
7245d3dd98SRobert Mustacchi if ((ret = libsff_parse(buf, sizeof (buf), 0xa0, &nvl)) != 0) {
73*8d195583SRobert Mustacchi errc(1, ret, "TEST FAILED: failed to parse SFP wavelength "
74*8d195583SRobert Mustacchi "values");
7545d3dd98SRobert Mustacchi }
7645d3dd98SRobert Mustacchi
7745d3dd98SRobert Mustacchi if ((ret = nvlist_lookup_string(nvl, LIBSFF_KEY_WAVELENGTH, &val)) !=
7845d3dd98SRobert Mustacchi ENOENT) {
7945d3dd98SRobert Mustacchi errx(1, "TEST FALIED: found unexpected return value for key "
80*8d195583SRobert Mustacchi "%s: %d", LIBSFF_KEY_WAVELENGTH, ret);
8145d3dd98SRobert Mustacchi }
8245d3dd98SRobert Mustacchi
8345d3dd98SRobert Mustacchi nvlist_free(nvl);
8445d3dd98SRobert Mustacchi
8545d3dd98SRobert Mustacchi bzero(buf, sizeof (buf));
8645d3dd98SRobert Mustacchi buf[SFF_8472_COMPLIANCE_SFP] = 0x04;
8745d3dd98SRobert Mustacchi buf[SFF_8472_WAVELENGTH_HI] = 0x12;
8845d3dd98SRobert Mustacchi buf[SFF_8472_WAVELENGTH_LOW] = 0x34;
8945d3dd98SRobert Mustacchi
9045d3dd98SRobert Mustacchi if ((ret = libsff_parse(buf, sizeof (buf), 0xa0, &nvl)) != 0) {
91*8d195583SRobert Mustacchi errc(1, ret, "TEST FAILED: failed to parse SFP wavelength "
92*8d195583SRobert Mustacchi "values");
9345d3dd98SRobert Mustacchi }
9445d3dd98SRobert Mustacchi
9545d3dd98SRobert Mustacchi if ((ret = nvlist_lookup_string(nvl, LIBSFF_KEY_WAVELENGTH, &val)) !=
9645d3dd98SRobert Mustacchi ENOENT) {
9745d3dd98SRobert Mustacchi errx(1, "TEST FALIED: found unexpected return value for key "
98*8d195583SRobert Mustacchi "%s: %d", LIBSFF_KEY_WAVELENGTH, ret);
9945d3dd98SRobert Mustacchi }
10045d3dd98SRobert Mustacchi
10145d3dd98SRobert Mustacchi nvlist_free(nvl);
10245d3dd98SRobert Mustacchi
10345d3dd98SRobert Mustacchi /*
10445d3dd98SRobert Mustacchi * Now for QSFP+
10545d3dd98SRobert Mustacchi */
10645d3dd98SRobert Mustacchi (void) puts("\n\nQSFP\n");
10745d3dd98SRobert Mustacchi
10845d3dd98SRobert Mustacchi /* First copper */
10945d3dd98SRobert Mustacchi bzero(buf, sizeof (buf));
11045d3dd98SRobert Mustacchi buf[SFF_8472_IDENTIFIER] = SFF_8024_ID_QSFP;
11145d3dd98SRobert Mustacchi buf[SFF_8636_DEVICE_TECH] = 0xa0;
11245d3dd98SRobert Mustacchi
11345d3dd98SRobert Mustacchi buf[SFF_8636_ATTENUATE_2G] = 0x42;
11445d3dd98SRobert Mustacchi buf[SFF_8636_ATTENUATE_5G] = 0x43;
11545d3dd98SRobert Mustacchi buf[SFF_8636_ATTENUATE_7G] = 0x44;
11645d3dd98SRobert Mustacchi buf[SFF_8636_ATTENUATE_12G] = 0x45;
11745d3dd98SRobert Mustacchi
11845d3dd98SRobert Mustacchi if ((ret = libsff_parse(buf, sizeof (buf), 0xa0, &nvl)) != 0) {
119*8d195583SRobert Mustacchi errc(1, ret, "TEST FAILED: failed to parse QSFP BR "
120*8d195583SRobert Mustacchi "values");
12145d3dd98SRobert Mustacchi }
12245d3dd98SRobert Mustacchi
12345d3dd98SRobert Mustacchi for (i = 0; attenuate[i] != NULL; i++) {
12445d3dd98SRobert Mustacchi if ((ret = nvlist_lookup_string(nvl, attenuate[i], &val)) !=
12545d3dd98SRobert Mustacchi 0) {
126*8d195583SRobert Mustacchi errc(1, ret, "TEST FAILED: failed to find %s",
127*8d195583SRobert Mustacchi attenuate[i]);
12845d3dd98SRobert Mustacchi }
12945d3dd98SRobert Mustacchi (void) printf("%s: %s\n", attenuate[i], val);
13045d3dd98SRobert Mustacchi }
13145d3dd98SRobert Mustacchi
13245d3dd98SRobert Mustacchi for (i = 0; wave[i] != NULL; i++) {
13345d3dd98SRobert Mustacchi if ((ret = nvlist_lookup_string(nvl, wave[i], &val)) !=
13445d3dd98SRobert Mustacchi ENOENT) {
135*8d195583SRobert Mustacchi errx(1, "TEST FAILED: found unexpected return value "
136*8d195583SRobert Mustacchi "for key %s: %d", attenuate[i], ret);
13745d3dd98SRobert Mustacchi }
13845d3dd98SRobert Mustacchi
13945d3dd98SRobert Mustacchi }
14045d3dd98SRobert Mustacchi nvlist_free(nvl);
14145d3dd98SRobert Mustacchi
14245d3dd98SRobert Mustacchi /* Now normal wavelengths */
14345d3dd98SRobert Mustacchi bzero(buf, sizeof (buf));
14445d3dd98SRobert Mustacchi buf[SFF_8472_IDENTIFIER] = SFF_8024_ID_QSFP;
14545d3dd98SRobert Mustacchi
14645d3dd98SRobert Mustacchi buf[SFF_8636_WAVELENGTH_NOMINAL_HI] = 0x12;
14745d3dd98SRobert Mustacchi buf[SFF_8636_WAVELENGTH_NOMINAL_LOW] = 0x34;
14845d3dd98SRobert Mustacchi buf[SFF_8636_WAVELENGTH_TOLERANCE_HI] = 0x56;
14945d3dd98SRobert Mustacchi buf[SFF_8636_WAVELENGTH_TOLERANCE_LOW] = 0x78;
15045d3dd98SRobert Mustacchi
15145d3dd98SRobert Mustacchi if ((ret = libsff_parse(buf, sizeof (buf), 0xa0, &nvl)) != 0) {
152*8d195583SRobert Mustacchi errc(1, ret, "TEST FAILED: failed to parse QSFP Wavelength "
153*8d195583SRobert Mustacchi "values");
15445d3dd98SRobert Mustacchi }
15545d3dd98SRobert Mustacchi
15645d3dd98SRobert Mustacchi for (i = 0; wave[i] != NULL; i++) {
15745d3dd98SRobert Mustacchi if ((ret = nvlist_lookup_string(nvl, wave[i], &val)) != 0) {
158*8d195583SRobert Mustacchi errc(1, ret, "TEST FAILED: failed to find %s", wave[i]);
15945d3dd98SRobert Mustacchi }
16045d3dd98SRobert Mustacchi (void) printf("%s: %s\n", wave[i], val);
16145d3dd98SRobert Mustacchi }
16245d3dd98SRobert Mustacchi
16345d3dd98SRobert Mustacchi for (i = 0; attenuate[i] != NULL; i++) {
16445d3dd98SRobert Mustacchi if ((ret = nvlist_lookup_string(nvl, attenuate[i], &val)) !=
16545d3dd98SRobert Mustacchi ENOENT) {
16645d3dd98SRobert Mustacchi errx(1, "TEST FALIED: found unexpected return value "
167*8d195583SRobert Mustacchi "for key %s: %d", attenuate[i], ret);
16845d3dd98SRobert Mustacchi }
16945d3dd98SRobert Mustacchi
17045d3dd98SRobert Mustacchi }
17145d3dd98SRobert Mustacchi nvlist_free(nvl);
17245d3dd98SRobert Mustacchi
17345d3dd98SRobert Mustacchi return (0);
17445d3dd98SRobert Mustacchi }
175