Home | History | Annotate | Download | only in ibnex
      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 2009 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 #ifndef _SYS_IB_IBNEX_IBNEX_H
     27 #define	_SYS_IB_IBNEX_IBNEX_H
     28 
     29 /*
     30  * ibnex.h
     31  * This file contains defines and structures used within the IB Nexus
     32  */
     33 
     34 #ifdef __cplusplus
     35 extern "C" {
     36 #endif
     37 
     38 #include <sys/sunndi.h>
     39 
     40 /* Defines for return codes within the IB nexus driver */
     41 typedef enum {
     42 	IBNEX_SUCCESS =	0,
     43 	IBNEX_FAILURE = -1,
     44 	IBNEX_OFFLINE_FAILED = -2,
     45 	IBNEX_BUSY = -3,
     46 	IBNEX_INVALID_NODE = -4
     47 } ibnex_rval_t;
     48 
     49 #define	IBNEX_IOC_GUID_LEN	33
     50 #define	IBNEX_PHCI_GUID_LEN	66
     51 
     52 /* IOC device node specific data */
     53 typedef struct ibnex_ioc_node_s {
     54 	ib_guid_t		iou_guid;	/* GUID of the IOU */
     55 	ib_guid_t		ioc_guid;	/* GUID of the IOC */
     56 	char			ioc_id_string[IB_DM_IOC_ID_STRING_LEN];
     57 	uint32_t		ioc_ngids;
     58 	/* This field will be non NULL only for diconnected IOCs */
     59 	ib_dm_ioc_ctrl_profile_t	*ioc_profile;
     60 	char				ioc_guid_str[IBNEX_IOC_GUID_LEN];
     61 	char				ioc_phci_guid[IBNEX_PHCI_GUID_LEN];
     62 } ibnex_ioc_node_t;
     63 
     64 /* DLPI device node specific data */
     65 typedef struct ibnex_port_node_s {
     66 	uint8_t			port_num;
     67 	int			port_commsvc_idx;
     68 	ib_guid_t		port_guid;
     69 	ib_guid_t		port_hcaguid;
     70 	ib_pkey_t		port_pkey;
     71 	dev_info_t		*port_pdip;
     72 } ibnex_port_node_t;
     73 
     74 /* Pseudo device node specific data */
     75 typedef struct ibnex_pseudo_node_s {
     76 	char			*pseudo_node_addr;	/* node addr of drvr */
     77 	char			*pseudo_unit_addr;	/* unit addr of drvr */
     78 	int			pseudo_unit_addr_len;	/* unit addr len */
     79 	char			*pseudo_devi_name;	/* name of driver */
     80 	int			pseudo_merge_node;	/* merge node */
     81 } ibnex_pseudo_node_t;
     82 
     83 /*
     84  * Defines for Child device node types. Note that these values are also
     85  * in use by usr/src/lib/cfgadm_plugins/ib/common/cfga_ib.h.
     86  * Any changes to these need to be reflected in that file as well.
     87  */
     88 typedef enum {
     89 	IBNEX_PORT_COMMSVC_NODE,
     90 	IBNEX_VPPA_COMMSVC_NODE,
     91 	IBNEX_HCASVC_COMMSVC_NODE,
     92 	IBNEX_IOC_NODE,
     93 	IBNEX_PSEUDO_NODE
     94 } ibnex_node_type_t;
     95 
     96 
     97 /*
     98  * Defines for Child device node state:
     99  *
    100  * By default the node is set to CONFIGURED state.
    101  *	CONFIGURED:---(bus_config/cfgadm configure)---->CONFIGURED
    102  *	CONFIGURED:----(cfgadm unconfigure:success)--->UNCONFIGURED
    103  *	CONFIGURED:----(cfgadm unconfigure:fail)--->still CONFIGURED
    104  *	UNCONFIGURED:----(cfgadm configure:success)--->CONFIGURED
    105  *
    106  * We maintain two additional states:
    107  *	CONFIGURING:---(bus_config/cfgadm configure in progress
    108  *	UNCONFIGURING:--(cfgadm unconfigure in progress)
    109  * This is maintained to avoid race conditions between multiple cfgadm
    110  * operations.
    111  */
    112 typedef enum ibnex_node_state_e {
    113 	IBNEX_CFGADM_CONFIGURED,	/* node is "configured" */
    114 	IBNEX_CFGADM_UNCONFIGURED,	/* node is "unconfigured" */
    115 	IBNEX_CFGADM_CONFIGURING,	/* node getting configured */
    116 	IBNEX_CFGADM_UNCONFIGURING	/* node getting unconfigured */
    117 } ibnex_node_state_t;
    118 
    119 /*
    120  * Defines for reprobe_state:
    121  * 	IBNEX_NODE_REPROBE_NOTIFY_ON_UPDATE
    122  *		Reprobe and notify if there is a property update
    123  *	IBNEX_NODE_REPROBE_NOTIFY_ALWAYS
    124  *		Reprobe and notify always.
    125  *	IBNEX_NODE_REPROBE_IOC_WAIT
    126  *		Reprobe for IOC apid waiting
    127  *
    128  * Device reprobes triggered by ibt_reprobe_dev will result in an DDI
    129  * event, even though no prepoerties have changed.
    130  */
    131 
    132 /*
    133  * Defines for node_ap_state:
    134  * IBNEX_NODE_AP_CONFIGURED
    135  * 	this node was not unconfigured by cfgadm.
    136  * IBNEX_NODE_AP_UNCONFIGURED
    137  * 	this node has been unconfigured by cfgadm.
    138  * IBNEX_NODE_AP_CONFIGURING
    139  * 	this node is being configured by cfgadm
    140  */
    141 #define	IBNEX_NODE_AP_CONFIGURED	0x0
    142 #define	IBNEX_NODE_AP_UNCONFIGURED	0x1
    143 #define	IBNEX_NODE_AP_CONFIGURING	0x2
    144 
    145 #define	IBNEX_NODE_REPROBE_NOTIFY_ON_UPDATE	0x01
    146 #define	IBNEX_NODE_REPROBE_NOTIFY_ALWAYS	0x02
    147 #define	IBNEX_NODE_REPROBE_IOC_WAIT			0x04
    148 
    149 /* Node specific information, stored as dev_info_t private data */
    150 typedef struct ibnex_node_data_s {
    151 	dev_info_t		*node_dip;
    152 	union {
    153 		ibnex_ioc_node_t	ioc_node;
    154 		ibnex_port_node_t	port_node;
    155 		ibnex_pseudo_node_t	pseudo_node;
    156 	} node_data;
    157 	struct ibnex_node_data_s *node_next;
    158 	struct ibnex_node_data_s *node_prev;
    159 	ibnex_node_type_t	node_type;
    160 	ibnex_node_state_t	node_state;
    161 	int			node_reprobe_state;	/* Node reprobe flag */
    162 	unsigned int		node_ap_state;
    163 } ibnex_node_data_t;
    164 
    165 /*
    166  * The fields of IOC and Port node are initialized when the
    167  * device node is created. These are read only for the rest
    168  * of the IBnexus driver.
    169  */
    170 _NOTE(SCHEME_PROTECTS_DATA("stable data", ibnex_ioc_node_s))
    171 _NOTE(SCHEME_PROTECTS_DATA("stable data", ibnex_port_node_s))
    172 _NOTE(SCHEME_PROTECTS_DATA("stable data", ibnex_pseudo_node_s))
    173 _NOTE(SCHEME_PROTECTS_DATA("stable data", ibnex_node_data_s))
    174 
    175 #define	IBNEX_VALID_NODE_TYPE(n)	\
    176 	(((n)->node_type == IBNEX_PORT_COMMSVC_NODE) || \
    177 	((n)->node_type == IBNEX_VPPA_COMMSVC_NODE) || \
    178 	((n)->node_type == IBNEX_HCASVC_COMMSVC_NODE) || \
    179 	((n)->node_type == IBNEX_IOC_NODE) || \
    180 	((n)->node_type == IBNEX_PSEUDO_NODE))
    181 
    182 #define	IBNEX_COMMSVC_NODE_TYPE(n)	\
    183 	(((n)->node_type == IBNEX_PORT_COMMSVC_NODE) || \
    184 	((n)->node_type == IBNEX_VPPA_COMMSVC_NODE) || \
    185 	((n)->node_type == IBNEX_HCASVC_COMMSVC_NODE))
    186 
    187 /*
    188  * Definition for the IB nexus global per-instance structure.
    189  * IB nexus supports only one instance.
    190  */
    191 typedef struct ibnex_s {
    192 	dev_info_t		*ibnex_dip;
    193 	kmutex_t		ibnex_mutex;
    194 	int			ibnex_num_comm_svcs;
    195 	char			**ibnex_comm_svc_names;
    196 	int			ibnex_nvppa_comm_svcs;
    197 	char			**ibnex_vppa_comm_svc_names;
    198 	int			ibnex_nhcasvc_comm_svcs;
    199 	char			**ibnex_hcasvc_comm_svc_names;
    200 	ibnex_node_data_t	*ibnex_port_node_head;
    201 	ibnex_node_data_t	*ibnex_ioc_node_head;
    202 	ibnex_node_data_t	*ibnex_pseudo_node_head;
    203 
    204 	/*
    205 	 * NDI Event handle for -all- ibnexus events
    206 	 * Event Cookie for IB_PROP_UPDATE_EVENT event
    207 	 */
    208 	ndi_event_hdl_t		ibnex_ndi_event_hdl;
    209 	ddi_eventcookie_t	ibnex_prop_update_evt_cookie;
    210 
    211 	/* Flags & condition variables for reprobe handling */
    212 	int					ibnex_reprobe_state;
    213 	kcondvar_t			ibnex_reprobe_cv;
    214 
    215 	/* Count of disconnected IOCs still configured */
    216 	int					ibnex_num_disconnect_iocs;
    217 
    218 	/* Pseudo nodes inited from ibnex_get_snapshot? */
    219 	int			ibnex_pseudo_inited;
    220 	/*
    221 	 * IOC list used by all HCAs.
    222 	 */
    223 	kcondvar_t		ibnex_ioc_list_cv;
    224 	uint32_t		ibnex_ioc_list_state;
    225 	ibdm_ioc_info_t		*ibnex_ioc_list;
    226 } ibnex_t;
    227 
    228 /*
    229  * States for ibnex_ioc_list_state
    230  */
    231 #define	IBNEX_IOC_LIST_READY	0x0
    232 #define	IBNEX_IOC_LIST_RENEW	0x1
    233 #define	IBNEX_IOC_LIST_ACCESS	0x2
    234 
    235 /*
    236  * States for ibnex_reprobe_state
    237  *	0 to REPROBE_ALL_PROGRESS
    238  *		Reprobe all when no reprobes pending
    239  *	REPROBE_ALL_PROGRESS to REPROBE_ALL_WAIT
    240  *		Reprobe all request when another in progress
    241  *	0 to REPROBE_IOC_WAIT
    242  *		Waiting for One or more reprobe_ioc to complete
    243  *
    244  * Reprobe logic will ensure :
    245  *	1. A single reprobe all at any time.
    246  *	2. No individual IOC reprobe overlaps with reprobe all.
    247  *	3. Reprobe for multiple IOCs can be in parallel
    248  *	4. Single reprobe for each IOC.
    249  */
    250 #define	IBNEX_REPROBE_ALL_PROGRESS	0x01
    251 #define	IBNEX_REPROBE_ALL_WAIT		0x02
    252 #define	IBNEX_REPROBE_IOC_WAIT		0x04
    253 
    254 /* Defines for creating and binding device nodes.  */
    255 #define	IBNEX_MAX_COMPAT_NAMES		6
    256 #define	IBNEX_MAX_IBPORT_COMPAT_NAMES	3
    257 #define	IBNEX_MAX_COMPAT_LEN		48
    258 #define	IBNEX_MAX_COMPAT_PROP_SZ	\
    259 	IBNEX_MAX_COMPAT_NAMES * IBNEX_MAX_COMPAT_LEN
    260 #define	IBNEX_MAX_IBPORT_COMPAT_PROP_SZ	\
    261 	IBNEX_MAX_IBPORT_COMPAT_NAMES * IBNEX_MAX_COMPAT_LEN
    262 #define	IBNEX_DEVFS_ENUMERATE		0x1	/* enumerate via devfs(7fs) */
    263 #define	IBNEX_CFGADM_ENUMERATE		0x2	/* enumerate via cfgadm */
    264 
    265 #define	IBNEX_MAX_NODEADDR_SZ		35
    266 
    267 /* Define for forming the unit address from GUID and class string */
    268 #define	IBNEX_FORM_GUID(buf, size, guid) \
    269 		(void) snprintf((buf), (size), "%llX", (longlong_t)guid);
    270 
    271 #define	IBNEX_INVALID_PKEY(pkey)	\
    272 		(((pkey) == IB_PKEY_INVALID_FULL) || \
    273 		((pkey) == IB_PKEY_INVALID_LIMITED))
    274 
    275 /*
    276  * Defines for the tags of IB DDI events
    277  */
    278 typedef enum {
    279 		IB_EVENT_TAG_PROP_UPDATE = 0
    280 } ib_ddi_event_tag_t;
    281 
    282 /* Definations for IB HW in device tree status */
    283 #define	IBNEX_DEVTREE_NOT_CHECKED	-1
    284 #define	IBNEX_HW_NOT_IN_DEVTREE		0
    285 #define	IBNEX_HW_IN_DEVTREE		1
    286 
    287 #ifdef __cplusplus
    288 }
    289 #endif
    290 
    291 #endif	/* _SYS_IB_IBNEX_IBNEX_H */
    292