Explorar el Código

[infiniband] Update subnet management agent to use a management interface

tags/v0.9.8
Michael Brown hace 15 años
padre
commit
44251ebb9a

+ 4
- 4
src/drivers/infiniband/linda.c Ver fichero

@@ -1606,15 +1606,15 @@ static int linda_read_eeprom ( struct linda *linda,
1606 1606
 
1607 1607
 	/* Read GUID */
1608 1608
 	if ( ( rc = i2c->read ( i2c, &linda->eeprom, LINDA_EEPROM_GUID_OFFSET,
1609
-				guid->bytes, sizeof ( *guid ) ) ) != 0 ) {
1609
+				guid->u.bytes, sizeof ( *guid ) ) ) != 0 ) {
1610 1610
 		DBGC ( linda, "Linda %p could not read GUID: %s\n",
1611 1611
 		       linda, strerror ( rc ) );
1612 1612
 		return rc;
1613 1613
 	}
1614 1614
 	DBGC2 ( linda, "Linda %p has GUID %02x:%02x:%02x:%02x:%02x:%02x:"
1615
-		"%02x:%02x\n", linda, guid->bytes[0], guid->bytes[1],
1616
-		guid->bytes[2], guid->bytes[3], guid->bytes[4],
1617
-		guid->bytes[5], guid->bytes[6], guid->bytes[7] );
1615
+		"%02x:%02x\n", linda, guid->u.bytes[0], guid->u.bytes[1],
1616
+		guid->u.bytes[2], guid->u.bytes[3], guid->u.bytes[4],
1617
+		guid->u.bytes[5], guid->u.bytes[6], guid->u.bytes[7] );
1618 1618
 
1619 1619
 	/* Read serial number (debug only) */
