1*d6b92ffaSHans Petter Selasky /*
2*d6b92ffaSHans Petter Selasky * Copyright (c) 2004-2009 Voltaire Inc. All rights reserved.
3*d6b92ffaSHans Petter Selasky * Copyright (c) 2007 Xsigo Systems Inc. All rights reserved.
4*d6b92ffaSHans Petter Selasky * Copyright (c) 2008 Lawrence Livermore National Lab. All rights reserved.
5*d6b92ffaSHans Petter Selasky * Copyright (c) 2010 HNR Consulting. All rights reserved.
6*d6b92ffaSHans Petter Selasky *
7*d6b92ffaSHans Petter Selasky * This software is available to you under a choice of one of two
8*d6b92ffaSHans Petter Selasky * licenses. You may choose to be licensed under the terms of the GNU
9*d6b92ffaSHans Petter Selasky * General Public License (GPL) Version 2, available from the file
10*d6b92ffaSHans Petter Selasky * COPYING in the main directory of this source tree, or the
11*d6b92ffaSHans Petter Selasky * OpenIB.org BSD license below:
12*d6b92ffaSHans Petter Selasky *
13*d6b92ffaSHans Petter Selasky * Redistribution and use in source and binary forms, with or
14*d6b92ffaSHans Petter Selasky * without modification, are permitted provided that the following
15*d6b92ffaSHans Petter Selasky * conditions are met:
16*d6b92ffaSHans Petter Selasky *
17*d6b92ffaSHans Petter Selasky * - Redistributions of source code must retain the above
18*d6b92ffaSHans Petter Selasky * copyright notice, this list of conditions and the following
19*d6b92ffaSHans Petter Selasky * disclaimer.
20*d6b92ffaSHans Petter Selasky *
21*d6b92ffaSHans Petter Selasky * - Redistributions in binary form must reproduce the above
22*d6b92ffaSHans Petter Selasky * copyright notice, this list of conditions and the following
23*d6b92ffaSHans Petter Selasky * disclaimer in the documentation and/or other materials
24*d6b92ffaSHans Petter Selasky * provided with the distribution.
25*d6b92ffaSHans Petter Selasky *
26*d6b92ffaSHans Petter Selasky * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27*d6b92ffaSHans Petter Selasky * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28*d6b92ffaSHans Petter Selasky * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29*d6b92ffaSHans Petter Selasky * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
30*d6b92ffaSHans Petter Selasky * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
31*d6b92ffaSHans Petter Selasky * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
32*d6b92ffaSHans Petter Selasky * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33*d6b92ffaSHans Petter Selasky * SOFTWARE.
34*d6b92ffaSHans Petter Selasky *
35*d6b92ffaSHans Petter Selasky */
36*d6b92ffaSHans Petter Selasky
37*d6b92ffaSHans Petter Selasky /*========================================================*/
38*d6b92ffaSHans Petter Selasky /* FABRIC SCANNER SPECIFIC DATA */
39*d6b92ffaSHans Petter Selasky /*========================================================*/
40*d6b92ffaSHans Petter Selasky
41*d6b92ffaSHans Petter Selasky #if HAVE_CONFIG_H
42*d6b92ffaSHans Petter Selasky #include <config.h>
43*d6b92ffaSHans Petter Selasky #endif /* HAVE_CONFIG_H */
44*d6b92ffaSHans Petter Selasky
45*d6b92ffaSHans Petter Selasky #include <stdlib.h>
46*d6b92ffaSHans Petter Selasky #include <inttypes.h>
47*d6b92ffaSHans Petter Selasky
48*d6b92ffaSHans Petter Selasky #include <infiniband/mad.h>
49*d6b92ffaSHans Petter Selasky
50*d6b92ffaSHans Petter Selasky #include "internal.h"
51*d6b92ffaSHans Petter Selasky #include "chassis.h"
52*d6b92ffaSHans Petter Selasky
53*d6b92ffaSHans Petter Selasky static char *ChassisTypeStr[] =
54*d6b92ffaSHans Petter Selasky { "", "ISR9288", "ISR9096", "ISR2012", "ISR2004", "ISR4700", "ISR4200" };
55*d6b92ffaSHans Petter Selasky static char *ChassisSlotTypeStr[] = { "", "Line", "Spine", "SRBD" };
56*d6b92ffaSHans Petter Selasky
57*d6b92ffaSHans Petter Selasky typedef struct chassis_scan {
58*d6b92ffaSHans Petter Selasky ibnd_chassis_t *first_chassis;
59*d6b92ffaSHans Petter Selasky ibnd_chassis_t *current_chassis;
60*d6b92ffaSHans Petter Selasky ibnd_chassis_t *last_chassis;
61*d6b92ffaSHans Petter Selasky } chassis_scan_t;
62*d6b92ffaSHans Petter Selasky
ibnd_get_chassis_type(ibnd_node_t * node)63*d6b92ffaSHans Petter Selasky char *ibnd_get_chassis_type(ibnd_node_t * node)
64*d6b92ffaSHans Petter Selasky {
65*d6b92ffaSHans Petter Selasky int chassis_type;
66*d6b92ffaSHans Petter Selasky
67*d6b92ffaSHans Petter Selasky if (!node) {
68*d6b92ffaSHans Petter Selasky IBND_DEBUG("node parameter NULL\n");
69*d6b92ffaSHans Petter Selasky return NULL;
70*d6b92ffaSHans Petter Selasky }
71*d6b92ffaSHans Petter Selasky
72*d6b92ffaSHans Petter Selasky if (!node->chassis)
73*d6b92ffaSHans Petter Selasky return NULL;
74*d6b92ffaSHans Petter Selasky
75*d6b92ffaSHans Petter Selasky chassis_type = mad_get_field(node->info, 0, IB_NODE_VENDORID_F);
76*d6b92ffaSHans Petter Selasky
77*d6b92ffaSHans Petter Selasky switch (chassis_type)
78*d6b92ffaSHans Petter Selasky {
79*d6b92ffaSHans Petter Selasky case VTR_VENDOR_ID: /* Voltaire chassis */
80*d6b92ffaSHans Petter Selasky {
81*d6b92ffaSHans Petter Selasky if (node->ch_type == UNRESOLVED_CT || node->ch_type > ISR4200_CT)
82*d6b92ffaSHans Petter Selasky return NULL;
83*d6b92ffaSHans Petter Selasky return ChassisTypeStr[node->ch_type];
84*d6b92ffaSHans Petter Selasky }
85*d6b92ffaSHans Petter Selasky case MLX_VENDOR_ID:
86*d6b92ffaSHans Petter Selasky {
87*d6b92ffaSHans Petter Selasky if (node->ch_type_str[0] == '\0')
88*d6b92ffaSHans Petter Selasky return NULL;
89*d6b92ffaSHans Petter Selasky return node->ch_type_str;
90*d6b92ffaSHans Petter Selasky }
91*d6b92ffaSHans Petter Selasky default:
92*d6b92ffaSHans Petter Selasky {
93*d6b92ffaSHans Petter Selasky break;
94*d6b92ffaSHans Petter Selasky }
95*d6b92ffaSHans Petter Selasky }
96*d6b92ffaSHans Petter Selasky return NULL;
97*d6b92ffaSHans Petter Selasky }
98*d6b92ffaSHans Petter Selasky
ibnd_get_chassis_slot_str(ibnd_node_t * node,char * str,size_t size)99*d6b92ffaSHans Petter Selasky char *ibnd_get_chassis_slot_str(ibnd_node_t * node, char *str, size_t size)
100*d6b92ffaSHans Petter Selasky {
101*d6b92ffaSHans Petter Selasky int vendor_id;
102*d6b92ffaSHans Petter Selasky
103*d6b92ffaSHans Petter Selasky if (!node) {
104*d6b92ffaSHans Petter Selasky IBND_DEBUG("node parameter NULL\n");
105*d6b92ffaSHans Petter Selasky return NULL;
106*d6b92ffaSHans Petter Selasky }
107*d6b92ffaSHans Petter Selasky
108*d6b92ffaSHans Petter Selasky /* Currently, only if Voltaire or Mellanox chassis */
109*d6b92ffaSHans Petter Selasky vendor_id = mad_get_field(node->info, 0,IB_NODE_VENDORID_F);
110*d6b92ffaSHans Petter Selasky
111*d6b92ffaSHans Petter Selasky if ((vendor_id != VTR_VENDOR_ID) && (vendor_id != MLX_VENDOR_ID))
112*d6b92ffaSHans Petter Selasky return NULL;
113*d6b92ffaSHans Petter Selasky if (!node->chassis)
114*d6b92ffaSHans Petter Selasky return NULL;
115*d6b92ffaSHans Petter Selasky if (node->ch_slot == UNRESOLVED_CS || node->ch_slot > SRBD_CS)
116*d6b92ffaSHans Petter Selasky return NULL;
117*d6b92ffaSHans Petter Selasky if (!str)
118*d6b92ffaSHans Petter Selasky return NULL;
119*d6b92ffaSHans Petter Selasky snprintf(str, size, "%s %d Chip %d", ChassisSlotTypeStr[node->ch_slot],
120*d6b92ffaSHans Petter Selasky node->ch_slotnum, node->ch_anafanum);
121*d6b92ffaSHans Petter Selasky return str;
122*d6b92ffaSHans Petter Selasky }
123*d6b92ffaSHans Petter Selasky
find_chassisnum(ibnd_fabric_t * fabric,unsigned char chassisnum)124*d6b92ffaSHans Petter Selasky static ibnd_chassis_t *find_chassisnum(ibnd_fabric_t * fabric,
125*d6b92ffaSHans Petter Selasky unsigned char chassisnum)
126*d6b92ffaSHans Petter Selasky {
127*d6b92ffaSHans Petter Selasky ibnd_chassis_t *current;
128*d6b92ffaSHans Petter Selasky
129*d6b92ffaSHans Petter Selasky for (current = fabric->chassis; current; current = current->next)
130*d6b92ffaSHans Petter Selasky if (current->chassisnum == chassisnum)
131*d6b92ffaSHans Petter Selasky return current;
132*d6b92ffaSHans Petter Selasky
133*d6b92ffaSHans Petter Selasky return NULL;
134*d6b92ffaSHans Petter Selasky }
135*d6b92ffaSHans Petter Selasky
topspin_chassisguid(uint64_t guid)136*d6b92ffaSHans Petter Selasky static uint64_t topspin_chassisguid(uint64_t guid)
137*d6b92ffaSHans Petter Selasky {
138*d6b92ffaSHans Petter Selasky /* Byte 3 in system image GUID is chassis type, and */
139*d6b92ffaSHans Petter Selasky /* Byte 4 is location ID (slot) so just mask off byte 4 */
140*d6b92ffaSHans Petter Selasky return guid & 0xffffffff00ffffffULL;
141*d6b92ffaSHans Petter Selasky }
142*d6b92ffaSHans Petter Selasky
ibnd_is_xsigo_guid(uint64_t guid)143*d6b92ffaSHans Petter Selasky int ibnd_is_xsigo_guid(uint64_t guid)
144*d6b92ffaSHans Petter Selasky {
145*d6b92ffaSHans Petter Selasky if ((guid & 0xffffff0000000000ULL) == 0x0013970000000000ULL)
146*d6b92ffaSHans Petter Selasky return 1;
147*d6b92ffaSHans Petter Selasky else
148*d6b92ffaSHans Petter Selasky return 0;
149*d6b92ffaSHans Petter Selasky }
150*d6b92ffaSHans Petter Selasky
is_xsigo_leafone(uint64_t guid)151*d6b92ffaSHans Petter Selasky static int is_xsigo_leafone(uint64_t guid)
152*d6b92ffaSHans Petter Selasky {
153*d6b92ffaSHans Petter Selasky if ((guid & 0xffffffffff000000ULL) == 0x0013970102000000ULL)
154*d6b92ffaSHans Petter Selasky return 1;
155*d6b92ffaSHans Petter Selasky else
156*d6b92ffaSHans Petter Selasky return 0;
157*d6b92ffaSHans Petter Selasky }
158*d6b92ffaSHans Petter Selasky
ibnd_is_xsigo_hca(uint64_t guid)159*d6b92ffaSHans Petter Selasky int ibnd_is_xsigo_hca(uint64_t guid)
160*d6b92ffaSHans Petter Selasky {
161*d6b92ffaSHans Petter Selasky /* NodeType 2 is HCA */
162*d6b92ffaSHans Petter Selasky if ((guid & 0xffffffff00000000ULL) == 0x0013970200000000ULL)
163*d6b92ffaSHans Petter Selasky return 1;
164*d6b92ffaSHans Petter Selasky else
165*d6b92ffaSHans Petter Selasky return 0;
166*d6b92ffaSHans Petter Selasky }
167*d6b92ffaSHans Petter Selasky
ibnd_is_xsigo_tca(uint64_t guid)168*d6b92ffaSHans Petter Selasky int ibnd_is_xsigo_tca(uint64_t guid)
169*d6b92ffaSHans Petter Selasky {
170*d6b92ffaSHans Petter Selasky /* NodeType 3 is TCA */
171*d6b92ffaSHans Petter Selasky if ((guid & 0xffffffff00000000ULL) == 0x0013970300000000ULL)
172*d6b92ffaSHans Petter Selasky return 1;
173*d6b92ffaSHans Petter Selasky else
174*d6b92ffaSHans Petter Selasky return 0;
175*d6b92ffaSHans Petter Selasky }
176*d6b92ffaSHans Petter Selasky
is_xsigo_ca(uint64_t guid)177*d6b92ffaSHans Petter Selasky static int is_xsigo_ca(uint64_t guid)
178*d6b92ffaSHans Petter Selasky {
179*d6b92ffaSHans Petter Selasky if (ibnd_is_xsigo_hca(guid) || ibnd_is_xsigo_tca(guid))
180*d6b92ffaSHans Petter Selasky return 1;
181*d6b92ffaSHans Petter Selasky else
182*d6b92ffaSHans Petter Selasky return 0;
183*d6b92ffaSHans Petter Selasky }
184*d6b92ffaSHans Petter Selasky
is_xsigo_switch(uint64_t guid)185*d6b92ffaSHans Petter Selasky static int is_xsigo_switch(uint64_t guid)
186*d6b92ffaSHans Petter Selasky {
187*d6b92ffaSHans Petter Selasky if ((guid & 0xffffffff00000000ULL) == 0x0013970100000000ULL)
188*d6b92ffaSHans Petter Selasky return 1;
189*d6b92ffaSHans Petter Selasky else
190*d6b92ffaSHans Petter Selasky return 0;
191*d6b92ffaSHans Petter Selasky }
192*d6b92ffaSHans Petter Selasky
xsigo_chassisguid(ibnd_node_t * node)193*d6b92ffaSHans Petter Selasky static uint64_t xsigo_chassisguid(ibnd_node_t * node)
194*d6b92ffaSHans Petter Selasky {
195*d6b92ffaSHans Petter Selasky uint64_t sysimgguid =
196*d6b92ffaSHans Petter Selasky mad_get_field64(node->info, 0, IB_NODE_SYSTEM_GUID_F);
197*d6b92ffaSHans Petter Selasky uint64_t remote_sysimgguid;
198*d6b92ffaSHans Petter Selasky
199*d6b92ffaSHans Petter Selasky if (!is_xsigo_ca(sysimgguid)) {
200*d6b92ffaSHans Petter Selasky /* Byte 3 is NodeType and byte 4 is PortType */
201*d6b92ffaSHans Petter Selasky /* If NodeType is 1 (switch), PortType is masked */
202*d6b92ffaSHans Petter Selasky if (is_xsigo_switch(sysimgguid))
203*d6b92ffaSHans Petter Selasky return sysimgguid & 0xffffffff00ffffffULL;
204*d6b92ffaSHans Petter Selasky else
205*d6b92ffaSHans Petter Selasky return sysimgguid;
206*d6b92ffaSHans Petter Selasky } else {
207*d6b92ffaSHans Petter Selasky if (!node->ports || !node->ports[1])
208*d6b92ffaSHans Petter Selasky return 0;
209*d6b92ffaSHans Petter Selasky
210*d6b92ffaSHans Petter Selasky /* Is there a peer port ? */
211*d6b92ffaSHans Petter Selasky if (!node->ports[1]->remoteport)
212*d6b92ffaSHans Petter Selasky return sysimgguid;
213*d6b92ffaSHans Petter Selasky
214*d6b92ffaSHans Petter Selasky /* If peer port is Leaf 1, use its chassis GUID */
215*d6b92ffaSHans Petter Selasky remote_sysimgguid =
216*d6b92ffaSHans Petter Selasky mad_get_field64(node->ports[1]->remoteport->node->info, 0,
217*d6b92ffaSHans Petter Selasky IB_NODE_SYSTEM_GUID_F);
218*d6b92ffaSHans Petter Selasky if (is_xsigo_leafone(remote_sysimgguid))
219*d6b92ffaSHans Petter Selasky return remote_sysimgguid & 0xffffffff00ffffffULL;
220*d6b92ffaSHans Petter Selasky else
221*d6b92ffaSHans Petter Selasky return sysimgguid;
222*d6b92ffaSHans Petter Selasky }
223*d6b92ffaSHans Petter Selasky }
224*d6b92ffaSHans Petter Selasky
get_chassisguid(ibnd_node_t * node)225*d6b92ffaSHans Petter Selasky static uint64_t get_chassisguid(ibnd_node_t * node)
226*d6b92ffaSHans Petter Selasky {
227*d6b92ffaSHans Petter Selasky uint32_t vendid = mad_get_field(node->info, 0, IB_NODE_VENDORID_F);
228*d6b92ffaSHans Petter Selasky uint64_t sysimgguid =
229*d6b92ffaSHans Petter Selasky mad_get_field64(node->info, 0, IB_NODE_SYSTEM_GUID_F);
230*d6b92ffaSHans Petter Selasky
231*d6b92ffaSHans Petter Selasky if (vendid == TS_VENDOR_ID || vendid == SS_VENDOR_ID)
232*d6b92ffaSHans Petter Selasky return topspin_chassisguid(sysimgguid);
233*d6b92ffaSHans Petter Selasky else if (vendid == XS_VENDOR_ID || ibnd_is_xsigo_guid(sysimgguid))
234*d6b92ffaSHans Petter Selasky return xsigo_chassisguid(node);
235*d6b92ffaSHans Petter Selasky else
236*d6b92ffaSHans Petter Selasky return sysimgguid;
237*d6b92ffaSHans Petter Selasky }
238*d6b92ffaSHans Petter Selasky
find_chassisguid(ibnd_fabric_t * fabric,ibnd_node_t * node)239*d6b92ffaSHans Petter Selasky static ibnd_chassis_t *find_chassisguid(ibnd_fabric_t * fabric,
240*d6b92ffaSHans Petter Selasky ibnd_node_t * node)
241*d6b92ffaSHans Petter Selasky {
242*d6b92ffaSHans Petter Selasky ibnd_chassis_t *current;
243*d6b92ffaSHans Petter Selasky uint64_t chguid;
244*d6b92ffaSHans Petter Selasky
245*d6b92ffaSHans Petter Selasky chguid = get_chassisguid(node);
246*d6b92ffaSHans Petter Selasky for (current = fabric->chassis; current; current = current->next)
247*d6b92ffaSHans Petter Selasky if (current->chassisguid == chguid)
248*d6b92ffaSHans Petter Selasky return current;
249*d6b92ffaSHans Petter Selasky
250*d6b92ffaSHans Petter Selasky return NULL;
251*d6b92ffaSHans Petter Selasky }
252*d6b92ffaSHans Petter Selasky
ibnd_get_chassis_guid(ibnd_fabric_t * fabric,unsigned char chassisnum)253*d6b92ffaSHans Petter Selasky uint64_t ibnd_get_chassis_guid(ibnd_fabric_t * fabric, unsigned char chassisnum)
254*d6b92ffaSHans Petter Selasky {
255*d6b92ffaSHans Petter Selasky ibnd_chassis_t *chassis;
256*d6b92ffaSHans Petter Selasky
257*d6b92ffaSHans Petter Selasky if (!fabric) {
258*d6b92ffaSHans Petter Selasky IBND_DEBUG("fabric parameter NULL\n");
259*d6b92ffaSHans Petter Selasky return 0;
260*d6b92ffaSHans Petter Selasky }
261*d6b92ffaSHans Petter Selasky
262*d6b92ffaSHans Petter Selasky chassis = find_chassisnum(fabric, chassisnum);
263*d6b92ffaSHans Petter Selasky if (chassis)
264*d6b92ffaSHans Petter Selasky return chassis->chassisguid;
265*d6b92ffaSHans Petter Selasky else
266*d6b92ffaSHans Petter Selasky return 0;
267*d6b92ffaSHans Petter Selasky }
268*d6b92ffaSHans Petter Selasky
is_router(ibnd_node_t * n)269*d6b92ffaSHans Petter Selasky static int is_router(ibnd_node_t * n)
270*d6b92ffaSHans Petter Selasky {
271*d6b92ffaSHans Petter Selasky uint32_t devid = mad_get_field(n->info, 0, IB_NODE_DEVID_F);
272*d6b92ffaSHans Petter Selasky return (devid == VTR_DEVID_IB_FC_ROUTER ||
273*d6b92ffaSHans Petter Selasky devid == VTR_DEVID_IB_IP_ROUTER);
274*d6b92ffaSHans Petter Selasky }
275*d6b92ffaSHans Petter Selasky
is_spine_9096(ibnd_node_t * n)276*d6b92ffaSHans Petter Selasky static int is_spine_9096(ibnd_node_t * n)
277*d6b92ffaSHans Petter Selasky {
278*d6b92ffaSHans Petter Selasky uint32_t devid = mad_get_field(n->info, 0, IB_NODE_DEVID_F);
279*d6b92ffaSHans Petter Selasky return (devid == VTR_DEVID_SFB4 || devid == VTR_DEVID_SFB4_DDR);
280*d6b92ffaSHans Petter Selasky }
281*d6b92ffaSHans Petter Selasky
is_spine_9288(ibnd_node_t * n)282*d6b92ffaSHans Petter Selasky static int is_spine_9288(ibnd_node_t * n)
283*d6b92ffaSHans Petter Selasky {
284*d6b92ffaSHans Petter Selasky uint32_t devid = mad_get_field(n->info, 0, IB_NODE_DEVID_F);
285*d6b92ffaSHans Petter Selasky return (devid == VTR_DEVID_SFB12 || devid == VTR_DEVID_SFB12_DDR);
286*d6b92ffaSHans Petter Selasky }
287*d6b92ffaSHans Petter Selasky
is_spine_2004(ibnd_node_t * n)288*d6b92ffaSHans Petter Selasky static int is_spine_2004(ibnd_node_t * n)
289*d6b92ffaSHans Petter Selasky {
290*d6b92ffaSHans Petter Selasky uint32_t devid = mad_get_field(n->info, 0, IB_NODE_DEVID_F);
291*d6b92ffaSHans Petter Selasky return (devid == VTR_DEVID_SFB2004);
292*d6b92ffaSHans Petter Selasky }
293*d6b92ffaSHans Petter Selasky
is_spine_2012(ibnd_node_t * n)294*d6b92ffaSHans Petter Selasky static int is_spine_2012(ibnd_node_t * n)
295*d6b92ffaSHans Petter Selasky {
296*d6b92ffaSHans Petter Selasky uint32_t devid = mad_get_field(n->info, 0, IB_NODE_DEVID_F);
297*d6b92ffaSHans Petter Selasky return (devid == VTR_DEVID_SFB2012);
298*d6b92ffaSHans Petter Selasky }
299*d6b92ffaSHans Petter Selasky
is_spine_4700(ibnd_node_t * n)300*d6b92ffaSHans Petter Selasky static int is_spine_4700(ibnd_node_t * n)
301*d6b92ffaSHans Petter Selasky {
302*d6b92ffaSHans Petter Selasky uint32_t devid = mad_get_field(n->info, 0, IB_NODE_DEVID_F);
303*d6b92ffaSHans Petter Selasky return (devid == VTR_DEVID_SFB4700);
304*d6b92ffaSHans Petter Selasky }
305*d6b92ffaSHans Petter Selasky
is_spine_4700x2(ibnd_node_t * n)306*d6b92ffaSHans Petter Selasky static int is_spine_4700x2(ibnd_node_t * n)
307*d6b92ffaSHans Petter Selasky {
308*d6b92ffaSHans Petter Selasky uint32_t devid = mad_get_field(n->info, 0, IB_NODE_DEVID_F);
309*d6b92ffaSHans Petter Selasky return (devid == VTR_DEVID_SFB4700X2);
310*d6b92ffaSHans Petter Selasky }
311*d6b92ffaSHans Petter Selasky
is_spine_4200(ibnd_node_t * n)312*d6b92ffaSHans Petter Selasky static int is_spine_4200(ibnd_node_t * n)
313*d6b92ffaSHans Petter Selasky {
314*d6b92ffaSHans Petter Selasky uint32_t devid = mad_get_field(n->info, 0, IB_NODE_DEVID_F);
315*d6b92ffaSHans Petter Selasky return (devid == VTR_DEVID_SFB4200);
316*d6b92ffaSHans Petter Selasky }
317*d6b92ffaSHans Petter Selasky
is_spine(ibnd_node_t * n)318*d6b92ffaSHans Petter Selasky static int is_spine(ibnd_node_t * n)
319*d6b92ffaSHans Petter Selasky {
320*d6b92ffaSHans Petter Selasky return (is_spine_9096(n) || is_spine_9288(n) ||
321*d6b92ffaSHans Petter Selasky is_spine_2004(n) || is_spine_2012(n) ||
322*d6b92ffaSHans Petter Selasky is_spine_4700(n) || is_spine_4700x2(n) ||
323*d6b92ffaSHans Petter Selasky is_spine_4200(n));
324*d6b92ffaSHans Petter Selasky }
325*d6b92ffaSHans Petter Selasky
is_line_24(ibnd_node_t * n)326*d6b92ffaSHans Petter Selasky static int is_line_24(ibnd_node_t * n)
327*d6b92ffaSHans Petter Selasky {
328*d6b92ffaSHans Petter Selasky uint32_t devid = mad_get_field(n->info, 0, IB_NODE_DEVID_F);
329*d6b92ffaSHans Petter Selasky return (devid == VTR_DEVID_SLB24 ||
330*d6b92ffaSHans Petter Selasky devid == VTR_DEVID_SLB24_DDR || devid == VTR_DEVID_SRB2004);
331*d6b92ffaSHans Petter Selasky }
332*d6b92ffaSHans Petter Selasky
is_line_8(ibnd_node_t * n)333*d6b92ffaSHans Petter Selasky static int is_line_8(ibnd_node_t * n)
334*d6b92ffaSHans Petter Selasky {
335*d6b92ffaSHans Petter Selasky uint32_t devid = mad_get_field(n->info, 0, IB_NODE_DEVID_F);
336*d6b92ffaSHans Petter Selasky return (devid == VTR_DEVID_SLB8);
337*d6b92ffaSHans Petter Selasky }
338*d6b92ffaSHans Petter Selasky
is_line_2024(ibnd_node_t * n)339*d6b92ffaSHans Petter Selasky static int is_line_2024(ibnd_node_t * n)
340*d6b92ffaSHans Petter Selasky {
341*d6b92ffaSHans Petter Selasky uint32_t devid = mad_get_field(n->info, 0, IB_NODE_DEVID_F);
342*d6b92ffaSHans Petter Selasky return (devid == VTR_DEVID_SLB2024);
343*d6b92ffaSHans Petter Selasky }
344*d6b92ffaSHans Petter Selasky
is_line_4700(ibnd_node_t * n)345*d6b92ffaSHans Petter Selasky static int is_line_4700(ibnd_node_t * n)
346*d6b92ffaSHans Petter Selasky {
347*d6b92ffaSHans Petter Selasky uint32_t devid = mad_get_field(n->info, 0, IB_NODE_DEVID_F);
348*d6b92ffaSHans Petter Selasky return (devid == VTR_DEVID_SLB4018);
349*d6b92ffaSHans Petter Selasky }
350*d6b92ffaSHans Petter Selasky
is_line(ibnd_node_t * n)351*d6b92ffaSHans Petter Selasky static int is_line(ibnd_node_t * n)
352*d6b92ffaSHans Petter Selasky {
353*d6b92ffaSHans Petter Selasky return (is_line_24(n) || is_line_8(n) ||
354*d6b92ffaSHans Petter Selasky is_line_2024(n) || is_line_4700(n));
355*d6b92ffaSHans Petter Selasky }
356*d6b92ffaSHans Petter Selasky
is_chassis_switch(ibnd_node_t * n)357*d6b92ffaSHans Petter Selasky int is_chassis_switch(ibnd_node_t * n)
358*d6b92ffaSHans Petter Selasky {
359*d6b92ffaSHans Petter Selasky return (is_spine(n) || is_line(n));
360*d6b92ffaSHans Petter Selasky }
361*d6b92ffaSHans Petter Selasky
362*d6b92ffaSHans Petter Selasky /* these structs help find Line (Anafa) slot number while using spine portnum */
363*d6b92ffaSHans Petter Selasky char line_slot_2_sfb4[37] = {
364*d6b92ffaSHans Petter Selasky 0,
365*d6b92ffaSHans Petter Selasky 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3,
366*d6b92ffaSHans Petter Selasky 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
367*d6b92ffaSHans Petter Selasky };
368*d6b92ffaSHans Petter Selasky char anafa_line_slot_2_sfb4[37] = {
369*d6b92ffaSHans Petter Selasky 0,
370*d6b92ffaSHans Petter Selasky 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2,
371*d6b92ffaSHans Petter Selasky 1, 1, 1, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
372*d6b92ffaSHans Petter Selasky };
373*d6b92ffaSHans Petter Selasky
374*d6b92ffaSHans Petter Selasky char line_slot_2_sfb12[37] = {
375*d6b92ffaSHans Petter Selasky 0,
376*d6b92ffaSHans Petter Selasky 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,
377*d6b92ffaSHans Petter Selasky 10, 10, 11, 11, 12, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
378*d6b92ffaSHans Petter Selasky };
379*d6b92ffaSHans Petter Selasky char anafa_line_slot_2_sfb12[37] = {
380*d6b92ffaSHans Petter Selasky 0,
381*d6b92ffaSHans Petter Selasky 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2,
382*d6b92ffaSHans Petter Selasky 1, 2, 1, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
383*d6b92ffaSHans Petter Selasky };
384*d6b92ffaSHans Petter Selasky
385*d6b92ffaSHans Petter Selasky /* LB slot = table[spine port] */
386*d6b92ffaSHans Petter Selasky char line_slot_2_sfb18[37] = {
387*d6b92ffaSHans Petter Selasky 0,
388*d6b92ffaSHans Petter Selasky 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,
389*d6b92ffaSHans Petter Selasky 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18};
390*d6b92ffaSHans Petter Selasky /* LB asic num = table[spine port] */
391*d6b92ffaSHans Petter Selasky char anafa_line_slot_2_sfb18[37] = {
392*d6b92ffaSHans Petter Selasky 0,
393*d6b92ffaSHans Petter Selasky 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
394*d6b92ffaSHans Petter Selasky 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
395*d6b92ffaSHans Petter Selasky };
396*d6b92ffaSHans Petter Selasky
397*d6b92ffaSHans Petter Selasky /* LB slot = table[spine port] */
398*d6b92ffaSHans Petter Selasky char line_slot_2_sfb18x2[37] = {
399*d6b92ffaSHans Petter Selasky 0,
400*d6b92ffaSHans Petter Selasky 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
401*d6b92ffaSHans Petter Selasky 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
402*d6b92ffaSHans Petter Selasky /* LB asic num = table[spine port] */
403*d6b92ffaSHans Petter Selasky char anafa_line_slot_2_sfb18x2[37] = {
404*d6b92ffaSHans Petter Selasky 0,
405*d6b92ffaSHans Petter Selasky 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
406*d6b92ffaSHans Petter Selasky 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
407*d6b92ffaSHans Petter Selasky };
408*d6b92ffaSHans Petter Selasky
409*d6b92ffaSHans Petter Selasky /* LB slot = table[spine port] */
410*d6b92ffaSHans Petter Selasky char line_slot_2_sfb4200[37] = {
411*d6b92ffaSHans Petter Selasky 0,
412*d6b92ffaSHans Petter Selasky 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5,
413*d6b92ffaSHans Petter Selasky 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9};
414*d6b92ffaSHans Petter Selasky /* LB asic num = table[spine port] */
415*d6b92ffaSHans Petter Selasky char anafa_line_slot_2_sfb4200[37] = {
416*d6b92ffaSHans Petter Selasky 0,
417*d6b92ffaSHans Petter Selasky 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
418*d6b92ffaSHans Petter Selasky 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
419*d6b92ffaSHans Petter Selasky };
420*d6b92ffaSHans Petter Selasky
421*d6b92ffaSHans Petter Selasky /* IPR FCR modules connectivity while using sFB4 port as reference */
422*d6b92ffaSHans Petter Selasky char ipr_slot_2_sfb4_port[37] = {
423*d6b92ffaSHans Petter Selasky 0,
424*d6b92ffaSHans Petter Selasky 3, 2, 1, 3, 2, 1, 3, 2, 1, 3, 2, 1, 3, 2, 1, 3, 2, 1,
425*d6b92ffaSHans Petter Selasky 3, 2, 1, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
426*d6b92ffaSHans Petter Selasky };
427*d6b92ffaSHans Petter Selasky
428*d6b92ffaSHans Petter Selasky /* these structs help find Spine (Anafa) slot number while using spine portnum */
429*d6b92ffaSHans Petter Selasky char spine12_slot_2_slb[37] = {
430*d6b92ffaSHans Petter Selasky 0,
431*d6b92ffaSHans Petter Selasky 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 0, 0, 0, 0, 0, 0,
432*d6b92ffaSHans Petter Selasky 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
433*d6b92ffaSHans Petter Selasky };
434*d6b92ffaSHans Petter Selasky char anafa_spine12_slot_2_slb[37] = {
435*d6b92ffaSHans Petter Selasky 0,
436*d6b92ffaSHans Petter Selasky 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 0, 0, 0, 0, 0, 0,
437*d6b92ffaSHans Petter Selasky 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
438*d6b92ffaSHans Petter Selasky };
439*d6b92ffaSHans Petter Selasky
440*d6b92ffaSHans Petter Selasky char spine4_slot_2_slb[37] = {
441*d6b92ffaSHans Petter Selasky 0,
442*d6b92ffaSHans Petter Selasky 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 0, 0, 0, 0, 0, 0,
443*d6b92ffaSHans Petter Selasky 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
444*d6b92ffaSHans Petter Selasky };
445*d6b92ffaSHans Petter Selasky char anafa_spine4_slot_2_slb[37] = {
446*d6b92ffaSHans Petter Selasky 0,
447*d6b92ffaSHans Petter Selasky 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
448*d6b92ffaSHans Petter Selasky 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
449*d6b92ffaSHans Petter Selasky };
450*d6b92ffaSHans Petter Selasky
451*d6b92ffaSHans Petter Selasky /* FB slot = table[line port] */
452*d6b92ffaSHans Petter Selasky char spine18_slot_2_slb[37] = {
453*d6b92ffaSHans Petter Selasky 0,
454*d6b92ffaSHans Petter Selasky 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,
455*d6b92ffaSHans Petter Selasky 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
456*d6b92ffaSHans Petter Selasky };
457*d6b92ffaSHans Petter Selasky /* FB asic = table[line port] */
458*d6b92ffaSHans Petter Selasky char anafa_spine18_slot_2_slb[37] = {
459*d6b92ffaSHans Petter Selasky 0,
460*d6b92ffaSHans Petter Selasky 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
461*d6b92ffaSHans Petter Selasky 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
462*d6b92ffaSHans Petter Selasky };
463*d6b92ffaSHans Petter Selasky char anafa_spine18x2_slot_2_slb[37] = {
464*d6b92ffaSHans Petter Selasky 0,
465*d6b92ffaSHans Petter Selasky 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1,
466*d6b92ffaSHans Petter Selasky 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
467*d6b92ffaSHans Petter Selasky };
468*d6b92ffaSHans Petter Selasky
469*d6b92ffaSHans Petter Selasky /* FB slot = table[line port] */
470*d6b92ffaSHans Petter Selasky char sfb4200_slot_2_slb[37] = {
471*d6b92ffaSHans Petter Selasky 0,
472*d6b92ffaSHans Petter Selasky 1, 1, 1, 1, 0, 0, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4,
473*d6b92ffaSHans Petter Selasky 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
474*d6b92ffaSHans Petter Selasky };
475*d6b92ffaSHans Petter Selasky /* FB asic = table[line port] */
476*d6b92ffaSHans Petter Selasky char anafa_sfb4200_slot_2_slb[37] = {
477*d6b92ffaSHans Petter Selasky 0,
478*d6b92ffaSHans Petter Selasky 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
479*d6b92ffaSHans Petter Selasky 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
480*d6b92ffaSHans Petter Selasky };
481*d6b92ffaSHans Petter Selasky
482*d6b92ffaSHans Petter Selasky /* reference { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 }; */
483*d6b92ffaSHans Petter Selasky
get_sfb_slot(ibnd_node_t * n,ibnd_port_t * lineport)484*d6b92ffaSHans Petter Selasky static int get_sfb_slot(ibnd_node_t * n, ibnd_port_t * lineport)
485*d6b92ffaSHans Petter Selasky {
486*d6b92ffaSHans Petter Selasky n->ch_slot = SPINE_CS;
487*d6b92ffaSHans Petter Selasky if (is_spine_9096(n)) {
488*d6b92ffaSHans Petter Selasky n->ch_type = ISR9096_CT;
489*d6b92ffaSHans Petter Selasky n->ch_slotnum = spine4_slot_2_slb[lineport->portnum];
490*d6b92ffaSHans Petter Selasky n->ch_anafanum = anafa_spine4_slot_2_slb[lineport->portnum];
491*d6b92ffaSHans Petter Selasky } else if (is_spine_9288(n)) {
492*d6b92ffaSHans Petter Selasky n->ch_type = ISR9288_CT;
493*d6b92ffaSHans Petter Selasky n->ch_slotnum = spine12_slot_2_slb[lineport->portnum];
494*d6b92ffaSHans Petter Selasky n->ch_anafanum = anafa_spine12_slot_2_slb[lineport->portnum];
495*d6b92ffaSHans Petter Selasky } else if (is_spine_2012(n)) {
496*d6b92ffaSHans Petter Selasky n->ch_type = ISR2012_CT;
497*d6b92ffaSHans Petter Selasky n->ch_slotnum = spine12_slot_2_slb[lineport->portnum];
498*d6b92ffaSHans Petter Selasky n->ch_anafanum = anafa_spine12_slot_2_slb[lineport->portnum];
499*d6b92ffaSHans Petter Selasky } else if (is_spine_2004(n)) {
500*d6b92ffaSHans Petter Selasky n->ch_type = ISR2004_CT;
501*d6b92ffaSHans Petter Selasky n->ch_slotnum = spine4_slot_2_slb[lineport->portnum];
502*d6b92ffaSHans Petter Selasky n->ch_anafanum = anafa_spine4_slot_2_slb[lineport->portnum];
503*d6b92ffaSHans Petter Selasky } else if (is_spine_4700(n)) {
504*d6b92ffaSHans Petter Selasky n->ch_type = ISR4700_CT;
505*d6b92ffaSHans Petter Selasky n->ch_slotnum = spine18_slot_2_slb[lineport->portnum];
506*d6b92ffaSHans Petter Selasky n->ch_anafanum = anafa_spine18_slot_2_slb[lineport->portnum];
507*d6b92ffaSHans Petter Selasky } else if (is_spine_4700x2(n)) {
508*d6b92ffaSHans Petter Selasky n->ch_type = ISR4700_CT;
509*d6b92ffaSHans Petter Selasky n->ch_slotnum = spine18_slot_2_slb[lineport->portnum];
510*d6b92ffaSHans Petter Selasky n->ch_anafanum = anafa_spine18x2_slot_2_slb[lineport->portnum];
511*d6b92ffaSHans Petter Selasky } else if (is_spine_4200(n)) {
512*d6b92ffaSHans Petter Selasky n->ch_type = ISR4200_CT;
513*d6b92ffaSHans Petter Selasky n->ch_slotnum = sfb4200_slot_2_slb[lineport->portnum];
514*d6b92ffaSHans Petter Selasky n->ch_anafanum = anafa_sfb4200_slot_2_slb[lineport->portnum];
515*d6b92ffaSHans Petter Selasky } else {
516*d6b92ffaSHans Petter Selasky IBND_ERROR("Unexpected node found: guid 0x%016" PRIx64 "\n",
517*d6b92ffaSHans Petter Selasky n->guid);
518*d6b92ffaSHans Petter Selasky }
519*d6b92ffaSHans Petter Selasky return 0;
520*d6b92ffaSHans Petter Selasky }
521*d6b92ffaSHans Petter Selasky
get_router_slot(ibnd_node_t * n,ibnd_port_t * spineport)522*d6b92ffaSHans Petter Selasky static int get_router_slot(ibnd_node_t * n, ibnd_port_t * spineport)
523*d6b92ffaSHans Petter Selasky {
524*d6b92ffaSHans Petter Selasky uint64_t guessnum = 0;
525*d6b92ffaSHans Petter Selasky
526*d6b92ffaSHans Petter Selasky n->ch_found = 1;
527*d6b92ffaSHans Petter Selasky
528*d6b92ffaSHans Petter Selasky n->ch_slot = SRBD_CS;
529*d6b92ffaSHans Petter Selasky if (is_spine_9096(spineport->node)) {
530*d6b92ffaSHans Petter Selasky n->ch_type = ISR9096_CT;
531*d6b92ffaSHans Petter Selasky n->ch_slotnum = line_slot_2_sfb4[spineport->portnum];
532*d6b92ffaSHans Petter Selasky n->ch_anafanum = ipr_slot_2_sfb4_port[spineport->portnum];
533*d6b92ffaSHans Petter Selasky } else if (is_spine_9288(spineport->node)) {
534*d6b92ffaSHans Petter Selasky n->ch_type = ISR9288_CT;
535*d6b92ffaSHans Petter Selasky n->ch_slotnum = line_slot_2_sfb12[spineport->portnum];
536*d6b92ffaSHans Petter Selasky /* this is a smart guess based on nodeguids order on sFB-12 module */
537*d6b92ffaSHans Petter Selasky guessnum = spineport->node->guid % 4;
538*d6b92ffaSHans Petter Selasky /* module 1 <--> remote anafa 3 */
539*d6b92ffaSHans Petter Selasky /* module 2 <--> remote anafa 2 */
540*d6b92ffaSHans Petter Selasky /* module 3 <--> remote anafa 1 */
541*d6b92ffaSHans Petter Selasky n->ch_anafanum = (guessnum == 3 ? 1 : (guessnum == 1 ? 3 : 2));
542*d6b92ffaSHans Petter Selasky } else if (is_spine_2012(spineport->node)) {
543*d6b92ffaSHans Petter Selasky n->ch_type = ISR2012_CT;
544*d6b92ffaSHans Petter Selasky n->ch_slotnum = line_slot_2_sfb12[spineport->portnum];
545*d6b92ffaSHans Petter Selasky /* this is a smart guess based on nodeguids order on sFB-12 module */
546*d6b92ffaSHans Petter Selasky guessnum = spineport->node->guid % 4;
547*d6b92ffaSHans Petter Selasky // module 1 <--> remote anafa 3
548*d6b92ffaSHans Petter Selasky // module 2 <--> remote anafa 2
549*d6b92ffaSHans Petter Selasky // module 3 <--> remote anafa 1
550*d6b92ffaSHans Petter Selasky n->ch_anafanum = (guessnum == 3 ? 1 : (guessnum == 1 ? 3 : 2));
551*d6b92ffaSHans Petter Selasky } else if (is_spine_2004(spineport->node)) {
552*d6b92ffaSHans Petter Selasky n->ch_type = ISR2004_CT;
553*d6b92ffaSHans Petter Selasky n->ch_slotnum = line_slot_2_sfb4[spineport->portnum];
554*d6b92ffaSHans Petter Selasky n->ch_anafanum = ipr_slot_2_sfb4_port[spineport->portnum];
555*d6b92ffaSHans Petter Selasky } else {
556*d6b92ffaSHans Petter Selasky IBND_ERROR("Unexpected node found: guid 0x%016" PRIx64 "\n",
557*d6b92ffaSHans Petter Selasky spineport->node->guid);
558*d6b92ffaSHans Petter Selasky }
559*d6b92ffaSHans Petter Selasky return 0;
560*d6b92ffaSHans Petter Selasky }
561*d6b92ffaSHans Petter Selasky
get_slb_slot(ibnd_node_t * n,ibnd_port_t * spineport)562*d6b92ffaSHans Petter Selasky static int get_slb_slot(ibnd_node_t * n, ibnd_port_t * spineport)
563*d6b92ffaSHans Petter Selasky {
564*d6b92ffaSHans Petter Selasky n->ch_slot = LINE_CS;
565*d6b92ffaSHans Petter Selasky if (is_spine_9096(spineport->node)) {
566*d6b92ffaSHans Petter Selasky n->ch_type = ISR9096_CT;
567*d6b92ffaSHans Petter Selasky n->ch_slotnum = line_slot_2_sfb4[spineport->portnum];
568*d6b92ffaSHans Petter Selasky n->ch_anafanum = anafa_line_slot_2_sfb4[spineport->portnum];
569*d6b92ffaSHans Petter Selasky } else if (is_spine_9288(spineport->node)) {
570*d6b92ffaSHans Petter Selasky n->ch_type = ISR9288_CT;
571*d6b92ffaSHans Petter Selasky n->ch_slotnum = line_slot_2_sfb12[spineport->portnum];
572*d6b92ffaSHans Petter Selasky n->ch_anafanum = anafa_line_slot_2_sfb12[spineport->portnum];
573*d6b92ffaSHans Petter Selasky } else if (is_spine_2012(spineport->node)) {
574*d6b92ffaSHans Petter Selasky n->ch_type = ISR2012_CT;
575*d6b92ffaSHans Petter Selasky n->ch_slotnum = line_slot_2_sfb12[spineport->portnum];
576*d6b92ffaSHans Petter Selasky n->ch_anafanum = anafa_line_slot_2_sfb12[spineport->portnum];
577*d6b92ffaSHans Petter Selasky } else if (is_spine_2004(spineport->node)) {
578*d6b92ffaSHans Petter Selasky n->ch_type = ISR2004_CT;
579*d6b92ffaSHans Petter Selasky n->ch_slotnum = line_slot_2_sfb4[spineport->portnum];
580*d6b92ffaSHans Petter Selasky n->ch_anafanum = anafa_line_slot_2_sfb4[spineport->portnum];
581*d6b92ffaSHans Petter Selasky } else if (is_spine_4700(spineport->node)) {
582*d6b92ffaSHans Petter Selasky n->ch_type = ISR4700_CT;
583*d6b92ffaSHans Petter Selasky n->ch_slotnum = line_slot_2_sfb18[spineport->portnum];
584*d6b92ffaSHans Petter Selasky n->ch_anafanum = anafa_line_slot_2_sfb18[spineport->portnum];
585*d6b92ffaSHans Petter Selasky } else if (is_spine_4700x2(spineport->node)) {
586*d6b92ffaSHans Petter Selasky n->ch_type = ISR4700_CT;
587*d6b92ffaSHans Petter Selasky n->ch_slotnum = line_slot_2_sfb18x2[spineport->portnum];
588*d6b92ffaSHans Petter Selasky n->ch_anafanum = anafa_line_slot_2_sfb18x2[spineport->portnum];
589*d6b92ffaSHans Petter Selasky } else if (is_spine_4200(spineport->node)) {
590*d6b92ffaSHans Petter Selasky n->ch_type = ISR4200_CT;
591*d6b92ffaSHans Petter Selasky n->ch_slotnum = line_slot_2_sfb4200[spineport->portnum];
592*d6b92ffaSHans Petter Selasky n->ch_anafanum = anafa_line_slot_2_sfb4200[spineport->portnum];
593*d6b92ffaSHans Petter Selasky } else {
594*d6b92ffaSHans Petter Selasky IBND_ERROR("Unexpected node found: guid 0x%016" PRIx64 "\n",
595*d6b92ffaSHans Petter Selasky spineport->node->guid);
596*d6b92ffaSHans Petter Selasky }
597*d6b92ffaSHans Petter Selasky return 0;
598*d6b92ffaSHans Petter Selasky }
599*d6b92ffaSHans Petter Selasky
600*d6b92ffaSHans Petter Selasky
601*d6b92ffaSHans Petter Selasky /*
602*d6b92ffaSHans Petter Selasky This function called for every Mellanox node in fabric
603*d6b92ffaSHans Petter Selasky */
fill_mellanox_chassis_record(ibnd_node_t * node)604*d6b92ffaSHans Petter Selasky static int fill_mellanox_chassis_record(ibnd_node_t * node)
605*d6b92ffaSHans Petter Selasky {
606*d6b92ffaSHans Petter Selasky int p = 0;
607*d6b92ffaSHans Petter Selasky ibnd_port_t *port;
608*d6b92ffaSHans Petter Selasky
609*d6b92ffaSHans Petter Selasky char node_desc[IB_SMP_DATA_SIZE];
610*d6b92ffaSHans Petter Selasky char *system_name;
611*d6b92ffaSHans Petter Selasky char *system_type;
612*d6b92ffaSHans Petter Selasky char *system_slot_name;
613*d6b92ffaSHans Petter Selasky char *node_index;
614*d6b92ffaSHans Petter Selasky char *iter;
615*d6b92ffaSHans Petter Selasky int dev_id;
616*d6b92ffaSHans Petter Selasky
617*d6b92ffaSHans Petter Selasky /*
618*d6b92ffaSHans Petter Selasky The node description has the following format:
619*d6b92ffaSHans Petter Selasky
620*d6b92ffaSHans Petter Selasky 'MF0;<system name>:<system type>/<system slot name>[:board type]/U<node index>'
621*d6b92ffaSHans Petter Selasky
622*d6b92ffaSHans Petter Selasky - System slot name in our systems can be L[01-36] , S[01-18]
623*d6b92ffaSHans Petter Selasky - Node index is always 1 (we don.t have boards with multiple IS4 chips).
624*d6b92ffaSHans Petter Selasky - System name is taken from the currently configured host name.
625*d6b92ffaSHans Petter Selasky -The board type is optional and we don.t set it currently - A leaf or spine slot can currently hold a single type of board.
626*d6b92ffaSHans Petter Selasky */
627*d6b92ffaSHans Petter Selasky
628*d6b92ffaSHans Petter Selasky memcpy(node_desc, node->nodedesc, IB_SMP_DATA_SIZE);
629*d6b92ffaSHans Petter Selasky
630*d6b92ffaSHans Petter Selasky IBND_DEBUG("fill_mellanox_chassis_record: node_desc:%s \n",node_desc);
631*d6b92ffaSHans Petter Selasky
632*d6b92ffaSHans Petter Selasky if (node->ch_found) /* somehow this node has already been passed */
633*d6b92ffaSHans Petter Selasky return 0;
634*d6b92ffaSHans Petter Selasky
635*d6b92ffaSHans Petter Selasky /* All mellanox IS4 switches have the same vendor id*/
636*d6b92ffaSHans Petter Selasky dev_id = mad_get_field(node->info, 0,IB_NODE_DEVID_F);
637*d6b92ffaSHans Petter Selasky if (dev_id != MLX_DEVID_IS4)
638*d6b92ffaSHans Petter Selasky return 0;
639*d6b92ffaSHans Petter Selasky
640*d6b92ffaSHans Petter Selasky if((node_desc[0] != 'M') ||
641*d6b92ffaSHans Petter Selasky (node_desc[1] != 'F') ||
642*d6b92ffaSHans Petter Selasky (node_desc[2] != '0') ||
643*d6b92ffaSHans Petter Selasky (node_desc[3] != ';')) {
644*d6b92ffaSHans Petter Selasky IBND_DEBUG("fill_mellanox_chassis_record: Unsupported node description format:%s \n",node_desc);
645*d6b92ffaSHans Petter Selasky return 0;
646*d6b92ffaSHans Petter Selasky }
647*d6b92ffaSHans Petter Selasky
648*d6b92ffaSHans Petter Selasky /* parse system name*/
649*d6b92ffaSHans Petter Selasky system_name = &node_desc[4];
650*d6b92ffaSHans Petter Selasky for (iter = system_name ; (*iter != ':') && (*iter != '\0') ; iter++);
651*d6b92ffaSHans Petter Selasky if(*iter == '\0'){
652*d6b92ffaSHans Petter Selasky IBND_DEBUG("fill_mellanox_chassis_record: Unsupported node description format:%s - (get system_name failed) \n",node_desc);
653*d6b92ffaSHans Petter Selasky return 0;
654*d6b92ffaSHans Petter Selasky }
655*d6b92ffaSHans Petter Selasky *iter = '\0';
656*d6b92ffaSHans Petter Selasky iter++;
657*d6b92ffaSHans Petter Selasky /* parse system type*/
658*d6b92ffaSHans Petter Selasky system_type = iter;
659*d6b92ffaSHans Petter Selasky for ( ; (*iter != '/') && (*iter != '\0') ; iter++);
660*d6b92ffaSHans Petter Selasky if(*iter == '\0'){
661*d6b92ffaSHans Petter Selasky IBND_DEBUG("fill_mellanox_chassis_record: Unsupported node description format:%s - (get system_type failed) \n",node_desc);
662*d6b92ffaSHans Petter Selasky return 0;
663*d6b92ffaSHans Petter Selasky }
664*d6b92ffaSHans Petter Selasky *iter = '\0';
665*d6b92ffaSHans Petter Selasky iter++;
666*d6b92ffaSHans Petter Selasky /* parse system slot name*/
667*d6b92ffaSHans Petter Selasky system_slot_name = iter;
668*d6b92ffaSHans Petter Selasky for ( ; (*iter != '/') && (*iter != ':') && (*iter != '\0') ; iter++);
669*d6b92ffaSHans Petter Selasky if(*iter == '\0'){
670*d6b92ffaSHans Petter Selasky IBND_DEBUG("fill_mellanox_chassis_record: Unsupported node description format:%s - (get system_slot_name failed) \n",node_desc);
671*d6b92ffaSHans Petter Selasky return 0;
672*d6b92ffaSHans Petter Selasky }
673*d6b92ffaSHans Petter Selasky if(*iter == ':'){
674*d6b92ffaSHans Petter Selasky *iter = '\0';
675*d6b92ffaSHans Petter Selasky iter++;
676*d6b92ffaSHans Petter Selasky for ( ; (*iter != '/') && (*iter != '\0') ; iter++);
677*d6b92ffaSHans Petter Selasky if(*iter == '\0'){
678*d6b92ffaSHans Petter Selasky IBND_DEBUG("fill_mellanox_chassis_record: Unsupported node description format:%s - (get board type failed) \n",node_desc);
679*d6b92ffaSHans Petter Selasky return 0;
680*d6b92ffaSHans Petter Selasky }
681*d6b92ffaSHans Petter Selasky }
682*d6b92ffaSHans Petter Selasky *iter = '\0';
683*d6b92ffaSHans Petter Selasky iter++;
684*d6b92ffaSHans Petter Selasky node_index = iter;
685*d6b92ffaSHans Petter Selasky if(node_index[0] != 'U'){
686*d6b92ffaSHans Petter Selasky IBND_DEBUG("fill_mellanox_chassis_record: Unsupported node description format:%s - (get node index) \n",node_desc);
687*d6b92ffaSHans Petter Selasky return 0;
688*d6b92ffaSHans Petter Selasky }
689*d6b92ffaSHans Petter Selasky
690*d6b92ffaSHans Petter Selasky /* set Chip number (node index) */
691*d6b92ffaSHans Petter Selasky node->ch_anafanum = (unsigned char) atoi(&node_index[1]);
692*d6b92ffaSHans Petter Selasky if(node->ch_anafanum != 1){
693*d6b92ffaSHans Petter Selasky IBND_DEBUG("Unexpected Chip number:%d \n",node->ch_anafanum);
694*d6b92ffaSHans Petter Selasky }
695*d6b92ffaSHans Petter Selasky
696*d6b92ffaSHans Petter Selasky
697*d6b92ffaSHans Petter Selasky /* set Line Spine numbers */
698*d6b92ffaSHans Petter Selasky if(system_slot_name[0] == 'L')
699*d6b92ffaSHans Petter Selasky node->ch_slot = LINE_CS;
700*d6b92ffaSHans Petter Selasky else if(system_slot_name[0] == 'S')
701*d6b92ffaSHans Petter Selasky node->ch_slot = SPINE_CS;
702*d6b92ffaSHans Petter Selasky else{
703*d6b92ffaSHans Petter Selasky IBND_DEBUG("fill_mellanox_chassis_record: Unsupported system_slot_name:%s \n",system_slot_name);
704*d6b92ffaSHans Petter Selasky return 0;
705*d6b92ffaSHans Petter Selasky }
706*d6b92ffaSHans Petter Selasky
707*d6b92ffaSHans Petter Selasky /* The switch will be displayed under Line or Spine and not under Chassis switches */
708*d6b92ffaSHans Petter Selasky node->ch_found = 1;
709*d6b92ffaSHans Petter Selasky
710*d6b92ffaSHans Petter Selasky node->ch_slotnum = (unsigned char) atoi(&system_slot_name[1]);
711*d6b92ffaSHans Petter Selasky if((node->ch_slot == LINE_CS && (node->ch_slotnum > (LINES_MAX_NUM + 1))) ||
712*d6b92ffaSHans Petter Selasky (node->ch_slot == SPINE_CS && (node->ch_slotnum > (SPINES_MAX_NUM + 1)))){
713*d6b92ffaSHans Petter Selasky IBND_ERROR("fill_mellanox_chassis_record: invalid slot number:%d \n",node->ch_slotnum);
714*d6b92ffaSHans Petter Selasky node->ch_slotnum = 0;
715*d6b92ffaSHans Petter Selasky return 0;
716*d6b92ffaSHans Petter Selasky }
717*d6b92ffaSHans Petter Selasky
718*d6b92ffaSHans Petter Selasky /*set ch_type_str*/
719*d6b92ffaSHans Petter Selasky strncpy(node->ch_type_str , system_type, sizeof(node->ch_type_str)-1);
720*d6b92ffaSHans Petter Selasky
721*d6b92ffaSHans Petter Selasky /* Line ports 1-18 are mapped to external ports 1-18*/
722*d6b92ffaSHans Petter Selasky if(node->ch_slot == LINE_CS)
723*d6b92ffaSHans Petter Selasky {
724*d6b92ffaSHans Petter Selasky for (p = 1; p <= node->numports && p <= 18 ; p++) {
725*d6b92ffaSHans Petter Selasky port = node->ports[p];
726*d6b92ffaSHans Petter Selasky if (!port)
727*d6b92ffaSHans Petter Selasky continue;
728*d6b92ffaSHans Petter Selasky port->ext_portnum = p;
729*d6b92ffaSHans Petter Selasky }
730*d6b92ffaSHans Petter Selasky }
731*d6b92ffaSHans Petter Selasky
732*d6b92ffaSHans Petter Selasky return 0;
733*d6b92ffaSHans Petter Selasky }
734*d6b92ffaSHans Petter Selasky
insert_mellanox_line_and_spine(ibnd_node_t * node,ibnd_chassis_t * chassis)735*d6b92ffaSHans Petter Selasky static int insert_mellanox_line_and_spine(ibnd_node_t * node, ibnd_chassis_t * chassis)
736*d6b92ffaSHans Petter Selasky {
737*d6b92ffaSHans Petter Selasky if (node->ch_slot == LINE_CS){
738*d6b92ffaSHans Petter Selasky
739*d6b92ffaSHans Petter Selasky if (chassis->linenode[node->ch_slotnum])
740*d6b92ffaSHans Petter Selasky return 0; /* already filled slot */
741*d6b92ffaSHans Petter Selasky
742*d6b92ffaSHans Petter Selasky chassis->linenode[node->ch_slotnum] = node;
743*d6b92ffaSHans Petter Selasky }
744*d6b92ffaSHans Petter Selasky else if (node->ch_slot == SPINE_CS){
745*d6b92ffaSHans Petter Selasky
746*d6b92ffaSHans Petter Selasky if (chassis->spinenode[node->ch_slotnum])
747*d6b92ffaSHans Petter Selasky return 0; /* already filled slot */
748*d6b92ffaSHans Petter Selasky
749*d6b92ffaSHans Petter Selasky chassis->spinenode[node->ch_slotnum] = node;
750*d6b92ffaSHans Petter Selasky }
751*d6b92ffaSHans Petter Selasky else
752*d6b92ffaSHans Petter Selasky return 0;
753*d6b92ffaSHans Petter Selasky
754*d6b92ffaSHans Petter Selasky node->chassis = chassis;
755*d6b92ffaSHans Petter Selasky
756*d6b92ffaSHans Petter Selasky return 0;
757*d6b92ffaSHans Petter Selasky }
758*d6b92ffaSHans Petter Selasky
759*d6b92ffaSHans Petter Selasky
760*d6b92ffaSHans Petter Selasky /* forward declare this */
761*d6b92ffaSHans Petter Selasky static void voltaire_portmap(ibnd_port_t * port);
762*d6b92ffaSHans Petter Selasky /*
763*d6b92ffaSHans Petter Selasky This function called for every Voltaire node in fabric
764*d6b92ffaSHans Petter Selasky It could be optimized so, but time overhead is very small
765*d6b92ffaSHans Petter Selasky and its only diag.util
766*d6b92ffaSHans Petter Selasky */
fill_voltaire_chassis_record(ibnd_node_t * node)767*d6b92ffaSHans Petter Selasky static int fill_voltaire_chassis_record(ibnd_node_t * node)
768*d6b92ffaSHans Petter Selasky {
769*d6b92ffaSHans Petter Selasky int p = 0;
770*d6b92ffaSHans Petter Selasky ibnd_port_t *port;
771*d6b92ffaSHans Petter Selasky ibnd_node_t *remnode = 0;
772*d6b92ffaSHans Petter Selasky
773*d6b92ffaSHans Petter Selasky if (node->ch_found) /* somehow this node has already been passed */
774*d6b92ffaSHans Petter Selasky return 0;
775*d6b92ffaSHans Petter Selasky node->ch_found = 1;
776*d6b92ffaSHans Petter Selasky
777*d6b92ffaSHans Petter Selasky /* node is router only in case of using unique lid */
778*d6b92ffaSHans Petter Selasky /* (which is lid of chassis router port) */
779*d6b92ffaSHans Petter Selasky /* in such case node->ports is actually a requested port... */
780*d6b92ffaSHans Petter Selasky if (is_router(node))
781*d6b92ffaSHans Petter Selasky /* find the remote node */
782*d6b92ffaSHans Petter Selasky for (p = 1; p <= node->numports; p++) {
783*d6b92ffaSHans Petter Selasky port = node->ports[p];
784*d6b92ffaSHans Petter Selasky if (port && is_spine(port->remoteport->node))
785*d6b92ffaSHans Petter Selasky get_router_slot(node, port->remoteport);
786*d6b92ffaSHans Petter Selasky }
787*d6b92ffaSHans Petter Selasky else if (is_spine(node)) {
788*d6b92ffaSHans Petter Selasky int is_4700x2 = is_spine_4700x2(node);
789*d6b92ffaSHans Petter Selasky
790*d6b92ffaSHans Petter Selasky for (p = 1; p <= node->numports; p++) {
791*d6b92ffaSHans Petter Selasky port = node->ports[p];
792*d6b92ffaSHans Petter Selasky if (!port || !port->remoteport)
793*d6b92ffaSHans Petter Selasky continue;
794*d6b92ffaSHans Petter Selasky
795*d6b92ffaSHans Petter Selasky /*
796*d6b92ffaSHans Petter Selasky * Skip ISR4700 double density fabric boards ports 19-36
797*d6b92ffaSHans Petter Selasky * as they are chassis external ports
798*d6b92ffaSHans Petter Selasky */
799*d6b92ffaSHans Petter Selasky if (is_4700x2 && (port->portnum > 18))
800*d6b92ffaSHans Petter Selasky continue;
801*d6b92ffaSHans Petter Selasky
802*d6b92ffaSHans Petter Selasky remnode = port->remoteport->node;
803*d6b92ffaSHans Petter Selasky if (remnode->type != IB_NODE_SWITCH) {
804*d6b92ffaSHans Petter Selasky if (!remnode->ch_found)
805*d6b92ffaSHans Petter Selasky get_router_slot(remnode, port);
806*d6b92ffaSHans Petter Selasky continue;
807*d6b92ffaSHans Petter Selasky }
808*d6b92ffaSHans Petter Selasky if (!node->ch_type)
809*d6b92ffaSHans Petter Selasky /* we assume here that remoteport belongs to line */
810*d6b92ffaSHans Petter Selasky get_sfb_slot(node, port->remoteport);
811*d6b92ffaSHans Petter Selasky
812*d6b92ffaSHans Petter Selasky /* we could break here, but need to find if more routers connected */
813*d6b92ffaSHans Petter Selasky }
814*d6b92ffaSHans Petter Selasky
815*d6b92ffaSHans Petter Selasky } else if (is_line(node)) {
816*d6b92ffaSHans Petter Selasky int is_4700_line = is_line_4700(node);
817*d6b92ffaSHans Petter Selasky
818*d6b92ffaSHans Petter Selasky for (p = 1; p <= node->numports; p++) {
819*d6b92ffaSHans Petter Selasky port = node->ports[p];
820*d6b92ffaSHans Petter Selasky if (!port || !port->remoteport)
821*d6b92ffaSHans Petter Selasky continue;
822*d6b92ffaSHans Petter Selasky
823*d6b92ffaSHans Petter Selasky if ((is_4700_line && (port->portnum > 18)) ||
824*d6b92ffaSHans Petter Selasky (!is_4700_line && (port->portnum > 12)))
825*d6b92ffaSHans Petter Selasky continue;
826*d6b92ffaSHans Petter Selasky
827*d6b92ffaSHans Petter Selasky /* we assume here that remoteport belongs to spine */
828*d6b92ffaSHans Petter Selasky get_slb_slot(node, port->remoteport);
829*d6b92ffaSHans Petter Selasky break;
830*d6b92ffaSHans Petter Selasky }
831*d6b92ffaSHans Petter Selasky }
832*d6b92ffaSHans Petter Selasky
833*d6b92ffaSHans Petter Selasky /* for each port of this node, map external ports */
834*d6b92ffaSHans Petter Selasky for (p = 1; p <= node->numports; p++) {
835*d6b92ffaSHans Petter Selasky port = node->ports[p];
836*d6b92ffaSHans Petter Selasky if (!port)
837*d6b92ffaSHans Petter Selasky continue;
838*d6b92ffaSHans Petter Selasky voltaire_portmap(port);
839*d6b92ffaSHans Petter Selasky }
840*d6b92ffaSHans Petter Selasky
841*d6b92ffaSHans Petter Selasky return 0;
842*d6b92ffaSHans Petter Selasky }
843*d6b92ffaSHans Petter Selasky
get_line_index(ibnd_node_t * node)844*d6b92ffaSHans Petter Selasky static int get_line_index(ibnd_node_t * node)
845*d6b92ffaSHans Petter Selasky {
846*d6b92ffaSHans Petter Selasky int retval;
847*d6b92ffaSHans Petter Selasky
848*d6b92ffaSHans Petter Selasky if (is_line_4700(node))
849*d6b92ffaSHans Petter Selasky retval = node->ch_slotnum;
850*d6b92ffaSHans Petter Selasky else
851*d6b92ffaSHans Petter Selasky retval = 3 * (node->ch_slotnum - 1) + node->ch_anafanum;
852*d6b92ffaSHans Petter Selasky
853*d6b92ffaSHans Petter Selasky if (retval > LINES_MAX_NUM || retval < 1) {
854*d6b92ffaSHans Petter Selasky printf("%s: retval = %d\n", __FUNCTION__, retval);
855*d6b92ffaSHans Petter Selasky IBND_ERROR("Internal error\n");
856*d6b92ffaSHans Petter Selasky return -1;
857*d6b92ffaSHans Petter Selasky }
858*d6b92ffaSHans Petter Selasky return retval;
859*d6b92ffaSHans Petter Selasky }
860*d6b92ffaSHans Petter Selasky
get_spine_index(ibnd_node_t * node)861*d6b92ffaSHans Petter Selasky static int get_spine_index(ibnd_node_t * node)
862*d6b92ffaSHans Petter Selasky {
863*d6b92ffaSHans Petter Selasky int retval;
864*d6b92ffaSHans Petter Selasky
865*d6b92ffaSHans Petter Selasky if (is_spine_9288(node) || is_spine_2012(node))
866*d6b92ffaSHans Petter Selasky retval = 3 * (node->ch_slotnum - 1) + node->ch_anafanum;
867*d6b92ffaSHans Petter Selasky else if (is_spine_4700(node) || is_spine_4700x2(node))
868*d6b92ffaSHans Petter Selasky retval = 2 * (node->ch_slotnum - 1) + node->ch_anafanum;
869*d6b92ffaSHans Petter Selasky else
870*d6b92ffaSHans Petter Selasky retval = node->ch_slotnum;
871*d6b92ffaSHans Petter Selasky
872*d6b92ffaSHans Petter Selasky if (retval > SPINES_MAX_NUM || retval < 1) {
873*d6b92ffaSHans Petter Selasky IBND_ERROR("Internal error\n");
874*d6b92ffaSHans Petter Selasky return -1;
875*d6b92ffaSHans Petter Selasky }
876*d6b92ffaSHans Petter Selasky return retval;
877*d6b92ffaSHans Petter Selasky }
878*d6b92ffaSHans Petter Selasky
insert_line_router(ibnd_node_t * node,ibnd_chassis_t * chassis)879*d6b92ffaSHans Petter Selasky static int insert_line_router(ibnd_node_t * node, ibnd_chassis_t * chassis)
880*d6b92ffaSHans Petter Selasky {
881*d6b92ffaSHans Petter Selasky int i = get_line_index(node);
882*d6b92ffaSHans Petter Selasky
883*d6b92ffaSHans Petter Selasky if (i < 0)
884*d6b92ffaSHans Petter Selasky return i;
885*d6b92ffaSHans Petter Selasky
886*d6b92ffaSHans Petter Selasky if (chassis->linenode[i])
887*d6b92ffaSHans Petter Selasky return 0; /* already filled slot */
888*d6b92ffaSHans Petter Selasky
889*d6b92ffaSHans Petter Selasky chassis->linenode[i] = node;
890*d6b92ffaSHans Petter Selasky node->chassis = chassis;
891*d6b92ffaSHans Petter Selasky return 0;
892*d6b92ffaSHans Petter Selasky }
893*d6b92ffaSHans Petter Selasky
insert_spine(ibnd_node_t * node,ibnd_chassis_t * chassis)894*d6b92ffaSHans Petter Selasky static int insert_spine(ibnd_node_t * node, ibnd_chassis_t * chassis)
895*d6b92ffaSHans Petter Selasky {
896*d6b92ffaSHans Petter Selasky int i = get_spine_index(node);
897*d6b92ffaSHans Petter Selasky
898*d6b92ffaSHans Petter Selasky if (i < 0)
899*d6b92ffaSHans Petter Selasky return i;
900*d6b92ffaSHans Petter Selasky
901*d6b92ffaSHans Petter Selasky if (chassis->spinenode[i])
902*d6b92ffaSHans Petter Selasky return 0; /* already filled slot */
903*d6b92ffaSHans Petter Selasky
904*d6b92ffaSHans Petter Selasky chassis->spinenode[i] = node;
905*d6b92ffaSHans Petter Selasky node->chassis = chassis;
906*d6b92ffaSHans Petter Selasky return 0;
907*d6b92ffaSHans Petter Selasky }
908*d6b92ffaSHans Petter Selasky
pass_on_lines_catch_spines(ibnd_chassis_t * chassis)909*d6b92ffaSHans Petter Selasky static int pass_on_lines_catch_spines(ibnd_chassis_t * chassis)
910*d6b92ffaSHans Petter Selasky {
911*d6b92ffaSHans Petter Selasky ibnd_node_t *node, *remnode;
912*d6b92ffaSHans Petter Selasky ibnd_port_t *port;
913*d6b92ffaSHans Petter Selasky int i, p;
914*d6b92ffaSHans Petter Selasky
915*d6b92ffaSHans Petter Selasky for (i = 1; i <= LINES_MAX_NUM; i++) {
916*d6b92ffaSHans Petter Selasky int is_4700_line;
917*d6b92ffaSHans Petter Selasky
918*d6b92ffaSHans Petter Selasky node = chassis->linenode[i];
919*d6b92ffaSHans Petter Selasky
920*d6b92ffaSHans Petter Selasky if (!(node && is_line(node)))
921*d6b92ffaSHans Petter Selasky continue; /* empty slot or router */
922*d6b92ffaSHans Petter Selasky
923*d6b92ffaSHans Petter Selasky is_4700_line = is_line_4700(node);
924*d6b92ffaSHans Petter Selasky
925*d6b92ffaSHans Petter Selasky for (p = 1; p <= node->numports; p++) {
926*d6b92ffaSHans Petter Selasky
927*d6b92ffaSHans Petter Selasky port = node->ports[p];
928*d6b92ffaSHans Petter Selasky if (!port || !port->remoteport)
929*d6b92ffaSHans Petter Selasky continue;
930*d6b92ffaSHans Petter Selasky
931*d6b92ffaSHans Petter Selasky if ((is_4700_line && (port->portnum > 18)) ||
932*d6b92ffaSHans Petter Selasky (!is_4700_line && (port->portnum > 12)))
933*d6b92ffaSHans Petter Selasky continue;
934*d6b92ffaSHans Petter Selasky
935*d6b92ffaSHans Petter Selasky remnode = port->remoteport->node;
936*d6b92ffaSHans Petter Selasky
937*d6b92ffaSHans Petter Selasky if (!remnode->ch_found)
938*d6b92ffaSHans Petter Selasky continue; /* some error - spine not initialized ? FIXME */
939*d6b92ffaSHans Petter Selasky if (insert_spine(remnode, chassis))
940*d6b92ffaSHans Petter Selasky return -1;
941*d6b92ffaSHans Petter Selasky }
942*d6b92ffaSHans Petter Selasky }
943*d6b92ffaSHans Petter Selasky return 0;
944*d6b92ffaSHans Petter Selasky }
945*d6b92ffaSHans Petter Selasky
pass_on_spines_catch_lines(ibnd_chassis_t * chassis)946*d6b92ffaSHans Petter Selasky static int pass_on_spines_catch_lines(ibnd_chassis_t * chassis)
947*d6b92ffaSHans Petter Selasky {
948*d6b92ffaSHans Petter Selasky ibnd_node_t *node, *remnode;
949*d6b92ffaSHans Petter Selasky ibnd_port_t *port;
950*d6b92ffaSHans Petter Selasky int i, p;
951*d6b92ffaSHans Petter Selasky
952*d6b92ffaSHans Petter Selasky for (i = 1; i <= SPINES_MAX_NUM; i++) {
953*d6b92ffaSHans Petter Selasky int is_4700x2;
954*d6b92ffaSHans Petter Selasky
955*d6b92ffaSHans Petter Selasky node = chassis->spinenode[i];
956*d6b92ffaSHans Petter Selasky if (!node)
957*d6b92ffaSHans Petter Selasky continue; /* empty slot */
958*d6b92ffaSHans Petter Selasky
959*d6b92ffaSHans Petter Selasky is_4700x2 = is_spine_4700x2(node);
960*d6b92ffaSHans Petter Selasky
961*d6b92ffaSHans Petter Selasky for (p = 1; p <= node->numports; p++) {
962*d6b92ffaSHans Petter Selasky port = node->ports[p];
963*d6b92ffaSHans Petter Selasky if (!port || !port->remoteport)
964*d6b92ffaSHans Petter Selasky continue;
965*d6b92ffaSHans Petter Selasky
966*d6b92ffaSHans Petter Selasky /*
967*d6b92ffaSHans Petter Selasky * ISR4700 double density fabric board ports 19-36 are
968*d6b92ffaSHans Petter Selasky * chassis external ports, so skip them
969*d6b92ffaSHans Petter Selasky */
970*d6b92ffaSHans Petter Selasky if (is_4700x2 && (port->portnum > 18))
971*d6b92ffaSHans Petter Selasky continue;
972*d6b92ffaSHans Petter Selasky
973*d6b92ffaSHans Petter Selasky remnode = port->remoteport->node;
974*d6b92ffaSHans Petter Selasky
975*d6b92ffaSHans Petter Selasky if (!remnode->ch_found)
976*d6b92ffaSHans Petter Selasky continue; /* some error - line/router not initialized ? FIXME */
977*d6b92ffaSHans Petter Selasky
978*d6b92ffaSHans Petter Selasky if (insert_line_router(remnode, chassis))
979*d6b92ffaSHans Petter Selasky return -1;
980*d6b92ffaSHans Petter Selasky }
981*d6b92ffaSHans Petter Selasky }
982*d6b92ffaSHans Petter Selasky return 0;
983*d6b92ffaSHans Petter Selasky }
984*d6b92ffaSHans Petter Selasky
985*d6b92ffaSHans Petter Selasky /*
986*d6b92ffaSHans Petter Selasky Stupid interpolation algorithm...
987*d6b92ffaSHans Petter Selasky But nothing to do - have to be compliant with VoltaireSM/NMS
988*d6b92ffaSHans Petter Selasky */
pass_on_spines_interpolate_chguid(ibnd_chassis_t * chassis)989*d6b92ffaSHans Petter Selasky static void pass_on_spines_interpolate_chguid(ibnd_chassis_t * chassis)
990*d6b92ffaSHans Petter Selasky {
991*d6b92ffaSHans Petter Selasky ibnd_node_t *node;
992*d6b92ffaSHans Petter Selasky int i;
993*d6b92ffaSHans Petter Selasky
994*d6b92ffaSHans Petter Selasky for (i = 1; i <= SPINES_MAX_NUM; i++) {
995*d6b92ffaSHans Petter Selasky node = chassis->spinenode[i];
996*d6b92ffaSHans Petter Selasky if (!node)
997*d6b92ffaSHans Petter Selasky continue; /* skip the empty slots */
998*d6b92ffaSHans Petter Selasky
999*d6b92ffaSHans Petter Selasky /* take first guid minus one to be consistent with SM */
1000*d6b92ffaSHans Petter Selasky chassis->chassisguid = node->guid - 1;
1001*d6b92ffaSHans Petter Selasky break;
1002*d6b92ffaSHans Petter Selasky }
1003*d6b92ffaSHans Petter Selasky }
1004*d6b92ffaSHans Petter Selasky
1005*d6b92ffaSHans Petter Selasky /*
1006*d6b92ffaSHans Petter Selasky This function fills chassis structure with all nodes
1007*d6b92ffaSHans Petter Selasky in that chassis
1008*d6b92ffaSHans Petter Selasky chassis structure = structure of one standalone chassis
1009*d6b92ffaSHans Petter Selasky */
build_chassis(ibnd_node_t * node,ibnd_chassis_t * chassis)1010*d6b92ffaSHans Petter Selasky static int build_chassis(ibnd_node_t * node, ibnd_chassis_t * chassis)
1011*d6b92ffaSHans Petter Selasky {
1012*d6b92ffaSHans Petter Selasky int p = 0;
1013*d6b92ffaSHans Petter Selasky ibnd_node_t *remnode = 0;
1014*d6b92ffaSHans Petter Selasky ibnd_port_t *port = 0;
1015*d6b92ffaSHans Petter Selasky
1016*d6b92ffaSHans Petter Selasky /* we get here with node = chassis_spine */
1017*d6b92ffaSHans Petter Selasky if (insert_spine(node, chassis))
1018*d6b92ffaSHans Petter Selasky return -1;
1019*d6b92ffaSHans Petter Selasky
1020*d6b92ffaSHans Petter Selasky /* loop: pass on all ports of node */
1021*d6b92ffaSHans Petter Selasky for (p = 1; p <= node->numports; p++) {
1022*d6b92ffaSHans Petter Selasky
1023*d6b92ffaSHans Petter Selasky port = node->ports[p];
1024*d6b92ffaSHans Petter Selasky if (!port || !port->remoteport)
1025*d6b92ffaSHans Petter Selasky continue;
1026*d6b92ffaSHans Petter Selasky
1027*d6b92ffaSHans Petter Selasky /*
1028*d6b92ffaSHans Petter Selasky * ISR4700 double density fabric board ports 19-36 are
1029*d6b92ffaSHans Petter Selasky * chassis external ports, so skip them
1030*d6b92ffaSHans Petter Selasky */
1031*d6b92ffaSHans Petter Selasky if (is_spine_4700x2(node) && (port->portnum > 18))
1032*d6b92ffaSHans Petter Selasky continue;
1033*d6b92ffaSHans Petter Selasky
1034*d6b92ffaSHans Petter Selasky remnode = port->remoteport->node;
1035*d6b92ffaSHans Petter Selasky
1036*d6b92ffaSHans Petter Selasky if (!remnode->ch_found)
1037*d6b92ffaSHans Petter Selasky continue; /* some error - line or router not initialized ? FIXME */
1038*d6b92ffaSHans Petter Selasky
1039*d6b92ffaSHans Petter Selasky insert_line_router(remnode, chassis);
1040*d6b92ffaSHans Petter Selasky }
1041*d6b92ffaSHans Petter Selasky
1042*d6b92ffaSHans Petter Selasky if (pass_on_lines_catch_spines(chassis))
1043*d6b92ffaSHans Petter Selasky return -1;
1044*d6b92ffaSHans Petter Selasky /* this pass needed for to catch routers, since routers connected only */
1045*d6b92ffaSHans Petter Selasky /* to spines in slot 1 or 4 and we could miss them first time */
1046*d6b92ffaSHans Petter Selasky if (pass_on_spines_catch_lines(chassis))
1047*d6b92ffaSHans Petter Selasky return -1;
1048*d6b92ffaSHans Petter Selasky
1049*d6b92ffaSHans Petter Selasky /* additional 2 passes needed for to overcome a problem of pure "in-chassis" */
1050*d6b92ffaSHans Petter Selasky /* connectivity - extra pass to ensure that all related chips/modules */
1051*d6b92ffaSHans Petter Selasky /* inserted into the chassis */
1052*d6b92ffaSHans Petter Selasky if (pass_on_lines_catch_spines(chassis))
1053*d6b92ffaSHans Petter Selasky return -1;
1054*d6b92ffaSHans Petter Selasky if (pass_on_spines_catch_lines(chassis))
1055*d6b92ffaSHans Petter Selasky return -1;
1056*d6b92ffaSHans Petter Selasky pass_on_spines_interpolate_chguid(chassis);
1057*d6b92ffaSHans Petter Selasky
1058*d6b92ffaSHans Petter Selasky return 0;
1059*d6b92ffaSHans Petter Selasky }
1060*d6b92ffaSHans Petter Selasky
1061*d6b92ffaSHans Petter Selasky /*========================================================*/
1062*d6b92ffaSHans Petter Selasky /* INTERNAL TO EXTERNAL PORT MAPPING */
1063*d6b92ffaSHans Petter Selasky /*========================================================*/
1064*d6b92ffaSHans Petter Selasky
1065*d6b92ffaSHans Petter Selasky /*
1066*d6b92ffaSHans Petter Selasky Description : On ISR9288/9096 external ports indexing
1067*d6b92ffaSHans Petter Selasky is not matching the internal ( anafa ) port
1068*d6b92ffaSHans Petter Selasky indexes. Use this MAP to translate the data you get from
1069*d6b92ffaSHans Petter Selasky the OpenIB diagnostics (smpquery, ibroute, ibtracert, etc.)
1070*d6b92ffaSHans Petter Selasky
1071*d6b92ffaSHans Petter Selasky Module : sLB-24
1072*d6b92ffaSHans Petter Selasky anafa 1 anafa 2
1073*d6b92ffaSHans Petter Selasky ext port | 13 14 15 16 17 18 | 19 20 21 22 23 24
1074*d6b92ffaSHans Petter Selasky int port | 22 23 24 18 17 16 | 22 23 24 18 17 16
1075*d6b92ffaSHans Petter Selasky ext port | 1 2 3 4 5 6 | 7 8 9 10 11 12
1076*d6b92ffaSHans Petter Selasky int port | 19 20 21 15 14 13 | 19 20 21 15 14 13
1077*d6b92ffaSHans Petter Selasky ------------------------------------------------
1078*d6b92ffaSHans Petter Selasky
1079*d6b92ffaSHans Petter Selasky Module : sLB-8
1080*d6b92ffaSHans Petter Selasky anafa 1 anafa 2
1081*d6b92ffaSHans Petter Selasky ext port | 13 14 15 16 17 18 | 19 20 21 22 23 24
1082*d6b92ffaSHans Petter Selasky int port | 24 23 22 18 17 16 | 24 23 22 18 17 16
1083*d6b92ffaSHans Petter Selasky ext port | 1 2 3 4 5 6 | 7 8 9 10 11 12
1084*d6b92ffaSHans Petter Selasky int port | 21 20 19 15 14 13 | 21 20 19 15 14 13
1085*d6b92ffaSHans Petter Selasky
1086*d6b92ffaSHans Petter Selasky ----------->
1087*d6b92ffaSHans Petter Selasky anafa 1 anafa 2
1088*d6b92ffaSHans Petter Selasky ext port | - - 5 - - 6 | - - 7 - - 8
1089*d6b92ffaSHans Petter Selasky int port | 24 23 22 18 17 16 | 24 23 22 18 17 16
1090*d6b92ffaSHans Petter Selasky ext port | - - 1 - - 2 | - - 3 - - 4
1091*d6b92ffaSHans Petter Selasky int port | 21 20 19 15 14 13 | 21 20 19 15 14 13
1092*d6b92ffaSHans Petter Selasky ------------------------------------------------
1093*d6b92ffaSHans Petter Selasky
1094*d6b92ffaSHans Petter Selasky Module : sLB-2024
1095*d6b92ffaSHans Petter Selasky
1096*d6b92ffaSHans Petter Selasky ext port | 13 14 15 16 17 18 19 20 21 22 23 24
1097*d6b92ffaSHans Petter Selasky A1 int port| 13 14 15 16 17 18 19 20 21 22 23 24
1098*d6b92ffaSHans Petter Selasky ext port | 1 2 3 4 5 6 7 8 9 10 11 12
1099*d6b92ffaSHans Petter Selasky A2 int port| 13 14 15 16 17 18 19 20 21 22 23 24
1100*d6b92ffaSHans Petter Selasky ---------------------------------------------------
1101*d6b92ffaSHans Petter Selasky
1102*d6b92ffaSHans Petter Selasky Module : sLB-4018
1103*d6b92ffaSHans Petter Selasky
1104*d6b92ffaSHans Petter Selasky int port | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
1105*d6b92ffaSHans Petter Selasky ext port | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
1106*d6b92ffaSHans Petter Selasky ---------------------------------------------------
1107*d6b92ffaSHans Petter Selasky
1108*d6b92ffaSHans Petter Selasky Module : sFB-4700X2
1109*d6b92ffaSHans Petter Selasky
1110*d6b92ffaSHans Petter Selasky 12X port -> 3 x 4X ports:
1111*d6b92ffaSHans Petter Selasky
1112*d6b92ffaSHans Petter Selasky A1 int port | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
1113*d6b92ffaSHans Petter Selasky ext port | 7 7 7 8 8 8 9 9 9 10 10 10 11 11 11 12 12 12
1114*d6b92ffaSHans Petter Selasky A2 int port | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
1115*d6b92ffaSHans Petter Selasky ext port | 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 6 6
1116*d6b92ffaSHans Petter Selasky
1117*d6b92ffaSHans Petter Selasky */
1118*d6b92ffaSHans Petter Selasky
1119*d6b92ffaSHans Petter Selasky int int2ext_map_slb24[2][25] = {
1120*d6b92ffaSHans Petter Selasky {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 5, 4, 18, 17, 16, 1, 2, 3,
1121*d6b92ffaSHans Petter Selasky 13, 14, 15},
1122*d6b92ffaSHans Petter Selasky {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 11, 10, 24, 23, 22, 7, 8, 9,
1123*d6b92ffaSHans Petter Selasky 19, 20, 21}
1124*d6b92ffaSHans Petter Selasky };
1125*d6b92ffaSHans Petter Selasky
1126*d6b92ffaSHans Petter Selasky int int2ext_map_slb8[2][25] = {
1127*d6b92ffaSHans Petter Selasky {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 6, 6, 6, 1, 1, 1, 5, 5,
1128*d6b92ffaSHans Petter Selasky 5},
1129*d6b92ffaSHans Petter Selasky {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 8, 8, 8, 3, 3, 3, 7, 7,
1130*d6b92ffaSHans Petter Selasky 7}
1131*d6b92ffaSHans Petter Selasky };
1132*d6b92ffaSHans Petter Selasky
1133*d6b92ffaSHans Petter Selasky int int2ext_map_slb2024[2][25] = {
1134*d6b92ffaSHans Petter Selasky {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 14, 15, 16, 17, 18, 19, 20,
1135*d6b92ffaSHans Petter Selasky 21, 22, 23, 24},
1136*d6b92ffaSHans Petter Selasky {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
1137*d6b92ffaSHans Petter Selasky 11, 12}
1138*d6b92ffaSHans Petter Selasky };
1139*d6b92ffaSHans Petter Selasky
1140*d6b92ffaSHans Petter Selasky int int2ext_map_slb4018[37] = {
1141*d6b92ffaSHans Petter Selasky 0,
1142*d6b92ffaSHans Petter Selasky 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1143*d6b92ffaSHans Petter Selasky 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18
1144*d6b92ffaSHans Petter Selasky };
1145*d6b92ffaSHans Petter Selasky
1146*d6b92ffaSHans Petter Selasky int int2ext_map_sfb4700x2[2][37] = {
1147*d6b92ffaSHans Petter Selasky {0,
1148*d6b92ffaSHans Petter Selasky 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1149*d6b92ffaSHans Petter Selasky 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 12},
1150*d6b92ffaSHans Petter Selasky {0,
1151*d6b92ffaSHans Petter Selasky 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1152*d6b92ffaSHans Petter Selasky 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6}
1153*d6b92ffaSHans Petter Selasky };
1154*d6b92ffaSHans Petter Selasky
1155*d6b92ffaSHans Petter Selasky /* reference { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 }; */
1156*d6b92ffaSHans Petter Selasky
1157*d6b92ffaSHans Petter Selasky /* map internal ports to external ports if appropriate */
voltaire_portmap(ibnd_port_t * port)1158*d6b92ffaSHans Petter Selasky static void voltaire_portmap(ibnd_port_t * port)
1159*d6b92ffaSHans Petter Selasky {
1160*d6b92ffaSHans Petter Selasky int portnum = port->portnum;
1161*d6b92ffaSHans Petter Selasky int chipnum = 0;
1162*d6b92ffaSHans Petter Selasky ibnd_node_t *node = port->node;
1163*d6b92ffaSHans Petter Selasky int is_4700_line = is_line_4700(node);
1164*d6b92ffaSHans Petter Selasky int is_4700x2_spine = is_spine_4700x2(node);
1165*d6b92ffaSHans Petter Selasky
1166*d6b92ffaSHans Petter Selasky if (!node->ch_found || (!is_line(node) && !is_4700x2_spine)) {
1167*d6b92ffaSHans Petter Selasky port->ext_portnum = 0;
1168*d6b92ffaSHans Petter Selasky return;
1169*d6b92ffaSHans Petter Selasky }
1170*d6b92ffaSHans Petter Selasky
1171*d6b92ffaSHans Petter Selasky if (((is_4700_line || is_4700x2_spine) &&
1172*d6b92ffaSHans Petter Selasky (portnum < 19 || portnum > 36)) ||
1173*d6b92ffaSHans Petter Selasky ((!is_4700_line && !is_4700x2_spine) &&
1174*d6b92ffaSHans Petter Selasky (portnum < 13 || portnum > 24))) {
1175*d6b92ffaSHans Petter Selasky port->ext_portnum = 0;
1176*d6b92ffaSHans Petter Selasky return;
1177*d6b92ffaSHans Petter Selasky }
1178*d6b92ffaSHans Petter Selasky
1179*d6b92ffaSHans Petter Selasky if (port->node->ch_anafanum < 1 || port->node->ch_anafanum > 2) {
1180*d6b92ffaSHans Petter Selasky port->ext_portnum = 0;
1181*d6b92ffaSHans Petter Selasky return;
1182*d6b92ffaSHans Petter Selasky }
1183*d6b92ffaSHans Petter Selasky
1184*d6b92ffaSHans Petter Selasky chipnum = port->node->ch_anafanum - 1;
1185*d6b92ffaSHans Petter Selasky
1186*d6b92ffaSHans Petter Selasky if (is_line_24(node))
1187*d6b92ffaSHans Petter Selasky port->ext_portnum = int2ext_map_slb24[chipnum][portnum];
1188*d6b92ffaSHans Petter Selasky else if (is_line_2024(node))
1189*d6b92ffaSHans Petter Selasky port->ext_portnum = int2ext_map_slb2024[chipnum][portnum];
1190*d6b92ffaSHans Petter Selasky /* sLB-4018: Only one asic per LB */
1191*d6b92ffaSHans Petter Selasky else if (is_4700_line)
1192*d6b92ffaSHans Petter Selasky port->ext_portnum = int2ext_map_slb4018[portnum];
1193*d6b92ffaSHans Petter Selasky /* sFB-4700X2 4X port */
1194*d6b92ffaSHans Petter Selasky else if (is_4700x2_spine)
1195*d6b92ffaSHans Petter Selasky port->ext_portnum = int2ext_map_sfb4700x2[chipnum][portnum];
1196*d6b92ffaSHans Petter Selasky else
1197*d6b92ffaSHans Petter Selasky port->ext_portnum = int2ext_map_slb8[chipnum][portnum];
1198*d6b92ffaSHans Petter Selasky }
1199*d6b92ffaSHans Petter Selasky
add_chassis(chassis_scan_t * chassis_scan)1200*d6b92ffaSHans Petter Selasky static int add_chassis(chassis_scan_t * chassis_scan)
1201*d6b92ffaSHans Petter Selasky {
1202*d6b92ffaSHans Petter Selasky if (!(chassis_scan->current_chassis =
1203*d6b92ffaSHans Petter Selasky calloc(1, sizeof(ibnd_chassis_t)))) {
1204*d6b92ffaSHans Petter Selasky IBND_ERROR("OOM: failed to allocate chassis object\n");
1205*d6b92ffaSHans Petter Selasky return -1;
1206*d6b92ffaSHans Petter Selasky }
1207*d6b92ffaSHans Petter Selasky
1208*d6b92ffaSHans Petter Selasky if (chassis_scan->first_chassis == NULL) {
1209*d6b92ffaSHans Petter Selasky chassis_scan->first_chassis = chassis_scan->current_chassis;
1210*d6b92ffaSHans Petter Selasky chassis_scan->last_chassis = chassis_scan->current_chassis;
1211*d6b92ffaSHans Petter Selasky } else {
1212*d6b92ffaSHans Petter Selasky chassis_scan->last_chassis->next =
1213*d6b92ffaSHans Petter Selasky chassis_scan->current_chassis;
1214*d6b92ffaSHans Petter Selasky chassis_scan->last_chassis = chassis_scan->current_chassis;
1215*d6b92ffaSHans Petter Selasky }
1216*d6b92ffaSHans Petter Selasky return 0;
1217*d6b92ffaSHans Petter Selasky }
1218*d6b92ffaSHans Petter Selasky
add_node_to_chassis(ibnd_chassis_t * chassis,ibnd_node_t * node)1219*d6b92ffaSHans Petter Selasky static void add_node_to_chassis(ibnd_chassis_t * chassis, ibnd_node_t * node)
1220*d6b92ffaSHans Petter Selasky {
1221*d6b92ffaSHans Petter Selasky node->chassis = chassis;
1222*d6b92ffaSHans Petter Selasky node->next_chassis_node = chassis->nodes;
1223*d6b92ffaSHans Petter Selasky chassis->nodes = node;
1224*d6b92ffaSHans Petter Selasky }
1225*d6b92ffaSHans Petter Selasky
1226*d6b92ffaSHans Petter Selasky /*
1227*d6b92ffaSHans Petter Selasky Main grouping function
1228*d6b92ffaSHans Petter Selasky Algorithm:
1229*d6b92ffaSHans Petter Selasky 1. pass on every Voltaire node
1230*d6b92ffaSHans Petter Selasky 2. catch spine chip for every Voltaire node
1231*d6b92ffaSHans Petter Selasky 2.1 build/interpolate chassis around this chip
1232*d6b92ffaSHans Petter Selasky 2.2 go to 1.
1233*d6b92ffaSHans Petter Selasky 3. pass on non Voltaire nodes (SystemImageGUID based grouping)
1234*d6b92ffaSHans Petter Selasky 4. now group non Voltaire nodes by SystemImageGUID
1235*d6b92ffaSHans Petter Selasky Returns:
1236*d6b92ffaSHans Petter Selasky 0 on success, -1 on failure
1237*d6b92ffaSHans Petter Selasky */
group_nodes(ibnd_fabric_t * fabric)1238*d6b92ffaSHans Petter Selasky int group_nodes(ibnd_fabric_t * fabric)
1239*d6b92ffaSHans Petter Selasky {
1240*d6b92ffaSHans Petter Selasky ibnd_node_t *node;
1241*d6b92ffaSHans Petter Selasky int chassisnum = 0;
1242*d6b92ffaSHans Petter Selasky ibnd_chassis_t *chassis;
1243*d6b92ffaSHans Petter Selasky ibnd_chassis_t *ch, *ch_next;
1244*d6b92ffaSHans Petter Selasky chassis_scan_t chassis_scan;
1245*d6b92ffaSHans Petter Selasky int vendor_id;
1246*d6b92ffaSHans Petter Selasky
1247*d6b92ffaSHans Petter Selasky chassis_scan.first_chassis = NULL;
1248*d6b92ffaSHans Petter Selasky chassis_scan.current_chassis = NULL;
1249*d6b92ffaSHans Petter Selasky chassis_scan.last_chassis = NULL;
1250*d6b92ffaSHans Petter Selasky
1251*d6b92ffaSHans Petter Selasky /* first pass on switches and build for every Voltaire node */
1252*d6b92ffaSHans Petter Selasky /* an appropriate chassis record (slotnum and position) */
1253*d6b92ffaSHans Petter Selasky /* according to internal connectivity */
1254*d6b92ffaSHans Petter Selasky /* not very efficient but clear code so... */
1255*d6b92ffaSHans Petter Selasky for (node = fabric->switches; node; node = node->type_next) {
1256*d6b92ffaSHans Petter Selasky
1257*d6b92ffaSHans Petter Selasky vendor_id = mad_get_field(node->info, 0,IB_NODE_VENDORID_F);
1258*d6b92ffaSHans Petter Selasky
1259*d6b92ffaSHans Petter Selasky if (vendor_id == VTR_VENDOR_ID
1260*d6b92ffaSHans Petter Selasky && fill_voltaire_chassis_record(node))
1261*d6b92ffaSHans Petter Selasky goto cleanup;
1262*d6b92ffaSHans Petter Selasky else if (vendor_id == MLX_VENDOR_ID
1263*d6b92ffaSHans Petter Selasky && fill_mellanox_chassis_record(node))
1264*d6b92ffaSHans Petter Selasky goto cleanup;
1265*d6b92ffaSHans Petter Selasky
1266*d6b92ffaSHans Petter Selasky }
1267*d6b92ffaSHans Petter Selasky
1268*d6b92ffaSHans Petter Selasky /* separate every Voltaire chassis from each other and build linked list of them */
1269*d6b92ffaSHans Petter Selasky /* algorithm: catch spine and find all surrounding nodes */
1270*d6b92ffaSHans Petter Selasky for (node = fabric->switches; node; node = node->type_next) {
1271*d6b92ffaSHans Petter Selasky if (mad_get_field(node->info, 0,
1272*d6b92ffaSHans Petter Selasky IB_NODE_VENDORID_F) != VTR_VENDOR_ID)
1273*d6b92ffaSHans Petter Selasky continue;
1274*d6b92ffaSHans Petter Selasky if (!node->ch_found
1275*d6b92ffaSHans Petter Selasky || (node->chassis && node->chassis->chassisnum)
1276*d6b92ffaSHans Petter Selasky || !is_spine(node))
1277*d6b92ffaSHans Petter Selasky continue;
1278*d6b92ffaSHans Petter Selasky if (add_chassis(&chassis_scan))
1279*d6b92ffaSHans Petter Selasky goto cleanup;
1280*d6b92ffaSHans Petter Selasky chassis_scan.current_chassis->chassisnum = ++chassisnum;
1281*d6b92ffaSHans Petter Selasky if (build_chassis(node, chassis_scan.current_chassis))
1282*d6b92ffaSHans Petter Selasky goto cleanup;
1283*d6b92ffaSHans Petter Selasky }
1284*d6b92ffaSHans Petter Selasky
1285*d6b92ffaSHans Petter Selasky /* now make pass on nodes for chassis which are not Voltaire */
1286*d6b92ffaSHans Petter Selasky /* grouped by common SystemImageGUID */
1287*d6b92ffaSHans Petter Selasky for (node = fabric->nodes; node; node = node->next) {
1288*d6b92ffaSHans Petter Selasky if (mad_get_field(node->info, 0,
1289*d6b92ffaSHans Petter Selasky IB_NODE_VENDORID_F) == VTR_VENDOR_ID)
1290*d6b92ffaSHans Petter Selasky continue;
1291*d6b92ffaSHans Petter Selasky if (mad_get_field64(node->info, 0, IB_NODE_SYSTEM_GUID_F)) {
1292*d6b92ffaSHans Petter Selasky chassis = find_chassisguid(fabric, node);
1293*d6b92ffaSHans Petter Selasky if (chassis)
1294*d6b92ffaSHans Petter Selasky chassis->nodecount++;
1295*d6b92ffaSHans Petter Selasky else {
1296*d6b92ffaSHans Petter Selasky /* Possible new chassis */
1297*d6b92ffaSHans Petter Selasky if (add_chassis(&chassis_scan))
1298*d6b92ffaSHans Petter Selasky goto cleanup;
1299*d6b92ffaSHans Petter Selasky chassis_scan.current_chassis->chassisguid =
1300*d6b92ffaSHans Petter Selasky get_chassisguid(node);
1301*d6b92ffaSHans Petter Selasky chassis_scan.current_chassis->nodecount = 1;
1302*d6b92ffaSHans Petter Selasky if (!fabric->chassis)
1303*d6b92ffaSHans Petter Selasky fabric->chassis = chassis_scan.first_chassis;
1304*d6b92ffaSHans Petter Selasky }
1305*d6b92ffaSHans Petter Selasky }
1306*d6b92ffaSHans Petter Selasky }
1307*d6b92ffaSHans Petter Selasky
1308*d6b92ffaSHans Petter Selasky /* now, make another pass to see which nodes are part of chassis */
1309*d6b92ffaSHans Petter Selasky /* (defined as chassis->nodecount > 1) */
1310*d6b92ffaSHans Petter Selasky for (node = fabric->nodes; node; node = node->next) {
1311*d6b92ffaSHans Petter Selasky
1312*d6b92ffaSHans Petter Selasky vendor_id = mad_get_field(node->info, 0,IB_NODE_VENDORID_F);
1313*d6b92ffaSHans Petter Selasky
1314*d6b92ffaSHans Petter Selasky if (vendor_id == VTR_VENDOR_ID)
1315*d6b92ffaSHans Petter Selasky continue;
1316*d6b92ffaSHans Petter Selasky if (mad_get_field64(node->info, 0, IB_NODE_SYSTEM_GUID_F)) {
1317*d6b92ffaSHans Petter Selasky chassis = find_chassisguid(fabric, node);
1318*d6b92ffaSHans Petter Selasky if (chassis && chassis->nodecount > 1) {
1319*d6b92ffaSHans Petter Selasky if (!chassis->chassisnum)
1320*d6b92ffaSHans Petter Selasky chassis->chassisnum = ++chassisnum;
1321*d6b92ffaSHans Petter Selasky if (!node->ch_found) {
1322*d6b92ffaSHans Petter Selasky node->ch_found = 1;
1323*d6b92ffaSHans Petter Selasky add_node_to_chassis(chassis, node);
1324*d6b92ffaSHans Petter Selasky }
1325*d6b92ffaSHans Petter Selasky else if (vendor_id == MLX_VENDOR_ID){
1326*d6b92ffaSHans Petter Selasky insert_mellanox_line_and_spine(node, chassis);
1327*d6b92ffaSHans Petter Selasky }
1328*d6b92ffaSHans Petter Selasky }
1329*d6b92ffaSHans Petter Selasky }
1330*d6b92ffaSHans Petter Selasky }
1331*d6b92ffaSHans Petter Selasky
1332*d6b92ffaSHans Petter Selasky fabric->chassis = chassis_scan.first_chassis;
1333*d6b92ffaSHans Petter Selasky return 0;
1334*d6b92ffaSHans Petter Selasky
1335*d6b92ffaSHans Petter Selasky cleanup:
1336*d6b92ffaSHans Petter Selasky ch = chassis_scan.first_chassis;
1337*d6b92ffaSHans Petter Selasky while (ch) {
1338*d6b92ffaSHans Petter Selasky ch_next = ch->next;
1339*d6b92ffaSHans Petter Selasky free(ch);
1340*d6b92ffaSHans Petter Selasky ch = ch_next;
1341*d6b92ffaSHans Petter Selasky }
1342*d6b92ffaSHans Petter Selasky fabric->chassis = NULL;
1343*d6b92ffaSHans Petter Selasky return -1;
1344*d6b92ffaSHans Petter Selasky }
1345