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 BR 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
31int
32main(void)
33{
34	int ret;
35	uint8_t buf[256];
36	nvlist_t *nvl;
37	char *val;
38
39	/*
40	 * SFF 8472 has two different modes of printing the bit rate. It has a
41	 * nominal bit rate and then if 0xff is in that field it has a max and
42	 * min.
43	 */
44	bzero(buf, sizeof (buf));
45	buf[SFF_8472_BR_NOMINAL] = 0x42;
46
47	if ((ret = libsff_parse(buf, sizeof (buf), 0xa0, &nvl)) != 0) {
48		errx(1, "TEST FAILED: failed to parse SFP compliance "
49		    "values: %s\n", strerror(ret));
50	}
51
52	if ((ret = nvlist_lookup_string(nvl, LIBSFF_KEY_BR_NOMINAL, &val)) !=
53	    0) {
54		errx(1, "TEST FAILED: failed to find %s: %s when "
55		    "parsing key %d: %s\n", LIBSFF_KEY_BR_NOMINAL,
56		    strerror(ret));
57	}
58	(void) printf("nominal: %s\n", val);
59
60	/*
61	 * Make sure min, max are missing.
62	 */
63	if ((ret = nvlist_lookup_string(nvl, LIBSFF_KEY_BR_MIN, &val)) !=
64	    ENOENT) {
65		errx(1, "TEST FALIED: found unexpected return value for key "
66		    "%s: %d\n", LIBSFF_KEY_BR_MIN, ret);
67	}
68
69	if ((ret = nvlist_lookup_string(nvl, LIBSFF_KEY_BR_MAX, &val)) !=
70	    ENOENT) {
71		errx(1, "TEST FALIED: found unexpected return value for key "
72		    "%s: %d\n", LIBSFF_KEY_BR_MAX, ret);
73	}
74	nvlist_free(nvl);
75
76	/*
77	 * Now the opposite.
78	 */
79	buf[SFF_8472_BR_NOMINAL] = 0xff;
80	buf[SFF_8472_BR_MAX] = 0x50;
81	buf[SFF_8472_BR_MIN] = 0x10;
82
83	if ((ret = libsff_parse(buf, sizeof (buf), 0xa0, &nvl)) != 0) {
84		errx(1, "TEST FAILED: failed to parse SFP compliance "
85		    "values: %s\n", strerror(ret));
86	}
87
88	if ((ret = nvlist_lookup_string(nvl, LIBSFF_KEY_BR_MAX, &val)) != 0) {
89		errx(1, "TEST FAILED: failed to find %s: %s when "
90		    "parsing key %d: %s\n", LIBSFF_KEY_BR_MAX,
91		    strerror(ret));
92	}
93	(void) printf("max: %s\n", val);
94
95	if ((ret = nvlist_lookup_string(nvl, LIBSFF_KEY_BR_MIN, &val)) != 0) {
96		errx(1, "TEST FAILED: failed to find %s: %s when "
97		    "parsing key %d: %s\n", LIBSFF_KEY_BR_MIN,
98		    strerror(ret));
99	}
100	(void) printf("min: %s\n", val);
101
102	if ((ret = nvlist_lookup_string(nvl, LIBSFF_KEY_BR_NOMINAL, &val)) !=
103	    ENOENT) {
104		errx(1, "TEST FALIED: found unexpected return value for key "
105		    "%s: %d\n", LIBSFF_KEY_BR_NOMINAL, ret);
106	}
107	nvlist_free(nvl);
108
109	/*
110	 * Now for QSFP+
111	 */
112	(void) puts("\n\nQSFP\n");
113	bzero(buf, sizeof (buf));
114	buf[SFF_8472_IDENTIFIER] = SFF_8024_ID_QSFP;
115	buf[SFF_8636_BR_NOMINAL] = 0x42;
116
117	if ((ret = libsff_parse(buf, sizeof (buf), 0xa0, &nvl)) != 0) {
118		errx(1, "TEST FAILED: failed to parse QSFP BR "
119		    "values: %s\n", strerror(ret));
120	}
121
122	if ((ret = nvlist_lookup_string(nvl, LIBSFF_KEY_BR_NOMINAL,
123	    &val)) != 0) {
124		errx(1, "TEST FAILED: failed to find %s: %s when "
125		    "parsing key %d: %s\n", LIBSFF_KEY_BR_NOMINAL,
126		    strerror(ret));
127	}
128	(void) printf("nominal: %s\n", val);
129
130	nvlist_free(nvl);
131
132	return (0);
133}
134