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 * Copyright 2020, the University of Queensland
13 */
14
15#pragma dictionary "NIC"
16
17/*
18 * Rules for the generic NIC (non-driver-specific) fault events.
19 */
20
21/*
22 * Transceiver events are emitted by drivers under ereport.io.nic.txr-err.
23 *
24 * These are emitted with detector = the PCI/PCIex function of the NIC.
25 * They must always have a string property "error", set to one of the
26 * generic transceiver fault type names (notsupp, whitelist, overtemp etc).
27 *
28 * As well as "error", they must have both the "port_index" and "txr_index"
29 * properties set in the event payload (both integer types).
30 *
31 * It is expected that drivers will call ddi_fm_service_impact() immediately
32 * after noticing a transceiver error, with an argument of DDI_SERVICE_LOST or
33 * DDI_SERVICE_DEGRADED (depending on the specific error -- at time of writing
34 * all the supported events expect DDI_SERVICE_LOST).
35 */
36
37asru pcifn;
38fru  pcifn/port/transceiver;
39
40asru pciexfn;
41fru  pciexfn/port/transceiver;
42
43#define	EV_DECL_TXR_FAULT(TYPE)		\
44	event fault.io.nic.transceiver.TYPE@pcifn/port/transceiver \
45	    FRU=pcifn/port/transceiver, ASRU=pcifn; \
46	event fault.io.nic.transceiver.TYPE@pciexfn/port/transceiver \
47	    FRU=pciexfn/port/transceiver, ASRU=pciexfn;
48
49EV_DECL_TXR_FAULT(notsupp)
50EV_DECL_TXR_FAULT(whitelist)
51EV_DECL_TXR_FAULT(overtemp)
52EV_DECL_TXR_FAULT(hwfail)
53EV_DECL_TXR_FAULT(unknown)
54
55event ereport.io.nic.txr-err@pcifn;
56event ereport.io.service.lost@pcifn;
57
58event ereport.io.nic.txr-err@pciexfn;
59event ereport.io.service.lost@pciexfn;
60
61#define	EV_PROP_TXR_FAULT(TYPE)		\
62	prop fault.io.nic.transceiver.TYPE@pcifn/port[pn]/transceiver[tn] (2) -> \
63	    ereport.io.nic.txr-err@pcifn { \
64	      payloadprop("txr_index") == tn && \
65	      payloadprop("port_index") == pn && \
66	      payloadprop("error") == "TYPE" && \
67	      setpayloadprop("txr_index", tn) && \
68	      setpayloadprop("link-name", confprop(pcifn/port[pn], "link-name")) && \
69	      setpayloadprop("primary-mac-address", confprop(pcifn/port[pn], "primary-mac-address")) && \
70	      (!confprop_defined(pcifn/port[pn]/transceiver[tn], "vendor") || \
71	       setpayloadprop("vendor", confprop(pcifn/port[pn]/transceiver[tn], "vendor"))) \
72	    }, \
73	    ereport.io.service.lost@pcifn { within(1s) }; \
74	prop fault.io.nic.transceiver.TYPE@pciexfn/port[pn]/transceiver[tn] (2) -> \
75	    ereport.io.nic.txr-err@pciexfn { \
76	      payloadprop("txr_index") == tn && \
77	      payloadprop("port_index") == pn && \
78	      payloadprop("error") == "TYPE" && \
79	      setpayloadprop("txr_index", tn) && \
80	      setpayloadprop("link-name", confprop(pciexfn/port[pn], "link-name")) && \
81	      setpayloadprop("primary-mac-address", confprop(pciexfn/port[pn], "primary-mac-address")) && \
82	      (!confprop_defined(pciexfn/port[pn]/transceiver[tn], "vendor") || \
83	       setpayloadprop("vendor", confprop(pciexfn/port[pn]/transceiver[tn], "vendor"))) \
84	    }, \
85	    ereport.io.service.lost@pciexfn { within(1s) };
86
87EV_PROP_TXR_FAULT(notsupp)
88EV_PROP_TXR_FAULT(whitelist)
89EV_PROP_TXR_FAULT(overtemp)
90EV_PROP_TXR_FAULT(hwfail)
91EV_PROP_TXR_FAULT(unknown)
92
93/*
94 * Allow drivers (e.g. i40e) which can't tell the difference between the events
95 * notsupp/unknown/whitelist to generate a single ereport covering all 3.
96 *
97 * If transceiver information is available in topo, we will turn it into
98 * a "notsupp" fault. If it isn't, we'll turn it into an "unknown" fault
99 * instead. The text in "notsupp" explicitly notes that certain drivers might
100 * have difficulty telling the difference between it and "whitelist".
101 *
102 * If you want this for a pcifn driver rather than pciexfn, you'll have to
103 * make another copy.
104 */
105prop fault.io.nic.transceiver.notsupp@pciexfn/port[pn]/transceiver[tn] (2) ->
106    ereport.io.nic.txr-err@pciexfn {
107      payloadprop("txr_index") == tn &&
108      payloadprop("port_index") == pn &&
109      payloadprop("error") == "notsupp/unknown" &&
110      confprop_defined(pciexfn/port[pn]/transceiver[tn], "vendor") &&
111      setpayloadprop("txr_index", tn) &&
112      setpayloadprop("link-name", confprop(pciexfn/port[pn], "link-name")) &&
113      setpayloadprop("primary-mac-address", confprop(pciexfn/port[pn], "primary-mac-address")) &&
114      setpayloadprop("vendor", confprop(pciexfn/port[pn]/transceiver[tn], "vendor"))
115    },
116    ereport.io.service.lost@pciexfn { within(1s) };
117prop fault.io.nic.transceiver.unknown@pciexfn/port[pn]/transceiver[tn] (2) ->
118    ereport.io.nic.txr-err@pciexfn {
119      payloadprop("txr_index") == tn &&
120      payloadprop("port_index") == pn &&
121      payloadprop("error") == "notsupp/unknown" &&
122      !confprop_defined(pciexfn/port[pn]/transceiver[tn], "vendor") &&
123      setpayloadprop("txr_index", tn) &&
124      setpayloadprop("link-name", confprop(pciexfn/port[pn], "link-name")) &&
125      setpayloadprop("primary-mac-address", confprop(pciexfn/port[pn], "primary-mac-address"))
126    },
127    ereport.io.service.lost@pciexfn { within(1s) };
128