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
46extern "C" {
47#endif
48
49struct ibnd_chassis;		/* forward declare */
50struct ibnd_port;		/* forward declare */
51
52#define CHASSIS_TYPE_SIZE 20
53
54/** =========================================================================
55 * Node
56 */
57typedef 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 */
107typedef 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 */
127typedef 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
148typedef 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 */
164typedef 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
191IBND_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	 */
202IBND_EXPORT void ibnd_destroy_fabric(ibnd_fabric_t * fabric);
203
204IBND_EXPORT ibnd_fabric_t *ibnd_load_fabric(const char *file,
205					   unsigned int flags);
206
207IBND_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 */
216IBND_EXPORT ibnd_node_t *ibnd_find_node_guid(ibnd_fabric_t * fabric,
217					    uint64_t guid);
218IBND_EXPORT ibnd_node_t *ibnd_find_node_dr(ibnd_fabric_t * fabric, char *dr_str);
219
220typedef void (*ibnd_iter_node_func_t) (ibnd_node_t * node, void *user_data);
221IBND_EXPORT void ibnd_iter_nodes(ibnd_fabric_t * fabric,
222				ibnd_iter_node_func_t func, void *user_data);
223IBND_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 */
230IBND_EXPORT ibnd_port_t *ibnd_find_port_guid(ibnd_fabric_t * fabric,
231					uint64_t guid);
232IBND_EXPORT ibnd_port_t *ibnd_find_port_dr(ibnd_fabric_t * fabric,
233					char *dr_str);
234IBND_EXPORT ibnd_port_t *ibnd_find_port_lid(ibnd_fabric_t * fabric,
235					    uint16_t lid);
236
237typedef void (*ibnd_iter_port_func_t) (ibnd_port_t * port, void *user_data);
238IBND_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 */
244IBND_EXPORT uint64_t ibnd_get_chassis_guid(ibnd_fabric_t * fabric,
245					  unsigned char chassisnum);
246IBND_EXPORT char *ibnd_get_chassis_type(ibnd_node_t * node);
247IBND_EXPORT char *ibnd_get_chassis_slot_str(ibnd_node_t * node,
248					   char *str, size_t size);
249
250IBND_EXPORT int ibnd_is_xsigo_guid(uint64_t guid);
251IBND_EXPORT int ibnd_is_xsigo_tca(uint64_t guid);
252IBND_EXPORT int ibnd_is_xsigo_hca(uint64_t guid);
253
254#ifdef __cplusplus
255}
256#endif
257
258#endif				/* _IBNETDISC_H_ */
259