1 /*
2  * Copyright (c) 2009 Voltaire, Inc. All rights reserved.
3  * Copyright (c) 2008 Lawrence Livermore National Lab.  All rights reserved.
4  * Copyright (c) 2010-2011 Mellanox Technologies LTD.  All rights reserved.
5  *
6  * This software is available to you under a choice of one of two
7  * licenses.  You may choose to be licensed under the terms of the GNU
8  * General Public License (GPL) Version 2, available from the file
9  * COPYING in the main directory of this source tree, or the
10  * OpenIB.org BSD license below:
11  *
12  *     Redistribution and use in source and binary forms, with or
13  *     without modification, are permitted provided that the following
14  *     conditions are met:
15  *
16  *      - Redistributions of source code must retain the above
17  *        copyright notice, this list of conditions and the following
18  *        disclaimer.
19  *
20  *      - Redistributions in binary form must reproduce the above
21  *        copyright notice, this list of conditions and the following
22  *        disclaimer in the documentation and/or other materials
23  *        provided with the distribution.
24  *
25  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32  * SOFTWARE.
33  *
34  */
35 
36 #ifndef _IBNETDISC_H_
37 #define _IBNETDISC_H_
38 
39 #include <stdio.h>
40 #include <infiniband/mad.h>
41 #include <iba/ib_types.h>
42 
43 #include <infiniband/ibnetdisc_osd.h>
44 
45 #ifdef __cplusplus
46 extern "C" {
47 #endif
48 
49 struct ibnd_chassis;		/* forward declare */
50 struct ibnd_port;		/* forward declare */
51 
52 #define CHASSIS_TYPE_SIZE 20
53 
54 /** =========================================================================
55  * Node
56  */
57 typedef struct ibnd_node {
58 	struct ibnd_node *next;	/* all node list in fabric */
59 
60 	ib_portid_t path_portid;	/* path from "from_node" */
61 					/* NOTE: this is not valid on a fabric
62 					 * read from a cache file */
63 	uint16_t smalid;
64 	uint8_t smalmc;
65 
66 	/* quick cache of switchinfo below */
67 	int smaenhsp0;
68 	/* use libibmad decoder functions for switchinfo */
69 	uint8_t switchinfo[IB_SMP_DATA_SIZE];
70 
71 	/* quick cache of info below */
72 	uint64_t guid;
73 	int type;
74 	int numports;
75 	/* use libibmad decoder functions for info */
76 	uint8_t info[IB_SMP_DATA_SIZE];
77 
78 	char nodedesc[IB_SMP_DATA_SIZE];
79 
80 	struct ibnd_port **ports;	/* array of ports, indexed by port number
81 					   ports[1] == port 1,
82 					   ports[2] == port 2,
83 					   etc...
84 					   Any port in the array MAY BE NULL!
85 					   Most notable is non-switches have no
86 					   port 0 therefore node.ports[0] == NULL
87 					   for those nodes */
88 
89 	/* chassis info */
90 	struct ibnd_node *next_chassis_node;	/* next node in ibnd_chassis_t->nodes */
91 	struct ibnd_chassis *chassis;	/* if != NULL the chassis this node belongs to */
92 	unsigned char ch_type;
93 	char ch_type_str[CHASSIS_TYPE_SIZE];
94 	unsigned char ch_anafanum;
95 	unsigned char ch_slotnum;
96 	unsigned char ch_slot;
97 
98 	/* internal use only */
99 	unsigned char ch_found;
100 	struct ibnd_node *htnext;	/* hash table list */
101 	struct ibnd_node *type_next;	/* next based on type */
102 } ibnd_node_t;
103 
104 /** =========================================================================
105  * Port
106  */
107 typedef struct ibnd_port {
108 	uint64_t guid;
109 	int portnum;
110 	int ext_portnum;	/* optional if != 0 external port num */
111 	ibnd_node_t *node;	/* node this port belongs to */
112 	struct ibnd_port *remoteport;	/* null if SMA, or does not exist */
113 	/* quick cache of info below */
114 	uint16_t base_lid;
115 	uint8_t lmc;
116 	/* use libibmad decoder functions for info */
117 	uint8_t info[IB_SMP_DATA_SIZE];
118 	uint8_t ext_info[IB_SMP_DATA_SIZE];
119 
120 	/* internal use only */
121 	struct ibnd_port *htnext;
122 } ibnd_port_t;
123 
124 /** =========================================================================
125  * Chassis
126  */
127 typedef struct ibnd_chassis {
128 	struct ibnd_chassis *next;
129 	uint64_t chassisguid;
130 	unsigned char chassisnum;
131 
132 	/* generic grouping by SystemImageGUID */
133 	unsigned char nodecount;
134 	ibnd_node_t *nodes;
135 
136 	/* specific to voltaire type nodes */
137 #define SPINES_MAX_NUM 18
138 #define LINES_MAX_NUM 36
139 	ibnd_node_t *spinenode[SPINES_MAX_NUM + 1];
140 	ibnd_node_t *linenode[LINES_MAX_NUM + 1];
141 } ibnd_chassis_t;
142 
143 #define HTSZ 137
144 
145 /* define config flags */
146 #define IBND_CONFIG_MLX_EPI (1 << 0)
147 
148 typedef struct ibnd_config {
149 	unsigned max_smps;
150 	unsigned show_progress;
151 	unsigned max_hops;
152 	unsigned debug;
153 	unsigned timeout_ms;
154 	unsigned retries;
155 	uint32_t flags;
156 	uint64_t mkey;
157 	uint8_t pad[44];
158 } ibnd_config_t;
159 
160 /** =========================================================================
161  * Fabric
162  * Main fabric object which is returned and represents the data discovered
163  */
164 typedef struct ibnd_fabric {
165 	/* the node the discover was initiated from
166 	 * "from" parameter in ibnd_discover_fabric
167 	 * or by default the node you ar running on
168 	 */
169 	ibnd_node_t *from_node;
170 	int from_portnum;
171 
172 	/* NULL term list of all nodes in the fabric */
173 	ibnd_node_t *nodes;
174 	/* NULL terminated list of all chassis found in the fabric */
175 	ibnd_chassis_t *chassis;
176 	unsigned maxhops_discovered;
177 	unsigned total_mads_used;
178 
179 	/* internal use only */
180 	ibnd_node_t *nodestbl[HTSZ];
181 	ibnd_port_t *portstbl[HTSZ];
182 	ibnd_node_t *switches;
183 	ibnd_node_t *ch_adapters;
184 	ibnd_node_t *routers;
185 } ibnd_fabric_t;
186 
187 /** =========================================================================
188  * Initialization (fabric operations)
189  */
190 
191 IBND_EXPORT ibnd_fabric_t *ibnd_discover_fabric(char * ca_name,
192 					       int ca_port,
193 					       ib_portid_t * from,
194 					       struct ibnd_config *config);
195 	/**
196 	 * ca_name: (optional) name of the CA to use
197 	 * ca_port: (optional) CA port to use
198 	 * from: (optional) specify the node to start scanning from.
199 	 *       If NULL start from the CA/CA port specified
200 	 * config: (optional) additional config options for the scan
201 	 */
202 IBND_EXPORT void ibnd_destroy_fabric(ibnd_fabric_t * fabric);
203 
204 IBND_EXPORT ibnd_fabric_t *ibnd_load_fabric(const char *file,
205 					   unsigned int flags);
206 
207 IBND_EXPORT int ibnd_cache_fabric(ibnd_fabric_t * fabric, const char *file,
208 				 unsigned int flags);
209 
210 #define IBND_CACHE_FABRIC_FLAG_DEFAULT      0x0000
211 #define IBND_CACHE_FABRIC_FLAG_NO_OVERWRITE 0x0001
212 
213 /** =========================================================================
214  * Node operations
215  */
216 IBND_EXPORT ibnd_node_t *ibnd_find_node_guid(ibnd_fabric_t * fabric,
217 					    uint64_t guid);
218 IBND_EXPORT ibnd_node_t *ibnd_find_node_dr(ibnd_fabric_t * fabric, char *dr_str);
219 
220 typedef void (*ibnd_iter_node_func_t) (ibnd_node_t * node, void *user_data);
221 IBND_EXPORT void ibnd_iter_nodes(ibnd_fabric_t * fabric,
222 				ibnd_iter_node_func_t func, void *user_data);
223 IBND_EXPORT void ibnd_iter_nodes_type(ibnd_fabric_t * fabric,
224 				     ibnd_iter_node_func_t func,
225 				     int node_type, void *user_data);
226 
227 /** =========================================================================
228  * Port operations
229  */
230 IBND_EXPORT ibnd_port_t *ibnd_find_port_guid(ibnd_fabric_t * fabric,
231 					uint64_t guid);
232 IBND_EXPORT ibnd_port_t *ibnd_find_port_dr(ibnd_fabric_t * fabric,
233 					char *dr_str);
234 IBND_EXPORT ibnd_port_t *ibnd_find_port_lid(ibnd_fabric_t * fabric,
235 					    uint16_t lid);
236 
237 typedef void (*ibnd_iter_port_func_t) (ibnd_port_t * port, void *user_data);
238 IBND_EXPORT void ibnd_iter_ports(ibnd_fabric_t * fabric,
239 				ibnd_iter_port_func_t func, void *user_data);
240 
241 /** =========================================================================
242  * Chassis queries
243  */
244 IBND_EXPORT uint64_t ibnd_get_chassis_guid(ibnd_fabric_t * fabric,
245 					  unsigned char chassisnum);
246 IBND_EXPORT char *ibnd_get_chassis_type(ibnd_node_t * node);
247 IBND_EXPORT char *ibnd_get_chassis_slot_str(ibnd_node_t * node,
248 					   char *str, size_t size);
249 
250 IBND_EXPORT int ibnd_is_xsigo_guid(uint64_t guid);
251 IBND_EXPORT int ibnd_is_xsigo_tca(uint64_t guid);
252 IBND_EXPORT int ibnd_is_xsigo_hca(uint64_t guid);
253 
254 #ifdef __cplusplus
255 }
256 #endif
257 
258 #endif				/* _IBNETDISC_H_ */
259