xref: /illumos-gate/usr/src/lib/fm/topo/modules/common/pciebus/topo_pcie_impl.h (revision 84ceaea936ebcf122d4f0756d298adf307fd491d)
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 2026 Oxide Computer Company
14  */
15 
16 #ifndef	_TOPO_PCIE_IMPL_H
17 #define	_TOPO_PCIE_IMPL_H
18 
19 #include <libdevinfo.h>
20 #include <libnvpair.h>
21 #include <stdbool.h>
22 #include <fm/topo_mod.h>
23 #include <sys/bitext.h>
24 #include <sys/pci.h>
25 #include "topo_pcie.h"
26 
27 /*
28  * Implementation-specific PCIe module header file.
29  */
30 
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34 
35 #define	PCI_MAX_BUS		0xff
36 #define	PCI_MAX_DEV		0x1f
37 #define	PCI_MAX_FUNC		0x7
38 
39 typedef enum {
40 	PCIE_NODE_ROOTNEXUS,
41 	PCIE_NODE_ROOTPORT,
42 	PCIE_NODE_PCI_DEV,
43 	PCIE_NODE_PCIE_DEV,
44 	PCIE_NODE_SWITCH_UP,
45 	PCIE_NODE_SWITCH_DOWN,
46 	PCIE_NODE_PCIE_PCI,
47 	PCIE_NODE_PCI_PCIE,
48 } pcie_node_type_t;
49 
50 typedef enum {
51 	TOPO_PORT_DOWNSTREAM,
52 	TOPO_PORT_UPSTREAM,
53 } topo_port_type_t;
54 
55 typedef struct pcie {
56 	di_node_t		tp_devinfo;
57 	pcidb_hdl_t		*tp_pcidb_hdl;
58 	topo_list_t		tp_rootnexus;
59 	bool			tp_enumdone;
60 	uint8_t			tp_nchip;
61 	nvlist_t		*tp_cpupcidata;
62 	void			*tp_privdata;
63 } pcie_t;
64 
65 typedef struct pcie_node {
66 	topo_list_t		pn_link;
67 
68 	pcie_t			*pn_pcie;
69 	di_node_t		pn_did;
70 	pcie_node_type_t	pn_type;
71 	topo_instance_t		pn_inst;
72 	topo_instance_t		pn_cpu;
73 	int			pn_class;
74 	int			pn_subclass;
75 	int			pn_intf;
76 	int			pn_bus;
77 	int			pn_dev;
78 	int			pn_func;
79 	bool			pn_is_pcie;
80 	const char		*pn_path;
81 	char			*pn_drvname;
82 	int			pn_drvinst;
83 
84 	/*
85 	 * These two keep track of devices that have already been seen
86 	 * underneath this node, and the topology function number that was last
87 	 * allocated. They are both indexed by the PCI device ID of the child.
88 	 */
89 	tnode_t			*pn_devices[PCI_MAX_DEV + 1];
90 	topo_instance_t		pn_devfunc[PCI_MAX_DEV + 1];
91 
92 	topo_list_t		pn_children;
93 	struct pcie_node	*pn_parent;
94 } pcie_node_t;
95 
96 typedef enum {
97 	PCI_LINK_UNKNOWN,
98 	PCI_LINK_UP,
99 	PCI_LINK_DOWN,
100 } topo_pcie_link_status_t;
101 
102 #define	TOPO_PCIE_LINK_UP_STR		"up"
103 #define	TOPO_PCIE_LINK_DOWN_STR		"down"
104 
105 extern bool pcie_set_platdata(pcie_t *, void *);
106 extern void *pcie_get_platdata(const pcie_t *);
107 
108 /*
109  * Each architecture must provide implementations of the following
110  * mod_pcie_*() functions that can be used to decorate or extend topology nodes
111  * based on system-specific knowledge.
112  */
113 
114 extern bool mod_pcie_platform_init(topo_mod_t *, pcie_t *);
115 extern void mod_pcie_platform_fini(topo_mod_t *, pcie_t *);
116 
117 /*
118  * This hook is called to create the authority information for the node.
119  */
120 extern nvlist_t *mod_pcie_platform_auth(topo_mod_t *, const pcie_t *,
121     tnode_t *);
122 
123 /*
124  * This hook is called for every newly created topology node, after the core
125  * module has populated common properties. The return value is the topology
126  * node from which to continue, allowing additional nodes to be inserted
127  * into the hierarchy by the module if required.
128  */
129 extern tnode_t *mod_pcie_platform_topo_node_decorate(topo_mod_t *,
130     const pcie_t *, const pcie_node_t *, tnode_t *);
131 
132 /* topo_pcie_util.c */
133 
134 extern bool topo_pcie_set_io_props(topo_mod_t *, pcie_t *, pcie_node_t *,
135     tnode_t *);
136 extern bool topo_pcie_set_pci_props(topo_mod_t *, pcie_t *, pcie_node_t *,
137     tnode_t *);
138 extern bool topo_pcie_set_port_props(topo_mod_t *, pcie_t *, pcie_node_t *,
139     tnode_t *, topo_port_type_t);
140 extern bool topo_pcie_set_link_props(topo_mod_t *, pcie_t *, pcie_node_t *,
141     tnode_t *);
142 
143 extern const char *pcie_type_name(pcie_node_type_t);
144 extern uint_t pcie_speed2gen(int64_t);
145 extern const char *pcie_speed2str(int64_t);
146 
147 /* topo_pcie_prop.c */
148 
149 extern bool pcie_topo_pgroup_create(topo_mod_t *, tnode_t *,
150     const topo_pgroup_info_t *);
151 extern bool pcie_topo_range_create(topo_mod_t *, tnode_t *, const char *,
152     topo_instance_t, topo_instance_t);
153 
154 extern int32_t pcie_devinfo_get32(topo_mod_t *, di_node_t, const char *);
155 extern int64_t pcie_devinfo_get64(topo_mod_t *, di_node_t, const char *);
156 extern bool pcie_devinfo_getbool(topo_mod_t *, di_node_t, const char *);
157 
158 extern bool pcie_topo_prop_set32(topo_mod_t *, tnode_t *,
159     const topo_pgroup_info_t *, const char *, uint32_t);
160 extern bool pcie_topo_prop_set64(topo_mod_t *, tnode_t *,
161     const topo_pgroup_info_t *, const char *, uint64_t);
162 extern bool pcie_topo_prop_set32_array(topo_mod_t *, tnode_t *,
163     const topo_pgroup_info_t *, const char *, uint32_t *, int);
164 extern bool pcie_topo_prop_set64_array(topo_mod_t *, tnode_t *,
165     const topo_pgroup_info_t *, const char *, uint64_t *, int);
166 extern bool pcie_topo_prop_setstr(topo_mod_t *, tnode_t *,
167     const topo_pgroup_info_t *, const char *, const char *);
168 
169 extern bool pcie_topo_prop_copy(topo_mod_t *, di_node_t, tnode_t *,
170     const topo_pgroup_info_t *, topo_type_t, const char *, const char *);
171 
172 /* topo_pcie_cfgspace.c */
173 
174 extern topo_pcie_link_status_t topo_pcie_link_status(topo_mod_t *,
175     pcie_node_t *);
176 
177 #define	GETCLASS(x)	bitx32((x), 23, 16);
178 #define	GETSUBCLASS(x)	bitx32((x), 15, 8);
179 #define	GETINTF(x)	bitx32((x), 7, 0);
180 
181 #define	PCIE			"pcie"
182 #define	PCIE_VERSION		1
183 
184 #define	PCIE_ROOT_NEXUS		"pciex_root_complex"
185 
186 /*
187  * Devinfo properties
188  */
189 
190 #define	DI_COMPATPROP		"compatible"
191 #define	DI_DEVTYPPROP		"device_type"
192 #define	DI_PCIETYPPROP		"pcie-type"
193 #define	DI_VENDIDPROP		"vendor-id"
194 #define	DI_SUBVENDIDPROP	"subsystem-vendor-id"
195 #define	DI_SUBSYSTEMID		"subsystem-id"
196 #define	DI_REVIDPROP		"revision-id"
197 #define	DI_DEVIDPROP		"device-id"
198 #define	DI_CLASSPROP		"class-code"
199 #define	DI_REGPROP		"reg"
200 #define	DI_PHYSPROP		"physical-slot#"
201 #define	DI_AADDRPROP		"assigned-addresses"
202 #define	DI_MODELNAME		"model"
203 #define	DI_VENDORNAME		"vendor-name"
204 #define	DI_DEVICENAME		"device-name"
205 #define	DI_SUBSYSNAME		"subsystem-name"
206 #define	DI_BUSRANGE		"bus-range"
207 
208 #define	DI_PCIE_MAX_WIDTH	"pcie-link-maximum-width"
209 #define	DI_PCIE_CUR_WIDTH	"pcie-link-current-width"
210 #define	DI_PCIE_MAX_SPEED	"pcie-link-maximum-speed"
211 #define	DI_PCIE_CUR_SPEED	"pcie-link-current-speed"
212 #define	DI_PCIE_SUP_SPEEDS	"pcie-link-supported-speeds"
213 #define	DI_PCIE_TARG_SPEED	"pcie-link-target-speed"
214 #define	DI_PCIE_ADMIN_TAG	"pcie-link-admin-target-speed"
215 
216 #define	DI_PCI_66MHZ_CAPABLE	"66mhz-capable"
217 
218 #ifdef __cplusplus
219 }
220 #endif
221 
222 #endif	/* _TOPO_PCIE_IMPL_H */
223