1620 1620
 	if ( DBG_LOG ) {

+ 0
- 3
src/include/gpxe/ib_mad.h Ver fichero

@@ -30,9 +30,6 @@ struct ib_smp_hdr {
30 30
 	uint8_t reserved[28];
31 31
 } __attribute__ (( packed ));
32 32
 
33
-/** Bits to ignore in the management class for subnet management MADs */
34
-#define IB_SMP_CLASS_IGNORE			0x80
35
-
36 33
 /** Subnet management class version */
37 34
 #define IB_SMP_CLASS_VERSION			1
38 35
 

+ 5
- 1
src/include/gpxe/ib_packet.h Ver fichero

@@ -16,7 +16,11 @@ struct io_buffer;
16 16
 
17 17
 /** Half of an Infiniband Global Identifier */
18 18
 struct ib_gid_half {
19
-	uint8_t bytes[8];
19
+	union {
20
+		uint8_t bytes[8];
21
+		uint16_t words[4];
22
+		uint32_t dwords[2];
23
+	} u;
20 24
 };
21 25
 
22 26
 /** An Infiniband Global Identifier */

+ 20
- 0
src/include/gpxe/ib_sma.h Ver fichero

@@ -0,0 +1,20 @@
1
+#ifndef _GPXE_IB_SMA_H
2
+#define _GPXE_IB_SMA_H
3
+
4
+/** @file
5
+ *
6
+ * Infiniband subnet management agent
7
+ *
8
+ */
9
+
10
+FILE_LICENCE ( GPL2_OR_LATER );
11
+
12
+struct ib_device;
13
+struct ib_mad_interface;
14
+
15
+extern int ib_create_sma ( struct ib_device *ibdev,
16
+			   struct ib_mad_interface *mi );
17
+extern void ib_destroy_sma ( struct ib_device *ibdev,
18
+			     struct ib_mad_interface *mi );
19
+
20
+#endif /* _GPXE_IB_SMA_H */

+ 3
- 2
src/include/gpxe/infiniband.h Ver fichero

@@ -45,6 +45,7 @@ struct ib_device;
45 45
 struct ib_queue_pair;
46 46
 struct ib_address_vector;
47 47
 struct ib_completion_queue;
48
+struct ib_mad_interface;
48 49
 struct ib_gma;
49 50
 
50 51
 /** Infiniband transmission rates */
@@ -413,8 +414,8 @@ struct ib_device {
413 414
 	 */
414 415
 	uint32_t rdma_key;
415 416
 
416
-	/** Subnet management agent */
417
-	struct ib_gma *sma;
417
+	/** Subnet management interface */
418
+	struct ib_mad_interface *smi;
418 419
 	/** General management agent */
419 420
 	struct ib_gma *gma;
420 421
 

+ 18
- 6
src/net/infiniband.c Ver fichero

@@ -33,6 +33,8 @@ FILE_LICENCE ( GPL2_OR_LATER );
33 33
 #include <gpxe/ipoib.h>
34 34
 #include <gpxe/process.h>
35 35
 #include <gpxe/infiniband.h>
36
+#include <gpxe/ib_mi.h>
37
+#include <gpxe/ib_sma.h>
36 38
 #include <gpxe/ib_gma.h>
37 39
 
38 40
 /** @file
@@ -534,11 +536,18 @@ int ib_open ( struct ib_device *ibdev ) {
534 536
 		return 0;
535 537
 	}
536 538
 
537
-	/* Create subnet management agent */
538
-	ibdev->sma = ib_create_gma ( ibdev, IB_QPT_SMI );
539
-	if ( ! ibdev->sma ) {
540
-		DBGC ( ibdev, "IBDEV %p could not create SMA\n", ibdev );
539
+	/* Create subnet management interface */
540
+	ibdev->smi = ib_create_mi ( ibdev, IB_QPT_SMI );
541
+	if ( ! ibdev->smi ) {
542
+		DBGC ( ibdev, "IBDEV %p could not create SMI\n", ibdev );
541 543
 		rc = -ENOMEM;
544
+		goto err_create_smi;
545
+	}
546
+
547
+	/* Create subnet management agent */
548
+	if ( ( rc = ib_create_sma ( ibdev, ibdev->smi ) ) != 0 ) {
549
+		DBGC ( ibdev, "IBDEV %p could not create SMA: %s\n",
550
+		       ibdev, strerror ( rc ) );
542 551
 		goto err_create_sma;
543 552
 	}
544 553
 
@@ -564,8 +573,10 @@ int ib_open ( struct ib_device *ibdev ) {
564 573
  err_open:
565 574
 	ib_destroy_gma ( ibdev->gma );
566 575
  err_create_gma:
567
-	ib_destroy_gma ( ibdev->sma );
576
+	ib_destroy_sma ( ibdev, ibdev->smi );
568 577
  err_create_sma:
578
+	ib_destroy_mi ( ibdev, ibdev->smi );
579
+ err_create_smi:
569 580
 	assert ( ibdev->open_count == 1 );
570 581
 	ibdev->open_count = 0;
571 582
 	return rc;
@@ -584,7 +595,8 @@ void ib_close ( struct ib_device *ibdev ) {
584 595
 	/* Close device if this was the last remaining requested opening */
585 596
 	if ( ibdev->open_count == 0 ) {
586 597
 		ib_destroy_gma ( ibdev->gma );
587
-		ib_destroy_gma ( ibdev->sma );
598
+		ib_destroy_sma ( ibdev, ibdev->smi );
599
+		ib_destroy_mi ( ibdev, ibdev->smi );
588 600
 		ibdev->op->close ( ibdev );
589 601
 	}
590 602
 }

+ 0
- 297
src/net/infiniband/ib_gma.c Ver fichero

@@ -74,303 +74,6 @@ struct ib_mad_request {
74 74
 /** TID to use for next MAD request */
75 75
 static unsigned int next_request_tid;
76 76
 
77
-/*****************************************************************************
78
- *
79
- * Subnet management MAD handlers
80
- *
81
- *****************************************************************************
82
- */
83
-
84
-/**
85
- * Construct directed route response, if necessary
86
- *
87
- * @v gma		General management agent
88
- * @v mad		MAD response without DR fields filled in
89
- * @ret mad		MAD response with DR fields filled in
90
- */
91
-static union ib_mad * ib_sma_dr_response ( struct ib_gma *gma,
92
-					   union ib_mad *mad ) {
93
-	struct ib_mad_hdr *hdr = &mad->hdr;
94
-	struct ib_mad_smp *smp = &mad->smp;
95
-	unsigned int hop_pointer;
96
-	unsigned int hop_count;
97
-
98
-	/* Set response fields for directed route SMPs */
99
-	if ( hdr->mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE ) {
100
-		hdr->status |= htons ( IB_SMP_STATUS_D_INBOUND );
101
-		hop_pointer = smp->mad_hdr.class_specific.smp.hop_pointer;
102
-		hop_count = smp->mad_hdr.class_specific.smp.hop_count;
103
-		assert ( hop_count == hop_pointer );
104
-		if ( hop_pointer < ( sizeof ( smp->return_path.hops ) /
105
-				     sizeof ( smp->return_path.hops[0] ) ) ) {
106
-			smp->return_path.hops[hop_pointer] = gma->ibdev->port;
107
-		} else {
108
-			DBGC ( gma, "GMA %p invalid hop pointer %d\n",
109
-			       gma, hop_pointer );
110
-			return NULL;
111
-		}
112
-	}
113
-
114
-	return mad;
115
-}
116
-
117
-/**
118
- * Get node information
119
- *
120
- * @v gma		General management agent
121
- * @v mad		MAD
122
- * @ret response	MAD response
123
- */
124
-static union ib_mad * ib_sma_get_node_info ( struct ib_gma *gma,
125
-					     union ib_mad *mad ) {
126
-	struct ib_device *ibdev = gma->ibdev;
127
-	struct ib_node_info *node_info = &mad->smp.smp_data.node_info;
128
-
129
-	memset ( node_info, 0, sizeof ( *node_info ) );
130
-	node_info->base_version = IB_MGMT_BASE_VERSION;
131
-	node_info->class_version = IB_SMP_CLASS_VERSION;
132
-	node_info->node_type = IB_NODE_TYPE_HCA;
133
-	node_info->num_ports = ib_get_hca_info ( ibdev, &node_info->sys_guid );
134
-	memcpy ( &node_info->node_guid, &node_info->sys_guid,
135
-		 sizeof ( node_info->node_guid ) );
136
-	memcpy ( &node_info->port_guid, &ibdev->gid.u.half[1],
137
-		 sizeof ( node_info->port_guid ) );
138
-	node_info->partition_cap = htons ( 1 );
139
-	node_info->local_port_num = ibdev->port;
140
-
141
-	mad->hdr.method = IB_MGMT_METHOD_GET_RESP;
142
-	return ib_sma_dr_response ( gma, mad );
143
-}
144
-
145
-/**
146
- * Get node description
147
- *
148
- * @v gma		General management agent
149
- * @v mad		MAD
150
- * @ret response	MAD response
151
- */
152
-static union ib_mad * ib_sma_get_node_desc ( struct ib_gma *gma,
153
-					     union ib_mad *mad ) {
154
-	struct ib_device *ibdev = gma->ibdev;
155
-	struct ib_node_desc *node_desc = &mad->smp.smp_data.node_desc;
156
-	struct ib_gid_half *guid = &ibdev->gid.u.half[1];
157
-
158
-	memset ( node_desc, 0, sizeof ( *node_desc ) );
159
-	snprintf ( node_desc->node_string, sizeof ( node_desc->node_string ),
160
-		   "gPXE %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x (%s)",
161
-		   guid->bytes[0], guid->bytes[1], guid->bytes[2],
162
-		   guid->bytes[3], guid->bytes[4], guid->bytes[5],
163
-		   guid->bytes[6], guid->bytes[7], ibdev->dev->name );
164
-
165
-	mad->hdr.method = IB_MGMT_METHOD_GET_RESP;
166
-	return ib_sma_dr_response ( gma, mad );
167
-}
168
-
169
-/**
170
- * Get GUID information
171
- *
172
- * @v gma		General management agent
173
- * @v mad		MAD
174
- * @ret response	MAD response
175
- */
176
-static union ib_mad * ib_sma_get_guid_info ( struct ib_gma *gma,
177
-					     union ib_mad *mad ) {
178
-	struct ib_device *ibdev = gma->ibdev;
179
-	struct ib_guid_info *guid_info = &mad->smp.smp_data.guid_info;
180
-
181
-	memset ( guid_info, 0, sizeof ( *guid_info ) );
182
-	memcpy ( guid_info->guid[0], &ibdev->gid.u.half[1],
183
-		 sizeof ( guid_info->guid[0] ) );
184
-
185
-	mad->hdr.method = IB_MGMT_METHOD_GET_RESP;
186
-	return ib_sma_dr_response ( gma, mad );
187
-}
188
-
189
-/**
190
- * Get port information
191
- *
192
- * @v gma		General management agent
193
- * @v mad		MAD
194
- * @ret response	MAD response
195
- */
196
-static union ib_mad * ib_sma_get_port_info ( struct ib_gma *gma,
197
-					     union ib_mad *mad ) {
198
-	struct ib_device *ibdev = gma->ibdev;
199
-	struct ib_port_info *port_info = &mad->smp.smp_data.port_info;
200
-
201
-	memset ( port_info, 0, sizeof ( *port_info ) );
202
-	memcpy ( port_info->gid_prefix, &ibdev->gid.u.half[0],
203
-		 sizeof ( port_info->gid_prefix ) );
204
-	port_info->lid = ntohs ( ibdev->lid );
205
-	port_info->mastersm_lid = ntohs ( ibdev->sm_lid );
206
-	port_info->local_port_num = ibdev->port;
207
-	port_info->link_width_enabled = ibdev->link_width_enabled;
208
-	port_info->link_width_supported = ibdev->link_width_supported;
209
-	port_info->link_width_active = ibdev->link_width_active;
210
-	port_info->link_speed_supported__port_state =
211
-		( ( ibdev->link_speed_supported << 4 ) | ibdev->port_state );
212
-	port_info->port_phys_state__link_down_def_state =
213
-		( ( IB_PORT_PHYS_STATE_POLLING << 4 ) |
214
-		  IB_PORT_PHYS_STATE_POLLING );
215
-	port_info->link_speed_active__link_speed_enabled =
216
-		( ( ibdev->link_speed_active << 4 ) |
217
-		  ibdev->link_speed_enabled );
218
-	port_info->neighbour_mtu__mastersm_sl =
219
-		( ( IB_MTU_2048 << 4 ) | ibdev->sm_sl );
220
-	port_info->vl_cap__init_type = ( IB_VL_0 << 4 );
221
-	port_info->init_type_reply__mtu_cap = IB_MTU_2048;
222
-	port_info->operational_vls__enforcement = ( IB_VL_0 << 4 );
223
-	port_info->guid_cap = 1;
224
-
225
-	mad->hdr.method = IB_MGMT_METHOD_GET_RESP;
226
-	return ib_sma_dr_response ( gma, mad );
227
-}
228
-
229
-/**
230
- * Set port information
231
- *
232
- * @v gma		General management agent
233
- * @v mad		MAD
234
- * @ret response	MAD response
235
- */
236
-static union ib_mad * ib_sma_set_port_info ( struct ib_gma *gma,
237
-					     union ib_mad *mad ) {
238
-	struct ib_device *ibdev = gma->ibdev;
239
-	const struct ib_port_info *port_info = &mad->smp.smp_data.port_info;
240
-	unsigned int link_width_enabled;
241
-	unsigned int link_speed_enabled;
242
-	int rc;
243
-
244
-	memcpy ( &ibdev->gid.u.half[0], port_info->gid_prefix,
245
-		 sizeof ( ibdev->gid.u.half[0] ) );
246
-	ibdev->lid = ntohs ( port_info->lid );
247
-	ibdev->sm_lid = ntohs ( port_info->mastersm_lid );
248
-	if ( ( link_width_enabled = port_info->link_width_enabled ) )
249
-		ibdev->link_width_enabled = link_width_enabled;
250
-	if ( ( link_speed_enabled =
251
-	       ( port_info->link_speed_active__link_speed_enabled & 0xf ) ) )
252
-		ibdev->link_speed_enabled = link_speed_enabled;
253
-	ibdev->sm_sl = ( port_info->neighbour_mtu__mastersm_sl & 0xf );
254
-	DBGC ( gma, "GMA %p set LID %04x SMLID %04x link width %02x speed "
255
-	       "%02x\n", gma, ibdev->lid, ibdev->sm_lid,
256
-	       ibdev->link_width_enabled, ibdev->link_speed_enabled );
257
-
258
-	if ( ( rc = ib_set_port_info ( ibdev, mad ) ) != 0 ) {
259
-		DBGC ( gma, "GMA %p could not set port information: %s\n",
260
-		       gma, strerror ( rc ) );
261
-		mad->hdr.status =
262
-			htons ( IB_MGMT_STATUS_UNSUPPORTED_METHOD_ATTR );
263
-	}
264
-
265
-	return ib_sma_get_port_info ( gma, mad );
266
-}
267
-
268
-/**
269
- * Get partition key table
270
- *
271
- * @v gma		General management agent
272
- * @v mad		MAD
273
- * @ret response	MAD response
274
- */
275
-static union ib_mad * ib_sma_get_pkey_table ( struct ib_gma *gma,
276
-					      union ib_mad *mad ) {
277
-	struct ib_device *ibdev = gma->ibdev;
278
-	struct ib_pkey_table *pkey_table = &mad->smp.smp_data.pkey_table;
279
-
280
-	mad->hdr.method = IB_MGMT_METHOD_GET_RESP;
281
-	memset ( pkey_table, 0, sizeof ( *pkey_table ) );
282
-	pkey_table->pkey[0] = htons ( ibdev->pkey );
283
-
284
-	mad->hdr.method = IB_MGMT_METHOD_GET_RESP;
285
-	return ib_sma_dr_response ( gma, mad );
286
-}
287
-
288
-/**
289
- * Set partition key table
290
- *
291
- * @v gma		General management agent
292
- * @v mad		MAD
293
- * @ret response	MAD response
294
- */
295
-static union ib_mad * ib_sma_set_pkey_table ( struct ib_gma *gma,
296
-					      union ib_mad *mad ) {
297
-	struct ib_device *ibdev = gma->ibdev;
298
-	struct ib_pkey_table *pkey_table = &mad->smp.smp_data.pkey_table;
299
-	int rc;
300
-
301
-	ibdev->pkey = ntohs ( pkey_table->pkey[0] );
302
-	DBGC ( gma, "GMA %p set pkey %04x\n", gma, ibdev->pkey );
303
-
304
-	if ( ( rc = ib_set_pkey_table ( ibdev, mad ) ) != 0 ) {
305
-		DBGC ( gma, "GMA %p could not set pkey table: %s\n",
306
-		       gma, strerror ( rc ) );
307
-		mad->hdr.status =
308
-			htons ( IB_MGMT_STATUS_UNSUPPORTED_METHOD_ATTR );
309
-	}
310
-
311
-	return ib_sma_get_pkey_table ( gma, mad );
312
-}
313
-
314
-/** List of attribute handlers */
315
-struct ib_gma_handler ib_sma_handlers[] __ib_gma_handler = {
316
-	{
317
-		.mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED,
318
-		.mgmt_class_ignore = IB_SMP_CLASS_IGNORE,
319
-		.class_version = IB_SMP_CLASS_VERSION,
320
-		.method = IB_MGMT_METHOD_GET,
321
-		.attr_id = htons ( IB_SMP_ATTR_NODE_INFO ),
322
-		.handle = ib_sma_get_node_info,
323
-	},
324
-	{
325
-		.mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED,
326
-		.mgmt_class_ignore = IB_SMP_CLASS_IGNORE,
327
-		.class_version = IB_SMP_CLASS_VERSION,
328
-		.method = IB_MGMT_METHOD_GET,
329
-		.attr_id = htons ( IB_SMP_ATTR_NODE_DESC ),
330
-		.handle = ib_sma_get_node_desc,
331
-	},
332
-	{
333
-		.mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED,
334
-		.mgmt_class_ignore = IB_SMP_CLASS_IGNORE,
335
-		.class_version = IB_SMP_CLASS_VERSION,
336
-		.method = IB_MGMT_METHOD_GET,
337
-		.attr_id = htons ( IB_SMP_ATTR_GUID_INFO ),
338
-		.handle = ib_sma_get_guid_info,
339
-	},
340
-	{
341
-		.mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED,
342
-		.mgmt_class_ignore = IB_SMP_CLASS_IGNORE,
343
-		.class_version = IB_SMP_CLASS_VERSION,
344
-		.method = IB_MGMT_METHOD_GET,
345
-		.attr_id = htons ( IB_SMP_ATTR_PORT_INFO ),
346
-		.handle = ib_sma_get_port_info,
347
-	},
348
-	{
349
-		.mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED,
350
-		.mgmt_class_ignore = IB_SMP_CLASS_IGNORE,
351
-		.class_version = IB_SMP_CLASS_VERSION,
352
-		.method = IB_MGMT_METHOD_SET,
353
-		.attr_id = htons ( IB_SMP_ATTR_PORT_INFO ),
354
-		.handle = ib_sma_set_port_info,
355
-	},
356
-	{
357
-		.mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED,
358
-		.mgmt_class_ignore = IB_SMP_CLASS_IGNORE,
359
-		.class_version = IB_SMP_CLASS_VERSION,
360
-		.method = IB_MGMT_METHOD_GET,
361
-		.attr_id = htons ( IB_SMP_ATTR_PKEY_TABLE ),
362
-		.handle = ib_sma_get_pkey_table,
363
-	},
364
-	{
365
-		.mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED,
366
-		.mgmt_class_ignore = IB_SMP_CLASS_IGNORE,
367
-		.class_version = IB_SMP_CLASS_VERSION,
368
-		.method = IB_MGMT_METHOD_SET,
369
-		.attr_id = htons ( IB_SMP_ATTR_PKEY_TABLE ),
370
-		.handle = ib_sma_set_pkey_table,
371
-	},
372
-};
373
-
374 77
 /*****************************************************************************
375 78
  *
376 79
  * General management agent

+ 362
- 0
src/net/infiniband/ib_sma.c Ver fichero

@@ -0,0 +1,362 @@
1
+/*
2
+ * Copyright (C) 2009 Michael Brown <mbrown@fensystems.co.uk>.
3
+ *
4
+ * This program is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU General Public License as
6
+ * published by the Free Software Foundation; either version 2 of the
7
+ * License, or any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful, but
10
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program; if not, write to the Free Software
16
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
+ */
18
+
19
+FILE_LICENCE ( GPL2_OR_LATER );
20
+
21
+#include <stdint.h>
22
+#include <stdlib.h>
23
+#include <string.h>
24
+#include <errno.h>
25
+#include <stdio.h>
26
+#include <unistd.h>
27
+#include <byteswap.h>
28
+#include <gpxe/infiniband.h>
29
+#include <gpxe/iobuf.h>
30
+#include <gpxe/ib_mi.h>
31
+#include <gpxe/ib_sma.h>
32
+
33
+/**
34
+ * @file
35
+ *
36
+ * Infiniband Subnet Management Agent
37
+ *
38
+ */
39
+
40
+/**
41
+ * Node information
42
+ *
43
+ * @v ibdev		Infiniband device
44
+ * @v mi		Management interface
45
+ * @v mad		Received MAD
46
+ * @v av		Source address vector
47
+ */
48
+static void ib_sma_node_info ( struct ib_device *ibdev,
49
+			       struct ib_mad_interface *mi,
50
+			       union ib_mad *mad,
51
+			       struct ib_address_vector *av ) {
52
+	struct ib_node_info *node_info = &mad->smp.smp_data.node_info;
53
+	int rc;
54
+
55
+	/* Fill in information */
56
+	memset ( node_info, 0, sizeof ( *node_info ) );
57
+	node_info->base_version = IB_MGMT_BASE_VERSION;
58
+	node_info->class_version = IB_SMP_CLASS_VERSION;
59
+	node_info->node_type = IB_NODE_TYPE_HCA;
60
+	node_info->num_ports = ib_get_hca_info ( ibdev, &node_info->sys_guid );
61
+	memcpy ( &node_info->node_guid, &node_info->sys_guid,
62
+		 sizeof ( node_info->node_guid ) );
63
+	memcpy ( &node_info->port_guid, &ibdev->gid.u.half[1],
64
+		 sizeof ( node_info->port_guid ) );
65
+	node_info->partition_cap = htons ( 1 );
66
+	node_info->local_port_num = ibdev->port;
67
+
68
+	/* Send GetResponse */
69
+	mad->hdr.method = IB_MGMT_METHOD_GET_RESP;
70
+	if ( ( rc = ib_mi_send ( ibdev, mi, mad, av ) ) != 0 ) {
71
+		DBGC ( mi, "SMA %p could not send NodeInfo GetResponse: %s\n",
72
+		       mi, strerror ( rc ) );
73
+		return;
74
+	}
75
+}
76
+
77
+/**
78
+ * Node description
79
+ *
80
+ * @v ibdev		Infiniband device
81
+ * @v mi		Management interface
82
+ * @v mad		Received MAD
83
+ * @v av		Source address vector
84
+ */
85
+static void ib_sma_node_desc ( struct ib_device *ibdev,
86
+			       struct ib_mad_interface *mi,
87
+			       union ib_mad *mad,
88
+			       struct ib_address_vector *av ) {
89
+	struct ib_node_desc *node_desc = &mad->smp.smp_data.node_desc;
90
+	struct ib_gid_half *guid = &ibdev->gid.u.half[1];
91
+	int rc;
92
+
93
+	/* Fill in information */
94
+	memset ( node_desc, 0, sizeof ( *node_desc ) );
95
+	snprintf ( node_desc->node_string, sizeof ( node_desc->node_string ),
96
+		   "gPXE %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x (%s)",
97
+		   guid->u.bytes[0], guid->u.bytes[1], guid->u.bytes[2],
98
+		   guid->u.bytes[3], guid->u.bytes[4], guid->u.bytes[5],
99
+		   guid->u.bytes[6], guid->u.bytes[7], ibdev->dev->name );
100
+
101
+	/* Send GetResponse */
102
+	mad->hdr.method = IB_MGMT_METHOD_GET_RESP;
103
+	if ( ( rc = ib_mi_send ( ibdev, mi, mad, av ) ) != 0 ) {
104
+		DBGC ( mi, "SMA %p could not send NodeDesc GetResponse: %s\n",
105
+		       mi, strerror ( rc ) );
106
+		return;
107
+	}
108
+}
109
+
110
+/**
111
+ * GUID information
112
+ *
113
+ * @v ibdev		Infiniband device
114
+ * @v mi		Management interface
115
+ * @v mad		Received MAD
116
+ * @v av		Source address vector
117
+ */
118
+static void ib_sma_guid_info ( struct ib_device *ibdev,
119
+			       struct ib_mad_interface *mi,
120
+			       union ib_mad *mad,
121
+			       struct ib_address_vector *av ) {
122
+	struct ib_guid_info *guid_info = &mad->smp.smp_data.guid_info;
123
+	int rc;
124
+
125
+	/* Fill in information */
126
+	memset ( guid_info, 0, sizeof ( *guid_info ) );
127
+	memcpy ( guid_info->guid[0], &ibdev->gid.u.half[1],
128
+		 sizeof ( guid_info->guid[0] ) );
129
+
130
+	/* Send GetResponse */
131
+	mad->hdr.method = IB_MGMT_METHOD_GET_RESP;
132
+	if ( ( rc = ib_mi_send ( ibdev, mi, mad, av ) ) != 0 ) {
133
+		DBGC ( mi, "SMA %p could not send GuidInfo GetResponse: %s\n",
134
+		       mi, strerror ( rc ) );
135
+		return;
136
+	}
137
+}
138
+
139
+/**
140
+ * Set port information
141
+ *
142
+ * @v ibdev		Infiniband device
143
+ * @v mi		Management interface
144
+ * @v mad		Received MAD
145
+ * @ret rc		Return status code
146
+ */
147
+static int ib_sma_set_port_info ( struct ib_device *ibdev,
148
+				  struct ib_mad_interface *mi,
149
+				  union ib_mad *mad ) {
150
+	const struct ib_port_info *port_info = &mad->smp.smp_data.port_info;
151
+	unsigned int link_width_enabled;
152
+	unsigned int link_speed_enabled;
153
+	int rc;
154
+
155
+	/* Set parameters */
156
+	memcpy ( &ibdev->gid.u.half[0], port_info->gid_prefix,
157
+		 sizeof ( ibdev->gid.u.half[0] ) );
158
+	ibdev->lid = ntohs ( port_info->lid );
159
+	ibdev->sm_lid = ntohs ( port_info->mastersm_lid );
160
+	if ( ( link_width_enabled = port_info->link_width_enabled ) )
161
+		ibdev->link_width_enabled = link_width_enabled;
162
+	if ( ( link_speed_enabled =
163
+	       ( port_info->link_speed_active__link_speed_enabled & 0xf ) ) )
164
+		ibdev->link_speed_enabled = link_speed_enabled;
165
+	ibdev->sm_sl = ( port_info->neighbour_mtu__mastersm_sl & 0xf );
166
+	DBGC ( mi, "SMA %p set LID %04x SMLID %04x link width %02x speed "
167
+	       "%02x\n", mi, ibdev->lid, ibdev->sm_lid,
168
+	       ibdev->link_width_enabled, ibdev->link_speed_enabled );
169
+
170
+	/* Update parameters on device */
171
+	if ( ( rc = ib_set_port_info ( ibdev, mad ) ) != 0 ) {
172
+		DBGC ( mi, "SMA %p could not set port information: %s\n",
173
+		       mi, strerror ( rc ) );
174
+		return rc;
175
+	}
176
+
177
+	return 0;
178
+}
179
+
180
+/**
181
+ * Port information
182
+ *
183
+ * @v ibdev		Infiniband device
184
+ * @v mi		Management interface
185
+ * @v mad		Received MAD
186
+ * @v av		Source address vector
187
+ */
188
+static void ib_sma_port_info ( struct ib_device *ibdev,
189
+			       struct ib_mad_interface *mi,
190
+			       union ib_mad *mad,
191
+			       struct ib_address_vector *av ) {
192
+	struct ib_port_info *port_info = &mad->smp.smp_data.port_info;
193
+	int rc;
194
+
195
+	/* Set parameters if applicable */
196
+	if ( mad->hdr.method == IB_MGMT_METHOD_SET ) {
197
+		if ( ( rc = ib_sma_set_port_info ( ibdev, mi, mad ) ) != 0 ) {
198
+			mad->hdr.status =
199
+			      htons ( IB_MGMT_STATUS_UNSUPPORTED_METHOD_ATTR );
200
+			/* Fall through to generate GetResponse */
201
+		}
202
+	}
203
+
204
+	/* Fill in information */
205
+	memset ( port_info, 0, sizeof ( *port_info ) );
206
+	memcpy ( port_info->gid_prefix, &ibdev->gid.u.half[0],
207
+		 sizeof ( port_info->gid_prefix ) );
208
+	port_info->lid = ntohs ( ibdev->lid );
209
+	port_info->mastersm_lid = ntohs ( ibdev->sm_lid );
210
+	port_info->local_port_num = ibdev->port;
211
+	port_info->link_width_enabled = ibdev->link_width_enabled;
212
+	port_info->link_width_supported = ibdev->link_width_supported;
213
+	port_info->link_width_active = ibdev->link_width_active;
214
+	port_info->link_speed_supported__port_state =
215
+		( ( ibdev->link_speed_supported << 4 ) | ibdev->port_state );
216
+	port_info->port_phys_state__link_down_def_state =
217
+		( ( IB_PORT_PHYS_STATE_POLLING << 4 ) |
218
+		  IB_PORT_PHYS_STATE_POLLING );
219
+	port_info->link_speed_active__link_speed_enabled =
220
+		( ( ibdev->link_speed_active << 4 ) |
221
+		  ibdev->link_speed_enabled );
222
+	port_info->neighbour_mtu__mastersm_sl =
223
+		( ( IB_MTU_2048 << 4 ) | ibdev->sm_sl );
224
+	port_info->vl_cap__init_type = ( IB_VL_0 << 4 );
225
+	port_info->init_type_reply__mtu_cap = IB_MTU_2048;
226
+	port_info->operational_vls__enforcement = ( IB_VL_0 << 4 );
227
+	port_info->guid_cap = 1;
228
+
229
+	/* Send GetResponse */
230
+	mad->hdr.method = IB_MGMT_METHOD_GET_RESP;
231
+	if ( ( rc = ib_mi_send ( ibdev, mi, mad, av ) ) != 0 ) {
232
+		DBGC ( mi, "SMA %p could not send PortInfo GetResponse: %s\n",
233
+		       mi, strerror ( rc ) );
234
+		return;
235
+	}
236
+}
237
+
238
+/**
239
+ * Set partition key table
240
+ *
241
+ * @v ibdev		Infiniband device
242
+ * @v mi		Management interface
243
+ * @v mad		Received MAD
244
+ * @ret rc		Return status code
245
+ */
246
+static int ib_sma_set_pkey_table ( struct ib_device *ibdev,
247
+				   struct ib_mad_interface *mi,
248
+				   union ib_mad *mad ) {
249
+	struct ib_pkey_table *pkey_table = &mad->smp.smp_data.pkey_table;
250
+	int rc;
251
+
252
+	/* Set parameters */
253
+	ibdev->pkey = ntohs ( pkey_table->pkey[0] );
254
+	DBGC ( mi, "SMA %p set pkey %04x\n", mi, ibdev->pkey );
255
+
256
+	/* Update parameters on device */
257
+	if ( ( rc = ib_set_pkey_table ( ibdev, mad ) ) != 0 ) {
258
+		DBGC ( mi, "SMA %p could not set pkey table: %s\n",
259
+		       mi, strerror ( rc ) );
260
+		return rc;
261
+	}
262
+
263
+	return 0;
264
+}
265
+
266
+/**
267
+ * Partition key table
268
+ *
269
+ * @v ibdev		Infiniband device
270
+ * @v mi		Management interface
271
+ * @v mad		Received MAD
272
+ * @v av		Source address vector
273
+ */
274
+static void ib_sma_pkey_table ( struct ib_device *ibdev,
275
+				struct ib_mad_interface *mi,
276
+				union ib_mad *mad,
277
+				struct ib_address_vector *av ) {
278
+	struct ib_pkey_table *pkey_table = &mad->smp.smp_data.pkey_table;
279
+	int rc;
280
+
281
+	/* Set parameters, if applicable */
282
+	if ( mad->hdr.method == IB_MGMT_METHOD_SET ) {
283
+		if ( ( rc = ib_sma_set_pkey_table ( ibdev, mi, mad ) ) != 0 ) {
284
+			mad->hdr.status =
285
+			      htons ( IB_MGMT_STATUS_UNSUPPORTED_METHOD_ATTR );
286
+			/* Fall through to generate GetResponse */
287
+		}
288
+	}
289
+
290
+	/* Fill in information */
291
+	mad->hdr.method = IB_MGMT_METHOD_GET_RESP;
292
+	memset ( pkey_table, 0, sizeof ( *pkey_table ) );
293
+	pkey_table->pkey[0] = htons ( ibdev->pkey );
294
+
295
+	/* Send GetResponse */
296
+	mad->hdr.method = IB_MGMT_METHOD_GET_RESP;
297
+	if ( ( rc = ib_mi_send ( ibdev, mi, mad, av ) ) != 0 ) {
298
+		DBGC ( mi, "SMA %p could not send PKeyTable GetResponse: %s\n",
299
+		       mi, strerror ( rc ) );
300
+		return;
301
+	}
302
+}
303
+
304
+/** Subnet management agent */
305
+struct ib_mad_agent ib_sma_agent[] __ib_mad_agent = {
306
+	{
307
+		.mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED,
308
+		.class_version = IB_SMP_CLASS_VERSION,
309
+		.attr_id = htons ( IB_SMP_ATTR_NODE_INFO ),
310
+		.handle = ib_sma_node_info,
311
+	},
312
+	{
313
+		.mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED,
314
+		.class_version = IB_SMP_CLASS_VERSION,
315
+		.attr_id = htons ( IB_SMP_ATTR_NODE_DESC ),
316
+		.handle = ib_sma_node_desc,
317
+	},
318
+	{
319
+		.mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED,
320
+		.class_version = IB_SMP_CLASS_VERSION,
321
+		.attr_id = htons ( IB_SMP_ATTR_GUID_INFO ),
322
+		.handle = ib_sma_guid_info,
323
+	},
324
+	{
325
+		.mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED,
326
+		.class_version = IB_SMP_CLASS_VERSION,
327
+		.attr_id = htons ( IB_SMP_ATTR_PORT_INFO ),
328
+		.handle = ib_sma_port_info,
329
+	},
330
+	{
331
+		.mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED,
332
+		.class_version = IB_SMP_CLASS_VERSION,
333
+		.attr_id = htons ( IB_SMP_ATTR_PKEY_TABLE ),
334
+		.handle = ib_sma_pkey_table,
335
+	},
336
+};
337
+
338
+/**
339
+ * Create subnet management agent and interface
340
+ *
341
+ * @v ibdev		Infiniband device
342
+ * @v mi		Management interface
343
+ * @ret rc		Return status code
344
+ */
345
+int ib_create_sma ( struct ib_device *ibdev, struct ib_mad_interface *mi ) {
346
+
347
+	/* Nothing to do */
348
+	DBGC ( ibdev, "IBDEV %p SMA using SMI %p\n", ibdev, mi );
349
+
350
+	return 0;
351
+}
352
+
353
+/**
354
+ * Destroy subnet management agent and interface
355
+ *
356
+ * @v ibdev		Infiniband device
357
+ * @v mi		Management interface
358
+ */
359
+void ib_destroy_sma ( struct ib_device *ibdev __unused,
360
+		      struct ib_mad_interface *mi __unused ) {
361
+	/* Nothing to do */
362
+}

Loading…
Cancelar
Guardar