xref: /onnv-gate/usr/src/uts/common/sys/pciev.h (revision 11596:e9010337bcd3)
1*11596SJason.Beloro@Sun.COM /*
2*11596SJason.Beloro@Sun.COM  * CDDL HEADER START
3*11596SJason.Beloro@Sun.COM  *
4*11596SJason.Beloro@Sun.COM  * The contents of this file are subject to the terms of the
5*11596SJason.Beloro@Sun.COM  * Common Development and Distribution License (the "License").
6*11596SJason.Beloro@Sun.COM  * You may not use this file except in compliance with the License.
7*11596SJason.Beloro@Sun.COM  *
8*11596SJason.Beloro@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*11596SJason.Beloro@Sun.COM  * or http://www.opensolaris.org/os/licensing.
10*11596SJason.Beloro@Sun.COM  * See the License for the specific language governing permissions
11*11596SJason.Beloro@Sun.COM  * and limitations under the License.
12*11596SJason.Beloro@Sun.COM  *
13*11596SJason.Beloro@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
14*11596SJason.Beloro@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*11596SJason.Beloro@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
16*11596SJason.Beloro@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
17*11596SJason.Beloro@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
18*11596SJason.Beloro@Sun.COM  *
19*11596SJason.Beloro@Sun.COM  * CDDL HEADER END
20*11596SJason.Beloro@Sun.COM  */
21*11596SJason.Beloro@Sun.COM /*
22*11596SJason.Beloro@Sun.COM  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
23*11596SJason.Beloro@Sun.COM  * Use is subject to license terms.
24*11596SJason.Beloro@Sun.COM  */
25*11596SJason.Beloro@Sun.COM 
26*11596SJason.Beloro@Sun.COM #ifndef	_SYS_PCIEV_H
27*11596SJason.Beloro@Sun.COM #define	_SYS_PCIEV_H
28*11596SJason.Beloro@Sun.COM 
29*11596SJason.Beloro@Sun.COM #ifdef	__cplusplus
30*11596SJason.Beloro@Sun.COM extern "C" {
31*11596SJason.Beloro@Sun.COM #endif
32*11596SJason.Beloro@Sun.COM 
33*11596SJason.Beloro@Sun.COM typedef struct pcie_eh_data {
34*11596SJason.Beloro@Sun.COM 	uint16_t minor_ver;	/* Minor data packet version, added data */
35*11596SJason.Beloro@Sun.COM 	uint16_t major_ver;	/* Major data packet version, struct change */
36*11596SJason.Beloro@Sun.COM 	uint16_t pci_err_status;	/* pci status register */
37*11596SJason.Beloro@Sun.COM 	uint16_t pci_bdg_sec_stat;	/* PCI secondary status reg */
38*11596SJason.Beloro@Sun.COM 	uint32_t pcix_status;		/* pcix status register */
39*11596SJason.Beloro@Sun.COM 	uint16_t pcix_bdg_sec_stat;	/* pcix bridge secondary status reg */
40*11596SJason.Beloro@Sun.COM 	uint32_t pcix_bdg_stat;		/* pcix bridge status reg */
41*11596SJason.Beloro@Sun.COM 	uint16_t pcix_ecc_control_0;	/* pcix ecc control status reg */
42*11596SJason.Beloro@Sun.COM 	uint16_t pcix_ecc_status_0;	/* pcix ecc control status reg */
43*11596SJason.Beloro@Sun.COM 	uint32_t pcix_ecc_fst_addr_0;	/* pcix ecc first address reg */
44*11596SJason.Beloro@Sun.COM 	uint32_t pcix_ecc_sec_addr_0;	/* pcix ecc second address reg */
45*11596SJason.Beloro@Sun.COM 	uint32_t pcix_ecc_attr_0;	/* pcix ecc attributes reg */
46*11596SJason.Beloro@Sun.COM 	uint16_t pcix_ecc_control_1;	/* pcix ecc control status reg */
47*11596SJason.Beloro@Sun.COM 	uint16_t pcix_ecc_status_1;	/* pcix ecc control status reg */
48*11596SJason.Beloro@Sun.COM 	uint32_t pcix_ecc_fst_addr_1;	/* pcix ecc first address reg */
49*11596SJason.Beloro@Sun.COM 	uint32_t pcix_ecc_sec_addr_1;	/* pcix ecc second address reg */
50*11596SJason.Beloro@Sun.COM 	uint32_t pcix_ecc_attr_1;	/* pcix ecc attributes reg */
51*11596SJason.Beloro@Sun.COM 	uint16_t pcie_err_status;	/* pcie device status register */
52*11596SJason.Beloro@Sun.COM 	uint32_t pcie_ue_status;	/* pcie ue error status reg */
53*11596SJason.Beloro@Sun.COM 	uint32_t pcie_ue_hdr[4];	/* pcie ue header log */
54*11596SJason.Beloro@Sun.COM 	uint32_t pcie_ce_status;	/* pcie ce error status reg */
55*11596SJason.Beloro@Sun.COM 	uint32_t pcie_sue_status;	/* pcie bridge secondary ue status */
56*11596SJason.Beloro@Sun.COM 	uint32_t pcie_sue_hdr[4];	/* pcie bridge secondary ue hdr log */
57*11596SJason.Beloro@Sun.COM 	uint16_t pcie_rp_ctl;		/* root port control register */
58*11596SJason.Beloro@Sun.COM 	uint32_t pcie_rp_err_status;	/* pcie root port error status reg */
59*11596SJason.Beloro@Sun.COM 	uint32_t pcie_rp_err_cmd;	/* pcie root port error cmd reg */
60*11596SJason.Beloro@Sun.COM 	uint16_t pcie_rp_ce_src_id;	/* pcie root port ce sourpe id */
61*11596SJason.Beloro@Sun.COM 	uint16_t pcie_rp_ue_src_id;	/* pcie root port ue sourpe id */
62*11596SJason.Beloro@Sun.COM } pcie_eh_data_t;
63*11596SJason.Beloro@Sun.COM 
64*11596SJason.Beloro@Sun.COM typedef struct pcie_domains {
65*11596SJason.Beloro@Sun.COM 	uint_t domain_id;
66*11596SJason.Beloro@Sun.COM 	uint_t cached_count;	/* Reference Count of cached dom id list */
67*11596SJason.Beloro@Sun.COM 	uint_t faulty_count;	/* Reference Count of faulty dom id list */
68*11596SJason.Beloro@Sun.COM 	struct pcie_domains *cached_next; /* Next on cached dom id list */
69*11596SJason.Beloro@Sun.COM 	struct pcie_domains *faulty_prev; /* Prev on faulty dom id list */
70*11596SJason.Beloro@Sun.COM 	struct pcie_domains *faulty_next; /* Next on faulty dom id list */
71*11596SJason.Beloro@Sun.COM } pcie_domains_t;
72*11596SJason.Beloro@Sun.COM 
73*11596SJason.Beloro@Sun.COM typedef struct pcie_req_id_list {
74*11596SJason.Beloro@Sun.COM 	pcie_req_id_t		bdf;
75*11596SJason.Beloro@Sun.COM 	struct pcie_req_id_list	*next;
76*11596SJason.Beloro@Sun.COM } pcie_req_id_list_t;
77*11596SJason.Beloro@Sun.COM 
78*11596SJason.Beloro@Sun.COM typedef struct pcie_child_domains {
79*11596SJason.Beloro@Sun.COM 	pcie_domains_t *ids;
80*11596SJason.Beloro@Sun.COM 	pcie_req_id_list_t *bdfs;
81*11596SJason.Beloro@Sun.COM } pcie_child_domains_t;
82*11596SJason.Beloro@Sun.COM 
83*11596SJason.Beloro@Sun.COM /*
84*11596SJason.Beloro@Sun.COM  * IOV data structure:
85*11596SJason.Beloro@Sun.COM  * This data strucutre is now statically allocated during bus_p
86*11596SJason.Beloro@Sun.COM  * initializing time. Do we need to have this data structure for
87*11596SJason.Beloro@Sun.COM  * non-root domains? If not, is there a way to differentiate root
88*11596SJason.Beloro@Sun.COM  * domain and non-root domain so that we do the initialization for
89*11596SJason.Beloro@Sun.COM  * root domain only?
90*11596SJason.Beloro@Sun.COM  */
91*11596SJason.Beloro@Sun.COM typedef struct pcie_domain {
92*11596SJason.Beloro@Sun.COM 	/*
93*11596SJason.Beloro@Sun.COM 	 * Bridges:
94*11596SJason.Beloro@Sun.COM 	 * Cache the domain/channel id and bdfs of all it's children.
95*11596SJason.Beloro@Sun.COM 	 *
96*11596SJason.Beloro@Sun.COM 	 * Leaves:
97*11596SJason.Beloro@Sun.COM 	 * Cache just the domain/channel id of self.
98*11596SJason.Beloro@Sun.COM 	 * Bridges will contain 0 <= N <= NumChild
99*11596SJason.Beloro@Sun.COM 	 *
100*11596SJason.Beloro@Sun.COM 	 * Note:
101*11596SJason.Beloro@Sun.COM 	 * there is no lock to protect the access to
102*11596SJason.Beloro@Sun.COM 	 * pcie_domains_t data struture. Currently we don't see
103*11596SJason.Beloro@Sun.COM 	 * the need for lock. But we need to pay attention if there
104*11596SJason.Beloro@Sun.COM 	 * might be issues when hotplug is enabled.
105*11596SJason.Beloro@Sun.COM 	 */
106*11596SJason.Beloro@Sun.COM 	union {
107*11596SJason.Beloro@Sun.COM 		pcie_child_domains_t ids;
108*11596SJason.Beloro@Sun.COM 		pcie_domains_t id;
109*11596SJason.Beloro@Sun.COM 	} domain;
110*11596SJason.Beloro@Sun.COM 
111*11596SJason.Beloro@Sun.COM 	/*
112*11596SJason.Beloro@Sun.COM 	 * Reference count of the domain type for this device and it's children.
113*11596SJason.Beloro@Sun.COM 	 * For leaf devices, fmadom + nfma + root = 1
114*11596SJason.Beloro@Sun.COM 	 * For bridges, the sum of the counts = number of LEAF children.
115*11596SJason.Beloro@Sun.COM 	 *
116*11596SJason.Beloro@Sun.COM 	 * All devices start with a count of 1 for either nfmadom or rootdom.
117*11596SJason.Beloro@Sun.COM 	 */
118*11596SJason.Beloro@Sun.COM 	uint_t		fmadom_count;	/* FMA channel capable domain */
119*11596SJason.Beloro@Sun.COM 	uint_t		nfmadom_count;	/* Non-FMA channel domain */
120*11596SJason.Beloro@Sun.COM 	uint_t		rootdom_count;	/* Root domain */
121*11596SJason.Beloro@Sun.COM 
122*11596SJason.Beloro@Sun.COM 	/* flag if the affected dev will cause guest domains to panic */
123*11596SJason.Beloro@Sun.COM 	boolean_t	nfma_panic;
124*11596SJason.Beloro@Sun.COM } pcie_domain_t;
125*11596SJason.Beloro@Sun.COM 
126*11596SJason.Beloro@Sun.COM extern void pcie_domain_list_add(uint_t, pcie_domains_t **);
127*11596SJason.Beloro@Sun.COM extern void pcie_domain_list_remove(uint_t, pcie_domains_t *);
128*11596SJason.Beloro@Sun.COM extern void pcie_save_domain_id(pcie_domains_t *);
129*11596SJason.Beloro@Sun.COM extern void pcie_init_dom(dev_info_t *);
130*11596SJason.Beloro@Sun.COM extern void pcie_fini_dom(dev_info_t *);
131*11596SJason.Beloro@Sun.COM 
132*11596SJason.Beloro@Sun.COM #define	PCIE_ASSIGNED_TO_FMA_DOM(bus_p)	\
133*11596SJason.Beloro@Sun.COM 	(!PCIE_IS_BDG(bus_p) && PCIE_BUS2DOM(bus_p)->fmadom_count > 0)
134*11596SJason.Beloro@Sun.COM #define	PCIE_ASSIGNED_TO_NFMA_DOM(bus_p)	\
135*11596SJason.Beloro@Sun.COM 	(!PCIE_IS_BDG(bus_p) && PCIE_BUS2DOM(bus_p)->nfmadom_count > 0)
136*11596SJason.Beloro@Sun.COM #define	PCIE_ASSIGNED_TO_ROOT_DOM(bus_p)			\
137*11596SJason.Beloro@Sun.COM 	(PCIE_IS_BDG(bus_p) || PCIE_BUS2DOM(bus_p)->rootdom_count > 0)
138*11596SJason.Beloro@Sun.COM #define	PCIE_BDG_HAS_CHILDREN_FMA_DOM(bus_p)			\
139*11596SJason.Beloro@Sun.COM 	(PCIE_IS_BDG(bus_p) && PCIE_BUS2DOM(bus_p)->fmadom_count > 0)
140*11596SJason.Beloro@Sun.COM #define	PCIE_BDG_HAS_CHILDREN_NFMA_DOM(bus_p)			\
141*11596SJason.Beloro@Sun.COM 	(PCIE_IS_BDG(bus_p) && PCIE_BUS2DOM(bus_p)->nfmadom_count > 0)
142*11596SJason.Beloro@Sun.COM #define	PCIE_BDG_HAS_CHILDREN_ROOT_DOM(bus_p)			\
143*11596SJason.Beloro@Sun.COM 	(PCIE_IS_BDG(bus_p) && PCIE_BUS2DOM(bus_p)->rootdom_count > 0)
144*11596SJason.Beloro@Sun.COM #define	PCIE_IS_ASSIGNED(bus_p)	\
145*11596SJason.Beloro@Sun.COM 	(!PCIE_ASSIGNED_TO_ROOT_DOM(bus_p))
146*11596SJason.Beloro@Sun.COM #define	PCIE_BDG_IS_UNASSIGNED(bus_p)	\
147*11596SJason.Beloro@Sun.COM 	(PCIE_IS_BDG(bus_p) &&		\
148*11596SJason.Beloro@Sun.COM 	(!PCIE_BDG_HAS_CHILDREN_NFMA_DOM(bus_p)) &&	\
149*11596SJason.Beloro@Sun.COM 	(!PCIE_BDG_HAS_CHILDREN_FMA_DOM(bus_p)))
150*11596SJason.Beloro@Sun.COM 
151*11596SJason.Beloro@Sun.COM 
152*11596SJason.Beloro@Sun.COM #define	PCIE_IN_DOMAIN(bus_p, id) (pcie_in_domain((bus_p), (id)))
153*11596SJason.Beloro@Sun.COM 
154*11596SJason.Beloro@Sun.COM /* Following macros are only valid for leaf devices */
155*11596SJason.Beloro@Sun.COM #define	PCIE_DOMAIN_ID_GET(bus_p) \
156*11596SJason.Beloro@Sun.COM 	((uint_t)(PCIE_IS_ASSIGNED(bus_p)			\
157*11596SJason.Beloro@Sun.COM 	    ? PCIE_BUS2DOM(bus_p)->domain.id.domain_id : NULL))
158*11596SJason.Beloro@Sun.COM #define	PCIE_DOMAIN_ID_SET(bus_p, new_id) \
159*11596SJason.Beloro@Sun.COM 	if (!PCIE_IS_BDG(bus_p)) \
160*11596SJason.Beloro@Sun.COM 		PCIE_BUS2DOM(bus_p)->domain.id.domain_id = (uint_t)(new_id)
161*11596SJason.Beloro@Sun.COM #define	PCIE_DOMAIN_ID_INCR_REF_COUNT(bus_p)	\
162*11596SJason.Beloro@Sun.COM 	if (!PCIE_IS_BDG(bus_p))	\
163*11596SJason.Beloro@Sun.COM 		PCIE_BUS2DOM(bus_p)->domain.id.cached_count = 1;
164*11596SJason.Beloro@Sun.COM #define	PCIE_DOMAIN_ID_DECR_REF_COUNT(bus_p)	\
165*11596SJason.Beloro@Sun.COM 	if (!PCIE_IS_BDG(bus_p))	\
166*11596SJason.Beloro@Sun.COM 		PCIE_BUS2DOM(bus_p)->domain.id.cached_count = 0;
167*11596SJason.Beloro@Sun.COM 
168*11596SJason.Beloro@Sun.COM /* Following macros are only valid for bridges */
169*11596SJason.Beloro@Sun.COM #define	PCIE_DOMAIN_LIST_GET(bus_p) \
170*11596SJason.Beloro@Sun.COM 	((pcie_domains_t *)(PCIE_IS_BDG(bus_p) ?	\
171*11596SJason.Beloro@Sun.COM 	    PCIE_BUS2DOM(bus_p)->domain.ids.ids : NULL))
172*11596SJason.Beloro@Sun.COM #define	PCIE_DOMAIN_LIST_ADD(bus_p, domain_id) \
173*11596SJason.Beloro@Sun.COM 	if (PCIE_IS_BDG(bus_p)) \
174*11596SJason.Beloro@Sun.COM 	    pcie_domain_list_add(domain_id, \
175*11596SJason.Beloro@Sun.COM 		&PCIE_BUS2DOM(bus_p)->domain.ids.ids)
176*11596SJason.Beloro@Sun.COM #define	PCIE_DOMAIN_LIST_REMOVE(bus_p, domain_id) \
177*11596SJason.Beloro@Sun.COM 	if (PCIE_IS_BDG(bus_p)) \
178*11596SJason.Beloro@Sun.COM 	    pcie_domain_list_remove(domain_id, \
179*11596SJason.Beloro@Sun.COM 		PCIE_BUS2DOM(bus_p)->domain.ids.ids)
180*11596SJason.Beloro@Sun.COM 
181*11596SJason.Beloro@Sun.COM #define	PCIE_BDF_LIST_GET(bus_p) \
182*11596SJason.Beloro@Sun.COM 	((pcie_req_id_list_t *)(PCIE_IS_BDG(bus_p) ? \
183*11596SJason.Beloro@Sun.COM 	    PCIE_BUS2DOM(bus_p)->domain.ids.bdfs : NULL))
184*11596SJason.Beloro@Sun.COM #define	PCIE_BDF_LIST_ADD(bus_p, bdf) \
185*11596SJason.Beloro@Sun.COM 	if (PCIE_IS_BDG(bus_p)) \
186*11596SJason.Beloro@Sun.COM 		pcie_bdf_list_add(bdf, &PCIE_BUS2DOM(bus_p)->domain.ids.bdfs)
187*11596SJason.Beloro@Sun.COM #define	PCIE_BDF_LIST_REMOVE(bus_p, bdf) \
188*11596SJason.Beloro@Sun.COM 	if (PCIE_IS_BDG(bus_p)) \
189*11596SJason.Beloro@Sun.COM 		pcie_bdf_list_remove(bdf, &PCIE_BUS2DOM(bus_p)->domain.ids.bdfs)
190*11596SJason.Beloro@Sun.COM 
191*11596SJason.Beloro@Sun.COM #ifdef	__cplusplus
192*11596SJason.Beloro@Sun.COM }
193*11596SJason.Beloro@Sun.COM #endif
194*11596SJason.Beloro@Sun.COM 
195*11596SJason.Beloro@Sun.COM #endif	/* _SYS_PCIEV_H */
196