1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
23  * Copyright 2019 Joyent, Inc.
24  */
25 
26 #ifndef _FABRIC_XLATE_H
27 #define	_FABRIC_XLATE_H
28 
29 #include <fm/fmd_api.h>
30 #include <sys/fm/protocol.h>
31 #include <sys/nvpair.h>
32 #include <sys/types.h>
33 #include <sys/pcie.h>
34 #include <sys/fm/io/pci.h>
35 #include <limits.h>
36 
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
40 
41 #define	STRCMP(s1, s2) (strcmp((const char *)s1, (const char *)s2) == 0)
42 /*
43  * These values are used for the xxx_tgt_trans value in fab_data_t.  They are
44  * originally set in pcie_fault.c and originally defined in pcie_impl.h.
45  */
46 #define	PF_ADDR_DMA		(1 << 0)
47 #define	PF_ADDR_PIO		(1 << 1)
48 #define	PF_ADDR_CFG		(1 << 2)
49 
50 
51 /*
52  * The fabric ereport preparation functions (fab_prep_*) in fab_erpt_tbl_t
53  * structures may return an error if the ereport could not be set up properly.
54  * Typically, these errors are errnos. It is possible that based on incoming
55  * ereport payload data, we might not want to generate an ereport at all: In
56  * this case, the preparation functions may instead return PF_EREPORT_IGNORE,
57  * which is set at a high value so as not to collide with the errnos.
58  */
59 #define	PF_EREPORT_IGNORE	INT_MAX
60 
61 extern fmd_xprt_t *fab_fmd_xprt;	/* FMD transport layer handle */
62 extern char fab_buf[];
63 
64 /* PCI-E config space data for error handling and fabric ereports */
65 typedef struct fab_data {
66 	/* Original ereport NVL */
67 	nvlist_t	*nvl;
68 
69 	/* Device Information */
70 	uint16_t bdf;
71 	uint16_t device_id;
72 	uint16_t vendor_id;
73 	uint8_t rev_id;
74 	uint16_t dev_type;
75 	uint16_t pcie_off;
76 	uint16_t pcix_off;
77 	uint16_t aer_off;
78 	uint16_t ecc_ver;
79 
80 	/* Ereport Information */
81 	uint32_t remainder;
82 	uint32_t severity;
83 
84 	/* Error Registers */
85 	uint16_t pci_err_status;	/* pci status register */
86 	uint16_t pci_cfg_comm;		/* pci command register */
87 
88 	uint16_t pci_bdg_sec_stat;	/* PCI secondary status reg */
89 	uint16_t pci_bdg_ctrl;		/* PCI bridge control reg */
90 
91 	uint16_t pcix_command;		/* pcix command register */
92 	uint32_t pcix_status;		/* pcix status register */
93 
94 	uint16_t pcix_bdg_sec_stat;	/* pcix bridge secondary status reg */
95 	uint32_t pcix_bdg_stat;		/* pcix bridge status reg */
96 
97 	uint16_t pcix_ecc_control_0;	/* pcix ecc control status reg */
98 	uint16_t pcix_ecc_status_0;	/* pcix ecc control status reg */
99 	uint32_t pcix_ecc_fst_addr_0;	/* pcix ecc first address reg */
100 	uint32_t pcix_ecc_sec_addr_0;	/* pcix ecc second address reg */
101 	uint32_t pcix_ecc_attr_0;	/* pcix ecc attributes reg */
102 	uint16_t pcix_ecc_control_1;	/* pcix ecc control status reg */
103 	uint16_t pcix_ecc_status_1;	/* pcix ecc control status reg */
104 	uint32_t pcix_ecc_fst_addr_1;	/* pcix ecc first address reg */
105 	uint32_t pcix_ecc_sec_addr_1;	/* pcix ecc second address reg */
106 	uint32_t pcix_ecc_attr_1;	/* pcix ecc attributes reg */
107 
108 	uint16_t pcie_err_status;	/* pcie device status register */
109 	uint16_t pcie_err_ctl;		/* pcie error control register */
110 	uint32_t pcie_dev_cap;		/* pcie device capabilities register */
111 
112 	uint32_t pcie_adv_ctl;		/* pcie advanced control reg */
113 	uint32_t pcie_ue_status;	/* pcie ue error status reg */
114 	uint32_t pcie_ue_mask;		/* pcie ue error mask reg */
115 	uint32_t pcie_ue_sev;		/* pcie ue error severity reg */
116 	uint32_t pcie_ue_hdr[4];	/* pcie ue header log */
117 	uint32_t pcie_ce_status;	/* pcie ce error status reg */
118 	uint32_t pcie_ce_mask;		/* pcie ce error mask reg */
119 	uint32_t pcie_ue_tgt_trans;	/* Fault trans type from AER Logs */
120 	uint64_t pcie_ue_tgt_addr;	/* Fault addr from AER Logs */
121 	pcie_req_id_t pcie_ue_tgt_bdf;	/* Fault bdf from SAER Logs */
122 	boolean_t pcie_ue_no_tgt_erpt;  /* Don't send target ereports */
123 
124 	uint32_t pcie_sue_ctl;		/* pcie bridge secondary ue control */
125 	uint32_t pcie_sue_status;	/* pcie bridge secondary ue status */
126 	uint32_t pcie_sue_mask;		/* pcie bridge secondary ue mask */
127 	uint32_t pcie_sue_sev;		/* pcie bridge secondary ue severity */
128 	uint32_t pcie_sue_hdr[4];	/* pcie bridge secondary ue hdr log */
129 	uint32_t pcie_sue_tgt_trans;	/* Fault trans type from AER Logs */
130 	uint64_t pcie_sue_tgt_addr;	/* Fault addr from AER Logs */
131 	pcie_req_id_t pcie_sue_tgt_bdf;	/* Fault bdf from SAER Logs */
132 
133 	uint32_t pcie_rp_status;	/* root complex status register */
134 	uint16_t pcie_rp_ctl;		/* root complex control register */
135 	uint32_t pcie_rp_err_status;	/* pcie root complex error status reg */
136 	uint32_t pcie_rp_err_cmd;	/* pcie root complex error cmd reg */
137 	uint16_t pcie_rp_ce_src_id;	/* pcie root complex ce source id */
138 	uint16_t pcie_rp_ue_src_id;	/* pcie root complex ue source id */
139 
140 	/*
141 	 * The slot register values refer to the registers of the component's
142 	 * parent slot, not the component itself.
143 	 *
144 	 * You should only use the register values -- i.e.,
145 	 * pcie_slot_{cap,control,status} -- if pcie_slot_data_valid is set to
146 	 * true.
147 	 */
148 	boolean_t pcie_slot_data_valid; /* true if slot data is valid */
149 	uint32_t pcie_slot_cap;		/* pcie slot capabilities */
150 	uint16_t pcie_slot_control;	/* pcie slot control */
151 	uint16_t pcie_slot_status;	/* pcie slot status */
152 
153 	/* Flags */
154 	boolean_t pcie_rp_send_all;	/* need to send ereports on all rps */
155 } fab_data_t;
156 
157 typedef struct fab_erpt_tbl {
158 	const char	*err_class;	/* Final Ereport Class */
159 	uint32_t	reg_bit;	/* Error Bit Mask */
160 	const char	*tgt_class;	/* Target Ereport Class */
161 } fab_erpt_tbl_t;
162 
163 typedef struct fab_err_tbl {
164 	fab_erpt_tbl_t	*erpt_tbl;	/* ereport table */
165 	uint32_t	reg_offset;	/* sts reg for ereport table offset */
166 	uint32_t	reg_size;	/* size of the status register */
167 	/* Pointer to function that prepares the ereport body */
168 	int		(*fab_prep)(fmd_hdl_t *, fab_data_t *, nvlist_t *,
169 	    fab_erpt_tbl_t *);
170 } fab_err_tbl_t;
171 
172 extern void fab_setup_master_table();
173 
174 /* Main functions for converting "fabric" ereports */
175 extern void fab_xlate_pcie_erpts(fmd_hdl_t *, fab_data_t *);
176 extern void fab_xlate_fabric_erpts(fmd_hdl_t *, nvlist_t *, const char *);
177 extern void fab_xlate_fire_erpts(fmd_hdl_t *, nvlist_t *, const char *);
178 extern void fab_xlate_epkt_erpts(fmd_hdl_t *, nvlist_t *, const char *);
179 
180 /* Common functions for sending translated ereports */
181 extern int fab_prep_basic_erpt(fmd_hdl_t *, nvlist_t *, nvlist_t *, boolean_t);
182 extern void fab_send_tgt_erpt(fmd_hdl_t *, fab_data_t *, const char *,
183     boolean_t);
184 extern void fab_send_erpt(fmd_hdl_t *hdl, fab_data_t *data, fab_err_tbl_t *tbl);
185 
186 /* Misc Functions */
187 extern void fab_pr(fmd_hdl_t *, fmd_event_t *, nvlist_t *);
188 extern boolean_t fab_get_hcpath(fmd_hdl_t *, nvlist_t *, char **, size_t *);
189 extern boolean_t fab_get_rcpath(fmd_hdl_t *, nvlist_t *, char *);
190 extern char *fab_find_rppath_by_df(fmd_hdl_t *, nvlist_t *, uint8_t);
191 extern char *fab_find_rppath_by_devbdf(fmd_hdl_t *, nvlist_t *, pcie_req_id_t);
192 extern char *fab_find_rppath_by_devpath(fmd_hdl_t *, const char *);
193 extern char *fab_find_addr(fmd_hdl_t *hdl, nvlist_t *nvl, uint64_t addr);
194 extern char *fab_find_bdf(fmd_hdl_t *hdl, nvlist_t *nvl, pcie_req_id_t bdf);
195 extern boolean_t fab_hc2dev(fmd_hdl_t *, const char *, char **);
196 extern boolean_t fab_hc2dev_nvl(fmd_hdl_t *, nvlist_t *, char **);
197 extern char *fab_get_rpdev(fmd_hdl_t *);
198 extern void fab_set_fake_rp(fmd_hdl_t *);
199 extern void fab_send_erpt_all_rps(fmd_hdl_t *, nvlist_t *);
200 
201 #ifdef __cplusplus
202 }
203 #endif
204 
205 #endif /* _FABRIC_XLATE_H */
206