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