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 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 errx(1, "TEST FAILED: failed to parse SFP wavelength " 53 "values: %s\n", strerror(ret)); 54 } 55 56 if ((ret = nvlist_lookup_string(nvl, LIBSFF_KEY_WAVELENGTH, &val)) != 57 0) { 58 errx(1, "TEST FAILED: failed to find %s: %s when " 59 "parsing key %d: %s\n", LIBSFF_KEY_WAVELENGTH, 60 strerror(ret)); 61 } 62 (void) printf("%s: %s\n", LIBSFF_KEY_WAVELENGTH, val); 63 nvlist_free(nvl); 64 65 /* 66 * Make sure wavelength is missing if we specify a copper compliance. 67 */ 68 bzero(buf, sizeof (buf)); 69 buf[SFF_8472_COMPLIANCE_SFP] = 0x08; 70 buf[SFF_8472_WAVELENGTH_HI] = 0x12; 71 buf[SFF_8472_WAVELENGTH_LOW] = 0x34; 72 73 if ((ret = libsff_parse(buf, sizeof (buf), 0xa0, &nvl)) != 0) { 74 errx(1, "TEST FAILED: failed to parse SFP wavelength " 75 "values: %s\n", strerror(ret)); 76 } 77 78 if ((ret = nvlist_lookup_string(nvl, LIBSFF_KEY_WAVELENGTH, &val)) != 79 ENOENT) { 80 errx(1, "TEST FALIED: found unexpected return value for key " 81 "%s: %d\n", LIBSFF_KEY_WAVELENGTH, ret); 82 } 83 84 nvlist_free(nvl); 85 86 bzero(buf, sizeof (buf)); 87 buf[SFF_8472_COMPLIANCE_SFP] = 0x04; 88 buf[SFF_8472_WAVELENGTH_HI] = 0x12; 89 buf[SFF_8472_WAVELENGTH_LOW] = 0x34; 90 91 if ((ret = libsff_parse(buf, sizeof (buf), 0xa0, &nvl)) != 0) { 92 errx(1, "TEST FAILED: failed to parse SFP wavelength " 93 "values: %s\n", strerror(ret)); 94 } 95 96 if ((ret = nvlist_lookup_string(nvl, LIBSFF_KEY_WAVELENGTH, &val)) != 97 ENOENT) { 98 errx(1, "TEST FALIED: found unexpected return value for key " 99 "%s: %d\n", LIBSFF_KEY_WAVELENGTH, ret); 100 } 101 102 nvlist_free(nvl); 103 104 /* 105 * Now for QSFP+ 106 */ 107 (void) puts("\n\nQSFP\n"); 108 109 /* First copper */ 110 bzero(buf, sizeof (buf)); 111 buf[SFF_8472_IDENTIFIER] = SFF_8024_ID_QSFP; 112 buf[SFF_8636_DEVICE_TECH] = 0xa0; 113 114 buf[SFF_8636_ATTENUATE_2G] = 0x42; 115 buf[SFF_8636_ATTENUATE_5G] = 0x43; 116 buf[SFF_8636_ATTENUATE_7G] = 0x44; 117 buf[SFF_8636_ATTENUATE_12G] = 0x45; 118 119 if ((ret = libsff_parse(buf, sizeof (buf), 0xa0, &nvl)) != 0) { 120 errx(1, "TEST FAILED: failed to parse QSFP BR " 121 "values: %s\n", strerror(ret)); 122 } 123 124 for (i = 0; attenuate[i] != NULL; i++) { 125 if ((ret = nvlist_lookup_string(nvl, attenuate[i], &val)) != 126 0) { 127 errx(1, "TEST FAILED: failed to find %s: %s when " 128 "parsing key %d: %s\n", attenuate[i], 129 strerror(ret)); 130 } 131 (void) printf("%s: %s\n", attenuate[i], val); 132 } 133 134 for (i = 0; wave[i] != NULL; i++) { 135 if ((ret = nvlist_lookup_string(nvl, wave[i], &val)) != 136 ENOENT) { 137 errx(1, "TEST FALIED: found unexpected return value " 138 "for key %s: %d\n", attenuate[i], ret); 139 } 140 141 } 142 nvlist_free(nvl); 143 144 /* Now normal wavelengths */ 145 bzero(buf, sizeof (buf)); 146 buf[SFF_8472_IDENTIFIER] = SFF_8024_ID_QSFP; 147 148 buf[SFF_8636_WAVELENGTH_NOMINAL_HI] = 0x12; 149 buf[SFF_8636_WAVELENGTH_NOMINAL_LOW] = 0x34; 150 buf[SFF_8636_WAVELENGTH_TOLERANCE_HI] = 0x56; 151 buf[SFF_8636_WAVELENGTH_TOLERANCE_LOW] = 0x78; 152 153 if ((ret = libsff_parse(buf, sizeof (buf), 0xa0, &nvl)) != 0) { 154 errx(1, "TEST FAILED: failed to parse QSFP Wavelength " 155 "values: %s\n", strerror(ret)); 156 } 157 158 for (i = 0; wave[i] != NULL; i++) { 159 if ((ret = nvlist_lookup_string(nvl, wave[i], &val)) != 0) { 160 errx(1, "TEST FAILED: failed to find %s: %s when " 161 "parsing key %d: %s\n", wave[i], strerror(ret)); 162 } 163 (void) printf("%s: %s\n", wave[i], val); 164 } 165 166 for (i = 0; attenuate[i] != NULL; i++) { 167 if ((ret = nvlist_lookup_string(nvl, attenuate[i], &val)) != 168 ENOENT) { 169 errx(1, "TEST FALIED: found unexpected return value " 170 "for key %s: %d\n", attenuate[i], ret); 171 } 172 173 } 174 nvlist_free(nvl); 175 176 return (0); 177 } 178