xref: /illumos-gate/usr/src/lib/fm/topo/modules/common/shared/topo_transceiver.c (revision 45d3dd981abb9025d8ac994cf4cc8ce8cb1a9480)
1*45d3dd98SRobert Mustacchi /*
2*45d3dd98SRobert Mustacchi  * This file and its contents are supplied under the terms of the
3*45d3dd98SRobert Mustacchi  * Common Development and Distribution License ("CDDL"), version 1.0.
4*45d3dd98SRobert Mustacchi  * You may only use this file in accordance with the terms of version
5*45d3dd98SRobert Mustacchi  * 1.0 of the CDDL.
6*45d3dd98SRobert Mustacchi  *
7*45d3dd98SRobert Mustacchi  * A full copy of the text of the CDDL should have accompanied this
8*45d3dd98SRobert Mustacchi  * source.  A copy of the CDDL is also available via the Internet at
9*45d3dd98SRobert Mustacchi  * http://www.illumos.org/license/CDDL.
10*45d3dd98SRobert Mustacchi  */
11*45d3dd98SRobert Mustacchi 
12*45d3dd98SRobert Mustacchi /*
13*45d3dd98SRobert Mustacchi  * Copyright (c) 2017, Joyent, Inc.
14*45d3dd98SRobert Mustacchi  */
15*45d3dd98SRobert Mustacchi 
16*45d3dd98SRobert Mustacchi #include <sys/fm/protocol.h>
17*45d3dd98SRobert Mustacchi #include <fm/topo_mod.h>
18*45d3dd98SRobert Mustacchi #include <fm/topo_list.h>
19*45d3dd98SRobert Mustacchi #include <fm/topo_method.h>
20*45d3dd98SRobert Mustacchi 
21*45d3dd98SRobert Mustacchi /*
22*45d3dd98SRobert Mustacchi  * Common routines to create transceiver entries in the topology tree.
23*45d3dd98SRobert Mustacchi  */
24*45d3dd98SRobert Mustacchi 
25*45d3dd98SRobert Mustacchi static const topo_pgroup_info_t transceiver_pgroup = {
26*45d3dd98SRobert Mustacchi 	TOPO_PGROUP_TRANSCEIVER,
27*45d3dd98SRobert Mustacchi 	TOPO_STABILITY_PRIVATE,
28*45d3dd98SRobert Mustacchi 	TOPO_STABILITY_PRIVATE,
29*45d3dd98SRobert Mustacchi 	1
30*45d3dd98SRobert Mustacchi };
31*45d3dd98SRobert Mustacchi 
32*45d3dd98SRobert Mustacchi static const topo_pgroup_info_t sff_transceiver_pgroup = {
33*45d3dd98SRobert Mustacchi 	TOPO_PGROUP_SFF_TRANSCEIVER,
34*45d3dd98SRobert Mustacchi 	TOPO_STABILITY_PRIVATE,
35*45d3dd98SRobert Mustacchi 	TOPO_STABILITY_PRIVATE,
36*45d3dd98SRobert Mustacchi 	1
37*45d3dd98SRobert Mustacchi };
38*45d3dd98SRobert Mustacchi 
39*45d3dd98SRobert Mustacchi int
40*45d3dd98SRobert Mustacchi transceiver_range_create(topo_mod_t *mod, tnode_t *pnode, topo_instance_t min,
41*45d3dd98SRobert Mustacchi     topo_instance_t max)
42*45d3dd98SRobert Mustacchi {
43*45d3dd98SRobert Mustacchi 	return (topo_node_range_create(mod, pnode, TRANSCEIVER, min, max));
44*45d3dd98SRobert Mustacchi }
45*45d3dd98SRobert Mustacchi 
46*45d3dd98SRobert Mustacchi static tnode_t *
47*45d3dd98SRobert Mustacchi transceiver_create_common(topo_mod_t *mod, tnode_t *pnode, topo_instance_t inst,
48*45d3dd98SRobert Mustacchi     const char *type, boolean_t usable, const char *part, const char *rev,
49*45d3dd98SRobert Mustacchi     const char *serial)
50*45d3dd98SRobert Mustacchi {
51*45d3dd98SRobert Mustacchi 	int err;
52*45d3dd98SRobert Mustacchi 	tnode_t *tn = NULL;
53*45d3dd98SRobert Mustacchi 	nvlist_t *fmri = NULL, *auth = NULL;
54*45d3dd98SRobert Mustacchi 
55*45d3dd98SRobert Mustacchi 	if (type == NULL) {
56*45d3dd98SRobert Mustacchi 		topo_mod_dprintf(mod, "transceiver_create_common missing type "
57*45d3dd98SRobert Mustacchi 		    "argument");
58*45d3dd98SRobert Mustacchi 		goto error;
59*45d3dd98SRobert Mustacchi 	}
60*45d3dd98SRobert Mustacchi 
61*45d3dd98SRobert Mustacchi 	if ((auth = topo_mod_auth(mod, pnode)) == NULL) {
62*45d3dd98SRobert Mustacchi 		topo_mod_dprintf(mod, "topo_mod_auth() failed: %s\n",
63*45d3dd98SRobert Mustacchi 		    topo_mod_errmsg(mod));
64*45d3dd98SRobert Mustacchi 		goto error;
65*45d3dd98SRobert Mustacchi 	}
66*45d3dd98SRobert Mustacchi 
67*45d3dd98SRobert Mustacchi 	if ((fmri = topo_mod_hcfmri(mod, pnode, FM_HC_SCHEME_VERSION,
68*45d3dd98SRobert Mustacchi 	    TRANSCEIVER, inst, NULL, auth, part, rev, serial)) == NULL) {
69*45d3dd98SRobert Mustacchi 		topo_mod_dprintf(mod, "topo_mod_hcfmri() failed: %s\n",
70*45d3dd98SRobert Mustacchi 		    topo_mod_errmsg(mod));
71*45d3dd98SRobert Mustacchi 		goto error;
72*45d3dd98SRobert Mustacchi 	}
73*45d3dd98SRobert Mustacchi 
74*45d3dd98SRobert Mustacchi 	if ((tn = topo_node_bind(mod, pnode, TRANSCEIVER, inst, fmri)) ==
75*45d3dd98SRobert Mustacchi 	    NULL) {
76*45d3dd98SRobert Mustacchi 		topo_mod_dprintf(mod, "topo_node_bind() failed: %s\n",
77*45d3dd98SRobert Mustacchi 		    topo_mod_errmsg(mod));
78*45d3dd98SRobert Mustacchi 		goto error;
79*45d3dd98SRobert Mustacchi 	}
80*45d3dd98SRobert Mustacchi 
81*45d3dd98SRobert Mustacchi 	/*
82*45d3dd98SRobert Mustacchi 	 * The FRU for a transceiver is always itself.
83*45d3dd98SRobert Mustacchi 	 */
84*45d3dd98SRobert Mustacchi 	if (topo_node_fru_set(tn, fmri, 0, &err) != 0) {
85*45d3dd98SRobert Mustacchi 		topo_mod_dprintf(mod, "topo_node_fru_set() failed: %s\n",
86*45d3dd98SRobert Mustacchi 		    topo_strerror(err));
87*45d3dd98SRobert Mustacchi 		goto error;
88*45d3dd98SRobert Mustacchi 	}
89*45d3dd98SRobert Mustacchi 
90*45d3dd98SRobert Mustacchi 	if (topo_pgroup_create(tn, &transceiver_pgroup, &err) != 0) {
91*45d3dd98SRobert Mustacchi 		topo_mod_dprintf(mod, "failed to create property group %s: "
92*45d3dd98SRobert Mustacchi 		    "%s\n", TOPO_PGROUP_TRANSCEIVER, topo_strerror(err));
93*45d3dd98SRobert Mustacchi 		goto error;
94*45d3dd98SRobert Mustacchi 	}
95*45d3dd98SRobert Mustacchi 
96*45d3dd98SRobert Mustacchi 	if (topo_prop_set_string(tn, TOPO_PGROUP_TRANSCEIVER,
97*45d3dd98SRobert Mustacchi 	    TOPO_PROP_TRANSCEIVER_TYPE, TOPO_PROP_IMMUTABLE, type,
98*45d3dd98SRobert Mustacchi 	    &err) != 0) {
99*45d3dd98SRobert Mustacchi 		topo_mod_dprintf(mod, "failed to set %s property: %s\n",
100*45d3dd98SRobert Mustacchi 		    TOPO_PROP_TRANSCEIVER_TYPE, topo_strerror(err));
101*45d3dd98SRobert Mustacchi 		goto error;
102*45d3dd98SRobert Mustacchi 	}
103*45d3dd98SRobert Mustacchi 
104*45d3dd98SRobert Mustacchi 	if (topo_prop_set_string(tn, TOPO_PGROUP_TRANSCEIVER,
105*45d3dd98SRobert Mustacchi 	    TOPO_PROP_TRANSCEIVER_USABLE, TOPO_PROP_IMMUTABLE,
106*45d3dd98SRobert Mustacchi 	    usable ? "true" : "false", &err) != 0) {
107*45d3dd98SRobert Mustacchi 		topo_mod_dprintf(mod, "failed to set %s property: %s\n",
108*45d3dd98SRobert Mustacchi 		    TOPO_PROP_TRANSCEIVER_USABLE, topo_strerror(err));
109*45d3dd98SRobert Mustacchi 		goto error;
110*45d3dd98SRobert Mustacchi 	}
111*45d3dd98SRobert Mustacchi 
112*45d3dd98SRobert Mustacchi 	nvlist_free(fmri);
113*45d3dd98SRobert Mustacchi 	nvlist_free(auth);
114*45d3dd98SRobert Mustacchi 	return (tn);
115*45d3dd98SRobert Mustacchi 
116*45d3dd98SRobert Mustacchi error:
117*45d3dd98SRobert Mustacchi 	topo_node_unbind(tn);
118*45d3dd98SRobert Mustacchi 	nvlist_free(fmri);
119*45d3dd98SRobert Mustacchi 	nvlist_free(auth);
120*45d3dd98SRobert Mustacchi 	return (NULL);
121*45d3dd98SRobert Mustacchi }
122*45d3dd98SRobert Mustacchi 
123*45d3dd98SRobert Mustacchi int
124*45d3dd98SRobert Mustacchi transceiver_create_sff(topo_mod_t *mod, tnode_t *pnode, topo_instance_t inst,
125*45d3dd98SRobert Mustacchi     boolean_t useable, const char *vendor, const char *part, const char *rev,
126*45d3dd98SRobert Mustacchi     const char *serial, tnode_t **nodep)
127*45d3dd98SRobert Mustacchi {
128*45d3dd98SRobert Mustacchi 	int err;
129*45d3dd98SRobert Mustacchi 	tnode_t *tn = NULL;
130*45d3dd98SRobert Mustacchi 
131*45d3dd98SRobert Mustacchi 	if ((tn = transceiver_create_common(mod, pnode, inst,
132*45d3dd98SRobert Mustacchi 	    TOPO_PROP_PORT_TYPE_SFF, useable, part, rev, serial)) == NULL) {
133*45d3dd98SRobert Mustacchi 		return (-1);
134*45d3dd98SRobert Mustacchi 	}
135*45d3dd98SRobert Mustacchi 
136*45d3dd98SRobert Mustacchi 	/*
137*45d3dd98SRobert Mustacchi 	 * Always create the SFF property group, even if we can't fill in any
138*45d3dd98SRobert Mustacchi 	 * properties.
139*45d3dd98SRobert Mustacchi 	 */
140*45d3dd98SRobert Mustacchi 	if (topo_pgroup_create(tn, &sff_transceiver_pgroup, &err) != 0) {
141*45d3dd98SRobert Mustacchi 		topo_mod_dprintf(mod, "failed to create property group %s: "
142*45d3dd98SRobert Mustacchi 		    "%s\n", TOPO_PGROUP_SFF_TRANSCEIVER, topo_strerror(err));
143*45d3dd98SRobert Mustacchi 		goto error;
144*45d3dd98SRobert Mustacchi 	}
145*45d3dd98SRobert Mustacchi 
146*45d3dd98SRobert Mustacchi 	if (vendor != NULL && topo_prop_set_string(tn,
147*45d3dd98SRobert Mustacchi 	    TOPO_PGROUP_SFF_TRANSCEIVER, TOPO_PORT_SFF_TRANSCEIVER_VENDOR,
148*45d3dd98SRobert Mustacchi 	    TOPO_PROP_IMMUTABLE, vendor, &err) != 0) {
149*45d3dd98SRobert Mustacchi 		topo_mod_dprintf(mod, "failed to set %s property: %s\n",
150*45d3dd98SRobert Mustacchi 		    TOPO_PORT_SFF_TRANSCEIVER_VENDOR, topo_strerror(err));
151*45d3dd98SRobert Mustacchi 		goto error;
152*45d3dd98SRobert Mustacchi 	}
153*45d3dd98SRobert Mustacchi 
154*45d3dd98SRobert Mustacchi 	if (part != NULL && topo_prop_set_string(tn,
155*45d3dd98SRobert Mustacchi 	    TOPO_PGROUP_SFF_TRANSCEIVER, TOPO_PORT_SFF_TRANSCEIVER_PN,
156*45d3dd98SRobert Mustacchi 	    TOPO_PROP_IMMUTABLE, part, &err) != 0) {
157*45d3dd98SRobert Mustacchi 		topo_mod_dprintf(mod, "failed to set %s property: %s\n",
158*45d3dd98SRobert Mustacchi 		    TOPO_PORT_SFF_TRANSCEIVER_PN, topo_strerror(err));
159*45d3dd98SRobert Mustacchi 		goto error;
160*45d3dd98SRobert Mustacchi 	}
161*45d3dd98SRobert Mustacchi 
162*45d3dd98SRobert Mustacchi 	if (rev != NULL && topo_prop_set_string(tn,
163*45d3dd98SRobert Mustacchi 	    TOPO_PGROUP_SFF_TRANSCEIVER, TOPO_PORT_SFF_TRANSCEIVER_REV,
164*45d3dd98SRobert Mustacchi 	    TOPO_PROP_IMMUTABLE, rev, &err) != 0) {
165*45d3dd98SRobert Mustacchi 		topo_mod_dprintf(mod, "failed to set %s property: %s\n",
166*45d3dd98SRobert Mustacchi 		    TOPO_PORT_SFF_TRANSCEIVER_REV, topo_strerror(err));
167*45d3dd98SRobert Mustacchi 		goto error;
168*45d3dd98SRobert Mustacchi 	}
169*45d3dd98SRobert Mustacchi 
170*45d3dd98SRobert Mustacchi 	if (serial != NULL && topo_prop_set_string(tn,
171*45d3dd98SRobert Mustacchi 	    TOPO_PGROUP_SFF_TRANSCEIVER, TOPO_PORT_SFF_TRANSCEIVER_SN,
172*45d3dd98SRobert Mustacchi 	    TOPO_PROP_IMMUTABLE, serial, &err) != 0) {
173*45d3dd98SRobert Mustacchi 		topo_mod_dprintf(mod, "failed to set %s property: %s\n",
174*45d3dd98SRobert Mustacchi 		    TOPO_PORT_SFF_TRANSCEIVER_SN, topo_strerror(err));
175*45d3dd98SRobert Mustacchi 		goto error;
176*45d3dd98SRobert Mustacchi 	}
177*45d3dd98SRobert Mustacchi 
178*45d3dd98SRobert Mustacchi 	if (nodep != NULL)
179*45d3dd98SRobert Mustacchi 		*nodep = tn;
180*45d3dd98SRobert Mustacchi 	return (0);
181*45d3dd98SRobert Mustacchi 
182*45d3dd98SRobert Mustacchi error:
183*45d3dd98SRobert Mustacchi 	topo_node_unbind(tn);
184*45d3dd98SRobert Mustacchi 	return (-1);
185*45d3dd98SRobert Mustacchi }
186